diff --git a/packages/components/src/components/Divider/ContentfulDivider.css b/packages/components/src/components/Divider/ContentfulDivider.css
index 1b4a103a6..e6e941df9 100644
--- a/packages/components/src/components/Divider/ContentfulDivider.css
+++ b/packages/components/src/components/Divider/ContentfulDivider.css
@@ -1,7 +1,11 @@
.cf-divider {
+ display: contents;
position: relative;
width: 100%;
height: 100%;
+}
+
+.cf-divider hr {
border: none;
}
diff --git a/packages/components/src/components/Divider/ContentfulDivider.tsx b/packages/components/src/components/Divider/ContentfulDivider.tsx
index b4e88289b..d1a6ba1fc 100644
--- a/packages/components/src/components/Divider/ContentfulDivider.tsx
+++ b/packages/components/src/components/Divider/ContentfulDivider.tsx
@@ -1,22 +1,14 @@
import React from 'react';
import './ContentfulDivider.css';
-import { css, cx } from 'emotion';
-
-const styles = {
- hr: css({
- border: 'none',
- }),
-};
export type ContentfulDividerProps = {
className?: string;
};
-export const ContentfulDivider = (props: ContentfulDividerProps) => {
- const { className } = props;
+export const ContentfulDivider = ({ className = '', ...props }: ContentfulDividerProps) => {
return (
-
+
);
};
diff --git a/packages/components/src/components/Image/Image.tsx b/packages/components/src/components/Image/Image.tsx
index ca65d46a3..b3326759d 100644
--- a/packages/components/src/components/Image/Image.tsx
+++ b/packages/components/src/components/Image/Image.tsx
@@ -30,8 +30,10 @@ export const Image: React.FC = ({ className = '', src, cfImageAsset,
);
}
+ const imageClasses = combineClasses('cf-image', className);
+
if (typeof cfImageAsset === 'string') {
- return ;
+ return ;
}
if (cfImageAsset) {
@@ -41,13 +43,13 @@ export const Image: React.FC = ({ className = '', src, cfImageAsset,
srcSet={cfImageAsset.srcSet?.length ? cfImageAsset.srcSet?.join(', ') : undefined}
sizes={cfImageAsset.sizes ? cfImageAsset.sizes : undefined}
loading={cfImageAsset.loading}
- className={'cf-image ' + className}
+ className={imageClasses}
{...props}
/>
);
}
if (src) {
- return ;
+ return ;
}
};
diff --git a/packages/visual-editor/src/hooks/useComponent.tsx b/packages/visual-editor/src/hooks/useComponent.tsx
index 90f091ef6..6a42c80ab 100644
--- a/packages/visual-editor/src/hooks/useComponent.tsx
+++ b/packages/visual-editor/src/hooks/useComponent.tsx
@@ -64,6 +64,10 @@ export const useComponent = ({
}, [node]);
const componentId = node.data.id;
+ const isAssembly = node.type === 'assembly';
+ const isStructureComponent = isContentfulStructureComponent(node.data.blockId);
+ const requiresDragWrapper =
+ !isAssembly && !isStructureComponent && !componentRegistration?.options?.wrapComponent;
const { componentProps, wrapperStyles } = useComponentProps({
node,
@@ -72,6 +76,7 @@ export const useComponent = ({
renderDropzone,
definition: componentRegistration?.definition,
userIsDragging,
+ requiresDragWrapper,
});
const elementToRender = (props?: { dragProps?: DragWrapperProps; rest?: unknown }) => {
@@ -88,14 +93,9 @@ export const useComponent = ({
...customComponentProps
} = componentProps;
- const isStructureComponent = isContentfulStructureComponent(node.data.blockId);
- const isAssembly = node.type === 'assembly';
const modifiedProps =
isStructureComponent || isAssembly ? componentProps : customComponentProps;
- const requiresDragWrapper =
- !isStructureComponent && componentRegistration.options?.wrapComponent === false;
-
const element = React.createElement(
ImportedComponentErrorBoundary,
{ componentId: node.data.blockId },
@@ -105,7 +105,7 @@ export const useComponent = ({
}),
);
- if (!requiresDragWrapper || isAssembly) {
+ if (!requiresDragWrapper) {
return element;
}
diff --git a/packages/visual-editor/src/hooks/useComponentProps.spec.ts b/packages/visual-editor/src/hooks/useComponentProps.spec.ts
index fdc2c8297..ff62f4890 100644
--- a/packages/visual-editor/src/hooks/useComponentProps.spec.ts
+++ b/packages/visual-editor/src/hooks/useComponentProps.spec.ts
@@ -1,4 +1,4 @@
-import { ASSEMBLY_NODE_TYPE } from '@contentful/experiences-core/constants';
+import { ASSEMBLY_NODE_TYPE, CONTENTFUL_COMPONENTS } from '@contentful/experiences-core/constants';
import { useComponentProps } from './useComponentProps';
import { ComponentDefinition, ExperienceTreeNode } from '@contentful/experiences-core/types';
import { vi } from 'vitest';
@@ -102,8 +102,8 @@ describe('useComponentProps', () => {
describe('structure components', () => {
const definition: ComponentDefinition = {
- id: 'contentful-section',
- name: 'Section',
+ id: CONTENTFUL_COMPONENTS.section.id,
+ name: CONTENTFUL_COMPONENTS.section.name,
variables: {
cfWidth: { type: 'Text' },
cfHeight: { type: 'Text' },
@@ -113,7 +113,7 @@ describe('useComponentProps', () => {
data: {
id: 'id',
// This block id will identify the component as a structure component
- blockId: 'contentful-section',
+ blockId: CONTENTFUL_COMPONENTS.section.id,
props: {
cfWidth: {
type: 'DesignValue',
@@ -160,6 +160,8 @@ describe('useComponentProps', () => {
variables: {
cfWidth: { type: 'Text' },
cfHeight: { type: 'Text' },
+ cfMaxWidth: { type: 'Text' },
+ cfMargin: { type: 'Text' },
},
};
const node: ExperienceTreeNode = {
@@ -180,6 +182,18 @@ describe('useComponentProps', () => {
[desktop.id]: '50%',
},
},
+ cfMaxWidth: {
+ type: 'DesignValue',
+ valuesByBreakpoint: {
+ [desktop.id]: '50%',
+ },
+ },
+ cfMargin: {
+ type: 'DesignValue',
+ valuesByBreakpoint: {
+ [desktop.id]: '10px 0 10px 0',
+ },
+ },
},
unboundValues: {},
dataSource: {},
@@ -189,7 +203,7 @@ describe('useComponentProps', () => {
type: 'block',
};
- it('should set the component size in wrapperStyles and set 100% size in componentStyles', () => {
+ it('should set the component size in wrapperStyles when drag wrapper is enabled', () => {
const { result } = renderHook(() =>
useComponentProps({
node,
@@ -197,14 +211,39 @@ describe('useComponentProps', () => {
resolveDesignValue,
renderDropzone,
definition,
+ requiresDragWrapper: true,
userIsDragging,
}),
);
expect(result.current.wrapperStyles.width).toEqual('50%');
expect(result.current.wrapperStyles.height).toEqual('50%');
+ expect(result.current.wrapperStyles.maxWidth).toEqual('50%');
+ expect(result.current.wrapperStyles.margin).toEqual('10px 0 10px 0');
+
expect(result.current.componentStyles.width).toEqual('100%');
expect(result.current.componentStyles.height).toEqual('100%');
+ expect(result.current.componentStyles.maxWidth).toEqual('none');
+ expect(result.current.componentStyles.margin).toEqual('0');
+ });
+
+ it('should set the component size in componentStyles when drag wrapper is disabled', () => {
+ const { result } = renderHook(() =>
+ useComponentProps({
+ node,
+ areEntitiesFetched,
+ resolveDesignValue,
+ renderDropzone,
+ definition,
+ requiresDragWrapper: false,
+ userIsDragging,
+ }),
+ );
+
+ expect(result.current.componentStyles.width).toEqual('50%');
+ expect(result.current.componentStyles.height).toEqual('50%');
+ expect(result.current.componentStyles.maxWidth).toEqual('50%');
+ expect(result.current.componentStyles.margin).toEqual('10px 0 10px 0');
});
});
});
diff --git a/packages/visual-editor/src/hooks/useComponentProps.ts b/packages/visual-editor/src/hooks/useComponentProps.ts
index 2572eff4f..9bef46b03 100644
--- a/packages/visual-editor/src/hooks/useComponentProps.ts
+++ b/packages/visual-editor/src/hooks/useComponentProps.ts
@@ -51,6 +51,7 @@ type UseComponentProps = {
renderDropzone: RenderDropzoneFunction;
userIsDragging: boolean;
slotId?: string;
+ requiresDragWrapper?: boolean;
};
export const useComponentProps = ({
@@ -60,6 +61,7 @@ export const useComponentProps = ({
renderDropzone,
definition,
userIsDragging,
+ requiresDragWrapper,
}: UseComponentProps) => {
const unboundValues = useEditorStore((state) => state.unboundValues);
const hyperlinkPattern = useEditorStore((state) => state.hyperLinkPattern);
@@ -223,18 +225,27 @@ export const useComponentProps = ({
// Move size styles to the wrapping div and override the component styles
const overrideStyles: CSSProperties = {};
- const wrapperStyles: CSSProperties = {
- width: cfStyles.width,
- maxWidth: cfStyles.maxWidth,
- };
- if (!isStructureComponent) {
+ const wrapperStyles: CSSProperties = {};
+ if (requiresDragWrapper) {
if (cfStyles.height) {
wrapperStyles.height = cfStyles.height;
overrideStyles.height = '100%';
}
+
if (cfStyles.width) {
+ wrapperStyles.width = cfStyles.width;
overrideStyles.width = '100%';
}
+
+ if (cfStyles.maxWidth) {
+ wrapperStyles.maxWidth = cfStyles.maxWidth;
+ overrideStyles.maxWidth = 'none';
+ }
+
+ if (cfStyles.margin) {
+ wrapperStyles.margin = cfStyles.margin;
+ overrideStyles.margin = '0';
+ }
}
// Styles that will be applied to the component element