Flows
Where things go: splits, routes, loops and switchovers, with what moves along each path.
Installation & usage
npx @youj/cli add app-flowAlso installs alert, button, card, empty, segmented-control, skeleton, table, use-announcer, use-controllable-state, youj-core, youj-presets, youj-ui-core.
The CLI copies the block to blocks/app/flow.tsx with every component it uses, so it’s yours to edit.
Every prop is optional and falls back to the demo, so it renders as you see it until you pass your own. Give it your data, rewrite or translate its strings through copy, and connect its actions:
'use client'
import { Flow, type FlowProps } from '@/blocks/app/flow'
export function FlowView({ stages, nodes, paths, ranges }: Pick<FlowProps, 'stages' | 'nodes' | 'paths' | 'ranges'>) {
return (
<Flow
stages={stages}
nodes={nodes}
paths={paths}
ranges={ranges}
copy={{ title: 'Trial flow' }}
onRangeChange={(range) => {
// your code
}}
onSelectedChange={(id) => {
// your code
}}
onRetry={() => {
// your code
}}
/>
)
}Description
Where things go, as a sankey. Each path is a ribbon of its own in its source's colour all the way to the end, so a source can be followed past the first step. Point at a step to light every path through it, press it to keep them lit, or point at a ribbon to follow one path. A new range morphs the flow, and View data swaps in the table.
How a stream is routed across the places it can go, and what that costs; the default is a team's LLM traffic, and card payments or a water network read the same way. The blended cost leads, with how far a draft moves it from the live policy and the throughput, slow time and failure rate it blends to. Your own strategies (Cost, Balanced and Quality in the demo) reshape the split: the source fans out to each route as a stream as dense as its share. Below, the routes with share, typical / slow time, cost and failures, each lighting its lane, and the fallback rule as a sentence; Deploy policy makes the draft the next live version. It has loading, error and empty states that keep its size.
Work moving through steps, live: arrivals, triage and teams with items riding the routes between them, shown as a support desk, an emergency room and a parcel sorter. Pick a lens (volume, wait time, rejects), add people to a team over target or clear the rejects.
A vehicle's loop as a route map (the demo: a plant's milk run, with a school bus and a campus shuttle in the stories): stops done, the next one ringed, the rest hollow, and the vehicle where it is now, with the loop count and what is on board in the middle. Below it the stops still to come with what each gets and its arrival time, then Skip stop and Rush delivery. format.time reads the times, and loading, error and empty states take the map's place.
A primary source handing over to its backup, told live. Simulate an outage and watch the primary fail its checks, the load move onto the backup and then Switch back; every step lands on a timeline. The demo is a home riding through a power cut; stories show a database failing over and a branch office's fiber falling back to a cellular link.
Code
Flow, the Flow story: the files youj add writes.
blocks/app
Reference
Props21 props
Props
| Prop | Type | |
|---|---|---|
theme | ThemeInputWraps the card in this theme. Default: the theme around it. | – |
embedded | booleanInside another app: a default true | true |
fill | booleanTake the whole width it's given instead of stopping at its natural width (768px at 100% scale). default false | false |
headingLevel | 1 | 2 | 3The title's level. Default: 2 when embedded, else 1. | – |
copy | Partial<FlowCopy>Any of the card's strings, to rewrite or translate. | – |
locale | stringFormats every figure (BCP 47). Default: | – |
stages | string[]The stages' names, first to last. Default: the demo's Source, Plan and Outcome. | – |
nodes | Node[]The nodes, each in its stage, in the order they stack. Default: the demo's sources, plans and outcomes. | – |
paths | Path[]The routes through the stages and how many took each. Default: the demo's trials for the range shown. | – |
format | Intl.NumberFormatOptionsIntl.NumberFormat options for every figure. default whole numbers | whole numbers |
ranges | Range[]The ranges the switch offers, each | – |
range | stringThe id of the range shown, controlled: pair it with | – |
defaultRange | stringThe id of the range shown first, uncontrolled. Default: the first of your | – |
onRangeChange | (range: string) => voidCalled with the id of the range picked; answer with its | – |
selected | string | nullThe node kept lit, controlled ( | – |
defaultSelected | string | nullThe node kept lit first, uncontrolled. default null | null |
onSelectedChange | (id: string | null) => voidCalled with the node pressed, or | – |
loading | booleanA skeleton in place of the chart while your data loads. default false | false |
error | ReactNodeShown in place of the chart when the data fails to load, with Retry when | – |
onRetry | () => voidRetries after an | – |
empty | ReactNodeReplaces the message when nothing has flowed. Default: | – |
Strings26 keys for copy
Strings
copy takes any of these keys; the rest keep their defaults. A key whose text holds a value (a count, a name) takes a function.
titledescriptionrangecountchartnodesnodeonwardfrompartpatharrowsummaryviewDatahideDatatablecolumnFromcolumnTocolumnValuecolumnShareannouncementloadingretryemptyemptyDescriptionlocaleBuilt from7 components
Built from
Components used
Accessibilitygroups, keyboard, live regions, motion
Accessibility
The flow's ribbons are decorative. Its steps are buttons on one tab stop: Up and Down move along a stage, Left and Right go to the nearest step of the next or last stage, and each is named with its figure, its share and where its people went next (or, at the end, where they came from). Enter pins a step and Escape lets it go. A new range is announced with its total, and View data shows every step to step as a table.
Routing flow names its strategy switch (a segmented control whose segments are pressed buttons) and announces the new blended cost in a polite live region. The flow is a named group described by its source and total, with each route in a list read with its rate and share; the drawing is decorative. The routes are a table with a header per column, and the fallback rule is a labelled switch and two named selects that turn off with it. The head's badge and the foot's caption say in words whether the policy is live or a draft, and a failed deploy says why in its button.
Queue flow lays steps out as a labelled group of buttons with aria-pressed, spoken with their name, kind, health and figure; the arrow keys move along the flow. The lens switch is labelled, the overview is a labelled stat group, and a hidden table lists every figure.
Loop route draws the map as an image whose text gives how many stops are done and how many bins are on board, and the list under it names each stop's state in words (the ring and the filled dots only echo it). Skip stop and Rush delivery announce their result, and the vehicle's ring holds still under reduced motion.
Switchover announces each step as it is logged. The four stages are an ordered list with aria-current="step" on the current one, the timeline is a labelled group, each source's carried power is a labelled group and its checks are an image with a spoken label. The simulation holds while it is off screen or the tab is hidden.
Under reduced motion pulses and pings stop and everything else changes in place.