Basic Components

[02] Basic Components

Progress

Progress is a determinate bar for a task with a known size, such as an upload or a setup step. A role="progressbar" track whose fill grows with value.

SourceEdit this page

Progress is a determinate bar: it shows how much of a task with a known size is done, such as a file upload, an import or step 3 of 8 in a setup flow. It renders a role="progressbar" track with aria-valuenow, aria-valuemin and aria-valuemax, and a fill that grows with value. It takes no children, so a label or a percentage goes beside it. When the end of the wait is unknown, use Spinner instead. Progress needs @vaneui/ui 1.4.5 or later.

Basic usage

value is required and fills the bar against max, which is 100 by default. Give the bar an aria-label, since the track itself carries no text.

<Progress value={40} aria-label="Upload"/>

md, primary, pill, transition and wFull are defaults, so a bare <Progress value={40}/> is an 8px pill bar across the full width of its parent.

Setting the range with max

Set max when the value counts something other than percent, such as steps or megabytes. value is clamped to the range 0 to max: a value above max shows a full bar and reports max in aria-valuenow, and a negative value shows an empty one.

<Col>
<Progress value={3} max={8} aria-label="Setup, step 3 of 8"/>
<Progress value={8} max={8} aria-label="Setup, step 8 of 8"/>
</Col>

Sizes

Size sets the bar height: 2, 4, 8, 12 and 16px from xs to xl, with md (8px) as the default. In a Row, flex1 lets the bar take the space its label leaves.

xs

sm

md

lg

xl

<Col>
<Row>
<Text sm secondary className="w-8">xs</Text>
<Progress xs flex1 value={60} aria-label="Progress xs"/>
</Row>
<Row>
<Text sm secondary className="w-8">sm</Text>
<Progress sm flex1 value={60} aria-label="Progress sm"/>
</Row>
<Row>
<Text sm secondary className="w-8">md</Text>
<Progress flex1 value={60} aria-label="Progress md"/>
</Row>
<Row>
<Text sm secondary className="w-8">lg</Text>
<Progress lg flex1 value={60} aria-label="Progress lg"/>
</Row>
<Row>
<Text sm secondary className="w-8">xl</Text>
<Progress xl flex1 value={60} aria-label="Progress xl"/>
</Row>
</Col>

Appearances

The fill is a filled bar in the appearance color, and the track stays neutral whatever the appearance. With the default primary, the fill is near-black in light mode and near-white in dark mode.

<Col>
<Progress value={70} aria-label="Primary"/>
<Progress accent value={70} aria-label="Accent"/>
<Progress secondary value={70} aria-label="Secondary"/>
<Progress tertiary value={70} aria-label="Tertiary"/>
<Progress success value={70} aria-label="Success"/>
<Progress danger value={70} aria-label="Danger"/>
<Progress warning value={70} aria-label="Warning"/>
<Progress info value={70} aria-label="Info"/>
</Col>

Shapes

pill is the default. rounded and sharp square the ends off, and the fill follows the shape of the track.

<Col>
<Progress lg value={45} aria-label="Pill progress"/>
<Progress lg rounded value={45} aria-label="Rounded progress"/>
<Progress lg sharp value={45} aria-label="Sharp progress"/>
</Col>

Animating the progress bar to a new value

With the default transition, the fill eases to each new value over --transition-duration (200ms); noTransition makes it jump. Under prefers-reduced-motion the fill moves without the animation. Each click below sends another megabyte, and the bar turns success once the upload completes.

quarterly-report.pdf

2 of 6MB

Uploading to the shared drive

const total = 6;
const [sent, setSent] = useState(2);
const done = sent >= total;
return (
<Card sm className="max-w-md">
<Row justifyBetween>
<Text sm fontSemibold>quarterly-report.pdf</Text>
<Text sm secondary>{sent} of {total}MB</Text>
</Row>
<Progress sm success={done} value={sent} max={total} aria-label="Uploading quarterly-report.pdf"/>
<Row justifyBetween>
<Text xs secondary>{done ? 'Upload complete' : 'Uploading to the shared drive'}</Text>
<Button xs secondary onClick={() => setSent(done ? 0 : sent + 1)}>
{done ? 'Restart' : 'Send 1MB'}
</Button>
</Row>
</Card>
);

Visible labels and value text

When a visible label names the bar, point aria-labelledby at it instead of repeating the text in aria-label. Screen readers announce a progressbar's value as a percentage of the range; for a count, aria-valuetext gives the wording to read instead.

Importing contacts

3 of 8 files

<Col>
<Row justifyBetween>
<Text sm id="import-label">Importing contacts</Text>
<Text sm secondary>3 of 8 files</Text>
</Row>
<Progress value={3} max={8} aria-labelledby="import-label" aria-valuetext="3 of 8 files"/>
</Col>

Customizing

Progress has two theme nodes for themeDefaults: progress.main for the track and progress.fill for the bar inside it. The fill follows the track's appearance, shape and transition whenever they differ from the library defaults, so most changes go on main. A fill default, such as success below, applies while the track keeps its default appearance.

<ThemeProvider themeDefaults={{
progress: { main: { sm: true }, fill: { success: true } },
}}>
<Progress value={65} aria-label="Storage used"/>
</ThemeProvider>

Progress Props

PropCategoryDefaultDescription
accent

Appearance

Accent color appearance (rose)

danger

Appearance

Danger color appearance (red)

info

Appearance

Info color appearance (cyan)

inheritAppearance

Appearance

Inherit appearance from parent — suppresses own data-appearance/data-variant, uses parent's CSS variables

primary

Appearance

✓

Primary color appearance (gray)

secondary

Appearance

Secondary color appearance (gray)

success

Appearance

Success color appearance (green)

tertiary

Appearance

Tertiary color appearance

warning

Appearance

Warning color appearance (amber)

flex1

Flex

Take up remaining space (= flex-1, i.e. flex: 1 1 0%)

flexAuto

Flex

Grow but respect intrinsic size (= flex-auto, i.e. flex: 1 1 auto)

flexNone

Flex

Don't grow and don't shrink (= flex-none, i.e. flex: none)

margin

Margin

Enable margin on all sides

marginB

Margin

Enable only bottom margin

marginT

Margin

Enable only top margin

marginX

Margin

Enable only horizontal (inline) margin

marginY

Margin

Enable only vertical (block) margin

noMargin

Margin

✓

Disable margin (reset to 0)

pill

Shape

✓

Fully rounded corners (circular)

rounded

Shape

Medium rounded corners (default)

sharp

Shape

No rounded corners (square)

lg

Size

Large size

md

Size

✓

Medium size (default)

sm

Size

Small size

xl

Size

Extra large size

xs

Size

Extra small size

Layout & utility props (gap, padding, hide, items, justify, ...) — documented on Common Props
PropCategoryDefaultDescription
desktopHide

Hide

Hide element on desktop devices and below (max-desktop: 80rem)

mobileHide

Hide

Hide element on mobile devices and below (max-mobile: 48rem)

tabletHide

Hide

Hide element on tablet devices and below (max-tablet: 64rem)

overflowAuto

Overflow

Auto overflow - show scrollbars if needed

overflowClip

Overflow

Clip overflow - hard clip without scrollbars

overflowHidden

Overflow

✓

Hidden overflow - clip content without scrollbars

overflowScroll

Overflow

Scroll overflow - always show scrollbars

overflowVisible

Overflow

Visible overflow - content extends beyond bounds

overflowXAuto

Overflow

Auto overflow on X-axis only

overflowXClip

Overflow

Clip overflow on X-axis only

overflowXHidden

Overflow

Hidden overflow on X-axis only

overflowXScroll

Overflow

Scroll overflow on X-axis only

overflowXVisible

Overflow

Visible overflow on X-axis only

overflowYAuto

Overflow

Auto overflow on Y-axis only

overflowYClip

Overflow

Clip overflow on Y-axis only

overflowYHidden

Overflow

Hidden overflow on Y-axis only

overflowYScroll

Overflow

Scroll overflow on Y-axis only

overflowYVisible

Overflow

Visible overflow on Y-axis only

noTransition

Transition

Disable transitions for instant state changes

transition

Transition

✓

Enable smooth transitions between states

wAuto

Width

Set width to auto

wFit

Width

Set width to fit-content

wFull

Width

✓

Set width to 100%

wScreen

Width

Set width to 100vw (viewport width), removes max-width constraint