Progress

How far along something is, or that it is working and will end.

Try it

Uploading xray31rt.pdf0%

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

Uploading xray31rt.pdf45%
Setting up your calendar3 of 5
45%

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

sm, 4 — as drawn60%
md, 8 — a bar that is the page’s subject60%
Uploaded100%
Upload failedFailed at 60%
Archived60%

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

Importing appointments

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

Justin - xray31rt.pdf

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.

Step 1 of 5: About you

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

Progress, Loader or Skeleton
WhenUse
How far along it is can be said: bytes sent, steps takenProgress
Something is working and how far is not known, but it will endProgress, with no value
Something is working and it is small: a button, a searchLoader
The layout of what is coming is known: a card, a row, a recordSkeleton

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

TSX
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} />
Progress props
PropTypeDefault
labelstringrequired
hideLabelbooleanfalse
valuenumber— (indeterminate)
maxnumber100
showValuebooleanfalse
valueTextstring — "3 of 5"a percentage
size'sm' | 'md''sm'
tone'accent' | 'neutral' | 'success' | 'danger''accent'
className, style—