Data display
Progress
Progress indicators show how far along a task or a quota is. Use the linear bar for uploads, imports and usage meters, with an optional visible label, value and hint; switch to indeterminate when the duration is unknown; and use the circular ring where space is tight. Bars follow the theme radius and the accent.
On this page
About 40 seconds left
Looking for duplicates…
<Progress label="Importing transactions" showLabel value={68} valueText="1,360 of 2,000" hint="About 40 seconds left" /><Progress label="Matching receipts" showLabel indeterminate hint="Looking for duplicates…" /><div className="flex flex-wrap items-center gap-5"> <ProgressCircle label="Storage used" value={72} size={56} /> <ProgressCircle label="Seats used" value={9} max={10} valueText="9/10" size={56} tone="warning" /> <ProgressCircle label="Onboarding complete" value={100} size={56} tone="success" /></div>Usage
import { Progress, ProgressCircle } from "@/components/ui/progress"; <Progress label="Importing transactions" showLabel value={68} /><ProgressCircle label="Storage used" value={72} />Examples
Overview
About 40 seconds left
Looking for duplicates…
<Progress label="Importing transactions" showLabel value={68} valueText="1,360 of 2,000" hint="About 40 seconds left" /><Progress label="Matching receipts" showLabel indeterminate hint="Looking for duplicates…" /><div className="flex flex-wrap items-center gap-5"> <ProgressCircle label="Storage used" value={72} size={56} /> <ProgressCircle label="Seats used" value={9} max={10} valueText="9/10" size={56} tone="warning" /> <ProgressCircle label="Onboarding complete" value={100} size={56} tone="success" /></div>Sizes
xs (4 px), sm (6 px, default) and md (10 px). Without showLabel the label is only announced, not shown.
<Progress label="Profile completeness" value={40} size="xs" /><Progress label="Profile completeness" value={60} size="sm" /><Progress label="Profile completeness" value={80} size="md" />Label, value and tones
showLabel prints the label with the value on the right; valueText replaces the percentage, for units like files or dollars. Tones signal state, so pair warning and danger with text that explains why.
<Progress label="Monthly budget" showLabel value={34} valueText="$3,400 / $10,000" /><Progress label="Tests passing" showLabel value={96} tone="success" /><Progress label="Disk usage" showLabel value={81} tone="warning" /><Progress label="API quota" showLabel value={99} tone="danger" valueText="99% · 12 left" /><Progress label="Indexing" showLabel value={52} tone="info" />Indeterminate
Leave out value (or set indeterminate) when you can't tell how long it will take. With reduced motion the bar stays still.
<Progress label="Connecting to your bank" indeterminate /><Progress label="Generating report" showLabel indeterminate size="md" tone="info" />Circular
ProgressCircle draws a ring with the value in the middle. The stroke scales with the size unless you set thickness.
<ProgressCircle label="Sprint progress" value={25} size={40} /><ProgressCircle label="Sprint progress" value={50} size={56} tone="info" /><ProgressCircle label="Sprint progress" value={75} size={72} tone="success" /><ProgressCircle label="Sprint progress" value={90} size={96} thickness={8} tone="warning" />Live updates
The bar animates between values. Switch the tone and hint when the task completes.
Ready to upload
<Progress label="Uploading march-statements.pdf" showLabel value={value} tone={value === 100 ? "success" : "accent"} hint={value === 100 ? "Upload complete" : running ? "Uploading…" : "Ready to upload"}/>Props
Progress
labelrequiredstringdefault: —Names the bar. Announced always, shown with showLabel.valuenumberdefault: —Current value. Leave out for an indeterminate bar.maxnumberdefault: 100Value that means complete.showLabelbooleandefault: falsePrint the label and value above the bar.valueTextstringdefault: —Visible and announced value, e.g. "3 of 5 files". Defaults to a percentage.hintReactNodedefault: —Helper line under the bar, linked with aria-describedby.tone"accent" | "success" | "warning" | "danger" | "info" | "neutral"default: "accent"Fill color.size"xs" | "sm" | "md"default: "sm"Bar thickness.indeterminatebooleandefault: falseAnimated bar for unknown durations.
ProgressCircle
labelrequiredstringdefault: —Accessible name.valuerequirednumberdefault: —Current value.maxnumberdefault: 100Value that means complete.sizenumberdefault: 48Diameter in px.thicknessnumberdefault: —Stroke width in px. Defaults to about a tenth of the size.showValuebooleandefault: trueShow the value in the middle.valueTextstringdefault: —Replaces the percentage.toneTonedefault: "accent"Ring color.
Accessibility
- Both components render role="progressbar" with aria-valuenow, aria-valuemin, aria-valuemax and a readable aria-valuetext.
- With showLabel the visible label names the bar through aria-labelledby; otherwise label becomes aria-label. Every bar has a name.
- Indeterminate bars drop the value attributes and set aria-busy, which is how screen readers know the duration is unknown.
- Hints are connected with aria-describedby, so "About 40 seconds left" is read with the bar.
- The indeterminate animation stops under prefers-reduced-motion and the bar is shown as a still, faded track.