Skip to main content

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 on value/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

PropTypeDefaultDescription
valuenumberCurrent progress value (determinate mode)
maxnumber100Maximum progress value
indeterminatebooleanfalseWhen true or value is undefined, shows indeterminate animation
labelstring'Progress'Accessible label for screen readers
classNamestring""Additional CSS class names
...restHTMLDivElement propsAny other forwarded native <div> attributes

Behavior Notes

  • Width of the bar is animated smoothly when value changes.
  • Indeterminate mode uses a looping animation; ARIA attributes for valuenow, valuemin, valuemax are not set.
  • Determinate mode clamps value between 0 and max.
<Progress value={120} max={100} /> // width capped at 100%

Accessibility

  • Renders as <div role="progressbar">.

  • ARIA attributes:

    • aria-valuemin, aria-valuemax, aria-valuenow in determinate mode.
    • aria-label for screen readers.
  • Indeterminate mode sets no aria-valuenow, aria-valuemin, or aria-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 determinate mode when progress value is known.
  • Provide meaningful label for screen readers.
  • Combine with other UI feedback (e.g., text percentage).

Don’t

  • Use indeterminate mode for known progress values.
  • Overload the component with extra content inside.
  • Rely on color alone to convey progress (accessibility concern).