Progresscomponent
Progress({ value, min = 0, max = 100, ...props }: ProgressProps): ReactElement| Param | Type | |
|---|---|---|
props | ProgressProps | Props for Progress, a continuous horizontal progress bar. required |
.value | Nullish<number> | Position within the min–max range, or null/undefined/omitted for an indeterminate bar. |
.min | number | |
.max | number |
| Return | |
|---|---|
ReactElement | A progress bar element. |
Show progress as a single continuous horizontal bar, filled to value within the min–max range (matches getPercent() and formatPercent()).
- Renders a native
<progress>element, sorole="progressbar"and the value/max semantics come from the browser. <progress>has nominattribute (its implicit minimum is0), so the range is normalised tovalue - min/max - minbefore it's handed to the element.- The browser clamps
valueto the0–maxrange, so an out-of-rangevalueshows an empty or full bar rather than overspilling. - Omit
value(or passnull/undefined) to drop the attribute entirely — exactly as a native<progress>does, the element becomes:indeterminate(noaria-valuenow) and a block of fill colour flows across the track on a loop. - Paints from the tint ladder, so
color=/status=recolour the fill (and track) by moving the tint anchor.
A continuous horizontal progress bar for the completion of a task. Rendered as a native <progress> element, so the progressbar role and value/max semantics come from the browser rather than hand-written ARIA.
Things to know:
- Use
Progressfor task completion — a value heading toward "done" (an upload, a multi-step form, a load). For a static reading within a range that can move up and down (disk usage, a score), a gauge is the right model, not a progress bar. valueis filled within themin–maxrange (defaults0–100), matchinggetPercent()andformatPercent().<progress>has nominattribute, so the range is normalised tovalue - min/max - minbefore it reaches the element.- The browser clamps
valueto the0–maxrange, so an out-of-rangevaluerenders an empty or full bar rather than overspilling. A non-positive range (min === max) falls back to an empty bar rather than the indeterminate state. - Omit
value(or passnull/undefined) for an ongoing task whose duration isn't known — exactly like a native<progress>, dropping the attribute switches the element into the:indeterminatestate (noaria-valuenow), and a block of fill colour flows across the track on a loop.color=/status=still recolour it. The animation runs even underprefers-reduced-motion— movement is the indeterminate bar's only signal, and a frozen block would read as a stalled bar. aria-valuetextcarries the formatted percentage, so assistive tech announces e.g. "75%".- Paints from the tint ladder:
color=andstatus=move the tint anchor for the bar, so the fill (and track) re-derive together —status="success"gives a green bar,color="purple"a purple one. Without either, the bar takes the ambient tint (--tint-50, gray by default).
Usage
Basic
import { Progress } from "shelving/ui";
// 75% full.
<Progress value={3} max={4} />Custom range
import { Progress } from "shelving/ui";
// 50% full — value 15 within the 10–20 range.
<Progress value={15} min={10} max={20} />Status and colour
import { Progress } from "shelving/ui";
<Progress value={90} status="success" />
<Progress value={20} status="danger" />
<Progress value={60} color="purple" />Indeterminate
import { Progress } from "shelving/ui";
// No `value` → looping flow animation for a task of unknown duration.
<Progress />
// The flowing block still picks up status/colour.
<Progress status="success" />Styling
Progress paints a track (the element / ::-webkit-progress-bar) and a fill (::-webkit-progress-value / ::-moz-progress-bar) from the tint ladder. Apply color= / status= (on the bar or a tinted ancestor scope) to recolour the fill and track together — reach for a per-property hook only for a single surgical change. Override these hooks at :root (or any ancestor scope) to retheme.
| Variable | Styles | Default |
|---|---|---|
--progress-height | Bar thickness | 0.375rem (6px) |
--progress-radius | Corner radius | 999px (pill) |
--progress-background | Track fill | var(--tint-90) |
--progress-color | Fill colour | var(--tint-50) |
--progress-duration | Indeterminate flow-loop duration | 1.5s |
Global tokens it reads — move these to retheme broadly rather than overriding the hooks directly: the tint-ladder steps --tint-50 (fill) and --tint-90 (track), plus --duration-fast (the fill's grow transition). To recolour a bar, prefer color= / status= (or a tinted ancestor scope) over the per-component hooks.
/* Theme: a chunkier, square-cornered bar. */
:root {
--progress-height: 0.75rem;
--progress-radius: var(--radius-small);
}Examples
<Progress value={3} max={4} /><Progress value={90} status="success" /><Progress />