Skip to Content
ExamplesNodes

Node Toolbar

For many types of applications, having a toolbar or set of controls appear when a node is selected can be quite useful. It’s so useful, in fact, that we’ve built the <NodeToolbar /> component to make it easy to add this functionality to your custom nodes!

Content in the toolbar is not scaled as you zoom your flow in and out: this means it should always be visible.

import { useCallback } from 'react'; import { Background, ReactFlow, ReactFlowProvider, Panel, NodeToolbar, Position, useNodesState, } from '@xyflow/react'; import '@xyflow/react/dist/style.css'; const initialNodes = [ { id: '1', position: { x: 0, y: 0 }, type: 'node-with-toolbar', data: { label: 'Select me to show the toolbar' }, }, ]; const nodeTypes = { 'node-with-toolbar': NodeWithToolbar, }; function NodeWithToolbar({ data }) { return ( <> <NodeToolbar isVisible={data.forceToolbarVisible || undefined} position={data.toolbarPosition} > <button>cut</button> <button>copy</button> <button>paste</button> </NodeToolbar> <div>{data?.label}</div> </> ); } function Flow() { const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); const setPosition = useCallback( (pos) => setNodes((nodes) => nodes.map((node) => ({ ...node, data: { ...node.data, toolbarPosition: pos }, })), ), [setNodes], ); const forceToolbarVisible = useCallback((enabled) => setNodes((nodes) => nodes.map((node) => ({ ...node, data: { ...node.data, forceToolbarVisible: enabled }, })), ), ); return ( <ReactFlowProvider> <ReactFlow nodes={nodes} onNodesChange={onNodesChange} nodeTypes={nodeTypes} fitView style={{ backgroundColor: "#F7F9FB" }} preventScrolling={false} > <Panel> <h3>Node Toolbar position:</h3> <button onClick={() => setPosition(Position.Top)}>top</button> <button onClick={() => setPosition(Position.Right)}>right</button> <button onClick={() => setPosition(Position.Bottom)}>bottom</button> <button onClick={() => setPosition(Position.Left)}>left</button> <h3>Override Node Toolbar visibility</h3> <label> <input type="checkbox" onChange={(e) => forceToolbarVisible(e.target.checked)} /> <span>Always show toolbar</span> </label> </Panel> <Background /> </ReactFlow> </ReactFlowProvider> ); } export default Flow;

For more information on the <NodeToolbar /> component and its props, check out the API reference.

Last updated on