@dschz/solid-flow 0.3.0-next.2 → 0.3.0-next.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.
@@ -1,13 +1,22 @@
1
1
  import { Dynamic, Portal, addEvent, claimElement, className, createComponent, delegateEvents, effect, insert, isServer, memo, mergeProps, ref, setAttribute, setStyleProperty, spread, style, template } from "@solidjs/web";
2
- import { ConnectionLineType, ConnectionMode, MarkerType, PanOnScrollMode, Position, Position as Position$1, ResizeControlVariant, SelectionMode, SelectionMode as SelectionMode$1, XYDrag, XYHandle, XYMinimap, XYPanZoom, XYResizer, XY_RESIZER_HANDLE_POSITIONS, XY_RESIZER_LINE_POSITIONS, addEdge, addEdge as addEdge$1, areConnectionMapsEqual, calcAutoPan, calculateNodePosition, clampPosition, clampPositionToParent, createDevWarn, createMarkerIds, elementSelectionKeys, evaluateAbsolutePosition, fitViewport, getBezierEdgeCenter, getBezierPath, getBezierPath as getBezierPath$1, getBoundsOfRects, getConnectedEdges, getConnectionStatus, getDimensions, getEdgeCenter, getEdgePosition, getEdgeToolbarTransform, getElementsToRemove, getElevatedEdgeZIndex, getEventPosition, getHandleBounds, getHostForElement, getIncomers, getInternalNodesBounds, getMarkerId, getNodeDimensions, getNodePositionWithOrigin, getNodeToolbarTransform, getNodesBounds, getNodesBounds as getNodesBounds$1, getNodesInside, getOutgoers, getOverlappingArea, getSmoothStepPath, getSmoothStepPath as getSmoothStepPath$1, getStraightPath, getStraightPath as getStraightPath$1, getViewportForBounds, getViewportForBounds as getViewportForBounds$1, handleConnectionChange, infiniteExtent, initialConnection, isCoordinateExtent, isEdgeBase, isInputDOMNode, isMacOs, isNodeBase, isNumeric, isRectObject, mergeAriaLabelConfig, nodeHasDimensions, nodeToRect, panBy, pointToRendererPoint, rendererPointToPoint, shallowNodeData, snapPosition } from "@xyflow/system";
2
+ import { ConnectionLineType, ConnectionMode, MarkerType, PanOnScrollMode, Position, Position as Position$1, ResizeControlVariant, SelectionMode as SelectionMode$1, XYDrag, XYHandle, XYMinimap, XYPanZoom, XYResizer, XY_RESIZER_HANDLE_POSITIONS, XY_RESIZER_LINE_POSITIONS, addEdge, addEdge as addEdge$1, areConnectionMapsEqual, calcAutoPan, calculateNodePosition, clampPosition, clampPositionToParent, createDevWarn, createMarkerIds, elementSelectionKeys, evaluateAbsolutePosition, fitViewport, getBezierEdgeCenter as getBezierEdgeCenter$1, getBezierPath, getBezierPath as getBezierPath$1, getBoundsOfRects, getConnectedEdges, getConnectionStatus, getDimensions, getEdgeCenter as getEdgeCenter$1, getEdgePosition, getEdgeToolbarTransform, getElementsToRemove, getElevatedEdgeZIndex, getEventPosition, getHandleBounds, getHostForElement, getIncomers, getInternalNodesBounds, getMarkerId, getNodeDimensions, getNodePositionWithOrigin, getNodeToolbarTransform, getNodesBounds, getNodesBounds as getNodesBounds$1, getNodesInside, getOutgoers, getOverlappingArea, getSmoothStepPath, getSmoothStepPath as getSmoothStepPath$1, getStraightPath, getStraightPath as getStraightPath$1, getViewportForBounds, getViewportForBounds as getViewportForBounds$1, handleConnectionChange, infiniteExtent, initialConnection, isCoordinateExtent, isEdgeBase, isInputDOMNode, isMacOs, isNodeBase, isNumeric, isRectObject, mergeAriaLabelConfig, nodeHasDimensions, nodeToRect, panBy, pointToRendererPoint, rendererPointToPoint, shallowNodeData, snapPosition } from "@xyflow/system";
3
3
  import { For, Show, createContext, createEffect, createMemo, createProjection, createSignal, createStore, flush, mapArray, merge, omit, onCleanup, onSettled, snapshot, untrack, useContext } from "solid-js";
4
4
  import { createMediaQuery } from "@solid-primitives/media";
5
5
  import { createEventListener, createEventListenerMap } from "@solid-primitives/event-listener";
6
6
  //#region src/contexts/edgeId.ts
7
7
  const EdgeIdContext = createContext(null);
8
+ /**
9
+ * Returns the id of the edge this component is rendered inside. Available
10
+ * anywhere in a custom edge's subtree (provided by the edge wrapper), so
11
+ * nested components — like a custom edge label — can learn their host edge
12
+ * without prop drilling.
13
+ *
14
+ * @public
15
+ * @returns a reactive accessor for the surrounding edge's id
16
+ */
8
17
  function useEdgeId() {
9
18
  let ctx = useContext(EdgeIdContext);
10
- if (!ctx) throw Error("solid-flow: Your application must be wrapped with <SolidFlow> in order to invoke useEdgeId");
19
+ if (!ctx) throw Error("solid-flow: useEdgeId must be called inside an edge component (anywhere under a custom edge's subtree)");
11
20
  return ctx;
12
21
  }
13
22
  //#endregion
@@ -75,6 +84,7 @@ const getEdgeId = (connection) => {
75
84
  //#endregion
76
85
  //#region src/components/edge/EdgeLabel.tsx
77
86
  var _tmpl$$34 = /* @__PURE__ */ template("<div>");
87
+ /** Renders an edge label positioned in graph coordinates. */
78
88
  const EdgeLabel = (props) => {
79
89
  let _props = propDefaults(props, {
80
90
  x: 0,
@@ -115,6 +125,7 @@ const EdgeLabel = (props) => {
115
125
  //#endregion
116
126
  //#region src/components/edge/BaseEdge.tsx
117
127
  var _tmpl$$33 = /* @__PURE__ */ template("<svg><path></svg>", 2), _tmpl$2$4 = /* @__PURE__ */ template("<svg><path stroke-opacity=0 fill=none class=solid-flow__edge-interaction></svg>", 2);
128
+ /** Lowest-level edge primitive: renders the SVG path, label, and interaction width. */
118
129
  const BaseEdge = (props) => {
119
130
  let _props = propDefaults(props, { interactionWidth: 20 }), rest = omit(_props, "class", "style", "path", "interactionWidth", "label", "labelStyle", "labelX", "labelY", "markerStart", "markerEnd");
120
131
  return [
@@ -273,16 +284,19 @@ const BaseEdge = (props) => {
273
284
  //#endregion
274
285
  //#region src/components/edge/EdgeReconnectAnchor.tsx
275
286
  var _tmpl$$32 = /* @__PURE__ */ template("<div style=background:transparent;border:none;cursor:move>");
287
+ /** Grab area that lets an edge end be dragged off its handle and reconnected. */
276
288
  const EdgeReconnectAnchor = (props) => {
277
289
  let _props = propDefaults(props, {
278
290
  size: 25,
279
291
  reconnecting: !1,
280
292
  style: {}
281
- }), rest = omit(_props, "type", "class", "style", "position", "size", "reconnecting", "children"), { store, nodeLookup, edgeLookup, actions } = useInternalSolidFlow(), edgeId = useEdgeId(), [reconnecting, setReconnecting] = createSignal(!1);
293
+ }), rest = omit(_props, "type", "class", "style", "position", "size", "reconnecting", "onReconnectingChange", "children"), { store, nodeLookup, edgeLookup, actions } = useInternalSolidFlow(), edgeId = useEdgeId(), [reconnecting, setReconnecting] = createSignal(!1);
282
294
  if (!edgeId()) throw Error("[solid-flow]: EdgeReconnectAnchor must be used within an Edge component");
283
- let edge = () => edgeLookup[edgeId()], onPointerDown = (event) => {
295
+ let edge = () => edgeLookup[edgeId()], isReconnecting = () => _props.reconnecting || reconnecting(), setReconnectingState = (next) => {
296
+ setReconnecting(next), _props.onReconnectingChange?.(next);
297
+ }, onPointerDown = (event) => {
284
298
  if (event.button !== 0) return;
285
- setReconnecting(!0), store.onReconnectStart?.(event, edge(), _props.type);
299
+ setReconnectingState(!0), store.onReconnectStart?.(event, edge(), _props.type);
286
300
  let opposite = _props.type === "target" ? {
287
301
  nodeId: edge().source,
288
302
  handleId: edge().sourceHandle ?? null,
@@ -306,7 +320,9 @@ const EdgeReconnectAnchor = (props) => {
306
320
  edgeUpdaterType: opposite.type,
307
321
  cancelConnection: actions.cancelConnection,
308
322
  panBy: actions.panBy,
309
- updateConnection: actions.setConnection,
323
+ updateConnection: (connection) => {
324
+ actions.setConnection(connection), flush();
325
+ },
310
326
  isValidConnection: store.isValidConnection,
311
327
  onConnectStart: store.onConnectStart,
312
328
  onConnectEnd: store.onConnectEnd,
@@ -318,7 +334,7 @@ const EdgeReconnectAnchor = (props) => {
318
334
  newEdge = store.onBeforeReconnect?.(newEdge, edge()) ?? newEdge, newEdge && actions.setEdges((edges) => edges.map((e) => e.id === edge().id ? newEdge : e)), store.onReconnect?.(edge(), connection);
319
335
  },
320
336
  onReconnectEnd: (event, connectionState) => {
321
- setReconnecting(!1), store.onReconnectEnd?.(event, edge(), opposite.type, connectionState);
337
+ setReconnectingState(!1), store.onReconnectEnd?.(event, edge(), opposite.type, connectionState);
322
338
  },
323
339
  getTransform: () => store.transform,
324
340
  getFromHandle: () => store.connection.fromHandle,
@@ -341,7 +357,7 @@ const EdgeReconnectAnchor = (props) => {
341
357
  var _el$ = _tmpl$$32();
342
358
  return _el$.$$pointerdown = onPointerDown, insert(_el$, createComponent(Show, {
343
359
  get when() {
344
- return !reconnecting();
360
+ return !isReconnecting();
345
361
  },
346
362
  get children() {
347
363
  return _props.children;
@@ -404,7 +420,6 @@ const A11yDescriptions = () => {
404
420
  let [store, setStore] = createStore(edges);
405
421
  return [store, setStore];
406
422
  }, STEP = .5 / 2, rectsEqual = (a, b) => a === b || !!a && !!b && a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height, rectsOverlap = (a, b) => a.x <= b.x + b.width && a.x + a.width >= b.x && a.y <= b.y + b.height && a.y + a.height >= b.y, createCullingViewport = (source) => createMemo(() => {
407
- if (!source.onlyRenderVisibleElements) return null;
408
423
  let { width, height } = source;
409
424
  if (!width || !height) return null;
410
425
  let [tx, ty, zoom] = source.transform, zoomBucket = 2 ** Math.floor(Math.log2(zoom)), bucketWidth = width / zoomBucket, bucketHeight = height / zoomBucket, stepX = bucketWidth * STEP, stepY = bucketHeight * STEP, centerX = (width / 2 - tx) / zoom, centerY = (height / 2 - ty) / zoom, quantizedX = Math.round(centerX / stepX) * stepX, quantizedY = Math.round(centerY / stepY) * stepY, halfWidth = bucketWidth * 1, halfHeight = bucketHeight * 1;
@@ -468,7 +483,7 @@ const A11yDescriptions = () => {
468
483
  selectNodesOnDrag: !0,
469
484
  elevateNodesOnSelect: !0,
470
485
  zIndexMode: "basic",
471
- onlyRenderVisibleElements: !0,
486
+ onlyRenderVisibleElements: !1,
472
487
  disableKeyboardA11y: !1,
473
488
  defaultMarkerColor: "#b1b1b7",
474
489
  ariaLiveMessage: "",
@@ -758,9 +773,17 @@ const createLayoutedEdges = (source) => {
758
773
  return config().zIndexMode;
759
774
  }
760
775
  }), nodeLookup = new RecordMapFacade(internalNodes), initialViewport = getInitialViewport(_props.fitView, _props.initialViewport, _props.width ?? 0, _props.height ?? 0, nodeLookup), [viewportStore, setViewportStore] = createStore(_props.viewport ?? initialViewport);
761
- createEffect(() => config().nodes, (next) => {
776
+ createEffect(() => {
777
+ let next = config().nodes;
778
+ for (let node of next);
779
+ return { next };
780
+ }, ({ next }) => {
762
781
  setNodesStore(() => next);
763
- }, { defer: !0 }), createEffect(() => config().edges, (next) => {
782
+ }, { defer: !0 }), createEffect(() => {
783
+ let next = config().edges;
784
+ for (let edge of next);
785
+ return { next };
786
+ }, ({ next }) => {
764
787
  setEdgesStore(() => next);
765
788
  }, { defer: !0 }), createEffect(() => config().viewport, (next) => {
766
789
  next && setViewportStore(() => next);
@@ -921,9 +944,6 @@ const createLayoutedEdges = (source) => {
921
944
  return zoomActivationKeyPressed();
922
945
  }
923
946
  }), cullingViewport = createCullingViewport({
924
- get onlyRenderVisibleElements() {
925
- return store.onlyRenderVisibleElements;
926
- },
927
947
  get width() {
928
948
  return store.width;
929
949
  },
@@ -1420,6 +1440,7 @@ const createLayoutedEdges = (source) => {
1420
1440
  //#endregion
1421
1441
  //#region src/components/edge/EdgeWrapper.tsx
1422
1442
  var _tmpl$$30 = /* @__PURE__ */ template("<svg class=solid-flow__edge-wrapper><g>");
1443
+ /** Internal per-edge wrapper: interaction, a11y, viewport culling, and the dynamic edge component. */
1423
1444
  const EdgeWrapper = (props) => {
1424
1445
  let edgeRef, { store, actions } = useInternalSolidFlow(), edgeId = () => props.edgeId, edge = () => actions.getEdge(edgeId()), edgeType = () => edge().type ?? "default", selectable = () => edge().selectable ?? store.elementsSelectable, focusable = () => edge().focusable ?? store.edgesFocusable, edgeComponent = () => store.edgeTypes[edgeType()], markerStartUrl = () => edge().markerStart ? `url('#${getMarkerId(edge().markerStart, store.id)}')` : void 0, markerEndUrl = () => edge().markerEnd ? `url('#${getMarkerId(edge().markerEnd, store.id)}')` : void 0, onClick = (event) => {
1425
1446
  selectable() && actions.handleEdgeSelection(edgeId()), props.onEdgeClick?.({
@@ -1854,6 +1875,7 @@ function useNodeConnectable() {
1854
1875
  //#endregion
1855
1876
  //#region src/components/handle/Handle.tsx
1856
1877
  var _tmpl$$29 = /* @__PURE__ */ template("<div>");
1878
+ /** Connection point on a node; place inside custom nodes to make them connectable. */
1857
1879
  const Handle = (props) => {
1858
1880
  let _props = propDefaults(props, {
1859
1881
  type: "source",
@@ -2021,6 +2043,7 @@ const Handle = (props) => {
2021
2043
  //#endregion
2022
2044
  //#region src/components/node/GroupNode.tsx
2023
2045
  var _tmpl$$28 = /* @__PURE__ */ template("<div style=position:absolute;left:0;top:0>");
2046
+ /** Built-in group node: a plain container for child nodes. */
2024
2047
  const GroupNode = (props) => (() => {
2025
2048
  var _el$ = _tmpl$$28();
2026
2049
  return effect(() => ({
@@ -2089,16 +2112,31 @@ const GroupNode = (props) => (() => {
2089
2112
  };
2090
2113
  }), dragging;
2091
2114
  }, NodeIdContext = createContext(null);
2115
+ /**
2116
+ * Returns the id of the node this component is rendered inside. Available
2117
+ * anywhere in a custom node's subtree (provided by the node wrapper), so
2118
+ * nested components — like a custom `Handle` — can learn their host node
2119
+ * without prop drilling.
2120
+ *
2121
+ * @public
2122
+ * @returns a reactive accessor for the surrounding node's id
2123
+ */
2092
2124
  function useNodeId() {
2093
2125
  let ctx = useContext(NodeIdContext);
2094
- if (!ctx) throw Error("solid-flow: Your application must be wrapped with <SolidFlow> in order to invoke useNodeId");
2126
+ if (!ctx) throw Error("solid-flow: useNodeId must be called inside a node component (anywhere under a custom node's subtree)");
2095
2127
  return ctx;
2096
2128
  }
2097
2129
  //#endregion
2098
2130
  //#region src/components/node/NodeWrapper.tsx
2099
2131
  var _tmpl$$27 = /* @__PURE__ */ template("<div>");
2132
+ /** Internal per-node wrapper: dragging, selection, a11y, measurement, viewport culling, and the dynamic node component. */
2100
2133
  const NodeWrapper = (props) => {
2101
- let { store, nodeLookup, parentIds, actions } = useInternalSolidFlow(), [nodeRef, setNodeRef] = createSignal(), node = () => nodeLookup.get(props.nodeId), nodeId = () => node().id, nodeType = () => node().type ?? "default", deletable = () => node().deletable ?? !0, selectable = () => node().selectable ?? store.elementsSelectable, focusable = () => node().focusable ?? store.nodesFocusable, draggable = () => node().draggable ?? store.nodesDraggable, connectable = () => node().connectable ?? store.nodesConnectable, userNode = () => node().internals.userNode, nodeTypeValid = () => nodeType() in store.nodeTypes, nodeComponent = () => store.nodeTypes[nodeType()], isParentNode = () => !!parentIds[node().id], transform = () => {
2134
+ let { store, nodeLookup, parentIds, actions } = useInternalSolidFlow(), [nodeRef, setNodeRef] = createSignal(), node = () => nodeLookup.get(props.nodeId);
2135
+ onCleanup(() => {
2136
+ let el = nodeRef();
2137
+ el && props.resizeObserver?.unobserve(el);
2138
+ });
2139
+ let nodeId = () => node().id, nodeType = () => node().type ?? "default", deletable = () => node().deletable ?? !0, selectable = () => node().selectable ?? store.elementsSelectable, focusable = () => node().focusable ?? store.nodesFocusable, draggable = () => node().draggable ?? store.nodesDraggable, connectable = () => node().connectable ?? store.nodesConnectable, userNode = () => node().internals.userNode, nodeTypeValid = () => nodeType() in store.nodeTypes, nodeComponent = () => store.nodeTypes[nodeType()], isParentNode = () => !!parentIds[node().id], transform = () => {
2102
2140
  let { x, y } = node().internals.positionAbsolute;
2103
2141
  return `translate(${x}px, ${y}px)`;
2104
2142
  }, sizeStyle = () => {
@@ -2494,6 +2532,7 @@ function useInternalSolidFlow() {
2494
2532
  //#endregion
2495
2533
  //#region src/components/connection/ConnectionLine.tsx
2496
2534
  var _tmpl$$26 = /* @__PURE__ */ template("<svg class=\"solid-flow__container solid-flow__connectionline\"><g>"), _tmpl$2$2 = /* @__PURE__ */ template("<svg><path class=solid-flow__connection-path fill=none></svg>", 2);
2535
+ /** Internal component rendering the in-progress connection line. */
2497
2536
  const ConnectionLine = (props) => {
2498
2537
  let { store } = useInternalSolidFlow(), connectionStatus = () => getConnectionStatus(store.connection.isValid);
2499
2538
  return createComponent(Show, {
@@ -2606,6 +2645,7 @@ const ConnectionLine = (props) => {
2606
2645
  //#endregion
2607
2646
  //#region src/components/marker/Marker.tsx
2608
2647
  var _tmpl$$25 = /* @__PURE__ */ template("<svg><polyline class=arrow fill=none stroke-linecap=round stroke-linejoin=round points=\"-5,-4 0,0 -5,4\"></svg>", 2), _tmpl$2$1 = /* @__PURE__ */ template("<svg><marker class=solid-flow__arrowhead viewBox=\"-10 -10 20 20\"refX=0 refY=0></svg>", 2), _tmpl$3$1 = /* @__PURE__ */ template("<svg><polyline class=arrowclosed stroke-linecap=round stroke-linejoin=round points=\"-5,-4 0,0 -5,4 -5,-4\"></svg>", 2);
2648
+ /** Internal SVG `<marker>` definition for one edge marker configuration. */
2609
2649
  const Marker = (props) => {
2610
2650
  let _props = propDefaults(props, {
2611
2651
  markerUnits: "strokeWidth",
@@ -2651,6 +2691,7 @@ const Marker = (props) => {
2651
2691
  //#endregion
2652
2692
  //#region src/components/marker/MarkerDefinition.tsx
2653
2693
  var _tmpl$$24 = /* @__PURE__ */ template("<svg class=solid-flow__marker><defs>");
2694
+ /** Internal collector rendering every unique edge marker into one SVG defs block. */
2654
2695
  const MarkerDefinition = () => {
2655
2696
  let { store } = useInternalSolidFlow(), markers = createMemo(() => createMarkerIds(store.edges, {
2656
2697
  id: store.id,
@@ -2676,35 +2717,55 @@ const MarkerDefinition = () => {
2676
2717
  //#endregion
2677
2718
  //#region src/components/container/EdgeRenderer.tsx
2678
2719
  var _tmpl$$23 = /* @__PURE__ */ template("<div class=solid-flow__edges><!><!>");
2720
+ /** Internal renderer iterating the edge id list into `EdgeWrapper`s. */
2679
2721
  const EdgeRenderer = (props) => {
2680
- let { store } = useInternalSolidFlow();
2722
+ let { store, actions } = useInternalSolidFlow(), [focusedEdgeId, setFocusedEdgeId] = createSignal(null), onFocusIn = (event) => {
2723
+ let edgeElement = event.target.closest("[data-id]");
2724
+ setFocusedEdgeId(edgeElement?.getAttribute("data-id") ?? null);
2725
+ };
2681
2726
  var _el$ = _tmpl$$23(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling;
2682
- return insert(_el$, createComponent(MarkerDefinition, {}), _el$2), insert(_el$, createComponent(For, {
2727
+ return _el$.$$focusout = () => setFocusedEdgeId(null), _el$.$$focusin = onFocusIn, insert(_el$, createComponent(MarkerDefinition, {}), _el$2), insert(_el$, createComponent(For, {
2683
2728
  get each() {
2684
2729
  return store.visibleEdgeIds;
2685
2730
  },
2686
- children: (edgeId) => createComponent(EdgeWrapper, {
2687
- edgeId,
2688
- get onEdgeClick() {
2689
- return props.onEdgeClick;
2690
- },
2691
- get onEdgeContextMenu() {
2692
- return props.onEdgeContextMenu;
2693
- },
2694
- get onEdgePointerEnter() {
2695
- return props.onEdgePointerEnter;
2696
- },
2697
- get onEdgePointerLeave() {
2698
- return props.onEdgePointerLeave;
2699
- }
2700
- })
2731
+ children: (edgeId) => {
2732
+ let unmounted = createMemo(() => {
2733
+ if (!store.onlyRenderVisibleElements || focusedEdgeId() === edgeId) return !1;
2734
+ let edge = actions.getEdge(edgeId);
2735
+ return !!edge && isEdgeCulled(edge, store.cullingViewport);
2736
+ });
2737
+ return createComponent(Show, {
2738
+ get when() {
2739
+ return !unmounted();
2740
+ },
2741
+ get children() {
2742
+ return createComponent(EdgeWrapper, {
2743
+ edgeId,
2744
+ get onEdgeClick() {
2745
+ return props.onEdgeClick;
2746
+ },
2747
+ get onEdgeContextMenu() {
2748
+ return props.onEdgeContextMenu;
2749
+ },
2750
+ get onEdgePointerEnter() {
2751
+ return props.onEdgePointerEnter;
2752
+ },
2753
+ get onEdgePointerLeave() {
2754
+ return props.onEdgePointerLeave;
2755
+ }
2756
+ });
2757
+ }
2758
+ });
2759
+ }
2701
2760
  }), _el$3), _el$;
2702
2761
  };
2762
+ delegateEvents(["focusin", "focusout"]);
2703
2763
  //#endregion
2704
2764
  //#region src/components/container/NodeRenderer.tsx
2705
2765
  var _tmpl$$22 = /* @__PURE__ */ template("<div class=\"solid-flow__container solid-flow__nodes\">");
2766
+ /** Internal renderer iterating the node id list into `NodeWrapper`s; owns the shared measurement `ResizeObserver`. */
2706
2767
  const NodeRenderer = (props) => {
2707
- let { actions, store } = useInternalSolidFlow(), resizeObserver = isServer ? void 0 : new ResizeObserver((entries) => {
2768
+ let { actions, store, nodeLookup } = useInternalSolidFlow(), resizeObserver = isServer ? void 0 : new ResizeObserver((entries) => {
2708
2769
  actions.requestUpdateNodeInternals(entries.map((entry) => {
2709
2770
  let id = entry.target.getAttribute("data-id");
2710
2771
  return [id, {
@@ -2717,44 +2778,63 @@ const NodeRenderer = (props) => {
2717
2778
  onCleanup(() => {
2718
2779
  resizeObserver?.disconnect();
2719
2780
  });
2781
+ let [focusedNodeId, setFocusedNodeId] = createSignal(null), onFocusIn = (event) => {
2782
+ let nodeElement = event.target.closest("[data-id]");
2783
+ setFocusedNodeId(nodeElement?.getAttribute("data-id") ?? null);
2784
+ };
2720
2785
  var _el$ = _tmpl$$22();
2721
- return insert(_el$, createComponent(For, {
2786
+ return _el$.$$focusout = () => setFocusedNodeId(null), _el$.$$focusin = onFocusIn, insert(_el$, createComponent(For, {
2722
2787
  get each() {
2723
2788
  return store.visibleNodeIds;
2724
2789
  },
2725
- children: (nodeId) => createComponent(NodeWrapper, {
2726
- nodeId,
2727
- resizeObserver,
2728
- get nodeClickDistance() {
2729
- return props.nodeClickDistance;
2730
- },
2731
- get onNodeClick() {
2732
- return props.onNodeClick;
2733
- },
2734
- get onNodePointerEnter() {
2735
- return props.onNodePointerEnter;
2736
- },
2737
- get onNodePointerMove() {
2738
- return props.onNodePointerMove;
2739
- },
2740
- get onNodePointerLeave() {
2741
- return props.onNodePointerLeave;
2742
- },
2743
- get onNodeDrag() {
2744
- return props.onNodeDrag;
2745
- },
2746
- get onNodeDragStart() {
2747
- return props.onNodeDragStart;
2748
- },
2749
- get onNodeDragStop() {
2750
- return props.onNodeDragStop;
2751
- },
2752
- get onNodeContextMenu() {
2753
- return props.onNodeContextMenu;
2754
- }
2755
- })
2790
+ children: (nodeId) => {
2791
+ let unmounted = createMemo(() => {
2792
+ if (!store.onlyRenderVisibleElements || focusedNodeId() === nodeId) return !1;
2793
+ let node = nodeLookup.get(nodeId);
2794
+ return !!node && isNodeCulled(node, store.cullingViewport);
2795
+ });
2796
+ return createComponent(Show, {
2797
+ get when() {
2798
+ return !unmounted();
2799
+ },
2800
+ get children() {
2801
+ return createComponent(NodeWrapper, {
2802
+ nodeId,
2803
+ resizeObserver,
2804
+ get nodeClickDistance() {
2805
+ return props.nodeClickDistance;
2806
+ },
2807
+ get onNodeClick() {
2808
+ return props.onNodeClick;
2809
+ },
2810
+ get onNodePointerEnter() {
2811
+ return props.onNodePointerEnter;
2812
+ },
2813
+ get onNodePointerMove() {
2814
+ return props.onNodePointerMove;
2815
+ },
2816
+ get onNodePointerLeave() {
2817
+ return props.onNodePointerLeave;
2818
+ },
2819
+ get onNodeDrag() {
2820
+ return props.onNodeDrag;
2821
+ },
2822
+ get onNodeDragStart() {
2823
+ return props.onNodeDragStart;
2824
+ },
2825
+ get onNodeDragStop() {
2826
+ return props.onNodeDragStop;
2827
+ },
2828
+ get onNodeContextMenu() {
2829
+ return props.onNodeContextMenu;
2830
+ }
2831
+ });
2832
+ }
2833
+ });
2834
+ }
2756
2835
  })), _el$;
2757
2836
  };
2837
+ delegateEvents(["focusin", "focusout"]);
2758
2838
  //#endregion
2759
2839
  //#region src/components/container/Pane.tsx
2760
2840
  var _tmpl$$21 = /* @__PURE__ */ template("<div class=\"solid-flow__container solid-flow__pane\">");
@@ -2907,6 +2987,7 @@ delegateEvents([
2907
2987
  //#endregion
2908
2988
  //#region src/components/container/Panel.tsx
2909
2989
  var _tmpl$$20 = /* @__PURE__ */ template("<div>");
2990
+ /** Positioned overlay container for UI placed above the flow (used by `Controls`, `MiniMap`, attribution). */
2910
2991
  const Panel = (props) => {
2911
2992
  let { store } = useInternalSolidFlow(), _props = propDefaults(props, {
2912
2993
  position: "top-right",
@@ -2957,6 +3038,7 @@ const Viewport = (props) => {
2957
3038
  //#endregion
2958
3039
  //#region src/components/container/Zoom.tsx
2959
3040
  var _tmpl$$18 = /* @__PURE__ */ template("<div class=\"solid-flow__container solid-flow__zoom\">");
3041
+ /** Internal viewport controller wiring pan/zoom gestures (XYPanZoom) to the flow. */
2960
3042
  const Zoom = (props) => {
2961
3043
  let [ref$3, setRef] = createSignal(), { store, actions } = useInternalSolidFlow(), viewPort = () => props.initialViewport || {
2962
3044
  x: 0,
@@ -3021,6 +3103,7 @@ const Zoom = (props) => {
3021
3103
  //#endregion
3022
3104
  //#region src/components/selection/Selection.tsx
3023
3105
  var _tmpl$$17 = /* @__PURE__ */ template("<div class=solid-flow__selection>");
3106
+ /** Internal selection-rectangle visual. */
3024
3107
  const Selection = (props) => {
3025
3108
  let _props = propDefaults(props, { isVisible: !0 }), styles = () => ({
3026
3109
  ..._props.width != null && { width: typeof _props.width == "string" ? _props.width : toPxString(_props.width) },
@@ -3042,6 +3125,7 @@ const Selection = (props) => {
3042
3125
  //#endregion
3043
3126
  //#region src/components/selection/NodeSelection.tsx
3044
3127
  var _tmpl$$16 = /* @__PURE__ */ template("<div>");
3128
+ /** Internal draggable bounding box rendered around multi-selected nodes. */
3045
3129
  const NodeSelection = (props) => {
3046
3130
  let { store, nodeLookup, actions } = useInternalSolidFlow(), [ref$2, setRef] = createSignal(), bounds = () => store.selectionRectMode === "nodes" ? getInternalNodesBounds(nodeLookup, { filter: (node) => !!node.selected }) : null;
3047
3131
  createEffect(() => ({
@@ -3151,25 +3235,14 @@ const Attribution = (props) => createComponent(Show, {
3151
3235
  * `const { flow, commands } = useSolidFlow()`.
3152
3236
  *
3153
3237
  * @public
3154
- * @returns the flow's read struct, write surface, and deprecated aliases
3238
+ * @returns the flow's read struct and write surface
3155
3239
  */
3156
3240
  function useSolidFlow() {
3157
- let { flow, commands, store, edgeLookup } = useInternalSolidFlow(), getInternalNode = (id) => flow.internalNodes[id];
3241
+ let { flow, commands } = useInternalSolidFlow();
3158
3242
  return {
3159
3243
  ...commands,
3160
3244
  flow,
3161
- commands,
3162
- getInternalNode,
3163
- getNode: (id) => getInternalNode(id)?.internals.userNode,
3164
- getNodes: (ids) => ids ? ids.flatMap((id) => {
3165
- let userNode = flow.internalNodes[id]?.internals.userNode;
3166
- return userNode ? [userNode] : [];
3167
- }) : [...flow.nodes],
3168
- getEdge: (id) => edgeLookup[id],
3169
- getEdges: (ids) => ids ? ids.flatMap((id) => edgeLookup[id] ? [edgeLookup[id]] : []) : [...flow.edges],
3170
- getViewport: () => snapshot(store.viewport),
3171
- getZoom: () => flow.viewport.zoom,
3172
- getHandleConnections: ({ type, id, nodeId }) => Object.values(flow.connections[connectionKey(nodeId, type, id ?? null)] ?? {})
3245
+ commands
3173
3246
  };
3174
3247
  }
3175
3248
  //#endregion
@@ -3246,8 +3319,9 @@ const KeyHandler = (props) => {
3246
3319
  }), null;
3247
3320
  };
3248
3321
  //#endregion
3249
- //#region src/components/SolidFlow/component.tsx
3322
+ //#region src/components/SolidFlow.tsx
3250
3323
  var _tmpl$$14 = /* @__PURE__ */ template("<div class=\"solid-flow__container solid-flow__viewport-back\">"), _tmpl$2 = /* @__PURE__ */ template("<div class=\"solid-flow__container solid-flow__edge-labels\">"), _tmpl$3 = /* @__PURE__ */ template("<div>");
3324
+ /** The flow canvas component: renders nodes and edges and wires up viewport and interactions. */
3251
3325
  const SolidFlow = (props) => {
3252
3326
  let [domNodeRef, setDomNodeRef] = createSignal(), domNode, _props = merge({
3253
3327
  ...getDefaultFlowStateProps(),
@@ -3610,18 +3684,6 @@ function useViewport() {
3610
3684
  return () => flow.viewport;
3611
3685
  }
3612
3686
  //#endregion
3613
- //#region src/hooks/useHandleEdgeSelect.ts
3614
- function useHandleEdgeSelect() {
3615
- let { store, edgeLookup, actions } = useInternalSolidFlow();
3616
- return (id) => {
3617
- let edge = edgeLookup[id];
3618
- edge && (edge.selectable || store.elementsSelectable && edge.selectable === void 0) && (actions.setSelectionRect(void 0), actions.setSelectionRectMode(void 0), edge.selected ? edge.selected && store.multiselectionKeyPressed && actions.unselectNodesAndEdges({
3619
- nodes: [],
3620
- edges: [edge]
3621
- }) : actions.addSelectedEdges([id]));
3622
- };
3623
- }
3624
- //#endregion
3625
3687
  //#region src/hooks/useInitialized.ts
3626
3688
  /**
3627
3689
  * Hook for seeing if all nodes have been measured.
@@ -3651,11 +3713,16 @@ function useViewportInitialized() {
3651
3713
  //#endregion
3652
3714
  //#region src/hooks/useInternalNode.ts
3653
3715
  /**
3654
- * Hook to get an internal node by id.
3716
+ * Hook to get an internal node (the node enriched with measured dimensions,
3717
+ * absolute position, and z-order) by id.
3718
+ *
3719
+ * The id is an accessor (not a plain string) on purpose: passing a raw
3720
+ * reactive read like `props.nodeId` would capture the value once and silently
3721
+ * lose reactivity — `useInternalNode(() => props.nodeId)` keeps it live.
3655
3722
  *
3656
3723
  * @public
3657
- * @param id - the node id
3658
- * @returns an accessor with an internal node or undefined
3724
+ * @param id - a reactive accessor for the node id
3725
+ * @returns an accessor with the internal node, or undefined while absent
3659
3726
  */
3660
3727
  function useInternalNode(id) {
3661
3728
  let { flow } = useInternalSolidFlow();
@@ -3766,7 +3833,6 @@ const DEFAULT_SIZE = {
3766
3833
  let _props = propDefaults(props, {
3767
3834
  variant: "dots",
3768
3835
  gap: 20,
3769
- size: 1,
3770
3836
  lineWidth: 1,
3771
3837
  style: {}
3772
3838
  }), { store } = useInternalSolidFlow(), isDots = () => _props.variant === "dots", isCross = () => _props.variant === "cross", patternId = () => `background-pattern-${store.id}-${_props.id ?? ""}`, scaledSize = () => (_props.size ?? DEFAULT_SIZE[_props.variant]) * store.viewport.zoom, gapXY = () => Array.isArray(_props.gap) ? _props.gap : [_props.gap, _props.gap], scaledGap = () => [gapXY()[0] * store.viewport.zoom || 1, gapXY()[1] * store.viewport.zoom || 1], patternDimensions = () => isCross() ? [scaledSize(), scaledSize()] : scaledGap(), patternOffset = () => isDots() ? [scaledSize() / 2, scaledSize() / 2] : [patternDimensions()[0] / 2, patternDimensions()[1] / 2];
@@ -3822,6 +3888,7 @@ const DEFAULT_SIZE = {
3822
3888
  //#endregion
3823
3889
  //#region src/plugins/controls/ControlButton.tsx
3824
3890
  var _tmpl$$10 = /* @__PURE__ */ template("<button>");
3891
+ /** A styled button for use inside `Controls`. */
3825
3892
  const ControlButton = (props) => {
3826
3893
  let rest = omit(props, "class", "bgColor", "bgColorHover", "color", "colorHover", "borderColor", "onClick", "children"), style = () => Object.entries({
3827
3894
  "--xy-controls-button-background-color-props": props.bgColor,
@@ -3997,18 +4064,19 @@ const Unlock = () => _tmpl$$5(), Controls = (props) => {
3997
4064
  //#endregion
3998
4065
  //#region src/plugins/minimap/MiniMapNode.tsx
3999
4066
  var _tmpl$$4 = /* @__PURE__ */ template("<svg><rect></svg>", 2);
4067
+ /** The default minimap node: a rounded rect. Custom `nodeComponent`s can wrap it. */
4000
4068
  const MiniMapNode = (props) => {
4001
4069
  let _props = propDefaults(props, {
4002
4070
  borderRadius: 5,
4003
4071
  width: 0,
4004
4072
  height: 0
4005
- }), style$1 = () => Object.entries({
4006
- fill: _props.color,
4073
+ }), fill = () => _props.color ?? _props.style?.background ?? _props.style?.["background-color"], style$1 = () => Object.entries({
4074
+ fill: fill(),
4007
4075
  stroke: _props.strokeColor,
4008
4076
  "stroke-width": _props.strokeWidth
4009
4077
  }).filter(([_, value]) => value !== void 0).reduce((acc, [key, value]) => (acc[key] = value, acc), {});
4010
4078
  var _el$ = _tmpl$$4();
4011
- return effect(() => ({
4079
+ return addEvent(_el$, "click", _props.onClick ? (event) => _props.onClick(event, _props.id) : void 0, !0), effect(() => ({
4012
4080
  e: [
4013
4081
  "solid-flow__minimap-node",
4014
4082
  { selected: !!_props.selected },
@@ -4026,6 +4094,7 @@ const MiniMapNode = (props) => {
4026
4094
  className(_el$, e, _p$?.e), t !== _p$?.t && setAttribute(_el$, "x", t), a !== _p$?.a && setAttribute(_el$, "y", a), o !== _p$?.o && setAttribute(_el$, "rx", o), i !== _p$?.i && setAttribute(_el$, "ry", i), n !== _p$?.n && setAttribute(_el$, "width", n), s !== _p$?.s && setAttribute(_el$, "height", s), h !== _p$?.h && setAttribute(_el$, "shape-rendering", h), style(_el$, r, _p$?.r);
4027
4095
  }), _el$;
4028
4096
  };
4097
+ delegateEvents(["click"]);
4029
4098
  //#endregion
4030
4099
  //#region src/plugins/minimap/MiniMap.tsx
4031
4100
  var _tmpl$$3 = /* @__PURE__ */ template("<svg class=solid-flow__minimap-svg role=img><title></title><path class=solid-flow__minimap-mask fill-rule=evenodd pointer-events=none>");
@@ -4041,7 +4110,7 @@ const getAttrFunction = (func) => func instanceof Function ? func : () => func,
4041
4110
  nodeBorderRadius: 5,
4042
4111
  nodeStrokeWidth: 2,
4043
4112
  style: {}
4044
- }), paneProps = omit(_props, "class", "style", "position", "nodeClass", "nodeStrokeColor", "nodeColor", "pannable", "zoomable", "inversePan", "zoomStep", "bgColor", "width", "height", "maskColor", "maskStrokeColor", "maskStrokeWidth", "nodeBorderRadius", "nodeStrokeWidth"), nodeColorFunc = () => _props.nodeColor === void 0 ? void 0 : getAttrFunction(_props.nodeColor), nodeStrokeColorFunc = () => getAttrFunction(_props.nodeStrokeColor), nodeClassFunc = () => getAttrFunction(_props.nodeClass), shapeRendering = () => typeof window > "u" || window.chrome ? "crispEdges" : "geometricPrecision", labelledBy = createMemo(() => `solid-flow__minimap-desc-${store.id}`), getViewBB = () => ({
4113
+ }), paneProps = omit(_props, "class", "style", "position", "nodeClass", "nodeStrokeColor", "nodeColor", "pannable", "zoomable", "inversePan", "zoomStep", "bgColor", "width", "height", "maskColor", "maskStrokeColor", "maskStrokeWidth", "nodeBorderRadius", "nodeStrokeWidth", "nodeComponent", "onClick", "onNodeClick"), nodeColorFunc = () => _props.nodeColor === void 0 ? void 0 : getAttrFunction(_props.nodeColor), nodeStrokeColorFunc = () => getAttrFunction(_props.nodeStrokeColor), nodeClassFunc = () => getAttrFunction(_props.nodeClass), shapeRendering = () => typeof window > "u" || window.chrome ? "crispEdges" : "geometricPrecision", labelledBy = createMemo(() => `solid-flow__minimap-desc-${store.id}`), getViewBB = () => ({
4045
4114
  x: -store.viewport.x / store.viewport.zoom,
4046
4115
  y: -store.viewport.y / store.viewport.zoom,
4047
4116
  width: store.width / store.viewport.zoom,
@@ -4108,8 +4177,19 @@ const getAttrFunction = (func) => func instanceof Function ? func : () => func,
4108
4177
  }), ({ instance, options }) => {
4109
4178
  instance?.update(options);
4110
4179
  });
4180
+ let onSvgClick = (event) => {
4181
+ if (!_props.onClick) return;
4182
+ let [x, y] = minimap()?.pointer(event) ?? [0, 0];
4183
+ _props.onClick(event, {
4184
+ x,
4185
+ y
4186
+ });
4187
+ }, onSvgNodeClick = (event, nodeId) => {
4188
+ let node = nodeLookup.get(nodeId)?.internals.userNode;
4189
+ node && _props.onNodeClick?.(event, node);
4190
+ };
4111
4191
  var _el$ = _tmpl$$3(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling;
4112
- return ref(() => setRef, _el$), insert(_el$2, () => store.ariaLabelConfig["minimap.ariaLabel"]), insert(_el$, createComponent(For, {
4192
+ return addEvent(_el$, "click", _props.onClick ? onSvgClick : void 0, !0), ref(() => setRef, _el$), insert(_el$2, () => store.ariaLabelConfig["minimap.ariaLabel"]), insert(_el$, createComponent(For, {
4113
4193
  keyed: !1,
4114
4194
  get each() {
4115
4195
  return nodeIds();
@@ -4120,7 +4200,13 @@ const getAttrFunction = (func) => func instanceof Function ? func : () => func,
4120
4200
  get when() {
4121
4201
  return memo(() => !!nodeVisible())() ? getNodeDimensions(node()) : nodeVisible();
4122
4202
  },
4123
- children: (nodeDimensions) => createComponent(MiniMapNode, {
4203
+ children: (nodeDimensions) => createComponent(Dynamic, {
4204
+ get component() {
4205
+ return _props.nodeComponent ?? MiniMapNode;
4206
+ },
4207
+ get id() {
4208
+ return nodeId();
4209
+ },
4124
4210
  get x() {
4125
4211
  return node().internals.positionAbsolute.x;
4126
4212
  },
@@ -4153,6 +4239,12 @@ const getAttrFunction = (func) => func instanceof Function ? func : () => func,
4153
4239
  },
4154
4240
  get class() {
4155
4241
  return nodeClassFunc().call(null, node());
4242
+ },
4243
+ get style() {
4244
+ return node().style;
4245
+ },
4246
+ get onClick() {
4247
+ return _props.onNodeClick ? onSvgNodeClick : void 0;
4156
4248
  }
4157
4249
  })
4158
4250
  });
@@ -4175,9 +4267,11 @@ const getAttrFunction = (func) => func instanceof Function ? func : () => func,
4175
4267
  });
4176
4268
  } }));
4177
4269
  };
4270
+ delegateEvents(["click"]);
4178
4271
  //#endregion
4179
4272
  //#region src/plugins/nodeResizer/ResizeControl.tsx
4180
4273
  var _tmpl$$2 = /* @__PURE__ */ template("<div>");
4274
+ /** A single resize handle or line — the building block of `NodeResizer`. */
4181
4275
  const ResizeControl = (props) => {
4182
4276
  let _props = propDefaults(props, {
4183
4277
  variant: "handle",
@@ -4349,8 +4443,9 @@ const EdgeToolbar = (props) => {
4349
4443
  //#endregion
4350
4444
  //#region src/plugins/toolbar/NodeToolbar.tsx
4351
4445
  var _tmpl$ = /* @__PURE__ */ template("<div>");
4446
+ /** Toolbar attached to a node, rendered above the graph so it does not scale with zoom. */
4352
4447
  const NodeToolbar = (props) => {
4353
- let { store } = useInternalSolidFlow(), { getNodes, getNodesBounds, getInternalNode } = useSolidFlow(), _props = propDefaults(props, {
4448
+ let { store } = useInternalSolidFlow(), { flow, getNodesBounds } = useSolidFlow(), _props = propDefaults(props, {
4354
4449
  offset: 10,
4355
4450
  position: "top",
4356
4451
  align: "center",
@@ -4359,7 +4454,7 @@ const NodeToolbar = (props) => {
4359
4454
  let id = useContext(NodeIdContext);
4360
4455
  return id ? id() : "";
4361
4456
  }, toolbarNodes = () => (Array.isArray(_props.nodeId) ? _props.nodeId : [_props.nodeId ?? ctxNodeId()]).reduce((res, nodeId) => {
4362
- let node = getInternalNode(nodeId);
4457
+ let node = flow.internalNodes[nodeId];
4363
4458
  return node && res.push(node), res;
4364
4459
  }, []), transform = () => {
4365
4460
  let nodeRect = getNodesBounds(toolbarNodes());
@@ -4367,7 +4462,7 @@ const NodeToolbar = (props) => {
4367
4462
  }, zIndex = () => {
4368
4463
  let nodes = toolbarNodes();
4369
4464
  return nodes.length === 0 ? 1 : Math.max(...nodes.map((node) => (node.internals.z || 5) + 1));
4370
- }, selectedNodesCount = () => getNodes().filter((node) => node.selected).length, isActive = () => {
4465
+ }, selectedNodesCount = () => flow.selection.nodes.length, isActive = () => {
4371
4466
  let nodes = toolbarNodes();
4372
4467
  return typeof _props.isVisible == "boolean" ? _props.isVisible : nodes.length === 1 && !!nodes[0].selected && selectedNodesCount() === 1;
4373
4468
  }, showPortal = () => !!(store.domNode && isActive() && toolbarNodes().length > 0);
@@ -4400,6 +4495,6 @@ const NodeToolbar = (props) => {
4400
4495
  });
4401
4496
  }
4402
4497
  });
4403
- };
4498
+ }, SelectionMode = SelectionMode$1, getEdgeCenter = getEdgeCenter$1, getBezierEdgeCenter = getBezierEdgeCenter$1;
4404
4499
  //#endregion
4405
- export { Background, BaseEdge, BezierEdge, BezierEdgeInternal, ConnectionLine, ConnectionLineType, ConnectionMode, ControlButton, Controls, DefaultNode, EdgeLabel, EdgeLabelRenderer, EdgeReconnectAnchor, EdgeRenderer, EdgeToolbar, EdgeWrapper, GroupNode, Handle, InputNode, Marker, MarkerDefinition, MarkerType, MiniMap, NodeRenderer, NodeResizer, NodeSelection, NodeToolbar, NodeWrapper, OutputNode, PanOnScrollMode, Pane, Panel, Position, ResizeControl, ResizeControlVariant, Selection, SelectionMode, SmoothStepEdge, SmoothStepEdgeInternal, SolidFlow, SolidFlowProvider, StepEdge, StepEdgeInternal, StraightEdge, StraightEdgeInternal, Viewport, ViewportPortal, Zoom, addEdge, connectionKey, createEdgeStore, createNodeStore, getBezierEdgeCenter, getBezierPath, getConnectedEdges, getEdgeCenter, getIncomers, getNodesBounds, getOutgoers, getSmoothStepPath, getStraightPath, getViewportForBounds, useColorMode, useConnection, useEdges, useHandleEdgeSelect, useInternalNode, useNodeConnections, useNodes, useNodesData, useNodesInitialized, useSolidFlow, useUpdateNodeInternals, useViewport, useViewportInitialized };
4500
+ export { Background, BaseEdge, BezierEdge, BezierEdgeInternal, ConnectionLine, ConnectionLineType, ConnectionMode, ControlButton, Controls, DefaultNode, EdgeLabel, EdgeLabelRenderer, EdgeReconnectAnchor, EdgeRenderer, EdgeToolbar, EdgeWrapper, GroupNode, Handle, InputNode, Marker, MarkerDefinition, MarkerType, MiniMap, MiniMapNode, NodeRenderer, NodeResizer, NodeSelection, NodeToolbar, NodeWrapper, OutputNode, PanOnScrollMode, Pane, Panel, Position, ResizeControl, ResizeControlVariant, Selection, SelectionMode, SmoothStepEdge, SmoothStepEdgeInternal, SolidFlow, SolidFlowProvider, StepEdge, StepEdgeInternal, StraightEdge, StraightEdgeInternal, Viewport, ViewportPortal, Zoom, addEdge, connectionKey, createEdgeStore, createNodeStore, getBezierEdgeCenter, getBezierPath, getConnectedEdges, getEdgeCenter, getIncomers, getNodesBounds, getOutgoers, getSmoothStepPath, getStraightPath, getViewportForBounds, useColorMode, useConnection, useEdgeId, useEdges, useInternalNode, useNodeConnections, useNodeId, useNodes, useNodesData, useNodesInitialized, useSolidFlow, useUpdateNodeInternals, useViewport, useViewportInitialized };