/// Feedback
ProgressBar
A thin track that fills to value/max, or sweeps indeterminately when value is omitted.
import { ProgressBar } from "@protocore/pds";Basics
Pass value (against a max of 100 by default) for a determinate fill. Always give it a label describing what is progressing.
Tones
The default fill is ink. A tone recolors it to a status meaning — a green uptime bar, an amber quota, a red remaining-budget — the one place a track carries color.
Indeterminate
Omit value for a continuous sweep. Use it only when the total is genuinely unknown; if you can estimate a percentage, show it.
Live progress
Driving value from state gives a real, measured bar. The fill transitions smoothly between updates.
When to use it
Use a ProgressBar when the work has a *measurable* extent — an upload, a migration, a chain sync, a multi-step import. The filled proportion is a promise that the task will end.
- Can't measure it, and the wait is short? Use a Spinner — a determinate bar stuck at an arbitrary percent is worse than an honest spin.
- Standing in for content that's about to render? Use a LoadingSkeleton.
- Letting the user *set* a value rather than observe one? That's a Slider, not a progress track.
Reserve the indeterminate sweep for truly open-ended work; prefer a real percentage whenever you can compute one.
Usage
Do
- Use it for work with a measurable, finite extent.
- Always pass a `label` naming what is progressing.
- Use `tone` to encode a status reading (uptime, quota, budget).
- Show a real percentage whenever the total is knowable.
Don't
- Fake progress or park a determinate bar at an arbitrary percent.
- Use an indeterminate bar where a Spinner is simpler and just as honest.
- Confuse it with a Slider — ProgressBar is read-only.
- Rely on `tone` color alone to convey the reading; keep the label meaningful.
Accessibility
- The root is `role="progressbar"` with `aria-valuemin`, `aria-valuemax`, and `aria-valuenow` (omitted while indeterminate).
- Provide `label` so `aria-label` names the task; without it the bar announces only a percentage.
- Value is clamped to the 0…max range, and a non-positive `max` falls back to 100, so ARIA values stay valid.
- The fill and indeterminate sweep respect `prefers-reduced-motion`.
ProgressBar props
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | |
label | string | — | Accessible label describing what is progressing. |
max | number | 100 | Upper bound of `value`. |
style | CSSProperties | — | |
tone | enum | — | Switches the fill from ink to a status color. |
value | number | — | Current progress. Omit for an indeterminate sweep. |