system-canvas-standalone 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/system-canvas.js +660 -205
- package/dist/system-canvas.js.map +1 -1
- package/dist/system-canvas.min.js +9 -9
- 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_react24 = __toESM(require_react(), 1);
|
|
12763
12763
|
var import_client = __toESM(require_client(), 1);
|
|
12764
12764
|
|
|
12765
12765
|
// ../react/dist/components/SystemCanvas.js
|
|
12766
12766
|
var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1);
|
|
12767
|
-
var
|
|
12767
|
+
var import_react23 = __toESM(require_react(), 1);
|
|
12768
12768
|
|
|
12769
12769
|
// ../core/dist/themes/dark.js
|
|
12770
12770
|
var darkTheme = {
|
|
@@ -14649,15 +14649,19 @@ var SystemCanvas = (() => {
|
|
|
14649
14649
|
// ../react/dist/hooks/useCanvasInteraction.js
|
|
14650
14650
|
var import_react2 = __toESM(require_react(), 1);
|
|
14651
14651
|
function useCanvasInteraction(options) {
|
|
14652
|
-
const { onNodeClick, onNodeDoubleClick, onEdgeClick, onEdgeDoubleClick, onContextMenu, onNavigableNodeClick, viewport, editable, onSelect, onBeginEdit, onSelectEdge, onBeginEditEdge } = options;
|
|
14652
|
+
const { onNodeClick, onNodeDoubleClick, onEdgeClick, onEdgeDoubleClick, onContextMenu, onNavigableNodeClick, viewport, editable, onSelect, onToggleSelect, onBeginEdit, onSelectEdge, onBeginEditEdge } = options;
|
|
14653
14653
|
const handleNodeClick = (0, import_react2.useCallback)((node, event) => {
|
|
14654
14654
|
event.stopPropagation();
|
|
14655
14655
|
if (editable) {
|
|
14656
|
-
|
|
14657
|
-
|
|
14656
|
+
if (event.shiftKey && onToggleSelect) {
|
|
14657
|
+
onToggleSelect(node.id);
|
|
14658
|
+
} else {
|
|
14659
|
+
onSelect?.(node.id);
|
|
14660
|
+
onSelectEdge?.(null);
|
|
14661
|
+
}
|
|
14658
14662
|
}
|
|
14659
14663
|
onNodeClick?.(node);
|
|
14660
|
-
}, [editable, onNodeClick, onSelect, onSelectEdge]);
|
|
14664
|
+
}, [editable, onNodeClick, onSelect, onToggleSelect, onSelectEdge]);
|
|
14661
14665
|
const handleNodeDoubleClick = (0, import_react2.useCallback)((node, event) => {
|
|
14662
14666
|
event.stopPropagation();
|
|
14663
14667
|
onNodeDoubleClick?.(node);
|
|
@@ -14736,7 +14740,7 @@ var SystemCanvas = (() => {
|
|
|
14736
14740
|
var import_react3 = __toESM(require_react(), 1);
|
|
14737
14741
|
var DRAG_THRESHOLD = 3;
|
|
14738
14742
|
function useNodeDrag(options) {
|
|
14739
|
-
const { viewport, nodesRef, onCommit, svgRef, canDropNodeOn, onNodeDrop } = options;
|
|
14743
|
+
const { viewport, nodesRef, onCommit, svgRef, canDropNodeOn, onNodeDrop, selectedIdsRef } = options;
|
|
14740
14744
|
const [dragOverrides, setDragOverrides] = (0, import_react3.useState)(() => /* @__PURE__ */ new Map());
|
|
14741
14745
|
const [isDragging, setIsDragging] = (0, import_react3.useState)(false);
|
|
14742
14746
|
const [dropTargetId, setDropTargetId] = (0, import_react3.useState)(null);
|
|
@@ -14748,6 +14752,8 @@ var SystemCanvas = (() => {
|
|
|
14748
14752
|
onNodeDropRef.current = onNodeDrop;
|
|
14749
14753
|
const svgRefRef = (0, import_react3.useRef)(svgRef);
|
|
14750
14754
|
svgRefRef.current = svgRef;
|
|
14755
|
+
const emptySetRef = (0, import_react3.useRef)(/* @__PURE__ */ new Set());
|
|
14756
|
+
const effectiveSelectedIdsRef = selectedIdsRef ?? emptySetRef;
|
|
14751
14757
|
const dropTargetIdRef = (0, import_react3.useRef)(null);
|
|
14752
14758
|
const computeDropTarget = (0, import_react3.useCallback)((clientX, clientY) => {
|
|
14753
14759
|
const cb = canDropNodeOnRef.current;
|
|
@@ -14869,12 +14875,22 @@ var SystemCanvas = (() => {
|
|
|
14869
14875
|
return;
|
|
14870
14876
|
event.stopPropagation();
|
|
14871
14877
|
const moving = /* @__PURE__ */ new Map();
|
|
14872
|
-
|
|
14873
|
-
if (
|
|
14874
|
-
const
|
|
14875
|
-
|
|
14876
|
-
if (
|
|
14877
|
-
moving.set(
|
|
14878
|
+
const sel = effectiveSelectedIdsRef.current;
|
|
14879
|
+
if (sel && sel.size > 1 && sel.has(node.id) && nodesRef.current) {
|
|
14880
|
+
for (const id2 of sel) {
|
|
14881
|
+
const n = nodesRef.current.find((r) => r.id === id2);
|
|
14882
|
+
if (n) {
|
|
14883
|
+
moving.set(id2, { startX: n.x, startY: n.y });
|
|
14884
|
+
}
|
|
14885
|
+
}
|
|
14886
|
+
} else {
|
|
14887
|
+
moving.set(node.id, { startX: node.x, startY: node.y });
|
|
14888
|
+
if (node.type === "group" && nodesRef.current) {
|
|
14889
|
+
const children2 = getGroupChildren(node, nodesRef.current);
|
|
14890
|
+
for (const c of children2) {
|
|
14891
|
+
if (!moving.has(c.id)) {
|
|
14892
|
+
moving.set(c.id, { startX: c.x, startY: c.y });
|
|
14893
|
+
}
|
|
14878
14894
|
}
|
|
14879
14895
|
}
|
|
14880
14896
|
}
|
|
@@ -15134,8 +15150,305 @@ var SystemCanvas = (() => {
|
|
|
15134
15150
|
return { pending, onHandlePointerDown };
|
|
15135
15151
|
}
|
|
15136
15152
|
|
|
15137
|
-
// ../react/dist/hooks/
|
|
15153
|
+
// ../react/dist/hooks/useMultiSelect.js
|
|
15138
15154
|
var import_react6 = __toESM(require_react(), 1);
|
|
15155
|
+
function useMultiSelect(options) {
|
|
15156
|
+
const { svgRef, viewport, nodesRef, containerRef, enabled } = options;
|
|
15157
|
+
const [selectedIds, setSelectedIds] = (0, import_react6.useState)(() => /* @__PURE__ */ new Set());
|
|
15158
|
+
const [marqueeRect, setMarqueeRect] = (0, import_react6.useState)(null);
|
|
15159
|
+
const marqueeActiveRef = (0, import_react6.useRef)(false);
|
|
15160
|
+
const isDrawingRef = (0, import_react6.useRef)(false);
|
|
15161
|
+
const startScreenRef = (0, import_react6.useRef)(null);
|
|
15162
|
+
const pointerIdRef = (0, import_react6.useRef)(null);
|
|
15163
|
+
const selectedIdsRef = (0, import_react6.useRef)(selectedIds);
|
|
15164
|
+
selectedIdsRef.current = selectedIds;
|
|
15165
|
+
const selectNode = (0, import_react6.useCallback)((id2) => {
|
|
15166
|
+
setSelectedIds(/* @__PURE__ */ new Set([id2]));
|
|
15167
|
+
}, []);
|
|
15168
|
+
const toggleNode = (0, import_react6.useCallback)((id2) => {
|
|
15169
|
+
setSelectedIds((prev) => {
|
|
15170
|
+
const next = new Set(prev);
|
|
15171
|
+
if (next.has(id2)) {
|
|
15172
|
+
next.delete(id2);
|
|
15173
|
+
} else {
|
|
15174
|
+
next.add(id2);
|
|
15175
|
+
}
|
|
15176
|
+
return next;
|
|
15177
|
+
});
|
|
15178
|
+
}, []);
|
|
15179
|
+
const selectAll = (0, import_react6.useCallback)(() => {
|
|
15180
|
+
const nodes = nodesRef.current;
|
|
15181
|
+
if (!nodes)
|
|
15182
|
+
return;
|
|
15183
|
+
setSelectedIds(new Set(nodes.map((n) => n.id)));
|
|
15184
|
+
}, [nodesRef]);
|
|
15185
|
+
const clearSelection = (0, import_react6.useCallback)(() => {
|
|
15186
|
+
setSelectedIds(/* @__PURE__ */ new Set());
|
|
15187
|
+
}, []);
|
|
15188
|
+
(0, import_react6.useEffect)(() => {
|
|
15189
|
+
if (!enabled)
|
|
15190
|
+
return;
|
|
15191
|
+
const container = containerRef.current;
|
|
15192
|
+
if (!container)
|
|
15193
|
+
return;
|
|
15194
|
+
const onKeyDown = (e) => {
|
|
15195
|
+
if (e.code === "Space" && !e.repeat) {
|
|
15196
|
+
const active = document.activeElement;
|
|
15197
|
+
if (active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement || active instanceof HTMLElement && active.isContentEditable) {
|
|
15198
|
+
return;
|
|
15199
|
+
}
|
|
15200
|
+
e.preventDefault();
|
|
15201
|
+
marqueeActiveRef.current = true;
|
|
15202
|
+
}
|
|
15203
|
+
};
|
|
15204
|
+
const onKeyUp = (e) => {
|
|
15205
|
+
if (e.code === "Space") {
|
|
15206
|
+
marqueeActiveRef.current = false;
|
|
15207
|
+
if (isDrawingRef.current) {
|
|
15208
|
+
isDrawingRef.current = false;
|
|
15209
|
+
startScreenRef.current = null;
|
|
15210
|
+
pointerIdRef.current = null;
|
|
15211
|
+
setMarqueeRect(null);
|
|
15212
|
+
}
|
|
15213
|
+
}
|
|
15214
|
+
};
|
|
15215
|
+
container.addEventListener("keydown", onKeyDown);
|
|
15216
|
+
container.addEventListener("keyup", onKeyUp);
|
|
15217
|
+
return () => {
|
|
15218
|
+
container.removeEventListener("keydown", onKeyDown);
|
|
15219
|
+
container.removeEventListener("keyup", onKeyUp);
|
|
15220
|
+
};
|
|
15221
|
+
}, [enabled, containerRef]);
|
|
15222
|
+
(0, import_react6.useEffect)(() => {
|
|
15223
|
+
if (!enabled)
|
|
15224
|
+
return;
|
|
15225
|
+
const container = containerRef.current;
|
|
15226
|
+
if (!container)
|
|
15227
|
+
return;
|
|
15228
|
+
const onKeyDown = (e) => {
|
|
15229
|
+
if ((e.metaKey || e.ctrlKey) && e.key === "a") {
|
|
15230
|
+
const active = document.activeElement;
|
|
15231
|
+
if (active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement || active instanceof HTMLElement && active.isContentEditable) {
|
|
15232
|
+
return;
|
|
15233
|
+
}
|
|
15234
|
+
e.preventDefault();
|
|
15235
|
+
selectAll();
|
|
15236
|
+
}
|
|
15237
|
+
};
|
|
15238
|
+
container.addEventListener("keydown", onKeyDown);
|
|
15239
|
+
return () => {
|
|
15240
|
+
container.removeEventListener("keydown", onKeyDown);
|
|
15241
|
+
};
|
|
15242
|
+
}, [enabled, containerRef, selectAll]);
|
|
15243
|
+
(0, import_react6.useEffect)(() => {
|
|
15244
|
+
if (!enabled)
|
|
15245
|
+
return;
|
|
15246
|
+
const container = containerRef.current;
|
|
15247
|
+
if (!container)
|
|
15248
|
+
return;
|
|
15249
|
+
const onPointerDown = (e) => {
|
|
15250
|
+
if (!marqueeActiveRef.current)
|
|
15251
|
+
return;
|
|
15252
|
+
if (e.button !== 0)
|
|
15253
|
+
return;
|
|
15254
|
+
const target = e.target;
|
|
15255
|
+
if (target && typeof target.closest === "function") {
|
|
15256
|
+
if (target.closest(".system-canvas-node"))
|
|
15257
|
+
return;
|
|
15258
|
+
}
|
|
15259
|
+
const svg = svgRef.current;
|
|
15260
|
+
if (!svg)
|
|
15261
|
+
return;
|
|
15262
|
+
const rect = svg.getBoundingClientRect();
|
|
15263
|
+
const x = e.clientX - rect.left;
|
|
15264
|
+
const y = e.clientY - rect.top;
|
|
15265
|
+
startScreenRef.current = { x, y };
|
|
15266
|
+
isDrawingRef.current = true;
|
|
15267
|
+
pointerIdRef.current = e.pointerId;
|
|
15268
|
+
setMarqueeRect({ x1: x, y1: y, x2: x, y2: y });
|
|
15269
|
+
try {
|
|
15270
|
+
container.setPointerCapture(e.pointerId);
|
|
15271
|
+
} catch {
|
|
15272
|
+
}
|
|
15273
|
+
e.preventDefault();
|
|
15274
|
+
e.stopPropagation();
|
|
15275
|
+
};
|
|
15276
|
+
const onPointerMove = (e) => {
|
|
15277
|
+
if (!isDrawingRef.current)
|
|
15278
|
+
return;
|
|
15279
|
+
if (e.pointerId !== pointerIdRef.current)
|
|
15280
|
+
return;
|
|
15281
|
+
const svg = svgRef.current;
|
|
15282
|
+
if (!svg)
|
|
15283
|
+
return;
|
|
15284
|
+
const rect = svg.getBoundingClientRect();
|
|
15285
|
+
const x = e.clientX - rect.left;
|
|
15286
|
+
const y = e.clientY - rect.top;
|
|
15287
|
+
const start2 = startScreenRef.current;
|
|
15288
|
+
setMarqueeRect({ x1: start2.x, y1: start2.y, x2: x, y2: y });
|
|
15289
|
+
};
|
|
15290
|
+
const onPointerUp = (e) => {
|
|
15291
|
+
if (!isDrawingRef.current)
|
|
15292
|
+
return;
|
|
15293
|
+
if (e.pointerId !== pointerIdRef.current)
|
|
15294
|
+
return;
|
|
15295
|
+
const svg = svgRef.current;
|
|
15296
|
+
if (!svg)
|
|
15297
|
+
return;
|
|
15298
|
+
const rect = svg.getBoundingClientRect();
|
|
15299
|
+
const x = e.clientX - rect.left;
|
|
15300
|
+
const y = e.clientY - rect.top;
|
|
15301
|
+
const start2 = startScreenRef.current;
|
|
15302
|
+
const vp = viewport.current ?? { x: 0, y: 0, zoom: 1 };
|
|
15303
|
+
const topLeft = screenToCanvas(Math.min(start2.x, x), Math.min(start2.y, y), vp);
|
|
15304
|
+
const bottomRight = screenToCanvas(Math.max(start2.x, x), Math.max(start2.y, y), vp);
|
|
15305
|
+
const rectLeft = topLeft.x;
|
|
15306
|
+
const rectTop = topLeft.y;
|
|
15307
|
+
const rectRight = bottomRight.x;
|
|
15308
|
+
const rectBottom = bottomRight.y;
|
|
15309
|
+
const nodes = nodesRef.current ?? [];
|
|
15310
|
+
const matched = /* @__PURE__ */ new Set();
|
|
15311
|
+
for (const node of nodes) {
|
|
15312
|
+
const nRight = node.x + node.width;
|
|
15313
|
+
const nBottom = node.y + node.height;
|
|
15314
|
+
if (node.x < rectRight && nRight > rectLeft && node.y < rectBottom && nBottom > rectTop) {
|
|
15315
|
+
matched.add(node.id);
|
|
15316
|
+
}
|
|
15317
|
+
}
|
|
15318
|
+
setSelectedIds(matched);
|
|
15319
|
+
setMarqueeRect(null);
|
|
15320
|
+
isDrawingRef.current = false;
|
|
15321
|
+
startScreenRef.current = null;
|
|
15322
|
+
pointerIdRef.current = null;
|
|
15323
|
+
try {
|
|
15324
|
+
container.releasePointerCapture(e.pointerId);
|
|
15325
|
+
} catch {
|
|
15326
|
+
}
|
|
15327
|
+
};
|
|
15328
|
+
container.addEventListener("pointerdown", onPointerDown);
|
|
15329
|
+
container.addEventListener("pointermove", onPointerMove);
|
|
15330
|
+
container.addEventListener("pointerup", onPointerUp);
|
|
15331
|
+
return () => {
|
|
15332
|
+
container.removeEventListener("pointerdown", onPointerDown);
|
|
15333
|
+
container.removeEventListener("pointermove", onPointerMove);
|
|
15334
|
+
container.removeEventListener("pointerup", onPointerUp);
|
|
15335
|
+
};
|
|
15336
|
+
}, [enabled, containerRef, svgRef, viewport, nodesRef]);
|
|
15337
|
+
return {
|
|
15338
|
+
selectedIds,
|
|
15339
|
+
selectNode,
|
|
15340
|
+
toggleNode,
|
|
15341
|
+
selectAll,
|
|
15342
|
+
clearSelection,
|
|
15343
|
+
marqueeRect,
|
|
15344
|
+
marqueeActiveRef
|
|
15345
|
+
};
|
|
15346
|
+
}
|
|
15347
|
+
|
|
15348
|
+
// ../react/dist/hooks/useMultiSelectClipboard.js
|
|
15349
|
+
var import_react7 = __toESM(require_react(), 1);
|
|
15350
|
+
var clipboardSnapshot = null;
|
|
15351
|
+
function useMultiSelectClipboard(options) {
|
|
15352
|
+
const { selectedIdsRef, nodesRef, edgesRef, viewport, onNodeAdd, onEdgeAdd, canvasRef, getCursorScreenPos } = options;
|
|
15353
|
+
const getCursorScreenPosRef = (0, import_react7.useRef)(getCursorScreenPos);
|
|
15354
|
+
getCursorScreenPosRef.current = getCursorScreenPos;
|
|
15355
|
+
const onNodeAddRef = (0, import_react7.useRef)(onNodeAdd);
|
|
15356
|
+
onNodeAddRef.current = onNodeAdd;
|
|
15357
|
+
const onEdgeAddRef = (0, import_react7.useRef)(onEdgeAdd);
|
|
15358
|
+
onEdgeAddRef.current = onEdgeAdd;
|
|
15359
|
+
const canvasRefRef = (0, import_react7.useRef)(canvasRef);
|
|
15360
|
+
canvasRefRef.current = canvasRef;
|
|
15361
|
+
(0, import_react7.useEffect)(() => {
|
|
15362
|
+
const handler = (e) => {
|
|
15363
|
+
const active = document.activeElement;
|
|
15364
|
+
if (active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement || active instanceof HTMLElement && active.isContentEditable) {
|
|
15365
|
+
return;
|
|
15366
|
+
}
|
|
15367
|
+
const isMod = e.metaKey || e.ctrlKey;
|
|
15368
|
+
if (isMod && e.key === "c") {
|
|
15369
|
+
const selectedIds = selectedIdsRef.current;
|
|
15370
|
+
if (!selectedIds || selectedIds.size === 0)
|
|
15371
|
+
return;
|
|
15372
|
+
const nodes = nodesRef.current ?? [];
|
|
15373
|
+
const edges = edgesRef.current ?? [];
|
|
15374
|
+
const vp = viewport.current ?? { x: 0, y: 0, zoom: 1 };
|
|
15375
|
+
const copiedNodes = nodes.filter((n) => selectedIds.has(n.id));
|
|
15376
|
+
if (copiedNodes.length === 0)
|
|
15377
|
+
return;
|
|
15378
|
+
const copiedEdges = edges.filter((edge) => selectedIds.has(edge.fromNode) && selectedIds.has(edge.toNode));
|
|
15379
|
+
clipboardSnapshot = {
|
|
15380
|
+
nodes: copiedNodes,
|
|
15381
|
+
edges: copiedEdges,
|
|
15382
|
+
viewportAtCopy: { ...vp }
|
|
15383
|
+
};
|
|
15384
|
+
e.preventDefault();
|
|
15385
|
+
return;
|
|
15386
|
+
}
|
|
15387
|
+
if (isMod && e.key === "v") {
|
|
15388
|
+
if (!clipboardSnapshot)
|
|
15389
|
+
return;
|
|
15390
|
+
const { nodes: srcNodes, edges: srcEdges } = clipboardSnapshot;
|
|
15391
|
+
if (srcNodes.length === 0)
|
|
15392
|
+
return;
|
|
15393
|
+
const oldToNew = /* @__PURE__ */ new Map();
|
|
15394
|
+
for (const n of srcNodes) {
|
|
15395
|
+
oldToNew.set(n.id, generateNodeId());
|
|
15396
|
+
}
|
|
15397
|
+
let minX = Infinity;
|
|
15398
|
+
let minY = Infinity;
|
|
15399
|
+
let maxX = -Infinity;
|
|
15400
|
+
let maxY = -Infinity;
|
|
15401
|
+
for (const n of srcNodes) {
|
|
15402
|
+
minX = Math.min(minX, n.x);
|
|
15403
|
+
minY = Math.min(minY, n.y);
|
|
15404
|
+
maxX = Math.max(maxX, n.x + (n.width ?? 0));
|
|
15405
|
+
maxY = Math.max(maxY, n.y + (n.height ?? 0));
|
|
15406
|
+
}
|
|
15407
|
+
const clusterCx = (minX + maxX) / 2;
|
|
15408
|
+
const clusterCy = (minY + maxY) / 2;
|
|
15409
|
+
const vp = viewport.current ?? { x: 0, y: 0, zoom: 1 };
|
|
15410
|
+
const cursorScreen = getCursorScreenPosRef.current?.();
|
|
15411
|
+
let targetCanvas;
|
|
15412
|
+
if (cursorScreen) {
|
|
15413
|
+
targetCanvas = screenToCanvas(cursorScreen.x, cursorScreen.y, vp);
|
|
15414
|
+
} else {
|
|
15415
|
+
targetCanvas = screenToCanvas(0, 0, vp);
|
|
15416
|
+
targetCanvas = { x: targetCanvas.x + 40, y: targetCanvas.y + 40 };
|
|
15417
|
+
}
|
|
15418
|
+
const dx = targetCanvas.x - clusterCx;
|
|
15419
|
+
const dy = targetCanvas.y - clusterCy;
|
|
15420
|
+
const clonedNodes = srcNodes.map((n) => ({
|
|
15421
|
+
...structuredClone(n),
|
|
15422
|
+
id: oldToNew.get(n.id),
|
|
15423
|
+
x: n.x + dx,
|
|
15424
|
+
y: n.y + dy
|
|
15425
|
+
}));
|
|
15426
|
+
const clonedEdges = srcEdges.filter((edge) => oldToNew.has(edge.fromNode) && oldToNew.has(edge.toNode)).map((edge) => ({
|
|
15427
|
+
...structuredClone(edge),
|
|
15428
|
+
id: generateEdgeId(),
|
|
15429
|
+
fromNode: oldToNew.get(edge.fromNode),
|
|
15430
|
+
toNode: oldToNew.get(edge.toNode)
|
|
15431
|
+
}));
|
|
15432
|
+
const ref = canvasRefRef.current;
|
|
15433
|
+
for (const node of clonedNodes) {
|
|
15434
|
+
onNodeAddRef.current(node, ref);
|
|
15435
|
+
}
|
|
15436
|
+
for (const edge of clonedEdges) {
|
|
15437
|
+
onEdgeAddRef.current(edge, ref);
|
|
15438
|
+
}
|
|
15439
|
+
e.preventDefault();
|
|
15440
|
+
return;
|
|
15441
|
+
}
|
|
15442
|
+
};
|
|
15443
|
+
document.addEventListener("keydown", handler);
|
|
15444
|
+
return () => {
|
|
15445
|
+
document.removeEventListener("keydown", handler);
|
|
15446
|
+
};
|
|
15447
|
+
}, [selectedIdsRef, nodesRef, edgesRef, viewport]);
|
|
15448
|
+
}
|
|
15449
|
+
|
|
15450
|
+
// ../react/dist/hooks/useZoomNavigation.js
|
|
15451
|
+
var import_react8 = __toESM(require_react(), 1);
|
|
15139
15452
|
function expandRect(rect, factor) {
|
|
15140
15453
|
if (factor === 1)
|
|
15141
15454
|
return rect;
|
|
@@ -15173,16 +15486,16 @@ var SystemCanvas = (() => {
|
|
|
15173
15486
|
}
|
|
15174
15487
|
function useZoomNavigation(options) {
|
|
15175
15488
|
const { enabled, config, nodes, currentCanvas, parentFrame, canvases, onResolveCanvas, onSeedCanvas, theme, getViewportSize, getCursorScreenPos, onEnter, onExit } = options;
|
|
15176
|
-
const committingRef = (0,
|
|
15177
|
-
(0,
|
|
15489
|
+
const committingRef = (0, import_react8.useRef)(false);
|
|
15490
|
+
(0, import_react8.useEffect)(() => {
|
|
15178
15491
|
committingRef.current = false;
|
|
15179
15492
|
}, [currentCanvas]);
|
|
15180
|
-
const exitArmedRef = (0,
|
|
15181
|
-
(0,
|
|
15493
|
+
const exitArmedRef = (0, import_react8.useRef)(false);
|
|
15494
|
+
(0, import_react8.useEffect)(() => {
|
|
15182
15495
|
exitArmedRef.current = false;
|
|
15183
15496
|
}, [currentCanvas, parentFrame]);
|
|
15184
|
-
const prefetchRef = (0,
|
|
15185
|
-
const prefetch = (0,
|
|
15497
|
+
const prefetchRef = (0, import_react8.useRef)(/* @__PURE__ */ new Map());
|
|
15498
|
+
const prefetch = (0, import_react8.useCallback)((ref) => {
|
|
15186
15499
|
if (!onResolveCanvas)
|
|
15187
15500
|
return;
|
|
15188
15501
|
if (canvases?.[ref])
|
|
@@ -15200,7 +15513,7 @@ var SystemCanvas = (() => {
|
|
|
15200
15513
|
state.loading = false;
|
|
15201
15514
|
});
|
|
15202
15515
|
}, [canvases, onResolveCanvas, onSeedCanvas]);
|
|
15203
|
-
const handleViewportChange = (0,
|
|
15516
|
+
const handleViewportChange = (0, import_react8.useCallback)((vp) => {
|
|
15204
15517
|
if (!enabled)
|
|
15205
15518
|
return;
|
|
15206
15519
|
if (committingRef.current)
|
|
@@ -15339,7 +15652,7 @@ var SystemCanvas = (() => {
|
|
|
15339
15652
|
onEnter,
|
|
15340
15653
|
onExit
|
|
15341
15654
|
]);
|
|
15342
|
-
const clearCommitting = (0,
|
|
15655
|
+
const clearCommitting = (0, import_react8.useCallback)(() => {
|
|
15343
15656
|
committingRef.current = false;
|
|
15344
15657
|
}, []);
|
|
15345
15658
|
return { handleViewportChange, clearCommitting };
|
|
@@ -15347,10 +15660,10 @@ var SystemCanvas = (() => {
|
|
|
15347
15660
|
|
|
15348
15661
|
// ../react/dist/components/Viewport.js
|
|
15349
15662
|
var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1);
|
|
15350
|
-
var
|
|
15663
|
+
var import_react17 = __toESM(require_react(), 1);
|
|
15351
15664
|
|
|
15352
15665
|
// ../react/dist/hooks/useViewport.js
|
|
15353
|
-
var
|
|
15666
|
+
var import_react9 = __toESM(require_react(), 1);
|
|
15354
15667
|
|
|
15355
15668
|
// ../../node_modules/d3-dispatch/src/dispatch.js
|
|
15356
15669
|
var noop = { value: () => {
|
|
@@ -18092,19 +18405,21 @@ var SystemCanvas = (() => {
|
|
|
18092
18405
|
|
|
18093
18406
|
// ../react/dist/hooks/useViewport.js
|
|
18094
18407
|
function useViewport(options) {
|
|
18095
|
-
const { minZoom, maxZoom, defaultViewport, onViewportChange } = options;
|
|
18096
|
-
const svgRef = (0,
|
|
18097
|
-
const groupRef = (0,
|
|
18098
|
-
const viewport = (0,
|
|
18099
|
-
const zoomBehaviorRef = (0,
|
|
18100
|
-
const onViewportChangeRef = (0,
|
|
18408
|
+
const { minZoom, maxZoom, defaultViewport, onViewportChange, marqueeActiveRef } = options;
|
|
18409
|
+
const svgRef = (0, import_react9.useRef)(null);
|
|
18410
|
+
const groupRef = (0, import_react9.useRef)(null);
|
|
18411
|
+
const viewport = (0, import_react9.useRef)(defaultViewport ?? { x: 0, y: 0, zoom: 1 });
|
|
18412
|
+
const zoomBehaviorRef = (0, import_react9.useRef)(null);
|
|
18413
|
+
const onViewportChangeRef = (0, import_react9.useRef)(onViewportChange);
|
|
18101
18414
|
onViewportChangeRef.current = onViewportChange;
|
|
18102
|
-
(0,
|
|
18415
|
+
(0, import_react9.useEffect)(() => {
|
|
18103
18416
|
const svg = svgRef.current;
|
|
18104
18417
|
const group = groupRef.current;
|
|
18105
18418
|
if (!svg || !group)
|
|
18106
18419
|
return;
|
|
18107
18420
|
const zoomBehavior = zoom_default2().scaleExtent([minZoom, maxZoom]).filter((event) => {
|
|
18421
|
+
if (marqueeActiveRef?.current && event.type !== "wheel")
|
|
18422
|
+
return false;
|
|
18108
18423
|
if (event.button)
|
|
18109
18424
|
return false;
|
|
18110
18425
|
if (event.type === "wheel")
|
|
@@ -18137,7 +18452,7 @@ var SystemCanvas = (() => {
|
|
|
18137
18452
|
selection2.on(".zoom", null);
|
|
18138
18453
|
};
|
|
18139
18454
|
}, [minZoom, maxZoom]);
|
|
18140
|
-
const fitToContent = (0,
|
|
18455
|
+
const fitToContent = (0, import_react9.useCallback)((nodes, animate = true) => {
|
|
18141
18456
|
const svg = svgRef.current;
|
|
18142
18457
|
if (!svg || !zoomBehaviorRef.current || nodes.length === 0)
|
|
18143
18458
|
return;
|
|
@@ -18150,13 +18465,13 @@ var SystemCanvas = (() => {
|
|
|
18150
18465
|
select_default2(svg).call(zoomBehaviorRef.current.transform, t);
|
|
18151
18466
|
}
|
|
18152
18467
|
}, []);
|
|
18153
|
-
const resetZoom = (0,
|
|
18468
|
+
const resetZoom = (0, import_react9.useCallback)(() => {
|
|
18154
18469
|
const svg = svgRef.current;
|
|
18155
18470
|
if (!svg || !zoomBehaviorRef.current)
|
|
18156
18471
|
return;
|
|
18157
18472
|
select_default2(svg).transition().duration(400).call(zoomBehaviorRef.current.transform, identity2);
|
|
18158
18473
|
}, []);
|
|
18159
|
-
const setTransform = (0,
|
|
18474
|
+
const setTransform = (0, import_react9.useCallback)((transform2, options2) => {
|
|
18160
18475
|
const svg = svgRef.current;
|
|
18161
18476
|
if (!svg || !zoomBehaviorRef.current)
|
|
18162
18477
|
return;
|
|
@@ -18168,7 +18483,7 @@ var SystemCanvas = (() => {
|
|
|
18168
18483
|
sel.call(zoomBehaviorRef.current.transform, t);
|
|
18169
18484
|
}
|
|
18170
18485
|
}, []);
|
|
18171
|
-
const zoomToNode = (0,
|
|
18486
|
+
const zoomToNode = (0, import_react9.useCallback)((node, onComplete, options2) => {
|
|
18172
18487
|
const svg = svgRef.current;
|
|
18173
18488
|
if (!svg || !zoomBehaviorRef.current) {
|
|
18174
18489
|
onComplete?.();
|
|
@@ -18362,9 +18677,9 @@ var SystemCanvas = (() => {
|
|
|
18362
18677
|
|
|
18363
18678
|
// ../react/dist/components/RefIndicator.js
|
|
18364
18679
|
var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
|
|
18365
|
-
var
|
|
18680
|
+
var import_react10 = __toESM(require_react(), 1);
|
|
18366
18681
|
function RefIndicator({ node, theme, nodeX, nodeY, nodeWidth, nodeHeight, strokeColor, strokeWidth, corner = "bottom-right", size: sizeProp, onNavigate }) {
|
|
18367
|
-
const [hover, setHover] = (0,
|
|
18682
|
+
const [hover, setHover] = (0, import_react10.useState)(false);
|
|
18368
18683
|
const iconKind = theme.node.refIndicator.icon;
|
|
18369
18684
|
if (iconKind === "none")
|
|
18370
18685
|
return null;
|
|
@@ -18435,7 +18750,7 @@ var SystemCanvas = (() => {
|
|
|
18435
18750
|
|
|
18436
18751
|
// ../react/dist/components/CategorySlotsLayer.js
|
|
18437
18752
|
var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1);
|
|
18438
|
-
var
|
|
18753
|
+
var import_react12 = __toESM(require_react(), 1);
|
|
18439
18754
|
|
|
18440
18755
|
// ../react/dist/primitives/NodeColorFill.js
|
|
18441
18756
|
var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -18555,9 +18870,9 @@ var SystemCanvas = (() => {
|
|
|
18555
18870
|
|
|
18556
18871
|
// ../react/dist/primitives/NodeText.js
|
|
18557
18872
|
var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
|
|
18558
|
-
var
|
|
18873
|
+
var import_react11 = __toESM(require_react(), 1);
|
|
18559
18874
|
function NodeText({ region, value, theme, color: color2, fill, align = "start", fontWeight = 500, uppercase = false, useLabelFont = false, fontFamily, fontSize: fontSizeProp, wrap = false, maxLines, lineHeight: lineHeightProp, verticalAlign = "top" }) {
|
|
18560
|
-
const reactId = (0,
|
|
18875
|
+
const reactId = (0, import_react11.useId)();
|
|
18561
18876
|
const safeId = reactId.replace(/:/g, "");
|
|
18562
18877
|
if (!value)
|
|
18563
18878
|
return null;
|
|
@@ -18631,8 +18946,8 @@ var SystemCanvas = (() => {
|
|
|
18631
18946
|
// ../react/dist/components/CategorySlotsLayer.js
|
|
18632
18947
|
function CategorySlotsLayer({ node, theme, canvases, slots: slotsProp }) {
|
|
18633
18948
|
const slots = slotsProp ?? getCategorySlots(node, theme);
|
|
18634
|
-
const regions = (0,
|
|
18635
|
-
const reactId = (0,
|
|
18949
|
+
const regions = (0, import_react12.useMemo)(() => computeCategorySlotRegions(node, theme, slots), [node, theme, slots]);
|
|
18950
|
+
const reactId = (0, import_react12.useId)();
|
|
18636
18951
|
const clipId = `sc-edge-clip-${reactId.replace(/:/g, "")}`;
|
|
18637
18952
|
if (!slots)
|
|
18638
18953
|
return null;
|
|
@@ -18865,7 +19180,7 @@ var SystemCanvas = (() => {
|
|
|
18865
19180
|
|
|
18866
19181
|
// ../react/dist/components/ResizeHandles.js
|
|
18867
19182
|
var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
|
|
18868
|
-
var
|
|
19183
|
+
var import_react13 = __toESM(require_react(), 1);
|
|
18869
19184
|
var HANDLE_SIZE = 7;
|
|
18870
19185
|
var CORNERS = [
|
|
18871
19186
|
{ corner: "nw", cursor: "nwse-resize", anchor: "nw" },
|
|
@@ -18876,7 +19191,7 @@ var SystemCanvas = (() => {
|
|
|
18876
19191
|
var cornerInset = (cornerRadius) => Math.min(cornerRadius * 0.25, 3);
|
|
18877
19192
|
function ResizeHandles({ node, theme, onHandlePointerDown }) {
|
|
18878
19193
|
const { x, y, width, height } = node;
|
|
18879
|
-
const [hoveredCorner, setHoveredCorner] = (0,
|
|
19194
|
+
const [hoveredCorner, setHoveredCorner] = (0, import_react13.useState)(null);
|
|
18880
19195
|
const handleColor = node.resolvedStroke ?? theme.node.labelColor;
|
|
18881
19196
|
const i = cornerInset(node.resolvedCornerRadius);
|
|
18882
19197
|
const anchorPos = (anchor) => {
|
|
@@ -18901,7 +19216,7 @@ var SystemCanvas = (() => {
|
|
|
18901
19216
|
}
|
|
18902
19217
|
|
|
18903
19218
|
// ../react/dist/components/NodeRenderer.js
|
|
18904
|
-
function NodeRenderer({ nodes, theme, onClick, onDoubleClick, onContextMenu, onNavigate, onPointerDown,
|
|
19219
|
+
function NodeRenderer({ nodes, theme, onClick, onDoubleClick, onContextMenu, onNavigate, onPointerDown, selectedIds, editingId, onResizeHandlePointerDown, canvases, only }) {
|
|
18905
19220
|
const groups = nodes.filter((n) => n.type === "group");
|
|
18906
19221
|
const others = nodes.filter((n) => n.type !== "group");
|
|
18907
19222
|
const common = (node) => {
|
|
@@ -18917,7 +19232,7 @@ var SystemCanvas = (() => {
|
|
|
18917
19232
|
onContextMenu,
|
|
18918
19233
|
onNavigate,
|
|
18919
19234
|
onPointerDown,
|
|
18920
|
-
isSelected:
|
|
19235
|
+
isSelected: selectedIds?.has(node.id) ?? false,
|
|
18921
19236
|
isEditing: editingId === node.id,
|
|
18922
19237
|
slots,
|
|
18923
19238
|
canvases,
|
|
@@ -18928,7 +19243,8 @@ var SystemCanvas = (() => {
|
|
|
18928
19243
|
refCorner
|
|
18929
19244
|
};
|
|
18930
19245
|
};
|
|
18931
|
-
const
|
|
19246
|
+
const singleSelectedId = selectedIds?.size === 1 ? Array.from(selectedIds)[0] : null;
|
|
19247
|
+
const selectedNode = singleSelectedId && editingId !== singleSelectedId ? nodes.find((n) => n.id === singleSelectedId) : void 0;
|
|
18932
19248
|
const renderResizeHandles = only !== "groups" && selectedNode && onResizeHandlePointerDown;
|
|
18933
19249
|
return (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [only !== "non-groups" && groups.map((node) => (0, import_jsx_runtime15.jsx)(GroupNode, { ...common(node) }, node.id)), only !== "groups" && others.map((node) => {
|
|
18934
19250
|
const Component = getNodeComponent(node.type);
|
|
@@ -18986,7 +19302,7 @@ var SystemCanvas = (() => {
|
|
|
18986
19302
|
|
|
18987
19303
|
// ../react/dist/components/NodeEditor.js
|
|
18988
19304
|
var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
|
|
18989
|
-
var
|
|
19305
|
+
var import_react14 = __toESM(require_react(), 1);
|
|
18990
19306
|
function NodeEditor({ node, theme, onCommit, onCancel }) {
|
|
18991
19307
|
const editableFields = useCategoryFields(node, theme);
|
|
18992
19308
|
if (editableFields) {
|
|
@@ -19005,11 +19321,11 @@ var SystemCanvas = (() => {
|
|
|
19005
19321
|
}
|
|
19006
19322
|
function SingleFieldEditor({ node, theme, onCommit, onCancel }) {
|
|
19007
19323
|
const initial = getInitialValue(node);
|
|
19008
|
-
const [value, setValue] = (0,
|
|
19009
|
-
const textareaRef = (0,
|
|
19010
|
-
const inputRef = (0,
|
|
19011
|
-
const committedRef = (0,
|
|
19012
|
-
(0,
|
|
19324
|
+
const [value, setValue] = (0, import_react14.useState)(initial);
|
|
19325
|
+
const textareaRef = (0, import_react14.useRef)(null);
|
|
19326
|
+
const inputRef = (0, import_react14.useRef)(null);
|
|
19327
|
+
const committedRef = (0, import_react14.useRef)(false);
|
|
19328
|
+
(0, import_react14.useEffect)(() => {
|
|
19013
19329
|
const el = textareaRef.current ?? inputRef.current;
|
|
19014
19330
|
if (el) {
|
|
19015
19331
|
el.focus();
|
|
@@ -19105,10 +19421,10 @@ var SystemCanvas = (() => {
|
|
|
19105
19421
|
}
|
|
19106
19422
|
}
|
|
19107
19423
|
function FormEditor({ node, theme, fields, onCommit, onCancel }) {
|
|
19108
|
-
const initial = (0,
|
|
19109
|
-
const [values, setValues] = (0,
|
|
19110
|
-
const committedRef = (0,
|
|
19111
|
-
const panelRef = (0,
|
|
19424
|
+
const initial = (0, import_react14.useMemo)(() => readInitialValues(node, fields), [node, fields]);
|
|
19425
|
+
const [values, setValues] = (0, import_react14.useState)(initial);
|
|
19426
|
+
const committedRef = (0, import_react14.useRef)(false);
|
|
19427
|
+
const panelRef = (0, import_react14.useRef)(null);
|
|
19112
19428
|
const width = Math.max(node.width, 240);
|
|
19113
19429
|
const height = Math.max(node.height, 36 + fields.length * 44);
|
|
19114
19430
|
const commit = () => {
|
|
@@ -19137,7 +19453,7 @@ var SystemCanvas = (() => {
|
|
|
19137
19453
|
const stopPointer = (e) => {
|
|
19138
19454
|
e.stopPropagation();
|
|
19139
19455
|
};
|
|
19140
|
-
(0,
|
|
19456
|
+
(0, import_react14.useEffect)(() => {
|
|
19141
19457
|
const el = panelRef.current;
|
|
19142
19458
|
if (!el)
|
|
19143
19459
|
return;
|
|
@@ -19267,13 +19583,13 @@ var SystemCanvas = (() => {
|
|
|
19267
19583
|
|
|
19268
19584
|
// ../react/dist/components/EdgeLabelEditor.js
|
|
19269
19585
|
var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
|
|
19270
|
-
var
|
|
19586
|
+
var import_react15 = __toESM(require_react(), 1);
|
|
19271
19587
|
var EDITOR_WIDTH = 110;
|
|
19272
19588
|
function EdgeLabelEditor({ initialLabel, midpoint, theme, onCommit, onCancel }) {
|
|
19273
|
-
const [value, setValue] = (0,
|
|
19274
|
-
const inputRef = (0,
|
|
19275
|
-
const committedRef = (0,
|
|
19276
|
-
(0,
|
|
19589
|
+
const [value, setValue] = (0, import_react15.useState)(initialLabel);
|
|
19590
|
+
const inputRef = (0, import_react15.useRef)(null);
|
|
19591
|
+
const committedRef = (0, import_react15.useRef)(false);
|
|
19592
|
+
(0, import_react15.useEffect)(() => {
|
|
19277
19593
|
const el = inputRef.current;
|
|
19278
19594
|
if (el) {
|
|
19279
19595
|
el.focus();
|
|
@@ -19328,7 +19644,7 @@ var SystemCanvas = (() => {
|
|
|
19328
19644
|
|
|
19329
19645
|
// ../react/dist/components/ConnectionHandles.js
|
|
19330
19646
|
var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1);
|
|
19331
|
-
var
|
|
19647
|
+
var import_react16 = __toESM(require_react(), 1);
|
|
19332
19648
|
var SIDES = ["top", "right", "bottom", "left"];
|
|
19333
19649
|
var HANDLE_RADIUS = 4;
|
|
19334
19650
|
var HANDLE_HIT_RADIUS = 10;
|
|
@@ -19337,9 +19653,9 @@ var SystemCanvas = (() => {
|
|
|
19337
19653
|
var HOVER_SCALE = 1.42;
|
|
19338
19654
|
var HOVER_TRANSITION_MS = 120;
|
|
19339
19655
|
function ConnectionHandles({ node, theme, onHandlePointerDown, immediate, activeSide }) {
|
|
19340
|
-
const [visible, setVisible] = (0,
|
|
19341
|
-
const [hoveredSide, setHoveredSide] = (0,
|
|
19342
|
-
(0,
|
|
19656
|
+
const [visible, setVisible] = (0, import_react16.useState)(!!immediate);
|
|
19657
|
+
const [hoveredSide, setHoveredSide] = (0, import_react16.useState)(null);
|
|
19658
|
+
(0, import_react16.useEffect)(() => {
|
|
19343
19659
|
if (immediate) {
|
|
19344
19660
|
setVisible(true);
|
|
19345
19661
|
return;
|
|
@@ -19426,17 +19742,18 @@ var SystemCanvas = (() => {
|
|
|
19426
19742
|
// ../react/dist/components/Viewport.js
|
|
19427
19743
|
var HOVER_PADDING = 10;
|
|
19428
19744
|
var EDGE_PROXIMITY = 16;
|
|
19429
|
-
var Viewport = (0,
|
|
19745
|
+
var Viewport = (0, import_react17.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) {
|
|
19430
19746
|
const { svgRef, groupRef, viewport, fitToContent, zoomToNode, setTransform } = useViewport({
|
|
19431
19747
|
minZoom,
|
|
19432
19748
|
maxZoom,
|
|
19433
19749
|
defaultViewport,
|
|
19434
|
-
onViewportChange
|
|
19750
|
+
onViewportChange,
|
|
19751
|
+
marqueeActiveRef
|
|
19435
19752
|
});
|
|
19436
|
-
const navigatingRef = (0,
|
|
19437
|
-
const fadeRafRef = (0,
|
|
19438
|
-
const fadeTimeoutRef = (0,
|
|
19439
|
-
const triggerFade = (0,
|
|
19753
|
+
const navigatingRef = (0, import_react17.useRef)(false);
|
|
19754
|
+
const fadeRafRef = (0, import_react17.useRef)(null);
|
|
19755
|
+
const fadeTimeoutRef = (0, import_react17.useRef)(null);
|
|
19756
|
+
const triggerFade = (0, import_react17.useCallback)((durationMs) => {
|
|
19440
19757
|
if (durationMs <= 0)
|
|
19441
19758
|
return;
|
|
19442
19759
|
const g = groupRef.current;
|
|
@@ -19459,7 +19776,7 @@ var SystemCanvas = (() => {
|
|
|
19459
19776
|
}, durationMs + 16);
|
|
19460
19777
|
});
|
|
19461
19778
|
}, []);
|
|
19462
|
-
(0,
|
|
19779
|
+
(0, import_react17.useEffect)(() => {
|
|
19463
19780
|
return () => {
|
|
19464
19781
|
if (fadeRafRef.current !== null)
|
|
19465
19782
|
cancelAnimationFrame(fadeRafRef.current);
|
|
@@ -19467,10 +19784,10 @@ var SystemCanvas = (() => {
|
|
|
19467
19784
|
clearTimeout(fadeTimeoutRef.current);
|
|
19468
19785
|
};
|
|
19469
19786
|
}, []);
|
|
19470
|
-
const [hoveredNodeId, setHoveredNodeId] = (0,
|
|
19471
|
-
const [hoveredSide, setHoveredSide] = (0,
|
|
19472
|
-
const cursorPosRef = (0,
|
|
19473
|
-
(0,
|
|
19787
|
+
const [hoveredNodeId, setHoveredNodeId] = (0, import_react17.useState)(null);
|
|
19788
|
+
const [hoveredSide, setHoveredSide] = (0, import_react17.useState)(null);
|
|
19789
|
+
const cursorPosRef = (0, import_react17.useRef)(null);
|
|
19790
|
+
(0, import_react17.useImperativeHandle)(ref, () => ({
|
|
19474
19791
|
zoomToNode: (node, onComplete, options) => {
|
|
19475
19792
|
navigatingRef.current = true;
|
|
19476
19793
|
zoomToNode(node, onComplete, options);
|
|
@@ -19481,7 +19798,7 @@ var SystemCanvas = (() => {
|
|
|
19481
19798
|
getViewport: () => viewport.current ?? { x: 0, y: 0, zoom: 1 },
|
|
19482
19799
|
getCursorScreenPos: () => cursorPosRef.current
|
|
19483
19800
|
}));
|
|
19484
|
-
const renderNodes = (0,
|
|
19801
|
+
const renderNodes = (0, import_react17.useMemo)(() => {
|
|
19485
19802
|
const hasDrag = dragOverrides && dragOverrides.size > 0;
|
|
19486
19803
|
const hasResize = resizeOverrides && resizeOverrides.size > 0;
|
|
19487
19804
|
if (!hasDrag && !hasResize)
|
|
@@ -19494,7 +19811,7 @@ var SystemCanvas = (() => {
|
|
|
19494
19811
|
return d ? { ...n, x: d.x, y: d.y } : n;
|
|
19495
19812
|
});
|
|
19496
19813
|
}, [nodes, dragOverrides, resizeOverrides]);
|
|
19497
|
-
const renderNodeMap = (0,
|
|
19814
|
+
const renderNodeMap = (0, import_react17.useMemo)(() => {
|
|
19498
19815
|
const hasDrag = dragOverrides && dragOverrides.size > 0;
|
|
19499
19816
|
const hasResize = resizeOverrides && resizeOverrides.size > 0;
|
|
19500
19817
|
if (!hasDrag && !hasResize)
|
|
@@ -19505,11 +19822,11 @@ var SystemCanvas = (() => {
|
|
|
19505
19822
|
}
|
|
19506
19823
|
return m;
|
|
19507
19824
|
}, [renderNodes, nodeMap, dragOverrides, resizeOverrides]);
|
|
19508
|
-
const latestNodesRef = (0,
|
|
19509
|
-
(0,
|
|
19825
|
+
const latestNodesRef = (0, import_react17.useRef)(nodes);
|
|
19826
|
+
(0, import_react17.useEffect)(() => {
|
|
19510
19827
|
latestNodesRef.current = nodes;
|
|
19511
19828
|
}, [nodes]);
|
|
19512
|
-
const fitNow = (0,
|
|
19829
|
+
const fitNow = (0, import_react17.useCallback)(() => {
|
|
19513
19830
|
const current = latestNodesRef.current;
|
|
19514
19831
|
if (current.length === 0)
|
|
19515
19832
|
return;
|
|
@@ -19519,7 +19836,7 @@ var SystemCanvas = (() => {
|
|
|
19519
19836
|
fitToContent(current, animate);
|
|
19520
19837
|
});
|
|
19521
19838
|
}, [fitToContent]);
|
|
19522
|
-
(0,
|
|
19839
|
+
(0, import_react17.useEffect)(() => {
|
|
19523
19840
|
if (defaultViewport)
|
|
19524
19841
|
return;
|
|
19525
19842
|
if (autoFit !== "always")
|
|
@@ -19528,8 +19845,8 @@ var SystemCanvas = (() => {
|
|
|
19528
19845
|
return;
|
|
19529
19846
|
fitNow();
|
|
19530
19847
|
}, [nodes, autoFit, defaultViewport, fitNow]);
|
|
19531
|
-
const fittedForRef = (0,
|
|
19532
|
-
(0,
|
|
19848
|
+
const fittedForRef = (0, import_react17.useRef)(null);
|
|
19849
|
+
(0, import_react17.useEffect)(() => {
|
|
19533
19850
|
if (defaultViewport)
|
|
19534
19851
|
return;
|
|
19535
19852
|
if (autoFit !== "canvas-change" && autoFit !== "initial")
|
|
@@ -19561,7 +19878,7 @@ var SystemCanvas = (() => {
|
|
|
19561
19878
|
triggerFade
|
|
19562
19879
|
]);
|
|
19563
19880
|
const editingNode = editingId ? renderNodes.find((n) => n.id === editingId) ?? null : null;
|
|
19564
|
-
const handleSvgPointerMove = (0,
|
|
19881
|
+
const handleSvgPointerMove = (0, import_react17.useCallback)((event) => {
|
|
19565
19882
|
const svg = svgRef.current;
|
|
19566
19883
|
if (!svg)
|
|
19567
19884
|
return;
|
|
@@ -19613,7 +19930,7 @@ var SystemCanvas = (() => {
|
|
|
19613
19930
|
setHoveredSide((prev) => prev === null ? prev : null);
|
|
19614
19931
|
}
|
|
19615
19932
|
}, [edgeCreateEnabled, renderNodes, svgRef, viewport]);
|
|
19616
|
-
const handleSvgPointerLeave = (0,
|
|
19933
|
+
const handleSvgPointerLeave = (0, import_react17.useCallback)(() => {
|
|
19617
19934
|
setHoveredNodeId(null);
|
|
19618
19935
|
setHoveredSide(null);
|
|
19619
19936
|
cursorPosRef.current = null;
|
|
@@ -19642,12 +19959,17 @@ var SystemCanvas = (() => {
|
|
|
19642
19959
|
WebkitUserSelect: "none",
|
|
19643
19960
|
MozUserSelect: "none",
|
|
19644
19961
|
msUserSelect: "none"
|
|
19645
|
-
}, onClick: onCanvasClick, onContextMenu: onCanvasContextMenu, onPointerMove: handleSvgPointerMove, onPointerLeave: handleSvgPointerLeave, children: [(0, import_jsx_runtime22.jsx)("defs", { children: (0, import_jsx_runtime22.jsx)("pattern", { id: "system-canvas-grid", width: theme.grid.size, height: theme.grid.size, patternUnits: "userSpaceOnUse", children: (0, import_jsx_runtime22.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_runtime22.jsx)("rect", { x: "-50000", y: "-50000", width: "100000", height: "100000", fill: "url(#system-canvas-grid)" }), (0, import_jsx_runtime22.jsxs)("g", { ref: groupRef, children: [(0, import_jsx_runtime22.jsx)(LanesBackground, { columns, rows, theme }), (0, import_jsx_runtime22.jsx)(NodeRenderer, { nodes: renderNodes, theme, onClick: onNodeClick, onDoubleClick: onNodeDoubleClick, onContextMenu: onNodeContextMenu, onNavigate: onNodeNavigate, onPointerDown: onNodePointerDown,
|
|
19962
|
+
}, onClick: onCanvasClick, onContextMenu: onCanvasContextMenu, onPointerMove: handleSvgPointerMove, onPointerLeave: handleSvgPointerLeave, children: [(0, import_jsx_runtime22.jsx)("defs", { children: (0, import_jsx_runtime22.jsx)("pattern", { id: "system-canvas-grid", width: theme.grid.size, height: theme.grid.size, patternUnits: "userSpaceOnUse", children: (0, import_jsx_runtime22.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_runtime22.jsx)("rect", { x: "-50000", y: "-50000", width: "100000", height: "100000", fill: "url(#system-canvas-grid)" }), (0, import_jsx_runtime22.jsxs)("g", { ref: groupRef, children: [(0, import_jsx_runtime22.jsx)(LanesBackground, { columns, rows, theme }), (0, import_jsx_runtime22.jsx)(NodeRenderer, { nodes: renderNodes, theme, onClick: onNodeClick, onDoubleClick: onNodeDoubleClick, onContextMenu: onNodeContextMenu, onNavigate: onNodeNavigate, onPointerDown: onNodePointerDown, selectedIds, editingId, canvases, only: "groups" }), (0, import_jsx_runtime22.jsx)(EdgeRenderer, { edges, nodeMap: renderNodeMap, theme, defaultEdgeStyle: edgeStyle, onClick: onEdgeClick, onDoubleClick: onEdgeDoubleClick, onContextMenu: onEdgeContextMenu, selectedId: selectedEdgeId, editingId: editingEdgeId }), (0, import_jsx_runtime22.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_runtime22.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_runtime22.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) => {
|
|
19963
|
+
const node = renderNodeMap.get(id2);
|
|
19964
|
+
if (!node)
|
|
19965
|
+
return null;
|
|
19966
|
+
return (0, import_jsx_runtime22.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}`);
|
|
19967
|
+
}), pendingEdge && pendingSourceNode && (0, import_jsx_runtime22.jsx)(PendingEdgeRenderer, { sourceNode: pendingSourceNode, sourceSide: pendingEdge.sourceSide, cursor: pendingEdge.cursor, targetNode: pendingTargetNode, theme, defaultEdgeStyle: edgeStyle }), handlesNode && onConnectionHandlePointerDown && (0, import_jsx_runtime22.jsx)(ConnectionHandles, { node: handlesNode, theme, onHandlePointerDown: onConnectionHandlePointerDown, immediate: !!pendingEdge, activeSide: hoveredSide }), editingNode && onEditorCommit && onEditorCancel && (0, import_jsx_runtime22.jsx)(NodeEditor, { node: editingNode, theme, onCommit: onEditorCommit, onCancel: onEditorCancel }), editingEdge && editingEdgeMidpoint && onEdgeEditorCommit && onEdgeEditorCancel && (0, import_jsx_runtime22.jsx)(EdgeLabelEditor, { initialLabel: editingEdge.label ?? "", midpoint: editingEdgeMidpoint, theme, onCommit: onEdgeEditorCommit, onCancel: onEdgeEditorCancel })] }), marqueeRect && (0, import_jsx_runtime22.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" })] });
|
|
19646
19968
|
});
|
|
19647
19969
|
|
|
19648
19970
|
// ../react/dist/components/Breadcrumbs.js
|
|
19649
19971
|
var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1);
|
|
19650
|
-
var
|
|
19972
|
+
var import_react18 = __toESM(require_react(), 1);
|
|
19651
19973
|
function Breadcrumbs({ breadcrumbs, theme, onNavigate }) {
|
|
19652
19974
|
if (breadcrumbs.length <= 1)
|
|
19653
19975
|
return null;
|
|
@@ -19668,7 +19990,7 @@ var SystemCanvas = (() => {
|
|
|
19668
19990
|
backdropFilter: "blur(8px)"
|
|
19669
19991
|
}, children: breadcrumbs.map((crumb, index) => {
|
|
19670
19992
|
const isLast = index === breadcrumbs.length - 1;
|
|
19671
|
-
return (0, import_jsx_runtime23.jsxs)(
|
|
19993
|
+
return (0, import_jsx_runtime23.jsxs)(import_react18.default.Fragment, { children: [index > 0 && (0, import_jsx_runtime23.jsx)("span", { style: {
|
|
19672
19994
|
color: theme.separatorColor,
|
|
19673
19995
|
margin: "0 2px"
|
|
19674
19996
|
}, children: "/" }), (0, import_jsx_runtime23.jsx)("span", { onClick: isLast ? void 0 : () => onNavigate(index), style: {
|
|
@@ -19692,11 +20014,11 @@ var SystemCanvas = (() => {
|
|
|
19692
20014
|
|
|
19693
20015
|
// ../react/dist/components/AddNodeButton.js
|
|
19694
20016
|
var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1);
|
|
19695
|
-
var
|
|
20017
|
+
var import_react19 = __toESM(require_react(), 1);
|
|
19696
20018
|
function AddNodeButton({ options, addNode: addNode2, theme }) {
|
|
19697
|
-
const [open, setOpen] = (0,
|
|
19698
|
-
const rootRef = (0,
|
|
19699
|
-
(0,
|
|
20019
|
+
const [open, setOpen] = (0, import_react19.useState)(false);
|
|
20020
|
+
const rootRef = (0, import_react19.useRef)(null);
|
|
20021
|
+
(0, import_react19.useEffect)(() => {
|
|
19700
20022
|
if (!open)
|
|
19701
20023
|
return;
|
|
19702
20024
|
function onDocClick(e) {
|
|
@@ -19785,7 +20107,7 @@ var SystemCanvas = (() => {
|
|
|
19785
20107
|
} });
|
|
19786
20108
|
}
|
|
19787
20109
|
function MenuRow({ theme, option, onClick }) {
|
|
19788
|
-
const [hover, setHover] = (0,
|
|
20110
|
+
const [hover, setHover] = (0, import_react19.useState)(false);
|
|
19789
20111
|
const swatchSize = 18;
|
|
19790
20112
|
return (0, import_jsx_runtime24.jsxs)("div", { role: "button", onClick, onMouseEnter: () => setHover(true), onMouseLeave: () => setHover(false), style: {
|
|
19791
20113
|
display: "flex",
|
|
@@ -19821,12 +20143,12 @@ var SystemCanvas = (() => {
|
|
|
19821
20143
|
|
|
19822
20144
|
// ../react/dist/components/LaneHeaders.js
|
|
19823
20145
|
var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1);
|
|
19824
|
-
var
|
|
20146
|
+
var import_react20 = __toESM(require_react(), 1);
|
|
19825
20147
|
function LaneHeaders({ columns, rows, theme, getViewport, width, height, pinned = true }) {
|
|
19826
20148
|
const hasColumns = columns && columns.length > 0;
|
|
19827
20149
|
const hasRows = rows && rows.length > 0;
|
|
19828
|
-
const [viewport, setViewport] = (0,
|
|
19829
|
-
(0,
|
|
20150
|
+
const [viewport, setViewport] = (0, import_react20.useState)(() => getViewport());
|
|
20151
|
+
(0, import_react20.useEffect)(() => {
|
|
19830
20152
|
if (!hasColumns && !hasRows)
|
|
19831
20153
|
return;
|
|
19832
20154
|
let raf = 0;
|
|
@@ -19900,7 +20222,7 @@ var SystemCanvas = (() => {
|
|
|
19900
20222
|
|
|
19901
20223
|
// ../react/dist/components/NodeToolbar.js
|
|
19902
20224
|
var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1);
|
|
19903
|
-
var
|
|
20225
|
+
var import_react21 = __toESM(require_react(), 1);
|
|
19904
20226
|
var NODE_GAP = 10;
|
|
19905
20227
|
var FLIP_MARGIN = 8;
|
|
19906
20228
|
var PADDING = 6;
|
|
@@ -19908,9 +20230,9 @@ var SystemCanvas = (() => {
|
|
|
19908
20230
|
var SWATCH_SIZE = 16;
|
|
19909
20231
|
var BUTTON_SIZE = 28;
|
|
19910
20232
|
var DELETE_SIZE = 14;
|
|
19911
|
-
function NodeToolbar({ node, theme, onPatch, onDelete, getViewport, containerWidth, containerHeight, render: render2 }) {
|
|
19912
|
-
const [viewport, setViewport] = (0,
|
|
19913
|
-
(0,
|
|
20233
|
+
function NodeToolbar({ node, theme, onPatch, onDelete, getViewport, containerWidth, containerHeight, render: render2, selectedNodes, onMultiPatch }) {
|
|
20234
|
+
const [viewport, setViewport] = (0, import_react21.useState)(() => getViewport());
|
|
20235
|
+
(0, import_react21.useEffect)(() => {
|
|
19914
20236
|
let raf = 0;
|
|
19915
20237
|
let lastX = -Infinity;
|
|
19916
20238
|
let lastY = -Infinity;
|
|
@@ -19928,13 +20250,28 @@ var SystemCanvas = (() => {
|
|
|
19928
20250
|
raf = requestAnimationFrame(tick);
|
|
19929
20251
|
return () => cancelAnimationFrame(raf);
|
|
19930
20252
|
}, [getViewport]);
|
|
20253
|
+
const isMulti = selectedNodes != null && selectedNodes.length > 1;
|
|
19931
20254
|
const align = theme.toolbarAlign ?? "center";
|
|
19932
|
-
const
|
|
19933
|
-
|
|
19934
|
-
|
|
19935
|
-
|
|
19936
|
-
|
|
19937
|
-
|
|
20255
|
+
const { anchorTopY, anchorBottomY, anchorX } = (0, import_react21.useMemo)(() => {
|
|
20256
|
+
if (isMulti && selectedNodes) {
|
|
20257
|
+
const minX = Math.min(...selectedNodes.map((n) => n.x));
|
|
20258
|
+
const maxX = Math.max(...selectedNodes.map((n) => n.x + n.width));
|
|
20259
|
+
const minY = Math.min(...selectedNodes.map((n) => n.y));
|
|
20260
|
+
const maxY = Math.max(...selectedNodes.map((n) => n.y + n.height));
|
|
20261
|
+
return {
|
|
20262
|
+
anchorX: (minX + maxX) / 2,
|
|
20263
|
+
anchorTopY: minY,
|
|
20264
|
+
anchorBottomY: maxY
|
|
20265
|
+
};
|
|
20266
|
+
}
|
|
20267
|
+
const x = align === "left" ? node.x : align === "right" ? node.x + node.width : node.x + node.width / 2;
|
|
20268
|
+
return { anchorX: x, anchorTopY: node.y, anchorBottomY: node.y + node.height };
|
|
20269
|
+
}, [isMulti, selectedNodes, align, node]);
|
|
20270
|
+
const topAnchor = canvasToScreen(anchorX, anchorTopY, viewport);
|
|
20271
|
+
const bottomAnchor = canvasToScreen(anchorX, anchorBottomY, viewport);
|
|
20272
|
+
const toolbarRef = (0, import_react21.useRef)(null);
|
|
20273
|
+
const [size, setSize] = (0, import_react21.useState)({ width: 0, height: 0 });
|
|
20274
|
+
(0, import_react21.useEffect)(() => {
|
|
19938
20275
|
const el = toolbarRef.current;
|
|
19939
20276
|
if (!el)
|
|
19940
20277
|
return;
|
|
@@ -19947,7 +20284,12 @@ var SystemCanvas = (() => {
|
|
|
19947
20284
|
ro.observe(el);
|
|
19948
20285
|
return () => ro.disconnect();
|
|
19949
20286
|
}, []);
|
|
19950
|
-
let left
|
|
20287
|
+
let left;
|
|
20288
|
+
if (isMulti) {
|
|
20289
|
+
left = topAnchor.x - size.width / 2;
|
|
20290
|
+
} else {
|
|
20291
|
+
left = align === "left" ? topAnchor.x : align === "right" ? topAnchor.x - size.width : topAnchor.x - size.width / 2;
|
|
20292
|
+
}
|
|
19951
20293
|
let top = topAnchor.y - size.height - NODE_GAP;
|
|
19952
20294
|
if (top < FLIP_MARGIN) {
|
|
19953
20295
|
top = bottomAnchor.y + NODE_GAP;
|
|
@@ -19984,13 +20326,51 @@ var SystemCanvas = (() => {
|
|
|
19984
20326
|
userSelect: "none",
|
|
19985
20327
|
whiteSpace: "nowrap"
|
|
19986
20328
|
},
|
|
19987
|
-
children: render2 ? render2({ node, theme, patch, deleteNode }) : (0, import_jsx_runtime26.jsx)(DefaultToolbarContent, { node, theme, onPatch: patch, onDelete: deleteNode })
|
|
20329
|
+
children: isMulti && selectedNodes && onMultiPatch ? (0, import_jsx_runtime26.jsx)(MultiToolbarContent, { selectedNodes, theme, onMultiPatch, onDelete: deleteNode }) : render2 ? render2({ node, theme, patch, deleteNode }) : (0, import_jsx_runtime26.jsx)(DefaultToolbarContent, { node, theme, onPatch: patch, onDelete: deleteNode })
|
|
19988
20330
|
});
|
|
19989
20331
|
}
|
|
20332
|
+
function MultiToolbarContent({ selectedNodes, theme, onMultiPatch, onDelete }) {
|
|
20333
|
+
const representativeNode = selectedNodes[0];
|
|
20334
|
+
const groups = (0, import_react21.useMemo)(() => getNodeActionsForNode(representativeNode, theme), [representativeNode, theme]);
|
|
20335
|
+
const showDelete = theme.showToolbarDelete === true;
|
|
20336
|
+
const swatchGroups = groups.filter((g) => g.kind === "swatches" || g.kind == null);
|
|
20337
|
+
const otherGroups = groups.filter((g) => g.kind !== "swatches" && g.kind != null && g.kind !== "menu");
|
|
20338
|
+
return (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [(0, import_jsx_runtime26.jsxs)("span", { style: {
|
|
20339
|
+
fontSize: 11,
|
|
20340
|
+
color: theme.breadcrumbs.textColor,
|
|
20341
|
+
opacity: 0.75,
|
|
20342
|
+
paddingRight: BUTTON_GAP,
|
|
20343
|
+
whiteSpace: "nowrap"
|
|
20344
|
+
}, children: [selectedNodes.length, " nodes"] }), swatchGroups.map((group, i) => {
|
|
20345
|
+
const actions = filterActionsForNode(group, representativeNode);
|
|
20346
|
+
if (actions.length === 0)
|
|
20347
|
+
return null;
|
|
20348
|
+
return (0, import_jsx_runtime26.jsxs)(import_react21.default.Fragment, { children: [i > 0 && (0, import_jsx_runtime26.jsx)(Divider2, { theme }), (0, import_jsx_runtime26.jsx)("div", { style: { display: "flex", alignItems: "center", gap: BUTTON_GAP }, children: actions.map((action) => {
|
|
20349
|
+
const active = action.isActive?.(representativeNode) ?? false;
|
|
20350
|
+
const handleClick = () => {
|
|
20351
|
+
const patch = resolveActionPatch(action, representativeNode);
|
|
20352
|
+
onMultiPatch(patch);
|
|
20353
|
+
};
|
|
20354
|
+
return (0, import_jsx_runtime26.jsx)(SwatchButton, { action, active, theme, onClick: handleClick }, action.id);
|
|
20355
|
+
}) })] }, group.id);
|
|
20356
|
+
}), otherGroups.map((group) => {
|
|
20357
|
+
const actions = filterActionsForNode(group, representativeNode);
|
|
20358
|
+
if (actions.length === 0)
|
|
20359
|
+
return null;
|
|
20360
|
+
return (0, import_jsx_runtime26.jsxs)(import_react21.default.Fragment, { children: [(0, import_jsx_runtime26.jsx)(Divider2, { theme }), (0, import_jsx_runtime26.jsx)("div", { style: { display: "flex", alignItems: "center", gap: BUTTON_GAP }, children: actions.map((action) => {
|
|
20361
|
+
const active = action.isActive?.(representativeNode) ?? false;
|
|
20362
|
+
const handleClick = () => {
|
|
20363
|
+
const patch = resolveActionPatch(action, representativeNode);
|
|
20364
|
+
onMultiPatch(patch);
|
|
20365
|
+
};
|
|
20366
|
+
return (0, import_jsx_runtime26.jsx)(IconButton, { action, active, theme, onClick: handleClick }, action.id);
|
|
20367
|
+
}) })] }, group.id);
|
|
20368
|
+
}), showDelete && (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [(0, import_jsx_runtime26.jsx)(Divider2, { theme }), (0, import_jsx_runtime26.jsx)(DeleteButton, { theme, onDelete })] })] });
|
|
20369
|
+
}
|
|
19990
20370
|
function DefaultToolbarContent({ node, theme, onPatch, onDelete }) {
|
|
19991
|
-
const groups = (0,
|
|
20371
|
+
const groups = (0, import_react21.useMemo)(() => getNodeActionsForNode(node, theme), [node, theme]);
|
|
19992
20372
|
const showDelete = theme.showToolbarDelete === true;
|
|
19993
|
-
return (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [groups.map((group, i) => (0, import_jsx_runtime26.jsxs)(
|
|
20373
|
+
return (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [groups.map((group, i) => (0, import_jsx_runtime26.jsxs)(import_react21.default.Fragment, { children: [i > 0 && (0, import_jsx_runtime26.jsx)(Divider2, { theme }), (0, import_jsx_runtime26.jsx)(ActionGroupView, { group, node, theme, onPatch })] }, group.id)), showDelete && (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [(0, import_jsx_runtime26.jsx)(Divider2, { theme }), (0, import_jsx_runtime26.jsx)(DeleteButton, { theme, onDelete })] })] });
|
|
19994
20374
|
}
|
|
19995
20375
|
function Divider2({ theme }) {
|
|
19996
20376
|
return (0, import_jsx_runtime26.jsx)("div", { style: {
|
|
@@ -20057,9 +20437,9 @@ var SystemCanvas = (() => {
|
|
|
20057
20437
|
} }) : (0, import_jsx_runtime26.jsx)("span", { style: { fontSize: 10 }, children: action.label.slice(0, 2) }) });
|
|
20058
20438
|
}
|
|
20059
20439
|
function MenuGroup({ group, actions, node, theme, onPatch }) {
|
|
20060
|
-
const [open, setOpen] = (0,
|
|
20061
|
-
const wrapRef = (0,
|
|
20062
|
-
(0,
|
|
20440
|
+
const [open, setOpen] = (0, import_react21.useState)(false);
|
|
20441
|
+
const wrapRef = (0, import_react21.useRef)(null);
|
|
20442
|
+
(0, import_react21.useEffect)(() => {
|
|
20063
20443
|
if (!open)
|
|
20064
20444
|
return;
|
|
20065
20445
|
const onDown = (e) => {
|
|
@@ -20146,18 +20526,18 @@ var SystemCanvas = (() => {
|
|
|
20146
20526
|
|
|
20147
20527
|
// ../react/dist/components/NodeContextMenuOverlay.js
|
|
20148
20528
|
var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
|
|
20149
|
-
var
|
|
20529
|
+
var import_react22 = __toESM(require_react(), 1);
|
|
20150
20530
|
var ESTIMATED_MENU_WIDTH = 200;
|
|
20151
20531
|
var MIN_MENU_WIDTH = 160;
|
|
20152
20532
|
var VIEWPORT_MARGIN = 8;
|
|
20153
20533
|
function NodeContextMenuOverlay({ state, config, theme, onClose }) {
|
|
20154
|
-
const rootRef = (0,
|
|
20155
|
-
const [hoveredId, setHoveredId] = (0,
|
|
20156
|
-
(0,
|
|
20534
|
+
const rootRef = (0, import_react22.useRef)(null);
|
|
20535
|
+
const [hoveredId, setHoveredId] = (0, import_react22.useState)(null);
|
|
20536
|
+
(0, import_react22.useEffect)(() => {
|
|
20157
20537
|
if (state)
|
|
20158
20538
|
setHoveredId(null);
|
|
20159
20539
|
}, [state]);
|
|
20160
|
-
(0,
|
|
20540
|
+
(0, import_react22.useEffect)(() => {
|
|
20161
20541
|
if (!state)
|
|
20162
20542
|
return;
|
|
20163
20543
|
function onDown(e) {
|
|
@@ -20265,8 +20645,8 @@ var SystemCanvas = (() => {
|
|
|
20265
20645
|
// ../react/dist/components/SystemCanvas.js
|
|
20266
20646
|
var CASCADE_WINDOW_MS = 1500;
|
|
20267
20647
|
var CASCADE_OFFSET = 20;
|
|
20268
|
-
var SystemCanvas = (0,
|
|
20269
|
-
const zoomNavConfig = (0,
|
|
20648
|
+
var SystemCanvas = (0, import_react23.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, className, style }, forwardedRef) {
|
|
20649
|
+
const zoomNavConfig = (0, import_react23.useMemo)(() => {
|
|
20270
20650
|
const defaults = {
|
|
20271
20651
|
enterThreshold: 0.66,
|
|
20272
20652
|
exitThreshold: 0.33,
|
|
@@ -20291,16 +20671,16 @@ var SystemCanvas = (() => {
|
|
|
20291
20671
|
}, [zoomNavigation]);
|
|
20292
20672
|
const effectiveMaxZoom = maxZoom ?? (zoomNavConfig.enabled ? 16 : 4);
|
|
20293
20673
|
const effectiveMinZoom = minZoomProp ?? (zoomNavConfig.enabled ? 0.01 : 0.1);
|
|
20294
|
-
(0,
|
|
20674
|
+
(0, import_react23.useEffect)(() => {
|
|
20295
20675
|
const env = globalThis.process?.env?.NODE_ENV;
|
|
20296
20676
|
if (editable && !canvases && env !== "production") {
|
|
20297
20677
|
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.");
|
|
20298
20678
|
}
|
|
20299
20679
|
}, [editable, canvases]);
|
|
20300
|
-
const [parentFrames, setParentFrames] = (0,
|
|
20301
|
-
const [pendingHandoff, setPendingHandoff] = (0,
|
|
20302
|
-
const suppressNextHandoffClearRef = (0,
|
|
20303
|
-
const handleBreadcrumbClick = (0,
|
|
20680
|
+
const [parentFrames, setParentFrames] = (0, import_react23.useState)([]);
|
|
20681
|
+
const [pendingHandoff, setPendingHandoff] = (0, import_react23.useState)(null);
|
|
20682
|
+
const suppressNextHandoffClearRef = (0, import_react23.useRef)(false);
|
|
20683
|
+
const handleBreadcrumbClick = (0, import_react23.useCallback)((index) => {
|
|
20304
20684
|
setParentFrames((prev) => prev.slice(0, index));
|
|
20305
20685
|
if (suppressNextHandoffClearRef.current) {
|
|
20306
20686
|
suppressNextHandoffClearRef.current = false;
|
|
@@ -20317,10 +20697,10 @@ var SystemCanvas = (() => {
|
|
|
20317
20697
|
onNavigate,
|
|
20318
20698
|
onBreadcrumbClick: handleBreadcrumbClick
|
|
20319
20699
|
});
|
|
20320
|
-
(0,
|
|
20700
|
+
(0, import_react23.useEffect)(() => {
|
|
20321
20701
|
onBreadcrumbsChange?.(breadcrumbs);
|
|
20322
20702
|
}, [breadcrumbs, onBreadcrumbsChange]);
|
|
20323
|
-
const theme = (0,
|
|
20703
|
+
const theme = (0, import_react23.useMemo)(() => {
|
|
20324
20704
|
const registry = { ...themes, ...customThemes };
|
|
20325
20705
|
const resolveByName = (name) => name && registry[name] ? registry[name] : null;
|
|
20326
20706
|
if (themeProp) {
|
|
@@ -20331,22 +20711,22 @@ var SystemCanvas = (() => {
|
|
|
20331
20711
|
}
|
|
20332
20712
|
return resolveByName(currentCanvas.theme?.base) ?? resolveByName(canvas.theme?.base) ?? darkTheme;
|
|
20333
20713
|
}, [themeProp, customThemes, currentCanvas.theme?.base, canvas.theme?.base]);
|
|
20334
|
-
const { nodes, edges, nodeMap } = (0,
|
|
20714
|
+
const { nodes, edges, nodeMap } = (0, import_react23.useMemo)(() => {
|
|
20335
20715
|
const resolved = resolveCanvas(currentCanvas, theme);
|
|
20336
20716
|
const map = buildNodeMap(resolved.nodes);
|
|
20337
20717
|
return { nodes: resolved.nodes, edges: resolved.edges, nodeMap: map };
|
|
20338
20718
|
}, [currentCanvas, theme]);
|
|
20339
|
-
const nodesRef = (0,
|
|
20719
|
+
const nodesRef = (0, import_react23.useRef)(nodes);
|
|
20340
20720
|
nodesRef.current = nodes;
|
|
20341
|
-
const viewportStateRef = (0,
|
|
20342
|
-
const viewportHandleRef = (0,
|
|
20343
|
-
const navigateToRefRef = (0,
|
|
20721
|
+
const viewportStateRef = (0, import_react23.useRef)(defaultViewport ?? { x: 0, y: 0, zoom: 1 });
|
|
20722
|
+
const viewportHandleRef = (0, import_react23.useRef)(null);
|
|
20723
|
+
const navigateToRefRef = (0, import_react23.useRef)(navigateToRef);
|
|
20344
20724
|
navigateToRefRef.current = navigateToRef;
|
|
20345
|
-
const navigateToBreadcrumbRef = (0,
|
|
20725
|
+
const navigateToBreadcrumbRef = (0, import_react23.useRef)(navigateToBreadcrumb);
|
|
20346
20726
|
navigateToBreadcrumbRef.current = navigateToBreadcrumb;
|
|
20347
|
-
const breadcrumbsRef = (0,
|
|
20727
|
+
const breadcrumbsRef = (0, import_react23.useRef)(breadcrumbs);
|
|
20348
20728
|
breadcrumbsRef.current = breadcrumbs;
|
|
20349
|
-
(0,
|
|
20729
|
+
(0, import_react23.useImperativeHandle)(forwardedRef, () => ({
|
|
20350
20730
|
zoomIntoNode: (nodeId, options) => {
|
|
20351
20731
|
return new Promise((resolve) => {
|
|
20352
20732
|
const node = nodesRef.current.find((n) => n.id === nodeId);
|
|
@@ -20378,26 +20758,64 @@ var SystemCanvas = (() => {
|
|
|
20378
20758
|
navigateToBreadcrumbRef.current(0);
|
|
20379
20759
|
}
|
|
20380
20760
|
}), [forwardedRef]);
|
|
20381
|
-
const [
|
|
20382
|
-
const [
|
|
20383
|
-
const [
|
|
20384
|
-
const
|
|
20385
|
-
(0,
|
|
20386
|
-
|
|
20761
|
+
const [editingId, setEditingId] = (0, import_react23.useState)(null);
|
|
20762
|
+
const [selectedEdgeId, setSelectedEdgeId] = (0, import_react23.useState)(null);
|
|
20763
|
+
const [editingEdgeId, setEditingEdgeId] = (0, import_react23.useState)(null);
|
|
20764
|
+
const svgProxyRef = (0, import_react23.useRef)(null);
|
|
20765
|
+
const containerRef = (0, import_react23.useRef)(null);
|
|
20766
|
+
const { selectedIds, selectNode, toggleNode, selectAll, clearSelection, marqueeRect, marqueeActiveRef } = useMultiSelect({
|
|
20767
|
+
svgRef: svgProxyRef,
|
|
20768
|
+
viewport: viewportStateRef,
|
|
20769
|
+
nodesRef,
|
|
20770
|
+
containerRef,
|
|
20771
|
+
enabled: editable
|
|
20772
|
+
});
|
|
20773
|
+
const selectedIdsRef = (0, import_react23.useRef)(selectedIds);
|
|
20774
|
+
(0, import_react23.useEffect)(() => {
|
|
20775
|
+
selectedIdsRef.current = selectedIds;
|
|
20776
|
+
}, [selectedIds]);
|
|
20777
|
+
const edgesRef = (0, import_react23.useRef)(edges);
|
|
20778
|
+
(0, import_react23.useEffect)(() => {
|
|
20779
|
+
edgesRef.current = edges;
|
|
20780
|
+
}, [edges]);
|
|
20781
|
+
useMultiSelectClipboard({
|
|
20782
|
+
selectedIdsRef,
|
|
20783
|
+
nodesRef,
|
|
20784
|
+
edgesRef,
|
|
20785
|
+
viewport: viewportStateRef,
|
|
20786
|
+
canvasContainerRef: containerRef,
|
|
20787
|
+
onNodeAdd: (node) => onNodeAdd?.(node, currentCanvasRef),
|
|
20788
|
+
onEdgeAdd: (edge) => onEdgeAdd?.(edge, currentCanvasRef),
|
|
20789
|
+
canvasRef: currentCanvasRef,
|
|
20790
|
+
getCursorScreenPos: () => viewportHandleRef.current?.getCursorScreenPos() ?? null
|
|
20791
|
+
});
|
|
20792
|
+
(0, import_react23.useEffect)(() => {
|
|
20793
|
+
clearSelection();
|
|
20387
20794
|
setEditingId(null);
|
|
20388
20795
|
setSelectedEdgeId(null);
|
|
20389
20796
|
setEditingEdgeId(null);
|
|
20390
20797
|
}, [currentCanvasRef]);
|
|
20391
|
-
const onSelectionChangeRef = (0,
|
|
20392
|
-
(0,
|
|
20798
|
+
const onSelectionChangeRef = (0, import_react23.useRef)(onSelectionChange);
|
|
20799
|
+
(0, import_react23.useEffect)(() => {
|
|
20393
20800
|
onSelectionChangeRef.current = onSelectionChange;
|
|
20394
20801
|
}, [onSelectionChange]);
|
|
20395
|
-
const lastEmittedSelectionRef = (0,
|
|
20396
|
-
(0,
|
|
20802
|
+
const lastEmittedSelectionRef = (0, import_react23.useRef)({ kind: null, id: null, multiIds: null, canvasRef: void 0 });
|
|
20803
|
+
(0, import_react23.useEffect)(() => {
|
|
20397
20804
|
const cb = onSelectionChangeRef.current;
|
|
20398
20805
|
let next = null;
|
|
20399
|
-
if (
|
|
20400
|
-
const
|
|
20806
|
+
if (selectedIds.size > 1) {
|
|
20807
|
+
const resolvedNodes = [];
|
|
20808
|
+
for (const id2 of selectedIds) {
|
|
20809
|
+
const n = nodeMap.get(id2);
|
|
20810
|
+
if (n)
|
|
20811
|
+
resolvedNodes.push(n);
|
|
20812
|
+
}
|
|
20813
|
+
if (resolvedNodes.length > 0) {
|
|
20814
|
+
next = { kind: "multi", nodes: resolvedNodes, canvasRef: currentCanvasRef };
|
|
20815
|
+
}
|
|
20816
|
+
} else if (selectedIds.size === 1) {
|
|
20817
|
+
const id2 = Array.from(selectedIds)[0];
|
|
20818
|
+
const node = nodeMap.get(id2);
|
|
20401
20819
|
if (node)
|
|
20402
20820
|
next = { kind: "node", node, canvasRef: currentCanvasRef };
|
|
20403
20821
|
}
|
|
@@ -20408,21 +20826,24 @@ var SystemCanvas = (() => {
|
|
|
20408
20826
|
}
|
|
20409
20827
|
const last = lastEmittedSelectionRef.current;
|
|
20410
20828
|
const nextKind = next?.kind ?? null;
|
|
20411
|
-
const nextId = next ? next.kind === "node" ? next.node.id : next.edge.id : null;
|
|
20412
20829
|
const nextRef = next?.canvasRef;
|
|
20413
|
-
if (
|
|
20414
|
-
|
|
20830
|
+
if (nextKind === "multi" && next?.kind === "multi") {
|
|
20831
|
+
const sortedIds = next.nodes.map((n) => n.id).sort().join(",");
|
|
20832
|
+
if (last.kind === "multi" && last.multiIds === sortedIds && last.canvasRef === nextRef) {
|
|
20833
|
+
return;
|
|
20834
|
+
}
|
|
20835
|
+
lastEmittedSelectionRef.current = { kind: "multi", id: null, multiIds: sortedIds, canvasRef: nextRef };
|
|
20836
|
+
} else {
|
|
20837
|
+
const nextId = next ? next.kind === "node" ? next.node.id : next.kind === "edge" ? next.edge.id : null : null;
|
|
20838
|
+
if (last.kind === nextKind && last.id === nextId && last.canvasRef === nextRef) {
|
|
20839
|
+
return;
|
|
20840
|
+
}
|
|
20841
|
+
lastEmittedSelectionRef.current = { kind: nextKind, id: nextId, multiIds: null, canvasRef: nextRef };
|
|
20415
20842
|
}
|
|
20416
|
-
lastEmittedSelectionRef.current = {
|
|
20417
|
-
kind: nextKind,
|
|
20418
|
-
id: nextId,
|
|
20419
|
-
canvasRef: nextRef
|
|
20420
|
-
};
|
|
20421
20843
|
cb?.(next);
|
|
20422
|
-
}, [
|
|
20423
|
-
const
|
|
20424
|
-
|
|
20425
|
-
(0, import_react21.useEffect)(() => {
|
|
20844
|
+
}, [selectedIds, selectedEdgeId, currentCanvasRef, nodeMap, edges]);
|
|
20845
|
+
const [containerSize, setContainerSize] = (0, import_react23.useState)({ width: 0, height: 0 });
|
|
20846
|
+
(0, import_react23.useEffect)(() => {
|
|
20426
20847
|
const el = containerRef.current;
|
|
20427
20848
|
if (!el)
|
|
20428
20849
|
return;
|
|
@@ -20437,8 +20858,8 @@ var SystemCanvas = (() => {
|
|
|
20437
20858
|
}, []);
|
|
20438
20859
|
const hasLanes = currentCanvas.columns && currentCanvas.columns.length > 0 || currentCanvas.rows && currentCanvas.rows.length > 0;
|
|
20439
20860
|
const showLaneHeaders = hasLanes && laneHeaders !== "none";
|
|
20440
|
-
const getViewportState = (0,
|
|
20441
|
-
const applyLaneSnap = (0,
|
|
20861
|
+
const getViewportState = (0, import_react23.useCallback)(() => viewportStateRef.current ?? { x: 0, y: 0, zoom: 1 }, []);
|
|
20862
|
+
const applyLaneSnap = (0, import_react23.useCallback)((id2, patch) => {
|
|
20442
20863
|
if (!snapToLanes)
|
|
20443
20864
|
return patch;
|
|
20444
20865
|
const cols = currentCanvas.columns;
|
|
@@ -20463,10 +20884,10 @@ var SystemCanvas = (() => {
|
|
|
20463
20884
|
}
|
|
20464
20885
|
return final;
|
|
20465
20886
|
}, [snapToLanes, currentCanvas.columns, currentCanvas.rows]);
|
|
20466
|
-
const commitResize = (0,
|
|
20887
|
+
const commitResize = (0, import_react23.useCallback)((id2, patch) => {
|
|
20467
20888
|
onNodeUpdate?.(id2, applyLaneSnap(id2, patch), currentCanvasRef);
|
|
20468
20889
|
}, [onNodeUpdate, currentCanvasRef, applyLaneSnap]);
|
|
20469
|
-
const commitDragBatch = (0,
|
|
20890
|
+
const commitDragBatch = (0, import_react23.useCallback)((updates) => {
|
|
20470
20891
|
const final = updates.map((u) => ({
|
|
20471
20892
|
id: u.id,
|
|
20472
20893
|
patch: applyLaneSnap(u.id, u.patch)
|
|
@@ -20481,8 +20902,7 @@ var SystemCanvas = (() => {
|
|
|
20481
20902
|
onNodeUpdate(id2, patch, currentCanvasRef);
|
|
20482
20903
|
}
|
|
20483
20904
|
}, [onNodeUpdate, onNodesUpdate, currentCanvasRef, applyLaneSnap]);
|
|
20484
|
-
const
|
|
20485
|
-
const handleNodeDrop = (0, import_react21.useCallback)((sources, target) => {
|
|
20905
|
+
const handleNodeDrop = (0, import_react23.useCallback)((sources, target) => {
|
|
20486
20906
|
onNodeDrop?.(sources, target, { canvasRef: currentCanvasRef });
|
|
20487
20907
|
}, [onNodeDrop, currentCanvasRef]);
|
|
20488
20908
|
const { dragOverrides, dropTargetId, onPointerDown: onNodePointerDown } = useNodeDrag({
|
|
@@ -20491,30 +20911,32 @@ var SystemCanvas = (() => {
|
|
|
20491
20911
|
onCommit: commitDragBatch,
|
|
20492
20912
|
svgRef: svgProxyRef,
|
|
20493
20913
|
canDropNodeOn,
|
|
20494
|
-
onNodeDrop: handleNodeDrop
|
|
20914
|
+
onNodeDrop: handleNodeDrop,
|
|
20915
|
+
selectedIdsRef
|
|
20495
20916
|
});
|
|
20496
20917
|
const { resizeOverrides, onHandlePointerDown: onResizeHandlePointerDown } = useNodeResize({
|
|
20497
20918
|
viewport: viewportStateRef,
|
|
20498
20919
|
onCommit: commitResize
|
|
20499
20920
|
});
|
|
20500
|
-
const
|
|
20501
|
-
|
|
20921
|
+
const singleSelectedId = selectedIds.size === 1 ? Array.from(selectedIds)[0] : null;
|
|
20922
|
+
const selectedResolvedNode = (0, import_react23.useMemo)(() => {
|
|
20923
|
+
if (!singleSelectedId)
|
|
20502
20924
|
return null;
|
|
20503
|
-
const base = nodeMap.get(
|
|
20925
|
+
const base = nodeMap.get(singleSelectedId);
|
|
20504
20926
|
if (!base)
|
|
20505
20927
|
return null;
|
|
20506
|
-
const resize = resizeOverrides.get(
|
|
20928
|
+
const resize = resizeOverrides.get(singleSelectedId);
|
|
20507
20929
|
if (resize) {
|
|
20508
20930
|
return { ...base, x: resize.x, y: resize.y, width: resize.width, height: resize.height };
|
|
20509
20931
|
}
|
|
20510
|
-
const drag = dragOverrides.get(
|
|
20932
|
+
const drag = dragOverrides.get(singleSelectedId);
|
|
20511
20933
|
if (drag) {
|
|
20512
20934
|
return { ...base, x: drag.x, y: drag.y };
|
|
20513
20935
|
}
|
|
20514
20936
|
return base;
|
|
20515
|
-
}, [
|
|
20937
|
+
}, [singleSelectedId, nodeMap, dragOverrides, resizeOverrides]);
|
|
20516
20938
|
svgProxyRef.current = viewportHandleRef.current?.getSvgElement() ?? null;
|
|
20517
|
-
const handleEdgeCreated = (0,
|
|
20939
|
+
const handleEdgeCreated = (0, import_react23.useCallback)((edge) => {
|
|
20518
20940
|
onEdgeAdd?.(edge, currentCanvasRef);
|
|
20519
20941
|
}, [onEdgeAdd, currentCanvasRef]);
|
|
20520
20942
|
const { pending: pendingEdge, onHandlePointerDown: onConnectionHandlePointerDown } = useEdgeCreate({
|
|
@@ -20523,7 +20945,7 @@ var SystemCanvas = (() => {
|
|
|
20523
20945
|
nodesRef,
|
|
20524
20946
|
onCreate: handleEdgeCreated
|
|
20525
20947
|
});
|
|
20526
|
-
const handleNavigableNodeClick = (0,
|
|
20948
|
+
const handleNavigableNodeClick = (0, import_react23.useCallback)((node) => {
|
|
20527
20949
|
const frame2 = {
|
|
20528
20950
|
parentCanvasRef: currentCanvasRef,
|
|
20529
20951
|
parentNodeRect: {
|
|
@@ -20550,7 +20972,7 @@ var SystemCanvas = (() => {
|
|
|
20550
20972
|
navigateToRef(node);
|
|
20551
20973
|
}
|
|
20552
20974
|
}, [navigateToRef, currentCanvasRef, zoomNavConfig.enabled]);
|
|
20553
|
-
const handleZoomEnter = (0,
|
|
20975
|
+
const handleZoomEnter = (0, import_react23.useCallback)((node, targetTransform) => {
|
|
20554
20976
|
const frame2 = {
|
|
20555
20977
|
parentCanvasRef: currentCanvasRef,
|
|
20556
20978
|
parentNodeRect: {
|
|
@@ -20564,7 +20986,7 @@ var SystemCanvas = (() => {
|
|
|
20564
20986
|
setPendingHandoff(targetTransform);
|
|
20565
20987
|
navigateToRef(node);
|
|
20566
20988
|
}, [currentCanvasRef, navigateToRef]);
|
|
20567
|
-
const handleZoomExit = (0,
|
|
20989
|
+
const handleZoomExit = (0, import_react23.useCallback)((targetTransform) => {
|
|
20568
20990
|
setPendingHandoff(targetTransform);
|
|
20569
20991
|
suppressNextHandoffClearRef.current = true;
|
|
20570
20992
|
navigateToBreadcrumb(breadcrumbs.length - 2);
|
|
@@ -20591,26 +21013,26 @@ var SystemCanvas = (() => {
|
|
|
20591
21013
|
onEnter: handleZoomEnter,
|
|
20592
21014
|
onExit: handleZoomExit
|
|
20593
21015
|
});
|
|
20594
|
-
const handleViewportChange = (0,
|
|
21016
|
+
const handleViewportChange = (0, import_react23.useCallback)((vp) => {
|
|
20595
21017
|
viewportStateRef.current = vp;
|
|
20596
21018
|
handleZoomNavViewportChange(vp);
|
|
20597
21019
|
onViewportChange?.(vp);
|
|
20598
21020
|
}, [handleZoomNavViewportChange, onViewportChange]);
|
|
20599
|
-
const handleHandoffApplied = (0,
|
|
21021
|
+
const handleHandoffApplied = (0, import_react23.useCallback)(() => {
|
|
20600
21022
|
setPendingHandoff(null);
|
|
20601
21023
|
clearZoomNavCommitting();
|
|
20602
21024
|
}, [clearZoomNavCommitting]);
|
|
20603
|
-
const handleBeginEdit = (0,
|
|
21025
|
+
const handleBeginEdit = (0, import_react23.useCallback)((node) => {
|
|
20604
21026
|
setEditingId(node.id);
|
|
20605
21027
|
}, []);
|
|
20606
|
-
const handleBeginEditEdge = (0,
|
|
21028
|
+
const handleBeginEditEdge = (0, import_react23.useCallback)((edge) => {
|
|
20607
21029
|
setEditingEdgeId(edge.id);
|
|
20608
21030
|
}, []);
|
|
20609
|
-
const [contextMenuState, setContextMenuState] = (0,
|
|
20610
|
-
(0,
|
|
21031
|
+
const [contextMenuState, setContextMenuState] = (0, import_react23.useState)(null);
|
|
21032
|
+
(0, import_react23.useEffect)(() => {
|
|
20611
21033
|
setContextMenuState(null);
|
|
20612
21034
|
}, [currentCanvasRef]);
|
|
20613
|
-
const handleContextMenu = (0,
|
|
21035
|
+
const handleContextMenu = (0, import_react23.useCallback)((event) => {
|
|
20614
21036
|
onContextMenu?.(event);
|
|
20615
21037
|
if (!nodeContextMenu)
|
|
20616
21038
|
return;
|
|
@@ -20642,32 +21064,38 @@ var SystemCanvas = (() => {
|
|
|
20642
21064
|
onNavigableNodeClick: handleNavigableNodeClick,
|
|
20643
21065
|
viewport: viewportStateRef,
|
|
20644
21066
|
editable,
|
|
20645
|
-
onSelect:
|
|
21067
|
+
onSelect: (id2) => {
|
|
21068
|
+
if (id2)
|
|
21069
|
+
selectNode(id2);
|
|
21070
|
+
else
|
|
21071
|
+
clearSelection();
|
|
21072
|
+
},
|
|
21073
|
+
onToggleSelect: toggleNode,
|
|
20646
21074
|
onBeginEdit: handleBeginEdit,
|
|
20647
21075
|
onSelectEdge: setSelectedEdgeId,
|
|
20648
21076
|
onBeginEditEdge: handleBeginEditEdge
|
|
20649
21077
|
});
|
|
20650
|
-
const handleEditorCommit = (0,
|
|
21078
|
+
const handleEditorCommit = (0, import_react23.useCallback)((patch) => {
|
|
20651
21079
|
if (editingId) {
|
|
20652
21080
|
onNodeUpdate?.(editingId, patch, currentCanvasRef);
|
|
20653
21081
|
}
|
|
20654
21082
|
setEditingId(null);
|
|
20655
21083
|
}, [editingId, onNodeUpdate, currentCanvasRef]);
|
|
20656
|
-
const handleEditorCancel = (0,
|
|
21084
|
+
const handleEditorCancel = (0, import_react23.useCallback)(() => {
|
|
20657
21085
|
setEditingId(null);
|
|
20658
21086
|
}, []);
|
|
20659
|
-
const handleEdgeEditorCommit = (0,
|
|
21087
|
+
const handleEdgeEditorCommit = (0, import_react23.useCallback)((patch) => {
|
|
20660
21088
|
if (editingEdgeId) {
|
|
20661
21089
|
onEdgeUpdate?.(editingEdgeId, patch, currentCanvasRef);
|
|
20662
21090
|
}
|
|
20663
21091
|
setEditingEdgeId(null);
|
|
20664
21092
|
}, [editingEdgeId, onEdgeUpdate, currentCanvasRef]);
|
|
20665
|
-
const handleEdgeEditorCancel = (0,
|
|
21093
|
+
const handleEdgeEditorCancel = (0, import_react23.useCallback)(() => {
|
|
20666
21094
|
setEditingEdgeId(null);
|
|
20667
21095
|
}, []);
|
|
20668
|
-
const lastAddRef = (0,
|
|
20669
|
-
const menuOptions = (0,
|
|
20670
|
-
const addNode2 = (0,
|
|
21096
|
+
const lastAddRef = (0, import_react23.useRef)(null);
|
|
21097
|
+
const menuOptions = (0, import_react23.useMemo)(() => getNodeMenuOptions(currentCanvas, theme), [currentCanvas, theme]);
|
|
21098
|
+
const addNode2 = (0, import_react23.useCallback)((option, position) => {
|
|
20671
21099
|
let x, y;
|
|
20672
21100
|
if (position) {
|
|
20673
21101
|
x = position.x;
|
|
@@ -20699,23 +21127,33 @@ var SystemCanvas = (() => {
|
|
|
20699
21127
|
const node = createNodeFromOption(option, Math.round(x), Math.round(y), void 0, theme);
|
|
20700
21128
|
onNodeAdd?.(node, currentCanvasRef);
|
|
20701
21129
|
}, [onNodeAdd, currentCanvasRef, theme]);
|
|
20702
|
-
const handleKeyDown = (0,
|
|
21130
|
+
const handleKeyDown = (0, import_react23.useCallback)((e) => {
|
|
20703
21131
|
if (!editable)
|
|
20704
21132
|
return;
|
|
20705
21133
|
if (e.key === "Escape") {
|
|
20706
21134
|
setEditingId(null);
|
|
20707
|
-
|
|
21135
|
+
clearSelection();
|
|
20708
21136
|
setEditingEdgeId(null);
|
|
20709
21137
|
setSelectedEdgeId(null);
|
|
20710
21138
|
return;
|
|
20711
21139
|
}
|
|
20712
21140
|
if (editingId || editingEdgeId)
|
|
20713
21141
|
return;
|
|
21142
|
+
if ((e.metaKey || e.ctrlKey) && e.key === "a") {
|
|
21143
|
+
e.preventDefault();
|
|
21144
|
+
selectAll();
|
|
21145
|
+
return;
|
|
21146
|
+
}
|
|
20714
21147
|
if (e.key === "Delete" || e.key === "Backspace") {
|
|
20715
|
-
if (
|
|
21148
|
+
if (selectedIds.size > 1) {
|
|
21149
|
+
e.preventDefault();
|
|
21150
|
+
onNodesDelete?.(Array.from(selectedIds), currentCanvasRef);
|
|
21151
|
+
clearSelection();
|
|
21152
|
+
} else if (selectedIds.size === 1) {
|
|
21153
|
+
const id2 = Array.from(selectedIds)[0];
|
|
20716
21154
|
e.preventDefault();
|
|
20717
|
-
onNodeDelete?.(
|
|
20718
|
-
|
|
21155
|
+
onNodeDelete?.(id2, currentCanvasRef);
|
|
21156
|
+
clearSelection();
|
|
20719
21157
|
} else if (selectedEdgeId) {
|
|
20720
21158
|
e.preventDefault();
|
|
20721
21159
|
onEdgeDelete?.(selectedEdgeId, currentCanvasRef);
|
|
@@ -20726,11 +21164,14 @@ var SystemCanvas = (() => {
|
|
|
20726
21164
|
editable,
|
|
20727
21165
|
editingId,
|
|
20728
21166
|
editingEdgeId,
|
|
20729
|
-
|
|
21167
|
+
selectedIds,
|
|
20730
21168
|
selectedEdgeId,
|
|
20731
21169
|
onNodeDelete,
|
|
21170
|
+
onNodesDelete,
|
|
20732
21171
|
onEdgeDelete,
|
|
20733
|
-
currentCanvasRef
|
|
21172
|
+
currentCanvasRef,
|
|
21173
|
+
clearSelection,
|
|
21174
|
+
selectAll
|
|
20734
21175
|
]);
|
|
20735
21176
|
const renderProps = { options: menuOptions, addNode: addNode2, theme };
|
|
20736
21177
|
return (0, import_jsx_runtime28.jsxs)("div", { ref: containerRef, className: `system-canvas ${className ?? ""}`, tabIndex: editable ? 0 : -1, onKeyDown: handleKeyDown, style: {
|
|
@@ -20752,12 +21193,26 @@ var SystemCanvas = (() => {
|
|
|
20752
21193
|
fontFamily: theme.node.fontFamily,
|
|
20753
21194
|
fontSize: 12,
|
|
20754
21195
|
backdropFilter: "blur(8px)"
|
|
20755
|
-
}, children: "Loading..." }), (0, import_jsx_runtime28.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,
|
|
21196
|
+
}, children: "Loading..." }), (0, import_jsx_runtime28.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 }), showLaneHeaders && (0, import_jsx_runtime28.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_runtime28.jsx)(NodeToolbar, { node: selectedResolvedNode, theme, onPatch: (update) => {
|
|
20756
21197
|
onNodeUpdate?.(selectedResolvedNode.id, update, currentCanvasRef);
|
|
20757
21198
|
}, onDelete: () => {
|
|
20758
21199
|
onNodeDelete?.(selectedResolvedNode.id, currentCanvasRef);
|
|
20759
|
-
|
|
20760
|
-
}, getViewport: getViewportState, containerWidth: containerSize.width, containerHeight: containerSize.height, render: renderNodeToolbar }), editable &&
|
|
21200
|
+
clearSelection();
|
|
21201
|
+
}, getViewport: getViewportState, containerWidth: containerSize.width, containerHeight: containerSize.height, render: renderNodeToolbar }), editable && showNodeToolbar && selectedIds.size > 1 && !editingId && (() => {
|
|
21202
|
+
const selectedResolvedNodes = Array.from(selectedIds).map((id2) => nodeMap.get(id2)).filter((n) => n != null);
|
|
21203
|
+
if (selectedResolvedNodes.length === 0)
|
|
21204
|
+
return null;
|
|
21205
|
+
const anchorNode = selectedResolvedNodes[0];
|
|
21206
|
+
return (0, import_jsx_runtime28.jsx)(NodeToolbar, { node: anchorNode, selectedNodes: selectedResolvedNodes, theme, onPatch: () => {
|
|
21207
|
+
}, onMultiPatch: (patch) => {
|
|
21208
|
+
for (const id2 of selectedIds) {
|
|
21209
|
+
onNodeUpdate?.(id2, patch, currentCanvasRef);
|
|
21210
|
+
}
|
|
21211
|
+
}, onDelete: () => {
|
|
21212
|
+
onNodesDelete?.(Array.from(selectedIds), currentCanvasRef);
|
|
21213
|
+
clearSelection();
|
|
21214
|
+
}, getViewport: getViewportState, containerWidth: containerSize.width, containerHeight: containerSize.height });
|
|
21215
|
+
})(), editable && (renderAddNodeButton ? renderAddNodeButton(renderProps) : (0, import_jsx_runtime28.jsx)(AddNodeButton, { ...renderProps })), nodeContextMenu && (0, import_jsx_runtime28.jsx)(NodeContextMenuOverlay, { state: contextMenuState, config: nodeContextMenu, theme, onClose: () => setContextMenuState(null) })] });
|
|
20761
21216
|
});
|
|
20762
21217
|
|
|
20763
21218
|
// src/index.tsx
|
|
@@ -20868,7 +21323,7 @@ var SystemCanvas = (() => {
|
|
|
20868
21323
|
onEdgeUpdate: handleEdgeUpdate,
|
|
20869
21324
|
onEdgeDelete: handleEdgeDelete
|
|
20870
21325
|
};
|
|
20871
|
-
root2.render(
|
|
21326
|
+
root2.render(import_react24.default.createElement(SystemCanvas, props));
|
|
20872
21327
|
};
|
|
20873
21328
|
doRender();
|
|
20874
21329
|
return {
|