@jbpark/live-editor 6.0.0 → 6.1.1

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 (67) hide show
  1. package/README.ko.md +8 -0
  2. package/README.md +8 -0
  3. package/dist/{boundary-CySnDUs2.js → boundary-CLMNMZFa.js} +4 -4
  4. package/dist/boundary-CLMNMZFa.js.map +1 -0
  5. package/dist/{cn-CAnad2vL.js → compile-BWZ5U59y.js} +135 -2
  6. package/dist/compile-BWZ5U59y.js.map +1 -0
  7. package/dist/{context-Bjq0CvBE.js → context-DJxX9epB.js} +2 -3
  8. package/dist/context-DJxX9epB.js.map +1 -0
  9. package/dist/{core-BNVuH8-l.js → core-BfJwD8Jx.js} +3 -6
  10. package/dist/core-BfJwD8Jx.js.map +1 -0
  11. package/dist/dnd/index.js +2 -2
  12. package/dist/{dnd-BvjEDo-x.js → dnd-DAGjlJ0_.js} +241 -170
  13. package/dist/dnd-DAGjlJ0_.js.map +1 -0
  14. package/dist/{document-uHqw0mvr.js → document-MkQGxfry.js} +1182 -636
  15. package/dist/document-MkQGxfry.js.map +1 -0
  16. package/dist/editor/index.js +2 -2
  17. package/dist/{editor-CvnzrM9J.js → editor-B_VOz3Q0.js} +2 -2
  18. package/dist/{editor-CvnzrM9J.js.map → editor-B_VOz3Q0.js.map} +1 -1
  19. package/dist/editor-caches-DXYXgWeD.js +63 -0
  20. package/dist/editor-caches-DXYXgWeD.js.map +1 -0
  21. package/dist/error/index.d.ts +1 -1
  22. package/dist/error/index.js +2 -2
  23. package/dist/{error-CFzvnLCf.js → error-E3T5CS3m.js} +13 -12
  24. package/dist/error-E3T5CS3m.js.map +1 -0
  25. package/dist/{index-DfIvkht8.d.ts → index-BC9hY7dI.d.ts} +5 -5
  26. package/dist/{index-CqsS207F.d.ts → index-D-Dfv65w.d.ts} +3 -2
  27. package/dist/index.d.ts +4 -4
  28. package/dist/index.js +5 -5
  29. package/dist/preview/index.d.ts +1 -1
  30. package/dist/preview/index.js +1 -1
  31. package/dist/{preview-B05MkVIQ.js → preview-DFb1pOqJ.js} +30 -11
  32. package/dist/preview-DFb1pOqJ.js.map +1 -0
  33. package/dist/provider/index.js +1 -1
  34. package/dist/{sections-DhH_aVf5.js → sections-CnG7OLr8.js} +3 -3
  35. package/dist/{sections-DhH_aVf5.js.map → sections-CnG7OLr8.js.map} +1 -1
  36. package/dist/states-Ci1AvoQ9.js.map +1 -1
  37. package/dist/style.css +74 -74
  38. package/dist/ui-kit/index.js +2 -2
  39. package/dist/ui-kit/style.css +22 -6
  40. package/dist/{update-BuYQJqjq.js → update-DnX2ibYn.js} +162 -43
  41. package/dist/update-DnX2ibYn.js.map +1 -0
  42. package/dist/{use-dynamic-tailwind-B3l1qZRW.js → use-dynamic-tailwind-CjXeHjsr.js} +115 -40
  43. package/dist/use-dynamic-tailwind-CjXeHjsr.js.map +1 -0
  44. package/dist/{use-field-state-iQGW0vc6.js → use-field-state-B1VLhWfr.js} +2 -2
  45. package/dist/{use-field-state-iQGW0vc6.js.map → use-field-state-B1VLhWfr.js.map} +1 -1
  46. package/dist/utils/ast/index.js +1 -86
  47. package/dist/utils/index.js +3 -4
  48. package/package.json +3 -4
  49. package/dist/boundary-CySnDUs2.js.map +0 -1
  50. package/dist/cn-CAnad2vL.js.map +0 -1
  51. package/dist/compile-my0AjsCw.js +0 -136
  52. package/dist/compile-my0AjsCw.js.map +0 -1
  53. package/dist/constants-st9gnJ5g.js +0 -55
  54. package/dist/constants-st9gnJ5g.js.map +0 -1
  55. package/dist/context-Bjq0CvBE.js.map +0 -1
  56. package/dist/core-BNVuH8-l.js.map +0 -1
  57. package/dist/detect-typescript-CMF0FVKD.js +0 -10
  58. package/dist/detect-typescript-CMF0FVKD.js.map +0 -1
  59. package/dist/dnd-BvjEDo-x.js.map +0 -1
  60. package/dist/document-uHqw0mvr.js.map +0 -1
  61. package/dist/editor-caches-ClMvdcQF.js +0 -23
  62. package/dist/editor-caches-ClMvdcQF.js.map +0 -1
  63. package/dist/error-CFzvnLCf.js.map +0 -1
  64. package/dist/preview-B05MkVIQ.js.map +0 -1
  65. package/dist/update-BuYQJqjq.js.map +0 -1
  66. package/dist/use-dynamic-tailwind-B3l1qZRW.js.map +0 -1
  67. package/dist/utils/ast/index.js.map +0 -1
@@ -1,15 +1,14 @@
1
- import { C as isJSXElement, D as isJSXIdentifier, E as isJSXFragment, I as isSpreadElement, L as isStringLiteral, N as isObjectExpression, O as isJSXOpeningElement, P as isObjectProperty, S as isJSXAttribute, a as inspectDocument, at as stringLiteral, b as isExpression, ct as traverseFast, d as applyEdits, dt as parseExpression, k as isJSXSpreadAttribute, l as fillIdsFrom, n as fillSectionIds, ot as templateElement, p as nanoid, st as templateLiteral, t as createSectionPreviewCache, u as replaceIds, x as isIdentifier } from "./document-uHqw0mvr.js";
2
- import { r as DATA_ATTR, s as RESERVED_BINDING_PROPERTIES, t as BINDING_PROP } from "./constants-st9gnJ5g.js";
1
+ import { C as isJSXElement, D as isJSXIdentifier, E as isJSXFragment, I as isSpreadElement, L as isStringLiteral, N as isObjectExpression, O as isJSXOpeningElement, P as isObjectProperty, S as isJSXAttribute, a as inspectDocument, at as stringLiteral, b as isExpression, ct as traverseFast, d as applyEdits, dt as parseExpression, k as isJSXSpreadAttribute, l as fillIdsFrom, n as fillSectionIds, ot as templateElement, p as nanoid, st as templateLiteral, t as createSectionPreviewCache, u as replaceIds, x as isIdentifier } from "./document-MkQGxfry.js";
2
+ import { i as BINDING_PROP, o as DATA_ATTR, u as RESERVED_BINDING_PROPERTIES } from "./editor-caches-DXYXgWeD.js";
3
3
  import { i as useLiveMessages } from "./messages-DrINcRdG.js";
4
4
  import { i as usePreview } from "./states-Ci1AvoQ9.js";
5
- import { _ as parseArrayExpression, a as getChildrenSignatures, b as generateCode, c as removeIndices, d as getStructuredValue, f as readNodeBindings, g as isLosslesslyEvaluable, h as extractObjectProperties, i as valueToExpression, l as findEditableChildren, m as extractNodeValue, n as updateAll, o as extract, p as canLosslesslyEvaluateSource, r as createNodeFromValue, s as moveSelectedIndices, u as getCurrentValue, v as parseValue } from "./update-BuYQJqjq.js";
6
- import { t as cn } from "./cn-CAnad2vL.js";
7
- import { r as preloadScripts } from "./compile-my0AjsCw.js";
8
- import { a as replaceSections, i as generateSection, r as extractSections } from "./sections-DhH_aVf5.js";
9
- import { n as Error$1, t as ErrorBoundary } from "./boundary-CySnDUs2.js";
10
- import { a as renderStableComponent, n as useCompiledModule, o as Frame, t as useDynamicTailwind } from "./use-dynamic-tailwind-B3l1qZRW.js";
11
- import { i as getFieldKind, n as FieldIdsContext, o as FieldError, r as LABELABLE_KINDS, s as fields_module_default, t as useFieldState } from "./use-field-state-iQGW0vc6.js";
12
- import { t as Core } from "./core-BNVuH8-l.js";
5
+ import { C as parseValue, S as parseArrayExpression, T as generateCode, _ as setEditableValue, a as getChildrenSignatures, b as extractObjectProperties, c as removeIndices, d as getStructuredValue, f as readNodeBindings, g as setEditableSource, h as isEditablePrimitive, i as valueToExpression, l as findEditableChildren, m as getEditableSource, n as updateAll, o as extract, r as createNodeFromValue, s as moveSelectedIndices, u as getCurrentValue, v as canLosslesslyEvaluateSource, w as assertJsxParses, x as isLosslesslyEvaluable, y as extractNodeValue } from "./update-DnX2ibYn.js";
6
+ import { a as cn, r as preloadScripts } from "./compile-BWZ5U59y.js";
7
+ import { a as replaceSections, i as generateSection, r as extractSections } from "./sections-CnG7OLr8.js";
8
+ import { n as Error$1, t as ErrorBoundary } from "./boundary-CLMNMZFa.js";
9
+ import { a as renderStableComponent, n as useCompiledModule, o as Frame, s as useIsClient, t as useDynamicTailwind } from "./use-dynamic-tailwind-CjXeHjsr.js";
10
+ import { i as getFieldKind, n as FieldIdsContext, o as FieldError, r as LABELABLE_KINDS, s as fields_module_default, t as useFieldState } from "./use-field-state-B1VLhWfr.js";
11
+ import { t as Core } from "./core-BfJwD8Jx.js";
13
12
  import { Children, createContext, memo, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
14
13
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
15
14
  import { DndContext, DragOverlay, KeyboardSensor, MouseSensor, PointerSensor, TouchSensor, closestCenter, useDndContext, useDraggable, useDroppable, useSensor, useSensors } from "@dnd-kit/core";
@@ -1092,8 +1091,9 @@ const SectionFallback = ({ args, builtin }) => {
1092
1091
  };
1093
1092
  //#endregion
1094
1093
  //#region src/components/dnd/canvas/renderer.tsx
1095
- const Renderer = ({ preview, sectionId = "", sectionName = "", sectionCode = preview, forceFallback = false, headers, modules, frame, dynamicTailwind = false, provider }) => {
1096
- const module = useCompiledModule(forceFallback ? "" : preview, modules);
1094
+ const Renderer = ({ preview, sectionId = "", sectionName = "", sectionCode = preview, forceFallback = false, componentProps, modules, frame, dynamicTailwind = false, provider }) => {
1095
+ const isClient = useIsClient();
1096
+ const module = useCompiledModule(forceFallback || !isClient ? "" : preview, modules);
1097
1097
  const section = {
1098
1098
  id: sectionId,
1099
1099
  name: sectionName,
@@ -1152,7 +1152,7 @@ const Renderer = ({ preview, sectionId = "", sectionName = "", sectionCode = pre
1152
1152
  })
1153
1153
  }),
1154
1154
  children: renderProvider(/* @__PURE__ */ jsxs(Fragment, { children: [renderStableComponent(Component, preview, {
1155
- headers,
1155
+ ...componentProps,
1156
1156
  container
1157
1157
  }), dynamicTailwind && dynamicCSS && /* @__PURE__ */ jsx("style", { children: dynamicCSS })] }))
1158
1158
  })
@@ -1174,25 +1174,29 @@ const sameFrame = (a, b) => {
1174
1174
  return [.../* @__PURE__ */ new Set([...Object.keys(a), ...Object.keys(b)])].every((key) => sameValue(a[key], b[key]));
1175
1175
  };
1176
1176
  const arePropsEqual = (prev, next) => {
1177
- return [.../* @__PURE__ */ new Set([...Object.keys(prev), ...Object.keys(next)])].every((key) => key === "frame" ? sameFrame(prev.frame, next.frame) : Object.is(prev[key], next[key]));
1177
+ return [.../* @__PURE__ */ new Set([...Object.keys(prev), ...Object.keys(next)])].every((key) => {
1178
+ if (key === "frame") return sameFrame(prev.frame, next.frame);
1179
+ if (key === "componentProps") return sameValue(prev.componentProps, next.componentProps);
1180
+ return Object.is(prev[key], next[key]);
1181
+ });
1178
1182
  };
1179
1183
  var renderer_default = memo(Renderer, arePropsEqual);
1180
1184
  //#endregion
1181
- //#region src/components/dnd/button.module.css
1185
+ //#region src/components/chrome/button.module.css
1182
1186
  var button_module_default = {
1183
- "button": "_49iObG_button",
1184
- "circle": "_49iObG_circle",
1185
- "danger": "_49iObG_danger",
1186
- "iconOnly": "_49iObG_iconOnly",
1187
- "outlined": "_49iObG_outlined",
1188
- "primary": "_49iObG_primary",
1189
- "small": "_49iObG_small",
1190
- "solid": "_49iObG_solid",
1191
- "success": "_49iObG_success",
1192
- "text": "_49iObG_text"
1187
+ "button": "d70MaW_button",
1188
+ "circle": "d70MaW_circle",
1189
+ "danger": "d70MaW_danger",
1190
+ "iconOnly": "d70MaW_iconOnly",
1191
+ "outlined": "d70MaW_outlined",
1192
+ "primary": "d70MaW_primary",
1193
+ "small": "d70MaW_small",
1194
+ "solid": "d70MaW_solid",
1195
+ "success": "d70MaW_success",
1196
+ "text": "d70MaW_text"
1193
1197
  };
1194
1198
  //#endregion
1195
- //#region src/components/dnd/button.tsx
1199
+ //#region src/components/chrome/button.tsx
1196
1200
  const Button = ({ variant = "outlined", tone = "neutral", size = "middle", shape = "default", icon, className, children, ...restProps }) => /* @__PURE__ */ jsxs("button", {
1197
1201
  type: "button",
1198
1202
  className: cn(button_module_default.button, button_module_default[variant], tone !== "neutral" && button_module_default[tone], size === "small" && button_module_default.small, shape === "circle" && button_module_default.circle, icon && !children && button_module_default.iconOnly, className),
@@ -1234,6 +1238,16 @@ const Sortable = ({ id, children, selected, onClick, onDelete, onCopy, onMoveUp,
1234
1238
  onClick?.();
1235
1239
  return;
1236
1240
  }
1241
+ if (e.altKey && (e.key === "ArrowUp" || e.key === "ArrowDown") && handlers) {
1242
+ e.preventDefault();
1243
+ handlers.onMoveKey(id, e.key === "ArrowUp" ? "up" : "down");
1244
+ return;
1245
+ }
1246
+ if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "d" && handlers) {
1247
+ e.preventDefault();
1248
+ handlers.onCopyKey(id);
1249
+ return;
1250
+ }
1237
1251
  const to = NAVIGATION_KEYS[e.key];
1238
1252
  if (to && handlers) {
1239
1253
  e.preventDefault();
@@ -1325,22 +1339,23 @@ const Overlay = ({ sections, isForced, renderProps }) => {
1325
1339
  forceFallback: isForced?.(section) ?? false,
1326
1340
  modules: renderProps.modules,
1327
1341
  frame: renderProps.frame,
1328
- dynamicTailwind: renderProps.dynamicTailwind
1342
+ dynamicTailwind: renderProps.dynamicTailwind,
1343
+ componentProps: renderProps.componentProps
1329
1344
  })
1330
1345
  });
1331
1346
  }
1332
1347
  return null;
1333
1348
  };
1334
1349
  //#endregion
1335
- //#region src/components/dnd/toast.module.css
1350
+ //#region src/components/chrome/toast.module.css
1336
1351
  var toast_module_default = {
1337
- "description": "YlF_3q_description",
1338
- "region": "YlF_3q_region",
1339
- "title": "YlF_3q_title",
1340
- "toast": "YlF_3q_toast"
1352
+ "description": "zcJzfW_description",
1353
+ "region": "zcJzfW_region",
1354
+ "title": "zcJzfW_title",
1355
+ "toast": "zcJzfW_toast"
1341
1356
  };
1342
1357
  //#endregion
1343
- //#region src/components/dnd/toast.ts
1358
+ //#region src/components/chrome/toast.ts
1344
1359
  const TOAST_DURATION = 6e3;
1345
1360
  let region = null;
1346
1361
  const getRegion = () => {
@@ -1436,17 +1451,17 @@ const viewportRect = (element) => {
1436
1451
  return new DOMRect(x, y, rect.width, rect.height);
1437
1452
  };
1438
1453
  //#endregion
1439
- //#region src/components/dnd/drawer.module.css
1454
+ //#region src/components/chrome/drawer.module.css
1440
1455
  var drawer_module_default = {
1441
- "body": "_ty1rG_body",
1442
- "content": "_ty1rG_content",
1443
- "drawer": "_ty1rG_drawer",
1444
- "header": "_ty1rG_header",
1445
- "slide-up": "_ty1rG_slide-up",
1446
- "title": "_ty1rG_title"
1456
+ "body": "SoEwJW_body",
1457
+ "content": "SoEwJW_content",
1458
+ "drawer": "SoEwJW_drawer",
1459
+ "header": "SoEwJW_header",
1460
+ "slide-up": "SoEwJW_slide-up",
1461
+ "title": "SoEwJW_title"
1447
1462
  };
1448
1463
  //#endregion
1449
- //#region src/components/dnd/drawer.tsx
1464
+ //#region src/components/chrome/drawer.tsx
1450
1465
  const Drawer = ({ open, title, closeLabel, onClose, children }) => {
1451
1466
  const titleId = useId();
1452
1467
  const dialogRef = useRef(null);
@@ -1495,6 +1510,121 @@ const Drawer = ({ open, title, closeLabel, onClose, children }) => {
1495
1510
  });
1496
1511
  };
1497
1512
  //#endregion
1513
+ //#region src/components/chrome/split-panes.module.css
1514
+ var split_panes_module_default = {
1515
+ "center": "Z4yoxa_center",
1516
+ "container": "Z4yoxa_container",
1517
+ "handle": "Z4yoxa_handle",
1518
+ "pane": "Z4yoxa_pane"
1519
+ };
1520
+ //#endregion
1521
+ //#region src/components/chrome/split-panes.tsx
1522
+ const DEFAULT_SIZE = 20;
1523
+ const MIN_SIZE = 15;
1524
+ const MAX_SIZE = 35;
1525
+ const KEYBOARD_STEP = 2;
1526
+ const clampSize = (size) => {
1527
+ if (size < MIN_SIZE / 2) return 0;
1528
+ return Math.min(MAX_SIZE, Math.max(MIN_SIZE, size));
1529
+ };
1530
+ const SplitPanes = ({ start, center, end, labels }) => {
1531
+ const containerRef = useRef(null);
1532
+ const [sizes, setSizes] = useState({
1533
+ start: DEFAULT_SIZE,
1534
+ end: DEFAULT_SIZE
1535
+ });
1536
+ const restoreRef = useRef({
1537
+ start: DEFAULT_SIZE,
1538
+ end: DEFAULT_SIZE
1539
+ });
1540
+ const resize = (side, size) => {
1541
+ if (size > 0) restoreRef.current[side] = size;
1542
+ setSizes((prev) => ({
1543
+ ...prev,
1544
+ [side]: size
1545
+ }));
1546
+ };
1547
+ const onPointerDown = (side) => (e) => {
1548
+ const container = containerRef.current;
1549
+ if (!container || e.button !== 0) return;
1550
+ e.preventDefault();
1551
+ const handle = e.currentTarget;
1552
+ const width = container.getBoundingClientRect().width;
1553
+ const startX = e.clientX;
1554
+ const startSize = sizes[side];
1555
+ handle.setPointerCapture(e.pointerId);
1556
+ const onMove = (move) => {
1557
+ const delta = (move.clientX - startX) / width * 100;
1558
+ resize(side, clampSize(startSize + (side === "start" ? delta : -delta)));
1559
+ };
1560
+ const onUp = () => {
1561
+ handle.removeEventListener("pointermove", onMove);
1562
+ handle.removeEventListener("pointerup", onUp);
1563
+ handle.removeEventListener("pointercancel", onUp);
1564
+ };
1565
+ handle.addEventListener("pointermove", onMove);
1566
+ handle.addEventListener("pointerup", onUp);
1567
+ handle.addEventListener("pointercancel", onUp);
1568
+ };
1569
+ const onKeyDown = (side) => (e) => {
1570
+ const grow = side === "start" ? "ArrowRight" : "ArrowLeft";
1571
+ const shrink = side === "start" ? "ArrowLeft" : "ArrowRight";
1572
+ const size = sizes[side];
1573
+ if (e.key === grow || e.key === shrink) {
1574
+ e.preventDefault();
1575
+ const step = e.key === grow ? KEYBOARD_STEP : -2;
1576
+ resize(side, Math.min(MAX_SIZE, Math.max(MIN_SIZE, size + step)));
1577
+ return;
1578
+ }
1579
+ if (e.key === "Home" || e.key === "End") {
1580
+ e.preventDefault();
1581
+ resize(side, e.key === "Home" ? MIN_SIZE : MAX_SIZE);
1582
+ return;
1583
+ }
1584
+ if (e.key === "Enter") {
1585
+ e.preventDefault();
1586
+ resize(side, size > 0 ? 0 : restoreRef.current[side]);
1587
+ }
1588
+ };
1589
+ const handle = (side) => /* @__PURE__ */ jsx("div", {
1590
+ role: "separator",
1591
+ tabIndex: 0,
1592
+ "aria-orientation": "vertical",
1593
+ "aria-label": labels[side],
1594
+ "aria-valuenow": Math.round(sizes[side]),
1595
+ "aria-valuemin": 0,
1596
+ "aria-valuemax": MAX_SIZE,
1597
+ className: split_panes_module_default.handle,
1598
+ onPointerDown: onPointerDown(side),
1599
+ onKeyDown: onKeyDown(side),
1600
+ onDoubleClick: () => resize(side, sizes[side] > 0 ? 0 : restoreRef.current[side])
1601
+ });
1602
+ return /* @__PURE__ */ jsxs("div", {
1603
+ ref: containerRef,
1604
+ className: split_panes_module_default.container,
1605
+ children: [
1606
+ /* @__PURE__ */ jsx("div", {
1607
+ className: split_panes_module_default.pane,
1608
+ style: { flexBasis: `${sizes.start}%` },
1609
+ hidden: sizes.start === 0,
1610
+ children: start
1611
+ }),
1612
+ handle("start"),
1613
+ /* @__PURE__ */ jsx("div", {
1614
+ className: split_panes_module_default.center,
1615
+ children: center
1616
+ }),
1617
+ handle("end"),
1618
+ /* @__PURE__ */ jsx("div", {
1619
+ className: split_panes_module_default.pane,
1620
+ style: { flexBasis: `${sizes.end}%` },
1621
+ hidden: sizes.end === 0,
1622
+ children: end
1623
+ })
1624
+ ]
1625
+ });
1626
+ };
1627
+ //#endregion
1498
1628
  //#region src/components/dnd/layout-context.ts
1499
1629
  const DndRegionContext = createContext(null);
1500
1630
  const useDndRegions = (subject) => {
@@ -2016,10 +2146,14 @@ const ColorField = ({ value: source, onChange, ...controlProps }) => {
2016
2146
  //#endregion
2017
2147
  //#region src/components/dnd/panel/fields/jsx-editor-field.tsx
2018
2148
  const JSXEditorField = ({ value, isHTML, onSave }) => {
2149
+ const onSaveRef = useLatest(onSave);
2150
+ const wrapperRef = useRef(null);
2019
2151
  const selectionRef = useRef(null);
2020
2152
  const focusedRef = useRef(false);
2153
+ const textRef = useRef(value);
2021
2154
  const handleUpdate = useCallback((update) => {
2022
2155
  selectionRef.current = update.state.selection;
2156
+ if (update.docChanged) textRef.current = update.state.doc.toString();
2023
2157
  }, []);
2024
2158
  const handleCreateEditor = useCallback((view) => {
2025
2159
  if (selectionRef.current) view.dispatch({ selection: selectionRef.current });
@@ -2030,8 +2164,14 @@ const JSXEditorField = ({ value, isHTML, onSave }) => {
2030
2164
  }, []);
2031
2165
  const handleBlur = useCallback((event) => {
2032
2166
  if (event.relatedTarget && !event.currentTarget.contains(event.relatedTarget)) focusedRef.current = false;
2033
- }, []);
2167
+ setTimeout(() => {
2168
+ const wrapper = wrapperRef.current;
2169
+ if (!wrapper || wrapper.contains(document.activeElement)) return;
2170
+ onSaveRef.current(textRef.current);
2171
+ }, 0);
2172
+ }, [onSaveRef]);
2034
2173
  return /* @__PURE__ */ jsx("div", {
2174
+ ref: wrapperRef,
2035
2175
  onFocusCapture: handleFocus,
2036
2176
  onBlurCapture: handleBlur,
2037
2177
  children: /* @__PURE__ */ jsx(Core, {
@@ -2955,6 +3095,15 @@ const BuiltinField = ({ binding, onNodeChange }) => {
2955
3095
  });
2956
3096
  if (kind === "object") {
2957
3097
  const objectValue = value;
3098
+ const commitKey = (key, next) => {
3099
+ const current = objectValue[key];
3100
+ if (Object.is(next, current)) return;
3101
+ const edited = isEditablePrimitive(next) && isEditablePrimitive(current) ? setEditableValue(rawValue, [key], next) : typeof next === "string" && typeof current === "object" && current !== null ? setEditableSource(rawValue, [key], next) : null;
3102
+ onChange(edited !== null && edited !== rawValue ? edited : {
3103
+ ...objectValue,
3104
+ [key]: next
3105
+ });
3106
+ };
2958
3107
  return /* @__PURE__ */ jsx("div", {
2959
3108
  className: fields_module_default.object,
2960
3109
  children: Object.entries(objectValue).map(([key, val]) => {
@@ -2973,13 +3122,8 @@ const BuiltinField = ({ binding, onNodeChange }) => {
2973
3122
  ...toBindingFields(nested),
2974
3123
  id,
2975
3124
  value: val,
2976
- rawValue: typeof val === "object" && val !== null ? JSON.stringify(val) : String(val),
2977
- onChange: (next) => {
2978
- onChange({
2979
- ...objectValue,
2980
- [key]: next
2981
- });
2982
- }
3125
+ rawValue: typeof val === "object" && val !== null ? getEditableSource(rawValue, [key]) ?? JSON.stringify(val) : String(val),
3126
+ onChange: (next) => commitKey(key, next)
2983
3127
  },
2984
3128
  onNodeChange
2985
3129
  })
@@ -3249,121 +3393,6 @@ const Panel$1 = ({ item, onDelete, onMoveUp, onMoveDown, canMoveUp = false, canM
3249
3393
  });
3250
3394
  };
3251
3395
  //#endregion
3252
- //#region src/components/dnd/split-panes.module.css
3253
- var split_panes_module_default = {
3254
- "center": "s-4F9W_center",
3255
- "container": "s-4F9W_container",
3256
- "handle": "s-4F9W_handle",
3257
- "pane": "s-4F9W_pane"
3258
- };
3259
- //#endregion
3260
- //#region src/components/dnd/split-panes.tsx
3261
- const DEFAULT_SIZE = 20;
3262
- const MIN_SIZE = 15;
3263
- const MAX_SIZE = 35;
3264
- const KEYBOARD_STEP = 2;
3265
- const clampSize = (size) => {
3266
- if (size < MIN_SIZE / 2) return 0;
3267
- return Math.min(MAX_SIZE, Math.max(MIN_SIZE, size));
3268
- };
3269
- const SplitPanes = ({ start, center, end, labels }) => {
3270
- const containerRef = useRef(null);
3271
- const [sizes, setSizes] = useState({
3272
- start: DEFAULT_SIZE,
3273
- end: DEFAULT_SIZE
3274
- });
3275
- const restoreRef = useRef({
3276
- start: DEFAULT_SIZE,
3277
- end: DEFAULT_SIZE
3278
- });
3279
- const resize = (side, size) => {
3280
- if (size > 0) restoreRef.current[side] = size;
3281
- setSizes((prev) => ({
3282
- ...prev,
3283
- [side]: size
3284
- }));
3285
- };
3286
- const onPointerDown = (side) => (e) => {
3287
- const container = containerRef.current;
3288
- if (!container || e.button !== 0) return;
3289
- e.preventDefault();
3290
- const handle = e.currentTarget;
3291
- const width = container.getBoundingClientRect().width;
3292
- const startX = e.clientX;
3293
- const startSize = sizes[side];
3294
- handle.setPointerCapture(e.pointerId);
3295
- const onMove = (move) => {
3296
- const delta = (move.clientX - startX) / width * 100;
3297
- resize(side, clampSize(startSize + (side === "start" ? delta : -delta)));
3298
- };
3299
- const onUp = () => {
3300
- handle.removeEventListener("pointermove", onMove);
3301
- handle.removeEventListener("pointerup", onUp);
3302
- handle.removeEventListener("pointercancel", onUp);
3303
- };
3304
- handle.addEventListener("pointermove", onMove);
3305
- handle.addEventListener("pointerup", onUp);
3306
- handle.addEventListener("pointercancel", onUp);
3307
- };
3308
- const onKeyDown = (side) => (e) => {
3309
- const grow = side === "start" ? "ArrowRight" : "ArrowLeft";
3310
- const shrink = side === "start" ? "ArrowLeft" : "ArrowRight";
3311
- const size = sizes[side];
3312
- if (e.key === grow || e.key === shrink) {
3313
- e.preventDefault();
3314
- const step = e.key === grow ? KEYBOARD_STEP : -2;
3315
- resize(side, Math.min(MAX_SIZE, Math.max(MIN_SIZE, size + step)));
3316
- return;
3317
- }
3318
- if (e.key === "Home" || e.key === "End") {
3319
- e.preventDefault();
3320
- resize(side, e.key === "Home" ? MIN_SIZE : MAX_SIZE);
3321
- return;
3322
- }
3323
- if (e.key === "Enter") {
3324
- e.preventDefault();
3325
- resize(side, size > 0 ? 0 : restoreRef.current[side]);
3326
- }
3327
- };
3328
- const handle = (side) => /* @__PURE__ */ jsx("div", {
3329
- role: "separator",
3330
- tabIndex: 0,
3331
- "aria-orientation": "vertical",
3332
- "aria-label": labels[side],
3333
- "aria-valuenow": Math.round(sizes[side]),
3334
- "aria-valuemin": 0,
3335
- "aria-valuemax": MAX_SIZE,
3336
- className: split_panes_module_default.handle,
3337
- onPointerDown: onPointerDown(side),
3338
- onKeyDown: onKeyDown(side),
3339
- onDoubleClick: () => resize(side, sizes[side] > 0 ? 0 : restoreRef.current[side])
3340
- });
3341
- return /* @__PURE__ */ jsxs("div", {
3342
- ref: containerRef,
3343
- className: split_panes_module_default.container,
3344
- children: [
3345
- /* @__PURE__ */ jsx("div", {
3346
- className: split_panes_module_default.pane,
3347
- style: { flexBasis: `${sizes.start}%` },
3348
- hidden: sizes.start === 0,
3349
- children: start
3350
- }),
3351
- handle("start"),
3352
- /* @__PURE__ */ jsx("div", {
3353
- className: split_panes_module_default.center,
3354
- children: center
3355
- }),
3356
- handle("end"),
3357
- /* @__PURE__ */ jsx("div", {
3358
- className: split_panes_module_default.pane,
3359
- style: { flexBasis: `${sizes.end}%` },
3360
- hidden: sizes.end === 0,
3361
- children: end
3362
- })
3363
- ]
3364
- });
3365
- };
3366
- //#endregion
3367
3396
  //#region src/components/dnd/layout.tsx
3368
3397
  const PaletteItems = ({ subject }) => {
3369
3398
  const { palette: { items, onAdd }, isMobile } = useDndRegions(subject);
@@ -3605,7 +3634,7 @@ const createNodeRegistry = () => {
3605
3634
  }
3606
3635
  };
3607
3636
  };
3608
- const useDndKeyboard = ({ sections, selectedId, selectedIndex, selectOnly, move, requestDelete }) => {
3637
+ const useDndKeyboard = ({ sections, selectedId, selectedIndex, selectOnly, move, copy, requestDelete }) => {
3609
3638
  const { announcements: say } = useLiveMessages();
3610
3639
  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 10 } }), useSensor(KeyboardSensor, {
3611
3640
  coordinateGetter: sortableKeyboardCoordinates,
@@ -3643,6 +3672,23 @@ const useDndKeyboard = ({ sections, selectedId, selectedIndex, selectOnly, move,
3643
3672
  move(id, direction);
3644
3673
  if (to === 0 || to === sections.length - 1) focusSection(id);
3645
3674
  };
3675
+ const focusSelectedRef = useRef(false);
3676
+ const onMoveKey = (id, direction) => {
3677
+ const to = sections.findIndex((section) => section.id === id) + (direction === "up" ? -1 : 1);
3678
+ if (to < 0 || to >= sections.length) return;
3679
+ selectOnly(id);
3680
+ move(id, direction);
3681
+ focusSelectedRef.current = true;
3682
+ };
3683
+ const onCopyKey = (id) => {
3684
+ copy(id);
3685
+ focusSelectedRef.current = true;
3686
+ };
3687
+ useEffect(() => {
3688
+ if (!focusSelectedRef.current || selectedId === null) return;
3689
+ focusSelectedRef.current = false;
3690
+ focusSection(selectedId);
3691
+ });
3646
3692
  useEffect(() => {
3647
3693
  if (selectedId === null) return;
3648
3694
  const frame = requestAnimationFrame(() => {
@@ -3661,6 +3707,8 @@ const useDndKeyboard = ({ sections, selectedId, selectedIndex, selectOnly, move,
3661
3707
  sectionNodes,
3662
3708
  onNavigate,
3663
3709
  onDeleteKey,
3710
+ onMoveKey,
3711
+ onCopyKey,
3664
3712
  onMoveButton
3665
3713
  };
3666
3714
  };
@@ -3942,6 +3990,24 @@ const useSectionEditing = ({ selectedSection, stale, problem, missingContainer,
3942
3990
  });
3943
3991
  return;
3944
3992
  }
3993
+ try {
3994
+ assertJsxParses(result.code);
3995
+ } catch (error) {
3996
+ const { id, label, property } = changes[0];
3997
+ const failure = {
3998
+ reason: "parse-error",
3999
+ error
4000
+ };
4001
+ reportError({
4002
+ type: "update",
4003
+ id,
4004
+ label,
4005
+ property,
4006
+ failure,
4007
+ ...describeUpdateFailure(failure, label, messages)
4008
+ });
4009
+ return;
4010
+ }
3945
4011
  if (selectedSection) onChange({
3946
4012
  ...selectedSection,
3947
4013
  code: result.code
@@ -3981,6 +4047,7 @@ const Dnd$1 = ({ value: _value, props, modules: _modules = NO_MODULES, onChange:
3981
4047
  const modules = useStableValue(_modules);
3982
4048
  const [mobilePaletteOpen, setMobilePaletteOpen] = useState(false);
3983
4049
  const { breakpoint } = useResponsiveSize();
4050
+ const dndContextId = useId();
3984
4051
  const isMobile = breakpoint.current === "xs" || breakpoint.current === "sm";
3985
4052
  const { code } = usePreview();
3986
4053
  const isForced = (section) => {
@@ -4017,12 +4084,13 @@ const Dnd$1 = ({ value: _value, props, modules: _modules = NO_MODULES, onChange:
4017
4084
  onBeforeDelete
4018
4085
  });
4019
4086
  const onDelete = (id) => requestDelete(id);
4020
- const { sensors, announcements, screenReaderInstructions, sectionNodes, onNavigate, onDeleteKey, onMoveButton } = useDndKeyboard({
4087
+ const { sensors, announcements, screenReaderInstructions, sectionNodes, onNavigate, onDeleteKey, onMoveKey, onCopyKey, onMoveButton } = useDndKeyboard({
4021
4088
  sections,
4022
4089
  selectedId,
4023
4090
  selectedIndex,
4024
4091
  selectOnly,
4025
4092
  move: moveSection,
4093
+ copy: onCopy,
4026
4094
  requestDelete
4027
4095
  });
4028
4096
  const { inspector, inspecting, onInspectMove, onInspectPick, onInspectLeave, highlightRect } = useInspectorState({
@@ -4082,7 +4150,9 @@ const Dnd$1 = ({ value: _value, props, modules: _modules = NO_MODULES, onChange:
4082
4150
  onInspectLeave,
4083
4151
  nodeRef: sectionNodes.register,
4084
4152
  onNavigate,
4085
- onDeleteKey
4153
+ onDeleteKey,
4154
+ onMoveKey,
4155
+ onCopyKey
4086
4156
  };
4087
4157
  const canvas = /* @__PURE__ */ jsxs(SectionHandlersContext.Provider, {
4088
4158
  value: sectionHandlers,
@@ -4121,7 +4191,7 @@ const Dnd$1 = ({ value: _value, props, modules: _modules = NO_MODULES, onChange:
4121
4191
  frame,
4122
4192
  dynamicTailwind,
4123
4193
  provider,
4124
- ...props
4194
+ componentProps: props
4125
4195
  })
4126
4196
  }, section.id))
4127
4197
  })
@@ -4132,6 +4202,7 @@ const Dnd$1 = ({ value: _value, props, modules: _modules = NO_MODULES, onChange:
4132
4202
  return /* @__PURE__ */ jsx(SectionFallbackContext.Provider, {
4133
4203
  value: renderSectionFallback,
4134
4204
  children: /* @__PURE__ */ jsxs(DndContext, {
4205
+ id: dndContextId,
4135
4206
  sensors,
4136
4207
  collisionDetection: closestCenter,
4137
4208
  accessibility: {
@@ -4175,7 +4246,7 @@ const Dnd$1 = ({ value: _value, props, modules: _modules = NO_MODULES, onChange:
4175
4246
  modules,
4176
4247
  frame,
4177
4248
  dynamicTailwind,
4178
- ...props,
4249
+ componentProps: props,
4179
4250
  containerId
4180
4251
  }
4181
4252
  }) })]
@@ -4194,4 +4265,4 @@ Dnd.Layout = Layout;
4194
4265
  //#endregion
4195
4266
  export { Panel as a, useDndChildren as c, useDndLayout as d, useDndPalette as f, DraggableItem as h, Palette as i, resolvePanelBindings as l, useDndInspector as m, Canvas as n, Field as o, useDndPanel as p, Layout as r, useDndItems as s, Dnd as t, withPanelCommit as u };
4196
4267
 
4197
- //# sourceMappingURL=dnd-BvjEDo-x.js.map
4268
+ //# sourceMappingURL=dnd-DAGjlJ0_.js.map