Breadcrumbs

The <smart-breadcrumbs> component renders a list of navigation items separated by visual delimiters (chevron, slash, or arrow shape). It follows the Base + Standard + Wrapper pattern with an InjectionToken-based extension mechanism. The abstract BreadcrumbsBaseComponent defines the shared API — options (IBreadcrumbsOptions), cssClass (alias class), and the itemClick output. BreadcrumbsStandardComponent is a barebones placeholder using native <nav>, <ol>, <li>, <a>, and <button> elements. BreadcrumbsComponent is the public wrapper that renders BreadcrumbsStandardComponent by default and accepts a custom replacement via BREADCRUMBS_STANDARD_COMPONENT_TOKEN.


Usage

<smart-breadcrumbs [options]="options" (itemClick)="onItemClick($event)" />

Components

Main wrapper. Delegates to BreadcrumbsStandardComponent by default. When BREADCRUMBS_STANDARD_COMPONENT_TOKEN is provided, renders the injected component via NgComponentOutlet. Re-emits itemClick.

Barebones placeholder using native HTML. Renders a <nav class="breadcrumbs"> (with aria-label from options.ariaLabel or default "Breadcrumb") containing an <ol> of items. Each item renders as <a class="breadcrumbs-link"> (when href provided) or <button class="breadcrumbs-button"> (otherwise, emitting itemClick). Items get current class and aria-current="page" when item.current === true. Supports iconTpl (e.g. for the home item) and srOnlyLabel. Items are joined by a <span class="breadcrumbs-separator"> with a data-separator attribute reflecting options.separator (defaults to chevron).

Styled variation that extends BreadcrumbsBaseComponent and is a drop-in replacement for BreadcrumbsStandardComponent. Register it via BREADCRUMBS_STANDARD_COMPONENT_TOKEN to restyle every <smart-breadcrumbs>, or use the <smart-breadcrumbs-preset> selector directly. Translates the Preline breadcrumb: muted links (text-gray-500) that brighten to blue on hover/focus, a bold non-link current crumb (font-semibold text-gray-900), and a configurable separator SVG between crumbs selected via options.separator — chevron (default), slash (drawn slightly larger), or arrow. The options.layout field wraps the bar: contained (inline padded gray panel with rounded corners) and full-width-bar (full-width gray bar with top/bottom borders); the simple-with-slashes layout also implies a slash separator when separator is unset. Items render as <a> (when href is set and not current), <button> (no href → emits itemClick), or a plain <span> (when current). All classes are smart:-prefixed Tailwind with explicit dark: variants. Class recipes live in preset/preset-classes.util.ts (getNavClasses, getListClasses, getItemClasses, getLinkClasses, getSeparatorClasses, resolveSeparator).

Because BreadcrumbsComponent renders injected components via NgComponentOutlet (which passes inputs by canonical name), BreadcrumbsPresetComponent overrides cssClass as input<string>('') without the class alias. Bind it as [cssClass] when using the <smart-breadcrumbs-preset> selector directly, or just pass class on <smart-breadcrumbs> (the wrapper forwards it).

Abstract base directive. Exposes:

  • options: InputSignal<IBreadcrumbsOptions | undefined>
  • cssClass: InputSignal<string> (alias class)
  • itemClick: OutputEmitterRef<IBreadcrumbsItemClick>

IBreadcrumbsItemClick = { itemId: string }.

API

Inputs

InputTypeDefaultDescription
optionsInputSignal<IBreadcrumbsOptions | undefined>-Breadcrumbs configuration
classInputSignal<string>''External CSS classes (alias for cssClass)

Outputs

OutputTypeDescription
itemClickOutputEmitterRef<IBreadcrumbsItemClick>Emitted when a button-type breadcrumb is clicked

Extending the base class

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

import {
  BreadcrumbsBaseComponent,
  BreadcrumbsComponent,
  BREADCRUMBS_STANDARD_COMPONENT_TOKEN,
  IBreadcrumbsOptions,
} from '@smartsoft001/angular';

@Component({
  selector: 'docs-custom-breadcrumbs',
  template: `
    <nav
      class="docs-breadcrumbs"
      [class]="cssClass()"
      [attr.aria-label]="options()?.ariaLabel ?? 'Breadcrumb'"
    >
      <ol class="docs-breadcrumbs__list">
        @for (item of options()?.items ?? []; track item.id; let last = $last) {
          <li class="docs-breadcrumbs__item">
            <a
              class="docs-breadcrumbs__link"
              [href]="item.href ?? '#'"
              [attr.aria-current]="item.current ? 'page' : null"
              (click)="select($event, item.id)"
            >
              {{ item.label }}
            </a>

            @if (!last) {
              <span class="docs-breadcrumbs__separator" aria-hidden="true">
                /
              </span>
            }
          </li>
        }
      </ol>
    </nav>
  `,
  encapsulation: ViewEncapsulation.None,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CustomBreadcrumbsComponent extends BreadcrumbsBaseComponent {
  // NgComponentOutlet passes 'cssClass' by canonical name, not the 'class' alias.
  override cssClass = input<string>('');

  select(event: MouseEvent, itemId: string): void {
    event.preventDefault();
    this.itemClick.emit({ itemId });
  }
}

@Component({
  selector: 'docs-breadcrumbs-custom-example',
  imports: [BreadcrumbsComponent],
  providers: [
    {
      provide: BREADCRUMBS_STANDARD_COMPONENT_TOKEN,
      useValue: CustomBreadcrumbsComponent,
    },
  ],
  template: `<smart-breadcrumbs [options]="options" />`,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class BreadcrumbsCustomExampleComponent {
  options: IBreadcrumbsOptions = {
    separator: 'slash',
    ariaLabel: 'Breadcrumb',
    items: [
      { id: 'home', label: 'Home', href: '#' },
      { id: 'center', label: 'App Center', href: '#' },
      { id: 'app', label: 'Application', current: true },
    ],
  };
}

Source

The component lives in packages/shared/angular/src/lib/components/breadcrumbs and is documented for Claude Code by the angular-components-breadcrumbs skill.