Skip to main content
cngx-src documentation

CngxBreadcrumbSiblingsRouterSync

DirectivePrimaryv0.1.0WCAG AA

projects/ui/breadcrumb/breadcrumb-siblings-router-sync.directive.ts

Import#

import { CngxBreadcrumbSiblingsRouterSync } from '@cngx/ui/breadcrumb'

Description#

Opt-in router mode for CngxBreadcrumbSiblings. Add cngxRouterSync to a <cngx-breadcrumb-siblings> and its rows are derived from the activated route tree: the sibling routes at [depth] (the other children of that level's parent) whose data[dataKey] is a non-empty string each become a row, and the active child is marked current. The dropdown reads the set through the CNGX_BREADCRUMB_SIBLINGS_SOURCE seam (provided here via useExisting), so the directive never writes the component's [siblings] input and never injects the concrete component class - decompose-clean (Pillar 1; reference_atomic_decompose rule 4).

The navigation stream converts to a signal at the boundary via toSignal (Pillar 1, no raw subscription); the set is a computed over that trigger, depth, and dataKey, carrying a shape-based equal so a same-shape navigation does not cascade. Router is optional - without it the directive logs a dev warning and stays an empty source.

<cngx-breadcrumb-siblings cngxRouterSync [depth]="1" />
// Route config supplies the sibling labels:
{ path: 'eu', data: { breadcrumb: 'Region EU' }, children: [
  { path: 'munich', data: { breadcrumb: 'Munich' } },
  { path: 'berlin', data: { breadcrumb: 'Berlin' } },
] }

Metadata#

Providers#

CNGX_BREADCRUMB_SIBLINGS_SOURCE
useExisting CngxBreadcrumbSiblingsRouterSync

Relationships

Index#

Properties

Inputs#

dataKey#string
input()

Route data key the sibling labels are read from. Falls back through the config cascade to 'breadcrumb'; override per-instance to read a different key.

default this.cfg.router?.dataKey ?? 'breadcrumb'
depth#number
input()

Index into the activated route chain (root's first real child is 0) whose siblings are listed. 0 lists the top-level routes; 1 lists the children of the first-level active route, and so on. The directive owns this keying as its own input (mirrors the trail sync owning dataKey).

default 0

Instance Properties#

siblings#Signal
Readonly

The router-derived siblings. Wins over the component's [siblings] input.

Router-driven siblings over a nested route tree

import { ChangeDetectionStrategy, Component } from '@angular/core';
import { RouterLink, RouterOutlet } from '@angular/router';

import {
  CngxBreadcrumb,
  CngxBreadcrumbItem,
  CngxBreadcrumbSeparator,
} from '@cngx/common/interactive';
import { CngxBreadcrumbSiblings, CngxBreadcrumbSiblingsRouterSync } from '@cngx/ui/breadcrumb';

// Re-export forces compodocx to ship app.config.ts (and, transitively,
// demo-routes.ts) in the StackBlitz manifest - the router lives there.
export { appConfig } from './app.config';

/**
 * Router-driven sibling dropdown over a nested route tree.
 *
 * A hand-composed `cngxBreadcrumb` trail ends in a
 * `<cngx-breadcrumb-siblings cngxRouterSync [depth]="1">`: the directive
 * reads the activated route tree, enumerates the children of the active
 * route's parent (Munich / Berlin / Hamburg under `eu`), and marks the
 * active one `aria-current="page"`. No `[siblings]` input - the set is
 * derived from the route through the `CNGX_BREADCRUMB_SIBLINGS_SOURCE`
 * seam (Pillar 1).
 *
 * - **Navigate with the routerLink switchers.** The sibling rows the
 *   dropdown renders are native `<a href>` (SPA-link support is a later
 *   release), so use the switchers below - or browser back/forward - to
 *   move between cities and watch the dropdown's current marker follow.
 * - **Derivation, not management.** Every navigation re-derives the set;
 *   a same-shape move keeps the previous `siblings()` reference via a
 *   shape-based `equal`, so it never cascades.
 */
@Component({
  selector: 'app-root',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [
    CngxBreadcrumb,
    CngxBreadcrumbItem,
    CngxBreadcrumbSeparator,
    CngxBreadcrumbSiblings,
    CngxBreadcrumbSiblingsRouterSync,
    RouterLink,
    RouterOutlet,
  ],
  styleUrls: ['./router-driven.component.css'],
  template: `
    <p style="opacity: 0.8; font-size: 0.875rem; margin-top: 0">
      Switch city (real <code>routerLink</code> navigation), then open the
      chevron: the sibling set is derived from the route and the active city
      is marked <code>aria-current</code>.
    </p>

    <nav class="switcher" aria-label="Jump to city">
      <a routerLink="/eu/munich">Munich</a>
      <a routerLink="/eu/berlin">Berlin</a>
      <a routerLink="/eu/hamburg">Hamburg</a>
    </nav>

    <nav cngxBreadcrumb class="cngx-breadcrumb">
      <ol>
        <li><a cngxBreadcrumbItem routerLink="/">Home</a></li>
        <li cngxBreadcrumbSeparator>/</li>
        <li>
          <a cngxBreadcrumbItem>Region EU</a>
          <cngx-breadcrumb-siblings cngxRouterSync [depth]="1" />
        </li>
      </ol>
    </nav>

    <div class="outlet">
      <router-outlet></router-outlet>
    </div>
  `,
})
export class RouterDrivenSiblingsExample {}
export { RouterDrivenSiblingsExample as AppComponent };