Skip to Content
ExamplesNodes

Add Node On Edge Drop

You can create a new node when you drop the connection line on the pane by using the onConnectStart and onConnectEnd handlers.

import React, { useCallback, useRef } from 'react'; import { Background, ReactFlow, useNodesState, useEdgesState, addEdge, useReactFlow, ReactFlowProvider, } from '@xyflow/react'; import '@xyflow/react/dist/style.css'; const initialNodes = [ { id: '0', type: 'input', data: { label: 'Node' }, position: { x: 0, y: 50 }, }, ]; let id = 1; const getId = () => `${id++}`; const nodeOrigin = [0.5, 0]; const AddNodeOnEdgeDrop = () => { const reactFlowWrapper = useRef(null); const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); const [edges, setEdges, onEdgesChange] = useEdgesState([]); const { screenToFlowPosition } = useReactFlow(); const onConnect = useCallback( (params) => setEdges((eds) => addEdge(params, eds)), [], ); const onConnectEnd = useCallback( (event, connectionState) => { // when a connection is dropped on the pane it's not valid if (!connectionState.isValid) { // we need to remove the wrapper bounds, in order to get the correct position const id = getId(); const { clientX, clientY } = 'changedTouches' in event ? event.changedTouches[0] : event; const newNode = { id, position: screenToFlowPosition({ x: clientX, y: clientY, }), data: { label: `Node ${id}` }, origin: [0.5, 0.0], }; setNodes((nds) => nds.concat(newNode)); setEdges((eds) => eds.concat({ id, source: connectionState.fromNode.id, target: id }), ); } }, [screenToFlowPosition], ); return ( <div className="wrapper" ref={reactFlowWrapper}> <ReactFlow style={{ backgroundColor: "#F7F9FB" }} nodes={nodes} edges={edges} onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onConnect={onConnect} onConnectEnd={onConnectEnd} fitView fitViewOptions={{ padding: 2 }} nodeOrigin={nodeOrigin} > <Background /> </ReactFlow> </div> ); }; export default () => ( <ReactFlowProvider> <AddNodeOnEdgeDrop /> </ReactFlowProvider> );
Last updated on