Stepper

A progress indicator for a sequence of steps, horizontal or vertical, with optional per-step content rendered only while that step is active. Compose BbStepper with BbStep children.

Progress Only

A stepper with no step content is a progress indicator and nothing more. State is derived from position: a step behind the active one is Completed, the active one is Active, and a step ahead is Pending.

Clickable with Your Own Navigation

With Clickable each marker becomes a <button> with a focus ring. Only the active step's ChildContent renders. Supply your own Back and Next buttons and bind ActiveStep — the stepper is controlled while ActiveStepChanged is wired.

States

Pending, Active and Completed come from position. Error and Skipped must be set explicitly through BbStep.State, which always wins over the derived state. Each step also renders screen-reader-only text naming its position and state, so a state is never conveyed by colour alone.

Vertical with Icons

Vertical runs the steps down the leading side with the content beside them — leading, so it follows the reading direction. A step marker shows its Lucide Icon when one is set, and the step number otherwise. Optional adds a localized hint under the title.

Behaviour

Controlled or not. The stepper is controlled while ActiveStepChanged is wired (@bind-ActiveStep). Without a binding it keeps the index itself and treats ActiveStep as the initial value only.

Index clamping. Steps register while the child content renders, which is after the indicator above them has already rendered. The active index therefore cannot be clamped when it arrives — the step count is still zero at that moment — so it is clamped to the registered range on every read instead. An out-of-range ActiveStep resolves to the first or last step rather than throwing.

Two-pass render. Because steps register after the indicator renders, the stepper re-renders once when the registered step count changes, so the indicator comes into line with the steps that exist. Steps register keyed on the component instance, so a re-render does not duplicate one, and a disposed step unregisters with the remaining indices staying contiguous.

Clicks. A click is ignored when the step is disabled, when the index is out of range, or when the step is already active. With Clickable false the markers are static text rather than buttons.