Feedback

Progress

A bar that shows how far along a task is, or that it is under way when you can't tell. It is a labeled progressbar, so screen readers hear the label and the value.

Uploading photos
x
Importing recipes
x

Install

Once per app, with Tailwind CSS v4 and an @/* path alias (Ouro HX is built on Base UI, so --base base; skip -t in an existing app):

npx shadcn@latest init --base base --preset nova --yes --no-monorepo
npx shadcn@latest add ourostack/ouro-ui/ouro-base#v1.2.13

Then the component. From v0.8.0 it installs only the helpers it imports and never touches your stylesheet (Installing):

npx shadcn@latest add ourostack/ouro-ui/progress#v1.2.13

Or, with the @ouro namespace set up:

npx shadcn@latest add @ouro/ouro-base @ouro/progress

Its tests, stories and Playwright spec are optional. They need Vitest 4.1.11 or later, and from v0.8.0 never change a version your app has (Testing):

npx shadcn@latest add ourostack/ouro-ui/progress#v1.2.13 ourostack/ouro-ui/progress-tests#v1.2.13
import { Progress } from "@/components/ouro/progress/progress";

Paths use shadcn's default @/ alias; the CLI rewrites them to yours.

Example

<Progress label="Uploading photos" value={40} showValue />
<Progress label="Importing recipes" value={null} />

Use instead when

  • Use Spinner instead for a short wait with no measurable progress, and Skeleton to hold the place of content that is loading.

Props

Type: ProgressProps.

className
Type: string
Layout only: margins, width, grid placement (mt-4, max-w-sm). Appearance classes warn in development; use tone.
format
Type: Intl.NumberFormatOptions
How the value is written, for showValue and screen readers: { style: "unit", unit: "megabyte" }. In the reader's locale once the page has hydrated; en-US in the server's HTML and during hydration, since the server cannot know the reader's.
hideLabel
Type: boolean
Hides the label visually; screen readers still use it.
id
Type: string
The progress bar's id, for aria-describedby or aria-controls elsewhere on the page.
indeterminateText
Type: string
Default: "Loading"
What screen readers say for the value while it is null, that the work is under way. Translate it with the rest of your interface.
label (required)
Type: string
What is in progress: "Uploading photos". It names the bar for screen readers.
max
Type: number
Default: 100
The value at the end of the bar, when the work is done.
min
Type: number
Default: 0
The value at the start of the bar.
ref
Type: Ref<HTMLDivElement>
Reaches the rendered element.
showValue
Type: boolean
Shows the value beside the label, as a percentage unless format says otherwise.
tone
Type: "primary" | "secondary" | "destructive" | "success" | "warning"
Default: "primary"
Color role from the theme for the filled part, named after its token. secondary is the muted foreground.
value (required)
Type: number | null
How far along the work is, from min to max. null while you don't know: the bar is indeterminate and slides instead of filling.

Don't use

These are not props. Passing one fails the type check with the fix in the error, and in development a console message names the fix.

  • color: Not a prop. Ouro UI uses tone: <Progress tone="success">.
  • indeterminate: Not a prop. An unknown value is null: <Progress value={null}>.
  • isIndeterminate: Not a prop. An unknown value is null: <Progress value={null}>.
  • variant: Not a prop. A number value is determinate, null indeterminate.

className is for layout only

Pass margins, width and grid placement (mt-4, w-full, col-span-2).

Appearance comes from props, not classes. In development, a class that sets appearance logs one warning per component instance, naming the prop to use instead. A class sets appearance when, after its variants (hover:, sm:) and any ! are removed, it starts with bg-, text-, border-, rounded-, shadow-, font-, ring-, from-, via-, to-, fill- or stroke-, or is border, rounded, shadow or ring, or has a dark: variant. Text wrapping, overflow and table layout classes (text-wrap, text-ellipsis, border-collapse) are layout and do not warn.

Alignment classes (text-center) warn too: set alignment on a parent element.