Progress
FreeA measured bar for work with a known size, such as an upload.
pnpm dlx shadcn@latest add https://caliperui.site/r/progress.jsonUploading report
20%
When to use #
Use it for
- You know how much is done and how much remains.
- Uploads, imports and multi-step processing.
Skip it when
- The total is unknown; use a loader.
- The structure of incoming content is known; use a skeleton.
Installation #
pnpm dlx shadcn@latest add https://caliperui.site/r/progress.json
Adds its 3 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above.
import { useState } from "react" import { Button } from "@/components/ui/button" import { Progress } from "@/components/ui/progress" export function UploadProgress() { const [sent, setSent] = useState(24); return ( <div className="grid w-full max-w-sm gap-3"> <Progress label="Uploading report" value={sent} max={120} showValue /> <div className="flex gap-2"> <Button size="sm" variant="secondary" onClick={() => setSent((value) => Math.min(120, value + 24))}>Advance</Button> <Button size="sm" variant="ghost" onClick={() => setSent(0)}>Reset</Button> </div> </div> ); }
API reference #
Progress
component
Also accepts the native props of its root element and a ref.
Accessibility #
It exposes progressbar semantics, with aria-hidden, aria-valuemin, aria-valuemax, aria-valuenow, aria-valuetext and aria-label kept in step with state.
No custom key handling; Tab and the native activation keys do the work.
Motion #
Transitions use the shared duration and easing tokens. Under prefers-reduced-motion those tokens collapse to instant and travel distances go to zero, so state changes still happen without movement.