@kubuild/editor 0.1.0 → 0.1.3
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/blocks-panel.d.ts.map +1 -1
- package/dist/canvas.d.ts.map +1 -1
- package/dist/component-panel.d.ts.map +1 -1
- package/dist/editor.d.ts.map +1 -1
- package/dist/index.cjs +547 -148
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +554 -147
- package/dist/index.js.map +1 -1
- package/dist/layers-panel.d.ts.map +1 -1
- package/dist/store.d.ts +15 -2
- package/dist/store.d.ts.map +1 -1
- package/dist/table-spreadsheet-editor.d.ts.map +1 -1
- package/dist/toolbar.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
// src/editor.tsx
|
|
2
|
-
import React19, { useEffect as useEffect10, useMemo as useMemo4 } from "react";
|
|
2
|
+
import React19, { useEffect as useEffect10, useMemo as useMemo4, useState as useState17 } from "react";
|
|
3
3
|
import { createDefaultComponentRegistry as createDefaultComponentRegistry2 } from "@kubuild/components";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
buildSampleVariablesFromCatalog
|
|
6
|
+
} from "@kubuild/core";
|
|
5
7
|
|
|
6
8
|
// src/store.ts
|
|
7
9
|
import { create } from "zustand";
|
|
@@ -25,6 +27,9 @@ import {
|
|
|
25
27
|
saveDraftAsTemplate,
|
|
26
28
|
cloneTemplateAsPage
|
|
27
29
|
} from "@kubuild/core";
|
|
30
|
+
import {
|
|
31
|
+
STARTER_BLOCKS
|
|
32
|
+
} from "@kubuild/components";
|
|
28
33
|
function formatCommandError(err) {
|
|
29
34
|
if (err && typeof err === "object" && Array.isArray(err.issues)) {
|
|
30
35
|
const issues = err.issues;
|
|
@@ -49,7 +54,11 @@ function buildDefaultChildren(specs, existingIds, registry) {
|
|
|
49
54
|
const def = registry.get(spec.type);
|
|
50
55
|
const nodeProps = deepClone(spec.props ?? def?.defaultProps ?? {});
|
|
51
56
|
const nodeStyles = spec.styles ?? def?.defaultStyles;
|
|
52
|
-
const childNodes = buildDefaultChildren(
|
|
57
|
+
const childNodes = buildDefaultChildren(
|
|
58
|
+
spec.children ?? def?.defaultChildren,
|
|
59
|
+
existingIds,
|
|
60
|
+
registry
|
|
61
|
+
);
|
|
53
62
|
const node = {
|
|
54
63
|
id,
|
|
55
64
|
type: spec.type,
|
|
@@ -69,6 +78,7 @@ var useEditorStore = create((set, get) => ({
|
|
|
69
78
|
document: historyManager.document,
|
|
70
79
|
selectedNodeId: null,
|
|
71
80
|
hoveredNodeId: null,
|
|
81
|
+
dragPayload: null,
|
|
72
82
|
viewport: "desktop",
|
|
73
83
|
isDirty: false,
|
|
74
84
|
canUndo: false,
|
|
@@ -78,6 +88,7 @@ var useEditorStore = create((set, get) => ({
|
|
|
78
88
|
variableCatalog: [],
|
|
79
89
|
navigatorMode: "floating",
|
|
80
90
|
tableSpreadsheetMode: "floating",
|
|
91
|
+
setDragPayload: (payload) => set({ dragPayload: payload }),
|
|
81
92
|
setVariableCatalog: (catalog) => set({ variableCatalog: catalog }),
|
|
82
93
|
setNavigatorMode: (mode) => set({ navigatorMode: mode }),
|
|
83
94
|
toggleNavigator: () => set((state) => ({
|
|
@@ -94,6 +105,7 @@ var useEditorStore = create((set, get) => ({
|
|
|
94
105
|
isDirty: false,
|
|
95
106
|
selectedNodeId: null,
|
|
96
107
|
hoveredNodeId: null,
|
|
108
|
+
dragPayload: null,
|
|
97
109
|
clipboard: null,
|
|
98
110
|
canUndo: false,
|
|
99
111
|
canRedo: false
|
|
@@ -112,12 +124,15 @@ var useEditorStore = create((set, get) => ({
|
|
|
112
124
|
});
|
|
113
125
|
onChangeHandler?.(result.document);
|
|
114
126
|
},
|
|
115
|
-
insertComponent: (type, registry, parentId) => {
|
|
127
|
+
insertComponent: (type, registry, parentId, index) => {
|
|
116
128
|
const state = get();
|
|
117
129
|
const targetParentId = parentId ?? state.selectedNodeId ?? state.document.document.id;
|
|
118
130
|
const parentNode = findNodeById(state.document.document, targetParentId);
|
|
119
131
|
if (!parentNode) {
|
|
120
|
-
return {
|
|
132
|
+
return {
|
|
133
|
+
success: false,
|
|
134
|
+
error: `Insertion target "${targetParentId}" was not found in the document.`
|
|
135
|
+
};
|
|
121
136
|
}
|
|
122
137
|
const definition = registry.get(type);
|
|
123
138
|
if (!definition) {
|
|
@@ -134,7 +149,10 @@ var useEditorStore = create((set, get) => ({
|
|
|
134
149
|
return { success: false, error: propResult.join(" ") };
|
|
135
150
|
}
|
|
136
151
|
if (propResult === false) {
|
|
137
|
-
return {
|
|
152
|
+
return {
|
|
153
|
+
success: false,
|
|
154
|
+
error: `Default props for "${definition.label}" failed validation.`
|
|
155
|
+
};
|
|
138
156
|
}
|
|
139
157
|
}
|
|
140
158
|
const existingIds = collectNodeIdSet(state.document.document);
|
|
@@ -148,10 +166,49 @@ var useEditorStore = create((set, get) => ({
|
|
|
148
166
|
...definition.defaultStyles ? { styles: deepClone(definition.defaultStyles) } : {},
|
|
149
167
|
...children ? { children } : {}
|
|
150
168
|
};
|
|
151
|
-
get().dispatch((doc) => insertNode(doc, { parentId: targetParentId, node }));
|
|
169
|
+
get().dispatch((doc) => insertNode(doc, { parentId: targetParentId, node, index }));
|
|
152
170
|
get().selectNode(nodeId);
|
|
153
171
|
return { success: true, nodeId };
|
|
154
172
|
},
|
|
173
|
+
insertBlock: (blockOrId, parentId, index) => {
|
|
174
|
+
const state = get();
|
|
175
|
+
const targetParentId = parentId ?? state.selectedNodeId ?? state.document.document.id;
|
|
176
|
+
let blockDef;
|
|
177
|
+
if (typeof blockOrId === "string") {
|
|
178
|
+
blockDef = STARTER_BLOCKS.find((b) => b.id === blockOrId);
|
|
179
|
+
} else {
|
|
180
|
+
blockDef = blockOrId;
|
|
181
|
+
}
|
|
182
|
+
if (!blockDef) {
|
|
183
|
+
return { success: false, error: "Block definition not found." };
|
|
184
|
+
}
|
|
185
|
+
const existingIds = collectNodeIdSet(state.document.document);
|
|
186
|
+
let counter = 1;
|
|
187
|
+
const generateId = (prefix = "node") => {
|
|
188
|
+
let id = `${prefix}-${Date.now().toString(36)}-${counter++}`;
|
|
189
|
+
while (existingIds.has(id)) {
|
|
190
|
+
id = `${prefix}-${Date.now().toString(36)}-${counter++}`;
|
|
191
|
+
}
|
|
192
|
+
existingIds.add(id);
|
|
193
|
+
return id;
|
|
194
|
+
};
|
|
195
|
+
const nodeTree = blockDef.createNodeTree(generateId);
|
|
196
|
+
try {
|
|
197
|
+
get().dispatch((doc) => insertNode(doc, { parentId: targetParentId, node: nodeTree, index }));
|
|
198
|
+
get().selectNode(nodeTree.id);
|
|
199
|
+
return { success: true, nodeId: nodeTree.id };
|
|
200
|
+
} catch {
|
|
201
|
+
try {
|
|
202
|
+
get().dispatch(
|
|
203
|
+
(doc) => insertNode(doc, { parentId: state.document.document.id, node: nodeTree })
|
|
204
|
+
);
|
|
205
|
+
get().selectNode(nodeTree.id);
|
|
206
|
+
return { success: true, nodeId: nodeTree.id };
|
|
207
|
+
} catch (err) {
|
|
208
|
+
return { success: false, error: formatCommandError(err) };
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
},
|
|
155
212
|
moveComponent: (nodeId, targetParentId, registry, index) => {
|
|
156
213
|
const state = get();
|
|
157
214
|
if (nodeId === state.document.document.id) {
|
|
@@ -163,10 +220,16 @@ var useEditorStore = create((set, get) => ({
|
|
|
163
220
|
}
|
|
164
221
|
const targetParent = findNodeById(state.document.document, targetParentId);
|
|
165
222
|
if (!targetParent) {
|
|
166
|
-
return {
|
|
223
|
+
return {
|
|
224
|
+
success: false,
|
|
225
|
+
error: `Move target "${targetParentId}" was not found in the document.`
|
|
226
|
+
};
|
|
167
227
|
}
|
|
168
228
|
if (isDescendantOf(sourceLocation.node, targetParentId)) {
|
|
169
|
-
return {
|
|
229
|
+
return {
|
|
230
|
+
success: false,
|
|
231
|
+
error: "Cannot move a node into itself or one of its own descendants."
|
|
232
|
+
};
|
|
170
233
|
}
|
|
171
234
|
const policy = registry.canInsertChild(targetParent.type, sourceLocation.node.type);
|
|
172
235
|
if (!policy.valid) {
|
|
@@ -303,10 +366,16 @@ var useEditorStore = create((set, get) => ({
|
|
|
303
366
|
}
|
|
304
367
|
const targetParent = findNodeById(document2.document, targetParentId);
|
|
305
368
|
if (!targetParent) {
|
|
306
|
-
return {
|
|
369
|
+
return {
|
|
370
|
+
success: false,
|
|
371
|
+
error: `Paste target "${targetParentId}" was not found in the document.`
|
|
372
|
+
};
|
|
307
373
|
}
|
|
308
374
|
if (isDescendantOf(clipboard, targetParentId)) {
|
|
309
|
-
return {
|
|
375
|
+
return {
|
|
376
|
+
success: false,
|
|
377
|
+
error: "Cannot paste a node into itself or one of its own descendants."
|
|
378
|
+
};
|
|
310
379
|
}
|
|
311
380
|
const policy = registry.canInsertChild(targetParent.type, clipboard.type);
|
|
312
381
|
if (!policy.valid) {
|
|
@@ -315,7 +384,9 @@ var useEditorStore = create((set, get) => ({
|
|
|
315
384
|
const existingIds = collectNodeIdSet(document2.document);
|
|
316
385
|
const { clonedNode } = cloneTreeWithNewIds(clipboard, void 0, existingIds);
|
|
317
386
|
try {
|
|
318
|
-
get().dispatch(
|
|
387
|
+
get().dispatch(
|
|
388
|
+
(doc) => insertNode(doc, { parentId: targetParentId, node: clonedNode, index })
|
|
389
|
+
);
|
|
319
390
|
} catch (err) {
|
|
320
391
|
return { success: false, error: formatCommandError(err) };
|
|
321
392
|
}
|
|
@@ -485,7 +556,19 @@ var EditorCanvas = ({
|
|
|
485
556
|
onDiagnostic,
|
|
486
557
|
config
|
|
487
558
|
}) => {
|
|
488
|
-
const {
|
|
559
|
+
const {
|
|
560
|
+
document: storeDoc,
|
|
561
|
+
selectedNodeId,
|
|
562
|
+
hoveredNodeId,
|
|
563
|
+
dragPayload,
|
|
564
|
+
selectNode,
|
|
565
|
+
hoverNode,
|
|
566
|
+
updateNodeProps,
|
|
567
|
+
setDragPayload,
|
|
568
|
+
insertComponent,
|
|
569
|
+
insertBlock,
|
|
570
|
+
moveComponent
|
|
571
|
+
} = useEditorStore();
|
|
489
572
|
const document2 = propDoc ?? storeDoc;
|
|
490
573
|
const showFloatingBadges = config?.showFloatingBadges !== false;
|
|
491
574
|
const containerRef = useRef(null);
|
|
@@ -562,7 +645,11 @@ var EditorCanvas = ({
|
|
|
562
645
|
const direction = ARROW_DIRECTIONS[e.key];
|
|
563
646
|
if (direction) {
|
|
564
647
|
e.preventDefault();
|
|
565
|
-
const target = getNavigationTarget(
|
|
648
|
+
const target = getNavigationTarget(
|
|
649
|
+
state.document.document,
|
|
650
|
+
state.selectedNodeId,
|
|
651
|
+
direction
|
|
652
|
+
);
|
|
566
653
|
if (target) state.selectNode(target);
|
|
567
654
|
}
|
|
568
655
|
};
|
|
@@ -589,24 +676,71 @@ var EditorCanvas = ({
|
|
|
589
676
|
e.stopPropagation();
|
|
590
677
|
e.dataTransfer.effectAllowed = "move";
|
|
591
678
|
e.dataTransfer.setData("text/plain", nodeId);
|
|
679
|
+
e.dataTransfer.setData("application/kubuild-drag-type", "node");
|
|
680
|
+
e.dataTransfer.setData("application/kubuild-node-id", nodeId);
|
|
592
681
|
setDraggingId(nodeId);
|
|
682
|
+
setDragPayload({ type: "node", nodeId });
|
|
593
683
|
selectNode(nodeId);
|
|
594
684
|
};
|
|
595
685
|
const handleDragOver = (e) => {
|
|
596
|
-
|
|
686
|
+
const activePayload = dragPayload ?? (draggingId ? { type: "node", nodeId: draggingId } : null);
|
|
687
|
+
if (!activePayload) return;
|
|
597
688
|
const container = containerRef.current;
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
const
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
689
|
+
if (!container) return;
|
|
690
|
+
const containerRect = container.getBoundingClientRect();
|
|
691
|
+
const hoveredEl = e.target.closest(
|
|
692
|
+
"[data-kubuild-node]"
|
|
693
|
+
);
|
|
694
|
+
let incomingType = null;
|
|
695
|
+
if (activePayload.type === "node") {
|
|
696
|
+
const draggedNode = findNodeById3(document2.document, activePayload.nodeId);
|
|
697
|
+
incomingType = draggedNode?.type ?? null;
|
|
698
|
+
} else if (activePayload.type === "component") {
|
|
699
|
+
incomingType = activePayload.componentType;
|
|
700
|
+
} else if (activePayload.type === "block") {
|
|
701
|
+
incomingType = "section";
|
|
702
|
+
}
|
|
703
|
+
if (!incomingType) {
|
|
604
704
|
setDropTarget(null);
|
|
605
705
|
e.dataTransfer.dropEffect = "none";
|
|
606
706
|
return;
|
|
607
707
|
}
|
|
708
|
+
if (!hoveredEl) {
|
|
709
|
+
const rootNode = document2.document;
|
|
710
|
+
const policy2 = registry.canInsertChild(rootNode.type, incomingType);
|
|
711
|
+
if (!policy2.valid) {
|
|
712
|
+
setDropTarget(null);
|
|
713
|
+
e.dataTransfer.dropEffect = "none";
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
e.preventDefault();
|
|
717
|
+
e.dataTransfer.dropEffect = activePayload.type === "node" ? "move" : "copy";
|
|
718
|
+
setDropTarget({
|
|
719
|
+
parentId: rootNode.id,
|
|
720
|
+
index: rootNode.children?.length ?? 0,
|
|
721
|
+
position: "inside",
|
|
722
|
+
rect: {
|
|
723
|
+
top: 0,
|
|
724
|
+
left: 0,
|
|
725
|
+
width: containerRect.width,
|
|
726
|
+
height: Math.max(containerRect.height, 200)
|
|
727
|
+
}
|
|
728
|
+
});
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
const hoveredId = hoveredEl.getAttribute("data-kubuild-node");
|
|
732
|
+
if (!hoveredId) return;
|
|
733
|
+
if (activePayload.type === "node") {
|
|
734
|
+
const draggedNode = findNodeById3(document2.document, activePayload.nodeId);
|
|
735
|
+
if (!draggedNode || isDescendantOf2(draggedNode, hoveredId)) {
|
|
736
|
+
setDropTarget(null);
|
|
737
|
+
e.dataTransfer.dropEffect = "none";
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
const hoveredNode = findNodeById3(document2.document, hoveredId);
|
|
742
|
+
if (!hoveredNode) return;
|
|
608
743
|
const elRect = hoveredEl.getBoundingClientRect();
|
|
609
|
-
const containerRect = container.getBoundingClientRect();
|
|
610
744
|
const ratio = elRect.height > 0 ? (e.clientY - elRect.top) / elRect.height : 0.5;
|
|
611
745
|
const hoveredDef = registry.get(hoveredNode.type);
|
|
612
746
|
const canGoInside = !!hoveredDef?.acceptsChildren;
|
|
@@ -627,18 +761,21 @@ var EditorCanvas = ({
|
|
|
627
761
|
targetType: location.parent.type
|
|
628
762
|
};
|
|
629
763
|
} else {
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
764
|
+
candidate = {
|
|
765
|
+
parentId: document2.document.id,
|
|
766
|
+
index: document2.document.children?.length ?? 0,
|
|
767
|
+
position: "inside",
|
|
768
|
+
targetType: document2.document.type
|
|
769
|
+
};
|
|
633
770
|
}
|
|
634
|
-
const policy = registry.canInsertChild(candidate.targetType,
|
|
771
|
+
const policy = registry.canInsertChild(candidate.targetType, incomingType);
|
|
635
772
|
if (!policy.valid) {
|
|
636
773
|
setDropTarget(null);
|
|
637
774
|
e.dataTransfer.dropEffect = "none";
|
|
638
775
|
return;
|
|
639
776
|
}
|
|
640
777
|
e.preventDefault();
|
|
641
|
-
e.dataTransfer.dropEffect = "move";
|
|
778
|
+
e.dataTransfer.dropEffect = activePayload.type === "node" ? "move" : "copy";
|
|
642
779
|
setDropTarget({
|
|
643
780
|
parentId: candidate.parentId,
|
|
644
781
|
index: candidate.index,
|
|
@@ -653,15 +790,29 @@ var EditorCanvas = ({
|
|
|
653
790
|
};
|
|
654
791
|
const handleDrop = (e) => {
|
|
655
792
|
e.preventDefault();
|
|
656
|
-
|
|
657
|
-
|
|
793
|
+
const activePayload = dragPayload ?? (draggingId ? { type: "node", nodeId: draggingId } : null);
|
|
794
|
+
if (activePayload && dropTarget) {
|
|
795
|
+
if (activePayload.type === "node") {
|
|
796
|
+
moveComponent(activePayload.nodeId, dropTarget.parentId, registry, dropTarget.index);
|
|
797
|
+
} else if (activePayload.type === "component") {
|
|
798
|
+
insertComponent(
|
|
799
|
+
activePayload.componentType,
|
|
800
|
+
registry,
|
|
801
|
+
dropTarget.parentId,
|
|
802
|
+
dropTarget.index
|
|
803
|
+
);
|
|
804
|
+
} else if (activePayload.type === "block") {
|
|
805
|
+
insertBlock(activePayload.blockId, dropTarget.parentId, dropTarget.index);
|
|
806
|
+
}
|
|
658
807
|
}
|
|
659
808
|
setDraggingId(null);
|
|
660
809
|
setDropTarget(null);
|
|
810
|
+
setDragPayload(null);
|
|
661
811
|
};
|
|
662
812
|
const handleDragEnd = () => {
|
|
663
813
|
setDraggingId(null);
|
|
664
814
|
setDropTarget(null);
|
|
815
|
+
setDragPayload(null);
|
|
665
816
|
};
|
|
666
817
|
return /* @__PURE__ */ jsxs2(
|
|
667
818
|
"div",
|
|
@@ -1877,14 +2028,7 @@ var CodeViewerModal = ({
|
|
|
1877
2028
|
};
|
|
1878
2029
|
|
|
1879
2030
|
// src/toolbar.tsx
|
|
1880
|
-
import {
|
|
1881
|
-
Copy as Copy2,
|
|
1882
|
-
ClipboardPaste,
|
|
1883
|
-
CopyPlus,
|
|
1884
|
-
Trash2 as Trash22,
|
|
1885
|
-
Undo2,
|
|
1886
|
-
Redo2
|
|
1887
|
-
} from "lucide-react";
|
|
2031
|
+
import { Copy as Copy2, ClipboardPaste, CopyPlus, Trash2 as Trash22, Undo2, Redo2 } from "lucide-react";
|
|
1888
2032
|
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1889
2033
|
var ToolbarIconButton = ({
|
|
1890
2034
|
icon,
|
|
@@ -2028,21 +2172,32 @@ var EditorToolbar = ({
|
|
|
2028
2172
|
type: "button",
|
|
2029
2173
|
title: `Navigator / Element Tree (${navigatorMode !== "hidden" ? "Open" : "Hidden"})`,
|
|
2030
2174
|
onClick: toggleNavigator,
|
|
2031
|
-
className: `flex items-center gap-1 text-xs px-2.5 py-1 rounded border transition font-medium cursor-pointer ${navigatorMode !== "hidden" ? "border-blue-500 bg-blue-50 text-blue-700 shadow-xs" : "border-slate-200 bg-white hover:border-slate-300 text-slate-700"}`,
|
|
2175
|
+
className: `hidden sm:flex items-center gap-1 text-xs px-2.5 py-1 rounded border transition font-medium cursor-pointer ${navigatorMode !== "hidden" ? "border-blue-500 bg-blue-50 text-blue-700 shadow-xs" : "border-slate-200 bg-white hover:border-slate-300 text-slate-700"}`,
|
|
2032
2176
|
children: [
|
|
2033
|
-
/* @__PURE__ */ jsxs5(
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2177
|
+
/* @__PURE__ */ jsxs5(
|
|
2178
|
+
"svg",
|
|
2179
|
+
{
|
|
2180
|
+
width: "13",
|
|
2181
|
+
height: "13",
|
|
2182
|
+
viewBox: "0 0 24 24",
|
|
2183
|
+
fill: "none",
|
|
2184
|
+
stroke: "currentColor",
|
|
2185
|
+
strokeWidth: "2",
|
|
2186
|
+
children: [
|
|
2187
|
+
/* @__PURE__ */ jsx6("line", { x1: "8", y1: "6", x2: "21", y2: "6" }),
|
|
2188
|
+
/* @__PURE__ */ jsx6("line", { x1: "8", y1: "12", x2: "21", y2: "12" }),
|
|
2189
|
+
/* @__PURE__ */ jsx6("line", { x1: "8", y1: "18", x2: "21", y2: "18" }),
|
|
2190
|
+
/* @__PURE__ */ jsx6("line", { x1: "3", y1: "6", x2: "3.01", y2: "6" }),
|
|
2191
|
+
/* @__PURE__ */ jsx6("line", { x1: "3", y1: "12", x2: "3.01", y2: "12" }),
|
|
2192
|
+
/* @__PURE__ */ jsx6("line", { x1: "3", y1: "18", x2: "3.01", y2: "18" })
|
|
2193
|
+
]
|
|
2194
|
+
}
|
|
2195
|
+
),
|
|
2041
2196
|
/* @__PURE__ */ jsx6("span", { children: "Navigator" })
|
|
2042
2197
|
]
|
|
2043
2198
|
}
|
|
2044
2199
|
),
|
|
2045
|
-
showNavigatorToggle && (showClipboard || showHistory || showCodeViewer || showExportImport) && /* @__PURE__ */ jsx6("div", { className: "h-4 w-px bg-slate-200 mx-1" }),
|
|
2200
|
+
showNavigatorToggle && (showClipboard || showHistory || showCodeViewer || showExportImport) && /* @__PURE__ */ jsx6("div", { className: "hidden sm:block h-4 w-px bg-slate-200 mx-1" }),
|
|
2046
2201
|
(showClipboard || showHistory) && /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-1", children: [
|
|
2047
2202
|
showClipboard && /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
2048
2203
|
/* @__PURE__ */ jsx6(
|
|
@@ -2117,21 +2272,21 @@ var EditorToolbar = ({
|
|
|
2117
2272
|
)
|
|
2118
2273
|
] })
|
|
2119
2274
|
] }),
|
|
2120
|
-
(showClipboard || showHistory) && (showCodeViewer || showExportImport) && /* @__PURE__ */ jsx6("div", { className: "h-4 w-px bg-slate-200 mx-1" }),
|
|
2275
|
+
(showClipboard || showHistory) && (showCodeViewer || showExportImport) && /* @__PURE__ */ jsx6("div", { className: "hidden sm:block h-4 w-px bg-slate-200 mx-1" }),
|
|
2121
2276
|
showCodeViewer && /* @__PURE__ */ jsxs5(
|
|
2122
2277
|
"button",
|
|
2123
2278
|
{
|
|
2124
2279
|
type: "button",
|
|
2125
2280
|
title: "View Semantic HTML & CSS (< >)",
|
|
2126
2281
|
onClick: () => setIsCodeViewerModalOpen(true),
|
|
2127
|
-
className: "flex items-center gap-1.5 text-xs px-2.5 py-1 rounded border border-slate-200 bg-white hover:border-blue-500 hover:text-blue-600 font-medium text-slate-700 transition",
|
|
2282
|
+
className: "flex items-center gap-1.5 text-xs px-2 sm:px-2.5 py-1 rounded border border-slate-200 bg-white hover:border-blue-500 hover:text-blue-600 font-medium text-slate-700 transition",
|
|
2128
2283
|
children: [
|
|
2129
2284
|
/* @__PURE__ */ jsx6("span", { className: "font-mono text-[11px] font-bold text-blue-600", children: "<>" }),
|
|
2130
|
-
/* @__PURE__ */ jsx6("span", { children: "View Code" })
|
|
2285
|
+
/* @__PURE__ */ jsx6("span", { className: "hidden sm:inline", children: "View Code" })
|
|
2131
2286
|
]
|
|
2132
2287
|
}
|
|
2133
2288
|
),
|
|
2134
|
-
showExportImport && /* @__PURE__ */ jsxs5(
|
|
2289
|
+
showExportImport && /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-1", children: [
|
|
2135
2290
|
showCodeViewer && /* @__PURE__ */ jsx6("div", { className: "h-4 w-px bg-slate-200 mx-1" }),
|
|
2136
2291
|
/* @__PURE__ */ jsx6(
|
|
2137
2292
|
"button",
|
|
@@ -2139,7 +2294,7 @@ var EditorToolbar = ({
|
|
|
2139
2294
|
type: "button",
|
|
2140
2295
|
title: "Import .stora Package",
|
|
2141
2296
|
onClick: () => setIsImportModalOpen(true),
|
|
2142
|
-
className: "text-xs px-2.5 py-1 rounded border border-slate-200 bg-white hover:border-blue-500 hover:text-blue-600 font-medium text-slate-700 transition",
|
|
2297
|
+
className: "text-xs px-2 sm:px-2.5 py-1 rounded border border-slate-200 bg-white hover:border-blue-500 hover:text-blue-600 font-medium text-slate-700 transition",
|
|
2143
2298
|
children: "Import"
|
|
2144
2299
|
}
|
|
2145
2300
|
),
|
|
@@ -2150,8 +2305,8 @@ var EditorToolbar = ({
|
|
|
2150
2305
|
title: "Export .stora Archive",
|
|
2151
2306
|
disabled: isExporting,
|
|
2152
2307
|
onClick: handleExportStora,
|
|
2153
|
-
className: "text-xs px-2.5 py-1 rounded border border-blue-600 bg-blue-600 hover:bg-blue-500 text-white font-medium disabled:opacity-50 transition shadow-
|
|
2154
|
-
children: isExporting ? "
|
|
2308
|
+
className: "text-xs px-2 sm:px-2.5 py-1 rounded border border-blue-600 bg-blue-600 hover:bg-blue-500 text-white font-medium disabled:opacity-50 transition shadow-xs",
|
|
2309
|
+
children: isExporting ? "..." : "Export"
|
|
2155
2310
|
}
|
|
2156
2311
|
),
|
|
2157
2312
|
/* @__PURE__ */ jsx6(
|
|
@@ -2160,7 +2315,7 @@ var EditorToolbar = ({
|
|
|
2160
2315
|
type: "button",
|
|
2161
2316
|
title: "Download page.json",
|
|
2162
2317
|
onClick: handleExportJson,
|
|
2163
|
-
className: "text-xs px-2 py-1 rounded border border-slate-200 bg-white hover:border-slate-400 text-slate-600 transition",
|
|
2318
|
+
className: "hidden md:inline-block text-xs px-2 py-1 rounded border border-slate-200 bg-white hover:border-slate-400 text-slate-600 transition",
|
|
2164
2319
|
children: "JSON"
|
|
2165
2320
|
}
|
|
2166
2321
|
)
|
|
@@ -3001,15 +3156,18 @@ var TableSpreadsheetEditor = ({
|
|
|
3001
3156
|
setIsImportModalOpen(false);
|
|
3002
3157
|
setCsvInputText("");
|
|
3003
3158
|
};
|
|
3004
|
-
const [pos, setPos] = useState6(
|
|
3159
|
+
const [pos, setPos] = useState6(() => ({
|
|
3160
|
+
x: typeof window !== "undefined" ? Math.max(10, Math.min(window.innerWidth - 400, 20)) : 20,
|
|
3161
|
+
y: 120
|
|
3162
|
+
}));
|
|
3005
3163
|
const [isDragging, setIsDragging] = useState6(false);
|
|
3006
3164
|
const dragStartRef = useRef4({
|
|
3007
3165
|
startX: 0,
|
|
3008
3166
|
startY: 0,
|
|
3009
|
-
posX:
|
|
3167
|
+
posX: 20,
|
|
3010
3168
|
posY: 120
|
|
3011
3169
|
});
|
|
3012
|
-
const
|
|
3170
|
+
const handleHeaderPointerDown = (e) => {
|
|
3013
3171
|
if (e.target.closest("button, input, select, textarea")) return;
|
|
3014
3172
|
setIsDragging(true);
|
|
3015
3173
|
dragStartRef.current = {
|
|
@@ -3021,22 +3179,26 @@ var TableSpreadsheetEditor = ({
|
|
|
3021
3179
|
};
|
|
3022
3180
|
useEffect2(() => {
|
|
3023
3181
|
if (!isDragging) return;
|
|
3024
|
-
const
|
|
3182
|
+
const handlePointerMove = (e) => {
|
|
3025
3183
|
const dx = e.clientX - dragStartRef.current.startX;
|
|
3026
3184
|
const dy = e.clientY - dragStartRef.current.startY;
|
|
3185
|
+
const maxX = Math.max(8, window.innerWidth - 320);
|
|
3186
|
+
const maxY = Math.max(8, window.innerHeight - 100);
|
|
3027
3187
|
setPos({
|
|
3028
|
-
x: Math.max(
|
|
3029
|
-
y: Math.max(
|
|
3188
|
+
x: Math.max(8, Math.min(maxX, dragStartRef.current.posX + dx)),
|
|
3189
|
+
y: Math.max(8, Math.min(maxY, dragStartRef.current.posY + dy))
|
|
3030
3190
|
});
|
|
3031
3191
|
};
|
|
3032
|
-
const
|
|
3192
|
+
const handlePointerUp = () => {
|
|
3033
3193
|
setIsDragging(false);
|
|
3034
3194
|
};
|
|
3035
|
-
window.addEventListener("
|
|
3036
|
-
window.addEventListener("
|
|
3195
|
+
window.addEventListener("pointermove", handlePointerMove);
|
|
3196
|
+
window.addEventListener("pointerup", handlePointerUp);
|
|
3197
|
+
window.addEventListener("pointercancel", handlePointerUp);
|
|
3037
3198
|
return () => {
|
|
3038
|
-
window.removeEventListener("
|
|
3039
|
-
window.removeEventListener("
|
|
3199
|
+
window.removeEventListener("pointermove", handlePointerMove);
|
|
3200
|
+
window.removeEventListener("pointerup", handlePointerUp);
|
|
3201
|
+
window.removeEventListener("pointercancel", handlePointerUp);
|
|
3040
3202
|
};
|
|
3041
3203
|
}, [isDragging]);
|
|
3042
3204
|
if (!tableNode) return null;
|
|
@@ -3590,9 +3752,9 @@ var TableSpreadsheetEditor = ({
|
|
|
3590
3752
|
/* @__PURE__ */ jsx10(
|
|
3591
3753
|
"div",
|
|
3592
3754
|
{
|
|
3593
|
-
style: { left: `${pos.x}px`, top: `${pos.y}px
|
|
3594
|
-
|
|
3595
|
-
className: `fixed z-40 min-w-[380px] max-w-[620px] bg-white/95 backdrop-blur-md rounded-xl shadow-2xl border border-slate-300 flex flex-col max-h-[460px] overflow-hidden ${className}`,
|
|
3755
|
+
style: { left: `${pos.x}px`, top: `${pos.y}px`, touchAction: "none" },
|
|
3756
|
+
onPointerDown: handleHeaderPointerDown,
|
|
3757
|
+
className: `fixed z-40 min-w-[320px] sm:min-w-[380px] max-w-[620px] bg-white/95 backdrop-blur-md rounded-xl shadow-2xl border border-slate-300 flex flex-col max-h-[460px] overflow-hidden cursor-grab active:cursor-grabbing touch-none ${className}`,
|
|
3596
3758
|
children: content
|
|
3597
3759
|
}
|
|
3598
3760
|
)
|
|
@@ -6657,16 +6819,19 @@ var LayersPanel = ({ registry, className }) => {
|
|
|
6657
6819
|
const [expandedIds, setExpandedIds] = useState13(() => /* @__PURE__ */ new Set([document2.document.id]));
|
|
6658
6820
|
const [draggingId, setDraggingId] = useState13(null);
|
|
6659
6821
|
const [dropCandidate, setDropCandidate] = useState13(null);
|
|
6660
|
-
const [pos, setPos] = useState13(
|
|
6822
|
+
const [pos, setPos] = useState13(() => ({
|
|
6823
|
+
x: typeof window !== "undefined" ? Math.max(12, Math.min(window.innerWidth - 300, 24)) : 24,
|
|
6824
|
+
y: 70
|
|
6825
|
+
}));
|
|
6661
6826
|
const [isDraggingWindow, setIsDraggingWindow] = useState13(false);
|
|
6662
6827
|
const dragStartRef = useRef9({
|
|
6663
6828
|
startX: 0,
|
|
6664
6829
|
startY: 0,
|
|
6665
|
-
posX:
|
|
6830
|
+
posX: 24,
|
|
6666
6831
|
posY: 70
|
|
6667
6832
|
});
|
|
6668
|
-
const
|
|
6669
|
-
if (e.target.closest("button")) return;
|
|
6833
|
+
const handleHeaderPointerDown = (e) => {
|
|
6834
|
+
if (e.target.closest("button, input, select, textarea")) return;
|
|
6670
6835
|
setIsDraggingWindow(true);
|
|
6671
6836
|
dragStartRef.current = {
|
|
6672
6837
|
startX: e.clientX,
|
|
@@ -6677,22 +6842,26 @@ var LayersPanel = ({ registry, className }) => {
|
|
|
6677
6842
|
};
|
|
6678
6843
|
useEffect9(() => {
|
|
6679
6844
|
if (!isDraggingWindow) return;
|
|
6680
|
-
const
|
|
6845
|
+
const handlePointerMove = (e) => {
|
|
6681
6846
|
const dx = e.clientX - dragStartRef.current.startX;
|
|
6682
6847
|
const dy = e.clientY - dragStartRef.current.startY;
|
|
6848
|
+
const maxX = Math.max(8, window.innerWidth - 296);
|
|
6849
|
+
const maxY = Math.max(8, window.innerHeight - 100);
|
|
6683
6850
|
setPos({
|
|
6684
|
-
x: Math.max(
|
|
6685
|
-
y: Math.max(
|
|
6851
|
+
x: Math.max(8, Math.min(maxX, dragStartRef.current.posX + dx)),
|
|
6852
|
+
y: Math.max(8, Math.min(maxY, dragStartRef.current.posY + dy))
|
|
6686
6853
|
});
|
|
6687
6854
|
};
|
|
6688
|
-
const
|
|
6855
|
+
const handlePointerUp = () => {
|
|
6689
6856
|
setIsDraggingWindow(false);
|
|
6690
6857
|
};
|
|
6691
|
-
window.addEventListener("
|
|
6692
|
-
window.addEventListener("
|
|
6858
|
+
window.addEventListener("pointermove", handlePointerMove);
|
|
6859
|
+
window.addEventListener("pointerup", handlePointerUp);
|
|
6860
|
+
window.addEventListener("pointercancel", handlePointerUp);
|
|
6693
6861
|
return () => {
|
|
6694
|
-
window.removeEventListener("
|
|
6695
|
-
window.removeEventListener("
|
|
6862
|
+
window.removeEventListener("pointermove", handlePointerMove);
|
|
6863
|
+
window.removeEventListener("pointerup", handlePointerUp);
|
|
6864
|
+
window.removeEventListener("pointercancel", handlePointerUp);
|
|
6696
6865
|
};
|
|
6697
6866
|
}, [isDraggingWindow]);
|
|
6698
6867
|
useEffect9(() => {
|
|
@@ -6843,8 +7012,9 @@ var LayersPanel = ({ registry, className }) => {
|
|
|
6843
7012
|
const header = /* @__PURE__ */ jsxs17(
|
|
6844
7013
|
"div",
|
|
6845
7014
|
{
|
|
6846
|
-
|
|
6847
|
-
|
|
7015
|
+
onPointerDown: isFloating ? handleHeaderPointerDown : void 0,
|
|
7016
|
+
style: { touchAction: isFloating ? "none" : "auto" },
|
|
7017
|
+
className: `flex items-center justify-between px-3 py-2 border-b border-slate-200/90 select-none ${isFloating ? "cursor-grab active:cursor-grabbing bg-slate-50/90 rounded-t-xl touch-none" : "bg-slate-50"}`,
|
|
6848
7018
|
children: [
|
|
6849
7019
|
/* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-1.5 font-semibold text-xs text-slate-700", children: [
|
|
6850
7020
|
isFloating && /* @__PURE__ */ jsx18(GripVertical, { className: "w-3 h-3 text-slate-400 mr-0.5", "aria-hidden": "true" }),
|
|
@@ -6973,7 +7143,15 @@ import { Boxes, Blocks, Layers } from "lucide-react";
|
|
|
6973
7143
|
// src/component-panel.tsx
|
|
6974
7144
|
import { useState as useState14 } from "react";
|
|
6975
7145
|
import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
6976
|
-
var CATEGORY_ORDER = [
|
|
7146
|
+
var CATEGORY_ORDER = [
|
|
7147
|
+
"layout",
|
|
7148
|
+
"typography",
|
|
7149
|
+
"media",
|
|
7150
|
+
"form",
|
|
7151
|
+
"interactive",
|
|
7152
|
+
"data",
|
|
7153
|
+
"custom"
|
|
7154
|
+
];
|
|
6977
7155
|
var CATEGORY_LABELS = {
|
|
6978
7156
|
layout: "Layout",
|
|
6979
7157
|
typography: "Typography",
|
|
@@ -6985,6 +7163,7 @@ var CATEGORY_LABELS = {
|
|
|
6985
7163
|
};
|
|
6986
7164
|
var ComponentPanel = ({ registry, className }) => {
|
|
6987
7165
|
const insertComponent = useEditorStore((s) => s.insertComponent);
|
|
7166
|
+
const setDragPayload = useEditorStore((s) => s.setDragPayload);
|
|
6988
7167
|
const [error, setError] = useState14(null);
|
|
6989
7168
|
const groups = CATEGORY_ORDER.map((category) => ({
|
|
6990
7169
|
category,
|
|
@@ -6994,6 +7173,16 @@ var ComponentPanel = ({ registry, className }) => {
|
|
|
6994
7173
|
const result = insertComponent(definition.type, registry);
|
|
6995
7174
|
setError(result.success ? null : result.error ?? `Could not insert "${definition.label}".`);
|
|
6996
7175
|
};
|
|
7176
|
+
const handleDragStart = (e, definition) => {
|
|
7177
|
+
e.dataTransfer.effectAllowed = "copy";
|
|
7178
|
+
e.dataTransfer.setData("text/plain", `component:${definition.type}`);
|
|
7179
|
+
e.dataTransfer.setData("application/kubuild-drag-type", "component");
|
|
7180
|
+
e.dataTransfer.setData("application/kubuild-component-type", definition.type);
|
|
7181
|
+
setDragPayload({ type: "component", componentType: definition.type });
|
|
7182
|
+
};
|
|
7183
|
+
const handleDragEnd = () => {
|
|
7184
|
+
setDragPayload(null);
|
|
7185
|
+
};
|
|
6997
7186
|
return /* @__PURE__ */ jsxs19("div", { className: `flex flex-col gap-4 p-3 overflow-y-auto h-full min-h-0 ${className || ""}`, children: [
|
|
6998
7187
|
error && /* @__PURE__ */ jsx20(
|
|
6999
7188
|
"div",
|
|
@@ -7009,12 +7198,16 @@ var ComponentPanel = ({ registry, className }) => {
|
|
|
7009
7198
|
"button",
|
|
7010
7199
|
{
|
|
7011
7200
|
type: "button",
|
|
7201
|
+
draggable: true,
|
|
7202
|
+
onDragStart: (e) => handleDragStart(e, definition),
|
|
7203
|
+
onDragEnd: handleDragEnd,
|
|
7012
7204
|
onClick: () => handleInsert(definition),
|
|
7013
|
-
|
|
7014
|
-
|
|
7205
|
+
"data-testid": `component-item-${definition.type}`,
|
|
7206
|
+
title: definition.description || `Click to insert or drag to canvas: ${definition.label}`,
|
|
7207
|
+
className: "flex flex-col items-center justify-center p-2.5 min-h-[74px] rounded-lg border border-slate-200 bg-white hover:border-blue-400 hover:bg-blue-50/50 hover:shadow text-slate-700 transition group cursor-grab active:cursor-grabbing text-center select-none",
|
|
7015
7208
|
children: [
|
|
7016
|
-
/* @__PURE__ */ jsx20("span", { className: "mb-1.5 text-slate-500 group-hover:text-blue-600 transition-colors", children: /* @__PURE__ */ jsx20(ComponentIcon, { iconOrType: definition.icon ?? definition.type, size: 22 }) }),
|
|
7017
|
-
/* @__PURE__ */ jsx20("span", { className: "text-[11px] font-medium text-slate-700 group-hover:text-blue-600 text-center leading-tight break-words w-full
|
|
7209
|
+
/* @__PURE__ */ jsx20("span", { className: "mb-1.5 text-slate-500 group-hover:text-blue-600 transition-colors pointer-events-none", children: /* @__PURE__ */ jsx20(ComponentIcon, { iconOrType: definition.icon ?? definition.type, size: 22 }) }),
|
|
7210
|
+
/* @__PURE__ */ jsx20("span", { className: "text-[11px] font-medium text-slate-700 group-hover:text-blue-600 text-center leading-tight break-words w-full pointer-events-none", children: definition.label })
|
|
7018
7211
|
]
|
|
7019
7212
|
},
|
|
7020
7213
|
definition.type
|
|
@@ -7025,7 +7218,7 @@ var ComponentPanel = ({ registry, className }) => {
|
|
|
7025
7218
|
|
|
7026
7219
|
// src/blocks-panel.tsx
|
|
7027
7220
|
import { useState as useState15, useMemo as useMemo3 } from "react";
|
|
7028
|
-
import { STARTER_BLOCKS } from "@kubuild/components";
|
|
7221
|
+
import { STARTER_BLOCKS as STARTER_BLOCKS2 } from "@kubuild/components";
|
|
7029
7222
|
import { insertNode as insertNode2, collectNodeIdSet as collectNodeIdSet2 } from "@kubuild/core";
|
|
7030
7223
|
import { Image as ImageIcon } from "lucide-react";
|
|
7031
7224
|
import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
@@ -7091,7 +7284,7 @@ var BlockThumbnail = ({ block }) => {
|
|
|
7091
7284
|
}
|
|
7092
7285
|
};
|
|
7093
7286
|
var BlocksPanel = ({
|
|
7094
|
-
blocks =
|
|
7287
|
+
blocks = STARTER_BLOCKS2,
|
|
7095
7288
|
className,
|
|
7096
7289
|
onInsertBlock
|
|
7097
7290
|
}) => {
|
|
@@ -7135,6 +7328,17 @@ var BlocksPanel = ({
|
|
|
7135
7328
|
selectNode(nodeTree.id);
|
|
7136
7329
|
}
|
|
7137
7330
|
};
|
|
7331
|
+
const setDragPayload = useEditorStore((s) => s.setDragPayload);
|
|
7332
|
+
const handleDragStart = (e, block) => {
|
|
7333
|
+
e.dataTransfer.effectAllowed = "copy";
|
|
7334
|
+
e.dataTransfer.setData("text/plain", `block:${block.id}`);
|
|
7335
|
+
e.dataTransfer.setData("application/kubuild-drag-type", "block");
|
|
7336
|
+
e.dataTransfer.setData("application/kubuild-block-id", block.id);
|
|
7337
|
+
setDragPayload({ type: "block", blockId: block.id });
|
|
7338
|
+
};
|
|
7339
|
+
const handleDragEnd = () => {
|
|
7340
|
+
setDragPayload(null);
|
|
7341
|
+
};
|
|
7138
7342
|
return /* @__PURE__ */ jsxs20(
|
|
7139
7343
|
"div",
|
|
7140
7344
|
{
|
|
@@ -7165,13 +7369,17 @@ var BlocksPanel = ({
|
|
|
7165
7369
|
"button",
|
|
7166
7370
|
{
|
|
7167
7371
|
type: "button",
|
|
7372
|
+
draggable: true,
|
|
7373
|
+
onDragStart: (e) => handleDragStart(e, block),
|
|
7374
|
+
onDragEnd: handleDragEnd,
|
|
7168
7375
|
"data-testid": "block-card",
|
|
7169
7376
|
"data-block-id": block.id,
|
|
7170
7377
|
onClick: () => handleInsert(block),
|
|
7171
|
-
|
|
7378
|
+
title: block.description || `Click to insert or drag to canvas: ${block.name}`,
|
|
7379
|
+
className: "flex flex-col justify-between p-2 rounded-lg border border-slate-200 bg-white hover:border-blue-400 hover:shadow-md hover:bg-blue-50/20 transition-all text-left group cursor-grab active:cursor-grabbing select-none",
|
|
7172
7380
|
children: [
|
|
7173
|
-
/* @__PURE__ */ jsx21("div", { className: "mb-2 w-full", children: /* @__PURE__ */ jsx21(BlockThumbnail, { block }) }),
|
|
7174
|
-
/* @__PURE__ */ jsxs20("div", { className: "w-full", children: [
|
|
7381
|
+
/* @__PURE__ */ jsx21("div", { className: "mb-2 w-full pointer-events-none", children: /* @__PURE__ */ jsx21(BlockThumbnail, { block }) }),
|
|
7382
|
+
/* @__PURE__ */ jsxs20("div", { className: "w-full pointer-events-none", children: [
|
|
7175
7383
|
/* @__PURE__ */ jsx21("div", { className: "flex items-center justify-between gap-1 mb-0.5", children: /* @__PURE__ */ jsx21("span", { className: "text-[11px] font-semibold text-slate-800 group-hover:text-blue-600 truncate", children: block.name }) }),
|
|
7176
7384
|
/* @__PURE__ */ jsx21("span", { className: "inline-block text-[9px] uppercase tracking-wider font-semibold text-slate-400 bg-slate-100 px-1 py-0.2 rounded", children: block.category })
|
|
7177
7385
|
] })
|
|
@@ -7321,6 +7529,18 @@ function resolveEditorConfig(config) {
|
|
|
7321
7529
|
}
|
|
7322
7530
|
|
|
7323
7531
|
// src/editor.tsx
|
|
7532
|
+
import {
|
|
7533
|
+
Monitor,
|
|
7534
|
+
Tablet,
|
|
7535
|
+
Smartphone,
|
|
7536
|
+
Plus,
|
|
7537
|
+
Layers as Layers2,
|
|
7538
|
+
Sliders,
|
|
7539
|
+
Undo2 as Undo22,
|
|
7540
|
+
Redo2 as Redo22,
|
|
7541
|
+
X as X5,
|
|
7542
|
+
Boxes as Boxes2
|
|
7543
|
+
} from "lucide-react";
|
|
7324
7544
|
import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
7325
7545
|
var KubuildEditor = ({
|
|
7326
7546
|
initialDocument,
|
|
@@ -7342,9 +7562,16 @@ var KubuildEditor = ({
|
|
|
7342
7562
|
selectedNodeId,
|
|
7343
7563
|
navigatorMode,
|
|
7344
7564
|
tableSpreadsheetMode,
|
|
7345
|
-
setTableSpreadsheetMode
|
|
7565
|
+
setTableSpreadsheetMode,
|
|
7566
|
+
undo,
|
|
7567
|
+
redo,
|
|
7568
|
+
canUndo,
|
|
7569
|
+
canRedo
|
|
7346
7570
|
} = useEditorStore();
|
|
7347
7571
|
const lastLoadedDocRef = React19.useRef(void 0);
|
|
7572
|
+
const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState17(false);
|
|
7573
|
+
const [isMobileInspectorOpen, setIsMobileInspectorOpen] = useState17(false);
|
|
7574
|
+
const [isMobileLayersOpen, setIsMobileLayersOpen] = useState17(false);
|
|
7348
7575
|
const activeTable = useMemo4(
|
|
7349
7576
|
() => findActiveTableNode(document2.document, selectedNodeId),
|
|
7350
7577
|
[document2.document, selectedNodeId]
|
|
@@ -7373,65 +7600,245 @@ var KubuildEditor = ({
|
|
|
7373
7600
|
}, [context, sampleVariables]);
|
|
7374
7601
|
const viewportWidthMap = {
|
|
7375
7602
|
desktop: "w-full max-w-6xl",
|
|
7376
|
-
tablet: "w-[768px]",
|
|
7377
|
-
mobile: "w-[375px]"
|
|
7603
|
+
tablet: "w-full max-w-[768px] sm:w-[768px]",
|
|
7604
|
+
mobile: "w-full max-w-[375px] sm:w-[375px]"
|
|
7605
|
+
};
|
|
7606
|
+
const viewportIcons = {
|
|
7607
|
+
desktop: /* @__PURE__ */ jsx23(Monitor, { className: "w-3.5 h-3.5" }),
|
|
7608
|
+
tablet: /* @__PURE__ */ jsx23(Tablet, { className: "w-3.5 h-3.5" }),
|
|
7609
|
+
mobile: /* @__PURE__ */ jsx23(Smartphone, { className: "w-3.5 h-3.5" })
|
|
7378
7610
|
};
|
|
7379
7611
|
const resolvedConfig = useMemo4(() => resolveEditorConfig(config), [config]);
|
|
7380
|
-
return /* @__PURE__ */ jsxs22(
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7385
|
-
registry,
|
|
7386
|
-
|
|
7387
|
-
|
|
7388
|
-
onToggleMode: () => setTableSpreadsheetMode("docked"),
|
|
7389
|
-
onClose: () => setTableSpreadsheetMode("hidden")
|
|
7390
|
-
}
|
|
7391
|
-
),
|
|
7392
|
-
resolvedConfig.toolbar.enabled && /* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between px-4 py-2 bg-white border-b border-slate-200", children: [
|
|
7393
|
-
resolvedConfig.toolbar.showTitle ? /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2", children: [
|
|
7394
|
-
/* @__PURE__ */ jsx23("span", { className: "font-semibold text-slate-800 text-sm", children: "KUBUILD Editor" }),
|
|
7395
|
-
/* @__PURE__ */ jsx23("span", { className: "text-xs bg-slate-100 text-slate-600 px-2 py-0.5 rounded border", children: document2.metadata?.title || "Untitled" })
|
|
7396
|
-
] }) : /* @__PURE__ */ jsx23("div", {}),
|
|
7397
|
-
/* @__PURE__ */ jsx23(EditorToolbar, { registry, config: resolvedConfig.toolbar }),
|
|
7398
|
-
resolvedConfig.toolbar.showViewportSwitcher && /* @__PURE__ */ jsx23("div", { className: "flex items-center gap-1 bg-slate-100 p-1 rounded-md text-xs", children: ["desktop", "tablet", "mobile"].map((vp) => /* @__PURE__ */ jsx23(
|
|
7399
|
-
"button",
|
|
7400
|
-
{
|
|
7401
|
-
type: "button",
|
|
7402
|
-
onClick: () => setViewport(vp),
|
|
7403
|
-
className: `px-3 py-1 rounded capitalize font-medium transition ${viewport === vp ? "bg-white text-blue-600 shadow-sm" : "text-slate-600 hover:text-slate-900"}`,
|
|
7404
|
-
children: vp
|
|
7405
|
-
},
|
|
7406
|
-
vp
|
|
7407
|
-
)) }),
|
|
7408
|
-
resolvedConfig.toolbar.showSelectionStatus && /* @__PURE__ */ jsx23("div", { className: "text-xs text-slate-500", children: selectedNodeId ? `Selected: #${selectedNodeId}` : "No element selected" })
|
|
7409
|
-
] }),
|
|
7410
|
-
/* @__PURE__ */ jsxs22("div", { className: "flex flex-1 overflow-hidden min-h-0", children: [
|
|
7411
|
-
resolvedConfig.sidebar.enabled && /* @__PURE__ */ jsx23("div", { className: "w-80 shrink-0 bg-white border-r border-slate-200 overflow-hidden flex flex-col min-h-0 h-full", children: /* @__PURE__ */ jsx23(LeftSidebar, { registry, config: resolvedConfig.sidebar }) }),
|
|
7412
|
-
navigatorMode === "docked" && /* @__PURE__ */ jsx23("div", { className: "w-60 shrink-0 bg-white border-r border-slate-200 overflow-hidden flex flex-col min-h-0 h-full", children: /* @__PURE__ */ jsx23(LayersPanel, { registry }) }),
|
|
7413
|
-
/* @__PURE__ */ jsxs22("div", { className: "flex-1 overflow-hidden flex flex-col min-h-0 h-full", children: [
|
|
7414
|
-
/* @__PURE__ */ jsx23("div", { className: "flex-1 overflow-auto p-8 flex justify-center items-start min-h-0", children: /* @__PURE__ */ jsx23(
|
|
7415
|
-
"div",
|
|
7612
|
+
return /* @__PURE__ */ jsxs22(
|
|
7613
|
+
"div",
|
|
7614
|
+
{
|
|
7615
|
+
className: `flex flex-col h-full bg-slate-100 text-slate-900 relative overflow-hidden ${className || ""}`,
|
|
7616
|
+
children: [
|
|
7617
|
+
navigatorMode === "floating" && /* @__PURE__ */ jsx23(LayersPanel, { registry }),
|
|
7618
|
+
activeTable && tableSpreadsheetMode === "floating" && /* @__PURE__ */ jsx23(
|
|
7619
|
+
TableSpreadsheetEditor,
|
|
7416
7620
|
{
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7621
|
+
registry,
|
|
7622
|
+
tableNode: activeTable,
|
|
7623
|
+
mode: "floating",
|
|
7624
|
+
onToggleMode: () => setTableSpreadsheetMode("docked"),
|
|
7625
|
+
onClose: () => setTableSpreadsheetMode("hidden")
|
|
7626
|
+
}
|
|
7627
|
+
),
|
|
7628
|
+
isMobileSidebarOpen && resolvedConfig.sidebar.enabled && /* @__PURE__ */ jsxs22("div", { className: "fixed inset-0 z-50 flex lg:hidden animate-in fade-in duration-200", children: [
|
|
7629
|
+
/* @__PURE__ */ jsx23(
|
|
7630
|
+
"div",
|
|
7631
|
+
{
|
|
7632
|
+
className: "fixed inset-0 bg-slate-950/50 backdrop-blur-xs transition-opacity",
|
|
7633
|
+
onClick: () => setIsMobileSidebarOpen(false)
|
|
7634
|
+
}
|
|
7635
|
+
),
|
|
7636
|
+
/* @__PURE__ */ jsxs22("div", { className: "relative w-80 max-w-[85vw] bg-white h-full shadow-2xl flex flex-col z-10 animate-in slide-in-from-left duration-200", children: [
|
|
7637
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between px-3.5 py-2.5 border-b border-slate-200 bg-slate-50", children: [
|
|
7638
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2", children: [
|
|
7639
|
+
/* @__PURE__ */ jsx23(Boxes2, { className: "w-4 h-4 text-blue-600" }),
|
|
7640
|
+
/* @__PURE__ */ jsx23("span", { className: "font-bold text-xs text-slate-800", children: "Add Components & Blocks" })
|
|
7641
|
+
] }),
|
|
7642
|
+
/* @__PURE__ */ jsx23(
|
|
7643
|
+
"button",
|
|
7644
|
+
{
|
|
7645
|
+
type: "button",
|
|
7646
|
+
onClick: () => setIsMobileSidebarOpen(false),
|
|
7647
|
+
className: "p-1 rounded-md text-slate-400 hover:text-slate-700 hover:bg-slate-200 transition",
|
|
7648
|
+
children: /* @__PURE__ */ jsx23(X5, { className: "w-4 h-4" })
|
|
7649
|
+
}
|
|
7650
|
+
)
|
|
7651
|
+
] }),
|
|
7652
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 overflow-hidden min-h-0", children: /* @__PURE__ */ jsx23(LeftSidebar, { registry, config: resolvedConfig.sidebar }) })
|
|
7653
|
+
] })
|
|
7654
|
+
] }),
|
|
7655
|
+
isMobileInspectorOpen && resolvedConfig.inspector.enabled && /* @__PURE__ */ jsxs22("div", { className: "fixed inset-0 z-50 flex justify-end lg:hidden animate-in fade-in duration-200", children: [
|
|
7656
|
+
/* @__PURE__ */ jsx23(
|
|
7657
|
+
"div",
|
|
7658
|
+
{
|
|
7659
|
+
className: "fixed inset-0 bg-slate-950/50 backdrop-blur-xs transition-opacity",
|
|
7660
|
+
onClick: () => setIsMobileInspectorOpen(false)
|
|
7661
|
+
}
|
|
7662
|
+
),
|
|
7663
|
+
/* @__PURE__ */ jsxs22("div", { className: "relative w-84 max-w-[90vw] sm:max-w-md bg-white h-full shadow-2xl flex flex-col z-10 animate-in slide-in-from-right duration-200", children: [
|
|
7664
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between px-3.5 py-2.5 border-b border-slate-200 bg-slate-50", children: [
|
|
7665
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2", children: [
|
|
7666
|
+
/* @__PURE__ */ jsx23(Sliders, { className: "w-4 h-4 text-blue-600" }),
|
|
7667
|
+
/* @__PURE__ */ jsx23("span", { className: "font-bold text-xs text-slate-800", children: selectedNodeId ? `Inspector (#${selectedNodeId})` : "Inspector & Properties" })
|
|
7668
|
+
] }),
|
|
7669
|
+
/* @__PURE__ */ jsx23(
|
|
7670
|
+
"button",
|
|
7671
|
+
{
|
|
7672
|
+
type: "button",
|
|
7673
|
+
onClick: () => setIsMobileInspectorOpen(false),
|
|
7674
|
+
className: "p-1 rounded-md text-slate-400 hover:text-slate-700 hover:bg-slate-200 transition",
|
|
7675
|
+
children: /* @__PURE__ */ jsx23(X5, { className: "w-4 h-4" })
|
|
7676
|
+
}
|
|
7677
|
+
)
|
|
7678
|
+
] }),
|
|
7679
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 overflow-hidden min-h-0", children: /* @__PURE__ */ jsx23(InspectorPanel, { registry, config: resolvedConfig.inspector }) })
|
|
7680
|
+
] })
|
|
7681
|
+
] }),
|
|
7682
|
+
isMobileLayersOpen && /* @__PURE__ */ jsxs22("div", { className: "fixed inset-0 z-50 flex lg:hidden animate-in fade-in duration-200", children: [
|
|
7683
|
+
/* @__PURE__ */ jsx23(
|
|
7684
|
+
"div",
|
|
7685
|
+
{
|
|
7686
|
+
className: "fixed inset-0 bg-slate-950/50 backdrop-blur-xs transition-opacity",
|
|
7687
|
+
onClick: () => setIsMobileLayersOpen(false)
|
|
7688
|
+
}
|
|
7689
|
+
),
|
|
7690
|
+
/* @__PURE__ */ jsxs22("div", { className: "relative w-72 max-w-[85vw] bg-white h-full shadow-2xl flex flex-col z-10 animate-in slide-in-from-left duration-200", children: [
|
|
7691
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between px-3.5 py-2.5 border-b border-slate-200 bg-slate-50", children: [
|
|
7692
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2", children: [
|
|
7693
|
+
/* @__PURE__ */ jsx23(Layers2, { className: "w-4 h-4 text-blue-600" }),
|
|
7694
|
+
/* @__PURE__ */ jsx23("span", { className: "font-bold text-xs text-slate-800", children: "Element Tree / Layers" })
|
|
7695
|
+
] }),
|
|
7696
|
+
/* @__PURE__ */ jsx23(
|
|
7697
|
+
"button",
|
|
7698
|
+
{
|
|
7699
|
+
type: "button",
|
|
7700
|
+
onClick: () => setIsMobileLayersOpen(false),
|
|
7701
|
+
className: "p-1 rounded-md text-slate-400 hover:text-slate-700 hover:bg-slate-200 transition",
|
|
7702
|
+
children: /* @__PURE__ */ jsx23(X5, { className: "w-4 h-4" })
|
|
7703
|
+
}
|
|
7704
|
+
)
|
|
7705
|
+
] }),
|
|
7706
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 overflow-hidden min-h-0", children: /* @__PURE__ */ jsx23(LayersPanel, { registry }) })
|
|
7707
|
+
] })
|
|
7708
|
+
] }),
|
|
7709
|
+
resolvedConfig.toolbar.enabled && /* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between px-3 py-1.5 sm:px-4 sm:py-2 bg-white border-b border-slate-200 gap-2 overflow-x-auto min-h-[44px]", children: [
|
|
7710
|
+
resolvedConfig.toolbar.showTitle ? /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
7711
|
+
/* @__PURE__ */ jsx23("span", { className: "font-bold text-slate-800 text-xs sm:text-sm tracking-tight", children: "KUBUILD Editor" }),
|
|
7712
|
+
/* @__PURE__ */ jsx23("span", { className: "text-[11px] bg-slate-100 text-slate-600 px-1.5 py-0.5 rounded border max-w-[120px] sm:max-w-[200px] truncate font-medium", children: document2.metadata?.title || "Untitled" })
|
|
7713
|
+
] }) : /* @__PURE__ */ jsx23("div", {}),
|
|
7714
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
7715
|
+
/* @__PURE__ */ jsx23(EditorToolbar, { registry, config: resolvedConfig.toolbar }),
|
|
7716
|
+
resolvedConfig.toolbar.showViewportSwitcher && /* @__PURE__ */ jsx23("div", { className: "flex items-center gap-0.5 bg-slate-100 p-0.5 sm:p-1 rounded-md text-xs border border-slate-200/80", children: ["desktop", "tablet", "mobile"].map((vp) => /* @__PURE__ */ jsxs22(
|
|
7717
|
+
"button",
|
|
7718
|
+
{
|
|
7719
|
+
type: "button",
|
|
7720
|
+
onClick: () => setViewport(vp),
|
|
7721
|
+
title: `Switch to ${vp} preview`,
|
|
7722
|
+
className: `px-2 py-1 sm:px-2.5 sm:py-1 rounded capitalize font-medium transition flex items-center gap-1 text-[11px] sm:text-xs ${viewport === vp ? "bg-white text-blue-600 shadow-xs font-semibold" : "text-slate-600 hover:text-slate-900"}`,
|
|
7723
|
+
children: [
|
|
7724
|
+
viewportIcons[vp],
|
|
7725
|
+
/* @__PURE__ */ jsx23("span", { className: "hidden md:inline", children: vp })
|
|
7726
|
+
]
|
|
7727
|
+
},
|
|
7728
|
+
vp
|
|
7729
|
+
)) })
|
|
7730
|
+
] }),
|
|
7731
|
+
resolvedConfig.toolbar.showSelectionStatus && /* @__PURE__ */ jsx23("div", { className: "hidden xl:block text-xs text-slate-500 shrink-0 font-mono", children: selectedNodeId ? `Selected: #${selectedNodeId}` : "No element selected" })
|
|
7732
|
+
] }),
|
|
7733
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex flex-1 overflow-hidden min-h-0 relative", children: [
|
|
7734
|
+
resolvedConfig.sidebar.enabled && /* @__PURE__ */ jsx23("div", { className: "hidden lg:flex w-80 shrink-0 bg-white border-r border-slate-200 overflow-hidden flex-col min-h-0 h-full", children: /* @__PURE__ */ jsx23(LeftSidebar, { registry, config: resolvedConfig.sidebar }) }),
|
|
7735
|
+
navigatorMode === "docked" && /* @__PURE__ */ jsx23("div", { className: "hidden lg:flex w-60 shrink-0 bg-white border-r border-slate-200 overflow-hidden flex-col min-h-0 h-full", children: /* @__PURE__ */ jsx23(LayersPanel, { registry }) }),
|
|
7736
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex-1 overflow-hidden flex flex-col min-h-0 h-full bg-slate-100/90 relative", children: [
|
|
7737
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 overflow-auto p-2 sm:p-4 md:p-8 flex justify-center items-start min-h-0", children: /* @__PURE__ */ jsx23(
|
|
7738
|
+
"div",
|
|
7739
|
+
{
|
|
7740
|
+
className: `${viewportWidthMap[viewport]} bg-white shadow-md rounded-lg overflow-hidden transition-all duration-200 min-h-[500px] border border-slate-200`,
|
|
7741
|
+
children: /* @__PURE__ */ jsx23(
|
|
7742
|
+
EditorCanvas,
|
|
7743
|
+
{
|
|
7744
|
+
registry,
|
|
7745
|
+
context: previewContext,
|
|
7746
|
+
viewport,
|
|
7747
|
+
onDiagnostic,
|
|
7748
|
+
config: resolvedConfig.canvas
|
|
7749
|
+
}
|
|
7750
|
+
)
|
|
7751
|
+
}
|
|
7752
|
+
) }),
|
|
7753
|
+
selectedNodeId && !isMobileInspectorOpen && resolvedConfig.inspector.enabled && /* @__PURE__ */ jsx23("div", { className: "lg:hidden fixed bottom-14 left-1/2 -translate-x-1/2 z-30 animate-in fade-in slide-in-from-bottom-2", children: /* @__PURE__ */ jsxs22(
|
|
7754
|
+
"button",
|
|
7755
|
+
{
|
|
7756
|
+
type: "button",
|
|
7757
|
+
onClick: () => setIsMobileInspectorOpen(true),
|
|
7758
|
+
className: "flex items-center gap-2 bg-blue-600 hover:bg-blue-500 text-white text-xs font-semibold px-4 py-2 rounded-full shadow-xl border border-blue-400/40 active:scale-95 transition",
|
|
7759
|
+
children: [
|
|
7760
|
+
/* @__PURE__ */ jsx23(Sliders, { className: "w-3.5 h-3.5" }),
|
|
7761
|
+
/* @__PURE__ */ jsxs22("span", { children: [
|
|
7762
|
+
"Edit Element (#",
|
|
7763
|
+
selectedNodeId,
|
|
7764
|
+
")"
|
|
7765
|
+
] })
|
|
7766
|
+
]
|
|
7767
|
+
}
|
|
7768
|
+
) }),
|
|
7769
|
+
resolvedConfig.canvas.showBreadcrumbs && /* @__PURE__ */ jsx23(HierarchyBreadcrumbs, { registry })
|
|
7770
|
+
] }),
|
|
7771
|
+
resolvedConfig.inspector.enabled && /* @__PURE__ */ jsx23("div", { className: "hidden lg:flex w-72 shrink-0 bg-white border-l border-slate-200 overflow-hidden flex-col min-h-0 h-full", children: /* @__PURE__ */ jsx23(InspectorPanel, { registry, config: resolvedConfig.inspector }) })
|
|
7772
|
+
] }),
|
|
7773
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex lg:hidden items-center justify-around bg-white border-t border-slate-200 px-2 py-1.5 z-20 shrink-0 shadow-lg select-none min-h-[48px]", children: [
|
|
7774
|
+
resolvedConfig.sidebar.enabled && /* @__PURE__ */ jsxs22(
|
|
7775
|
+
"button",
|
|
7776
|
+
{
|
|
7777
|
+
type: "button",
|
|
7778
|
+
onClick: () => setIsMobileSidebarOpen(true),
|
|
7779
|
+
className: "flex flex-col items-center justify-center gap-0.5 px-3 py-1 rounded-md text-slate-600 hover:text-blue-600 hover:bg-slate-50 active:bg-slate-100 transition",
|
|
7780
|
+
children: [
|
|
7781
|
+
/* @__PURE__ */ jsx23(Plus, { className: "w-4 h-4 text-blue-600" }),
|
|
7782
|
+
/* @__PURE__ */ jsx23("span", { className: "text-[10px] font-medium", children: "Add" })
|
|
7783
|
+
]
|
|
7784
|
+
}
|
|
7785
|
+
),
|
|
7786
|
+
/* @__PURE__ */ jsxs22(
|
|
7787
|
+
"button",
|
|
7788
|
+
{
|
|
7789
|
+
type: "button",
|
|
7790
|
+
onClick: () => setIsMobileLayersOpen(true),
|
|
7791
|
+
className: "flex flex-col items-center justify-center gap-0.5 px-3 py-1 rounded-md text-slate-600 hover:text-blue-600 hover:bg-slate-50 active:bg-slate-100 transition",
|
|
7792
|
+
children: [
|
|
7793
|
+
/* @__PURE__ */ jsx23(Layers2, { className: "w-4 h-4" }),
|
|
7794
|
+
/* @__PURE__ */ jsx23("span", { className: "text-[10px] font-medium", children: "Layers" })
|
|
7795
|
+
]
|
|
7796
|
+
}
|
|
7797
|
+
),
|
|
7798
|
+
resolvedConfig.inspector.enabled && /* @__PURE__ */ jsxs22(
|
|
7799
|
+
"button",
|
|
7800
|
+
{
|
|
7801
|
+
type: "button",
|
|
7802
|
+
onClick: () => setIsMobileInspectorOpen(true),
|
|
7803
|
+
className: `flex flex-col items-center justify-center gap-0.5 px-3 py-1 rounded-md transition relative ${selectedNodeId ? "text-blue-600 font-semibold" : "text-slate-600 hover:text-blue-600 hover:bg-slate-50"}`,
|
|
7804
|
+
children: [
|
|
7805
|
+
/* @__PURE__ */ jsxs22("div", { className: "relative", children: [
|
|
7806
|
+
/* @__PURE__ */ jsx23(Sliders, { className: "w-4 h-4" }),
|
|
7807
|
+
selectedNodeId && /* @__PURE__ */ jsx23("span", { className: "absolute -top-1 -right-1 w-2 h-2 rounded-full bg-blue-600 ring-2 ring-white" })
|
|
7808
|
+
] }),
|
|
7809
|
+
/* @__PURE__ */ jsx23("span", { className: "text-[10px]", children: selectedNodeId ? "Inspect *" : "Inspect" })
|
|
7810
|
+
]
|
|
7811
|
+
}
|
|
7812
|
+
),
|
|
7813
|
+
/* @__PURE__ */ jsx23("div", { className: "h-5 w-px bg-slate-200 mx-0.5" }),
|
|
7814
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-1", children: [
|
|
7815
|
+
/* @__PURE__ */ jsx23(
|
|
7816
|
+
"button",
|
|
7817
|
+
{
|
|
7818
|
+
type: "button",
|
|
7819
|
+
disabled: !canUndo,
|
|
7820
|
+
onClick: undo,
|
|
7821
|
+
title: "Undo",
|
|
7822
|
+
className: "p-2 rounded text-slate-600 hover:text-blue-600 disabled:opacity-30 disabled:hover:text-slate-600 transition",
|
|
7823
|
+
children: /* @__PURE__ */ jsx23(Undo22, { className: "w-4 h-4" })
|
|
7824
|
+
}
|
|
7825
|
+
),
|
|
7826
|
+
/* @__PURE__ */ jsx23(
|
|
7827
|
+
"button",
|
|
7420
7828
|
{
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
|
|
7829
|
+
type: "button",
|
|
7830
|
+
disabled: !canRedo,
|
|
7831
|
+
onClick: redo,
|
|
7832
|
+
title: "Redo",
|
|
7833
|
+
className: "p-2 rounded text-slate-600 hover:text-blue-600 disabled:opacity-30 disabled:hover:text-slate-600 transition",
|
|
7834
|
+
children: /* @__PURE__ */ jsx23(Redo22, { className: "w-4 h-4" })
|
|
7426
7835
|
}
|
|
7427
7836
|
)
|
|
7428
|
-
}
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
] })
|
|
7434
|
-
] });
|
|
7837
|
+
] })
|
|
7838
|
+
] })
|
|
7839
|
+
]
|
|
7840
|
+
}
|
|
7841
|
+
);
|
|
7435
7842
|
};
|
|
7436
7843
|
export {
|
|
7437
7844
|
ANIMATION_TYPES,
|