Progress
How far along something is, or that it is working and will end.
Try it
A change of value travels over the motion token, so a jump from 20 to 60 slides rather than snaps. The element is the native progress: the name, the value and the state are the platform’s, and what a screen reader is told changes with the bar.
Label and value
label is required: it is the element’s name, visible unless hideLabel, as under a file whose name is already the line above. showValue puts the value at the end of the label’s line, a percentage unless valueText says otherwise; valueText is also what a screen reader is told, so what is seen is what is said.
Sizes and tones
The tones are the Loader’s: one vocabulary for what is working. success is done and danger is failed; the fill is held to 3:1 against every surface it can stand on, in both modes. The track is the pressed wash, as the Skeleton’s fill: surface/sunken is the page in dark, where the wash lies over any surface.
Not known how far
Without a value a band crosses the track, in its own loop. Reduced motion holds it at the centre and lets it breathe: the travel is the movement the preference is about, and a still bar says nothing is happening.
Where it stands
Drawn under a file being uploaded: the name is the line above, so the label is hidden and the bar is the whole width of the words. It is a plain 4 with no value; the card says what is happening.
Drawn along the top edge of the onboarding, where the fill runs from cyan into the accent. That is not decoration (Fernando, 2026-09-22): the colour shifting as the bar grows says how close to the end you are. The theme has no gradient token, so the component ships none; the fill is --progress-fill, an image the caller composes from two tokens, here text/info into interactive/accent, and --progress-radius is 0 for a bar that is the page’s edge. The caller pins it.
Which one
| When | Use |
|---|---|
| How far along it is can be said: bytes sent, steps taken | Progress |
| Something is working and how far is not known, but it will end | Progress, with no value |
| Something is working and it is small: a button, a search | Loader |
| The layout of what is coming is known: a card, a row, a record | Skeleton |
Accessibility
A progressbar named by its label, with aria-valuetext when the value has words. The bar is not a live region: a reader who asks is told where it is, and one who does not is not interrupted at every percent. When it finishes, the caller says so, in a Toast or by what appears. The fill is a graphical object held to 3:1; the track is decoration, as the Loader’s.
Using it
import { Progress } from 'alpenglow';
// How far along, with the value in words.
<Progress label="Uploading xray31rt.pdf" value={bytesSent} max={bytes} showValue />
// Steps, said as steps.
<Progress label="Setting up" value={3} max={5} showValue valueText="3 of 5" />
// Not known how far: a band that crosses.
<Progress label="Importing" />
// Done, and failed.
<Progress label="Uploaded" value={100} tone="success" />
<Progress label="Upload failed" value={60} tone="danger" />
// Along the page's top edge: the label hidden, the corners square, the fill
// composed from two tokens. The caller pins it.
const onboarding = {
'--progress-radius': 0,
'--progress-fill': 'linear-gradient(90deg, var(--ap-color-text-info), var(--ap-color-interactive-accent))',
} as CSSProperties;
<Progress label="Onboarding" value={step} max={steps} hideLabel style={onboarding} />| Prop | Type | Default |
|---|---|---|
label | string | required |
hideLabel | boolean | false |
value | number | — (indeterminate) |
max | number | 100 |
showValue | boolean | false |
valueText | string — "3 of 5" | a percentage |
size | 'sm' | 'md' | 'sm' |
tone | 'accent' | 'neutral' | 'success' | 'danger' | 'accent' |
className, style | — |