fold-ng 0.10.2 → 0.11.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.
@@ -1133,7 +1133,10 @@ const UI_ICONS = {
1133
1133
  globe: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 3C6.5 3 2 9 2 12s4.5 9 10 9 10-6 10-9-4.5-9-10-9z"/><circle cx="12" cy="12" r="3"/></svg>',
1134
1134
  grid: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>',
1135
1135
  list: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M3 6h18M3 10h18M3 14h18M3 18h18"/></svg>',
1136
+ inbox: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 12 16 12 14 15 10 15 8 12 2 12"/><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/></svg>',
1136
1137
  lock: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>',
1138
+ hash: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="4" y1="9" x2="20" y2="9"/><line x1="4" y1="15" x2="20" y2="15"/><line x1="10" y1="3" x2="8" y2="21"/><line x1="16" y1="3" x2="14" y2="21"/></svg>',
1139
+ phone: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.9.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z"/></svg>',
1137
1140
  mail: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="m3 7 9 6 9-6"/></svg>',
1138
1141
  menu: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 7h16a1 1 0 0 0 0-2H4a1 1 0 0 0 0 2zm16 4H4a1 1 0 0 0 0 2h16a1 1 0 0 0 0-2zm0 6H4a1 1 0 0 0 0 2h16a1 1 0 0 0 0-2z"/></svg>',
1139
1142
  "more-vertical": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="5" r="1.8"/><circle cx="12" cy="12" r="1.8"/><circle cx="12" cy="19" r="1.8"/></svg>',
@@ -1164,6 +1167,7 @@ const NAV_ICONS = {
1164
1167
  contracts: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><rect x="2.5" y="2.5" width="12" height="17" rx="2"/><path d="M5.5 6.5h3M5.5 9.5h5.5M5.5 12.5h5.5"/><path d="M5.5 15.8l1.6 1.6 3-3.4"/><path d="M12 20.5 14.59 19.16 21.28 8.29 18.72 6.71 12.03 17.58Z"/><path d="M12.03 17.58 14.59 19.16M17.94 7.99 20.49 9.56"/></svg>',
1165
1168
  help: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>',
1166
1169
  home: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M3 11l9-8 9 8v10a1 1 0 0 1-1 1h-5v-7H9v7H4a1 1 0 0 1-1-1z"/></svg>',
1170
+ login: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g transform="translate(24,0) scale(-1,1)"><path d="M24,1.5V22.5c0,.83-.67,1.5-1.5,1.5s-1.5-.67-1.5-1.5V1.5c0-.83,.67-1.5,1.5-1.5s1.5,.67,1.5,1.5Zm-6.5,9H4.25l3.33-3.46c.57-.6,.56-1.55-.04-2.12-.6-.58-1.55-.56-2.12,.04L1.03,9.52c-.66,.66-1.03,1.54-1.03,2.48s.36,1.81,1.01,2.45l4.41,4.59c.29,.31,.69,.46,1.08,.46s.75-.14,1.04-.42c.6-.57,.62-1.52,.04-2.12l-3.33-3.46h13.25c.83,0,1.5-.67,1.5-1.5s-.67-1.5-1.5-1.5Z"/></g></svg>',
1167
1171
  logout: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M24,1.5V22.5c0,.83-.67,1.5-1.5,1.5s-1.5-.67-1.5-1.5V1.5c0-.83,.67-1.5,1.5-1.5s1.5,.67,1.5,1.5Zm-6.5,9H4.25l3.33-3.46c.57-.6,.56-1.55-.04-2.12-.6-.58-1.55-.56-2.12,.04L1.03,9.52c-.66,.66-1.03,1.54-1.03,2.48s.36,1.81,1.01,2.45l4.41,4.59c.29,.31,.69,.46,1.08,.46s.75-.14,1.04-.42c.6-.57,.62-1.52,.04-2.12l-3.33-3.46h13.25c.83,0,1.5-.67,1.5-1.5s-.67-1.5-1.5-1.5Z"/></svg>',
1168
1172
  music: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="M9 17V5l10-2v12"/><circle cx="7" cy="17" r="2.5"/><circle cx="17" cy="15" r="2.5"/></svg>',
1169
1173
  "org-chart": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M22 11V3h-7v3H9V3H2v8h7V8h2v10h4v3h7v-8h-7v3h-2V8h2v3h7zM7 9H4V5h3v4zm10 6h3v4h-3v-4zm0-10v4h3V5h-3z"/></svg>',
@@ -1240,6 +1244,7 @@ const MUSIC_ICONS = {
1240
1244
  // package ships self-contained. Single-colour SVGs using `currentColor`, so
1241
1245
  // each icon inherits `color` from its host. Hand-maintained; keys are kebab-case.
1242
1246
  const STATUS_ICONS = {
1247
+ alert: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="7" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>',
1243
1248
  award: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m23.664,0h-8.475l-2.97,6.003c-.073-.002-.146-.003-.22-.003-.076,0-.152,0-.228.003L8.811,0H.324l4.637,9.399c-1.227,1.538-1.961,3.486-1.961,5.601,0,4.962,4.038,9,9,9s9-4.038,9-9c0-2.121-.738-4.072-1.97-5.612L23.664,0Zm-7.854,1h6.243l-3.751,7.582c-1.334-1.311-3.074-2.209-5.011-2.489l2.52-5.093ZM1.933,1h6.256l2.513,5.094c-1.943.282-3.686,1.186-5.021,2.504L1.933,1Zm18.067,14c0,4.411-3.589,8-8,8s-8-3.589-8-8S7.589,7,12,7s8,3.589,8,8Zm-7.244-5.135h-1.494l-.897,3.135h-3.365v1.453l2.318,1.336-1.081,2.955,1.158.86,2.614-2.074,2.609,2.093,1.205-.831-1.171-2.969,2.347-1.377v-1.445h-3.347l-.896-3.135Zm.652,5.528l1.14,2.892-2.536-2.034-2.535,2.011,1.067-2.919-2.328-1.343h2.902l.89-3.11.89,3.11h2.884l-2.375,1.393Z"/></svg>',
1244
1249
  clock: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12,24C5.383,24,0,18.617,0,12S5.383,0,12,0s12,5.383,12,12-5.383,12-12,12ZM12,1C5.935,1,1,5.935,1,12s4.935,11,11,11,11-4.935,11-11S18.065,1,12,1Zm5,11.5c0-.276-.224-.5-.5-.5h-4.5V5.5c0-.276-.224-.5-.5-.5s-.5,.224-.5,.5v7c0,.276,.224,.5,.5,.5h5c.276,0,.5-.224,.5-.5Z"/></svg>',
1245
1250
  completed: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m13,11h4v1h-4v-1ZM21,2v19.5c0,1.378-1.121,2.5-2.5,2.5H5.5c-1.379,0-2.5-1.122-2.5-2.5V2h5.05c.232-1.14,1.243-2,2.45-2h3c1.207,0,2.218.86,2.45,2h5.05Zm-1,1h-5v-.5c0-.827-.673-1.5-1.5-1.5h-3c-.827,0-1.5.673-1.5,1.5v.5h-5v18.5c0,.827.673,1.5,1.5,1.5h13c.827,0,1.5-.673,1.5-1.5V3Zm-11.216,7.952c-.056.056-.18.055-.241-.006l-1.778-1.721-.695.719,1.772,1.716c.221.22.514.341.825.341s.604-.122.821-.339l3.362-3.305-.701-.713-3.365,3.308Zm4.216,7.048h4v-1h-4v1Zm-4.216-1.048c-.056.057-.18.055-.241-.006l-1.778-1.721-.695.719,1.772,1.716c.221.22.514.341.825.341s.604-.122.821-.339l3.362-3.305-.701-.713-3.365,3.308Z"/></svg>',
@@ -1313,14 +1318,23 @@ const FOLD_BUILTIN_ICONS = {
1313
1318
  * built-in category, so tooling buckets them separately.
1314
1319
  */
1315
1320
  const FOLD_BUILTIN_ICON_CATEGORIES = [
1316
- { id: "ui", label: "UI", names: Object.keys(UI_ICONS) },
1317
- { id: "nav", label: "Navigation", names: Object.keys(NAV_ICONS) },
1318
- { id: "commerce", label: "Commerce", names: Object.keys(COMMERCE_ICONS) },
1319
- { id: "music", label: "Music", names: Object.keys(MUSIC_ICONS) },
1320
- { id: "status", label: "Status", names: Object.keys(STATUS_ICONS) },
1321
- { id: "people", label: "People", names: Object.keys(PEOPLE_ICONS) },
1322
- { id: "brands", label: "Brands", names: Object.keys(BRANDS_ICONS) },
1321
+ { id: "ui", label: "UI", names: namesOf(UI_ICONS) },
1322
+ { id: "nav", label: "Navigation", names: namesOf(NAV_ICONS) },
1323
+ { id: "commerce", label: "Commerce", names: namesOf(COMMERCE_ICONS) },
1324
+ { id: "music", label: "Music", names: namesOf(MUSIC_ICONS) },
1325
+ { id: "status", label: "Status", names: namesOf(STATUS_ICONS) },
1326
+ { id: "people", label: "People", names: namesOf(PEOPLE_ICONS) },
1327
+ { id: "brands", label: "Brands", names: namesOf(BRANDS_ICONS) },
1323
1328
  ];
1329
+ /**
1330
+ * The keys of an icon slice, keeping their literal type. `Object.keys` only ever
1331
+ * promises `string`, so the narrowing goes through a **checked predicate** — no
1332
+ * assertion (rule 2.1), and every name kept is genuinely a key of the object.
1333
+ */
1334
+ function namesOf(icons) {
1335
+ const known = (name) => name in icons;
1336
+ return Object.keys(icons).filter(known);
1337
+ }
1324
1338
 
1325
1339
  /**
1326
1340
  * The trust contract for icon markup.
@@ -1414,9 +1428,16 @@ class FoldIconRegistry {
1414
1428
  }
1415
1429
  /** Every registered icon name (built-ins + runtime additions), sorted.
1416
1430
  * Reactive — recomputes when an icon is registered. Powers tooling that
1417
- * browses the live catalogue (e.g. the `fold-icon-devtool`). */
1431
+ * browses the live catalogue (e.g. the `fold-icon-devtool`).
1432
+ *
1433
+ * Typed as {@link FoldIconName}, so a browser of the catalogue can hand each
1434
+ * name straight back to `fold-icon`. `Object.keys` only ever promises
1435
+ * `string`, so the narrowing goes through a **checked predicate** rather than
1436
+ * an assertion (rule 2.1): every name kept is one the registry resolves. */
1418
1437
  names() {
1419
- return Object.keys(this._icons()).sort();
1438
+ const icons = this._icons();
1439
+ const registered = (name) => name in icons;
1440
+ return Object.keys(icons).filter(registered).sort();
1420
1441
  }
1421
1442
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldIconRegistry, deps: [], target: i0.ɵɵFactoryTarget.Service });
1422
1443
  static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.8", ngImport: i0, type: FoldIconRegistry });
@@ -2053,6 +2074,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
2053
2074
  }, template: "<button\n [type]=\"type()\"\n [disabled]=\"disabled() || loading()\"\n [attr.title]=\"tooltip() || null\"\n [attr.aria-label]=\"tooltip() || null\"\n [attr.aria-busy]=\"loading() ? 'true' : null\"\n (click)=\"onClick($event)\"\n>\n @if (loading()) {\n <fold-spinner [size]=\"iconSize()\" aria-hidden=\"true\" />\n } @else {\n <fold-icon [name]=\"icon()\" [size]=\"iconSize()\" />\n }\n</button>\n", styles: [":host{display:inline-flex}:host[data-size=xs]{--bi-size: 22px;--bi-radius: var(--fold-radius-xs)}:host[data-size=sm]{--bi-size: 28px;--bi-radius: var(--fold-radius-sm)}:host[data-size=md]{--bi-size: 32px;--bi-radius: var(--fold-radius-md)}:host[data-size=lg]{--bi-size: 38px;--bi-radius: var(--fold-radius-md)}:host[data-shape=round]{--bi-radius: 50%}:host[data-tone=ghost]{--bi-color: var(--fold-color-text-muted);--bi-color-hover: var(--fold-color-text);--bi-bg: transparent;--bi-bg-hover: var(--fold-color-primary-surface);--bi-bg-active: var(--fold-color-primary-surface);--bi-color-active: var(--fold-color-primary)}:host[data-tone=accent]{--bi-color: var(--fold-color-on-primary);--bi-color-hover: var(--fold-color-on-primary);--bi-bg: var(--fold-color-primary);--bi-bg-hover: var(--fold-color-primary-strong);--bi-bg-active: var(--fold-color-primary-strong);--bi-color-active: var(--fold-color-on-primary)}:host[data-tone=critical]{--bi-color: var(--fold-color-alert);--bi-color-hover: var(--fold-color-alert);--bi-bg: transparent;--bi-bg-hover: color-mix(in srgb, var(--fold-color-alert) 12%, transparent);--bi-bg-active: color-mix( in srgb, var(--fold-color-alert) 18%, transparent );--bi-color-active: var(--fold-color-alert)}button{all:unset;display:inline-flex;align-items:center;justify-content:center;width:var(--bi-size);height:var(--bi-size);border-radius:var(--bi-radius);background:var(--bi-bg);color:var(--bi-color);cursor:pointer;flex-shrink:0;transition:background var(--fold-motion-fast),color var(--fold-motion-fast),transform var(--fold-motion-fast)}button:hover:not(:disabled){background:var(--bi-bg-hover);color:var(--bi-color-hover)}button:active:not(:disabled){transform:scale(.94)}button:focus-visible{outline:2px solid var(--fold-color-primary);outline-offset:1px}button:disabled{cursor:not-allowed;opacity:.4}:host([data-loading]) button:disabled{opacity:1;cursor:progress}@media(forced-colors:active){button{border:1px solid ButtonText}button:focus-visible{outline-color:CanvasText}button:disabled{color:GrayText;border-color:GrayText}}@media(prefers-reduced-motion:reduce){button{transition:none}button:active:not(:disabled){transform:none}}\n"] }]
2054
2075
  }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: true }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], tooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltip", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
2055
2076
 
2077
+ /** The English defaults — the base every override merges onto. */
2078
+ const FOLD_COMMON_DEFAULT_LABELS = {
2079
+ optional: "optional",
2080
+ info: "More information",
2081
+ clear: "Clear",
2082
+ loading: "Loading...",
2083
+ };
2084
+ /** App-wide shared labels; defaults to English. */
2085
+ const FOLD_COMMON_LABELS = new InjectionToken("FOLD_COMMON_LABELS", { factory: () => FOLD_COMMON_DEFAULT_LABELS });
2086
+ /**
2087
+ * Provide the package's shared labels once at bootstrap. Partial — any key you
2088
+ * omit keeps its English default.
2089
+ *
2090
+ * @example
2091
+ * ```ts
2092
+ * // app.config.ts
2093
+ * providers: [
2094
+ * provideFoldCommonLabels({
2095
+ * optional: "facultatif",
2096
+ * info: "En savoir plus",
2097
+ * clear: "Effacer",
2098
+ * loading: "Chargement…",
2099
+ * }),
2100
+ * ];
2101
+ * ```
2102
+ */
2103
+ function provideFoldCommonLabels(labels) {
2104
+ return {
2105
+ provide: FOLD_COMMON_LABELS,
2106
+ useValue: { ...FOLD_COMMON_DEFAULT_LABELS, ...labels },
2107
+ };
2108
+ }
2109
+
2056
2110
  /**
2057
2111
  * Zero-dependency placement math for {@link FoldPopoverComponent}. Pure and
2058
2112
  * framework-free so it unit-tests without a DOM: give it the anchor rect, the
@@ -2586,8 +2640,8 @@ class FoldInfoComponent {
2586
2640
  * when several sit on the same screen.
2587
2641
  * @default 'More information'
2588
2642
  */
2589
- label = input("More information", /* @ts-ignore */
2590
- ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
2643
+ label = input(/* @ts-ignore */
2644
+ ...(ngDevMode ? [undefined, { debugName: "label" }] : /* istanbul ignore next */ []));
2591
2645
  /**
2592
2646
  * Where the panel opens. `bottom-end` by default because the trigger usually
2593
2647
  * sits at the **end** of a label line or a card header, where a panel growing
@@ -2595,12 +2649,16 @@ class FoldInfoComponent {
2595
2649
  */
2596
2650
  placement = input("bottom-end", /* @ts-ignore */
2597
2651
  ...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
2652
+ common = inject(FOLD_COMMON_LABELS);
2653
+ /** English default ← app-wide provider ← this instance's own input. */
2654
+ triggerLabel = computed(() => this.label() ?? this.common.info, /* @ts-ignore */
2655
+ ...(ngDevMode ? [{ debugName: "triggerLabel" }] : /* istanbul ignore next */ []));
2598
2656
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldInfoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2599
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: FoldInfoComponent, isStandalone: true, selector: "fold-info", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<fold-popover [placement]=\"placement()\" arrow>\n <button\n foldPopoverTrigger\n type=\"button\"\n class=\"fi-trigger\"\n [attr.aria-label]=\"label()\"\n >\n <span aria-hidden=\"true\">i</span>\n </button>\n <div foldPopoverPanel class=\"fi-panel\">{{ text() }}</div>\n</fold-popover>\n", styles: [":host{display:inline-flex;flex:0 0 auto}.fi-trigger{display:inline-flex;align-items:center;justify-content:center;width:1.125rem;height:1.125rem;padding:0;border:1px solid var(--fold-color-border);border-radius:50%;background:transparent;color:var(--fold-color-text-muted);font:inherit;font-size:.6875rem;font-style:italic;font-weight:700;line-height:1;cursor:help;transition:border-color var(--fold-motion-fast, .12s) ease,color var(--fold-motion-fast, .12s) ease}.fi-trigger:hover,.fi-trigger:focus-visible{border-color:var(--fold-color-primary);color:var(--fold-color-primary)}.fi-panel{max-width:17rem;padding:var(--fold-space-sm) var(--fold-space-md);font-size:var(--fold-text-xs);font-weight:400;line-height:1.45;text-align:start;white-space:normal}@media(forced-colors:active){.fi-trigger{border-color:ButtonText;color:ButtonText}.fi-trigger:hover,.fi-trigger:focus-visible{border-color:Highlight;color:Highlight}}\n"], dependencies: [{ kind: "component", type: FoldPopoverComponent, selector: "fold-popover", inputs: ["placement", "fallbackPlacements", "offset", "padding", "autoFocus", "arrow", "open", "ariaControls"], outputs: ["openChange"] }, { kind: "directive", type: FoldPopoverTriggerDirective, selector: "[foldPopoverTrigger]", inputs: ["foldPopoverTrigger"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2657
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: FoldInfoComponent, isStandalone: true, selector: "fold-info", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<fold-popover [placement]=\"placement()\" arrow>\n <button\n foldPopoverTrigger\n type=\"button\"\n class=\"fi-trigger\"\n [attr.aria-label]=\"triggerLabel()\"\n >\n <span aria-hidden=\"true\">i</span>\n </button>\n <div foldPopoverPanel class=\"fi-panel\">{{ text() }}</div>\n</fold-popover>\n", styles: [":host{display:inline-flex;flex:0 0 auto}.fi-trigger{display:inline-flex;align-items:center;justify-content:center;width:1.125rem;height:1.125rem;padding:0;border:1px solid var(--fold-color-border);border-radius:50%;background:transparent;color:var(--fold-color-text-muted);font:inherit;font-size:.6875rem;font-style:italic;font-weight:700;line-height:1;cursor:help;transition:border-color var(--fold-motion-fast, .12s) ease,color var(--fold-motion-fast, .12s) ease}.fi-trigger:hover,.fi-trigger:focus-visible{border-color:var(--fold-color-primary);color:var(--fold-color-primary)}.fi-panel{max-width:17rem;padding:var(--fold-space-sm) var(--fold-space-md);font-size:var(--fold-text-xs);font-weight:400;line-height:1.45;text-align:start;white-space:normal}@media(forced-colors:active){.fi-trigger{border-color:ButtonText;color:ButtonText}.fi-trigger:hover,.fi-trigger:focus-visible{border-color:Highlight;color:Highlight}}\n"], dependencies: [{ kind: "component", type: FoldPopoverComponent, selector: "fold-popover", inputs: ["placement", "fallbackPlacements", "offset", "padding", "autoFocus", "arrow", "open", "ariaControls"], outputs: ["openChange"] }, { kind: "directive", type: FoldPopoverTriggerDirective, selector: "[foldPopoverTrigger]", inputs: ["foldPopoverTrigger"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2600
2658
  }
2601
2659
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldInfoComponent, decorators: [{
2602
2660
  type: Component,
2603
- args: [{ selector: "fold-info", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [FoldPopoverComponent, FoldPopoverTriggerDirective], template: "<fold-popover [placement]=\"placement()\" arrow>\n <button\n foldPopoverTrigger\n type=\"button\"\n class=\"fi-trigger\"\n [attr.aria-label]=\"label()\"\n >\n <span aria-hidden=\"true\">i</span>\n </button>\n <div foldPopoverPanel class=\"fi-panel\">{{ text() }}</div>\n</fold-popover>\n", styles: [":host{display:inline-flex;flex:0 0 auto}.fi-trigger{display:inline-flex;align-items:center;justify-content:center;width:1.125rem;height:1.125rem;padding:0;border:1px solid var(--fold-color-border);border-radius:50%;background:transparent;color:var(--fold-color-text-muted);font:inherit;font-size:.6875rem;font-style:italic;font-weight:700;line-height:1;cursor:help;transition:border-color var(--fold-motion-fast, .12s) ease,color var(--fold-motion-fast, .12s) ease}.fi-trigger:hover,.fi-trigger:focus-visible{border-color:var(--fold-color-primary);color:var(--fold-color-primary)}.fi-panel{max-width:17rem;padding:var(--fold-space-sm) var(--fold-space-md);font-size:var(--fold-text-xs);font-weight:400;line-height:1.45;text-align:start;white-space:normal}@media(forced-colors:active){.fi-trigger{border-color:ButtonText;color:ButtonText}.fi-trigger:hover,.fi-trigger:focus-visible{border-color:Highlight;color:Highlight}}\n"] }]
2661
+ args: [{ selector: "fold-info", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [FoldPopoverComponent, FoldPopoverTriggerDirective], template: "<fold-popover [placement]=\"placement()\" arrow>\n <button\n foldPopoverTrigger\n type=\"button\"\n class=\"fi-trigger\"\n [attr.aria-label]=\"triggerLabel()\"\n >\n <span aria-hidden=\"true\">i</span>\n </button>\n <div foldPopoverPanel class=\"fi-panel\">{{ text() }}</div>\n</fold-popover>\n", styles: [":host{display:inline-flex;flex:0 0 auto}.fi-trigger{display:inline-flex;align-items:center;justify-content:center;width:1.125rem;height:1.125rem;padding:0;border:1px solid var(--fold-color-border);border-radius:50%;background:transparent;color:var(--fold-color-text-muted);font:inherit;font-size:.6875rem;font-style:italic;font-weight:700;line-height:1;cursor:help;transition:border-color var(--fold-motion-fast, .12s) ease,color var(--fold-motion-fast, .12s) ease}.fi-trigger:hover,.fi-trigger:focus-visible{border-color:var(--fold-color-primary);color:var(--fold-color-primary)}.fi-panel{max-width:17rem;padding:var(--fold-space-sm) var(--fold-space-md);font-size:var(--fold-text-xs);font-weight:400;line-height:1.45;text-align:start;white-space:normal}@media(forced-colors:active){.fi-trigger{border-color:ButtonText;color:ButtonText}.fi-trigger:hover,.fi-trigger:focus-visible{border-color:Highlight;color:Highlight}}\n"] }]
2604
2662
  }], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }] } });
2605
2663
 
2606
2664
  /**
@@ -2624,15 +2682,19 @@ class FoldLabelComponent {
2624
2682
  /** Show a lighter, parenthesised optional marker after the label. */
2625
2683
  optional = input(false, { ...(ngDevMode ? { debugName: "optional" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2626
2684
  /** The word inside the optional marker's parentheses. @default 'optional' */
2627
- optionalLabel = input("optional", /* @ts-ignore */
2628
- ...(ngDevMode ? [{ debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
2685
+ optionalLabel = input(/* @ts-ignore */
2686
+ ...(ngDevMode ? [undefined, { debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
2687
+ common = inject(FOLD_COMMON_LABELS);
2688
+ /** English default ← app-wide provider ← this instance's own input. */
2689
+ optionalWord = computed(() => this.optionalLabel() ?? this.common.optional, /* @ts-ignore */
2690
+ ...(ngDevMode ? [{ debugName: "optionalWord" }] : /* istanbul ignore next */ []));
2629
2691
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2630
2692
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldLabelComponent, isStandalone: true, selector: "fold-label", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, for: { classPropertyName: "for", publicName: "for", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, optional: { classPropertyName: "optional", publicName: "optional", isSignal: true, isRequired: false, transformFunction: null }, optionalLabel: { classPropertyName: "optionalLabel", publicName: "optionalLabel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `<label [attr.for]="for()"
2631
2693
  >{{ text() }}
2632
2694
  @if (required()) {
2633
2695
  <span class="req" aria-hidden="true">*</span>
2634
2696
  } @else if (optional()) {
2635
- <span class="opt">({{ optionalLabel() }})</span>
2697
+ <span class="opt">({{ optionalWord() }})</span>
2636
2698
  }
2637
2699
  </label>`, isInline: true, styles: [":host{display:block}label{font-size:var(--fold-text-xs);font-weight:600;color:var(--fold-color-text-secondary)}.req{color:var(--fold-color-alert-text);margin-left:2px}.opt{margin-left:var(--fold-space-xs);font-weight:500;color:var(--fold-color-text-faded)}\n"] });
2638
2700
  }
@@ -2643,7 +2705,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
2643
2705
  @if (required()) {
2644
2706
  <span class="req" aria-hidden="true">*</span>
2645
2707
  } @else if (optional()) {
2646
- <span class="opt">({{ optionalLabel() }})</span>
2708
+ <span class="opt">({{ optionalWord() }})</span>
2647
2709
  }
2648
2710
  </label>`, styles: [":host{display:block}label{font-size:var(--fold-text-xs);font-weight:600;color:var(--fold-color-text-secondary)}.req{color:var(--fold-color-alert-text);margin-left:2px}.opt{margin-left:var(--fold-space-xs);font-weight:500;color:var(--fold-color-text-faded)}\n"] }]
2649
2711
  }], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: true }] }], for: [{ type: i0.Input, args: [{ isSignal: true, alias: "for", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], optional: [{ type: i0.Input, args: [{ isSignal: true, alias: "optional", required: false }] }], optionalLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionalLabel", required: false }] }] } });
@@ -2683,8 +2745,8 @@ class FoldInputBaseComponent {
2683
2745
  /** Show a lighter `(optional)` marker on the label (ignored when required). */
2684
2746
  optional = input(false, { ...(ngDevMode ? { debugName: "optional" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2685
2747
  /** The word inside the optional marker. @default 'optional' */
2686
- optionalLabel = input("optional", /* @ts-ignore */
2687
- ...(ngDevMode ? [{ debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
2748
+ optionalLabel = input(/* @ts-ignore */
2749
+ ...(ngDevMode ? [undefined, { debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
2688
2750
  /** Helper text shown under the control. */
2689
2751
  hint = input(/* @ts-ignore */
2690
2752
  ...(ngDevMode ? [undefined, { debugName: "hint" }] : /* istanbul ignore next */ []));
@@ -2699,8 +2761,8 @@ class FoldInputBaseComponent {
2699
2761
  info = input(/* @ts-ignore */
2700
2762
  ...(ngDevMode ? [undefined, { debugName: "info" }] : /* istanbul ignore next */ []));
2701
2763
  /** Accessible name of the info button. @default 'More information' */
2702
- infoLabel = input("More information", /* @ts-ignore */
2703
- ...(ngDevMode ? [{ debugName: "infoLabel" }] : /* istanbul ignore next */ []));
2764
+ infoLabel = input(/* @ts-ignore */
2765
+ ...(ngDevMode ? [undefined, { debugName: "infoLabel" }] : /* istanbul ignore next */ []));
2704
2766
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldInputBaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2705
2767
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldInputBaseComponent, isStandalone: true, selector: "fold-input-base", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, for: { classPropertyName: "for", publicName: "for", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, optional: { classPropertyName: "optional", publicName: "optional", isSignal: true, isRequired: false, transformFunction: null }, optionalLabel: { classPropertyName: "optionalLabel", publicName: "optionalLabel", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, info: { classPropertyName: "info", publicName: "info", isSignal: true, isRequired: false, transformFunction: null }, infoLabel: { classPropertyName: "infoLabel", publicName: "infoLabel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (label(); as labelText) {\n <div class=\"ib-label-row\">\n <fold-label\n [text]=\"labelText\"\n [for]=\"for()\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n />\n @if (info(); as infoText) {\n <fold-info [text]=\"infoText\" [label]=\"infoLabel()\" />\n }\n </div>\n}\n\n<ng-content />\n\n@if (error(); as errorText) {\n <p\n class=\"ib-msg ib-error\"\n role=\"alert\"\n [attr.id]=\"for() ? for() + '-error' : null\"\n >\n {{ errorText }}\n </p>\n} @else if (hint(); as hintText) {\n <p class=\"ib-msg ib-hint\" [attr.id]=\"for() ? for() + '-hint' : null\">\n {{ hintText }}\n </p>\n}\n", styles: [":host{display:flex;flex-direction:column;gap:var(--fold-space-xs);min-width:0}.ib-msg{margin:0;font-size:var(--fold-text-xs)}.ib-hint{color:var(--fold-color-text-muted)}.ib-error{color:var(--fold-color-alert-text)}.ib-label-row{display:flex;align-items:center;justify-content:space-between;gap:var(--fold-space-xs);min-width:0}\n"], dependencies: [{ kind: "component", type: FoldLabelComponent, selector: "fold-label", inputs: ["text", "for", "required", "optional", "optionalLabel"] }, { kind: "component", type: FoldInfoComponent, selector: "fold-info", inputs: ["text", "label", "placement"] }] });
2706
2768
  }
@@ -2817,8 +2879,8 @@ class FoldInputComponent {
2817
2879
  /** Show a lighter `(optional)` marker on the label (ignored when required). */
2818
2880
  optional = input(false, { ...(ngDevMode ? { debugName: "optional" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2819
2881
  /** The word inside the optional marker. @default 'optional' */
2820
- optionalLabel = input("optional", /* @ts-ignore */
2821
- ...(ngDevMode ? [{ debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
2882
+ optionalLabel = input(/* @ts-ignore */
2883
+ ...(ngDevMode ? [undefined, { debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
2822
2884
  /**
2823
2885
  * Longer explanation behind an `i` at the end of the label line — for the
2824
2886
  * sentence or two a {@link hint} can't carry. Forwarded to `fold-input-base`.
@@ -2826,8 +2888,20 @@ class FoldInputComponent {
2826
2888
  info = input(/* @ts-ignore */
2827
2889
  ...(ngDevMode ? [undefined, { debugName: "info" }] : /* istanbul ignore next */ []));
2828
2890
  /** Accessible name of the info button. @default 'More information' */
2829
- infoLabel = input("More information", /* @ts-ignore */
2830
- ...(ngDevMode ? [{ debugName: "infoLabel" }] : /* istanbul ignore next */ []));
2891
+ infoLabel = input(/* @ts-ignore */
2892
+ ...(ngDevMode ? [undefined, { debugName: "infoLabel" }] : /* istanbul ignore next */ []));
2893
+ /**
2894
+ * Accessible name for the control itself, when there is **no visible
2895
+ * `label`** — a filter in a toolbar, a control whose meaning the surrounding
2896
+ * text already carries. Without it such a control reaches assistive tech named
2897
+ * only by its current value ("Week"), which says nothing about what it sets.
2898
+ *
2899
+ * Prefer a visible `label`: it names the control for *everyone*. Set this only
2900
+ * where the design genuinely has no room — and never both, since `aria-label`
2901
+ * would override the visible one and leave the two out of sync.
2902
+ */
2903
+ ariaLabel = input(undefined, /* @ts-ignore */
2904
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
2831
2905
  /** Optional helper text shown under the input. */
2832
2906
  hint = input(/* @ts-ignore */
2833
2907
  ...(ngDevMode ? [undefined, { debugName: "hint" }] : /* istanbul ignore next */ []));
@@ -2900,14 +2974,14 @@ class FoldInputComponent {
2900
2974
  this.touched.set(true);
2901
2975
  }
2902
2976
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2903
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldInputComponent, isStandalone: true, selector: "fold-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, revealable: { classPropertyName: "revealable", publicName: "revealable", isSignal: true, isRequired: false, transformFunction: null }, revealLabel: { classPropertyName: "revealLabel", publicName: "revealLabel", isSignal: true, isRequired: false, transformFunction: null }, hideLabel: { classPropertyName: "hideLabel", publicName: "hideLabel", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, optional: { classPropertyName: "optional", publicName: "optional", isSignal: true, isRequired: false, transformFunction: null }, optionalLabel: { classPropertyName: "optionalLabel", publicName: "optionalLabel", isSignal: true, isRequired: false, transformFunction: null }, info: { classPropertyName: "info", publicName: "info", isSignal: true, isRequired: false, transformFunction: null }, infoLabel: { classPropertyName: "infoLabel", publicName: "infoLabel", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null }, autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange" }, host: { properties: { "class": "size() + \" \" + align() + \" \" + variant()" } }, ngImport: i0, template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <div class=\"in-field\">\n <input\n [id]=\"inputId\"\n [class.has-reveal]=\"showReveal()\"\n [attr.type]=\"effectiveType()\"\n [attr.placeholder]=\"placeholder()\"\n [attr.readonly]=\"readOnly() || null\"\n [attr.disabled]=\"disabled() || null\"\n [attr.required]=\"required() || null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.autocomplete]=\"autocomplete()\"\n [value]=\"value()\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n />\n @if (showReveal()) {\n <button\n type=\"button\"\n class=\"in-reveal\"\n [attr.aria-label]=\"revealAria()\"\n [attr.aria-pressed]=\"revealed()\"\n [disabled]=\"disabled() || readOnly()\"\n (click)=\"toggleReveal()\"\n >\n <fold-icon\n [name]=\"revealed() ? 'eye-off' : 'eye'\"\n size=\"sm\"\n aria-hidden=\"true\"\n />\n </button>\n }\n </div>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}input,select,textarea{all:unset;box-sizing:border-box;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}input::placeholder,select::placeholder,textarea::placeholder{color:var(--fold-color-text-faded)}input:hover:not(:disabled):not(:read-only):not(:focus),select:hover:not(:disabled):not(:read-only):not(:focus),textarea:hover:not(:disabled):not(:read-only):not(:focus){border-color:var(--fold-color-border)}input:focus,select:focus,textarea:focus{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}input:disabled,select:disabled,textarea:disabled{opacity:.4;cursor:not-allowed}input:read-only,select:read-only,textarea:read-only{opacity:.6;cursor:default}input[type=number],select[type=number],textarea[type=number]{appearance:textfield;-moz-appearance:textfield}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button,select[type=number]::-webkit-inner-spin-button,select[type=number]::-webkit-outer-spin-button,textarea[type=number]::-webkit-inner-spin-button,textarea[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}:host(.sm) input,:host(.sm) select{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.sm) textarea{font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) input,:host(.md) select{height:2.25rem;font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.md) textarea{font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) input,:host(.lg) select{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.lg) textarea{font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.center) input{text-align:center}:host(.panel) input,:host(.panel) select,:host(.panel) textarea{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) input:focus,:host(.panel) select:focus,:host(.panel) textarea:focus{box-shadow:none}.in-field{position:relative}:host input.has-reveal{padding-inline-end:2.1rem}.in-reveal{all:unset;position:absolute;inset-inline-end:.4rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;padding:.2rem;border-radius:var(--fold-radius-xs);color:var(--fold-color-text-muted);cursor:pointer}.in-reveal:hover:not(:disabled),.in-reveal:focus-visible{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}.in-reveal:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:1px}.in-reveal:disabled{cursor:not-allowed;opacity:.4}@media(forced-colors:active){.in-reveal:focus-visible{outline-color:Highlight}}\n"], dependencies: [{ kind: "component", type: FoldInputBaseComponent, selector: "fold-input-base", inputs: ["label", "for", "required", "optional", "optionalLabel", "hint", "error", "info", "infoLabel"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
2977
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldInputComponent, isStandalone: true, selector: "fold-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, revealable: { classPropertyName: "revealable", publicName: "revealable", isSignal: true, isRequired: false, transformFunction: null }, revealLabel: { classPropertyName: "revealLabel", publicName: "revealLabel", isSignal: true, isRequired: false, transformFunction: null }, hideLabel: { classPropertyName: "hideLabel", publicName: "hideLabel", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, optional: { classPropertyName: "optional", publicName: "optional", isSignal: true, isRequired: false, transformFunction: null }, optionalLabel: { classPropertyName: "optionalLabel", publicName: "optionalLabel", isSignal: true, isRequired: false, transformFunction: null }, info: { classPropertyName: "info", publicName: "info", isSignal: true, isRequired: false, transformFunction: null }, infoLabel: { classPropertyName: "infoLabel", publicName: "infoLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null }, autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange" }, host: { properties: { "class": "size() + \" \" + align() + \" \" + variant()" } }, ngImport: i0, template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <div class=\"in-field\">\n <input\n [id]=\"inputId\"\n [class.has-reveal]=\"showReveal()\"\n [attr.type]=\"effectiveType()\"\n [attr.placeholder]=\"placeholder()\"\n [attr.readonly]=\"readOnly() || null\"\n [attr.disabled]=\"disabled() || null\"\n [attr.required]=\"required() || null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.autocomplete]=\"autocomplete()\"\n [value]=\"value()\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n />\n @if (showReveal()) {\n <button\n type=\"button\"\n class=\"in-reveal\"\n [attr.aria-label]=\"revealAria()\"\n [attr.aria-pressed]=\"revealed()\"\n [disabled]=\"disabled() || readOnly()\"\n (click)=\"toggleReveal()\"\n >\n <fold-icon\n [name]=\"revealed() ? 'eye-off' : 'eye'\"\n size=\"sm\"\n aria-hidden=\"true\"\n />\n </button>\n }\n </div>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}input,select,textarea{all:unset;box-sizing:border-box;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}input::placeholder,select::placeholder,textarea::placeholder{color:var(--fold-color-text-faded)}input:hover:not(:disabled):not(:read-only):not(:focus),select:hover:not(:disabled):not(:read-only):not(:focus),textarea:hover:not(:disabled):not(:read-only):not(:focus){border-color:var(--fold-color-border)}input:focus,select:focus,textarea:focus{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}input:disabled,select:disabled,textarea:disabled{opacity:.4;cursor:not-allowed}input:read-only,select:read-only,textarea:read-only{opacity:.6;cursor:default}input[type=number],select[type=number],textarea[type=number]{appearance:textfield;-moz-appearance:textfield}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button,select[type=number]::-webkit-inner-spin-button,select[type=number]::-webkit-outer-spin-button,textarea[type=number]::-webkit-inner-spin-button,textarea[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}:host(.sm) input,:host(.sm) select{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.sm) textarea{font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) input,:host(.md) select{height:2.25rem;font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.md) textarea{font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) input,:host(.lg) select{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.lg) textarea{font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.center) input{text-align:center}:host(.panel) input,:host(.panel) select,:host(.panel) textarea{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) input:focus,:host(.panel) select:focus,:host(.panel) textarea:focus{box-shadow:none}.in-field{position:relative}:host input.has-reveal{padding-inline-end:2.1rem}.in-reveal{all:unset;position:absolute;inset-inline-end:.4rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;padding:.2rem;border-radius:var(--fold-radius-xs);color:var(--fold-color-text-muted);cursor:pointer}.in-reveal:hover:not(:disabled),.in-reveal:focus-visible{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}.in-reveal:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:1px}.in-reveal:disabled{cursor:not-allowed;opacity:.4}@media(forced-colors:active){.in-reveal:focus-visible{outline-color:Highlight}}\n"], dependencies: [{ kind: "component", type: FoldInputBaseComponent, selector: "fold-input-base", inputs: ["label", "for", "required", "optional", "optionalLabel", "hint", "error", "info", "infoLabel"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
2904
2978
  }
2905
2979
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldInputComponent, decorators: [{
2906
2980
  type: Component,
2907
2981
  args: [{ selector: "fold-input", standalone: true, imports: [FoldInputBaseComponent, FoldIconComponent], host: {
2908
2982
  "[class]": 'size() + " " + align() + " " + variant()',
2909
- }, template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <div class=\"in-field\">\n <input\n [id]=\"inputId\"\n [class.has-reveal]=\"showReveal()\"\n [attr.type]=\"effectiveType()\"\n [attr.placeholder]=\"placeholder()\"\n [attr.readonly]=\"readOnly() || null\"\n [attr.disabled]=\"disabled() || null\"\n [attr.required]=\"required() || null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.autocomplete]=\"autocomplete()\"\n [value]=\"value()\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n />\n @if (showReveal()) {\n <button\n type=\"button\"\n class=\"in-reveal\"\n [attr.aria-label]=\"revealAria()\"\n [attr.aria-pressed]=\"revealed()\"\n [disabled]=\"disabled() || readOnly()\"\n (click)=\"toggleReveal()\"\n >\n <fold-icon\n [name]=\"revealed() ? 'eye-off' : 'eye'\"\n size=\"sm\"\n aria-hidden=\"true\"\n />\n </button>\n }\n </div>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}input,select,textarea{all:unset;box-sizing:border-box;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}input::placeholder,select::placeholder,textarea::placeholder{color:var(--fold-color-text-faded)}input:hover:not(:disabled):not(:read-only):not(:focus),select:hover:not(:disabled):not(:read-only):not(:focus),textarea:hover:not(:disabled):not(:read-only):not(:focus){border-color:var(--fold-color-border)}input:focus,select:focus,textarea:focus{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}input:disabled,select:disabled,textarea:disabled{opacity:.4;cursor:not-allowed}input:read-only,select:read-only,textarea:read-only{opacity:.6;cursor:default}input[type=number],select[type=number],textarea[type=number]{appearance:textfield;-moz-appearance:textfield}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button,select[type=number]::-webkit-inner-spin-button,select[type=number]::-webkit-outer-spin-button,textarea[type=number]::-webkit-inner-spin-button,textarea[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}:host(.sm) input,:host(.sm) select{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.sm) textarea{font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) input,:host(.md) select{height:2.25rem;font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.md) textarea{font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) input,:host(.lg) select{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.lg) textarea{font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.center) input{text-align:center}:host(.panel) input,:host(.panel) select,:host(.panel) textarea{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) input:focus,:host(.panel) select:focus,:host(.panel) textarea:focus{box-shadow:none}.in-field{position:relative}:host input.has-reveal{padding-inline-end:2.1rem}.in-reveal{all:unset;position:absolute;inset-inline-end:.4rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;padding:.2rem;border-radius:var(--fold-radius-xs);color:var(--fold-color-text-muted);cursor:pointer}.in-reveal:hover:not(:disabled),.in-reveal:focus-visible{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}.in-reveal:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:1px}.in-reveal:disabled{cursor:not-allowed;opacity:.4}@media(forced-colors:active){.in-reveal:focus-visible{outline-color:Highlight}}\n"] }]
2910
- }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], revealable: [{ type: i0.Input, args: [{ isSignal: true, alias: "revealable", required: false }] }], revealLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "revealLabel", required: false }] }], hideLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideLabel", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], optional: [{ type: i0.Input, args: [{ isSignal: true, alias: "optional", required: false }] }], optionalLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionalLabel", required: false }] }], info: [{ type: i0.Input, args: [{ isSignal: true, alias: "info", required: false }] }], infoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "infoLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }], autofocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autofocus", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }] } });
2983
+ }, template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <div class=\"in-field\">\n <input\n [id]=\"inputId\"\n [class.has-reveal]=\"showReveal()\"\n [attr.type]=\"effectiveType()\"\n [attr.placeholder]=\"placeholder()\"\n [attr.readonly]=\"readOnly() || null\"\n [attr.disabled]=\"disabled() || null\"\n [attr.required]=\"required() || null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.autocomplete]=\"autocomplete()\"\n [value]=\"value()\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n />\n @if (showReveal()) {\n <button\n type=\"button\"\n class=\"in-reveal\"\n [attr.aria-label]=\"revealAria()\"\n [attr.aria-pressed]=\"revealed()\"\n [disabled]=\"disabled() || readOnly()\"\n (click)=\"toggleReveal()\"\n >\n <fold-icon\n [name]=\"revealed() ? 'eye-off' : 'eye'\"\n size=\"sm\"\n aria-hidden=\"true\"\n />\n </button>\n }\n </div>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}input,select,textarea{all:unset;box-sizing:border-box;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}input::placeholder,select::placeholder,textarea::placeholder{color:var(--fold-color-text-faded)}input:hover:not(:disabled):not(:read-only):not(:focus),select:hover:not(:disabled):not(:read-only):not(:focus),textarea:hover:not(:disabled):not(:read-only):not(:focus){border-color:var(--fold-color-border)}input:focus,select:focus,textarea:focus{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}input:disabled,select:disabled,textarea:disabled{opacity:.4;cursor:not-allowed}input:read-only,select:read-only,textarea:read-only{opacity:.6;cursor:default}input[type=number],select[type=number],textarea[type=number]{appearance:textfield;-moz-appearance:textfield}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button,select[type=number]::-webkit-inner-spin-button,select[type=number]::-webkit-outer-spin-button,textarea[type=number]::-webkit-inner-spin-button,textarea[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}:host(.sm) input,:host(.sm) select{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.sm) textarea{font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) input,:host(.md) select{height:2.25rem;font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.md) textarea{font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) input,:host(.lg) select{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.lg) textarea{font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.center) input{text-align:center}:host(.panel) input,:host(.panel) select,:host(.panel) textarea{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) input:focus,:host(.panel) select:focus,:host(.panel) textarea:focus{box-shadow:none}.in-field{position:relative}:host input.has-reveal{padding-inline-end:2.1rem}.in-reveal{all:unset;position:absolute;inset-inline-end:.4rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;padding:.2rem;border-radius:var(--fold-radius-xs);color:var(--fold-color-text-muted);cursor:pointer}.in-reveal:hover:not(:disabled),.in-reveal:focus-visible{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}.in-reveal:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:1px}.in-reveal:disabled{cursor:not-allowed;opacity:.4}@media(forced-colors:active){.in-reveal:focus-visible{outline-color:Highlight}}\n"] }]
2984
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], revealable: [{ type: i0.Input, args: [{ isSignal: true, alias: "revealable", required: false }] }], revealLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "revealLabel", required: false }] }], hideLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideLabel", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], optional: [{ type: i0.Input, args: [{ isSignal: true, alias: "optional", required: false }] }], optionalLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionalLabel", required: false }] }], info: [{ type: i0.Input, args: [{ isSignal: true, alias: "info", required: false }] }], infoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "infoLabel", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }], autofocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autofocus", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }] } });
2911
2985
 
2912
2986
  /** The English defaults — the base every override merges onto. */
2913
2987
  const FOLD_INLINE_CONFIRM_DEFAULT_LABELS = {
@@ -3150,7 +3224,7 @@ class FoldInlineConfirmComponent {
3150
3224
  this.cancelled.emit();
3151
3225
  }
3152
3226
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldInlineConfirmComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3153
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldInlineConfirmComponent, isStandalone: true, selector: "fold-inline-confirm", inputs: { intent: { classPropertyName: "intent", publicName: "intent", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, match: { classPropertyName: "match", publicName: "match", isSignal: true, isRequired: false, transformFunction: null }, password: { classPropertyName: "password", publicName: "password", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, confirmIcon: { classPropertyName: "confirmIcon", publicName: "confirmIcon", isSignal: true, isRequired: false, transformFunction: null }, cancelIcon: { classPropertyName: "cancelIcon", publicName: "cancelIcon", isSignal: true, isRequired: false, transformFunction: null }, keepOpenOnConfirm: { classPropertyName: "keepOpenOnConfirm", publicName: "keepOpenOnConfirm", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirmed: "confirmed", cancelled: "cancelled", open: "openChange" }, host: { properties: { "class.is-open": "open()" } }, viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["triggerWrap"], descendants: true, isSignal: true }, { propertyName: "groupEl", first: true, predicate: ["groupEl"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (!open()) {\n <!-- Idle: the host's projected trigger. A click anywhere in it starts the\n flow; the trigger itself stays a real focusable control (button / anchor),\n so keyboard activation is native (Enter/Space \u2192 click) \u2014 no extra\n role/tabindex, and no keydown handler that would double-fire. -->\n <span #triggerWrap class=\"fic-trigger\" (click)=\"activate()\">\n <ng-content />\n </span>\n} @else {\n <div\n #groupEl\n class=\"fic-confirm\"\n role=\"group\"\n [attr.aria-label]=\"l().group\"\n (keydown.escape)=\"cancel(); $event.stopPropagation()\"\n >\n @if (message(); as text) {\n <p class=\"fic-message\" [id]=\"msgId\">{{ text }}</p>\n }\n\n @if (needsInput()) {\n <fold-input\n class=\"fic-field\"\n [label]=\"prompt()\"\n [type]=\"fieldType()\"\n [size]=\"size() === 'lg' ? 'lg' : 'sm'\"\n [placeholder]=\"placeholder() ?? ''\"\n [autocomplete]=\"password() ? 'current-password' : 'off'\"\n [(value)]=\"typed\"\n (keydown.enter)=\"confirm()\"\n />\n }\n\n <div class=\"fic-actions\">\n <button\n foldButton\n emphasis=\"solid\"\n [intent]=\"intent()\"\n [size]=\"size()\"\n [icon]=\"confirmIcon()\"\n [disabled]=\"!canConfirm()\"\n [attr.aria-describedby]=\"message() ? msgId : null\"\n (click)=\"confirm()\"\n >\n {{ loading() ? l().busy : l().confirm }}\n </button>\n\n @if (cancelIcon(); as icon) {\n <fold-button-icon\n [icon]=\"icon\"\n tone=\"ghost\"\n [size]=\"size()\"\n [disabled]=\"loading()\"\n [tooltip]=\"l().cancelAria\"\n (clicked)=\"cancel()\"\n />\n } @else {\n <button\n foldButton\n emphasis=\"soft\"\n intent=\"neutral\"\n [size]=\"size()\"\n [disabled]=\"loading()\"\n (click)=\"cancel()\"\n >\n {{ l().cancel }}\n </button>\n }\n </div>\n </div>\n}\n", styles: [":host{display:inline-flex;align-items:center;min-width:0}.fic-trigger{display:contents}.fic-confirm{display:inline-flex;flex-direction:column;gap:var(--fold-space-sm);min-width:0;animation:fic-in var(--fold-motion-fast)}.fic-message{margin:0;font-size:var(--fold-text-xs);line-height:1.5;color:var(--fold-color-text-secondary)}.fic-field{display:block;width:15rem;max-width:100%}.fic-actions{display:inline-flex;align-items:center;gap:var(--fold-space-xs)}@keyframes fic-in{0%{opacity:0;transform:translateY(-2px)}to{opacity:1;transform:none}}@media(prefers-reduced-motion:reduce){.fic-confirm{animation:none}}\n"], dependencies: [{ kind: "component", type: FoldButtonComponent, selector: "button[foldButton], a[foldButton]", inputs: ["emphasis", "intent", "size", "shape", "block", "icon", "iconTrailing", "type", "disabled", "loading"] }, { kind: "component", type: FoldButtonIconComponent, selector: "fold-button-icon", inputs: ["icon", "shape", "size", "tone", "disabled", "loading", "tooltip", "type"], outputs: ["clicked"] }, { kind: "component", type: FoldInputComponent, selector: "fold-input", inputs: ["value", "disabled", "touched", "errors", "type", "revealable", "revealLabel", "hideLabel", "size", "align", "variant", "label", "required", "optional", "optionalLabel", "info", "infoLabel", "hint", "placeholder", "readOnly", "autofocus", "autocomplete"], outputs: ["valueChange", "touchedChange"] }] });
3227
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldInlineConfirmComponent, isStandalone: true, selector: "fold-inline-confirm", inputs: { intent: { classPropertyName: "intent", publicName: "intent", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, match: { classPropertyName: "match", publicName: "match", isSignal: true, isRequired: false, transformFunction: null }, password: { classPropertyName: "password", publicName: "password", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, confirmIcon: { classPropertyName: "confirmIcon", publicName: "confirmIcon", isSignal: true, isRequired: false, transformFunction: null }, cancelIcon: { classPropertyName: "cancelIcon", publicName: "cancelIcon", isSignal: true, isRequired: false, transformFunction: null }, keepOpenOnConfirm: { classPropertyName: "keepOpenOnConfirm", publicName: "keepOpenOnConfirm", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirmed: "confirmed", cancelled: "cancelled", open: "openChange" }, host: { properties: { "class.is-open": "open()" } }, viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["triggerWrap"], descendants: true, isSignal: true }, { propertyName: "groupEl", first: true, predicate: ["groupEl"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (!open()) {\n <!-- Idle: the host's projected trigger. A click anywhere in it starts the\n flow; the trigger itself stays a real focusable control (button / anchor),\n so keyboard activation is native (Enter/Space \u2192 click) \u2014 no extra\n role/tabindex, and no keydown handler that would double-fire. -->\n <span #triggerWrap class=\"fic-trigger\" (click)=\"activate()\">\n <ng-content />\n </span>\n} @else {\n <div\n #groupEl\n class=\"fic-confirm\"\n role=\"group\"\n [attr.aria-label]=\"l().group\"\n (keydown.escape)=\"cancel(); $event.stopPropagation()\"\n >\n @if (message(); as text) {\n <p class=\"fic-message\" [id]=\"msgId\">{{ text }}</p>\n }\n\n @if (needsInput()) {\n <fold-input\n class=\"fic-field\"\n [label]=\"prompt()\"\n [type]=\"fieldType()\"\n [size]=\"size() === 'lg' ? 'lg' : 'sm'\"\n [placeholder]=\"placeholder() ?? ''\"\n [autocomplete]=\"password() ? 'current-password' : 'off'\"\n [(value)]=\"typed\"\n (keydown.enter)=\"confirm()\"\n />\n }\n\n <div class=\"fic-actions\">\n <button\n foldButton\n emphasis=\"solid\"\n [intent]=\"intent()\"\n [size]=\"size()\"\n [icon]=\"confirmIcon()\"\n [disabled]=\"!canConfirm()\"\n [attr.aria-describedby]=\"message() ? msgId : null\"\n (click)=\"confirm()\"\n >\n {{ loading() ? l().busy : l().confirm }}\n </button>\n\n @if (cancelIcon(); as icon) {\n <fold-button-icon\n [icon]=\"icon\"\n tone=\"ghost\"\n [size]=\"size()\"\n [disabled]=\"loading()\"\n [tooltip]=\"l().cancelAria\"\n (clicked)=\"cancel()\"\n />\n } @else {\n <button\n foldButton\n emphasis=\"soft\"\n intent=\"neutral\"\n [size]=\"size()\"\n [disabled]=\"loading()\"\n (click)=\"cancel()\"\n >\n {{ l().cancel }}\n </button>\n }\n </div>\n </div>\n}\n", styles: [":host{display:inline-flex;align-items:center;min-width:0}.fic-trigger{display:contents}.fic-confirm{display:inline-flex;flex-direction:column;gap:var(--fold-space-sm);min-width:0;animation:fic-in var(--fold-motion-fast)}.fic-message{margin:0;font-size:var(--fold-text-xs);line-height:1.5;color:var(--fold-color-text-secondary)}.fic-field{display:block;width:15rem;max-width:100%}.fic-actions{display:inline-flex;align-items:center;gap:var(--fold-space-xs)}@keyframes fic-in{0%{opacity:0;transform:translateY(-2px)}to{opacity:1;transform:none}}@media(prefers-reduced-motion:reduce){.fic-confirm{animation:none}}\n"], dependencies: [{ kind: "component", type: FoldButtonComponent, selector: "button[foldButton], a[foldButton]", inputs: ["emphasis", "intent", "size", "shape", "block", "icon", "iconTrailing", "type", "disabled", "loading"] }, { kind: "component", type: FoldButtonIconComponent, selector: "fold-button-icon", inputs: ["icon", "shape", "size", "tone", "disabled", "loading", "tooltip", "type"], outputs: ["clicked"] }, { kind: "component", type: FoldInputComponent, selector: "fold-input", inputs: ["value", "disabled", "touched", "errors", "type", "revealable", "revealLabel", "hideLabel", "size", "align", "variant", "label", "required", "optional", "optionalLabel", "info", "infoLabel", "ariaLabel", "hint", "placeholder", "readOnly", "autofocus", "autocomplete"], outputs: ["valueChange", "touchedChange"] }] });
3154
3228
  }
3155
3229
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldInlineConfirmComponent, decorators: [{
3156
3230
  type: Component,
@@ -4257,10 +4331,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
4257
4331
  *
4258
4332
  * @selector `a[fold-nav-tile]`, `button[fold-nav-tile]`
4259
4333
  *
4334
+ * `badge` puts a count (or a short tag) in the tile's corner, with the same
4335
+ * meaning as {@link FoldMenuItemComponent}'s: a rail entry and its launcher tile
4336
+ * are **the same destination**, so what one can say the other must be able to
4337
+ * say too — otherwise an app that shows "3 waiting" in the rail goes silent the
4338
+ * moment the window narrows.
4339
+ *
4260
4340
  * @example
4261
4341
  * ```html
4262
4342
  * <a fold-nav-tile icon="home" label="Home" routerLink="/"></a>
4263
4343
  * <button fold-nav-tile icon="music" label="Music" variant="filled"></button>
4344
+ * <a fold-nav-tile icon="inbox" label="Inbox" [badge]="3" badgeTone="accent"></a>
4264
4345
  * ```
4265
4346
  */
4266
4347
  class FoldNavTileComponent {
@@ -4275,8 +4356,40 @@ class FoldNavTileComponent {
4275
4356
  ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
4276
4357
  /** Lights the active indicator — the current destination. */
4277
4358
  active = input(false, { ...(ngDevMode ? { debugName: "active" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4359
+ /**
4360
+ * Optional badge: a count (`3`) or a short text tag (`"new"`). Same reading as
4361
+ * {@link FoldMenuItemComponent.badge} — nullish, `""` and a count of **`0`**
4362
+ * all render nothing, so a caller can pass a raw count and let zero mean
4363
+ * "nothing to say" rather than pre-mapping it to `null`.
4364
+ */
4365
+ badge = input(/* @ts-ignore */
4366
+ ...(ngDevMode ? [undefined, { debugName: "badge" }] : /* istanbul ignore next */ []));
4367
+ /** Badge colour — `follow` (default) tracks the tile's look, or a semantic tone. */
4368
+ badgeTone = input("follow", /* @ts-ignore */
4369
+ ...(ngDevMode ? [{ debugName: "badgeTone" }] : /* istanbul ignore next */ []));
4370
+ /** Whether a badge renders at all (non-empty text / non-zero count). */
4371
+ hasBadge = computed(() => {
4372
+ const b = this.badge();
4373
+ return b !== undefined && b !== "" && b !== 0;
4374
+ }, /* @ts-ignore */
4375
+ ...(ngDevMode ? [{ debugName: "hasBadge" }] : /* istanbul ignore next */ []));
4376
+ /** The badge's text — a count over 99 is capped, as in the collapsed rail. */
4377
+ badgeText = computed(() => {
4378
+ const b = this.badge();
4379
+ if (b === undefined) {
4380
+ return "";
4381
+ }
4382
+ return typeof b === "number" && b > 99 ? "99+" : String(b);
4383
+ }, /* @ts-ignore */
4384
+ ...(ngDevMode ? [{ debugName: "badgeText" }] : /* istanbul ignore next */ []));
4385
+ /**
4386
+ * Accessible name folding the badge in. The bubble itself is `aria-hidden`:
4387
+ * read on its own it would announce a bare "3", detached from what it counts.
4388
+ */
4389
+ ariaLabel = computed(() => this.hasBadge() ? `${this.label()}, ${this.badgeText()}` : null, /* @ts-ignore */
4390
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
4278
4391
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldNavTileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4279
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: FoldNavTileComponent, isStandalone: true, selector: "a[fold-nav-tile], button[fold-nav-tile]", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.is-filled": "variant() === 'filled'", "class.is-active": "active()", "attr.aria-current": "active() ? 'page' : null" }, classAttribute: "fold-nav-tile" }, ngImport: i0, template: "<fold-icon [name]=\"icon()\" [size]=\"26\" class=\"nt-icon\" />\n<span class=\"nt-label\">{{ label() }}</span>\n", styles: ["@charset \"UTF-8\";:host{box-sizing:border-box;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--fold-space-sm);aspect-ratio:1;padding:var(--fold-space-md);border-radius:var(--fold-radius-lg);background:var(--fold-color-surface-raised);border:1px solid var(--fold-color-border);color:var(--fold-color-text-secondary);text-decoration:none;cursor:pointer;opacity:0;animation:fold-nav-tile-in .26s ease forwards;transition:transform .14s ease,background .14s ease,border-color .14s ease,color .14s ease}:host(:hover){transform:translateY(-2px);background:var(--fold-color-surface-hover);border-color:var(--fold-color-primary);color:var(--fold-color-text)}:host(:active){transform:scale(.97)}:host(.is-active){border-color:var(--fold-color-primary);color:var(--fold-color-primary-text)}:host(.is-filled){background:var(--fold-color-primary);border-color:transparent;color:var(--fold-color-on-primary)}:host(.is-filled:hover){background:var(--fold-color-primary-strong);border-color:transparent;color:var(--fold-color-on-primary)}:host(.is-filled.is-active){outline:2px solid var(--fold-color-on-primary);outline-offset:-5px}.nt-icon{flex:none}.nt-label{font-size:var(--fold-text-xs);font-weight:600;line-height:1.2;text-align:center}:host(:nth-child(1)){animation-delay:0ms}:host(:nth-child(2)){animation-delay:35ms}:host(:nth-child(3)){animation-delay:70ms}:host(:nth-child(4)){animation-delay:105ms}:host(:nth-child(5)){animation-delay:.14s}:host(:nth-child(6)){animation-delay:175ms}:host(:nth-child(7)){animation-delay:.21s}:host(:nth-child(8)){animation-delay:245ms}:host(:nth-child(9)){animation-delay:.28s}:host(:nth-child(10)){animation-delay:315ms}:host(:nth-child(11)){animation-delay:.35s}:host(:nth-child(12)){animation-delay:385ms}@keyframes fold-nav-tile-in{0%{opacity:0;transform:scale(.82)}to{opacity:1;transform:scale(1)}}@media(prefers-reduced-motion:reduce){:host{animation:none;opacity:1}}\n"], dependencies: [{ kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
4392
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldNavTileComponent, isStandalone: true, selector: "a[fold-nav-tile], button[fold-nav-tile]", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null }, badge: { classPropertyName: "badge", publicName: "badge", isSignal: true, isRequired: false, transformFunction: null }, badgeTone: { classPropertyName: "badgeTone", publicName: "badgeTone", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.is-filled": "variant() === 'filled'", "class.is-active": "active()", "attr.aria-current": "active() ? 'page' : null", "attr.aria-label": "ariaLabel()" }, classAttribute: "fold-nav-tile" }, ngImport: i0, template: "<fold-icon [name]=\"icon()\" [size]=\"26\" class=\"nt-icon\" />\n<span class=\"nt-label\">{{ label() }}</span>\n\n<!-- Corner bubble, like the collapsed rail's. `aria-hidden` \u2014 the count reaches\n assistive tech through the host's composed `aria-label`. -->\n@if (hasBadge()) {\n <span class=\"nt-badge\" [attr.data-tone]=\"badgeTone()\" aria-hidden=\"true\">{{\n badgeText()\n }}</span>\n}\n", styles: ["@charset \"UTF-8\";:host{position:relative;box-sizing:border-box;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--fold-space-sm);aspect-ratio:1;padding:var(--fold-space-md);border-radius:var(--fold-radius-lg);background:var(--fold-color-surface-raised);border:1px solid var(--fold-color-border);color:var(--fold-color-text-secondary);text-decoration:none;cursor:pointer;opacity:0;animation:fold-nav-tile-in .26s ease forwards;transition:transform .14s ease,background .14s ease,border-color .14s ease,color .14s ease}:host(:hover){transform:translateY(-2px);background:var(--fold-color-surface-hover);border-color:var(--fold-color-primary);color:var(--fold-color-text)}:host(:active){transform:scale(.97)}:host(.is-active){border-color:var(--fold-color-primary);color:var(--fold-color-primary-text)}:host(.is-filled){background:var(--fold-color-primary);border-color:transparent;color:var(--fold-color-on-primary)}:host(.is-filled:hover){background:var(--fold-color-primary-strong);border-color:transparent;color:var(--fold-color-on-primary)}:host(.is-filled.is-active){outline:2px solid var(--fold-color-on-primary);outline-offset:-5px}.nt-icon{flex:none}.nt-label{font-size:var(--fold-text-xs);font-weight:600;line-height:1.2;text-align:center}:host(:nth-child(1)){animation-delay:0ms}:host(:nth-child(2)){animation-delay:35ms}:host(:nth-child(3)){animation-delay:70ms}:host(:nth-child(4)){animation-delay:105ms}:host(:nth-child(5)){animation-delay:.14s}:host(:nth-child(6)){animation-delay:175ms}:host(:nth-child(7)){animation-delay:.21s}:host(:nth-child(8)){animation-delay:245ms}:host(:nth-child(9)){animation-delay:.28s}:host(:nth-child(10)){animation-delay:315ms}:host(:nth-child(11)){animation-delay:.35s}:host(:nth-child(12)){animation-delay:385ms}@keyframes fold-nav-tile-in{0%{opacity:0;transform:scale(.82)}to{opacity:1;transform:scale(1)}}@media(prefers-reduced-motion:reduce){:host{animation:none;opacity:1}}.nt-badge{position:absolute;top:var(--fold-space-sm);right:var(--fold-space-sm);min-width:16px;height:16px;padding:0 var(--fold-space-xs);display:grid;place-items:center;border-radius:var(--fold-radius-pill);background:var(--fold-color-primary);color:var(--fold-color-on-primary);font-size:var(--fold-text-xs);font-weight:600;line-height:1;pointer-events:none}.nt-badge[data-tone=neutral]{background:var(--fold-color-text-muted)}.nt-badge[data-tone=info]{background:var(--fold-color-info)}.nt-badge[data-tone=warning]{background:var(--fold-color-warning)}.nt-badge[data-tone=alert]{background:var(--fold-color-alert)}.nt-badge[data-tone=success]{background:var(--fold-color-success)}:host(.is-filled) .nt-badge[data-tone=follow]{background:var(--fold-color-on-primary);color:var(--fold-color-primary)}@media(forced-colors:active){.nt-badge{border:1px solid CanvasText}}\n"], dependencies: [{ kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
4280
4393
  }
4281
4394
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldNavTileComponent, decorators: [{
4282
4395
  type: Component,
@@ -4285,8 +4398,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
4285
4398
  "[class.is-filled]": "variant() === 'filled'",
4286
4399
  "[class.is-active]": "active()",
4287
4400
  "[attr.aria-current]": "active() ? 'page' : null",
4288
- }, template: "<fold-icon [name]=\"icon()\" [size]=\"26\" class=\"nt-icon\" />\n<span class=\"nt-label\">{{ label() }}</span>\n", styles: ["@charset \"UTF-8\";:host{box-sizing:border-box;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--fold-space-sm);aspect-ratio:1;padding:var(--fold-space-md);border-radius:var(--fold-radius-lg);background:var(--fold-color-surface-raised);border:1px solid var(--fold-color-border);color:var(--fold-color-text-secondary);text-decoration:none;cursor:pointer;opacity:0;animation:fold-nav-tile-in .26s ease forwards;transition:transform .14s ease,background .14s ease,border-color .14s ease,color .14s ease}:host(:hover){transform:translateY(-2px);background:var(--fold-color-surface-hover);border-color:var(--fold-color-primary);color:var(--fold-color-text)}:host(:active){transform:scale(.97)}:host(.is-active){border-color:var(--fold-color-primary);color:var(--fold-color-primary-text)}:host(.is-filled){background:var(--fold-color-primary);border-color:transparent;color:var(--fold-color-on-primary)}:host(.is-filled:hover){background:var(--fold-color-primary-strong);border-color:transparent;color:var(--fold-color-on-primary)}:host(.is-filled.is-active){outline:2px solid var(--fold-color-on-primary);outline-offset:-5px}.nt-icon{flex:none}.nt-label{font-size:var(--fold-text-xs);font-weight:600;line-height:1.2;text-align:center}:host(:nth-child(1)){animation-delay:0ms}:host(:nth-child(2)){animation-delay:35ms}:host(:nth-child(3)){animation-delay:70ms}:host(:nth-child(4)){animation-delay:105ms}:host(:nth-child(5)){animation-delay:.14s}:host(:nth-child(6)){animation-delay:175ms}:host(:nth-child(7)){animation-delay:.21s}:host(:nth-child(8)){animation-delay:245ms}:host(:nth-child(9)){animation-delay:.28s}:host(:nth-child(10)){animation-delay:315ms}:host(:nth-child(11)){animation-delay:.35s}:host(:nth-child(12)){animation-delay:385ms}@keyframes fold-nav-tile-in{0%{opacity:0;transform:scale(.82)}to{opacity:1;transform:scale(1)}}@media(prefers-reduced-motion:reduce){:host{animation:none;opacity:1}}\n"] }]
4289
- }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }] } });
4401
+ "[attr.aria-label]": "ariaLabel()",
4402
+ }, template: "<fold-icon [name]=\"icon()\" [size]=\"26\" class=\"nt-icon\" />\n<span class=\"nt-label\">{{ label() }}</span>\n\n<!-- Corner bubble, like the collapsed rail's. `aria-hidden` \u2014 the count reaches\n assistive tech through the host's composed `aria-label`. -->\n@if (hasBadge()) {\n <span class=\"nt-badge\" [attr.data-tone]=\"badgeTone()\" aria-hidden=\"true\">{{\n badgeText()\n }}</span>\n}\n", styles: ["@charset \"UTF-8\";:host{position:relative;box-sizing:border-box;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--fold-space-sm);aspect-ratio:1;padding:var(--fold-space-md);border-radius:var(--fold-radius-lg);background:var(--fold-color-surface-raised);border:1px solid var(--fold-color-border);color:var(--fold-color-text-secondary);text-decoration:none;cursor:pointer;opacity:0;animation:fold-nav-tile-in .26s ease forwards;transition:transform .14s ease,background .14s ease,border-color .14s ease,color .14s ease}:host(:hover){transform:translateY(-2px);background:var(--fold-color-surface-hover);border-color:var(--fold-color-primary);color:var(--fold-color-text)}:host(:active){transform:scale(.97)}:host(.is-active){border-color:var(--fold-color-primary);color:var(--fold-color-primary-text)}:host(.is-filled){background:var(--fold-color-primary);border-color:transparent;color:var(--fold-color-on-primary)}:host(.is-filled:hover){background:var(--fold-color-primary-strong);border-color:transparent;color:var(--fold-color-on-primary)}:host(.is-filled.is-active){outline:2px solid var(--fold-color-on-primary);outline-offset:-5px}.nt-icon{flex:none}.nt-label{font-size:var(--fold-text-xs);font-weight:600;line-height:1.2;text-align:center}:host(:nth-child(1)){animation-delay:0ms}:host(:nth-child(2)){animation-delay:35ms}:host(:nth-child(3)){animation-delay:70ms}:host(:nth-child(4)){animation-delay:105ms}:host(:nth-child(5)){animation-delay:.14s}:host(:nth-child(6)){animation-delay:175ms}:host(:nth-child(7)){animation-delay:.21s}:host(:nth-child(8)){animation-delay:245ms}:host(:nth-child(9)){animation-delay:.28s}:host(:nth-child(10)){animation-delay:315ms}:host(:nth-child(11)){animation-delay:.35s}:host(:nth-child(12)){animation-delay:385ms}@keyframes fold-nav-tile-in{0%{opacity:0;transform:scale(.82)}to{opacity:1;transform:scale(1)}}@media(prefers-reduced-motion:reduce){:host{animation:none;opacity:1}}.nt-badge{position:absolute;top:var(--fold-space-sm);right:var(--fold-space-sm);min-width:16px;height:16px;padding:0 var(--fold-space-xs);display:grid;place-items:center;border-radius:var(--fold-radius-pill);background:var(--fold-color-primary);color:var(--fold-color-on-primary);font-size:var(--fold-text-xs);font-weight:600;line-height:1;pointer-events:none}.nt-badge[data-tone=neutral]{background:var(--fold-color-text-muted)}.nt-badge[data-tone=info]{background:var(--fold-color-info)}.nt-badge[data-tone=warning]{background:var(--fold-color-warning)}.nt-badge[data-tone=alert]{background:var(--fold-color-alert)}.nt-badge[data-tone=success]{background:var(--fold-color-success)}:host(.is-filled) .nt-badge[data-tone=follow]{background:var(--fold-color-on-primary);color:var(--fold-color-primary)}@media(forced-colors:active){.nt-badge{border:1px solid CanvasText}}\n"] }]
4403
+ }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], badge: [{ type: i0.Input, args: [{ isSignal: true, alias: "badge", required: false }] }], badgeTone: [{ type: i0.Input, args: [{ isSignal: true, alias: "badgeTone", required: false }] }] } });
4290
4404
 
4291
4405
  /**
4292
4406
  * `<fold-nav-launcher>` — a full-screen mobile navigation launcher: a centred
@@ -7737,8 +7851,8 @@ class FoldNumberInputComponent {
7737
7851
  /** Show a lighter `(optional)` marker on the label (ignored when required). */
7738
7852
  optional = input(false, { ...(ngDevMode ? { debugName: "optional" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
7739
7853
  /** The word inside the optional marker. @default 'optional' */
7740
- optionalLabel = input("optional", /* @ts-ignore */
7741
- ...(ngDevMode ? [{ debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
7854
+ optionalLabel = input(/* @ts-ignore */
7855
+ ...(ngDevMode ? [undefined, { debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
7742
7856
  /**
7743
7857
  * Longer explanation behind an `i` at the end of the label line — for the
7744
7858
  * sentence or two a {@link hint} can't carry. Forwarded to `fold-input-base`.
@@ -7746,8 +7860,8 @@ class FoldNumberInputComponent {
7746
7860
  info = input(/* @ts-ignore */
7747
7861
  ...(ngDevMode ? [undefined, { debugName: "info" }] : /* istanbul ignore next */ []));
7748
7862
  /** Accessible name of the info button. @default 'More information' */
7749
- infoLabel = input("More information", /* @ts-ignore */
7750
- ...(ngDevMode ? [{ debugName: "infoLabel" }] : /* istanbul ignore next */ []));
7863
+ infoLabel = input(/* @ts-ignore */
7864
+ ...(ngDevMode ? [undefined, { debugName: "infoLabel" }] : /* istanbul ignore next */ []));
7751
7865
  /** Optional helper text shown under the input. */
7752
7866
  hint = input(/* @ts-ignore */
7753
7867
  ...(ngDevMode ? [undefined, { debugName: "hint" }] : /* istanbul ignore next */ []));
@@ -8008,8 +8122,8 @@ class FoldTextareaComponent {
8008
8122
  /** Show a lighter `(optional)` marker on the label (ignored when required). */
8009
8123
  optional = input(false, { ...(ngDevMode ? { debugName: "optional" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
8010
8124
  /** The word inside the optional marker. @default 'optional' */
8011
- optionalLabel = input("optional", /* @ts-ignore */
8012
- ...(ngDevMode ? [{ debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
8125
+ optionalLabel = input(/* @ts-ignore */
8126
+ ...(ngDevMode ? [undefined, { debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
8013
8127
  /**
8014
8128
  * Longer explanation behind an `i` at the end of the label line — for the
8015
8129
  * sentence or two a {@link hint} can't carry. Forwarded to `fold-input-base`.
@@ -8017,8 +8131,8 @@ class FoldTextareaComponent {
8017
8131
  info = input(/* @ts-ignore */
8018
8132
  ...(ngDevMode ? [undefined, { debugName: "info" }] : /* istanbul ignore next */ []));
8019
8133
  /** Accessible name of the info button. @default 'More information' */
8020
- infoLabel = input("More information", /* @ts-ignore */
8021
- ...(ngDevMode ? [{ debugName: "infoLabel" }] : /* istanbul ignore next */ []));
8134
+ infoLabel = input(/* @ts-ignore */
8135
+ ...(ngDevMode ? [undefined, { debugName: "infoLabel" }] : /* istanbul ignore next */ []));
8022
8136
  /** Optional helper text shown under the control. */
8023
8137
  hint = input(/* @ts-ignore */
8024
8138
  ...(ngDevMode ? [undefined, { debugName: "hint" }] : /* istanbul ignore next */ []));
@@ -8137,8 +8251,8 @@ class FoldDateComponent {
8137
8251
  /** Show a lighter `(optional)` marker on the label (ignored when required). */
8138
8252
  optional = input(false, { ...(ngDevMode ? { debugName: "optional" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
8139
8253
  /** The word inside the optional marker. @default 'optional' */
8140
- optionalLabel = input("optional", /* @ts-ignore */
8141
- ...(ngDevMode ? [{ debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
8254
+ optionalLabel = input(/* @ts-ignore */
8255
+ ...(ngDevMode ? [undefined, { debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
8142
8256
  /**
8143
8257
  * Longer explanation behind an `i` at the end of the label line — for the
8144
8258
  * sentence or two a {@link hint} can't carry. Forwarded to `fold-input-base`.
@@ -8146,8 +8260,8 @@ class FoldDateComponent {
8146
8260
  info = input(/* @ts-ignore */
8147
8261
  ...(ngDevMode ? [undefined, { debugName: "info" }] : /* istanbul ignore next */ []));
8148
8262
  /** Accessible name of the info button. @default 'More information' */
8149
- infoLabel = input("More information", /* @ts-ignore */
8150
- ...(ngDevMode ? [{ debugName: "infoLabel" }] : /* istanbul ignore next */ []));
8263
+ infoLabel = input(/* @ts-ignore */
8264
+ ...(ngDevMode ? [undefined, { debugName: "infoLabel" }] : /* istanbul ignore next */ []));
8151
8265
  /** Optional helper text shown under the control. */
8152
8266
  hint = input(/* @ts-ignore */
8153
8267
  ...(ngDevMode ? [undefined, { debugName: "hint" }] : /* istanbul ignore next */ []));
@@ -8256,8 +8370,8 @@ class FoldTimeComponent {
8256
8370
  /** Show a lighter `(optional)` marker on the label (ignored when required). */
8257
8371
  optional = input(false, { ...(ngDevMode ? { debugName: "optional" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
8258
8372
  /** The word inside the optional marker. @default 'optional' */
8259
- optionalLabel = input("optional", /* @ts-ignore */
8260
- ...(ngDevMode ? [{ debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
8373
+ optionalLabel = input(/* @ts-ignore */
8374
+ ...(ngDevMode ? [undefined, { debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
8261
8375
  /**
8262
8376
  * Longer explanation behind an `i` at the end of the label line — for the
8263
8377
  * sentence or two a {@link hint} can't carry. Forwarded to `fold-input-base`.
@@ -8265,8 +8379,8 @@ class FoldTimeComponent {
8265
8379
  info = input(/* @ts-ignore */
8266
8380
  ...(ngDevMode ? [undefined, { debugName: "info" }] : /* istanbul ignore next */ []));
8267
8381
  /** Accessible name of the info button. @default 'More information' */
8268
- infoLabel = input("More information", /* @ts-ignore */
8269
- ...(ngDevMode ? [{ debugName: "infoLabel" }] : /* istanbul ignore next */ []));
8382
+ infoLabel = input(/* @ts-ignore */
8383
+ ...(ngDevMode ? [undefined, { debugName: "infoLabel" }] : /* istanbul ignore next */ []));
8270
8384
  /** Optional helper text shown under the control. */
8271
8385
  hint = input(/* @ts-ignore */
8272
8386
  ...(ngDevMode ? [undefined, { debugName: "hint" }] : /* istanbul ignore next */ []));
@@ -8373,7 +8487,7 @@ class FoldSearchComponent {
8373
8487
  [variant]="variant()"
8374
8488
  (valueChange)="onInput($event)"
8375
8489
  />
8376
- `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: FoldInputComponent, selector: "fold-input", inputs: ["value", "disabled", "touched", "errors", "type", "revealable", "revealLabel", "hideLabel", "size", "align", "variant", "label", "required", "optional", "optionalLabel", "info", "infoLabel", "hint", "placeholder", "readOnly", "autofocus", "autocomplete"], outputs: ["valueChange", "touchedChange"] }] });
8490
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: FoldInputComponent, selector: "fold-input", inputs: ["value", "disabled", "touched", "errors", "type", "revealable", "revealLabel", "hideLabel", "size", "align", "variant", "label", "required", "optional", "optionalLabel", "info", "infoLabel", "ariaLabel", "hint", "placeholder", "readOnly", "autofocus", "autocomplete"], outputs: ["valueChange", "touchedChange"] }] });
8377
8491
  }
8378
8492
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldSearchComponent, decorators: [{
8379
8493
  type: Component,
@@ -8440,8 +8554,8 @@ class FoldSelectComponent {
8440
8554
  /** Show a lighter `(optional)` marker on the label (ignored when required). */
8441
8555
  optional = input(false, { ...(ngDevMode ? { debugName: "optional" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
8442
8556
  /** The word inside the optional marker. @default 'optional' */
8443
- optionalLabel = input("optional", /* @ts-ignore */
8444
- ...(ngDevMode ? [{ debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
8557
+ optionalLabel = input(/* @ts-ignore */
8558
+ ...(ngDevMode ? [undefined, { debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
8445
8559
  /**
8446
8560
  * Longer explanation behind an `i` at the end of the label line — for the
8447
8561
  * sentence or two a {@link hint} can't carry. Forwarded to `fold-input-base`.
@@ -8449,8 +8563,20 @@ class FoldSelectComponent {
8449
8563
  info = input(/* @ts-ignore */
8450
8564
  ...(ngDevMode ? [undefined, { debugName: "info" }] : /* istanbul ignore next */ []));
8451
8565
  /** Accessible name of the info button. @default 'More information' */
8452
- infoLabel = input("More information", /* @ts-ignore */
8453
- ...(ngDevMode ? [{ debugName: "infoLabel" }] : /* istanbul ignore next */ []));
8566
+ infoLabel = input(/* @ts-ignore */
8567
+ ...(ngDevMode ? [undefined, { debugName: "infoLabel" }] : /* istanbul ignore next */ []));
8568
+ /**
8569
+ * Accessible name for the control itself, when there is **no visible
8570
+ * `label`** — a filter in a toolbar, a control whose meaning the surrounding
8571
+ * text already carries. Without it such a control reaches assistive tech named
8572
+ * only by its current value ("Week"), which says nothing about what it sets.
8573
+ *
8574
+ * Prefer a visible `label`: it names the control for *everyone*. Set this only
8575
+ * where the design genuinely has no room — and never both, since `aria-label`
8576
+ * would override the visible one and leave the two out of sync.
8577
+ */
8578
+ ariaLabel = input(undefined, /* @ts-ignore */
8579
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
8454
8580
  /** Optional helper text shown under the control. */
8455
8581
  hint = input(/* @ts-ignore */
8456
8582
  ...(ngDevMode ? [undefined, { debugName: "hint" }] : /* istanbul ignore next */ []));
@@ -8485,14 +8611,14 @@ class FoldSelectComponent {
8485
8611
  this.touched.set(true);
8486
8612
  }
8487
8613
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8488
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldSelectComponent, isStandalone: true, selector: "fold-select", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, optional: { classPropertyName: "optional", publicName: "optional", isSignal: true, isRequired: false, transformFunction: null }, optionalLabel: { classPropertyName: "optionalLabel", publicName: "optionalLabel", isSignal: true, isRequired: false, transformFunction: null }, info: { classPropertyName: "info", publicName: "info", isSignal: true, isRequired: false, transformFunction: null }, infoLabel: { classPropertyName: "infoLabel", publicName: "infoLabel", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange" }, host: { properties: { "class": "size() + \" \" + variant()" } }, ngImport: i0, template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <div class=\"sel-wrap\">\n <select\n [id]=\"inputId\"\n class=\"sel\"\n [disabled]=\"disabled()\"\n [attr.required]=\"required() || null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [value]=\"value()\"\n (change)=\"onChange($event)\"\n (blur)=\"onBlur()\"\n >\n @if (placeholder(); as ph) {\n <option value=\"\" disabled hidden>{{ ph }}</option>\n }\n <ng-content />\n </select>\n <fold-icon\n name=\"chevron-down\"\n size=\"sm\"\n class=\"sel-caret\"\n aria-hidden=\"true\"\n />\n </div>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}input,select,textarea{all:unset;box-sizing:border-box;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}input::placeholder,select::placeholder,textarea::placeholder{color:var(--fold-color-text-faded)}input:hover:not(:disabled):not(:read-only):not(:focus),select:hover:not(:disabled):not(:read-only):not(:focus),textarea:hover:not(:disabled):not(:read-only):not(:focus){border-color:var(--fold-color-border)}input:focus,select:focus,textarea:focus{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}input:disabled,select:disabled,textarea:disabled{opacity:.4;cursor:not-allowed}input:read-only,select:read-only,textarea:read-only{opacity:.6;cursor:default}input[type=number],select[type=number],textarea[type=number]{appearance:textfield;-moz-appearance:textfield}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button,select[type=number]::-webkit-inner-spin-button,select[type=number]::-webkit-outer-spin-button,textarea[type=number]::-webkit-inner-spin-button,textarea[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}:host(.sm) input,:host(.sm) select{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.sm) textarea{font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) input,:host(.md) select{height:2.25rem;font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.md) textarea{font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) input,:host(.lg) select{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.lg) textarea{font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.center) input{text-align:center}:host(.panel) input,:host(.panel) select,:host(.panel) textarea{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) input:focus,:host(.panel) select:focus,:host(.panel) textarea:focus{box-shadow:none}.sel-wrap{position:relative}.sel{appearance:none;-webkit-appearance:none;padding-right:1.85rem;cursor:pointer}.sel:disabled{cursor:not-allowed}.sel-caret{position:absolute;top:50%;right:.6rem;transform:translateY(-50%);pointer-events:none;color:var(--fold-color-text-muted)}\n"], dependencies: [{ kind: "component", type: FoldInputBaseComponent, selector: "fold-input-base", inputs: ["label", "for", "required", "optional", "optionalLabel", "hint", "error", "info", "infoLabel"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
8614
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldSelectComponent, isStandalone: true, selector: "fold-select", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, optional: { classPropertyName: "optional", publicName: "optional", isSignal: true, isRequired: false, transformFunction: null }, optionalLabel: { classPropertyName: "optionalLabel", publicName: "optionalLabel", isSignal: true, isRequired: false, transformFunction: null }, info: { classPropertyName: "info", publicName: "info", isSignal: true, isRequired: false, transformFunction: null }, infoLabel: { classPropertyName: "infoLabel", publicName: "infoLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange" }, host: { properties: { "class": "size() + \" \" + variant()" } }, ngImport: i0, template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <div class=\"sel-wrap\">\n <select\n [id]=\"inputId\"\n class=\"sel\"\n [disabled]=\"disabled()\"\n [attr.required]=\"required() || null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-label]=\"ariaLabel()\"\n [value]=\"value()\"\n (change)=\"onChange($event)\"\n (blur)=\"onBlur()\"\n >\n @if (placeholder(); as ph) {\n <option value=\"\" disabled hidden>{{ ph }}</option>\n }\n <ng-content />\n </select>\n <fold-icon\n name=\"chevron-down\"\n size=\"sm\"\n class=\"sel-caret\"\n aria-hidden=\"true\"\n />\n </div>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}input,select,textarea{all:unset;box-sizing:border-box;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}input::placeholder,select::placeholder,textarea::placeholder{color:var(--fold-color-text-faded)}input:hover:not(:disabled):not(:read-only):not(:focus),select:hover:not(:disabled):not(:read-only):not(:focus),textarea:hover:not(:disabled):not(:read-only):not(:focus){border-color:var(--fold-color-border)}input:focus,select:focus,textarea:focus{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}input:disabled,select:disabled,textarea:disabled{opacity:.4;cursor:not-allowed}input:read-only,select:read-only,textarea:read-only{opacity:.6;cursor:default}input[type=number],select[type=number],textarea[type=number]{appearance:textfield;-moz-appearance:textfield}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button,select[type=number]::-webkit-inner-spin-button,select[type=number]::-webkit-outer-spin-button,textarea[type=number]::-webkit-inner-spin-button,textarea[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}:host(.sm) input,:host(.sm) select{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.sm) textarea{font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) input,:host(.md) select{height:2.25rem;font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.md) textarea{font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) input,:host(.lg) select{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.lg) textarea{font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.center) input{text-align:center}:host(.panel) input,:host(.panel) select,:host(.panel) textarea{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) input:focus,:host(.panel) select:focus,:host(.panel) textarea:focus{box-shadow:none}.sel-wrap{position:relative}.sel{appearance:none;-webkit-appearance:none;padding-right:1.85rem;cursor:pointer}.sel:disabled{cursor:not-allowed}.sel-caret{position:absolute;top:50%;right:.6rem;transform:translateY(-50%);pointer-events:none;color:var(--fold-color-text-muted)}\n"], dependencies: [{ kind: "component", type: FoldInputBaseComponent, selector: "fold-input-base", inputs: ["label", "for", "required", "optional", "optionalLabel", "hint", "error", "info", "infoLabel"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
8489
8615
  }
8490
8616
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldSelectComponent, decorators: [{
8491
8617
  type: Component,
8492
8618
  args: [{ selector: "fold-select", standalone: true, imports: [FoldInputBaseComponent, FoldIconComponent], host: {
8493
8619
  "[class]": 'size() + " " + variant()',
8494
- }, template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <div class=\"sel-wrap\">\n <select\n [id]=\"inputId\"\n class=\"sel\"\n [disabled]=\"disabled()\"\n [attr.required]=\"required() || null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [value]=\"value()\"\n (change)=\"onChange($event)\"\n (blur)=\"onBlur()\"\n >\n @if (placeholder(); as ph) {\n <option value=\"\" disabled hidden>{{ ph }}</option>\n }\n <ng-content />\n </select>\n <fold-icon\n name=\"chevron-down\"\n size=\"sm\"\n class=\"sel-caret\"\n aria-hidden=\"true\"\n />\n </div>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}input,select,textarea{all:unset;box-sizing:border-box;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}input::placeholder,select::placeholder,textarea::placeholder{color:var(--fold-color-text-faded)}input:hover:not(:disabled):not(:read-only):not(:focus),select:hover:not(:disabled):not(:read-only):not(:focus),textarea:hover:not(:disabled):not(:read-only):not(:focus){border-color:var(--fold-color-border)}input:focus,select:focus,textarea:focus{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}input:disabled,select:disabled,textarea:disabled{opacity:.4;cursor:not-allowed}input:read-only,select:read-only,textarea:read-only{opacity:.6;cursor:default}input[type=number],select[type=number],textarea[type=number]{appearance:textfield;-moz-appearance:textfield}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button,select[type=number]::-webkit-inner-spin-button,select[type=number]::-webkit-outer-spin-button,textarea[type=number]::-webkit-inner-spin-button,textarea[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}:host(.sm) input,:host(.sm) select{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.sm) textarea{font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) input,:host(.md) select{height:2.25rem;font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.md) textarea{font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) input,:host(.lg) select{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.lg) textarea{font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.center) input{text-align:center}:host(.panel) input,:host(.panel) select,:host(.panel) textarea{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) input:focus,:host(.panel) select:focus,:host(.panel) textarea:focus{box-shadow:none}.sel-wrap{position:relative}.sel{appearance:none;-webkit-appearance:none;padding-right:1.85rem;cursor:pointer}.sel:disabled{cursor:not-allowed}.sel-caret{position:absolute;top:50%;right:.6rem;transform:translateY(-50%);pointer-events:none;color:var(--fold-color-text-muted)}\n"] }]
8495
- }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], optional: [{ type: i0.Input, args: [{ isSignal: true, alias: "optional", required: false }] }], optionalLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionalLabel", required: false }] }], info: [{ type: i0.Input, args: [{ isSignal: true, alias: "info", required: false }] }], infoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "infoLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }] } });
8620
+ }, template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <div class=\"sel-wrap\">\n <select\n [id]=\"inputId\"\n class=\"sel\"\n [disabled]=\"disabled()\"\n [attr.required]=\"required() || null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-label]=\"ariaLabel()\"\n [value]=\"value()\"\n (change)=\"onChange($event)\"\n (blur)=\"onBlur()\"\n >\n @if (placeholder(); as ph) {\n <option value=\"\" disabled hidden>{{ ph }}</option>\n }\n <ng-content />\n </select>\n <fold-icon\n name=\"chevron-down\"\n size=\"sm\"\n class=\"sel-caret\"\n aria-hidden=\"true\"\n />\n </div>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}input,select,textarea{all:unset;box-sizing:border-box;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}input::placeholder,select::placeholder,textarea::placeholder{color:var(--fold-color-text-faded)}input:hover:not(:disabled):not(:read-only):not(:focus),select:hover:not(:disabled):not(:read-only):not(:focus),textarea:hover:not(:disabled):not(:read-only):not(:focus){border-color:var(--fold-color-border)}input:focus,select:focus,textarea:focus{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}input:disabled,select:disabled,textarea:disabled{opacity:.4;cursor:not-allowed}input:read-only,select:read-only,textarea:read-only{opacity:.6;cursor:default}input[type=number],select[type=number],textarea[type=number]{appearance:textfield;-moz-appearance:textfield}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button,select[type=number]::-webkit-inner-spin-button,select[type=number]::-webkit-outer-spin-button,textarea[type=number]::-webkit-inner-spin-button,textarea[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}:host(.sm) input,:host(.sm) select{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.sm) textarea{font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) input,:host(.md) select{height:2.25rem;font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.md) textarea{font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) input,:host(.lg) select{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.lg) textarea{font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.center) input{text-align:center}:host(.panel) input,:host(.panel) select,:host(.panel) textarea{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) input:focus,:host(.panel) select:focus,:host(.panel) textarea:focus{box-shadow:none}.sel-wrap{position:relative}.sel{appearance:none;-webkit-appearance:none;padding-right:1.85rem;cursor:pointer}.sel:disabled{cursor:not-allowed}.sel-caret{position:absolute;top:50%;right:.6rem;transform:translateY(-50%);pointer-events:none;color:var(--fold-color-text-muted)}\n"] }]
8621
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], optional: [{ type: i0.Input, args: [{ isSignal: true, alias: "optional", required: false }] }], optionalLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionalLabel", required: false }] }], info: [{ type: i0.Input, args: [{ isSignal: true, alias: "info", required: false }] }], infoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "infoLabel", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }] } });
8496
8622
 
8497
8623
  const FOLD_LISTBOX_OWNER = new InjectionToken("FOLD_LISTBOX_OWNER");
8498
8624
  /**
@@ -8836,8 +8962,8 @@ class FoldListboxComponent {
8836
8962
  /** Show a lighter `(optional)` marker on the label (ignored when required). */
8837
8963
  optional = input(false, { ...(ngDevMode ? { debugName: "optional" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
8838
8964
  /** The word inside the optional marker. @default 'optional' */
8839
- optionalLabel = input("optional", /* @ts-ignore */
8840
- ...(ngDevMode ? [{ debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
8965
+ optionalLabel = input(/* @ts-ignore */
8966
+ ...(ngDevMode ? [undefined, { debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
8841
8967
  /**
8842
8968
  * Longer explanation behind an `i` at the end of the label line — for the
8843
8969
  * sentence or two a {@link hint} can't carry. Forwarded to `fold-input-base`.
@@ -8845,8 +8971,20 @@ class FoldListboxComponent {
8845
8971
  info = input(/* @ts-ignore */
8846
8972
  ...(ngDevMode ? [undefined, { debugName: "info" }] : /* istanbul ignore next */ []));
8847
8973
  /** Accessible name of the info button. @default 'More information' */
8848
- infoLabel = input("More information", /* @ts-ignore */
8849
- ...(ngDevMode ? [{ debugName: "infoLabel" }] : /* istanbul ignore next */ []));
8974
+ infoLabel = input(/* @ts-ignore */
8975
+ ...(ngDevMode ? [undefined, { debugName: "infoLabel" }] : /* istanbul ignore next */ []));
8976
+ /**
8977
+ * Accessible name for the control itself, when there is **no visible
8978
+ * `label`** — a filter in a toolbar, a control whose meaning the surrounding
8979
+ * text already carries. Without it such a control reaches assistive tech named
8980
+ * only by its current value ("Week"), which says nothing about what it sets.
8981
+ *
8982
+ * Prefer a visible `label`: it names the control for *everyone*. Set this only
8983
+ * where the design genuinely has no room — and never both, since `aria-label`
8984
+ * would override the visible one and leave the two out of sync.
8985
+ */
8986
+ ariaLabel = input(undefined, /* @ts-ignore */
8987
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
8850
8988
  /** Optional helper text shown under the control. */
8851
8989
  hint = input(/* @ts-ignore */
8852
8990
  ...(ngDevMode ? [undefined, { debugName: "hint" }] : /* istanbul ignore next */ []));
@@ -8859,8 +8997,12 @@ class FoldListboxComponent {
8859
8997
  /** Show a clear (×) affordance on the trigger once a value is picked. */
8860
8998
  allowClear = input(false, { ...(ngDevMode ? { debugName: "allowClear" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
8861
8999
  /** Accessible name of the clear button. @default 'Clear' */
8862
- clearLabel = input("Clear", /* @ts-ignore */
8863
- ...(ngDevMode ? [{ debugName: "clearLabel" }] : /* istanbul ignore next */ []));
9000
+ clearLabel = input(/* @ts-ignore */
9001
+ ...(ngDevMode ? [undefined, { debugName: "clearLabel" }] : /* istanbul ignore next */ []));
9002
+ common = inject(FOLD_COMMON_LABELS);
9003
+ /** English default ← app-wide provider ← this instance's own input. */
9004
+ clearWord = computed(() => this.clearLabel() ?? this.common.clear, /* @ts-ignore */
9005
+ ...(ngDevMode ? [{ debugName: "clearWord" }] : /* istanbul ignore next */ []));
8864
9006
  /** Unique, SSR-safe id for label association (see {@link FoldIdService}). */
8865
9007
  inputId = inject(FoldIdService).next("fold-listbox");
8866
9008
  /** Id of the `role="listbox"` element (own, distinct from the popover panel). */
@@ -9041,9 +9183,9 @@ class FoldListboxComponent {
9041
9183
  this.open.set(false);
9042
9184
  }
9043
9185
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldListboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9044
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldListboxComponent, isStandalone: true, selector: "fold-listbox", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, optional: { classPropertyName: "optional", publicName: "optional", isSignal: true, isRequired: false, transformFunction: null }, optionalLabel: { classPropertyName: "optionalLabel", publicName: "optionalLabel", isSignal: true, isRequired: false, transformFunction: null }, info: { classPropertyName: "info", publicName: "info", isSignal: true, isRequired: false, transformFunction: null }, infoLabel: { classPropertyName: "infoLabel", publicName: "infoLabel", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, allowClear: { classPropertyName: "allowClear", publicName: "allowClear", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange", open: "openChange", selectionChange: "selectionChange" }, host: { properties: { "class": "size() + \" \" + variant()" } }, providers: [
9186
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldListboxComponent, isStandalone: true, selector: "fold-listbox", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, optional: { classPropertyName: "optional", publicName: "optional", isSignal: true, isRequired: false, transformFunction: null }, optionalLabel: { classPropertyName: "optionalLabel", publicName: "optionalLabel", isSignal: true, isRequired: false, transformFunction: null }, info: { classPropertyName: "info", publicName: "info", isSignal: true, isRequired: false, transformFunction: null }, infoLabel: { classPropertyName: "infoLabel", publicName: "infoLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, allowClear: { classPropertyName: "allowClear", publicName: "allowClear", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange", open: "openChange", selectionChange: "selectionChange" }, host: { properties: { "class": "size() + \" \" + variant()" } }, providers: [
9045
9187
  { provide: FOLD_LISTBOX_OWNER, useExisting: FoldListboxComponent },
9046
- ], queries: [{ propertyName: "optionTemplate", first: true, predicate: ["option"], descendants: true, isSignal: true }, { propertyName: "projectedOptions", predicate: FoldOptionComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "renderedOptions", predicate: FoldOptionComponent, descendants: true, isSignal: true }, { propertyName: "list", first: true, predicate: ["list"], descendants: true, isSignal: true }], ngImport: i0, template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <fold-popover\n [(open)]=\"open\"\n [autoFocus]=\"false\"\n [ariaControls]=\"listId\"\n [placement]=\"placement()\"\n [fallbackPlacements]=\"['top-start', 'bottom-end', 'top-end']\"\n >\n <div class=\"lb-field\">\n <button\n type=\"button\"\n class=\"lb-trigger\"\n [class.has-clear]=\"showClear()\"\n [id]=\"inputId\"\n foldPopoverTrigger=\"listbox\"\n [disabled]=\"disabled()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n @if (selectedLabel(); as lbl) {\n <span class=\"lb-value\">{{ lbl }}</span>\n } @else {\n <span class=\"lb-placeholder\">{{ placeholder() }}</span>\n }\n <fold-icon\n name=\"chevron-down\"\n size=\"sm\"\n class=\"lb-caret\"\n aria-hidden=\"true\"\n />\n </button>\n @if (showClear()) {\n <button\n type=\"button\"\n class=\"lb-clear\"\n [attr.aria-label]=\"clearLabel()\"\n (click)=\"clear($event)\"\n >\n <fold-icon name=\"close\" size=\"sm\" aria-hidden=\"true\" />\n </button>\n }\n </div>\n\n <div\n #list\n foldPopoverPanel\n class=\"lb-list\"\n role=\"listbox\"\n tabindex=\"-1\"\n [id]=\"listId\"\n [attr.aria-label]=\"label()\"\n [attr.aria-activedescendant]=\"activeId()\"\n (keydown)=\"onListKeydown($event)\"\n (click)=\"onListClick($event)\"\n (pointermove)=\"onListPointermove($event)\"\n >\n @if (options(); as opts) {\n @for (item of opts; track $index) {\n @if (asGroup(item); as group) {\n <fold-optgroup [label]=\"group.label\">\n @for (o of group.options; track o.value) {\n <fold-option [value]=\"o.value\" [disabled]=\"o.disabled ?? false\">\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: o }\"\n />\n } @else {\n {{ o.label }}\n }\n </fold-option>\n }\n </fold-optgroup>\n } @else if (asOption(item); as o) {\n <fold-option [value]=\"o.value\" [disabled]=\"o.disabled ?? false\">\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: o }\"\n />\n } @else {\n {{ o.label }}\n }\n </fold-option>\n }\n }\n } @else {\n <ng-content />\n }\n </div>\n </fold-popover>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}.lb-trigger{all:unset;box-sizing:border-box;display:flex;align-items:center;gap:.5rem;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);cursor:pointer;transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}@media(prefers-reduced-motion:reduce){.lb-trigger{transition:none}}.lb-trigger:hover:not(:disabled){border-color:var(--fold-color-border)}.lb-trigger:focus-visible{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}.lb-trigger:disabled{opacity:.4;cursor:not-allowed}.lb-value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.lb-placeholder{color:var(--fold-color-text-faded)}.lb-caret{margin-inline-start:auto;color:var(--fold-color-text-muted)}.lb-field{position:relative}.lb-trigger.has-clear .lb-caret{visibility:hidden}.lb-clear{all:unset;position:absolute;inset-inline-end:.4rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;padding:.15rem;border-radius:var(--fold-radius-xs);color:var(--fold-color-text-muted);cursor:pointer}.lb-clear:hover,.lb-clear:focus-visible{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}:host(.sm) .lb-trigger{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) .lb-trigger{height:2.25rem;font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) .lb-trigger{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.panel) .lb-trigger{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) .lb-trigger:focus-visible{box-shadow:none}.lb-list{display:flex;flex-direction:column;gap:1px;min-width:var(--fold-popover-anchor-width, 11rem);outline:none}\n"], dependencies: [{ kind: "component", type: FoldInputBaseComponent, selector: "fold-input-base", inputs: ["label", "for", "required", "optional", "optionalLabel", "hint", "error", "info", "infoLabel"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }, { kind: "component", type: FoldOptionComponent, selector: "fold-option", inputs: ["value", "disabled"] }, { kind: "component", type: FoldOptgroupComponent, selector: "fold-optgroup", inputs: ["label"] }, { kind: "component", type: FoldPopoverComponent, selector: "fold-popover", inputs: ["placement", "fallbackPlacements", "offset", "padding", "autoFocus", "arrow", "open", "ariaControls"], outputs: ["openChange"] }, { kind: "directive", type: FoldPopoverTriggerDirective, selector: "[foldPopoverTrigger]", inputs: ["foldPopoverTrigger"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
9188
+ ], queries: [{ propertyName: "optionTemplate", first: true, predicate: ["option"], descendants: true, isSignal: true }, { propertyName: "projectedOptions", predicate: FoldOptionComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "renderedOptions", predicate: FoldOptionComponent, descendants: true, isSignal: true }, { propertyName: "list", first: true, predicate: ["list"], descendants: true, isSignal: true }], ngImport: i0, template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <fold-popover\n [(open)]=\"open\"\n [autoFocus]=\"false\"\n [ariaControls]=\"listId\"\n [placement]=\"placement()\"\n [fallbackPlacements]=\"['top-start', 'bottom-end', 'top-end']\"\n >\n <div class=\"lb-field\">\n <button\n type=\"button\"\n class=\"lb-trigger\"\n [class.has-clear]=\"showClear()\"\n [id]=\"inputId\"\n foldPopoverTrigger=\"listbox\"\n [disabled]=\"disabled()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-label]=\"ariaLabel()\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n @if (selectedLabel(); as lbl) {\n <span class=\"lb-value\">{{ lbl }}</span>\n } @else {\n <span class=\"lb-placeholder\">{{ placeholder() }}</span>\n }\n <fold-icon\n name=\"chevron-down\"\n size=\"sm\"\n class=\"lb-caret\"\n aria-hidden=\"true\"\n />\n </button>\n @if (showClear()) {\n <button\n type=\"button\"\n class=\"lb-clear\"\n [attr.aria-label]=\"clearWord()\"\n (click)=\"clear($event)\"\n >\n <fold-icon name=\"close\" size=\"sm\" aria-hidden=\"true\" />\n </button>\n }\n </div>\n\n <div\n #list\n foldPopoverPanel\n class=\"lb-list\"\n role=\"listbox\"\n tabindex=\"-1\"\n [id]=\"listId\"\n [attr.aria-label]=\"label()\"\n [attr.aria-activedescendant]=\"activeId()\"\n (keydown)=\"onListKeydown($event)\"\n (click)=\"onListClick($event)\"\n (pointermove)=\"onListPointermove($event)\"\n >\n @if (options(); as opts) {\n @for (item of opts; track $index) {\n @if (asGroup(item); as group) {\n <fold-optgroup [label]=\"group.label\">\n @for (o of group.options; track o.value) {\n <fold-option [value]=\"o.value\" [disabled]=\"o.disabled ?? false\">\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: o }\"\n />\n } @else {\n {{ o.label }}\n }\n </fold-option>\n }\n </fold-optgroup>\n } @else if (asOption(item); as o) {\n <fold-option [value]=\"o.value\" [disabled]=\"o.disabled ?? false\">\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: o }\"\n />\n } @else {\n {{ o.label }}\n }\n </fold-option>\n }\n }\n } @else {\n <ng-content />\n }\n </div>\n </fold-popover>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}.lb-trigger{all:unset;box-sizing:border-box;display:flex;align-items:center;gap:.5rem;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);cursor:pointer;transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}@media(prefers-reduced-motion:reduce){.lb-trigger{transition:none}}.lb-trigger:hover:not(:disabled){border-color:var(--fold-color-border)}.lb-trigger:focus-visible{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}.lb-trigger:disabled{opacity:.4;cursor:not-allowed}.lb-value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.lb-placeholder{color:var(--fold-color-text-faded)}.lb-caret{margin-inline-start:auto;color:var(--fold-color-text-muted)}.lb-field{position:relative}.lb-trigger.has-clear .lb-caret{visibility:hidden}.lb-clear{all:unset;position:absolute;inset-inline-end:.4rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;padding:.15rem;border-radius:var(--fold-radius-xs);color:var(--fold-color-text-muted);cursor:pointer}.lb-clear:hover,.lb-clear:focus-visible{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}:host(.sm) .lb-trigger{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) .lb-trigger{height:2.25rem;font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) .lb-trigger{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.panel) .lb-trigger{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) .lb-trigger:focus-visible{box-shadow:none}.lb-list{display:flex;flex-direction:column;gap:1px;min-width:var(--fold-popover-anchor-width, 11rem);outline:none}\n"], dependencies: [{ kind: "component", type: FoldInputBaseComponent, selector: "fold-input-base", inputs: ["label", "for", "required", "optional", "optionalLabel", "hint", "error", "info", "infoLabel"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }, { kind: "component", type: FoldOptionComponent, selector: "fold-option", inputs: ["value", "disabled"] }, { kind: "component", type: FoldOptgroupComponent, selector: "fold-optgroup", inputs: ["label"] }, { kind: "component", type: FoldPopoverComponent, selector: "fold-popover", inputs: ["placement", "fallbackPlacements", "offset", "padding", "autoFocus", "arrow", "open", "ariaControls"], outputs: ["openChange"] }, { kind: "directive", type: FoldPopoverTriggerDirective, selector: "[foldPopoverTrigger]", inputs: ["foldPopoverTrigger"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
9047
9189
  }
9048
9190
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldListboxComponent, decorators: [{
9049
9191
  type: Component,
@@ -9057,8 +9199,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
9057
9199
  NgTemplateOutlet,
9058
9200
  ], host: { "[class]": 'size() + " " + variant()' }, providers: [
9059
9201
  { provide: FOLD_LISTBOX_OWNER, useExisting: FoldListboxComponent },
9060
- ], template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <fold-popover\n [(open)]=\"open\"\n [autoFocus]=\"false\"\n [ariaControls]=\"listId\"\n [placement]=\"placement()\"\n [fallbackPlacements]=\"['top-start', 'bottom-end', 'top-end']\"\n >\n <div class=\"lb-field\">\n <button\n type=\"button\"\n class=\"lb-trigger\"\n [class.has-clear]=\"showClear()\"\n [id]=\"inputId\"\n foldPopoverTrigger=\"listbox\"\n [disabled]=\"disabled()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n @if (selectedLabel(); as lbl) {\n <span class=\"lb-value\">{{ lbl }}</span>\n } @else {\n <span class=\"lb-placeholder\">{{ placeholder() }}</span>\n }\n <fold-icon\n name=\"chevron-down\"\n size=\"sm\"\n class=\"lb-caret\"\n aria-hidden=\"true\"\n />\n </button>\n @if (showClear()) {\n <button\n type=\"button\"\n class=\"lb-clear\"\n [attr.aria-label]=\"clearLabel()\"\n (click)=\"clear($event)\"\n >\n <fold-icon name=\"close\" size=\"sm\" aria-hidden=\"true\" />\n </button>\n }\n </div>\n\n <div\n #list\n foldPopoverPanel\n class=\"lb-list\"\n role=\"listbox\"\n tabindex=\"-1\"\n [id]=\"listId\"\n [attr.aria-label]=\"label()\"\n [attr.aria-activedescendant]=\"activeId()\"\n (keydown)=\"onListKeydown($event)\"\n (click)=\"onListClick($event)\"\n (pointermove)=\"onListPointermove($event)\"\n >\n @if (options(); as opts) {\n @for (item of opts; track $index) {\n @if (asGroup(item); as group) {\n <fold-optgroup [label]=\"group.label\">\n @for (o of group.options; track o.value) {\n <fold-option [value]=\"o.value\" [disabled]=\"o.disabled ?? false\">\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: o }\"\n />\n } @else {\n {{ o.label }}\n }\n </fold-option>\n }\n </fold-optgroup>\n } @else if (asOption(item); as o) {\n <fold-option [value]=\"o.value\" [disabled]=\"o.disabled ?? false\">\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: o }\"\n />\n } @else {\n {{ o.label }}\n }\n </fold-option>\n }\n }\n } @else {\n <ng-content />\n }\n </div>\n </fold-popover>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}.lb-trigger{all:unset;box-sizing:border-box;display:flex;align-items:center;gap:.5rem;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);cursor:pointer;transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}@media(prefers-reduced-motion:reduce){.lb-trigger{transition:none}}.lb-trigger:hover:not(:disabled){border-color:var(--fold-color-border)}.lb-trigger:focus-visible{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}.lb-trigger:disabled{opacity:.4;cursor:not-allowed}.lb-value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.lb-placeholder{color:var(--fold-color-text-faded)}.lb-caret{margin-inline-start:auto;color:var(--fold-color-text-muted)}.lb-field{position:relative}.lb-trigger.has-clear .lb-caret{visibility:hidden}.lb-clear{all:unset;position:absolute;inset-inline-end:.4rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;padding:.15rem;border-radius:var(--fold-radius-xs);color:var(--fold-color-text-muted);cursor:pointer}.lb-clear:hover,.lb-clear:focus-visible{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}:host(.sm) .lb-trigger{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) .lb-trigger{height:2.25rem;font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) .lb-trigger{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.panel) .lb-trigger{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) .lb-trigger:focus-visible{box-shadow:none}.lb-list{display:flex;flex-direction:column;gap:1px;min-width:var(--fold-popover-anchor-width, 11rem);outline:none}\n"] }]
9061
- }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "compareWith", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], optional: [{ type: i0.Input, args: [{ isSignal: true, alias: "optional", required: false }] }], optionalLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionalLabel", required: false }] }], info: [{ type: i0.Input, args: [{ isSignal: true, alias: "info", required: false }] }], infoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "infoLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], allowClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowClear", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], optionTemplate: [{ type: i0.ContentChild, args: ["option", { isSignal: true }] }], projectedOptions: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => FoldOptionComponent), { ...{ descendants: true }, isSignal: true }] }], renderedOptions: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => FoldOptionComponent), { isSignal: true }] }], list: [{ type: i0.ViewChild, args: ["list", { isSignal: true }] }] } });
9202
+ ], template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <fold-popover\n [(open)]=\"open\"\n [autoFocus]=\"false\"\n [ariaControls]=\"listId\"\n [placement]=\"placement()\"\n [fallbackPlacements]=\"['top-start', 'bottom-end', 'top-end']\"\n >\n <div class=\"lb-field\">\n <button\n type=\"button\"\n class=\"lb-trigger\"\n [class.has-clear]=\"showClear()\"\n [id]=\"inputId\"\n foldPopoverTrigger=\"listbox\"\n [disabled]=\"disabled()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-label]=\"ariaLabel()\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n @if (selectedLabel(); as lbl) {\n <span class=\"lb-value\">{{ lbl }}</span>\n } @else {\n <span class=\"lb-placeholder\">{{ placeholder() }}</span>\n }\n <fold-icon\n name=\"chevron-down\"\n size=\"sm\"\n class=\"lb-caret\"\n aria-hidden=\"true\"\n />\n </button>\n @if (showClear()) {\n <button\n type=\"button\"\n class=\"lb-clear\"\n [attr.aria-label]=\"clearWord()\"\n (click)=\"clear($event)\"\n >\n <fold-icon name=\"close\" size=\"sm\" aria-hidden=\"true\" />\n </button>\n }\n </div>\n\n <div\n #list\n foldPopoverPanel\n class=\"lb-list\"\n role=\"listbox\"\n tabindex=\"-1\"\n [id]=\"listId\"\n [attr.aria-label]=\"label()\"\n [attr.aria-activedescendant]=\"activeId()\"\n (keydown)=\"onListKeydown($event)\"\n (click)=\"onListClick($event)\"\n (pointermove)=\"onListPointermove($event)\"\n >\n @if (options(); as opts) {\n @for (item of opts; track $index) {\n @if (asGroup(item); as group) {\n <fold-optgroup [label]=\"group.label\">\n @for (o of group.options; track o.value) {\n <fold-option [value]=\"o.value\" [disabled]=\"o.disabled ?? false\">\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: o }\"\n />\n } @else {\n {{ o.label }}\n }\n </fold-option>\n }\n </fold-optgroup>\n } @else if (asOption(item); as o) {\n <fold-option [value]=\"o.value\" [disabled]=\"o.disabled ?? false\">\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: o }\"\n />\n } @else {\n {{ o.label }}\n }\n </fold-option>\n }\n }\n } @else {\n <ng-content />\n }\n </div>\n </fold-popover>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}.lb-trigger{all:unset;box-sizing:border-box;display:flex;align-items:center;gap:.5rem;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);cursor:pointer;transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}@media(prefers-reduced-motion:reduce){.lb-trigger{transition:none}}.lb-trigger:hover:not(:disabled){border-color:var(--fold-color-border)}.lb-trigger:focus-visible{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}.lb-trigger:disabled{opacity:.4;cursor:not-allowed}.lb-value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.lb-placeholder{color:var(--fold-color-text-faded)}.lb-caret{margin-inline-start:auto;color:var(--fold-color-text-muted)}.lb-field{position:relative}.lb-trigger.has-clear .lb-caret{visibility:hidden}.lb-clear{all:unset;position:absolute;inset-inline-end:.4rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;padding:.15rem;border-radius:var(--fold-radius-xs);color:var(--fold-color-text-muted);cursor:pointer}.lb-clear:hover,.lb-clear:focus-visible{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}:host(.sm) .lb-trigger{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) .lb-trigger{height:2.25rem;font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) .lb-trigger{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.panel) .lb-trigger{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) .lb-trigger:focus-visible{box-shadow:none}.lb-list{display:flex;flex-direction:column;gap:1px;min-width:var(--fold-popover-anchor-width, 11rem);outline:none}\n"] }]
9203
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "compareWith", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], optional: [{ type: i0.Input, args: [{ isSignal: true, alias: "optional", required: false }] }], optionalLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionalLabel", required: false }] }], info: [{ type: i0.Input, args: [{ isSignal: true, alias: "info", required: false }] }], infoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "infoLabel", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], allowClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowClear", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], optionTemplate: [{ type: i0.ContentChild, args: ["option", { isSignal: true }] }], projectedOptions: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => FoldOptionComponent), { ...{ descendants: true }, isSignal: true }] }], renderedOptions: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => FoldOptionComponent), { isSignal: true }] }], list: [{ type: i0.ViewChild, args: ["list", { isSignal: true }] }] } });
9062
9204
 
9063
9205
  /** Labels beyond this count collapse to a "+N" tail on the trigger summary. */
9064
9206
  const SUMMARY_MAX = 3;
@@ -9126,8 +9268,8 @@ class FoldMultiselectComponent {
9126
9268
  /** Show a lighter `(optional)` marker on the label (ignored when required). */
9127
9269
  optional = input(false, { ...(ngDevMode ? { debugName: "optional" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
9128
9270
  /** The word inside the optional marker. @default 'optional' */
9129
- optionalLabel = input("optional", /* @ts-ignore */
9130
- ...(ngDevMode ? [{ debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
9271
+ optionalLabel = input(/* @ts-ignore */
9272
+ ...(ngDevMode ? [undefined, { debugName: "optionalLabel" }] : /* istanbul ignore next */ []));
9131
9273
  /**
9132
9274
  * Longer explanation behind an `i` at the end of the label line — for the
9133
9275
  * sentence or two a {@link hint} can't carry. Forwarded to `fold-input-base`.
@@ -9135,8 +9277,8 @@ class FoldMultiselectComponent {
9135
9277
  info = input(/* @ts-ignore */
9136
9278
  ...(ngDevMode ? [undefined, { debugName: "info" }] : /* istanbul ignore next */ []));
9137
9279
  /** Accessible name of the info button. @default 'More information' */
9138
- infoLabel = input("More information", /* @ts-ignore */
9139
- ...(ngDevMode ? [{ debugName: "infoLabel" }] : /* istanbul ignore next */ []));
9280
+ infoLabel = input(/* @ts-ignore */
9281
+ ...(ngDevMode ? [undefined, { debugName: "infoLabel" }] : /* istanbul ignore next */ []));
9140
9282
  /** Optional helper text shown under the control. */
9141
9283
  hint = input(/* @ts-ignore */
9142
9284
  ...(ngDevMode ? [undefined, { debugName: "hint" }] : /* istanbul ignore next */ []));
@@ -9156,8 +9298,12 @@ class FoldMultiselectComponent {
9156
9298
  selectAllLabel = input("Select all", /* @ts-ignore */
9157
9299
  ...(ngDevMode ? [{ debugName: "selectAllLabel" }] : /* istanbul ignore next */ []));
9158
9300
  /** Label of the clear action. @default 'Clear' */
9159
- clearLabel = input("Clear", /* @ts-ignore */
9160
- ...(ngDevMode ? [{ debugName: "clearLabel" }] : /* istanbul ignore next */ []));
9301
+ clearLabel = input(/* @ts-ignore */
9302
+ ...(ngDevMode ? [undefined, { debugName: "clearLabel" }] : /* istanbul ignore next */ []));
9303
+ common = inject(FOLD_COMMON_LABELS);
9304
+ /** English default ← app-wide provider ← this instance's own input. */
9305
+ clearWord = computed(() => this.clearLabel() ?? this.common.clear, /* @ts-ignore */
9306
+ ...(ngDevMode ? [{ debugName: "clearWord" }] : /* istanbul ignore next */ []));
9161
9307
  /** Unique, SSR-safe id for label association (see {@link FoldIdService}). */
9162
9308
  inputId = inject(FoldIdService).next("fold-multiselect");
9163
9309
  /** Id of the `role="listbox"` element (own, distinct from the popover panel). */
@@ -9362,7 +9508,7 @@ class FoldMultiselectComponent {
9362
9508
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldMultiselectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9363
9509
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldMultiselectComponent, isStandalone: true, selector: "fold-multiselect", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, optional: { classPropertyName: "optional", publicName: "optional", isSignal: true, isRequired: false, transformFunction: null }, optionalLabel: { classPropertyName: "optionalLabel", publicName: "optionalLabel", isSignal: true, isRequired: false, transformFunction: null }, info: { classPropertyName: "info", publicName: "info", isSignal: true, isRequired: false, transformFunction: null }, infoLabel: { classPropertyName: "infoLabel", publicName: "infoLabel", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, allowSelectAll: { classPropertyName: "allowSelectAll", publicName: "allowSelectAll", isSignal: true, isRequired: false, transformFunction: null }, allowClear: { classPropertyName: "allowClear", publicName: "allowClear", isSignal: true, isRequired: false, transformFunction: null }, selectAllLabel: { classPropertyName: "selectAllLabel", publicName: "selectAllLabel", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange", open: "openChange" }, host: { properties: { "class": "size() + \" \" + variant()" } }, providers: [
9364
9510
  { provide: FOLD_LISTBOX_OWNER, useExisting: FoldMultiselectComponent },
9365
- ], queries: [{ propertyName: "optionTemplate", first: true, predicate: ["option"], descendants: true, isSignal: true }, { propertyName: "projectedOptions", predicate: FoldOptionComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "renderedOptions", predicate: FoldOptionComponent, descendants: true, isSignal: true }, { propertyName: "list", first: true, predicate: ["list"], descendants: true, isSignal: true }], ngImport: i0, template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <fold-popover\n [(open)]=\"open\"\n [autoFocus]=\"false\"\n [ariaControls]=\"listId\"\n [placement]=\"placement()\"\n [fallbackPlacements]=\"['top-start', 'bottom-end', 'top-end']\"\n >\n <button\n type=\"button\"\n class=\"lb-trigger\"\n [id]=\"inputId\"\n foldPopoverTrigger=\"listbox\"\n [disabled]=\"disabled()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n @if (summaryLabel(); as lbl) {\n <span class=\"lb-value\">{{ lbl }}</span>\n } @else {\n <span class=\"lb-placeholder\">{{ placeholder() }}</span>\n }\n <fold-icon\n name=\"chevron-down\"\n size=\"sm\"\n class=\"lb-caret\"\n aria-hidden=\"true\"\n />\n </button>\n\n <div foldPopoverPanel class=\"lb-panel\">\n @if (showBulk()) {\n <div class=\"lb-bulk\" role=\"group\" aria-label=\"Bulk actions\">\n @if (allowSelectAll()) {\n <button\n type=\"button\"\n class=\"lb-bulk-btn\"\n [disabled]=\"allEnabledSelected()\"\n (click)=\"selectAll()\"\n >\n <fold-icon name=\"check-circle\" size=\"sm\" aria-hidden=\"true\" />\n {{ selectAllLabel() }}\n </button>\n }\n @if (allowClear()) {\n <button\n type=\"button\"\n class=\"lb-bulk-btn\"\n [disabled]=\"value().length === 0\"\n (click)=\"clearAll()\"\n >\n <fold-icon name=\"close\" size=\"sm\" aria-hidden=\"true\" />\n {{ clearLabel() }}\n </button>\n }\n </div>\n }\n\n <div\n #list\n class=\"lb-list\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n tabindex=\"-1\"\n [id]=\"listId\"\n [attr.aria-label]=\"label()\"\n [attr.aria-activedescendant]=\"activeId()\"\n (keydown)=\"onListKeydown($event)\"\n (click)=\"onListClick($event)\"\n (pointermove)=\"onListPointermove($event)\"\n >\n @if (options(); as opts) {\n @for (item of opts; track $index) {\n @if (asGroup(item); as group) {\n <fold-optgroup [label]=\"group.label\">\n @for (o of group.options; track o.value) {\n <fold-option\n [value]=\"o.value\"\n [disabled]=\"o.disabled ?? false\"\n >\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: o }\"\n />\n } @else {\n {{ o.label }}\n }\n </fold-option>\n }\n </fold-optgroup>\n } @else if (asOption(item); as o) {\n <fold-option [value]=\"o.value\" [disabled]=\"o.disabled ?? false\">\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: o }\"\n />\n } @else {\n {{ o.label }}\n }\n </fold-option>\n }\n }\n } @else {\n <ng-content />\n }\n </div>\n </div>\n </fold-popover>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}.lb-trigger{all:unset;box-sizing:border-box;display:flex;align-items:center;gap:.5rem;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);cursor:pointer;transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}@media(prefers-reduced-motion:reduce){.lb-trigger{transition:none}}.lb-trigger:hover:not(:disabled){border-color:var(--fold-color-border)}.lb-trigger:focus-visible{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}.lb-trigger:disabled{opacity:.4;cursor:not-allowed}.lb-value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.lb-placeholder{color:var(--fold-color-text-faded)}.lb-caret{margin-inline-start:auto;color:var(--fold-color-text-muted)}.lb-field{position:relative}.lb-trigger.has-clear .lb-caret{visibility:hidden}.lb-clear{all:unset;position:absolute;inset-inline-end:.4rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;padding:.15rem;border-radius:var(--fold-radius-xs);color:var(--fold-color-text-muted);cursor:pointer}.lb-clear:hover,.lb-clear:focus-visible{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}:host(.sm) .lb-trigger{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) .lb-trigger{height:2.25rem;font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) .lb-trigger{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.panel) .lb-trigger{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) .lb-trigger:focus-visible{box-shadow:none}.lb-list{display:flex;flex-direction:column;gap:1px;min-width:var(--fold-popover-anchor-width, 11rem);outline:none}.lb-panel{display:flex;flex-direction:column}.lb-bulk{position:sticky;top:0;z-index:1;display:flex;gap:.25rem;padding:.25rem;margin-bottom:1px;background:var(--fold-color-surface-card);border-bottom:1px solid var(--fold-color-border-subtle)}.lb-bulk-btn{all:unset;display:inline-flex;align-items:center;gap:.3rem;padding:.3rem .5rem;border-radius:var(--fold-radius-sm);font-size:var(--fold-text-xs);color:var(--fold-color-text-secondary);cursor:pointer}.lb-bulk-btn:hover:not(:disabled){background:var(--fold-color-surface-hover);color:var(--fold-color-text)}.lb-bulk-btn:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:-2px}.lb-bulk-btn:disabled{opacity:.4;cursor:not-allowed}@media(forced-colors:active){.lb-bulk{border-bottom-color:CanvasText}}\n"], dependencies: [{ kind: "component", type: FoldInputBaseComponent, selector: "fold-input-base", inputs: ["label", "for", "required", "optional", "optionalLabel", "hint", "error", "info", "infoLabel"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }, { kind: "component", type: FoldOptionComponent, selector: "fold-option", inputs: ["value", "disabled"] }, { kind: "component", type: FoldOptgroupComponent, selector: "fold-optgroup", inputs: ["label"] }, { kind: "component", type: FoldPopoverComponent, selector: "fold-popover", inputs: ["placement", "fallbackPlacements", "offset", "padding", "autoFocus", "arrow", "open", "ariaControls"], outputs: ["openChange"] }, { kind: "directive", type: FoldPopoverTriggerDirective, selector: "[foldPopoverTrigger]", inputs: ["foldPopoverTrigger"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
9511
+ ], queries: [{ propertyName: "optionTemplate", first: true, predicate: ["option"], descendants: true, isSignal: true }, { propertyName: "projectedOptions", predicate: FoldOptionComponent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "renderedOptions", predicate: FoldOptionComponent, descendants: true, isSignal: true }, { propertyName: "list", first: true, predicate: ["list"], descendants: true, isSignal: true }], ngImport: i0, template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <fold-popover\n [(open)]=\"open\"\n [autoFocus]=\"false\"\n [ariaControls]=\"listId\"\n [placement]=\"placement()\"\n [fallbackPlacements]=\"['top-start', 'bottom-end', 'top-end']\"\n >\n <button\n type=\"button\"\n class=\"lb-trigger\"\n [id]=\"inputId\"\n foldPopoverTrigger=\"listbox\"\n [disabled]=\"disabled()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n @if (summaryLabel(); as lbl) {\n <span class=\"lb-value\">{{ lbl }}</span>\n } @else {\n <span class=\"lb-placeholder\">{{ placeholder() }}</span>\n }\n <fold-icon\n name=\"chevron-down\"\n size=\"sm\"\n class=\"lb-caret\"\n aria-hidden=\"true\"\n />\n </button>\n\n <div foldPopoverPanel class=\"lb-panel\">\n @if (showBulk()) {\n <div class=\"lb-bulk\" role=\"group\" aria-label=\"Bulk actions\">\n @if (allowSelectAll()) {\n <button\n type=\"button\"\n class=\"lb-bulk-btn\"\n [disabled]=\"allEnabledSelected()\"\n (click)=\"selectAll()\"\n >\n <fold-icon name=\"check-circle\" size=\"sm\" aria-hidden=\"true\" />\n {{ selectAllLabel() }}\n </button>\n }\n @if (allowClear()) {\n <button\n type=\"button\"\n class=\"lb-bulk-btn\"\n [disabled]=\"value().length === 0\"\n (click)=\"clearAll()\"\n >\n <fold-icon name=\"close\" size=\"sm\" aria-hidden=\"true\" />\n {{ clearWord() }}\n </button>\n }\n </div>\n }\n\n <div\n #list\n class=\"lb-list\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n tabindex=\"-1\"\n [id]=\"listId\"\n [attr.aria-label]=\"label()\"\n [attr.aria-activedescendant]=\"activeId()\"\n (keydown)=\"onListKeydown($event)\"\n (click)=\"onListClick($event)\"\n (pointermove)=\"onListPointermove($event)\"\n >\n @if (options(); as opts) {\n @for (item of opts; track $index) {\n @if (asGroup(item); as group) {\n <fold-optgroup [label]=\"group.label\">\n @for (o of group.options; track o.value) {\n <fold-option\n [value]=\"o.value\"\n [disabled]=\"o.disabled ?? false\"\n >\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: o }\"\n />\n } @else {\n {{ o.label }}\n }\n </fold-option>\n }\n </fold-optgroup>\n } @else if (asOption(item); as o) {\n <fold-option [value]=\"o.value\" [disabled]=\"o.disabled ?? false\">\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: o }\"\n />\n } @else {\n {{ o.label }}\n }\n </fold-option>\n }\n }\n } @else {\n <ng-content />\n }\n </div>\n </div>\n </fold-popover>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}.lb-trigger{all:unset;box-sizing:border-box;display:flex;align-items:center;gap:.5rem;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);cursor:pointer;transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}@media(prefers-reduced-motion:reduce){.lb-trigger{transition:none}}.lb-trigger:hover:not(:disabled){border-color:var(--fold-color-border)}.lb-trigger:focus-visible{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}.lb-trigger:disabled{opacity:.4;cursor:not-allowed}.lb-value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.lb-placeholder{color:var(--fold-color-text-faded)}.lb-caret{margin-inline-start:auto;color:var(--fold-color-text-muted)}.lb-field{position:relative}.lb-trigger.has-clear .lb-caret{visibility:hidden}.lb-clear{all:unset;position:absolute;inset-inline-end:.4rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;padding:.15rem;border-radius:var(--fold-radius-xs);color:var(--fold-color-text-muted);cursor:pointer}.lb-clear:hover,.lb-clear:focus-visible{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}:host(.sm) .lb-trigger{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) .lb-trigger{height:2.25rem;font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) .lb-trigger{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.panel) .lb-trigger{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) .lb-trigger:focus-visible{box-shadow:none}.lb-list{display:flex;flex-direction:column;gap:1px;min-width:var(--fold-popover-anchor-width, 11rem);outline:none}.lb-panel{display:flex;flex-direction:column}.lb-bulk{position:sticky;top:0;z-index:1;display:flex;gap:.25rem;padding:.25rem;margin-bottom:1px;background:var(--fold-color-surface-card);border-bottom:1px solid var(--fold-color-border-subtle)}.lb-bulk-btn{all:unset;display:inline-flex;align-items:center;gap:.3rem;padding:.3rem .5rem;border-radius:var(--fold-radius-sm);font-size:var(--fold-text-xs);color:var(--fold-color-text-secondary);cursor:pointer}.lb-bulk-btn:hover:not(:disabled){background:var(--fold-color-surface-hover);color:var(--fold-color-text)}.lb-bulk-btn:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:-2px}.lb-bulk-btn:disabled{opacity:.4;cursor:not-allowed}@media(forced-colors:active){.lb-bulk{border-bottom-color:CanvasText}}\n"], dependencies: [{ kind: "component", type: FoldInputBaseComponent, selector: "fold-input-base", inputs: ["label", "for", "required", "optional", "optionalLabel", "hint", "error", "info", "infoLabel"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }, { kind: "component", type: FoldOptionComponent, selector: "fold-option", inputs: ["value", "disabled"] }, { kind: "component", type: FoldOptgroupComponent, selector: "fold-optgroup", inputs: ["label"] }, { kind: "component", type: FoldPopoverComponent, selector: "fold-popover", inputs: ["placement", "fallbackPlacements", "offset", "padding", "autoFocus", "arrow", "open", "ariaControls"], outputs: ["openChange"] }, { kind: "directive", type: FoldPopoverTriggerDirective, selector: "[foldPopoverTrigger]", inputs: ["foldPopoverTrigger"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
9366
9512
  }
9367
9513
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldMultiselectComponent, decorators: [{
9368
9514
  type: Component,
@@ -9376,7 +9522,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
9376
9522
  NgTemplateOutlet,
9377
9523
  ], host: { "[class]": 'size() + " " + variant()' }, providers: [
9378
9524
  { provide: FOLD_LISTBOX_OWNER, useExisting: FoldMultiselectComponent },
9379
- ], template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <fold-popover\n [(open)]=\"open\"\n [autoFocus]=\"false\"\n [ariaControls]=\"listId\"\n [placement]=\"placement()\"\n [fallbackPlacements]=\"['top-start', 'bottom-end', 'top-end']\"\n >\n <button\n type=\"button\"\n class=\"lb-trigger\"\n [id]=\"inputId\"\n foldPopoverTrigger=\"listbox\"\n [disabled]=\"disabled()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n @if (summaryLabel(); as lbl) {\n <span class=\"lb-value\">{{ lbl }}</span>\n } @else {\n <span class=\"lb-placeholder\">{{ placeholder() }}</span>\n }\n <fold-icon\n name=\"chevron-down\"\n size=\"sm\"\n class=\"lb-caret\"\n aria-hidden=\"true\"\n />\n </button>\n\n <div foldPopoverPanel class=\"lb-panel\">\n @if (showBulk()) {\n <div class=\"lb-bulk\" role=\"group\" aria-label=\"Bulk actions\">\n @if (allowSelectAll()) {\n <button\n type=\"button\"\n class=\"lb-bulk-btn\"\n [disabled]=\"allEnabledSelected()\"\n (click)=\"selectAll()\"\n >\n <fold-icon name=\"check-circle\" size=\"sm\" aria-hidden=\"true\" />\n {{ selectAllLabel() }}\n </button>\n }\n @if (allowClear()) {\n <button\n type=\"button\"\n class=\"lb-bulk-btn\"\n [disabled]=\"value().length === 0\"\n (click)=\"clearAll()\"\n >\n <fold-icon name=\"close\" size=\"sm\" aria-hidden=\"true\" />\n {{ clearLabel() }}\n </button>\n }\n </div>\n }\n\n <div\n #list\n class=\"lb-list\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n tabindex=\"-1\"\n [id]=\"listId\"\n [attr.aria-label]=\"label()\"\n [attr.aria-activedescendant]=\"activeId()\"\n (keydown)=\"onListKeydown($event)\"\n (click)=\"onListClick($event)\"\n (pointermove)=\"onListPointermove($event)\"\n >\n @if (options(); as opts) {\n @for (item of opts; track $index) {\n @if (asGroup(item); as group) {\n <fold-optgroup [label]=\"group.label\">\n @for (o of group.options; track o.value) {\n <fold-option\n [value]=\"o.value\"\n [disabled]=\"o.disabled ?? false\"\n >\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: o }\"\n />\n } @else {\n {{ o.label }}\n }\n </fold-option>\n }\n </fold-optgroup>\n } @else if (asOption(item); as o) {\n <fold-option [value]=\"o.value\" [disabled]=\"o.disabled ?? false\">\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: o }\"\n />\n } @else {\n {{ o.label }}\n }\n </fold-option>\n }\n }\n } @else {\n <ng-content />\n }\n </div>\n </div>\n </fold-popover>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}.lb-trigger{all:unset;box-sizing:border-box;display:flex;align-items:center;gap:.5rem;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);cursor:pointer;transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}@media(prefers-reduced-motion:reduce){.lb-trigger{transition:none}}.lb-trigger:hover:not(:disabled){border-color:var(--fold-color-border)}.lb-trigger:focus-visible{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}.lb-trigger:disabled{opacity:.4;cursor:not-allowed}.lb-value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.lb-placeholder{color:var(--fold-color-text-faded)}.lb-caret{margin-inline-start:auto;color:var(--fold-color-text-muted)}.lb-field{position:relative}.lb-trigger.has-clear .lb-caret{visibility:hidden}.lb-clear{all:unset;position:absolute;inset-inline-end:.4rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;padding:.15rem;border-radius:var(--fold-radius-xs);color:var(--fold-color-text-muted);cursor:pointer}.lb-clear:hover,.lb-clear:focus-visible{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}:host(.sm) .lb-trigger{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) .lb-trigger{height:2.25rem;font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) .lb-trigger{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.panel) .lb-trigger{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) .lb-trigger:focus-visible{box-shadow:none}.lb-list{display:flex;flex-direction:column;gap:1px;min-width:var(--fold-popover-anchor-width, 11rem);outline:none}.lb-panel{display:flex;flex-direction:column}.lb-bulk{position:sticky;top:0;z-index:1;display:flex;gap:.25rem;padding:.25rem;margin-bottom:1px;background:var(--fold-color-surface-card);border-bottom:1px solid var(--fold-color-border-subtle)}.lb-bulk-btn{all:unset;display:inline-flex;align-items:center;gap:.3rem;padding:.3rem .5rem;border-radius:var(--fold-radius-sm);font-size:var(--fold-text-xs);color:var(--fold-color-text-secondary);cursor:pointer}.lb-bulk-btn:hover:not(:disabled){background:var(--fold-color-surface-hover);color:var(--fold-color-text)}.lb-bulk-btn:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:-2px}.lb-bulk-btn:disabled{opacity:.4;cursor:not-allowed}@media(forced-colors:active){.lb-bulk{border-bottom-color:CanvasText}}\n"] }]
9525
+ ], template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <fold-popover\n [(open)]=\"open\"\n [autoFocus]=\"false\"\n [ariaControls]=\"listId\"\n [placement]=\"placement()\"\n [fallbackPlacements]=\"['top-start', 'bottom-end', 'top-end']\"\n >\n <button\n type=\"button\"\n class=\"lb-trigger\"\n [id]=\"inputId\"\n foldPopoverTrigger=\"listbox\"\n [disabled]=\"disabled()\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n @if (summaryLabel(); as lbl) {\n <span class=\"lb-value\">{{ lbl }}</span>\n } @else {\n <span class=\"lb-placeholder\">{{ placeholder() }}</span>\n }\n <fold-icon\n name=\"chevron-down\"\n size=\"sm\"\n class=\"lb-caret\"\n aria-hidden=\"true\"\n />\n </button>\n\n <div foldPopoverPanel class=\"lb-panel\">\n @if (showBulk()) {\n <div class=\"lb-bulk\" role=\"group\" aria-label=\"Bulk actions\">\n @if (allowSelectAll()) {\n <button\n type=\"button\"\n class=\"lb-bulk-btn\"\n [disabled]=\"allEnabledSelected()\"\n (click)=\"selectAll()\"\n >\n <fold-icon name=\"check-circle\" size=\"sm\" aria-hidden=\"true\" />\n {{ selectAllLabel() }}\n </button>\n }\n @if (allowClear()) {\n <button\n type=\"button\"\n class=\"lb-bulk-btn\"\n [disabled]=\"value().length === 0\"\n (click)=\"clearAll()\"\n >\n <fold-icon name=\"close\" size=\"sm\" aria-hidden=\"true\" />\n {{ clearWord() }}\n </button>\n }\n </div>\n }\n\n <div\n #list\n class=\"lb-list\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n tabindex=\"-1\"\n [id]=\"listId\"\n [attr.aria-label]=\"label()\"\n [attr.aria-activedescendant]=\"activeId()\"\n (keydown)=\"onListKeydown($event)\"\n (click)=\"onListClick($event)\"\n (pointermove)=\"onListPointermove($event)\"\n >\n @if (options(); as opts) {\n @for (item of opts; track $index) {\n @if (asGroup(item); as group) {\n <fold-optgroup [label]=\"group.label\">\n @for (o of group.options; track o.value) {\n <fold-option\n [value]=\"o.value\"\n [disabled]=\"o.disabled ?? false\"\n >\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: o }\"\n />\n } @else {\n {{ o.label }}\n }\n </fold-option>\n }\n </fold-optgroup>\n } @else if (asOption(item); as o) {\n <fold-option [value]=\"o.value\" [disabled]=\"o.disabled ?? false\">\n @if (optionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl\"\n [ngTemplateOutletContext]=\"{ $implicit: o }\"\n />\n } @else {\n {{ o.label }}\n }\n </fold-option>\n }\n }\n } @else {\n <ng-content />\n }\n </div>\n </div>\n </fold-popover>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}.lb-trigger{all:unset;box-sizing:border-box;display:flex;align-items:center;gap:.5rem;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);cursor:pointer;transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}@media(prefers-reduced-motion:reduce){.lb-trigger{transition:none}}.lb-trigger:hover:not(:disabled){border-color:var(--fold-color-border)}.lb-trigger:focus-visible{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}.lb-trigger:disabled{opacity:.4;cursor:not-allowed}.lb-value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.lb-placeholder{color:var(--fold-color-text-faded)}.lb-caret{margin-inline-start:auto;color:var(--fold-color-text-muted)}.lb-field{position:relative}.lb-trigger.has-clear .lb-caret{visibility:hidden}.lb-clear{all:unset;position:absolute;inset-inline-end:.4rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;padding:.15rem;border-radius:var(--fold-radius-xs);color:var(--fold-color-text-muted);cursor:pointer}.lb-clear:hover,.lb-clear:focus-visible{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}:host(.sm) .lb-trigger{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) .lb-trigger{height:2.25rem;font-size:var(--fold-text-md);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) .lb-trigger{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.panel) .lb-trigger{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) .lb-trigger:focus-visible{box-shadow:none}.lb-list{display:flex;flex-direction:column;gap:1px;min-width:var(--fold-popover-anchor-width, 11rem);outline:none}.lb-panel{display:flex;flex-direction:column}.lb-bulk{position:sticky;top:0;z-index:1;display:flex;gap:.25rem;padding:.25rem;margin-bottom:1px;background:var(--fold-color-surface-card);border-bottom:1px solid var(--fold-color-border-subtle)}.lb-bulk-btn{all:unset;display:inline-flex;align-items:center;gap:.3rem;padding:.3rem .5rem;border-radius:var(--fold-radius-sm);font-size:var(--fold-text-xs);color:var(--fold-color-text-secondary);cursor:pointer}.lb-bulk-btn:hover:not(:disabled){background:var(--fold-color-surface-hover);color:var(--fold-color-text)}.lb-bulk-btn:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:-2px}.lb-bulk-btn:disabled{opacity:.4;cursor:not-allowed}@media(forced-colors:active){.lb-bulk{border-bottom-color:CanvasText}}\n"] }]
9380
9526
  }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "compareWith", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], optional: [{ type: i0.Input, args: [{ isSignal: true, alias: "optional", required: false }] }], optionalLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionalLabel", required: false }] }], info: [{ type: i0.Input, args: [{ isSignal: true, alias: "info", required: false }] }], infoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "infoLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], allowSelectAll: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowSelectAll", required: false }] }], allowClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowClear", required: false }] }], selectAllLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAllLabel", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], optionTemplate: [{ type: i0.ContentChild, args: ["option", { isSignal: true }] }], projectedOptions: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => FoldOptionComponent), { ...{ descendants: true }, isSignal: true }] }], renderedOptions: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => FoldOptionComponent), { isSignal: true }] }], list: [{ type: i0.ViewChild, args: ["list", { isSignal: true }] }] } });
9381
9527
 
9382
9528
  /** Build a rule from a `RegExp` — the common case. */
@@ -9490,7 +9636,7 @@ class FoldPasswordFieldComponent {
9490
9636
  effect(() => this.validChange.emit(this.allValid()));
9491
9637
  }
9492
9638
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldPasswordFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9493
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldPasswordFieldComponent, isStandalone: true, selector: "fold-password-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null }, revealable: { classPropertyName: "revealable", publicName: "revealable", isSignal: true, isRequired: false, transformFunction: null }, revealLabel: { classPropertyName: "revealLabel", publicName: "revealLabel", isSignal: true, isRequired: false, transformFunction: null }, hideLabel: { classPropertyName: "hideLabel", publicName: "hideLabel", isSignal: true, isRequired: false, transformFunction: null }, rules: { classPropertyName: "rules", publicName: "rules", isSignal: true, isRequired: false, transformFunction: null }, marker: { classPropertyName: "marker", publicName: "marker", isSignal: true, isRequired: false, transformFunction: null }, rulesLabel: { classPropertyName: "rulesLabel", publicName: "rulesLabel", isSignal: true, isRequired: false, transformFunction: null }, metLabel: { classPropertyName: "metLabel", publicName: "metLabel", isSignal: true, isRequired: false, transformFunction: null }, unmetLabel: { classPropertyName: "unmetLabel", publicName: "unmetLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange", validChange: "validChange" }, exportAs: ["foldPasswordField"], ngImport: i0, template: "<fold-input\n type=\"password\"\n [label]=\"label()\"\n [placeholder]=\"placeholder()\"\n [hint]=\"hint()\"\n [required]=\"required()\"\n [size]=\"size()\"\n [variant]=\"variant()\"\n [disabled]=\"disabled()\"\n [revealable]=\"revealable()\"\n [revealLabel]=\"revealLabel()\"\n [hideLabel]=\"hideLabel()\"\n [autocomplete]=\"autocomplete()\"\n [errors]=\"errors()\"\n [(value)]=\"value\"\n [(touched)]=\"touched\"\n/>\n\n<!-- Project into `[rules]` to redesign the checklist off the same state\n (`#pw=\"foldPasswordField\"` \u2192 `pw.checklist()`); otherwise the default list\n below is the fallback content. -->\n<ng-content select=\"[rules]\">\n @if (checklist().length) {\n <ul class=\"pw-rules\" [attr.aria-label]=\"rulesLabel()\" aria-live=\"polite\">\n @for (rule of checklist(); track rule.label) {\n <li class=\"pw-rule\" [class.is-met]=\"rule.met\">\n @if (marker() === \"check\") {\n <span class=\"pw-mark\" aria-hidden=\"true\">\n @if (rule.met) {\n <fold-icon name=\"check\" size=\"sm\" />\n }\n </span>\n } @else {\n <span class=\"pw-dot\" aria-hidden=\"true\"></span>\n }\n <span class=\"pw-rule-label\">{{ rule.label }}</span>\n <!-- The met/unmet word is real text (not just an attribute), so the\n aria-live region actually announces a rule flipping. -->\n <span class=\"pw-sr\"\n >\u2014 {{ rule.met ? metLabel() : unmetLabel() }}</span\n >\n </li>\n }\n </ul>\n }\n</ng-content>\n", styles: [":host{display:block}.pw-rules{list-style:none;margin:.5rem 0 0;padding:0;display:flex;flex-direction:column;gap:.25rem}.pw-rule{display:flex;align-items:center;gap:.45rem;font-size:var(--fold-text-xs);color:var(--fold-color-text-muted);transition:color var(--fold-motion-fast)}.pw-dot{flex:none;width:.5rem;height:.5rem;border-radius:var(--fold-radius-round);border:1.5px solid var(--fold-color-text-faded);box-sizing:border-box;transition:background var(--fold-motion-fast),border-color var(--fold-motion-fast)}.pw-rule.is-met{color:var(--fold-color-text)}.pw-rule.is-met .pw-dot{border-color:var(--fold-color-primary);background:var(--fold-color-primary)}.pw-mark{flex:none;width:.85rem;height:.85rem;display:grid;place-items:center;color:var(--fold-color-primary)}.pw-rule:not(.is-met) .pw-mark{border:1.5px solid var(--fold-color-text-faded);border-radius:var(--fold-radius-round);box-sizing:border-box}@media(forced-colors:active){.pw-rule.is-met .pw-dot{background:Highlight;border-color:Highlight}.pw-mark{color:Highlight}}.pw-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: FoldInputComponent, selector: "fold-input", inputs: ["value", "disabled", "touched", "errors", "type", "revealable", "revealLabel", "hideLabel", "size", "align", "variant", "label", "required", "optional", "optionalLabel", "info", "infoLabel", "hint", "placeholder", "readOnly", "autofocus", "autocomplete"], outputs: ["valueChange", "touchedChange"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
9639
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldPasswordFieldComponent, isStandalone: true, selector: "fold-password-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null }, revealable: { classPropertyName: "revealable", publicName: "revealable", isSignal: true, isRequired: false, transformFunction: null }, revealLabel: { classPropertyName: "revealLabel", publicName: "revealLabel", isSignal: true, isRequired: false, transformFunction: null }, hideLabel: { classPropertyName: "hideLabel", publicName: "hideLabel", isSignal: true, isRequired: false, transformFunction: null }, rules: { classPropertyName: "rules", publicName: "rules", isSignal: true, isRequired: false, transformFunction: null }, marker: { classPropertyName: "marker", publicName: "marker", isSignal: true, isRequired: false, transformFunction: null }, rulesLabel: { classPropertyName: "rulesLabel", publicName: "rulesLabel", isSignal: true, isRequired: false, transformFunction: null }, metLabel: { classPropertyName: "metLabel", publicName: "metLabel", isSignal: true, isRequired: false, transformFunction: null }, unmetLabel: { classPropertyName: "unmetLabel", publicName: "unmetLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange", validChange: "validChange" }, exportAs: ["foldPasswordField"], ngImport: i0, template: "<fold-input\n type=\"password\"\n [label]=\"label()\"\n [placeholder]=\"placeholder()\"\n [hint]=\"hint()\"\n [required]=\"required()\"\n [size]=\"size()\"\n [variant]=\"variant()\"\n [disabled]=\"disabled()\"\n [revealable]=\"revealable()\"\n [revealLabel]=\"revealLabel()\"\n [hideLabel]=\"hideLabel()\"\n [autocomplete]=\"autocomplete()\"\n [errors]=\"errors()\"\n [(value)]=\"value\"\n [(touched)]=\"touched\"\n/>\n\n<!-- Project into `[rules]` to redesign the checklist off the same state\n (`#pw=\"foldPasswordField\"` \u2192 `pw.checklist()`); otherwise the default list\n below is the fallback content. -->\n<ng-content select=\"[rules]\">\n @if (checklist().length) {\n <ul class=\"pw-rules\" [attr.aria-label]=\"rulesLabel()\" aria-live=\"polite\">\n @for (rule of checklist(); track rule.label) {\n <li class=\"pw-rule\" [class.is-met]=\"rule.met\">\n @if (marker() === \"check\") {\n <span class=\"pw-mark\" aria-hidden=\"true\">\n @if (rule.met) {\n <fold-icon name=\"check\" size=\"sm\" />\n }\n </span>\n } @else {\n <span class=\"pw-dot\" aria-hidden=\"true\"></span>\n }\n <span class=\"pw-rule-label\">{{ rule.label }}</span>\n <!-- The met/unmet word is real text (not just an attribute), so the\n aria-live region actually announces a rule flipping. -->\n <span class=\"pw-sr\"\n >\u2014 {{ rule.met ? metLabel() : unmetLabel() }}</span\n >\n </li>\n }\n </ul>\n }\n</ng-content>\n", styles: [":host{display:block}.pw-rules{list-style:none;margin:.5rem 0 0;padding:0;display:flex;flex-direction:column;gap:.25rem}.pw-rule{display:flex;align-items:center;gap:.45rem;font-size:var(--fold-text-xs);color:var(--fold-color-text-muted);transition:color var(--fold-motion-fast)}.pw-dot{flex:none;width:.5rem;height:.5rem;border-radius:var(--fold-radius-round);border:1.5px solid var(--fold-color-text-faded);box-sizing:border-box;transition:background var(--fold-motion-fast),border-color var(--fold-motion-fast)}.pw-rule.is-met{color:var(--fold-color-text)}.pw-rule.is-met .pw-dot{border-color:var(--fold-color-primary);background:var(--fold-color-primary)}.pw-mark{flex:none;width:.85rem;height:.85rem;display:grid;place-items:center;color:var(--fold-color-primary)}.pw-rule:not(.is-met) .pw-mark{border:1.5px solid var(--fold-color-text-faded);border-radius:var(--fold-radius-round);box-sizing:border-box}@media(forced-colors:active){.pw-rule.is-met .pw-dot{background:Highlight;border-color:Highlight}.pw-mark{color:Highlight}}.pw-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: FoldInputComponent, selector: "fold-input", inputs: ["value", "disabled", "touched", "errors", "type", "revealable", "revealLabel", "hideLabel", "size", "align", "variant", "label", "required", "optional", "optionalLabel", "info", "infoLabel", "ariaLabel", "hint", "placeholder", "readOnly", "autofocus", "autocomplete"], outputs: ["valueChange", "touchedChange"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
9494
9640
  }
9495
9641
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldPasswordFieldComponent, decorators: [{
9496
9642
  type: Component,
@@ -10200,28 +10346,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
10200
10346
  */
10201
10347
  class FoldLoadingStateComponent {
10202
10348
  /** Text to display. Defaults to "Loading...". */
10203
- message = input("Loading...", /* @ts-ignore */
10204
- ...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
10349
+ message = input(/* @ts-ignore */
10350
+ ...(ngDevMode ? [undefined, { debugName: "message" }] : /* istanbul ignore next */ []));
10205
10351
  /** Spinner size — an icon-size token (`xs…xl`, default `md`) or a pixel number. */
10206
10352
  size = input("md", /* @ts-ignore */
10207
10353
  ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
10354
+ common = inject(FOLD_COMMON_LABELS);
10355
+ /** English default ← app-wide provider ← this instance's own input. */
10356
+ text = computed(() => this.message() ?? this.common.loading, /* @ts-ignore */
10357
+ ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
10208
10358
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldLoadingStateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10209
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldLoadingStateComponent, isStandalone: true, selector: "fold-loading", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "status", "aria-live": "polite" } }, ngImport: i0, template: "<div class=\"loading\">\n <fold-spinner [size]=\"size()\" aria-hidden=\"true\" />\n @if (message()) {\n <span>{{ message() }}</span>\n }\n</div>\n", styles: [":host{display:flex;align-items:center;justify-content:center;flex:1}.loading{display:flex;flex-direction:column;align-items:center;gap:var(--fold-space-sm);color:var(--fold-color-text-muted);font-size:var(--fold-text-sm)}\n"], dependencies: [{ kind: "component", type: FoldSpinnerComponent, selector: "fold-spinner", inputs: ["size", "label"] }] });
10359
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldLoadingStateComponent, isStandalone: true, selector: "fold-loading", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "status", "aria-live": "polite" } }, ngImport: i0, template: "<div class=\"loading\">\n <fold-spinner [size]=\"size()\" aria-hidden=\"true\" />\n @if (text(); as message) {\n <span>{{ message }}</span>\n }\n</div>\n", styles: [":host{display:flex;align-items:center;justify-content:center;flex:1}.loading{display:flex;flex-direction:column;align-items:center;gap:var(--fold-space-sm);color:var(--fold-color-text-muted);font-size:var(--fold-text-sm)}\n"], dependencies: [{ kind: "component", type: FoldSpinnerComponent, selector: "fold-spinner", inputs: ["size", "label"] }] });
10210
10360
  }
10211
10361
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldLoadingStateComponent, decorators: [{
10212
10362
  type: Component,
10213
10363
  args: [{ selector: "fold-loading", standalone: true, imports: [FoldSpinnerComponent], host: {
10214
10364
  role: "status",
10215
10365
  "aria-live": "polite",
10216
- }, template: "<div class=\"loading\">\n <fold-spinner [size]=\"size()\" aria-hidden=\"true\" />\n @if (message()) {\n <span>{{ message() }}</span>\n }\n</div>\n", styles: [":host{display:flex;align-items:center;justify-content:center;flex:1}.loading{display:flex;flex-direction:column;align-items:center;gap:var(--fold-space-sm);color:var(--fold-color-text-muted);font-size:var(--fold-text-sm)}\n"] }]
10366
+ }, template: "<div class=\"loading\">\n <fold-spinner [size]=\"size()\" aria-hidden=\"true\" />\n @if (text(); as message) {\n <span>{{ message }}</span>\n }\n</div>\n", styles: [":host{display:flex;align-items:center;justify-content:center;flex:1}.loading{display:flex;flex-direction:column;align-items:center;gap:var(--fold-space-sm);color:var(--fold-color-text-muted);font-size:var(--fold-text-sm)}\n"] }]
10217
10367
  }], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
10218
10368
 
10219
10369
  /**
10220
10370
  * `<fold-empty-state>` — centered empty state with an optional icon, a title, an
10221
10371
  * optional subtitle and an optional action.
10222
10372
  *
10223
- * Content projection carries the icon and the action:
10224
- * - `[empty-icon]` — projected above the title (typically an SVG)
10373
+ * The glyph comes from `icon` — a registered icon name, the common case:
10374
+ *
10375
+ * ```html
10376
+ * <fold-empty-state icon="inbox" title="Nothing here" />
10377
+ * ```
10378
+ *
10379
+ * Content projection carries a custom illustration and the action:
10380
+ * - `[empty-icon]` — projected above the title, for art the registry can't hold
10381
+ * (a bespoke SVG, an image). It **wins** over `icon` when both are given.
10225
10382
  * - default `ng-content` — projected below the subtitle (typically a button)
10226
10383
  *
10227
10384
  * `tone="alert"` turns it into an error state (red title + icon); the default
@@ -10251,16 +10408,28 @@ class FoldEmptyStateComponent {
10251
10408
  /** Optional muted secondary line. */
10252
10409
  subtitle = input("", /* @ts-ignore */
10253
10410
  ...(ngDevMode ? [{ debugName: "subtitle" }] : /* istanbul ignore next */ []));
10411
+ /**
10412
+ * The glyph above the title, by registered name — the common case, so the
10413
+ * caller doesn't have to know a slot exists.
10414
+ *
10415
+ * A **projected** `[empty-icon]` wins: the slot stays the way to supply art
10416
+ * the registry can't hold (rule 4.7's illustration exception).
10417
+ */
10418
+ icon = input(/* @ts-ignore */
10419
+ ...(ngDevMode ? [undefined, { debugName: "icon" }] : /* istanbul ignore next */ []));
10420
+ /** Size of the `icon` glyph. Projected art sizes itself. @default 'xl' */
10421
+ iconSize = input("xl", /* @ts-ignore */
10422
+ ...(ngDevMode ? [{ debugName: "iconSize" }] : /* istanbul ignore next */ []));
10254
10423
  /** `alert` renders an error state (red title + icon); `neutral` is default. */
10255
10424
  tone = input("neutral", /* @ts-ignore */
10256
10425
  ...(ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []));
10257
10426
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldEmptyStateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10258
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldEmptyStateComponent, isStandalone: true, selector: "fold-empty-state", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.alert": "tone() === 'alert'", "attr.title": "null" } }, ngImport: i0, template: "<div class=\"empty\">\n <div class=\"empty-icon\">\n <ng-content select=\"[empty-icon]\" />\n </div>\n <p class=\"empty-title\">{{ title() }}</p>\n @if (subtitle()) {\n <p class=\"empty-sub\">{{ subtitle() }}</p>\n }\n <div class=\"empty-action\">\n <ng-content />\n </div>\n</div>\n", styles: [":host{display:flex;align-items:center;justify-content:center;flex:1}.empty{display:flex;flex-direction:column;align-items:center;gap:var(--fold-space-sm);padding:var(--fold-space-4xl) var(--fold-space-2xl)}.empty-icon{color:var(--fold-color-text-faded);margin-bottom:var(--fold-space-xs)}.empty-icon:empty{display:none}.empty-title{font-size:var(--fold-text-sm);font-weight:600;color:var(--fold-color-text);margin:0}.empty-sub{font-size:var(--fold-text-xs);color:var(--fold-color-text-muted);margin:0;text-align:center;max-width:320px;line-height:1.6}.empty-action{margin-top:var(--fold-space-xs)}.empty-action:empty{display:none}:host(.alert) .empty-icon,:host(.alert) .empty-title{color:var(--fold-color-alert-text)}\n"] });
10427
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldEmptyStateComponent, isStandalone: true, selector: "fold-empty-state", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconSize: { classPropertyName: "iconSize", publicName: "iconSize", isSignal: true, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.alert": "tone() === 'alert'", "attr.title": "null" } }, ngImport: i0, template: "<div class=\"empty\">\n <div class=\"empty-icon\">\n <ng-content select=\"[empty-icon]\" />\n <!-- Precedence is decided in CSS (`:has`), not by DOM order: sitting side\n by side here, both would simply render. -->\n @if (icon(); as name) {\n <fold-icon [name]=\"name\" [size]=\"iconSize()\" />\n }\n </div>\n <p class=\"empty-title\">{{ title() }}</p>\n @if (subtitle()) {\n <p class=\"empty-sub\">{{ subtitle() }}</p>\n }\n <div class=\"empty-action\">\n <ng-content />\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;align-items:center;justify-content:center;flex:1}.empty{display:flex;flex-direction:column;align-items:center;gap:var(--fold-space-sm);padding:var(--fold-space-4xl) var(--fold-space-2xl)}.empty-icon{color:var(--fold-color-text-faded);margin-bottom:var(--fold-space-xs)}.empty-icon:not(:has(*)){display:none}.empty-icon:has([empty-icon]) fold-icon{display:none}.empty-title{font-size:var(--fold-text-sm);font-weight:600;color:var(--fold-color-text);margin:0}.empty-sub{font-size:var(--fold-text-xs);color:var(--fold-color-text-muted);margin:0;text-align:center;max-width:320px;line-height:1.6}.empty-action{margin-top:var(--fold-space-xs)}.empty-action:empty{display:none}:host(.alert) .empty-icon,:host(.alert) .empty-title{color:var(--fold-color-alert-text)}\n"], dependencies: [{ kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
10259
10428
  }
10260
10429
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldEmptyStateComponent, decorators: [{
10261
10430
  type: Component,
10262
- args: [{ selector: "fold-empty-state", standalone: true, host: { "[class.alert]": "tone() === 'alert'", "[attr.title]": "null" }, template: "<div class=\"empty\">\n <div class=\"empty-icon\">\n <ng-content select=\"[empty-icon]\" />\n </div>\n <p class=\"empty-title\">{{ title() }}</p>\n @if (subtitle()) {\n <p class=\"empty-sub\">{{ subtitle() }}</p>\n }\n <div class=\"empty-action\">\n <ng-content />\n </div>\n</div>\n", styles: [":host{display:flex;align-items:center;justify-content:center;flex:1}.empty{display:flex;flex-direction:column;align-items:center;gap:var(--fold-space-sm);padding:var(--fold-space-4xl) var(--fold-space-2xl)}.empty-icon{color:var(--fold-color-text-faded);margin-bottom:var(--fold-space-xs)}.empty-icon:empty{display:none}.empty-title{font-size:var(--fold-text-sm);font-weight:600;color:var(--fold-color-text);margin:0}.empty-sub{font-size:var(--fold-text-xs);color:var(--fold-color-text-muted);margin:0;text-align:center;max-width:320px;line-height:1.6}.empty-action{margin-top:var(--fold-space-xs)}.empty-action:empty{display:none}:host(.alert) .empty-icon,:host(.alert) .empty-title{color:var(--fold-color-alert-text)}\n"] }]
10263
- }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }] } });
10431
+ args: [{ selector: "fold-empty-state", standalone: true, imports: [FoldIconComponent], host: { "[class.alert]": "tone() === 'alert'", "[attr.title]": "null" }, template: "<div class=\"empty\">\n <div class=\"empty-icon\">\n <ng-content select=\"[empty-icon]\" />\n <!-- Precedence is decided in CSS (`:has`), not by DOM order: sitting side\n by side here, both would simply render. -->\n @if (icon(); as name) {\n <fold-icon [name]=\"name\" [size]=\"iconSize()\" />\n }\n </div>\n <p class=\"empty-title\">{{ title() }}</p>\n @if (subtitle()) {\n <p class=\"empty-sub\">{{ subtitle() }}</p>\n }\n <div class=\"empty-action\">\n <ng-content />\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;align-items:center;justify-content:center;flex:1}.empty{display:flex;flex-direction:column;align-items:center;gap:var(--fold-space-sm);padding:var(--fold-space-4xl) var(--fold-space-2xl)}.empty-icon{color:var(--fold-color-text-faded);margin-bottom:var(--fold-space-xs)}.empty-icon:not(:has(*)){display:none}.empty-icon:has([empty-icon]) fold-icon{display:none}.empty-title{font-size:var(--fold-text-sm);font-weight:600;color:var(--fold-color-text);margin:0}.empty-sub{font-size:var(--fold-text-xs);color:var(--fold-color-text-muted);margin:0;text-align:center;max-width:320px;line-height:1.6}.empty-action{margin-top:var(--fold-space-xs)}.empty-action:empty{display:none}:host(.alert) .empty-icon,:host(.alert) .empty-title{color:var(--fold-color-alert-text)}\n"] }]
10432
+ }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], iconSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconSize", required: false }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }] } });
10264
10433
 
10265
10434
  /**
10266
10435
  * `<fold-aside-layout>` — a centered, self-scrolling content column flanked by
@@ -10498,13 +10667,13 @@ class FoldNavLayoutComponent {
10498
10667
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldNavLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10499
10668
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.8", type: FoldNavLayoutComponent, isStandalone: true, selector: "fold-nav-layout", inputs: { placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, foldAt: { classPropertyName: "foldAt", publicName: "foldAt", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.is-row": "!stacked()" } }, providers: [
10500
10669
  { provide: FOLD_NAV_LAYOUT, useExisting: FoldNavLayoutComponent },
10501
- ], exportAs: ["foldNavLayout"], ngImport: i0, template: "<div class=\"tl-nav\"><ng-content select=\"[tabNav]\" /></div>\n<div class=\"tl-body\"><ng-content /></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;gap:var(--fold-nav-layout-gap, var(--fold-space-lg, 16px))}@media(max-width:640px){:host{gap:var(--fold-nav-layout-gap, var(--fold-space-xs, 4px))}}:host{min-width:0}:host(.is-row){flex-direction:row}.tl-nav{display:grid;min-width:0}:host(.is-row) .tl-nav{flex:0 0 var(--fold-nav-layout-rail-width, var(--fold-rail-tertiary, 200px))}.tl-body{flex:1 1 auto;min-width:0}@media(max-width:640px){.tl-body{--fold-page-gutter: 0px}}\n"] });
10670
+ ], exportAs: ["foldNavLayout"], ngImport: i0, template: "<div class=\"tl-nav\"><ng-content select=\"[tabNav]\" /></div>\n<div class=\"tl-body\"><ng-content /></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;gap:var(--fold-nav-layout-gap, var(--fold-space-lg, 16px))}@media(max-width:640px){:host{gap:var(--fold-nav-layout-gap, var(--fold-space-xs, 4px))}}:host{min-width:0}:host(.is-row){flex-direction:row}.tl-nav{display:grid;min-width:0}:host(.is-row) .tl-nav{flex:0 0 var(--fold-nav-layout-rail-width, var(--fold-rail-tertiary, 200px))}.tl-body{flex:1 1 auto;min-width:0}.tl-body{--fold-page-gutter: 0px}\n"] });
10502
10671
  }
10503
10672
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldNavLayoutComponent, decorators: [{
10504
10673
  type: Component,
10505
10674
  args: [{ selector: "fold-nav-layout", standalone: true, exportAs: "foldNavLayout", host: { "[class.is-row]": "!stacked()" }, providers: [
10506
10675
  { provide: FOLD_NAV_LAYOUT, useExisting: FoldNavLayoutComponent },
10507
- ], template: "<div class=\"tl-nav\"><ng-content select=\"[tabNav]\" /></div>\n<div class=\"tl-body\"><ng-content /></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;gap:var(--fold-nav-layout-gap, var(--fold-space-lg, 16px))}@media(max-width:640px){:host{gap:var(--fold-nav-layout-gap, var(--fold-space-xs, 4px))}}:host{min-width:0}:host(.is-row){flex-direction:row}.tl-nav{display:grid;min-width:0}:host(.is-row) .tl-nav{flex:0 0 var(--fold-nav-layout-rail-width, var(--fold-rail-tertiary, 200px))}.tl-body{flex:1 1 auto;min-width:0}@media(max-width:640px){.tl-body{--fold-page-gutter: 0px}}\n"] }]
10676
+ ], template: "<div class=\"tl-nav\"><ng-content select=\"[tabNav]\" /></div>\n<div class=\"tl-body\"><ng-content /></div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;flex-direction:column;gap:var(--fold-nav-layout-gap, var(--fold-space-lg, 16px))}@media(max-width:640px){:host{gap:var(--fold-nav-layout-gap, var(--fold-space-xs, 4px))}}:host{min-width:0}:host(.is-row){flex-direction:row}.tl-nav{display:grid;min-width:0}:host(.is-row) .tl-nav{flex:0 0 var(--fold-nav-layout-rail-width, var(--fold-rail-tertiary, 200px))}.tl-body{flex:1 1 auto;min-width:0}.tl-body{--fold-page-gutter: 0px}\n"] }]
10508
10677
  }], ctorParameters: () => [], propDecorators: { placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], foldAt: [{ type: i0.Input, args: [{ isSignal: true, alias: "foldAt", required: false }] }] } });
10509
10678
 
10510
10679
  /**
@@ -11069,6 +11238,13 @@ class FoldViewNavComponent {
11069
11238
  * `link`). Bind `[(activeKey)]` and a click writes the new key back; there is
11070
11239
  * no separate change output (the model is the one way). Link items ignore it:
11071
11240
  * their active state comes from the URL via `routerLinkActive`.
11241
+ *
11242
+ * **Deliberately `string`, where {@link FoldTabsComponent.activeKey} is
11243
+ * generic.** This model has a zero value — `""`, "no item selected", the state
11244
+ * a bar of pure link items sits in forever. No caller's union of view keys
11245
+ * contains `""`, so a generic `K` here would have to be `K | ""` and hand the
11246
+ * narrowing back to the caller — the very burden the generic exists to remove.
11247
+ * `fold-tabs` has no such zero value (`model.required`), which is why it can.
11072
11248
  */
11073
11249
  activeKey = model("", /* @ts-ignore */
11074
11250
  ...(ngDevMode ? [{ debugName: "activeKey" }] : /* istanbul ignore next */ []));
@@ -11108,6 +11284,14 @@ class FoldViewNavComponent {
11108
11284
  */
11109
11285
  background = input("transparent", /* @ts-ignore */
11110
11286
  ...(ngDevMode ? [{ debugName: "background" }] : /* istanbul ignore next */ []));
11287
+ /**
11288
+ * Pin the bar to the top of its scroll container, so a long view can be
11289
+ * navigated without scrolling back up. Pair it with the default
11290
+ * `background="surface"`: a `transparent` bar would let the content scroll
11291
+ * through it. Bleeding the bar to the page's edges stays the page's business
11292
+ * — the page owns the gutter.
11293
+ */
11294
+ sticky = input(false, { ...(ngDevMode ? { debugName: "sticky" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
11111
11295
  /** The nearest layout, if any — lets `direction="auto"` follow it. */
11112
11296
  layout = inject(FOLD_NAV_LAYOUT, { optional: true });
11113
11297
  /**
@@ -11127,7 +11311,7 @@ class FoldViewNavComponent {
11127
11311
  }, /* @ts-ignore */
11128
11312
  ...(ngDevMode ? [{ debugName: "resolvedDirection" }] : /* istanbul ignore next */ []));
11129
11313
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldViewNavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11130
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldViewNavComponent, isStandalone: true, selector: "fold-view-nav", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, activeKey: { classPropertyName: "activeKey", publicName: "activeKey", isSignal: true, isRequired: false, transformFunction: null }, activeStyle: { classPropertyName: "activeStyle", publicName: "activeStyle", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, background: { classPropertyName: "background", publicName: "background", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeKey: "activeKeyChange" }, host: { properties: { "class.is-standalone": "isStandalone()", "class.is-horizontal": "resolvedDirection() === 'horizontal'" } }, ngImport: i0, template: "<nav\n class=\"tab-bar\"\n [class.style-underline]=\"activeStyle() === 'underline'\"\n [class.style-fill]=\"activeStyle() === 'fill'\"\n [class.dir-vertical]=\"resolvedDirection() === 'vertical'\"\n [class.size-comfortable]=\"size() === 'comfortable'\"\n [class.is-collapsed]=\"collapsed()\"\n [class.bg-surface]=\"background() === 'surface'\"\n>\n @for (item of items(); track item.key) {\n @if (item.disabled) {\n <button\n type=\"button\"\n class=\"tab-bar-item is-disabled\"\n disabled\n aria-disabled=\"true\"\n >\n <ng-container\n [ngTemplateOutlet]=\"body\"\n [ngTemplateOutletContext]=\"{ $implicit: item, active: false }\"\n />\n </button>\n } @else if (item.link !== undefined) {\n <a\n class=\"tab-bar-item\"\n [routerLink]=\"item.link\"\n routerLinkActive=\"is-active\"\n #rla=\"routerLinkActive\"\n [attr.aria-current]=\"rla.isActive ? 'page' : null\"\n >\n <ng-container\n [ngTemplateOutlet]=\"body\"\n [ngTemplateOutletContext]=\"{ $implicit: item, active: rla.isActive }\"\n />\n </a>\n } @else if (item.href !== undefined) {\n <a\n class=\"tab-bar-item\"\n [href]=\"item.href\"\n [class.is-active]=\"activeKey() === item.key\"\n [attr.aria-current]=\"activeKey() === item.key ? 'page' : null\"\n >\n <ng-container\n [ngTemplateOutlet]=\"body\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n active: activeKey() === item.key,\n }\"\n />\n </a>\n } @else {\n <button\n type=\"button\"\n class=\"tab-bar-item\"\n [class.is-active]=\"activeKey() === item.key\"\n [attr.aria-current]=\"activeKey() === item.key ? 'page' : null\"\n (click)=\"activeKey.set(item.key)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"body\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n active: activeKey() === item.key,\n }\"\n />\n </button>\n }\n }\n</nav>\n\n<!-- One item's inner content, shared by the link / button branches. -->\n<ng-template #body let-item let-active=\"active\">\n @if (item.icon; as ic) {\n <fold-icon class=\"tab-bar-icon\" [name]=\"ic\" size=\"sm\" />\n } @else if (collapsed()) {\n <!-- Collapsed needs a fixed glyph; an icon-less item falls back to its\n initial so the rail stays icon-width and the label still tooltips. -->\n <span class=\"tab-bar-icon tab-bar-initial\" aria-hidden=\"true\">{{\n item.label.charAt(0)\n }}</span>\n }\n <span class=\"tab-bar-label\">{{ item.label }}</span>\n @if (item.badge !== undefined && item.badge !== null) {\n <fold-badge\n class=\"tab-bar-badge\"\n [content]=\"item.badge + ''\"\n [variant]=\"active ? 'accent' : 'neutral'\"\n />\n }\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host{display:flex;width:100%;max-width:100%;overflow:hidden}:host:has(.tab-bar:not(.dir-vertical):not(.is-collapsed)){overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;overscroll-behavior-x:contain}:host:has(.tab-bar:not(.dir-vertical):not(.is-collapsed)) .tab-bar{min-width:max-content;max-width:none}.tab-bar{flex:1;display:flex;max-width:100%;gap:2px;-webkit-user-select:none;user-select:none}.bg-surface{background:linear-gradient(var(--fold-color-bg-rail-tertiary),var(--fold-color-bg-rail-tertiary)),var(--fold-color-bg-page);padding:var(--fold-space-xs) var(--fold-space-sm) 0}.bg-surface.dir-vertical{padding:var(--fold-space-md) var(--fold-space-sm)}.tab-bar-item{flex:1;display:flex;align-items:center;justify-content:center;gap:var(--fold-space-sm);padding:var(--fold-space-sm) var(--fold-space-sm);background:none;border:none;color:var(--fold-color-text-muted);font-family:inherit;font-size:10px;font-weight:600;cursor:pointer;text-align:center;text-decoration:none;transition:color .1s ease,background .1s ease,border-color .1s ease;white-space:nowrap}.tab-bar-item:hover{color:var(--fold-color-text-secondary)}.tab-bar-item.is-disabled{opacity:.5;cursor:default;pointer-events:none}.size-comfortable .tab-bar-item{flex:0 1 auto;gap:var(--fold-space-sm);padding:var(--fold-space-md) var(--fold-space-lg);font-size:var(--fold-text-sm)}.dir-vertical.size-comfortable .tab-bar-item{padding:var(--fold-space-md) var(--fold-space-md);font-size:var(--fold-text-md)}.style-underline{border-bottom:1px solid var(--fold-color-border)}.style-underline .tab-bar-item{border-bottom:2px solid transparent;margin-bottom:-1px}.style-underline .tab-bar-item.is-active{color:var(--fold-color-text);border-bottom-color:var(--fold-color-primary)}.style-fill .tab-bar-item{border-radius:var(--fold-radius-sm);border:1px solid transparent}.style-fill .tab-bar-item.is-active{background:var(--fold-color-primary-surface);color:var(--fold-color-primary-text);font-weight:600}.style-fill .tab-bar-item:hover:not(.is-active){background:var(--fold-color-surface-hover);color:var(--fold-color-text)}.dir-vertical{flex-direction:column}.dir-vertical .tab-bar-item{flex:none;justify-content:flex-start;text-align:left;padding:var(--fold-space-sm) var(--fold-space-md);gap:var(--fold-space-sm);border-radius:var(--fold-radius-sm);font-size:var(--fold-text-sm);font-weight:500}.dir-vertical.style-underline{border-bottom:none;border-right:1px solid var(--fold-color-border)}.dir-vertical.style-underline .tab-bar-item{border-bottom:none;border-left:2px solid transparent;margin-bottom:0;margin-right:-1px}.dir-vertical.style-underline .tab-bar-item.is-active{border-left-color:var(--fold-color-primary)}.dir-vertical.style-fill .tab-bar-item.is-active{background:var(--fold-color-primary-surface);color:var(--fold-color-primary-text);font-weight:600}.is-collapsed .tab-bar-item{position:relative;flex:0 0 auto;gap:0}.is-collapsed .tab-bar-item:not(.is-active) .tab-bar-badge{display:none}.is-collapsed .tab-bar-item.is-active{flex:1 1 auto;min-width:0;gap:var(--fold-space-sm)}.is-collapsed .tab-bar-item.is-active .tab-bar-label{overflow:hidden;text-overflow:ellipsis}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active) .tab-bar-icon~.tab-bar-label{position:absolute;padding:var(--fold-space-xs) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-glass);border:1px solid var(--fold-color-glass-border);color:var(--fold-color-text);font-size:var(--fold-text-xs);font-weight:500;white-space:nowrap;opacity:0;pointer-events:none;box-shadow:var(--fold-shadow-md);transition:opacity var(--fold-motion-fast);z-index:100}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-icon~.tab-bar-label{left:calc(100% + 8px);top:50%;transform:translateY(-50%)}.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active) .tab-bar-icon~.tab-bar-label{top:calc(100% + 6px);left:50%;transform:translate(-50%)}.dir-vertical.is-collapsed .tab-bar-item:hover .tab-bar-icon~.tab-bar-label,.dir-vertical.is-collapsed .tab-bar-item:focus-visible .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active):hover .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active):focus-visible .tab-bar-icon~.tab-bar-label{opacity:1}.dir-vertical.is-collapsed{align-items:center}.dir-vertical.is-collapsed .tab-bar-item,.dir-vertical.is-collapsed .tab-bar-item.is-active{justify-content:center;gap:0}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-badge{display:block;position:absolute;top:-2px;right:-2px;transform:scale(.85);transform-origin:top right;pointer-events:none}:host:has(.is-collapsed){overflow:visible}.tab-bar-icon{flex-shrink:0}.tab-bar-initial{display:grid;place-items:center;width:18px;height:18px;border-radius:var(--fold-radius-sm);font-size:11px;font-weight:700;line-height:1;text-transform:uppercase}.tab-bar-badge{flex-shrink:0;font-variant-numeric:tabular-nums}.tab-bar-item:focus-visible{outline:2px solid var(--fold-color-primary);outline-offset:-2px;border-radius:var(--fold-radius-sm)}:host(.is-standalone.is-horizontal){margin-block-end:var(--fold-nav-layout-gap, var(--fold-space-lg, 16px))}@media(max-width:640px){:host(.is-standalone.is-horizontal){margin-block-end:var(--fold-nav-layout-gap, var(--fold-space-xs, 4px))}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }, { kind: "component", type: FoldBadgeComponent, selector: "fold-badge", inputs: ["content", "radius", "variant"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] });
11314
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldViewNavComponent, isStandalone: true, selector: "fold-view-nav", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, activeKey: { classPropertyName: "activeKey", publicName: "activeKey", isSignal: true, isRequired: false, transformFunction: null }, activeStyle: { classPropertyName: "activeStyle", publicName: "activeStyle", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, background: { classPropertyName: "background", publicName: "background", isSignal: true, isRequired: false, transformFunction: null }, sticky: { classPropertyName: "sticky", publicName: "sticky", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeKey: "activeKeyChange" }, host: { properties: { "class.is-standalone": "isStandalone()", "class.is-horizontal": "resolvedDirection() === 'horizontal'", "class.is-sticky": "sticky()" } }, ngImport: i0, template: "<nav\n class=\"tab-bar\"\n [class.style-underline]=\"activeStyle() === 'underline'\"\n [class.style-fill]=\"activeStyle() === 'fill'\"\n [class.dir-vertical]=\"resolvedDirection() === 'vertical'\"\n [class.size-comfortable]=\"size() === 'comfortable'\"\n [class.is-collapsed]=\"collapsed()\"\n [class.bg-surface]=\"background() === 'surface'\"\n>\n @for (item of items(); track item.key) {\n @if (item.disabled) {\n <button\n type=\"button\"\n class=\"tab-bar-item is-disabled\"\n disabled\n aria-disabled=\"true\"\n >\n <ng-container\n [ngTemplateOutlet]=\"body\"\n [ngTemplateOutletContext]=\"{ $implicit: item, active: false }\"\n />\n </button>\n } @else if (item.link !== undefined) {\n <a\n class=\"tab-bar-item\"\n [routerLink]=\"item.link\"\n routerLinkActive=\"is-active\"\n #rla=\"routerLinkActive\"\n [attr.aria-current]=\"rla.isActive ? 'page' : null\"\n >\n <ng-container\n [ngTemplateOutlet]=\"body\"\n [ngTemplateOutletContext]=\"{ $implicit: item, active: rla.isActive }\"\n />\n </a>\n } @else if (item.href !== undefined) {\n <a\n class=\"tab-bar-item\"\n [href]=\"item.href\"\n [class.is-active]=\"activeKey() === item.key\"\n [attr.aria-current]=\"activeKey() === item.key ? 'page' : null\"\n >\n <ng-container\n [ngTemplateOutlet]=\"body\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n active: activeKey() === item.key,\n }\"\n />\n </a>\n } @else {\n <button\n type=\"button\"\n class=\"tab-bar-item\"\n [class.is-active]=\"activeKey() === item.key\"\n [attr.aria-current]=\"activeKey() === item.key ? 'page' : null\"\n (click)=\"activeKey.set(item.key)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"body\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n active: activeKey() === item.key,\n }\"\n />\n </button>\n }\n }\n</nav>\n\n<!-- One item's inner content, shared by the link / button branches. -->\n<ng-template #body let-item let-active=\"active\">\n @if (item.icon; as ic) {\n <fold-icon class=\"tab-bar-icon\" [name]=\"ic\" size=\"sm\" />\n } @else if (collapsed()) {\n <!-- Collapsed needs a fixed glyph; an icon-less item falls back to its\n initial so the rail stays icon-width and the label still tooltips. -->\n <span class=\"tab-bar-icon tab-bar-initial\" aria-hidden=\"true\">{{\n item.label.charAt(0)\n }}</span>\n }\n <span class=\"tab-bar-label\">{{ item.label }}</span>\n @if (item.badge !== undefined && item.badge !== null) {\n <fold-badge\n class=\"tab-bar-badge\"\n [content]=\"item.badge + ''\"\n [variant]=\"active ? 'accent' : 'neutral'\"\n />\n }\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host{display:flex;width:100%;max-width:100%;overflow:hidden}:host(.is-sticky){position:sticky;top:0;z-index:2}:host:has(.tab-bar:not(.dir-vertical):not(.is-collapsed)){overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;overscroll-behavior-x:contain}:host:has(.tab-bar:not(.dir-vertical):not(.is-collapsed)) .tab-bar{min-width:max-content;max-width:none}.tab-bar{flex:1;display:flex;max-width:100%;gap:2px;-webkit-user-select:none;user-select:none}.bg-surface{background:linear-gradient(var(--fold-color-bg-rail-tertiary),var(--fold-color-bg-rail-tertiary)),var(--fold-color-bg-page);padding:var(--fold-space-xs) var(--fold-space-sm) 0}.bg-surface.dir-vertical{padding:var(--fold-space-md) var(--fold-space-sm)}.tab-bar-item{flex:1;display:flex;align-items:center;justify-content:center;gap:var(--fold-space-sm);padding:var(--fold-space-sm) var(--fold-space-sm);background:none;border:none;color:var(--fold-color-text-muted);font-family:inherit;font-size:10px;font-weight:600;cursor:pointer;text-align:center;text-decoration:none;transition:color .1s ease,background .1s ease,border-color .1s ease;white-space:nowrap}.tab-bar-item:hover{color:var(--fold-color-text-secondary)}.tab-bar-item.is-disabled{opacity:.5;cursor:default;pointer-events:none}.size-comfortable .tab-bar-item{flex:0 1 auto;gap:var(--fold-space-sm);padding:var(--fold-space-md) var(--fold-space-lg);font-size:var(--fold-text-sm)}.dir-vertical.size-comfortable .tab-bar-item{padding:var(--fold-space-md) var(--fold-space-md);font-size:var(--fold-text-md)}.style-underline{border-bottom:1px solid var(--fold-color-border)}.style-underline .tab-bar-item{border-bottom:2px solid transparent;margin-bottom:-1px}.style-underline .tab-bar-item.is-active{color:var(--fold-color-text);border-bottom-color:var(--fold-color-primary)}.style-fill .tab-bar-item{border-radius:var(--fold-radius-sm);border:1px solid transparent}.style-fill .tab-bar-item.is-active{background:var(--fold-color-primary-surface);color:var(--fold-color-primary-text);font-weight:600}.style-fill .tab-bar-item:hover:not(.is-active){background:var(--fold-color-surface-hover);color:var(--fold-color-text)}.dir-vertical{flex-direction:column}.dir-vertical .tab-bar-item{flex:none;justify-content:flex-start;text-align:left;padding:var(--fold-space-sm) var(--fold-space-md);gap:var(--fold-space-sm);border-radius:var(--fold-radius-sm);font-size:var(--fold-text-sm);font-weight:500}.dir-vertical.style-underline{border-bottom:none;border-right:1px solid var(--fold-color-border)}.dir-vertical.style-underline .tab-bar-item{border-bottom:none;border-left:2px solid transparent;margin-bottom:0;margin-right:-1px}.dir-vertical.style-underline .tab-bar-item.is-active{border-left-color:var(--fold-color-primary)}.dir-vertical.style-fill .tab-bar-item.is-active{background:var(--fold-color-primary-surface);color:var(--fold-color-primary-text);font-weight:600}.is-collapsed .tab-bar-item{position:relative;flex:0 0 auto;gap:0}.is-collapsed .tab-bar-item:not(.is-active) .tab-bar-badge{display:none}.is-collapsed .tab-bar-item.is-active{flex:1 1 auto;min-width:0;gap:var(--fold-space-sm)}.is-collapsed .tab-bar-item.is-active .tab-bar-label{overflow:hidden;text-overflow:ellipsis}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active) .tab-bar-icon~.tab-bar-label{position:absolute;padding:var(--fold-space-xs) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-glass);border:1px solid var(--fold-color-glass-border);color:var(--fold-color-text);font-size:var(--fold-text-xs);font-weight:500;white-space:nowrap;opacity:0;pointer-events:none;box-shadow:var(--fold-shadow-md);transition:opacity var(--fold-motion-fast);z-index:100}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-icon~.tab-bar-label{left:calc(100% + 8px);top:50%;transform:translateY(-50%)}.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active) .tab-bar-icon~.tab-bar-label{top:calc(100% + 6px);left:50%;transform:translate(-50%)}.dir-vertical.is-collapsed .tab-bar-item:hover .tab-bar-icon~.tab-bar-label,.dir-vertical.is-collapsed .tab-bar-item:focus-visible .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active):hover .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active):focus-visible .tab-bar-icon~.tab-bar-label{opacity:1}.dir-vertical.is-collapsed{align-items:center}.dir-vertical.is-collapsed .tab-bar-item,.dir-vertical.is-collapsed .tab-bar-item.is-active{justify-content:center;gap:0}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-badge{display:block;position:absolute;top:-2px;right:-2px;transform:scale(.85);transform-origin:top right;pointer-events:none}:host:has(.is-collapsed){overflow:visible}.tab-bar-icon{flex-shrink:0}.tab-bar-initial{display:grid;place-items:center;width:18px;height:18px;border-radius:var(--fold-radius-sm);font-size:11px;font-weight:700;line-height:1;text-transform:uppercase}.tab-bar-badge{flex-shrink:0;font-variant-numeric:tabular-nums}.tab-bar-item:focus-visible{outline:2px solid var(--fold-color-primary);outline-offset:-2px;border-radius:var(--fold-radius-sm)}:host(.is-standalone.is-horizontal){margin-block-end:var(--fold-nav-layout-gap, var(--fold-space-lg, 16px))}@media(max-width:640px){:host(.is-standalone.is-horizontal){margin-block-end:var(--fold-nav-layout-gap, var(--fold-space-xs, 4px))}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }, { kind: "component", type: FoldBadgeComponent, selector: "fold-badge", inputs: ["content", "radius", "variant"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }] });
11131
11315
  }
11132
11316
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldViewNavComponent, decorators: [{
11133
11317
  type: Component,
@@ -11144,8 +11328,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
11144
11328
  // conjunction. Vertical is a side rail, not a header — no block-end margin.
11145
11329
  "[class.is-standalone]": "isStandalone()",
11146
11330
  "[class.is-horizontal]": "resolvedDirection() === 'horizontal'",
11147
- }, template: "<nav\n class=\"tab-bar\"\n [class.style-underline]=\"activeStyle() === 'underline'\"\n [class.style-fill]=\"activeStyle() === 'fill'\"\n [class.dir-vertical]=\"resolvedDirection() === 'vertical'\"\n [class.size-comfortable]=\"size() === 'comfortable'\"\n [class.is-collapsed]=\"collapsed()\"\n [class.bg-surface]=\"background() === 'surface'\"\n>\n @for (item of items(); track item.key) {\n @if (item.disabled) {\n <button\n type=\"button\"\n class=\"tab-bar-item is-disabled\"\n disabled\n aria-disabled=\"true\"\n >\n <ng-container\n [ngTemplateOutlet]=\"body\"\n [ngTemplateOutletContext]=\"{ $implicit: item, active: false }\"\n />\n </button>\n } @else if (item.link !== undefined) {\n <a\n class=\"tab-bar-item\"\n [routerLink]=\"item.link\"\n routerLinkActive=\"is-active\"\n #rla=\"routerLinkActive\"\n [attr.aria-current]=\"rla.isActive ? 'page' : null\"\n >\n <ng-container\n [ngTemplateOutlet]=\"body\"\n [ngTemplateOutletContext]=\"{ $implicit: item, active: rla.isActive }\"\n />\n </a>\n } @else if (item.href !== undefined) {\n <a\n class=\"tab-bar-item\"\n [href]=\"item.href\"\n [class.is-active]=\"activeKey() === item.key\"\n [attr.aria-current]=\"activeKey() === item.key ? 'page' : null\"\n >\n <ng-container\n [ngTemplateOutlet]=\"body\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n active: activeKey() === item.key,\n }\"\n />\n </a>\n } @else {\n <button\n type=\"button\"\n class=\"tab-bar-item\"\n [class.is-active]=\"activeKey() === item.key\"\n [attr.aria-current]=\"activeKey() === item.key ? 'page' : null\"\n (click)=\"activeKey.set(item.key)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"body\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n active: activeKey() === item.key,\n }\"\n />\n </button>\n }\n }\n</nav>\n\n<!-- One item's inner content, shared by the link / button branches. -->\n<ng-template #body let-item let-active=\"active\">\n @if (item.icon; as ic) {\n <fold-icon class=\"tab-bar-icon\" [name]=\"ic\" size=\"sm\" />\n } @else if (collapsed()) {\n <!-- Collapsed needs a fixed glyph; an icon-less item falls back to its\n initial so the rail stays icon-width and the label still tooltips. -->\n <span class=\"tab-bar-icon tab-bar-initial\" aria-hidden=\"true\">{{\n item.label.charAt(0)\n }}</span>\n }\n <span class=\"tab-bar-label\">{{ item.label }}</span>\n @if (item.badge !== undefined && item.badge !== null) {\n <fold-badge\n class=\"tab-bar-badge\"\n [content]=\"item.badge + ''\"\n [variant]=\"active ? 'accent' : 'neutral'\"\n />\n }\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host{display:flex;width:100%;max-width:100%;overflow:hidden}:host:has(.tab-bar:not(.dir-vertical):not(.is-collapsed)){overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;overscroll-behavior-x:contain}:host:has(.tab-bar:not(.dir-vertical):not(.is-collapsed)) .tab-bar{min-width:max-content;max-width:none}.tab-bar{flex:1;display:flex;max-width:100%;gap:2px;-webkit-user-select:none;user-select:none}.bg-surface{background:linear-gradient(var(--fold-color-bg-rail-tertiary),var(--fold-color-bg-rail-tertiary)),var(--fold-color-bg-page);padding:var(--fold-space-xs) var(--fold-space-sm) 0}.bg-surface.dir-vertical{padding:var(--fold-space-md) var(--fold-space-sm)}.tab-bar-item{flex:1;display:flex;align-items:center;justify-content:center;gap:var(--fold-space-sm);padding:var(--fold-space-sm) var(--fold-space-sm);background:none;border:none;color:var(--fold-color-text-muted);font-family:inherit;font-size:10px;font-weight:600;cursor:pointer;text-align:center;text-decoration:none;transition:color .1s ease,background .1s ease,border-color .1s ease;white-space:nowrap}.tab-bar-item:hover{color:var(--fold-color-text-secondary)}.tab-bar-item.is-disabled{opacity:.5;cursor:default;pointer-events:none}.size-comfortable .tab-bar-item{flex:0 1 auto;gap:var(--fold-space-sm);padding:var(--fold-space-md) var(--fold-space-lg);font-size:var(--fold-text-sm)}.dir-vertical.size-comfortable .tab-bar-item{padding:var(--fold-space-md) var(--fold-space-md);font-size:var(--fold-text-md)}.style-underline{border-bottom:1px solid var(--fold-color-border)}.style-underline .tab-bar-item{border-bottom:2px solid transparent;margin-bottom:-1px}.style-underline .tab-bar-item.is-active{color:var(--fold-color-text);border-bottom-color:var(--fold-color-primary)}.style-fill .tab-bar-item{border-radius:var(--fold-radius-sm);border:1px solid transparent}.style-fill .tab-bar-item.is-active{background:var(--fold-color-primary-surface);color:var(--fold-color-primary-text);font-weight:600}.style-fill .tab-bar-item:hover:not(.is-active){background:var(--fold-color-surface-hover);color:var(--fold-color-text)}.dir-vertical{flex-direction:column}.dir-vertical .tab-bar-item{flex:none;justify-content:flex-start;text-align:left;padding:var(--fold-space-sm) var(--fold-space-md);gap:var(--fold-space-sm);border-radius:var(--fold-radius-sm);font-size:var(--fold-text-sm);font-weight:500}.dir-vertical.style-underline{border-bottom:none;border-right:1px solid var(--fold-color-border)}.dir-vertical.style-underline .tab-bar-item{border-bottom:none;border-left:2px solid transparent;margin-bottom:0;margin-right:-1px}.dir-vertical.style-underline .tab-bar-item.is-active{border-left-color:var(--fold-color-primary)}.dir-vertical.style-fill .tab-bar-item.is-active{background:var(--fold-color-primary-surface);color:var(--fold-color-primary-text);font-weight:600}.is-collapsed .tab-bar-item{position:relative;flex:0 0 auto;gap:0}.is-collapsed .tab-bar-item:not(.is-active) .tab-bar-badge{display:none}.is-collapsed .tab-bar-item.is-active{flex:1 1 auto;min-width:0;gap:var(--fold-space-sm)}.is-collapsed .tab-bar-item.is-active .tab-bar-label{overflow:hidden;text-overflow:ellipsis}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active) .tab-bar-icon~.tab-bar-label{position:absolute;padding:var(--fold-space-xs) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-glass);border:1px solid var(--fold-color-glass-border);color:var(--fold-color-text);font-size:var(--fold-text-xs);font-weight:500;white-space:nowrap;opacity:0;pointer-events:none;box-shadow:var(--fold-shadow-md);transition:opacity var(--fold-motion-fast);z-index:100}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-icon~.tab-bar-label{left:calc(100% + 8px);top:50%;transform:translateY(-50%)}.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active) .tab-bar-icon~.tab-bar-label{top:calc(100% + 6px);left:50%;transform:translate(-50%)}.dir-vertical.is-collapsed .tab-bar-item:hover .tab-bar-icon~.tab-bar-label,.dir-vertical.is-collapsed .tab-bar-item:focus-visible .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active):hover .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active):focus-visible .tab-bar-icon~.tab-bar-label{opacity:1}.dir-vertical.is-collapsed{align-items:center}.dir-vertical.is-collapsed .tab-bar-item,.dir-vertical.is-collapsed .tab-bar-item.is-active{justify-content:center;gap:0}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-badge{display:block;position:absolute;top:-2px;right:-2px;transform:scale(.85);transform-origin:top right;pointer-events:none}:host:has(.is-collapsed){overflow:visible}.tab-bar-icon{flex-shrink:0}.tab-bar-initial{display:grid;place-items:center;width:18px;height:18px;border-radius:var(--fold-radius-sm);font-size:11px;font-weight:700;line-height:1;text-transform:uppercase}.tab-bar-badge{flex-shrink:0;font-variant-numeric:tabular-nums}.tab-bar-item:focus-visible{outline:2px solid var(--fold-color-primary);outline-offset:-2px;border-radius:var(--fold-radius-sm)}:host(.is-standalone.is-horizontal){margin-block-end:var(--fold-nav-layout-gap, var(--fold-space-lg, 16px))}@media(max-width:640px){:host(.is-standalone.is-horizontal){margin-block-end:var(--fold-nav-layout-gap, var(--fold-space-xs, 4px))}}\n"] }]
11148
- }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], activeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeKey", required: false }] }, { type: i0.Output, args: ["activeKeyChange"] }], activeStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeStyle", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }], background: [{ type: i0.Input, args: [{ isSignal: true, alias: "background", required: false }] }] } });
11331
+ "[class.is-sticky]": "sticky()",
11332
+ }, template: "<nav\n class=\"tab-bar\"\n [class.style-underline]=\"activeStyle() === 'underline'\"\n [class.style-fill]=\"activeStyle() === 'fill'\"\n [class.dir-vertical]=\"resolvedDirection() === 'vertical'\"\n [class.size-comfortable]=\"size() === 'comfortable'\"\n [class.is-collapsed]=\"collapsed()\"\n [class.bg-surface]=\"background() === 'surface'\"\n>\n @for (item of items(); track item.key) {\n @if (item.disabled) {\n <button\n type=\"button\"\n class=\"tab-bar-item is-disabled\"\n disabled\n aria-disabled=\"true\"\n >\n <ng-container\n [ngTemplateOutlet]=\"body\"\n [ngTemplateOutletContext]=\"{ $implicit: item, active: false }\"\n />\n </button>\n } @else if (item.link !== undefined) {\n <a\n class=\"tab-bar-item\"\n [routerLink]=\"item.link\"\n routerLinkActive=\"is-active\"\n #rla=\"routerLinkActive\"\n [attr.aria-current]=\"rla.isActive ? 'page' : null\"\n >\n <ng-container\n [ngTemplateOutlet]=\"body\"\n [ngTemplateOutletContext]=\"{ $implicit: item, active: rla.isActive }\"\n />\n </a>\n } @else if (item.href !== undefined) {\n <a\n class=\"tab-bar-item\"\n [href]=\"item.href\"\n [class.is-active]=\"activeKey() === item.key\"\n [attr.aria-current]=\"activeKey() === item.key ? 'page' : null\"\n >\n <ng-container\n [ngTemplateOutlet]=\"body\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n active: activeKey() === item.key,\n }\"\n />\n </a>\n } @else {\n <button\n type=\"button\"\n class=\"tab-bar-item\"\n [class.is-active]=\"activeKey() === item.key\"\n [attr.aria-current]=\"activeKey() === item.key ? 'page' : null\"\n (click)=\"activeKey.set(item.key)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"body\"\n [ngTemplateOutletContext]=\"{\n $implicit: item,\n active: activeKey() === item.key,\n }\"\n />\n </button>\n }\n }\n</nav>\n\n<!-- One item's inner content, shared by the link / button branches. -->\n<ng-template #body let-item let-active=\"active\">\n @if (item.icon; as ic) {\n <fold-icon class=\"tab-bar-icon\" [name]=\"ic\" size=\"sm\" />\n } @else if (collapsed()) {\n <!-- Collapsed needs a fixed glyph; an icon-less item falls back to its\n initial so the rail stays icon-width and the label still tooltips. -->\n <span class=\"tab-bar-icon tab-bar-initial\" aria-hidden=\"true\">{{\n item.label.charAt(0)\n }}</span>\n }\n <span class=\"tab-bar-label\">{{ item.label }}</span>\n @if (item.badge !== undefined && item.badge !== null) {\n <fold-badge\n class=\"tab-bar-badge\"\n [content]=\"item.badge + ''\"\n [variant]=\"active ? 'accent' : 'neutral'\"\n />\n }\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host{display:flex;width:100%;max-width:100%;overflow:hidden}:host(.is-sticky){position:sticky;top:0;z-index:2}:host:has(.tab-bar:not(.dir-vertical):not(.is-collapsed)){overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;overscroll-behavior-x:contain}:host:has(.tab-bar:not(.dir-vertical):not(.is-collapsed)) .tab-bar{min-width:max-content;max-width:none}.tab-bar{flex:1;display:flex;max-width:100%;gap:2px;-webkit-user-select:none;user-select:none}.bg-surface{background:linear-gradient(var(--fold-color-bg-rail-tertiary),var(--fold-color-bg-rail-tertiary)),var(--fold-color-bg-page);padding:var(--fold-space-xs) var(--fold-space-sm) 0}.bg-surface.dir-vertical{padding:var(--fold-space-md) var(--fold-space-sm)}.tab-bar-item{flex:1;display:flex;align-items:center;justify-content:center;gap:var(--fold-space-sm);padding:var(--fold-space-sm) var(--fold-space-sm);background:none;border:none;color:var(--fold-color-text-muted);font-family:inherit;font-size:10px;font-weight:600;cursor:pointer;text-align:center;text-decoration:none;transition:color .1s ease,background .1s ease,border-color .1s ease;white-space:nowrap}.tab-bar-item:hover{color:var(--fold-color-text-secondary)}.tab-bar-item.is-disabled{opacity:.5;cursor:default;pointer-events:none}.size-comfortable .tab-bar-item{flex:0 1 auto;gap:var(--fold-space-sm);padding:var(--fold-space-md) var(--fold-space-lg);font-size:var(--fold-text-sm)}.dir-vertical.size-comfortable .tab-bar-item{padding:var(--fold-space-md) var(--fold-space-md);font-size:var(--fold-text-md)}.style-underline{border-bottom:1px solid var(--fold-color-border)}.style-underline .tab-bar-item{border-bottom:2px solid transparent;margin-bottom:-1px}.style-underline .tab-bar-item.is-active{color:var(--fold-color-text);border-bottom-color:var(--fold-color-primary)}.style-fill .tab-bar-item{border-radius:var(--fold-radius-sm);border:1px solid transparent}.style-fill .tab-bar-item.is-active{background:var(--fold-color-primary-surface);color:var(--fold-color-primary-text);font-weight:600}.style-fill .tab-bar-item:hover:not(.is-active){background:var(--fold-color-surface-hover);color:var(--fold-color-text)}.dir-vertical{flex-direction:column}.dir-vertical .tab-bar-item{flex:none;justify-content:flex-start;text-align:left;padding:var(--fold-space-sm) var(--fold-space-md);gap:var(--fold-space-sm);border-radius:var(--fold-radius-sm);font-size:var(--fold-text-sm);font-weight:500}.dir-vertical.style-underline{border-bottom:none;border-right:1px solid var(--fold-color-border)}.dir-vertical.style-underline .tab-bar-item{border-bottom:none;border-left:2px solid transparent;margin-bottom:0;margin-right:-1px}.dir-vertical.style-underline .tab-bar-item.is-active{border-left-color:var(--fold-color-primary)}.dir-vertical.style-fill .tab-bar-item.is-active{background:var(--fold-color-primary-surface);color:var(--fold-color-primary-text);font-weight:600}.is-collapsed .tab-bar-item{position:relative;flex:0 0 auto;gap:0}.is-collapsed .tab-bar-item:not(.is-active) .tab-bar-badge{display:none}.is-collapsed .tab-bar-item.is-active{flex:1 1 auto;min-width:0;gap:var(--fold-space-sm)}.is-collapsed .tab-bar-item.is-active .tab-bar-label{overflow:hidden;text-overflow:ellipsis}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active) .tab-bar-icon~.tab-bar-label{position:absolute;padding:var(--fold-space-xs) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-glass);border:1px solid var(--fold-color-glass-border);color:var(--fold-color-text);font-size:var(--fold-text-xs);font-weight:500;white-space:nowrap;opacity:0;pointer-events:none;box-shadow:var(--fold-shadow-md);transition:opacity var(--fold-motion-fast);z-index:100}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-icon~.tab-bar-label{left:calc(100% + 8px);top:50%;transform:translateY(-50%)}.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active) .tab-bar-icon~.tab-bar-label{top:calc(100% + 6px);left:50%;transform:translate(-50%)}.dir-vertical.is-collapsed .tab-bar-item:hover .tab-bar-icon~.tab-bar-label,.dir-vertical.is-collapsed .tab-bar-item:focus-visible .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active):hover .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active):focus-visible .tab-bar-icon~.tab-bar-label{opacity:1}.dir-vertical.is-collapsed{align-items:center}.dir-vertical.is-collapsed .tab-bar-item,.dir-vertical.is-collapsed .tab-bar-item.is-active{justify-content:center;gap:0}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-badge{display:block;position:absolute;top:-2px;right:-2px;transform:scale(.85);transform-origin:top right;pointer-events:none}:host:has(.is-collapsed){overflow:visible}.tab-bar-icon{flex-shrink:0}.tab-bar-initial{display:grid;place-items:center;width:18px;height:18px;border-radius:var(--fold-radius-sm);font-size:11px;font-weight:700;line-height:1;text-transform:uppercase}.tab-bar-badge{flex-shrink:0;font-variant-numeric:tabular-nums}.tab-bar-item:focus-visible{outline:2px solid var(--fold-color-primary);outline-offset:-2px;border-radius:var(--fold-radius-sm)}:host(.is-standalone.is-horizontal){margin-block-end:var(--fold-nav-layout-gap, var(--fold-space-lg, 16px))}@media(max-width:640px){:host(.is-standalone.is-horizontal){margin-block-end:var(--fold-nav-layout-gap, var(--fold-space-xs, 4px))}}\n"] }]
11333
+ }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], activeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeKey", required: false }] }, { type: i0.Output, args: ["activeKeyChange"] }], activeStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeStyle", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }], background: [{ type: i0.Input, args: [{ isSignal: true, alias: "background", required: false }] }], sticky: [{ type: i0.Input, args: [{ isSignal: true, alias: "sticky", required: false }] }] } });
11149
11334
 
11150
11335
  /**
11151
11336
  * `<fold-breadcrumb>` — a hierarchical trail of links to the current page. Data
@@ -11249,7 +11434,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
11249
11434
  *
11250
11435
  * ```html
11251
11436
  * <fold-nav-layout>
11252
- * <fold-tabs nav #t="foldTabs" [tabs]="tabs" [(activeKey)]="tab" />
11437
+ * <fold-tabs tabNav #t="foldTabs" [tabs]="tabs" [(activeKey)]="tab" />
11253
11438
  * <fold-tab-panel [tabs]="t" key="overview">…</fold-tab-panel>
11254
11439
  * <fold-tab-panel [tabs]="t" key="settings">…</fold-tab-panel>
11255
11440
  * </fold-nav-layout>
@@ -11290,6 +11475,14 @@ class FoldTabsComponent {
11290
11475
  /** `surface` (filled bar, default) or `transparent`. */
11291
11476
  background = input("surface", /* @ts-ignore */
11292
11477
  ...(ngDevMode ? [{ debugName: "background" }] : /* istanbul ignore next */ []));
11478
+ /**
11479
+ * Pin the bar to the top of its scroll container, so a long view can be
11480
+ * navigated without scrolling back up. Pair it with the default
11481
+ * `background="surface"`: a `transparent` bar would let the content scroll
11482
+ * through it. Bleeding the bar to the page's edges stays the page's business
11483
+ * — the page owns the gutter.
11484
+ */
11485
+ sticky = input(false, { ...(ngDevMode ? { debugName: "sticky" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
11293
11486
  /** The nearest layout, if any — lets `direction="auto"` follow it. */
11294
11487
  layout = inject(FOLD_NAV_LAYOUT, { optional: true });
11295
11488
  /** `direction` with `auto` resolved against the wrapping layout. */
@@ -11359,12 +11552,12 @@ class FoldTabsComponent {
11359
11552
  this.tabButtons()[target]?.nativeElement.focus();
11360
11553
  }
11361
11554
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldTabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11362
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldTabsComponent, isStandalone: true, selector: "fold-tabs", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: true, transformFunction: null }, activeKey: { classPropertyName: "activeKey", publicName: "activeKey", isSignal: true, isRequired: true, transformFunction: null }, activeStyle: { classPropertyName: "activeStyle", publicName: "activeStyle", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, background: { classPropertyName: "background", publicName: "background", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeKey: "activeKeyChange" }, viewQueries: [{ propertyName: "tabButtons", predicate: ["tabBtn"], descendants: true, isSignal: true }], exportAs: ["foldTabs"], ngImport: i0, template: "<div\n class=\"tab-bar\"\n role=\"tablist\"\n [attr.aria-orientation]=\"\n resolvedDirection() === 'vertical' ? 'vertical' : 'horizontal'\n \"\n [class.style-underline]=\"activeStyle() === 'underline'\"\n [class.style-fill]=\"activeStyle() === 'fill'\"\n [class.dir-vertical]=\"resolvedDirection() === 'vertical'\"\n [class.size-comfortable]=\"size() === 'comfortable'\"\n [class.is-collapsed]=\"collapsed()\"\n [class.bg-surface]=\"background() === 'surface'\"\n (keydown)=\"onKeydown($event)\"\n>\n @for (tab of tabs(); track tab.key) {\n <button\n #tabBtn\n type=\"button\"\n role=\"tab\"\n class=\"tab-bar-item\"\n [id]=\"tabId(tab.key)\"\n [class.is-active]=\"activeKey() === tab.key\"\n [attr.aria-selected]=\"activeKey() === tab.key\"\n [attr.aria-controls]=\"panelId(tab.key)\"\n [tabindex]=\"activeKey() === tab.key ? 0 : -1\"\n (click)=\"select(tab.key)\"\n >\n @if (tab.icon; as ic) {\n <fold-icon class=\"tab-bar-icon\" [name]=\"ic\" size=\"sm\" />\n } @else if (collapsed()) {\n <span class=\"tab-bar-icon tab-bar-initial\" aria-hidden=\"true\">{{\n tab.label.charAt(0)\n }}</span>\n }\n <span class=\"tab-bar-label\">{{ tab.label }}</span>\n @if (tab.badge !== undefined && tab.badge !== null) {\n <fold-badge\n class=\"tab-bar-badge\"\n [content]=\"tab.badge + ''\"\n [variant]=\"activeKey() === tab.key ? 'accent' : 'neutral'\"\n />\n }\n </button>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;width:100%;max-width:100%;overflow:hidden}:host:has(.tab-bar:not(.dir-vertical):not(.is-collapsed)){overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;overscroll-behavior-x:contain}:host:has(.tab-bar:not(.dir-vertical):not(.is-collapsed)) .tab-bar{min-width:max-content;max-width:none}.tab-bar{flex:1;display:flex;max-width:100%;gap:2px;-webkit-user-select:none;user-select:none}.bg-surface{background:linear-gradient(var(--fold-color-bg-rail-tertiary),var(--fold-color-bg-rail-tertiary)),var(--fold-color-bg-page);padding:var(--fold-space-xs) var(--fold-space-sm) 0}.bg-surface.dir-vertical{padding:var(--fold-space-md) var(--fold-space-sm)}.tab-bar-item{flex:1;display:flex;align-items:center;justify-content:center;gap:var(--fold-space-sm);padding:var(--fold-space-sm) var(--fold-space-sm);background:none;border:none;color:var(--fold-color-text-muted);font-family:inherit;font-size:10px;font-weight:600;cursor:pointer;text-align:center;text-decoration:none;transition:color .1s ease,background .1s ease,border-color .1s ease;white-space:nowrap}.tab-bar-item:hover{color:var(--fold-color-text-secondary)}.tab-bar-item.is-disabled{opacity:.5;cursor:default;pointer-events:none}.size-comfortable .tab-bar-item{flex:0 1 auto;gap:var(--fold-space-sm);padding:var(--fold-space-md) var(--fold-space-lg);font-size:var(--fold-text-sm)}.dir-vertical.size-comfortable .tab-bar-item{padding:var(--fold-space-md) var(--fold-space-md);font-size:var(--fold-text-md)}.style-underline{border-bottom:1px solid var(--fold-color-border)}.style-underline .tab-bar-item{border-bottom:2px solid transparent;margin-bottom:-1px}.style-underline .tab-bar-item.is-active{color:var(--fold-color-text);border-bottom-color:var(--fold-color-primary)}.style-fill .tab-bar-item{border-radius:var(--fold-radius-sm);border:1px solid transparent}.style-fill .tab-bar-item.is-active{background:var(--fold-color-primary-surface);color:var(--fold-color-primary-text);font-weight:600}.style-fill .tab-bar-item:hover:not(.is-active){background:var(--fold-color-surface-hover);color:var(--fold-color-text)}.dir-vertical{flex-direction:column}.dir-vertical .tab-bar-item{flex:none;justify-content:flex-start;text-align:left;padding:var(--fold-space-sm) var(--fold-space-md);gap:var(--fold-space-sm);border-radius:var(--fold-radius-sm);font-size:var(--fold-text-sm);font-weight:500}.dir-vertical.style-underline{border-bottom:none;border-right:1px solid var(--fold-color-border)}.dir-vertical.style-underline .tab-bar-item{border-bottom:none;border-left:2px solid transparent;margin-bottom:0;margin-right:-1px}.dir-vertical.style-underline .tab-bar-item.is-active{border-left-color:var(--fold-color-primary)}.dir-vertical.style-fill .tab-bar-item.is-active{background:var(--fold-color-primary-surface);color:var(--fold-color-primary-text);font-weight:600}.is-collapsed .tab-bar-item{position:relative;flex:0 0 auto;gap:0}.is-collapsed .tab-bar-item:not(.is-active) .tab-bar-badge{display:none}.is-collapsed .tab-bar-item.is-active{flex:1 1 auto;min-width:0;gap:var(--fold-space-sm)}.is-collapsed .tab-bar-item.is-active .tab-bar-label{overflow:hidden;text-overflow:ellipsis}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active) .tab-bar-icon~.tab-bar-label{position:absolute;padding:var(--fold-space-xs) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-glass);border:1px solid var(--fold-color-glass-border);color:var(--fold-color-text);font-size:var(--fold-text-xs);font-weight:500;white-space:nowrap;opacity:0;pointer-events:none;box-shadow:var(--fold-shadow-md);transition:opacity var(--fold-motion-fast);z-index:100}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-icon~.tab-bar-label{left:calc(100% + 8px);top:50%;transform:translateY(-50%)}.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active) .tab-bar-icon~.tab-bar-label{top:calc(100% + 6px);left:50%;transform:translate(-50%)}.dir-vertical.is-collapsed .tab-bar-item:hover .tab-bar-icon~.tab-bar-label,.dir-vertical.is-collapsed .tab-bar-item:focus-visible .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active):hover .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active):focus-visible .tab-bar-icon~.tab-bar-label{opacity:1}.dir-vertical.is-collapsed{align-items:center}.dir-vertical.is-collapsed .tab-bar-item,.dir-vertical.is-collapsed .tab-bar-item.is-active{justify-content:center;gap:0}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-badge{display:block;position:absolute;top:-2px;right:-2px;transform:scale(.85);transform-origin:top right;pointer-events:none}:host:has(.is-collapsed){overflow:visible}.tab-bar-icon{flex-shrink:0}.tab-bar-initial{display:grid;place-items:center;width:18px;height:18px;border-radius:var(--fold-radius-sm);font-size:11px;font-weight:700;line-height:1;text-transform:uppercase}.tab-bar-badge{flex-shrink:0;font-variant-numeric:tabular-nums}.tab-bar-item:focus-visible{outline:2px solid var(--fold-color-primary);outline-offset:-2px;border-radius:var(--fold-radius-sm)}\n"], dependencies: [{ kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }, { kind: "component", type: FoldBadgeComponent, selector: "fold-badge", inputs: ["content", "radius", "variant"] }] });
11555
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldTabsComponent, isStandalone: true, selector: "fold-tabs", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: true, transformFunction: null }, activeKey: { classPropertyName: "activeKey", publicName: "activeKey", isSignal: true, isRequired: true, transformFunction: null }, activeStyle: { classPropertyName: "activeStyle", publicName: "activeStyle", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, background: { classPropertyName: "background", publicName: "background", isSignal: true, isRequired: false, transformFunction: null }, sticky: { classPropertyName: "sticky", publicName: "sticky", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeKey: "activeKeyChange" }, host: { properties: { "class.is-sticky": "sticky()" } }, viewQueries: [{ propertyName: "tabButtons", predicate: ["tabBtn"], descendants: true, isSignal: true }], exportAs: ["foldTabs"], ngImport: i0, template: "<div\n class=\"tab-bar\"\n role=\"tablist\"\n [attr.aria-orientation]=\"\n resolvedDirection() === 'vertical' ? 'vertical' : 'horizontal'\n \"\n [class.style-underline]=\"activeStyle() === 'underline'\"\n [class.style-fill]=\"activeStyle() === 'fill'\"\n [class.dir-vertical]=\"resolvedDirection() === 'vertical'\"\n [class.size-comfortable]=\"size() === 'comfortable'\"\n [class.is-collapsed]=\"collapsed()\"\n [class.bg-surface]=\"background() === 'surface'\"\n (keydown)=\"onKeydown($event)\"\n>\n @for (tab of tabs(); track tab.key) {\n <button\n #tabBtn\n type=\"button\"\n role=\"tab\"\n class=\"tab-bar-item\"\n [id]=\"tabId(tab.key)\"\n [class.is-active]=\"activeKey() === tab.key\"\n [attr.aria-selected]=\"activeKey() === tab.key\"\n [attr.aria-controls]=\"panelId(tab.key)\"\n [tabindex]=\"activeKey() === tab.key ? 0 : -1\"\n (click)=\"select(tab.key)\"\n >\n @if (tab.icon; as ic) {\n <fold-icon class=\"tab-bar-icon\" [name]=\"ic\" size=\"sm\" />\n } @else if (collapsed()) {\n <span class=\"tab-bar-icon tab-bar-initial\" aria-hidden=\"true\">{{\n tab.label.charAt(0)\n }}</span>\n }\n <span class=\"tab-bar-label\">{{ tab.label }}</span>\n @if (tab.badge !== undefined && tab.badge !== null) {\n <fold-badge\n class=\"tab-bar-badge\"\n [content]=\"tab.badge + ''\"\n [variant]=\"activeKey() === tab.key ? 'accent' : 'neutral'\"\n />\n }\n </button>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;width:100%;max-width:100%;overflow:hidden}:host(.is-sticky){position:sticky;top:0;z-index:2}:host:has(.tab-bar:not(.dir-vertical):not(.is-collapsed)){overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;overscroll-behavior-x:contain}:host:has(.tab-bar:not(.dir-vertical):not(.is-collapsed)) .tab-bar{min-width:max-content;max-width:none}.tab-bar{flex:1;display:flex;max-width:100%;gap:2px;-webkit-user-select:none;user-select:none}.bg-surface{background:linear-gradient(var(--fold-color-bg-rail-tertiary),var(--fold-color-bg-rail-tertiary)),var(--fold-color-bg-page);padding:var(--fold-space-xs) var(--fold-space-sm) 0}.bg-surface.dir-vertical{padding:var(--fold-space-md) var(--fold-space-sm)}.tab-bar-item{flex:1;display:flex;align-items:center;justify-content:center;gap:var(--fold-space-sm);padding:var(--fold-space-sm) var(--fold-space-sm);background:none;border:none;color:var(--fold-color-text-muted);font-family:inherit;font-size:10px;font-weight:600;cursor:pointer;text-align:center;text-decoration:none;transition:color .1s ease,background .1s ease,border-color .1s ease;white-space:nowrap}.tab-bar-item:hover{color:var(--fold-color-text-secondary)}.tab-bar-item.is-disabled{opacity:.5;cursor:default;pointer-events:none}.size-comfortable .tab-bar-item{flex:0 1 auto;gap:var(--fold-space-sm);padding:var(--fold-space-md) var(--fold-space-lg);font-size:var(--fold-text-sm)}.dir-vertical.size-comfortable .tab-bar-item{padding:var(--fold-space-md) var(--fold-space-md);font-size:var(--fold-text-md)}.style-underline{border-bottom:1px solid var(--fold-color-border)}.style-underline .tab-bar-item{border-bottom:2px solid transparent;margin-bottom:-1px}.style-underline .tab-bar-item.is-active{color:var(--fold-color-text);border-bottom-color:var(--fold-color-primary)}.style-fill .tab-bar-item{border-radius:var(--fold-radius-sm);border:1px solid transparent}.style-fill .tab-bar-item.is-active{background:var(--fold-color-primary-surface);color:var(--fold-color-primary-text);font-weight:600}.style-fill .tab-bar-item:hover:not(.is-active){background:var(--fold-color-surface-hover);color:var(--fold-color-text)}.dir-vertical{flex-direction:column}.dir-vertical .tab-bar-item{flex:none;justify-content:flex-start;text-align:left;padding:var(--fold-space-sm) var(--fold-space-md);gap:var(--fold-space-sm);border-radius:var(--fold-radius-sm);font-size:var(--fold-text-sm);font-weight:500}.dir-vertical.style-underline{border-bottom:none;border-right:1px solid var(--fold-color-border)}.dir-vertical.style-underline .tab-bar-item{border-bottom:none;border-left:2px solid transparent;margin-bottom:0;margin-right:-1px}.dir-vertical.style-underline .tab-bar-item.is-active{border-left-color:var(--fold-color-primary)}.dir-vertical.style-fill .tab-bar-item.is-active{background:var(--fold-color-primary-surface);color:var(--fold-color-primary-text);font-weight:600}.is-collapsed .tab-bar-item{position:relative;flex:0 0 auto;gap:0}.is-collapsed .tab-bar-item:not(.is-active) .tab-bar-badge{display:none}.is-collapsed .tab-bar-item.is-active{flex:1 1 auto;min-width:0;gap:var(--fold-space-sm)}.is-collapsed .tab-bar-item.is-active .tab-bar-label{overflow:hidden;text-overflow:ellipsis}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active) .tab-bar-icon~.tab-bar-label{position:absolute;padding:var(--fold-space-xs) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-glass);border:1px solid var(--fold-color-glass-border);color:var(--fold-color-text);font-size:var(--fold-text-xs);font-weight:500;white-space:nowrap;opacity:0;pointer-events:none;box-shadow:var(--fold-shadow-md);transition:opacity var(--fold-motion-fast);z-index:100}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-icon~.tab-bar-label{left:calc(100% + 8px);top:50%;transform:translateY(-50%)}.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active) .tab-bar-icon~.tab-bar-label{top:calc(100% + 6px);left:50%;transform:translate(-50%)}.dir-vertical.is-collapsed .tab-bar-item:hover .tab-bar-icon~.tab-bar-label,.dir-vertical.is-collapsed .tab-bar-item:focus-visible .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active):hover .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active):focus-visible .tab-bar-icon~.tab-bar-label{opacity:1}.dir-vertical.is-collapsed{align-items:center}.dir-vertical.is-collapsed .tab-bar-item,.dir-vertical.is-collapsed .tab-bar-item.is-active{justify-content:center;gap:0}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-badge{display:block;position:absolute;top:-2px;right:-2px;transform:scale(.85);transform-origin:top right;pointer-events:none}:host:has(.is-collapsed){overflow:visible}.tab-bar-icon{flex-shrink:0}.tab-bar-initial{display:grid;place-items:center;width:18px;height:18px;border-radius:var(--fold-radius-sm);font-size:11px;font-weight:700;line-height:1;text-transform:uppercase}.tab-bar-badge{flex-shrink:0;font-variant-numeric:tabular-nums}.tab-bar-item:focus-visible{outline:2px solid var(--fold-color-primary);outline-offset:-2px;border-radius:var(--fold-radius-sm)}\n"], dependencies: [{ kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }, { kind: "component", type: FoldBadgeComponent, selector: "fold-badge", inputs: ["content", "radius", "variant"] }] });
11363
11556
  }
11364
11557
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldTabsComponent, decorators: [{
11365
11558
  type: Component,
11366
- args: [{ selector: "fold-tabs", standalone: true, exportAs: "foldTabs", imports: [FoldIconComponent, FoldBadgeComponent], template: "<div\n class=\"tab-bar\"\n role=\"tablist\"\n [attr.aria-orientation]=\"\n resolvedDirection() === 'vertical' ? 'vertical' : 'horizontal'\n \"\n [class.style-underline]=\"activeStyle() === 'underline'\"\n [class.style-fill]=\"activeStyle() === 'fill'\"\n [class.dir-vertical]=\"resolvedDirection() === 'vertical'\"\n [class.size-comfortable]=\"size() === 'comfortable'\"\n [class.is-collapsed]=\"collapsed()\"\n [class.bg-surface]=\"background() === 'surface'\"\n (keydown)=\"onKeydown($event)\"\n>\n @for (tab of tabs(); track tab.key) {\n <button\n #tabBtn\n type=\"button\"\n role=\"tab\"\n class=\"tab-bar-item\"\n [id]=\"tabId(tab.key)\"\n [class.is-active]=\"activeKey() === tab.key\"\n [attr.aria-selected]=\"activeKey() === tab.key\"\n [attr.aria-controls]=\"panelId(tab.key)\"\n [tabindex]=\"activeKey() === tab.key ? 0 : -1\"\n (click)=\"select(tab.key)\"\n >\n @if (tab.icon; as ic) {\n <fold-icon class=\"tab-bar-icon\" [name]=\"ic\" size=\"sm\" />\n } @else if (collapsed()) {\n <span class=\"tab-bar-icon tab-bar-initial\" aria-hidden=\"true\">{{\n tab.label.charAt(0)\n }}</span>\n }\n <span class=\"tab-bar-label\">{{ tab.label }}</span>\n @if (tab.badge !== undefined && tab.badge !== null) {\n <fold-badge\n class=\"tab-bar-badge\"\n [content]=\"tab.badge + ''\"\n [variant]=\"activeKey() === tab.key ? 'accent' : 'neutral'\"\n />\n }\n </button>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;width:100%;max-width:100%;overflow:hidden}:host:has(.tab-bar:not(.dir-vertical):not(.is-collapsed)){overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;overscroll-behavior-x:contain}:host:has(.tab-bar:not(.dir-vertical):not(.is-collapsed)) .tab-bar{min-width:max-content;max-width:none}.tab-bar{flex:1;display:flex;max-width:100%;gap:2px;-webkit-user-select:none;user-select:none}.bg-surface{background:linear-gradient(var(--fold-color-bg-rail-tertiary),var(--fold-color-bg-rail-tertiary)),var(--fold-color-bg-page);padding:var(--fold-space-xs) var(--fold-space-sm) 0}.bg-surface.dir-vertical{padding:var(--fold-space-md) var(--fold-space-sm)}.tab-bar-item{flex:1;display:flex;align-items:center;justify-content:center;gap:var(--fold-space-sm);padding:var(--fold-space-sm) var(--fold-space-sm);background:none;border:none;color:var(--fold-color-text-muted);font-family:inherit;font-size:10px;font-weight:600;cursor:pointer;text-align:center;text-decoration:none;transition:color .1s ease,background .1s ease,border-color .1s ease;white-space:nowrap}.tab-bar-item:hover{color:var(--fold-color-text-secondary)}.tab-bar-item.is-disabled{opacity:.5;cursor:default;pointer-events:none}.size-comfortable .tab-bar-item{flex:0 1 auto;gap:var(--fold-space-sm);padding:var(--fold-space-md) var(--fold-space-lg);font-size:var(--fold-text-sm)}.dir-vertical.size-comfortable .tab-bar-item{padding:var(--fold-space-md) var(--fold-space-md);font-size:var(--fold-text-md)}.style-underline{border-bottom:1px solid var(--fold-color-border)}.style-underline .tab-bar-item{border-bottom:2px solid transparent;margin-bottom:-1px}.style-underline .tab-bar-item.is-active{color:var(--fold-color-text);border-bottom-color:var(--fold-color-primary)}.style-fill .tab-bar-item{border-radius:var(--fold-radius-sm);border:1px solid transparent}.style-fill .tab-bar-item.is-active{background:var(--fold-color-primary-surface);color:var(--fold-color-primary-text);font-weight:600}.style-fill .tab-bar-item:hover:not(.is-active){background:var(--fold-color-surface-hover);color:var(--fold-color-text)}.dir-vertical{flex-direction:column}.dir-vertical .tab-bar-item{flex:none;justify-content:flex-start;text-align:left;padding:var(--fold-space-sm) var(--fold-space-md);gap:var(--fold-space-sm);border-radius:var(--fold-radius-sm);font-size:var(--fold-text-sm);font-weight:500}.dir-vertical.style-underline{border-bottom:none;border-right:1px solid var(--fold-color-border)}.dir-vertical.style-underline .tab-bar-item{border-bottom:none;border-left:2px solid transparent;margin-bottom:0;margin-right:-1px}.dir-vertical.style-underline .tab-bar-item.is-active{border-left-color:var(--fold-color-primary)}.dir-vertical.style-fill .tab-bar-item.is-active{background:var(--fold-color-primary-surface);color:var(--fold-color-primary-text);font-weight:600}.is-collapsed .tab-bar-item{position:relative;flex:0 0 auto;gap:0}.is-collapsed .tab-bar-item:not(.is-active) .tab-bar-badge{display:none}.is-collapsed .tab-bar-item.is-active{flex:1 1 auto;min-width:0;gap:var(--fold-space-sm)}.is-collapsed .tab-bar-item.is-active .tab-bar-label{overflow:hidden;text-overflow:ellipsis}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active) .tab-bar-icon~.tab-bar-label{position:absolute;padding:var(--fold-space-xs) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-glass);border:1px solid var(--fold-color-glass-border);color:var(--fold-color-text);font-size:var(--fold-text-xs);font-weight:500;white-space:nowrap;opacity:0;pointer-events:none;box-shadow:var(--fold-shadow-md);transition:opacity var(--fold-motion-fast);z-index:100}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-icon~.tab-bar-label{left:calc(100% + 8px);top:50%;transform:translateY(-50%)}.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active) .tab-bar-icon~.tab-bar-label{top:calc(100% + 6px);left:50%;transform:translate(-50%)}.dir-vertical.is-collapsed .tab-bar-item:hover .tab-bar-icon~.tab-bar-label,.dir-vertical.is-collapsed .tab-bar-item:focus-visible .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active):hover .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active):focus-visible .tab-bar-icon~.tab-bar-label{opacity:1}.dir-vertical.is-collapsed{align-items:center}.dir-vertical.is-collapsed .tab-bar-item,.dir-vertical.is-collapsed .tab-bar-item.is-active{justify-content:center;gap:0}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-badge{display:block;position:absolute;top:-2px;right:-2px;transform:scale(.85);transform-origin:top right;pointer-events:none}:host:has(.is-collapsed){overflow:visible}.tab-bar-icon{flex-shrink:0}.tab-bar-initial{display:grid;place-items:center;width:18px;height:18px;border-radius:var(--fold-radius-sm);font-size:11px;font-weight:700;line-height:1;text-transform:uppercase}.tab-bar-badge{flex-shrink:0;font-variant-numeric:tabular-nums}.tab-bar-item:focus-visible{outline:2px solid var(--fold-color-primary);outline-offset:-2px;border-radius:var(--fold-radius-sm)}\n"] }]
11367
- }], propDecorators: { tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: true }] }], activeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeKey", required: true }] }, { type: i0.Output, args: ["activeKeyChange"] }], activeStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeStyle", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }], background: [{ type: i0.Input, args: [{ isSignal: true, alias: "background", required: false }] }], tabButtons: [{ type: i0.ViewChildren, args: ["tabBtn", { isSignal: true }] }] } });
11559
+ args: [{ selector: "fold-tabs", standalone: true, exportAs: "foldTabs", imports: [FoldIconComponent, FoldBadgeComponent], host: { "[class.is-sticky]": "sticky()" }, template: "<div\n class=\"tab-bar\"\n role=\"tablist\"\n [attr.aria-orientation]=\"\n resolvedDirection() === 'vertical' ? 'vertical' : 'horizontal'\n \"\n [class.style-underline]=\"activeStyle() === 'underline'\"\n [class.style-fill]=\"activeStyle() === 'fill'\"\n [class.dir-vertical]=\"resolvedDirection() === 'vertical'\"\n [class.size-comfortable]=\"size() === 'comfortable'\"\n [class.is-collapsed]=\"collapsed()\"\n [class.bg-surface]=\"background() === 'surface'\"\n (keydown)=\"onKeydown($event)\"\n>\n @for (tab of tabs(); track tab.key) {\n <button\n #tabBtn\n type=\"button\"\n role=\"tab\"\n class=\"tab-bar-item\"\n [id]=\"tabId(tab.key)\"\n [class.is-active]=\"activeKey() === tab.key\"\n [attr.aria-selected]=\"activeKey() === tab.key\"\n [attr.aria-controls]=\"panelId(tab.key)\"\n [tabindex]=\"activeKey() === tab.key ? 0 : -1\"\n (click)=\"select(tab.key)\"\n >\n @if (tab.icon; as ic) {\n <fold-icon class=\"tab-bar-icon\" [name]=\"ic\" size=\"sm\" />\n } @else if (collapsed()) {\n <span class=\"tab-bar-icon tab-bar-initial\" aria-hidden=\"true\">{{\n tab.label.charAt(0)\n }}</span>\n }\n <span class=\"tab-bar-label\">{{ tab.label }}</span>\n @if (tab.badge !== undefined && tab.badge !== null) {\n <fold-badge\n class=\"tab-bar-badge\"\n [content]=\"tab.badge + ''\"\n [variant]=\"activeKey() === tab.key ? 'accent' : 'neutral'\"\n />\n }\n </button>\n }\n</div>\n", styles: ["@charset \"UTF-8\";:host{display:flex;width:100%;max-width:100%;overflow:hidden}:host(.is-sticky){position:sticky;top:0;z-index:2}:host:has(.tab-bar:not(.dir-vertical):not(.is-collapsed)){overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;overscroll-behavior-x:contain}:host:has(.tab-bar:not(.dir-vertical):not(.is-collapsed)) .tab-bar{min-width:max-content;max-width:none}.tab-bar{flex:1;display:flex;max-width:100%;gap:2px;-webkit-user-select:none;user-select:none}.bg-surface{background:linear-gradient(var(--fold-color-bg-rail-tertiary),var(--fold-color-bg-rail-tertiary)),var(--fold-color-bg-page);padding:var(--fold-space-xs) var(--fold-space-sm) 0}.bg-surface.dir-vertical{padding:var(--fold-space-md) var(--fold-space-sm)}.tab-bar-item{flex:1;display:flex;align-items:center;justify-content:center;gap:var(--fold-space-sm);padding:var(--fold-space-sm) var(--fold-space-sm);background:none;border:none;color:var(--fold-color-text-muted);font-family:inherit;font-size:10px;font-weight:600;cursor:pointer;text-align:center;text-decoration:none;transition:color .1s ease,background .1s ease,border-color .1s ease;white-space:nowrap}.tab-bar-item:hover{color:var(--fold-color-text-secondary)}.tab-bar-item.is-disabled{opacity:.5;cursor:default;pointer-events:none}.size-comfortable .tab-bar-item{flex:0 1 auto;gap:var(--fold-space-sm);padding:var(--fold-space-md) var(--fold-space-lg);font-size:var(--fold-text-sm)}.dir-vertical.size-comfortable .tab-bar-item{padding:var(--fold-space-md) var(--fold-space-md);font-size:var(--fold-text-md)}.style-underline{border-bottom:1px solid var(--fold-color-border)}.style-underline .tab-bar-item{border-bottom:2px solid transparent;margin-bottom:-1px}.style-underline .tab-bar-item.is-active{color:var(--fold-color-text);border-bottom-color:var(--fold-color-primary)}.style-fill .tab-bar-item{border-radius:var(--fold-radius-sm);border:1px solid transparent}.style-fill .tab-bar-item.is-active{background:var(--fold-color-primary-surface);color:var(--fold-color-primary-text);font-weight:600}.style-fill .tab-bar-item:hover:not(.is-active){background:var(--fold-color-surface-hover);color:var(--fold-color-text)}.dir-vertical{flex-direction:column}.dir-vertical .tab-bar-item{flex:none;justify-content:flex-start;text-align:left;padding:var(--fold-space-sm) var(--fold-space-md);gap:var(--fold-space-sm);border-radius:var(--fold-radius-sm);font-size:var(--fold-text-sm);font-weight:500}.dir-vertical.style-underline{border-bottom:none;border-right:1px solid var(--fold-color-border)}.dir-vertical.style-underline .tab-bar-item{border-bottom:none;border-left:2px solid transparent;margin-bottom:0;margin-right:-1px}.dir-vertical.style-underline .tab-bar-item.is-active{border-left-color:var(--fold-color-primary)}.dir-vertical.style-fill .tab-bar-item.is-active{background:var(--fold-color-primary-surface);color:var(--fold-color-primary-text);font-weight:600}.is-collapsed .tab-bar-item{position:relative;flex:0 0 auto;gap:0}.is-collapsed .tab-bar-item:not(.is-active) .tab-bar-badge{display:none}.is-collapsed .tab-bar-item.is-active{flex:1 1 auto;min-width:0;gap:var(--fold-space-sm)}.is-collapsed .tab-bar-item.is-active .tab-bar-label{overflow:hidden;text-overflow:ellipsis}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active) .tab-bar-icon~.tab-bar-label{position:absolute;padding:var(--fold-space-xs) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-glass);border:1px solid var(--fold-color-glass-border);color:var(--fold-color-text);font-size:var(--fold-text-xs);font-weight:500;white-space:nowrap;opacity:0;pointer-events:none;box-shadow:var(--fold-shadow-md);transition:opacity var(--fold-motion-fast);z-index:100}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-icon~.tab-bar-label{left:calc(100% + 8px);top:50%;transform:translateY(-50%)}.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active) .tab-bar-icon~.tab-bar-label{top:calc(100% + 6px);left:50%;transform:translate(-50%)}.dir-vertical.is-collapsed .tab-bar-item:hover .tab-bar-icon~.tab-bar-label,.dir-vertical.is-collapsed .tab-bar-item:focus-visible .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active):hover .tab-bar-icon~.tab-bar-label,.is-collapsed:not(.dir-vertical) .tab-bar-item:not(.is-active):focus-visible .tab-bar-icon~.tab-bar-label{opacity:1}.dir-vertical.is-collapsed{align-items:center}.dir-vertical.is-collapsed .tab-bar-item,.dir-vertical.is-collapsed .tab-bar-item.is-active{justify-content:center;gap:0}.dir-vertical.is-collapsed .tab-bar-item .tab-bar-badge{display:block;position:absolute;top:-2px;right:-2px;transform:scale(.85);transform-origin:top right;pointer-events:none}:host:has(.is-collapsed){overflow:visible}.tab-bar-icon{flex-shrink:0}.tab-bar-initial{display:grid;place-items:center;width:18px;height:18px;border-radius:var(--fold-radius-sm);font-size:11px;font-weight:700;line-height:1;text-transform:uppercase}.tab-bar-badge{flex-shrink:0;font-variant-numeric:tabular-nums}.tab-bar-item:focus-visible{outline:2px solid var(--fold-color-primary);outline-offset:-2px;border-radius:var(--fold-radius-sm)}\n"] }]
11560
+ }], propDecorators: { tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: true }] }], activeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeKey", required: true }] }, { type: i0.Output, args: ["activeKeyChange"] }], activeStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeStyle", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }], background: [{ type: i0.Input, args: [{ isSignal: true, alias: "background", required: false }] }], sticky: [{ type: i0.Input, args: [{ isSignal: true, alias: "sticky", required: false }] }], tabButtons: [{ type: i0.ViewChildren, args: ["tabBtn", { isSignal: true }] }] } });
11368
11561
 
11369
11562
  /**
11370
11563
  * `<fold-tab-panel>` — one panel of a {@link FoldTabsComponent}. Handed the bar
@@ -11387,7 +11580,11 @@ class FoldTabPanelComponent {
11387
11580
  /** The owning `fold-tabs`, read via its template ref (`#t="foldTabs"`). */
11388
11581
  tabs = input.required(/* @ts-ignore */
11389
11582
  ...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
11390
- /** This panel's tab key — must match one tab in the bar. */
11583
+ /**
11584
+ * This panel's tab key — must match one tab in the bar. When the bar is typed
11585
+ * on a union of keys, a key outside it fails to compile instead of rendering a
11586
+ * panel no tab can ever reach.
11587
+ */
11391
11588
  key = input.required(/* @ts-ignore */
11392
11589
  ...(ngDevMode ? [{ debugName: "key" }] : /* istanbul ignore next */ []));
11393
11590
  isActive = computed(() => this.tabs().activeKey() === this.key(), /* @ts-ignore */
@@ -13060,5 +13257,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
13060
13257
  * Generated bundle index. Do not edit.
13061
13258
  */
13062
13259
 
13063
- export { FOLD_AUTO_PALETTES, FOLD_BLUR_TOKENS, FOLD_BUILTIN_ICONS, FOLD_BUILTIN_ICON_CATEGORIES, FOLD_CALENDAR_DEFAULT_LABELS, FOLD_CALENDAR_FORMATS, FOLD_CALENDAR_LABELS, FOLD_DATA_TABLE_DEFAULT_LABELS, FOLD_DATA_TABLE_LABELS, FOLD_DEFAULT_WEEKEND_DAYS, FOLD_FALLBACK_WEEK_INFO, FOLD_INLINE_CONFIRM_DEFAULT_LABELS, FOLD_INLINE_CONFIRM_LABELS, FOLD_MINUTES_PER_DAY, FOLD_MOTION_TOKENS, FOLD_PAGINATOR_DEFAULT_LABELS, FOLD_PAGINATOR_LABELS, FOLD_PALETTE_DEFAULT, FOLD_PANEL_CLOSE_LABEL, FOLD_PANEL_DEFAULTS, FOLD_RADIUS_TOKENS, FOLD_SEMANTIC_COLOR_TOKENS, FOLD_SHADOW_TOKENS, FOLD_SPACE_TOKENS, FOLD_TEXT_TOKENS, FOLD_TOAST_CONFIG, FoldAppShellComponent, FoldAsideLayoutComponent, FoldAvatarComponent, FoldAvatarDetailComponent, FoldAvatarListComponent, FoldBackLinkComponent, FoldBadgeComponent, FoldBreadcrumbComponent, FoldButtonComponent, FoldButtonIconComponent, FoldCalendarAgendaComponent, FoldCalendarChromeDirective, FoldCalendarDayComponent, FoldCalendarDayDirective, FoldCalendarEventDirective, FoldCalendarHeadingDirective, FoldCalendarListComponent, FoldCalendarMonthComponent, FoldCalendarOverflowDirective, FoldCalendarSourceFilterComponent, FoldCalendarTimegridComponent, FoldCalendarTitleDirective, FoldCalendarToolbarComponent, FoldCalendarWeekComponent, FoldCalloutComponent, FoldCardComponent, FoldCheckboxComponent, FoldChoiceRowComponent, FoldContextCardComponent, FoldDangerZoneComponent, FoldDataTableCellDirective, FoldDataTableComponent, FoldDataTableRowCardDirective, FoldDateComponent, FoldDisclosureComponent, FoldDropdownComponent, FoldDropdownItemComponent, FoldElementTitleComponent, FoldElevatedDirective, FoldEmptyStateComponent, FoldFieldComponent, FoldFieldIdDirective, FoldFieldListComponent, FoldFileDropzoneComponent, FoldHeroCardComponent, FoldHeroSectionComponent, FoldIconComponent, FoldIconRegistry, FoldIdService, FoldInfoComponent, FoldInlineConfirmComponent, FoldInputComponent, FoldLinkComponent, FoldListboxComponent, FoldLoadingStateComponent, FoldMenuComponent, FoldMenuItemComponent, FoldMenuSectionComponent, FoldMenuSeparatorComponent, FoldMultiselectComponent, FoldNavLauncherComponent, FoldNavLayoutComponent, FoldNavTileComponent, FoldNumberInputComponent, FoldOptgroupComponent, FoldOptionComponent, FoldPageLayoutComponent, FoldPageSectionComponent, FoldPageTitleDirective, FoldPaginatorComponent, FoldPaletteRegistry, FoldPanelComponentOutletDirective, FoldPanelFooterComponent, FoldPanelHeaderComponent, FoldPanelHostComponent, FoldPanelHostService, FoldPanelRef, FoldPanelToggle, FoldPasswordFieldComponent, FoldPopoverComponent, FoldPopoverTriggerDirective, FoldRangeSliderComponent, FoldRepeatPressDirective, FoldScrollRegionDirective, FoldSearchComponent, FoldSelectComponent, FoldSliderComponent, FoldSpinnerComponent, FoldStatusBadgeComponent, FoldStickyColumnDirective, FoldSurfaceDirective, FoldTabPanelComponent, FoldTabsComponent, FoldTextareaComponent, FoldTimeComponent, FoldTimelineComponent, FoldToastComponent, FoldToastContainerComponent, FoldToastService, FoldToggleIconComponent, FoldViewNavComponent, FoldViewToggleComponent, ScrollRegionRegistry, autoUpdate, computePlacement, foldAddDays, foldAddMinutes, foldAddMonths, foldBlurVar, foldBuildAgenda, foldBuildDay, foldBuildMonthGrid, foldBuildTimeGrid, foldBuildWeek, foldCalendarNextFocus, foldCardBandChrome, foldColorProperty, foldColorVar, foldCountActionable, foldDaysBetween, foldDefaultPasswordRules, foldEndOfMonth, foldEventsInRange, foldEventsOnDay, foldFilterBySource, foldFromMinutes, foldFromNativeDate, foldFromTemporal, foldHashSeed, foldIsActionable, foldIsCalendarDate, foldIsCalendarTime, foldIsTimed, foldIsWeekend, foldIsoWeek, foldIsoWeekYear, foldLayOutOverlaps, foldLocaleWeekInfo, foldMotionVar, foldRadiusVar, foldRangeForView, foldRegexRule, foldResolvePalette, foldShadowVar, foldShiftDate, foldSpaceVar, foldStartOfMonth, foldStartOfWeek, foldTextVar, foldToMinutes, foldToNativeDate, foldToday, foldViewTitle, foldWeekdayIndex, foldWeekdayOf, isFoldSelectOptionGroup, observeElementWidth, provideFoldCalendarLabels, provideFoldDataTableLabels, provideFoldIcons, provideFoldInlineConfirmLabels, provideFoldPaginatorLabels, provideFoldPalette, provideFoldPanelDefaults, provideFoldPanelLabels, provideFoldToasts };
13260
+ export { FOLD_AUTO_PALETTES, FOLD_BLUR_TOKENS, FOLD_BUILTIN_ICONS, FOLD_BUILTIN_ICON_CATEGORIES, FOLD_CALENDAR_DEFAULT_LABELS, FOLD_CALENDAR_FORMATS, FOLD_CALENDAR_LABELS, FOLD_COMMON_DEFAULT_LABELS, FOLD_COMMON_LABELS, FOLD_DATA_TABLE_DEFAULT_LABELS, FOLD_DATA_TABLE_LABELS, FOLD_DEFAULT_WEEKEND_DAYS, FOLD_FALLBACK_WEEK_INFO, FOLD_INLINE_CONFIRM_DEFAULT_LABELS, FOLD_INLINE_CONFIRM_LABELS, FOLD_MINUTES_PER_DAY, FOLD_MOTION_TOKENS, FOLD_PAGINATOR_DEFAULT_LABELS, FOLD_PAGINATOR_LABELS, FOLD_PALETTE_DEFAULT, FOLD_PANEL_CLOSE_LABEL, FOLD_PANEL_DEFAULTS, FOLD_RADIUS_TOKENS, FOLD_SEMANTIC_COLOR_TOKENS, FOLD_SHADOW_TOKENS, FOLD_SPACE_TOKENS, FOLD_TEXT_TOKENS, FOLD_TOAST_CONFIG, FoldAppShellComponent, FoldAsideLayoutComponent, FoldAvatarComponent, FoldAvatarDetailComponent, FoldAvatarListComponent, FoldBackLinkComponent, FoldBadgeComponent, FoldBreadcrumbComponent, FoldButtonComponent, FoldButtonIconComponent, FoldCalendarAgendaComponent, FoldCalendarChromeDirective, FoldCalendarDayComponent, FoldCalendarDayDirective, FoldCalendarEventDirective, FoldCalendarHeadingDirective, FoldCalendarListComponent, FoldCalendarMonthComponent, FoldCalendarOverflowDirective, FoldCalendarSourceFilterComponent, FoldCalendarTimegridComponent, FoldCalendarTitleDirective, FoldCalendarToolbarComponent, FoldCalendarWeekComponent, FoldCalloutComponent, FoldCardComponent, FoldCheckboxComponent, FoldChoiceRowComponent, FoldContextCardComponent, FoldDangerZoneComponent, FoldDataTableCellDirective, FoldDataTableComponent, FoldDataTableRowCardDirective, FoldDateComponent, FoldDisclosureComponent, FoldDropdownComponent, FoldDropdownItemComponent, FoldElementTitleComponent, FoldElevatedDirective, FoldEmptyStateComponent, FoldFieldComponent, FoldFieldIdDirective, FoldFieldListComponent, FoldFileDropzoneComponent, FoldHeroCardComponent, FoldHeroSectionComponent, FoldIconComponent, FoldIconRegistry, FoldIdService, FoldInfoComponent, FoldInlineConfirmComponent, FoldInputComponent, FoldLinkComponent, FoldListboxComponent, FoldLoadingStateComponent, FoldMenuComponent, FoldMenuItemComponent, FoldMenuSectionComponent, FoldMenuSeparatorComponent, FoldMultiselectComponent, FoldNavLauncherComponent, FoldNavLayoutComponent, FoldNavTileComponent, FoldNumberInputComponent, FoldOptgroupComponent, FoldOptionComponent, FoldPageLayoutComponent, FoldPageSectionComponent, FoldPageTitleDirective, FoldPaginatorComponent, FoldPaletteRegistry, FoldPanelComponentOutletDirective, FoldPanelFooterComponent, FoldPanelHeaderComponent, FoldPanelHostComponent, FoldPanelHostService, FoldPanelRef, FoldPanelToggle, FoldPasswordFieldComponent, FoldPopoverComponent, FoldPopoverTriggerDirective, FoldRangeSliderComponent, FoldRepeatPressDirective, FoldScrollRegionDirective, FoldSearchComponent, FoldSelectComponent, FoldSliderComponent, FoldSpinnerComponent, FoldStatusBadgeComponent, FoldStickyColumnDirective, FoldSurfaceDirective, FoldTabPanelComponent, FoldTabsComponent, FoldTextareaComponent, FoldTimeComponent, FoldTimelineComponent, FoldToastComponent, FoldToastContainerComponent, FoldToastService, FoldToggleIconComponent, FoldViewNavComponent, FoldViewToggleComponent, ScrollRegionRegistry, autoUpdate, computePlacement, foldAddDays, foldAddMinutes, foldAddMonths, foldBlurVar, foldBuildAgenda, foldBuildDay, foldBuildMonthGrid, foldBuildTimeGrid, foldBuildWeek, foldCalendarNextFocus, foldCardBandChrome, foldColorProperty, foldColorVar, foldCountActionable, foldDaysBetween, foldDefaultPasswordRules, foldEndOfMonth, foldEventsInRange, foldEventsOnDay, foldFilterBySource, foldFromMinutes, foldFromNativeDate, foldFromTemporal, foldHashSeed, foldIsActionable, foldIsCalendarDate, foldIsCalendarTime, foldIsTimed, foldIsWeekend, foldIsoWeek, foldIsoWeekYear, foldLayOutOverlaps, foldLocaleWeekInfo, foldMotionVar, foldRadiusVar, foldRangeForView, foldRegexRule, foldResolvePalette, foldShadowVar, foldShiftDate, foldSpaceVar, foldStartOfMonth, foldStartOfWeek, foldTextVar, foldToMinutes, foldToNativeDate, foldToday, foldViewTitle, foldWeekdayIndex, foldWeekdayOf, isFoldSelectOptionGroup, observeElementWidth, provideFoldCalendarLabels, provideFoldCommonLabels, provideFoldDataTableLabels, provideFoldIcons, provideFoldInlineConfirmLabels, provideFoldPaginatorLabels, provideFoldPalette, provideFoldPanelDefaults, provideFoldPanelLabels, provideFoldToasts };
13064
13261
  //# sourceMappingURL=fold-ng.mjs.map