@contentful/experiences-visual-editor-react 3.3.1-dev-20250825T0713-34ae1b3.0 → 3.4.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1011,6 +1011,18 @@ var CodeNames$1;
1011
1011
  CodeNames["Custom"] = "custom";
1012
1012
  })(CodeNames$1 || (CodeNames$1 = {}));
1013
1013
 
1014
+ const sdkOptionsRegistry = {};
1015
+ /**
1016
+ * Used inside defineComponents to forward registry arguments to this registry
1017
+ * of SDK options.
1018
+ */
1019
+ const defineSdkOptions = (options) => {
1020
+ Object.assign(sdkOptionsRegistry, options);
1021
+ };
1022
+ const getSdkOptions = () => {
1023
+ return { ...sdkOptionsRegistry };
1024
+ };
1025
+
1014
1026
  const MEDIA_QUERY_REGEXP = /(<|>)(\d{1,})(px|cm|mm|in|pt|pc)$/;
1015
1027
  const toCSSMediaQuery = ({ query }) => {
1016
1028
  if (query === '*')
@@ -1595,6 +1607,20 @@ const transformBackgroundImage = (cfBackgroundImageUrl, cfBackgroundImageOptions
1595
1607
  backgroundSize: matchBackgroundSize(cfBackgroundImageOptions?.scaling),
1596
1608
  };
1597
1609
  };
1610
+ const transformTextAlign = (value) => {
1611
+ if (!value)
1612
+ return undefined;
1613
+ const sdkOptions = getSdkOptions();
1614
+ // New behavior: translate left/right to start/end
1615
+ // Customer can opt-out by activating this global option toggle
1616
+ if (!sdkOptions.__disableTextAlignmentTransform) {
1617
+ if (value === 'left')
1618
+ return 'start';
1619
+ if (value === 'right')
1620
+ return 'end';
1621
+ }
1622
+ return value;
1623
+ };
1598
1624
 
1599
1625
  const toCSSAttribute = (key) => {
1600
1626
  let val = key.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase());
@@ -1672,7 +1698,7 @@ const buildCfStyles = (values) => {
1672
1698
  lineHeight: values.cfLineHeight,
1673
1699
  letterSpacing: values.cfLetterSpacing,
1674
1700
  color: values.cfTextColor,
1675
- textAlign: values.cfTextAlign,
1701
+ textAlign: transformTextAlign(values.cfTextAlign),
1676
1702
  textTransform: values.cfTextTransform,
1677
1703
  objectFit: values.cfImageOptions?.objectFit,
1678
1704
  objectPosition: values.cfImageOptions?.objectPosition,
@@ -2151,6 +2177,27 @@ const tryParseMessage = (event) => {
2151
2177
  return eventData;
2152
2178
  };
2153
2179
 
2180
+ const splitDirectAndSlotChildren = (allChildNodes, componentDefinition) => {
2181
+ // Bridge difference between editor and delivery mode
2182
+ const getSlotId = (child) => {
2183
+ if ('data' in child)
2184
+ return child.data.slotId;
2185
+ return child.slotId;
2186
+ };
2187
+ const slotNodesMap = {};
2188
+ for (const slotId in componentDefinition.slots) {
2189
+ // We only allow one component per slot (container). This is just safer to not render components twice or not at all
2190
+ const nodes = allChildNodes.filter((child) => getSlotId(child) === slotId);
2191
+ slotNodesMap[slotId] = nodes.length ? nodes : null;
2192
+ }
2193
+ const directChildNodes = allChildNodes.filter((child) => getSlotId(child) === undefined);
2194
+ if (!componentDefinition.children || !directChildNodes.length) {
2195
+ // If there are no children allowed in the component or no children added, render as undefined
2196
+ return { slotNodesMap, directChildNodes: undefined };
2197
+ }
2198
+ return { slotNodesMap, directChildNodes };
2199
+ };
2200
+
2154
2201
  const sendMessage = (eventType, data) => {
2155
2202
  if (typeof window === 'undefined') {
2156
2203
  return;
@@ -3219,12 +3266,14 @@ const useEditorStore = create((set, get) => ({
3219
3266
  }
3220
3267
  set({ locale });
3221
3268
  },
3222
- initializeEditor({ componentRegistry: initialRegistry, designTokens, initialLocale }) {
3269
+ initializeEditor({ componentRegistry: initialRegistry, designTokens, sdkOptions, initialLocale, }) {
3223
3270
  initialRegistry.forEach((registration) => {
3224
3271
  componentRegistry.set(registration.definition.id, registration);
3225
3272
  });
3226
3273
  // Re-register the design tokens with the Visual Editor's instance of the experiences-core package
3227
3274
  defineDesignTokens(designTokens);
3275
+ // Same copy over from one instance to the other is necessary for the sdk options
3276
+ defineSdkOptions(sdkOptions);
3228
3277
  set({ locale: initialLocale });
3229
3278
  },
3230
3279
  }));
@@ -4905,18 +4954,19 @@ function EditorBlock({ node, resolveDesignValue, wrappingPatternIds: parentWrapp
4905
4954
  if (isRootAssemblyNode && node.data.blockId && parentWrappingPatternIds.has(node.data.blockId)) {
4906
4955
  return React.createElement(CircularDependencyErrorPlaceholder, { wrappingPatternIds: wrappingPatternIds });
4907
4956
  }
4908
- const slotNodes = {};
4909
- for (const slotId in componentRegistration.definition.slots) {
4910
- const nodes = node.children.filter((child) => child.data.slotId === slotId);
4911
- slotNodes[slotId] =
4912
- nodes.length === 0 ? (React.createElement("div", { className: styles$1.emptySlot })) : (React.createElement(React.Fragment, null, nodes.map((slotChildNode) => (React.createElement(EditorBlock, { key: slotChildNode.data.id, node: slotChildNode, resolveDesignValue: resolveDesignValue, wrappingPatternIds: wrappingPatternIds, entityStore: entityStore, areEntitiesFetched: areEntitiesFetched })))));
4913
- }
4914
- const children = componentRegistration.definition.children
4915
- ? node.children
4916
- .filter((node) => node.data.slotId === undefined)
4917
- .map((childNode) => (React.createElement(EditorBlock, { key: childNode.data.id, node: childNode, resolveDesignValue: resolveDesignValue, wrappingPatternIds: wrappingPatternIds, entityStore: entityStore, areEntitiesFetched: areEntitiesFetched })))
4918
- : null;
4919
- return (React.createElement(RegistrationComponent, { node: node, resolveDesignValue: resolveDesignValue, componentRegistration: componentRegistration, slotNodes: slotNodes, entityStore: entityStore, areEntitiesFetched: areEntitiesFetched }, children));
4957
+ const { slotNodesMap, directChildNodes } = splitDirectAndSlotChildren(node.children, componentRegistration.definition);
4958
+ const renderChildNode = (childNode) => (React.createElement(EditorBlock, { key: childNode.data.id, node: childNode, resolveDesignValue: resolveDesignValue, wrappingPatternIds: wrappingPatternIds, entityStore: entityStore, areEntitiesFetched: areEntitiesFetched }));
4959
+ const renderedSlotNodesMap = Object.entries(slotNodesMap).reduce((acc, [slotId, nodes]) => {
4960
+ if (nodes?.length) {
4961
+ acc[slotId] = React.createElement(React.Fragment, null, nodes.map((slotChildNode) => renderChildNode(slotChildNode)));
4962
+ }
4963
+ else {
4964
+ acc[slotId] = React.createElement("div", { className: styles$1.emptySlot });
4965
+ }
4966
+ return acc;
4967
+ }, {});
4968
+ const renderedChildren = directChildNodes?.map((childNode) => renderChildNode(childNode));
4969
+ return (React.createElement(RegistrationComponent, { node: node, resolveDesignValue: resolveDesignValue, componentRegistration: componentRegistration, slotNodes: renderedSlotNodesMap, entityStore: entityStore, areEntitiesFetched: areEntitiesFetched }, renderedChildren));
4920
4970
  }
4921
4971
  const RegistrationComponent = ({ node, resolveDesignValue, componentRegistration, slotNodes, children, entityStore, areEntitiesFetched, }) => {
4922
4972
  const { componentProps } = useComponentProps({
@@ -5149,11 +5199,12 @@ const useInitializeEditor = (inMemoryEntitiesStore) => {
5149
5199
  const onVisualEditorInitialize = (event) => {
5150
5200
  if (!event.detail)
5151
5201
  return;
5152
- const { componentRegistry, designTokens, locale: initialLocale, entities } = event.detail;
5202
+ const { componentRegistry, designTokens, sdkOptions, locale: initialLocale, entities, } = event.detail;
5153
5203
  initializeEditor({
5154
5204
  initialLocale,
5155
5205
  componentRegistry,
5156
5206
  designTokens,
5207
+ sdkOptions,
5157
5208
  });
5158
5209
  // if entities is set to [], then everything will still work as EntityStore will
5159
5210
  // request entities on demand via ▲REQUEST_ENTITY