Progress
StableShows how far a task has gone: a linear bar in layouts, a circular ring in compact spots. Indeterminate when the duration is unknown.
When to use
Use it for
- Tasks that take more than about two seconds and report progress: publishing, importing from Figma, running contrast checks.
- Indeterminate (value null) when the task runs but its length is unknown.
- Switch tone to success or danger when the task ends, and say so in the label.
Not for
- Short waits or busy controls: use Spinner (or Button loading).
- Content that is loading into a layout: use Skeleton in the shape of the content.
- A static measurement like storage used or a score: that is a meter, not progress.
Do and don't
Every example is rendered with the real component, so it always matches what ships.
Label the task, show the value
"Publishing tokens 64%" tells users what is happening and how long is left.
Use counts when they mean more than percent
getAriaValueText and the label can say "12 of 40 pairs".
A progress bar that never moves
If you cannot report progress, use the indeterminate state rather than a fake value.
Accessibility
- Base UI Progress: role="progressbar" with aria-valuenow, aria-valuemin and aria-valuemax; indeterminate drops aria-valuenow.
- Needs a name: the label prop, or aria-label when there is no visible label (rings).
- The visible value text is aria-hidden; screen readers get it from aria-valuetext (customize with getAriaValueText).
- The fill uses the signal color with at least 3:1 against the track and surfaces.
- Under reduced motion the indeterminate bar stops sliding and shows a full, softened track instead.
Anatomy and tokens
Read from packages/react/src/components/Progress/Progress.module.css at build time. Every value is a token: open one to see its
alias chain in both themes.
- Root
.progress - success
.success - warning
.warning - danger
.danger - sm
.sm - lg
.lg - Label and value row
.header - Label
.label - Value text
.value, .ringValue - Track (linear)
.track - Fill (linear)
.indicator - Root
.progress[data-indeterminate] .indicator - circular
.circular - Ring track
.ringTrack - Ring fill
.ringFill - Root
.progress[data-indeterminate] .svg - Value inside the ring (lg)
.ringValue
Props
Parsed from the TypeScript types in packages/react/src/components/Progress/Progress.tsx, so this table cannot drift from the
code.
It also accepts every native <div> attribute except children.
| Prop | Type | Default | Description |
|---|---|---|---|
value required | number | null | none | Current value. `null` means indeterminate (the duration is unknown). |
min | number | 0 | No description in the code yet. |
max | number | 100 | No description in the code yet. |
label | ReactNode | none | Visible label, for example "Publishing tokens". Without it, pass aria-label. |
showValue | boolean | none | Show the formatted value ("64%") next to the label, or inside a large ring. Default true for linear with a label. |
variant | 'linear' | 'circular' | 'linear' | `linear` bar for tasks in a layout; `circular` ring for compact spots. Default `linear`. |
size | 'sm' | 'md' | 'lg' | 'md' | Bar thickness or ring diameter. Default `md`. |
tone | 'signal' | 'success' | 'warning' | 'danger' | 'signal' | Signal color while working; switch to success or danger when the task ends. Default `signal`. |
format | Intl.NumberFormatOptions | none | Intl number format for the value text. Default: percent of the range. |
getAriaValueText | (formattedValue: string, value: number | null) => string | none | Human-readable value for screen readers, for example "12 of 40 tokens". |
Playground
Change the props and see the real Progress update. Controls are generated from the TypeScript props; nothing here changes the system.
<Progress label="Publishing tokens" />Workbench
For contributors: every state with the accessibility panel, in the component workbench (Storybook). The stories double as visual test fixtures; the guidance on this page is the user documentation (open Progress in Storybook) .
Embed Storybook stories here (4)
Loads from https://bridge-storybook.floriangouloubi.com (set STORYBOOK_URL at build time). If Storybook is not running, the frames stay
empty.
Linear
Indeterminate
Circular
AllStates
Changelog
- New
Feedback: Alert (five tones, actions, dismiss, correct live region), Toast (ToastProvider and useToast with success, error, warning, info, promise, update and close), Progress (linear and circular, determinate and indeterminate), Skeleton, EmptyState, plus Spinner stories and guidance. Adds alert and skeleton component tokens.
Unreleased (current version 0.1.0, no release tagged yet) , Oct 17, 2026
- New
Bridge token system v1. Adds a brand mapping layer (`bridge` default, `ocean` alternate) between primitives and semantic tokens, a component tier (button, input, checkbox, switch, slider, card, popup, dialog, tooltip, toast, table, tabs, progress, nav), comfortable and compact density, motion durations and easings with a reduced-motion override, layers (z-index), icon sizes, breakpoints, a 1.2 type scale from 14px with tracking tokens, and self-hosted IBM Plex Sans and Mono (`@bridge-ds/tokens/fonts.css`). Primitives are regenerated in OKLCH on one lightness ladder. The build now writes `dist/resolved.json` and fails when any pair in `contrast.checks.json` drops below its WCAG minimum in any brand and theme. Fixes `color.border.strong` against `color.surface.default` (now at least 3:1 in both themes).
Unreleased (current version 0.1.0, no release tagged yet) , Oct 17, 2026