Progress
Progress bar component with support for standard and segmented modes.
Standard Mode
Single progress value with optional labels:
// No labels (just the bar)
<Progress value={42} aria-label="Upload progress" />
// Labels above the bar
<Progress
value={33}
labelPosition="above"
labelStart="33% Complete"
labelEnd="3/9 Steps"
/>
// Labels inline (beside the bar)
<Progress
value={67}
labelPosition="inline"
labelEnd="67%"
/>
Segmented Mode
Multiple stacked segments for comparing values (e.g., actual vs expected):
<Progress
segments={[
{ value: 24, label: 'Progress' },
{ value: 38, label: 'Expected' },
]}
/>
Note: Segmented mode only supports line mode. Passing mode="circle" with segments will cause a TypeScript error.
CSS Custom Properties
| Property | Description | Default |
|---|---|---|
--tui-progress-fill |
Bar fill color (standard mode) | Primary |
--tui-progress-track |
Track background | Border color |
--tui-progress-radius |
Border radius | Medium |
--tui-progress-block-size |
Line-mode track thickness | 1em (scales with size class) |
--tui-progress-z1-fill |
Segment 1 color | Primary |
--tui-progress-z2-fill |
Segment 2 color | Warning |
--tui-progress-z3-fill |
Segment 3 color | Success |
--tui-progress-z4-fill |
Segment 4 color | Danger |
--tui-progress-z5-fill |
Segment 5 color | Info |
Accessibility
role="progressbar"witharia-valuenow,aria-valuemin,aria-valuemaxaria-valuetextin segmented mode announces all valuesaria-busyduring indeterminate state- Respects
prefers-reduced-motion
import { Progress } from '@tangible/ui';
Interactive docs and examples: Progress in Storybook.
Progress props
| Prop | Type | Default | Description |
|---|---|---|---|
aria-label? |
string |
ARIA: Accessible name for the progress bar. Use when no visible label exists. Takes precedence over defaultLabel. |
|
aria-labelledby? |
string |
ARIA: ID of an element that labels this progress bar. Takes precedence over aria-label and defaultLabel. |
|
children? |
React.ReactNode |
Custom content to render inside the progress indicator. Line mode with inside: Replaces default content inside the bar; Circle mode with inside: Replaces centered content; Segmented mode: Replaces the segment labels area below the bar |
|
className? |
string |
Additional CSS class names to apply to the root element. | |
defaultLabel? |
string |
Fallback accessible name, rendered as visually-hidden text. Only used if neither aria-labelledby nor aria-label is provided. |
|
indeterminate? |
boolean |
false |
Only in some variants; the others reject it. Not supported in segmented mode. |
labelEnd? |
React.ReactNode |
Only in some variants; the others reject it. Not available in segmented mode. | |
labelPosition? |
"above" | "below" | "inline" | "inside" |
'inline' |
Only in some variants; the others reject it. Not available in segmented mode. Labels appear below the bar. |
labelStart? |
React.ReactNode |
Only in some variants; the others reject it. Not available in segmented mode. | |
max? |
number |
100 |
Maximum value for the progress calculation. Progress percentage = (value / max) × 100 |
mode? |
"circle" | "line" |
'line' |
Display mode. Segmented progress only supports line mode. |
segments? |
ProgressSegment[] |
Only in some variants; the others reject it. Segments to display, ordered front-to-back (z1, z2, z3...). Maximum 5 segments have default colors; beyond that, override via CSS. | |
showLabels? |
boolean |
true |
Whether to display labels. When false, hides all label content regardless of other props. |
size? |
"lg" | "md" | "sm" | "xs" |
'md' |
Size of the progress bar, affecting height and font size. 'xs': 12px font, thinnest bar (for dense step indicators); 'sm': 14px font, thinner bar; 'md': 16px font, standard bar (default); 'lg': 20px font, thicker bar |
value? |
number |
0 |
Only in some variants; the others reject it. Not available in segmented mode. |
variant? |
"ring" | "solid" |
'ring' |
Visual variant for circle mode. 'ring': Hollow centre (default) — shows progress as a ring/donut; 'solid': Filled centre — shows as a solid filled circle Only applies when mode="circle". Ignored in line mode. |
Examples
-
Line (Labels Above): Split labels above the bar — ideal for sidebar progress indicators.
-
Circle (Solid Variant): The
variant="solid"circle fills its centre instead of rendering a hollow ring. Only applies to circle mode. -
Accessibility (Labelling): Naming precedence is
aria-labelledby→aria-label→defaultLabel. Preferaria-labelledbywhen a visible heading already names the operation — one string, no drift. Segmented mode announces every segment viaaria-valuetext; indeterminate mode setsaria-busywhile it has no value to report.
Other stories: Line (No Labels), Circle (No Labels), Line (Labels Inline), Line (Inline, End Only), Line (Labels Below), Line (Label Inside), Circle (Label Inside), Circle (Ring vs Solid), Indeterminate (Line), Indeterminate (Circle), Segmented (2 segments), Segmented (Behind Schedule), Segmented (On Track), Segmented (Ahead), Segmented (3 segments), Segmented (No Label Text), Segmented (Labels Hidden), Size Variants, Segmented (Size Variants) (interactive page).
Component API tokens
Read via fallback, never declared. Set one on an ancestor to restyle every instance under it.
--tui-progress-track--tui-progress-fill--tui-progress-label--tui-progress-radius--tui-progress-block-size--tui-progress-z1-fill--tui-progress-z2-fill--tui-progress-z3-fill--tui-progress-z4-fill--tui-progress-z5-fill--tui-progress-z1-label--tui-progress-z2-label--tui-progress-z3-label--tui-progress-z4-label--tui-progress-z5-label