Skip to content

BbProgress

A progress bar that draws the value you bind, in your own units.

import { BbProgress } from 'bitboss-ui';

On this page

Use it for

Use BbProgress when you can measure how far along a task is: bytes uploaded, steps completed, gigabytes of a quota consumed.

Use something else when

  • BbSpinner, when the wait cannot be measured and there is no bar to keep on screen
  • BbTable, when a table is fetching: its skeleton rows say more

Passthrough

Hover or tap a part to outline it. The toggles turn on loading, errors and warnings where the component has them; only parts get a row.

Track measurable work

Bind the value you already own and let max do the arithmetic in the task's real units.

  • Q3 board deck.pdf8 MB · Done
  • Warehouse photos.zip18.8 MB of 49.6 MB
  • Catalogue export 2026-08.csvWaiting
  • Supplier contract (signed).pdfUpload failed

The bar is display-only: it emits no events, and v-model writes nothing back.

Your own units

Megabytes, euros and steps all work as they are, so there is no percentage to compute first.

min moves the lower bound for a range that does not start at zero: a sales floor, an XP band. Leave it at zero on such a range and the bar still looks reasonable while showing the wrong fraction. Values outside the range from min to max are clamped.

Q3 revenue €310k
Floor €250k · target €370k

A bar that moves

The bar follows your state and never drives it, animating each change over 250 ms. Do not add a transition of your own.

Create workspace0 of 4 done

There are no events, so derive completion from the same state that feeds the bar, and announce it yourself: a bar reaching its end is silent.

In a real upload the value comes from your request layer. BbDropzone captures and validates the files but does not send them, so the request and the progress it reports stay yours.

ts
const sentBytes = ref(0);

await axios.post('/imports', form, {
    onUploadProgress: (event) => (sentBytes.value = event.loaded),
});

When there is no number

Set indeterminate while the wait has no measurable end: the bar slides and announces no value, and any aria-valuetext you set waits until it turns off.

catalogue-2026-08.csv640 KB

The boundary worth handling is the end of an upload, where the bytes stop and the work does not. Switch the same bar to indeterminate there rather than creeping it toward 99%. A model-value of null alone is an empty bar, not a moving one.

Naming and announcing

The bar already carries role="progressbar" and its values, so do not repeat the role on a wrapper. label becomes the aria-label; a bar with no label, aria-label or aria-labelledby is an error for npx bitboss-ui check and the ESLint rule require-accessible-name.

Print the number beside the bar: geometry alone is not a readable value. aria-valuetext gives screen readers the unit a raw number lacks.

vue
<BbProgress
    aria-valuetext="220 of 500 gigabytes"
    label="Storage used"
    :max="500"
    :model-value="220"
/>

Track and fill

There are no size or colour props. Four locals do the job, the same words as BbSlider's rail and bar: --track (the height, 4px), --track-color (the unfilled track, var(--bb-track)), --accent (the bar, var(--bb-primary)) and --r (the radius of both, var(--bb-radius)).

Onboarding · 45%
Storage · 46 / 50 GB
Nearly full

Point --accent at a token rather than a hex, so a retinted bar still follows the theme.