Overlays & feedback
Progress
Shows how far along an operation is — an upload, an import, a multi-step setup, or a quota. Linear bars, circular rings, and segmented steps, each determinate or indeterminate.
npx shadcn@latest add @orbit/progressLive
A simulated import driving all three forms at once.
Linear bars
The default. Four heights — xs 4px · sm 6px · md 8px · lg 12px — an optional label and percentage, and an indeterminate mode for unknown durations.
Circular rings
For compact spots and dashboards. Four sizes — sm 40px · md 56px · lg 80px · xl 120px — with an optional centered percentage, plus a spinning indeterminate ring.
Steps & tones
Segmented steps for discrete flows like setup wizards. Tones carry status — green for done, amber for caution, red for a stalled or failing task, neutral for muted.
Props
ProgressBar
| Prop | Type | Default | Description |
|---|---|---|---|
| value | number | 0 | Current value, clamped to 0–max. Ignored while indeterminate. |
| max | number | 100 | Upper bound of the range. |
| size | "xs" | "sm" | "md" | "lg" | "md" | Track height: 4 / 6 / 8 / 12px. |
| tone | "blue" | "green" | "amber" | "red" | "neutral" | "blue" | Fill color intent, mapped to theme tokens. |
| indeterminate | boolean | false | Looping 1.3s sweep for unknown durations; omits aria-valuenow. |
| label | ReactNode | — | Header-row label; also names the bar for screen readers via the Base UI Label. |
| showValue | boolean | false | Percentage readout on the right of the header (hidden while indeterminate). |
| caption | ReactNode | — | Muted helper line under the track, e.g. “412 of 600 imported”. |
ProgressRing
| Prop | Type | Default | Description |
|---|---|---|---|
| value | number | 0 | Current value, clamped to 0–max. |
| max | number | 100 | Upper bound of the range. |
| size | "sm" | "md" | "lg" | "xl" | "md" | Diameter: 40 / 56 / 80 / 120px (stroke 4 / 5 / 6 / 8px). |
| tone | "blue" | "green" | "amber" | "red" | "neutral" | "blue" | Arc color intent. |
| indeterminate | boolean | false | 0.9s spinning arc; omits aria-valuenow. |
| showValue | boolean | false | Centered percentage (hidden while indeterminate). |
ProgressSteps
| Prop | Type | Default | Description |
|---|---|---|---|
| value | number | 0 | Completed step count. |
| steps | number | 5 | Total number of segments. |
| tone | "blue" | "green" | "amber" | "red" | "neutral" | "blue" | Filled-segment color intent. |
| label | ReactNode | — | Header-row label; showing it also shows the “Step x of y” readout. |
Usage
Use indeterminate for unknown waits
When you can’t estimate duration, show the looping bar or spinning ring instead of a fake percentage.
Animate a determinate bar backward
Progress should only move forward; jumping back reads as an error.
Pair long bars with a count
“412 of 600 imported” tells the user more than a percentage alone.
Use a tiny ring for a long task
For multi-minute work, a labeled bar with a count communicates far better than a small ring.
Keyboard & accessibility
Every form exposes the progressbar pattern: role=progressbar with aria-valuemin 0, aria-valuemax, and aria-valuenow — omitted while indeterminate so screen readers announce a busy state. The bar builds on Base UI Progress, so a label is wired up automatically; pass aria-label when there's no visible label (rings, bare bars). The steps form adds aria-valuetext (“Step 2 of 4”). All animations freeze under prefers-reduced-motion via the global guard.