Portal Community

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 CombinationVisual
isMain: trueLarger (12px) white circle with accent glow
isErrorPort: trueRed (#f87171) circle — always smaller regardless of isMain
isRequired: true + no edge connectedAsterisk 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.