Node Header
A header designed to work with the <BaseNode />
component.
It can contain a title, icon, and list of actions.
Dependencies:
@xyflow/reactInstallation
Make sure to follow the prerequisites before installing the component.
npx shadcn@latest add https://ui.reactflow.dev/node-header
Usage
1. Copy the component into your app
import { memo } from "react";
import { NodeProps } from "@xyflow/react";
import { BaseNode } from "@/components/base-node";
import {
NodeHeader,
NodeHeaderTitle,
NodeHeaderActions,
NodeHeaderMenuAction,
NodeHeaderIcon,
NodeHeaderDeleteAction,
} from "@/components/node-header";
import {
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
} from "@/components/ui/dropdown-menu";
import { Rocket } from "lucide-react";
const NodeHeaderDemo = memo(({ selected }: NodeProps) => {
return (
<BaseNode selected={selected} className="px-3 py-2">
<NodeHeader className="-mx-3 -mt-2 border-b">
<NodeHeaderIcon>
<Rocket />
</NodeHeaderIcon>
<NodeHeaderTitle>Node Title</NodeHeaderTitle>
<NodeHeaderActions>
<NodeHeaderMenuAction label="Expand account options">
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Billing</DropdownMenuItem>
<DropdownMenuItem>Team</DropdownMenuItem>
<DropdownMenuItem>Subscription</DropdownMenuItem>
</NodeHeaderMenuAction>
<NodeHeaderDeleteAction />
</NodeHeaderActions>
</NodeHeader>
<div className="mt-2">Node Content</div>
</BaseNode>
);
});
export default NodeHeaderDemo;
2. Connect the component with your React Flow application.
import { Background, ReactFlow } from "@xyflow/react";
import NodeHeaderDemoNode from "./component-example";
const nodeTypes = {
nodeHeaderNode: NodeHeaderDemoNode,
};
const defaultNodes = [
{
id: "1",
type: "nodeHeaderNode",
position: { x: 200, y: 200 },
data: {},
},
];
export default function App() {
return (
<div className="h-full w-full">
<ReactFlow defaultNodes={defaultNodes} nodeTypes={nodeTypes} fitView>
<Background />
</ReactFlow>
</div>
);
}
Custom node actions
Many node header actions will be useful across multiple custom nodes. Below are some examples of custom node actions that you might define.
Custom Delete action
export type NodeHeaderCustomDeleteActionProps = Omit<
NodeHeaderActionProps,
'onClick'
>;
/**
* A custom delete action button that removes the node from the graph when clicked.
*/
export const NodeHeaderCustomDeleteAction = React.forwardRef<
HTMLButtonElement,
NodeHeaderCustomDeleteActionProps
>((props, ref) => {
const id = useNodeId();
const { setNodes } = useReactFlow();
const handleClick = useCallback(() => {
setNodes((prevNodes) => prevNodes.filter((node) => node.id !== id));
}, []);
return (
<NodeHeaderAction
ref={ref}
onClick={handleClick}
variant="ghost"
{...props}
>
<Trash />
</NodeHeaderAction>
);
});
NodeHeaderCustomDeleteAction.displayName = 'NodeHeaderCustomDeleteAction';
Copy action
export interface NodeHeaderCopyActionProps
extends Omit<NodeHeaderActionProps, 'onClick'> {
onClick?: (nodeId: string, event: React.MouseEvent) => void;
}
/**
* A copy action button that passes the node's id to the `onClick` handler when
* clicked.
*/
export const NodeHeaderCopyAction = React.forwardRef<
HTMLButtonElement,
NodeHeaderCopyActionProps
>(({ onClick, ...props }, ref) => {
const id = useNodeId();
const handleClick = useCallback(
(event: React.MouseEvent) => {
if (!onClick || !id) return;
onClick(id, event);
},
[onClick],
);
return (
<NodeHeaderAction
ref={ref}
onClick={handleClick}
variant="ghost"
{...props}
>
<Copy />
</NodeHeaderAction>
);
});
NodeHeaderCopyAction.displayName = 'NodeHeaderCopyAction';
Last updated on