Progress
Show how far a task has gotten, or that it's running when the end is unknown
Primitive
A progress bar shows how far a task has gotten. Use it for uploads, downloads, and exports, and pass value={null} until you can measure the work. For a static reading in a fixed range, use Meter instead.
Preview
Installation
Usage
Composition
The root puts the label and value on the first row and spans everything else below, so you don't need a wrapper. For a ring, swap the track for ProgressCircle:
Examples
Sizes
Use size to set the track thickness.
| Value | Description |
|---|---|
sm | 4px, for dense lists and rows. |
md | The default 6px track. |
lg | 10px, for a task in the spotlight. |
Variants
Use variant to color the indicator with the primary, neutral, or a status token.
| Value | Description |
|---|---|
default | The primary color. |
neutral | No hue, for quiet UI like lists and toasts. |
info | Background work, like indexing. |
success | A finished task. |
warning | A slow or retrying task. |
danger | A stalled or failed task. |
Indeterminate
Pass value={null} while the amount of work is unknown, and the indicator sweeps across the track.
Upload Lifecycle
Switch value from null to a number, then variant to "success", to walk a task from connecting to done.
Buffer
Set buffer on the root and place ProgressBuffer before the indicator to show a second value, like loaded media.
Circle
Use ProgressCircle in place of the track where a bar won't fit; a nested ProgressValue centers and scales with the ring. At value={null} it spins, so a small ring doubles as a spinner.
Attachment List
Give ProgressCircle a small size to fit a ring inline in a list row.
- launch-brief.pdf
- investor-deck.keyQueued
- call-notes.mdQueued
Custom Range and Format
Use min, max, and format to count in your own units.
Accessibility
Screen readers skip ProgressValue and read the root's value text instead. When the visible text adds context, like "1.4 GB of 4.2 GB", pass the same string through getAriaValueText.
With reduced motion on, the indicator jumps between values, and the indeterminate sweep and ring spin turn into a slow fade.
ProgressRoot renders a <div>. To put a ring inside a button, pass render={<span />} to keep the markup valid.
API Reference
The Progress component is built on top of Base UI's Progress. All Base UI props are supported. The documentation below only covers custom props and modified defaults specific to our implementation.
For the complete Base UI API, see the Base UI Progress documentation.
Props
ProgressRoot
Holds the value and lays out the parts. Wraps Base UI's Progress.Root.
ProgressTrack
The full range of the bar. Wraps Base UI's Progress.Track.
ProgressIndicator
The filled part of the track. Wraps Base UI's Progress.Indicator.
ProgressBuffer
The root's buffer, drawn behind the indicator. A plain <div>, hidden while indeterminate.
ProgressCircle
A ring drawn in place of the track, driven by the same root. A plain <span> holding an SVG.
ProgressValue
The formatted value text, hidden while indeterminate. Wraps Base UI's Progress.Value.
Data Attributes
| Attribute | Element | Description |
|---|---|---|
data-indeterminate | Base UI parts | Present while value is null. |
data-progressing | Base UI parts | Present while the value is below max. |
data-complete | Base UI parts | Present once the value reaches max. |
data-size | Root | The current size. |
data-empty | Root | Present while the value equals min. |
ProgressBuffer and ProgressCircle don't get the state attributes. Style them from the root with group-data-complete/progress: and the like.
CSS Variables
| Variable | Element | Description |
|---|---|---|
--progress-color | Root | Indicator and buffer color, set by variant. |
--progress-buffer | Root | The buffer value as a percentage of the track. |
--progress-percent | Root | The value as a unitless number from 0 to 100. |