Default
Show the codeHide the code
Default, code
<ProgressBar label="Uploading report.pdf" value={40} />How far a task has got (ProgressBar, ProgressCircle) or how full something is (Meter).
These are the real React components. Use them with a mouse, touch or keyboard, and switch the theme and density for every example at once.
Default, code
<ProgressBar label="Uploading report.pdf" value={40} />Indeterminate, code
<ProgressBar value={40} label="Preparing export" isIndeterminate />Segments, code
<div className="flex max-w-md flex-col gap-stack-md">
<ProgressBar label="Account setup" variant="segments" value={2} maxValue={5} valueLabel="Step 2 of 5" />
<ProgressBar label="Onboarding progress" variant="segments" value={1} maxValue={4} valueLabel="Step 1 of 4" hideLabel />
</div>Circle, code
<div className="flex items-center gap-gap-lg">
<ProgressCircle aria-label="Upload" value={25} size="sm" />
<ProgressCircle aria-label="Upload" value={60} />
<ProgressCircle aria-label="Upload" value={80} size="lg" showValue />
<ProgressCircle aria-label="Syncing" isIndeterminate />
</div>Meter, code
<div className="max-w-md"><Meter label="Storage used" value={72} valueLabel="7.2 GB of 10 GB" tone="warning" /></div>The 12 design tokens Progress reads, with the value each has in the theme and density chosen above. Change a token and the component follows, in Figma and in code.
| Token | Value now | CSS variable |
|---|---|---|
| color.action.danger | … | --sd-color-action-danger |
| color.action.primary | … | --sd-color-action-primary |
| color.bg.canvas | … | --sd-color-bg-canvas |
| color.bg.muted | … | --sd-color-bg-muted |
| color.border.control | … | --sd-color-border-control |
| color.icon.warning | … | --sd-color-icon-warning |
| color.text.default | … | --sd-color-text-default |
| color.text.secondary | … | --sd-color-text-secondary |
| radius.full | … | --sd-radius-full |
| spacing.gap.md | … | --sd-spacing-gap-md |
| spacing.gap.xs | … | --sd-spacing-gap-xs |
| spacing.stack.xs | … | --sd-spacing-stack-xs |
The npm package isn’t published yet. When it is, this is the install line; until then, this page runs the same build of the package (from commit fa3abf8).
Install
npm i @superduperui/react @superduperui/tokensImport
import { ProgressBar, ProgressCircle, Meter } from "@superduperui/react"Progress also takes the props of the React Aria component it’s built on.
| Prop | Type | What it does |
|---|---|---|
labelrequired | string | Visible label (required): what is progressing. |
showValue | boolean | Show the value text ("40%" or your valueLabel) at the end of the label row. Default true when determinate. |
hideLabel | boolean | Keep the label for assistive technology but hide it visually. |
variant | 'bar' | 'segments'Default 'bar' | bar (default) is one continuous track; segments draws one segment per step with the steps done (and the current one) filled, for onboarding headers. Indeterminate bars always sweep as a bar. |
segmentCount | number | How many segments the segments variant draws. Default: the number of steps in the range (maxValue - minValue), so value 2 with maxValue 5 fills two of five. |
Screen readers announce "Uploading report.pdf, 40%, progress bar".
WCAG 2.2 AAA criteria the component meets in Comfortable density: 1.4.6, 1.4.9, 2.3.2, 2.3.3.
Not interactive: density changes spacing only.
| axe-core (WCAG A, AA, AAA and best practice) | 120 runs across every story, theme, density and width: 0 violations |
|---|---|
| Rendered text contrast | 225 text runs: 0 below 7:1, lowest 11.42:1 |
| Target size | 0 targets: 0 under 44px in Comfortable |
| Focus appearance (2.4.13) | 0 focus stops in 0 browser engines: all pass |
Manual passes with VoiceOver and NVDA haven’t been done yet.
The Figma component is ProgressBar, with Type (Determinate, Indeterminate); Variant (Bar, Segments); Fill (0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100). The Figma library isn’t published yet.
Figma to code: Type (Determinate = value, Indeterminate = isIndeterminate); Label → label; Value → value (percentage text is generated); Show value → showValue; Variant → variant (Bar = "bar", Segments = "segments"); Fill → value (0 = 0, 10 = 10, 20 = 20, 30 = 30, 40 = 40, 50 = 50, 60 = 60, 70 = 70, 80 = 80, 90 = 90, 100 = 100).