- Start
- Branch A
- Branch B
- Branch C
- End
<script lang="ts">
import * as Flow from "kumo-svelte/components/flow";
</script>
<Flow.Root>
<Flow.Node>Start</Flow.Node>
<Flow.Parallel>
<Flow.Node>Branch A</Flow.Node>
<Flow.Node>Branch B</Flow.Node>
<Flow.Node>Branch C</Flow.Node>
</Flow.Parallel>
<Flow.Node>End</Flow.Node>
</Flow.Root>
Import
import * as Flow from "kumo-svelte/components/flow"; Usage
The Flow components work together to create directed flow diagrams. Use Flow as the container, Flow.Node for individual steps,
and Flow.Parallel to create branching paths.
<script lang="ts">
import * as Flow from "kumo-svelte/components/flow";
</script>
<Flow.Root>
<Flow.Node>Step 1</Flow.Node>
<Flow.Node>Step 2</Flow.Node>
<Flow.Node>Step 3</Flow.Node>
</Flow.Root> Examples
Sequential Flow
A simple linear flow with nodes connected in sequence.
- Step 1
- Step 2
- Step 3
<script lang="ts">
import * as Flow from "kumo-svelte/components/flow";
</script>
<Flow.Root>
<Flow.Node>Step 1</Flow.Node>
<Flow.Node>Step 2</Flow.Node>
<Flow.Node>Step 3</Flow.Node>
</Flow.Root>
Parallel Branches
Use Flow.Parallel to create branching paths that run in parallel.
- Start
- Branch A
- Branch B
- Branch C
- End
<script lang="ts">
import * as Flow from "kumo-svelte/components/flow";
</script>
<Flow.Root>
<Flow.Node>Start</Flow.Node>
<Flow.Parallel>
<Flow.Node>Branch A</Flow.Node>
<Flow.Node>Branch B</Flow.Node>
<Flow.Node>Branch C</Flow.Node>
</Flow.Parallel>
<Flow.Node>End</Flow.Node>
</Flow.Root>
Custom Node Styling
Use class and child content to customize node appearance. Flow.Node owns the list item and connector registration, so custom nodes stay ordinary Svelte markup.
- my-worker
<script lang="ts">
import * as Flow from "kumo-svelte/components/flow";
</script>
<Flow.Root>
<Flow.Node class="size-4 rounded-full bg-kumo-hairline p-0 shadow-none ring-0" />
<Flow.Node class="rounded-lg bg-kumo-contrast px-3 py-2 font-medium text-kumo-inverse">
my-worker
</Flow.Node>
</Flow.Root>
Centered Alignment
Use the align prop to vertically center nodes. This is useful when nodes have different heights.
- my-worker
- Taller node
<script lang="ts">
import * as Flow from "kumo-svelte/components/flow";
</script>
<Flow.Root align="center">
<Flow.Node class="size-4 rounded-full bg-kumo-hairline p-0 shadow-none ring-0" />
<Flow.Node>my-worker</Flow.Node>
<Flow.Node class="rounded-md bg-kumo-base px-3 py-6 shadow ring ring-kumo-hairline">
Taller node
</Flow.Node>
</Flow.Root>
Complex Flow
Combine sequential and parallel nodes to build complex workflows.
- HTTP Trigger
- Cron Trigger
- Process Request
- Log Analytics
- Update Cache
- Send Notification
- Complete
<script lang="ts">
import * as Flow from "kumo-svelte/components/flow";
</script>
<Flow.Root>
<Flow.Parallel>
<Flow.Node>HTTP Trigger</Flow.Node>
<Flow.Node>Cron Trigger</Flow.Node>
</Flow.Parallel>
<Flow.Node>Process Request</Flow.Node>
<Flow.Parallel>
<Flow.Node>Log Analytics</Flow.Node>
<Flow.Node>Update Cache</Flow.Node>
<Flow.Node>Send Notification</Flow.Node>
</Flow.Parallel>
<Flow.Node>Complete</Flow.Node>
</Flow.Root>
Custom Anchor Points
By default, connectors attach to the center of each node. Use Flow.Anchor to specify custom attachment points. The type prop controls whether the anchor serves as a "start" point or an "end" point.
- Load balancer
- DATABASE
- OTHER_SERVICE
<script lang="ts">
import * as Flow from "kumo-svelte/components/flow";
</script>
<Flow.Root>
<Flow.Node>Load balancer</Flow.Node>
<Flow.Node class="rounded-lg bg-kumo-overlay p-0 shadow-none ring ring-kumo-hairline">
<Flow.Anchor type="end" class="flex h-10 items-center px-2.5 text-kumo-subtle">
my-worker
</Flow.Anchor>
<Flow.Anchor type="start" class="m-1.5 mt-0 rounded bg-kumo-base px-2 py-1.5 shadow ring ring-kumo-hairline">
Bindings <span class="ml-3 w-5 text-kumo-subtle">2</span>
</Flow.Anchor>
</Flow.Node>
<Flow.Parallel>
<Flow.Node>DATABASE</Flow.Node>
<Flow.Node>OTHER_SERVICE</Flow.Node>
</Flow.Parallel>
</Flow.Root>
Panning Large Diagrams
When a diagram exceeds its container, Flow enables panning. Drag to pan the viewport, or use the scroll wheel.
- Start
- Authenticate
- Validate
- Transform
- Process
- Store
- Notify
- Log
- Complete
- End
<script lang="ts">
import * as Flow from "kumo-svelte/components/flow";
const steps = ["Start", "Authenticate", "Validate", "Transform", "Process", "Store", "Notify", "Log", "Complete", "End"];
</script>
<Flow.Root class="rounded-lg border border-kumo-hairline">
{#each steps as step}
<Flow.Node>{step}</Flow.Node>
{/each}
</Flow.Root>
Disabled Nodes
Use the disabled prop on a node to visually indicate it’s inactive. Connectors linking to disabled nodes are rendered with reduced opacity.
- Request
- Primary Handler
- Backup Handler (disabled)
- Response
<script lang="ts">
import * as Flow from "kumo-svelte/components/flow";
</script>
<Flow.Root>
<Flow.Node>Request</Flow.Node>
<Flow.Parallel>
<Flow.Node>Primary Handler</Flow.Node>
<Flow.Node disabled>Backup Handler (disabled)</Flow.Node>
</Flow.Parallel>
<Flow.Node>Response</Flow.Node>
</Flow.Root>
Parallel Node Alignment
Use the align prop on Flow.Parallel to control how nodes with different widths are aligned. Use "start" (default) to align left, or "end" to align right.
- Start
- Short
- Medium Length
- Very Long Node Name
- End
<script lang="ts">
import * as Flow from "kumo-svelte/components/flow";
</script>
<Flow.Root>
<Flow.Node>Start</Flow.Node>
<Flow.Parallel align="end">
<Flow.Node>Short</Flow.Node>
<Flow.Node>Medium Length</Flow.Node>
<Flow.Node>Very Long Node Name</Flow.Node>
</Flow.Parallel>
<Flow.Node>End</Flow.Node>
</Flow.Root>
Known Issue: Sidebar / Layout Shift
Toggling the sidebar shifts the Flow container’s viewport position. Connector coordinates should stay aligned through the layout shift and through scrolling while the sidebar is open.
Sidebar
- HTTP Request
- Auth Check
- Rate Limit
- Cache Lookup
- Route Handler
- Log
- Respond
<script lang="ts">
import SidebarSimpleIcon from "phosphor-svelte/lib/SidebarSimpleIcon";
import * as Flow from "kumo-svelte/components/flow";
const navItems = ["Overview", "Settings", "Logs", "Analytics"];
let sidebarOpen = $state(true);
</script>
<div class="relative flex min-h-64 flex-col overflow-hidden rounded-lg bg-kumo-base ring ring-kumo-hairline">
<div class="flex shrink-0 items-center gap-2 border-b border-kumo-hairline px-3 py-2">
<button
type="button"
class="flex items-center gap-1.5 rounded px-2 py-1 text-xs font-medium text-kumo-default transition-colors hover:bg-kumo-elevated"
onclick={() => (sidebarOpen = !sidebarOpen)}
>
<SidebarSimpleIcon class="size-4" />
{sidebarOpen ? "Close sidebar" : "Open sidebar"}
</button>
<span class="text-xs text-kumo-subtle">Toggle the sidebar — connectors should stay aligned</span>
</div>
<div class="flex min-h-0 flex-1">
<div
class="shrink-0 overflow-hidden border-r border-kumo-hairline bg-kumo-elevated transition-[width] duration-300"
style:width={sidebarOpen ? "160px" : "0px"}
>
<div class="w-40 space-y-1 p-3">
<p class="mb-2 text-xs font-semibold uppercase tracking-wide text-kumo-subtle">Sidebar</p>
{#each navItems as item}
<div class="cursor-default rounded px-2 py-1 text-sm text-kumo-default hover:bg-kumo-base">
{item}
</div>
{/each}
</div>
</div>
<div class="h-48 flex-1 overflow-auto p-4">
<Flow.Root>
<Flow.Node>HTTP Request</Flow.Node>
<Flow.Parallel>
<Flow.Node>Auth Check</Flow.Node>
<Flow.Node>Rate Limit</Flow.Node>
<Flow.Node>Cache Lookup</Flow.Node>
</Flow.Parallel>
<Flow.Node>Route Handler</Flow.Node>
<Flow.Parallel>
<Flow.Node>Log</Flow.Node>
<Flow.Node>Respond</Flow.Node>
</Flow.Parallel>
</Flow.Root>
</div>
</div>
</div>
Other Examples
Nested Node Lists in Parallel
Use Flow.List inside Flow.Parallel to create parallel branches where each branch contains a sequence of connected nodes.
- Client Users
- Engineering Team Access
- All Authenticated Users
- Client Users
- Site Users
- Contractor Access
- Destinations
<script lang="ts">
import * as Flow from "kumo-svelte/components/flow";
</script>
<Flow.Root>
<Flow.Parallel>
<Flow.List>
<Flow.Node>Client Users</Flow.Node>
<Flow.Node>Engineering Team Access</Flow.Node>
</Flow.List>
<Flow.List>
<Flow.Parallel>
<Flow.Node>All Authenticated Users</Flow.Node>
<Flow.Node>Client Users</Flow.Node>
<Flow.Node>Site Users</Flow.Node>
</Flow.Parallel>
<Flow.Node>Contractor Access</Flow.Node>
</Flow.List>
</Flow.Parallel>
<Flow.Node>Destinations</Flow.Node>
</Flow.Root>
API Reference
Flow
| Prop | Type | Default |
|---|---|---|
| align | FlowAlign | "start" |
| canvas | boolean | true |
| children | Snippet | — |
| class | string | — |
| onOverflowChange | (overflow: { x: boolean; y: boolean }) => void | — |
| orientation | FlowOrientation | "horizontal" |
| padding | { x?: number; y?: number } | — |
Flow.Anchor
| Prop | Type | Default |
|---|---|---|
| children | Snippet | — |
| class | string | — |
| type | FlowAnchorType | — |
Flow.Connectors
| Prop | Type | Default |
|---|---|---|
| children | Snippet | — |
| connectors* | FlowConnector[] | — |
| markerId | string | generatedMarkerId |
Flow.List
| Prop | Type | Default |
|---|---|---|
| children | Snippet | — |
| class | string | — |
| id | string | — |
Flow.Node
| Prop | Type | Default |
|---|---|---|
| children | Snippet | — |
| class | string | — |
| disabled | boolean | false |
| id | string | — |
Flow.Parallel
| Prop | Type | Default |
|---|---|---|
| align | FlowParallelAlign | "start" |
| children* | Snippet | — |
| id | string | — |