Angular Stepper Component | ng-hub-ui-stepper
Angular stepper component with validation, orientation modes, custom controls, i18n and CSS-variable theming.
API reference
Here's the full contract for stepper: everything you can bind, listen to, project and theme, gathered in one place. Wire up what you need and style what you want — it's standalone and signal-friendly.
Inputs
Dial stepper in with 13 inputs. Bind them like any Angular @Input.
| Name | Type | Default | Description |
|---|---|---|---|
options (hub-stepper) | StepperOptions | {} | Stepper configuration object: `layout` (`vertical` | `sidebar`) and `rtl` (boolean). |
variant (hub-stepper) | string | undefined | Semantic accent applied to the active step pill and the next / submit controls. Built-in values: `primary`, `secondary`, `success`, `danger`, `warning`, `info`, `neutral`, `light`, `dark`; any other string resolves through `--hub-sys-color-<variant>`. |
backLabel (hub-stepper) | string | null | null | Overrides the "Back" control label. Falls back to the built-in i18n label when null. |
continueLabel (hub-stepper) | string | null | null | Overrides the "Continue" control label. |
submitLabel (hub-stepper) | string | null | null | Overrides the final-step "Submit" control label. |
truncateTitles (hub-stepper) | boolean | false | Clips each rail step title to `--hub-stepper-nav-title-max-width` (default `12rem`) and reveals the full text as a tooltip when it overflows. |
railLabel (hub-stepper) | string | 'Steps' | Accessible name of the step rail tablist. |
nav (hub-stepper) | 'pills' | 'track' | 'pills' | Which rail the stepper draws. `pills` is what it has always drawn. `track` is the inline variant: a numbered marker per step, a tick on a step that is in order, and a connector that takes the accent as it leaves one. |
inOrderLabel (hub-stepper) | string | null | null | What a screen reader hears on a ticked marker. The tick itself is decorative, so this is the only thing that says the step is in order. Falls back to the bundled dictionary. |
beforeStepChange (hub-stepper) | StepperStepChangeGuard | null | null | A gate the stepper asks before it moves, so a wizard can save first. It runs with the index still where it was, and returning `false` — or a promise that resolves `false`, or a rejection — keeps the stepper where it stands. An output could not do this: by the time one fires the step has already changed. |
title (hub-step) | string | undefined | The step title shown in the stepper navigation. |
disabled (hub-step) | boolean | false | Disables navigation to this step. |
valid (hub-step) | boolean | null | null | The wizard's verdict on this step's own data. Three states, and the third matters: `true`, `false`, or `null` meaning nobody has said. The library never inspects a form — it records the answer, and the rail reasons with it. |
Outputs
React to what stepper does — 3 events to hook your logic onto.
| Name | Type | Description |
|---|---|---|
completed (hub-stepper) | OutputEmitterRef<void> | Emitted when the user submits the final step. |
nextStep (hub-stepper) | OutputEmitterRef<number> | Emitted when advancing to a step, with the new step index. |
previousStep (hub-stepper) | OutputEmitterRef<number> | Emitted when going back to a step, with the new step index. |
Templates
Make it yours — 4 template slots let you project custom markup.
| Name | Description | Example |
|---|---|---|
stepperNav / hubStepperNav | Replaces the whole default step rail. The template context exposes steps (the projected StepComponent instances) and currentIndex, so bind let-steps="steps" and let-currentIndex="currentIndex". | <hub-stepper>
<ng-template hubStepperNav let-steps="steps" let-currentIndex="currentIndex">
<ol class="my-rail">
@for (step of steps; track step; let i = $index) {
<li [class.current]="i === currentIndex">{{ step.title() || 'Step ' + (i + 1) }}</li>
}
</ol>
</ng-template>
<hub-step title="Account">…</hub-step>
<hub-step title="Review">…</hub-step>
</hub-stepper> |
stepTrigger / hubStepTrigger | Replaces the control the default rail draws inside each item, keeping the rail itself — its list, its role="tablist", its orientation and its label. The context exposes the step as $implicit and as step, plus title, index, isCurrent, isCompleted and disabled; activation stays with you, through a template reference on the host. Ignored when a hubStepperNav template is present. | <hub-stepper #wizard>
<ng-template hubStepTrigger let-title="title" let-index="index" let-isCurrent="isCurrent"
let-inOrder="inOrder" let-reachable="reachable">
<button type="button" role="tab" [attr.aria-selected]="isCurrent" [disabled]="!reachable" (click)="wizard.goTo(index)">
<span class="badge">{{ inOrder ? '✓' : index + 1 }}</span> {{ title }}
</button>
</ng-template>
<hub-step title="Account" [valid]="account.valid">…</hub-step>
<hub-step title="Review">…</hub-step>
</hub-stepper> |
provideHubStepper | Registers the ten bundled dictionaries (en, es, ca, eu, gl, ast, an, de, zh and ar) and the HubTranslationService the built-in Back / Continue / Submit controls resolve their text through. This is what replaces StepperModule.forRoot(), removed in 23.0.0. | providers: [provideHubStepper({ language: 'en', fallbackLanguage: 'en' })] |
STEPPER_DICTIONARIES | The bundled dictionaries as a plain record, exported so an application can register only the languages it ships or merge them into a dictionary of its own. The keys are flat — BACK, CONTINUE and SUBMIT — because that is what the component resolves once its HUBUI.STEPPER namespace misses. | provideHubTranslation({ language: 'ca', dictionaries: { ca: { ...STEPPER_DICTIONARIES['ca'], ...myLabels } } }) |