Progress button
FreeA button that fills with determinate progress while its work runs, writes the percentage, and settles on a check.
pnpm dlx shadcn@latest add https://caliperui.site/r/progress-button.jsonWhen to use #
Use it for
- Exports, uploads and syncs started from a button.
- Work that takes seconds and has a known size.
Skip it when
- Unknown durations; use the button's loading state.
Installation #
pnpm dlx shadcn@latest add https://caliperui.site/r/progress-button.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 { useEffect, useRef, useState } from "react" import { ProgressButton } from "@/components/ui/progress-button" export function ProgressButtonDemo() { const [progress, setProgress] = useState<number | null>(null); const [done, setDone] = useState(false); const timer = useRef<ReturnType<typeof setInterval>>(undefined); useEffect(() => () => clearInterval(timer.current), []); function start() { if (done) { setDone(false); setProgress(null); return; } let value = 0; setProgress(0); timer.current = setInterval(() => { value = Math.min(100, value + 7 + Math.random() * 12); setProgress(value); if (value >= 100) { clearInterval(timer.current); setDone(true); } }, 260); } return ( <ProgressButton progress={progress} done={done} workingLabel="Exporting" doneLabel="Exported" onClick={start}> {done ? "Export again" : "Export 2,481 rows"} </ProgressButton> ); }
API reference #
ProgressButton
component
Also accepts the native props of its root element and a ref.
Accessibility #
It is built on native elements and keeps aria-disabled, aria-busy and aria-hidden in step with state.
No custom key handling; Tab and the native activation keys do the work.
Motion #
It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.