State Flow
Graph-driven diagram for visualizing async UI state machines - idle, loading, success, and error paths with linear or expanded layout modes.
API Request Status
Simulated fetch lifecycle with auto-reset - linear mode for happy-path status indicators.
API request
Linear mode focuses on the happy path - ideal for fetch/submit status indicators that auto-reset after completion.
IdleClick to send request
>
LoadingCalling API...
>
SuccessResponse received
api-request-status-example.tsx
1"use client";23import { useEffect, useRef, useState } from "react";4import {5 StateFlowDiagram,6 type StateFlowState,7} from "@/registry/ui/state-flow";8import { MotionButton } from "./motion-button";910export function StateFlowApiRequestStatusExample() {11 const [state, setState] = useState<StateFlowState>("idle");12 const resetTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);1314 useEffect(() => {15 return () => {16 if (resetTimerRef.current) clearTimeout(resetTimerRef.current);17 };18 }, []);1920 const simulateRequest = async () => {21 if (resetTimerRef.current) clearTimeout(resetTimerRef.current);2223 setState("loading");2425 await new Promise((resolve) => setTimeout(resolve, 1200));2627 const success = Math.random() > 0.3;28 setState(success ? "success" : "error");2930 resetTimerRef.current = setTimeout(() => setState("idle"), 2000);31 };3233 return (34 <div className="space-y-6 rounded-lg border border-border p-6">35 <div className="space-y-1 text-center">36 <p className="text-sm font-medium text-foreground">API request</p>37 <p className="text-xs text-muted-foreground">38 Linear mode focuses on the happy path - ideal for fetch/submit status39 indicators that auto-reset after completion.40 </p>41 </div>4243 <StateFlowDiagram44 currentState={state}45 mode="linear"46 labels={{47 idle: "Click to send request",48 loading: "Calling API...",49 success: "Response received",50 error: "Request failed",51 }}52 />5354 <div className="flex justify-center">55 <MotionButton56 variant="info"57 onClick={simulateRequest}58 disabled={state === "loading"}59 >60 Trigger Request61 </MotionButton>62 </div>63 </div>64 );65}
Job Queue Visualizer
Background worker with success/failure branches - expanded mode for queue and retry flows.
Background job
Expanded mode shows the success path and failure branch together - useful for queue workers and retry flows.
IdleQueue idle
>
LoadingWorker processing job
>
SuccessJob completed
v
ErrorJob failed / retry needed
job-queue-visualizer-example.tsx
1"use client";23import { useEffect, useRef, useState } from "react";4import {5 StateFlowDiagram,6 type StateFlowState,7} from "@/registry/ui/state-flow";8import { MotionButton } from "./motion-button";910export function StateFlowJobQueueVisualizerExample() {11 const [state, setState] = useState<StateFlowState>("idle");12 const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);1314 useEffect(() => {15 return () => {16 if (timerRef.current) clearTimeout(timerRef.current);17 };18 }, []);1920 const runJob = () => {21 if (timerRef.current) clearTimeout(timerRef.current);2223 setState("loading");2425 timerRef.current = setTimeout(() => {26 setState(Math.random() < 0.6 ? "success" : "error");27 }, 1500);28 };2930 return (31 <div className="space-y-6 rounded-lg border border-border bg-slate-950 p-6">32 <div className="space-y-1 text-center">33 <p className="text-sm font-medium text-foreground">Background job</p>34 <p className="text-xs text-muted-foreground">35 Expanded mode shows the success path and failure branch together -36 useful for queue workers and retry flows.37 </p>38 </div>3940 <StateFlowDiagram41 currentState={state}42 mode="expanded"43 labels={{44 idle: "Queue idle",45 loading: "Worker processing job",46 success: "Job completed",47 error: "Job failed / retry needed",48 }}49 />5051 <div className="flex flex-wrap justify-center gap-3">52 <MotionButton53 variant="success"54 onClick={runJob}55 disabled={state === "loading"}56 >57 Run Job58 </MotionButton>5960 <MotionButton variant="neutral" onClick={() => setState("idle")}>61 Reset62 </MotionButton>63 </div>64 </div>65 );66}
Installation & source
Install via the shadcn CLI or copy the registry files manually.
bash
npx shadcn@latest add @tt-ui/state-flow
Props
| Name | Type | Default | Description |
|---|---|---|---|
| currentState | "idle" | "loading" | "success" | "error" | Required | The active state in the flow |
| mode | "linear" | "expanded" | "linear" | Linear shows the main chain only; expanded stacks branch nodes (e.g. error paths) |
| labels | { idle?: string; loading?: string; success?: string; error?: string } | undefined | Optional per-state description overrides under each node |