Progress Bar
A thin bar that reports a quantity, or sweeps when there is none to report. Two modes, one element.
API
Props
| prop | type | default | |
|---|---|---|---|
as? | ElementType | "div" | the element or component to render |
mode? | ProgressBarMode | "indeterminate" | determinate reports value, indeterminate sweeps |
value? | number | 0 | percentage, clamped between 0 and 100 |
animate? | boolean | true | when false, value changes are not transitioned |
fill? | string | the primary gradient | anything a background accepts: a colour, a gradient |
className? | string | — | merged over the defaults, so it wins |
Examples
Usage
<ProgressBar mode="determinate" value={uploaded} />
<ProgressBar />Details
The two modes
In determinate mode the fill is clipped to the percentage, and the clip transitions, so a value that moves reads as motion rather than as a jump. The value is clamped between 0 and 100, so an out of range number is a harmless bug instead of a broken bar.
In indeterminate mode — the default — a segment sweeps back and forth forever. It says only that something is happening, which is why it belongs to waits with no measurable end.
Accessibility follows the mode
The element is always a progressbar, but only determinate mode carries aria-valuenow with its minimum and maximum. Indeterminate deliberately carries none: an unknown quantity is announced by the absence of a value, not by a zero.
Fill and animation
fill takes anything a background accepts — a flat colour, another gradient, a token — and the component writes it into its own custom property. The default lives in the signature, so the gradient is discoverable from the props table rather than from the stylesheet.
<ProgressBar mode="determinate" value={62} fill="var(--margo-color-on-main)" />animate set to false removes the transition on the clip, which is what you want when the value comes from a scroll position or a drag: there the number is already continuous, and a transition would make it lag behind the input.
<ProgressBar mode="determinate" value={value} animate={false} />Not the navigation bar
This component reports a real quantity or an honest unknown. Route changes are neither: they have no measurable progress, but a sweeping bar reads as a stalled page. That is what NavigationBar is for — it simulates an approach that never reaches the end, then completes.