Skip to main content
cngx-src documentation

CngxProgressBarStepper

ComponentPrimaryOnPushNo encapsulationv0.1.0WCAG AA

projects/ui/stepper/progress-bar-stepper.component.ts

Import#

import { CngxProgressBarStepper } from '@cngx/ui/stepper'

Description#

Progress-Bar stepper variant. Thin Level-4 organism composing CngxStepperPresenter via hostDirectives and rendering the existing <cngx-progress> primitive as the visual bar instead of reinventing <div role="progressbar">. Material consumers inherit Material progress styling through CngxProgress automatically.

completedPercent() is computed from presenter.activeStepIndex() and the count of step nodes in presenter.flatSteps(). Optional [showStepCount] adds a Step N of M caption sourced from CngxStepperI18n.textStepperFormat.

https://cngxjs.github.io/cngx/examples/#/ui/stepper/progress-bar/onboarding-flow

Metadata#

Host#

Dependencies#

CNGX_STEPPER_HOSTinject()presenter

Relationships

Index#

Inputs#

ariaLabel#string | undefined
input()
default undefined, { alias: 'aria-label' }
ariaLabelledBy#string | undefined
input()
default undefined, { alias: 'aria-labelledby' }
showStepCount#boolean
input()

Render a Step N of M caption below the bar. Off by default.

default false

Instance Properties#

errorGlyph#unknown
ProtectedReadonly

Default error glyph for the error caption.

CNGX_STEPPER_GLYPHS.errorBadge
i18n#unknown
ProtectedReadonly
injectStepperI18n()
stateView#unknown
ProtectedReadonly

Shared per-step/aggregate state derivations - the single error source.

createStepperStateView({
  presenter: this.presenter,
  stepsOnly: this.presenter.stepsOnly,
})

HostBindings#

BindingExpression
[attr.aria-roledescription]"stepper"
[attr.aria-label]ariaLabel()
[attr.aria-labelledby]ariaLabelledBy()
[attr.data-state]stateView.hasAnyError() ? "error" : null
[attr.aria-invalid]stateView.hasAnyError() ? "true" : null

Structural skin for <cngx-progress-bar-stepper>.\ Theming flows through the embedded <cngx-progress> primitive's --cngx-progress-* custom properties, so this file only owns the layout (stacked bar + optional caption).

Material consumers using @cngx/themes/material/feedback-theme inherit Material progress palette automatically; no per-variant Material theme bridge is needed.

Material theme coverage across variants

import { ChangeDetectionStrategy, Component, ViewEncapsulation, signal } from '@angular/core';

import { CngxStep } from '@cngx/common/stepper';
import { CngxDotStepper, CngxProgressBarStepper, CngxTextStepper } from '@cngx/ui/stepper';

/**
 * The three indicator-only stepper variants under one Material 3 palette.
 *
 * `CngxProgressBarStepper`, `CngxDotStepper`, and `CngxTextStepper` each
 * honour the Material bridge: the progress bar inherits palette through
 * `CngxProgress`, the dot variant picks up the `--cngx-dot-step-*`
 * overrides, and the text variant follows the surrounding typography. The
 * stylesheet builds a real M3 theme in SCSS - `mat.theme` emits the
 * `--mat-sys-*` tokens and the published `@cngx/themes/material/stepper-theme`
 * bridge mixin maps the `--cngx-step-*` / `--cngx-dot-step-*` tokens onto
 * them, so nothing is hand-copied.
 */
@Component({
  selector: 'app-root',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  imports: [CngxProgressBarStepper, CngxDotStepper, CngxTextStepper, CngxStep],
  styleUrl: './variants-coverage.component.scss',
  template: `
    <div class="coverage">
      <section>
        <h3>CngxProgressBarStepper</h3>
        <cngx-progress-bar-stepper [(activeStepIndex)]="active" [showStepCount]="true" aria-label="Progress bar">
          <div cngxStep label="Customer"></div>
          <div cngxStep label="Payment"></div>
          <div cngxStep label="Review"></div>
        </cngx-progress-bar-stepper>
      </section>
      <section>
        <h3>CngxDotStepper</h3>
        <cngx-dot-stepper [(activeStepIndex)]="active" aria-label="Dots" tabindex="0">
          <div cngxStep label="Customer"></div>
          <div cngxStep label="Payment"></div>
          <div cngxStep label="Review"></div>
        </cngx-dot-stepper>
      </section>
      <section>
        <h3>CngxTextStepper</h3>
        <cngx-text-stepper [(activeStepIndex)]="active" [showCurrentLabel]="true">
          <div cngxStep label="Customer"></div>
          <div cngxStep label="Payment"></div>
          <div cngxStep label="Review"></div>
        </cngx-text-stepper>
      </section>
      <div class="coverage__toolbar">
        <button type="button" (click)="prev()">Previous</button>
        <button type="button" (click)="next()">Next</button>
        <span>Active step: {{ active() }}</span>
      </div>
    </div>
  `,
})
export class VariantsCoverageExample {
  protected readonly active = signal(1);

  protected next(): void {
    this.active.update((i) => Math.min(i + 1, 2));
  }

  protected prev(): void {
    this.active.update((i) => Math.max(i - 1, 0));
  }
}
export { VariantsCoverageExample as AppComponent };