@kubuild/editor 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/canvas/canvas-pan-zoom.d.ts +1 -1
- package/dist/components/canvas/canvas-pan-zoom.d.ts.map +1 -1
- package/dist/components/canvas/canvas.d.ts.map +1 -1
- package/dist/components/canvas/floating-badges.d.ts +1 -0
- package/dist/components/canvas/floating-badges.d.ts.map +1 -1
- package/dist/components/canvas/multi-device-preview.d.ts.map +1 -1
- package/dist/components/canvas/resize-handles.d.ts.map +1 -1
- package/dist/components/layout/editor.d.ts +1 -0
- package/dist/components/layout/editor.d.ts.map +1 -1
- package/dist/components/panels/blocks-panel.d.ts +1 -0
- package/dist/components/panels/blocks-panel.d.ts.map +1 -1
- package/dist/components/panels/component-panel.d.ts +1 -0
- package/dist/components/panels/component-panel.d.ts.map +1 -1
- package/dist/components/panels/left-sidebar.d.ts +1 -0
- package/dist/components/panels/left-sidebar.d.ts.map +1 -1
- package/dist/index.cjs +385 -108
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +394 -114
- package/dist/index.js.map +1 -1
- package/dist/store/store.d.ts +3 -1
- package/dist/store/store.d.ts.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -384,19 +384,55 @@ var useEditorStore = create((set, get) => ({
|
|
|
384
384
|
setAiGenerationStatus: (status) => set({ aiGenerationStatus: status }),
|
|
385
385
|
insertComponent: (type, registry, parentId, index) => {
|
|
386
386
|
const state = get();
|
|
387
|
-
|
|
388
|
-
|
|
387
|
+
let targetParentId = parentId ?? state.selectedNodeId ?? state.document.document.id;
|
|
388
|
+
let targetIndex = index;
|
|
389
|
+
let parentNode = findNodeById(state.document.document, targetParentId);
|
|
389
390
|
if (!parentNode) {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
error: `Insertion target "${targetParentId}" was not found in the document.`
|
|
393
|
-
};
|
|
391
|
+
targetParentId = state.document.document.id;
|
|
392
|
+
parentNode = state.document.document;
|
|
394
393
|
}
|
|
395
394
|
const definition = registry.get(type);
|
|
396
395
|
if (!definition) {
|
|
397
396
|
return { success: false, error: `Unknown component type "${type}".` };
|
|
398
397
|
}
|
|
399
|
-
|
|
398
|
+
let policy = registry.canInsertChild(parentNode.type, type);
|
|
399
|
+
if (!policy.valid && !parentId) {
|
|
400
|
+
const loc = findNodeLocation(state.document.document, targetParentId);
|
|
401
|
+
if (loc && loc.parent) {
|
|
402
|
+
const parentPolicy = registry.canInsertChild(loc.parent.type, type);
|
|
403
|
+
if (parentPolicy.valid) {
|
|
404
|
+
targetParentId = loc.parent.id;
|
|
405
|
+
targetIndex = loc.index + 1;
|
|
406
|
+
parentNode = loc.parent;
|
|
407
|
+
policy = parentPolicy;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
if (!policy.valid && parentNode.type === "page" && type !== "section") {
|
|
411
|
+
const sections = parentNode.children?.filter((c) => c.type === "section") ?? [];
|
|
412
|
+
const lastSection = sections[sections.length - 1];
|
|
413
|
+
if (lastSection) {
|
|
414
|
+
const sectionPolicy = registry.canInsertChild(lastSection.type, type);
|
|
415
|
+
if (sectionPolicy.valid) {
|
|
416
|
+
targetParentId = lastSection.id;
|
|
417
|
+
targetIndex = lastSection.children?.length ?? 0;
|
|
418
|
+
parentNode = lastSection;
|
|
419
|
+
policy = sectionPolicy;
|
|
420
|
+
} else {
|
|
421
|
+
const containers = lastSection.children?.filter((c) => c.type === "container") ?? [];
|
|
422
|
+
const lastContainer = containers[containers.length - 1];
|
|
423
|
+
if (lastContainer) {
|
|
424
|
+
const containerPolicy = registry.canInsertChild(lastContainer.type, type);
|
|
425
|
+
if (containerPolicy.valid) {
|
|
426
|
+
targetParentId = lastContainer.id;
|
|
427
|
+
targetIndex = lastContainer.children?.length ?? 0;
|
|
428
|
+
parentNode = lastContainer;
|
|
429
|
+
policy = containerPolicy;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
400
436
|
if (!policy.valid) {
|
|
401
437
|
return { success: false, error: policy.errors.join(" ") };
|
|
402
438
|
}
|
|
@@ -424,7 +460,7 @@ var useEditorStore = create((set, get) => ({
|
|
|
424
460
|
...definition.defaultStyles ? { styles: deepClone(definition.defaultStyles) } : {},
|
|
425
461
|
...children ? { children } : {}
|
|
426
462
|
};
|
|
427
|
-
get().dispatch((doc) => insertNode(doc, { parentId: targetParentId, node, index }));
|
|
463
|
+
get().dispatch((doc) => insertNode(doc, { parentId: targetParentId, node, index: targetIndex }));
|
|
428
464
|
if (!state.activeArtboardId && OVERLAY_COMPONENT_TYPES.includes(type)) {
|
|
429
465
|
const detached = get().detachNodeToArtboard(nodeId, { name: definition.label });
|
|
430
466
|
if (detached.success && detached.triggerId && detached.stubNodeId) {
|
|
@@ -526,14 +562,36 @@ var useEditorStore = create((set, get) => ({
|
|
|
526
562
|
error: "Cannot move a node into itself or one of its own descendants."
|
|
527
563
|
};
|
|
528
564
|
}
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
565
|
+
if (registry) {
|
|
566
|
+
const policy = registry.canInsertChild(targetParent.type, sourceLocation.node.type);
|
|
567
|
+
if (!policy.valid) {
|
|
568
|
+
return { success: false, error: policy.errors.join(" ") };
|
|
569
|
+
}
|
|
532
570
|
}
|
|
533
571
|
const adjustedIndex = sourceLocation.parent.id === targetParentId && typeof index === "number" && index > sourceLocation.index ? index - 1 : index;
|
|
534
572
|
get().dispatch((doc) => moveNode(doc, { nodeId, targetParentId, index: adjustedIndex }));
|
|
535
573
|
return { success: true };
|
|
536
574
|
},
|
|
575
|
+
moveComponentUp: (nodeId, registry) => {
|
|
576
|
+
const state = get();
|
|
577
|
+
const loc = findNodeLocation(state.document.document, nodeId);
|
|
578
|
+
if (!loc || !loc.parent || loc.index <= 0) {
|
|
579
|
+
return { success: false, error: "Cannot move up: already at the top." };
|
|
580
|
+
}
|
|
581
|
+
return get().moveComponent(nodeId, loc.parent.id, registry, loc.index - 1);
|
|
582
|
+
},
|
|
583
|
+
moveComponentDown: (nodeId, registry) => {
|
|
584
|
+
const state = get();
|
|
585
|
+
const loc = findNodeLocation(state.document.document, nodeId);
|
|
586
|
+
if (!loc || !loc.parent) {
|
|
587
|
+
return { success: false, error: "Node parent not found." };
|
|
588
|
+
}
|
|
589
|
+
const siblingCount = loc.parent.children?.length ?? 1;
|
|
590
|
+
if (loc.index >= siblingCount - 1) {
|
|
591
|
+
return { success: false, error: "Cannot move down: already at the bottom." };
|
|
592
|
+
}
|
|
593
|
+
return get().moveComponent(nodeId, loc.parent.id, registry, loc.index + 2);
|
|
594
|
+
},
|
|
537
595
|
duplicateComponent: (nodeId, _registry) => {
|
|
538
596
|
const state = get();
|
|
539
597
|
if (nodeId === state.document.document.id) {
|
|
@@ -4523,7 +4581,7 @@ import {
|
|
|
4523
4581
|
// src/components/canvas/floating-badges.tsx
|
|
4524
4582
|
import { ARTBOARD_REFERENCE_NODE_TYPE } from "@kubuild/schema";
|
|
4525
4583
|
import { findNodeById as findNodeById4, getParentNodeId as getParentNodeId2 } from "@kubuild/core";
|
|
4526
|
-
import { ArrowUp, Move, Copy as Copy2, Trash2 as Trash24, ExternalLink } from "lucide-react";
|
|
4584
|
+
import { ArrowUp, ChevronUp as ChevronUp3, ChevronDown as ChevronDown3, Move, Copy as Copy2, Trash2 as Trash24, ExternalLink } from "lucide-react";
|
|
4527
4585
|
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
4528
4586
|
var FloatingActionBadges = ({
|
|
4529
4587
|
selectedNodeId,
|
|
@@ -4536,6 +4594,8 @@ var FloatingActionBadges = ({
|
|
|
4536
4594
|
selectNode,
|
|
4537
4595
|
duplicateComponent,
|
|
4538
4596
|
deleteComponent,
|
|
4597
|
+
moveComponentUp,
|
|
4598
|
+
moveComponentDown,
|
|
4539
4599
|
detachNodeToArtboard,
|
|
4540
4600
|
activateArtboard,
|
|
4541
4601
|
activeArtboardId
|
|
@@ -4593,6 +4653,30 @@ var FloatingActionBadges = ({
|
|
|
4593
4653
|
children: /* @__PURE__ */ jsx7(Move, { className: "w-3.5 h-3.5", "aria-hidden": "true" })
|
|
4594
4654
|
}
|
|
4595
4655
|
),
|
|
4656
|
+
!isRoot && /* @__PURE__ */ jsx7(
|
|
4657
|
+
"button",
|
|
4658
|
+
{
|
|
4659
|
+
type: "button",
|
|
4660
|
+
"data-testid": "floating-badge-move-up",
|
|
4661
|
+
title: "Move Up",
|
|
4662
|
+
"aria-label": "Move Up",
|
|
4663
|
+
onClick: () => moveComponentUp(node.id, registry),
|
|
4664
|
+
className: "px-1.5 py-1 hover:bg-blue-500 active:bg-blue-700 transition flex items-center justify-center border-l border-blue-500/40 text-[11px]",
|
|
4665
|
+
children: /* @__PURE__ */ jsx7(ChevronUp3, { className: "w-3.5 h-3.5", "aria-hidden": "true" })
|
|
4666
|
+
}
|
|
4667
|
+
),
|
|
4668
|
+
!isRoot && /* @__PURE__ */ jsx7(
|
|
4669
|
+
"button",
|
|
4670
|
+
{
|
|
4671
|
+
type: "button",
|
|
4672
|
+
"data-testid": "floating-badge-move-down",
|
|
4673
|
+
title: "Move Down",
|
|
4674
|
+
"aria-label": "Move Down",
|
|
4675
|
+
onClick: () => moveComponentDown(node.id, registry),
|
|
4676
|
+
className: "px-1.5 py-1 hover:bg-blue-500 active:bg-blue-700 transition flex items-center justify-center border-l border-blue-500/40 text-[11px]",
|
|
4677
|
+
children: /* @__PURE__ */ jsx7(ChevronDown3, { className: "w-3.5 h-3.5", "aria-hidden": "true" })
|
|
4678
|
+
}
|
|
4679
|
+
),
|
|
4596
4680
|
!isRoot && /* @__PURE__ */ jsx7(
|
|
4597
4681
|
"button",
|
|
4598
4682
|
{
|
|
@@ -5143,6 +5227,7 @@ var ResizeHandles = ({
|
|
|
5143
5227
|
borderRadius: "1px",
|
|
5144
5228
|
boxShadow: "0 1px 2px rgba(0, 0, 0, 0.15)",
|
|
5145
5229
|
pointerEvents: "auto",
|
|
5230
|
+
touchAction: "none",
|
|
5146
5231
|
cursor,
|
|
5147
5232
|
zIndex: 51,
|
|
5148
5233
|
boxSizing: "border-box",
|
|
@@ -6133,6 +6218,7 @@ function useCanvasPanZoom({
|
|
|
6133
6218
|
const isSpacePressedRef = useRef5(isSpacePressed);
|
|
6134
6219
|
isSpacePressedRef.current = isSpacePressed;
|
|
6135
6220
|
const dragStartRef = useRef5(null);
|
|
6221
|
+
const activePointerIdRef = useRef5(null);
|
|
6136
6222
|
useEffect7(() => {
|
|
6137
6223
|
if (!enabled) return;
|
|
6138
6224
|
const onKeyDown = (e) => {
|
|
@@ -6192,16 +6278,94 @@ function useCanvasPanZoom({
|
|
|
6192
6278
|
container.addEventListener("wheel", onWheel, { passive: false });
|
|
6193
6279
|
return () => container.removeEventListener("wheel", onWheel);
|
|
6194
6280
|
}, [containerRef, enabled]);
|
|
6281
|
+
const rafPanRef = useRef5(null);
|
|
6282
|
+
const pendingPanRef = useRef5(null);
|
|
6283
|
+
useEffect7(() => {
|
|
6284
|
+
const container = containerRef.current;
|
|
6285
|
+
if (!container || !enabled) return;
|
|
6286
|
+
let touchStartDistance = 0;
|
|
6287
|
+
let touchStartZoom = 1;
|
|
6288
|
+
let touchStartPan = { x: 0, y: 0 };
|
|
6289
|
+
let touchStartMid = { x: 0, y: 0 };
|
|
6290
|
+
let isPinching = false;
|
|
6291
|
+
const onTouchStart = (e) => {
|
|
6292
|
+
if (e.touches.length === 2) {
|
|
6293
|
+
e.preventDefault();
|
|
6294
|
+
activePointerIdRef.current = null;
|
|
6295
|
+
dragStartRef.current = null;
|
|
6296
|
+
pendingPanRef.current = null;
|
|
6297
|
+
if (rafPanRef.current !== null) {
|
|
6298
|
+
cancelAnimationFrame(rafPanRef.current);
|
|
6299
|
+
rafPanRef.current = null;
|
|
6300
|
+
}
|
|
6301
|
+
const t1 = e.touches[0];
|
|
6302
|
+
const t2 = e.touches[1];
|
|
6303
|
+
touchStartDistance = Math.hypot(t2.clientX - t1.clientX, t2.clientY - t1.clientY);
|
|
6304
|
+
touchStartZoom = zoomRef.current;
|
|
6305
|
+
touchStartPan = { ...panRef.current };
|
|
6306
|
+
touchStartMid = {
|
|
6307
|
+
x: (t1.clientX + t2.clientX) / 2,
|
|
6308
|
+
y: (t1.clientY + t2.clientY) / 2
|
|
6309
|
+
};
|
|
6310
|
+
isPinching = true;
|
|
6311
|
+
setIsPanning(true);
|
|
6312
|
+
}
|
|
6313
|
+
};
|
|
6314
|
+
const onTouchMove = (e) => {
|
|
6315
|
+
if (e.touches.length === 2 && isPinching && touchStartDistance > 0) {
|
|
6316
|
+
e.preventDefault();
|
|
6317
|
+
const t1 = e.touches[0];
|
|
6318
|
+
const t2 = e.touches[1];
|
|
6319
|
+
const currentDistance = Math.hypot(t2.clientX - t1.clientX, t2.clientY - t1.clientY);
|
|
6320
|
+
const scale = currentDistance / touchStartDistance;
|
|
6321
|
+
const nextZoom = clampZoom(touchStartZoom * scale);
|
|
6322
|
+
const currentMidX = (t1.clientX + t2.clientX) / 2;
|
|
6323
|
+
const currentMidY = (t1.clientY + t2.clientY) / 2;
|
|
6324
|
+
const rect = container.getBoundingClientRect();
|
|
6325
|
+
const midContainerX = touchStartMid.x - rect.left;
|
|
6326
|
+
const midContainerY = touchStartMid.y - rect.top;
|
|
6327
|
+
const newPanX = midContainerX - (midContainerX - touchStartPan.x) * (nextZoom / touchStartZoom) + (currentMidX - touchStartMid.x);
|
|
6328
|
+
const newPanY = midContainerY - (midContainerY - touchStartPan.y) * (nextZoom / touchStartZoom) + (currentMidY - touchStartMid.y);
|
|
6329
|
+
if (rafPanRef.current === null) {
|
|
6330
|
+
rafPanRef.current = requestAnimationFrame(() => {
|
|
6331
|
+
setZoom(nextZoom);
|
|
6332
|
+
setPan({ x: Math.round(newPanX), y: Math.round(newPanY) });
|
|
6333
|
+
rafPanRef.current = null;
|
|
6334
|
+
});
|
|
6335
|
+
}
|
|
6336
|
+
}
|
|
6337
|
+
};
|
|
6338
|
+
const onTouchEnd = (e) => {
|
|
6339
|
+
if (isPinching && e.touches.length < 2) {
|
|
6340
|
+
isPinching = false;
|
|
6341
|
+
touchStartDistance = 0;
|
|
6342
|
+
setIsPanning(false);
|
|
6343
|
+
}
|
|
6344
|
+
};
|
|
6345
|
+
container.addEventListener("touchstart", onTouchStart, { passive: false });
|
|
6346
|
+
container.addEventListener("touchmove", onTouchMove, { passive: false });
|
|
6347
|
+
container.addEventListener("touchend", onTouchEnd, { passive: false });
|
|
6348
|
+
container.addEventListener("touchcancel", onTouchEnd, { passive: false });
|
|
6349
|
+
return () => {
|
|
6350
|
+
container.removeEventListener("touchstart", onTouchStart);
|
|
6351
|
+
container.removeEventListener("touchmove", onTouchMove);
|
|
6352
|
+
container.removeEventListener("touchend", onTouchEnd);
|
|
6353
|
+
container.removeEventListener("touchcancel", onTouchEnd);
|
|
6354
|
+
};
|
|
6355
|
+
}, [containerRef, enabled]);
|
|
6195
6356
|
const handlePointerDown = useCallback5(
|
|
6196
|
-
(e) => {
|
|
6357
|
+
(e, forcePan = false) => {
|
|
6197
6358
|
if (!enabled) return;
|
|
6359
|
+
const isTouch = e.pointerType === "touch" || e.pointerType === "pen";
|
|
6360
|
+
if (isTouch && e.isPrimary === false) return;
|
|
6198
6361
|
const isMiddleClick = e.button === 1;
|
|
6199
6362
|
const isSpacePan = isSpacePressedRef.current && e.button === 0;
|
|
6200
|
-
const isHandMode = toolModeRef.current === "hand" && e.button === 0;
|
|
6201
|
-
if (isMiddleClick || isSpacePan || isHandMode) {
|
|
6363
|
+
const isHandMode = toolModeRef.current === "hand" && (e.button === 0 || isTouch);
|
|
6364
|
+
if (forcePan || isMiddleClick || isSpacePan || isHandMode) {
|
|
6202
6365
|
e.preventDefault();
|
|
6203
6366
|
e.stopPropagation();
|
|
6204
6367
|
setIsPanning(true);
|
|
6368
|
+
activePointerIdRef.current = e.pointerId;
|
|
6205
6369
|
dragStartRef.current = {
|
|
6206
6370
|
startX: e.clientX,
|
|
6207
6371
|
startY: e.clientY,
|
|
@@ -6215,14 +6379,33 @@ function useCanvasPanZoom({
|
|
|
6215
6379
|
const handlePointerMove = useCallback5((e) => {
|
|
6216
6380
|
const drag = dragStartRef.current;
|
|
6217
6381
|
if (!drag) return;
|
|
6382
|
+
if (activePointerIdRef.current !== null && e.pointerId !== activePointerIdRef.current) return;
|
|
6218
6383
|
const deltaX = e.clientX - drag.startX;
|
|
6219
6384
|
const deltaY = e.clientY - drag.startY;
|
|
6220
|
-
|
|
6385
|
+
pendingPanRef.current = {
|
|
6221
6386
|
x: Math.round(drag.initialPanX + deltaX),
|
|
6222
6387
|
y: Math.round(drag.initialPanY + deltaY)
|
|
6223
|
-
}
|
|
6388
|
+
};
|
|
6389
|
+
if (rafPanRef.current === null) {
|
|
6390
|
+
rafPanRef.current = requestAnimationFrame(() => {
|
|
6391
|
+
if (pendingPanRef.current) {
|
|
6392
|
+
setPan(pendingPanRef.current);
|
|
6393
|
+
}
|
|
6394
|
+
rafPanRef.current = null;
|
|
6395
|
+
});
|
|
6396
|
+
}
|
|
6224
6397
|
}, []);
|
|
6225
|
-
const handlePointerUp = useCallback5(() => {
|
|
6398
|
+
const handlePointerUp = useCallback5((e) => {
|
|
6399
|
+
if (activePointerIdRef.current !== null && e.pointerId !== activePointerIdRef.current) return;
|
|
6400
|
+
if (rafPanRef.current !== null) {
|
|
6401
|
+
cancelAnimationFrame(rafPanRef.current);
|
|
6402
|
+
rafPanRef.current = null;
|
|
6403
|
+
}
|
|
6404
|
+
if (pendingPanRef.current) {
|
|
6405
|
+
setPan(pendingPanRef.current);
|
|
6406
|
+
pendingPanRef.current = null;
|
|
6407
|
+
}
|
|
6408
|
+
activePointerIdRef.current = null;
|
|
6226
6409
|
if (dragStartRef.current) {
|
|
6227
6410
|
dragStartRef.current = null;
|
|
6228
6411
|
setIsPanning(false);
|
|
@@ -6235,6 +6418,10 @@ function useCanvasPanZoom({
|
|
|
6235
6418
|
return () => {
|
|
6236
6419
|
window.removeEventListener("pointermove", handlePointerMove);
|
|
6237
6420
|
window.removeEventListener("pointerup", handlePointerUp);
|
|
6421
|
+
if (rafPanRef.current !== null) {
|
|
6422
|
+
cancelAnimationFrame(rafPanRef.current);
|
|
6423
|
+
rafPanRef.current = null;
|
|
6424
|
+
}
|
|
6238
6425
|
};
|
|
6239
6426
|
}
|
|
6240
6427
|
}, [isPanning, handlePointerMove, handlePointerUp]);
|
|
@@ -6539,6 +6726,7 @@ var MultiDevicePreview = ({
|
|
|
6539
6726
|
context,
|
|
6540
6727
|
viewport: device.id,
|
|
6541
6728
|
mode: previewMode ? "runtime" : "editor",
|
|
6729
|
+
selectedNodeId,
|
|
6542
6730
|
onNodeClick: (id) => {
|
|
6543
6731
|
selectNode(id);
|
|
6544
6732
|
setViewport(device.id);
|
|
@@ -7231,7 +7419,7 @@ var ViewportResizer = ({
|
|
|
7231
7419
|
showPresets && /* @__PURE__ */ jsxs15(
|
|
7232
7420
|
"div",
|
|
7233
7421
|
{
|
|
7234
|
-
className: "flex items-center justify-between gap-2 w-full px-1 py-1 mb-2 select-none text-xs",
|
|
7422
|
+
className: "flex flex-wrap items-center justify-between gap-x-2 gap-y-1 w-full px-1 py-1 mb-2 select-none text-xs",
|
|
7235
7423
|
onPointerDown: onHeaderPointerDown,
|
|
7236
7424
|
children: [
|
|
7237
7425
|
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2 min-w-0 cursor-grab active:cursor-grabbing", children: [
|
|
@@ -7431,42 +7619,34 @@ var EditorCanvas = ({
|
|
|
7431
7619
|
activeArtboardId: propActiveArtboardId,
|
|
7432
7620
|
className
|
|
7433
7621
|
}) => {
|
|
7434
|
-
const
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
7446
|
-
|
|
7447
|
-
|
|
7448
|
-
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
aiGenerationStatus: storeAiGenerationStatus,
|
|
7463
|
-
componentArtboards: storeComponentArtboards,
|
|
7464
|
-
activeArtboardId: storeActiveArtboardId,
|
|
7465
|
-
activateArtboard,
|
|
7466
|
-
removeComponentArtboard,
|
|
7467
|
-
setComponentArtboardPosition,
|
|
7468
|
-
setComponentArtboardWidth
|
|
7469
|
-
} = useEditorStore();
|
|
7622
|
+
const storeDoc = useEditorStore((s) => s.document);
|
|
7623
|
+
const selectedNodeId = useEditorStore((s) => s.selectedNodeId);
|
|
7624
|
+
const selectedNodeIds = useEditorStore((s) => s.selectedNodeIds);
|
|
7625
|
+
const hoveredNodeId = useEditorStore((s) => s.hoveredNodeId);
|
|
7626
|
+
const dragPayload = useEditorStore((s) => s.dragPayload);
|
|
7627
|
+
const selectNode = useEditorStore((s) => s.selectNode);
|
|
7628
|
+
const selectMultipleNodes = useEditorStore((s) => s.selectMultipleNodes);
|
|
7629
|
+
const toggleNodeSelection = useEditorStore((s) => s.toggleNodeSelection);
|
|
7630
|
+
const hoverNode = useEditorStore((s) => s.hoverNode);
|
|
7631
|
+
const updateNodeProps = useEditorStore((s) => s.updateNodeProps);
|
|
7632
|
+
const setDragPayload = useEditorStore((s) => s.setDragPayload);
|
|
7633
|
+
const insertComponent = useEditorStore((s) => s.insertComponent);
|
|
7634
|
+
const insertBlock = useEditorStore((s) => s.insertBlock);
|
|
7635
|
+
const moveComponent = useEditorStore((s) => s.moveComponent);
|
|
7636
|
+
const deleteComponent = useEditorStore((s) => s.deleteComponent);
|
|
7637
|
+
const duplicateComponent = useEditorStore((s) => s.duplicateComponent);
|
|
7638
|
+
const previewMode = useEditorStore((s) => s.previewMode);
|
|
7639
|
+
const multiDeviceMode = useEditorStore((s) => s.multiDeviceMode);
|
|
7640
|
+
const toggleMultiDeviceMode = useEditorStore((s) => s.toggleMultiDeviceMode);
|
|
7641
|
+
const addActionLog = useEditorStore((s) => s.addActionLog);
|
|
7642
|
+
const setLiveFormState = useEditorStore((s) => s.setLiveFormState);
|
|
7643
|
+
const storeAiGenerationStatus = useEditorStore((s) => s.aiGenerationStatus);
|
|
7644
|
+
const storeComponentArtboards = useEditorStore((s) => s.componentArtboards);
|
|
7645
|
+
const storeActiveArtboardId = useEditorStore((s) => s.activeArtboardId);
|
|
7646
|
+
const activateArtboard = useEditorStore((s) => s.activateArtboard);
|
|
7647
|
+
const removeComponentArtboard = useEditorStore((s) => s.removeComponentArtboard);
|
|
7648
|
+
const setComponentArtboardPosition = useEditorStore((s) => s.setComponentArtboardPosition);
|
|
7649
|
+
const setComponentArtboardWidth = useEditorStore((s) => s.setComponentArtboardWidth);
|
|
7470
7650
|
const document2 = propDoc ?? storeDoc;
|
|
7471
7651
|
const aiGenerationStatus = propAiGenerationStatus ?? storeAiGenerationStatus;
|
|
7472
7652
|
const componentArtboards = propComponentArtboards ?? storeComponentArtboards;
|
|
@@ -7727,6 +7907,14 @@ var EditorCanvas = ({
|
|
|
7727
7907
|
const [draggingArtboardId, setDraggingArtboardId] = useState12(null);
|
|
7728
7908
|
const [dragPosition, setDragPosition] = useState12(null);
|
|
7729
7909
|
const marqueeDragRef = useRef7(null);
|
|
7910
|
+
const isTouchDevice = useMemo7(() => {
|
|
7911
|
+
if (typeof window === "undefined") return false;
|
|
7912
|
+
return window.matchMedia && window.matchMedia("(pointer: coarse)").matches || "ontouchstart" in window;
|
|
7913
|
+
}, []);
|
|
7914
|
+
const isSmallScreen = useMemo7(() => {
|
|
7915
|
+
if (typeof window === "undefined") return false;
|
|
7916
|
+
return window.innerWidth < 768;
|
|
7917
|
+
}, []);
|
|
7730
7918
|
const {
|
|
7731
7919
|
pan,
|
|
7732
7920
|
setPan,
|
|
@@ -7821,14 +8009,23 @@ var EditorCanvas = ({
|
|
|
7821
8009
|
setSelectedRects(multi);
|
|
7822
8010
|
};
|
|
7823
8011
|
recompute();
|
|
8012
|
+
let rafId = null;
|
|
8013
|
+
const throttledRecompute = () => {
|
|
8014
|
+
if (rafId !== null) return;
|
|
8015
|
+
rafId = requestAnimationFrame(() => {
|
|
8016
|
+
recompute();
|
|
8017
|
+
rafId = null;
|
|
8018
|
+
});
|
|
8019
|
+
};
|
|
7824
8020
|
const container = containerRef.current;
|
|
7825
|
-
window.addEventListener("resize",
|
|
7826
|
-
window.addEventListener("scroll",
|
|
7827
|
-
container?.addEventListener("input",
|
|
8021
|
+
window.addEventListener("resize", throttledRecompute);
|
|
8022
|
+
window.addEventListener("scroll", throttledRecompute, { passive: true, capture: true });
|
|
8023
|
+
container?.addEventListener("input", throttledRecompute);
|
|
7828
8024
|
return () => {
|
|
7829
|
-
|
|
7830
|
-
window.removeEventListener("
|
|
7831
|
-
|
|
8025
|
+
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
8026
|
+
window.removeEventListener("resize", throttledRecompute);
|
|
8027
|
+
window.removeEventListener("scroll", throttledRecompute, true);
|
|
8028
|
+
container?.removeEventListener("input", throttledRecompute);
|
|
7832
8029
|
};
|
|
7833
8030
|
}, [activeDoc, selectedNodeId, selectedNodeIds, hoveredNodeId, viewport, zoom, pan, fluidWidth, effectiveActivePageId]);
|
|
7834
8031
|
useEffect10(() => {
|
|
@@ -7923,6 +8120,7 @@ var EditorCanvas = ({
|
|
|
7923
8120
|
};
|
|
7924
8121
|
}, [registry]);
|
|
7925
8122
|
const candidateRects = useMemo7(() => {
|
|
8123
|
+
if (isTouchDevice && isSmallScreen) return [];
|
|
7926
8124
|
const layer = layerRef.current;
|
|
7927
8125
|
if (!layer || !selectedNodeId) return [];
|
|
7928
8126
|
const elements = layer.querySelectorAll("[data-kubuild-node]");
|
|
@@ -7942,12 +8140,16 @@ var EditorCanvas = ({
|
|
|
7942
8140
|
}
|
|
7943
8141
|
});
|
|
7944
8142
|
return results;
|
|
7945
|
-
}, [document2, selectedNodeId, zoom]);
|
|
8143
|
+
}, [document2, selectedNodeId, zoom, isTouchDevice, isSmallScreen]);
|
|
7946
8144
|
const handleMouseOver = (e) => {
|
|
8145
|
+
if (isTouchDevice) return;
|
|
7947
8146
|
const el = e.target.closest("[data-kubuild-node]");
|
|
7948
8147
|
if (el) hoverNode(el.getAttribute("data-kubuild-node"));
|
|
7949
8148
|
};
|
|
7950
|
-
const handleMouseLeave = () =>
|
|
8149
|
+
const handleMouseLeave = () => {
|
|
8150
|
+
if (isTouchDevice) return;
|
|
8151
|
+
hoverNode(null);
|
|
8152
|
+
};
|
|
7951
8153
|
const handleCanvasPointerDown = (e) => {
|
|
7952
8154
|
if (e.button === 1 || isSpacePressed || toolMode === "hand") {
|
|
7953
8155
|
handlePanPointerDown(e);
|
|
@@ -7959,7 +8161,14 @@ var EditorCanvas = ({
|
|
|
7959
8161
|
const isRootOrEmpty = !clickedNode || clickedNode.getAttribute("data-kubuild-node") === document2.document.id;
|
|
7960
8162
|
const isDirectCanvasBg = target === containerRef.current || target === layerRef.current || target.getAttribute("data-testid") === "canvas-viewport-container" || target.getAttribute("data-testid") === "canvas-transform-layer";
|
|
7961
8163
|
if (isDirectCanvasBg && !e.shiftKey) {
|
|
7962
|
-
handlePanPointerDown(e);
|
|
8164
|
+
handlePanPointerDown(e, true);
|
|
8165
|
+
return;
|
|
8166
|
+
}
|
|
8167
|
+
if (e.pointerType === "touch" || e.pointerType === "pen") {
|
|
8168
|
+
if (isRootOrEmpty) {
|
|
8169
|
+
selectNode(null);
|
|
8170
|
+
handlePanPointerDown(e, true);
|
|
8171
|
+
}
|
|
7963
8172
|
return;
|
|
7964
8173
|
}
|
|
7965
8174
|
if (isRootOrEmpty) {
|
|
@@ -8308,9 +8517,12 @@ var EditorCanvas = ({
|
|
|
8308
8517
|
overflow: "hidden",
|
|
8309
8518
|
cursor: cursorStyle,
|
|
8310
8519
|
backgroundColor: "#f1f5f9",
|
|
8311
|
-
|
|
8312
|
-
|
|
8313
|
-
|
|
8520
|
+
// App owns single-finger pan and two-finger pinch-zoom on this container itself,
|
|
8521
|
+
// so native browser pan/zoom must stay fully off to avoid the two fighting.
|
|
8522
|
+
touchAction: "none",
|
|
8523
|
+
backgroundImage: isSmallScreen && isTouchDevice ? void 0 : `radial-gradient(circle, #cbd5e1 ${Math.max(0.75, Math.min(2.5, 1.2 * zoom))}px, transparent ${Math.max(0.75, Math.min(2.5, 1.2 * zoom))}px)`,
|
|
8524
|
+
backgroundSize: isSmallScreen && isTouchDevice ? void 0 : `${24 * zoom}px ${24 * zoom}px`,
|
|
8525
|
+
backgroundPosition: isSmallScreen && isTouchDevice ? void 0 : `${pan.x}px ${pan.y}px`
|
|
8314
8526
|
},
|
|
8315
8527
|
onPointerDown: handleCanvasPointerDown,
|
|
8316
8528
|
onPointerMove: handleCanvasPointerMove,
|
|
@@ -8389,6 +8601,7 @@ var EditorCanvas = ({
|
|
|
8389
8601
|
context: contextForArtboard(pageItem),
|
|
8390
8602
|
viewport: pageViewport,
|
|
8391
8603
|
mode: previewMode ? "runtime" : "editor",
|
|
8604
|
+
selectedNodeId,
|
|
8392
8605
|
onNodeClick: (id, e) => {
|
|
8393
8606
|
if (!previewMode) {
|
|
8394
8607
|
if (e?.shiftKey) {
|
|
@@ -8524,7 +8737,7 @@ var EditorCanvas = ({
|
|
|
8524
8737
|
containerRef: activeArtboardRef
|
|
8525
8738
|
}
|
|
8526
8739
|
),
|
|
8527
|
-
!previewMode && !isMultiSelecting && selectedRect && selectedNodeId && selectedNodeId !== activeDoc.document.id && /* @__PURE__ */ jsx18(
|
|
8740
|
+
!previewMode && !isMultiSelecting && !(isTouchDevice && isSmallScreen) && selectedRect && selectedNodeId && selectedNodeId !== activeDoc.document.id && /* @__PURE__ */ jsx18(
|
|
8528
8741
|
ResizeHandles,
|
|
8529
8742
|
{
|
|
8530
8743
|
selectedNodeId,
|
|
@@ -8534,7 +8747,7 @@ var EditorCanvas = ({
|
|
|
8534
8747
|
onGuidesChange: setActiveGuides
|
|
8535
8748
|
}
|
|
8536
8749
|
),
|
|
8537
|
-
!previewMode && !isMultiSelecting && selectedRect && selectedNodeId && selectedNodeId !== activeDoc.document.id && /* @__PURE__ */ jsx18(
|
|
8750
|
+
!previewMode && !isMultiSelecting && !(isTouchDevice && isSmallScreen) && selectedRect && selectedNodeId && selectedNodeId !== activeDoc.document.id && /* @__PURE__ */ jsx18(
|
|
8538
8751
|
SpacingSliders,
|
|
8539
8752
|
{
|
|
8540
8753
|
selectedNodeId,
|
|
@@ -17830,7 +18043,7 @@ var InspectorPanel = ({
|
|
|
17830
18043
|
// src/components/panels/layers-panel.tsx
|
|
17831
18044
|
import { useEffect as useEffect22, useState as useState30 } from "react";
|
|
17832
18045
|
import { findNodeById as findNodeById10, findNodeLocation as findNodeLocation4, isDescendantOf as isDescendantOf3, getAncestorChain as getAncestorChain2 } from "@kubuild/core";
|
|
17833
|
-
import { ChevronDown as
|
|
18046
|
+
import { ChevronDown as ChevronDown4, ChevronRight as ChevronRight2 } from "lucide-react";
|
|
17834
18047
|
import { jsx as jsx41, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
17835
18048
|
var LayersPanel = ({ registry, className }) => {
|
|
17836
18049
|
const { document: document2, selectedNodeId, hoveredNodeId, selectNode, hoverNode, moveComponent } = useEditorStore();
|
|
@@ -17962,7 +18175,7 @@ var LayersPanel = ({ registry, className }) => {
|
|
|
17962
18175
|
},
|
|
17963
18176
|
"aria-label": isExpanded ? "Collapse" : "Expand",
|
|
17964
18177
|
className: "w-4 shrink-0 text-slate-400 hover:text-slate-700 flex items-center justify-center",
|
|
17965
|
-
children: isExpanded ? /* @__PURE__ */ jsx41(
|
|
18178
|
+
children: isExpanded ? /* @__PURE__ */ jsx41(ChevronDown4, { className: "w-3 h-3", "aria-hidden": "true" }) : /* @__PURE__ */ jsx41(ChevronRight2, { className: "w-3 h-3", "aria-hidden": "true" })
|
|
17966
18179
|
}
|
|
17967
18180
|
) : /* @__PURE__ */ jsx41("span", { className: "w-4 shrink-0" }),
|
|
17968
18181
|
/* @__PURE__ */ jsx41("span", { className: "shrink-0 text-slate-400", children: /* @__PURE__ */ jsx41(ComponentIcon, { iconOrType: registry.get(node.type)?.icon ?? node.type, size: 13 }) }),
|
|
@@ -18012,7 +18225,12 @@ var CATEGORY_LABELS = {
|
|
|
18012
18225
|
data: "Data",
|
|
18013
18226
|
custom: "Custom"
|
|
18014
18227
|
};
|
|
18015
|
-
var ComponentPanel = ({
|
|
18228
|
+
var ComponentPanel = ({
|
|
18229
|
+
registry,
|
|
18230
|
+
config,
|
|
18231
|
+
className,
|
|
18232
|
+
onItemInserted
|
|
18233
|
+
}) => {
|
|
18016
18234
|
const insertComponent = useEditorStore((s) => s.insertComponent);
|
|
18017
18235
|
const setDragPayload = useEditorStore((s) => s.setDragPayload);
|
|
18018
18236
|
const [error, setError] = useState31(null);
|
|
@@ -18044,7 +18262,12 @@ var ComponentPanel = ({ registry, config, className }) => {
|
|
|
18044
18262
|
}).filter((group) => group.items.length > 0);
|
|
18045
18263
|
const handleInsert = (definition) => {
|
|
18046
18264
|
const result = insertComponent(definition.type, registry);
|
|
18047
|
-
|
|
18265
|
+
if (result.success) {
|
|
18266
|
+
setError(null);
|
|
18267
|
+
onItemInserted?.();
|
|
18268
|
+
} else {
|
|
18269
|
+
setError(result.error ?? `Could not insert "${definition.label}".`);
|
|
18270
|
+
}
|
|
18048
18271
|
};
|
|
18049
18272
|
const handleDragStart = (e, definition) => {
|
|
18050
18273
|
e.dataTransfer.effectAllowed = "copy";
|
|
@@ -18210,7 +18433,8 @@ var BlockThumbnail = ({ block }) => {
|
|
|
18210
18433
|
var BlocksPanel = ({
|
|
18211
18434
|
blocks = STARTER_BLOCKS3,
|
|
18212
18435
|
className,
|
|
18213
|
-
onInsertBlock
|
|
18436
|
+
onInsertBlock,
|
|
18437
|
+
onItemInserted
|
|
18214
18438
|
}) => {
|
|
18215
18439
|
const { document: document2, selectedNodeId, dispatch, selectNode } = useEditorStore();
|
|
18216
18440
|
const [selectedCategory, setSelectedCategory] = useState32("all");
|
|
@@ -18230,6 +18454,7 @@ var BlocksPanel = ({
|
|
|
18230
18454
|
const handleInsert = (block) => {
|
|
18231
18455
|
if (onInsertBlock) {
|
|
18232
18456
|
onInsertBlock(block);
|
|
18457
|
+
onItemInserted?.();
|
|
18233
18458
|
return;
|
|
18234
18459
|
}
|
|
18235
18460
|
const existingIds = collectNodeIdSet3(document2.document);
|
|
@@ -18247,9 +18472,11 @@ var BlocksPanel = ({
|
|
|
18247
18472
|
try {
|
|
18248
18473
|
dispatch((doc) => insertNode3(doc, { parentId: targetParentId, node: nodeTree }));
|
|
18249
18474
|
selectNode(nodeTree.id);
|
|
18475
|
+
onItemInserted?.();
|
|
18250
18476
|
} catch {
|
|
18251
18477
|
dispatch((doc) => insertNode3(doc, { parentId: document2.document.id, node: nodeTree }));
|
|
18252
18478
|
selectNode(nodeTree.id);
|
|
18479
|
+
onItemInserted?.();
|
|
18253
18480
|
}
|
|
18254
18481
|
};
|
|
18255
18482
|
const setDragPayload = useEditorStore((s) => s.setDragPayload);
|
|
@@ -18323,7 +18550,8 @@ var LeftSidebar = ({
|
|
|
18323
18550
|
defaultTab: propDefaultTab,
|
|
18324
18551
|
availableTabs: propAvailableTabs,
|
|
18325
18552
|
config,
|
|
18326
|
-
className
|
|
18553
|
+
className,
|
|
18554
|
+
onItemInserted
|
|
18327
18555
|
}) => {
|
|
18328
18556
|
const tabsList = config?.availableTabs ?? propAvailableTabs ?? ["components", "blocks", "layers"];
|
|
18329
18557
|
const initialTabCandidate = config?.defaultTab ?? propDefaultTab ?? "components";
|
|
@@ -18398,8 +18626,8 @@ var LeftSidebar = ({
|
|
|
18398
18626
|
}
|
|
18399
18627
|
),
|
|
18400
18628
|
/* @__PURE__ */ jsxs41("div", { className: "flex-1 overflow-hidden min-h-0", children: [
|
|
18401
|
-
activeTab === "components" && tabsList.includes("components") && /* @__PURE__ */ jsx44("div", { role: "tabpanel", id: "tabpanel-components", "aria-labelledby": "tab-components", className: "h-full", children: /* @__PURE__ */ jsx44(ComponentPanel, { registry, config }) }),
|
|
18402
|
-
activeTab === "blocks" && tabsList.includes("blocks") && /* @__PURE__ */ jsx44("div", { role: "tabpanel", id: "tabpanel-blocks", "aria-labelledby": "tab-blocks", className: "h-full", children: /* @__PURE__ */ jsx44(BlocksPanel, { registry }) }),
|
|
18629
|
+
activeTab === "components" && tabsList.includes("components") && /* @__PURE__ */ jsx44("div", { role: "tabpanel", id: "tabpanel-components", "aria-labelledby": "tab-components", className: "h-full", children: /* @__PURE__ */ jsx44(ComponentPanel, { registry, config, onItemInserted }) }),
|
|
18630
|
+
activeTab === "blocks" && tabsList.includes("blocks") && /* @__PURE__ */ jsx44("div", { role: "tabpanel", id: "tabpanel-blocks", "aria-labelledby": "tab-blocks", className: "h-full", children: /* @__PURE__ */ jsx44(BlocksPanel, { registry, onItemInserted }) }),
|
|
18403
18631
|
activeTab === "layers" && tabsList.includes("layers") && /* @__PURE__ */ jsx44("div", { role: "tabpanel", id: "tabpanel-layers", "aria-labelledby": "tab-layers", className: "h-full", children: /* @__PURE__ */ jsx44(LayersPanel, { registry }) })
|
|
18404
18632
|
] })
|
|
18405
18633
|
] });
|
|
@@ -18417,7 +18645,7 @@ import {
|
|
|
18417
18645
|
Copy as Copy5,
|
|
18418
18646
|
Check as Check7,
|
|
18419
18647
|
ChevronRight as ChevronRight3,
|
|
18420
|
-
ChevronDown as
|
|
18648
|
+
ChevronDown as ChevronDown5,
|
|
18421
18649
|
RotateCcw as RotateCcw5,
|
|
18422
18650
|
Sliders as Sliders3,
|
|
18423
18651
|
Maximize2 as Maximize24,
|
|
@@ -18728,7 +18956,7 @@ var ActionDebuggerPanel = ({
|
|
|
18728
18956
|
] }),
|
|
18729
18957
|
/* @__PURE__ */ jsxs42("div", { className: "flex items-center gap-1.5 shrink-0", children: [
|
|
18730
18958
|
/* @__PURE__ */ jsx45("span", { className: "text-[10px] font-mono text-slate-500", children: log.timestamp.slice(11, 19) }),
|
|
18731
|
-
isExpanded ? /* @__PURE__ */ jsx45(
|
|
18959
|
+
isExpanded ? /* @__PURE__ */ jsx45(ChevronDown5, { className: "w-3 h-3 text-slate-400" }) : /* @__PURE__ */ jsx45(ChevronRight3, { className: "w-3 h-3 text-slate-400" })
|
|
18732
18960
|
] })
|
|
18733
18961
|
]
|
|
18734
18962
|
}
|
|
@@ -18771,13 +18999,17 @@ import {
|
|
|
18771
18999
|
Undo2 as Undo22,
|
|
18772
19000
|
Redo2 as Redo22,
|
|
18773
19001
|
X as X9,
|
|
18774
|
-
Boxes as Boxes2
|
|
19002
|
+
Boxes as Boxes2,
|
|
19003
|
+
ArrowUp as ArrowUp2,
|
|
19004
|
+
ArrowDown,
|
|
19005
|
+
Trash2 as Trash212
|
|
18775
19006
|
} from "lucide-react";
|
|
18776
19007
|
import { jsx as jsx46, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
18777
19008
|
var KubuildEditor = ({
|
|
18778
19009
|
initialDocument,
|
|
18779
19010
|
pages,
|
|
18780
19011
|
activePageId,
|
|
19012
|
+
selectedNodeId: propSelectedNodeId,
|
|
18781
19013
|
onActivePageChange,
|
|
18782
19014
|
onPagesChange,
|
|
18783
19015
|
registry = createDefaultComponentRegistry3(),
|
|
@@ -18789,27 +19021,29 @@ var KubuildEditor = ({
|
|
|
18789
19021
|
ai,
|
|
18790
19022
|
className
|
|
18791
19023
|
}) => {
|
|
18792
|
-
const
|
|
18793
|
-
|
|
18794
|
-
|
|
18795
|
-
|
|
18796
|
-
|
|
18797
|
-
|
|
18798
|
-
|
|
18799
|
-
|
|
18800
|
-
|
|
18801
|
-
|
|
18802
|
-
|
|
18803
|
-
|
|
18804
|
-
|
|
18805
|
-
|
|
18806
|
-
|
|
18807
|
-
|
|
18808
|
-
|
|
18809
|
-
|
|
18810
|
-
|
|
18811
|
-
|
|
18812
|
-
|
|
19024
|
+
const document2 = useEditorStore((state) => state.document);
|
|
19025
|
+
const setDocument = useEditorStore((state) => state.setDocument);
|
|
19026
|
+
const setOnChangeHandler = useEditorStore((state) => state.setOnChangeHandler);
|
|
19027
|
+
const setVariableCatalog = useEditorStore((state) => state.setVariableCatalog);
|
|
19028
|
+
const viewport = useEditorStore((state) => state.viewport);
|
|
19029
|
+
const setViewport = useEditorStore((state) => state.setViewport);
|
|
19030
|
+
const storeSelectedNodeId = useEditorStore((state) => state.selectedNodeId);
|
|
19031
|
+
const selectedNodeId = propSelectedNodeId !== void 0 ? propSelectedNodeId : storeSelectedNodeId;
|
|
19032
|
+
const tableSpreadsheetMode = useEditorStore((state) => state.tableSpreadsheetMode);
|
|
19033
|
+
const setTableSpreadsheetMode = useEditorStore((state) => state.setTableSpreadsheetMode);
|
|
19034
|
+
const aiChatMode = useEditorStore((state) => state.aiChatMode);
|
|
19035
|
+
const setAiChatMode = useEditorStore((state) => state.setAiChatMode);
|
|
19036
|
+
const undo = useEditorStore((state) => state.undo);
|
|
19037
|
+
const redo = useEditorStore((state) => state.redo);
|
|
19038
|
+
const canUndo = useEditorStore((state) => state.canUndo);
|
|
19039
|
+
const canRedo = useEditorStore((state) => state.canRedo);
|
|
19040
|
+
const previewMode = useEditorStore((state) => state.previewMode);
|
|
19041
|
+
const multiDeviceMode = useEditorStore((state) => state.multiDeviceMode);
|
|
19042
|
+
const toggleMultiDeviceMode = useEditorStore((state) => state.toggleMultiDeviceMode);
|
|
19043
|
+
const actionDebuggerOpen = useEditorStore((state) => state.actionDebuggerOpen);
|
|
19044
|
+
const moveComponentUp = useEditorStore((state) => state.moveComponentUp);
|
|
19045
|
+
const moveComponentDown = useEditorStore((state) => state.moveComponentDown);
|
|
19046
|
+
const deleteComponent = useEditorStore((state) => state.deleteComponent);
|
|
18813
19047
|
const lastLoadedDocRef = React39.useRef(void 0);
|
|
18814
19048
|
const [isMobileSidebarOpen, setIsMobileSidebarOpen] = useState35(false);
|
|
18815
19049
|
const [isMobileInspectorOpen, setIsMobileInspectorOpen] = useState35(false);
|
|
@@ -18986,7 +19220,14 @@ var KubuildEditor = ({
|
|
|
18986
19220
|
}
|
|
18987
19221
|
)
|
|
18988
19222
|
] }),
|
|
18989
|
-
/* @__PURE__ */ jsx46("div", { className: "flex-1 overflow-hidden min-h-0", children: /* @__PURE__ */ jsx46(
|
|
19223
|
+
/* @__PURE__ */ jsx46("div", { className: "flex-1 overflow-hidden min-h-0", children: /* @__PURE__ */ jsx46(
|
|
19224
|
+
LeftSidebar,
|
|
19225
|
+
{
|
|
19226
|
+
registry,
|
|
19227
|
+
config: resolvedConfig.sidebar,
|
|
19228
|
+
onItemInserted: () => setIsMobileSidebarOpen(false)
|
|
19229
|
+
}
|
|
19230
|
+
) })
|
|
18990
19231
|
] })
|
|
18991
19232
|
] }),
|
|
18992
19233
|
isMobileInspectorOpen && resolvedConfig.inspector.enabled && /* @__PURE__ */ jsxs43("div", { className: "fixed inset-0 z-50 flex justify-end lg:hidden animate-in fade-in duration-200", children: [
|
|
@@ -19129,22 +19370,61 @@ var KubuildEditor = ({
|
|
|
19129
19370
|
className: "flex-1 min-h-0"
|
|
19130
19371
|
}
|
|
19131
19372
|
),
|
|
19132
|
-
selectedNodeId && !isMobileInspectorOpen && resolvedConfig.inspector.enabled && /* @__PURE__ */
|
|
19133
|
-
"
|
|
19373
|
+
selectedNodeId && !isMobileInspectorOpen && resolvedConfig.inspector.enabled && /* @__PURE__ */ jsxs43(
|
|
19374
|
+
"div",
|
|
19134
19375
|
{
|
|
19135
|
-
|
|
19136
|
-
|
|
19137
|
-
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",
|
|
19376
|
+
"data-testid": "mobile-selected-node-actions",
|
|
19377
|
+
className: "lg:hidden fixed bottom-14 left-1/2 -translate-x-1/2 z-30 animate-in fade-in slide-in-from-bottom-2 flex items-center bg-slate-900/90 text-white rounded-full shadow-2xl backdrop-blur-md border border-slate-700/60 p-1 gap-1",
|
|
19138
19378
|
children: [
|
|
19139
|
-
/* @__PURE__ */ jsx46(
|
|
19140
|
-
|
|
19141
|
-
|
|
19142
|
-
|
|
19143
|
-
|
|
19144
|
-
|
|
19379
|
+
/* @__PURE__ */ jsx46(
|
|
19380
|
+
"button",
|
|
19381
|
+
{
|
|
19382
|
+
type: "button",
|
|
19383
|
+
onClick: () => moveComponentUp(selectedNodeId, registry),
|
|
19384
|
+
title: "Move Up",
|
|
19385
|
+
"aria-label": "Move Up",
|
|
19386
|
+
className: "p-1.5 rounded-full hover:bg-slate-800 active:bg-slate-700 text-slate-200 hover:text-white transition cursor-pointer",
|
|
19387
|
+
children: /* @__PURE__ */ jsx46(ArrowUp2, { className: "w-3.5 h-3.5" })
|
|
19388
|
+
}
|
|
19389
|
+
),
|
|
19390
|
+
/* @__PURE__ */ jsx46(
|
|
19391
|
+
"button",
|
|
19392
|
+
{
|
|
19393
|
+
type: "button",
|
|
19394
|
+
onClick: () => moveComponentDown(selectedNodeId, registry),
|
|
19395
|
+
title: "Move Down",
|
|
19396
|
+
"aria-label": "Move Down",
|
|
19397
|
+
className: "p-1.5 rounded-full hover:bg-slate-800 active:bg-slate-700 text-slate-200 hover:text-white transition cursor-pointer",
|
|
19398
|
+
children: /* @__PURE__ */ jsx46(ArrowDown, { className: "w-3.5 h-3.5" })
|
|
19399
|
+
}
|
|
19400
|
+
),
|
|
19401
|
+
/* @__PURE__ */ jsx46("div", { className: "w-px h-3.5 bg-slate-700 mx-0.5" }),
|
|
19402
|
+
/* @__PURE__ */ jsxs43(
|
|
19403
|
+
"button",
|
|
19404
|
+
{
|
|
19405
|
+
type: "button",
|
|
19406
|
+
onClick: () => setIsMobileInspectorOpen(true),
|
|
19407
|
+
className: "flex items-center gap-1.5 bg-blue-600 hover:bg-blue-500 text-white text-[11px] font-semibold px-2.5 py-1 rounded-full shadow-md active:scale-95 transition cursor-pointer",
|
|
19408
|
+
children: [
|
|
19409
|
+
/* @__PURE__ */ jsx46(Sliders4, { className: "w-3 h-3" }),
|
|
19410
|
+
/* @__PURE__ */ jsx46("span", { children: `Edit (#${selectedNodeId})` })
|
|
19411
|
+
]
|
|
19412
|
+
}
|
|
19413
|
+
),
|
|
19414
|
+
/* @__PURE__ */ jsx46(
|
|
19415
|
+
"button",
|
|
19416
|
+
{
|
|
19417
|
+
type: "button",
|
|
19418
|
+
onClick: () => deleteComponent(selectedNodeId),
|
|
19419
|
+
title: "Delete",
|
|
19420
|
+
"aria-label": "Delete",
|
|
19421
|
+
className: "p-1.5 rounded-full hover:bg-red-900/40 text-red-400 hover:text-red-300 transition active:scale-95 cursor-pointer",
|
|
19422
|
+
children: /* @__PURE__ */ jsx46(Trash212, { className: "w-3.5 h-3.5" })
|
|
19423
|
+
}
|
|
19424
|
+
)
|
|
19145
19425
|
]
|
|
19146
19426
|
}
|
|
19147
|
-
)
|
|
19427
|
+
),
|
|
19148
19428
|
resolvedConfig.canvas.showBreadcrumbs && /* @__PURE__ */ jsx46(HierarchyBreadcrumbs, { registry }),
|
|
19149
19429
|
previewMode && actionDebuggerOpen && /* @__PURE__ */ jsx46("div", { className: "fixed bottom-4 right-4 z-50 animate-in fade-in slide-in-from-bottom-3 duration-200", children: /* @__PURE__ */ jsx46(ActionDebuggerPanel, {}) })
|
|
19150
19430
|
] }),
|