Progress
Determinate and indeterminate progress bars. The indicator moves with transforms only, so it stays smooth under reduced motion and on low-power devices.
Preview
Live preview
Preparing workspace…
Usage
Examples
With a readable value
<Progress
value={45}
max={100}
valueText="45 of 100 uploads"
aria-label="Upload"
/>Indeterminate while working
{uploading && <Progress aria-label="Uploading" />}Sizing and color
<Progress value={80} variant="brand" size="lg" aria-label="Storage" />
<Progress value={30} variant="destructive" size="sm" aria-label="Errors" />Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| value | number | — | Current value clamped between 0 and max. Omit it for an indeterminate bar (no aria-valuenow). |
| max | number | 100 | Upper bound of the range, exposed as aria-valuemax. |
| valueText | string | — | Human readable value announced instead of the raw number, e.g. "45 of 100 uploads". |
| variant | "default" | "brand" | "destructive" | "default" | Color of the filled portion. |
| size | "sm" | "md" | "lg" | "md" | Track height. |
Accessibility
Accessibility notes
- Renders role="progressbar" with aria-valuemin, aria-valuemax and aria-valuenow.
- Always pass aria-label (or aria-labelledby) — a bare progress bar has no accessible name.
- valueText is what gets announced: prefer "45 of 100 uploads" over a bare number.
- Indeterminate bars omit aria-valuenow, which is how assistive tech recognises unknown duration.
- The indicator only animates transform, and the global reduced-motion override shortens it to 0.01ms.