Skip to content

SIG—05 Signature system

FlowGraph

A node-and-wire editor: drag, wire with magnetic ports or the keyboard, refuse bad connections, watch runs flow and tidy into layers.

Live — this one is real

Scenario

Drag nodes; drag from an output diamond to an input to wire (or press Enter on an output, then on an input). Delete removes the selection. Loops are refused.

Trigger

New sign-up

From the web form

No inputs connected. Sends to Enrich profile.

Action

Enrich profile

Company size, region

Receives from New sign-up. Sends to Enterprise domain?.

Condition

Enterprise domain?

Receives from Enrich profile. Sends to Notify sales, Send welcome.

Action

Notify sales

#pipeline channel

Receives from Enterprise domain?. Sends to Offer a demo.

Action

Offer a demo

Calendar link, 3 slots

Receives from Notify sales. No outputs connected.

Email

Send welcome

Template: first-steps

Receives from Enterprise domain?. Sends to Wait 2 days.

Delay

Wait 2 days

Receives from Send welcome. Sends to Activated?.

Condition

Activated?

Receives from Wait 2 days. Sends to Send a nudge.

Email

Send a nudge

Template: getting-unstuck

Receives from Activated?. No outputs connected.

Arrow keys move the view, plus and minus zoom, 0 fits everything, 1 returns to 100%. Tab moves between items and the view follows.

Usage

tsx
import { FlowGraph } from "mizu-ui";

export function Example() {
  return (
    <FlowGraph
      label="Support intake"
      defaultNodes={[
        {
          id: "a",
          x: 0,
          y: 0,
          kind: "Trigger",
          label: "Form submitted",
          inputs: [],
        },
        { id: "b", x: 320, y: 0, kind: "Action", label: "Create ticket" },
        {
          id: "c",
          x: 640,
          y: 0,
          kind: "Email",
          label: "Confirm receipt",
          outputs: [],
        },
      ]}
      defaultEdges={[{ id: "ab", source: "a", target: "b" }]}
    />
  );
}

This code, running — no configuration beyond the data

Trigger

Form submitted

No inputs connected. Sends to Create ticket.

Action

Create ticket

Receives from Form submitted. No outputs connected.

Email

Confirm receipt

No inputs connected. No outputs connected.

Arrow keys move the view, plus and minus zoom, 0 fits everything, 1 returns to 100%. Tab moves between items and the view follows.

Keyboard

Enter
On an output: start a connection
Tab·Enter
Reach an input · connect
Esc
Cancel a connection
Delete
Remove the selected node or connection
←→↑↓
Nudge the focused node

Source & setup

Add this component to your project with the shadcn CLI. The command copies its source and styles into your configured UI directory.

sh
npx shadcn@latest add 0xuser64bit/mizu/flow-graph

For npm imports, import mizu-ui/styles.css once. Fonts are optional via mizu-ui/fonts.css. Override --mizu-* tokens or use className for local styling. Requires React and Motion.

Inspect signature/FlowGraph.tsx

Source is included in the npm package under src/signature/FlowGraph.tsx.

Open full source ↗

Props

PropTypeDefaultDescription
labelstring—Accessible name of the canvas.
nodes / defaultNodes / onNodesChangeFlowNode[]—id, x, y, label, kind, description, inputs, outputs and status.
edges / defaultEdges / onEdgesChangeFlowEdge[]—source, target, optional ports and label.
readOnlybooleanfalseWatch only: no dragging, wiring, tidying or deleting.
selected / defaultSelected / onSelectedChangestring | null—Selected node or connection id.
validateConnection(edge) => boolean | string—Refuse a wire; a string explains why.
renderNode / nodeWidth(node) => ReactNode / number— / 232Custom node heading and width.
tidyFlow(nodes, edges)function—The layered layout behind Tidy, for positioning stored graphs.

Accessibility

Nodes are named groups whose description lists what they receive from and send to. Output ports start a connection with Enter; input ports then become tabbable targets and Enter connects. Connections are focusable buttons. Refusals are alerts; connections and removals are announced.

Motion

Selection brackets snap in around a node, running nodes scan, and their outgoing wires carry flowing dashes. Wiring snaps magnetically to the nearest input. Tidy animates every node and wire together into layers, then frames the result.

Works alongside