@contentful/experiences-visual-editor-react 0.0.1-alpha.5 → 0.0.1-alpha.6

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
@@ -1442,8 +1442,8 @@ function gatherDeepReferencesFromTree(startingNode, dataSource) {
1442
1442
  return deepReferences;
1443
1443
  }
1444
1444
 
1445
- var css_248z$6 = ".styles-module_DraggableComponent__m5-dA {\n pointer-events: all;\n position: relative;\n transition: outline 0.2s;\n cursor: grab;\n box-sizing: border-box;\n display: flex;\n}\n\n.styles-module_DraggableComponent__m5-dA:before {\n content: \"\";\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n outline-offset: -2px;\n outline: 2px solid transparent;\n z-index: 1;\n}\n\n.styles-module_DraggableClone__X8zTA:before {\n outline: 2px solid var(--exp-builder-blue500);\n}\n\n.styles-module_DraggableComponent__m5-dA > * {\n pointer-events: none;\n}\n\n.styles-module_isDragging__WHjPU {\n overflow: hidden;\n}\n\n.styles-module_isDragging__WHjPU * {\n pointer-events: none !important;\n}\n\n.styles-module_isSelected__BzICQ:before {\n outline: 2px solid transparent !important;\n}\n\n.styles-module_overlay__r4th9 {\n position: absolute;\n display: flex;\n align-items: center;\n min-width: max-content;\n height: 24px;\n z-index: 1;\n font-family: var(--exp-builder-font-stack-primary);\n font-size: 14px;\n font-weight: 500;\n background-color: var(--exp-builder-gray500);\n color: var(--exp-builder-color-white);\n border-radius: 0 0 2px 0;\n padding: 4px 12px 4px 12px;\n transition: opacity 0.2s;\n opacity: 0;\n text-wrap: nowrap;\n}\n\n.styles-module_overlayContainer__eiX-5 {\n opacity: 0;\n}\n\n.styles-module_overlayAssembly__tOzZU {\n background-color: var(--exp-builder-purple600);\n}\n\n.styles-module_userIsDragging__lqbjG > .styles-module_overlay__r4th9,\n.styles-module_userIsDragging__lqbjG > .styles-module_overlayContainer__eiX-5 {\n opacity: 0 !important;\n}\n\n.styles-module_userIsDragging__lqbjG:before {\n outline: 2px solid transparent !important;\n}\n\n.styles-module_DraggableComponent__m5-dA:hover:not(:has(div[data-rfd-draggable-id]:hover)) > .styles-module_overlay__r4th9 {\n opacity: 1;\n}\n\n.styles-module_DraggableComponent__m5-dA:hover:before,\n.styles-module_DraggableComponent__m5-dA:hover div[data-rfd-draggable-id]:before {\n outline: 2px dashed var(--exp-builder-gray500);\n}\n\n.styles-module_DraggableComponent__m5-dA:hover:not(:has(div[data-rfd-draggable-id]:hover)):before {\n outline: 2px solid var(--exp-builder-gray500);\n}\n\n.styles-module_isAssemblyBlock__Y3Avk:hover:before,\n.styles-module_isAssemblyBlock__Y3Avk:hover div[data-rfd-draggable-id]:before,\n.styles-module_DraggableComponent__m5-dA:hover div[data-rfd-draggable-id][data-cf-node-block-type^='assembly']:before {\n outline: 2px dashed var(--exp-builder-purple600);\n}\n\n.styles-module_isAssemblyBlock__Y3Avk:hover:not(:has(div[data-rfd-draggable-id]:hover)):before {\n outline: 2px solid var(--exp-builder-purple600);\n}\n";
1446
- var styles$3 = {"DraggableComponent":"styles-module_DraggableComponent__m5-dA","DraggableClone":"styles-module_DraggableClone__X8zTA","isDragging":"styles-module_isDragging__WHjPU","isSelected":"styles-module_isSelected__BzICQ","overlay":"styles-module_overlay__r4th9","overlayContainer":"styles-module_overlayContainer__eiX-5","overlayAssembly":"styles-module_overlayAssembly__tOzZU","userIsDragging":"styles-module_userIsDragging__lqbjG","isAssemblyBlock":"styles-module_isAssemblyBlock__Y3Avk"};
1445
+ var css_248z$6 = ".styles-module_DraggableComponent__m5-dA {\n pointer-events: all;\n position: relative;\n transition: outline 0.2s;\n cursor: grab;\n box-sizing: border-box;\n display: flex;\n}\n\n.styles-module_DraggableComponent__m5-dA:before {\n content: '';\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n outline-offset: -2px;\n outline: 2px solid transparent;\n z-index: 1;\n pointer-events: none;\n}\n\n.styles-module_DraggableClone__X8zTA:before {\n outline: 2px solid var(--exp-builder-blue500);\n}\n\n.styles-module_DraggableClone__X8zTA,\n.styles-module_DraggableClone__X8zTA * {\n pointer-events: none !important;\n}\n\n.styles-module_DraggableComponent__m5-dA:not(.styles-module_userIsDragging__lqbjG) :not(.styles-module_DraggableComponent__m5-dA) {\n pointer-events: none;\n}\n\n.styles-module_isDragging__WHjPU {\n overflow: hidden;\n}\n\n.styles-module_isSelected__BzICQ:before {\n outline: 2px solid transparent !important;\n}\n\n.styles-module_overlay__r4th9 {\n position: absolute;\n display: flex;\n align-items: center;\n min-width: max-content;\n height: 24px;\n z-index: 1;\n font-family: var(--exp-builder-font-stack-primary);\n font-size: 14px;\n font-weight: 500;\n background-color: var(--exp-builder-gray500);\n color: var(--exp-builder-color-white);\n border-radius: 0 0 2px 0;\n padding: 4px 12px 4px 12px;\n transition: opacity 0.2s;\n opacity: 0;\n text-wrap: nowrap;\n}\n\n.styles-module_overlayContainer__eiX-5 {\n opacity: 0;\n}\n\n.styles-module_overlayAssembly__tOzZU {\n background-color: var(--exp-builder-purple600);\n}\n\n.styles-module_userIsDragging__lqbjG > .styles-module_overlay__r4th9,\n.styles-module_userIsDragging__lqbjG > .styles-module_overlayContainer__eiX-5 {\n opacity: 0 !important;\n}\n\n.styles-module_userIsDragging__lqbjG:before {\n outline: 2px solid transparent !important;\n}\n\n.styles-module_DraggableComponent__m5-dA:hover:not(:has(div[data-rfd-draggable-id]:hover)) > .styles-module_overlay__r4th9 {\n opacity: 1;\n}\n\n.styles-module_DraggableComponent__m5-dA:hover:before,\n.styles-module_DraggableComponent__m5-dA:hover div[data-rfd-draggable-id]:before {\n outline: 2px dashed var(--exp-builder-gray500);\n}\n\n.styles-module_DraggableComponent__m5-dA:hover:not(:has(div[data-rfd-draggable-id]:hover)):before {\n outline: 2px solid var(--exp-builder-gray500);\n}\n\n.styles-module_isAssemblyBlock__Y3Avk:hover:before,\n.styles-module_isAssemblyBlock__Y3Avk:hover div[data-rfd-draggable-id]:before,\n.styles-module_DraggableComponent__m5-dA:hover div[data-rfd-draggable-id][data-cf-node-block-type^='assembly']:before {\n outline: 2px dashed var(--exp-builder-purple600);\n}\n\n.styles-module_isAssemblyBlock__Y3Avk:hover:not(:has(div[data-rfd-draggable-id]:hover)):before {\n outline: 2px solid var(--exp-builder-purple600);\n}\n";
1446
+ var styles$3 = {"DraggableComponent":"styles-module_DraggableComponent__m5-dA","DraggableClone":"styles-module_DraggableClone__X8zTA","userIsDragging":"styles-module_userIsDragging__lqbjG","isDragging":"styles-module_isDragging__WHjPU","isSelected":"styles-module_isSelected__BzICQ","overlay":"styles-module_overlay__r4th9","overlayContainer":"styles-module_overlayContainer__eiX-5","overlayAssembly":"styles-module_overlayAssembly__tOzZU","isAssemblyBlock":"styles-module_isAssemblyBlock__Y3Avk"};
1447
1447
  styleInject(css_248z$6);
1448
1448
 
1449
1449
  const SCROLL_STATES = {
@@ -1741,6 +1741,41 @@ var DraggablePosition;
1741
1741
  DraggablePosition[DraggablePosition["MOUSE_POSITION"] = 1] = "MOUSE_POSITION";
1742
1742
  })(DraggablePosition || (DraggablePosition = {}));
1743
1743
 
1744
+ const calcOffsetLeft = (parentElement, placeholderWidth, nodeWidth) => {
1745
+ if (!parentElement) {
1746
+ return 0;
1747
+ }
1748
+ const alignItems = window.getComputedStyle(parentElement).alignItems;
1749
+ if (alignItems === 'center') {
1750
+ return -(placeholderWidth - nodeWidth) / 2;
1751
+ }
1752
+ if (alignItems === 'end') {
1753
+ return -placeholderWidth + nodeWidth + 2;
1754
+ }
1755
+ return 0;
1756
+ };
1757
+ const calcOffsetTop = (parentElement, placeholderHeight, nodeHeight) => {
1758
+ if (!parentElement) {
1759
+ return 0;
1760
+ }
1761
+ const alignItems = window.getComputedStyle(parentElement).alignItems;
1762
+ if (alignItems === 'center') {
1763
+ return -(placeholderHeight - nodeHeight) / 2;
1764
+ }
1765
+ if (alignItems === 'end') {
1766
+ return -placeholderHeight + nodeHeight + 2;
1767
+ }
1768
+ return 0;
1769
+ };
1770
+ const getPaddingOffset = (element) => {
1771
+ const paddingLeft = parseFloat(window.getComputedStyle(element).paddingLeft);
1772
+ const paddingRight = parseFloat(window.getComputedStyle(element).paddingRight);
1773
+ const paddingTop = parseFloat(window.getComputedStyle(element).paddingTop);
1774
+ const paddingBottom = parseFloat(window.getComputedStyle(element).paddingBottom);
1775
+ const horizontalOffset = paddingLeft + paddingRight;
1776
+ const verticalOffset = paddingTop + paddingBottom;
1777
+ return [horizontalOffset, verticalOffset];
1778
+ };
1744
1779
  /**
1745
1780
  * Calculate the size and position of the dropzone indicator
1746
1781
  * when dragging a new component onto the canvas
@@ -1758,10 +1793,15 @@ const calcNewComponentStyles = (params) => {
1758
1793
  }
1759
1794
  const elementSizes = element.getBoundingClientRect();
1760
1795
  const dropzoneSizes = dropzone.getBoundingClientRect();
1761
- const width = isHorizontal ? DRAGGABLE_WIDTH : dropzoneSizes.width;
1762
- const height = isHorizontal ? dropzoneSizes.height : DRAGGABLE_HEIGHT;
1763
- const top = isHorizontal ? -(height - elementSizes.height) / 2 : -height;
1764
- const left = isHorizontal ? -width : -(width - elementSizes.width) / 2;
1796
+ const [horizontalPadding, verticalPadding] = getPaddingOffset(dropzone);
1797
+ const width = isHorizontal ? DRAGGABLE_WIDTH : dropzoneSizes.width - horizontalPadding;
1798
+ const height = isHorizontal ? dropzoneSizes.height - verticalPadding : DRAGGABLE_HEIGHT;
1799
+ const top = isHorizontal
1800
+ ? calcOffsetTop(element.parentElement, height, elementSizes.height)
1801
+ : -height;
1802
+ const left = isHorizontal
1803
+ ? -width
1804
+ : calcOffsetLeft(element.parentElement, width, elementSizes.width);
1765
1805
  return {
1766
1806
  width,
1767
1807
  height,
@@ -1792,10 +1832,15 @@ const calcMovementStyles = (params) => {
1792
1832
  const elementSizes = element.getBoundingClientRect();
1793
1833
  const dropzoneSizes = dropzone.getBoundingClientRect();
1794
1834
  const draggableSizes = draggable.getBoundingClientRect();
1795
- const width = isHorizontal ? draggableSizes.width : dropzoneSizes.width;
1796
- const height = isHorizontal ? dropzoneSizes.height : draggableSizes.height;
1797
- const top = isHorizontal ? -(height - elementSizes.height) / 2 : -height;
1798
- const left = isHorizontal ? -width : -(width - elementSizes.width) / 2;
1835
+ const [horizontalPadding, verticalPadding] = getPaddingOffset(dropzone);
1836
+ const width = isHorizontal ? draggableSizes.width : dropzoneSizes.width - horizontalPadding;
1837
+ const height = isHorizontal ? dropzoneSizes.height - verticalPadding : draggableSizes.height;
1838
+ const top = isHorizontal
1839
+ ? calcOffsetTop(element.parentElement, height, elementSizes.height)
1840
+ : -height;
1841
+ const left = isHorizontal
1842
+ ? -width
1843
+ : calcOffsetLeft(element.parentElement, width, elementSizes.width);
1799
1844
  return {
1800
1845
  width,
1801
1846
  height,
@@ -2513,7 +2558,7 @@ const DraggableChildComponent = (props) => {
2513
2558
  })));
2514
2559
  };
2515
2560
 
2516
- var css_248z$2 = ".styles-module_container__te-1H {\n margin-left: auto;\n margin-right: auto;\n position: relative;\n height: 100%;\n width: 100%;\n background-color: transparent;\n transition: background-color 0.2s;\n pointer-events: all;\n}\n\n.styles-module_container__te-1H:not(.styles-module_isRoot__5cn-i):before {\n content: \"\";\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n outline-offset: -1px;\n outline: 2px solid transparent;\n z-index: 1;\n transition: outline 0.2s;\n}\n\n.styles-module_isRoot__5cn-i,\n.styles-module_isEmptyCanvas__0XHZR {\n flex: 1;\n}\n\n.styles-module_isEmptyZone__zVpnZ {\n min-height: 80px;\n}\n\n.styles-module_isDragging__Gm8v5:not(.styles-module_isRoot__5cn-i):before {\n outline: 2px dashed var(--exp-builder-gray300);\n}\n\n.styles-module_isDestination__5sCQx:not(.styles-module_isRoot__5cn-i):before {\n transition: outline 0.2s, background-color 0.2s;\n outline: 2px dashed var(--exp-builder-blue400);\n background-color: rgba(var(--exp-builder-blue100-rgb), 0.5);\n z-index: 2;\n}\n\n.styles-module_hitbox__YQ-1Z {\n position: fixed;\n pointer-events: all !important;\n}\n";
2561
+ var css_248z$2 = ".styles-module_container__te-1H {\n margin-left: auto;\n margin-right: auto;\n position: relative;\n height: 100%;\n width: 100%;\n background-color: transparent;\n transition: background-color 0.2s;\n pointer-events: all !important;\n}\n\n.styles-module_container__te-1H:not(.styles-module_isRoot__5cn-i):before {\n content: '';\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n outline-offset: -1px;\n outline: 2px solid transparent;\n z-index: 1;\n transition: outline 0.2s;\n pointer-events: none;\n}\n\n.styles-module_isRoot__5cn-i,\n.styles-module_isEmptyCanvas__0XHZR {\n flex: 1;\n}\n\n.styles-module_isEmptyZone__zVpnZ {\n min-height: 80px;\n}\n\n.styles-module_isDragging__Gm8v5:not(.styles-module_isRoot__5cn-i):before {\n outline: 2px dashed var(--exp-builder-gray300);\n}\n\n.styles-module_isDestination__5sCQx:not(.styles-module_isRoot__5cn-i):before {\n transition:\n outline 0.2s,\n background-color 0.2s;\n outline: 2px dashed var(--exp-builder-blue400);\n background-color: rgba(var(--exp-builder-blue100-rgb), 0.5);\n z-index: 2;\n}\n\n.styles-module_hitbox__YQ-1Z {\n position: fixed;\n pointer-events: all !important;\n}\n";
2517
2562
  var styles$2 = {"container":"styles-module_container__te-1H","isRoot":"styles-module_isRoot__5cn-i","isEmptyCanvas":"styles-module_isEmptyCanvas__0XHZR","isEmptyZone":"styles-module_isEmptyZone__zVpnZ","isDragging":"styles-module_isDragging__Gm8v5","isDestination":"styles-module_isDestination__5sCQx","hitbox":"styles-module_hitbox__YQ-1Z"};
2518
2563
  styleInject(css_248z$2);
2519
2564
 
@@ -4145,23 +4190,14 @@ const RootRenderer = ({ onChange }) => {
4145
4190
  const dragItem = useDraggedItemStore((state) => state.componentId);
4146
4191
  const userIsDragging = useDraggedItemStore((state) => state.isDraggingOnCanvas);
4147
4192
  const breakpoints = useTreeStore((state) => state.breakpoints);
4193
+ const setSelectedNodeId = useEditorStore((state) => state.setSelectedNodeId);
4148
4194
  const draggableSourceId = useDraggedItemStore((state) => state.draggedItem?.source.droppableId);
4149
4195
  const draggingNewComponent = !!draggableSourceId?.startsWith(COMPONENT_LIST_ID);
4150
4196
  const containerRef = useRef(null);
4151
4197
  const { resolveDesignValue } = useBreakpoints(breakpoints);
4152
4198
  const [containerStyles, setContainerStyles] = useState({});
4153
4199
  const tree = useTreeStore((state) => state.tree);
4154
- useEffect(() => {
4155
- if (onChange)
4156
- onChange(tree);
4157
- }, [tree, onChange]);
4158
- useEffect(() => {
4159
- document.addEventListener('click', handleClickOutside);
4160
- return () => {
4161
- document.removeEventListener('click', handleClickOutside);
4162
- };
4163
- }, []);
4164
- const handleClickOutside = (e) => {
4200
+ const handleClickOutside = useCallback((e) => {
4165
4201
  const element = e.target;
4166
4202
  const isRoot = element.getAttribute('data-ctfl-zone-id') === ROOT_ID;
4167
4203
  const clickedOnCanvas = element.closest(`[data-ctfl-root]`);
@@ -4174,7 +4210,8 @@ const RootRenderer = ({ onChange }) => {
4174
4210
  sendMessage(OUTGOING_EVENTS.ComponentSelected, {
4175
4211
  selectedId: '',
4176
4212
  });
4177
- };
4213
+ setSelectedNodeId('');
4214
+ }, [setSelectedNodeId]);
4178
4215
  const handleResizeCanvas = useCallback(() => {
4179
4216
  const parentElement = containerRef.current?.parentElement;
4180
4217
  if (!parentElement) {
@@ -4204,6 +4241,16 @@ const RootRenderer = ({ onChange }) => {
4204
4241
  });
4205
4242
  // eslint-disable-next-line react-hooks/exhaustive-deps
4206
4243
  }, [containerRef.current]);
4244
+ useEffect(() => {
4245
+ if (onChange)
4246
+ onChange(tree);
4247
+ }, [tree, onChange]);
4248
+ useEffect(() => {
4249
+ document.addEventListener('click', handleClickOutside);
4250
+ return () => {
4251
+ document.removeEventListener('click', handleClickOutside);
4252
+ };
4253
+ }, [handleClickOutside]);
4207
4254
  useEffect(() => {
4208
4255
  handleResizeCanvas();
4209
4256
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -4255,16 +4302,6 @@ const useInitializeEditor = () => {
4255
4302
  return initialized;
4256
4303
  };
4257
4304
 
4258
- const findNearestDropzone = (element) => {
4259
- const zoneId = element.getAttribute(CTFL_ZONE_ID);
4260
- if (!element.parentElement) {
4261
- return null;
4262
- }
4263
- if (element.tagName === 'BODY') {
4264
- return null;
4265
- }
4266
- return zoneId ?? findNearestDropzone(element.parentElement);
4267
- };
4268
4305
  const VisualEditorRoot = () => {
4269
4306
  const initialized = useInitializeEditor();
4270
4307
  const locale = useEditorStore((state) => state.locale);
@@ -4285,7 +4322,7 @@ const VisualEditorRoot = () => {
4285
4322
  const onMouseMove = (e) => {
4286
4323
  setMousePosition(e.clientX, e.clientY);
4287
4324
  const target = e.target;
4288
- const zoneId = findNearestDropzone(target);
4325
+ const zoneId = target.closest(`[${CTFL_ZONE_ID}]`)?.getAttribute(CTFL_ZONE_ID);
4289
4326
  if (zoneId) {
4290
4327
  setHoveringZone(zoneId);
4291
4328
  }