Skip to content
UI

Progress

A bar that shows how far a long-running task has advanced.

@zenoxai/ui/components/progressBase UI Markdown
Scanning assets
x
<Progress value={64} className="w-full max-w-sm">
  <ProgressLabel>Scanning assets</ProgressLabel>
  <ProgressValue />
</Progress>

Usage

import {
  Progress,
  ProgressLabel,
  ProgressValue,
} from "@zenoxai/ui/components/progress"

export function ScanProgress({ value }: { value: number }) {
  return (
    <Progress value={value}>
      <ProgressLabel>Scanning assets</ProgressLabel>
      <ProgressValue />
    </Progress>
  )
}

Use a progress bar when a task reports how much of it is done: a scan, an export, an import. Progress renders the track and the indicator itself; its children (a label and a value) go on a row above the bar.

Use something else when:

  • The duration is unknown: use a Spinner. This component draws an empty track for value={null}, so it cannot show an indeterminate state.
  • The value is a measurement, not a task, such as storage used or a risk score: a progress bar tells screen readers that something is loading.

Examples

Without a label

When the label is elsewhere on screen, or the bar sits inside a row that names the task, drop the children and set aria-label on Progress.

x
<Progress
  value={30}
  aria-label="Report export"
  className="w-full max-w-sm"
/>

Custom range and value text

value runs from min to max (0 to 100 by default). ProgressValue shows a percentage unless you pass a function as its child, which receives the formatted and the raw value. Set getAriaValueText to the same text so screen readers hear it too.

Checking domains
x
<Progress
  value={12}
  max={40}
  getAriaValueText={(_, value) => `${value} of 40 domains checked`}
  className="w-full max-w-sm"
>
  <ProgressLabel>Checking domains</ProgressLabel>
  <ProgressValue>{(_, value) => `${value} of 40`}</ProgressValue>
</Progress>

Updating

The indicator animates between values. Update value as the task reports progress; at max, the root gets data-complete, which you can use to change the style or swap in a done message.

Exporting incident report
x
function ProgressSimulated() {
  const [value, setValue] = React.useState(0)
  const [started, setStarted] = React.useState(false)
  const running = started && value < 100

  React.useEffect(() => {
    if (!running) return
    const timer = setTimeout(() => setValue((current) => current + 10), 400)
    return () => clearTimeout(timer)
  }, [running, value])

  return (
    <div className="flex w-full max-w-sm flex-col items-start gap-4">
      <Progress value={value} className="w-full">
        <ProgressLabel>Exporting incident report</ProgressLabel>
        <ProgressValue />
      </Progress>
      <Button
        variant="outline"
        size="sm"
        disabled={running}
        onClick={() => {
          setValue(0)
          setStarted(true)
        }}
      >
        {value === 100 ? "Export again" : "Start export"}
      </Button>
    </div>
  )
}

Accessibility

  • The root renders role="progressbar" with aria-valuenow, aria-valuemin and aria-valuemax. ProgressLabel names it through aria-labelledby; without one, set aria-label.
  • Screen readers do not announce every change of the value. When the task ends, announce the result separately, with a toast or a role="status" message.

API reference

Generated from the TypeScript source. className, style and children are accepted everywhere and omitted below.

Progress

Progress is a bar that shows how much of a task is done, such as an upload or an import. Pass `value` from 0 to `max` (100 by default), or null while the amount is unknown.

PropTypeDefault
aria-valuetextstring

A string value that provides a user-friendly name for `aria-valuenow`, the current value of the progress bar.

-
formatNumberFormatOptions

Options to format the value.

-
getAriaValueText((formattedValue: string, value: number | null) => string)

Accepts a function which returns a string value that provides a human-readable text alternative for the current value of the progress bar.

-
localeLocalesArgument

The locale used by `Intl.NumberFormat` when formatting the value. Defaults to the user's runtime locale.

-
maxnumber

The maximum value.

100
minnumber

The minimum value.

0
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ProgressRootState>

Allows you to replace the component's HTML element with a different tag, or compose it with another component.

-
value*number | null

The current value. The component is indeterminate when value is `null`.

-

ProgressTrack

ProgressTrack is the bar's background. Progress renders it already; it is exported for custom layouts.

PropTypeDefault
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ProgressTrackState>

Allows you to replace the component's HTML element with a different tag, or compose it with another component.

-

ProgressIndicator

ProgressIndicator is the filled part of the bar. Progress renders it already; it is exported for custom layouts.

PropTypeDefault
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ProgressIndicatorState>

Allows you to replace the component's HTML element with a different tag, or compose it with another component.

-

ProgressLabel

ProgressLabel names the bar, above the track on the left.

PropTypeDefault
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ProgressLabelState>

Allows you to replace the component's HTML element with a different tag, or compose it with another component.

-

ProgressValue

ProgressValue shows the formatted value, above the track on the right.

PropTypeDefault
renderReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, ProgressValueState>

Allows you to replace the component's HTML element with a different tag, or compose it with another component.

-