@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.cjs
CHANGED
|
@@ -88,12 +88,13 @@ module.exports = __toCommonJS(index_exports);
|
|
|
88
88
|
|
|
89
89
|
// src/editor.tsx
|
|
90
90
|
var import_react19 = __toESM(require("react"), 1);
|
|
91
|
-
var
|
|
91
|
+
var import_components7 = require("@kubuild/components");
|
|
92
92
|
var import_core12 = require("@kubuild/core");
|
|
93
93
|
|
|
94
94
|
// src/store.ts
|
|
95
95
|
var import_zustand = require("zustand");
|
|
96
96
|
var import_core = require("@kubuild/core");
|
|
97
|
+
var import_components = require("@kubuild/components");
|
|
97
98
|
function formatCommandError(err) {
|
|
98
99
|
if (err && typeof err === "object" && Array.isArray(err.issues)) {
|
|
99
100
|
const issues = err.issues;
|
|
@@ -118,7 +119,11 @@ function buildDefaultChildren(specs, existingIds, registry) {
|
|
|
118
119
|
const def = registry.get(spec.type);
|
|
119
120
|
const nodeProps = (0, import_core.deepClone)(spec.props ?? def?.defaultProps ?? {});
|
|
120
121
|
const nodeStyles = spec.styles ?? def?.defaultStyles;
|
|
121
|
-
const childNodes = buildDefaultChildren(
|
|
122
|
+
const childNodes = buildDefaultChildren(
|
|
123
|
+
spec.children ?? def?.defaultChildren,
|
|
124
|
+
existingIds,
|
|
125
|
+
registry
|
|
126
|
+
);
|
|
122
127
|
const node = {
|
|
123
128
|
id,
|
|
124
129
|
type: spec.type,
|
|
@@ -138,6 +143,7 @@ var useEditorStore = (0, import_zustand.create)((set, get) => ({
|
|
|
138
143
|
document: historyManager.document,
|
|
139
144
|
selectedNodeId: null,
|
|
140
145
|
hoveredNodeId: null,
|
|
146
|
+
dragPayload: null,
|
|
141
147
|
viewport: "desktop",
|
|
142
148
|
isDirty: false,
|
|
143
149
|
canUndo: false,
|
|
@@ -147,6 +153,7 @@ var useEditorStore = (0, import_zustand.create)((set, get) => ({
|
|
|
147
153
|
variableCatalog: [],
|
|
148
154
|
navigatorMode: "floating",
|
|
149
155
|
tableSpreadsheetMode: "floating",
|
|
156
|
+
setDragPayload: (payload) => set({ dragPayload: payload }),
|
|
150
157
|
setVariableCatalog: (catalog) => set({ variableCatalog: catalog }),
|
|
151
158
|
setNavigatorMode: (mode) => set({ navigatorMode: mode }),
|
|
152
159
|
toggleNavigator: () => set((state) => ({
|
|
@@ -163,6 +170,7 @@ var useEditorStore = (0, import_zustand.create)((set, get) => ({
|
|
|
163
170
|
isDirty: false,
|
|
164
171
|
selectedNodeId: null,
|
|
165
172
|
hoveredNodeId: null,
|
|
173
|
+
dragPayload: null,
|
|
166
174
|
clipboard: null,
|
|
167
175
|
canUndo: false,
|
|
168
176
|
canRedo: false
|
|
@@ -181,12 +189,15 @@ var useEditorStore = (0, import_zustand.create)((set, get) => ({
|
|
|
181
189
|
});
|
|
182
190
|
onChangeHandler?.(result.document);
|
|
183
191
|
},
|
|
184
|
-
insertComponent: (type, registry, parentId) => {
|
|
192
|
+
insertComponent: (type, registry, parentId, index) => {
|
|
185
193
|
const state = get();
|
|
186
194
|
const targetParentId = parentId ?? state.selectedNodeId ?? state.document.document.id;
|
|
187
195
|
const parentNode = (0, import_core.findNodeById)(state.document.document, targetParentId);
|
|
188
196
|
if (!parentNode) {
|
|
189
|
-
return {
|
|
197
|
+
return {
|
|
198
|
+
success: false,
|
|
199
|
+
error: `Insertion target "${targetParentId}" was not found in the document.`
|
|
200
|
+
};
|
|
190
201
|
}
|
|
191
202
|
const definition = registry.get(type);
|
|
192
203
|
if (!definition) {
|
|
@@ -203,7 +214,10 @@ var useEditorStore = (0, import_zustand.create)((set, get) => ({
|
|
|
203
214
|
return { success: false, error: propResult.join(" ") };
|
|
204
215
|
}
|
|
205
216
|
if (propResult === false) {
|
|
206
|
-
return {
|
|
217
|
+
return {
|
|
218
|
+
success: false,
|
|
219
|
+
error: `Default props for "${definition.label}" failed validation.`
|
|
220
|
+
};
|
|
207
221
|
}
|
|
208
222
|
}
|
|
209
223
|
const existingIds = (0, import_core.collectNodeIdSet)(state.document.document);
|
|
@@ -217,10 +231,49 @@ var useEditorStore = (0, import_zustand.create)((set, get) => ({
|
|
|
217
231
|
...definition.defaultStyles ? { styles: (0, import_core.deepClone)(definition.defaultStyles) } : {},
|
|
218
232
|
...children ? { children } : {}
|
|
219
233
|
};
|
|
220
|
-
get().dispatch((doc) => (0, import_core.insertNode)(doc, { parentId: targetParentId, node }));
|
|
234
|
+
get().dispatch((doc) => (0, import_core.insertNode)(doc, { parentId: targetParentId, node, index }));
|
|
221
235
|
get().selectNode(nodeId);
|
|
222
236
|
return { success: true, nodeId };
|
|
223
237
|
},
|
|
238
|
+
insertBlock: (blockOrId, parentId, index) => {
|
|
239
|
+
const state = get();
|
|
240
|
+
const targetParentId = parentId ?? state.selectedNodeId ?? state.document.document.id;
|
|
241
|
+
let blockDef;
|
|
242
|
+
if (typeof blockOrId === "string") {
|
|
243
|
+
blockDef = import_components.STARTER_BLOCKS.find((b) => b.id === blockOrId);
|
|
244
|
+
} else {
|
|
245
|
+
blockDef = blockOrId;
|
|
246
|
+
}
|
|
247
|
+
if (!blockDef) {
|
|
248
|
+
return { success: false, error: "Block definition not found." };
|
|
249
|
+
}
|
|
250
|
+
const existingIds = (0, import_core.collectNodeIdSet)(state.document.document);
|
|
251
|
+
let counter = 1;
|
|
252
|
+
const generateId = (prefix = "node") => {
|
|
253
|
+
let id = `${prefix}-${Date.now().toString(36)}-${counter++}`;
|
|
254
|
+
while (existingIds.has(id)) {
|
|
255
|
+
id = `${prefix}-${Date.now().toString(36)}-${counter++}`;
|
|
256
|
+
}
|
|
257
|
+
existingIds.add(id);
|
|
258
|
+
return id;
|
|
259
|
+
};
|
|
260
|
+
const nodeTree = blockDef.createNodeTree(generateId);
|
|
261
|
+
try {
|
|
262
|
+
get().dispatch((doc) => (0, import_core.insertNode)(doc, { parentId: targetParentId, node: nodeTree, index }));
|
|
263
|
+
get().selectNode(nodeTree.id);
|
|
264
|
+
return { success: true, nodeId: nodeTree.id };
|
|
265
|
+
} catch {
|
|
266
|
+
try {
|
|
267
|
+
get().dispatch(
|
|
268
|
+
(doc) => (0, import_core.insertNode)(doc, { parentId: state.document.document.id, node: nodeTree })
|
|
269
|
+
);
|
|
270
|
+
get().selectNode(nodeTree.id);
|
|
271
|
+
return { success: true, nodeId: nodeTree.id };
|
|
272
|
+
} catch (err) {
|
|
273
|
+
return { success: false, error: formatCommandError(err) };
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
},
|
|
224
277
|
moveComponent: (nodeId, targetParentId, registry, index) => {
|
|
225
278
|
const state = get();
|
|
226
279
|
if (nodeId === state.document.document.id) {
|
|
@@ -232,10 +285,16 @@ var useEditorStore = (0, import_zustand.create)((set, get) => ({
|
|
|
232
285
|
}
|
|
233
286
|
const targetParent = (0, import_core.findNodeById)(state.document.document, targetParentId);
|
|
234
287
|
if (!targetParent) {
|
|
235
|
-
return {
|
|
288
|
+
return {
|
|
289
|
+
success: false,
|
|
290
|
+
error: `Move target "${targetParentId}" was not found in the document.`
|
|
291
|
+
};
|
|
236
292
|
}
|
|
237
293
|
if ((0, import_core.isDescendantOf)(sourceLocation.node, targetParentId)) {
|
|
238
|
-
return {
|
|
294
|
+
return {
|
|
295
|
+
success: false,
|
|
296
|
+
error: "Cannot move a node into itself or one of its own descendants."
|
|
297
|
+
};
|
|
239
298
|
}
|
|
240
299
|
const policy = registry.canInsertChild(targetParent.type, sourceLocation.node.type);
|
|
241
300
|
if (!policy.valid) {
|
|
@@ -372,10 +431,16 @@ var useEditorStore = (0, import_zustand.create)((set, get) => ({
|
|
|
372
431
|
}
|
|
373
432
|
const targetParent = (0, import_core.findNodeById)(document2.document, targetParentId);
|
|
374
433
|
if (!targetParent) {
|
|
375
|
-
return {
|
|
434
|
+
return {
|
|
435
|
+
success: false,
|
|
436
|
+
error: `Paste target "${targetParentId}" was not found in the document.`
|
|
437
|
+
};
|
|
376
438
|
}
|
|
377
439
|
if ((0, import_core.isDescendantOf)(clipboard, targetParentId)) {
|
|
378
|
-
return {
|
|
440
|
+
return {
|
|
441
|
+
success: false,
|
|
442
|
+
error: "Cannot paste a node into itself or one of its own descendants."
|
|
443
|
+
};
|
|
379
444
|
}
|
|
380
445
|
const policy = registry.canInsertChild(targetParent.type, clipboard.type);
|
|
381
446
|
if (!policy.valid) {
|
|
@@ -384,7 +449,9 @@ var useEditorStore = (0, import_zustand.create)((set, get) => ({
|
|
|
384
449
|
const existingIds = (0, import_core.collectNodeIdSet)(document2.document);
|
|
385
450
|
const { clonedNode } = (0, import_core.cloneTreeWithNewIds)(clipboard, void 0, existingIds);
|
|
386
451
|
try {
|
|
387
|
-
get().dispatch(
|
|
452
|
+
get().dispatch(
|
|
453
|
+
(doc) => (0, import_core.insertNode)(doc, { parentId: targetParentId, node: clonedNode, index })
|
|
454
|
+
);
|
|
388
455
|
} catch (err) {
|
|
389
456
|
return { success: false, error: formatCommandError(err) };
|
|
390
457
|
}
|
|
@@ -549,7 +616,19 @@ var EditorCanvas = ({
|
|
|
549
616
|
onDiagnostic,
|
|
550
617
|
config
|
|
551
618
|
}) => {
|
|
552
|
-
const {
|
|
619
|
+
const {
|
|
620
|
+
document: storeDoc,
|
|
621
|
+
selectedNodeId,
|
|
622
|
+
hoveredNodeId,
|
|
623
|
+
dragPayload,
|
|
624
|
+
selectNode,
|
|
625
|
+
hoverNode,
|
|
626
|
+
updateNodeProps,
|
|
627
|
+
setDragPayload,
|
|
628
|
+
insertComponent,
|
|
629
|
+
insertBlock,
|
|
630
|
+
moveComponent
|
|
631
|
+
} = useEditorStore();
|
|
553
632
|
const document2 = propDoc ?? storeDoc;
|
|
554
633
|
const showFloatingBadges = config?.showFloatingBadges !== false;
|
|
555
634
|
const containerRef = (0, import_react.useRef)(null);
|
|
@@ -626,7 +705,11 @@ var EditorCanvas = ({
|
|
|
626
705
|
const direction = ARROW_DIRECTIONS[e.key];
|
|
627
706
|
if (direction) {
|
|
628
707
|
e.preventDefault();
|
|
629
|
-
const target = (0, import_core3.getNavigationTarget)(
|
|
708
|
+
const target = (0, import_core3.getNavigationTarget)(
|
|
709
|
+
state.document.document,
|
|
710
|
+
state.selectedNodeId,
|
|
711
|
+
direction
|
|
712
|
+
);
|
|
630
713
|
if (target) state.selectNode(target);
|
|
631
714
|
}
|
|
632
715
|
};
|
|
@@ -653,24 +736,71 @@ var EditorCanvas = ({
|
|
|
653
736
|
e.stopPropagation();
|
|
654
737
|
e.dataTransfer.effectAllowed = "move";
|
|
655
738
|
e.dataTransfer.setData("text/plain", nodeId);
|
|
739
|
+
e.dataTransfer.setData("application/kubuild-drag-type", "node");
|
|
740
|
+
e.dataTransfer.setData("application/kubuild-node-id", nodeId);
|
|
656
741
|
setDraggingId(nodeId);
|
|
742
|
+
setDragPayload({ type: "node", nodeId });
|
|
657
743
|
selectNode(nodeId);
|
|
658
744
|
};
|
|
659
745
|
const handleDragOver = (e) => {
|
|
660
|
-
|
|
746
|
+
const activePayload = dragPayload ?? (draggingId ? { type: "node", nodeId: draggingId } : null);
|
|
747
|
+
if (!activePayload) return;
|
|
661
748
|
const container = containerRef.current;
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
const
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
749
|
+
if (!container) return;
|
|
750
|
+
const containerRect = container.getBoundingClientRect();
|
|
751
|
+
const hoveredEl = e.target.closest(
|
|
752
|
+
"[data-kubuild-node]"
|
|
753
|
+
);
|
|
754
|
+
let incomingType = null;
|
|
755
|
+
if (activePayload.type === "node") {
|
|
756
|
+
const draggedNode = (0, import_core3.findNodeById)(document2.document, activePayload.nodeId);
|
|
757
|
+
incomingType = draggedNode?.type ?? null;
|
|
758
|
+
} else if (activePayload.type === "component") {
|
|
759
|
+
incomingType = activePayload.componentType;
|
|
760
|
+
} else if (activePayload.type === "block") {
|
|
761
|
+
incomingType = "section";
|
|
762
|
+
}
|
|
763
|
+
if (!incomingType) {
|
|
668
764
|
setDropTarget(null);
|
|
669
765
|
e.dataTransfer.dropEffect = "none";
|
|
670
766
|
return;
|
|
671
767
|
}
|
|
768
|
+
if (!hoveredEl) {
|
|
769
|
+
const rootNode = document2.document;
|
|
770
|
+
const policy2 = registry.canInsertChild(rootNode.type, incomingType);
|
|
771
|
+
if (!policy2.valid) {
|
|
772
|
+
setDropTarget(null);
|
|
773
|
+
e.dataTransfer.dropEffect = "none";
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
776
|
+
e.preventDefault();
|
|
777
|
+
e.dataTransfer.dropEffect = activePayload.type === "node" ? "move" : "copy";
|
|
778
|
+
setDropTarget({
|
|
779
|
+
parentId: rootNode.id,
|
|
780
|
+
index: rootNode.children?.length ?? 0,
|
|
781
|
+
position: "inside",
|
|
782
|
+
rect: {
|
|
783
|
+
top: 0,
|
|
784
|
+
left: 0,
|
|
785
|
+
width: containerRect.width,
|
|
786
|
+
height: Math.max(containerRect.height, 200)
|
|
787
|
+
}
|
|
788
|
+
});
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
const hoveredId = hoveredEl.getAttribute("data-kubuild-node");
|
|
792
|
+
if (!hoveredId) return;
|
|
793
|
+
if (activePayload.type === "node") {
|
|
794
|
+
const draggedNode = (0, import_core3.findNodeById)(document2.document, activePayload.nodeId);
|
|
795
|
+
if (!draggedNode || (0, import_core3.isDescendantOf)(draggedNode, hoveredId)) {
|
|
796
|
+
setDropTarget(null);
|
|
797
|
+
e.dataTransfer.dropEffect = "none";
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
const hoveredNode = (0, import_core3.findNodeById)(document2.document, hoveredId);
|
|
802
|
+
if (!hoveredNode) return;
|
|
672
803
|
const elRect = hoveredEl.getBoundingClientRect();
|
|
673
|
-
const containerRect = container.getBoundingClientRect();
|
|
674
804
|
const ratio = elRect.height > 0 ? (e.clientY - elRect.top) / elRect.height : 0.5;
|
|
675
805
|
const hoveredDef = registry.get(hoveredNode.type);
|
|
676
806
|
const canGoInside = !!hoveredDef?.acceptsChildren;
|
|
@@ -691,18 +821,21 @@ var EditorCanvas = ({
|
|
|
691
821
|
targetType: location.parent.type
|
|
692
822
|
};
|
|
693
823
|
} else {
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
824
|
+
candidate = {
|
|
825
|
+
parentId: document2.document.id,
|
|
826
|
+
index: document2.document.children?.length ?? 0,
|
|
827
|
+
position: "inside",
|
|
828
|
+
targetType: document2.document.type
|
|
829
|
+
};
|
|
697
830
|
}
|
|
698
|
-
const policy = registry.canInsertChild(candidate.targetType,
|
|
831
|
+
const policy = registry.canInsertChild(candidate.targetType, incomingType);
|
|
699
832
|
if (!policy.valid) {
|
|
700
833
|
setDropTarget(null);
|
|
701
834
|
e.dataTransfer.dropEffect = "none";
|
|
702
835
|
return;
|
|
703
836
|
}
|
|
704
837
|
e.preventDefault();
|
|
705
|
-
e.dataTransfer.dropEffect = "move";
|
|
838
|
+
e.dataTransfer.dropEffect = activePayload.type === "node" ? "move" : "copy";
|
|
706
839
|
setDropTarget({
|
|
707
840
|
parentId: candidate.parentId,
|
|
708
841
|
index: candidate.index,
|
|
@@ -717,15 +850,29 @@ var EditorCanvas = ({
|
|
|
717
850
|
};
|
|
718
851
|
const handleDrop = (e) => {
|
|
719
852
|
e.preventDefault();
|
|
720
|
-
|
|
721
|
-
|
|
853
|
+
const activePayload = dragPayload ?? (draggingId ? { type: "node", nodeId: draggingId } : null);
|
|
854
|
+
if (activePayload && dropTarget) {
|
|
855
|
+
if (activePayload.type === "node") {
|
|
856
|
+
moveComponent(activePayload.nodeId, dropTarget.parentId, registry, dropTarget.index);
|
|
857
|
+
} else if (activePayload.type === "component") {
|
|
858
|
+
insertComponent(
|
|
859
|
+
activePayload.componentType,
|
|
860
|
+
registry,
|
|
861
|
+
dropTarget.parentId,
|
|
862
|
+
dropTarget.index
|
|
863
|
+
);
|
|
864
|
+
} else if (activePayload.type === "block") {
|
|
865
|
+
insertBlock(activePayload.blockId, dropTarget.parentId, dropTarget.index);
|
|
866
|
+
}
|
|
722
867
|
}
|
|
723
868
|
setDraggingId(null);
|
|
724
869
|
setDropTarget(null);
|
|
870
|
+
setDragPayload(null);
|
|
725
871
|
};
|
|
726
872
|
const handleDragEnd = () => {
|
|
727
873
|
setDraggingId(null);
|
|
728
874
|
setDropTarget(null);
|
|
875
|
+
setDragPayload(null);
|
|
729
876
|
};
|
|
730
877
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
731
878
|
"div",
|
|
@@ -2077,21 +2224,32 @@ var EditorToolbar = ({
|
|
|
2077
2224
|
type: "button",
|
|
2078
2225
|
title: `Navigator / Element Tree (${navigatorMode !== "hidden" ? "Open" : "Hidden"})`,
|
|
2079
2226
|
onClick: toggleNavigator,
|
|
2080
|
-
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"}`,
|
|
2227
|
+
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"}`,
|
|
2081
2228
|
children: [
|
|
2082
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2229
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2230
|
+
"svg",
|
|
2231
|
+
{
|
|
2232
|
+
width: "13",
|
|
2233
|
+
height: "13",
|
|
2234
|
+
viewBox: "0 0 24 24",
|
|
2235
|
+
fill: "none",
|
|
2236
|
+
stroke: "currentColor",
|
|
2237
|
+
strokeWidth: "2",
|
|
2238
|
+
children: [
|
|
2239
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "8", y1: "6", x2: "21", y2: "6" }),
|
|
2240
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "8", y1: "12", x2: "21", y2: "12" }),
|
|
2241
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "8", y1: "18", x2: "21", y2: "18" }),
|
|
2242
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "3", y1: "6", x2: "3.01", y2: "6" }),
|
|
2243
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "3", y1: "12", x2: "3.01", y2: "12" }),
|
|
2244
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "3", y1: "18", x2: "3.01", y2: "18" })
|
|
2245
|
+
]
|
|
2246
|
+
}
|
|
2247
|
+
),
|
|
2090
2248
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "Navigator" })
|
|
2091
2249
|
]
|
|
2092
2250
|
}
|
|
2093
2251
|
),
|
|
2094
|
-
showNavigatorToggle && (showClipboard || showHistory || showCodeViewer || showExportImport) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "h-4 w-px bg-slate-200 mx-1" }),
|
|
2252
|
+
showNavigatorToggle && (showClipboard || showHistory || showCodeViewer || showExportImport) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hidden sm:block h-4 w-px bg-slate-200 mx-1" }),
|
|
2095
2253
|
(showClipboard || showHistory) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
2096
2254
|
showClipboard && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
2097
2255
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
@@ -2166,21 +2324,21 @@ var EditorToolbar = ({
|
|
|
2166
2324
|
)
|
|
2167
2325
|
] })
|
|
2168
2326
|
] }),
|
|
2169
|
-
(showClipboard || showHistory) && (showCodeViewer || showExportImport) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "h-4 w-px bg-slate-200 mx-1" }),
|
|
2327
|
+
(showClipboard || showHistory) && (showCodeViewer || showExportImport) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "hidden sm:block h-4 w-px bg-slate-200 mx-1" }),
|
|
2170
2328
|
showCodeViewer && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2171
2329
|
"button",
|
|
2172
2330
|
{
|
|
2173
2331
|
type: "button",
|
|
2174
2332
|
title: "View Semantic HTML & CSS (< >)",
|
|
2175
2333
|
onClick: () => setIsCodeViewerModalOpen(true),
|
|
2176
|
-
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",
|
|
2334
|
+
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",
|
|
2177
2335
|
children: [
|
|
2178
2336
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "font-mono text-[11px] font-bold text-blue-600", children: "<>" }),
|
|
2179
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "View Code" })
|
|
2337
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "hidden sm:inline", children: "View Code" })
|
|
2180
2338
|
]
|
|
2181
2339
|
}
|
|
2182
2340
|
),
|
|
2183
|
-
showExportImport && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2341
|
+
showExportImport && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
2184
2342
|
showCodeViewer && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "h-4 w-px bg-slate-200 mx-1" }),
|
|
2185
2343
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2186
2344
|
"button",
|
|
@@ -2188,7 +2346,7 @@ var EditorToolbar = ({
|
|
|
2188
2346
|
type: "button",
|
|
2189
2347
|
title: "Import .stora Package",
|
|
2190
2348
|
onClick: () => setIsImportModalOpen(true),
|
|
2191
|
-
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",
|
|
2349
|
+
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",
|
|
2192
2350
|
children: "Import"
|
|
2193
2351
|
}
|
|
2194
2352
|
),
|
|
@@ -2199,8 +2357,8 @@ var EditorToolbar = ({
|
|
|
2199
2357
|
title: "Export .stora Archive",
|
|
2200
2358
|
disabled: isExporting,
|
|
2201
2359
|
onClick: handleExportStora,
|
|
2202
|
-
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-
|
|
2203
|
-
children: isExporting ? "
|
|
2360
|
+
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",
|
|
2361
|
+
children: isExporting ? "..." : "Export"
|
|
2204
2362
|
}
|
|
2205
2363
|
),
|
|
2206
2364
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
@@ -2209,7 +2367,7 @@ var EditorToolbar = ({
|
|
|
2209
2367
|
type: "button",
|
|
2210
2368
|
title: "Download page.json",
|
|
2211
2369
|
onClick: handleExportJson,
|
|
2212
|
-
className: "text-xs px-2 py-1 rounded border border-slate-200 bg-white hover:border-slate-400 text-slate-600 transition",
|
|
2370
|
+
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",
|
|
2213
2371
|
children: "JSON"
|
|
2214
2372
|
}
|
|
2215
2373
|
)
|
|
@@ -2242,16 +2400,16 @@ var EditorToolbar = ({
|
|
|
2242
2400
|
|
|
2243
2401
|
// src/inspector-panel.tsx
|
|
2244
2402
|
var import_react13 = require("react");
|
|
2245
|
-
var
|
|
2403
|
+
var import_components4 = require("@kubuild/components");
|
|
2246
2404
|
var import_core8 = require("@kubuild/core");
|
|
2247
2405
|
var import_schema5 = require("@kubuild/schema");
|
|
2248
2406
|
|
|
2249
2407
|
// src/variable-picker.tsx
|
|
2250
2408
|
var import_schema2 = require("@kubuild/schema");
|
|
2251
|
-
var
|
|
2409
|
+
var import_components2 = require("@kubuild/components");
|
|
2252
2410
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
2253
2411
|
function getCompatibleCatalogEntries(field, catalog) {
|
|
2254
|
-
const expectedType = (0,
|
|
2412
|
+
const expectedType = (0, import_components2.primitiveTypeForField)(field);
|
|
2255
2413
|
if (!expectedType || !catalog) {
|
|
2256
2414
|
return [];
|
|
2257
2415
|
}
|
|
@@ -3050,15 +3208,18 @@ var TableSpreadsheetEditor = ({
|
|
|
3050
3208
|
setIsImportModalOpen(false);
|
|
3051
3209
|
setCsvInputText("");
|
|
3052
3210
|
};
|
|
3053
|
-
const [pos, setPos] = (0, import_react7.useState)(
|
|
3211
|
+
const [pos, setPos] = (0, import_react7.useState)(() => ({
|
|
3212
|
+
x: typeof window !== "undefined" ? Math.max(10, Math.min(window.innerWidth - 400, 20)) : 20,
|
|
3213
|
+
y: 120
|
|
3214
|
+
}));
|
|
3054
3215
|
const [isDragging, setIsDragging] = (0, import_react7.useState)(false);
|
|
3055
3216
|
const dragStartRef = (0, import_react7.useRef)({
|
|
3056
3217
|
startX: 0,
|
|
3057
3218
|
startY: 0,
|
|
3058
|
-
posX:
|
|
3219
|
+
posX: 20,
|
|
3059
3220
|
posY: 120
|
|
3060
3221
|
});
|
|
3061
|
-
const
|
|
3222
|
+
const handleHeaderPointerDown = (e) => {
|
|
3062
3223
|
if (e.target.closest("button, input, select, textarea")) return;
|
|
3063
3224
|
setIsDragging(true);
|
|
3064
3225
|
dragStartRef.current = {
|
|
@@ -3070,22 +3231,26 @@ var TableSpreadsheetEditor = ({
|
|
|
3070
3231
|
};
|
|
3071
3232
|
(0, import_react7.useEffect)(() => {
|
|
3072
3233
|
if (!isDragging) return;
|
|
3073
|
-
const
|
|
3234
|
+
const handlePointerMove = (e) => {
|
|
3074
3235
|
const dx = e.clientX - dragStartRef.current.startX;
|
|
3075
3236
|
const dy = e.clientY - dragStartRef.current.startY;
|
|
3237
|
+
const maxX = Math.max(8, window.innerWidth - 320);
|
|
3238
|
+
const maxY = Math.max(8, window.innerHeight - 100);
|
|
3076
3239
|
setPos({
|
|
3077
|
-
x: Math.max(
|
|
3078
|
-
y: Math.max(
|
|
3240
|
+
x: Math.max(8, Math.min(maxX, dragStartRef.current.posX + dx)),
|
|
3241
|
+
y: Math.max(8, Math.min(maxY, dragStartRef.current.posY + dy))
|
|
3079
3242
|
});
|
|
3080
3243
|
};
|
|
3081
|
-
const
|
|
3244
|
+
const handlePointerUp = () => {
|
|
3082
3245
|
setIsDragging(false);
|
|
3083
3246
|
};
|
|
3084
|
-
window.addEventListener("
|
|
3085
|
-
window.addEventListener("
|
|
3247
|
+
window.addEventListener("pointermove", handlePointerMove);
|
|
3248
|
+
window.addEventListener("pointerup", handlePointerUp);
|
|
3249
|
+
window.addEventListener("pointercancel", handlePointerUp);
|
|
3086
3250
|
return () => {
|
|
3087
|
-
window.removeEventListener("
|
|
3088
|
-
window.removeEventListener("
|
|
3251
|
+
window.removeEventListener("pointermove", handlePointerMove);
|
|
3252
|
+
window.removeEventListener("pointerup", handlePointerUp);
|
|
3253
|
+
window.removeEventListener("pointercancel", handlePointerUp);
|
|
3089
3254
|
};
|
|
3090
3255
|
}, [isDragging]);
|
|
3091
3256
|
if (!tableNode) return null;
|
|
@@ -3639,9 +3804,9 @@ var TableSpreadsheetEditor = ({
|
|
|
3639
3804
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
3640
3805
|
"div",
|
|
3641
3806
|
{
|
|
3642
|
-
style: { left: `${pos.x}px`, top: `${pos.y}px
|
|
3643
|
-
|
|
3644
|
-
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}`,
|
|
3807
|
+
style: { left: `${pos.x}px`, top: `${pos.y}px`, touchAction: "none" },
|
|
3808
|
+
onPointerDown: handleHeaderPointerDown,
|
|
3809
|
+
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}`,
|
|
3645
3810
|
children: content
|
|
3646
3811
|
}
|
|
3647
3812
|
)
|
|
@@ -5456,7 +5621,7 @@ var StyleManagerAccordion = ({
|
|
|
5456
5621
|
|
|
5457
5622
|
// src/traits-panel.tsx
|
|
5458
5623
|
var import_react12 = require("react");
|
|
5459
|
-
var
|
|
5624
|
+
var import_components3 = require("@kubuild/components");
|
|
5460
5625
|
var import_core7 = require("@kubuild/core");
|
|
5461
5626
|
var import_lucide_react5 = require("lucide-react");
|
|
5462
5627
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
@@ -5779,7 +5944,7 @@ var TraitsPanel = ({
|
|
|
5779
5944
|
grouped.set(key, list);
|
|
5780
5945
|
}
|
|
5781
5946
|
const orderedGroups = [
|
|
5782
|
-
...
|
|
5947
|
+
...import_components3.TRAIT_GROUP_ORDER.filter((g) => grouped.has(g)),
|
|
5783
5948
|
...grouped.has(void 0) ? [void 0] : []
|
|
5784
5949
|
];
|
|
5785
5950
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: `flex flex-col gap-4 ${className ?? "p-3"} text-sm text-slate-900`, children: orderedGroups.map((group) => {
|
|
@@ -5787,7 +5952,7 @@ var TraitsPanel = ({
|
|
|
5787
5952
|
const traitNames = new Set(groupTraits.map((t) => t.name));
|
|
5788
5953
|
const isLinkGroup = group === "link" && traitNames.has("href");
|
|
5789
5954
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
|
|
5790
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2", children: group ?
|
|
5955
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2", children: group ? import_components3.TRAIT_GROUP_LABELS[group] : "Other" }),
|
|
5791
5956
|
isLinkGroup ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
5792
5957
|
LinkTraitControl,
|
|
5793
5958
|
{
|
|
@@ -6601,7 +6766,7 @@ var InspectorPanel = ({
|
|
|
6601
6766
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
|
|
6602
6767
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { className: "block text-xs font-medium text-slate-600 mb-1", children: field.label }),
|
|
6603
6768
|
!bound && renderPropControl(field),
|
|
6604
|
-
(0,
|
|
6769
|
+
(0, import_components4.isBindableField)(field) && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
6605
6770
|
VariableBindingControl,
|
|
6606
6771
|
{
|
|
6607
6772
|
field,
|
|
@@ -6703,16 +6868,19 @@ var LayersPanel = ({ registry, className }) => {
|
|
|
6703
6868
|
const [expandedIds, setExpandedIds] = (0, import_react14.useState)(() => /* @__PURE__ */ new Set([document2.document.id]));
|
|
6704
6869
|
const [draggingId, setDraggingId] = (0, import_react14.useState)(null);
|
|
6705
6870
|
const [dropCandidate, setDropCandidate] = (0, import_react14.useState)(null);
|
|
6706
|
-
const [pos, setPos] = (0, import_react14.useState)(
|
|
6871
|
+
const [pos, setPos] = (0, import_react14.useState)(() => ({
|
|
6872
|
+
x: typeof window !== "undefined" ? Math.max(12, Math.min(window.innerWidth - 300, 24)) : 24,
|
|
6873
|
+
y: 70
|
|
6874
|
+
}));
|
|
6707
6875
|
const [isDraggingWindow, setIsDraggingWindow] = (0, import_react14.useState)(false);
|
|
6708
6876
|
const dragStartRef = (0, import_react14.useRef)({
|
|
6709
6877
|
startX: 0,
|
|
6710
6878
|
startY: 0,
|
|
6711
|
-
posX:
|
|
6879
|
+
posX: 24,
|
|
6712
6880
|
posY: 70
|
|
6713
6881
|
});
|
|
6714
|
-
const
|
|
6715
|
-
if (e.target.closest("button")) return;
|
|
6882
|
+
const handleHeaderPointerDown = (e) => {
|
|
6883
|
+
if (e.target.closest("button, input, select, textarea")) return;
|
|
6716
6884
|
setIsDraggingWindow(true);
|
|
6717
6885
|
dragStartRef.current = {
|
|
6718
6886
|
startX: e.clientX,
|
|
@@ -6723,22 +6891,26 @@ var LayersPanel = ({ registry, className }) => {
|
|
|
6723
6891
|
};
|
|
6724
6892
|
(0, import_react14.useEffect)(() => {
|
|
6725
6893
|
if (!isDraggingWindow) return;
|
|
6726
|
-
const
|
|
6894
|
+
const handlePointerMove = (e) => {
|
|
6727
6895
|
const dx = e.clientX - dragStartRef.current.startX;
|
|
6728
6896
|
const dy = e.clientY - dragStartRef.current.startY;
|
|
6897
|
+
const maxX = Math.max(8, window.innerWidth - 296);
|
|
6898
|
+
const maxY = Math.max(8, window.innerHeight - 100);
|
|
6729
6899
|
setPos({
|
|
6730
|
-
x: Math.max(
|
|
6731
|
-
y: Math.max(
|
|
6900
|
+
x: Math.max(8, Math.min(maxX, dragStartRef.current.posX + dx)),
|
|
6901
|
+
y: Math.max(8, Math.min(maxY, dragStartRef.current.posY + dy))
|
|
6732
6902
|
});
|
|
6733
6903
|
};
|
|
6734
|
-
const
|
|
6904
|
+
const handlePointerUp = () => {
|
|
6735
6905
|
setIsDraggingWindow(false);
|
|
6736
6906
|
};
|
|
6737
|
-
window.addEventListener("
|
|
6738
|
-
window.addEventListener("
|
|
6907
|
+
window.addEventListener("pointermove", handlePointerMove);
|
|
6908
|
+
window.addEventListener("pointerup", handlePointerUp);
|
|
6909
|
+
window.addEventListener("pointercancel", handlePointerUp);
|
|
6739
6910
|
return () => {
|
|
6740
|
-
window.removeEventListener("
|
|
6741
|
-
window.removeEventListener("
|
|
6911
|
+
window.removeEventListener("pointermove", handlePointerMove);
|
|
6912
|
+
window.removeEventListener("pointerup", handlePointerUp);
|
|
6913
|
+
window.removeEventListener("pointercancel", handlePointerUp);
|
|
6742
6914
|
};
|
|
6743
6915
|
}, [isDraggingWindow]);
|
|
6744
6916
|
(0, import_react14.useEffect)(() => {
|
|
@@ -6889,8 +7061,9 @@ var LayersPanel = ({ registry, className }) => {
|
|
|
6889
7061
|
const header = /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
6890
7062
|
"div",
|
|
6891
7063
|
{
|
|
6892
|
-
|
|
6893
|
-
|
|
7064
|
+
onPointerDown: isFloating ? handleHeaderPointerDown : void 0,
|
|
7065
|
+
style: { touchAction: isFloating ? "none" : "auto" },
|
|
7066
|
+
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"}`,
|
|
6894
7067
|
children: [
|
|
6895
7068
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center gap-1.5 font-semibold text-xs text-slate-700", children: [
|
|
6896
7069
|
isFloating && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react7.GripVertical, { className: "w-3 h-3 text-slate-400 mr-0.5", "aria-hidden": "true" }),
|
|
@@ -6949,11 +7122,11 @@ var LayersPanel = ({ registry, className }) => {
|
|
|
6949
7122
|
|
|
6950
7123
|
// src/breadcrumbs.tsx
|
|
6951
7124
|
var import_react15 = __toESM(require("react"), 1);
|
|
6952
|
-
var
|
|
7125
|
+
var import_components5 = require("@kubuild/components");
|
|
6953
7126
|
var import_core10 = require("@kubuild/core");
|
|
6954
7127
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
6955
7128
|
var HierarchyBreadcrumbs = ({
|
|
6956
|
-
registry = (0,
|
|
7129
|
+
registry = (0, import_components5.createDefaultComponentRegistry)(),
|
|
6957
7130
|
document: propDoc,
|
|
6958
7131
|
selectedNodeId: propSelectedNodeId,
|
|
6959
7132
|
className
|
|
@@ -7019,7 +7192,15 @@ var import_lucide_react9 = require("lucide-react");
|
|
|
7019
7192
|
// src/component-panel.tsx
|
|
7020
7193
|
var import_react16 = require("react");
|
|
7021
7194
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
7022
|
-
var CATEGORY_ORDER = [
|
|
7195
|
+
var CATEGORY_ORDER = [
|
|
7196
|
+
"layout",
|
|
7197
|
+
"typography",
|
|
7198
|
+
"media",
|
|
7199
|
+
"form",
|
|
7200
|
+
"interactive",
|
|
7201
|
+
"data",
|
|
7202
|
+
"custom"
|
|
7203
|
+
];
|
|
7023
7204
|
var CATEGORY_LABELS = {
|
|
7024
7205
|
layout: "Layout",
|
|
7025
7206
|
typography: "Typography",
|
|
@@ -7031,6 +7212,7 @@ var CATEGORY_LABELS = {
|
|
|
7031
7212
|
};
|
|
7032
7213
|
var ComponentPanel = ({ registry, className }) => {
|
|
7033
7214
|
const insertComponent = useEditorStore((s) => s.insertComponent);
|
|
7215
|
+
const setDragPayload = useEditorStore((s) => s.setDragPayload);
|
|
7034
7216
|
const [error, setError] = (0, import_react16.useState)(null);
|
|
7035
7217
|
const groups = CATEGORY_ORDER.map((category) => ({
|
|
7036
7218
|
category,
|
|
@@ -7040,6 +7222,16 @@ var ComponentPanel = ({ registry, className }) => {
|
|
|
7040
7222
|
const result = insertComponent(definition.type, registry);
|
|
7041
7223
|
setError(result.success ? null : result.error ?? `Could not insert "${definition.label}".`);
|
|
7042
7224
|
};
|
|
7225
|
+
const handleDragStart = (e, definition) => {
|
|
7226
|
+
e.dataTransfer.effectAllowed = "copy";
|
|
7227
|
+
e.dataTransfer.setData("text/plain", `component:${definition.type}`);
|
|
7228
|
+
e.dataTransfer.setData("application/kubuild-drag-type", "component");
|
|
7229
|
+
e.dataTransfer.setData("application/kubuild-component-type", definition.type);
|
|
7230
|
+
setDragPayload({ type: "component", componentType: definition.type });
|
|
7231
|
+
};
|
|
7232
|
+
const handleDragEnd = () => {
|
|
7233
|
+
setDragPayload(null);
|
|
7234
|
+
};
|
|
7043
7235
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: `flex flex-col gap-4 p-3 overflow-y-auto h-full min-h-0 ${className || ""}`, children: [
|
|
7044
7236
|
error && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
7045
7237
|
"div",
|
|
@@ -7055,12 +7247,16 @@ var ComponentPanel = ({ registry, className }) => {
|
|
|
7055
7247
|
"button",
|
|
7056
7248
|
{
|
|
7057
7249
|
type: "button",
|
|
7250
|
+
draggable: true,
|
|
7251
|
+
onDragStart: (e) => handleDragStart(e, definition),
|
|
7252
|
+
onDragEnd: handleDragEnd,
|
|
7058
7253
|
onClick: () => handleInsert(definition),
|
|
7059
|
-
|
|
7060
|
-
|
|
7254
|
+
"data-testid": `component-item-${definition.type}`,
|
|
7255
|
+
title: definition.description || `Click to insert or drag to canvas: ${definition.label}`,
|
|
7256
|
+
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",
|
|
7061
7257
|
children: [
|
|
7062
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "mb-1.5 text-slate-500 group-hover:text-blue-600 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ComponentIcon, { iconOrType: definition.icon ?? definition.type, size: 22 }) }),
|
|
7063
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-[11px] font-medium text-slate-700 group-hover:text-blue-600 text-center leading-tight break-words w-full
|
|
7258
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "mb-1.5 text-slate-500 group-hover:text-blue-600 transition-colors pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ComponentIcon, { iconOrType: definition.icon ?? definition.type, size: 22 }) }),
|
|
7259
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("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 })
|
|
7064
7260
|
]
|
|
7065
7261
|
},
|
|
7066
7262
|
definition.type
|
|
@@ -7071,7 +7267,7 @@ var ComponentPanel = ({ registry, className }) => {
|
|
|
7071
7267
|
|
|
7072
7268
|
// src/blocks-panel.tsx
|
|
7073
7269
|
var import_react17 = require("react");
|
|
7074
|
-
var
|
|
7270
|
+
var import_components6 = require("@kubuild/components");
|
|
7075
7271
|
var import_core11 = require("@kubuild/core");
|
|
7076
7272
|
var import_lucide_react8 = require("lucide-react");
|
|
7077
7273
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
@@ -7137,7 +7333,7 @@ var BlockThumbnail = ({ block }) => {
|
|
|
7137
7333
|
}
|
|
7138
7334
|
};
|
|
7139
7335
|
var BlocksPanel = ({
|
|
7140
|
-
blocks =
|
|
7336
|
+
blocks = import_components6.STARTER_BLOCKS,
|
|
7141
7337
|
className,
|
|
7142
7338
|
onInsertBlock
|
|
7143
7339
|
}) => {
|
|
@@ -7181,6 +7377,17 @@ var BlocksPanel = ({
|
|
|
7181
7377
|
selectNode(nodeTree.id);
|
|
7182
7378
|
}
|
|
7183
7379
|
};
|
|
7380
|
+
const setDragPayload = useEditorStore((s) => s.setDragPayload);
|
|
7381
|
+
const handleDragStart = (e, block) => {
|
|
7382
|
+
e.dataTransfer.effectAllowed = "copy";
|
|
7383
|
+
e.dataTransfer.setData("text/plain", `block:${block.id}`);
|
|
7384
|
+
e.dataTransfer.setData("application/kubuild-drag-type", "block");
|
|
7385
|
+
e.dataTransfer.setData("application/kubuild-block-id", block.id);
|
|
7386
|
+
setDragPayload({ type: "block", blockId: block.id });
|
|
7387
|
+
};
|
|
7388
|
+
const handleDragEnd = () => {
|
|
7389
|
+
setDragPayload(null);
|
|
7390
|
+
};
|
|
7184
7391
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
7185
7392
|
"div",
|
|
7186
7393
|
{
|
|
@@ -7211,13 +7418,17 @@ var BlocksPanel = ({
|
|
|
7211
7418
|
"button",
|
|
7212
7419
|
{
|
|
7213
7420
|
type: "button",
|
|
7421
|
+
draggable: true,
|
|
7422
|
+
onDragStart: (e) => handleDragStart(e, block),
|
|
7423
|
+
onDragEnd: handleDragEnd,
|
|
7214
7424
|
"data-testid": "block-card",
|
|
7215
7425
|
"data-block-id": block.id,
|
|
7216
7426
|
onClick: () => handleInsert(block),
|
|
7217
|
-
|
|
7427
|
+
title: block.description || `Click to insert or drag to canvas: ${block.name}`,
|
|
7428
|
+
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",
|
|
7218
7429
|
children: [
|
|
7219
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "mb-2 w-full", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(BlockThumbnail, { block }) }),
|
|
7220
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "w-full", children: [
|
|
7430
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "mb-2 w-full pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(BlockThumbnail, { block }) }),
|
|
7431
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "w-full pointer-events-none", children: [
|
|
7221
7432
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex items-center justify-between gap-1 mb-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[11px] font-semibold text-slate-800 group-hover:text-blue-600 truncate", children: block.name }) }),
|
|
7222
7433
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("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 })
|
|
7223
7434
|
] })
|
|
@@ -7367,10 +7578,11 @@ function resolveEditorConfig(config) {
|
|
|
7367
7578
|
}
|
|
7368
7579
|
|
|
7369
7580
|
// src/editor.tsx
|
|
7581
|
+
var import_lucide_react10 = require("lucide-react");
|
|
7370
7582
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
7371
7583
|
var KubuildEditor = ({
|
|
7372
7584
|
initialDocument,
|
|
7373
|
-
registry = (0,
|
|
7585
|
+
registry = (0, import_components7.createDefaultComponentRegistry)(),
|
|
7374
7586
|
context,
|
|
7375
7587
|
variableCatalog,
|
|
7376
7588
|
onChange,
|
|
@@ -7388,9 +7600,16 @@ var KubuildEditor = ({
|
|
|
7388
7600
|
selectedNodeId,
|
|
7389
7601
|
navigatorMode,
|
|
7390
7602
|
tableSpreadsheetMode,
|
|
7391
|
-
setTableSpreadsheetMode
|
|
7603
|
+
setTableSpreadsheetMode,
|
|
7604
|
+
undo,
|
|
7605
|
+
redo,
|
|
7606
|
+
canUndo,
|
|
7607
|
+
canRedo
|
|
7392
7608
|
} = useEditorStore();
|
|
7393
7609
|
const lastLoadedDocRef = import_react19.default.useRef(void 0);
|
|
7610
|
+
const [isMobileSidebarOpen, setIsMobileSidebarOpen] = (0, import_react19.useState)(false);
|
|
7611
|
+
const [isMobileInspectorOpen, setIsMobileInspectorOpen] = (0, import_react19.useState)(false);
|
|
7612
|
+
const [isMobileLayersOpen, setIsMobileLayersOpen] = (0, import_react19.useState)(false);
|
|
7394
7613
|
const activeTable = (0, import_react19.useMemo)(
|
|
7395
7614
|
() => findActiveTableNode(document2.document, selectedNodeId),
|
|
7396
7615
|
[document2.document, selectedNodeId]
|
|
@@ -7419,65 +7638,245 @@ var KubuildEditor = ({
|
|
|
7419
7638
|
}, [context, sampleVariables]);
|
|
7420
7639
|
const viewportWidthMap = {
|
|
7421
7640
|
desktop: "w-full max-w-6xl",
|
|
7422
|
-
tablet: "w-[768px]",
|
|
7423
|
-
mobile: "w-[375px]"
|
|
7641
|
+
tablet: "w-full max-w-[768px] sm:w-[768px]",
|
|
7642
|
+
mobile: "w-full max-w-[375px] sm:w-[375px]"
|
|
7643
|
+
};
|
|
7644
|
+
const viewportIcons = {
|
|
7645
|
+
desktop: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Monitor, { className: "w-3.5 h-3.5" }),
|
|
7646
|
+
tablet: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Tablet, { className: "w-3.5 h-3.5" }),
|
|
7647
|
+
mobile: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Smartphone, { className: "w-3.5 h-3.5" })
|
|
7424
7648
|
};
|
|
7425
7649
|
const resolvedConfig = (0, import_react19.useMemo)(() => resolveEditorConfig(config), [config]);
|
|
7426
|
-
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7430
|
-
|
|
7431
|
-
registry,
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
onToggleMode: () => setTableSpreadsheetMode("docked"),
|
|
7435
|
-
onClose: () => setTableSpreadsheetMode("hidden")
|
|
7436
|
-
}
|
|
7437
|
-
),
|
|
7438
|
-
resolvedConfig.toolbar.enabled && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center justify-between px-4 py-2 bg-white border-b border-slate-200", children: [
|
|
7439
|
-
resolvedConfig.toolbar.showTitle ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
7440
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "font-semibold text-slate-800 text-sm", children: "KUBUILD Editor" }),
|
|
7441
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-xs bg-slate-100 text-slate-600 px-2 py-0.5 rounded border", children: document2.metadata?.title || "Untitled" })
|
|
7442
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", {}),
|
|
7443
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EditorToolbar, { registry, config: resolvedConfig.toolbar }),
|
|
7444
|
-
resolvedConfig.toolbar.showViewportSwitcher && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex items-center gap-1 bg-slate-100 p-1 rounded-md text-xs", children: ["desktop", "tablet", "mobile"].map((vp) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7445
|
-
"button",
|
|
7446
|
-
{
|
|
7447
|
-
type: "button",
|
|
7448
|
-
onClick: () => setViewport(vp),
|
|
7449
|
-
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"}`,
|
|
7450
|
-
children: vp
|
|
7451
|
-
},
|
|
7452
|
-
vp
|
|
7453
|
-
)) }),
|
|
7454
|
-
resolvedConfig.toolbar.showSelectionStatus && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "text-xs text-slate-500", children: selectedNodeId ? `Selected: #${selectedNodeId}` : "No element selected" })
|
|
7455
|
-
] }),
|
|
7456
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-1 overflow-hidden min-h-0", children: [
|
|
7457
|
-
resolvedConfig.sidebar.enabled && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("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__ */ (0, import_jsx_runtime23.jsx)(LeftSidebar, { registry, config: resolvedConfig.sidebar }) }),
|
|
7458
|
-
navigatorMode === "docked" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("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__ */ (0, import_jsx_runtime23.jsx)(LayersPanel, { registry }) }),
|
|
7459
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden flex flex-col min-h-0 h-full", children: [
|
|
7460
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 overflow-auto p-8 flex justify-center items-start min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7461
|
-
"div",
|
|
7650
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
7651
|
+
"div",
|
|
7652
|
+
{
|
|
7653
|
+
className: `flex flex-col h-full bg-slate-100 text-slate-900 relative overflow-hidden ${className || ""}`,
|
|
7654
|
+
children: [
|
|
7655
|
+
navigatorMode === "floating" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LayersPanel, { registry }),
|
|
7656
|
+
activeTable && tableSpreadsheetMode === "floating" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7657
|
+
TableSpreadsheetEditor,
|
|
7462
7658
|
{
|
|
7463
|
-
|
|
7464
|
-
|
|
7465
|
-
|
|
7659
|
+
registry,
|
|
7660
|
+
tableNode: activeTable,
|
|
7661
|
+
mode: "floating",
|
|
7662
|
+
onToggleMode: () => setTableSpreadsheetMode("docked"),
|
|
7663
|
+
onClose: () => setTableSpreadsheetMode("hidden")
|
|
7664
|
+
}
|
|
7665
|
+
),
|
|
7666
|
+
isMobileSidebarOpen && resolvedConfig.sidebar.enabled && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "fixed inset-0 z-50 flex lg:hidden animate-in fade-in duration-200", children: [
|
|
7667
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7668
|
+
"div",
|
|
7669
|
+
{
|
|
7670
|
+
className: "fixed inset-0 bg-slate-950/50 backdrop-blur-xs transition-opacity",
|
|
7671
|
+
onClick: () => setIsMobileSidebarOpen(false)
|
|
7672
|
+
}
|
|
7673
|
+
),
|
|
7674
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("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: [
|
|
7675
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center justify-between px-3.5 py-2.5 border-b border-slate-200 bg-slate-50", children: [
|
|
7676
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
7677
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Boxes, { className: "w-4 h-4 text-blue-600" }),
|
|
7678
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "font-bold text-xs text-slate-800", children: "Add Components & Blocks" })
|
|
7679
|
+
] }),
|
|
7680
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7681
|
+
"button",
|
|
7682
|
+
{
|
|
7683
|
+
type: "button",
|
|
7684
|
+
onClick: () => setIsMobileSidebarOpen(false),
|
|
7685
|
+
className: "p-1 rounded-md text-slate-400 hover:text-slate-700 hover:bg-slate-200 transition",
|
|
7686
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.X, { className: "w-4 h-4" })
|
|
7687
|
+
}
|
|
7688
|
+
)
|
|
7689
|
+
] }),
|
|
7690
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 overflow-hidden min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LeftSidebar, { registry, config: resolvedConfig.sidebar }) })
|
|
7691
|
+
] })
|
|
7692
|
+
] }),
|
|
7693
|
+
isMobileInspectorOpen && resolvedConfig.inspector.enabled && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "fixed inset-0 z-50 flex justify-end lg:hidden animate-in fade-in duration-200", children: [
|
|
7694
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7695
|
+
"div",
|
|
7696
|
+
{
|
|
7697
|
+
className: "fixed inset-0 bg-slate-950/50 backdrop-blur-xs transition-opacity",
|
|
7698
|
+
onClick: () => setIsMobileInspectorOpen(false)
|
|
7699
|
+
}
|
|
7700
|
+
),
|
|
7701
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("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: [
|
|
7702
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center justify-between px-3.5 py-2.5 border-b border-slate-200 bg-slate-50", children: [
|
|
7703
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
7704
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Sliders, { className: "w-4 h-4 text-blue-600" }),
|
|
7705
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "font-bold text-xs text-slate-800", children: selectedNodeId ? `Inspector (#${selectedNodeId})` : "Inspector & Properties" })
|
|
7706
|
+
] }),
|
|
7707
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7708
|
+
"button",
|
|
7709
|
+
{
|
|
7710
|
+
type: "button",
|
|
7711
|
+
onClick: () => setIsMobileInspectorOpen(false),
|
|
7712
|
+
className: "p-1 rounded-md text-slate-400 hover:text-slate-700 hover:bg-slate-200 transition",
|
|
7713
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.X, { className: "w-4 h-4" })
|
|
7714
|
+
}
|
|
7715
|
+
)
|
|
7716
|
+
] }),
|
|
7717
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 overflow-hidden min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(InspectorPanel, { registry, config: resolvedConfig.inspector }) })
|
|
7718
|
+
] })
|
|
7719
|
+
] }),
|
|
7720
|
+
isMobileLayersOpen && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "fixed inset-0 z-50 flex lg:hidden animate-in fade-in duration-200", children: [
|
|
7721
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7722
|
+
"div",
|
|
7723
|
+
{
|
|
7724
|
+
className: "fixed inset-0 bg-slate-950/50 backdrop-blur-xs transition-opacity",
|
|
7725
|
+
onClick: () => setIsMobileLayersOpen(false)
|
|
7726
|
+
}
|
|
7727
|
+
),
|
|
7728
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("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: [
|
|
7729
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center justify-between px-3.5 py-2.5 border-b border-slate-200 bg-slate-50", children: [
|
|
7730
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
7731
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Layers, { className: "w-4 h-4 text-blue-600" }),
|
|
7732
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "font-bold text-xs text-slate-800", children: "Element Tree / Layers" })
|
|
7733
|
+
] }),
|
|
7734
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7735
|
+
"button",
|
|
7736
|
+
{
|
|
7737
|
+
type: "button",
|
|
7738
|
+
onClick: () => setIsMobileLayersOpen(false),
|
|
7739
|
+
className: "p-1 rounded-md text-slate-400 hover:text-slate-700 hover:bg-slate-200 transition",
|
|
7740
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.X, { className: "w-4 h-4" })
|
|
7741
|
+
}
|
|
7742
|
+
)
|
|
7743
|
+
] }),
|
|
7744
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 overflow-hidden min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LayersPanel, { registry }) })
|
|
7745
|
+
] })
|
|
7746
|
+
] }),
|
|
7747
|
+
resolvedConfig.toolbar.enabled && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("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: [
|
|
7748
|
+
resolvedConfig.toolbar.showTitle ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
7749
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "font-bold text-slate-800 text-xs sm:text-sm tracking-tight", children: "KUBUILD Editor" }),
|
|
7750
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("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" })
|
|
7751
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", {}),
|
|
7752
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
7753
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(EditorToolbar, { registry, config: resolvedConfig.toolbar }),
|
|
7754
|
+
resolvedConfig.toolbar.showViewportSwitcher && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("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__ */ (0, import_jsx_runtime23.jsxs)(
|
|
7755
|
+
"button",
|
|
7756
|
+
{
|
|
7757
|
+
type: "button",
|
|
7758
|
+
onClick: () => setViewport(vp),
|
|
7759
|
+
title: `Switch to ${vp} preview`,
|
|
7760
|
+
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"}`,
|
|
7761
|
+
children: [
|
|
7762
|
+
viewportIcons[vp],
|
|
7763
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "hidden md:inline", children: vp })
|
|
7764
|
+
]
|
|
7765
|
+
},
|
|
7766
|
+
vp
|
|
7767
|
+
)) })
|
|
7768
|
+
] }),
|
|
7769
|
+
resolvedConfig.toolbar.showSelectionStatus && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "hidden xl:block text-xs text-slate-500 shrink-0 font-mono", children: selectedNodeId ? `Selected: #${selectedNodeId}` : "No element selected" })
|
|
7770
|
+
] }),
|
|
7771
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-1 overflow-hidden min-h-0 relative", children: [
|
|
7772
|
+
resolvedConfig.sidebar.enabled && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("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__ */ (0, import_jsx_runtime23.jsx)(LeftSidebar, { registry, config: resolvedConfig.sidebar }) }),
|
|
7773
|
+
navigatorMode === "docked" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("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__ */ (0, import_jsx_runtime23.jsx)(LayersPanel, { registry }) }),
|
|
7774
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden flex flex-col min-h-0 h-full bg-slate-100/90 relative", children: [
|
|
7775
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 overflow-auto p-2 sm:p-4 md:p-8 flex justify-center items-start min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7776
|
+
"div",
|
|
7466
7777
|
{
|
|
7467
|
-
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
|
|
7471
|
-
|
|
7778
|
+
className: `${viewportWidthMap[viewport]} bg-white shadow-md rounded-lg overflow-hidden transition-all duration-200 min-h-[500px] border border-slate-200`,
|
|
7779
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7780
|
+
EditorCanvas,
|
|
7781
|
+
{
|
|
7782
|
+
registry,
|
|
7783
|
+
context: previewContext,
|
|
7784
|
+
viewport,
|
|
7785
|
+
onDiagnostic,
|
|
7786
|
+
config: resolvedConfig.canvas
|
|
7787
|
+
}
|
|
7788
|
+
)
|
|
7789
|
+
}
|
|
7790
|
+
) }),
|
|
7791
|
+
selectedNodeId && !isMobileInspectorOpen && resolvedConfig.inspector.enabled && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("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__ */ (0, import_jsx_runtime23.jsxs)(
|
|
7792
|
+
"button",
|
|
7793
|
+
{
|
|
7794
|
+
type: "button",
|
|
7795
|
+
onClick: () => setIsMobileInspectorOpen(true),
|
|
7796
|
+
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",
|
|
7797
|
+
children: [
|
|
7798
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Sliders, { className: "w-3.5 h-3.5" }),
|
|
7799
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { children: [
|
|
7800
|
+
"Edit Element (#",
|
|
7801
|
+
selectedNodeId,
|
|
7802
|
+
")"
|
|
7803
|
+
] })
|
|
7804
|
+
]
|
|
7805
|
+
}
|
|
7806
|
+
) }),
|
|
7807
|
+
resolvedConfig.canvas.showBreadcrumbs && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HierarchyBreadcrumbs, { registry })
|
|
7808
|
+
] }),
|
|
7809
|
+
resolvedConfig.inspector.enabled && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("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__ */ (0, import_jsx_runtime23.jsx)(InspectorPanel, { registry, config: resolvedConfig.inspector }) })
|
|
7810
|
+
] }),
|
|
7811
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("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: [
|
|
7812
|
+
resolvedConfig.sidebar.enabled && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
7813
|
+
"button",
|
|
7814
|
+
{
|
|
7815
|
+
type: "button",
|
|
7816
|
+
onClick: () => setIsMobileSidebarOpen(true),
|
|
7817
|
+
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",
|
|
7818
|
+
children: [
|
|
7819
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Plus, { className: "w-4 h-4 text-blue-600" }),
|
|
7820
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] font-medium", children: "Add" })
|
|
7821
|
+
]
|
|
7822
|
+
}
|
|
7823
|
+
),
|
|
7824
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
7825
|
+
"button",
|
|
7826
|
+
{
|
|
7827
|
+
type: "button",
|
|
7828
|
+
onClick: () => setIsMobileLayersOpen(true),
|
|
7829
|
+
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",
|
|
7830
|
+
children: [
|
|
7831
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Layers, { className: "w-4 h-4" }),
|
|
7832
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] font-medium", children: "Layers" })
|
|
7833
|
+
]
|
|
7834
|
+
}
|
|
7835
|
+
),
|
|
7836
|
+
resolvedConfig.inspector.enabled && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
7837
|
+
"button",
|
|
7838
|
+
{
|
|
7839
|
+
type: "button",
|
|
7840
|
+
onClick: () => setIsMobileInspectorOpen(true),
|
|
7841
|
+
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"}`,
|
|
7842
|
+
children: [
|
|
7843
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "relative", children: [
|
|
7844
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Sliders, { className: "w-4 h-4" }),
|
|
7845
|
+
selectedNodeId && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "absolute -top-1 -right-1 w-2 h-2 rounded-full bg-blue-600 ring-2 ring-white" })
|
|
7846
|
+
] }),
|
|
7847
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px]", children: selectedNodeId ? "Inspect *" : "Inspect" })
|
|
7848
|
+
]
|
|
7849
|
+
}
|
|
7850
|
+
),
|
|
7851
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "h-5 w-px bg-slate-200 mx-0.5" }),
|
|
7852
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
7853
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7854
|
+
"button",
|
|
7855
|
+
{
|
|
7856
|
+
type: "button",
|
|
7857
|
+
disabled: !canUndo,
|
|
7858
|
+
onClick: undo,
|
|
7859
|
+
title: "Undo",
|
|
7860
|
+
className: "p-2 rounded text-slate-600 hover:text-blue-600 disabled:opacity-30 disabled:hover:text-slate-600 transition",
|
|
7861
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Undo2, { className: "w-4 h-4" })
|
|
7862
|
+
}
|
|
7863
|
+
),
|
|
7864
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
7865
|
+
"button",
|
|
7866
|
+
{
|
|
7867
|
+
type: "button",
|
|
7868
|
+
disabled: !canRedo,
|
|
7869
|
+
onClick: redo,
|
|
7870
|
+
title: "Redo",
|
|
7871
|
+
className: "p-2 rounded text-slate-600 hover:text-blue-600 disabled:opacity-30 disabled:hover:text-slate-600 transition",
|
|
7872
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react10.Redo2, { className: "w-4 h-4" })
|
|
7472
7873
|
}
|
|
7473
7874
|
)
|
|
7474
|
-
}
|
|
7475
|
-
|
|
7476
|
-
|
|
7477
|
-
|
|
7478
|
-
|
|
7479
|
-
] })
|
|
7480
|
-
] });
|
|
7875
|
+
] })
|
|
7876
|
+
] })
|
|
7877
|
+
]
|
|
7878
|
+
}
|
|
7879
|
+
);
|
|
7481
7880
|
};
|
|
7482
7881
|
// Annotate the CommonJS export names for ESM import in node:
|
|
7483
7882
|
0 && (module.exports = {
|