Progress

Displays an indicator showing the completion progress of a task.

Upload progress66%
x
Review completion33%
x
Installation
$Terminal
npx shadcn@latest add https://sdk-components.thesqd.com/r/progress.json
Usage
Pass `value` (0–100) to drive the indicator. Use `null` for indeterminate.
TSImport
import { Progress, CircularProgress } from "@/components/ui/progress";
TSExample
import { Progress } from "@/components/ui/progress";

export function Example() {
  return <Progress value={66} label="Upload progress" valueLabel="66%" />;
}
Composition
Anatomy of the Progress primitive.
Progress                          (horizontal bar — pass everything as props)
├── value={0..100 | null}        (null → indeterminate)
├── label={<ReactNode>}          (auto-emits ProgressLabel above the track)
├── valueLabel={<ReactNode>}     (right-aligned percentage / status text)
├── labelPosition="top" | "left" | "right" (left/right: compact 90px bar, text beside it)
├── colorRules={[{ from, color }, …]} (recolour by % of max; highest reached wins)
└── className                    (wraps Progress.Root — typically max-w-sm)

CircularProgress                 (SVG ring sibling — same value semantics)
├── value={0..100 | null}        (null → indeterminate, ring spins)
├── size={number}                (diameter in px, default 40)
├── strokeWidth={number}          (default 4)
├── label={<ReactNode>}          (caption beneath the ring)
├── showValue                    (renders the percent text inside the ring)
└── trackClassName / indicatorClassName

ProgressSteps                    (segmented milestone bar with tooltips)
├── steps={[{ label?, description?, status?, icon?, completed?, current? }, …]}
├── value={number}               (fills the first N segments in brand primary)
├── label={<ReactNode>}          (header — renders "{label}: {value} / {total}")
├── showCount={boolean}          (default true — hide the "4 / 9" count)
└── segmentClassName             (override segment size/rounding)

Need a custom header (icons, multiple values, status pill)? The slot
exports — ProgressLabel, ProgressValue, ProgressTrack, ProgressIndicator —
are still exported as the escape hatch.
Static values
Plain progress bars at common completion checkpoints.
0%
x
33%
x
66%
x
100%
x
Labeled
Pass `label` + `valueLabel` and the header strip auto-emits above the track.
Upload progress66%
x
Review completion33%
x
Animated
A live example that increments on an interval and loops back to zero.
Processing assets12%
x

Simulates an in-flight upload or generation task.

Range label (animated swap)
Drive the `label` from an array of `{ from, to, label }` bands, falling back to a required base `label`. As the value crosses a band boundary, the label text-swaps with a blurred up-and-in animation.
Starting up8%
x

The label is driven by an array of { from, to, label } bands and falls back to the required label; the text swap animates on every band change.

Indeterminate (bouncing)
Pass `indeterminate` to ignore `value` and render a segment 60% narrower than a full bar that bounces side to side — same track and indicator styling as the determinate bar. Use it when progress can't be measured.
Indeterminate
x
Inline (compact)
`labelPosition="left"` or `"right"` draws a small 90px bar — the indeterminate example's size — with `label` and `valueLabel` beside it instead of above. Works for determinate and indeterminate bars, in a table cell, a list row or a toolbar.
Uploading60%x
3/5
x
Syncingx
Color rules
`colorRules` recolours the bar by how far along it is — a list of `{ from, color }` where `from` is a percentage of `max` and `color` any CSS colour. The highest `from` the value has reached wins; below every rule the bar keeps its default colour. Here, a usage meter goes amber at 75% and red at 90%.
Projects this month40%x
Projects this month80%x
Projects this month95%x
Circular
An SVG ring driven by the same `value` semantics as the bar. Set `size`/`strokeWidth` to scale it, `showValue` to render the percent inside the ring, and `label` to drop a caption beneath it.
25%
50%
75%
Uploading
Done
Circular (indeterminate)
Pass `value={null}` to spin the ring as an indeterminate loader — handy as an inline spinner with an optional `label`.
Loading…
Loading
Auto-animates from 0 toward ~90% on an ease-out curve, then snaps to 100 when `done` flips true. Drop-in replacement for NProgress-style loaders.
Uploading...0%
Progress Steps
A segmented milestone bar — one chunky segment per step, completed segments filled in brand primary, the `current` step highlighted in squad peach. Hovering a segment opens a rich tooltip with the step's `label`, `description` (e.g. a date), and a `status` row with an icon. Header renders as `Your Progress: 4 / 9`.
Your Progress: 4 / 9
API Reference
Props exposed by the Progress primitive.

Progress

PropTypeDefaultDescription
valuenumber | null0Current value 0–100. Pass `null` for an indeterminate progress.
labelReactNode—Heading rendered above the track. Auto-emits a `<ProgressLabel>`.
valueLabelReactNode—Right-aligned label rendered alongside `label` (e.g. `"66%"`).
colorRules{ from: number; color: string }[]—Recolour the bar by progress. `from` is a percentage of `max`, `color` any CSS colour; the rule with the highest `from` the value has reached wins, and below every rule the bar keeps its default colour.
labelPosition"top" | "left" | "right""top"Where the text sits. `top` is the strip above a full-width track; `left` / `right` is the compact inline bar — a 90px track with `label` and `valueLabel` beside it.
classNamestring—Override the wrapper layout.

CircularProgress

PropTypeDefaultDescription
valuenumber | null—Current value 0–100. Pass `null` for an indeterminate spinner.
sizenumber40Diameter of the ring in pixels.
strokeWidthnumber4Stroke width for both the track and the indicator.
showValuebooleanfalseRender the percent text inside the ring (ignored for indeterminate).
labelReactNode—Caption rendered beneath the ring.
trackClassNamestring—Class names applied to the empty track segment.
indicatorClassNamestring—Class names applied to the filled indicator segment.

LoadingProgress

PropTypeDefaultDescription
minDurationnumber3000Minimum milliseconds the bar takes to reach 100. While waiting, the bar asymptotes toward ~90%.
donebooleanfalseWhen `true`, animates to 100 (respecting `minDuration`) and fires `onComplete`.
labelReactNode—Default heading. Used as the fallback when `uploadingLabel`/`completeLabel` are not provided.
uploadingLabelReactNode—Heading shown while value < 100. Falls back to `label` if omitted.
completeLabelReactNode—Heading shown once value reaches 100. Falls back to `label` if omitted.
valueLabelReactNode | boolean—Right-aligned status text. Pass `true` to auto-render the rounded percentage.
onComplete() => void—Fires once after the bar reaches 100.
easeStartnumber0Starting percentage of the ease-out curve.
easeEndnumber90Ceiling percentage the curve asymptotes toward while waiting.
classNamestring—Override the wrapper layout.

ProgressSteps

PropTypeDefaultDescription
stepsProgressStep[]—One segment per entry. Steps with a `label`/`description`/`status` get a hover tooltip.
valuenumber—Number of completed steps — fills the first `value` segments in brand primary. Omit to derive from each step's `completed` flag.
labelReactNode—Header rendered above the bar as `"{label}: {value} / {total}"`. Omit to hide the header entirely — including the count.
showCountbooleantrueHide the `4 / 9` count after the label.
segmentClassNamestring—Per-segment override (height, rounding, colors).

ProgressStep

PropTypeDefaultDescription
labelReactNode—Tooltip title (bold first line).
descriptionReactNode—Tooltip second line — e.g. a date ("Wed, Jan 16").
statusReactNode—Tooltip status row — e.g. "Scheduled". Rendered beside `icon`.
iconReactNode—Icon for the status row. Defaults to a clock when `status` is set.
completedboolean—Force the completed fill (defaults to index < `value`).
currentboolean—Highlight this segment as the current/upcoming step (peach fill).