@contentful/experiences-visual-editor-react 0.0.1-alpha.5 → 0.0.1-alpha.7
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 +90 -63
- package/dist/index.js.map +1 -1
- package/dist/renderApp.js +90 -63
- package/dist/renderApp.js.map +1 -1
- package/package.json +2 -2
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:
|
|
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","
|
|
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 = {
|
|
@@ -1703,7 +1703,7 @@ const NEW_COMPONENT_ID = 'ctfl-new-draggable';
|
|
|
1703
1703
|
const CTFL_ZONE_ID = 'data-ctfl-zone-id';
|
|
1704
1704
|
const CTFL_DRAGGING_ELEMENT = 'data-ctfl-dragging-element';
|
|
1705
1705
|
const HITBOX = {
|
|
1706
|
-
WIDTH:
|
|
1706
|
+
WIDTH: 70,
|
|
1707
1707
|
HEIGHT: 20,
|
|
1708
1708
|
INITIAL_OFFSET: 10,
|
|
1709
1709
|
OFFSET_INCREMENT: 8,
|
|
@@ -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
|
|
1762
|
-
const
|
|
1763
|
-
const
|
|
1764
|
-
const
|
|
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
|
|
1796
|
-
const
|
|
1797
|
-
const
|
|
1798
|
-
const
|
|
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,
|
|
@@ -2075,10 +2120,12 @@ const useEntityStore = create((set) => ({
|
|
|
2075
2120
|
},
|
|
2076
2121
|
resetEntityStore(locale, entities = []) {
|
|
2077
2122
|
console.debug(`[experiences-sdk-react] Resetting entity store because the locale changed to '${locale}'.`);
|
|
2123
|
+
const newEntityStore = new EditorModeEntityStore({ locale, entities });
|
|
2078
2124
|
set({
|
|
2079
|
-
entityStore:
|
|
2125
|
+
entityStore: newEntityStore,
|
|
2080
2126
|
areEntitiesFetched: false,
|
|
2081
2127
|
});
|
|
2128
|
+
return newEntityStore;
|
|
2082
2129
|
},
|
|
2083
2130
|
}));
|
|
2084
2131
|
|
|
@@ -2513,7 +2560,7 @@ const DraggableChildComponent = (props) => {
|
|
|
2513
2560
|
})));
|
|
2514
2561
|
};
|
|
2515
2562
|
|
|
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:
|
|
2563
|
+
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
2564
|
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
2565
|
styleInject(css_248z$2);
|
|
2519
2566
|
|
|
@@ -3057,11 +3104,11 @@ const EditorBlock = ({ node: rawNode, resolveDesignValue, renderDropzone, draggi
|
|
|
3057
3104
|
if (node.data.blockId === CONTENTFUL_COMPONENTS.singleColumn.id) {
|
|
3058
3105
|
return (React.createElement(React.Fragment, null,
|
|
3059
3106
|
React.createElement(DraggableChildComponent, { elementToRender: elementToRender, id: componentId, index: index, isAssemblyBlock: isAssemblyBlock, isDragDisabled: isSingleColumn, isSelected: selectedNodeId === componentId, userIsDragging: userIsDragging, isContainer: isContainer, blockId: node.data.blockId, coordinates: coordinates, wrapperProps: wrapperProps, onClick: onClick, definition: definition }),
|
|
3060
|
-
isStructureComponent && userIsDragging && (React.createElement(Hitboxes, { parentZoneId: zoneId, zoneId: componentId, enableRootHitboxes: enableRootHitboxes }))));
|
|
3107
|
+
isStructureComponent && !isSingleColumn && userIsDragging && (React.createElement(Hitboxes, { parentZoneId: zoneId, zoneId: componentId, enableRootHitboxes: enableRootHitboxes }))));
|
|
3061
3108
|
}
|
|
3062
3109
|
return (React.createElement(DraggableComponent, { placeholder: placeholder, definition: definition, id: componentId, index: index, isAssemblyBlock: isAssemblyBlock, isDragDisabled: isAssemblyBlock, isSelected: selectedNodeId === componentId, userIsDragging: userIsDragging, isContainer: isContainer, blockId: node.data.blockId, coordinates: coordinates, wrapperProps: wrapperProps, onClick: onClick },
|
|
3063
3110
|
elementToRender(),
|
|
3064
|
-
isStructureComponent && userIsDragging && (React.createElement(Hitboxes, { parentZoneId: zoneId, zoneId: componentId, enableRootHitboxes: enableRootHitboxes }))));
|
|
3111
|
+
isStructureComponent && !isSingleColumn && userIsDragging && (React.createElement(Hitboxes, { parentZoneId: zoneId, zoneId: componentId, enableRootHitboxes: enableRootHitboxes }))));
|
|
3065
3112
|
};
|
|
3066
3113
|
|
|
3067
3114
|
var css_248z$1 = ".EmptyContainer-module_container__XPH5b {\n height: 200px;\n display: flex;\n width: 100%;\n position: absolute;\n align-items: center;\n justify-content: center;\n flex-direction: row;\n transition: all 0.2s;\n color: var(--exp-builder-gray400);\n font-size: var(--exp-builder-font-size-l);\n font-family: var(--exp-builder-font-stack-primary);\n outline: 2px dashed var(--exp-builder-gray400);\n outline-offset: -2px;\n}\n\n.EmptyContainer-module_highlight__lcICy:hover {\n outline: 2px dashed var(--exp-builder-blue500);\n background-color: rgba(var(--exp-builder-blue100-rgb), 0.5);\n cursor: grabbing;\n}\n\n.EmptyContainer-module_icon__82-2O rect {\n fill: var(--exp-builder-gray400);\n}\n\n.EmptyContainer-module_label__4TxRa {\n margin-left: var(--exp-builder-spacing-s);\n}\n";
|
|
@@ -3588,6 +3635,7 @@ function useEditorSubscriber() {
|
|
|
3588
3635
|
const setDataSource = useEditorStore((state) => state.setDataSource);
|
|
3589
3636
|
const setSelectedNodeId = useEditorStore((state) => state.setSelectedNodeId);
|
|
3590
3637
|
const selectedNodeId = useEditorStore((state) => state.selectedNodeId);
|
|
3638
|
+
const resetEntityStore = useEntityStore((state) => state.resetEntityStore);
|
|
3591
3639
|
const setComponentId = useDraggedItemStore((state) => state.setComponentId);
|
|
3592
3640
|
const setDraggingOnCanvas = useDraggedItemStore((state) => state.setDraggingOnCanvas);
|
|
3593
3641
|
const setMousePosition = useDraggedItemStore((state) => state.setMousePosition);
|
|
@@ -3609,7 +3657,7 @@ function useEditorSubscriber() {
|
|
|
3609
3657
|
* Fills up entityStore with entities from newDataSource and from the tree.
|
|
3610
3658
|
* Also manages "entity status" variables (areEntitiesFetched, isFetchingEntities)
|
|
3611
3659
|
*/
|
|
3612
|
-
const fetchMissingEntities = useCallback(async (newDataSource, tree) => {
|
|
3660
|
+
const fetchMissingEntities = useCallback(async (entityStore, newDataSource, tree) => {
|
|
3613
3661
|
// if we realize that there's nothing missing and nothing to fill-fetch before we do any async call,
|
|
3614
3662
|
// then we can simply return and not lock the EntityStore at all.
|
|
3615
3663
|
const startFetching = () => {
|
|
@@ -3680,10 +3728,7 @@ function useEditorSubscriber() {
|
|
|
3680
3728
|
finally {
|
|
3681
3729
|
endFetching();
|
|
3682
3730
|
}
|
|
3683
|
-
}, [
|
|
3684
|
-
/* dataSource, */ entityStore,
|
|
3685
|
-
setEntitiesFetched /* setFetchingEntities, assembliesRegistry */,
|
|
3686
|
-
]);
|
|
3731
|
+
}, [setEntitiesFetched /* setFetchingEntities, assembliesRegistry */]);
|
|
3687
3732
|
useEffect(() => {
|
|
3688
3733
|
const onMessage = async (event) => {
|
|
3689
3734
|
let reason;
|
|
@@ -3713,6 +3758,11 @@ function useEditorSubscriber() {
|
|
|
3713
3758
|
// If the assemblyEntry is not yet fetched, this will be done below by
|
|
3714
3759
|
// the imperative calls to fetchMissingEntities.
|
|
3715
3760
|
}
|
|
3761
|
+
let newEntityStore = entityStore;
|
|
3762
|
+
if (entityStore.locale !== locale) {
|
|
3763
|
+
newEntityStore = resetEntityStore(locale);
|
|
3764
|
+
setLocale(locale);
|
|
3765
|
+
}
|
|
3716
3766
|
// Below are mutually exclusive cases
|
|
3717
3767
|
if (changedNode) {
|
|
3718
3768
|
/**
|
|
@@ -3725,7 +3775,7 @@ function useEditorSubscriber() {
|
|
|
3725
3775
|
if (changedValueType === 'BoundValue') {
|
|
3726
3776
|
const newDataSource = { ...dataSource, ...changedNode.data.dataSource };
|
|
3727
3777
|
setDataSource(newDataSource);
|
|
3728
|
-
await fetchMissingEntities(newDataSource, tree);
|
|
3778
|
+
await fetchMissingEntities(newEntityStore, newDataSource, tree);
|
|
3729
3779
|
}
|
|
3730
3780
|
else if (changedValueType === 'UnboundValue') {
|
|
3731
3781
|
setUnboundValues({
|
|
@@ -3733,19 +3783,15 @@ function useEditorSubscriber() {
|
|
|
3733
3783
|
...changedNode.data.unboundValues,
|
|
3734
3784
|
});
|
|
3735
3785
|
}
|
|
3736
|
-
// Update the tree when all necessary data is fetched and ready for rendering.
|
|
3737
|
-
updateTree(tree);
|
|
3738
|
-
setLocale(locale);
|
|
3739
3786
|
}
|
|
3740
3787
|
else {
|
|
3741
3788
|
const { dataSource, unboundValues } = getDataFromTree(tree);
|
|
3742
3789
|
setDataSource(dataSource);
|
|
3743
3790
|
setUnboundValues(unboundValues);
|
|
3744
|
-
await fetchMissingEntities(dataSource, tree);
|
|
3745
|
-
// Update the tree when all necessary data is fetched and ready for rendering.
|
|
3746
|
-
updateTree(tree);
|
|
3747
|
-
setLocale(locale);
|
|
3791
|
+
await fetchMissingEntities(newEntityStore, dataSource, tree);
|
|
3748
3792
|
}
|
|
3793
|
+
// Update the tree when all necessary data is fetched and ready for rendering.
|
|
3794
|
+
updateTree(tree);
|
|
3749
3795
|
break;
|
|
3750
3796
|
}
|
|
3751
3797
|
case INCOMING_EVENTS.AssembliesRegistered: {
|
|
@@ -3879,6 +3925,7 @@ function useEditorSubscriber() {
|
|
|
3879
3925
|
updateTree,
|
|
3880
3926
|
updateNodesByUpdatedEntity,
|
|
3881
3927
|
setMousePosition,
|
|
3928
|
+
resetEntityStore,
|
|
3882
3929
|
]);
|
|
3883
3930
|
/*
|
|
3884
3931
|
* Handles on scroll business
|
|
@@ -4145,23 +4192,14 @@ const RootRenderer = ({ onChange }) => {
|
|
|
4145
4192
|
const dragItem = useDraggedItemStore((state) => state.componentId);
|
|
4146
4193
|
const userIsDragging = useDraggedItemStore((state) => state.isDraggingOnCanvas);
|
|
4147
4194
|
const breakpoints = useTreeStore((state) => state.breakpoints);
|
|
4195
|
+
const setSelectedNodeId = useEditorStore((state) => state.setSelectedNodeId);
|
|
4148
4196
|
const draggableSourceId = useDraggedItemStore((state) => state.draggedItem?.source.droppableId);
|
|
4149
4197
|
const draggingNewComponent = !!draggableSourceId?.startsWith(COMPONENT_LIST_ID);
|
|
4150
4198
|
const containerRef = useRef(null);
|
|
4151
4199
|
const { resolveDesignValue } = useBreakpoints(breakpoints);
|
|
4152
4200
|
const [containerStyles, setContainerStyles] = useState({});
|
|
4153
4201
|
const tree = useTreeStore((state) => state.tree);
|
|
4154
|
-
|
|
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) => {
|
|
4202
|
+
const handleClickOutside = useCallback((e) => {
|
|
4165
4203
|
const element = e.target;
|
|
4166
4204
|
const isRoot = element.getAttribute('data-ctfl-zone-id') === ROOT_ID;
|
|
4167
4205
|
const clickedOnCanvas = element.closest(`[data-ctfl-root]`);
|
|
@@ -4174,7 +4212,8 @@ const RootRenderer = ({ onChange }) => {
|
|
|
4174
4212
|
sendMessage(OUTGOING_EVENTS.ComponentSelected, {
|
|
4175
4213
|
selectedId: '',
|
|
4176
4214
|
});
|
|
4177
|
-
|
|
4215
|
+
setSelectedNodeId('');
|
|
4216
|
+
}, [setSelectedNodeId]);
|
|
4178
4217
|
const handleResizeCanvas = useCallback(() => {
|
|
4179
4218
|
const parentElement = containerRef.current?.parentElement;
|
|
4180
4219
|
if (!parentElement) {
|
|
@@ -4204,6 +4243,16 @@ const RootRenderer = ({ onChange }) => {
|
|
|
4204
4243
|
});
|
|
4205
4244
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4206
4245
|
}, [containerRef.current]);
|
|
4246
|
+
useEffect(() => {
|
|
4247
|
+
if (onChange)
|
|
4248
|
+
onChange(tree);
|
|
4249
|
+
}, [tree, onChange]);
|
|
4250
|
+
useEffect(() => {
|
|
4251
|
+
document.addEventListener('click', handleClickOutside);
|
|
4252
|
+
return () => {
|
|
4253
|
+
document.removeEventListener('click', handleClickOutside);
|
|
4254
|
+
};
|
|
4255
|
+
}, [handleClickOutside]);
|
|
4207
4256
|
useEffect(() => {
|
|
4208
4257
|
handleResizeCanvas();
|
|
4209
4258
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -4255,37 +4304,15 @@ const useInitializeEditor = () => {
|
|
|
4255
4304
|
return initialized;
|
|
4256
4305
|
};
|
|
4257
4306
|
|
|
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
4307
|
const VisualEditorRoot = () => {
|
|
4269
4308
|
const initialized = useInitializeEditor();
|
|
4270
|
-
const locale = useEditorStore((state) => state.locale);
|
|
4271
4309
|
const setMousePosition = useDraggedItemStore((state) => state.setMousePosition);
|
|
4272
|
-
const entityStore = useEntityStore((state) => state.entityStore);
|
|
4273
4310
|
const setHoveringZone = useZoneStore((state) => state.setHoveringZone);
|
|
4274
|
-
const resetEntityStore = useEntityStore((state) => state.resetEntityStore);
|
|
4275
|
-
useEffect(() => {
|
|
4276
|
-
if (!locale) {
|
|
4277
|
-
return;
|
|
4278
|
-
}
|
|
4279
|
-
if (entityStore.locale === locale) {
|
|
4280
|
-
return;
|
|
4281
|
-
}
|
|
4282
|
-
resetEntityStore(locale);
|
|
4283
|
-
}, [locale, resetEntityStore, entityStore.locale]);
|
|
4284
4311
|
useEffect(() => {
|
|
4285
4312
|
const onMouseMove = (e) => {
|
|
4286
4313
|
setMousePosition(e.clientX, e.clientY);
|
|
4287
4314
|
const target = e.target;
|
|
4288
|
-
const zoneId =
|
|
4315
|
+
const zoneId = target.closest(`[${CTFL_ZONE_ID}]`)?.getAttribute(CTFL_ZONE_ID);
|
|
4289
4316
|
if (zoneId) {
|
|
4290
4317
|
setHoveringZone(zoneId);
|
|
4291
4318
|
}
|