Progress
The Progress component shows users how far a task has come.
When to Use
- for a task that reports how much of it is done, such as “Uploading receipts” at 45%
- to show how much of a whole has been reached, such as the share of a project that is done
- as an indeterminate bar, for a task that has started and can’t be measured yet
When Not to Use
- for a wait with no measure in a small part, like a Badge (use a Spinner)
- for content whose layout is known while it loads (use a Skeleton)
- for a request that a Button started (use a Loading Button)
- for a value that users set (use a Slider)
| Spinner | Progress | Skeleton | |
|---|---|---|---|
| Purpose | A wait of unknown length | A task that reports how much of it is done | Content whose layout is known |
| Shape | An icon | A bar as wide as its container | A block sized by its classes |
| Role | status | progressbar | None |
| Name | “Loading”, from the Summit Provider | ProgressLabel or aria-label | None |
Anatomy
| Element | Usage |
|---|---|
| Label | Optional |
| Value | Optional |
| Track | Required |
| Indicator | Required |
Progress renders the track and the indicator, so you don’t need to add them. The label and the value are its children.
Show the label and the value with the bar. The label tells users what the bar measures, and the value tells them how far the task has come.
States
To show an indeterminate bar, pass value={null}. The indicator then fills the track and pulses. Set a number as soon as the task can be measured.
Behavior
The Progress component is as wide as its container.
Fill
The fill is value minus min, divided by max minus min, and it stops at the ends of the track. By default, min is 0 and max is 100.
Value
ProgressValue shows the fill as a percentage, such as “45%”, in the locale of the browser. To change the locale or the number format, set locale and format on Progress.
Content
| String | Rule | Example | Counterexample |
|---|---|---|---|
| Label | Name the task that is running | “Uploading receipts” | “Progress” |
Accessibility
The Progress component isn’t focusable and has no keys.
The Progress component needs a name so that screen readers can announce what it measures. To provide one, add a
ProgressLabel or set aria-label. WCAG 2.2 SC 1.1.1 Non-text Content requires a text alternative for content that isn’t text,
and ARIA 1.2 requires a name for the role.
Installation
npx shadcn@latest add @summit/progressUsage
import { Progress, ProgressLabel, ProgressValue } from '@/components/ui/progress';
<Progress value={45}>
<ProgressLabel>Uploading receipts</ProgressLabel>
<ProgressValue />
</Progress>;Without a Visible Label
If a heading or a sentence next to the bar already names the task, name the bar with aria-label.
<Progress value={30} aria-label="Upload progress" />A Range
To set the ends of the range, pass min and max. The bar in this example is half full.
<Progress value={6} min={0} max={12}>
<ProgressLabel>Invoices sent</ProgressLabel>
</Progress>Indeterminate
Pass null until the task reports a value.
<Progress value={null} aria-label="Upload progress" />Color the Indicator
To replace the primary fill, pass a class in indicatorClassName. The fill needs a contrast of 3 to 1 on the muted track so that users with low vision can see how far it reaches, as WCAG 2.2 SC 1.4.11 Non-text Contrast requires. chart-1 meets that floor in light and in dark.
<Progress value={75} indicatorClassName="bg-chart-1">
<ProgressLabel>Website and brand</ProgressLabel>
<ProgressValue />
</Progress>API Reference
The parts accept the props of their matching parts in Base UI’s Progress, where Progress is Progress.Root.
Progress
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | null | Required | The current value. If it is null, the bar is indeterminate. |
min | number | 0 | The value of an empty bar |
max | number | 100 | The value of a full bar |
indicatorClassName | string | None | Classes for the indicator |
See the Base UI Progress documentation for format, locale, and getAriaValueText.