Brik Design System
Components

Progress bar

Visual indicator of completion. Use for measurable tasks — uploads, multi-step forms, batch operations.

ProgressBar shows how far along a measurable task is. Use it whenever you can answer "what % done?" — file uploads, multi-step forms, batch syncs, scrape progress. For unmeasurable loading, use Spinner.

Use it for

  • File upload progress
  • Multi-step form completion (Step 2 of 5)
  • Batch operation progress (12 of 50 records processed)
  • Scrape / sync / migration jobs with known totals

Import

import { ProgressBar } from '@brikdesigns/bds';

Variants

Default

value is a number 0–100.

<ProgressBar value={35} label="Upload progress" />

Empty / partial / full

<ProgressBar value={0} label="Not started" />
<ProgressBar value={50} label="Halfway" />
<ProgressBar value={100} label="Complete" />

Custom fill color

fillColor overrides the brand-primary default. Use for status-coded progress (red for "deletion in progress", green for "import complete").

<ProgressBar value={75} label="Migration progress" fillColor="var(--background-positive)" />

Pattern: animated progress

Drive value from state for live progress updates. Pair with a label that includes the actual count for accessibility.

import { useState, useEffect } from 'react';

const [progress, setProgress] = useState(0);

useEffect(() => {
  const id = setInterval(() => setProgress((p) => Math.min(p + 10, 100)), 500);
  return () => clearInterval(id);
}, []);

<ProgressBar value={progress} label={`Upload progress: ${progress}%`} />

When not to use

Don't use ProgressBar for unmeasurable loading. If you can't compute a percentage ("waiting on server"), use Spinner instead. A fake "indeterminate" progress bar is worse than honest indeterminate-spinner UX.

  • Don't use ProgressBar for boolean done/not-done states. That's a Badge (Active / Failed) or Counter ("3 of 5").
  • Don't show a ProgressBar that doesn't move. A frozen progress bar is broken UX — if the value won't update for >5s, switch to a Spinner with a message.

Accessibility

  • Renders a <div> with role="progressbar", aria-valuenow, aria-valuemin="0", aria-valuemax="100".
  • Always pass label — it becomes the accessible name. Screen readers without it get "progress bar 35" with no context.

API

PropTypeDefault
valuenumber (0–100) (required)
labelstring
fillColorstringvar(--background-brand-primary)

Plus all standard <div> HTML attributes (excluding role, which ProgressBar locks to progressbar).

On this page