Drag and Drop sidebar handling is not built in but can be implemented with the native HTML Drag and Drop API, as this example shows.
Drag and Drop Source Code
index.js
import React, { useState, useRef } from 'react';
import ReactFlow, {
ReactFlowProvider,
addEdge,
removeElements,
Controls,
} from 'react-flow-renderer';
import Sidebar from './Sidebar';
import './dnd.css';
const initialElements = [
{
id: '1',
type: 'input',
data: { label: 'input node' },
position: { x: 250, y: 5 },
},
];
let id = 0;
const getId = () => `dndnode_${id++}`;
const DnDFlow = () => {
const reactFlowWrapper = useRef(null);
const [reactFlowInstance, setReactFlowInstance] = useState(null);
const [elements, setElements] = useState(initialElements);
const onConnect = (params) => setElements((els) => addEdge(params, els));
const onElementsRemove = (elementsToRemove) =>
setElements((els) => removeElements(elementsToRemove, els));
const onLoad = (_reactFlowInstance) =>
setReactFlowInstance(_reactFlowInstance);
const onDragOver = (event) => {
event.preventDefault();
event.dataTransfer.dropEffect = 'move';
};
const onDrop = (event) => {
event.preventDefault();
const reactFlowBounds = reactFlowWrapper.current.getBoundingClientRect();
const type = event.dataTransfer.getData('application/reactflow');
const position = reactFlowInstance.project({
x: event.clientX - reactFlowBounds.left,
y: event.clientY - reactFlowBounds.top,
});
const newNode = {
id: getId(),
type,
position,
data: { label: `${type} node` },
};
setElements((es) => es.concat(newNode));
};
return (
<div className="dndflow">
<ReactFlowProvider>
<div className="reactflow-wrapper" ref={reactFlowWrapper}>
<ReactFlow
elements={elements}
onConnect={onConnect}
onElementsRemove={onElementsRemove}
onLoad={onLoad}
onDrop={onDrop}
onDragOver={onDragOver}
>
<Controls />
</ReactFlow>
</div>
<Sidebar />
</ReactFlowProvider>
</div>
);
};
export default DnDFlow;
Sidebar.js
import React from 'react';
export default () => {
const onDragStart = (event, nodeType) => {
event.dataTransfer.setData('application/reactflow', nodeType);
event.dataTransfer.effectAllowed = 'move';
};
return (
<aside>
<div className="description">You can drag these nodes to the pane on the right.</div>
<div className="dndnode input" onDragStart={(event) => onDragStart(event, 'input')} draggable>
Input Node
</div>
<div className="dndnode" onDragStart={(event) => onDragStart(event, 'default')} draggable>
Default Node
</div>
<div className="dndnode output" onDragStart={(event) => onDragStart(event, 'output')} draggable>
Output Node
</div>
</aside>
);
};