Brik Design System
Components

Progress stepper

Step indicator for multi-step flows. Two variants — labeled vertical steps and compact horizontal dots.

ProgressStepper shows where the user is in a multi-step flow. One component, two layouts: steps (labeled, vertical or horizontal with descriptions) and dots (compact horizontal indicator). Both share the same activeStep, linear, and onStepClick model.

The dots variant replaced the standalone ProgressDots component per ADR-004 §3 — same shape, same logic, different layout = one component with a variant prop, not two.

Note: this is not the same as Stepper — that's a numeric +/− input.

Use it for

  • Checkout / signup / setup wizard step indicators
  • Multi-page form progress
  • Onboarding flow markers
  • Any sequential flow where the user benefits from seeing position + total steps

For boolean done/in-progress on a single task, use ProgressBar. For numeric input, use Stepper.

Import

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

Variants

Steps (default, labeled)

<ProgressStepper
  steps={[
    { label: 'Account' },
    { label: 'Profile' },
    { label: 'Review' },
  ]}
  activeStep={1}
/>

Steps with descriptions

<ProgressStepper
  steps={[
    { label: 'Details', description: 'Enter your information' },
    { label: 'Payment', description: 'Add billing details' },
    { label: 'Confirm', description: 'Review and submit' },
  ]}
  activeStep={0}
  onStepClick={(step) => setStep(step)}
/>

Dots variant — compact horizontal

The active dot stretches wider; completed dots are dimmed; upcoming dots are muted. No label text — pair with a page heading or step counter.

<ProgressStepper
  variant="dots"
  count={5}
  activeStep={2}
  onStepClick={(step) => setStep(step)}
/>

Linear mode

Restrict navigation to sequential steps — clicking a future step beyond activeStep + 1 is blocked. Use for flows where steps depend on completion of prior ones.

<ProgressStepper
  steps={steps}
  activeStep={1}
  linear
  onStepClick={(step) => setStep(step)}
/>

Sizes

sm for constrained layouts, md (default) otherwise.

<ProgressStepper steps={steps} activeStep={0} size="sm" />

When not to use

Don't use ProgressStepper for measurable progress within a single task. That's ProgressBar. ProgressStepper is for between discrete steps; ProgressBar is for within a single step.

  • Don't use Steps with >5 entries. A 7-step labeled flow is unscannable — switch to dots and lean on the page heading for context.
  • Don't use Dots for unfamiliar flows. Without labels, dots assume the user already knows what each step is about. Use Steps for first-time-user flows.

Accessibility

  • Renders an <ol> with aria-label describing the flow.
  • Active step carries aria-current="step".
  • onStepClick makes each step a real <button> — keyboard navigation, focus ring all work.
  • linear mode disables future steps via aria-disabled so assistive tech announces the constraint.

API

PropTypeDefault
variant'steps' | 'dots''steps'
activeStepnumber (0-indexed)
stepsArray<{ label: string; description?: string }> (steps variant)
countnumber (dots variant)
linearbooleanfalse
onStepClick(step: number) => void
size'sm' | 'md''md'

The steps and count props are mutually exclusive — variant="steps" requires steps, variant="dots" requires count.

On this page