chore(react): add addNodeOnEdgeDrop example
This commit is contained in:
@@ -49,6 +49,7 @@ import UseConnection from '../examples/UseConnection';
|
||||
import UseNodesInitialized from '../examples/UseNodesInit';
|
||||
import UseNodesData from '../examples/UseNodesData';
|
||||
import UseHandleConnections from '../examples/UseHandleConnections';
|
||||
import AddNodeOnEdgeDrop from '../examples/AddNodeOnEdgeDrop';
|
||||
|
||||
export interface IRoute {
|
||||
name: string;
|
||||
@@ -57,6 +58,11 @@ export interface IRoute {
|
||||
}
|
||||
|
||||
const routes: IRoute[] = [
|
||||
{
|
||||
name: 'Add Node on edge Drop',
|
||||
path: 'add-node-edge-drop',
|
||||
component: AddNodeOnEdgeDrop,
|
||||
},
|
||||
{
|
||||
name: 'Basic',
|
||||
path: 'basic',
|
||||
|
||||
99
examples/react/src/examples/AddNodeOnEdgeDrop/index.tsx
Normal file
99
examples/react/src/examples/AddNodeOnEdgeDrop/index.tsx
Normal file
@@ -0,0 +1,99 @@
|
||||
import { useCallback, useRef } from 'react';
|
||||
import {
|
||||
ReactFlow,
|
||||
useNodesState,
|
||||
useEdgesState,
|
||||
addEdge,
|
||||
useReactFlow,
|
||||
ReactFlowProvider,
|
||||
OnConnect,
|
||||
OnConnectStart,
|
||||
OnConnectEnd,
|
||||
Node,
|
||||
Edge,
|
||||
} from '@xyflow/react';
|
||||
import '@xyflow/react/dist/style.css';
|
||||
|
||||
const initialNodes: Node[] = [
|
||||
{
|
||||
id: '0',
|
||||
type: 'input',
|
||||
data: { label: 'Node' },
|
||||
position: { x: 0, y: 50 },
|
||||
},
|
||||
];
|
||||
|
||||
const initialEdges: Edge[] = [];
|
||||
|
||||
let id = 1;
|
||||
const getId = () => `${id++}`;
|
||||
|
||||
const AddNodeOnEdgeDrop = () => {
|
||||
const reactFlowWrapper = useRef(null);
|
||||
const connectingNodeId = useRef<string | null>(null);
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
||||
const { screenToFlowPosition } = useReactFlow();
|
||||
const onConnect: OnConnect = useCallback((params) => {
|
||||
// reset the start node on connections
|
||||
connectingNodeId.current = null;
|
||||
setEdges((eds) => addEdge(params, eds));
|
||||
}, []);
|
||||
|
||||
const onConnectStart: OnConnectStart = useCallback((_, { nodeId }) => {
|
||||
connectingNodeId.current = nodeId;
|
||||
}, []);
|
||||
|
||||
const onConnectEnd: OnConnectEnd = useCallback(
|
||||
(event) => {
|
||||
if (!connectingNodeId.current) return;
|
||||
|
||||
const targetIsPane = (event.target as HTMLDivElement)?.classList.contains('react-flow__pane');
|
||||
|
||||
if (targetIsPane && 'clientX' in event && 'clientY' in event) {
|
||||
// we need to remove the wrapper bounds, in order to get the correct position
|
||||
const id = getId();
|
||||
const newNode: Node = {
|
||||
id,
|
||||
position: screenToFlowPosition({
|
||||
x: event.clientX,
|
||||
y: event.clientY,
|
||||
}),
|
||||
data: { label: `Node ${id}` },
|
||||
origin: [0.5, 0.0],
|
||||
};
|
||||
|
||||
const newEdge: Edge = {
|
||||
id,
|
||||
source: connectingNodeId.current,
|
||||
target: id,
|
||||
};
|
||||
|
||||
setNodes((nds) => nds.concat(newNode));
|
||||
setEdges((eds) => eds.concat(newEdge));
|
||||
}
|
||||
},
|
||||
[screenToFlowPosition]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="wrapper" ref={reactFlowWrapper} style={{ height: '100%' }}>
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
onConnect={onConnect}
|
||||
onConnectStart={onConnectStart}
|
||||
onConnectEnd={onConnectEnd}
|
||||
fitView
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default () => (
|
||||
<ReactFlowProvider>
|
||||
<AddNodeOnEdgeDrop />
|
||||
</ReactFlowProvider>
|
||||
);
|
||||
Reference in New Issue
Block a user