Progress
Free · MITA bar for work whose progress is measured: an upload, an import, an index. It moves only between values the service reported, and it starts at the first value it is given rather than filling from empty. With no value it is indeterminate: a pulsing bar and the label as text, and never a made-up percentage.
Version 5.2.0· other versions
This page is for 5.2.0, the current release. An earlier release’s page is the Markdown that release published, so the docs match the version you have installed (candor-lock.json records it).
- 5.1.0
- 5.0.0
- 4.5.0
- 4.4.0
- 4.3.0
- 4.2.0
- 4.1.0
- 4.0.2
- 4.0.1
- 4.0.0
- 3.0.0
- 2.10.0
- 2.9.0
- 2.8.0
- 2.7.0
- 2.6.2
- 2.6.1
- 2.6.0
- 2.5.1
- 2.5.0
- 2.4.0
- 2.3.0
Not in the docs of 1.3.0, 1.4.0, 1.5.0, 1.5.1, 1.6.0, 1.7.0, 1.8.0, 1.8.1, 1.9.0, 1.9.1, 2.0.0, 2.1.0 and 2.2.0: the page came later, or had another name then.
Docs pages weren’t kept for 1.0.0, 1.0.1, 1.1.0, 1.1.1, 1.2.0 and 1.2.1: they are kept from 1.3.0 on, and before that only llms.txt was published.
Preview
Loading the preview
Install
Opens the free starter app in StackBlitz, in your browser, on stackblitz.com. Progress isn’t added for you: run npx candor-ui add progress in its terminal. The starter’s agent needs an Anthropic API key to chat; without one it shows the components only.
First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/progress
Brings in: locale, motion, tokens, utils · npm: @base-ui/react@^1.9.0
Usage
"use client"
import * as React from "react"
import { Progress } from "@/components/candor/ui/progress"
export default function Example() {
// The bar shows what the service reported, so it moves when a new figure arrives and not before.
const [done, setDone] = React.useState(12)
return (
<div className="flex w-full max-w-sm flex-col gap-6">
<div className="flex flex-col gap-2">
<div className="flex items-center justify-between text-sm">
<span className="font-medium">Importing records</span>
<span className="tabular-nums text-muted-foreground">{done} of 40</span>
</div>
<Progress label="Importing records" value={done} max={40} />
<button type="button" className="self-start text-xs text-accent-text underline-offset-4 hover:underline" onClick={() => setDone((d) => Math.min(40, d + 7))}>
Next report from the service
</button>
</div>
<div className="flex flex-col">
<Progress label="Indexing documents. The total isn't known yet." />
</div>
</div>
)
}<Progress>
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | undefined | — | Classes for the bar's track. |
| value | number | null | undefined | — | How far along the work is, from `0` to `max`, as the service reported it. Leave it out (or pass `null`) when the total isn't known: the bar then shows no fraction, only that work is going on, with the `label`. A bar is a claim about a fraction, so the app never estimates one. |
| max | number | undefined | — | The value that means finished. Defaults to 100. |
| label | string | undefined | — | What is progressing, in the app's words and language ("Indexing 12 files", "Uploading report.pdf"). It names the bar for assistive technology, and when `value` is unknown it is printed under the bar as the word that says so. |
Also takes the props of Omit<ProgressPrimitive.Root.Props, "value" | "max" | "className">.
Motion
| Moment | Family | What it does |
|---|---|---|
| indeterminate | live | While the total is unknown, the bar pulses (the live family's pulse) and the label shimmers with it; it runs only while that state lasts, and stops the moment a value arrives. |
| value | fill | The filled part moves to each new measured value in the slow duration, and not on first draw. |
Set with --cd-motion-progress-<moment>-* in your brand file; the families are in the design reference.