Progress bar
A thin bar that shows how far a task has run, or that it is running when the end is unknown. Use it for work in motion, not for a quantity at rest like storage used.
Live preview
Rendered by the component itself from the same generated tokens as the rest of the site.
<ProgressBar
label="Uploading report.pdf"
value={50}
helperText="About a minute left"
/>Installation
Install it with the shadcn CLI, along with everything it uses. New project? Set it up first, as Quick start shows.
npx shadcn@latest add https://www.graphite-ui.com/r/progress-bar.jsonimport { ProgressBar } from '@/components/ui/progress-bar'Anatomy
The label above the track, which is also its accessible name, and an optional helper below, 8 from it on each side. Nothing is ever painted inside the track.
- LabelRequiredThe task, painted above the track (beside it inline) and the bar's accessible name. hideLabel keeps the name and drops it from view.
- Helper textOptionalUnder the track, replaced by the success or error message once the task finishes. Not drawn inline.
Variants
Determinate when you know the total, indeterminate when you do not. Size is a 4px or 8px track. Alignment puts the label above, beside, or above and indented. Once the task ends, Success and Error fill the track and say so.
API reference
Generated from the contract, versioned with it, and checked by drift-check. This table cannot describe props the component does not have.
| Prop | Type | Default | Notes |
|---|---|---|---|
| value | 0–100 | — | |
| variant | 'determinate' | 'indeterminate' | — | |
| size | 'sm' | 'lg' | — | The kit's Size, a 4px track (Small) or 8px (Big). |
| alignment | 'default' | 'inline' | 'indent' | — | The kit's Alignment. Default puts the label above and the helper below, 8 from the track; Inline puts the label beside a track that fills the rest, with no helper; Indent sets the label in Input Label type and indents label and helper 16. |
| status | 'active' | 'success' | 'error' | — | The kit's State. A finished task fills the track in success or danger, with the kit's status icon at the end of the label row and its message in place of the helper. |
| hideLabel | boolean | — | |
| helperText | — | — | |
| successText | — | — | |
| errorText | — | — |
Design tokens
Every swatch is live. Change the source color in the header and this table repaints, because it reads the same roles the component does.
outlineThe track, through its subtle step (outline-subtle, the kit's border-subtle-00). It reads faintly against the page by design; the label and value carry the meaning.primaryThe fill while active.successThe fill and the status icon once the task succeeds.dangerThe fill, the status icon and the message once the task fails.on-surfaceThe label.on-surface-variantThe helper and success messages.textThe label at Body/3 (Input Label when indented), messages at 12/16.spacingTrack height, the 8 between label, track and message, and the 16 indent and inline gap.motionIndeterminate sweep duration and easing, defined once and shared with Spinner.radiusTrack and indicator corner.
Usage
The contract's prohibitions, written as the choices you will actually face.
Do
- Name the task in label and let the bar paint it. Use hideLabel only when a richer label already sits beside it, and the bar still keeps the name.
- Switch to determinate as soon as you know the total. A bar heading toward an end is easier to wait on.
- Name the task in label, like “Uploading report.pdf”, rather than “Progress”.
- Set status to success or error when the task ends, with a message that says what happened next.
Don’t
- Paint the percentage inside the bar. The track has no room and no slot for text; put it in the label or the helper.
- Turn the fill green or red while the task is still running. Success and danger are for a finished task only.
- Give the sweep its own duration or easing. The motion tokens set it once for every indeterminate indicator.
- Use it for a value that is not moving, like a quota. It announces as progress, so a reader waits for it to finish.
Accessibility
What the component does for you, and what it leaves to you.
- Roles
- role="progressbar" with aria-valuemin 0, aria-valuemax 100 and aria-valuenow set to the current value.
- Indeterminate
- All three value attributes are dropped. Leaving out aria-valuenow is what tells assistive tech the end is unknown.
- Labels
- label is required, painted, and names the bar through aria-labelledby; hideLabel keeps it as the name while dropping it from view. The helper, success or error message is linked with aria-describedby.
- Outcome
- Success and error set the value to 100 and announce their message as a status when it arrives. The status icon is decorative: the message carries the meaning.
- Values
- Values outside 0 to 100 are clamped before they reach the width or ARIA, so the two always agree.
- Motion
- The sweep is a quarter of the track at a constant speed, as the kit runs it. Under prefers-reduced-motion the width stops animating and the sweep slows to 3 seconds rather than stopping, so the bar still reads as working.
Figma parity
The kit's Progress bar page ships 31 variants across 3 sets. The code exposes 9 props. This table is where those two facts are reconciled instead of quietly diverging.
| Kit axis | Values | Code | How it maps |
|---|---|---|---|
| Progress | 0% · 25% · 50% · 75% · Indeterminate · Success · Error | value · variant · status | The percentages are value, and any number from 0 to 100 works. Indeterminate is variant="indeterminate". Success and Error are status. |
| State | Active · Success · Error | status | A finished bar fills in success or danger, with the kit’s status icon at the end of the label row and its message in place of the helper. |
| Size | Small · Big | size | sm and lg: a 4px or 8px track. |
| Alignment | Default · Inline · Indent | alignment | Label above; beside, hugging, 16 before the track and with no helper; or above in Input Label type with label and helper indented 16. The kit draws Inline only with a 4px track; the code allows either size. |
| Track | border-subtle-00 | — | outline-subtle, the kit’s value. It was outline, a much darker track, until 2.0.0. |
| Status icons · messages | Carbon status icons; Caption/1 and Helper Text | — | One 12/16 message style for all three; the kit’s own Succeeded and Failed status icons. |
