system-canvas-standalone 0.2.2 → 0.2.4
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 +974 -217
- 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_react25 = __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_react24 = __toESM(require_react(), 1);
|
|
12768
12768
|
|
|
12769
12769
|
// ../core/dist/themes/dark.js
|
|
12770
12770
|
var darkTheme = {
|
|
@@ -15150,8 +15150,601 @@ 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, onBeginBatch, onEndBatch } = 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
|
+
const onBeginBatchRef = (0, import_react7.useRef)(onBeginBatch);
|
|
15362
|
+
onBeginBatchRef.current = onBeginBatch;
|
|
15363
|
+
const onEndBatchRef = (0, import_react7.useRef)(onEndBatch);
|
|
15364
|
+
onEndBatchRef.current = onEndBatch;
|
|
15365
|
+
(0, import_react7.useEffect)(() => {
|
|
15366
|
+
const handler = (e) => {
|
|
15367
|
+
const active = document.activeElement;
|
|
15368
|
+
if (active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement || active instanceof HTMLElement && active.isContentEditable) {
|
|
15369
|
+
return;
|
|
15370
|
+
}
|
|
15371
|
+
const isMod = e.metaKey || e.ctrlKey;
|
|
15372
|
+
if (isMod && e.key === "c") {
|
|
15373
|
+
const selectedIds = selectedIdsRef.current;
|
|
15374
|
+
if (!selectedIds || selectedIds.size === 0)
|
|
15375
|
+
return;
|
|
15376
|
+
const nodes = nodesRef.current ?? [];
|
|
15377
|
+
const edges = edgesRef.current ?? [];
|
|
15378
|
+
const vp = viewport.current ?? { x: 0, y: 0, zoom: 1 };
|
|
15379
|
+
const copiedNodes = nodes.filter((n) => selectedIds.has(n.id));
|
|
15380
|
+
if (copiedNodes.length === 0)
|
|
15381
|
+
return;
|
|
15382
|
+
const copiedEdges = edges.filter((edge) => selectedIds.has(edge.fromNode) && selectedIds.has(edge.toNode));
|
|
15383
|
+
clipboardSnapshot = {
|
|
15384
|
+
nodes: copiedNodes,
|
|
15385
|
+
edges: copiedEdges,
|
|
15386
|
+
viewportAtCopy: { ...vp }
|
|
15387
|
+
};
|
|
15388
|
+
e.preventDefault();
|
|
15389
|
+
return;
|
|
15390
|
+
}
|
|
15391
|
+
if (isMod && e.key === "v") {
|
|
15392
|
+
if (!clipboardSnapshot)
|
|
15393
|
+
return;
|
|
15394
|
+
const { nodes: srcNodes, edges: srcEdges } = clipboardSnapshot;
|
|
15395
|
+
if (srcNodes.length === 0)
|
|
15396
|
+
return;
|
|
15397
|
+
const oldToNew = /* @__PURE__ */ new Map();
|
|
15398
|
+
for (const n of srcNodes) {
|
|
15399
|
+
oldToNew.set(n.id, generateNodeId());
|
|
15400
|
+
}
|
|
15401
|
+
let minX = Infinity;
|
|
15402
|
+
let minY = Infinity;
|
|
15403
|
+
let maxX = -Infinity;
|
|
15404
|
+
let maxY = -Infinity;
|
|
15405
|
+
for (const n of srcNodes) {
|
|
15406
|
+
minX = Math.min(minX, n.x);
|
|
15407
|
+
minY = Math.min(minY, n.y);
|
|
15408
|
+
maxX = Math.max(maxX, n.x + (n.width ?? 0));
|
|
15409
|
+
maxY = Math.max(maxY, n.y + (n.height ?? 0));
|
|
15410
|
+
}
|
|
15411
|
+
const clusterCx = (minX + maxX) / 2;
|
|
15412
|
+
const clusterCy = (minY + maxY) / 2;
|
|
15413
|
+
const vp = viewport.current ?? { x: 0, y: 0, zoom: 1 };
|
|
15414
|
+
const cursorScreen = getCursorScreenPosRef.current?.();
|
|
15415
|
+
let targetCanvas;
|
|
15416
|
+
if (cursorScreen) {
|
|
15417
|
+
targetCanvas = screenToCanvas(cursorScreen.x, cursorScreen.y, vp);
|
|
15418
|
+
} else {
|
|
15419
|
+
targetCanvas = screenToCanvas(0, 0, vp);
|
|
15420
|
+
targetCanvas = { x: targetCanvas.x + 40, y: targetCanvas.y + 40 };
|
|
15421
|
+
}
|
|
15422
|
+
const dx = targetCanvas.x - clusterCx;
|
|
15423
|
+
const dy = targetCanvas.y - clusterCy;
|
|
15424
|
+
const clonedNodes = srcNodes.map((n) => ({
|
|
15425
|
+
...structuredClone(n),
|
|
15426
|
+
id: oldToNew.get(n.id),
|
|
15427
|
+
x: n.x + dx,
|
|
15428
|
+
y: n.y + dy
|
|
15429
|
+
}));
|
|
15430
|
+
const clonedEdges = srcEdges.filter((edge) => oldToNew.has(edge.fromNode) && oldToNew.has(edge.toNode)).map((edge) => ({
|
|
15431
|
+
...structuredClone(edge),
|
|
15432
|
+
id: generateEdgeId(),
|
|
15433
|
+
fromNode: oldToNew.get(edge.fromNode),
|
|
15434
|
+
toNode: oldToNew.get(edge.toNode)
|
|
15435
|
+
}));
|
|
15436
|
+
const ref = canvasRefRef.current;
|
|
15437
|
+
onBeginBatchRef.current?.();
|
|
15438
|
+
for (const node of clonedNodes) {
|
|
15439
|
+
onNodeAddRef.current(node, ref);
|
|
15440
|
+
}
|
|
15441
|
+
for (const edge of clonedEdges) {
|
|
15442
|
+
onEdgeAddRef.current(edge, ref);
|
|
15443
|
+
}
|
|
15444
|
+
onEndBatchRef.current?.();
|
|
15445
|
+
e.preventDefault();
|
|
15446
|
+
return;
|
|
15447
|
+
}
|
|
15448
|
+
};
|
|
15449
|
+
document.addEventListener("keydown", handler);
|
|
15450
|
+
return () => {
|
|
15451
|
+
document.removeEventListener("keydown", handler);
|
|
15452
|
+
};
|
|
15453
|
+
}, [selectedIdsRef, nodesRef, edgesRef, viewport]);
|
|
15454
|
+
}
|
|
15455
|
+
|
|
15456
|
+
// ../react/dist/hooks/useCommandHistory.js
|
|
15457
|
+
var import_react8 = __toESM(require_react(), 1);
|
|
15458
|
+
function getCanvasRef(cmd) {
|
|
15459
|
+
if (cmd.type === "batch") {
|
|
15460
|
+
return cmd.commands.length > 0 ? getCanvasRef(cmd.commands[0]) : void 0;
|
|
15461
|
+
}
|
|
15462
|
+
return cmd.canvasRef;
|
|
15463
|
+
}
|
|
15464
|
+
function useCommandHistory(options) {
|
|
15465
|
+
const { nodesRef, edgesRef, onNodeAdd, onNodeUpdate, onNodesUpdate, onNodeDelete, onNodesDelete, onEdgeAdd, onEdgeUpdate, onEdgeDelete, maxDepth = 50, enabled = true, onUndo, onRedo } = options;
|
|
15466
|
+
const onNodeAddRef = (0, import_react8.useRef)(onNodeAdd);
|
|
15467
|
+
onNodeAddRef.current = onNodeAdd;
|
|
15468
|
+
const onNodeUpdateRef = (0, import_react8.useRef)(onNodeUpdate);
|
|
15469
|
+
onNodeUpdateRef.current = onNodeUpdate;
|
|
15470
|
+
const onNodesUpdateRef = (0, import_react8.useRef)(onNodesUpdate);
|
|
15471
|
+
onNodesUpdateRef.current = onNodesUpdate;
|
|
15472
|
+
const onNodeDeleteRef = (0, import_react8.useRef)(onNodeDelete);
|
|
15473
|
+
onNodeDeleteRef.current = onNodeDelete;
|
|
15474
|
+
const onNodesDeleteRef = (0, import_react8.useRef)(onNodesDelete);
|
|
15475
|
+
onNodesDeleteRef.current = onNodesDelete;
|
|
15476
|
+
const onEdgeAddRef = (0, import_react8.useRef)(onEdgeAdd);
|
|
15477
|
+
onEdgeAddRef.current = onEdgeAdd;
|
|
15478
|
+
const onEdgeUpdateRef = (0, import_react8.useRef)(onEdgeUpdate);
|
|
15479
|
+
onEdgeUpdateRef.current = onEdgeUpdate;
|
|
15480
|
+
const onEdgeDeleteRef = (0, import_react8.useRef)(onEdgeDelete);
|
|
15481
|
+
onEdgeDeleteRef.current = onEdgeDelete;
|
|
15482
|
+
const undoStack = (0, import_react8.useRef)([]);
|
|
15483
|
+
const redoStack = (0, import_react8.useRef)([]);
|
|
15484
|
+
const isUndoingRef = (0, import_react8.useRef)(false);
|
|
15485
|
+
const pendingBatchRef = (0, import_react8.useRef)(null);
|
|
15486
|
+
const [canUndo, setCanUndo] = (0, import_react8.useState)(false);
|
|
15487
|
+
const [canRedo, setCanRedo] = (0, import_react8.useState)(false);
|
|
15488
|
+
function syncBooleans() {
|
|
15489
|
+
setCanUndo(undoStack.current.length > 0);
|
|
15490
|
+
setCanRedo(redoStack.current.length > 0);
|
|
15491
|
+
}
|
|
15492
|
+
function pushCommand(cmd) {
|
|
15493
|
+
if (pendingBatchRef.current) {
|
|
15494
|
+
pendingBatchRef.current.push(cmd);
|
|
15495
|
+
return;
|
|
15496
|
+
}
|
|
15497
|
+
undoStack.current.push(cmd);
|
|
15498
|
+
if (undoStack.current.length > maxDepth)
|
|
15499
|
+
undoStack.current.shift();
|
|
15500
|
+
redoStack.current = [];
|
|
15501
|
+
syncBooleans();
|
|
15502
|
+
}
|
|
15503
|
+
function applyInverse(cmd) {
|
|
15504
|
+
switch (cmd.type) {
|
|
15505
|
+
case "node:add":
|
|
15506
|
+
onNodeDeleteRef.current?.(cmd.node.id, cmd.canvasRef);
|
|
15507
|
+
break;
|
|
15508
|
+
case "node:delete":
|
|
15509
|
+
onNodeAddRef.current?.(cmd.node, cmd.canvasRef);
|
|
15510
|
+
break;
|
|
15511
|
+
case "node:update":
|
|
15512
|
+
onNodeUpdateRef.current?.(cmd.id, cmd.prev, cmd.canvasRef);
|
|
15513
|
+
break;
|
|
15514
|
+
case "nodes:update":
|
|
15515
|
+
onNodesUpdateRef.current?.(cmd.updates.map((u) => ({ id: u.id, patch: u.prev })), cmd.canvasRef);
|
|
15516
|
+
break;
|
|
15517
|
+
case "nodes:delete":
|
|
15518
|
+
for (const node of cmd.nodes) {
|
|
15519
|
+
onNodeAddRef.current?.(node, cmd.canvasRef);
|
|
15520
|
+
}
|
|
15521
|
+
break;
|
|
15522
|
+
case "edge:add":
|
|
15523
|
+
onEdgeDeleteRef.current?.(cmd.edge.id, cmd.canvasRef);
|
|
15524
|
+
break;
|
|
15525
|
+
case "edge:delete":
|
|
15526
|
+
onEdgeAddRef.current?.(cmd.edge, cmd.canvasRef);
|
|
15527
|
+
break;
|
|
15528
|
+
case "edge:update":
|
|
15529
|
+
onEdgeUpdateRef.current?.(cmd.id, cmd.prev, cmd.canvasRef);
|
|
15530
|
+
break;
|
|
15531
|
+
case "batch":
|
|
15532
|
+
for (let i = cmd.commands.length - 1; i >= 0; i--) {
|
|
15533
|
+
applyInverse(cmd.commands[i]);
|
|
15534
|
+
}
|
|
15535
|
+
break;
|
|
15536
|
+
}
|
|
15537
|
+
}
|
|
15538
|
+
function applyForward(cmd) {
|
|
15539
|
+
switch (cmd.type) {
|
|
15540
|
+
case "node:add":
|
|
15541
|
+
onNodeAddRef.current?.(cmd.node, cmd.canvasRef);
|
|
15542
|
+
break;
|
|
15543
|
+
case "node:delete":
|
|
15544
|
+
onNodeDeleteRef.current?.(cmd.node.id, cmd.canvasRef);
|
|
15545
|
+
break;
|
|
15546
|
+
case "node:update":
|
|
15547
|
+
onNodeUpdateRef.current?.(cmd.id, cmd.patch, cmd.canvasRef);
|
|
15548
|
+
break;
|
|
15549
|
+
case "nodes:update":
|
|
15550
|
+
onNodesUpdateRef.current?.(cmd.updates.map((u) => ({ id: u.id, patch: u.patch })), cmd.canvasRef);
|
|
15551
|
+
break;
|
|
15552
|
+
case "nodes:delete":
|
|
15553
|
+
onNodesDeleteRef.current?.(cmd.nodes.map((n) => n.id), cmd.canvasRef);
|
|
15554
|
+
break;
|
|
15555
|
+
case "edge:add":
|
|
15556
|
+
onEdgeAddRef.current?.(cmd.edge, cmd.canvasRef);
|
|
15557
|
+
break;
|
|
15558
|
+
case "edge:delete":
|
|
15559
|
+
onEdgeDeleteRef.current?.(cmd.edge.id, cmd.canvasRef);
|
|
15560
|
+
break;
|
|
15561
|
+
case "edge:update":
|
|
15562
|
+
onEdgeUpdateRef.current?.(cmd.id, cmd.patch, cmd.canvasRef);
|
|
15563
|
+
break;
|
|
15564
|
+
case "batch":
|
|
15565
|
+
for (const c of cmd.commands) {
|
|
15566
|
+
applyForward(c);
|
|
15567
|
+
}
|
|
15568
|
+
break;
|
|
15569
|
+
}
|
|
15570
|
+
}
|
|
15571
|
+
const undo = (0, import_react8.useCallback)(() => {
|
|
15572
|
+
if (!enabled)
|
|
15573
|
+
return;
|
|
15574
|
+
const cmd = undoStack.current.pop();
|
|
15575
|
+
if (!cmd)
|
|
15576
|
+
return;
|
|
15577
|
+
isUndoingRef.current = true;
|
|
15578
|
+
applyInverse(cmd);
|
|
15579
|
+
isUndoingRef.current = false;
|
|
15580
|
+
redoStack.current.push(cmd);
|
|
15581
|
+
syncBooleans();
|
|
15582
|
+
onUndo?.(getCanvasRef(cmd));
|
|
15583
|
+
}, [enabled, onUndo]);
|
|
15584
|
+
const redo = (0, import_react8.useCallback)(() => {
|
|
15585
|
+
if (!enabled)
|
|
15586
|
+
return;
|
|
15587
|
+
const cmd = redoStack.current.pop();
|
|
15588
|
+
if (!cmd)
|
|
15589
|
+
return;
|
|
15590
|
+
isUndoingRef.current = true;
|
|
15591
|
+
applyForward(cmd);
|
|
15592
|
+
isUndoingRef.current = false;
|
|
15593
|
+
undoStack.current.push(cmd);
|
|
15594
|
+
if (undoStack.current.length > maxDepth)
|
|
15595
|
+
undoStack.current.shift();
|
|
15596
|
+
syncBooleans();
|
|
15597
|
+
onRedo?.(getCanvasRef(cmd));
|
|
15598
|
+
}, [enabled, onRedo, maxDepth]);
|
|
15599
|
+
const beginBatch = (0, import_react8.useCallback)(() => {
|
|
15600
|
+
if (!enabled)
|
|
15601
|
+
return;
|
|
15602
|
+
pendingBatchRef.current = [];
|
|
15603
|
+
}, [enabled]);
|
|
15604
|
+
const endBatch = (0, import_react8.useCallback)(() => {
|
|
15605
|
+
if (!enabled)
|
|
15606
|
+
return;
|
|
15607
|
+
const cmds = pendingBatchRef.current;
|
|
15608
|
+
pendingBatchRef.current = null;
|
|
15609
|
+
if (!cmds || cmds.length === 0)
|
|
15610
|
+
return;
|
|
15611
|
+
if (cmds.length === 1) {
|
|
15612
|
+
pushCommand(cmds[0]);
|
|
15613
|
+
return;
|
|
15614
|
+
}
|
|
15615
|
+
undoStack.current.push({ type: "batch", commands: cmds });
|
|
15616
|
+
if (undoStack.current.length > maxDepth)
|
|
15617
|
+
undoStack.current.shift();
|
|
15618
|
+
redoStack.current = [];
|
|
15619
|
+
syncBooleans();
|
|
15620
|
+
}, [enabled, maxDepth]);
|
|
15621
|
+
const wrappedOnNodeAdd = (0, import_react8.useCallback)(
|
|
15622
|
+
(node, canvasRef) => {
|
|
15623
|
+
if (enabled && !isUndoingRef.current) {
|
|
15624
|
+
pushCommand({ type: "node:add", node, canvasRef });
|
|
15625
|
+
}
|
|
15626
|
+
onNodeAddRef.current?.(node, canvasRef);
|
|
15627
|
+
},
|
|
15628
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
15629
|
+
[enabled]
|
|
15630
|
+
);
|
|
15631
|
+
const wrappedOnNodeUpdate = (0, import_react8.useCallback)(
|
|
15632
|
+
(id2, patch, canvasRef) => {
|
|
15633
|
+
if (enabled && !isUndoingRef.current) {
|
|
15634
|
+
const node = nodesRef.current?.find((n) => n.id === id2);
|
|
15635
|
+
if (node) {
|
|
15636
|
+
const prev = Object.fromEntries(Object.keys(patch).map((k) => [k, node[k]]));
|
|
15637
|
+
pushCommand({ type: "node:update", id: id2, prev, patch, canvasRef });
|
|
15638
|
+
}
|
|
15639
|
+
}
|
|
15640
|
+
onNodeUpdateRef.current?.(id2, patch, canvasRef);
|
|
15641
|
+
},
|
|
15642
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
15643
|
+
[enabled, nodesRef]
|
|
15644
|
+
);
|
|
15645
|
+
const wrappedOnNodesUpdate = (0, import_react8.useCallback)(
|
|
15646
|
+
(updates, canvasRef) => {
|
|
15647
|
+
if (enabled && !isUndoingRef.current) {
|
|
15648
|
+
const enriched = [];
|
|
15649
|
+
for (const u of updates) {
|
|
15650
|
+
const node = nodesRef.current?.find((n) => n.id === u.id);
|
|
15651
|
+
if (node) {
|
|
15652
|
+
const prev = Object.fromEntries(Object.keys(u.patch).map((k) => [k, node[k]]));
|
|
15653
|
+
enriched.push({ id: u.id, prev, patch: u.patch });
|
|
15654
|
+
}
|
|
15655
|
+
}
|
|
15656
|
+
if (enriched.length > 0) {
|
|
15657
|
+
pushCommand({ type: "nodes:update", updates: enriched, canvasRef });
|
|
15658
|
+
}
|
|
15659
|
+
}
|
|
15660
|
+
onNodesUpdateRef.current?.(updates, canvasRef);
|
|
15661
|
+
},
|
|
15662
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
15663
|
+
[enabled, nodesRef]
|
|
15664
|
+
);
|
|
15665
|
+
const wrappedOnNodeDelete = (0, import_react8.useCallback)(
|
|
15666
|
+
(nodeId, canvasRef) => {
|
|
15667
|
+
if (enabled && !isUndoingRef.current) {
|
|
15668
|
+
const node = nodesRef.current?.find((n) => n.id === nodeId);
|
|
15669
|
+
if (node) {
|
|
15670
|
+
pushCommand({ type: "node:delete", node, canvasRef });
|
|
15671
|
+
}
|
|
15672
|
+
}
|
|
15673
|
+
onNodeDeleteRef.current?.(nodeId, canvasRef);
|
|
15674
|
+
},
|
|
15675
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
15676
|
+
[enabled, nodesRef]
|
|
15677
|
+
);
|
|
15678
|
+
const wrappedOnNodesDelete = (0, import_react8.useCallback)(
|
|
15679
|
+
(nodeIds, canvasRef) => {
|
|
15680
|
+
if (enabled && !isUndoingRef.current) {
|
|
15681
|
+
const nodes = nodesRef.current?.filter((n) => nodeIds.includes(n.id)) ?? [];
|
|
15682
|
+
if (nodes.length > 0) {
|
|
15683
|
+
pushCommand({ type: "nodes:delete", nodes, canvasRef });
|
|
15684
|
+
}
|
|
15685
|
+
}
|
|
15686
|
+
onNodesDeleteRef.current?.(nodeIds, canvasRef);
|
|
15687
|
+
},
|
|
15688
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
15689
|
+
[enabled, nodesRef]
|
|
15690
|
+
);
|
|
15691
|
+
const wrappedOnEdgeAdd = (0, import_react8.useCallback)(
|
|
15692
|
+
(edge, canvasRef) => {
|
|
15693
|
+
if (enabled && !isUndoingRef.current) {
|
|
15694
|
+
pushCommand({ type: "edge:add", edge, canvasRef });
|
|
15695
|
+
}
|
|
15696
|
+
onEdgeAddRef.current?.(edge, canvasRef);
|
|
15697
|
+
},
|
|
15698
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
15699
|
+
[enabled]
|
|
15700
|
+
);
|
|
15701
|
+
const wrappedOnEdgeUpdate = (0, import_react8.useCallback)(
|
|
15702
|
+
(id2, patch, canvasRef) => {
|
|
15703
|
+
if (enabled && !isUndoingRef.current) {
|
|
15704
|
+
const edge = edgesRef.current?.find((e) => e.id === id2);
|
|
15705
|
+
if (edge) {
|
|
15706
|
+
const prev = Object.fromEntries(Object.keys(patch).map((k) => [k, edge[k]]));
|
|
15707
|
+
pushCommand({ type: "edge:update", id: id2, prev, patch, canvasRef });
|
|
15708
|
+
}
|
|
15709
|
+
}
|
|
15710
|
+
onEdgeUpdateRef.current?.(id2, patch, canvasRef);
|
|
15711
|
+
},
|
|
15712
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
15713
|
+
[enabled, edgesRef]
|
|
15714
|
+
);
|
|
15715
|
+
const wrappedOnEdgeDelete = (0, import_react8.useCallback)(
|
|
15716
|
+
(edgeId, canvasRef) => {
|
|
15717
|
+
if (enabled && !isUndoingRef.current) {
|
|
15718
|
+
const edge = edgesRef.current?.find((e) => e.id === edgeId);
|
|
15719
|
+
if (edge) {
|
|
15720
|
+
pushCommand({ type: "edge:delete", edge, canvasRef });
|
|
15721
|
+
}
|
|
15722
|
+
}
|
|
15723
|
+
onEdgeDeleteRef.current?.(edgeId, canvasRef);
|
|
15724
|
+
},
|
|
15725
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
15726
|
+
[enabled, edgesRef]
|
|
15727
|
+
);
|
|
15728
|
+
return {
|
|
15729
|
+
wrappedOnNodeAdd,
|
|
15730
|
+
wrappedOnNodeUpdate,
|
|
15731
|
+
wrappedOnNodesUpdate,
|
|
15732
|
+
wrappedOnNodeDelete,
|
|
15733
|
+
wrappedOnNodesDelete,
|
|
15734
|
+
wrappedOnEdgeAdd,
|
|
15735
|
+
wrappedOnEdgeUpdate,
|
|
15736
|
+
wrappedOnEdgeDelete,
|
|
15737
|
+
beginBatch,
|
|
15738
|
+
endBatch,
|
|
15739
|
+
undo,
|
|
15740
|
+
redo,
|
|
15741
|
+
canUndo,
|
|
15742
|
+
canRedo
|
|
15743
|
+
};
|
|
15744
|
+
}
|
|
15745
|
+
|
|
15746
|
+
// ../react/dist/hooks/useZoomNavigation.js
|
|
15747
|
+
var import_react9 = __toESM(require_react(), 1);
|
|
15155
15748
|
function expandRect(rect, factor) {
|
|
15156
15749
|
if (factor === 1)
|
|
15157
15750
|
return rect;
|
|
@@ -15189,16 +15782,16 @@ var SystemCanvas = (() => {
|
|
|
15189
15782
|
}
|
|
15190
15783
|
function useZoomNavigation(options) {
|
|
15191
15784
|
const { enabled, config, nodes, currentCanvas, parentFrame, canvases, onResolveCanvas, onSeedCanvas, theme, getViewportSize, getCursorScreenPos, onEnter, onExit } = options;
|
|
15192
|
-
const committingRef = (0,
|
|
15193
|
-
(0,
|
|
15785
|
+
const committingRef = (0, import_react9.useRef)(false);
|
|
15786
|
+
(0, import_react9.useEffect)(() => {
|
|
15194
15787
|
committingRef.current = false;
|
|
15195
15788
|
}, [currentCanvas]);
|
|
15196
|
-
const exitArmedRef = (0,
|
|
15197
|
-
(0,
|
|
15789
|
+
const exitArmedRef = (0, import_react9.useRef)(false);
|
|
15790
|
+
(0, import_react9.useEffect)(() => {
|
|
15198
15791
|
exitArmedRef.current = false;
|
|
15199
15792
|
}, [currentCanvas, parentFrame]);
|
|
15200
|
-
const prefetchRef = (0,
|
|
15201
|
-
const prefetch = (0,
|
|
15793
|
+
const prefetchRef = (0, import_react9.useRef)(/* @__PURE__ */ new Map());
|
|
15794
|
+
const prefetch = (0, import_react9.useCallback)((ref) => {
|
|
15202
15795
|
if (!onResolveCanvas)
|
|
15203
15796
|
return;
|
|
15204
15797
|
if (canvases?.[ref])
|
|
@@ -15216,7 +15809,7 @@ var SystemCanvas = (() => {
|
|
|
15216
15809
|
state.loading = false;
|
|
15217
15810
|
});
|
|
15218
15811
|
}, [canvases, onResolveCanvas, onSeedCanvas]);
|
|
15219
|
-
const handleViewportChange = (0,
|
|
15812
|
+
const handleViewportChange = (0, import_react9.useCallback)((vp) => {
|
|
15220
15813
|
if (!enabled)
|
|
15221
15814
|
return;
|
|
15222
15815
|
if (committingRef.current)
|
|
@@ -15355,7 +15948,7 @@ var SystemCanvas = (() => {
|
|
|
15355
15948
|
onEnter,
|
|
15356
15949
|
onExit
|
|
15357
15950
|
]);
|
|
15358
|
-
const clearCommitting = (0,
|
|
15951
|
+
const clearCommitting = (0, import_react9.useCallback)(() => {
|
|
15359
15952
|
committingRef.current = false;
|
|
15360
15953
|
}, []);
|
|
15361
15954
|
return { handleViewportChange, clearCommitting };
|
|
@@ -15363,10 +15956,10 @@ var SystemCanvas = (() => {
|
|
|
15363
15956
|
|
|
15364
15957
|
// ../react/dist/components/Viewport.js
|
|
15365
15958
|
var import_jsx_runtime22 = __toESM(require_jsx_runtime(), 1);
|
|
15366
|
-
var
|
|
15959
|
+
var import_react18 = __toESM(require_react(), 1);
|
|
15367
15960
|
|
|
15368
15961
|
// ../react/dist/hooks/useViewport.js
|
|
15369
|
-
var
|
|
15962
|
+
var import_react10 = __toESM(require_react(), 1);
|
|
15370
15963
|
|
|
15371
15964
|
// ../../node_modules/d3-dispatch/src/dispatch.js
|
|
15372
15965
|
var noop = { value: () => {
|
|
@@ -18109,13 +18702,13 @@ var SystemCanvas = (() => {
|
|
|
18109
18702
|
// ../react/dist/hooks/useViewport.js
|
|
18110
18703
|
function useViewport(options) {
|
|
18111
18704
|
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,
|
|
18705
|
+
const svgRef = (0, import_react10.useRef)(null);
|
|
18706
|
+
const groupRef = (0, import_react10.useRef)(null);
|
|
18707
|
+
const viewport = (0, import_react10.useRef)(defaultViewport ?? { x: 0, y: 0, zoom: 1 });
|
|
18708
|
+
const zoomBehaviorRef = (0, import_react10.useRef)(null);
|
|
18709
|
+
const onViewportChangeRef = (0, import_react10.useRef)(onViewportChange);
|
|
18117
18710
|
onViewportChangeRef.current = onViewportChange;
|
|
18118
|
-
(0,
|
|
18711
|
+
(0, import_react10.useEffect)(() => {
|
|
18119
18712
|
const svg = svgRef.current;
|
|
18120
18713
|
const group = groupRef.current;
|
|
18121
18714
|
if (!svg || !group)
|
|
@@ -18155,7 +18748,7 @@ var SystemCanvas = (() => {
|
|
|
18155
18748
|
selection2.on(".zoom", null);
|
|
18156
18749
|
};
|
|
18157
18750
|
}, [minZoom, maxZoom]);
|
|
18158
|
-
const fitToContent = (0,
|
|
18751
|
+
const fitToContent = (0, import_react10.useCallback)((nodes, animate = true) => {
|
|
18159
18752
|
const svg = svgRef.current;
|
|
18160
18753
|
if (!svg || !zoomBehaviorRef.current || nodes.length === 0)
|
|
18161
18754
|
return;
|
|
@@ -18168,13 +18761,13 @@ var SystemCanvas = (() => {
|
|
|
18168
18761
|
select_default2(svg).call(zoomBehaviorRef.current.transform, t);
|
|
18169
18762
|
}
|
|
18170
18763
|
}, []);
|
|
18171
|
-
const resetZoom = (0,
|
|
18764
|
+
const resetZoom = (0, import_react10.useCallback)(() => {
|
|
18172
18765
|
const svg = svgRef.current;
|
|
18173
18766
|
if (!svg || !zoomBehaviorRef.current)
|
|
18174
18767
|
return;
|
|
18175
18768
|
select_default2(svg).transition().duration(400).call(zoomBehaviorRef.current.transform, identity2);
|
|
18176
18769
|
}, []);
|
|
18177
|
-
const setTransform = (0,
|
|
18770
|
+
const setTransform = (0, import_react10.useCallback)((transform2, options2) => {
|
|
18178
18771
|
const svg = svgRef.current;
|
|
18179
18772
|
if (!svg || !zoomBehaviorRef.current)
|
|
18180
18773
|
return;
|
|
@@ -18186,7 +18779,7 @@ var SystemCanvas = (() => {
|
|
|
18186
18779
|
sel.call(zoomBehaviorRef.current.transform, t);
|
|
18187
18780
|
}
|
|
18188
18781
|
}, []);
|
|
18189
|
-
const zoomToNode = (0,
|
|
18782
|
+
const zoomToNode = (0, import_react10.useCallback)((node, onComplete, options2) => {
|
|
18190
18783
|
const svg = svgRef.current;
|
|
18191
18784
|
if (!svg || !zoomBehaviorRef.current) {
|
|
18192
18785
|
onComplete?.();
|
|
@@ -18380,9 +18973,9 @@ var SystemCanvas = (() => {
|
|
|
18380
18973
|
|
|
18381
18974
|
// ../react/dist/components/RefIndicator.js
|
|
18382
18975
|
var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
|
|
18383
|
-
var
|
|
18976
|
+
var import_react11 = __toESM(require_react(), 1);
|
|
18384
18977
|
function RefIndicator({ node, theme, nodeX, nodeY, nodeWidth, nodeHeight, strokeColor, strokeWidth, corner = "bottom-right", size: sizeProp, onNavigate }) {
|
|
18385
|
-
const [hover, setHover] = (0,
|
|
18978
|
+
const [hover, setHover] = (0, import_react11.useState)(false);
|
|
18386
18979
|
const iconKind = theme.node.refIndicator.icon;
|
|
18387
18980
|
if (iconKind === "none")
|
|
18388
18981
|
return null;
|
|
@@ -18453,7 +19046,7 @@ var SystemCanvas = (() => {
|
|
|
18453
19046
|
|
|
18454
19047
|
// ../react/dist/components/CategorySlotsLayer.js
|
|
18455
19048
|
var import_jsx_runtime9 = __toESM(require_jsx_runtime(), 1);
|
|
18456
|
-
var
|
|
19049
|
+
var import_react13 = __toESM(require_react(), 1);
|
|
18457
19050
|
|
|
18458
19051
|
// ../react/dist/primitives/NodeColorFill.js
|
|
18459
19052
|
var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -18573,9 +19166,9 @@ var SystemCanvas = (() => {
|
|
|
18573
19166
|
|
|
18574
19167
|
// ../react/dist/primitives/NodeText.js
|
|
18575
19168
|
var import_jsx_runtime7 = __toESM(require_jsx_runtime(), 1);
|
|
18576
|
-
var
|
|
19169
|
+
var import_react12 = __toESM(require_react(), 1);
|
|
18577
19170
|
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,
|
|
19171
|
+
const reactId = (0, import_react12.useId)();
|
|
18579
19172
|
const safeId = reactId.replace(/:/g, "");
|
|
18580
19173
|
if (!value)
|
|
18581
19174
|
return null;
|
|
@@ -18649,8 +19242,8 @@ var SystemCanvas = (() => {
|
|
|
18649
19242
|
// ../react/dist/components/CategorySlotsLayer.js
|
|
18650
19243
|
function CategorySlotsLayer({ node, theme, canvases, slots: slotsProp }) {
|
|
18651
19244
|
const slots = slotsProp ?? getCategorySlots(node, theme);
|
|
18652
|
-
const regions = (0,
|
|
18653
|
-
const reactId = (0,
|
|
19245
|
+
const regions = (0, import_react13.useMemo)(() => computeCategorySlotRegions(node, theme, slots), [node, theme, slots]);
|
|
19246
|
+
const reactId = (0, import_react13.useId)();
|
|
18654
19247
|
const clipId = `sc-edge-clip-${reactId.replace(/:/g, "")}`;
|
|
18655
19248
|
if (!slots)
|
|
18656
19249
|
return null;
|
|
@@ -18883,7 +19476,7 @@ var SystemCanvas = (() => {
|
|
|
18883
19476
|
|
|
18884
19477
|
// ../react/dist/components/ResizeHandles.js
|
|
18885
19478
|
var import_jsx_runtime14 = __toESM(require_jsx_runtime(), 1);
|
|
18886
|
-
var
|
|
19479
|
+
var import_react14 = __toESM(require_react(), 1);
|
|
18887
19480
|
var HANDLE_SIZE = 7;
|
|
18888
19481
|
var CORNERS = [
|
|
18889
19482
|
{ corner: "nw", cursor: "nwse-resize", anchor: "nw" },
|
|
@@ -18894,7 +19487,7 @@ var SystemCanvas = (() => {
|
|
|
18894
19487
|
var cornerInset = (cornerRadius) => Math.min(cornerRadius * 0.25, 3);
|
|
18895
19488
|
function ResizeHandles({ node, theme, onHandlePointerDown }) {
|
|
18896
19489
|
const { x, y, width, height } = node;
|
|
18897
|
-
const [hoveredCorner, setHoveredCorner] = (0,
|
|
19490
|
+
const [hoveredCorner, setHoveredCorner] = (0, import_react14.useState)(null);
|
|
18898
19491
|
const handleColor = node.resolvedStroke ?? theme.node.labelColor;
|
|
18899
19492
|
const i = cornerInset(node.resolvedCornerRadius);
|
|
18900
19493
|
const anchorPos = (anchor) => {
|
|
@@ -18919,7 +19512,7 @@ var SystemCanvas = (() => {
|
|
|
18919
19512
|
}
|
|
18920
19513
|
|
|
18921
19514
|
// ../react/dist/components/NodeRenderer.js
|
|
18922
|
-
function NodeRenderer({ nodes, theme, onClick, onDoubleClick, onContextMenu, onNavigate, onPointerDown,
|
|
19515
|
+
function NodeRenderer({ nodes, theme, onClick, onDoubleClick, onContextMenu, onNavigate, onPointerDown, selectedIds, editingId, onResizeHandlePointerDown, canvases, only }) {
|
|
18923
19516
|
const groups = nodes.filter((n) => n.type === "group");
|
|
18924
19517
|
const others = nodes.filter((n) => n.type !== "group");
|
|
18925
19518
|
const common = (node) => {
|
|
@@ -18935,7 +19528,7 @@ var SystemCanvas = (() => {
|
|
|
18935
19528
|
onContextMenu,
|
|
18936
19529
|
onNavigate,
|
|
18937
19530
|
onPointerDown,
|
|
18938
|
-
isSelected:
|
|
19531
|
+
isSelected: selectedIds?.has(node.id) ?? false,
|
|
18939
19532
|
isEditing: editingId === node.id,
|
|
18940
19533
|
slots,
|
|
18941
19534
|
canvases,
|
|
@@ -18946,7 +19539,8 @@ var SystemCanvas = (() => {
|
|
|
18946
19539
|
refCorner
|
|
18947
19540
|
};
|
|
18948
19541
|
};
|
|
18949
|
-
const
|
|
19542
|
+
const singleSelectedId = selectedIds?.size === 1 ? Array.from(selectedIds)[0] : null;
|
|
19543
|
+
const selectedNode = singleSelectedId && editingId !== singleSelectedId ? nodes.find((n) => n.id === singleSelectedId) : void 0;
|
|
18950
19544
|
const renderResizeHandles = only !== "groups" && selectedNode && onResizeHandlePointerDown;
|
|
18951
19545
|
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
19546
|
const Component = getNodeComponent(node.type);
|
|
@@ -19004,7 +19598,7 @@ var SystemCanvas = (() => {
|
|
|
19004
19598
|
|
|
19005
19599
|
// ../react/dist/components/NodeEditor.js
|
|
19006
19600
|
var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
|
|
19007
|
-
var
|
|
19601
|
+
var import_react15 = __toESM(require_react(), 1);
|
|
19008
19602
|
function NodeEditor({ node, theme, onCommit, onCancel }) {
|
|
19009
19603
|
const editableFields = useCategoryFields(node, theme);
|
|
19010
19604
|
if (editableFields) {
|
|
@@ -19023,11 +19617,11 @@ var SystemCanvas = (() => {
|
|
|
19023
19617
|
}
|
|
19024
19618
|
function SingleFieldEditor({ node, theme, onCommit, onCancel }) {
|
|
19025
19619
|
const initial = getInitialValue(node);
|
|
19026
|
-
const [value, setValue] = (0,
|
|
19027
|
-
const textareaRef = (0,
|
|
19028
|
-
const inputRef = (0,
|
|
19029
|
-
const committedRef = (0,
|
|
19030
|
-
(0,
|
|
19620
|
+
const [value, setValue] = (0, import_react15.useState)(initial);
|
|
19621
|
+
const textareaRef = (0, import_react15.useRef)(null);
|
|
19622
|
+
const inputRef = (0, import_react15.useRef)(null);
|
|
19623
|
+
const committedRef = (0, import_react15.useRef)(false);
|
|
19624
|
+
(0, import_react15.useEffect)(() => {
|
|
19031
19625
|
const el = textareaRef.current ?? inputRef.current;
|
|
19032
19626
|
if (el) {
|
|
19033
19627
|
el.focus();
|
|
@@ -19123,10 +19717,10 @@ var SystemCanvas = (() => {
|
|
|
19123
19717
|
}
|
|
19124
19718
|
}
|
|
19125
19719
|
function FormEditor({ node, theme, fields, onCommit, onCancel }) {
|
|
19126
|
-
const initial = (0,
|
|
19127
|
-
const [values, setValues] = (0,
|
|
19128
|
-
const committedRef = (0,
|
|
19129
|
-
const panelRef = (0,
|
|
19720
|
+
const initial = (0, import_react15.useMemo)(() => readInitialValues(node, fields), [node, fields]);
|
|
19721
|
+
const [values, setValues] = (0, import_react15.useState)(initial);
|
|
19722
|
+
const committedRef = (0, import_react15.useRef)(false);
|
|
19723
|
+
const panelRef = (0, import_react15.useRef)(null);
|
|
19130
19724
|
const width = Math.max(node.width, 240);
|
|
19131
19725
|
const height = Math.max(node.height, 36 + fields.length * 44);
|
|
19132
19726
|
const commit = () => {
|
|
@@ -19155,7 +19749,7 @@ var SystemCanvas = (() => {
|
|
|
19155
19749
|
const stopPointer = (e) => {
|
|
19156
19750
|
e.stopPropagation();
|
|
19157
19751
|
};
|
|
19158
|
-
(0,
|
|
19752
|
+
(0, import_react15.useEffect)(() => {
|
|
19159
19753
|
const el = panelRef.current;
|
|
19160
19754
|
if (!el)
|
|
19161
19755
|
return;
|
|
@@ -19285,13 +19879,13 @@ var SystemCanvas = (() => {
|
|
|
19285
19879
|
|
|
19286
19880
|
// ../react/dist/components/EdgeLabelEditor.js
|
|
19287
19881
|
var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
|
|
19288
|
-
var
|
|
19882
|
+
var import_react16 = __toESM(require_react(), 1);
|
|
19289
19883
|
var EDITOR_WIDTH = 110;
|
|
19290
19884
|
function EdgeLabelEditor({ initialLabel, midpoint, theme, onCommit, onCancel }) {
|
|
19291
|
-
const [value, setValue] = (0,
|
|
19292
|
-
const inputRef = (0,
|
|
19293
|
-
const committedRef = (0,
|
|
19294
|
-
(0,
|
|
19885
|
+
const [value, setValue] = (0, import_react16.useState)(initialLabel);
|
|
19886
|
+
const inputRef = (0, import_react16.useRef)(null);
|
|
19887
|
+
const committedRef = (0, import_react16.useRef)(false);
|
|
19888
|
+
(0, import_react16.useEffect)(() => {
|
|
19295
19889
|
const el = inputRef.current;
|
|
19296
19890
|
if (el) {
|
|
19297
19891
|
el.focus();
|
|
@@ -19346,7 +19940,7 @@ var SystemCanvas = (() => {
|
|
|
19346
19940
|
|
|
19347
19941
|
// ../react/dist/components/ConnectionHandles.js
|
|
19348
19942
|
var import_jsx_runtime19 = __toESM(require_jsx_runtime(), 1);
|
|
19349
|
-
var
|
|
19943
|
+
var import_react17 = __toESM(require_react(), 1);
|
|
19350
19944
|
var SIDES = ["top", "right", "bottom", "left"];
|
|
19351
19945
|
var HANDLE_RADIUS = 4;
|
|
19352
19946
|
var HANDLE_HIT_RADIUS = 10;
|
|
@@ -19355,9 +19949,9 @@ var SystemCanvas = (() => {
|
|
|
19355
19949
|
var HOVER_SCALE = 1.42;
|
|
19356
19950
|
var HOVER_TRANSITION_MS = 120;
|
|
19357
19951
|
function ConnectionHandles({ node, theme, onHandlePointerDown, immediate, activeSide }) {
|
|
19358
|
-
const [visible, setVisible] = (0,
|
|
19359
|
-
const [hoveredSide, setHoveredSide] = (0,
|
|
19360
|
-
(0,
|
|
19952
|
+
const [visible, setVisible] = (0, import_react17.useState)(!!immediate);
|
|
19953
|
+
const [hoveredSide, setHoveredSide] = (0, import_react17.useState)(null);
|
|
19954
|
+
(0, import_react17.useEffect)(() => {
|
|
19361
19955
|
if (immediate) {
|
|
19362
19956
|
setVisible(true);
|
|
19363
19957
|
return;
|
|
@@ -19444,17 +20038,18 @@ var SystemCanvas = (() => {
|
|
|
19444
20038
|
// ../react/dist/components/Viewport.js
|
|
19445
20039
|
var HOVER_PADDING = 10;
|
|
19446
20040
|
var EDGE_PROXIMITY = 16;
|
|
19447
|
-
var Viewport = (0,
|
|
20041
|
+
var Viewport = (0, import_react18.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
20042
|
const { svgRef, groupRef, viewport, fitToContent, zoomToNode, setTransform } = useViewport({
|
|
19449
20043
|
minZoom,
|
|
19450
20044
|
maxZoom,
|
|
19451
20045
|
defaultViewport,
|
|
19452
|
-
onViewportChange
|
|
20046
|
+
onViewportChange,
|
|
20047
|
+
marqueeActiveRef
|
|
19453
20048
|
});
|
|
19454
|
-
const navigatingRef = (0,
|
|
19455
|
-
const fadeRafRef = (0,
|
|
19456
|
-
const fadeTimeoutRef = (0,
|
|
19457
|
-
const triggerFade = (0,
|
|
20049
|
+
const navigatingRef = (0, import_react18.useRef)(false);
|
|
20050
|
+
const fadeRafRef = (0, import_react18.useRef)(null);
|
|
20051
|
+
const fadeTimeoutRef = (0, import_react18.useRef)(null);
|
|
20052
|
+
const triggerFade = (0, import_react18.useCallback)((durationMs) => {
|
|
19458
20053
|
if (durationMs <= 0)
|
|
19459
20054
|
return;
|
|
19460
20055
|
const g = groupRef.current;
|
|
@@ -19477,7 +20072,7 @@ var SystemCanvas = (() => {
|
|
|
19477
20072
|
}, durationMs + 16);
|
|
19478
20073
|
});
|
|
19479
20074
|
}, []);
|
|
19480
|
-
(0,
|
|
20075
|
+
(0, import_react18.useEffect)(() => {
|
|
19481
20076
|
return () => {
|
|
19482
20077
|
if (fadeRafRef.current !== null)
|
|
19483
20078
|
cancelAnimationFrame(fadeRafRef.current);
|
|
@@ -19485,10 +20080,10 @@ var SystemCanvas = (() => {
|
|
|
19485
20080
|
clearTimeout(fadeTimeoutRef.current);
|
|
19486
20081
|
};
|
|
19487
20082
|
}, []);
|
|
19488
|
-
const [hoveredNodeId, setHoveredNodeId] = (0,
|
|
19489
|
-
const [hoveredSide, setHoveredSide] = (0,
|
|
19490
|
-
const cursorPosRef = (0,
|
|
19491
|
-
(0,
|
|
20083
|
+
const [hoveredNodeId, setHoveredNodeId] = (0, import_react18.useState)(null);
|
|
20084
|
+
const [hoveredSide, setHoveredSide] = (0, import_react18.useState)(null);
|
|
20085
|
+
const cursorPosRef = (0, import_react18.useRef)(null);
|
|
20086
|
+
(0, import_react18.useImperativeHandle)(ref, () => ({
|
|
19492
20087
|
zoomToNode: (node, onComplete, options) => {
|
|
19493
20088
|
navigatingRef.current = true;
|
|
19494
20089
|
zoomToNode(node, onComplete, options);
|
|
@@ -19499,7 +20094,7 @@ var SystemCanvas = (() => {
|
|
|
19499
20094
|
getViewport: () => viewport.current ?? { x: 0, y: 0, zoom: 1 },
|
|
19500
20095
|
getCursorScreenPos: () => cursorPosRef.current
|
|
19501
20096
|
}));
|
|
19502
|
-
const renderNodes = (0,
|
|
20097
|
+
const renderNodes = (0, import_react18.useMemo)(() => {
|
|
19503
20098
|
const hasDrag = dragOverrides && dragOverrides.size > 0;
|
|
19504
20099
|
const hasResize = resizeOverrides && resizeOverrides.size > 0;
|
|
19505
20100
|
if (!hasDrag && !hasResize)
|
|
@@ -19512,7 +20107,7 @@ var SystemCanvas = (() => {
|
|
|
19512
20107
|
return d ? { ...n, x: d.x, y: d.y } : n;
|
|
19513
20108
|
});
|
|
19514
20109
|
}, [nodes, dragOverrides, resizeOverrides]);
|
|
19515
|
-
const renderNodeMap = (0,
|
|
20110
|
+
const renderNodeMap = (0, import_react18.useMemo)(() => {
|
|
19516
20111
|
const hasDrag = dragOverrides && dragOverrides.size > 0;
|
|
19517
20112
|
const hasResize = resizeOverrides && resizeOverrides.size > 0;
|
|
19518
20113
|
if (!hasDrag && !hasResize)
|
|
@@ -19523,11 +20118,11 @@ var SystemCanvas = (() => {
|
|
|
19523
20118
|
}
|
|
19524
20119
|
return m;
|
|
19525
20120
|
}, [renderNodes, nodeMap, dragOverrides, resizeOverrides]);
|
|
19526
|
-
const latestNodesRef = (0,
|
|
19527
|
-
(0,
|
|
20121
|
+
const latestNodesRef = (0, import_react18.useRef)(nodes);
|
|
20122
|
+
(0, import_react18.useEffect)(() => {
|
|
19528
20123
|
latestNodesRef.current = nodes;
|
|
19529
20124
|
}, [nodes]);
|
|
19530
|
-
const fitNow = (0,
|
|
20125
|
+
const fitNow = (0, import_react18.useCallback)(() => {
|
|
19531
20126
|
const current = latestNodesRef.current;
|
|
19532
20127
|
if (current.length === 0)
|
|
19533
20128
|
return;
|
|
@@ -19537,7 +20132,7 @@ var SystemCanvas = (() => {
|
|
|
19537
20132
|
fitToContent(current, animate);
|
|
19538
20133
|
});
|
|
19539
20134
|
}, [fitToContent]);
|
|
19540
|
-
(0,
|
|
20135
|
+
(0, import_react18.useEffect)(() => {
|
|
19541
20136
|
if (defaultViewport)
|
|
19542
20137
|
return;
|
|
19543
20138
|
if (autoFit !== "always")
|
|
@@ -19546,8 +20141,8 @@ var SystemCanvas = (() => {
|
|
|
19546
20141
|
return;
|
|
19547
20142
|
fitNow();
|
|
19548
20143
|
}, [nodes, autoFit, defaultViewport, fitNow]);
|
|
19549
|
-
const fittedForRef = (0,
|
|
19550
|
-
(0,
|
|
20144
|
+
const fittedForRef = (0, import_react18.useRef)(null);
|
|
20145
|
+
(0, import_react18.useEffect)(() => {
|
|
19551
20146
|
if (defaultViewport)
|
|
19552
20147
|
return;
|
|
19553
20148
|
if (autoFit !== "canvas-change" && autoFit !== "initial")
|
|
@@ -19579,7 +20174,7 @@ var SystemCanvas = (() => {
|
|
|
19579
20174
|
triggerFade
|
|
19580
20175
|
]);
|
|
19581
20176
|
const editingNode = editingId ? renderNodes.find((n) => n.id === editingId) ?? null : null;
|
|
19582
|
-
const handleSvgPointerMove = (0,
|
|
20177
|
+
const handleSvgPointerMove = (0, import_react18.useCallback)((event) => {
|
|
19583
20178
|
const svg = svgRef.current;
|
|
19584
20179
|
if (!svg)
|
|
19585
20180
|
return;
|
|
@@ -19631,7 +20226,7 @@ var SystemCanvas = (() => {
|
|
|
19631
20226
|
setHoveredSide((prev) => prev === null ? prev : null);
|
|
19632
20227
|
}
|
|
19633
20228
|
}, [edgeCreateEnabled, renderNodes, svgRef, viewport]);
|
|
19634
|
-
const handleSvgPointerLeave = (0,
|
|
20229
|
+
const handleSvgPointerLeave = (0, import_react18.useCallback)(() => {
|
|
19635
20230
|
setHoveredNodeId(null);
|
|
19636
20231
|
setHoveredSide(null);
|
|
19637
20232
|
cursorPosRef.current = null;
|
|
@@ -19660,12 +20255,17 @@ var SystemCanvas = (() => {
|
|
|
19660
20255
|
WebkitUserSelect: "none",
|
|
19661
20256
|
MozUserSelect: "none",
|
|
19662
20257
|
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,
|
|
20258
|
+
}, 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) => {
|
|
20259
|
+
const node = renderNodeMap.get(id2);
|
|
20260
|
+
if (!node)
|
|
20261
|
+
return null;
|
|
20262
|
+
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}`);
|
|
20263
|
+
}), 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
20264
|
});
|
|
19665
20265
|
|
|
19666
20266
|
// ../react/dist/components/Breadcrumbs.js
|
|
19667
20267
|
var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1);
|
|
19668
|
-
var
|
|
20268
|
+
var import_react19 = __toESM(require_react(), 1);
|
|
19669
20269
|
function Breadcrumbs({ breadcrumbs, theme, onNavigate }) {
|
|
19670
20270
|
if (breadcrumbs.length <= 1)
|
|
19671
20271
|
return null;
|
|
@@ -19686,7 +20286,7 @@ var SystemCanvas = (() => {
|
|
|
19686
20286
|
backdropFilter: "blur(8px)"
|
|
19687
20287
|
}, children: breadcrumbs.map((crumb, index) => {
|
|
19688
20288
|
const isLast = index === breadcrumbs.length - 1;
|
|
19689
|
-
return (0, import_jsx_runtime23.jsxs)(
|
|
20289
|
+
return (0, import_jsx_runtime23.jsxs)(import_react19.default.Fragment, { children: [index > 0 && (0, import_jsx_runtime23.jsx)("span", { style: {
|
|
19690
20290
|
color: theme.separatorColor,
|
|
19691
20291
|
margin: "0 2px"
|
|
19692
20292
|
}, children: "/" }), (0, import_jsx_runtime23.jsx)("span", { onClick: isLast ? void 0 : () => onNavigate(index), style: {
|
|
@@ -19710,11 +20310,11 @@ var SystemCanvas = (() => {
|
|
|
19710
20310
|
|
|
19711
20311
|
// ../react/dist/components/AddNodeButton.js
|
|
19712
20312
|
var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1);
|
|
19713
|
-
var
|
|
20313
|
+
var import_react20 = __toESM(require_react(), 1);
|
|
19714
20314
|
function AddNodeButton({ options, addNode: addNode2, theme }) {
|
|
19715
|
-
const [open, setOpen] = (0,
|
|
19716
|
-
const rootRef = (0,
|
|
19717
|
-
(0,
|
|
20315
|
+
const [open, setOpen] = (0, import_react20.useState)(false);
|
|
20316
|
+
const rootRef = (0, import_react20.useRef)(null);
|
|
20317
|
+
(0, import_react20.useEffect)(() => {
|
|
19718
20318
|
if (!open)
|
|
19719
20319
|
return;
|
|
19720
20320
|
function onDocClick(e) {
|
|
@@ -19803,7 +20403,7 @@ var SystemCanvas = (() => {
|
|
|
19803
20403
|
} });
|
|
19804
20404
|
}
|
|
19805
20405
|
function MenuRow({ theme, option, onClick }) {
|
|
19806
|
-
const [hover, setHover] = (0,
|
|
20406
|
+
const [hover, setHover] = (0, import_react20.useState)(false);
|
|
19807
20407
|
const swatchSize = 18;
|
|
19808
20408
|
return (0, import_jsx_runtime24.jsxs)("div", { role: "button", onClick, onMouseEnter: () => setHover(true), onMouseLeave: () => setHover(false), style: {
|
|
19809
20409
|
display: "flex",
|
|
@@ -19839,12 +20439,12 @@ var SystemCanvas = (() => {
|
|
|
19839
20439
|
|
|
19840
20440
|
// ../react/dist/components/LaneHeaders.js
|
|
19841
20441
|
var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1);
|
|
19842
|
-
var
|
|
20442
|
+
var import_react21 = __toESM(require_react(), 1);
|
|
19843
20443
|
function LaneHeaders({ columns, rows, theme, getViewport, width, height, pinned = true }) {
|
|
19844
20444
|
const hasColumns = columns && columns.length > 0;
|
|
19845
20445
|
const hasRows = rows && rows.length > 0;
|
|
19846
|
-
const [viewport, setViewport] = (0,
|
|
19847
|
-
(0,
|
|
20446
|
+
const [viewport, setViewport] = (0, import_react21.useState)(() => getViewport());
|
|
20447
|
+
(0, import_react21.useEffect)(() => {
|
|
19848
20448
|
if (!hasColumns && !hasRows)
|
|
19849
20449
|
return;
|
|
19850
20450
|
let raf = 0;
|
|
@@ -19918,7 +20518,7 @@ var SystemCanvas = (() => {
|
|
|
19918
20518
|
|
|
19919
20519
|
// ../react/dist/components/NodeToolbar.js
|
|
19920
20520
|
var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1);
|
|
19921
|
-
var
|
|
20521
|
+
var import_react22 = __toESM(require_react(), 1);
|
|
19922
20522
|
var NODE_GAP = 10;
|
|
19923
20523
|
var FLIP_MARGIN = 8;
|
|
19924
20524
|
var PADDING = 6;
|
|
@@ -19926,9 +20526,9 @@ var SystemCanvas = (() => {
|
|
|
19926
20526
|
var SWATCH_SIZE = 16;
|
|
19927
20527
|
var BUTTON_SIZE = 28;
|
|
19928
20528
|
var DELETE_SIZE = 14;
|
|
19929
|
-
function NodeToolbar({ node, theme, onPatch, onDelete, getViewport, containerWidth, containerHeight, render: render2 }) {
|
|
19930
|
-
const [viewport, setViewport] = (0,
|
|
19931
|
-
(0,
|
|
20529
|
+
function NodeToolbar({ node, theme, onPatch, onDelete, getViewport, containerWidth, containerHeight, render: render2, selectedNodes, onMultiPatch }) {
|
|
20530
|
+
const [viewport, setViewport] = (0, import_react22.useState)(() => getViewport());
|
|
20531
|
+
(0, import_react22.useEffect)(() => {
|
|
19932
20532
|
let raf = 0;
|
|
19933
20533
|
let lastX = -Infinity;
|
|
19934
20534
|
let lastY = -Infinity;
|
|
@@ -19946,13 +20546,28 @@ var SystemCanvas = (() => {
|
|
|
19946
20546
|
raf = requestAnimationFrame(tick);
|
|
19947
20547
|
return () => cancelAnimationFrame(raf);
|
|
19948
20548
|
}, [getViewport]);
|
|
20549
|
+
const isMulti = selectedNodes != null && selectedNodes.length > 1;
|
|
19949
20550
|
const align = theme.toolbarAlign ?? "center";
|
|
19950
|
-
const
|
|
19951
|
-
|
|
19952
|
-
|
|
19953
|
-
|
|
19954
|
-
|
|
19955
|
-
|
|
20551
|
+
const { anchorTopY, anchorBottomY, anchorX } = (0, import_react22.useMemo)(() => {
|
|
20552
|
+
if (isMulti && selectedNodes) {
|
|
20553
|
+
const minX = Math.min(...selectedNodes.map((n) => n.x));
|
|
20554
|
+
const maxX = Math.max(...selectedNodes.map((n) => n.x + n.width));
|
|
20555
|
+
const minY = Math.min(...selectedNodes.map((n) => n.y));
|
|
20556
|
+
const maxY = Math.max(...selectedNodes.map((n) => n.y + n.height));
|
|
20557
|
+
return {
|
|
20558
|
+
anchorX: (minX + maxX) / 2,
|
|
20559
|
+
anchorTopY: minY,
|
|
20560
|
+
anchorBottomY: maxY
|
|
20561
|
+
};
|
|
20562
|
+
}
|
|
20563
|
+
const x = align === "left" ? node.x : align === "right" ? node.x + node.width : node.x + node.width / 2;
|
|
20564
|
+
return { anchorX: x, anchorTopY: node.y, anchorBottomY: node.y + node.height };
|
|
20565
|
+
}, [isMulti, selectedNodes, align, node]);
|
|
20566
|
+
const topAnchor = canvasToScreen(anchorX, anchorTopY, viewport);
|
|
20567
|
+
const bottomAnchor = canvasToScreen(anchorX, anchorBottomY, viewport);
|
|
20568
|
+
const toolbarRef = (0, import_react22.useRef)(null);
|
|
20569
|
+
const [size, setSize] = (0, import_react22.useState)({ width: 0, height: 0 });
|
|
20570
|
+
(0, import_react22.useEffect)(() => {
|
|
19956
20571
|
const el = toolbarRef.current;
|
|
19957
20572
|
if (!el)
|
|
19958
20573
|
return;
|
|
@@ -19965,7 +20580,12 @@ var SystemCanvas = (() => {
|
|
|
19965
20580
|
ro.observe(el);
|
|
19966
20581
|
return () => ro.disconnect();
|
|
19967
20582
|
}, []);
|
|
19968
|
-
let left
|
|
20583
|
+
let left;
|
|
20584
|
+
if (isMulti) {
|
|
20585
|
+
left = topAnchor.x - size.width / 2;
|
|
20586
|
+
} else {
|
|
20587
|
+
left = align === "left" ? topAnchor.x : align === "right" ? topAnchor.x - size.width : topAnchor.x - size.width / 2;
|
|
20588
|
+
}
|
|
19969
20589
|
let top = topAnchor.y - size.height - NODE_GAP;
|
|
19970
20590
|
if (top < FLIP_MARGIN) {
|
|
19971
20591
|
top = bottomAnchor.y + NODE_GAP;
|
|
@@ -20002,13 +20622,51 @@ var SystemCanvas = (() => {
|
|
|
20002
20622
|
userSelect: "none",
|
|
20003
20623
|
whiteSpace: "nowrap"
|
|
20004
20624
|
},
|
|
20005
|
-
children: render2 ? render2({ node, theme, patch, deleteNode }) : (0, import_jsx_runtime26.jsx)(DefaultToolbarContent, { node, theme, onPatch: patch, onDelete: deleteNode })
|
|
20625
|
+
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
20626
|
});
|
|
20007
20627
|
}
|
|
20628
|
+
function MultiToolbarContent({ selectedNodes, theme, onMultiPatch, onDelete }) {
|
|
20629
|
+
const representativeNode = selectedNodes[0];
|
|
20630
|
+
const groups = (0, import_react22.useMemo)(() => getNodeActionsForNode(representativeNode, theme), [representativeNode, theme]);
|
|
20631
|
+
const showDelete = theme.showToolbarDelete === true;
|
|
20632
|
+
const swatchGroups = groups.filter((g) => g.kind === "swatches" || g.kind == null);
|
|
20633
|
+
const otherGroups = groups.filter((g) => g.kind !== "swatches" && g.kind != null && g.kind !== "menu");
|
|
20634
|
+
return (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [(0, import_jsx_runtime26.jsxs)("span", { style: {
|
|
20635
|
+
fontSize: 11,
|
|
20636
|
+
color: theme.breadcrumbs.textColor,
|
|
20637
|
+
opacity: 0.75,
|
|
20638
|
+
paddingRight: BUTTON_GAP,
|
|
20639
|
+
whiteSpace: "nowrap"
|
|
20640
|
+
}, children: [selectedNodes.length, " nodes"] }), swatchGroups.map((group, i) => {
|
|
20641
|
+
const actions = filterActionsForNode(group, representativeNode);
|
|
20642
|
+
if (actions.length === 0)
|
|
20643
|
+
return null;
|
|
20644
|
+
return (0, import_jsx_runtime26.jsxs)(import_react22.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) => {
|
|
20645
|
+
const active = action.isActive?.(representativeNode) ?? false;
|
|
20646
|
+
const handleClick = () => {
|
|
20647
|
+
const patch = resolveActionPatch(action, representativeNode);
|
|
20648
|
+
onMultiPatch(patch);
|
|
20649
|
+
};
|
|
20650
|
+
return (0, import_jsx_runtime26.jsx)(SwatchButton, { action, active, theme, onClick: handleClick }, action.id);
|
|
20651
|
+
}) })] }, group.id);
|
|
20652
|
+
}), otherGroups.map((group) => {
|
|
20653
|
+
const actions = filterActionsForNode(group, representativeNode);
|
|
20654
|
+
if (actions.length === 0)
|
|
20655
|
+
return null;
|
|
20656
|
+
return (0, import_jsx_runtime26.jsxs)(import_react22.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) => {
|
|
20657
|
+
const active = action.isActive?.(representativeNode) ?? false;
|
|
20658
|
+
const handleClick = () => {
|
|
20659
|
+
const patch = resolveActionPatch(action, representativeNode);
|
|
20660
|
+
onMultiPatch(patch);
|
|
20661
|
+
};
|
|
20662
|
+
return (0, import_jsx_runtime26.jsx)(IconButton, { action, active, theme, onClick: handleClick }, action.id);
|
|
20663
|
+
}) })] }, group.id);
|
|
20664
|
+
}), 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 })] })] });
|
|
20665
|
+
}
|
|
20008
20666
|
function DefaultToolbarContent({ node, theme, onPatch, onDelete }) {
|
|
20009
|
-
const groups = (0,
|
|
20667
|
+
const groups = (0, import_react22.useMemo)(() => getNodeActionsForNode(node, theme), [node, theme]);
|
|
20010
20668
|
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)(
|
|
20669
|
+
return (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [groups.map((group, i) => (0, import_jsx_runtime26.jsxs)(import_react22.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
20670
|
}
|
|
20013
20671
|
function Divider2({ theme }) {
|
|
20014
20672
|
return (0, import_jsx_runtime26.jsx)("div", { style: {
|
|
@@ -20075,9 +20733,9 @@ var SystemCanvas = (() => {
|
|
|
20075
20733
|
} }) : (0, import_jsx_runtime26.jsx)("span", { style: { fontSize: 10 }, children: action.label.slice(0, 2) }) });
|
|
20076
20734
|
}
|
|
20077
20735
|
function MenuGroup({ group, actions, node, theme, onPatch }) {
|
|
20078
|
-
const [open, setOpen] = (0,
|
|
20079
|
-
const wrapRef = (0,
|
|
20080
|
-
(0,
|
|
20736
|
+
const [open, setOpen] = (0, import_react22.useState)(false);
|
|
20737
|
+
const wrapRef = (0, import_react22.useRef)(null);
|
|
20738
|
+
(0, import_react22.useEffect)(() => {
|
|
20081
20739
|
if (!open)
|
|
20082
20740
|
return;
|
|
20083
20741
|
const onDown = (e) => {
|
|
@@ -20164,18 +20822,18 @@ var SystemCanvas = (() => {
|
|
|
20164
20822
|
|
|
20165
20823
|
// ../react/dist/components/NodeContextMenuOverlay.js
|
|
20166
20824
|
var import_jsx_runtime27 = __toESM(require_jsx_runtime(), 1);
|
|
20167
|
-
var
|
|
20825
|
+
var import_react23 = __toESM(require_react(), 1);
|
|
20168
20826
|
var ESTIMATED_MENU_WIDTH = 200;
|
|
20169
20827
|
var MIN_MENU_WIDTH = 160;
|
|
20170
20828
|
var VIEWPORT_MARGIN = 8;
|
|
20171
20829
|
function NodeContextMenuOverlay({ state, config, theme, onClose }) {
|
|
20172
|
-
const rootRef = (0,
|
|
20173
|
-
const [hoveredId, setHoveredId] = (0,
|
|
20174
|
-
(0,
|
|
20830
|
+
const rootRef = (0, import_react23.useRef)(null);
|
|
20831
|
+
const [hoveredId, setHoveredId] = (0, import_react23.useState)(null);
|
|
20832
|
+
(0, import_react23.useEffect)(() => {
|
|
20175
20833
|
if (state)
|
|
20176
20834
|
setHoveredId(null);
|
|
20177
20835
|
}, [state]);
|
|
20178
|
-
(0,
|
|
20836
|
+
(0, import_react23.useEffect)(() => {
|
|
20179
20837
|
if (!state)
|
|
20180
20838
|
return;
|
|
20181
20839
|
function onDown(e) {
|
|
@@ -20283,8 +20941,8 @@ var SystemCanvas = (() => {
|
|
|
20283
20941
|
// ../react/dist/components/SystemCanvas.js
|
|
20284
20942
|
var CASCADE_WINDOW_MS = 1500;
|
|
20285
20943
|
var CASCADE_OFFSET = 20;
|
|
20286
|
-
var SystemCanvas = (0,
|
|
20287
|
-
const zoomNavConfig = (0,
|
|
20944
|
+
var SystemCanvas = (0, import_react24.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, historyDepth, onUndo, onRedo, className, style }, forwardedRef) {
|
|
20945
|
+
const zoomNavConfig = (0, import_react24.useMemo)(() => {
|
|
20288
20946
|
const defaults = {
|
|
20289
20947
|
enterThreshold: 0.66,
|
|
20290
20948
|
exitThreshold: 0.33,
|
|
@@ -20309,16 +20967,16 @@ var SystemCanvas = (() => {
|
|
|
20309
20967
|
}, [zoomNavigation]);
|
|
20310
20968
|
const effectiveMaxZoom = maxZoom ?? (zoomNavConfig.enabled ? 16 : 4);
|
|
20311
20969
|
const effectiveMinZoom = minZoomProp ?? (zoomNavConfig.enabled ? 0.01 : 0.1);
|
|
20312
|
-
(0,
|
|
20970
|
+
(0, import_react24.useEffect)(() => {
|
|
20313
20971
|
const env = globalThis.process?.env?.NODE_ENV;
|
|
20314
20972
|
if (editable && !canvases && env !== "production") {
|
|
20315
20973
|
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
20974
|
}
|
|
20317
20975
|
}, [editable, canvases]);
|
|
20318
|
-
const [parentFrames, setParentFrames] = (0,
|
|
20319
|
-
const [pendingHandoff, setPendingHandoff] = (0,
|
|
20320
|
-
const suppressNextHandoffClearRef = (0,
|
|
20321
|
-
const handleBreadcrumbClick = (0,
|
|
20976
|
+
const [parentFrames, setParentFrames] = (0, import_react24.useState)([]);
|
|
20977
|
+
const [pendingHandoff, setPendingHandoff] = (0, import_react24.useState)(null);
|
|
20978
|
+
const suppressNextHandoffClearRef = (0, import_react24.useRef)(false);
|
|
20979
|
+
const handleBreadcrumbClick = (0, import_react24.useCallback)((index) => {
|
|
20322
20980
|
setParentFrames((prev) => prev.slice(0, index));
|
|
20323
20981
|
if (suppressNextHandoffClearRef.current) {
|
|
20324
20982
|
suppressNextHandoffClearRef.current = false;
|
|
@@ -20335,10 +20993,10 @@ var SystemCanvas = (() => {
|
|
|
20335
20993
|
onNavigate,
|
|
20336
20994
|
onBreadcrumbClick: handleBreadcrumbClick
|
|
20337
20995
|
});
|
|
20338
|
-
(0,
|
|
20996
|
+
(0, import_react24.useEffect)(() => {
|
|
20339
20997
|
onBreadcrumbsChange?.(breadcrumbs);
|
|
20340
20998
|
}, [breadcrumbs, onBreadcrumbsChange]);
|
|
20341
|
-
const theme = (0,
|
|
20999
|
+
const theme = (0, import_react24.useMemo)(() => {
|
|
20342
21000
|
const registry = { ...themes, ...customThemes };
|
|
20343
21001
|
const resolveByName = (name) => name && registry[name] ? registry[name] : null;
|
|
20344
21002
|
if (themeProp) {
|
|
@@ -20349,22 +21007,22 @@ var SystemCanvas = (() => {
|
|
|
20349
21007
|
}
|
|
20350
21008
|
return resolveByName(currentCanvas.theme?.base) ?? resolveByName(canvas.theme?.base) ?? darkTheme;
|
|
20351
21009
|
}, [themeProp, customThemes, currentCanvas.theme?.base, canvas.theme?.base]);
|
|
20352
|
-
const { nodes, edges, nodeMap } = (0,
|
|
21010
|
+
const { nodes, edges, nodeMap } = (0, import_react24.useMemo)(() => {
|
|
20353
21011
|
const resolved = resolveCanvas(currentCanvas, theme);
|
|
20354
21012
|
const map = buildNodeMap(resolved.nodes);
|
|
20355
21013
|
return { nodes: resolved.nodes, edges: resolved.edges, nodeMap: map };
|
|
20356
21014
|
}, [currentCanvas, theme]);
|
|
20357
|
-
const nodesRef = (0,
|
|
21015
|
+
const nodesRef = (0, import_react24.useRef)(nodes);
|
|
20358
21016
|
nodesRef.current = nodes;
|
|
20359
|
-
const viewportStateRef = (0,
|
|
20360
|
-
const viewportHandleRef = (0,
|
|
20361
|
-
const navigateToRefRef = (0,
|
|
21017
|
+
const viewportStateRef = (0, import_react24.useRef)(defaultViewport ?? { x: 0, y: 0, zoom: 1 });
|
|
21018
|
+
const viewportHandleRef = (0, import_react24.useRef)(null);
|
|
21019
|
+
const navigateToRefRef = (0, import_react24.useRef)(navigateToRef);
|
|
20362
21020
|
navigateToRefRef.current = navigateToRef;
|
|
20363
|
-
const navigateToBreadcrumbRef = (0,
|
|
21021
|
+
const navigateToBreadcrumbRef = (0, import_react24.useRef)(navigateToBreadcrumb);
|
|
20364
21022
|
navigateToBreadcrumbRef.current = navigateToBreadcrumb;
|
|
20365
|
-
const breadcrumbsRef = (0,
|
|
21023
|
+
const breadcrumbsRef = (0, import_react24.useRef)(breadcrumbs);
|
|
20366
21024
|
breadcrumbsRef.current = breadcrumbs;
|
|
20367
|
-
(0,
|
|
21025
|
+
(0, import_react24.useImperativeHandle)(forwardedRef, () => ({
|
|
20368
21026
|
zoomIntoNode: (nodeId, options) => {
|
|
20369
21027
|
return new Promise((resolve) => {
|
|
20370
21028
|
const node = nodesRef.current.find((n) => n.id === nodeId);
|
|
@@ -20396,26 +21054,82 @@ var SystemCanvas = (() => {
|
|
|
20396
21054
|
navigateToBreadcrumbRef.current(0);
|
|
20397
21055
|
}
|
|
20398
21056
|
}), [forwardedRef]);
|
|
20399
|
-
const [
|
|
20400
|
-
const [
|
|
20401
|
-
const [
|
|
20402
|
-
const
|
|
20403
|
-
(0,
|
|
20404
|
-
|
|
21057
|
+
const [editingId, setEditingId] = (0, import_react24.useState)(null);
|
|
21058
|
+
const [selectedEdgeId, setSelectedEdgeId] = (0, import_react24.useState)(null);
|
|
21059
|
+
const [editingEdgeId, setEditingEdgeId] = (0, import_react24.useState)(null);
|
|
21060
|
+
const svgProxyRef = (0, import_react24.useRef)(null);
|
|
21061
|
+
const containerRef = (0, import_react24.useRef)(null);
|
|
21062
|
+
const { selectedIds, selectNode, toggleNode, selectAll, clearSelection, marqueeRect, marqueeActiveRef } = useMultiSelect({
|
|
21063
|
+
svgRef: svgProxyRef,
|
|
21064
|
+
viewport: viewportStateRef,
|
|
21065
|
+
nodesRef,
|
|
21066
|
+
containerRef,
|
|
21067
|
+
enabled: editable
|
|
21068
|
+
});
|
|
21069
|
+
const selectedIdsRef = (0, import_react24.useRef)(selectedIds);
|
|
21070
|
+
(0, import_react24.useEffect)(() => {
|
|
21071
|
+
selectedIdsRef.current = selectedIds;
|
|
21072
|
+
}, [selectedIds]);
|
|
21073
|
+
const edgesRef = (0, import_react24.useRef)(edges);
|
|
21074
|
+
(0, import_react24.useEffect)(() => {
|
|
21075
|
+
edgesRef.current = edges;
|
|
21076
|
+
}, [edges]);
|
|
21077
|
+
const { wrappedOnNodeAdd, wrappedOnNodeUpdate, wrappedOnNodesUpdate, wrappedOnNodeDelete, wrappedOnNodesDelete, wrappedOnEdgeAdd, wrappedOnEdgeUpdate, wrappedOnEdgeDelete, beginBatch, endBatch, undo, redo } = useCommandHistory({
|
|
21078
|
+
nodesRef,
|
|
21079
|
+
edgesRef,
|
|
21080
|
+
onNodeAdd,
|
|
21081
|
+
onNodeUpdate,
|
|
21082
|
+
onNodesUpdate,
|
|
21083
|
+
onNodeDelete,
|
|
21084
|
+
onNodesDelete,
|
|
21085
|
+
onEdgeAdd,
|
|
21086
|
+
onEdgeUpdate,
|
|
21087
|
+
onEdgeDelete,
|
|
21088
|
+
maxDepth: historyDepth ?? 50,
|
|
21089
|
+
enabled: editable,
|
|
21090
|
+
onUndo,
|
|
21091
|
+
onRedo
|
|
21092
|
+
});
|
|
21093
|
+
useMultiSelectClipboard({
|
|
21094
|
+
selectedIdsRef,
|
|
21095
|
+
nodesRef,
|
|
21096
|
+
edgesRef,
|
|
21097
|
+
viewport: viewportStateRef,
|
|
21098
|
+
canvasContainerRef: containerRef,
|
|
21099
|
+
onNodeAdd: (node) => wrappedOnNodeAdd(node, currentCanvasRef),
|
|
21100
|
+
onEdgeAdd: (edge) => wrappedOnEdgeAdd(edge, currentCanvasRef),
|
|
21101
|
+
canvasRef: currentCanvasRef,
|
|
21102
|
+
getCursorScreenPos: () => viewportHandleRef.current?.getCursorScreenPos() ?? null,
|
|
21103
|
+
onBeginBatch: beginBatch,
|
|
21104
|
+
onEndBatch: endBatch
|
|
21105
|
+
});
|
|
21106
|
+
(0, import_react24.useEffect)(() => {
|
|
21107
|
+
clearSelection();
|
|
20405
21108
|
setEditingId(null);
|
|
20406
21109
|
setSelectedEdgeId(null);
|
|
20407
21110
|
setEditingEdgeId(null);
|
|
20408
21111
|
}, [currentCanvasRef]);
|
|
20409
|
-
const onSelectionChangeRef = (0,
|
|
20410
|
-
(0,
|
|
21112
|
+
const onSelectionChangeRef = (0, import_react24.useRef)(onSelectionChange);
|
|
21113
|
+
(0, import_react24.useEffect)(() => {
|
|
20411
21114
|
onSelectionChangeRef.current = onSelectionChange;
|
|
20412
21115
|
}, [onSelectionChange]);
|
|
20413
|
-
const lastEmittedSelectionRef = (0,
|
|
20414
|
-
(0,
|
|
21116
|
+
const lastEmittedSelectionRef = (0, import_react24.useRef)({ kind: null, id: null, multiIds: null, canvasRef: void 0 });
|
|
21117
|
+
(0, import_react24.useEffect)(() => {
|
|
20415
21118
|
const cb = onSelectionChangeRef.current;
|
|
20416
21119
|
let next = null;
|
|
20417
|
-
if (
|
|
20418
|
-
const
|
|
21120
|
+
if (selectedIds.size > 1) {
|
|
21121
|
+
const resolvedNodes = [];
|
|
21122
|
+
for (const id2 of selectedIds) {
|
|
21123
|
+
const n = nodeMap.get(id2);
|
|
21124
|
+
if (n)
|
|
21125
|
+
resolvedNodes.push(n);
|
|
21126
|
+
}
|
|
21127
|
+
if (resolvedNodes.length > 0) {
|
|
21128
|
+
next = { kind: "multi", nodes: resolvedNodes, canvasRef: currentCanvasRef };
|
|
21129
|
+
}
|
|
21130
|
+
} else if (selectedIds.size === 1) {
|
|
21131
|
+
const id2 = Array.from(selectedIds)[0];
|
|
21132
|
+
const node = nodeMap.get(id2);
|
|
20419
21133
|
if (node)
|
|
20420
21134
|
next = { kind: "node", node, canvasRef: currentCanvasRef };
|
|
20421
21135
|
}
|
|
@@ -20426,21 +21140,24 @@ var SystemCanvas = (() => {
|
|
|
20426
21140
|
}
|
|
20427
21141
|
const last = lastEmittedSelectionRef.current;
|
|
20428
21142
|
const nextKind = next?.kind ?? null;
|
|
20429
|
-
const nextId = next ? next.kind === "node" ? next.node.id : next.edge.id : null;
|
|
20430
21143
|
const nextRef = next?.canvasRef;
|
|
20431
|
-
if (
|
|
20432
|
-
|
|
21144
|
+
if (nextKind === "multi" && next?.kind === "multi") {
|
|
21145
|
+
const sortedIds = next.nodes.map((n) => n.id).sort().join(",");
|
|
21146
|
+
if (last.kind === "multi" && last.multiIds === sortedIds && last.canvasRef === nextRef) {
|
|
21147
|
+
return;
|
|
21148
|
+
}
|
|
21149
|
+
lastEmittedSelectionRef.current = { kind: "multi", id: null, multiIds: sortedIds, canvasRef: nextRef };
|
|
21150
|
+
} else {
|
|
21151
|
+
const nextId = next ? next.kind === "node" ? next.node.id : next.kind === "edge" ? next.edge.id : null : null;
|
|
21152
|
+
if (last.kind === nextKind && last.id === nextId && last.canvasRef === nextRef) {
|
|
21153
|
+
return;
|
|
21154
|
+
}
|
|
21155
|
+
lastEmittedSelectionRef.current = { kind: nextKind, id: nextId, multiIds: null, canvasRef: nextRef };
|
|
20433
21156
|
}
|
|
20434
|
-
lastEmittedSelectionRef.current = {
|
|
20435
|
-
kind: nextKind,
|
|
20436
|
-
id: nextId,
|
|
20437
|
-
canvasRef: nextRef
|
|
20438
|
-
};
|
|
20439
21157
|
cb?.(next);
|
|
20440
|
-
}, [
|
|
20441
|
-
const
|
|
20442
|
-
|
|
20443
|
-
(0, import_react21.useEffect)(() => {
|
|
21158
|
+
}, [selectedIds, selectedEdgeId, currentCanvasRef, nodeMap, edges]);
|
|
21159
|
+
const [containerSize, setContainerSize] = (0, import_react24.useState)({ width: 0, height: 0 });
|
|
21160
|
+
(0, import_react24.useEffect)(() => {
|
|
20444
21161
|
const el = containerRef.current;
|
|
20445
21162
|
if (!el)
|
|
20446
21163
|
return;
|
|
@@ -20455,8 +21172,8 @@ var SystemCanvas = (() => {
|
|
|
20455
21172
|
}, []);
|
|
20456
21173
|
const hasLanes = currentCanvas.columns && currentCanvas.columns.length > 0 || currentCanvas.rows && currentCanvas.rows.length > 0;
|
|
20457
21174
|
const showLaneHeaders = hasLanes && laneHeaders !== "none";
|
|
20458
|
-
const getViewportState = (0,
|
|
20459
|
-
const applyLaneSnap = (0,
|
|
21175
|
+
const getViewportState = (0, import_react24.useCallback)(() => viewportStateRef.current ?? { x: 0, y: 0, zoom: 1 }, []);
|
|
21176
|
+
const applyLaneSnap = (0, import_react24.useCallback)((id2, patch) => {
|
|
20460
21177
|
if (!snapToLanes)
|
|
20461
21178
|
return patch;
|
|
20462
21179
|
const cols = currentCanvas.columns;
|
|
@@ -20481,26 +21198,25 @@ var SystemCanvas = (() => {
|
|
|
20481
21198
|
}
|
|
20482
21199
|
return final;
|
|
20483
21200
|
}, [snapToLanes, currentCanvas.columns, currentCanvas.rows]);
|
|
20484
|
-
const commitResize = (0,
|
|
20485
|
-
|
|
20486
|
-
}, [
|
|
20487
|
-
const commitDragBatch = (0,
|
|
21201
|
+
const commitResize = (0, import_react24.useCallback)((id2, patch) => {
|
|
21202
|
+
wrappedOnNodeUpdate(id2, applyLaneSnap(id2, patch), currentCanvasRef);
|
|
21203
|
+
}, [wrappedOnNodeUpdate, currentCanvasRef, applyLaneSnap]);
|
|
21204
|
+
const commitDragBatch = (0, import_react24.useCallback)((updates) => {
|
|
20488
21205
|
const final = updates.map((u) => ({
|
|
20489
21206
|
id: u.id,
|
|
20490
21207
|
patch: applyLaneSnap(u.id, u.patch)
|
|
20491
21208
|
}));
|
|
20492
21209
|
if (onNodesUpdate) {
|
|
20493
|
-
|
|
21210
|
+
wrappedOnNodesUpdate(final, currentCanvasRef);
|
|
20494
21211
|
return;
|
|
20495
21212
|
}
|
|
20496
21213
|
if (!onNodeUpdate)
|
|
20497
21214
|
return;
|
|
20498
21215
|
for (const { id: id2, patch } of final) {
|
|
20499
|
-
|
|
21216
|
+
wrappedOnNodeUpdate(id2, patch, currentCanvasRef);
|
|
20500
21217
|
}
|
|
20501
|
-
}, [onNodeUpdate, onNodesUpdate, currentCanvasRef, applyLaneSnap]);
|
|
20502
|
-
const
|
|
20503
|
-
const handleNodeDrop = (0, import_react21.useCallback)((sources, target) => {
|
|
21218
|
+
}, [wrappedOnNodeUpdate, wrappedOnNodesUpdate, onNodeUpdate, onNodesUpdate, currentCanvasRef, applyLaneSnap]);
|
|
21219
|
+
const handleNodeDrop = (0, import_react24.useCallback)((sources, target) => {
|
|
20504
21220
|
onNodeDrop?.(sources, target, { canvasRef: currentCanvasRef });
|
|
20505
21221
|
}, [onNodeDrop, currentCanvasRef]);
|
|
20506
21222
|
const { dragOverrides, dropTargetId, onPointerDown: onNodePointerDown } = useNodeDrag({
|
|
@@ -20509,39 +21225,41 @@ var SystemCanvas = (() => {
|
|
|
20509
21225
|
onCommit: commitDragBatch,
|
|
20510
21226
|
svgRef: svgProxyRef,
|
|
20511
21227
|
canDropNodeOn,
|
|
20512
|
-
onNodeDrop: handleNodeDrop
|
|
21228
|
+
onNodeDrop: handleNodeDrop,
|
|
21229
|
+
selectedIdsRef
|
|
20513
21230
|
});
|
|
20514
21231
|
const { resizeOverrides, onHandlePointerDown: onResizeHandlePointerDown } = useNodeResize({
|
|
20515
21232
|
viewport: viewportStateRef,
|
|
20516
21233
|
onCommit: commitResize
|
|
20517
21234
|
});
|
|
20518
|
-
const
|
|
20519
|
-
|
|
21235
|
+
const singleSelectedId = selectedIds.size === 1 ? Array.from(selectedIds)[0] : null;
|
|
21236
|
+
const selectedResolvedNode = (0, import_react24.useMemo)(() => {
|
|
21237
|
+
if (!singleSelectedId)
|
|
20520
21238
|
return null;
|
|
20521
|
-
const base = nodeMap.get(
|
|
21239
|
+
const base = nodeMap.get(singleSelectedId);
|
|
20522
21240
|
if (!base)
|
|
20523
21241
|
return null;
|
|
20524
|
-
const resize = resizeOverrides.get(
|
|
21242
|
+
const resize = resizeOverrides.get(singleSelectedId);
|
|
20525
21243
|
if (resize) {
|
|
20526
21244
|
return { ...base, x: resize.x, y: resize.y, width: resize.width, height: resize.height };
|
|
20527
21245
|
}
|
|
20528
|
-
const drag = dragOverrides.get(
|
|
21246
|
+
const drag = dragOverrides.get(singleSelectedId);
|
|
20529
21247
|
if (drag) {
|
|
20530
21248
|
return { ...base, x: drag.x, y: drag.y };
|
|
20531
21249
|
}
|
|
20532
21250
|
return base;
|
|
20533
|
-
}, [
|
|
21251
|
+
}, [singleSelectedId, nodeMap, dragOverrides, resizeOverrides]);
|
|
20534
21252
|
svgProxyRef.current = viewportHandleRef.current?.getSvgElement() ?? null;
|
|
20535
|
-
const handleEdgeCreated = (0,
|
|
20536
|
-
|
|
20537
|
-
}, [
|
|
21253
|
+
const handleEdgeCreated = (0, import_react24.useCallback)((edge) => {
|
|
21254
|
+
wrappedOnEdgeAdd(edge, currentCanvasRef);
|
|
21255
|
+
}, [wrappedOnEdgeAdd, currentCanvasRef]);
|
|
20538
21256
|
const { pending: pendingEdge, onHandlePointerDown: onConnectionHandlePointerDown } = useEdgeCreate({
|
|
20539
21257
|
svgRef: svgProxyRef,
|
|
20540
21258
|
viewport: viewportStateRef,
|
|
20541
21259
|
nodesRef,
|
|
20542
21260
|
onCreate: handleEdgeCreated
|
|
20543
21261
|
});
|
|
20544
|
-
const handleNavigableNodeClick = (0,
|
|
21262
|
+
const handleNavigableNodeClick = (0, import_react24.useCallback)((node) => {
|
|
20545
21263
|
const frame2 = {
|
|
20546
21264
|
parentCanvasRef: currentCanvasRef,
|
|
20547
21265
|
parentNodeRect: {
|
|
@@ -20568,7 +21286,7 @@ var SystemCanvas = (() => {
|
|
|
20568
21286
|
navigateToRef(node);
|
|
20569
21287
|
}
|
|
20570
21288
|
}, [navigateToRef, currentCanvasRef, zoomNavConfig.enabled]);
|
|
20571
|
-
const handleZoomEnter = (0,
|
|
21289
|
+
const handleZoomEnter = (0, import_react24.useCallback)((node, targetTransform) => {
|
|
20572
21290
|
const frame2 = {
|
|
20573
21291
|
parentCanvasRef: currentCanvasRef,
|
|
20574
21292
|
parentNodeRect: {
|
|
@@ -20582,7 +21300,7 @@ var SystemCanvas = (() => {
|
|
|
20582
21300
|
setPendingHandoff(targetTransform);
|
|
20583
21301
|
navigateToRef(node);
|
|
20584
21302
|
}, [currentCanvasRef, navigateToRef]);
|
|
20585
|
-
const handleZoomExit = (0,
|
|
21303
|
+
const handleZoomExit = (0, import_react24.useCallback)((targetTransform) => {
|
|
20586
21304
|
setPendingHandoff(targetTransform);
|
|
20587
21305
|
suppressNextHandoffClearRef.current = true;
|
|
20588
21306
|
navigateToBreadcrumb(breadcrumbs.length - 2);
|
|
@@ -20609,26 +21327,26 @@ var SystemCanvas = (() => {
|
|
|
20609
21327
|
onEnter: handleZoomEnter,
|
|
20610
21328
|
onExit: handleZoomExit
|
|
20611
21329
|
});
|
|
20612
|
-
const handleViewportChange = (0,
|
|
21330
|
+
const handleViewportChange = (0, import_react24.useCallback)((vp) => {
|
|
20613
21331
|
viewportStateRef.current = vp;
|
|
20614
21332
|
handleZoomNavViewportChange(vp);
|
|
20615
21333
|
onViewportChange?.(vp);
|
|
20616
21334
|
}, [handleZoomNavViewportChange, onViewportChange]);
|
|
20617
|
-
const handleHandoffApplied = (0,
|
|
21335
|
+
const handleHandoffApplied = (0, import_react24.useCallback)(() => {
|
|
20618
21336
|
setPendingHandoff(null);
|
|
20619
21337
|
clearZoomNavCommitting();
|
|
20620
21338
|
}, [clearZoomNavCommitting]);
|
|
20621
|
-
const handleBeginEdit = (0,
|
|
21339
|
+
const handleBeginEdit = (0, import_react24.useCallback)((node) => {
|
|
20622
21340
|
setEditingId(node.id);
|
|
20623
21341
|
}, []);
|
|
20624
|
-
const handleBeginEditEdge = (0,
|
|
21342
|
+
const handleBeginEditEdge = (0, import_react24.useCallback)((edge) => {
|
|
20625
21343
|
setEditingEdgeId(edge.id);
|
|
20626
21344
|
}, []);
|
|
20627
|
-
const [contextMenuState, setContextMenuState] = (0,
|
|
20628
|
-
(0,
|
|
21345
|
+
const [contextMenuState, setContextMenuState] = (0, import_react24.useState)(null);
|
|
21346
|
+
(0, import_react24.useEffect)(() => {
|
|
20629
21347
|
setContextMenuState(null);
|
|
20630
21348
|
}, [currentCanvasRef]);
|
|
20631
|
-
const handleContextMenu = (0,
|
|
21349
|
+
const handleContextMenu = (0, import_react24.useCallback)((event) => {
|
|
20632
21350
|
onContextMenu?.(event);
|
|
20633
21351
|
if (!nodeContextMenu)
|
|
20634
21352
|
return;
|
|
@@ -20660,32 +21378,38 @@ var SystemCanvas = (() => {
|
|
|
20660
21378
|
onNavigableNodeClick: handleNavigableNodeClick,
|
|
20661
21379
|
viewport: viewportStateRef,
|
|
20662
21380
|
editable,
|
|
20663
|
-
onSelect:
|
|
21381
|
+
onSelect: (id2) => {
|
|
21382
|
+
if (id2)
|
|
21383
|
+
selectNode(id2);
|
|
21384
|
+
else
|
|
21385
|
+
clearSelection();
|
|
21386
|
+
},
|
|
21387
|
+
onToggleSelect: toggleNode,
|
|
20664
21388
|
onBeginEdit: handleBeginEdit,
|
|
20665
21389
|
onSelectEdge: setSelectedEdgeId,
|
|
20666
21390
|
onBeginEditEdge: handleBeginEditEdge
|
|
20667
21391
|
});
|
|
20668
|
-
const handleEditorCommit = (0,
|
|
21392
|
+
const handleEditorCommit = (0, import_react24.useCallback)((patch) => {
|
|
20669
21393
|
if (editingId) {
|
|
20670
|
-
|
|
21394
|
+
wrappedOnNodeUpdate(editingId, patch, currentCanvasRef);
|
|
20671
21395
|
}
|
|
20672
21396
|
setEditingId(null);
|
|
20673
|
-
}, [editingId,
|
|
20674
|
-
const handleEditorCancel = (0,
|
|
21397
|
+
}, [editingId, wrappedOnNodeUpdate, currentCanvasRef]);
|
|
21398
|
+
const handleEditorCancel = (0, import_react24.useCallback)(() => {
|
|
20675
21399
|
setEditingId(null);
|
|
20676
21400
|
}, []);
|
|
20677
|
-
const handleEdgeEditorCommit = (0,
|
|
21401
|
+
const handleEdgeEditorCommit = (0, import_react24.useCallback)((patch) => {
|
|
20678
21402
|
if (editingEdgeId) {
|
|
20679
|
-
|
|
21403
|
+
wrappedOnEdgeUpdate(editingEdgeId, patch, currentCanvasRef);
|
|
20680
21404
|
}
|
|
20681
21405
|
setEditingEdgeId(null);
|
|
20682
|
-
}, [editingEdgeId,
|
|
20683
|
-
const handleEdgeEditorCancel = (0,
|
|
21406
|
+
}, [editingEdgeId, wrappedOnEdgeUpdate, currentCanvasRef]);
|
|
21407
|
+
const handleEdgeEditorCancel = (0, import_react24.useCallback)(() => {
|
|
20684
21408
|
setEditingEdgeId(null);
|
|
20685
21409
|
}, []);
|
|
20686
|
-
const lastAddRef = (0,
|
|
20687
|
-
const menuOptions = (0,
|
|
20688
|
-
const addNode2 = (0,
|
|
21410
|
+
const lastAddRef = (0, import_react24.useRef)(null);
|
|
21411
|
+
const menuOptions = (0, import_react24.useMemo)(() => getNodeMenuOptions(currentCanvas, theme), [currentCanvas, theme]);
|
|
21412
|
+
const addNode2 = (0, import_react24.useCallback)((option, position) => {
|
|
20689
21413
|
let x, y;
|
|
20690
21414
|
if (position) {
|
|
20691
21415
|
x = position.x;
|
|
@@ -20715,28 +21439,48 @@ var SystemCanvas = (() => {
|
|
|
20715
21439
|
lastAddRef.current = { t: now2, offset: nextOffset };
|
|
20716
21440
|
}
|
|
20717
21441
|
const node = createNodeFromOption(option, Math.round(x), Math.round(y), void 0, theme);
|
|
20718
|
-
|
|
20719
|
-
}, [
|
|
20720
|
-
const handleKeyDown = (0,
|
|
21442
|
+
wrappedOnNodeAdd(node, currentCanvasRef);
|
|
21443
|
+
}, [wrappedOnNodeAdd, currentCanvasRef, theme]);
|
|
21444
|
+
const handleKeyDown = (0, import_react24.useCallback)((e) => {
|
|
20721
21445
|
if (!editable)
|
|
20722
21446
|
return;
|
|
20723
21447
|
if (e.key === "Escape") {
|
|
20724
21448
|
setEditingId(null);
|
|
20725
|
-
|
|
21449
|
+
clearSelection();
|
|
20726
21450
|
setEditingEdgeId(null);
|
|
20727
21451
|
setSelectedEdgeId(null);
|
|
20728
21452
|
return;
|
|
20729
21453
|
}
|
|
20730
21454
|
if (editingId || editingEdgeId)
|
|
20731
21455
|
return;
|
|
21456
|
+
if ((e.metaKey || e.ctrlKey) && !e.shiftKey && e.key === "z") {
|
|
21457
|
+
e.preventDefault();
|
|
21458
|
+
undo();
|
|
21459
|
+
return;
|
|
21460
|
+
}
|
|
21461
|
+
if ((e.metaKey || e.ctrlKey) && e.shiftKey && e.key === "z") {
|
|
21462
|
+
e.preventDefault();
|
|
21463
|
+
redo();
|
|
21464
|
+
return;
|
|
21465
|
+
}
|
|
21466
|
+
if ((e.metaKey || e.ctrlKey) && e.key === "a") {
|
|
21467
|
+
e.preventDefault();
|
|
21468
|
+
selectAll();
|
|
21469
|
+
return;
|
|
21470
|
+
}
|
|
20732
21471
|
if (e.key === "Delete" || e.key === "Backspace") {
|
|
20733
|
-
if (
|
|
21472
|
+
if (selectedIds.size > 1) {
|
|
21473
|
+
e.preventDefault();
|
|
21474
|
+
wrappedOnNodesDelete(Array.from(selectedIds), currentCanvasRef);
|
|
21475
|
+
clearSelection();
|
|
21476
|
+
} else if (selectedIds.size === 1) {
|
|
21477
|
+
const id2 = Array.from(selectedIds)[0];
|
|
20734
21478
|
e.preventDefault();
|
|
20735
|
-
|
|
20736
|
-
|
|
21479
|
+
wrappedOnNodeDelete(id2, currentCanvasRef);
|
|
21480
|
+
clearSelection();
|
|
20737
21481
|
} else if (selectedEdgeId) {
|
|
20738
21482
|
e.preventDefault();
|
|
20739
|
-
|
|
21483
|
+
wrappedOnEdgeDelete(selectedEdgeId, currentCanvasRef);
|
|
20740
21484
|
setSelectedEdgeId(null);
|
|
20741
21485
|
}
|
|
20742
21486
|
}
|
|
@@ -20744,11 +21488,16 @@ var SystemCanvas = (() => {
|
|
|
20744
21488
|
editable,
|
|
20745
21489
|
editingId,
|
|
20746
21490
|
editingEdgeId,
|
|
20747
|
-
|
|
21491
|
+
selectedIds,
|
|
20748
21492
|
selectedEdgeId,
|
|
20749
|
-
|
|
20750
|
-
|
|
20751
|
-
|
|
21493
|
+
wrappedOnNodeDelete,
|
|
21494
|
+
wrappedOnNodesDelete,
|
|
21495
|
+
wrappedOnEdgeDelete,
|
|
21496
|
+
currentCanvasRef,
|
|
21497
|
+
clearSelection,
|
|
21498
|
+
selectAll,
|
|
21499
|
+
undo,
|
|
21500
|
+
redo
|
|
20752
21501
|
]);
|
|
20753
21502
|
const renderProps = { options: menuOptions, addNode: addNode2, theme };
|
|
20754
21503
|
return (0, import_jsx_runtime28.jsxs)("div", { ref: containerRef, className: `system-canvas ${className ?? ""}`, tabIndex: editable ? 0 : -1, onKeyDown: handleKeyDown, style: {
|
|
@@ -20770,20 +21519,28 @@ var SystemCanvas = (() => {
|
|
|
20770
21519
|
fontFamily: theme.node.fontFamily,
|
|
20771
21520
|
fontSize: 12,
|
|
20772
21521
|
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,
|
|
20774
|
-
|
|
21522
|
+
}, 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) => {
|
|
21523
|
+
wrappedOnNodeUpdate(selectedResolvedNode.id, update, currentCanvasRef);
|
|
20775
21524
|
}, onDelete: () => {
|
|
20776
|
-
|
|
20777
|
-
|
|
20778
|
-
}, getViewport: getViewportState, containerWidth: containerSize.width, containerHeight: containerSize.height, render: renderNodeToolbar }), editable &&
|
|
21525
|
+
wrappedOnNodeDelete(selectedResolvedNode.id, currentCanvasRef);
|
|
21526
|
+
clearSelection();
|
|
21527
|
+
}, getViewport: getViewportState, containerWidth: containerSize.width, containerHeight: containerSize.height, render: renderNodeToolbar }), editable && showNodeToolbar && selectedIds.size > 1 && !editingId && (() => {
|
|
21528
|
+
const selectedResolvedNodes = Array.from(selectedIds).map((id2) => nodeMap.get(id2)).filter((n) => n != null);
|
|
21529
|
+
if (selectedResolvedNodes.length === 0)
|
|
21530
|
+
return null;
|
|
21531
|
+
const anchorNode = selectedResolvedNodes[0];
|
|
21532
|
+
return (0, import_jsx_runtime28.jsx)(NodeToolbar, { node: anchorNode, selectedNodes: selectedResolvedNodes, theme, onPatch: () => {
|
|
21533
|
+
}, onMultiPatch: (patch) => {
|
|
21534
|
+
for (const id2 of selectedIds) {
|
|
21535
|
+
wrappedOnNodeUpdate(id2, patch, currentCanvasRef);
|
|
21536
|
+
}
|
|
21537
|
+
}, onDelete: () => {
|
|
21538
|
+
wrappedOnNodesDelete(Array.from(selectedIds), currentCanvasRef);
|
|
21539
|
+
clearSelection();
|
|
21540
|
+
}, getViewport: getViewportState, containerWidth: containerSize.width, containerHeight: containerSize.height });
|
|
21541
|
+
})(), 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
21542
|
});
|
|
20780
21543
|
|
|
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
21544
|
// src/index.tsx
|
|
20788
21545
|
function resolveThemeOption(theme) {
|
|
20789
21546
|
if (typeof theme === "string") {
|
|
@@ -20892,7 +21649,7 @@ var SystemCanvas = (() => {
|
|
|
20892
21649
|
onEdgeUpdate: handleEdgeUpdate,
|
|
20893
21650
|
onEdgeDelete: handleEdgeDelete
|
|
20894
21651
|
};
|
|
20895
|
-
root2.render(
|
|
21652
|
+
root2.render(import_react25.default.createElement(SystemCanvas, props));
|
|
20896
21653
|
};
|
|
20897
21654
|
doRender();
|
|
20898
21655
|
return {
|