@jbpark/live-editor 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ast-CrSMBsL4.js → ast-BKQmEBj9.js} +394 -71
- package/dist/ast-BKQmEBj9.js.map +1 -0
- package/dist/dnd/index.d.ts +1 -1
- package/dist/dnd/index.js +1 -1
- package/dist/{dnd-DMh9mSaU.js → dnd-Cyuif73L.js} +63 -180
- package/dist/dnd-Cyuif73L.js.map +1 -0
- package/dist/{index-7J3AYBNK.d.ts → index-2CUWhF-T.d.ts} +2 -2
- package/dist/{index-Wh6AGoXW.d.ts → index-FKgYmeNR.d.ts} +21 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/utils/ast/index.d.ts +2 -2
- package/dist/utils/ast/index.js +2 -2
- package/package.json +1 -1
- package/dist/ast-CrSMBsL4.js.map +0 -1
- package/dist/dnd-DMh9mSaU.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dnd-Cyuif73L.js","names":["LiveError","Renderer","t","TiptapEditor","CoreEditor","Dnd","Renderer","DndImpl","DefaultPanel"],"sources":["../src/components/dnd/draggable.tsx","../src/components/dnd/droppable.tsx","../src/components/dnd/renderer.tsx","../src/components/dnd/sortable.tsx","../src/components/dnd/overlay.tsx","../src/components/editor/tiptap.tsx","../src/components/dnd/panel/node.tsx","../src/components/dnd/panel/items.tsx","../src/components/dnd/panel/children.tsx","../src/components/dnd/panel/icon-map.tsx","../src/components/dnd/panel/field.tsx","../src/components/dnd/panel/field-group.tsx","../src/components/dnd/panel/panel.tsx","../src/components/dnd/use-section-document.ts","../src/components/dnd/dnd.tsx","../src/components/dnd/index.ts"],"sourcesContent":["import { useDraggable } from '@dnd-kit/core';\nimport { Card } from '@jbpark/ui-kit';\n\nimport type { Section } from '~/types';\nimport { cn } from '~/utils';\n\nexport interface DraggableItemDragState {\n ref: (node: HTMLElement | null) => void;\n dragProps: React.HTMLAttributes<HTMLElement>;\n isDragging: boolean;\n}\n\nexport interface DraggableItemProps {\n item: Section;\n children: (drag: DraggableItemDragState) => React.ReactNode;\n}\n\n// Owns the dnd-kit wiring (useDraggable + the `type: 'new-item'` data shape\n// Dnd's onDragEnd expects) so a custom renderPalette only has to decide how\n// an item *looks*, not how dragging itself works. Exported as\n// Dnd.DraggableItem for that purpose; also used internally for the default\n// palette rendering, so both paths share the exact same drag wiring.\nconst DraggableItem = ({ item, children }: DraggableItemProps) => {\n const { attributes, listeners, setNodeRef, isDragging } = useDraggable({\n id: item.id,\n data: { type: 'new-item', item },\n });\n\n return children({\n ref: setNodeRef,\n dragProps: { ...listeners, ...attributes },\n isDragging,\n });\n};\n\n// The built-in card look, shared by the default (non-custom) palette\n// rendering and the drag overlay's floating preview — both rendered a plain\n// `<Draggable>` before this became a children-render-prop component.\nexport interface DefaultDraggableItemProps {\n item: Section;\n onAdd?: (item: Section) => void;\n // Double-click is the desktop convenience shortcut alongside drag — a\n // single click there would fire on every aborted/failed drag attempt.\n // On mobile there's nowhere to drag *to* (the palette lives in a Drawer\n // stacked over the canvas), so a tap can't be a failed drag, and\n // double-tap-to-dblclick synthesis from touch is unreliable anyway\n // (iOS Safari inconsistently fires it, and it can compete with the\n // browser's native double-tap-to-zoom gesture). Tapping just adds there.\n tapToAdd?: boolean;\n}\n\nexport const DefaultDraggableItem = ({\n item,\n onAdd,\n tapToAdd = false,\n}: DefaultDraggableItemProps) => (\n <DraggableItem item={item}>\n {({ ref, dragProps, isDragging }) => (\n <Card\n ref={ref}\n style={{ opacity: isDragging ? 0.5 : 1 }}\n {...dragProps}\n className={cn(\n 'cursor-grab',\n 'outline-none',\n 'hover:border-blue-300 hover:shadow-md',\n isDragging && 'opacity-50',\n )}\n onClick={tapToAdd && onAdd ? () => onAdd(item) : undefined}\n onDoubleClick={onAdd ? () => onAdd(item) : undefined}\n >\n {item.name}\n </Card>\n )}\n </DraggableItem>\n);\n\nexport default DraggableItem;\n","import { useDroppable } from '@dnd-kit/core';\nimport { Typography } from '@jbpark/ui-kit';\n\nimport { cn } from '~/utils';\n\nconst Droppable = ({\n children,\n className,\n}: React.ComponentPropsWithRef<'div'>) => {\n const { setNodeRef, isOver, active } = useDroppable({\n id: 'sortable-area',\n });\n\n const { setNodeRef: setBottomRef, isOver: isBottomOver } = useDroppable({\n id: 'sortable-area-bottom',\n });\n\n const isNewItemDragging = active?.data.current?.type === 'new-item';\n const shouldHighlight = isOver && isNewItemDragging;\n const shouldHighlightBottom = isBottomOver && isNewItemDragging;\n\n return (\n <div\n ref={setNodeRef}\n className={cn(\n 'min-h-full',\n 'border-2 border-dashed p-1',\n shouldHighlight ? 'border-blue-300 bg-blue-50' : 'border-gray-200',\n className,\n )}\n >\n {children}\n {isNewItemDragging && (\n <div\n ref={setBottomRef}\n className={cn(\n 'mt-2 min-h-24',\n 'rounded-lg border-2 border-dashed',\n 'transition-all duration-200',\n 'flex items-center justify-center',\n shouldHighlightBottom\n ? 'border-blue-400 bg-blue-100'\n : 'border-gray-300 bg-gray-50',\n )}\n >\n <Typography.Text className=\"text-sm text-gray-500\">\n {shouldHighlightBottom ? 'Drop here' : 'Drag here to add at bottom'}\n </Typography.Text>\n </div>\n )}\n </div>\n );\n};\n\nexport default Droppable;\n","import { memo } from 'react';\n\nimport ErrorBoundary from '~/components/error/boundary';\nimport LiveError from '~/components/error/error';\nimport Frame, { type FrameProps } from '~/components/frame';\nimport { useCompiledModule } from '~/components/preview/use-compiled-module';\nimport { useDynamicTailwind } from '~/components/preview/use-dynamic-tailwind';\n\ninterface Props {\n preview: string;\n modules?: Record<string, unknown>;\n headers?: Record<string, boolean>;\n frame?: FrameProps;\n dynamicTailwind?: boolean;\n provider?: (children: React.ReactNode) => React.ReactNode;\n}\n\n// Wrapped in memo() because `preview` is a plain string: for a section that\n// didn't change, the parent hands back the same content it computed last\n// render (see generateSections()/dnd.tsx), so a shallow prop comparison\n// lets React skip both the recompile below and reconciling this section's\n// iframe tree at all — see #97.\nconst Renderer = ({\n preview,\n headers,\n modules,\n frame,\n dynamicTailwind = false,\n provider,\n}: Props) => {\n const module = useCompiledModule(preview, modules);\n\n // In `shadow` mode there's no separate document to load a stylesheet into\n // — the shadow root only gets whatever CSS naturally inherits across the\n // boundary (see `frame/shadow.tsx`), not utility classes. So this section's\n // own Tailwind classes are compiled and portalled in as a `<style>` tag\n // alongside the rendered content, which crosses the shadow boundary fine\n // since it lives inside the same portal target.\n const { ref: wrapperRef, css: dynamicCSS } = useDynamicTailwind(\n preview,\n dynamicTailwind,\n );\n\n const renderProvider = (component: React.ReactNode) => {\n return provider ? provider(component) : component;\n };\n\n // Rendered in place of the frame rather than inside it: there is nothing to\n // portal into an iframe for code that never produced a component, and a\n // silent blank slot (the previous behaviour) gives the author no clue why\n // their section vanished. Mirrors preview/client.tsx's compile-error branch.\n if (module?.error) {\n return <LiveError message={module.error} title=\"Compile Error\" />;\n }\n\n const Component = module?.exports?.default;\n\n if (!Component) {\n return null;\n }\n\n return (\n <Frame {...frame} autoHeight>\n {container => (\n <div\n ref={wrapperRef}\n className=\"w-full overflow-x-hidden\"\n data-editor-mode\n >\n {/*\n Without this, a render error in any single canvas section\n propagated past Dnd and unmounted the whole editor — palette,\n canvas and panel — while the same error in <Preview> was caught\n and displayed (see #246). Kept inside the frame so the failure is\n reported in the slot the broken section occupies, and so a\n transient error while the author is mid-edit doesn't tear down and\n rebuild the iframe (script loading, style sync, resize observers)\n on every keystroke. `Error` is inline-styled, so it stays readable\n even in a frame that never received the host's CSS.\n\n resetKeys={[preview]} makes the fix itself the recovery signal: the\n next edit to this section produces a new preview string, which\n clears the caught error without needing a remount.\n\n No `Error.Guard` here, unlike client.tsx: it listens on `window`,\n not on its subtree, so one per section would mean N global\n listeners all tripping on any single error — every section would\n show a runtime error regardless of which one actually threw.\n\n Errors also stay local rather than going to ErrorContext, whose\n `error` is a single string shared by the whole tree: N sections\n reporting into it would overwrite each other with no way to tell\n which section failed.\n */}\n <ErrorBoundary resetKeys={[preview]}>\n {renderProvider(\n <>\n <Component\n headers={headers}\n container={container}\n //\n />\n {dynamicTailwind && dynamicCSS && <style>{dynamicCSS}</style>}\n </>,\n )}\n </ErrorBoundary>\n </div>\n )}\n </Frame>\n );\n};\n\nexport default memo(Renderer);\n","import { useSortable } from '@dnd-kit/sortable';\nimport { CSS } from '@dnd-kit/utilities';\nimport { Button, Space } from '@jbpark/ui-kit';\nimport { Copy, Trash } from 'lucide-react';\n\nimport { cn } from '~/utils';\n\ninterface Props {\n id: string;\n name?: string;\n children: React.ReactNode;\n selected?: boolean;\n onClick?: () => void;\n onDelete?: (id: string) => void;\n onCopy?: (id: string) => void;\n}\n\nconst Sortable = ({\n id,\n children,\n selected,\n onClick,\n onDelete: _onDelete,\n onCopy: _onCopy,\n}: Props) => {\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition,\n isDragging,\n isOver,\n active,\n } = useSortable({ id });\n\n const style = {\n transform: CSS.Transform.toString(transform),\n transition,\n opacity: isDragging ? 0.5 : 1,\n cursor: 'grab',\n };\n\n const isNewItemOver = isOver && active?.data.current?.type === 'new-item';\n\n const onDelete = (e: React.MouseEvent) => {\n e.stopPropagation();\n _onDelete?.(id);\n };\n\n const onCopy = (e: React.MouseEvent) => {\n e.stopPropagation();\n _onCopy?.(id);\n };\n\n return (\n <div\n ref={setNodeRef}\n style={style}\n {...attributes}\n {...listeners}\n onClick={onClick}\n className={cn(\n 'relative',\n selected && 'z-10 outline-2 outline-offset-2 outline-blue-500',\n isNewItemOver && 'border-t-4 border-t-green-500',\n //\n )}\n >\n <div\n className={cn(\n 'absolute inset-0 z-50',\n //\n )}\n />\n {children}\n {selected && (\n <Space\n className={cn(\n 'absolute top-1 right-1 z-60',\n //\n )}\n >\n <Button icon={<Copy />} onClick={onCopy} />\n <Button danger icon={<Trash />} onClick={onDelete} />\n </Space>\n )}\n </div>\n );\n};\n\nexport default Sortable;\n","import { useDndContext } from '@dnd-kit/core';\n\nimport type { FrameProps } from '~/components/frame';\nimport type { Section } from '~/types';\nimport { generateSection } from '~/utils';\n\nimport { DefaultDraggableItem } from './draggable';\nimport Renderer from './renderer';\nimport Sortable from './sortable';\n\ninterface Props {\n sections: Section[];\n renderProps: {\n fullCode: string;\n modules: Record<string, unknown>;\n frame?: FrameProps;\n dynamicTailwind?: boolean;\n };\n}\n\nconst Overlay = ({ sections, renderProps }: Props) => {\n const { active } = useDndContext();\n\n if (!active) {\n return null;\n }\n\n if (active.data.current?.type === 'new-item') {\n const item = active.data.current.item;\n\n return <DefaultDraggableItem item={item} />;\n }\n\n const section = sections.find(s => s.id === active.id);\n\n if (section) {\n const preview = generateSection(section.code, renderProps.fullCode);\n\n return (\n <Sortable id={section.id} name={section.name}>\n <Renderer\n preview={preview}\n modules={renderProps.modules}\n frame={renderProps.frame}\n dynamicTailwind={renderProps.dynamicTailwind}\n />\n </Sortable>\n );\n }\n\n return null;\n};\n\nexport default Overlay;\n","import { useEffect } from 'react';\n\nimport Placeholder from '@tiptap/extension-placeholder';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport StarterKit from '@tiptap/starter-kit';\n\nimport { cn } from '~/utils';\n\nexport interface Props {\n value?: string;\n placeholder?: string;\n className?: string;\n onChange?: (value: string) => void;\n}\n\nconst Tiptap = ({\n value = '',\n placeholder = 'Enter text...',\n className,\n onChange,\n}: Props) => {\n const editor = useEditor({\n extensions: [StarterKit, Placeholder.configure({ placeholder })],\n content: value,\n onBlur: ({ editor: e }) => {\n onChange?.(e.getHTML());\n },\n });\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const current = editor.getHTML();\n\n if (current !== value) {\n editor.commands.setContent(value, { emitUpdate: false });\n }\n }, [value, editor]);\n\n return (\n <EditorContent\n editor={editor}\n className={cn(\n `tiptap-editor min-h-20 rounded border border-gray-200 bg-white px-3\n py-2`,\n 'prose prose-sm max-w-none text-sm text-gray-800',\n '[&_.tiptap]:outline-none',\n '[&_.tiptap_p.is-editor-empty:first-child::before]:pointer-events-none',\n '[&_.tiptap_p.is-editor-empty:first-child::before]:float-left',\n '[&_.tiptap_p.is-editor-empty:first-child::before]:h-0',\n '[&_.tiptap_p.is-editor-empty:first-child::before]:text-gray-400',\n '[&_.tiptap_p.is-editor-empty:first-child::before]:content-[attr(data-placeholder)]',\n className,\n )}\n />\n );\n};\n\nexport default Tiptap;\n","import {\n type DataAttrNode,\n getCurrentValue,\n getStructuredValue,\n parseBinding,\n} from '~/utils/ast';\n\nimport Field from './field';\n\nexport interface FieldEditorProps {\n data: DataAttrNode;\n onChange?: (params: {\n id: string;\n label: string;\n property: string;\n value: unknown;\n }) => void;\n}\n\nconst Node = ({ data, onChange }: FieldEditorProps) => {\n const idAttr = data.dataAttributes.find(a => a.name === 'data-id');\n const bindingAttr = data.dataAttributes.find(a => a.name === 'data-binding');\n\n if (!idAttr?.value || !bindingAttr?.value) {\n return null;\n }\n\n const dataId = idAttr.value;\n const bindings = data.bindings || parseBinding(bindingAttr.value);\n\n if (!bindings.length) {\n return null;\n }\n\n return (\n <div className=\"space-y-2 rounded\">\n <div className=\"space-y-1\">\n {bindings.map(binding => {\n const currentValue = getCurrentValue(data, binding.property);\n const structuredValue = getStructuredValue(\n data,\n binding.property,\n binding.type,\n );\n\n return (\n <div key={binding.label} className=\"space-y-1\">\n <label className=\"block text-xs font-semibold text-gray-700\">\n {binding.label}\n <span className=\"ml-1 text-gray-400\">({binding.property})</span>\n </label>\n <Field\n binding={{\n id: dataId,\n label: binding.label,\n property: binding.property,\n type: binding.type,\n widget: binding.widget,\n options: binding.options,\n render: binding.render,\n min: binding.min,\n max: binding.max,\n pattern: binding.pattern,\n required: binding.required,\n meta: binding.meta,\n value: structuredValue,\n rawValue: currentValue,\n onChange: next =>\n onChange?.({\n id: dataId,\n label: binding.label,\n property: binding.property,\n value: next,\n }),\n }}\n onNodeChange={onChange}\n />\n </div>\n );\n })}\n </div>\n </div>\n );\n};\n\nexport default Node;\n","import { useEffect, useMemo } from 'react';\n\nimport * as t from '@babel/types';\nimport { Button, Checkbox, Toast } from '@jbpark/ui-kit';\nimport { useMultiSelect } from '@jbpark/use-hooks';\nimport { ArrowDown, ArrowUp, Copy, Plus, X } from 'lucide-react';\nimport { nanoid } from 'nanoid';\n\nimport {\n type BindingRenderLeaf,\n type BindingRenderMap,\n type DataAttrNode,\n type ExtractedNodeValue,\n type NodeValueType,\n appendArrayItem,\n duplicateArrayItems,\n extract,\n extractNodeValue,\n extractObjectProperties,\n findEditableChildren,\n generateCode,\n moveArrayItem,\n moveArrayItems,\n parseArrayExpression,\n parseValue,\n removeArrayItems,\n updateArrayItemProperty,\n updateArrayItemValue,\n} from '~/utils/ast';\n\nimport Field from './field';\nimport Node from './node';\n\ninterface ItemProperty extends ExtractedNodeValue {\n astNode: t.Node;\n}\n\ninterface ItemData {\n id: string;\n index: number;\n // Position in the array's elements, which is what `~/utils/ast`'s item\n // functions address. Only differs from `index` when the array mixes\n // objects and primitives.\n elementIndex: number;\n editableProperties: Record<string, ItemProperty>;\n jsxBindings: Record<string, DataAttrNode[]>;\n}\n\ninterface PrimitiveItem {\n id: string;\n index: number;\n elementIndex: number;\n value: string | number | boolean | null;\n type: NodeValueType;\n}\n\ninterface Props {\n value: string;\n render?: BindingRenderMap;\n onChange?: (value: string) => void;\n onChildChange?: (params: {\n id: string;\n label: string;\n property: string;\n value: unknown;\n }) => void;\n}\n\ninterface BulkActionsBarProps {\n count: number;\n onDuplicate: () => void;\n onMoveUp: () => void;\n onMoveDown: () => void;\n onDelete: () => void;\n onClear: () => void;\n}\n\nconst BulkActionsBar = ({\n count,\n onDuplicate,\n onMoveUp,\n onMoveDown,\n onDelete,\n onClear,\n}: BulkActionsBarProps) => {\n if (count === 0) {\n return null;\n }\n\n return (\n <div\n className=\"flex items-center justify-between rounded border\n border-blue-200 bg-blue-50 p-2\"\n >\n <div className=\"text-xs font-medium text-blue-700\">{count} selected</div>\n <div className=\"flex items-center space-x-1\">\n <Button\n size=\"small\"\n icon={<Copy />}\n title=\"Duplicate selected\"\n onClick={onDuplicate}\n />\n <Button\n size=\"small\"\n icon={<ArrowUp />}\n title=\"Move selected up\"\n onClick={onMoveUp}\n />\n <Button\n size=\"small\"\n icon={<ArrowDown />}\n title=\"Move selected down\"\n onClick={onMoveDown}\n />\n <Button\n danger\n size=\"small\"\n icon={<X />}\n title=\"Delete selected\"\n onClick={onDelete}\n />\n <Button size=\"small\" onClick={onClear}>\n Clear\n </Button>\n </div>\n </div>\n );\n};\n\nconst Items = ({ value, render, onChange, onChildChange }: Props) => {\n const { objectItems, primitiveItems, parseError } = useMemo(() => {\n const ast = parseArrayExpression(value);\n\n if (!ast) {\n return {\n objectItems: [],\n primitiveItems: [],\n parseError: true,\n };\n }\n\n const objectItems: ItemData[] = [];\n const primitiveItems: PrimitiveItem[] = [];\n const elements = ast.elements.filter((element): element is t.Expression =>\n Boolean(element),\n );\n\n elements.forEach((element, elementIndex) => {\n if (!t.isObjectExpression(element)) {\n const extracted = extractNodeValue(element);\n\n primitiveItems.push({\n id: nanoid(6),\n index: primitiveItems.length,\n elementIndex,\n value: extracted.value,\n type: extracted.type,\n });\n return;\n }\n\n const jsxBindings: Record<string, DataAttrNode[]> = {};\n\n element.properties.forEach(prop => {\n if (\n !t.isObjectProperty(prop) ||\n !t.isIdentifier(prop.key) ||\n !t.isJSXElement(prop.value)\n ) {\n return;\n }\n\n const propertyName = prop.key.name;\n\n try {\n const jsxCode = generateCode(prop.value);\n const nodes = extract(jsxCode);\n const bindings: DataAttrNode[] = [];\n\n const bindingContainer = nodes.find(node =>\n node.bindings?.some(b => b.property === 'children'),\n );\n\n if (bindingContainer) {\n bindings.push(bindingContainer);\n } else {\n nodes.forEach(node => {\n if (\n node.bindings &&\n node.bindings.length > 0 &&\n node.dataAttributes.some(a => a.name === 'data-id')\n ) {\n bindings.push(node);\n }\n const editableChildren = findEditableChildren(node);\n bindings.push(...editableChildren);\n });\n }\n\n if (bindings.length > 0) {\n jsxBindings[propertyName] = bindings;\n }\n } catch (error) {\n console.error(\n `Failed to parse JSX in property '${propertyName}':`,\n error,\n );\n }\n });\n\n objectItems.push({\n id: nanoid(6),\n index: objectItems.length,\n elementIndex,\n editableProperties: extractObjectProperties(element),\n jsxBindings,\n });\n });\n\n return { objectItems, primitiveItems, parseError: false };\n }, [value]);\n\n useEffect(() => {\n if (parseError) {\n Toast.error('Failed to parse items', {\n description: 'Check the console for details.',\n });\n }\n }, [parseError]);\n\n const isPrimitive = primitiveItems.length > 0 && objectItems.length === 0;\n\n const selection = useMultiSelect(\n isPrimitive ? primitiveItems.length : objectItems.length,\n );\n\n // Every mutation goes through `~/utils/ast`'s item functions: the array\n // source is re-parsed there and a new string comes back, so nothing here\n // holds or edits AST nodes across renders. `null` means the edit could\n // not be applied.\n const commit = (next: string | null) => {\n if (next === null) {\n Toast.error('Failed to update this item', {\n description: 'Check the console for details.',\n });\n return;\n }\n\n onChange?.(next);\n };\n\n // The panel shows one kind at a time, but the array can hold both, so\n // selection indices (positions among the visible items) are translated to\n // element positions before any edit. Keeping the two apart is what stops\n // an edit from dropping the items that aren't on screen.\n const elementIndicesOf = (\n items: { index: number; elementIndex: number }[],\n indices: Set<number>,\n ) => {\n return new Set(\n items\n .filter(item => indices.has(item.index))\n .map(item => item.elementIndex),\n );\n };\n\n const updatePrimitive = (elementIndex: number, next: unknown) => {\n commit(updateArrayItemValue(value, elementIndex, next));\n };\n\n const movePrimitive = (from: number, to: number) => {\n const target = primitiveItems.find(item => item.index === to);\n\n if (!target) {\n return;\n }\n\n commit(moveArrayItem(value, from, target.elementIndex));\n };\n\n const deleteSelectedPrimitives = (indices: Set<number>) => {\n commit(\n removeArrayItems(\n value,\n elementIndicesOf(primitiveItems, indices),\n 'primitive',\n ),\n );\n };\n\n const deletePrimitive = (elementIndex: number) => {\n commit(removeArrayItems(value, new Set([elementIndex]), 'primitive'));\n };\n\n const addPrimitive = () => {\n commit(appendArrayItem(value, 'primitive'));\n };\n\n const duplicateSelectedPrimitives = (indices: Set<number>) => {\n commit(\n duplicateArrayItems(value, elementIndicesOf(primitiveItems, indices)),\n );\n };\n\n const moveSelectedPrimitives = (\n indices: Set<number>,\n direction: 'up' | 'down',\n ) => {\n const result = moveArrayItems(\n value,\n elementIndicesOf(primitiveItems, indices),\n direction,\n );\n\n if (!result) {\n commit(null);\n return;\n }\n\n // Element positions, which match selection indices for the all-one-kind\n // arrays the panel is built for.\n selection.replace(result.indices);\n commit(result.code);\n };\n\n const moveItem = (from: number, to: number) => {\n const target = objectItems.find(item => item.index === to);\n\n if (!target) {\n return;\n }\n\n commit(moveArrayItem(value, from, target.elementIndex));\n };\n\n const updateProperty = (\n elementIndex: number,\n propertyKey: string,\n next: unknown,\n ) => {\n commit(\n updateArrayItemProperty(value, elementIndex, propertyKey, next, render),\n );\n };\n\n const deleteSelectedItems = (indices: Set<number>) => {\n commit(\n removeArrayItems(value, elementIndicesOf(objectItems, indices), 'object'),\n );\n };\n\n const deleteItem = (elementIndex: number) => {\n commit(removeArrayItems(value, new Set([elementIndex]), 'object'));\n };\n\n const addItem = () => {\n commit(appendArrayItem(value, 'object'));\n };\n\n const duplicateSelectedItems = (indices: Set<number>) => {\n commit(duplicateArrayItems(value, elementIndicesOf(objectItems, indices)));\n };\n\n const moveSelectedItems = (\n indices: Set<number>,\n direction: 'up' | 'down',\n ) => {\n const result = moveArrayItems(\n value,\n elementIndicesOf(objectItems, indices),\n direction,\n );\n\n if (!result) {\n commit(null);\n return;\n }\n\n selection.replace(result.indices);\n commit(result.code);\n };\n\n if (isPrimitive) {\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"text-sm font-semibold\">\n Items ({primitiveItems.length})\n </div>\n <Button\n size=\"small\"\n icon={<Plus />}\n variant=\"solid\"\n color=\"green\"\n onClick={addPrimitive}\n >\n Add Item\n </Button>\n </div>\n\n <BulkActionsBar\n count={selection.selected.size}\n onDuplicate={() => duplicateSelectedPrimitives(selection.selected)}\n onMoveUp={() => moveSelectedPrimitives(selection.selected, 'up')}\n onMoveDown={() => moveSelectedPrimitives(selection.selected, 'down')}\n onDelete={() => {\n deleteSelectedPrimitives(selection.selected);\n selection.clear();\n }}\n onClear={selection.clear}\n />\n\n {primitiveItems.map((item, i) => (\n <div\n key={item.id}\n className=\"space-y-2 rounded border border-gray-100 bg-gray-50 p-2\"\n >\n <div className=\"flex items-center justify-between space-x-1\">\n <div\n onClick={e => selection.toggle(item.index, e.shiftKey)}\n className=\"inline-flex\"\n >\n <Checkbox\n checked={selection.isSelected(item.index)}\n onChange={() => {}}\n />\n </div>\n <div className=\"flex space-x-1\">\n <Button\n size=\"small\"\n icon={<ArrowUp />}\n disabled={i === 0}\n onClick={() =>\n movePrimitive(item.elementIndex, item.index - 1)\n }\n />\n <Button\n size=\"small\"\n icon={<ArrowDown />}\n disabled={i === primitiveItems.length - 1}\n onClick={() =>\n movePrimitive(item.elementIndex, item.index + 1)\n }\n />\n <Button\n danger\n size=\"small\"\n icon={<X />}\n disabled={primitiveItems.length <= 1}\n onClick={() => deletePrimitive(item.elementIndex)}\n />\n </div>\n </div>\n <Field\n binding={{\n id: `primitive-${item.id}`,\n label: `item-${i}`,\n property: item.type,\n value: item.value ?? '',\n rawValue: String(item.value ?? ''),\n onChange: next => updatePrimitive(item.elementIndex, next),\n }}\n onNodeChange={onChildChange}\n />\n </div>\n ))}\n </div>\n );\n }\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"text-sm font-semibold\">\n Items ({objectItems.length})\n </div>\n <Button\n size=\"small\"\n icon={<Plus />}\n variant=\"solid\"\n color=\"green\"\n disabled={objectItems.length === 0}\n onClick={addItem}\n >\n Add Item\n </Button>\n </div>\n\n <BulkActionsBar\n count={selection.selected.size}\n onDuplicate={() => duplicateSelectedItems(selection.selected)}\n onMoveUp={() => moveSelectedItems(selection.selected, 'up')}\n onMoveDown={() => moveSelectedItems(selection.selected, 'down')}\n onDelete={() => {\n deleteSelectedItems(selection.selected);\n selection.clear();\n }}\n onClear={selection.clear}\n />\n\n {objectItems.map(item => (\n <div key={item.id} className=\"space-y-3 rounded border bg-gray-50 p-3\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center space-x-2\">\n <div\n onClick={e => selection.toggle(item.index, e.shiftKey)}\n className=\"inline-flex\"\n >\n <Checkbox\n checked={selection.isSelected(item.index)}\n onChange={() => {}}\n />\n </div>\n <div className=\"text-xs font-medium\">Item {item.index + 1}</div>\n </div>\n <div className=\"flex space-x-1\">\n <Button\n size=\"small\"\n icon={<ArrowUp />}\n disabled={item.index === 0}\n onClick={() => moveItem(item.elementIndex, item.index - 1)}\n />\n <Button\n size=\"small\"\n icon={<ArrowDown />}\n disabled={item.index === objectItems.length - 1}\n onClick={() => moveItem(item.elementIndex, item.index + 1)}\n />\n <Button\n danger\n size=\"small\"\n icon={<X />}\n disabled={objectItems.length <= 1}\n onClick={() => deleteItem(item.elementIndex)}\n />\n </div>\n </div>\n <div className=\"space-y-2\">\n {Object.entries(item.editableProperties).map(([key, prop]) => (\n <div key={`${item.id}-${key}`}>\n <div className=\"flex flex-col space-y-2\">\n <label className=\"w-20 shrink-0 text-xs font-medium\">\n {key}\n </label>\n <Field\n binding={{\n id: `item-${item.id}-${key}`,\n label: key,\n property:\n render?.[key] && 'type' in render[key]\n ? ((render[key] as BindingRenderLeaf).property ??\n (render[key].type as string))\n : key,\n type:\n render?.[key] && 'type' in render[key]\n ? (render[key] as BindingRenderLeaf).type\n : undefined,\n render:\n render?.[key] && 'type' in render[key]\n ? (render[key] as BindingRenderLeaf).render\n : render?.[key] && !('type' in render[key])\n ? (render[key] as BindingRenderMap)\n : undefined,\n value: parseValue(String(prop.value)),\n rawValue: String(prop.value),\n onChange: next =>\n updateProperty(item.elementIndex, key, next),\n }}\n onNodeChange={onChildChange}\n />\n </div>\n <span className=\"text-right text-xs text-gray-500\">\n ({prop.type})\n </span>\n </div>\n ))}\n </div>\n <div className=\"space-y-3 border-t pt-2\">\n {Object.entries(item.jsxBindings).length > 0 ? (\n Object.entries(item.jsxBindings).map(\n ([propertyName, bindings]) => (\n <div key={propertyName} className=\"space-y-2\">\n <div className=\"text-xs font-medium text-blue-700\">\n {propertyName} Bindings ({bindings.length}):\n </div>\n {bindings.map((bindingNode, idx) => {\n const nodeId = bindingNode.dataAttributes.find(\n a => a.name === 'data-id',\n )?.value;\n\n return (\n <div\n key={`binding-${item.id}-${propertyName}-${nodeId || idx}`}\n className=\"rounded border border-blue-100 bg-blue-50\n p-2\"\n >\n <div className=\"mb-1 text-xs text-blue-600\">\n <{bindingNode.tagName || 'element'}>\n </div>\n <Node data={bindingNode} onChange={onChildChange} />\n </div>\n );\n })}\n </div>\n ),\n )\n ) : (\n <div className=\"text-xs text-gray-500\">\n ✓ No JSX bindings found\n </div>\n )}\n </div>\n </div>\n ))}\n </div>\n );\n};\n\nexport default Items;\nexport { BulkActionsBar };\n","import { useMemo } from 'react';\n\nimport { Button, Checkbox } from '@jbpark/ui-kit';\nimport { useMultiSelect } from '@jbpark/use-hooks';\nimport { ArrowDown, ArrowUp, Plus, X } from 'lucide-react';\nimport { nanoid } from 'nanoid';\n\nimport { type DataAttrNode, findEditableChildren } from '~/utils/ast';\nimport { moveSelectedIndices, removeIndices } from '~/utils/selection';\n\nimport { BulkActionsBar } from './items';\nimport Node from './node';\n\ninterface Props {\n value: DataAttrNode[];\n onChange?: (value: string) => void;\n onNodeChange?: (params: {\n id: string;\n label: string;\n property: string;\n value: unknown;\n }) => void;\n}\n\nconst Children = ({ value, onChange, onNodeChange }: Props) => {\n const items = useMemo(() => (Array.isArray(value) ? value : []), [value]);\n\n const selection = useMultiSelect(items.length);\n\n const editableChildrenMap = useMemo(() => {\n const map = new Map<number, DataAttrNode[]>();\n items.forEach((item, index) => {\n const editableNodes = findEditableChildren(item);\n if (editableNodes.length > 0) {\n map.set(index, editableNodes);\n }\n });\n return map;\n }, [items]);\n\n const moveItem = (fromIndex: number, toIndex: number) => {\n const nextItems = [...items];\n const [movedItem] = nextItems.splice(fromIndex, 1);\n nextItems.splice(toIndex, 0, movedItem!);\n\n onChange?.(JSON.stringify(nextItems));\n };\n\n const moveSelectedItems = (\n indices: Set<number>,\n direction: 'up' | 'down',\n ) => {\n const { items: nextItems, indices: nextIndices } = moveSelectedIndices(\n items,\n indices,\n direction,\n );\n\n selection.replace(nextIndices);\n onChange?.(JSON.stringify(nextItems));\n };\n\n const deleteSelectedItems = (indices: Set<number>) => {\n if (items.length - indices.size < 1) {\n return;\n }\n\n const nextItems = removeIndices(items, indices);\n onChange?.(JSON.stringify(nextItems));\n };\n\n const deleteItem = (index: number) => deleteSelectedItems(new Set([index]));\n\n const addItem = () => {\n const template = items[0] || createDefaultItem();\n const newItem = cloneDataAttrNode(template);\n\n const nextItems = [...items, newItem];\n onChange?.(JSON.stringify(nextItems));\n };\n\n const duplicateSelectedItems = (indices: Set<number>) => {\n const sources = [...indices]\n .sort((a, b) => a - b)\n .map(index => items[index])\n .filter((item): item is DataAttrNode => Boolean(item));\n\n if (sources.length === 0) {\n return;\n }\n\n const clones = sources.map(cloneDataAttrNode);\n onChange?.(JSON.stringify([...items, ...clones]));\n };\n\n const createDefaultItem = (): DataAttrNode => ({\n id: nanoid(6),\n tagName: 'div',\n attributes: [\n { name: 'data-id', value: nanoid(6) },\n { name: 'data-item', value: 'true' },\n ],\n dataAttributes: [\n { name: 'data-id', value: nanoid(6) },\n { name: 'data-item', value: 'true' },\n ],\n textContent: '',\n children: [],\n });\n\n const cloneDataAttrNode = (node: DataAttrNode): DataAttrNode => ({\n ...node,\n id: nanoid(6),\n attributes: node.attributes.map(attr => ({\n ...attr,\n value: attr.name === 'data-id' ? nanoid(6) : attr.value,\n })),\n dataAttributes: node.dataAttributes.map(attr => ({\n ...attr,\n value: attr.name === 'data-id' ? nanoid(6) : attr.value,\n })),\n children: node.children?.map(cloneDataAttrNode),\n });\n\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <div className=\"text-sm font-semibold text-green-700\">\n Children Items ({items.length})\n </div>\n <Button size=\"small\" color=\"green\" icon={<Plus />} onClick={addItem}>\n Add Child\n </Button>\n </div>\n\n <BulkActionsBar\n count={selection.selected.size}\n onDuplicate={() => duplicateSelectedItems(selection.selected)}\n onMoveUp={() => moveSelectedItems(selection.selected, 'up')}\n onMoveDown={() => moveSelectedItems(selection.selected, 'down')}\n onDelete={() => {\n deleteSelectedItems(selection.selected);\n selection.clear();\n }}\n onClear={selection.clear}\n />\n\n {items.map((item, itemIndex) => (\n <div\n key={item.id || itemIndex}\n className=\"space-y-2 rounded border border-green-200 bg-green-50 p-3\"\n >\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center space-x-2\">\n <div\n onClick={e => selection.toggle(itemIndex, e.shiftKey)}\n className=\"inline-flex\"\n >\n <Checkbox\n checked={selection.isSelected(itemIndex)}\n onChange={() => {}}\n />\n </div>\n <div className=\"text-xs font-medium text-green-800\">\n Child {itemIndex + 1} ({item.tagName || 'fragment'})\n </div>\n </div>\n\n <div className=\"flex space-x-1\">\n <Button\n size=\"small\"\n icon={<ArrowUp />}\n disabled={itemIndex === 0}\n onClick={() => moveItem(itemIndex, itemIndex - 1)}\n />\n <Button\n size=\"small\"\n icon={<ArrowDown />}\n disabled={itemIndex === items.length - 1}\n onClick={() => moveItem(itemIndex, itemIndex + 1)}\n />\n <Button\n title={\n items.length <= 1\n ? 'At least 1 item is required'\n : 'Delete item'\n }\n danger\n size=\"small\"\n icon={<X />}\n disabled={items.length <= 1}\n onClick={() => deleteItem(itemIndex)}\n />\n </div>\n </div>\n\n {editableChildrenMap.has(itemIndex) && (\n <div className=\"space-y-2\">\n <div className=\"text-xs font-medium text-green-700\">\n Editable Bindings:\n </div>\n {editableChildrenMap.get(itemIndex)!.map((editableNode, idx) => {\n const nodeId = editableNode.dataAttributes.find(\n a => a.name === 'data-id',\n )?.value;\n\n return (\n <div\n key={`editable-${itemIndex}-${nodeId || idx}`}\n className=\"rounded border border-green-100 bg-white p-2\"\n >\n <div className=\"mb-1 text-xs text-green-600\">\n {editableNode.tagName}\n </div>\n <Node data={editableNode} onChange={onNodeChange} />\n </div>\n );\n })}\n </div>\n )}\n\n {!!item.children && !editableChildrenMap.has(itemIndex) && (\n <div className=\"space-y-1\">\n <div className=\"text-xs font-medium text-green-700\">\n Child Nodes:\n </div>\n {item.children.map((node, nodeIndex) => (\n <div\n key={`node-${itemIndex}-${nodeIndex}`}\n className=\"ml-2 rounded border border-green-100 bg-white p-2\"\n >\n <Node data={node} onChange={onNodeChange} />\n </div>\n ))}\n </div>\n )}\n </div>\n ))}\n </div>\n );\n};\n\nexport default Children;\n","import type { LucideIcon } from 'lucide-react';\nimport {\n AlertCircle,\n ArrowDown,\n ArrowLeft,\n ArrowRight,\n ArrowUp,\n Bell,\n Bookmark,\n Calendar,\n Camera,\n Check,\n ChevronDown,\n ChevronRight,\n Clock,\n Download,\n Edit,\n Eye,\n Filter,\n Heart,\n Home,\n Image,\n Info,\n Link,\n Mail,\n Map,\n Menu,\n MessageCircle,\n Phone,\n Plus,\n Search,\n Settings,\n Share,\n ShoppingCart,\n Star,\n Trash,\n Upload,\n User,\n X,\n} from 'lucide-react';\n\nexport const ICON_MAP: Record<string, LucideIcon> = {\n AlertCircle,\n ArrowDown,\n ArrowLeft,\n ArrowRight,\n ArrowUp,\n Bell,\n Bookmark,\n Calendar,\n Camera,\n Check,\n ChevronDown,\n ChevronRight,\n Clock,\n Download,\n Edit,\n Eye,\n Filter,\n Heart,\n Home,\n Image,\n Info,\n Link,\n Mail,\n Map,\n Menu,\n MessageCircle,\n Phone,\n Plus,\n Search,\n Settings,\n Share,\n ShoppingCart,\n Star,\n Trash,\n Upload,\n User,\n X,\n};\n\n// The label/value pairs Field's icon-picker feeds to Select, derived once\n// from ICON_MAP — exported (see index.ts) so a custom renderPanel can\n// reach icon-picker parity without rebuilding this itself, per #236/#237.\nexport const ICON_OPTIONS = Object.entries(ICON_MAP).map(([name, Icon]) => ({\n label: (\n <span className=\"flex items-center gap-2\">\n <Icon size={14} />\n {name}\n </span>\n ),\n value: name,\n}));\n","import { useEffect, useRef, useState } from 'react';\n\nimport {\n Checkbox,\n ColorPicker,\n DatePicker,\n Input,\n Select,\n Upload,\n type UploadFile,\n} from '@jbpark/ui-kit';\nimport { useDebounce } from '@jbpark/use-hooks';\n\nimport CoreEditor from '~/components/editor/core';\nimport TiptapEditor from '~/components/editor/tiptap';\nimport { BINDING_PROP } from '~/constants';\nimport { parseValue, validateBindingValue } from '~/utils/ast';\n\nimport type { PanelBinding } from '../dnd';\nimport Children from './children';\nimport { ICON_MAP, ICON_OPTIONS } from './icon-map';\nimport Items from './items';\n\ninterface Props {\n binding: PanelBinding;\n // `Items`/`Children` edit a *different* element than `binding` itself —\n // an array item or a sibling child, each with its own id/label/property —\n // which `binding.onChange`'s single-value shape can't express. This is\n // the internal, node-level escape hatch those two still need (see #237's\n // documented items/children boundary); it isn't part of the public\n // `PanelBinding` surface a custom `renderPanel` sees.\n onNodeChange?: (params: {\n id: string;\n label: string;\n property: string;\n value: unknown;\n }) => void;\n}\n\nconst isColorProperty = (propertyName: string): boolean => {\n const name = propertyName.toLowerCase();\n return name.includes('color');\n};\n\nconst normalizeToHex = (value: string): string => {\n const trimmed = value.trim();\n\n if (/^#([0-9A-Fa-f]{3}){1,2}$/.test(trimmed)) {\n return trimmed;\n }\n return '#000000';\n};\n\nconst parseDateValue = (value: string): Date | undefined => {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value.trim());\n\n if (!match) {\n return undefined;\n }\n\n const [, year, month, day] = match;\n const date = new Date(Number(year), Number(month) - 1, Number(day));\n\n return Number.isNaN(date.getTime()) ? undefined : date;\n};\n\nconst formatDateValue = (date: Date): string => {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n\n return `${year}-${month}-${day}`;\n};\n\n// ColorPicker's onChange fires on every drag frame — committing straight\n// to `onChange` (which drives the AST parse/mutate/re-serialize +\n// generateSections + compile pipeline, see #130) makes a single drag cost\n// upward of 15-25ms per frame. Debouncing the *commit* keeps that pipeline\n// to roughly one run per pause instead of one per frame, while a local\n// `liveValue` state keeps the swatch/hex text updating every frame for\n// responsiveness — ColorPicker is fully controlled (`useControllableState`\n// with `value` always set here), so without this it would visually snap\n// back to the last committed color between debounced commits.\nconst COLOR_COMMIT_DELAY = 75;\n\ninterface ColorPickerFieldProps {\n value: string;\n onChange: (value: string) => void;\n}\n\nconst ColorPickerField = ({ value, onChange }: ColorPickerFieldProps) => {\n const [liveValue, setLiveValue] = useState(value);\n // Tracks `value` purely to detect an external change during render (see\n // below) — refs can't be read/written during render, so this has to be\n // state even though nothing here reads `prevValue` itself afterward.\n const [prevValue, setPrevValue] = useState(value);\n const lastCommittedRef = useRef(value);\n\n // The committed `value` can also change from outside (undo/redo, another\n // field touching the same binding) — stay in sync with it rather than\n // only ever tracking our own commits. Adjusted during render (React's\n // recommended \"reset state when a prop changes\" pattern) rather than in\n // an effect, so the mismatched frame never actually paints.\n if (value !== prevValue) {\n setPrevValue(value);\n setLiveValue(value);\n }\n\n // `lastCommittedRef` only needs to be current by the time `commit` next\n // runs (always from an event handler / debounce timer, never render), so\n // syncing it in an effect — instead of alongside the state adjustment\n // above — keeps the ref access out of the render phase entirely.\n useEffect(() => {\n lastCommittedRef.current = value;\n }, [value]);\n\n const commit = (next: string) => {\n if (next === lastCommittedRef.current) {\n return;\n }\n lastCommittedRef.current = next;\n onChange(next);\n };\n\n const debouncedCommit = useDebounce(() => commit(liveValue), {\n delay: COLOR_COMMIT_DELAY,\n autoInvoke: false,\n });\n\n return (\n <ColorPicker\n showText\n value={liveValue}\n onChange={next => {\n setLiveValue(next);\n debouncedCommit();\n }}\n onOpenChange={open => {\n // Flush immediately on close (picker dismissed / selection\n // finished) instead of waiting out the debounce window, so the\n // last color is never at risk of being dropped by an unmount\n // racing the pending timeout.\n if (!open) {\n commit(liveValue);\n }\n }}\n />\n );\n};\n\nconst Field = ({ binding, onNodeChange }: Props) => {\n // `value` is already structured (its real JS type); `rawValue` is the exact\n // source text used for the raw editors (Items/code/textarea) and as the\n // <input> defaultValue. See #238.\n const { id, value, rawValue, onChange } = binding;\n\n const [validationError, setValidationError] = useState<string | null>(null);\n\n if (\n binding.property === 'items' ||\n binding.property === 'data' ||\n binding.type === 'array'\n ) {\n return (\n <Items\n value={rawValue}\n render={binding.render}\n onChange={onChange}\n onChildChange={onNodeChange}\n />\n );\n }\n\n if (binding.type === 'richtext') {\n return (\n <TiptapEditor\n value={rawValue}\n onChange={next => {\n if (next !== rawValue) {\n onChange(next);\n }\n }}\n />\n );\n }\n\n if (binding.property === BINDING_PROP.INNER_HTML || binding.type === 'jsx') {\n const isHTML = binding.property === BINDING_PROP.INNER_HTML;\n\n return (\n <CoreEditor\n value={rawValue}\n height=\"150px\"\n fragment={!isHTML}\n raw={isHTML}\n onSave={next => {\n if (next !== rawValue) {\n onChange(next);\n }\n }}\n />\n );\n }\n\n if (binding.property === 'children' && Array.isArray(value)) {\n return (\n <Children value={value} onChange={onChange} onNodeChange={onNodeChange} />\n );\n }\n\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n const objectValue = value as Record<string, unknown>;\n\n return (\n <div className=\"space-y-2 rounded border border-gray-200 bg-gray-50 p-2\">\n {Object.entries(objectValue).map(([key, val]) => (\n <div key={key} className=\"space-y-1\">\n <label className=\"block text-xs font-medium text-gray-600\">\n {key}\n </label>\n <Field\n binding={{\n id,\n label: key,\n property:\n binding.render?.[key] && 'type' in binding.render[key]\n ? (binding.render[key].type as string)\n : key,\n type:\n binding.render?.[key] && 'type' in binding.render[key]\n ? (binding.render[key] as { type: PanelBinding['type'] })\n .type\n : undefined,\n render:\n binding.render?.[key] && !('type' in binding.render[key])\n ? (binding.render[key] as PanelBinding['render'])\n : undefined,\n value: val,\n rawValue:\n typeof val === 'object' && val !== null\n ? JSON.stringify(val)\n : String(val),\n onChange: next => {\n onChange({ ...objectValue, [key]: next });\n },\n }}\n onNodeChange={onNodeChange}\n />\n </div>\n ))}\n </div>\n );\n }\n\n if (binding.type === 'boolean' || typeof value === 'boolean') {\n return (\n <Checkbox\n checked={value === true || value === 'true'}\n onChange={checked => {\n onChange(checked);\n }}\n />\n );\n }\n\n const stringValue = rawValue;\n\n if (binding.options && Array.isArray(binding.options)) {\n return (\n <Select\n value={stringValue}\n options={binding.options}\n onChange={next => {\n if (next !== value) {\n onChange(next);\n }\n }}\n />\n );\n }\n\n if (binding.type === 'color' || isColorProperty(binding.property)) {\n return (\n <ColorPickerField\n value={normalizeToHex(stringValue)}\n onChange={onChange}\n />\n );\n }\n\n if (binding.type === 'date') {\n return (\n <div>\n <DatePicker\n defaultValue={parseDateValue(stringValue)}\n onChange={date => {\n const next = date ? formatDateValue(date) : '';\n const result = validateBindingValue(binding, next);\n\n if (!result.valid) {\n setValidationError(result.message ?? 'Invalid value.');\n return;\n }\n\n setValidationError(null);\n\n if (next !== value) {\n onChange(next);\n }\n }}\n />\n {validationError && (\n <p className=\"mt-1 text-xs text-red-500\">{validationError}</p>\n )}\n </div>\n );\n }\n\n if (binding.type === 'url') {\n return (\n <div>\n <Input\n type=\"url\"\n defaultValue={stringValue}\n placeholder=\"https://example.com\"\n onBlur={e => {\n const next = e.target.value.trim();\n const result = validateBindingValue(binding, next);\n\n if (!result.valid) {\n setValidationError(result.message ?? 'Invalid value.');\n return;\n }\n\n setValidationError(null);\n\n if (next !== value) {\n onChange(next);\n }\n }}\n />\n {validationError && (\n <p className=\"mt-1 text-xs text-red-500\">{validationError}</p>\n )}\n </div>\n );\n }\n\n // Checks `type` too, not just `widget`: a `type: 'icon-picker'` binding\n // parsed by `parseBinding` is already normalized to `widget: 'icon-picker'`\n // (see #236), but a hand-constructed BindingItem — e.g. the nested\n // render-leaf case just above, which doesn't carry `widget` — can still\n // arrive with the alias directly in `type`.\n if (binding.widget === 'icon-picker' || binding.type === 'icon-picker') {\n const SelectedIcon = ICON_MAP[stringValue];\n\n return (\n <div className=\"flex items-center gap-2\">\n <Select\n value={stringValue}\n options={ICON_OPTIONS}\n onChange={next => {\n if (next !== value) {\n onChange(next);\n }\n }}\n />\n {SelectedIcon && <SelectedIcon size={18} className=\"shrink-0\" />}\n </div>\n );\n }\n\n if (binding.widget === 'asset-picker' || binding.type === 'asset-picker') {\n const defaultUploadValue: UploadFile[] = stringValue\n ? [\n {\n uid: 'current',\n name: stringValue.split('/').pop() || 'asset',\n url: stringValue,\n },\n ]\n : [];\n\n return (\n <div className=\"space-y-2\">\n <Input\n defaultValue={stringValue}\n placeholder=\"Enter an image URL\"\n onBlur={e => {\n const next = e.target.value.trim();\n const result = validateBindingValue(binding, next);\n\n if (!result.valid) {\n setValidationError(result.message ?? 'Invalid value.');\n return;\n }\n\n setValidationError(null);\n\n if (next !== value) {\n onChange(next);\n }\n }}\n />\n <Upload\n multiple={false}\n maxCount={1}\n accept=\"image/*\"\n defaultValue={defaultUploadValue}\n onChange={files => {\n const next = files[0]?.url ?? '';\n\n if (next !== value) {\n onChange(next);\n }\n }}\n />\n {validationError && (\n <p className=\"mt-1 text-xs text-red-500\">{validationError}</p>\n )}\n </div>\n );\n }\n\n if (binding.type === 'number' || typeof value === 'number') {\n return (\n <div>\n <Input\n type=\"number\"\n defaultValue={stringValue}\n placeholder=\"Enter a numeric value\"\n onBlur={e => {\n const raw = e.target.value.trim();\n // Commit a real number, not a numeric string — the AST boundary\n // and `validateBindingValue` (its `min`/`max`) both expect the\n // value as its declared type now. An unparseable entry falls\n // back to the raw text so a genuine mistake still round-trips\n // rather than becoming `NaN`.\n const next: unknown =\n raw !== '' && !Number.isNaN(Number(raw)) ? Number(raw) : raw;\n const result = validateBindingValue(binding, next);\n\n if (!result.valid) {\n setValidationError(result.message ?? 'Invalid value.');\n return;\n }\n\n setValidationError(null);\n\n if (next !== value) {\n onChange(next);\n }\n }}\n />\n {validationError && (\n <p className=\"mt-1 text-xs text-red-500\">{validationError}</p>\n )}\n </div>\n );\n }\n\n return (\n <div>\n <Input.TextArea\n defaultValue={rawValue}\n placeholder=\"Enter a value\"\n onBlur={e => {\n const raw = e.target.value.trim();\n // Untyped field: infer the value's type from the text the user\n // entered (so `42` commits as a number), the way the old boundary\n // did — but here, in the presentation layer, not by re-guessing in\n // the AST pipeline. A declared string-family type keeps the text\n // verbatim, so `\"{x}\"` stays a string.\n const next: unknown = binding.type ? raw : parseValue(raw);\n const result = validateBindingValue(binding, next);\n\n if (!result.valid) {\n setValidationError(result.message ?? 'Invalid value.');\n return;\n }\n\n setValidationError(null);\n\n if (next !== rawValue) {\n onChange(next);\n }\n }}\n />\n {validationError && (\n <p className=\"mt-1 text-xs text-red-500\">{validationError}</p>\n )}\n </div>\n );\n};\n\nexport default Field;\n","import type { PanelBinding } from '../dnd';\nimport Field from './field';\n\ninterface Props {\n bindings: PanelBinding[];\n onNodeChange?: (params: {\n id: string;\n label: string;\n property: string;\n value: unknown;\n }) => void;\n}\n\n// One bordered group per element `id` — the same visual grouping `Node`\n// (panel/node.tsx) renders, but for the top-level panel list, where\n// `bindings` are already resolved PanelBindings (see dnd.tsx's `bindings`\n// useMemo). `Node` stays a separate component: it still parses a raw\n// DataAttrNode itself, which `Items` needs for elements it discovers\n// dynamically inside an array item's `children` (not present in the\n// top-level `bindings` array at all) — see #237's items/children boundary.\nconst FieldGroup = ({ bindings, onNodeChange }: Props) => (\n <div className=\"space-y-2 rounded\">\n <div className=\"space-y-1\">\n {bindings.map(binding => (\n <div key={binding.label} className=\"space-y-1\">\n <label className=\"block text-xs font-semibold text-gray-700\">\n {binding.label}\n <span className=\"ml-1 text-gray-400\">({binding.property})</span>\n </label>\n <Field binding={binding} onNodeChange={onNodeChange} />\n </div>\n ))}\n </div>\n </div>\n);\n\nexport default FieldGroup;\n","import { useMemo } from 'react';\n\nimport { Button, Typography } from '@jbpark/ui-kit';\nimport { ChevronDown, ChevronUp, Trash } from 'lucide-react';\n\nimport type { Section } from '~/types';\nimport { cn } from '~/utils';\n\nimport type { PanelBinding } from '../dnd';\nimport FieldGroup from './field-group';\n\n// Exported as `Live.Dnd.DefaultPanel` (see index.ts) so a consumer can\n// wrap or partially override the built-in panel instead of starting a\n// `renderPanel` from zero — see #237. Every field here lines up 1:1 with\n// `PanelRenderData` (drop `onChange`, which this panel never needed) with\n// one exception: `onNodeChange` isn't part of the public data a\n// `renderPanel` receives, because it's the internal, node-level escape\n// hatch `Items`/`Children` use to commit a *different* element's edit\n// than any single `PanelBinding.onChange` can express (see field.tsx's\n// items/children boundary note from step 1). It's optional here — a\n// consumer re-embedding `DefaultPanel` outside of `Dnd` itself can omit\n// it, at the cost of nested array/children edits not committing.\nexport interface PanelProps {\n item?: Section;\n onDelete?: (id: string) => void;\n // Reordering by dragging a section on the canvas doesn't work from\n // inside this panel on mobile — the canvas sits behind the Drawer this\n // panel renders in, so there's nothing visible to drag onto. These give\n // an explicit alternative that works regardless of layout.\n onMoveUp?: () => void;\n onMoveDown?: () => void;\n canMoveUp?: boolean;\n canMoveDown?: boolean;\n // `item`'s editable fields, already resolved to PanelBindings by Dnd's\n // `bindings` useMemo — the same data a custom renderPanel receives, so\n // this panel doesn't re-derive it from DataAttrNode a second time (#237).\n bindings: PanelBinding[];\n onNodeChange?: (params: {\n id: string;\n label: string;\n property: string;\n value: unknown;\n }) => void;\n}\n\n// `bindings` is flat (one entry per bound property, across every editable\n// element in the section) — regroup by `id` to render the same \"one\n// bordered box per element\" layout as before. `bindings` is already\n// ordered element-by-element, property-by-property (dnd.tsx builds it via\n// `fields.flatMap`), so a Map preserves both the element order and each\n// element's own property order with no extra sorting.\nconst groupBindingsById = (bindings: PanelBinding[]): PanelBinding[][] => {\n const groups = new Map<string, PanelBinding[]>();\n\n for (const binding of bindings) {\n const group = groups.get(binding.id);\n\n if (group) {\n group.push(binding);\n } else {\n groups.set(binding.id, [binding]);\n }\n }\n\n return [...groups.values()];\n};\n\nconst Panel = ({\n item,\n onDelete,\n onMoveUp,\n onMoveDown,\n canMoveUp = false,\n canMoveDown = false,\n bindings,\n onNodeChange,\n}: PanelProps) => {\n const groups = useMemo(() => groupBindingsById(bindings), [bindings]);\n\n if (!item) {\n return (\n <Typography.Paragraph\n className={cn(\n 'p-4 text-sm text-gray-500',\n //\n )}\n >\n Please select a section.\n </Typography.Paragraph>\n );\n }\n\n return (\n <div\n className={cn(\n 'h-full space-y-4 p-4',\n 'overflow-x-hidden overflow-y-auto',\n //\n )}\n >\n <div className=\"flex items-center justify-between\">\n <Typography.Title className=\"text-lg font-semibold\">\n {item.name}\n </Typography.Title>\n <div className=\"flex items-center gap-1\">\n {onMoveUp && (\n <Button\n icon={<ChevronUp />}\n disabled={!canMoveUp}\n onClick={onMoveUp}\n aria-label=\"Move section up\"\n />\n )}\n {onMoveDown && (\n <Button\n icon={<ChevronDown />}\n disabled={!canMoveDown}\n onClick={onMoveDown}\n aria-label=\"Move section down\"\n />\n )}\n {onDelete && (\n <Button\n danger\n icon={<Trash />}\n onClick={() => onDelete(item.id)}\n aria-label=\"Delete section\"\n />\n )}\n </div>\n </div>\n {!groups.length && (\n <Typography.Text className=\"text-xs text-gray-400\">\n No editable elements.\n </Typography.Text>\n )}\n {groups.map(group => (\n <FieldGroup\n key={group[0]!.id}\n bindings={group}\n onNodeChange={onNodeChange}\n />\n ))}\n </div>\n );\n};\n\nexport default Panel;\n","import { useCallback, useMemo, useState } from 'react';\n\nimport { arrayMove } from '@dnd-kit/sortable';\n\nimport type { Section } from '~/types';\nimport {\n createSectionPreviewCache,\n extractSections,\n replaceSections,\n} from '~/utils';\nimport { fillSectionIds, replaceIds } from '~/utils/ast';\n\nimport { usePreview } from '../context/states';\n\nexport interface SectionDocument {\n sections: Section[];\n previews: string[];\n selectedId: string | null;\n selectedItem?: Section;\n selectedIndex: number;\n select: (id: string) => void;\n clearSelection: () => void;\n add: (item: Pick<Section, 'name' | 'code'>, atIndex?: number) => void;\n remove: (id: string) => void;\n copy: (id: string) => void;\n move: (id: string | null, direction: 'up' | 'down') => void;\n reorder: (activeId: string, overId: string) => void;\n patch: (next: Partial<Section> & { id: string }) => void;\n}\n\n// Owns the document side of the DnD canvas: deriving sections from the code\n// string, tracking which one is selected, and committing every mutation.\n//\n// Extracted from Dnd (#245), where the commit sequence\n// `replaceSections -> onChange -> setCode` was spelled out seven separate\n// times. Naming it once means no mutation can perform half of it, and it\n// puts the section logic somewhere reachable without rendering dnd-kit.\nexport const useSectionDocument = (\n value: string,\n onChange?: (value: string) => void,\n): SectionDocument => {\n const { setCode } = usePreview();\n const [selectedId, setSelectedId] = useState<string | null>(null);\n\n // Sections identify themselves by `data-id`; `getSections` falls back to a\n // positional id for documents predating that (see #245). Filling the gap\n // here makes the ids below real identities rather than positions, so a\n // held `selectedId` survives an insert, copy, move or delete.\n //\n // Deliberately not committed on its own — like dnd.tsx's existing use of\n // fillIds for field ids, the filled document only reaches\n // `onChange`/`setCode` when a real mutation commits, so merely opening a\n // document never rewrites the author's code.\n const document = useMemo(() => fillSectionIds(value), [value]);\n const sections = useMemo(() => extractSections(document), [document]);\n\n // One cache per hook instance (lazy `useState` initializer, never\n // replaced) — see createSectionPreviewCache (#131). It's stateful by\n // design (remembers the previous render's previews to reuse the ones that\n // didn't change), which a `useMemo`/`useRef` can't do without touching a\n // ref during render; a cache object stored via `useState` and only ever\n // mutated through its own method isn't subject to that restriction the way\n // `ref.current` is.\n const [previewCache] = useState(() => createSectionPreviewCache());\n const previews = useMemo(\n () => previewCache.compute(document, sections),\n [previewCache, sections, document],\n );\n\n const selectedIndex = sections.findIndex(s => s.id === selectedId);\n const selectedItem = selectedIndex >= 0 ? sections[selectedIndex] : undefined;\n\n // The single place a set of sections becomes a new document. Takes only\n // `code` because that is genuinely all a commit reads — ids and names are\n // re-derived from the result, never carried across.\n //\n // Runs `fillSectionIds` on the way out so a section that arrived without\n // one still lands with an id: a palette template is a bare `<section>`\n // snippet with no `#app-container`, so it cannot be filled until after\n // it's spliced in. Returns the resulting sections so a caller that needs\n // to select what it just created can read the real id back rather than\n // inventing one.\n const commit = useCallback(\n (nextSections: { code: string }[]): Section[] => {\n const nextCode = fillSectionIds(\n replaceSections(\n document,\n nextSections.map(s => s.code),\n ),\n );\n\n onChange?.(nextCode);\n setCode(nextCode);\n\n return extractSections(nextCode);\n },\n [document, onChange, setCode],\n );\n\n const select = useCallback((id: string) => {\n setSelectedId(prev => (prev === id ? null : id));\n }, []);\n\n const clearSelection = useCallback(() => setSelectedId(null), []);\n\n const add = useCallback(\n (item: Pick<Section, 'name' | 'code'>, atIndex?: number) => {\n const next = { code: item.code };\n\n commit(\n atIndex === undefined || atIndex < 0\n ? [...sections, next]\n : [...sections.slice(0, atIndex), next, ...sections.slice(atIndex)],\n );\n },\n [commit, sections],\n );\n\n const remove = useCallback(\n (id: string) => {\n // Removes by position, not by predicate: `fillSectionIds` keeps ids\n // unique, but a filter would delete every match if that invariant ever\n // slipped — and this is the one destructive operation here, so it\n // shouldn't be the one relying on it.\n const index = sections.findIndex(s => s.id === id);\n\n if (index < 0) {\n return;\n }\n\n // Only the deleted section loses the selection. The previous\n // implementation cleared it unconditionally, so deleting any section\n // closed the panel for whichever one was open.\n if (id === selectedId) {\n setSelectedId(null);\n }\n\n commit(sections.filter((_, i) => i !== index));\n },\n [commit, sections, selectedId],\n );\n\n const copy = useCallback(\n (id: string) => {\n const index = sections.findIndex(s => s.id === id);\n const source = sections[index];\n\n if (!source) {\n return;\n }\n\n // replaceIds refreshes every data-id in the snippet, the section's own\n // included, so the copy carries a distinct identity into the document.\n const committed = commit([\n ...sections.slice(0, index + 1),\n { code: replaceIds(source.code) },\n ...sections.slice(index + 1),\n ]);\n\n // Read the new id back from the committed document. This used to\n // select a `uuidv4()` that was never written into the code and so\n // didn't exist after the next parse, leaving the panel empty right\n // after a copy (#245).\n setSelectedId(committed[index + 1]?.id ?? null);\n },\n [commit, sections],\n );\n\n const move = useCallback(\n (id: string | null, direction: 'up' | 'down') => {\n const index = sections.findIndex(s => s.id === id);\n const targetIndex = direction === 'up' ? index - 1 : index + 1;\n\n if (index < 0 || targetIndex < 0 || targetIndex >= sections.length) {\n return;\n }\n\n // No `setSelectedId` compensation needed any more: the id travels with\n // the section's own markup, so the selection follows it across a move.\n commit(arrayMove(sections, index, targetIndex));\n },\n [commit, sections],\n );\n\n const reorder = useCallback(\n (activeId: string, overId: string) => {\n const prevIndex = sections.findIndex(s => s.id === activeId);\n const nextIndex = sections.findIndex(s => s.id === overId);\n\n if (prevIndex < 0 || nextIndex < 0 || prevIndex === nextIndex) {\n return;\n }\n\n commit(arrayMove(sections, prevIndex, nextIndex));\n },\n [commit, sections],\n );\n\n const patch = useCallback(\n (next: Partial<Section> & { id: string }) => {\n commit(sections.map(s => (s.id === next.id ? { ...s, ...next } : s)));\n },\n [commit, sections],\n );\n\n return {\n sections,\n previews,\n selectedId,\n selectedItem,\n selectedIndex,\n select,\n clearSelection,\n add,\n remove,\n copy,\n move,\n reorder,\n patch,\n };\n};\n","import { useEffect, useMemo, useState } from 'react';\n\nimport {\n DndContext,\n type DragEndEvent,\n type DragOverEvent,\n DragOverlay,\n type DragStartEvent,\n type Modifier,\n PointerSensor,\n closestCenter,\n useSensor,\n useSensors,\n} from '@dnd-kit/core';\nimport { restrictToVerticalAxis } from '@dnd-kit/modifiers';\nimport {\n SortableContext,\n verticalListSortingStrategy,\n} from '@dnd-kit/sortable';\nimport { Button, Drawer, Space, Toast, Typography } from '@jbpark/ui-kit';\nimport { useResponsiveSize } from '@jbpark/use-hooks';\nimport { LayoutGrid } from 'lucide-react';\n\nimport { DRAGGABLE_ITEMS } from '~/constants';\nimport type { Section } from '~/types';\nimport {\n type BindingOption,\n type BindingRenderMap,\n type BindingType,\n type DataAttrNode,\n extract,\n fillIds,\n getCurrentValue,\n getStructuredValue,\n parseBinding,\n update,\n} from '~/utils/ast';\n\nimport { DEFAULT_TEMPLATE } from '../../constants';\nimport { cn, preloadScripts } from '../../utils';\nimport { usePreview } from '../context/states';\nimport { type FrameProps } from '../frame';\nimport DraggableItem, { DefaultDraggableItem } from './draggable';\nimport Droppable from './droppable';\nimport Overlay from './overlay';\nimport Panel from './panel';\nimport Renderer from './renderer';\nimport Sortable from './sortable';\nimport { useSectionDocument } from './use-section-document';\n\nexport interface PaletteRenderData {\n items: Section[];\n onAdd: (item: Section) => void;\n DraggableItem: typeof DraggableItem;\n // True when the palette is rendering inside the mobile Drawer, where a\n // tap can't be a failed drag attempt (there's nothing to drag onto —\n // the canvas is stacked behind the Drawer) and native dblclick synthesis\n // from double-tap is unreliable on touch. Custom renderPalette\n // implementations should treat a single click/tap as \"add\" here instead\n // of relying on onDoubleClick.\n isMobile: boolean;\n}\n\nexport interface PanelRenderData {\n item?: Section;\n onChange: (next: Partial<Section>) => void;\n onDelete: (id: string) => void;\n // Alternative to dragging a section to reorder it — needed since the\n // canvas sits behind the mobile Drawer this panel renders in, so\n // there's nothing visible to drag onto there.\n onMoveUp: () => void;\n onMoveDown: () => void;\n canMoveUp: boolean;\n canMoveDown: boolean;\n // `item`'s editable data-binding fields, already flattened to one entry\n // per bound property (across every non-<section> descendant carrying a\n // `data-binding` attribute). Each entry carries the binding's `type` and\n // current `value` plus an `onChange` wired straight into the same\n // AST-update pipeline the built-in panel uses — including the error Toast\n // on a bad edit. Switch on `type` to render your own control (an\n // `<input>`, `<textarea>`, `<select>`, ...) instead of the built-in one.\n bindings: PanelBinding[];\n}\n\n// One editable data-binding, flattened out of the selected section for a\n// custom renderPanel. Exposes just what a consumer needs to render its own\n// control — the declared `type`, the current `value`, and an `onChange`\n// that commits through Dnd's AST-update pipeline — so it never has to touch\n// DataAttrNode/parseBinding/getCurrentValue itself.\nexport interface PanelBinding {\n // `data-id` of the owning element — stable across edits.\n id: string;\n // Human-readable label from the binding definition.\n label: string;\n // The bound prop/attribute name (e.g. `children`, `src`, `color`).\n property: string;\n // The declared data-binding type — switch on this to pick a control\n // (`string`/`url` -> <input>, `jsx`/`richtext` -> <textarea>, `boolean`\n // -> checkbox, ...). `undefined` means a plain string binding.\n type?: BindingType;\n // Presentation, as opposed to `type`'s data kind — an open string, not a\n // closed enum, since a custom renderPanel can declare any widget it\n // wants (e.g. `'slider'`) and switch on it itself. The built-in panel\n // only recognizes `'icon-picker'`/`'asset-picker'`; anything else falls\n // back to the `type`-appropriate default control. See #236.\n widget?: string;\n // Present when the binding defines a fixed option set (render a <select>).\n options?: BindingOption[];\n // Present for `object`/`array` bindings whose nested keys/items declare\n // their own types — the same map the built-in panel uses to type each\n // nested field instead of falling back to a plain string input.\n render?: BindingRenderMap;\n // Constraints declared on the binding. `min`/`max` compare against the\n // real number `value` delivers for `type: 'number'` bindings (see\n // `validateBindingValue`).\n min?: number;\n max?: number;\n pattern?: string;\n required?: boolean;\n // Consumer-defined keys carried straight through from the authored\n // data-binding — namespaced instead of spread onto PanelBinding so they\n // can't collide with a future first-class field. Absent when nothing\n // extra was authored. See #234.\n meta?: Record<string, unknown>;\n // Current value as its real JS type — a number for `type: 'number'`, a\n // boolean for `type: 'boolean'`, an object/array for `object`/`array`,\n // a string otherwise. Switch on this without re-parsing. See #238.\n value: unknown;\n // The exact source text behind `value`, for cases that can't round-trip\n // through a JS value — `jsx`/`richtext` bindings, or an attribute whose\n // source is an expression you want to edit as text.\n rawValue: string;\n // Commit a new value through the same AST-update pipeline the built-in\n // panel uses (including the error Toast on a bad edit). Pass the value as\n // its real type; it's serialized once, at the AST boundary, where the\n // declared `type` is known — so no string quoting/guessing on your side.\n onChange: (value: unknown) => void;\n}\n\nexport interface Props extends Omit<\n React.ComponentPropsWithRef<'div'>,\n 'onChange'\n> {\n value?: string;\n props?: Record<string, unknown>;\n modules?: Record<string, unknown>;\n items?: Section[];\n frame?: FrameProps;\n dynamicTailwind?: boolean;\n provider?: (children: React.ReactNode) => React.ReactNode;\n onChange?: (value: string) => void;\n // Full replacements for the built-in left palette / right panel — receive\n // the same data/callbacks Dnd itself uses, so drag-and-drop and field\n // editing keep working exactly as before, just with custom markup. Used\n // for both the desktop layout and the mobile drawer, since those already\n // render identical content today.\n renderPalette?: (data: PaletteRenderData) => React.ReactNode;\n renderPanel?: (data: PanelRenderData) => React.ReactNode;\n}\n\nconst conditionalModifiers: Modifier = args => {\n const { active } = args;\n\n if (active?.data.current?.type === 'new-item') {\n return args.transform;\n }\n\n return restrictToVerticalAxis(args);\n};\n\nconst Dnd = ({\n value: _value,\n props,\n modules = {},\n onChange: _onChange,\n className,\n items = [],\n frame,\n dynamicTailwind = false,\n provider,\n renderPalette,\n renderPanel,\n ...restProps\n}: Props) => {\n const [mobilePaletteOpen, setMobilePaletteOpen] = useState(false);\n\n const { breakpoint } = useResponsiveSize();\n const isMobile = breakpoint.current === 'xs' || breakpoint.current === 'sm';\n\n // Read-only here — `useSectionDocument` below owns `setCode` (the commit\n // side). `code` is still needed locally: it feeds `value`'s fallback\n // chain just below, and `value` itself is read again further down for\n // the drag overlay's `fullCode` — not something `useSectionDocument`\n // exposes back out.\n const { code } = usePreview();\n\n const sensors = useSensors(\n useSensor(PointerSensor, {\n activationConstraint: {\n distance: 10,\n },\n }),\n );\n\n // Uncontrolled usage (`<Live.Dnd />` with no `value`) used to read\n // nothing but DEFAULT_TEMPLATE forever: every edit committed through\n // useSectionDocument writes into PreviewContext, but this component\n // never read `code` back — so the section a reader just dragged in\n // vanished on the very next render. `Client` (preview/client.tsx)\n // already resolves the same dual-source situation with `_code || code`;\n // mirrored here, with DEFAULT_TEMPLATE kept only as the final fallback\n // for the case neither is set (fresh, empty context) — see #244.\n const value = _value || code || DEFAULT_TEMPLATE;\n\n const {\n sections,\n previews,\n selectedId,\n selectedItem,\n selectedIndex,\n select,\n clearSelection,\n add: addItem,\n remove: onDelete,\n copy: onCopy,\n move: moveSection,\n reorder,\n patch,\n } = useSectionDocument(value, _onChange);\n\n const onDragStart = (_: DragStartEvent) => {};\n\n const onDragOver = (_e: DragOverEvent) => {};\n\n const onDragEnd = (event: DragEndEvent) => {\n const { active, over } = event;\n\n if (!over) {\n return;\n }\n\n if (active.data.current?.type === 'new-item') {\n const item = active.data.current.item as Section;\n const atBottom =\n over.id === 'sortable-area' || over.id === 'sortable-area-bottom';\n\n addItem(\n item,\n atBottom ? undefined : sections.findIndex(s => s.id === over.id),\n );\n return;\n }\n\n if (active.id !== over.id && sections.some(s => s.id === active.id)) {\n reorder(String(active.id), String(over.id));\n }\n };\n\n const onSelect = (id: string) => select(id);\n\n const onChange = (next: Partial<Section>) => {\n if (!next.id) {\n return;\n }\n\n patch(next as Partial<Section> & { id: string });\n };\n\n // Reads only the extracted `code` local, not `selectedItem`, so the\n // compiler can verify this dependency array actually matches what the\n // body reads — matches Panel's own former version of this same logic,\n // now shared here so both the built-in Panel and a custom renderPanel\n // get the same extraction/update pipeline instead of each needing it.\n const selectedCode = selectedItem?.code;\n const { fields, updatedCode, parseError } = useMemo(() => {\n if (!selectedCode) {\n return {\n fields: [] as DataAttrNode[],\n updatedCode: '',\n parseError: false,\n };\n }\n\n try {\n const updated = fillIds(selectedCode);\n const allNodes = extract(updated);\n const filtered = allNodes.filter(node => node.tagName !== 'section');\n\n return {\n fields: filtered,\n updatedCode: updated !== selectedCode ? updated : selectedCode,\n parseError: false,\n };\n } catch (e) {\n console.warn('⚠️ Parsing error', e);\n return {\n fields: [] as DataAttrNode[],\n updatedCode: '',\n parseError: true,\n };\n }\n }, [selectedCode]);\n\n useEffect(() => {\n if (parseError) {\n Toast.error('Failed to parse this section', {\n description: 'Check the console for details.',\n });\n }\n }, [parseError]);\n\n const onFieldChange = ({\n id,\n label,\n property,\n value: fieldValue,\n }: {\n id: string;\n label: string;\n property: string;\n value: unknown;\n }) => {\n const result = update(updatedCode, id, label, fieldValue, property);\n\n if (!result.success) {\n Toast.error('Failed to update this field', {\n description: 'Check the console for details.',\n });\n return;\n }\n\n if (selectedItem) {\n onChange({ ...selectedItem, code: result.code });\n }\n };\n\n // Flattens the extracted `fields` (one DataAttrNode per element) down to\n // one PanelBinding per bound property — the same walk the built-in\n // FieldEditor/Node does internally (data-id + parsed data-binding +\n // current value), but handed to a custom renderPanel as plain data so it\n // can render its own controls. Kept in a useMemo keyed on `fields` alone;\n // `onFieldChange` closes over `updatedCode`/`selectedItem` but is stable\n // enough per render, and rebuilding on every render would defeat the memo\n // guarding renderPanel's children.\n const bindings = useMemo<PanelBinding[]>(() => {\n return fields.flatMap(node => {\n const dataId = node.dataAttributes.find(a => a.name === 'data-id')?.value;\n const bindingAttr = node.dataAttributes.find(\n a => a.name === 'data-binding',\n )?.value;\n\n if (!dataId || !bindingAttr) {\n return [];\n }\n\n const parsed = node.bindings ?? parseBinding(bindingAttr);\n\n return parsed.map(binding => ({\n id: dataId,\n label: binding.label,\n property: binding.property,\n type: binding.type,\n widget: binding.widget,\n options: binding.options,\n render: binding.render,\n min: binding.min,\n max: binding.max,\n pattern: binding.pattern,\n required: binding.required,\n meta: binding.meta,\n value: getStructuredValue(node, binding.property, binding.type),\n rawValue: getCurrentValue(node, binding.property),\n onChange: (value: unknown) =>\n onFieldChange({\n id: dataId,\n label: binding.label,\n property: binding.property,\n value,\n }),\n }));\n });\n // onFieldChange is intentionally omitted — it's recreated every render\n // but only ever called from a user event, so closing over the latest\n // one via the render that produced these bindings is fine.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fields]);\n\n useEffect(() => {\n if (frame?.scripts?.length) {\n preloadScripts(frame.scripts);\n }\n }, [frame?.scripts]);\n\n const renderPaletteItems = (\n onAdd: (item: Section) => void,\n forMobileDrawer = false,\n ) => {\n const paletteItems = items?.length ? items : DRAGGABLE_ITEMS;\n\n if (renderPalette) {\n return renderPalette({\n items: paletteItems,\n onAdd,\n DraggableItem,\n isMobile: forMobileDrawer,\n });\n }\n\n return (\n <Space orientation=\"vertical\" align=\"start\">\n {paletteItems.map(item => (\n <DefaultDraggableItem\n key={item.id}\n item={item}\n onAdd={onAdd}\n tapToAdd={forMobileDrawer}\n />\n ))}\n </Space>\n );\n };\n\n const renderPanelContent = () => {\n const canMoveUp = selectedIndex > 0;\n const canMoveDown =\n selectedIndex >= 0 && selectedIndex < sections.length - 1;\n\n if (renderPanel) {\n return renderPanel({\n item: selectedItem,\n onChange,\n onDelete,\n onMoveUp: () => moveSection(selectedId, 'up'),\n onMoveDown: () => moveSection(selectedId, 'down'),\n canMoveUp,\n canMoveDown,\n bindings,\n });\n }\n\n return (\n <Panel\n item={selectedItem}\n onDelete={onDelete}\n onMoveUp={() => moveSection(selectedId, 'up')}\n onMoveDown={() => moveSection(selectedId, 'down')}\n canMoveUp={canMoveUp}\n canMoveDown={canMoveDown}\n bindings={bindings}\n onNodeChange={onFieldChange}\n />\n );\n };\n\n return (\n <>\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n modifiers={[\n conditionalModifiers,\n //\n ]}\n onDragStart={onDragStart}\n onDragOver={onDragOver}\n onDragEnd={onDragEnd}\n >\n <div\n className={cn(\n 'relative flex w-full',\n className,\n //\n )}\n {...restProps}\n >\n <div className=\"hidden w-1/5 overflow-y-auto md:block\">\n <div className=\"h-full bg-gray-50 p-4\">\n {renderPaletteItems(addItem)}\n </div>\n </div>\n <div\n className={cn(\n 'relative',\n 'h-full w-full md:w-3/5',\n 'overflow-y-auto',\n //\n )}\n data-frame-container\n style={{\n isolation: 'isolate',\n contain: 'layout style',\n transform: 'translateZ(0)',\n }}\n >\n <Droppable\n className={cn(\n !sections.length && 'h-full',\n //\n )}\n >\n {!sections.length ? (\n <div\n className={cn(\n 'flex items-center justify-center',\n 'h-full',\n 'text-gray-500',\n )}\n >\n <Space orientation=\"vertical\" align=\"center\">\n <Typography.Paragraph>\n No sections available\n </Typography.Paragraph>\n <Typography.Text>\n {isMobile\n ? 'Tap a component to add it'\n : 'Drag a component from the left to add it'}\n </Typography.Text>\n </Space>\n </div>\n ) : (\n <SortableContext\n items={sections.map(s => s.id)}\n strategy={verticalListSortingStrategy}\n >\n {sections.map((section, index) => (\n <Sortable\n key={section.id}\n id={section.id}\n name={section.name}\n selected={selectedId === section.id}\n onClick={() => onSelect(section.id)}\n onDelete={onDelete}\n onCopy={onCopy}\n >\n <Renderer\n preview={previews[index]!}\n modules={modules}\n frame={frame}\n dynamicTailwind={dynamicTailwind}\n provider={provider}\n {...props}\n />\n </Sortable>\n ))}\n </SortableContext>\n )}\n </Droppable>\n </div>\n <div className=\"hidden w-1/5 md:block\">{renderPanelContent()}</div>\n <Button\n type=\"primary\"\n shape=\"circle\"\n icon={<LayoutGrid />}\n aria-label=\"Components\"\n className=\"fixed right-4 bottom-4 z-20 md:hidden\"\n onClick={() => setMobilePaletteOpen(true)}\n />\n <Drawer\n open={isMobile && mobilePaletteOpen}\n onClose={() => setMobilePaletteOpen(false)}\n direction=\"bottom\"\n size=\"large\"\n title=\"Components\"\n >\n {renderPaletteItems(item => {\n addItem(item);\n setMobilePaletteOpen(false);\n }, true)}\n </Drawer>\n <Drawer\n open={isMobile && Boolean(selectedId)}\n onClose={clearSelection}\n direction=\"bottom\"\n size=\"large\"\n title=\"Properties\"\n >\n {renderPanelContent()}\n </Drawer>\n </div>\n <DragOverlay>\n <Overlay\n sections={sections}\n renderProps={{\n fullCode: value,\n modules,\n frame,\n dynamicTailwind,\n ...props,\n }}\n />\n </DragOverlay>\n </DndContext>\n </>\n );\n};\n\nexport default Dnd;\n","import DndImpl, {\n type PaletteRenderData,\n type PanelBinding,\n type PanelRenderData,\n type Props,\n} from './dnd';\nimport DraggableItem, {\n type DraggableItemDragState,\n type DraggableItemProps,\n} from './draggable';\nimport { ICON_MAP, ICON_OPTIONS } from './panel/icon-map';\nimport DefaultPanel, { type PanelProps } from './panel/panel';\n\ntype DndComponent = typeof DndImpl & {\n DraggableItem: typeof DraggableItem;\n // The built-in property panel, exported so a `renderPanel` can wrap or\n // partially override it instead of starting from zero — see #237. Its\n // props line up with `PanelRenderData` (drop `onChange`; `bindings`\n // is the same array). See panel.tsx's own doc comment for the one\n // exception (`onNodeChange`, optional, internal-only).\n DefaultPanel: typeof DefaultPanel;\n};\n\nconst Dnd = DndImpl as DndComponent;\n\nDnd.DraggableItem = DraggableItem;\nDnd.DefaultPanel = DefaultPanel;\n\nexport { DraggableItem, DefaultPanel };\n// The built-in panel's own `widget: 'icon-picker'` icon set/options —\n// exported so a custom renderPanel can reach icon-picker parity (name ->\n// lucide-react component, and the same label/value pairs fed to Select)\n// instead of reimplementing an icon library, per #236/#237.\nexport { ICON_MAP, ICON_OPTIONS };\nexport type {\n Props,\n PaletteRenderData,\n PanelRenderData,\n PanelBinding,\n PanelProps,\n DraggableItemProps,\n DraggableItemDragState,\n};\nexport default Dnd;\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { v as Section } from "./document-J9Lo9p81.js";
|
|
2
|
-
import {
|
|
2
|
+
import { B as BindingRenderMap, R as BindingOption, V as BindingType } from "./index-FKgYmeNR.js";
|
|
3
3
|
import { t as FrameProps } from "./index-DpDU1IAw.js";
|
|
4
4
|
import { LucideIcon } from "lucide-react";
|
|
5
5
|
//#region src/components/dnd/draggable.d.ts
|
|
@@ -95,4 +95,4 @@ type DndComponent = typeof Dnd$1 & {
|
|
|
95
95
|
declare const Dnd: DndComponent;
|
|
96
96
|
//#endregion
|
|
97
97
|
export { ICON_OPTIONS as a, PanelRenderData as c, DraggableItemDragState as d, DraggableItemProps as f, ICON_MAP as i, Props as l, Panel as n, PaletteRenderData as o, PanelProps as r, PanelBinding as s, Dnd as t, DraggableItem as u };
|
|
98
|
-
//# sourceMappingURL=index-
|
|
98
|
+
//# sourceMappingURL=index-2CUWhF-T.d.ts.map
|
|
@@ -88,6 +88,25 @@ declare const arrayExpressionToCode: (elements: ObjectExpression[]) => string;
|
|
|
88
88
|
//#region src/utils/ast/helpers.d.ts
|
|
89
89
|
declare const generateCode: (node: Node) => string;
|
|
90
90
|
//#endregion
|
|
91
|
+
//#region src/utils/ast/items.d.ts
|
|
92
|
+
type ItemKind = 'object' | 'primitive';
|
|
93
|
+
interface ArrayItem {
|
|
94
|
+
index: number;
|
|
95
|
+
kind: ItemKind;
|
|
96
|
+
node: Expression;
|
|
97
|
+
}
|
|
98
|
+
declare const parseItems: (code: string) => ArrayItem[] | null;
|
|
99
|
+
declare const updateArrayItemProperty: (code: string, index: number, key: string, value: unknown, render?: BindingRenderMap) => string | null;
|
|
100
|
+
declare const updateArrayItemValue: (code: string, index: number, value: unknown) => string | null;
|
|
101
|
+
declare const moveArrayItem: (code: string, from: number, to: number) => string | null;
|
|
102
|
+
declare const moveArrayItems: (code: string, indices: Set<number>, direction: "up" | "down") => {
|
|
103
|
+
code: string;
|
|
104
|
+
indices: Set<number>;
|
|
105
|
+
} | null;
|
|
106
|
+
declare const removeArrayItems: (code: string, indices: Set<number>, kind?: ItemKind) => string | null;
|
|
107
|
+
declare const duplicateArrayItems: (code: string, indices: Set<number>, generateId?: () => string) => string | null;
|
|
108
|
+
declare const appendArrayItem: (code: string, kind: ItemKind, generateId?: () => string) => string | null;
|
|
109
|
+
//#endregion
|
|
91
110
|
//#region src/utils/ast/extract.d.ts
|
|
92
111
|
declare function extract(raw: string): DataAttrNode[];
|
|
93
112
|
declare function clearExtractCache(): void;
|
|
@@ -143,5 +162,5 @@ interface ValidationResult {
|
|
|
143
162
|
}
|
|
144
163
|
declare const validateBindingValue: (binding: BindingItem, value: unknown) => ValidationResult;
|
|
145
164
|
//#endregion
|
|
146
|
-
export {
|
|
147
|
-
//# sourceMappingURL=index-
|
|
165
|
+
export { parseValue as A, BindingRenderMap as B, EditableValueEntry as C, extractObjectProperties as D, extractNodeValue as E, parseBinding as F, NodeValueType as G, DataAttrNode as H, parseBindingExpression as I, BindingItem as L, findEditableChildren as M, getCurrentValue as N, flattenEditableValue as O, getStructuredValue as P, BindingOption as R, EditablePrimitive as S, createNodeFromValue as T, EditableNodeValueType as U, BindingType as V, ExtractedNodeValue as W, removeArrayItems as _, replaceIds as a, generateCode as b, clearExtractCache as c, ItemKind as d, appendArrayItem as f, parseItems as g, moveArrayItems as h, fillIds as i, setEditableValue as j, parseArrayExpression as k, extract as l, moveArrayItem as m, validateBindingValue as n, bulkUpdate as o, duplicateArrayItems as p, clone as r, update as s, ValidationResult as t, ArrayItem as u, updateArrayItemProperty as v, arrayExpressionToCode as w, EditablePathSegment as x, updateArrayItemValue as y, BindingRenderLeaf as z };
|
|
166
|
+
//# sourceMappingURL=index-FKgYmeNR.d.ts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { v as Section } from "./document-J9Lo9p81.js";
|
|
2
2
|
import { t as FrameProps } from "./index-DpDU1IAw.js";
|
|
3
|
-
import { c as PanelRenderData, f as DraggableItemProps, l as Props, o as PaletteRenderData, r as PanelProps, s as PanelBinding, t as Dnd } from "./index-
|
|
3
|
+
import { c as PanelRenderData, f as DraggableItemProps, l as Props, o as PaletteRenderData, r as PanelProps, s as PanelBinding, t as Dnd } from "./index-2CUWhF-T.js";
|
|
4
4
|
import { a as Props$2, n as EditorRenderData, r as Props$1, t as Editor } from "./index-C4TBkJBG.js";
|
|
5
5
|
import { a as Props$5, n as Props$4, o as Props$3, s as ErrorBoundary, t as Error } from "./index-CCynrS6c.js";
|
|
6
6
|
import { n as Props$6, t as Preview } from "./index-lgHdCda5.js";
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as ContextProvider } from "./context-Yb81ZxnN.js";
|
|
2
|
-
import { t as Dnd } from "./dnd-
|
|
2
|
+
import { t as Dnd } from "./dnd-Cyuif73L.js";
|
|
3
3
|
import { t as Editor } from "./editor-jzeeLkwi.js";
|
|
4
4
|
import { t as Error } from "./error-C47PVZgY.js";
|
|
5
5
|
import { t as Preview } from "./preview-8OZDsfGT.js";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { a as fillSectionIds, c as generateSectionPreviews, d as replaceDocumentSections, i as createSectionPreviewCache, l as getSections, n as SectionPreviewCache, o as generateDocumentCode, r as clearDocumentParseCache, s as generateSectionPreview, t as DocumentTree, u as parseDocument } from "../../document-J9Lo9p81.js";
|
|
2
|
-
import { A as BindingRenderMap, C as
|
|
3
|
-
export { type BindingItem, type BindingOption, type BindingRenderLeaf, type BindingRenderMap, type BindingType, type DataAttrNode, type DocumentTree, type EditableNodeValueType, type EditablePathSegment, type EditablePrimitive, type EditableValueEntry, type ExtractedNodeValue, type NodeValueType, type SectionPreviewCache, type ValidationResult, arrayExpressionToCode, bulkUpdate, clearDocumentParseCache, clearExtractCache, clone, createNodeFromValue, createSectionPreviewCache, extract, extractNodeValue, extractObjectProperties, fillIds, fillSectionIds, findEditableChildren, flattenEditableValue, generateCode, generateDocumentCode, generateSectionPreview, generateSectionPreviews, getCurrentValue, getSections, getStructuredValue, parseArrayExpression, parseBinding, parseBindingExpression, parseDocument, parseValue, replaceDocumentSections, replaceIds, setEditableValue, update, validateBindingValue };
|
|
2
|
+
import { A as parseValue, B as BindingRenderMap, C as EditableValueEntry, D as extractObjectProperties, E as extractNodeValue, F as parseBinding, G as NodeValueType, H as DataAttrNode, I as parseBindingExpression, L as BindingItem, M as findEditableChildren, N as getCurrentValue, O as flattenEditableValue, P as getStructuredValue, R as BindingOption, S as EditablePrimitive, T as createNodeFromValue, U as EditableNodeValueType, V as BindingType, W as ExtractedNodeValue, _ as removeArrayItems, a as replaceIds, b as generateCode, c as clearExtractCache, d as ItemKind, f as appendArrayItem, g as parseItems, h as moveArrayItems, i as fillIds, j as setEditableValue, k as parseArrayExpression, l as extract, m as moveArrayItem, n as validateBindingValue, o as bulkUpdate, p as duplicateArrayItems, r as clone, s as update, t as ValidationResult, u as ArrayItem, v as updateArrayItemProperty, w as arrayExpressionToCode, x as EditablePathSegment, y as updateArrayItemValue, z as BindingRenderLeaf } from "../../index-FKgYmeNR.js";
|
|
3
|
+
export { type ArrayItem, type BindingItem, type BindingOption, type BindingRenderLeaf, type BindingRenderMap, type BindingType, type DataAttrNode, type DocumentTree, type EditableNodeValueType, type EditablePathSegment, type EditablePrimitive, type EditableValueEntry, type ExtractedNodeValue, type ItemKind, type NodeValueType, type SectionPreviewCache, type ValidationResult, appendArrayItem, arrayExpressionToCode, bulkUpdate, clearDocumentParseCache, clearExtractCache, clone, createNodeFromValue, createSectionPreviewCache, duplicateArrayItems, extract, extractNodeValue, extractObjectProperties, fillIds, fillSectionIds, findEditableChildren, flattenEditableValue, generateCode, generateDocumentCode, generateSectionPreview, generateSectionPreviews, getCurrentValue, getSections, getStructuredValue, moveArrayItem, moveArrayItems, parseArrayExpression, parseBinding, parseBindingExpression, parseDocument, parseItems, parseValue, removeArrayItems, replaceDocumentSections, replaceIds, setEditableValue, update, updateArrayItemProperty, updateArrayItemValue, validateBindingValue };
|
package/dist/utils/ast/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { a as generateSectionPreview, c as parseDocument, i as generateDocumentCode, l as replaceDocumentSections, n as createSectionPreviewCache, o as generateSectionPreviews, r as fillSectionIds, s as getSections, t as clearDocumentParseCache } from "../../document-DEx4WyCn.js";
|
|
2
|
-
import {
|
|
3
|
-
export { arrayExpressionToCode, bulkUpdate, clearDocumentParseCache, clearExtractCache, clone, createNodeFromValue, createSectionPreviewCache, extract, extractNodeValue, extractObjectProperties, fillIds, fillSectionIds, findEditableChildren, flattenEditableValue, generateCode, generateDocumentCode, generateSectionPreview, generateSectionPreviews, getCurrentValue, getSections, getStructuredValue, parseArrayExpression, parseBinding, parseBindingExpression, parseDocument, parseValue, replaceDocumentSections, replaceIds, setEditableValue, update, validateBindingValue };
|
|
2
|
+
import { A as parseValue, C as parseBindingExpression, D as extractObjectProperties, E as extractNodeValue, M as generateCode, O as flattenEditableValue, S as parseBinding, T as createNodeFromValue, a as extract, b as getCurrentValue, c as moveArrayItem, d as removeArrayItems, f as updateArrayItemProperty, g as replaceIds, h as fillIds, i as clearExtractCache, j as setEditableValue, k as parseArrayExpression, l as moveArrayItems, m as clone, n as bulkUpdate, o as appendArrayItem, p as updateArrayItemValue, r as update, s as duplicateArrayItems, t as validateBindingValue, u as parseItems, w as arrayExpressionToCode, x as getStructuredValue, y as findEditableChildren } from "../../ast-BKQmEBj9.js";
|
|
3
|
+
export { appendArrayItem, arrayExpressionToCode, bulkUpdate, clearDocumentParseCache, clearExtractCache, clone, createNodeFromValue, createSectionPreviewCache, duplicateArrayItems, extract, extractNodeValue, extractObjectProperties, fillIds, fillSectionIds, findEditableChildren, flattenEditableValue, generateCode, generateDocumentCode, generateSectionPreview, generateSectionPreviews, getCurrentValue, getSections, getStructuredValue, moveArrayItem, moveArrayItems, parseArrayExpression, parseBinding, parseBindingExpression, parseDocument, parseItems, parseValue, removeArrayItems, replaceDocumentSections, replaceIds, setEditableValue, update, updateArrayItemProperty, updateArrayItemValue, validateBindingValue };
|