@xyflow/react 12.0.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (464) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -0
  3. package/dist/base.css +364 -0
  4. package/dist/esm/additional-components/Background/Background.d.ts +9 -0
  5. package/dist/esm/additional-components/Background/Background.d.ts.map +1 -0
  6. package/dist/esm/additional-components/Background/Patterns.d.ts +15 -0
  7. package/dist/esm/additional-components/Background/Patterns.d.ts.map +1 -0
  8. package/dist/esm/additional-components/Background/index.d.ts +3 -0
  9. package/dist/esm/additional-components/Background/index.d.ts.map +1 -0
  10. package/dist/esm/additional-components/Background/types.d.ts +20 -0
  11. package/dist/esm/additional-components/Background/types.d.ts.map +1 -0
  12. package/dist/esm/additional-components/Controls/ControlButton.d.ts +5 -0
  13. package/dist/esm/additional-components/Controls/ControlButton.d.ts.map +1 -0
  14. package/dist/esm/additional-components/Controls/Controls.d.ts +5 -0
  15. package/dist/esm/additional-components/Controls/Controls.d.ts.map +1 -0
  16. package/dist/esm/additional-components/Controls/Icons/FitView.d.ts +3 -0
  17. package/dist/esm/additional-components/Controls/Icons/FitView.d.ts.map +1 -0
  18. package/dist/esm/additional-components/Controls/Icons/Lock.d.ts +3 -0
  19. package/dist/esm/additional-components/Controls/Icons/Lock.d.ts.map +1 -0
  20. package/dist/esm/additional-components/Controls/Icons/Minus.d.ts +3 -0
  21. package/dist/esm/additional-components/Controls/Icons/Minus.d.ts.map +1 -0
  22. package/dist/esm/additional-components/Controls/Icons/Plus.d.ts +3 -0
  23. package/dist/esm/additional-components/Controls/Icons/Plus.d.ts.map +1 -0
  24. package/dist/esm/additional-components/Controls/Icons/Unlock.d.ts +3 -0
  25. package/dist/esm/additional-components/Controls/Icons/Unlock.d.ts.map +1 -0
  26. package/dist/esm/additional-components/Controls/index.d.ts +4 -0
  27. package/dist/esm/additional-components/Controls/index.d.ts.map +1 -0
  28. package/dist/esm/additional-components/Controls/types.d.ts +16 -0
  29. package/dist/esm/additional-components/Controls/types.d.ts.map +1 -0
  30. package/dist/esm/additional-components/MiniMap/MiniMap.d.ts +9 -0
  31. package/dist/esm/additional-components/MiniMap/MiniMap.d.ts.map +1 -0
  32. package/dist/esm/additional-components/MiniMap/MiniMapNode.d.ts +6 -0
  33. package/dist/esm/additional-components/MiniMap/MiniMapNode.d.ts.map +1 -0
  34. package/dist/esm/additional-components/MiniMap/MiniMapNodes.d.ts +6 -0
  35. package/dist/esm/additional-components/MiniMap/MiniMapNodes.d.ts.map +1 -0
  36. package/dist/esm/additional-components/MiniMap/index.d.ts +3 -0
  37. package/dist/esm/additional-components/MiniMap/index.d.ts.map +1 -0
  38. package/dist/esm/additional-components/MiniMap/types.d.ts +44 -0
  39. package/dist/esm/additional-components/MiniMap/types.d.ts.map +1 -0
  40. package/dist/esm/additional-components/NodeResizer/NodeResizer.d.ts +3 -0
  41. package/dist/esm/additional-components/NodeResizer/NodeResizer.d.ts.map +1 -0
  42. package/dist/esm/additional-components/NodeResizer/ResizeControl.d.ts +7 -0
  43. package/dist/esm/additional-components/NodeResizer/ResizeControl.d.ts.map +1 -0
  44. package/dist/esm/additional-components/NodeResizer/index.d.ts +4 -0
  45. package/dist/esm/additional-components/NodeResizer/index.d.ts.map +1 -0
  46. package/dist/esm/additional-components/NodeResizer/types.d.ts +53 -0
  47. package/dist/esm/additional-components/NodeResizer/types.d.ts.map +1 -0
  48. package/dist/esm/additional-components/NodeResizer/utils.d.ts +11 -0
  49. package/dist/esm/additional-components/NodeResizer/utils.d.ts.map +1 -0
  50. package/dist/esm/additional-components/NodeToolbar/NodeToolbar.d.ts +4 -0
  51. package/dist/esm/additional-components/NodeToolbar/NodeToolbar.d.ts.map +1 -0
  52. package/dist/esm/additional-components/NodeToolbar/NodeToolbarPortal.d.ts +6 -0
  53. package/dist/esm/additional-components/NodeToolbar/NodeToolbarPortal.d.ts.map +1 -0
  54. package/dist/esm/additional-components/NodeToolbar/index.d.ts +3 -0
  55. package/dist/esm/additional-components/NodeToolbar/index.d.ts.map +1 -0
  56. package/dist/esm/additional-components/NodeToolbar/types.d.ts +10 -0
  57. package/dist/esm/additional-components/NodeToolbar/types.d.ts.map +1 -0
  58. package/dist/esm/additional-components/index.d.ts +6 -0
  59. package/dist/esm/additional-components/index.d.ts.map +1 -0
  60. package/dist/esm/components/A11yDescriptions/index.d.ts +9 -0
  61. package/dist/esm/components/A11yDescriptions/index.d.ts.map +1 -0
  62. package/dist/esm/components/Attribution/index.d.ts +8 -0
  63. package/dist/esm/components/Attribution/index.d.ts.map +1 -0
  64. package/dist/esm/components/ConnectionLine/index.d.ts +12 -0
  65. package/dist/esm/components/ConnectionLine/index.d.ts.map +1 -0
  66. package/dist/esm/components/EdgeLabelRenderer/index.d.ts +6 -0
  67. package/dist/esm/components/EdgeLabelRenderer/index.d.ts.map +1 -0
  68. package/dist/esm/components/EdgeWrapper/EdgeUpdateAnchors.d.ts +17 -0
  69. package/dist/esm/components/EdgeWrapper/EdgeUpdateAnchors.d.ts.map +1 -0
  70. package/dist/esm/components/EdgeWrapper/index.d.ts +9 -0
  71. package/dist/esm/components/EdgeWrapper/index.d.ts.map +1 -0
  72. package/dist/esm/components/EdgeWrapper/utils.d.ts +11 -0
  73. package/dist/esm/components/EdgeWrapper/utils.d.ts.map +1 -0
  74. package/dist/esm/components/Edges/BaseEdge.d.ts +7 -0
  75. package/dist/esm/components/Edges/BaseEdge.d.ts.map +1 -0
  76. package/dist/esm/components/Edges/BezierEdge.d.ts +6 -0
  77. package/dist/esm/components/Edges/BezierEdge.d.ts.map +1 -0
  78. package/dist/esm/components/Edges/EdgeAnchor.d.ts +14 -0
  79. package/dist/esm/components/Edges/EdgeAnchor.d.ts.map +1 -0
  80. package/dist/esm/components/Edges/EdgeText.d.ts +5 -0
  81. package/dist/esm/components/Edges/EdgeText.d.ts.map +1 -0
  82. package/dist/esm/components/Edges/SimpleBezierEdge.d.ts +16 -0
  83. package/dist/esm/components/Edges/SimpleBezierEdge.d.ts.map +1 -0
  84. package/dist/esm/components/Edges/SmoothStepEdge.d.ts +6 -0
  85. package/dist/esm/components/Edges/SmoothStepEdge.d.ts.map +1 -0
  86. package/dist/esm/components/Edges/StepEdge.d.ts +6 -0
  87. package/dist/esm/components/Edges/StepEdge.d.ts.map +1 -0
  88. package/dist/esm/components/Edges/StraightEdge.d.ts +6 -0
  89. package/dist/esm/components/Edges/StraightEdge.d.ts.map +1 -0
  90. package/dist/esm/components/Edges/index.d.ts +6 -0
  91. package/dist/esm/components/Edges/index.d.ts.map +1 -0
  92. package/dist/esm/components/Handle/index.d.ts +6 -0
  93. package/dist/esm/components/Handle/index.d.ts.map +1 -0
  94. package/dist/esm/components/NodeWrapper/index.d.ts +8 -0
  95. package/dist/esm/components/NodeWrapper/index.d.ts.map +1 -0
  96. package/dist/esm/components/NodeWrapper/utils.d.ts +5 -0
  97. package/dist/esm/components/NodeWrapper/utils.d.ts.map +1 -0
  98. package/dist/esm/components/Nodes/DefaultNode.d.ts +8 -0
  99. package/dist/esm/components/Nodes/DefaultNode.d.ts.map +1 -0
  100. package/dist/esm/components/Nodes/GroupNode.d.ts +6 -0
  101. package/dist/esm/components/Nodes/GroupNode.d.ts.map +1 -0
  102. package/dist/esm/components/Nodes/InputNode.d.ts +8 -0
  103. package/dist/esm/components/Nodes/InputNode.d.ts.map +1 -0
  104. package/dist/esm/components/Nodes/OutputNode.d.ts +8 -0
  105. package/dist/esm/components/Nodes/OutputNode.d.ts.map +1 -0
  106. package/dist/esm/components/Nodes/utils.d.ts +13 -0
  107. package/dist/esm/components/Nodes/utils.d.ts.map +1 -0
  108. package/dist/esm/components/NodesSelection/index.d.ts +15 -0
  109. package/dist/esm/components/NodesSelection/index.d.ts.map +1 -0
  110. package/dist/esm/components/Panel/index.d.ts +9 -0
  111. package/dist/esm/components/Panel/index.d.ts.map +1 -0
  112. package/dist/esm/components/ReactFlowProvider/index.d.ts +15 -0
  113. package/dist/esm/components/ReactFlowProvider/index.d.ts.map +1 -0
  114. package/dist/esm/components/SelectionListener/index.d.ts +7 -0
  115. package/dist/esm/components/SelectionListener/index.d.ts.map +1 -0
  116. package/dist/esm/components/StoreUpdater/index.d.ts +9 -0
  117. package/dist/esm/components/StoreUpdater/index.d.ts.map +1 -0
  118. package/dist/esm/components/UserSelection/index.d.ts +3 -0
  119. package/dist/esm/components/UserSelection/index.d.ts.map +1 -0
  120. package/dist/esm/components/ViewportPortal/index.d.ts +6 -0
  121. package/dist/esm/components/ViewportPortal/index.d.ts.map +1 -0
  122. package/dist/esm/container/EdgeRenderer/MarkerDefinitions.d.ts +11 -0
  123. package/dist/esm/container/EdgeRenderer/MarkerDefinitions.d.ts.map +1 -0
  124. package/dist/esm/container/EdgeRenderer/MarkerSymbols.d.ts +9 -0
  125. package/dist/esm/container/EdgeRenderer/MarkerSymbols.d.ts.map +1 -0
  126. package/dist/esm/container/EdgeRenderer/index.d.ts +11 -0
  127. package/dist/esm/container/EdgeRenderer/index.d.ts.map +1 -0
  128. package/dist/esm/container/FlowRenderer/index.d.ts +12 -0
  129. package/dist/esm/container/FlowRenderer/index.d.ts.map +1 -0
  130. package/dist/esm/container/GraphView/index.d.ts +11 -0
  131. package/dist/esm/container/GraphView/index.d.ts.map +1 -0
  132. package/dist/esm/container/GraphView/useNodeOrEdgeTypesWarning.d.ts +5 -0
  133. package/dist/esm/container/GraphView/useNodeOrEdgeTypesWarning.d.ts.map +1 -0
  134. package/dist/esm/container/NodeRenderer/index.d.ts +9 -0
  135. package/dist/esm/container/NodeRenderer/index.d.ts.map +1 -0
  136. package/dist/esm/container/NodeRenderer/useResizeObserver.d.ts +2 -0
  137. package/dist/esm/container/NodeRenderer/useResizeObserver.d.ts.map +1 -0
  138. package/dist/esm/container/Pane/index.d.ts +12 -0
  139. package/dist/esm/container/Pane/index.d.ts.map +1 -0
  140. package/dist/esm/container/ReactFlow/Wrapper.d.ts +15 -0
  141. package/dist/esm/container/ReactFlow/Wrapper.d.ts.map +1 -0
  142. package/dist/esm/container/ReactFlow/index.d.ts +120 -0
  143. package/dist/esm/container/ReactFlow/index.d.ts.map +1 -0
  144. package/dist/esm/container/Viewport/index.d.ts +7 -0
  145. package/dist/esm/container/Viewport/index.d.ts.map +1 -0
  146. package/dist/esm/container/ZoomPane/index.d.ts +7 -0
  147. package/dist/esm/container/ZoomPane/index.d.ts.map +1 -0
  148. package/dist/esm/contexts/NodeIdContext.d.ts +7 -0
  149. package/dist/esm/contexts/NodeIdContext.d.ts.map +1 -0
  150. package/dist/esm/contexts/RFStoreContext.d.ts +5 -0
  151. package/dist/esm/contexts/RFStoreContext.d.ts.map +1 -0
  152. package/dist/esm/hooks/useColorModeClass.d.ts +9 -0
  153. package/dist/esm/hooks/useColorModeClass.d.ts.map +1 -0
  154. package/dist/esm/hooks/useConnection.d.ts +14 -0
  155. package/dist/esm/hooks/useConnection.d.ts.map +1 -0
  156. package/dist/esm/hooks/useDrag.d.ts +17 -0
  157. package/dist/esm/hooks/useDrag.d.ts.map +1 -0
  158. package/dist/esm/hooks/useEdges.d.ts +10 -0
  159. package/dist/esm/hooks/useEdges.d.ts.map +1 -0
  160. package/dist/esm/hooks/useGlobalKeyHandler.d.ts +12 -0
  161. package/dist/esm/hooks/useGlobalKeyHandler.d.ts.map +1 -0
  162. package/dist/esm/hooks/useHandleConnections.d.ts +22 -0
  163. package/dist/esm/hooks/useHandleConnections.d.ts.map +1 -0
  164. package/dist/esm/hooks/useKeyPress.d.ts +16 -0
  165. package/dist/esm/hooks/useKeyPress.d.ts.map +1 -0
  166. package/dist/esm/hooks/useNodes.d.ts +10 -0
  167. package/dist/esm/hooks/useNodes.d.ts.map +1 -0
  168. package/dist/esm/hooks/useNodesData.d.ts +13 -0
  169. package/dist/esm/hooks/useNodesData.d.ts.map +1 -0
  170. package/dist/esm/hooks/useNodesEdgesState.d.ts +19 -0
  171. package/dist/esm/hooks/useNodesEdgesState.d.ts.map +1 -0
  172. package/dist/esm/hooks/useNodesInitialized.d.ts +13 -0
  173. package/dist/esm/hooks/useNodesInitialized.d.ts.map +1 -0
  174. package/dist/esm/hooks/useOnInitHandler.d.ts +9 -0
  175. package/dist/esm/hooks/useOnInitHandler.d.ts.map +1 -0
  176. package/dist/esm/hooks/useOnSelectionChange.d.ts +13 -0
  177. package/dist/esm/hooks/useOnSelectionChange.d.ts.map +1 -0
  178. package/dist/esm/hooks/useOnViewportChange.d.ts +17 -0
  179. package/dist/esm/hooks/useOnViewportChange.d.ts.map +1 -0
  180. package/dist/esm/hooks/useReactFlow.d.ts +9 -0
  181. package/dist/esm/hooks/useReactFlow.d.ts.map +1 -0
  182. package/dist/esm/hooks/useResizeHandler.d.ts +9 -0
  183. package/dist/esm/hooks/useResizeHandler.d.ts.map +1 -0
  184. package/dist/esm/hooks/useStore.d.ts +22 -0
  185. package/dist/esm/hooks/useStore.d.ts.map +1 -0
  186. package/dist/esm/hooks/useUpdateNodeInternals.d.ts +10 -0
  187. package/dist/esm/hooks/useUpdateNodeInternals.d.ts.map +1 -0
  188. package/dist/esm/hooks/useUpdateNodePositions.d.ts +13 -0
  189. package/dist/esm/hooks/useUpdateNodePositions.d.ts.map +1 -0
  190. package/dist/esm/hooks/useViewport.d.ts +10 -0
  191. package/dist/esm/hooks/useViewport.d.ts.map +1 -0
  192. package/dist/esm/hooks/useViewportHelper.d.ts +10 -0
  193. package/dist/esm/hooks/useViewportHelper.d.ts.map +1 -0
  194. package/dist/esm/hooks/useViewportSync.d.ts +9 -0
  195. package/dist/esm/hooks/useViewportSync.d.ts.map +1 -0
  196. package/dist/esm/hooks/useVisibleEdgeIds.d.ts +10 -0
  197. package/dist/esm/hooks/useVisibleEdgeIds.d.ts.map +1 -0
  198. package/dist/esm/hooks/useVisibleNodeIds.d.ts +10 -0
  199. package/dist/esm/hooks/useVisibleNodeIds.d.ts.map +1 -0
  200. package/dist/esm/index.d.ts +35 -0
  201. package/dist/esm/index.d.ts.map +1 -0
  202. package/dist/esm/index.js +3547 -0
  203. package/dist/esm/index.mjs +3547 -0
  204. package/dist/esm/store/index.d.ts +10 -0
  205. package/dist/esm/store/index.d.ts.map +1 -0
  206. package/dist/esm/store/initialState.d.ts +10 -0
  207. package/dist/esm/store/initialState.d.ts.map +1 -0
  208. package/dist/esm/store/utils.d.ts +12 -0
  209. package/dist/esm/store/utils.d.ts.map +1 -0
  210. package/dist/esm/styles/utils.d.ts +3 -0
  211. package/dist/esm/styles/utils.d.ts.map +1 -0
  212. package/dist/esm/types/changes.d.ts +50 -0
  213. package/dist/esm/types/changes.d.ts.map +1 -0
  214. package/dist/esm/types/component-props.d.ts +124 -0
  215. package/dist/esm/types/component-props.d.ts.map +1 -0
  216. package/dist/esm/types/edges.d.ts +148 -0
  217. package/dist/esm/types/edges.d.ts.map +1 -0
  218. package/dist/esm/types/general.d.ts +45 -0
  219. package/dist/esm/types/general.d.ts.map +1 -0
  220. package/dist/esm/types/index.d.ts +8 -0
  221. package/dist/esm/types/index.d.ts.map +1 -0
  222. package/dist/esm/types/instance.d.ts +70 -0
  223. package/dist/esm/types/instance.d.ts.map +1 -0
  224. package/dist/esm/types/nodes.d.ts +39 -0
  225. package/dist/esm/types/nodes.d.ts.map +1 -0
  226. package/dist/esm/types/store.d.ts +105 -0
  227. package/dist/esm/types/store.d.ts.map +1 -0
  228. package/dist/esm/utils/changes.d.ts +47 -0
  229. package/dist/esm/utils/changes.d.ts.map +1 -0
  230. package/dist/esm/utils/general.d.ts +65 -0
  231. package/dist/esm/utils/general.d.ts.map +1 -0
  232. package/dist/esm/utils/index.d.ts +3 -0
  233. package/dist/esm/utils/index.d.ts.map +1 -0
  234. package/dist/style.css +560 -0
  235. package/dist/umd/additional-components/Background/Background.d.ts +9 -0
  236. package/dist/umd/additional-components/Background/Background.d.ts.map +1 -0
  237. package/dist/umd/additional-components/Background/Patterns.d.ts +15 -0
  238. package/dist/umd/additional-components/Background/Patterns.d.ts.map +1 -0
  239. package/dist/umd/additional-components/Background/index.d.ts +3 -0
  240. package/dist/umd/additional-components/Background/index.d.ts.map +1 -0
  241. package/dist/umd/additional-components/Background/types.d.ts +20 -0
  242. package/dist/umd/additional-components/Background/types.d.ts.map +1 -0
  243. package/dist/umd/additional-components/Controls/ControlButton.d.ts +5 -0
  244. package/dist/umd/additional-components/Controls/ControlButton.d.ts.map +1 -0
  245. package/dist/umd/additional-components/Controls/Controls.d.ts +5 -0
  246. package/dist/umd/additional-components/Controls/Controls.d.ts.map +1 -0
  247. package/dist/umd/additional-components/Controls/Icons/FitView.d.ts +3 -0
  248. package/dist/umd/additional-components/Controls/Icons/FitView.d.ts.map +1 -0
  249. package/dist/umd/additional-components/Controls/Icons/Lock.d.ts +3 -0
  250. package/dist/umd/additional-components/Controls/Icons/Lock.d.ts.map +1 -0
  251. package/dist/umd/additional-components/Controls/Icons/Minus.d.ts +3 -0
  252. package/dist/umd/additional-components/Controls/Icons/Minus.d.ts.map +1 -0
  253. package/dist/umd/additional-components/Controls/Icons/Plus.d.ts +3 -0
  254. package/dist/umd/additional-components/Controls/Icons/Plus.d.ts.map +1 -0
  255. package/dist/umd/additional-components/Controls/Icons/Unlock.d.ts +3 -0
  256. package/dist/umd/additional-components/Controls/Icons/Unlock.d.ts.map +1 -0
  257. package/dist/umd/additional-components/Controls/index.d.ts +4 -0
  258. package/dist/umd/additional-components/Controls/index.d.ts.map +1 -0
  259. package/dist/umd/additional-components/Controls/types.d.ts +16 -0
  260. package/dist/umd/additional-components/Controls/types.d.ts.map +1 -0
  261. package/dist/umd/additional-components/MiniMap/MiniMap.d.ts +9 -0
  262. package/dist/umd/additional-components/MiniMap/MiniMap.d.ts.map +1 -0
  263. package/dist/umd/additional-components/MiniMap/MiniMapNode.d.ts +6 -0
  264. package/dist/umd/additional-components/MiniMap/MiniMapNode.d.ts.map +1 -0
  265. package/dist/umd/additional-components/MiniMap/MiniMapNodes.d.ts +6 -0
  266. package/dist/umd/additional-components/MiniMap/MiniMapNodes.d.ts.map +1 -0
  267. package/dist/umd/additional-components/MiniMap/index.d.ts +3 -0
  268. package/dist/umd/additional-components/MiniMap/index.d.ts.map +1 -0
  269. package/dist/umd/additional-components/MiniMap/types.d.ts +44 -0
  270. package/dist/umd/additional-components/MiniMap/types.d.ts.map +1 -0
  271. package/dist/umd/additional-components/NodeResizer/NodeResizer.d.ts +3 -0
  272. package/dist/umd/additional-components/NodeResizer/NodeResizer.d.ts.map +1 -0
  273. package/dist/umd/additional-components/NodeResizer/ResizeControl.d.ts +7 -0
  274. package/dist/umd/additional-components/NodeResizer/ResizeControl.d.ts.map +1 -0
  275. package/dist/umd/additional-components/NodeResizer/index.d.ts +4 -0
  276. package/dist/umd/additional-components/NodeResizer/index.d.ts.map +1 -0
  277. package/dist/umd/additional-components/NodeResizer/types.d.ts +53 -0
  278. package/dist/umd/additional-components/NodeResizer/types.d.ts.map +1 -0
  279. package/dist/umd/additional-components/NodeResizer/utils.d.ts +11 -0
  280. package/dist/umd/additional-components/NodeResizer/utils.d.ts.map +1 -0
  281. package/dist/umd/additional-components/NodeToolbar/NodeToolbar.d.ts +4 -0
  282. package/dist/umd/additional-components/NodeToolbar/NodeToolbar.d.ts.map +1 -0
  283. package/dist/umd/additional-components/NodeToolbar/NodeToolbarPortal.d.ts +6 -0
  284. package/dist/umd/additional-components/NodeToolbar/NodeToolbarPortal.d.ts.map +1 -0
  285. package/dist/umd/additional-components/NodeToolbar/index.d.ts +3 -0
  286. package/dist/umd/additional-components/NodeToolbar/index.d.ts.map +1 -0
  287. package/dist/umd/additional-components/NodeToolbar/types.d.ts +10 -0
  288. package/dist/umd/additional-components/NodeToolbar/types.d.ts.map +1 -0
  289. package/dist/umd/additional-components/index.d.ts +6 -0
  290. package/dist/umd/additional-components/index.d.ts.map +1 -0
  291. package/dist/umd/components/A11yDescriptions/index.d.ts +9 -0
  292. package/dist/umd/components/A11yDescriptions/index.d.ts.map +1 -0
  293. package/dist/umd/components/Attribution/index.d.ts +8 -0
  294. package/dist/umd/components/Attribution/index.d.ts.map +1 -0
  295. package/dist/umd/components/ConnectionLine/index.d.ts +12 -0
  296. package/dist/umd/components/ConnectionLine/index.d.ts.map +1 -0
  297. package/dist/umd/components/EdgeLabelRenderer/index.d.ts +6 -0
  298. package/dist/umd/components/EdgeLabelRenderer/index.d.ts.map +1 -0
  299. package/dist/umd/components/EdgeWrapper/EdgeUpdateAnchors.d.ts +17 -0
  300. package/dist/umd/components/EdgeWrapper/EdgeUpdateAnchors.d.ts.map +1 -0
  301. package/dist/umd/components/EdgeWrapper/index.d.ts +9 -0
  302. package/dist/umd/components/EdgeWrapper/index.d.ts.map +1 -0
  303. package/dist/umd/components/EdgeWrapper/utils.d.ts +11 -0
  304. package/dist/umd/components/EdgeWrapper/utils.d.ts.map +1 -0
  305. package/dist/umd/components/Edges/BaseEdge.d.ts +7 -0
  306. package/dist/umd/components/Edges/BaseEdge.d.ts.map +1 -0
  307. package/dist/umd/components/Edges/BezierEdge.d.ts +6 -0
  308. package/dist/umd/components/Edges/BezierEdge.d.ts.map +1 -0
  309. package/dist/umd/components/Edges/EdgeAnchor.d.ts +14 -0
  310. package/dist/umd/components/Edges/EdgeAnchor.d.ts.map +1 -0
  311. package/dist/umd/components/Edges/EdgeText.d.ts +5 -0
  312. package/dist/umd/components/Edges/EdgeText.d.ts.map +1 -0
  313. package/dist/umd/components/Edges/SimpleBezierEdge.d.ts +16 -0
  314. package/dist/umd/components/Edges/SimpleBezierEdge.d.ts.map +1 -0
  315. package/dist/umd/components/Edges/SmoothStepEdge.d.ts +6 -0
  316. package/dist/umd/components/Edges/SmoothStepEdge.d.ts.map +1 -0
  317. package/dist/umd/components/Edges/StepEdge.d.ts +6 -0
  318. package/dist/umd/components/Edges/StepEdge.d.ts.map +1 -0
  319. package/dist/umd/components/Edges/StraightEdge.d.ts +6 -0
  320. package/dist/umd/components/Edges/StraightEdge.d.ts.map +1 -0
  321. package/dist/umd/components/Edges/index.d.ts +6 -0
  322. package/dist/umd/components/Edges/index.d.ts.map +1 -0
  323. package/dist/umd/components/Handle/index.d.ts +6 -0
  324. package/dist/umd/components/Handle/index.d.ts.map +1 -0
  325. package/dist/umd/components/NodeWrapper/index.d.ts +8 -0
  326. package/dist/umd/components/NodeWrapper/index.d.ts.map +1 -0
  327. package/dist/umd/components/NodeWrapper/utils.d.ts +5 -0
  328. package/dist/umd/components/NodeWrapper/utils.d.ts.map +1 -0
  329. package/dist/umd/components/Nodes/DefaultNode.d.ts +8 -0
  330. package/dist/umd/components/Nodes/DefaultNode.d.ts.map +1 -0
  331. package/dist/umd/components/Nodes/GroupNode.d.ts +6 -0
  332. package/dist/umd/components/Nodes/GroupNode.d.ts.map +1 -0
  333. package/dist/umd/components/Nodes/InputNode.d.ts +8 -0
  334. package/dist/umd/components/Nodes/InputNode.d.ts.map +1 -0
  335. package/dist/umd/components/Nodes/OutputNode.d.ts +8 -0
  336. package/dist/umd/components/Nodes/OutputNode.d.ts.map +1 -0
  337. package/dist/umd/components/Nodes/utils.d.ts +13 -0
  338. package/dist/umd/components/Nodes/utils.d.ts.map +1 -0
  339. package/dist/umd/components/NodesSelection/index.d.ts +15 -0
  340. package/dist/umd/components/NodesSelection/index.d.ts.map +1 -0
  341. package/dist/umd/components/Panel/index.d.ts +9 -0
  342. package/dist/umd/components/Panel/index.d.ts.map +1 -0
  343. package/dist/umd/components/ReactFlowProvider/index.d.ts +15 -0
  344. package/dist/umd/components/ReactFlowProvider/index.d.ts.map +1 -0
  345. package/dist/umd/components/SelectionListener/index.d.ts +7 -0
  346. package/dist/umd/components/SelectionListener/index.d.ts.map +1 -0
  347. package/dist/umd/components/StoreUpdater/index.d.ts +9 -0
  348. package/dist/umd/components/StoreUpdater/index.d.ts.map +1 -0
  349. package/dist/umd/components/UserSelection/index.d.ts +3 -0
  350. package/dist/umd/components/UserSelection/index.d.ts.map +1 -0
  351. package/dist/umd/components/ViewportPortal/index.d.ts +6 -0
  352. package/dist/umd/components/ViewportPortal/index.d.ts.map +1 -0
  353. package/dist/umd/container/EdgeRenderer/MarkerDefinitions.d.ts +11 -0
  354. package/dist/umd/container/EdgeRenderer/MarkerDefinitions.d.ts.map +1 -0
  355. package/dist/umd/container/EdgeRenderer/MarkerSymbols.d.ts +9 -0
  356. package/dist/umd/container/EdgeRenderer/MarkerSymbols.d.ts.map +1 -0
  357. package/dist/umd/container/EdgeRenderer/index.d.ts +11 -0
  358. package/dist/umd/container/EdgeRenderer/index.d.ts.map +1 -0
  359. package/dist/umd/container/FlowRenderer/index.d.ts +12 -0
  360. package/dist/umd/container/FlowRenderer/index.d.ts.map +1 -0
  361. package/dist/umd/container/GraphView/index.d.ts +11 -0
  362. package/dist/umd/container/GraphView/index.d.ts.map +1 -0
  363. package/dist/umd/container/GraphView/useNodeOrEdgeTypesWarning.d.ts +5 -0
  364. package/dist/umd/container/GraphView/useNodeOrEdgeTypesWarning.d.ts.map +1 -0
  365. package/dist/umd/container/NodeRenderer/index.d.ts +9 -0
  366. package/dist/umd/container/NodeRenderer/index.d.ts.map +1 -0
  367. package/dist/umd/container/NodeRenderer/useResizeObserver.d.ts +2 -0
  368. package/dist/umd/container/NodeRenderer/useResizeObserver.d.ts.map +1 -0
  369. package/dist/umd/container/Pane/index.d.ts +12 -0
  370. package/dist/umd/container/Pane/index.d.ts.map +1 -0
  371. package/dist/umd/container/ReactFlow/Wrapper.d.ts +15 -0
  372. package/dist/umd/container/ReactFlow/Wrapper.d.ts.map +1 -0
  373. package/dist/umd/container/ReactFlow/index.d.ts +120 -0
  374. package/dist/umd/container/ReactFlow/index.d.ts.map +1 -0
  375. package/dist/umd/container/Viewport/index.d.ts +7 -0
  376. package/dist/umd/container/Viewport/index.d.ts.map +1 -0
  377. package/dist/umd/container/ZoomPane/index.d.ts +7 -0
  378. package/dist/umd/container/ZoomPane/index.d.ts.map +1 -0
  379. package/dist/umd/contexts/NodeIdContext.d.ts +7 -0
  380. package/dist/umd/contexts/NodeIdContext.d.ts.map +1 -0
  381. package/dist/umd/contexts/RFStoreContext.d.ts +5 -0
  382. package/dist/umd/contexts/RFStoreContext.d.ts.map +1 -0
  383. package/dist/umd/hooks/useColorModeClass.d.ts +9 -0
  384. package/dist/umd/hooks/useColorModeClass.d.ts.map +1 -0
  385. package/dist/umd/hooks/useConnection.d.ts +14 -0
  386. package/dist/umd/hooks/useConnection.d.ts.map +1 -0
  387. package/dist/umd/hooks/useDrag.d.ts +17 -0
  388. package/dist/umd/hooks/useDrag.d.ts.map +1 -0
  389. package/dist/umd/hooks/useEdges.d.ts +10 -0
  390. package/dist/umd/hooks/useEdges.d.ts.map +1 -0
  391. package/dist/umd/hooks/useGlobalKeyHandler.d.ts +12 -0
  392. package/dist/umd/hooks/useGlobalKeyHandler.d.ts.map +1 -0
  393. package/dist/umd/hooks/useHandleConnections.d.ts +22 -0
  394. package/dist/umd/hooks/useHandleConnections.d.ts.map +1 -0
  395. package/dist/umd/hooks/useKeyPress.d.ts +16 -0
  396. package/dist/umd/hooks/useKeyPress.d.ts.map +1 -0
  397. package/dist/umd/hooks/useNodes.d.ts +10 -0
  398. package/dist/umd/hooks/useNodes.d.ts.map +1 -0
  399. package/dist/umd/hooks/useNodesData.d.ts +13 -0
  400. package/dist/umd/hooks/useNodesData.d.ts.map +1 -0
  401. package/dist/umd/hooks/useNodesEdgesState.d.ts +19 -0
  402. package/dist/umd/hooks/useNodesEdgesState.d.ts.map +1 -0
  403. package/dist/umd/hooks/useNodesInitialized.d.ts +13 -0
  404. package/dist/umd/hooks/useNodesInitialized.d.ts.map +1 -0
  405. package/dist/umd/hooks/useOnInitHandler.d.ts +9 -0
  406. package/dist/umd/hooks/useOnInitHandler.d.ts.map +1 -0
  407. package/dist/umd/hooks/useOnSelectionChange.d.ts +13 -0
  408. package/dist/umd/hooks/useOnSelectionChange.d.ts.map +1 -0
  409. package/dist/umd/hooks/useOnViewportChange.d.ts +17 -0
  410. package/dist/umd/hooks/useOnViewportChange.d.ts.map +1 -0
  411. package/dist/umd/hooks/useReactFlow.d.ts +9 -0
  412. package/dist/umd/hooks/useReactFlow.d.ts.map +1 -0
  413. package/dist/umd/hooks/useResizeHandler.d.ts +9 -0
  414. package/dist/umd/hooks/useResizeHandler.d.ts.map +1 -0
  415. package/dist/umd/hooks/useStore.d.ts +22 -0
  416. package/dist/umd/hooks/useStore.d.ts.map +1 -0
  417. package/dist/umd/hooks/useUpdateNodeInternals.d.ts +10 -0
  418. package/dist/umd/hooks/useUpdateNodeInternals.d.ts.map +1 -0
  419. package/dist/umd/hooks/useUpdateNodePositions.d.ts +13 -0
  420. package/dist/umd/hooks/useUpdateNodePositions.d.ts.map +1 -0
  421. package/dist/umd/hooks/useViewport.d.ts +10 -0
  422. package/dist/umd/hooks/useViewport.d.ts.map +1 -0
  423. package/dist/umd/hooks/useViewportHelper.d.ts +10 -0
  424. package/dist/umd/hooks/useViewportHelper.d.ts.map +1 -0
  425. package/dist/umd/hooks/useViewportSync.d.ts +9 -0
  426. package/dist/umd/hooks/useViewportSync.d.ts.map +1 -0
  427. package/dist/umd/hooks/useVisibleEdgeIds.d.ts +10 -0
  428. package/dist/umd/hooks/useVisibleEdgeIds.d.ts.map +1 -0
  429. package/dist/umd/hooks/useVisibleNodeIds.d.ts +10 -0
  430. package/dist/umd/hooks/useVisibleNodeIds.d.ts.map +1 -0
  431. package/dist/umd/index.d.ts +35 -0
  432. package/dist/umd/index.d.ts.map +1 -0
  433. package/dist/umd/index.js +10 -0
  434. package/dist/umd/store/index.d.ts +10 -0
  435. package/dist/umd/store/index.d.ts.map +1 -0
  436. package/dist/umd/store/initialState.d.ts +10 -0
  437. package/dist/umd/store/initialState.d.ts.map +1 -0
  438. package/dist/umd/store/utils.d.ts +12 -0
  439. package/dist/umd/store/utils.d.ts.map +1 -0
  440. package/dist/umd/styles/utils.d.ts +3 -0
  441. package/dist/umd/styles/utils.d.ts.map +1 -0
  442. package/dist/umd/types/changes.d.ts +50 -0
  443. package/dist/umd/types/changes.d.ts.map +1 -0
  444. package/dist/umd/types/component-props.d.ts +124 -0
  445. package/dist/umd/types/component-props.d.ts.map +1 -0
  446. package/dist/umd/types/edges.d.ts +148 -0
  447. package/dist/umd/types/edges.d.ts.map +1 -0
  448. package/dist/umd/types/general.d.ts +45 -0
  449. package/dist/umd/types/general.d.ts.map +1 -0
  450. package/dist/umd/types/index.d.ts +8 -0
  451. package/dist/umd/types/index.d.ts.map +1 -0
  452. package/dist/umd/types/instance.d.ts +70 -0
  453. package/dist/umd/types/instance.d.ts.map +1 -0
  454. package/dist/umd/types/nodes.d.ts +39 -0
  455. package/dist/umd/types/nodes.d.ts.map +1 -0
  456. package/dist/umd/types/store.d.ts +105 -0
  457. package/dist/umd/types/store.d.ts.map +1 -0
  458. package/dist/umd/utils/changes.d.ts +47 -0
  459. package/dist/umd/utils/changes.d.ts.map +1 -0
  460. package/dist/umd/utils/general.d.ts +65 -0
  461. package/dist/umd/utils/general.d.ts.map +1 -0
  462. package/dist/umd/utils/index.d.ts +3 -0
  463. package/dist/umd/utils/index.d.ts.map +1 -0
  464. package/package.json +92 -0
@@ -0,0 +1,3547 @@
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';
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';
7
+ import { useStoreWithEqualityFn, createWithEqualityFn } from 'zustand/traditional';
8
+ import { shallow } from 'zustand/shallow';
9
+ import { createPortal } from 'react-dom';
10
+ import { drag } from 'd3-drag';
11
+ import { select } from 'd3-selection';
12
+
13
+ const StoreContext = createContext(null);
14
+ const Provider$1 = StoreContext.Provider;
15
+
16
+ const zustandErrorMessage = errorMessages['error001']();
17
+ /**
18
+ * Hook for accessing the internal store. Should only be used in rare cases.
19
+ *
20
+ * @public
21
+ * @param selector
22
+ * @param equalityFn
23
+ * @returns The selected state slice
24
+ */
25
+ function useStore(selector, equalityFn) {
26
+ const store = useContext(StoreContext);
27
+ if (store === null) {
28
+ throw new Error(zustandErrorMessage);
29
+ }
30
+ return useStoreWithEqualityFn(store, selector, equalityFn);
31
+ }
32
+ const useStoreApi = () => {
33
+ const store = useContext(StoreContext);
34
+ if (store === null) {
35
+ throw new Error(zustandErrorMessage);
36
+ }
37
+ return useMemo(() => ({
38
+ getState: store.getState,
39
+ setState: store.setState,
40
+ subscribe: store.subscribe,
41
+ destroy: store.destroy,
42
+ }), [store]);
43
+ };
44
+
45
+ const selector$q = (s) => (s.userSelectionActive ? 'none' : 'all');
46
+ function Panel({ position, children, className, style, ...rest }) {
47
+ const pointerEvents = useStore(selector$q);
48
+ const positionClasses = `${position}`.split('-');
49
+ return (jsx("div", { className: cc(['react-flow__panel', className, ...positionClasses]), style: { ...style, pointerEvents }, ...rest, children: children }));
50
+ }
51
+
52
+ function Attribution({ proOptions, position = 'bottom-right' }) {
53
+ if (proOptions?.hideAttribution) {
54
+ return null;
55
+ }
56
+ 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
+ }
58
+
59
+ const selector$p = (s) => ({
60
+ selectedNodes: s.nodes.filter((n) => n.selected),
61
+ selectedEdges: s.edges.filter((e) => e.selected),
62
+ });
63
+ const selectId = (obj) => obj.id;
64
+ function areEqual(a, b) {
65
+ return (shallow(a.selectedNodes.map(selectId), b.selectedNodes.map(selectId)) &&
66
+ shallow(a.selectedEdges.map(selectId), b.selectedEdges.map(selectId)));
67
+ }
68
+ const SelectionListener = memo(({ onSelectionChange }) => {
69
+ const store = useStoreApi();
70
+ const { selectedNodes, selectedEdges } = useStore(selector$p, areEqual);
71
+ useEffect(() => {
72
+ const params = { nodes: selectedNodes, edges: selectedEdges };
73
+ onSelectionChange?.(params);
74
+ store.getState().onSelectionChangeHandlers.forEach((fn) => fn(params));
75
+ }, [selectedNodes, selectedEdges, onSelectionChange]);
76
+ return null;
77
+ });
78
+ SelectionListener.displayName = 'SelectionListener';
79
+ const changeSelector = (s) => !!s.onSelectionChangeHandlers;
80
+ function Wrapper$1({ onSelectionChange }) {
81
+ const storeHasSelectionChangeHandlers = useStore(changeSelector);
82
+ if (onSelectionChange || storeHasSelectionChangeHandlers) {
83
+ return jsx(SelectionListener, { onSelectionChange: onSelectionChange });
84
+ }
85
+ return null;
86
+ }
87
+
88
+ /*
89
+ * This component helps us to update the store with the vlues coming from the user.
90
+ * We distinguish between values we can update directly with `useDirectStoreUpdater` (like `snapGrid`)
91
+ * and values that have a dedicated setter function in the store (like `setNodes`).
92
+ */
93
+ // these fields exist in the global store and we need to keep them up to date
94
+ const reactFlowFieldsToTrack = [
95
+ 'nodes',
96
+ 'edges',
97
+ 'defaultNodes',
98
+ 'defaultEdges',
99
+ 'onConnect',
100
+ 'onConnectStart',
101
+ 'onConnectEnd',
102
+ 'onClickConnectStart',
103
+ 'onClickConnectEnd',
104
+ 'nodesDraggable',
105
+ 'nodesConnectable',
106
+ 'nodesFocusable',
107
+ 'edgesFocusable',
108
+ 'edgesUpdatable',
109
+ 'elevateNodesOnSelect',
110
+ 'elevateEdgesOnSelect',
111
+ 'minZoom',
112
+ 'maxZoom',
113
+ 'nodeExtent',
114
+ 'onNodesChange',
115
+ 'onEdgesChange',
116
+ 'elementsSelectable',
117
+ 'connectionMode',
118
+ 'snapGrid',
119
+ 'snapToGrid',
120
+ 'translateExtent',
121
+ 'connectOnClick',
122
+ 'defaultEdgeOptions',
123
+ 'fitView',
124
+ 'fitViewOptions',
125
+ 'onNodesDelete',
126
+ 'onEdgesDelete',
127
+ 'onDelete',
128
+ 'onNodeDrag',
129
+ 'onNodeDragStart',
130
+ 'onNodeDragStop',
131
+ 'onSelectionDrag',
132
+ 'onSelectionDragStart',
133
+ 'onSelectionDragStop',
134
+ 'onMoveStart',
135
+ 'onMove',
136
+ 'onMoveEnd',
137
+ 'noPanClassName',
138
+ 'nodeOrigin',
139
+ 'autoPanOnConnect',
140
+ 'autoPanOnNodeDrag',
141
+ 'onError',
142
+ 'connectionRadius',
143
+ 'isValidConnection',
144
+ 'selectNodesOnDrag',
145
+ 'nodeDragThreshold',
146
+ 'onBeforeDelete',
147
+ ];
148
+ // rfId doesn't exist in ReactFlowProps, but it's one of the fields we want to update
149
+ const fieldsToTrack = [...reactFlowFieldsToTrack, 'rfId'];
150
+ const selector$o = (s) => ({
151
+ setNodes: s.setNodes,
152
+ setEdges: s.setEdges,
153
+ setDefaultNodesAndEdges: s.setDefaultNodesAndEdges,
154
+ setMinZoom: s.setMinZoom,
155
+ setMaxZoom: s.setMaxZoom,
156
+ setTranslateExtent: s.setTranslateExtent,
157
+ setNodeExtent: s.setNodeExtent,
158
+ reset: s.reset,
159
+ });
160
+ const StoreUpdater = (props) => {
161
+ const { setNodes, setEdges, setDefaultNodesAndEdges, setMinZoom, setMaxZoom, setTranslateExtent, setNodeExtent, reset, } = useStore(selector$o, shallow);
162
+ const store = useStoreApi();
163
+ useEffect(() => {
164
+ const edgesWithDefaults = props.defaultEdges?.map((e) => ({ ...e, ...props.defaultEdgeOptions }));
165
+ setDefaultNodesAndEdges(props.defaultNodes, edgesWithDefaults);
166
+ return () => {
167
+ reset();
168
+ };
169
+ }, []);
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
+ });
182
+ useEffect(() => {
183
+ for (const fieldName of fieldsToTrack) {
184
+ const fieldValue = props[fieldName];
185
+ const previousFieldValue = previousFields.current[fieldName];
186
+ if (fieldValue === previousFieldValue)
187
+ continue;
188
+ if (typeof props[fieldName] === 'undefined')
189
+ continue;
190
+ // Custom handling with dedicated setters for some fields
191
+ if (fieldName === 'nodes')
192
+ setNodes(fieldValue);
193
+ else if (fieldName === 'edges')
194
+ setEdges(fieldValue);
195
+ else if (fieldName === 'minZoom')
196
+ setMinZoom(fieldValue);
197
+ else if (fieldName === 'maxZoom')
198
+ setMaxZoom(fieldValue);
199
+ else if (fieldName === 'translateExtent')
200
+ setTranslateExtent(fieldValue);
201
+ else if (fieldName === 'nodeExtent')
202
+ setNodeExtent(fieldValue);
203
+ // Renamed fields
204
+ else if (fieldName === 'fitView')
205
+ store.setState({ fitViewOnInit: fieldValue });
206
+ else if (fieldName === 'fitViewOptions')
207
+ store.setState({ fitViewOnInitOptions: fieldValue });
208
+ // General case
209
+ else
210
+ store.setState({ [fieldName]: fieldValue });
211
+ }
212
+ previousFields.current = props;
213
+ },
214
+ // Only re-run the effect if one of the fields we track changes
215
+ fieldsToTrack.map((fieldName) => props[fieldName]));
216
+ return null;
217
+ };
218
+
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 }));
238
+ }
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 })] }));
241
+ }
242
+
243
+ const defaultDoc = typeof document !== 'undefined' ? document : null;
244
+ /**
245
+ * Hook for handling key events.
246
+ *
247
+ * @public
248
+ * @param param.keyCode - The key code (string or array of strings) to use
249
+ * @param param.options - Options
250
+ * @returns boolean
251
+ */
252
+ var useKeyPress = (
253
+ // the keycode can be a string 'a' or an array of strings ['a', 'a+d']
254
+ // a string means a single key 'a' or a combination when '+' is used 'a+d'
255
+ // an array means different possibilites. Explainer: ['a', 'd+s'] here the
256
+ // user can use the single key 'a' or the combination 'd' + 's'
257
+ keyCode = null, options = { target: defaultDoc, actInsideInputWithModifier: true }) => {
258
+ const [keyPressed, setKeyPressed] = useState(false);
259
+ // we need to remember if a modifier key is pressed in order to track it
260
+ const modifierPressed = useRef(false);
261
+ // we need to remember the pressed keys in order to support combinations
262
+ const pressedKeys = useRef(new Set([]));
263
+ // keyCodes = array with single keys [['a']] or key combinations [['a', 's']]
264
+ // keysToWatch = array with all keys flattened ['a', 'd', 'ShiftLeft']
265
+ // used to check if we store event.code or event.key. When the code is in the list of keysToWatch
266
+ // we use the code otherwise the key. Explainer: When you press the left "command" key, the code is "MetaLeft"
267
+ // and the key is "Meta". We want users to be able to pass keys and codes so we assume that the key is meant when
268
+ // we can't find it in the list of keysToWatch.
269
+ const [keyCodes, keysToWatch] = useMemo(() => {
270
+ if (keyCode !== null) {
271
+ const keyCodeArr = Array.isArray(keyCode) ? keyCode : [keyCode];
272
+ const keys = keyCodeArr.filter((kc) => typeof kc === 'string').map((kc) => kc.split('+'));
273
+ const keysFlat = keys.reduce((res, item) => res.concat(...item), []);
274
+ return [keys, keysFlat];
275
+ }
276
+ return [[], []];
277
+ }, [keyCode]);
278
+ useEffect(() => {
279
+ const target = options?.target || defaultDoc;
280
+ if (keyCode !== null) {
281
+ const downHandler = (event) => {
282
+ modifierPressed.current = event.ctrlKey || event.metaKey || event.shiftKey;
283
+ const preventAction = (!modifierPressed.current || (modifierPressed.current && !options.actInsideInputWithModifier)) &&
284
+ isInputDOMNode(event);
285
+ if (preventAction) {
286
+ return false;
287
+ }
288
+ const keyOrCode = useKeyOrCode(event.code, keysToWatch);
289
+ pressedKeys.current.add(event[keyOrCode]);
290
+ if (isMatchingKey(keyCodes, pressedKeys.current, false)) {
291
+ event.preventDefault();
292
+ setKeyPressed(true);
293
+ }
294
+ };
295
+ const upHandler = (event) => {
296
+ const preventAction = (!modifierPressed.current || (modifierPressed.current && !options.actInsideInputWithModifier)) &&
297
+ isInputDOMNode(event);
298
+ if (preventAction) {
299
+ return false;
300
+ }
301
+ const keyOrCode = useKeyOrCode(event.code, keysToWatch);
302
+ if (isMatchingKey(keyCodes, pressedKeys.current, true)) {
303
+ setKeyPressed(false);
304
+ pressedKeys.current.clear();
305
+ }
306
+ else {
307
+ pressedKeys.current.delete(event[keyOrCode]);
308
+ }
309
+ modifierPressed.current = false;
310
+ };
311
+ const resetHandler = () => {
312
+ pressedKeys.current.clear();
313
+ setKeyPressed(false);
314
+ };
315
+ target?.addEventListener('keydown', downHandler);
316
+ target?.addEventListener('keyup', upHandler);
317
+ window.addEventListener('blur', resetHandler);
318
+ return () => {
319
+ target?.removeEventListener('keydown', downHandler);
320
+ target?.removeEventListener('keyup', upHandler);
321
+ window.removeEventListener('blur', resetHandler);
322
+ };
323
+ }
324
+ }, [keyCode, setKeyPressed]);
325
+ return keyPressed;
326
+ };
327
+ // utils
328
+ function isMatchingKey(keyCodes, pressedKeys, isUp) {
329
+ return (keyCodes
330
+ // we only want to compare same sizes of keyCode definitions
331
+ // and pressed keys. When the user specified 'Meta' as a key somewhere
332
+ // this would also be truthy without this filter when user presses 'Meta' + 'r'
333
+ .filter((keys) => isUp || keys.length === pressedKeys.size)
334
+ // since we want to support multiple possibilities only one of the
335
+ // combinations need to be part of the pressed keys
336
+ .some((keys) => keys.every((k) => pressedKeys.has(k))));
337
+ }
338
+ function useKeyOrCode(eventCode, keysToWatch) {
339
+ return keysToWatch.includes(eventCode) ? 'code' : 'key';
340
+ }
341
+
342
+ const selector$m = (s) => !!s.panZoom;
343
+ /**
344
+ * Hook for getting viewport helper functions.
345
+ *
346
+ * @internal
347
+ * @returns viewport helper functions
348
+ */
349
+ const useViewportHelper = () => {
350
+ const store = useStoreApi();
351
+ const panZoomInitialized = useStore(selector$m);
352
+ const viewportHelperFunctions = useMemo(() => {
353
+ return {
354
+ zoomIn: (options) => store.getState().panZoom?.scaleBy(1.2, { duration: options?.duration }),
355
+ zoomOut: (options) => store.getState().panZoom?.scaleBy(1 / 1.2, { duration: options?.duration }),
356
+ zoomTo: (zoomLevel, options) => store.getState().panZoom?.scaleTo(zoomLevel, { duration: options?.duration }),
357
+ getZoom: () => store.getState().transform[2],
358
+ setViewport: (viewport, options) => {
359
+ const { transform: [tX, tY, tZoom], panZoom, } = store.getState();
360
+ panZoom?.setViewport({
361
+ x: viewport.x ?? tX,
362
+ y: viewport.y ?? tY,
363
+ zoom: viewport.zoom ?? tZoom,
364
+ }, { duration: options?.duration });
365
+ },
366
+ getViewport: () => {
367
+ const [x, y, zoom] = store.getState().transform;
368
+ return { x, y, zoom };
369
+ },
370
+ fitView: (options) => {
371
+ const { nodes, width, height, nodeOrigin, minZoom, maxZoom, panZoom } = store.getState();
372
+ return panZoom
373
+ ? fitView({
374
+ nodes,
375
+ width,
376
+ height,
377
+ nodeOrigin,
378
+ minZoom,
379
+ maxZoom,
380
+ panZoom,
381
+ }, options)
382
+ : false;
383
+ },
384
+ setCenter: (x, y, options) => {
385
+ const { width, height, maxZoom, panZoom } = store.getState();
386
+ const nextZoom = typeof options?.zoom !== 'undefined' ? options.zoom : maxZoom;
387
+ const centerX = width / 2 - x * nextZoom;
388
+ const centerY = height / 2 - y * nextZoom;
389
+ panZoom?.setViewport({
390
+ x: centerX,
391
+ y: centerY,
392
+ zoom: nextZoom,
393
+ }, { duration: options?.duration });
394
+ },
395
+ fitBounds: (bounds, options) => {
396
+ const { width, height, minZoom, maxZoom, panZoom } = store.getState();
397
+ const viewport = getViewportForBounds(bounds, width, height, minZoom, maxZoom, options?.padding ?? 0.1);
398
+ panZoom?.setViewport(viewport, { duration: options?.duration });
399
+ },
400
+ screenToFlowPosition: (position) => {
401
+ const { transform, snapToGrid, snapGrid, domNode } = store.getState();
402
+ if (!domNode) {
403
+ return position;
404
+ }
405
+ const { x: domX, y: domY } = domNode.getBoundingClientRect();
406
+ const correctedPosition = {
407
+ x: position.x - domX,
408
+ y: position.y - domY,
409
+ };
410
+ return pointToRendererPoint(correctedPosition, transform, snapToGrid, snapGrid || [1, 1]);
411
+ },
412
+ flowToScreenPosition: (position) => {
413
+ const { transform, domNode } = store.getState();
414
+ if (!domNode) {
415
+ return position;
416
+ }
417
+ const { x: domX, y: domY } = domNode.getBoundingClientRect();
418
+ const rendererPosition = rendererPointToPoint(position, transform);
419
+ return {
420
+ x: rendererPosition.x + domX,
421
+ y: rendererPosition.y + domY,
422
+ };
423
+ },
424
+ viewportInitialized: panZoomInitialized,
425
+ };
426
+ }, [panZoomInitialized]);
427
+ return viewportHelperFunctions;
428
+ };
429
+
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;
459
+ }
460
+ parent.computed.width = parent.style.width;
461
+ parent.computed.height = parent.style.height;
462
+ }
463
+ }
464
+ }
465
+ // This function applies changes to nodes or edges that are triggered by React Flow internally.
466
+ // When you drag a node for example, React Flow will send a position change update.
467
+ // This function then applies the changes and returns the updated elements.
468
+ 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
+ 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);
484
+ }
485
+ else {
486
+ _remainingChanges.push(c);
487
+ }
488
+ }
489
+ remainingChanges = _remainingChanges;
490
+ if (nextChanges.length === 0) {
491
+ updatedElements.push(item);
492
+ continue;
493
+ }
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
+ }
542
+ }
543
+ }
544
+ updatedElements.push(updateItem);
545
+ }
546
+ }
547
+ return updatedElements;
548
+ }
549
+ /**
550
+ * Drop in function that applies node changes to an array of nodes.
551
+ * @public
552
+ * @remarks Various events on the <ReactFlow /> component can produce an {@link NodeChange} that describes how to update the edges of your flow in some way.
553
+ If you don't need any custom behaviour, this util can be used to take an array of these changes and apply them to your edges.
554
+ * @param changes - Array of changes to apply
555
+ * @param nodes - Array of nodes to apply the changes to
556
+ * @returns Array of updated nodes
557
+ * @example
558
+ * const onNodesChange = useCallback(
559
+ (changes) => {
560
+ setNodes((oldNodes) => applyNodeChanges(changes, oldNodes));
561
+ },
562
+ [setNodes],
563
+ );
564
+
565
+ return (
566
+ <ReactFLow nodes={nodes} edges={edges} onNodesChange={onNodesChange} />
567
+ );
568
+ */
569
+ function applyNodeChanges(changes, nodes) {
570
+ return applyChanges(changes, nodes);
571
+ }
572
+ /**
573
+ * Drop in function that applies edge changes to an array of edges.
574
+ * @public
575
+ * @remarks Various events on the <ReactFlow /> component can produce an {@link EdgeChange} that describes how to update the edges of your flow in some way.
576
+ If you don't need any custom behaviour, this util can be used to take an array of these changes and apply them to your edges.
577
+ * @param changes - Array of changes to apply
578
+ * @param edges - Array of edge to apply the changes to
579
+ * @returns Array of updated edges
580
+ * @example
581
+ * const onEdgesChange = useCallback(
582
+ (changes) => {
583
+ setEdges((oldEdges) => applyEdgeChanges(changes, oldEdges));
584
+ },
585
+ [setEdges],
586
+ );
587
+
588
+ return (
589
+ <ReactFLow nodes={nodes} edges={edges} onEdgesChange={onEdgesChange} />
590
+ );
591
+ */
592
+ function applyEdgeChanges(changes, edges) {
593
+ return applyChanges(changes, edges);
594
+ }
595
+ const createSelectionChange = (id, selected) => ({
596
+ id,
597
+ type: 'select',
598
+ selected,
599
+ });
600
+ function getSelectionChanges(items, selectedIds = new Set(), mutateItem = false) {
601
+ const changes = [];
602
+ for (const item of items) {
603
+ const willBeSelected = selectedIds.has(item.id);
604
+ // we don't want to set all items to selected=false on the first selection
605
+ if (!(item.selected === undefined && !willBeSelected) && item.selected !== willBeSelected) {
606
+ if (mutateItem) {
607
+ // this hack is needed for nodes. When the user dragged a node, it's selected.
608
+ // When another node gets dragged, we need to deselect the previous one,
609
+ // in order to have only one selected node at a time - the onNodesChange callback comes too late here :/
610
+ item.selected = willBeSelected;
611
+ }
612
+ changes.push(createSelectionChange(item.id, willBeSelected));
613
+ }
614
+ }
615
+ return changes;
616
+ }
617
+
618
+ /**
619
+ * Test whether an object is useable as a Node
620
+ * @public
621
+ * @remarks In TypeScript this is a type guard that will narrow the type of whatever you pass in to Node if it returns true
622
+ * @param element - The element to test
623
+ * @returns A boolean indicating whether the element is an Node
624
+ */
625
+ const isNode = (isNodeBase);
626
+ /**
627
+ * Test whether an object is useable as an Edge
628
+ * @public
629
+ * @remarks In TypeScript this is a type guard that will narrow the type of whatever you pass in to Edge if it returns true
630
+ * @param element - The element to test
631
+ * @returns A boolean indicating whether the element is an Edge
632
+ */
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);
677
+
678
+ /**
679
+ * Hook for accessing the ReactFlow instance.
680
+ *
681
+ * @public
682
+ * @returns ReactFlowInstance
683
+ */
684
+ function useReactFlow() {
685
+ const viewportHelper = useViewportHelper();
686
+ const store = useStoreApi();
687
+ const getNodes = useCallback(() => {
688
+ return store.getState().nodes.map((n) => ({ ...n }));
689
+ }, []);
690
+ const getNode = useCallback((id) => {
691
+ return store.getState().nodeLookup.get(id);
692
+ }, []);
693
+ const getEdges = useCallback(() => {
694
+ const { edges = [] } = store.getState();
695
+ return edges.map((e) => ({ ...e }));
696
+ }, []);
697
+ const getEdge = useCallback((id) => {
698
+ const { edges = [] } = store.getState();
699
+ return edges.find((e) => e.id === id);
700
+ }, []);
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);
706
+ }
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);
712
+ }
713
+ }, []);
714
+ 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
+ }
726
+ }, []);
727
+ 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
+ }
738
+ }, []);
739
+ 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
+ }
749
+ }, []);
750
+ const toObject = useCallback(() => {
751
+ const { nodes = [], edges = [], transform } = store.getState();
752
+ const [x, y, zoom] = transform;
753
+ return {
754
+ nodes: nodes.map((n) => ({ ...n })),
755
+ edges: edges.map((e) => ({ ...e })),
756
+ viewport: {
757
+ x,
758
+ y,
759
+ zoom,
760
+ },
761
+ };
762
+ }, []);
763
+ const deleteElements = useCallback(async ({ nodes: nodesToRemove = [], edges: edgesToRemove = [], onBeforeDelete }) => {
764
+ const { nodes, edges, hasDefaultNodes, hasDefaultEdges, onNodesDelete, onEdgesDelete, onNodesChange, onEdgesChange, onDelete, } = store.getState();
765
+ const { nodes: matchingNodes, edges: matchingEdges } = await getElementsToRemove({
766
+ nodesToRemove,
767
+ edgesToRemove,
768
+ nodes,
769
+ edges,
770
+ onBeforeDelete,
771
+ });
772
+ const hasMatchingEdges = matchingEdges.length > 0;
773
+ const hasMatchingNodes = matchingNodes.length > 0;
774
+ if (hasMatchingEdges) {
775
+ if (hasDefaultEdges) {
776
+ store.setState({
777
+ edges: edges.filter((e) => !matchingEdges.some((mE) => mE.id === e.id)),
778
+ });
779
+ }
780
+ onEdgesDelete?.(matchingEdges);
781
+ onEdgesChange?.(matchingEdges.map((edge) => ({
782
+ id: edge.id,
783
+ type: 'remove',
784
+ })));
785
+ }
786
+ if (hasMatchingNodes) {
787
+ if (hasDefaultNodes) {
788
+ store.setState({
789
+ nodes: nodes.filter((n) => !matchingNodes.some((mN) => mN.id === n.id)),
790
+ });
791
+ }
792
+ onNodesDelete?.(matchingNodes);
793
+ onNodesChange?.(matchingNodes.map((node) => ({ id: node.id, type: 'remove' })));
794
+ }
795
+ if (hasMatchingNodes || hasMatchingEdges) {
796
+ onDelete?.({ nodes: matchingNodes, edges: matchingEdges });
797
+ }
798
+ return { deletedNodes: matchingNodes, deletedEdges: matchingEdges };
799
+ }, []);
800
+ const getNodeRect = useCallback((nodeOrRect) => {
801
+ const isRect = isRectObject(nodeOrRect);
802
+ const node = isRect ? null : store.getState().nodeLookup.get(nodeOrRect.id);
803
+ const nodeRect = isRect ? nodeOrRect : nodeToRect(node);
804
+ return [nodeRect, node, isRect];
805
+ }, []);
806
+ const getIntersectingNodes = useCallback((nodeOrRect, partially = true, nodes) => {
807
+ const [nodeRect, node, isRect] = getNodeRect(nodeOrRect);
808
+ if (!nodeRect) {
809
+ return [];
810
+ }
811
+ return (nodes || store.getState().nodes).filter((n) => {
812
+ if (!isRect && (n.id === node.id || !n.computed?.positionAbsolute)) {
813
+ return false;
814
+ }
815
+ const currNodeRect = nodeToRect(n);
816
+ const overlappingArea = getOverlappingArea(currNodeRect, nodeRect);
817
+ const partiallyVisible = partially && overlappingArea > 0;
818
+ return partiallyVisible || overlappingArea >= nodeRect.width * nodeRect.height;
819
+ });
820
+ }, []);
821
+ const isNodeIntersecting = useCallback((nodeOrRect, area, partially = true) => {
822
+ const [nodeRect] = getNodeRect(nodeOrRect);
823
+ if (!nodeRect) {
824
+ return false;
825
+ }
826
+ const overlappingArea = getOverlappingArea(nodeRect, area);
827
+ const partiallyVisible = partially && overlappingArea > 0;
828
+ return partiallyVisible || overlappingArea >= nodeRect.width * nodeRect.height;
829
+ }, []);
830
+ const updateNode = useCallback((id, nodeUpdate, options = { replace: true }) => {
831
+ setNodes((prevNodes) => prevNodes.map((node) => {
832
+ if (node.id === id) {
833
+ const nextNode = typeof nodeUpdate === 'function' ? nodeUpdate(node) : nodeUpdate;
834
+ return options.replace && isNode(nextNode) ? nextNode : { ...node, ...nextNode };
835
+ }
836
+ return node;
837
+ }));
838
+ }, [setNodes]);
839
+ const updateNodeData = useCallback((id, dataUpdate, options = { replace: false }) => {
840
+ updateNode(id, (node) => {
841
+ const nextData = typeof dataUpdate === 'function' ? dataUpdate(node) : dataUpdate;
842
+ return options.replace ? { ...node, data: nextData } : { ...node, data: { ...node.data, ...nextData } };
843
+ }, options);
844
+ }, [updateNode]);
845
+ return useMemo(() => {
846
+ return {
847
+ ...viewportHelper,
848
+ getNodes,
849
+ getNode,
850
+ getEdges,
851
+ getEdge,
852
+ setNodes,
853
+ setEdges,
854
+ addNodes,
855
+ addEdges,
856
+ toObject,
857
+ deleteElements,
858
+ getIntersectingNodes,
859
+ isNodeIntersecting,
860
+ updateNode,
861
+ updateNodeData,
862
+ };
863
+ }, [
864
+ viewportHelper,
865
+ getNodes,
866
+ getNode,
867
+ getEdges,
868
+ getEdge,
869
+ setNodes,
870
+ setEdges,
871
+ addNodes,
872
+ addEdges,
873
+ toObject,
874
+ deleteElements,
875
+ getIntersectingNodes,
876
+ isNodeIntersecting,
877
+ updateNode,
878
+ updateNodeData,
879
+ ]);
880
+ }
881
+
882
+ const selected = (item) => item.selected;
883
+ const deleteKeyOptions = { actInsideInputWithModifier: false };
884
+ /**
885
+ * Hook for handling global key events.
886
+ *
887
+ * @internal
888
+ */
889
+ var useGlobalKeyHandler = ({ deleteKeyCode, multiSelectionKeyCode, }) => {
890
+ const store = useStoreApi();
891
+ const { deleteElements } = useReactFlow();
892
+ const deleteKeyPressed = useKeyPress(deleteKeyCode, deleteKeyOptions);
893
+ const multiSelectionKeyPressed = useKeyPress(multiSelectionKeyCode);
894
+ useEffect(() => {
895
+ if (deleteKeyPressed) {
896
+ const { edges, nodes, onBeforeDelete } = store.getState();
897
+ deleteElements({ nodes: nodes.filter(selected), edges: edges.filter(selected), onBeforeDelete });
898
+ store.setState({ nodesSelectionActive: false });
899
+ }
900
+ }, [deleteKeyPressed]);
901
+ useEffect(() => {
902
+ store.setState({ multiSelectionActive: multiSelectionKeyPressed });
903
+ }, [multiSelectionKeyPressed]);
904
+ };
905
+
906
+ /**
907
+ * Hook for handling resize events.
908
+ *
909
+ * @internal
910
+ */
911
+ function useResizeHandler(domNode) {
912
+ const store = useStoreApi();
913
+ useEffect(() => {
914
+ const updateDimensions = () => {
915
+ if (!domNode.current) {
916
+ return false;
917
+ }
918
+ const size = getDimensions(domNode.current);
919
+ if (size.height === 0 || size.width === 0) {
920
+ store.getState().onError?.('004', errorMessages['error004']());
921
+ }
922
+ store.setState({ width: size.width || 500, height: size.height || 500 });
923
+ };
924
+ if (domNode.current) {
925
+ updateDimensions();
926
+ window.addEventListener('resize', updateDimensions);
927
+ const resizeObserver = new ResizeObserver(() => updateDimensions());
928
+ resizeObserver.observe(domNode.current);
929
+ return () => {
930
+ window.removeEventListener('resize', updateDimensions);
931
+ if (resizeObserver && domNode.current) {
932
+ resizeObserver.unobserve(domNode.current);
933
+ }
934
+ };
935
+ }
936
+ }, []);
937
+ }
938
+
939
+ const containerStyle = {
940
+ position: 'absolute',
941
+ width: '100%',
942
+ height: '100%',
943
+ top: 0,
944
+ left: 0,
945
+ };
946
+
947
+ const selector$l = (s) => ({
948
+ userSelectionActive: s.userSelectionActive,
949
+ lib: s.lib,
950
+ });
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, }) => {
952
+ const store = useStoreApi();
953
+ const zoomPane = useRef(null);
954
+ const { userSelectionActive, lib } = useStore(selector$l, shallow);
955
+ const zoomActivationKeyPressed = useKeyPress(zoomActivationKeyCode);
956
+ const panZoom = useRef();
957
+ useResizeHandler(zoomPane);
958
+ useEffect(() => {
959
+ if (zoomPane.current) {
960
+ panZoom.current = XYPanZoom({
961
+ domNode: zoomPane.current,
962
+ minZoom,
963
+ maxZoom,
964
+ translateExtent,
965
+ viewport: defaultViewport,
966
+ onTransformChange: (transform) => {
967
+ onViewportChange?.({ x: transform[0], y: transform[1], zoom: transform[2] });
968
+ if (!isControlledViewport) {
969
+ store.setState({ transform });
970
+ }
971
+ },
972
+ onDraggingChange: (paneDragging) => store.setState({ paneDragging }),
973
+ onPanZoomStart: (event, vp) => {
974
+ const { onViewportChangeStart, onMoveStart } = store.getState();
975
+ onMoveStart?.(event, vp);
976
+ onViewportChangeStart?.(vp);
977
+ },
978
+ onPanZoom: (event, vp) => {
979
+ const { onViewportChange, onMove } = store.getState();
980
+ onMove?.(event, vp);
981
+ onViewportChange?.(vp);
982
+ },
983
+ onPanZoomEnd: (event, vp) => {
984
+ const { onViewportChangeEnd, onMoveEnd } = store.getState();
985
+ onMoveEnd?.(event, vp);
986
+ onViewportChangeEnd?.(vp);
987
+ },
988
+ });
989
+ const { x, y, zoom } = panZoom.current.getViewport();
990
+ store.setState({
991
+ panZoom: panZoom.current,
992
+ transform: [x, y, zoom],
993
+ domNode: zoomPane.current.closest('.react-flow'),
994
+ });
995
+ return () => {
996
+ panZoom.current?.destroy();
997
+ };
998
+ }
999
+ }, []);
1000
+ useEffect(() => {
1001
+ panZoom.current?.update({
1002
+ onPaneContextMenu,
1003
+ zoomOnScroll,
1004
+ zoomOnPinch,
1005
+ panOnScroll,
1006
+ panOnScrollSpeed,
1007
+ panOnScrollMode,
1008
+ zoomOnDoubleClick,
1009
+ panOnDrag,
1010
+ zoomActivationKeyPressed,
1011
+ preventScrolling,
1012
+ noPanClassName,
1013
+ userSelectionActive,
1014
+ noWheelClassName,
1015
+ lib,
1016
+ });
1017
+ }, [
1018
+ onPaneContextMenu,
1019
+ zoomOnScroll,
1020
+ zoomOnPinch,
1021
+ panOnScroll,
1022
+ panOnScrollSpeed,
1023
+ panOnScrollMode,
1024
+ zoomOnDoubleClick,
1025
+ panOnDrag,
1026
+ zoomActivationKeyPressed,
1027
+ preventScrolling,
1028
+ noPanClassName,
1029
+ userSelectionActive,
1030
+ noWheelClassName,
1031
+ lib,
1032
+ ]);
1033
+ return (jsx("div", { className: "react-flow__renderer", ref: zoomPane, style: containerStyle, children: children }));
1034
+ };
1035
+
1036
+ const selector$k = (s) => ({
1037
+ userSelectionActive: s.userSelectionActive,
1038
+ userSelectionRect: s.userSelectionRect,
1039
+ });
1040
+ function UserSelection() {
1041
+ const { userSelectionActive, userSelectionRect } = useStore(selector$k, shallow);
1042
+ const isActive = userSelectionActive && userSelectionRect;
1043
+ if (!isActive) {
1044
+ return null;
1045
+ }
1046
+ return (jsx("div", { className: "react-flow__selection react-flow__container", style: {
1047
+ width: userSelectionRect.width,
1048
+ height: userSelectionRect.height,
1049
+ transform: `translate(${userSelectionRect.x}px, ${userSelectionRect.y}px)`,
1050
+ } }));
1051
+ }
1052
+
1053
+ const wrapHandler = (handler, containerRef) => {
1054
+ return (event) => {
1055
+ if (event.target !== containerRef.current) {
1056
+ return;
1057
+ }
1058
+ handler?.(event);
1059
+ };
1060
+ };
1061
+ const selector$j = (s) => ({
1062
+ userSelectionActive: s.userSelectionActive,
1063
+ elementsSelectable: s.elementsSelectable,
1064
+ dragging: s.paneDragging,
1065
+ });
1066
+ const Pane = memo(({ isSelecting, selectionMode = SelectionMode.Full, panOnDrag, onSelectionStart, onSelectionEnd, onPaneClick, onPaneContextMenu, onPaneScroll, onPaneMouseEnter, onPaneMouseMove, onPaneMouseLeave, children, }) => {
1067
+ const container = useRef(null);
1068
+ const store = useStoreApi();
1069
+ const prevSelectedNodesCount = useRef(0);
1070
+ const prevSelectedEdgesCount = useRef(0);
1071
+ const containerBounds = useRef();
1072
+ const { userSelectionActive, elementsSelectable, dragging } = useStore(selector$j, shallow);
1073
+ const resetUserSelection = () => {
1074
+ store.setState({ userSelectionActive: false, userSelectionRect: null });
1075
+ prevSelectedNodesCount.current = 0;
1076
+ prevSelectedEdgesCount.current = 0;
1077
+ };
1078
+ const onClick = (event) => {
1079
+ onPaneClick?.(event);
1080
+ store.getState().resetSelectedElements();
1081
+ store.setState({ nodesSelectionActive: false });
1082
+ };
1083
+ const onContextMenu = (event) => {
1084
+ if (Array.isArray(panOnDrag) && panOnDrag?.includes(2)) {
1085
+ event.preventDefault();
1086
+ return;
1087
+ }
1088
+ onPaneContextMenu?.(event);
1089
+ };
1090
+ const onWheel = onPaneScroll ? (event) => onPaneScroll(event) : undefined;
1091
+ const onMouseDown = (event) => {
1092
+ const { resetSelectedElements, domNode } = store.getState();
1093
+ containerBounds.current = domNode?.getBoundingClientRect();
1094
+ if (!elementsSelectable ||
1095
+ !isSelecting ||
1096
+ event.button !== 0 ||
1097
+ event.target !== container.current ||
1098
+ !containerBounds.current) {
1099
+ return;
1100
+ }
1101
+ const { x, y } = getEventPosition(event.nativeEvent, containerBounds.current);
1102
+ resetSelectedElements();
1103
+ store.setState({
1104
+ userSelectionRect: {
1105
+ width: 0,
1106
+ height: 0,
1107
+ startX: x,
1108
+ startY: y,
1109
+ x,
1110
+ y,
1111
+ },
1112
+ });
1113
+ onSelectionStart?.(event);
1114
+ };
1115
+ const onMouseMove = (event) => {
1116
+ const { userSelectionRect, edges, transform, nodeOrigin, nodes, onNodesChange, onEdgesChange } = store.getState();
1117
+ if (!isSelecting || !containerBounds.current || !userSelectionRect) {
1118
+ return;
1119
+ }
1120
+ store.setState({ userSelectionActive: true, nodesSelectionActive: false });
1121
+ const mousePos = getEventPosition(event.nativeEvent, containerBounds.current);
1122
+ const startX = userSelectionRect.startX ?? 0;
1123
+ const startY = userSelectionRect.startY ?? 0;
1124
+ const nextUserSelectRect = {
1125
+ ...userSelectionRect,
1126
+ x: mousePos.x < startX ? mousePos.x : startX,
1127
+ y: mousePos.y < startY ? mousePos.y : startY,
1128
+ width: Math.abs(mousePos.x - startX),
1129
+ height: Math.abs(mousePos.y - startY),
1130
+ };
1131
+ const selectedNodes = getNodesInside(nodes, nextUserSelectRect, transform, selectionMode === SelectionMode.Partial, true, nodeOrigin);
1132
+ const selectedEdgeIds = new Set();
1133
+ const selectedNodeIds = new Set();
1134
+ for (const selectedNode of selectedNodes) {
1135
+ selectedNodeIds.add(selectedNode.id);
1136
+ for (const edge of edges) {
1137
+ if (edge.source === selectedNode.id || edge.target === selectedNode.id) {
1138
+ selectedEdgeIds.add(edge.id);
1139
+ }
1140
+ }
1141
+ }
1142
+ if (prevSelectedNodesCount.current !== selectedNodeIds.size) {
1143
+ prevSelectedNodesCount.current = selectedNodeIds.size;
1144
+ const changes = getSelectionChanges(nodes, selectedNodeIds, true);
1145
+ if (changes.length) {
1146
+ onNodesChange?.(changes);
1147
+ }
1148
+ }
1149
+ if (prevSelectedEdgesCount.current !== selectedEdgeIds.size) {
1150
+ prevSelectedEdgesCount.current = selectedEdgeIds.size;
1151
+ const changes = getSelectionChanges(edges, selectedEdgeIds);
1152
+ if (changes.length) {
1153
+ onEdgesChange?.(changes);
1154
+ }
1155
+ }
1156
+ store.setState({
1157
+ userSelectionRect: nextUserSelectRect,
1158
+ });
1159
+ };
1160
+ const onMouseUp = (event) => {
1161
+ if (event.button !== 0) {
1162
+ return;
1163
+ }
1164
+ const { userSelectionRect } = store.getState();
1165
+ // We only want to trigger click functions when in selection mode if
1166
+ // the user did not move the mouse.
1167
+ if (!userSelectionActive && userSelectionRect && event.target === container.current) {
1168
+ onClick?.(event);
1169
+ }
1170
+ store.setState({ nodesSelectionActive: prevSelectedNodesCount.current > 0 });
1171
+ resetUserSelection();
1172
+ onSelectionEnd?.(event);
1173
+ };
1174
+ const onMouseLeave = (event) => {
1175
+ if (userSelectionActive) {
1176
+ store.setState({ nodesSelectionActive: prevSelectedNodesCount.current > 0 });
1177
+ onSelectionEnd?.(event);
1178
+ }
1179
+ resetUserSelection();
1180
+ };
1181
+ 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';
1185
+
1186
+ // this handler is called by
1187
+ // 1. the click handler when node is not draggable or selectNodesOnDrag = false
1188
+ // or
1189
+ // 2. the on drag start handler when node is draggable and selectNodesOnDrag = true
1190
+ function handleNodeClick({ id, store, unselect = false, nodeRef, }) {
1191
+ const { addSelectedNodes, unselectNodesAndEdges, multiSelectionActive, nodeLookup, onError } = store.getState();
1192
+ const node = nodeLookup.get(id);
1193
+ if (!node) {
1194
+ onError?.('012', errorMessages['error012'](id));
1195
+ return;
1196
+ }
1197
+ store.setState({ nodesSelectionActive: false });
1198
+ if (!node.selected) {
1199
+ addSelectedNodes([id]);
1200
+ }
1201
+ else if (unselect || (node.selected && multiSelectionActive)) {
1202
+ unselectNodesAndEdges({ nodes: [node], edges: [] });
1203
+ requestAnimationFrame(() => nodeRef?.current?.blur());
1204
+ }
1205
+ }
1206
+
1207
+ /**
1208
+ * Hook for calling XYDrag helper from @xyflow/system.
1209
+ *
1210
+ * @internal
1211
+ */
1212
+ function useDrag({ nodeRef, disabled = false, noDragClassName, handleSelector, nodeId, isSelectable }) {
1213
+ const store = useStoreApi();
1214
+ const [dragging, setDragging] = useState(false);
1215
+ const xyDrag = useRef();
1216
+ 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
+ }
1236
+ }, []);
1237
+ useEffect(() => {
1238
+ if (disabled) {
1239
+ xyDrag.current?.destroy();
1240
+ }
1241
+ else {
1242
+ xyDrag.current?.update({
1243
+ noDragClassName,
1244
+ handleSelector,
1245
+ domNode: nodeRef.current,
1246
+ isSelectable,
1247
+ nodeId,
1248
+ });
1249
+ return () => {
1250
+ xyDrag.current?.destroy();
1251
+ };
1252
+ }
1253
+ }, [noDragClassName, handleSelector, disabled, isSelectable, nodeRef, nodeId]);
1254
+ return dragging;
1255
+ }
1256
+
1257
+ const selectedAndDraggable = (nodesDraggable) => (n) => n.selected && (n.draggable || (nodesDraggable && typeof n.draggable === 'undefined'));
1258
+ /**
1259
+ * Hook for updating node positions.
1260
+ *
1261
+ * @internal
1262
+ * @returns function for updating node positions
1263
+ */
1264
+ function useUpdateNodePositions() {
1265
+ const store = useStoreApi();
1266
+ const updatePositions = useCallback((params) => {
1267
+ const { nodeExtent, nodes, snapToGrid, snapGrid, nodesDraggable, onError, updateNodePositions } = store.getState();
1268
+ 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.
1271
+ const xVelo = snapToGrid ? snapGrid[0] : 5;
1272
+ 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;
1276
+ const nodeUpdates = selectedNodes.map((node) => {
1277
+ if (node.computed?.positionAbsolute) {
1278
+ let nextPosition = {
1279
+ x: node.computed?.positionAbsolute.x + xDiff,
1280
+ y: node.computed?.positionAbsolute.y + yDiff,
1281
+ };
1282
+ if (snapToGrid) {
1283
+ nextPosition = snapPosition(nextPosition, snapGrid);
1284
+ }
1285
+ const { positionAbsolute, position } = calcNextPosition(node, nextPosition, nodes, nodeExtent, undefined, onError);
1286
+ node.position = position;
1287
+ if (!node.computed) {
1288
+ node.computed = {};
1289
+ }
1290
+ node.computed.positionAbsolute = positionAbsolute;
1291
+ }
1292
+ return node;
1293
+ });
1294
+ updateNodePositions(nodeUpdates, true, false);
1295
+ }, []);
1296
+ return updatePositions;
1297
+ }
1298
+
1299
+ const NodeIdContext = createContext(null);
1300
+ const Provider = NodeIdContext.Provider;
1301
+ NodeIdContext.Consumer;
1302
+ const useNodeId = () => {
1303
+ const nodeId = useContext(NodeIdContext);
1304
+ return nodeId;
1305
+ };
1306
+
1307
+ const selector$i = (s) => ({
1308
+ connectionStartHandle: s.connectionStartHandle,
1309
+ connectOnClick: s.connectOnClick,
1310
+ noPanClassName: s.noPanClassName,
1311
+ });
1312
+ const connectingSelector = (nodeId, handleId, type) => (state) => {
1313
+ const { connectionStartHandle: startHandle, connectionEndHandle: endHandle, connectionClickStartHandle: clickHandle, } = state;
1314
+ return {
1315
+ connecting: (startHandle?.nodeId === nodeId && startHandle?.handleId === handleId && startHandle?.type === type) ||
1316
+ (endHandle?.nodeId === nodeId && endHandle?.handleId === handleId && endHandle?.type === type),
1317
+ clickConnecting: clickHandle?.nodeId === nodeId && clickHandle?.handleId === handleId && clickHandle?.type === type,
1318
+ };
1319
+ };
1320
+ const Handle = forwardRef(({ type = 'source', position = Position.Top, isValidConnection, isConnectable = true, isConnectableStart = true, isConnectableEnd = true, id, onConnect, children, className, onMouseDown, onTouchStart, ...rest }, ref) => {
1321
+ const handleId = id || null;
1322
+ const isTarget = type === 'target';
1323
+ const store = useStoreApi();
1324
+ const nodeId = useNodeId();
1325
+ const { connectOnClick, noPanClassName } = useStore(selector$i, shallow);
1326
+ const { connecting, clickConnecting } = useStore(connectingSelector(nodeId, handleId, type), shallow);
1327
+ if (!nodeId) {
1328
+ store.getState().onError?.('010', errorMessages['error010']());
1329
+ }
1330
+ const onConnectExtended = (params) => {
1331
+ const { defaultEdgeOptions, onConnect: onConnectAction, hasDefaultEdges } = store.getState();
1332
+ const edgeParams = {
1333
+ ...defaultEdgeOptions,
1334
+ ...params,
1335
+ };
1336
+ if (hasDefaultEdges) {
1337
+ const { edges, setEdges } = store.getState();
1338
+ setEdges(addEdge(edgeParams, edges));
1339
+ }
1340
+ onConnectAction?.(edgeParams);
1341
+ onConnect?.(edgeParams);
1342
+ };
1343
+ const onPointerDown = (event) => {
1344
+ if (!nodeId) {
1345
+ return;
1346
+ }
1347
+ const isMouseTriggered = isMouseEvent(event.nativeEvent);
1348
+ if (isConnectableStart &&
1349
+ ((isMouseTriggered && event.button === 0) || !isMouseTriggered)) {
1350
+ const currentStore = store.getState();
1351
+ XYHandle.onPointerDown(event.nativeEvent, {
1352
+ autoPanOnConnect: currentStore.autoPanOnConnect,
1353
+ connectionMode: currentStore.connectionMode,
1354
+ connectionRadius: currentStore.connectionRadius,
1355
+ domNode: currentStore.domNode,
1356
+ nodes: currentStore.nodes,
1357
+ lib: currentStore.lib,
1358
+ isTarget,
1359
+ handleId,
1360
+ nodeId,
1361
+ panBy: currentStore.panBy,
1362
+ cancelConnection: currentStore.cancelConnection,
1363
+ onConnectStart: currentStore.onConnectStart,
1364
+ onConnectEnd: currentStore.onConnectEnd,
1365
+ updateConnection: currentStore.updateConnection,
1366
+ onConnect: onConnectExtended,
1367
+ isValidConnection: isValidConnection || currentStore.isValidConnection,
1368
+ getTransform: () => store.getState().transform,
1369
+ });
1370
+ }
1371
+ if (isMouseTriggered) {
1372
+ onMouseDown?.(event);
1373
+ }
1374
+ else {
1375
+ onTouchStart?.(event);
1376
+ }
1377
+ };
1378
+ const onClick = (event) => {
1379
+ const { onClickConnectStart, onClickConnectEnd, connectionClickStartHandle, connectionMode, isValidConnection: isValidConnectionStore, lib, } = store.getState();
1380
+ if (!nodeId || (!connectionClickStartHandle && !isConnectableStart)) {
1381
+ return;
1382
+ }
1383
+ if (!connectionClickStartHandle) {
1384
+ onClickConnectStart?.(event.nativeEvent, { nodeId, handleId, handleType: type });
1385
+ store.setState({ connectionClickStartHandle: { nodeId, type, handleId } });
1386
+ return;
1387
+ }
1388
+ const doc = getHostForElement(event.target);
1389
+ const isValidConnectionHandler = isValidConnection || isValidConnectionStore;
1390
+ const { connection, isValid } = XYHandle.isValid(event.nativeEvent, {
1391
+ handle: {
1392
+ nodeId,
1393
+ id: handleId,
1394
+ type,
1395
+ },
1396
+ connectionMode,
1397
+ fromNodeId: connectionClickStartHandle.nodeId,
1398
+ fromHandleId: connectionClickStartHandle.handleId || null,
1399
+ fromType: connectionClickStartHandle.type,
1400
+ isValidConnection: isValidConnectionHandler,
1401
+ doc,
1402
+ lib,
1403
+ });
1404
+ if (isValid && connection) {
1405
+ onConnectExtended(connection);
1406
+ }
1407
+ onClickConnectEnd?.(event);
1408
+ store.setState({ connectionClickStartHandle: null });
1409
+ };
1410
+ return (jsx("div", { "data-handleid": handleId, "data-nodeid": nodeId, "data-handlepos": position, "data-id": `${nodeId}-${handleId}-${type}`, className: cc([
1411
+ 'react-flow__handle',
1412
+ `react-flow__handle-${position}`,
1413
+ 'nodrag',
1414
+ noPanClassName,
1415
+ className,
1416
+ {
1417
+ source: !isTarget,
1418
+ target: isTarget,
1419
+ connectable: isConnectable,
1420
+ connectablestart: isConnectableStart,
1421
+ 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)),
1425
+ },
1426
+ ]), onMouseDown: onPointerDown, onTouchStart: onPointerDown, onClick: connectOnClick ? onClick : undefined, ref: ref, ...rest, children: children }));
1427
+ });
1428
+ Handle.displayName = 'Handle';
1429
+ var Handle$1 = memo(Handle);
1430
+
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);
1434
+
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);
1440
+
1441
+ const GroupNode = () => null;
1442
+ GroupNode.displayName = 'GroupNode';
1443
+
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);
1447
+
1448
+ const arrowKeyDiffs = {
1449
+ ArrowUp: { x: 0, y: -1 },
1450
+ ArrowDown: { x: 0, y: 1 },
1451
+ ArrowLeft: { x: -1, y: 0 },
1452
+ ArrowRight: { x: 1, y: 0 },
1453
+ };
1454
+ const builtinNodeTypes = {
1455
+ input: InputNode$1,
1456
+ default: DefaultNode$1,
1457
+ output: OutputNode$1,
1458
+ group: GroupNode,
1459
+ };
1460
+
1461
+ const selector$h = (s) => {
1462
+ const selectedNodes = s.nodes.filter((n) => n.selected);
1463
+ const { width, height, x, y } = getNodesBounds(selectedNodes, s.nodeOrigin);
1464
+ return {
1465
+ width,
1466
+ height,
1467
+ userSelectionActive: s.userSelectionActive,
1468
+ transformString: `translate(${s.transform[0]}px,${s.transform[1]}px) scale(${s.transform[2]}) translate(${x}px,${y}px)`,
1469
+ };
1470
+ };
1471
+ function NodesSelection({ onSelectionContextMenu, noPanClassName, disableKeyboardA11y }) {
1472
+ const store = useStoreApi();
1473
+ const { width, height, transformString, userSelectionActive } = useStore(selector$h, shallow);
1474
+ const updatePositions = useUpdateNodePositions();
1475
+ const nodeRef = useRef(null);
1476
+ useEffect(() => {
1477
+ if (!disableKeyboardA11y) {
1478
+ nodeRef.current?.focus({
1479
+ preventScroll: true,
1480
+ });
1481
+ }
1482
+ }, [disableKeyboardA11y]);
1483
+ useDrag({
1484
+ nodeRef,
1485
+ });
1486
+ if (userSelectionActive || !width || !height) {
1487
+ return null;
1488
+ }
1489
+ const onContextMenu = onSelectionContextMenu
1490
+ ? (event) => {
1491
+ const selectedNodes = store.getState().nodes.filter((n) => n.selected);
1492
+ onSelectionContextMenu(event, selectedNodes);
1493
+ }
1494
+ : undefined;
1495
+ const onKeyDown = (event) => {
1496
+ 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,
1501
+ });
1502
+ }
1503
+ };
1504
+ return (jsx("div", { className: cc(['react-flow__nodesselection', 'react-flow__container', noPanClassName]), style: {
1505
+ transform: transformString,
1506
+ }, children: jsx("div", { ref: nodeRef, className: "react-flow__nodesselection-rect", onContextMenu: onContextMenu, tabIndex: disableKeyboardA11y ? undefined : -1, onKeyDown: disableKeyboardA11y ? undefined : onKeyDown, style: {
1507
+ width,
1508
+ height,
1509
+ } }) }));
1510
+ }
1511
+ var NodesSelection$1 = memo(NodesSelection);
1512
+
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);
1516
+ const selectionKeyPressed = useKeyPress(selectionKeyCode);
1517
+ const panActivationKeyPressed = useKeyPress(panActivationKeyCode);
1518
+ const panOnDrag = panActivationKeyPressed || _panOnDrag;
1519
+ const panOnScroll = panActivationKeyPressed || _panOnScroll;
1520
+ const isSelecting = selectionKeyPressed || (selectionOnDrag && panOnDrag !== true);
1521
+ 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);
1526
+
1527
+ const selector$f = (onlyRenderVisible) => (s) => {
1528
+ return onlyRenderVisible
1529
+ ? getNodesInside(s.nodes, { x: 0, y: 0, width: s.width, height: s.height }, s.transform, true).map((node) => node.id)
1530
+ : Array.from(s.nodeLookup.keys());
1531
+ };
1532
+ /**
1533
+ * Hook for getting the visible node ids from the store.
1534
+ *
1535
+ * @internal
1536
+ * @param onlyRenderVisible
1537
+ * @returns array with visible node ids
1538
+ */
1539
+ function useVisibleNodeIds(onlyRenderVisible) {
1540
+ const nodeIds = useStore(useCallback(selector$f(onlyRenderVisible), [onlyRenderVisible]), shallow);
1541
+ return nodeIds;
1542
+ }
1543
+
1544
+ const selector$e = (s) => s.updateNodeDimensions;
1545
+ function useResizeObserver() {
1546
+ const updateNodeDimensions = useStore(selector$e);
1547
+ const resizeObserverRef = useRef();
1548
+ const resizeObserver = useMemo(() => {
1549
+ if (typeof ResizeObserver === 'undefined') {
1550
+ return null;
1551
+ }
1552
+ const observer = new ResizeObserver((entries) => {
1553
+ const updates = new Map();
1554
+ entries.forEach((entry) => {
1555
+ const id = entry.target.getAttribute('data-id');
1556
+ updates.set(id, {
1557
+ id,
1558
+ nodeElement: entry.target,
1559
+ forceUpdate: true,
1560
+ });
1561
+ });
1562
+ updateNodeDimensions(updates);
1563
+ });
1564
+ resizeObserverRef.current = observer;
1565
+ return observer;
1566
+ }, []);
1567
+ useEffect(() => {
1568
+ return () => {
1569
+ resizeObserverRef?.current?.disconnect();
1570
+ };
1571
+ }, []);
1572
+ return resizeObserver;
1573
+ }
1574
+
1575
+ const NodeWrapper = ({ id, onClick, onMouseEnter, onMouseMove, onMouseLeave, onContextMenu, onDoubleClick, nodesDraggable, elementsSelectable, nodesConnectable, nodesFocusable, resizeObserver, noDragClassName, noPanClassName, disableKeyboardA11y, rfId, nodeTypes, nodeExtent, nodeOrigin, onError, }) => {
1576
+ const { node, positionAbsoluteX, positionAbsoluteY, zIndex, isParent } = useStore((s) => {
1577
+ const node = s.nodeLookup.get(id);
1578
+ const positionAbsolute = nodeExtent
1579
+ ? clampPosition(node.computed?.positionAbsolute, nodeExtent)
1580
+ : node.computed?.positionAbsolute || { x: 0, y: 0 };
1581
+ return {
1582
+ node,
1583
+ // we are mutating positionAbsolute, z and isParent attributes for sub flows
1584
+ // so we we need to force a re-render when some change
1585
+ positionAbsoluteX: positionAbsolute.x,
1586
+ positionAbsoluteY: positionAbsolute.y,
1587
+ zIndex: node[internalsSymbol]?.z ?? 0,
1588
+ isParent: !!node[internalsSymbol]?.isParent,
1589
+ };
1590
+ }, shallow);
1591
+ let nodeType = node.type || 'default';
1592
+ let NodeComponent = nodeTypes?.[nodeType] || builtinNodeTypes[nodeType];
1593
+ if (NodeComponent === undefined) {
1594
+ onError?.('003', errorMessages['error003'](nodeType));
1595
+ nodeType = 'default';
1596
+ NodeComponent = builtinNodeTypes.default;
1597
+ }
1598
+ const isDraggable = !!(node.draggable || (nodesDraggable && typeof node.draggable === 'undefined'));
1599
+ const isSelectable = !!(node.selectable || (elementsSelectable && typeof node.selectable === 'undefined'));
1600
+ const isConnectable = !!(node.connectable || (nodesConnectable && typeof node.connectable === 'undefined'));
1601
+ const isFocusable = !!(node.focusable || (nodesFocusable && typeof node.focusable === 'undefined'));
1602
+ const store = useStoreApi();
1603
+ const nodeRef = useRef(null);
1604
+ const prevSourcePosition = useRef(node.sourcePosition);
1605
+ const prevTargetPosition = useRef(node.targetPosition);
1606
+ const prevType = useRef(nodeType);
1607
+ const updatePositions = useUpdateNodePositions();
1608
+ useEffect(() => {
1609
+ if (nodeRef.current && !node.hidden) {
1610
+ const currNode = nodeRef.current;
1611
+ resizeObserver?.observe(currNode);
1612
+ return () => resizeObserver?.unobserve(currNode);
1613
+ }
1614
+ }, [node.hidden]);
1615
+ useEffect(() => {
1616
+ // when the user programmatically changes the source or handle position, we re-initialize the node
1617
+ const typeChanged = prevType.current !== nodeType;
1618
+ const sourcePosChanged = prevSourcePosition.current !== node.sourcePosition;
1619
+ const targetPosChanged = prevTargetPosition.current !== node.targetPosition;
1620
+ if (nodeRef.current && (typeChanged || sourcePosChanged || targetPosChanged)) {
1621
+ if (typeChanged) {
1622
+ prevType.current = nodeType;
1623
+ }
1624
+ if (sourcePosChanged) {
1625
+ prevSourcePosition.current = node.sourcePosition;
1626
+ }
1627
+ if (targetPosChanged) {
1628
+ prevTargetPosition.current = node.targetPosition;
1629
+ }
1630
+ store.getState().updateNodeDimensions(new Map([[id, { id, nodeElement: nodeRef.current, forceUpdate: true }]]));
1631
+ }
1632
+ }, [id, nodeType, node.sourcePosition, node.targetPosition]);
1633
+ const dragging = useDrag({
1634
+ nodeRef,
1635
+ disabled: node.hidden || !isDraggable,
1636
+ noDragClassName,
1637
+ handleSelector: node.dragHandle,
1638
+ nodeId: id,
1639
+ isSelectable,
1640
+ });
1641
+ if (node.hidden) {
1642
+ return null;
1643
+ }
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
+ const positionAbsoluteOrigin = getPositionWithOrigin({
1649
+ x: positionAbsoluteX,
1650
+ y: positionAbsoluteY,
1651
+ width: computedWidth ?? width ?? 0,
1652
+ height: computedHeight ?? height ?? 0,
1653
+ origin: node.origin || nodeOrigin,
1654
+ });
1655
+ const initialized = (!!computedWidth && !!computedHeight) || (!!width && !!height);
1656
+ const hasPointerEvents = isSelectable || isDraggable || onClick || onMouseEnter || onMouseMove || onMouseLeave;
1657
+ const onMouseEnterHandler = onMouseEnter ? (event) => onMouseEnter(event, { ...node }) : undefined;
1658
+ const onMouseMoveHandler = onMouseMove ? (event) => onMouseMove(event, { ...node }) : undefined;
1659
+ const onMouseLeaveHandler = onMouseLeave ? (event) => onMouseLeave(event, { ...node }) : undefined;
1660
+ const onContextMenuHandler = onContextMenu ? (event) => onContextMenu(event, { ...node }) : undefined;
1661
+ const onDoubleClickHandler = onDoubleClick ? (event) => onDoubleClick(event, { ...node }) : undefined;
1662
+ const onSelectNodeHandler = (event) => {
1663
+ const { selectNodesOnDrag, nodeDragThreshold } = store.getState();
1664
+ if (isSelectable && (!selectNodesOnDrag || !isDraggable || nodeDragThreshold > 0)) {
1665
+ // this handler gets called by XYDrag on drag start when selectNodesOnDrag=true
1666
+ // here we only need to call it when selectNodesOnDrag=false
1667
+ handleNodeClick({
1668
+ id,
1669
+ store,
1670
+ nodeRef,
1671
+ });
1672
+ }
1673
+ if (onClick) {
1674
+ onClick(event, { ...node });
1675
+ }
1676
+ };
1677
+ const onKeyDown = (event) => {
1678
+ if (isInputDOMNode(event.nativeEvent)) {
1679
+ return;
1680
+ }
1681
+ if (elementSelectionKeys.includes(event.key) && isSelectable) {
1682
+ const unselect = event.key === 'Escape';
1683
+ handleNodeClick({
1684
+ id,
1685
+ store,
1686
+ unselect,
1687
+ nodeRef,
1688
+ });
1689
+ }
1690
+ else if (!disableKeyboardA11y &&
1691
+ isDraggable &&
1692
+ node.selected &&
1693
+ Object.prototype.hasOwnProperty.call(arrowKeyDiffs, event.key)) {
1694
+ store.setState({
1695
+ ariaLiveMessage: `Moved selected node ${event.key
1696
+ .replace('Arrow', '')
1697
+ .toLowerCase()}. New position, x: ${~~positionAbsoluteX}, y: ${~~positionAbsoluteY}`,
1698
+ });
1699
+ updatePositions({
1700
+ x: arrowKeyDiffs[event.key].x,
1701
+ y: arrowKeyDiffs[event.key].y,
1702
+ isShiftPressed: event.shiftKey,
1703
+ });
1704
+ }
1705
+ };
1706
+ return (jsx("div", { className: cc([
1707
+ 'react-flow__node',
1708
+ `react-flow__node-${nodeType}`,
1709
+ {
1710
+ // this is overwritable by passing `nopan` as a class name
1711
+ [noPanClassName]: isDraggable,
1712
+ },
1713
+ node.className,
1714
+ {
1715
+ selected: node.selected,
1716
+ selectable: isSelectable,
1717
+ parent: isParent,
1718
+ dragging,
1719
+ },
1720
+ ]), ref: nodeRef, style: {
1721
+ zIndex,
1722
+ transform: `translate(${positionAbsoluteOrigin.x}px,${positionAbsoluteOrigin.y}px)`,
1723
+ pointerEvents: hasPointerEvents ? 'all' : 'none',
1724
+ visibility: initialized ? 'visible' : 'hidden',
1725
+ width,
1726
+ height,
1727
+ ...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);
1732
+
1733
+ const selector$d = (s) => ({
1734
+ nodesDraggable: s.nodesDraggable,
1735
+ nodesConnectable: s.nodesConnectable,
1736
+ nodesFocusable: s.nodesFocusable,
1737
+ elementsSelectable: s.elementsSelectable,
1738
+ onError: s.onError,
1739
+ });
1740
+ const NodeRenderer = (props) => {
1741
+ const { nodesDraggable, nodesConnectable, nodesFocusable, elementsSelectable, onError } = useStore(selector$d, shallow);
1742
+ const nodeIds = useVisibleNodeIds(props.onlyRenderVisibleElements);
1743
+ const resizeObserver = useResizeObserver();
1744
+ return (jsx("div", { className: "react-flow__nodes", style: containerStyle, children: nodeIds.map((nodeId) => {
1745
+ return (
1746
+ // The split of responsibilities between NodeRenderer and
1747
+ // NodeComponentWrapper may appear weird. However, it’s designed to
1748
+ // minimize the cost of updates when individual nodes change.
1749
+ //
1750
+ // For example, when you’re dragging a single node, that node gets
1751
+ // updated multiple times per second. If `NodeRenderer` were to update
1752
+ // every time, it would have to re-run the `nodes.map()` loop every
1753
+ // time. This gets pricey with hundreds of nodes, especially if every
1754
+ // loop cycle does more than just rendering a JSX element!
1755
+ //
1756
+ // As a result of this choice, we took the following implementation
1757
+ // decisions:
1758
+ // - NodeRenderer subscribes *only* to node IDs – and therefore
1759
+ // rerender *only* when visible nodes are added or removed.
1760
+ // - NodeRenderer performs all operations the result of which can be
1761
+ // shared between nodes (such as creating the `ResizeObserver`
1762
+ // instance, or subscribing to `selector`). This means extra prop
1763
+ // drilling into `NodeComponentWrapper`, but it means we need to run
1764
+ // these operations only once – instead of once per node.
1765
+ // - Any operations that you’d normally write inside `nodes.map` are
1766
+ // moved into `NodeComponentWrapper`. This ensures they are
1767
+ // memorized – so if `NodeRenderer` *has* to rerender, it only
1768
+ // 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));
1770
+ }) }));
1771
+ };
1772
+ NodeRenderer.displayName = 'NodeRenderer';
1773
+ var NodeRenderer$1 = memo(NodeRenderer);
1774
+
1775
+ /**
1776
+ * Hook for getting the visible edge ids from the store.
1777
+ *
1778
+ * @internal
1779
+ * @param onlyRenderVisible
1780
+ * @returns array with visible edge ids
1781
+ */
1782
+ function useVisibleEdgeIds(onlyRenderVisible) {
1783
+ const edgeIds = useStore(useCallback((s) => {
1784
+ if (!onlyRenderVisible) {
1785
+ return s.edges.map((edge) => edge.id);
1786
+ }
1787
+ const visibleEdgeIds = [];
1788
+ if (s.width && s.height) {
1789
+ for (const edge of s.edges) {
1790
+ const sourceNode = s.nodeLookup.get(edge.source);
1791
+ const targetNode = s.nodeLookup.get(edge.target);
1792
+ if (sourceNode &&
1793
+ targetNode &&
1794
+ isEdgeVisible({
1795
+ sourceNode,
1796
+ targetNode,
1797
+ width: s.width,
1798
+ height: s.height,
1799
+ transform: s.transform,
1800
+ })) {
1801
+ visibleEdgeIds.push(edge.id);
1802
+ }
1803
+ }
1804
+ }
1805
+ return visibleEdgeIds;
1806
+ }, [onlyRenderVisible]), shallow);
1807
+ return edgeIds;
1808
+ }
1809
+
1810
+ const ArrowSymbol = ({ color = 'none', strokeWidth = 1 }) => {
1811
+ return (jsx("polyline", { style: {
1812
+ stroke: color,
1813
+ strokeWidth,
1814
+ }, strokeLinecap: "round", strokeLinejoin: "round", fill: "none", points: "-5,-4 0,0 -5,4" }));
1815
+ };
1816
+ const ArrowClosedSymbol = ({ color = 'none', strokeWidth = 1 }) => {
1817
+ return (jsx("polyline", { style: {
1818
+ stroke: color,
1819
+ fill: color,
1820
+ strokeWidth,
1821
+ }, strokeLinecap: "round", strokeLinejoin: "round", points: "-5,-4 0,0 -5,4 -5,-4" }));
1822
+ };
1823
+ const MarkerSymbols = {
1824
+ [MarkerType.Arrow]: ArrowSymbol,
1825
+ [MarkerType.ArrowClosed]: ArrowClosedSymbol,
1826
+ };
1827
+ function useMarkerSymbol(type) {
1828
+ const store = useStoreApi();
1829
+ const symbol = useMemo(() => {
1830
+ const symbolExists = Object.prototype.hasOwnProperty.call(MarkerSymbols, type);
1831
+ if (!symbolExists) {
1832
+ store.getState().onError?.('009', errorMessages['error009'](type));
1833
+ return null;
1834
+ }
1835
+ return MarkerSymbols[type];
1836
+ }, [type]);
1837
+ return symbol;
1838
+ }
1839
+
1840
+ const Marker = ({ id, type, color, width = 12.5, height = 12.5, markerUnits = 'strokeWidth', strokeWidth, orient = 'auto-start-reverse', }) => {
1841
+ const Symbol = useMarkerSymbol(type);
1842
+ if (!Symbol) {
1843
+ return null;
1844
+ }
1845
+ 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
+ };
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
+ // when you have multiple flows on a page and you hide the first one, the other ones have no markers anymore
1855
+ // 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
+ // that we can then use for creating our unique marker ids
1857
+ const MarkerDefinitions = ({ defaultColor, rfId }) => {
1858
+ const markers = useStore(useCallback(markerSelector({ defaultColor, rfId }), [defaultColor, rfId]), markersEqual);
1859
+ if (!markers.length) {
1860
+ return null;
1861
+ }
1862
+ return (jsx("svg", { className: "react-flow__marker", children: jsx("defs", { children: markers.map((marker) => (jsx(Marker, { id: marker.id, type: marker.type, color: marker.color, width: marker.width, height: marker.height, markerUnits: marker.markerUnits, strokeWidth: marker.strokeWidth, orient: marker.orient }, marker.id))) }) }));
1863
+ };
1864
+ MarkerDefinitions.displayName = 'MarkerDefinitions';
1865
+ var MarkerDefinitions$1 = memo(MarkerDefinitions);
1866
+
1867
+ const EdgeText = ({ x, y, label, labelStyle = {}, labelShowBg = true, labelBgStyle = {}, labelBgPadding = [2, 4], labelBgBorderRadius = 2, children, className, ...rest }) => {
1868
+ const [edgeTextBbox, setEdgeTextBbox] = useState({ x: 1, y: 0, width: 0, height: 0 });
1869
+ const edgeTextClasses = cc(['react-flow__edge-textwrapper', className]);
1870
+ const onEdgeTextRefChange = useCallback((edgeRef) => {
1871
+ if (edgeRef === null)
1872
+ return;
1873
+ const textBbox = edgeRef.getBBox();
1874
+ setEdgeTextBbox({
1875
+ x: textBbox.x,
1876
+ y: textBbox.y,
1877
+ width: textBbox.width,
1878
+ height: textBbox.height,
1879
+ });
1880
+ }, []);
1881
+ if (typeof label === 'undefined' || !label) {
1882
+ return null;
1883
+ }
1884
+ 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);
1887
+
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';
1892
+
1893
+ function getControl({ pos, x1, y1, x2, y2 }) {
1894
+ if (pos === Position.Left || pos === Position.Right) {
1895
+ return [0.5 * (x1 + x2), y1];
1896
+ }
1897
+ return [x1, 0.5 * (y1 + y2)];
1898
+ }
1899
+ function getSimpleBezierPath({ sourceX, sourceY, sourcePosition = Position.Bottom, targetX, targetY, targetPosition = Position.Top, }) {
1900
+ const [sourceControlX, sourceControlY] = getControl({
1901
+ pos: sourcePosition,
1902
+ x1: sourceX,
1903
+ y1: sourceY,
1904
+ x2: targetX,
1905
+ y2: targetY,
1906
+ });
1907
+ const [targetControlX, targetControlY] = getControl({
1908
+ pos: targetPosition,
1909
+ x1: targetX,
1910
+ y1: targetY,
1911
+ x2: sourceX,
1912
+ y2: sourceY,
1913
+ });
1914
+ const [labelX, labelY, offsetX, offsetY] = getBezierEdgeCenter({
1915
+ sourceX,
1916
+ sourceY,
1917
+ targetX,
1918
+ targetY,
1919
+ sourceControlX,
1920
+ sourceControlY,
1921
+ targetControlX,
1922
+ targetControlY,
1923
+ });
1924
+ return [
1925
+ `M${sourceX},${sourceY} C${sourceControlX},${sourceControlY} ${targetControlX},${targetControlY} ${targetX},${targetY}`,
1926
+ labelX,
1927
+ labelY,
1928
+ offsetX,
1929
+ offsetY,
1930
+ ];
1931
+ }
1932
+ function createSimpleBezierEdge(params) {
1933
+ // eslint-disable-next-line react/display-name
1934
+ return memo(({ id, sourceX, sourceY, targetX, targetY, sourcePosition = Position.Bottom, targetPosition = Position.Top, label, labelStyle, labelShowBg, labelBgStyle, labelBgPadding, labelBgBorderRadius, style, markerEnd, markerStart, interactionWidth, }) => {
1935
+ const [path, labelX, labelY] = getSimpleBezierPath({
1936
+ sourceX,
1937
+ sourceY,
1938
+ sourcePosition,
1939
+ targetX,
1940
+ targetY,
1941
+ targetPosition,
1942
+ });
1943
+ const _id = params.isInternal ? undefined : id;
1944
+ return (jsx(BaseEdge, { id: _id, path: path, labelX: labelX, labelY: labelY, label: label, labelStyle: labelStyle, labelShowBg: labelShowBg, labelBgStyle: labelBgStyle, labelBgPadding: labelBgPadding, labelBgBorderRadius: labelBgBorderRadius, style: style, markerEnd: markerEnd, markerStart: markerStart, interactionWidth: interactionWidth }));
1945
+ });
1946
+ }
1947
+ const SimpleBezierEdge = createSimpleBezierEdge({ isInternal: false });
1948
+ const SimpleBezierEdgeInternal = createSimpleBezierEdge({ isInternal: true });
1949
+ SimpleBezierEdge.displayName = 'SimpleBezierEdge';
1950
+ SimpleBezierEdgeInternal.displayName = 'SimpleBezierEdgeInternal';
1951
+
1952
+ function createSmoothStepEdge(params) {
1953
+ // eslint-disable-next-line react/display-name
1954
+ return memo(({ id, sourceX, sourceY, targetX, targetY, label, labelStyle, labelShowBg, labelBgStyle, labelBgPadding, labelBgBorderRadius, style, sourcePosition = Position.Bottom, targetPosition = Position.Top, markerEnd, markerStart, pathOptions, interactionWidth, }) => {
1955
+ const [path, labelX, labelY] = getSmoothStepPath({
1956
+ sourceX,
1957
+ sourceY,
1958
+ sourcePosition,
1959
+ targetX,
1960
+ targetY,
1961
+ targetPosition,
1962
+ borderRadius: pathOptions?.borderRadius,
1963
+ offset: pathOptions?.offset,
1964
+ });
1965
+ const _id = params.isInternal ? undefined : id;
1966
+ return (jsx(BaseEdge, { id: _id, path: path, labelX: labelX, labelY: labelY, label: label, labelStyle: labelStyle, labelShowBg: labelShowBg, labelBgStyle: labelBgStyle, labelBgPadding: labelBgPadding, labelBgBorderRadius: labelBgBorderRadius, style: style, markerEnd: markerEnd, markerStart: markerStart, interactionWidth: interactionWidth }));
1967
+ });
1968
+ }
1969
+ const SmoothStepEdge = createSmoothStepEdge({ isInternal: false });
1970
+ const SmoothStepEdgeInternal = createSmoothStepEdge({ isInternal: true });
1971
+ SmoothStepEdge.displayName = 'SmoothStepEdge';
1972
+ SmoothStepEdgeInternal.displayName = 'SmoothStepEdgeInternal';
1973
+
1974
+ function createStepEdge(params) {
1975
+ // eslint-disable-next-line react/display-name
1976
+ return memo(({ id, ...props }) => {
1977
+ const _id = params.isInternal ? undefined : id;
1978
+ return (jsx(SmoothStepEdge, { ...props, id: _id, pathOptions: useMemo(() => ({ borderRadius: 0, offset: props.pathOptions?.offset }), [props.pathOptions?.offset]) }));
1979
+ });
1980
+ }
1981
+ const StepEdge = createStepEdge({ isInternal: false });
1982
+ const StepEdgeInternal = createStepEdge({ isInternal: true });
1983
+ StepEdge.displayName = 'StepEdge';
1984
+ StepEdgeInternal.displayName = 'StepEdgeInternal';
1985
+
1986
+ function createStraightEdge(params) {
1987
+ // eslint-disable-next-line react/display-name
1988
+ return memo(({ id, sourceX, sourceY, targetX, targetY, label, labelStyle, labelShowBg, labelBgStyle, labelBgPadding, labelBgBorderRadius, style, markerEnd, markerStart, interactionWidth, }) => {
1989
+ const [path, labelX, labelY] = getStraightPath({ sourceX, sourceY, targetX, targetY });
1990
+ const _id = params.isInternal ? undefined : id;
1991
+ return (jsx(BaseEdge, { id: _id, path: path, labelX: labelX, labelY: labelY, label: label, labelStyle: labelStyle, labelShowBg: labelShowBg, labelBgStyle: labelBgStyle, labelBgPadding: labelBgPadding, labelBgBorderRadius: labelBgBorderRadius, style: style, markerEnd: markerEnd, markerStart: markerStart, interactionWidth: interactionWidth }));
1992
+ });
1993
+ }
1994
+ const StraightEdge = createStraightEdge({ isInternal: false });
1995
+ const StraightEdgeInternal = createStraightEdge({ isInternal: true });
1996
+ StraightEdge.displayName = 'StraightEdge';
1997
+ StraightEdgeInternal.displayName = 'StraightEdgeInternal';
1998
+
1999
+ function createBezierEdge(params) {
2000
+ // eslint-disable-next-line react/display-name
2001
+ return memo(({ id, sourceX, sourceY, targetX, targetY, sourcePosition = Position.Bottom, targetPosition = Position.Top, label, labelStyle, labelShowBg, labelBgStyle, labelBgPadding, labelBgBorderRadius, style, markerEnd, markerStart, pathOptions, interactionWidth, }) => {
2002
+ const [path, labelX, labelY] = getBezierPath({
2003
+ sourceX,
2004
+ sourceY,
2005
+ sourcePosition,
2006
+ targetX,
2007
+ targetY,
2008
+ targetPosition,
2009
+ curvature: pathOptions?.curvature,
2010
+ });
2011
+ const _id = params.isInternal ? undefined : id;
2012
+ return (jsx(BaseEdge, { id: _id, path: path, labelX: labelX, labelY: labelY, label: label, labelStyle: labelStyle, labelShowBg: labelShowBg, labelBgStyle: labelBgStyle, labelBgPadding: labelBgPadding, labelBgBorderRadius: labelBgBorderRadius, style: style, markerEnd: markerEnd, markerStart: markerStart, interactionWidth: interactionWidth }));
2013
+ });
2014
+ }
2015
+ const BezierEdge = createBezierEdge({ isInternal: false });
2016
+ const BezierEdgeInternal = createBezierEdge({ isInternal: true });
2017
+ BezierEdge.displayName = 'BezierEdge';
2018
+ BezierEdgeInternal.displayName = 'BezierEdgeInternal';
2019
+
2020
+ const builtinEdgeTypes = {
2021
+ default: BezierEdgeInternal,
2022
+ straight: StraightEdgeInternal,
2023
+ step: StepEdgeInternal,
2024
+ smoothstep: SmoothStepEdgeInternal,
2025
+ simplebezier: SimpleBezierEdgeInternal,
2026
+ };
2027
+ const nullPosition = {
2028
+ sourceX: null,
2029
+ sourceY: null,
2030
+ targetX: null,
2031
+ targetY: null,
2032
+ sourcePosition: null,
2033
+ targetPosition: null,
2034
+ };
2035
+
2036
+ const shiftX = (x, shift, position) => {
2037
+ if (position === Position.Left)
2038
+ return x - shift;
2039
+ if (position === Position.Right)
2040
+ return x + shift;
2041
+ return x;
2042
+ };
2043
+ const shiftY = (y, shift, position) => {
2044
+ if (position === Position.Top)
2045
+ return y - shift;
2046
+ if (position === Position.Bottom)
2047
+ return y + shift;
2048
+ return y;
2049
+ };
2050
+ 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" }));
2052
+
2053
+ function EdgeUpdateAnchors({ isUpdatable, edgeUpdaterRadius, edge, targetHandleId, sourceHandleId, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, onEdgeUpdate, onEdgeUpdateStart, onEdgeUpdateEnd, setUpdating, setUpdateHover, }) {
2054
+ const store = useStoreApi();
2055
+ const handleEdgeUpdater = (event, isSourceHandle) => {
2056
+ // avoid triggering edge updater if mouse btn is not left
2057
+ if (event.button !== 0) {
2058
+ return;
2059
+ }
2060
+ const { autoPanOnConnect, domNode, isValidConnection, connectionMode, connectionRadius, lib, onConnectStart, onConnectEnd, cancelConnection, nodes, panBy, updateConnection, } = store.getState();
2061
+ const nodeId = isSourceHandle ? edge.target : edge.source;
2062
+ const handleId = (isSourceHandle ? targetHandleId : sourceHandleId) || null;
2063
+ const handleType = isSourceHandle ? 'target' : 'source';
2064
+ const isTarget = isSourceHandle;
2065
+ setUpdating(true);
2066
+ onEdgeUpdateStart?.(event, edge, handleType);
2067
+ const _onEdgeUpdateEnd = (evt) => {
2068
+ setUpdating(false);
2069
+ onEdgeUpdateEnd?.(evt, edge, handleType);
2070
+ };
2071
+ const onConnectEdge = (connection) => onEdgeUpdate?.(edge, connection);
2072
+ XYHandle.onPointerDown(event.nativeEvent, {
2073
+ autoPanOnConnect,
2074
+ connectionMode,
2075
+ connectionRadius,
2076
+ domNode,
2077
+ handleId,
2078
+ nodeId,
2079
+ nodes,
2080
+ isTarget,
2081
+ edgeUpdaterType: handleType,
2082
+ lib,
2083
+ cancelConnection,
2084
+ panBy,
2085
+ isValidConnection,
2086
+ onConnect: onConnectEdge,
2087
+ onConnectStart,
2088
+ onConnectEnd,
2089
+ onEdgeUpdateEnd: _onEdgeUpdateEnd,
2090
+ updateConnection,
2091
+ getTransform: () => store.getState().transform,
2092
+ });
2093
+ };
2094
+ const onEdgeUpdaterSourceMouseDown = (event) => handleEdgeUpdater(event, true);
2095
+ const onEdgeUpdaterTargetMouseDown = (event) => handleEdgeUpdater(event, false);
2096
+ const onEdgeUpdaterMouseEnter = () => setUpdateHover(true);
2097
+ const onEdgeUpdaterMouseOut = () => setUpdateHover(false);
2098
+ 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
+ }
2100
+
2101
+ function EdgeWrapper({ id, edgesFocusable, edgesUpdatable, elementsSelectable, onClick, onDoubleClick, sourceHandleId, targetHandleId, onContextMenu, onMouseEnter, onMouseMove, onMouseLeave, edgeUpdaterRadius, onEdgeUpdate, onEdgeUpdateStart, onEdgeUpdateEnd, rfId, edgeTypes, noPanClassName, onError, }) {
2102
+ let edge = useStore((s) => s.edgeLookup.get(id));
2103
+ const defaultEdgeOptions = useStore((s) => s.defaultEdgeOptions);
2104
+ edge = defaultEdgeOptions ? { ...defaultEdgeOptions, ...edge } : edge;
2105
+ let edgeType = edge.type || 'default';
2106
+ let EdgeComponent = edgeTypes?.[edgeType] || builtinEdgeTypes[edgeType];
2107
+ if (EdgeComponent === undefined) {
2108
+ onError?.('011', errorMessages['error011'](edgeType));
2109
+ edgeType = 'default';
2110
+ EdgeComponent = builtinEdgeTypes.default;
2111
+ }
2112
+ const isFocusable = !!(edge.focusable || (edgesFocusable && typeof edge.focusable === 'undefined'));
2113
+ const isUpdatable = typeof onEdgeUpdate !== 'undefined' &&
2114
+ (edge.updatable || (edgesUpdatable && typeof edge.updatable === 'undefined'));
2115
+ const isSelectable = !!(edge.selectable || (elementsSelectable && typeof edge.selectable === 'undefined'));
2116
+ const edgeRef = useRef(null);
2117
+ const [updateHover, setUpdateHover] = useState(false);
2118
+ const [updating, setUpdating] = useState(false);
2119
+ const store = useStoreApi();
2120
+ const { zIndex, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition } = useStore(useCallback((store) => {
2121
+ const sourceNode = store.nodeLookup.get(edge.source);
2122
+ const targetNode = store.nodeLookup.get(edge.target);
2123
+ if (!sourceNode || !targetNode) {
2124
+ return {
2125
+ zIndex: edge.zIndex,
2126
+ ...nullPosition,
2127
+ };
2128
+ }
2129
+ const edgePosition = getEdgePosition({
2130
+ id,
2131
+ sourceNode,
2132
+ targetNode,
2133
+ sourceHandle: sourceHandleId || null,
2134
+ targetHandle: targetHandleId || null,
2135
+ connectionMode: store.connectionMode,
2136
+ onError,
2137
+ });
2138
+ const zIndex = getElevatedEdgeZIndex({
2139
+ selected: edge.selected,
2140
+ zIndex: edge.zIndex,
2141
+ sourceNode,
2142
+ targetNode,
2143
+ elevateOnSelect: store.elevateEdgesOnSelect,
2144
+ });
2145
+ return {
2146
+ zIndex,
2147
+ ...(edgePosition || nullPosition),
2148
+ };
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]);
2152
+ if (edge.hidden || !sourceX || !sourceY || !targetX || !targetY) {
2153
+ return null;
2154
+ }
2155
+ const onEdgeClick = (event) => {
2156
+ const { addSelectedEdges, unselectNodesAndEdges, multiSelectionActive } = store.getState();
2157
+ if (isSelectable) {
2158
+ store.setState({ nodesSelectionActive: false });
2159
+ if (edge.selected && multiSelectionActive) {
2160
+ unselectNodesAndEdges({ nodes: [], edges: [edge] });
2161
+ edgeRef.current?.blur();
2162
+ }
2163
+ else {
2164
+ addSelectedEdges([id]);
2165
+ }
2166
+ }
2167
+ if (onClick) {
2168
+ onClick(event, edge);
2169
+ }
2170
+ };
2171
+ const onEdgeDoubleClick = onDoubleClick
2172
+ ? (event) => {
2173
+ onDoubleClick(event, { ...edge });
2174
+ }
2175
+ : undefined;
2176
+ const onEdgeContextMenu = onContextMenu
2177
+ ? (event) => {
2178
+ onContextMenu(event, { ...edge });
2179
+ }
2180
+ : undefined;
2181
+ const onEdgeMouseEnter = onMouseEnter
2182
+ ? (event) => {
2183
+ onMouseEnter(event, { ...edge });
2184
+ }
2185
+ : undefined;
2186
+ const onEdgeMouseMove = onMouseMove
2187
+ ? (event) => {
2188
+ onMouseMove(event, { ...edge });
2189
+ }
2190
+ : undefined;
2191
+ const onEdgeMouseLeave = onMouseLeave
2192
+ ? (event) => {
2193
+ onMouseLeave(event, { ...edge });
2194
+ }
2195
+ : undefined;
2196
+ const onKeyDown = (event) => {
2197
+ if (elementSelectionKeys.includes(event.key) && isSelectable) {
2198
+ const { unselectNodesAndEdges, addSelectedEdges } = store.getState();
2199
+ const unselect = event.key === 'Escape';
2200
+ if (unselect) {
2201
+ edgeRef.current?.blur();
2202
+ unselectNodesAndEdges({ edges: [edge] });
2203
+ }
2204
+ else {
2205
+ addSelectedEdges([id]);
2206
+ }
2207
+ }
2208
+ };
2209
+ return (jsx("svg", { style: { zIndex }, children: jsxs("g", { className: cc([
2210
+ 'react-flow__edge',
2211
+ `react-flow__edge-${edgeType}`,
2212
+ edge.className,
2213
+ noPanClassName,
2214
+ {
2215
+ selected: edge.selected,
2216
+ animated: edge.animated,
2217
+ inactive: !isSelectable && !onClick,
2218
+ updating: updateHover,
2219
+ },
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 }))] }) }));
2221
+ }
2222
+ EdgeWrapper.displayName = 'EdgeWrapper';
2223
+ var EdgeWrapper$1 = memo(EdgeWrapper);
2224
+
2225
+ const selector$c = (s) => ({
2226
+ width: s.width,
2227
+ height: s.height,
2228
+ edgesFocusable: s.edgesFocusable,
2229
+ edgesUpdatable: s.edgesUpdatable,
2230
+ elementsSelectable: s.elementsSelectable,
2231
+ connectionMode: s.connectionMode,
2232
+ onError: s.onError,
2233
+ });
2234
+ const EdgeRenderer = ({ defaultMarkerColor, onlyRenderVisibleElements, rfId, edgeTypes, noPanClassName, onEdgeUpdate, onEdgeContextMenu, onEdgeMouseEnter, onEdgeMouseMove, onEdgeMouseLeave, onEdgeClick, edgeUpdaterRadius, onEdgeDoubleClick, onEdgeUpdateStart, onEdgeUpdateEnd, children, }) => {
2235
+ const { edgesFocusable, edgesUpdatable, elementsSelectable, onError } = useStore(selector$c, shallow);
2236
+ const edgeIds = useVisibleEdgeIds(onlyRenderVisibleElements);
2237
+ 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);
2243
+
2244
+ const selector$b = (s) => `translate(${s.transform[0]}px,${s.transform[1]}px) scale(${s.transform[2]})`;
2245
+ function Viewport({ children }) {
2246
+ const transform = useStore(selector$b);
2247
+ return (jsx("div", { className: "react-flow__viewport xyflow__viewport react-flow__container", style: { transform }, children: children }));
2248
+ }
2249
+
2250
+ /**
2251
+ * Hook for calling onInit handler.
2252
+ *
2253
+ * @internal
2254
+ */
2255
+ function useOnInitHandler(onInit) {
2256
+ const rfInstance = useReactFlow();
2257
+ const isInitialized = useRef(false);
2258
+ useEffect(() => {
2259
+ if (!isInitialized.current && rfInstance.viewportInitialized && onInit) {
2260
+ setTimeout(() => onInit(rfInstance), 1);
2261
+ isInitialized.current = true;
2262
+ }
2263
+ }, [onInit, rfInstance.viewportInitialized]);
2264
+ }
2265
+
2266
+ const selector$a = (state) => state.panZoom?.syncViewport;
2267
+ /**
2268
+ * Hook for syncing the viewport with the panzoom instance.
2269
+ *
2270
+ * @internal
2271
+ * @param viewport
2272
+ */
2273
+ function useViewportSync(viewport) {
2274
+ const syncViewport = useStore(selector$a);
2275
+ const store = useStoreApi();
2276
+ useEffect(() => {
2277
+ if (viewport) {
2278
+ syncViewport?.(viewport);
2279
+ store.setState({ transform: [viewport.x, viewport.y, viewport.zoom] });
2280
+ }
2281
+ }, [viewport, syncViewport]);
2282
+ return null;
2283
+ }
2284
+
2285
+ const oppositePosition = {
2286
+ [Position.Left]: Position.Right,
2287
+ [Position.Right]: Position.Left,
2288
+ [Position.Top]: Position.Bottom,
2289
+ [Position.Bottom]: Position.Top,
2290
+ };
2291
+ const ConnectionLine = ({ nodeId, handleType, style, type = ConnectionLineType.Bezier, CustomComponent, connectionStatus, }) => {
2292
+ const { fromNode, handleId, toX, toY, connectionMode } = useStore(useCallback((s) => ({
2293
+ fromNode: s.nodeLookup.get(nodeId),
2294
+ handleId: s.connectionStartHandle?.handleId,
2295
+ toX: (s.connectionPosition.x - s.transform[0]) / s.transform[2],
2296
+ toY: (s.connectionPosition.y - s.transform[1]) / s.transform[2],
2297
+ connectionMode: s.connectionMode,
2298
+ }), [nodeId]), shallow);
2299
+ const fromHandleBounds = fromNode?.[internalsSymbol]?.handleBounds;
2300
+ let handleBounds = fromHandleBounds?.[handleType];
2301
+ if (connectionMode === ConnectionMode.Loose) {
2302
+ handleBounds = handleBounds ? handleBounds : fromHandleBounds?.[handleType === 'source' ? 'target' : 'source'];
2303
+ }
2304
+ if (!fromNode || !handleBounds) {
2305
+ return null;
2306
+ }
2307
+ const fromHandle = handleId ? handleBounds.find((d) => d.id === handleId) : handleBounds[0];
2308
+ const fromHandleX = fromHandle ? fromHandle.x + fromHandle.width / 2 : (fromNode.computed?.width ?? 0) / 2;
2309
+ const fromHandleY = fromHandle ? fromHandle.y + fromHandle.height / 2 : fromNode.computed?.height ?? 0;
2310
+ const fromX = (fromNode.computed?.positionAbsolute?.x ?? 0) + fromHandleX;
2311
+ const fromY = (fromNode.computed?.positionAbsolute?.y ?? 0) + fromHandleY;
2312
+ const fromPosition = fromHandle?.position;
2313
+ const toPosition = fromPosition ? oppositePosition[fromPosition] : null;
2314
+ if (!fromPosition || !toPosition) {
2315
+ return null;
2316
+ }
2317
+ if (CustomComponent) {
2318
+ return (jsx(CustomComponent, { connectionLineType: type, connectionLineStyle: style, fromNode: fromNode, fromHandle: fromHandle, fromX: fromX, fromY: fromY, toX: toX, toY: toY, fromPosition: fromPosition, toPosition: toPosition, connectionStatus: connectionStatus }));
2319
+ }
2320
+ let dAttr = '';
2321
+ const pathParams = {
2322
+ sourceX: fromX,
2323
+ sourceY: fromY,
2324
+ sourcePosition: fromPosition,
2325
+ targetX: toX,
2326
+ targetY: toY,
2327
+ targetPosition: toPosition,
2328
+ };
2329
+ if (type === ConnectionLineType.Bezier) {
2330
+ // we assume the destination position is opposite to the source position
2331
+ [dAttr] = getBezierPath(pathParams);
2332
+ }
2333
+ else if (type === ConnectionLineType.Step) {
2334
+ [dAttr] = getSmoothStepPath({
2335
+ ...pathParams,
2336
+ borderRadius: 0,
2337
+ });
2338
+ }
2339
+ else if (type === ConnectionLineType.SmoothStep) {
2340
+ [dAttr] = getSmoothStepPath(pathParams);
2341
+ }
2342
+ else if (type === ConnectionLineType.SimpleBezier) {
2343
+ [dAttr] = getSimpleBezierPath(pathParams);
2344
+ }
2345
+ else {
2346
+ dAttr = `M${fromX},${fromY} ${toX},${toY}`;
2347
+ }
2348
+ return jsx("path", { d: dAttr, fill: "none", className: "react-flow__connection-path", style: style });
2349
+ };
2350
+ ConnectionLine.displayName = 'ConnectionLine';
2351
+ const selector$9 = (s) => ({
2352
+ nodeId: s.connectionStartHandle?.nodeId,
2353
+ handleType: s.connectionStartHandle?.type,
2354
+ nodesConnectable: s.nodesConnectable,
2355
+ connectionStatus: s.connectionStatus,
2356
+ width: s.width,
2357
+ height: s.height,
2358
+ });
2359
+ function ConnectionLineWrapper({ containerStyle, style, type, component }) {
2360
+ const { nodeId, handleType, nodesConnectable, width, height, connectionStatus } = useStore(selector$9, shallow);
2361
+ const isValid = !!(nodeId && handleType && width && nodesConnectable);
2362
+ if (!isValid) {
2363
+ return null;
2364
+ }
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 }) }) }));
2366
+ }
2367
+
2368
+ const emptyTypes = {};
2369
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2370
+ function useNodeOrEdgeTypesWarning(nodeOrEdgeTypes = emptyTypes) {
2371
+ const updateCount = useRef(0);
2372
+ const store = useStoreApi();
2373
+ useEffect(() => {
2374
+ if (process.env.NODE_ENV === 'development') {
2375
+ if (updateCount.current > 1) {
2376
+ store.getState().onError?.('002', errorMessages['error002']());
2377
+ }
2378
+ updateCount.current += 1;
2379
+ }
2380
+ }, [nodeOrEdgeTypes]);
2381
+ }
2382
+
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, }) => {
2384
+ useNodeOrEdgeTypesWarning(nodeTypes);
2385
+ useNodeOrEdgeTypesWarning(edgeTypes);
2386
+ useOnInitHandler(onInit);
2387
+ 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
+ }
2416
+ }
2417
+
2418
+ const getInitialState = ({ nodes = [], edges = [], width, height, fitView, } = {}) => {
2419
+ const nodeLookup = new Map();
2420
+ const connectionLookup = new Map();
2421
+ const edgeLookup = new Map();
2422
+ updateConnectionLookup(connectionLookup, edgeLookup, edges);
2423
+ const nextNodes = adoptUserProvidedNodes(nodes, nodeLookup, {
2424
+ nodeOrigin: [0, 0],
2425
+ elevateNodesOnSelect: false,
2426
+ });
2427
+ let transform = [0, 0, 1];
2428
+ if (fitView && width && height) {
2429
+ const nodesWithDimensions = nextNodes.filter((node) => node.width && node.height);
2430
+ const bounds = getNodesBounds(nodesWithDimensions, [0, 0]);
2431
+ const { x, y, zoom } = getViewportForBounds(bounds, width, height, 0.5, 2, 0.1);
2432
+ transform = [x, y, zoom];
2433
+ }
2434
+ return {
2435
+ rfId: '1',
2436
+ width: 0,
2437
+ height: 0,
2438
+ transform,
2439
+ nodes: nextNodes,
2440
+ nodeLookup,
2441
+ edges,
2442
+ edgeLookup,
2443
+ connectionLookup,
2444
+ onNodesChange: null,
2445
+ onEdgesChange: null,
2446
+ hasDefaultNodes: false,
2447
+ hasDefaultEdges: false,
2448
+ panZoom: null,
2449
+ minZoom: 0.5,
2450
+ maxZoom: 2,
2451
+ translateExtent: infiniteExtent,
2452
+ nodeExtent: infiniteExtent,
2453
+ nodesSelectionActive: false,
2454
+ userSelectionActive: false,
2455
+ userSelectionRect: null,
2456
+ connectionPosition: { x: 0, y: 0 },
2457
+ connectionStatus: null,
2458
+ connectionMode: ConnectionMode.Strict,
2459
+ domNode: null,
2460
+ paneDragging: false,
2461
+ noPanClassName: 'nopan',
2462
+ nodeOrigin: [0, 0],
2463
+ nodeDragThreshold: 1,
2464
+ snapGrid: [15, 15],
2465
+ snapToGrid: false,
2466
+ nodesDraggable: true,
2467
+ nodesConnectable: true,
2468
+ nodesFocusable: true,
2469
+ edgesFocusable: true,
2470
+ edgesUpdatable: true,
2471
+ elementsSelectable: true,
2472
+ elevateNodesOnSelect: true,
2473
+ elevateEdgesOnSelect: false,
2474
+ fitViewOnInit: false,
2475
+ fitViewDone: false,
2476
+ fitViewOnInitOptions: undefined,
2477
+ selectNodesOnDrag: true,
2478
+ multiSelectionActive: false,
2479
+ connectionStartHandle: null,
2480
+ connectionEndHandle: null,
2481
+ connectionClickStartHandle: null,
2482
+ connectOnClick: true,
2483
+ ariaLiveMessage: '',
2484
+ autoPanOnConnect: true,
2485
+ autoPanOnNodeDrag: true,
2486
+ connectionRadius: 20,
2487
+ onError: () => null,
2488
+ isValidConnection: undefined,
2489
+ onSelectionChangeHandlers: [],
2490
+ lib: 'react',
2491
+ };
2492
+ };
2493
+
2494
+ const createRFStore = ({ nodes, edges, width, height, fitView: fitView$1, }) => createWithEqualityFn((set, get) => ({
2495
+ ...getInitialState({ nodes, edges, width, height, fitView: fitView$1 }),
2496
+ setNodes: (nodes) => {
2497
+ const { nodeLookup, nodeOrigin, elevateNodesOnSelect } = get();
2498
+ // setNodes() is called exclusively in response to user actions:
2499
+ // - either when the `<ReactFlow nodes>` prop is updated in the controlled ReactFlow setup,
2500
+ // - or when the user calls something like `reactFlowInstance.setNodes()` in an uncontrolled ReactFlow setup.
2501
+ //
2502
+ // When this happens, we take the note objects passed by the user and extend them with fields
2503
+ // relevant for internal React Flow operations.
2504
+ // TODO: consider updating the types to reflect the distinction between user-provided nodes and internal nodes.
2505
+ const nodesWithInternalData = adoptUserProvidedNodes(nodes, nodeLookup, { nodeOrigin, elevateNodesOnSelect });
2506
+ set({ nodes: nodesWithInternalData });
2507
+ },
2508
+ setEdges: (edges) => {
2509
+ const { connectionLookup, edgeLookup } = get();
2510
+ updateConnectionLookup(connectionLookup, edgeLookup, edges);
2511
+ set({ edges });
2512
+ },
2513
+ // when the user works with an uncontrolled flow,
2514
+ // we set a flag `hasDefaultNodes` / `hasDefaultEdges`
2515
+ 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
+ });
2528
+ }
2529
+ if (hasDefaultEdges) {
2530
+ const { connectionLookup, edgeLookup } = get();
2531
+ updateConnectionLookup(connectionLookup, edgeLookup, edges);
2532
+ nextState.edges = edges;
2533
+ }
2534
+ set(nextState);
2535
+ },
2536
+ // Every node gets registerd at a ResizeObserver. Whenever a node
2537
+ // changes its dimensions, this function is called to measure the
2538
+ // new dimensions and update the nodes.
2539
+ updateNodeDimensions: (updates) => {
2540
+ const { onNodesChange, fitView, nodes, nodeLookup, fitViewOnInit, fitViewDone, fitViewOnInitOptions, domNode, nodeOrigin, } = get();
2541
+ const changes = [];
2542
+ const updatedNodes = updateNodeDimensions(updates, nodes, nodeLookup, domNode, nodeOrigin, (id, dimensions) => {
2543
+ changes.push({
2544
+ id: id,
2545
+ type: 'dimensions',
2546
+ dimensions,
2547
+ });
2548
+ });
2549
+ if (!updatedNodes) {
2550
+ return;
2551
+ }
2552
+ const nextNodes = updateAbsolutePositions(updatedNodes, nodeLookup, nodeOrigin);
2553
+ // we call fitView once initially after all dimensions are set
2554
+ let nextFitViewDone = fitViewDone;
2555
+ if (!fitViewDone && fitViewOnInit) {
2556
+ nextFitViewDone = fitView(nextNodes, {
2557
+ ...fitViewOnInitOptions,
2558
+ nodes: fitViewOnInitOptions?.nodes || nextNodes,
2559
+ });
2560
+ }
2561
+ // here we are cirmumventing the onNodesChange handler
2562
+ // in order to be able to display nodes even if the user
2563
+ // has not provided an onNodesChange handler.
2564
+ // Nodes are only rendered if they have a width and height
2565
+ // attribute which they get from this handler.
2566
+ set({ nodes: nextNodes, fitViewDone: nextFitViewDone });
2567
+ if (changes?.length > 0) {
2568
+ onNodesChange?.(changes);
2569
+ }
2570
+ },
2571
+ updateNodePositions: (nodeDragItems, positionChanged = true, dragging = false) => {
2572
+ const changes = nodeDragItems.map((node) => {
2573
+ const change = {
2574
+ id: node.id,
2575
+ type: 'position',
2576
+ dragging,
2577
+ };
2578
+ if (positionChanged) {
2579
+ change.positionAbsolute = node.computed?.positionAbsolute;
2580
+ change.position = node.position;
2581
+ }
2582
+ return change;
2583
+ });
2584
+ get().triggerNodeChanges(changes);
2585
+ },
2586
+ triggerNodeChanges: (changes) => {
2587
+ const { onNodesChange, nodeLookup, nodes, hasDefaultNodes, nodeOrigin, elevateNodesOnSelect } = get();
2588
+ if (changes?.length) {
2589
+ if (hasDefaultNodes) {
2590
+ const updatedNodes = applyNodeChanges(changes, nodes);
2591
+ const nextNodes = adoptUserProvidedNodes(updatedNodes, nodeLookup, {
2592
+ nodeOrigin,
2593
+ elevateNodesOnSelect,
2594
+ });
2595
+ set({ nodes: nextNodes });
2596
+ }
2597
+ onNodesChange?.(changes);
2598
+ }
2599
+ },
2600
+ addSelectedNodes: (selectedNodeIds) => {
2601
+ const { multiSelectionActive, edges, nodes } = get();
2602
+ let changedNodes;
2603
+ let changedEdges = null;
2604
+ if (multiSelectionActive) {
2605
+ changedNodes = selectedNodeIds.map((nodeId) => createSelectionChange(nodeId, true));
2606
+ }
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
+ });
2617
+ },
2618
+ addSelectedEdges: (selectedEdgeIds) => {
2619
+ const { multiSelectionActive, edges, nodes } = get();
2620
+ let changedEdges;
2621
+ let changedNodes = null;
2622
+ if (multiSelectionActive) {
2623
+ changedEdges = selectedEdgeIds.map((edgeId) => createSelectionChange(edgeId, true));
2624
+ }
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
+ });
2635
+ },
2636
+ unselectNodesAndEdges: ({ nodes, edges } = {}) => {
2637
+ const { edges: storeEdges, nodes: storeNodes } = get();
2638
+ const nodesToUnselect = nodes ? nodes : storeNodes;
2639
+ const edgesToUnselect = edges ? edges : storeEdges;
2640
+ const changedNodes = nodesToUnselect.map((n) => {
2641
+ n.selected = false;
2642
+ return createSelectionChange(n.id, false);
2643
+ });
2644
+ const changedEdges = edgesToUnselect.map((edge) => createSelectionChange(edge.id, false));
2645
+ updateNodesAndEdgesSelections({
2646
+ changedNodes,
2647
+ changedEdges,
2648
+ get,
2649
+ set,
2650
+ });
2651
+ },
2652
+ setMinZoom: (minZoom) => {
2653
+ const { panZoom, maxZoom } = get();
2654
+ panZoom?.setScaleExtent([minZoom, maxZoom]);
2655
+ set({ minZoom });
2656
+ },
2657
+ setMaxZoom: (maxZoom) => {
2658
+ const { panZoom, minZoom } = get();
2659
+ panZoom?.setScaleExtent([minZoom, maxZoom]);
2660
+ set({ maxZoom });
2661
+ },
2662
+ setTranslateExtent: (translateExtent) => {
2663
+ get().panZoom?.setTranslateExtent(translateExtent);
2664
+ set({ translateExtent });
2665
+ },
2666
+ 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
+ });
2680
+ },
2681
+ setNodeExtent: (nodeExtent) => {
2682
+ const { nodes } = get();
2683
+ set({
2684
+ nodeExtent,
2685
+ nodes: nodes.map((node) => {
2686
+ const positionAbsolute = clampPosition(node.position, nodeExtent);
2687
+ return {
2688
+ ...node,
2689
+ computed: {
2690
+ ...node.computed,
2691
+ positionAbsolute,
2692
+ },
2693
+ };
2694
+ }),
2695
+ });
2696
+ },
2697
+ panBy: (delta) => {
2698
+ const { transform, width, height, panZoom, translateExtent } = get();
2699
+ return panBy({ delta, panZoom, transform, translateExtent, width, height });
2700
+ },
2701
+ fitView: (nodes, options) => {
2702
+ const { panZoom, width, height, minZoom, maxZoom, nodeOrigin } = get();
2703
+ if (!panZoom) {
2704
+ return false;
2705
+ }
2706
+ return fitView({
2707
+ nodes,
2708
+ width,
2709
+ height,
2710
+ panZoom,
2711
+ minZoom,
2712
+ maxZoom,
2713
+ nodeOrigin,
2714
+ }, options);
2715
+ },
2716
+ cancelConnection: () => set({
2717
+ connectionStatus: null,
2718
+ connectionStartHandle: null,
2719
+ connectionEndHandle: null,
2720
+ }),
2721
+ updateConnection: (params) => {
2722
+ const { connectionStatus, connectionStartHandle, connectionEndHandle, connectionPosition } = get();
2723
+ const currentConnection = {
2724
+ connectionPosition: params.connectionPosition ?? connectionPosition,
2725
+ connectionStatus: params.connectionStatus ?? connectionStatus,
2726
+ connectionStartHandle: params.connectionStartHandle ?? connectionStartHandle,
2727
+ connectionEndHandle: params.connectionEndHandle ?? connectionEndHandle,
2728
+ };
2729
+ set(currentConnection);
2730
+ },
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
+ },
2738
+ }), Object.is);
2739
+
2740
+ function ReactFlowProvider({ children, initialNodes, initialEdges, initialWidth, initialHeight, fitView, }) {
2741
+ const storeRef = useRef(null);
2742
+ if (!storeRef.current) {
2743
+ storeRef.current = createRFStore({
2744
+ nodes: initialNodes,
2745
+ edges: initialEdges,
2746
+ width: initialWidth,
2747
+ height: initialHeight,
2748
+ fitView,
2749
+ });
2750
+ }
2751
+ return jsx(Provider$1, { value: storeRef.current, children: children });
2752
+ }
2753
+ ReactFlowProvider.displayName = 'ReactFlowProvider';
2754
+
2755
+ function Wrapper({ children, nodes, edges, width, height, fitView, }) {
2756
+ const isWrapped = useContext(StoreContext);
2757
+ if (isWrapped) {
2758
+ // we need to wrap it with a fragment because it's not allowed for children to be a ReactNode
2759
+ // https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18051
2760
+ return jsx(Fragment, { children: children });
2761
+ }
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';
2794
+ }
2795
+
2796
+ const initNodeOrigin = [0, 0];
2797
+ const initDefaultViewport = { x: 0, y: 0, zoom: 1 };
2798
+ const wrapperStyle = {
2799
+ width: '100%',
2800
+ height: '100%',
2801
+ overflow: 'hidden',
2802
+ position: 'relative',
2803
+ zIndex: 0,
2804
+ };
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) => {
2806
+ const rfId = id || '1';
2807
+ 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';
2811
+
2812
+ const selector$8 = (s) => s.domNode?.querySelector('.react-flow__edgelabel-renderer');
2813
+ function EdgeLabelRenderer({ children }) {
2814
+ const edgeLabelRenderer = useStore(selector$8);
2815
+ if (!edgeLabelRenderer) {
2816
+ return null;
2817
+ }
2818
+ return createPortal(children, edgeLabelRenderer);
2819
+ }
2820
+
2821
+ const selector$7 = (s) => s.domNode?.querySelector('.react-flow__viewport-portal');
2822
+ function ViewportPortal({ children }) {
2823
+ const viewPortalDiv = useStore(selector$7);
2824
+ if (!viewPortalDiv) {
2825
+ return null;
2826
+ }
2827
+ return createPortal(children, viewPortalDiv);
2828
+ }
2829
+
2830
+ /**
2831
+ * Hook for updating node internals.
2832
+ *
2833
+ * @public
2834
+ * @returns function for updating node internals
2835
+ */
2836
+ function useUpdateNodeInternals() {
2837
+ const store = useStoreApi();
2838
+ return useCallback((id) => {
2839
+ const { domNode, updateNodeDimensions } = store.getState();
2840
+ const updateIds = Array.isArray(id) ? id : [id];
2841
+ const updates = new Map();
2842
+ updateIds.forEach((updateId) => {
2843
+ const nodeElement = domNode?.querySelector(`.react-flow__node[data-id="${updateId}"]`);
2844
+ if (nodeElement) {
2845
+ updates.set(updateId, { id: updateId, nodeElement, forceUpdate: true });
2846
+ }
2847
+ });
2848
+ requestAnimationFrame(() => updateNodeDimensions(updates));
2849
+ }, []);
2850
+ }
2851
+
2852
+ const nodesSelector = (state) => state.nodes;
2853
+ /**
2854
+ * Hook for getting the current nodes from the store.
2855
+ *
2856
+ * @public
2857
+ * @returns An array of nodes
2858
+ */
2859
+ function useNodes() {
2860
+ const nodes = useStore(nodesSelector, shallow);
2861
+ return nodes;
2862
+ }
2863
+
2864
+ const edgesSelector = (state) => state.edges;
2865
+ /**
2866
+ * Hook for getting the current edges from the store.
2867
+ *
2868
+ * @public
2869
+ * @returns An array of edges
2870
+ */
2871
+ function useEdges() {
2872
+ const edges = useStore(edgesSelector, shallow);
2873
+ return edges;
2874
+ }
2875
+
2876
+ const viewportSelector = (state) => ({
2877
+ x: state.transform[0],
2878
+ y: state.transform[1],
2879
+ zoom: state.transform[2],
2880
+ });
2881
+ /**
2882
+ * Hook for getting the current viewport from the store.
2883
+ *
2884
+ * @public
2885
+ * @returns The current viewport
2886
+ */
2887
+ function useViewport() {
2888
+ const viewport = useStore(viewportSelector, shallow);
2889
+ return viewport;
2890
+ }
2891
+
2892
+ /**
2893
+ * Hook for managing the state of nodes - should only be used for prototyping / simple use cases.
2894
+ *
2895
+ * @public
2896
+ * @param initialNodes
2897
+ * @returns an array [nodes, setNodes, onNodesChange]
2898
+ */
2899
+ function useNodesState(initialNodes) {
2900
+ const [nodes, setNodes] = useState(initialNodes);
2901
+ const onNodesChange = useCallback((changes) => setNodes((nds) => applyNodeChanges(changes, nds)), []);
2902
+ return [nodes, setNodes, onNodesChange];
2903
+ }
2904
+ /**
2905
+ * Hook for managing the state of edges - should only be used for prototyping / simple use cases.
2906
+ *
2907
+ * @public
2908
+ * @param initialEdges
2909
+ * @returns an array [edges, setEdges, onEdgesChange]
2910
+ */
2911
+ function useEdgesState(initialEdges) {
2912
+ const [edges, setEdges] = useState(initialEdges);
2913
+ const onEdgesChange = useCallback((changes) => setEdges((eds) => applyEdgeChanges(changes, eds)), []);
2914
+ return [edges, setEdges, onEdgesChange];
2915
+ }
2916
+
2917
+ /**
2918
+ * Hook for registering an onViewportChange handler.
2919
+ *
2920
+ * @public
2921
+ * @param params.onStart - gets called when the viewport starts changing
2922
+ * @param params.onChange - gets called when the viewport changes
2923
+ * @param params.onEnd - gets called when the viewport stops changing
2924
+ */
2925
+ function useOnViewportChange({ onStart, onChange, onEnd }) {
2926
+ const store = useStoreApi();
2927
+ useEffect(() => {
2928
+ store.setState({ onViewportChangeStart: onStart });
2929
+ }, [onStart]);
2930
+ useEffect(() => {
2931
+ store.setState({ onViewportChange: onChange });
2932
+ }, [onChange]);
2933
+ useEffect(() => {
2934
+ store.setState({ onViewportChangeEnd: onEnd });
2935
+ }, [onEnd]);
2936
+ }
2937
+
2938
+ /**
2939
+ * Hook for registering an onSelectionChange handler.
2940
+ *
2941
+ * @public
2942
+ * @params params.onChange - The handler to register
2943
+ */
2944
+ function useOnSelectionChange({ onChange }) {
2945
+ const store = useStoreApi();
2946
+ useEffect(() => {
2947
+ const nextOnSelectionChangeHandlers = [...store.getState().onSelectionChangeHandlers, onChange];
2948
+ store.setState({ onSelectionChangeHandlers: nextOnSelectionChangeHandlers });
2949
+ return () => {
2950
+ const nextHandlers = store.getState().onSelectionChangeHandlers.filter((fn) => fn !== onChange);
2951
+ store.setState({ onSelectionChangeHandlers: nextHandlers });
2952
+ };
2953
+ }, [onChange]);
2954
+ }
2955
+
2956
+ const selector$6 = (options) => (s) => {
2957
+ if (s.nodes.length === 0) {
2958
+ return false;
2959
+ }
2960
+ return s.nodes
2961
+ .filter((n) => (options.includeHiddenNodes ? true : !n.hidden))
2962
+ .every((n) => n[internalsSymbol]?.handleBounds !== undefined);
2963
+ };
2964
+ const defaultOptions = {
2965
+ includeHiddenNodes: false,
2966
+ };
2967
+ /**
2968
+ * Hook which returns true when all nodes are initialized.
2969
+ *
2970
+ * @public
2971
+ * @param options.includeHiddenNodes - defaults to false
2972
+ * @returns boolean indicating whether all nodes are initialized
2973
+ */
2974
+ function useNodesInitialized(options = defaultOptions) {
2975
+ const initialized = useStore(selector$6(options));
2976
+ return initialized;
2977
+ }
2978
+
2979
+ /**
2980
+ * Hook to check if a <Handle /> is connected to another <Handle /> and get the connections.
2981
+ *
2982
+ * @public
2983
+ * @param param.type - handle type 'source' or 'target'
2984
+ * @param param.nodeId - node id - if not provided, the node id from the NodeIdContext is used
2985
+ * @param param.id - the handle id (this is only needed if the node has multiple handles of the same type)
2986
+ * @param param.onConnect - gets called when a connection is established
2987
+ * @param param.onDisconnect - gets called when a connection is removed
2988
+ * @returns an array with connections
2989
+ */
2990
+ function useHandleConnections({ type, id = null, nodeId, onConnect, onDisconnect, }) {
2991
+ const _nodeId = useNodeId();
2992
+ const prevConnections = useRef(null);
2993
+ const currentNodeId = nodeId || _nodeId;
2994
+ const connections = useStore((state) => state.connectionLookup.get(`${currentNodeId}-${type}-${id}`), areConnectionMapsEqual);
2995
+ useEffect(() => {
2996
+ // @todo dicuss if onConnect/onDisconnect should be called when the component mounts/unmounts
2997
+ if (prevConnections.current && prevConnections.current !== connections) {
2998
+ const _connections = connections ?? new Map();
2999
+ handleConnectionChange(prevConnections.current, _connections, onDisconnect);
3000
+ handleConnectionChange(_connections, prevConnections.current, onConnect);
3001
+ }
3002
+ prevConnections.current = connections ?? new Map();
3003
+ }, [connections, onConnect, onDisconnect]);
3004
+ return useMemo(() => Array.from(connections?.values() ?? []), [connections]);
3005
+ }
3006
+
3007
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3008
+ function useNodesData(nodeIds) {
3009
+ const nodesData = useStore(useCallback((s) => {
3010
+ if (!Array.isArray(nodeIds)) {
3011
+ return s.nodeLookup.get(nodeIds)?.data || null;
3012
+ }
3013
+ const data = [];
3014
+ for (const nodeId of nodeIds) {
3015
+ const nodeData = s.nodeLookup.get(nodeId)?.data;
3016
+ if (nodeData) {
3017
+ data.push(nodeData);
3018
+ }
3019
+ }
3020
+ return data;
3021
+ }, [nodeIds]), shallow);
3022
+ return nodesData;
3023
+ }
3024
+
3025
+ const selector$5 = (s) => ({
3026
+ startHandle: s.connectionStartHandle,
3027
+ endHandle: s.connectionEndHandle,
3028
+ status: s.connectionStatus,
3029
+ position: s.connectionStartHandle ? s.connectionPosition : null,
3030
+ });
3031
+ /**
3032
+ * Hook for accessing the ongoing connection.
3033
+ *
3034
+ * @public
3035
+ * @returns ongoing connection: startHandle, endHandle, status, position
3036
+ */
3037
+ function useConnection() {
3038
+ const ongoingConnection = useStore(selector$5, shallow);
3039
+ return ongoingConnection;
3040
+ }
3041
+
3042
+ var BackgroundVariant;
3043
+ (function (BackgroundVariant) {
3044
+ BackgroundVariant["Lines"] = "lines";
3045
+ BackgroundVariant["Dots"] = "dots";
3046
+ BackgroundVariant["Cross"] = "cross";
3047
+ })(BackgroundVariant || (BackgroundVariant = {}));
3048
+
3049
+ function LinePattern({ dimensions, lineWidth, variant, className }) {
3050
+ 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
+ }
3052
+ function DotPattern({ radius, className }) {
3053
+ return (jsx("circle", { cx: radius, cy: radius, r: radius, className: cc(['react-flow__background-pattern', 'dots', className]) }));
3054
+ }
3055
+
3056
+ const defaultSize = {
3057
+ [BackgroundVariant.Dots]: 1,
3058
+ [BackgroundVariant.Lines]: 1,
3059
+ [BackgroundVariant.Cross]: 6,
3060
+ };
3061
+ const selector$4 = (s) => ({ transform: s.transform, patternId: `pattern-${s.rfId}` });
3062
+ function Background({ id, variant = BackgroundVariant.Dots,
3063
+ // only used for dots and cross
3064
+ gap = 20,
3065
+ // only used for lines and cross
3066
+ size, lineWidth = 1, offset = 2, color, bgColor, style, className, patternClassName, }) {
3067
+ const ref = useRef(null);
3068
+ const { transform, patternId } = useStore(selector$4, shallow);
3069
+ const patternSize = size || defaultSize[variant];
3070
+ const isDots = variant === BackgroundVariant.Dots;
3071
+ const isCross = variant === BackgroundVariant.Cross;
3072
+ const gapXY = Array.isArray(gap) ? gap : [gap, gap];
3073
+ const scaledGap = [gapXY[0] * transform[2] || 1, gapXY[1] * transform[2] || 1];
3074
+ const scaledSize = patternSize * transform[2];
3075
+ const patternDimensions = isCross ? [scaledSize, scaledSize] : scaledGap;
3076
+ const patternOffset = isDots
3077
+ ? [scaledSize / offset, scaledSize / offset]
3078
+ : [patternDimensions[0] / offset, patternDimensions[1] / offset];
3079
+ const _patternId = `${patternId}${id ? id : ''}`;
3080
+ return (jsxs("svg", { className: cc(['react-flow__background', className]), style: {
3081
+ ...style,
3082
+ ...containerStyle,
3083
+ '--xy-background-color-props': bgColor,
3084
+ '--xy-background-pattern-color-props': color,
3085
+ }, 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
+ }
3087
+ Background.displayName = 'Background';
3088
+ var Background$1 = memo(Background);
3089
+
3090
+ function PlusIcon() {
3091
+ 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" }) }));
3092
+ }
3093
+
3094
+ function MinusIcon() {
3095
+ return (jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 32 5", children: jsx("path", { d: "M0 0h32v4.2H0z" }) }));
3096
+ }
3097
+
3098
+ function FitViewIcon() {
3099
+ return (jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 32 30", children: jsx("path", { d: "M3.692 4.63c0-.53.4-.938.939-.938h5.215V0H4.708C2.13 0 0 2.054 0 4.63v5.216h3.692V4.631zM27.354 0h-5.2v3.692h5.17c.53 0 .984.4.984.939v5.215H32V4.631A4.624 4.624 0 0027.354 0zm.954 24.83c0 .532-.4.94-.939.94h-5.215v3.768h5.215c2.577 0 4.631-2.13 4.631-4.707v-5.139h-3.692v5.139zm-23.677.94c-.531 0-.939-.4-.939-.94v-5.138H0v5.139c0 2.577 2.13 4.707 4.708 4.707h5.138V25.77H4.631z" }) }));
3100
+ }
3101
+
3102
+ function LockIcon() {
3103
+ 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 0 8 0 4.571 3.429 4.571 7.619v3.048H3.048A3.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.047zm4.724-13.866H7.467V7.619c0-2.59 2.133-4.724 4.723-4.724 2.591 0 4.724 2.133 4.724 4.724v3.048z" }) }));
3104
+ }
3105
+
3106
+ function UnlockIcon() {
3107
+ 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
+ }
3109
+
3110
+ const ControlButton = ({ children, className, ...rest }) => (jsx("button", { type: "button", className: cc(['react-flow__controls-button', className]), ...rest, children: children }));
3111
+ ControlButton.displayName = 'ControlButton';
3112
+
3113
+ const selector$3 = (s) => ({
3114
+ isInteractive: s.nodesDraggable || s.nodesConnectable || s.elementsSelectable,
3115
+ minZoomReached: s.transform[2] <= s.minZoom,
3116
+ maxZoomReached: s.transform[2] >= s.maxZoom,
3117
+ });
3118
+ const Controls = ({ style, showZoom = true, showFitView = true, showInteractive = true, fitViewOptions, onZoomIn, onZoomOut, onFitView, onInteractiveChange, className, children, position = 'bottom-left', }) => {
3119
+ const store = useStoreApi();
3120
+ const { isInteractive, minZoomReached, maxZoomReached } = useStore(selector$3, shallow);
3121
+ const { zoomIn, zoomOut, fitView } = useReactFlow();
3122
+ const onZoomInHandler = () => {
3123
+ zoomIn();
3124
+ onZoomIn?.();
3125
+ };
3126
+ const onZoomOutHandler = () => {
3127
+ zoomOut();
3128
+ onZoomOut?.();
3129
+ };
3130
+ const onFitViewHandler = () => {
3131
+ fitView(fitViewOptions);
3132
+ onFitView?.();
3133
+ };
3134
+ const onToggleInteractivity = () => {
3135
+ store.setState({
3136
+ nodesDraggable: !isInteractive,
3137
+ nodesConnectable: !isInteractive,
3138
+ elementsSelectable: !isInteractive,
3139
+ });
3140
+ onInteractiveChange?.(!isInteractive);
3141
+ };
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);
3146
+
3147
+ function MiniMapNode({ id, x, y, width, height, style, color, strokeColor, strokeWidth, className, borderRadius, shapeRendering, selected, onClick, }) {
3148
+ const { background, backgroundColor } = style || {};
3149
+ const fill = (color || background || backgroundColor);
3150
+ return (jsx("rect", { className: cc(['react-flow__minimap-node', { selected }, className]), x: x, y: y, rx: borderRadius, ry: borderRadius, width: width, height: height, style: {
3151
+ fill,
3152
+ stroke: strokeColor,
3153
+ strokeWidth,
3154
+ }, shapeRendering: shapeRendering, onClick: onClick ? (event) => onClick(event, id) : undefined }));
3155
+ }
3156
+ var MiniMapNode$1 = memo(MiniMapNode);
3157
+
3158
+ const selector$2 = (s) => s.nodeOrigin;
3159
+ const selectorNodeIds = (s) => s.nodes.map((node) => node.id);
3160
+ const getAttrFunction = (func) => (func instanceof Function ? func : () => func);
3161
+ function MiniMapNodes({ nodeStrokeColor, nodeColor, nodeClassName = '', nodeBorderRadius = 5, nodeStrokeWidth,
3162
+ // We need to rename the prop to be `CapitalCase` so that JSX will render it as
3163
+ // a component properly.
3164
+ nodeComponent: NodeComponent = MiniMapNode$1, onClick, }) {
3165
+ const nodeIds = useStore(selectorNodeIds, shallow);
3166
+ const nodeOrigin = useStore(selector$2);
3167
+ const nodeColorFunc = getAttrFunction(nodeColor);
3168
+ const nodeStrokeColorFunc = getAttrFunction(nodeStrokeColor);
3169
+ const nodeClassNameFunc = getAttrFunction(nodeClassName);
3170
+ const shapeRendering = typeof window === 'undefined' || !!window.chrome ? 'crispEdges' : 'geometricPrecision';
3171
+ return (jsx(Fragment, { children: nodeIds.map((nodeId) => (
3172
+ // The split of responsibilities between MiniMapNodes and
3173
+ // NodeComponentWrapper may appear weird. However, it’s designed to
3174
+ // minimize the cost of updates when individual nodes change.
3175
+ //
3176
+ // For more details, see a similar commit in `NodeRenderer/index.tsx`.
3177
+ jsx(NodeComponentWrapper, { id: nodeId, nodeOrigin: nodeOrigin, nodeColorFunc: nodeColorFunc, nodeStrokeColorFunc: nodeStrokeColorFunc, nodeClassNameFunc: nodeClassNameFunc, nodeBorderRadius: nodeBorderRadius, nodeStrokeWidth: nodeStrokeWidth, NodeComponent: NodeComponent, onClick: onClick, shapeRendering: shapeRendering }, nodeId))) }));
3178
+ }
3179
+ const NodeComponentWrapper = memo(function NodeComponentWrapper({ id, nodeOrigin, nodeColorFunc, nodeStrokeColorFunc, nodeClassNameFunc, nodeBorderRadius, nodeStrokeWidth, shapeRendering, NodeComponent, onClick, }) {
3180
+ const { node, x, y } = useStore((s) => {
3181
+ const node = s.nodeLookup.get(id);
3182
+ const { x, y } = getNodePositionWithOrigin(node, node?.origin || nodeOrigin).positionAbsolute;
3183
+ return {
3184
+ node,
3185
+ x,
3186
+ y,
3187
+ };
3188
+ }, shallow);
3189
+ if (!node || node.hidden || !(node.computed?.width || node.width) || !(node.computed?.height || node.height)) {
3190
+ return null;
3191
+ }
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
+ });
3194
+ var MiniMapNodes$1 = memo(MiniMapNodes);
3195
+
3196
+ const defaultWidth = 200;
3197
+ const defaultHeight = 150;
3198
+ const selector$1 = (s) => {
3199
+ const viewBB = {
3200
+ x: -s.transform[0] / s.transform[2],
3201
+ y: -s.transform[1] / s.transform[2],
3202
+ width: s.width / s.transform[2],
3203
+ height: s.height / s.transform[2],
3204
+ };
3205
+ return {
3206
+ viewBB,
3207
+ boundingRect: s.nodes.length > 0 ? getBoundsOfRects(getNodesBounds(s.nodes, s.nodeOrigin), viewBB) : viewBB,
3208
+ rfId: s.rfId,
3209
+ nodeOrigin: s.nodeOrigin,
3210
+ panZoom: s.panZoom,
3211
+ translateExtent: s.translateExtent,
3212
+ flowWidth: s.width,
3213
+ flowHeight: s.height,
3214
+ };
3215
+ };
3216
+ const ARIA_LABEL_KEY = 'react-flow__minimap-desc';
3217
+ function MiniMap({ style, className, nodeStrokeColor, nodeColor, nodeClassName = '', nodeBorderRadius = 5, nodeStrokeWidth,
3218
+ // We need to rename the prop to be `CapitalCase` so that JSX will render it as
3219
+ // 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, }) {
3221
+ const store = useStoreApi();
3222
+ const svg = useRef(null);
3223
+ const { boundingRect, viewBB, rfId, panZoom, translateExtent, flowWidth, flowHeight } = useStore(selector$1, shallow);
3224
+ const elementWidth = style?.width ?? defaultWidth;
3225
+ const elementHeight = style?.height ?? defaultHeight;
3226
+ const scaledWidth = boundingRect.width / elementWidth;
3227
+ const scaledHeight = boundingRect.height / elementHeight;
3228
+ const viewScale = Math.max(scaledWidth, scaledHeight);
3229
+ const viewWidth = viewScale * elementWidth;
3230
+ const viewHeight = viewScale * elementHeight;
3231
+ const offset = offsetScale * viewScale;
3232
+ const x = boundingRect.x - (viewWidth - boundingRect.width) / 2 - offset;
3233
+ const y = boundingRect.y - (viewHeight - boundingRect.height) / 2 - offset;
3234
+ const width = viewWidth + offset * 2;
3235
+ const height = viewHeight + offset * 2;
3236
+ const labelledBy = `${ARIA_LABEL_KEY}-${rfId}`;
3237
+ const viewScaleRef = useRef(0);
3238
+ const minimapInstance = useRef();
3239
+ viewScaleRef.current = viewScale;
3240
+ useEffect(() => {
3241
+ if (svg.current && panZoom) {
3242
+ minimapInstance.current = XYMinimap({
3243
+ domNode: svg.current,
3244
+ panZoom,
3245
+ getTransform: () => store.getState().transform,
3246
+ getViewScale: () => viewScaleRef.current,
3247
+ });
3248
+ return () => {
3249
+ minimapInstance.current?.destroy();
3250
+ };
3251
+ }
3252
+ }, [panZoom]);
3253
+ useEffect(() => {
3254
+ minimapInstance.current?.update({
3255
+ translateExtent,
3256
+ width: flowWidth,
3257
+ height: flowHeight,
3258
+ inversePan,
3259
+ pannable,
3260
+ zoomStep,
3261
+ zoomable,
3262
+ });
3263
+ }, [pannable, zoomable, inversePan, zoomStep, translateExtent, flowWidth, flowHeight]);
3264
+ const onSvgClick = onClick
3265
+ ? (event) => {
3266
+ const [x, y] = minimapInstance.current?.pointer(event) || [0, 0];
3267
+ onClick(event, { x, y });
3268
+ }
3269
+ : undefined;
3270
+ const onSvgNodeClick = onNodeClick
3271
+ ? useCallback((event, nodeId) => {
3272
+ const node = store.getState().nodeLookup.get(nodeId);
3273
+ onNodeClick(event, node);
3274
+ }, [])
3275
+ : undefined;
3276
+ return (jsx(Panel, { position: position, style: {
3277
+ ...style,
3278
+ '--xy-minimap-mask-color-props': typeof maskColor === 'string' ? maskColor : undefined,
3279
+ '--xy-minimap-node-background-color-props': typeof nodeColor === 'string' ? nodeColor : undefined,
3280
+ '--xy-minimap-node-stroke-color-props': typeof nodeStrokeColor === 'string' ? nodeStrokeColor : undefined,
3281
+ '--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;
3307
+ }
3308
+
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
+ 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
+ const contextNodeId = useNodeId();
3318
+ const id = typeof nodeId === 'string' ? nodeId : contextNodeId;
3319
+ const store = useStoreApi();
3320
+ const resizeControlRef = useRef(null);
3321
+ const startValues = useRef(initStartValues);
3322
+ const prevValues = useRef(initPrevValues);
3323
+ const defaultPosition = variant === ResizeControlVariant.Line ? 'right' : 'bottom-right';
3324
+ const controlPosition = position ?? defaultPosition;
3325
+ useEffect(() => {
3326
+ if (!resizeControlRef.current || !id) {
3327
+ return;
3328
+ }
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) {
3398
+ const positionChange = {
3399
+ id: node.id,
3400
+ type: 'position',
3401
+ position: {
3402
+ x: isXPosChange ? x : prevX,
3403
+ y: isYPosChange ? y : prevY,
3404
+ },
3405
+ };
3406
+ changes.push(positionChange);
3407
+ prevValues.current.x = positionChange.position.x;
3408
+ prevValues.current.y = positionChange.position.y;
3409
+ }
3410
+ }
3411
+ if (isWidthChange || isHeightChange) {
3412
+ const dimensionChange = {
3413
+ id: id,
3414
+ type: 'dimensions',
3415
+ updateStyle: true,
3416
+ resizing: true,
3417
+ dimensions: {
3418
+ width: width,
3419
+ height: height,
3420
+ },
3421
+ };
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]);
3454
+ });
3455
+ selection.call(dragHandler);
3456
+ return () => {
3457
+ selection.on('.drag', null);
3458
+ };
3459
+ }, [
3460
+ id,
3461
+ controlPosition,
3462
+ minWidth,
3463
+ minHeight,
3464
+ maxWidth,
3465
+ maxHeight,
3466
+ keepAspectRatio,
3467
+ onResizeStart,
3468
+ onResize,
3469
+ onResizeEnd,
3470
+ ]);
3471
+ const positionClassNames = controlPosition.split('-');
3472
+ const colorStyleProp = variant === ResizeControlVariant.Line ? 'borderColor' : 'backgroundColor';
3473
+ const controlStyle = color ? { ...style, [colorStyleProp]: color } : style;
3474
+ return (jsx("div", { className: cc(['react-flow__resize-control', 'nodrag', ...positionClassNames, variant, className]), ref: resizeControlRef, style: controlStyle, children: children }));
3475
+ }
3476
+ var ResizeControl$1 = memo(ResizeControl);
3477
+
3478
+ const handleControls = ['top-left', 'top-right', 'bottom-left', 'bottom-right'];
3479
+ const lineControls = ['top', 'right', 'bottom', 'left'];
3480
+ 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
+ if (!isVisible) {
3482
+ return null;
3483
+ }
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)))] }));
3485
+ }
3486
+
3487
+ const selector = (state) => state.domNode?.querySelector('.react-flow__renderer');
3488
+ function NodeToolbarPortal({ children }) {
3489
+ const wrapperRef = useStore(selector);
3490
+ if (!wrapperRef) {
3491
+ return null;
3492
+ }
3493
+ return createPortal(children, wrapperRef);
3494
+ }
3495
+
3496
+ const nodeEqualityFn = (a, b) => a?.computed?.positionAbsolute?.x !== b?.computed?.positionAbsolute?.x ||
3497
+ a?.computed?.positionAbsolute?.y !== b?.computed?.positionAbsolute?.y ||
3498
+ a?.computed?.width !== b?.computed?.width ||
3499
+ a?.computed?.height !== b?.computed?.height ||
3500
+ a?.selected !== b?.selected ||
3501
+ a?.[internalsSymbol]?.z !== b?.[internalsSymbol]?.z;
3502
+ const nodesEqualityFn = (a, b) => {
3503
+ if (a.length !== b.length) {
3504
+ return false;
3505
+ }
3506
+ return !a.some((node, i) => nodeEqualityFn(node, b[i]));
3507
+ };
3508
+ const storeSelector = (state) => ({
3509
+ viewport: {
3510
+ x: state.transform[0],
3511
+ y: state.transform[1],
3512
+ zoom: state.transform[2],
3513
+ },
3514
+ nodeOrigin: state.nodeOrigin,
3515
+ selectedNodesCount: state.nodes.filter((node) => node.selected).length,
3516
+ });
3517
+ function NodeToolbar({ nodeId, children, className, style, isVisible, position = Position.Top, offset = 10, align = 'center', ...rest }) {
3518
+ const contextNodeId = useNodeId();
3519
+ const nodesSelector = useCallback((state) => {
3520
+ const nodeIds = Array.isArray(nodeId) ? nodeId : [nodeId || contextNodeId || ''];
3521
+ return nodeIds.reduce((acc, id) => {
3522
+ const node = state.nodeLookup.get(id);
3523
+ if (node) {
3524
+ acc.push(node);
3525
+ }
3526
+ return acc;
3527
+ }, []);
3528
+ }, [nodeId, contextNodeId]);
3529
+ const nodes = useStore(nodesSelector, nodesEqualityFn);
3530
+ const { viewport, nodeOrigin, selectedNodesCount } = useStore(storeSelector, shallow);
3531
+ // if isVisible is not set, we show the toolbar only if its node is selected and no other node is selected
3532
+ const isActive = typeof isVisible === 'boolean' ? isVisible : nodes.length === 1 && nodes[0].selected && selectedNodesCount === 1;
3533
+ if (!isActive || !nodes.length) {
3534
+ return null;
3535
+ }
3536
+ const nodeRect = getNodesBounds(nodes, nodeOrigin);
3537
+ const zIndex = Math.max(...nodes.map((node) => (node[internalsSymbol]?.z || 1) + 1));
3538
+ const wrapperStyle = {
3539
+ position: 'absolute',
3540
+ transform: getNodeToolbarTransform(nodeRect, viewport, position, offset, align),
3541
+ zIndex,
3542
+ ...style,
3543
+ };
3544
+ 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
+ }
3546
+
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 };