system-canvas-standalone 0.2.2 → 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 +628 -197
- 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
|
@@ -12764,7 +12764,7 @@ var SystemCanvas = (() => {
|
|
|
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 = {
|
|
@@ -15150,8 +15150,305 @@ var SystemCanvas = (() => {
|
|
|
15150
15150
|
return { pending, onHandlePointerDown };
|
|
15151
15151
|
}
|
|
15152
15152
|
|
|
15153
|
-
// ../react/dist/hooks/
|
|
15153
|
+
// ../react/dist/hooks/useMultiSelect.js
|
|
15154
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);
|
|
15155
15452
|
function expandRect(rect, factor) {
|
|
15156
15453
|
if (factor === 1)
|
|
15157
15454
|
return rect;
|
|
@@ -15189,16 +15486,16 @@ var SystemCanvas = (() => {
|
|
|
15189
15486
|
}
|
|
15190
15487
|
function useZoomNavigation(options) {
|
|
15191
15488
|
const { enabled, config, nodes, currentCanvas, parentFrame, canvases, onResolveCanvas, onSeedCanvas, theme, getViewportSize, getCursorScreenPos, onEnter, onExit } = options;
|
|
15192
|
-
const committingRef = (0,
|
|
15193
|
-
(0,
|
|
15489
|
+
const committingRef = (0, import_react8.useRef)(false);
|
|
15490
|
+
(0, import_react8.useEffect)(() => {
|
|
15194
15491
|
committingRef.current = false;
|
|
15195
15492
|
}, [currentCanvas]);
|
|
15196
|
-
const exitArmedRef = (0,
|
|
15197
|
-
(0,
|
|
15493
|
+
const exitArmedRef = (0, import_react8.useRef)(false);
|
|
15494
|
+
(0, import_react8.useEffect)(() => {
|
|
15198
15495
|
exitArmedRef.current = false;
|
|
15199
15496
|
}, [currentCanvas, parentFrame]);
|
|
15200
|
-
const prefetchRef = (0,
|
|
15201
|
-
const prefetch = (0,
|
|
15497
|
+
const prefetchRef = (0, import_react8.useRef)(/* @__PURE__ */ new Map());
|
|
15498
|
+
const prefetch = (0, import_react8.useCallback)((ref) => {
|
|
15202
15499
|
if (!onResolveCanvas)
|
|
15203
15500
|
return;
|
|
15204
15501
|
if (canvases?.[ref])
|
|
@@ -15216,7 +15513,7 @@ var SystemCanvas = (() => {
|
|
|
15216
15513
|
state.loading = false;
|
|
15217
15514
|
});
|
|
15218
15515
|
}, [canvases, onResolveCanvas, onSeedCanvas]);
|
|
15219
|
-
const handleViewportChange = (0,
|
|
15516
|
+
const handleViewportChange = (0, import_react8.useCallback)((vp) => {
|
|
15220
15517
|
if (!enabled)
|
|
15221
15518
|
return;
|
|
15222
15519
|
if (committingRef.current)
|
|
@@ -15355,7 +15652,7 @@ var SystemCanvas = (() => {
|
|
|
15355
15652
|
onEnter,
|
|
15356
15653
|
onExit
|
|
15357
15654
|
]);
|
|
15358
|
-
const clearCommitting = (0,
|
|
15655
|
+
const clearCommitting = (0, import_react8.useCallback)(() => {
|
|
15359
15656
|
committingRef.current = false;
|
|
15360
15657
|
}, []);
|
|
15361
15658
|
return { handleViewportChange, clearCommitting };
|
|
@@ -15363,10 +15660,10 @@ var SystemCanvas = (() => {
|
|
|
15363
15660
|
|
|
15364
15661
|
// ../react/dist/components/Viewport.js
|
|
15365
15662
|
var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1);
|
|
15366
|
-
var
|
|
15663
|
+
var import_react17 = __toESM(require_react(), 1);
|
|
15367
15664
|
|
|
15368
15665
|
// ../react/dist/hooks/useViewport.js
|
|
15369
|
-
var
|
|
15666
|
+
var import_react9 = __toESM(require_react(), 1);
|
|
15370
15667
|
|
|
15371
15668
|
// ../../node_modules/d3-dispatch/src/dispatch.js
|
|
15372
15669
|
var noop = { value: () => {
|
|
@@ -18109,13 +18406,13 @@ var SystemCanvas = (() => {
|
|
|
18109
18406
|
// ../react/dist/hooks/useViewport.js
|
|
18110
18407
|
function useViewport(options) {
|
|
18111
18408
|
const { minZoom, maxZoom, defaultViewport, onViewportChange, marqueeActiveRef } = options;
|
|
18112
|
-
const svgRef = (0,
|
|
18113
|
-
const groupRef = (0,
|
|
18114
|
-
const viewport = (0,
|
|
18115
|
-
const zoomBehaviorRef = (0,
|
|
18116
|
-
const onViewportChangeRef = (0,
|
|
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);
|
|
18117
18414
|
onViewportChangeRef.current = onViewportChange;
|
|
18118
|
-
(0,
|
|
18415
|
+
(0, import_react9.useEffect)(() => {
|
|
18119
18416
|
const svg = svgRef.current;
|
|
18120
18417
|
const group = groupRef.current;
|
|
18121
18418
|
if (!svg || !group)
|
|
@@ -18155,7 +18452,7 @@ var SystemCanvas = (() => {
|
|
|
18155
18452
|
selection2.on(".zoom", null);
|
|
18156
18453
|
};
|
|
18157
18454
|
}, [minZoom, maxZoom]);
|
|
18158
|
-
const fitToContent = (0,
|
|
18455
|
+
const fitToContent = (0, import_react9.useCallback)((nodes, animate = true) => {
|
|
18159
18456
|
const svg = svgRef.current;
|
|
18160
18457
|
if (!svg || !zoomBehaviorRef.current || nodes.length === 0)
|
|
18161
18458
|
return;
|
|
@@ -18168,13 +18465,13 @@ var SystemCanvas = (() => {
|
|
|
18168
18465
|
select_default2(svg).call(zoomBehaviorRef.current.transform, t);
|
|
18169
18466
|
}
|
|
18170
18467
|
}, []);
|
|
18171
|
-
const resetZoom = (0,
|
|
18468
|
+
const resetZoom = (0, import_react9.useCallback)(() => {
|
|
18172
18469
|
const svg = svgRef.current;
|
|
18173
18470
|
if (!svg || !zoomBehaviorRef.current)
|
|
18174
18471
|
return;
|
|
18175
18472
|
select_default2(svg).transition().duration(400).call(zoomBehaviorRef.current.transform, identity2);
|
|
18176
18473
|
}, []);
|
|
18177
|
-
const setTransform = (0,
|
|
18474
|
+
const setTransform = (0, import_react9.useCallback)((transform2, options2) => {
|
|
18178
18475
|
const svg = svgRef.current;
|
|
18179
18476
|
if (!svg || !zoomBehaviorRef.current)
|
|
18180
18477
|
return;
|
|
@@ -18186,7 +18483,7 @@ var SystemCanvas = (() => {
|
|
|
18186
18483
|
sel.call(zoomBehaviorRef.current.transform, t);
|
|
18187
18484
|
}
|
|
18188
18485
|
}, []);
|
|
18189
|
-
const zoomToNode = (0,
|
|
18486
|
+
const zoomToNode = (0, import_react9.useCallback)((node, onComplete, options2) => {
|
|
18190
18487
|
const svg = svgRef.current;
|
|
18191
18488
|
if (!svg || !zoomBehaviorRef.current) {
|
|
18192
18489
|
onComplete?.();
|
|
@@ -18380,9 +18677,9 @@ var SystemCanvas = (() => {
|
|
|
18380
18677
|
|
|
18381
18678
|
// ../react/dist/components/RefIndicator.js
|
|
18382
18679
|
var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
|
|
18383
|
-
var
|
|
18680
|
+
var import_react10 = __toESM(require_react(), 1);
|
|
18384
18681
|
function RefIndicator({ node, theme, nodeX, nodeY, nodeWidth, nodeHeight, strokeColor, strokeWidth, corner = "bottom-right", size: sizeProp, onNavigate }) {
|
|
18385
|
-
const [hover, setHover] = (0,
|
|
18682
|
+
const [hover, setHover] = (0, import_react10.useState)(false);
|
|
18386
18683
|
const iconKind = theme.node.refIndicator.icon;
|
|
18387
18684
|
if (iconKind === "none")
|
|
18388
18685
|
return null;
|
|
@@ -18453,7 +18750,7 @@ var SystemCanvas = (() => {
|
|
|
18453
18750
|
|
|
18454
18751
|
// ../react/dist/components/CategorySlotsLayer.js
|
|
18455
18752
|
var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1);
|
|
18456
|
-
var
|
|
18753
|
+
var import_react12 = __toESM(require_react(), 1);
|
|
18457
18754
|
|
|
18458
18755
|
// ../react/dist/primitives/NodeColorFill.js
|
|
18459
18756
|
var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -18573,9 +18870,9 @@ var SystemCanvas = (() => {
|
|
|
18573
18870
|
|
|
18574
18871
|
// ../react/dist/primitives/NodeText.js
|
|
18575
18872
|
var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
|
|
18576
|
-
var
|
|
18873
|
+
var import_react11 = __toESM(require_react(), 1);
|
|
18577
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" }) {
|
|
18578
|
-
const reactId = (0,
|
|
18875
|
+
const reactId = (0, import_react11.useId)();
|
|
18579
18876
|
const safeId = reactId.replace(/:/g, "");
|
|
18580
18877
|
if (!value)
|
|
18581
18878
|
return null;
|
|
@@ -18649,8 +18946,8 @@ var SystemCanvas = (() => {
|
|
|
18649
18946
|
// ../react/dist/components/CategorySlotsLayer.js
|
|
18650
18947
|
function CategorySlotsLayer({ node, theme, canvases, slots: slotsProp }) {
|
|
18651
18948
|
const slots = slotsProp ?? getCategorySlots(node, theme);
|
|
18652
|
-
const regions = (0,
|
|
18653
|
-
const reactId = (0,
|
|
18949
|
+
const regions = (0, import_react12.useMemo)(() => computeCategorySlotRegions(node, theme, slots), [node, theme, slots]);
|
|
18950
|
+
const reactId = (0, import_react12.useId)();
|
|
18654
18951
|
const clipId = `sc-edge-clip-${reactId.replace(/:/g, "")}`;
|
|
18655
18952
|
if (!slots)
|
|
18656
18953
|
return null;
|
|
@@ -18883,7 +19180,7 @@ var SystemCanvas = (() => {
|
|
|
18883
19180
|
|
|
18884
19181
|
// ../react/dist/components/ResizeHandles.js
|
|
18885
19182
|
var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
|
|
18886
|
-
var
|
|
19183
|
+
var import_react13 = __toESM(require_react(), 1);
|
|
18887
19184
|
var HANDLE_SIZE = 7;
|
|
18888
19185
|
var CORNERS = [
|
|
18889
19186
|
{ corner: "nw", cursor: "nwse-resize", anchor: "nw" },
|
|
@@ -18894,7 +19191,7 @@ var SystemCanvas = (() => {
|
|
|
18894
19191
|
var cornerInset = (cornerRadius) => Math.min(cornerRadius * 0.25, 3);
|
|
18895
19192
|
function ResizeHandles({ node, theme, onHandlePointerDown }) {
|
|
18896
19193
|
const { x, y, width, height } = node;
|
|
18897
|
-
const [hoveredCorner, setHoveredCorner] = (0,
|
|
19194
|
+
const [hoveredCorner, setHoveredCorner] = (0, import_react13.useState)(null);
|
|
18898
19195
|
const handleColor = node.resolvedStroke ?? theme.node.labelColor;
|
|
18899
19196
|
const i = cornerInset(node.resolvedCornerRadius);
|
|
18900
19197
|
const anchorPos = (anchor) => {
|
|
@@ -18919,7 +19216,7 @@ var SystemCanvas = (() => {
|
|
|
18919
19216
|
}
|
|
18920
19217
|
|
|
18921
19218
|
// ../react/dist/components/NodeRenderer.js
|
|
18922
|
-
function NodeRenderer({ nodes, theme, onClick, onDoubleClick, onContextMenu, onNavigate, onPointerDown,
|
|
19219
|
+
function NodeRenderer({ nodes, theme, onClick, onDoubleClick, onContextMenu, onNavigate, onPointerDown, selectedIds, editingId, onResizeHandlePointerDown, canvases, only }) {
|
|
18923
19220
|
const groups = nodes.filter((n) => n.type === "group");
|
|
18924
19221
|
const others = nodes.filter((n) => n.type !== "group");
|
|
18925
19222
|
const common = (node) => {
|
|
@@ -18935,7 +19232,7 @@ var SystemCanvas = (() => {
|
|
|
18935
19232
|
onContextMenu,
|
|
18936
19233
|
onNavigate,
|
|
18937
19234
|
onPointerDown,
|
|
18938
|
-
isSelected:
|
|
19235
|
+
isSelected: selectedIds?.has(node.id) ?? false,
|
|
18939
19236
|
isEditing: editingId === node.id,
|
|
18940
19237
|
slots,
|
|
18941
19238
|
canvases,
|
|
@@ -18946,7 +19243,8 @@ var SystemCanvas = (() => {
|
|
|
18946
19243
|
refCorner
|
|
18947
19244
|
};
|
|
18948
19245
|
};
|
|
18949
|
-
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;
|
|
18950
19248
|
const renderResizeHandles = only !== "groups" && selectedNode && onResizeHandlePointerDown;
|
|
18951
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) => {
|
|
18952
19250
|
const Component = getNodeComponent(node.type);
|
|
@@ -19004,7 +19302,7 @@ var SystemCanvas = (() => {
|
|
|
19004
19302
|
|
|
19005
19303
|
// ../react/dist/components/NodeEditor.js
|
|
19006
19304
|
var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
|
|
19007
|
-
var
|
|
19305
|
+
var import_react14 = __toESM(require_react(), 1);
|
|
19008
19306
|
function NodeEditor({ node, theme, onCommit, onCancel }) {
|
|
19009
19307
|
const editableFields = useCategoryFields(node, theme);
|
|
19010
19308
|
if (editableFields) {
|
|
@@ -19023,11 +19321,11 @@ var SystemCanvas = (() => {
|
|
|
19023
19321
|
}
|
|
19024
19322
|
function SingleFieldEditor({ node, theme, onCommit, onCancel }) {
|
|
19025
19323
|
const initial = getInitialValue(node);
|
|
19026
|
-
const [value, setValue] = (0,
|
|
19027
|
-
const textareaRef = (0,
|
|
19028
|
-
const inputRef = (0,
|
|
19029
|
-
const committedRef = (0,
|
|
19030
|
-
(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)(() => {
|
|
19031
19329
|
const el = textareaRef.current ?? inputRef.current;
|
|
19032
19330
|
if (el) {
|
|
19033
19331
|
el.focus();
|
|
@@ -19123,10 +19421,10 @@ var SystemCanvas = (() => {
|
|
|
19123
19421
|
}
|
|
19124
19422
|
}
|
|
19125
19423
|
function FormEditor({ node, theme, fields, onCommit, onCancel }) {
|
|
19126
|
-
const initial = (0,
|
|
19127
|
-
const [values, setValues] = (0,
|
|
19128
|
-
const committedRef = (0,
|
|
19129
|
-
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);
|
|
19130
19428
|
const width = Math.max(node.width, 240);
|
|
19131
19429
|
const height = Math.max(node.height, 36 + fields.length * 44);
|
|
19132
19430
|
const commit = () => {
|
|
@@ -19155,7 +19453,7 @@ var SystemCanvas = (() => {
|
|
|
19155
19453
|
const stopPointer = (e) => {
|
|
19156
19454
|
e.stopPropagation();
|
|
19157
19455
|
};
|
|
19158
|
-
(0,
|
|
19456
|
+
(0, import_react14.useEffect)(() => {
|
|
19159
19457
|
const el = panelRef.current;
|
|
19160
19458
|
if (!el)
|
|
19161
19459
|
return;
|
|
@@ -19285,13 +19583,13 @@ var SystemCanvas = (() => {
|
|
|
19285
19583
|
|
|
19286
19584
|
// ../react/dist/components/EdgeLabelEditor.js
|
|
19287
19585
|
var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
|
|
19288
|
-
var
|
|
19586
|
+
var import_react15 = __toESM(require_react(), 1);
|
|
19289
19587
|
var EDITOR_WIDTH = 110;
|
|
19290
19588
|
function EdgeLabelEditor({ initialLabel, midpoint, theme, onCommit, onCancel }) {
|
|
19291
|
-
const [value, setValue] = (0,
|
|
19292
|
-
const inputRef = (0,
|
|
19293
|
-
const committedRef = (0,
|
|
19294
|
-
(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)(() => {
|
|
19295
19593
|
const el = inputRef.current;
|
|
19296
19594
|
if (el) {
|
|
19297
19595
|
el.focus();
|
|
@@ -19346,7 +19644,7 @@ var SystemCanvas = (() => {
|
|
|
19346
19644
|
|
|
19347
19645
|
// ../react/dist/components/ConnectionHandles.js
|
|
19348
19646
|
var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1);
|
|
19349
|
-
var
|
|
19647
|
+
var import_react16 = __toESM(require_react(), 1);
|
|
19350
19648
|
var SIDES = ["top", "right", "bottom", "left"];
|
|
19351
19649
|
var HANDLE_RADIUS = 4;
|
|
19352
19650
|
var HANDLE_HIT_RADIUS = 10;
|
|
@@ -19355,9 +19653,9 @@ var SystemCanvas = (() => {
|
|
|
19355
19653
|
var HOVER_SCALE = 1.42;
|
|
19356
19654
|
var HOVER_TRANSITION_MS = 120;
|
|
19357
19655
|
function ConnectionHandles({ node, theme, onHandlePointerDown, immediate, activeSide }) {
|
|
19358
|
-
const [visible, setVisible] = (0,
|
|
19359
|
-
const [hoveredSide, setHoveredSide] = (0,
|
|
19360
|
-
(0,
|
|
19656
|
+
const [visible, setVisible] = (0, import_react16.useState)(!!immediate);
|
|
19657
|
+
const [hoveredSide, setHoveredSide] = (0, import_react16.useState)(null);
|
|
19658
|
+
(0, import_react16.useEffect)(() => {
|
|
19361
19659
|
if (immediate) {
|
|
19362
19660
|
setVisible(true);
|
|
19363
19661
|
return;
|
|
@@ -19444,17 +19742,18 @@ var SystemCanvas = (() => {
|
|
|
19444
19742
|
// ../react/dist/components/Viewport.js
|
|
19445
19743
|
var HOVER_PADDING = 10;
|
|
19446
19744
|
var EDGE_PROXIMITY = 16;
|
|
19447
|
-
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) {
|
|
19448
19746
|
const { svgRef, groupRef, viewport, fitToContent, zoomToNode, setTransform } = useViewport({
|
|
19449
19747
|
minZoom,
|
|
19450
19748
|
maxZoom,
|
|
19451
19749
|
defaultViewport,
|
|
19452
|
-
onViewportChange
|
|
19750
|
+
onViewportChange,
|
|
19751
|
+
marqueeActiveRef
|
|
19453
19752
|
});
|
|
19454
|
-
const navigatingRef = (0,
|
|
19455
|
-
const fadeRafRef = (0,
|
|
19456
|
-
const fadeTimeoutRef = (0,
|
|
19457
|
-
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) => {
|
|
19458
19757
|
if (durationMs <= 0)
|
|
19459
19758
|
return;
|
|
19460
19759
|
const g = groupRef.current;
|
|
@@ -19477,7 +19776,7 @@ var SystemCanvas = (() => {
|
|
|
19477
19776
|
}, durationMs + 16);
|
|
19478
19777
|
});
|
|
19479
19778
|
}, []);
|
|
19480
|
-
(0,
|
|
19779
|
+
(0, import_react17.useEffect)(() => {
|
|
19481
19780
|
return () => {
|
|
19482
19781
|
if (fadeRafRef.current !== null)
|
|
19483
19782
|
cancelAnimationFrame(fadeRafRef.current);
|
|
@@ -19485,10 +19784,10 @@ var SystemCanvas = (() => {
|
|
|
19485
19784
|
clearTimeout(fadeTimeoutRef.current);
|
|
19486
19785
|
};
|
|
19487
19786
|
}, []);
|
|
19488
|
-
const [hoveredNodeId, setHoveredNodeId] = (0,
|
|
19489
|
-
const [hoveredSide, setHoveredSide] = (0,
|
|
19490
|
-
const cursorPosRef = (0,
|
|
19491
|
-
(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, () => ({
|
|
19492
19791
|
zoomToNode: (node, onComplete, options) => {
|
|
19493
19792
|
navigatingRef.current = true;
|
|
19494
19793
|
zoomToNode(node, onComplete, options);
|
|
@@ -19499,7 +19798,7 @@ var SystemCanvas = (() => {
|
|
|
19499
19798
|
getViewport: () => viewport.current ?? { x: 0, y: 0, zoom: 1 },
|
|
19500
19799
|
getCursorScreenPos: () => cursorPosRef.current
|
|
19501
19800
|
}));
|
|
19502
|
-
const renderNodes = (0,
|
|
19801
|
+
const renderNodes = (0, import_react17.useMemo)(() => {
|
|
19503
19802
|
const hasDrag = dragOverrides && dragOverrides.size > 0;
|
|
19504
19803
|
const hasResize = resizeOverrides && resizeOverrides.size > 0;
|
|
19505
19804
|
if (!hasDrag && !hasResize)
|
|
@@ -19512,7 +19811,7 @@ var SystemCanvas = (() => {
|
|
|
19512
19811
|
return d ? { ...n, x: d.x, y: d.y } : n;
|
|
19513
19812
|
});
|
|
19514
19813
|
}, [nodes, dragOverrides, resizeOverrides]);
|
|
19515
|
-
const renderNodeMap = (0,
|
|
19814
|
+
const renderNodeMap = (0, import_react17.useMemo)(() => {
|
|
19516
19815
|
const hasDrag = dragOverrides && dragOverrides.size > 0;
|
|
19517
19816
|
const hasResize = resizeOverrides && resizeOverrides.size > 0;
|
|
19518
19817
|
if (!hasDrag && !hasResize)
|
|
@@ -19523,11 +19822,11 @@ var SystemCanvas = (() => {
|
|
|
19523
19822
|
}
|
|
19524
19823
|
return m;
|
|
19525
19824
|
}, [renderNodes, nodeMap, dragOverrides, resizeOverrides]);
|
|
19526
|
-
const latestNodesRef = (0,
|
|
19527
|
-
(0,
|
|
19825
|
+
const latestNodesRef = (0, import_react17.useRef)(nodes);
|
|
19826
|
+
(0, import_react17.useEffect)(() => {
|
|
19528
19827
|
latestNodesRef.current = nodes;
|
|
19529
19828
|
}, [nodes]);
|
|
19530
|
-
const fitNow = (0,
|
|
19829
|
+
const fitNow = (0, import_react17.useCallback)(() => {
|
|
19531
19830
|
const current = latestNodesRef.current;
|
|
19532
19831
|
if (current.length === 0)
|
|
19533
19832
|
return;
|
|
@@ -19537,7 +19836,7 @@ var SystemCanvas = (() => {
|
|
|
19537
19836
|
fitToContent(current, animate);
|
|
19538
19837
|
});
|
|
19539
19838
|
}, [fitToContent]);
|
|
19540
|
-
(0,
|
|
19839
|
+
(0, import_react17.useEffect)(() => {
|
|
19541
19840
|
if (defaultViewport)
|
|
19542
19841
|
return;
|
|
19543
19842
|
if (autoFit !== "always")
|
|
@@ -19546,8 +19845,8 @@ var SystemCanvas = (() => {
|
|
|
19546
19845
|
return;
|
|
19547
19846
|
fitNow();
|
|
19548
19847
|
}, [nodes, autoFit, defaultViewport, fitNow]);
|
|
19549
|
-
const fittedForRef = (0,
|
|
19550
|
-
(0,
|
|
19848
|
+
const fittedForRef = (0, import_react17.useRef)(null);
|
|
19849
|
+
(0, import_react17.useEffect)(() => {
|
|
19551
19850
|
if (defaultViewport)
|
|
19552
19851
|
return;
|
|
19553
19852
|
if (autoFit !== "canvas-change" && autoFit !== "initial")
|
|
@@ -19579,7 +19878,7 @@ var SystemCanvas = (() => {
|
|
|
19579
19878
|
triggerFade
|
|
19580
19879
|
]);
|
|
19581
19880
|
const editingNode = editingId ? renderNodes.find((n) => n.id === editingId) ?? null : null;
|
|
19582
|
-
const handleSvgPointerMove = (0,
|
|
19881
|
+
const handleSvgPointerMove = (0, import_react17.useCallback)((event) => {
|
|
19583
19882
|
const svg = svgRef.current;
|
|
19584
19883
|
if (!svg)
|
|
19585
19884
|
return;
|
|
@@ -19631,7 +19930,7 @@ var SystemCanvas = (() => {
|
|
|
19631
19930
|
setHoveredSide((prev) => prev === null ? prev : null);
|
|
19632
19931
|
}
|
|
19633
19932
|
}, [edgeCreateEnabled, renderNodes, svgRef, viewport]);
|
|
19634
|
-
const handleSvgPointerLeave = (0,
|
|
19933
|
+
const handleSvgPointerLeave = (0, import_react17.useCallback)(() => {
|
|
19635
19934
|
setHoveredNodeId(null);
|
|
19636
19935
|
setHoveredSide(null);
|
|
19637
19936
|
cursorPosRef.current = null;
|
|
@@ -19660,12 +19959,17 @@ var SystemCanvas = (() => {
|
|
|
19660
19959
|
WebkitUserSelect: "none",
|
|
19661
19960
|
MozUserSelect: "none",
|
|
19662
19961
|
msUserSelect: "none"
|
|
19663
|
-
}, 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" })] });
|
|
19664
19968
|
});
|
|
19665
19969
|
|
|
19666
19970
|
// ../react/dist/components/Breadcrumbs.js
|
|
19667
19971
|
var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1);
|
|
19668
|
-
var
|
|
19972
|
+
var import_react18 = __toESM(require_react(), 1);
|
|
19669
19973
|
function Breadcrumbs({ breadcrumbs, theme, onNavigate }) {
|
|
19670
19974
|
if (breadcrumbs.length <= 1)
|
|
19671
19975
|
return null;
|
|
@@ -19686,7 +19990,7 @@ var SystemCanvas = (() => {
|
|
|
19686
19990
|
backdropFilter: "blur(8px)"
|
|
19687
19991
|
}, children: breadcrumbs.map((crumb, index) => {
|
|
19688
19992
|
const isLast = index === breadcrumbs.length - 1;
|
|
19689
|
-
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: {
|
|
19690
19994
|
color: theme.separatorColor,
|
|
19691
19995
|
margin: "0 2px"
|
|
19692
19996
|
}, children: "/" }), (0, import_jsx_runtime23.jsx)("span", { onClick: isLast ? void 0 : () => onNavigate(index), style: {
|
|
@@ -19710,11 +20014,11 @@ var SystemCanvas = (() => {
|
|
|
19710
20014
|
|
|
19711
20015
|
// ../react/dist/components/AddNodeButton.js
|
|
19712
20016
|
var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1);
|
|
19713
|
-
var
|
|
20017
|
+
var import_react19 = __toESM(require_react(), 1);
|
|
19714
20018
|
function AddNodeButton({ options, addNode: addNode2, theme }) {
|
|
19715
|
-
const [open, setOpen] = (0,
|
|
19716
|
-
const rootRef = (0,
|
|
19717
|
-
(0,
|
|
20019
|
+
const [open, setOpen] = (0, import_react19.useState)(false);
|
|
20020
|
+
const rootRef = (0, import_react19.useRef)(null);
|
|
20021
|
+
(0, import_react19.useEffect)(() => {
|
|
19718
20022
|
if (!open)
|
|
19719
20023
|
return;
|
|
19720
20024
|
function onDocClick(e) {
|
|
@@ -19803,7 +20107,7 @@ var SystemCanvas = (() => {
|
|
|
19803
20107
|
} });
|
|
19804
20108
|
}
|
|
19805
20109
|
function MenuRow({ theme, option, onClick }) {
|
|
19806
|
-
const [hover, setHover] = (0,
|
|
20110
|
+
const [hover, setHover] = (0, import_react19.useState)(false);
|
|
19807
20111
|
const swatchSize = 18;
|
|
19808
20112
|
return (0, import_jsx_runtime24.jsxs)("div", { role: "button", onClick, onMouseEnter: () => setHover(true), onMouseLeave: () => setHover(false), style: {
|
|
19809
20113
|
display: "flex",
|
|
@@ -19839,12 +20143,12 @@ var SystemCanvas = (() => {
|
|
|
19839
20143
|
|
|
19840
20144
|
// ../react/dist/components/LaneHeaders.js
|
|
19841
20145
|
var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1);
|
|
19842
|
-
var
|
|
20146
|
+
var import_react20 = __toESM(require_react(), 1);
|
|
19843
20147
|
function LaneHeaders({ columns, rows, theme, getViewport, width, height, pinned = true }) {
|
|
19844
20148
|
const hasColumns = columns && columns.length > 0;
|
|
19845
20149
|
const hasRows = rows && rows.length > 0;
|
|
19846
|
-
const [viewport, setViewport] = (0,
|
|
19847
|
-
(0,
|
|
20150
|
+
const [viewport, setViewport] = (0, import_react20.useState)(() => getViewport());
|
|
20151
|
+
(0, import_react20.useEffect)(() => {
|
|
19848
20152
|
if (!hasColumns && !hasRows)
|
|
19849
20153
|
return;
|
|
19850
20154
|
let raf = 0;
|
|
@@ -19918,7 +20222,7 @@ var SystemCanvas = (() => {
|
|
|
19918
20222
|
|
|
19919
20223
|
// ../react/dist/components/NodeToolbar.js
|
|
19920
20224
|
var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1);
|
|
19921
|
-
var
|
|
20225
|
+
var import_react21 = __toESM(require_react(), 1);
|
|
19922
20226
|
var NODE_GAP = 10;
|
|
19923
20227
|
var FLIP_MARGIN = 8;
|
|
19924
20228
|
var PADDING = 6;
|
|
@@ -19926,9 +20230,9 @@ var SystemCanvas = (() => {
|
|
|
19926
20230
|
var SWATCH_SIZE = 16;
|
|
19927
20231
|
var BUTTON_SIZE = 28;
|
|
19928
20232
|
var DELETE_SIZE = 14;
|
|
19929
|
-
function NodeToolbar({ node, theme, onPatch, onDelete, getViewport, containerWidth, containerHeight, render: render2 }) {
|
|
19930
|
-
const [viewport, setViewport] = (0,
|
|
19931
|
-
(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)(() => {
|
|
19932
20236
|
let raf = 0;
|
|
19933
20237
|
let lastX = -Infinity;
|
|
19934
20238
|
let lastY = -Infinity;
|
|
@@ -19946,13 +20250,28 @@ var SystemCanvas = (() => {
|
|
|
19946
20250
|
raf = requestAnimationFrame(tick);
|
|
19947
20251
|
return () => cancelAnimationFrame(raf);
|
|
19948
20252
|
}, [getViewport]);
|
|
20253
|
+
const isMulti = selectedNodes != null && selectedNodes.length > 1;
|
|
19949
20254
|
const align = theme.toolbarAlign ?? "center";
|
|
19950
|
-
const
|
|
19951
|
-
|
|
19952
|
-
|
|
19953
|
-
|
|
19954
|
-
|
|
19955
|
-
|
|
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)(() => {
|
|
19956
20275
|
const el = toolbarRef.current;
|
|
19957
20276
|
if (!el)
|
|
19958
20277
|
return;
|
|
@@ -19965,7 +20284,12 @@ var SystemCanvas = (() => {
|
|
|
19965
20284
|
ro.observe(el);
|
|
19966
20285
|
return () => ro.disconnect();
|
|
19967
20286
|
}, []);
|
|
19968
|
-
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
|
+
}
|
|
19969
20293
|
let top = topAnchor.y - size.height - NODE_GAP;
|
|
19970
20294
|
if (top < FLIP_MARGIN) {
|
|
19971
20295
|
top = bottomAnchor.y + NODE_GAP;
|
|
@@ -20002,13 +20326,51 @@ var SystemCanvas = (() => {
|
|
|
20002
20326
|
userSelect: "none",
|
|
20003
20327
|
whiteSpace: "nowrap"
|
|
20004
20328
|
},
|
|
20005
|
-
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 })
|
|
20006
20330
|
});
|
|
20007
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
|
+
}
|
|
20008
20370
|
function DefaultToolbarContent({ node, theme, onPatch, onDelete }) {
|
|
20009
|
-
const groups = (0,
|
|
20371
|
+
const groups = (0, import_react21.useMemo)(() => getNodeActionsForNode(node, theme), [node, theme]);
|
|
20010
20372
|
const showDelete = theme.showToolbarDelete === true;
|
|
20011
|
-
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 })] })] });
|
|
20012
20374
|
}
|
|
20013
20375
|
function Divider2({ theme }) {
|
|
20014
20376
|
return (0, import_jsx_runtime26.jsx)("div", { style: {
|
|
@@ -20075,9 +20437,9 @@ var SystemCanvas = (() => {
|
|
|
20075
20437
|
} }) : (0, import_jsx_runtime26.jsx)("span", { style: { fontSize: 10 }, children: action.label.slice(0, 2) }) });
|
|
20076
20438
|
}
|
|
20077
20439
|
function MenuGroup({ group, actions, node, theme, onPatch }) {
|
|
20078
|
-
const [open, setOpen] = (0,
|
|
20079
|
-
const wrapRef = (0,
|
|
20080
|
-
(0,
|
|
20440
|
+
const [open, setOpen] = (0, import_react21.useState)(false);
|
|
20441
|
+
const wrapRef = (0, import_react21.useRef)(null);
|
|
20442
|
+
(0, import_react21.useEffect)(() => {
|
|
20081
20443
|
if (!open)
|
|
20082
20444
|
return;
|
|
20083
20445
|
const onDown = (e) => {
|
|
@@ -20164,18 +20526,18 @@ var SystemCanvas = (() => {
|
|
|
20164
20526
|
|
|
20165
20527
|
// ../react/dist/components/NodeContextMenuOverlay.js
|
|
20166
20528
|
var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
|
|
20167
|
-
var
|
|
20529
|
+
var import_react22 = __toESM(require_react(), 1);
|
|
20168
20530
|
var ESTIMATED_MENU_WIDTH = 200;
|
|
20169
20531
|
var MIN_MENU_WIDTH = 160;
|
|
20170
20532
|
var VIEWPORT_MARGIN = 8;
|
|
20171
20533
|
function NodeContextMenuOverlay({ state, config, theme, onClose }) {
|
|
20172
|
-
const rootRef = (0,
|
|
20173
|
-
const [hoveredId, setHoveredId] = (0,
|
|
20174
|
-
(0,
|
|
20534
|
+
const rootRef = (0, import_react22.useRef)(null);
|
|
20535
|
+
const [hoveredId, setHoveredId] = (0, import_react22.useState)(null);
|
|
20536
|
+
(0, import_react22.useEffect)(() => {
|
|
20175
20537
|
if (state)
|
|
20176
20538
|
setHoveredId(null);
|
|
20177
20539
|
}, [state]);
|
|
20178
|
-
(0,
|
|
20540
|
+
(0, import_react22.useEffect)(() => {
|
|
20179
20541
|
if (!state)
|
|
20180
20542
|
return;
|
|
20181
20543
|
function onDown(e) {
|
|
@@ -20283,8 +20645,8 @@ var SystemCanvas = (() => {
|
|
|
20283
20645
|
// ../react/dist/components/SystemCanvas.js
|
|
20284
20646
|
var CASCADE_WINDOW_MS = 1500;
|
|
20285
20647
|
var CASCADE_OFFSET = 20;
|
|
20286
|
-
var SystemCanvas = (0,
|
|
20287
|
-
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)(() => {
|
|
20288
20650
|
const defaults = {
|
|
20289
20651
|
enterThreshold: 0.66,
|
|
20290
20652
|
exitThreshold: 0.33,
|
|
@@ -20309,16 +20671,16 @@ var SystemCanvas = (() => {
|
|
|
20309
20671
|
}, [zoomNavigation]);
|
|
20310
20672
|
const effectiveMaxZoom = maxZoom ?? (zoomNavConfig.enabled ? 16 : 4);
|
|
20311
20673
|
const effectiveMinZoom = minZoomProp ?? (zoomNavConfig.enabled ? 0.01 : 0.1);
|
|
20312
|
-
(0,
|
|
20674
|
+
(0, import_react23.useEffect)(() => {
|
|
20313
20675
|
const env = globalThis.process?.env?.NODE_ENV;
|
|
20314
20676
|
if (editable && !canvases && env !== "production") {
|
|
20315
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.");
|
|
20316
20678
|
}
|
|
20317
20679
|
}, [editable, canvases]);
|
|
20318
|
-
const [parentFrames, setParentFrames] = (0,
|
|
20319
|
-
const [pendingHandoff, setPendingHandoff] = (0,
|
|
20320
|
-
const suppressNextHandoffClearRef = (0,
|
|
20321
|
-
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) => {
|
|
20322
20684
|
setParentFrames((prev) => prev.slice(0, index));
|
|
20323
20685
|
if (suppressNextHandoffClearRef.current) {
|
|
20324
20686
|
suppressNextHandoffClearRef.current = false;
|
|
@@ -20335,10 +20697,10 @@ var SystemCanvas = (() => {
|
|
|
20335
20697
|
onNavigate,
|
|
20336
20698
|
onBreadcrumbClick: handleBreadcrumbClick
|
|
20337
20699
|
});
|
|
20338
|
-
(0,
|
|
20700
|
+
(0, import_react23.useEffect)(() => {
|
|
20339
20701
|
onBreadcrumbsChange?.(breadcrumbs);
|
|
20340
20702
|
}, [breadcrumbs, onBreadcrumbsChange]);
|
|
20341
|
-
const theme = (0,
|
|
20703
|
+
const theme = (0, import_react23.useMemo)(() => {
|
|
20342
20704
|
const registry = { ...themes, ...customThemes };
|
|
20343
20705
|
const resolveByName = (name) => name && registry[name] ? registry[name] : null;
|
|
20344
20706
|
if (themeProp) {
|
|
@@ -20349,22 +20711,22 @@ var SystemCanvas = (() => {
|
|
|
20349
20711
|
}
|
|
20350
20712
|
return resolveByName(currentCanvas.theme?.base) ?? resolveByName(canvas.theme?.base) ?? darkTheme;
|
|
20351
20713
|
}, [themeProp, customThemes, currentCanvas.theme?.base, canvas.theme?.base]);
|
|
20352
|
-
const { nodes, edges, nodeMap } = (0,
|
|
20714
|
+
const { nodes, edges, nodeMap } = (0, import_react23.useMemo)(() => {
|
|
20353
20715
|
const resolved = resolveCanvas(currentCanvas, theme);
|
|
20354
20716
|
const map = buildNodeMap(resolved.nodes);
|
|
20355
20717
|
return { nodes: resolved.nodes, edges: resolved.edges, nodeMap: map };
|
|
20356
20718
|
}, [currentCanvas, theme]);
|
|
20357
|
-
const nodesRef = (0,
|
|
20719
|
+
const nodesRef = (0, import_react23.useRef)(nodes);
|
|
20358
20720
|
nodesRef.current = nodes;
|
|
20359
|
-
const viewportStateRef = (0,
|
|
20360
|
-
const viewportHandleRef = (0,
|
|
20361
|
-
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);
|
|
20362
20724
|
navigateToRefRef.current = navigateToRef;
|
|
20363
|
-
const navigateToBreadcrumbRef = (0,
|
|
20725
|
+
const navigateToBreadcrumbRef = (0, import_react23.useRef)(navigateToBreadcrumb);
|
|
20364
20726
|
navigateToBreadcrumbRef.current = navigateToBreadcrumb;
|
|
20365
|
-
const breadcrumbsRef = (0,
|
|
20727
|
+
const breadcrumbsRef = (0, import_react23.useRef)(breadcrumbs);
|
|
20366
20728
|
breadcrumbsRef.current = breadcrumbs;
|
|
20367
|
-
(0,
|
|
20729
|
+
(0, import_react23.useImperativeHandle)(forwardedRef, () => ({
|
|
20368
20730
|
zoomIntoNode: (nodeId, options) => {
|
|
20369
20731
|
return new Promise((resolve) => {
|
|
20370
20732
|
const node = nodesRef.current.find((n) => n.id === nodeId);
|
|
@@ -20396,26 +20758,64 @@ var SystemCanvas = (() => {
|
|
|
20396
20758
|
navigateToBreadcrumbRef.current(0);
|
|
20397
20759
|
}
|
|
20398
20760
|
}), [forwardedRef]);
|
|
20399
|
-
const [
|
|
20400
|
-
const [
|
|
20401
|
-
const [
|
|
20402
|
-
const
|
|
20403
|
-
(0,
|
|
20404
|
-
|
|
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();
|
|
20405
20794
|
setEditingId(null);
|
|
20406
20795
|
setSelectedEdgeId(null);
|
|
20407
20796
|
setEditingEdgeId(null);
|
|
20408
20797
|
}, [currentCanvasRef]);
|
|
20409
|
-
const onSelectionChangeRef = (0,
|
|
20410
|
-
(0,
|
|
20798
|
+
const onSelectionChangeRef = (0, import_react23.useRef)(onSelectionChange);
|
|
20799
|
+
(0, import_react23.useEffect)(() => {
|
|
20411
20800
|
onSelectionChangeRef.current = onSelectionChange;
|
|
20412
20801
|
}, [onSelectionChange]);
|
|
20413
|
-
const lastEmittedSelectionRef = (0,
|
|
20414
|
-
(0,
|
|
20802
|
+
const lastEmittedSelectionRef = (0, import_react23.useRef)({ kind: null, id: null, multiIds: null, canvasRef: void 0 });
|
|
20803
|
+
(0, import_react23.useEffect)(() => {
|
|
20415
20804
|
const cb = onSelectionChangeRef.current;
|
|
20416
20805
|
let next = null;
|
|
20417
|
-
if (
|
|
20418
|
-
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);
|
|
20419
20819
|
if (node)
|
|
20420
20820
|
next = { kind: "node", node, canvasRef: currentCanvasRef };
|
|
20421
20821
|
}
|
|
@@ -20426,21 +20826,24 @@ var SystemCanvas = (() => {
|
|
|
20426
20826
|
}
|
|
20427
20827
|
const last = lastEmittedSelectionRef.current;
|
|
20428
20828
|
const nextKind = next?.kind ?? null;
|
|
20429
|
-
const nextId = next ? next.kind === "node" ? next.node.id : next.edge.id : null;
|
|
20430
20829
|
const nextRef = next?.canvasRef;
|
|
20431
|
-
if (
|
|
20432
|
-
|
|
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 };
|
|
20433
20842
|
}
|
|
20434
|
-
lastEmittedSelectionRef.current = {
|
|
20435
|
-
kind: nextKind,
|
|
20436
|
-
id: nextId,
|
|
20437
|
-
canvasRef: nextRef
|
|
20438
|
-
};
|
|
20439
20843
|
cb?.(next);
|
|
20440
|
-
}, [
|
|
20441
|
-
const
|
|
20442
|
-
|
|
20443
|
-
(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)(() => {
|
|
20444
20847
|
const el = containerRef.current;
|
|
20445
20848
|
if (!el)
|
|
20446
20849
|
return;
|
|
@@ -20455,8 +20858,8 @@ var SystemCanvas = (() => {
|
|
|
20455
20858
|
}, []);
|
|
20456
20859
|
const hasLanes = currentCanvas.columns && currentCanvas.columns.length > 0 || currentCanvas.rows && currentCanvas.rows.length > 0;
|
|
20457
20860
|
const showLaneHeaders = hasLanes && laneHeaders !== "none";
|
|
20458
|
-
const getViewportState = (0,
|
|
20459
|
-
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) => {
|
|
20460
20863
|
if (!snapToLanes)
|
|
20461
20864
|
return patch;
|
|
20462
20865
|
const cols = currentCanvas.columns;
|
|
@@ -20481,10 +20884,10 @@ var SystemCanvas = (() => {
|
|
|
20481
20884
|
}
|
|
20482
20885
|
return final;
|
|
20483
20886
|
}, [snapToLanes, currentCanvas.columns, currentCanvas.rows]);
|
|
20484
|
-
const commitResize = (0,
|
|
20887
|
+
const commitResize = (0, import_react23.useCallback)((id2, patch) => {
|
|
20485
20888
|
onNodeUpdate?.(id2, applyLaneSnap(id2, patch), currentCanvasRef);
|
|
20486
20889
|
}, [onNodeUpdate, currentCanvasRef, applyLaneSnap]);
|
|
20487
|
-
const commitDragBatch = (0,
|
|
20890
|
+
const commitDragBatch = (0, import_react23.useCallback)((updates) => {
|
|
20488
20891
|
const final = updates.map((u) => ({
|
|
20489
20892
|
id: u.id,
|
|
20490
20893
|
patch: applyLaneSnap(u.id, u.patch)
|
|
@@ -20499,8 +20902,7 @@ var SystemCanvas = (() => {
|
|
|
20499
20902
|
onNodeUpdate(id2, patch, currentCanvasRef);
|
|
20500
20903
|
}
|
|
20501
20904
|
}, [onNodeUpdate, onNodesUpdate, currentCanvasRef, applyLaneSnap]);
|
|
20502
|
-
const
|
|
20503
|
-
const handleNodeDrop = (0, import_react21.useCallback)((sources, target) => {
|
|
20905
|
+
const handleNodeDrop = (0, import_react23.useCallback)((sources, target) => {
|
|
20504
20906
|
onNodeDrop?.(sources, target, { canvasRef: currentCanvasRef });
|
|
20505
20907
|
}, [onNodeDrop, currentCanvasRef]);
|
|
20506
20908
|
const { dragOverrides, dropTargetId, onPointerDown: onNodePointerDown } = useNodeDrag({
|
|
@@ -20509,30 +20911,32 @@ var SystemCanvas = (() => {
|
|
|
20509
20911
|
onCommit: commitDragBatch,
|
|
20510
20912
|
svgRef: svgProxyRef,
|
|
20511
20913
|
canDropNodeOn,
|
|
20512
|
-
onNodeDrop: handleNodeDrop
|
|
20914
|
+
onNodeDrop: handleNodeDrop,
|
|
20915
|
+
selectedIdsRef
|
|
20513
20916
|
});
|
|
20514
20917
|
const { resizeOverrides, onHandlePointerDown: onResizeHandlePointerDown } = useNodeResize({
|
|
20515
20918
|
viewport: viewportStateRef,
|
|
20516
20919
|
onCommit: commitResize
|
|
20517
20920
|
});
|
|
20518
|
-
const
|
|
20519
|
-
|
|
20921
|
+
const singleSelectedId = selectedIds.size === 1 ? Array.from(selectedIds)[0] : null;
|
|
20922
|
+
const selectedResolvedNode = (0, import_react23.useMemo)(() => {
|
|
20923
|
+
if (!singleSelectedId)
|
|
20520
20924
|
return null;
|
|
20521
|
-
const base = nodeMap.get(
|
|
20925
|
+
const base = nodeMap.get(singleSelectedId);
|
|
20522
20926
|
if (!base)
|
|
20523
20927
|
return null;
|
|
20524
|
-
const resize = resizeOverrides.get(
|
|
20928
|
+
const resize = resizeOverrides.get(singleSelectedId);
|
|
20525
20929
|
if (resize) {
|
|
20526
20930
|
return { ...base, x: resize.x, y: resize.y, width: resize.width, height: resize.height };
|
|
20527
20931
|
}
|
|
20528
|
-
const drag = dragOverrides.get(
|
|
20932
|
+
const drag = dragOverrides.get(singleSelectedId);
|
|
20529
20933
|
if (drag) {
|
|
20530
20934
|
return { ...base, x: drag.x, y: drag.y };
|
|
20531
20935
|
}
|
|
20532
20936
|
return base;
|
|
20533
|
-
}, [
|
|
20937
|
+
}, [singleSelectedId, nodeMap, dragOverrides, resizeOverrides]);
|
|
20534
20938
|
svgProxyRef.current = viewportHandleRef.current?.getSvgElement() ?? null;
|
|
20535
|
-
const handleEdgeCreated = (0,
|
|
20939
|
+
const handleEdgeCreated = (0, import_react23.useCallback)((edge) => {
|
|
20536
20940
|
onEdgeAdd?.(edge, currentCanvasRef);
|
|
20537
20941
|
}, [onEdgeAdd, currentCanvasRef]);
|
|
20538
20942
|
const { pending: pendingEdge, onHandlePointerDown: onConnectionHandlePointerDown } = useEdgeCreate({
|
|
@@ -20541,7 +20945,7 @@ var SystemCanvas = (() => {
|
|
|
20541
20945
|
nodesRef,
|
|
20542
20946
|
onCreate: handleEdgeCreated
|
|
20543
20947
|
});
|
|
20544
|
-
const handleNavigableNodeClick = (0,
|
|
20948
|
+
const handleNavigableNodeClick = (0, import_react23.useCallback)((node) => {
|
|
20545
20949
|
const frame2 = {
|
|
20546
20950
|
parentCanvasRef: currentCanvasRef,
|
|
20547
20951
|
parentNodeRect: {
|
|
@@ -20568,7 +20972,7 @@ var SystemCanvas = (() => {
|
|
|
20568
20972
|
navigateToRef(node);
|
|
20569
20973
|
}
|
|
20570
20974
|
}, [navigateToRef, currentCanvasRef, zoomNavConfig.enabled]);
|
|
20571
|
-
const handleZoomEnter = (0,
|
|
20975
|
+
const handleZoomEnter = (0, import_react23.useCallback)((node, targetTransform) => {
|
|
20572
20976
|
const frame2 = {
|
|
20573
20977
|
parentCanvasRef: currentCanvasRef,
|
|
20574
20978
|
parentNodeRect: {
|
|
@@ -20582,7 +20986,7 @@ var SystemCanvas = (() => {
|
|
|
20582
20986
|
setPendingHandoff(targetTransform);
|
|
20583
20987
|
navigateToRef(node);
|
|
20584
20988
|
}, [currentCanvasRef, navigateToRef]);
|
|
20585
|
-
const handleZoomExit = (0,
|
|
20989
|
+
const handleZoomExit = (0, import_react23.useCallback)((targetTransform) => {
|
|
20586
20990
|
setPendingHandoff(targetTransform);
|
|
20587
20991
|
suppressNextHandoffClearRef.current = true;
|
|
20588
20992
|
navigateToBreadcrumb(breadcrumbs.length - 2);
|
|
@@ -20609,26 +21013,26 @@ var SystemCanvas = (() => {
|
|
|
20609
21013
|
onEnter: handleZoomEnter,
|
|
20610
21014
|
onExit: handleZoomExit
|
|
20611
21015
|
});
|
|
20612
|
-
const handleViewportChange = (0,
|
|
21016
|
+
const handleViewportChange = (0, import_react23.useCallback)((vp) => {
|
|
20613
21017
|
viewportStateRef.current = vp;
|
|
20614
21018
|
handleZoomNavViewportChange(vp);
|
|
20615
21019
|
onViewportChange?.(vp);
|
|
20616
21020
|
}, [handleZoomNavViewportChange, onViewportChange]);
|
|
20617
|
-
const handleHandoffApplied = (0,
|
|
21021
|
+
const handleHandoffApplied = (0, import_react23.useCallback)(() => {
|
|
20618
21022
|
setPendingHandoff(null);
|
|
20619
21023
|
clearZoomNavCommitting();
|
|
20620
21024
|
}, [clearZoomNavCommitting]);
|
|
20621
|
-
const handleBeginEdit = (0,
|
|
21025
|
+
const handleBeginEdit = (0, import_react23.useCallback)((node) => {
|
|
20622
21026
|
setEditingId(node.id);
|
|
20623
21027
|
}, []);
|
|
20624
|
-
const handleBeginEditEdge = (0,
|
|
21028
|
+
const handleBeginEditEdge = (0, import_react23.useCallback)((edge) => {
|
|
20625
21029
|
setEditingEdgeId(edge.id);
|
|
20626
21030
|
}, []);
|
|
20627
|
-
const [contextMenuState, setContextMenuState] = (0,
|
|
20628
|
-
(0,
|
|
21031
|
+
const [contextMenuState, setContextMenuState] = (0, import_react23.useState)(null);
|
|
21032
|
+
(0, import_react23.useEffect)(() => {
|
|
20629
21033
|
setContextMenuState(null);
|
|
20630
21034
|
}, [currentCanvasRef]);
|
|
20631
|
-
const handleContextMenu = (0,
|
|
21035
|
+
const handleContextMenu = (0, import_react23.useCallback)((event) => {
|
|
20632
21036
|
onContextMenu?.(event);
|
|
20633
21037
|
if (!nodeContextMenu)
|
|
20634
21038
|
return;
|
|
@@ -20660,32 +21064,38 @@ var SystemCanvas = (() => {
|
|
|
20660
21064
|
onNavigableNodeClick: handleNavigableNodeClick,
|
|
20661
21065
|
viewport: viewportStateRef,
|
|
20662
21066
|
editable,
|
|
20663
|
-
onSelect:
|
|
21067
|
+
onSelect: (id2) => {
|
|
21068
|
+
if (id2)
|
|
21069
|
+
selectNode(id2);
|
|
21070
|
+
else
|
|
21071
|
+
clearSelection();
|
|
21072
|
+
},
|
|
21073
|
+
onToggleSelect: toggleNode,
|
|
20664
21074
|
onBeginEdit: handleBeginEdit,
|
|
20665
21075
|
onSelectEdge: setSelectedEdgeId,
|
|
20666
21076
|
onBeginEditEdge: handleBeginEditEdge
|
|
20667
21077
|
});
|
|
20668
|
-
const handleEditorCommit = (0,
|
|
21078
|
+
const handleEditorCommit = (0, import_react23.useCallback)((patch) => {
|
|
20669
21079
|
if (editingId) {
|
|
20670
21080
|
onNodeUpdate?.(editingId, patch, currentCanvasRef);
|
|
20671
21081
|
}
|
|
20672
21082
|
setEditingId(null);
|
|
20673
21083
|
}, [editingId, onNodeUpdate, currentCanvasRef]);
|
|
20674
|
-
const handleEditorCancel = (0,
|
|
21084
|
+
const handleEditorCancel = (0, import_react23.useCallback)(() => {
|
|
20675
21085
|
setEditingId(null);
|
|
20676
21086
|
}, []);
|
|
20677
|
-
const handleEdgeEditorCommit = (0,
|
|
21087
|
+
const handleEdgeEditorCommit = (0, import_react23.useCallback)((patch) => {
|
|
20678
21088
|
if (editingEdgeId) {
|
|
20679
21089
|
onEdgeUpdate?.(editingEdgeId, patch, currentCanvasRef);
|
|
20680
21090
|
}
|
|
20681
21091
|
setEditingEdgeId(null);
|
|
20682
21092
|
}, [editingEdgeId, onEdgeUpdate, currentCanvasRef]);
|
|
20683
|
-
const handleEdgeEditorCancel = (0,
|
|
21093
|
+
const handleEdgeEditorCancel = (0, import_react23.useCallback)(() => {
|
|
20684
21094
|
setEditingEdgeId(null);
|
|
20685
21095
|
}, []);
|
|
20686
|
-
const lastAddRef = (0,
|
|
20687
|
-
const menuOptions = (0,
|
|
20688
|
-
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) => {
|
|
20689
21099
|
let x, y;
|
|
20690
21100
|
if (position) {
|
|
20691
21101
|
x = position.x;
|
|
@@ -20717,23 +21127,33 @@ var SystemCanvas = (() => {
|
|
|
20717
21127
|
const node = createNodeFromOption(option, Math.round(x), Math.round(y), void 0, theme);
|
|
20718
21128
|
onNodeAdd?.(node, currentCanvasRef);
|
|
20719
21129
|
}, [onNodeAdd, currentCanvasRef, theme]);
|
|
20720
|
-
const handleKeyDown = (0,
|
|
21130
|
+
const handleKeyDown = (0, import_react23.useCallback)((e) => {
|
|
20721
21131
|
if (!editable)
|
|
20722
21132
|
return;
|
|
20723
21133
|
if (e.key === "Escape") {
|
|
20724
21134
|
setEditingId(null);
|
|
20725
|
-
|
|
21135
|
+
clearSelection();
|
|
20726
21136
|
setEditingEdgeId(null);
|
|
20727
21137
|
setSelectedEdgeId(null);
|
|
20728
21138
|
return;
|
|
20729
21139
|
}
|
|
20730
21140
|
if (editingId || editingEdgeId)
|
|
20731
21141
|
return;
|
|
21142
|
+
if ((e.metaKey || e.ctrlKey) && e.key === "a") {
|
|
21143
|
+
e.preventDefault();
|
|
21144
|
+
selectAll();
|
|
21145
|
+
return;
|
|
21146
|
+
}
|
|
20732
21147
|
if (e.key === "Delete" || e.key === "Backspace") {
|
|
20733
|
-
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];
|
|
20734
21154
|
e.preventDefault();
|
|
20735
|
-
onNodeDelete?.(
|
|
20736
|
-
|
|
21155
|
+
onNodeDelete?.(id2, currentCanvasRef);
|
|
21156
|
+
clearSelection();
|
|
20737
21157
|
} else if (selectedEdgeId) {
|
|
20738
21158
|
e.preventDefault();
|
|
20739
21159
|
onEdgeDelete?.(selectedEdgeId, currentCanvasRef);
|
|
@@ -20744,11 +21164,14 @@ var SystemCanvas = (() => {
|
|
|
20744
21164
|
editable,
|
|
20745
21165
|
editingId,
|
|
20746
21166
|
editingEdgeId,
|
|
20747
|
-
|
|
21167
|
+
selectedIds,
|
|
20748
21168
|
selectedEdgeId,
|
|
20749
21169
|
onNodeDelete,
|
|
21170
|
+
onNodesDelete,
|
|
20750
21171
|
onEdgeDelete,
|
|
20751
|
-
currentCanvasRef
|
|
21172
|
+
currentCanvasRef,
|
|
21173
|
+
clearSelection,
|
|
21174
|
+
selectAll
|
|
20752
21175
|
]);
|
|
20753
21176
|
const renderProps = { options: menuOptions, addNode: addNode2, theme };
|
|
20754
21177
|
return (0, import_jsx_runtime28.jsxs)("div", { ref: containerRef, className: `system-canvas ${className ?? ""}`, tabIndex: editable ? 0 : -1, onKeyDown: handleKeyDown, style: {
|
|
@@ -20770,20 +21193,28 @@ var SystemCanvas = (() => {
|
|
|
20770
21193
|
fontFamily: theme.node.fontFamily,
|
|
20771
21194
|
fontSize: 12,
|
|
20772
21195
|
backdropFilter: "blur(8px)"
|
|
20773
|
-
}, 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) => {
|
|
20774
21197
|
onNodeUpdate?.(selectedResolvedNode.id, update, currentCanvasRef);
|
|
20775
21198
|
}, onDelete: () => {
|
|
20776
21199
|
onNodeDelete?.(selectedResolvedNode.id, currentCanvasRef);
|
|
20777
|
-
|
|
20778
|
-
}, 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) })] });
|
|
20779
21216
|
});
|
|
20780
21217
|
|
|
20781
|
-
// ../react/dist/hooks/useMultiSelect.js
|
|
20782
|
-
var import_react22 = __toESM(require_react(), 1);
|
|
20783
|
-
|
|
20784
|
-
// ../react/dist/hooks/useMultiSelectClipboard.js
|
|
20785
|
-
var import_react23 = __toESM(require_react(), 1);
|
|
20786
|
-
|
|
20787
21218
|
// src/index.tsx
|
|
20788
21219
|
function resolveThemeOption(theme) {
|
|
20789
21220
|
if (typeof theme === "string") {
|