Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.
"use client";
import "@xyflow/react/dist/style.css";
import {
addEdge,
applyEdgeChanges,
applyNodeChanges,
Background,
type Connection,
type EdgeChange,
type Node,
type NodeChange,
type NodeProps,
type NodeTypes,
ReactFlow,
ReactFlowProvider,
} from "@xyflow/react";
import { useCallback, useState } from "react";
import { ResizableNode } from "@/components/ui/flow/resizable-node";
const TextResizableNode = (props: NodeProps<Node>) => {
return (
<ResizableNode
selected={props.selected}
className="flex flex-col items-center justify-center p-4"
>
<span>{props.data.value as string}</span>
</ResizableNode>
);
};
const nodeTypes: NodeTypes = {
"text-resizable-node": TextResizableNode,
};
const initialNodes = [
{
id: "node-1",
type: "text-resizable-node",
position: { x: 0, y: 0 },
data: { value: "Try to resize me" },
},
];
export function ResizableNodeDemo() {
const [nodes, setNodes] = useState<Node[]>(initialNodes);
const [edges, setEdges] = useState([]);
// Add default viewport configuration
const defaultViewport = { x: 100, y: 150, zoom: 1 };
const onNodesChange = useCallback(
(changes: NodeChange<Node>[]) =>
setNodes((nds) => applyNodeChanges(changes, nds)),
[],
);
const onEdgesChange = useCallback(
(changes: EdgeChange<never>[]) =>
setEdges((eds) => applyEdgeChanges(changes, eds)),
[],
);
const onConnect = useCallback(
(connection: Connection) => setEdges((eds) => addEdge(connection, eds)),
[],
);
return (
<div className="w-full h-full">
<ReactFlowProvider>
<ReactFlow
nodes={nodes}
edges={edges}
onNodesChange={onNodesChange}
onEdgesChange={onEdgesChange}
onConnect={onConnect}
nodeTypes={nodeTypes}
defaultViewport={defaultViewport}
/* fitView */
>
<Background />
</ReactFlow>
</ReactFlowProvider>
</div>
);
}
Overview
The Resizable Node is a simple wrapper component that adds resizing functionality to other nodes in your React Flow application. It provides:
- Resize handles that appear when the node is selected
- Built-in size constraints for consistent node sizes
- Integration with React Flow's base node system
Components Used
This node is built using several React Flow Components:
- Base Node - For the core node structure and styling
- Node Resizer - For the resizing functionality
Installation
pnpm dlx shadcn@latest add @simple-ai/resizable-node
Usage
The Resizable Node is designed to wrap other node content to make it resizable. Here's how to use it in your React Flow application:
// Example of a custom node using ResizableNode
const TextResizableNode = (props: NodeProps<Node>) => {
return (
<ResizableNode
selected={props.selected}
className="flex flex-col items-center justify-center p-4"
>
<span>{props.data.value as string}</span>
</ResizableNode>
);
};
// Register the node type
const nodeTypes = {
"text-resizable-node": TextResizableNode,
};The node includes the following features:
- Size constraints (min: 250x200px, max: 800x800px)
- Resize handles visible on selection
- Hover effect with orange highlight
- Customizable through className prop