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