Progress
A Base UI Progress for task completion: uploads, step position in a form, reading or quiz progress. It is drawn in ink only, and the value is always shown in text.
import { Progress } from '@fairgarden-private/design/components/Progress'
The label is a caps label, the value a data figure ("62%", "2 of 4"). Every part is the scope's step-12 ink on the ground, with no tinted track, so it reads on any ground. For a bounded measurement such as storage used, use a Meter instead.
Kinds and states
Kinds and states
bar is the default: an outlined 8 px track with a solid indicator. steps draws one outlined 12 px cell per step and reads "2 of 4". ring is a 2 px arc beside its value, and rail is the 2 px carousel position rail. At the maximum, the bar shows "Done" with the success glyph. value={null} is indeterminate: a dashed track with "Loading…", whose dashes move only when motion is allowed; show it only after one second. A failure or a limit is a status glyph plus words (status, statusText), never an indicator color swap; put a Retry button beside it.
'use client'
import * as React from 'react'
import { Button } from '@fairgarden-private/design/components/Button'
import { Progress } from '@fairgarden-private/design/components/Progress'
import styles from './kinds.module.css'
/** Bar, steps, ring and rail; indeterminate, complete and failed. */
export function ProgressKinds() {
const [upload, setUpload] = React.useState(62)
return (
<div className={styles.stack}>
<Progress label="Uploading trail map" value={upload} />
<div className={styles.row}>
<Button size="sm" onClick={() => setUpload((value) => Math.min(100, value + 19))}>
Upload More
</Button>
<Button size="sm" variant="text" onClick={() => setUpload(0)}>
Reset
</Button>
</div>
<Progress kind="steps" label="Membership form" value={2} max={4} />
<Progress kind="ring" label="Quiz" value={3} max={5} formatValue={(_formatted, value) => `${value} of 5`} />
<Progress label="Loading sightings" value={null} />
<Progress
label="Photo upload"
value={40}
status="danger"
statusText="Upload failed. Retry"
/>
<Progress kind="rail" label="Gallery position" value={3} max={8} formatValue={(_formatted, value) => `${value} of 8`} />
</div>
)
}
Layout
The label and value sit above a full-width track. Inside a MeterPanel (from the Meter component), label, track and value share one row once the panel is at least 768 px wide. Without a panel, the row starts at the medium breakpoint.
In print
Progress is hidden in print, except steps, which prints its "2 of 4" text.
API Reference
A Base UI Progress drawn in ink only: every part is --primary12 on the
ground, and the value is always shown in text, because the fill vanishes
in print. value={null} is indeterminate: a dashed track with “Loading…";
show it only after 1 s. Progress is hidden in print, except steps,
which prints its text.
| Prop | Type | Description |
|---|---|---|
label | | The label, in caps ( |
completeLabel | | The word shown at completion. Default “Done”. |
formatValue | | Formats the visible value ( |
indeterminateLabel | | The words beside an indeterminate track ( |
kind | |
|
primary | | Primary Radix scale: track, indicator, label and value. Never defaulted; omitted, it inherits the scope [D133]. |
secondary | | Secondary Radix scale: unused; status glyphs take their own scale. Never defaulted. |
status | | The status part beside the value. Complete progress shows |
statusText | | The status word: “Upload failed. Retry”, “Near limit”. A Retry button goes beside it. |
ProgressProps
Props for Progress: Base UI Progress Root props plus the kind and color axes, the label and the status.
type ProgressProps = {
/**
* `bar` (default): an outlined 8 px track with a solid indicator; label
* left, value right. `steps`: one outlined 12 px cell per step
* (`max` − `min` cells), "2 of 4". `ring`: a 2 px arc beside its value.
* `rail`: the 2 px carousel position rail.
*/
kind?: 'bar' | 'steps' | 'ring' | 'rail' | null;
/**
* Primary Radix scale: track, indicator, label and value. Never defaulted;
* omitted, it inherits the scope [D133].
*/
primary?:
| 'ruby'
| 'olive'
| 'sage'
| 'slate'
| 'sand'
| 'gray'
| 'mauve'
| 'brown'
| 'bronze'
| 'gold'
| 'red'
| 'crimson'
| 'tomato'
| 'pink'
| 'plum'
| 'indigo'
| 'iris'
| 'violet'
| 'purple'
| null;
/** Secondary Radix scale: unused; status glyphs take their own scale. Never defaulted. */
secondary?:
| 'ruby'
| 'olive'
| 'sage'
| 'slate'
| 'sand'
| 'gray'
| 'mauve'
| 'brown'
| 'bronze'
| 'gold'
| 'red'
| 'crimson'
| 'tomato'
| 'pink'
| 'plum'
| 'indigo'
| 'iris'
| 'violet'
| 'purple'
| 'amber'
| 'blue'
| 'cyan'
| 'grass'
| 'green'
| 'jade'
| 'lime'
| 'mint'
| 'orange'
| 'sky'
| 'teal'
| 'yellow'
| null;
/** The label, in caps (`type-label`); author it in sentence case. */
label?: React.ReactNode;
/**
* Formats the visible value (`type-data`): "62%", "3 of 5", "4.2 of 10
* GB". Default: the Base UI formatted value (a percentage), or "n of N"
* for `steps`.
*/
formatValue?: (formattedValue: string, value: number) => React.ReactNode;
/**
* The status part beside the value. Complete progress shows `success`
* with `completeLabel` unless you pass another status. A threshold is
* always a glyph plus a word, never an indicator color swap.
*/
status?: ProgressStatus;
/** The status word: "Upload failed. Retry", "Near limit". A Retry button goes beside it. */
statusText?: React.ReactNode;
/** The word shown at completion. Default "Done". */
completeLabel?: React.ReactNode;
/** The words beside an indeterminate track (`value={null}`). Default "Loading…". */
indeterminateLabel?: React.ReactNode;
}progressStatus
The status part: a §1.5.4 glyph plus a word, in the status scale [D129].
type progressStatus = progressStatusProgressStatus
A status beside the value: complete (success), near a limit (warning), failed or over (danger).
type ProgressStatus = 'success' | 'warning' | 'danger'Specification: DESIGN-SYSTEM.md §10.18 (progress and meter) and §8.9 (meters, scales and data progress).