@jbpark/live-editor 4.2.0 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/{ast-CMD20ykx.js → ast-BFbDWO-l.js} +198 -208
  2. package/dist/ast-BFbDWO-l.js.map +1 -0
  3. package/dist/{boundary-D2IFja-3.js → boundary-B17cepvm.js} +12 -9
  4. package/dist/boundary-B17cepvm.js.map +1 -0
  5. package/dist/dnd/index.d.ts +2 -2
  6. package/dist/dnd/index.js +2 -2
  7. package/dist/{dnd-DBaH2L8N.js → dnd-Z1KS16Fy.js} +462 -222
  8. package/dist/dnd-Z1KS16Fy.js.map +1 -0
  9. package/dist/{document-C3eCRQlj.js → document-cEEdFERz.js} +79 -20
  10. package/dist/document-cEEdFERz.js.map +1 -0
  11. package/dist/error/index.d.ts +1 -1
  12. package/dist/error/index.js +2 -2
  13. package/dist/{error-KW8XCcjH.js → error-DWhxQEom.js} +2 -2
  14. package/dist/{error-KW8XCcjH.js.map → error-DWhxQEom.js.map} +1 -1
  15. package/dist/{index-DNNj_0ba.d.ts → index-C4SGQ3Ci.d.ts} +4 -3
  16. package/dist/{index-DVgwXnPa.d.ts → index-CtlUYnWq.d.ts} +25 -3
  17. package/dist/index.d.ts +4 -4
  18. package/dist/index.js +3 -3
  19. package/dist/index.js.map +1 -1
  20. package/dist/preview/index.js +2 -2
  21. package/dist/{preview-B9Jhv1Up.js → preview-C_UzpGWh.js} +3 -3
  22. package/dist/{preview-B9Jhv1Up.js.map → preview-C_UzpGWh.js.map} +1 -1
  23. package/dist/{sections-A4TAXUP8.js → sections-GJQ63uEB.js} +2 -2
  24. package/dist/{sections-A4TAXUP8.js.map → sections-GJQ63uEB.js.map} +1 -1
  25. package/dist/{use-dynamic-tailwind-BDfytfYC.js → use-dynamic-tailwind-DpbjmATF.js} +5 -5
  26. package/dist/use-dynamic-tailwind-DpbjmATF.js.map +1 -0
  27. package/dist/utils/ast/index.js +2 -2
  28. package/dist/utils/index.js +2 -2
  29. package/package.json +1 -1
  30. package/dist/ast-CMD20ykx.js.map +0 -1
  31. package/dist/boundary-D2IFja-3.js.map +0 -1
  32. package/dist/dnd-DBaH2L8N.js.map +0 -1
  33. package/dist/document-C3eCRQlj.js.map +0 -1
  34. package/dist/use-dynamic-tailwind-BDfytfYC.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast-BFbDWO-l.js","names":["t","parseExpression","parseExpression","t","t","t","parseExpression","t","parse","parseExpression","t","t","parseExpression","parse"],"sources":["../src/utils/ast/types.ts","../src/utils/ast/value.ts","../src/utils/ast/binding.ts","../src/utils/selection.ts","../src/utils/ast/patch.ts","../src/utils/ast/array-source.ts","../src/utils/ast/items.ts","../src/utils/ast/extract.ts","../src/utils/ast/children.ts","../src/utils/ast/update.ts","../src/utils/ast/validate.ts"],"sourcesContent":["export interface Attribute {\n name: string;\n value: string | null;\n isStringLiteral?: boolean;\n}\n\nexport interface DataAttrNode {\n id?: string;\n tagName: string;\n attributes: Attribute[];\n dataAttributes: Attribute[];\n textContent: string;\n rawChildren?: string;\n // Exact structural child source, used to validate source-preserving edits.\n source?: string;\n loc?: {\n start: { line: number; column: number };\n end: { line: number; column: number };\n };\n children?: DataAttrNode[];\n isFragment?: boolean;\n bindings?: BindingItem[];\n}\n\nexport interface BindingOption {\n label: string;\n value: string;\n}\n\n// Data kinds only — what a value *is*, never how to draw it. How a field is\n// rendered belongs to `BindingItem.widget`, which the library passes through\n// without interpreting: choosing a control is the consumer's job, so the\n// built-in panel only ever renders the default control for each kind.\nexport const BINDING_TYPES = [\n 'array',\n 'object',\n 'string',\n 'number',\n 'boolean',\n 'color',\n 'jsx',\n 'richtext',\n 'date',\n 'url',\n] as const;\n\nexport type BindingType = (typeof BINDING_TYPES)[number];\n\n// Presentation config for one field, as opposed to `BindingItem.type`'s data\n// kind. Authored either as the bare control name (`widget: 'slider'`) or as\n// this object; `parseBinding` normalizes the string form into `{ type }`, so\n// consumers only ever see one shape.\n//\n// Value *constraints* deliberately stay on the item, not here: `min`/`max`/\n// `pattern`/`required` are enforced by `validateBindingValue` whether or not\n// a widget was declared, so a plain number input still range-checks. Putting\n// them here too would make the range unexpressible without a widget, and\n// give a slider a second, conflicting source for the same bounds.\nexport interface BindingWidget {\n // The control name. Open string, not an enum: the library implements no\n // controls of its own, so every value (e.g. `'slider'`) is a custom\n // panel's to switch on. The built-in panel ignores it.\n type: string;\n // Presentation hints general enough to be worth typing. Both were already\n // authorable before this object existed — they just landed in the untyped\n // `meta` bag, where nothing checked their names or value types.\n step?: number;\n unit?: string;\n // Any further widget-specific config the consumer declared. Open for the\n // same reason `type` is: a custom control's options are not this library's\n // to enumerate. See #234 on keeping unknown keys rather than stripping.\n [key: string]: unknown;\n}\n\n// The fields a binding declares about itself, shared by a top-level\n// `BindingItem` and a nested render-map leaf so the two can't drift apart:\n// a leaf is a field in the panel like any other and can say everything a\n// flat field can. See #383.\nexport interface BindingFieldSpec {\n // Data kind — what the value *is*. Closed, since the library's own\n // validation/coercion (validateBindingValue, parseValue) has to be able\n // to switch on it exhaustively.\n type?: BindingType;\n // Presentation — how to *render* it, plus that control's own config. Always\n // the object form here even when authored as a bare string; see\n // BindingWidget.\n widget?: BindingWidget;\n options?: BindingOption[];\n render?: BindingRenderMap;\n min?: number;\n max?: number;\n pattern?: string;\n required?: boolean;\n // Consumer-defined keys that aren't one of the fields above — namespaced\n // here rather than spread onto the item itself so they can't collide with\n // a future first-class field. Per-widget config belongs in `widget`, not\n // here; this is for metadata about the field as a whole.\n // Undefined when nothing extra was authored, not an empty object. See\n // #234: `parseBinding` used to silently strip these.\n meta?: Record<string, unknown>;\n}\n\n// A render-map entry is a leaf when it declares `type` — even one that didn't\n// survive sanitization, so an unrecognized leaf type degrades to untyped\n// instead of dropping the entry (see sanitizeRenderMap in binding.ts and\n// #234). `label`/`property` are optional here, unlike on BindingItem: both\n// fall back to the entry's key.\nexport interface BindingRenderLeaf extends BindingFieldSpec {\n label?: string;\n property?: string;\n}\n\nexport interface BindingRenderMap {\n [key: string]: BindingRenderLeaf | BindingRenderMap;\n}\n\nexport interface BindingItem extends BindingFieldSpec {\n label: string;\n property: string;\n}\n\nexport type NodeValueType =\n 'boolean' | 'number' | 'string' | 'null' | 'array' | 'object' | 'unknown';\n\nexport type EditableNodeValueType = 'boolean' | 'number' | 'string' | 'null';\n\nexport interface ExtractedNodeValue {\n type: NodeValueType;\n value: string | number | boolean | null;\n}\n","import { parseExpression } from '@babel/parser';\nimport * as t from '@babel/types';\n\nimport { REGEX } from '../../constants';\nimport { generateCode } from './helpers';\nimport type { ExtractedNodeValue, NodeValueType } from './types';\n\nconst dedent = (str: string): string => {\n const lines = str\n .replace(/^\\n/, '')\n .replace(/\\n\\s*$/, '')\n .split('\\n');\n\n const indent = lines.reduce((min, line) => {\n if (!line.trim()) {\n return min;\n }\n const match = line.match(/^(\\s*)/);\n return Math.min(min, match?.[1]?.length ?? 0);\n }, Infinity);\n\n return indent === Infinity\n ? str.trim()\n : lines.map(line => line.slice(indent)).join('\\n');\n};\n\n// Peel type-only wrappers and parentheses off an expression so the literal\n// underneath can be read. Authored bindings may carry `satisfies BindingItem[]`\n// (or `as const`, a type assertion, ...) for editor type-safety; those are\n// erased at build time and mean nothing to this literal evaluator, so without\n// unwrapping them the value — or the whole binding array — would be silently\n// dropped as \"not a literal\".\nexport const unwrapExpression = (node: t.Node): t.Node => {\n let current = node;\n\n while (\n t.isTSAsExpression(current) ||\n t.isTSSatisfiesExpression(current) ||\n t.isTSNonNullExpression(current) ||\n t.isTSTypeAssertion(current) ||\n t.isParenthesizedExpression(current)\n ) {\n current = current.expression;\n }\n\n return current;\n};\n\n// Whether evaluateLiteral() and valueToExpression() can round-trip a value\n// without dropping calls, references, spreads, holes or computed properties.\n// Presentation uses this to disable partial editors and mutation reuses it as\n// the final guard, so both layers share one editable-syntax boundary.\nexport const isLosslesslyEvaluable = (node: t.Node): boolean => {\n const value = unwrapExpression(node);\n\n if (\n t.isStringLiteral(value) ||\n t.isNumericLiteral(value) ||\n t.isBooleanLiteral(value) ||\n t.isNullLiteral(value)\n ) {\n return true;\n }\n\n if (\n t.isUnaryExpression(value) &&\n value.operator === '-' &&\n t.isNumericLiteral(value.argument)\n ) {\n return true;\n }\n\n if (t.isTemplateLiteral(value)) {\n return value.expressions.length === 0;\n }\n\n if (t.isArrayExpression(value)) {\n return value.elements.every(\n element => element !== null && isLosslesslyEvaluable(element),\n );\n }\n\n if (t.isObjectExpression(value)) {\n return value.properties.every(\n property =>\n t.isObjectProperty(property) &&\n !property.computed &&\n (t.isIdentifier(property.key) ||\n t.isStringLiteral(property.key) ||\n t.isNumericLiteral(property.key)) &&\n isLosslesslyEvaluable(property.value),\n );\n }\n\n return false;\n};\n\nexport const canLosslesslyEvaluateSource = (source: string): boolean => {\n try {\n return isLosslesslyEvaluable(\n parseExpression(source, { plugins: ['jsx', 'typescript'] }),\n );\n } catch {\n return false;\n }\n};\n\n// AST 노드를 코드 실행(new Function/eval) 없이 순수 리터럴 구조만 재귀적으로\n// 실제 JS 값으로 변환한다. 함수 호출, 변수 참조 등 리터럴이 아닌 표현식은\n// 평가하지 않고 undefined를 반환한다 — 사용자 코드는 iframe 안에서만 실행한다는\n// 이 저장소의 원칙(AGENTS.md)을 이 패널 UI(메인 문서에서 렌더링됨)에서도 지키기 위함.\nexport const evaluateLiteral = (rawNode: t.Node): unknown => {\n const node = unwrapExpression(rawNode);\n\n if (t.isStringLiteral(node)) {\n return node.value;\n }\n\n if (t.isNumericLiteral(node)) {\n return node.value;\n }\n\n if (t.isBooleanLiteral(node)) {\n return node.value;\n }\n\n if (t.isNullLiteral(node)) {\n return null;\n }\n\n if (t.isIdentifier(node) && node.name === 'undefined') {\n return undefined;\n }\n\n if (\n t.isUnaryExpression(node) &&\n node.operator === '-' &&\n t.isNumericLiteral(node.argument)\n ) {\n return -node.argument.value;\n }\n\n if (t.isTemplateLiteral(node) && node.expressions.length === 0) {\n return node.quasis[0]?.value.cooked ?? node.quasis[0]?.value.raw ?? '';\n }\n\n if (t.isJSXElement(node) || t.isJSXFragment(node)) {\n return generateCode(node);\n }\n\n if (t.isArrayExpression(node)) {\n return node.elements.map(element =>\n element ? evaluateLiteral(element) : null,\n );\n }\n\n if (t.isObjectExpression(node)) {\n const result: Record<string, unknown> = {};\n\n for (const prop of node.properties) {\n if (!t.isObjectProperty(prop)) {\n continue;\n }\n\n let key: string | null = null;\n\n if (t.isIdentifier(prop.key)) {\n key = prop.key.name;\n } else if (t.isStringLiteral(prop.key)) {\n key = prop.key.value;\n } else if (t.isNumericLiteral(prop.key)) {\n key = String(prop.key.value);\n }\n\n if (key === null) {\n continue;\n }\n\n result[key] = evaluateLiteral(prop.value);\n }\n\n return result;\n }\n\n return undefined;\n};\n\nexport const parseValue = (value: unknown): unknown => {\n if (typeof value !== 'string') {\n return value;\n }\n\n const trimmed = value.trim();\n\n if (!trimmed) {\n return value;\n }\n\n if (REGEX.NUMBER.test(trimmed)) {\n return parseFloat(trimmed);\n }\n\n if (REGEX.BOOLEAN_OR_NULL.test(trimmed)) {\n if (trimmed === 'true') {\n return true;\n }\n if (trimmed === 'false') {\n return false;\n }\n if (trimmed === 'null') {\n return null;\n }\n if (trimmed === 'undefined') {\n return undefined;\n }\n }\n\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n try {\n const ast = parseExpression(trimmed, {\n plugins: ['jsx', 'typescript'],\n });\n\n if (t.isObjectExpression(ast) || t.isArrayExpression(ast)) {\n return evaluateLiteral(ast);\n }\n } catch {\n /* ignore */\n }\n\n return value;\n }\n\n return value;\n};\n\nexport type EditablePathSegment = string | number;\nexport type EditablePrimitive = string | number | boolean;\n\nexport interface EditableValueEntry {\n path: EditablePathSegment[];\n value: EditablePrimitive;\n}\n\nconst MAX_FLATTEN_DEPTH = 20;\n\nconst isEditablePrimitive = (value: unknown): value is EditablePrimitive =>\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean';\n\n// A binding's data-binding declaration is one way to know a value is\n// structured (`type: 'object'` + a `render` map — see #225), but most\n// existing content declares neither; it's just an object/array-shaped\n// string because that's what the bound prop actually is (e.g. `style`).\n// This recovers editable leaves from the *parsed value's own shape*\n// instead, so it works on content authored without a custom panel in mind\n// — including an array of objects whose own members embed further JSX\n// (Live Editor's shipped Stats/FAQ sections both look like this: an\n// `items` array of `{ key, children }`, where `children` is itself a\n// nested, separately data-bound element). A JSX-bearing string is never\n// parsed further here — `parseValue` already reduced it to plain text\n// (see `evaluateLiteral`'s JSXElement case), and this function only ever\n// recurses into genuine object/array structure, treating every string,\n// number, and boolean as a leaf regardless of what the string contains.\n// Depth is capped defensively (pathological/deeply-recursive input\n// shouldn't be able to blow the stack); anything past that depth is\n// treated as a leaf-less dead end and simply omitted, not thrown.\nexport const flattenEditableValue = (\n value: string,\n): EditableValueEntry[] | null => {\n const parsed = parseValue(value);\n\n if (\n typeof parsed !== 'object' ||\n parsed === null ||\n Object.keys(parsed).length === 0\n ) {\n return null;\n }\n\n const entries: EditableValueEntry[] = [];\n\n const walk = (node: unknown, path: EditablePathSegment[], depth: number) => {\n if (depth > MAX_FLATTEN_DEPTH) {\n return;\n }\n\n if (isEditablePrimitive(node)) {\n entries.push({ path, value: node });\n return;\n }\n\n if (Array.isArray(node)) {\n node.forEach((item, index) => walk(item, [...path, index], depth + 1));\n return;\n }\n\n if (typeof node === 'object' && node !== null) {\n Object.entries(node).forEach(([key, item]) =>\n walk(item, [...path, key], depth + 1),\n );\n }\n\n // null/undefined/function/symbol values have no editable leaf form —\n // silently omitted rather than represented as, say, an empty string,\n // which would misrepresent what's actually stored there.\n };\n\n walk(parsed, [], 0);\n\n return entries.length ? entries : null;\n};\n\n// Finds the node `flattenEditableValue` reported at `path`, walking the\n// same literal structure `evaluateLiteral` reads. Returns null for anything\n// it can't point at with certainty: a missing key or index, a step through\n// something that isn't an object or array, or a spread that could replace\n// the entry at runtime.\nconst findEditableLeaf = (\n root: t.Node,\n path: EditablePathSegment[],\n): t.Node | null => {\n let node = unwrapExpression(root);\n\n for (const segment of path) {\n if (t.isArrayExpression(node)) {\n if (typeof segment !== 'number') {\n return null;\n }\n\n const elements = node.elements.slice(0, segment + 1);\n const element = node.elements[segment];\n\n if (!element || elements.some(item => t.isSpreadElement(item))) {\n return null;\n }\n\n node = unwrapExpression(element);\n continue;\n }\n\n if (t.isObjectExpression(node)) {\n const key = String(segment);\n const matches = (property: t.ObjectExpression['properties'][number]) =>\n t.isObjectProperty(property) &&\n !property.computed &&\n ((t.isIdentifier(property.key) && property.key.name === key) ||\n (t.isStringLiteral(property.key) && property.key.value === key) ||\n (t.isNumericLiteral(property.key) &&\n String(property.key.value) === key));\n // The last match is the one a duplicate key leaves in effect, and the\n // one `evaluateLiteral` reports.\n let index = node.properties.length - 1;\n\n while (index >= 0 && !matches(node.properties[index]!)) {\n index--;\n }\n\n const property = node.properties[index];\n\n if (\n !property ||\n !t.isObjectProperty(property) ||\n node.properties.slice(index + 1).some(item => t.isSpreadElement(item))\n ) {\n return null;\n }\n\n node = unwrapExpression(property.value);\n continue;\n }\n\n return null;\n }\n\n return node;\n};\n\nconst isEditableLeaf = (node: t.Node): boolean =>\n t.isStringLiteral(node) ||\n t.isNumericLiteral(node) ||\n t.isBooleanLiteral(node) ||\n (t.isUnaryExpression(node) &&\n node.operator === '-' &&\n t.isNumericLiteral(node.argument)) ||\n (t.isTemplateLiteral(node) && node.expressions.length === 0) ||\n t.isJSXElement(node) ||\n t.isJSXFragment(node);\n\nconst quoteString = (text: string, quote: string): string => {\n if (quote === '`') {\n return `\\`${text.replace(/[\\\\`]|\\$\\{/g, match => `\\\\${match}`)}\\``;\n }\n\n const escaped = JSON.stringify(text).slice(1, -1);\n\n return quote === '\"'\n ? `\"${escaped}\"`\n : `'${escaped.replace(/\\\\\"/g, '\"').replace(/'/g, \"\\\\'\")}'`;\n};\n\nconst isJSXSource = (text: string): boolean => {\n try {\n const expression = parseExpression(text, { plugins: ['jsx'] });\n\n return t.isJSXElement(expression) || t.isJSXFragment(expression);\n } catch {\n return false;\n }\n};\n\n// Source text for `next` in place of `leaf`, keeping the leaf's own form\n// where it has one: a string keeps its quotes, and a JSX leaf, which\n// `flattenEditableValue` reports as its source text, stays JSX when the\n// edited text still is.\nconst leafSource = (\n value: string,\n leaf: t.Node,\n next: EditablePrimitive,\n): string => {\n if (typeof next !== 'string') {\n return String(next);\n }\n\n if ((t.isJSXElement(leaf) || t.isJSXFragment(leaf)) && isJSXSource(next)) {\n return next.trim();\n }\n\n const quote =\n t.isStringLiteral(leaf) || t.isTemplateLiteral(leaf)\n ? value[leaf.start!]!\n : \"'\";\n\n return quoteString(next, quote);\n};\n\n// Companion to `flattenEditableValue`: replaces the single leaf at `path`\n// and returns `value` with only that leaf's source text changed, so the\n// rest of the value keeps its formatting, comments, JSX, functions and\n// references. The result is a plain string for `PanelBinding.onChange`,\n// like any other committed value. It used to re-serialize the whole value\n// as JSON, which turned JSX into text and dropped functions and comments\n// on every edit (#427). Fails safe: a path `flattenEditableValue` wouldn't\n// report (a missing key, an out-of-range index, a step through something\n// that isn't an object or array, a non-literal leaf) or a `value` that\n// doesn't parse returns `value` unchanged rather than writing to the wrong\n// place. It never adds a key or grows an array.\nexport const setEditableValue = (\n value: string,\n path: EditablePathSegment[],\n next: EditablePrimitive,\n): string => {\n if (!path.length) {\n return value;\n }\n\n let leaf: t.Node | null;\n\n try {\n leaf = findEditableLeaf(\n parseExpression(value, { plugins: ['jsx', 'typescript'] }),\n path,\n );\n } catch {\n return value;\n }\n\n if (\n !leaf ||\n !isEditableLeaf(leaf) ||\n leaf.start == null ||\n leaf.end == null\n ) {\n return value;\n }\n\n return `${value.slice(0, leaf.start)}${leafSource(value, leaf, next)}${value.slice(leaf.end)}`;\n};\n\nexport const extractNodeValue = (node: t.Node): ExtractedNodeValue => {\n if (t.isBooleanLiteral(node)) {\n return { type: 'boolean', value: node.value };\n }\n\n if (t.isNumericLiteral(node)) {\n return { type: 'number', value: node.value };\n }\n\n if (\n t.isUnaryExpression(node) &&\n node.operator === '-' &&\n t.isNumericLiteral(node.argument)\n ) {\n return { type: 'number', value: -node.argument.value };\n }\n\n if (t.isStringLiteral(node)) {\n return { type: 'string', value: node.value };\n }\n\n if (t.isTemplateLiteral(node)) {\n if (node.expressions.length === 0 && node.quasis.length === 1) {\n return {\n type: 'string',\n value: dedent(\n node.quasis[0]!.value.cooked ?? node.quasis[0]!.value.raw,\n ),\n };\n }\n return { type: 'string', value: generateCode(node) };\n }\n\n if (t.isNullLiteral(node)) {\n return { type: 'null', value: null };\n }\n\n if (t.isArrayExpression(node)) {\n return { type: 'array', value: generateCode(node) };\n }\n\n if (t.isObjectExpression(node)) {\n return { type: 'object', value: generateCode(node) };\n }\n\n if (t.isJSXElement(node) || t.isJSXFragment(node)) {\n return { type: 'string', value: generateCode(node) };\n }\n\n return { type: 'unknown', value: null };\n};\n\nexport const createNodeFromValue = (\n type: NodeValueType,\n value: unknown,\n): t.Expression | null => {\n switch (type) {\n case 'boolean': {\n return t.booleanLiteral(value === true);\n }\n case 'number': {\n return t.numericLiteral(Number(value));\n }\n case 'string': {\n return t.stringLiteral(String(value));\n }\n case 'null': {\n return t.nullLiteral();\n }\n case 'array':\n case 'object':\n case 'unknown': {\n return null;\n }\n default: {\n return null;\n }\n }\n};\n\n// Faithfully rebuilds a JS value into an AST expression node — the inverse\n// of `evaluateLiteral`, and the single serialization point #238 moves the\n// panel's value contract onto. Because the caller already knows what the\n// value *is* (a real number/boolean/object/array, not a string that has to\n// be re-guessed), there is no string-vs-expression heuristic here: each JS\n// type maps to exactly one literal kind. Values with no literal form\n// (`undefined`, functions, symbols) are dropped — an object property whose\n// value is `undefined` is omitted rather than emitted as `undefined`,\n// mirroring `flattenEditableValue`, which also treats them as absent.\nexport const valueToExpression = (value: unknown): t.Expression | null => {\n if (typeof value === 'string') {\n return t.stringLiteral(value);\n }\n\n if (typeof value === 'number') {\n return value < 0\n ? t.unaryExpression('-', t.numericLiteral(-value))\n : t.numericLiteral(value);\n }\n\n if (typeof value === 'boolean') {\n return t.booleanLiteral(value);\n }\n\n if (value === null) {\n return t.nullLiteral();\n }\n\n if (Array.isArray(value)) {\n return t.arrayExpression(\n value.map(item => valueToExpression(item) ?? t.nullLiteral()),\n );\n }\n\n if (typeof value === 'object') {\n const properties: t.ObjectProperty[] = [];\n\n for (const [key, item] of Object.entries(value)) {\n const expr = valueToExpression(item);\n if (expr === null) {\n continue;\n }\n properties.push(t.objectProperty(t.stringLiteral(key), expr));\n }\n\n return t.objectExpression(properties);\n }\n\n return null;\n};\n\nexport const parseArrayExpression = (value: string) => {\n try {\n const ast = unwrapExpression(\n parseExpression(value, {\n plugins: ['jsx', 'typescript'],\n }),\n );\n\n if (!t.isArrayExpression(ast)) {\n return null;\n }\n\n return ast;\n } catch (error) {\n console.error('❌ Array parsing error:', error);\n return null;\n }\n};\n\nexport const extractObjectProperties = (\n element: t.ObjectExpression,\n): Record<string, ExtractedNodeValue & { astNode: t.Node }> => {\n const properties: Record<string, ExtractedNodeValue & { astNode: t.Node }> =\n {};\n\n element.properties.forEach(prop => {\n if (t.isObjectProperty(prop) && t.isIdentifier(prop.key)) {\n const key = prop.key.name;\n\n // `children` and any other JSX-valued property (e.g. `label`) are\n // handled separately, via `items.tsx`'s `jsxBindings`/fallback\n // extraction, which parses the JSX subtree properly instead of\n // stringifying it into a raw-source textarea. See #298.\n if (\n key === 'children' ||\n t.isJSXElement(prop.value) ||\n t.isJSXFragment(prop.value)\n ) {\n return;\n }\n\n const extracted = extractNodeValue(prop.value);\n\n properties[key] = {\n ...extracted,\n astNode: prop.value,\n };\n }\n });\n\n return properties;\n};\n\nexport const arrayExpressionToCode = (\n elements: t.ObjectExpression[],\n): string => {\n const nextAst = t.arrayExpression(elements);\n return generateCode(nextAst);\n};\n","import { parseExpression } from '@babel/parser';\nimport * as t from '@babel/types';\nimport { z } from 'zod';\n\nimport { BINDING_PROP, DATA_ATTR } from '../../constants';\nimport {\n BINDING_TYPES,\n type BindingItem,\n type BindingOption,\n type BindingRenderLeaf,\n type BindingRenderMap,\n type BindingType,\n type BindingWidget,\n type DataAttrNode,\n} from './types';\nimport { evaluateLiteral, parseArrayExpression, parseValue } from './value';\n\nconst bindingTypeSchema = z.enum(BINDING_TYPES);\n\nconst bindingOptionSchema = z.object({\n label: z.string(),\n value: z.string(),\n});\n\n// `widget.type` is deliberately just `z.string()`, not an enum — see #236. The\n// library implements no widgets, so every value is a custom panel author's\n// own. `.passthrough()` keeps that panel's own control config\n// (`{ type: 'slider', snapTo: [...] }`) instead of stripping it.\nconst bindingWidgetSchema = z\n .object({\n type: z.string().min(1),\n step: z.number().optional(),\n unit: z.string().optional(),\n })\n .passthrough();\n\n// Parse one field on its own, degrading a malformed value to absent instead\n// of failing the whole binding — a typo'd `min` or an unrecognized `type`\n// costs that one axis, not the field. See #234.\nconst pick = <T>(schema: z.ZodType<T>, value: unknown): T | undefined => {\n const parsed = schema.safeParse(value);\n\n return parsed.success ? parsed.data : undefined;\n};\n\n// The bare-string form (`widget: 'slider'`) means the control with no extra\n// config; normalizing it to `{ type }` leaves consumers one shape to switch on.\nconst sanitizeWidget = (value: unknown): BindingWidget | undefined => {\n if (typeof value === 'string') {\n return value ? { type: value } : undefined;\n }\n\n return pick(bindingWidgetSchema, value);\n};\n\n// Drop individually malformed options instead of rejecting them all — a\n// select field with 3 valid options and 1 malformed one should still work\n// with the 3 valid ones.\nconst sanitizeOptions = (value: unknown): BindingOption[] | undefined => {\n if (!Array.isArray(value)) {\n return undefined;\n }\n\n const options = value.flatMap(option => {\n const parsed = pick(bindingOptionSchema, option);\n\n return parsed ? [parsed] : [];\n });\n\n return options.length > 0 ? options : undefined;\n};\n\n// Every key this library reads off a binding — anything else authored on it\n// is consumer-defined and belongs in `meta`, not treated as one of this\n// library's own fields.\nconst KNOWN_BINDING_KEYS = new Set([\n 'label',\n 'property',\n 'type',\n 'widget',\n 'options',\n 'render',\n 'min',\n 'max',\n 'pattern',\n 'required',\n]);\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n};\n\n// The one sanitizer for what a binding declares about itself, shared by a\n// top-level item and a render-map leaf so a field added later reaches both.\n// Absent fields are left off rather than set to `undefined`.\nconst sanitizeField = (raw: Record<string, unknown>): BindingRenderLeaf => {\n const metaEntries = Object.entries(raw).filter(\n ([key]) => !KNOWN_BINDING_KEYS.has(key),\n );\n const field: BindingRenderLeaf = {\n label: pick(z.string(), raw.label),\n property: pick(z.string(), raw.property),\n type: pick(bindingTypeSchema, raw.type),\n widget: sanitizeWidget(raw.widget),\n options: sanitizeOptions(raw.options),\n render: sanitizeRenderMap(raw.render),\n min: pick(z.number(), raw.min),\n max: pick(z.number(), raw.max),\n pattern: pick(z.string(), raw.pattern),\n required: pick(z.boolean(), raw.required),\n meta: metaEntries.length > 0 ? Object.fromEntries(metaEntries) : undefined,\n };\n\n return Object.fromEntries(\n Object.entries(field).filter(([, value]) => value !== undefined),\n );\n};\n\n// A render map entry is either a \"leaf\" (has its own `type`) or a nested\n// map of further entries — recurse into whichever it looks like, and drop\n// anything that matches neither instead of failing the whole map.\nfunction sanitizeRenderMap(value: unknown): BindingRenderMap | undefined {\n if (!isPlainObject(value)) {\n return undefined;\n }\n\n const map: BindingRenderMap = {};\n\n for (const [key, raw] of Object.entries(value)) {\n if (!isPlainObject(raw)) {\n continue;\n }\n\n if ('type' in raw) {\n // `type` is always set, even to `undefined` when it didn't survive\n // sanitization, so `'type' in leaf` keeps identifying it as a leaf: a\n // typo'd/future leaf type still shows up as a plain field instead of\n // vanishing (#234).\n map[key] = { type: undefined, ...sanitizeField(raw) };\n continue;\n }\n\n const nested = sanitizeRenderMap(raw);\n\n if (nested) {\n map[key] = nested;\n }\n }\n\n return Object.keys(map).length > 0 ? map : undefined;\n}\n\n// Shared tail of `parseBinding`/`parseBindingExpression`: turn the raw,\n// already-evaluated array literal into validated `BindingItem[]`. The two\n// callers differ only in how they reach this array — from a source string\n// (public API) or straight off an expression AST (extract's hot path).\nconst buildBindingItems = (raw: unknown): BindingItem[] => {\n if (!Array.isArray(raw)) {\n return [];\n }\n\n return raw.flatMap(rawItem => {\n if (!isPlainObject(rawItem)) {\n return [];\n }\n\n const { label, property, ...field } = sanitizeField(rawItem);\n\n if (label === undefined) {\n return [];\n }\n\n if (property === undefined && field.type !== 'richtext') {\n return [];\n }\n\n return [{ label, property: property ?? BINDING_PROP.INNER_HTML, ...field }];\n });\n};\n\nexport const parseBinding = (bindingValue: string | null): BindingItem[] => {\n if (!bindingValue) {\n return [];\n }\n\n const ast = parseArrayExpression(bindingValue);\n\n if (!ast) {\n return [];\n }\n\n return buildBindingItems(evaluateLiteral(ast));\n};\n\n// Same result as `parseBinding`, but fed the array-literal expression the\n// parser already produced instead of a source string. `extract` authors\n// `data-binding` as a real JSX object-array expression, so re-serializing it\n// to a string only to `parseExpression` it straight back was a wasted Babel\n// round-trip (#241's \"two parsers\"); evaluate that AST in place.\nexport const parseBindingExpression = (\n expression: t.ArrayExpression,\n): BindingItem[] => buildBindingItems(evaluateLiteral(expression));\n\nexport const getCurrentValue = (\n node: DataAttrNode,\n property: string,\n): string => {\n switch (property) {\n case BINDING_PROP.INNER_TEXT: {\n return node.textContent || '';\n }\n\n case BINDING_PROP.INNER_HTML: {\n // richtext 타입: dangerouslySetInnerHTML={{ __html }} 에서 읽기\n const dsiAttr = node.attributes.find(\n a => a.name === 'dangerouslySetInnerHTML',\n );\n if (dsiAttr?.value) {\n try {\n const expr = parseExpression(dsiAttr.value, {\n plugins: ['jsx', 'typescript'],\n });\n if (t.isObjectExpression(expr)) {\n const htmlProp = expr.properties.find(\n p =>\n t.isObjectProperty(p) &&\n t.isIdentifier(p.key) &&\n p.key.name === '__html',\n ) as t.ObjectProperty | undefined;\n if (htmlProp) {\n if (t.isStringLiteral(htmlProp.value)) {\n return htmlProp.value.value;\n }\n if (\n t.isTemplateLiteral(htmlProp.value) &&\n htmlProp.value.expressions.length === 0\n ) {\n return (\n htmlProp.value.quasis[0]?.value.cooked ??\n htmlProp.value.quasis[0]?.value.raw ??\n ''\n );\n }\n }\n }\n } catch {\n // ignore\n }\n }\n return node.rawChildren || node.textContent || '';\n }\n\n case BINDING_PROP.CHILDREN: {\n return JSON.stringify(node?.children || []);\n }\n\n default: {\n const customAttr = node.attributes.find(attr => attr.name === property);\n const value = customAttr?.value || '';\n\n return value;\n }\n }\n};\n\n// Declared types whose value is genuinely text — never re-parsed into a\n// number/object/array even when the text happens to look like one. `jsx`\n// and `richtext` carry source that is an expression, not a literal, so they\n// stay as their exact source string too (the update pipeline re-inserts\n// them as expressions, not string literals).\nexport const STRING_VALUED_TYPES: ReadonlySet<BindingType> = new Set([\n 'string',\n 'url',\n 'date',\n 'color',\n 'jsx',\n 'richtext',\n]);\n\n// Structured counterpart to `getCurrentValue`: returns the value as its real\n// JS type (number/boolean/object/array/string) rather than always as a\n// string, so both the built-in panel and a custom panel receive\n// `PanelBinding.value` already typed. `getCurrentValue` still supplies the\n// exact source text (`PanelBinding.rawValue`). See #238.\n//\n// The string-vs-structure decision is made *here*, from information the AST\n// still has — an attribute that was a string literal in source is a genuine\n// string whatever its contents, so `\"{not an expression}\"` stays a string\n// instead of being re-parsed into an object. Only genuine expressions\n// (`count={3}`, `data={[...]}`) are recovered into their real shape.\nexport const getStructuredValue = (\n node: DataAttrNode,\n property: string,\n type?: BindingType,\n): unknown => {\n switch (property) {\n case BINDING_PROP.INNER_TEXT:\n case BINDING_PROP.INNER_HTML: {\n return getCurrentValue(node, property);\n }\n\n case BINDING_PROP.CHILDREN: {\n return node.children ?? [];\n }\n\n default: {\n const raw = getCurrentValue(node, property);\n const attr = node.attributes.find(a => a.name === property);\n\n if (attr?.isStringLiteral || (type && STRING_VALUED_TYPES.has(type))) {\n return raw;\n }\n\n return parseValue(raw);\n }\n }\n};\n\nconst hasEditableBindings = (node: DataAttrNode): boolean => {\n const bindingAttr = node.dataAttributes.find(\n attr => attr.name === DATA_ATTR.BINDING,\n );\n\n if (!bindingAttr?.value) {\n return false;\n }\n\n const bindings = node.bindings || parseBinding(bindingAttr.value);\n\n return bindings.length > 0;\n};\n\nexport const findEditableChildren = (node: DataAttrNode): DataAttrNode[] => {\n const editableChildren: DataAttrNode[] = [];\n\n const traverse = (children: DataAttrNode[] | undefined) => {\n if (!children) {\n return;\n }\n\n for (const child of children) {\n if (hasEditableBindings(child)) {\n editableChildren.push(child);\n }\n traverse(child.children);\n }\n };\n\n traverse(node.children);\n\n return editableChildren;\n};\n","export const removeIndices = <T>(items: T[], indices: Set<number>): T[] => {\n return items.filter((_, index) => !indices.has(index));\n};\n\n/**\n * Shifts every selected index up/down by one step as a block, preserving\n * relative order — scattered selections stop moving individually once they\n * hit an unselected neighbor, so the whole group slides together instead of\n * items passing through each other.\n */\nexport const moveSelectedIndices = <T>(\n items: T[],\n indices: Set<number>,\n direction: 'up' | 'down',\n): { items: T[]; indices: Set<number> } => {\n const next = [...items];\n const nextIndices = new Set(indices);\n\n const ordered = [...indices].sort((a, b) =>\n direction === 'up' ? a - b : b - a,\n );\n\n for (const index of ordered) {\n const target = direction === 'up' ? index - 1 : index + 1;\n\n if (target < 0 || target >= next.length || nextIndices.has(target)) {\n continue;\n }\n\n [next[index], next[target]] = [next[target]!, next[index]!];\n nextIndices.delete(index);\n nextIndices.add(target);\n }\n\n return { items: next, indices: nextIndices };\n};\n","// Positional source patching: the write-side counterpart to `extract`'s\n// read-side `loc`. `update` records the exact byte spans it wants to change\n// and everything else is copied through verbatim, so an edit can no longer\n// reformat code it didn't touch. See #239.\n//\n// Deliberately not `magic-string`: it is the usual tool for this, but it is\n// only available here transitively (via Vite) and would have to become a\n// real runtime dependency shipped to consumers' browsers. Its value is\n// source maps and interleaved insert/move semantics — neither of which this\n// needs. Edits here are non-overlapping span replacements applied in one\n// forward pass, which is the whole implementation below.\nexport interface SourceEdit {\n start: number;\n end: number;\n content: string;\n // Re-indent `content`'s continuation lines to the indentation of the line\n // it lands on. Opt-in because it must apply to *generated* fragments only:\n // a generated fragment is printed from column zero and would otherwise\n // land ragged inside indented markup, whereas a raw user-authored value\n // (an innerHTML string, a hand-written JSX attribute) has to go in byte\n // for byte — re-indenting it would silently rewrite the value itself.\n //\n // Even within a generated fragment this is applied only when every\n // newline is provably layout; see `hasOnlyLayoutNewlines`.\n indent?: boolean;\n}\n\n// Whether every newline in generated code is layout rather than part of a\n// value. Babel escapes newlines inside ordinary string literals, so the only\n// newlines that carry meaning come from a template literal or from JSX text\n// — and both announce themselves with a backtick or a `<`.\n//\n// This matters because indenting a value-newline silently rewrites the\n// value, and the damage compounds: the built-in array editor re-serializes\n// its own output and feeds it back through `update`, so an `innerHTML` leaf\n// stored as a template literal would gain a level of indentation on every\n// single edit.\n//\n// The scan is deliberately conservative. Quotes, comments and regex\n// literals can all hide a backtick, and telling a regex from a division\n// needs real parsing — so anything ambiguous returns false. A false\n// \"unsafe\" only costs a fragment that isn't re-indented; a false \"safe\"\n// corrupts the value.\nconst hasOnlyLayoutNewlines = (content: string): boolean => {\n let index = 0;\n\n while (index < content.length) {\n const char = content[index];\n\n // `<` also matches comparison operators and TS generics. Refusing those\n // is harmless.\n if (char === '`' || char === '<') {\n return false;\n }\n\n if (char === '\"' || char === \"'\") {\n const next = skipStringLiteral(content, index);\n\n if (next === -1) {\n return false;\n }\n\n index = next;\n continue;\n }\n\n if (char === '/') {\n const following = content[index + 1];\n\n if (following === '/') {\n const lineEnd = content.indexOf('\\n', index + 2);\n index = lineEnd === -1 ? content.length : lineEnd;\n continue;\n }\n\n if (following === '*') {\n const commentEnd = content.indexOf('*/', index + 2);\n\n if (commentEnd === -1) {\n return false;\n }\n\n index = commentEnd + 2;\n continue;\n }\n\n // Division or a regex literal — indistinguishable without parsing.\n return false;\n }\n\n index++;\n }\n\n return true;\n};\n\n// Index just past the closing quote, or -1 if the literal doesn't terminate\n// before the end of its line. Valid generated JS never contains a bare\n// newline inside a string literal, so hitting one means the scan has lost\n// track of where it is and the caller should stop trusting it.\nconst skipStringLiteral = (content: string, start: number): number => {\n const quote = content[start];\n\n for (let index = start + 1; index < content.length; index++) {\n const char = content[index];\n\n if (char === '\\\\') {\n // A backslash immediately before a newline is a line continuation:\n // legal JS, and Babel re-emits it verbatim because it contributes\n // nothing to the value. The newline is then part of the literal's raw\n // text, so indenting it would rewrite the string — bail out instead\n // of treating the continuation as an ordinary escape.\n const escaped = content[index + 1];\n\n if (escaped === '\\n' || escaped === '\\r') {\n return -1;\n }\n\n index++;\n continue;\n }\n\n if (char === quote) {\n return index + 1;\n }\n\n if (char === '\\n') {\n return -1;\n }\n }\n\n return -1;\n};\n\n// Indentation of the line that `offset` falls on.\nconst lineIndentAt = (source: string, offset: number): string => {\n const lineStart = source.lastIndexOf('\\n', offset - 1) + 1;\n const match = /^[ \\t]*/.exec(source.slice(lineStart, offset));\n\n return match?.[0] ?? '';\n};\n\n// Babel always emits LF. Inserting that straight into a CRLF file leaves it\n// with mixed endings, so a generated fragment adopts whichever the file\n// already uses. Only ever applied alongside re-indentation, where the\n// newlines are known to be layout rather than part of a value.\nconst lineTerminatorOf = (source: string): string => {\n return source.includes('\\r\\n') ? '\\r\\n' : '\\n';\n};\n\n// Applies non-overlapping edits to `source` in a single forward pass.\n// An edit with `start === end` is an insertion at that offset.\n//\n// Throws on overlapping or out-of-bounds edits rather than silently\n// producing corrupt output: callers build spans from parsed node offsets,\n// so an overlap means the caller's model of the tree is wrong, and a\n// half-applied patch would be far harder to diagnose than a failure.\nexport const applyEdits = (source: string, edits: SourceEdit[]): string => {\n if (edits.length === 0) {\n return source;\n }\n\n const ordered = [...edits].sort((a, b) => a.start - b.start || a.end - b.end);\n\n for (const edit of ordered) {\n if (\n !Number.isInteger(edit.start) ||\n !Number.isInteger(edit.end) ||\n edit.start < 0 ||\n edit.end > source.length ||\n edit.start > edit.end\n ) {\n throw new Error(\n `Invalid source edit [${edit.start}, ${edit.end}) for a source of length ${source.length}`,\n );\n }\n }\n\n for (let i = 1; i < ordered.length; i++) {\n const previous = ordered[i - 1]!;\n const current = ordered[i]!;\n\n if (current.start < previous.end) {\n throw new Error(\n `Overlapping source edits: [${previous.start}, ${previous.end}) and [${current.start}, ${current.end})`,\n );\n }\n }\n\n let result = '';\n let cursor = 0;\n const terminator = lineTerminatorOf(source);\n\n for (const edit of ordered) {\n const content =\n edit.indent &&\n edit.content.includes('\\n') &&\n hasOnlyLayoutNewlines(edit.content)\n ? edit.content.replace(\n /\\n/g,\n `${terminator}${lineIndentAt(source, edit.start)}`,\n )\n : edit.content;\n\n result += source.slice(cursor, edit.start) + content;\n cursor = edit.end;\n }\n\n return result + source.slice(cursor);\n};\n","import * as t from '@babel/types';\n\nimport { type SourceEdit, applyEdits } from './patch';\nimport { parseArrayExpression } from './value';\n\n// Gaps between dense elements contain only whitespace, comments and one\n// comma. Scan those gaps, never the expressions (which can contain JSX,\n// regexes, templates and nested commas).\nconst commaIn = (source: string, start: number, end: number): number | null => {\n let comma: number | null = null;\n\n for (let at = start; at < end; at++) {\n if (/\\s/.test(source[at]!)) {\n continue;\n }\n\n if (source.startsWith('/*', at)) {\n const close = source.indexOf('*/', at + 2);\n\n if (close < 0 || close + 2 > end) {\n return null;\n }\n\n at = close + 1;\n } else if (source.startsWith('//', at)) {\n const newline = source.indexOf('\\n', at + 2);\n at = newline < 0 ? end : newline;\n } else if (source[at] === ',' && comma === null) {\n comma = at;\n } else {\n return null;\n }\n }\n\n return comma;\n};\n\nexport const denseArraySource = (source: string) => {\n const array = parseArrayExpression(source);\n\n // Holes/spreads have source positions but no stable visible item count.\n // Value edits can preserve them; structural edits deliberately refuse.\n if (\n !array ||\n array.elements.some(\n node => !t.isExpression(node) || node.extra?.parenthesized,\n )\n ) {\n return null;\n }\n\n const elements = array.elements as t.Expression[];\n const commas = elements\n .slice(0, -1)\n .map((node, index) =>\n commaIn(source, node.end!, elements[index + 1]!.start!),\n );\n\n if (commas.some(comma => comma === null)) {\n return null;\n }\n\n const last = elements.at(-1);\n const trailing = last ? commaIn(source, last.end!, array.end! - 1) : null;\n\n return { array, elements, commas: commas as number[], trailing };\n};\n\n// Keep presentation and mutation on the same syntax boundary. Consumers can\n// use this before offering structural controls, while every write still calls\n// denseArraySource() again so stale source is refused at commit time.\nexport const canStructurallyEditArray = (source: string) =>\n denseArraySource(source) !== null;\n\nexport const validArrayIndices = (indices: Iterable<number>, length: number) =>\n [...indices].every(\n index => Number.isInteger(index) && index >= 0 && index < length,\n );\n\nexport const reorderArraySource = (\n source: string,\n elements: t.Expression[],\n next: t.Expression[],\n): string =>\n applyEdits(\n source,\n elements.map((node, index) => ({\n start: node.start!,\n end: node.end!,\n content: source.slice(next[index]!.start!, next[index]!.end!),\n })),\n );\n\nexport const removeArraySource = (\n source: string,\n data: NonNullable<ReturnType<typeof denseArraySource>>,\n indices: Set<number>,\n): string => {\n const edits: SourceEdit[] = [];\n const removedCommas = new Set<number>();\n const { elements, commas, trailing } = data;\n\n // Each consecutive removed run consumes its following commas. A run\n // ending at the last element consumes the preceding separator instead;\n // a trailing comma, when present, stays a trailing comma.\n for (let index = 0; index < elements.length; index++) {\n if (!indices.has(index)) {\n continue;\n }\n\n const start = index;\n\n while (index + 1 < elements.length && indices.has(index + 1)) {\n index++;\n }\n\n for (let current = start; current <= index; current++) {\n const node = elements[current]!;\n edits.push({ start: node.start!, end: node.end!, content: '' });\n\n if (current < elements.length - 1) {\n removedCommas.add(commas[current]!);\n }\n }\n\n if (index === elements.length - 1) {\n if (trailing !== null) {\n removedCommas.add(trailing);\n } else if (start > 0) {\n removedCommas.add(commas[start - 1]!);\n }\n }\n }\n\n for (const comma of removedCommas) {\n edits.push({ start: comma, end: comma + 1, content: '' });\n }\n\n return applyEdits(source, edits);\n};\n\nexport const appendArraySource = (\n source: string,\n data: NonNullable<ReturnType<typeof denseArraySource>>,\n copies: string[],\n): string => {\n const last = data.elements.at(-1);\n\n if (!last || copies.length === 0) {\n return source;\n }\n\n // Insert before the old trailing gap so line comments cannot swallow a\n // new item, and keep an existing trailing comma in its original role.\n return applyEdits(source, [\n {\n start: last.end!,\n end: last.end!,\n content: `, ${copies.join(', ')}`,\n },\n ]);\n};\n","import { parseExpression } from '@babel/parser';\nimport * as t from '@babel/types';\nimport { nanoid } from 'nanoid';\n\nimport { BINDING_PROP } from '../../constants';\nimport { moveSelectedIndices, removeIndices } from '../selection';\nimport {\n appendArraySource,\n denseArraySource,\n removeArraySource,\n reorderArraySource,\n validArrayIndices,\n} from './array-source';\nimport { generateCode } from './helpers';\nimport { type SourceEdit, applyEdits } from './patch';\nimport type {\n BindingRenderLeaf,\n BindingRenderMap,\n NodeValueType,\n} from './types';\nimport {\n createNodeFromValue,\n extractNodeValue,\n extractObjectProperties,\n isLosslesslyEvaluable,\n parseArrayExpression,\n parseValue,\n valueToExpression,\n} from './value';\n\n// Array edits are source patches. Parsing locates the requested value or\n// element; unrelated expressions, comments and formatting are not printed\n// again. Structural edits require dense arrays; value edits preserve holes\n// and spreads at their existing source positions. `null` means refusal.\n\nexport type ItemKind = 'object' | 'primitive';\n\nexport interface ArrayItem {\n // Position in the array's elements, which is what every function here\n // indexes by. Items of one kind are not renumbered, so a mixed array\n // stays addressable.\n index: number;\n kind: ItemKind;\n node: t.Expression;\n}\n\nconst elementsOf = (code: string) =>\n parseArrayExpression(code)?.elements ?? null;\n\nconst kindOf = (element: t.Expression): ItemKind =>\n t.isObjectExpression(element) ? 'object' : 'primitive';\n\n// Omit holes and spreads from the visible list without renumbering source\n// positions. A spread is not one runtime value that the panel can edit.\nexport const parseItems = (code: string): ArrayItem[] | null => {\n const elements = elementsOf(code);\n\n return (\n elements?.flatMap((node, index) =>\n t.isExpression(node) ? [{ index, kind: kindOf(node), node }] : [],\n ) ?? null\n );\n};\n\nconst resolveRenderLeaf = (\n render: BindingRenderMap | undefined,\n key: string,\n): BindingRenderLeaf | null => {\n const leaf = render?.[key];\n\n return leaf && 'type' in leaf ? (leaf as BindingRenderLeaf) : null;\n};\n\n// Escapes text for a template literal's raw slot. `@babel/types` rejects a\n// raw containing an unescaped backtick or `${`, a lone backslash would\n// otherwise be read back as an escape sequence, and a carriage return is\n// normalized to a newline by the spec's raw-value rules — so raw markup\n// pasted into an innerHTML field used to throw straight out of the edit\n// handler, and CRLF would not survive a round trip.\nconst toTemplateRaw = (value: string): string => {\n return value\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/`/g, '\\\\`')\n .replace(/\\$\\{/g, '\\\\${')\n .replace(/\\r/g, '\\\\r');\n};\n\n// Builds the node a property should hold, from the value the panel produced.\n// Returns `undefined` when the value can't be represented, which callers\n// treat as \"leave the source alone\".\nconst buildPropertyValue = (\n value: unknown,\n declaredType: NodeValueType,\n renderLeaf: BindingRenderLeaf | null,\n current: t.Expression,\n): t.Expression | undefined => {\n // innerHTML carries raw markup, which has to survive as written — a\n // template literal keeps it verbatim without escaping.\n if (renderLeaf?.property === BINDING_PROP.INNER_HTML) {\n const raw = String(value);\n\n return t.templateLiteral(\n [t.templateElement({ raw: toTemplateRaw(raw), cooked: raw }, true)],\n [],\n );\n }\n\n // A declared `render[key].type === 'jsx'` covers a schema-declared JSX\n // property; a property whose *current* value is already JSX (e.g. the\n // items panel's fallback editor for a JSX-valued property with no\n // extractable bindings, see #298) needs the same treatment even without\n // that declaration, so it round-trips as JSX rather than as a string.\n if (\n renderLeaf?.type === 'jsx' ||\n t.isJSXElement(current) ||\n t.isJSXFragment(current)\n ) {\n const trimmed = String(value).trim();\n\n // Anything that isn't markup is a plain string for this property.\n if (!trimmed.startsWith('<')) {\n return t.stringLiteral(trimmed);\n }\n\n try {\n return parseExpression(trimmed, { plugins: ['jsx', 'typescript'] });\n } catch {\n return undefined;\n }\n }\n\n if (declaredType === 'array' || declaredType === 'object') {\n // The nested Items editor commits serialized source text, while the\n // object editor and the fallback TextArea commit a real JS value.\n // Parsing the former directly avoids evaluating it and `String()`-ing\n // it back to `1,2` (a sequence expression).\n if (typeof value === 'string') {\n try {\n return parseExpression(value, { plugins: ['jsx', 'typescript'] });\n } catch {\n return undefined;\n }\n }\n\n // The latter has already been through `evaluateLiteral`, so it can only\n // be rebuilt faithfully when the property held nothing but literals to\n // begin with. Otherwise the edit is refused and the source is left\n // alone, which is the safe half of what this path used to do.\n if (!isLosslesslyEvaluable(current)) {\n return undefined;\n }\n\n return valueToExpression(value) ?? undefined;\n }\n\n // Scalars arrive as the text typed into the field, so coerce before\n // building the literal — `createNodeFromValue('boolean', 'true')` would\n // otherwise compare the string against `true` and yield `false`.\n return createNodeFromValue(declaredType, parseValue(value)) ?? undefined;\n};\n\nexport const updateArrayItemProperty = (\n code: string,\n index: number,\n key: string,\n value: unknown,\n render?: BindingRenderMap,\n): string | null => {\n const elements = elementsOf(code);\n const element = elements?.[index];\n\n if (!elements || !t.isObjectExpression(element)) {\n return null;\n }\n\n const target = element.properties.find(\n (property): property is t.ObjectProperty =>\n t.isObjectProperty(property) &&\n t.isIdentifier(property.key) &&\n property.key.name === key,\n );\n\n if (!target) {\n return null;\n }\n\n const declaredType = extractObjectProperties(element)[key]?.type ?? 'string';\n const nextValue = buildPropertyValue(\n value,\n declaredType,\n resolveRenderLeaf(render, key),\n target.value as t.Expression,\n );\n\n if (!nextValue) {\n return null;\n }\n\n let serialized =\n typeof value === 'string' &&\n (declaredType === 'array' ||\n declaredType === 'object' ||\n t.isJSXElement(nextValue) ||\n t.isJSXFragment(nextValue))\n ? value.trim()\n : generateCode(nextValue);\n\n if (\n nextValue.trailingComments?.some(comment => comment.type === 'CommentLine')\n ) {\n serialized += '\\n';\n }\n\n // A shorthand property shares the key/value span: expand it explicitly.\n const content = target.shorthand ? `${key}: ${serialized}` : serialized;\n\n return applyEdits(code, [\n { start: target.value.start!, end: target.value.end!, content },\n ]);\n};\n\nexport const updateArrayItemValue = (\n code: string,\n index: number,\n value: unknown,\n): string | null => {\n const elements = elementsOf(code);\n const element = elements?.[index];\n\n if (!elements || !t.isExpression(element)) {\n return null;\n }\n\n const nextValue = createNodeFromValue(\n extractNodeValue(element).type,\n parseValue(value),\n );\n\n if (!nextValue) {\n return null;\n }\n\n return applyEdits(code, [\n {\n start: element.start!,\n end: element.end!,\n content: generateCode(nextValue),\n },\n ]);\n};\n\nexport const moveArrayItem = (\n code: string,\n from: number,\n to: number,\n): string | null => {\n const data = denseArraySource(code);\n\n if (\n !data ||\n !validArrayIndices([from], data.elements.length) ||\n !Number.isInteger(to)\n ) {\n return null;\n }\n\n // Preserve the existing splice destination semantics (including append).\n const next = [...data.elements];\n const [moved] = next.splice(from, 1);\n next.splice(to, 0, moved!);\n\n return reorderArraySource(code, data.elements, next);\n};\n\nexport const moveArrayItems = (\n code: string,\n indices: Set<number>,\n direction: 'up' | 'down',\n): { code: string; indices: Set<number> } | null => {\n const data = denseArraySource(code);\n\n if (\n !data ||\n !validArrayIndices(indices, data.elements.length) ||\n !['up', 'down'].includes(direction)\n ) {\n return null;\n }\n\n const next = moveSelectedIndices(data.elements, indices, direction);\n\n return {\n code: reorderArraySource(code, data.elements, next.items),\n indices: next.indices,\n };\n};\n\n// Keep the last-item guard until the empty-array creation contract (#316)\n// is implemented. It must count the visible kind in a mixed array.\nexport const removeArrayItems = (\n code: string,\n indices: Set<number>,\n kind?: ItemKind,\n): string | null => {\n const data = denseArraySource(code);\n\n if (!data || !validArrayIndices(indices, data.elements.length)) {\n return null;\n }\n\n const remaining = removeIndices(data.elements, indices);\n const survivors =\n kind === undefined\n ? remaining\n : remaining.filter(node => kindOf(node) === kind);\n\n if (!survivors.length) {\n return null;\n }\n\n return removeArraySource(code, data, indices);\n};\n\n// Copy exact source; only static object keys / JSX identities get changed.\n// Re-evaluating modeled property values here would erase expressions.\nconst copyItem = (\n code: string,\n element: t.Expression,\n generateId: () => string,\n usedIds: Set<string>,\n): string | null => {\n const edits: SourceEdit[] = [];\n let unsupported = false;\n const reserveId = (id: string) => {\n if (usedIds.has(id)) {\n unsupported = true;\n }\n\n usedIds.add(id);\n\n return JSON.stringify(id);\n };\n\n t.traverseFast(element, node => {\n if (!t.isJSXOpeningElement(node)) {\n return;\n }\n\n const ids = node.attributes.filter(\n (attr): attr is t.JSXAttribute =>\n t.isJSXAttribute(attr) &&\n t.isJSXIdentifier(attr.name, { name: 'data-id' }),\n );\n const attr = ids[0];\n\n if (\n ids.length > 1 ||\n (attr &&\n (!t.isStringLiteral(attr.value) ||\n node.attributes\n .slice(node.attributes.indexOf(attr) + 1)\n .some(a => t.isJSXSpreadAttribute(a))))\n ) {\n unsupported = true;\n return;\n }\n\n if (attr && t.isStringLiteral(attr.value)) {\n edits.push({\n start: attr.value.start!,\n end: attr.value.end!,\n content: reserveId(generateId()),\n });\n }\n });\n\n if (t.isObjectExpression(element)) {\n const keys = element.properties.filter(\n (prop): prop is t.ObjectProperty =>\n t.isObjectProperty(prop) &&\n !prop.computed &&\n (t.isIdentifier(prop.key, { name: 'key' }) ||\n t.isStringLiteral(prop.key, { value: 'key' })),\n );\n const key = keys[0];\n\n if (\n keys.length > 1 ||\n (key &&\n (!t.isStringLiteral(key.value) ||\n element.properties\n .slice(element.properties.indexOf(key) + 1)\n .some(\n prop =>\n t.isSpreadElement(prop) ||\n ('computed' in prop && prop.computed),\n )))\n ) {\n return null;\n }\n\n if (key && t.isStringLiteral(key.value)) {\n edits.push({\n start: key.value.start!,\n end: key.value.end!,\n content: reserveId(`${key.value.value}-${generateId()}`),\n });\n }\n }\n\n if (unsupported) {\n return null;\n }\n\n return applyEdits(\n code.slice(element.start!, element.end!),\n edits.map(edit => ({\n ...edit,\n start: edit.start - element.start!,\n end: edit.end - element.start!,\n })),\n );\n};\n\nexport const duplicateArrayItems = (\n code: string,\n indices: Set<number>,\n generateId: () => string = () => nanoid(6),\n): string | null => {\n const data = denseArraySource(code);\n\n if (\n !data ||\n !indices.size ||\n !validArrayIndices(indices, data.elements.length)\n ) {\n return null;\n }\n\n const usedIds = new Set<string>();\n\n t.traverseFast(data.array, node => {\n if (\n t.isJSXAttribute(node) &&\n t.isJSXIdentifier(node.name, { name: 'data-id' }) &&\n t.isStringLiteral(node.value)\n ) {\n usedIds.add(node.value.value);\n } else if (\n t.isObjectProperty(node) &&\n !node.computed &&\n (t.isIdentifier(node.key, { name: 'key' }) ||\n t.isStringLiteral(node.key, { value: 'key' })) &&\n t.isStringLiteral(node.value)\n ) {\n usedIds.add(node.value.value);\n }\n });\n\n const copies = [...indices]\n .sort((a, b) => a - b)\n .map(index => copyItem(code, data.elements[index]!, generateId, usedIds));\n\n return copies.every((copy): copy is string => copy !== null)\n ? appendArraySource(code, data, copies)\n : null;\n};\n\n// Appends a copy of the first item of `kind`. There is deliberately no\n// \"create from scratch\" path: the shape of an item is defined by its\n// siblings, and inventing one (`{}`, or a guess from the render map) would\n// either be uneditable or silently impose a shape the consumer never\n// declared. An array binding is therefore editable only while it holds at\n// least one item — the same invariant `removeArrayItems` maintains by\n// refusing any edit that would empty the array. `null` here means the array\n// has no item of `kind` to copy; the first one belongs in the source (#316).\nexport const appendArrayItem = (\n code: string,\n kind: ItemKind,\n generateId: () => string = () => nanoid(6),\n): string | null => {\n const data = denseArraySource(code);\n const index = data?.elements.findIndex(node => kindOf(node) === kind) ?? -1;\n\n return index < 0\n ? null\n : duplicateArrayItems(code, new Set([index]), generateId);\n};\n","import { parse } from '@babel/parser';\nimport * as t from '@babel/types';\nimport { nanoid } from 'nanoid';\n\nimport { BINDING_PROP, CONFIG, DATA_ATTR } from '../../constants';\nimport { createBoundedCache } from '../cache';\nimport { registerEditorCache } from '../editor-caches';\nimport { parseBinding, parseBindingExpression } from './binding';\nimport { traverse } from './document';\nimport { attrValue, generateCode, wrap } from './helpers';\nimport { getJSXTagName } from './jsx-name';\nimport type { Attribute, BindingItem, DataAttrNode } from './types';\nimport { unwrapExpression } from './value';\n\nconst collectText = (\n children: (\n | t.JSXText\n | t.JSXExpressionContainer\n | t.JSXElement\n | t.JSXFragment\n | t.JSXSpreadChild\n )[],\n) => {\n return children\n .filter(c => t.isJSXText(c))\n .map(c => (c as t.JSXText).value.trim())\n .filter(v => v.length)\n .join(' ');\n};\n\nconst parseJSXName = (\n tagName: string,\n): t.JSXIdentifier | t.JSXMemberExpression => {\n const parts = tagName.split('.');\n\n if (parts.length === 1) {\n return t.jsxIdentifier(parts[0]!);\n }\n\n let expr: t.JSXIdentifier | t.JSXMemberExpression = t.jsxIdentifier(\n parts[0]!,\n );\n\n for (let i = 1; i < parts.length; i++) {\n expr = t.jsxMemberExpression(expr, t.jsxIdentifier(parts[i]!));\n }\n\n return expr;\n};\n\nconst extractCache = createBoundedCache<string, DataAttrNode[]>(\n CONFIG.CACHE_LIMIT,\n);\n\nconst extractAttributes = (\n attributes: (t.JSXAttribute | t.JSXSpreadAttribute)[],\n source?: string,\n): { allAttrs: Attribute[]; dataAttrs: Attribute[] } => {\n const allAttrs: Attribute[] = [];\n const dataAttrs: Attribute[] = [];\n\n for (const attr of attributes) {\n if (!t.isJSXAttribute(attr) || !t.isJSXIdentifier(attr.name)) {\n continue;\n }\n\n const name = attr.name.name;\n let value: string | null = null;\n let isStringLiteral = false;\n\n if (attr.value) {\n if (t.isStringLiteral(attr.value)) {\n value = attr.value.value;\n isStringLiteral = true;\n } else if (t.isJSXExpressionContainer(attr.value)) {\n try {\n const expression = attr.value.expression;\n const structural =\n t.isArrayExpression(unwrapExpression(expression)) ||\n t.isObjectExpression(unwrapExpression(expression));\n value =\n source &&\n structural &&\n expression.start != null &&\n expression.end != null\n ? source.slice(expression.start, expression.end)\n : generateCode(expression);\n isStringLiteral = false;\n } catch {\n value = null;\n }\n }\n }\n\n const entry = { name, value, isStringLiteral };\n\n allAttrs.push(entry);\n\n if (name.startsWith('data-')) {\n dataAttrs.push(entry);\n }\n }\n\n return { allAttrs, dataAttrs };\n};\n\nconst buildChildElements = (\n node: DataAttrNode,\n): (t.JSXText | t.JSXElement | t.JSXFragment)[] => {\n const childElements: (t.JSXText | t.JSXElement | t.JSXFragment)[] = [];\n\n if (node.textContent) {\n childElements.push(t.jsxText(node.textContent));\n }\n\n node.children?.forEach(child => {\n const childJSX = nodeToJSX(child);\n if (childJSX) {\n childElements.push(childJSX);\n }\n });\n\n return childElements;\n};\n\nexport const nodeToJSX = (\n node: DataAttrNode,\n): t.JSXElement | t.JSXFragment | null => {\n try {\n if (node.isFragment) {\n const childElements = buildChildElements(node);\n\n return t.jsxFragment(\n t.jsxOpeningFragment(),\n t.jsxClosingFragment(),\n childElements,\n );\n }\n\n if (\n node.tagName === 'div' &&\n node.dataAttributes.some(attr => attr.name === 'data-item')\n ) {\n if (node.children) {\n return nodeToJSX(node.children[0]!);\n }\n return null;\n }\n\n const attributes = node.attributes.map(attr => {\n const attrName = t.jsxIdentifier(attr.name);\n\n if (!attr.value) {\n return t.jsxAttribute(attrName, null);\n }\n\n return t.jsxAttribute(attrName, attrValue(attr));\n });\n\n const elementName = parseJSXName(node.tagName);\n\n const openingElement = t.jsxOpeningElement(elementName, attributes);\n\n const closingElement = t.jsxClosingElement(elementName);\n const children = buildChildElements(node);\n\n return t.jsxElement(openingElement, closingElement, children, false);\n } catch (error) {\n console.error('❌ DataAttrNode to JSX conversion error:', error);\n return null;\n }\n};\n\nconst createWrapperNode = (\n textContent: string,\n children: DataAttrNode[],\n): DataAttrNode => ({\n tagName: 'div',\n id: nanoid(6),\n attributes: [{ name: DATA_ATTR.ITEM, value: 'true' }],\n dataAttributes: [{ name: DATA_ATTR.ITEM, value: 'true' }],\n textContent,\n children,\n});\n\nconst createFragmentNode = (\n textContent: string,\n children: DataAttrNode[],\n): DataAttrNode => ({\n tagName: '',\n id: nanoid(6),\n attributes: [],\n dataAttributes: [],\n textContent,\n children,\n isFragment: true,\n});\n\nconst processChildrenBinding = (\n jsxElement: t.JSXElement,\n processedNodes?: WeakSet<t.JSXElement | t.JSXFragment>,\n shouldWrap: boolean = true,\n source?: string,\n): DataAttrNode[] | undefined => {\n const jsxChildren = jsxElement.children.filter(\n child => t.isJSXElement(child) || t.isJSXFragment(child),\n );\n\n if (!jsxChildren.length) {\n return undefined;\n }\n\n const childrenNodes: DataAttrNode[] = [];\n\n jsxChildren.forEach(child => {\n if (t.isJSXElement(child)) {\n const childResults = extractFromNode(child, processedNodes, source);\n\n if (shouldWrap) {\n const wrapperNode = createWrapperNode(\n collectText(child.children),\n childResults,\n );\n wrapperNode.source = source?.slice(child.start!, child.end!);\n const dataId = childResults[0]?.dataAttributes.find(\n attr => attr.name === DATA_ATTR.ID,\n )?.value;\n\n if (dataId) {\n wrapperNode.id = `child:${dataId}`;\n }\n\n childrenNodes.push(wrapperNode);\n } else {\n childrenNodes.push(...childResults);\n }\n } else if (t.isJSXFragment(child)) {\n processedNodes?.add(child);\n\n const fragmentChildren: DataAttrNode[] = [];\n\n child.children.forEach(fragmentChild => {\n if (t.isJSXElement(fragmentChild)) {\n const childResults = extractFromNode(\n fragmentChild,\n processedNodes,\n source,\n );\n fragmentChildren.push(...childResults);\n }\n });\n\n if (fragmentChildren.length) {\n const fragmentNode = createFragmentNode(\n collectText(child.children),\n fragmentChildren,\n );\n fragmentNode.source = source?.slice(child.start!, child.end!);\n childrenNodes.push(fragmentNode);\n }\n }\n });\n\n return childrenNodes.length ? childrenNodes : undefined;\n};\n\nconst skipItemsChildren = (\n jsxElement: t.JSXElement,\n processedNodes: WeakSet<t.JSXElement | t.JSXFragment>,\n propertyName: string = 'items',\n): void => {\n const opening = jsxElement.openingElement;\n\n const itemsAttr = opening.attributes.find(\n attr =>\n t.isJSXAttribute(attr) &&\n t.isJSXIdentifier(attr.name) &&\n attr.name.name === propertyName,\n );\n\n if (!itemsAttr || !t.isJSXAttribute(itemsAttr)) {\n return;\n }\n\n if (\n itemsAttr.value &&\n t.isJSXExpressionContainer(itemsAttr.value) &&\n t.isArrayExpression(itemsAttr.value.expression)\n ) {\n const arrayExpr = itemsAttr.value.expression;\n\n arrayExpr.elements.forEach(element => {\n if (t.isObjectExpression(element)) {\n element.properties.forEach(prop => {\n if (\n t.isObjectProperty(prop) &&\n t.isIdentifier(prop.key) &&\n t.isJSXElement(prop.value)\n ) {\n markProcessedJSX(prop.value, processedNodes);\n }\n });\n }\n });\n }\n};\n\nconst markProcessedJSX = (\n node: t.Node,\n processedNodes: WeakSet<t.JSXElement | t.JSXFragment>,\n): void => {\n if (t.isJSXElement(node) || t.isJSXFragment(node)) {\n processedNodes.add(node as t.JSXElement | t.JSXFragment);\n node.children.forEach(child => markProcessedJSX(child, processedNodes));\n return;\n }\n\n const expression =\n t.isJSXExpressionContainer(node) || t.isParenthesizedExpression(node);\n\n if (expression) {\n markProcessedJSX(node.expression, processedNodes);\n }\n};\n\ninterface NodeBindingInfo {\n tagName: string;\n allAttrs: Attribute[];\n dataAttrs: Attribute[];\n bindings: BindingItem[];\n childrenBinding: BindingItem | undefined;\n arrayBindings: BindingItem[];\n rawChildren: string | undefined;\n}\n\n// Shared prefix for the top-level traverse() visitor below and the manual\n// recursive descent in extractFromNode: read the tag name, attributes, and\n// parsed bindings off one JSXElement. What differs between the two callers\n// is how childrenNodes gets computed and whether the result is pushed at\n// all — traverse() only records elements with data-* attributes, while\n// extractFromNode always records the children it's asked to (see each call\n// site for details).\n// `data-binding` is authored as a JSX object-array expression, so the\n// original `ArrayExpression` node is still on hand here. Return it so\n// `readNodeBindingInfo` can evaluate bindings straight off the AST instead\n// of re-parsing the stringified form. Null when the attribute is absent or\n// written as a plain string literal (bench/tests) — those still go through\n// `parseBinding(string)`.\nconst getBindingExpression = (\n opening: t.JSXOpeningElement,\n): t.ArrayExpression | null => {\n for (const attr of opening.attributes) {\n if (\n t.isJSXAttribute(attr) &&\n t.isJSXIdentifier(attr.name) &&\n attr.name.name === DATA_ATTR.BINDING &&\n attr.value &&\n t.isJSXExpressionContainer(attr.value)\n ) {\n // Unwrap `satisfies BindingItem[]`/`as const`/parentheses so the array\n // is still recognized when authored with an editor type annotation.\n const expression = unwrapExpression(attr.value.expression);\n\n if (t.isArrayExpression(expression)) {\n return expression;\n }\n }\n }\n\n return null;\n};\n\nconst readNodeBindingInfo = (\n node: t.JSXElement,\n source?: string,\n): NodeBindingInfo => {\n const opening = node.openingElement;\n const tagName = getJSXTagName(opening);\n const { allAttrs, dataAttrs } = extractAttributes(opening.attributes, source);\n\n const bindingAttr = dataAttrs.find(attr => attr.name === DATA_ATTR.BINDING);\n const bindingExpr = getBindingExpression(opening);\n const bindings = bindingExpr\n ? parseBindingExpression(bindingExpr)\n : bindingAttr?.value\n ? parseBinding(bindingAttr.value)\n : [];\n\n const childrenBinding = bindings.find(\n b => b.property === BINDING_PROP.CHILDREN,\n );\n const arrayBindings = bindings.filter(\n b => b.property === BINDING_PROP.ITEMS || b.type === 'array',\n );\n\n const innerHtmlBinding = bindings.find(\n b => b.property === BINDING_PROP.INNER_HTML,\n );\n\n let rawChildren: string | undefined;\n if (innerHtmlBinding && node.children.length > 0) {\n rawChildren = node.children\n .map(child => generateCode(child))\n .join('')\n .trim();\n }\n\n return {\n tagName,\n allAttrs,\n dataAttrs,\n bindings,\n childrenBinding,\n arrayBindings,\n rawChildren,\n };\n};\n\nconst parseToNodes = (raw: string): DataAttrNode[] => {\n const wrapped = wrap(raw);\n const ast = parse(wrapped, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n errorRecovery: true,\n });\n\n const results: DataAttrNode[] = [];\n\n // babel's traverse() below visits every JSXElement in the tree, top to\n // bottom, regardless of structure. But some elements are meant to be\n // recorded as *structural* children of another result — e.g. a node\n // wrapped by processChildrenBinding()/extractFromNode() into a parent's\n // `children` array, or an element sitting inside an `items` binding's\n // array literal (skipped via skipItemsChildren()/markProcessedJSX()) —\n // not as their own top-level entry in `results`. Without this WeakSet,\n // traverse() would independently re-visit those same elements once it\n // reaches them in the tree and add a second, duplicate entry for them.\n // Each helper below adds a node here the moment it pulls that node out\n // of the normal top-level flow, and the JSXElement() visitor skips\n // anything already marked.\n const processedNodes = new WeakSet<t.JSXElement | t.JSXFragment>();\n\n traverse(ast, {\n JSXElement(path) {\n if (processedNodes.has(path.node)) {\n return;\n }\n\n const {\n tagName,\n allAttrs,\n dataAttrs,\n bindings,\n childrenBinding,\n arrayBindings,\n rawChildren,\n } = readNodeBindingInfo(path.node, wrapped);\n\n if (!tagName || !dataAttrs.length) {\n return;\n }\n\n let childrenNodes: DataAttrNode[] | undefined;\n\n if (childrenBinding) {\n childrenNodes = processChildrenBinding(\n path.node,\n processedNodes,\n true,\n wrapped,\n );\n }\n\n for (const arrayBinding of arrayBindings) {\n skipItemsChildren(path.node, processedNodes, arrayBinding.property);\n }\n\n results.push({\n tagName,\n attributes: allAttrs,\n dataAttributes: dataAttrs,\n textContent: collectText(path.node.children),\n rawChildren,\n children: childrenNodes,\n bindings,\n loc: path.node.loc\n ? {\n start: {\n line: path.node.loc.start.line,\n column: path.node.loc.start.column,\n },\n end: {\n line: path.node.loc.end.line,\n column: path.node.loc.end.column,\n },\n }\n : undefined,\n });\n },\n });\n\n return results;\n};\n\nexport function extract(raw: string): DataAttrNode[] {\n if (extractCache.has(raw)) {\n return extractCache.get(raw)!;\n }\n\n const results = parseToNodes(raw);\n\n extractCache.set(raw, results);\n\n return results;\n}\n\nfunction extractFromNode(\n node: t.JSXElement,\n processedNodes?: WeakSet<t.JSXElement | t.JSXFragment>,\n source?: string,\n): DataAttrNode[] {\n processedNodes?.add(node);\n\n const {\n tagName,\n allAttrs,\n dataAttrs,\n bindings,\n childrenBinding,\n rawChildren,\n } = readNodeBindingInfo(node, source);\n\n let childrenNodes: DataAttrNode[] | undefined;\n\n if (childrenBinding) {\n childrenNodes = processChildrenBinding(node, processedNodes, true, source);\n }\n\n if (!childrenNodes) {\n childrenNodes = processChildrenBinding(node, processedNodes, false, source);\n }\n\n return [\n {\n tagName,\n attributes: allAttrs,\n dataAttributes: dataAttrs,\n textContent: collectText(node.children),\n rawChildren,\n children: childrenNodes,\n bindings,\n },\n ];\n}\n\nexport function clearExtractCache() {\n extractCache.clear();\n}\n\nregisterEditorCache(clearExtractCache);\n","import { parseExpression } from '@babel/parser';\nimport * as t from '@babel/types';\nimport { nanoid } from 'nanoid';\n\nimport { moveSelectedIndices } from '../selection';\nimport { extract, nodeToJSX } from './extract';\nimport { generateCode } from './helpers';\nimport { type SourceEdit, applyEdits } from './patch';\nimport type { DataAttrNode } from './types';\n\nexport type ChildrenAction =\n | { type: 'move'; from: number; to: number }\n | { type: 'move-selected'; indices: number[]; direction: 'up' | 'down' }\n | { type: 'remove' | 'duplicate'; indices: number[] }\n | { type: 'append' };\n\nexport interface ChildrenEdit {\n kind: 'children-edit';\n expected: string[];\n action: ChildrenAction;\n}\n\n// Signatures address the extracted list, not synthetic wrapper IDs. The\n// source editor checks them against the latest parent before using indices.\nconst modeledSignatures = (nodes: DataAttrNode[]): string[] =>\n nodes.map(node => {\n const jsx = nodeToJSX(node);\n\n if (!jsx) {\n throw new Error('Invalid child node');\n }\n\n return generateCode(jsx);\n });\n\nexport const getChildrenSignatures = (nodes: DataAttrNode[]): string[] => {\n const modeled = modeledSignatures(nodes);\n\n return nodes.map((node, index) =>\n JSON.stringify([node.source ?? null, modeled[index]]),\n );\n};\n\nconst indicesAreValid = (\n indices: unknown,\n count: number,\n): indices is number[] =>\n Array.isArray(indices) &&\n new Set(indices).size === indices.length &&\n indices.every(\n index => Number.isInteger(index) && index >= 0 && index < count,\n );\n\n// Only ID attributes are replaced: expressions, spreads, comments and text\n// in a copied subtree retain their exact source. Dynamic IDs are ambiguous.\nconst copySource = (source: string, usedIds: Set<string>): string => {\n const node = parseExpression(source, { plugins: ['jsx', 'typescript'] });\n const edits: SourceEdit[] = [];\n const newId = () => {\n let id = nanoid(12);\n\n while (usedIds.has(id)) {\n id = nanoid(12);\n }\n\n usedIds.add(id);\n\n return id;\n };\n\n t.traverseFast(node, child => {\n if (!t.isJSXOpeningElement(child)) {\n return;\n }\n\n const ids = child.attributes.filter(\n (attr): attr is t.JSXAttribute =>\n t.isJSXAttribute(attr) &&\n t.isJSXIdentifier(attr.name, { name: 'data-id' }),\n );\n\n if (ids.length > 1) {\n throw new Error('Duplicate data-id attributes');\n }\n\n const attr = ids[0];\n\n if (\n attr &&\n child.attributes\n .slice(child.attributes.indexOf(attr) + 1)\n .some(attribute => t.isJSXSpreadAttribute(attribute))\n ) {\n throw new Error('A spread may override the copied data-id');\n }\n\n if (attr) {\n const value = attr.value;\n\n if (\n !t.isStringLiteral(value) ||\n value.start == null ||\n value.end == null\n ) {\n throw new Error('Cannot copy a dynamic data-id');\n }\n\n edits.push({\n start: value.start,\n end: value.end,\n content: JSON.stringify(newId()),\n });\n } else {\n const at = child.attributes.at(-1)?.end ?? child.name.end;\n\n if (at == null) {\n throw new Error('Missing opening element span');\n }\n\n edits.push({\n start: at,\n end: at,\n content: ` data-id=\"${newId()}\"`,\n });\n }\n });\n\n return applyEdits(source, edits);\n};\n\n// Coordinates refer to the caller's wrapped source, just like other update\n// editors. Non-element gaps stay at their original positions; moving a JSX\n// child moves its entire subtree but never regenerates intervening content.\nexport const editChildrenSource = (\n source: string,\n parent: t.JSXElement,\n input: unknown,\n): SourceEdit[] | null => {\n try {\n if (!parent.closingElement || parent.start == null || parent.end == null) {\n return null;\n }\n\n const value = typeof input === 'string' ? JSON.parse(input) : input;\n const children = parent.children.filter(\n (child): child is t.JSXElement | t.JSXFragment =>\n t.isJSXElement(child) || t.isJSXFragment(child),\n );\n const raw = children.map(child => source.slice(child.start!, child.end!));\n const models =\n extract(source.slice(parent.start, parent.end))[0]?.children ?? [];\n\n // The extractor currently omits some empty/expression-only fragments.\n // Never interpret its visible indices as different source children.\n if (models.length !== children.length) {\n return null;\n }\n\n const signatures = modeledSignatures(models);\n const replaceSlots = (next: string[]): SourceEdit[] => {\n const edits = children.map((child, index) => ({\n start: child.start!,\n end: child.end!,\n content: next[index] ?? '',\n }));\n\n if (next.length > children.length) {\n const at = parent.closingElement!.start!;\n edits.push({\n start: at,\n end: at,\n content: next.slice(children.length).join(''),\n });\n }\n\n return edits;\n };\n\n if (Array.isArray(value)) {\n // Preserve the existing JSON API. Unchanged modeled children reuse\n // their full original source; arbitrary replacements are allowed only\n // when every original child can be represented without information loss.\n const desired = modeledSignatures(value);\n const lossless = raw.every(\n (text, index) =>\n generateCode(\n parseExpression(text, { plugins: ['jsx', 'typescript'] }),\n ) === signatures[index],\n );\n const consumed = new Set<number>();\n const next = desired.map((signature, position) => {\n const index = signatures.findIndex(\n (candidate, i) =>\n candidate === signature &&\n !consumed.has(i) &&\n (value[position].source === undefined ||\n value[position].source === raw[i]),\n );\n\n if (index >= 0) {\n consumed.add(index);\n\n return raw[index]!;\n }\n\n if (\n !lossless ||\n (value[position].source !== undefined &&\n !raw.includes(value[position].source))\n ) {\n throw new Error(\n 'Use children commands to copy or edit unsupported source',\n );\n }\n\n return signature;\n });\n\n // Legacy callers may supply entirely new modeled children. Do not\n // accept a duplicated identity that would make later edits ambiguous.\n const countIds = (text: string) => {\n const counts = new Map<string, number>();\n t.traverseFast(\n parseExpression(text, { plugins: ['jsx', 'typescript'] }),\n node => {\n if (\n t.isJSXAttribute(node) &&\n t.isJSXIdentifier(node.name, { name: 'data-id' }) &&\n t.isStringLiteral(node.value)\n ) {\n counts.set(\n node.value.value,\n (counts.get(node.value.value) ?? 0) + 1,\n );\n }\n },\n );\n\n return counts;\n };\n const previousIds = countIds(source);\n const updatedParent = applyEdits(source, replaceSlots(next));\n const nextIds = countIds(updatedParent);\n\n if (\n [...nextIds].some(\n ([id, count]) => count > 1 && count > (previousIds.get(id) ?? 0),\n )\n ) {\n return null;\n }\n\n return replaceSlots(next);\n }\n\n const request = value as ChildrenEdit | null;\n\n if (\n request?.kind !== 'children-edit' ||\n !Array.isArray(request.expected) ||\n request.expected.length !== signatures.length ||\n !getChildrenSignatures(models).every(\n (signature, index) => signature === request.expected[index],\n ) ||\n !request.action\n ) {\n return null;\n }\n\n const { action } = request;\n const usedIds = new Set<string>();\n\n t.traverseFast(parent, node => {\n if (\n t.isJSXAttribute(node) &&\n t.isJSXIdentifier(node.name, { name: 'data-id' }) &&\n t.isStringLiteral(node.value)\n ) {\n usedIds.add(node.value.value);\n }\n });\n\n switch (action.type) {\n case 'move': {\n if (\n !indicesAreValid([action.from], raw.length) ||\n !indicesAreValid([action.to], raw.length)\n ) {\n return null;\n }\n\n const next = [...raw];\n const [moved] = next.splice(action.from, 1);\n next.splice(action.to, 0, moved!);\n\n return replaceSlots(next);\n }\n case 'move-selected': {\n if (\n !indicesAreValid(action.indices, raw.length) ||\n !['up', 'down'].includes(action.direction)\n ) {\n return null;\n }\n\n return replaceSlots(\n moveSelectedIndices(raw, new Set(action.indices), action.direction)\n .items,\n );\n }\n case 'remove': {\n if (!indicesAreValid(action.indices, raw.length)) {\n return null;\n }\n\n return action.indices.map(index => ({\n start: children[index]!.start!,\n end: children[index]!.end!,\n content: '',\n }));\n }\n case 'duplicate': {\n if (!indicesAreValid(action.indices, raw.length)) {\n return null;\n }\n\n const content = [...action.indices]\n .sort((a, b) => a - b)\n .map(index => copySource(raw[index]!, usedIds))\n .join('');\n const at = parent.closingElement.start!;\n\n return [{ start: at, end: at, content }];\n }\n case 'append': {\n const content = copySource(raw[0] ?? '<div></div>', usedIds);\n const at = parent.closingElement.start!;\n\n return [{ start: at, end: at, content }];\n }\n default:\n return null;\n }\n } catch {\n return null;\n }\n};\n","import { parse, parseExpression } from '@babel/parser';\nimport * as t from '@babel/types';\n\nimport {\n BINDING_PROP,\n DATA_ATTR,\n RESERVED_BINDING_PROPERTIES,\n} from '../../constants';\nimport { STRING_VALUED_TYPES, parseBinding } from './binding';\nimport { editChildrenSource } from './children';\nimport { traverse } from './document';\nimport { generateCode, unwrap, wrap } from './helpers';\nimport { type SourceEdit, applyEdits } from './patch';\nimport type { BindingType } from './types';\nimport {\n isLosslesslyEvaluable,\n unwrapExpression,\n valueToExpression,\n} from './value';\n\n// Every editor below returns the source spans it wants to change rather\n// than mutating the tree, so `update` can patch the original text and leave\n// untouched bytes byte-identical. An empty array means \"nothing to write,\n// but this counts as handled\"; `null` means the edit failed. See #239.\ntype EditResult = SourceEdit[] | null;\n\n// The span between `>` and `</`, i.e. everything the element encloses.\n// `null` for a self-closing element, which has nowhere to put children.\nconst childrenRange = (\n element: t.JSXElement,\n): { start: number; end: number } | null => {\n const { openingElement, closingElement } = element;\n\n if (\n !closingElement ||\n openingElement.end == null ||\n closingElement.start == null\n ) {\n return null;\n }\n\n return { start: openingElement.end, end: closingElement.start };\n};\n\nconst findAttribute = (\n opening: t.JSXOpeningElement,\n propertyName: string,\n): t.JSXAttribute | undefined => {\n return opening.attributes.find(\n (attr): attr is t.JSXAttribute =>\n t.isJSXAttribute(attr) &&\n t.isJSXIdentifier(attr.name) &&\n attr.name.name === propertyName,\n );\n};\n\n// Where a brand-new attribute should be inserted: after the last existing\n// attribute, or straight after the element name when there are none.\nconst attributeInsertPoint = (opening: t.JSXOpeningElement): number | null => {\n const last = opening.attributes[opening.attributes.length - 1];\n\n return last?.end ?? opening.name.end ?? null;\n};\n\n// Drops the element's JSXText children and writes `value` just before the\n// closing tag — the positional equivalent of the previous \"splice out every\n// JSXText, then push a new one\" mutation, including its handling of mixed\n// children (a nested element stays, the text around it doesn't).\n//\n// The common case — a single text child — is narrowed further: only the\n// text's *trimmed* span is replaced, so the author's line breaks and\n// indentation around it survive. Rewriting the whole children region would\n// collapse\n//\n// >\n// Old Title\n// </h1>\n//\n// down to `>New Title</h1>`, which is exactly the formatting loss #239 is\n// about, just at a smaller scale.\n//\n// A self-closing element yields no edits: there is no children region to\n// write into. That matches the old behaviour, which pushed onto a `children`\n// array the generator then ignored — a silent no-op still reported as\n// success. Left as-is here deliberately; it is a reporting bug, tracked\n// with the rest of that class in #270.\nconst editInnerText = (\n source: string,\n element: t.JSXElement,\n value: string,\n): EditResult => {\n const range = childrenRange(element);\n\n if (!range) {\n return [];\n }\n\n const [only] = element.children;\n\n if (\n element.children.length === 1 &&\n t.isJSXText(only) &&\n only.start != null &&\n only.end != null\n ) {\n // Measured on the raw source slice, never on `only.value`: the latter is\n // Babel's *cooked* text, with HTML entities decoded and CRLF collapsed\n // to LF, so its character counts don't line up with the raw offsets the\n // span is built from. `&nbsp;Old&nbsp;` would put the span six bytes\n // inside the entity (yielding `&New;`), and a CRLF file would lose a\n // byte off each end of every innerText edit.\n const raw = source.slice(only.start, only.end);\n\n if (raw.trim() !== '') {\n const leading = raw.length - raw.trimStart().length;\n const trailing = raw.length - raw.trimEnd().length;\n\n return [\n {\n start: only.start + leading,\n end: only.end - trailing,\n content: value,\n },\n ];\n }\n }\n\n const edits: SourceEdit[] = [];\n\n for (const child of element.children) {\n if (t.isJSXText(child) && child.start != null && child.end != null) {\n edits.push({ start: child.start, end: child.end, content: '' });\n }\n }\n\n edits.push({ start: range.end, end: range.end, content: value });\n\n return edits;\n};\n\n// Raw HTML replaces the children region verbatim. This is what the old\n// `__HTML_<id>__` placeholder existed to achieve: the value can't be\n// represented as an AST literal, so it had to be smuggled past the\n// generator and string-substituted back in afterwards. Writing directly\n// into the source removes that round-trip — and with it the `$&`/`$$`\n// substitution hazard that the replacement step had to guard against.\nconst editInnerHTML = (element: t.JSXElement, value: string): EditResult => {\n const range = childrenRange(element);\n\n if (!range) {\n return [];\n }\n\n return [{ start: range.start, end: range.end, content: value }];\n};\n\nconst editRichtext = (element: t.JSXElement, value: string): EditResult => {\n const edits: SourceEdit[] = [];\n const range = childrenRange(element);\n\n // richtext owns the element's content, so any prior markup goes.\n if (range && range.start !== range.end) {\n edits.push({ start: range.start, end: range.end, content: '' });\n }\n\n const opening = element.openingElement;\n const attribute = t.jsxAttribute(\n t.jsxIdentifier('dangerouslySetInnerHTML'),\n t.jsxExpressionContainer(\n t.objectExpression([\n t.objectProperty(t.identifier('__html'), t.stringLiteral(value)),\n ]),\n ),\n );\n const content = generateCode(attribute);\n const existing = findAttribute(opening, 'dangerouslySetInnerHTML');\n\n if (existing && existing.start != null && existing.end != null) {\n edits.push({\n start: existing.start,\n end: existing.end,\n content,\n indent: true,\n });\n\n return edits;\n }\n\n const insertAt = attributeInsertPoint(opening);\n\n if (insertAt == null) {\n return null;\n }\n\n edits.push({\n start: insertAt,\n end: insertAt,\n content: ` ${content}`,\n indent: true,\n });\n\n return edits;\n};\n\n// A `type: 'jsx'` value is arbitrary user-authored JSX, so it goes in as\n// written rather than being parsed into nodes and printed back out.\nconst editJsxAttribute = (\n opening: t.JSXOpeningElement,\n propertyName: string,\n value: unknown,\n): EditResult => {\n const attribute = findAttribute(opening, propertyName);\n\n if (!attribute) {\n return null;\n }\n\n const content = `{${String(value).trim()}}`;\n\n if (attribute.value?.start != null && attribute.value.end != null) {\n return [\n {\n start: attribute.value.start,\n end: attribute.value.end,\n content,\n },\n ];\n }\n\n // Valueless shorthand (`<Icon icon />`): there is no value span to\n // overwrite, so append one after the attribute name.\n const insertAt = attribute.name.end;\n\n if (insertAt == null) {\n return null;\n }\n\n return [{ start: insertAt, end: insertAt, content: `=${content}` }];\n};\n\n// Whether the attribute being replaced was authored as an array or object\n// literal inside a JSX expression container. Narrower than \"is an\n// expression\" on purpose: `className={cn(...)}` and `items={rows}` are\n// expressions too, but their value doesn't round-trip through the panel as\n// source text, so a string committed against them stays a string.\nconst holdsStructuralExpression = (value?: t.JSXAttribute['value']): boolean =>\n t.isJSXExpressionContainer(value) &&\n (t.isArrayExpression(unwrapExpression(value.expression)) ||\n t.isObjectExpression(unwrapExpression(value.expression)));\n\n// Parses committed text back into the array/object literal it claims to be.\n// Requiring that exact shape is what keeps a plain string from silently\n// becoming something else: `\"hello\"` parses fine as an identifier, and\n// writing `items={hello}` would turn a value into a variable reference.\nconst structuralSource = (value: string): t.Expression | null => {\n try {\n const expression = parseExpression(value.trim(), {\n plugins: ['jsx', 'typescript'],\n });\n\n return t.isArrayExpression(unwrapExpression(expression)) ||\n t.isObjectExpression(unwrapExpression(expression))\n ? expression\n : null;\n } catch {\n return null;\n }\n};\n\n// Serialize a structured value into a JSX attribute value, once, at the AST\n// boundary — the single point where the declared `type` is known. Replaces\n// the old first-character heuristic (`startsWith('{')` ...) that guessed\n// string-vs-expression and then let `attrValue` guess again. See #238.\n//\n// `current` is the attribute value being replaced. The declared `type` is\n// authoritative when there is one, but most shipped `items` bindings declare\n// none (`{ label: 'FAQ Items', property: 'items' }`), so the source is the\n// only remaining evidence of what the attribute holds — the same evidence\n// `getStructuredValue` reads on the way out via `attr.isStringLiteral`.\nconst buildAttributeValue = (\n value: unknown,\n type?: BindingType,\n current?: t.JSXAttribute['value'],\n): t.JSXAttribute['value'] => {\n // Declared object/array bindings: an expression container. A string here\n // is already-serialized source text (from the built-in Items/flatten\n // editor, which re-emits the whole array/object as code) — parse it back\n // to an expression rather than quoting it as a literal.\n if (type === 'array' || type === 'object') {\n if (typeof value === 'string') {\n try {\n return t.jsxExpressionContainer(\n parseExpression(value.trim(), { plugins: ['jsx', 'typescript'] }),\n );\n } catch {\n return t.stringLiteral(value);\n }\n }\n\n const expr = valueToExpression(value);\n return expr ? t.jsxExpressionContainer(expr) : t.stringLiteral('');\n }\n\n // Everything else maps one JS type to one literal kind — no guessing. A\n // string stays a string literal whatever it contains, so a genuine\n // `\"{not an expression}\"` no longer becomes a JSX expression container.\n if (typeof value === 'string') {\n // ...except when the attribute being replaced is itself an array/object\n // literal expression. Those hand the panel their *source text* as\n // `rawValue`, and the array editors commit that same source text back,\n // so quoting it would rewrite `items={[...]}` into an `items=\"[{\\n ...\"`\n // string literal and leave the document unparseable. Undeclared-type\n // `items`/`data` bindings only reach here, which is why they broke.\n if (\n holdsStructuralExpression(current) &&\n !(type && STRING_VALUED_TYPES.has(type))\n ) {\n const structural = structuralSource(value);\n\n if (structural) {\n return t.jsxExpressionContainer(structural);\n }\n }\n\n return t.stringLiteral(value);\n }\n\n const expr = valueToExpression(value);\n return expr ? t.jsxExpressionContainer(expr) : t.stringLiteral(String(value));\n};\n\nconst editAttribute = (\n opening: t.JSXOpeningElement,\n propertyName: string,\n value: unknown,\n type?: BindingType,\n): EditResult => {\n const attribute = findAttribute(opening, propertyName);\n\n if (!attribute || attribute.start == null || attribute.end == null) {\n return null;\n }\n\n // Serialized array/object edits already carry preserved source. Validate\n // their shape, then replace only the expression value instead of printing\n // the attribute (which would reformat every untouched array sibling).\n if (\n typeof value === 'string' &&\n (type === 'array' ||\n type === 'object' ||\n (holdsStructuralExpression(attribute.value) &&\n !(type && STRING_VALUED_TYPES.has(type))))\n ) {\n const expression = structuralSource(value);\n\n if (expression && t.isJSXExpressionContainer(attribute.value)) {\n const text = value.trim();\n const lineComment = expression.trailingComments?.some(\n comment => comment.type === 'CommentLine',\n );\n\n return [\n {\n start: attribute.value.expression.start!,\n end: attribute.value.expression.end!,\n content: `${text}${lineComment ? '\\n' : ''}`,\n },\n ];\n }\n }\n\n // Generate the whole attribute rather than just its value, so Babel's\n // JSX-attribute printing path decides the quoting and escaping — the same\n // path that produced this text before, when the enclosing tree was\n // regenerated. Reuses the parsed name node instead of building a fresh\n // identifier so namespaced/dashed names survive untouched.\n const content = generateCode(\n t.jsxAttribute(\n attribute.name,\n buildAttributeValue(value, type, attribute.value),\n ),\n );\n\n return [\n { start: attribute.start, end: attribute.end, content, indent: true },\n ];\n};\n\n// Removes an attribute along with the whitespace before it, so no gap or\n// blank line is left where it was. `undefined` is how a caller asks for this:\n// to React an `undefined` prop and a missing one are the same, and writing it\n// used to leave the literal text `\"undefined\"` in the source (#426).\nconst removeAttribute = (\n source: string,\n attribute: t.JSXAttribute,\n): EditResult => {\n if (attribute.start == null || attribute.end == null) {\n return null;\n }\n\n let start = attribute.start;\n\n while (start > 0 && /\\s/.test(source[start - 1]!)) {\n start -= 1;\n }\n\n return [{ start, end: attribute.end, content: '' }];\n};\n\n// Adds an attribute the element doesn't have yet, after its last attribute.\n// Only for a real value: an empty string or `undefined` for a missing\n// attribute leaves the element as it is, so clearing a field never creates\n// the attribute it was clearing (#426).\n//\n// Follows the tag's own layout: when its last attribute sits on a line of its\n// own, the new one goes on the next line with the same indentation, instead\n// of trailing the last one.\nconst addAttribute = (\n source: string,\n opening: t.JSXOpeningElement,\n propertyName: string,\n value: unknown,\n type?: BindingType,\n): EditResult => {\n const insertAt = attributeInsertPoint(opening);\n\n if (insertAt == null) {\n return null;\n }\n\n // `indent: true` below re-indents every line after the first to the\n // indentation of the line the edit starts on, so a bare newline is enough\n // to line the new attribute up under the last one.\n const lastStart = opening.attributes[opening.attributes.length - 1]?.start;\n const lineStart =\n lastStart == null ? -1 : source.lastIndexOf('\\n', lastStart - 1) + 1;\n const ownLine =\n lastStart != null &&\n lineStart > 0 &&\n /^\\s*$/.test(source.slice(lineStart, lastStart));\n const separator = ownLine ? '\\n' : ' ';\n\n const content =\n type === 'jsx'\n ? `${propertyName}={${String(value).trim()}}`\n : generateCode(\n t.jsxAttribute(\n t.jsxIdentifier(propertyName),\n buildAttributeValue(value, type),\n ),\n );\n\n return [\n {\n start: insertAt,\n end: insertAt,\n content: `${separator}${content}`,\n indent: true,\n },\n ];\n};\n\nconst canEditAttributeValue = (\n attribute: t.JSXAttribute,\n value: unknown,\n type?: BindingType,\n) => {\n if (\n !t.isJSXExpressionContainer(attribute.value) ||\n t.isJSXEmptyExpression(attribute.value.expression) ||\n isLosslesslyEvaluable(attribute.value.expression)\n ) {\n return true;\n }\n\n // Array/object editors commit validated source strings rather than a\n // partially evaluated JS value. Their own patch engines preserve every\n // expression, so accept that raw-source handoff here.\n return (\n typeof value === 'string' &&\n holdsStructuralExpression(attribute.value) &&\n !(type && STRING_VALUED_TYPES.has(type)) &&\n structuralSource(value) !== null\n );\n};\n\n// Why an edit failed. Before #270 every one of these collapsed into a bare\n// `success: false`, so the panel showed one generic \"Failed to update this\n// field / check the console\" toast for structurally different problems — and\n// nothing was ever logged, so the console it pointed at was empty. Each\n// variant carries the identifiers a caller needs to name the real fault\n// (usually a wrong `property`/`label` in the element's `data-binding`, not\n// the value the author just typed).\nexport type UpdateFailure =\n | { reason: 'element-not-found'; dataId: string }\n | { reason: 'no-binding'; dataId: string }\n // The binding targets an attribute the editor owns (`data-id`,\n // `data-name`, `data-binding`), which a panel edit must not rewrite.\n | { reason: 'reserved-property'; dataId: string; property: string }\n // Asked to remove (`undefined`) a property whose binding is `required`.\n | { reason: 'required-property'; dataId: string; property: string }\n | {\n reason: 'binding-not-declared';\n dataId: string;\n label: string;\n property?: string;\n }\n | {\n reason: 'duplicate-binding';\n dataId: string;\n label: string;\n property?: string;\n count: number;\n }\n | { reason: 'attribute-not-found'; dataId: string; property: string }\n | { reason: 'unsupported-syntax'; dataId: string; property: string }\n | { reason: 'parse-error'; error: unknown };\n\nexport interface UpdateResult {\n code: string;\n success: boolean;\n // Present iff `success === false`. The deprecated `bulkUpdate` reports\n // per-entry failures via `failures` instead, since one boolean can't say\n // how many of several entries failed or which ones.\n failure?: UpdateFailure;\n failures?: UpdateFailure[];\n}\n\n// `label` is a display string — reworded, duplicated, or translated at\n// authors' whim — so it identifies a binding only as a fallback. `property`\n// (an actual key, unique per element) is the real identity; pass it\n// whenever the caller has it (every internal caller does, via\n// PanelBinding.property). See #240: two bindings sharing a label used to\n// resolve to whichever `.find()` hit first, silently dropping the other's\n// edit while still reporting success.\nexport const update = (\n code: string,\n dataId: string,\n label: string,\n value: unknown,\n property?: string,\n): UpdateResult => {\n try {\n const wrapped = wrap(code);\n const ast = parse(wrapped, {\n sourceType: 'module',\n plugins: ['jsx', 'typescript'],\n });\n\n let changed = false;\n let failure: UpdateFailure | undefined;\n const edits: SourceEdit[] = [];\n\n // Records an editor's outcome. `null` is a failure — the caller passes\n // the reason so it isn't discarded; anything else counts as handled,\n // even when it produces no edits.\n const collect = (result: EditResult, onNull: () => UpdateFailure) => {\n if (!result) {\n failure = onNull();\n return;\n }\n\n edits.push(...result);\n changed = true;\n };\n\n traverse(ast, {\n JSXElement(path) {\n const opening = path.node.openingElement;\n\n const idAttr = opening.attributes.find(attr => {\n return (\n t.isJSXAttribute(attr) &&\n t.isJSXIdentifier(attr.name) &&\n attr.name.name === DATA_ATTR.ID &&\n attr.value &&\n t.isStringLiteral(attr.value) &&\n attr.value.value === dataId\n );\n });\n\n if (!idAttr) {\n return;\n }\n\n const bindingAttr = opening.attributes.find(\n (attr): attr is t.JSXAttribute =>\n t.isJSXAttribute(attr) &&\n t.isJSXIdentifier(attr.name) &&\n attr.name.name === DATA_ATTR.BINDING,\n );\n\n if (!bindingAttr?.value) {\n failure = { reason: 'no-binding', dataId };\n return;\n }\n\n let bindingValue = '';\n\n if (t.isStringLiteral(bindingAttr.value)) {\n bindingValue = bindingAttr.value.value;\n } else if (t.isJSXExpressionContainer(bindingAttr.value)) {\n try {\n bindingValue = generateCode(bindingAttr.value.expression);\n } catch (error) {\n failure = { reason: 'parse-error', error };\n return;\n }\n }\n\n const bindings = parseBinding(bindingValue);\n\n // Prefer `property` (an actual key) over `label` (a display\n // string) — see the module-level comment on `update`. Either way,\n // more than one match on this element is an authoring ambiguity\n // (duplicate labels, or a genuine property collision), not a case\n // to silently resolve by picking the first — see #240.\n const matches = bindings.filter(binding =>\n property !== undefined\n ? binding.property === property\n : binding.label === label,\n );\n\n if (matches.length === 0) {\n failure = { reason: 'binding-not-declared', dataId, label, property };\n return;\n }\n\n if (matches.length > 1) {\n failure = {\n reason: 'duplicate-binding',\n dataId,\n label,\n property,\n count: matches.length,\n };\n return;\n }\n\n const propertyBinding = matches[0]!;\n const prop = propertyBinding.property;\n\n if (RESERVED_BINDING_PROPERTIES.includes(prop)) {\n failure = { reason: 'reserved-property', dataId, property: prop };\n return;\n }\n\n // `undefined` asks for the property to go: an attribute is removed,\n // content is emptied. A `required` binding can't be removed (#426).\n const unset = value === undefined;\n\n if (unset && propertyBinding.required) {\n failure = { reason: 'required-property', dataId, property: prop };\n return;\n }\n\n switch (prop) {\n case BINDING_PROP.INNER_TEXT: {\n collect(\n editInnerText(wrapped, path.node, unset ? '' : String(value)),\n () => ({\n reason: 'parse-error',\n error: new Error(`could not update \"${prop}\"`),\n }),\n );\n break;\n }\n\n case BINDING_PROP.INNER_HTML: {\n collect(\n propertyBinding.type === 'richtext'\n ? editRichtext(path.node, unset ? '' : String(value))\n : editInnerHTML(path.node, unset ? '' : String(value)),\n () => ({\n reason: 'parse-error',\n error: new Error(`could not update \"${prop}\"`),\n }),\n );\n break;\n }\n\n case BINDING_PROP.CHILDREN: {\n // Children are edited as a structure (move, add, remove one), so\n // there is no whole-value removal to map `undefined` onto.\n if (unset) {\n failure = {\n reason: 'unsupported-syntax',\n dataId,\n property: prop,\n };\n break;\n }\n\n collect(editChildrenSource(wrapped, path.node, value), () => ({\n reason: 'parse-error',\n error: new Error(\n 'Unsupported or stale children edit; source was preserved',\n ),\n }));\n break;\n }\n\n default: {\n const attribute = findAttribute(opening, prop);\n\n if (unset) {\n // Already absent: nothing to remove, and nothing went wrong.\n collect(\n attribute ? removeAttribute(wrapped, attribute) : [],\n () => ({\n reason: 'parse-error',\n error: new Error(`could not remove \"${prop}\"`),\n }),\n );\n break;\n }\n\n // A declared property the element doesn't have yet is added when\n // it's given a real value, so a field that was switched off can be\n // switched on again. An empty string leaves it absent (#426).\n if (!attribute) {\n collect(\n value === ''\n ? []\n : addAttribute(\n wrapped,\n opening,\n prop,\n value,\n propertyBinding.type,\n ),\n () => ({\n reason: 'attribute-not-found',\n dataId,\n property: prop,\n }),\n );\n break;\n }\n\n if (\n attribute &&\n propertyBinding.type !== 'jsx' &&\n !canEditAttributeValue(attribute, value, propertyBinding.type)\n ) {\n failure = {\n reason: 'unsupported-syntax',\n dataId,\n property: prop,\n };\n break;\n }\n\n collect(\n propertyBinding.type === 'jsx'\n ? editJsxAttribute(opening, prop, value)\n : editAttribute(opening, prop, value, propertyBinding.type),\n () => ({ reason: 'attribute-not-found', dataId, property: prop }),\n );\n break;\n }\n }\n },\n });\n\n if (!changed) {\n return {\n code,\n success: false,\n // No specific reason recorded means the traversal never reached the\n // target element at all.\n failure: failure ?? { reason: 'element-not-found', dataId },\n };\n }\n\n // Patch the original source instead of re-emitting the tree: every byte\n // outside a recorded span is copied through unchanged, so an edit to\n // one field can no longer reflow the author's formatting elsewhere in\n // the section — including the `data-binding` array itself, which is now\n // authored as a JSX expression. See #239.\n return { code: unwrap(applyEdits(wrapped, edits)), success: true };\n } catch (error) {\n console.error('❌ Code update error:', error);\n return { code, success: false, failure: { reason: 'parse-error', error } };\n }\n};\n\nexport interface UpdateEntry {\n dataId: string;\n label: string;\n value: unknown;\n property?: string;\n}\n\n// The result of `updateAll`: every entry applied, or none. On failure `code`\n// is the source as it came in, `index` says which entry was refused, and\n// `failure` says why.\nexport type UpdateAllResult =\n | { success: true; code: string }\n | { success: false; code: string; failure: UpdateFailure; index: number };\n\n// Applies several edits as one: all of them, in array order, or none. The\n// first entry that fails stops the run and the source comes back untouched,\n// so a caller can commit the result as a single change (#425). An entry sees\n// the source the earlier ones left, and a later entry for the same\n// `dataId`/`property` wins.\n//\n// Each entry re-parses the source the one before it produced, so every offset\n// is fresh, and the outcome matches applying the entries one at a time (#239).\nexport const updateAll = (\n raw: string,\n entries: UpdateEntry[],\n): UpdateAllResult => {\n let current = raw;\n\n for (const [index, entry] of entries.entries()) {\n const result = update(\n current,\n entry.dataId,\n entry.label,\n entry.value,\n entry.property,\n );\n\n if (!result.success) {\n return {\n success: false,\n code: raw,\n failure: result.failure ?? {\n reason: 'element-not-found',\n dataId: entry.dataId,\n },\n index,\n };\n }\n\n current = result.code;\n }\n\n return { success: true, code: current };\n};\n\n/**\n * @deprecated Not atomic: when an entry fails, the ones before and after it\n * are still applied, and the returned `code` carries them. Use `updateAll`,\n * which applies every entry or none. Will be removed in the next major.\n */\nexport const bulkUpdate = (\n raw: string,\n entries: UpdateEntry[],\n): UpdateResult => {\n let current = raw;\n const failures: UpdateFailure[] = [];\n\n for (const entry of entries) {\n const result = update(\n current,\n entry.dataId,\n entry.label,\n entry.value,\n entry.property,\n );\n current = result.code;\n if (!result.success && result.failure) {\n failures.push(result.failure);\n }\n }\n\n return failures.length > 0\n ? { code: current, success: false, failures }\n : { code: current, success: true };\n};\n","import type { BindingItem } from './types';\n\nexport interface ValidationResult {\n valid: boolean;\n message?: string;\n}\n\nconst VALID: ValidationResult = { valid: true };\n\nexport const validateBindingValue = (\n binding: BindingItem,\n value: unknown,\n): ValidationResult => {\n const isEmpty = value === '' || value === null || value === undefined;\n\n if (isEmpty) {\n if (binding.required) {\n return { valid: false, message: 'This field is required.' };\n }\n return VALID;\n }\n\n // `min`/`max` compare against a real number. Since #238, a `type:\n // 'number'` binding delivers an actual number across the panel boundary,\n // so callers pass one here directly — no string coercion to re-derive the\n // type. A non-number value simply isn't range-checked.\n if (typeof value === 'number') {\n if (binding.min !== undefined && value < binding.min) {\n return { valid: false, message: `Must be at least ${binding.min}.` };\n }\n if (binding.max !== undefined && value > binding.max) {\n return { valid: false, message: `Must be at most ${binding.max}.` };\n }\n }\n\n if (typeof value === 'string' && binding.pattern) {\n let regex: RegExp;\n\n try {\n regex = new RegExp(binding.pattern);\n } catch {\n // Malformed pattern authored on the binding itself — don't block the\n // user's input for an authoring mistake that isn't theirs to fix.\n return VALID;\n }\n\n if (!regex.test(value)) {\n return {\n valid: false,\n message: 'Value does not match the required format.',\n };\n }\n }\n\n if (typeof value === 'string' && binding.type === 'url') {\n try {\n new URL(value);\n } catch {\n return { valid: false, message: 'Must be a valid URL.' };\n }\n }\n\n if (typeof value === 'string' && binding.type === 'date') {\n if (Number.isNaN(Date.parse(value))) {\n return { valid: false, message: 'Must be a valid date.' };\n }\n }\n\n return VALID;\n};\n"],"mappings":"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"}
@@ -50,10 +50,14 @@ const Error = ({ message, title = "An error occurred", className, onReset }) =>
50
50
  };
51
51
  //#endregion
52
52
  //#region src/components/error/boundary.tsx
53
+ const keysChanged = (prev = [], next = []) => prev.length !== next.length || next.some((key, i) => key !== prev[i]);
53
54
  var ErrorBoundary = class extends React.Component {
54
55
  constructor(props) {
55
56
  super(props);
56
- this.state = { hasError: false };
57
+ this.state = {
58
+ hasError: false,
59
+ resetKeys: props.resetKeys
60
+ };
57
61
  }
58
62
  static getDerivedStateFromError(error) {
59
63
  return {
@@ -65,14 +69,13 @@ var ErrorBoundary = class extends React.Component {
65
69
  console.error("🚨 [Boundary] Rendering error:", error, errorInfo);
66
70
  this.props.onError?.(error, errorInfo);
67
71
  }
68
- componentDidUpdate(prevProps) {
69
- if (!this.state.hasError) return;
70
- const prevKeys = prevProps.resetKeys ?? [];
71
- const nextKeys = this.props.resetKeys ?? [];
72
- if (prevKeys.length !== nextKeys.length || nextKeys.some((key, i) => key !== prevKeys[i])) this.setState({
72
+ static getDerivedStateFromProps(props, state) {
73
+ if (!keysChanged(state.resetKeys, props.resetKeys)) return null;
74
+ return state.hasError ? {
73
75
  hasError: false,
74
- error: void 0
75
- });
76
+ error: void 0,
77
+ resetKeys: props.resetKeys
78
+ } : { resetKeys: props.resetKeys };
76
79
  }
77
80
  reset = () => this.setState({
78
81
  hasError: false,
@@ -90,4 +93,4 @@ var ErrorBoundary = class extends React.Component {
90
93
  //#endregion
91
94
  export { Error as n, ErrorBoundary as t };
92
95
 
93
- //# sourceMappingURL=boundary-D2IFja-3.js.map
96
+ //# sourceMappingURL=boundary-B17cepvm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boundary-B17cepvm.js","names":[],"sources":["../src/components/error/error.tsx","../src/components/error/boundary.tsx"],"sourcesContent":["import { cn } from '~/utils/cn';\n\nexport interface Props extends React.ComponentPropsWithRef<'div'> {\n message?: string | null;\n title?: string;\n onReset?: () => void;\n}\n\nconst Error = ({\n message,\n title = 'An error occurred',\n className,\n onReset,\n}: Props) => {\n if (!message) {\n return null;\n }\n\n return (\n <div\n className={cn(className)}\n style={{\n padding: '16px',\n backgroundColor: '#fee2e2',\n border: '1px solid #fca5a5',\n borderRadius: '6px',\n color: '#7f1d1d',\n }}\n >\n <h3 style={{ fontSize: '14px', fontWeight: 'bold', margin: 0 }}>\n {title}\n </h3>\n <pre\n style={{\n marginTop: '8px',\n fontSize: '12px',\n whiteSpace: 'pre-wrap',\n margin: '8px 0 0 0',\n }}\n >\n {message}\n </pre>\n {onReset && (\n <button\n style={{\n marginTop: '8px',\n padding: '4px 12px',\n fontSize: '12px',\n color: 'white',\n backgroundColor: '#dc2626',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n }}\n onClick={onReset}\n >\n Try Again\n </button>\n )}\n </div>\n );\n};\n\nexport default Error;\n","import React from 'react';\n\nimport Error from './error';\n\ninterface Props {\n children: React.ReactNode;\n // `reset` clears the caught error and renders `children` again, the same\n // thing the built-in error's reset button does.\n fallback?: (message?: string, reset?: () => void) => React.ReactNode;\n onError?: (e: Error, info: React.ErrorInfo) => void;\n // Values whose identity changing (typically the code/module that produced\n // `children`) should auto-recover a caught error without needing a\n // remount — compared shallowly, one entry at a time, same idea as\n // react-error-boundary's resetKeys. Without this, once tripped, render()\n // never even attempts `children` again (see below), so a fix to the\n // underlying code has no way to reach the screen until this array changes\n // or something remounts the boundary via `key`.\n resetKeys?: readonly unknown[];\n}\n\ninterface State {\n hasError: boolean;\n error?: Error;\n // The resetKeys the last render saw, so getDerivedStateFromProps can tell\n // when they change.\n resetKeys?: readonly unknown[];\n}\n\nconst keysChanged = (\n prev: readonly unknown[] = [],\n next: readonly unknown[] = [],\n) => prev.length !== next.length || next.some((key, i) => key !== prev[i]);\n\nclass ErrorBoundary extends React.Component<Props, State> {\n constructor(props: Props) {\n super(props);\n this.state = { hasError: false, resetKeys: props.resetKeys };\n }\n\n static getDerivedStateFromError(error: Error): Partial<State> {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {\n console.error('🚨 [Boundary] Rendering error:', error, errorInfo);\n this.props.onError?.(error, errorInfo);\n }\n\n // Clears a caught error in the same render that sees new resetKeys, so\n // `children` get their next chance right away and the fallback doesn't\n // render (and run its effects) once more first (#442). If `children` throw\n // again with the new keys, getDerivedStateFromError catches that in this\n // same render pass.\n static getDerivedStateFromProps(\n props: Props,\n state: State,\n ): Partial<State> | null {\n if (!keysChanged(state.resetKeys, props.resetKeys)) {\n return null;\n }\n\n return state.hasError\n ? { hasError: false, error: undefined, resetKeys: props.resetKeys }\n : { resetKeys: props.resetKeys };\n }\n\n reset = () => this.setState({ hasError: false, error: undefined });\n\n render() {\n if (this.state.hasError) {\n return this.props.fallback ? (\n <>{this.props.fallback(this.state.error?.message, this.reset)}</>\n ) : (\n <Error\n message={this.state.error?.message}\n onReset={this.reset}\n title=\"Rendering Error\"\n />\n );\n }\n\n return this.props.children;\n }\n}\n\nexport default ErrorBoundary;\n"],"mappings":";;;;AAQA,MAAM,SAAS,EACb,SACA,QAAQ,qBACR,WACA,cACW;CACX,IAAI,CAAC,SACH,OAAO;CAGT,OACE,qBAAC,OAAD;EACE,WAAW,GAAG,SAAS;EACvB,OAAO;GACL,SAAS;GACT,iBAAiB;GACjB,QAAQ;GACR,cAAc;GACd,OAAO;EACT;EARF,UAAA;GAUE,oBAAC,MAAD;IAAI,OAAO;KAAE,UAAU;KAAQ,YAAY;KAAQ,QAAQ;IAAE;IAC1D,UAAA;GACC,CAAA;GACJ,oBAAC,OAAD;IACE,OAAO;KACL,WAAW;KACX,UAAU;KACV,YAAY;KACZ,QAAQ;IACV;IAEC,UAAA;GACE,CAAA;GACJ,WACC,oBAAC,UAAD;IACE,OAAO;KACL,WAAW;KACX,SAAS;KACT,UAAU;KACV,OAAO;KACP,iBAAiB;KACjB,QAAQ;KACR,cAAc;KACd,QAAQ;IACV;IACA,SAAS;IACV,UAAA;GAEO,CAAA;EAEP;;AAET;;;ACjCA,MAAM,eACJ,OAA2B,CAAC,GAC5B,OAA2B,CAAC,MACzB,KAAK,WAAW,KAAK,UAAU,KAAK,MAAM,KAAK,MAAM,QAAQ,KAAK,EAAE;AAEzE,IAAM,gBAAN,cAA4B,MAAM,UAAwB;CACxD,YAAY,OAAc;EACxB,MAAM,KAAK;EACX,KAAK,QAAQ;GAAE,UAAU;GAAO,WAAW,MAAM;EAAU;CAC7D;CAEA,OAAO,yBAAyB,OAA8B;EAC5D,OAAO;GAAE,UAAU;GAAM;EAAM;CACjC;CAEA,kBAAkB,OAAc,WAA4B;EAC1D,QAAQ,MAAM,kCAAkC,OAAO,SAAS;EAChE,KAAK,MAAM,UAAU,OAAO,SAAS;CACvC;CAOA,OAAO,yBACL,OACA,OACuB;EACvB,IAAI,CAAC,YAAY,MAAM,WAAW,MAAM,SAAS,GAC/C,OAAO;EAGT,OAAO,MAAM,WACT;GAAE,UAAU;GAAO,OAAO,KAAA;GAAW,WAAW,MAAM;EAAU,IAChE,EAAE,WAAW,MAAM,UAAU;CACnC;CAEA,cAAc,KAAK,SAAS;EAAE,UAAU;EAAO,OAAO,KAAA;CAAU,CAAC;CAEjE,SAAS;EACP,IAAI,KAAK,MAAM,UACb,OAAO,KAAK,MAAM,WAChB,oBAAA,UAAA,EAAA,UAAG,KAAK,MAAM,SAAS,KAAK,MAAM,OAAO,SAAS,KAAK,KAAK,EAAI,CAAA,IAEhE,oBAAC,OAAD;GACE,SAAS,KAAK,MAAM,OAAO;GAC3B,SAAS,KAAK;GACd,OAAM;EACP,CAAA;EAIL,OAAO,KAAK,MAAM;CACpB;AACF"}
@@ -1,2 +1,2 @@
1
- import { $ as Field, A as Canvas, B as DndPanel, C as DndChildren, D as useDndLayout, E as DndLayout, F as Panel, G as PanelBindingData, H as DndRenderSectionFallback, I as DraggableItem, J as PanelNodesChange, K as PanelBindingSource, L as DraggableItemDragState, M as DndRegionProps, N as Layout, O as useDndPalette, P as Palette, Q as DndRenderField, R as DraggableItemProps, S as useDndItems, T as useDndChildren, U as DndSectionFallbackArgs, V as Props, W as PanelBinding, X as withPanelCommit, Y as resolvePanelBindings, Z as DndEditError, _ as DndItemsActions, a as ItemsEditorActions, b as DndItemsNestedGroup, c as ItemsEditorNestedGroup, d as useItemsEditor, et as FieldProps, f as FieldKind, g as DndItems, h as isStructuralFieldKind, i as ItemsEditor, j as DndLayoutProps, k as useDndPanel, l as ItemsEditorOptions, m as getFieldKind, n as ChildrenEditorOptions, o as ItemsEditorItem, p as FieldKindBinding, q as PanelNodeChange, r as Dnd, s as ItemsEditorNestedElement, t as ChildrenEditor, u as useChildrenEditor, v as DndItemsItem, w as DndChildrenOptions, x as DndItemsOptions, y as DndItemsNestedElement, z as DndPalette } from "../index-DVgwXnPa.js";
2
- export { Canvas, ChildrenEditor, ChildrenEditorOptions, type DndChildren, type DndChildrenOptions, type DndEditError, type DndItems, type DndItemsActions, type DndItemsItem, type DndItemsNestedElement, type DndItemsNestedGroup, type DndItemsOptions, type DndLayout, type DndLayoutProps, type DndPalette, type DndPanel, type DndRegionProps, type DndRenderField, type DndRenderSectionFallback, type DndSectionFallbackArgs, DraggableItem, type DraggableItemDragState, type DraggableItemProps, Field, type FieldKind, type FieldKindBinding, type FieldProps, ItemsEditor, ItemsEditorActions, ItemsEditorItem, ItemsEditorNestedElement, ItemsEditorNestedGroup, ItemsEditorOptions, Layout, Palette, Panel, type PanelBinding, type PanelBindingData, type PanelBindingSource, type PanelNodeChange, type PanelNodesChange, type Props, Dnd as default, getFieldKind, isStructuralFieldKind, resolvePanelBindings, useChildrenEditor, useDndChildren, useDndItems, useDndLayout, useDndPalette, useDndPanel, useItemsEditor, withPanelCommit };
1
+ import { $ as DndNodePick, A as useDndPanel, B as DndPalette, C as useDndItems, D as DndLayout, E as useDndChildren, F as Palette, G as PanelBinding, H as Props, I as Panel, J as PanelNodeChange, K as PanelBindingData, L as DraggableItem, M as DndLayoutProps, N as DndRegionProps, O as useDndLayout, P as Layout, Q as DndInspector, R as DraggableItemDragState, S as DndItemsOptions, T as DndChildrenOptions, U as DndRenderSectionFallback, V as DndPanel, W as DndSectionFallbackArgs, X as resolvePanelBindings, Y as PanelNodesChange, Z as withPanelCommit, _ as DndItemsActions, a as ItemsEditorActions, b as DndItemsNestedElement, c as ItemsEditorNestedGroup, d as useItemsEditor, et as useDndInspector, f as FieldKind, g as DndItems, h as isStructuralFieldKind, i as ItemsEditor, it as FieldProps, j as Canvas, k as useDndPalette, l as ItemsEditorOptions, m as getFieldKind, n as ChildrenEditorOptions, nt as DndRenderField, o as ItemsEditorItem, p as FieldKindBinding, q as PanelBindingSource, r as Dnd, rt as Field, s as ItemsEditorNestedElement, t as ChildrenEditor, tt as DndEditError, u as useChildrenEditor, v as DndItemsExpansion, w as DndChildren, x as DndItemsNestedGroup, y as DndItemsItem, z as DraggableItemProps } from "../index-CtlUYnWq.js";
2
+ export { Canvas, ChildrenEditor, ChildrenEditorOptions, type DndChildren, type DndChildrenOptions, type DndEditError, type DndInspector, type DndItems, type DndItemsActions, type DndItemsExpansion, type DndItemsItem, type DndItemsNestedElement, type DndItemsNestedGroup, type DndItemsOptions, type DndLayout, type DndLayoutProps, type DndNodePick, type DndPalette, type DndPanel, type DndRegionProps, type DndRenderField, type DndRenderSectionFallback, type DndSectionFallbackArgs, DraggableItem, type DraggableItemDragState, type DraggableItemProps, Field, type FieldKind, type FieldKindBinding, type FieldProps, ItemsEditor, ItemsEditorActions, ItemsEditorItem, ItemsEditorNestedElement, ItemsEditorNestedGroup, ItemsEditorOptions, Layout, Palette, Panel, type PanelBinding, type PanelBindingData, type PanelBindingSource, type PanelNodeChange, type PanelNodesChange, type Props, Dnd as default, getFieldKind, isStructuralFieldKind, resolvePanelBindings, useChildrenEditor, useDndChildren, useDndInspector, useDndItems, useDndLayout, useDndPalette, useDndPanel, useItemsEditor, withPanelCommit };
package/dist/dnd/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { _ as useDndPanel, a as Layout, c as Field, d as isStructuralFieldKind, f as useDndChildren, g as useDndPalette, h as useDndLayout, i as Canvas, l as useDndItems, m as withPanelCommit, n as useChildrenEditor, o as Palette, p as resolvePanelBindings, r as useItemsEditor, s as Panel, t as Dnd, u as getFieldKind, v as DraggableItem } from "../dnd-DBaH2L8N.js";
2
- export { Canvas, DraggableItem, Field, Layout, Palette, Panel, Dnd as default, getFieldKind, isStructuralFieldKind, resolvePanelBindings, useChildrenEditor, useDndChildren, useDndItems, useDndLayout, useDndPalette, useDndPanel, useItemsEditor, withPanelCommit };
1
+ import { _ as useDndPanel, a as Layout, c as Field, d as isStructuralFieldKind, f as useDndChildren, g as useDndPalette, h as useDndLayout, i as Canvas, l as useDndItems, m as withPanelCommit, n as useChildrenEditor, o as Palette, p as resolvePanelBindings, r as useItemsEditor, s as Panel, t as Dnd, u as getFieldKind, v as DraggableItem, y as useDndInspector } from "../dnd-Z1KS16Fy.js";
2
+ export { Canvas, DraggableItem, Field, Layout, Palette, Panel, Dnd as default, getFieldKind, isStructuralFieldKind, resolvePanelBindings, useChildrenEditor, useDndChildren, useDndInspector, useDndItems, useDndLayout, useDndPalette, useDndPanel, useItemsEditor, withPanelCommit };