@xyflow/react 12.0.0-next.0 → 12.0.0-next.10

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 (409) hide show
  1. package/LICENSE +1 -1
  2. package/dist/base.css +47 -26
  3. package/dist/esm/additional-components/Background/Background.d.ts +5 -5
  4. package/dist/esm/additional-components/Background/Background.d.ts.map +1 -1
  5. package/dist/esm/additional-components/Background/index.d.ts +2 -2
  6. package/dist/esm/additional-components/Background/index.d.ts.map +1 -1
  7. package/dist/esm/additional-components/Background/types.d.ts +13 -0
  8. package/dist/esm/additional-components/Background/types.d.ts.map +1 -1
  9. package/dist/esm/additional-components/Controls/ControlButton.d.ts +1 -3
  10. package/dist/esm/additional-components/Controls/ControlButton.d.ts.map +1 -1
  11. package/dist/esm/additional-components/Controls/Controls.d.ts +7 -3
  12. package/dist/esm/additional-components/Controls/Controls.d.ts.map +1 -1
  13. package/dist/esm/additional-components/Controls/Icons/FitView.d.ts +1 -2
  14. package/dist/esm/additional-components/Controls/Icons/FitView.d.ts.map +1 -1
  15. package/dist/esm/additional-components/Controls/Icons/Lock.d.ts +1 -2
  16. package/dist/esm/additional-components/Controls/Icons/Lock.d.ts.map +1 -1
  17. package/dist/esm/additional-components/Controls/Icons/Minus.d.ts +1 -2
  18. package/dist/esm/additional-components/Controls/Icons/Minus.d.ts.map +1 -1
  19. package/dist/esm/additional-components/Controls/Icons/Plus.d.ts +1 -2
  20. package/dist/esm/additional-components/Controls/Icons/Plus.d.ts.map +1 -1
  21. package/dist/esm/additional-components/Controls/Icons/Unlock.d.ts +1 -2
  22. package/dist/esm/additional-components/Controls/Icons/Unlock.d.ts.map +1 -1
  23. package/dist/esm/additional-components/Controls/index.d.ts +3 -3
  24. package/dist/esm/additional-components/Controls/index.d.ts.map +1 -1
  25. package/dist/esm/additional-components/Controls/types.d.ts +20 -2
  26. package/dist/esm/additional-components/Controls/types.d.ts.map +1 -1
  27. package/dist/esm/additional-components/MiniMap/MiniMap.d.ts +5 -5
  28. package/dist/esm/additional-components/MiniMap/MiniMap.d.ts.map +1 -1
  29. package/dist/esm/additional-components/MiniMap/MiniMapNode.d.ts +3 -3
  30. package/dist/esm/additional-components/MiniMap/MiniMapNode.d.ts.map +1 -1
  31. package/dist/esm/additional-components/MiniMap/MiniMapNodes.d.ts +3 -3
  32. package/dist/esm/additional-components/MiniMap/MiniMapNodes.d.ts.map +1 -1
  33. package/dist/esm/additional-components/MiniMap/index.d.ts +1 -1
  34. package/dist/esm/additional-components/MiniMap/index.d.ts.map +1 -1
  35. package/dist/esm/additional-components/MiniMap/types.d.ts +23 -0
  36. package/dist/esm/additional-components/MiniMap/types.d.ts.map +1 -1
  37. package/dist/esm/additional-components/NodeResizer/NodeResizeControl.d.ts +7 -0
  38. package/dist/esm/additional-components/NodeResizer/NodeResizeControl.d.ts.map +1 -0
  39. package/dist/esm/additional-components/NodeResizer/NodeResizer.d.ts +2 -2
  40. package/dist/esm/additional-components/NodeResizer/NodeResizer.d.ts.map +1 -1
  41. package/dist/esm/additional-components/NodeResizer/ResizeControl.d.ts.map +1 -1
  42. package/dist/esm/additional-components/NodeResizer/index.d.ts +2 -2
  43. package/dist/esm/additional-components/NodeResizer/index.d.ts.map +1 -1
  44. package/dist/esm/additional-components/NodeResizer/types.d.ts +26 -23
  45. package/dist/esm/additional-components/NodeResizer/types.d.ts.map +1 -1
  46. package/dist/esm/additional-components/NodeToolbar/NodeToolbar.d.ts +2 -3
  47. package/dist/esm/additional-components/NodeToolbar/NodeToolbar.d.ts.map +1 -1
  48. package/dist/esm/additional-components/NodeToolbar/NodeToolbarPortal.d.ts +1 -2
  49. package/dist/esm/additional-components/NodeToolbar/NodeToolbarPortal.d.ts.map +1 -1
  50. package/dist/esm/additional-components/NodeToolbar/index.d.ts +2 -2
  51. package/dist/esm/additional-components/NodeToolbar/index.d.ts.map +1 -1
  52. package/dist/esm/additional-components/NodeToolbar/types.d.ts +10 -0
  53. package/dist/esm/additional-components/NodeToolbar/types.d.ts.map +1 -1
  54. package/dist/esm/components/A11yDescriptions/index.d.ts +1 -2
  55. package/dist/esm/components/A11yDescriptions/index.d.ts.map +1 -1
  56. package/dist/esm/components/Attribution/index.d.ts +2 -2
  57. package/dist/esm/components/Attribution/index.d.ts.map +1 -1
  58. package/dist/esm/components/ConnectionLine/index.d.ts +2 -2
  59. package/dist/esm/components/ConnectionLine/index.d.ts.map +1 -1
  60. package/dist/esm/components/EdgeLabelRenderer/index.d.ts +1 -2
  61. package/dist/esm/components/EdgeLabelRenderer/index.d.ts.map +1 -1
  62. package/dist/esm/components/EdgeWrapper/EdgeUpdateAnchors.d.ts +9 -9
  63. package/dist/esm/components/EdgeWrapper/EdgeUpdateAnchors.d.ts.map +1 -1
  64. package/dist/esm/components/EdgeWrapper/index.d.ts +2 -7
  65. package/dist/esm/components/EdgeWrapper/index.d.ts.map +1 -1
  66. package/dist/esm/components/Edges/BaseEdge.d.ts +1 -5
  67. package/dist/esm/components/Edges/BaseEdge.d.ts.map +1 -1
  68. package/dist/esm/components/Edges/EdgeAnchor.d.ts +2 -2
  69. package/dist/esm/components/Edges/EdgeAnchor.d.ts.map +1 -1
  70. package/dist/esm/components/Edges/EdgeText.d.ts +7 -3
  71. package/dist/esm/components/Edges/EdgeText.d.ts.map +1 -1
  72. package/dist/esm/components/Handle/index.d.ts +6 -3
  73. package/dist/esm/components/Handle/index.d.ts.map +1 -1
  74. package/dist/esm/components/NodeWrapper/index.d.ts +2 -7
  75. package/dist/esm/components/NodeWrapper/index.d.ts.map +1 -1
  76. package/dist/esm/components/NodeWrapper/utils.d.ts +5 -1
  77. package/dist/esm/components/NodeWrapper/utils.d.ts.map +1 -1
  78. package/dist/esm/components/Nodes/DefaultNode.d.ts +1 -6
  79. package/dist/esm/components/Nodes/DefaultNode.d.ts.map +1 -1
  80. package/dist/esm/components/Nodes/GroupNode.d.ts +1 -5
  81. package/dist/esm/components/Nodes/GroupNode.d.ts.map +1 -1
  82. package/dist/esm/components/Nodes/InputNode.d.ts +1 -6
  83. package/dist/esm/components/Nodes/InputNode.d.ts.map +1 -1
  84. package/dist/esm/components/Nodes/OutputNode.d.ts +1 -6
  85. package/dist/esm/components/Nodes/OutputNode.d.ts.map +1 -1
  86. package/dist/esm/components/Nodes/utils.d.ts.map +1 -1
  87. package/dist/esm/components/NodesSelection/index.d.ts +3 -5
  88. package/dist/esm/components/NodesSelection/index.d.ts.map +1 -1
  89. package/dist/esm/components/Panel/index.d.ts +5 -3
  90. package/dist/esm/components/Panel/index.d.ts.map +1 -1
  91. package/dist/esm/components/ReactFlowProvider/index.d.ts +3 -5
  92. package/dist/esm/components/ReactFlowProvider/index.d.ts.map +1 -1
  93. package/dist/esm/components/SelectionListener/index.d.ts +2 -2
  94. package/dist/esm/components/SelectionListener/index.d.ts.map +1 -1
  95. package/dist/esm/components/StoreUpdater/index.d.ts +5 -5
  96. package/dist/esm/components/StoreUpdater/index.d.ts.map +1 -1
  97. package/dist/esm/components/UserSelection/index.d.ts +1 -2
  98. package/dist/esm/components/UserSelection/index.d.ts.map +1 -1
  99. package/dist/esm/components/ViewportPortal/index.d.ts +1 -2
  100. package/dist/esm/components/ViewportPortal/index.d.ts.map +1 -1
  101. package/dist/esm/container/EdgeRenderer/MarkerDefinitions.d.ts.map +1 -1
  102. package/dist/esm/container/EdgeRenderer/MarkerSymbols.d.ts +1 -1
  103. package/dist/esm/container/EdgeRenderer/MarkerSymbols.d.ts.map +1 -1
  104. package/dist/esm/container/EdgeRenderer/index.d.ts +9 -7
  105. package/dist/esm/container/EdgeRenderer/index.d.ts.map +1 -1
  106. package/dist/esm/container/FlowRenderer/index.d.ts +8 -6
  107. package/dist/esm/container/FlowRenderer/index.d.ts.map +1 -1
  108. package/dist/esm/container/GraphView/index.d.ts +8 -8
  109. package/dist/esm/container/GraphView/index.d.ts.map +1 -1
  110. package/dist/esm/container/GraphView/useNodeOrEdgeTypesWarning.d.ts +0 -1
  111. package/dist/esm/container/GraphView/useNodeOrEdgeTypesWarning.d.ts.map +1 -1
  112. package/dist/esm/container/NodeRenderer/index.d.ts +8 -7
  113. package/dist/esm/container/NodeRenderer/index.d.ts.map +1 -1
  114. package/dist/esm/container/NodeRenderer/useResizeObserver.d.ts +1 -1
  115. package/dist/esm/container/NodeRenderer/useResizeObserver.d.ts.map +1 -1
  116. package/dist/esm/container/Pane/index.d.ts +2 -2
  117. package/dist/esm/container/Pane/index.d.ts.map +1 -1
  118. package/dist/esm/container/ReactFlow/Wrapper.d.ts +3 -5
  119. package/dist/esm/container/ReactFlow/Wrapper.d.ts.map +1 -1
  120. package/dist/esm/container/ReactFlow/index.d.ts +5 -119
  121. package/dist/esm/container/ReactFlow/index.d.ts.map +1 -1
  122. package/dist/esm/container/ReactFlow/init-values.d.ts +4 -0
  123. package/dist/esm/container/ReactFlow/init-values.d.ts.map +1 -0
  124. package/dist/esm/container/Viewport/index.d.ts +1 -1
  125. package/dist/esm/container/Viewport/index.d.ts.map +1 -1
  126. package/dist/esm/container/ZoomPane/index.d.ts +2 -2
  127. package/dist/esm/container/ZoomPane/index.d.ts.map +1 -1
  128. package/dist/esm/contexts/RFStoreContext.d.ts +2 -2
  129. package/dist/esm/contexts/RFStoreContext.d.ts.map +1 -1
  130. package/dist/esm/hooks/useColorModeClass.d.ts +1 -1
  131. package/dist/esm/hooks/useColorModeClass.d.ts.map +1 -1
  132. package/dist/esm/hooks/useConnection.d.ts +13 -7
  133. package/dist/esm/hooks/useConnection.d.ts.map +1 -1
  134. package/dist/esm/hooks/useDrag.d.ts +3 -3
  135. package/dist/esm/hooks/useDrag.d.ts.map +1 -1
  136. package/dist/esm/hooks/useEdges.d.ts +1 -2
  137. package/dist/esm/hooks/useEdges.d.ts.map +1 -1
  138. package/dist/esm/hooks/useGlobalKeyHandler.d.ts +2 -3
  139. package/dist/esm/hooks/useGlobalKeyHandler.d.ts.map +1 -1
  140. package/dist/esm/hooks/useHandleConnections.d.ts +4 -4
  141. package/dist/esm/hooks/useHandleConnections.d.ts.map +1 -1
  142. package/dist/esm/hooks/useIsomorphicLayoutEffect.d.ts +3 -0
  143. package/dist/esm/hooks/useIsomorphicLayoutEffect.d.ts.map +1 -0
  144. package/dist/esm/hooks/useKeyPress.d.ts +1 -2
  145. package/dist/esm/hooks/useKeyPress.d.ts.map +1 -1
  146. package/dist/esm/hooks/useMoveSelectedNodes.d.ts +12 -0
  147. package/dist/esm/hooks/useMoveSelectedNodes.d.ts.map +1 -0
  148. package/dist/esm/hooks/useNodes.d.ts +1 -2
  149. package/dist/esm/hooks/useNodes.d.ts.map +1 -1
  150. package/dist/esm/hooks/useNodesData.d.ts +8 -4
  151. package/dist/esm/hooks/useNodesData.d.ts.map +1 -1
  152. package/dist/esm/hooks/useNodesEdgesState.d.ts +3 -3
  153. package/dist/esm/hooks/useNodesEdgesState.d.ts.map +1 -1
  154. package/dist/esm/hooks/useNodesInitialized.d.ts +1 -2
  155. package/dist/esm/hooks/useNodesInitialized.d.ts.map +1 -1
  156. package/dist/esm/hooks/useOnInitHandler.d.ts +2 -3
  157. package/dist/esm/hooks/useOnInitHandler.d.ts.map +1 -1
  158. package/dist/esm/hooks/useOnSelectionChange.d.ts +2 -3
  159. package/dist/esm/hooks/useOnSelectionChange.d.ts.map +1 -1
  160. package/dist/esm/hooks/useOnViewportChange.d.ts +1 -2
  161. package/dist/esm/hooks/useOnViewportChange.d.ts.map +1 -1
  162. package/dist/esm/hooks/useReactFlow.d.ts +1 -1
  163. package/dist/esm/hooks/useReactFlow.d.ts.map +1 -1
  164. package/dist/esm/hooks/useResizeHandler.d.ts +1 -2
  165. package/dist/esm/hooks/useResizeHandler.d.ts.map +1 -1
  166. package/dist/esm/hooks/useStore.d.ts +10 -10
  167. package/dist/esm/hooks/useStore.d.ts.map +1 -1
  168. package/dist/esm/hooks/useUpdateNodeInternals.d.ts +1 -2
  169. package/dist/esm/hooks/useUpdateNodeInternals.d.ts.map +1 -1
  170. package/dist/esm/hooks/useUpdateNodePositions.d.ts +1 -2
  171. package/dist/esm/hooks/useUpdateNodePositions.d.ts.map +1 -1
  172. package/dist/esm/hooks/useViewport.d.ts +1 -2
  173. package/dist/esm/hooks/useViewport.d.ts.map +1 -1
  174. package/dist/esm/hooks/useViewportSync.d.ts +1 -1
  175. package/dist/esm/hooks/useViewportSync.d.ts.map +1 -1
  176. package/dist/esm/hooks/useVisibleEdgeIds.d.ts +1 -2
  177. package/dist/esm/hooks/useVisibleEdgeIds.d.ts.map +1 -1
  178. package/dist/esm/hooks/useVisibleNodeIds.d.ts +1 -2
  179. package/dist/esm/hooks/useVisibleNodeIds.d.ts.map +1 -1
  180. package/dist/esm/index.d.ts +20 -20
  181. package/dist/esm/index.d.ts.map +1 -1
  182. package/dist/esm/index.js +750 -803
  183. package/dist/esm/index.mjs +750 -803
  184. package/dist/esm/store/index.d.ts +6 -4
  185. package/dist/esm/store/index.d.ts.map +1 -1
  186. package/dist/esm/store/initialState.d.ts +5 -3
  187. package/dist/esm/store/initialState.d.ts.map +1 -1
  188. package/dist/esm/types/changes.d.ts +8 -7
  189. package/dist/esm/types/changes.d.ts.map +1 -1
  190. package/dist/esm/types/component-props.d.ts +380 -37
  191. package/dist/esm/types/component-props.d.ts.map +1 -1
  192. package/dist/esm/types/edges.d.ts +34 -27
  193. package/dist/esm/types/edges.d.ts.map +1 -1
  194. package/dist/esm/types/general.d.ts +88 -10
  195. package/dist/esm/types/general.d.ts.map +1 -1
  196. package/dist/esm/types/instance.d.ts +94 -11
  197. package/dist/esm/types/instance.d.ts.map +1 -1
  198. package/dist/esm/types/nodes.d.ts +14 -11
  199. package/dist/esm/types/nodes.d.ts.map +1 -1
  200. package/dist/esm/types/store.d.ts +24 -22
  201. package/dist/esm/types/store.d.ts.map +1 -1
  202. package/dist/esm/utils/changes.d.ts +23 -5
  203. package/dist/esm/utils/changes.d.ts.map +1 -1
  204. package/dist/esm/utils/general.d.ts +2 -49
  205. package/dist/esm/utils/general.d.ts.map +1 -1
  206. package/dist/style.css +58 -29
  207. package/dist/umd/additional-components/Background/Background.d.ts +5 -5
  208. package/dist/umd/additional-components/Background/Background.d.ts.map +1 -1
  209. package/dist/umd/additional-components/Background/index.d.ts +2 -2
  210. package/dist/umd/additional-components/Background/index.d.ts.map +1 -1
  211. package/dist/umd/additional-components/Background/types.d.ts +13 -0
  212. package/dist/umd/additional-components/Background/types.d.ts.map +1 -1
  213. package/dist/umd/additional-components/Controls/ControlButton.d.ts +1 -3
  214. package/dist/umd/additional-components/Controls/ControlButton.d.ts.map +1 -1
  215. package/dist/umd/additional-components/Controls/Controls.d.ts +7 -3
  216. package/dist/umd/additional-components/Controls/Controls.d.ts.map +1 -1
  217. package/dist/umd/additional-components/Controls/Icons/FitView.d.ts +1 -2
  218. package/dist/umd/additional-components/Controls/Icons/FitView.d.ts.map +1 -1
  219. package/dist/umd/additional-components/Controls/Icons/Lock.d.ts +1 -2
  220. package/dist/umd/additional-components/Controls/Icons/Lock.d.ts.map +1 -1
  221. package/dist/umd/additional-components/Controls/Icons/Minus.d.ts +1 -2
  222. package/dist/umd/additional-components/Controls/Icons/Minus.d.ts.map +1 -1
  223. package/dist/umd/additional-components/Controls/Icons/Plus.d.ts +1 -2
  224. package/dist/umd/additional-components/Controls/Icons/Plus.d.ts.map +1 -1
  225. package/dist/umd/additional-components/Controls/Icons/Unlock.d.ts +1 -2
  226. package/dist/umd/additional-components/Controls/Icons/Unlock.d.ts.map +1 -1
  227. package/dist/umd/additional-components/Controls/index.d.ts +3 -3
  228. package/dist/umd/additional-components/Controls/index.d.ts.map +1 -1
  229. package/dist/umd/additional-components/Controls/types.d.ts +20 -2
  230. package/dist/umd/additional-components/Controls/types.d.ts.map +1 -1
  231. package/dist/umd/additional-components/MiniMap/MiniMap.d.ts +5 -5
  232. package/dist/umd/additional-components/MiniMap/MiniMap.d.ts.map +1 -1
  233. package/dist/umd/additional-components/MiniMap/MiniMapNode.d.ts +3 -3
  234. package/dist/umd/additional-components/MiniMap/MiniMapNode.d.ts.map +1 -1
  235. package/dist/umd/additional-components/MiniMap/MiniMapNodes.d.ts +3 -3
  236. package/dist/umd/additional-components/MiniMap/MiniMapNodes.d.ts.map +1 -1
  237. package/dist/umd/additional-components/MiniMap/index.d.ts +1 -1
  238. package/dist/umd/additional-components/MiniMap/index.d.ts.map +1 -1
  239. package/dist/umd/additional-components/MiniMap/types.d.ts +23 -0
  240. package/dist/umd/additional-components/MiniMap/types.d.ts.map +1 -1
  241. package/dist/umd/additional-components/NodeResizer/NodeResizeControl.d.ts +7 -0
  242. package/dist/umd/additional-components/NodeResizer/NodeResizeControl.d.ts.map +1 -0
  243. package/dist/umd/additional-components/NodeResizer/NodeResizer.d.ts +2 -2
  244. package/dist/umd/additional-components/NodeResizer/NodeResizer.d.ts.map +1 -1
  245. package/dist/umd/additional-components/NodeResizer/ResizeControl.d.ts.map +1 -1
  246. package/dist/umd/additional-components/NodeResizer/index.d.ts +2 -2
  247. package/dist/umd/additional-components/NodeResizer/index.d.ts.map +1 -1
  248. package/dist/umd/additional-components/NodeResizer/types.d.ts +26 -23
  249. package/dist/umd/additional-components/NodeResizer/types.d.ts.map +1 -1
  250. package/dist/umd/additional-components/NodeToolbar/NodeToolbar.d.ts +2 -3
  251. package/dist/umd/additional-components/NodeToolbar/NodeToolbar.d.ts.map +1 -1
  252. package/dist/umd/additional-components/NodeToolbar/NodeToolbarPortal.d.ts +1 -2
  253. package/dist/umd/additional-components/NodeToolbar/NodeToolbarPortal.d.ts.map +1 -1
  254. package/dist/umd/additional-components/NodeToolbar/index.d.ts +2 -2
  255. package/dist/umd/additional-components/NodeToolbar/index.d.ts.map +1 -1
  256. package/dist/umd/additional-components/NodeToolbar/types.d.ts +10 -0
  257. package/dist/umd/additional-components/NodeToolbar/types.d.ts.map +1 -1
  258. package/dist/umd/components/A11yDescriptions/index.d.ts +1 -2
  259. package/dist/umd/components/A11yDescriptions/index.d.ts.map +1 -1
  260. package/dist/umd/components/Attribution/index.d.ts +2 -2
  261. package/dist/umd/components/Attribution/index.d.ts.map +1 -1
  262. package/dist/umd/components/ConnectionLine/index.d.ts +2 -2
  263. package/dist/umd/components/ConnectionLine/index.d.ts.map +1 -1
  264. package/dist/umd/components/EdgeLabelRenderer/index.d.ts +1 -2
  265. package/dist/umd/components/EdgeLabelRenderer/index.d.ts.map +1 -1
  266. package/dist/umd/components/EdgeWrapper/EdgeUpdateAnchors.d.ts +9 -9
  267. package/dist/umd/components/EdgeWrapper/EdgeUpdateAnchors.d.ts.map +1 -1
  268. package/dist/umd/components/EdgeWrapper/index.d.ts +2 -7
  269. package/dist/umd/components/EdgeWrapper/index.d.ts.map +1 -1
  270. package/dist/umd/components/Edges/BaseEdge.d.ts +1 -5
  271. package/dist/umd/components/Edges/BaseEdge.d.ts.map +1 -1
  272. package/dist/umd/components/Edges/EdgeAnchor.d.ts +2 -2
  273. package/dist/umd/components/Edges/EdgeAnchor.d.ts.map +1 -1
  274. package/dist/umd/components/Edges/EdgeText.d.ts +7 -3
  275. package/dist/umd/components/Edges/EdgeText.d.ts.map +1 -1
  276. package/dist/umd/components/Handle/index.d.ts +6 -3
  277. package/dist/umd/components/Handle/index.d.ts.map +1 -1
  278. package/dist/umd/components/NodeWrapper/index.d.ts +2 -7
  279. package/dist/umd/components/NodeWrapper/index.d.ts.map +1 -1
  280. package/dist/umd/components/NodeWrapper/utils.d.ts +5 -1
  281. package/dist/umd/components/NodeWrapper/utils.d.ts.map +1 -1
  282. package/dist/umd/components/Nodes/DefaultNode.d.ts +1 -6
  283. package/dist/umd/components/Nodes/DefaultNode.d.ts.map +1 -1
  284. package/dist/umd/components/Nodes/GroupNode.d.ts +1 -5
  285. package/dist/umd/components/Nodes/GroupNode.d.ts.map +1 -1
  286. package/dist/umd/components/Nodes/InputNode.d.ts +1 -6
  287. package/dist/umd/components/Nodes/InputNode.d.ts.map +1 -1
  288. package/dist/umd/components/Nodes/OutputNode.d.ts +1 -6
  289. package/dist/umd/components/Nodes/OutputNode.d.ts.map +1 -1
  290. package/dist/umd/components/Nodes/utils.d.ts.map +1 -1
  291. package/dist/umd/components/NodesSelection/index.d.ts +3 -5
  292. package/dist/umd/components/NodesSelection/index.d.ts.map +1 -1
  293. package/dist/umd/components/Panel/index.d.ts +5 -3
  294. package/dist/umd/components/Panel/index.d.ts.map +1 -1
  295. package/dist/umd/components/ReactFlowProvider/index.d.ts +3 -5
  296. package/dist/umd/components/ReactFlowProvider/index.d.ts.map +1 -1
  297. package/dist/umd/components/SelectionListener/index.d.ts +2 -2
  298. package/dist/umd/components/SelectionListener/index.d.ts.map +1 -1
  299. package/dist/umd/components/StoreUpdater/index.d.ts +5 -5
  300. package/dist/umd/components/StoreUpdater/index.d.ts.map +1 -1
  301. package/dist/umd/components/UserSelection/index.d.ts +1 -2
  302. package/dist/umd/components/UserSelection/index.d.ts.map +1 -1
  303. package/dist/umd/components/ViewportPortal/index.d.ts +1 -2
  304. package/dist/umd/components/ViewportPortal/index.d.ts.map +1 -1
  305. package/dist/umd/container/EdgeRenderer/MarkerDefinitions.d.ts.map +1 -1
  306. package/dist/umd/container/EdgeRenderer/MarkerSymbols.d.ts +1 -1
  307. package/dist/umd/container/EdgeRenderer/MarkerSymbols.d.ts.map +1 -1
  308. package/dist/umd/container/EdgeRenderer/index.d.ts +9 -7
  309. package/dist/umd/container/EdgeRenderer/index.d.ts.map +1 -1
  310. package/dist/umd/container/FlowRenderer/index.d.ts +8 -6
  311. package/dist/umd/container/FlowRenderer/index.d.ts.map +1 -1
  312. package/dist/umd/container/GraphView/index.d.ts +8 -8
  313. package/dist/umd/container/GraphView/index.d.ts.map +1 -1
  314. package/dist/umd/container/GraphView/useNodeOrEdgeTypesWarning.d.ts +0 -1
  315. package/dist/umd/container/GraphView/useNodeOrEdgeTypesWarning.d.ts.map +1 -1
  316. package/dist/umd/container/NodeRenderer/index.d.ts +8 -7
  317. package/dist/umd/container/NodeRenderer/index.d.ts.map +1 -1
  318. package/dist/umd/container/NodeRenderer/useResizeObserver.d.ts +1 -1
  319. package/dist/umd/container/NodeRenderer/useResizeObserver.d.ts.map +1 -1
  320. package/dist/umd/container/Pane/index.d.ts +2 -2
  321. package/dist/umd/container/Pane/index.d.ts.map +1 -1
  322. package/dist/umd/container/ReactFlow/Wrapper.d.ts +3 -5
  323. package/dist/umd/container/ReactFlow/Wrapper.d.ts.map +1 -1
  324. package/dist/umd/container/ReactFlow/index.d.ts +5 -119
  325. package/dist/umd/container/ReactFlow/index.d.ts.map +1 -1
  326. package/dist/umd/container/ReactFlow/init-values.d.ts +4 -0
  327. package/dist/umd/container/ReactFlow/init-values.d.ts.map +1 -0
  328. package/dist/umd/container/Viewport/index.d.ts +1 -1
  329. package/dist/umd/container/Viewport/index.d.ts.map +1 -1
  330. package/dist/umd/container/ZoomPane/index.d.ts +2 -2
  331. package/dist/umd/container/ZoomPane/index.d.ts.map +1 -1
  332. package/dist/umd/contexts/RFStoreContext.d.ts +2 -2
  333. package/dist/umd/contexts/RFStoreContext.d.ts.map +1 -1
  334. package/dist/umd/hooks/useColorModeClass.d.ts +1 -1
  335. package/dist/umd/hooks/useColorModeClass.d.ts.map +1 -1
  336. package/dist/umd/hooks/useConnection.d.ts +13 -7
  337. package/dist/umd/hooks/useConnection.d.ts.map +1 -1
  338. package/dist/umd/hooks/useDrag.d.ts +3 -3
  339. package/dist/umd/hooks/useDrag.d.ts.map +1 -1
  340. package/dist/umd/hooks/useEdges.d.ts +1 -2
  341. package/dist/umd/hooks/useEdges.d.ts.map +1 -1
  342. package/dist/umd/hooks/useGlobalKeyHandler.d.ts +2 -3
  343. package/dist/umd/hooks/useGlobalKeyHandler.d.ts.map +1 -1
  344. package/dist/umd/hooks/useHandleConnections.d.ts +4 -4
  345. package/dist/umd/hooks/useHandleConnections.d.ts.map +1 -1
  346. package/dist/umd/hooks/useIsomorphicLayoutEffect.d.ts +3 -0
  347. package/dist/umd/hooks/useIsomorphicLayoutEffect.d.ts.map +1 -0
  348. package/dist/umd/hooks/useKeyPress.d.ts +1 -2
  349. package/dist/umd/hooks/useKeyPress.d.ts.map +1 -1
  350. package/dist/umd/hooks/useMoveSelectedNodes.d.ts +12 -0
  351. package/dist/umd/hooks/useMoveSelectedNodes.d.ts.map +1 -0
  352. package/dist/umd/hooks/useNodes.d.ts +1 -2
  353. package/dist/umd/hooks/useNodes.d.ts.map +1 -1
  354. package/dist/umd/hooks/useNodesData.d.ts +8 -4
  355. package/dist/umd/hooks/useNodesData.d.ts.map +1 -1
  356. package/dist/umd/hooks/useNodesEdgesState.d.ts +3 -3
  357. package/dist/umd/hooks/useNodesEdgesState.d.ts.map +1 -1
  358. package/dist/umd/hooks/useNodesInitialized.d.ts +1 -2
  359. package/dist/umd/hooks/useNodesInitialized.d.ts.map +1 -1
  360. package/dist/umd/hooks/useOnInitHandler.d.ts +2 -3
  361. package/dist/umd/hooks/useOnInitHandler.d.ts.map +1 -1
  362. package/dist/umd/hooks/useOnSelectionChange.d.ts +2 -3
  363. package/dist/umd/hooks/useOnSelectionChange.d.ts.map +1 -1
  364. package/dist/umd/hooks/useOnViewportChange.d.ts +1 -2
  365. package/dist/umd/hooks/useOnViewportChange.d.ts.map +1 -1
  366. package/dist/umd/hooks/useReactFlow.d.ts +1 -1
  367. package/dist/umd/hooks/useReactFlow.d.ts.map +1 -1
  368. package/dist/umd/hooks/useResizeHandler.d.ts +1 -2
  369. package/dist/umd/hooks/useResizeHandler.d.ts.map +1 -1
  370. package/dist/umd/hooks/useStore.d.ts +10 -10
  371. package/dist/umd/hooks/useStore.d.ts.map +1 -1
  372. package/dist/umd/hooks/useUpdateNodeInternals.d.ts +1 -2
  373. package/dist/umd/hooks/useUpdateNodeInternals.d.ts.map +1 -1
  374. package/dist/umd/hooks/useUpdateNodePositions.d.ts +1 -2
  375. package/dist/umd/hooks/useUpdateNodePositions.d.ts.map +1 -1
  376. package/dist/umd/hooks/useViewport.d.ts +1 -2
  377. package/dist/umd/hooks/useViewport.d.ts.map +1 -1
  378. package/dist/umd/hooks/useViewportSync.d.ts +1 -1
  379. package/dist/umd/hooks/useViewportSync.d.ts.map +1 -1
  380. package/dist/umd/hooks/useVisibleEdgeIds.d.ts +1 -2
  381. package/dist/umd/hooks/useVisibleEdgeIds.d.ts.map +1 -1
  382. package/dist/umd/hooks/useVisibleNodeIds.d.ts +1 -2
  383. package/dist/umd/hooks/useVisibleNodeIds.d.ts.map +1 -1
  384. package/dist/umd/index.d.ts +20 -20
  385. package/dist/umd/index.d.ts.map +1 -1
  386. package/dist/umd/index.js +2 -2
  387. package/dist/umd/store/index.d.ts +6 -4
  388. package/dist/umd/store/index.d.ts.map +1 -1
  389. package/dist/umd/store/initialState.d.ts +5 -3
  390. package/dist/umd/store/initialState.d.ts.map +1 -1
  391. package/dist/umd/types/changes.d.ts +8 -7
  392. package/dist/umd/types/changes.d.ts.map +1 -1
  393. package/dist/umd/types/component-props.d.ts +380 -37
  394. package/dist/umd/types/component-props.d.ts.map +1 -1
  395. package/dist/umd/types/edges.d.ts +34 -27
  396. package/dist/umd/types/edges.d.ts.map +1 -1
  397. package/dist/umd/types/general.d.ts +88 -10
  398. package/dist/umd/types/general.d.ts.map +1 -1
  399. package/dist/umd/types/instance.d.ts +94 -11
  400. package/dist/umd/types/instance.d.ts.map +1 -1
  401. package/dist/umd/types/nodes.d.ts +14 -11
  402. package/dist/umd/types/nodes.d.ts.map +1 -1
  403. package/dist/umd/types/store.d.ts +24 -22
  404. package/dist/umd/types/store.d.ts.map +1 -1
  405. package/dist/umd/utils/changes.d.ts +23 -5
  406. package/dist/umd/utils/changes.d.ts.map +1 -1
  407. package/dist/umd/utils/general.d.ts +2 -49
  408. package/dist/umd/utils/general.d.ts.map +1 -1
  409. package/package.json +3 -10
package/dist/esm/index.js CHANGED
@@ -1,14 +1,12 @@
1
1
  "use client"
2
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
- import { createContext, useContext, useMemo, memo, useEffect, useRef, useState, useCallback, forwardRef } from 'react';
2
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
+ import { createContext, useContext, useMemo, useEffect, useRef, useState, useLayoutEffect, 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, getPointerPosition, clamp, 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, ConnectionMode, addEdge, getNodesBounds, clampPosition, internalsSymbol, getNodeDimensions, nodeHasDimensions, getPositionWithOrigin, elementSelectionKeys, isEdgeVisible, MarkerType, createMarkerIds, isNumeric, getBezierEdgeCenter, getSmoothStepPath, getStraightPath, getBezierPath, getEdgePosition, getElevatedEdgeZIndex, getMarkerId, 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';
10
- import { drag } from 'd3-drag';
11
- import { select } from 'd3-selection';
12
10
 
13
11
  const StoreContext = createContext(null);
14
12
  const Provider$1 = StoreContext.Provider;
@@ -21,6 +19,10 @@ const zustandErrorMessage = errorMessages['error001']();
21
19
  * @param selector
22
20
  * @param equalityFn
23
21
  * @returns The selected state slice
22
+ *
23
+ * @example
24
+ * const nodes = useStore((state: ReactFlowState<MyNodeType>) => state.nodes);
25
+ *
24
26
  */
25
27
  function useStore(selector, equalityFn) {
26
28
  const store = useContext(StoreContext);
@@ -29,7 +31,7 @@ function useStore(selector, equalityFn) {
29
31
  }
30
32
  return useStoreWithEqualityFn(store, selector, equalityFn);
31
33
  }
32
- const useStoreApi = () => {
34
+ function useStoreApi() {
33
35
  const store = useContext(StoreContext);
34
36
  if (store === null) {
35
37
  throw new Error(zustandErrorMessage);
@@ -40,11 +42,35 @@ const useStoreApi = () => {
40
42
  subscribe: store.subscribe,
41
43
  destroy: store.destroy,
42
44
  }), [store]);
45
+ }
46
+
47
+ const style = { display: 'none' };
48
+ const ariaLiveStyle = {
49
+ position: 'absolute',
50
+ width: 1,
51
+ height: 1,
52
+ margin: -1,
53
+ border: 0,
54
+ padding: 0,
55
+ overflow: 'hidden',
56
+ clip: 'rect(0px, 0px, 0px, 0px)',
57
+ clipPath: 'inset(100%)',
43
58
  };
59
+ const ARIA_NODE_DESC_KEY = 'react-flow__node-desc';
60
+ const ARIA_EDGE_DESC_KEY = 'react-flow__edge-desc';
61
+ const ARIA_LIVE_MESSAGE = 'react-flow__aria-live';
62
+ const selector$q = (s) => s.ariaLiveMessage;
63
+ function AriaLiveMessage({ rfId }) {
64
+ const ariaLiveMessage = useStore(selector$q);
65
+ return (jsx("div", { id: `${ARIA_LIVE_MESSAGE}-${rfId}`, "aria-live": "assertive", "aria-atomic": "true", style: ariaLiveStyle, children: ariaLiveMessage }));
66
+ }
67
+ function A11yDescriptions({ rfId, disableKeyboardA11y }) {
68
+ return (jsxs(Fragment, { children: [jsxs("div", { id: `${ARIA_NODE_DESC_KEY}-${rfId}`, style: style, children: ["Press enter or space to select a node.", !disableKeyboardA11y && 'You can then use the arrow keys to move the node around.', " Press delete to remove it and escape to cancel.", ' '] }), jsx("div", { id: `${ARIA_EDGE_DESC_KEY}-${rfId}`, style: style, children: "Press enter or space to select an edge. You can then press delete to remove it or escape to cancel." }), !disableKeyboardA11y && jsx(AriaLiveMessage, { rfId: rfId })] }));
69
+ }
44
70
 
45
- const selector$q = (s) => (s.userSelectionActive ? 'none' : 'all');
46
- function Panel({ position, children, className, style, ...rest }) {
47
- const pointerEvents = useStore(selector$q);
71
+ const selector$p = (s) => (s.userSelectionActive ? 'none' : 'all');
72
+ function Panel({ position = 'top-left', children, className, style, ...rest }) {
73
+ const pointerEvents = useStore(selector$p);
48
74
  const positionClasses = `${position}`.split('-');
49
75
  return (jsx("div", { className: cc(['react-flow__panel', className, ...positionClasses]), style: { ...style, pointerEvents }, ...rest, children: children }));
50
76
  }
@@ -56,7 +82,7 @@ function Attribution({ proOptions, position = 'bottom-right' }) {
56
82
  return (jsx(Panel, { position: position, className: "react-flow__attribution", "data-message": "Please only hide this attribution when you are subscribed to React Flow Pro: https://pro.reactflow.dev", children: jsx("a", { href: "https://reactflow.dev", target: "_blank", rel: "noopener noreferrer", "aria-label": "React Flow attribution", children: "React Flow" }) }));
57
83
  }
58
84
 
59
- const selector$p = (s) => ({
85
+ const selector$o = (s) => ({
60
86
  selectedNodes: s.nodes.filter((n) => n.selected),
61
87
  selectedEdges: s.edges.filter((e) => e.selected),
62
88
  });
@@ -65,26 +91,28 @@ function areEqual(a, b) {
65
91
  return (shallow(a.selectedNodes.map(selectId), b.selectedNodes.map(selectId)) &&
66
92
  shallow(a.selectedEdges.map(selectId), b.selectedEdges.map(selectId)));
67
93
  }
68
- const SelectionListener = memo(({ onSelectionChange }) => {
94
+ function SelectionListenerInner({ onSelectionChange }) {
69
95
  const store = useStoreApi();
70
- const { selectedNodes, selectedEdges } = useStore(selector$p, areEqual);
96
+ const { selectedNodes, selectedEdges } = useStore(selector$o, areEqual);
71
97
  useEffect(() => {
72
98
  const params = { nodes: selectedNodes, edges: selectedEdges };
73
99
  onSelectionChange?.(params);
74
100
  store.getState().onSelectionChangeHandlers.forEach((fn) => fn(params));
75
101
  }, [selectedNodes, selectedEdges, onSelectionChange]);
76
102
  return null;
77
- });
78
- SelectionListener.displayName = 'SelectionListener';
103
+ }
79
104
  const changeSelector = (s) => !!s.onSelectionChangeHandlers;
80
- function Wrapper$1({ onSelectionChange }) {
105
+ function SelectionListener({ onSelectionChange }) {
81
106
  const storeHasSelectionChangeHandlers = useStore(changeSelector);
82
107
  if (onSelectionChange || storeHasSelectionChangeHandlers) {
83
- return jsx(SelectionListener, { onSelectionChange: onSelectionChange });
108
+ return jsx(SelectionListenerInner, { onSelectionChange: onSelectionChange });
84
109
  }
85
110
  return null;
86
111
  }
87
112
 
113
+ const defaultNodeOrigin = [0, 0];
114
+ const defaultViewport = { x: 0, y: 0, zoom: 1 };
115
+
88
116
  /*
89
117
  * This component helps us to update the store with the vlues coming from the user.
90
118
  * We distinguish between values we can update directly with `useDirectStoreUpdater` (like `snapGrid`)
@@ -144,41 +172,44 @@ const reactFlowFieldsToTrack = [
144
172
  'selectNodesOnDrag',
145
173
  'nodeDragThreshold',
146
174
  'onBeforeDelete',
175
+ 'debug',
147
176
  ];
148
177
  // rfId doesn't exist in ReactFlowProps, but it's one of the fields we want to update
149
178
  const fieldsToTrack = [...reactFlowFieldsToTrack, 'rfId'];
150
- const selector$o = (s) => ({
179
+ const selector$n = (s) => ({
151
180
  setNodes: s.setNodes,
152
181
  setEdges: s.setEdges,
153
- setDefaultNodesAndEdges: s.setDefaultNodesAndEdges,
154
182
  setMinZoom: s.setMinZoom,
155
183
  setMaxZoom: s.setMaxZoom,
156
184
  setTranslateExtent: s.setTranslateExtent,
157
185
  setNodeExtent: s.setNodeExtent,
158
186
  reset: s.reset,
187
+ setDefaultNodesAndEdges: s.setDefaultNodesAndEdges,
159
188
  });
160
- const StoreUpdater = (props) => {
161
- const { setNodes, setEdges, setDefaultNodesAndEdges, setMinZoom, setMaxZoom, setTranslateExtent, setNodeExtent, reset, } = useStore(selector$o, shallow);
189
+ const initPrevValues = {
190
+ // these are values that are also passed directly to other components
191
+ // than the StoreUpdater. We can reduce the number of setStore calls
192
+ // by setting the same values here as prev fields.
193
+ translateExtent: infiniteExtent,
194
+ nodeOrigin: defaultNodeOrigin,
195
+ minZoom: 0.5,
196
+ maxZoom: 2,
197
+ elementsSelectable: true,
198
+ noPanClassName: 'nopan',
199
+ rfId: '1',
200
+ };
201
+ function StoreUpdater(props) {
202
+ const { setNodes, setEdges, setMinZoom, setMaxZoom, setTranslateExtent, setNodeExtent, reset, setDefaultNodesAndEdges, } = useStore(selector$n, shallow);
162
203
  const store = useStoreApi();
163
204
  useEffect(() => {
164
- const edgesWithDefaults = props.defaultEdges?.map((e) => ({ ...e, ...props.defaultEdgeOptions }));
165
- setDefaultNodesAndEdges(props.defaultNodes, edgesWithDefaults);
205
+ setDefaultNodesAndEdges(props.defaultNodes, props.defaultEdges);
166
206
  return () => {
207
+ // when we reset the store we also need to reset the previous fields
208
+ previousFields.current = initPrevValues;
167
209
  reset();
168
210
  };
169
211
  }, []);
170
- const previousFields = useRef({
171
- // these are values that are also passed directly to other components
172
- // than the StoreUpdater. We can reduce the number of setStore calls
173
- // by setting the same values here as prev fields.
174
- translateExtent: infiniteExtent,
175
- nodeOrigin: initNodeOrigin,
176
- minZoom: 0.5,
177
- maxZoom: 2,
178
- elementsSelectable: true,
179
- noPanClassName: 'nopan',
180
- rfId: '1',
181
- });
212
+ const previousFields = useRef(initPrevValues);
182
213
  useEffect(() => {
183
214
  for (const fieldName of fieldsToTrack) {
184
215
  const fieldValue = props[fieldName];
@@ -214,30 +245,36 @@ const StoreUpdater = (props) => {
214
245
  // Only re-run the effect if one of the fields we track changes
215
246
  fieldsToTrack.map((fieldName) => props[fieldName]));
216
247
  return null;
217
- };
248
+ }
218
249
 
219
- const style = { display: 'none' };
220
- const ariaLiveStyle = {
221
- position: 'absolute',
222
- width: 1,
223
- height: 1,
224
- margin: -1,
225
- border: 0,
226
- padding: 0,
227
- overflow: 'hidden',
228
- clip: 'rect(0px, 0px, 0px, 0px)',
229
- clipPath: 'inset(100%)',
230
- };
231
- const ARIA_NODE_DESC_KEY = 'react-flow__node-desc';
232
- const ARIA_EDGE_DESC_KEY = 'react-flow__edge-desc';
233
- const ARIA_LIVE_MESSAGE = 'react-flow__aria-live';
234
- const selector$n = (s) => s.ariaLiveMessage;
235
- function AriaLiveMessage({ rfId }) {
236
- const ariaLiveMessage = useStore(selector$n);
237
- return (jsx("div", { id: `${ARIA_LIVE_MESSAGE}-${rfId}`, "aria-live": "assertive", "aria-atomic": "true", style: ariaLiveStyle, children: ariaLiveMessage }));
250
+ function getMediaQuery() {
251
+ if (typeof window === 'undefined' || !window.matchMedia) {
252
+ return null;
253
+ }
254
+ return window.matchMedia('(prefers-color-scheme: dark)');
238
255
  }
239
- function A11yDescriptions({ rfId, disableKeyboardA11y }) {
240
- return (jsxs(Fragment, { children: [jsxs("div", { id: `${ARIA_NODE_DESC_KEY}-${rfId}`, style: style, children: ["Press enter or space to select a node.", !disableKeyboardA11y && 'You can then use the arrow keys to move the node around.', " Press delete to remove it and escape to cancel.", ' '] }), jsx("div", { id: `${ARIA_EDGE_DESC_KEY}-${rfId}`, style: style, children: "Press enter or space to select an edge. You can then press delete to remove it or escape to cancel." }), !disableKeyboardA11y && jsx(AriaLiveMessage, { rfId: rfId })] }));
256
+ /**
257
+ * Hook for receiving the current color mode class 'dark' or 'light'.
258
+ *
259
+ * @internal
260
+ * @param colorMode - The color mode to use ('dark', 'light' or 'system')
261
+ */
262
+ function useColorModeClass(colorMode) {
263
+ const [colorModeClass, setColorModeClass] = useState(colorMode === 'system' ? null : colorMode);
264
+ useEffect(() => {
265
+ if (colorMode !== 'system') {
266
+ setColorModeClass(colorMode);
267
+ return;
268
+ }
269
+ const mediaQuery = getMediaQuery();
270
+ const updateColorModeClass = () => setColorModeClass(mediaQuery?.matches ? 'dark' : 'light');
271
+ updateColorModeClass();
272
+ mediaQuery?.addEventListener('change', updateColorModeClass);
273
+ return () => {
274
+ mediaQuery?.removeEventListener('change', updateColorModeClass);
275
+ };
276
+ }, [colorMode]);
277
+ return colorModeClass !== null ? colorModeClass : getMediaQuery()?.matches ? 'dark' : 'light';
241
278
  }
242
279
 
243
280
  const defaultDoc = typeof document !== 'undefined' ? document : null;
@@ -249,12 +286,12 @@ const defaultDoc = typeof document !== 'undefined' ? document : null;
249
286
  * @param param.options - Options
250
287
  * @returns boolean
251
288
  */
252
- var useKeyPress = (
289
+ function useKeyPress(
253
290
  // the keycode can be a string 'a' or an array of strings ['a', 'a+d']
254
291
  // a string means a single key 'a' or a combination when '+' is used 'a+d'
255
292
  // an array means different possibilites. Explainer: ['a', 'd+s'] here the
256
293
  // user can use the single key 'a' or the combination 'd' + 's'
257
- keyCode = null, options = { target: defaultDoc, actInsideInputWithModifier: true }) => {
294
+ keyCode = null, options = { target: defaultDoc, actInsideInputWithModifier: true }) {
258
295
  const [keyPressed, setKeyPressed] = useState(false);
259
296
  // we need to remember if a modifier key is pressed in order to track it
260
297
  const modifierPressed = useRef(false);
@@ -306,6 +343,10 @@ keyCode = null, options = { target: defaultDoc, actInsideInputWithModifier: true
306
343
  else {
307
344
  pressedKeys.current.delete(event[keyOrCode]);
308
345
  }
346
+ // fix for Mac: when cmd key is pressed, keyup is not triggered for any other key, see: https://stackoverflow.com/questions/27380018/when-cmd-key-is-kept-pressed-keyup-is-not-triggered-for-any-other-key
347
+ if (event.key === 'Meta') {
348
+ pressedKeys.current.clear();
349
+ }
309
350
  modifierPressed.current = false;
310
351
  };
311
352
  const resetHandler = () => {
@@ -323,7 +364,7 @@ keyCode = null, options = { target: defaultDoc, actInsideInputWithModifier: true
323
364
  }
324
365
  }, [keyCode, setKeyPressed]);
325
366
  return keyPressed;
326
- };
367
+ }
327
368
  // utils
328
369
  function isMatchingKey(keyCodes, pressedKeys, isUp) {
329
370
  return (keyCodes
@@ -397,25 +438,25 @@ const useViewportHelper = () => {
397
438
  const viewport = getViewportForBounds(bounds, width, height, minZoom, maxZoom, options?.padding ?? 0.1);
398
439
  panZoom?.setViewport(viewport, { duration: options?.duration });
399
440
  },
400
- screenToFlowPosition: (position) => {
401
- const { transform, snapToGrid, snapGrid, domNode } = store.getState();
441
+ screenToFlowPosition: (clientPosition, options = { snapToGrid: true }) => {
442
+ const { transform, snapGrid, domNode } = store.getState();
402
443
  if (!domNode) {
403
- return position;
444
+ return clientPosition;
404
445
  }
405
446
  const { x: domX, y: domY } = domNode.getBoundingClientRect();
406
447
  const correctedPosition = {
407
- x: position.x - domX,
408
- y: position.y - domY,
448
+ x: clientPosition.x - domX,
449
+ y: clientPosition.y - domY,
409
450
  };
410
- return pointToRendererPoint(correctedPosition, transform, snapToGrid, snapGrid || [1, 1]);
451
+ return pointToRendererPoint(correctedPosition, transform, options.snapToGrid, snapGrid);
411
452
  },
412
- flowToScreenPosition: (position) => {
453
+ flowToScreenPosition: (flowPosition) => {
413
454
  const { transform, domNode } = store.getState();
414
455
  if (!domNode) {
415
- return position;
456
+ return flowPosition;
416
457
  }
417
458
  const { x: domX, y: domY } = domNode.getBoundingClientRect();
418
- const rendererPosition = rendererPointToPoint(position, transform);
459
+ const rendererPosition = rendererPointToPoint(flowPosition, transform);
419
460
  return {
420
461
  x: rendererPosition.x + domX,
421
462
  y: rendererPosition.y + domY,
@@ -427,38 +468,39 @@ const useViewportHelper = () => {
427
468
  return viewportHelperFunctions;
428
469
  };
429
470
 
430
- function handleParentExpand(res, updateItem) {
431
- const parent = res.find((e) => e.id === updateItem.parentNode);
432
- if (parent) {
433
- if (!parent.computed) {
434
- parent.computed = {};
435
- }
436
- const extendWidth = updateItem.position.x + updateItem.computed.width - parent.computed.width;
437
- const extendHeight = updateItem.position.y + updateItem.computed.height - parent.computed.height;
438
- if (extendWidth > 0 || extendHeight > 0 || updateItem.position.x < 0 || updateItem.position.y < 0) {
439
- parent.style = { ...parent.style } || {};
440
- parent.style.width = parent.style.width ?? parent.computed.width;
441
- parent.style.height = parent.style.height ?? parent.computed.height;
442
- if (extendWidth > 0) {
443
- parent.style.width += extendWidth;
444
- }
445
- if (extendHeight > 0) {
446
- parent.style.height += extendHeight;
447
- }
448
- if (updateItem.position.x < 0) {
449
- const xDiff = Math.abs(updateItem.position.x);
450
- parent.position.x = parent.position.x - xDiff;
451
- parent.style.width += xDiff;
452
- updateItem.position.x = 0;
453
- }
454
- if (updateItem.position.y < 0) {
455
- const yDiff = Math.abs(updateItem.position.y);
456
- parent.position.y = parent.position.y - yDiff;
457
- parent.style.height += yDiff;
458
- updateItem.position.y = 0;
471
+ function handleParentExpand(updatedElements, updateItem) {
472
+ for (const [index, item] of updatedElements.entries()) {
473
+ if (item.id === updateItem.parentNode) {
474
+ const parent = { ...item };
475
+ parent.computed ??= {};
476
+ const extendWidth = updateItem.position.x + updateItem.computed.width - parent.computed.width;
477
+ const extendHeight = updateItem.position.y + updateItem.computed.height - parent.computed.height;
478
+ if (extendWidth > 0 || extendHeight > 0 || updateItem.position.x < 0 || updateItem.position.y < 0) {
479
+ parent.width = parent.width ?? parent.computed.width;
480
+ parent.height = parent.height ?? parent.computed.height;
481
+ if (extendWidth > 0) {
482
+ parent.width += extendWidth;
483
+ }
484
+ if (extendHeight > 0) {
485
+ parent.height += extendHeight;
486
+ }
487
+ if (updateItem.position.x < 0) {
488
+ const xDiff = Math.abs(updateItem.position.x);
489
+ parent.position.x = parent.position.x - xDiff;
490
+ parent.width += xDiff;
491
+ updateItem.position.x = 0;
492
+ }
493
+ if (updateItem.position.y < 0) {
494
+ const yDiff = Math.abs(updateItem.position.y);
495
+ parent.position.y = parent.position.y - yDiff;
496
+ parent.height += yDiff;
497
+ updateItem.position.y = 0;
498
+ }
499
+ parent.computed.width = parent.width;
500
+ parent.computed.height = parent.height;
501
+ updatedElements[index] = parent;
459
502
  }
460
- parent.computed.width = parent.style.width;
461
- parent.computed.height = parent.style.height;
503
+ break;
462
504
  }
463
505
  }
464
506
  }
@@ -466,85 +508,101 @@ function handleParentExpand(res, updateItem) {
466
508
  // When you drag a node for example, React Flow will send a position change update.
467
509
  // This function then applies the changes and returns the updated elements.
468
510
  function applyChanges(changes, elements) {
469
- // we need this hack to handle the setNodes and setEdges function of the useReactFlow hook for controlled flows
470
- if (changes.some((c) => c.type === 'reset')) {
471
- return changes.filter((c) => c.type === 'reset').map((c) => c.item);
472
- }
473
- let remainingChanges = changes;
474
511
  const updatedElements = [];
475
- for (const item of elements) {
476
- const nextChanges = [];
477
- const _remainingChanges = [];
478
- for (const c of remainingChanges) {
479
- if (c.type === 'add') {
480
- updatedElements.push(c.item);
481
- }
482
- else if (c.id === item.id) {
483
- nextChanges.push(c);
512
+ // By storing a map of changes for each element, we can a quick lookup as we
513
+ // iterate over the elements array!
514
+ const changesMap = new Map();
515
+ for (const change of changes) {
516
+ if (change.type === 'add') {
517
+ updatedElements.push(change.item);
518
+ continue;
519
+ }
520
+ else if (change.type === 'remove' || change.type === 'replace') {
521
+ // For a 'remove' change we can safely ignore any other changes queued for
522
+ // the same element, it's going to be removed anyway!
523
+ changesMap.set(change.id, [change]);
524
+ }
525
+ else {
526
+ const elementChanges = changesMap.get(change.id);
527
+ if (elementChanges) {
528
+ // If we have some changes queued already, we can do a mutable update of
529
+ // that array and save ourselves some copying.
530
+ elementChanges.push(change);
484
531
  }
485
532
  else {
486
- _remainingChanges.push(c);
533
+ changesMap.set(change.id, [change]);
487
534
  }
488
535
  }
489
- remainingChanges = _remainingChanges;
490
- if (nextChanges.length === 0) {
491
- updatedElements.push(item);
536
+ }
537
+ for (const element of elements) {
538
+ const changes = changesMap.get(element.id);
539
+ // When there are no changes for an element we can just push it unmodified,
540
+ // no need to copy it.
541
+ if (!changes) {
542
+ updatedElements.push(element);
492
543
  continue;
493
544
  }
494
- const updateItem = { ...item };
495
- for (const currentChange of nextChanges) {
496
- if (currentChange) {
497
- switch (currentChange.type) {
498
- case 'select': {
499
- updateItem.selected = currentChange.selected;
500
- break;
501
- }
502
- case 'position': {
503
- if (typeof currentChange.position !== 'undefined') {
504
- updateItem.position = currentChange.position;
505
- }
506
- if (typeof currentChange.positionAbsolute !== 'undefined') {
507
- if (!updateItem.computed) {
508
- updateItem.computed = {};
509
- }
510
- updateItem.computed.positionAbsolute = currentChange.positionAbsolute;
511
- }
512
- if (typeof currentChange.dragging !== 'undefined') {
513
- updateItem.dragging = currentChange.dragging;
514
- }
515
- if (updateItem.expandParent) {
516
- handleParentExpand(updatedElements, updateItem);
517
- }
518
- break;
519
- }
520
- case 'dimensions': {
521
- if (typeof currentChange.dimensions !== 'undefined') {
522
- if (!updateItem.computed) {
523
- updateItem.computed = {};
524
- }
525
- updateItem.computed.width = currentChange.dimensions.width;
526
- updateItem.computed.height = currentChange.dimensions.height;
527
- }
528
- if (typeof currentChange.updateStyle !== 'undefined') {
529
- updateItem.style = { ...(updateItem.style || {}), ...currentChange.dimensions };
530
- }
531
- if (typeof currentChange.resizing === 'boolean') {
532
- updateItem.resizing = currentChange.resizing;
533
- }
534
- if (updateItem.expandParent) {
535
- handleParentExpand(updatedElements, updateItem);
536
- }
537
- break;
538
- }
539
- case 'remove': {
540
- continue;
541
- }
545
+ // If we have a 'remove' change queued, it'll be the only change in the array
546
+ if (changes[0].type === 'remove') {
547
+ continue;
548
+ }
549
+ if (changes[0].type === 'replace') {
550
+ updatedElements.push({ ...changes[0].item });
551
+ continue;
552
+ }
553
+ // For other types of changes, we want to start with a shallow copy of the
554
+ // object so React knows this element has changed. Sequential changes will
555
+ /// each _mutate_ this object, so there's only ever one copy.
556
+ const updatedElement = { ...element };
557
+ for (const change of changes) {
558
+ applyChange(change, updatedElement, updatedElements);
559
+ }
560
+ updatedElements.push(updatedElement);
561
+ }
562
+ return updatedElements;
563
+ }
564
+ // Applies a single change to an element. This is a *mutable* update.
565
+ function applyChange(change, element, elements = []) {
566
+ switch (change.type) {
567
+ case 'select': {
568
+ element.selected = change.selected;
569
+ break;
570
+ }
571
+ case 'position': {
572
+ if (typeof change.position !== 'undefined') {
573
+ element.position = change.position;
574
+ }
575
+ if (typeof change.positionAbsolute !== 'undefined') {
576
+ element.computed ??= {};
577
+ element.computed.positionAbsolute = change.positionAbsolute;
578
+ }
579
+ if (typeof change.dragging !== 'undefined') {
580
+ element.dragging = change.dragging;
581
+ }
582
+ if (element.expandParent) {
583
+ handleParentExpand(elements, element);
584
+ }
585
+ break;
586
+ }
587
+ case 'dimensions': {
588
+ if (typeof change.dimensions !== 'undefined') {
589
+ element.computed ??= {};
590
+ element.computed.width = change.dimensions.width;
591
+ element.computed.height = change.dimensions.height;
592
+ if (change.resizing) {
593
+ element.width = change.dimensions.width;
594
+ element.height = change.dimensions.height;
542
595
  }
543
596
  }
544
- updatedElements.push(updateItem);
597
+ if (typeof change.resizing === 'boolean') {
598
+ element.resizing = change.resizing;
599
+ }
600
+ if (element.expandParent) {
601
+ handleParentExpand(elements, element);
602
+ }
603
+ break;
545
604
  }
546
605
  }
547
- return updatedElements;
548
606
  }
549
607
  /**
550
608
  * Drop in function that applies node changes to an array of nodes.
@@ -586,17 +644,19 @@ function applyNodeChanges(changes, nodes) {
586
644
  );
587
645
 
588
646
  return (
589
- <ReactFLow nodes={nodes} edges={edges} onEdgesChange={onEdgesChange} />
647
+ <ReactFlow nodes={nodes} edges={edges} onEdgesChange={onEdgesChange} />
590
648
  );
591
649
  */
592
650
  function applyEdgeChanges(changes, edges) {
593
651
  return applyChanges(changes, edges);
594
652
  }
595
- const createSelectionChange = (id, selected) => ({
596
- id,
597
- type: 'select',
598
- selected,
599
- });
653
+ function createSelectionChange(id, selected) {
654
+ return {
655
+ id,
656
+ type: 'select',
657
+ selected,
658
+ };
659
+ }
600
660
  function getSelectionChanges(items, selectedIds = new Set(), mutateItem = false) {
601
661
  const changes = [];
602
662
  for (const item of items) {
@@ -614,6 +674,26 @@ function getSelectionChanges(items, selectedIds = new Set(), mutateItem = false)
614
674
  }
615
675
  return changes;
616
676
  }
677
+ function getElementsDiffChanges({ items = [], lookup, }) {
678
+ const changes = [];
679
+ const itemsLookup = new Map(items.map((item) => [item.id, item]));
680
+ for (const item of items) {
681
+ const storeItem = lookup.get(item.id);
682
+ if (storeItem !== undefined && storeItem !== item) {
683
+ changes.push({ id: item.id, item: item, type: 'replace' });
684
+ }
685
+ if (storeItem === undefined) {
686
+ changes.push({ item: item, type: 'add' });
687
+ }
688
+ }
689
+ for (const [id] of lookup) {
690
+ const nextNode = itemsLookup.get(id);
691
+ if (nextNode === undefined) {
692
+ changes.push({ id, type: 'remove' });
693
+ }
694
+ }
695
+ return changes;
696
+ }
617
697
 
618
698
  /**
619
699
  * Test whether an object is useable as a Node
@@ -622,7 +702,7 @@ function getSelectionChanges(items, selectedIds = new Set(), mutateItem = false)
622
702
  * @param element - The element to test
623
703
  * @returns A boolean indicating whether the element is an Node
624
704
  */
625
- const isNode = (isNodeBase);
705
+ const isNode = (element) => isNodeBase(element);
626
706
  /**
627
707
  * Test whether an object is useable as an Edge
628
708
  * @public
@@ -630,50 +710,10 @@ const isNode = (isNodeBase);
630
710
  * @param element - The element to test
631
711
  * @returns A boolean indicating whether the element is an Edge
632
712
  */
633
- const isEdge = (isEdgeBase);
634
- /**
635
- * Pass in a node, and get connected nodes where edge.source === node.id
636
- * @public
637
- * @param node - The node to get the connected nodes from
638
- * @param nodes - The array of all nodes
639
- * @param edges - The array of all edges
640
- * @returns An array of nodes that are connected over eges where the source is the given node
641
- */
642
- const getOutgoers = (getOutgoersBase);
643
- /**
644
- * Pass in a node, and get connected nodes where edge.target === node.id
645
- * @public
646
- * @param node - The node to get the connected nodes from
647
- * @param nodes - The array of all nodes
648
- * @param edges - The array of all edges
649
- * @returns An array of nodes that are connected over eges where the target is the given node
650
- */
651
- const getIncomers = (getIncomersBase);
652
- /**
653
- * This util is a convenience function to add a new Edge to an array of edges
654
- * @remarks It also performs some validation to make sure you don't add an invalid edge or duplicate an existing one.
655
- * @public
656
- * @param edgeParams - Either an Edge or a Connection you want to add
657
- * @param edges - The array of all current edges
658
- * @returns A new array of edges with the new edge added
659
- */
660
- const addEdge = (addEdgeBase);
661
- /**
662
- * A handy utility to update an existing Edge with new properties
663
- * @param oldEdge - The edge you want to update
664
- * @param newConnection - The new connection you want to update the edge with
665
- * @param edges - The array of all current edges
666
- * @param options.shouldReplaceId - should the id of the old edge be replaced with the new connection id
667
- * @returns the updated edges array
668
- */
669
- const updateEdge = (updateEdgeBase);
670
- /**
671
- * Get all connecting edges for a given set of nodes
672
- * @param nodes - Nodes you want to get the connected edges for
673
- * @param edges - All edges
674
- * @returns Array of edges that connect any of the given nodes with each other
675
- */
676
- const getConnectedEdges = (getConnectedEdgesBase);
713
+ const isEdge = (element) => isEdgeBase(element);
714
+
715
+ // we need this hook to prevent a warning when using react-flow in SSR
716
+ const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
677
717
 
678
718
  /**
679
719
  * Hook for accessing the ReactFlow instance.
@@ -698,54 +738,86 @@ function useReactFlow() {
698
738
  const { edges = [] } = store.getState();
699
739
  return edges.find((e) => e.id === id);
700
740
  }, []);
701
- const setNodes = useCallback((payload) => {
702
- const { nodes, setNodes, hasDefaultNodes, onNodesChange } = store.getState();
703
- const nextNodes = typeof payload === 'function' ? payload(nodes) : payload;
704
- if (hasDefaultNodes) {
705
- setNodes(nextNodes);
741
+ // A reference of all the batched updates to process before the next render. We
742
+ // want a mutable reference here so multiple synchronous calls to `setNodes` etc
743
+ // can be batched together.
744
+ const setElementsQueue = useRef({ nodes: [], edges: [] });
745
+ // Because we're using a ref above, we need some way to let React know when to
746
+ // actually process the queue. We flip this bit of state to `true` any time we
747
+ // mutate the queue and then flip it back to `false` after flushing the queue.
748
+ const [shouldFlushQueue, setShouldFlushQueue] = useState(false);
749
+ // Layout effects are guaranteed to run before the next render which means we
750
+ // shouldn't run into any issues with stale state or weird issues that come from
751
+ // rendering things one frame later than expected (we used to use `setTimeout`).
752
+ useIsomorphicLayoutEffect(() => {
753
+ // Because we need to flip the state back to false after flushing, this should
754
+ // trigger the hook again (!). If the hook is being run again we know that any
755
+ // updates should have been processed by now and we can safely clear the queue
756
+ // and bail early.
757
+ if (!shouldFlushQueue) {
758
+ setElementsQueue.current = { nodes: [], edges: [] };
759
+ return;
760
+ }
761
+ if (setElementsQueue.current.nodes.length) {
762
+ const { nodes = [], setNodes, hasDefaultNodes, onNodesChange, nodeLookup } = store.getState();
763
+ // This is essentially an `Array.reduce` in imperative clothing. Processing
764
+ // this queue is a relatively hot path so we'd like to avoid the overhead of
765
+ // array methods where we can.
766
+ let next = nodes;
767
+ for (const payload of setElementsQueue.current.nodes) {
768
+ next = typeof payload === 'function' ? payload(next) : payload;
769
+ }
770
+ if (hasDefaultNodes) {
771
+ setNodes(next);
772
+ }
773
+ else if (onNodesChange) {
774
+ onNodesChange(getElementsDiffChanges({
775
+ items: next,
776
+ lookup: nodeLookup,
777
+ }));
778
+ }
779
+ setElementsQueue.current.nodes = [];
706
780
  }
707
- else if (onNodesChange) {
708
- const changes = nextNodes.length === 0
709
- ? nodes.map((node) => ({ type: 'remove', id: node.id }))
710
- : nextNodes.map((node) => ({ item: node, type: 'reset' }));
711
- onNodesChange(changes);
781
+ if (setElementsQueue.current.edges.length) {
782
+ const { edges = [], setEdges, hasDefaultEdges, onEdgesChange, edgeLookup } = store.getState();
783
+ let next = edges;
784
+ for (const payload of setElementsQueue.current.edges) {
785
+ next = typeof payload === 'function' ? payload(next) : payload;
786
+ }
787
+ if (hasDefaultEdges) {
788
+ setEdges(next);
789
+ }
790
+ else if (onEdgesChange) {
791
+ onEdgesChange(getElementsDiffChanges({
792
+ items: next,
793
+ lookup: edgeLookup,
794
+ }));
795
+ }
796
+ setElementsQueue.current.edges = [];
712
797
  }
798
+ // Beacuse we're using reactive state to trigger this effect, we need to flip
799
+ // it back to false.
800
+ setShouldFlushQueue(false);
801
+ }, [shouldFlushQueue]);
802
+ const setNodes = useCallback((payload) => {
803
+ setElementsQueue.current.nodes.push(payload);
804
+ setShouldFlushQueue(true);
713
805
  }, []);
714
806
  const setEdges = useCallback((payload) => {
715
- const { edges = [], setEdges, hasDefaultEdges, onEdgesChange } = store.getState();
716
- const nextEdges = typeof payload === 'function' ? payload(edges) : payload;
717
- if (hasDefaultEdges) {
718
- setEdges(nextEdges);
719
- }
720
- else if (onEdgesChange) {
721
- const changes = nextEdges.length === 0
722
- ? edges.map((edge) => ({ type: 'remove', id: edge.id }))
723
- : nextEdges.map((edge) => ({ item: edge, type: 'reset' }));
724
- onEdgesChange(changes);
725
- }
807
+ setElementsQueue.current.edges.push(payload);
808
+ setShouldFlushQueue(true);
726
809
  }, []);
727
810
  const addNodes = useCallback((payload) => {
728
- const nodes = Array.isArray(payload) ? payload : [payload];
729
- const { nodes: currentNodes, hasDefaultNodes, onNodesChange, setNodes } = store.getState();
730
- if (hasDefaultNodes) {
731
- const nextNodes = [...currentNodes, ...nodes];
732
- setNodes(nextNodes);
733
- }
734
- else if (onNodesChange) {
735
- const changes = nodes.map((node) => ({ item: node, type: 'add' }));
736
- onNodesChange(changes);
737
- }
811
+ const newNodes = Array.isArray(payload) ? payload : [payload];
812
+ // Queueing a functional update means that we won't worry about other calls
813
+ // to `setNodes` that might happen elsewhere.
814
+ setElementsQueue.current.nodes.push((nodes) => [...nodes, ...newNodes]);
815
+ setShouldFlushQueue(true);
738
816
  }, []);
739
817
  const addEdges = useCallback((payload) => {
740
- const nextEdges = Array.isArray(payload) ? payload : [payload];
741
- const { edges = [], setEdges, hasDefaultEdges, onEdgesChange } = store.getState();
742
- if (hasDefaultEdges) {
743
- setEdges([...edges, ...nextEdges]);
744
- }
745
- else if (onEdgesChange) {
746
- const changes = nextEdges.map((edge) => ({ item: edge, type: 'add' }));
747
- onEdgesChange(changes);
748
- }
818
+ const newEdges = Array.isArray(payload) ? payload : [payload];
819
+ setElementsQueue.current.edges.push((edges) => [...edges, ...newEdges]);
820
+ setShouldFlushQueue(true);
749
821
  }, []);
750
822
  const toObject = useCallback(() => {
751
823
  const { nodes = [], edges = [], transform } = store.getState();
@@ -760,8 +832,8 @@ function useReactFlow() {
760
832
  },
761
833
  };
762
834
  }, []);
763
- const deleteElements = useCallback(async ({ nodes: nodesToRemove = [], edges: edgesToRemove = [], onBeforeDelete }) => {
764
- const { nodes, edges, hasDefaultNodes, hasDefaultEdges, onNodesDelete, onEdgesDelete, onNodesChange, onEdgesChange, onDelete, } = store.getState();
835
+ const deleteElements = useCallback(async ({ nodes: nodesToRemove = [], edges: edgesToRemove = [] }) => {
836
+ const { nodes, edges, hasDefaultNodes, hasDefaultEdges, onNodesDelete, onEdgesDelete, onNodesChange, onEdgesChange, onDelete, onBeforeDelete, } = store.getState();
765
837
  const { nodes: matchingNodes, edges: matchingEdges } = await getElementsToRemove({
766
838
  nodesToRemove,
767
839
  edgesToRemove,
@@ -773,9 +845,8 @@ function useReactFlow() {
773
845
  const hasMatchingNodes = matchingNodes.length > 0;
774
846
  if (hasMatchingEdges) {
775
847
  if (hasDefaultEdges) {
776
- store.setState({
777
- edges: edges.filter((e) => !matchingEdges.some((mE) => mE.id === e.id)),
778
- });
848
+ const nextEdges = edges.filter((e) => !matchingEdges.some((mE) => mE.id === e.id));
849
+ store.getState().setEdges(nextEdges);
779
850
  }
780
851
  onEdgesDelete?.(matchingEdges);
781
852
  onEdgesChange?.(matchingEdges.map((edge) => ({
@@ -785,9 +856,8 @@ function useReactFlow() {
785
856
  }
786
857
  if (hasMatchingNodes) {
787
858
  if (hasDefaultNodes) {
788
- store.setState({
789
- nodes: nodes.filter((n) => !matchingNodes.some((mN) => mN.id === n.id)),
790
- });
859
+ const nextNodes = nodes.filter((n) => !matchingNodes.some((mN) => mN.id === n.id));
860
+ store.getState().setNodes(nextNodes);
791
861
  }
792
862
  onNodesDelete?.(matchingNodes);
793
863
  onNodesChange?.(matchingNodes.map((node) => ({ id: node.id, type: 'remove' })));
@@ -800,6 +870,9 @@ function useReactFlow() {
800
870
  const getNodeRect = useCallback((nodeOrRect) => {
801
871
  const isRect = isRectObject(nodeOrRect);
802
872
  const node = isRect ? null : store.getState().nodeLookup.get(nodeOrRect.id);
873
+ if (!isRect && !node) {
874
+ return [null, null, isRect];
875
+ }
803
876
  const nodeRect = isRect ? nodeOrRect : nodeToRect(node);
804
877
  return [nodeRect, node, isRect];
805
878
  }, []);
@@ -886,22 +959,22 @@ const deleteKeyOptions = { actInsideInputWithModifier: false };
886
959
  *
887
960
  * @internal
888
961
  */
889
- var useGlobalKeyHandler = ({ deleteKeyCode, multiSelectionKeyCode, }) => {
962
+ function useGlobalKeyHandler({ deleteKeyCode, multiSelectionKeyCode, }) {
890
963
  const store = useStoreApi();
891
964
  const { deleteElements } = useReactFlow();
892
965
  const deleteKeyPressed = useKeyPress(deleteKeyCode, deleteKeyOptions);
893
966
  const multiSelectionKeyPressed = useKeyPress(multiSelectionKeyCode);
894
967
  useEffect(() => {
895
968
  if (deleteKeyPressed) {
896
- const { edges, nodes, onBeforeDelete } = store.getState();
897
- deleteElements({ nodes: nodes.filter(selected), edges: edges.filter(selected), onBeforeDelete });
969
+ const { edges, nodes } = store.getState();
970
+ deleteElements({ nodes: nodes.filter(selected), edges: edges.filter(selected) });
898
971
  store.setState({ nodesSelectionActive: false });
899
972
  }
900
973
  }, [deleteKeyPressed]);
901
974
  useEffect(() => {
902
975
  store.setState({ multiSelectionActive: multiSelectionKeyPressed });
903
976
  }, [multiSelectionKeyPressed]);
904
- };
977
+ }
905
978
 
906
979
  /**
907
980
  * Hook for handling resize events.
@@ -948,7 +1021,7 @@ const selector$l = (s) => ({
948
1021
  userSelectionActive: s.userSelectionActive,
949
1022
  lib: s.lib,
950
1023
  });
951
- const ZoomPane = ({ onPaneContextMenu, zoomOnScroll = true, zoomOnPinch = true, panOnScroll = false, panOnScrollSpeed = 0.5, panOnScrollMode = PanOnScrollMode.Free, zoomOnDoubleClick = true, panOnDrag = true, defaultViewport, translateExtent, minZoom, maxZoom, zoomActivationKeyCode, preventScrolling = true, children, noWheelClassName, noPanClassName, onViewportChange, isControlledViewport, }) => {
1024
+ function ZoomPane({ onPaneContextMenu, zoomOnScroll = true, zoomOnPinch = true, panOnScroll = false, panOnScrollSpeed = 0.5, panOnScrollMode = PanOnScrollMode.Free, zoomOnDoubleClick = true, panOnDrag = true, defaultViewport, translateExtent, minZoom, maxZoom, zoomActivationKeyCode, preventScrolling = true, children, noWheelClassName, noPanClassName, onViewportChange, isControlledViewport, }) {
952
1025
  const store = useStoreApi();
953
1026
  const zoomPane = useRef(null);
954
1027
  const { userSelectionActive, lib } = useStore(selector$l, shallow);
@@ -1031,7 +1104,7 @@ const ZoomPane = ({ onPaneContextMenu, zoomOnScroll = true, zoomOnPinch = true,
1031
1104
  lib,
1032
1105
  ]);
1033
1106
  return (jsx("div", { className: "react-flow__renderer", ref: zoomPane, style: containerStyle, children: children }));
1034
- };
1107
+ }
1035
1108
 
1036
1109
  const selector$k = (s) => ({
1037
1110
  userSelectionActive: s.userSelectionActive,
@@ -1063,7 +1136,7 @@ const selector$j = (s) => ({
1063
1136
  elementsSelectable: s.elementsSelectable,
1064
1137
  dragging: s.paneDragging,
1065
1138
  });
1066
- const Pane = memo(({ isSelecting, selectionMode = SelectionMode.Full, panOnDrag, onSelectionStart, onSelectionEnd, onPaneClick, onPaneContextMenu, onPaneScroll, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, children, }) => {
1139
+ function Pane({ isSelecting, selectionMode = SelectionMode.Full, panOnDrag, onSelectionStart, onSelectionEnd, onPaneClick, onPaneContextMenu, onPaneScroll, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, children, }) {
1067
1140
  const container = useRef(null);
1068
1141
  const store = useStoreApi();
1069
1142
  const prevSelectedNodesCount = useRef(0);
@@ -1179,9 +1252,8 @@ const Pane = memo(({ isSelecting, selectionMode = SelectionMode.Full, panOnDrag,
1179
1252
  resetUserSelection();
1180
1253
  };
1181
1254
  const hasActiveSelection = elementsSelectable && (isSelecting || userSelectionActive);
1182
- return (jsxs("div", { className: cc(['react-flow__pane', { dragging, selection: isSelecting }]), onClick: hasActiveSelection ? undefined : wrapHandler(onClick, container), onContextMenu: wrapHandler(onContextMenu, container), onWheel: wrapHandler(onWheel, container), onMouseEnter: hasActiveSelection ? undefined : onPaneMouseEnter, onMouseDown: hasActiveSelection ? onMouseDown : undefined, onMouseMove: hasActiveSelection ? onMouseMove : onPaneMouseMove, onMouseUp: hasActiveSelection ? onMouseUp : undefined, onMouseLeave: hasActiveSelection ? onMouseLeave : onPaneMouseLeave, ref: container, style: containerStyle, children: [children, jsx(UserSelection, {})] }));
1183
- });
1184
- Pane.displayName = 'Pane';
1255
+ return (jsxs("div", { className: cc(['react-flow__pane', { draggable: panOnDrag, dragging, selection: isSelecting }]), onClick: hasActiveSelection ? undefined : wrapHandler(onClick, container), onContextMenu: wrapHandler(onContextMenu, container), onWheel: wrapHandler(onWheel, container), onMouseEnter: hasActiveSelection ? undefined : onPaneMouseEnter, onMouseDown: hasActiveSelection ? onMouseDown : undefined, onMouseMove: hasActiveSelection ? onMouseMove : onPaneMouseMove, onMouseUp: hasActiveSelection ? onMouseUp : undefined, onMouseLeave: hasActiveSelection ? onMouseLeave : onPaneMouseLeave, ref: container, style: containerStyle, children: [children, jsx(UserSelection, {})] }));
1256
+ }
1185
1257
 
1186
1258
  // this handler is called by
1187
1259
  // 1. the click handler when node is not draggable or selectNodesOnDrag = false
@@ -1209,36 +1281,33 @@ function handleNodeClick({ id, store, unselect = false, nodeRef, }) {
1209
1281
  *
1210
1282
  * @internal
1211
1283
  */
1212
- function useDrag({ nodeRef, disabled = false, noDragClassName, handleSelector, nodeId, isSelectable }) {
1284
+ function useDrag({ nodeRef, disabled = false, noDragClassName, handleSelector, nodeId, isSelectable, }) {
1213
1285
  const store = useStoreApi();
1214
1286
  const [dragging, setDragging] = useState(false);
1215
1287
  const xyDrag = useRef();
1216
1288
  useEffect(() => {
1217
- if (nodeRef?.current) {
1218
- xyDrag.current = XYDrag({
1219
- domNode: nodeRef.current,
1220
- getStoreItems: () => store.getState(),
1221
- onNodeMouseDown: (id) => {
1222
- handleNodeClick({
1223
- id,
1224
- store,
1225
- nodeRef: nodeRef,
1226
- });
1227
- },
1228
- onDragStart: () => {
1229
- setDragging(true);
1230
- },
1231
- onDragStop: () => {
1232
- setDragging(false);
1233
- },
1234
- });
1235
- }
1289
+ xyDrag.current = XYDrag({
1290
+ getStoreItems: () => store.getState(),
1291
+ onNodeMouseDown: (id) => {
1292
+ handleNodeClick({
1293
+ id,
1294
+ store,
1295
+ nodeRef,
1296
+ });
1297
+ },
1298
+ onDragStart: () => {
1299
+ setDragging(true);
1300
+ },
1301
+ onDragStop: () => {
1302
+ setDragging(false);
1303
+ },
1304
+ });
1236
1305
  }, []);
1237
1306
  useEffect(() => {
1238
1307
  if (disabled) {
1239
1308
  xyDrag.current?.destroy();
1240
1309
  }
1241
- else {
1310
+ else if (nodeRef.current) {
1242
1311
  xyDrag.current?.update({
1243
1312
  noDragClassName,
1244
1313
  handleSelector,
@@ -1256,44 +1325,47 @@ function useDrag({ nodeRef, disabled = false, noDragClassName, handleSelector, n
1256
1325
 
1257
1326
  const selectedAndDraggable = (nodesDraggable) => (n) => n.selected && (n.draggable || (nodesDraggable && typeof n.draggable === 'undefined'));
1258
1327
  /**
1259
- * Hook for updating node positions.
1328
+ * Hook for updating node positions by passing a direction and factor
1260
1329
  *
1261
1330
  * @internal
1262
1331
  * @returns function for updating node positions
1263
1332
  */
1264
- function useUpdateNodePositions() {
1333
+ function useMoveSelectedNodes() {
1265
1334
  const store = useStoreApi();
1266
- const updatePositions = useCallback((params) => {
1267
- const { nodeExtent, nodes, snapToGrid, snapGrid, nodesDraggable, onError, updateNodePositions } = store.getState();
1335
+ const moveSelectedNodes = useCallback((params) => {
1336
+ const { nodeExtent, nodes, snapToGrid, snapGrid, nodesDraggable, onError, updateNodePositions, nodeLookup, nodeOrigin, } = store.getState();
1268
1337
  const selectedNodes = nodes.filter(selectedAndDraggable(nodesDraggable));
1269
- // by default a node moves 5px on each key press, or 20px if shift is pressed
1270
- // if snap grid is enabled, we use that for the velocity.
1338
+ // by default a node moves 5px on each key press
1339
+ // if snap grid is enabled, we use that for the velocity
1271
1340
  const xVelo = snapToGrid ? snapGrid[0] : 5;
1272
1341
  const yVelo = snapToGrid ? snapGrid[1] : 5;
1273
- const factor = params.isShiftPressed ? 4 : 1;
1274
- const xDiff = params.x * xVelo * factor;
1275
- const yDiff = params.y * yVelo * factor;
1342
+ const xDiff = params.direction.x * xVelo * params.factor;
1343
+ const yDiff = params.direction.y * yVelo * params.factor;
1276
1344
  const nodeUpdates = selectedNodes.map((node) => {
1277
1345
  if (node.computed?.positionAbsolute) {
1278
1346
  let nextPosition = {
1279
- x: node.computed?.positionAbsolute.x + xDiff,
1280
- y: node.computed?.positionAbsolute.y + yDiff,
1347
+ x: node.computed.positionAbsolute.x + xDiff,
1348
+ y: node.computed.positionAbsolute.y + yDiff,
1281
1349
  };
1282
1350
  if (snapToGrid) {
1283
1351
  nextPosition = snapPosition(nextPosition, snapGrid);
1284
1352
  }
1285
- const { positionAbsolute, position } = calcNextPosition(node, nextPosition, nodes, nodeExtent, undefined, onError);
1353
+ const { position, positionAbsolute } = calculateNodePosition({
1354
+ nodeId: node.id,
1355
+ nextPosition,
1356
+ nodeLookup,
1357
+ nodeExtent,
1358
+ nodeOrigin,
1359
+ onError,
1360
+ });
1286
1361
  node.position = position;
1287
- if (!node.computed) {
1288
- node.computed = {};
1289
- }
1290
1362
  node.computed.positionAbsolute = positionAbsolute;
1291
1363
  }
1292
1364
  return node;
1293
1365
  });
1294
- updateNodePositions(nodeUpdates, true, false);
1366
+ updateNodePositions(nodeUpdates);
1295
1367
  }, []);
1296
- return updatePositions;
1368
+ return moveSelectedNodes;
1297
1369
  }
1298
1370
 
1299
1371
  const NodeIdContext = createContext(null);
@@ -1305,25 +1377,31 @@ const useNodeId = () => {
1305
1377
  };
1306
1378
 
1307
1379
  const selector$i = (s) => ({
1308
- connectionStartHandle: s.connectionStartHandle,
1309
1380
  connectOnClick: s.connectOnClick,
1310
1381
  noPanClassName: s.noPanClassName,
1382
+ rfId: s.rfId,
1311
1383
  });
1312
1384
  const connectingSelector = (nodeId, handleId, type) => (state) => {
1313
- const { connectionStartHandle: startHandle, connectionEndHandle: endHandle, connectionClickStartHandle: clickHandle, } = state;
1385
+ const { connectionStartHandle: startHandle, connectionEndHandle: endHandle, connectionClickStartHandle: clickHandle, connectionMode, connectionStatus, } = state;
1386
+ const connectingTo = endHandle?.nodeId === nodeId && endHandle?.handleId === handleId && endHandle?.type === type;
1314
1387
  return {
1315
- connecting: (startHandle?.nodeId === nodeId && startHandle?.handleId === handleId && startHandle?.type === type) ||
1316
- (endHandle?.nodeId === nodeId && endHandle?.handleId === handleId && endHandle?.type === type),
1388
+ connectingFrom: startHandle?.nodeId === nodeId && startHandle?.handleId === handleId && startHandle?.type === type,
1389
+ connectingTo,
1317
1390
  clickConnecting: clickHandle?.nodeId === nodeId && clickHandle?.handleId === handleId && clickHandle?.type === type,
1391
+ isPossibleEndHandle: connectionMode === ConnectionMode.Strict
1392
+ ? startHandle?.type !== type
1393
+ : nodeId !== startHandle?.nodeId || handleId !== startHandle?.handleId,
1394
+ connectionInProcess: !!startHandle,
1395
+ valid: connectingTo && connectionStatus === 'valid',
1318
1396
  };
1319
1397
  };
1320
- const Handle = forwardRef(({ type = 'source', position = Position.Top, isValidConnection, isConnectable = true, isConnectableStart = true, isConnectableEnd = true, id, onConnect, children, className, onMouseDown, onTouchStart, ...rest }, ref) => {
1398
+ const HandleComponent = forwardRef(({ type = 'source', position = Position.Top, isValidConnection, isConnectable = true, isConnectableStart = true, isConnectableEnd = true, id, onConnect, children, className, onMouseDown, onTouchStart, ...rest }, ref) => {
1321
1399
  const handleId = id || null;
1322
1400
  const isTarget = type === 'target';
1323
1401
  const store = useStoreApi();
1324
1402
  const nodeId = useNodeId();
1325
- const { connectOnClick, noPanClassName } = useStore(selector$i, shallow);
1326
- const { connecting, clickConnecting } = useStore(connectingSelector(nodeId, handleId, type), shallow);
1403
+ const { connectOnClick, noPanClassName, rfId } = useStore(selector$i, shallow);
1404
+ const { connectingFrom, connectingTo, clickConnecting, isPossibleEndHandle, connectionInProcess, valid } = useStore(connectingSelector(nodeId, handleId, type), shallow);
1327
1405
  if (!nodeId) {
1328
1406
  store.getState().onError?.('010', errorMessages['error010']());
1329
1407
  }
@@ -1358,6 +1436,7 @@ const Handle = forwardRef(({ type = 'source', position = Position.Top, isValidCo
1358
1436
  isTarget,
1359
1437
  handleId,
1360
1438
  nodeId,
1439
+ flowId: currentStore.rfId,
1361
1440
  panBy: currentStore.panBy,
1362
1441
  cancelConnection: currentStore.cancelConnection,
1363
1442
  onConnectStart: currentStore.onConnectStart,
@@ -1376,7 +1455,7 @@ const Handle = forwardRef(({ type = 'source', position = Position.Top, isValidCo
1376
1455
  }
1377
1456
  };
1378
1457
  const onClick = (event) => {
1379
- const { onClickConnectStart, onClickConnectEnd, connectionClickStartHandle, connectionMode, isValidConnection: isValidConnectionStore, lib, } = store.getState();
1458
+ const { onClickConnectStart, onClickConnectEnd, connectionClickStartHandle, connectionMode, isValidConnection: isValidConnectionStore, lib, rfId: flowId, } = store.getState();
1380
1459
  if (!nodeId || (!connectionClickStartHandle && !isConnectableStart)) {
1381
1460
  return;
1382
1461
  }
@@ -1398,6 +1477,7 @@ const Handle = forwardRef(({ type = 'source', position = Position.Top, isValidCo
1398
1477
  fromHandleId: connectionClickStartHandle.handleId || null,
1399
1478
  fromType: connectionClickStartHandle.type,
1400
1479
  isValidConnection: isValidConnectionHandler,
1480
+ flowId,
1401
1481
  doc,
1402
1482
  lib,
1403
1483
  });
@@ -1407,7 +1487,7 @@ const Handle = forwardRef(({ type = 'source', position = Position.Top, isValidCo
1407
1487
  onClickConnectEnd?.(event);
1408
1488
  store.setState({ connectionClickStartHandle: null });
1409
1489
  };
1410
- return (jsx("div", { "data-handleid": handleId, "data-nodeid": nodeId, "data-handlepos": position, "data-id": `${nodeId}-${handleId}-${type}`, className: cc([
1490
+ return (jsx("div", { "data-handleid": handleId, "data-nodeid": nodeId, "data-handlepos": position, "data-id": `${rfId}-${nodeId}-${handleId}-${type}`, className: cc([
1411
1491
  'react-flow__handle',
1412
1492
  `react-flow__handle-${position}`,
1413
1493
  'nodrag',
@@ -1419,31 +1499,39 @@ const Handle = forwardRef(({ type = 'source', position = Position.Top, isValidCo
1419
1499
  connectable: isConnectable,
1420
1500
  connectablestart: isConnectableStart,
1421
1501
  connectableend: isConnectableEnd,
1422
- connecting: clickConnecting,
1423
- // this class is used to style the handle when the user is connecting
1424
- connectionindicator: isConnectable && ((isConnectableStart && !connecting) || (isConnectableEnd && connecting)),
1502
+ clickconnecting: clickConnecting,
1503
+ connectingfrom: connectingFrom,
1504
+ connectingto: connectingTo,
1505
+ valid,
1506
+ // shows where you can start a connection from
1507
+ // and where you can end it while connecting
1508
+ connectionindicator: isConnectable &&
1509
+ (!connectionInProcess || isPossibleEndHandle) &&
1510
+ (connectionInProcess ? isConnectableEnd : isConnectableStart),
1425
1511
  },
1426
1512
  ]), onMouseDown: onPointerDown, onTouchStart: onPointerDown, onClick: connectOnClick ? onClick : undefined, ref: ref, ...rest, children: children }));
1427
1513
  });
1428
- Handle.displayName = 'Handle';
1429
- var Handle$1 = memo(Handle);
1514
+ HandleComponent.displayName = 'Handle';
1515
+ /**
1516
+ * The Handle component is the part of a node that can be used to connect nodes.
1517
+ */
1518
+ const Handle = memo(HandleComponent);
1430
1519
 
1431
- const InputNode = ({ data, isConnectable, sourcePosition = Position.Bottom }) => (jsxs(Fragment, { children: [data?.label, jsx(Handle$1, { type: "source", position: sourcePosition, isConnectable: isConnectable })] }));
1432
- InputNode.displayName = 'InputNode';
1433
- var InputNode$1 = memo(InputNode);
1520
+ function InputNode({ data, isConnectable, sourcePosition = Position.Bottom }) {
1521
+ return (jsxs(Fragment, { children: [data?.label, jsx(Handle, { type: "source", position: sourcePosition, isConnectable: isConnectable })] }));
1522
+ }
1434
1523
 
1435
- const DefaultNode = ({ data, isConnectable, targetPosition = Position.Top, sourcePosition = Position.Bottom, }) => {
1436
- return (jsxs(Fragment, { children: [jsx(Handle$1, { type: "target", position: targetPosition, isConnectable: isConnectable }), data?.label, jsx(Handle$1, { type: "source", position: sourcePosition, isConnectable: isConnectable })] }));
1437
- };
1438
- DefaultNode.displayName = 'DefaultNode';
1439
- var DefaultNode$1 = memo(DefaultNode);
1524
+ function DefaultNode({ data, isConnectable, targetPosition = Position.Top, sourcePosition = Position.Bottom, }) {
1525
+ return (jsxs(Fragment, { children: [jsx(Handle, { type: "target", position: targetPosition, isConnectable: isConnectable }), data?.label, jsx(Handle, { type: "source", position: sourcePosition, isConnectable: isConnectable })] }));
1526
+ }
1440
1527
 
1441
- const GroupNode = () => null;
1442
- GroupNode.displayName = 'GroupNode';
1528
+ function GroupNode() {
1529
+ return null;
1530
+ }
1443
1531
 
1444
- const OutputNode = ({ data, isConnectable, targetPosition = Position.Top }) => (jsxs(Fragment, { children: [jsx(Handle$1, { type: "target", position: targetPosition, isConnectable: isConnectable }), data?.label] }));
1445
- OutputNode.displayName = 'OutputNode';
1446
- var OutputNode$1 = memo(OutputNode);
1532
+ function OutputNode({ data, isConnectable, targetPosition = Position.Top }) {
1533
+ return (jsxs(Fragment, { children: [jsx(Handle, { type: "target", position: targetPosition, isConnectable: isConnectable }), data?.label] }));
1534
+ }
1447
1535
 
1448
1536
  const arrowKeyDiffs = {
1449
1537
  ArrowUp: { x: 0, y: -1 },
@@ -1452,15 +1540,27 @@ const arrowKeyDiffs = {
1452
1540
  ArrowRight: { x: 1, y: 0 },
1453
1541
  };
1454
1542
  const builtinNodeTypes = {
1455
- input: InputNode$1,
1456
- default: DefaultNode$1,
1457
- output: OutputNode$1,
1543
+ input: InputNode,
1544
+ default: DefaultNode,
1545
+ output: OutputNode,
1458
1546
  group: GroupNode,
1459
1547
  };
1548
+ function getNodeInlineStyleDimensions(node) {
1549
+ if (!node.computed) {
1550
+ return {
1551
+ width: node.width ?? node.initialWidth ?? node.style?.width,
1552
+ height: node.height ?? node.initialHeight ?? node.style?.height,
1553
+ };
1554
+ }
1555
+ return {
1556
+ width: node.width ?? node.style?.width,
1557
+ height: node.height ?? node.style?.height,
1558
+ };
1559
+ }
1460
1560
 
1461
1561
  const selector$h = (s) => {
1462
1562
  const selectedNodes = s.nodes.filter((n) => n.selected);
1463
- const { width, height, x, y } = getNodesBounds(selectedNodes, s.nodeOrigin);
1563
+ const { width, height, x, y } = getNodesBounds(selectedNodes, { nodeOrigin: s.nodeOrigin });
1464
1564
  return {
1465
1565
  width,
1466
1566
  height,
@@ -1468,10 +1568,10 @@ const selector$h = (s) => {
1468
1568
  transformString: `translate(${s.transform[0]}px,${s.transform[1]}px) scale(${s.transform[2]}) translate(${x}px,${y}px)`,
1469
1569
  };
1470
1570
  };
1471
- function NodesSelection({ onSelectionContextMenu, noPanClassName, disableKeyboardA11y }) {
1571
+ function NodesSelection({ onSelectionContextMenu, noPanClassName, disableKeyboardA11y, }) {
1472
1572
  const store = useStoreApi();
1473
1573
  const { width, height, transformString, userSelectionActive } = useStore(selector$h, shallow);
1474
- const updatePositions = useUpdateNodePositions();
1574
+ const moveSelectedNodes = useMoveSelectedNodes();
1475
1575
  const nodeRef = useRef(null);
1476
1576
  useEffect(() => {
1477
1577
  if (!disableKeyboardA11y) {
@@ -1494,10 +1594,9 @@ function NodesSelection({ onSelectionContextMenu, noPanClassName, disableKeyboar
1494
1594
  : undefined;
1495
1595
  const onKeyDown = (event) => {
1496
1596
  if (Object.prototype.hasOwnProperty.call(arrowKeyDiffs, event.key)) {
1497
- updatePositions({
1498
- x: arrowKeyDiffs[event.key].x,
1499
- y: arrowKeyDiffs[event.key].y,
1500
- isShiftPressed: event.shiftKey,
1597
+ moveSelectedNodes({
1598
+ direction: arrowKeyDiffs[event.key],
1599
+ factor: event.shiftKey ? 4 : 1,
1501
1600
  });
1502
1601
  }
1503
1602
  };
@@ -1508,21 +1607,22 @@ function NodesSelection({ onSelectionContextMenu, noPanClassName, disableKeyboar
1508
1607
  height,
1509
1608
  } }) }));
1510
1609
  }
1511
- var NodesSelection$1 = memo(NodesSelection);
1512
1610
 
1513
- const selector$g = (s) => s.nodesSelectionActive;
1514
- const FlowRenderer = ({ 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, }) => {
1515
- const nodesSelectionActive = useStore(selector$g);
1611
+ const selector$g = (s) => {
1612
+ return { nodesSelectionActive: s.nodesSelectionActive, userSelectionActive: s.userSelectionActive };
1613
+ };
1614
+ function 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, }) {
1615
+ const { nodesSelectionActive, userSelectionActive } = useStore(selector$g);
1516
1616
  const selectionKeyPressed = useKeyPress(selectionKeyCode);
1517
1617
  const panActivationKeyPressed = useKeyPress(panActivationKeyCode);
1518
1618
  const panOnDrag = panActivationKeyPressed || _panOnDrag;
1519
1619
  const panOnScroll = panActivationKeyPressed || _panOnScroll;
1520
- const isSelecting = selectionKeyPressed || (selectionOnDrag && panOnDrag !== true);
1620
+ const isSelecting = selectionKeyPressed || userSelectionActive || (selectionOnDrag && panOnDrag !== true);
1521
1621
  useGlobalKeyHandler({ deleteKeyCode, multiSelectionKeyCode });
1522
- 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$1, { onSelectionContextMenu: onSelectionContextMenu, noPanClassName: noPanClassName, disableKeyboardA11y: disableKeyboardA11y }))] }) }));
1523
- };
1524
- FlowRenderer.displayName = 'FlowRenderer';
1525
- var FlowRenderer$1 = memo(FlowRenderer);
1622
+ 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 }))] }) }));
1623
+ }
1624
+ FlowRendererComponent.displayName = 'FlowRenderer';
1625
+ const FlowRenderer = memo(FlowRendererComponent);
1526
1626
 
1527
1627
  const selector$f = (onlyRenderVisible) => (s) => {
1528
1628
  return onlyRenderVisible
@@ -1572,7 +1672,7 @@ function useResizeObserver() {
1572
1672
  return resizeObserver;
1573
1673
  }
1574
1674
 
1575
- const NodeWrapper = ({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onContextMenu, onDoubleClick, nodesDraggable, elementsSelectable, nodesConnectable, nodesFocusable, resizeObserver, noDragClassName, noPanClassName, disableKeyboardA11y, rfId, nodeTypes, nodeExtent, nodeOrigin, onError, }) => {
1675
+ function NodeWrapper({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onContextMenu, onDoubleClick, nodesDraggable, elementsSelectable, nodesConnectable, nodesFocusable, resizeObserver, noDragClassName, noPanClassName, disableKeyboardA11y, rfId, nodeTypes, nodeExtent, nodeOrigin, onError, }) {
1576
1676
  const { node, positionAbsoluteX, positionAbsoluteY, zIndex, isParent } = useStore((s) => {
1577
1677
  const node = s.nodeLookup.get(id);
1578
1678
  const positionAbsolute = nodeExtent
@@ -1604,14 +1704,27 @@ const NodeWrapper = ({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onC
1604
1704
  const prevSourcePosition = useRef(node.sourcePosition);
1605
1705
  const prevTargetPosition = useRef(node.targetPosition);
1606
1706
  const prevType = useRef(nodeType);
1607
- const updatePositions = useUpdateNodePositions();
1707
+ const nodeDimensions = getNodeDimensions(node);
1708
+ const inlineDimensions = getNodeInlineStyleDimensions(node);
1709
+ const initialized = nodeHasDimensions(node);
1710
+ const hasHandleBounds = !!node[internalsSymbol]?.handleBounds;
1711
+ const moveSelectedNodes = useMoveSelectedNodes();
1712
+ useEffect(() => {
1713
+ return () => {
1714
+ if (nodeRef.current) {
1715
+ resizeObserver?.unobserve(nodeRef.current);
1716
+ }
1717
+ };
1718
+ }, []);
1608
1719
  useEffect(() => {
1609
1720
  if (nodeRef.current && !node.hidden) {
1610
1721
  const currNode = nodeRef.current;
1611
- resizeObserver?.observe(currNode);
1612
- return () => resizeObserver?.unobserve(currNode);
1722
+ if (!initialized || !hasHandleBounds) {
1723
+ resizeObserver?.unobserve(currNode);
1724
+ resizeObserver?.observe(currNode);
1725
+ }
1613
1726
  }
1614
- }, [node.hidden]);
1727
+ }, [node.hidden, initialized, hasHandleBounds]);
1615
1728
  useEffect(() => {
1616
1729
  // when the user programmatically changes the source or handle position, we re-initialize the node
1617
1730
  const typeChanged = prevType.current !== nodeType;
@@ -1641,18 +1754,12 @@ const NodeWrapper = ({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onC
1641
1754
  if (node.hidden) {
1642
1755
  return null;
1643
1756
  }
1644
- const width = node.width ?? undefined;
1645
- const height = node.height ?? undefined;
1646
- const computedWidth = node.computed?.width;
1647
- const computedHeight = node.computed?.height;
1648
1757
  const positionAbsoluteOrigin = getPositionWithOrigin({
1649
1758
  x: positionAbsoluteX,
1650
1759
  y: positionAbsoluteY,
1651
- width: computedWidth ?? width ?? 0,
1652
- height: computedHeight ?? height ?? 0,
1760
+ ...nodeDimensions,
1653
1761
  origin: node.origin || nodeOrigin,
1654
1762
  });
1655
- const initialized = (!!computedWidth && !!computedHeight) || (!!width && !!height);
1656
1763
  const hasPointerEvents = isSelectable || isDraggable || onClick || onMouseEnter || onMouseMove || onMouseLeave;
1657
1764
  const onMouseEnterHandler = onMouseEnter ? (event) => onMouseEnter(event, { ...node }) : undefined;
1658
1765
  const onMouseMoveHandler = onMouseMove ? (event) => onMouseMove(event, { ...node }) : undefined;
@@ -1675,7 +1782,7 @@ const NodeWrapper = ({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onC
1675
1782
  }
1676
1783
  };
1677
1784
  const onKeyDown = (event) => {
1678
- if (isInputDOMNode(event.nativeEvent)) {
1785
+ if (isInputDOMNode(event.nativeEvent) || disableKeyboardA11y) {
1679
1786
  return;
1680
1787
  }
1681
1788
  if (elementSelectionKeys.includes(event.key) && isSelectable) {
@@ -1687,19 +1794,15 @@ const NodeWrapper = ({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onC
1687
1794
  nodeRef,
1688
1795
  });
1689
1796
  }
1690
- else if (!disableKeyboardA11y &&
1691
- isDraggable &&
1692
- node.selected &&
1693
- Object.prototype.hasOwnProperty.call(arrowKeyDiffs, event.key)) {
1797
+ else if (isDraggable && node.selected && Object.prototype.hasOwnProperty.call(arrowKeyDiffs, event.key)) {
1694
1798
  store.setState({
1695
1799
  ariaLiveMessage: `Moved selected node ${event.key
1696
1800
  .replace('Arrow', '')
1697
1801
  .toLowerCase()}. New position, x: ${~~positionAbsoluteX}, y: ${~~positionAbsoluteY}`,
1698
1802
  });
1699
- updatePositions({
1700
- x: arrowKeyDiffs[event.key].x,
1701
- y: arrowKeyDiffs[event.key].y,
1702
- isShiftPressed: event.shiftKey,
1803
+ moveSelectedNodes({
1804
+ direction: arrowKeyDiffs[event.key],
1805
+ factor: event.shiftKey ? 4 : 1,
1703
1806
  });
1704
1807
  }
1705
1808
  };
@@ -1715,6 +1818,7 @@ const NodeWrapper = ({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onC
1715
1818
  selected: node.selected,
1716
1819
  selectable: isSelectable,
1717
1820
  parent: isParent,
1821
+ draggable: isDraggable,
1718
1822
  dragging,
1719
1823
  },
1720
1824
  ]), ref: nodeRef, style: {
@@ -1722,13 +1826,10 @@ const NodeWrapper = ({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onC
1722
1826
  transform: `translate(${positionAbsoluteOrigin.x}px,${positionAbsoluteOrigin.y}px)`,
1723
1827
  pointerEvents: hasPointerEvents ? 'all' : 'none',
1724
1828
  visibility: initialized ? 'visible' : 'hidden',
1725
- width,
1726
- height,
1727
1829
  ...node.style,
1728
- }, "data-id": id, "data-testid": `rf__node-${id}`, onMouseEnter: onMouseEnterHandler, onMouseMove: onMouseMoveHandler, onMouseLeave: onMouseLeaveHandler, onContextMenu: onContextMenuHandler, onClick: onSelectNodeHandler, onDoubleClick: onDoubleClickHandler, onKeyDown: isFocusable ? onKeyDown : undefined, tabIndex: isFocusable ? 0 : undefined, role: isFocusable ? 'button' : undefined, "aria-describedby": disableKeyboardA11y ? undefined : `${ARIA_NODE_DESC_KEY}-${rfId}`, "aria-label": node.ariaLabel, children: jsx(Provider, { value: id, children: jsx(NodeComponent, { id: id, data: node.data, type: nodeType, width: computedWidth, height: computedHeight, positionAbsoluteX: positionAbsoluteX, positionAbsoluteY: positionAbsoluteY, selected: node.selected, isConnectable: isConnectable, sourcePosition: node.sourcePosition, targetPosition: node.targetPosition, dragging: dragging, dragHandle: node.dragHandle, zIndex: zIndex }) }) }));
1729
- };
1730
- NodeWrapper.displayName = 'NodeWrapper';
1731
- var NodeWrapper$1 = memo(NodeWrapper);
1830
+ ...inlineDimensions,
1831
+ }, "data-id": id, "data-testid": `rf__node-${id}`, onMouseEnter: onMouseEnterHandler, onMouseMove: onMouseMoveHandler, onMouseLeave: onMouseLeaveHandler, onContextMenu: onContextMenuHandler, onClick: onSelectNodeHandler, onDoubleClick: onDoubleClickHandler, onKeyDown: isFocusable ? onKeyDown : undefined, tabIndex: isFocusable ? 0 : undefined, role: isFocusable ? 'button' : undefined, "aria-describedby": disableKeyboardA11y ? undefined : `${ARIA_NODE_DESC_KEY}-${rfId}`, "aria-label": node.ariaLabel, children: jsx(Provider, { value: id, children: jsx(NodeComponent, { id: id, data: node.data, type: nodeType, positionAbsoluteX: positionAbsoluteX, positionAbsoluteY: positionAbsoluteY, selected: node.selected, isConnectable: isConnectable, sourcePosition: node.sourcePosition, targetPosition: node.targetPosition, dragging: dragging, dragHandle: node.dragHandle, zIndex: zIndex, ...nodeDimensions }) }) }));
1832
+ }
1732
1833
 
1733
1834
  const selector$d = (s) => ({
1734
1835
  nodesDraggable: s.nodesDraggable,
@@ -1737,7 +1838,7 @@ const selector$d = (s) => ({
1737
1838
  elementsSelectable: s.elementsSelectable,
1738
1839
  onError: s.onError,
1739
1840
  });
1740
- const NodeRenderer = (props) => {
1841
+ function NodeRendererComponent(props) {
1741
1842
  const { nodesDraggable, nodesConnectable, nodesFocusable, elementsSelectable, onError } = useStore(selector$d, shallow);
1742
1843
  const nodeIds = useVisibleNodeIds(props.onlyRenderVisibleElements);
1743
1844
  const resizeObserver = useResizeObserver();
@@ -1766,11 +1867,11 @@ const NodeRenderer = (props) => {
1766
1867
  // moved into `NodeComponentWrapper`. This ensures they are
1767
1868
  // memorized – so if `NodeRenderer` *has* to rerender, it only
1768
1869
  // needs to regenerate the list of nodes, nothing else.
1769
- jsx(NodeWrapper$1, { id: nodeId, nodeTypes: props.nodeTypes, nodeExtent: props.nodeExtent, nodeOrigin: props.nodeOrigin, onClick: props.onNodeClick, onMouseEnter: props.onNodeMouseEnter, onMouseMove: props.onNodeMouseMove, onMouseLeave: props.onNodeMouseLeave, onContextMenu: props.onNodeContextMenu, onDoubleClick: props.onNodeDoubleClick, noDragClassName: props.noDragClassName, noPanClassName: props.noPanClassName, rfId: props.rfId, disableKeyboardA11y: props.disableKeyboardA11y, resizeObserver: resizeObserver, nodesDraggable: nodesDraggable, nodesConnectable: nodesConnectable, nodesFocusable: nodesFocusable, elementsSelectable: elementsSelectable, onError: onError }, nodeId));
1870
+ jsx(NodeWrapper, { id: nodeId, nodeTypes: props.nodeTypes, nodeExtent: props.nodeExtent, nodeOrigin: props.nodeOrigin, onClick: props.onNodeClick, onMouseEnter: props.onNodeMouseEnter, onMouseMove: props.onNodeMouseMove, onMouseLeave: props.onNodeMouseLeave, onContextMenu: props.onNodeContextMenu, onDoubleClick: props.onNodeDoubleClick, noDragClassName: props.noDragClassName, noPanClassName: props.noPanClassName, rfId: props.rfId, disableKeyboardA11y: props.disableKeyboardA11y, resizeObserver: resizeObserver, nodesDraggable: nodesDraggable, nodesConnectable: nodesConnectable, nodesFocusable: nodesFocusable, elementsSelectable: elementsSelectable, onError: onError }, nodeId));
1770
1871
  }) }));
1771
- };
1772
- NodeRenderer.displayName = 'NodeRenderer';
1773
- var NodeRenderer$1 = memo(NodeRenderer);
1872
+ }
1873
+ NodeRendererComponent.displayName = 'NodeRenderer';
1874
+ const NodeRenderer = memo(NodeRendererComponent);
1774
1875
 
1775
1876
  /**
1776
1877
  * Hook for getting the visible edge ids from the store.
@@ -1844,18 +1945,21 @@ const Marker = ({ id, type, color, width = 12.5, height = 12.5, markerUnits = 's
1844
1945
  }
1845
1946
  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 }) }));
1846
1947
  };
1847
- const markerSelector = ({ defaultColor, rfId }) => (s) => {
1848
- const markers = createMarkerIds(s.edges, { id: rfId, defaultColor });
1849
- return markers;
1850
- };
1851
- const markersEqual = (a, b) =>
1852
- // the id includes all marker options, so we just need to look at that part of the marker
1853
- !(a.length !== b.length || a.some((m, i) => m.id !== b[i].id));
1854
1948
  // when you have multiple flows on a page and you hide the first one, the other ones have no markers anymore
1855
1949
  // when they do have markers with the same ids. To prevent this the user can pass a unique id to the react flow wrapper
1856
1950
  // that we can then use for creating our unique marker ids
1857
1951
  const MarkerDefinitions = ({ defaultColor, rfId }) => {
1858
- const markers = useStore(useCallback(markerSelector({ defaultColor, rfId }), [defaultColor, rfId]), markersEqual);
1952
+ const edges = useStore((s) => s.edges);
1953
+ const defaultEdgeOptions = useStore((s) => s.defaultEdgeOptions);
1954
+ const markers = useMemo(() => {
1955
+ const markers = createMarkerIds(edges, {
1956
+ id: rfId,
1957
+ defaultColor,
1958
+ defaultMarkerStart: defaultEdgeOptions?.markerStart,
1959
+ defaultMarkerEnd: defaultEdgeOptions?.markerEnd,
1960
+ });
1961
+ return markers;
1962
+ }, [edges, defaultEdgeOptions, rfId, defaultColor]);
1859
1963
  if (!markers.length) {
1860
1964
  return null;
1861
1965
  }
@@ -1864,7 +1968,7 @@ const MarkerDefinitions = ({ defaultColor, rfId }) => {
1864
1968
  MarkerDefinitions.displayName = 'MarkerDefinitions';
1865
1969
  var MarkerDefinitions$1 = memo(MarkerDefinitions);
1866
1970
 
1867
- const EdgeText = ({ x, y, label, labelStyle = {}, labelShowBg = true, labelBgStyle = {}, labelBgPadding = [2, 4], labelBgBorderRadius = 2, children, className, ...rest }) => {
1971
+ function EdgeTextComponent({ x, y, label, labelStyle = {}, labelShowBg = true, labelBgStyle = {}, labelBgPadding = [2, 4], labelBgBorderRadius = 2, children, className, ...rest }) {
1868
1972
  const [edgeTextBbox, setEdgeTextBbox] = useState({ x: 1, y: 0, width: 0, height: 0 });
1869
1973
  const edgeTextClasses = cc(['react-flow__edge-textwrapper', className]);
1870
1974
  const onEdgeTextRefChange = useCallback((edgeRef) => {
@@ -1882,13 +1986,13 @@ const EdgeText = ({ x, y, label, labelStyle = {}, labelShowBg = true, labelBgSty
1882
1986
  return null;
1883
1987
  }
1884
1988
  return (jsxs("g", { transform: `translate(${x - edgeTextBbox.width / 2} ${y - edgeTextBbox.height / 2})`, className: edgeTextClasses, visibility: edgeTextBbox.width ? 'visible' : 'hidden', ...rest, children: [labelShowBg && (jsx("rect", { width: edgeTextBbox.width + 2 * labelBgPadding[0], x: -labelBgPadding[0], y: -labelBgPadding[1], height: edgeTextBbox.height + 2 * labelBgPadding[1], className: "react-flow__edge-textbg", style: labelBgStyle, rx: labelBgBorderRadius, ry: labelBgBorderRadius })), jsx("text", { className: "react-flow__edge-text", y: edgeTextBbox.height / 2, dy: "0.3em", ref: onEdgeTextRefChange, style: labelStyle, children: label }), children] }));
1885
- };
1886
- var EdgeText$1 = memo(EdgeText);
1989
+ }
1990
+ EdgeTextComponent.displayName = 'EdgeText';
1991
+ const EdgeText = memo(EdgeTextComponent);
1887
1992
 
1888
- const BaseEdge = ({ id, path, labelX, labelY, label, labelStyle, labelShowBg, labelBgStyle, labelBgPadding, labelBgBorderRadius, style, markerEnd, markerStart, className, interactionWidth = 20, }) => {
1889
- return (jsxs(Fragment, { children: [jsx("path", { id: id, style: style, d: path, fill: "none", className: cc(['react-flow__edge-path', className]), markerEnd: markerEnd, markerStart: markerStart }), interactionWidth && (jsx("path", { d: path, fill: "none", strokeOpacity: 0, strokeWidth: interactionWidth, className: "react-flow__edge-interaction" })), label && isNumeric(labelX) && isNumeric(labelY) ? (jsx(EdgeText$1, { x: labelX, y: labelY, label: label, labelStyle: labelStyle, labelShowBg: labelShowBg, labelBgStyle: labelBgStyle, labelBgPadding: labelBgPadding, labelBgBorderRadius: labelBgBorderRadius })) : null] }));
1890
- };
1891
- BaseEdge.displayName = 'BaseEdge';
1993
+ function BaseEdge({ id, path, labelX, labelY, label, labelStyle, labelShowBg, labelBgStyle, labelBgPadding, labelBgBorderRadius, style, markerEnd, markerStart, className, interactionWidth = 20, }) {
1994
+ return (jsxs(Fragment, { children: [jsx("path", { id: id, style: style, d: path, fill: "none", className: cc(['react-flow__edge-path', className]), markerEnd: markerEnd, markerStart: markerStart }), interactionWidth && (jsx("path", { d: path, fill: "none", strokeOpacity: 0, strokeWidth: interactionWidth, className: "react-flow__edge-interaction" })), label && isNumeric(labelX) && isNumeric(labelY) ? (jsx(EdgeText, { x: labelX, y: labelY, label: label, labelStyle: labelStyle, labelShowBg: labelShowBg, labelBgStyle: labelBgStyle, labelBgPadding: labelBgPadding, labelBgBorderRadius: labelBgBorderRadius })) : null] }));
1995
+ }
1892
1996
 
1893
1997
  function getControl({ pos, x1, y1, x2, y2 }) {
1894
1998
  if (pos === Position.Left || pos === Position.Right) {
@@ -2048,7 +2152,9 @@ const shiftY = (y, shift, position) => {
2048
2152
  return y;
2049
2153
  };
2050
2154
  const EdgeUpdaterClassName = 'react-flow__edgeupdater';
2051
- const EdgeAnchor = ({ position, centerX, centerY, radius = 10, onMouseDown, onMouseEnter, onMouseOut, type, }) => (jsx("circle", { onMouseDown: onMouseDown, onMouseEnter: onMouseEnter, onMouseOut: onMouseOut, className: cc([EdgeUpdaterClassName, `${EdgeUpdaterClassName}-${type}`]), cx: shiftX(centerX, radius, position), cy: shiftY(centerY, radius, position), r: radius, stroke: "transparent", fill: "transparent" }));
2155
+ function EdgeAnchor({ position, centerX, centerY, radius = 10, onMouseDown, onMouseEnter, onMouseOut, type, }) {
2156
+ return (jsx("circle", { onMouseDown: onMouseDown, onMouseEnter: onMouseEnter, onMouseOut: onMouseOut, className: cc([EdgeUpdaterClassName, `${EdgeUpdaterClassName}-${type}`]), cx: shiftX(centerX, radius, position), cy: shiftY(centerY, radius, position), r: radius, stroke: "transparent", fill: "transparent" }));
2157
+ }
2052
2158
 
2053
2159
  function EdgeUpdateAnchors({ isUpdatable, edgeUpdaterRadius, edge, targetHandleId, sourceHandleId, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, onEdgeUpdate, onEdgeUpdateStart, onEdgeUpdateEnd, setUpdating, setUpdateHover, }) {
2054
2160
  const store = useStoreApi();
@@ -2057,7 +2163,7 @@ function EdgeUpdateAnchors({ isUpdatable, edgeUpdaterRadius, edge, targetHandleI
2057
2163
  if (event.button !== 0) {
2058
2164
  return;
2059
2165
  }
2060
- const { autoPanOnConnect, domNode, isValidConnection, connectionMode, connectionRadius, lib, onConnectStart, onConnectEnd, cancelConnection, nodes, panBy, updateConnection, } = store.getState();
2166
+ const { autoPanOnConnect, domNode, isValidConnection, connectionMode, connectionRadius, lib, onConnectStart, onConnectEnd, cancelConnection, nodes, rfId: flowId, panBy, updateConnection, } = store.getState();
2061
2167
  const nodeId = isSourceHandle ? edge.target : edge.source;
2062
2168
  const handleId = (isSourceHandle ? targetHandleId : sourceHandleId) || null;
2063
2169
  const handleType = isSourceHandle ? 'target' : 'source';
@@ -2080,6 +2186,7 @@ function EdgeUpdateAnchors({ isUpdatable, edgeUpdaterRadius, edge, targetHandleI
2080
2186
  isTarget,
2081
2187
  edgeUpdaterType: handleType,
2082
2188
  lib,
2189
+ flowId,
2083
2190
  cancelConnection,
2084
2191
  panBy,
2085
2192
  isValidConnection,
@@ -2098,7 +2205,7 @@ function EdgeUpdateAnchors({ isUpdatable, edgeUpdaterRadius, edge, targetHandleI
2098
2205
  return (jsxs(Fragment, { children: [(isUpdatable === 'source' || isUpdatable === true) && (jsx(EdgeAnchor, { position: sourcePosition, centerX: sourceX, centerY: sourceY, radius: edgeUpdaterRadius, onMouseDown: onEdgeUpdaterSourceMouseDown, onMouseEnter: onEdgeUpdaterMouseEnter, onMouseOut: onEdgeUpdaterMouseOut, type: "source" })), (isUpdatable === 'target' || isUpdatable === true) && (jsx(EdgeAnchor, { position: targetPosition, centerX: targetX, centerY: targetY, radius: edgeUpdaterRadius, onMouseDown: onEdgeUpdaterTargetMouseDown, onMouseEnter: onEdgeUpdaterMouseEnter, onMouseOut: onEdgeUpdaterMouseOut, type: "target" }))] }));
2099
2206
  }
2100
2207
 
2101
- function EdgeWrapper({ id, edgesFocusable, edgesUpdatable, elementsSelectable, onClick, onDoubleClick, sourceHandleId, targetHandleId, onContextMenu, onMouseEnter, onMouseMove, onMouseLeave, edgeUpdaterRadius, onEdgeUpdate, onEdgeUpdateStart, onEdgeUpdateEnd, rfId, edgeTypes, noPanClassName, onError, }) {
2208
+ function EdgeWrapper({ id, edgesFocusable, edgesUpdatable, elementsSelectable, onClick, onDoubleClick, onContextMenu, onMouseEnter, onMouseMove, onMouseLeave, edgeUpdaterRadius, onEdgeUpdate, onEdgeUpdateStart, onEdgeUpdateEnd, rfId, edgeTypes, noPanClassName, onError, disableKeyboardA11y, }) {
2102
2209
  let edge = useStore((s) => s.edgeLookup.get(id));
2103
2210
  const defaultEdgeOptions = useStore((s) => s.defaultEdgeOptions);
2104
2211
  edge = defaultEdgeOptions ? { ...defaultEdgeOptions, ...edge } : edge;
@@ -2130,8 +2237,8 @@ function EdgeWrapper({ id, edgesFocusable, edgesUpdatable, elementsSelectable, o
2130
2237
  id,
2131
2238
  sourceNode,
2132
2239
  targetNode,
2133
- sourceHandle: sourceHandleId || null,
2134
- targetHandle: targetHandleId || null,
2240
+ sourceHandle: edge.sourceHandle || null,
2241
+ targetHandle: edge.targetHandle || null,
2135
2242
  connectionMode: store.connectionMode,
2136
2243
  onError,
2137
2244
  });
@@ -2146,9 +2253,9 @@ function EdgeWrapper({ id, edgesFocusable, edgesUpdatable, elementsSelectable, o
2146
2253
  zIndex,
2147
2254
  ...(edgePosition || nullPosition),
2148
2255
  };
2149
- }, [edge.source, edge.target, edge.selected, edge.zIndex]), shallow);
2150
- const markerStartUrl = useMemo(() => (edge.markerStart ? `url(#${getMarkerId(edge.markerStart, rfId)})` : undefined), [edge.markerStart, rfId]);
2151
- const markerEndUrl = useMemo(() => (edge.markerEnd ? `url(#${getMarkerId(edge.markerEnd, rfId)})` : undefined), [edge.markerEnd, rfId]);
2256
+ }, [edge.source, edge.target, edge.sourceHandle, edge.targetHandle, edge.selected, edge.zIndex]), shallow);
2257
+ const markerStartUrl = useMemo(() => (edge.markerStart ? `url('#${getMarkerId(edge.markerStart, rfId)}')` : undefined), [edge.markerStart, rfId]);
2258
+ const markerEndUrl = useMemo(() => (edge.markerEnd ? `url('#${getMarkerId(edge.markerEnd, rfId)}')` : undefined), [edge.markerEnd, rfId]);
2152
2259
  if (edge.hidden || !sourceX || !sourceY || !targetX || !targetY) {
2153
2260
  return null;
2154
2261
  }
@@ -2194,7 +2301,7 @@ function EdgeWrapper({ id, edgesFocusable, edgesUpdatable, elementsSelectable, o
2194
2301
  }
2195
2302
  : undefined;
2196
2303
  const onKeyDown = (event) => {
2197
- if (elementSelectionKeys.includes(event.key) && isSelectable) {
2304
+ if (!disableKeyboardA11y && elementSelectionKeys.includes(event.key) && isSelectable) {
2198
2305
  const { unselectNodesAndEdges, addSelectedEdges } = store.getState();
2199
2306
  const unselect = event.key === 'Escape';
2200
2307
  if (unselect) {
@@ -2216,11 +2323,10 @@ function EdgeWrapper({ id, edgesFocusable, edgesUpdatable, elementsSelectable, o
2216
2323
  animated: edge.animated,
2217
2324
  inactive: !isSelectable && !onClick,
2218
2325
  updating: updateHover,
2326
+ selectable: isSelectable,
2219
2327
  },
2220
- ]), 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: sourceHandleId, targetHandleId: targetHandleId, 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: sourceHandleId, targetHandleId: targetHandleId }))] }) }));
2328
+ ]), 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 }))] }) }));
2221
2329
  }
2222
- EdgeWrapper.displayName = 'EdgeWrapper';
2223
- var EdgeWrapper$1 = memo(EdgeWrapper);
2224
2330
 
2225
2331
  const selector$c = (s) => ({
2226
2332
  width: s.width,
@@ -2231,15 +2337,15 @@ const selector$c = (s) => ({
2231
2337
  connectionMode: s.connectionMode,
2232
2338
  onError: s.onError,
2233
2339
  });
2234
- const EdgeRenderer = ({ defaultMarkerColor, onlyRenderVisibleElements, rfId, edgeTypes, noPanClassName, onEdgeUpdate, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, onEdgeClick, edgeUpdaterRadius, onEdgeDoubleClick, onEdgeUpdateStart, onEdgeUpdateEnd, children, }) => {
2340
+ function EdgeRendererComponent({ defaultMarkerColor, onlyRenderVisibleElements, rfId, edgeTypes, noPanClassName, onEdgeUpdate, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, onEdgeClick, edgeUpdaterRadius, onEdgeDoubleClick, onEdgeUpdateStart, onEdgeUpdateEnd, disableKeyboardA11y, }) {
2235
2341
  const { edgesFocusable, edgesUpdatable, elementsSelectable, onError } = useStore(selector$c, shallow);
2236
2342
  const edgeIds = useVisibleEdgeIds(onlyRenderVisibleElements);
2237
2343
  return (jsxs("div", { className: "react-flow__edges", children: [jsx(MarkerDefinitions$1, { defaultColor: defaultMarkerColor, rfId: rfId }), edgeIds.map((id) => {
2238
- return (jsx(EdgeWrapper$1, { id: id, edgesFocusable: edgesFocusable, edgesUpdatable: edgesUpdatable, elementsSelectable: elementsSelectable, noPanClassName: noPanClassName, onEdgeUpdate: onEdgeUpdate, onContextMenu: onEdgeContextMenu, onMouseEnter: onEdgeMouseEnter, onMouseMove: onEdgeMouseMove, onMouseLeave: onEdgeMouseLeave, onClick: onEdgeClick, edgeUpdaterRadius: edgeUpdaterRadius, onDoubleClick: onEdgeDoubleClick, onEdgeUpdateStart: onEdgeUpdateStart, onEdgeUpdateEnd: onEdgeUpdateEnd, rfId: rfId, onError: onError, edgeTypes: edgeTypes }, id));
2239
- }), children] }));
2240
- };
2241
- EdgeRenderer.displayName = 'EdgeRenderer';
2242
- var EdgeRenderer$1 = memo(EdgeRenderer);
2344
+ return (jsx(EdgeWrapper, { id: id, edgesFocusable: edgesFocusable, edgesUpdatable: edgesUpdatable, elementsSelectable: elementsSelectable, noPanClassName: noPanClassName, onEdgeUpdate: onEdgeUpdate, onContextMenu: onEdgeContextMenu, onMouseEnter: onEdgeMouseEnter, onMouseMove: onEdgeMouseMove, onMouseLeave: onEdgeMouseLeave, onClick: onEdgeClick, edgeUpdaterRadius: edgeUpdaterRadius, onDoubleClick: onEdgeDoubleClick, onEdgeUpdateStart: onEdgeUpdateStart, onEdgeUpdateEnd: onEdgeUpdateEnd, rfId: rfId, onError: onError, edgeTypes: edgeTypes, disableKeyboardA11y: disableKeyboardA11y }, id));
2345
+ })] }));
2346
+ }
2347
+ EdgeRendererComponent.displayName = 'EdgeRenderer';
2348
+ const EdgeRenderer = memo(EdgeRendererComponent);
2243
2349
 
2244
2350
  const selector$b = (s) => `translate(${s.transform[0]}px,${s.transform[1]}px) scale(${s.transform[2]})`;
2245
2351
  function Viewport({ children }) {
@@ -2362,7 +2468,7 @@ function ConnectionLineWrapper({ containerStyle, style, type, component }) {
2362
2468
  if (!isValid) {
2363
2469
  return null;
2364
2470
  }
2365
- return (jsx("svg", { style: containerStyle, width: width, height: height, className: "react-flow__edges react-flow__connectionline react-flow__container", children: jsx("g", { className: cc(['react-flow__connection', connectionStatus]), children: jsx(ConnectionLine, { nodeId: nodeId, handleType: handleType, style: style, type: type, CustomComponent: component, connectionStatus: connectionStatus }) }) }));
2471
+ return (jsx("svg", { style: containerStyle, width: width, height: height, className: "react-flow__connectionline react-flow__container", children: jsx("g", { className: cc(['react-flow__connection', connectionStatus]), children: jsx(ConnectionLine, { nodeId: nodeId, handleType: handleType, style: style, type: type, CustomComponent: component, connectionStatus: connectionStatus }) }) }));
2366
2472
  }
2367
2473
 
2368
2474
  const emptyTypes = {};
@@ -2380,54 +2486,32 @@ function useNodeOrEdgeTypesWarning(nodeOrEdgeTypes = emptyTypes) {
2380
2486
  }, [nodeOrEdgeTypes]);
2381
2487
  }
2382
2488
 
2383
- const GraphView = ({ nodeTypes, edgeTypes, 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, 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, }) => {
2489
+ function GraphViewComponent({ nodeTypes, edgeTypes, 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, 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, }) {
2384
2490
  useNodeOrEdgeTypesWarning(nodeTypes);
2385
2491
  useNodeOrEdgeTypesWarning(edgeTypes);
2386
2492
  useOnInitHandler(onInit);
2387
2493
  useViewportSync(viewport);
2388
- return (jsx(FlowRenderer$1, { onPaneClick: onPaneClick, onPaneMouseEnter: onPaneMouseEnter, onPaneMouseMove: onPaneMouseMove, onPaneMouseLeave: onPaneMouseLeave, onPaneContextMenu: onPaneContextMenu, onPaneScroll: onPaneScroll, deleteKeyCode: deleteKeyCode, selectionKeyCode: selectionKeyCode, selectionOnDrag: selectionOnDrag, selectionMode: selectionMode, onSelectionStart: onSelectionStart, onSelectionEnd: onSelectionEnd, multiSelectionKeyCode: multiSelectionKeyCode, panActivationKeyCode: panActivationKeyCode, zoomActivationKeyCode: zoomActivationKeyCode, elementsSelectable: elementsSelectable, zoomOnScroll: zoomOnScroll, zoomOnPinch: zoomOnPinch, zoomOnDoubleClick: zoomOnDoubleClick, panOnScroll: panOnScroll, panOnScrollSpeed: panOnScrollSpeed, panOnScrollMode: panOnScrollMode, panOnDrag: panOnDrag, defaultViewport: defaultViewport, translateExtent: translateExtent, minZoom: minZoom, maxZoom: maxZoom, onSelectionContextMenu: onSelectionContextMenu, preventScrolling: preventScrolling, noDragClassName: noDragClassName, noWheelClassName: noWheelClassName, noPanClassName: noPanClassName, disableKeyboardA11y: disableKeyboardA11y, onViewportChange: onViewportChange, isControlledViewport: !!viewport, children: jsxs(Viewport, { children: [jsx(EdgeRenderer$1, { edgeTypes: edgeTypes, onEdgeClick: onEdgeClick, onEdgeDoubleClick: onEdgeDoubleClick, onEdgeUpdate: onEdgeUpdate, onlyRenderVisibleElements: onlyRenderVisibleElements, onEdgeContextMenu: onEdgeContextMenu, onEdgeMouseEnter: onEdgeMouseEnter, onEdgeMouseMove: onEdgeMouseMove, onEdgeMouseLeave: onEdgeMouseLeave, onEdgeUpdateStart: onEdgeUpdateStart, onEdgeUpdateEnd: onEdgeUpdateEnd, edgeUpdaterRadius: edgeUpdaterRadius, defaultMarkerColor: defaultMarkerColor, noPanClassName: noPanClassName, disableKeyboardA11y: disableKeyboardA11y, rfId: rfId, children: jsx(ConnectionLineWrapper, { style: connectionLineStyle, type: connectionLineType, component: connectionLineComponent, containerStyle: connectionLineContainerStyle }) }), jsx("div", { className: "react-flow__edgelabel-renderer" }), jsx("div", { className: "react-flow__viewport-portal" }), jsx(NodeRenderer$1, { nodeTypes: nodeTypes, onNodeClick: onNodeClick, onNodeDoubleClick: onNodeDoubleClick, onNodeMouseEnter: onNodeMouseEnter, onNodeMouseMove: onNodeMouseMove, onNodeMouseLeave: onNodeMouseLeave, onNodeContextMenu: onNodeContextMenu, onlyRenderVisibleElements: onlyRenderVisibleElements, noPanClassName: noPanClassName, noDragClassName: noDragClassName, disableKeyboardA11y: disableKeyboardA11y, nodeOrigin: nodeOrigin, nodeExtent: nodeExtent, rfId: rfId })] }) }));
2389
- };
2390
- GraphView.displayName = 'GraphView';
2391
- var GraphView$1 = memo(GraphView);
2392
-
2393
- function handleControlledSelectionChange(changes, items) {
2394
- return items.map((item) => {
2395
- const change = changes.find((change) => change.id === item.id);
2396
- if (change) {
2397
- item.selected = change.selected;
2398
- }
2399
- return item;
2400
- });
2401
- }
2402
- function updateNodesAndEdgesSelections({ changedNodes, changedEdges, get, set }) {
2403
- const { nodes, edges, onNodesChange, onEdgesChange, hasDefaultNodes, hasDefaultEdges } = get();
2404
- if (changedNodes?.length) {
2405
- if (hasDefaultNodes) {
2406
- set({ nodes: handleControlledSelectionChange(changedNodes, nodes) });
2407
- }
2408
- onNodesChange?.(changedNodes);
2409
- }
2410
- if (changedEdges?.length) {
2411
- if (hasDefaultEdges) {
2412
- set({ edges: handleControlledSelectionChange(changedEdges, edges) });
2413
- }
2414
- onEdgesChange?.(changedEdges);
2415
- }
2494
+ return (jsx(FlowRenderer, { onPaneClick: onPaneClick, onPaneMouseEnter: onPaneMouseEnter, onPaneMouseMove: onPaneMouseMove, onPaneMouseLeave: onPaneMouseLeave, onPaneContextMenu: onPaneContextMenu, onPaneScroll: onPaneScroll, deleteKeyCode: deleteKeyCode, selectionKeyCode: selectionKeyCode, selectionOnDrag: selectionOnDrag, selectionMode: selectionMode, onSelectionStart: onSelectionStart, onSelectionEnd: onSelectionEnd, multiSelectionKeyCode: multiSelectionKeyCode, panActivationKeyCode: panActivationKeyCode, zoomActivationKeyCode: zoomActivationKeyCode, elementsSelectable: elementsSelectable, zoomOnScroll: zoomOnScroll, zoomOnPinch: zoomOnPinch, zoomOnDoubleClick: zoomOnDoubleClick, panOnScroll: panOnScroll, panOnScrollSpeed: panOnScrollSpeed, panOnScrollMode: panOnScrollMode, panOnDrag: panOnDrag, defaultViewport: defaultViewport, translateExtent: translateExtent, minZoom: minZoom, maxZoom: maxZoom, onSelectionContextMenu: onSelectionContextMenu, preventScrolling: preventScrolling, noDragClassName: noDragClassName, noWheelClassName: noWheelClassName, noPanClassName: noPanClassName, disableKeyboardA11y: disableKeyboardA11y, onViewportChange: onViewportChange, isControlledViewport: !!viewport, children: jsxs(Viewport, { children: [jsx(EdgeRenderer, { edgeTypes: edgeTypes, onEdgeClick: onEdgeClick, onEdgeDoubleClick: onEdgeDoubleClick, onEdgeUpdate: onEdgeUpdate, onlyRenderVisibleElements: onlyRenderVisibleElements, onEdgeContextMenu: onEdgeContextMenu, onEdgeMouseEnter: onEdgeMouseEnter, onEdgeMouseMove: onEdgeMouseMove, onEdgeMouseLeave: onEdgeMouseLeave, onEdgeUpdateStart: onEdgeUpdateStart, onEdgeUpdateEnd: onEdgeUpdateEnd, edgeUpdaterRadius: edgeUpdaterRadius, defaultMarkerColor: defaultMarkerColor, noPanClassName: noPanClassName, disableKeyboardA11y: disableKeyboardA11y, rfId: rfId }), jsx(ConnectionLineWrapper, { style: connectionLineStyle, type: connectionLineType, component: connectionLineComponent, containerStyle: connectionLineContainerStyle }), jsx("div", { className: "react-flow__edgelabel-renderer" }), jsx("div", { className: "react-flow__viewport-portal" }), jsx(NodeRenderer, { nodeTypes: nodeTypes, onNodeClick: onNodeClick, onNodeDoubleClick: onNodeDoubleClick, onNodeMouseEnter: onNodeMouseEnter, onNodeMouseMove: onNodeMouseMove, onNodeMouseLeave: onNodeMouseLeave, onNodeContextMenu: onNodeContextMenu, onlyRenderVisibleElements: onlyRenderVisibleElements, noPanClassName: noPanClassName, noDragClassName: noDragClassName, disableKeyboardA11y: disableKeyboardA11y, nodeOrigin: nodeOrigin, nodeExtent: nodeExtent, rfId: rfId })] }) }));
2416
2495
  }
2496
+ GraphViewComponent.displayName = 'GraphView';
2497
+ const GraphView = memo(GraphViewComponent);
2417
2498
 
2418
- const getInitialState = ({ nodes = [], edges = [], width, height, fitView, } = {}) => {
2499
+ const getInitialState = ({ nodes, edges, defaultNodes, defaultEdges, width, height, fitView, } = {}) => {
2419
2500
  const nodeLookup = new Map();
2420
2501
  const connectionLookup = new Map();
2421
2502
  const edgeLookup = new Map();
2422
- updateConnectionLookup(connectionLookup, edgeLookup, edges);
2423
- const nextNodes = adoptUserProvidedNodes(nodes, nodeLookup, {
2503
+ const storeEdges = defaultEdges ?? edges ?? [];
2504
+ const storeNodes = defaultNodes ?? nodes ?? [];
2505
+ updateConnectionLookup(connectionLookup, edgeLookup, storeEdges);
2506
+ const nextNodes = adoptUserProvidedNodes(storeNodes, nodeLookup, {
2424
2507
  nodeOrigin: [0, 0],
2425
2508
  elevateNodesOnSelect: false,
2426
2509
  });
2427
2510
  let transform = [0, 0, 1];
2428
2511
  if (fitView && width && height) {
2429
- const nodesWithDimensions = nextNodes.filter((node) => node.width && node.height);
2430
- const bounds = getNodesBounds(nodesWithDimensions, [0, 0]);
2512
+ const nodesWithDimensions = nextNodes.filter((node) => (node.width || node.initialWidth) && (node.height || node.initialHeight));
2513
+ // @todo users nodeOrigin should be used here
2514
+ const bounds = getNodesBounds(nodesWithDimensions, { nodeOrigin: [0, 0] });
2431
2515
  const { x, y, zoom } = getViewportForBounds(bounds, width, height, 0.5, 2, 0.1);
2432
2516
  transform = [x, y, zoom];
2433
2517
  }
@@ -2438,13 +2522,13 @@ const getInitialState = ({ nodes = [], edges = [], width, height, fitView, } = {
2438
2522
  transform,
2439
2523
  nodes: nextNodes,
2440
2524
  nodeLookup,
2441
- edges,
2525
+ edges: storeEdges,
2442
2526
  edgeLookup,
2443
2527
  connectionLookup,
2444
2528
  onNodesChange: null,
2445
2529
  onEdgesChange: null,
2446
- hasDefaultNodes: false,
2447
- hasDefaultEdges: false,
2530
+ hasDefaultNodes: defaultNodes !== undefined,
2531
+ hasDefaultEdges: defaultEdges !== undefined,
2448
2532
  panZoom: null,
2449
2533
  minZoom: 0.5,
2450
2534
  maxZoom: 2,
@@ -2484,15 +2568,16 @@ const getInitialState = ({ nodes = [], edges = [], width, height, fitView, } = {
2484
2568
  autoPanOnConnect: true,
2485
2569
  autoPanOnNodeDrag: true,
2486
2570
  connectionRadius: 20,
2487
- onError: () => null,
2571
+ onError: devWarn,
2488
2572
  isValidConnection: undefined,
2489
2573
  onSelectionChangeHandlers: [],
2490
2574
  lib: 'react',
2575
+ debug: false,
2491
2576
  };
2492
2577
  };
2493
2578
 
2494
- const createRFStore = ({ nodes, edges, width, height, fitView: fitView$1, }) => createWithEqualityFn((set, get) => ({
2495
- ...getInitialState({ nodes, edges, width, height, fitView: fitView$1 }),
2579
+ const createRFStore = ({ nodes, edges, defaultNodes, defaultEdges, width, height, fitView: fitView$1, }) => createWithEqualityFn((set, get) => ({
2580
+ ...getInitialState({ nodes, edges, width, height, fitView: fitView$1, defaultNodes, defaultEdges }),
2496
2581
  setNodes: (nodes) => {
2497
2582
  const { nodeLookup, nodeOrigin, elevateNodesOnSelect } = get();
2498
2583
  // setNodes() is called exclusively in response to user actions:
@@ -2501,7 +2586,6 @@ const createRFStore = ({ nodes, edges, width, height, fitView: fitView$1, }) =>
2501
2586
  //
2502
2587
  // When this happens, we take the note objects passed by the user and extend them with fields
2503
2588
  // relevant for internal React Flow operations.
2504
- // TODO: consider updating the types to reflect the distinction between user-provided nodes and internal nodes.
2505
2589
  const nodesWithInternalData = adoptUserProvidedNodes(nodes, nodeLookup, { nodeOrigin, elevateNodesOnSelect });
2506
2590
  set({ nodes: nodesWithInternalData });
2507
2591
  },
@@ -2510,34 +2594,23 @@ const createRFStore = ({ nodes, edges, width, height, fitView: fitView$1, }) =>
2510
2594
  updateConnectionLookup(connectionLookup, edgeLookup, edges);
2511
2595
  set({ edges });
2512
2596
  },
2513
- // when the user works with an uncontrolled flow,
2514
- // we set a flag `hasDefaultNodes` / `hasDefaultEdges`
2515
2597
  setDefaultNodesAndEdges: (nodes, edges) => {
2516
- const hasDefaultNodes = typeof nodes !== 'undefined';
2517
- const hasDefaultEdges = typeof edges !== 'undefined';
2518
- const nextState = {
2519
- hasDefaultNodes,
2520
- hasDefaultEdges,
2521
- };
2522
- if (hasDefaultNodes) {
2523
- const { nodeLookup, nodeOrigin, elevateNodesOnSelect } = get();
2524
- nextState.nodes = adoptUserProvidedNodes(nodes, nodeLookup, {
2525
- nodeOrigin,
2526
- elevateNodesOnSelect,
2527
- });
2598
+ if (nodes) {
2599
+ const { setNodes } = get();
2600
+ setNodes(nodes);
2601
+ set({ hasDefaultNodes: true });
2528
2602
  }
2529
- if (hasDefaultEdges) {
2530
- const { connectionLookup, edgeLookup } = get();
2531
- updateConnectionLookup(connectionLookup, edgeLookup, edges);
2532
- nextState.edges = edges;
2603
+ if (edges) {
2604
+ const { setEdges } = get();
2605
+ setEdges(edges);
2606
+ set({ hasDefaultEdges: true });
2533
2607
  }
2534
- set(nextState);
2535
2608
  },
2536
2609
  // Every node gets registerd at a ResizeObserver. Whenever a node
2537
2610
  // changes its dimensions, this function is called to measure the
2538
2611
  // new dimensions and update the nodes.
2539
2612
  updateNodeDimensions: (updates) => {
2540
- const { onNodesChange, fitView, nodes, nodeLookup, fitViewOnInit, fitViewDone, fitViewOnInitOptions, domNode, nodeOrigin, } = get();
2613
+ const { onNodesChange, fitView, nodes, nodeLookup, fitViewOnInit, fitViewDone, fitViewOnInitOptions, domNode, nodeOrigin, debug, } = get();
2541
2614
  const changes = [];
2542
2615
  const updatedNodes = updateNodeDimensions(updates, nodes, nodeLookup, domNode, nodeOrigin, (id, dimensions) => {
2543
2616
  changes.push({
@@ -2565,89 +2638,82 @@ const createRFStore = ({ nodes, edges, width, height, fitView: fitView$1, }) =>
2565
2638
  // attribute which they get from this handler.
2566
2639
  set({ nodes: nextNodes, fitViewDone: nextFitViewDone });
2567
2640
  if (changes?.length > 0) {
2641
+ if (debug) {
2642
+ console.log('React Flow: trigger node changes', changes);
2643
+ }
2568
2644
  onNodesChange?.(changes);
2569
2645
  }
2570
2646
  },
2571
- updateNodePositions: (nodeDragItems, positionChanged = true, dragging = false) => {
2647
+ updateNodePositions: (nodeDragItems, dragging = false) => {
2572
2648
  const changes = nodeDragItems.map((node) => {
2573
2649
  const change = {
2574
2650
  id: node.id,
2575
2651
  type: 'position',
2652
+ position: node.position,
2653
+ positionAbsolute: node.computed?.positionAbsolute,
2576
2654
  dragging,
2577
2655
  };
2578
- if (positionChanged) {
2579
- change.positionAbsolute = node.computed?.positionAbsolute;
2580
- change.position = node.position;
2581
- }
2582
2656
  return change;
2583
2657
  });
2584
2658
  get().triggerNodeChanges(changes);
2585
2659
  },
2586
2660
  triggerNodeChanges: (changes) => {
2587
- const { onNodesChange, nodeLookup, nodes, hasDefaultNodes, nodeOrigin, elevateNodesOnSelect } = get();
2661
+ const { onNodesChange, setNodes, nodes, hasDefaultNodes, debug } = get();
2588
2662
  if (changes?.length) {
2589
2663
  if (hasDefaultNodes) {
2590
2664
  const updatedNodes = applyNodeChanges(changes, nodes);
2591
- const nextNodes = adoptUserProvidedNodes(updatedNodes, nodeLookup, {
2592
- nodeOrigin,
2593
- elevateNodesOnSelect,
2594
- });
2595
- set({ nodes: nextNodes });
2665
+ setNodes(updatedNodes);
2666
+ }
2667
+ if (debug) {
2668
+ console.log('React Flow: trigger node changes', changes);
2596
2669
  }
2597
2670
  onNodesChange?.(changes);
2598
2671
  }
2599
2672
  },
2673
+ triggerEdgeChanges: (changes) => {
2674
+ const { onEdgesChange, setEdges, edges, hasDefaultEdges, debug } = get();
2675
+ if (changes?.length) {
2676
+ if (hasDefaultEdges) {
2677
+ const updatedEdges = applyEdgeChanges(changes, edges);
2678
+ setEdges(updatedEdges);
2679
+ }
2680
+ if (debug) {
2681
+ console.log('React Flow: trigger edge changes', changes);
2682
+ }
2683
+ onEdgesChange?.(changes);
2684
+ }
2685
+ },
2600
2686
  addSelectedNodes: (selectedNodeIds) => {
2601
- const { multiSelectionActive, edges, nodes } = get();
2602
- let changedNodes;
2603
- let changedEdges = null;
2687
+ const { multiSelectionActive, edges, nodes, triggerNodeChanges, triggerEdgeChanges } = get();
2604
2688
  if (multiSelectionActive) {
2605
- changedNodes = selectedNodeIds.map((nodeId) => createSelectionChange(nodeId, true));
2689
+ const nodeChanges = selectedNodeIds.map((nodeId) => createSelectionChange(nodeId, true));
2690
+ triggerNodeChanges(nodeChanges);
2691
+ return;
2606
2692
  }
2607
- else {
2608
- changedNodes = getSelectionChanges(nodes, new Set([...selectedNodeIds]), true);
2609
- changedEdges = getSelectionChanges(edges);
2610
- }
2611
- updateNodesAndEdgesSelections({
2612
- changedNodes,
2613
- changedEdges,
2614
- get,
2615
- set,
2616
- });
2693
+ triggerNodeChanges(getSelectionChanges(nodes, new Set([...selectedNodeIds]), true));
2694
+ triggerEdgeChanges(getSelectionChanges(edges));
2617
2695
  },
2618
2696
  addSelectedEdges: (selectedEdgeIds) => {
2619
- const { multiSelectionActive, edges, nodes } = get();
2620
- let changedEdges;
2621
- let changedNodes = null;
2697
+ const { multiSelectionActive, edges, nodes, triggerNodeChanges, triggerEdgeChanges } = get();
2622
2698
  if (multiSelectionActive) {
2623
- changedEdges = selectedEdgeIds.map((edgeId) => createSelectionChange(edgeId, true));
2699
+ const changedEdges = selectedEdgeIds.map((edgeId) => createSelectionChange(edgeId, true));
2700
+ triggerEdgeChanges(changedEdges);
2701
+ return;
2624
2702
  }
2625
- else {
2626
- changedEdges = getSelectionChanges(edges, new Set([...selectedEdgeIds]));
2627
- changedNodes = getSelectionChanges(nodes, new Set(), true);
2628
- }
2629
- updateNodesAndEdgesSelections({
2630
- changedNodes,
2631
- changedEdges,
2632
- get,
2633
- set,
2634
- });
2703
+ triggerEdgeChanges(getSelectionChanges(edges, new Set([...selectedEdgeIds])));
2704
+ triggerNodeChanges(getSelectionChanges(nodes, new Set(), true));
2635
2705
  },
2636
2706
  unselectNodesAndEdges: ({ nodes, edges } = {}) => {
2637
- const { edges: storeEdges, nodes: storeNodes } = get();
2707
+ const { edges: storeEdges, nodes: storeNodes, triggerNodeChanges, triggerEdgeChanges } = get();
2638
2708
  const nodesToUnselect = nodes ? nodes : storeNodes;
2639
2709
  const edgesToUnselect = edges ? edges : storeEdges;
2640
- const changedNodes = nodesToUnselect.map((n) => {
2710
+ const nodeChanges = nodesToUnselect.map((n) => {
2641
2711
  n.selected = false;
2642
2712
  return createSelectionChange(n.id, false);
2643
2713
  });
2644
- const changedEdges = edgesToUnselect.map((edge) => createSelectionChange(edge.id, false));
2645
- updateNodesAndEdgesSelections({
2646
- changedNodes,
2647
- changedEdges,
2648
- get,
2649
- set,
2650
- });
2714
+ const edgeChanges = edgesToUnselect.map((edge) => createSelectionChange(edge.id, false));
2715
+ triggerNodeChanges(nodeChanges);
2716
+ triggerEdgeChanges(edgeChanges);
2651
2717
  },
2652
2718
  setMinZoom: (minZoom) => {
2653
2719
  const { panZoom, maxZoom } = get();
@@ -2664,19 +2730,11 @@ const createRFStore = ({ nodes, edges, width, height, fitView: fitView$1, }) =>
2664
2730
  set({ translateExtent });
2665
2731
  },
2666
2732
  resetSelectedElements: () => {
2667
- const { edges, nodes } = get();
2668
- const nodesToUnselect = nodes
2669
- .filter((e) => e.selected)
2670
- .map((n) => createSelectionChange(n.id, false));
2671
- const edgesToUnselect = edges
2672
- .filter((e) => e.selected)
2673
- .map((e) => createSelectionChange(e.id, false));
2674
- updateNodesAndEdgesSelections({
2675
- changedNodes: nodesToUnselect,
2676
- changedEdges: edgesToUnselect,
2677
- get,
2678
- set,
2679
- });
2733
+ const { edges, nodes, triggerNodeChanges, triggerEdgeChanges } = get();
2734
+ const nodeChanges = nodes.reduce((res, node) => (node.selected ? [...res, createSelectionChange(node.id, false)] : res), []);
2735
+ const edgeChanges = edges.reduce((res, edge) => (edge.selected ? [...res, createSelectionChange(edge.id, false)] : res), []);
2736
+ triggerNodeChanges(nodeChanges);
2737
+ triggerEdgeChanges(edgeChanges);
2680
2738
  },
2681
2739
  setNodeExtent: (nodeExtent) => {
2682
2740
  const { nodes } = get();
@@ -2719,30 +2777,24 @@ const createRFStore = ({ nodes, edges, width, height, fitView: fitView$1, }) =>
2719
2777
  connectionEndHandle: null,
2720
2778
  }),
2721
2779
  updateConnection: (params) => {
2722
- const { connectionStatus, connectionStartHandle, connectionEndHandle, connectionPosition } = get();
2780
+ const { connectionPosition } = get();
2723
2781
  const currentConnection = {
2782
+ ...params,
2724
2783
  connectionPosition: params.connectionPosition ?? connectionPosition,
2725
- connectionStatus: params.connectionStatus ?? connectionStatus,
2726
- connectionStartHandle: params.connectionStartHandle ?? connectionStartHandle,
2727
- connectionEndHandle: params.connectionEndHandle ?? connectionEndHandle,
2728
2784
  };
2729
2785
  set(currentConnection);
2730
2786
  },
2731
- reset: () => {
2732
- // @todo: what should we do about this? Do we still need it?
2733
- // if you are on a SPA with multiple flows, we want to make sure that the store gets resetted
2734
- // when you switch pages. Does this reset solves this? Currently it always gets called. This
2735
- // leads to an emtpy nodes array at the beginning.
2736
- // set({ ...getInitialState() });
2737
- },
2787
+ reset: () => set({ ...getInitialState() }),
2738
2788
  }), Object.is);
2739
2789
 
2740
- function ReactFlowProvider({ children, initialNodes, initialEdges, initialWidth, initialHeight, fitView, }) {
2790
+ function ReactFlowProvider({ children, initialNodes, initialEdges, defaultNodes, defaultEdges, initialWidth, initialHeight, fitView, }) {
2741
2791
  const storeRef = useRef(null);
2742
2792
  if (!storeRef.current) {
2743
2793
  storeRef.current = createRFStore({
2744
2794
  nodes: initialNodes,
2745
2795
  edges: initialEdges,
2796
+ defaultNodes,
2797
+ defaultEdges,
2746
2798
  width: initialWidth,
2747
2799
  height: initialHeight,
2748
2800
  fitView,
@@ -2750,51 +2802,17 @@ function ReactFlowProvider({ children, initialNodes, initialEdges, initialWidth,
2750
2802
  }
2751
2803
  return jsx(Provider$1, { value: storeRef.current, children: children });
2752
2804
  }
2753
- ReactFlowProvider.displayName = 'ReactFlowProvider';
2754
2805
 
2755
- function Wrapper({ children, nodes, edges, width, height, fitView, }) {
2806
+ function Wrapper({ children, nodes, edges, defaultNodes, defaultEdges, width, height, fitView, }) {
2756
2807
  const isWrapped = useContext(StoreContext);
2757
2808
  if (isWrapped) {
2758
2809
  // we need to wrap it with a fragment because it's not allowed for children to be a ReactNode
2759
2810
  // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18051
2760
2811
  return jsx(Fragment, { children: children });
2761
2812
  }
2762
- return (jsx(ReactFlowProvider, { initialNodes: nodes, initialEdges: edges, initialWidth: width, initialHeight: height, fitView: fitView, children: children }));
2763
- }
2764
- Wrapper.displayName = 'ReactFlowWrapper';
2765
-
2766
- function getMediaQuery() {
2767
- if (typeof window === 'undefined' || !window.matchMedia) {
2768
- return null;
2769
- }
2770
- return window.matchMedia('(prefers-color-scheme: dark)');
2771
- }
2772
- /**
2773
- * Hook for receiving the current color mode class 'dark' or 'light'.
2774
- *
2775
- * @internal
2776
- * @param colorMode - The color mode to use ('dark', 'light' or 'system')
2777
- */
2778
- function useColorModeClass(colorMode) {
2779
- const [colorModeClass, setColorModeClass] = useState(colorMode === 'system' ? null : colorMode);
2780
- useEffect(() => {
2781
- if (colorMode !== 'system') {
2782
- setColorModeClass(colorMode);
2783
- return;
2784
- }
2785
- const mediaQuery = getMediaQuery();
2786
- const updateColorModeClass = () => setColorModeClass(mediaQuery?.matches ? 'dark' : 'light');
2787
- updateColorModeClass();
2788
- mediaQuery?.addEventListener('change', updateColorModeClass);
2789
- return () => {
2790
- mediaQuery?.removeEventListener('change', updateColorModeClass);
2791
- };
2792
- }, [colorMode]);
2793
- return colorModeClass !== null ? colorModeClass : getMediaQuery()?.matches ? 'dark' : 'light';
2813
+ return (jsx(ReactFlowProvider, { initialNodes: nodes, initialEdges: edges, defaultNodes: defaultNodes, defaultEdges: defaultEdges, initialWidth: width, initialHeight: height, fitView: fitView, children: children }));
2794
2814
  }
2795
2815
 
2796
- const initNodeOrigin = [0, 0];
2797
- const initDefaultViewport = { x: 0, y: 0, zoom: 1 };
2798
2816
  const wrapperStyle = {
2799
2817
  width: '100%',
2800
2818
  height: '100%',
@@ -2802,12 +2820,12 @@ const wrapperStyle = {
2802
2820
  position: 'relative',
2803
2821
  zIndex: 0,
2804
2822
  };
2805
- const ReactFlow = forwardRef(({ nodes, edges, defaultNodes, defaultEdges, className, nodeTypes, edgeTypes, 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 = false, selectionMode = SelectionMode.Full, panActivationKeyCode = 'Space', multiSelectionKeyCode = isMacOs() ? 'Meta' : 'Control', zoomActivationKeyCode = isMacOs() ? 'Meta' : 'Control', snapToGrid, snapGrid, onlyRenderVisibleElements = false, selectNodesOnDrag, nodesDraggable, nodesConnectable, nodesFocusable, nodeOrigin = initNodeOrigin, edgesFocusable, edgesUpdatable, elementsSelectable = true, defaultViewport = initDefaultViewport, minZoom = 0.5, maxZoom = 2, translateExtent = infiniteExtent, preventScrolling = true, nodeExtent, defaultMarkerColor = '#b1b1b7', zoomOnScroll = true, zoomOnPinch = true, panOnScroll = false, panOnScrollSpeed = 0.5, panOnScrollMode = PanOnScrollMode.Free, zoomOnDoubleClick = true, panOnDrag = true, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneScroll, onPaneContextMenu, children, onEdgeUpdate, onEdgeContextMenu, onEdgeDoubleClick, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, onEdgeUpdateStart, onEdgeUpdateEnd, edgeUpdaterRadius = 10, onNodesChange, onEdgesChange, noDragClassName = 'nodrag', noWheelClassName = 'nowheel', noPanClassName = 'nopan', fitView, fitViewOptions, connectOnClick, attributionPosition, proOptions, defaultEdgeOptions, elevateNodesOnSelect, elevateEdgesOnSelect, disableKeyboardA11y = false, autoPanOnConnect, autoPanOnNodeDrag, connectionRadius, isValidConnection, onError, style, id, nodeDragThreshold, viewport, onViewportChange, width, height, colorMode = 'light', ...rest }, ref) => {
2823
+ function ReactFlow({ nodes, edges, defaultNodes, defaultEdges, className, nodeTypes, edgeTypes, 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 = false, selectionMode = SelectionMode.Full, panActivationKeyCode = 'Space', multiSelectionKeyCode = isMacOs() ? 'Meta' : 'Control', zoomActivationKeyCode = isMacOs() ? 'Meta' : 'Control', snapToGrid, snapGrid, onlyRenderVisibleElements = false, selectNodesOnDrag, nodesDraggable, nodesConnectable, nodesFocusable, nodeOrigin = defaultNodeOrigin, edgesFocusable, edgesUpdatable, elementsSelectable = true, defaultViewport: defaultViewport$1 = defaultViewport, minZoom = 0.5, maxZoom = 2, translateExtent = infiniteExtent, preventScrolling = true, nodeExtent, defaultMarkerColor = '#b1b1b7', zoomOnScroll = true, zoomOnPinch = true, panOnScroll = false, panOnScrollSpeed = 0.5, panOnScrollMode = PanOnScrollMode.Free, zoomOnDoubleClick = true, panOnDrag = true, onPaneClick, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, onPaneScroll, onPaneContextMenu, children, onEdgeUpdate, onEdgeContextMenu, onEdgeDoubleClick, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, onEdgeUpdateStart, onEdgeUpdateEnd, edgeUpdaterRadius = 10, onNodesChange, onEdgesChange, noDragClassName = 'nodrag', noWheelClassName = 'nowheel', noPanClassName = 'nopan', fitView, fitViewOptions, connectOnClick, attributionPosition, proOptions, defaultEdgeOptions, elevateNodesOnSelect, elevateEdgesOnSelect, disableKeyboardA11y = false, autoPanOnConnect, autoPanOnNodeDrag, connectionRadius, isValidConnection, onError, style, id, nodeDragThreshold, viewport, onViewportChange, width, height, colorMode = 'light', debug, ...rest }, ref) {
2806
2824
  const rfId = id || '1';
2807
2825
  const colorModeClassName = useColorModeClass(colorMode);
2808
- return (jsx("div", { ...rest, style: { ...style, ...wrapperStyle }, ref: ref, className: cc(['react-flow', className, colorModeClassName]), "data-testid": "rf__wrapper", id: id, children: jsxs(Wrapper, { nodes: nodes, edges: edges, width: width, height: height, fitView: fitView, children: [jsx(GraphView$1, { onInit: onInit, onNodeClick: onNodeClick, onEdgeClick: onEdgeClick, onNodeMouseEnter: onNodeMouseEnter, onNodeMouseMove: onNodeMouseMove, onNodeMouseLeave: onNodeMouseLeave, onNodeContextMenu: onNodeContextMenu, onNodeDoubleClick: onNodeDoubleClick, nodeTypes: nodeTypes, edgeTypes: edgeTypes, connectionLineType: connectionLineType, connectionLineStyle: connectionLineStyle, connectionLineComponent: connectionLineComponent, connectionLineContainerStyle: connectionLineContainerStyle, selectionKeyCode: selectionKeyCode, selectionOnDrag: selectionOnDrag, selectionMode: selectionMode, deleteKeyCode: deleteKeyCode, multiSelectionKeyCode: multiSelectionKeyCode, panActivationKeyCode: panActivationKeyCode, zoomActivationKeyCode: zoomActivationKeyCode, onlyRenderVisibleElements: onlyRenderVisibleElements, defaultViewport: defaultViewport, translateExtent: translateExtent, minZoom: minZoom, maxZoom: maxZoom, preventScrolling: preventScrolling, zoomOnScroll: zoomOnScroll, zoomOnPinch: zoomOnPinch, zoomOnDoubleClick: zoomOnDoubleClick, panOnScroll: panOnScroll, panOnScrollSpeed: panOnScrollSpeed, panOnScrollMode: panOnScrollMode, panOnDrag: panOnDrag, onPaneClick: onPaneClick, onPaneMouseEnter: onPaneMouseEnter, onPaneMouseMove: onPaneMouseMove, onPaneMouseLeave: onPaneMouseLeave, onPaneScroll: onPaneScroll, onPaneContextMenu: onPaneContextMenu, onSelectionContextMenu: onSelectionContextMenu, onSelectionStart: onSelectionStart, onSelectionEnd: onSelectionEnd, onEdgeUpdate: onEdgeUpdate, onEdgeContextMenu: onEdgeContextMenu, onEdgeDoubleClick: onEdgeDoubleClick, onEdgeMouseEnter: onEdgeMouseEnter, onEdgeMouseMove: onEdgeMouseMove, onEdgeMouseLeave: onEdgeMouseLeave, onEdgeUpdateStart: onEdgeUpdateStart, onEdgeUpdateEnd: onEdgeUpdateEnd, edgeUpdaterRadius: edgeUpdaterRadius, defaultMarkerColor: defaultMarkerColor, noDragClassName: noDragClassName, noWheelClassName: noWheelClassName, noPanClassName: noPanClassName, rfId: rfId, disableKeyboardA11y: disableKeyboardA11y, nodeOrigin: nodeOrigin, nodeExtent: nodeExtent, viewport: viewport, onViewportChange: onViewportChange }), jsx(StoreUpdater, { nodes: nodes, edges: edges, defaultNodes: defaultNodes, defaultEdges: defaultEdges, onConnect: onConnect, onConnectStart: onConnectStart, onConnectEnd: onConnectEnd, onClickConnectStart: onClickConnectStart, onClickConnectEnd: onClickConnectEnd, nodesDraggable: nodesDraggable, nodesConnectable: nodesConnectable, nodesFocusable: nodesFocusable, edgesFocusable: edgesFocusable, edgesUpdatable: edgesUpdatable, elementsSelectable: elementsSelectable, elevateNodesOnSelect: elevateNodesOnSelect, elevateEdgesOnSelect: elevateEdgesOnSelect, minZoom: minZoom, maxZoom: maxZoom, nodeExtent: nodeExtent, onNodesChange: onNodesChange, onEdgesChange: onEdgesChange, snapToGrid: snapToGrid, snapGrid: snapGrid, connectionMode: connectionMode, translateExtent: translateExtent, connectOnClick: connectOnClick, defaultEdgeOptions: defaultEdgeOptions, fitView: fitView, fitViewOptions: fitViewOptions, onNodesDelete: onNodesDelete, onEdgesDelete: onEdgesDelete, onDelete: onDelete, onNodeDragStart: onNodeDragStart, onNodeDrag: onNodeDrag, onNodeDragStop: onNodeDragStop, onSelectionDrag: onSelectionDrag, onSelectionDragStart: onSelectionDragStart, onSelectionDragStop: onSelectionDragStop, onMove: onMove, onMoveStart: onMoveStart, onMoveEnd: onMoveEnd, noPanClassName: noPanClassName, nodeOrigin: nodeOrigin, rfId: rfId, autoPanOnConnect: autoPanOnConnect, autoPanOnNodeDrag: autoPanOnNodeDrag, onError: onError, connectionRadius: connectionRadius, isValidConnection: isValidConnection, selectNodesOnDrag: selectNodesOnDrag, nodeDragThreshold: nodeDragThreshold, onBeforeDelete: onBeforeDelete }), jsx(Wrapper$1, { onSelectionChange: onSelectionChange }), children, jsx(Attribution, { proOptions: proOptions, position: attributionPosition }), jsx(A11yDescriptions, { rfId: rfId, disableKeyboardA11y: disableKeyboardA11y })] }) }));
2809
- });
2810
- ReactFlow.displayName = 'ReactFlow';
2826
+ return (jsx("div", { ...rest, style: { ...style, ...wrapperStyle }, ref: ref, className: cc(['react-flow', className, colorModeClassName]), "data-testid": "rf__wrapper", id: id, children: jsxs(Wrapper, { nodes: nodes, edges: edges, width: width, height: height, fitView: fitView, children: [jsx(GraphView, { onInit: onInit, onNodeClick: onNodeClick, onEdgeClick: onEdgeClick, onNodeMouseEnter: onNodeMouseEnter, onNodeMouseMove: onNodeMouseMove, onNodeMouseLeave: onNodeMouseLeave, onNodeContextMenu: onNodeContextMenu, onNodeDoubleClick: onNodeDoubleClick, nodeTypes: nodeTypes, edgeTypes: edgeTypes, connectionLineType: connectionLineType, connectionLineStyle: connectionLineStyle, connectionLineComponent: connectionLineComponent, connectionLineContainerStyle: connectionLineContainerStyle, selectionKeyCode: selectionKeyCode, selectionOnDrag: selectionOnDrag, selectionMode: selectionMode, deleteKeyCode: deleteKeyCode, multiSelectionKeyCode: multiSelectionKeyCode, panActivationKeyCode: panActivationKeyCode, zoomActivationKeyCode: zoomActivationKeyCode, onlyRenderVisibleElements: onlyRenderVisibleElements, defaultViewport: defaultViewport$1, translateExtent: translateExtent, minZoom: minZoom, maxZoom: maxZoom, preventScrolling: preventScrolling, zoomOnScroll: zoomOnScroll, zoomOnPinch: zoomOnPinch, zoomOnDoubleClick: zoomOnDoubleClick, panOnScroll: panOnScroll, panOnScrollSpeed: panOnScrollSpeed, panOnScrollMode: panOnScrollMode, panOnDrag: panOnDrag, onPaneClick: onPaneClick, onPaneMouseEnter: onPaneMouseEnter, onPaneMouseMove: onPaneMouseMove, onPaneMouseLeave: onPaneMouseLeave, onPaneScroll: onPaneScroll, onPaneContextMenu: onPaneContextMenu, onSelectionContextMenu: onSelectionContextMenu, onSelectionStart: onSelectionStart, onSelectionEnd: onSelectionEnd, onEdgeUpdate: onEdgeUpdate, onEdgeContextMenu: onEdgeContextMenu, onEdgeDoubleClick: onEdgeDoubleClick, onEdgeMouseEnter: onEdgeMouseEnter, onEdgeMouseMove: onEdgeMouseMove, onEdgeMouseLeave: onEdgeMouseLeave, onEdgeUpdateStart: onEdgeUpdateStart, onEdgeUpdateEnd: onEdgeUpdateEnd, edgeUpdaterRadius: edgeUpdaterRadius, defaultMarkerColor: defaultMarkerColor, noDragClassName: noDragClassName, noWheelClassName: noWheelClassName, noPanClassName: noPanClassName, rfId: rfId, disableKeyboardA11y: disableKeyboardA11y, nodeOrigin: nodeOrigin, nodeExtent: nodeExtent, viewport: viewport, onViewportChange: onViewportChange }), jsx(StoreUpdater, { nodes: nodes, edges: edges, defaultNodes: defaultNodes, defaultEdges: defaultEdges, onConnect: onConnect, onConnectStart: onConnectStart, onConnectEnd: onConnectEnd, onClickConnectStart: onClickConnectStart, onClickConnectEnd: onClickConnectEnd, nodesDraggable: nodesDraggable, nodesConnectable: nodesConnectable, nodesFocusable: nodesFocusable, edgesFocusable: edgesFocusable, edgesUpdatable: edgesUpdatable, elementsSelectable: elementsSelectable, elevateNodesOnSelect: elevateNodesOnSelect, elevateEdgesOnSelect: elevateEdgesOnSelect, minZoom: minZoom, maxZoom: maxZoom, nodeExtent: nodeExtent, onNodesChange: onNodesChange, onEdgesChange: onEdgesChange, snapToGrid: snapToGrid, snapGrid: snapGrid, connectionMode: connectionMode, translateExtent: translateExtent, connectOnClick: connectOnClick, defaultEdgeOptions: defaultEdgeOptions, fitView: fitView, fitViewOptions: fitViewOptions, onNodesDelete: onNodesDelete, onEdgesDelete: onEdgesDelete, onDelete: onDelete, onNodeDragStart: onNodeDragStart, onNodeDrag: onNodeDrag, onNodeDragStop: onNodeDragStop, onSelectionDrag: onSelectionDrag, onSelectionDragStart: onSelectionDragStart, onSelectionDragStop: onSelectionDragStop, onMove: onMove, onMoveStart: onMoveStart, onMoveEnd: onMoveEnd, noPanClassName: noPanClassName, nodeOrigin: nodeOrigin, rfId: rfId, autoPanOnConnect: autoPanOnConnect, autoPanOnNodeDrag: autoPanOnNodeDrag, onError: onError, connectionRadius: connectionRadius, isValidConnection: isValidConnection, selectNodesOnDrag: selectNodesOnDrag, nodeDragThreshold: nodeDragThreshold, onBeforeDelete: onBeforeDelete, debug: debug }), jsx(SelectionListener, { onSelectionChange: onSelectionChange }), children, jsx(Attribution, { proOptions: proOptions, position: attributionPosition }), jsx(A11yDescriptions, { rfId: rfId, disableKeyboardA11y: disableKeyboardA11y })] }) }));
2827
+ }
2828
+ var index = forwardRef(ReactFlow);
2811
2829
 
2812
2830
  const selector$8 = (s) => s.domNode?.querySelector('.react-flow__edgelabel-renderer');
2813
2831
  function EdgeLabelRenderer({ children }) {
@@ -2939,7 +2957,7 @@ function useOnViewportChange({ onStart, onChange, onEnd }) {
2939
2957
  * Hook for registering an onSelectionChange handler.
2940
2958
  *
2941
2959
  * @public
2942
- * @params params.onChange - The handler to register
2960
+ * @param params.onChange - The handler to register
2943
2961
  */
2944
2962
  function useOnSelectionChange({ onChange }) {
2945
2963
  const store = useStoreApi();
@@ -2957,9 +2975,14 @@ const selector$6 = (options) => (s) => {
2957
2975
  if (s.nodes.length === 0) {
2958
2976
  return false;
2959
2977
  }
2960
- return s.nodes
2961
- .filter((n) => (options.includeHiddenNodes ? true : !n.hidden))
2962
- .every((n) => n[internalsSymbol]?.handleBounds !== undefined);
2978
+ for (const node of s.nodes) {
2979
+ if (options.includeHiddenNodes || !node.hidden) {
2980
+ if (node[internalsSymbol]?.handleBounds === undefined) {
2981
+ return false;
2982
+ }
2983
+ }
2984
+ }
2985
+ return true;
2963
2986
  };
2964
2987
  const defaultOptions = {
2965
2988
  includeHiddenNodes: false,
@@ -2977,7 +3000,7 @@ function useNodesInitialized(options = defaultOptions) {
2977
3000
  }
2978
3001
 
2979
3002
  /**
2980
- * Hook to check if a <Handle /> is connected to another <Handle /> and get the connections.
3003
+ * Hook to check if a <Handle /> is connected to another <Handle /> and get the connections.
2981
3004
  *
2982
3005
  * @public
2983
3006
  * @param param.type - handle type 'source' or 'target'
@@ -2985,12 +3008,12 @@ function useNodesInitialized(options = defaultOptions) {
2985
3008
  * @param param.id - the handle id (this is only needed if the node has multiple handles of the same type)
2986
3009
  * @param param.onConnect - gets called when a connection is established
2987
3010
  * @param param.onDisconnect - gets called when a connection is removed
2988
- * @returns an array with connections
3011
+ * @returns an array with handle connections
2989
3012
  */
2990
3013
  function useHandleConnections({ type, id = null, nodeId, onConnect, onDisconnect, }) {
2991
3014
  const _nodeId = useNodeId();
3015
+ const currentNodeId = nodeId ?? _nodeId;
2992
3016
  const prevConnections = useRef(null);
2993
- const currentNodeId = nodeId || _nodeId;
2994
3017
  const connections = useStore((state) => state.connectionLookup.get(`${currentNodeId}-${type}-${id}`), areConnectionMapsEqual);
2995
3018
  useEffect(() => {
2996
3019
  // @todo dicuss if onConnect/onDisconnect should be called when the component mounts/unmounts
@@ -3007,17 +3030,20 @@ function useHandleConnections({ type, id = null, nodeId, onConnect, onDisconnect
3007
3030
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
3008
3031
  function useNodesData(nodeIds) {
3009
3032
  const nodesData = useStore(useCallback((s) => {
3010
- if (!Array.isArray(nodeIds)) {
3011
- return s.nodeLookup.get(nodeIds)?.data || null;
3012
- }
3013
3033
  const data = [];
3014
- for (const nodeId of nodeIds) {
3015
- const nodeData = s.nodeLookup.get(nodeId)?.data;
3016
- if (nodeData) {
3017
- data.push(nodeData);
3034
+ const isArrayOfIds = Array.isArray(nodeIds);
3035
+ const _nodeIds = isArrayOfIds ? nodeIds : [nodeIds];
3036
+ for (const nodeId of _nodeIds) {
3037
+ const node = s.nodeLookup.get(nodeId);
3038
+ if (node) {
3039
+ data.push({
3040
+ id: node.id,
3041
+ type: node.type,
3042
+ data: node.data,
3043
+ });
3018
3044
  }
3019
3045
  }
3020
- return data;
3046
+ return isArrayOfIds ? data : data[0] ?? null;
3021
3047
  }, [nodeIds]), shallow);
3022
3048
  return nodesData;
3023
3049
  }
@@ -3032,20 +3058,13 @@ const selector$5 = (s) => ({
3032
3058
  * Hook for accessing the ongoing connection.
3033
3059
  *
3034
3060
  * @public
3035
- * @returns ongoing connection: startHandle, endHandle, status, position
3061
+ * @returns ongoing connection
3036
3062
  */
3037
3063
  function useConnection() {
3038
3064
  const ongoingConnection = useStore(selector$5, shallow);
3039
3065
  return ongoingConnection;
3040
3066
  }
3041
3067
 
3042
- var BackgroundVariant;
3043
- (function (BackgroundVariant) {
3044
- BackgroundVariant["Lines"] = "lines";
3045
- BackgroundVariant["Dots"] = "dots";
3046
- BackgroundVariant["Cross"] = "cross";
3047
- })(BackgroundVariant || (BackgroundVariant = {}));
3048
-
3049
3068
  function LinePattern({ dimensions, lineWidth, variant, className }) {
3050
3069
  return (jsx("path", { strokeWidth: lineWidth, d: `M${dimensions[0] / 2} 0 V${dimensions[1]} M0 ${dimensions[1] / 2} H${dimensions[0]}`, className: cc(['react-flow__background-pattern', variant, className]) }));
3051
3070
  }
@@ -3053,13 +3072,20 @@ function DotPattern({ radius, className }) {
3053
3072
  return (jsx("circle", { cx: radius, cy: radius, r: radius, className: cc(['react-flow__background-pattern', 'dots', className]) }));
3054
3073
  }
3055
3074
 
3075
+ var BackgroundVariant;
3076
+ (function (BackgroundVariant) {
3077
+ BackgroundVariant["Lines"] = "lines";
3078
+ BackgroundVariant["Dots"] = "dots";
3079
+ BackgroundVariant["Cross"] = "cross";
3080
+ })(BackgroundVariant || (BackgroundVariant = {}));
3081
+
3056
3082
  const defaultSize = {
3057
3083
  [BackgroundVariant.Dots]: 1,
3058
3084
  [BackgroundVariant.Lines]: 1,
3059
3085
  [BackgroundVariant.Cross]: 6,
3060
3086
  };
3061
3087
  const selector$4 = (s) => ({ transform: s.transform, patternId: `pattern-${s.rfId}` });
3062
- function Background({ id, variant = BackgroundVariant.Dots,
3088
+ function BackgroundComponent({ id, variant = BackgroundVariant.Dots,
3063
3089
  // only used for dots and cross
3064
3090
  gap = 20,
3065
3091
  // only used for lines and cross
@@ -3084,8 +3110,8 @@ size, lineWidth = 1, offset = 2, color, bgColor, style, className, patternClassN
3084
3110
  '--xy-background-pattern-color-props': color,
3085
3111
  }, ref: ref, "data-testid": "rf__background", children: [jsx("pattern", { id: _patternId, x: transform[0] % scaledGap[0], y: transform[1] % scaledGap[1], width: scaledGap[0], height: scaledGap[1], patternUnits: "userSpaceOnUse", patternTransform: `translate(-${patternOffset[0]},-${patternOffset[1]})`, children: isDots ? (jsx(DotPattern, { radius: scaledSize / offset, className: patternClassName })) : (jsx(LinePattern, { dimensions: patternDimensions, lineWidth: lineWidth, variant: variant, className: patternClassName })) }), jsx("rect", { x: "0", y: "0", width: "100%", height: "100%", fill: `url(#${_patternId})` })] }));
3086
3112
  }
3087
- Background.displayName = 'Background';
3088
- var Background$1 = memo(Background);
3113
+ BackgroundComponent.displayName = 'Background';
3114
+ const Background = memo(BackgroundComponent);
3089
3115
 
3090
3116
  function PlusIcon() {
3091
3117
  return (jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 32 32", children: jsx("path", { d: "M32 18.133H18.133V32h-4.266V18.133H0v-4.266h13.867V0h4.266v13.867H32z" }) }));
@@ -3107,15 +3133,16 @@ function UnlockIcon() {
3107
3133
  return (jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 25 32", children: jsx("path", { d: "M21.333 10.667H19.81V7.619C19.81 3.429 16.38 0 12.19 0c-4.114 1.828-1.37 2.133.305 2.438 1.676.305 4.42 2.59 4.42 5.181v3.048H3.047A3.056 3.056 0 000 13.714v15.238A3.056 3.056 0 003.048 32h18.285a3.056 3.056 0 003.048-3.048V13.714a3.056 3.056 0 00-3.048-3.047zM12.19 24.533a3.056 3.056 0 01-3.047-3.047 3.056 3.056 0 013.047-3.048 3.056 3.056 0 013.048 3.048 3.056 3.056 0 01-3.048 3.047z" }) }));
3108
3134
  }
3109
3135
 
3110
- const ControlButton = ({ children, className, ...rest }) => (jsx("button", { type: "button", className: cc(['react-flow__controls-button', className]), ...rest, children: children }));
3111
- ControlButton.displayName = 'ControlButton';
3136
+ function ControlButton({ children, className, ...rest }) {
3137
+ return (jsx("button", { type: "button", className: cc(['react-flow__controls-button', className]), ...rest, children: children }));
3138
+ }
3112
3139
 
3113
3140
  const selector$3 = (s) => ({
3114
3141
  isInteractive: s.nodesDraggable || s.nodesConnectable || s.elementsSelectable,
3115
3142
  minZoomReached: s.transform[2] <= s.minZoom,
3116
3143
  maxZoomReached: s.transform[2] >= s.maxZoom,
3117
3144
  });
3118
- const Controls = ({ style, showZoom = true, showFitView = true, showInteractive = true, fitViewOptions, onZoomIn, onZoomOut, onFitView, onInteractiveChange, className, children, position = 'bottom-left', }) => {
3145
+ function ControlsComponent({ style, showZoom = true, showFitView = true, showInteractive = true, fitViewOptions, onZoomIn, onZoomOut, onFitView, onInteractiveChange, className, children, position = 'bottom-left', 'aria-label': ariaLabel = 'React Flow controls', }) {
3119
3146
  const store = useStoreApi();
3120
3147
  const { isInteractive, minZoomReached, maxZoomReached } = useStore(selector$3, shallow);
3121
3148
  const { zoomIn, zoomOut, fitView } = useReactFlow();
@@ -3139,12 +3166,12 @@ const Controls = ({ style, showZoom = true, showFitView = true, showInteractive
3139
3166
  });
3140
3167
  onInteractiveChange?.(!isInteractive);
3141
3168
  };
3142
- return (jsxs(Panel, { className: cc(['react-flow__controls', className]), position: position, style: style, "data-testid": "rf__controls", children: [showZoom && (jsxs(Fragment, { children: [jsx(ControlButton, { onClick: onZoomInHandler, className: "react-flow__controls-zoomin", title: "zoom in", "aria-label": "zoom in", disabled: maxZoomReached, children: jsx(PlusIcon, {}) }), jsx(ControlButton, { onClick: onZoomOutHandler, className: "react-flow__controls-zoomout", title: "zoom out", "aria-label": "zoom out", disabled: minZoomReached, children: jsx(MinusIcon, {}) })] })), showFitView && (jsx(ControlButton, { className: "react-flow__controls-fitview", onClick: onFitViewHandler, title: "fit view", "aria-label": "fit view", children: jsx(FitViewIcon, {}) })), showInteractive && (jsx(ControlButton, { className: "react-flow__controls-interactive", onClick: onToggleInteractivity, title: "toggle interactivity", "aria-label": "toggle interactivity", children: isInteractive ? jsx(UnlockIcon, {}) : jsx(LockIcon, {}) })), children] }));
3143
- };
3144
- Controls.displayName = 'Controls';
3145
- var Controls$1 = memo(Controls);
3169
+ return (jsxs(Panel, { className: cc(['react-flow__controls', className]), position: position, style: style, "data-testid": "rf__controls", "aria-label": ariaLabel, children: [showZoom && (jsxs(Fragment, { children: [jsx(ControlButton, { onClick: onZoomInHandler, className: "react-flow__controls-zoomin", title: "zoom in", "aria-label": "zoom in", disabled: maxZoomReached, children: jsx(PlusIcon, {}) }), jsx(ControlButton, { onClick: onZoomOutHandler, className: "react-flow__controls-zoomout", title: "zoom out", "aria-label": "zoom out", disabled: minZoomReached, children: jsx(MinusIcon, {}) })] })), showFitView && (jsx(ControlButton, { className: "react-flow__controls-fitview", onClick: onFitViewHandler, title: "fit view", "aria-label": "fit view", children: jsx(FitViewIcon, {}) })), showInteractive && (jsx(ControlButton, { className: "react-flow__controls-interactive", onClick: onToggleInteractivity, title: "toggle interactivity", "aria-label": "toggle interactivity", children: isInteractive ? jsx(UnlockIcon, {}) : jsx(LockIcon, {}) })), children] }));
3170
+ }
3171
+ ControlsComponent.displayName = 'Controls';
3172
+ const Controls = memo(ControlsComponent);
3146
3173
 
3147
- function MiniMapNode({ id, x, y, width, height, style, color, strokeColor, strokeWidth, className, borderRadius, shapeRendering, selected, onClick, }) {
3174
+ function MiniMapNodeComponent({ id, x, y, width, height, style, color, strokeColor, strokeWidth, className, borderRadius, shapeRendering, selected, onClick, }) {
3148
3175
  const { background, backgroundColor } = style || {};
3149
3176
  const fill = (color || background || backgroundColor);
3150
3177
  return (jsx("rect", { className: cc(['react-flow__minimap-node', { selected }, className]), x: x, y: y, rx: borderRadius, ry: borderRadius, width: width, height: height, style: {
@@ -3153,15 +3180,15 @@ function MiniMapNode({ id, x, y, width, height, style, color, strokeColor, strok
3153
3180
  strokeWidth,
3154
3181
  }, shapeRendering: shapeRendering, onClick: onClick ? (event) => onClick(event, id) : undefined }));
3155
3182
  }
3156
- var MiniMapNode$1 = memo(MiniMapNode);
3183
+ const MiniMapNode = memo(MiniMapNodeComponent);
3157
3184
 
3158
3185
  const selector$2 = (s) => s.nodeOrigin;
3159
3186
  const selectorNodeIds = (s) => s.nodes.map((node) => node.id);
3160
- const getAttrFunction = (func) => (func instanceof Function ? func : () => func);
3187
+ const getAttrFunction = (func) => func instanceof Function ? func : () => func;
3161
3188
  function MiniMapNodes({ nodeStrokeColor, nodeColor, nodeClassName = '', nodeBorderRadius = 5, nodeStrokeWidth,
3162
3189
  // We need to rename the prop to be `CapitalCase` so that JSX will render it as
3163
3190
  // a component properly.
3164
- nodeComponent: NodeComponent = MiniMapNode$1, onClick, }) {
3191
+ nodeComponent: NodeComponent = MiniMapNode, onClick, }) {
3165
3192
  const nodeIds = useStore(selectorNodeIds, shallow);
3166
3193
  const nodeOrigin = useStore(selector$2);
3167
3194
  const nodeColorFunc = getAttrFunction(nodeColor);
@@ -3176,7 +3203,7 @@ nodeComponent: NodeComponent = MiniMapNode$1, onClick, }) {
3176
3203
  // For more details, see a similar commit in `NodeRenderer/index.tsx`.
3177
3204
  jsx(NodeComponentWrapper, { id: nodeId, nodeOrigin: nodeOrigin, nodeColorFunc: nodeColorFunc, nodeStrokeColorFunc: nodeStrokeColorFunc, nodeClassNameFunc: nodeClassNameFunc, nodeBorderRadius: nodeBorderRadius, nodeStrokeWidth: nodeStrokeWidth, NodeComponent: NodeComponent, onClick: onClick, shapeRendering: shapeRendering }, nodeId))) }));
3178
3205
  }
3179
- const NodeComponentWrapper = memo(function NodeComponentWrapper({ id, nodeOrigin, nodeColorFunc, nodeStrokeColorFunc, nodeClassNameFunc, nodeBorderRadius, nodeStrokeWidth, shapeRendering, NodeComponent, onClick, }) {
3206
+ function NodeComponentWrapperInner({ id, nodeOrigin, nodeColorFunc, nodeStrokeColorFunc, nodeClassNameFunc, nodeBorderRadius, nodeStrokeWidth, shapeRendering, NodeComponent, onClick, }) {
3180
3207
  const { node, x, y } = useStore((s) => {
3181
3208
  const node = s.nodeLookup.get(id);
3182
3209
  const { x, y } = getNodePositionWithOrigin(node, node?.origin || nodeOrigin).positionAbsolute;
@@ -3186,11 +3213,13 @@ const NodeComponentWrapper = memo(function NodeComponentWrapper({ id, nodeOrigin
3186
3213
  y,
3187
3214
  };
3188
3215
  }, shallow);
3189
- if (!node || node.hidden || !(node.computed?.width || node.width) || !(node.computed?.height || node.height)) {
3216
+ if (!node || node.hidden || !nodeHasDimensions(node)) {
3190
3217
  return null;
3191
3218
  }
3192
- return (jsx(NodeComponent, { x: x, y: y, width: node.computed?.width ?? node.width ?? 0, height: node.computed?.height ?? node.height ?? 0, style: node.style, selected: !!node.selected, className: nodeClassNameFunc(node), color: nodeColorFunc(node), borderRadius: nodeBorderRadius, strokeColor: nodeStrokeColorFunc(node), strokeWidth: nodeStrokeWidth, shapeRendering: shapeRendering, onClick: onClick, id: node.id }));
3193
- });
3219
+ const { width, height } = getNodeDimensions(node);
3220
+ return (jsx(NodeComponent, { x: x, y: y, width: width, height: height, style: node.style, selected: !!node.selected, className: nodeClassNameFunc(node), color: nodeColorFunc(node), borderRadius: nodeBorderRadius, strokeColor: nodeStrokeColorFunc(node), strokeWidth: nodeStrokeWidth, shapeRendering: shapeRendering, onClick: onClick, id: node.id }));
3221
+ }
3222
+ const NodeComponentWrapper = memo(NodeComponentWrapperInner);
3194
3223
  var MiniMapNodes$1 = memo(MiniMapNodes);
3195
3224
 
3196
3225
  const defaultWidth = 200;
@@ -3204,7 +3233,7 @@ const selector$1 = (s) => {
3204
3233
  };
3205
3234
  return {
3206
3235
  viewBB,
3207
- boundingRect: s.nodes.length > 0 ? getBoundsOfRects(getNodesBounds(s.nodes, s.nodeOrigin), viewBB) : viewBB,
3236
+ boundingRect: s.nodes.length > 0 ? getBoundsOfRects(getNodesBounds(s.nodes, { nodeOrigin: s.nodeOrigin }), viewBB) : viewBB,
3208
3237
  rfId: s.rfId,
3209
3238
  nodeOrigin: s.nodeOrigin,
3210
3239
  panZoom: s.panZoom,
@@ -3214,10 +3243,10 @@ const selector$1 = (s) => {
3214
3243
  };
3215
3244
  };
3216
3245
  const ARIA_LABEL_KEY = 'react-flow__minimap-desc';
3217
- function MiniMap({ style, className, nodeStrokeColor, nodeColor, nodeClassName = '', nodeBorderRadius = 5, nodeStrokeWidth,
3246
+ function MiniMapComponent({ style, className, nodeStrokeColor, nodeColor, nodeClassName = '', nodeBorderRadius = 5, nodeStrokeWidth,
3218
3247
  // We need to rename the prop to be `CapitalCase` so that JSX will render it as
3219
3248
  // a component properly.
3220
- nodeComponent, maskColor, maskStrokeColor = 'none', maskStrokeWidth = 1, position = 'bottom-right', onClick, onNodeClick, pannable = false, zoomable = false, ariaLabel = 'React Flow mini map', inversePan, zoomStep = 10, offsetScale = 5, }) {
3249
+ nodeComponent, bgColor, maskColor, maskStrokeColor, maskStrokeWidth, position = 'bottom-right', onClick, onNodeClick, pannable = false, zoomable = false, ariaLabel = 'React Flow mini map', inversePan, zoomStep = 10, offsetScale = 5, }) {
3221
3250
  const store = useStoreApi();
3222
3251
  const svg = useRef(null);
3223
3252
  const { boundingRect, viewBB, rfId, panZoom, translateExtent, flowWidth, flowHeight } = useStore(selector$1, shallow);
@@ -3275,189 +3304,108 @@ nodeComponent, maskColor, maskStrokeColor = 'none', maskStrokeWidth = 1, positio
3275
3304
  : undefined;
3276
3305
  return (jsx(Panel, { position: position, style: {
3277
3306
  ...style,
3278
- '--xy-minimap-mask-color-props': typeof maskColor === 'string' ? maskColor : undefined,
3307
+ '--xy-minimap-background-color-props': typeof bgColor === 'string' ? bgColor : undefined,
3308
+ '--xy-minimap-mask-background-color-props': typeof maskColor === 'string' ? maskColor : undefined,
3309
+ '--xy-minimap-mask-stroke-color-props': typeof maskStrokeColor === 'string' ? maskStrokeColor : undefined,
3310
+ '--xy-minimap-mask-stroke-width-props': typeof maskStrokeWidth === 'number' ? maskStrokeWidth * viewScale : undefined,
3279
3311
  '--xy-minimap-node-background-color-props': typeof nodeColor === 'string' ? nodeColor : undefined,
3280
3312
  '--xy-minimap-node-stroke-color-props': typeof nodeStrokeColor === 'string' ? nodeStrokeColor : undefined,
3281
3313
  '--xy-minimap-node-stroke-width-props': typeof nodeStrokeWidth === 'string' ? nodeStrokeWidth : undefined,
3282
- }, className: cc(['react-flow__minimap', className]), "data-testid": "rf__minimap", children: jsxs("svg", { width: elementWidth, height: elementHeight, viewBox: `${x} ${y} ${width} ${height}`, role: "img", "aria-labelledby": labelledBy, ref: svg, onClick: onSvgClick, children: [ariaLabel && jsx("title", { id: labelledBy, children: ariaLabel }), jsx(MiniMapNodes$1, { onClick: onSvgNodeClick, nodeColor: nodeColor, nodeStrokeColor: nodeStrokeColor, nodeBorderRadius: nodeBorderRadius, nodeClassName: nodeClassName, nodeStrokeWidth: nodeStrokeWidth, nodeComponent: nodeComponent }), jsx("path", { className: "react-flow__minimap-mask", d: `M${x - offset},${y - offset}h${width + offset * 2}v${height + offset * 2}h${-width - offset * 2}z
3283
- M${viewBB.x},${viewBB.y}h${viewBB.width}v${viewBB.height}h${-viewBB.width}z`, fillRule: "evenodd", stroke: maskStrokeColor, strokeWidth: maskStrokeWidth, pointerEvents: "none" })] }) }));
3284
- }
3285
- MiniMap.displayName = 'MiniMap';
3286
- var MiniMap$1 = memo(MiniMap);
3287
-
3288
- var ResizeControlVariant;
3289
- (function (ResizeControlVariant) {
3290
- ResizeControlVariant["Line"] = "line";
3291
- ResizeControlVariant["Handle"] = "handle";
3292
- })(ResizeControlVariant || (ResizeControlVariant = {}));
3293
-
3294
- // returns an array of two numbers (0, 1 or -1) representing the direction of the resize
3295
- // 0 = no change, 1 = increase, -1 = decrease
3296
- function getDirection({ width, prevWidth, height, prevHeight, invertX, invertY }) {
3297
- const deltaWidth = width - prevWidth;
3298
- const deltaHeight = height - prevHeight;
3299
- const direction = [deltaWidth > 0 ? 1 : deltaWidth < 0 ? -1 : 0, deltaHeight > 0 ? 1 : deltaHeight < 0 ? -1 : 0];
3300
- if (deltaWidth && invertX) {
3301
- direction[0] = direction[0] * -1;
3302
- }
3303
- if (deltaHeight && invertY) {
3304
- direction[1] = direction[1] * -1;
3305
- }
3306
- return direction;
3314
+ }, className: cc(['react-flow__minimap', className]), "data-testid": "rf__minimap", children: jsxs("svg", { width: elementWidth, height: elementHeight, viewBox: `${x} ${y} ${width} ${height}`, className: "react-flow__minimap-svg", role: "img", "aria-labelledby": labelledBy, ref: svg, onClick: onSvgClick, children: [ariaLabel && jsx("title", { id: labelledBy, children: ariaLabel }), jsx(MiniMapNodes$1, { onClick: onSvgNodeClick, nodeColor: nodeColor, nodeStrokeColor: nodeStrokeColor, nodeBorderRadius: nodeBorderRadius, nodeClassName: nodeClassName, nodeStrokeWidth: nodeStrokeWidth, nodeComponent: nodeComponent }), jsx("path", { className: "react-flow__minimap-mask", d: `M${x - offset},${y - offset}h${width + offset * 2}v${height + offset * 2}h${-width - offset * 2}z
3315
+ M${viewBB.x},${viewBB.y}h${viewBB.width}v${viewBB.height}h${-viewBB.width}z`, fillRule: "evenodd", pointerEvents: "none" })] }) }));
3307
3316
  }
3317
+ MiniMapComponent.displayName = 'MiniMap';
3318
+ const MiniMap = memo(MiniMapComponent);
3308
3319
 
3309
- const initPrevValues = { width: 0, height: 0, x: 0, y: 0 };
3310
- const initStartValues = {
3311
- ...initPrevValues,
3312
- pointerX: 0,
3313
- pointerY: 0,
3314
- aspectRatio: 1,
3315
- };
3316
3320
  function ResizeControl({ nodeId, position, variant = ResizeControlVariant.Handle, className, style = {}, children, color, minWidth = 10, minHeight = 10, maxWidth = Number.MAX_VALUE, maxHeight = Number.MAX_VALUE, keepAspectRatio = false, shouldResize, onResizeStart, onResize, onResizeEnd, }) {
3317
3321
  const contextNodeId = useNodeId();
3318
3322
  const id = typeof nodeId === 'string' ? nodeId : contextNodeId;
3319
3323
  const store = useStoreApi();
3320
3324
  const resizeControlRef = useRef(null);
3321
- const startValues = useRef(initStartValues);
3322
- const prevValues = useRef(initPrevValues);
3323
3325
  const defaultPosition = variant === ResizeControlVariant.Line ? 'right' : 'bottom-right';
3324
3326
  const controlPosition = position ?? defaultPosition;
3327
+ const resizer = useRef(null);
3325
3328
  useEffect(() => {
3326
3329
  if (!resizeControlRef.current || !id) {
3327
3330
  return;
3328
3331
  }
3329
- const selection = select(resizeControlRef.current);
3330
- const enableX = controlPosition.includes('right') || controlPosition.includes('left');
3331
- const enableY = controlPosition.includes('bottom') || controlPosition.includes('top');
3332
- const invertX = controlPosition.includes('left');
3333
- const invertY = controlPosition.includes('top');
3334
- const dragHandler = drag()
3335
- .on('start', (event) => {
3336
- const { nodeLookup, transform, snapGrid, snapToGrid } = store.getState();
3337
- const node = nodeLookup.get(id);
3338
- const { xSnapped, ySnapped } = getPointerPosition(event.sourceEvent, { transform, snapGrid, snapToGrid });
3339
- prevValues.current = {
3340
- width: node?.computed?.width ?? 0,
3341
- height: node?.computed?.height ?? 0,
3342
- x: node?.position.x ?? 0,
3343
- y: node?.position.y ?? 0,
3344
- };
3345
- startValues.current = {
3346
- ...prevValues.current,
3347
- pointerX: xSnapped,
3348
- pointerY: ySnapped,
3349
- aspectRatio: prevValues.current.width / prevValues.current.height,
3350
- };
3351
- onResizeStart?.(event, { ...prevValues.current });
3352
- })
3353
- .on('drag', (event) => {
3354
- const { nodeLookup, transform, snapGrid, snapToGrid, triggerNodeChanges } = store.getState();
3355
- const { xSnapped, ySnapped } = getPointerPosition(event.sourceEvent, { transform, snapGrid, snapToGrid });
3356
- const node = nodeLookup.get(id);
3357
- if (node) {
3358
- const changes = [];
3359
- const { pointerX: startX, pointerY: startY, width: startWidth, height: startHeight, x: startNodeX, y: startNodeY, aspectRatio, } = startValues.current;
3360
- const { x: prevX, y: prevY, width: prevWidth, height: prevHeight } = prevValues.current;
3361
- const distX = Math.floor(enableX ? xSnapped - startX : 0);
3362
- const distY = Math.floor(enableY ? ySnapped - startY : 0);
3363
- let width = clamp(startWidth + (invertX ? -distX : distX), minWidth, maxWidth);
3364
- let height = clamp(startHeight + (invertY ? -distY : distY), minHeight, maxHeight);
3365
- if (keepAspectRatio) {
3366
- const nextAspectRatio = width / height;
3367
- const isDiagonal = enableX && enableY;
3368
- const isHorizontal = enableX && !enableY;
3369
- const isVertical = enableY && !enableX;
3370
- width = (nextAspectRatio <= aspectRatio && isDiagonal) || isVertical ? height * aspectRatio : width;
3371
- height = (nextAspectRatio > aspectRatio && isDiagonal) || isHorizontal ? width / aspectRatio : height;
3372
- if (width >= maxWidth) {
3373
- width = maxWidth;
3374
- height = maxWidth / aspectRatio;
3375
- }
3376
- else if (width <= minWidth) {
3377
- width = minWidth;
3378
- height = minWidth / aspectRatio;
3379
- }
3380
- if (height >= maxHeight) {
3381
- height = maxHeight;
3382
- width = maxHeight * aspectRatio;
3383
- }
3384
- else if (height <= minHeight) {
3385
- height = minHeight;
3386
- width = minHeight * aspectRatio;
3387
- }
3388
- }
3389
- const isWidthChange = width !== prevWidth;
3390
- const isHeightChange = height !== prevHeight;
3391
- if (invertX || invertY) {
3392
- const x = invertX ? startNodeX - (width - startWidth) : startNodeX;
3393
- const y = invertY ? startNodeY - (height - startHeight) : startNodeY;
3394
- // only transform the node if the width or height changes
3395
- const isXPosChange = x !== prevX && isWidthChange;
3396
- const isYPosChange = y !== prevY && isHeightChange;
3397
- if (isXPosChange || isYPosChange) {
3332
+ if (!resizer.current) {
3333
+ resizer.current = XYResizer({
3334
+ domNode: resizeControlRef.current,
3335
+ nodeId: id,
3336
+ getStoreItems: () => {
3337
+ const { nodeLookup, transform, snapGrid, snapToGrid, nodeOrigin } = store.getState();
3338
+ return {
3339
+ nodeLookup,
3340
+ transform,
3341
+ snapGrid,
3342
+ snapToGrid,
3343
+ nodeOrigin,
3344
+ };
3345
+ },
3346
+ onChange: (change, childChanges) => {
3347
+ const { triggerNodeChanges } = store.getState();
3348
+ const changes = [];
3349
+ if (change.isXPosChange || change.isYPosChange) {
3398
3350
  const positionChange = {
3399
- id: node.id,
3351
+ id,
3400
3352
  type: 'position',
3401
3353
  position: {
3402
- x: isXPosChange ? x : prevX,
3403
- y: isYPosChange ? y : prevY,
3354
+ x: change.x,
3355
+ y: change.y,
3404
3356
  },
3405
3357
  };
3406
3358
  changes.push(positionChange);
3407
- prevValues.current.x = positionChange.position.x;
3408
- prevValues.current.y = positionChange.position.y;
3409
3359
  }
3410
- }
3411
- if (isWidthChange || isHeightChange) {
3360
+ if (change.isWidthChange || change.isHeightChange) {
3361
+ const dimensionChange = {
3362
+ id,
3363
+ type: 'dimensions',
3364
+ resizing: true,
3365
+ dimensions: {
3366
+ width: change.width,
3367
+ height: change.height,
3368
+ },
3369
+ };
3370
+ changes.push(dimensionChange);
3371
+ }
3372
+ for (const childChange of childChanges) {
3373
+ const positionChange = {
3374
+ ...childChange,
3375
+ type: 'position',
3376
+ };
3377
+ changes.push(positionChange);
3378
+ }
3379
+ triggerNodeChanges(changes);
3380
+ },
3381
+ onEnd: () => {
3412
3382
  const dimensionChange = {
3413
3383
  id: id,
3414
3384
  type: 'dimensions',
3415
- updateStyle: true,
3416
- resizing: true,
3417
- dimensions: {
3418
- width: width,
3419
- height: height,
3420
- },
3385
+ resizing: false,
3421
3386
  };
3422
- changes.push(dimensionChange);
3423
- prevValues.current.width = width;
3424
- prevValues.current.height = height;
3425
- }
3426
- if (changes.length === 0) {
3427
- return;
3428
- }
3429
- const direction = getDirection({
3430
- width: prevValues.current.width,
3431
- prevWidth,
3432
- height: prevValues.current.height,
3433
- prevHeight,
3434
- invertX,
3435
- invertY,
3436
- });
3437
- const nextValues = { ...prevValues.current, direction };
3438
- const callResize = shouldResize?.(event, nextValues);
3439
- if (callResize === false) {
3440
- return;
3441
- }
3442
- onResize?.(event, nextValues);
3443
- triggerNodeChanges(changes);
3444
- }
3445
- })
3446
- .on('end', (event) => {
3447
- const dimensionChange = {
3448
- id: id,
3449
- type: 'dimensions',
3450
- resizing: false,
3451
- };
3452
- onResizeEnd?.(event, { ...prevValues.current });
3453
- store.getState().triggerNodeChanges([dimensionChange]);
3387
+ store.getState().triggerNodeChanges([dimensionChange]);
3388
+ },
3389
+ });
3390
+ }
3391
+ resizer.current.update({
3392
+ controlPosition,
3393
+ boundaries: {
3394
+ minWidth,
3395
+ minHeight,
3396
+ maxWidth,
3397
+ maxHeight,
3398
+ },
3399
+ keepAspectRatio,
3400
+ onResizeStart,
3401
+ onResize,
3402
+ onResizeEnd,
3403
+ shouldResize,
3454
3404
  });
3455
- selection.call(dragHandler);
3456
3405
  return () => {
3457
- selection.on('.drag', null);
3406
+ resizer.current?.destroy();
3458
3407
  };
3459
3408
  }, [
3460
- id,
3461
3409
  controlPosition,
3462
3410
  minWidth,
3463
3411
  minHeight,
@@ -3467,21 +3415,20 @@ function ResizeControl({ nodeId, position, variant = ResizeControlVariant.Handle
3467
3415
  onResizeStart,
3468
3416
  onResize,
3469
3417
  onResizeEnd,
3418
+ shouldResize,
3470
3419
  ]);
3471
3420
  const positionClassNames = controlPosition.split('-');
3472
3421
  const colorStyleProp = variant === ResizeControlVariant.Line ? 'borderColor' : 'backgroundColor';
3473
3422
  const controlStyle = color ? { ...style, [colorStyleProp]: color } : style;
3474
3423
  return (jsx("div", { className: cc(['react-flow__resize-control', 'nodrag', ...positionClassNames, variant, className]), ref: resizeControlRef, style: controlStyle, children: children }));
3475
3424
  }
3476
- var ResizeControl$1 = memo(ResizeControl);
3425
+ const NodeResizeControl = memo(ResizeControl);
3477
3426
 
3478
- const handleControls = ['top-left', 'top-right', 'bottom-left', 'bottom-right'];
3479
- const lineControls = ['top', 'right', 'bottom', 'left'];
3480
3427
  function NodeResizer({ nodeId, isVisible = true, handleClassName, handleStyle, lineClassName, lineStyle, color, minWidth = 10, minHeight = 10, maxWidth = Number.MAX_VALUE, maxHeight = Number.MAX_VALUE, keepAspectRatio = false, shouldResize, onResizeStart, onResize, onResizeEnd, }) {
3481
3428
  if (!isVisible) {
3482
3429
  return null;
3483
3430
  }
3484
- return (jsxs(Fragment, { children: [lineControls.map((c) => (jsx(ResizeControl$1, { className: lineClassName, style: lineStyle, nodeId: nodeId, position: c, variant: ResizeControlVariant.Line, color: color, minWidth: minWidth, minHeight: minHeight, maxWidth: maxWidth, maxHeight: maxHeight, onResizeStart: onResizeStart, keepAspectRatio: keepAspectRatio, shouldResize: shouldResize, onResize: onResize, onResizeEnd: onResizeEnd }, c))), handleControls.map((c) => (jsx(ResizeControl$1, { className: handleClassName, style: handleStyle, nodeId: nodeId, position: c, color: color, minWidth: minWidth, minHeight: minHeight, maxWidth: maxWidth, maxHeight: maxHeight, onResizeStart: onResizeStart, keepAspectRatio: keepAspectRatio, shouldResize: shouldResize, onResize: onResize, onResizeEnd: onResizeEnd }, c)))] }));
3431
+ return (jsxs(Fragment, { children: [XY_RESIZER_LINE_POSITIONS.map((position) => (jsx(NodeResizeControl, { className: lineClassName, style: lineStyle, nodeId: nodeId, position: position, variant: ResizeControlVariant.Line, color: color, minWidth: minWidth, minHeight: minHeight, maxWidth: maxWidth, maxHeight: maxHeight, onResizeStart: onResizeStart, keepAspectRatio: keepAspectRatio, shouldResize: shouldResize, onResize: onResize, onResizeEnd: onResizeEnd }, position))), XY_RESIZER_HANDLE_POSITIONS.map((position) => (jsx(NodeResizeControl, { className: handleClassName, style: handleStyle, nodeId: nodeId, position: position, color: color, minWidth: minWidth, minHeight: minHeight, maxWidth: maxWidth, maxHeight: maxHeight, onResizeStart: onResizeStart, keepAspectRatio: keepAspectRatio, shouldResize: shouldResize, onResize: onResize, onResizeEnd: onResizeEnd }, position)))] }));
3485
3432
  }
3486
3433
 
3487
3434
  const selector = (state) => state.domNode?.querySelector('.react-flow__renderer');
@@ -3533,7 +3480,7 @@ function NodeToolbar({ nodeId, children, className, style, isVisible, position =
3533
3480
  if (!isActive || !nodes.length) {
3534
3481
  return null;
3535
3482
  }
3536
- const nodeRect = getNodesBounds(nodes, nodeOrigin);
3483
+ const nodeRect = getNodesBounds(nodes, { nodeOrigin });
3537
3484
  const zIndex = Math.max(...nodes.map((node) => (node[internalsSymbol]?.z || 1) + 1));
3538
3485
  const wrapperStyle = {
3539
3486
  position: 'absolute',
@@ -3544,4 +3491,4 @@ function NodeToolbar({ nodeId, children, className, style, isVisible, position =
3544
3491
  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 }) }));
3545
3492
  }
3546
3493
 
3547
- export { Background$1 as Background, BackgroundVariant, BaseEdge, BezierEdge, ControlButton, Controls$1 as Controls, EdgeLabelRenderer, EdgeText$1 as EdgeText, Handle$1 as Handle, MiniMap$1 as MiniMap, ResizeControl$1 as NodeResizeControl, NodeResizer, NodeToolbar, Panel, ReactFlow, ReactFlowProvider, ResizeControlVariant, 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 };
3494
+ export { Background, BackgroundVariant, BaseEdge, BezierEdge, ControlButton, Controls, EdgeLabelRenderer, EdgeText, Handle, MiniMap, NodeResizeControl, NodeResizer, NodeToolbar, Panel, index as 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 };