Skip to content

Flow Lanes

Show where a stream goes: one source fanning out to a lane per destination, each a stream of particles as dense as its rate.

import { FlowLane, FlowLanes } from '@youj/react'

Installation & usage

npm i @youj/react

For an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.

Use flow lanes for one stream split many ways, where the split is the story: a model router's traffic by model, a load balancer's pools, a queue's consumers, an inbox's routing rules. The Routing flow card is built on it. For a run of steps with branches use a Flow Graph; for shares without a source, a Share Bar.

import { FlowLanes } from '@youj/react'

<FlowLanes
  source="Gateway"
  label="Requests by model"
  lanes={[
    { id: 'pro', label: 'Kestrel 3 Pro', value: 47, tone: 'chart-1' },
    { id: 'orrery', label: 'Orrery 2', value: 137, tone: 'chart-2' },
  ]}
  formatValue={(v) => `${Math.round(v)}/s`}
/>

source names the node the lanes leave from. Each lane's value is its rate in any unit: it sets how many particles ride it (a share of the whole, at least one for any flow), the weight of its line and the share spoken with it. Lanes take the chart colors in order unless they set a tone. formatValue writes a rate with its unit. The particles stop while the chart is off screen or the tab is hidden, and paused stops them for good. No lanes, or nothing flowing, shows the empty state.

Reference

Propssource, lanes, active, onActiveChange, paused, formatValue…

Props

FlowLanes props
PropType
sourceRequiredstring

The node every lane leaves from, named over it: "Gateway".

–
lanesRequiredreadonly FlowLane[]–
activestring | null

The lane to light, by id (controlled); null for none.

–
defaultActivestring | null

The lane lit at first (uncontrolled).

default null

null
onActiveChange(id: string | null) => void

Called when pointing or focus moves to a lane, or off them (null).

–
pausedboolean

Stops the particles where they are. They also stop while the chart is off screen or the tab is hidden.

default false

false
formatValue(value: number) => string

Writes a rate with its unit: "57/s". Default: the locale's number format.

–
localestring

Default: the YoujProvider locale.

–
labelstring

Accessible name. Default: the labels' "Flow lanes".

–
configReadonly<Record<string, { color?: string }>>

A ChartConfig shared with your other charts: a lane whose id is a key takes its color, so one series matches across chart types.

–
Other props pass through: extends ComponentProps<'div'>.
StylingParts and data attributes

Styling

Parts: flow-lanes, flow-lanes-plot, flow-lanes-source, flow-lanes-source-node, flow-lanes-lane, flow-lanes-stream, flow-lanes-particles, flow-lanes-particle, flow-lanes-list, flow-lanes-item, flow-lanes-label, flow-lanes-value, flow-lanes-summary and flow-lanes-empty. While a lane is lit, its lane, particles and item have data-state="active" and the others data-state="inactive". The lane pitch is --flow-lanes-pitch (32px, 28px compact).

MotionDraw, stream, reweight · reduced motion

Motion

Motion tokens
MomentTokens
Drawthe lanes draw out from the source when a third of the chart scrolls into view, a lane after another
duration.deliberateease.enter

560ms · cubic-bezier(0.16, 1, 0.3, 1)

560mscubic-bezier(0.16, 1, 0.3, 1)
Streamparticles cross at one steady speed, a full width in six deliberate beats, fading in and out at the ends; they stop off screen
no token

linear, looping

linear, looping
Reweighta new rate thickens or thins the line and reseeds the stream
duration.slowease.standard

340ms · cubic-bezier(0.2, 0, 0, 1)

340mscubic-bezier(0.2, 0, 0, 1)
Pointingthe other lanes and their streams quiet
duration.fastease.standard

140ms · cubic-bezier(0.2, 0, 0, 1)

140mscubic-bezier(0.2, 0, 0, 1)

Reduced motion

Drawn in place; the particles rest on their lanes, spaced by the rate, so the density still reads.

Reduced motion

The lanes are drawn in place and the particles stand still on them, as many as the rate gives, so a busy lane still looks busy.

AccessibilityKeyboard, focus, screen readers

Accessibility

  • A named group (your label, or the labels' "Flow lanes") described by the source, how many lanes it feeds and their total ("Gateway to 4 lanes, 312/s in all.").
  • The lanes are a list; each is read with its name, rate and share ("Orrery 2: 137/s, 44%").
  • The names are one tab stop. The arrow keys, Home and End move between them, and focus lights the lane as pointing does.
  • The drawing and the particles are decorative; the list says the same in words. Color is never the only cue: every lane is named.
  • Its built-in text comes from the labels, so <YoujProvider labels> translates it.