@jbpark/live-editor 1.12.0 → 1.14.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 +15 -16
- package/README.md +17 -16
- package/dist/{ast-9E8pNi7j.mjs → ast-Dq1EfxA5.js} +113 -135
- package/dist/ast-Dq1EfxA5.js.map +1 -0
- package/dist/{document-DocoSXLT.mjs → document-CSIscFpL.js} +54 -369
- package/dist/document-CSIscFpL.js.map +1 -0
- package/dist/{document-BVWq-dmf.d.mts → document-DXOwpvWM.d.ts} +15 -3
- package/dist/{utils/ast/index.d.mts → index-BVjSMVya.d.ts} +3 -3
- package/dist/{index.d.mts → index.d.ts} +18 -2
- package/dist/{index.mjs → index.js} +154 -59
- package/dist/index.js.map +1 -0
- package/dist/style.css +491 -706
- package/dist/{tailwind-CzPhj3D9.mjs → tailwind-CzPhj3D9.js} +1 -1
- package/dist/tailwind-CzPhj3D9.js.map +1 -0
- package/dist/utils/ast/index.d.ts +3 -0
- package/dist/utils/ast/{index.mjs → index.js} +2 -2
- package/dist/utils/{index.d.mts → index.d.ts} +2 -3
- package/dist/utils/{index.mjs → index.js} +2 -2
- package/dist/utils/tailwind/{index.d.mts → index.d.ts} +1 -1
- package/dist/utils/tailwind/{index.mjs → index.js} +1 -1
- package/dist/{utils-DP9WPbBJ.mjs → utils-B11t9ZYd.js} +2 -2
- package/dist/utils-B11t9ZYd.js.map +1 -0
- package/package.json +10 -14
- package/dist/ast-9E8pNi7j.mjs.map +0 -1
- package/dist/document-DocoSXLT.mjs.map +0 -1
- package/dist/index-C8h8TcIl.d.mts +0 -15
- package/dist/index.mjs.map +0 -1
- package/dist/tailwind-CzPhj3D9.mjs.map +0 -1
- package/dist/utils-DP9WPbBJ.mjs.map +0 -1
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/types/index.d.ts
|
|
2
|
+
interface Module {
|
|
3
|
+
exports: {
|
|
4
|
+
default?: React.ComponentType<Record<string, unknown>>;
|
|
5
|
+
};
|
|
6
|
+
error?: string;
|
|
7
|
+
}
|
|
8
|
+
interface Section {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
code: string;
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
2
14
|
//#region node_modules/.pnpm/@babel+types@7.29.8/node_modules/@babel/types/lib/index-legacy.d.ts
|
|
3
15
|
// NOTE: This file is autogenerated. Do not modify.
|
|
4
16
|
// See packages/babel-types/scripts/generators/typescript-legacy.ts for script used.
|
|
@@ -1516,5 +1528,5 @@ interface SectionPreviewCache {
|
|
|
1516
1528
|
}
|
|
1517
1529
|
declare const createSectionPreviewCache: () => SectionPreviewCache;
|
|
1518
1530
|
//#endregion
|
|
1519
|
-
export { generateDocumentCode as a, getSections as c, ArrayExpression as d, Expression as f, ObjectExpression as h, createSectionPreviewCache as i, parseDocument as l, Node as m, SectionPreviewCache as n, generateSectionPreview as o, File as p, clearDocumentParseCache as r, generateSectionPreviews as s, DocumentTree as t, replaceDocumentSections as u };
|
|
1520
|
-
//# sourceMappingURL=document-
|
|
1531
|
+
export { Section as _, generateDocumentCode as a, getSections as c, ArrayExpression as d, Expression as f, Module as g, ObjectExpression as h, createSectionPreviewCache as i, parseDocument as l, Node as m, SectionPreviewCache as n, generateSectionPreview as o, File as p, clearDocumentParseCache as r, generateSectionPreviews as s, DocumentTree as t, replaceDocumentSections as u };
|
|
1532
|
+
//# sourceMappingURL=document-DXOwpvWM.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { d as ArrayExpression, f as Expression, h as ObjectExpression, m as Node, p as File } from "./document-DXOwpvWM.js";
|
|
2
2
|
//#region src/utils/ast/types.d.ts
|
|
3
3
|
interface Attribute {
|
|
4
4
|
name: string;
|
|
@@ -134,5 +134,5 @@ interface ValidationResult {
|
|
|
134
134
|
}
|
|
135
135
|
declare const validateBindingValue: (binding: BindingItem, value: unknown) => ValidationResult;
|
|
136
136
|
//#endregion
|
|
137
|
-
export {
|
|
138
|
-
//# sourceMappingURL=index.d.
|
|
137
|
+
export { BindingRenderMap as C, ExtractedNodeValue as D, EditableNodeValueType as E, NodeValueType as O, BindingRenderLeaf as S, DataAttrNode as T, findEditableChildren as _, replaceIds as a, BindingItem as b, clearExtractCache as c, arrayExpressionToCode as d, createNodeFromValue as f, parseValue as g, parseArrayExpression as h, fillIds as i, extract as l, extractObjectProperties as m, validateBindingValue as n, bulkUpdate as o, extractNodeValue as p, clone as r, update as s, ValidationResult as t, generateCode as u, getCurrentValue as v, BindingType as w, BindingOption as x, parseBinding as y };
|
|
138
|
+
//# sourceMappingURL=index-BVjSMVya.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as Section } from "./document-DXOwpvWM.js";
|
|
2
|
+
import { w as BindingType, x as BindingOption } from "./index-BVjSMVya.js";
|
|
2
3
|
import "@jbpark/ui-kit/style.css";
|
|
3
4
|
import React$1, { ReactNode } from "react";
|
|
4
5
|
import { Extension } from "@uiw/react-codemirror";
|
|
@@ -135,11 +136,26 @@ interface PaletteRenderData {
|
|
|
135
136
|
items: Section[];
|
|
136
137
|
onAdd: (item: Section) => void;
|
|
137
138
|
DraggableItem: typeof DraggableItem;
|
|
139
|
+
isMobile: boolean;
|
|
138
140
|
}
|
|
139
141
|
interface PanelRenderData {
|
|
140
142
|
item?: Section;
|
|
141
143
|
onChange: (next: Partial<Section>) => void;
|
|
142
144
|
onDelete: (id: string) => void;
|
|
145
|
+
onMoveUp: () => void;
|
|
146
|
+
onMoveDown: () => void;
|
|
147
|
+
canMoveUp: boolean;
|
|
148
|
+
canMoveDown: boolean;
|
|
149
|
+
bindings: PanelBinding[];
|
|
150
|
+
}
|
|
151
|
+
interface PanelBinding {
|
|
152
|
+
id: string;
|
|
153
|
+
label: string;
|
|
154
|
+
property: string;
|
|
155
|
+
type?: BindingType;
|
|
156
|
+
options?: BindingOption[];
|
|
157
|
+
value: string;
|
|
158
|
+
onChange: (value: string) => void;
|
|
143
159
|
}
|
|
144
160
|
interface Props extends Omit<React.ComponentPropsWithRef<'div'>, 'onChange'> {
|
|
145
161
|
value?: string;
|
|
@@ -182,4 +198,4 @@ declare const App: {
|
|
|
182
198
|
declare const LiveRenderer: ({ code, props, modules, dynamicTailwind, provider, ...restProps }: Props$7) => import("react").JSX.Element;
|
|
183
199
|
//#endregion
|
|
184
200
|
export { Dnd as LiveDnd, Editor as LiveEditor, Error$1 as LiveError, Preview as LivePreview, App as LiveProvider, App as default, LiveRenderer };
|
|
185
|
-
//# sourceMappingURL=index.d.
|
|
201
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { _ as DEFAULT_TEMPLATE, f as require_lib$1, m as BINDING_PROP, n as createSectionPreviewCache, p as require_lib, v as DRAGGABLE_ITEMS, x as __toESM } from "./document-
|
|
2
|
-
import { a as detectTypeScript, d as replaceSections, i as compile, l as getCachedScriptBlob, n as clearCompilationCache, o as extractSections, r as cn, s as generateSection, t as baseModules, u as preloadScripts } from "./utils-
|
|
3
|
-
import { _ as parseArrayExpression, c as extract, d as getCurrentValue, f as parseBinding, g as extractObjectProperties, h as extractNodeValue, i as replaceIds, l as nanoid, m as createNodeFromValue, n as clone, o as update, p as arrayExpressionToCode, r as fillIds, t as validateBindingValue, u as findEditableChildren, v as parseValue, y as generateCode } from "./ast-
|
|
4
|
-
import { t as generateTailwindCSS } from "./tailwind-CzPhj3D9.
|
|
1
|
+
import { _ as DEFAULT_TEMPLATE, f as require_lib$1, m as BINDING_PROP, n as createSectionPreviewCache, p as require_lib, v as DRAGGABLE_ITEMS, x as __toESM } from "./document-CSIscFpL.js";
|
|
2
|
+
import { a as detectTypeScript, d as replaceSections, i as compile, l as getCachedScriptBlob, n as clearCompilationCache, o as extractSections, r as cn, s as generateSection, t as baseModules, u as preloadScripts } from "./utils-B11t9ZYd.js";
|
|
3
|
+
import { _ as parseArrayExpression, c as extract, d as getCurrentValue, f as parseBinding, g as extractObjectProperties, h as extractNodeValue, i as replaceIds, l as nanoid, m as createNodeFromValue, n as clone, o as update, p as arrayExpressionToCode, r as fillIds, t as validateBindingValue, u as findEditableChildren, v as parseValue, y as generateCode } from "./ast-Dq1EfxA5.js";
|
|
4
|
+
import { t as generateTailwindCSS } from "./tailwind-CzPhj3D9.js";
|
|
5
5
|
import "@jbpark/ui-kit/style.css";
|
|
6
6
|
import React, { createContext, memo, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
7
7
|
import { Button, Card, Checkbox, ColorPicker, DatePicker, Drawer, Input, Select, Space, Toast, Typography, Upload } from "@jbpark/ui-kit";
|
|
@@ -10,7 +10,7 @@ import { DndContext, DragOverlay, PointerSensor, closestCenter, useDndContext, u
|
|
|
10
10
|
import { restrictToVerticalAxis } from "@dnd-kit/modifiers";
|
|
11
11
|
import { SortableContext, arrayMove, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
|
|
12
12
|
import { useDebounce, useDebouncedValue, useEventListener, useMultiSelect, useMutationObserver, useResizeObserver, useResponsiveSize } from "@jbpark/use-hooks";
|
|
13
|
-
import { AlertCircle, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, Bell, Bookmark, Calendar, Camera, Check, ChevronDown, ChevronRight, Clock, Copy, Download, Edit, Eye, Filter, Heart, Home, Image, Info, LayoutGrid, Link, Mail, Map as Map$1, Menu, MessageCircle, Phone, Plus, Search, Settings, Share, ShoppingCart, Star, Trash, Upload as Upload$1, User, X } from "lucide-react";
|
|
13
|
+
import { AlertCircle, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, Bell, Bookmark, Calendar, Camera, Check, ChevronDown, ChevronRight, ChevronUp, Clock, Copy, Download, Edit, Eye, Filter, Heart, Home, Image, Info, LayoutGrid, Link, Mail, Map as Map$1, Menu, MessageCircle, Phone, Plus, Search, Settings, Share, ShoppingCart, Star, Trash, Upload as Upload$1, User, X } from "lucide-react";
|
|
14
14
|
import { v4 } from "uuid";
|
|
15
15
|
import { createPortal } from "react-dom";
|
|
16
16
|
import { CSS } from "@dnd-kit/utilities";
|
|
@@ -100,6 +100,20 @@ const UNIT_MAP = {
|
|
|
100
100
|
const UNITS_PATTERN = Object.keys(UNIT_MAP).sort((a, b) => b.length - a.length).join("|");
|
|
101
101
|
const VIEWPORT_UNIT_RE = new RegExp(`(?<![\\w.-])(-?(?:\\d+\\.?\\d*|\\.\\d+))(${UNITS_PATTERN})(?![a-zA-Z0-9_-])`, "gi");
|
|
102
102
|
const convertViewportUnits = (css) => css.replace(VIEWPORT_UNIT_RE, (_match, number, unit) => number + UNIT_MAP[unit.toLowerCase()]);
|
|
103
|
+
const rewriteInlineViewportUnits = (root) => {
|
|
104
|
+
root.querySelectorAll("[style*=\"vh\" i], [style*=\"vmin\" i], [style*=\"vmax\" i]").forEach((el) => {
|
|
105
|
+
const current = el.getAttribute("style");
|
|
106
|
+
if (current == null) return;
|
|
107
|
+
const converted = convertViewportUnits(current);
|
|
108
|
+
if (converted !== current) el.setAttribute("style", converted);
|
|
109
|
+
});
|
|
110
|
+
root.querySelectorAll("style").forEach((styleEl) => {
|
|
111
|
+
const current = styleEl.textContent;
|
|
112
|
+
if (!current) return;
|
|
113
|
+
const converted = convertViewportUnits(current);
|
|
114
|
+
if (converted !== current) styleEl.textContent = converted;
|
|
115
|
+
});
|
|
116
|
+
};
|
|
103
117
|
//#endregion
|
|
104
118
|
//#region src/components/frame/iframe.tsx
|
|
105
119
|
const EMPTY_STRING_ARRAY = [];
|
|
@@ -237,6 +251,7 @@ const IFrame = ({ title = "Live Preview", sandbox, style = {}, scripts = EMPTY_S
|
|
|
237
251
|
prevStylesheetCountRef.current = stylesheets.length;
|
|
238
252
|
}, [styles, stylesheets]);
|
|
239
253
|
const CONTAINER_STYLE_ID = "autoheight-container";
|
|
254
|
+
const HIDE_SCROLLBAR_STYLE_ID = "autoheight-hide-scrollbar";
|
|
240
255
|
const ensureContainerStyle = (doc, probeHeight) => {
|
|
241
256
|
let styleEl = doc.getElementById(CONTAINER_STYLE_ID);
|
|
242
257
|
if (!styleEl) {
|
|
@@ -288,6 +303,7 @@ const IFrame = ({ title = "Live Preview", sandbox, style = {}, scripts = EMPTY_S
|
|
|
288
303
|
let contentHeight = 0;
|
|
289
304
|
withMeasurementOverrides(doc, () => {
|
|
290
305
|
ensureContainerStyle(doc, probeHeight);
|
|
306
|
+
rewriteInlineViewportUnits(mountNode);
|
|
291
307
|
contentHeight = mountNode.scrollHeight;
|
|
292
308
|
mountNode.querySelectorAll("*").forEach((el) => {
|
|
293
309
|
const style = win.getComputedStyle(el);
|
|
@@ -304,6 +320,20 @@ const IFrame = ({ title = "Live Preview", sandbox, style = {}, scripts = EMPTY_S
|
|
|
304
320
|
if (shouldAutoHeight) return;
|
|
305
321
|
iframeRef.current?.contentDocument?.getElementById(CONTAINER_STYLE_ID)?.remove();
|
|
306
322
|
}, [shouldAutoHeight]);
|
|
323
|
+
useEffect(() => {
|
|
324
|
+
const doc = iframeRef.current?.contentDocument;
|
|
325
|
+
if (!doc?.head) return;
|
|
326
|
+
const existing = doc.getElementById(HIDE_SCROLLBAR_STYLE_ID);
|
|
327
|
+
if (!shouldAutoHeight) {
|
|
328
|
+
existing?.remove();
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
if (existing) return;
|
|
332
|
+
const styleEl = doc.createElement("style");
|
|
333
|
+
styleEl.id = HIDE_SCROLLBAR_STYLE_ID;
|
|
334
|
+
styleEl.textContent = ["html, body { scrollbar-width: none !important; }", "html::-webkit-scrollbar, body::-webkit-scrollbar { display: none !important; }"].join("\n");
|
|
335
|
+
doc.head.appendChild(styleEl);
|
|
336
|
+
}, [shouldAutoHeight, mountNode]);
|
|
307
337
|
useEffect(() => {
|
|
308
338
|
updateHeight();
|
|
309
339
|
}, [updateHeight]);
|
|
@@ -405,13 +435,14 @@ const DraggableItem = ({ item, children }) => {
|
|
|
405
435
|
isDragging
|
|
406
436
|
});
|
|
407
437
|
};
|
|
408
|
-
const DefaultDraggableItem = ({ item, onAdd }) => /* @__PURE__ */ jsx(DraggableItem, {
|
|
438
|
+
const DefaultDraggableItem = ({ item, onAdd, tapToAdd = false }) => /* @__PURE__ */ jsx(DraggableItem, {
|
|
409
439
|
item,
|
|
410
440
|
children: ({ ref, dragProps, isDragging }) => /* @__PURE__ */ jsx(Card, {
|
|
411
441
|
ref,
|
|
412
442
|
style: { opacity: isDragging ? .5 : 1 },
|
|
413
443
|
...dragProps,
|
|
414
444
|
className: cn("cursor-grab", "outline-none", "hover:border-blue-300 hover:shadow-md", isDragging && "opacity-50"),
|
|
445
|
+
onClick: tapToAdd && onAdd ? () => onAdd(item) : void 0,
|
|
415
446
|
onDoubleClick: onAdd ? () => onAdd(item) : void 0,
|
|
416
447
|
children: item.name
|
|
417
448
|
})
|
|
@@ -12861,33 +12892,7 @@ const Node = ({ data, onChange }) => {
|
|
|
12861
12892
|
};
|
|
12862
12893
|
//#endregion
|
|
12863
12894
|
//#region src/components/dnd/panel/panel.tsx
|
|
12864
|
-
const Panel = ({ item,
|
|
12865
|
-
const code = item?.code;
|
|
12866
|
-
const { dataAttrNodes, updatedCode, parseError } = useMemo(() => {
|
|
12867
|
-
if (!code) return {
|
|
12868
|
-
dataAttrNodes: [],
|
|
12869
|
-
updatedCode: "",
|
|
12870
|
-
parseError: false
|
|
12871
|
-
};
|
|
12872
|
-
try {
|
|
12873
|
-
const updatedCode = fillIds(code);
|
|
12874
|
-
return {
|
|
12875
|
-
dataAttrNodes: extract(updatedCode).filter((node) => node.tagName !== "section"),
|
|
12876
|
-
updatedCode: updatedCode !== code ? updatedCode : code,
|
|
12877
|
-
parseError: false
|
|
12878
|
-
};
|
|
12879
|
-
} catch (e) {
|
|
12880
|
-
console.warn("⚠️ Parsing error", e);
|
|
12881
|
-
return {
|
|
12882
|
-
dataAttrNodes: [],
|
|
12883
|
-
updatedCode: "",
|
|
12884
|
-
parseError: true
|
|
12885
|
-
};
|
|
12886
|
-
}
|
|
12887
|
-
}, [code]);
|
|
12888
|
-
useEffect(() => {
|
|
12889
|
-
if (parseError) Toast.error("Failed to parse this section", { description: "Check the console for details." });
|
|
12890
|
-
}, [parseError]);
|
|
12895
|
+
const Panel = ({ item, onDelete, onMoveUp, onMoveDown, canMoveUp = false, canMoveDown = false, fields, onFieldChange }) => {
|
|
12891
12896
|
if (!item) return /* @__PURE__ */ jsx(Typography.Paragraph, {
|
|
12892
12897
|
className: cn("p-4 text-sm text-gray-500"),
|
|
12893
12898
|
children: "Please select a section."
|
|
@@ -12900,29 +12905,37 @@ const Panel = ({ item, onChange, onDelete }) => {
|
|
|
12900
12905
|
children: [/* @__PURE__ */ jsx(Typography.Title, {
|
|
12901
12906
|
className: "text-lg font-semibold",
|
|
12902
12907
|
children: item.name
|
|
12903
|
-
}),
|
|
12904
|
-
|
|
12905
|
-
|
|
12906
|
-
|
|
12908
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
12909
|
+
className: "flex items-center gap-1",
|
|
12910
|
+
children: [
|
|
12911
|
+
onMoveUp && /* @__PURE__ */ jsx(Button, {
|
|
12912
|
+
icon: /* @__PURE__ */ jsx(ChevronUp, {}),
|
|
12913
|
+
disabled: !canMoveUp,
|
|
12914
|
+
onClick: onMoveUp,
|
|
12915
|
+
"aria-label": "Move section up"
|
|
12916
|
+
}),
|
|
12917
|
+
onMoveDown && /* @__PURE__ */ jsx(Button, {
|
|
12918
|
+
icon: /* @__PURE__ */ jsx(ChevronDown, {}),
|
|
12919
|
+
disabled: !canMoveDown,
|
|
12920
|
+
onClick: onMoveDown,
|
|
12921
|
+
"aria-label": "Move section down"
|
|
12922
|
+
}),
|
|
12923
|
+
onDelete && /* @__PURE__ */ jsx(Button, {
|
|
12924
|
+
danger: true,
|
|
12925
|
+
icon: /* @__PURE__ */ jsx(Trash, {}),
|
|
12926
|
+
onClick: () => onDelete(item.id),
|
|
12927
|
+
"aria-label": "Delete section"
|
|
12928
|
+
})
|
|
12929
|
+
]
|
|
12907
12930
|
})]
|
|
12908
12931
|
}),
|
|
12909
|
-
!
|
|
12932
|
+
!fields.length && /* @__PURE__ */ jsx(Typography.Text, {
|
|
12910
12933
|
className: "text-xs text-gray-400",
|
|
12911
12934
|
children: "No editable elements."
|
|
12912
12935
|
}),
|
|
12913
|
-
|
|
12936
|
+
fields.map((node, index) => /* @__PURE__ */ jsx(Node, {
|
|
12914
12937
|
data: node,
|
|
12915
|
-
onChange:
|
|
12916
|
-
const result = update(updatedCode, id, label, value);
|
|
12917
|
-
if (!result.success) {
|
|
12918
|
-
Toast.error("Failed to update this field", { description: "Check the console for details." });
|
|
12919
|
-
return;
|
|
12920
|
-
}
|
|
12921
|
-
onChange?.({
|
|
12922
|
-
...item,
|
|
12923
|
-
code: result.code
|
|
12924
|
-
});
|
|
12925
|
-
}
|
|
12938
|
+
onChange: onFieldChange
|
|
12926
12939
|
}, `${item.id}-${index}`))
|
|
12927
12940
|
]
|
|
12928
12941
|
});
|
|
@@ -12943,6 +12956,7 @@ const Dnd$1 = ({ value: _value, props, modules = {}, onChange: _onChange, classN
|
|
|
12943
12956
|
const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 10 } }));
|
|
12944
12957
|
const value = _value || DEFAULT_TEMPLATE;
|
|
12945
12958
|
const sections = useMemo(() => extractSections(value), [value]);
|
|
12959
|
+
const selectedItem = useMemo(() => sections.find((s) => s.id === selectedId), [sections, selectedId]);
|
|
12946
12960
|
const [previewCache] = useState(() => createSectionPreviewCache());
|
|
12947
12961
|
const previews = useMemo(() => previewCache.compute(value, sections), [
|
|
12948
12962
|
previewCache,
|
|
@@ -13006,6 +13020,16 @@ const Dnd$1 = ({ value: _value, props, modules = {}, onChange: _onChange, classN
|
|
|
13006
13020
|
_onChange?.(nextCode);
|
|
13007
13021
|
setCode(nextCode);
|
|
13008
13022
|
};
|
|
13023
|
+
const moveSection = (id, direction) => {
|
|
13024
|
+
const index = sections.findIndex((s) => s.id === id);
|
|
13025
|
+
const targetIndex = direction === "up" ? index - 1 : index + 1;
|
|
13026
|
+
if (index < 0 || targetIndex < 0 || targetIndex >= sections.length) return;
|
|
13027
|
+
const nextSections = arrayMove(sections, index, targetIndex);
|
|
13028
|
+
const nextCode = replaceSections(value, nextSections.map((s) => s.code));
|
|
13029
|
+
_onChange?.(nextCode);
|
|
13030
|
+
setCode(nextCode);
|
|
13031
|
+
setSelectedId(String(targetIndex));
|
|
13032
|
+
};
|
|
13009
13033
|
const onCopy = (id) => {
|
|
13010
13034
|
const sectionIndex = sections.findIndex((s) => s.id === id);
|
|
13011
13035
|
const sectionToCopy = sections[sectionIndex];
|
|
@@ -13039,36 +13063,107 @@ const Dnd$1 = ({ value: _value, props, modules = {}, onChange: _onChange, classN
|
|
|
13039
13063
|
_onChange?.(nextCode);
|
|
13040
13064
|
setCode(nextCode);
|
|
13041
13065
|
};
|
|
13066
|
+
const selectedCode = selectedItem?.code;
|
|
13067
|
+
const { fields, updatedCode, parseError } = useMemo(() => {
|
|
13068
|
+
if (!selectedCode) return {
|
|
13069
|
+
fields: [],
|
|
13070
|
+
updatedCode: "",
|
|
13071
|
+
parseError: false
|
|
13072
|
+
};
|
|
13073
|
+
try {
|
|
13074
|
+
const updated = fillIds(selectedCode);
|
|
13075
|
+
return {
|
|
13076
|
+
fields: extract(updated).filter((node) => node.tagName !== "section"),
|
|
13077
|
+
updatedCode: updated !== selectedCode ? updated : selectedCode,
|
|
13078
|
+
parseError: false
|
|
13079
|
+
};
|
|
13080
|
+
} catch (e) {
|
|
13081
|
+
console.warn("⚠️ Parsing error", e);
|
|
13082
|
+
return {
|
|
13083
|
+
fields: [],
|
|
13084
|
+
updatedCode: "",
|
|
13085
|
+
parseError: true
|
|
13086
|
+
};
|
|
13087
|
+
}
|
|
13088
|
+
}, [selectedCode]);
|
|
13089
|
+
useEffect(() => {
|
|
13090
|
+
if (parseError) Toast.error("Failed to parse this section", { description: "Check the console for details." });
|
|
13091
|
+
}, [parseError]);
|
|
13092
|
+
const onFieldChange = ({ id, label, value: fieldValue }) => {
|
|
13093
|
+
const result = update(updatedCode, id, label, fieldValue);
|
|
13094
|
+
if (!result.success) {
|
|
13095
|
+
Toast.error("Failed to update this field", { description: "Check the console for details." });
|
|
13096
|
+
return;
|
|
13097
|
+
}
|
|
13098
|
+
if (selectedItem) onChange({
|
|
13099
|
+
...selectedItem,
|
|
13100
|
+
code: result.code
|
|
13101
|
+
});
|
|
13102
|
+
};
|
|
13103
|
+
const bindings = useMemo(() => {
|
|
13104
|
+
return fields.flatMap((node) => {
|
|
13105
|
+
const dataId = node.dataAttributes.find((a) => a.name === "data-id")?.value;
|
|
13106
|
+
const bindingAttr = node.dataAttributes.find((a) => a.name === "data-binding")?.value;
|
|
13107
|
+
if (!dataId || !bindingAttr) return [];
|
|
13108
|
+
return (node.bindings ?? parseBinding(bindingAttr)).map((binding) => ({
|
|
13109
|
+
id: dataId,
|
|
13110
|
+
label: binding.label,
|
|
13111
|
+
property: binding.property,
|
|
13112
|
+
type: binding.type,
|
|
13113
|
+
options: binding.options,
|
|
13114
|
+
value: getCurrentValue(node, binding.property),
|
|
13115
|
+
onChange: (value) => onFieldChange({
|
|
13116
|
+
id: dataId,
|
|
13117
|
+
label: binding.label,
|
|
13118
|
+
value
|
|
13119
|
+
})
|
|
13120
|
+
}));
|
|
13121
|
+
});
|
|
13122
|
+
}, [fields]);
|
|
13042
13123
|
useEffect(() => {
|
|
13043
13124
|
if (frame?.scripts?.length) preloadScripts(frame.scripts);
|
|
13044
13125
|
}, [frame?.scripts]);
|
|
13045
|
-
const renderPaletteItems = (onAdd) => {
|
|
13126
|
+
const renderPaletteItems = (onAdd, forMobileDrawer = false) => {
|
|
13046
13127
|
const paletteItems = items?.length ? items : DRAGGABLE_ITEMS;
|
|
13047
13128
|
if (renderPalette) return renderPalette({
|
|
13048
13129
|
items: paletteItems,
|
|
13049
13130
|
onAdd,
|
|
13050
|
-
DraggableItem
|
|
13131
|
+
DraggableItem,
|
|
13132
|
+
isMobile: forMobileDrawer
|
|
13051
13133
|
});
|
|
13052
13134
|
return /* @__PURE__ */ jsx(Space, {
|
|
13053
13135
|
orientation: "vertical",
|
|
13054
13136
|
align: "start",
|
|
13055
13137
|
children: paletteItems.map((item) => /* @__PURE__ */ jsx(DefaultDraggableItem, {
|
|
13056
13138
|
item,
|
|
13057
|
-
onAdd
|
|
13139
|
+
onAdd,
|
|
13140
|
+
tapToAdd: forMobileDrawer
|
|
13058
13141
|
}, item.id))
|
|
13059
13142
|
});
|
|
13060
13143
|
};
|
|
13061
13144
|
const renderPanelContent = () => {
|
|
13062
|
-
const
|
|
13145
|
+
const selectedIndex = sections.findIndex((s) => s.id === selectedId);
|
|
13146
|
+
const canMoveUp = selectedIndex > 0;
|
|
13147
|
+
const canMoveDown = selectedIndex >= 0 && selectedIndex < sections.length - 1;
|
|
13063
13148
|
if (renderPanel) return renderPanel({
|
|
13064
13149
|
item: selectedItem,
|
|
13065
13150
|
onChange,
|
|
13066
|
-
onDelete
|
|
13151
|
+
onDelete,
|
|
13152
|
+
onMoveUp: () => moveSection(selectedId, "up"),
|
|
13153
|
+
onMoveDown: () => moveSection(selectedId, "down"),
|
|
13154
|
+
canMoveUp,
|
|
13155
|
+
canMoveDown,
|
|
13156
|
+
bindings
|
|
13067
13157
|
});
|
|
13068
13158
|
return /* @__PURE__ */ jsx(Panel, {
|
|
13069
13159
|
item: selectedItem,
|
|
13070
|
-
|
|
13071
|
-
|
|
13160
|
+
onDelete,
|
|
13161
|
+
onMoveUp: () => moveSection(selectedId, "up"),
|
|
13162
|
+
onMoveDown: () => moveSection(selectedId, "down"),
|
|
13163
|
+
canMoveUp,
|
|
13164
|
+
canMoveDown,
|
|
13165
|
+
fields,
|
|
13166
|
+
onFieldChange
|
|
13072
13167
|
});
|
|
13073
13168
|
};
|
|
13074
13169
|
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(DndContext, {
|
|
@@ -13148,7 +13243,7 @@ const Dnd$1 = ({ value: _value, props, modules = {}, onChange: _onChange, classN
|
|
|
13148
13243
|
children: renderPaletteItems((item) => {
|
|
13149
13244
|
addItem(item);
|
|
13150
13245
|
setMobilePaletteOpen(false);
|
|
13151
|
-
})
|
|
13246
|
+
}, true)
|
|
13152
13247
|
}),
|
|
13153
13248
|
/* @__PURE__ */ jsx(Drawer, {
|
|
13154
13249
|
open: isMobile && Boolean(selectedId),
|
|
@@ -13528,4 +13623,4 @@ App.Dnd = Dnd;
|
|
|
13528
13623
|
//#endregion
|
|
13529
13624
|
export { Dnd as LiveDnd, Editor as LiveEditor, Error$1 as LiveError, Preview as LivePreview, App as LiveProvider, App as default, LiveRenderer };
|
|
13530
13625
|
|
|
13531
|
-
//# sourceMappingURL=index.
|
|
13626
|
+
//# sourceMappingURL=index.js.map
|