@kubuild/editor 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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 +504 -120
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +511 -119
- package/dist/index.js.map +1 -1
- package/dist/store.d.ts +15 -2
- package/dist/store.d.ts.map +1 -1
- package/dist/toolbar.d.ts.map +1 -1
- package/package.json +2 -2
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
|
)
|
|
@@ -6973,7 +7128,15 @@ import { Boxes, Blocks, Layers } from "lucide-react";
|
|
|
6973
7128
|
// src/component-panel.tsx
|
|
6974
7129
|
import { useState as useState14 } from "react";
|
|
6975
7130
|
import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
6976
|
-
var CATEGORY_ORDER = [
|
|
7131
|
+
var CATEGORY_ORDER = [
|
|
7132
|
+
"layout",
|
|
7133
|
+
"typography",
|
|
7134
|
+
"media",
|
|
7135
|
+
"form",
|
|
7136
|
+
"interactive",
|
|
7137
|
+
"data",
|
|
7138
|
+
"custom"
|
|
7139
|
+
];
|
|
6977
7140
|
var CATEGORY_LABELS = {
|
|
6978
7141
|
layout: "Layout",
|
|
6979
7142
|
typography: "Typography",
|
|
@@ -6985,6 +7148,7 @@ var CATEGORY_LABELS = {
|
|
|
6985
7148
|
};
|
|
6986
7149
|
var ComponentPanel = ({ registry, className }) => {
|
|
6987
7150
|
const insertComponent = useEditorStore((s) => s.insertComponent);
|
|
7151
|
+
const setDragPayload = useEditorStore((s) => s.setDragPayload);
|
|
6988
7152
|
const [error, setError] = useState14(null);
|
|
6989
7153
|
const groups = CATEGORY_ORDER.map((category) => ({
|
|
6990
7154
|
category,
|
|
@@ -6994,6 +7158,16 @@ var ComponentPanel = ({ registry, className }) => {
|
|
|
6994
7158
|
const result = insertComponent(definition.type, registry);
|
|
6995
7159
|
setError(result.success ? null : result.error ?? `Could not insert "${definition.label}".`);
|
|
6996
7160
|
};
|
|
7161
|
+
const handleDragStart = (e, definition) => {
|
|
7162
|
+
e.dataTransfer.effectAllowed = "copy";
|
|
7163
|
+
e.dataTransfer.setData("text/plain", `component:${definition.type}`);
|
|
7164
|
+
e.dataTransfer.setData("application/kubuild-drag-type", "component");
|
|
7165
|
+
e.dataTransfer.setData("application/kubuild-component-type", definition.type);
|
|
7166
|
+
setDragPayload({ type: "component", componentType: definition.type });
|
|
7167
|
+
};
|
|
7168
|
+
const handleDragEnd = () => {
|
|
7169
|
+
setDragPayload(null);
|
|
7170
|
+
};
|
|
6997
7171
|
return /* @__PURE__ */ jsxs19("div", { className: `flex flex-col gap-4 p-3 overflow-y-auto h-full min-h-0 ${className || ""}`, children: [
|
|
6998
7172
|
error && /* @__PURE__ */ jsx20(
|
|
6999
7173
|
"div",
|
|
@@ -7009,12 +7183,16 @@ var ComponentPanel = ({ registry, className }) => {
|
|
|
7009
7183
|
"button",
|
|
7010
7184
|
{
|
|
7011
7185
|
type: "button",
|
|
7186
|
+
draggable: true,
|
|
7187
|
+
onDragStart: (e) => handleDragStart(e, definition),
|
|
7188
|
+
onDragEnd: handleDragEnd,
|
|
7012
7189
|
onClick: () => handleInsert(definition),
|
|
7013
|
-
|
|
7014
|
-
|
|
7190
|
+
"data-testid": `component-item-${definition.type}`,
|
|
7191
|
+
title: definition.description || `Click to insert or drag to canvas: ${definition.label}`,
|
|
7192
|
+
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
7193
|
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
|
|
7194
|
+
/* @__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 }) }),
|
|
7195
|
+
/* @__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
7196
|
]
|
|
7019
7197
|
},
|
|
7020
7198
|
definition.type
|
|
@@ -7025,7 +7203,7 @@ var ComponentPanel = ({ registry, className }) => {
|
|
|
7025
7203
|
|
|
7026
7204
|
// src/blocks-panel.tsx
|
|
7027
7205
|
import { useState as useState15, useMemo as useMemo3 } from "react";
|
|
7028
|
-
import { STARTER_BLOCKS } from "@kubuild/components";
|
|
7206
|
+
import { STARTER_BLOCKS as STARTER_BLOCKS2 } from "@kubuild/components";
|
|
7029
7207
|
import { insertNode as insertNode2, collectNodeIdSet as collectNodeIdSet2 } from "@kubuild/core";
|
|
7030
7208
|
import { Image as ImageIcon } from "lucide-react";
|
|
7031
7209
|
import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
@@ -7091,7 +7269,7 @@ var BlockThumbnail = ({ block }) => {
|
|
|
7091
7269
|
}
|
|
7092
7270
|
};
|
|
7093
7271
|
var BlocksPanel = ({
|
|
7094
|
-
blocks =
|
|
7272
|
+
blocks = STARTER_BLOCKS2,
|
|
7095
7273
|
className,
|
|
7096
7274
|
onInsertBlock
|
|
7097
7275
|
}) => {
|
|
@@ -7135,6 +7313,17 @@ var BlocksPanel = ({
|
|
|
7135
7313
|
selectNode(nodeTree.id);
|
|
7136
7314
|
}
|
|
7137
7315
|
};
|
|
7316
|
+
const setDragPayload = useEditorStore((s) => s.setDragPayload);
|
|
7317
|
+
const handleDragStart = (e, block) => {
|
|
7318
|
+
e.dataTransfer.effectAllowed = "copy";
|
|
7319
|
+
e.dataTransfer.setData("text/plain", `block:${block.id}`);
|
|
7320
|
+
e.dataTransfer.setData("application/kubuild-drag-type", "block");
|
|
7321
|
+
e.dataTransfer.setData("application/kubuild-block-id", block.id);
|
|
7322
|
+
setDragPayload({ type: "block", blockId: block.id });
|
|
7323
|
+
};
|
|
7324
|
+
const handleDragEnd = () => {
|
|
7325
|
+
setDragPayload(null);
|
|
7326
|
+
};
|
|
7138
7327
|
return /* @__PURE__ */ jsxs20(
|
|
7139
7328
|
"div",
|
|
7140
7329
|
{
|
|
@@ -7165,13 +7354,17 @@ var BlocksPanel = ({
|
|
|
7165
7354
|
"button",
|
|
7166
7355
|
{
|
|
7167
7356
|
type: "button",
|
|
7357
|
+
draggable: true,
|
|
7358
|
+
onDragStart: (e) => handleDragStart(e, block),
|
|
7359
|
+
onDragEnd: handleDragEnd,
|
|
7168
7360
|
"data-testid": "block-card",
|
|
7169
7361
|
"data-block-id": block.id,
|
|
7170
7362
|
onClick: () => handleInsert(block),
|
|
7171
|
-
|
|
7363
|
+
title: block.description || `Click to insert or drag to canvas: ${block.name}`,
|
|
7364
|
+
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
7365
|
children: [
|
|
7173
|
-
/* @__PURE__ */ jsx21("div", { className: "mb-2 w-full", children: /* @__PURE__ */ jsx21(BlockThumbnail, { block }) }),
|
|
7174
|
-
/* @__PURE__ */ jsxs20("div", { className: "w-full", children: [
|
|
7366
|
+
/* @__PURE__ */ jsx21("div", { className: "mb-2 w-full pointer-events-none", children: /* @__PURE__ */ jsx21(BlockThumbnail, { block }) }),
|
|
7367
|
+
/* @__PURE__ */ jsxs20("div", { className: "w-full pointer-events-none", children: [
|
|
7175
7368
|
/* @__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
7369
|
/* @__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
7370
|
] })
|
|
@@ -7321,6 +7514,18 @@ function resolveEditorConfig(config) {
|
|
|
7321
7514
|
}
|
|
7322
7515
|
|
|
7323
7516
|
// src/editor.tsx
|
|
7517
|
+
import {
|
|
7518
|
+
Monitor,
|
|
7519
|
+
Tablet,
|
|
7520
|
+
Smartphone,
|
|
7521
|
+
Plus,
|
|
7522
|
+
Layers as Layers2,
|
|
7523
|
+
Sliders,
|
|
7524
|
+
Undo2 as Undo22,
|
|
7525
|
+
Redo2 as Redo22,
|
|
7526
|
+
X as X5,
|
|
7527
|
+
Boxes as Boxes2
|
|
7528
|
+
} from "lucide-react";
|
|
7324
7529
|
import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
7325
7530
|
var KubuildEditor = ({
|
|
7326
7531
|
initialDocument,
|
|
@@ -7342,9 +7547,16 @@ var KubuildEditor = ({
|
|
|
7342
7547
|
selectedNodeId,
|
|
7343
7548
|
navigatorMode,
|
|
7344
7549
|
tableSpreadsheetMode,
|
|
7345
|
-
setTableSpreadsheetMode
|
|
7550
|
+
setTableSpreadsheetMode,
|
|
7551
|
+
undo,
|
|
7552
|
+
redo,
|
|
7553
|
+
canUndo,
|
|
7554
|
+
canRedo
|
|
7346
7555
|
} = useEditorStore();
|
|
7347
7556
|
const lastLoadedDocRef = React19.useRef(void 0);
|
|
7557
|
+
const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState17(false);
|
|
7558
|
+
const [isMobileInspectorOpen, setIsMobileInspectorOpen] = useState17(false);
|
|
7559
|
+
const [isMobileLayersOpen, setIsMobileLayersOpen] = useState17(false);
|
|
7348
7560
|
const activeTable = useMemo4(
|
|
7349
7561
|
() => findActiveTableNode(document2.document, selectedNodeId),
|
|
7350
7562
|
[document2.document, selectedNodeId]
|
|
@@ -7373,65 +7585,245 @@ var KubuildEditor = ({
|
|
|
7373
7585
|
}, [context, sampleVariables]);
|
|
7374
7586
|
const viewportWidthMap = {
|
|
7375
7587
|
desktop: "w-full max-w-6xl",
|
|
7376
|
-
tablet: "w-[768px]",
|
|
7377
|
-
mobile: "w-[375px]"
|
|
7588
|
+
tablet: "w-full max-w-[768px] sm:w-[768px]",
|
|
7589
|
+
mobile: "w-full max-w-[375px] sm:w-[375px]"
|
|
7590
|
+
};
|
|
7591
|
+
const viewportIcons = {
|
|
7592
|
+
desktop: /* @__PURE__ */ jsx23(Monitor, { className: "w-3.5 h-3.5" }),
|
|
7593
|
+
tablet: /* @__PURE__ */ jsx23(Tablet, { className: "w-3.5 h-3.5" }),
|
|
7594
|
+
mobile: /* @__PURE__ */ jsx23(Smartphone, { className: "w-3.5 h-3.5" })
|
|
7378
7595
|
};
|
|
7379
7596
|
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",
|
|
7597
|
+
return /* @__PURE__ */ jsxs22(
|
|
7598
|
+
"div",
|
|
7599
|
+
{
|
|
7600
|
+
className: `flex flex-col h-full bg-slate-100 text-slate-900 relative overflow-hidden ${className || ""}`,
|
|
7601
|
+
children: [
|
|
7602
|
+
navigatorMode === "floating" && /* @__PURE__ */ jsx23(LayersPanel, { registry }),
|
|
7603
|
+
activeTable && tableSpreadsheetMode === "floating" && /* @__PURE__ */ jsx23(
|
|
7604
|
+
TableSpreadsheetEditor,
|
|
7416
7605
|
{
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7606
|
+
registry,
|
|
7607
|
+
tableNode: activeTable,
|
|
7608
|
+
mode: "floating",
|
|
7609
|
+
onToggleMode: () => setTableSpreadsheetMode("docked"),
|
|
7610
|
+
onClose: () => setTableSpreadsheetMode("hidden")
|
|
7611
|
+
}
|
|
7612
|
+
),
|
|
7613
|
+
isMobileSidebarOpen && resolvedConfig.sidebar.enabled && /* @__PURE__ */ jsxs22("div", { className: "fixed inset-0 z-50 flex lg:hidden animate-in fade-in duration-200", children: [
|
|
7614
|
+
/* @__PURE__ */ jsx23(
|
|
7615
|
+
"div",
|
|
7616
|
+
{
|
|
7617
|
+
className: "fixed inset-0 bg-slate-950/50 backdrop-blur-xs transition-opacity",
|
|
7618
|
+
onClick: () => setIsMobileSidebarOpen(false)
|
|
7619
|
+
}
|
|
7620
|
+
),
|
|
7621
|
+
/* @__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: [
|
|
7622
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between px-3.5 py-2.5 border-b border-slate-200 bg-slate-50", children: [
|
|
7623
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2", children: [
|
|
7624
|
+
/* @__PURE__ */ jsx23(Boxes2, { className: "w-4 h-4 text-blue-600" }),
|
|
7625
|
+
/* @__PURE__ */ jsx23("span", { className: "font-bold text-xs text-slate-800", children: "Add Components & Blocks" })
|
|
7626
|
+
] }),
|
|
7627
|
+
/* @__PURE__ */ jsx23(
|
|
7628
|
+
"button",
|
|
7629
|
+
{
|
|
7630
|
+
type: "button",
|
|
7631
|
+
onClick: () => setIsMobileSidebarOpen(false),
|
|
7632
|
+
className: "p-1 rounded-md text-slate-400 hover:text-slate-700 hover:bg-slate-200 transition",
|
|
7633
|
+
children: /* @__PURE__ */ jsx23(X5, { className: "w-4 h-4" })
|
|
7634
|
+
}
|
|
7635
|
+
)
|
|
7636
|
+
] }),
|
|
7637
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 overflow-hidden min-h-0", children: /* @__PURE__ */ jsx23(LeftSidebar, { registry, config: resolvedConfig.sidebar }) })
|
|
7638
|
+
] })
|
|
7639
|
+
] }),
|
|
7640
|
+
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: [
|
|
7641
|
+
/* @__PURE__ */ jsx23(
|
|
7642
|
+
"div",
|
|
7643
|
+
{
|
|
7644
|
+
className: "fixed inset-0 bg-slate-950/50 backdrop-blur-xs transition-opacity",
|
|
7645
|
+
onClick: () => setIsMobileInspectorOpen(false)
|
|
7646
|
+
}
|
|
7647
|
+
),
|
|
7648
|
+
/* @__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: [
|
|
7649
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between px-3.5 py-2.5 border-b border-slate-200 bg-slate-50", children: [
|
|
7650
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2", children: [
|
|
7651
|
+
/* @__PURE__ */ jsx23(Sliders, { className: "w-4 h-4 text-blue-600" }),
|
|
7652
|
+
/* @__PURE__ */ jsx23("span", { className: "font-bold text-xs text-slate-800", children: selectedNodeId ? `Inspector (#${selectedNodeId})` : "Inspector & Properties" })
|
|
7653
|
+
] }),
|
|
7654
|
+
/* @__PURE__ */ jsx23(
|
|
7655
|
+
"button",
|
|
7656
|
+
{
|
|
7657
|
+
type: "button",
|
|
7658
|
+
onClick: () => setIsMobileInspectorOpen(false),
|
|
7659
|
+
className: "p-1 rounded-md text-slate-400 hover:text-slate-700 hover:bg-slate-200 transition",
|
|
7660
|
+
children: /* @__PURE__ */ jsx23(X5, { className: "w-4 h-4" })
|
|
7661
|
+
}
|
|
7662
|
+
)
|
|
7663
|
+
] }),
|
|
7664
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 overflow-hidden min-h-0", children: /* @__PURE__ */ jsx23(InspectorPanel, { registry, config: resolvedConfig.inspector }) })
|
|
7665
|
+
] })
|
|
7666
|
+
] }),
|
|
7667
|
+
isMobileLayersOpen && /* @__PURE__ */ jsxs22("div", { className: "fixed inset-0 z-50 flex lg:hidden animate-in fade-in duration-200", children: [
|
|
7668
|
+
/* @__PURE__ */ jsx23(
|
|
7669
|
+
"div",
|
|
7670
|
+
{
|
|
7671
|
+
className: "fixed inset-0 bg-slate-950/50 backdrop-blur-xs transition-opacity",
|
|
7672
|
+
onClick: () => setIsMobileLayersOpen(false)
|
|
7673
|
+
}
|
|
7674
|
+
),
|
|
7675
|
+
/* @__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: [
|
|
7676
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between px-3.5 py-2.5 border-b border-slate-200 bg-slate-50", children: [
|
|
7677
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2", children: [
|
|
7678
|
+
/* @__PURE__ */ jsx23(Layers2, { className: "w-4 h-4 text-blue-600" }),
|
|
7679
|
+
/* @__PURE__ */ jsx23("span", { className: "font-bold text-xs text-slate-800", children: "Element Tree / Layers" })
|
|
7680
|
+
] }),
|
|
7681
|
+
/* @__PURE__ */ jsx23(
|
|
7682
|
+
"button",
|
|
7683
|
+
{
|
|
7684
|
+
type: "button",
|
|
7685
|
+
onClick: () => setIsMobileLayersOpen(false),
|
|
7686
|
+
className: "p-1 rounded-md text-slate-400 hover:text-slate-700 hover:bg-slate-200 transition",
|
|
7687
|
+
children: /* @__PURE__ */ jsx23(X5, { className: "w-4 h-4" })
|
|
7688
|
+
}
|
|
7689
|
+
)
|
|
7690
|
+
] }),
|
|
7691
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 overflow-hidden min-h-0", children: /* @__PURE__ */ jsx23(LayersPanel, { registry }) })
|
|
7692
|
+
] })
|
|
7693
|
+
] }),
|
|
7694
|
+
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: [
|
|
7695
|
+
resolvedConfig.toolbar.showTitle ? /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
7696
|
+
/* @__PURE__ */ jsx23("span", { className: "font-bold text-slate-800 text-xs sm:text-sm tracking-tight", children: "KUBUILD Editor" }),
|
|
7697
|
+
/* @__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" })
|
|
7698
|
+
] }) : /* @__PURE__ */ jsx23("div", {}),
|
|
7699
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
7700
|
+
/* @__PURE__ */ jsx23(EditorToolbar, { registry, config: resolvedConfig.toolbar }),
|
|
7701
|
+
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(
|
|
7702
|
+
"button",
|
|
7703
|
+
{
|
|
7704
|
+
type: "button",
|
|
7705
|
+
onClick: () => setViewport(vp),
|
|
7706
|
+
title: `Switch to ${vp} preview`,
|
|
7707
|
+
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"}`,
|
|
7708
|
+
children: [
|
|
7709
|
+
viewportIcons[vp],
|
|
7710
|
+
/* @__PURE__ */ jsx23("span", { className: "hidden md:inline", children: vp })
|
|
7711
|
+
]
|
|
7712
|
+
},
|
|
7713
|
+
vp
|
|
7714
|
+
)) })
|
|
7715
|
+
] }),
|
|
7716
|
+
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" })
|
|
7717
|
+
] }),
|
|
7718
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex flex-1 overflow-hidden min-h-0 relative", children: [
|
|
7719
|
+
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 }) }),
|
|
7720
|
+
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 }) }),
|
|
7721
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex-1 overflow-hidden flex flex-col min-h-0 h-full bg-slate-100/90 relative", children: [
|
|
7722
|
+
/* @__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(
|
|
7723
|
+
"div",
|
|
7420
7724
|
{
|
|
7421
|
-
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
|
|
7425
|
-
|
|
7725
|
+
className: `${viewportWidthMap[viewport]} bg-white shadow-md rounded-lg overflow-hidden transition-all duration-200 min-h-[500px] border border-slate-200`,
|
|
7726
|
+
children: /* @__PURE__ */ jsx23(
|
|
7727
|
+
EditorCanvas,
|
|
7728
|
+
{
|
|
7729
|
+
registry,
|
|
7730
|
+
context: previewContext,
|
|
7731
|
+
viewport,
|
|
7732
|
+
onDiagnostic,
|
|
7733
|
+
config: resolvedConfig.canvas
|
|
7734
|
+
}
|
|
7735
|
+
)
|
|
7736
|
+
}
|
|
7737
|
+
) }),
|
|
7738
|
+
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(
|
|
7739
|
+
"button",
|
|
7740
|
+
{
|
|
7741
|
+
type: "button",
|
|
7742
|
+
onClick: () => setIsMobileInspectorOpen(true),
|
|
7743
|
+
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",
|
|
7744
|
+
children: [
|
|
7745
|
+
/* @__PURE__ */ jsx23(Sliders, { className: "w-3.5 h-3.5" }),
|
|
7746
|
+
/* @__PURE__ */ jsxs22("span", { children: [
|
|
7747
|
+
"Edit Element (#",
|
|
7748
|
+
selectedNodeId,
|
|
7749
|
+
")"
|
|
7750
|
+
] })
|
|
7751
|
+
]
|
|
7752
|
+
}
|
|
7753
|
+
) }),
|
|
7754
|
+
resolvedConfig.canvas.showBreadcrumbs && /* @__PURE__ */ jsx23(HierarchyBreadcrumbs, { registry })
|
|
7755
|
+
] }),
|
|
7756
|
+
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 }) })
|
|
7757
|
+
] }),
|
|
7758
|
+
/* @__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: [
|
|
7759
|
+
resolvedConfig.sidebar.enabled && /* @__PURE__ */ jsxs22(
|
|
7760
|
+
"button",
|
|
7761
|
+
{
|
|
7762
|
+
type: "button",
|
|
7763
|
+
onClick: () => setIsMobileSidebarOpen(true),
|
|
7764
|
+
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",
|
|
7765
|
+
children: [
|
|
7766
|
+
/* @__PURE__ */ jsx23(Plus, { className: "w-4 h-4 text-blue-600" }),
|
|
7767
|
+
/* @__PURE__ */ jsx23("span", { className: "text-[10px] font-medium", children: "Add" })
|
|
7768
|
+
]
|
|
7769
|
+
}
|
|
7770
|
+
),
|
|
7771
|
+
/* @__PURE__ */ jsxs22(
|
|
7772
|
+
"button",
|
|
7773
|
+
{
|
|
7774
|
+
type: "button",
|
|
7775
|
+
onClick: () => setIsMobileLayersOpen(true),
|
|
7776
|
+
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",
|
|
7777
|
+
children: [
|
|
7778
|
+
/* @__PURE__ */ jsx23(Layers2, { className: "w-4 h-4" }),
|
|
7779
|
+
/* @__PURE__ */ jsx23("span", { className: "text-[10px] font-medium", children: "Layers" })
|
|
7780
|
+
]
|
|
7781
|
+
}
|
|
7782
|
+
),
|
|
7783
|
+
resolvedConfig.inspector.enabled && /* @__PURE__ */ jsxs22(
|
|
7784
|
+
"button",
|
|
7785
|
+
{
|
|
7786
|
+
type: "button",
|
|
7787
|
+
onClick: () => setIsMobileInspectorOpen(true),
|
|
7788
|
+
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"}`,
|
|
7789
|
+
children: [
|
|
7790
|
+
/* @__PURE__ */ jsxs22("div", { className: "relative", children: [
|
|
7791
|
+
/* @__PURE__ */ jsx23(Sliders, { className: "w-4 h-4" }),
|
|
7792
|
+
selectedNodeId && /* @__PURE__ */ jsx23("span", { className: "absolute -top-1 -right-1 w-2 h-2 rounded-full bg-blue-600 ring-2 ring-white" })
|
|
7793
|
+
] }),
|
|
7794
|
+
/* @__PURE__ */ jsx23("span", { className: "text-[10px]", children: selectedNodeId ? "Inspect *" : "Inspect" })
|
|
7795
|
+
]
|
|
7796
|
+
}
|
|
7797
|
+
),
|
|
7798
|
+
/* @__PURE__ */ jsx23("div", { className: "h-5 w-px bg-slate-200 mx-0.5" }),
|
|
7799
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-1", children: [
|
|
7800
|
+
/* @__PURE__ */ jsx23(
|
|
7801
|
+
"button",
|
|
7802
|
+
{
|
|
7803
|
+
type: "button",
|
|
7804
|
+
disabled: !canUndo,
|
|
7805
|
+
onClick: undo,
|
|
7806
|
+
title: "Undo",
|
|
7807
|
+
className: "p-2 rounded text-slate-600 hover:text-blue-600 disabled:opacity-30 disabled:hover:text-slate-600 transition",
|
|
7808
|
+
children: /* @__PURE__ */ jsx23(Undo22, { className: "w-4 h-4" })
|
|
7809
|
+
}
|
|
7810
|
+
),
|
|
7811
|
+
/* @__PURE__ */ jsx23(
|
|
7812
|
+
"button",
|
|
7813
|
+
{
|
|
7814
|
+
type: "button",
|
|
7815
|
+
disabled: !canRedo,
|
|
7816
|
+
onClick: redo,
|
|
7817
|
+
title: "Redo",
|
|
7818
|
+
className: "p-2 rounded text-slate-600 hover:text-blue-600 disabled:opacity-30 disabled:hover:text-slate-600 transition",
|
|
7819
|
+
children: /* @__PURE__ */ jsx23(Redo22, { className: "w-4 h-4" })
|
|
7426
7820
|
}
|
|
7427
7821
|
)
|
|
7428
|
-
}
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
] })
|
|
7434
|
-
] });
|
|
7822
|
+
] })
|
|
7823
|
+
] })
|
|
7824
|
+
]
|
|
7825
|
+
}
|
|
7826
|
+
);
|
|
7435
7827
|
};
|
|
7436
7828
|
export {
|
|
7437
7829
|
ANIMATION_TYPES,
|