ProgressBar
Overviewimport { ProgressBar, ProgressCircle } from '@nili/ui';This is the library’s own overview page, rendered live. Switch the language or the theme in the header and it follows.
Basic
value is clamped to 0…max. A bare bar with no visible label needs an aria-label — there is nothing else in a table cell to name it.
import { ProgressBar } from "@nili/ui"
export function Example() {
return (
<>
<ProgressBar value={35} aria-label={t('upload')} />
<ProgressBar value={70} label={t('storage')} showValue />
<ProgressBar value={7} max={10} label="Files" valueLabel="7 of 10 files" />
</>
)
}Colors
Four colours. The colour is a signal, not decoration — warning and error should mean the number is bad, not merely high.
import { ProgressBar } from "@nili/ui"
export function Example() {
return (
<>
<ProgressBar value={40} color="primary" label="Primary" />
<ProgressBar value={100} color="success" label="Success" />
<ProgressBar value={85} color="warning" label="Warning" />
<ProgressBar value={95} color="error" label="Error" />
</>
)
}Label position and actions
labelPosition is Figma's On Top / On Right, and it is logical — end follows reading direction. linkButton is the action under the bar.
import { ProgressBar, LinkButton } from "@nili/ui"
export function Example() {
return (
<>
<ProgressBar value={60} label="Storage" labelPosition="top" showValue />
<ProgressBar value={60} label="Storage" labelPosition="end" showValue />
<ProgressBar
value={92}
color="warning"
label="Storage"
showValue
linkButton={<LinkButton href="#" size="sm">Upgrade plan</LinkButton>}
/>
</>
)
}Indeterminate
For work of unknown duration. It drops aria-valuenow, so assistive tech announces “busy” rather than inventing a percentage.
import { ProgressBar, ProgressCircle } from "@nili/ui"
export function Example() {
return (
<>
<ProgressBar indeterminate label={t('indet.syncing')} />
<ProgressCircle indeterminate aria-label={t('indet.loading')} />
</>
)
}Progress Circle
The same API in a ring. Six sizes, and thickness in pixels when the default stroke is wrong for the context.
import { ProgressCircle } from "@nili/ui"
export function Example() {
return (
<>
<ProgressCircle value={65} showValue aria-label="Complete" />
<ProgressCircle value={65} size={80} showValue aria-label="Complete" />
<ProgressCircle value={65} thickness={2} showValue aria-label="Complete" />
{/* anything in the middle */}
<ProgressCircle value={65} aria-label="Complete">
<span className="text-[12px]">65/100</span>
</ProgressCircle>
</>
)
}ProgressBar
extends ProgressCommonProps, Omit<ComponentPropsWithoutRef<'div'>, 'color' | 'children'>
Other props
| Prop | Type | Default | Notes |
|---|---|---|---|
| children | ReactNode | — | |
| aria-label | string | — | Accessible name when there is no visible `label` — a bare bar in a table cell has nothing to be named by otherwise. |
| value | number | 0 | Current value, clamped to `0…max`. Ignored while `indeterminate`. |
| max | number | 100 | |
| color | error | warning | success | primary | primary | |
| indeterminate | boolean | false | Unknown duration: drops `aria-valuenow` so assistive tech announces "busy" rather than inventing a percentage. |
| label | ReactNode | — | Visible label. Also becomes the accessible name. |
| labelPosition | end | top | top | Figma's label `Type`. |
| linkButton | ReactNode | — | Action under the bar. Figma's "Link Button". |
| showValue | boolean | false | Shows the percentage. |
| valueLabel | ReactNode | — | Overrides the rendered readout — `'3 of 10 files'`, a size, an ETA. |
| locale | string | — | BCP-47 tag driving the digits (`'fa'` → Persian). Defaults to the ambient locale from `NiliProvider`. |
ProgressCircle
extends ProgressCommonProps, Omit<ComponentPropsWithoutRef<'div'>, 'color' | 'children'>
Variant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| size | 80 | 72 | 64 | 56 | 48 | 40 | 64 |
Other props
| Prop | Type | Default | Notes |
|---|---|---|---|
| children | ReactNode | — | Content in the middle. Defaults to the percentage when `showValue`. |
| aria-label | string | — | Accessible name when there is no visible `label` — a bare bar in a table cell has nothing to be named by otherwise. |
| thickness | number | — | Stroke width in px. |
| value | number | 0 | Current value, clamped to `0…max`. Ignored while `indeterminate`. |
| max | number | 100 | |
| color | error | warning | success | primary | primary | |
| indeterminate | boolean | false | Unknown duration: drops `aria-valuenow` so assistive tech announces "busy" rather than inventing a percentage. |
| label | ReactNode | — | Visible label. Also becomes the accessible name. |
| labelPosition | end | top | — | Figma's label `Type`. |
| linkButton | ReactNode | — | Action under the bar. Figma's "Link Button". |
| showValue | boolean | true | Shows the percentage. |
| valueLabel | ReactNode | — | Overrides the rendered readout — `'3 of 10 files'`, a size, an ETA. |
| locale | string | — | BCP-47 tag driving the digits (`'fa'` → Persian). Defaults to the ambient locale from `NiliProvider`. |
ProgressCircleStroke
internalVariant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| color | primary | success | warning | error | primary |
ProgressCommon
internalOther props
| Prop | Type | Default | Notes |
|---|---|---|---|
| value | number | — | Current value, clamped to `0…max`. Ignored while `indeterminate`. |
| max | number | — | |
| color | error | warning | success | primary | — | |
| indeterminate | boolean | — | Unknown duration: drops `aria-valuenow` so assistive tech announces "busy" rather than inventing a percentage. |
| label | ReactNode | — | Visible label. Also becomes the accessible name. |
| labelPosition | end | top | — | Figma's label `Type`. |
| linkButton | ReactNode | — | Action under the bar. Figma's "Link Button". |
| showValue | boolean | — | Shows the percentage. |
| valueLabel | ReactNode | — | Overrides the rendered readout — `'3 of 10 files'`, a size, an ETA. |
| locale | string | — | BCP-47 tag driving the digits (`'fa'` → Persian). Defaults to the ambient locale from `NiliProvider`. |
| aria-label | string | — | Accessible name when there is no visible `label` — a bare bar in a table cell has nothing to be named by otherwise. |
ProgressFill
internalVariant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| color | primary | success | warning | error | primary | |
| indeterminate | 'true' | 'false' | false |
ProgressLabel
internalVariant axes — from the component’s cva definition
| Prop | Type | Default | Notes |
|---|---|---|---|
| position | top | end | top |