Progress
Custom progress bar with color, striped, and animated variants, plus inline-value and custom compositions.
Overview
<Progress> renders both the wrapper and the inner bar from a single value prop, using its own markup instead of the HTML5 <progress> element for full control over color, stripes, animation, and text labels.
Basic usage
Pass label and showValue alongside value to render a caption and the current percentage above the bar.
import { useEffect, useState } from 'react'
import { Progress } from '@chassis-ui/react'
export const Example = () => {
const [value, setValue] = useState(10)
useEffect(() => {
const interval = setInterval(() => {
setValue((current) =>
Math.min(100, current >= 100 ? 10 : current + Math.round(Math.random() * 25))
)
}, 1000)
return () => clearInterval(interval)
}, [])
return <Progress label="Progress" showValue inlineValue value={value} />
}Inline value
Set inlineValue to display the current percentage inside the bar.
import { Progress } from '@chassis-ui/react'
export const Example = () => {
return <Progress aria-label="Example with value" inlineValue value={25} />
}Height
Setting a height value on <Progress> resizes the inner bar automatically.
import { Progress } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<Progress aria-label="1px high example" height={1} value={25} />
<Progress aria-label="20px high example" height={20} value={25} />
</>
)
}Colors
Use the color prop to change the appearance of the progress bar.
import { Progress } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<Progress aria-label="Basic (Primary) example" value={25} />
<Progress aria-label="Default example" color="default" value={25} />
<Progress aria-label="Success example" color="success" value={25} />
<Progress aria-label="Info example" color="info" value={50} />
<Progress aria-label="Warning example" color="warning" value={75} />
<Progress aria-label="Danger example" color="danger" value={100} />
</>
)
}Striped
Add the striped prop to apply a stripe via CSS gradient over the progress bar's background context.
import { Progress } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<Progress aria-label="Basic (Primary) striped example" striped value={25} />
<Progress aria-label="Default striped example" color="default" striped value={25} />
<Progress aria-label="Success striped example" color="success" striped value={25} />
<Progress aria-label="Info striped example" color="info" striped value={50} />
<Progress aria-label="Warning striped example" color="warning" striped value={75} />
<Progress aria-label="Danger striped example" color="danger" striped value={100} />
</>
)
}Animated stripes
The striped gradient can also be animated. Add the animated prop alongside striped to animate the stripes right to left via CSS3 animations.
import { Progress } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<Progress animated aria-label="Basic (Primary) animated example" striped value={25} />
<Progress animated aria-label="Success animated example" color="success" striped value={25} />
<Progress animated aria-label="Info animated example" color="info" striped value={50} />
<Progress animated aria-label="Warning animated example" color="warning" striped value={75} />
<Progress animated aria-label="Danger animated example" color="danger" striped value={100} />
</>
)
}Indeterminate
Set indeterminate when work is under way and how much of it is done isn't known: a page navigation, an upload before its size is known, a request with no progress events. The bar sweeps across the track, and the aria-valuenow, aria-valuemin and aria-valuemax attributes are left out, so a screen reader announces a progress bar and no percentage. value and inlineValue are ignored, and showValue keeps its place in the caption row empty, so nothing moves when a value arrives.
Add striped to fill the track with stripes instead of the sweep, and animated to move them. Text inside the bar belongs with striped: the sweep stretches the bar it is drawn with.
import { Progress } from '@chassis-ui/react'
export const Example = () => {
return (
<>
<Progress aria-label="Loading page" height={4} indeterminate />
<Progress color="success" indeterminate label="Connecting" />
<Progress animated indeterminate label="Uploading" striped />
</>
)
}The sweep animates transform only, so it keeps running while the page is busy. Under prefers-reduced-motion: reduce it is replaced by still stripes. Set the --cx-progress-indeterminate-animation custom property to run an animation of your own, for example a bar that grows towards the end of the track for a page navigation:
<Progress aria-label="Loading page" className="navigation-progress" height={3} indeterminate />@keyframes navigation-progress {
from {
transform: translateX(-100%);
}
to {
transform: translateX(-10%);
}
}
.navigation-progress {
--cx-progress-indeterminate-animation: 8s cubic-bezier(0.1, 0.8, 0.2, 1) forwards navigation-progress;
}The indeterminate bar is styled by @chassis-ui/react/style.css, not by @chassis-ui/css.
Custom compositions
Combine <Progress> with flex utilities to build layouts beyond the built-in inlineValue placement, like a leading label and a trailing percentage flanking the bar.
import { Progress, Flex } from '@chassis-ui/react'
export const Example = () => {
const value = 25
return (
<Flex gap="xs" align="center">
<div>Progress:</div>
<Progress aria-label="Basic example" value={value} className="w-100" />
<div className="ms-auto">{value}%</div>
</Flex>
)
}API
Progress
| Prop | Type | Default |
|---|---|---|
animated? | boolean | — |
| Use to animate the stripes right to left via CSS3 animations. | ||
asChild? | boolean | — |
Render the single child element in place of this component's own element, with this
component's classes, props and ref merged onto it: <Button asChild><Link href="/login">Log
in</Link></Button>. The alternative to component for React Server Components — an element
can be passed from the server to this package's client components, a component reference
(component={Link}) can't. | ||
className? | string | — |
| A string of all className you want applied to the component. | ||
color? | ContextColor | — |
| Sets the color of the component to one of Chassis context colors. | ||
component? | ElementType | — |
| Component used for the root node. Either a string to use a HTML element or a component. | ||
height? | number | — |
Sets the height of the component, via the --cx-height custom property. If you set that
value the inner bar (and the striped pattern's tile size) automatically resizes accordingly. | ||
indeterminate? | boolean | — |
Shows that work is under way without saying how much, for a request with no progress events.
The bar sweeps across the track, or fills it with stripes when striped is set, and the
aria-valuenow, aria-valuemin and aria-valuemax attributes are left out. value and
inlineValue are ignored, and showValue keeps its place in the caption row empty. | ||
inlineValue? | boolean | — |
Shows the current value as text inside the bar, independently of showValue — combine both
to get a label + showValue caption above the bar alongside an inlineValue reading
inside it. | ||
label? | ReactNode | — |
A text label describing the progress. Rendered in a caption row above the bar. Also used as
the default accessible name when no aria-label/aria-labelledby is supplied. | ||
ref? | any | — |
showValue? | boolean | — |
Shows the current value as text in the caption row above the bar, alongside label when
both are set, or alone otherwise. Use inlineValue to show it inside the bar instead. | ||
striped? | boolean | — |
| Adds a diagonal stripe pattern over the bar's background. | ||
value? | number | — |
| The percent to progress the ProgressBar (out of 100). | ||
ProgressBar
<ProgressBar> is the presentational inner element <Progress> renders automatically. It's exported for advanced, manual compositions (for example custom stacked layouts) — for typical use, <Progress> alone is enough. An indeterminate segment of a stacked layout needs striped: the sweep is clipped by the track, not by its segment.
| Prop | Type | Default |
|---|---|---|
animated? | boolean | — |
| Use to animate the stripes right to left via CSS3 animations. | ||
asChild? | boolean | — |
Render the single child element in place of this component's own element, with this
component's classes, props and ref merged onto it: <Button asChild><Link href="/login">Log
in</Link></Button>. The alternative to component for React Server Components — an element
can be passed from the server to this package's client components, a component reference
(component={Link}) can't. | ||
className? | string | — |
| A string of all className you want applied to the component. | ||
color? | ContextColor | — |
| Sets the color of the component to one of Chassis context colors. | ||
component? | ElementType | — |
| Component used for the root node. Either a string to use a HTML element or a component. | ||
indeterminate? | boolean | — |
Shows that work is under way without saying how much: the bar fills the track and sweeps
across it, or shows its stripes when striped is set. value is ignored. | ||
ref? | any | — |
striped? | boolean | — |
| Adds a diagonal stripe pattern over the bar's background. | ||
value? | number | — |
| The percent to progress the ProgressBar. | ||