Progress
Progress is a visual component to indicate completion of a task. It supports both determinate (specific value) and indeterminate (ongoing process) modes, with smooth animation and full ARIA compliance.
Usage
Basic usage
import { Progress } from "@nofinite/nui";
<Progress value={50} />
<Progress indeterminate />
With typical interaction
<Progress value={30} max={200} label="Uploading file" />
Variants
Progress does not have visual variants beyond determinate and indeterminate modes, which are controlled via props:
<Progress value={40} />
<Progress indeterminate />
Available modes:
determinate– displays a specific percentage based onvalue/max.indeterminate– animated bar for unknown or ongoing progress.
Guidelines:
- Use determinate when you know progress value.
- Use indeterminate when progress cannot be measured.
Sizes
Currently, Progress comes in a single height (8px) and full width by default. Height and width can be overridden via CSS.
<Progress value={50} style={{ width: '50%' }} />
States
Progress supports two primary states:
<Progress value={40} /> // determinate
<Progress indeterminate /> // indeterminate
determinate– shows completion percentage visually and via ARIA attributes.indeterminate– shows animated ongoing progress, ARIA values are undefined.
Native Props / Composition
Progress extends standard HTML <div> props:
<Progress
className="custom-progress"
aria-label="Uploading file"
data-testid="progress-1"
/>
Custom CSS can be applied via className.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | — | Current progress value (determinate mode) |
max | number | 100 | Maximum progress value |
indeterminate | boolean | false | When true or value is undefined, shows indeterminate animation |
label | string | 'Progress' | Accessible label for screen readers |
className | string | "" | Additional CSS class names |
...rest | HTMLDivElement props | — | Any other forwarded native <div> attributes |
Behavior Notes
- Width of the bar is animated smoothly when
valuechanges. - Indeterminate mode uses a looping animation; ARIA attributes for
valuenow,valuemin,valuemaxare not set. - Determinate mode clamps
valuebetween0andmax.
<Progress value={120} max={100} /> // width capped at 100%
Accessibility
-
Renders as
<div role="progressbar">. -
ARIA attributes:
aria-valuemin,aria-valuemax,aria-valuenowin determinate mode.aria-labelfor screen readers.
-
Indeterminate mode sets no
aria-valuenow,aria-valuemin, oraria-valuemax.
Example:
<Progress value={65} label="Uploading file" />
Layout
- Full-width by default (
width: 100%). - Inline or block layout can be controlled via parent container.
- Rounded corners with
border-radius: var(--radius-md).
<Progress style={{ width: '50%' }} />
Best Practices
Do
- Use
determinatemode when progress value is known. - Provide meaningful
labelfor screen readers. - Combine with other UI feedback (e.g., text percentage).
Don’t
- Use
indeterminatemode for known progress values. - Overload the component with extra content inside.
- Rely on color alone to convey progress (accessibility concern).