Skip to main content

Stepper

Stepper is a progress indicator component used to display and navigate through a sequence of steps in a linear flow, such as forms, onboarding, or multi-step processes.


Usage

Basic usage

import { Stepper } from '@nofinite/nui';

<Stepper steps={['Info', 'Address', 'Payment']} active={1} />;

With step interaction

<Stepper
steps={['Start', 'Build', 'Finish']}
active={currentStep}
onChange={setCurrentStep}
/>

Variants

Stepper does not expose visual variants via props. Styling and theming are handled through CSS variables and class names.

Guidelines:

  • Use theming tokens (--color-primary, --color-border, etc.) to adapt appearance.
  • Keep step labels short for best readability.

Sizes

The component has a single default size.

Customization tip: Sizes can be adjusted via CSS by overriding:

  • .ui-stepper-circle
  • .ui-stepper-label
  • .ui-stepper-line

States

The Stepper automatically manages visual states based on the active index.

<Stepper steps={['One', 'Two', 'Three']} active={1} />

States explained:

  • Active (index === active) Highlighted circle and label, uses aria-current="step".

  • Completed (index < active) Displays a ✓ checkmark; connector line becomes active color.

  • Upcoming (index > active) Default muted appearance.


Native Props / Composition

The component renders a semantic navigation structure and supports composition through props.

<Stepper
steps={['Account', 'Verify', 'Complete']}
active={0}
onChange={(index) => console.log(index)}
className="my-custom-stepper"
/>
  • Root element: <nav>
  • Steps are rendered as <button> elements for accessibility.
  • className is forwarded to the root container.

Props

PropTypeDefaultDescription
steps(string | StepItem)[]List of steps to display
activenumberZero-based index of the active step
onChange(index: number) => voidCallback when a step is clicked
classNamestring""Additional class names for the root

StepItem

interface StepItem {
label: React.ReactNode;
}

Allows rendering custom labels (icons, formatted text, etc.).


Behavior Notes

  • Navigation is linear by default, but users can click any step if onChange is provided.
  • Completed steps automatically show a checkmark.
  • The component is fully controlled via the active prop.

Example:

<Stepper steps={steps} active={2} />

Accessibility

  • Renders inside a <nav aria-label="Progress Steps">.
  • Steps are interactive <button> elements.
  • Active step uses aria-current="step".
  • Fully keyboard accessible (Tab + Enter/Space).

Recommended usage:

<Stepper steps={['Info', 'Confirm', 'Done']} active={1} />

Layout

  • Takes full width of its container by default.
  • Steps are laid out horizontally using flexbox.
  • Connector lines automatically expand between steps.
<Stepper
steps={['Start', 'Middle', 'End']}
active={0}
style={{ maxWidth: 600 }}
/>

Best Practices

Do

  • Use for linear, ordered flows.
  • Keep step labels concise.
  • Control state externally via active.

Don’t

  • Use for non-sequential navigation.
  • Overload labels with long text.
  • Rely on it as the sole indicator of form validation.