Skip to content

ProgressBox

A row of acrylic plates that light up.

tsx
import { ProgressBox } from 'neba';

<ProgressBox />
<ProgressBox value={62} label="Migrating" showValue />

Props

PropTypeDefaultDescription
valuenumber | nullnullHow far along, between min and max. null — the default — is indeterminate: an indicator that has not been told a value should say so rather than draw an empty bar
minnumber0The bottom of the range
maxnumber100The top of the range
sizeshared'xs' | 'sm' | 'md' | 'lg' | 'xl''md'The size of one plate
colorshared'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info''primary'Semantic colour role
labelReactNodeA name for what is loading. Read out with the value by a screen reader
showValuebooleanfalseShows the value as text beside the shape. Percentage of the range unless format says otherwise
formatIntl.NumberFormatOptionsHow to write the value. Without it the value is a percentage of min…max, the only formatting that holds for a range nobody described
countnumber4How many plates. Four reads as a wave and can still be counted at a glance. Set it to the number of steps when the thing being waited on genuinely has steps

Examples

How many plates

When the thing really has steps

Give count the number of steps and the plates stop being a decoration: each one is a step, and the leading plate fills as that step runs.

Why a third shape

A bar and a ring both say "this much of it is done" — they are about the quantity. A row of plates says "this is working" in the library's own vocabulary: the same cut sheet, the same hairline, the same fill. That is what makes it the right one for a loading state inside a Neba surface, where a foreign grey spinner looks borrowed.

It still answers a value when it has one. The plates fill left to right and the leading one fills partially, because four all-or-nothing plates could only ever show 0, 25, 50, 75 or 100 — and a value of 30% would round away to a quarter.

Colour, not motion

The plates never move. The wave animates the fill and the light edge and nothing else, each plate held back by its own index, so a row of them reads as a surface being written to rather than as something bouncing. Under prefers-reduced-motion the cycle simply slows to where it stops reading as motion at all.

Accessibility

Same as the other two: Base UI's Progress owns role="progressbar" and the value attributes, label is the accessible name, and an indeterminate row reports itself as indeterminate rather than as zero.

Released under the MIT License