Skip to content

ProgressBar ​

A progress bar is a task moving towards its end — a file uploading, an import working through its rows. Where the quantity is settled rather than moving, that is a Meter; and where nothing can be said about how far along a wait is, a Spinner says less and says it more honestly.

ts
import { Label, ProgressBar, ProgressBarFill, ProgressBarOutput, ProgressBarTrack } from "ropav";

ProgressBarTrack is the groove and ProgressBarFill is what travels along it. ProgressBarOutput prints the value as text, and a Label names the task the bar belongs to — without one, the bar needs an aria-label instead.

Uploading60%
color
size
template
<ProgressBar class="w-80" :value="60">
  <Label>Uploading</Label>
  <ProgressBarOutput />
  <ProgressBarTrack>
    <ProgressBarFill />
  </ProgressBarTrack>
</ProgressBar>

When the end is not known ​

is-indeterminate drops the value and animates the fill in its place, for a wait that has begun but cannot yet be measured. The bar keeps its role and simply stops reporting a number, which is the difference a screen reader is told about.

Uploading60%
Contacting the server
progress-bar-indeterminate.vue
vue
<script setup lang="ts">
import { Label, ProgressBar, ProgressBarFill, ProgressBarOutput, ProgressBarTrack } from "ropav";
</script>

<template>
  <div class="stack">
    <ProgressBar :value="60">
      <Label>Uploading</Label>
      <ProgressBarOutput />
      <ProgressBarTrack><ProgressBarFill /></ProgressBarTrack>
    </ProgressBar>

    <ProgressBar is-indeterminate>
      <Label>Contacting the server</Label>
      <ProgressBarTrack><ProgressBarFill /></ProgressBarTrack>
    </ProgressBar>
  </div>
</template>

<style scoped>
.stack {
  display: flex;
  width: 100%;
  max-width: var(--rp-container-md);
  flex-direction: column;
  gap: calc(var(--rp-spacing) * 6);
}
</style>

Stripes ​

is-striped lays a diagonal band over the fill and is-animated sets it travelling. Animating turns the band on by itself, so is-striped is only needed for a still one. Under reduced motion the travelling band settles into that still band rather than vanishing, so the bar does not change shape when the setting does.

Striped60%
Animated60%
progress-bar-striped.vue
vue
<script setup lang="ts">
import { Label, ProgressBar, ProgressBarFill, ProgressBarOutput, ProgressBarTrack } from "ropav";

const bars = [
  { animated: false, label: "Striped", striped: true },
  { animated: true, label: "Animated", striped: false },
] as const;
</script>

<template>
  <div class="stack">
    <ProgressBar
      v-for="bar in bars"
      :key="bar.label"
      :is-animated="bar.animated"
      :is-striped="bar.striped"
      :value="60"
    >
      <Label>{{ bar.label }}</Label>
      <ProgressBarOutput />
      <ProgressBarTrack><ProgressBarFill /></ProgressBarTrack>
    </ProgressBar>
  </div>
</template>

<style scoped>
.stack {
  display: flex;
  width: 100%;
  max-width: var(--rp-container-md);
  flex-direction: column;
  gap: calc(var(--rp-spacing) * 6);
}
</style>

Accessibility ​

  • The bar is a role="progressbar" carrying aria-valuenow, aria-valuemin and aria-valuemax, so its value is announced as a proportion rather than as a bare number.
  • format-options decides how that value reads — a percentage by default, but bytes or a plain count where those are what the reader is actually waiting on. value-label replaces the text outright.
  • An indeterminate bar drops aria-valuenow rather than reporting zero, which is what stops it being read as no progress at all.
  • Name the task, not the widget. A label reading "Uploading" tells the reader what is happening; one reading "Progress" tells them what they can already see.

API ​

ProgressBar

PropTypeDefaultDescription
ariaDescribedbystring—
ariaLabelstring—
ariaLabelledbystring—
color"default" | "accent" | "success" | "warning" | "danger""accent"Progress bar color.
formatOptionsIntl.NumberFormatOptions{style: "percent"}Localized number formatting.
idstring—
isAnimatedboolean—Whether the band travels. Turns the band on by itself, so isStriped is only needed for a still one. Under reduced motion it settles into that still band rather than disappearing.
isIndeterminateboolean—Whether progress is not currently measurable.
isStripedboolean—Whether a diagonal band is laid over the fill.
maxValuenumber100
minValuenumber0
size"xs" | "sm" | "md" | "lg""md"Progress bar size.
valuenumber0Current progress.
valueLabelstring—Explicit text announced and rendered for the current value.

The default slot receives:

Slot propType
isIndeterminateboolean
percentagenumber | undefined
valueTextstring | undefined

ProgressBarFill

PropTypeDefaultDescription
stylestring | CSSProperties—

ProgressBarOutput

Slots: default.

ProgressBarTrack

Slots: default.