Progress
Preview appears after the next Storybook update.
<Progress />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.
Content guidelines
- Labels use the present participle of the action: "Publishing tokens", "Importing variables".
- When done, change the label to the outcome: "Published".
From the code Generated from the component, not editable here.
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
Motion and interaction
Progress loops while it is shown. Try it in the preview at the top.
| Part | When | What changes | Duration | Easing |
|---|---|---|---|---|
| Linear | While shown | Loops (slide) | motion.duration.shimmer1400 ms | Part of the loop |
| Circular | While shown | Loops (spin) | motion.duration.spin700 ms | Part of the loop |
With reduced motion turned on, the loop stops and the spinner keeps turning, slower, so it never looks frozen.
It also uses motion.duration.moderate for motion this table does not list yet.
From the code Generated from the component, not editable here.
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 |
|---|---|---|---|
valuerequired | 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
From the code Generated from the component, not editable here.
Changelog
- New
The measure now writes the Figma sets drawn under a component's folder as their own entries, so Claude can fix them: popups drawn open (Dialog/Popup, AlertDialog/Popup, Drawer/Popup, Menu/Popup, Popover/Popup, Tooltip/Popup, and Select/Popup or Combobox/Popup, measured open when the stories show them closed) and sets that fix a prop (Pagination/Full, Pagination/Compact, Progress/Linear)
v1.0.0, Nov 11, 2026
- 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
v1.0.0, Nov 11, 2026
- New
One progress bar for every long job in the plugin
v1.0.0, Nov 11, 2026
- Fix
Being built lists explorations handed to developers next to build requests: waiting for code reads Waiting to be picked up, developers pushing reads In progress, merged this week reads Shipped this week
v1.0.0, Nov 11, 2026
- Fix
Measure: a part's box-shadow becomes a
shadowfield (drop and inner shadows, transparent rings left out), drawn as Figma effects by the plugin; and a part a transform moves or scales (a progress indicator slid left with translateX) sits where and as big as it is drawn, out of the flow, instead of where the layout would put itv1.0.0, Nov 11, 2026
- Fix
Check the build: the exploration page shows a short list of where the build differs (one line each, the two versions under a line on hover or focus, the header primary following progress), the handover notes become a checklist whose ticks are saved, the check page walks the differences with a stepper and ends on a recap with one Send
v1.0.0, Nov 11, 2026
- Fix
Studio Home no longer shows a wrong home for a second while it loads: it waits until it knows who is reading and has read what waits on them, their explorations and their products, holding their space meanwhile, so nothing says "Nothing in progress" or "no exploration" before it knows
v1.0.0, Nov 11, 2026