Components

Progress

How far a task has got - determinate, or indeterminate while the total is unknown.

Loading...

Installation

npx shadcn@latest add @fujin/progress

The install also adds a progress-indeterminate keyframes rule to your CSS.

Usage

import {
  Progress,
  ProgressLabel,
  ProgressValue,
} from "@/components/ui/progress"
<Progress value={uploaded}>
  <ProgressLabel>Uploading invoices.csv</ProgressLabel>
  <ProgressValue />
</Progress>

Progress renders the track and bar itself; label and value go inside it as children. Pass value={null} while the total is unknown - the bar slides back and forth (or pulses, with reduced motion) and ProgressValue renders nothing.

Accessible name

A progressbar without a name is announced as just "progress bar, 40%". Either render a ProgressLabel (Base UI wires it up with aria-labelledby) or pass aria-label:

<Progress value={value} aria-label="Uploading invoices.csv" />

ProgressValue is aria-hidden - the percentage is announced through aria-valuetext. If you customise what ProgressValue shows, pass the same text through getAriaValueText.

Progress or meter?

progress is for a task moving towards completion (upload, import, setup steps). For a measurement in a range that is not "finishing" - storage used, quota, strength - use meter.

What's different from shadcn/ui

  • Indeterminate state (value={null}) is animated instead of an empty bar.
  • ProgressLabel and ProgressValue parts, from Base UI.
  • The bar's width transition is turned off under prefers-reduced-motion.

API Reference

Prop

Type

Every other prop is forwarded to the Base UI Progress.

On this page