Placeholder Node
A custom node that can be clicked to create a new node.
UI Component: placeholder-node
index.tsx
"use client";
import React, { useCallback, type ReactNode } from "react";
import {
useReactFlow,
useNodeId,
Handle,
Position,
type NodeProps,
} from "@xyflow/react";
import { BaseNode } from "@/registry/components/base-node";
export type PlaceholderNodeProps = Partial<NodeProps> & {
children?: ReactNode;
};
export function PlaceholderNode({ children }: PlaceholderNodeProps) {
const id = useNodeId();
const { setNodes, setEdges } = useReactFlow();
const handleClick = useCallback(() => {
if (!id) return;
setEdges((edges) =>
edges.map((edge) =>
edge.target === id ? { ...edge, animated: false } : edge,
),
);
setNodes((nodes) => {
const updatedNodes = nodes.map((node) => {
if (node.id === id) {
// Customize this function to update the node's data as needed.
// For example, you can change the label or other properties of the node.
return {
...node,
data: { ...node.data, label: "Node" },
type: "default",
};
}
return node;
});
return updatedNodes;
});
}, [id, setEdges, setNodes]);
return (
<BaseNode
className="bg-card w-[150px] border-dashed border-gray-400 p-2 text-center text-gray-400 shadow-none"
onClick={handleClick}
>
{children}
<Handle
type="target"
style={{ visibility: "hidden" }}
position={Position.Top}
isConnectable={false}
/>
<Handle
type="source"
style={{ visibility: "hidden" }}
position={Position.Bottom}
isConnectable={false}
/>
</BaseNode>
);
}component-example.tsx
import { memo } from "react";
import { PlaceholderNode } from "@/registry/components/placeholder-node";
const PlaceholderNodeDemo = memo(() => {
return (
<PlaceholderNode>
<div>+</div>
</PlaceholderNode>
);
});
PlaceholderNodeDemo.displayName = "PlaceholderNodeDemo";
export default PlaceholderNodeDemo;