system-canvas-standalone 0.2.36 → 0.2.37

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.
@@ -15107,6 +15107,9 @@ var SystemCanvas = (() => {
15107
15107
  }
15108
15108
  if (editingId || editingEdgeId)
15109
15109
  return;
15110
+ const tag = e.target?.tagName;
15111
+ if (tag === "INPUT" || tag === "TEXTAREA")
15112
+ return;
15110
15113
  if ((meta || ctrl) && !shift && key === "z") {
15111
15114
  e.preventDefault();
15112
15115
  undo();
@@ -20214,7 +20217,7 @@ var SystemCanvas = (() => {
20214
20217
  }
20215
20218
 
20216
20219
  // ../react/dist/components/NodeRenderer.js
20217
- function NodeRenderer({ nodes, theme, onClick, onDoubleClick, onContextMenu, onNavigate, onPointerDown, selectedIds, editingId, onResizeHandlePointerDown, canvases, only, dimmedNodeIds, highlightedNodeIds }) {
20220
+ function NodeRenderer({ nodes, theme, onClick, onDoubleClick, onContextMenu, onNavigate, onPointerDown, selectedIds, editingId, onResizeHandlePointerDown, canvases, only, dimmedNodeIds, highlightedNodeIds, activeMatchNodeId }) {
20218
20221
  const groups = nodes.filter((n) => n.type === "group");
20219
20222
  const others = nodes.filter((n) => n.type !== "group");
20220
20223
  const common = (node) => {
@@ -20248,12 +20251,14 @@ var SystemCanvas = (() => {
20248
20251
  return (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [only !== "non-groups" && groups.map((node) => {
20249
20252
  const isDimmed = dimmedNodeIds?.has(node.id) ?? false;
20250
20253
  const isHighlighted = highlightedNodeIds?.has(node.id) ?? false;
20251
- return (0, import_jsx_runtime15.jsxs)("g", { opacity: isDimmed ? 0.15 : 1, children: [isHighlighted && (0, import_jsx_runtime15.jsx)("rect", { x: node.x - 4, y: node.y - 4, width: node.width + 8, height: node.height + 8, rx: 6, fill: "none", stroke: theme.node.labelColor, strokeWidth: 2, opacity: 0.6, pointerEvents: "none" }), (0, import_jsx_runtime15.jsx)(GroupNode, { ...common(node) })] }, node.id);
20254
+ const isActiveMatch = node.id === activeMatchNodeId;
20255
+ return (0, import_jsx_runtime15.jsxs)("g", { opacity: isDimmed ? 0.15 : 1, children: [isHighlighted && (0, import_jsx_runtime15.jsx)("rect", { x: node.x - 4, y: node.y - 4, width: node.width + 8, height: node.height + 8, rx: 6, fill: "none", stroke: theme.node.labelColor, strokeWidth: isActiveMatch ? 3.5 : 2, opacity: isActiveMatch ? 1 : 0.6, pointerEvents: "none" }), (0, import_jsx_runtime15.jsx)(GroupNode, { ...common(node) })] }, node.id);
20252
20256
  }), only !== "groups" && others.map((node) => {
20253
20257
  const Component = getNodeComponent(node.type);
20254
20258
  const isDimmed = dimmedNodeIds?.has(node.id) ?? false;
20255
20259
  const isHighlighted = highlightedNodeIds?.has(node.id) ?? false;
20256
- return (0, import_jsx_runtime15.jsxs)("g", { opacity: isDimmed ? 0.15 : 1, children: [isHighlighted && (0, import_jsx_runtime15.jsx)("rect", { x: node.x - 4, y: node.y - 4, width: node.width + 8, height: node.height + 8, rx: 6, fill: "none", stroke: theme.node.labelColor, strokeWidth: 2, opacity: 0.6, pointerEvents: "none" }), (0, import_jsx_runtime15.jsx)(Component, { ...common(node) })] }, node.id);
20260
+ const isActiveMatch = node.id === activeMatchNodeId;
20261
+ return (0, import_jsx_runtime15.jsxs)("g", { opacity: isDimmed ? 0.15 : 1, children: [isHighlighted && (0, import_jsx_runtime15.jsx)("rect", { x: node.x - 4, y: node.y - 4, width: node.width + 8, height: node.height + 8, rx: 6, fill: "none", stroke: theme.node.labelColor, strokeWidth: isActiveMatch ? 3.5 : 2, opacity: isActiveMatch ? 1 : 0.6, pointerEvents: "none" }), (0, import_jsx_runtime15.jsx)(Component, { ...common(node) })] }, node.id);
20257
20262
  }), renderResizeHandles && (0, import_jsx_runtime15.jsx)(ResizeHandles, { node: selectedNode, theme, onHandlePointerDown: onResizeHandlePointerDown }), renderResizeHandles && (() => {
20258
20263
  const slots = getCategorySlots(selectedNode, theme);
20259
20264
  if (!slots?.topRightOuter)
@@ -21156,7 +21161,7 @@ var SystemCanvas = (() => {
21156
21161
  // ../react/dist/components/Viewport.js
21157
21162
  var HOVER_PADDING = 10;
21158
21163
  var EDGE_PROXIMITY = 16;
21159
- var Viewport = (0, import_react22.forwardRef)(function Viewport2({ nodes, edges, nodeMap, theme, edgeStyle, columns, rows, canvases, minZoom, maxZoom, defaultViewport, panMode, 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, onEdgeWaypointUpdate, pendingEdge, onConnectionHandlePointerDown, edgeCreateEnabled, alignmentGuides, dimmedNodeIds, highlightedNodeIds, viewportState, autoFit = "canvas-change", canvasRef, handoffTransform, onHandoffApplied, handoffFadeMs = 0 }, ref) {
21164
+ var Viewport = (0, import_react22.forwardRef)(function Viewport2({ nodes, edges, nodeMap, theme, edgeStyle, columns, rows, canvases, minZoom, maxZoom, defaultViewport, panMode, 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, onEdgeWaypointUpdate, pendingEdge, onConnectionHandlePointerDown, edgeCreateEnabled, alignmentGuides, dimmedNodeIds, highlightedNodeIds, activeMatchNodeId, viewportState, autoFit = "canvas-change", canvasRef, handoffTransform, onHandoffApplied, handoffFadeMs = 0 }, ref) {
21160
21165
  const { svgRef, groupRef, viewport, fitToContent, zoomToNode, setTransform } = useViewport({
21161
21166
  minZoom,
21162
21167
  maxZoom,
@@ -21399,7 +21404,7 @@ var SystemCanvas = (() => {
21399
21404
  WebkitUserSelect: "none",
21400
21405
  MozUserSelect: "none",
21401
21406
  msUserSelect: "none"
21402
- }, onClick: onCanvasClick, onContextMenu: onCanvasContextMenu, onPointerMove: handleSvgPointerMove, onPointerLeave: handleSvgPointerLeave, children: [(0, import_jsx_runtime24.jsx)("defs", { children: (0, import_jsx_runtime24.jsx)("pattern", { id: "system-canvas-grid", width: theme.grid.size, height: theme.grid.size, patternUnits: "userSpaceOnUse", children: (0, import_jsx_runtime24.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_runtime24.jsx)("rect", { x: "-50000", y: "-50000", width: "100000", height: "100000", fill: "url(#system-canvas-grid)" }), (0, import_jsx_runtime24.jsxs)("g", { ref: groupRef, children: [(0, import_jsx_runtime24.jsx)(LanesBackground, { columns, rows, theme }), (0, import_jsx_runtime24.jsx)(NodeRenderer, { nodes: visibleNodes, theme, onClick: onNodeClick, onDoubleClick: onNodeDoubleClick, onContextMenu: onNodeContextMenu, onNavigate: onNodeNavigate, onPointerDown: onNodePointerDown, selectedIds, editingId, canvases, only: "groups", dimmedNodeIds, highlightedNodeIds }), (0, import_jsx_runtime24.jsx)(EdgeRenderer, { edges, nodeMap: renderNodeMap, theme, defaultEdgeStyle: edgeStyle, onClick: onEdgeClick, onDoubleClick: onEdgeDoubleClick, onContextMenu: onEdgeContextMenu, selectedId: selectedEdgeId, editingId: editingEdgeId, dimmedNodeIds, parallelGroups, editable: !!onNodePointerDown, onWaypointCommit: onEdgeWaypointUpdate ? (id2, wps) => onEdgeWaypointUpdate(id2, { waypoints: wps }) : void 0, viewportRef: viewport }), (0, import_jsx_runtime24.jsx)(NodeRenderer, { nodes: visibleNodes, theme, onClick: onNodeClick, onDoubleClick: onNodeDoubleClick, onContextMenu: onNodeContextMenu, onNavigate: onNodeNavigate, onPointerDown: onNodePointerDown, selectedIds, editingId, onResizeHandlePointerDown, canvases, only: "non-groups", dimmedNodeIds, highlightedNodeIds }), (0, import_jsx_runtime24.jsx)(RevealsLayer, { nodes: visibleNodes, theme, canvases, getViewport }), pendingTargetNode && (0, import_jsx_runtime24.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_runtime24.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) => {
21407
+ }, onClick: onCanvasClick, onContextMenu: onCanvasContextMenu, onPointerMove: handleSvgPointerMove, onPointerLeave: handleSvgPointerLeave, children: [(0, import_jsx_runtime24.jsx)("defs", { children: (0, import_jsx_runtime24.jsx)("pattern", { id: "system-canvas-grid", width: theme.grid.size, height: theme.grid.size, patternUnits: "userSpaceOnUse", children: (0, import_jsx_runtime24.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_runtime24.jsx)("rect", { x: "-50000", y: "-50000", width: "100000", height: "100000", fill: "url(#system-canvas-grid)" }), (0, import_jsx_runtime24.jsxs)("g", { ref: groupRef, children: [(0, import_jsx_runtime24.jsx)(LanesBackground, { columns, rows, theme }), (0, import_jsx_runtime24.jsx)(NodeRenderer, { nodes: visibleNodes, theme, onClick: onNodeClick, onDoubleClick: onNodeDoubleClick, onContextMenu: onNodeContextMenu, onNavigate: onNodeNavigate, onPointerDown: onNodePointerDown, selectedIds, editingId, canvases, only: "groups", dimmedNodeIds, highlightedNodeIds, activeMatchNodeId }), (0, import_jsx_runtime24.jsx)(EdgeRenderer, { edges, nodeMap: renderNodeMap, theme, defaultEdgeStyle: edgeStyle, onClick: onEdgeClick, onDoubleClick: onEdgeDoubleClick, onContextMenu: onEdgeContextMenu, selectedId: selectedEdgeId, editingId: editingEdgeId, dimmedNodeIds, parallelGroups, editable: !!onNodePointerDown, onWaypointCommit: onEdgeWaypointUpdate ? (id2, wps) => onEdgeWaypointUpdate(id2, { waypoints: wps }) : void 0, viewportRef: viewport }), (0, import_jsx_runtime24.jsx)(NodeRenderer, { nodes: visibleNodes, theme, onClick: onNodeClick, onDoubleClick: onNodeDoubleClick, onContextMenu: onNodeContextMenu, onNavigate: onNodeNavigate, onPointerDown: onNodePointerDown, selectedIds, editingId, onResizeHandlePointerDown, canvases, only: "non-groups", dimmedNodeIds, highlightedNodeIds, activeMatchNodeId }), (0, import_jsx_runtime24.jsx)(RevealsLayer, { nodes: visibleNodes, theme, canvases, getViewport }), pendingTargetNode && (0, import_jsx_runtime24.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_runtime24.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) => {
21403
21408
  const node = renderNodeMap.get(id2);
21404
21409
  if (!node)
21405
21410
  return null;
@@ -22247,7 +22252,7 @@ var SystemCanvas = (() => {
22247
22252
  // ../react/dist/components/SearchOverlay.js
22248
22253
  var import_jsx_runtime31 = __toESM(require_jsx_runtime(), 1);
22249
22254
  var import_react30 = __toESM(require_react(), 1);
22250
- function SearchOverlay({ open, query, onQueryChange, theme, hiddenCategories, onToggleCategory, matchCount, totalCount, onClose, onPanToMatch }) {
22255
+ function SearchOverlay({ open, query, onQueryChange, theme, hiddenCategories, onToggleCategory, matchCount, matchIndex, onNext, onPrev, onClose }) {
22251
22256
  const inputRef = (0, import_react30.useRef)(null);
22252
22257
  (0, import_react30.useEffect)(() => {
22253
22258
  if (open) {
@@ -22265,9 +22270,12 @@ var SystemCanvas = (() => {
22265
22270
  if (e.key === "Escape") {
22266
22271
  e.preventDefault();
22267
22272
  onClose();
22268
- } else if (e.key === "Enter") {
22273
+ } else if (e.key === "Enter" || e.key === "ArrowDown") {
22274
+ e.preventDefault();
22275
+ onNext();
22276
+ } else if (e.key === "ArrowUp") {
22269
22277
  e.preventDefault();
22270
- onPanToMatch();
22278
+ onPrev();
22271
22279
  }
22272
22280
  };
22273
22281
  return (0, import_jsx_runtime31.jsxs)("div", { style: {
@@ -22301,14 +22309,41 @@ var SystemCanvas = (() => {
22301
22309
  fontSize: 13,
22302
22310
  width: 160,
22303
22311
  caretColor: textColor
22304
- } }), query.length > 0 && (0, import_jsx_runtime31.jsxs)("span", { style: {
22312
+ } }), query.length > 0 && matchCount > 0 && (0, import_jsx_runtime31.jsxs)(import_jsx_runtime31.Fragment, { children: [(0, import_jsx_runtime31.jsx)("button", { onClick: onPrev, style: {
22313
+ background: "transparent",
22314
+ border: "none",
22315
+ cursor: "pointer",
22316
+ padding: "2px 3px",
22317
+ display: "flex",
22318
+ alignItems: "center",
22319
+ color: textColor,
22320
+ opacity: 0.7,
22321
+ flexShrink: 0
22322
+ }, title: "Previous match (\u2191)", children: (0, import_jsx_runtime31.jsx)("svg", { width: 10, height: 10, viewBox: "0 0 10 10", fill: "none", stroke: "currentColor", strokeWidth: 1.5, children: (0, import_jsx_runtime31.jsx)("polyline", { points: "2,7 5,3 8,7" }) }) }), (0, import_jsx_runtime31.jsxs)("span", { style: {
22305
22323
  fontSize: 11,
22306
22324
  fontFamily,
22307
22325
  color: textColor,
22308
22326
  opacity: 0.7,
22309
22327
  whiteSpace: "nowrap",
22310
22328
  flexShrink: 0
22311
- }, children: [matchCount, " of ", totalCount] }), (0, import_jsx_runtime31.jsx)("button", { onClick: onClose, style: {
22329
+ }, children: [matchIndex + 1, "/", matchCount] }), (0, import_jsx_runtime31.jsx)("button", { onClick: onNext, style: {
22330
+ background: "transparent",
22331
+ border: "none",
22332
+ cursor: "pointer",
22333
+ padding: "2px 3px",
22334
+ display: "flex",
22335
+ alignItems: "center",
22336
+ color: textColor,
22337
+ opacity: 0.7,
22338
+ flexShrink: 0
22339
+ }, title: "Next match (\u2193)", children: (0, import_jsx_runtime31.jsx)("svg", { width: 10, height: 10, viewBox: "0 0 10 10", fill: "none", stroke: "currentColor", strokeWidth: 1.5, children: (0, import_jsx_runtime31.jsx)("polyline", { points: "2,3 5,7 8,3" }) }) })] }), query.length > 0 && matchCount === 0 && (0, import_jsx_runtime31.jsx)("span", { style: {
22340
+ fontSize: 11,
22341
+ fontFamily,
22342
+ color: textColor,
22343
+ opacity: 0.5,
22344
+ whiteSpace: "nowrap",
22345
+ flexShrink: 0
22346
+ }, children: "No matches" }), (0, import_jsx_runtime31.jsx)("button", { onClick: onClose, style: {
22312
22347
  background: "transparent",
22313
22348
  border: "none",
22314
22349
  cursor: "pointer",
@@ -22861,6 +22896,7 @@ var SystemCanvas = (() => {
22861
22896
  const [searchOpen, setSearchOpen] = (0, import_react33.useState)(false);
22862
22897
  const [searchQuery, setSearchQuery] = (0, import_react33.useState)("");
22863
22898
  const [hiddenCategories, setHiddenCategories] = (0, import_react33.useState)(/* @__PURE__ */ new Set());
22899
+ const [searchIndex, setSearchIndex] = (0, import_react33.useState)(0);
22864
22900
  const [importError, setImportError] = (0, import_react33.useState)(null);
22865
22901
  const svgProxyRef = (0, import_react33.useRef)(null);
22866
22902
  const containerRef = (0, import_react33.useRef)(null);
@@ -22921,13 +22957,7 @@ var SystemCanvas = (() => {
22921
22957
  const onKey = (e) => {
22922
22958
  if ((e.metaKey || e.ctrlKey) && e.key === "f") {
22923
22959
  e.preventDefault();
22924
- setSearchOpen((prev) => {
22925
- if (prev) {
22926
- setSearchQuery("");
22927
- setHiddenCategories(/* @__PURE__ */ new Set());
22928
- }
22929
- return !prev;
22930
- });
22960
+ setSearchOpen((prev) => !prev);
22931
22961
  }
22932
22962
  };
22933
22963
  window.addEventListener("keydown", onKey);
@@ -23012,11 +23042,16 @@ var SystemCanvas = (() => {
23012
23042
  const showLaneHeaders = hasLanes && laneHeaders !== "none";
23013
23043
  const getViewportState = (0, import_react33.useCallback)(() => viewportStateRef.current ?? { x: 0, y: 0, zoom: 1 }, []);
23014
23044
  const { matchingIds, dimmedIds } = (0, import_react33.useMemo)(() => computeNodeFilter(nodes, searchOpen ? searchQuery : "", hiddenCategories), [nodes, searchQuery, searchOpen, hiddenCategories]);
23015
- const panToFirstMatch = (0, import_react33.useCallback)(() => {
23016
- if (matchingIds.size === 0)
23045
+ const matchingIdsArray = (0, import_react33.useMemo)(() => Array.from(matchingIds), [matchingIds]);
23046
+ const activeMatchId = matchingIdsArray[searchIndex];
23047
+ (0, import_react33.useEffect)(() => {
23048
+ setSearchIndex(0);
23049
+ }, [matchingIds]);
23050
+ const panToMatch = (0, import_react33.useCallback)((index) => {
23051
+ const id2 = matchingIdsArray[index];
23052
+ if (!id2)
23017
23053
  return;
23018
- const firstId = matchingIds.values().next().value;
23019
- const node = nodesRef.current.find((n) => n.id === firstId);
23054
+ const node = nodesRef.current.find((n) => n.id === id2);
23020
23055
  const handle = viewportHandleRef.current;
23021
23056
  if (!node || !handle)
23022
23057
  return;
@@ -23025,7 +23060,21 @@ var SystemCanvas = (() => {
23025
23060
  targetZoom: Math.max(currentZoom, 1.5),
23026
23061
  durationMs: 400
23027
23062
  });
23028
- }, [matchingIds]);
23063
+ }, [matchingIdsArray]);
23064
+ const goNextMatch = (0, import_react33.useCallback)(() => {
23065
+ if (matchingIdsArray.length === 0)
23066
+ return;
23067
+ const next = (searchIndex + 1) % matchingIdsArray.length;
23068
+ setSearchIndex(next);
23069
+ panToMatch(next);
23070
+ }, [matchingIdsArray, searchIndex, panToMatch]);
23071
+ const goPrevMatch = (0, import_react33.useCallback)(() => {
23072
+ if (matchingIdsArray.length === 0)
23073
+ return;
23074
+ const prev = (searchIndex - 1 + matchingIdsArray.length) % matchingIdsArray.length;
23075
+ setSearchIndex(prev);
23076
+ panToMatch(prev);
23077
+ }, [matchingIdsArray, searchIndex, panToMatch]);
23029
23078
  const applyLaneSnap = (0, import_react33.useCallback)((id2, patch) => {
23030
23079
  if (!snapToLanes)
23031
23080
  return patch;
@@ -23563,7 +23612,7 @@ var SystemCanvas = (() => {
23563
23612
  fontFamily: theme.node.fontFamily,
23564
23613
  fontSize: 12,
23565
23614
  backdropFilter: "blur(8px)"
23566
- }, children: "Loading..." }), (0, import_jsx_runtime34.jsx)(Viewport, { ref: viewportHandleRef, nodes, edges, nodeMap, theme, edgeStyle, columns: currentCanvas.columns, rows: currentCanvas.rows, canvases, minZoom: effectiveMinZoom, maxZoom: effectiveMaxZoom, defaultViewport, panMode, 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, onEdgeWaypointUpdate: editable ? handleEdgeWaypointUpdate : void 0, pendingEdge: editable ? pendingEdge : null, onConnectionHandlePointerDown: editable ? onConnectionHandlePointerDown : void 0, edgeCreateEnabled: editable, alignmentGuides: editable ? alignmentGuides : void 0, dimmedNodeIds: dimmedIds, highlightedNodeIds: matchingIds, viewportState: collaboratorViewport }), collaborators.length > 0 || flashNodeIds.size > 0 ? (0, import_jsx_runtime34.jsx)(CollaboratorsOverlay, { collaborators, viewport: collaboratorViewport, nodeMap, flashNodeIds }) : null, showLaneHeaders && (0, import_jsx_runtime34.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_runtime34.jsx)(NodeToolbar, { node: selectedResolvedNode, theme, onPatch: (update) => {
23615
+ }, children: "Loading..." }), (0, import_jsx_runtime34.jsx)(Viewport, { ref: viewportHandleRef, nodes, edges, nodeMap, theme, edgeStyle, columns: currentCanvas.columns, rows: currentCanvas.rows, canvases, minZoom: effectiveMinZoom, maxZoom: effectiveMaxZoom, defaultViewport, panMode, 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, onEdgeWaypointUpdate: editable ? handleEdgeWaypointUpdate : void 0, pendingEdge: editable ? pendingEdge : null, onConnectionHandlePointerDown: editable ? onConnectionHandlePointerDown : void 0, edgeCreateEnabled: editable, alignmentGuides: editable ? alignmentGuides : void 0, dimmedNodeIds: dimmedIds, highlightedNodeIds: matchingIds, activeMatchNodeId: activeMatchId, viewportState: collaboratorViewport }), collaborators.length > 0 || flashNodeIds.size > 0 ? (0, import_jsx_runtime34.jsx)(CollaboratorsOverlay, { collaborators, viewport: collaboratorViewport, nodeMap, flashNodeIds }) : null, showLaneHeaders && (0, import_jsx_runtime34.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_runtime34.jsx)(NodeToolbar, { node: selectedResolvedNode, theme, onPatch: (update) => {
23567
23616
  wrappedOnNodeUpdate(selectedResolvedNode.id, update, currentCanvasRef);
23568
23617
  }, onDelete: () => {
23569
23618
  wrappedOnNodeDelete(selectedResolvedNode.id, currentCanvasRef);
@@ -23595,11 +23644,7 @@ var SystemCanvas = (() => {
23595
23644
  const next = new Set(prev);
23596
23645
  next.has(cat) ? next.delete(cat) : next.add(cat);
23597
23646
  return next;
23598
- }), matchCount: matchingIds.size, totalCount: nodes.length, onClose: () => {
23599
- setSearchOpen(false);
23600
- setSearchQuery("");
23601
- setHiddenCategories(/* @__PURE__ */ new Set());
23602
- }, onPanToMatch: panToFirstMatch })] });
23647
+ }), matchCount: matchingIds.size, matchIndex: searchIndex, onNext: goNextMatch, onPrev: goPrevMatch, onClose: () => setSearchOpen(false) })] });
23603
23648
  });
23604
23649
 
23605
23650
  // src/index.tsx