@jbpark/live-editor 4.4.0 → 4.6.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/README.ko.md +4 -1
- package/README.md +7 -3
- package/dist/{boundary-B17cepvm.js → boundary-BLB80tyw.js} +8 -5
- package/dist/boundary-BLB80tyw.js.map +1 -0
- package/dist/cache-B0-XcIxJ.js.map +1 -1
- package/dist/{compile-DDfk5P25.js → compile-Dxas-D05.js} +3 -3
- package/dist/compile-Dxas-D05.js.map +1 -0
- package/dist/{constants-h1JAgOeW.js → constants-DU17Tdwo.js} +3 -3
- package/dist/constants-DU17Tdwo.js.map +1 -0
- package/dist/{context-DB5kW3qe.js → context-B8MzP7_p.js} +11 -5
- package/dist/context-B8MzP7_p.js.map +1 -0
- package/dist/{core-CRsAGpei.js → core-Bgfek364.js} +2 -2
- package/dist/core-Bgfek364.js.map +1 -0
- package/dist/{detect-typescript-CCj9ALXc.js → detect-typescript-Dr_oLniM.js} +2 -2
- package/dist/detect-typescript-Dr_oLniM.js.map +1 -0
- package/dist/dnd/index.d.ts +1 -1
- package/dist/dnd/index.js +1 -1
- package/dist/{dnd-BE5ZizqX.js → dnd-UoJILA75.js} +973 -885
- package/dist/dnd-UoJILA75.js.map +1 -0
- package/dist/{document-BDn_f08_.js → document-CGbe6bSV.js} +7739 -7736
- package/dist/document-CGbe6bSV.js.map +1 -0
- package/dist/editor/index.js +2 -2
- package/dist/{editor-DQ8Q--qR.js → editor-CMElfHer.js} +2 -2
- package/dist/editor-CMElfHer.js.map +1 -0
- package/dist/editor-caches-ClMvdcQF.js.map +1 -1
- package/dist/error/index.d.ts +1 -1
- package/dist/error/index.js +2 -2
- package/dist/{error-DWhxQEom.js → error-CN_GCnXB.js} +13 -6
- package/dist/error-CN_GCnXB.js.map +1 -0
- package/dist/{index-Dgh1JTX3.d.ts → index-C69Lv-jR.d.ts} +72 -69
- package/dist/{index-C4SGQ3Ci.d.ts → index-CRwEhJ7w.d.ts} +4 -1
- package/dist/{index-f7ijuNTa.d.ts → index-DKYUxi-E.d.ts} +115 -155
- package/dist/index-DrWtSKXu.d.ts +11 -0
- package/dist/index.d.ts +18 -18
- package/dist/index.js +12 -8
- package/dist/index.js.map +1 -1
- package/dist/{ast-dYb78955.js → items-B6OXxcLG.js} +588 -718
- package/dist/items-B6OXxcLG.js.map +1 -0
- package/dist/messages-CSrMI4Rm.js +133 -0
- package/dist/messages-CSrMI4Rm.js.map +1 -0
- package/dist/messages-IBPs4TkZ.d.ts +130 -0
- package/dist/preview/index.js +2 -2
- package/dist/{preview-BnaCEFsF.js → preview-CtyG5UbH.js} +6 -4
- package/dist/preview-CtyG5UbH.js.map +1 -0
- package/dist/provider/index.d.ts +3 -8
- package/dist/provider/index.js +3 -2
- package/dist/{sections-CBVMO8Jl.js → sections-BYWOBISr.js} +9 -4
- package/dist/sections-BYWOBISr.js.map +1 -0
- package/dist/states-Ci1AvoQ9.js.map +1 -1
- package/dist/style.css +505 -21
- package/dist/{use-dynamic-tailwind-Bcipc1hL.js → use-dynamic-tailwind-BP1toJkW.js} +66 -40
- package/dist/use-dynamic-tailwind-BP1toJkW.js.map +1 -0
- package/dist/utils/ast/index.d.ts +3 -2
- package/dist/utils/ast/index.js +150 -3
- package/dist/utils/ast/index.js.map +1 -0
- package/dist/utils/index.d.ts +30 -13
- package/dist/utils/index.js +26 -6
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/tailwind/index.js.map +1 -1
- package/dist/validate-DB59Z_Nx.d.ts +100 -0
- package/dist/validate-iLo8IONY.js +64 -0
- package/dist/validate-iLo8IONY.js.map +1 -0
- package/package.json +3 -3
- package/dist/ast-dYb78955.js.map +0 -1
- package/dist/boundary-B17cepvm.js.map +0 -1
- package/dist/compile-DDfk5P25.js.map +0 -1
- package/dist/constants-h1JAgOeW.js.map +0 -1
- package/dist/context-DB5kW3qe.js.map +0 -1
- package/dist/core-CRsAGpei.js.map +0 -1
- package/dist/detect-typescript-CCj9ALXc.js.map +0 -1
- package/dist/dnd-BE5ZizqX.js.map +0 -1
- package/dist/document-BDn_f08_.js.map +0 -1
- package/dist/editor-DQ8Q--qR.js.map +0 -1
- package/dist/error-DWhxQEom.js.map +0 -1
- package/dist/preview-BnaCEFsF.js.map +0 -1
- package/dist/sections-CBVMO8Jl.js.map +0 -1
- package/dist/use-dynamic-tailwind-Bcipc1hL.js.map +0 -1
|
@@ -1,133 +1,91 @@
|
|
|
1
|
-
import { S as require_lib,
|
|
2
|
-
import { c as RESERVED_BINDING_PROPERTIES, o as
|
|
1
|
+
import { S as require_lib, c as inspectDocument, h as replaceIds, m as fillIdsFrom, n as createSectionPreviewCache, r as fillSectionIds, w as __toESM, x as nanoid } from "./document-CGbe6bSV.js";
|
|
2
|
+
import { c as RESERVED_BINDING_PROPERTIES, o as PALETTE_SECTIONS, r as DATA_ATTR, t as BINDING_PROP } from "./constants-DU17Tdwo.js";
|
|
3
|
+
import { n as validateBindingValue } from "./validate-iLo8IONY.js";
|
|
4
|
+
import { i as useLiveMessages } from "./messages-CSrMI4Rm.js";
|
|
3
5
|
import { i as usePreview } from "./states-Ci1AvoQ9.js";
|
|
4
|
-
import {
|
|
6
|
+
import { A as extractNodeValue, C as getStructuredValue, D as readNodeBindings, M as parseArrayExpression, N as parseValue, b as getCurrentValue, c as updateArrayItemValue, f as updateAll, g as moveSelectedIndices, h as getChildrenSignatures, i as moveArrayItems, j as extractObjectProperties, k as canLosslesslyEvaluateSource, l as canStructurallyEditArray, n as duplicateArrayItems, o as removeArrayItems, r as moveArrayItem, s as updateArrayItemProperty, t as appendArrayItem, v as extract, y as findEditableChildren } from "./items-B6OXxcLG.js";
|
|
5
7
|
import { t as cn } from "./cn-CAnad2vL.js";
|
|
6
|
-
import { o as preloadScripts } from "./compile-
|
|
7
|
-
import { a as
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { Children, createContext, memo, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
8
|
+
import { o as preloadScripts } from "./compile-Dxas-D05.js";
|
|
9
|
+
import { a as useStableModules, i as Frame, n as useCompiledModule, t as useDynamicTailwind } from "./use-dynamic-tailwind-BP1toJkW.js";
|
|
10
|
+
import { i as generateSection, o as replaceSections, r as extractSections } from "./sections-BYWOBISr.js";
|
|
11
|
+
import { n as Error$1, t as ErrorBoundary } from "./boundary-BLB80tyw.js";
|
|
12
|
+
import { t as Core } from "./core-Bgfek364.js";
|
|
13
|
+
import { Children, createContext, memo, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
12
14
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
13
15
|
import { DndContext, DragOverlay, KeyboardSensor, MouseSensor, PointerSensor, TouchSensor, closestCenter, useDndContext, useDraggable, useDroppable, useSensor, useSensors } from "@dnd-kit/core";
|
|
14
16
|
import { restrictToParentElement, restrictToVerticalAxis } from "@dnd-kit/modifiers";
|
|
15
17
|
import { SortableContext, arrayMove, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
|
|
16
18
|
import { Button, Card, Checkbox, ColorPicker, DatePicker, Drawer, Input, RichTextEditor, Select, Space, Splitter, Toast, Typography } from "@jbpark/ui-kit";
|
|
17
19
|
import { useDebounce, useMultiSelect, useResponsiveSize } from "@jbpark/use-hooks";
|
|
18
|
-
import { createPortal } from "react-dom";
|
|
19
|
-
import { ArrowDown, ArrowUp, ChevronDown, ChevronRight, ChevronUp, Copy, Crosshair, GripVertical, LayoutGrid, Plus, Trash, X } from "lucide-react";
|
|
20
20
|
import { CSS as CSS$1 } from "@dnd-kit/utilities";
|
|
21
|
-
|
|
21
|
+
import { ArrowDown, ArrowUp, ChevronDown, ChevronRight, ChevronUp, Copy, Crosshair, GripVertical, LayoutGrid, Plus, Trash, X } from "lucide-react";
|
|
22
|
+
//#region src/components/dnd/palette/palette-drag.ts
|
|
22
23
|
var import_lib = /* @__PURE__ */ __toESM(require_lib(), 1);
|
|
24
|
+
const PALETTE_SECTION = "palette-section";
|
|
25
|
+
const paletteDragData = (section) => ({
|
|
26
|
+
type: PALETTE_SECTION,
|
|
27
|
+
section
|
|
28
|
+
});
|
|
29
|
+
const paletteSectionOf = (data) => {
|
|
30
|
+
const current = data?.current;
|
|
31
|
+
return current?.type === PALETTE_SECTION ? current.section : void 0;
|
|
32
|
+
};
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/components/dnd/canvas/droppable.tsx
|
|
23
35
|
const Droppable = ({ children, className }) => {
|
|
24
36
|
const { setNodeRef, isOver, active } = useDroppable({ id: "sortable-area" });
|
|
25
37
|
const { setNodeRef: setBottomRef, isOver: isBottomOver } = useDroppable({ id: "sortable-area-bottom" });
|
|
26
|
-
const
|
|
27
|
-
const shouldHighlight = isOver &&
|
|
28
|
-
const shouldHighlightBottom = isBottomOver &&
|
|
38
|
+
const isPaletteSectionDragging = !!paletteSectionOf(active?.data);
|
|
39
|
+
const shouldHighlight = isOver && isPaletteSectionDragging;
|
|
40
|
+
const shouldHighlightBottom = isBottomOver && isPaletteSectionDragging;
|
|
41
|
+
const messages = useLiveMessages();
|
|
29
42
|
return /* @__PURE__ */ jsxs("div", {
|
|
30
43
|
ref: setNodeRef,
|
|
31
44
|
className: cn("min-h-full", "border-2 border-dashed p-1", shouldHighlight ? "border-blue-300 bg-blue-50" : "border-gray-200", className),
|
|
32
|
-
children: [children,
|
|
45
|
+
children: [children, isPaletteSectionDragging && /* @__PURE__ */ jsx("div", {
|
|
33
46
|
ref: setBottomRef,
|
|
34
47
|
className: cn("mt-2 min-h-24", "rounded-lg border-2 border-dashed", "transition-all duration-200", "flex items-center justify-center", shouldHighlightBottom ? "border-blue-400 bg-blue-100" : "border-gray-300 bg-gray-50"),
|
|
35
48
|
children: /* @__PURE__ */ jsx(Typography.Text, {
|
|
36
49
|
className: "text-sm text-gray-500",
|
|
37
|
-
children: shouldHighlightBottom ?
|
|
50
|
+
children: shouldHighlightBottom ? messages.canvas.dropHere : messages.canvas.dropAtBottom
|
|
38
51
|
})
|
|
39
52
|
})]
|
|
40
53
|
});
|
|
41
54
|
};
|
|
42
55
|
//#endregion
|
|
43
|
-
//#region src/components/dnd/
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
};
|
|
70
|
-
const hasId = (element) => Boolean(element.getAttribute(DATA_ATTR.ID));
|
|
71
|
-
const pickElement = (section, overlay, x, y) => {
|
|
72
|
-
let element = deepestAt(section.ownerDocument, x, y, (candidate) => candidate === overlay || candidate === section || !section.contains(candidate));
|
|
73
|
-
while (element && element !== section && !hasId(element)) element = element.parentElement ?? element.parentNode?.host ?? null;
|
|
74
|
-
return element === section ? null : element;
|
|
75
|
-
};
|
|
76
|
-
const findElementById = (section, id) => {
|
|
77
|
-
const selector = `[${DATA_ATTR.ID}="${CSS.escape(id)}"]`;
|
|
78
|
-
const roots = [section];
|
|
79
|
-
for (const root of roots) {
|
|
80
|
-
const found = root.querySelector(selector);
|
|
81
|
-
if (found) return found;
|
|
82
|
-
root.querySelectorAll("iframe").forEach((frame) => {
|
|
83
|
-
if (frame.contentDocument) roots.push(frame.contentDocument);
|
|
84
|
-
});
|
|
85
|
-
root.querySelectorAll("*").forEach((element) => {
|
|
86
|
-
if (element.shadowRoot) roots.push(element.shadowRoot);
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
return null;
|
|
90
|
-
};
|
|
91
|
-
const viewportRect = (element) => {
|
|
92
|
-
const rect = element.getBoundingClientRect();
|
|
93
|
-
let x = rect.left;
|
|
94
|
-
let y = rect.top;
|
|
95
|
-
let frame = element.ownerDocument.defaultView?.frameElement ?? null;
|
|
96
|
-
while (frame) {
|
|
97
|
-
const frameRect = frame.getBoundingClientRect();
|
|
98
|
-
x += frameRect.left;
|
|
99
|
-
y += frameRect.top;
|
|
100
|
-
frame = frame.ownerDocument.defaultView?.frameElement ?? null;
|
|
101
|
-
}
|
|
102
|
-
return new DOMRect(x, y, rect.width, rect.height);
|
|
56
|
+
//#region src/components/dnd/canvas/inspector-highlight.tsx
|
|
57
|
+
const InspectorHighlight = ({ rect }) => {
|
|
58
|
+
const ref = useRef(null);
|
|
59
|
+
useLayoutEffect(() => {
|
|
60
|
+
const box = ref.current;
|
|
61
|
+
const container = box?.closest("[data-frame-container]");
|
|
62
|
+
if (!box || !rect || !container) return;
|
|
63
|
+
const outer = container.getBoundingClientRect();
|
|
64
|
+
box.style.left = `${rect.left - outer.left - container.clientLeft + container.scrollLeft}px`;
|
|
65
|
+
box.style.top = `${rect.top - outer.top - container.clientTop + container.scrollTop}px`;
|
|
66
|
+
box.style.width = `${rect.width}px`;
|
|
67
|
+
box.style.height = `${rect.height}px`;
|
|
68
|
+
}, [rect]);
|
|
69
|
+
return rect ? /* @__PURE__ */ jsx("div", {
|
|
70
|
+
ref,
|
|
71
|
+
"aria-hidden": true,
|
|
72
|
+
"data-dnd-inspector-highlight": true,
|
|
73
|
+
style: {
|
|
74
|
+
position: "absolute",
|
|
75
|
+
pointerEvents: "none",
|
|
76
|
+
outline: "2px solid #3b82f6",
|
|
77
|
+
outlineOffset: -1,
|
|
78
|
+
background: "rgba(59, 130, 246, 0.12)",
|
|
79
|
+
zIndex: 65
|
|
80
|
+
}
|
|
81
|
+
}) : null;
|
|
103
82
|
};
|
|
104
83
|
//#endregion
|
|
105
|
-
//#region src/components/dnd/
|
|
106
|
-
const InspectorHighlight = ({ rect }) => rect ? createPortal(/* @__PURE__ */ jsx("div", {
|
|
107
|
-
"aria-hidden": true,
|
|
108
|
-
"data-dnd-inspector-highlight": true,
|
|
109
|
-
style: {
|
|
110
|
-
position: "fixed",
|
|
111
|
-
left: rect.left,
|
|
112
|
-
top: rect.top,
|
|
113
|
-
width: rect.width,
|
|
114
|
-
height: rect.height,
|
|
115
|
-
pointerEvents: "none",
|
|
116
|
-
outline: "2px solid #3b82f6",
|
|
117
|
-
outlineOffset: -1,
|
|
118
|
-
background: "rgba(59, 130, 246, 0.12)",
|
|
119
|
-
zIndex: 2147483647
|
|
120
|
-
}
|
|
121
|
-
}), document.body) : null;
|
|
122
|
-
//#endregion
|
|
123
|
-
//#region src/components/dnd/draggable.tsx
|
|
84
|
+
//#region src/components/dnd/palette/draggable.tsx
|
|
124
85
|
const DraggableItem = ({ item, children }) => {
|
|
125
86
|
const { attributes, listeners, setNodeRef, isDragging } = useDraggable({
|
|
126
87
|
id: item.id,
|
|
127
|
-
data:
|
|
128
|
-
type: "new-item",
|
|
129
|
-
item
|
|
130
|
-
}
|
|
88
|
+
data: paletteDragData(item)
|
|
131
89
|
});
|
|
132
90
|
return children({
|
|
133
91
|
ref: setNodeRef,
|
|
@@ -158,173 +116,475 @@ const DefaultDraggableItem = ({ item, onAdd, tapToAdd = false }) => /* @__PURE__
|
|
|
158
116
|
})
|
|
159
117
|
});
|
|
160
118
|
//#endregion
|
|
161
|
-
//#region src/components/dnd/
|
|
162
|
-
const
|
|
163
|
-
const useDndRegions = (subject) => {
|
|
164
|
-
const regions = useContext(DndRegionContext);
|
|
165
|
-
if (!regions) throw new Error(`${subject} must be used inside <Live.Dnd>.`);
|
|
166
|
-
return regions;
|
|
167
|
-
};
|
|
168
|
-
const useDndPalette = () => useDndRegions("useDndPalette()").palette;
|
|
169
|
-
const useDndPanel = () => useDndRegions("useDndPanel()").panel;
|
|
170
|
-
const useDndLayout = () => useDndRegions("useDndLayout()");
|
|
119
|
+
//#region src/components/dnd/canvas/section-fallback-context.ts
|
|
120
|
+
const SectionFallbackContext = createContext(void 0);
|
|
171
121
|
//#endregion
|
|
172
|
-
//#region src/components/dnd/
|
|
173
|
-
const
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
if (binding.property === "children" || binding.property === "innerText" || binding.property === "innerHTML" || binding.property === "items" || binding.property === "data" || binding.type === "array" || binding.type === "jsx" || binding.type === "richtext") return true;
|
|
177
|
-
const attribute = node.attributes.find((candidate) => candidate.name === binding.property);
|
|
178
|
-
if (!attribute) return true;
|
|
179
|
-
return attribute.isStringLiteral === true || canLosslesslyEvaluateSource(attribute?.value ?? "");
|
|
180
|
-
};
|
|
181
|
-
const toBindingFields = (binding) => ({
|
|
182
|
-
label: binding.label,
|
|
183
|
-
property: binding.property,
|
|
184
|
-
type: binding.type,
|
|
185
|
-
widget: binding.widget,
|
|
186
|
-
options: binding.options,
|
|
187
|
-
render: binding.render,
|
|
188
|
-
min: binding.min,
|
|
189
|
-
max: binding.max,
|
|
190
|
-
pattern: binding.pattern,
|
|
191
|
-
required: binding.required,
|
|
192
|
-
meta: binding.meta
|
|
193
|
-
});
|
|
194
|
-
const resolveRenderEntry = (render, key) => {
|
|
195
|
-
const entry = render?.[key];
|
|
196
|
-
if (entry && "type" in entry) {
|
|
197
|
-
const leaf = entry;
|
|
198
|
-
return {
|
|
199
|
-
...leaf,
|
|
200
|
-
label: leaf.label ?? key,
|
|
201
|
-
property: leaf.property ?? key
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
return {
|
|
205
|
-
label: key,
|
|
206
|
-
property: key,
|
|
207
|
-
render: entry
|
|
208
|
-
};
|
|
209
|
-
};
|
|
210
|
-
const CONTENT_PROPERTIES = /* @__PURE__ */ new Set([
|
|
211
|
-
"innerText",
|
|
212
|
-
"innerHTML",
|
|
213
|
-
"children"
|
|
214
|
-
]);
|
|
215
|
-
const isAttributeAbsent = (node, binding) => !CONTENT_PROPERTIES.has(binding.property) && !node.attributes.some((candidate) => candidate.name === binding.property);
|
|
216
|
-
const toPanelBindingData = (node, id, binding) => ({
|
|
217
|
-
...toBindingFields(binding),
|
|
218
|
-
id,
|
|
219
|
-
value: getStructuredValue(node, binding.property, binding.type),
|
|
220
|
-
rawValue: getCurrentValue(node, binding.property),
|
|
221
|
-
...!canEditBindingValue(node, binding) && { canEditValue: false },
|
|
222
|
-
...isAttributeAbsent(node, binding) && { present: false },
|
|
223
|
-
element: {
|
|
224
|
-
tagName: node.tagName || "element",
|
|
225
|
-
text: node.textContent.replace(/\s+/g, " ").trim()
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
const resolvePanelBindings = (node) => {
|
|
229
|
-
const id = readAttribute(node, "data-id");
|
|
230
|
-
if (!id) return null;
|
|
231
|
-
const parsed = readNodeBindings(node);
|
|
232
|
-
if (!parsed.length) return null;
|
|
233
|
-
return {
|
|
234
|
-
id,
|
|
235
|
-
tagName: node.tagName || "element",
|
|
236
|
-
bindings: parsed.map((binding) => toPanelBindingData(node, id, binding))
|
|
237
|
-
};
|
|
122
|
+
//#region src/components/dnd/canvas/section-fallback.tsx
|
|
123
|
+
const ConsumerFallback = ({ render, args, builtin }) => {
|
|
124
|
+
const node = render(args);
|
|
125
|
+
return node === void 0 ? builtin : /* @__PURE__ */ jsx(Fragment, { children: node });
|
|
238
126
|
};
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
//#region src/components/dnd/panel/bulk-actions-bar.tsx
|
|
250
|
-
const BulkActionsBar = ({ count, disabled = false, onDuplicate, onMoveUp, onMoveDown, onDelete, onClear }) => {
|
|
251
|
-
if (count === 0) return null;
|
|
252
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
253
|
-
className: "flex items-center justify-between rounded border\n border-blue-200 bg-blue-50 p-2",
|
|
254
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
255
|
-
className: "text-xs font-medium text-blue-700",
|
|
256
|
-
children: [count, " selected"]
|
|
257
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
258
|
-
className: "flex items-center space-x-1",
|
|
259
|
-
children: [
|
|
260
|
-
/* @__PURE__ */ jsx(Button, {
|
|
261
|
-
size: "small",
|
|
262
|
-
icon: /* @__PURE__ */ jsx(Copy, {}),
|
|
263
|
-
title: "Duplicate selected",
|
|
264
|
-
disabled,
|
|
265
|
-
onClick: onDuplicate
|
|
266
|
-
}),
|
|
267
|
-
/* @__PURE__ */ jsx(Button, {
|
|
268
|
-
size: "small",
|
|
269
|
-
icon: /* @__PURE__ */ jsx(ArrowUp, {}),
|
|
270
|
-
title: "Move selected up",
|
|
271
|
-
disabled,
|
|
272
|
-
onClick: onMoveUp
|
|
273
|
-
}),
|
|
274
|
-
/* @__PURE__ */ jsx(Button, {
|
|
275
|
-
size: "small",
|
|
276
|
-
icon: /* @__PURE__ */ jsx(ArrowDown, {}),
|
|
277
|
-
title: "Move selected down",
|
|
278
|
-
disabled,
|
|
279
|
-
onClick: onMoveDown
|
|
280
|
-
}),
|
|
281
|
-
/* @__PURE__ */ jsx(Button, {
|
|
282
|
-
danger: true,
|
|
283
|
-
size: "small",
|
|
284
|
-
icon: /* @__PURE__ */ jsx(X, {}),
|
|
285
|
-
title: "Delete selected",
|
|
286
|
-
disabled,
|
|
287
|
-
onClick: onDelete
|
|
288
|
-
}),
|
|
289
|
-
/* @__PURE__ */ jsx(Button, {
|
|
290
|
-
size: "small",
|
|
291
|
-
onClick: onClear,
|
|
292
|
-
children: "Clear"
|
|
293
|
-
})
|
|
294
|
-
]
|
|
295
|
-
})]
|
|
127
|
+
const SectionFallback = ({ args, builtin }) => {
|
|
128
|
+
const render = useContext(SectionFallbackContext);
|
|
129
|
+
if (!render) return builtin;
|
|
130
|
+
return /* @__PURE__ */ jsx(ErrorBoundary, {
|
|
131
|
+
fallback: () => builtin,
|
|
132
|
+
children: /* @__PURE__ */ jsx(ConsumerFallback, {
|
|
133
|
+
render,
|
|
134
|
+
args,
|
|
135
|
+
builtin
|
|
136
|
+
})
|
|
296
137
|
});
|
|
297
138
|
};
|
|
298
139
|
//#endregion
|
|
299
|
-
//#region src/components/dnd/
|
|
300
|
-
const
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
binding,
|
|
321
|
-
onNodeChange: onChange
|
|
322
|
-
})]
|
|
323
|
-
}, `${binding.id}-${binding.property}`))
|
|
140
|
+
//#region src/components/dnd/canvas/renderer.tsx
|
|
141
|
+
const Renderer = ({ preview, sectionId = "", sectionName = "", sectionCode = preview, forceFallback = false, headers, modules, frame, dynamicTailwind = false, provider }) => {
|
|
142
|
+
const module = useCompiledModule(forceFallback ? "" : preview, modules);
|
|
143
|
+
const section = {
|
|
144
|
+
id: sectionId,
|
|
145
|
+
name: sectionName,
|
|
146
|
+
code: sectionCode
|
|
147
|
+
};
|
|
148
|
+
const messages = useLiveMessages();
|
|
149
|
+
const { ref: wrapperRef, css: dynamicCSS } = useDynamicTailwind(preview, dynamicTailwind && !forceFallback);
|
|
150
|
+
const renderProvider = (component) => {
|
|
151
|
+
return provider ? provider(component) : component;
|
|
152
|
+
};
|
|
153
|
+
if (forceFallback) return /* @__PURE__ */ jsx(SectionFallback, {
|
|
154
|
+
args: {
|
|
155
|
+
section,
|
|
156
|
+
reason: "forced"
|
|
157
|
+
},
|
|
158
|
+
builtin: /* @__PURE__ */ jsx(Error$1, {
|
|
159
|
+
message: messages.errors.sectionNotRendered,
|
|
160
|
+
title: messages.errors.sectionUnavailable
|
|
324
161
|
})
|
|
325
162
|
});
|
|
326
|
-
|
|
327
|
-
|
|
163
|
+
if (module?.error) return /* @__PURE__ */ jsx(SectionFallback, {
|
|
164
|
+
args: {
|
|
165
|
+
section,
|
|
166
|
+
reason: "compile",
|
|
167
|
+
message: module.error
|
|
168
|
+
},
|
|
169
|
+
builtin: /* @__PURE__ */ jsx(Error$1, {
|
|
170
|
+
message: module.error,
|
|
171
|
+
title: messages.errors.compile
|
|
172
|
+
})
|
|
173
|
+
});
|
|
174
|
+
const Component = module?.exports?.default;
|
|
175
|
+
if (!Component) return null;
|
|
176
|
+
return /* @__PURE__ */ jsx(Frame, {
|
|
177
|
+
...frame,
|
|
178
|
+
autoHeight: true,
|
|
179
|
+
children: (container) => /* @__PURE__ */ jsx("div", {
|
|
180
|
+
ref: wrapperRef,
|
|
181
|
+
className: "w-full overflow-x-hidden",
|
|
182
|
+
"data-editor-mode": true,
|
|
183
|
+
children: /* @__PURE__ */ jsx(ErrorBoundary, {
|
|
184
|
+
resetKeys: [preview],
|
|
185
|
+
fallback: (message, reset) => /* @__PURE__ */ jsx(SectionFallback, {
|
|
186
|
+
args: {
|
|
187
|
+
section,
|
|
188
|
+
reason: "runtime",
|
|
189
|
+
message
|
|
190
|
+
},
|
|
191
|
+
builtin: /* @__PURE__ */ jsx(Error$1, {
|
|
192
|
+
message,
|
|
193
|
+
onReset: reset,
|
|
194
|
+
title: messages.errors.rendering
|
|
195
|
+
})
|
|
196
|
+
}),
|
|
197
|
+
children: renderProvider(/* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Component, {
|
|
198
|
+
headers,
|
|
199
|
+
container
|
|
200
|
+
}), dynamicTailwind && dynamicCSS && /* @__PURE__ */ jsx("style", { children: dynamicCSS })] }))
|
|
201
|
+
})
|
|
202
|
+
})
|
|
203
|
+
});
|
|
204
|
+
};
|
|
205
|
+
const sameValue = (a, b) => {
|
|
206
|
+
if (Object.is(a, b)) return true;
|
|
207
|
+
if (Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((item, i) => Object.is(item, b[i]));
|
|
208
|
+
if (a && b && typeof a === "object" && typeof b === "object" && Object.getPrototypeOf(a) === Object.prototype && Object.getPrototypeOf(b) === Object.prototype) {
|
|
209
|
+
const aKeys = Object.keys(a);
|
|
210
|
+
return aKeys.length === Object.keys(b).length && aKeys.every((key) => Object.is(a[key], b[key]));
|
|
211
|
+
}
|
|
212
|
+
return false;
|
|
213
|
+
};
|
|
214
|
+
const sameFrame = (a, b) => {
|
|
215
|
+
if (a === b) return true;
|
|
216
|
+
if (!a || !b) return false;
|
|
217
|
+
return [.../* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)])].every((key) => sameValue(a[key], b[key]));
|
|
218
|
+
};
|
|
219
|
+
const arePropsEqual = (prev, next) => {
|
|
220
|
+
return [.../* @__PURE__ */ new Set([...Object.keys(prev), ...Object.keys(next)])].every((key) => key === "frame" ? sameFrame(prev.frame, next.frame) : Object.is(prev[key], next[key]));
|
|
221
|
+
};
|
|
222
|
+
var renderer_default = memo(Renderer, arePropsEqual);
|
|
223
|
+
//#endregion
|
|
224
|
+
//#region src/components/dnd/canvas/sortable.tsx
|
|
225
|
+
const NAVIGATION_KEYS = {
|
|
226
|
+
ArrowUp: "previous",
|
|
227
|
+
ArrowDown: "next",
|
|
228
|
+
Home: "first",
|
|
229
|
+
End: "last"
|
|
230
|
+
};
|
|
231
|
+
const Sortable = ({ id, children, selected, onClick, onDelete: _onDelete, onCopy: _onCopy, onMoveUp, onMoveDown, canMoveUp = false, canMoveDown = false, nodeRef, onNavigate, onDeleteKey, inspecting = false, onInspectMove, onInspectPick, onInspectLeave }) => {
|
|
232
|
+
const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging, isOver, active } = useSortable({
|
|
233
|
+
id,
|
|
234
|
+
disabled: inspecting
|
|
235
|
+
});
|
|
236
|
+
const messages = useLiveMessages();
|
|
237
|
+
const style = {
|
|
238
|
+
transform: CSS$1.Transform.toString(transform),
|
|
239
|
+
transition,
|
|
240
|
+
opacity: isDragging ? .5 : 1,
|
|
241
|
+
cursor: inspecting ? "crosshair" : "grab"
|
|
242
|
+
};
|
|
243
|
+
const isPaletteSectionOver = isOver && !!paletteSectionOf(active?.data);
|
|
244
|
+
const onKeyDown = (e) => {
|
|
245
|
+
listeners?.onKeyDown?.(e);
|
|
246
|
+
if (e.target !== e.currentTarget || active || e.defaultPrevented) return;
|
|
247
|
+
if (e.key === "Enter") {
|
|
248
|
+
e.preventDefault();
|
|
249
|
+
onClick?.();
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const to = NAVIGATION_KEYS[e.key];
|
|
253
|
+
if (to && onNavigate) {
|
|
254
|
+
e.preventDefault();
|
|
255
|
+
onNavigate(to);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
if ((e.key === "Delete" || e.key === "Backspace") && onDeleteKey) {
|
|
259
|
+
e.preventDefault();
|
|
260
|
+
onDeleteKey();
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
const setRefs = (node) => {
|
|
264
|
+
setNodeRef(node);
|
|
265
|
+
setActivatorNodeRef(node);
|
|
266
|
+
nodeRef?.(node);
|
|
267
|
+
};
|
|
268
|
+
const onDelete = (e) => {
|
|
269
|
+
e.stopPropagation();
|
|
270
|
+
_onDelete?.(id);
|
|
271
|
+
};
|
|
272
|
+
const onCopy = (e) => {
|
|
273
|
+
e.stopPropagation();
|
|
274
|
+
_onCopy?.(id);
|
|
275
|
+
};
|
|
276
|
+
const press = (action) => (e) => {
|
|
277
|
+
e.stopPropagation();
|
|
278
|
+
action?.();
|
|
279
|
+
};
|
|
280
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
281
|
+
ref: setRefs,
|
|
282
|
+
style,
|
|
283
|
+
...attributes,
|
|
284
|
+
...listeners,
|
|
285
|
+
onKeyDown,
|
|
286
|
+
onClick,
|
|
287
|
+
className: cn("relative", selected && "z-10 outline-2 outline-offset-2 outline-blue-500", isPaletteSectionOver && "border-t-4 border-t-green-500"),
|
|
288
|
+
children: [
|
|
289
|
+
/* @__PURE__ */ jsx("div", {
|
|
290
|
+
className: cn("absolute inset-0 z-50"),
|
|
291
|
+
onPointerMove: inspecting ? (e) => onInspectMove?.(e.currentTarget.parentElement, e.currentTarget, e.clientX, e.clientY) : void 0,
|
|
292
|
+
onPointerLeave: inspecting ? onInspectLeave : void 0,
|
|
293
|
+
onClick: inspecting ? (e) => {
|
|
294
|
+
e.stopPropagation();
|
|
295
|
+
onInspectPick?.(e.currentTarget.parentElement, e.currentTarget, e.clientX, e.clientY);
|
|
296
|
+
} : void 0
|
|
297
|
+
}),
|
|
298
|
+
children,
|
|
299
|
+
selected && /* @__PURE__ */ jsxs(Space, {
|
|
300
|
+
className: cn("absolute top-1 right-1 z-60"),
|
|
301
|
+
children: [
|
|
302
|
+
onMoveUp && /* @__PURE__ */ jsx(Button, {
|
|
303
|
+
icon: /* @__PURE__ */ jsx(ChevronUp, {}),
|
|
304
|
+
disabled: !canMoveUp,
|
|
305
|
+
onClick: press(onMoveUp),
|
|
306
|
+
"aria-label": messages.section.moveUp
|
|
307
|
+
}),
|
|
308
|
+
onMoveDown && /* @__PURE__ */ jsx(Button, {
|
|
309
|
+
icon: /* @__PURE__ */ jsx(ChevronDown, {}),
|
|
310
|
+
disabled: !canMoveDown,
|
|
311
|
+
onClick: press(onMoveDown),
|
|
312
|
+
"aria-label": messages.section.moveDown
|
|
313
|
+
}),
|
|
314
|
+
/* @__PURE__ */ jsx(Button, {
|
|
315
|
+
icon: /* @__PURE__ */ jsx(Copy, {}),
|
|
316
|
+
onClick: onCopy,
|
|
317
|
+
"aria-label": messages.section.duplicate
|
|
318
|
+
}),
|
|
319
|
+
/* @__PURE__ */ jsx(Button, {
|
|
320
|
+
danger: true,
|
|
321
|
+
icon: /* @__PURE__ */ jsx(Trash, {}),
|
|
322
|
+
onClick: onDelete,
|
|
323
|
+
"aria-label": messages.section.delete
|
|
324
|
+
})
|
|
325
|
+
]
|
|
326
|
+
})
|
|
327
|
+
]
|
|
328
|
+
});
|
|
329
|
+
};
|
|
330
|
+
//#endregion
|
|
331
|
+
//#region src/components/dnd/canvas/overlay.tsx
|
|
332
|
+
const Overlay = ({ sections, isForced, renderProps }) => {
|
|
333
|
+
const { active } = useDndContext();
|
|
334
|
+
if (!active) return null;
|
|
335
|
+
const paletteSection = paletteSectionOf(active.data);
|
|
336
|
+
if (paletteSection) return /* @__PURE__ */ jsx(DefaultDraggableItem, { item: paletteSection });
|
|
337
|
+
const section = sections.find((s) => s.id === active.id);
|
|
338
|
+
if (section) {
|
|
339
|
+
const preview = generateSection(section.code, renderProps.fullCode, { containerId: renderProps.containerId });
|
|
340
|
+
return /* @__PURE__ */ jsx(Sortable, {
|
|
341
|
+
id: section.id,
|
|
342
|
+
name: section.name,
|
|
343
|
+
children: /* @__PURE__ */ jsx(renderer_default, {
|
|
344
|
+
preview,
|
|
345
|
+
sectionId: section.id,
|
|
346
|
+
sectionName: section.name,
|
|
347
|
+
sectionCode: section.code,
|
|
348
|
+
forceFallback: isForced?.(section) ?? false,
|
|
349
|
+
modules: renderProps.modules,
|
|
350
|
+
frame: renderProps.frame,
|
|
351
|
+
dynamicTailwind: renderProps.dynamicTailwind
|
|
352
|
+
})
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
return null;
|
|
356
|
+
};
|
|
357
|
+
//#endregion
|
|
358
|
+
//#region src/components/dnd/edit-options.ts
|
|
359
|
+
const toastEditError = (error) => {
|
|
360
|
+
Toast.error(error.title, error.description ? { description: error.description } : void 0);
|
|
361
|
+
};
|
|
362
|
+
const DndEditOptionsContext = createContext({ reportError: toastEditError });
|
|
363
|
+
const useDndEditOptions = () => useContext(DndEditOptionsContext);
|
|
364
|
+
//#endregion
|
|
365
|
+
//#region src/components/dnd/inspector.ts
|
|
366
|
+
const DndInspectorContext = createContext(null);
|
|
367
|
+
const useDndInspector = () => {
|
|
368
|
+
const inspector = useContext(DndInspectorContext);
|
|
369
|
+
if (!inspector) throw new Error("useDndInspector() must be used inside <Live.Dnd>.");
|
|
370
|
+
return inspector;
|
|
371
|
+
};
|
|
372
|
+
const outside = (root) => (element) => element.getRootNode() !== root;
|
|
373
|
+
const deepestAt = (root, x, y, skip) => {
|
|
374
|
+
const element = root.elementsFromPoint(x, y).find((candidate) => !skip(candidate));
|
|
375
|
+
if (!element) return null;
|
|
376
|
+
if (element instanceof HTMLIFrameElement) {
|
|
377
|
+
const document = element.contentDocument;
|
|
378
|
+
if (!document) return element;
|
|
379
|
+
const rect = element.getBoundingClientRect();
|
|
380
|
+
return deepestAt(document, x - rect.left, y - rect.top, outside(document)) ?? element;
|
|
381
|
+
}
|
|
382
|
+
if (element.shadowRoot && element.shadowRoot !== root) return deepestAt(element.shadowRoot, x, y, outside(element.shadowRoot)) ?? element;
|
|
383
|
+
return element;
|
|
384
|
+
};
|
|
385
|
+
const hasId = (element) => Boolean(element.getAttribute(DATA_ATTR.ID));
|
|
386
|
+
const pickElement = (section, overlay, x, y) => {
|
|
387
|
+
let element = deepestAt(section.ownerDocument, x, y, (candidate) => candidate === overlay || candidate === section || !section.contains(candidate));
|
|
388
|
+
while (element && element !== section && !hasId(element)) element = element.parentElement ?? element.parentNode?.host ?? null;
|
|
389
|
+
return element === section ? null : element;
|
|
390
|
+
};
|
|
391
|
+
const findElementById = (section, id) => {
|
|
392
|
+
const selector = `[${DATA_ATTR.ID}="${CSS.escape(id)}"]`;
|
|
393
|
+
const roots = [section];
|
|
394
|
+
for (const root of roots) {
|
|
395
|
+
const found = root.querySelector(selector);
|
|
396
|
+
if (found) return found;
|
|
397
|
+
root.querySelectorAll("iframe").forEach((frame) => {
|
|
398
|
+
if (frame.contentDocument) roots.push(frame.contentDocument);
|
|
399
|
+
});
|
|
400
|
+
root.querySelectorAll("*").forEach((element) => {
|
|
401
|
+
if (element.shadowRoot) roots.push(element.shadowRoot);
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
return null;
|
|
405
|
+
};
|
|
406
|
+
const viewportRect = (element) => {
|
|
407
|
+
const rect = element.getBoundingClientRect();
|
|
408
|
+
let x = rect.left;
|
|
409
|
+
let y = rect.top;
|
|
410
|
+
let frame = element.ownerDocument.defaultView?.frameElement ?? null;
|
|
411
|
+
while (frame) {
|
|
412
|
+
const frameRect = frame.getBoundingClientRect();
|
|
413
|
+
x += frameRect.left;
|
|
414
|
+
y += frameRect.top;
|
|
415
|
+
frame = frame.ownerDocument.defaultView?.frameElement ?? null;
|
|
416
|
+
}
|
|
417
|
+
return new DOMRect(x, y, rect.width, rect.height);
|
|
418
|
+
};
|
|
419
|
+
//#endregion
|
|
420
|
+
//#region src/components/dnd/layout-context.ts
|
|
421
|
+
const DndRegionContext = createContext(null);
|
|
422
|
+
const useDndRegions = (subject) => {
|
|
423
|
+
const regions = useContext(DndRegionContext);
|
|
424
|
+
if (!regions) throw new Error(`${subject} must be used inside <Live.Dnd>.`);
|
|
425
|
+
return regions;
|
|
426
|
+
};
|
|
427
|
+
const useDndPalette = () => useDndRegions("useDndPalette()").palette;
|
|
428
|
+
const useDndPanel = () => useDndRegions("useDndPanel()").panel;
|
|
429
|
+
const useDndLayout = () => useDndRegions("useDndLayout()");
|
|
430
|
+
//#endregion
|
|
431
|
+
//#region src/components/dnd/panel-binding.ts
|
|
432
|
+
const readAttribute = (node, name) => node.dataAttributes.find((attribute) => attribute.name === name)?.value;
|
|
433
|
+
const canEditBindingValue = (node, binding) => {
|
|
434
|
+
if (RESERVED_BINDING_PROPERTIES.includes(binding.property)) return false;
|
|
435
|
+
if (binding.property === "children" || binding.property === "innerText" || binding.property === "innerHTML" || binding.property === "items" || binding.property === "data" || binding.type === "array" || binding.type === "jsx" || binding.type === "richtext") return true;
|
|
436
|
+
const attribute = node.attributes.find((candidate) => candidate.name === binding.property);
|
|
437
|
+
if (!attribute) return true;
|
|
438
|
+
return attribute.isStringLiteral === true || canLosslesslyEvaluateSource(attribute?.value ?? "");
|
|
439
|
+
};
|
|
440
|
+
const toBindingFields = (binding) => ({
|
|
441
|
+
label: binding.label,
|
|
442
|
+
property: binding.property,
|
|
443
|
+
type: binding.type,
|
|
444
|
+
widget: binding.widget,
|
|
445
|
+
options: binding.options,
|
|
446
|
+
render: binding.render,
|
|
447
|
+
min: binding.min,
|
|
448
|
+
max: binding.max,
|
|
449
|
+
pattern: binding.pattern,
|
|
450
|
+
required: binding.required,
|
|
451
|
+
meta: binding.meta
|
|
452
|
+
});
|
|
453
|
+
const resolveRenderEntry = (render, key) => {
|
|
454
|
+
const entry = render?.[key];
|
|
455
|
+
if (entry && "type" in entry) {
|
|
456
|
+
const leaf = entry;
|
|
457
|
+
return {
|
|
458
|
+
...leaf,
|
|
459
|
+
label: leaf.label ?? key,
|
|
460
|
+
property: leaf.property ?? key
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
return {
|
|
464
|
+
label: key,
|
|
465
|
+
property: key,
|
|
466
|
+
render: entry
|
|
467
|
+
};
|
|
468
|
+
};
|
|
469
|
+
const CONTENT_PROPERTIES = /* @__PURE__ */ new Set([
|
|
470
|
+
"innerText",
|
|
471
|
+
"innerHTML",
|
|
472
|
+
"children"
|
|
473
|
+
]);
|
|
474
|
+
const isAttributeAbsent = (node, binding) => !CONTENT_PROPERTIES.has(binding.property) && !node.attributes.some((candidate) => candidate.name === binding.property);
|
|
475
|
+
const toPanelBindingData = (node, id, binding) => ({
|
|
476
|
+
...toBindingFields(binding),
|
|
477
|
+
id,
|
|
478
|
+
value: getStructuredValue(node, binding.property, binding.type),
|
|
479
|
+
rawValue: getCurrentValue(node, binding.property),
|
|
480
|
+
...!canEditBindingValue(node, binding) && { canEditValue: false },
|
|
481
|
+
...isAttributeAbsent(node, binding) && { present: false },
|
|
482
|
+
element: {
|
|
483
|
+
tagName: node.tagName || "element",
|
|
484
|
+
text: node.textContent.replace(/\s+/g, " ").trim()
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
const resolvePanelBindings = (node) => {
|
|
488
|
+
const id = readAttribute(node, "data-id");
|
|
489
|
+
if (!id) return null;
|
|
490
|
+
const parsed = readNodeBindings(node);
|
|
491
|
+
if (!parsed.length) return null;
|
|
492
|
+
return {
|
|
493
|
+
id,
|
|
494
|
+
tagName: node.tagName || "element",
|
|
495
|
+
bindings: parsed.map((binding) => toPanelBindingData(node, id, binding))
|
|
496
|
+
};
|
|
497
|
+
};
|
|
498
|
+
const withPanelCommit = (bindings, commit) => bindings.map((binding) => ({
|
|
499
|
+
...binding,
|
|
500
|
+
onChange: (value) => commit?.({
|
|
501
|
+
id: binding.id,
|
|
502
|
+
label: binding.label,
|
|
503
|
+
property: binding.property,
|
|
504
|
+
value
|
|
505
|
+
})
|
|
506
|
+
}));
|
|
507
|
+
//#endregion
|
|
508
|
+
//#region src/components/dnd/panel/bulk-actions-bar.tsx
|
|
509
|
+
const BulkActionsBar = ({ count, disabled = false, onDuplicate, onMoveUp, onMoveDown, onDelete, onClear }) => {
|
|
510
|
+
const messages = useLiveMessages();
|
|
511
|
+
if (count === 0) return null;
|
|
512
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
513
|
+
className: "flex items-center justify-between rounded border\n border-blue-200 bg-blue-50 p-2",
|
|
514
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
515
|
+
className: "text-xs font-medium text-blue-700",
|
|
516
|
+
children: messages.selection.count(count)
|
|
517
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
518
|
+
className: "flex items-center space-x-1",
|
|
519
|
+
children: [
|
|
520
|
+
/* @__PURE__ */ jsx(Button, {
|
|
521
|
+
size: "small",
|
|
522
|
+
icon: /* @__PURE__ */ jsx(Copy, {}),
|
|
523
|
+
title: messages.selection.duplicate,
|
|
524
|
+
disabled,
|
|
525
|
+
onClick: onDuplicate
|
|
526
|
+
}),
|
|
527
|
+
/* @__PURE__ */ jsx(Button, {
|
|
528
|
+
size: "small",
|
|
529
|
+
icon: /* @__PURE__ */ jsx(ArrowUp, {}),
|
|
530
|
+
title: messages.selection.moveUp,
|
|
531
|
+
disabled,
|
|
532
|
+
onClick: onMoveUp
|
|
533
|
+
}),
|
|
534
|
+
/* @__PURE__ */ jsx(Button, {
|
|
535
|
+
size: "small",
|
|
536
|
+
icon: /* @__PURE__ */ jsx(ArrowDown, {}),
|
|
537
|
+
title: messages.selection.moveDown,
|
|
538
|
+
disabled,
|
|
539
|
+
onClick: onMoveDown
|
|
540
|
+
}),
|
|
541
|
+
/* @__PURE__ */ jsx(Button, {
|
|
542
|
+
danger: true,
|
|
543
|
+
size: "small",
|
|
544
|
+
icon: /* @__PURE__ */ jsx(X, {}),
|
|
545
|
+
title: messages.selection.delete,
|
|
546
|
+
disabled,
|
|
547
|
+
onClick: onDelete
|
|
548
|
+
}),
|
|
549
|
+
/* @__PURE__ */ jsx(Button, {
|
|
550
|
+
size: "small",
|
|
551
|
+
onClick: onClear,
|
|
552
|
+
children: messages.selection.clear
|
|
553
|
+
})
|
|
554
|
+
]
|
|
555
|
+
})]
|
|
556
|
+
});
|
|
557
|
+
};
|
|
558
|
+
//#endregion
|
|
559
|
+
//#region src/components/dnd/panel/node.tsx
|
|
560
|
+
const Node = ({ data, onChange }) => {
|
|
561
|
+
const source = resolvePanelBindings(data);
|
|
562
|
+
if (!source) return null;
|
|
563
|
+
return /* @__PURE__ */ jsx("div", {
|
|
564
|
+
className: "space-y-2 rounded",
|
|
565
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
566
|
+
className: "space-y-1",
|
|
567
|
+
children: withPanelCommit(source.bindings, onChange).map((binding) => /* @__PURE__ */ jsxs("div", {
|
|
568
|
+
className: "space-y-1",
|
|
569
|
+
children: [/* @__PURE__ */ jsxs("label", {
|
|
570
|
+
className: "block text-xs font-semibold text-gray-700",
|
|
571
|
+
children: [binding.label, /* @__PURE__ */ jsxs("span", {
|
|
572
|
+
className: "ml-1 text-gray-400",
|
|
573
|
+
children: [
|
|
574
|
+
"(",
|
|
575
|
+
binding.property,
|
|
576
|
+
")"
|
|
577
|
+
]
|
|
578
|
+
})]
|
|
579
|
+
}), /* @__PURE__ */ jsx(Field, {
|
|
580
|
+
binding,
|
|
581
|
+
onNodeChange: onChange
|
|
582
|
+
})]
|
|
583
|
+
}, `${binding.id}-${binding.property}`))
|
|
584
|
+
})
|
|
585
|
+
});
|
|
586
|
+
};
|
|
587
|
+
//#endregion
|
|
328
588
|
//#region src/components/dnd/panel/use-structural-selection.ts
|
|
329
589
|
const selectionAfter = (command, selected, count) => {
|
|
330
590
|
switch (command.type) {
|
|
@@ -420,6 +680,7 @@ const useDndChildren = (items, { onChange } = {}) => {
|
|
|
420
680
|
const Children$1 = ({ value, onChange, onNodeChange }) => {
|
|
421
681
|
const items = useMemo(() => Array.isArray(value) ? value : [], [value]);
|
|
422
682
|
const { selection, actions } = useDndChildren(items, { onChange });
|
|
683
|
+
const messages = useLiveMessages();
|
|
423
684
|
const editableChildrenMap = useMemo(() => {
|
|
424
685
|
const map = /* @__PURE__ */ new Map();
|
|
425
686
|
items.forEach((item, index) => {
|
|
@@ -433,19 +694,15 @@ const Children$1 = ({ value, onChange, onNodeChange }) => {
|
|
|
433
694
|
children: [
|
|
434
695
|
/* @__PURE__ */ jsxs("div", {
|
|
435
696
|
className: "flex items-center justify-between",
|
|
436
|
-
children: [/* @__PURE__ */
|
|
697
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
437
698
|
className: "text-sm font-semibold text-green-700",
|
|
438
|
-
children:
|
|
439
|
-
"Children Items (",
|
|
440
|
-
items.length,
|
|
441
|
-
")"
|
|
442
|
-
]
|
|
699
|
+
children: messages.children.heading(items.length)
|
|
443
700
|
}), /* @__PURE__ */ jsx(Button, {
|
|
444
701
|
size: "small",
|
|
445
702
|
color: "green",
|
|
446
703
|
icon: /* @__PURE__ */ jsx(Plus, {}),
|
|
447
704
|
onClick: actions.add,
|
|
448
|
-
children:
|
|
705
|
+
children: messages.children.add
|
|
449
706
|
})]
|
|
450
707
|
}),
|
|
451
708
|
/* @__PURE__ */ jsx(BulkActionsBar, {
|
|
@@ -470,15 +727,9 @@ const Children$1 = ({ value, onChange, onNodeChange }) => {
|
|
|
470
727
|
checked: selection.isSelected(itemIndex),
|
|
471
728
|
onChange: () => {}
|
|
472
729
|
})
|
|
473
|
-
}), /* @__PURE__ */
|
|
730
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
474
731
|
className: "text-xs font-medium text-green-800",
|
|
475
|
-
children:
|
|
476
|
-
"Child ",
|
|
477
|
-
itemIndex + 1,
|
|
478
|
-
" (",
|
|
479
|
-
item.tagName || "fragment",
|
|
480
|
-
")"
|
|
481
|
-
]
|
|
732
|
+
children: messages.children.child(itemIndex + 1, item.tagName || "fragment")
|
|
482
733
|
})]
|
|
483
734
|
}), /* @__PURE__ */ jsxs("div", {
|
|
484
735
|
className: "flex space-x-1",
|
|
@@ -486,17 +737,20 @@ const Children$1 = ({ value, onChange, onNodeChange }) => {
|
|
|
486
737
|
/* @__PURE__ */ jsx(Button, {
|
|
487
738
|
size: "small",
|
|
488
739
|
icon: /* @__PURE__ */ jsx(ArrowUp, {}),
|
|
740
|
+
"aria-label": messages.children.moveUp,
|
|
489
741
|
disabled: itemIndex === 0,
|
|
490
742
|
onClick: () => actions.move(itemIndex, itemIndex - 1)
|
|
491
743
|
}),
|
|
492
744
|
/* @__PURE__ */ jsx(Button, {
|
|
493
745
|
size: "small",
|
|
494
746
|
icon: /* @__PURE__ */ jsx(ArrowDown, {}),
|
|
747
|
+
"aria-label": messages.children.moveDown,
|
|
495
748
|
disabled: itemIndex === items.length - 1,
|
|
496
749
|
onClick: () => actions.move(itemIndex, itemIndex + 1)
|
|
497
750
|
}),
|
|
498
751
|
/* @__PURE__ */ jsx(Button, {
|
|
499
|
-
|
|
752
|
+
"aria-label": messages.children.delete,
|
|
753
|
+
title: messages.children.delete,
|
|
500
754
|
danger: true,
|
|
501
755
|
size: "small",
|
|
502
756
|
icon: /* @__PURE__ */ jsx(X, {}),
|
|
@@ -509,7 +763,7 @@ const Children$1 = ({ value, onChange, onNodeChange }) => {
|
|
|
509
763
|
className: "space-y-2",
|
|
510
764
|
children: [/* @__PURE__ */ jsx("div", {
|
|
511
765
|
className: "text-xs font-medium text-green-700",
|
|
512
|
-
children:
|
|
766
|
+
children: messages.children.editableBindings
|
|
513
767
|
}), editableChildrenMap.get(itemIndex).map((editableNode, idx) => {
|
|
514
768
|
const nodeId = editableNode.dataAttributes.find((a) => a.name === "data-id")?.value;
|
|
515
769
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -529,7 +783,7 @@ const Children$1 = ({ value, onChange, onNodeChange }) => {
|
|
|
529
783
|
className: "space-y-1",
|
|
530
784
|
children: [/* @__PURE__ */ jsx("div", {
|
|
531
785
|
className: "text-xs font-medium text-green-700",
|
|
532
|
-
children:
|
|
786
|
+
children: messages.children.childNodes
|
|
533
787
|
}), item.children.map((node, nodeIndex) => /* @__PURE__ */ jsx("div", {
|
|
534
788
|
className: "ml-2 rounded border border-green-100 bg-white p-2",
|
|
535
789
|
children: /* @__PURE__ */ jsx(Node, {
|
|
@@ -566,9 +820,9 @@ const getFieldKind = (binding) => {
|
|
|
566
820
|
const isStructuralFieldKind = (kind) => kind === "items" || kind === "children";
|
|
567
821
|
//#endregion
|
|
568
822
|
//#region src/components/dnd/panel/sortable-items.tsx
|
|
569
|
-
const label = (items, id) => {
|
|
823
|
+
const label = (messages, items, id) => {
|
|
570
824
|
const index = items.findIndex((item) => item.id === id);
|
|
571
|
-
return index >= 0 ?
|
|
825
|
+
return index >= 0 ? messages.items.item(index + 1) : String(id);
|
|
572
826
|
};
|
|
573
827
|
const SortableItems = ({ items, disabled, onMove, children }) => {
|
|
574
828
|
const sensors = useSensors(useSensor(MouseSensor, { activationConstraint: { distance: 4 } }), useSensor(TouchSensor, { activationConstraint: {
|
|
@@ -580,15 +834,18 @@ const SortableItems = ({ items, disabled, onMove, children }) => {
|
|
|
580
834
|
const to = items.find((item) => item.id === over?.id);
|
|
581
835
|
if (from && to && from !== to) onMove(from, to.index);
|
|
582
836
|
};
|
|
837
|
+
const messages = useLiveMessages();
|
|
838
|
+
const { announcements: say } = messages;
|
|
839
|
+
const name = (id) => label(messages, items, id);
|
|
583
840
|
return /* @__PURE__ */ jsx(DndContext, {
|
|
584
841
|
sensors,
|
|
585
842
|
collisionDetection: closestCenter,
|
|
586
843
|
modifiers: [restrictToVerticalAxis, restrictToParentElement],
|
|
587
844
|
accessibility: { announcements: {
|
|
588
|
-
onDragStart: ({ active }) =>
|
|
589
|
-
onDragOver: ({ active, over }) => over ?
|
|
590
|
-
onDragEnd: ({ active, over }) => over ?
|
|
591
|
-
onDragCancel: ({ active }) =>
|
|
845
|
+
onDragStart: ({ active }) => say.pickedUp(name(active.id)),
|
|
846
|
+
onDragOver: ({ active, over }) => over ? say.itemOver(name(active.id), name(over.id)) : void 0,
|
|
847
|
+
onDragEnd: ({ active, over }) => over ? say.itemMoved(name(active.id), name(over.id)) : say.dropped(name(active.id)),
|
|
848
|
+
onDragCancel: ({ active }) => say.cancelled(name(active.id))
|
|
592
849
|
} },
|
|
593
850
|
onDragEnd,
|
|
594
851
|
children: /* @__PURE__ */ jsx(SortableContext, {
|
|
@@ -603,6 +860,7 @@ const SortableItems = ({ items, disabled, onMove, children }) => {
|
|
|
603
860
|
});
|
|
604
861
|
};
|
|
605
862
|
const ItemCard = ({ id, title, disabled, expanded, onToggle, checkbox, controls, className, children }) => {
|
|
863
|
+
const messages = useLiveMessages();
|
|
606
864
|
const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } = useSortable({
|
|
607
865
|
id,
|
|
608
866
|
disabled
|
|
@@ -624,7 +882,7 @@ const ItemCard = ({ id, title, disabled, expanded, onToggle, checkbox, controls,
|
|
|
624
882
|
ref: setActivatorNodeRef,
|
|
625
883
|
...attributes,
|
|
626
884
|
...listeners,
|
|
627
|
-
"aria-label":
|
|
885
|
+
"aria-label": messages.items.reorder(title),
|
|
628
886
|
disabled,
|
|
629
887
|
className: "cursor-grab rounded p-0.5 text-gray-400\n hover:text-gray-700 disabled:cursor-not-allowed\n disabled:opacity-40",
|
|
630
888
|
children: /* @__PURE__ */ jsx(GripVertical, { size: 14 })
|
|
@@ -755,18 +1013,21 @@ const removeIds = (ids, indices) => {
|
|
|
755
1013
|
};
|
|
756
1014
|
const useDndItems = (value, { render, onChange, onNodeChange } = {}) => {
|
|
757
1015
|
const { reportError, bindingOptions } = useDndEditOptions();
|
|
1016
|
+
const messages = useLiveMessages();
|
|
758
1017
|
const { objectItems, primitiveItems, parseError } = useMemo(() => parseSource(value, bindingOptions), [value, bindingOptions]);
|
|
759
1018
|
const canEditStructure = useMemo(() => canStructurallyEditArray(value), [value]);
|
|
760
1019
|
const reportErrorRef = useRef(reportError);
|
|
1020
|
+
const messagesRef = useRef(messages);
|
|
761
1021
|
useEffect(() => {
|
|
762
1022
|
reportErrorRef.current = reportError;
|
|
1023
|
+
messagesRef.current = messages;
|
|
763
1024
|
});
|
|
764
1025
|
useEffect(() => {
|
|
765
1026
|
if (parseError) reportErrorRef.current({
|
|
766
1027
|
type: "parse",
|
|
767
1028
|
target: "items",
|
|
768
|
-
title:
|
|
769
|
-
description:
|
|
1029
|
+
title: messagesRef.current.editErrors.itemsParseFailed,
|
|
1030
|
+
description: messagesRef.current.editErrors.checkConsole
|
|
770
1031
|
});
|
|
771
1032
|
}, [parseError]);
|
|
772
1033
|
const kind = primitiveItems.length > 0 && objectItems.length === 0 ? "primitive" : "object";
|
|
@@ -811,8 +1072,8 @@ const useDndItems = (value, { render, onChange, onNodeChange } = {}) => {
|
|
|
811
1072
|
if (next === null) {
|
|
812
1073
|
reportError({
|
|
813
1074
|
type: "items",
|
|
814
|
-
title:
|
|
815
|
-
description:
|
|
1075
|
+
title: messages.editErrors.itemUpdateFailed,
|
|
1076
|
+
description: messages.editErrors.itemUpdateFailedDetail
|
|
816
1077
|
});
|
|
817
1078
|
return false;
|
|
818
1079
|
}
|
|
@@ -1036,6 +1297,7 @@ const NestedGroup = ({ group, onNodeChange }) => {
|
|
|
1036
1297
|
});
|
|
1037
1298
|
};
|
|
1038
1299
|
const Items = ({ value, render, onChange, onChildChange }) => {
|
|
1300
|
+
const messages = useLiveMessages();
|
|
1039
1301
|
const { kind, items, selection, expansion, actions, canEditStructure, parseError } = useDndItems(value, {
|
|
1040
1302
|
render,
|
|
1041
1303
|
onChange,
|
|
@@ -1043,34 +1305,30 @@ const Items = ({ value, render, onChange, onChildChange }) => {
|
|
|
1043
1305
|
});
|
|
1044
1306
|
const header = /* @__PURE__ */ jsxs("div", {
|
|
1045
1307
|
className: "flex items-center justify-between",
|
|
1046
|
-
children: [/* @__PURE__ */
|
|
1308
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
1047
1309
|
className: "text-sm font-semibold",
|
|
1048
|
-
children:
|
|
1049
|
-
"Items (",
|
|
1050
|
-
items.length,
|
|
1051
|
-
")"
|
|
1052
|
-
]
|
|
1310
|
+
children: messages.items.heading(items.length)
|
|
1053
1311
|
}), items.length > 0 && canEditStructure && /* @__PURE__ */ jsx(Button, {
|
|
1054
1312
|
size: "small",
|
|
1055
1313
|
icon: /* @__PURE__ */ jsx(Plus, {}),
|
|
1056
1314
|
variant: "solid",
|
|
1057
1315
|
color: "green",
|
|
1058
1316
|
onClick: actions.add,
|
|
1059
|
-
children:
|
|
1317
|
+
children: messages.items.add
|
|
1060
1318
|
})]
|
|
1061
1319
|
});
|
|
1062
1320
|
if (parseError) return /* @__PURE__ */ jsxs("div", {
|
|
1063
1321
|
className: "space-y-4",
|
|
1064
1322
|
children: [header, /* @__PURE__ */ jsx("div", {
|
|
1065
1323
|
className: "rounded border border-dashed border-red-200 p-3 text-xs\n text-red-600",
|
|
1066
|
-
children:
|
|
1324
|
+
children: messages.items.unreadable
|
|
1067
1325
|
})]
|
|
1068
1326
|
});
|
|
1069
1327
|
if (items.length === 0) return /* @__PURE__ */ jsxs("div", {
|
|
1070
1328
|
className: "space-y-4",
|
|
1071
1329
|
children: [header, /* @__PURE__ */ jsx("div", {
|
|
1072
1330
|
className: "rounded border border-dashed border-gray-200 p-3 text-xs\n text-gray-500",
|
|
1073
|
-
children:
|
|
1331
|
+
children: messages.items.empty
|
|
1074
1332
|
})]
|
|
1075
1333
|
});
|
|
1076
1334
|
const bulkBar = /* @__PURE__ */ jsx(BulkActionsBar, {
|
|
@@ -1088,12 +1346,14 @@ const Items = ({ value, render, onChange, onChildChange }) => {
|
|
|
1088
1346
|
/* @__PURE__ */ jsx(Button, {
|
|
1089
1347
|
size: "small",
|
|
1090
1348
|
icon: /* @__PURE__ */ jsx(ArrowUp, {}),
|
|
1349
|
+
"aria-label": messages.items.moveUp,
|
|
1091
1350
|
disabled: !canEditStructure || item.index === 0,
|
|
1092
1351
|
onClick: () => actions.move(item.elementIndex, item.index - 1)
|
|
1093
1352
|
}),
|
|
1094
1353
|
/* @__PURE__ */ jsx(Button, {
|
|
1095
1354
|
size: "small",
|
|
1096
1355
|
icon: /* @__PURE__ */ jsx(ArrowDown, {}),
|
|
1356
|
+
"aria-label": messages.items.moveDown,
|
|
1097
1357
|
disabled: !canEditStructure || item.index === items.length - 1,
|
|
1098
1358
|
onClick: () => actions.move(item.elementIndex, item.index + 1)
|
|
1099
1359
|
}),
|
|
@@ -1101,6 +1361,7 @@ const Items = ({ value, render, onChange, onChildChange }) => {
|
|
|
1101
1361
|
danger: true,
|
|
1102
1362
|
size: "small",
|
|
1103
1363
|
icon: /* @__PURE__ */ jsx(X, {}),
|
|
1364
|
+
"aria-label": messages.items.delete,
|
|
1104
1365
|
disabled: !canEditStructure || items.length <= 1,
|
|
1105
1366
|
onClick: () => actions.remove(item.elementIndex)
|
|
1106
1367
|
})
|
|
@@ -1139,9 +1400,16 @@ const Items = ({ value, render, onChange, onChildChange }) => {
|
|
|
1139
1400
|
children: item.nested.length ? item.nested.map((group) => /* @__PURE__ */ jsx(NestedGroup, {
|
|
1140
1401
|
group,
|
|
1141
1402
|
onNodeChange: onChildChange
|
|
1142
|
-
}, group.property)) : /* @__PURE__ */
|
|
1403
|
+
}, group.property)) : /* @__PURE__ */ jsxs("div", {
|
|
1143
1404
|
className: "text-xs text-gray-500",
|
|
1144
|
-
children:
|
|
1405
|
+
children: [
|
|
1406
|
+
/* @__PURE__ */ jsx("span", {
|
|
1407
|
+
"aria-hidden": "true",
|
|
1408
|
+
children: "✓"
|
|
1409
|
+
}),
|
|
1410
|
+
" ",
|
|
1411
|
+
messages.items.noNestedBindings
|
|
1412
|
+
]
|
|
1145
1413
|
})
|
|
1146
1414
|
})] });
|
|
1147
1415
|
const allExpanded = expansion.expandedIds.length === items.length;
|
|
@@ -1155,13 +1423,13 @@ const Items = ({ value, render, onChange, onChildChange }) => {
|
|
|
1155
1423
|
size: "small",
|
|
1156
1424
|
variant: "text",
|
|
1157
1425
|
onClick: () => expansion.setExpanded(allExpanded ? [] : items.map((item) => item.id)),
|
|
1158
|
-
children: allExpanded ?
|
|
1426
|
+
children: allExpanded ? messages.items.collapseAll : messages.items.expandAll
|
|
1159
1427
|
})
|
|
1160
1428
|
}),
|
|
1161
1429
|
bulkBar,
|
|
1162
1430
|
!canEditStructure && /* @__PURE__ */ jsx("div", {
|
|
1163
1431
|
className: "rounded border border-dashed border-amber-200 p-3 text-xs\n text-amber-700",
|
|
1164
|
-
children:
|
|
1432
|
+
children: messages.items.structureLocked
|
|
1165
1433
|
}),
|
|
1166
1434
|
/* @__PURE__ */ jsx(SortableItems, {
|
|
1167
1435
|
items,
|
|
@@ -1169,7 +1437,7 @@ const Items = ({ value, render, onChange, onChildChange }) => {
|
|
|
1169
1437
|
onMove: (item, toIndex) => actions.move(item.elementIndex, toIndex),
|
|
1170
1438
|
children: (item) => /* @__PURE__ */ jsx(ItemCard, {
|
|
1171
1439
|
id: item.id,
|
|
1172
|
-
title:
|
|
1440
|
+
title: messages.items.item(item.index + 1),
|
|
1173
1441
|
disabled: !canEditStructure,
|
|
1174
1442
|
expanded: expansion.isExpanded(item.id),
|
|
1175
1443
|
onToggle: () => expansion.toggle(item.id),
|
|
@@ -1278,6 +1546,8 @@ const FieldError = ({ message }) => message ? /* @__PURE__ */ jsx("p", {
|
|
|
1278
1546
|
children: message
|
|
1279
1547
|
}) : null;
|
|
1280
1548
|
const BuiltinField = ({ binding, onNodeChange }) => {
|
|
1549
|
+
const messages = useLiveMessages();
|
|
1550
|
+
const validationOptions = { messages: messages.validation };
|
|
1281
1551
|
const { id, value, rawValue, onChange } = binding;
|
|
1282
1552
|
const [validationError, setValidationError] = useState(null);
|
|
1283
1553
|
const [text, setText] = useState(rawValue);
|
|
@@ -1290,12 +1560,12 @@ const BuiltinField = ({ binding, onNodeChange }) => {
|
|
|
1290
1560
|
if (kind === "readonly") return /* @__PURE__ */ jsxs("div", {
|
|
1291
1561
|
className: "space-y-1 rounded border border-dashed border-amber-200 p-3\n text-xs text-amber-700",
|
|
1292
1562
|
children: [
|
|
1293
|
-
/* @__PURE__ */ jsx("div", { children:
|
|
1563
|
+
/* @__PURE__ */ jsx("div", { children: messages.panel.expressionPreserved }),
|
|
1294
1564
|
/* @__PURE__ */ jsx("code", {
|
|
1295
1565
|
className: "block overflow-x-auto text-amber-800",
|
|
1296
1566
|
children: rawValue
|
|
1297
1567
|
}),
|
|
1298
|
-
/* @__PURE__ */ jsx("div", { children:
|
|
1568
|
+
/* @__PURE__ */ jsx("div", { children: messages.panel.useCodeEditor })
|
|
1299
1569
|
]
|
|
1300
1570
|
});
|
|
1301
1571
|
const commitIfChanged = (next) => {
|
|
@@ -1372,9 +1642,9 @@ const BuiltinField = ({ binding, onNodeChange }) => {
|
|
|
1372
1642
|
value: parseDateValue(stringValue),
|
|
1373
1643
|
onChange: (date) => {
|
|
1374
1644
|
const next = date ? formatDateValue(date) : "";
|
|
1375
|
-
const result = validateBindingValue(binding, next);
|
|
1645
|
+
const result = validateBindingValue(binding, next, validationOptions);
|
|
1376
1646
|
if (!result.valid) {
|
|
1377
|
-
setValidationError(result.message ??
|
|
1647
|
+
setValidationError(result.message ?? messages.panel.invalidValue);
|
|
1378
1648
|
return;
|
|
1379
1649
|
}
|
|
1380
1650
|
setValidationError(null);
|
|
@@ -1385,12 +1655,12 @@ const BuiltinField = ({ binding, onNodeChange }) => {
|
|
|
1385
1655
|
type: "url",
|
|
1386
1656
|
value: text,
|
|
1387
1657
|
onChange: (e) => setText(e.target.value),
|
|
1388
|
-
placeholder:
|
|
1658
|
+
placeholder: messages.panel.urlPlaceholder,
|
|
1389
1659
|
onBlur: (e) => {
|
|
1390
1660
|
const next = e.target.value.trim();
|
|
1391
|
-
const result = validateBindingValue(binding, next);
|
|
1661
|
+
const result = validateBindingValue(binding, next, validationOptions);
|
|
1392
1662
|
if (!result.valid) {
|
|
1393
|
-
setValidationError(result.message ??
|
|
1663
|
+
setValidationError(result.message ?? messages.panel.invalidValue);
|
|
1394
1664
|
return;
|
|
1395
1665
|
}
|
|
1396
1666
|
setValidationError(null);
|
|
@@ -1401,13 +1671,13 @@ const BuiltinField = ({ binding, onNodeChange }) => {
|
|
|
1401
1671
|
type: "number",
|
|
1402
1672
|
value: text,
|
|
1403
1673
|
onChange: (e) => setText(e.target.value),
|
|
1404
|
-
placeholder:
|
|
1674
|
+
placeholder: messages.panel.numberPlaceholder,
|
|
1405
1675
|
onBlur: (e) => {
|
|
1406
1676
|
const raw = e.target.value.trim();
|
|
1407
1677
|
const next = raw !== "" && !Number.isNaN(Number(raw)) ? Number(raw) : raw;
|
|
1408
|
-
const result = validateBindingValue(binding, next);
|
|
1678
|
+
const result = validateBindingValue(binding, next, validationOptions);
|
|
1409
1679
|
if (!result.valid) {
|
|
1410
|
-
setValidationError(result.message ??
|
|
1680
|
+
setValidationError(result.message ?? messages.panel.invalidValue);
|
|
1411
1681
|
return;
|
|
1412
1682
|
}
|
|
1413
1683
|
setValidationError(null);
|
|
@@ -1417,13 +1687,13 @@ const BuiltinField = ({ binding, onNodeChange }) => {
|
|
|
1417
1687
|
return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx(Input.TextArea, {
|
|
1418
1688
|
value: text,
|
|
1419
1689
|
onChange: (e) => setText(e.target.value),
|
|
1420
|
-
placeholder:
|
|
1690
|
+
placeholder: messages.panel.textPlaceholder,
|
|
1421
1691
|
onBlur: (e) => {
|
|
1422
1692
|
const raw = e.target.value.trim();
|
|
1423
1693
|
const next = binding.type ? raw : parseValue(raw);
|
|
1424
|
-
const result = validateBindingValue(binding, next);
|
|
1694
|
+
const result = validateBindingValue(binding, next, validationOptions);
|
|
1425
1695
|
if (!result.valid) {
|
|
1426
|
-
setValidationError(result.message ??
|
|
1696
|
+
setValidationError(result.message ?? messages.panel.invalidValue);
|
|
1427
1697
|
return;
|
|
1428
1698
|
}
|
|
1429
1699
|
setValidationError(null);
|
|
@@ -1484,6 +1754,7 @@ const describeElement = (binding) => {
|
|
|
1484
1754
|
};
|
|
1485
1755
|
const nodeIdOf = (target) => target instanceof Element && target.closest("[data-node-id]")?.getAttribute("data-node-id") || null;
|
|
1486
1756
|
const Panel$1 = ({ item, onDelete, onMoveUp, onMoveDown, canMoveUp = false, canMoveDown = false, bindings, onNodeChange, readOnly = false }) => {
|
|
1757
|
+
const messages = useLiveMessages();
|
|
1487
1758
|
const groups = groupBindingsById(bindings);
|
|
1488
1759
|
const rootRef = useRef(null);
|
|
1489
1760
|
const inspector = useContext(DndInspectorContext);
|
|
@@ -1519,7 +1790,7 @@ const Panel$1 = ({ item, onDelete, onMoveUp, onMoveDown, canMoveUp = false, canM
|
|
|
1519
1790
|
}, [pickedId, groups.length]);
|
|
1520
1791
|
if (!item) return /* @__PURE__ */ jsx(Typography.Paragraph, {
|
|
1521
1792
|
className: cn("p-4 text-sm text-gray-500"),
|
|
1522
|
-
children:
|
|
1793
|
+
children: messages.panel.selectSection
|
|
1523
1794
|
});
|
|
1524
1795
|
return /* @__PURE__ */ jsxs("div", {
|
|
1525
1796
|
ref: rootRef,
|
|
@@ -1543,19 +1814,19 @@ const Panel$1 = ({ item, onDelete, onMoveUp, onMoveDown, canMoveUp = false, canM
|
|
|
1543
1814
|
icon: /* @__PURE__ */ jsx(ChevronUp, {}),
|
|
1544
1815
|
disabled: !canMoveUp,
|
|
1545
1816
|
onClick: onMoveUp,
|
|
1546
|
-
"aria-label":
|
|
1817
|
+
"aria-label": messages.section.moveUp
|
|
1547
1818
|
}),
|
|
1548
1819
|
onMoveDown && /* @__PURE__ */ jsx(Button, {
|
|
1549
1820
|
icon: /* @__PURE__ */ jsx(ChevronDown, {}),
|
|
1550
1821
|
disabled: !canMoveDown,
|
|
1551
1822
|
onClick: onMoveDown,
|
|
1552
|
-
"aria-label":
|
|
1823
|
+
"aria-label": messages.section.moveDown
|
|
1553
1824
|
}),
|
|
1554
1825
|
onDelete && /* @__PURE__ */ jsx(Button, {
|
|
1555
1826
|
danger: true,
|
|
1556
1827
|
icon: /* @__PURE__ */ jsx(Trash, {}),
|
|
1557
1828
|
onClick: () => onDelete(item.id),
|
|
1558
|
-
"aria-label":
|
|
1829
|
+
"aria-label": messages.section.delete
|
|
1559
1830
|
})
|
|
1560
1831
|
]
|
|
1561
1832
|
})]
|
|
@@ -1563,11 +1834,11 @@ const Panel$1 = ({ item, onDelete, onMoveUp, onMoveDown, canMoveUp = false, canM
|
|
|
1563
1834
|
readOnly && /* @__PURE__ */ jsx(Typography.Text, {
|
|
1564
1835
|
role: "status",
|
|
1565
1836
|
className: "block text-xs text-amber-700",
|
|
1566
|
-
children:
|
|
1837
|
+
children: messages.panel.readOnly
|
|
1567
1838
|
}),
|
|
1568
1839
|
!groups.length && /* @__PURE__ */ jsx(Typography.Text, {
|
|
1569
1840
|
className: "text-xs text-gray-400",
|
|
1570
|
-
children:
|
|
1841
|
+
children: messages.panel.noEditableElements
|
|
1571
1842
|
}),
|
|
1572
1843
|
groups.map((group) => {
|
|
1573
1844
|
const element = describeElement(group[0]);
|
|
@@ -1630,6 +1901,7 @@ const Palette = ({ className, ...restProps }) => /* @__PURE__ */ jsx("div", {
|
|
|
1630
1901
|
const Canvas = ({ className, style, ...restProps }) => {
|
|
1631
1902
|
const { canvas, documentError } = useDndRegions("<Live.Dnd.Canvas>");
|
|
1632
1903
|
const inspector = useDndInspector();
|
|
1904
|
+
const messages = useLiveMessages();
|
|
1633
1905
|
return /* @__PURE__ */ jsxs("div", {
|
|
1634
1906
|
className: cn("relative h-full w-full overflow-y-auto", className),
|
|
1635
1907
|
"data-frame-container": true,
|
|
@@ -1649,8 +1921,8 @@ const Canvas = ({ className, style, ...restProps }) => {
|
|
|
1649
1921
|
color: "primary",
|
|
1650
1922
|
variant: inspector.active ? "solid" : "outlined",
|
|
1651
1923
|
"aria-pressed": inspector.active,
|
|
1652
|
-
"aria-label":
|
|
1653
|
-
title: inspector.active ?
|
|
1924
|
+
"aria-label": messages.canvas.pickElement,
|
|
1925
|
+
title: inspector.active ? messages.canvas.pickElementActive : messages.canvas.pickElement,
|
|
1654
1926
|
onClick: inspector.toggle
|
|
1655
1927
|
})
|
|
1656
1928
|
})
|
|
@@ -1664,298 +1936,259 @@ const Panel = ({ className, ...restProps }) => /* @__PURE__ */ jsx("div", {
|
|
|
1664
1936
|
});
|
|
1665
1937
|
const Layout = ({ palette, panel }) => {
|
|
1666
1938
|
const { isMobile, selectedId, clearSelection, paletteOpen, setPaletteOpen } = useDndRegions("<Live.Dnd.Layout>");
|
|
1939
|
+
const messages = useLiveMessages();
|
|
1667
1940
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1668
1941
|
isMobile ? /* @__PURE__ */ jsx(Canvas, {}) : /* @__PURE__ */ jsxs(Splitter, {
|
|
1669
1942
|
withHandle: true,
|
|
1670
1943
|
orientation: "horizontal",
|
|
1671
|
-
children: [
|
|
1672
|
-
/* @__PURE__ */ jsx(Splitter.Panel, {
|
|
1673
|
-
defaultSize: "20%",
|
|
1674
|
-
minSize: "15%",
|
|
1675
|
-
maxSize: "35%",
|
|
1676
|
-
collapsible: true,
|
|
1677
|
-
children: palette ?? /* @__PURE__ */ jsx(Palette, {})
|
|
1678
|
-
}),
|
|
1679
|
-
/* @__PURE__ */ jsx(Splitter.Panel, {
|
|
1680
|
-
defaultSize: "60%",
|
|
1681
|
-
children: /* @__PURE__ */ jsx(Canvas, {})
|
|
1682
|
-
}),
|
|
1683
|
-
/* @__PURE__ */ jsx(Splitter.Panel, {
|
|
1684
|
-
defaultSize: "20%",
|
|
1685
|
-
minSize: "15%",
|
|
1686
|
-
maxSize: "35%",
|
|
1687
|
-
collapsible: true,
|
|
1688
|
-
children: panel ?? /* @__PURE__ */ jsx(Panel, {})
|
|
1689
|
-
})
|
|
1690
|
-
]
|
|
1691
|
-
}),
|
|
1692
|
-
/* @__PURE__ */ jsx(Button, {
|
|
1693
|
-
type: "primary",
|
|
1694
|
-
shape: "circle",
|
|
1695
|
-
icon: /* @__PURE__ */ jsx(LayoutGrid, {}),
|
|
1696
|
-
"aria-label": "Components",
|
|
1697
|
-
className: "fixed right-4 bottom-4 z-20 md:hidden",
|
|
1698
|
-
onClick: () => setPaletteOpen(true)
|
|
1699
|
-
}),
|
|
1700
|
-
/* @__PURE__ */ jsx(Drawer, {
|
|
1701
|
-
open: isMobile && paletteOpen,
|
|
1702
|
-
onClose: () => setPaletteOpen(false),
|
|
1703
|
-
direction: "bottom",
|
|
1704
|
-
size: "large",
|
|
1705
|
-
title: "Components",
|
|
1706
|
-
children: palette ?? /* @__PURE__ */ jsx(PaletteItems, { subject: "<Live.Dnd.Layout>" })
|
|
1707
|
-
}),
|
|
1708
|
-
/* @__PURE__ */ jsx(Drawer, {
|
|
1709
|
-
open: isMobile && Boolean(selectedId),
|
|
1710
|
-
onClose: clearSelection,
|
|
1711
|
-
direction: "bottom",
|
|
1712
|
-
size: "large",
|
|
1713
|
-
title: "Properties",
|
|
1714
|
-
children: panel ?? /* @__PURE__ */ jsx(PanelFields, { subject: "<Live.Dnd.Layout>" })
|
|
1715
|
-
})
|
|
1716
|
-
] });
|
|
1717
|
-
};
|
|
1718
|
-
//#endregion
|
|
1719
|
-
//#region src/components/dnd/section-fallback-context.ts
|
|
1720
|
-
const SectionFallbackContext = createContext(void 0);
|
|
1721
|
-
//#endregion
|
|
1722
|
-
//#region src/components/dnd/section-fallback.tsx
|
|
1723
|
-
const ConsumerFallback = ({ render, args, builtin }) => {
|
|
1724
|
-
const node = render(args);
|
|
1725
|
-
return node === void 0 ? builtin : /* @__PURE__ */ jsx(Fragment, { children: node });
|
|
1726
|
-
};
|
|
1727
|
-
const SectionFallback = ({ args, builtin }) => {
|
|
1728
|
-
const render = useContext(SectionFallbackContext);
|
|
1729
|
-
if (!render) return builtin;
|
|
1730
|
-
return /* @__PURE__ */ jsx(ErrorBoundary, {
|
|
1731
|
-
fallback: () => builtin,
|
|
1732
|
-
children: /* @__PURE__ */ jsx(ConsumerFallback, {
|
|
1733
|
-
render,
|
|
1734
|
-
args,
|
|
1735
|
-
builtin
|
|
1736
|
-
})
|
|
1737
|
-
});
|
|
1738
|
-
};
|
|
1739
|
-
//#endregion
|
|
1740
|
-
//#region src/components/dnd/renderer.tsx
|
|
1741
|
-
const Renderer = ({ preview, sectionId = "", sectionName = "", sectionCode = preview, forceFallback = false, headers, modules, frame, dynamicTailwind = false, provider }) => {
|
|
1742
|
-
const module = useCompiledModule(forceFallback ? "" : preview, modules);
|
|
1743
|
-
const section = {
|
|
1744
|
-
id: sectionId,
|
|
1745
|
-
name: sectionName,
|
|
1746
|
-
code: sectionCode
|
|
1747
|
-
};
|
|
1748
|
-
const { ref: wrapperRef, css: dynamicCSS } = useDynamicTailwind(preview, dynamicTailwind && !forceFallback);
|
|
1749
|
-
const renderProvider = (component) => {
|
|
1750
|
-
return provider ? provider(component) : component;
|
|
1751
|
-
};
|
|
1752
|
-
if (forceFallback) return /* @__PURE__ */ jsx(SectionFallback, {
|
|
1753
|
-
args: {
|
|
1754
|
-
section,
|
|
1755
|
-
reason: "forced"
|
|
1756
|
-
},
|
|
1757
|
-
builtin: /* @__PURE__ */ jsx(Error$1, {
|
|
1758
|
-
message: "This section is not rendered in this editor.",
|
|
1759
|
-
title: "Section Unavailable"
|
|
1760
|
-
})
|
|
1761
|
-
});
|
|
1762
|
-
if (module?.error) return /* @__PURE__ */ jsx(SectionFallback, {
|
|
1763
|
-
args: {
|
|
1764
|
-
section,
|
|
1765
|
-
reason: "compile",
|
|
1766
|
-
message: module.error
|
|
1767
|
-
},
|
|
1768
|
-
builtin: /* @__PURE__ */ jsx(Error$1, {
|
|
1769
|
-
message: module.error,
|
|
1770
|
-
title: "Compile Error"
|
|
1771
|
-
})
|
|
1772
|
-
});
|
|
1773
|
-
const Component = module?.exports?.default;
|
|
1774
|
-
if (!Component) return null;
|
|
1775
|
-
return /* @__PURE__ */ jsx(Frame, {
|
|
1776
|
-
...frame,
|
|
1777
|
-
autoHeight: true,
|
|
1778
|
-
children: (container) => /* @__PURE__ */ jsx("div", {
|
|
1779
|
-
ref: wrapperRef,
|
|
1780
|
-
className: "w-full overflow-x-hidden",
|
|
1781
|
-
"data-editor-mode": true,
|
|
1782
|
-
children: /* @__PURE__ */ jsx(ErrorBoundary, {
|
|
1783
|
-
resetKeys: [preview],
|
|
1784
|
-
fallback: (message, reset) => /* @__PURE__ */ jsx(SectionFallback, {
|
|
1785
|
-
args: {
|
|
1786
|
-
section,
|
|
1787
|
-
reason: "runtime",
|
|
1788
|
-
message
|
|
1789
|
-
},
|
|
1790
|
-
builtin: /* @__PURE__ */ jsx(Error$1, {
|
|
1791
|
-
message,
|
|
1792
|
-
onReset: reset,
|
|
1793
|
-
title: "Rendering Error"
|
|
1794
|
-
})
|
|
1944
|
+
children: [
|
|
1945
|
+
/* @__PURE__ */ jsx(Splitter.Panel, {
|
|
1946
|
+
defaultSize: "20%",
|
|
1947
|
+
minSize: "15%",
|
|
1948
|
+
maxSize: "35%",
|
|
1949
|
+
collapsible: true,
|
|
1950
|
+
children: palette ?? /* @__PURE__ */ jsx(Palette, {})
|
|
1795
1951
|
}),
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
}),
|
|
1800
|
-
|
|
1952
|
+
/* @__PURE__ */ jsx(Splitter.Panel, {
|
|
1953
|
+
defaultSize: "60%",
|
|
1954
|
+
children: /* @__PURE__ */ jsx(Canvas, {})
|
|
1955
|
+
}),
|
|
1956
|
+
/* @__PURE__ */ jsx(Splitter.Panel, {
|
|
1957
|
+
defaultSize: "20%",
|
|
1958
|
+
minSize: "15%",
|
|
1959
|
+
maxSize: "35%",
|
|
1960
|
+
collapsible: true,
|
|
1961
|
+
children: panel ?? /* @__PURE__ */ jsx(Panel, {})
|
|
1962
|
+
})
|
|
1963
|
+
]
|
|
1964
|
+
}),
|
|
1965
|
+
/* @__PURE__ */ jsx(Button, {
|
|
1966
|
+
type: "primary",
|
|
1967
|
+
shape: "circle",
|
|
1968
|
+
icon: /* @__PURE__ */ jsx(LayoutGrid, {}),
|
|
1969
|
+
"aria-label": messages.canvas.palette,
|
|
1970
|
+
className: "fixed right-4 bottom-4 z-20 md:hidden",
|
|
1971
|
+
onClick: () => setPaletteOpen(true)
|
|
1972
|
+
}),
|
|
1973
|
+
/* @__PURE__ */ jsx(Drawer, {
|
|
1974
|
+
open: isMobile && paletteOpen,
|
|
1975
|
+
onClose: () => setPaletteOpen(false),
|
|
1976
|
+
direction: "bottom",
|
|
1977
|
+
size: "large",
|
|
1978
|
+
title: messages.canvas.palette,
|
|
1979
|
+
children: palette ?? /* @__PURE__ */ jsx(PaletteItems, { subject: "<Live.Dnd.Layout>" })
|
|
1980
|
+
}),
|
|
1981
|
+
/* @__PURE__ */ jsx(Drawer, {
|
|
1982
|
+
open: isMobile && Boolean(selectedId),
|
|
1983
|
+
onClose: clearSelection,
|
|
1984
|
+
direction: "bottom",
|
|
1985
|
+
size: "large",
|
|
1986
|
+
title: messages.canvas.properties,
|
|
1987
|
+
children: panel ?? /* @__PURE__ */ jsx(PanelFields, { subject: "<Live.Dnd.Layout>" })
|
|
1801
1988
|
})
|
|
1802
|
-
});
|
|
1803
|
-
};
|
|
1804
|
-
const sameValue = (a, b) => {
|
|
1805
|
-
if (Object.is(a, b)) return true;
|
|
1806
|
-
if (Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((item, i) => Object.is(item, b[i]));
|
|
1807
|
-
if (a && b && typeof a === "object" && typeof b === "object" && Object.getPrototypeOf(a) === Object.prototype && Object.getPrototypeOf(b) === Object.prototype) {
|
|
1808
|
-
const aKeys = Object.keys(a);
|
|
1809
|
-
return aKeys.length === Object.keys(b).length && aKeys.every((key) => Object.is(a[key], b[key]));
|
|
1810
|
-
}
|
|
1811
|
-
return false;
|
|
1812
|
-
};
|
|
1813
|
-
const sameFrame = (a, b) => {
|
|
1814
|
-
if (a === b) return true;
|
|
1815
|
-
if (!a || !b) return false;
|
|
1816
|
-
return [.../* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)])].every((key) => sameValue(a[key], b[key]));
|
|
1817
|
-
};
|
|
1818
|
-
const arePropsEqual = (prev, next) => {
|
|
1819
|
-
return [.../* @__PURE__ */ new Set([...Object.keys(prev), ...Object.keys(next)])].every((key) => key === "frame" ? sameFrame(prev.frame, next.frame) : Object.is(prev[key], next[key]));
|
|
1989
|
+
] });
|
|
1820
1990
|
};
|
|
1821
|
-
var renderer_default = memo(Renderer, arePropsEqual);
|
|
1822
1991
|
//#endregion
|
|
1823
|
-
//#region src/components/dnd/
|
|
1824
|
-
const
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
End: "last"
|
|
1829
|
-
};
|
|
1830
|
-
const Sortable = ({ id, children, selected, onClick, onDelete: _onDelete, onCopy: _onCopy, onMoveUp, onMoveDown, canMoveUp = false, canMoveDown = false, nodeRef, onNavigate, onDeleteKey, inspecting = false, onInspectMove, onInspectPick, onInspectLeave }) => {
|
|
1831
|
-
const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging, isOver, active } = useSortable({
|
|
1832
|
-
id,
|
|
1833
|
-
disabled: inspecting
|
|
1992
|
+
//#region src/components/dnd/state/use-delete-flow.ts
|
|
1993
|
+
const useDeleteFlow = ({ sections, remove, onBeforeDelete }) => {
|
|
1994
|
+
const removeRef = useRef(remove);
|
|
1995
|
+
useEffect(() => {
|
|
1996
|
+
removeRef.current = remove;
|
|
1834
1997
|
});
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
};
|
|
1841
|
-
const isNewItemOver = isOver && active?.data.current?.type === "new-item";
|
|
1842
|
-
const onKeyDown = (e) => {
|
|
1843
|
-
listeners?.onKeyDown?.(e);
|
|
1844
|
-
if (e.target !== e.currentTarget || active || e.defaultPrevented) return;
|
|
1845
|
-
if (e.key === "Enter") {
|
|
1846
|
-
e.preventDefault();
|
|
1847
|
-
onClick?.();
|
|
1998
|
+
return (id, onDeleted) => {
|
|
1999
|
+
const section = sections.find((candidate) => candidate.id === id);
|
|
2000
|
+
if (!onBeforeDelete || !section) {
|
|
2001
|
+
remove(id);
|
|
2002
|
+
onDeleted?.();
|
|
1848
2003
|
return;
|
|
1849
2004
|
}
|
|
1850
|
-
const
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
2005
|
+
const decide = (allowed) => {
|
|
2006
|
+
if (allowed) {
|
|
2007
|
+
removeRef.current(id);
|
|
2008
|
+
onDeleted?.();
|
|
2009
|
+
}
|
|
2010
|
+
};
|
|
2011
|
+
try {
|
|
2012
|
+
const answer = onBeforeDelete(section);
|
|
2013
|
+
if (typeof answer === "boolean") {
|
|
2014
|
+
decide(answer);
|
|
2015
|
+
return;
|
|
2016
|
+
}
|
|
2017
|
+
answer.then(decide, (error) => {
|
|
2018
|
+
console.error("onBeforeDelete rejected; the section was kept", error);
|
|
2019
|
+
});
|
|
2020
|
+
} catch (error) {
|
|
2021
|
+
console.error("onBeforeDelete threw; the section was kept", error);
|
|
1855
2022
|
}
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
2023
|
+
};
|
|
2024
|
+
};
|
|
2025
|
+
//#endregion
|
|
2026
|
+
//#region src/components/dnd/state/use-dnd-keyboard.ts
|
|
2027
|
+
const KEYBOARD_CODES = {
|
|
2028
|
+
start: ["Space"],
|
|
2029
|
+
cancel: ["Escape"],
|
|
2030
|
+
end: ["Space", "Enter"]
|
|
2031
|
+
};
|
|
2032
|
+
const createNodeRegistry = () => {
|
|
2033
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
2034
|
+
const callbacks = /* @__PURE__ */ new Map();
|
|
2035
|
+
return {
|
|
2036
|
+
get: (id) => nodes.get(id),
|
|
2037
|
+
register: (id) => {
|
|
2038
|
+
let callback = callbacks.get(id);
|
|
2039
|
+
if (!callback) {
|
|
2040
|
+
callback = (node) => {
|
|
2041
|
+
if (node) nodes.set(id, node);
|
|
2042
|
+
else {
|
|
2043
|
+
nodes.delete(id);
|
|
2044
|
+
callbacks.delete(id);
|
|
2045
|
+
}
|
|
2046
|
+
};
|
|
2047
|
+
callbacks.set(id, callback);
|
|
2048
|
+
}
|
|
2049
|
+
return callback;
|
|
1859
2050
|
}
|
|
1860
2051
|
};
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
2052
|
+
};
|
|
2053
|
+
const useDndKeyboard = ({ sections, selectedId, selectedIndex, selectOnly, move, requestDelete }) => {
|
|
2054
|
+
const { announcements: say } = useLiveMessages();
|
|
2055
|
+
const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 10 } }), useSensor(KeyboardSensor, {
|
|
2056
|
+
coordinateGetter: sortableKeyboardCoordinates,
|
|
2057
|
+
keyboardCodes: KEYBOARD_CODES
|
|
2058
|
+
}));
|
|
2059
|
+
const nameOf = (id, data) => {
|
|
2060
|
+
return paletteSectionOf(data)?.name ?? sections.find((section) => section.id === id)?.name ?? say.section;
|
|
1865
2061
|
};
|
|
1866
|
-
const
|
|
1867
|
-
|
|
1868
|
-
|
|
2062
|
+
const positionOf = (id) => sections.findIndex((section) => section.id === id) + 1;
|
|
2063
|
+
const announcements = {
|
|
2064
|
+
onDragStart: ({ active }) => say.pickedUp(nameOf(active.id, active.data)),
|
|
2065
|
+
onDragOver: ({ active, over }) => over && positionOf(over.id) > 0 ? say.movedTo(nameOf(active.id, active.data), positionOf(over.id), sections.length) : say.notOver(nameOf(active.id, active.data)),
|
|
2066
|
+
onDragEnd: ({ active, over }) => over && positionOf(over.id) > 0 ? say.droppedAt(nameOf(active.id, active.data), positionOf(over.id), sections.length) : say.dropped(nameOf(active.id, active.data)),
|
|
2067
|
+
onDragCancel: ({ active }) => say.cancelled(nameOf(active.id, active.data))
|
|
1869
2068
|
};
|
|
1870
|
-
const
|
|
1871
|
-
|
|
1872
|
-
|
|
2069
|
+
const screenReaderInstructions = { draggable: say.instructions };
|
|
2070
|
+
const [sectionNodes] = useState(createNodeRegistry);
|
|
2071
|
+
const focusSection = (id) => sectionNodes.get(id)?.focus();
|
|
2072
|
+
const onNavigate = (fromId, to) => {
|
|
2073
|
+
const from = sections.findIndex((section) => section.id === fromId);
|
|
2074
|
+
const target = sections[to === "first" ? 0 : to === "last" ? sections.length - 1 : from + (to === "next" ? 1 : -1)];
|
|
2075
|
+
if (from < 0 || !target || target.id === fromId) return;
|
|
2076
|
+
selectOnly(target.id);
|
|
2077
|
+
focusSection(target.id);
|
|
2078
|
+
};
|
|
2079
|
+
const onDeleteKey = (id) => {
|
|
2080
|
+
const index = sections.findIndex((section) => section.id === id);
|
|
2081
|
+
const neighbor = sections[index + 1] ?? sections[index - 1];
|
|
2082
|
+
requestDelete(id, () => {
|
|
2083
|
+
if (neighbor) focusSection(neighbor.id);
|
|
2084
|
+
});
|
|
2085
|
+
};
|
|
2086
|
+
const onMoveButton = (id, direction) => {
|
|
2087
|
+
const to = sections.findIndex((section) => section.id === id) + (direction === "up" ? -1 : 1);
|
|
2088
|
+
move(id, direction);
|
|
2089
|
+
if (to === 0 || to === sections.length - 1) focusSection(id);
|
|
2090
|
+
};
|
|
2091
|
+
useEffect(() => {
|
|
2092
|
+
if (selectedId === null) return;
|
|
2093
|
+
const frame = requestAnimationFrame(() => {
|
|
2094
|
+
sectionNodes.get(selectedId)?.scrollIntoView?.({ block: "nearest" });
|
|
2095
|
+
});
|
|
2096
|
+
return () => cancelAnimationFrame(frame);
|
|
2097
|
+
}, [
|
|
2098
|
+
sectionNodes,
|
|
2099
|
+
selectedId,
|
|
2100
|
+
selectedIndex
|
|
2101
|
+
]);
|
|
2102
|
+
return {
|
|
2103
|
+
sensors,
|
|
2104
|
+
announcements,
|
|
2105
|
+
screenReaderInstructions,
|
|
2106
|
+
sectionNodes,
|
|
2107
|
+
onNavigate,
|
|
2108
|
+
onDeleteKey,
|
|
2109
|
+
onMoveButton
|
|
2110
|
+
};
|
|
2111
|
+
};
|
|
2112
|
+
//#endregion
|
|
2113
|
+
//#region src/components/dnd/state/use-inspector-state.ts
|
|
2114
|
+
const useInspectorState = ({ selectedId, selectOnly, sectionNodes, onNodePick }) => {
|
|
2115
|
+
const [inspecting, setInspecting] = useState(false);
|
|
2116
|
+
const [picked, setPicked] = useState(null);
|
|
2117
|
+
const [hoverRect, setHoverRect] = useState(null);
|
|
2118
|
+
const [fieldTarget, setFieldTarget] = useState(null);
|
|
2119
|
+
const [fieldRect, setFieldRect] = useState(null);
|
|
2120
|
+
if (picked && picked.sectionId !== selectedId) setPicked(null);
|
|
2121
|
+
const stopInspecting = useCallback(() => {
|
|
2122
|
+
setInspecting(false);
|
|
2123
|
+
setHoverRect(null);
|
|
2124
|
+
}, []);
|
|
2125
|
+
useEffect(() => {
|
|
2126
|
+
if (!inspecting) return;
|
|
2127
|
+
const onKeyDown = (e) => {
|
|
2128
|
+
if (e.key === "Escape") stopInspecting();
|
|
2129
|
+
};
|
|
2130
|
+
window.addEventListener("keydown", onKeyDown);
|
|
2131
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
2132
|
+
}, [inspecting, stopInspecting]);
|
|
2133
|
+
useEffect(() => {
|
|
2134
|
+
const section = selectedId === null ? null : sectionNodes.get(selectedId);
|
|
2135
|
+
if (!fieldTarget || !section) return;
|
|
2136
|
+
let frame = 0;
|
|
2137
|
+
const measure = () => {
|
|
2138
|
+
cancelAnimationFrame(frame);
|
|
2139
|
+
frame = requestAnimationFrame(() => {
|
|
2140
|
+
const element = findElementById(section, fieldTarget);
|
|
2141
|
+
setFieldRect(element ? viewportRect(element) : null);
|
|
2142
|
+
});
|
|
2143
|
+
};
|
|
2144
|
+
measure();
|
|
2145
|
+
window.addEventListener("scroll", measure, true);
|
|
2146
|
+
window.addEventListener("resize", measure);
|
|
2147
|
+
return () => {
|
|
2148
|
+
cancelAnimationFrame(frame);
|
|
2149
|
+
window.removeEventListener("scroll", measure, true);
|
|
2150
|
+
window.removeEventListener("resize", measure);
|
|
2151
|
+
};
|
|
2152
|
+
}, [
|
|
2153
|
+
fieldTarget,
|
|
2154
|
+
selectedId,
|
|
2155
|
+
sectionNodes
|
|
2156
|
+
]);
|
|
2157
|
+
const inspector = {
|
|
2158
|
+
active: inspecting,
|
|
2159
|
+
activate: () => setInspecting(true),
|
|
2160
|
+
deactivate: stopInspecting,
|
|
2161
|
+
toggle: () => inspecting ? stopInspecting() : setInspecting(true),
|
|
2162
|
+
picked,
|
|
2163
|
+
highlight: setFieldTarget
|
|
2164
|
+
};
|
|
2165
|
+
const onInspectMove = (section, overlay, x, y) => {
|
|
2166
|
+
const element = pickElement(section, overlay, x, y);
|
|
2167
|
+
setHoverRect(element ? viewportRect(element) : null);
|
|
2168
|
+
};
|
|
2169
|
+
const onInspectPick = (sectionId, section, overlay, x, y) => {
|
|
2170
|
+
const id = pickElement(section, overlay, x, y)?.getAttribute(DATA_ATTR.ID);
|
|
2171
|
+
if (!id) return;
|
|
2172
|
+
const pick = {
|
|
2173
|
+
id,
|
|
2174
|
+
sectionId
|
|
2175
|
+
};
|
|
2176
|
+
selectOnly(sectionId);
|
|
2177
|
+
setPicked(pick);
|
|
2178
|
+
stopInspecting();
|
|
2179
|
+
onNodePick?.(pick);
|
|
1873
2180
|
};
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
2181
|
+
return {
|
|
2182
|
+
inspector,
|
|
2183
|
+
inspecting,
|
|
2184
|
+
onInspectMove,
|
|
2185
|
+
onInspectPick,
|
|
2186
|
+
onInspectLeave: () => setHoverRect(null),
|
|
2187
|
+
highlightRect: inspecting ? hoverRect : fieldTarget ? fieldRect : null
|
|
1877
2188
|
};
|
|
1878
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
1879
|
-
ref: setRefs,
|
|
1880
|
-
style,
|
|
1881
|
-
...attributes,
|
|
1882
|
-
...listeners,
|
|
1883
|
-
onKeyDown,
|
|
1884
|
-
onClick,
|
|
1885
|
-
className: cn("relative", selected && "z-10 outline-2 outline-offset-2 outline-blue-500", isNewItemOver && "border-t-4 border-t-green-500"),
|
|
1886
|
-
children: [
|
|
1887
|
-
/* @__PURE__ */ jsx("div", {
|
|
1888
|
-
className: cn("absolute inset-0 z-50"),
|
|
1889
|
-
onPointerMove: inspecting ? (e) => onInspectMove?.(e.currentTarget.parentElement, e.currentTarget, e.clientX, e.clientY) : void 0,
|
|
1890
|
-
onPointerLeave: inspecting ? onInspectLeave : void 0,
|
|
1891
|
-
onClick: inspecting ? (e) => {
|
|
1892
|
-
e.stopPropagation();
|
|
1893
|
-
onInspectPick?.(e.currentTarget.parentElement, e.currentTarget, e.clientX, e.clientY);
|
|
1894
|
-
} : void 0
|
|
1895
|
-
}),
|
|
1896
|
-
children,
|
|
1897
|
-
selected && /* @__PURE__ */ jsxs(Space, {
|
|
1898
|
-
className: cn("absolute top-1 right-1 z-60"),
|
|
1899
|
-
children: [
|
|
1900
|
-
onMoveUp && /* @__PURE__ */ jsx(Button, {
|
|
1901
|
-
icon: /* @__PURE__ */ jsx(ChevronUp, {}),
|
|
1902
|
-
disabled: !canMoveUp,
|
|
1903
|
-
onClick: press(onMoveUp),
|
|
1904
|
-
"aria-label": "Move section up"
|
|
1905
|
-
}),
|
|
1906
|
-
onMoveDown && /* @__PURE__ */ jsx(Button, {
|
|
1907
|
-
icon: /* @__PURE__ */ jsx(ChevronDown, {}),
|
|
1908
|
-
disabled: !canMoveDown,
|
|
1909
|
-
onClick: press(onMoveDown),
|
|
1910
|
-
"aria-label": "Move section down"
|
|
1911
|
-
}),
|
|
1912
|
-
/* @__PURE__ */ jsx(Button, {
|
|
1913
|
-
icon: /* @__PURE__ */ jsx(Copy, {}),
|
|
1914
|
-
onClick: onCopy,
|
|
1915
|
-
"aria-label": "Duplicate section"
|
|
1916
|
-
}),
|
|
1917
|
-
/* @__PURE__ */ jsx(Button, {
|
|
1918
|
-
danger: true,
|
|
1919
|
-
icon: /* @__PURE__ */ jsx(Trash, {}),
|
|
1920
|
-
onClick: onDelete,
|
|
1921
|
-
"aria-label": "Delete section"
|
|
1922
|
-
})
|
|
1923
|
-
]
|
|
1924
|
-
})
|
|
1925
|
-
]
|
|
1926
|
-
});
|
|
1927
|
-
};
|
|
1928
|
-
//#endregion
|
|
1929
|
-
//#region src/components/dnd/overlay.tsx
|
|
1930
|
-
const Overlay = ({ sections, isForced, renderProps }) => {
|
|
1931
|
-
const { active } = useDndContext();
|
|
1932
|
-
if (!active) return null;
|
|
1933
|
-
if (active.data.current?.type === "new-item") {
|
|
1934
|
-
const item = active.data.current.item;
|
|
1935
|
-
return /* @__PURE__ */ jsx(DefaultDraggableItem, { item });
|
|
1936
|
-
}
|
|
1937
|
-
const section = sections.find((s) => s.id === active.id);
|
|
1938
|
-
if (section) {
|
|
1939
|
-
const preview = generateSection(section.code, renderProps.fullCode, { containerId: renderProps.containerId });
|
|
1940
|
-
return /* @__PURE__ */ jsx(Sortable, {
|
|
1941
|
-
id: section.id,
|
|
1942
|
-
name: section.name,
|
|
1943
|
-
children: /* @__PURE__ */ jsx(renderer_default, {
|
|
1944
|
-
preview,
|
|
1945
|
-
sectionId: section.id,
|
|
1946
|
-
sectionName: section.name,
|
|
1947
|
-
sectionCode: section.code,
|
|
1948
|
-
forceFallback: isForced?.(section) ?? false,
|
|
1949
|
-
modules: renderProps.modules,
|
|
1950
|
-
frame: renderProps.frame,
|
|
1951
|
-
dynamicTailwind: renderProps.dynamicTailwind
|
|
1952
|
-
})
|
|
1953
|
-
});
|
|
1954
|
-
}
|
|
1955
|
-
return null;
|
|
1956
2189
|
};
|
|
1957
2190
|
//#endregion
|
|
1958
|
-
//#region src/components/dnd/use-section-document.ts
|
|
2191
|
+
//#region src/components/dnd/state/use-section-document.ts
|
|
1959
2192
|
const createLastParsed = () => {
|
|
1960
2193
|
let last = null;
|
|
1961
2194
|
return {
|
|
@@ -2008,7 +2241,7 @@ const useSectionDocument = (value, onChange, { containerId, sectionNameFallback,
|
|
|
2008
2241
|
view.document
|
|
2009
2242
|
]);
|
|
2010
2243
|
const selectedIndex = sections.findIndex((s) => s.id === selectedId);
|
|
2011
|
-
const
|
|
2244
|
+
const selectedSection = selectedIndex >= 0 ? sections[selectedIndex] : void 0;
|
|
2012
2245
|
const pendingRef = useRef(null);
|
|
2013
2246
|
useEffect(() => {
|
|
2014
2247
|
pendingRef.current = null;
|
|
@@ -2054,17 +2287,17 @@ const useSectionDocument = (value, onChange, { containerId, sectionNameFallback,
|
|
|
2054
2287
|
sections,
|
|
2055
2288
|
previews,
|
|
2056
2289
|
selectedId,
|
|
2057
|
-
|
|
2290
|
+
selectedSection,
|
|
2058
2291
|
selectedIndex,
|
|
2059
2292
|
select: useCallback((id) => {
|
|
2060
2293
|
setSelectedId((prev) => prev === id ? null : id);
|
|
2061
2294
|
}, []),
|
|
2062
2295
|
selectOnly: useCallback((id) => setSelectedId(id), []),
|
|
2063
2296
|
clearSelection: useCallback(() => setSelectedId(null), []),
|
|
2064
|
-
add: useCallback((
|
|
2297
|
+
add: useCallback((section, atIndex) => {
|
|
2065
2298
|
if (refuse()) return;
|
|
2066
2299
|
const current = latestSections();
|
|
2067
|
-
const next = { code:
|
|
2300
|
+
const next = { code: section.code };
|
|
2068
2301
|
commit(atIndex === void 0 || atIndex < 0 ? [...current, next] : [
|
|
2069
2302
|
...current.slice(0, atIndex),
|
|
2070
2303
|
next,
|
|
@@ -2148,85 +2381,69 @@ const useSectionDocument = (value, onChange, { containerId, sectionNameFallback,
|
|
|
2148
2381
|
};
|
|
2149
2382
|
//#endregion
|
|
2150
2383
|
//#region src/components/dnd/dnd.tsx
|
|
2151
|
-
const describeUpdateFailure = (failure, label) => {
|
|
2384
|
+
const describeUpdateFailure = (failure, label, { editErrors: m }) => {
|
|
2152
2385
|
switch (failure?.reason) {
|
|
2153
2386
|
case "attribute-not-found": return {
|
|
2154
|
-
title:
|
|
2155
|
-
description:
|
|
2387
|
+
title: m.updateFailed(label),
|
|
2388
|
+
description: m.attributeNotFound(failure.property)
|
|
2156
2389
|
};
|
|
2157
2390
|
case "binding-not-declared": return {
|
|
2158
|
-
title:
|
|
2159
|
-
description:
|
|
2391
|
+
title: m.updateFailed(label),
|
|
2392
|
+
description: m.bindingNotDeclared({
|
|
2393
|
+
label,
|
|
2394
|
+
property: failure.property
|
|
2395
|
+
})
|
|
2160
2396
|
};
|
|
2161
2397
|
case "duplicate-binding": return {
|
|
2162
|
-
title:
|
|
2163
|
-
description:
|
|
2398
|
+
title: m.updateFailed(label),
|
|
2399
|
+
description: m.duplicateBinding({
|
|
2400
|
+
count: failure.count,
|
|
2401
|
+
label,
|
|
2402
|
+
property: failure.property
|
|
2403
|
+
})
|
|
2164
2404
|
};
|
|
2165
2405
|
case "reserved-property": return {
|
|
2166
|
-
title:
|
|
2167
|
-
description:
|
|
2406
|
+
title: m.cannotEdit(label),
|
|
2407
|
+
description: m.reservedProperty(failure.property)
|
|
2168
2408
|
};
|
|
2169
2409
|
case "required-property": return {
|
|
2170
|
-
title:
|
|
2171
|
-
description:
|
|
2410
|
+
title: m.cannotRemove(label),
|
|
2411
|
+
description: m.requiredProperty(failure.property)
|
|
2172
2412
|
};
|
|
2173
2413
|
case "no-binding": return {
|
|
2174
|
-
title:
|
|
2175
|
-
description:
|
|
2414
|
+
title: m.updateFailed(label),
|
|
2415
|
+
description: m.noBinding
|
|
2176
2416
|
};
|
|
2177
2417
|
case "element-not-found": return {
|
|
2178
|
-
title:
|
|
2179
|
-
description:
|
|
2418
|
+
title: m.updateFailed(label),
|
|
2419
|
+
description: m.elementNotFound
|
|
2420
|
+
};
|
|
2421
|
+
case "self-closing": return {
|
|
2422
|
+
title: m.cannotEdit(label),
|
|
2423
|
+
description: m.selfClosing(failure.property)
|
|
2180
2424
|
};
|
|
2181
2425
|
case "unsupported-syntax": return {
|
|
2182
|
-
title:
|
|
2183
|
-
description:
|
|
2426
|
+
title: m.cannotEdit(label),
|
|
2427
|
+
description: m.unsupportedSyntax(failure.property)
|
|
2184
2428
|
};
|
|
2185
2429
|
case "parse-error": return {
|
|
2186
|
-
title:
|
|
2187
|
-
description: failure.error instanceof Error ? failure.error.message :
|
|
2430
|
+
title: m.updateFailed(label),
|
|
2431
|
+
description: failure.error instanceof Error ? failure.error.message : m.checkConsole
|
|
2188
2432
|
};
|
|
2189
|
-
default: return { title:
|
|
2433
|
+
default: return { title: m.updateFailed(label) };
|
|
2190
2434
|
}
|
|
2191
2435
|
};
|
|
2192
|
-
const
|
|
2193
|
-
start: ["Space"],
|
|
2194
|
-
cancel: ["Escape"],
|
|
2195
|
-
end: ["Space", "Enter"]
|
|
2196
|
-
};
|
|
2197
|
-
const SCREEN_READER_INSTRUCTIONS = { draggable: "On a palette item, press Enter to add it to the canvas. On a canvas section, press Enter to select it, the up and down arrow keys to go to the previous or next section, and Delete to remove it. Press Space to pick a section up, the arrow keys to move it, and Space or Enter to drop it. Press Escape to cancel." };
|
|
2198
|
-
const createNodeRegistry = () => {
|
|
2199
|
-
const nodes = /* @__PURE__ */ new Map();
|
|
2200
|
-
const callbacks = /* @__PURE__ */ new Map();
|
|
2201
|
-
return {
|
|
2202
|
-
get: (id) => nodes.get(id),
|
|
2203
|
-
register: (id) => {
|
|
2204
|
-
let callback = callbacks.get(id);
|
|
2205
|
-
if (!callback) {
|
|
2206
|
-
callback = (node) => {
|
|
2207
|
-
if (node) nodes.set(id, node);
|
|
2208
|
-
else {
|
|
2209
|
-
nodes.delete(id);
|
|
2210
|
-
callbacks.delete(id);
|
|
2211
|
-
}
|
|
2212
|
-
};
|
|
2213
|
-
callbacks.set(id, callback);
|
|
2214
|
-
}
|
|
2215
|
-
return callback;
|
|
2216
|
-
}
|
|
2217
|
-
};
|
|
2218
|
-
};
|
|
2219
|
-
const blockedEditError = (error) => ({
|
|
2436
|
+
const blockedEditError = (error, { editErrors: m }) => ({
|
|
2220
2437
|
type: "parse",
|
|
2221
2438
|
target: "document",
|
|
2222
2439
|
reason: "parse-error",
|
|
2223
2440
|
error,
|
|
2224
|
-
title:
|
|
2225
|
-
description:
|
|
2441
|
+
title: m.syntaxError,
|
|
2442
|
+
description: m.syntaxErrorDetail
|
|
2226
2443
|
});
|
|
2227
2444
|
const conditionalModifiers = (args) => {
|
|
2228
2445
|
const { active } = args;
|
|
2229
|
-
if (active?.data
|
|
2446
|
+
if (paletteSectionOf(active?.data)) return args.transform;
|
|
2230
2447
|
return restrictToVerticalAxis(args);
|
|
2231
2448
|
};
|
|
2232
2449
|
const NO_MODULES = {};
|
|
@@ -2244,179 +2461,56 @@ const Dnd$1 = ({ value: _value, props, modules: _modules = NO_MODULES, onChange:
|
|
|
2244
2461
|
return false;
|
|
2245
2462
|
}
|
|
2246
2463
|
};
|
|
2247
|
-
const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 10 } }), useSensor(KeyboardSensor, {
|
|
2248
|
-
coordinateGetter: sortableKeyboardCoordinates,
|
|
2249
|
-
keyboardCodes: KEYBOARD_CODES
|
|
2250
|
-
}));
|
|
2251
|
-
const nameOf = (id, data) => {
|
|
2252
|
-
return (data?.current)?.item?.name ?? sections.find((section) => section.id === id)?.name ?? "section";
|
|
2253
|
-
};
|
|
2254
|
-
const positionOf = (id) => sections.findIndex((section) => section.id === id) + 1;
|
|
2255
|
-
const announcements = {
|
|
2256
|
-
onDragStart: ({ active }) => `Picked up ${nameOf(active.id, active.data)}.`,
|
|
2257
|
-
onDragOver: ({ active, over }) => over && positionOf(over.id) > 0 ? `${nameOf(active.id, active.data)} moved to position ${positionOf(over.id)} of ${sections.length}.` : `${nameOf(active.id, active.data)} is no longer over a position.`,
|
|
2258
|
-
onDragEnd: ({ active, over }) => over && positionOf(over.id) > 0 ? `${nameOf(active.id, active.data)} dropped at position ${positionOf(over.id)} of ${sections.length}.` : `${nameOf(active.id, active.data)} dropped.`,
|
|
2259
|
-
onDragCancel: ({ active }) => `Moving ${nameOf(active.id, active.data)} was cancelled.`
|
|
2260
|
-
};
|
|
2261
2464
|
const value = _value === void 0 ? code : _value;
|
|
2465
|
+
const messages = useLiveMessages();
|
|
2262
2466
|
const reportError = onEditError ?? toastEditError;
|
|
2263
2467
|
const reportErrorRef = useRef(reportError);
|
|
2468
|
+
const messagesRef = useRef(messages);
|
|
2264
2469
|
useEffect(() => {
|
|
2265
2470
|
reportErrorRef.current = reportError;
|
|
2471
|
+
messagesRef.current = messages;
|
|
2266
2472
|
});
|
|
2267
2473
|
const onBlockedEdit = useCallback((problem) => {
|
|
2268
|
-
if (problem.reason === "parse-error") reportErrorRef.current(blockedEditError(problem.error));
|
|
2474
|
+
if (problem.reason === "parse-error") reportErrorRef.current(blockedEditError(problem.error, messagesRef.current));
|
|
2269
2475
|
}, []);
|
|
2270
|
-
const { sections, previews, selectedId,
|
|
2476
|
+
const { sections, previews, selectedId, selectedSection, selectedIndex, select, selectOnly, clearSelection, add: addSection, remove, copy: onCopy, move: moveSection, reorder, patch, getCommittedSection, problem, stale } = useSectionDocument(value, _onChange, {
|
|
2271
2477
|
containerId,
|
|
2272
2478
|
sectionNameFallback,
|
|
2273
2479
|
onBlockedEdit
|
|
2274
2480
|
});
|
|
2275
2481
|
const missingContainer = problem?.reason === "container-not-found" ? problem.containerId : null;
|
|
2276
|
-
const onDragStart = (_) => {};
|
|
2277
|
-
const onDragOver = (_e) => {};
|
|
2278
2482
|
const onDragEnd = (event) => {
|
|
2279
2483
|
const { active, over } = event;
|
|
2280
2484
|
if (!over) return;
|
|
2281
|
-
|
|
2282
|
-
|
|
2485
|
+
const section = paletteSectionOf(active.data);
|
|
2486
|
+
if (section) {
|
|
2283
2487
|
const atBottom = over.id === "sortable-area" || over.id === "sortable-area-bottom";
|
|
2284
|
-
|
|
2488
|
+
addSection(section, atBottom ? void 0 : sections.findIndex((s) => s.id === over.id));
|
|
2285
2489
|
return;
|
|
2286
2490
|
}
|
|
2287
2491
|
if (active.id !== over.id && sections.some((s) => s.id === active.id)) reorder(String(active.id), String(over.id));
|
|
2288
2492
|
};
|
|
2289
2493
|
const onSelect = (id) => select(id);
|
|
2290
|
-
const
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
const [fieldRect, setFieldRect] = useState(null);
|
|
2295
|
-
if (picked && picked.sectionId !== selectedId) setPicked(null);
|
|
2296
|
-
const stopInspecting = useCallback(() => {
|
|
2297
|
-
setInspecting(false);
|
|
2298
|
-
setHighlight(null);
|
|
2299
|
-
}, []);
|
|
2300
|
-
useEffect(() => {
|
|
2301
|
-
if (!inspecting) return;
|
|
2302
|
-
const onKeyDown = (e) => {
|
|
2303
|
-
if (e.key === "Escape") stopInspecting();
|
|
2304
|
-
};
|
|
2305
|
-
window.addEventListener("keydown", onKeyDown);
|
|
2306
|
-
return () => window.removeEventListener("keydown", onKeyDown);
|
|
2307
|
-
}, [inspecting, stopInspecting]);
|
|
2308
|
-
const inspector = {
|
|
2309
|
-
active: inspecting,
|
|
2310
|
-
activate: () => setInspecting(true),
|
|
2311
|
-
deactivate: stopInspecting,
|
|
2312
|
-
toggle: () => inspecting ? stopInspecting() : setInspecting(true),
|
|
2313
|
-
picked,
|
|
2314
|
-
highlight: setFieldTarget
|
|
2315
|
-
};
|
|
2316
|
-
const onInspectMove = (section, overlay, x, y) => {
|
|
2317
|
-
const element = pickElement(section, overlay, x, y);
|
|
2318
|
-
setHighlight(element ? viewportRect(element) : null);
|
|
2319
|
-
};
|
|
2320
|
-
const onInspectPick = (sectionId, section, overlay, x, y) => {
|
|
2321
|
-
const id = pickElement(section, overlay, x, y)?.getAttribute(DATA_ATTR.ID);
|
|
2322
|
-
if (!id) return;
|
|
2323
|
-
const pick = {
|
|
2324
|
-
id,
|
|
2325
|
-
sectionId
|
|
2326
|
-
};
|
|
2327
|
-
selectOnly(sectionId);
|
|
2328
|
-
setPicked(pick);
|
|
2329
|
-
stopInspecting();
|
|
2330
|
-
onNodePick?.(pick);
|
|
2331
|
-
};
|
|
2332
|
-
const removeRef = useRef(remove);
|
|
2333
|
-
useEffect(() => {
|
|
2334
|
-
removeRef.current = remove;
|
|
2494
|
+
const requestDelete = useDeleteFlow({
|
|
2495
|
+
sections,
|
|
2496
|
+
remove,
|
|
2497
|
+
onBeforeDelete
|
|
2335
2498
|
});
|
|
2336
|
-
const requestDelete = (id, onDeleted) => {
|
|
2337
|
-
const section = sections.find((candidate) => candidate.id === id);
|
|
2338
|
-
if (!onBeforeDelete || !section) {
|
|
2339
|
-
remove(id);
|
|
2340
|
-
onDeleted?.();
|
|
2341
|
-
return;
|
|
2342
|
-
}
|
|
2343
|
-
const decide = (allowed) => {
|
|
2344
|
-
if (allowed) {
|
|
2345
|
-
removeRef.current(id);
|
|
2346
|
-
onDeleted?.();
|
|
2347
|
-
}
|
|
2348
|
-
};
|
|
2349
|
-
try {
|
|
2350
|
-
const answer = onBeforeDelete(section);
|
|
2351
|
-
if (typeof answer === "boolean") {
|
|
2352
|
-
decide(answer);
|
|
2353
|
-
return;
|
|
2354
|
-
}
|
|
2355
|
-
answer.then(decide, (error) => {
|
|
2356
|
-
console.error("onBeforeDelete rejected; the section was kept", error);
|
|
2357
|
-
});
|
|
2358
|
-
} catch (error) {
|
|
2359
|
-
console.error("onBeforeDelete threw; the section was kept", error);
|
|
2360
|
-
}
|
|
2361
|
-
};
|
|
2362
2499
|
const onDelete = (id) => requestDelete(id);
|
|
2363
|
-
const
|
|
2364
|
-
|
|
2365
|
-
const onNavigate = (fromId, to) => {
|
|
2366
|
-
const from = sections.findIndex((section) => section.id === fromId);
|
|
2367
|
-
const index = to === "first" ? 0 : to === "last" ? sections.length - 1 : from + (to === "next" ? 1 : -1);
|
|
2368
|
-
const target = sections[index];
|
|
2369
|
-
if (from < 0 || !target || target.id === fromId) return;
|
|
2370
|
-
selectOnly(target.id);
|
|
2371
|
-
focusSection(target.id);
|
|
2372
|
-
};
|
|
2373
|
-
const onDeleteKey = (id) => {
|
|
2374
|
-
const index = sections.findIndex((section) => section.id === id);
|
|
2375
|
-
const neighbor = sections[index + 1] ?? sections[index - 1];
|
|
2376
|
-
requestDelete(id, () => {
|
|
2377
|
-
if (neighbor) focusSection(neighbor.id);
|
|
2378
|
-
});
|
|
2379
|
-
};
|
|
2380
|
-
const onMoveButton = (id, direction) => {
|
|
2381
|
-
const to = sections.findIndex((section) => section.id === id) + (direction === "up" ? -1 : 1);
|
|
2382
|
-
moveSection(id, direction);
|
|
2383
|
-
if (to === 0 || to === sections.length - 1) focusSection(id);
|
|
2384
|
-
};
|
|
2385
|
-
useEffect(() => {
|
|
2386
|
-
const section = selectedId === null ? null : sectionNodes.get(selectedId);
|
|
2387
|
-
if (!fieldTarget || !section) return;
|
|
2388
|
-
let frame = 0;
|
|
2389
|
-
const measure = () => {
|
|
2390
|
-
cancelAnimationFrame(frame);
|
|
2391
|
-
frame = requestAnimationFrame(() => {
|
|
2392
|
-
const element = findElementById(section, fieldTarget);
|
|
2393
|
-
setFieldRect(element ? viewportRect(element) : null);
|
|
2394
|
-
});
|
|
2395
|
-
};
|
|
2396
|
-
measure();
|
|
2397
|
-
window.addEventListener("scroll", measure, true);
|
|
2398
|
-
window.addEventListener("resize", measure);
|
|
2399
|
-
return () => {
|
|
2400
|
-
cancelAnimationFrame(frame);
|
|
2401
|
-
window.removeEventListener("scroll", measure, true);
|
|
2402
|
-
window.removeEventListener("resize", measure);
|
|
2403
|
-
};
|
|
2404
|
-
}, [
|
|
2405
|
-
fieldTarget,
|
|
2500
|
+
const { sensors, announcements, screenReaderInstructions, sectionNodes, onNavigate, onDeleteKey, onMoveButton } = useDndKeyboard({
|
|
2501
|
+
sections,
|
|
2406
2502
|
selectedId,
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
});
|
|
2414
|
-
return () => cancelAnimationFrame(frame);
|
|
2415
|
-
}, [
|
|
2416
|
-
sectionNodes,
|
|
2503
|
+
selectedIndex,
|
|
2504
|
+
selectOnly,
|
|
2505
|
+
move: moveSection,
|
|
2506
|
+
requestDelete
|
|
2507
|
+
});
|
|
2508
|
+
const { inspector, inspecting, onInspectMove, onInspectPick, onInspectLeave, highlightRect } = useInspectorState({
|
|
2417
2509
|
selectedId,
|
|
2418
|
-
|
|
2419
|
-
|
|
2510
|
+
selectOnly,
|
|
2511
|
+
sectionNodes,
|
|
2512
|
+
onNodePick
|
|
2513
|
+
});
|
|
2420
2514
|
const onChange = (next) => {
|
|
2421
2515
|
if (!next.id) return;
|
|
2422
2516
|
patch(next);
|
|
@@ -2425,8 +2519,8 @@ const Dnd$1 = ({ value: _value, props, modules: _modules = NO_MODULES, onChange:
|
|
|
2425
2519
|
bindings: bindingRegistry,
|
|
2426
2520
|
bindingKeys
|
|
2427
2521
|
}), [bindingRegistry, bindingKeys]);
|
|
2428
|
-
const selectedCode =
|
|
2429
|
-
const selectedSectionId =
|
|
2522
|
+
const selectedCode = selectedSection?.code;
|
|
2523
|
+
const selectedSectionId = selectedSection?.id;
|
|
2430
2524
|
const { fields, updatedCode, parseError } = useMemo(() => {
|
|
2431
2525
|
if (!selectedCode) return {
|
|
2432
2526
|
fields: [],
|
|
@@ -2459,8 +2553,8 @@ const Dnd$1 = ({ value: _value, props, modules: _modules = NO_MODULES, onChange:
|
|
|
2459
2553
|
target: "document",
|
|
2460
2554
|
reason: "container-not-found",
|
|
2461
2555
|
containerId: missingContainer,
|
|
2462
|
-
title:
|
|
2463
|
-
description:
|
|
2556
|
+
title: messagesRef.current.editErrors.missingContainer(missingContainer),
|
|
2557
|
+
description: messagesRef.current.editErrors.missingContainerDetail(missingContainer)
|
|
2464
2558
|
});
|
|
2465
2559
|
}, [missingContainer]);
|
|
2466
2560
|
useEffect(() => {
|
|
@@ -2468,17 +2562,17 @@ const Dnd$1 = ({ value: _value, props, modules: _modules = NO_MODULES, onChange:
|
|
|
2468
2562
|
type: "parse",
|
|
2469
2563
|
target: "section",
|
|
2470
2564
|
error: parseError.error,
|
|
2471
|
-
title:
|
|
2472
|
-
description:
|
|
2565
|
+
title: messagesRef.current.editErrors.sectionParseFailed,
|
|
2566
|
+
description: messagesRef.current.editErrors.checkConsole
|
|
2473
2567
|
});
|
|
2474
2568
|
}, [parseError]);
|
|
2475
2569
|
const commitChanges = (changes) => {
|
|
2476
2570
|
if (changes.length === 0) return;
|
|
2477
2571
|
if (stale && problem?.reason === "parse-error") {
|
|
2478
|
-
reportError(blockedEditError(problem.error));
|
|
2572
|
+
reportError(blockedEditError(problem.error, messages));
|
|
2479
2573
|
return;
|
|
2480
2574
|
}
|
|
2481
|
-
const committed =
|
|
2575
|
+
const committed = selectedSection && getCommittedSection(selectedSection.id)?.code;
|
|
2482
2576
|
const result = updateAll(committed && committed !== selectedCode ? committed : updatedCode, changes.map(({ id, label, property, value: changeValue }) => ({
|
|
2483
2577
|
dataId: id,
|
|
2484
2578
|
label,
|
|
@@ -2493,12 +2587,12 @@ const Dnd$1 = ({ value: _value, props, modules: _modules = NO_MODULES, onChange:
|
|
|
2493
2587
|
label,
|
|
2494
2588
|
property,
|
|
2495
2589
|
failure: result.failure,
|
|
2496
|
-
...describeUpdateFailure(result.failure, label)
|
|
2590
|
+
...describeUpdateFailure(result.failure, label, messages)
|
|
2497
2591
|
});
|
|
2498
2592
|
return;
|
|
2499
2593
|
}
|
|
2500
|
-
if (
|
|
2501
|
-
...
|
|
2594
|
+
if (selectedSection) onChange({
|
|
2595
|
+
...selectedSection,
|
|
2502
2596
|
code: result.code
|
|
2503
2597
|
});
|
|
2504
2598
|
};
|
|
@@ -2509,14 +2603,14 @@ const Dnd$1 = ({ value: _value, props, modules: _modules = NO_MODULES, onChange:
|
|
|
2509
2603
|
if (frame?.scripts?.length) preloadScripts(frame.scripts);
|
|
2510
2604
|
}, [frame?.scripts]);
|
|
2511
2605
|
const palette = {
|
|
2512
|
-
items: items?.length ? items :
|
|
2513
|
-
onAdd: (
|
|
2514
|
-
|
|
2606
|
+
items: items?.length ? items : PALETTE_SECTIONS,
|
|
2607
|
+
onAdd: (section) => {
|
|
2608
|
+
addSection(section);
|
|
2515
2609
|
setMobilePaletteOpen(false);
|
|
2516
2610
|
}
|
|
2517
2611
|
};
|
|
2518
2612
|
const panel = {
|
|
2519
|
-
item:
|
|
2613
|
+
item: selectedSection,
|
|
2520
2614
|
onChange,
|
|
2521
2615
|
onDelete,
|
|
2522
2616
|
onMoveUp: () => moveSection(selectedId, "up"),
|
|
@@ -2529,71 +2623,67 @@ const Dnd$1 = ({ value: _value, props, modules: _modules = NO_MODULES, onChange:
|
|
|
2529
2623
|
readOnly: stale,
|
|
2530
2624
|
bindingOptions
|
|
2531
2625
|
};
|
|
2532
|
-
const canvas = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
className: cn(
|
|
2540
|
-
children:
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
missingContainer,
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
"\""
|
|
2555
|
-
] })]
|
|
2556
|
-
}) : /* @__PURE__ */ jsxs(Space, {
|
|
2557
|
-
orientation: "vertical",
|
|
2558
|
-
align: "center",
|
|
2559
|
-
children: [/* @__PURE__ */ jsx(Typography.Paragraph, { children: "No sections available" }), /* @__PURE__ */ jsx(Typography.Text, { children: isMobile ? "Tap a component to add it" : "Drag a component from the left to add it" })]
|
|
2560
|
-
})
|
|
2561
|
-
}) : /* @__PURE__ */ jsx(SortableContext, {
|
|
2562
|
-
items: sections.map((s) => s.id),
|
|
2563
|
-
strategy: verticalListSortingStrategy,
|
|
2564
|
-
children: sections.map((section, index) => /* @__PURE__ */ jsx(Sortable, {
|
|
2565
|
-
id: section.id,
|
|
2566
|
-
name: section.name,
|
|
2567
|
-
selected: selectedId === section.id,
|
|
2568
|
-
onClick: () => onSelect(section.id),
|
|
2569
|
-
onDelete,
|
|
2570
|
-
onCopy,
|
|
2571
|
-
onMoveUp: () => onMoveButton(section.id, "up"),
|
|
2572
|
-
onMoveDown: () => onMoveButton(section.id, "down"),
|
|
2573
|
-
canMoveUp: index > 0,
|
|
2574
|
-
canMoveDown: index < sections.length - 1,
|
|
2575
|
-
nodeRef: sectionNodes.register(section.id),
|
|
2576
|
-
onNavigate: (to) => onNavigate(section.id, to),
|
|
2577
|
-
onDeleteKey: () => onDeleteKey(section.id),
|
|
2578
|
-
inspecting,
|
|
2579
|
-
onInspectMove,
|
|
2580
|
-
onInspectPick: (...args) => onInspectPick(section.id, ...args),
|
|
2581
|
-
onInspectLeave: () => setHighlight(null),
|
|
2582
|
-
children: /* @__PURE__ */ jsx(renderer_default, {
|
|
2583
|
-
preview: previews[index],
|
|
2584
|
-
sectionId: section.id,
|
|
2585
|
-
sectionName: section.name,
|
|
2586
|
-
sectionCode: section.code,
|
|
2587
|
-
forceFallback: isForced(section),
|
|
2588
|
-
modules,
|
|
2589
|
-
frame,
|
|
2590
|
-
dynamicTailwind,
|
|
2591
|
-
provider,
|
|
2592
|
-
...props
|
|
2626
|
+
const canvas = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2627
|
+
stale && /* @__PURE__ */ jsx("div", {
|
|
2628
|
+
role: "status",
|
|
2629
|
+
className: cn("sticky top-0 z-70", "border-b border-amber-200 bg-amber-50 px-3 py-2", "text-sm text-amber-900"),
|
|
2630
|
+
children: messages.canvas.stale
|
|
2631
|
+
}),
|
|
2632
|
+
/* @__PURE__ */ jsx(Droppable, {
|
|
2633
|
+
className: cn(!sections.length && "h-full"),
|
|
2634
|
+
children: !sections.length ? /* @__PURE__ */ jsx("div", {
|
|
2635
|
+
className: cn("flex items-center justify-center", "h-full", "text-gray-500"),
|
|
2636
|
+
children: problem?.reason === "parse-error" ? /* @__PURE__ */ jsxs(Space, {
|
|
2637
|
+
orientation: "vertical",
|
|
2638
|
+
align: "center",
|
|
2639
|
+
children: [/* @__PURE__ */ jsx(Typography.Paragraph, { children: messages.canvas.syntaxError }), /* @__PURE__ */ jsx(Typography.Text, { children: messages.canvas.syntaxErrorDetail })]
|
|
2640
|
+
}) : missingContainer !== null ? /* @__PURE__ */ jsxs(Space, {
|
|
2641
|
+
orientation: "vertical",
|
|
2642
|
+
align: "center",
|
|
2643
|
+
children: [/* @__PURE__ */ jsx(Typography.Paragraph, { children: messages.canvas.missingContainer(missingContainer) }), /* @__PURE__ */ jsx(Typography.Text, { children: messages.canvas.missingContainerDetail(missingContainer) })]
|
|
2644
|
+
}) : /* @__PURE__ */ jsxs(Space, {
|
|
2645
|
+
orientation: "vertical",
|
|
2646
|
+
align: "center",
|
|
2647
|
+
children: [/* @__PURE__ */ jsx(Typography.Paragraph, { children: messages.canvas.empty }), /* @__PURE__ */ jsx(Typography.Text, { children: isMobile ? messages.canvas.emptyHintTouch : messages.canvas.emptyHintDrag })]
|
|
2593
2648
|
})
|
|
2594
|
-
},
|
|
2595
|
-
|
|
2596
|
-
|
|
2649
|
+
}) : /* @__PURE__ */ jsx(SortableContext, {
|
|
2650
|
+
items: sections.map((s) => s.id),
|
|
2651
|
+
strategy: verticalListSortingStrategy,
|
|
2652
|
+
children: sections.map((section, index) => /* @__PURE__ */ jsx(Sortable, {
|
|
2653
|
+
id: section.id,
|
|
2654
|
+
name: section.name,
|
|
2655
|
+
selected: selectedId === section.id,
|
|
2656
|
+
onClick: () => onSelect(section.id),
|
|
2657
|
+
onDelete,
|
|
2658
|
+
onCopy,
|
|
2659
|
+
onMoveUp: () => onMoveButton(section.id, "up"),
|
|
2660
|
+
onMoveDown: () => onMoveButton(section.id, "down"),
|
|
2661
|
+
canMoveUp: index > 0,
|
|
2662
|
+
canMoveDown: index < sections.length - 1,
|
|
2663
|
+
nodeRef: sectionNodes.register(section.id),
|
|
2664
|
+
onNavigate: (to) => onNavigate(section.id, to),
|
|
2665
|
+
onDeleteKey: () => onDeleteKey(section.id),
|
|
2666
|
+
inspecting,
|
|
2667
|
+
onInspectMove,
|
|
2668
|
+
onInspectPick: (...args) => onInspectPick(section.id, ...args),
|
|
2669
|
+
onInspectLeave,
|
|
2670
|
+
children: /* @__PURE__ */ jsx(renderer_default, {
|
|
2671
|
+
preview: previews[index],
|
|
2672
|
+
sectionId: section.id,
|
|
2673
|
+
sectionName: section.name,
|
|
2674
|
+
sectionCode: section.code,
|
|
2675
|
+
forceFallback: isForced(section),
|
|
2676
|
+
modules,
|
|
2677
|
+
frame,
|
|
2678
|
+
dynamicTailwind,
|
|
2679
|
+
provider,
|
|
2680
|
+
...props
|
|
2681
|
+
})
|
|
2682
|
+
}, section.id))
|
|
2683
|
+
})
|
|
2684
|
+
}),
|
|
2685
|
+
/* @__PURE__ */ jsx(InspectorHighlight, { rect: highlightRect })
|
|
2686
|
+
] });
|
|
2597
2687
|
return /* @__PURE__ */ jsx(SectionFallbackContext.Provider, {
|
|
2598
2688
|
value: renderSectionFallback,
|
|
2599
2689
|
children: /* @__PURE__ */ jsxs(DndContext, {
|
|
@@ -2601,22 +2691,20 @@ const Dnd$1 = ({ value: _value, props, modules: _modules = NO_MODULES, onChange:
|
|
|
2601
2691
|
collisionDetection: closestCenter,
|
|
2602
2692
|
accessibility: {
|
|
2603
2693
|
announcements,
|
|
2604
|
-
screenReaderInstructions
|
|
2694
|
+
screenReaderInstructions
|
|
2605
2695
|
},
|
|
2606
2696
|
modifiers: [conditionalModifiers],
|
|
2607
|
-
onDragStart,
|
|
2608
|
-
onDragOver,
|
|
2609
2697
|
onDragEnd,
|
|
2610
2698
|
children: [/* @__PURE__ */ jsx("div", {
|
|
2611
2699
|
className: cn("relative flex h-full w-full", className),
|
|
2612
2700
|
...restProps,
|
|
2613
|
-
children: /* @__PURE__ */
|
|
2701
|
+
children: /* @__PURE__ */ jsx(DndEditOptionsContext.Provider, {
|
|
2614
2702
|
value: {
|
|
2615
2703
|
renderField,
|
|
2616
2704
|
reportError,
|
|
2617
2705
|
bindingOptions
|
|
2618
2706
|
},
|
|
2619
|
-
children:
|
|
2707
|
+
children: /* @__PURE__ */ jsx(DndRegionContext.Provider, {
|
|
2620
2708
|
value: {
|
|
2621
2709
|
palette,
|
|
2622
2710
|
panel,
|
|
@@ -2632,7 +2720,7 @@ const Dnd$1 = ({ value: _value, props, modules: _modules = NO_MODULES, onChange:
|
|
|
2632
2720
|
value: inspector,
|
|
2633
2721
|
children: Children.toArray(children).length ? children : /* @__PURE__ */ jsx(Layout, {})
|
|
2634
2722
|
})
|
|
2635
|
-
})
|
|
2723
|
+
})
|
|
2636
2724
|
})
|
|
2637
2725
|
}), /* @__PURE__ */ jsx(DragOverlay, { children: /* @__PURE__ */ jsx(Overlay, {
|
|
2638
2726
|
sections,
|
|
@@ -2663,6 +2751,6 @@ const useItemsEditor = useDndItems;
|
|
|
2663
2751
|
/** @deprecated Renamed to `useDndChildren`. */
|
|
2664
2752
|
const useChildrenEditor = useDndChildren;
|
|
2665
2753
|
//#endregion
|
|
2666
|
-
export { useDndPanel as _, Layout as a, Field as c, isStructuralFieldKind as d, useDndChildren as f, useDndPalette as g, useDndLayout as h, Canvas as i, useDndItems as l, withPanelCommit as m, useChildrenEditor as n, Palette as o, resolvePanelBindings as p, useItemsEditor as r, Panel as s, Dnd as t, getFieldKind as u,
|
|
2754
|
+
export { useDndPanel as _, Layout as a, Field as c, isStructuralFieldKind as d, useDndChildren as f, useDndPalette as g, useDndLayout as h, Canvas as i, useDndItems as l, withPanelCommit as m, useChildrenEditor as n, Palette as o, resolvePanelBindings as p, useItemsEditor as r, Panel as s, Dnd as t, getFieldKind as u, useDndInspector as v, DraggableItem as y };
|
|
2667
2755
|
|
|
2668
|
-
//# sourceMappingURL=dnd-
|
|
2756
|
+
//# sourceMappingURL=dnd-UoJILA75.js.map
|