# Progress A bar that fills, or sweeps when the end is unknown. - Group: Feedback - Import: `import { Progress } from '@misoto22/folio'` - Page: https://ui.misoto22.com/components/progress/ - Related: spinner ## Anatomy - **Track** (required) — The Radix root: 4px of --stone at the pill radius, carrying role="progressbar" and aria-label from label. It is full width by default, so it takes the measure of whatever column it is dropped into. - **Fill** — The indicator, in --accent, sized by width rather than a translate so it grows from the inline start in a right-to-left document too. Present only when value is a number. - **Sweep** — What replaces the fill when value is null: a quarter-width --accent bar travelling the track on transform alone, mirrored under rtl so it never reads as progress running backwards. Under prefers-reduced-motion it stops where it is drawn rather than filling the track. - **Value row** — label on the left, a tabular-nums percentage on the right, above the track. It renders only when showValue is set and value is a number, which makes it the only place label is ever visible. - **Column** — The flex wrapper holding the row and the track. className lands here; every other prop is forwarded to the Radix root instead. ## Best practices ### Do - Pass showValue on any determinate bar. It is the only thing that puts label on screen — without it the name exists solely as aria-label, and a sighted reader is left with an unlabelled 4px rule and no number. - Switch value back to null the moment the estimate stops being real. The fill transitions its width over --duration-slow, so a number that revises downward animates backwards and the reader watches progress undo itself. - Set max to the real total rather than converting to a percentage yourself. The width and aria-valuemax come off the same number, so the picture and the announcement cannot drift — but a value past the ceiling still clamps, and an underestimated total parks the bar at full for the rest of the operation rather than admitting the estimate was wrong. ### Don’t - Do not pass a max that is not a positive number. Radix refuses it, prints its own warning and falls back to 100, and the width falls back with it — so value={40} paints and announces forty per cent of a ceiling nobody chose. - Do not read the resting sweep as a position. Under prefers-reduced-motion it stops at a quarter of the track, which is what a determinate bar at 25% looks like — the announcement is the only thing that tells the two apart, and it is the reason omitting value matters. - className styles the column, not the track, so a height utility passed that way stretches the wrapper and leaves the 4px bar exactly where it was. ## Accessibility - Omitting value drops aria-valuenow, so a screen reader hears “indeterminate” rather than a number that is a guess. - label is required — a bare bar announces nothing. - The width is computed from value and max, the same pair Radix announces as aria-valuenow and aria-valuemax, so what is drawn and what is said cannot disagree. ## Progress A bar that fills, or sweeps when the end is unknown. Flat: a track in `--stone`, a fill in `--ink`. The White Reset has no gradient and no glow, so the only thing carrying the reading is the boundary between the two. ### Props - `value` — `number | null` default `null`. 0 to `max`, which is 100 unless you say otherwise. Omit (or pass `null`) when the duration is genuinely unknown — the bar then sweeps instead of filling, and Radix drops `aria-valuenow` so a screen reader is told "indeterminate" rather than a number that is a guess. - `max` — `number`. What `value` is measured against. 100 by default. The width is computed from it as well as announced from it. It used to be only announced: `max` reached Radix through `...rest` while the width was `value` clamped to 100, so `max={500}` with `value={100}` painted a full bar and told a screen reader "100 of 500". A max that is not a positive number is refused the way Radix refuses it — Radix warns, and both fall back to 100 rather than drawing one picture and announcing another. - `label` (required) — `string`. Names what is progressing. Required: a bare bar announces nothing. - `showValue` — `boolean` default `false`. Prints the percentage above the bar. Only meaningful when `value` is set. Also accepts: `Omit, 'value' | 'max'>`. ## Example — determinate ```tsx import { Progress } from '@misoto22/folio'
``` ## Example — indeterminate ```tsx import { Progress, Text } from '@misoto22/folio'
Rebuilding the search index Started 40 seconds ago. No estimate yet.
``` ## Example — bytes into percent ```tsx import { Progress, Text } from '@misoto22/folio'
18.2 MB of 29.4 MB
```