system-canvas-standalone 0.2.5 → 0.2.7
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/system-canvas.js +438 -146
- package/dist/system-canvas.js.map +1 -1
- package/dist/system-canvas.min.js +8 -8
- package/dist/system-canvas.min.js.map +1 -1
- package/package.json +3 -3
package/dist/system-canvas.js
CHANGED
|
@@ -12759,12 +12759,12 @@ var SystemCanvas = (() => {
|
|
|
12759
12759
|
render: () => render,
|
|
12760
12760
|
themes: () => themes
|
|
12761
12761
|
});
|
|
12762
|
-
var
|
|
12762
|
+
var import_react27 = __toESM(require_react(), 1);
|
|
12763
12763
|
var import_client = __toESM(require_client(), 1);
|
|
12764
12764
|
|
|
12765
12765
|
// ../react/dist/components/SystemCanvas.js
|
|
12766
|
-
var
|
|
12767
|
-
var
|
|
12766
|
+
var import_jsx_runtime29 = __toESM(require_jsx_runtime(), 1);
|
|
12767
|
+
var import_react26 = __toESM(require_react(), 1);
|
|
12768
12768
|
|
|
12769
12769
|
// ../core/dist/themes/dark.js
|
|
12770
12770
|
var darkTheme = {
|
|
@@ -14565,6 +14565,136 @@ var SystemCanvas = (() => {
|
|
|
14565
14565
|
return { ...canvas, edges };
|
|
14566
14566
|
}
|
|
14567
14567
|
|
|
14568
|
+
// ../core/dist/grid.js
|
|
14569
|
+
function snapToGrid(value, size) {
|
|
14570
|
+
if (size <= 0)
|
|
14571
|
+
return value;
|
|
14572
|
+
return Math.round(value / size) * size;
|
|
14573
|
+
}
|
|
14574
|
+
|
|
14575
|
+
// ../core/dist/alignment.js
|
|
14576
|
+
function getAnchors(n) {
|
|
14577
|
+
return [
|
|
14578
|
+
{ axis: "x", value: n.x, kind: "edge", perpStart: n.y, perpEnd: n.y + n.height },
|
|
14579
|
+
{ axis: "x", value: n.x + n.width / 2, kind: "center", perpStart: n.y, perpEnd: n.y + n.height },
|
|
14580
|
+
{ axis: "x", value: n.x + n.width, kind: "edge", perpStart: n.y, perpEnd: n.y + n.height },
|
|
14581
|
+
{ axis: "y", value: n.y, kind: "edge", perpStart: n.x, perpEnd: n.x + n.width },
|
|
14582
|
+
{ axis: "y", value: n.y + n.height / 2, kind: "center", perpStart: n.x, perpEnd: n.x + n.width },
|
|
14583
|
+
{ axis: "y", value: n.y + n.height, kind: "edge", perpStart: n.x, perpEnd: n.x + n.width }
|
|
14584
|
+
];
|
|
14585
|
+
}
|
|
14586
|
+
function computeAlignmentGuides(dragging, others, threshold) {
|
|
14587
|
+
if (dragging.length === 0 || others.length === 0)
|
|
14588
|
+
return [];
|
|
14589
|
+
const map = /* @__PURE__ */ new Map();
|
|
14590
|
+
for (const d of dragging) {
|
|
14591
|
+
const dAnchors = getAnchors(d);
|
|
14592
|
+
for (const o of others) {
|
|
14593
|
+
const oAnchors = getAnchors(o);
|
|
14594
|
+
for (const da of dAnchors) {
|
|
14595
|
+
for (const oa of oAnchors) {
|
|
14596
|
+
if (da.axis !== oa.axis || da.kind !== oa.kind)
|
|
14597
|
+
continue;
|
|
14598
|
+
if (Math.abs(da.value - oa.value) > threshold)
|
|
14599
|
+
continue;
|
|
14600
|
+
const position = oa.value;
|
|
14601
|
+
const spanStart = Math.min(da.perpStart, oa.perpStart);
|
|
14602
|
+
const spanEnd = Math.max(da.perpEnd, oa.perpEnd);
|
|
14603
|
+
const key = `${da.axis}:${position}`;
|
|
14604
|
+
const existing = map.get(key);
|
|
14605
|
+
if (!existing || spanEnd - spanStart > existing.span.end - existing.span.start) {
|
|
14606
|
+
map.set(key, { axis: da.axis, position, span: { start: spanStart, end: spanEnd }, kind: da.kind });
|
|
14607
|
+
}
|
|
14608
|
+
}
|
|
14609
|
+
}
|
|
14610
|
+
}
|
|
14611
|
+
}
|
|
14612
|
+
return Array.from(map.values());
|
|
14613
|
+
}
|
|
14614
|
+
function alignNodes(nodes, direction) {
|
|
14615
|
+
if (nodes.length === 0)
|
|
14616
|
+
return [];
|
|
14617
|
+
let ref;
|
|
14618
|
+
switch (direction) {
|
|
14619
|
+
case "left":
|
|
14620
|
+
ref = Math.min(...nodes.map((n) => n.x));
|
|
14621
|
+
break;
|
|
14622
|
+
case "right":
|
|
14623
|
+
ref = Math.max(...nodes.map((n) => n.x + n.width));
|
|
14624
|
+
break;
|
|
14625
|
+
case "top":
|
|
14626
|
+
ref = Math.min(...nodes.map((n) => n.y));
|
|
14627
|
+
break;
|
|
14628
|
+
case "bottom":
|
|
14629
|
+
ref = Math.max(...nodes.map((n) => n.y + n.height));
|
|
14630
|
+
break;
|
|
14631
|
+
case "centerH":
|
|
14632
|
+
ref = nodes.reduce((s, n) => s + (n.x + n.width / 2), 0) / nodes.length;
|
|
14633
|
+
break;
|
|
14634
|
+
case "centerV":
|
|
14635
|
+
ref = nodes.reduce((s, n) => s + (n.y + n.height / 2), 0) / nodes.length;
|
|
14636
|
+
break;
|
|
14637
|
+
}
|
|
14638
|
+
const result = [];
|
|
14639
|
+
for (const n of nodes) {
|
|
14640
|
+
let newX;
|
|
14641
|
+
let newY;
|
|
14642
|
+
switch (direction) {
|
|
14643
|
+
case "left":
|
|
14644
|
+
newX = ref;
|
|
14645
|
+
break;
|
|
14646
|
+
case "right":
|
|
14647
|
+
newX = ref - n.width;
|
|
14648
|
+
break;
|
|
14649
|
+
case "top":
|
|
14650
|
+
newY = ref;
|
|
14651
|
+
break;
|
|
14652
|
+
case "bottom":
|
|
14653
|
+
newY = ref - n.height;
|
|
14654
|
+
break;
|
|
14655
|
+
case "centerH":
|
|
14656
|
+
newX = ref - n.width / 2;
|
|
14657
|
+
break;
|
|
14658
|
+
case "centerV":
|
|
14659
|
+
newY = ref - n.height / 2;
|
|
14660
|
+
break;
|
|
14661
|
+
}
|
|
14662
|
+
const patch = {};
|
|
14663
|
+
if (newX !== void 0 && newX !== n.x)
|
|
14664
|
+
patch.x = newX;
|
|
14665
|
+
if (newY !== void 0 && newY !== n.y)
|
|
14666
|
+
patch.y = newY;
|
|
14667
|
+
if (Object.keys(patch).length > 0)
|
|
14668
|
+
result.push({ id: n.id, patch });
|
|
14669
|
+
}
|
|
14670
|
+
return result;
|
|
14671
|
+
}
|
|
14672
|
+
function distributeNodes(nodes, axis) {
|
|
14673
|
+
if (nodes.length < 3)
|
|
14674
|
+
return [];
|
|
14675
|
+
const isH = axis === "horizontal";
|
|
14676
|
+
const sorted = [...nodes].sort((a, b) => isH ? a.x - b.x : a.y - b.y);
|
|
14677
|
+
const first = sorted[0];
|
|
14678
|
+
const last = sorted[sorted.length - 1];
|
|
14679
|
+
const outerStart = isH ? first.x : first.y;
|
|
14680
|
+
const outerEnd = isH ? last.x + last.width : last.y + last.height;
|
|
14681
|
+
const sumInnerSizes = sorted.slice(1, -1).reduce((s, n) => s + (isH ? n.width : n.height), 0);
|
|
14682
|
+
const totalOuterSize = isH ? first.width + last.width : first.height + last.height;
|
|
14683
|
+
const spacing = (outerEnd - outerStart - totalOuterSize - sumInnerSizes) / (sorted.length - 1);
|
|
14684
|
+
const result = [];
|
|
14685
|
+
let cursor = outerStart + (isH ? first.width : first.height) + spacing;
|
|
14686
|
+
for (let i = 1; i < sorted.length - 1; i++) {
|
|
14687
|
+
const n = sorted[i];
|
|
14688
|
+
const newVal = cursor;
|
|
14689
|
+
const oldVal = isH ? n.x : n.y;
|
|
14690
|
+
if (newVal !== oldVal) {
|
|
14691
|
+
result.push({ id: n.id, patch: isH ? { x: newVal } : { y: newVal } });
|
|
14692
|
+
}
|
|
14693
|
+
cursor += (isH ? n.width : n.height) + spacing;
|
|
14694
|
+
}
|
|
14695
|
+
return result;
|
|
14696
|
+
}
|
|
14697
|
+
|
|
14568
14698
|
// ../core/dist/index.js
|
|
14569
14699
|
var themes = {
|
|
14570
14700
|
dark: darkTheme,
|
|
@@ -14973,7 +15103,7 @@ var SystemCanvas = (() => {
|
|
|
14973
15103
|
var import_react4 = __toESM(require_react(), 1);
|
|
14974
15104
|
var DRAG_THRESHOLD = 3;
|
|
14975
15105
|
function useNodeDrag(options) {
|
|
14976
|
-
const { viewport, nodesRef, onCommit, svgRef, canDropNodeOn, onNodeDrop, selectedIdsRef } = options;
|
|
15106
|
+
const { viewport, nodesRef, onCommit, svgRef, canDropNodeOn, onNodeDrop, selectedIdsRef, snapGridSize = 0 } = options;
|
|
14977
15107
|
const [dragOverrides, setDragOverrides] = (0, import_react4.useState)(() => /* @__PURE__ */ new Map());
|
|
14978
15108
|
const [isDragging, setIsDragging] = (0, import_react4.useState)(false);
|
|
14979
15109
|
const [dropTargetId, setDropTargetId] = (0, import_react4.useState)(null);
|
|
@@ -15030,7 +15160,9 @@ var SystemCanvas = (() => {
|
|
|
15030
15160
|
const dy = dyScreen / zoom;
|
|
15031
15161
|
const next = /* @__PURE__ */ new Map();
|
|
15032
15162
|
for (const [id2, start2] of st.moving) {
|
|
15033
|
-
|
|
15163
|
+
const sx = snapGridSize > 0 ? snapToGrid(start2.startX + dx, snapGridSize) : start2.startX + dx;
|
|
15164
|
+
const sy = snapGridSize > 0 ? snapToGrid(start2.startY + dy, snapGridSize) : start2.startY + dy;
|
|
15165
|
+
next.set(id2, { x: sx, y: sy });
|
|
15034
15166
|
}
|
|
15035
15167
|
setDragOverrides(next);
|
|
15036
15168
|
const nextTarget = computeDropTarget(event.clientX, event.clientY);
|
|
@@ -15157,7 +15289,7 @@ var SystemCanvas = (() => {
|
|
|
15157
15289
|
var import_react5 = __toESM(require_react(), 1);
|
|
15158
15290
|
var DEFAULT_MIN_SIZE = 40;
|
|
15159
15291
|
function useNodeResize(options) {
|
|
15160
|
-
const { viewport, onCommit, minSize = DEFAULT_MIN_SIZE } = options;
|
|
15292
|
+
const { viewport, onCommit, minSize = DEFAULT_MIN_SIZE, snapGridSize = 0 } = options;
|
|
15161
15293
|
const [resizeOverrides, setResizeOverrides] = (0, import_react5.useState)(() => /* @__PURE__ */ new Map());
|
|
15162
15294
|
const [isResizing, setIsResizing] = (0, import_react5.useState)(false);
|
|
15163
15295
|
const stateRef = (0, import_react5.useRef)(null);
|
|
@@ -15205,6 +15337,14 @@ var SystemCanvas = (() => {
|
|
|
15205
15337
|
}
|
|
15206
15338
|
nh = minSize;
|
|
15207
15339
|
}
|
|
15340
|
+
if (snapGridSize > 0) {
|
|
15341
|
+
nw = Math.max(minSize, snapToGrid(nw, snapGridSize));
|
|
15342
|
+
nh = Math.max(minSize, snapToGrid(nh, snapGridSize));
|
|
15343
|
+
if (st.corner === "sw" || st.corner === "nw")
|
|
15344
|
+
nx = st.startX + st.startW - nw;
|
|
15345
|
+
if (st.corner === "ne" || st.corner === "nw")
|
|
15346
|
+
ny = st.startY + st.startH - nh;
|
|
15347
|
+
}
|
|
15208
15348
|
const next = new Map(overridesRef.current);
|
|
15209
15349
|
next.set(st.nodeId, { x: nx, y: ny, width: nw, height: nh });
|
|
15210
15350
|
setResizeOverrides(next);
|
|
@@ -16196,7 +16336,7 @@ var SystemCanvas = (() => {
|
|
|
16196
16336
|
}
|
|
16197
16337
|
|
|
16198
16338
|
// ../react/dist/components/Viewport.js
|
|
16199
|
-
var
|
|
16339
|
+
var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1);
|
|
16200
16340
|
var import_react19 = __toESM(require_react(), 1);
|
|
16201
16341
|
|
|
16202
16342
|
// ../react/dist/hooks/useViewport.js
|
|
@@ -20276,10 +20416,18 @@ var SystemCanvas = (() => {
|
|
|
20276
20416
|
})] });
|
|
20277
20417
|
}
|
|
20278
20418
|
|
|
20419
|
+
// ../react/dist/components/AlignmentGuidesLayer.js
|
|
20420
|
+
var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1);
|
|
20421
|
+
function AlignmentGuidesLayer({ guides }) {
|
|
20422
|
+
if (guides.length === 0)
|
|
20423
|
+
return null;
|
|
20424
|
+
return (0, import_jsx_runtime22.jsx)(import_jsx_runtime22.Fragment, { children: guides.map((g, i) => (0, import_jsx_runtime22.jsx)("line", { x1: g.axis === "x" ? g.position : g.span.start, y1: g.axis === "y" ? g.position : g.span.start, x2: g.axis === "x" ? g.position : g.span.end, y2: g.axis === "y" ? g.position : g.span.end, stroke: "#38BDF8", strokeWidth: 1, strokeDasharray: "4 3", pointerEvents: "none" }, i)) });
|
|
20425
|
+
}
|
|
20426
|
+
|
|
20279
20427
|
// ../react/dist/components/Viewport.js
|
|
20280
20428
|
var HOVER_PADDING = 10;
|
|
20281
20429
|
var EDGE_PROXIMITY = 16;
|
|
20282
|
-
var Viewport = (0, import_react19.forwardRef)(function Viewport2({ nodes, edges, nodeMap, theme, edgeStyle, columns, rows, canvases, minZoom, maxZoom, defaultViewport, onViewportChange, onNodeClick, onNodeDoubleClick, onNodeNavigate, onEdgeClick, onEdgeDoubleClick, onCanvasClick, onCanvasContextMenu, onNodeContextMenu, onEdgeContextMenu, onNodePointerDown, selectedIds, editingId, selectedEdgeId, editingEdgeId, dragOverrides, dropTargetId, marqueeRect, marqueeActiveRef, resizeOverrides, onResizeHandlePointerDown, onEditorCommit, onEditorCancel, onEdgeEditorCommit, onEdgeEditorCancel, pendingEdge, onConnectionHandlePointerDown, edgeCreateEnabled, autoFit = "canvas-change", canvasRef, handoffTransform, onHandoffApplied, handoffFadeMs = 0 }, ref) {
|
|
20430
|
+
var Viewport = (0, import_react19.forwardRef)(function Viewport2({ nodes, edges, nodeMap, theme, edgeStyle, columns, rows, canvases, minZoom, maxZoom, defaultViewport, onViewportChange, onNodeClick, onNodeDoubleClick, onNodeNavigate, onEdgeClick, onEdgeDoubleClick, onCanvasClick, onCanvasContextMenu, onNodeContextMenu, onEdgeContextMenu, onNodePointerDown, selectedIds, editingId, selectedEdgeId, editingEdgeId, dragOverrides, dropTargetId, marqueeRect, marqueeActiveRef, resizeOverrides, onResizeHandlePointerDown, onEditorCommit, onEditorCancel, onEdgeEditorCommit, onEdgeEditorCancel, pendingEdge, onConnectionHandlePointerDown, edgeCreateEnabled, alignmentGuides, autoFit = "canvas-change", canvasRef, handoffTransform, onHandoffApplied, handoffFadeMs = 0 }, ref) {
|
|
20283
20431
|
const { svgRef, groupRef, viewport, fitToContent, zoomToNode, setTransform } = useViewport({
|
|
20284
20432
|
minZoom,
|
|
20285
20433
|
maxZoom,
|
|
@@ -20487,7 +20635,7 @@ var SystemCanvas = (() => {
|
|
|
20487
20635
|
return null;
|
|
20488
20636
|
return computeEdgeMidpoint(editingEdge, from, to);
|
|
20489
20637
|
})();
|
|
20490
|
-
return (0,
|
|
20638
|
+
return (0, import_jsx_runtime23.jsxs)("svg", { ref: svgRef, className: "system-canvas-viewport", style: {
|
|
20491
20639
|
width: "100%",
|
|
20492
20640
|
height: "100%",
|
|
20493
20641
|
display: "block",
|
|
@@ -20496,21 +20644,21 @@ var SystemCanvas = (() => {
|
|
|
20496
20644
|
WebkitUserSelect: "none",
|
|
20497
20645
|
MozUserSelect: "none",
|
|
20498
20646
|
msUserSelect: "none"
|
|
20499
|
-
}, onClick: onCanvasClick, onContextMenu: onCanvasContextMenu, onPointerMove: handleSvgPointerMove, onPointerLeave: handleSvgPointerLeave, children: [(0,
|
|
20647
|
+
}, onClick: onCanvasClick, onContextMenu: onCanvasContextMenu, onPointerMove: handleSvgPointerMove, onPointerLeave: handleSvgPointerLeave, children: [(0, import_jsx_runtime23.jsx)("defs", { children: (0, import_jsx_runtime23.jsx)("pattern", { id: "system-canvas-grid", width: theme.grid.size, height: theme.grid.size, patternUnits: "userSpaceOnUse", children: (0, import_jsx_runtime23.jsx)("path", { d: `M ${theme.grid.size} 0 L 0 0 0 ${theme.grid.size}`, fill: "none", stroke: theme.grid.color, strokeWidth: theme.grid.strokeWidth }) }) }), (0, import_jsx_runtime23.jsx)("rect", { x: "-50000", y: "-50000", width: "100000", height: "100000", fill: "url(#system-canvas-grid)" }), (0, import_jsx_runtime23.jsxs)("g", { ref: groupRef, children: [(0, import_jsx_runtime23.jsx)(LanesBackground, { columns, rows, theme }), (0, import_jsx_runtime23.jsx)(NodeRenderer, { nodes: renderNodes, theme, onClick: onNodeClick, onDoubleClick: onNodeDoubleClick, onContextMenu: onNodeContextMenu, onNavigate: onNodeNavigate, onPointerDown: onNodePointerDown, selectedIds, editingId, canvases, only: "groups" }), (0, import_jsx_runtime23.jsx)(EdgeRenderer, { edges, nodeMap: renderNodeMap, theme, defaultEdgeStyle: edgeStyle, onClick: onEdgeClick, onDoubleClick: onEdgeDoubleClick, onContextMenu: onEdgeContextMenu, selectedId: selectedEdgeId, editingId: editingEdgeId }), (0, import_jsx_runtime23.jsx)(NodeRenderer, { nodes: renderNodes, theme, onClick: onNodeClick, onDoubleClick: onNodeDoubleClick, onContextMenu: onNodeContextMenu, onNavigate: onNodeNavigate, onPointerDown: onNodePointerDown, selectedIds, editingId, onResizeHandlePointerDown, canvases, only: "non-groups" }), pendingTargetNode && (0, import_jsx_runtime23.jsx)("rect", { className: "system-canvas-drop-target", x: pendingTargetNode.x - 4, y: pendingTargetNode.y - 4, width: pendingTargetNode.width + 8, height: pendingTargetNode.height + 8, rx: pendingTargetNode.resolvedCornerRadius + 4, fill: "none", stroke: theme.node.labelColor, strokeWidth: 2, opacity: 0.85, pointerEvents: "none" }), dropTargetNode && (0, import_jsx_runtime23.jsx)("rect", { className: "system-canvas-drop-target system-canvas-node-drop-target", x: dropTargetNode.x - 4, y: dropTargetNode.y - 4, width: dropTargetNode.width + 8, height: dropTargetNode.height + 8, rx: dropTargetNode.resolvedCornerRadius + 4, fill: "none", stroke: theme.node.labelColor, strokeWidth: 2, strokeDasharray: "6 4", opacity: 0.9, pointerEvents: "none" }), selectedIds && selectedIds.size > 0 && Array.from(selectedIds).map((id2) => {
|
|
20500
20648
|
const node = renderNodeMap.get(id2);
|
|
20501
20649
|
if (!node)
|
|
20502
20650
|
return null;
|
|
20503
|
-
return (0,
|
|
20504
|
-
}), pendingEdge && pendingSourceNode && (0,
|
|
20651
|
+
return (0, import_jsx_runtime23.jsx)("rect", { x: node.x - 3, y: node.y - 3, width: node.width + 6, height: node.height + 6, rx: (node.resolvedCornerRadius ?? 0) + 3, fill: "none", stroke: theme.node.labelColor, strokeWidth: 1.5, opacity: 0.7, pointerEvents: "none" }, `halo-${id2}`);
|
|
20652
|
+
}), pendingEdge && pendingSourceNode && (0, import_jsx_runtime23.jsx)(PendingEdgeRenderer, { sourceNode: pendingSourceNode, sourceSide: pendingEdge.sourceSide, cursor: pendingEdge.cursor, targetNode: pendingTargetNode, theme, defaultEdgeStyle: edgeStyle }), handlesNode && onConnectionHandlePointerDown && (0, import_jsx_runtime23.jsx)(ConnectionHandles, { node: handlesNode, theme, onHandlePointerDown: onConnectionHandlePointerDown, immediate: !!pendingEdge, activeSide: hoveredSide }), alignmentGuides && alignmentGuides.length > 0 && (0, import_jsx_runtime23.jsx)(AlignmentGuidesLayer, { guides: alignmentGuides }), editingNode && onEditorCommit && onEditorCancel && (0, import_jsx_runtime23.jsx)(NodeEditor, { node: editingNode, theme, onCommit: onEditorCommit, onCancel: onEditorCancel }), editingEdge && editingEdgeMidpoint && onEdgeEditorCommit && onEdgeEditorCancel && (0, import_jsx_runtime23.jsx)(EdgeLabelEditor, { initialLabel: editingEdge.label ?? "", midpoint: editingEdgeMidpoint, theme, onCommit: onEdgeEditorCommit, onCancel: onEdgeEditorCancel })] }), marqueeRect && (0, import_jsx_runtime23.jsx)("rect", { x: Math.min(marqueeRect.x1, marqueeRect.x2), y: Math.min(marqueeRect.y1, marqueeRect.y2), width: Math.abs(marqueeRect.x2 - marqueeRect.x1), height: Math.abs(marqueeRect.y2 - marqueeRect.y1), fill: theme.node.labelColor + "18", stroke: theme.node.labelColor, strokeWidth: 1, opacity: 0.9, pointerEvents: "none" })] });
|
|
20505
20653
|
});
|
|
20506
20654
|
|
|
20507
20655
|
// ../react/dist/components/Breadcrumbs.js
|
|
20508
|
-
var
|
|
20656
|
+
var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1);
|
|
20509
20657
|
var import_react20 = __toESM(require_react(), 1);
|
|
20510
20658
|
function Breadcrumbs({ breadcrumbs, theme, onNavigate }) {
|
|
20511
20659
|
if (breadcrumbs.length <= 1)
|
|
20512
20660
|
return null;
|
|
20513
|
-
return (0,
|
|
20661
|
+
return (0, import_jsx_runtime24.jsx)("div", { className: "system-canvas-breadcrumbs", style: {
|
|
20514
20662
|
position: "absolute",
|
|
20515
20663
|
top: 12,
|
|
20516
20664
|
left: 12,
|
|
@@ -20527,10 +20675,10 @@ var SystemCanvas = (() => {
|
|
|
20527
20675
|
backdropFilter: "blur(8px)"
|
|
20528
20676
|
}, children: breadcrumbs.map((crumb, index) => {
|
|
20529
20677
|
const isLast = index === breadcrumbs.length - 1;
|
|
20530
|
-
return (0,
|
|
20678
|
+
return (0, import_jsx_runtime24.jsxs)(import_react20.default.Fragment, { children: [index > 0 && (0, import_jsx_runtime24.jsx)("span", { style: {
|
|
20531
20679
|
color: theme.separatorColor,
|
|
20532
20680
|
margin: "0 2px"
|
|
20533
|
-
}, children: "/" }), (0,
|
|
20681
|
+
}, children: "/" }), (0, import_jsx_runtime24.jsx)("span", { onClick: isLast ? void 0 : () => onNavigate(index), style: {
|
|
20534
20682
|
color: isLast ? theme.activeColor : theme.textColor,
|
|
20535
20683
|
cursor: isLast ? "default" : "pointer",
|
|
20536
20684
|
fontWeight: isLast ? 600 : 400,
|
|
@@ -20550,7 +20698,7 @@ var SystemCanvas = (() => {
|
|
|
20550
20698
|
}
|
|
20551
20699
|
|
|
20552
20700
|
// ../react/dist/components/AddNodeButton.js
|
|
20553
|
-
var
|
|
20701
|
+
var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1);
|
|
20554
20702
|
var import_react21 = __toESM(require_react(), 1);
|
|
20555
20703
|
function AddNodeButton({ options, addNode: addNode2, theme }) {
|
|
20556
20704
|
const [open, setOpen] = (0, import_react21.useState)(false);
|
|
@@ -20578,7 +20726,7 @@ var SystemCanvas = (() => {
|
|
|
20578
20726
|
}, [open]);
|
|
20579
20727
|
const categoryOptions = options.filter((o) => o.kind === "category");
|
|
20580
20728
|
const typeOptions = options.filter((o) => o.kind === "type");
|
|
20581
|
-
return (0,
|
|
20729
|
+
return (0, import_jsx_runtime25.jsxs)("div", { ref: rootRef, className: "system-canvas-add-node", style: {
|
|
20582
20730
|
position: "absolute",
|
|
20583
20731
|
bottom: 16,
|
|
20584
20732
|
right: 16,
|
|
@@ -20586,7 +20734,7 @@ var SystemCanvas = (() => {
|
|
|
20586
20734
|
fontFamily: theme.breadcrumbs.fontFamily,
|
|
20587
20735
|
fontSize: theme.breadcrumbs.fontSize,
|
|
20588
20736
|
userSelect: "none"
|
|
20589
|
-
}, children: [open && (0,
|
|
20737
|
+
}, children: [open && (0, import_jsx_runtime25.jsxs)("div", { style: {
|
|
20590
20738
|
position: "absolute",
|
|
20591
20739
|
bottom: 52,
|
|
20592
20740
|
right: 0,
|
|
@@ -20599,13 +20747,13 @@ var SystemCanvas = (() => {
|
|
|
20599
20747
|
borderRadius: 10,
|
|
20600
20748
|
boxShadow: "0 8px 24px rgba(0,0,0,0.35)",
|
|
20601
20749
|
backdropFilter: "blur(10px)"
|
|
20602
|
-
}, children: [categoryOptions.length > 0 && (0,
|
|
20750
|
+
}, children: [categoryOptions.length > 0 && (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [(0, import_jsx_runtime25.jsx)(SectionLabel, { theme, children: "Categories" }), categoryOptions.map((opt) => (0, import_jsx_runtime25.jsx)(MenuRow, { theme, option: opt, onClick: () => {
|
|
20603
20751
|
addNode2(opt);
|
|
20604
20752
|
setOpen(false);
|
|
20605
|
-
} }, `cat-${opt.value}`)), (0,
|
|
20753
|
+
} }, `cat-${opt.value}`)), (0, import_jsx_runtime25.jsx)(Divider, { theme })] }), (0, import_jsx_runtime25.jsx)(SectionLabel, { theme, children: "Basic" }), typeOptions.map((opt) => (0, import_jsx_runtime25.jsx)(MenuRow, { theme, option: opt, onClick: () => {
|
|
20606
20754
|
addNode2(opt);
|
|
20607
20755
|
setOpen(false);
|
|
20608
|
-
} }, `type-${opt.value}`))] }), (0,
|
|
20756
|
+
} }, `type-${opt.value}`))] }), (0, import_jsx_runtime25.jsx)("button", { type: "button", "aria-label": open ? "Close add node menu" : "Add node", onClick: () => setOpen((v) => !v), style: {
|
|
20609
20757
|
width: 44,
|
|
20610
20758
|
height: 44,
|
|
20611
20759
|
borderRadius: 22,
|
|
@@ -20626,7 +20774,7 @@ var SystemCanvas = (() => {
|
|
|
20626
20774
|
}, children: "+" })] });
|
|
20627
20775
|
}
|
|
20628
20776
|
function SectionLabel({ theme, children: children2 }) {
|
|
20629
|
-
return (0,
|
|
20777
|
+
return (0, import_jsx_runtime25.jsx)("div", { style: {
|
|
20630
20778
|
padding: "4px 8px",
|
|
20631
20779
|
fontSize: theme.breadcrumbs.fontSize - 2,
|
|
20632
20780
|
color: theme.breadcrumbs.textColor,
|
|
@@ -20636,7 +20784,7 @@ var SystemCanvas = (() => {
|
|
|
20636
20784
|
}, children: children2 });
|
|
20637
20785
|
}
|
|
20638
20786
|
function Divider({ theme }) {
|
|
20639
|
-
return (0,
|
|
20787
|
+
return (0, import_jsx_runtime25.jsx)("div", { style: {
|
|
20640
20788
|
height: 1,
|
|
20641
20789
|
margin: "4px 0",
|
|
20642
20790
|
background: theme.breadcrumbs.separatorColor,
|
|
@@ -20646,7 +20794,7 @@ var SystemCanvas = (() => {
|
|
|
20646
20794
|
function MenuRow({ theme, option, onClick }) {
|
|
20647
20795
|
const [hover, setHover] = (0, import_react21.useState)(false);
|
|
20648
20796
|
const swatchSize = 18;
|
|
20649
|
-
return (0,
|
|
20797
|
+
return (0, import_jsx_runtime25.jsxs)("div", { role: "button", onClick, onMouseEnter: () => setHover(true), onMouseLeave: () => setHover(false), style: {
|
|
20650
20798
|
display: "flex",
|
|
20651
20799
|
alignItems: "center",
|
|
20652
20800
|
gap: 8,
|
|
@@ -20655,7 +20803,7 @@ var SystemCanvas = (() => {
|
|
|
20655
20803
|
cursor: "pointer",
|
|
20656
20804
|
background: hover ? "rgba(255,255,255,0.06)" : "transparent",
|
|
20657
20805
|
color: theme.breadcrumbs.activeColor
|
|
20658
|
-
}, children: [option.kind === "category" ? (0,
|
|
20806
|
+
}, children: [option.kind === "category" ? (0, import_jsx_runtime25.jsx)("span", { style: {
|
|
20659
20807
|
width: swatchSize,
|
|
20660
20808
|
height: swatchSize,
|
|
20661
20809
|
borderRadius: 4,
|
|
@@ -20665,13 +20813,13 @@ var SystemCanvas = (() => {
|
|
|
20665
20813
|
alignItems: "center",
|
|
20666
20814
|
justifyContent: "center",
|
|
20667
20815
|
flexShrink: 0
|
|
20668
|
-
}, children: option.icon && (0,
|
|
20816
|
+
}, children: option.icon && (0, import_jsx_runtime25.jsx)("svg", { width: 12, height: 12, viewBox: "0 0 14 14", style: { overflow: "visible" }, children: (0, import_jsx_runtime25.jsx)("g", { transform: "translate(-1, -1)", children: (0, import_jsx_runtime25.jsx)(NodeIcon, { icon: option.icon, x: 0, y: 0, size: 14, color: option.stroke ?? theme.breadcrumbs.activeColor, opacity: 0.9, customIcons: theme.icons }) }) }) }) : (0, import_jsx_runtime25.jsx)("span", { style: {
|
|
20669
20817
|
width: swatchSize,
|
|
20670
20818
|
height: swatchSize,
|
|
20671
20819
|
borderRadius: 4,
|
|
20672
20820
|
border: `1px dashed ${theme.breadcrumbs.separatorColor}`,
|
|
20673
20821
|
flexShrink: 0
|
|
20674
|
-
} }), (0,
|
|
20822
|
+
} }), (0, import_jsx_runtime25.jsx)("span", { style: { textTransform: "capitalize" }, children: option.label }), (0, import_jsx_runtime25.jsx)("span", { style: {
|
|
20675
20823
|
marginLeft: "auto",
|
|
20676
20824
|
fontSize: theme.breadcrumbs.fontSize - 2,
|
|
20677
20825
|
opacity: 0.5
|
|
@@ -20679,7 +20827,7 @@ var SystemCanvas = (() => {
|
|
|
20679
20827
|
}
|
|
20680
20828
|
|
|
20681
20829
|
// ../react/dist/components/LaneHeaders.js
|
|
20682
|
-
var
|
|
20830
|
+
var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1);
|
|
20683
20831
|
var import_react22 = __toESM(require_react(), 1);
|
|
20684
20832
|
function LaneHeaders({ columns, rows, theme, getViewport, width, height, pinned = true }) {
|
|
20685
20833
|
const hasColumns = columns && columns.length > 0;
|
|
@@ -20712,14 +20860,14 @@ var SystemCanvas = (() => {
|
|
|
20712
20860
|
const pad = lanesTheme.headerPadding;
|
|
20713
20861
|
const colsOffsetLeft = hasRows && pinned ? headerSize : 0;
|
|
20714
20862
|
const rowsOffsetTop = hasColumns && pinned ? headerSize : 0;
|
|
20715
|
-
return (0,
|
|
20863
|
+
return (0, import_jsx_runtime26.jsxs)("svg", { className: "system-canvas-lane-headers", style: {
|
|
20716
20864
|
position: "absolute",
|
|
20717
20865
|
top: 0,
|
|
20718
20866
|
left: 0,
|
|
20719
20867
|
width,
|
|
20720
20868
|
height,
|
|
20721
20869
|
pointerEvents: "none"
|
|
20722
|
-
}, children: [hasColumns && (0,
|
|
20870
|
+
}, children: [hasColumns && (0, import_jsx_runtime26.jsxs)("g", { children: [pinned && (0, import_jsx_runtime26.jsx)("rect", { x: colsOffsetLeft, y: 0, width: width - colsOffsetLeft, height: headerSize, fill: lanesTheme.headerBackground }), columns.map((col) => {
|
|
20723
20871
|
const startScreen = canvasToScreen(col.start, 0, viewport).x;
|
|
20724
20872
|
const endScreen = canvasToScreen(col.start + col.size, 0, viewport).x;
|
|
20725
20873
|
const w = endScreen - startScreen;
|
|
@@ -20730,8 +20878,8 @@ var SystemCanvas = (() => {
|
|
|
20730
20878
|
const cx = visibleLeft + visibleW / 2;
|
|
20731
20879
|
if (endScreen <= colsOffsetLeft || startScreen >= width)
|
|
20732
20880
|
return null;
|
|
20733
|
-
return (0,
|
|
20734
|
-
}), pinned && (0,
|
|
20881
|
+
return (0, import_jsx_runtime26.jsxs)("g", { children: [(0, import_jsx_runtime26.jsx)("line", { x1: startScreen, y1: pinned ? headerSize : y + headerSize, x2: startScreen, y2: pinned ? 0 : y, stroke: lanesTheme.dividerColor, strokeWidth: lanesTheme.dividerWidth }), (0, import_jsx_runtime26.jsx)("text", { x: cx, y: (pinned ? 0 : y) + headerSize / 2, textAnchor: "middle", dominantBaseline: "middle", fill: lanesTheme.headerTextColor, fontFamily: lanesTheme.headerFontFamily, fontSize: lanesTheme.headerFontSize, style: { userSelect: "none" }, children: truncateToWidth2(col.label, visibleW - pad * 2, lanesTheme.headerFontSize) })] }, `colh-${col.id}`);
|
|
20882
|
+
}), pinned && (0, import_jsx_runtime26.jsx)("line", { x1: colsOffsetLeft, y1: headerSize, x2: width, y2: headerSize, stroke: lanesTheme.dividerColor, strokeWidth: lanesTheme.dividerWidth })] }), hasRows && (0, import_jsx_runtime26.jsxs)("g", { children: [pinned && (0, import_jsx_runtime26.jsx)("rect", { x: 0, y: rowsOffsetTop, width: headerSize, height: height - rowsOffsetTop, fill: lanesTheme.headerBackground }), rows.map((row) => {
|
|
20735
20883
|
const startScreen = canvasToScreen(0, row.start, viewport).y;
|
|
20736
20884
|
const endScreen = canvasToScreen(0, row.start + row.size, viewport).y;
|
|
20737
20885
|
const h = endScreen - startScreen;
|
|
@@ -20742,8 +20890,8 @@ var SystemCanvas = (() => {
|
|
|
20742
20890
|
const cy = visibleTop + visibleH / 2;
|
|
20743
20891
|
if (endScreen <= rowsOffsetTop || startScreen >= height)
|
|
20744
20892
|
return null;
|
|
20745
|
-
return (0,
|
|
20746
|
-
}), pinned && (0,
|
|
20893
|
+
return (0, import_jsx_runtime26.jsxs)("g", { children: [(0, import_jsx_runtime26.jsx)("line", { x1: pinned ? 0 : x, y1: startScreen, x2: pinned ? headerSize : x + headerSize, y2: startScreen, stroke: lanesTheme.dividerColor, strokeWidth: lanesTheme.dividerWidth }), (0, import_jsx_runtime26.jsx)("text", { x: (pinned ? 0 : x) + headerSize / 2, y: cy, textAnchor: "middle", dominantBaseline: "middle", fill: lanesTheme.headerTextColor, fontFamily: lanesTheme.headerFontFamily, fontSize: lanesTheme.headerFontSize, transform: `rotate(-90 ${(pinned ? 0 : x) + headerSize / 2} ${cy})`, style: { userSelect: "none" }, children: truncateToWidth2(row.label, visibleH - pad * 2, lanesTheme.headerFontSize) })] }, `rowh-${row.id}`);
|
|
20894
|
+
}), pinned && (0, import_jsx_runtime26.jsx)("line", { x1: headerSize, y1: rowsOffsetTop, x2: headerSize, y2: height, stroke: lanesTheme.dividerColor, strokeWidth: lanesTheme.dividerWidth })] }), hasColumns && hasRows && pinned && (0, import_jsx_runtime26.jsx)("rect", { x: 0, y: 0, width: headerSize, height: headerSize, fill: lanesTheme.headerBackground })] });
|
|
20747
20895
|
}
|
|
20748
20896
|
function truncateToWidth2(label, availablePx, fontSize) {
|
|
20749
20897
|
if (availablePx <= 0)
|
|
@@ -20758,7 +20906,7 @@ var SystemCanvas = (() => {
|
|
|
20758
20906
|
}
|
|
20759
20907
|
|
|
20760
20908
|
// ../react/dist/components/NodeToolbar.js
|
|
20761
|
-
var
|
|
20909
|
+
var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
|
|
20762
20910
|
var import_react23 = __toESM(require_react(), 1);
|
|
20763
20911
|
var NODE_GAP = 10;
|
|
20764
20912
|
var FLIP_MARGIN = 8;
|
|
@@ -20767,7 +20915,7 @@ var SystemCanvas = (() => {
|
|
|
20767
20915
|
var SWATCH_SIZE = 16;
|
|
20768
20916
|
var BUTTON_SIZE = 28;
|
|
20769
20917
|
var DELETE_SIZE = 14;
|
|
20770
|
-
function NodeToolbar({ node, theme, onPatch, onDelete, getViewport, containerWidth, containerHeight, render: render2, selectedNodes, onMultiPatch }) {
|
|
20918
|
+
function NodeToolbar({ node, theme, onPatch, onDelete, getViewport, containerWidth, containerHeight, render: render2, selectedNodes, onMultiPatch, onAlign, onDistribute }) {
|
|
20771
20919
|
const [viewport, setViewport] = (0, import_react23.useState)(() => getViewport());
|
|
20772
20920
|
(0, import_react23.useEffect)(() => {
|
|
20773
20921
|
let raf = 0;
|
|
@@ -20834,7 +20982,7 @@ var SystemCanvas = (() => {
|
|
|
20834
20982
|
left = Math.max(FLIP_MARGIN, Math.min(left, containerWidth - size.width - FLIP_MARGIN));
|
|
20835
20983
|
const patch = (update) => onPatch(update);
|
|
20836
20984
|
const deleteNode = () => onDelete();
|
|
20837
|
-
return (0,
|
|
20985
|
+
return (0, import_jsx_runtime27.jsx)("div", {
|
|
20838
20986
|
ref: toolbarRef,
|
|
20839
20987
|
className: "system-canvas-node-toolbar",
|
|
20840
20988
|
// Stop pointer events from bubbling to the canvas (which would
|
|
@@ -20863,16 +21011,16 @@ var SystemCanvas = (() => {
|
|
|
20863
21011
|
userSelect: "none",
|
|
20864
21012
|
whiteSpace: "nowrap"
|
|
20865
21013
|
},
|
|
20866
|
-
children: isMulti && selectedNodes && onMultiPatch ? (0,
|
|
21014
|
+
children: isMulti && selectedNodes && onMultiPatch ? (0, import_jsx_runtime27.jsx)(MultiToolbarContent, { selectedNodes, theme, onMultiPatch, onDelete: deleteNode, onAlign, onDistribute }) : render2 ? render2({ node, theme, patch, deleteNode }) : (0, import_jsx_runtime27.jsx)(DefaultToolbarContent, { node, theme, onPatch: patch, onDelete: deleteNode })
|
|
20867
21015
|
});
|
|
20868
21016
|
}
|
|
20869
|
-
function MultiToolbarContent({ selectedNodes, theme, onMultiPatch, onDelete }) {
|
|
21017
|
+
function MultiToolbarContent({ selectedNodes, theme, onMultiPatch, onDelete, onAlign, onDistribute }) {
|
|
20870
21018
|
const representativeNode = selectedNodes[0];
|
|
20871
21019
|
const groups = (0, import_react23.useMemo)(() => getNodeActionsForNode(representativeNode, theme), [representativeNode, theme]);
|
|
20872
21020
|
const showDelete = theme.showToolbarDelete === true;
|
|
20873
21021
|
const swatchGroups = groups.filter((g) => g.kind === "swatches" || g.kind == null);
|
|
20874
21022
|
const otherGroups = groups.filter((g) => g.kind !== "swatches" && g.kind != null && g.kind !== "menu");
|
|
20875
|
-
return (0,
|
|
21023
|
+
return (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [(0, import_jsx_runtime27.jsxs)("span", { style: {
|
|
20876
21024
|
fontSize: 11,
|
|
20877
21025
|
color: theme.breadcrumbs.textColor,
|
|
20878
21026
|
opacity: 0.75,
|
|
@@ -20882,35 +21030,75 @@ var SystemCanvas = (() => {
|
|
|
20882
21030
|
const actions = filterActionsForNode(group, representativeNode);
|
|
20883
21031
|
if (actions.length === 0)
|
|
20884
21032
|
return null;
|
|
20885
|
-
return (0,
|
|
21033
|
+
return (0, import_jsx_runtime27.jsxs)(import_react23.default.Fragment, { children: [i > 0 && (0, import_jsx_runtime27.jsx)(Divider2, { theme }), (0, import_jsx_runtime27.jsx)("div", { style: { display: "flex", alignItems: "center", gap: BUTTON_GAP }, children: actions.map((action) => {
|
|
20886
21034
|
const active = action.isActive?.(representativeNode) ?? false;
|
|
20887
21035
|
const handleClick = () => {
|
|
20888
21036
|
const patch = resolveActionPatch(action, representativeNode);
|
|
20889
21037
|
onMultiPatch(patch);
|
|
20890
21038
|
};
|
|
20891
|
-
return (0,
|
|
21039
|
+
return (0, import_jsx_runtime27.jsx)(SwatchButton, { action, active, theme, onClick: handleClick }, action.id);
|
|
20892
21040
|
}) })] }, group.id);
|
|
20893
21041
|
}), otherGroups.map((group) => {
|
|
20894
21042
|
const actions = filterActionsForNode(group, representativeNode);
|
|
20895
21043
|
if (actions.length === 0)
|
|
20896
21044
|
return null;
|
|
20897
|
-
return (0,
|
|
21045
|
+
return (0, import_jsx_runtime27.jsxs)(import_react23.default.Fragment, { children: [(0, import_jsx_runtime27.jsx)(Divider2, { theme }), (0, import_jsx_runtime27.jsx)("div", { style: { display: "flex", alignItems: "center", gap: BUTTON_GAP }, children: actions.map((action) => {
|
|
20898
21046
|
const active = action.isActive?.(representativeNode) ?? false;
|
|
20899
21047
|
const handleClick = () => {
|
|
20900
21048
|
const patch = resolveActionPatch(action, representativeNode);
|
|
20901
21049
|
onMultiPatch(patch);
|
|
20902
21050
|
};
|
|
20903
|
-
return (0,
|
|
21051
|
+
return (0, import_jsx_runtime27.jsx)(IconButton, { action, active, theme, onClick: handleClick }, action.id);
|
|
20904
21052
|
}) })] }, group.id);
|
|
20905
|
-
}),
|
|
21053
|
+
}), onAlign && (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [(0, import_jsx_runtime27.jsx)(Divider2, { theme }), (0, import_jsx_runtime27.jsx)("div", { style: { display: "flex", alignItems: "center", gap: BUTTON_GAP }, children: [
|
|
21054
|
+
{ dir: "left", label: "Align Left", path: "M 3 3 L 3 13 M 5 6 L 13 6 M 5 10 L 11 10" },
|
|
21055
|
+
{ dir: "right", label: "Align Right", path: "M 13 3 L 13 13 M 3 6 L 11 6 M 5 10 L 11 10" },
|
|
21056
|
+
{ dir: "top", label: "Align Top", path: "M 3 3 L 13 3 M 6 5 L 6 13 M 10 5 L 10 11" },
|
|
21057
|
+
{ dir: "bottom", label: "Align Bottom", path: "M 3 13 L 13 13 M 6 3 L 6 11 M 10 5 L 10 11" },
|
|
21058
|
+
{ dir: "centerH", label: "Center Horizontally", path: "M 8 3 L 8 13 M 5 6 L 11 6 M 4 10 L 12 10" },
|
|
21059
|
+
{ dir: "centerV", label: "Center Vertically", path: "M 3 8 L 13 8 M 6 5 L 6 11 M 10 4 L 10 12" }
|
|
21060
|
+
].map(({ dir, label, path }) => (0, import_jsx_runtime27.jsx)("button", { type: "button", title: label, onClick: () => onAlign(dir), onMouseDown: (e) => e.preventDefault(), style: {
|
|
21061
|
+
width: BUTTON_SIZE,
|
|
21062
|
+
height: BUTTON_SIZE,
|
|
21063
|
+
display: "inline-flex",
|
|
21064
|
+
alignItems: "center",
|
|
21065
|
+
justifyContent: "center",
|
|
21066
|
+
background: "transparent",
|
|
21067
|
+
border: `1px solid ${theme.breadcrumbs.separatorColor}`,
|
|
21068
|
+
borderRadius: 6,
|
|
21069
|
+
color: theme.breadcrumbs.textColor,
|
|
21070
|
+
cursor: "pointer",
|
|
21071
|
+
padding: 0,
|
|
21072
|
+
outline: "none"
|
|
21073
|
+
}, children: (0, import_jsx_runtime27.jsx)("svg", { width: 16, height: 16, viewBox: "0 0 16 16", children: (0, import_jsx_runtime27.jsx)("path", { d: path, fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round" }) }) }, dir)) })] }), onDistribute && (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [(0, import_jsx_runtime27.jsx)(Divider2, { theme }), (0, import_jsx_runtime27.jsx)("div", { style: { display: "flex", alignItems: "center", gap: BUTTON_GAP }, children: [
|
|
21074
|
+
{ axis: "horizontal", label: "Distribute Horizontally", path: "M 3 3 L 3 13 M 13 3 L 13 13 M 7 6 L 7 10 M 9 6 L 9 10" },
|
|
21075
|
+
{ axis: "vertical", label: "Distribute Vertically", path: "M 3 3 L 13 3 M 3 13 L 13 13 M 6 7 L 10 7 M 6 9 L 10 9" }
|
|
21076
|
+
].map(({ axis, label, path }) => {
|
|
21077
|
+
const disabled = selectedNodes.length < 3;
|
|
21078
|
+
return (0, import_jsx_runtime27.jsx)("button", { type: "button", title: label, disabled, onClick: () => !disabled && onDistribute(axis), onMouseDown: (e) => e.preventDefault(), style: {
|
|
21079
|
+
width: BUTTON_SIZE,
|
|
21080
|
+
height: BUTTON_SIZE,
|
|
21081
|
+
display: "inline-flex",
|
|
21082
|
+
alignItems: "center",
|
|
21083
|
+
justifyContent: "center",
|
|
21084
|
+
background: "transparent",
|
|
21085
|
+
border: `1px solid ${theme.breadcrumbs.separatorColor}`,
|
|
21086
|
+
borderRadius: 6,
|
|
21087
|
+
color: disabled ? theme.breadcrumbs.separatorColor : theme.breadcrumbs.textColor,
|
|
21088
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
21089
|
+
opacity: disabled ? 0.4 : 1,
|
|
21090
|
+
padding: 0,
|
|
21091
|
+
outline: "none"
|
|
21092
|
+
}, children: (0, import_jsx_runtime27.jsx)("svg", { width: 16, height: 16, viewBox: "0 0 16 16", children: (0, import_jsx_runtime27.jsx)("path", { d: path, fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round" }) }) }, axis);
|
|
21093
|
+
}) })] }), showDelete && (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [(0, import_jsx_runtime27.jsx)(Divider2, { theme }), (0, import_jsx_runtime27.jsx)(DeleteButton, { theme, onDelete })] })] });
|
|
20906
21094
|
}
|
|
20907
21095
|
function DefaultToolbarContent({ node, theme, onPatch, onDelete }) {
|
|
20908
21096
|
const groups = (0, import_react23.useMemo)(() => getNodeActionsForNode(node, theme), [node, theme]);
|
|
20909
21097
|
const showDelete = theme.showToolbarDelete === true;
|
|
20910
|
-
return (0,
|
|
21098
|
+
return (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [groups.map((group, i) => (0, import_jsx_runtime27.jsxs)(import_react23.default.Fragment, { children: [i > 0 && (0, import_jsx_runtime27.jsx)(Divider2, { theme }), (0, import_jsx_runtime27.jsx)(ActionGroupView, { group, node, theme, onPatch })] }, group.id)), showDelete && (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [(0, import_jsx_runtime27.jsx)(Divider2, { theme }), (0, import_jsx_runtime27.jsx)(DeleteButton, { theme, onDelete })] })] });
|
|
20911
21099
|
}
|
|
20912
21100
|
function Divider2({ theme }) {
|
|
20913
|
-
return (0,
|
|
21101
|
+
return (0, import_jsx_runtime27.jsx)("div", { style: {
|
|
20914
21102
|
width: 1,
|
|
20915
21103
|
alignSelf: "stretch",
|
|
20916
21104
|
background: theme.breadcrumbs.separatorColor,
|
|
@@ -20923,23 +21111,23 @@ var SystemCanvas = (() => {
|
|
|
20923
21111
|
return null;
|
|
20924
21112
|
const kind = group.kind ?? "buttons";
|
|
20925
21113
|
if (kind === "menu") {
|
|
20926
|
-
return (0,
|
|
21114
|
+
return (0, import_jsx_runtime27.jsx)(MenuGroup, { group, actions, node, theme, onPatch });
|
|
20927
21115
|
}
|
|
20928
|
-
return (0,
|
|
21116
|
+
return (0, import_jsx_runtime27.jsx)("div", { title: group.label, style: { display: "flex", alignItems: "center", gap: BUTTON_GAP }, children: actions.map((action) => {
|
|
20929
21117
|
const handleClick = () => {
|
|
20930
21118
|
const patch = resolveActionPatch(action, node);
|
|
20931
21119
|
onPatch(patch);
|
|
20932
21120
|
};
|
|
20933
21121
|
const active = action.isActive?.(node) ?? false;
|
|
20934
21122
|
if (kind === "swatches") {
|
|
20935
|
-
return (0,
|
|
21123
|
+
return (0, import_jsx_runtime27.jsx)(SwatchButton, { action, active, theme, onClick: handleClick }, action.id);
|
|
20936
21124
|
}
|
|
20937
|
-
return (0,
|
|
21125
|
+
return (0, import_jsx_runtime27.jsx)(IconButton, { action, active, theme, onClick: handleClick }, action.id);
|
|
20938
21126
|
}) });
|
|
20939
21127
|
}
|
|
20940
21128
|
function SwatchButton({ action, active, theme, onClick }) {
|
|
20941
21129
|
const color2 = action.swatch ?? theme.node.labelColor;
|
|
20942
|
-
return (0,
|
|
21130
|
+
return (0, import_jsx_runtime27.jsx)("button", { type: "button", title: action.label, onClick, style: {
|
|
20943
21131
|
width: SWATCH_SIZE,
|
|
20944
21132
|
height: SWATCH_SIZE,
|
|
20945
21133
|
borderRadius: "50%",
|
|
@@ -20953,7 +21141,7 @@ var SystemCanvas = (() => {
|
|
|
20953
21141
|
}, onMouseDown: (e) => e.preventDefault() });
|
|
20954
21142
|
}
|
|
20955
21143
|
function IconButton({ action, active, theme, onClick }) {
|
|
20956
|
-
return (0,
|
|
21144
|
+
return (0, import_jsx_runtime27.jsx)("button", { type: "button", title: action.label, onClick, style: {
|
|
20957
21145
|
width: BUTTON_SIZE,
|
|
20958
21146
|
height: BUTTON_SIZE,
|
|
20959
21147
|
display: "inline-flex",
|
|
@@ -20966,12 +21154,12 @@ var SystemCanvas = (() => {
|
|
|
20966
21154
|
cursor: "pointer",
|
|
20967
21155
|
padding: 0,
|
|
20968
21156
|
outline: "none"
|
|
20969
|
-
}, onMouseDown: (e) => e.preventDefault(), children: action.icon ? (0,
|
|
21157
|
+
}, onMouseDown: (e) => e.preventDefault(), children: action.icon ? (0, import_jsx_runtime27.jsx)("svg", { width: 16, height: 16, viewBox: "0 0 16 16", children: (0, import_jsx_runtime27.jsx)(NodeIcon, { icon: action.icon, x: 0, y: 0, size: 16, color: active ? theme.breadcrumbs.activeColor : theme.breadcrumbs.textColor, opacity: 1, customIcons: theme.icons }) }) : action.swatch ? (0, import_jsx_runtime27.jsx)("span", { style: {
|
|
20970
21158
|
width: 10,
|
|
20971
21159
|
height: 10,
|
|
20972
21160
|
borderRadius: "50%",
|
|
20973
21161
|
background: action.swatch
|
|
20974
|
-
} }) : (0,
|
|
21162
|
+
} }) : (0, import_jsx_runtime27.jsx)("span", { style: { fontSize: 10 }, children: action.label.slice(0, 2) }) });
|
|
20975
21163
|
}
|
|
20976
21164
|
function MenuGroup({ group, actions, node, theme, onPatch }) {
|
|
20977
21165
|
const [open, setOpen] = (0, import_react23.useState)(false);
|
|
@@ -20989,7 +21177,7 @@ var SystemCanvas = (() => {
|
|
|
20989
21177
|
const active = actions.find((a) => a.isActive?.(node));
|
|
20990
21178
|
const triggerLabel = active?.label ?? group.label ?? "Menu";
|
|
20991
21179
|
const triggerIcon = active?.icon ?? void 0;
|
|
20992
|
-
return (0,
|
|
21180
|
+
return (0, import_jsx_runtime27.jsxs)("div", { ref: wrapRef, style: { position: "relative" }, children: [(0, import_jsx_runtime27.jsxs)("button", { type: "button", title: group.label, onClick: () => setOpen((v) => !v), style: {
|
|
20993
21181
|
height: BUTTON_SIZE,
|
|
20994
21182
|
display: "inline-flex",
|
|
20995
21183
|
alignItems: "center",
|
|
@@ -21003,7 +21191,7 @@ var SystemCanvas = (() => {
|
|
|
21003
21191
|
fontFamily: "inherit",
|
|
21004
21192
|
fontSize: "inherit",
|
|
21005
21193
|
outline: "none"
|
|
21006
|
-
}, onMouseDown: (e) => e.preventDefault(), children: [triggerIcon && (0,
|
|
21194
|
+
}, onMouseDown: (e) => e.preventDefault(), children: [triggerIcon && (0, import_jsx_runtime27.jsx)("svg", { width: 14, height: 14, viewBox: "0 0 16 16", children: (0, import_jsx_runtime27.jsx)(NodeIcon, { icon: triggerIcon, x: 0, y: 0, size: 14, color: theme.breadcrumbs.textColor, opacity: 1, customIcons: theme.icons }) }), (0, import_jsx_runtime27.jsx)("span", { children: triggerLabel }), (0, import_jsx_runtime27.jsx)("span", { style: { opacity: 0.6, fontSize: 8 }, children: "\u25BE" })] }), open && (0, import_jsx_runtime27.jsx)("div", { style: {
|
|
21007
21195
|
position: "absolute",
|
|
21008
21196
|
top: "100%",
|
|
21009
21197
|
left: 0,
|
|
@@ -21018,7 +21206,7 @@ var SystemCanvas = (() => {
|
|
|
21018
21206
|
zIndex: 1
|
|
21019
21207
|
}, children: actions.map((action) => {
|
|
21020
21208
|
const isActive = action.isActive?.(node) ?? false;
|
|
21021
|
-
return (0,
|
|
21209
|
+
return (0, import_jsx_runtime27.jsxs)("button", { type: "button", onClick: () => {
|
|
21022
21210
|
onPatch(resolveActionPatch(action, node));
|
|
21023
21211
|
setOpen(false);
|
|
21024
21212
|
}, style: {
|
|
@@ -21035,17 +21223,17 @@ var SystemCanvas = (() => {
|
|
|
21035
21223
|
fontFamily: "inherit",
|
|
21036
21224
|
fontSize: "inherit",
|
|
21037
21225
|
textAlign: "left"
|
|
21038
|
-
}, onMouseDown: (e) => e.preventDefault(), children: [action.icon && (0,
|
|
21226
|
+
}, onMouseDown: (e) => e.preventDefault(), children: [action.icon && (0, import_jsx_runtime27.jsx)("svg", { width: 14, height: 14, viewBox: "0 0 16 16", children: (0, import_jsx_runtime27.jsx)(NodeIcon, { icon: action.icon, x: 0, y: 0, size: 14, color: isActive ? theme.breadcrumbs.activeColor : theme.breadcrumbs.textColor, opacity: 1, customIcons: theme.icons }) }), action.swatch && (0, import_jsx_runtime27.jsx)("span", { style: {
|
|
21039
21227
|
width: 10,
|
|
21040
21228
|
height: 10,
|
|
21041
21229
|
borderRadius: "50%",
|
|
21042
21230
|
background: action.swatch,
|
|
21043
21231
|
flexShrink: 0
|
|
21044
|
-
} }), (0,
|
|
21232
|
+
} }), (0, import_jsx_runtime27.jsx)("span", { children: action.label })] }, action.id);
|
|
21045
21233
|
}) })] });
|
|
21046
21234
|
}
|
|
21047
21235
|
function DeleteButton({ theme, onDelete }) {
|
|
21048
|
-
return (0,
|
|
21236
|
+
return (0, import_jsx_runtime27.jsx)("button", { type: "button", title: "Delete", onClick: onDelete, onMouseDown: (e) => e.preventDefault(), style: {
|
|
21049
21237
|
width: BUTTON_SIZE,
|
|
21050
21238
|
height: BUTTON_SIZE,
|
|
21051
21239
|
display: "inline-flex",
|
|
@@ -21058,23 +21246,44 @@ var SystemCanvas = (() => {
|
|
|
21058
21246
|
cursor: "pointer",
|
|
21059
21247
|
padding: 0,
|
|
21060
21248
|
outline: "none"
|
|
21061
|
-
}, children: (0,
|
|
21249
|
+
}, children: (0, import_jsx_runtime27.jsx)("svg", { width: DELETE_SIZE, height: DELETE_SIZE, viewBox: "0 0 16 16", children: (0, import_jsx_runtime27.jsx)("path", { d: "M 3 5 L 13 5 M 6 5 L 6 3 L 10 3 L 10 5 M 5 5 L 5.5 14 L 10.5 14 L 11 5 M 7 7 L 7 12 M 9 7 L 9 12", fill: "none", stroke: "currentColor", strokeWidth: 1.2, strokeLinecap: "round", strokeLinejoin: "round" }) }) });
|
|
21062
21250
|
}
|
|
21063
21251
|
|
|
21064
|
-
// ../react/dist/
|
|
21065
|
-
var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
|
|
21252
|
+
// ../react/dist/hooks/useAlignmentGuides.js
|
|
21066
21253
|
var import_react24 = __toESM(require_react(), 1);
|
|
21254
|
+
function useAlignmentGuides(options) {
|
|
21255
|
+
const { dragOverrides, nodesRef, isDragging, threshold } = options;
|
|
21256
|
+
return (0, import_react24.useMemo)(() => {
|
|
21257
|
+
if (!isDragging || dragOverrides.size === 0)
|
|
21258
|
+
return [];
|
|
21259
|
+
const all = nodesRef.current ?? [];
|
|
21260
|
+
const dragging = [];
|
|
21261
|
+
const others = [];
|
|
21262
|
+
for (const n of all) {
|
|
21263
|
+
const override = dragOverrides.get(n.id);
|
|
21264
|
+
if (override)
|
|
21265
|
+
dragging.push({ ...n, ...override });
|
|
21266
|
+
else
|
|
21267
|
+
others.push(n);
|
|
21268
|
+
}
|
|
21269
|
+
return computeAlignmentGuides(dragging, others, threshold);
|
|
21270
|
+
}, [dragOverrides, isDragging, nodesRef, threshold]);
|
|
21271
|
+
}
|
|
21272
|
+
|
|
21273
|
+
// ../react/dist/components/NodeContextMenuOverlay.js
|
|
21274
|
+
var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
|
|
21275
|
+
var import_react25 = __toESM(require_react(), 1);
|
|
21067
21276
|
var ESTIMATED_MENU_WIDTH = 200;
|
|
21068
21277
|
var MIN_MENU_WIDTH = 160;
|
|
21069
21278
|
var VIEWPORT_MARGIN = 8;
|
|
21070
21279
|
function NodeContextMenuOverlay({ state, config, theme, onClose }) {
|
|
21071
|
-
const rootRef = (0,
|
|
21072
|
-
const [hoveredId, setHoveredId] = (0,
|
|
21073
|
-
(0,
|
|
21280
|
+
const rootRef = (0, import_react25.useRef)(null);
|
|
21281
|
+
const [hoveredId, setHoveredId] = (0, import_react25.useState)(null);
|
|
21282
|
+
(0, import_react25.useEffect)(() => {
|
|
21074
21283
|
if (state)
|
|
21075
21284
|
setHoveredId(null);
|
|
21076
21285
|
}, [state]);
|
|
21077
|
-
(0,
|
|
21286
|
+
(0, import_react25.useEffect)(() => {
|
|
21078
21287
|
if (!state)
|
|
21079
21288
|
return;
|
|
21080
21289
|
function onDown(e) {
|
|
@@ -21118,7 +21327,7 @@ var SystemCanvas = (() => {
|
|
|
21118
21327
|
const top = vh ? Math.min(state.screenPosition.y, vh - estimatedHeight - VIEWPORT_MARGIN) : state.screenPosition.y;
|
|
21119
21328
|
const matchCtx = { canvasRef: state.canvasRef };
|
|
21120
21329
|
const anyIcon = state.items.some((item) => !!item.icon);
|
|
21121
|
-
return (0,
|
|
21330
|
+
return (0, import_jsx_runtime28.jsx)("div", {
|
|
21122
21331
|
ref: rootRef,
|
|
21123
21332
|
role: "menu",
|
|
21124
21333
|
// Stop right-clicks inside the menu from bubbling into the document
|
|
@@ -21151,7 +21360,7 @@ var SystemCanvas = (() => {
|
|
|
21151
21360
|
const isDisabled = item.disabled?.(state.node, matchCtx) ?? false;
|
|
21152
21361
|
const isHovered = !isDisabled && hoveredId === item.id;
|
|
21153
21362
|
const color2 = item.destructive ? cm.destructiveItemColor : cm.itemColor;
|
|
21154
|
-
return (0,
|
|
21363
|
+
return (0, import_jsx_runtime28.jsxs)("div", { role: "menuitem", "aria-disabled": isDisabled, onMouseEnter: () => !isDisabled && setHoveredId(item.id), onMouseLeave: () => setHoveredId((id2) => id2 === item.id ? null : id2), onClick: () => {
|
|
21155
21364
|
if (isDisabled)
|
|
21156
21365
|
return;
|
|
21157
21366
|
config.onSelect(item.id, state.node, {
|
|
@@ -21169,12 +21378,12 @@ var SystemCanvas = (() => {
|
|
|
21169
21378
|
opacity: isDisabled ? 0.45 : 1,
|
|
21170
21379
|
background: isHovered ? cm.itemHoverBackground : "transparent",
|
|
21171
21380
|
color: color2
|
|
21172
|
-
}, children: [item.icon ? (0,
|
|
21381
|
+
}, children: [item.icon ? (0, import_jsx_runtime28.jsx)("svg", { width: 14, height: 14, viewBox: "0 0 16 16", style: { flexShrink: 0, overflow: "visible" }, children: (0, import_jsx_runtime28.jsx)(NodeIcon, { icon: item.icon, x: 0, y: 0, size: 14, color: color2, opacity: 1, customIcons: theme.icons }) }) : anyIcon ? (
|
|
21173
21382
|
// Only reserve a spacer when other items in the same menu
|
|
21174
21383
|
// do have icons — keeps labels vertically aligned in a
|
|
21175
21384
|
// mixed menu without padding lone-item menus.
|
|
21176
|
-
(0,
|
|
21177
|
-
) : null, (0,
|
|
21385
|
+
(0, import_jsx_runtime28.jsx)("span", { style: { width: 14, flexShrink: 0 }, "aria-hidden": true })
|
|
21386
|
+
) : null, (0, import_jsx_runtime28.jsx)("span", { children: item.label })] }, item.id);
|
|
21178
21387
|
})
|
|
21179
21388
|
});
|
|
21180
21389
|
}
|
|
@@ -21182,8 +21391,8 @@ var SystemCanvas = (() => {
|
|
|
21182
21391
|
// ../react/dist/components/SystemCanvas.js
|
|
21183
21392
|
var CASCADE_WINDOW_MS = 1500;
|
|
21184
21393
|
var CASCADE_OFFSET = 20;
|
|
21185
|
-
var SystemCanvas = (0,
|
|
21186
|
-
const zoomNavConfig = (0,
|
|
21394
|
+
var SystemCanvas = (0, import_react26.forwardRef)(function SystemCanvas2({ canvas, onResolveCanvas, canvases, rootLabel = "Home", onNavigate, onBreadcrumbClick, onBreadcrumbsChange, onNodeClick, onNodeDoubleClick, onEdgeClick, onEdgeDoubleClick, onContextMenu, onSelectionChange, nodeContextMenu, editable = false, onNodeAdd, onNodeUpdate, onNodesUpdate, onNodeDelete, onNodesDelete, onEdgeUpdate, onEdgeDelete, onEdgeAdd, canDropNodeOn, onNodeDrop, renderAddNodeButton, showNodeToolbar = true, renderNodeToolbar, theme: themeProp, themes: customThemes, edgeStyle = "bezier", defaultViewport, minZoom: minZoomProp, maxZoom, onViewportChange, autoFit = "canvas-change", laneHeaders = "pinned", snapToLanes = false, zoomNavigation = false, snapGrid, guideThreshold, alignDistributeMenu, historyDepth, onUndo, onRedo, className, style }, forwardedRef) {
|
|
21395
|
+
const zoomNavConfig = (0, import_react26.useMemo)(() => {
|
|
21187
21396
|
const defaults = {
|
|
21188
21397
|
enterThreshold: 0.66,
|
|
21189
21398
|
exitThreshold: 0.33,
|
|
@@ -21208,16 +21417,16 @@ var SystemCanvas = (() => {
|
|
|
21208
21417
|
}, [zoomNavigation]);
|
|
21209
21418
|
const effectiveMaxZoom = maxZoom ?? (zoomNavConfig.enabled ? 16 : 4);
|
|
21210
21419
|
const effectiveMinZoom = minZoomProp ?? (zoomNavConfig.enabled ? 0.01 : 0.1);
|
|
21211
|
-
(0,
|
|
21420
|
+
(0, import_react26.useEffect)(() => {
|
|
21212
21421
|
const env = globalThis.process?.env?.NODE_ENV;
|
|
21213
21422
|
if (editable && !canvases && env !== "production") {
|
|
21214
21423
|
console.warn("[system-canvas] `editable` is enabled but `canvases` prop is missing. Edits to sub-canvases will not be reflected without a synchronous ref \u2192 CanvasData map.");
|
|
21215
21424
|
}
|
|
21216
21425
|
}, [editable, canvases]);
|
|
21217
|
-
const [parentFrames, setParentFrames] = (0,
|
|
21218
|
-
const [pendingHandoff, setPendingHandoff] = (0,
|
|
21219
|
-
const suppressNextHandoffClearRef = (0,
|
|
21220
|
-
const handleBreadcrumbClick = (0,
|
|
21426
|
+
const [parentFrames, setParentFrames] = (0, import_react26.useState)([]);
|
|
21427
|
+
const [pendingHandoff, setPendingHandoff] = (0, import_react26.useState)(null);
|
|
21428
|
+
const suppressNextHandoffClearRef = (0, import_react26.useRef)(false);
|
|
21429
|
+
const handleBreadcrumbClick = (0, import_react26.useCallback)((index) => {
|
|
21221
21430
|
setParentFrames((prev) => prev.slice(0, index));
|
|
21222
21431
|
if (suppressNextHandoffClearRef.current) {
|
|
21223
21432
|
suppressNextHandoffClearRef.current = false;
|
|
@@ -21234,10 +21443,10 @@ var SystemCanvas = (() => {
|
|
|
21234
21443
|
onNavigate,
|
|
21235
21444
|
onBreadcrumbClick: handleBreadcrumbClick
|
|
21236
21445
|
});
|
|
21237
|
-
(0,
|
|
21446
|
+
(0, import_react26.useEffect)(() => {
|
|
21238
21447
|
onBreadcrumbsChange?.(breadcrumbs);
|
|
21239
21448
|
}, [breadcrumbs, onBreadcrumbsChange]);
|
|
21240
|
-
const theme = (0,
|
|
21449
|
+
const theme = (0, import_react26.useMemo)(() => {
|
|
21241
21450
|
const registry = { ...themes, ...customThemes };
|
|
21242
21451
|
const resolveByName = (name) => name && registry[name] ? registry[name] : null;
|
|
21243
21452
|
if (themeProp) {
|
|
@@ -21248,22 +21457,23 @@ var SystemCanvas = (() => {
|
|
|
21248
21457
|
}
|
|
21249
21458
|
return resolveByName(currentCanvas.theme?.base) ?? resolveByName(canvas.theme?.base) ?? darkTheme;
|
|
21250
21459
|
}, [themeProp, customThemes, currentCanvas.theme?.base, canvas.theme?.base]);
|
|
21251
|
-
const
|
|
21460
|
+
const snapGridSize = snapGrid === true ? theme.grid.size : typeof snapGrid === "number" ? snapGrid : 0;
|
|
21461
|
+
const { nodes, edges, nodeMap } = (0, import_react26.useMemo)(() => {
|
|
21252
21462
|
const resolved = resolveCanvas(currentCanvas, theme);
|
|
21253
21463
|
const map = buildNodeMap(resolved.nodes);
|
|
21254
21464
|
return { nodes: resolved.nodes, edges: resolved.edges, nodeMap: map };
|
|
21255
21465
|
}, [currentCanvas, theme]);
|
|
21256
|
-
const nodesRef = (0,
|
|
21466
|
+
const nodesRef = (0, import_react26.useRef)(nodes);
|
|
21257
21467
|
nodesRef.current = nodes;
|
|
21258
|
-
const viewportStateRef = (0,
|
|
21259
|
-
const viewportHandleRef = (0,
|
|
21260
|
-
const navigateToRefRef = (0,
|
|
21468
|
+
const viewportStateRef = (0, import_react26.useRef)(defaultViewport ?? { x: 0, y: 0, zoom: 1 });
|
|
21469
|
+
const viewportHandleRef = (0, import_react26.useRef)(null);
|
|
21470
|
+
const navigateToRefRef = (0, import_react26.useRef)(navigateToRef);
|
|
21261
21471
|
navigateToRefRef.current = navigateToRef;
|
|
21262
|
-
const navigateToBreadcrumbRef = (0,
|
|
21472
|
+
const navigateToBreadcrumbRef = (0, import_react26.useRef)(navigateToBreadcrumb);
|
|
21263
21473
|
navigateToBreadcrumbRef.current = navigateToBreadcrumb;
|
|
21264
|
-
const breadcrumbsRef = (0,
|
|
21474
|
+
const breadcrumbsRef = (0, import_react26.useRef)(breadcrumbs);
|
|
21265
21475
|
breadcrumbsRef.current = breadcrumbs;
|
|
21266
|
-
(0,
|
|
21476
|
+
(0, import_react26.useImperativeHandle)(forwardedRef, () => ({
|
|
21267
21477
|
zoomIntoNode: (nodeId, options) => {
|
|
21268
21478
|
return new Promise((resolve) => {
|
|
21269
21479
|
const node = nodesRef.current.find((n) => n.id === nodeId);
|
|
@@ -21295,11 +21505,11 @@ var SystemCanvas = (() => {
|
|
|
21295
21505
|
navigateToBreadcrumbRef.current(0);
|
|
21296
21506
|
}
|
|
21297
21507
|
}), [forwardedRef]);
|
|
21298
|
-
const [editingId, setEditingId] = (0,
|
|
21299
|
-
const [selectedEdgeId, setSelectedEdgeId] = (0,
|
|
21300
|
-
const [editingEdgeId, setEditingEdgeId] = (0,
|
|
21301
|
-
const svgProxyRef = (0,
|
|
21302
|
-
const containerRef = (0,
|
|
21508
|
+
const [editingId, setEditingId] = (0, import_react26.useState)(null);
|
|
21509
|
+
const [selectedEdgeId, setSelectedEdgeId] = (0, import_react26.useState)(null);
|
|
21510
|
+
const [editingEdgeId, setEditingEdgeId] = (0, import_react26.useState)(null);
|
|
21511
|
+
const svgProxyRef = (0, import_react26.useRef)(null);
|
|
21512
|
+
const containerRef = (0, import_react26.useRef)(null);
|
|
21303
21513
|
const { selectedIds, selectNode, toggleNode, selectAll, clearSelection, selectMultiple, marqueeRect, marqueeActiveRef } = useMultiSelect({
|
|
21304
21514
|
svgRef: svgProxyRef,
|
|
21305
21515
|
viewport: viewportStateRef,
|
|
@@ -21307,12 +21517,12 @@ var SystemCanvas = (() => {
|
|
|
21307
21517
|
containerRef,
|
|
21308
21518
|
enabled: editable
|
|
21309
21519
|
});
|
|
21310
|
-
const selectedIdsRef = (0,
|
|
21311
|
-
(0,
|
|
21520
|
+
const selectedIdsRef = (0, import_react26.useRef)(selectedIds);
|
|
21521
|
+
(0, import_react26.useEffect)(() => {
|
|
21312
21522
|
selectedIdsRef.current = selectedIds;
|
|
21313
21523
|
}, [selectedIds]);
|
|
21314
|
-
const edgesRef = (0,
|
|
21315
|
-
(0,
|
|
21524
|
+
const edgesRef = (0, import_react26.useRef)(edges);
|
|
21525
|
+
(0, import_react26.useEffect)(() => {
|
|
21316
21526
|
edgesRef.current = edges;
|
|
21317
21527
|
}, [edges]);
|
|
21318
21528
|
const { wrappedOnNodeAdd, wrappedOnNodeUpdate, wrappedOnNodesUpdate, wrappedOnNodeDelete, wrappedOnNodesDelete, wrappedOnEdgeAdd, wrappedOnEdgeUpdate, wrappedOnEdgeDelete, beginBatch, endBatch, undo, redo } = useCommandHistory({
|
|
@@ -21344,18 +21554,18 @@ var SystemCanvas = (() => {
|
|
|
21344
21554
|
onBeginBatch: beginBatch,
|
|
21345
21555
|
onEndBatch: endBatch
|
|
21346
21556
|
});
|
|
21347
|
-
(0,
|
|
21557
|
+
(0, import_react26.useEffect)(() => {
|
|
21348
21558
|
clearSelection();
|
|
21349
21559
|
setEditingId(null);
|
|
21350
21560
|
setSelectedEdgeId(null);
|
|
21351
21561
|
setEditingEdgeId(null);
|
|
21352
21562
|
}, [currentCanvasRef]);
|
|
21353
|
-
const onSelectionChangeRef = (0,
|
|
21354
|
-
(0,
|
|
21563
|
+
const onSelectionChangeRef = (0, import_react26.useRef)(onSelectionChange);
|
|
21564
|
+
(0, import_react26.useEffect)(() => {
|
|
21355
21565
|
onSelectionChangeRef.current = onSelectionChange;
|
|
21356
21566
|
}, [onSelectionChange]);
|
|
21357
|
-
const lastEmittedSelectionRef = (0,
|
|
21358
|
-
(0,
|
|
21567
|
+
const lastEmittedSelectionRef = (0, import_react26.useRef)({ kind: null, id: null, multiIds: null, canvasRef: void 0 });
|
|
21568
|
+
(0, import_react26.useEffect)(() => {
|
|
21359
21569
|
const cb = onSelectionChangeRef.current;
|
|
21360
21570
|
let next = null;
|
|
21361
21571
|
if (selectedIds.size > 1) {
|
|
@@ -21397,8 +21607,8 @@ var SystemCanvas = (() => {
|
|
|
21397
21607
|
}
|
|
21398
21608
|
cb?.(next);
|
|
21399
21609
|
}, [selectedIds, selectedEdgeId, currentCanvasRef, nodeMap, edges]);
|
|
21400
|
-
const [containerSize, setContainerSize] = (0,
|
|
21401
|
-
(0,
|
|
21610
|
+
const [containerSize, setContainerSize] = (0, import_react26.useState)({ width: 0, height: 0 });
|
|
21611
|
+
(0, import_react26.useEffect)(() => {
|
|
21402
21612
|
const el = containerRef.current;
|
|
21403
21613
|
if (!el)
|
|
21404
21614
|
return;
|
|
@@ -21413,8 +21623,8 @@ var SystemCanvas = (() => {
|
|
|
21413
21623
|
}, []);
|
|
21414
21624
|
const hasLanes = currentCanvas.columns && currentCanvas.columns.length > 0 || currentCanvas.rows && currentCanvas.rows.length > 0;
|
|
21415
21625
|
const showLaneHeaders = hasLanes && laneHeaders !== "none";
|
|
21416
|
-
const getViewportState = (0,
|
|
21417
|
-
const applyLaneSnap = (0,
|
|
21626
|
+
const getViewportState = (0, import_react26.useCallback)(() => viewportStateRef.current ?? { x: 0, y: 0, zoom: 1 }, []);
|
|
21627
|
+
const applyLaneSnap = (0, import_react26.useCallback)((id2, patch) => {
|
|
21418
21628
|
if (!snapToLanes)
|
|
21419
21629
|
return patch;
|
|
21420
21630
|
const cols = currentCanvas.columns;
|
|
@@ -21439,10 +21649,10 @@ var SystemCanvas = (() => {
|
|
|
21439
21649
|
}
|
|
21440
21650
|
return final;
|
|
21441
21651
|
}, [snapToLanes, currentCanvas.columns, currentCanvas.rows]);
|
|
21442
|
-
const commitResize = (0,
|
|
21652
|
+
const commitResize = (0, import_react26.useCallback)((id2, patch) => {
|
|
21443
21653
|
wrappedOnNodeUpdate(id2, applyLaneSnap(id2, patch), currentCanvasRef);
|
|
21444
21654
|
}, [wrappedOnNodeUpdate, currentCanvasRef, applyLaneSnap]);
|
|
21445
|
-
const commitDragBatch = (0,
|
|
21655
|
+
const commitDragBatch = (0, import_react26.useCallback)((updates) => {
|
|
21446
21656
|
const final = updates.map((u) => ({
|
|
21447
21657
|
id: u.id,
|
|
21448
21658
|
patch: applyLaneSnap(u.id, u.patch)
|
|
@@ -21457,24 +21667,32 @@ var SystemCanvas = (() => {
|
|
|
21457
21667
|
wrappedOnNodeUpdate(id2, patch, currentCanvasRef);
|
|
21458
21668
|
}
|
|
21459
21669
|
}, [wrappedOnNodeUpdate, wrappedOnNodesUpdate, onNodeUpdate, onNodesUpdate, currentCanvasRef, applyLaneSnap]);
|
|
21460
|
-
const handleNodeDrop = (0,
|
|
21670
|
+
const handleNodeDrop = (0, import_react26.useCallback)((sources, target) => {
|
|
21461
21671
|
onNodeDrop?.(sources, target, { canvasRef: currentCanvasRef });
|
|
21462
21672
|
}, [onNodeDrop, currentCanvasRef]);
|
|
21463
|
-
const { dragOverrides, dropTargetId, onPointerDown: onNodePointerDown, cancelDrag } = useNodeDrag({
|
|
21673
|
+
const { dragOverrides, dropTargetId, onPointerDown: onNodePointerDown, cancelDrag, isDragging } = useNodeDrag({
|
|
21464
21674
|
viewport: viewportStateRef,
|
|
21465
21675
|
nodesRef,
|
|
21466
21676
|
onCommit: commitDragBatch,
|
|
21467
21677
|
svgRef: svgProxyRef,
|
|
21468
21678
|
canDropNodeOn,
|
|
21469
21679
|
onNodeDrop: handleNodeDrop,
|
|
21470
|
-
selectedIdsRef
|
|
21680
|
+
selectedIdsRef,
|
|
21681
|
+
snapGridSize
|
|
21471
21682
|
});
|
|
21472
21683
|
const { resizeOverrides, onHandlePointerDown: onResizeHandlePointerDown } = useNodeResize({
|
|
21473
21684
|
viewport: viewportStateRef,
|
|
21474
|
-
onCommit: commitResize
|
|
21685
|
+
onCommit: commitResize,
|
|
21686
|
+
snapGridSize
|
|
21687
|
+
});
|
|
21688
|
+
const alignmentGuides = useAlignmentGuides({
|
|
21689
|
+
dragOverrides,
|
|
21690
|
+
nodesRef,
|
|
21691
|
+
isDragging,
|
|
21692
|
+
threshold: guideThreshold ?? 4
|
|
21475
21693
|
});
|
|
21476
21694
|
const singleSelectedId = selectedIds.size === 1 ? Array.from(selectedIds)[0] : null;
|
|
21477
|
-
const selectedResolvedNode = (0,
|
|
21695
|
+
const selectedResolvedNode = (0, import_react26.useMemo)(() => {
|
|
21478
21696
|
if (!singleSelectedId)
|
|
21479
21697
|
return null;
|
|
21480
21698
|
const base = nodeMap.get(singleSelectedId);
|
|
@@ -21491,7 +21709,7 @@ var SystemCanvas = (() => {
|
|
|
21491
21709
|
return base;
|
|
21492
21710
|
}, [singleSelectedId, nodeMap, dragOverrides, resizeOverrides]);
|
|
21493
21711
|
svgProxyRef.current = viewportHandleRef.current?.getSvgElement() ?? null;
|
|
21494
|
-
const handleEdgeCreated = (0,
|
|
21712
|
+
const handleEdgeCreated = (0, import_react26.useCallback)((edge) => {
|
|
21495
21713
|
wrappedOnEdgeAdd(edge, currentCanvasRef);
|
|
21496
21714
|
}, [wrappedOnEdgeAdd, currentCanvasRef]);
|
|
21497
21715
|
const { pending: pendingEdge, onHandlePointerDown: onConnectionHandlePointerDown } = useEdgeCreate({
|
|
@@ -21500,7 +21718,7 @@ var SystemCanvas = (() => {
|
|
|
21500
21718
|
nodesRef,
|
|
21501
21719
|
onCreate: handleEdgeCreated
|
|
21502
21720
|
});
|
|
21503
|
-
const handleNavigableNodeClick = (0,
|
|
21721
|
+
const handleNavigableNodeClick = (0, import_react26.useCallback)((node) => {
|
|
21504
21722
|
const frame2 = {
|
|
21505
21723
|
parentCanvasRef: currentCanvasRef,
|
|
21506
21724
|
parentNodeRect: {
|
|
@@ -21527,7 +21745,7 @@ var SystemCanvas = (() => {
|
|
|
21527
21745
|
navigateToRef(node);
|
|
21528
21746
|
}
|
|
21529
21747
|
}, [navigateToRef, currentCanvasRef, zoomNavConfig.enabled]);
|
|
21530
|
-
const handleZoomEnter = (0,
|
|
21748
|
+
const handleZoomEnter = (0, import_react26.useCallback)((node, targetTransform) => {
|
|
21531
21749
|
const frame2 = {
|
|
21532
21750
|
parentCanvasRef: currentCanvasRef,
|
|
21533
21751
|
parentNodeRect: {
|
|
@@ -21541,7 +21759,7 @@ var SystemCanvas = (() => {
|
|
|
21541
21759
|
setPendingHandoff(targetTransform);
|
|
21542
21760
|
navigateToRef(node);
|
|
21543
21761
|
}, [currentCanvasRef, navigateToRef]);
|
|
21544
|
-
const handleZoomExit = (0,
|
|
21762
|
+
const handleZoomExit = (0, import_react26.useCallback)((targetTransform) => {
|
|
21545
21763
|
setPendingHandoff(targetTransform);
|
|
21546
21764
|
suppressNextHandoffClearRef.current = true;
|
|
21547
21765
|
navigateToBreadcrumb(breadcrumbs.length - 2);
|
|
@@ -21568,37 +21786,70 @@ var SystemCanvas = (() => {
|
|
|
21568
21786
|
onEnter: handleZoomEnter,
|
|
21569
21787
|
onExit: handleZoomExit
|
|
21570
21788
|
});
|
|
21571
|
-
const handleViewportChange = (0,
|
|
21789
|
+
const handleViewportChange = (0, import_react26.useCallback)((vp) => {
|
|
21572
21790
|
viewportStateRef.current = vp;
|
|
21573
21791
|
handleZoomNavViewportChange(vp);
|
|
21574
21792
|
onViewportChange?.(vp);
|
|
21575
21793
|
}, [handleZoomNavViewportChange, onViewportChange]);
|
|
21576
|
-
const handleHandoffApplied = (0,
|
|
21794
|
+
const handleHandoffApplied = (0, import_react26.useCallback)(() => {
|
|
21577
21795
|
setPendingHandoff(null);
|
|
21578
21796
|
clearZoomNavCommitting();
|
|
21579
21797
|
}, [clearZoomNavCommitting]);
|
|
21580
|
-
const handleBeginEdit = (0,
|
|
21798
|
+
const handleBeginEdit = (0, import_react26.useCallback)((node) => {
|
|
21581
21799
|
setEditingId(node.id);
|
|
21582
21800
|
}, []);
|
|
21583
|
-
const handleBeginEditEdge = (0,
|
|
21801
|
+
const handleBeginEditEdge = (0, import_react26.useCallback)((edge) => {
|
|
21584
21802
|
setEditingEdgeId(edge.id);
|
|
21585
21803
|
}, []);
|
|
21586
|
-
const
|
|
21587
|
-
|
|
21804
|
+
const handleAlign = (0, import_react26.useCallback)((direction) => {
|
|
21805
|
+
const selectedNodes = Array.from(selectedIds).map((id2) => nodesRef.current.find((n) => n.id === id2)).filter((n) => n != null);
|
|
21806
|
+
const updates = alignNodes(selectedNodes, direction);
|
|
21807
|
+
if (updates.length > 0)
|
|
21808
|
+
wrappedOnNodesUpdate(updates, currentCanvasRef);
|
|
21809
|
+
}, [selectedIds, nodesRef, wrappedOnNodesUpdate, currentCanvasRef]);
|
|
21810
|
+
const handleDistribute = (0, import_react26.useCallback)((axis) => {
|
|
21811
|
+
const selectedNodes = Array.from(selectedIds).map((id2) => nodesRef.current.find((n) => n.id === id2)).filter((n) => n != null);
|
|
21812
|
+
const updates = distributeNodes(selectedNodes, axis);
|
|
21813
|
+
if (updates.length > 0)
|
|
21814
|
+
wrappedOnNodesUpdate(updates, currentCanvasRef);
|
|
21815
|
+
}, [selectedIds, nodesRef, wrappedOnNodesUpdate, currentCanvasRef]);
|
|
21816
|
+
const [contextMenuState, setContextMenuState] = (0, import_react26.useState)(null);
|
|
21817
|
+
(0, import_react26.useEffect)(() => {
|
|
21588
21818
|
setContextMenuState(null);
|
|
21589
21819
|
}, [currentCanvasRef]);
|
|
21590
|
-
const handleContextMenu = (0,
|
|
21820
|
+
const handleContextMenu = (0, import_react26.useCallback)((event) => {
|
|
21591
21821
|
onContextMenu?.(event);
|
|
21592
|
-
if (!nodeContextMenu)
|
|
21822
|
+
if (!nodeContextMenu && !alignDistributeMenu)
|
|
21593
21823
|
return;
|
|
21594
21824
|
if (event.type !== "node")
|
|
21595
21825
|
return;
|
|
21596
21826
|
const node = event.target;
|
|
21597
21827
|
if (!node)
|
|
21598
21828
|
return;
|
|
21599
|
-
const
|
|
21600
|
-
|
|
21601
|
-
|
|
21829
|
+
const matchCtx = { canvasRef: currentCanvasRef ?? null };
|
|
21830
|
+
const matched = nodeContextMenu ? filterContextMenuItems(nodeContextMenu.items, node, matchCtx) : [];
|
|
21831
|
+
if (alignDistributeMenu && selectedIds.size >= 2 && selectedIds.has(node.id)) {
|
|
21832
|
+
const canDistribute = selectedIds.size >= 3;
|
|
21833
|
+
const builtins = [
|
|
21834
|
+
{ id: "__sys_align_left__", label: "Align Left" },
|
|
21835
|
+
{ id: "__sys_align_right__", label: "Align Right" },
|
|
21836
|
+
{ id: "__sys_align_top__", label: "Align Top" },
|
|
21837
|
+
{ id: "__sys_align_bottom__", label: "Align Bottom" },
|
|
21838
|
+
{ id: "__sys_align_centerH__", label: "Align Center Horizontal" },
|
|
21839
|
+
{ id: "__sys_align_centerV__", label: "Align Center Vertical" },
|
|
21840
|
+
{
|
|
21841
|
+
id: "__sys_distribute_h__",
|
|
21842
|
+
label: "Distribute Horizontally",
|
|
21843
|
+
disabled: canDistribute ? void 0 : () => !canDistribute
|
|
21844
|
+
},
|
|
21845
|
+
{
|
|
21846
|
+
id: "__sys_distribute_v__",
|
|
21847
|
+
label: "Distribute Vertically",
|
|
21848
|
+
disabled: canDistribute ? void 0 : () => !canDistribute
|
|
21849
|
+
}
|
|
21850
|
+
];
|
|
21851
|
+
matched.push(...builtins);
|
|
21852
|
+
}
|
|
21602
21853
|
if (matched.length === 0) {
|
|
21603
21854
|
setContextMenuState(null);
|
|
21604
21855
|
return;
|
|
@@ -21609,7 +21860,48 @@ var SystemCanvas = (() => {
|
|
|
21609
21860
|
screenPosition: event.screenPosition,
|
|
21610
21861
|
canvasRef: currentCanvasRef ?? null
|
|
21611
21862
|
});
|
|
21612
|
-
}, [onContextMenu, nodeContextMenu, currentCanvasRef]);
|
|
21863
|
+
}, [onContextMenu, nodeContextMenu, currentCanvasRef, alignDistributeMenu, selectedIds]);
|
|
21864
|
+
const effectiveNodeContextMenu = (0, import_react26.useMemo)(() => {
|
|
21865
|
+
if (!nodeContextMenu && !alignDistributeMenu)
|
|
21866
|
+
return null;
|
|
21867
|
+
const baseItems = nodeContextMenu?.items ?? [];
|
|
21868
|
+
const wrappedOnSelect = (itemId, node, ctx) => {
|
|
21869
|
+
if (itemId === "__sys_align_left__") {
|
|
21870
|
+
handleAlign("left");
|
|
21871
|
+
return;
|
|
21872
|
+
}
|
|
21873
|
+
if (itemId === "__sys_align_right__") {
|
|
21874
|
+
handleAlign("right");
|
|
21875
|
+
return;
|
|
21876
|
+
}
|
|
21877
|
+
if (itemId === "__sys_align_top__") {
|
|
21878
|
+
handleAlign("top");
|
|
21879
|
+
return;
|
|
21880
|
+
}
|
|
21881
|
+
if (itemId === "__sys_align_bottom__") {
|
|
21882
|
+
handleAlign("bottom");
|
|
21883
|
+
return;
|
|
21884
|
+
}
|
|
21885
|
+
if (itemId === "__sys_align_centerH__") {
|
|
21886
|
+
handleAlign("centerH");
|
|
21887
|
+
return;
|
|
21888
|
+
}
|
|
21889
|
+
if (itemId === "__sys_align_centerV__") {
|
|
21890
|
+
handleAlign("centerV");
|
|
21891
|
+
return;
|
|
21892
|
+
}
|
|
21893
|
+
if (itemId === "__sys_distribute_h__") {
|
|
21894
|
+
handleDistribute("horizontal");
|
|
21895
|
+
return;
|
|
21896
|
+
}
|
|
21897
|
+
if (itemId === "__sys_distribute_v__") {
|
|
21898
|
+
handleDistribute("vertical");
|
|
21899
|
+
return;
|
|
21900
|
+
}
|
|
21901
|
+
nodeContextMenu?.onSelect(itemId, node, ctx);
|
|
21902
|
+
};
|
|
21903
|
+
return { items: baseItems, onSelect: wrappedOnSelect };
|
|
21904
|
+
}, [nodeContextMenu, alignDistributeMenu, handleAlign, handleDistribute]);
|
|
21613
21905
|
const { handleNodeClick, handleNodeDoubleClick, handleNodeNavigate, handleEdgeClick, handleEdgeDoubleClick, handleCanvasClick, handleCanvasContextMenu, handleNodeContextMenu, handleEdgeContextMenu } = useCanvasInteraction({
|
|
21614
21906
|
onNodeClick,
|
|
21615
21907
|
onNodeDoubleClick,
|
|
@@ -21630,27 +21922,27 @@ var SystemCanvas = (() => {
|
|
|
21630
21922
|
onSelectEdge: setSelectedEdgeId,
|
|
21631
21923
|
onBeginEditEdge: handleBeginEditEdge
|
|
21632
21924
|
});
|
|
21633
|
-
const handleEditorCommit = (0,
|
|
21925
|
+
const handleEditorCommit = (0, import_react26.useCallback)((patch) => {
|
|
21634
21926
|
if (editingId) {
|
|
21635
21927
|
wrappedOnNodeUpdate(editingId, patch, currentCanvasRef);
|
|
21636
21928
|
}
|
|
21637
21929
|
setEditingId(null);
|
|
21638
21930
|
}, [editingId, wrappedOnNodeUpdate, currentCanvasRef]);
|
|
21639
|
-
const handleEditorCancel = (0,
|
|
21931
|
+
const handleEditorCancel = (0, import_react26.useCallback)(() => {
|
|
21640
21932
|
setEditingId(null);
|
|
21641
21933
|
}, []);
|
|
21642
|
-
const handleEdgeEditorCommit = (0,
|
|
21934
|
+
const handleEdgeEditorCommit = (0, import_react26.useCallback)((patch) => {
|
|
21643
21935
|
if (editingEdgeId) {
|
|
21644
21936
|
wrappedOnEdgeUpdate(editingEdgeId, patch, currentCanvasRef);
|
|
21645
21937
|
}
|
|
21646
21938
|
setEditingEdgeId(null);
|
|
21647
21939
|
}, [editingEdgeId, wrappedOnEdgeUpdate, currentCanvasRef]);
|
|
21648
|
-
const handleEdgeEditorCancel = (0,
|
|
21940
|
+
const handleEdgeEditorCancel = (0, import_react26.useCallback)(() => {
|
|
21649
21941
|
setEditingEdgeId(null);
|
|
21650
21942
|
}, []);
|
|
21651
|
-
const lastAddRef = (0,
|
|
21652
|
-
const menuOptions = (0,
|
|
21653
|
-
const addNode2 = (0,
|
|
21943
|
+
const lastAddRef = (0, import_react26.useRef)(null);
|
|
21944
|
+
const menuOptions = (0, import_react26.useMemo)(() => getNodeMenuOptions(currentCanvas, theme), [currentCanvas, theme]);
|
|
21945
|
+
const addNode2 = (0, import_react26.useCallback)((option, position) => {
|
|
21654
21946
|
let x, y;
|
|
21655
21947
|
if (position) {
|
|
21656
21948
|
x = position.x;
|
|
@@ -21717,14 +22009,14 @@ var SystemCanvas = (() => {
|
|
|
21717
22009
|
cancelDrag
|
|
21718
22010
|
});
|
|
21719
22011
|
const renderProps = { options: menuOptions, addNode: addNode2, theme };
|
|
21720
|
-
return (0,
|
|
22012
|
+
return (0, import_jsx_runtime29.jsxs)("div", { ref: containerRef, className: `system-canvas ${className ?? ""}`, tabIndex: editable ? 0 : -1, onKeyDown: handleKeyDown, style: {
|
|
21721
22013
|
position: "relative",
|
|
21722
22014
|
width: "100%",
|
|
21723
22015
|
height: "100%",
|
|
21724
22016
|
overflow: "hidden",
|
|
21725
22017
|
outline: "none",
|
|
21726
22018
|
...style
|
|
21727
|
-
}, children: [(0,
|
|
22019
|
+
}, children: [(0, import_jsx_runtime29.jsx)(Breadcrumbs, { breadcrumbs, theme: theme.breadcrumbs, onNavigate: navigateToBreadcrumb }), isLoading && (0, import_jsx_runtime29.jsx)("div", { className: "system-canvas-loading", style: {
|
|
21728
22020
|
position: "absolute",
|
|
21729
22021
|
top: 12,
|
|
21730
22022
|
right: 12,
|
|
@@ -21736,7 +22028,7 @@ var SystemCanvas = (() => {
|
|
|
21736
22028
|
fontFamily: theme.node.fontFamily,
|
|
21737
22029
|
fontSize: 12,
|
|
21738
22030
|
backdropFilter: "blur(8px)"
|
|
21739
|
-
}, children: "Loading..." }), (0,
|
|
22031
|
+
}, children: "Loading..." }), (0, import_jsx_runtime29.jsx)(Viewport, { ref: viewportHandleRef, nodes, edges, nodeMap, theme, edgeStyle, columns: currentCanvas.columns, rows: currentCanvas.rows, canvases, minZoom: effectiveMinZoom, maxZoom: effectiveMaxZoom, defaultViewport, autoFit, canvasRef: currentCanvasRef, handoffTransform: pendingHandoff, onHandoffApplied: handleHandoffApplied, handoffFadeMs: zoomNavConfig.fadeDuration, onViewportChange: handleViewportChange, onNodeClick: handleNodeClick, onNodeDoubleClick: handleNodeDoubleClick, onNodeNavigate: handleNodeNavigate, onEdgeClick: handleEdgeClick, onEdgeDoubleClick: handleEdgeDoubleClick, onCanvasClick: editable ? handleCanvasClick : void 0, onCanvasContextMenu: handleCanvasContextMenu, onNodeContextMenu: handleNodeContextMenu, onEdgeContextMenu: handleEdgeContextMenu, onNodePointerDown: editable ? onNodePointerDown : void 0, selectedIds: editable ? selectedIds : void 0, marqueeRect: editable ? marqueeRect : null, marqueeActiveRef: editable ? marqueeActiveRef : void 0, editingId: editable ? editingId : null, selectedEdgeId: editable ? selectedEdgeId : null, editingEdgeId: editable ? editingEdgeId : null, dragOverrides, dropTargetId, resizeOverrides, onResizeHandlePointerDown: editable ? onResizeHandlePointerDown : void 0, onEditorCommit: handleEditorCommit, onEditorCancel: handleEditorCancel, onEdgeEditorCommit: handleEdgeEditorCommit, onEdgeEditorCancel: handleEdgeEditorCancel, pendingEdge: editable ? pendingEdge : null, onConnectionHandlePointerDown: editable ? onConnectionHandlePointerDown : void 0, edgeCreateEnabled: editable, alignmentGuides: editable ? alignmentGuides : void 0 }), showLaneHeaders && (0, import_jsx_runtime29.jsx)(LaneHeaders, { columns: currentCanvas.columns, rows: currentCanvas.rows, theme, getViewport: getViewportState, width: containerSize.width, height: containerSize.height, pinned: laneHeaders === "pinned" }), editable && showNodeToolbar && selectedIds.size === 1 && selectedResolvedNode && !editingId && (0, import_jsx_runtime29.jsx)(NodeToolbar, { node: selectedResolvedNode, theme, onPatch: (update) => {
|
|
21740
22032
|
wrappedOnNodeUpdate(selectedResolvedNode.id, update, currentCanvasRef);
|
|
21741
22033
|
}, onDelete: () => {
|
|
21742
22034
|
wrappedOnNodeDelete(selectedResolvedNode.id, currentCanvasRef);
|
|
@@ -21746,7 +22038,7 @@ var SystemCanvas = (() => {
|
|
|
21746
22038
|
if (selectedResolvedNodes.length === 0)
|
|
21747
22039
|
return null;
|
|
21748
22040
|
const anchorNode = selectedResolvedNodes[0];
|
|
21749
|
-
return (0,
|
|
22041
|
+
return (0, import_jsx_runtime29.jsx)(NodeToolbar, { node: anchorNode, selectedNodes: selectedResolvedNodes, theme, onPatch: () => {
|
|
21750
22042
|
}, onMultiPatch: (patch) => {
|
|
21751
22043
|
for (const id2 of selectedIds) {
|
|
21752
22044
|
wrappedOnNodeUpdate(id2, patch, currentCanvasRef);
|
|
@@ -21754,8 +22046,8 @@ var SystemCanvas = (() => {
|
|
|
21754
22046
|
}, onDelete: () => {
|
|
21755
22047
|
wrappedOnNodesDelete(Array.from(selectedIds), currentCanvasRef);
|
|
21756
22048
|
clearSelection();
|
|
21757
|
-
}, getViewport: getViewportState, containerWidth: containerSize.width, containerHeight: containerSize.height });
|
|
21758
|
-
})(), editable && (renderAddNodeButton ? renderAddNodeButton(renderProps) : (0,
|
|
22049
|
+
}, getViewport: getViewportState, containerWidth: containerSize.width, containerHeight: containerSize.height, onAlign: handleAlign, onDistribute: handleDistribute });
|
|
22050
|
+
})(), editable && (renderAddNodeButton ? renderAddNodeButton(renderProps) : (0, import_jsx_runtime29.jsx)(AddNodeButton, { ...renderProps })), effectiveNodeContextMenu && (0, import_jsx_runtime29.jsx)(NodeContextMenuOverlay, { state: contextMenuState, config: effectiveNodeContextMenu, theme, onClose: () => setContextMenuState(null) })] });
|
|
21759
22051
|
});
|
|
21760
22052
|
|
|
21761
22053
|
// src/index.tsx
|
|
@@ -21866,7 +22158,7 @@ var SystemCanvas = (() => {
|
|
|
21866
22158
|
onEdgeUpdate: handleEdgeUpdate,
|
|
21867
22159
|
onEdgeDelete: handleEdgeDelete
|
|
21868
22160
|
};
|
|
21869
|
-
root2.render(
|
|
22161
|
+
root2.render(import_react27.default.createElement(SystemCanvas, props));
|
|
21870
22162
|
};
|
|
21871
22163
|
doRender();
|
|
21872
22164
|
return {
|