Skip to content
Nizivo UI

ProgressBar

A native progress bar for a task or goal, determinate or indeterminate, with a visible label and value.

Server component, no client JS

Import

import { ProgressBar } from '@nizivo/react/progress-bar';

// Once per app (Getting started), after
// @nizivo/tokens/tokens.css and @nizivo/react/css/base.css
import '@nizivo/react/css/progress-bar.css';

Static or interactive

Server. It ships no client JavaScript when a Server Component renders it, in every Next.js build mode; its code is bundled only when a client component (a 'use client' file) imports it. The indeterminate bar is a CSS animation. How to choose.

In a client app (a Vite or React Router single-page app, or a 'use client' file) it is an ordinary React component: event handlers, refs and state work as usual. In a client app.

Examples

Basic

Monthly goal
Setup guide
Uploading product photos
import type { JSX } from 'react';
import { ProgressBar } from '@nizivo/react/progress-bar';

export function ProgressBarExample(): JSX.Element {
  return (
    <div>
      <ProgressBar label="Monthly goal" value={68} />
      <ProgressBar label="Setup guide" value={3} max={5} valueText="3 of 5 steps" tone="success" />
      <ProgressBar label="Uploading product photos" indeterminate />
      <ProgressBar aria-label="Import" value={40} showValue={false} tone="neutral" />
    </div>
  );
}

Props

Server component Renders data-slot="progress-bar" with the class nz-progress-bar. Props: ProgressBarProps. Source: src/progress-bar/progress-bar.tsx.

NameTypeDefaultDescription
indeterminatebooleanfalse

Work is under way but its amount is unknown: the bar has no value.

labelReactNode–

The visible name. Without it, name the bar with aria-label or aria-labelledby.

localestring'en-US'

BCP 47 tag for the percentage.

maxnumber100

Must be above zero.

renderRenderProp<ProgressBarState>–

Composition of the root; the native <progress> inside keeps its semantics.

showValuebooleantrue

Shows the value as a percentage beside the label (hidden from assistive technology, which reads the bar itself).

toneProgressBarTone
"brand""success""warning""critical""neutral"
'brand'
valuenumber0

Clamped to 0…max.

valueTextstring–

Replaces the shown percentage and is read instead of it, for example "3 of 5 steps".

  • Also takes every attribute of <div> except children. (Omit<ComponentPropsWithRef<"div">, "children">)

render takes an element, or, in client code, a function of the props and this state (ProgressBarState):

NameTypeDefaultDescription
indeterminaterequiredboolean–
maxrequirednumber–
tonerequiredProgressBarTone
"brand""success""warning""critical""neutral"
–
valuerequirednumber | null–

The clamped value, or null while indeterminate.

Other exports

ProgressBarProps type

import type { ProgressBarProps } from '@nizivo/react/progress-bar'

The props of ProgressBar, listed above.

ProgressBarState type

import type { ProgressBarState } from '@nizivo/react/progress-bar'

The render state of ProgressBar, listed above.

ProgressBarTone type

import type { ProgressBarTone } from '@nizivo/react/progress-bar'

Figma "Tone" (Brand, Warning, Critical) plus success and neutral.

type ProgressBarTone = "brand" | "success" | "warning" | "critical" | "neutral"

Data attributes and slots

Style parts by class (.nz-<slot>) and state by data attribute. Attribute meanings come from contracts/vocabulary.json.

SlotRendered byData attributes
progress-bar
.nz-progress-bar
ProgressBar
root (takes render)
  • data-tone: "brand""success""warning""critical""neutral" ← tone
    The tone prop; values in each component manifest
progress-bar-header
.nz-progress-bar-header
ProgressBar
inner element (CSS only)
none
progress-bar-label
.nz-progress-bar-label
ProgressBar
inner element (CSS only)
none
progress-bar-track
.nz-progress-bar-track
ProgressBar
inner element (CSS only); forced colours: fill on ::-webkit-progress-value, fill on ::-moz-progress-bar
none
progress-bar-value
.nz-progress-bar-value
ProgressBar
inner element (CSS only)
none

CSS hooks

Set a hook on the component's class or any ancestor to restyle it without specificity games; leave it unset for the default shown.

HookDefaultRead as
--nz-progress-bar-fill
  • default: var(--nz-chart-primary)
  • data-tone="critical": var(--nz-chart-critical)
  • data-tone="neutral": var(--nz-chart-neutral)
  • data-tone="success": var(--nz-chart-success)
  • data-tone="warning": var(--nz-chart-warning)
  • background on .nz-progress-bar-track::-moz-progress-bar
  • background on .nz-progress-bar-track::-webkit-progress-value
  • background-image on .nz-progress-bar-track:indeterminate
--nz-progress-bar-gap--nz-space-2
  • gap on .nz-progress-bar
--nz-progress-bar-height--nz-space-2
  • block-size on .nz-progress-bar-track
--nz-progress-bar-label-font--nz-font-label-m
  • font on .nz-progress-bar-label
--nz-progress-bar-radius--nz-radius-full
  • border-radius on .nz-progress-bar-track
  • border-radius on .nz-progress-bar-track::-moz-progress-bar
  • border-radius on .nz-progress-bar-track::-webkit-progress-value
--nz-progress-bar-track-bg--nz-chart-track
  • background on .nz-progress-bar-track

Layers: nz.components. Classes: .nz-progress-bar, .nz-progress-bar-header, .nz-progress-bar-label, .nz-progress-bar-track, .nz-progress-bar-value.

Tokens this stylesheet reads (16)

--nz-chart-critical, --nz-chart-neutral, --nz-chart-primary, --nz-chart-success, --nz-chart-track, --nz-chart-warning, --nz-duration-base, --nz-duration-pulse, --nz-easing-standard, --nz-font-label-m, --nz-font-numeric-m, --nz-radius-full, --nz-space-2, --nz-space-3, --nz-text-primary, --nz-text-secondary

Accessibility

Nothing in this component takes focus or keyboard input.

In forced-colours mode these states keep a visible system colour: progress-bar-track::-webkit-progress-value (fill), progress-bar-track::-moz-progress-bar (fill).

Keyboard

None.

Figma

Node ids from design/component-map.json, which nz gen writes from component.json. The links open the Nizivo Figma library, which may ask you to sign in.

On this page