fold-ng 0.14.0 → 0.15.0

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/CHANGELOG.md CHANGED
@@ -8,6 +8,30 @@ All notable changes to **fold-ng** are documented here. The format follows
8
8
 
9
9
  _Nothing yet._
10
10
 
11
+ ## [0.15.0] - 2026-08-24
12
+
13
+ ### Added
14
+
15
+ - **`fold-page-layout` a un créneau `[pageEyebrow]`** — la rangée AU-DESSUS du
16
+ titre, pour un fil d'Ariane, un lien de retour, une étiquette de rubrique.
17
+ C'est le seul créneau d'en-tête dont la mise en page ne restyle pas le
18
+ contenu : un fil et une étiquette n'ont rien de typographique en commun, donc
19
+ ce qu'on y projette garde son visage. Un eyebrow seul **n'allume pas**
20
+ l'en-tête — une étiquette sans titre n'étiquette rien.
21
+
22
+ Ce que ça remplace : un lien « ← Retour » projeté dans `[pageActions]`, donc
23
+ peint en haut à DROITE alors qu'il désigne le haut de la hiérarchie. Il y
24
+ était faute de place pour l'écrire ailleurs.
25
+
26
+ - **`fold-breadcrumb` gagne `[currentPage]`** (défaut `true`, aucun changement).
27
+ À `false`, le fil ne nomme que les **ancêtres** : le dernier maillon se
28
+ comporte comme les autres — lien s'il porte une cible, texte sinon — et plus
29
+ rien ne porte `aria-current`. C'est la forme qu'un fil prend au-dessus d'un
30
+ `<h1>` : le titre de la page EST la page courante. Sans ça, un fil posé dans
31
+ `[pageEyebrow]` devait soit répéter le titre en dernier maillon (du bruit que
32
+ l'œil saute), soit désigner la famille comme page courante — ce qui raconte au
33
+ lecteur d'écran quelque chose de faux.
34
+
11
35
  ## [0.14.0] - 2026-08-23
12
36
 
13
37
  ### Changed
@@ -1912,7 +1936,8 @@ design-token stylesheet.
1912
1936
  `currentColor`; `prefers-reduced-motion` + `forced-colors` are respected;
1913
1937
  strings localise via inputs / providers (`provideFoldPanelLabels`).
1914
1938
 
1915
- [unreleased]: https://github.com/hugoheynard/fold-ng/compare/v0.14.0...HEAD
1939
+ [unreleased]: https://github.com/hugoheynard/fold-ng/compare/v0.15.0...HEAD
1940
+ [0.15.0]: https://github.com/hugoheynard/fold-ng/releases/tag/v0.15.0
1916
1941
  [0.14.0]: https://github.com/hugoheynard/fold-ng/releases/tag/v0.14.0
1917
1942
  [0.13.0]: https://github.com/hugoheynard/fold-ng/releases/tag/v0.13.0
1918
1943
  [0.12.1]: https://github.com/hugoheynard/fold-ng/releases/tag/v0.12.1
@@ -11517,6 +11517,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
11517
11517
  *
11518
11518
  * Content projection:
11519
11519
  * - default slot → the page body (sections, cards, banners…).
11520
+ * - `[pageEyebrow]` → the row **above** the title: a {@link FoldBreadcrumbComponent}
11521
+ * trail, a {@link FoldBackLinkComponent}, a kicker label. It is the one header
11522
+ * row the layout does not restyle — a trail and a kicker share no typography,
11523
+ * so what you project keeps its own face. A breadcrumb placed here should name
11524
+ * the **ancestors only** (`[currentPage]="false"`): the page's own `<h1>` is
11525
+ * the current page, and repeating it in the trail is noise. Projecting an
11526
+ * eyebrow alone does **not** switch the header on — an eyebrow without a title
11527
+ * is a label with nothing to label.
11520
11528
  * - `[pageTitle]` ({@link FoldPageTitleDirective}) → a custom title, rendered
11521
11529
  * inside the `<h1>` in place of the `icon` + `title` inputs, for when a plain
11522
11530
  * string won't do (an avatar, a two-tone title). Its presence alone switches
@@ -11579,11 +11587,11 @@ class FoldPageLayoutComponent {
11579
11587
  customTitle = contentChild(FoldPageTitleDirective, /* @ts-ignore */
11580
11588
  ...(ngDevMode ? [{ debugName: "customTitle" }] : /* istanbul ignore next */ []));
11581
11589
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldPageLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11582
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldPageLayoutComponent, isStandalone: true, selector: "fold-page-layout", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, scroll: { classPropertyName: "scroll", publicName: "scroll", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.title": "null", "attr.data-scroll": "scroll()" } }, queries: [{ propertyName: "customTitle", first: true, predicate: FoldPageTitleDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (title() || customTitle()) {\n <header class=\"page-head\">\n <div class=\"page-head-text\">\n <h1 class=\"page-title\">\n @if (title(); as t) {\n @if (icon(); as ic) {\n <fold-icon class=\"page-icon\" [name]=\"ic\" [size]=\"22\" />\n }\n <span>{{ t }}</span>\n }\n <ng-content select=\"[pageTitle]\" />\n <span class=\"page-title-badge\"\n ><ng-content select=\"[titleBadge]\"\n /></span>\n </h1>\n <div class=\"page-desc\"><ng-content select=\"p[description]\" /></div>\n </div>\n <div class=\"page-actions\"><ng-content select=\"[pageActions]\" /></div>\n </header>\n}\n<div class=\"page-body\"><ng-content /></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;gap:var(--fold-page-gap, 32px);box-sizing:border-box;padding-block:var(--fold-page-pad-top, 28px) var(--fold-page-pad-bottom, 40px);padding-inline:var(--fold-page-gutter, 32px);flex:1 0 auto;min-height:0}:host([data-scroll=own]){flex:1 1 auto;overflow-y:auto;overscroll-behavior:contain}.page-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--fold-space-lg)}.page-head-text{display:flex;flex-direction:column;gap:var(--fold-space-xs);min-width:0}.page-title{margin:0;display:flex;align-items:center;gap:var(--fold-space-sm);font-size:var(--fold-text-xl);font-weight:var(--fold-weight-bold);letter-spacing:var(--fold-tracking-tighter);line-height:var(--fold-leading-tight);color:var(--fold-color-text)}.page-icon{flex:none;color:var(--fold-color-primary-text)}.page-title-badge{display:inline-flex;align-items:center;gap:var(--fold-space-sm)}.page-title-badge:empty{display:none}.page-desc{font-size:var(--fold-text-sm);line-height:var(--fold-leading-normal);max-width:var(--fold-page-desc-measure, none);color:var(--fold-color-text-muted)}.page-desc:empty{display:none}.page-desc>*{margin:0}.page-actions{flex:none;display:inline-flex;align-items:center;flex-wrap:wrap;gap:var(--fold-space-sm)}.page-actions:empty{display:none}@media(max-width:640px){.page-head{flex-direction:column;align-items:stretch;gap:var(--fold-space-md)}.page-actions{justify-content:flex-start}:host{padding-inline:calc(var(--fold-page-gutter, 32px) / 2)}}@container (max-width: 640px){.page-head{flex-direction:column;align-items:stretch;gap:var(--fold-space-md)}.page-actions{justify-content:flex-start}:host{padding-inline:calc(var(--fold-page-gutter, 32px) / 2)}}.page-body{display:flex;flex-direction:column;gap:var(--fold-page-gap, 32px)}\n"], dependencies: [{ kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
11590
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldPageLayoutComponent, isStandalone: true, selector: "fold-page-layout", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, scroll: { classPropertyName: "scroll", publicName: "scroll", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.title": "null", "attr.data-scroll": "scroll()" } }, queries: [{ propertyName: "customTitle", first: true, predicate: FoldPageTitleDirective, descendants: true, isSignal: true }], ngImport: i0, template: "@if (title() || customTitle()) {\n <header class=\"page-head\">\n <div class=\"page-head-text\">\n <div class=\"page-eyebrow\"><ng-content select=\"[pageEyebrow]\" /></div>\n <h1 class=\"page-title\">\n @if (title(); as t) {\n @if (icon(); as ic) {\n <fold-icon class=\"page-icon\" [name]=\"ic\" [size]=\"22\" />\n }\n <span>{{ t }}</span>\n }\n <ng-content select=\"[pageTitle]\" />\n <span class=\"page-title-badge\"\n ><ng-content select=\"[titleBadge]\"\n /></span>\n </h1>\n <div class=\"page-desc\"><ng-content select=\"p[description]\" /></div>\n </div>\n <div class=\"page-actions\"><ng-content select=\"[pageActions]\" /></div>\n </header>\n}\n<div class=\"page-body\"><ng-content /></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;gap:var(--fold-page-gap, 32px);box-sizing:border-box;padding-block:var(--fold-page-pad-top, 28px) var(--fold-page-pad-bottom, 40px);padding-inline:var(--fold-page-gutter, 32px);flex:1 0 auto;min-height:0}:host([data-scroll=own]){flex:1 1 auto;overflow-y:auto;overscroll-behavior:contain}.page-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--fold-space-lg)}.page-head-text{display:flex;flex-direction:column;gap:var(--fold-space-xs);min-width:0}.page-eyebrow{margin-block-end:var(--fold-space-xs)}.page-eyebrow:empty{display:none}.page-title{margin:0;display:flex;align-items:center;gap:var(--fold-space-sm);font-size:var(--fold-text-xl);font-weight:var(--fold-weight-bold);letter-spacing:var(--fold-tracking-tighter);line-height:var(--fold-leading-tight);color:var(--fold-color-text)}.page-icon{flex:none;color:var(--fold-color-primary-text)}.page-title-badge{display:inline-flex;align-items:center;gap:var(--fold-space-sm)}.page-title-badge:empty{display:none}.page-desc{font-size:var(--fold-text-sm);line-height:var(--fold-leading-normal);max-width:var(--fold-page-desc-measure, none);color:var(--fold-color-text-muted)}.page-desc:empty{display:none}.page-desc>*{margin:0}.page-actions{flex:none;display:inline-flex;align-items:center;flex-wrap:wrap;gap:var(--fold-space-sm)}.page-actions:empty{display:none}@media(max-width:640px){.page-head{flex-direction:column;align-items:stretch;gap:var(--fold-space-md)}.page-actions{justify-content:flex-start}:host{padding-inline:calc(var(--fold-page-gutter, 32px) / 2)}}@container (max-width: 640px){.page-head{flex-direction:column;align-items:stretch;gap:var(--fold-space-md)}.page-actions{justify-content:flex-start}:host{padding-inline:calc(var(--fold-page-gutter, 32px) / 2)}}.page-body{display:flex;flex-direction:column;gap:var(--fold-page-gap, 32px)}\n"], dependencies: [{ kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
11583
11591
  }
11584
11592
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldPageLayoutComponent, decorators: [{
11585
11593
  type: Component,
11586
- args: [{ selector: "fold-page-layout", standalone: true, imports: [FoldIconComponent], host: { "[attr.title]": "null", "[attr.data-scroll]": "scroll()" }, template: "@if (title() || customTitle()) {\n <header class=\"page-head\">\n <div class=\"page-head-text\">\n <h1 class=\"page-title\">\n @if (title(); as t) {\n @if (icon(); as ic) {\n <fold-icon class=\"page-icon\" [name]=\"ic\" [size]=\"22\" />\n }\n <span>{{ t }}</span>\n }\n <ng-content select=\"[pageTitle]\" />\n <span class=\"page-title-badge\"\n ><ng-content select=\"[titleBadge]\"\n /></span>\n </h1>\n <div class=\"page-desc\"><ng-content select=\"p[description]\" /></div>\n </div>\n <div class=\"page-actions\"><ng-content select=\"[pageActions]\" /></div>\n </header>\n}\n<div class=\"page-body\"><ng-content /></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;gap:var(--fold-page-gap, 32px);box-sizing:border-box;padding-block:var(--fold-page-pad-top, 28px) var(--fold-page-pad-bottom, 40px);padding-inline:var(--fold-page-gutter, 32px);flex:1 0 auto;min-height:0}:host([data-scroll=own]){flex:1 1 auto;overflow-y:auto;overscroll-behavior:contain}.page-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--fold-space-lg)}.page-head-text{display:flex;flex-direction:column;gap:var(--fold-space-xs);min-width:0}.page-title{margin:0;display:flex;align-items:center;gap:var(--fold-space-sm);font-size:var(--fold-text-xl);font-weight:var(--fold-weight-bold);letter-spacing:var(--fold-tracking-tighter);line-height:var(--fold-leading-tight);color:var(--fold-color-text)}.page-icon{flex:none;color:var(--fold-color-primary-text)}.page-title-badge{display:inline-flex;align-items:center;gap:var(--fold-space-sm)}.page-title-badge:empty{display:none}.page-desc{font-size:var(--fold-text-sm);line-height:var(--fold-leading-normal);max-width:var(--fold-page-desc-measure, none);color:var(--fold-color-text-muted)}.page-desc:empty{display:none}.page-desc>*{margin:0}.page-actions{flex:none;display:inline-flex;align-items:center;flex-wrap:wrap;gap:var(--fold-space-sm)}.page-actions:empty{display:none}@media(max-width:640px){.page-head{flex-direction:column;align-items:stretch;gap:var(--fold-space-md)}.page-actions{justify-content:flex-start}:host{padding-inline:calc(var(--fold-page-gutter, 32px) / 2)}}@container (max-width: 640px){.page-head{flex-direction:column;align-items:stretch;gap:var(--fold-space-md)}.page-actions{justify-content:flex-start}:host{padding-inline:calc(var(--fold-page-gutter, 32px) / 2)}}.page-body{display:flex;flex-direction:column;gap:var(--fold-page-gap, 32px)}\n"] }]
11594
+ args: [{ selector: "fold-page-layout", standalone: true, imports: [FoldIconComponent], host: { "[attr.title]": "null", "[attr.data-scroll]": "scroll()" }, template: "@if (title() || customTitle()) {\n <header class=\"page-head\">\n <div class=\"page-head-text\">\n <div class=\"page-eyebrow\"><ng-content select=\"[pageEyebrow]\" /></div>\n <h1 class=\"page-title\">\n @if (title(); as t) {\n @if (icon(); as ic) {\n <fold-icon class=\"page-icon\" [name]=\"ic\" [size]=\"22\" />\n }\n <span>{{ t }}</span>\n }\n <ng-content select=\"[pageTitle]\" />\n <span class=\"page-title-badge\"\n ><ng-content select=\"[titleBadge]\"\n /></span>\n </h1>\n <div class=\"page-desc\"><ng-content select=\"p[description]\" /></div>\n </div>\n <div class=\"page-actions\"><ng-content select=\"[pageActions]\" /></div>\n </header>\n}\n<div class=\"page-body\"><ng-content /></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;gap:var(--fold-page-gap, 32px);box-sizing:border-box;padding-block:var(--fold-page-pad-top, 28px) var(--fold-page-pad-bottom, 40px);padding-inline:var(--fold-page-gutter, 32px);flex:1 0 auto;min-height:0}:host([data-scroll=own]){flex:1 1 auto;overflow-y:auto;overscroll-behavior:contain}.page-head{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--fold-space-lg)}.page-head-text{display:flex;flex-direction:column;gap:var(--fold-space-xs);min-width:0}.page-eyebrow{margin-block-end:var(--fold-space-xs)}.page-eyebrow:empty{display:none}.page-title{margin:0;display:flex;align-items:center;gap:var(--fold-space-sm);font-size:var(--fold-text-xl);font-weight:var(--fold-weight-bold);letter-spacing:var(--fold-tracking-tighter);line-height:var(--fold-leading-tight);color:var(--fold-color-text)}.page-icon{flex:none;color:var(--fold-color-primary-text)}.page-title-badge{display:inline-flex;align-items:center;gap:var(--fold-space-sm)}.page-title-badge:empty{display:none}.page-desc{font-size:var(--fold-text-sm);line-height:var(--fold-leading-normal);max-width:var(--fold-page-desc-measure, none);color:var(--fold-color-text-muted)}.page-desc:empty{display:none}.page-desc>*{margin:0}.page-actions{flex:none;display:inline-flex;align-items:center;flex-wrap:wrap;gap:var(--fold-space-sm)}.page-actions:empty{display:none}@media(max-width:640px){.page-head{flex-direction:column;align-items:stretch;gap:var(--fold-space-md)}.page-actions{justify-content:flex-start}:host{padding-inline:calc(var(--fold-page-gutter, 32px) / 2)}}@container (max-width: 640px){.page-head{flex-direction:column;align-items:stretch;gap:var(--fold-space-md)}.page-actions{justify-content:flex-start}:host{padding-inline:calc(var(--fold-page-gutter, 32px) / 2)}}.page-body{display:flex;flex-direction:column;gap:var(--fold-page-gap, 32px)}\n"] }]
11587
11595
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], scroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "scroll", required: false }] }], customTitle: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FoldPageTitleDirective), { isSignal: true }] }] } });
11588
11596
 
11589
11597
  /**
@@ -12297,7 +12305,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
12297
12305
  * works in a router app and degrades to plain anchors without one (importing it
12298
12306
  * never forces `@angular/router` — `RouterLink` is only instantiated on a crumb
12299
12307
  * that actually sets `routerLink`). The last item renders as the current page
12300
- * (`aria-current="page"`), not a link. Chevron separators are decorative.
12308
+ * (`aria-current="page"`), not a link unless the trail names ancestors ONLY,
12309
+ * for which see {@link currentPage}. Chevron separators are decorative.
12301
12310
  *
12302
12311
  * ```html
12303
12312
  * <fold-breadcrumb
@@ -12318,16 +12327,32 @@ class FoldBreadcrumbComponent {
12318
12327
  /** Accessible name of the navigation landmark. @default 'Breadcrumb' */
12319
12328
  ariaLabel = input("Breadcrumb", /* @ts-ignore */
12320
12329
  ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
12330
+ /**
12331
+ * Does the last crumb stand for the **current page**?
12332
+ *
12333
+ * `true` (default) — the trail ends *on* the page you are reading: the last
12334
+ * crumb is emphasised, never a link, and carries `aria-current="page"`.
12335
+ *
12336
+ * `false` — the trail names the **ancestors only**, and the page's own `<h1>`
12337
+ * is the current page (the shape a breadcrumb takes when it sits above a
12338
+ * title, e.g. in `fold-page-layout`'s `[pageEyebrow]`). The last crumb then
12339
+ * behaves like any other: a link when it carries a target, plain text when it
12340
+ * does not, and no `aria-current` anywhere — because claiming a parent is the
12341
+ * current page tells a screen reader something untrue, and repeating the
12342
+ * heading as a final crumb is noise a sighted reader has to skip.
12343
+ */
12344
+ currentPage = input(true, /* @ts-ignore */
12345
+ ...(ngDevMode ? [{ debugName: "currentPage" }] : /* istanbul ignore next */ []));
12321
12346
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12322
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldBreadcrumbComponent, isStandalone: true, selector: "fold-breadcrumb", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "navigation" }, properties: { "attr.aria-label": "ariaLabel()" } }, ngImport: i0, template: "<ol class=\"bc-list\">\n @for (item of items(); track $index; let last = $last) {\n <li class=\"bc-item\">\n @if (last) {\n <span class=\"bc-node bc-current\" aria-current=\"page\">{{\n item.label\n }}</span>\n } @else if (item.routerLink !== undefined) {\n <a class=\"bc-node bc-link\" [routerLink]=\"item.routerLink\">{{\n item.label\n }}</a>\n } @else if (item.href !== undefined) {\n <a class=\"bc-node bc-link\" [href]=\"item.href\">{{ item.label }}</a>\n } @else {\n <span class=\"bc-node\">{{ item.label }}</span>\n }\n\n @if (!last) {\n <fold-icon\n class=\"bc-sep\"\n name=\"chevron-right\"\n size=\"sm\"\n aria-hidden=\"true\"\n />\n }\n </li>\n }\n</ol>\n", styles: ["@charset \"UTF-8\";:host{display:block}.bc-list{display:flex;flex-wrap:wrap;align-items:center;gap:.15rem;margin:0;padding:0;list-style:none;font-size:var(--fold-text-sm, .875rem)}.bc-item{display:inline-flex;align-items:center;gap:.15rem;min-width:0}.bc-node{padding:.15rem .3rem;border-radius:var(--fold-radius-sm, 8px);color:var(--fold-color-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bc-link{text-decoration:none;cursor:pointer;transition:color var(--fold-motion-fast)}.bc-link:hover{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}.bc-link:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:0}@media(prefers-reduced-motion:reduce){.bc-link{transition:none}}.bc-current{color:var(--fold-color-text);font-weight:var(--fold-weight-semibold)}.bc-sep{flex:none;color:var(--fold-color-text-faded)}@media(forced-colors:active){.bc-link:hover{background:Highlight;color:HighlightText}}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12347
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldBreadcrumbComponent, isStandalone: true, selector: "fold-breadcrumb", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, currentPage: { classPropertyName: "currentPage", publicName: "currentPage", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "navigation" }, properties: { "attr.aria-label": "ariaLabel()" } }, ngImport: i0, template: "<ol class=\"bc-list\">\n @for (item of items(); track $index; let last = $last) {\n <li class=\"bc-item\">\n @if (last && currentPage()) {\n <span class=\"bc-node bc-current\" aria-current=\"page\">{{\n item.label\n }}</span>\n } @else if (item.routerLink !== undefined) {\n <a class=\"bc-node bc-link\" [routerLink]=\"item.routerLink\">{{\n item.label\n }}</a>\n } @else if (item.href !== undefined) {\n <a class=\"bc-node bc-link\" [href]=\"item.href\">{{ item.label }}</a>\n } @else {\n <span class=\"bc-node\">{{ item.label }}</span>\n }\n\n @if (!last) {\n <fold-icon\n class=\"bc-sep\"\n name=\"chevron-right\"\n size=\"sm\"\n aria-hidden=\"true\"\n />\n }\n </li>\n }\n</ol>\n", styles: ["@charset \"UTF-8\";:host{display:block}.bc-list{display:flex;flex-wrap:wrap;align-items:center;gap:.15rem;margin:0;padding:0;list-style:none;font-size:var(--fold-text-sm, .875rem)}.bc-item{display:inline-flex;align-items:center;gap:.15rem;min-width:0}.bc-node{padding:.15rem .3rem;border-radius:var(--fold-radius-sm, 8px);color:var(--fold-color-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bc-link{text-decoration:none;cursor:pointer;transition:color var(--fold-motion-fast)}.bc-link:hover{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}.bc-link:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:0}@media(prefers-reduced-motion:reduce){.bc-link{transition:none}}.bc-current{color:var(--fold-color-text);font-weight:var(--fold-weight-semibold)}.bc-sep{flex:none;color:var(--fold-color-text-faded)}@media(forced-colors:active){.bc-link:hover{background:Highlight;color:HighlightText}}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12323
12348
  }
12324
12349
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldBreadcrumbComponent, decorators: [{
12325
12350
  type: Component,
12326
12351
  args: [{ selector: "fold-breadcrumb", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [RouterLink, FoldIconComponent], host: {
12327
12352
  role: "navigation",
12328
12353
  "[attr.aria-label]": "ariaLabel()",
12329
- }, template: "<ol class=\"bc-list\">\n @for (item of items(); track $index; let last = $last) {\n <li class=\"bc-item\">\n @if (last) {\n <span class=\"bc-node bc-current\" aria-current=\"page\">{{\n item.label\n }}</span>\n } @else if (item.routerLink !== undefined) {\n <a class=\"bc-node bc-link\" [routerLink]=\"item.routerLink\">{{\n item.label\n }}</a>\n } @else if (item.href !== undefined) {\n <a class=\"bc-node bc-link\" [href]=\"item.href\">{{ item.label }}</a>\n } @else {\n <span class=\"bc-node\">{{ item.label }}</span>\n }\n\n @if (!last) {\n <fold-icon\n class=\"bc-sep\"\n name=\"chevron-right\"\n size=\"sm\"\n aria-hidden=\"true\"\n />\n }\n </li>\n }\n</ol>\n", styles: ["@charset \"UTF-8\";:host{display:block}.bc-list{display:flex;flex-wrap:wrap;align-items:center;gap:.15rem;margin:0;padding:0;list-style:none;font-size:var(--fold-text-sm, .875rem)}.bc-item{display:inline-flex;align-items:center;gap:.15rem;min-width:0}.bc-node{padding:.15rem .3rem;border-radius:var(--fold-radius-sm, 8px);color:var(--fold-color-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bc-link{text-decoration:none;cursor:pointer;transition:color var(--fold-motion-fast)}.bc-link:hover{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}.bc-link:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:0}@media(prefers-reduced-motion:reduce){.bc-link{transition:none}}.bc-current{color:var(--fold-color-text);font-weight:var(--fold-weight-semibold)}.bc-sep{flex:none;color:var(--fold-color-text-faded)}@media(forced-colors:active){.bc-link:hover{background:Highlight;color:HighlightText}}\n"] }]
12330
- }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
12354
+ }, template: "<ol class=\"bc-list\">\n @for (item of items(); track $index; let last = $last) {\n <li class=\"bc-item\">\n @if (last && currentPage()) {\n <span class=\"bc-node bc-current\" aria-current=\"page\">{{\n item.label\n }}</span>\n } @else if (item.routerLink !== undefined) {\n <a class=\"bc-node bc-link\" [routerLink]=\"item.routerLink\">{{\n item.label\n }}</a>\n } @else if (item.href !== undefined) {\n <a class=\"bc-node bc-link\" [href]=\"item.href\">{{ item.label }}</a>\n } @else {\n <span class=\"bc-node\">{{ item.label }}</span>\n }\n\n @if (!last) {\n <fold-icon\n class=\"bc-sep\"\n name=\"chevron-right\"\n size=\"sm\"\n aria-hidden=\"true\"\n />\n }\n </li>\n }\n</ol>\n", styles: ["@charset \"UTF-8\";:host{display:block}.bc-list{display:flex;flex-wrap:wrap;align-items:center;gap:.15rem;margin:0;padding:0;list-style:none;font-size:var(--fold-text-sm, .875rem)}.bc-item{display:inline-flex;align-items:center;gap:.15rem;min-width:0}.bc-node{padding:.15rem .3rem;border-radius:var(--fold-radius-sm, 8px);color:var(--fold-color-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bc-link{text-decoration:none;cursor:pointer;transition:color var(--fold-motion-fast)}.bc-link:hover{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}.bc-link:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:0}@media(prefers-reduced-motion:reduce){.bc-link{transition:none}}.bc-current{color:var(--fold-color-text);font-weight:var(--fold-weight-semibold)}.bc-sep{flex:none;color:var(--fold-color-text-faded)}@media(forced-colors:active){.bc-link:hover{background:Highlight;color:HighlightText}}\n"] }]
12355
+ }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], currentPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentPage", required: false }] }] } });
12331
12356
 
12332
12357
  /**
12333
12358
  * `<fold-back-link>` — the “← Back” affordance for a detail page. Three modes,