Progress
Progress is a neobrutalist React component from Cruise UI. Linear bars and circular rings for how far along something is, or a spinner. Install it with npx shadcn@latest add @cruiseui/progress.
Install
Terminal
npx shadcn@latest add @cruiseui/progressFirst time? Installation shows the one-off components.json setup (the @cruiseui registry) and how to turn the theme on.
Example
Corners
Loading…
import { CruiseProgress, CruiseProgressRing } from "@/components/cruise/progress";
export default function ProgressExample() {
return (
<div className="flex flex-col gap-6">
<CruiseProgress label="Uploading photos" value={65} showLabel />
<CruiseProgress label="Order packed" value={100} tone="success" showLabel />
<CruiseProgress label="Saving changes" showLabel />
<div className="flex flex-wrap items-center gap-6">
<CruiseProgressRing label="Storage used" value={30} size="sm" />
<CruiseProgressRing label="Course progress" value={72} />
<CruiseProgressRing label="Loading orders" />
</div>
</div>
);
}
<div class="progress" role="progressbar" aria-label="Uploading photos" aria-valuemin="0" aria-valuemax="100" aria-valuenow="65">
<div class="progress-label" aria-hidden="true"><span>Uploading photos</span><span>65%</span></div>
<div class="progress-track"><div class="progress-fill on-primary" style="width: 65%"></div></div>
</div>
<div class="progress progress-sm" role="progressbar" aria-label="Order packed" aria-valuemin="0" aria-valuemax="100" aria-valuenow="100" data-tone="success">
<div class="progress-track"><div class="progress-fill" data-flush style="width: 100%"></div></div>
</div>
<!-- Indeterminate: no aria-valuenow -->
<div class="progress" role="progressbar" aria-label="Saving changes" aria-valuemin="0" aria-valuemax="100" data-indeterminate>
<div class="progress-track"><div class="progress-fill"></div></div>
</div>
<span class="progress-ring" role="progressbar" aria-label="Course progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="72">
<svg width="80" height="80" viewBox="0 0 80 80" aria-hidden="true">
<circle class="progress-ring-outline" cx="40" cy="40" r="32" stroke-width="16"/>
<circle class="progress-ring-track" cx="40" cy="40" r="32" stroke-width="12"/>
<circle class="progress-ring-value" cx="40" cy="40" r="32" stroke-width="12" pathLength="100" stroke-dasharray="72 100"/>
</svg>
<span class="progress-ring-text" aria-hidden="true">72%</span>
</span>
<!-- Spinner (sm: 48px, stroke 10, r 13) -->
<span class="progress-ring progress-ring-sm" role="progressbar" aria-label="Loading orders" aria-valuemin="0" aria-valuemax="100" data-indeterminate>
<svg width="48" height="48" viewBox="0 0 48 48" aria-hidden="true">
<circle class="progress-ring-outline" cx="24" cy="24" r="13" stroke-width="14"/>
<circle class="progress-ring-track" cx="24" cy="24" r="13" stroke-width="10"/>
<circle class="progress-ring-value" cx="24" cy="24" r="13" stroke-width="10" pathLength="100" stroke-dasharray="25 100"/>
</svg>
</span>
<span class="progress-ring-loading">Loading…</span>Needs theme.css. Interactive parts (menus, tabs, drawers) also need the script in the spec for that component.
When to use it
When to use
Uploads, half-filled profiles, deliveries; a ring where space is tight.
When not to
Static amounts that aren't progress (use a number or a Table).
Props
CruiseProgress
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Accessible name, and the visible name when `showLabel` is on. |
value? | number | — | Leave out for an indeterminate bar (working, no known end). |
max? | number | 100 | — |
tone? | CruiseProgressTone | "primary" | — |
size? | "lg" | "md" | "sm" | "md" | — |
showLabel? | boolean | false | Shows the name on the left and the value on the right above the bar. |
valueText? | string | — | Visible value text, e.g. "₦1,200 of ₦5,000". Defaults to a percentage. |
className? | string | — | — |
CruiseProgressRing
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Accessible name, and the visible name when `showLabel` is on. |
max? | number | 100 | — |
size? | "lg" | "md" | "sm" | "md" | — |
value? | number | — | Leave out for an indeterminate bar (working, no known end). |
className? | string | — | — |
tone? | CruiseProgressTone | "primary" | — |
Accessibility
- role="progressbar" with aria-valuemin, aria-valuemax, aria-valuenow and a label.
- Indeterminate: no aria-valuenow; with reduced motion the spinner stops and says "Loading…".