Skip to main content
Version: 1.0.3

WorkflowBuilderLayout

The Workflow Builder Layout template provides the shell behind visual automation/workflow tools (n8n, Zapier, Node-RED): a node palette on the left, an optional inspector panel on the right, and a pannable, zoomable canvas in between. Nodes are placed via the nodes array, dragged by their header, and wired together by dragging from one node's output port to another node's input port.

verified
New Signup
Filter: Verified
Send Welcome Email
100%

Installation

ignix add component WorkflowBuilderLayout

Usage

import {
WorkflowBuilderLayout,
type WorkflowNodeData,
type WorkflowEdgeData,
type WorkflowPaletteItem,
} from '@ignix-ui/workflow-builder-layout';

Basic Usage

import { useState } from 'react';

function App() {
const [nodes, setNodes] = useState<WorkflowNodeData[]>([
{ id: 'trigger', x: 0, y: 0, title: 'New Signup' },
{ id: 'email', x: 300, y: 0, title: 'Send Email' },
]);
const [edges, setEdges] = useState<WorkflowEdgeData[]>([
{ id: 'trigger-email', source: 'trigger', target: 'email' },
]);

return (
<WorkflowBuilderLayout
nodes={nodes}
edges={edges}
onNodesChange={setNodes}
onConnect={(edge) => setEdges((prev) => [...prev, { id: `${edge.source}-${edge.target}`, ...edge }])}
/>
);
}

With a Palette and Inspector

<WorkflowBuilderLayout
nodes={nodes}
edges={edges}
onNodesChange={setNodes}
onConnect={handleConnect}
paletteItems={[
{ type: 'webhook', label: 'Webhook', icon: <Webhook className="h-4 w-4" /> },
{ type: 'email', label: 'Send Email', icon: <Mail className="h-4 w-4" /> },
]}
onPaletteItemDrop={(item, position) =>
setNodes((prev) => [...prev, { id: crypto.randomUUID(), x: position.x, y: position.y, title: item.label }])
}
selectedNodeId={selectedNodeId}
onNodeSelect={setSelectedNodeId}
inspector={selectedNode && <NodeSettingsForm node={selectedNode} onChange={updateSelectedNode} />}
/>

Controlled Viewport

import { useState } from 'react';

function App() {
const [viewport, setViewport] = useState({ x: 0, y: 0, zoom: 1 });

return (
<WorkflowBuilderLayout
nodes={nodes}
onNodesChange={setNodes}
viewport={viewport}
onViewportChange={setViewport}
/>
);
}

Interaction Reference

InputAction
Drag on empty canvasPan the canvas
Drag a node's headerMove that node
Drag from an output port to an input portCreate a connection between the two nodes
Drag a palette item onto the canvasDrop a new node at that position (requires onPaletteItemDrop)
Click a palette itemSelect it via onPaletteItemSelect (accessible alternative to dragging)
Mouse wheel / trackpad scrollPan the canvas
Ctrl/Cmd + wheelZoom toward the cursor
Arrow keys (canvas focused)Pan the canvas
Arrow keys (node focused)Nudge that node; hold Shift for a larger step
Delete / Backspace (node focused)Remove that node via onNodeDelete
Enter / Space (node focused)Select the node
EscapeCancel an in-progress connection drag
+ / - (canvas focused)Zoom in / out
0 (canvas focused)Reset to defaultViewport
Zoom control buttonsZoom in / out / reset

Props

WorkflowBuilderLayout

PropTypeDefaultDescription
headerReact.ReactNodeundefinedCustom node rendered at the start of the top toolbar (e.g. a logo/title)
actionsReact.ReactNodeundefinedOptional node rendered at the end of the top toolbar
paletteItemsWorkflowPaletteItem[]undefinedNode types listed in the left sidebar; omit or pass an empty array to hide it
onPaletteItemSelect(item: WorkflowPaletteItem) => voidundefinedCalled when a palette item is clicked
onPaletteItemDrop(item: WorkflowPaletteItem, position: { x: number; y: number }) => voidundefinedCalled with the dropped item and world-space drop position
showPalettebooleantrueWhether to render the palette sidebar when paletteItems is non-empty
nodesWorkflowNodeData[]The nodes currently on the canvas (this component is fully controlled)
edgesWorkflowEdgeData[][]Connections between nodes, rendered as curved lines between ports
onNodesChange(nodes: WorkflowNodeData[]) => voidundefinedCalled with the next nodes array after a drag or keyboard nudge
onNodeDelete(id: string) => voidundefinedCalled with a node's id when Delete/Backspace is pressed while it's focused
onConnect(connection: { source: string; target: string }) => voidundefinedCalled when a drag from an output port is released over an input port
selectedNodeIdstring | nullundefinedControlled selected node id; provide alongside onNodeSelect to drive selection externally
onNodeSelect(id: string | null) => voidundefinedCalled whenever the selected node changes, whether controlled or not
inspectorReact.ReactNodeundefinedContent rendered in the right panel while a node is selected
showNodeEditButtonbooleantrueWhether each node renders a pencil icon that selects it (opening inspector) without starting a drag; set to false when no inspector is wired up
viewportWorkflowViewportundefinedControlled pan/zoom state; provide alongside onViewportChange to drive the canvas externally
defaultViewportWorkflowViewportx: 0, y: 0, zoom: 1Initial pan/zoom state when uncontrolled, and the state "Reset view" returns to
onViewportChange(viewport: WorkflowViewport) => voidundefinedCalled whenever the viewport changes, whether controlled or not
minZoomnumber0.25Minimum zoom factor
maxZoomnumber2.5Maximum zoom factor
showGridbooleantrueWhether to render the background dot grid
gridSizenumber32Spacing between grid dots, in canvas world units
showControlsbooleantrueWhether to render the floating zoom in/out/reset control panel
classNamestringundefinedAdditional CSS classes applied to the root container

WorkflowNodeData

PropTypeDefaultDescription
idstringUnique node identifier
xnumberHorizontal position in the canvas's world space
ynumberVertical position in the canvas's world space
widthnumber220Node width in canvas world units
titlestringText shown in the node's header
iconReact.ReactNodeundefinedIcon shown before the title
status"idle" | "running" | "success" | "error"undefinedShows a colored status dot in the header when set
contentReact.ReactNodeundefinedOptional body content below the header
hasInputbooleantrueWhether to render an input port on the left edge
hasOutputbooleantrueWhether to render an output port on the right edge

WorkflowEdgeData

PropTypeDefaultDescription
idstringUnique edge identifier
sourcestringId of the node the edge starts from (its output port)
targetstringId of the node the edge ends at (its input port)
labelstringundefinedOptional text drawn at the midpoint of the edge

WorkflowPaletteItem

PropTypeDefaultDescription
typestringIdentifier used to look up the item on drop
labelstringText shown in the palette
iconReact.ReactNodeundefinedIcon shown before the label
descriptionstringundefinedSecondary text shown below the label

WorkflowViewport

PropTypeDescription
xnumberHorizontal pan offset, in pixels
ynumberVertical pan offset, in pixels
zoomnumberZoom factor (1 = 100%)