feat(build): Add custom node, edge components, and canvas mapping hook

Introduce `BuildCustomNode` and `BuildCustomEdge` components for enhanced React Flow visualizations, enabling node focus and styled edges. Implement `useCanvasMapping` hook to map and enhance nodes and edges dynamically with custom labels and styles.
This commit is contained in:
Andy Hooker
2025-02-22 17:16:16 -06:00
parent a692eedb1c
commit c178a537b7
3 changed files with 106 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
import React from "react";
import { EdgeProps, getBezierPath } from "@xyflow/react";
const BuildCustomEdge: React.FC<EdgeProps> = ({
id,
sourceX,
sourceY,
targetX,
targetY,
sourcePosition,
targetPosition,
style = {},
markerEnd,
}) => {
const [edgePath] = getBezierPath({
sourceX,
sourceY,
sourcePosition,
targetX,
targetY,
targetPosition,
});
return (
<>
<path
id={id}
style={{ ...style, stroke: "#888", strokeWidth: 2 }}
className="react-flow__edge-path"
d={edgePath}
markerEnd={markerEnd}
/>
</>
);
};
export default BuildCustomEdge;

View File

@@ -0,0 +1,35 @@
import React, { useCallback } from "react";
import { Handle, Position, useReactFlow, Node } from "@xyflow/react";
export interface BuildCustomNodeData extends Record<string, unknown> {
label: string; // Label to be displayed in the node
}
const BuildCustomNode: React.FC<Node<BuildCustomNodeData>> = ({ id, data }) => {
const { fitView } = useReactFlow();
const handleClick = useCallback(() => {
console.log(`Fitting view on Node: ${id}`);
fitView({ duration: 800 });
}, [id, fitView]);
return (
<div
style={{
border: "1px solid #ddd",
padding: "10px",
borderRadius: "4px",
background: "white",
}}
>
<Handle type="target" position={Position.Top} />
<div>{data.label}</div>
<button onClick={handleClick} style={{ marginTop: "5px" }}>
Focus Node
</button>
<Handle type="source" position={Position.Bottom} />
</div>
);
};
export default BuildCustomNode;

View File

@@ -0,0 +1,34 @@
import { useMemo } from "react";
import { Node, Edge } from "@xyflow/react";
interface UseCanvasMappingProps<T extends Record<string, unknown> = any> {
nodes: Node<T>[];
edges: Edge[];
}
export const useCanvasMapping = <T extends Record<string, unknown>>({
nodes,
edges,
}: UseCanvasMappingProps<T>) => {
// Map or enhance nodes
const mappedNodes = useMemo(
() =>
nodes.map((node) => ({
...node,
data: { ...node.data, label: `Mapped Node - ${node.id}` },
})),
[nodes],
);
// Map or enhance edges
const mappedEdges = useMemo(
() =>
edges.map((edge) => ({
...edge,
style: { ...edge.style, stroke: "#00f" },
})),
[edges],
);
return { mappedNodes, mappedEdges };
};