@xyflow/react 12.0.0-next.6 → 12.0.0-next.8

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 (111) hide show
  1. package/LICENSE +1 -1
  2. package/dist/base.css +2 -16
  3. package/dist/esm/additional-components/Background/types.d.ts +13 -0
  4. package/dist/esm/additional-components/Background/types.d.ts.map +1 -1
  5. package/dist/esm/additional-components/Controls/types.d.ts +14 -0
  6. package/dist/esm/additional-components/Controls/types.d.ts.map +1 -1
  7. package/dist/esm/additional-components/MiniMap/MiniMap.d.ts.map +1 -1
  8. package/dist/esm/additional-components/MiniMap/types.d.ts +21 -0
  9. package/dist/esm/additional-components/MiniMap/types.d.ts.map +1 -1
  10. package/dist/esm/additional-components/NodeResizer/types.d.ts +25 -0
  11. package/dist/esm/additional-components/NodeResizer/types.d.ts.map +1 -1
  12. package/dist/esm/additional-components/NodeToolbar/types.d.ts +10 -0
  13. package/dist/esm/additional-components/NodeToolbar/types.d.ts.map +1 -1
  14. package/dist/esm/components/EdgeWrapper/EdgeUpdateAnchors.d.ts.map +1 -1
  15. package/dist/esm/components/EdgeWrapper/index.d.ts.map +1 -1
  16. package/dist/esm/components/Handle/index.d.ts +6 -2
  17. package/dist/esm/components/Handle/index.d.ts.map +1 -1
  18. package/dist/esm/components/Panel/index.d.ts +3 -0
  19. package/dist/esm/components/Panel/index.d.ts.map +1 -1
  20. package/dist/esm/container/EdgeRenderer/MarkerDefinitions.d.ts.map +1 -1
  21. package/dist/esm/container/FlowRenderer/index.d.ts.map +1 -1
  22. package/dist/esm/container/ReactFlow/index.d.ts +4 -117
  23. package/dist/esm/container/ReactFlow/index.d.ts.map +1 -1
  24. package/dist/esm/hooks/useConnection.d.ts +13 -7
  25. package/dist/esm/hooks/useConnection.d.ts.map +1 -1
  26. package/dist/esm/hooks/useDrag.d.ts +1 -1
  27. package/dist/esm/hooks/useDrag.d.ts.map +1 -1
  28. package/dist/esm/hooks/useHandleConnections.d.ts +1 -1
  29. package/dist/esm/hooks/useNodesEdgesState.d.ts +2 -2
  30. package/dist/esm/hooks/useNodesEdgesState.d.ts.map +1 -1
  31. package/dist/esm/hooks/useNodesInitialized.d.ts.map +1 -1
  32. package/dist/esm/hooks/useOnSelectionChange.d.ts +1 -1
  33. package/dist/esm/hooks/useUpdateNodePositions.d.ts.map +1 -1
  34. package/dist/esm/index.d.ts +3 -3
  35. package/dist/esm/index.d.ts.map +1 -1
  36. package/dist/esm/index.js +76 -96
  37. package/dist/esm/index.mjs +76 -96
  38. package/dist/esm/store/initialState.d.ts.map +1 -1
  39. package/dist/esm/types/changes.d.ts +2 -2
  40. package/dist/esm/types/changes.d.ts.map +1 -1
  41. package/dist/esm/types/component-props.d.ts +346 -8
  42. package/dist/esm/types/component-props.d.ts.map +1 -1
  43. package/dist/esm/types/edges.d.ts +11 -0
  44. package/dist/esm/types/edges.d.ts.map +1 -1
  45. package/dist/esm/types/general.d.ts +83 -6
  46. package/dist/esm/types/general.d.ts.map +1 -1
  47. package/dist/esm/types/instance.d.ts +93 -9
  48. package/dist/esm/types/instance.d.ts.map +1 -1
  49. package/dist/esm/types/nodes.d.ts +3 -3
  50. package/dist/esm/types/nodes.d.ts.map +1 -1
  51. package/dist/esm/types/store.d.ts +2 -2
  52. package/dist/esm/types/store.d.ts.map +1 -1
  53. package/dist/esm/utils/changes.d.ts +3 -3
  54. package/dist/esm/utils/changes.d.ts.map +1 -1
  55. package/dist/esm/utils/general.d.ts +2 -49
  56. package/dist/esm/utils/general.d.ts.map +1 -1
  57. package/dist/style.css +10 -12
  58. package/dist/umd/additional-components/Background/types.d.ts +13 -0
  59. package/dist/umd/additional-components/Background/types.d.ts.map +1 -1
  60. package/dist/umd/additional-components/Controls/types.d.ts +14 -0
  61. package/dist/umd/additional-components/Controls/types.d.ts.map +1 -1
  62. package/dist/umd/additional-components/MiniMap/MiniMap.d.ts.map +1 -1
  63. package/dist/umd/additional-components/MiniMap/types.d.ts +21 -0
  64. package/dist/umd/additional-components/MiniMap/types.d.ts.map +1 -1
  65. package/dist/umd/additional-components/NodeResizer/types.d.ts +25 -0
  66. package/dist/umd/additional-components/NodeResizer/types.d.ts.map +1 -1
  67. package/dist/umd/additional-components/NodeToolbar/types.d.ts +10 -0
  68. package/dist/umd/additional-components/NodeToolbar/types.d.ts.map +1 -1
  69. package/dist/umd/components/EdgeWrapper/EdgeUpdateAnchors.d.ts.map +1 -1
  70. package/dist/umd/components/EdgeWrapper/index.d.ts.map +1 -1
  71. package/dist/umd/components/Handle/index.d.ts +6 -2
  72. package/dist/umd/components/Handle/index.d.ts.map +1 -1
  73. package/dist/umd/components/Panel/index.d.ts +3 -0
  74. package/dist/umd/components/Panel/index.d.ts.map +1 -1
  75. package/dist/umd/container/EdgeRenderer/MarkerDefinitions.d.ts.map +1 -1
  76. package/dist/umd/container/FlowRenderer/index.d.ts.map +1 -1
  77. package/dist/umd/container/ReactFlow/index.d.ts +4 -117
  78. package/dist/umd/container/ReactFlow/index.d.ts.map +1 -1
  79. package/dist/umd/hooks/useConnection.d.ts +13 -7
  80. package/dist/umd/hooks/useConnection.d.ts.map +1 -1
  81. package/dist/umd/hooks/useDrag.d.ts +1 -1
  82. package/dist/umd/hooks/useDrag.d.ts.map +1 -1
  83. package/dist/umd/hooks/useHandleConnections.d.ts +1 -1
  84. package/dist/umd/hooks/useNodesEdgesState.d.ts +2 -2
  85. package/dist/umd/hooks/useNodesEdgesState.d.ts.map +1 -1
  86. package/dist/umd/hooks/useNodesInitialized.d.ts.map +1 -1
  87. package/dist/umd/hooks/useOnSelectionChange.d.ts +1 -1
  88. package/dist/umd/hooks/useUpdateNodePositions.d.ts.map +1 -1
  89. package/dist/umd/index.d.ts +3 -3
  90. package/dist/umd/index.d.ts.map +1 -1
  91. package/dist/umd/index.js +2 -2
  92. package/dist/umd/store/initialState.d.ts.map +1 -1
  93. package/dist/umd/types/changes.d.ts +2 -2
  94. package/dist/umd/types/changes.d.ts.map +1 -1
  95. package/dist/umd/types/component-props.d.ts +346 -8
  96. package/dist/umd/types/component-props.d.ts.map +1 -1
  97. package/dist/umd/types/edges.d.ts +11 -0
  98. package/dist/umd/types/edges.d.ts.map +1 -1
  99. package/dist/umd/types/general.d.ts +83 -6
  100. package/dist/umd/types/general.d.ts.map +1 -1
  101. package/dist/umd/types/instance.d.ts +93 -9
  102. package/dist/umd/types/instance.d.ts.map +1 -1
  103. package/dist/umd/types/nodes.d.ts +3 -3
  104. package/dist/umd/types/nodes.d.ts.map +1 -1
  105. package/dist/umd/types/store.d.ts +2 -2
  106. package/dist/umd/types/store.d.ts.map +1 -1
  107. package/dist/umd/utils/changes.d.ts +3 -3
  108. package/dist/umd/utils/changes.d.ts.map +1 -1
  109. package/dist/umd/utils/general.d.ts +2 -49
  110. package/dist/umd/utils/general.d.ts.map +1 -1
  111. package/package.json +4 -4
package/dist/esm/index.js CHANGED
@@ -2,8 +2,8 @@
2
2
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
3
  import { createContext, useContext, useMemo, useEffect, useRef, useState, useCallback, forwardRef, memo } from 'react';
4
4
  import cc from 'classcat';
5
- import { errorMessages, infiniteExtent, isInputDOMNode, fitView, getViewportForBounds, pointToRendererPoint, rendererPointToPoint, isNodeBase, isEdgeBase, getOutgoersBase, getIncomersBase, addEdgeBase, updateEdgeBase, getConnectedEdgesBase, getElementsToRemove, isRectObject, nodeToRect, getOverlappingArea, getDimensions, XYPanZoom, PanOnScrollMode, SelectionMode, getEventPosition, getNodesInside, XYDrag, snapPosition, calcNextPosition, Position, isMouseEvent, XYHandle, getHostForElement, getNodesBounds, clampPosition, internalsSymbol, getPositionWithOrigin, elementSelectionKeys, isEdgeVisible, MarkerType, createMarkerIds, isNumeric, getBezierEdgeCenter, getSmoothStepPath, getStraightPath, getBezierPath, getEdgePosition, getElevatedEdgeZIndex, getMarkerId, ConnectionMode, ConnectionLineType, updateConnectionLookup, adoptUserProvidedNodes, updateNodeDimensions, updateAbsolutePositions, panBy, isMacOs, areConnectionMapsEqual, handleConnectionChange, getNodePositionWithOrigin, XYMinimap, getBoundsOfRects, ResizeControlVariant, XYResizer, XY_RESIZER_LINE_POSITIONS, XY_RESIZER_HANDLE_POSITIONS, getNodeToolbarTransform } from '@xyflow/system';
6
- export { ConnectionLineType, ConnectionMode, MarkerType, PanOnScrollMode, Position, SelectionMode, getBezierEdgeCenter, getBezierPath, getEdgeCenter, getNodesBounds, getSmoothStepPath, getStraightPath, getViewportForBounds, internalsSymbol } from '@xyflow/system';
5
+ import { errorMessages, infiniteExtent, isInputDOMNode, fitView, getViewportForBounds, pointToRendererPoint, rendererPointToPoint, isNodeBase, isEdgeBase, getElementsToRemove, isRectObject, nodeToRect, getOverlappingArea, getDimensions, XYPanZoom, PanOnScrollMode, SelectionMode, getEventPosition, getNodesInside, XYDrag, snapPosition, calculateNodePosition, Position, isMouseEvent, XYHandle, getHostForElement, addEdge, getNodesBounds, clampPosition, internalsSymbol, getPositionWithOrigin, elementSelectionKeys, isEdgeVisible, MarkerType, createMarkerIds, isNumeric, getBezierEdgeCenter, getSmoothStepPath, getStraightPath, getBezierPath, getEdgePosition, getElevatedEdgeZIndex, getMarkerId, ConnectionMode, ConnectionLineType, updateConnectionLookup, adoptUserProvidedNodes, devWarn, updateNodeDimensions, updateAbsolutePositions, panBy, isMacOs, areConnectionMapsEqual, handleConnectionChange, getNodePositionWithOrigin, XYMinimap, getBoundsOfRects, ResizeControlVariant, XYResizer, XY_RESIZER_LINE_POSITIONS, XY_RESIZER_HANDLE_POSITIONS, getNodeToolbarTransform } from '@xyflow/system';
6
+ export { ConnectionLineType, ConnectionMode, MarkerType, PanOnScrollMode, Position, SelectionMode, addEdge, getBezierEdgeCenter, getBezierPath, getConnectedEdges, getEdgeCenter, getIncomers, getNodesBounds, getOutgoers, getSmoothStepPath, getStraightPath, getViewportForBounds, internalsSymbol, updateEdge } from '@xyflow/system';
7
7
  import { useStoreWithEqualityFn, createWithEqualityFn } from 'zustand/traditional';
8
8
  import { shallow } from 'zustand/shallow';
9
9
  import { createPortal } from 'react-dom';
@@ -424,25 +424,25 @@ const useViewportHelper = () => {
424
424
  const viewport = getViewportForBounds(bounds, width, height, minZoom, maxZoom, options?.padding ?? 0.1);
425
425
  panZoom?.setViewport(viewport, { duration: options?.duration });
426
426
  },
427
- screenToFlowPosition: (position) => {
428
- const { transform, snapToGrid, snapGrid, domNode } = store.getState();
427
+ screenToFlowPosition: (clientPosition, options = { snapToGrid: true }) => {
428
+ const { transform, snapGrid, domNode } = store.getState();
429
429
  if (!domNode) {
430
- return position;
430
+ return clientPosition;
431
431
  }
432
432
  const { x: domX, y: domY } = domNode.getBoundingClientRect();
433
433
  const correctedPosition = {
434
- x: position.x - domX,
435
- y: position.y - domY,
434
+ x: clientPosition.x - domX,
435
+ y: clientPosition.y - domY,
436
436
  };
437
- return pointToRendererPoint(correctedPosition, transform, snapToGrid, snapGrid || [1, 1]);
437
+ return pointToRendererPoint(correctedPosition, transform, options.snapToGrid, snapGrid);
438
438
  },
439
- flowToScreenPosition: (position) => {
439
+ flowToScreenPosition: (flowPosition) => {
440
440
  const { transform, domNode } = store.getState();
441
441
  if (!domNode) {
442
- return position;
442
+ return flowPosition;
443
443
  }
444
444
  const { x: domX, y: domY } = domNode.getBoundingClientRect();
445
- const rendererPosition = rendererPointToPoint(position, transform);
445
+ const rendererPosition = rendererPointToPoint(flowPosition, transform);
446
446
  return {
447
447
  x: rendererPosition.x + domX,
448
448
  y: rendererPosition.y + domY,
@@ -458,9 +458,7 @@ function handleParentExpand(updatedElements, updateItem) {
458
458
  for (const [index, item] of updatedElements.entries()) {
459
459
  if (item.id === updateItem.parentNode) {
460
460
  const parent = { ...item };
461
- if (!parent.computed) {
462
- parent.computed = {};
463
- }
461
+ parent.computed ??= {};
464
462
  const extendWidth = updateItem.position.x + updateItem.computed.width - parent.computed.width;
465
463
  const extendHeight = updateItem.position.y + updateItem.computed.height - parent.computed.height;
466
464
  if (extendWidth > 0 || extendHeight > 0 || updateItem.position.x < 0 || updateItem.position.y < 0) {
@@ -543,7 +541,7 @@ function applyChanges(changes, elements) {
543
541
  /// each _mutate_ this object, so there's only ever one copy.
544
542
  const updatedElement = { ...element };
545
543
  for (const change of changes) {
546
- applyChange(change, updatedElement, elements);
544
+ applyChange(change, updatedElement, updatedElements);
547
545
  }
548
546
  updatedElements.push(updatedElement);
549
547
  }
@@ -688,7 +686,7 @@ function getElementsDiffChanges({ items = [], lookup, }) {
688
686
  * @param element - The element to test
689
687
  * @returns A boolean indicating whether the element is an Node
690
688
  */
691
- const isNode = (isNodeBase);
689
+ const isNode = (element) => isNodeBase(element);
692
690
  /**
693
691
  * Test whether an object is useable as an Edge
694
692
  * @public
@@ -696,50 +694,7 @@ const isNode = (isNodeBase);
696
694
  * @param element - The element to test
697
695
  * @returns A boolean indicating whether the element is an Edge
698
696
  */
699
- const isEdge = (isEdgeBase);
700
- /**
701
- * Pass in a node, and get connected nodes where edge.source === node.id
702
- * @public
703
- * @param node - The node to get the connected nodes from
704
- * @param nodes - The array of all nodes
705
- * @param edges - The array of all edges
706
- * @returns An array of nodes that are connected over eges where the source is the given node
707
- */
708
- const getOutgoers = (getOutgoersBase);
709
- /**
710
- * Pass in a node, and get connected nodes where edge.target === node.id
711
- * @public
712
- * @param node - The node to get the connected nodes from
713
- * @param nodes - The array of all nodes
714
- * @param edges - The array of all edges
715
- * @returns An array of nodes that are connected over eges where the target is the given node
716
- */
717
- const getIncomers = (getIncomersBase);
718
- /**
719
- * This util is a convenience function to add a new Edge to an array of edges
720
- * @remarks It also performs some validation to make sure you don't add an invalid edge or duplicate an existing one.
721
- * @public
722
- * @param edgeParams - Either an Edge or a Connection you want to add
723
- * @param edges - The array of all current edges
724
- * @returns A new array of edges with the new edge added
725
- */
726
- const addEdge = (addEdgeBase);
727
- /**
728
- * A handy utility to update an existing Edge with new properties
729
- * @param oldEdge - The edge you want to update
730
- * @param newConnection - The new connection you want to update the edge with
731
- * @param edges - The array of all current edges
732
- * @param options.shouldReplaceId - should the id of the old edge be replaced with the new connection id
733
- * @returns the updated edges array
734
- */
735
- const updateEdge = (updateEdgeBase);
736
- /**
737
- * Get all connecting edges for a given set of nodes
738
- * @param nodes - Nodes you want to get the connected edges for
739
- * @param edges - All edges
740
- * @returns Array of edges that connect any of the given nodes with each other
741
- */
742
- const getConnectedEdges = (getConnectedEdgesBase);
697
+ const isEdge = (element) => isEdgeBase(element);
743
698
 
744
699
  /**
745
700
  * Hook for accessing the ReactFlow instance.
@@ -883,6 +838,9 @@ function useReactFlow() {
883
838
  const getNodeRect = useCallback((nodeOrRect) => {
884
839
  const isRect = isRectObject(nodeOrRect);
885
840
  const node = isRect ? null : store.getState().nodeLookup.get(nodeOrRect.id);
841
+ if (!isRect && !node) {
842
+ return [null, null, isRect];
843
+ }
886
844
  const nodeRect = isRect ? nodeOrRect : nodeToRect(node);
887
845
  return [nodeRect, node, isRect];
888
846
  }, []);
@@ -1304,7 +1262,7 @@ function useDrag({ nodeRef, disabled = false, noDragClassName, handleSelector, n
1304
1262
  handleNodeClick({
1305
1263
  id,
1306
1264
  store,
1307
- nodeRef: nodeRef,
1265
+ nodeRef,
1308
1266
  });
1309
1267
  },
1310
1268
  onDragStart: () => {
@@ -1346,7 +1304,7 @@ const selectedAndDraggable = (nodesDraggable) => (n) => n.selected && (n.draggab
1346
1304
  function useUpdateNodePositions() {
1347
1305
  const store = useStoreApi();
1348
1306
  const updatePositions = useCallback((params) => {
1349
- const { nodeExtent, nodes, snapToGrid, snapGrid, nodesDraggable, onError, updateNodePositions } = store.getState();
1307
+ const { nodeExtent, nodes, snapToGrid, snapGrid, nodesDraggable, onError, updateNodePositions, nodeLookup, nodeOrigin, } = store.getState();
1350
1308
  const selectedNodes = nodes.filter(selectedAndDraggable(nodesDraggable));
1351
1309
  // by default a node moves 5px on each key press, or 20px if shift is pressed
1352
1310
  // if snap grid is enabled, we use that for the velocity.
@@ -1358,17 +1316,21 @@ function useUpdateNodePositions() {
1358
1316
  const nodeUpdates = selectedNodes.map((node) => {
1359
1317
  if (node.computed?.positionAbsolute) {
1360
1318
  let nextPosition = {
1361
- x: node.computed?.positionAbsolute.x + xDiff,
1362
- y: node.computed?.positionAbsolute.y + yDiff,
1319
+ x: node.computed.positionAbsolute.x + xDiff,
1320
+ y: node.computed.positionAbsolute.y + yDiff,
1363
1321
  };
1364
1322
  if (snapToGrid) {
1365
1323
  nextPosition = snapPosition(nextPosition, snapGrid);
1366
1324
  }
1367
- const { positionAbsolute, position } = calcNextPosition(node, nextPosition, nodes, nodeExtent, undefined, onError);
1325
+ const { position, positionAbsolute } = calculateNodePosition({
1326
+ nodeId: node.id,
1327
+ nextPosition,
1328
+ nodeLookup,
1329
+ nodeExtent,
1330
+ nodeOrigin,
1331
+ onError,
1332
+ });
1368
1333
  node.position = position;
1369
- if (!node.computed) {
1370
- node.computed = {};
1371
- }
1372
1334
  node.computed.positionAbsolute = positionAbsolute;
1373
1335
  }
1374
1336
  return node;
@@ -1387,9 +1349,9 @@ const useNodeId = () => {
1387
1349
  };
1388
1350
 
1389
1351
  const selector$i = (s) => ({
1390
- connectionStartHandle: s.connectionStartHandle,
1391
1352
  connectOnClick: s.connectOnClick,
1392
1353
  noPanClassName: s.noPanClassName,
1354
+ rfId: s.rfId,
1393
1355
  });
1394
1356
  const connectingSelector = (nodeId, handleId, type) => (state) => {
1395
1357
  const { connectionStartHandle: startHandle, connectionEndHandle: endHandle, connectionClickStartHandle: clickHandle, } = state;
@@ -1404,7 +1366,7 @@ const HandleComponent = forwardRef(({ type = 'source', position = Position.Top,
1404
1366
  const isTarget = type === 'target';
1405
1367
  const store = useStoreApi();
1406
1368
  const nodeId = useNodeId();
1407
- const { connectOnClick, noPanClassName } = useStore(selector$i, shallow);
1369
+ const { connectOnClick, noPanClassName, rfId } = useStore(selector$i, shallow);
1408
1370
  const { connecting, clickConnecting } = useStore(connectingSelector(nodeId, handleId, type), shallow);
1409
1371
  if (!nodeId) {
1410
1372
  store.getState().onError?.('010', errorMessages['error010']());
@@ -1440,6 +1402,7 @@ const HandleComponent = forwardRef(({ type = 'source', position = Position.Top,
1440
1402
  isTarget,
1441
1403
  handleId,
1442
1404
  nodeId,
1405
+ flowId: currentStore.rfId,
1443
1406
  panBy: currentStore.panBy,
1444
1407
  cancelConnection: currentStore.cancelConnection,
1445
1408
  onConnectStart: currentStore.onConnectStart,
@@ -1458,7 +1421,7 @@ const HandleComponent = forwardRef(({ type = 'source', position = Position.Top,
1458
1421
  }
1459
1422
  };
1460
1423
  const onClick = (event) => {
1461
- const { onClickConnectStart, onClickConnectEnd, connectionClickStartHandle, connectionMode, isValidConnection: isValidConnectionStore, lib, } = store.getState();
1424
+ const { onClickConnectStart, onClickConnectEnd, connectionClickStartHandle, connectionMode, isValidConnection: isValidConnectionStore, lib, rfId: flowId, } = store.getState();
1462
1425
  if (!nodeId || (!connectionClickStartHandle && !isConnectableStart)) {
1463
1426
  return;
1464
1427
  }
@@ -1480,6 +1443,7 @@ const HandleComponent = forwardRef(({ type = 'source', position = Position.Top,
1480
1443
  fromHandleId: connectionClickStartHandle.handleId || null,
1481
1444
  fromType: connectionClickStartHandle.type,
1482
1445
  isValidConnection: isValidConnectionHandler,
1446
+ flowId,
1483
1447
  doc,
1484
1448
  lib,
1485
1449
  });
@@ -1489,7 +1453,7 @@ const HandleComponent = forwardRef(({ type = 'source', position = Position.Top,
1489
1453
  onClickConnectEnd?.(event);
1490
1454
  store.setState({ connectionClickStartHandle: null });
1491
1455
  };
1492
- return (jsx("div", { "data-handleid": handleId, "data-nodeid": nodeId, "data-handlepos": position, "data-id": `${nodeId}-${handleId}-${type}`, className: cc([
1456
+ return (jsx("div", { "data-handleid": handleId, "data-nodeid": nodeId, "data-handlepos": position, "data-id": `${rfId}-${nodeId}-${handleId}-${type}`, className: cc([
1493
1457
  'react-flow__handle',
1494
1458
  `react-flow__handle-${position}`,
1495
1459
  'nodrag',
@@ -1508,6 +1472,9 @@ const HandleComponent = forwardRef(({ type = 'source', position = Position.Top,
1508
1472
  ]), onMouseDown: onPointerDown, onTouchStart: onPointerDown, onClick: connectOnClick ? onClick : undefined, ref: ref, ...rest, children: children }));
1509
1473
  });
1510
1474
  HandleComponent.displayName = 'Handle';
1475
+ /**
1476
+ * The Handle component is the part of a node that can be used to connect nodes.
1477
+ */
1511
1478
  const Handle = memo(HandleComponent);
1512
1479
 
1513
1480
  function InputNode({ data, isConnectable, sourcePosition = Position.Bottom }) {
@@ -1541,7 +1508,7 @@ const builtinNodeTypes = {
1541
1508
 
1542
1509
  const selector$h = (s) => {
1543
1510
  const selectedNodes = s.nodes.filter((n) => n.selected);
1544
- const { width, height, x, y } = getNodesBounds(selectedNodes, s.nodeOrigin);
1511
+ const { width, height, x, y } = getNodesBounds(selectedNodes, { nodeOrigin: s.nodeOrigin });
1545
1512
  return {
1546
1513
  width,
1547
1514
  height,
@@ -1590,14 +1557,16 @@ function NodesSelection({ onSelectionContextMenu, noPanClassName, disableKeyboar
1590
1557
  } }) }));
1591
1558
  }
1592
1559
 
1593
- const selector$g = (s) => s.nodesSelectionActive;
1560
+ const selector$g = (s) => {
1561
+ return { nodesSelectionActive: s.nodesSelectionActive, userSelectionActive: s.userSelectionActive };
1562
+ };
1594
1563
  const FlowRendererComponent = ({ children, 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, translateExtent, minZoom, maxZoom, preventScrolling, onSelectionContextMenu, noWheelClassName, noPanClassName, disableKeyboardA11y, onViewportChange, isControlledViewport, }) => {
1595
- const nodesSelectionActive = useStore(selector$g);
1564
+ const { nodesSelectionActive, userSelectionActive } = useStore(selector$g);
1596
1565
  const selectionKeyPressed = useKeyPress(selectionKeyCode);
1597
1566
  const panActivationKeyPressed = useKeyPress(panActivationKeyCode);
1598
1567
  const panOnDrag = panActivationKeyPressed || _panOnDrag;
1599
1568
  const panOnScroll = panActivationKeyPressed || _panOnScroll;
1600
- const isSelecting = selectionKeyPressed || (selectionOnDrag && panOnDrag !== true);
1569
+ const isSelecting = selectionKeyPressed || userSelectionActive || (selectionOnDrag && panOnDrag !== true);
1601
1570
  useGlobalKeyHandler({ deleteKeyCode, multiSelectionKeyCode });
1602
1571
  return (jsx(ZoomPane, { onPaneContextMenu: onPaneContextMenu, elementsSelectable: elementsSelectable, zoomOnScroll: zoomOnScroll, zoomOnPinch: zoomOnPinch, panOnScroll: panOnScroll, panOnScrollSpeed: panOnScrollSpeed, panOnScrollMode: panOnScrollMode, zoomOnDoubleClick: zoomOnDoubleClick, panOnDrag: !selectionKeyPressed && panOnDrag, defaultViewport: defaultViewport, translateExtent: translateExtent, minZoom: minZoom, maxZoom: maxZoom, zoomActivationKeyCode: zoomActivationKeyCode, preventScrolling: preventScrolling, noWheelClassName: noWheelClassName, noPanClassName: noPanClassName, onViewportChange: onViewportChange, isControlledViewport: isControlledViewport, children: jsxs(Pane, { onSelectionStart: onSelectionStart, onSelectionEnd: onSelectionEnd, onPaneClick: onPaneClick, onPaneMouseEnter: onPaneMouseEnter, onPaneMouseMove: onPaneMouseMove, onPaneMouseLeave: onPaneMouseLeave, onPaneContextMenu: onPaneContextMenu, onPaneScroll: onPaneScroll, panOnDrag: panOnDrag, isSelecting: !!isSelecting, selectionMode: selectionMode, children: [children, nodesSelectionActive && (jsx(NodesSelection, { onSelectionContextMenu: onSelectionContextMenu, noPanClassName: noPanClassName, disableKeyboardA11y: disableKeyboardA11y }))] }) }));
1603
1572
  };
@@ -1922,18 +1891,21 @@ const Marker = ({ id, type, color, width = 12.5, height = 12.5, markerUnits = 's
1922
1891
  }
1923
1892
  return (jsx("marker", { className: "react-flow__arrowhead", id: id, markerWidth: `${width}`, markerHeight: `${height}`, viewBox: "-10 -10 20 20", markerUnits: markerUnits, orient: orient, refX: "0", refY: "0", children: jsx(Symbol, { color: color, strokeWidth: strokeWidth }) }));
1924
1893
  };
1925
- const markerSelector = ({ defaultColor, rfId }) => (s) => {
1926
- const markers = createMarkerIds(s.edges, { id: rfId, defaultColor });
1927
- return markers;
1928
- };
1929
- const markersEqual = (a, b) =>
1930
- // the id includes all marker options, so we just need to look at that part of the marker
1931
- !(a.length !== b.length || a.some((m, i) => m.id !== b[i].id));
1932
1894
  // when you have multiple flows on a page and you hide the first one, the other ones have no markers anymore
1933
1895
  // when they do have markers with the same ids. To prevent this the user can pass a unique id to the react flow wrapper
1934
1896
  // that we can then use for creating our unique marker ids
1935
1897
  const MarkerDefinitions = ({ defaultColor, rfId }) => {
1936
- const markers = useStore(useCallback(markerSelector({ defaultColor, rfId }), [defaultColor, rfId]), markersEqual);
1898
+ const edges = useStore((s) => s.edges);
1899
+ const defaultEdgeOptions = useStore((s) => s.defaultEdgeOptions);
1900
+ const markers = useMemo(() => {
1901
+ const markers = createMarkerIds(edges, {
1902
+ id: rfId,
1903
+ defaultColor,
1904
+ defaultMarkerStart: defaultEdgeOptions?.markerStart,
1905
+ defaultMarkerEnd: defaultEdgeOptions?.markerEnd,
1906
+ });
1907
+ return markers;
1908
+ }, [edges, defaultEdgeOptions, rfId, defaultColor]);
1937
1909
  if (!markers.length) {
1938
1910
  return null;
1939
1911
  }
@@ -2137,7 +2109,7 @@ function EdgeUpdateAnchors({ isUpdatable, edgeUpdaterRadius, edge, targetHandleI
2137
2109
  if (event.button !== 0) {
2138
2110
  return;
2139
2111
  }
2140
- const { autoPanOnConnect, domNode, isValidConnection, connectionMode, connectionRadius, lib, onConnectStart, onConnectEnd, cancelConnection, nodes, panBy, updateConnection, } = store.getState();
2112
+ const { autoPanOnConnect, domNode, isValidConnection, connectionMode, connectionRadius, lib, onConnectStart, onConnectEnd, cancelConnection, nodes, rfId: flowId, panBy, updateConnection, } = store.getState();
2141
2113
  const nodeId = isSourceHandle ? edge.target : edge.source;
2142
2114
  const handleId = (isSourceHandle ? targetHandleId : sourceHandleId) || null;
2143
2115
  const handleType = isSourceHandle ? 'target' : 'source';
@@ -2160,6 +2132,7 @@ function EdgeUpdateAnchors({ isUpdatable, edgeUpdaterRadius, edge, targetHandleI
2160
2132
  isTarget,
2161
2133
  edgeUpdaterType: handleType,
2162
2134
  lib,
2135
+ flowId,
2163
2136
  cancelConnection,
2164
2137
  panBy,
2165
2138
  isValidConnection,
@@ -2296,6 +2269,7 @@ function EdgeWrapper({ id, edgesFocusable, edgesUpdatable, elementsSelectable, o
2296
2269
  animated: edge.animated,
2297
2270
  inactive: !isSelectable && !onClick,
2298
2271
  updating: updateHover,
2272
+ selectable: isSelectable,
2299
2273
  },
2300
2274
  ]), onClick: onEdgeClick, onDoubleClick: onEdgeDoubleClick, onContextMenu: onEdgeContextMenu, onMouseEnter: onEdgeMouseEnter, onMouseMove: onEdgeMouseMove, onMouseLeave: onEdgeMouseLeave, onKeyDown: isFocusable ? onKeyDown : undefined, tabIndex: isFocusable ? 0 : undefined, role: isFocusable ? 'button' : 'img', "data-id": id, "data-testid": `rf__edge-${id}`, "aria-label": edge.ariaLabel === null ? undefined : edge.ariaLabel || `Edge from ${edge.source} to ${edge.target}`, "aria-describedby": isFocusable ? `${ARIA_EDGE_DESC_KEY}-${rfId}` : undefined, ref: edgeRef, children: [!updating && (jsx(EdgeComponent, { id: id, source: edge.source, target: edge.target, selected: edge.selected, animated: edge.animated, label: edge.label, labelStyle: edge.labelStyle, labelShowBg: edge.labelShowBg, labelBgStyle: edge.labelBgStyle, labelBgPadding: edge.labelBgPadding, labelBgBorderRadius: edge.labelBgBorderRadius, sourceX: sourceX, sourceY: sourceY, targetX: targetX, targetY: targetY, sourcePosition: sourcePosition, targetPosition: targetPosition, data: edge.data, style: edge.style, sourceHandleId: edge.sourceHandle, targetHandleId: edge.targetHandle, markerStart: markerStartUrl, markerEnd: markerEndUrl, pathOptions: 'pathOptions' in edge ? edge.pathOptions : undefined, interactionWidth: edge.interactionWidth })), isUpdatable && (jsx(EdgeUpdateAnchors, { edge: edge, isUpdatable: isUpdatable, edgeUpdaterRadius: edgeUpdaterRadius, onEdgeUpdate: onEdgeUpdate, onEdgeUpdateStart: onEdgeUpdateStart, onEdgeUpdateEnd: onEdgeUpdateEnd, sourceX: sourceX, sourceY: sourceY, targetX: targetX, targetY: targetY, sourcePosition: sourcePosition, targetPosition: targetPosition, setUpdateHover: setUpdateHover, setUpdating: setUpdating, sourceHandleId: edge.sourceHandle, targetHandleId: edge.targetHandle }))] }) }));
2301
2275
  }
@@ -2505,7 +2479,8 @@ const getInitialState = ({ nodes = [], edges = [], width, height, fitView, } = {
2505
2479
  let transform = [0, 0, 1];
2506
2480
  if (fitView && width && height) {
2507
2481
  const nodesWithDimensions = nextNodes.filter((node) => node.width && node.height);
2508
- const bounds = getNodesBounds(nodesWithDimensions, [0, 0]);
2482
+ // @todo users nodeOrigin should be used here
2483
+ const bounds = getNodesBounds(nodesWithDimensions, { nodeOrigin: [0, 0] });
2509
2484
  const { x, y, zoom } = getViewportForBounds(bounds, width, height, 0.5, 2, 0.1);
2510
2485
  transform = [x, y, zoom];
2511
2486
  }
@@ -2562,7 +2537,7 @@ const getInitialState = ({ nodes = [], edges = [], width, height, fitView, } = {
2562
2537
  autoPanOnConnect: true,
2563
2538
  autoPanOnNodeDrag: true,
2564
2539
  connectionRadius: 20,
2565
- onError: () => null,
2540
+ onError: devWarn,
2566
2541
  isValidConnection: undefined,
2567
2542
  onSelectionChangeHandlers: [],
2568
2543
  lib: 'react',
@@ -2985,7 +2960,7 @@ function useOnViewportChange({ onStart, onChange, onEnd }) {
2985
2960
  * Hook for registering an onSelectionChange handler.
2986
2961
  *
2987
2962
  * @public
2988
- * @params params.onChange - The handler to register
2963
+ * @param params.onChange - The handler to register
2989
2964
  */
2990
2965
  function useOnSelectionChange({ onChange }) {
2991
2966
  const store = useStoreApi();
@@ -3003,9 +2978,14 @@ const selector$6 = (options) => (s) => {
3003
2978
  if (s.nodes.length === 0) {
3004
2979
  return false;
3005
2980
  }
3006
- return s.nodes
3007
- .filter((n) => (options.includeHiddenNodes ? true : !n.hidden))
3008
- .every((n) => n[internalsSymbol]?.handleBounds !== undefined);
2981
+ for (const node of s.nodes) {
2982
+ if (options.includeHiddenNodes || !node.hidden) {
2983
+ if (node[internalsSymbol]?.handleBounds === undefined) {
2984
+ return false;
2985
+ }
2986
+ }
2987
+ }
2988
+ return true;
3009
2989
  };
3010
2990
  const defaultOptions = {
3011
2991
  includeHiddenNodes: false,
@@ -3023,7 +3003,7 @@ function useNodesInitialized(options = defaultOptions) {
3023
3003
  }
3024
3004
 
3025
3005
  /**
3026
- * Hook to check if a <Handle /> is connected to another <Handle /> and get the connections.
3006
+ * Hook to check if a <Handle /> is connected to another <Handle /> and get the connections.
3027
3007
  *
3028
3008
  * @public
3029
3009
  * @param param.type - handle type 'source' or 'target'
@@ -3078,7 +3058,7 @@ const selector$5 = (s) => ({
3078
3058
  * Hook for accessing the ongoing connection.
3079
3059
  *
3080
3060
  * @public
3081
- * @returns ongoing connection: startHandle, endHandle, status, position
3061
+ * @returns ongoing connection
3082
3062
  */
3083
3063
  function useConnection() {
3084
3064
  const ongoingConnection = useStore(selector$5, shallow);
@@ -3251,7 +3231,7 @@ const selector$1 = (s) => {
3251
3231
  };
3252
3232
  return {
3253
3233
  viewBB,
3254
- boundingRect: s.nodes.length > 0 ? getBoundsOfRects(getNodesBounds(s.nodes, s.nodeOrigin), viewBB) : viewBB,
3234
+ boundingRect: s.nodes.length > 0 ? getBoundsOfRects(getNodesBounds(s.nodes, { nodeOrigin: s.nodeOrigin }), viewBB) : viewBB,
3255
3235
  rfId: s.rfId,
3256
3236
  nodeOrigin: s.nodeOrigin,
3257
3237
  panZoom: s.panZoom,
@@ -3487,7 +3467,7 @@ function NodeToolbar({ nodeId, children, className, style, isVisible, position =
3487
3467
  if (!isActive || !nodes.length) {
3488
3468
  return null;
3489
3469
  }
3490
- const nodeRect = getNodesBounds(nodes, nodeOrigin);
3470
+ const nodeRect = getNodesBounds(nodes, { nodeOrigin });
3491
3471
  const zIndex = Math.max(...nodes.map((node) => (node[internalsSymbol]?.z || 1) + 1));
3492
3472
  const wrapperStyle = {
3493
3473
  position: 'absolute',
@@ -3498,4 +3478,4 @@ function NodeToolbar({ nodeId, children, className, style, isVisible, position =
3498
3478
  return (jsx(NodeToolbarPortal, { children: jsx("div", { style: wrapperStyle, className: cc(['react-flow__node-toolbar', className]), ...rest, "data-id": nodes.reduce((acc, node) => `${acc}${node.id} `, '').trim(), children: children }) }));
3499
3479
  }
3500
3480
 
3501
- export { Background, BackgroundVariant, BaseEdge, BezierEdge, ControlButton, Controls, EdgeLabelRenderer, EdgeText, Handle, MiniMap, NodeResizeControl, NodeResizer, NodeToolbar, Panel, ReactFlow, ReactFlowProvider, SimpleBezierEdge, SmoothStepEdge, StepEdge, StraightEdge, ViewportPortal, addEdge, applyEdgeChanges, applyNodeChanges, getConnectedEdges, getIncomers, getOutgoers, getSimpleBezierPath, handleParentExpand, isEdge, isNode, updateEdge, useConnection, useEdges, useEdgesState, useHandleConnections, useKeyPress, useNodeId, useNodes, useNodesData, useNodesInitialized, useNodesState, useOnSelectionChange, useOnViewportChange, useReactFlow, useStore, useStoreApi, useUpdateNodeInternals, useViewport };
3481
+ export { Background, BackgroundVariant, BaseEdge, BezierEdge, ControlButton, Controls, EdgeLabelRenderer, EdgeText, Handle, MiniMap, NodeResizeControl, NodeResizer, NodeToolbar, Panel, ReactFlow, ReactFlowProvider, SimpleBezierEdge, SmoothStepEdge, StepEdge, StraightEdge, ViewportPortal, applyEdgeChanges, applyNodeChanges, getSimpleBezierPath, handleParentExpand, isEdge, isNode, useConnection, useEdges, useEdgesState, useHandleConnections, useKeyPress, useNodeId, useNodes, useNodesData, useNodesInitialized, useNodesState, useOnSelectionChange, useOnViewportChange, useReactFlow, useStore, useStoreApi, useUpdateNodeInternals, useViewport };