ng-hub-ui-breadcrumbs 22.6.0 → 22.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -279,20 +279,20 @@ The main container component. It reads the breadcrumb trail directly from the An
279
279
 
280
280
  #### Inputs
281
281
 
282
- | Input | Type | Default | Description |
283
- | --------- | -------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
284
- | `variant` | `string` | `undefined` | Selects a **semantic accent** for the breadcrumb links and their hover. The built-in values (`primary`, `secondary`, `success`, `danger`, `warning`, `info`, `neutral`, `light`, `dark`) map to the exact design-system tints; **any other string is also accepted** and resolves through `--hub-sys-color-<variant>`. The current (last) item always stays muted. When omitted, links use the standard link colour (no visual change). |
285
- | `truncateItems` | `boolean` | `false` | When `true`, clips each label to `--hub-breadcrumb-max-item-width` (default `12rem`) with an ellipsis and shows the full text as a tooltip when a label overflows. Off by default, so the standard layout and wrapping are unchanged. It dresses the markup the component renders itself: a `hubBreadcrumbItem` template supplies its own elements, which the component's scoped styles cannot reach — see [`HubBreadcrumbLabelDirective`](#hubbreadcrumblabeldirective) for how a custom template opts back in. |
286
- | `items` | `BreadcrumbItem[] \| null` | `null` | Trail supplied by you, replacing the one derived from the router. The way in for crumbs the route tree cannot express — an ancestor served by another application, or a trail assembled by hand. Left `null`, the component keeps reading `HubBreadcrumbsService`. |
287
- | `maxItems` | `number \| undefined` | `undefined` | Length above which the trail collapses behind an indicator. Undefined never collapses, however long the trail grows. |
288
- | `itemsBeforeCollapse` | `number` | `1` | Crumbs kept at the head of a collapsed trail. |
289
- | `itemsAfterCollapse` | `number` | `1` | Crumbs kept at the tail of a collapsed trail, the current page included. |
290
- | `collapsedAriaLabel` | `string` | `'Show the hidden breadcrumb items'` | Accessible name of the collapsed indicator. It is an input because it is the one string this component announces, and the library carries no translations of its own. |
282
+ | Input | Type | Default | Description |
283
+ | --------------------- | -------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
284
+ | `variant` | `string` | `undefined` | Selects a **semantic accent** for the breadcrumb links and their hover. The built-in values (`primary`, `secondary`, `success`, `danger`, `warning`, `info`, `neutral`, `light`, `dark`) map to the exact design-system tints; **any other string is also accepted** and resolves through `--hub-sys-color-<variant>`. The current (last) item always stays muted. When omitted, links use the standard link colour (no visual change). |
285
+ | `truncateItems` | `boolean` | `false` | When `true`, clips each label to `--hub-breadcrumb-max-item-width` (default `12rem`) with an ellipsis and shows the full text as a tooltip when a label overflows. Off by default, so the standard layout and wrapping are unchanged. It covers a `hubBreadcrumbItem` template too: the component draws the clipping box (`span.hub-breadcrumb__custom`) around the projected content, since scoped styles cannot reach elements the consuming component owns. |
286
+ | `items` | `BreadcrumbItem[] \| null` | `null` | Trail supplied by you, replacing the one derived from the router. The way in for crumbs the route tree cannot express — an ancestor served by another application, or a trail assembled by hand. Left `null`, the component keeps reading `HubBreadcrumbsService`. |
287
+ | `maxItems` | `number \| undefined` | `undefined` | Length above which the trail collapses behind an indicator. Undefined never collapses, however long the trail grows. |
288
+ | `itemsBeforeCollapse` | `number` | `1` | Crumbs kept at the head of a collapsed trail. |
289
+ | `itemsAfterCollapse` | `number` | `1` | Crumbs kept at the tail of a collapsed trail, the current page included. |
290
+ | `collapsedAriaLabel` | `string` | `'Show the hidden breadcrumb items'` | Accessible name of the collapsed indicator. It is an input because it is the one string this component announces, and the library carries no translations of its own. |
291
291
 
292
292
  #### Outputs
293
293
 
294
- | Output | Type | Description |
295
- | ------ | ---- | ----------- |
294
+ | Output | Type | Description |
295
+ | ---------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
296
296
  | `collapsedClick` | `void` | Fires when the collapsed indicator is activated. The trail expands on its own; the event is there for consumers that want to react as well — open a menu of the hidden crumbs, log the interaction. |
297
297
 
298
298
  ```html
@@ -368,7 +368,7 @@ import { provideHubBreadcrumbTooltip } from 'ng-hub-ui-breadcrumbs';
368
368
  import { hubTooltipAdapter } from 'ng-hub-ui-utils';
369
369
 
370
370
  export const appConfig: ApplicationConfig = {
371
- providers: [provideHubBreadcrumbTooltip(hubTooltipAdapter)]
371
+ providers: [provideHubBreadcrumbTooltip(hubTooltipAdapter)]
372
372
  };
373
373
  ```
374
374
 
@@ -386,23 +386,28 @@ A structural directive used to define a custom template for breadcrumb items.
386
386
 
387
387
  ### HubBreadcrumbLabelDirective
388
388
 
389
- Adds the overflow tooltip to a breadcrumb label. The component applies it to the labels it
390
- renders itself; it is exported so a custom `hubBreadcrumbItem` template can opt back in.
389
+ Adds the overflow tooltip to a breadcrumb label. Since 22.7.0 the component wraps a
390
+ `hubBreadcrumbItem` template in its own clipping box, so a custom crumb gets the tooltip
391
+ without asking. Apply the directive by hand only to give it different text.
391
392
 
392
- | Selector | Input | Default |
393
- | ---------------------- | ----------------------------------------- | ------- |
394
- | `[hubBreadcrumbLabel]` | `hubBreadcrumbLabel: string` (alias) — explicit tooltip text | `''` |
393
+ | Selector | Input | Default |
394
+ | ---------------------- | ------------------------------------------------------------ | ------- |
395
+ | `[hubBreadcrumbLabel]` | `hubBreadcrumbLabel: string` (alias) — explicit tooltip text | `''` |
395
396
 
396
397
  Left empty, the tooltip text is the host element's own text content, and it is shown only
397
398
  while that text is actually clipped. The directive never clips anything itself: the ellipsis
398
- comes from the `truncateItems` styles, which reach only the component's own markup, so a
399
- custom template has to clip its label in its own stylesheet. Import
400
- `HubBreadcrumbLabelDirective` into the component that declares the template.
399
+ comes from the `truncateItems` styles.
400
+
401
+ Applying it by hand is optional. The component already puts it on the labels it renders and on
402
+ the box it wraps a `hubBreadcrumbItem` template in, so a custom crumb is clipped and gets its
403
+ tooltip with nothing added. Reach for the directive when the tooltip should say something other
404
+ than the label — a full path, a date spelled out — and import `HubBreadcrumbLabelDirective` into
405
+ the component that declares the template.
401
406
 
402
407
  ```html
403
408
  <hub-breadcrumb [truncateItems]="true">
404
409
  <ng-template hubBreadcrumbItem let-item>
405
- <a class="my-crumb" hubBreadcrumbLabel [routerLink]="item.url">{{ item.label }}</a>
410
+ <a class="my-crumb" [hubBreadcrumbLabel]="item.url" [routerLink]="item.url">{{ item.label }}</a>
406
411
  </ng-template>
407
412
  </hub-breadcrumb>
408
413
  ```
@@ -412,21 +417,21 @@ custom template has to clip its label in its own stylesheet. Import
412
417
  The contract truncated labels use to reach a richer tooltip. It is structurally typed and
413
418
  declared here rather than imported, so the package keeps zero hard dependencies.
414
419
 
415
- | Export | Kind | Description |
416
- | -------------------------------- | ---------------------- | ------------------------------------------------------------------------ |
417
- | `provideHubBreadcrumbTooltip()` | `EnvironmentProviders` | Registers an adapter once for the whole application. |
418
- | `HUB_BREADCRUMB_TOOLTIP_ADAPTER` | `InjectionToken` | The token the provider fills. Inject it with `{ optional: true }`. |
419
- | `HubBreadcrumbTooltipAdapter` | interface | `attach(host: HTMLElement, text: string): HubBreadcrumbTooltipHandle`. |
420
- | `HubBreadcrumbTooltipHandle` | interface | `update(text: string): void` and `destroy(): void`. |
420
+ | Export | Kind | Description |
421
+ | -------------------------------- | ---------------------- | ---------------------------------------------------------------------- |
422
+ | `provideHubBreadcrumbTooltip()` | `EnvironmentProviders` | Registers an adapter once for the whole application. |
423
+ | `HUB_BREADCRUMB_TOOLTIP_ADAPTER` | `InjectionToken` | The token the provider fills. Inject it with `{ optional: true }`. |
424
+ | `HubBreadcrumbTooltipAdapter` | interface | `attach(host: HTMLElement, text: string): HubBreadcrumbTooltipHandle`. |
425
+ | `HubBreadcrumbTooltipHandle` | interface | `update(text: string): void` and `destroy(): void`. |
421
426
 
422
427
  ### HubBreadcrumbsService
423
428
 
424
429
  An injectable (`providedIn: 'root'`) service that publishes the breadcrumb trail. The component reads the signal; you can also inject it directly when you need the breadcrumb data elsewhere.
425
430
 
426
- | Member | Type | Description |
427
- | -------------- | ------------------------------ | ---------------------------------------------------------------------------------- |
428
- | `breadcrumbs` | `Signal<BreadcrumbItem[]>` | The current trail. Read it in a template or a `computed`, with nothing to wrap. |
429
- | `breadcrumbs$` | `Observable<BreadcrumbItem[]>` | The same trail as a stream, for code already composing with rxjs. |
431
+ | Member | Type | Description |
432
+ | -------------- | ------------------------------ | ------------------------------------------------------------------------------- |
433
+ | `breadcrumbs` | `Signal<BreadcrumbItem[]>` | The current trail. Read it in a template or a `computed`, with nothing to wrap. |
434
+ | `breadcrumbs$` | `Observable<BreadcrumbItem[]>` | The same trail as a stream, for code already composing with rxjs. |
430
435
 
431
436
  Replacing the service (a test double, a facade over another source) means publishing
432
437
  `breadcrumbs`: that is the member the component reads.
@@ -439,33 +444,33 @@ Replacing the service (a test double, a facade over another source) means publis
439
444
 
440
445
  #### BreadcrumbItem
441
446
 
442
- | Property | Type | Description |
443
- | -------- | -------- | -------------------------------------------------------- |
444
- | `label` | `string` | The resolved text to display for the breadcrumb. |
445
- | `url` | `string` | The in-app destination, handed to `routerLink`. |
446
- | `data` | `any` | Optional. The original route data object (useful for icons, etc.). |
447
- | `href` | `string` | Optional. External destination. When present the crumb renders a plain anchor instead of a `routerLink`. |
448
- | `target` | `string` | Optional. Anchor `target` (e.g. `_blank`). Only meaningful alongside `href`. |
449
- | `rel` | `string` | Optional. Anchor `rel`. Left unset, a `_blank` crumb still gets `noopener noreferrer`. |
450
- | `download` | `string` | Optional. Anchor `download`: the crumb points at a file to save instead of a page to open. |
447
+ | Property | Type | Description |
448
+ | ---------- | -------- | -------------------------------------------------------------------------------------------------------- |
449
+ | `label` | `string` | The resolved text to display for the breadcrumb. |
450
+ | `url` | `string` | The in-app destination, handed to `routerLink`. |
451
+ | `data` | `any` | Optional. The original route data object (useful for icons, etc.). |
452
+ | `href` | `string` | Optional. External destination. When present the crumb renders a plain anchor instead of a `routerLink`. |
453
+ | `target` | `string` | Optional. Anchor `target` (e.g. `_blank`). Only meaningful alongside `href`. |
454
+ | `rel` | `string` | Optional. Anchor `rel`. Left unset, a `_blank` crumb still gets `noopener noreferrer`. |
455
+ | `download` | `string` | Optional. Anchor `download`: the crumb points at a file to save instead of a page to open. |
451
456
 
452
457
  #### BreadcrumbRouteConfig
453
458
 
454
459
  The object form accepted by a route's `data.breadcrumb`, for crumbs whose destination lies outside the router. The string and function forms stay valid and remain the right choice for an ordinary in-app crumb.
455
460
 
456
- | Property | Type | Description |
457
- | ---------- | ------------------------------------- | -------------------------------------------------------------- |
458
- | `label` | `string \| ((data: any) => string)` | Static label, or a function receiving the route's resolved `data`. |
459
- | `href` | `string` | Optional. Same as on `BreadcrumbItem`. |
460
- | `target` | `string` | Optional. Same as on `BreadcrumbItem`. |
461
- | `rel` | `string` | Optional. Same as on `BreadcrumbItem`. |
462
- | `download` | `string` | Optional. Same as on `BreadcrumbItem`. |
461
+ | Property | Type | Description |
462
+ | ---------- | ----------------------------------- | ------------------------------------------------------------------ |
463
+ | `label` | `string \| ((data: any) => string)` | Static label, or a function receiving the route's resolved `data`. |
464
+ | `href` | `string` | Optional. Same as on `BreadcrumbItem`. |
465
+ | `target` | `string` | Optional. Same as on `BreadcrumbItem`. |
466
+ | `rel` | `string` | Optional. Same as on `BreadcrumbItem`. |
467
+ | `download` | `string` | Optional. Same as on `BreadcrumbItem`. |
463
468
 
464
469
  #### BreadcrumbTemplateContext
465
470
 
466
- | Property | Type | Description |
467
- | ----------- | ---------------- | -------------------------------------------------------------- |
468
- | `$implicit` | `BreadcrumbItem` | The current breadcrumb item object (bound via `let-item`). |
471
+ | Property | Type | Description |
472
+ | ----------- | ---------------- | --------------------------------------------------------------- |
473
+ | `$implicit` | `BreadcrumbItem` | The current breadcrumb item object (bound via `let-item`). |
469
474
  | `isLast` | `boolean` | `true` if this item is the last one in the list (current page). |
470
475
 
471
476
  ## Styling
@@ -554,7 +559,8 @@ hub-breadcrumb.docs-breadcrumb {
554
559
  @include hub-breadcrumb-theme(
555
560
  $bg: #f8fafc,
556
561
  $padding-x: 0.75rem,
557
- $divider: "'/'", // keep the inner quotes — it feeds CSS `content`
562
+ $divider: "'/'",
563
+ // keep the inner quotes — it feeds CSS `content`
558
564
  $accent: var(--hub-sys-color-info)
559
565
  );
560
566
  }
@@ -567,7 +573,7 @@ not declared on the host, so it may sit on an ancestor and still recolour the li
567
573
 
568
574
  All notable changes are documented in the [CHANGELOG.md](./CHANGELOG.md). For breaking changes, see [BREAKING_CHANGES.md](./BREAKING_CHANGES.md).
569
575
 
570
- The latest release is **v22.5.2**, a fix for a breadcrumb drawn before the first navigation completes. The collapsing inputs, crumbs pointing outside the router and the keyboard focus ring arrived in **v22.5.0**; the packaging path `ng-hub-ui-breadcrumbs/styles` in **v22.4.0**.
576
+ The latest release is **v22.7.1**, which declares the optional `ng-hub-ui-ds` peer the token defaults have always resolved against. **v22.7.0** made `truncateItems` clip a crumb rendered by a `hubBreadcrumbItem` template, which it had never reached; **v22.6.0** published the trail as a signal on `HubBreadcrumbsService.breadcrumbs` and stopped the component re-exporting `breadcrumbs$`.
571
577
 
572
578
  ## Contributing
573
579
 
@@ -29,12 +29,16 @@ const HUB_BREADCRUMB_TOOLTIP_ADAPTER = new InjectionToken('HUB_BREADCRUMB_TOOLTI
29
29
  /**
30
30
  * Adds an overflow-aware tooltip to a breadcrumb label element.
31
31
  *
32
- * Apply `[hubBreadcrumbLabel]` to the link/text of each breadcrumb item. When the
33
- * label is truncated (its rendered text is wider than its box — typically because
34
- * `hub-breadcrumb` truncation is enabled), the directive exposes the full text as
35
- * a tooltip: the native `title` attribute by default, or the richer hub-ui
32
+ * When the label is truncated (its rendered text is wider than its box — typically
33
+ * because `hub-breadcrumb` truncation is enabled), the directive exposes the full
34
+ * text as a tooltip: the native `title` attribute by default, or the richer hub-ui
36
35
  * tooltip when a {@link HUB_BREADCRUMB_TOOLTIP_ADAPTER} is provided. When the
37
36
  * label fits, no tooltip is shown.
37
+ *
38
+ * `hub-breadcrumb` already applies it to the labels it renders and to the box it
39
+ * wraps a `hubBreadcrumbItem` template in, so applying `[hubBreadcrumbLabel]` by
40
+ * hand is for saying something other than the label — a full path, a spelled-out
41
+ * date — through the directive's own input.
38
42
  */
39
43
  class HubBreadcrumbLabelDirective {
40
44
  /**
@@ -252,6 +256,10 @@ class HubBreadcrumbComponent {
252
256
  * exposes its full text as a tooltip (native `title`, or the hub-ui tooltip
253
257
  * when {@link provideHubBreadcrumbTooltip} is wired). Off by default, so the
254
258
  * standard breadcrumb layout is unchanged.
259
+ *
260
+ * It reaches a `hubBreadcrumbItem` template as well: the projected elements
261
+ * belong to the consuming component, so the template wraps them in a
262
+ * `span.hub-breadcrumb__custom` of its own and clips that instead.
255
263
  */
256
264
  truncateItems = input(false, /* @ts-ignore */
257
265
  ...(ngDevMode ? [{ debugName: "truncateItems" }] : /* istanbul ignore next */ []));
@@ -367,7 +375,7 @@ class HubBreadcrumbComponent {
367
375
  return item.rel ?? (item.target === '_blank' ? 'noopener noreferrer' : null);
368
376
  }
369
377
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
370
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubBreadcrumbComponent, isStandalone: true, selector: "hub-breadcrumb", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, truncateItems: { classPropertyName: "truncateItems", publicName: "truncateItems", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, maxItems: { classPropertyName: "maxItems", publicName: "maxItems", isSignal: true, isRequired: false, transformFunction: null }, itemsBeforeCollapse: { classPropertyName: "itemsBeforeCollapse", publicName: "itemsBeforeCollapse", isSignal: true, isRequired: false, transformFunction: null }, itemsAfterCollapse: { classPropertyName: "itemsAfterCollapse", publicName: "itemsAfterCollapse", isSignal: true, isRequired: false, transformFunction: null }, collapsedAriaLabel: { classPropertyName: "collapsedAriaLabel", publicName: "collapsedAriaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsedClick: "collapsedClick" }, host: { properties: { "class.hub-breadcrumb--truncate": "truncateItems()", "attr.data-variant": "variant() ?? null", "style.--hub-breadcrumb-accent": "customAccent()" }, classAttribute: "hub-breadcrumb" }, queries: [{ propertyName: "itemTemplate", first: true, predicate: HubBreadcrumbItemDirective, descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: "<nav aria-label=\"breadcrumb\" class=\"hub-breadcrumb__nav\">\n\t<ol class=\"hub-breadcrumb__list\">\n\t\t@for (row of rows(); track $index) {\n\t\t\t@if (row.item; as item) {\n\t\t\t\t<li\n\t\t\t\t\tclass=\"hub-breadcrumb__item\"\n\t\t\t\t\t[class.hub-breadcrumb__item--active]=\"row.isLast\"\n\t\t\t\t\t[attr.aria-current]=\"row.isLast ? 'page' : null\"\n\t\t\t\t>\n\t\t\t\t\t@if (itemTemplate(); as template) {\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"template\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{\n\t\t\t\t\t\t\t\t$implicit: item,\n\t\t\t\t\t\t\t\tisLast: row.isLast\n\t\t\t\t\t\t\t}\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t} @else if (row.isLast) {\n\t\t\t\t\t\t<span class=\"hub-breadcrumb__text\" hubBreadcrumbLabel>{{ item.label }}</span>\n\t\t\t\t\t} @else if (item.href) {\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\tclass=\"hub-breadcrumb__link\"\n\t\t\t\t\t\t\thubBreadcrumbLabel\n\t\t\t\t\t\t\t[href]=\"item.href\"\n\t\t\t\t\t\t\t[attr.target]=\"item.target ?? null\"\n\t\t\t\t\t\t\t[attr.rel]=\"row.rel\"\n\t\t\t\t\t\t\t[attr.download]=\"item.download ?? null\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<a [routerLink]=\"item.url\" class=\"hub-breadcrumb__link\" hubBreadcrumbLabel>\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t}\n\t\t\t\t</li>\n\t\t\t} @else {\n\t\t\t\t<li class=\"hub-breadcrumb__item hub-breadcrumb__item--collapsed\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-breadcrumb__collapsed\"\n\t\t\t\t\t\t[attr.aria-label]=\"collapsedAriaLabel()\"\n\t\t\t\t\t\t[attr.aria-expanded]=\"expanded()\"\n\t\t\t\t\t\t(click)=\"expand()\"\n\t\t\t\t\t>\n\t\t\t\t\t\t&hellip;\n\t\t\t\t\t</button>\n\t\t\t\t</li>\n\t\t\t}\n\t\t}\n\t</ol>\n</nav>\n", styles: [":root,:host{--hub-breadcrumb-padding-x: var(--hub-ref-space-3, 1rem);--hub-breadcrumb-padding-y: .25rem;--hub-breadcrumb-margin-bottom: var(--hub-ref-space-0, 0);--hub-breadcrumb-bg: var(--hub-sys-surface-page, transparent);--hub-breadcrumb-color: var(--hub-sys-text-primary, #212529);--hub-breadcrumb-border-radius: var(--hub-ref-radius-md, .375rem);--hub-breadcrumb-divider-color: var(--hub-sys-text-muted, #6c757d);--hub-breadcrumb-item-padding-x: var(--hub-ref-space-1, .25rem);--hub-breadcrumb-item-active-color: var(--hub-sys-text-muted, #6c757d);--hub-breadcrumb-accent-emphasis: color-mix(in oklch, var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd)) 80%, var(--hub-sys-color-ink, #212529));--hub-breadcrumb-accent-subtle: color-mix(in oklch, var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd)) 12%, var(--hub-sys-surface-page, #fff));--hub-breadcrumb-accent-on: oklch(from var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd)) clamp(0, (.62 - l) * 1000, 1) 0 h);--hub-breadcrumb-link-color: var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd));--hub-breadcrumb-link-hover-color: var(--hub-breadcrumb-accent-emphasis, var(--hub-sys-link-hover-color, #0a58ca));--hub-breadcrumb-link-decoration: none;--hub-breadcrumb-link-hover-decoration: underline;--hub-breadcrumb-link-focus-color: var(--hub-breadcrumb-accent-emphasis);--hub-breadcrumb-focus-bg: transparent;--hub-breadcrumb-focus-ring-width: var(--hub-sys-focus-ring-width, .25rem);--hub-breadcrumb-focus-ring-color: var(--hub-sys-focus-ring-color, rgba(13, 110, 253, .25));--hub-breadcrumb-focus-ring-radius: var(--hub-ref-radius-sm, .25rem);--hub-breadcrumb-collapsed-color: var(--hub-sys-text-muted, #6c757d);--hub-breadcrumb-collapsed-hover-color: var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd));--hub-breadcrumb-collapsed-bg: transparent;--hub-breadcrumb-collapsed-hover-bg: var(--hub-breadcrumb-accent-subtle);--hub-breadcrumb-divider: \">\";--hub-breadcrumb-divider-flipped: \"<\";--hub-breadcrumb-font-size: inherit;--hub-breadcrumb-max-item-width: 12rem}.hub-breadcrumb__nav .hub-breadcrumb__list{display:flex;flex-wrap:wrap;font-size:var(--hub-breadcrumb-font-size, inherit);padding:var(--hub-breadcrumb-padding-y, .25rem) var(--hub-breadcrumb-padding-x, var(--hub-ref-space-3, 1rem));margin-bottom:var(--hub-breadcrumb-margin-bottom, var(--hub-ref-space-0, 0));list-style:none;color:var(--hub-breadcrumb-color, var(--hub-sys-text-primary, #212529));background-color:var(--hub-breadcrumb-bg, var(--hub-sys-surface-page, transparent));border-radius:var(--hub-breadcrumb-border-radius, var(--hub-ref-radius-md, .375rem))}.hub-breadcrumb__nav .hub-breadcrumb__item+.hub-breadcrumb__item{padding-inline-start:var(--hub-breadcrumb-item-padding-x, var(--hub-ref-space-1, .25rem))}.hub-breadcrumb__nav .hub-breadcrumb__item+.hub-breadcrumb__item:before{padding-inline-end:var(--hub-breadcrumb-item-padding-x, var(--hub-ref-space-1, .25rem));color:var(--hub-breadcrumb-divider-color, var(--hub-sys-text-muted, #6c757d));content:var(--hub-breadcrumb-divider, \">\")}.hub-breadcrumb__nav .hub-breadcrumb__item--active{color:var(--hub-breadcrumb-item-active-color, var(--hub-sys-text-muted, #6c757d))}.hub-breadcrumb__nav .hub-breadcrumb__link{color:var(--hub-breadcrumb-link-color, var(--hub-sys-link-color, #0d6efd));text-decoration:var(--hub-breadcrumb-link-decoration, none)}.hub-breadcrumb__nav .hub-breadcrumb__link:hover{color:var(--hub-breadcrumb-link-hover-color, var(--hub-sys-link-hover-color, #0a58ca));text-decoration:var(--hub-breadcrumb-link-hover-decoration, underline)}.hub-breadcrumb__nav .hub-breadcrumb__collapsed{display:inline-flex;align-items:center;padding:0 .125rem;border:0;border-radius:var(--hub-breadcrumb-focus-ring-radius, var(--hub-ref-radius-sm, .25rem));background-color:var(--hub-breadcrumb-collapsed-bg, transparent);color:var(--hub-breadcrumb-collapsed-color, var(--hub-sys-text-muted, #6c757d));font:inherit;line-height:inherit;cursor:pointer}.hub-breadcrumb__nav .hub-breadcrumb__collapsed:hover{background-color:var(--hub-breadcrumb-collapsed-hover-bg);color:var(--hub-breadcrumb-collapsed-hover-color)}.hub-breadcrumb__nav .hub-breadcrumb__link:focus-visible,.hub-breadcrumb__nav .hub-breadcrumb__collapsed:focus-visible{outline:0;border-radius:var(--hub-breadcrumb-focus-ring-radius, var(--hub-ref-radius-sm, .25rem));background-color:var(--hub-breadcrumb-focus-bg, transparent);color:var(--hub-breadcrumb-link-focus-color);box-shadow:0 0 0 var(--hub-breadcrumb-focus-ring-width, var(--hub-sys-focus-ring-width, .25rem)) var(--hub-breadcrumb-focus-ring-color, var(--hub-sys-focus-ring-color, rgba(13, 110, 253, .25)))}[dir=rtl] .hub-breadcrumb__nav .hub-breadcrumb__item+.hub-breadcrumb__item:before{content:var(--hub-breadcrumb-divider-flipped, var(--hub-breadcrumb-divider, \">\"))}:host(.hub-breadcrumb--truncate) .hub-breadcrumb__nav .hub-breadcrumb__link,:host(.hub-breadcrumb--truncate) .hub-breadcrumb__nav .hub-breadcrumb__text,.hub-breadcrumb--truncate .hub-breadcrumb__nav .hub-breadcrumb__link,.hub-breadcrumb--truncate .hub-breadcrumb__nav .hub-breadcrumb__text{display:inline-block;max-inline-size:var(--hub-breadcrumb-max-item-width, 12rem);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}:host([data-variant=primary]),.hub-breadcrumb[data-variant=primary]{--hub-breadcrumb-accent: var(--hub-sys-color-primary)}:host([data-variant=secondary]),.hub-breadcrumb[data-variant=secondary]{--hub-breadcrumb-accent: var(--hub-sys-color-secondary)}:host([data-variant=success]),.hub-breadcrumb[data-variant=success]{--hub-breadcrumb-accent: var(--hub-sys-color-success)}:host([data-variant=danger]),.hub-breadcrumb[data-variant=danger]{--hub-breadcrumb-accent: var(--hub-sys-color-danger)}:host([data-variant=warning]),.hub-breadcrumb[data-variant=warning]{--hub-breadcrumb-accent: var(--hub-sys-color-warning)}:host([data-variant=info]),.hub-breadcrumb[data-variant=info]{--hub-breadcrumb-accent: var(--hub-sys-color-info)}:host([data-variant=neutral]),.hub-breadcrumb[data-variant=neutral]{--hub-breadcrumb-accent: var(--hub-sys-color-neutral)}:host([data-variant=light]),.hub-breadcrumb[data-variant=light]{--hub-breadcrumb-accent: var(--hub-sys-color-light)}:host([data-variant=dark]),.hub-breadcrumb[data-variant=dark]{--hub-breadcrumb-accent: var(--hub-sys-color-dark)}:host([data-variant]),.hub-breadcrumb[data-variant]{--hub-breadcrumb-accent-emphasis: color-mix(in oklch, var(--hub-breadcrumb-accent) 80%, var(--hub-sys-color-ink, #212529));--hub-breadcrumb-accent-subtle: color-mix(in oklch, var(--hub-breadcrumb-accent) 12%, var(--hub-sys-surface-page, #fff));--hub-breadcrumb-accent-on: oklch(from var(--hub-breadcrumb-accent) clamp(0, (.62 - l) * 1000, 1) 0 h);--hub-breadcrumb-link-hover-color: var(--hub-breadcrumb-accent-emphasis)}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: HubBreadcrumbLabelDirective, selector: "[hubBreadcrumbLabel]", inputs: ["hubBreadcrumbLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
378
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubBreadcrumbComponent, isStandalone: true, selector: "hub-breadcrumb", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, truncateItems: { classPropertyName: "truncateItems", publicName: "truncateItems", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, maxItems: { classPropertyName: "maxItems", publicName: "maxItems", isSignal: true, isRequired: false, transformFunction: null }, itemsBeforeCollapse: { classPropertyName: "itemsBeforeCollapse", publicName: "itemsBeforeCollapse", isSignal: true, isRequired: false, transformFunction: null }, itemsAfterCollapse: { classPropertyName: "itemsAfterCollapse", publicName: "itemsAfterCollapse", isSignal: true, isRequired: false, transformFunction: null }, collapsedAriaLabel: { classPropertyName: "collapsedAriaLabel", publicName: "collapsedAriaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsedClick: "collapsedClick" }, host: { properties: { "class.hub-breadcrumb--truncate": "truncateItems()", "attr.data-variant": "variant() ?? null", "style.--hub-breadcrumb-accent": "customAccent()" }, classAttribute: "hub-breadcrumb" }, queries: [{ propertyName: "itemTemplate", first: true, predicate: HubBreadcrumbItemDirective, descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: "<nav aria-label=\"breadcrumb\" class=\"hub-breadcrumb__nav\">\n\t<ol class=\"hub-breadcrumb__list\">\n\t\t@for (row of rows(); track $index) {\n\t\t\t@if (row.item; as item) {\n\t\t\t\t<li\n\t\t\t\t\tclass=\"hub-breadcrumb__item\"\n\t\t\t\t\t[class.hub-breadcrumb__item--active]=\"row.isLast\"\n\t\t\t\t\t[attr.aria-current]=\"row.isLast ? 'page' : null\"\n\t\t\t\t>\n\t\t\t\t\t@if (itemTemplate(); as template) {\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\tThe clipping box for a custom crumb. Scoped styles never reach the elements\n\t\t\t\t\t\t\ta `hubBreadcrumbItem` template renders \u2014 they belong to the consuming\n\t\t\t\t\t\t\tcomponent \u2014 so `truncateItems` can only clip something this component draws\n\t\t\t\t\t\t\titself. It sits exactly where a built-in label sits, inside the item and\n\t\t\t\t\t\t\toutside the separator, so a projected crumb gets the same width as any other.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<span class=\"hub-breadcrumb__custom\" hubBreadcrumbLabel>\n\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"template\"\n\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{\n\t\t\t\t\t\t\t\t\t$implicit: item,\n\t\t\t\t\t\t\t\t\tisLast: row.isLast\n\t\t\t\t\t\t\t\t}\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t} @else if (row.isLast) {\n\t\t\t\t\t\t<span class=\"hub-breadcrumb__text\" hubBreadcrumbLabel>{{ item.label }}</span>\n\t\t\t\t\t} @else if (item.href) {\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\tclass=\"hub-breadcrumb__link\"\n\t\t\t\t\t\t\thubBreadcrumbLabel\n\t\t\t\t\t\t\t[href]=\"item.href\"\n\t\t\t\t\t\t\t[attr.target]=\"item.target ?? null\"\n\t\t\t\t\t\t\t[attr.rel]=\"row.rel\"\n\t\t\t\t\t\t\t[attr.download]=\"item.download ?? null\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<a [routerLink]=\"item.url\" class=\"hub-breadcrumb__link\" hubBreadcrumbLabel>\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t}\n\t\t\t\t</li>\n\t\t\t} @else {\n\t\t\t\t<li class=\"hub-breadcrumb__item hub-breadcrumb__item--collapsed\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-breadcrumb__collapsed\"\n\t\t\t\t\t\t[attr.aria-label]=\"collapsedAriaLabel()\"\n\t\t\t\t\t\t[attr.aria-expanded]=\"expanded()\"\n\t\t\t\t\t\t(click)=\"expand()\"\n\t\t\t\t\t>\n\t\t\t\t\t\t&hellip;\n\t\t\t\t\t</button>\n\t\t\t\t</li>\n\t\t\t}\n\t\t}\n\t</ol>\n</nav>\n", styles: [":root,:host{--hub-breadcrumb-padding-x: var(--hub-ref-space-3, 1rem);--hub-breadcrumb-padding-y: .25rem;--hub-breadcrumb-margin-bottom: var(--hub-ref-space-0, 0);--hub-breadcrumb-bg: var(--hub-sys-surface-page, transparent);--hub-breadcrumb-color: var(--hub-sys-text-primary, #212529);--hub-breadcrumb-border-radius: var(--hub-ref-radius-md, .375rem);--hub-breadcrumb-divider-color: var(--hub-sys-text-muted, #6c757d);--hub-breadcrumb-item-padding-x: var(--hub-ref-space-1, .25rem);--hub-breadcrumb-item-active-color: var(--hub-sys-text-muted, #6c757d);--hub-breadcrumb-accent-emphasis: color-mix(in oklch, var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd)) 80%, var(--hub-sys-color-ink, #212529));--hub-breadcrumb-accent-subtle: color-mix(in oklch, var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd)) 12%, var(--hub-sys-surface-page, #fff));--hub-breadcrumb-accent-on: oklch(from var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd)) clamp(0, (.62 - l) * 1000, 1) 0 h);--hub-breadcrumb-link-color: var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd));--hub-breadcrumb-link-hover-color: var(--hub-breadcrumb-accent-emphasis, var(--hub-sys-link-hover-color, #0a58ca));--hub-breadcrumb-link-decoration: none;--hub-breadcrumb-link-hover-decoration: underline;--hub-breadcrumb-link-focus-color: var(--hub-breadcrumb-accent-emphasis);--hub-breadcrumb-focus-bg: transparent;--hub-breadcrumb-focus-ring-width: var(--hub-sys-focus-ring-width, .25rem);--hub-breadcrumb-focus-ring-color: var(--hub-sys-focus-ring-color, rgba(13, 110, 253, .25));--hub-breadcrumb-focus-ring-radius: var(--hub-ref-radius-sm, .25rem);--hub-breadcrumb-collapsed-color: var(--hub-sys-text-muted, #6c757d);--hub-breadcrumb-collapsed-hover-color: var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd));--hub-breadcrumb-collapsed-bg: transparent;--hub-breadcrumb-collapsed-hover-bg: var(--hub-breadcrumb-accent-subtle);--hub-breadcrumb-divider: \">\";--hub-breadcrumb-divider-flipped: \"<\";--hub-breadcrumb-font-size: inherit;--hub-breadcrumb-max-item-width: 12rem}.hub-breadcrumb__nav .hub-breadcrumb__list{display:flex;flex-wrap:wrap;font-size:var(--hub-breadcrumb-font-size, inherit);padding:var(--hub-breadcrumb-padding-y, .25rem) var(--hub-breadcrumb-padding-x, var(--hub-ref-space-3, 1rem));margin-bottom:var(--hub-breadcrumb-margin-bottom, var(--hub-ref-space-0, 0));list-style:none;color:var(--hub-breadcrumb-color, var(--hub-sys-text-primary, #212529));background-color:var(--hub-breadcrumb-bg, var(--hub-sys-surface-page, transparent));border-radius:var(--hub-breadcrumb-border-radius, var(--hub-ref-radius-md, .375rem))}.hub-breadcrumb__nav .hub-breadcrumb__item+.hub-breadcrumb__item{padding-inline-start:var(--hub-breadcrumb-item-padding-x, var(--hub-ref-space-1, .25rem))}.hub-breadcrumb__nav .hub-breadcrumb__item+.hub-breadcrumb__item:before{padding-inline-end:var(--hub-breadcrumb-item-padding-x, var(--hub-ref-space-1, .25rem));color:var(--hub-breadcrumb-divider-color, var(--hub-sys-text-muted, #6c757d));content:var(--hub-breadcrumb-divider, \">\")}.hub-breadcrumb__nav .hub-breadcrumb__item--active{color:var(--hub-breadcrumb-item-active-color, var(--hub-sys-text-muted, #6c757d))}.hub-breadcrumb__nav .hub-breadcrumb__link{color:var(--hub-breadcrumb-link-color, var(--hub-sys-link-color, #0d6efd));text-decoration:var(--hub-breadcrumb-link-decoration, none)}.hub-breadcrumb__nav .hub-breadcrumb__link:hover{color:var(--hub-breadcrumb-link-hover-color, var(--hub-sys-link-hover-color, #0a58ca));text-decoration:var(--hub-breadcrumb-link-hover-decoration, underline)}.hub-breadcrumb__nav .hub-breadcrumb__collapsed{display:inline-flex;align-items:center;padding:0 .125rem;border:0;border-radius:var(--hub-breadcrumb-focus-ring-radius, var(--hub-ref-radius-sm, .25rem));background-color:var(--hub-breadcrumb-collapsed-bg, transparent);color:var(--hub-breadcrumb-collapsed-color, var(--hub-sys-text-muted, #6c757d));font:inherit;line-height:inherit;cursor:pointer}.hub-breadcrumb__nav .hub-breadcrumb__collapsed:hover{background-color:var(--hub-breadcrumb-collapsed-hover-bg);color:var(--hub-breadcrumb-collapsed-hover-color)}.hub-breadcrumb__nav .hub-breadcrumb__link:focus-visible,.hub-breadcrumb__nav .hub-breadcrumb__collapsed:focus-visible{outline:0;border-radius:var(--hub-breadcrumb-focus-ring-radius, var(--hub-ref-radius-sm, .25rem));background-color:var(--hub-breadcrumb-focus-bg, transparent);color:var(--hub-breadcrumb-link-focus-color);box-shadow:0 0 0 var(--hub-breadcrumb-focus-ring-width, var(--hub-sys-focus-ring-width, .25rem)) var(--hub-breadcrumb-focus-ring-color, var(--hub-sys-focus-ring-color, rgba(13, 110, 253, .25)))}[dir=rtl] .hub-breadcrumb__nav .hub-breadcrumb__item+.hub-breadcrumb__item:before{content:var(--hub-breadcrumb-divider-flipped, var(--hub-breadcrumb-divider, \">\"))}:host(.hub-breadcrumb--truncate) .hub-breadcrumb__nav .hub-breadcrumb__link,:host(.hub-breadcrumb--truncate) .hub-breadcrumb__nav .hub-breadcrumb__text,:host(.hub-breadcrumb--truncate) .hub-breadcrumb__nav .hub-breadcrumb__custom,.hub-breadcrumb--truncate .hub-breadcrumb__nav .hub-breadcrumb__link,.hub-breadcrumb--truncate .hub-breadcrumb__nav .hub-breadcrumb__text,.hub-breadcrumb--truncate .hub-breadcrumb__nav .hub-breadcrumb__custom{display:inline-block;max-inline-size:var(--hub-breadcrumb-max-item-width, 12rem);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}:host([data-variant=primary]),.hub-breadcrumb[data-variant=primary]{--hub-breadcrumb-accent: var(--hub-sys-color-primary)}:host([data-variant=secondary]),.hub-breadcrumb[data-variant=secondary]{--hub-breadcrumb-accent: var(--hub-sys-color-secondary)}:host([data-variant=success]),.hub-breadcrumb[data-variant=success]{--hub-breadcrumb-accent: var(--hub-sys-color-success)}:host([data-variant=danger]),.hub-breadcrumb[data-variant=danger]{--hub-breadcrumb-accent: var(--hub-sys-color-danger)}:host([data-variant=warning]),.hub-breadcrumb[data-variant=warning]{--hub-breadcrumb-accent: var(--hub-sys-color-warning)}:host([data-variant=info]),.hub-breadcrumb[data-variant=info]{--hub-breadcrumb-accent: var(--hub-sys-color-info)}:host([data-variant=neutral]),.hub-breadcrumb[data-variant=neutral]{--hub-breadcrumb-accent: var(--hub-sys-color-neutral)}:host([data-variant=light]),.hub-breadcrumb[data-variant=light]{--hub-breadcrumb-accent: var(--hub-sys-color-light)}:host([data-variant=dark]),.hub-breadcrumb[data-variant=dark]{--hub-breadcrumb-accent: var(--hub-sys-color-dark)}:host([data-variant]),.hub-breadcrumb[data-variant]{--hub-breadcrumb-accent-emphasis: color-mix(in oklch, var(--hub-breadcrumb-accent) 80%, var(--hub-sys-color-ink, #212529));--hub-breadcrumb-accent-subtle: color-mix(in oklch, var(--hub-breadcrumb-accent) 12%, var(--hub-sys-surface-page, #fff));--hub-breadcrumb-accent-on: oklch(from var(--hub-breadcrumb-accent) clamp(0, (.62 - l) * 1000, 1) 0 h);--hub-breadcrumb-link-hover-color: var(--hub-breadcrumb-accent-emphasis)}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: HubBreadcrumbLabelDirective, selector: "[hubBreadcrumbLabel]", inputs: ["hubBreadcrumbLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
371
379
  }
372
380
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubBreadcrumbComponent, decorators: [{
373
381
  type: Component,
@@ -376,7 +384,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
376
384
  '[class.hub-breadcrumb--truncate]': 'truncateItems()',
377
385
  '[attr.data-variant]': 'variant() ?? null',
378
386
  '[style.--hub-breadcrumb-accent]': 'customAccent()'
379
- }, template: "<nav aria-label=\"breadcrumb\" class=\"hub-breadcrumb__nav\">\n\t<ol class=\"hub-breadcrumb__list\">\n\t\t@for (row of rows(); track $index) {\n\t\t\t@if (row.item; as item) {\n\t\t\t\t<li\n\t\t\t\t\tclass=\"hub-breadcrumb__item\"\n\t\t\t\t\t[class.hub-breadcrumb__item--active]=\"row.isLast\"\n\t\t\t\t\t[attr.aria-current]=\"row.isLast ? 'page' : null\"\n\t\t\t\t>\n\t\t\t\t\t@if (itemTemplate(); as template) {\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"template\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{\n\t\t\t\t\t\t\t\t$implicit: item,\n\t\t\t\t\t\t\t\tisLast: row.isLast\n\t\t\t\t\t\t\t}\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t} @else if (row.isLast) {\n\t\t\t\t\t\t<span class=\"hub-breadcrumb__text\" hubBreadcrumbLabel>{{ item.label }}</span>\n\t\t\t\t\t} @else if (item.href) {\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\tclass=\"hub-breadcrumb__link\"\n\t\t\t\t\t\t\thubBreadcrumbLabel\n\t\t\t\t\t\t\t[href]=\"item.href\"\n\t\t\t\t\t\t\t[attr.target]=\"item.target ?? null\"\n\t\t\t\t\t\t\t[attr.rel]=\"row.rel\"\n\t\t\t\t\t\t\t[attr.download]=\"item.download ?? null\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<a [routerLink]=\"item.url\" class=\"hub-breadcrumb__link\" hubBreadcrumbLabel>\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t}\n\t\t\t\t</li>\n\t\t\t} @else {\n\t\t\t\t<li class=\"hub-breadcrumb__item hub-breadcrumb__item--collapsed\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-breadcrumb__collapsed\"\n\t\t\t\t\t\t[attr.aria-label]=\"collapsedAriaLabel()\"\n\t\t\t\t\t\t[attr.aria-expanded]=\"expanded()\"\n\t\t\t\t\t\t(click)=\"expand()\"\n\t\t\t\t\t>\n\t\t\t\t\t\t&hellip;\n\t\t\t\t\t</button>\n\t\t\t\t</li>\n\t\t\t}\n\t\t}\n\t</ol>\n</nav>\n", styles: [":root,:host{--hub-breadcrumb-padding-x: var(--hub-ref-space-3, 1rem);--hub-breadcrumb-padding-y: .25rem;--hub-breadcrumb-margin-bottom: var(--hub-ref-space-0, 0);--hub-breadcrumb-bg: var(--hub-sys-surface-page, transparent);--hub-breadcrumb-color: var(--hub-sys-text-primary, #212529);--hub-breadcrumb-border-radius: var(--hub-ref-radius-md, .375rem);--hub-breadcrumb-divider-color: var(--hub-sys-text-muted, #6c757d);--hub-breadcrumb-item-padding-x: var(--hub-ref-space-1, .25rem);--hub-breadcrumb-item-active-color: var(--hub-sys-text-muted, #6c757d);--hub-breadcrumb-accent-emphasis: color-mix(in oklch, var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd)) 80%, var(--hub-sys-color-ink, #212529));--hub-breadcrumb-accent-subtle: color-mix(in oklch, var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd)) 12%, var(--hub-sys-surface-page, #fff));--hub-breadcrumb-accent-on: oklch(from var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd)) clamp(0, (.62 - l) * 1000, 1) 0 h);--hub-breadcrumb-link-color: var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd));--hub-breadcrumb-link-hover-color: var(--hub-breadcrumb-accent-emphasis, var(--hub-sys-link-hover-color, #0a58ca));--hub-breadcrumb-link-decoration: none;--hub-breadcrumb-link-hover-decoration: underline;--hub-breadcrumb-link-focus-color: var(--hub-breadcrumb-accent-emphasis);--hub-breadcrumb-focus-bg: transparent;--hub-breadcrumb-focus-ring-width: var(--hub-sys-focus-ring-width, .25rem);--hub-breadcrumb-focus-ring-color: var(--hub-sys-focus-ring-color, rgba(13, 110, 253, .25));--hub-breadcrumb-focus-ring-radius: var(--hub-ref-radius-sm, .25rem);--hub-breadcrumb-collapsed-color: var(--hub-sys-text-muted, #6c757d);--hub-breadcrumb-collapsed-hover-color: var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd));--hub-breadcrumb-collapsed-bg: transparent;--hub-breadcrumb-collapsed-hover-bg: var(--hub-breadcrumb-accent-subtle);--hub-breadcrumb-divider: \">\";--hub-breadcrumb-divider-flipped: \"<\";--hub-breadcrumb-font-size: inherit;--hub-breadcrumb-max-item-width: 12rem}.hub-breadcrumb__nav .hub-breadcrumb__list{display:flex;flex-wrap:wrap;font-size:var(--hub-breadcrumb-font-size, inherit);padding:var(--hub-breadcrumb-padding-y, .25rem) var(--hub-breadcrumb-padding-x, var(--hub-ref-space-3, 1rem));margin-bottom:var(--hub-breadcrumb-margin-bottom, var(--hub-ref-space-0, 0));list-style:none;color:var(--hub-breadcrumb-color, var(--hub-sys-text-primary, #212529));background-color:var(--hub-breadcrumb-bg, var(--hub-sys-surface-page, transparent));border-radius:var(--hub-breadcrumb-border-radius, var(--hub-ref-radius-md, .375rem))}.hub-breadcrumb__nav .hub-breadcrumb__item+.hub-breadcrumb__item{padding-inline-start:var(--hub-breadcrumb-item-padding-x, var(--hub-ref-space-1, .25rem))}.hub-breadcrumb__nav .hub-breadcrumb__item+.hub-breadcrumb__item:before{padding-inline-end:var(--hub-breadcrumb-item-padding-x, var(--hub-ref-space-1, .25rem));color:var(--hub-breadcrumb-divider-color, var(--hub-sys-text-muted, #6c757d));content:var(--hub-breadcrumb-divider, \">\")}.hub-breadcrumb__nav .hub-breadcrumb__item--active{color:var(--hub-breadcrumb-item-active-color, var(--hub-sys-text-muted, #6c757d))}.hub-breadcrumb__nav .hub-breadcrumb__link{color:var(--hub-breadcrumb-link-color, var(--hub-sys-link-color, #0d6efd));text-decoration:var(--hub-breadcrumb-link-decoration, none)}.hub-breadcrumb__nav .hub-breadcrumb__link:hover{color:var(--hub-breadcrumb-link-hover-color, var(--hub-sys-link-hover-color, #0a58ca));text-decoration:var(--hub-breadcrumb-link-hover-decoration, underline)}.hub-breadcrumb__nav .hub-breadcrumb__collapsed{display:inline-flex;align-items:center;padding:0 .125rem;border:0;border-radius:var(--hub-breadcrumb-focus-ring-radius, var(--hub-ref-radius-sm, .25rem));background-color:var(--hub-breadcrumb-collapsed-bg, transparent);color:var(--hub-breadcrumb-collapsed-color, var(--hub-sys-text-muted, #6c757d));font:inherit;line-height:inherit;cursor:pointer}.hub-breadcrumb__nav .hub-breadcrumb__collapsed:hover{background-color:var(--hub-breadcrumb-collapsed-hover-bg);color:var(--hub-breadcrumb-collapsed-hover-color)}.hub-breadcrumb__nav .hub-breadcrumb__link:focus-visible,.hub-breadcrumb__nav .hub-breadcrumb__collapsed:focus-visible{outline:0;border-radius:var(--hub-breadcrumb-focus-ring-radius, var(--hub-ref-radius-sm, .25rem));background-color:var(--hub-breadcrumb-focus-bg, transparent);color:var(--hub-breadcrumb-link-focus-color);box-shadow:0 0 0 var(--hub-breadcrumb-focus-ring-width, var(--hub-sys-focus-ring-width, .25rem)) var(--hub-breadcrumb-focus-ring-color, var(--hub-sys-focus-ring-color, rgba(13, 110, 253, .25)))}[dir=rtl] .hub-breadcrumb__nav .hub-breadcrumb__item+.hub-breadcrumb__item:before{content:var(--hub-breadcrumb-divider-flipped, var(--hub-breadcrumb-divider, \">\"))}:host(.hub-breadcrumb--truncate) .hub-breadcrumb__nav .hub-breadcrumb__link,:host(.hub-breadcrumb--truncate) .hub-breadcrumb__nav .hub-breadcrumb__text,.hub-breadcrumb--truncate .hub-breadcrumb__nav .hub-breadcrumb__link,.hub-breadcrumb--truncate .hub-breadcrumb__nav .hub-breadcrumb__text{display:inline-block;max-inline-size:var(--hub-breadcrumb-max-item-width, 12rem);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}:host([data-variant=primary]),.hub-breadcrumb[data-variant=primary]{--hub-breadcrumb-accent: var(--hub-sys-color-primary)}:host([data-variant=secondary]),.hub-breadcrumb[data-variant=secondary]{--hub-breadcrumb-accent: var(--hub-sys-color-secondary)}:host([data-variant=success]),.hub-breadcrumb[data-variant=success]{--hub-breadcrumb-accent: var(--hub-sys-color-success)}:host([data-variant=danger]),.hub-breadcrumb[data-variant=danger]{--hub-breadcrumb-accent: var(--hub-sys-color-danger)}:host([data-variant=warning]),.hub-breadcrumb[data-variant=warning]{--hub-breadcrumb-accent: var(--hub-sys-color-warning)}:host([data-variant=info]),.hub-breadcrumb[data-variant=info]{--hub-breadcrumb-accent: var(--hub-sys-color-info)}:host([data-variant=neutral]),.hub-breadcrumb[data-variant=neutral]{--hub-breadcrumb-accent: var(--hub-sys-color-neutral)}:host([data-variant=light]),.hub-breadcrumb[data-variant=light]{--hub-breadcrumb-accent: var(--hub-sys-color-light)}:host([data-variant=dark]),.hub-breadcrumb[data-variant=dark]{--hub-breadcrumb-accent: var(--hub-sys-color-dark)}:host([data-variant]),.hub-breadcrumb[data-variant]{--hub-breadcrumb-accent-emphasis: color-mix(in oklch, var(--hub-breadcrumb-accent) 80%, var(--hub-sys-color-ink, #212529));--hub-breadcrumb-accent-subtle: color-mix(in oklch, var(--hub-breadcrumb-accent) 12%, var(--hub-sys-surface-page, #fff));--hub-breadcrumb-accent-on: oklch(from var(--hub-breadcrumb-accent) clamp(0, (.62 - l) * 1000, 1) 0 h);--hub-breadcrumb-link-hover-color: var(--hub-breadcrumb-accent-emphasis)}\n"] }]
387
+ }, template: "<nav aria-label=\"breadcrumb\" class=\"hub-breadcrumb__nav\">\n\t<ol class=\"hub-breadcrumb__list\">\n\t\t@for (row of rows(); track $index) {\n\t\t\t@if (row.item; as item) {\n\t\t\t\t<li\n\t\t\t\t\tclass=\"hub-breadcrumb__item\"\n\t\t\t\t\t[class.hub-breadcrumb__item--active]=\"row.isLast\"\n\t\t\t\t\t[attr.aria-current]=\"row.isLast ? 'page' : null\"\n\t\t\t\t>\n\t\t\t\t\t@if (itemTemplate(); as template) {\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\tThe clipping box for a custom crumb. Scoped styles never reach the elements\n\t\t\t\t\t\t\ta `hubBreadcrumbItem` template renders \u2014 they belong to the consuming\n\t\t\t\t\t\t\tcomponent \u2014 so `truncateItems` can only clip something this component draws\n\t\t\t\t\t\t\titself. It sits exactly where a built-in label sits, inside the item and\n\t\t\t\t\t\t\toutside the separator, so a projected crumb gets the same width as any other.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<span class=\"hub-breadcrumb__custom\" hubBreadcrumbLabel>\n\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"template\"\n\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{\n\t\t\t\t\t\t\t\t\t$implicit: item,\n\t\t\t\t\t\t\t\t\tisLast: row.isLast\n\t\t\t\t\t\t\t\t}\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t} @else if (row.isLast) {\n\t\t\t\t\t\t<span class=\"hub-breadcrumb__text\" hubBreadcrumbLabel>{{ item.label }}</span>\n\t\t\t\t\t} @else if (item.href) {\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\tclass=\"hub-breadcrumb__link\"\n\t\t\t\t\t\t\thubBreadcrumbLabel\n\t\t\t\t\t\t\t[href]=\"item.href\"\n\t\t\t\t\t\t\t[attr.target]=\"item.target ?? null\"\n\t\t\t\t\t\t\t[attr.rel]=\"row.rel\"\n\t\t\t\t\t\t\t[attr.download]=\"item.download ?? null\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<a [routerLink]=\"item.url\" class=\"hub-breadcrumb__link\" hubBreadcrumbLabel>\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t}\n\t\t\t\t</li>\n\t\t\t} @else {\n\t\t\t\t<li class=\"hub-breadcrumb__item hub-breadcrumb__item--collapsed\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-breadcrumb__collapsed\"\n\t\t\t\t\t\t[attr.aria-label]=\"collapsedAriaLabel()\"\n\t\t\t\t\t\t[attr.aria-expanded]=\"expanded()\"\n\t\t\t\t\t\t(click)=\"expand()\"\n\t\t\t\t\t>\n\t\t\t\t\t\t&hellip;\n\t\t\t\t\t</button>\n\t\t\t\t</li>\n\t\t\t}\n\t\t}\n\t</ol>\n</nav>\n", styles: [":root,:host{--hub-breadcrumb-padding-x: var(--hub-ref-space-3, 1rem);--hub-breadcrumb-padding-y: .25rem;--hub-breadcrumb-margin-bottom: var(--hub-ref-space-0, 0);--hub-breadcrumb-bg: var(--hub-sys-surface-page, transparent);--hub-breadcrumb-color: var(--hub-sys-text-primary, #212529);--hub-breadcrumb-border-radius: var(--hub-ref-radius-md, .375rem);--hub-breadcrumb-divider-color: var(--hub-sys-text-muted, #6c757d);--hub-breadcrumb-item-padding-x: var(--hub-ref-space-1, .25rem);--hub-breadcrumb-item-active-color: var(--hub-sys-text-muted, #6c757d);--hub-breadcrumb-accent-emphasis: color-mix(in oklch, var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd)) 80%, var(--hub-sys-color-ink, #212529));--hub-breadcrumb-accent-subtle: color-mix(in oklch, var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd)) 12%, var(--hub-sys-surface-page, #fff));--hub-breadcrumb-accent-on: oklch(from var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd)) clamp(0, (.62 - l) * 1000, 1) 0 h);--hub-breadcrumb-link-color: var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd));--hub-breadcrumb-link-hover-color: var(--hub-breadcrumb-accent-emphasis, var(--hub-sys-link-hover-color, #0a58ca));--hub-breadcrumb-link-decoration: none;--hub-breadcrumb-link-hover-decoration: underline;--hub-breadcrumb-link-focus-color: var(--hub-breadcrumb-accent-emphasis);--hub-breadcrumb-focus-bg: transparent;--hub-breadcrumb-focus-ring-width: var(--hub-sys-focus-ring-width, .25rem);--hub-breadcrumb-focus-ring-color: var(--hub-sys-focus-ring-color, rgba(13, 110, 253, .25));--hub-breadcrumb-focus-ring-radius: var(--hub-ref-radius-sm, .25rem);--hub-breadcrumb-collapsed-color: var(--hub-sys-text-muted, #6c757d);--hub-breadcrumb-collapsed-hover-color: var(--hub-breadcrumb-accent, var(--hub-sys-color-primary, #0d6efd));--hub-breadcrumb-collapsed-bg: transparent;--hub-breadcrumb-collapsed-hover-bg: var(--hub-breadcrumb-accent-subtle);--hub-breadcrumb-divider: \">\";--hub-breadcrumb-divider-flipped: \"<\";--hub-breadcrumb-font-size: inherit;--hub-breadcrumb-max-item-width: 12rem}.hub-breadcrumb__nav .hub-breadcrumb__list{display:flex;flex-wrap:wrap;font-size:var(--hub-breadcrumb-font-size, inherit);padding:var(--hub-breadcrumb-padding-y, .25rem) var(--hub-breadcrumb-padding-x, var(--hub-ref-space-3, 1rem));margin-bottom:var(--hub-breadcrumb-margin-bottom, var(--hub-ref-space-0, 0));list-style:none;color:var(--hub-breadcrumb-color, var(--hub-sys-text-primary, #212529));background-color:var(--hub-breadcrumb-bg, var(--hub-sys-surface-page, transparent));border-radius:var(--hub-breadcrumb-border-radius, var(--hub-ref-radius-md, .375rem))}.hub-breadcrumb__nav .hub-breadcrumb__item+.hub-breadcrumb__item{padding-inline-start:var(--hub-breadcrumb-item-padding-x, var(--hub-ref-space-1, .25rem))}.hub-breadcrumb__nav .hub-breadcrumb__item+.hub-breadcrumb__item:before{padding-inline-end:var(--hub-breadcrumb-item-padding-x, var(--hub-ref-space-1, .25rem));color:var(--hub-breadcrumb-divider-color, var(--hub-sys-text-muted, #6c757d));content:var(--hub-breadcrumb-divider, \">\")}.hub-breadcrumb__nav .hub-breadcrumb__item--active{color:var(--hub-breadcrumb-item-active-color, var(--hub-sys-text-muted, #6c757d))}.hub-breadcrumb__nav .hub-breadcrumb__link{color:var(--hub-breadcrumb-link-color, var(--hub-sys-link-color, #0d6efd));text-decoration:var(--hub-breadcrumb-link-decoration, none)}.hub-breadcrumb__nav .hub-breadcrumb__link:hover{color:var(--hub-breadcrumb-link-hover-color, var(--hub-sys-link-hover-color, #0a58ca));text-decoration:var(--hub-breadcrumb-link-hover-decoration, underline)}.hub-breadcrumb__nav .hub-breadcrumb__collapsed{display:inline-flex;align-items:center;padding:0 .125rem;border:0;border-radius:var(--hub-breadcrumb-focus-ring-radius, var(--hub-ref-radius-sm, .25rem));background-color:var(--hub-breadcrumb-collapsed-bg, transparent);color:var(--hub-breadcrumb-collapsed-color, var(--hub-sys-text-muted, #6c757d));font:inherit;line-height:inherit;cursor:pointer}.hub-breadcrumb__nav .hub-breadcrumb__collapsed:hover{background-color:var(--hub-breadcrumb-collapsed-hover-bg);color:var(--hub-breadcrumb-collapsed-hover-color)}.hub-breadcrumb__nav .hub-breadcrumb__link:focus-visible,.hub-breadcrumb__nav .hub-breadcrumb__collapsed:focus-visible{outline:0;border-radius:var(--hub-breadcrumb-focus-ring-radius, var(--hub-ref-radius-sm, .25rem));background-color:var(--hub-breadcrumb-focus-bg, transparent);color:var(--hub-breadcrumb-link-focus-color);box-shadow:0 0 0 var(--hub-breadcrumb-focus-ring-width, var(--hub-sys-focus-ring-width, .25rem)) var(--hub-breadcrumb-focus-ring-color, var(--hub-sys-focus-ring-color, rgba(13, 110, 253, .25)))}[dir=rtl] .hub-breadcrumb__nav .hub-breadcrumb__item+.hub-breadcrumb__item:before{content:var(--hub-breadcrumb-divider-flipped, var(--hub-breadcrumb-divider, \">\"))}:host(.hub-breadcrumb--truncate) .hub-breadcrumb__nav .hub-breadcrumb__link,:host(.hub-breadcrumb--truncate) .hub-breadcrumb__nav .hub-breadcrumb__text,:host(.hub-breadcrumb--truncate) .hub-breadcrumb__nav .hub-breadcrumb__custom,.hub-breadcrumb--truncate .hub-breadcrumb__nav .hub-breadcrumb__link,.hub-breadcrumb--truncate .hub-breadcrumb__nav .hub-breadcrumb__text,.hub-breadcrumb--truncate .hub-breadcrumb__nav .hub-breadcrumb__custom{display:inline-block;max-inline-size:var(--hub-breadcrumb-max-item-width, 12rem);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}:host([data-variant=primary]),.hub-breadcrumb[data-variant=primary]{--hub-breadcrumb-accent: var(--hub-sys-color-primary)}:host([data-variant=secondary]),.hub-breadcrumb[data-variant=secondary]{--hub-breadcrumb-accent: var(--hub-sys-color-secondary)}:host([data-variant=success]),.hub-breadcrumb[data-variant=success]{--hub-breadcrumb-accent: var(--hub-sys-color-success)}:host([data-variant=danger]),.hub-breadcrumb[data-variant=danger]{--hub-breadcrumb-accent: var(--hub-sys-color-danger)}:host([data-variant=warning]),.hub-breadcrumb[data-variant=warning]{--hub-breadcrumb-accent: var(--hub-sys-color-warning)}:host([data-variant=info]),.hub-breadcrumb[data-variant=info]{--hub-breadcrumb-accent: var(--hub-sys-color-info)}:host([data-variant=neutral]),.hub-breadcrumb[data-variant=neutral]{--hub-breadcrumb-accent: var(--hub-sys-color-neutral)}:host([data-variant=light]),.hub-breadcrumb[data-variant=light]{--hub-breadcrumb-accent: var(--hub-sys-color-light)}:host([data-variant=dark]),.hub-breadcrumb[data-variant=dark]{--hub-breadcrumb-accent: var(--hub-sys-color-dark)}:host([data-variant]),.hub-breadcrumb[data-variant]{--hub-breadcrumb-accent-emphasis: color-mix(in oklch, var(--hub-breadcrumb-accent) 80%, var(--hub-sys-color-ink, #212529));--hub-breadcrumb-accent-subtle: color-mix(in oklch, var(--hub-breadcrumb-accent) 12%, var(--hub-sys-surface-page, #fff));--hub-breadcrumb-accent-on: oklch(from var(--hub-breadcrumb-accent) clamp(0, (.62 - l) * 1000, 1) 0 h);--hub-breadcrumb-link-hover-color: var(--hub-breadcrumb-accent-emphasis)}\n"] }]
380
388
  }], propDecorators: { itemTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubBreadcrumbItemDirective), { ...{ read: TemplateRef }, isSignal: true }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], truncateItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "truncateItems", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], maxItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxItems", required: false }] }], itemsBeforeCollapse: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemsBeforeCollapse", required: false }] }], itemsAfterCollapse: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemsAfterCollapse", required: false }] }], collapsedAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsedAriaLabel", required: false }] }], collapsedClick: [{ type: i0.Output, args: ["collapsedClick"] }] } });
381
389
 
382
390
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ng-hub-ui-breadcrumbs.mjs","sources":["../../../projects/breadcrumbs/src/lib/directives/breadcrumb-item.directive.ts","../../../projects/breadcrumbs/src/lib/breadcrumb-tooltip/breadcrumb-tooltip.token.ts","../../../projects/breadcrumbs/src/lib/directives/breadcrumb-label.directive.ts","../../../projects/breadcrumbs/src/lib/services/breadcrumbs.service.ts","../../../projects/breadcrumbs/src/lib/components/breadcrumb/breadcrumb.component.ts","../../../projects/breadcrumbs/src/lib/components/breadcrumb/breadcrumb.component.html","../../../projects/breadcrumbs/src/lib/breadcrumbs.module.ts","../../../projects/breadcrumbs/src/lib/breadcrumb-tooltip/breadcrumb-tooltip.provider.ts","../../../projects/breadcrumbs/src/public-api.ts","../../../projects/breadcrumbs/src/ng-hub-ui-breadcrumbs.ts"],"sourcesContent":["import { Directive, inject, TemplateRef } from '@angular/core';\nimport { BreadcrumbTemplateContext } from '../models/breadcrumb-template-context';\n\n@Directive({\n\tselector: '[hubBreadcrumbItem]'\n})\nexport class HubBreadcrumbItemDirective {\n\ttemplate = inject(TemplateRef<BreadcrumbTemplateContext>);\n}\n","import { InjectionToken } from '@angular/core';\nimport { HubBreadcrumbTooltipAdapter } from './breadcrumb-tooltip.types';\n\n/**\n * Injection token resolving the optional tooltip adapter used by truncated\n * breadcrumb labels.\n *\n * Inject it with `{ optional: true }`; a `null` value means \"use the native\n * `title` fallback\". Register it through {@link provideHubBreadcrumbTooltip}.\n */\nexport const HUB_BREADCRUMB_TOOLTIP_ADAPTER = new InjectionToken<HubBreadcrumbTooltipAdapter>('HUB_BREADCRUMB_TOOLTIP_ADAPTER');\n","import { afterNextRender, Directive, effect, ElementRef, inject, input, OnDestroy, signal } from '@angular/core';\nimport { HUB_BREADCRUMB_TOOLTIP_ADAPTER } from '../breadcrumb-tooltip/breadcrumb-tooltip.token';\nimport { HubBreadcrumbTooltipHandle } from '../breadcrumb-tooltip/breadcrumb-tooltip.types';\n\n/**\n * Adds an overflow-aware tooltip to a breadcrumb label element.\n *\n * Apply `[hubBreadcrumbLabel]` to the link/text of each breadcrumb item. When the\n * label is truncated (its rendered text is wider than its box — typically because\n * `hub-breadcrumb` truncation is enabled), the directive exposes the full text as\n * a tooltip: the native `title` attribute by default, or the richer hub-ui\n * tooltip when a {@link HUB_BREADCRUMB_TOOLTIP_ADAPTER} is provided. When the\n * label fits, no tooltip is shown.\n */\n@Directive({\n\tselector: '[hubBreadcrumbLabel]'\n})\nexport class HubBreadcrumbLabelDirective implements OnDestroy {\n\t/**\n\t * Explicit tooltip text. When empty, the host's own text content is used, but\n\t * only while it is truncated.\n\t */\n\treadonly tooltip = input('', { alias: 'hubBreadcrumbLabel' });\n\n\tprivate readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n\n\t/** Optional hub-ui tooltip adapter; absent means native `title` fallback. */\n\tprivate readonly adapter = inject(HUB_BREADCRUMB_TOOLTIP_ADAPTER, { optional: true });\n\n\t/** Whether the rendered label is wider than its clipping box. */\n\tprivate readonly isOverflowing = signal(false);\n\n\t/** Trimmed text content of the label, used as the auto tooltip source. */\n\tprivate readonly text = signal('');\n\n\t/** Becomes true once the browser-only overflow tracking is wired. */\n\tprivate readonly ready = signal(false);\n\n\tprivate resizeObserver: ResizeObserver | null = null;\n\tprivate mutationObserver: MutationObserver | null = null;\n\tprivate handle: HubBreadcrumbTooltipHandle | null = null;\n\n\tconstructor() {\n\t\tafterNextRender(() => this.initOverflowTracking());\n\n\t\teffect(() => {\n\t\t\tif (!this.ready()) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst explicit = this.tooltip().trim();\n\t\t\tconst text = explicit || (this.isOverflowing() ? this.text() : '');\n\t\t\tthis.applyTooltip(text);\n\t\t});\n\t}\n\n\tngOnDestroy(): void {\n\t\tthis.resizeObserver?.disconnect();\n\t\tthis.mutationObserver?.disconnect();\n\t\tthis.handle?.destroy();\n\t\tthis.handle = null;\n\t}\n\n\t/** Wires browser-only observers that keep the truncation state in sync. */\n\tprivate initOverflowTracking(): void {\n\t\tconst el = this.host.nativeElement;\n\t\tthis.measure(el);\n\n\t\tif (typeof ResizeObserver !== 'undefined') {\n\t\t\tthis.resizeObserver = new ResizeObserver(() => this.measure(el));\n\t\t\tthis.resizeObserver.observe(el);\n\t\t}\n\n\t\tif (typeof MutationObserver !== 'undefined') {\n\t\t\tthis.mutationObserver = new MutationObserver(() => this.measure(el));\n\t\t\tthis.mutationObserver.observe(el, { childList: true, characterData: true, subtree: true });\n\t\t}\n\n\t\tthis.ready.set(true);\n\t}\n\n\t/** Reads the host's text and truncation state into the signals. */\n\tprivate measure(el: HTMLElement): void {\n\t\tthis.text.set((el.textContent ?? '').trim());\n\t\tthis.isOverflowing.set(el.scrollWidth > el.clientWidth + 1);\n\t}\n\n\t/**\n\t * Applies the effective tooltip text through the hub-ui adapter when present,\n\t * or the native `title` attribute otherwise. An empty text removes both.\n\t */\n\tprivate applyTooltip(text: string): void {\n\t\tconst el = this.host.nativeElement;\n\n\t\tif (this.adapter) {\n\t\t\tel.removeAttribute('title');\n\t\t\tif (text) {\n\t\t\t\tif (this.handle) {\n\t\t\t\t\tthis.handle.update(text);\n\t\t\t\t} else {\n\t\t\t\t\tthis.handle = this.adapter.attach(el, text);\n\t\t\t\t}\n\t\t\t} else if (this.handle) {\n\t\t\t\tthis.handle.destroy();\n\t\t\t\tthis.handle = null;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (text) {\n\t\t\tel.setAttribute('title', text);\n\t\t} else {\n\t\t\tel.removeAttribute('title');\n\t\t}\n\t}\n}\n","import { inject, Injectable, Signal } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { ActivatedRoute, NavigationEnd, Router } from '@angular/router';\nimport { filter, map, startWith } from 'rxjs';\nimport { BreadcrumbItem, BreadcrumbRouteConfig, BreadcrumbRouteData } from '../models/breadcrumb-item';\n\n@Injectable({\n\tprovidedIn: 'root'\n})\nexport class HubBreadcrumbsService {\n\t#router = inject(Router);\n\t#activatedRoute = inject(ActivatedRoute);\n\n\t/** The trail as a stream, for consumers already composing with rxjs. */\n\tbreadcrumbs$ = this.#router.events.pipe(\n\t\tfilter((event) => event instanceof NavigationEnd),\n\t\tstartWith(undefined),\n\t\tmap(() => this.createBreadcrumbs(this.#activatedRoute.root))\n\t);\n\n\t/**\n\t * The trail as a signal, and the surface the component reads. Published here\n\t * rather than left to each consumer, because a stream that only ever carries\n\t * the current trail is one every caller was wrapping in the same `toSignal`\n\t * — the component included. Wrapped once, subscribed once.\n\t */\n\treadonly breadcrumbs: Signal<BreadcrumbItem[]> = toSignal(this.breadcrumbs$, { initialValue: [] as BreadcrumbItem[] });\n\n\tprivate createBreadcrumbs(route: ActivatedRoute, url: string = '', breadcrumbs: BreadcrumbItem[] = []): BreadcrumbItem[] {\n\t\tconst children: ActivatedRoute[] = route.children;\n\n\t\tif (children.length === 0) {\n\t\t\treturn breadcrumbs;\n\t\t}\n\n\t\tfor (const child of children) {\n\t\t\t// A route is recognised before it is activated, and carries `_futureSnapshot`\n\t\t\t// in between while `snapshot` is still unset. `breadcrumbs$` opens with\n\t\t\t// `startWith(undefined)`, so a shell that draws its breadcrumb on the first\n\t\t\t// paint walks the tree inside that window — and reading `.url` there threw,\n\t\t\t// out of a subscription that draws the whole page header, taking the header\n\t\t\t// with it. There is nothing to name yet either: a route with no snapshot has\n\t\t\t// no segments and no resolved data, so it is skipped rather than guessed at.\n\t\t\tif (!child.snapshot) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst routeSegments = child.snapshot.url;\n\n\t\t\t// URL of this level\n\t\t\tconst routeURL: string = routeSegments.map((segment) => segment.path).join('/');\n\n\t\t\tconst nextUrl = routeURL ? `${url}/${routeURL}` : url;\n\n\t\t\t// Only the routes declaring their own breadcrumb become a crumb\n\t\t\tconst hasBreadcrumbData = this.hasOwnBreadcrumbData(child);\n\n\t\t\tif (hasBreadcrumbData) {\n\t\t\t\tbreadcrumbs.push(this.createItem(child, nextUrl));\n\t\t\t}\n\n\t\t\treturn this.createBreadcrumbs(child, nextUrl, breadcrumbs);\n\t\t}\n\n\t\treturn breadcrumbs;\n\t}\n\n\tprivate hasOwnBreadcrumbData(route: ActivatedRoute): boolean {\n\t\tconst routeConfig = route.routeConfig;\n\t\treturn !!(routeConfig && routeConfig.data && routeConfig.data['breadcrumb']);\n\t}\n\n\t/**\n\t * Builds the crumb for a route. The object form of `data.breadcrumb` carries\n\t * anchor metadata for destinations outside the router; whatever accompanies\n\t * `label` there travels to the item untouched, so a new anchor attribute needs\n\t * no change here.\n\t */\n\tprivate createItem(route: ActivatedRoute, url: string): BreadcrumbItem {\n\t\tconst data = route.snapshot.data;\n\t\tconst config: BreadcrumbRouteData = data['breadcrumb'];\n\n\t\tif (this.isRouteConfig(config)) {\n\t\t\tconst { label: labelSource, ...anchor } = config;\n\t\t\treturn { label: this.resolveLabel(labelSource, data), url, data, ...anchor };\n\t\t}\n\n\t\treturn { label: this.resolveLabel(config, data), url, data };\n\t}\n\n\t/** Narrows `data.breadcrumb` to its object form, excluding the function form. */\n\tprivate isRouteConfig(config: BreadcrumbRouteData): config is BreadcrumbRouteConfig {\n\t\treturn typeof config === 'object' && config !== null;\n\t}\n\n\tprivate resolveLabel(source: string | ((data: any) => string), data: any): string {\n\t\tconst label = typeof source === 'function' ? source(data) : source;\n\n\t\treturn data['resolvedData'] ? this.getResolvedBreadcrumb(label, data['resolvedData']) : label;\n\t}\n\n\tprivate getResolvedBreadcrumb(template: string, data: any): string {\n\t\treturn template.replace(/\\{([^}]+)\\}/g, (match, key) => {\n\t\t\treturn data[key] || match;\n\t\t});\n\t}\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n\tafterNextRender,\n\tChangeDetectionStrategy,\n\tComponent,\n\tcomputed,\n\tcontentChild,\n\tElementRef,\n\tinject,\n\tInjector,\n\tinput,\n\tlinkedSignal,\n\toutput,\n\tTemplateRef\n} from '@angular/core';\nimport { RouterLink } from '@angular/router';\nimport { HubBreadcrumbItemDirective } from '../../directives/breadcrumb-item.directive';\nimport { HubBreadcrumbLabelDirective } from '../../directives/breadcrumb-label.directive';\nimport { BreadcrumbItem } from '../../models/breadcrumb-item';\nimport { HubBreadcrumbsService } from '../../services/breadcrumbs.service';\n\n/**\n * Variants with exact design-system token coverage via the SCSS `@each` loop.\n * Kept in step with that loop by hand, because Sass cannot read this file: a name\n * dropped from here is not broken, only paid for twice — once inline and once by\n * the stylesheet.\n */\nconst BUILT_IN_VARIANTS = new Set<string>([\n\t'primary',\n\t'secondary',\n\t'success',\n\t'danger',\n\t'warning',\n\t'info',\n\t'neutral',\n\t'light',\n\t'dark'\n]);\n\n/**\n * One rendered position of the trail. A `null` item is the collapsed indicator,\n * which occupies a position of its own so the separators fall around it exactly\n * as they do around a crumb.\n */\ninterface BreadcrumbRow {\n\titem: BreadcrumbItem | null;\n\tisLast: boolean;\n\t/** Resolved anchor `rel`, already defended for `_blank` targets. */\n\trel: string | null;\n}\n\n@Component({\n\tselector: 'hub-breadcrumb',\n\timports: [RouterLink, NgTemplateOutlet, HubBreadcrumbLabelDirective],\n\ttemplateUrl: './breadcrumb.component.html',\n\tstyleUrl: './breadcrumb.component.scss',\n\tchangeDetection: ChangeDetectionStrategy.OnPush,\n\thost: {\n\t\tclass: 'hub-breadcrumb',\n\t\t'[class.hub-breadcrumb--truncate]': 'truncateItems()',\n\t\t'[attr.data-variant]': 'variant() ?? null',\n\t\t'[style.--hub-breadcrumb-accent]': 'customAccent()'\n\t}\n})\nexport class HubBreadcrumbComponent {\n\t#breadcrumbsSvc = inject(HubBreadcrumbsService);\n\t#host = inject<ElementRef<HTMLElement>>(ElementRef);\n\t#injector = inject(Injector);\n\n\treadonly itemTemplate = contentChild(HubBreadcrumbItemDirective, { read: TemplateRef });\n\n\t/**\n\t * Semantic accent for the breadcrumb links: `'primary'` · `'secondary'` ·\n\t * `'success'` · `'danger'` · `'warning'` · `'info'` · `'neutral'` · `'light'` ·\n\t * `'dark'`, or any custom string (read as `--hub-sys-color-<variant>`).\n\t * Re-bases `--hub-breadcrumb-accent`; the current (last) item stays muted.\n\t * Defaults to the standard link colour.\n\t */\n\treadonly variant = input<string>();\n\n\t/**\n\t * Opt-in per-item truncation. When `true`, each label is clipped to\n\t * `--hub-breadcrumb-max-item-width` with an ellipsis and, if it overflows,\n\t * exposes its full text as a tooltip (native `title`, or the hub-ui tooltip\n\t * when {@link provideHubBreadcrumbTooltip} is wired). Off by default, so the\n\t * standard breadcrumb layout is unchanged.\n\t */\n\treadonly truncateItems = input(false);\n\n\t/**\n\t * Trail supplied by the consumer, replacing the one derived from the router.\n\t * It is the way in for crumbs the route tree cannot express — an ancestor\n\t * served by another application, or a trail assembled by hand. Left `null`,\n\t * the component keeps reading {@link HubBreadcrumbsService}.\n\t */\n\treadonly items = input<BreadcrumbItem[] | null>(null);\n\n\t/**\n\t * Length above which the trail collapses behind an indicator. Undefined (the\n\t * default) never collapses, however long the trail grows.\n\t */\n\treadonly maxItems = input<number | undefined>(undefined);\n\n\t/** Crumbs kept at the head of a collapsed trail. */\n\treadonly itemsBeforeCollapse = input(1);\n\n\t/** Crumbs kept at the tail of a collapsed trail, the current page included. */\n\treadonly itemsAfterCollapse = input(1);\n\n\t/**\n\t * Accessible name of the collapsed indicator. It is an input rather than a\n\t * literal because it is the one string of this component a screen reader\n\t * announces, and the library carries no translations of its own.\n\t */\n\treadonly collapsedAriaLabel = input('Show the hidden breadcrumb items');\n\n\t/**\n\t * Fires when the collapsed indicator is activated. The trail expands in place\n\t * on its own; the event is there for consumers who want to react as well —\n\t * open a menu of the hidden crumbs, log the interaction.\n\t */\n\treadonly collapsedClick = output<void>();\n\n\t/** Effective trail: the manual one when supplied, the router's otherwise. */\n\tprotected readonly trail = computed(() => this.items() ?? this.#breadcrumbsSvc.breadcrumbs());\n\n\t/**\n\t * Whether the reader has opened a collapsed trail. Derived from the trail so a\n\t * new navigation collapses it again — an expansion answers one trail, not the\n\t * component's whole lifetime.\n\t */\n\tprotected readonly expanded = linkedSignal<BreadcrumbItem[], boolean>({\n\t\tsource: this.trail,\n\t\tcomputation: () => false\n\t});\n\n\t/** Rendered positions, with the collapsed range folded into one indicator. */\n\tprotected readonly rows = computed<BreadcrumbRow[]>(() => {\n\t\tconst items = this.trail();\n\t\tconst before = Math.max(0, this.itemsBeforeCollapse());\n\t\tconst after = Math.max(0, this.itemsAfterCollapse());\n\t\tconst max = this.maxItems();\n\n\t\tconst rowAt = (item: BreadcrumbItem, index: number): BreadcrumbRow => ({\n\t\t\titem,\n\t\t\tisLast: index === items.length - 1,\n\t\t\trel: this.resolveRel(item)\n\t\t});\n\n\t\tconst collapses = max !== undefined && max > 0 && items.length > max && before + after < items.length;\n\n\t\tif (!collapses || this.expanded()) {\n\t\t\treturn items.map(rowAt);\n\t\t}\n\n\t\tconst tailStart = items.length - after;\n\n\t\treturn [\n\t\t\t...items.slice(0, before).map(rowAt),\n\t\t\t{ item: null, isLast: false, rel: null },\n\t\t\t...items.slice(tailStart).map((item, index) => rowAt(item, tailStart + index))\n\t\t];\n\t});\n\n\t/**\n\t * Inline accent for custom (non-built-in) variants — the nine built-in accents\n\t * are resolved by the SCSS `@each` loop, so this returns `null` for them.\n\t */\n\tprotected readonly customAccent = computed(() => {\n\t\tconst v = this.variant();\n\t\treturn v && !BUILT_IN_VARIANTS.has(v) ? `var(--hub-sys-color-${v})` : null;\n\t});\n\n\t/** Opens a collapsed trail and lets the consumer act on the same gesture. */\n\tprotected expand(): void {\n\t\tthis.expanded.set(true);\n\t\tthis.collapsedClick.emit();\n\t\tafterNextRender(() => this.#focusFirstRevealedCrumb(), { injector: this.#injector });\n\t}\n\n\t/**\n\t * Expanding removes the indicator — the element that was holding focus — from the\n\t * DOM, and a browser answers that by focusing `<body>`: whoever opened the trail\n\t * from the keyboard would have to tab from the top of the page to reach the crumbs\n\t * they just asked for. Focus lands on the first revealed crumb instead, which is\n\t * where reading continues.\n\t */\n\t#focusFirstRevealedCrumb(): void {\n\t\tconst crumbs = this.#host.nativeElement.querySelectorAll<HTMLElement>('.hub-breadcrumb__item');\n\t\tconst revealed = crumbs[Math.max(0, this.itemsBeforeCollapse())];\n\n\t\tif (!revealed) {\n\t\t\treturn;\n\t\t}\n\n\t\t// A crumb may render as plain text — the current page, or a custom template with\n\t\t// no control of its own — and text takes no focus. Make that one crumb\n\t\t// programmatically focusable rather than let focus fall back to the body.\n\t\tconst target = revealed.querySelector<HTMLElement>('a, button, [tabindex]') ?? revealed;\n\t\tif (target === revealed) {\n\t\t\trevealed.tabIndex = -1;\n\t\t}\n\n\t\ttarget.focus();\n\t}\n\n\t/**\n\t * A crumb opening in a new tab hands the opener to the destination unless it\n\t * says otherwise, so the default closes that door rather than leaving it to\n\t * each consumer to remember.\n\t */\n\tprivate resolveRel(item: BreadcrumbItem): string | null {\n\t\treturn item.rel ?? (item.target === '_blank' ? 'noopener noreferrer' : null);\n\t}\n}\n","<nav aria-label=\"breadcrumb\" class=\"hub-breadcrumb__nav\">\n\t<ol class=\"hub-breadcrumb__list\">\n\t\t@for (row of rows(); track $index) {\n\t\t\t@if (row.item; as item) {\n\t\t\t\t<li\n\t\t\t\t\tclass=\"hub-breadcrumb__item\"\n\t\t\t\t\t[class.hub-breadcrumb__item--active]=\"row.isLast\"\n\t\t\t\t\t[attr.aria-current]=\"row.isLast ? 'page' : null\"\n\t\t\t\t>\n\t\t\t\t\t@if (itemTemplate(); as template) {\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"template\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{\n\t\t\t\t\t\t\t\t$implicit: item,\n\t\t\t\t\t\t\t\tisLast: row.isLast\n\t\t\t\t\t\t\t}\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t} @else if (row.isLast) {\n\t\t\t\t\t\t<span class=\"hub-breadcrumb__text\" hubBreadcrumbLabel>{{ item.label }}</span>\n\t\t\t\t\t} @else if (item.href) {\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\tclass=\"hub-breadcrumb__link\"\n\t\t\t\t\t\t\thubBreadcrumbLabel\n\t\t\t\t\t\t\t[href]=\"item.href\"\n\t\t\t\t\t\t\t[attr.target]=\"item.target ?? null\"\n\t\t\t\t\t\t\t[attr.rel]=\"row.rel\"\n\t\t\t\t\t\t\t[attr.download]=\"item.download ?? null\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<a [routerLink]=\"item.url\" class=\"hub-breadcrumb__link\" hubBreadcrumbLabel>\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t}\n\t\t\t\t</li>\n\t\t\t} @else {\n\t\t\t\t<li class=\"hub-breadcrumb__item hub-breadcrumb__item--collapsed\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-breadcrumb__collapsed\"\n\t\t\t\t\t\t[attr.aria-label]=\"collapsedAriaLabel()\"\n\t\t\t\t\t\t[attr.aria-expanded]=\"expanded()\"\n\t\t\t\t\t\t(click)=\"expand()\"\n\t\t\t\t\t>\n\t\t\t\t\t\t&hellip;\n\t\t\t\t\t</button>\n\t\t\t\t</li>\n\t\t\t}\n\t\t}\n\t</ol>\n</nav>\n","import { NgModule } from '@angular/core';\nimport { HubBreadcrumbComponent } from './components/breadcrumb/breadcrumb.component';\nimport { HubBreadcrumbItemDirective } from './directives/breadcrumb-item.directive';\n\n/**\n * Backward-compatibility module for NgModule-based applications.\n *\n * @deprecated Import the standalone `HubBreadcrumbComponent` and `HubBreadcrumbItemDirective`\n * directly; this module only re-exports them and provides nothing of its own. Scheduled for\n * removal in **23.0.0**.\n */\n@NgModule({\n\tdeclarations: [],\n\timports: [HubBreadcrumbComponent, HubBreadcrumbItemDirective],\n\texports: [HubBreadcrumbComponent, HubBreadcrumbItemDirective]\n})\nexport class HubBreadcrumbsModule {}\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { HUB_BREADCRUMB_TOOLTIP_ADAPTER } from './breadcrumb-tooltip.token';\nimport { HubBreadcrumbTooltipAdapter } from './breadcrumb-tooltip.types';\n\n/**\n * Registers a tooltip adapter so truncated breadcrumb labels render the rich\n * hub-ui tooltip instead of the native `title` fallback.\n *\n * ```ts\n * import { provideHubBreadcrumbTooltip } from 'ng-hub-ui-breadcrumbs';\n * import { hubTooltipAdapter } from 'ng-hub-ui-utils';\n *\n * providers: [provideHubBreadcrumbTooltip(hubTooltipAdapter)];\n * ```\n *\n * @param adapter Tooltip adapter implementation (e.g. `hubTooltipAdapter` from\n * `ng-hub-ui-utils`).\n * @returns Environment providers to add to the application config.\n */\nexport function provideHubBreadcrumbTooltip(adapter: HubBreadcrumbTooltipAdapter): EnvironmentProviders {\n\treturn makeEnvironmentProviders([\n\t\t{\n\t\t\tprovide: HUB_BREADCRUMB_TOOLTIP_ADAPTER,\n\t\t\tuseValue: adapter\n\t\t}\n\t]);\n}\n","/*\n * Public API Surface of breadcrumbs\n */\nexport * from './lib/breadcrumbs.module';\nexport * from './lib/breadcrumb-tooltip';\nexport * from './lib/components/breadcrumb/breadcrumb.component';\nexport * from './lib/directives/breadcrumb-item.directive';\nexport * from './lib/directives/breadcrumb-label.directive';\nexport * from './lib/models/breadcrumb-item';\nexport * from './lib/models/breadcrumb-template-context';\nexport * from './lib/services/breadcrumbs.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ng-hub-ui-breadcrumbs.mjs","sources":["../../../projects/breadcrumbs/src/lib/directives/breadcrumb-item.directive.ts","../../../projects/breadcrumbs/src/lib/breadcrumb-tooltip/breadcrumb-tooltip.token.ts","../../../projects/breadcrumbs/src/lib/directives/breadcrumb-label.directive.ts","../../../projects/breadcrumbs/src/lib/services/breadcrumbs.service.ts","../../../projects/breadcrumbs/src/lib/components/breadcrumb/breadcrumb.component.ts","../../../projects/breadcrumbs/src/lib/components/breadcrumb/breadcrumb.component.html","../../../projects/breadcrumbs/src/lib/breadcrumbs.module.ts","../../../projects/breadcrumbs/src/lib/breadcrumb-tooltip/breadcrumb-tooltip.provider.ts","../../../projects/breadcrumbs/src/public-api.ts","../../../projects/breadcrumbs/src/ng-hub-ui-breadcrumbs.ts"],"sourcesContent":["import { Directive, inject, TemplateRef } from '@angular/core';\nimport { BreadcrumbTemplateContext } from '../models/breadcrumb-template-context';\n\n@Directive({\n\tselector: '[hubBreadcrumbItem]'\n})\nexport class HubBreadcrumbItemDirective {\n\ttemplate = inject(TemplateRef<BreadcrumbTemplateContext>);\n}\n","import { InjectionToken } from '@angular/core';\nimport { HubBreadcrumbTooltipAdapter } from './breadcrumb-tooltip.types';\n\n/**\n * Injection token resolving the optional tooltip adapter used by truncated\n * breadcrumb labels.\n *\n * Inject it with `{ optional: true }`; a `null` value means \"use the native\n * `title` fallback\". Register it through {@link provideHubBreadcrumbTooltip}.\n */\nexport const HUB_BREADCRUMB_TOOLTIP_ADAPTER = new InjectionToken<HubBreadcrumbTooltipAdapter>('HUB_BREADCRUMB_TOOLTIP_ADAPTER');\n","import { afterNextRender, Directive, effect, ElementRef, inject, input, OnDestroy, signal } from '@angular/core';\nimport { HUB_BREADCRUMB_TOOLTIP_ADAPTER } from '../breadcrumb-tooltip/breadcrumb-tooltip.token';\nimport { HubBreadcrumbTooltipHandle } from '../breadcrumb-tooltip/breadcrumb-tooltip.types';\n\n/**\n * Adds an overflow-aware tooltip to a breadcrumb label element.\n *\n * When the label is truncated (its rendered text is wider than its box — typically\n * because `hub-breadcrumb` truncation is enabled), the directive exposes the full\n * text as a tooltip: the native `title` attribute by default, or the richer hub-ui\n * tooltip when a {@link HUB_BREADCRUMB_TOOLTIP_ADAPTER} is provided. When the\n * label fits, no tooltip is shown.\n *\n * `hub-breadcrumb` already applies it to the labels it renders and to the box it\n * wraps a `hubBreadcrumbItem` template in, so applying `[hubBreadcrumbLabel]` by\n * hand is for saying something other than the label — a full path, a spelled-out\n * date — through the directive's own input.\n */\n@Directive({\n\tselector: '[hubBreadcrumbLabel]'\n})\nexport class HubBreadcrumbLabelDirective implements OnDestroy {\n\t/**\n\t * Explicit tooltip text. When empty, the host's own text content is used, but\n\t * only while it is truncated.\n\t */\n\treadonly tooltip = input('', { alias: 'hubBreadcrumbLabel' });\n\n\tprivate readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n\n\t/** Optional hub-ui tooltip adapter; absent means native `title` fallback. */\n\tprivate readonly adapter = inject(HUB_BREADCRUMB_TOOLTIP_ADAPTER, { optional: true });\n\n\t/** Whether the rendered label is wider than its clipping box. */\n\tprivate readonly isOverflowing = signal(false);\n\n\t/** Trimmed text content of the label, used as the auto tooltip source. */\n\tprivate readonly text = signal('');\n\n\t/** Becomes true once the browser-only overflow tracking is wired. */\n\tprivate readonly ready = signal(false);\n\n\tprivate resizeObserver: ResizeObserver | null = null;\n\tprivate mutationObserver: MutationObserver | null = null;\n\tprivate handle: HubBreadcrumbTooltipHandle | null = null;\n\n\tconstructor() {\n\t\tafterNextRender(() => this.initOverflowTracking());\n\n\t\teffect(() => {\n\t\t\tif (!this.ready()) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst explicit = this.tooltip().trim();\n\t\t\tconst text = explicit || (this.isOverflowing() ? this.text() : '');\n\t\t\tthis.applyTooltip(text);\n\t\t});\n\t}\n\n\tngOnDestroy(): void {\n\t\tthis.resizeObserver?.disconnect();\n\t\tthis.mutationObserver?.disconnect();\n\t\tthis.handle?.destroy();\n\t\tthis.handle = null;\n\t}\n\n\t/** Wires browser-only observers that keep the truncation state in sync. */\n\tprivate initOverflowTracking(): void {\n\t\tconst el = this.host.nativeElement;\n\t\tthis.measure(el);\n\n\t\tif (typeof ResizeObserver !== 'undefined') {\n\t\t\tthis.resizeObserver = new ResizeObserver(() => this.measure(el));\n\t\t\tthis.resizeObserver.observe(el);\n\t\t}\n\n\t\tif (typeof MutationObserver !== 'undefined') {\n\t\t\tthis.mutationObserver = new MutationObserver(() => this.measure(el));\n\t\t\tthis.mutationObserver.observe(el, { childList: true, characterData: true, subtree: true });\n\t\t}\n\n\t\tthis.ready.set(true);\n\t}\n\n\t/** Reads the host's text and truncation state into the signals. */\n\tprivate measure(el: HTMLElement): void {\n\t\tthis.text.set((el.textContent ?? '').trim());\n\t\tthis.isOverflowing.set(el.scrollWidth > el.clientWidth + 1);\n\t}\n\n\t/**\n\t * Applies the effective tooltip text through the hub-ui adapter when present,\n\t * or the native `title` attribute otherwise. An empty text removes both.\n\t */\n\tprivate applyTooltip(text: string): void {\n\t\tconst el = this.host.nativeElement;\n\n\t\tif (this.adapter) {\n\t\t\tel.removeAttribute('title');\n\t\t\tif (text) {\n\t\t\t\tif (this.handle) {\n\t\t\t\t\tthis.handle.update(text);\n\t\t\t\t} else {\n\t\t\t\t\tthis.handle = this.adapter.attach(el, text);\n\t\t\t\t}\n\t\t\t} else if (this.handle) {\n\t\t\t\tthis.handle.destroy();\n\t\t\t\tthis.handle = null;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (text) {\n\t\t\tel.setAttribute('title', text);\n\t\t} else {\n\t\t\tel.removeAttribute('title');\n\t\t}\n\t}\n}\n","import { inject, Injectable, Signal } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { ActivatedRoute, NavigationEnd, Router } from '@angular/router';\nimport { filter, map, startWith } from 'rxjs';\nimport { BreadcrumbItem, BreadcrumbRouteConfig, BreadcrumbRouteData } from '../models/breadcrumb-item';\n\n@Injectable({\n\tprovidedIn: 'root'\n})\nexport class HubBreadcrumbsService {\n\t#router = inject(Router);\n\t#activatedRoute = inject(ActivatedRoute);\n\n\t/** The trail as a stream, for consumers already composing with rxjs. */\n\tbreadcrumbs$ = this.#router.events.pipe(\n\t\tfilter((event) => event instanceof NavigationEnd),\n\t\tstartWith(undefined),\n\t\tmap(() => this.createBreadcrumbs(this.#activatedRoute.root))\n\t);\n\n\t/**\n\t * The trail as a signal, and the surface the component reads. Published here\n\t * rather than left to each consumer, because a stream that only ever carries\n\t * the current trail is one every caller was wrapping in the same `toSignal`\n\t * — the component included. Wrapped once, subscribed once.\n\t */\n\treadonly breadcrumbs: Signal<BreadcrumbItem[]> = toSignal(this.breadcrumbs$, { initialValue: [] as BreadcrumbItem[] });\n\n\tprivate createBreadcrumbs(route: ActivatedRoute, url: string = '', breadcrumbs: BreadcrumbItem[] = []): BreadcrumbItem[] {\n\t\tconst children: ActivatedRoute[] = route.children;\n\n\t\tif (children.length === 0) {\n\t\t\treturn breadcrumbs;\n\t\t}\n\n\t\tfor (const child of children) {\n\t\t\t// A route is recognised before it is activated, and carries `_futureSnapshot`\n\t\t\t// in between while `snapshot` is still unset. `breadcrumbs$` opens with\n\t\t\t// `startWith(undefined)`, so a shell that draws its breadcrumb on the first\n\t\t\t// paint walks the tree inside that window — and reading `.url` there threw,\n\t\t\t// out of a subscription that draws the whole page header, taking the header\n\t\t\t// with it. There is nothing to name yet either: a route with no snapshot has\n\t\t\t// no segments and no resolved data, so it is skipped rather than guessed at.\n\t\t\tif (!child.snapshot) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst routeSegments = child.snapshot.url;\n\n\t\t\t// URL of this level\n\t\t\tconst routeURL: string = routeSegments.map((segment) => segment.path).join('/');\n\n\t\t\tconst nextUrl = routeURL ? `${url}/${routeURL}` : url;\n\n\t\t\t// Only the routes declaring their own breadcrumb become a crumb\n\t\t\tconst hasBreadcrumbData = this.hasOwnBreadcrumbData(child);\n\n\t\t\tif (hasBreadcrumbData) {\n\t\t\t\tbreadcrumbs.push(this.createItem(child, nextUrl));\n\t\t\t}\n\n\t\t\treturn this.createBreadcrumbs(child, nextUrl, breadcrumbs);\n\t\t}\n\n\t\treturn breadcrumbs;\n\t}\n\n\tprivate hasOwnBreadcrumbData(route: ActivatedRoute): boolean {\n\t\tconst routeConfig = route.routeConfig;\n\t\treturn !!(routeConfig && routeConfig.data && routeConfig.data['breadcrumb']);\n\t}\n\n\t/**\n\t * Builds the crumb for a route. The object form of `data.breadcrumb` carries\n\t * anchor metadata for destinations outside the router; whatever accompanies\n\t * `label` there travels to the item untouched, so a new anchor attribute needs\n\t * no change here.\n\t */\n\tprivate createItem(route: ActivatedRoute, url: string): BreadcrumbItem {\n\t\tconst data = route.snapshot.data;\n\t\tconst config: BreadcrumbRouteData = data['breadcrumb'];\n\n\t\tif (this.isRouteConfig(config)) {\n\t\t\tconst { label: labelSource, ...anchor } = config;\n\t\t\treturn { label: this.resolveLabel(labelSource, data), url, data, ...anchor };\n\t\t}\n\n\t\treturn { label: this.resolveLabel(config, data), url, data };\n\t}\n\n\t/** Narrows `data.breadcrumb` to its object form, excluding the function form. */\n\tprivate isRouteConfig(config: BreadcrumbRouteData): config is BreadcrumbRouteConfig {\n\t\treturn typeof config === 'object' && config !== null;\n\t}\n\n\tprivate resolveLabel(source: string | ((data: any) => string), data: any): string {\n\t\tconst label = typeof source === 'function' ? source(data) : source;\n\n\t\treturn data['resolvedData'] ? this.getResolvedBreadcrumb(label, data['resolvedData']) : label;\n\t}\n\n\tprivate getResolvedBreadcrumb(template: string, data: any): string {\n\t\treturn template.replace(/\\{([^}]+)\\}/g, (match, key) => {\n\t\t\treturn data[key] || match;\n\t\t});\n\t}\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n\tafterNextRender,\n\tChangeDetectionStrategy,\n\tComponent,\n\tcomputed,\n\tcontentChild,\n\tElementRef,\n\tinject,\n\tInjector,\n\tinput,\n\tlinkedSignal,\n\toutput,\n\tTemplateRef\n} from '@angular/core';\nimport { RouterLink } from '@angular/router';\nimport { HubBreadcrumbItemDirective } from '../../directives/breadcrumb-item.directive';\nimport { HubBreadcrumbLabelDirective } from '../../directives/breadcrumb-label.directive';\nimport { BreadcrumbItem } from '../../models/breadcrumb-item';\nimport { HubBreadcrumbsService } from '../../services/breadcrumbs.service';\n\n/**\n * Variants with exact design-system token coverage via the SCSS `@each` loop.\n * Kept in step with that loop by hand, because Sass cannot read this file: a name\n * dropped from here is not broken, only paid for twice — once inline and once by\n * the stylesheet.\n */\nconst BUILT_IN_VARIANTS = new Set<string>([\n\t'primary',\n\t'secondary',\n\t'success',\n\t'danger',\n\t'warning',\n\t'info',\n\t'neutral',\n\t'light',\n\t'dark'\n]);\n\n/**\n * One rendered position of the trail. A `null` item is the collapsed indicator,\n * which occupies a position of its own so the separators fall around it exactly\n * as they do around a crumb.\n */\ninterface BreadcrumbRow {\n\titem: BreadcrumbItem | null;\n\tisLast: boolean;\n\t/** Resolved anchor `rel`, already defended for `_blank` targets. */\n\trel: string | null;\n}\n\n@Component({\n\tselector: 'hub-breadcrumb',\n\timports: [RouterLink, NgTemplateOutlet, HubBreadcrumbLabelDirective],\n\ttemplateUrl: './breadcrumb.component.html',\n\tstyleUrl: './breadcrumb.component.scss',\n\tchangeDetection: ChangeDetectionStrategy.OnPush,\n\thost: {\n\t\tclass: 'hub-breadcrumb',\n\t\t'[class.hub-breadcrumb--truncate]': 'truncateItems()',\n\t\t'[attr.data-variant]': 'variant() ?? null',\n\t\t'[style.--hub-breadcrumb-accent]': 'customAccent()'\n\t}\n})\nexport class HubBreadcrumbComponent {\n\t#breadcrumbsSvc = inject(HubBreadcrumbsService);\n\t#host = inject<ElementRef<HTMLElement>>(ElementRef);\n\t#injector = inject(Injector);\n\n\treadonly itemTemplate = contentChild(HubBreadcrumbItemDirective, { read: TemplateRef });\n\n\t/**\n\t * Semantic accent for the breadcrumb links: `'primary'` · `'secondary'` ·\n\t * `'success'` · `'danger'` · `'warning'` · `'info'` · `'neutral'` · `'light'` ·\n\t * `'dark'`, or any custom string (read as `--hub-sys-color-<variant>`).\n\t * Re-bases `--hub-breadcrumb-accent`; the current (last) item stays muted.\n\t * Defaults to the standard link colour.\n\t */\n\treadonly variant = input<string>();\n\n\t/**\n\t * Opt-in per-item truncation. When `true`, each label is clipped to\n\t * `--hub-breadcrumb-max-item-width` with an ellipsis and, if it overflows,\n\t * exposes its full text as a tooltip (native `title`, or the hub-ui tooltip\n\t * when {@link provideHubBreadcrumbTooltip} is wired). Off by default, so the\n\t * standard breadcrumb layout is unchanged.\n\t *\n\t * It reaches a `hubBreadcrumbItem` template as well: the projected elements\n\t * belong to the consuming component, so the template wraps them in a\n\t * `span.hub-breadcrumb__custom` of its own and clips that instead.\n\t */\n\treadonly truncateItems = input(false);\n\n\t/**\n\t * Trail supplied by the consumer, replacing the one derived from the router.\n\t * It is the way in for crumbs the route tree cannot express — an ancestor\n\t * served by another application, or a trail assembled by hand. Left `null`,\n\t * the component keeps reading {@link HubBreadcrumbsService}.\n\t */\n\treadonly items = input<BreadcrumbItem[] | null>(null);\n\n\t/**\n\t * Length above which the trail collapses behind an indicator. Undefined (the\n\t * default) never collapses, however long the trail grows.\n\t */\n\treadonly maxItems = input<number | undefined>(undefined);\n\n\t/** Crumbs kept at the head of a collapsed trail. */\n\treadonly itemsBeforeCollapse = input(1);\n\n\t/** Crumbs kept at the tail of a collapsed trail, the current page included. */\n\treadonly itemsAfterCollapse = input(1);\n\n\t/**\n\t * Accessible name of the collapsed indicator. It is an input rather than a\n\t * literal because it is the one string of this component a screen reader\n\t * announces, and the library carries no translations of its own.\n\t */\n\treadonly collapsedAriaLabel = input('Show the hidden breadcrumb items');\n\n\t/**\n\t * Fires when the collapsed indicator is activated. The trail expands in place\n\t * on its own; the event is there for consumers who want to react as well —\n\t * open a menu of the hidden crumbs, log the interaction.\n\t */\n\treadonly collapsedClick = output<void>();\n\n\t/** Effective trail: the manual one when supplied, the router's otherwise. */\n\tprotected readonly trail = computed(() => this.items() ?? this.#breadcrumbsSvc.breadcrumbs());\n\n\t/**\n\t * Whether the reader has opened a collapsed trail. Derived from the trail so a\n\t * new navigation collapses it again — an expansion answers one trail, not the\n\t * component's whole lifetime.\n\t */\n\tprotected readonly expanded = linkedSignal<BreadcrumbItem[], boolean>({\n\t\tsource: this.trail,\n\t\tcomputation: () => false\n\t});\n\n\t/** Rendered positions, with the collapsed range folded into one indicator. */\n\tprotected readonly rows = computed<BreadcrumbRow[]>(() => {\n\t\tconst items = this.trail();\n\t\tconst before = Math.max(0, this.itemsBeforeCollapse());\n\t\tconst after = Math.max(0, this.itemsAfterCollapse());\n\t\tconst max = this.maxItems();\n\n\t\tconst rowAt = (item: BreadcrumbItem, index: number): BreadcrumbRow => ({\n\t\t\titem,\n\t\t\tisLast: index === items.length - 1,\n\t\t\trel: this.resolveRel(item)\n\t\t});\n\n\t\tconst collapses = max !== undefined && max > 0 && items.length > max && before + after < items.length;\n\n\t\tif (!collapses || this.expanded()) {\n\t\t\treturn items.map(rowAt);\n\t\t}\n\n\t\tconst tailStart = items.length - after;\n\n\t\treturn [\n\t\t\t...items.slice(0, before).map(rowAt),\n\t\t\t{ item: null, isLast: false, rel: null },\n\t\t\t...items.slice(tailStart).map((item, index) => rowAt(item, tailStart + index))\n\t\t];\n\t});\n\n\t/**\n\t * Inline accent for custom (non-built-in) variants — the nine built-in accents\n\t * are resolved by the SCSS `@each` loop, so this returns `null` for them.\n\t */\n\tprotected readonly customAccent = computed(() => {\n\t\tconst v = this.variant();\n\t\treturn v && !BUILT_IN_VARIANTS.has(v) ? `var(--hub-sys-color-${v})` : null;\n\t});\n\n\t/** Opens a collapsed trail and lets the consumer act on the same gesture. */\n\tprotected expand(): void {\n\t\tthis.expanded.set(true);\n\t\tthis.collapsedClick.emit();\n\t\tafterNextRender(() => this.#focusFirstRevealedCrumb(), { injector: this.#injector });\n\t}\n\n\t/**\n\t * Expanding removes the indicator — the element that was holding focus — from the\n\t * DOM, and a browser answers that by focusing `<body>`: whoever opened the trail\n\t * from the keyboard would have to tab from the top of the page to reach the crumbs\n\t * they just asked for. Focus lands on the first revealed crumb instead, which is\n\t * where reading continues.\n\t */\n\t#focusFirstRevealedCrumb(): void {\n\t\tconst crumbs = this.#host.nativeElement.querySelectorAll<HTMLElement>('.hub-breadcrumb__item');\n\t\tconst revealed = crumbs[Math.max(0, this.itemsBeforeCollapse())];\n\n\t\tif (!revealed) {\n\t\t\treturn;\n\t\t}\n\n\t\t// A crumb may render as plain text — the current page, or a custom template with\n\t\t// no control of its own — and text takes no focus. Make that one crumb\n\t\t// programmatically focusable rather than let focus fall back to the body.\n\t\tconst target = revealed.querySelector<HTMLElement>('a, button, [tabindex]') ?? revealed;\n\t\tif (target === revealed) {\n\t\t\trevealed.tabIndex = -1;\n\t\t}\n\n\t\ttarget.focus();\n\t}\n\n\t/**\n\t * A crumb opening in a new tab hands the opener to the destination unless it\n\t * says otherwise, so the default closes that door rather than leaving it to\n\t * each consumer to remember.\n\t */\n\tprivate resolveRel(item: BreadcrumbItem): string | null {\n\t\treturn item.rel ?? (item.target === '_blank' ? 'noopener noreferrer' : null);\n\t}\n}\n","<nav aria-label=\"breadcrumb\" class=\"hub-breadcrumb__nav\">\n\t<ol class=\"hub-breadcrumb__list\">\n\t\t@for (row of rows(); track $index) {\n\t\t\t@if (row.item; as item) {\n\t\t\t\t<li\n\t\t\t\t\tclass=\"hub-breadcrumb__item\"\n\t\t\t\t\t[class.hub-breadcrumb__item--active]=\"row.isLast\"\n\t\t\t\t\t[attr.aria-current]=\"row.isLast ? 'page' : null\"\n\t\t\t\t>\n\t\t\t\t\t@if (itemTemplate(); as template) {\n\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\tThe clipping box for a custom crumb. Scoped styles never reach the elements\n\t\t\t\t\t\t\ta `hubBreadcrumbItem` template renders — they belong to the consuming\n\t\t\t\t\t\t\tcomponent — so `truncateItems` can only clip something this component draws\n\t\t\t\t\t\t\titself. It sits exactly where a built-in label sits, inside the item and\n\t\t\t\t\t\t\toutside the separator, so a projected crumb gets the same width as any other.\n\t\t\t\t\t\t-->\n\t\t\t\t\t\t<span class=\"hub-breadcrumb__custom\" hubBreadcrumbLabel>\n\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"template\"\n\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{\n\t\t\t\t\t\t\t\t\t$implicit: item,\n\t\t\t\t\t\t\t\t\tisLast: row.isLast\n\t\t\t\t\t\t\t\t}\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t} @else if (row.isLast) {\n\t\t\t\t\t\t<span class=\"hub-breadcrumb__text\" hubBreadcrumbLabel>{{ item.label }}</span>\n\t\t\t\t\t} @else if (item.href) {\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\tclass=\"hub-breadcrumb__link\"\n\t\t\t\t\t\t\thubBreadcrumbLabel\n\t\t\t\t\t\t\t[href]=\"item.href\"\n\t\t\t\t\t\t\t[attr.target]=\"item.target ?? null\"\n\t\t\t\t\t\t\t[attr.rel]=\"row.rel\"\n\t\t\t\t\t\t\t[attr.download]=\"item.download ?? null\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<a [routerLink]=\"item.url\" class=\"hub-breadcrumb__link\" hubBreadcrumbLabel>\n\t\t\t\t\t\t\t{{ item.label }}\n\t\t\t\t\t\t</a>\n\t\t\t\t\t}\n\t\t\t\t</li>\n\t\t\t} @else {\n\t\t\t\t<li class=\"hub-breadcrumb__item hub-breadcrumb__item--collapsed\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"hub-breadcrumb__collapsed\"\n\t\t\t\t\t\t[attr.aria-label]=\"collapsedAriaLabel()\"\n\t\t\t\t\t\t[attr.aria-expanded]=\"expanded()\"\n\t\t\t\t\t\t(click)=\"expand()\"\n\t\t\t\t\t>\n\t\t\t\t\t\t&hellip;\n\t\t\t\t\t</button>\n\t\t\t\t</li>\n\t\t\t}\n\t\t}\n\t</ol>\n</nav>\n","import { NgModule } from '@angular/core';\nimport { HubBreadcrumbComponent } from './components/breadcrumb/breadcrumb.component';\nimport { HubBreadcrumbItemDirective } from './directives/breadcrumb-item.directive';\n\n/**\n * Backward-compatibility module for NgModule-based applications.\n *\n * @deprecated Import the standalone `HubBreadcrumbComponent` and `HubBreadcrumbItemDirective`\n * directly; this module only re-exports them and provides nothing of its own. Scheduled for\n * removal in **23.0.0**.\n */\n@NgModule({\n\tdeclarations: [],\n\timports: [HubBreadcrumbComponent, HubBreadcrumbItemDirective],\n\texports: [HubBreadcrumbComponent, HubBreadcrumbItemDirective]\n})\nexport class HubBreadcrumbsModule {}\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { HUB_BREADCRUMB_TOOLTIP_ADAPTER } from './breadcrumb-tooltip.token';\nimport { HubBreadcrumbTooltipAdapter } from './breadcrumb-tooltip.types';\n\n/**\n * Registers a tooltip adapter so truncated breadcrumb labels render the rich\n * hub-ui tooltip instead of the native `title` fallback.\n *\n * ```ts\n * import { provideHubBreadcrumbTooltip } from 'ng-hub-ui-breadcrumbs';\n * import { hubTooltipAdapter } from 'ng-hub-ui-utils';\n *\n * providers: [provideHubBreadcrumbTooltip(hubTooltipAdapter)];\n * ```\n *\n * @param adapter Tooltip adapter implementation (e.g. `hubTooltipAdapter` from\n * `ng-hub-ui-utils`).\n * @returns Environment providers to add to the application config.\n */\nexport function provideHubBreadcrumbTooltip(adapter: HubBreadcrumbTooltipAdapter): EnvironmentProviders {\n\treturn makeEnvironmentProviders([\n\t\t{\n\t\t\tprovide: HUB_BREADCRUMB_TOOLTIP_ADAPTER,\n\t\t\tuseValue: adapter\n\t\t}\n\t]);\n}\n","/*\n * Public API Surface of breadcrumbs\n */\nexport * from './lib/breadcrumbs.module';\nexport * from './lib/breadcrumb-tooltip';\nexport * from './lib/components/breadcrumb/breadcrumb.component';\nexport * from './lib/directives/breadcrumb-item.directive';\nexport * from './lib/directives/breadcrumb-label.directive';\nexport * from './lib/models/breadcrumb-item';\nexport * from './lib/models/breadcrumb-template-context';\nexport * from './lib/services/breadcrumbs.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ng-hub-ui-breadcrumbs",
3
- "version": "22.6.0",
3
+ "version": "22.7.1",
4
4
  "description": "A flexible and reusable breadcrumb component for Angular applications that automatically generates breadcrumbs based on routing configuration",
5
5
  "keywords": [
6
6
  "angular",
@@ -25,7 +25,13 @@
25
25
  "homepage": "https://hubui.dev/en/breadcrumbs/overview/",
26
26
  "peerDependencies": {
27
27
  "@angular/common": ">=18.0.0",
28
- "@angular/core": ">=18.0.0"
28
+ "@angular/core": ">=18.0.0",
29
+ "ng-hub-ui-ds": ">=22.0.0"
30
+ },
31
+ "peerDependenciesMeta": {
32
+ "ng-hub-ui-ds": {
33
+ "optional": true
34
+ }
29
35
  },
30
36
  "dependencies": {
31
37
  "tslib": "^2.3.0"
@@ -67,6 +67,10 @@ declare class HubBreadcrumbComponent {
67
67
  * exposes its full text as a tooltip (native `title`, or the hub-ui tooltip
68
68
  * when {@link provideHubBreadcrumbTooltip} is wired). Off by default, so the
69
69
  * standard breadcrumb layout is unchanged.
70
+ *
71
+ * It reaches a `hubBreadcrumbItem` template as well: the projected elements
72
+ * belong to the consuming component, so the template wraps them in a
73
+ * `span.hub-breadcrumb__custom` of its own and clips that instead.
70
74
  */
71
75
  readonly truncateItems: _angular_core.InputSignal<boolean>;
72
76
  /**
@@ -203,12 +207,16 @@ declare function provideHubBreadcrumbTooltip(adapter: HubBreadcrumbTooltipAdapte
203
207
  /**
204
208
  * Adds an overflow-aware tooltip to a breadcrumb label element.
205
209
  *
206
- * Apply `[hubBreadcrumbLabel]` to the link/text of each breadcrumb item. When the
207
- * label is truncated (its rendered text is wider than its box — typically because
208
- * `hub-breadcrumb` truncation is enabled), the directive exposes the full text as
209
- * a tooltip: the native `title` attribute by default, or the richer hub-ui
210
+ * When the label is truncated (its rendered text is wider than its box — typically
211
+ * because `hub-breadcrumb` truncation is enabled), the directive exposes the full
212
+ * text as a tooltip: the native `title` attribute by default, or the richer hub-ui
210
213
  * tooltip when a {@link HUB_BREADCRUMB_TOOLTIP_ADAPTER} is provided. When the
211
214
  * label fits, no tooltip is shown.
215
+ *
216
+ * `hub-breadcrumb` already applies it to the labels it renders and to the box it
217
+ * wraps a `hubBreadcrumbItem` template in, so applying `[hubBreadcrumbLabel]` by
218
+ * hand is for saying something other than the label — a full path, a spelled-out
219
+ * date — through the directive's own input.
212
220
  */
213
221
  declare class HubBreadcrumbLabelDirective implements OnDestroy {
214
222
  /**