Flow Studio
Adding Handles
CustomHandle is the Flow Studio wrapper around React Flow's Handle component. It adds visual styles (colour, shape, tooltip) and validation state (required, error port) on top of the standard connection point.
CustomHandle Props
// packages/flow-studio-designer/src/components/Handles/CustomHandle.tsx
interface CustomHandleProps {
type: 'source' | 'target';
position: Position; // Position.Left | Right | Top | Bottom
id: string; // portKey — must match ProcessElementPort.portKey
isMain?: boolean; // larger handle, bright colour (default: false)
isRequired?: boolean; // shows asterisk if no edge connected
isErrorPort?: boolean; // renders red (#f87171)
label?: string; // shown on hover
isMultiple?: boolean; // allows multiple edges (fan-in/fan-out)
}
Handle Visual States
| Prop Combination | Visual |
|---|---|
isMain: true | Larger (12px) white circle with accent glow |
isErrorPort: true | Red (#f87171) circle — always smaller regardless of isMain |
isRequired: true + no edge connected | Asterisk indicator + orange tint when validation runs |
| Default (none) | Small (8px) grey circle |
Multi-Port Node Example
// Node with main output and error output
renderBody() {
return (
<>
<CustomHandle type="target" position={Position.Left} id="main" isMain isRequired />
<div className="node-header">...</div>
<div className="node-body">...</div>
{/* Main success output */}
<CustomHandle type="source" position={Position.Right} id="main" isMain label="Success" />
{/* Error route output — positioned below the main handle */}
<CustomHandle type="source" position={Position.Right} id="error" isErrorPort label="On Error"
style={{ top: '75%' }} // offset to avoid overlap
/>
</>
);
}
id Must Match portKey
The
id prop on CustomHandle must exactly match the portKey defined in the NodeType's port array. React Flow uses this id as the sourceHandle or targetHandle on edges. A mismatch will cause edges to not connect correctly.