diff --git a/examples/react/src/App/routes.ts b/examples/react/src/App/routes.ts index d38f5449..2f3d55ba 100644 --- a/examples/react/src/App/routes.ts +++ b/examples/react/src/App/routes.ts @@ -43,6 +43,7 @@ import CancelConnection from '../examples/CancelConnection'; import InteractiveMinimap from '../examples/InteractiveMinimap'; import UseOnSelectionChange from '../examples/UseOnSelectionChange'; import NodeToolbar from '../examples/NodeToolbar'; +import UseConnection from '../examples/UseConnection'; import UseNodesInitialized from '../examples/UseNodesInit'; import UseNodesData from '../examples/UseNodesData'; import UseHandleConnections from '../examples/UseHandleConnections'; @@ -254,6 +255,11 @@ const routes: IRoute[] = [ path: 'update-node', component: UpdateNode, }, + { + name: 'useConnection', + path: 'use-connection', + component: UseConnection, + }, { name: 'useNodesInitialized', path: 'use-nodes-initialized', diff --git a/examples/react/src/examples/UseConnection/index.tsx b/examples/react/src/examples/UseConnection/index.tsx new file mode 100644 index 00000000..cc90f11f --- /dev/null +++ b/examples/react/src/examples/UseConnection/index.tsx @@ -0,0 +1,75 @@ +import { useCallback, useEffect } from 'react'; +import { + ReactFlow, + Background, + MiniMap, + Node, + addEdge, + ReactFlowProvider, + Edge, + useNodesState, + useEdgesState, + OnConnect, + useConnection, +} from '@xyflow/react'; + +const initialNodes: Node[] = [ + { + id: '1', + type: 'input', + data: { label: 'Node 1' }, + position: { x: 250, y: 5 }, + className: 'light', + }, + { + id: '2', + data: { label: 'Node 2' }, + position: { x: 100, y: 100 }, + className: 'light', + }, + { + id: '3', + data: { label: 'Node 3' }, + position: { x: 400, y: 100 }, + className: 'light', + }, +]; + +const initialEdges: Edge[] = [ + { id: 'e1-2', source: '1', target: '2' }, + { id: 'e1-3', source: '1', target: '3' }, +]; + +const UseZoomPanHelperFlow = () => { + const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); + const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); + + const onConnect: OnConnect = useCallback((params) => setEdges((eds) => addEdge(params, eds)), []); + const connection = useConnection(); + + useEffect(() => { + console.log('connection', connection); + }, [connection]); + + return ( + + + + + ); +}; + +const WrappedFlow = () => ( + + + +); + +export default WrappedFlow; diff --git a/packages/react/src/hooks/useConnection.ts b/packages/react/src/hooks/useConnection.ts new file mode 100644 index 00000000..641c22c8 --- /dev/null +++ b/packages/react/src/hooks/useConnection.ts @@ -0,0 +1,27 @@ +import { shallow } from 'zustand/shallow'; + +import { useStore } from './useStore'; +import type { ReactFlowStore } from '../types/store'; + +const selector = (s: ReactFlowStore) => ({ + startHandle: s.connectionStartHandle, + endHandle: s.connectionEndHandle, + status: s.connectionStatus, + position: s.connectionStartHandle ? s.connectionPosition : null, +}); + +/** + * Hook for accessing the ongoing connection. + * + * @returns ongoing connection: startHandle, endHandle, status, position + */ +export function useConnection(): { + startHandle: ReactFlowStore['connectionStartHandle']; + endHandle: ReactFlowStore['connectionEndHandle']; + status: ReactFlowStore['connectionStatus']; + position: ReactFlowStore['connectionPosition'] | null; +} { + const ongoingConnection = useStore(selector, shallow); + + return ongoingConnection; +} diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 9f30289d..c3baba48 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -25,6 +25,7 @@ export { default as useOnSelectionChange, type UseOnSelectionChangeOptions } fro export { default as useNodesInitialized, type UseNodesInitializedOptions } from './hooks/useNodesInitialized'; export { useHandleConnections } from './hooks/useHandleConnections'; export { useNodesData } from './hooks/useNodesData'; +export { useConnection } from './hooks/useConnection'; export { useNodeId } from './contexts/NodeIdContext'; export { applyNodeChanges, applyEdgeChanges, handleParentExpand } from './utils/changes';