Workflow
Edge
Customizable edge components for React Flow canvases with animated and temporary states.
The Edge component provides two pre-styled edge types for React Flow canvases: Temporary for dashed temporary connections and Animated for connections with animated indicators.
Installation
npx ai-elements@latest add edgenpx shadcn@latest add @ai-elements/edgeimport { BaseEdge, type EdgeProps, getBezierPath, getSimpleBezierPath, type InternalNode, type Node, Position, useInternalNode,} from "@xyflow/react";const Temporary = ({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition,}: EdgeProps) => { const [edgePath] = getSimpleBezierPath({ sourceX, sourceY, sourcePosition, targetX, targetY, targetPosition, }); return ( <BaseEdge className="stroke-1 stroke-ring" id={id} path={edgePath} style={{ strokeDasharray: "5, 5", }} /> );};const getHandleCoordsByPosition = ( node: InternalNode<Node>, handlePosition: Position) => { // Choose the handle type based on position - Left is for target, Right is for source const handleType = handlePosition === Position.Left ? "target" : "source"; const handle = node.internals.handleBounds?.[handleType]?.find( (h) => h.position === handlePosition ); if (!handle) { return [0, 0]; } let offsetX = handle.width / 2; let offsetY = handle.height / 2; // this is a tiny detail to make the markerEnd of an edge visible. // The handle position that gets calculated has the origin top-left, so depending which side we are using, we add a little offset // when the handlePosition is Position.Right for example, we need to add an offset as big as the handle itself in order to get the correct position switch (handlePosition) { case Position.Left: offsetX = 0; break; case Position.Right: offsetX = handle.width; break; case Position.Top: offsetY = 0; break; case Position.Bottom: offsetY = handle.height; break; default: throw new Error(`Invalid handle position: ${handlePosition}`); } const x = node.internals.positionAbsolute.x + handle.x + offsetX; const y = node.internals.positionAbsolute.y + handle.y + offsetY; return [x, y];};const getEdgeParams = ( source: InternalNode<Node>, target: InternalNode<Node>) => { const sourcePos = Position.Right; const [sx, sy] = getHandleCoordsByPosition(source, sourcePos); const targetPos = Position.Left; const [tx, ty] = getHandleCoordsByPosition(target, targetPos); return { sx, sy, tx, ty, sourcePos, targetPos, };};const Animated = ({ id, source, target, markerEnd, style }: EdgeProps) => { const sourceNode = useInternalNode(source); const targetNode = useInternalNode(target); if (!(sourceNode && targetNode)) { return null; } const { sx, sy, tx, ty, sourcePos, targetPos } = getEdgeParams( sourceNode, targetNode ); const [edgePath] = getBezierPath({ sourceX: sx, sourceY: sy, sourcePosition: sourcePos, targetX: tx, targetY: ty, targetPosition: targetPos, }); return ( <> <BaseEdge id={id} markerEnd={markerEnd} path={edgePath} style={style} /> <circle fill="var(--primary)" r="4"> <animateMotion dur="2s" path={edgePath} repeatCount="indefinite" /> </circle> </> );};export const Edge = { Temporary, Animated,};Usage
import { Edge } from '@/components/ai-elements/edge';const edgeTypes = {
temporary: Edge.Temporary,
animated: Edge.Animated,
};
<Canvas
nodes={nodes}
edges={edges}
edgeTypes={edgeTypes}
/>Features
- Two distinct edge types: Temporary and Animated
- Temporary edges use dashed lines with ring color
- Animated edges include a moving circle indicator
- Automatic handle position calculation
- Smart offset calculation based on handle type and position
- Uses Bezier curves for smooth, natural-looking connections
- Fully compatible with React Flow's edge system
- Type-safe implementation with TypeScript
Edge Types
Edge.Temporary
A dashed edge style for temporary or preview connections. Uses a simple Bezier path with a dashed stroke pattern.
Edge.Animated
A solid edge with an animated circle that moves along the path. The animation repeats indefinitely with a 2-second duration, providing visual feedback for active connections.
Props
Both edge types accept standard React Flow EdgeProps:
Prop
Type