@contentful/experiences-visual-editor-react 3.3.0 → 3.3.1-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/renderApp.js CHANGED
@@ -40832,9 +40832,9 @@ var nodeIsSet = nodeUtil && nodeUtil.isSet;
40832
40832
  var isSet$1 = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
40833
40833
 
40834
40834
  /** Used to compose bitmasks for cloning. */
40835
- var CLONE_DEEP_FLAG$1 = 1,
40835
+ var CLONE_DEEP_FLAG$2 = 1,
40836
40836
  CLONE_FLAT_FLAG$1 = 2,
40837
- CLONE_SYMBOLS_FLAG$1 = 4;
40837
+ CLONE_SYMBOLS_FLAG$2 = 4;
40838
40838
 
40839
40839
  /** `Object#toString` result references. */
40840
40840
  var argsTag$1 = '[object Arguments]',
@@ -40899,9 +40899,9 @@ cloneableTags[weakMapTag] = false;
40899
40899
  */
40900
40900
  function baseClone(value, bitmask, customizer, key, object, stack) {
40901
40901
  var result,
40902
- isDeep = bitmask & CLONE_DEEP_FLAG$1,
40902
+ isDeep = bitmask & CLONE_DEEP_FLAG$2,
40903
40903
  isFlat = bitmask & CLONE_FLAT_FLAG$1,
40904
- isFull = bitmask & CLONE_SYMBOLS_FLAG$1;
40904
+ isFull = bitmask & CLONE_SYMBOLS_FLAG$2;
40905
40905
 
40906
40906
  if (customizer) {
40907
40907
  result = object ? customizer(value, key, object, stack) : customizer(value);
@@ -40973,6 +40973,32 @@ function baseClone(value, bitmask, customizer, key, object, stack) {
40973
40973
  return result;
40974
40974
  }
40975
40975
 
40976
+ /** Used to compose bitmasks for cloning. */
40977
+ var CLONE_DEEP_FLAG$1 = 1,
40978
+ CLONE_SYMBOLS_FLAG$1 = 4;
40979
+
40980
+ /**
40981
+ * This method is like `_.clone` except that it recursively clones `value`.
40982
+ *
40983
+ * @static
40984
+ * @memberOf _
40985
+ * @since 1.0.0
40986
+ * @category Lang
40987
+ * @param {*} value The value to recursively clone.
40988
+ * @returns {*} Returns the deep cloned value.
40989
+ * @see _.clone
40990
+ * @example
40991
+ *
40992
+ * var objects = [{ 'a': 1 }, { 'b': 2 }];
40993
+ *
40994
+ * var deep = _.cloneDeep(objects);
40995
+ * console.log(deep[0] === objects[0]);
40996
+ * // => false
40997
+ */
40998
+ function cloneDeep(value) {
40999
+ return baseClone(value, CLONE_DEEP_FLAG$1 | CLONE_SYMBOLS_FLAG$1);
41000
+ }
41001
+
40976
41002
  /** Used to stand-in for `undefined` hash values. */
40977
41003
  var HASH_UNDEFINED = '__lodash_hash_undefined__';
40978
41004
 
@@ -44449,6 +44475,18 @@ var CodeNames$1;
44449
44475
  CodeNames["Custom"] = "custom";
44450
44476
  })(CodeNames$1 || (CodeNames$1 = {}));
44451
44477
 
44478
+ const sdkOptionsRegistry = {};
44479
+ /**
44480
+ * Used inside defineComponents to forward registry arguments to this registry
44481
+ * of SDK options.
44482
+ */
44483
+ const defineSdkOptions = (options) => {
44484
+ Object.assign(sdkOptionsRegistry, options);
44485
+ };
44486
+ const getSdkOptions = () => {
44487
+ return { ...sdkOptionsRegistry };
44488
+ };
44489
+
44452
44490
  const MEDIA_QUERY_REGEXP = /(<|>)(\d{1,})(px|cm|mm|in|pt|pc)$/;
44453
44491
  const toCSSMediaQuery = ({ query }) => {
44454
44492
  if (query === '*')
@@ -45033,6 +45071,20 @@ const transformBackgroundImage = (cfBackgroundImageUrl, cfBackgroundImageOptions
45033
45071
  backgroundSize: matchBackgroundSize(cfBackgroundImageOptions?.scaling),
45034
45072
  };
45035
45073
  };
45074
+ const transformTextAlign = (value) => {
45075
+ if (!value)
45076
+ return undefined;
45077
+ const sdkOptions = getSdkOptions();
45078
+ // New behavior: translate left/right to start/end
45079
+ // Customer can opt-out by activating this global option toggle
45080
+ if (!sdkOptions.__disableTextAlignmentTransform) {
45081
+ if (value === 'left')
45082
+ return 'start';
45083
+ if (value === 'right')
45084
+ return 'end';
45085
+ }
45086
+ return value;
45087
+ };
45036
45088
 
45037
45089
  const toCSSAttribute = (key) => {
45038
45090
  let val = key.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase());
@@ -45110,7 +45162,7 @@ const buildCfStyles = (values) => {
45110
45162
  lineHeight: values.cfLineHeight,
45111
45163
  letterSpacing: values.cfLetterSpacing,
45112
45164
  color: values.cfTextColor,
45113
- textAlign: values.cfTextAlign,
45165
+ textAlign: transformTextAlign(values.cfTextAlign),
45114
45166
  textTransform: values.cfTextTransform,
45115
45167
  objectFit: values.cfImageOptions?.objectFit,
45116
45168
  objectPosition: values.cfImageOptions?.objectPosition,
@@ -45243,7 +45295,7 @@ const transformRichText = (entryOrAsset, entityStore, path) => {
45243
45295
  // resolve any links to assets/entries/hyperlinks
45244
45296
  // we need to clone, as we want to keep the original Entity in the EntityStore intact,
45245
45297
  // and resolveLinks() is mutating the node object.
45246
- const richTextDocument = structuredClone(value);
45298
+ const richTextDocument = cloneDeep(value);
45247
45299
  resolveLinks(richTextDocument, entityStore);
45248
45300
  return richTextDocument;
45249
45301
  }
@@ -45589,6 +45641,27 @@ const tryParseMessage = (event) => {
45589
45641
  return eventData;
45590
45642
  };
45591
45643
 
45644
+ const splitDirectAndSlotChildren = (allChildNodes, componentDefinition) => {
45645
+ // Bridge difference between editor and delivery mode
45646
+ const getSlotId = (child) => {
45647
+ if ('data' in child)
45648
+ return child.data.slotId;
45649
+ return child.slotId;
45650
+ };
45651
+ const slotNodesMap = {};
45652
+ for (const slotId in componentDefinition.slots) {
45653
+ // We only allow one component per slot (container). This is just safer to not render components twice or not at all
45654
+ const nodes = allChildNodes.filter((child) => getSlotId(child) === slotId);
45655
+ slotNodesMap[slotId] = nodes.length ? nodes : null;
45656
+ }
45657
+ const directChildNodes = allChildNodes.filter((child) => getSlotId(child) === undefined);
45658
+ if (!componentDefinition.children || !directChildNodes.length) {
45659
+ // If there are no children allowed in the component or no children added, render as undefined
45660
+ return { slotNodesMap, directChildNodes: undefined };
45661
+ }
45662
+ return { slotNodesMap, directChildNodes };
45663
+ };
45664
+
45592
45665
  const sendMessage = (eventType, data) => {
45593
45666
  if (typeof window === 'undefined') {
45594
45667
  return;
@@ -45720,11 +45793,11 @@ let EntityStoreBase$1 = class EntityStoreBase {
45720
45793
  addEntity(entity) {
45721
45794
  if (isAsset$1(entity)) {
45722
45795
  // cloned and frozen
45723
- this.assetMap.set(entity.sys.id, deepFreeze$1(structuredClone(entity)));
45796
+ this.assetMap.set(entity.sys.id, deepFreeze$1(cloneDeep(entity)));
45724
45797
  }
45725
45798
  else if (isEntry$1(entity)) {
45726
45799
  // cloned and frozen
45727
- this.entryMap.set(entity.sys.id, deepFreeze$1(structuredClone(entity)));
45800
+ this.entryMap.set(entity.sys.id, deepFreeze$1(cloneDeep(entity)));
45728
45801
  }
45729
45802
  else {
45730
45803
  throw new Error(`Attempted to add an entity to the store that is neither Asset nor Entry: '${JSON.stringify(entity)}'`);
@@ -47363,12 +47436,14 @@ const useEditorStore = create((set, get) => ({
47363
47436
  }
47364
47437
  set({ locale });
47365
47438
  },
47366
- initializeEditor({ componentRegistry: initialRegistry, designTokens, initialLocale }) {
47439
+ initializeEditor({ componentRegistry: initialRegistry, designTokens, sdkOptions, initialLocale, }) {
47367
47440
  initialRegistry.forEach((registration) => {
47368
47441
  componentRegistry.set(registration.definition.id, registration);
47369
47442
  });
47370
47443
  // Re-register the design tokens with the Visual Editor's instance of the experiences-core package
47371
47444
  defineDesignTokens(designTokens);
47445
+ // Same copy over from one instance to the other is necessary for the sdk options
47446
+ defineSdkOptions(sdkOptions);
47372
47447
  set({ locale: initialLocale });
47373
47448
  },
47374
47449
  }));
@@ -49463,11 +49538,11 @@ class EntityStoreBase {
49463
49538
  addEntity(entity) {
49464
49539
  if (isAsset(entity)) {
49465
49540
  // cloned and frozen
49466
- this.assetMap.set(entity.sys.id, deepFreeze(structuredClone(entity)));
49541
+ this.assetMap.set(entity.sys.id, deepFreeze(cloneDeep(entity)));
49467
49542
  }
49468
49543
  else if (isEntry(entity)) {
49469
49544
  // cloned and frozen
49470
- this.entryMap.set(entity.sys.id, deepFreeze(structuredClone(entity)));
49545
+ this.entryMap.set(entity.sys.id, deepFreeze(cloneDeep(entity)));
49471
49546
  }
49472
49547
  else {
49473
49548
  throw new Error(`Attempted to add an entity to the store that is neither Asset nor Entry: '${JSON.stringify(entity)}'`);
@@ -50275,18 +50350,19 @@ function EditorBlock({ node, resolveDesignValue, wrappingPatternIds: parentWrapp
50275
50350
  if (isRootAssemblyNode && node.data.blockId && parentWrappingPatternIds.has(node.data.blockId)) {
50276
50351
  return React$1.createElement(CircularDependencyErrorPlaceholder, { wrappingPatternIds: wrappingPatternIds });
50277
50352
  }
50278
- const slotNodes = {};
50279
- for (const slotId in componentRegistration.definition.slots) {
50280
- const nodes = node.children.filter((child) => child.data.slotId === slotId);
50281
- slotNodes[slotId] =
50282
- nodes.length === 0 ? (React$1.createElement("div", { className: styles$1.emptySlot })) : (React$1.createElement(React$1.Fragment, null, nodes.map((slotChildNode) => (React$1.createElement(EditorBlock, { key: slotChildNode.data.id, node: slotChildNode, resolveDesignValue: resolveDesignValue, wrappingPatternIds: wrappingPatternIds, entityStore: entityStore, areEntitiesFetched: areEntitiesFetched })))));
50283
- }
50284
- const children = componentRegistration.definition.children
50285
- ? node.children
50286
- .filter((node) => node.data.slotId === undefined)
50287
- .map((childNode) => (React$1.createElement(EditorBlock, { key: childNode.data.id, node: childNode, resolveDesignValue: resolveDesignValue, wrappingPatternIds: wrappingPatternIds, entityStore: entityStore, areEntitiesFetched: areEntitiesFetched })))
50288
- : null;
50289
- return (React$1.createElement(RegistrationComponent, { node: node, resolveDesignValue: resolveDesignValue, componentRegistration: componentRegistration, slotNodes: slotNodes, entityStore: entityStore, areEntitiesFetched: areEntitiesFetched }, children));
50353
+ const { slotNodesMap, directChildNodes } = splitDirectAndSlotChildren(node.children, componentRegistration.definition);
50354
+ const renderChildNode = (childNode) => (React$1.createElement(EditorBlock, { key: childNode.data.id, node: childNode, resolveDesignValue: resolveDesignValue, wrappingPatternIds: wrappingPatternIds, entityStore: entityStore, areEntitiesFetched: areEntitiesFetched }));
50355
+ const renderedSlotNodesMap = Object.entries(slotNodesMap).reduce((acc, [slotId, nodes]) => {
50356
+ if (nodes?.length) {
50357
+ acc[slotId] = React$1.createElement(React$1.Fragment, null, nodes.map((slotChildNode) => renderChildNode(slotChildNode)));
50358
+ }
50359
+ else {
50360
+ acc[slotId] = React$1.createElement("div", { className: styles$1.emptySlot });
50361
+ }
50362
+ return acc;
50363
+ }, {});
50364
+ const renderedChildren = directChildNodes?.map((childNode) => renderChildNode(childNode));
50365
+ return (React$1.createElement(RegistrationComponent, { node: node, resolveDesignValue: resolveDesignValue, componentRegistration: componentRegistration, slotNodes: renderedSlotNodesMap, entityStore: entityStore, areEntitiesFetched: areEntitiesFetched }, renderedChildren));
50290
50366
  }
50291
50367
  const RegistrationComponent = ({ node, resolveDesignValue, componentRegistration, slotNodes, children, entityStore, areEntitiesFetched, }) => {
50292
50368
  const { componentProps } = useComponentProps({
@@ -50519,11 +50595,12 @@ const useInitializeEditor = (inMemoryEntitiesStore) => {
50519
50595
  const onVisualEditorInitialize = (event) => {
50520
50596
  if (!event.detail)
50521
50597
  return;
50522
- const { componentRegistry, designTokens, locale: initialLocale, entities } = event.detail;
50598
+ const { componentRegistry, designTokens, sdkOptions, locale: initialLocale, entities, } = event.detail;
50523
50599
  initializeEditor({
50524
50600
  initialLocale,
50525
50601
  componentRegistry,
50526
50602
  designTokens,
50603
+ sdkOptions,
50527
50604
  });
50528
50605
  // if entities is set to [], then everything will still work as EntityStore will
50529
50606
  // request entities on demand via ▲REQUEST_ENTITY