@btst/stack 1.10.0 → 1.11.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/packages/ui/src/components/minimal-tiptap/utils.cjs +15 -11
- package/dist/packages/ui/src/components/minimal-tiptap/utils.mjs +15 -11
- package/dist/packages/ui/src/components/ui-builder/index.cjs +9 -7
- package/dist/packages/ui/src/components/ui-builder/index.mjs +9 -7
- package/dist/packages/ui/src/components/ui-builder/internal/canvas/auto-frame.cjs +6 -3
- package/dist/packages/ui/src/components/ui-builder/internal/canvas/auto-frame.mjs +6 -3
- package/dist/packages/ui/src/components/ui-builder/internal/components/add-component-popover.cjs +228 -48
- package/dist/packages/ui/src/components/ui-builder/internal/components/add-component-popover.mjs +228 -48
- package/dist/packages/ui/src/components/ui-builder/internal/components/element-selector.cjs +1 -1
- package/dist/packages/ui/src/components/ui-builder/internal/components/element-selector.mjs +1 -1
- package/dist/packages/ui/src/components/ui-builder/internal/components/error-fallback.cjs +4 -2
- package/dist/packages/ui/src/components/ui-builder/internal/components/error-fallback.mjs +4 -2
- package/dist/packages/ui/src/components/ui-builder/internal/components/multi-select.cjs +6 -3
- package/dist/packages/ui/src/components/ui-builder/internal/components/multi-select.mjs +6 -3
- package/dist/packages/ui/src/components/ui-builder/internal/dnd/draggable-new-component.cjs +67 -0
- package/dist/packages/ui/src/components/ui-builder/internal/dnd/draggable-new-component.mjs +62 -0
- package/dist/packages/ui/src/components/ui-builder/internal/dnd/drop-zone.cjs +181 -37
- package/dist/packages/ui/src/components/ui-builder/internal/dnd/drop-zone.mjs +181 -38
- package/dist/packages/ui/src/components/ui-builder/internal/editor-panel.cjs +1 -1
- package/dist/packages/ui/src/components/ui-builder/internal/editor-panel.mjs +1 -1
- package/dist/packages/ui/src/components/ui-builder/internal/form-fields/classname-control/classname-group-control.cjs +1 -1
- package/dist/packages/ui/src/components/ui-builder/internal/form-fields/classname-control/classname-group-control.mjs +1 -1
- package/dist/packages/ui/src/components/ui-builder/internal/form-fields/classname-control/classname-item-control.cjs +9 -2
- package/dist/packages/ui/src/components/ui-builder/internal/form-fields/classname-control/classname-item-control.mjs +9 -2
- package/dist/packages/ui/src/components/ui-builder/internal/form-fields/iconname-field.cjs +3 -2
- package/dist/packages/ui/src/components/ui-builder/internal/form-fields/iconname-field.mjs +3 -2
- package/dist/packages/ui/src/components/ui-builder/internal/layers-panel.cjs +1 -1
- package/dist/packages/ui/src/components/ui-builder/internal/layers-panel.mjs +1 -1
- package/dist/packages/ui/src/components/ui-builder/internal/props-panel.cjs +17 -5
- package/dist/packages/ui/src/components/ui-builder/internal/props-panel.mjs +17 -5
- package/dist/packages/ui/src/components/ui-builder/internal/utils/render-utils.cjs +70 -16
- package/dist/packages/ui/src/components/ui-builder/internal/utils/render-utils.mjs +73 -20
- package/dist/packages/ui/src/lib/ui-builder/context/dnd-context-colission-utils.cjs +14 -9
- package/dist/packages/ui/src/lib/ui-builder/context/dnd-context-colission-utils.mjs +14 -9
- package/dist/packages/ui/src/lib/ui-builder/context/dnd-context.cjs +38 -10
- package/dist/packages/ui/src/lib/ui-builder/context/dnd-context.mjs +35 -11
- package/dist/packages/ui/src/lib/ui-builder/context/dnd-contexts.cjs +1 -0
- package/dist/packages/ui/src/lib/ui-builder/context/dnd-contexts.mjs +1 -0
- package/dist/packages/ui/src/lib/ui-builder/context/drag-overlay.cjs +7 -4
- package/dist/packages/ui/src/lib/ui-builder/context/drag-overlay.mjs +7 -4
- package/dist/packages/ui/src/lib/ui-builder/hooks/use-auto-scroll.cjs +4 -4
- package/dist/packages/ui/src/lib/ui-builder/hooks/use-auto-scroll.mjs +4 -4
- package/dist/packages/ui/src/lib/ui-builder/hooks/use-dnd-event-handlers.cjs +53 -16
- package/dist/packages/ui/src/lib/ui-builder/hooks/use-dnd-event-handlers.mjs +53 -16
- package/dist/packages/ui/src/lib/ui-builder/hooks/use-drop-validation.cjs +23 -7
- package/dist/packages/ui/src/lib/ui-builder/hooks/use-drop-validation.mjs +23 -7
- package/dist/packages/ui/src/lib/ui-builder/registry/form-field-overrides.cjs +110 -11
- package/dist/packages/ui/src/lib/ui-builder/registry/form-field-overrides.mjs +111 -13
- package/dist/packages/ui/src/lib/ui-builder/store/editor-store.cjs +3 -2
- package/dist/packages/ui/src/lib/ui-builder/store/editor-store.mjs +3 -2
- package/dist/packages/ui/src/lib/ui-builder/store/layer-store.cjs +53 -7
- package/dist/packages/ui/src/lib/ui-builder/store/layer-store.mjs +54 -8
- package/dist/packages/ui/src/lib/ui-builder/store/layer-utils.cjs +4 -3
- package/dist/packages/ui/src/lib/ui-builder/store/layer-utils.mjs +4 -3
- package/dist/packages/ui/src/lib/ui-builder/utils/variable-resolver.cjs +12 -0
- package/dist/packages/ui/src/lib/ui-builder/utils/variable-resolver.mjs +12 -1
- package/dist/plugins/ui-builder/client/components/index.d.cts +1 -1
- package/dist/plugins/ui-builder/client/components/index.d.mts +1 -1
- package/dist/plugins/ui-builder/client/components/index.d.ts +1 -1
- package/dist/plugins/ui-builder/client/hooks/index.d.cts +2 -2
- package/dist/plugins/ui-builder/client/hooks/index.d.mts +2 -2
- package/dist/plugins/ui-builder/client/hooks/index.d.ts +2 -2
- package/dist/plugins/ui-builder/client/index.d.cts +17 -7
- package/dist/plugins/ui-builder/client/index.d.mts +17 -7
- package/dist/plugins/ui-builder/client/index.d.ts +17 -7
- package/dist/plugins/ui-builder/index.d.cts +2 -2
- package/dist/plugins/ui-builder/index.d.mts +2 -2
- package/dist/plugins/ui-builder/index.d.ts +2 -2
- package/dist/shared/{stack.BSM2cgoq.d.cts → stack.BYysGdHl.d.cts} +1 -1
- package/dist/shared/{stack.CqfZWfjJ.d.cts → stack.BdJFrdyt.d.cts} +8 -2
- package/dist/shared/{stack.e1FN86dE.d.mts → stack.ChVuHi5e.d.mts} +8 -2
- package/dist/shared/{stack.CLtOoAqF.d.mts → stack.DYCFcnkL.d.mts} +1 -1
- package/dist/shared/{stack.MMntCVZZ.d.ts → stack.EhM4pmtN.d.ts} +8 -2
- package/dist/shared/{stack.BD1m-4yB.d.ts → stack.kFbDspnF.d.ts} +1 -1
- package/package.json +1 -1
|
@@ -32,7 +32,9 @@ function ClassNameItemControl({ value, onChange }) {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
});
|
|
35
|
-
if (!found
|
|
35
|
+
if (!found && group.keys[0]) {
|
|
36
|
+
initialSelected[group.label] = group.keys[0];
|
|
37
|
+
}
|
|
36
38
|
});
|
|
37
39
|
const handledTokens = new Set(
|
|
38
40
|
Object.values(parsedState).flatMap(
|
|
@@ -50,7 +52,9 @@ function ClassNameItemControl({ value, onChange }) {
|
|
|
50
52
|
} else {
|
|
51
53
|
const initialSelected = {};
|
|
52
54
|
LAYOUT_GROUPS.forEach((group) => {
|
|
53
|
-
|
|
55
|
+
if (group.keys[0]) {
|
|
56
|
+
initialSelected[group.label] = group.keys[0];
|
|
57
|
+
}
|
|
54
58
|
});
|
|
55
59
|
return {
|
|
56
60
|
parsedState: {},
|
|
@@ -172,7 +176,9 @@ function ClassNameItemControl({ value, onChange }) {
|
|
|
172
176
|
const keys = group.keys.map(String);
|
|
173
177
|
const selectedKey = selectedKeys[group.label] || keys[0];
|
|
174
178
|
if (entry.isVisible && !entry.isVisible(state)) return null;
|
|
179
|
+
if (!selectedKey) return null;
|
|
175
180
|
const groupConfig = CONFIG[selectedKey];
|
|
181
|
+
if (!groupConfig) return null;
|
|
176
182
|
return /* @__PURE__ */ jsx("div", { className: cn("w-full", entry.className), "data-testid": `group-${group.label.toLowerCase().replace(/\s+/g, "-")}`, children: /* @__PURE__ */ jsx(
|
|
177
183
|
ClassNameGroupControl,
|
|
178
184
|
{
|
|
@@ -188,6 +194,7 @@ function ClassNameItemControl({ value, onChange }) {
|
|
|
188
194
|
if (entry.isVisible && !entry.isVisible(state)) return null;
|
|
189
195
|
const configKey = entry.key;
|
|
190
196
|
const ungroupedConfig = CONFIG[configKey];
|
|
197
|
+
if (!ungroupedConfig) return null;
|
|
191
198
|
return /* @__PURE__ */ jsx("div", { className: cn("w-full", entry.className), "data-testid": `item-${configKey}`, children: /* @__PURE__ */ jsx(
|
|
192
199
|
ungroupedConfig.component,
|
|
193
200
|
{
|
|
@@ -29,8 +29,9 @@ const IconNameField = ({
|
|
|
29
29
|
}, []);
|
|
30
30
|
const handleChange = React.useCallback(
|
|
31
31
|
(values) => {
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
const firstValue = values[0];
|
|
33
|
+
if (firstValue) {
|
|
34
|
+
onChange(firstValue.value);
|
|
34
35
|
}
|
|
35
36
|
},
|
|
36
37
|
[onChange]
|
|
@@ -27,8 +27,9 @@ const IconNameField = ({
|
|
|
27
27
|
}, []);
|
|
28
28
|
const handleChange = useCallback(
|
|
29
29
|
(values) => {
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
const firstValue = values[0];
|
|
31
|
+
if (firstValue) {
|
|
32
|
+
onChange(firstValue.value);
|
|
32
33
|
}
|
|
33
34
|
},
|
|
34
35
|
[onChange]
|
|
@@ -84,7 +84,7 @@ const LayersTree = React__default.memo(
|
|
|
84
84
|
}
|
|
85
85
|
const updatedChildren = layerUtils.hasLayerChildren(updatedPageLayer) ? updatedPageLayer.children || [] : [];
|
|
86
86
|
const currentLayer = layers[0];
|
|
87
|
-
const currentChildren = layerUtils.hasLayerChildren(currentLayer) ? currentLayer.children || [] : [];
|
|
87
|
+
const currentChildren = currentLayer && layerUtils.hasLayerChildren(currentLayer) ? currentLayer.children || [] : [];
|
|
88
88
|
if (!index(currentChildren, updatedChildren)) {
|
|
89
89
|
updateLayer(selectedPageId, {}, { children: updatedChildren });
|
|
90
90
|
}
|
|
@@ -76,7 +76,7 @@ const LayersTree = React__default.memo(
|
|
|
76
76
|
}
|
|
77
77
|
const updatedChildren = hasLayerChildren(updatedPageLayer) ? updatedPageLayer.children || [] : [];
|
|
78
78
|
const currentLayer = layers[0];
|
|
79
|
-
const currentChildren = hasLayerChildren(currentLayer) ? currentLayer.children || [] : [];
|
|
79
|
+
const currentChildren = currentLayer && hasLayerChildren(currentLayer) ? currentLayer.children || [] : [];
|
|
80
80
|
if (!isDeepEqual(currentChildren, updatedChildren)) {
|
|
81
81
|
updateLayer(selectedPageId, {}, { children: updatedChildren });
|
|
82
82
|
}
|
|
@@ -101,7 +101,10 @@ const ComponentPropsAutoForm = ({
|
|
|
101
101
|
);
|
|
102
102
|
const { schema } = React.useMemo(() => {
|
|
103
103
|
if (selectedLayer && componentRegistry[selectedLayer.type]) {
|
|
104
|
-
|
|
104
|
+
const registryEntry = componentRegistry[selectedLayer.type];
|
|
105
|
+
if (registryEntry) {
|
|
106
|
+
return registryEntry;
|
|
107
|
+
}
|
|
105
108
|
}
|
|
106
109
|
return { schema: EMPTY_ZOD_SCHEMA };
|
|
107
110
|
}, [selectedLayer, componentRegistry]);
|
|
@@ -111,6 +114,7 @@ const ComponentPropsAutoForm = ({
|
|
|
111
114
|
const handleDuplicateLayer = React.useCallback(() => {
|
|
112
115
|
duplicateLayer(selectedLayerId);
|
|
113
116
|
}, [duplicateLayer, selectedLayerId]);
|
|
117
|
+
const variables = layerStore.useLayerStore((state) => state.variables);
|
|
114
118
|
const onParsedValuesChange = React.useCallback(
|
|
115
119
|
(parsedValues) => {
|
|
116
120
|
const { children, ...dataProps } = parsedValues;
|
|
@@ -123,7 +127,12 @@ const ComponentPropsAutoForm = ({
|
|
|
123
127
|
const fieldDef = "shape" in schema && schema.shape ? schema.shape[key] : void 0;
|
|
124
128
|
const baseType = fieldDef ? helpers.getBaseType(fieldDef) : void 0;
|
|
125
129
|
if (types.isVariableReference(originalValue)) {
|
|
126
|
-
|
|
130
|
+
const variableExists = variables.some((v) => v.id === originalValue.__variableRef);
|
|
131
|
+
if (variableExists) {
|
|
132
|
+
preservedProps[key] = originalValue;
|
|
133
|
+
} else {
|
|
134
|
+
preservedProps[key] = newValue;
|
|
135
|
+
}
|
|
127
136
|
} else {
|
|
128
137
|
if (baseType === "ZodDate" && newValue instanceof Date) {
|
|
129
138
|
preservedProps[key] = newValue.toISOString();
|
|
@@ -133,7 +142,11 @@ const ComponentPropsAutoForm = ({
|
|
|
133
142
|
}
|
|
134
143
|
});
|
|
135
144
|
}
|
|
136
|
-
|
|
145
|
+
const originalChildren = selectedLayer?.children;
|
|
146
|
+
const shouldPreserveChildrenBinding = types.isVariableReference(originalChildren) && variables.some((v) => v.id === originalChildren.__variableRef);
|
|
147
|
+
if (shouldPreserveChildrenBinding) {
|
|
148
|
+
updateLayer(selectedLayerId, preservedProps);
|
|
149
|
+
} else if (typeof children === "string") {
|
|
137
150
|
updateLayer(selectedLayerId, preservedProps, { children });
|
|
138
151
|
} else if (children && children.layerType) {
|
|
139
152
|
updateLayer(selectedLayerId, preservedProps, {
|
|
@@ -148,9 +161,8 @@ const ComponentPropsAutoForm = ({
|
|
|
148
161
|
updateLayer(selectedLayerId, preservedProps);
|
|
149
162
|
}
|
|
150
163
|
},
|
|
151
|
-
[updateLayer, selectedLayerId, selectedLayer, addComponentLayer, schema]
|
|
164
|
+
[updateLayer, selectedLayerId, selectedLayer, addComponentLayer, schema, variables]
|
|
152
165
|
);
|
|
153
|
-
const variables = layerStore.useLayerStore((state) => state.variables);
|
|
154
166
|
const formValues = React.useMemo(() => {
|
|
155
167
|
if (!selectedLayer) return EMPTY_FORM_VALUES;
|
|
156
168
|
const resolvedProps = variableResolver.resolveVariableReferences(
|
|
@@ -95,7 +95,10 @@ const ComponentPropsAutoForm = ({
|
|
|
95
95
|
);
|
|
96
96
|
const { schema } = useMemo(() => {
|
|
97
97
|
if (selectedLayer && componentRegistry[selectedLayer.type]) {
|
|
98
|
-
|
|
98
|
+
const registryEntry = componentRegistry[selectedLayer.type];
|
|
99
|
+
if (registryEntry) {
|
|
100
|
+
return registryEntry;
|
|
101
|
+
}
|
|
99
102
|
}
|
|
100
103
|
return { schema: EMPTY_ZOD_SCHEMA };
|
|
101
104
|
}, [selectedLayer, componentRegistry]);
|
|
@@ -105,6 +108,7 @@ const ComponentPropsAutoForm = ({
|
|
|
105
108
|
const handleDuplicateLayer = useCallback(() => {
|
|
106
109
|
duplicateLayer(selectedLayerId);
|
|
107
110
|
}, [duplicateLayer, selectedLayerId]);
|
|
111
|
+
const variables = useLayerStore((state) => state.variables);
|
|
108
112
|
const onParsedValuesChange = useCallback(
|
|
109
113
|
(parsedValues) => {
|
|
110
114
|
const { children, ...dataProps } = parsedValues;
|
|
@@ -117,7 +121,12 @@ const ComponentPropsAutoForm = ({
|
|
|
117
121
|
const fieldDef = "shape" in schema && schema.shape ? schema.shape[key] : void 0;
|
|
118
122
|
const baseType = fieldDef ? getBaseType(fieldDef) : void 0;
|
|
119
123
|
if (isVariableReference(originalValue)) {
|
|
120
|
-
|
|
124
|
+
const variableExists = variables.some((v) => v.id === originalValue.__variableRef);
|
|
125
|
+
if (variableExists) {
|
|
126
|
+
preservedProps[key] = originalValue;
|
|
127
|
+
} else {
|
|
128
|
+
preservedProps[key] = newValue;
|
|
129
|
+
}
|
|
121
130
|
} else {
|
|
122
131
|
if (baseType === "ZodDate" && newValue instanceof Date) {
|
|
123
132
|
preservedProps[key] = newValue.toISOString();
|
|
@@ -127,7 +136,11 @@ const ComponentPropsAutoForm = ({
|
|
|
127
136
|
}
|
|
128
137
|
});
|
|
129
138
|
}
|
|
130
|
-
|
|
139
|
+
const originalChildren = selectedLayer?.children;
|
|
140
|
+
const shouldPreserveChildrenBinding = isVariableReference(originalChildren) && variables.some((v) => v.id === originalChildren.__variableRef);
|
|
141
|
+
if (shouldPreserveChildrenBinding) {
|
|
142
|
+
updateLayer(selectedLayerId, preservedProps);
|
|
143
|
+
} else if (typeof children === "string") {
|
|
131
144
|
updateLayer(selectedLayerId, preservedProps, { children });
|
|
132
145
|
} else if (children && children.layerType) {
|
|
133
146
|
updateLayer(selectedLayerId, preservedProps, {
|
|
@@ -142,9 +155,8 @@ const ComponentPropsAutoForm = ({
|
|
|
142
155
|
updateLayer(selectedLayerId, preservedProps);
|
|
143
156
|
}
|
|
144
157
|
},
|
|
145
|
-
[updateLayer, selectedLayerId, selectedLayer, addComponentLayer, schema]
|
|
158
|
+
[updateLayer, selectedLayerId, selectedLayer, addComponentLayer, schema, variables]
|
|
146
159
|
);
|
|
147
|
-
const variables = useLayerStore((state) => state.variables);
|
|
148
160
|
const formValues = useMemo(() => {
|
|
149
161
|
if (!selectedLayer) return EMPTY_FORM_VALUES;
|
|
150
162
|
const resolvedProps = resolveVariableReferences(
|
|
@@ -16,11 +16,30 @@ const reactErrorBoundary = require('react-error-boundary');
|
|
|
16
16
|
const errorFallback = require('../components/error-fallback.cjs');
|
|
17
17
|
const editorUtils = require('../../../../lib/ui-builder/store/editor-utils.cjs');
|
|
18
18
|
const devProfiler = require('../components/dev-profiler.cjs');
|
|
19
|
+
const types = require('../../types.cjs');
|
|
19
20
|
const variableResolver = require('../../../../lib/ui-builder/utils/variable-resolver.cjs');
|
|
20
21
|
|
|
22
|
+
const POSITION_CLASSES = ["static", "fixed", "absolute", "relative", "sticky"];
|
|
23
|
+
function hasPositionClass(className) {
|
|
24
|
+
const classes = className.split(/\s+/);
|
|
25
|
+
return POSITION_CLASSES.some((posClass) => classes.includes(posClass));
|
|
26
|
+
}
|
|
27
|
+
function isLayerBeingDraggedOrDescendant(layerId, activeLayerId, pages) {
|
|
28
|
+
if (!activeLayerId) return false;
|
|
29
|
+
if (layerId === activeLayerId) return true;
|
|
30
|
+
if (!pages || !Array.isArray(pages) || pages.length === 0) return false;
|
|
31
|
+
const draggedLayer = layerUtils.findLayerRecursive(pages, activeLayerId);
|
|
32
|
+
if (!draggedLayer) return false;
|
|
33
|
+
if (layerUtils.hasLayerChildren(draggedLayer)) {
|
|
34
|
+
const foundInDragged = layerUtils.findLayerRecursive([draggedLayer], layerId);
|
|
35
|
+
return !!foundInDragged;
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
21
39
|
const RenderLayer = React.memo(
|
|
22
40
|
({ layer, componentRegistry, editorConfig, variables, variableValues }) => {
|
|
23
41
|
const storeVariables = layerStore.useLayerStore((state) => state.variables);
|
|
42
|
+
const pages = layerStore.useLayerStore((state) => state.pages);
|
|
24
43
|
const isLayerAPage = layerStore.useLayerStore((state) => state.isLayerAPage(layer.id));
|
|
25
44
|
const registry = editorStore.useEditorStore((state) => state.registry);
|
|
26
45
|
const dndContext = dndContexts.useDndContext();
|
|
@@ -38,15 +57,29 @@ const RenderLayer = React.memo(
|
|
|
38
57
|
() => variableResolver.resolveVariableReferences(layer.props, effectiveVariables, variableValues),
|
|
39
58
|
[layer.props, effectiveVariables, variableValues]
|
|
40
59
|
);
|
|
41
|
-
const childProps = React.useMemo(() => ({ ...resolvedProps }), [resolvedProps]);
|
|
42
60
|
const childEditorConfig = React.useMemo(() => {
|
|
43
61
|
return editorConfig ? { ...editorConfig, zIndex: editorConfig.zIndex + 1, parentUpdated: editorConfig.parentUpdated || !index(prevLayer.current, layer) } : void 0;
|
|
44
62
|
}, [editorConfig, layer]);
|
|
63
|
+
const isBeingDragged = React.useMemo(
|
|
64
|
+
() => isLayerBeingDraggedOrDescendant(layer.id, dndContext.activeLayerId, pages),
|
|
65
|
+
[layer.id, dndContext.activeLayerId, pages]
|
|
66
|
+
);
|
|
67
|
+
const isRootDraggedLayer = layer.id === dndContext.activeLayerId;
|
|
45
68
|
const canAcceptChildren = React.useMemo(() => layerUtils.canLayerAcceptChildren(layer, registry), [layer, registry]);
|
|
46
69
|
const showDropZones = React.useMemo(
|
|
47
|
-
() => editorConfig && dndContext.isDragging && canAcceptChildren,
|
|
48
|
-
[editorConfig, dndContext.isDragging, canAcceptChildren]
|
|
70
|
+
() => editorConfig && dndContext.isDragging && canAcceptChildren && !isBeingDragged,
|
|
71
|
+
[editorConfig, dndContext.isDragging, canAcceptChildren, isBeingDragged]
|
|
49
72
|
);
|
|
73
|
+
const childProps = React.useMemo(() => {
|
|
74
|
+
const props = { ...resolvedProps };
|
|
75
|
+
if (showDropZones && layerUtils.hasLayerChildren(layer)) {
|
|
76
|
+
const existingClassName = props.className || "";
|
|
77
|
+
if (!hasPositionClass(existingClassName)) {
|
|
78
|
+
props.className = existingClassName ? `${existingClassName} relative` : "relative";
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return props;
|
|
82
|
+
}, [resolvedProps, showDropZones, layer]);
|
|
50
83
|
if (!componentDefinition) {
|
|
51
84
|
console.error(
|
|
52
85
|
`[UIBuilder] Component definition not found in registry:`,
|
|
@@ -75,7 +108,7 @@ const RenderLayer = React.memo(
|
|
|
75
108
|
child.id
|
|
76
109
|
);
|
|
77
110
|
if (showDropZones) {
|
|
78
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
111
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
|
|
79
112
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
80
113
|
dropZone.DropPlaceholder,
|
|
81
114
|
{
|
|
@@ -90,21 +123,30 @@ const RenderLayer = React.memo(
|
|
|
90
123
|
return childElement;
|
|
91
124
|
});
|
|
92
125
|
if (showDropZones) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
126
|
+
childElements.push(
|
|
127
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
128
|
+
dropZone.DropPlaceholder,
|
|
129
|
+
{
|
|
130
|
+
parentId: layer.id,
|
|
131
|
+
position: layer.children.length,
|
|
132
|
+
isActive: true
|
|
133
|
+
},
|
|
134
|
+
`drop-${layer.id}-${layer.children.length}`
|
|
135
|
+
)
|
|
136
|
+
);
|
|
102
137
|
}
|
|
103
138
|
childProps.children = childElements;
|
|
139
|
+
} else if (types.isVariableReference(layer.children)) {
|
|
140
|
+
const resolvedChildren = variableResolver.resolveChildrenVariableReference(
|
|
141
|
+
layer.children,
|
|
142
|
+
effectiveVariables,
|
|
143
|
+
variableValues
|
|
144
|
+
);
|
|
145
|
+
childProps.children = resolvedChildren;
|
|
104
146
|
} else if (typeof layer.children === "string") {
|
|
105
147
|
childProps.children = layer.children;
|
|
106
148
|
} else if (showDropZones && layerUtils.hasLayerChildren(layer)) {
|
|
107
|
-
childProps.children = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "
|
|
149
|
+
childProps.children = /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-[2rem] w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
108
150
|
dropZone.DropPlaceholder,
|
|
109
151
|
{
|
|
110
152
|
parentId: layer.id,
|
|
@@ -114,8 +156,19 @@ const RenderLayer = React.memo(
|
|
|
114
156
|
) });
|
|
115
157
|
}
|
|
116
158
|
const WrappedComponent = isPrimitive ? /* @__PURE__ */ jsxRuntime.jsx(Component, { id: layer.id, "data-testid": layer.id, "data-layer-id": layer.id, ...childProps }) : /* @__PURE__ */ jsxRuntime.jsx(ErrorSuspenseWrapper, { id: layer.id, children: /* @__PURE__ */ jsxRuntime.jsx(Component, { "data-testid": layer.id, "data-layer-id": layer.id, ...childProps }) }, layer.id);
|
|
159
|
+
const DragFeedbackWrapper = isRootDraggedLayer ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
160
|
+
"div",
|
|
161
|
+
{
|
|
162
|
+
className: "relative opacity-50 pointer-events-none",
|
|
163
|
+
"data-dragging": "true",
|
|
164
|
+
children: [
|
|
165
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-primary/20 rounded pointer-events-none z-10" }),
|
|
166
|
+
WrappedComponent
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
) : WrappedComponent;
|
|
117
170
|
if (!editorConfig) {
|
|
118
|
-
return
|
|
171
|
+
return DragFeedbackWrapper;
|
|
119
172
|
} else {
|
|
120
173
|
const {
|
|
121
174
|
zIndex,
|
|
@@ -141,7 +194,7 @@ const RenderLayer = React.memo(
|
|
|
141
194
|
totalLayers,
|
|
142
195
|
onDuplicateLayer: handleDuplicateLayer,
|
|
143
196
|
onDeleteLayer: handleDeleteLayer,
|
|
144
|
-
children:
|
|
197
|
+
children: DragFeedbackWrapper
|
|
145
198
|
},
|
|
146
199
|
layer.id
|
|
147
200
|
)
|
|
@@ -171,3 +224,4 @@ const ErrorSuspenseWrapper = ({ children }) => {
|
|
|
171
224
|
const LoadingComponent = () => /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Loading..." });
|
|
172
225
|
|
|
173
226
|
exports.RenderLayer = RenderLayer;
|
|
227
|
+
exports.hasPositionClass = hasPositionClass;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import { memo, useRef, useMemo, Suspense } from 'react';
|
|
2
|
+
import { memo, useRef, useMemo, Fragment, Suspense } from 'react';
|
|
3
3
|
import isDeepEqual from '../../../../../../../_virtual/index.mjs';
|
|
4
4
|
import { ElementSelector } from '../components/element-selector.mjs';
|
|
5
5
|
import { DropPlaceholder } from '../dnd/drop-zone.mjs';
|
|
@@ -8,17 +8,36 @@ import '../../../../lib/ui-builder/context/dnd-context-colission-utils.mjs';
|
|
|
8
8
|
import { useDndContext } from '../../../../lib/ui-builder/context/dnd-contexts.mjs';
|
|
9
9
|
import 'react-dom';
|
|
10
10
|
import { useLayerStore } from '../../../../lib/ui-builder/store/layer-store.mjs';
|
|
11
|
-
import { canLayerAcceptChildren, hasLayerChildren } from '../../../../lib/ui-builder/store/layer-utils.mjs';
|
|
11
|
+
import { canLayerAcceptChildren, hasLayerChildren, findLayerRecursive } from '../../../../lib/ui-builder/store/layer-utils.mjs';
|
|
12
12
|
import { useEditorStore } from '../../../../lib/ui-builder/store/editor-store.mjs';
|
|
13
13
|
import { ErrorBoundary } from 'react-error-boundary';
|
|
14
14
|
import { ErrorFallback } from '../components/error-fallback.mjs';
|
|
15
15
|
import { isPrimitiveComponent } from '../../../../lib/ui-builder/store/editor-utils.mjs';
|
|
16
16
|
import { DevProfiler } from '../components/dev-profiler.mjs';
|
|
17
|
-
import {
|
|
17
|
+
import { isVariableReference } from '../../types.mjs';
|
|
18
|
+
import { resolveVariableReferences, resolveChildrenVariableReference } from '../../../../lib/ui-builder/utils/variable-resolver.mjs';
|
|
18
19
|
|
|
20
|
+
const POSITION_CLASSES = ["static", "fixed", "absolute", "relative", "sticky"];
|
|
21
|
+
function hasPositionClass(className) {
|
|
22
|
+
const classes = className.split(/\s+/);
|
|
23
|
+
return POSITION_CLASSES.some((posClass) => classes.includes(posClass));
|
|
24
|
+
}
|
|
25
|
+
function isLayerBeingDraggedOrDescendant(layerId, activeLayerId, pages) {
|
|
26
|
+
if (!activeLayerId) return false;
|
|
27
|
+
if (layerId === activeLayerId) return true;
|
|
28
|
+
if (!pages || !Array.isArray(pages) || pages.length === 0) return false;
|
|
29
|
+
const draggedLayer = findLayerRecursive(pages, activeLayerId);
|
|
30
|
+
if (!draggedLayer) return false;
|
|
31
|
+
if (hasLayerChildren(draggedLayer)) {
|
|
32
|
+
const foundInDragged = findLayerRecursive([draggedLayer], layerId);
|
|
33
|
+
return !!foundInDragged;
|
|
34
|
+
}
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
19
37
|
const RenderLayer = memo(
|
|
20
38
|
({ layer, componentRegistry, editorConfig, variables, variableValues }) => {
|
|
21
39
|
const storeVariables = useLayerStore((state) => state.variables);
|
|
40
|
+
const pages = useLayerStore((state) => state.pages);
|
|
22
41
|
const isLayerAPage = useLayerStore((state) => state.isLayerAPage(layer.id));
|
|
23
42
|
const registry = useEditorStore((state) => state.registry);
|
|
24
43
|
const dndContext = useDndContext();
|
|
@@ -36,15 +55,29 @@ const RenderLayer = memo(
|
|
|
36
55
|
() => resolveVariableReferences(layer.props, effectiveVariables, variableValues),
|
|
37
56
|
[layer.props, effectiveVariables, variableValues]
|
|
38
57
|
);
|
|
39
|
-
const childProps = useMemo(() => ({ ...resolvedProps }), [resolvedProps]);
|
|
40
58
|
const childEditorConfig = useMemo(() => {
|
|
41
59
|
return editorConfig ? { ...editorConfig, zIndex: editorConfig.zIndex + 1, parentUpdated: editorConfig.parentUpdated || !isDeepEqual(prevLayer.current, layer) } : void 0;
|
|
42
60
|
}, [editorConfig, layer]);
|
|
61
|
+
const isBeingDragged = useMemo(
|
|
62
|
+
() => isLayerBeingDraggedOrDescendant(layer.id, dndContext.activeLayerId, pages),
|
|
63
|
+
[layer.id, dndContext.activeLayerId, pages]
|
|
64
|
+
);
|
|
65
|
+
const isRootDraggedLayer = layer.id === dndContext.activeLayerId;
|
|
43
66
|
const canAcceptChildren = useMemo(() => canLayerAcceptChildren(layer, registry), [layer, registry]);
|
|
44
67
|
const showDropZones = useMemo(
|
|
45
|
-
() => editorConfig && dndContext.isDragging && canAcceptChildren,
|
|
46
|
-
[editorConfig, dndContext.isDragging, canAcceptChildren]
|
|
68
|
+
() => editorConfig && dndContext.isDragging && canAcceptChildren && !isBeingDragged,
|
|
69
|
+
[editorConfig, dndContext.isDragging, canAcceptChildren, isBeingDragged]
|
|
47
70
|
);
|
|
71
|
+
const childProps = useMemo(() => {
|
|
72
|
+
const props = { ...resolvedProps };
|
|
73
|
+
if (showDropZones && hasLayerChildren(layer)) {
|
|
74
|
+
const existingClassName = props.className || "";
|
|
75
|
+
if (!hasPositionClass(existingClassName)) {
|
|
76
|
+
props.className = existingClassName ? `${existingClassName} relative` : "relative";
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return props;
|
|
80
|
+
}, [resolvedProps, showDropZones, layer]);
|
|
48
81
|
if (!componentDefinition) {
|
|
49
82
|
console.error(
|
|
50
83
|
`[UIBuilder] Component definition not found in registry:`,
|
|
@@ -73,7 +106,7 @@ const RenderLayer = memo(
|
|
|
73
106
|
child.id
|
|
74
107
|
);
|
|
75
108
|
if (showDropZones) {
|
|
76
|
-
return /* @__PURE__ */ jsxs(
|
|
109
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
77
110
|
/* @__PURE__ */ jsx(
|
|
78
111
|
DropPlaceholder,
|
|
79
112
|
{
|
|
@@ -88,21 +121,30 @@ const RenderLayer = memo(
|
|
|
88
121
|
return childElement;
|
|
89
122
|
});
|
|
90
123
|
if (showDropZones) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
124
|
+
childElements.push(
|
|
125
|
+
/* @__PURE__ */ jsx(
|
|
126
|
+
DropPlaceholder,
|
|
127
|
+
{
|
|
128
|
+
parentId: layer.id,
|
|
129
|
+
position: layer.children.length,
|
|
130
|
+
isActive: true
|
|
131
|
+
},
|
|
132
|
+
`drop-${layer.id}-${layer.children.length}`
|
|
133
|
+
)
|
|
134
|
+
);
|
|
100
135
|
}
|
|
101
136
|
childProps.children = childElements;
|
|
137
|
+
} else if (isVariableReference(layer.children)) {
|
|
138
|
+
const resolvedChildren = resolveChildrenVariableReference(
|
|
139
|
+
layer.children,
|
|
140
|
+
effectiveVariables,
|
|
141
|
+
variableValues
|
|
142
|
+
);
|
|
143
|
+
childProps.children = resolvedChildren;
|
|
102
144
|
} else if (typeof layer.children === "string") {
|
|
103
145
|
childProps.children = layer.children;
|
|
104
146
|
} else if (showDropZones && hasLayerChildren(layer)) {
|
|
105
|
-
childProps.children = /* @__PURE__ */ jsx("div", { className: "
|
|
147
|
+
childProps.children = /* @__PURE__ */ jsx("div", { className: "min-h-[2rem] w-full", children: /* @__PURE__ */ jsx(
|
|
106
148
|
DropPlaceholder,
|
|
107
149
|
{
|
|
108
150
|
parentId: layer.id,
|
|
@@ -112,8 +154,19 @@ const RenderLayer = memo(
|
|
|
112
154
|
) });
|
|
113
155
|
}
|
|
114
156
|
const WrappedComponent = isPrimitive ? /* @__PURE__ */ jsx(Component, { id: layer.id, "data-testid": layer.id, "data-layer-id": layer.id, ...childProps }) : /* @__PURE__ */ jsx(ErrorSuspenseWrapper, { id: layer.id, children: /* @__PURE__ */ jsx(Component, { "data-testid": layer.id, "data-layer-id": layer.id, ...childProps }) }, layer.id);
|
|
157
|
+
const DragFeedbackWrapper = isRootDraggedLayer ? /* @__PURE__ */ jsxs(
|
|
158
|
+
"div",
|
|
159
|
+
{
|
|
160
|
+
className: "relative opacity-50 pointer-events-none",
|
|
161
|
+
"data-dragging": "true",
|
|
162
|
+
children: [
|
|
163
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-primary/20 rounded pointer-events-none z-10" }),
|
|
164
|
+
WrappedComponent
|
|
165
|
+
]
|
|
166
|
+
}
|
|
167
|
+
) : WrappedComponent;
|
|
115
168
|
if (!editorConfig) {
|
|
116
|
-
return
|
|
169
|
+
return DragFeedbackWrapper;
|
|
117
170
|
} else {
|
|
118
171
|
const {
|
|
119
172
|
zIndex,
|
|
@@ -139,7 +192,7 @@ const RenderLayer = memo(
|
|
|
139
192
|
totalLayers,
|
|
140
193
|
onDuplicateLayer: handleDuplicateLayer,
|
|
141
194
|
onDeleteLayer: handleDeleteLayer,
|
|
142
|
-
children:
|
|
195
|
+
children: DragFeedbackWrapper
|
|
143
196
|
},
|
|
144
197
|
layer.id
|
|
145
198
|
)
|
|
@@ -168,4 +221,4 @@ const ErrorSuspenseWrapper = ({ children }) => {
|
|
|
168
221
|
};
|
|
169
222
|
const LoadingComponent = () => /* @__PURE__ */ jsx("div", { children: "Loading..." });
|
|
170
223
|
|
|
171
|
-
export { RenderLayer };
|
|
224
|
+
export { RenderLayer, hasPositionClass };
|
|
@@ -138,17 +138,22 @@ const getTransformState = () => {
|
|
|
138
138
|
const transform = computedStyle.transform;
|
|
139
139
|
if (transform && transform !== "none") {
|
|
140
140
|
const matrixMatch = transform.match(/matrix\(([^)]*)\)/);
|
|
141
|
-
if (matrixMatch) {
|
|
141
|
+
if (matrixMatch && matrixMatch[1]) {
|
|
142
142
|
const values = matrixMatch[1].split(",").map((v) => parseFloat(v.trim()));
|
|
143
143
|
if (values.length >= 6) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
144
|
+
const scale = values[0];
|
|
145
|
+
const positionX = values[4];
|
|
146
|
+
const positionY = values[5];
|
|
147
|
+
if (scale !== void 0 && positionX !== void 0 && positionY !== void 0) {
|
|
148
|
+
transformState = {
|
|
149
|
+
scale,
|
|
150
|
+
// scaleX
|
|
151
|
+
positionX,
|
|
152
|
+
// translateX
|
|
153
|
+
positionY
|
|
154
|
+
// translateY
|
|
155
|
+
};
|
|
156
|
+
}
|
|
152
157
|
}
|
|
153
158
|
}
|
|
154
159
|
}
|
|
@@ -136,17 +136,22 @@ const getTransformState = () => {
|
|
|
136
136
|
const transform = computedStyle.transform;
|
|
137
137
|
if (transform && transform !== "none") {
|
|
138
138
|
const matrixMatch = transform.match(/matrix\(([^)]*)\)/);
|
|
139
|
-
if (matrixMatch) {
|
|
139
|
+
if (matrixMatch && matrixMatch[1]) {
|
|
140
140
|
const values = matrixMatch[1].split(",").map((v) => parseFloat(v.trim()));
|
|
141
141
|
if (values.length >= 6) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
142
|
+
const scale = values[0];
|
|
143
|
+
const positionX = values[4];
|
|
144
|
+
const positionY = values[5];
|
|
145
|
+
if (scale !== void 0 && positionX !== void 0 && positionY !== void 0) {
|
|
146
|
+
transformState = {
|
|
147
|
+
scale,
|
|
148
|
+
// scaleX
|
|
149
|
+
positionX,
|
|
150
|
+
// translateX
|
|
151
|
+
positionY
|
|
152
|
+
// translateY
|
|
153
|
+
};
|
|
154
|
+
}
|
|
150
155
|
}
|
|
151
156
|
}
|
|
152
157
|
}
|