ProgressBar
Progress bars show how far a task has got, such as an upload or a course, or that it is running with no known length.
import { ProgressBar } from '@aksornproject/aksara-ui'Basic progress bar
value is required. label is the first line and wraps when it is long. valueLabel sits on the right of the header, and description sits under the bar.
The bar fills its container with a 96px minimum. Set a width through className.
<ProgressBar
value={64}
label="Disk usage"
valueLabel="3.2 GB / 5 GB"
description="1.8 GB remaining"
className="max-w-[360px]"
/>Variants
variant sets what the fill colour means. accent is the default. positive, warning and negative carry a status, and neutral carries none.
<div className="flex w-full max-w-[360px] flex-col gap-spacing-24">
<ProgressBar value={40} label="Course progress" variant="accent" />
<ProgressBar value={100} label="Upload complete" variant="positive" />
<ProgressBar value={85} label="Storage" variant="warning" />
<ProgressBar value={95} label="Absences" variant="negative" />
<ProgressBar value={25} label="Survey responses" variant="neutral" />
</div>Range and value text
min and max default to 0 and 100, and the value is clamped to them. Screen readers hear valueLabel as the value. Without it they hear the percentage.
Changes to value ease the fill over 200ms.
<div className="flex w-full max-w-[360px] flex-col items-start gap-spacing-16">
<ProgressBar
value={marked}
max={TOTAL}
label="Marking essays"
valueLabel={`${marked} of ${TOTAL}`}
/>
<Button
size="sm"
variant="secondary-accent"
disabled={marked === TOTAL}
onClick={() => setMarked((count) => count + 1)}
>
Mark next essay
</Button>
</div>Indeterminate
value={null} means the length is unknown. The fill slides across the track and stops under prefers-reduced-motion. NaN and Infinity also draw the indeterminate bar.
<ProgressBar
value={null}
label="Importing class list"
description="This can take a minute."
className="max-w-[360px]"
/>Track only
With no label, valueLabel or description, the root holds only the track. It still needs a name, from aria-label or from aria-labelledby, here the row header.
| Unit 1: Fractions | |
|---|---|
| Unit 2: Decimals |
<table className={`${typography('body-regular')} text-color-text-primary`}>
<tbody>
<tr>
<th
id="unit-1"
scope="row"
className="pr-spacing-16 text-left font-normal"
>
Unit 1: Fractions
</th>
<td>
<ProgressBar
value={80}
aria-labelledby="unit-1"
className="w-[120px]"
/>
</td>
</tr>
<tr>
<th
id="unit-2"
scope="row"
className="pr-spacing-16 text-left font-normal"
>
Unit 2: Decimals
</th>
<td>
<ProgressBar
value={35}
aria-labelledby="unit-2"
className="w-[120px]"
/>
</td>
</tr>
</tbody>
</table>Accessibility
- The root has
role="progressbar"witharia-valuenow,aria-valueminandaria-valuemax. An indeterminate bar has noaria-valuenow. - A bar needs exactly one name. Pass a visible
label, oraria-labeloraria-labelledbywhen nothing shows. TypeScript rejects a nameless bar and alabelpaired with another name. valueLabelis hidden from screen readers and announced asaria-valuetextinstead. Without it they hear the percentage, or "indeterminate progress".descriptionis linked witharia-describedby, after any ids you pass.
API
ProgressBar
Prop
Type