Feedback
IProgress
A determinate bar for work with a known end, with an indeterminate mode, a stacked mode and a ring.
Label and value
label renders above the track and is tied to the bar with aria-labelledby. showValue adds the percentage on the right.
Formatting the value
formatValue receives the value and the max, so the readout can say something more useful than a percentage.
Variants
Sizes
Indeterminate
Set indeterminate, or leave the model null, when the work has no measurable end. The bar animates without claiming a position.
Circle
shape="circle" draws the same value as a ring with the readout in the middle. Everything else is unchanged — variant, size, formatValue and the indeterminate mode all behave as they do on the bar.
size sets the ring's diameter; the stroke scales with it.
angle shortens the track to part of a circle — 180 for a half, 270 for a gauge. The arc is centred at the top, so the gap sits at the bottom, and the value is measured against the track rather than the whole ring: half of a half circle is a quarter turn.
A ring ignores segments. A broken-up ring is a donut chart, and IDonutChart is the component for that.
Stacked
segments breaks one track into runs — storage by file type, a budget by category, a release by status. Each run carries its own value and variant, and modelValue is ignored; the accessible value is their sum.
- Documents180 GB
- Images120 GB
- Video60 GB
- Other25 GB
A run with a label gets a legend row beneath the track, which is where the breakdown is readable. Leave the labels off for a bare stacked bar.
A run with no variant takes the neutral fill.
More than the track holds
Runs can sum past max — a disk that grew, a budget overspent. They are clamped cumulatively rather than scaled, so the bar fills and stops.
- Committed70%
- Requested55%
The legend still shows each run's own value, so the overspend stays readable as a number.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | number | null | — | Current value; null means indeterminate |
max | number | 100 | Value representing full |
shape | 'linear' | 'circle' | 'linear' | A bar, or a ring with the readout in the middle |
angle | number | 360 | Degrees of the ring the track covers |
variant | 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'neutral' | 'primary' | Bar colour |
segments | ProgressSegment[] | — | Runs sharing one track; supersedes modelValue |
size | 'sm' | 'md' | 'lg' | 'md' | Track thickness |
indeterminate | boolean | false | Animate without a position |
label | string | — | Text above the track, wired to the bar |
showValue | boolean | false | Show the readout on the right |
formatValue | (value, max) => string | percentage | Formats that readout |
unstyled | boolean | — | Drop built-in classes |
class | string | — | Merged with the built-in classes |
ui | { root?, header?, label?, value?, track?, indicator?, segment?, legend?, legendItem?, legendSwatch?, legendValue? } | — | Per-element class overrides |
The value is clamped to 0…max.
interface ProgressSegment {
value: number
label?: string
variant?: 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'neutral'
}With no label, put an aria-label on the component: attributes reach the progressbar itself.
For a trend rather than a proportion, use ISparkline; for a wait inside a button, IButton's loading.