Components · Data display
Progress
Linear progress, quota meters and stacked segments.
Determinate and indeterminate
import { Progress } from '@rookcom/monarch-react';
<Progress label="Upload progress" value={40} />
<Progress label="Import progress" value={100} tone="success" size="sm" />
<Progress label="Syncing members" />Usage examples
Quota meter
import { Progress } from '@rookcom/monarch-react';
<Progress
semantics="meter"
label="Storage"
value={4.2}
max={10}
valueText="4.2 of 10 GB used"
/>
<Progress
semantics="meter"
label="Seats"
value={46}
max={50}
thresholds={{ warning: 40, danger: 50 }}
valueText="46 of 50 seats"
/>
<Progress
semantics="meter"
label="Capacity"
value={52}
max={40}
valueText="52 of 40 hours, overbooked"
/>Segmented
import { Progress } from '@rookcom/monarch-react';
<Progress
label="Sprint progress"
max={24}
segments={[
{ label: 'Done', value: 11, tone: 'success' },
{ label: 'In review', value: 4, tone: 'info' },
{ label: 'In progress', value: 5, tone: 'warning' },
]}
/>
<Progress
semantics="meter"
label="Logged hours"
max={40}
segments={[
{ label: 'Billable', value: 22 },
{ label: 'Internal', value: 9 },
{ label: 'Leave', value: 4 },
]}
/>Purpose
Shows how far a task has got (uploads, syncs, imports), or that it is running when the amount is unknown.
Use when
- A task reports progress as a number (
value). - A long task runs with unknown duration (omit
value). - A measured quantity within a range, such as storage, seats or capacity (
semantics="meter"). - Parts of one total, such as done / in review / in progress (
segments).
Avoid when
- A short wait inside a control: use Spinner.
- Placeholder content while a page loads: use Skeleton or LoadingState.
Design principles
- Always named: give
label(oraria-labelledby) so the bar says what is progressing. - Omitting
valuemeans indeterminate; never fake a moving value. - Progress is a task; a meter is a measurement. Choose the role that says which.
- Colour reinforces state (warning, over the limit) but the value text always says it too.
API reference
import { Progress } from '@rookcom/monarch-react';| Export | Kind | Rendering | Root class |
|---|---|---|---|
Progress | component | server-safe | .mn-progress |
The default progress bar is built on @radix-ui/react-progress; meters and segmented bars render their own <div> with the same mn-progress classes. The ref is forwarded to the root element in every form.
Types ProgressTone, ProgressSegment and ProgressSegmentTone are exported.
Generated from the TypeScript declarations of packages/react/src/components/data-display/progress-bar.
Properties
value is clamped to 0–100% of max for the bar width.
For meters, aria-valuenow is clamped to max and the real value is in aria-valuetext.
Progress
Linear progress bar; `value` undefined renders an indeterminate animation. Also a quota meter (`semantics="meter"`) and a stacked bar (`segments`).
| Prop | Type | Description |
|---|---|---|
asChild | boolean | |
children | ReactNode | |
className | string | |
id | string | |
label | string | Accessible name, e.g. "Upload progress". Required unless aria-labelledby is set. |
max | number | |
segments | ProgressSegment[] | Stacked parts that add up to the filled amount, e.g. done / in review / in progress. `value` is then the sum of the segments. |
semantics | "meter" | "progressbar" | `progressbar` (default) for a task moving towards completion; `meter` for a measured quantity within a known range, such as a quota or capacity (`role="meter"`). A meter is never indeterminate. |
size | "sm" | "md" | |
thresholds | { warning?: number; danger?: number; } | Meter only: values at or above which the automatic tone becomes `warning` and `danger`, e.g. `{ warning: 80, danger: 95 }` of 100. |
tone | ProgressTone | Fill colour. Default `accent`. With `semantics="meter"` and no tone, the tone is `neutral` (a normal quota is not a status), follows `thresholds`, and a value over `max` is `danger`. |
value | number | null | 0–`max`. Omit for indeterminate. |
valueText | string | Text alternative for the value (`aria-valuetext`), e.g. "7.2 of 10 GB used". Default for meters and segmented bars: generated from the values. |
Variants
| Prop | Values | Description |
|---|---|---|
size | 'sm''md' | Bar height. Default md. Exposed as data-size. |
tone | 'accent''success''warning''danger''neutral' | Fill colour. Default accent. Exposed as data-tone. Meters without a tone default to neutral, follow thresholds, and turn danger over the limit. |
semantics | 'progressbar''meter' | ARIA role. Exposed as data-semantics on meters and segmented bars. |
segments | 'ProgressSegment[]' | Stacked parts in order. Segment tones: the five tones plus info and data-1…data-5 (default: the data palette in order). |
States
| State | Exposed as | Behaviour |
|---|---|---|
| Determinate | – | The bar width is value / max, clamped to 0–100%. |
| Indeterminate | data-indeterminate | Set when value is undefined or null; the bar animates and has no aria-valuenow. Meters are never indeterminate. |
| Warning and danger | data-tone | Meter tone once the value reaches thresholds.warning or thresholds.danger. |
| Over the limit | data-over | Meter value above max: full bar, danger tone, “over the limit” in the value text. |
| Segmented | data-segmented | Stacked segments; the value is their sum and they never overflow the track. |
Interaction behaviour
- None. Progress is a read-only indicator.
Keyboard support
Not interactive, so there is no keyboard behaviour.
Accessibility
- Role
- progressbar, or meter with
semantics="meter" - Accessible name
labelbecomesaria-label; or passaria-labelledby.
valueTextsetsaria-valuetext(“7.2 of 10 GB used”); meters and segmented bars generate one (“Done 8, In review 4 (12 of 20)”) when it is not given.- Determinate bars expose
aria-valuenow(from Radix Progress). - Indeterminate bars omit
aria-valuenow. - With reduced motion the indeterminate animation slows to 3s per cycle.
Responsive behaviour
- No breakpoints: the bar fills its container width.
Theme support
- Fill and track use Monarch tokens;
accentfollows the product accent.neutral(the meter default) uses--mn-color-text-muted, so a normal quota never reads as a status. - Segment colours use the strong intent tokens and the
--mn-color-data-*palette, separated by a 2px surface-coloured gap. - Width transitions are removed under reduced motion.
Do and don't
Do
- Name every bar with
label. - Switch to
tone="success"or"danger"only when the task has finished that way.
Don't
- Do not animate a determinate value you cannot measure; use the indeterminate form.
- Do not leave
semanticsasprogressbarfor static quantities such as storage used: usesemantics="meter". - Do not rely on segment colours alone: label each segment, and show a legend when the parts matter.
Related components
- Spinner: Indeterminate progress inside a control.
- LoadingState: Placeholder for a whole loading region.
- StackedProportionBar: Planned chart-style bar with a legend for proportions.
- StatCard: Headline figure that can sit above a meter.
Dependencies
| Kind | Depends on |
|---|---|
| npm packages | @radix-ui/react-progressreact |
| Monarch components | None |
Testing coverage
- Is a labelled progressbar with
aria-valuenow; indeterminate has none. - Default markup is unchanged from 0.3;
valueTextsetsaria-valuetext. - Meter role, value text, neutral default and threshold tones; an explicit tone wins.
- Over the limit: danger tone, clamped
aria-valuenow, “over the limit” text, full bar. - Segments: order, default tones, offsets, generated value text, no overflow.
| Check | Covered |
|---|---|
| Axe in jsdom | Yes |
| Server rendering | Yes |
| Browser suites | None yet |
Tests: packages/react/src/components/data-display/progress-bar