@contentful/experiences-visual-editor-react 1.0.4 → 1.0.5-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.d.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  import React from 'react';
2
+ import { EntityStore } from '@contentful/experiences-core';
3
+ import { Experience } from '@contentful/experiences-core/types';
2
4
 
3
- declare const VisualEditorRoot: () => React.JSX.Element | null;
5
+ declare const VisualEditorRoot: ({ experience }: {
6
+ experience?: Experience<EntityStore> | undefined;
7
+ }) => React.JSX.Element | null;
4
8
 
5
9
  export { VisualEditorRoot as default };
package/dist/index.js CHANGED
@@ -725,7 +725,7 @@ const builtInStyles = {
725
725
  },
726
726
  cfHyperlink: {
727
727
  displayName: 'Hyperlink',
728
- type: 'Text',
728
+ type: 'Hyperlink',
729
729
  defaultValue: '',
730
730
  validations: {
731
731
  format: 'URL',
@@ -1185,6 +1185,56 @@ const lastPathNamedSegmentEq = (path, expectedName) => {
1185
1185
  return secondLast === expectedName;
1186
1186
  };
1187
1187
 
1188
+ const resolveHyperlinkPattern = (pattern, entry, locale) => {
1189
+ if (!entry || !locale)
1190
+ return null;
1191
+ const variables = {
1192
+ entry,
1193
+ locale,
1194
+ };
1195
+ return buildTemplate({ template: pattern, context: variables });
1196
+ };
1197
+ function getValue(obj, path) {
1198
+ return path
1199
+ .replace(/\[/g, '.')
1200
+ .replace(/\]/g, '')
1201
+ .split('.')
1202
+ .reduce((o, k) => (o || {})[k], obj);
1203
+ }
1204
+ function addLocale(str, locale) {
1205
+ const fieldsIndicator = 'fields';
1206
+ const fieldsIndex = str.indexOf(fieldsIndicator);
1207
+ if (fieldsIndex !== -1) {
1208
+ const dotIndex = str.indexOf('.', fieldsIndex + fieldsIndicator.length + 1); // +1 for '.'
1209
+ if (dotIndex !== -1) {
1210
+ return str.slice(0, dotIndex + 1) + locale + '.' + str.slice(dotIndex + 1);
1211
+ }
1212
+ }
1213
+ return str;
1214
+ }
1215
+ function getTemplateValue(ctx, path) {
1216
+ const pathWithLocale = addLocale(path, ctx.locale);
1217
+ const retrievedValue = getValue(ctx, pathWithLocale);
1218
+ return typeof retrievedValue === 'object' && retrievedValue !== null
1219
+ ? retrievedValue[ctx.locale]
1220
+ : retrievedValue;
1221
+ }
1222
+ function buildTemplate({ template, context, }) {
1223
+ const localeVariable = /{\s*locale\s*}/g;
1224
+ // e.g. "{ page.sys.id }"
1225
+ const variables = /{\s*([\S]+?)\s*}/g;
1226
+ return (template
1227
+ // first replace the locale pattern
1228
+ .replace(localeVariable, context.locale)
1229
+ // then resolve the remaining variables
1230
+ .replace(variables, (_, path) => {
1231
+ const fallback = path + '_NOT_FOUND';
1232
+ const value = getTemplateValue(context, path) ?? fallback;
1233
+ // using _.result didn't gave proper results so we run our own version of it
1234
+ return String(typeof value === 'function' ? value() : value);
1235
+ }));
1236
+ }
1237
+
1188
1238
  const sendMessage = (eventType, data) => {
1189
1239
  if (typeof window === 'undefined') {
1190
1240
  return;
@@ -1794,6 +1844,7 @@ const CF_STYLE_ATTRIBUTES = [
1794
1844
  'cfBackgroundImageAlignmentHorizontal',
1795
1845
  ];
1796
1846
  const EMPTY_CONTAINER_HEIGHT = '80px';
1847
+ const HYPERLINK_DEFAULT_PATTERN = `/{locale}/{entry.fields.slug}/`;
1797
1848
  var PostMessageMethods$1;
1798
1849
  (function (PostMessageMethods) {
1799
1850
  PostMessageMethods["REQUEST_ENTITIES"] = "REQUEST_ENTITIES";
@@ -2248,11 +2299,15 @@ const createAssemblyRegistration = ({ definitionId, definitionName, component, }
2248
2299
 
2249
2300
  const useEditorStore = create((set, get) => ({
2250
2301
  dataSource: {},
2302
+ hyperLinkPattern: undefined,
2251
2303
  unboundValues: {},
2252
2304
  isDragging: false,
2253
2305
  dragItem: '',
2254
2306
  selectedNodeId: null,
2255
2307
  locale: null,
2308
+ setHyperLinkPattern: (pattern) => {
2309
+ set({ hyperLinkPattern: pattern });
2310
+ },
2256
2311
  setSelectedNodeId: (id) => {
2257
2312
  set({ selectedNodeId: id });
2258
2313
  },
@@ -2364,6 +2419,8 @@ const useEntityStore = create((set) => ({
2364
2419
 
2365
2420
  const useComponentProps = ({ node, areEntitiesFetched, resolveDesignValue, renderDropzone, definition, userIsDragging, }) => {
2366
2421
  const unboundValues = useEditorStore((state) => state.unboundValues);
2422
+ const hyperlinkPattern = useEditorStore((state) => state.hyperLinkPattern);
2423
+ const locale = useEditorStore((state) => state.locale);
2367
2424
  const dataSource = useEditorStore((state) => state.dataSource);
2368
2425
  const entityStore = useEntityStore((state) => state.entityStore);
2369
2426
  const props = useMemo(() => {
@@ -2393,6 +2450,14 @@ const useComponentProps = ({ node, areEntitiesFetched, resolveDesignValue, rende
2393
2450
  [variableName]: designValue,
2394
2451
  };
2395
2452
  }
2453
+ else if (variableMapping.type === 'HyperlinkValue') {
2454
+ const binding = dataSource[variableMapping.linkTargetKey];
2455
+ const hyperlinkEntry = entityStore.getEntryOrAsset(binding, variableMapping.linkTargetKey);
2456
+ return {
2457
+ ...acc,
2458
+ [variableName]: resolveHyperlinkPattern(definition.hyperlinkPattern || hyperlinkPattern || HYPERLINK_DEFAULT_PATTERN, hyperlinkEntry, locale),
2459
+ };
2460
+ }
2396
2461
  else if (variableMapping.type === 'BoundValue') {
2397
2462
  const [, uuid, path] = variableMapping.path.split('/');
2398
2463
  const binding = dataSource[uuid];
@@ -2431,15 +2496,14 @@ const useComponentProps = ({ node, areEntitiesFetched, resolveDesignValue, rende
2431
2496
  }
2432
2497
  }, {});
2433
2498
  }, [
2499
+ hyperlinkPattern,
2500
+ node,
2501
+ locale,
2434
2502
  definition,
2435
- node.data.props,
2436
- node.children,
2437
- node.data.blockId,
2438
2503
  resolveDesignValue,
2439
2504
  dataSource,
2440
2505
  areEntitiesFetched,
2441
2506
  unboundValues,
2442
- node.type,
2443
2507
  entityStore,
2444
2508
  ]);
2445
2509
  const cfStyles = buildCfStyles(props, node.data.blockId);
@@ -2616,6 +2680,11 @@ const deserializeAssemblyNode = ({ node, nodeId, nodeLocation, parentId, assembl
2616
2680
  path: instanceProperty.path,
2617
2681
  };
2618
2682
  }
2683
+ else if (instanceProperty?.type === 'HyperlinkValue') {
2684
+ const componentInstanceValue = componentInstanceDataSource[instanceProperty.linkTargetKey];
2685
+ dataSource[instanceProperty.linkTargetKey] == componentInstanceValue;
2686
+ childNodeVariable[variableName] = instanceProperty;
2687
+ }
2619
2688
  }
2620
2689
  }
2621
2690
  const isAssembly = assembliesRegistry.has(node.definitionId);
@@ -4513,10 +4582,16 @@ const useInitializeEditor = () => {
4513
4582
  return initialized;
4514
4583
  };
4515
4584
 
4516
- const VisualEditorRoot = () => {
4585
+ const VisualEditorRoot = ({ experience }) => {
4517
4586
  const initialized = useInitializeEditor();
4587
+ const setHyperLinkPattern = useEditorStore((state) => state.setHyperLinkPattern);
4518
4588
  const setMousePosition = useDraggedItemStore((state) => state.setMousePosition);
4519
4589
  const setHoveringZone = useZoneStore((state) => state.setHoveringZone);
4590
+ useEffect(() => {
4591
+ if (experience?.hyperlinkPattern) {
4592
+ setHyperLinkPattern(experience.hyperlinkPattern);
4593
+ }
4594
+ }, [experience?.hyperlinkPattern, setHyperLinkPattern]);
4520
4595
  useEffect(() => {
4521
4596
  const onMouseMove = (e) => {
4522
4597
  setMousePosition(e.clientX, e.clientY);