Skip to content

ProgressCircular

A ring that fills, for where there is no room for a bar.

tsx
import { ProgressCircular } from 'neba';

<ProgressCircular value={72} showValue label="Indexing" />
<ProgressCircular />

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'Diameter of the ring. It lands just under the control ladder at every step, so dropping one into a button or a field never makes the row taller
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

Examples

Sizes

Inside a control

The ring lands just under the control ladder at every step — a md ring is 20px inside a 32px control — so dropping one into a button, a field or a table row never makes the row taller than it already was.

The number goes beside it

A percentage in the middle of a dial is the picture everyone has of this component, and it only works at two of the five sizes: at xs the ring is fourteen pixels across and there is nowhere for "40%" to go. Beside the ring, every size reads — so showValue and label sit in a row with it.

The one rotation in the library

The house style is against transforms on a control because scaling or moving one resamples its label. A ring has no label inside it: what turns is a glyph, which is the same allowance the Select chevron takes.

The arc's starting point is an SVG geometry attribute rather than a CSS transform. Without it a determinate ring would fill from three o'clock, which is not what anyone means by "72%".

Accessibility

The drawing is aria-hidden; the value reaches a screen reader through Base UI's role="progressbar" on the element around it, exactly as it does on the bar. label becomes the accessible name.

Released under the MIT License