@visual-json/react 0.2.0 → 0.3.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.
package/dist/index.js CHANGED
@@ -39,20 +39,11 @@ var import_react10 = require("react");
39
39
 
40
40
  // src/visual-json.tsx
41
41
  var import_react2 = require("react");
42
- var import_core2 = require("@visual-json/core");
43
-
44
- // src/context.ts
45
- var import_react = require("react");
46
- var StudioContext = (0, import_react.createContext)(null);
47
- function useStudio() {
48
- const ctx = (0, import_react.useContext)(StudioContext);
49
- if (!ctx) {
50
- throw new Error("useStudio must be used within a <VisualJson> provider");
51
- }
52
- return ctx;
53
- }
42
+ var import_core4 = require("@visual-json/core");
54
43
 
55
- // src/get-visible-nodes.ts
44
+ // ../../@internal/ui/dist/index.mjs
45
+ var import_core = require("@visual-json/core");
46
+ var import_core2 = require("@visual-json/core");
56
47
  function getVisibleNodes(root, isExpanded) {
57
48
  const result = [];
58
49
  function walk(node) {
@@ -66,9 +57,171 @@ function getVisibleNodes(root, isExpanded) {
66
57
  walk(root);
67
58
  return result;
68
59
  }
60
+ var LABEL_FIELDS = ["name", "type", "title", "id", "label", "key"];
61
+ function getDisplayKey(node, state) {
62
+ if (node.parentId === null) return "/";
63
+ const parent = state.nodesById.get(node.parentId);
64
+ if (parent?.type !== "array" || node.type !== "object") return node.key;
65
+ for (const field of LABEL_FIELDS) {
66
+ const child = node.children.find((c) => c.key === field);
67
+ if (child?.value != null && child.value !== "") {
68
+ return String(child.value);
69
+ }
70
+ }
71
+ return node.key;
72
+ }
73
+ function collectAllIds(node) {
74
+ const ids = [node.id];
75
+ for (const child of node.children) {
76
+ ids.push(...collectAllIds(child));
77
+ }
78
+ return ids;
79
+ }
80
+ var DEFAULT_CSS_VARS = {
81
+ "--vj-bg": "#1e1e1e",
82
+ "--vj-bg-panel": "#252526",
83
+ "--vj-bg-hover": "#2a2d2e",
84
+ "--vj-bg-selected": "#2a5a1e",
85
+ "--vj-bg-selected-muted": "#2a2d2e",
86
+ "--vj-bg-match": "#3a3520",
87
+ "--vj-bg-match-active": "#51502b",
88
+ "--vj-border": "#333333",
89
+ "--vj-border-subtle": "#2a2a2a",
90
+ "--vj-text": "#cccccc",
91
+ "--vj-text-muted": "#888888",
92
+ "--vj-text-dim": "#666666",
93
+ "--vj-text-dimmer": "#555555",
94
+ "--vj-string": "#ce9178",
95
+ "--vj-number": "#b5cea8",
96
+ "--vj-boolean": "#569cd6",
97
+ "--vj-accent": "#007acc",
98
+ "--vj-accent-muted": "#094771",
99
+ "--vj-input-bg": "#3c3c3c",
100
+ "--vj-input-border": "#555555",
101
+ "--vj-error": "#f48771",
102
+ "--vj-font": "monospace",
103
+ "--vj-input-font-size": "13px"
104
+ };
105
+ var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
106
+ function sortByTreeOrder(root, ids) {
107
+ const result = [];
108
+ function walk(node) {
109
+ if (ids.has(node.id)) result.push(node.id);
110
+ for (const child of node.children) walk(child);
111
+ }
112
+ walk(root);
113
+ return result;
114
+ }
115
+ function computeDrop(tree, drag) {
116
+ const { draggedNodeIds, dropTargetNodeId, dropPosition } = drag;
117
+ if (draggedNodeIds.size === 0 || !dropTargetNodeId || !dropPosition)
118
+ return null;
119
+ const targetNode = tree.nodesById.get(dropTargetNodeId);
120
+ if (!targetNode || !targetNode.parentId) return null;
121
+ for (const id of draggedNodeIds) {
122
+ if ((0, import_core.isDescendant)(tree, dropTargetNodeId, id)) return null;
123
+ }
124
+ const targetParentId = targetNode.parentId;
125
+ const targetParent = tree.nodesById.get(targetParentId);
126
+ if (!targetParent) return null;
127
+ const parentChildren = targetParent.children;
128
+ const orderedDragIds = parentChildren.filter((c) => draggedNodeIds.has(c.id)).map((c) => c.id);
129
+ const allSameParent = orderedDragIds.length === draggedNodeIds.size && [...draggedNodeIds].every((id) => {
130
+ const n = tree.nodesById.get(id);
131
+ return n?.parentId === targetParentId;
132
+ });
133
+ if (allSameParent) {
134
+ return (0, import_core.reorderChildrenMulti)(
135
+ tree,
136
+ targetParentId,
137
+ orderedDragIds,
138
+ dropTargetNodeId,
139
+ dropPosition
140
+ );
141
+ }
142
+ const orderedIds = sortByTreeOrder(tree.root, draggedNodeIds);
143
+ const draggedNodes = orderedIds.map((id) => tree.nodesById.get(id)).filter((n) => !!n && n.parentId !== null).map((n) => structuredClone(n));
144
+ let newTree = tree;
145
+ for (const id of [...orderedIds].reverse()) {
146
+ if (newTree.nodesById.has(id)) {
147
+ newTree = (0, import_core.removeNode)(newTree, id);
148
+ }
149
+ }
150
+ const updatedTarget = newTree.nodesById.get(dropTargetNodeId);
151
+ if (!updatedTarget || !updatedTarget.parentId) return null;
152
+ const updatedParent = newTree.nodesById.get(updatedTarget.parentId);
153
+ if (!updatedParent) return null;
154
+ let insertIdx = updatedParent.children.findIndex(
155
+ (c) => c.id === dropTargetNodeId
156
+ );
157
+ if (dropPosition === "after") insertIdx++;
158
+ for (let i = 0; i < draggedNodes.length; i++) {
159
+ newTree = (0, import_core.insertNode)(
160
+ newTree,
161
+ updatedParent.id,
162
+ draggedNodes[i],
163
+ insertIdx + i
164
+ );
165
+ }
166
+ return newTree;
167
+ }
168
+ function setMultiDragImage(dataTransfer, count, rootEl) {
169
+ const ghost = document.createElement("div");
170
+ ghost.textContent = `${count} selected`;
171
+ const root = rootEl ?? document.querySelector("[data-form-container], [role='tree']");
172
+ const cs = root ? getComputedStyle(root) : null;
173
+ const bg = cs?.getPropertyValue("--vj-bg-selected").trim() || DEFAULT_CSS_VARS["--vj-bg-selected"];
174
+ const fg = cs?.getPropertyValue("--vj-text-selected").trim() || cs?.getPropertyValue("--vj-text").trim() || DEFAULT_CSS_VARS["--vj-text"];
175
+ const font = cs?.getPropertyValue("--vj-font").trim() || DEFAULT_CSS_VARS["--vj-font"];
176
+ ghost.style.cssText = [
177
+ "position:fixed",
178
+ "top:-1000px",
179
+ "left:-1000px",
180
+ "padding:4px 12px",
181
+ `background:${bg}`,
182
+ `color:${fg}`,
183
+ `font-family:${font}`,
184
+ "font-size:13px",
185
+ "border-radius:4px",
186
+ "white-space:nowrap",
187
+ "pointer-events:none"
188
+ ].join(";");
189
+ document.body.appendChild(ghost);
190
+ dataTransfer.setDragImage(ghost, 0, 14);
191
+ requestAnimationFrame(() => ghost.remove());
192
+ }
193
+ var DIFF_COLORS = {
194
+ added: { bg: "#1e3a1e", marker: "+", label: "#4ec94e" },
195
+ removed: { bg: "#3a1e1e", marker: "-", label: "#f48771" },
196
+ changed: { bg: "#3a3a1e", marker: "~", label: "#dcdcaa" }
197
+ };
198
+ function formatValue(value) {
199
+ if (value === void 0) return "";
200
+ if (value === null) return "null";
201
+ if (typeof value === "string") return JSON.stringify(value);
202
+ if (typeof value === "object") {
203
+ const json = JSON.stringify(value, null, 2);
204
+ if (json.length > 80) {
205
+ return JSON.stringify(value).slice(0, 77) + "...";
206
+ }
207
+ return json;
208
+ }
209
+ return String(value);
210
+ }
211
+
212
+ // src/context.ts
213
+ var import_react = require("react");
214
+ var StudioContext = (0, import_react.createContext)(null);
215
+ function useStudio() {
216
+ const ctx = (0, import_react.useContext)(StudioContext);
217
+ if (!ctx) {
218
+ throw new Error("useStudio must be used within a <VisualJson> provider");
219
+ }
220
+ return ctx;
221
+ }
69
222
 
70
223
  // src/selection-utils.ts
71
- var import_core = require("@visual-json/core");
224
+ var import_core3 = require("@visual-json/core");
72
225
  function computeSelectAllIds(tree, focusedNodeId, currentlySelected) {
73
226
  if (!focusedNodeId) return null;
74
227
  let node = tree.nodesById.get(focusedNodeId);
@@ -114,7 +267,7 @@ function deleteSelectedNodes(tree, selectedIds, visibleNodes) {
114
267
  let newTree = tree;
115
268
  for (const id of idsToDelete) {
116
269
  if (newTree.nodesById.has(id)) {
117
- newTree = (0, import_core.removeNode)(newTree, id);
270
+ newTree = (0, import_core3.removeNode)(newTree, id);
118
271
  }
119
272
  }
120
273
  let nextFocusId = null;
@@ -139,20 +292,13 @@ function deleteSelectedNodes(tree, selectedIds, visibleNodes) {
139
292
 
140
293
  // src/visual-json.tsx
141
294
  var import_jsx_runtime = require("react/jsx-runtime");
142
- function collectAllIds(node) {
143
- const ids = [node.id];
144
- for (const child of node.children) {
145
- ids.push(...collectAllIds(child));
146
- }
147
- return ids;
148
- }
149
295
  function VisualJson({
150
296
  value,
151
297
  onChange,
152
298
  schema,
153
299
  children
154
300
  }) {
155
- const [tree, setTreeState] = (0, import_react2.useState)(() => (0, import_core2.fromJson)(value));
301
+ const [tree, setTreeState] = (0, import_react2.useState)(() => (0, import_core4.fromJson)(value));
156
302
  const [focusedNodeId, setFocusedNodeId] = (0, import_react2.useState)(null);
157
303
  const [selectedNodeIds, setSelectedNodeIdsState] = (0, import_react2.useState)(
158
304
  () => /* @__PURE__ */ new Set()
@@ -189,7 +335,7 @@ function VisualJson({
189
335
  const setVisibleNodesOverride = (0, import_react2.useCallback)((nodes) => {
190
336
  visibleNodesOverrideRef.current = nodes;
191
337
  }, []);
192
- const historyRef = (0, import_react2.useRef)(new import_core2.History());
338
+ const historyRef = (0, import_react2.useRef)(new import_core4.History());
193
339
  const isInternalChange = (0, import_react2.useRef)(false);
194
340
  const hasMounted = (0, import_react2.useRef)(false);
195
341
  const [canUndo, setCanUndo] = (0, import_react2.useState)(false);
@@ -214,11 +360,11 @@ function VisualJson({
214
360
  isInternalChange.current = false;
215
361
  return;
216
362
  }
217
- const newTree = (0, import_core2.fromJson)(value);
363
+ const newTree = (0, import_core4.fromJson)(value);
218
364
  setTreeState(newTree);
219
365
  setExpandedNodeIds(/* @__PURE__ */ new Set([newTree.root.id]));
220
366
  focusSelectAndDrillDown(null);
221
- historyRef.current = new import_core2.History();
367
+ historyRef.current = new import_core4.History();
222
368
  historyRef.current.push(newTree);
223
369
  setCanUndo(false);
224
370
  setCanRedo(false);
@@ -234,7 +380,7 @@ function VisualJson({
234
380
  setCanUndo(historyRef.current.canUndo);
235
381
  setCanRedo(historyRef.current.canRedo);
236
382
  isInternalChange.current = true;
237
- onChange?.((0, import_core2.toJson)(newTree.root));
383
+ onChange?.((0, import_core4.toJson)(newTree.root));
238
384
  },
239
385
  [onChange]
240
386
  );
@@ -245,7 +391,7 @@ function VisualJson({
245
391
  setCanUndo(historyRef.current.canUndo);
246
392
  setCanRedo(historyRef.current.canRedo);
247
393
  isInternalChange.current = true;
248
- onChange?.((0, import_core2.toJson)(prev.root));
394
+ onChange?.((0, import_core4.toJson)(prev.root));
249
395
  }
250
396
  }, [onChange]);
251
397
  const redo = (0, import_react2.useCallback)(() => {
@@ -255,7 +401,7 @@ function VisualJson({
255
401
  setCanUndo(historyRef.current.canUndo);
256
402
  setCanRedo(historyRef.current.canRedo);
257
403
  isInternalChange.current = true;
258
- onChange?.((0, import_core2.toJson)(next.root));
404
+ onChange?.((0, import_core4.toJson)(next.root));
259
405
  }
260
406
  }, [onChange]);
261
407
  (0, import_react2.useEffect)(() => {
@@ -374,14 +520,14 @@ function VisualJson({
374
520
  setSearchMatchNodeIds(/* @__PURE__ */ new Set());
375
521
  return;
376
522
  }
377
- const matches = (0, import_core2.searchNodes)(tree, query);
523
+ const matches = (0, import_core4.searchNodes)(tree, query);
378
524
  setSearchMatches(matches);
379
525
  setSearchMatchIndex(0);
380
526
  const matchIds = new Set(matches.map((m) => m.nodeId));
381
527
  setSearchMatchNodeIds(matchIds);
382
528
  if (matches.length > 0) {
383
529
  const firstId = matches[0].nodeId;
384
- const ancestors = (0, import_core2.getAncestorIds)(
530
+ const ancestors = (0, import_core4.getAncestorIds)(
385
531
  tree,
386
532
  matches.map((m) => m.nodeId)
387
533
  );
@@ -409,7 +555,7 @@ function VisualJson({
409
555
  }, [searchMatches, searchMatchIndex, focusSelectAndDrillDown]);
410
556
  (0, import_react2.useEffect)(() => {
411
557
  if (!searchQuery.trim()) return;
412
- const matches = (0, import_core2.searchNodes)(tree, searchQuery);
558
+ const matches = (0, import_core4.searchNodes)(tree, searchQuery);
413
559
  setSearchMatches(matches);
414
560
  setSearchMatchIndex(
415
561
  (prev) => Math.min(prev, Math.max(matches.length - 1, 0))
@@ -496,7 +642,7 @@ function VisualJson({
496
642
 
497
643
  // src/tree-view.tsx
498
644
  var import_react5 = require("react");
499
- var import_core4 = require("@visual-json/core");
645
+ var import_core6 = require("@visual-json/core");
500
646
 
501
647
  // src/context-menu.tsx
502
648
  var import_react3 = require("react");
@@ -595,92 +741,17 @@ function ContextMenu({ x, y, items, onClose }) {
595
741
  );
596
742
  }
597
743
 
598
- // src/display-key.ts
599
- var LABEL_FIELDS = ["name", "type", "title", "id", "label", "key"];
600
- function getDisplayKey(node, state) {
601
- if (node.parentId === null) return "/";
602
- const parent = state.nodesById.get(node.parentId);
603
- if (parent?.type !== "array" || node.type !== "object") return node.key;
604
- for (const field of LABEL_FIELDS) {
605
- const child = node.children.find((c) => c.key === field);
606
- if (child?.value != null && child.value !== "") {
607
- return String(child.value);
608
- }
609
- }
610
- return node.key;
611
- }
612
-
613
744
  // src/use-drag-drop.ts
614
745
  var import_react4 = require("react");
615
- var import_core3 = require("@visual-json/core");
616
-
617
- // src/theme.ts
618
- var DEFAULT_CSS_VARS = {
619
- "--vj-bg": "#1e1e1e",
620
- "--vj-bg-panel": "#252526",
621
- "--vj-bg-hover": "#2a2d2e",
622
- "--vj-bg-selected": "#2a5a1e",
623
- "--vj-bg-selected-muted": "#2a2d2e",
624
- "--vj-bg-match": "#3a3520",
625
- "--vj-bg-match-active": "#51502b",
626
- "--vj-border": "#333333",
627
- "--vj-border-subtle": "#2a2a2a",
628
- "--vj-text": "#cccccc",
629
- "--vj-text-muted": "#888888",
630
- "--vj-text-dim": "#666666",
631
- "--vj-text-dimmer": "#555555",
632
- "--vj-string": "#ce9178",
633
- "--vj-number": "#b5cea8",
634
- "--vj-boolean": "#569cd6",
635
- "--vj-accent": "#007acc",
636
- "--vj-accent-muted": "#094771",
637
- "--vj-input-bg": "#3c3c3c",
638
- "--vj-input-border": "#555555",
639
- "--vj-error": "#f48771",
640
- "--vj-font": "monospace",
641
- "--vj-input-font-size": "13px"
642
- };
643
-
644
- // src/use-drag-drop.ts
645
- var EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
746
+ var import_core5 = require("@visual-json/core");
747
+ var EMPTY_SET2 = Object.freeze(/* @__PURE__ */ new Set());
646
748
  var INITIAL_DRAG_STATE = {
647
- draggedNodeIds: EMPTY_SET,
749
+ draggedNodeIds: EMPTY_SET2,
648
750
  dropTargetNodeId: null,
649
751
  dropPosition: null
650
752
  };
651
- function sortByTreeOrder(root, ids) {
652
- const result = [];
653
- function walk(node) {
654
- if (ids.has(node.id)) result.push(node.id);
655
- for (const child of node.children) walk(child);
656
- }
657
- walk(root);
658
- return result;
659
- }
660
- function setMultiDragImage(e, count) {
661
- const ghost = document.createElement("div");
662
- ghost.textContent = `${count} selected`;
663
- const root = document.querySelector("[data-form-container], [role='tree']");
664
- const cs = root ? getComputedStyle(root) : null;
665
- const bg = cs?.getPropertyValue("--vj-bg-selected").trim() || DEFAULT_CSS_VARS["--vj-bg-selected"];
666
- const fg = cs?.getPropertyValue("--vj-text-selected").trim() || cs?.getPropertyValue("--vj-text").trim() || DEFAULT_CSS_VARS["--vj-text"];
667
- const font = cs?.getPropertyValue("--vj-font").trim() || DEFAULT_CSS_VARS["--vj-font"];
668
- ghost.style.cssText = [
669
- "position:fixed",
670
- "top:-1000px",
671
- "left:-1000px",
672
- "padding:4px 12px",
673
- `background:${bg}`,
674
- `color:${fg}`,
675
- `font-family:${font}`,
676
- "font-size:13px",
677
- "border-radius:4px",
678
- "white-space:nowrap",
679
- "pointer-events:none"
680
- ].join(";");
681
- document.body.appendChild(ghost);
682
- e.dataTransfer.setDragImage(ghost, 0, 14);
683
- requestAnimationFrame(() => ghost.remove());
753
+ function setMultiDragImage2(e, count) {
754
+ setMultiDragImage(e.dataTransfer, count);
684
755
  }
685
756
  function useDragDrop(visibleNodes, selectedNodeIds) {
686
757
  const { state, actions } = useStudio();
@@ -712,7 +783,7 @@ function useDragDrop(visibleNodes, selectedNodeIds) {
712
783
  (nodeId, position) => {
713
784
  const draggedIds = dragStateRef.current.draggedNodeIds;
714
785
  for (const draggedId of draggedIds) {
715
- if (nodeId === draggedId || (0, import_core3.isDescendant)(state.tree, nodeId, draggedId)) {
786
+ if (nodeId === draggedId || (0, import_core5.isDescendant)(state.tree, nodeId, draggedId)) {
716
787
  return;
717
788
  }
718
789
  }
@@ -741,62 +812,9 @@ function useDragDrop(visibleNodes, selectedNodeIds) {
741
812
  setDragState(INITIAL_DRAG_STATE);
742
813
  }, []);
743
814
  const handleDrop = (0, import_react4.useCallback)(() => {
744
- const { draggedNodeIds, dropTargetNodeId, dropPosition } = dragStateRef.current;
745
- if (draggedNodeIds.size === 0 || !dropTargetNodeId || !dropPosition) return;
746
- const targetNode = state.tree.nodesById.get(dropTargetNodeId);
747
- if (!targetNode || !targetNode.parentId) return;
748
- for (const id of draggedNodeIds) {
749
- if ((0, import_core3.isDescendant)(state.tree, dropTargetNodeId, id)) return;
750
- }
751
- const targetParentId = targetNode.parentId;
752
- const targetParent = state.tree.nodesById.get(targetParentId);
753
- if (!targetParent) return;
754
- const parentChildren = targetParent.children;
755
- const orderedDragIds = parentChildren.filter((c) => draggedNodeIds.has(c.id)).map((c) => c.id);
756
- const allSameParent = orderedDragIds.length === draggedNodeIds.size && [...draggedNodeIds].every((id) => {
757
- const n = state.tree.nodesById.get(id);
758
- return n?.parentId === targetParentId;
759
- });
760
- if (allSameParent) {
761
- const newTree = (0, import_core3.reorderChildrenMulti)(
762
- state.tree,
763
- targetParentId,
764
- orderedDragIds,
765
- dropTargetNodeId,
766
- dropPosition
767
- );
768
- actions.setTree(newTree);
769
- } else {
770
- const orderedIds = sortByTreeOrder(state.tree.root, draggedNodeIds);
771
- const draggedNodes = orderedIds.map((id) => state.tree.nodesById.get(id)).filter((n) => !!n && n.parentId !== null).map((n) => structuredClone(n));
772
- let newTree = state.tree;
773
- for (const id of [...orderedIds].reverse()) {
774
- if (newTree.nodesById.has(id)) {
775
- newTree = (0, import_core3.removeNode)(newTree, id);
776
- }
777
- }
778
- const updatedTarget = newTree.nodesById.get(dropTargetNodeId);
779
- if (!updatedTarget || !updatedTarget.parentId) {
780
- setDragState(INITIAL_DRAG_STATE);
781
- return;
782
- }
783
- const updatedParent = newTree.nodesById.get(updatedTarget.parentId);
784
- if (!updatedParent) {
785
- setDragState(INITIAL_DRAG_STATE);
786
- return;
787
- }
788
- let insertIdx = updatedParent.children.findIndex(
789
- (c) => c.id === dropTargetNodeId
790
- );
791
- if (dropPosition === "after") insertIdx++;
792
- for (let i = 0; i < draggedNodes.length; i++) {
793
- newTree = (0, import_core3.insertNode)(
794
- newTree,
795
- updatedParent.id,
796
- draggedNodes[i],
797
- insertIdx + i
798
- );
799
- }
815
+ const currentDragState = dragStateRef.current;
816
+ const newTree = computeDrop(state.tree, currentDragState);
817
+ if (newTree) {
800
818
  actions.setTree(newTree);
801
819
  }
802
820
  setDragState(INITIAL_DRAG_STATE);
@@ -881,7 +899,7 @@ function TreeNodeRow({
881
899
  onDragStart: (e) => {
882
900
  e.dataTransfer.effectAllowed = "move";
883
901
  if (state.selectedNodeIds.size > 1 && state.selectedNodeIds.has(node.id)) {
884
- setMultiDragImage(e, state.selectedNodeIds.size);
902
+ setMultiDragImage2(e, state.selectedNodeIds.size);
885
903
  }
886
904
  onDragStart(node.id);
887
905
  },
@@ -1077,7 +1095,7 @@ function TreeView({
1077
1095
  items.push({
1078
1096
  label: "Copy value as JSON",
1079
1097
  action: () => {
1080
- const val = (0, import_core4.toJson)(node);
1098
+ const val = (0, import_core6.toJson)(node);
1081
1099
  const text = typeof val === "string" ? val : JSON.stringify(val, null, 2);
1082
1100
  navigator.clipboard.writeText(text).catch(() => {
1083
1101
  });
@@ -1088,7 +1106,7 @@ function TreeView({
1088
1106
  items.push({
1089
1107
  label: "Duplicate",
1090
1108
  action: () => {
1091
- const newTree = (0, import_core4.duplicateNode)(state.tree, node.id);
1109
+ const newTree = (0, import_core6.duplicateNode)(state.tree, node.id);
1092
1110
  actions.setTree(newTree);
1093
1111
  }
1094
1112
  });
@@ -1102,7 +1120,7 @@ function TreeView({
1102
1120
  ].filter((t) => t !== node.type).map((t) => ({
1103
1121
  label: `Change to ${t}`,
1104
1122
  action: () => {
1105
- const newTree = (0, import_core4.changeType)(state.tree, node.id, t);
1123
+ const newTree = (0, import_core6.changeType)(state.tree, node.id, t);
1106
1124
  actions.setTree(newTree);
1107
1125
  }
1108
1126
  }));
@@ -1112,7 +1130,7 @@ function TreeView({
1112
1130
  items.push({
1113
1131
  label: "Delete",
1114
1132
  action: () => {
1115
- const newTree = (0, import_core4.removeNode)(state.tree, node.id);
1133
+ const newTree = (0, import_core6.removeNode)(state.tree, node.id);
1116
1134
  actions.setTree(newTree);
1117
1135
  }
1118
1136
  });
@@ -1295,7 +1313,7 @@ function TreeView({
1295
1313
 
1296
1314
  // src/form-view.tsx
1297
1315
  var import_react8 = require("react");
1298
- var import_core5 = require("@visual-json/core");
1316
+ var import_core7 = require("@visual-json/core");
1299
1317
 
1300
1318
  // src/breadcrumbs.tsx
1301
1319
  var import_react6 = require("react");
@@ -1650,9 +1668,9 @@ function EnumInput({
1650
1668
  var import_jsx_runtime6 = require("react/jsx-runtime");
1651
1669
  function getResolvedSchema(schema, rootSchema, path) {
1652
1670
  if (!schema) return void 0;
1653
- const raw = (0, import_core5.getPropertySchema)(schema, path, rootSchema);
1671
+ const raw = (0, import_core7.getPropertySchema)(schema, path, rootSchema);
1654
1672
  if (!raw) return void 0;
1655
- return (0, import_core5.resolveRef)(raw, rootSchema ?? schema);
1673
+ return (0, import_core7.resolveRef)(raw, rootSchema ?? schema);
1656
1674
  }
1657
1675
  function getValueColor(node) {
1658
1676
  if (node.type === "boolean" || node.type === "null")
@@ -1739,25 +1757,25 @@ function FormField({
1739
1757
  } else {
1740
1758
  parsed = newValue;
1741
1759
  }
1742
- const newTree = (0, import_core5.setValue)(state.tree, node.id, parsed);
1760
+ const newTree = (0, import_core7.setValue)(state.tree, node.id, parsed);
1743
1761
  actions.setTree(newTree);
1744
1762
  },
1745
1763
  [state.tree, node.id, node.type, actions, propSchema]
1746
1764
  );
1747
1765
  const handleKeyChange = (0, import_react8.useCallback)(
1748
1766
  (newKey) => {
1749
- const newTree = (0, import_core5.setKey)(state.tree, node.id, newKey);
1767
+ const newTree = (0, import_core7.setKey)(state.tree, node.id, newKey);
1750
1768
  actions.setTree(newTree);
1751
1769
  },
1752
1770
  [state.tree, node.id, actions]
1753
1771
  );
1754
1772
  const handleRemove = (0, import_react8.useCallback)(() => {
1755
- const newTree = (0, import_core5.removeNode)(state.tree, node.id);
1773
+ const newTree = (0, import_core7.removeNode)(state.tree, node.id);
1756
1774
  actions.setTree(newTree);
1757
1775
  }, [state.tree, node.id, actions]);
1758
1776
  const handleAddChild = (0, import_react8.useCallback)(() => {
1759
1777
  const key = node.type === "array" ? String(node.children.length) : `newKey${node.children.length}`;
1760
- const newTree = (0, import_core5.addProperty)(state.tree, node.id, key, "");
1778
+ const newTree = (0, import_core7.addProperty)(state.tree, node.id, key, "");
1761
1779
  actions.setTree(newTree);
1762
1780
  }, [state.tree, node.id, node.type, node.children.length, actions]);
1763
1781
  const description = propSchema?.description;
@@ -1776,7 +1794,7 @@ function FormField({
1776
1794
  onDragStart: (e) => {
1777
1795
  e.dataTransfer.effectAllowed = "move";
1778
1796
  if (state.selectedNodeIds.size > 1 && state.selectedNodeIds.has(node.id)) {
1779
- setMultiDragImage(e, state.selectedNodeIds.size);
1797
+ setMultiDragImage2(e, state.selectedNodeIds.size);
1780
1798
  }
1781
1799
  onDragStart(node.id);
1782
1800
  },
@@ -1989,7 +2007,7 @@ function FormField({
1989
2007
  onDragStart: (e) => {
1990
2008
  e.dataTransfer.effectAllowed = "move";
1991
2009
  if (state.selectedNodeIds.size > 1 && state.selectedNodeIds.has(node.id)) {
1992
- setMultiDragImage(e, state.selectedNodeIds.size);
2010
+ setMultiDragImage2(e, state.selectedNodeIds.size);
1993
2011
  }
1994
2012
  onDragStart(node.id);
1995
2013
  },
@@ -3109,26 +3127,8 @@ function EditorLayout({
3109
3127
 
3110
3128
  // src/diff-view.tsx
3111
3129
  var import_react11 = require("react");
3112
- var import_core6 = require("@visual-json/core");
3130
+ var import_core8 = require("@visual-json/core");
3113
3131
  var import_jsx_runtime9 = require("react/jsx-runtime");
3114
- var DIFF_COLORS = {
3115
- added: { bg: "#1e3a1e", marker: "+", label: "#4ec94e" },
3116
- removed: { bg: "#3a1e1e", marker: "-", label: "#f48771" },
3117
- changed: { bg: "#3a3a1e", marker: "~", label: "#dcdcaa" }
3118
- };
3119
- function formatValue(value) {
3120
- if (value === void 0) return "";
3121
- if (value === null) return "null";
3122
- if (typeof value === "string") return JSON.stringify(value);
3123
- if (typeof value === "object") {
3124
- const json = JSON.stringify(value, null, 2);
3125
- if (json.length > 80) {
3126
- return JSON.stringify(value).slice(0, 77) + "...";
3127
- }
3128
- return json;
3129
- }
3130
- return String(value);
3131
- }
3132
3132
  function DiffRow({ entry }) {
3133
3133
  const colors = DIFF_COLORS[entry.type];
3134
3134
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
@@ -3188,7 +3188,7 @@ function DiffView({
3188
3188
  className
3189
3189
  }) {
3190
3190
  const entries = (0, import_react11.useMemo)(
3191
- () => (0, import_core6.computeDiff)(originalJson, currentJson),
3191
+ () => (0, import_core8.computeDiff)(originalJson, currentJson),
3192
3192
  [originalJson, currentJson]
3193
3193
  );
3194
3194
  const added = entries.filter((e) => e.type === "added").length;