@likec4/diagram 1.3.0 → 1.4.0

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.
Files changed (44) hide show
  1. package/dist/LikeC4Diagram.d.ts +1 -1
  2. package/dist/LikeC4Diagram.props.d.ts +6 -1
  3. package/dist/index.mjs +270 -168
  4. package/dist/state/DiagramContext.d.ts +155 -154
  5. package/dist/state/diagramStore.d.ts +154 -154
  6. package/dist/state/index.d.ts +0 -1
  7. package/dist/state/useDiagramStore.d.ts +3 -4622
  8. package/dist/state/useNavigationHistory.d.ts +5 -0
  9. package/dist/style.css +86 -54
  10. package/dist/theme.css.d.ts +5 -0
  11. package/dist/ui/BackwardForwardPanel.css.d.ts +1 -0
  12. package/dist/ui/BackwardForwardPanel.d.ts +1 -0
  13. package/dist/ui/DiagramTitlePanel.css.d.ts +1 -1
  14. package/dist/ui/OptionsPanel.d.ts +1 -3
  15. package/dist/xyflow/XYFlowEvents.d.ts +4 -4
  16. package/dist/xyflow/XYFlowInner.d.ts +1 -0
  17. package/dist/xyflow/edges/RelationshipEdge.d.ts +1 -1
  18. package/dist/xyflow/hooks/useXYFlow.d.ts +9 -9
  19. package/dist/xyflow/nodes/element/element.css.d.ts +1 -0
  20. package/dist/xyflow/types.d.ts +1 -1
  21. package/package.json +10 -10
  22. package/src/LikeC4Diagram.css.ts +11 -1
  23. package/src/LikeC4Diagram.props.ts +10 -3
  24. package/src/LikeC4Diagram.tsx +30 -7
  25. package/src/globals.css.ts +1 -1
  26. package/src/state/DiagramContext.tsx +3 -3
  27. package/src/state/diagramStore.ts +27 -30
  28. package/src/state/index.ts +0 -1
  29. package/src/state/useDiagramStore.ts +6 -13
  30. package/src/state/useNavigationHistory.ts +39 -0
  31. package/src/theme.css.ts +5 -0
  32. package/src/ui/BackwardForwardPanel.css.ts +22 -0
  33. package/src/ui/BackwardForwardPanel.tsx +59 -0
  34. package/src/ui/DiagramTitlePanel.css.ts +11 -5
  35. package/src/ui/DiagramTitlePanel.tsx +105 -93
  36. package/src/ui/OptionsPanel.tsx +28 -19
  37. package/src/xyflow/XYFlowInner.tsx +5 -2
  38. package/src/xyflow/diagram-to-xyflow.ts +2 -13
  39. package/src/xyflow/edges/RelationshipEdge.tsx +11 -8
  40. package/src/xyflow/edges/edges.css.ts +14 -10
  41. package/src/xyflow/hooks/useLayoutConstraints.ts +2 -1
  42. package/src/xyflow/nodes/compound/CompoundNode.css.ts +8 -8
  43. package/src/xyflow/nodes/element/ElementNode.tsx +7 -8
  44. package/src/xyflow/nodes/element/element.css.ts +18 -5
package/dist/index.mjs CHANGED
@@ -9,15 +9,15 @@ import { createPortal } from "react-dom";
9
9
  import { DEV } from "esm-env";
10
10
  import { shallowEqual, deepEqual } from "fast-equals";
11
11
  import { m, AnimatePresence, LazyMotion, domAnimation } from "framer-motion";
12
- import { Box, MantineContext, ActionIcon, Text, HoverCard, HoverCardTarget, UnstyledButton, HoverCardDropdown, Stack, Group, Anchor, CopyButton, Button, Paper, Spoiler, Divider, TooltipGroup, Flex, Tooltip, ColorSwatch, CheckIcon, rem, Select, Slider, SegmentedControl, Card } from "@mantine/core";
13
- import { isArray, isNullish, entries, reduce, hasSubObject, hasAtLeast as hasAtLeast$1, isTruthy, first, last, clamp as clamp$1, isNumber, keys, takeWhile, isNonNull } from "remeda";
12
+ import { Box, MantineContext, ActionIcon, Text, HoverCard, HoverCardTarget, UnstyledButton, HoverCardDropdown, Stack, Group, Anchor, CopyButton, Button, Card, CardSection, Spoiler, Divider, TooltipGroup, Flex, Tooltip, ColorSwatch, CheckIcon, rem, Select, Slider, SegmentedControl } from "@mantine/core";
13
+ import { isArray, isNullish, entries, reduce, isEmpty, hasSubObject, hasAtLeast as hasAtLeast$1, isTruthy, first, last, clamp as clamp$1, isNumber, keys, takeWhile, isNonNull } from "remeda";
14
14
  import { invariant, hasAtLeast, isAncestor, nonNullable, StepEdgeId, nonexhaustive, extractStep, defaultTheme, ElementShapes } from "@likec4/core";
15
15
  import { subscribeWithSelector, devtools } from "zustand/middleware";
16
16
  import { useFirstMountState, useCustomCompareEffect, useDebouncedEffect, useIsomorphicLayoutEffect as useIsomorphicLayoutEffect$1 } from "@react-hookz/web";
17
17
  import { assignInlineVars } from "@vanilla-extract/dynamic";
18
18
  import { line, curveCatmullRomOpen } from "d3-shape";
19
- import { IconZoomScan, IconPlayerPlayFilled, IconPlayerSkipBackFilled, IconPlayerStopFilled, IconPlayerSkipForwardFilled } from "@tabler/icons-react";
20
- import { useLocalStorage, useHotkeys } from "@mantine/hooks";
19
+ import { IconZoomScan, IconChevronLeft, IconChevronRight, IconMenu, IconPlayerPlayFilled, IconPlayerSkipBackFilled, IconPlayerStopFilled, IconPlayerSkipForwardFilled } from "@tabler/icons-react";
20
+ import { useStateHistory, useLocalStorage, useHotkeys } from "@mantine/hooks";
21
21
  function cc(names) {
22
22
  if (typeof names == "string" || typeof names == "number") return "" + names;
23
23
  let out = "";
@@ -2638,14 +2638,14 @@ function getEdgePosition(params) {
2638
2638
  // when connection type is loose we can define all handles as sources and connect source -> source
2639
2639
  params.connectionMode === ConnectionMode.Strict ? (targetHandleBounds == null ? void 0 : targetHandleBounds.target) ?? [] : ((targetHandleBounds == null ? void 0 : targetHandleBounds.target) ?? []).concat((targetHandleBounds == null ? void 0 : targetHandleBounds.source) ?? []),
2640
2640
  params.targetHandle
2641
- ), sourcePosition = (sourceHandle == null ? void 0 : sourceHandle.position) || Position.Bottom, targetPosition = (targetHandle == null ? void 0 : targetHandle.position) || Position.Top;
2641
+ );
2642
2642
  if (!sourceHandle || !targetHandle)
2643
2643
  return (_a = params.onError) == null || _a.call(params, "008", errorMessages.error008(sourceHandle ? "target" : "source", {
2644
2644
  id: params.id,
2645
2645
  sourceHandle: params.sourceHandle,
2646
2646
  targetHandle: params.targetHandle
2647
2647
  })), null;
2648
- const [sourceX, sourceY] = getHandlePosition(sourcePosition, sourceNode, sourceHandle), [targetX, targetY] = getHandlePosition(targetPosition, targetNode, targetHandle);
2648
+ const sourcePosition = (sourceHandle == null ? void 0 : sourceHandle.position) || Position.Bottom, targetPosition = (targetHandle == null ? void 0 : targetHandle.position) || Position.Top, [sourceX, sourceY] = getHandlePosition(sourceNode, sourceHandle, sourcePosition), [targetX, targetY] = getHandlePosition(targetNode, targetHandle, targetPosition);
2649
2649
  return {
2650
2650
  sourceX,
2651
2651
  sourceY,
@@ -2666,9 +2666,9 @@ function toHandleBounds(handles) {
2666
2666
  target
2667
2667
  };
2668
2668
  }
2669
- function getHandlePosition(position, node, handle = null) {
2669
+ function getHandlePosition(node, handle, fallbackPosition = Position.Left) {
2670
2670
  const x = ((handle == null ? void 0 : handle.x) ?? 0) + node.internals.positionAbsolute.x, y = ((handle == null ? void 0 : handle.y) ?? 0) + node.internals.positionAbsolute.y, { width, height } = handle ?? getNodeDimensions(node);
2671
- switch (position) {
2671
+ switch ((handle == null ? void 0 : handle.position) ?? fallbackPosition) {
2672
2672
  case Position.Top:
2673
2673
  return [x + width / 2, y];
2674
2674
  case Position.Right:
@@ -3046,13 +3046,19 @@ function XYDrag({ onNodeMouseDown, getStoreItems, onDragStart, onDrag, onDragSto
3046
3046
  };
3047
3047
  }
3048
3048
  function getHandles(node, handleBounds, type, currentHandle) {
3049
- return (handleBounds[type] || []).reduce((res, h) => (`${node.id}-${h.id}-${type}` !== currentHandle && res.push({
3050
- id: h.id || null,
3051
- type,
3052
- nodeId: node.id,
3053
- x: node.internals.positionAbsolute.x + h.x + h.width / 2,
3054
- y: node.internals.positionAbsolute.y + h.y + h.height / 2
3055
- }), res), []);
3049
+ return (handleBounds[type] || []).reduce((res, handle) => {
3050
+ if (`${node.id}-${handle.id}-${type}` !== currentHandle) {
3051
+ const [x, y] = getHandlePosition(node, handle);
3052
+ res.push({
3053
+ id: handle.id || null,
3054
+ type,
3055
+ nodeId: node.id,
3056
+ x,
3057
+ y
3058
+ });
3059
+ }
3060
+ return res;
3061
+ }, []);
3056
3062
  }
3057
3063
  function getClosestHandle(pos, connectionRadius, handles) {
3058
3064
  let closestHandles = [], minDistance = 1 / 0;
@@ -3083,7 +3089,7 @@ function getConnectionStatus(isInsideConnectionRadius, isHandleValid) {
3083
3089
  }
3084
3090
  const alwaysValid = () => !0;
3085
3091
  let connectionStartHandle = null;
3086
- function onPointerDown(event, { connectionMode, connectionRadius, handleId, nodeId, edgeUpdaterType, isTarget, domNode, nodeLookup, lib, autoPanOnConnect, flowId, panBy: panBy2, cancelConnection, onConnectStart, onConnect, onConnectEnd, isValidConnection = alwaysValid, onEdgeUpdateEnd, updateConnection, getTransform, getConnectionStartHandle }) {
3092
+ function onPointerDown(event, { connectionMode, connectionRadius, handleId, nodeId, edgeUpdaterType, isTarget, domNode, nodeLookup, lib, autoPanOnConnect, flowId, panBy: panBy2, cancelConnection, onConnectStart, onConnect, onConnectEnd, isValidConnection = alwaysValid, onReconnectEnd, updateConnection, getTransform, getConnectionStartHandle }) {
3087
3093
  const doc = getHostForElement(event.target);
3088
3094
  let autoPanId = 0, closestHandle;
3089
3095
  const { x, y } = getEventPosition(event), clickedHandle = doc == null ? void 0 : doc.elementFromPoint(x, y), handleType = getHandleType(edgeUpdaterType, clickedHandle), containerBounds = domNode == null ? void 0 : domNode.getBoundingClientRect();
@@ -3105,11 +3111,11 @@ function onPointerDown(event, { connectionMode, connectionRadius, handleId, node
3105
3111
  connectionStartHandle = {
3106
3112
  nodeId,
3107
3113
  handleId,
3108
- type: handleType
3114
+ type: handleType,
3115
+ position: (clickedHandle == null ? void 0 : clickedHandle.getAttribute("data-handlepos")) || Position.Top
3109
3116
  }, updateConnection({
3110
3117
  connectionPosition,
3111
3118
  connectionStatus: null,
3112
- // connectionNodeId etc will be removed in the next major in favor of connectionStartHandle
3113
3119
  connectionStartHandle,
3114
3120
  connectionEndHandle: null
3115
3121
  }), onConnectStart == null || onConnectStart(event, { nodeId, handleId, handleType });
@@ -3139,7 +3145,7 @@ function onPointerDown(event, { connectionMode, connectionRadius, handleId, node
3139
3145
  });
3140
3146
  }
3141
3147
  function onPointerUp(event2) {
3142
- (closestHandle || handleDomNode) && connection && isValid && (onConnect == null || onConnect(connection)), onConnectEnd == null || onConnectEnd(event2), edgeUpdaterType && (onEdgeUpdateEnd == null || onEdgeUpdateEnd(event2)), cancelConnection(), cancelAnimationFrame(autoPanId), autoPanStarted = !1, isValid = !1, connection = null, handleDomNode = null, connectionStartHandle = null, doc.removeEventListener("mousemove", onPointerMove), doc.removeEventListener("mouseup", onPointerUp), doc.removeEventListener("touchmove", onPointerMove), doc.removeEventListener("touchend", onPointerUp);
3148
+ (closestHandle || handleDomNode) && connection && isValid && (onConnect == null || onConnect(connection)), onConnectEnd == null || onConnectEnd(event2), edgeUpdaterType && (onReconnectEnd == null || onReconnectEnd(event2)), cancelConnection(), cancelAnimationFrame(autoPanId), autoPanStarted = !1, isValid = !1, connection = null, handleDomNode = null, connectionStartHandle = null, doc.removeEventListener("mousemove", onPointerMove), doc.removeEventListener("mouseup", onPointerUp), doc.removeEventListener("touchmove", onPointerMove), doc.removeEventListener("touchend", onPointerUp);
3143
3149
  }
3144
3150
  doc.addEventListener("mousemove", onPointerMove), doc.addEventListener("mouseup", onPointerUp), doc.addEventListener("touchmove", onPointerMove), doc.addEventListener("touchend", onPointerUp);
3145
3151
  }
@@ -3160,11 +3166,14 @@ function isValidHandle(event, { handle, connectionMode, fromNodeId, fromHandleId
3160
3166
  target: isTarget ? fromNodeId : handleNodeId,
3161
3167
  targetHandle: isTarget ? fromHandleId : handleId
3162
3168
  };
3163
- result.connection = connection, connectable && connectableEnd && (connectionMode === ConnectionMode.Strict ? isTarget && handleType === "source" || !isTarget && handleType === "target" : handleNodeId !== fromNodeId || handleId !== fromHandleId) && (result.endHandle = {
3169
+ result.connection = connection;
3170
+ const isValid = connectable && connectableEnd && (connectionMode === ConnectionMode.Strict ? isTarget && handleType === "source" || !isTarget && handleType === "target" : handleNodeId !== fromNodeId || handleId !== fromHandleId);
3171
+ result.isValid = isValid && isValidConnection(connection), result.endHandle = {
3164
3172
  nodeId: handleNodeId,
3165
3173
  handleId,
3166
- type: handleType
3167
- }, result.isValid = isValidConnection(connection));
3174
+ type: handleType,
3175
+ position: handleToCheck.getAttribute("data-handlepos")
3176
+ };
3168
3177
  }
3169
3178
  return result;
3170
3179
  }
@@ -3683,7 +3692,7 @@ const defaultNodeOrigin = [0, 0], defaultViewport = { x: 0, y: 0, zoom: 1 }, rea
3683
3692
  "nodesConnectable",
3684
3693
  "nodesFocusable",
3685
3694
  "edgesFocusable",
3686
- "edgesUpdatable",
3695
+ "edgesReconnectable",
3687
3696
  "elevateNodesOnSelect",
3688
3697
  "elevateEdgesOnSelect",
3689
3698
  "minZoom",
@@ -4057,7 +4066,7 @@ function useReactFlow() {
4057
4066
  }
4058
4067
  return node;
4059
4068
  }));
4060
- }, updateEdge2 = (id2, edgeUpdate, options = { replace: !1 }) => {
4069
+ }, updateEdge = (id2, edgeUpdate, options = { replace: !1 }) => {
4061
4070
  setEdges((prevEdges) => prevEdges.map((edge) => {
4062
4071
  if (edge.id === id2) {
4063
4072
  const nextEdge = typeof edgeUpdate == "function" ? edgeUpdate(edge) : edgeUpdate;
@@ -4142,9 +4151,9 @@ function useReactFlow() {
4142
4151
  return options.replace ? { ...node, data: nextData } : { ...node, data: { ...node.data, ...nextData } };
4143
4152
  }, options);
4144
4153
  },
4145
- updateEdge: updateEdge2,
4154
+ updateEdge,
4146
4155
  updateEdgeData: (id2, dataUpdate, options = { replace: !1 }) => {
4147
- updateEdge2(id2, (edge) => {
4156
+ updateEdge(id2, (edge) => {
4148
4157
  const nextData = typeof dataUpdate == "function" ? dataUpdate(edge) : dataUpdate;
4149
4158
  return options.replace ? { ...edge, data: nextData } : { ...edge, data: { ...edge.data, ...nextData } };
4150
4159
  }, options);
@@ -4157,9 +4166,9 @@ function useReactFlow() {
4157
4166
  viewportInitialized
4158
4167
  }), [viewportInitialized]);
4159
4168
  }
4160
- const selected = (item) => item.selected, deleteKeyOptions = { actInsideInputWithModifier: !1 };
4169
+ const selected = (item) => item.selected, deleteKeyOptions = { actInsideInputWithModifier: !1 }, win$1 = typeof window < "u" ? window : void 0;
4161
4170
  function useGlobalKeyHandler({ deleteKeyCode, multiSelectionKeyCode }) {
4162
- const store = useStoreApi(), { deleteElements } = useReactFlow(), deleteKeyPressed = useKeyPress(deleteKeyCode, deleteKeyOptions), multiSelectionKeyPressed = useKeyPress(multiSelectionKeyCode);
4171
+ const store = useStoreApi(), { deleteElements } = useReactFlow(), deleteKeyPressed = useKeyPress(deleteKeyCode, deleteKeyOptions), multiSelectionKeyPressed = useKeyPress(multiSelectionKeyCode, { target: win$1 });
4163
4172
  useEffect(() => {
4164
4173
  if (deleteKeyPressed) {
4165
4174
  const { edges, nodes } = store.getState();
@@ -4289,10 +4298,14 @@ const wrapHandler = (handler, containerRef) => (event) => {
4289
4298
  elementsSelectable: s.elementsSelectable,
4290
4299
  dragging: s.paneDragging
4291
4300
  });
4292
- function Pane({ isSelecting, selectionMode = SelectionMode.Full, panOnDrag, onSelectionStart, onSelectionEnd, onPaneClick, onPaneContextMenu, onPaneScroll, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, children: children2 }) {
4293
- const container2 = useRef(null), store = useStoreApi(), prevSelectedNodesCount = useRef(0), prevSelectedEdgesCount = useRef(0), containerBounds = useRef(), edgeIdLookup = useRef(/* @__PURE__ */ new Map()), { userSelectionActive, elementsSelectable, dragging } = useStore(selector$j, shallow), resetUserSelection = () => {
4301
+ function Pane({ isSelecting, selectionKeyPressed, selectionMode = SelectionMode.Full, panOnDrag, onSelectionStart, onSelectionEnd, onPaneClick, onPaneContextMenu, onPaneScroll, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, children: children2 }) {
4302
+ const container2 = useRef(null), store = useStoreApi(), prevSelectedNodesCount = useRef(0), prevSelectedEdgesCount = useRef(0), containerBounds = useRef(), edgeIdLookup = useRef(/* @__PURE__ */ new Map()), { userSelectionActive, elementsSelectable, dragging } = useStore(selector$j, shallow), hasActiveSelection = elementsSelectable && (isSelecting || userSelectionActive), selectionInProgress = useRef(!1), resetUserSelection = () => {
4294
4303
  store.setState({ userSelectionActive: !1, userSelectionRect: null }), prevSelectedNodesCount.current = 0, prevSelectedEdgesCount.current = 0;
4295
4304
  }, onClick = (event) => {
4305
+ if (selectionInProgress.current) {
4306
+ selectionInProgress.current = !1;
4307
+ return;
4308
+ }
4296
4309
  onPaneClick == null || onPaneClick(event), store.getState().resetSelectedElements(), store.setState({ nodesSelectionActive: !1 });
4297
4310
  }, onContextMenu = (event) => {
4298
4311
  if (Array.isArray(panOnDrag) && (panOnDrag != null && panOnDrag.includes(2))) {
@@ -4300,14 +4313,14 @@ function Pane({ isSelecting, selectionMode = SelectionMode.Full, panOnDrag, onSe
4300
4313
  return;
4301
4314
  }
4302
4315
  onPaneContextMenu == null || onPaneContextMenu(event);
4303
- }, onWheel = onPaneScroll ? (event) => onPaneScroll(event) : void 0, onMouseDown = (event) => {
4304
- var _a, _b;
4316
+ }, onWheel = onPaneScroll ? (event) => onPaneScroll(event) : void 0, onPointerDown2 = (event) => {
4317
+ var _a, _b, _c;
4305
4318
  const { resetSelectedElements, domNode, edgeLookup } = store.getState();
4306
- if (containerBounds.current = domNode == null ? void 0 : domNode.getBoundingClientRect(), !elementsSelectable || !isSelecting || event.button !== 0 || event.target !== container2.current || !containerBounds.current)
4319
+ if (containerBounds.current = domNode == null ? void 0 : domNode.getBoundingClientRect(), (_a = container2.current) == null || _a.setPointerCapture(event.pointerId), !elementsSelectable || !isSelecting || event.button !== 0 || event.target !== container2.current || !containerBounds.current)
4307
4320
  return;
4308
4321
  edgeIdLookup.current = /* @__PURE__ */ new Map();
4309
4322
  for (const [id2, edge] of edgeLookup)
4310
- edgeIdLookup.current.set(edge.source, ((_a = edgeIdLookup.current.get(edge.source)) == null ? void 0 : _a.add(id2)) || /* @__PURE__ */ new Set([id2])), edgeIdLookup.current.set(edge.target, ((_b = edgeIdLookup.current.get(edge.target)) == null ? void 0 : _b.add(id2)) || /* @__PURE__ */ new Set([id2]));
4323
+ edgeIdLookup.current.set(edge.source, ((_b = edgeIdLookup.current.get(edge.source)) == null ? void 0 : _b.add(id2)) || /* @__PURE__ */ new Set([id2])), edgeIdLookup.current.set(edge.target, ((_c = edgeIdLookup.current.get(edge.target)) == null ? void 0 : _c.add(id2)) || /* @__PURE__ */ new Set([id2]));
4311
4324
  const { x, y } = getEventPosition(event.nativeEvent, containerBounds.current);
4312
4325
  resetSelectedElements(), store.setState({
4313
4326
  userSelectionRect: {
@@ -4319,10 +4332,11 @@ function Pane({ isSelecting, selectionMode = SelectionMode.Full, panOnDrag, onSe
4319
4332
  y
4320
4333
  }
4321
4334
  }), onSelectionStart == null || onSelectionStart(event);
4322
- }, onMouseMove = (event) => {
4335
+ }, onPointerMove = (event) => {
4323
4336
  const { userSelectionRect, edgeLookup, transform: transform2, nodeOrigin, nodeLookup, triggerNodeChanges, triggerEdgeChanges } = store.getState();
4324
- if (!isSelecting || !containerBounds.current || !userSelectionRect)
4337
+ if (!containerBounds.current || !userSelectionRect)
4325
4338
  return;
4339
+ selectionInProgress.current = !0;
4326
4340
  const { x: mouseX, y: mouseY } = getEventPosition(event.nativeEvent, containerBounds.current), { startX, startY } = userSelectionRect, nextUserSelectRect = {
4327
4341
  startX,
4328
4342
  startY,
@@ -4353,15 +4367,15 @@ function Pane({ isSelecting, selectionMode = SelectionMode.Full, panOnDrag, onSe
4353
4367
  userSelectionActive: !0,
4354
4368
  nodesSelectionActive: !1
4355
4369
  });
4356
- }, onMouseUp = (event) => {
4370
+ }, onPointerUp = (event) => {
4371
+ var _a;
4357
4372
  if (event.button !== 0)
4358
4373
  return;
4374
+ (_a = container2.current) == null || _a.releasePointerCapture(event.pointerId);
4359
4375
  const { userSelectionRect } = store.getState();
4360
- !userSelectionActive && userSelectionRect && event.target === container2.current && (onClick == null || onClick(event)), store.setState({ nodesSelectionActive: prevSelectedNodesCount.current > 0 }), resetUserSelection(), onSelectionEnd == null || onSelectionEnd(event);
4361
- }, onMouseLeave = (event) => {
4362
- userSelectionActive && (store.setState({ nodesSelectionActive: prevSelectedNodesCount.current > 0 }), onSelectionEnd == null || onSelectionEnd(event)), resetUserSelection();
4363
- }, hasActiveSelection = elementsSelectable && (isSelecting || userSelectionActive);
4364
- return jsxs("div", { className: cc(["react-flow__pane", { draggable: panOnDrag, dragging, selection: isSelecting }]), onClick: hasActiveSelection ? void 0 : wrapHandler(onClick, container2), onContextMenu: wrapHandler(onContextMenu, container2), onWheel: wrapHandler(onWheel, container2), onMouseEnter: hasActiveSelection ? void 0 : onPaneMouseEnter, onMouseDown: hasActiveSelection ? onMouseDown : void 0, onMouseMove: hasActiveSelection ? onMouseMove : onPaneMouseMove, onMouseUp: hasActiveSelection ? onMouseUp : void 0, onMouseLeave: hasActiveSelection ? onMouseLeave : onPaneMouseLeave, ref: container2, style: containerStyle, children: [children2, jsx(UserSelection, {})] });
4376
+ !userSelectionActive && userSelectionRect && event.target === container2.current && (onClick == null || onClick(event)), store.setState({ nodesSelectionActive: prevSelectedNodesCount.current > 0 }), resetUserSelection(), onSelectionEnd == null || onSelectionEnd(event), selectionKeyPressed && (selectionInProgress.current = !1);
4377
+ };
4378
+ return jsxs("div", { className: cc(["react-flow__pane", { draggable: panOnDrag, dragging, selection: isSelecting }]), onClick: hasActiveSelection ? void 0 : wrapHandler(onClick, container2), onContextMenu: wrapHandler(onContextMenu, container2), onWheel: wrapHandler(onWheel, container2), onPointerEnter: hasActiveSelection ? void 0 : onPaneMouseEnter, onPointerDown: hasActiveSelection ? onPointerDown2 : onPaneMouseMove, onPointerMove: hasActiveSelection ? onPointerMove : onPaneMouseMove, onPointerUp: hasActiveSelection ? onPointerUp : void 0, onPointerLeave: onPaneMouseLeave, ref: container2, style: containerStyle, children: [children2, jsx(UserSelection, {})] });
4365
4379
  }
4366
4380
  function handleNodeClick({ id: id2, store, unselect = !1, nodeRef }) {
4367
4381
  const { addSelectedNodes, unselectNodesAndEdges, multiSelectionActive, nodeLookup, onError } = store.getState(), node = nodeLookup.get(id2);
@@ -4616,10 +4630,10 @@ function NodesSelection({ onSelectionContextMenu, noPanClassName, disableKeyboar
4616
4630
  height
4617
4631
  } }) });
4618
4632
  }
4619
- const selector$g = (s) => ({ nodesSelectionActive: s.nodesSelectionActive, userSelectionActive: s.userSelectionActive });
4633
+ const win = typeof window < "u" ? window : void 0, selector$g = (s) => ({ nodesSelectionActive: s.nodesSelectionActive, userSelectionActive: s.userSelectionActive });
4620
4634
  function FlowRendererComponent({ children: children2, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneContextMenu, onPaneScroll, deleteKeyCode, selectionKeyCode, selectionOnDrag, selectionMode, onSelectionStart, onSelectionEnd, multiSelectionKeyCode, panActivationKeyCode, zoomActivationKeyCode, elementsSelectable, zoomOnScroll, zoomOnPinch, panOnScroll: _panOnScroll, panOnScrollSpeed, panOnScrollMode, zoomOnDoubleClick, panOnDrag: _panOnDrag, defaultViewport: defaultViewport2, translateExtent, minZoom, maxZoom, preventScrolling, onSelectionContextMenu, noWheelClassName, noPanClassName, disableKeyboardA11y, onViewportChange, isControlledViewport }) {
4621
- const { nodesSelectionActive, userSelectionActive } = useStore(selector$g), selectionKeyPressed = useKeyPress(selectionKeyCode), panActivationKeyPressed = useKeyPress(panActivationKeyCode), panOnDrag = panActivationKeyPressed || _panOnDrag, panOnScroll = panActivationKeyPressed || _panOnScroll, isSelecting = selectionKeyPressed || userSelectionActive || selectionOnDrag && panOnDrag !== !0;
4622
- return useGlobalKeyHandler({ deleteKeyCode, multiSelectionKeyCode }), jsx(ZoomPane, { onPaneContextMenu, elementsSelectable, zoomOnScroll, zoomOnPinch, panOnScroll, panOnScrollSpeed, panOnScrollMode, zoomOnDoubleClick, panOnDrag: !selectionKeyPressed && panOnDrag, defaultViewport: defaultViewport2, translateExtent, minZoom, maxZoom, zoomActivationKeyCode, preventScrolling, noWheelClassName, noPanClassName, onViewportChange, isControlledViewport, children: jsxs(Pane, { onSelectionStart, onSelectionEnd, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneContextMenu, onPaneScroll, panOnDrag, isSelecting: !!isSelecting, selectionMode, children: [children2, nodesSelectionActive && jsx(NodesSelection, { onSelectionContextMenu, noPanClassName, disableKeyboardA11y })] }) });
4635
+ const { nodesSelectionActive, userSelectionActive } = useStore(selector$g), selectionKeyPressed = useKeyPress(selectionKeyCode, { target: win }), panActivationKeyPressed = useKeyPress(panActivationKeyCode, { target: win }), panOnDrag = panActivationKeyPressed || _panOnDrag, panOnScroll = panActivationKeyPressed || _panOnScroll, isSelecting = selectionKeyPressed || userSelectionActive || selectionOnDrag && panOnDrag !== !0;
4636
+ return useGlobalKeyHandler({ deleteKeyCode, multiSelectionKeyCode }), jsx(ZoomPane, { onPaneContextMenu, elementsSelectable, zoomOnScroll, zoomOnPinch, panOnScroll, panOnScrollSpeed, panOnScrollMode, zoomOnDoubleClick, panOnDrag: !selectionKeyPressed && panOnDrag, defaultViewport: defaultViewport2, translateExtent, minZoom, maxZoom, zoomActivationKeyCode, preventScrolling, noWheelClassName, noPanClassName, onViewportChange, isControlledViewport, children: jsxs(Pane, { onSelectionStart, onSelectionEnd, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneContextMenu, onPaneScroll, panOnDrag, isSelecting: !!isSelecting, selectionMode, selectionKeyPressed, children: [children2, nodesSelectionActive && jsx(NodesSelection, { onSelectionContextMenu, noPanClassName, disableKeyboardA11y })] }) });
4623
4637
  }
4624
4638
  FlowRendererComponent.displayName = "FlowRenderer";
4625
4639
  const FlowRenderer = memo(FlowRendererComponent), selector$f = (onlyRenderVisible) => (s) => onlyRenderVisible ? getNodesInside(s.nodeLookup, { x: 0, y: 0, width: s.width, height: s.height }, s.transform, !0).map((node) => node.id) : Array.from(s.nodeLookup.keys());
@@ -4961,15 +4975,15 @@ const builtinEdgeTypes = {
4961
4975
  function EdgeAnchor({ position, centerX, centerY, radius = 10, onMouseDown, onMouseEnter, onMouseOut, type }) {
4962
4976
  return jsx("circle", { onMouseDown, onMouseEnter, onMouseOut, className: cc([EdgeUpdaterClassName, `${EdgeUpdaterClassName}-${type}`]), cx: shiftX(centerX, radius, position), cy: shiftY(centerY, radius, position), r: radius, stroke: "transparent", fill: "transparent" });
4963
4977
  }
4964
- function EdgeUpdateAnchors({ isUpdatable, edgeUpdaterRadius, edge, targetHandleId, sourceHandleId, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, onEdgeUpdate, onEdgeUpdateStart, onEdgeUpdateEnd, setUpdating, setUpdateHover }) {
4978
+ function EdgeUpdateAnchors({ isReconnectable, reconnectRadius, edge, targetHandleId, sourceHandleId, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, onReconnect, onReconnectStart, onReconnectEnd, setReconnecting, setUpdateHover }) {
4965
4979
  const store = useStoreApi(), handleEdgeUpdater = (event, isSourceHandle) => {
4966
4980
  if (event.button !== 0)
4967
4981
  return;
4968
4982
  const { autoPanOnConnect, domNode, isValidConnection, connectionMode, connectionRadius, lib, onConnectStart, onConnectEnd, cancelConnection, nodeLookup, rfId: flowId, panBy: panBy2, updateConnection } = store.getState(), nodeId = isSourceHandle ? edge.target : edge.source, handleId = (isSourceHandle ? targetHandleId : sourceHandleId) || null, handleType = isSourceHandle ? "target" : "source", isTarget = isSourceHandle;
4969
- setUpdating(!0), onEdgeUpdateStart == null || onEdgeUpdateStart(event, edge, handleType);
4970
- const _onEdgeUpdateEnd = (evt) => {
4971
- setUpdating(!1), onEdgeUpdateEnd == null || onEdgeUpdateEnd(evt, edge, handleType);
4972
- }, onConnectEdge = (connection) => onEdgeUpdate == null ? void 0 : onEdgeUpdate(edge, connection);
4983
+ setReconnecting(!0), onReconnectStart == null || onReconnectStart(event, edge, handleType);
4984
+ const _onReconnectEnd = (evt) => {
4985
+ setReconnecting(!1), onReconnectEnd == null || onReconnectEnd(evt, edge, handleType);
4986
+ }, onConnectEdge = (connection) => onReconnect == null ? void 0 : onReconnect(edge, connection);
4973
4987
  XYHandle.onPointerDown(event.nativeEvent, {
4974
4988
  autoPanOnConnect,
4975
4989
  connectionMode,
@@ -4988,21 +5002,21 @@ function EdgeUpdateAnchors({ isUpdatable, edgeUpdaterRadius, edge, targetHandleI
4988
5002
  onConnect: onConnectEdge,
4989
5003
  onConnectStart,
4990
5004
  onConnectEnd,
4991
- onEdgeUpdateEnd: _onEdgeUpdateEnd,
5005
+ onReconnectEnd: _onReconnectEnd,
4992
5006
  updateConnection,
4993
5007
  getTransform: () => store.getState().transform,
4994
5008
  getConnectionStartHandle: () => store.getState().connectionStartHandle
4995
5009
  });
4996
- }, onEdgeUpdaterSourceMouseDown = (event) => handleEdgeUpdater(event, !0), onEdgeUpdaterTargetMouseDown = (event) => handleEdgeUpdater(event, !1), onEdgeUpdaterMouseEnter = () => setUpdateHover(!0), onEdgeUpdaterMouseOut = () => setUpdateHover(!1);
4997
- return jsxs(Fragment, { children: [(isUpdatable === "source" || isUpdatable === !0) && jsx(EdgeAnchor, { position: sourcePosition, centerX: sourceX, centerY: sourceY, radius: edgeUpdaterRadius, onMouseDown: onEdgeUpdaterSourceMouseDown, onMouseEnter: onEdgeUpdaterMouseEnter, onMouseOut: onEdgeUpdaterMouseOut, type: "source" }), (isUpdatable === "target" || isUpdatable === !0) && jsx(EdgeAnchor, { position: targetPosition, centerX: targetX, centerY: targetY, radius: edgeUpdaterRadius, onMouseDown: onEdgeUpdaterTargetMouseDown, onMouseEnter: onEdgeUpdaterMouseEnter, onMouseOut: onEdgeUpdaterMouseOut, type: "target" })] });
5010
+ }, onReconnectSourceMouseDown = (event) => handleEdgeUpdater(event, !0), onReconnectTargetMouseDown = (event) => handleEdgeUpdater(event, !1), onReconnectMouseEnter = () => setUpdateHover(!0), onReconnectMouseOut = () => setUpdateHover(!1);
5011
+ return jsxs(Fragment, { children: [(isReconnectable === "source" || isReconnectable === !0) && jsx(EdgeAnchor, { position: sourcePosition, centerX: sourceX, centerY: sourceY, radius: reconnectRadius, onMouseDown: onReconnectSourceMouseDown, onMouseEnter: onReconnectMouseEnter, onMouseOut: onReconnectMouseOut, type: "source" }), (isReconnectable === "target" || isReconnectable === !0) && jsx(EdgeAnchor, { position: targetPosition, centerX: targetX, centerY: targetY, radius: reconnectRadius, onMouseDown: onReconnectTargetMouseDown, onMouseEnter: onReconnectMouseEnter, onMouseOut: onReconnectMouseOut, type: "target" })] });
4998
5012
  }
4999
- function EdgeWrapper({ id: id2, edgesFocusable, edgesUpdatable, elementsSelectable, onClick, onDoubleClick, onContextMenu, onMouseEnter, onMouseMove, onMouseLeave, edgeUpdaterRadius, onEdgeUpdate, onEdgeUpdateStart, onEdgeUpdateEnd, rfId, edgeTypes: edgeTypes2, noPanClassName, onError, disableKeyboardA11y }) {
5013
+ function EdgeWrapper({ id: id2, edgesFocusable, edgesReconnectable, elementsSelectable, onClick, onDoubleClick, onContextMenu, onMouseEnter, onMouseMove, onMouseLeave, reconnectRadius, onReconnect, onReconnectStart, onReconnectEnd, rfId, edgeTypes: edgeTypes2, noPanClassName, onError, disableKeyboardA11y }) {
5000
5014
  let edge = useStore((s) => s.edgeLookup.get(id2));
5001
5015
  const defaultEdgeOptions = useStore((s) => s.defaultEdgeOptions);
5002
5016
  edge = defaultEdgeOptions ? { ...defaultEdgeOptions, ...edge } : edge;
5003
5017
  let edgeType = edge.type || "default", EdgeComponent = (edgeTypes2 == null ? void 0 : edgeTypes2[edgeType]) || builtinEdgeTypes[edgeType];
5004
5018
  EdgeComponent === void 0 && (onError == null || onError("011", errorMessages.error011(edgeType)), edgeType = "default", EdgeComponent = builtinEdgeTypes.default);
5005
- const isFocusable = !!(edge.focusable || edgesFocusable && typeof edge.focusable > "u"), isUpdatable = typeof onEdgeUpdate < "u" && (edge.updatable || edgesUpdatable && typeof edge.updatable > "u"), isSelectable = !!(edge.selectable || elementsSelectable && typeof edge.selectable > "u"), edgeRef = useRef(null), [updateHover, setUpdateHover] = useState(!1), [updating, setUpdating] = useState(!1), store = useStoreApi(), { zIndex, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition } = useStore(useCallback((store2) => {
5019
+ const isFocusable = !!(edge.focusable || edgesFocusable && typeof edge.focusable > "u"), isReconnectable = typeof onReconnect < "u" && (edge.reconnectable || edgesReconnectable && typeof edge.reconnectable > "u"), isSelectable = !!(edge.selectable || elementsSelectable && typeof edge.selectable > "u"), edgeRef = useRef(null), [updateHover, setUpdateHover] = useState(!1), [reconnecting, setReconnecting] = useState(!1), store = useStoreApi(), { zIndex, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition } = useStore(useCallback((store2) => {
5006
5020
  const sourceNode = store2.nodeLookup.get(edge.source), targetNode = store2.nodeLookup.get(edge.target);
5007
5021
  if (!sourceNode || !targetNode)
5008
5022
  return {
@@ -5064,20 +5078,20 @@ function EdgeWrapper({ id: id2, edgesFocusable, edgesUpdatable, elementsSelectab
5064
5078
  updating: updateHover,
5065
5079
  selectable: isSelectable
5066
5080
  }
5067
- ]), onClick: onEdgeClick, onDoubleClick: onEdgeDoubleClick, onContextMenu: onEdgeContextMenu, onMouseEnter: onEdgeMouseEnter, onMouseMove: onEdgeMouseMove, onMouseLeave: onEdgeMouseLeave, onKeyDown: isFocusable ? onKeyDown : void 0, tabIndex: isFocusable ? 0 : void 0, role: isFocusable ? "button" : "img", "data-id": id2, "data-testid": `rf__edge-${id2}`, "aria-label": edge.ariaLabel === null ? void 0 : edge.ariaLabel || `Edge from ${edge.source} to ${edge.target}`, "aria-describedby": isFocusable ? `${ARIA_EDGE_DESC_KEY}-${rfId}` : void 0, ref: edgeRef, children: [!updating && jsx(EdgeComponent, { id: id2, source: edge.source, target: edge.target, type: edge.type, selected: edge.selected, animated: edge.animated, selectable: isSelectable, deletable: edge.deletable ?? !0, label: edge.label, labelStyle: edge.labelStyle, labelShowBg: edge.labelShowBg, labelBgStyle: edge.labelBgStyle, labelBgPadding: edge.labelBgPadding, labelBgBorderRadius: edge.labelBgBorderRadius, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, data: edge.data, style: edge.style, sourceHandleId: edge.sourceHandle, targetHandleId: edge.targetHandle, markerStart: markerStartUrl, markerEnd: markerEndUrl, pathOptions: "pathOptions" in edge ? edge.pathOptions : void 0, interactionWidth: edge.interactionWidth }), isUpdatable && jsx(EdgeUpdateAnchors, { edge, isUpdatable, edgeUpdaterRadius, onEdgeUpdate, onEdgeUpdateStart, onEdgeUpdateEnd, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, setUpdateHover, setUpdating, sourceHandleId: edge.sourceHandle, targetHandleId: edge.targetHandle })] }) });
5081
+ ]), onClick: onEdgeClick, onDoubleClick: onEdgeDoubleClick, onContextMenu: onEdgeContextMenu, onMouseEnter: onEdgeMouseEnter, onMouseMove: onEdgeMouseMove, onMouseLeave: onEdgeMouseLeave, onKeyDown: isFocusable ? onKeyDown : void 0, tabIndex: isFocusable ? 0 : void 0, role: isFocusable ? "button" : "img", "data-id": id2, "data-testid": `rf__edge-${id2}`, "aria-label": edge.ariaLabel === null ? void 0 : edge.ariaLabel || `Edge from ${edge.source} to ${edge.target}`, "aria-describedby": isFocusable ? `${ARIA_EDGE_DESC_KEY}-${rfId}` : void 0, ref: edgeRef, children: [!reconnecting && jsx(EdgeComponent, { id: id2, source: edge.source, target: edge.target, type: edge.type, selected: edge.selected, animated: edge.animated, selectable: isSelectable, deletable: edge.deletable ?? !0, label: edge.label, labelStyle: edge.labelStyle, labelShowBg: edge.labelShowBg, labelBgStyle: edge.labelBgStyle, labelBgPadding: edge.labelBgPadding, labelBgBorderRadius: edge.labelBgBorderRadius, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, data: edge.data, style: edge.style, sourceHandleId: edge.sourceHandle, targetHandleId: edge.targetHandle, markerStart: markerStartUrl, markerEnd: markerEndUrl, pathOptions: "pathOptions" in edge ? edge.pathOptions : void 0, interactionWidth: edge.interactionWidth }), isReconnectable && jsx(EdgeUpdateAnchors, { edge, isReconnectable, reconnectRadius, onReconnect, onReconnectStart, onReconnectEnd, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, setUpdateHover, setReconnecting, sourceHandleId: edge.sourceHandle, targetHandleId: edge.targetHandle })] }) });
5068
5082
  }
5069
5083
  const selector$c = (s) => ({
5070
5084
  width: s.width,
5071
5085
  height: s.height,
5072
5086
  edgesFocusable: s.edgesFocusable,
5073
- edgesUpdatable: s.edgesUpdatable,
5087
+ edgesReconnectable: s.edgesReconnectable,
5074
5088
  elementsSelectable: s.elementsSelectable,
5075
5089
  connectionMode: s.connectionMode,
5076
5090
  onError: s.onError
5077
5091
  });
5078
- function EdgeRendererComponent({ defaultMarkerColor, onlyRenderVisibleElements, rfId, edgeTypes: edgeTypes2, noPanClassName, onEdgeUpdate, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, onEdgeClick, edgeUpdaterRadius, onEdgeDoubleClick, onEdgeUpdateStart, onEdgeUpdateEnd, disableKeyboardA11y }) {
5079
- const { edgesFocusable, edgesUpdatable, elementsSelectable, onError } = useStore(selector$c, shallow), edgeIds = useVisibleEdgeIds(onlyRenderVisibleElements);
5080
- return jsxs("div", { className: "react-flow__edges", children: [jsx(MarkerDefinitions$1, { defaultColor: defaultMarkerColor, rfId }), edgeIds.map((id2) => jsx(EdgeWrapper, { id: id2, edgesFocusable, edgesUpdatable, elementsSelectable, noPanClassName, onEdgeUpdate, onContextMenu: onEdgeContextMenu, onMouseEnter: onEdgeMouseEnter, onMouseMove: onEdgeMouseMove, onMouseLeave: onEdgeMouseLeave, onClick: onEdgeClick, edgeUpdaterRadius, onDoubleClick: onEdgeDoubleClick, onEdgeUpdateStart, onEdgeUpdateEnd, rfId, onError, edgeTypes: edgeTypes2, disableKeyboardA11y }, id2))] });
5092
+ function EdgeRendererComponent({ defaultMarkerColor, onlyRenderVisibleElements, rfId, edgeTypes: edgeTypes2, noPanClassName, onReconnect, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, onEdgeClick, reconnectRadius, onEdgeDoubleClick, onReconnectStart, onReconnectEnd, disableKeyboardA11y }) {
5093
+ const { edgesFocusable, edgesReconnectable, elementsSelectable, onError } = useStore(selector$c, shallow), edgeIds = useVisibleEdgeIds(onlyRenderVisibleElements);
5094
+ return jsxs("div", { className: "react-flow__edges", children: [jsx(MarkerDefinitions$1, { defaultColor: defaultMarkerColor, rfId }), edgeIds.map((id2) => jsx(EdgeWrapper, { id: id2, edgesFocusable, edgesReconnectable, elementsSelectable, noPanClassName, onReconnect, onContextMenu: onEdgeContextMenu, onMouseEnter: onEdgeMouseEnter, onMouseMove: onEdgeMouseMove, onMouseLeave: onEdgeMouseLeave, onClick: onEdgeClick, reconnectRadius, onDoubleClick: onEdgeDoubleClick, onReconnectStart, onReconnectEnd, rfId, onError, edgeTypes: edgeTypes2, disableKeyboardA11y }, id2))] });
5081
5095
  }
5082
5096
  EdgeRendererComponent.displayName = "EdgeRenderer";
5083
5097
  const EdgeRenderer = memo(EdgeRendererComponent), selector$b = (s) => `translate(${s.transform[0]}px,${s.transform[1]}px) scale(${s.transform[2]})`;
@@ -5107,20 +5121,22 @@ const oppositePosition = {
5107
5121
  [Position.Top]: Position.Bottom,
5108
5122
  [Position.Bottom]: Position.Top
5109
5123
  }, ConnectionLine = ({ nodeId, handleType, style: style2, type = ConnectionLineType.Bezier, CustomComponent, connectionStatus }) => {
5110
- const { fromNode, handleId, toX, toY, connectionMode } = useStore(useCallback((s) => {
5111
- var _a;
5124
+ const { fromNode, handleId, toX, toY, connectionMode, endPosition, isValid } = useStore(useCallback((s) => {
5125
+ var _a, _b;
5112
5126
  return {
5113
5127
  fromNode: s.nodeLookup.get(nodeId),
5114
5128
  handleId: (_a = s.connectionStartHandle) == null ? void 0 : _a.handleId,
5115
5129
  toX: (s.connectionPosition.x - s.transform[0]) / s.transform[2],
5116
5130
  toY: (s.connectionPosition.y - s.transform[1]) / s.transform[2],
5117
- connectionMode: s.connectionMode
5131
+ connectionMode: s.connectionMode,
5132
+ endPosition: (_b = s.connectionEndHandle) == null ? void 0 : _b.position,
5133
+ isValid: s.connectionStatus === "valid"
5118
5134
  };
5119
5135
  }, [nodeId]), shallow), fromHandleBounds = fromNode == null ? void 0 : fromNode.internals.handleBounds;
5120
5136
  let handleBounds = fromHandleBounds == null ? void 0 : fromHandleBounds[handleType];
5121
5137
  if (connectionMode === ConnectionMode.Loose && (handleBounds = handleBounds || (fromHandleBounds == null ? void 0 : fromHandleBounds[handleType === "source" ? "target" : "source"])), !fromNode || !handleBounds)
5122
5138
  return null;
5123
- const fromHandle = handleId ? handleBounds.find((d) => d.id === handleId) : handleBounds[0], fromHandleX = fromHandle ? fromHandle.x + fromHandle.width / 2 : (fromNode.measured.width ?? 0) / 2, fromHandleY = fromHandle ? fromHandle.y + fromHandle.height / 2 : fromNode.measured.height ?? 0, fromX = fromNode.internals.positionAbsolute.x + fromHandleX, fromY = fromNode.internals.positionAbsolute.y + fromHandleY, fromPosition = fromHandle == null ? void 0 : fromHandle.position, toPosition = fromPosition ? oppositePosition[fromPosition] : null;
5139
+ const fromHandle = handleId ? handleBounds.find((d) => d.id === handleId) : handleBounds[0], fromHandleX = fromHandle ? fromHandle.x + fromHandle.width / 2 : (fromNode.measured.width ?? 0) / 2, fromHandleY = fromHandle ? fromHandle.y + fromHandle.height / 2 : fromNode.measured.height ?? 0, fromX = fromNode.internals.positionAbsolute.x + fromHandleX, fromY = fromNode.internals.positionAbsolute.y + fromHandleY, fromPosition = fromHandle == null ? void 0 : fromHandle.position, toPosition = isValid && endPosition ? endPosition : fromPosition ? oppositePosition[fromPosition] : null;
5124
5140
  if (!fromPosition || !toPosition)
5125
5141
  return null;
5126
5142
  if (CustomComponent)
@@ -5164,8 +5180,8 @@ function useStylesLoadedWarning() {
5164
5180
  useStoreApi(), useRef(!1), useEffect(() => {
5165
5181
  }, []);
5166
5182
  }
5167
- function GraphViewComponent({ nodeTypes: nodeTypes2, edgeTypes: edgeTypes2, onInit, onNodeClick, onEdgeClick, onNodeDoubleClick, onEdgeDoubleClick, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, onSelectionContextMenu, onSelectionStart, onSelectionEnd, connectionLineType, connectionLineStyle, connectionLineComponent, connectionLineContainerStyle, selectionKeyCode, selectionOnDrag, selectionMode, multiSelectionKeyCode, panActivationKeyCode, zoomActivationKeyCode, deleteKeyCode, onlyRenderVisibleElements, elementsSelectable, defaultViewport: defaultViewport2, translateExtent, minZoom, maxZoom, preventScrolling, defaultMarkerColor, zoomOnScroll, zoomOnPinch, panOnScroll, panOnScrollSpeed, panOnScrollMode, zoomOnDoubleClick, panOnDrag, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneScroll, onPaneContextMenu, onEdgeUpdate, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, edgeUpdaterRadius, onEdgeUpdateStart, onEdgeUpdateEnd, noDragClassName, noWheelClassName, noPanClassName, disableKeyboardA11y, nodeOrigin, nodeExtent, rfId, viewport, onViewportChange }) {
5168
- return useNodeOrEdgeTypesWarning(nodeTypes2), useNodeOrEdgeTypesWarning(edgeTypes2), useStylesLoadedWarning(), useOnInitHandler(onInit), useViewportSync(viewport), jsx(FlowRenderer, { onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneContextMenu, onPaneScroll, deleteKeyCode, selectionKeyCode, selectionOnDrag, selectionMode, onSelectionStart, onSelectionEnd, multiSelectionKeyCode, panActivationKeyCode, zoomActivationKeyCode, elementsSelectable, zoomOnScroll, zoomOnPinch, zoomOnDoubleClick, panOnScroll, panOnScrollSpeed, panOnScrollMode, panOnDrag, defaultViewport: defaultViewport2, translateExtent, minZoom, maxZoom, onSelectionContextMenu, preventScrolling, noDragClassName, noWheelClassName, noPanClassName, disableKeyboardA11y, onViewportChange, isControlledViewport: !!viewport, children: jsxs(Viewport, { children: [jsx(EdgeRenderer, { edgeTypes: edgeTypes2, onEdgeClick, onEdgeDoubleClick, onEdgeUpdate, onlyRenderVisibleElements, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, onEdgeUpdateStart, onEdgeUpdateEnd, edgeUpdaterRadius, defaultMarkerColor, noPanClassName, disableKeyboardA11y, rfId }), jsx(ConnectionLineWrapper, { style: connectionLineStyle, type: connectionLineType, component: connectionLineComponent, containerStyle: connectionLineContainerStyle }), jsx("div", { className: "react-flow__edgelabel-renderer" }), jsx(NodeRenderer, { nodeTypes: nodeTypes2, onNodeClick, onNodeDoubleClick, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, onlyRenderVisibleElements, noPanClassName, noDragClassName, disableKeyboardA11y, nodeOrigin, nodeExtent, rfId }), jsx("div", { className: "react-flow__viewport-portal" })] }) });
5183
+ function GraphViewComponent({ nodeTypes: nodeTypes2, edgeTypes: edgeTypes2, onInit, onNodeClick, onEdgeClick, onNodeDoubleClick, onEdgeDoubleClick, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, onSelectionContextMenu, onSelectionStart, onSelectionEnd, connectionLineType, connectionLineStyle, connectionLineComponent, connectionLineContainerStyle, selectionKeyCode, selectionOnDrag, selectionMode, multiSelectionKeyCode, panActivationKeyCode, zoomActivationKeyCode, deleteKeyCode, onlyRenderVisibleElements, elementsSelectable, defaultViewport: defaultViewport2, translateExtent, minZoom, maxZoom, preventScrolling, defaultMarkerColor, zoomOnScroll, zoomOnPinch, panOnScroll, panOnScrollSpeed, panOnScrollMode, zoomOnDoubleClick, panOnDrag, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneScroll, onPaneContextMenu, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, reconnectRadius, onReconnect, onReconnectStart, onReconnectEnd, noDragClassName, noWheelClassName, noPanClassName, disableKeyboardA11y, nodeOrigin, nodeExtent, rfId, viewport, onViewportChange }) {
5184
+ return useNodeOrEdgeTypesWarning(nodeTypes2), useNodeOrEdgeTypesWarning(edgeTypes2), useStylesLoadedWarning(), useOnInitHandler(onInit), useViewportSync(viewport), jsx(FlowRenderer, { onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneContextMenu, onPaneScroll, deleteKeyCode, selectionKeyCode, selectionOnDrag, selectionMode, onSelectionStart, onSelectionEnd, multiSelectionKeyCode, panActivationKeyCode, zoomActivationKeyCode, elementsSelectable, zoomOnScroll, zoomOnPinch, zoomOnDoubleClick, panOnScroll, panOnScrollSpeed, panOnScrollMode, panOnDrag, defaultViewport: defaultViewport2, translateExtent, minZoom, maxZoom, onSelectionContextMenu, preventScrolling, noDragClassName, noWheelClassName, noPanClassName, disableKeyboardA11y, onViewportChange, isControlledViewport: !!viewport, children: jsxs(Viewport, { children: [jsx(EdgeRenderer, { edgeTypes: edgeTypes2, onEdgeClick, onEdgeDoubleClick, onReconnect, onReconnectStart, onReconnectEnd, onlyRenderVisibleElements, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, reconnectRadius, defaultMarkerColor, noPanClassName, disableKeyboardA11y, rfId }), jsx(ConnectionLineWrapper, { style: connectionLineStyle, type: connectionLineType, component: connectionLineComponent, containerStyle: connectionLineContainerStyle }), jsx("div", { className: "react-flow__edgelabel-renderer" }), jsx(NodeRenderer, { nodeTypes: nodeTypes2, onNodeClick, onNodeDoubleClick, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, onlyRenderVisibleElements, noPanClassName, noDragClassName, disableKeyboardA11y, nodeOrigin, nodeExtent, rfId }), jsx("div", { className: "react-flow__viewport-portal" })] }) });
5169
5185
  }
5170
5186
  GraphViewComponent.displayName = "GraphView";
5171
5187
  const GraphView = memo(GraphViewComponent), getInitialState = ({ nodes, edges, defaultNodes, defaultEdges, width, height, fitView: fitView2 } = {}) => {
@@ -5219,7 +5235,7 @@ const GraphView = memo(GraphViewComponent), getInitialState = ({ nodes, edges, d
5219
5235
  nodesConnectable: !0,
5220
5236
  nodesFocusable: !0,
5221
5237
  edgesFocusable: !0,
5222
- edgesUpdatable: !0,
5238
+ edgesReconnectable: !0,
5223
5239
  elementsSelectable: !0,
5224
5240
  elevateNodesOnSelect: !0,
5225
5241
  elevateEdgesOnSelect: !1,
@@ -5427,9 +5443,9 @@ const wrapperStyle = {
5427
5443
  position: "relative",
5428
5444
  zIndex: 0
5429
5445
  };
5430
- function ReactFlow({ nodes, edges, defaultNodes, defaultEdges, className, nodeTypes: nodeTypes2, edgeTypes: edgeTypes2, onNodeClick, onEdgeClick, onInit, onMove, onMoveStart, onMoveEnd, onConnect, onConnectStart, onConnectEnd, onClickConnectStart, onClickConnectEnd, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, onNodeDoubleClick, onNodeDragStart, onNodeDrag, onNodeDragStop, onNodesDelete, onEdgesDelete, onDelete, onSelectionChange, onSelectionDragStart, onSelectionDrag, onSelectionDragStop, onSelectionContextMenu, onSelectionStart, onSelectionEnd, onBeforeDelete, connectionMode, connectionLineType = ConnectionLineType.Bezier, connectionLineStyle, connectionLineComponent, connectionLineContainerStyle, deleteKeyCode = "Backspace", selectionKeyCode = "Shift", selectionOnDrag = !1, selectionMode = SelectionMode.Full, panActivationKeyCode = "Space", multiSelectionKeyCode = isMacOs() ? "Meta" : "Control", zoomActivationKeyCode = isMacOs() ? "Meta" : "Control", snapToGrid, snapGrid, onlyRenderVisibleElements = !1, selectNodesOnDrag, nodesDraggable, nodesConnectable, nodesFocusable, nodeOrigin = defaultNodeOrigin, edgesFocusable, edgesUpdatable, elementsSelectable = !0, defaultViewport: defaultViewport$1 = defaultViewport, minZoom = 0.5, maxZoom = 2, translateExtent = infiniteExtent, preventScrolling = !0, nodeExtent, defaultMarkerColor = "#b1b1b7", zoomOnScroll = !0, zoomOnPinch = !0, panOnScroll = !1, panOnScrollSpeed = 0.5, panOnScrollMode = PanOnScrollMode.Free, zoomOnDoubleClick = !0, panOnDrag = !0, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneScroll, onPaneContextMenu, children: children2, onEdgeUpdate, onEdgeContextMenu, onEdgeDoubleClick, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, onEdgeUpdateStart, onEdgeUpdateEnd, edgeUpdaterRadius = 10, onNodesChange, onEdgesChange, noDragClassName = "nodrag", noWheelClassName = "nowheel", noPanClassName = "nopan", fitView: fitView2, fitViewOptions, connectOnClick, attributionPosition, proOptions, defaultEdgeOptions, elevateNodesOnSelect, elevateEdgesOnSelect, disableKeyboardA11y = !1, autoPanOnConnect, autoPanOnNodeDrag, connectionRadius, isValidConnection, onError, style: style2, id: id2, nodeDragThreshold, viewport, onViewportChange, width, height, colorMode = "light", debug, ...rest }, ref) {
5446
+ function ReactFlow({ nodes, edges, defaultNodes, defaultEdges, className, nodeTypes: nodeTypes2, edgeTypes: edgeTypes2, onNodeClick, onEdgeClick, onInit, onMove, onMoveStart, onMoveEnd, onConnect, onConnectStart, onConnectEnd, onClickConnectStart, onClickConnectEnd, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, onNodeDoubleClick, onNodeDragStart, onNodeDrag, onNodeDragStop, onNodesDelete, onEdgesDelete, onDelete, onSelectionChange, onSelectionDragStart, onSelectionDrag, onSelectionDragStop, onSelectionContextMenu, onSelectionStart, onSelectionEnd, onBeforeDelete, connectionMode, connectionLineType = ConnectionLineType.Bezier, connectionLineStyle, connectionLineComponent, connectionLineContainerStyle, deleteKeyCode = "Backspace", selectionKeyCode = "Shift", selectionOnDrag = !1, selectionMode = SelectionMode.Full, panActivationKeyCode = "Space", multiSelectionKeyCode = isMacOs() ? "Meta" : "Control", zoomActivationKeyCode = isMacOs() ? "Meta" : "Control", snapToGrid, snapGrid, onlyRenderVisibleElements = !1, selectNodesOnDrag, nodesDraggable, nodesConnectable, nodesFocusable, nodeOrigin = defaultNodeOrigin, edgesFocusable, edgesReconnectable, elementsSelectable = !0, defaultViewport: defaultViewport$1 = defaultViewport, minZoom = 0.5, maxZoom = 2, translateExtent = infiniteExtent, preventScrolling = !0, nodeExtent, defaultMarkerColor = "#b1b1b7", zoomOnScroll = !0, zoomOnPinch = !0, panOnScroll = !1, panOnScrollSpeed = 0.5, panOnScrollMode = PanOnScrollMode.Free, zoomOnDoubleClick = !0, panOnDrag = !0, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneScroll, onPaneContextMenu, children: children2, onReconnect, onReconnectStart, onReconnectEnd, onEdgeContextMenu, onEdgeDoubleClick, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, reconnectRadius = 10, onNodesChange, onEdgesChange, noDragClassName = "nodrag", noWheelClassName = "nowheel", noPanClassName = "nopan", fitView: fitView2, fitViewOptions, connectOnClick, attributionPosition, proOptions, defaultEdgeOptions, elevateNodesOnSelect, elevateEdgesOnSelect, disableKeyboardA11y = !1, autoPanOnConnect, autoPanOnNodeDrag, connectionRadius, isValidConnection, onError, style: style2, id: id2, nodeDragThreshold, viewport, onViewportChange, width, height, colorMode = "light", debug, ...rest }, ref) {
5431
5447
  const rfId = id2 || "1", colorModeClassName = useColorModeClass(colorMode);
5432
- return jsx("div", { ...rest, style: { ...style2, ...wrapperStyle }, ref, className: cc(["react-flow", className, colorModeClassName]), "data-testid": "rf__wrapper", id: id2, children: jsxs(Wrapper, { nodes, edges, width, height, fitView: fitView2, children: [jsx(GraphView, { onInit, onNodeClick, onEdgeClick, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, onNodeDoubleClick, nodeTypes: nodeTypes2, edgeTypes: edgeTypes2, connectionLineType, connectionLineStyle, connectionLineComponent, connectionLineContainerStyle, selectionKeyCode, selectionOnDrag, selectionMode, deleteKeyCode, multiSelectionKeyCode, panActivationKeyCode, zoomActivationKeyCode, onlyRenderVisibleElements, defaultViewport: defaultViewport$1, translateExtent, minZoom, maxZoom, preventScrolling, zoomOnScroll, zoomOnPinch, zoomOnDoubleClick, panOnScroll, panOnScrollSpeed, panOnScrollMode, panOnDrag, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneScroll, onPaneContextMenu, onSelectionContextMenu, onSelectionStart, onSelectionEnd, onEdgeUpdate, onEdgeContextMenu, onEdgeDoubleClick, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, onEdgeUpdateStart, onEdgeUpdateEnd, edgeUpdaterRadius, defaultMarkerColor, noDragClassName, noWheelClassName, noPanClassName, rfId, disableKeyboardA11y, nodeOrigin, nodeExtent, viewport, onViewportChange }), jsx(StoreUpdater, { nodes, edges, defaultNodes, defaultEdges, onConnect, onConnectStart, onConnectEnd, onClickConnectStart, onClickConnectEnd, nodesDraggable, nodesConnectable, nodesFocusable, edgesFocusable, edgesUpdatable, elementsSelectable, elevateNodesOnSelect, elevateEdgesOnSelect, minZoom, maxZoom, nodeExtent, onNodesChange, onEdgesChange, snapToGrid, snapGrid, connectionMode, translateExtent, connectOnClick, defaultEdgeOptions, fitView: fitView2, fitViewOptions, onNodesDelete, onEdgesDelete, onDelete, onNodeDragStart, onNodeDrag, onNodeDragStop, onSelectionDrag, onSelectionDragStart, onSelectionDragStop, onMove, onMoveStart, onMoveEnd, noPanClassName, nodeOrigin, rfId, autoPanOnConnect, autoPanOnNodeDrag, onError, connectionRadius, isValidConnection, selectNodesOnDrag, nodeDragThreshold, onBeforeDelete, debug }), jsx(SelectionListener, { onSelectionChange }), children2, jsx(Attribution, { proOptions, position: attributionPosition }), jsx(A11yDescriptions, { rfId, disableKeyboardA11y })] }) });
5448
+ return jsx("div", { ...rest, style: { ...style2, ...wrapperStyle }, ref, className: cc(["react-flow", className, colorModeClassName]), "data-testid": "rf__wrapper", id: id2, children: jsxs(Wrapper, { nodes, edges, width, height, fitView: fitView2, children: [jsx(GraphView, { onInit, onNodeClick, onEdgeClick, onNodeMouseEnter, onNodeMouseMove, onNodeMouseLeave, onNodeContextMenu, onNodeDoubleClick, nodeTypes: nodeTypes2, edgeTypes: edgeTypes2, connectionLineType, connectionLineStyle, connectionLineComponent, connectionLineContainerStyle, selectionKeyCode, selectionOnDrag, selectionMode, deleteKeyCode, multiSelectionKeyCode, panActivationKeyCode, zoomActivationKeyCode, onlyRenderVisibleElements, defaultViewport: defaultViewport$1, translateExtent, minZoom, maxZoom, preventScrolling, zoomOnScroll, zoomOnPinch, zoomOnDoubleClick, panOnScroll, panOnScrollSpeed, panOnScrollMode, panOnDrag, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneScroll, onPaneContextMenu, onSelectionContextMenu, onSelectionStart, onSelectionEnd, onReconnect, onReconnectStart, onReconnectEnd, onEdgeContextMenu, onEdgeDoubleClick, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, reconnectRadius, defaultMarkerColor, noDragClassName, noWheelClassName, noPanClassName, rfId, disableKeyboardA11y, nodeOrigin, nodeExtent, viewport, onViewportChange }), jsx(StoreUpdater, { nodes, edges, defaultNodes, defaultEdges, onConnect, onConnectStart, onConnectEnd, onClickConnectStart, onClickConnectEnd, nodesDraggable, nodesConnectable, nodesFocusable, edgesFocusable, edgesReconnectable, elementsSelectable, elevateNodesOnSelect, elevateEdgesOnSelect, minZoom, maxZoom, nodeExtent, onNodesChange, onEdgesChange, snapToGrid, snapGrid, connectionMode, translateExtent, connectOnClick, defaultEdgeOptions, fitView: fitView2, fitViewOptions, onNodesDelete, onEdgesDelete, onDelete, onNodeDragStart, onNodeDrag, onNodeDragStop, onSelectionDrag, onSelectionDragStart, onSelectionDragStop, onMove, onMoveStart, onMoveEnd, noPanClassName, nodeOrigin, rfId, autoPanOnConnect, autoPanOnNodeDrag, onError, connectionRadius, isValidConnection, selectNodesOnDrag, nodeDragThreshold, onBeforeDelete, debug }), jsx(SelectionListener, { onSelectionChange }), children2, jsx(Attribution, { proOptions, position: attributionPosition }), jsx(A11yDescriptions, { rfId, disableKeyboardA11y })] }) });
5433
5449
  }
5434
5450
  var index = fixedForwardRef(ReactFlow);
5435
5451
  const selector$8 = (s) => {
@@ -5450,16 +5466,6 @@ function useOnViewportChange({ onStart, onChange, onEnd }) {
5450
5466
  store.setState({ onViewportChangeEnd: onEnd });
5451
5467
  }, [onEnd]);
5452
5468
  }
5453
- function useOnSelectionChange({ onChange }) {
5454
- const store = useStoreApi();
5455
- useEffect(() => {
5456
- const nextOnSelectionChangeHandlers = [...store.getState().onSelectionChangeHandlers, onChange];
5457
- return store.setState({ onSelectionChangeHandlers: nextOnSelectionChangeHandlers }), () => {
5458
- const nextHandlers = store.getState().onSelectionChangeHandlers.filter((fn) => fn !== onChange);
5459
- store.setState({ onSelectionChangeHandlers: nextHandlers });
5460
- };
5461
- }, [onChange]);
5462
- }
5463
5469
  function useNodesData(nodeIds) {
5464
5470
  return useStore(useCallback((s) => {
5465
5471
  const data = [], isArrayOfIds = Array.isArray(nodeIds), _nodeIds = isArrayOfIds ? nodeIds : [nodeIds];
@@ -7011,24 +7017,7 @@ function useDiagramStoreApi() {
7011
7017
  const store = useContext(DiagramContext);
7012
7018
  if (store === null)
7013
7019
  throw new Error("useDiagramStoreApi could be used only inside DiagramContext");
7014
- return useMemo(
7015
- () => ({
7016
- getState: store.getState,
7017
- setState: store.setState,
7018
- subscribe: store.subscribe
7019
- }),
7020
- [store]
7021
- );
7022
- }
7023
- function WhenInitialized({ children: children2 }) {
7024
- const diagramApi = useDiagramStoreApi(), [isInitialized, setIsInitialized] = useState(diagramApi.getState().initialized);
7025
- return useEffect(() => {
7026
- if (!isInitialized)
7027
- return diagramApi.subscribe(
7028
- (s) => s.initialized,
7029
- setIsInitialized
7030
- );
7031
- }, [isInitialized]), isInitialized ? /* @__PURE__ */ jsx(Fragment, { children: children2 }) : null;
7020
+ return store;
7032
7021
  }
7033
7022
  const { abs: abs$1, cos: cos$1, sin: sin$1, acos: acos$1, atan2, sqrt: sqrt$1, pow } = Math;
7034
7023
  function crt(v) {
@@ -8145,8 +8134,8 @@ function useLayoutConstraints() {
8145
8134
  x: event.clientX,
8146
8135
  y: event.clientY
8147
8136
  };
8148
- const { xyflow } = diagramApi.getState();
8149
- solverRef.current = createLayoutConstraints(xyflow, xyflowApi, xynode.id);
8137
+ const { xyflow, cancelSaveManualLayout } = diagramApi.getState();
8138
+ cancelSaveManualLayout(), solverRef.current = createLayoutConstraints(xyflow, xyflowApi, xynode.id);
8150
8139
  },
8151
8140
  onNodeDrag: (_event, xynode) => {
8152
8141
  var _a;
@@ -8162,7 +8151,6 @@ const ZIndexes = {
8162
8151
  Edge: 2,
8163
8152
  Element: 3
8164
8153
  }, MinZoom = 0.1, StringSet = Set, DEFAULT_PROPS = {
8165
- viewSyncState: "synced",
8166
8154
  viewSyncDebounceTimeout: null,
8167
8155
  initialized: !1,
8168
8156
  xyflowSynced: !1,
@@ -8202,7 +8190,6 @@ function createDiagramStore(props) {
8202
8190
  updateView: (nextView) => {
8203
8191
  let {
8204
8192
  viewSyncDebounceTimeout,
8205
- viewSyncState,
8206
8193
  xyflow,
8207
8194
  dimmed: dimmed2,
8208
8195
  xyflowSynced,
@@ -8216,15 +8203,8 @@ function createDiagramStore(props) {
8216
8203
  hoveredEdgeId,
8217
8204
  hoveredNodeId
8218
8205
  } = get2();
8219
- if (viewSyncDebounceTimeout && (clearTimeout(viewSyncDebounceTimeout), viewSyncDebounceTimeout = null), shallowEqual(current, nextView)) {
8220
- (!xyflowSynced || viewSyncState === "changed") && set2(
8221
- {
8222
- viewSyncState: "synced",
8223
- xyflowSynced: !0
8224
- },
8225
- noReplace,
8226
- "updateView: xyflow synced"
8227
- ), DEV && console.debug("store: skip updateView");
8206
+ if (viewSyncDebounceTimeout !== null && (clearTimeout(viewSyncDebounceTimeout), viewSyncDebounceTimeout = null), shallowEqual(current, nextView)) {
8207
+ DEV && console.debug("store: skip updateView");
8228
8208
  return;
8229
8209
  }
8230
8210
  if (current.id === nextView.id) {
@@ -8245,7 +8225,6 @@ function createDiagramStore(props) {
8245
8225
  }
8246
8226
  set2(
8247
8227
  {
8248
- viewSyncState: "synced",
8249
8228
  viewSyncDebounceTimeout,
8250
8229
  view: nextView,
8251
8230
  activeDynamicViewStep,
@@ -8283,16 +8262,16 @@ function createDiagramStore(props) {
8283
8262
  }
8284
8263
  },
8285
8264
  setHoveredNode: (nodeId) => {
8286
- nodeId !== get2().hoveredNodeId && set2({ hoveredNodeId: nodeId }, noReplace, nodeId ? "setHoveredNode" : "unsetHoveredNode");
8265
+ nodeId !== get2().hoveredNodeId && set2({ hoveredNodeId: nodeId });
8287
8266
  },
8288
8267
  setHoveredEdge: (edgeId) => {
8289
- edgeId !== get2().hoveredEdgeId && set2({ hoveredEdgeId: edgeId }, noReplace, edgeId ? "setHoveredEdge" : "unsetHoveredEdge");
8268
+ edgeId !== get2().hoveredEdgeId && set2({ hoveredEdgeId: edgeId });
8290
8269
  },
8291
8270
  setLastClickedNode: (nodeId) => {
8292
- nodeId !== get2().lastClickedNodeId && set2({ lastClickedNodeId: nodeId }, noReplace, nodeId ? "setLastClickedNode" : "unsetLastClickedNode");
8271
+ nodeId !== get2().lastClickedNodeId && set2({ lastClickedNodeId: nodeId });
8293
8272
  },
8294
8273
  setLastClickedEdge: (edgeId) => {
8295
- edgeId !== get2().lastClickedEdgeId && set2({ lastClickedEdgeId: edgeId }, noReplace, edgeId ? "setLastClickedEdge" : "unsetLastClickedEdge");
8274
+ edgeId !== get2().lastClickedEdgeId && set2({ lastClickedEdgeId: edgeId });
8296
8275
  },
8297
8276
  resetLastClicked: () => {
8298
8277
  let {
@@ -8363,10 +8342,14 @@ function createDiagramStore(props) {
8363
8342
  }
8364
8343
  return element2 !== origin ? (hasChanges = !0, element2) : origin;
8365
8344
  });
8366
- hasChanges && (updateView({
8345
+ hasChanges && updateView({
8367
8346
  ...view,
8368
8347
  nodes
8369
- }), onChange && set2({ viewSyncState: "changed" }, noReplace, "change sync state")), onChange == null || onChange({ change });
8348
+ }), onChange == null || onChange({ change });
8349
+ },
8350
+ cancelSaveManualLayout: () => {
8351
+ let { viewSyncDebounceTimeout } = get2();
8352
+ viewSyncDebounceTimeout !== null && (clearTimeout(viewSyncDebounceTimeout), set2({ viewSyncDebounceTimeout: null }));
8370
8353
  },
8371
8354
  triggerSaveManualLayout: (xystore) => {
8372
8355
  let { viewSyncDebounceTimeout: debounced, onChange } = get2();
@@ -8375,7 +8358,9 @@ function createDiagramStore(props) {
8375
8358
  return;
8376
8359
  }
8377
8360
  debounced && clearTimeout(debounced), debounced = setTimeout(() => {
8378
- const { nodeLookup } = xystore.getState(), { xyflow, onChange: onChange2 } = get2(), movedNodes = new StringSet(), nodes = reduce([...nodeLookup.values()], (acc, node) => {
8361
+ const { nodeLookup } = xystore.getState(), { xyflow, onChange: onChange2 } = get2();
8362
+ set2({ viewSyncDebounceTimeout: null });
8363
+ const movedNodes = new StringSet(), nodes = reduce([...nodeLookup.values()], (acc, node) => {
8379
8364
  const dimensions = getNodeDimensions(node);
8380
8365
  return isSamePoint$1(node.internals.positionAbsolute, node.data.element.position) || movedNodes.add(node.id), acc[node.data.fqn] = {
8381
8366
  x: node.internals.positionAbsolute.x,
@@ -8388,19 +8373,23 @@ function createDiagramStore(props) {
8388
8373
  return !controlPoints && (movedNodes.has(source) || movedNodes.has(target)) && (controlPoints = bezierControlPoints(data.edge)), controlPoints && (acc[data.edge.id] = {
8389
8374
  controlPoints
8390
8375
  }), acc;
8391
- }, {}), change = {
8376
+ }, {});
8377
+ if (movedNodes.size === 0 && isEmpty(edges)) {
8378
+ DEV && console.debug("ignore triggerSaveManualLayout, as no changes detected");
8379
+ return;
8380
+ }
8381
+ const change = {
8392
8382
  op: "save-manual-layout",
8393
8383
  nodes,
8394
8384
  edges
8395
8385
  };
8396
- DEV && console.debug("triggerSaveManualLayout", change), set2({ viewSyncDebounceTimeout: null }, noReplace, "clear debounce timeout"), onChange2 == null || onChange2({ change });
8397
- }, 5e3), set2(
8386
+ DEV && console.debug("triggerSaveManualLayout", change), onChange2 == null || onChange2({ change });
8387
+ }, 2e3), set2(
8398
8388
  {
8399
- viewSyncDebounceTimeout: debounced,
8400
- viewSyncState: "changed"
8389
+ viewSyncDebounceTimeout: debounced
8401
8390
  },
8402
8391
  noReplace,
8403
- "change sync state"
8392
+ "debounce sync state"
8404
8393
  );
8405
8394
  },
8406
8395
  triggerOnNavigateTo: (xynodeId, event) => {
@@ -8863,7 +8852,7 @@ const isSame = (a, b) => Math.abs(a - b) < 3.1, isSamePoint = (a, b) => {
8863
8852
  let hasMoved = !1, pointer2 = { x: e.clientX, y: e.clientY };
8864
8853
  const onPointerMove = (e2) => {
8865
8854
  if (!isSamePoint(pointer2, [e2.clientX, e2.clientY])) {
8866
- hasMoved = !0, pointer2 = { x: e2.clientX, y: e2.clientY };
8855
+ hasMoved || diagramStore.getState().cancelSaveManualLayout(), hasMoved = !0, pointer2 = { x: e2.clientX, y: e2.clientY };
8867
8856
  const { x, y } = xyflow.screenToFlowPosition(pointer2, { snapToGrid: !1 }), newControlPoints = controlPoints.slice();
8868
8857
  newControlPoints[index2] = {
8869
8858
  x: toDomPrecision(x),
@@ -8888,6 +8877,16 @@ const isSame = (a, b) => Math.abs(a - b) < 3.1, isSamePoint = (a, b) => {
8888
8877
  "data-edge-active": isActive,
8889
8878
  "data-edge-hovered": isHovered,
8890
8879
  children: [
8880
+ /* @__PURE__ */ jsx(
8881
+ "path",
8882
+ {
8883
+ className: clsx("react-flow__edge-interaction"),
8884
+ d: edgePath,
8885
+ fill: "none",
8886
+ stroke: "transparent",
8887
+ strokeWidth: interactionWidth ?? 10
8888
+ }
8889
+ ),
8891
8890
  /* @__PURE__ */ jsxs("g", { className: markerContext, children: [
8892
8891
  /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(
8893
8892
  "marker",
@@ -8927,16 +8926,6 @@ const isSame = (a, b) => Math.abs(a - b) < 3.1, isSamePoint = (a, b) => {
8927
8926
  }
8928
8927
  )
8929
8928
  ] }),
8930
- /* @__PURE__ */ jsx(
8931
- "path",
8932
- {
8933
- className: clsx("react-flow__edge-interaction"),
8934
- d: edgePath,
8935
- fill: "none",
8936
- strokeOpacity: 0,
8937
- strokeWidth: interactionWidth ?? 10
8938
- }
8939
- ),
8940
8929
  isEdgePathEditable && controlPoints.map((p, i) => /* @__PURE__ */ jsx(
8941
8930
  "circle",
8942
8931
  {
@@ -9102,7 +9091,7 @@ const isEqualProps$1 = (prev, next) => prev.id === next.id && deepEqual(prev.dat
9102
9091
  }
9103
9092
  );
9104
9093
  }, isEqualProps$1);
9105
- var container$2 = "_1b6tkn2", dimmed = "_1b6tkn3", indicator = "_1b6tkn5", fillElementFill = "_1b6tkn6", fillMixStroke = "_1b6tkn8", title$1 = "_1b6tkn9", description$1 = "_1b6tkna", technology = "_1b6tknb", element = "_1b6tknc", iconMaxH = "var(--_1b6tknd)", elementIcon = "_1b6tkne", cssShapeSvg = "_1b6tknh", cssNavigateBtn = "_1b6tkni";
9094
+ var container$2 = "_1b6tkn2", containerAnimated = "_1b6tkn3", dimmed = "_1b6tkn4", indicator = "_1b6tkn6", fillElementFill = "_1b6tkn7", fillMixStroke = "_1b6tkn9", title$1 = "_1b6tkna", description$1 = "_1b6tknb", technology = "_1b6tknc", element = "_1b6tknd", iconMaxH = "var(--_1b6tkne)", elementIcon = "_1b6tknf", cssShapeSvg = "_1b6tkni", cssNavigateBtn = "_1b6tknj";
9106
9095
  function ElementIcon({
9107
9096
  node,
9108
9097
  paddingY = 32
@@ -9371,13 +9360,13 @@ const selectedScale = 1.015, variants = {
9371
9360
  idle: (_, { scale }) => ({
9372
9361
  scale: 1,
9373
9362
  transition: {
9374
- delay: isNumber(scale) && scale > selectedScale ? 0.075 : 0
9363
+ delay: isNumber(scale) && scale > selectedScale ? 0.09 : 0
9375
9364
  }
9376
9365
  }),
9377
9366
  selected: (_, { scale }) => ({
9378
9367
  scale: selectedScale,
9379
9368
  transition: {
9380
- delay: isNumber(scale) && scale > selectedScale ? 0.075 : 0
9369
+ delay: isNumber(scale) && scale > selectedScale ? 0.09 : 0
9381
9370
  }
9382
9371
  }),
9383
9372
  // dimmed: {
@@ -9401,12 +9390,9 @@ const selectedScale = 1.015, variants = {
9401
9390
  // delay: 1
9402
9391
  // }
9403
9392
  // }),
9404
- hovered: (_, { scale }) => ({
9405
- scale: 1.06,
9406
- transition: {
9407
- delay: isNumber(scale) && scale !== 1 && scale !== selectedScale ? 0 : 0.15
9408
- }
9409
- }),
9393
+ hovered: {
9394
+ scale: 1.06
9395
+ },
9410
9396
  tap: {
9411
9397
  scale: 0.975
9412
9398
  }
@@ -9453,8 +9439,10 @@ const selectedScale = 1.015, variants = {
9453
9439
  className: clsx([
9454
9440
  container$2,
9455
9441
  isDimmed && dimmed,
9442
+ animate !== "idle" && containerAnimated,
9456
9443
  "likec4-element-node"
9457
9444
  ]),
9445
+ "data-hovered": !dragging && isHovered,
9458
9446
  "data-likec4-color": element$1.color,
9459
9447
  "data-likec4-shape": element$1.shape,
9460
9448
  variants,
@@ -9771,7 +9759,88 @@ function XYFlow({
9771
9759
  }
9772
9760
  );
9773
9761
  }
9774
- var container$1 = "hbkbtj0", paper = "hbkbtj1", title = "hbkbtj2", description = "hbkbtj3";
9762
+ function useNavigationHistory() {
9763
+ const store = useDiagramStoreApi(), viewId = useDiagramState((s) => s.view.id), [historyViewId, historyOps, {
9764
+ history,
9765
+ current: historyIndex
9766
+ }] = useStateHistory(viewId), hasBack = historyIndex > 0, hasForward = historyIndex < history.length - 1;
9767
+ return useUpdateEffect(() => {
9768
+ viewId !== historyViewId && historyOps.set(viewId);
9769
+ }, [viewId]), useUpdateEffect(() => {
9770
+ var _a, _b;
9771
+ viewId !== historyViewId && ((_b = (_a = store.getState()).onNavigateTo) == null || _b.call(_a, historyViewId));
9772
+ }, [historyViewId]), useMemo(() => ({
9773
+ hasBack,
9774
+ hasForward,
9775
+ ops: historyOps
9776
+ }), [
9777
+ hasBack,
9778
+ hasForward,
9779
+ historyOps
9780
+ ]);
9781
+ }
9782
+ var panel$1 = "_19mimxc0";
9783
+ function BackwardForwardPanel() {
9784
+ const { hasBack, hasForward, ops } = useNavigationHistory();
9785
+ return /* @__PURE__ */ jsx(
9786
+ Group,
9787
+ {
9788
+ className: clsx(
9789
+ "react-flow__panel",
9790
+ panel$1,
9791
+ "likec4-navigation-panel"
9792
+ ),
9793
+ gap: "xs",
9794
+ children: /* @__PURE__ */ jsxs(AnimatePresence, { children: [
9795
+ hasBack && /* @__PURE__ */ jsx(
9796
+ m.div,
9797
+ {
9798
+ layout: !0,
9799
+ initial: { opacity: 0.05, transform: "translateX(-10px)" },
9800
+ animate: { opacity: 1, transform: "translateX(0)" },
9801
+ exit: {
9802
+ opacity: 0.05,
9803
+ transform: "translateX(-10px)"
9804
+ },
9805
+ children: /* @__PURE__ */ jsx(
9806
+ ActionIcon,
9807
+ {
9808
+ variant: "light",
9809
+ color: "gray",
9810
+ onClick: () => ops.back(),
9811
+ children: /* @__PURE__ */ jsx(IconChevronLeft, {})
9812
+ }
9813
+ )
9814
+ },
9815
+ "back"
9816
+ ),
9817
+ hasForward && /* @__PURE__ */ jsx(
9818
+ m.div,
9819
+ {
9820
+ layout: !0,
9821
+ initial: { opacity: 0.05, transform: "translateX(10px)" },
9822
+ animate: { opacity: 1, transform: "translateX(0)" },
9823
+ exit: {
9824
+ opacity: 0,
9825
+ transform: "translateX(10px)"
9826
+ },
9827
+ children: /* @__PURE__ */ jsx(
9828
+ ActionIcon,
9829
+ {
9830
+ variant: "light",
9831
+ color: "gray",
9832
+ onClick: () => ops.forward(),
9833
+ children: /* @__PURE__ */ jsx(IconChevronRight, {})
9834
+ }
9835
+ )
9836
+ },
9837
+ "forward"
9838
+ )
9839
+ ] })
9840
+ }
9841
+ );
9842
+ }
9843
+ var container$1 = "hbkbtj0", card = "hbkbtj1", title = "hbkbtj2", description = "hbkbtj3";
9775
9844
  const selector = (s) => ({
9776
9845
  id: s.view.id,
9777
9846
  title: s.view.title ?? "untitled",
@@ -9796,16 +9865,29 @@ function DiagramTitlePanel() {
9796
9865
  style: {
9797
9866
  transformOrigin: "left center"
9798
9867
  },
9799
- children: /* @__PURE__ */ jsx(
9800
- Paper,
9868
+ children: /* @__PURE__ */ jsxs(
9869
+ Card,
9801
9870
  {
9802
9871
  radius: "sm",
9803
- withBorder: !isCollapsed,
9804
- className: paper,
9805
- p: isCollapsed ? "xs" : "lg",
9872
+ className: card,
9873
+ p: "md",
9806
9874
  onDoubleClick: (e) => e.stopPropagation(),
9807
- children: /* @__PURE__ */ jsxs(Stack, { gap: "sm", justify: "stretch", align: "stretch", children: [
9808
- /* @__PURE__ */ jsxs(Group, { justify: "stretch", wrap: "nowrap", onClick: toggle, style: { cursor: "pointer" }, children: [
9875
+ children: [
9876
+ /* @__PURE__ */ jsx(CardSection, { mb: 4, children: /* @__PURE__ */ jsx(
9877
+ Button,
9878
+ {
9879
+ fullWidth: !0,
9880
+ size: "xs",
9881
+ h: "sm",
9882
+ py: 2,
9883
+ radius: "0",
9884
+ variant: "subtle",
9885
+ color: "gray",
9886
+ onClick: toggle,
9887
+ children: /* @__PURE__ */ jsx(IconMenu, { size: 11, opacity: 0.7 })
9888
+ }
9889
+ ) }),
9890
+ /* @__PURE__ */ jsxs(Group, { justify: "stretch", wrap: "nowrap", mb: isCollapsed ? 0 : "sm", children: [
9809
9891
  /* @__PURE__ */ jsx(
9810
9892
  Text,
9811
9893
  {
@@ -9903,7 +9985,7 @@ function DiagramTitlePanel() {
9903
9985
  }
9904
9986
  )
9905
9987
  ] })
9906
- ] })
9988
+ ]
9907
9989
  }
9908
9990
  )
9909
9991
  },
@@ -10219,14 +10301,16 @@ function BorderStyleOption({
10219
10301
  ) });
10220
10302
  }
10221
10303
  var panel = "_1lmzt1h0";
10222
- const OptionsPanelMemo = memo(function() {
10223
- const isFocusDisabled = useDiagramState((s) => isNullish(s.focusedNodeId)), [selectedNodes, setSelectedNodes] = useState([]);
10224
- return useOnSelectionChange({
10225
- onChange: ({ nodes }) => {
10226
- const next = nodes.map((n) => n.id);
10227
- setSelectedNodes((prev) => deepEqual(prev, next) ? prev : next);
10228
- }
10229
- }), /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: isFocusDisabled && selectedNodes.length > 0 && /* @__PURE__ */ jsx(
10304
+ const Empty = [];
10305
+ function OptionsPanel() {
10306
+ const { isFocusDisabled, viewId } = useDiagramState((s) => ({
10307
+ viewId: s.view.id,
10308
+ isFocusDisabled: s.focusedNodeId === null && s.activeDynamicViewStep === null
10309
+ })), selectedNodes = useXYStore(
10310
+ useCallback((s) => s.elementsSelectable && isFocusDisabled ? reduce(s.nodes, (acc, n) => (n.selected && acc.push(n.id), acc), []) : Empty, [isFocusDisabled]),
10311
+ shallowEqual
10312
+ );
10313
+ return DEV && useTilg(), /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: selectedNodes.length > 0 && /* @__PURE__ */ jsx(
10230
10314
  m.div,
10231
10315
  {
10232
10316
  initial: { opacity: 0, scale: 0.85 },
@@ -10241,9 +10325,10 @@ const OptionsPanelMemo = memo(function() {
10241
10325
  transformOrigin: "center right"
10242
10326
  },
10243
10327
  children: /* @__PURE__ */ jsx(Card, { shadow: "sm", children: /* @__PURE__ */ jsx(NodeOptions, { selectedNodeIds: selectedNodes }) })
10244
- }
10328
+ },
10329
+ viewId
10245
10330
  ) });
10246
- }), OptionsPanel2 = OptionsPanelMemo;
10331
+ }
10247
10332
  function literalToEnum(value) {
10248
10333
  switch (value) {
10249
10334
  case "dots":
@@ -10267,10 +10352,11 @@ const XYFlowInner = memo(function({
10267
10352
  background,
10268
10353
  controls,
10269
10354
  showDiagramTitle,
10355
+ showNavigationButtons,
10270
10356
  enableDynamicViewWalkthrough
10271
10357
  }) {
10272
10358
  const {
10273
- isDynamicView: isDynamicView2,
10359
+ isDynamicView,
10274
10360
  isDynamicViewActive,
10275
10361
  readonly
10276
10362
  } = useDiagramState((s) => ({
@@ -10281,9 +10367,10 @@ const XYFlowInner = memo(function({
10281
10367
  return /* @__PURE__ */ jsxs(Fragment, { children: [
10282
10368
  background !== "transparent" && background !== "solid" && /* @__PURE__ */ jsx(XYFlowBackground, { background }),
10283
10369
  controls && /* @__PURE__ */ jsx(Controls, { position: "bottom-right" }),
10284
- readonly === !1 && /* @__PURE__ */ jsx(OptionsPanel2, {}),
10370
+ readonly === !1 && /* @__PURE__ */ jsx(OptionsPanel, {}),
10285
10371
  !isDynamicViewActive && showDiagramTitle === !0 && /* @__PURE__ */ jsx(DiagramTitlePanel, {}),
10286
- isDynamicView2 && enableDynamicViewWalkthrough && /* @__PURE__ */ jsx(DynamicViewWalkthrough, {}),
10372
+ isDynamicView && enableDynamicViewWalkthrough && /* @__PURE__ */ jsx(DynamicViewWalkthrough, {}),
10373
+ showNavigationButtons && /* @__PURE__ */ jsx(BackwardForwardPanel, {}),
10287
10374
  children2
10288
10375
  ] });
10289
10376
  }, shallowEqual);
@@ -10301,6 +10388,7 @@ function LikeC4Diagram({
10301
10388
  controls = !1,
10302
10389
  showElementLinks = !0,
10303
10390
  showDiagramTitle = !0,
10391
+ showNavigationButtons = !1,
10304
10392
  enableDynamicViewWalkthrough = !0,
10305
10393
  initialWidth,
10306
10394
  initialHeight,
@@ -10375,6 +10463,7 @@ function LikeC4Diagram({
10375
10463
  controls,
10376
10464
  pannable,
10377
10465
  showDiagramTitle,
10466
+ showNavigationButtons,
10378
10467
  enableDynamicViewWalkthrough
10379
10468
  }
10380
10469
  )
@@ -10394,9 +10483,21 @@ const LikeC4DiagramInnerMemo = memo(function({
10394
10483
  defaultNodes,
10395
10484
  defaultEdges,
10396
10485
  showDiagramTitle,
10486
+ showNavigationButtons,
10397
10487
  enableDynamicViewWalkthrough
10398
10488
  }) {
10399
- return DEV && useTilg(), /* @__PURE__ */ jsxs(Fragment, { children: [
10489
+ DEV && useTilg();
10490
+ const diagramApi = useDiagramStoreApi(), [isInitialized, setIsInitialized] = useState(diagramApi.getState().initialized);
10491
+ return useEffect(() => {
10492
+ if (!isInitialized)
10493
+ return diagramApi.subscribe(
10494
+ (s) => s.initialized,
10495
+ setIsInitialized,
10496
+ {
10497
+ fireImmediately: !0
10498
+ }
10499
+ );
10500
+ }, [isInitialized]), /* @__PURE__ */ jsxs(Fragment, { children: [
10400
10501
  /* @__PURE__ */ jsx(
10401
10502
  XYFlow,
10402
10503
  {
@@ -10412,6 +10513,7 @@ const LikeC4DiagramInnerMemo = memo(function({
10412
10513
  children: /* @__PURE__ */ jsx(
10413
10514
  XYFlowInner,
10414
10515
  {
10516
+ showNavigationButtons,
10415
10517
  showDiagramTitle,
10416
10518
  enableDynamicViewWalkthrough,
10417
10519
  background,
@@ -10420,7 +10522,7 @@ const LikeC4DiagramInnerMemo = memo(function({
10420
10522
  )
10421
10523
  }
10422
10524
  ),
10423
- /* @__PURE__ */ jsxs(WhenInitialized, { children: [
10525
+ isInitialized && /* @__PURE__ */ jsxs(Fragment, { children: [
10424
10526
  /* @__PURE__ */ jsx(SyncWithDiagram, {}),
10425
10527
  fitView2 && /* @__PURE__ */ jsx(FitViewOnDiagramChange, {}),
10426
10528
  fitView2 && zoomable && /* @__PURE__ */ jsx(SelectEdgesOnNodeFocus, {})