@wildmason/aegis 1.7.6 → 1.9.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.
@@ -1,6 +1,6 @@
1
+ import { CdkTrapFocus } from '@angular/cdk/a11y';
1
2
  import * as i0 from '@angular/core';
2
3
  import { input, output, HostListener, ChangeDetectionStrategy, Component, model, signal, computed, inject, ElementRef, Renderer2, ChangeDetectorRef, viewChild, effect, ViewEncapsulation, Input, Directive, contentChildren, forwardRef, ViewChild, Injectable } from '@angular/core';
3
- import { CdkTrapFocus } from '@angular/cdk/a11y';
4
4
  import { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay';
5
5
  import { NgTemplateOutlet } from '@angular/common';
6
6
  import { NG_VALUE_ACCESSOR } from '@angular/forms';
@@ -12,8 +12,24 @@ import { invoke } from '@tauri-apps/api/core';
12
12
  /**
13
13
  * WmModal — Lightweight modal backdrop with Escape key and click-outside dismissal.
14
14
  *
15
- * Owns the fixed backdrop, centering, and keyboard/pointer dismissal so individual
16
- * modal components don't need to repeat this logic or add their own HostListeners.
15
+ * Owns the fixed backdrop, centering, keyboard/pointer dismissal AND the focus trap,
16
+ * so individual modal components don't need to repeat this logic or add their own
17
+ * HostListeners.
18
+ *
19
+ * ## Focus is trapped here, and it has to be
20
+ *
21
+ * The trap lives on the wrapper INSIDE this component's `@if (visible())`, exactly as
22
+ * `wm-dialog` does. That placement is not a style preference — it is the only placement
23
+ * that works. `CdkTrapFocus.ngAfterContentInit` calls `attachAnchors()`, which is a
24
+ * no-op unless the element already has a `parentNode`. An element the consumer projects
25
+ * in through `<ng-content/>` does not have one at that moment, so a consumer-applied
26
+ * `cdkTrapFocus` attaches zero anchors and silently traps nothing — `autoCapture` still
27
+ * pulls focus in, which makes it look like it works, while Tab walks straight out the
28
+ * back of the dialog. Three Helm surfaces shipped that way before it was measured.
29
+ *
30
+ * Consumers must therefore NOT add their own `cdkTrapFocus`; nesting a second trap
31
+ * inside this one only creates a conflict. Consumers DO still own `role="dialog"`,
32
+ * `aria-modal` and the accessible name, because only they know what the dialog is.
17
33
  *
18
34
  * Usage:
19
35
  * <wm-modal [visible]="visible()" (dismiss)="close()">
@@ -44,11 +60,11 @@ class WmModal {
44
60
  this.dismiss.emit();
45
61
  }
46
62
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: WmModal, deps: [], target: i0.ɵɵFactoryTarget.Component });
47
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: WmModal, isStandalone: true, selector: "wm-modal", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: true, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dismiss: "dismiss" }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: "@if (visible()) {\r\n <div [class]=\"align() === 'top'\r\n ? 'fixed inset-0 flex items-start justify-center pt-20 z-50'\r\n : 'fixed inset-0 flex items-center justify-center z-50'\"\r\n style=\"background: var(--wm-modal-backdrop)\"\r\n (click)=\"dismiss.emit()\">\r\n <div (click)=\"$event.stopPropagation()\">\r\n <ng-content />\r\n </div>\r\n </div>\r\n}\r\n", changeDetection: i0.ChangeDetectionStrategy.OnPush });
63
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: WmModal, isStandalone: true, selector: "wm-modal", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: true, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dismiss: "dismiss" }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: "@if (visible()) {\n <div [class]=\"align() === 'top'\n ? 'fixed inset-0 flex items-start justify-center pt-20 z-50'\n : 'fixed inset-0 flex items-center justify-center z-50'\"\n style=\"background: var(--wm-modal-backdrop)\"\n (click)=\"dismiss.emit()\">\n <!-- The trap must sit on an element this template owns, inside this `@if`, so it\n has a parentNode by the time CdkTrapFocus runs ngAfterContentInit. A consumer\n cannot achieve that on projected content \u2014 see the class doc. -->\n <div (click)=\"$event.stopPropagation()\" cdkTrapFocus [cdkTrapFocusAutoCapture]=\"true\">\n <ng-content />\n </div>\n </div>\n}\n", dependencies: [{ kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
48
64
  }
49
65
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: WmModal, decorators: [{
50
66
  type: Component,
51
- args: [{ selector: 'wm-modal', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (visible()) {\r\n <div [class]=\"align() === 'top'\r\n ? 'fixed inset-0 flex items-start justify-center pt-20 z-50'\r\n : 'fixed inset-0 flex items-center justify-center z-50'\"\r\n style=\"background: var(--wm-modal-backdrop)\"\r\n (click)=\"dismiss.emit()\">\r\n <div (click)=\"$event.stopPropagation()\">\r\n <ng-content />\r\n </div>\r\n </div>\r\n}\r\n" }]
67
+ args: [{ selector: 'wm-modal', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CdkTrapFocus], template: "@if (visible()) {\n <div [class]=\"align() === 'top'\n ? 'fixed inset-0 flex items-start justify-center pt-20 z-50'\n : 'fixed inset-0 flex items-center justify-center z-50'\"\n style=\"background: var(--wm-modal-backdrop)\"\n (click)=\"dismiss.emit()\">\n <!-- The trap must sit on an element this template owns, inside this `@if`, so it\n has a parentNode by the time CdkTrapFocus runs ngAfterContentInit. A consumer\n cannot achieve that on projected content \u2014 see the class doc. -->\n <div (click)=\"$event.stopPropagation()\" cdkTrapFocus [cdkTrapFocusAutoCapture]=\"true\">\n <ng-content />\n </div>\n </div>\n}\n" }]
52
68
  }], propDecorators: { visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: true }] }], dismiss: [{ type: i0.Output, args: ["dismiss"] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], onEscape: [{
53
69
  type: HostListener,
54
70
  args: ['document:keydown.escape']
@@ -94,11 +110,11 @@ class WmDialog {
94
110
  this.close();
95
111
  }
96
112
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: WmDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
97
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: WmDialog, isStandalone: true, selector: "wm-dialog", inputs: { isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isOpen: "isOpenChange" }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: "@if (isOpen()) {\r\n <!-- Backdrop \u2014 click to close -->\r\n <div class=\"wm-dialog-backdrop\" (click)=\"close()\" aria-hidden=\"true\"></div>\r\n\r\n <!-- Panel -->\r\n <div\r\n class=\"wm-dialog\"\r\n [class]=\"'wm-dialog--' + size()\"\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n [attr.aria-labelledby]=\"title() ? 'wm-dialog-title' : null\"\r\n cdkTrapFocus\r\n [cdkTrapFocusAutoCapture]=\"true\"\r\n >\r\n <div class=\"wm-dialog-header\">\r\n <h2 class=\"wm-dialog-title\" id=\"wm-dialog-title\">{{ title() }}</h2>\r\n <button\r\n class=\"wm-dialog-close\"\r\n type=\"button\"\r\n (click)=\"close()\"\r\n aria-label=\"Close dialog\"\r\n >\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"wm-dialog-body\">\r\n <ng-content select=\"[body]\" />\r\n </div>\r\n </div>\r\n}\r\n", styles: [":host{display:contents}.wm-dialog-backdrop{position:fixed;inset:0;background:rgba(0,0,0,var(--wm-backdrop-opacity));z-index:100}.wm-dialog{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:101;background:var(--wm-bg-float);border:1px solid var(--wm-border);border-radius:var(--wm-radius-lg);box-shadow:var(--wm-shadow-lg);width:var(--wm-dialog-width, 480px);max-width:calc(100vw - 2rem);max-height:calc(100dvh - 4rem);display:flex;flex-direction:column;overflow:hidden;outline:none}.wm-dialog--sm{width:var(--wm-dialog-width, 360px)}.wm-dialog--lg{width:var(--wm-dialog-width, 640px)}.wm-dialog-header{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:1.125rem 1.25rem;flex-shrink:0;background:var(--wm-bg-raised)}.wm-dialog-title{font-size:1rem;font-weight:600;color:var(--wm-text-primary);margin:0;line-height:1.3}.wm-dialog-close{display:flex;align-items:center;justify-content:center;width:28px;height:28px;flex-shrink:0;border-radius:var(--wm-radius-sm);border:none;background:transparent;color:var(--wm-text-muted);cursor:pointer;transition:background var(--wm-transition-fast),color var(--wm-transition-fast)}.wm-dialog-close:hover{background:var(--wm-bg-hover);color:var(--wm-text-primary)}.wm-dialog-close:focus-visible{outline:2px solid var(--wm-color-accent);outline-offset:1px}.wm-dialog-body{flex:1;overflow-y:auto;padding:1rem 1.25rem 1.25rem;font-size:.875rem;color:var(--wm-text-secondary);line-height:1.6}@media(prefers-reduced-motion:reduce){.wm-dialog-close{transition:none}}\n"], dependencies: [{ kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }] });
113
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: WmDialog, isStandalone: true, selector: "wm-dialog", inputs: { isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isOpen: "isOpenChange" }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: "@if (isOpen()) {\n <!-- Backdrop \u2014 click to close -->\n <div class=\"wm-dialog-backdrop\" (click)=\"close()\" aria-hidden=\"true\"></div>\n\n <!-- Panel -->\n <div\n class=\"wm-dialog\"\n [class]=\"'wm-dialog--' + size()\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-labelledby]=\"title() ? 'wm-dialog-title' : null\"\n cdkTrapFocus\n [cdkTrapFocusAutoCapture]=\"true\"\n >\n <div class=\"wm-dialog-header\">\n <h2 class=\"wm-dialog-title\" id=\"wm-dialog-title\">{{ title() }}</h2>\n <button\n class=\"wm-dialog-close\"\n type=\"button\"\n (click)=\"close()\"\n aria-label=\"Close dialog\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n </div>\n\n <div class=\"wm-dialog-body\">\n <ng-content select=\"[body]\" />\n </div>\n </div>\n}\n", styles: [":host{display:contents}.wm-dialog-backdrop{position:fixed;inset:0;background:rgba(0,0,0,var(--wm-backdrop-opacity));z-index:100}.wm-dialog{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:101;background:var(--wm-bg-float);border:1px solid var(--wm-border);border-radius:var(--wm-radius-lg);box-shadow:var(--wm-shadow-lg);width:var(--wm-dialog-width, 480px);max-width:calc(100vw - 2rem);max-height:calc(100dvh - 4rem);display:flex;flex-direction:column;overflow:hidden;outline:none}.wm-dialog--sm{width:var(--wm-dialog-width, 360px)}.wm-dialog--lg{width:var(--wm-dialog-width, 640px)}.wm-dialog-header{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:1.125rem 1.25rem;flex-shrink:0;background:var(--wm-bg-raised)}.wm-dialog-title{font-size:1rem;font-weight:600;color:var(--wm-text-primary);margin:0;line-height:1.3}.wm-dialog-close{display:flex;align-items:center;justify-content:center;width:28px;height:28px;flex-shrink:0;border-radius:var(--wm-radius-sm);border:none;background:transparent;color:var(--wm-text-muted);cursor:pointer;transition:background var(--wm-transition-fast),color var(--wm-transition-fast)}.wm-dialog-close:hover{background:var(--wm-bg-hover);color:var(--wm-text-primary)}.wm-dialog-close:focus-visible{outline:2px solid var(--wm-color-accent);outline-offset:1px}.wm-dialog-body{flex:1;overflow-y:auto;padding:1rem 1.25rem 1.25rem;font-size:.875rem;color:var(--wm-text-secondary);line-height:1.6}@media(prefers-reduced-motion:reduce){.wm-dialog-close{transition:none}}\n"], dependencies: [{ kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }] });
98
114
  }
99
115
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: WmDialog, decorators: [{
100
116
  type: Component,
101
- args: [{ selector: 'wm-dialog', imports: [CdkTrapFocus], template: "@if (isOpen()) {\r\n <!-- Backdrop \u2014 click to close -->\r\n <div class=\"wm-dialog-backdrop\" (click)=\"close()\" aria-hidden=\"true\"></div>\r\n\r\n <!-- Panel -->\r\n <div\r\n class=\"wm-dialog\"\r\n [class]=\"'wm-dialog--' + size()\"\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n [attr.aria-labelledby]=\"title() ? 'wm-dialog-title' : null\"\r\n cdkTrapFocus\r\n [cdkTrapFocusAutoCapture]=\"true\"\r\n >\r\n <div class=\"wm-dialog-header\">\r\n <h2 class=\"wm-dialog-title\" id=\"wm-dialog-title\">{{ title() }}</h2>\r\n <button\r\n class=\"wm-dialog-close\"\r\n type=\"button\"\r\n (click)=\"close()\"\r\n aria-label=\"Close dialog\"\r\n >\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"wm-dialog-body\">\r\n <ng-content select=\"[body]\" />\r\n </div>\r\n </div>\r\n}\r\n", styles: [":host{display:contents}.wm-dialog-backdrop{position:fixed;inset:0;background:rgba(0,0,0,var(--wm-backdrop-opacity));z-index:100}.wm-dialog{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:101;background:var(--wm-bg-float);border:1px solid var(--wm-border);border-radius:var(--wm-radius-lg);box-shadow:var(--wm-shadow-lg);width:var(--wm-dialog-width, 480px);max-width:calc(100vw - 2rem);max-height:calc(100dvh - 4rem);display:flex;flex-direction:column;overflow:hidden;outline:none}.wm-dialog--sm{width:var(--wm-dialog-width, 360px)}.wm-dialog--lg{width:var(--wm-dialog-width, 640px)}.wm-dialog-header{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:1.125rem 1.25rem;flex-shrink:0;background:var(--wm-bg-raised)}.wm-dialog-title{font-size:1rem;font-weight:600;color:var(--wm-text-primary);margin:0;line-height:1.3}.wm-dialog-close{display:flex;align-items:center;justify-content:center;width:28px;height:28px;flex-shrink:0;border-radius:var(--wm-radius-sm);border:none;background:transparent;color:var(--wm-text-muted);cursor:pointer;transition:background var(--wm-transition-fast),color var(--wm-transition-fast)}.wm-dialog-close:hover{background:var(--wm-bg-hover);color:var(--wm-text-primary)}.wm-dialog-close:focus-visible{outline:2px solid var(--wm-color-accent);outline-offset:1px}.wm-dialog-body{flex:1;overflow-y:auto;padding:1rem 1.25rem 1.25rem;font-size:.875rem;color:var(--wm-text-secondary);line-height:1.6}@media(prefers-reduced-motion:reduce){.wm-dialog-close{transition:none}}\n"] }]
117
+ args: [{ selector: 'wm-dialog', imports: [CdkTrapFocus], template: "@if (isOpen()) {\n <!-- Backdrop \u2014 click to close -->\n <div class=\"wm-dialog-backdrop\" (click)=\"close()\" aria-hidden=\"true\"></div>\n\n <!-- Panel -->\n <div\n class=\"wm-dialog\"\n [class]=\"'wm-dialog--' + size()\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-labelledby]=\"title() ? 'wm-dialog-title' : null\"\n cdkTrapFocus\n [cdkTrapFocusAutoCapture]=\"true\"\n >\n <div class=\"wm-dialog-header\">\n <h2 class=\"wm-dialog-title\" id=\"wm-dialog-title\">{{ title() }}</h2>\n <button\n class=\"wm-dialog-close\"\n type=\"button\"\n (click)=\"close()\"\n aria-label=\"Close dialog\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/>\n </svg>\n </button>\n </div>\n\n <div class=\"wm-dialog-body\">\n <ng-content select=\"[body]\" />\n </div>\n </div>\n}\n", styles: [":host{display:contents}.wm-dialog-backdrop{position:fixed;inset:0;background:rgba(0,0,0,var(--wm-backdrop-opacity));z-index:100}.wm-dialog{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:101;background:var(--wm-bg-float);border:1px solid var(--wm-border);border-radius:var(--wm-radius-lg);box-shadow:var(--wm-shadow-lg);width:var(--wm-dialog-width, 480px);max-width:calc(100vw - 2rem);max-height:calc(100dvh - 4rem);display:flex;flex-direction:column;overflow:hidden;outline:none}.wm-dialog--sm{width:var(--wm-dialog-width, 360px)}.wm-dialog--lg{width:var(--wm-dialog-width, 640px)}.wm-dialog-header{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:1.125rem 1.25rem;flex-shrink:0;background:var(--wm-bg-raised)}.wm-dialog-title{font-size:1rem;font-weight:600;color:var(--wm-text-primary);margin:0;line-height:1.3}.wm-dialog-close{display:flex;align-items:center;justify-content:center;width:28px;height:28px;flex-shrink:0;border-radius:var(--wm-radius-sm);border:none;background:transparent;color:var(--wm-text-muted);cursor:pointer;transition:background var(--wm-transition-fast),color var(--wm-transition-fast)}.wm-dialog-close:hover{background:var(--wm-bg-hover);color:var(--wm-text-primary)}.wm-dialog-close:focus-visible{outline:2px solid var(--wm-color-accent);outline-offset:1px}.wm-dialog-body{flex:1;overflow-y:auto;padding:1rem 1.25rem 1.25rem;font-size:.875rem;color:var(--wm-text-secondary);line-height:1.6}@media(prefers-reduced-motion:reduce){.wm-dialog-close{transition:none}}\n"] }]
102
118
  }], propDecorators: { isOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOpen", required: false }] }, { type: i0.Output, args: ["isOpenChange"] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], onEscape: [{
103
119
  type: HostListener,
104
120
  args: ['document:keydown.escape']
@@ -167,11 +183,11 @@ class WmSelect {
167
183
  }
168
184
  }
169
185
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: WmSelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
170
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: WmSelect, isStandalone: true, selector: "wm-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, ngImport: i0, template: "<!-- Trigger button \u2014 anchors the CDK overlay -->\r\n<div\r\n class=\"wm-select-host\"\r\n cdkOverlayOrigin\r\n #origin=\"cdkOverlayOrigin\"\r\n>\r\n <button\r\n type=\"button\"\r\n role=\"combobox\"\r\n class=\"wm-select-trigger\"\r\n [class.is-open]=\"isOpen()\"\r\n [class.is-disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-haspopup=\"listbox\"\r\n [attr.aria-disabled]=\"disabled() ? true : null\"\r\n [disabled]=\"disabled() || null\"\r\n (click)=\"toggleOpen()\"\r\n >\r\n <span class=\"wm-select-value\" [class.is-placeholder]=\"!selectedOption()\">\r\n {{ selectedOption()?.label ?? placeholder() }}\r\n </span>\r\n <!-- Chevron icon \u2014 rotates when open -->\r\n <svg\r\n class=\"wm-select-chevron\"\r\n [class.is-open]=\"isOpen()\"\r\n width=\"16\" height=\"16\" viewBox=\"0 0 24 24\"\r\n fill=\"none\" aria-hidden=\"true\"\r\n >\r\n <path d=\"M6 9l6 6 6-6\"\r\n stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n </button>\r\n</div>\r\n\r\n<!-- Dropdown panel \u2014 rendered in CDK overlay container -->\r\n<ng-template\r\n cdkConnectedOverlay\r\n [cdkConnectedOverlayOrigin]=\"origin\"\r\n [cdkConnectedOverlayOpen]=\"isOpen()\"\r\n [cdkConnectedOverlayPositions]=\"positions\"\r\n [cdkConnectedOverlayWidth]=\"overlayWidth\"\r\n [cdkConnectedOverlayHasBackdrop]=\"true\"\r\n cdkConnectedOverlayBackdropClass=\"wm-select-backdrop\"\r\n (backdropClick)=\"isOpen.set(false)\"\r\n (detach)=\"isOpen.set(false)\"\r\n>\r\n <div\r\n class=\"wm-select-panel\"\r\n role=\"listbox\"\r\n cdkTrapFocus\r\n [cdkTrapFocusAutoCapture]=\"true\"\r\n >\r\n @for (opt of options(); track opt.value) {\r\n <button\r\n type=\"button\"\r\n role=\"option\"\r\n class=\"wm-select-option\"\r\n [class.is-selected]=\"opt.value === value()\"\r\n [class.is-disabled]=\"!!opt.disabled\"\r\n [attr.aria-selected]=\"opt.value === value()\"\r\n [attr.aria-disabled]=\"opt.disabled ? true : null\"\r\n [disabled]=\"opt.disabled || null\"\r\n (click)=\"selectOption(opt)\"\r\n >\r\n <span class=\"wm-select-option-label\">{{ opt.label }}</span>\r\n @if (opt.value === value()) {\r\n <!-- Checkmark for selected option -->\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <polyline points=\"20 6 9 17 4 12\"\r\n stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n }\r\n </button>\r\n }\r\n </div>\r\n</ng-template>\r\n", styles: [":host{display:block}.wm-select-host{display:block}.wm-select-trigger{display:flex;align-items:center;justify-content:space-between;gap:.5rem;width:100%;padding:0 .75rem;height:36px;background:var(--wm-bg-base);border:1px solid var(--wm-border-input);border-radius:var(--wm-radius-md);color:var(--wm-text-primary);font-size:.875rem;font-family:inherit;cursor:pointer;transition:border-color var(--wm-transition-fast),box-shadow var(--wm-transition-fast);outline:none;text-align:left}.wm-select-trigger:hover:not(.is-disabled){border-color:var(--wm-color-accent-readable)}.wm-select-trigger:focus-visible{border-color:var(--wm-color-accent-readable);box-shadow:0 0 0 3px color-mix(in srgb,var(--wm-color-accent) 25%,transparent)}.wm-select-trigger.is-open{border-color:var(--wm-color-accent-readable);box-shadow:0 0 0 3px color-mix(in srgb,var(--wm-color-accent) 20%,transparent)}.wm-select-trigger.is-disabled{opacity:.45;cursor:not-allowed}.wm-select-value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wm-select-value.is-placeholder{color:var(--wm-text-placeholder)}.wm-select-chevron{flex-shrink:0;color:var(--wm-text-muted);transition:transform var(--wm-transition-fast)}.wm-select-chevron.is-open{transform:rotate(180deg)}.wm-select-backdrop{position:fixed;inset:0}.wm-select-panel{width:100%;background:var(--wm-bg-float);border:1px solid var(--wm-border);border-radius:var(--wm-radius-lg);box-shadow:0 4px 6px -1px #00000014,0 10px 20px -4px #0000001f;overflow:hidden;outline:none;padding:.25rem}.wm-select-option{display:flex;align-items:center;justify-content:space-between;gap:.5rem;width:100%;padding:.4375rem .625rem;border:none;border-radius:var(--wm-radius-sm);background:transparent;color:var(--wm-text-primary);font-size:.875rem;font-family:inherit;cursor:pointer;text-align:left;transition:background var(--wm-transition-fast)}.wm-select-option:hover:not(.is-disabled):not(.is-selected){background:var(--wm-bg-active)}.wm-select-option.is-selected{background:color-mix(in srgb,var(--wm-color-accent) 10%,transparent);color:var(--wm-color-accent-readable);font-weight:500}.wm-select-option.is-disabled{opacity:.4;cursor:not-allowed}.wm-select-option-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wm-select-option svg{flex-shrink:0;color:var(--wm-color-accent-readable)}\n"], dependencies: [{ kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }] });
186
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: WmSelect, isStandalone: true, selector: "wm-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, ngImport: i0, template: "<!-- Trigger button \u2014 anchors the CDK overlay -->\n<div\n class=\"wm-select-host\"\n cdkOverlayOrigin\n #origin=\"cdkOverlayOrigin\"\n>\n <button\n type=\"button\"\n role=\"combobox\"\n class=\"wm-select-trigger\"\n [class.is-open]=\"isOpen()\"\n [class.is-disabled]=\"disabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n aria-haspopup=\"listbox\"\n [attr.aria-disabled]=\"disabled() ? true : null\"\n [disabled]=\"disabled() || null\"\n (click)=\"toggleOpen()\"\n >\n <span class=\"wm-select-value\" [class.is-placeholder]=\"!selectedOption()\">\n {{ selectedOption()?.label ?? placeholder() }}\n </span>\n <!-- Chevron icon \u2014 rotates when open -->\n <svg\n class=\"wm-select-chevron\"\n [class.is-open]=\"isOpen()\"\n width=\"16\" height=\"16\" viewBox=\"0 0 24 24\"\n fill=\"none\" aria-hidden=\"true\"\n >\n <path d=\"M6 9l6 6 6-6\"\n stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n</div>\n\n<!-- Dropdown panel \u2014 rendered in CDK overlay container -->\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayWidth]=\"overlayWidth\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n cdkConnectedOverlayBackdropClass=\"wm-select-backdrop\"\n (backdropClick)=\"isOpen.set(false)\"\n (detach)=\"isOpen.set(false)\"\n>\n <div\n class=\"wm-select-panel\"\n role=\"listbox\"\n cdkTrapFocus\n [cdkTrapFocusAutoCapture]=\"true\"\n >\n @for (opt of options(); track opt.value) {\n <button\n type=\"button\"\n role=\"option\"\n class=\"wm-select-option\"\n [class.is-selected]=\"opt.value === value()\"\n [class.is-disabled]=\"!!opt.disabled\"\n [attr.aria-selected]=\"opt.value === value()\"\n [attr.aria-disabled]=\"opt.disabled ? true : null\"\n [disabled]=\"opt.disabled || null\"\n (click)=\"selectOption(opt)\"\n >\n <span class=\"wm-select-option-label\">{{ opt.label }}</span>\n @if (opt.value === value()) {\n <!-- Checkmark for selected option -->\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <polyline points=\"20 6 9 17 4 12\"\n stroke=\"currentColor\" stroke-width=\"2.5\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n }\n </button>\n }\n </div>\n</ng-template>\n", styles: [":host{display:block}.wm-select-host{display:block}.wm-select-trigger{display:flex;align-items:center;justify-content:space-between;gap:.5rem;width:100%;padding:0 .75rem;height:36px;background:var(--wm-bg-base);border:1px solid var(--wm-border-input);border-radius:var(--wm-radius-md);color:var(--wm-text-primary);font-size:.875rem;font-family:inherit;cursor:pointer;transition:border-color var(--wm-transition-fast),box-shadow var(--wm-transition-fast);outline:none;text-align:left}.wm-select-trigger:hover:not(.is-disabled){border-color:var(--wm-color-accent-readable)}.wm-select-trigger:focus-visible{border-color:var(--wm-color-accent-readable);box-shadow:0 0 0 3px color-mix(in srgb,var(--wm-color-accent) 25%,transparent)}.wm-select-trigger.is-open{border-color:var(--wm-color-accent-readable);box-shadow:0 0 0 3px color-mix(in srgb,var(--wm-color-accent) 20%,transparent)}.wm-select-trigger.is-disabled{opacity:.45;cursor:not-allowed}.wm-select-value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wm-select-value.is-placeholder{color:var(--wm-text-placeholder)}.wm-select-chevron{flex-shrink:0;color:var(--wm-text-muted);transition:transform var(--wm-transition-fast)}.wm-select-chevron.is-open{transform:rotate(180deg)}.wm-select-backdrop{position:fixed;inset:0}.wm-select-panel{width:100%;background:var(--wm-bg-float);border:1px solid var(--wm-border);border-radius:var(--wm-radius-lg);box-shadow:0 4px 6px -1px #00000014,0 10px 20px -4px #0000001f;overflow:hidden;outline:none;padding:.25rem}.wm-select-option{display:flex;align-items:center;justify-content:space-between;gap:.5rem;width:100%;padding:.4375rem .625rem;border:none;border-radius:var(--wm-radius-sm);background:transparent;color:var(--wm-text-primary);font-size:.875rem;font-family:inherit;cursor:pointer;text-align:left;transition:background var(--wm-transition-fast)}.wm-select-option:hover:not(.is-disabled):not(.is-selected){background:var(--wm-bg-active)}.wm-select-option.is-selected{background:color-mix(in srgb,var(--wm-color-accent) 10%,transparent);color:var(--wm-color-accent-readable);font-weight:500}.wm-select-option.is-disabled{opacity:.4;cursor:not-allowed}.wm-select-option-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wm-select-option svg{flex-shrink:0;color:var(--wm-color-accent-readable)}\n"], dependencies: [{ kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }] });
171
187
  }
172
188
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: WmSelect, decorators: [{
173
189
  type: Component,
174
- args: [{ selector: 'wm-select', imports: [CdkConnectedOverlay, CdkOverlayOrigin, CdkTrapFocus], template: "<!-- Trigger button \u2014 anchors the CDK overlay -->\r\n<div\r\n class=\"wm-select-host\"\r\n cdkOverlayOrigin\r\n #origin=\"cdkOverlayOrigin\"\r\n>\r\n <button\r\n type=\"button\"\r\n role=\"combobox\"\r\n class=\"wm-select-trigger\"\r\n [class.is-open]=\"isOpen()\"\r\n [class.is-disabled]=\"disabled()\"\r\n [attr.aria-expanded]=\"isOpen()\"\r\n aria-haspopup=\"listbox\"\r\n [attr.aria-disabled]=\"disabled() ? true : null\"\r\n [disabled]=\"disabled() || null\"\r\n (click)=\"toggleOpen()\"\r\n >\r\n <span class=\"wm-select-value\" [class.is-placeholder]=\"!selectedOption()\">\r\n {{ selectedOption()?.label ?? placeholder() }}\r\n </span>\r\n <!-- Chevron icon \u2014 rotates when open -->\r\n <svg\r\n class=\"wm-select-chevron\"\r\n [class.is-open]=\"isOpen()\"\r\n width=\"16\" height=\"16\" viewBox=\"0 0 24 24\"\r\n fill=\"none\" aria-hidden=\"true\"\r\n >\r\n <path d=\"M6 9l6 6 6-6\"\r\n stroke=\"currentColor\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n </button>\r\n</div>\r\n\r\n<!-- Dropdown panel \u2014 rendered in CDK overlay container -->\r\n<ng-template\r\n cdkConnectedOverlay\r\n [cdkConnectedOverlayOrigin]=\"origin\"\r\n [cdkConnectedOverlayOpen]=\"isOpen()\"\r\n [cdkConnectedOverlayPositions]=\"positions\"\r\n [cdkConnectedOverlayWidth]=\"overlayWidth\"\r\n [cdkConnectedOverlayHasBackdrop]=\"true\"\r\n cdkConnectedOverlayBackdropClass=\"wm-select-backdrop\"\r\n (backdropClick)=\"isOpen.set(false)\"\r\n (detach)=\"isOpen.set(false)\"\r\n>\r\n <div\r\n class=\"wm-select-panel\"\r\n role=\"listbox\"\r\n cdkTrapFocus\r\n [cdkTrapFocusAutoCapture]=\"true\"\r\n >\r\n @for (opt of options(); track opt.value) {\r\n <button\r\n type=\"button\"\r\n role=\"option\"\r\n class=\"wm-select-option\"\r\n [class.is-selected]=\"opt.value === value()\"\r\n [class.is-disabled]=\"!!opt.disabled\"\r\n [attr.aria-selected]=\"opt.value === value()\"\r\n [attr.aria-disabled]=\"opt.disabled ? true : null\"\r\n [disabled]=\"opt.disabled || null\"\r\n (click)=\"selectOption(opt)\"\r\n >\r\n <span class=\"wm-select-option-label\">{{ opt.label }}</span>\r\n @if (opt.value === value()) {\r\n <!-- Checkmark for selected option -->\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\r\n <polyline points=\"20 6 9 17 4 12\"\r\n stroke=\"currentColor\" stroke-width=\"2.5\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n }\r\n </button>\r\n }\r\n </div>\r\n</ng-template>\r\n", styles: [":host{display:block}.wm-select-host{display:block}.wm-select-trigger{display:flex;align-items:center;justify-content:space-between;gap:.5rem;width:100%;padding:0 .75rem;height:36px;background:var(--wm-bg-base);border:1px solid var(--wm-border-input);border-radius:var(--wm-radius-md);color:var(--wm-text-primary);font-size:.875rem;font-family:inherit;cursor:pointer;transition:border-color var(--wm-transition-fast),box-shadow var(--wm-transition-fast);outline:none;text-align:left}.wm-select-trigger:hover:not(.is-disabled){border-color:var(--wm-color-accent-readable)}.wm-select-trigger:focus-visible{border-color:var(--wm-color-accent-readable);box-shadow:0 0 0 3px color-mix(in srgb,var(--wm-color-accent) 25%,transparent)}.wm-select-trigger.is-open{border-color:var(--wm-color-accent-readable);box-shadow:0 0 0 3px color-mix(in srgb,var(--wm-color-accent) 20%,transparent)}.wm-select-trigger.is-disabled{opacity:.45;cursor:not-allowed}.wm-select-value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wm-select-value.is-placeholder{color:var(--wm-text-placeholder)}.wm-select-chevron{flex-shrink:0;color:var(--wm-text-muted);transition:transform var(--wm-transition-fast)}.wm-select-chevron.is-open{transform:rotate(180deg)}.wm-select-backdrop{position:fixed;inset:0}.wm-select-panel{width:100%;background:var(--wm-bg-float);border:1px solid var(--wm-border);border-radius:var(--wm-radius-lg);box-shadow:0 4px 6px -1px #00000014,0 10px 20px -4px #0000001f;overflow:hidden;outline:none;padding:.25rem}.wm-select-option{display:flex;align-items:center;justify-content:space-between;gap:.5rem;width:100%;padding:.4375rem .625rem;border:none;border-radius:var(--wm-radius-sm);background:transparent;color:var(--wm-text-primary);font-size:.875rem;font-family:inherit;cursor:pointer;text-align:left;transition:background var(--wm-transition-fast)}.wm-select-option:hover:not(.is-disabled):not(.is-selected){background:var(--wm-bg-active)}.wm-select-option.is-selected{background:color-mix(in srgb,var(--wm-color-accent) 10%,transparent);color:var(--wm-color-accent-readable);font-weight:500}.wm-select-option.is-disabled{opacity:.4;cursor:not-allowed}.wm-select-option-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wm-select-option svg{flex-shrink:0;color:var(--wm-color-accent-readable)}\n"] }]
190
+ args: [{ selector: 'wm-select', imports: [CdkConnectedOverlay, CdkOverlayOrigin, CdkTrapFocus], template: "<!-- Trigger button \u2014 anchors the CDK overlay -->\n<div\n class=\"wm-select-host\"\n cdkOverlayOrigin\n #origin=\"cdkOverlayOrigin\"\n>\n <button\n type=\"button\"\n role=\"combobox\"\n class=\"wm-select-trigger\"\n [class.is-open]=\"isOpen()\"\n [class.is-disabled]=\"disabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n aria-haspopup=\"listbox\"\n [attr.aria-disabled]=\"disabled() ? true : null\"\n [disabled]=\"disabled() || null\"\n (click)=\"toggleOpen()\"\n >\n <span class=\"wm-select-value\" [class.is-placeholder]=\"!selectedOption()\">\n {{ selectedOption()?.label ?? placeholder() }}\n </span>\n <!-- Chevron icon \u2014 rotates when open -->\n <svg\n class=\"wm-select-chevron\"\n [class.is-open]=\"isOpen()\"\n width=\"16\" height=\"16\" viewBox=\"0 0 24 24\"\n fill=\"none\" aria-hidden=\"true\"\n >\n <path d=\"M6 9l6 6 6-6\"\n stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n</div>\n\n<!-- Dropdown panel \u2014 rendered in CDK overlay container -->\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayWidth]=\"overlayWidth\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n cdkConnectedOverlayBackdropClass=\"wm-select-backdrop\"\n (backdropClick)=\"isOpen.set(false)\"\n (detach)=\"isOpen.set(false)\"\n>\n <div\n class=\"wm-select-panel\"\n role=\"listbox\"\n cdkTrapFocus\n [cdkTrapFocusAutoCapture]=\"true\"\n >\n @for (opt of options(); track opt.value) {\n <button\n type=\"button\"\n role=\"option\"\n class=\"wm-select-option\"\n [class.is-selected]=\"opt.value === value()\"\n [class.is-disabled]=\"!!opt.disabled\"\n [attr.aria-selected]=\"opt.value === value()\"\n [attr.aria-disabled]=\"opt.disabled ? true : null\"\n [disabled]=\"opt.disabled || null\"\n (click)=\"selectOption(opt)\"\n >\n <span class=\"wm-select-option-label\">{{ opt.label }}</span>\n @if (opt.value === value()) {\n <!-- Checkmark for selected option -->\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <polyline points=\"20 6 9 17 4 12\"\n stroke=\"currentColor\" stroke-width=\"2.5\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n }\n </button>\n }\n </div>\n</ng-template>\n", styles: [":host{display:block}.wm-select-host{display:block}.wm-select-trigger{display:flex;align-items:center;justify-content:space-between;gap:.5rem;width:100%;padding:0 .75rem;height:36px;background:var(--wm-bg-base);border:1px solid var(--wm-border-input);border-radius:var(--wm-radius-md);color:var(--wm-text-primary);font-size:.875rem;font-family:inherit;cursor:pointer;transition:border-color var(--wm-transition-fast),box-shadow var(--wm-transition-fast);outline:none;text-align:left}.wm-select-trigger:hover:not(.is-disabled){border-color:var(--wm-color-accent-readable)}.wm-select-trigger:focus-visible{border-color:var(--wm-color-accent-readable);box-shadow:0 0 0 3px color-mix(in srgb,var(--wm-color-accent) 25%,transparent)}.wm-select-trigger.is-open{border-color:var(--wm-color-accent-readable);box-shadow:0 0 0 3px color-mix(in srgb,var(--wm-color-accent) 20%,transparent)}.wm-select-trigger.is-disabled{opacity:.45;cursor:not-allowed}.wm-select-value{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wm-select-value.is-placeholder{color:var(--wm-text-placeholder)}.wm-select-chevron{flex-shrink:0;color:var(--wm-text-muted);transition:transform var(--wm-transition-fast)}.wm-select-chevron.is-open{transform:rotate(180deg)}.wm-select-backdrop{position:fixed;inset:0}.wm-select-panel{width:100%;background:var(--wm-bg-float);border:1px solid var(--wm-border);border-radius:var(--wm-radius-lg);box-shadow:0 4px 6px -1px #00000014,0 10px 20px -4px #0000001f;overflow:hidden;outline:none;padding:.25rem}.wm-select-option{display:flex;align-items:center;justify-content:space-between;gap:.5rem;width:100%;padding:.4375rem .625rem;border:none;border-radius:var(--wm-radius-sm);background:transparent;color:var(--wm-text-primary);font-size:.875rem;font-family:inherit;cursor:pointer;text-align:left;transition:background var(--wm-transition-fast)}.wm-select-option:hover:not(.is-disabled):not(.is-selected){background:var(--wm-bg-active)}.wm-select-option.is-selected{background:color-mix(in srgb,var(--wm-color-accent) 10%,transparent);color:var(--wm-color-accent-readable);font-weight:500}.wm-select-option.is-disabled{opacity:.4;cursor:not-allowed}.wm-select-option-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wm-select-option svg{flex-shrink:0;color:var(--wm-color-accent-readable)}\n"] }]
175
191
  }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
176
192
 
177
193
  /**
@@ -343,9 +359,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
343
359
 
344
360
  class WmTab {
345
361
  value = input.required(...(ngDevMode ? [{ debugName: "value" }] : []));
362
+ /**
363
+ * Keeps a prerequisite-gated tab discoverable while preventing activation.
364
+ * Unlike a native disabled button, unavailable tabs remain in the roving
365
+ * focus order so keyboard and assistive-technology users can learn why the
366
+ * destination cannot be opened yet.
367
+ */
368
+ unavailable = input(false, ...(ngDevMode ? [{ debugName: "unavailable" }] : []));
369
+ /** Exact prerequisite guidance exposed to both pointer and AT users. */
370
+ unavailableReason = input('', ...(ngDevMode ? [{ debugName: "unavailableReason" }] : []));
371
+ /** Render a non-interactive group divider immediately before this tab. */
372
+ separatorBefore = input(false, ...(ngDevMode ? [{ debugName: "separatorBefore" }] : []));
346
373
  tmpl = viewChild.required('tmpl');
347
374
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: WmTab, deps: [], target: i0.ɵɵFactoryTarget.Component });
348
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.1", type: WmTab, isStandalone: true, selector: "wm-tab", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null } }, host: { styleAttribute: "display: none" }, viewQueries: [{ propertyName: "tmpl", first: true, predicate: ["tmpl"], descendants: true, isSignal: true }], ngImport: i0, template: `<ng-template #tmpl><ng-content /></ng-template>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
375
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.1", type: WmTab, isStandalone: true, selector: "wm-tab", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, unavailable: { classPropertyName: "unavailable", publicName: "unavailable", isSignal: true, isRequired: false, transformFunction: null }, unavailableReason: { classPropertyName: "unavailableReason", publicName: "unavailableReason", isSignal: true, isRequired: false, transformFunction: null }, separatorBefore: { classPropertyName: "separatorBefore", publicName: "separatorBefore", isSignal: true, isRequired: false, transformFunction: null } }, host: { styleAttribute: "display: none" }, viewQueries: [{ propertyName: "tmpl", first: true, predicate: ["tmpl"], descendants: true, isSignal: true }], ngImport: i0, template: `<ng-template #tmpl><ng-content /></ng-template>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
349
376
  }
350
377
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: WmTab, decorators: [{
351
378
  type: Component,
@@ -355,7 +382,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
355
382
  host: { style: 'display: none' },
356
383
  changeDetection: ChangeDetectionStrategy.OnPush,
357
384
  }]
358
- }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], tmpl: [{ type: i0.ViewChild, args: ['tmpl', { isSignal: true }] }] } });
385
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], unavailable: [{ type: i0.Input, args: [{ isSignal: true, alias: "unavailable", required: false }] }], unavailableReason: [{ type: i0.Input, args: [{ isSignal: true, alias: "unavailableReason", required: false }] }], separatorBefore: [{ type: i0.Input, args: [{ isSignal: true, alias: "separatorBefore", required: false }] }], tmpl: [{ type: i0.ViewChild, args: ['tmpl', { isSignal: true }] }] } });
359
386
 
360
387
  class WmTabs {
361
388
  activeValue = input.required(...(ngDevMode ? [{ debugName: "activeValue" }] : []));
@@ -363,9 +390,10 @@ class WmTabs {
363
390
  select = output();
364
391
  tabs = contentChildren(WmTab, ...(ngDevMode ? [{ debugName: "tabs" }] : []));
365
392
  focusedIndex = signal(null, ...(ngDevMode ? [{ debugName: "focusedIndex" }] : []));
366
- selectTab(value, index) {
393
+ selectTab(tab, index) {
367
394
  this.focusedIndex.set(index);
368
- this.select.emit(value);
395
+ if (!tab.unavailable())
396
+ this.select.emit(tab.value());
369
397
  }
370
398
  onBlur() {
371
399
  setTimeout(() => {
@@ -376,7 +404,10 @@ class WmTabs {
376
404
  }
377
405
  onKeyDown(event, container) {
378
406
  const tabs = this.tabs();
379
- const currentIndex = this.focusedIndex() ?? tabs.findIndex(t => t.value() === this.activeValue());
407
+ if (tabs.length === 0)
408
+ return;
409
+ const activeIndex = tabs.findIndex(t => t.value() === this.activeValue());
410
+ const currentIndex = this.focusedIndex() ?? (activeIndex >= 0 ? activeIndex : 0);
380
411
  let nextIndex = null;
381
412
  switch (event.key) {
382
413
  case 'ArrowRight':
@@ -402,11 +433,11 @@ class WmTabs {
402
433
  }
403
434
  }
404
435
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: WmTabs, deps: [], target: i0.ɵɵFactoryTarget.Component });
405
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: WmTabs, isStandalone: true, selector: "wm-tabs", inputs: { activeValue: { classPropertyName: "activeValue", publicName: "activeValue", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select" }, queries: [{ propertyName: "tabs", predicate: WmTab, isSignal: true }], ngImport: i0, template: "<div\r\n class=\"wm-tabs\"\r\n [class.wm-tabs--line]=\"variant() === 'line'\"\r\n [class.wm-tabs--pill]=\"variant() === 'pill'\"\r\n role=\"tablist\"\r\n #container\r\n (keydown)=\"onKeyDown($event, container)\"\r\n>\r\n @for (tab of tabs(); track tab.value(); let i = $index) {\r\n <button\r\n type=\"button\"\r\n role=\"tab\"\r\n class=\"wm-tab\"\r\n [id]=\"'wm-tab-' + tab.value()\"\r\n [attr.aria-selected]=\"activeValue() === tab.value()\"\r\n [attr.aria-controls]=\"'wm-panel-' + tab.value()\"\r\n [tabIndex]=\"(focusedIndex() === null ? activeValue() === tab.value() : focusedIndex() === i) ? 0 : -1\"\r\n [class.is-active]=\"activeValue() === tab.value()\"\r\n (click)=\"selectTab(tab.value(), i)\"\r\n (focus)=\"focusedIndex.set(i)\"\r\n (blur)=\"onBlur()\"\r\n >\r\n <ng-container [ngTemplateOutlet]=\"tab.tmpl()\" />\r\n </button>\r\n }\r\n</div>\r\n", styles: [".wm-tab{display:inline-flex;align-items:center;gap:6px;font-size:.8125rem;font-weight:600;background:transparent;border:none;cursor:pointer;white-space:nowrap;transition:color var(--wm-duration-fast) var(--wm-ease-standard),background var(--wm-duration-fast) var(--wm-ease-standard),border-color var(--wm-duration-fast) var(--wm-ease-standard)}.wm-tab:focus-visible{outline:2px solid var(--wm-color-accent);outline-offset:-2px;border-radius:var(--wm-radius-sm)}.wm-tabs--line{display:flex;gap:1.5rem;border-bottom:1px solid var(--wm-border-subtle)}.wm-tabs--line .wm-tab{padding:.625rem .25rem;color:var(--wm-text-muted);border-radius:0;border-bottom:2px solid transparent;margin-bottom:-1px}.wm-tabs--line .wm-tab:hover{color:var(--wm-text-secondary)}.wm-tabs--line .wm-tab.is-active{color:var(--wm-color-accent-readable);border-bottom-color:var(--wm-color-accent-readable)}.wm-tabs--pill{display:inline-flex;background:var(--wm-bg-sunken);padding:.25rem;border-radius:var(--wm-radius-md);gap:.125rem;border:1px solid var(--wm-border-subtle)}.wm-tabs--pill .wm-tab{padding:.375rem .75rem;border-radius:var(--wm-radius-sm);color:var(--wm-text-muted)}.wm-tabs--pill .wm-tab:hover{background:color-mix(in srgb,var(--wm-color-accent) 5%,transparent);color:var(--wm-text-secondary)}.wm-tabs--pill .wm-tab.is-active{background:var(--wm-bg-float);color:var(--wm-text-primary);box-shadow:var(--wm-shadow-sm)}@media(prefers-reduced-motion:reduce){.wm-tab{transition:none}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
436
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: WmTabs, isStandalone: true, selector: "wm-tabs", inputs: { activeValue: { classPropertyName: "activeValue", publicName: "activeValue", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select" }, queries: [{ propertyName: "tabs", predicate: WmTab, isSignal: true }], ngImport: i0, template: "<div\n class=\"wm-tabs\"\n [class.wm-tabs--line]=\"variant() === 'line'\"\n [class.wm-tabs--pill]=\"variant() === 'pill'\"\n role=\"tablist\"\n #container\n (keydown)=\"onKeyDown($event, container)\"\n>\n @for (tab of tabs(); track tab.value(); let i = $index) {\n @if (tab.separatorBefore()) {\n <span class=\"wm-tab-separator\" role=\"presentation\" aria-hidden=\"true\"></span>\n }\n <button\n type=\"button\"\n role=\"tab\"\n class=\"wm-tab\"\n [id]=\"'wm-tab-' + tab.value()\"\n [attr.aria-selected]=\"activeValue() === tab.value()\"\n [attr.aria-controls]=\"'wm-panel-' + tab.value()\"\n [attr.aria-disabled]=\"tab.unavailable() ? true : null\"\n [attr.aria-description]=\"tab.unavailable() ? tab.unavailableReason() : null\"\n [attr.title]=\"tab.unavailable() ? tab.unavailableReason() : null\"\n [tabIndex]=\"(focusedIndex() === null ? activeValue() === tab.value() : focusedIndex() === i) ? 0 : -1\"\n [class.is-active]=\"activeValue() === tab.value()\"\n [class.is-unavailable]=\"tab.unavailable()\"\n (click)=\"selectTab(tab, i)\"\n (focus)=\"focusedIndex.set(i)\"\n (blur)=\"onBlur()\"\n >\n <ng-container [ngTemplateOutlet]=\"tab.tmpl()\" />\n </button>\n }\n</div>\n", styles: [".wm-tab{display:inline-flex;align-items:center;gap:6px;font-size:.8125rem;font-weight:600;background:transparent;border:none;cursor:pointer;white-space:nowrap;transition:color var(--wm-duration-fast) var(--wm-ease-standard),background var(--wm-duration-fast) var(--wm-ease-standard),border-color var(--wm-duration-fast) var(--wm-ease-standard)}.wm-tab:focus-visible{outline:2px solid var(--wm-color-accent);outline-offset:-2px;border-radius:var(--wm-radius-sm)}.wm-tab.is-unavailable{cursor:not-allowed;color:var(--wm-text-muted);box-shadow:none;filter:saturate(.35)}.wm-tab.is-unavailable:hover{background:transparent;color:var(--wm-text-muted)}.wm-tab-separator{flex:0 0 1px;align-self:center;width:1px;height:1.25rem;margin:0 .375rem;background:var(--wm-border-strong, var(--wm-border-subtle))}.wm-tabs--line{display:flex;gap:1.5rem;border-bottom:1px solid var(--wm-border-subtle)}.wm-tabs--line .wm-tab{padding:.625rem .25rem;color:var(--wm-text-muted);border-radius:0;border-bottom:2px solid transparent;margin-bottom:-1px}.wm-tabs--line .wm-tab:hover{color:var(--wm-text-secondary)}.wm-tabs--line .wm-tab.is-active{color:var(--wm-color-accent-readable);border-bottom-color:var(--wm-color-accent-readable)}.wm-tabs--pill{display:inline-flex;background:var(--wm-bg-sunken);padding:.25rem;border-radius:var(--wm-radius-md);gap:.125rem;border:1px solid var(--wm-border-subtle)}.wm-tabs--pill .wm-tab{padding:.375rem .75rem;border-radius:var(--wm-radius-sm);color:var(--wm-text-muted)}.wm-tabs--pill .wm-tab:hover{background:color-mix(in srgb,var(--wm-color-accent) 5%,transparent);color:var(--wm-text-secondary)}.wm-tabs--pill .wm-tab.is-active{background:var(--wm-bg-float);color:var(--wm-text-primary);box-shadow:var(--wm-shadow-sm)}.wm-tabs--line .wm-tab.is-unavailable,.wm-tabs--line .wm-tab.is-unavailable:hover,.wm-tabs--pill .wm-tab.is-unavailable,.wm-tabs--pill .wm-tab.is-unavailable:hover{background:transparent;color:var(--wm-text-muted);box-shadow:none}@media(prefers-reduced-motion:reduce){.wm-tab{transition:none}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
406
437
  }
407
438
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: WmTabs, decorators: [{
408
439
  type: Component,
409
- args: [{ selector: 'wm-tabs', imports: [NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\r\n class=\"wm-tabs\"\r\n [class.wm-tabs--line]=\"variant() === 'line'\"\r\n [class.wm-tabs--pill]=\"variant() === 'pill'\"\r\n role=\"tablist\"\r\n #container\r\n (keydown)=\"onKeyDown($event, container)\"\r\n>\r\n @for (tab of tabs(); track tab.value(); let i = $index) {\r\n <button\r\n type=\"button\"\r\n role=\"tab\"\r\n class=\"wm-tab\"\r\n [id]=\"'wm-tab-' + tab.value()\"\r\n [attr.aria-selected]=\"activeValue() === tab.value()\"\r\n [attr.aria-controls]=\"'wm-panel-' + tab.value()\"\r\n [tabIndex]=\"(focusedIndex() === null ? activeValue() === tab.value() : focusedIndex() === i) ? 0 : -1\"\r\n [class.is-active]=\"activeValue() === tab.value()\"\r\n (click)=\"selectTab(tab.value(), i)\"\r\n (focus)=\"focusedIndex.set(i)\"\r\n (blur)=\"onBlur()\"\r\n >\r\n <ng-container [ngTemplateOutlet]=\"tab.tmpl()\" />\r\n </button>\r\n }\r\n</div>\r\n", styles: [".wm-tab{display:inline-flex;align-items:center;gap:6px;font-size:.8125rem;font-weight:600;background:transparent;border:none;cursor:pointer;white-space:nowrap;transition:color var(--wm-duration-fast) var(--wm-ease-standard),background var(--wm-duration-fast) var(--wm-ease-standard),border-color var(--wm-duration-fast) var(--wm-ease-standard)}.wm-tab:focus-visible{outline:2px solid var(--wm-color-accent);outline-offset:-2px;border-radius:var(--wm-radius-sm)}.wm-tabs--line{display:flex;gap:1.5rem;border-bottom:1px solid var(--wm-border-subtle)}.wm-tabs--line .wm-tab{padding:.625rem .25rem;color:var(--wm-text-muted);border-radius:0;border-bottom:2px solid transparent;margin-bottom:-1px}.wm-tabs--line .wm-tab:hover{color:var(--wm-text-secondary)}.wm-tabs--line .wm-tab.is-active{color:var(--wm-color-accent-readable);border-bottom-color:var(--wm-color-accent-readable)}.wm-tabs--pill{display:inline-flex;background:var(--wm-bg-sunken);padding:.25rem;border-radius:var(--wm-radius-md);gap:.125rem;border:1px solid var(--wm-border-subtle)}.wm-tabs--pill .wm-tab{padding:.375rem .75rem;border-radius:var(--wm-radius-sm);color:var(--wm-text-muted)}.wm-tabs--pill .wm-tab:hover{background:color-mix(in srgb,var(--wm-color-accent) 5%,transparent);color:var(--wm-text-secondary)}.wm-tabs--pill .wm-tab.is-active{background:var(--wm-bg-float);color:var(--wm-text-primary);box-shadow:var(--wm-shadow-sm)}@media(prefers-reduced-motion:reduce){.wm-tab{transition:none}}\n"] }]
440
+ args: [{ selector: 'wm-tabs', imports: [NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"wm-tabs\"\n [class.wm-tabs--line]=\"variant() === 'line'\"\n [class.wm-tabs--pill]=\"variant() === 'pill'\"\n role=\"tablist\"\n #container\n (keydown)=\"onKeyDown($event, container)\"\n>\n @for (tab of tabs(); track tab.value(); let i = $index) {\n @if (tab.separatorBefore()) {\n <span class=\"wm-tab-separator\" role=\"presentation\" aria-hidden=\"true\"></span>\n }\n <button\n type=\"button\"\n role=\"tab\"\n class=\"wm-tab\"\n [id]=\"'wm-tab-' + tab.value()\"\n [attr.aria-selected]=\"activeValue() === tab.value()\"\n [attr.aria-controls]=\"'wm-panel-' + tab.value()\"\n [attr.aria-disabled]=\"tab.unavailable() ? true : null\"\n [attr.aria-description]=\"tab.unavailable() ? tab.unavailableReason() : null\"\n [attr.title]=\"tab.unavailable() ? tab.unavailableReason() : null\"\n [tabIndex]=\"(focusedIndex() === null ? activeValue() === tab.value() : focusedIndex() === i) ? 0 : -1\"\n [class.is-active]=\"activeValue() === tab.value()\"\n [class.is-unavailable]=\"tab.unavailable()\"\n (click)=\"selectTab(tab, i)\"\n (focus)=\"focusedIndex.set(i)\"\n (blur)=\"onBlur()\"\n >\n <ng-container [ngTemplateOutlet]=\"tab.tmpl()\" />\n </button>\n }\n</div>\n", styles: [".wm-tab{display:inline-flex;align-items:center;gap:6px;font-size:.8125rem;font-weight:600;background:transparent;border:none;cursor:pointer;white-space:nowrap;transition:color var(--wm-duration-fast) var(--wm-ease-standard),background var(--wm-duration-fast) var(--wm-ease-standard),border-color var(--wm-duration-fast) var(--wm-ease-standard)}.wm-tab:focus-visible{outline:2px solid var(--wm-color-accent);outline-offset:-2px;border-radius:var(--wm-radius-sm)}.wm-tab.is-unavailable{cursor:not-allowed;color:var(--wm-text-muted);box-shadow:none;filter:saturate(.35)}.wm-tab.is-unavailable:hover{background:transparent;color:var(--wm-text-muted)}.wm-tab-separator{flex:0 0 1px;align-self:center;width:1px;height:1.25rem;margin:0 .375rem;background:var(--wm-border-strong, var(--wm-border-subtle))}.wm-tabs--line{display:flex;gap:1.5rem;border-bottom:1px solid var(--wm-border-subtle)}.wm-tabs--line .wm-tab{padding:.625rem .25rem;color:var(--wm-text-muted);border-radius:0;border-bottom:2px solid transparent;margin-bottom:-1px}.wm-tabs--line .wm-tab:hover{color:var(--wm-text-secondary)}.wm-tabs--line .wm-tab.is-active{color:var(--wm-color-accent-readable);border-bottom-color:var(--wm-color-accent-readable)}.wm-tabs--pill{display:inline-flex;background:var(--wm-bg-sunken);padding:.25rem;border-radius:var(--wm-radius-md);gap:.125rem;border:1px solid var(--wm-border-subtle)}.wm-tabs--pill .wm-tab{padding:.375rem .75rem;border-radius:var(--wm-radius-sm);color:var(--wm-text-muted)}.wm-tabs--pill .wm-tab:hover{background:color-mix(in srgb,var(--wm-color-accent) 5%,transparent);color:var(--wm-text-secondary)}.wm-tabs--pill .wm-tab.is-active{background:var(--wm-bg-float);color:var(--wm-text-primary);box-shadow:var(--wm-shadow-sm)}.wm-tabs--line .wm-tab.is-unavailable,.wm-tabs--line .wm-tab.is-unavailable:hover,.wm-tabs--pill .wm-tab.is-unavailable,.wm-tabs--pill .wm-tab.is-unavailable:hover{background:transparent;color:var(--wm-text-muted);box-shadow:none}@media(prefers-reduced-motion:reduce){.wm-tab{transition:none}}\n"] }]
410
441
  }], propDecorators: { activeValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeValue", required: true }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], select: [{ type: i0.Output, args: ["select"] }], tabs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => WmTab), { isSignal: true }] }] } });
411
442
 
412
443
  class WmButton {
@@ -425,11 +456,11 @@ class WmButton {
425
456
  return this.iconOnly() ? `${base} btn-icon-only` : base;
426
457
  }, ...(ngDevMode ? [{ debugName: "btnClass" }] : []));
427
458
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: WmButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
428
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.1", type: WmButton, isStandalone: true, selector: "wm-button", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, iconOnly: { classPropertyName: "iconOnly", publicName: "iconOnly", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, btnTitle: { classPropertyName: "btnTitle", publicName: "btnTitle", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<button\r\n [class]=\"btnClass()\"\r\n [disabled]=\"disabled()\"\r\n [type]=\"type()\"\r\n [attr.aria-label]=\"ariaLabel() || null\"\r\n [attr.title]=\"btnTitle() || null\"\r\n>\r\n <ng-content />\r\n</button>\r\n", styles: [":host{display:inline-flex}\n"] });
459
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.1", type: WmButton, isStandalone: true, selector: "wm-button", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, iconOnly: { classPropertyName: "iconOnly", publicName: "iconOnly", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, btnTitle: { classPropertyName: "btnTitle", publicName: "btnTitle", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<button\n [class]=\"btnClass()\"\n [disabled]=\"disabled()\"\n [type]=\"type()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.title]=\"btnTitle() || null\"\n>\n <ng-content />\n</button>\n", styles: [":host{display:inline-flex}\n"] });
429
460
  }
430
461
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: WmButton, decorators: [{
431
462
  type: Component,
432
- args: [{ selector: 'wm-button', template: "<button\r\n [class]=\"btnClass()\"\r\n [disabled]=\"disabled()\"\r\n [type]=\"type()\"\r\n [attr.aria-label]=\"ariaLabel() || null\"\r\n [attr.title]=\"btnTitle() || null\"\r\n>\r\n <ng-content />\r\n</button>\r\n", styles: [":host{display:inline-flex}\n"] }]
463
+ args: [{ selector: 'wm-button', template: "<button\n [class]=\"btnClass()\"\n [disabled]=\"disabled()\"\n [type]=\"type()\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.title]=\"btnTitle() || null\"\n>\n <ng-content />\n</button>\n", styles: [":host{display:inline-flex}\n"] }]
433
464
  }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], iconOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnly", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], btnTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "btnTitle", required: false }] }] } });
434
465
 
435
466
  /**
@@ -476,11 +507,11 @@ class Checkbox {
476
507
  }
477
508
  }
478
509
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: Checkbox, deps: [], target: i0.ɵɵFactoryTarget.Component });
479
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: Checkbox, isStandalone: true, selector: "wm-checkbox", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange" }, ngImport: i0, template: "<label class=\"wm-checkbox-wrap\" [class.is-disabled]=\"disabled()\">\r\n <button\r\n type=\"button\"\r\n role=\"checkbox\"\r\n class=\"wm-checkbox-box\"\r\n [class.is-checked]=\"checked()\"\r\n [class.is-indeterminate]=\"indeterminate() && !checked()\"\r\n [attr.aria-checked]=\"ariaChecked()\"\r\n [attr.aria-disabled]=\"disabled() ? true : null\"\r\n [disabled]=\"disabled() || null\"\r\n (click)=\"toggle()\"\r\n (keydown.space)=\"$event.preventDefault(); toggle()\"\r\n >\r\n @if (indeterminate() && !checked()) {\r\n <!-- Dash for indeterminate (\"some selected\") state -->\r\n <svg class=\"wm-checkbox-icon\" viewBox=\"0 0 12 12\" aria-hidden=\"true\">\r\n <line x1=\"2\" y1=\"6\" x2=\"10\" y2=\"6\"\r\n stroke=\"currentColor\" stroke-width=\"2.25\" stroke-linecap=\"round\"/>\r\n </svg>\r\n } @else if (checked()) {\r\n <!-- Animated checkmark for selected state -->\r\n <svg class=\"wm-checkbox-icon\" viewBox=\"0 0 12 12\" aria-hidden=\"true\">\r\n <polyline class=\"check-mark\" points=\"2,6.5 4.5,9 10,3\"\r\n fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n }\r\n </button>\r\n\r\n @if (label()) {\r\n <span class=\"wm-checkbox-label\">{{ label() }}</span>\r\n }\r\n</label>\r\n", styles: [":host{display:inline-flex}.wm-checkbox-wrap{display:inline-flex;align-items:center;gap:.5rem;cursor:pointer;-webkit-user-select:none;user-select:none}.wm-checkbox-wrap.is-disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.wm-checkbox-box{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;flex-shrink:0;border:2px solid var(--wm-border-input);border-radius:4px;background:var(--wm-bg-base);color:#fff;cursor:pointer;padding:0;outline:none;transition:background var(--wm-transition-fast),border-color var(--wm-transition-fast),box-shadow var(--wm-transition-fast)}.wm-checkbox-box:focus-visible{box-shadow:0 0 0 2px var(--wm-bg-base),0 0 0 4px var(--wm-color-accent)}.wm-checkbox-box.is-checked,.wm-checkbox-box.is-indeterminate{background:var(--wm-color-accent);border-color:var(--wm-color-accent-readable)}.wm-checkbox-icon{width:12px;height:12px;display:block;flex-shrink:0}@keyframes check-draw{0%{stroke-dashoffset:16}to{stroke-dashoffset:0}}.check-mark{stroke-dasharray:16;stroke-dashoffset:0;animation:check-draw .18s ease-out forwards}.wm-checkbox-label{font-size:.875rem;color:var(--wm-text-primary);line-height:1.4}@media(prefers-reduced-motion:reduce){.wm-checkbox-box{transition:none}.check-mark{animation:none}}\n"] });
510
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: Checkbox, isStandalone: true, selector: "wm-checkbox", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange" }, ngImport: i0, template: "<label class=\"wm-checkbox-wrap\" [class.is-disabled]=\"disabled()\">\n <button\n type=\"button\"\n role=\"checkbox\"\n class=\"wm-checkbox-box\"\n [class.is-checked]=\"checked()\"\n [class.is-indeterminate]=\"indeterminate() && !checked()\"\n [attr.aria-checked]=\"ariaChecked()\"\n [attr.aria-disabled]=\"disabled() ? true : null\"\n [disabled]=\"disabled() || null\"\n (click)=\"toggle()\"\n (keydown.space)=\"$event.preventDefault(); toggle()\"\n >\n @if (indeterminate() && !checked()) {\n <!-- Dash for indeterminate (\"some selected\") state -->\n <svg class=\"wm-checkbox-icon\" viewBox=\"0 0 12 12\" aria-hidden=\"true\">\n <line x1=\"2\" y1=\"6\" x2=\"10\" y2=\"6\"\n stroke=\"currentColor\" stroke-width=\"2.25\" stroke-linecap=\"round\"/>\n </svg>\n } @else if (checked()) {\n <!-- Animated checkmark for selected state -->\n <svg class=\"wm-checkbox-icon\" viewBox=\"0 0 12 12\" aria-hidden=\"true\">\n <polyline class=\"check-mark\" points=\"2,6.5 4.5,9 10,3\"\n fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n }\n </button>\n\n @if (label()) {\n <span class=\"wm-checkbox-label\">{{ label() }}</span>\n }\n</label>\n", styles: [":host{display:inline-flex}.wm-checkbox-wrap{display:inline-flex;align-items:center;gap:.5rem;cursor:pointer;-webkit-user-select:none;user-select:none}.wm-checkbox-wrap.is-disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.wm-checkbox-box{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;flex-shrink:0;border:2px solid var(--wm-border-input);border-radius:4px;background:var(--wm-bg-base);color:#fff;cursor:pointer;padding:0;outline:none;transition:background var(--wm-transition-fast),border-color var(--wm-transition-fast),box-shadow var(--wm-transition-fast)}.wm-checkbox-box:focus-visible{box-shadow:0 0 0 2px var(--wm-bg-base),0 0 0 4px var(--wm-color-accent)}.wm-checkbox-box.is-checked,.wm-checkbox-box.is-indeterminate{background:var(--wm-color-accent);border-color:var(--wm-color-accent-readable)}.wm-checkbox-icon{width:12px;height:12px;display:block;flex-shrink:0}@keyframes check-draw{0%{stroke-dashoffset:16}to{stroke-dashoffset:0}}.check-mark{stroke-dasharray:16;stroke-dashoffset:0;animation:check-draw .18s ease-out forwards}.wm-checkbox-label{font-size:.875rem;color:var(--wm-text-primary);line-height:1.4}@media(prefers-reduced-motion:reduce){.wm-checkbox-box{transition:none}.check-mark{animation:none}}\n"] });
480
511
  }
481
512
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: Checkbox, decorators: [{
482
513
  type: Component,
483
- args: [{ selector: 'wm-checkbox', template: "<label class=\"wm-checkbox-wrap\" [class.is-disabled]=\"disabled()\">\r\n <button\r\n type=\"button\"\r\n role=\"checkbox\"\r\n class=\"wm-checkbox-box\"\r\n [class.is-checked]=\"checked()\"\r\n [class.is-indeterminate]=\"indeterminate() && !checked()\"\r\n [attr.aria-checked]=\"ariaChecked()\"\r\n [attr.aria-disabled]=\"disabled() ? true : null\"\r\n [disabled]=\"disabled() || null\"\r\n (click)=\"toggle()\"\r\n (keydown.space)=\"$event.preventDefault(); toggle()\"\r\n >\r\n @if (indeterminate() && !checked()) {\r\n <!-- Dash for indeterminate (\"some selected\") state -->\r\n <svg class=\"wm-checkbox-icon\" viewBox=\"0 0 12 12\" aria-hidden=\"true\">\r\n <line x1=\"2\" y1=\"6\" x2=\"10\" y2=\"6\"\r\n stroke=\"currentColor\" stroke-width=\"2.25\" stroke-linecap=\"round\"/>\r\n </svg>\r\n } @else if (checked()) {\r\n <!-- Animated checkmark for selected state -->\r\n <svg class=\"wm-checkbox-icon\" viewBox=\"0 0 12 12\" aria-hidden=\"true\">\r\n <polyline class=\"check-mark\" points=\"2,6.5 4.5,9 10,3\"\r\n fill=\"none\" stroke=\"currentColor\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n }\r\n </button>\r\n\r\n @if (label()) {\r\n <span class=\"wm-checkbox-label\">{{ label() }}</span>\r\n }\r\n</label>\r\n", styles: [":host{display:inline-flex}.wm-checkbox-wrap{display:inline-flex;align-items:center;gap:.5rem;cursor:pointer;-webkit-user-select:none;user-select:none}.wm-checkbox-wrap.is-disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.wm-checkbox-box{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;flex-shrink:0;border:2px solid var(--wm-border-input);border-radius:4px;background:var(--wm-bg-base);color:#fff;cursor:pointer;padding:0;outline:none;transition:background var(--wm-transition-fast),border-color var(--wm-transition-fast),box-shadow var(--wm-transition-fast)}.wm-checkbox-box:focus-visible{box-shadow:0 0 0 2px var(--wm-bg-base),0 0 0 4px var(--wm-color-accent)}.wm-checkbox-box.is-checked,.wm-checkbox-box.is-indeterminate{background:var(--wm-color-accent);border-color:var(--wm-color-accent-readable)}.wm-checkbox-icon{width:12px;height:12px;display:block;flex-shrink:0}@keyframes check-draw{0%{stroke-dashoffset:16}to{stroke-dashoffset:0}}.check-mark{stroke-dasharray:16;stroke-dashoffset:0;animation:check-draw .18s ease-out forwards}.wm-checkbox-label{font-size:.875rem;color:var(--wm-text-primary);line-height:1.4}@media(prefers-reduced-motion:reduce){.wm-checkbox-box{transition:none}.check-mark{animation:none}}\n"] }]
514
+ args: [{ selector: 'wm-checkbox', template: "<label class=\"wm-checkbox-wrap\" [class.is-disabled]=\"disabled()\">\n <button\n type=\"button\"\n role=\"checkbox\"\n class=\"wm-checkbox-box\"\n [class.is-checked]=\"checked()\"\n [class.is-indeterminate]=\"indeterminate() && !checked()\"\n [attr.aria-checked]=\"ariaChecked()\"\n [attr.aria-disabled]=\"disabled() ? true : null\"\n [disabled]=\"disabled() || null\"\n (click)=\"toggle()\"\n (keydown.space)=\"$event.preventDefault(); toggle()\"\n >\n @if (indeterminate() && !checked()) {\n <!-- Dash for indeterminate (\"some selected\") state -->\n <svg class=\"wm-checkbox-icon\" viewBox=\"0 0 12 12\" aria-hidden=\"true\">\n <line x1=\"2\" y1=\"6\" x2=\"10\" y2=\"6\"\n stroke=\"currentColor\" stroke-width=\"2.25\" stroke-linecap=\"round\"/>\n </svg>\n } @else if (checked()) {\n <!-- Animated checkmark for selected state -->\n <svg class=\"wm-checkbox-icon\" viewBox=\"0 0 12 12\" aria-hidden=\"true\">\n <polyline class=\"check-mark\" points=\"2,6.5 4.5,9 10,3\"\n fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n }\n </button>\n\n @if (label()) {\n <span class=\"wm-checkbox-label\">{{ label() }}</span>\n }\n</label>\n", styles: [":host{display:inline-flex}.wm-checkbox-wrap{display:inline-flex;align-items:center;gap:.5rem;cursor:pointer;-webkit-user-select:none;user-select:none}.wm-checkbox-wrap.is-disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.wm-checkbox-box{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;flex-shrink:0;border:2px solid var(--wm-border-input);border-radius:4px;background:var(--wm-bg-base);color:#fff;cursor:pointer;padding:0;outline:none;transition:background var(--wm-transition-fast),border-color var(--wm-transition-fast),box-shadow var(--wm-transition-fast)}.wm-checkbox-box:focus-visible{box-shadow:0 0 0 2px var(--wm-bg-base),0 0 0 4px var(--wm-color-accent)}.wm-checkbox-box.is-checked,.wm-checkbox-box.is-indeterminate{background:var(--wm-color-accent);border-color:var(--wm-color-accent-readable)}.wm-checkbox-icon{width:12px;height:12px;display:block;flex-shrink:0}@keyframes check-draw{0%{stroke-dashoffset:16}to{stroke-dashoffset:0}}.check-mark{stroke-dasharray:16;stroke-dashoffset:0;animation:check-draw .18s ease-out forwards}.wm-checkbox-label{font-size:.875rem;color:var(--wm-text-primary);line-height:1.4}@media(prefers-reduced-motion:reduce){.wm-checkbox-box{transition:none}.check-mark{animation:none}}\n"] }]
484
515
  }], propDecorators: { checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
485
516
 
486
517
  /**
@@ -577,7 +608,7 @@ class NumberInput {
577
608
  useExisting: forwardRef(() => NumberInput),
578
609
  multi: true,
579
610
  },
580
- ], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<!--\r\n Uses .wm-input-group and .wm-number-* classes from inputs.css.\r\n The input fills the group; the controls column sits at the trailing edge.\r\n-->\r\n<div\r\n class=\"wm-input-group wm-number-field\"\r\n [class.is-disabled]=\"disabled()\"\r\n>\r\n <input\r\n #inputEl\r\n type=\"number\"\r\n class=\"wm-input-bare wm-number-input\"\r\n [value]=\"internalValue() ?? ''\"\r\n [placeholder]=\"placeholder()\"\r\n [attr.min]=\"min() ?? null\"\r\n [attr.max]=\"max() ?? null\"\r\n [step]=\"step()\"\r\n [disabled]=\"disabled() || null\"\r\n (change)=\"onInputChange($event)\"\r\n (input)=\"onInputChange($event)\"\r\n (blur)=\"onTouchedFn()\"\r\n />\r\n\r\n <div class=\"wm-number-controls\" aria-hidden=\"true\">\r\n <button\r\n type=\"button\"\r\n class=\"wm-number-btn\"\r\n tabindex=\"-1\"\r\n [disabled]=\"disabled() || null\"\r\n (mousedown)=\"preventFocusSteal($event)\"\r\n (click)=\"increment()\"\r\n aria-label=\"Increment\"\r\n >\r\n <!-- chevron-up (lucide) -->\r\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <path d=\"m18 15-6-6-6 6\"/>\r\n </svg>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"wm-number-btn\"\r\n tabindex=\"-1\"\r\n [disabled]=\"disabled() || null\"\r\n (mousedown)=\"preventFocusSteal($event)\"\r\n (click)=\"decrement()\"\r\n aria-label=\"Decrement\"\r\n >\r\n <!-- chevron-down (lucide) -->\r\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <path d=\"m6 9 6 6 6-6\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n</div>\r\n", styles: [":host{display:block}.wm-number-field.is-disabled{opacity:.45;pointer-events:none}\n"] });
611
+ ], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<!--\n Uses .wm-input-group and .wm-number-* classes from inputs.css.\n The input fills the group; the controls column sits at the trailing edge.\n-->\n<div\n class=\"wm-input-group wm-number-field\"\n [class.is-disabled]=\"disabled()\"\n>\n <input\n #inputEl\n type=\"number\"\n class=\"wm-input-bare wm-number-input\"\n [value]=\"internalValue() ?? ''\"\n [placeholder]=\"placeholder()\"\n [attr.min]=\"min() ?? null\"\n [attr.max]=\"max() ?? null\"\n [step]=\"step()\"\n [disabled]=\"disabled() || null\"\n (change)=\"onInputChange($event)\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onTouchedFn()\"\n />\n\n <div class=\"wm-number-controls\" aria-hidden=\"true\">\n <button\n type=\"button\"\n class=\"wm-number-btn\"\n tabindex=\"-1\"\n [disabled]=\"disabled() || null\"\n (mousedown)=\"preventFocusSteal($event)\"\n (click)=\"increment()\"\n aria-label=\"Increment\"\n >\n <!-- chevron-up (lucide) -->\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <path d=\"m18 15-6-6-6 6\"/>\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"wm-number-btn\"\n tabindex=\"-1\"\n [disabled]=\"disabled() || null\"\n (mousedown)=\"preventFocusSteal($event)\"\n (click)=\"decrement()\"\n aria-label=\"Decrement\"\n >\n <!-- chevron-down (lucide) -->\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\"/>\n </svg>\n </button>\n </div>\n</div>\n", styles: [":host{display:block}.wm-number-field.is-disabled{opacity:.45;pointer-events:none}\n"] });
581
612
  }
582
613
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: NumberInput, decorators: [{
583
614
  type: Component,
@@ -587,7 +618,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
587
618
  useExisting: forwardRef(() => NumberInput),
588
619
  multi: true,
589
620
  },
590
- ], template: "<!--\r\n Uses .wm-input-group and .wm-number-* classes from inputs.css.\r\n The input fills the group; the controls column sits at the trailing edge.\r\n-->\r\n<div\r\n class=\"wm-input-group wm-number-field\"\r\n [class.is-disabled]=\"disabled()\"\r\n>\r\n <input\r\n #inputEl\r\n type=\"number\"\r\n class=\"wm-input-bare wm-number-input\"\r\n [value]=\"internalValue() ?? ''\"\r\n [placeholder]=\"placeholder()\"\r\n [attr.min]=\"min() ?? null\"\r\n [attr.max]=\"max() ?? null\"\r\n [step]=\"step()\"\r\n [disabled]=\"disabled() || null\"\r\n (change)=\"onInputChange($event)\"\r\n (input)=\"onInputChange($event)\"\r\n (blur)=\"onTouchedFn()\"\r\n />\r\n\r\n <div class=\"wm-number-controls\" aria-hidden=\"true\">\r\n <button\r\n type=\"button\"\r\n class=\"wm-number-btn\"\r\n tabindex=\"-1\"\r\n [disabled]=\"disabled() || null\"\r\n (mousedown)=\"preventFocusSteal($event)\"\r\n (click)=\"increment()\"\r\n aria-label=\"Increment\"\r\n >\r\n <!-- chevron-up (lucide) -->\r\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <path d=\"m18 15-6-6-6 6\"/>\r\n </svg>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"wm-number-btn\"\r\n tabindex=\"-1\"\r\n [disabled]=\"disabled() || null\"\r\n (mousedown)=\"preventFocusSteal($event)\"\r\n (click)=\"decrement()\"\r\n aria-label=\"Decrement\"\r\n >\r\n <!-- chevron-down (lucide) -->\r\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\r\n <path d=\"m6 9 6 6 6-6\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n</div>\r\n", styles: [":host{display:block}.wm-number-field.is-disabled{opacity:.45;pointer-events:none}\n"] }]
621
+ ], template: "<!--\n Uses .wm-input-group and .wm-number-* classes from inputs.css.\n The input fills the group; the controls column sits at the trailing edge.\n-->\n<div\n class=\"wm-input-group wm-number-field\"\n [class.is-disabled]=\"disabled()\"\n>\n <input\n #inputEl\n type=\"number\"\n class=\"wm-input-bare wm-number-input\"\n [value]=\"internalValue() ?? ''\"\n [placeholder]=\"placeholder()\"\n [attr.min]=\"min() ?? null\"\n [attr.max]=\"max() ?? null\"\n [step]=\"step()\"\n [disabled]=\"disabled() || null\"\n (change)=\"onInputChange($event)\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onTouchedFn()\"\n />\n\n <div class=\"wm-number-controls\" aria-hidden=\"true\">\n <button\n type=\"button\"\n class=\"wm-number-btn\"\n tabindex=\"-1\"\n [disabled]=\"disabled() || null\"\n (mousedown)=\"preventFocusSteal($event)\"\n (click)=\"increment()\"\n aria-label=\"Increment\"\n >\n <!-- chevron-up (lucide) -->\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <path d=\"m18 15-6-6-6 6\"/>\n </svg>\n </button>\n <button\n type=\"button\"\n class=\"wm-number-btn\"\n tabindex=\"-1\"\n [disabled]=\"disabled() || null\"\n (mousedown)=\"preventFocusSteal($event)\"\n (click)=\"decrement()\"\n aria-label=\"Decrement\"\n >\n <!-- chevron-down (lucide) -->\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\"/>\n </svg>\n </button>\n </div>\n</div>\n", styles: [":host{display:block}.wm-number-field.is-disabled{opacity:.45;pointer-events:none}\n"] }]
591
622
  }], propDecorators: { min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], inputRef: [{ type: i0.ViewChild, args: ['inputEl', { isSignal: true }] }] } });
592
623
 
593
624
  /**
@@ -616,11 +647,11 @@ class Toggle {
616
647
  }
617
648
  }
618
649
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: Toggle, deps: [], target: i0.ɵɵFactoryTarget.Component });
619
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.1", type: Toggle, isStandalone: true, selector: "wm-toggle", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange" }, ngImport: i0, template: "<button\r\n type=\"button\"\r\n role=\"switch\"\r\n class=\"wm-toggle\"\r\n [class.is-on]=\"checked()\"\r\n [class.is-disabled]=\"disabled()\"\r\n [attr.aria-checked]=\"checked()\"\r\n [attr.aria-label]=\"ariaLabel()\"\r\n [attr.aria-disabled]=\"disabled() ? true : null\"\r\n [disabled]=\"disabled() || null\"\r\n (click)=\"toggle()\"\r\n>\r\n <span class=\"wm-toggle-track\" aria-hidden=\"true\">\r\n <span class=\"wm-toggle-thumb\"></span>\r\n </span>\r\n</button>\r\n", styles: [":host{display:inline-flex}.wm-toggle{display:inline-flex;align-items:center;background:none;border:none;padding:2px;margin:-2px;cursor:pointer;border-radius:var(--wm-radius-full);outline:none}.wm-toggle:focus-visible .wm-toggle-track{outline:2px solid var(--wm-color-accent);outline-offset:2px}.wm-toggle.is-disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.wm-toggle-track{position:relative;width:40px;height:22px;background:var(--wm-border-input);border-radius:var(--wm-radius-full);transition:background var(--wm-transition-fast);flex-shrink:0}.wm-toggle.is-on .wm-toggle-track{background:var(--wm-color-accent)}.wm-toggle-thumb{position:absolute;top:3px;left:3px;width:16px;height:16px;background:#fff;border-radius:var(--wm-radius-full);box-shadow:0 1px 3px #00000040;transition:transform var(--wm-transition-fast)}.wm-toggle.is-on .wm-toggle-thumb{transform:translate(18px)}@media(prefers-reduced-motion:reduce){.wm-toggle-track,.wm-toggle-thumb{transition:none}}\n"] });
650
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.1", type: Toggle, isStandalone: true, selector: "wm-toggle", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange" }, ngImport: i0, template: "<button\n type=\"button\"\n role=\"switch\"\n class=\"wm-toggle\"\n [class.is-on]=\"checked()\"\n [class.is-disabled]=\"disabled()\"\n [attr.aria-checked]=\"checked()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-disabled]=\"disabled() ? true : null\"\n [disabled]=\"disabled() || null\"\n (click)=\"toggle()\"\n>\n <span class=\"wm-toggle-track\" aria-hidden=\"true\">\n <span class=\"wm-toggle-thumb\"></span>\n </span>\n</button>\n", styles: [":host{display:inline-flex}.wm-toggle{display:inline-flex;align-items:center;background:none;border:none;padding:2px;margin:-2px;cursor:pointer;border-radius:var(--wm-radius-full);outline:none}.wm-toggle:focus-visible .wm-toggle-track{outline:2px solid var(--wm-color-accent);outline-offset:2px}.wm-toggle.is-disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.wm-toggle-track{position:relative;width:40px;height:22px;background:var(--wm-border-input);border-radius:var(--wm-radius-full);transition:background var(--wm-transition-fast);flex-shrink:0}.wm-toggle.is-on .wm-toggle-track{background:var(--wm-color-accent)}.wm-toggle-thumb{position:absolute;top:3px;left:3px;width:16px;height:16px;background:#fff;border-radius:var(--wm-radius-full);box-shadow:0 1px 3px #00000040;transition:transform var(--wm-transition-fast)}.wm-toggle.is-on .wm-toggle-thumb{transform:translate(18px)}@media(prefers-reduced-motion:reduce){.wm-toggle-track,.wm-toggle-thumb{transition:none}}\n"] });
620
651
  }
621
652
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: Toggle, decorators: [{
622
653
  type: Component,
623
- args: [{ selector: 'wm-toggle', template: "<button\r\n type=\"button\"\r\n role=\"switch\"\r\n class=\"wm-toggle\"\r\n [class.is-on]=\"checked()\"\r\n [class.is-disabled]=\"disabled()\"\r\n [attr.aria-checked]=\"checked()\"\r\n [attr.aria-label]=\"ariaLabel()\"\r\n [attr.aria-disabled]=\"disabled() ? true : null\"\r\n [disabled]=\"disabled() || null\"\r\n (click)=\"toggle()\"\r\n>\r\n <span class=\"wm-toggle-track\" aria-hidden=\"true\">\r\n <span class=\"wm-toggle-thumb\"></span>\r\n </span>\r\n</button>\r\n", styles: [":host{display:inline-flex}.wm-toggle{display:inline-flex;align-items:center;background:none;border:none;padding:2px;margin:-2px;cursor:pointer;border-radius:var(--wm-radius-full);outline:none}.wm-toggle:focus-visible .wm-toggle-track{outline:2px solid var(--wm-color-accent);outline-offset:2px}.wm-toggle.is-disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.wm-toggle-track{position:relative;width:40px;height:22px;background:var(--wm-border-input);border-radius:var(--wm-radius-full);transition:background var(--wm-transition-fast);flex-shrink:0}.wm-toggle.is-on .wm-toggle-track{background:var(--wm-color-accent)}.wm-toggle-thumb{position:absolute;top:3px;left:3px;width:16px;height:16px;background:#fff;border-radius:var(--wm-radius-full);box-shadow:0 1px 3px #00000040;transition:transform var(--wm-transition-fast)}.wm-toggle.is-on .wm-toggle-thumb{transform:translate(18px)}@media(prefers-reduced-motion:reduce){.wm-toggle-track,.wm-toggle-thumb{transition:none}}\n"] }]
654
+ args: [{ selector: 'wm-toggle', template: "<button\n type=\"button\"\n role=\"switch\"\n class=\"wm-toggle\"\n [class.is-on]=\"checked()\"\n [class.is-disabled]=\"disabled()\"\n [attr.aria-checked]=\"checked()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-disabled]=\"disabled() ? true : null\"\n [disabled]=\"disabled() || null\"\n (click)=\"toggle()\"\n>\n <span class=\"wm-toggle-track\" aria-hidden=\"true\">\n <span class=\"wm-toggle-thumb\"></span>\n </span>\n</button>\n", styles: [":host{display:inline-flex}.wm-toggle{display:inline-flex;align-items:center;background:none;border:none;padding:2px;margin:-2px;cursor:pointer;border-radius:var(--wm-radius-full);outline:none}.wm-toggle:focus-visible .wm-toggle-track{outline:2px solid var(--wm-color-accent);outline-offset:2px}.wm-toggle.is-disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.wm-toggle-track{position:relative;width:40px;height:22px;background:var(--wm-border-input);border-radius:var(--wm-radius-full);transition:background var(--wm-transition-fast);flex-shrink:0}.wm-toggle.is-on .wm-toggle-track{background:var(--wm-color-accent)}.wm-toggle-thumb{position:absolute;top:3px;left:3px;width:16px;height:16px;background:#fff;border-radius:var(--wm-radius-full);box-shadow:0 1px 3px #00000040;transition:transform var(--wm-transition-fast)}.wm-toggle.is-on .wm-toggle-thumb{transform:translate(18px)}@media(prefers-reduced-motion:reduce){.wm-toggle-track,.wm-toggle-thumb{transition:none}}\n"] }]
624
655
  }], propDecorators: { checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
625
656
 
626
657
  /**
@@ -671,11 +702,11 @@ class PageHeader {
671
702
  subtitle = input(...(ngDevMode ? [undefined, { debugName: "subtitle" }] : []));
672
703
  badgeLabel = input(...(ngDevMode ? [undefined, { debugName: "badgeLabel" }] : []));
673
704
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: PageHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
674
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: PageHeader, isStandalone: true, selector: "wm-page-header", inputs: { flavourText: { classPropertyName: "flavourText", publicName: "flavourText", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, badgeLabel: { classPropertyName: "badgeLabel", publicName: "badgeLabel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<header class=\"wm-page-header\">\r\n <div class=\"wm-page-header__left\">\r\n <div class=\"wm-page-header__eyebrow\">\r\n <ng-content select=\"[icon]\" />\r\n <span>{{ flavourText() }}</span>\r\n </div>\r\n <h2 class=\"wm-page-header__title\">{{ title() }}</h2>\r\n @if (subtitle()) {\r\n <p class=\"wm-page-header__subtitle\">{{ subtitle() }}</p>\r\n }\r\n </div>\r\n\r\n <div class=\"wm-page-header__right\">\r\n <div class=\"wm-page-header__status\">\r\n @if (badgeLabel()) {\r\n <span class=\"wm-page-header__badge\">{{ badgeLabel() }}</span>\r\n }\r\n <ng-content select=\"[back]\" />\r\n </div>\r\n <div class=\"wm-page-header__actions\">\r\n <ng-content />\r\n </div>\r\n </div>\r\n</header>\r\n", styles: ["wm-page-header,.wm-page-header{display:flex;align-items:flex-end;justify-content:space-between;border-bottom:1px solid var(--wm-border-subtle);padding-bottom:1.5rem}.wm-page-header__left{display:flex;flex-direction:column;gap:4px}.wm-page-header__eyebrow{display:flex;align-items:center;gap:8px;font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.1em;color:var(--wm-text-muted)}.wm-page-header__eyebrow svg,.wm-page-header__eyebrow img{width:12px;height:12px;flex-shrink:0}.wm-page-header__title{margin:0;font-size:1.5rem;font-weight:700;letter-spacing:-.025em;color:var(--wm-text-primary)}.wm-page-header__subtitle{margin:0;font-size:.875rem;color:var(--wm-text-muted)}.wm-page-header__right{display:flex;flex-direction:column;align-items:flex-end;gap:12px}.wm-page-header__status,.wm-page-header__actions{display:flex;align-items:center;gap:12px}.wm-page-header__actions:empty{display:none}.wm-page-header__badge{font-size:.6875rem;font-family:monospace;font-weight:700;text-transform:uppercase;letter-spacing:-.05em;color:var(--wm-text-muted);background:var(--wm-bg-float);padding:4px 8px;border-radius:var(--wm-radius-sm);border:1px solid var(--wm-border-subtle);box-shadow:0 1px 2px #0000000d;white-space:nowrap}@media(max-width:767px){wm-page-header,.wm-page-header{flex-direction:column;align-items:stretch;gap:6px;padding-bottom:0;border-bottom:none}.wm-page-header__right{align-items:flex-start}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
705
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: PageHeader, isStandalone: true, selector: "wm-page-header", inputs: { flavourText: { classPropertyName: "flavourText", publicName: "flavourText", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, badgeLabel: { classPropertyName: "badgeLabel", publicName: "badgeLabel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<header class=\"wm-page-header\">\n <div class=\"wm-page-header__left\">\n <div class=\"wm-page-header__eyebrow\">\n <ng-content select=\"[icon]\" />\n <span>{{ flavourText() }}</span>\n </div>\n <h2 class=\"wm-page-header__title\">{{ title() }}</h2>\n @if (subtitle()) {\n <p class=\"wm-page-header__subtitle\">{{ subtitle() }}</p>\n }\n </div>\n\n <div class=\"wm-page-header__right\">\n <div class=\"wm-page-header__status\">\n @if (badgeLabel()) {\n <span class=\"wm-page-header__badge\">{{ badgeLabel() }}</span>\n }\n <ng-content select=\"[back]\" />\n </div>\n <div class=\"wm-page-header__actions\">\n <ng-content />\n </div>\n </div>\n</header>\n", styles: ["wm-page-header,.wm-page-header{display:flex;align-items:flex-end;justify-content:space-between;border-bottom:1px solid var(--wm-border-subtle);padding-bottom:1.5rem}.wm-page-header__left{display:flex;flex-direction:column;gap:4px}.wm-page-header__eyebrow{display:flex;align-items:center;gap:8px;font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.1em;color:var(--wm-text-muted)}.wm-page-header__eyebrow svg,.wm-page-header__eyebrow img{width:12px;height:12px;flex-shrink:0}.wm-page-header__title{margin:0;font-size:1.5rem;font-weight:700;letter-spacing:-.025em;color:var(--wm-text-primary)}.wm-page-header__subtitle{margin:0;font-size:.875rem;color:var(--wm-text-muted)}.wm-page-header__right{display:flex;flex-direction:column;align-items:flex-end;gap:12px}.wm-page-header__status,.wm-page-header__actions{display:flex;align-items:center;gap:12px}.wm-page-header__actions:empty{display:none}.wm-page-header__badge{font-size:.6875rem;font-family:monospace;font-weight:700;text-transform:uppercase;letter-spacing:-.05em;color:var(--wm-text-muted);background:var(--wm-bg-float);padding:4px 8px;border-radius:var(--wm-radius-sm);border:1px solid var(--wm-border-subtle);box-shadow:0 1px 2px #0000000d;white-space:nowrap}@media(max-width:767px){wm-page-header,.wm-page-header{flex-direction:column;align-items:stretch;gap:6px;padding-bottom:0;border-bottom:none}.wm-page-header__right{align-items:flex-start}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
675
706
  }
676
707
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: PageHeader, decorators: [{
677
708
  type: Component,
678
- args: [{ selector: 'wm-page-header', standalone: true, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"wm-page-header\">\r\n <div class=\"wm-page-header__left\">\r\n <div class=\"wm-page-header__eyebrow\">\r\n <ng-content select=\"[icon]\" />\r\n <span>{{ flavourText() }}</span>\r\n </div>\r\n <h2 class=\"wm-page-header__title\">{{ title() }}</h2>\r\n @if (subtitle()) {\r\n <p class=\"wm-page-header__subtitle\">{{ subtitle() }}</p>\r\n }\r\n </div>\r\n\r\n <div class=\"wm-page-header__right\">\r\n <div class=\"wm-page-header__status\">\r\n @if (badgeLabel()) {\r\n <span class=\"wm-page-header__badge\">{{ badgeLabel() }}</span>\r\n }\r\n <ng-content select=\"[back]\" />\r\n </div>\r\n <div class=\"wm-page-header__actions\">\r\n <ng-content />\r\n </div>\r\n </div>\r\n</header>\r\n", styles: ["wm-page-header,.wm-page-header{display:flex;align-items:flex-end;justify-content:space-between;border-bottom:1px solid var(--wm-border-subtle);padding-bottom:1.5rem}.wm-page-header__left{display:flex;flex-direction:column;gap:4px}.wm-page-header__eyebrow{display:flex;align-items:center;gap:8px;font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.1em;color:var(--wm-text-muted)}.wm-page-header__eyebrow svg,.wm-page-header__eyebrow img{width:12px;height:12px;flex-shrink:0}.wm-page-header__title{margin:0;font-size:1.5rem;font-weight:700;letter-spacing:-.025em;color:var(--wm-text-primary)}.wm-page-header__subtitle{margin:0;font-size:.875rem;color:var(--wm-text-muted)}.wm-page-header__right{display:flex;flex-direction:column;align-items:flex-end;gap:12px}.wm-page-header__status,.wm-page-header__actions{display:flex;align-items:center;gap:12px}.wm-page-header__actions:empty{display:none}.wm-page-header__badge{font-size:.6875rem;font-family:monospace;font-weight:700;text-transform:uppercase;letter-spacing:-.05em;color:var(--wm-text-muted);background:var(--wm-bg-float);padding:4px 8px;border-radius:var(--wm-radius-sm);border:1px solid var(--wm-border-subtle);box-shadow:0 1px 2px #0000000d;white-space:nowrap}@media(max-width:767px){wm-page-header,.wm-page-header{flex-direction:column;align-items:stretch;gap:6px;padding-bottom:0;border-bottom:none}.wm-page-header__right{align-items:flex-start}}\n"] }]
709
+ args: [{ selector: 'wm-page-header', standalone: true, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"wm-page-header\">\n <div class=\"wm-page-header__left\">\n <div class=\"wm-page-header__eyebrow\">\n <ng-content select=\"[icon]\" />\n <span>{{ flavourText() }}</span>\n </div>\n <h2 class=\"wm-page-header__title\">{{ title() }}</h2>\n @if (subtitle()) {\n <p class=\"wm-page-header__subtitle\">{{ subtitle() }}</p>\n }\n </div>\n\n <div class=\"wm-page-header__right\">\n <div class=\"wm-page-header__status\">\n @if (badgeLabel()) {\n <span class=\"wm-page-header__badge\">{{ badgeLabel() }}</span>\n }\n <ng-content select=\"[back]\" />\n </div>\n <div class=\"wm-page-header__actions\">\n <ng-content />\n </div>\n </div>\n</header>\n", styles: ["wm-page-header,.wm-page-header{display:flex;align-items:flex-end;justify-content:space-between;border-bottom:1px solid var(--wm-border-subtle);padding-bottom:1.5rem}.wm-page-header__left{display:flex;flex-direction:column;gap:4px}.wm-page-header__eyebrow{display:flex;align-items:center;gap:8px;font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.1em;color:var(--wm-text-muted)}.wm-page-header__eyebrow svg,.wm-page-header__eyebrow img{width:12px;height:12px;flex-shrink:0}.wm-page-header__title{margin:0;font-size:1.5rem;font-weight:700;letter-spacing:-.025em;color:var(--wm-text-primary)}.wm-page-header__subtitle{margin:0;font-size:.875rem;color:var(--wm-text-muted)}.wm-page-header__right{display:flex;flex-direction:column;align-items:flex-end;gap:12px}.wm-page-header__status,.wm-page-header__actions{display:flex;align-items:center;gap:12px}.wm-page-header__actions:empty{display:none}.wm-page-header__badge{font-size:.6875rem;font-family:monospace;font-weight:700;text-transform:uppercase;letter-spacing:-.05em;color:var(--wm-text-muted);background:var(--wm-bg-float);padding:4px 8px;border-radius:var(--wm-radius-sm);border:1px solid var(--wm-border-subtle);box-shadow:0 1px 2px #0000000d;white-space:nowrap}@media(max-width:767px){wm-page-header,.wm-page-header{flex-direction:column;align-items:stretch;gap:6px;padding-bottom:0;border-bottom:none}.wm-page-header__right{align-items:flex-start}}\n"] }]
679
710
  }], propDecorators: { flavourText: [{ type: i0.Input, args: [{ isSignal: true, alias: "flavourText", required: true }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], badgeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "badgeLabel", required: false }] }] } });
680
711
 
681
712
  /** Module-level counter for unique panel instance IDs. */
@@ -854,6 +885,22 @@ class WmCombobox {
854
885
  allowFreeform = input(false, ...(ngDevMode ? [{ debugName: "allowFreeform" }] : []));
855
886
  /** Placeholder text for the input. */
856
887
  placeholder = input('Search\u2026', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
888
+ /**
889
+ * Accessible name for the combobox input.
890
+ *
891
+ * Required unless `ariaLabelledby` is supplied. The host `<wm-combobox>` is
892
+ * not a labelable element, so a consumer's `<label for="\u2026">` cannot reach the
893
+ * inner input \u2014 and the placeholder is blanked as soon as a chip is selected,
894
+ * so in multi-select mode there is otherwise no accessible name at all once
895
+ * the user picks anything.
896
+ */
897
+ ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
898
+ /**
899
+ * ID of a visible element that names this combobox. Prefer this over
900
+ * `ariaLabel` when a visible caption exists, so the accessible name matches
901
+ * the visible text (WCAG 2.5.3, Label in Name).
902
+ */
903
+ ariaLabelledby = input(null, ...(ngDevMode ? [{ debugName: "ariaLabelledby" }] : []));
857
904
  /** Disable the combobox. */
858
905
  disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
859
906
  /** Custom async filter function. Overrides default substring matching. */
@@ -1334,13 +1381,13 @@ class WmCombobox {
1334
1381
  this.inputText.set(opt?.label ?? (typeof v === 'string' ? v : ''));
1335
1382
  }
1336
1383
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: WmCombobox, deps: [], target: i0.ɵɵFactoryTarget.Component });
1337
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: WmCombobox, isStandalone: true, selector: "wm-combobox", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, values: { classPropertyName: "values", publicName: "values", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, allowFreeform: { classPropertyName: "allowFreeform", publicName: "allowFreeform", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, filterFn: { classPropertyName: "filterFn", publicName: "filterFn", isSignal: true, isRequired: false, transformFunction: null }, itemHeight: { classPropertyName: "itemHeight", publicName: "itemHeight", isSignal: true, isRequired: false, transformFunction: null }, maxPanelHeight: { classPropertyName: "maxPanelHeight", publicName: "maxPanelHeight", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", values: "valuesChange", query: "query", opened: "opened", closed: "closed" }, providers: [
1384
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.1", type: WmCombobox, isStandalone: true, selector: "wm-combobox", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, values: { classPropertyName: "values", publicName: "values", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, allowFreeform: { classPropertyName: "allowFreeform", publicName: "allowFreeform", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "ariaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, filterFn: { classPropertyName: "filterFn", publicName: "filterFn", isSignal: true, isRequired: false, transformFunction: null }, itemHeight: { classPropertyName: "itemHeight", publicName: "itemHeight", isSignal: true, isRequired: false, transformFunction: null }, maxPanelHeight: { classPropertyName: "maxPanelHeight", publicName: "maxPanelHeight", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", values: "valuesChange", query: "query", opened: "opened", closed: "closed" }, providers: [
1338
1385
  {
1339
1386
  provide: NG_VALUE_ACCESSOR,
1340
1387
  useExisting: forwardRef(() => WmCombobox),
1341
1388
  multi: true,
1342
1389
  },
1343
- ], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputEl"], descendants: true, isSignal: true }, { propertyName: "panel", first: true, predicate: ComboboxPanel, descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Trigger wrapper \u2014 anchors the CDK overlay -->\n<div\n class=\"wm-cb-trigger\"\n [class.is-open]=\"isOpen()\"\n [class.is-disabled]=\"disabled()\"\n cdkOverlayOrigin\n #origin=\"cdkOverlayOrigin\"\n (click)=\"onTriggerClick()\"\n>\n <!-- Multi-select chips -->\n @if (multiple()) {\n @for (chip of chips(); track chip.value) {\n <span class=\"wm-cb-chip\">\n <span class=\"wm-cb-chip-label\">{{ chip.label }}</span>\n <button\n type=\"button\"\n class=\"wm-cb-chip-remove\"\n tabindex=\"-1\"\n [attr.aria-label]=\"'Remove ' + chip.label\"\n (mousedown)=\"$event.preventDefault(); $event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); removeChip(chip.value)\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M18 6L6 18M6 6l12 12\"\n stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n </span>\n }\n }\n\n <!-- Text input -->\n <input\n #inputEl\n type=\"text\"\n class=\"wm-cb-input\"\n role=\"combobox\"\n autocomplete=\"off\"\n [attr.placeholder]=\"chips().length ? '' : placeholder()\"\n [attr.aria-expanded]=\"isOpen()\"\n aria-haspopup=\"listbox\"\n [attr.aria-autocomplete]=\"allowFreeform() ? 'both' : 'list'\"\n [attr.aria-activedescendant]=\"activeDescendant()\"\n [attr.aria-controls]=\"isOpen() ? panelListboxId() : null\"\n [disabled]=\"disabled() || null\"\n [value]=\"inputText()\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onBlur()\"\n />\n\n <!-- Chevron -->\n <svg\n class=\"wm-cb-chevron\"\n [class.is-open]=\"isOpen()\"\n width=\"16\" height=\"16\" viewBox=\"0 0 24 24\"\n fill=\"none\" aria-hidden=\"true\"\n >\n <path d=\"M6 9l6 6 6-6\"\n stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n</div>\n\n<!-- Live region for screen readers -->\n<span class=\"wm-cb-sr-only\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ liveText() }}\n</span>\n\n<!-- Dropdown panel in CDK overlay -->\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayWidth]=\"overlayWidth\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n cdkConnectedOverlayBackdropClass=\"wm-cb-backdrop\"\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n>\n <div class=\"wm-cb-panel\">\n <wm-combobox-panel\n [options]=\"filteredOptions()\"\n [highlightIndex]=\"highlightIndex()\"\n [selectedValues]=\"selectedValues()\"\n [multiple]=\"multiple()\"\n [itemHeight]=\"itemHeight()\"\n [maxHeight]=\"maxPanelHeight()\"\n [filterQuery]=\"inputText()\"\n [loading]=\"asyncLoading()\"\n [freeformHint]=\"freeformHint()\"\n (optionClicked)=\"onOptionClicked($event)\"\n />\n </div>\n</ng-template>\n", styles: [":host{display:block}.wm-cb-trigger{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;width:100%;min-height:36px;padding:.25rem .5rem;background:var(--wm-bg-base);border:1px solid var(--wm-border-input);border-radius:var(--wm-radius-sm);color:var(--wm-text-primary);font-size:.875rem;cursor:text;transition:border-color var(--wm-transition-fast),box-shadow var(--wm-transition-fast)}.wm-cb-trigger:hover:not(.is-disabled){border-color:var(--wm-color-accent-readable)}.wm-cb-trigger:focus-within:not(.is-disabled){border-color:var(--wm-color-accent-readable);box-shadow:0 0 0 3px color-mix(in srgb,var(--wm-color-accent) 25%,transparent)}.wm-cb-trigger.is-open{border-color:var(--wm-color-accent-readable);box-shadow:0 0 0 3px color-mix(in srgb,var(--wm-color-accent) 20%,transparent)}.wm-cb-trigger.is-disabled{opacity:.45;cursor:not-allowed}.wm-cb-input{flex:1 1 60px;min-width:60px;border:none;outline:none;background:transparent;color:inherit;font:inherit;padding:.125rem 0}.wm-cb-input::placeholder{color:var(--wm-text-placeholder)}.wm-cb-input:disabled{cursor:not-allowed}.wm-cb-chevron{flex-shrink:0;color:var(--wm-text-muted);transition:transform var(--wm-transition-fast);pointer-events:none}.wm-cb-chevron.is-open{transform:rotate(180deg)}.wm-cb-chip{display:inline-flex;align-items:center;gap:.25rem;max-width:100%;padding:.125rem .375rem;background:color-mix(in srgb,var(--wm-color-accent) 15%,transparent);border:1px solid color-mix(in srgb,var(--wm-color-accent) 30%,transparent);border-radius:var(--wm-radius-sm);font-size:.8125rem;line-height:1.4;color:var(--wm-text-primary);-webkit-user-select:none;user-select:none}.wm-cb-chip-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wm-cb-chip-remove{display:inline-flex;align-items:center;justify-content:center;padding:0;border:none;background:transparent;color:var(--wm-text-muted);cursor:pointer;border-radius:var(--wm-radius-sm);transition:color var(--wm-transition-fast)}.wm-cb-chip-remove:hover{color:var(--wm-text-primary)}.wm-cb-backdrop{position:fixed;inset:0}.wm-cb-panel{width:100%;background:var(--wm-bg-float);border:1px solid var(--wm-border);border-radius:var(--wm-radius-lg);box-shadow:0 4px 6px -1px #00000014,0 10px 20px -4px #0000001f;overflow:hidden;padding:.25rem}.wm-cb-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: ComboboxPanel, selector: "wm-combobox-panel", inputs: ["options", "highlightIndex", "selectedValues", "multiple", "itemHeight", "maxHeight", "filterQuery", "loading", "freeformHint"], outputs: ["optionClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1390
+ ], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputEl"], descendants: true, isSignal: true }, { propertyName: "panel", first: true, predicate: ComboboxPanel, descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Trigger wrapper \u2014 anchors the CDK overlay -->\n<div\n class=\"wm-cb-trigger\"\n [class.is-open]=\"isOpen()\"\n [class.is-disabled]=\"disabled()\"\n cdkOverlayOrigin\n #origin=\"cdkOverlayOrigin\"\n (click)=\"onTriggerClick()\"\n>\n <!-- Multi-select chips -->\n @if (multiple()) {\n @for (chip of chips(); track chip.value) {\n <span class=\"wm-cb-chip\">\n <span class=\"wm-cb-chip-label\">{{ chip.label }}</span>\n <button\n type=\"button\"\n class=\"wm-cb-chip-remove\"\n tabindex=\"-1\"\n [attr.aria-label]=\"'Remove ' + chip.label\"\n (mousedown)=\"$event.preventDefault(); $event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); removeChip(chip.value)\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M18 6L6 18M6 6l12 12\"\n stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n </span>\n }\n }\n\n <!-- Text input -->\n <input\n #inputEl\n type=\"text\"\n class=\"wm-cb-input\"\n role=\"combobox\"\n autocomplete=\"off\"\n [attr.placeholder]=\"chips().length ? '' : placeholder()\"\n [attr.aria-label]=\"ariaLabelledby() ? null : ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledby()\"\n [attr.aria-expanded]=\"isOpen()\"\n aria-haspopup=\"listbox\"\n [attr.aria-autocomplete]=\"allowFreeform() ? 'both' : 'list'\"\n [attr.aria-activedescendant]=\"activeDescendant()\"\n [attr.aria-controls]=\"isOpen() ? panelListboxId() : null\"\n [disabled]=\"disabled() || null\"\n [value]=\"inputText()\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onBlur()\"\n />\n\n <!-- Chevron -->\n <svg\n class=\"wm-cb-chevron\"\n [class.is-open]=\"isOpen()\"\n width=\"16\" height=\"16\" viewBox=\"0 0 24 24\"\n fill=\"none\" aria-hidden=\"true\"\n >\n <path d=\"M6 9l6 6 6-6\"\n stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n</div>\n\n<!-- Live region for screen readers -->\n<span class=\"wm-cb-sr-only\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ liveText() }}\n</span>\n\n<!-- Dropdown panel in CDK overlay -->\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayWidth]=\"overlayWidth\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n cdkConnectedOverlayBackdropClass=\"wm-cb-backdrop\"\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n>\n <div class=\"wm-cb-panel\">\n <wm-combobox-panel\n [options]=\"filteredOptions()\"\n [highlightIndex]=\"highlightIndex()\"\n [selectedValues]=\"selectedValues()\"\n [multiple]=\"multiple()\"\n [itemHeight]=\"itemHeight()\"\n [maxHeight]=\"maxPanelHeight()\"\n [filterQuery]=\"inputText()\"\n [loading]=\"asyncLoading()\"\n [freeformHint]=\"freeformHint()\"\n (optionClicked)=\"onOptionClicked($event)\"\n />\n </div>\n</ng-template>\n", styles: [":host{display:block}.wm-cb-trigger{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;width:100%;min-height:36px;padding:.25rem .5rem;background:var(--wm-bg-base);border:1px solid var(--wm-border-input);border-radius:var(--wm-radius-sm);color:var(--wm-text-primary);font-size:.875rem;cursor:text;transition:border-color var(--wm-transition-fast),box-shadow var(--wm-transition-fast)}.wm-cb-trigger:hover:not(.is-disabled){border-color:var(--wm-color-accent-readable)}.wm-cb-trigger:focus-within:not(.is-disabled){border-color:var(--wm-color-accent-readable);box-shadow:0 0 0 3px color-mix(in srgb,var(--wm-color-accent) 25%,transparent)}.wm-cb-trigger.is-open{border-color:var(--wm-color-accent-readable);box-shadow:0 0 0 3px color-mix(in srgb,var(--wm-color-accent) 20%,transparent)}.wm-cb-trigger.is-disabled{opacity:.45;cursor:not-allowed}.wm-cb-input{flex:1 1 60px;min-width:60px;border:none;outline:none;background:transparent;color:inherit;font:inherit;padding:.125rem 0}.wm-cb-input::placeholder{color:var(--wm-text-placeholder)}.wm-cb-input:disabled{cursor:not-allowed}.wm-cb-chevron{flex-shrink:0;color:var(--wm-text-muted);transition:transform var(--wm-transition-fast);pointer-events:none}.wm-cb-chevron.is-open{transform:rotate(180deg)}.wm-cb-chip{display:inline-flex;align-items:center;gap:.25rem;max-width:100%;padding:.125rem .375rem;background:color-mix(in srgb,var(--wm-color-accent) 15%,transparent);border:1px solid color-mix(in srgb,var(--wm-color-accent) 30%,transparent);border-radius:var(--wm-radius-sm);font-size:.8125rem;line-height:1.4;color:var(--wm-text-primary);-webkit-user-select:none;user-select:none}.wm-cb-chip-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wm-cb-chip-remove{display:inline-flex;align-items:center;justify-content:center;padding:0;border:none;background:transparent;color:var(--wm-text-muted);cursor:pointer;border-radius:var(--wm-radius-sm);transition:color var(--wm-transition-fast)}.wm-cb-chip-remove:hover{color:var(--wm-text-primary)}.wm-cb-backdrop{position:fixed;inset:0}.wm-cb-panel{width:100%;background:var(--wm-bg-float);border:1px solid var(--wm-border);border-radius:var(--wm-radius-lg);box-shadow:0 4px 6px -1px #00000014,0 10px 20px -4px #0000001f;overflow:hidden;padding:.25rem}.wm-cb-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: ComboboxPanel, selector: "wm-combobox-panel", inputs: ["options", "highlightIndex", "selectedValues", "multiple", "itemHeight", "maxHeight", "filterQuery", "loading", "freeformHint"], outputs: ["optionClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1344
1391
  }
1345
1392
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImport: i0, type: WmCombobox, decorators: [{
1346
1393
  type: Component,
@@ -1350,8 +1397,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
1350
1397
  useExisting: forwardRef(() => WmCombobox),
1351
1398
  multi: true,
1352
1399
  },
1353
- ], template: "<!-- Trigger wrapper \u2014 anchors the CDK overlay -->\n<div\n class=\"wm-cb-trigger\"\n [class.is-open]=\"isOpen()\"\n [class.is-disabled]=\"disabled()\"\n cdkOverlayOrigin\n #origin=\"cdkOverlayOrigin\"\n (click)=\"onTriggerClick()\"\n>\n <!-- Multi-select chips -->\n @if (multiple()) {\n @for (chip of chips(); track chip.value) {\n <span class=\"wm-cb-chip\">\n <span class=\"wm-cb-chip-label\">{{ chip.label }}</span>\n <button\n type=\"button\"\n class=\"wm-cb-chip-remove\"\n tabindex=\"-1\"\n [attr.aria-label]=\"'Remove ' + chip.label\"\n (mousedown)=\"$event.preventDefault(); $event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); removeChip(chip.value)\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M18 6L6 18M6 6l12 12\"\n stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n </span>\n }\n }\n\n <!-- Text input -->\n <input\n #inputEl\n type=\"text\"\n class=\"wm-cb-input\"\n role=\"combobox\"\n autocomplete=\"off\"\n [attr.placeholder]=\"chips().length ? '' : placeholder()\"\n [attr.aria-expanded]=\"isOpen()\"\n aria-haspopup=\"listbox\"\n [attr.aria-autocomplete]=\"allowFreeform() ? 'both' : 'list'\"\n [attr.aria-activedescendant]=\"activeDescendant()\"\n [attr.aria-controls]=\"isOpen() ? panelListboxId() : null\"\n [disabled]=\"disabled() || null\"\n [value]=\"inputText()\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onBlur()\"\n />\n\n <!-- Chevron -->\n <svg\n class=\"wm-cb-chevron\"\n [class.is-open]=\"isOpen()\"\n width=\"16\" height=\"16\" viewBox=\"0 0 24 24\"\n fill=\"none\" aria-hidden=\"true\"\n >\n <path d=\"M6 9l6 6 6-6\"\n stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n</div>\n\n<!-- Live region for screen readers -->\n<span class=\"wm-cb-sr-only\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ liveText() }}\n</span>\n\n<!-- Dropdown panel in CDK overlay -->\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayWidth]=\"overlayWidth\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n cdkConnectedOverlayBackdropClass=\"wm-cb-backdrop\"\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n>\n <div class=\"wm-cb-panel\">\n <wm-combobox-panel\n [options]=\"filteredOptions()\"\n [highlightIndex]=\"highlightIndex()\"\n [selectedValues]=\"selectedValues()\"\n [multiple]=\"multiple()\"\n [itemHeight]=\"itemHeight()\"\n [maxHeight]=\"maxPanelHeight()\"\n [filterQuery]=\"inputText()\"\n [loading]=\"asyncLoading()\"\n [freeformHint]=\"freeformHint()\"\n (optionClicked)=\"onOptionClicked($event)\"\n />\n </div>\n</ng-template>\n", styles: [":host{display:block}.wm-cb-trigger{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;width:100%;min-height:36px;padding:.25rem .5rem;background:var(--wm-bg-base);border:1px solid var(--wm-border-input);border-radius:var(--wm-radius-sm);color:var(--wm-text-primary);font-size:.875rem;cursor:text;transition:border-color var(--wm-transition-fast),box-shadow var(--wm-transition-fast)}.wm-cb-trigger:hover:not(.is-disabled){border-color:var(--wm-color-accent-readable)}.wm-cb-trigger:focus-within:not(.is-disabled){border-color:var(--wm-color-accent-readable);box-shadow:0 0 0 3px color-mix(in srgb,var(--wm-color-accent) 25%,transparent)}.wm-cb-trigger.is-open{border-color:var(--wm-color-accent-readable);box-shadow:0 0 0 3px color-mix(in srgb,var(--wm-color-accent) 20%,transparent)}.wm-cb-trigger.is-disabled{opacity:.45;cursor:not-allowed}.wm-cb-input{flex:1 1 60px;min-width:60px;border:none;outline:none;background:transparent;color:inherit;font:inherit;padding:.125rem 0}.wm-cb-input::placeholder{color:var(--wm-text-placeholder)}.wm-cb-input:disabled{cursor:not-allowed}.wm-cb-chevron{flex-shrink:0;color:var(--wm-text-muted);transition:transform var(--wm-transition-fast);pointer-events:none}.wm-cb-chevron.is-open{transform:rotate(180deg)}.wm-cb-chip{display:inline-flex;align-items:center;gap:.25rem;max-width:100%;padding:.125rem .375rem;background:color-mix(in srgb,var(--wm-color-accent) 15%,transparent);border:1px solid color-mix(in srgb,var(--wm-color-accent) 30%,transparent);border-radius:var(--wm-radius-sm);font-size:.8125rem;line-height:1.4;color:var(--wm-text-primary);-webkit-user-select:none;user-select:none}.wm-cb-chip-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wm-cb-chip-remove{display:inline-flex;align-items:center;justify-content:center;padding:0;border:none;background:transparent;color:var(--wm-text-muted);cursor:pointer;border-radius:var(--wm-radius-sm);transition:color var(--wm-transition-fast)}.wm-cb-chip-remove:hover{color:var(--wm-text-primary)}.wm-cb-backdrop{position:fixed;inset:0}.wm-cb-panel{width:100%;background:var(--wm-bg-float);border:1px solid var(--wm-border);border-radius:var(--wm-radius-lg);box-shadow:0 4px 6px -1px #00000014,0 10px 20px -4px #0000001f;overflow:hidden;padding:.25rem}.wm-cb-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
1354
- }], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], values: [{ type: i0.Input, args: [{ isSignal: true, alias: "values", required: false }] }, { type: i0.Output, args: ["valuesChange"] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], allowFreeform: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowFreeform", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], filterFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterFn", required: false }] }], itemHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemHeight", required: false }] }], maxPanelHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxPanelHeight", required: false }] }], query: [{ type: i0.Output, args: ["query"] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], inputRef: [{ type: i0.ViewChild, args: ['inputEl', { isSignal: true }] }], panel: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ComboboxPanel), { isSignal: true }] }] } });
1400
+ ], template: "<!-- Trigger wrapper \u2014 anchors the CDK overlay -->\n<div\n class=\"wm-cb-trigger\"\n [class.is-open]=\"isOpen()\"\n [class.is-disabled]=\"disabled()\"\n cdkOverlayOrigin\n #origin=\"cdkOverlayOrigin\"\n (click)=\"onTriggerClick()\"\n>\n <!-- Multi-select chips -->\n @if (multiple()) {\n @for (chip of chips(); track chip.value) {\n <span class=\"wm-cb-chip\">\n <span class=\"wm-cb-chip-label\">{{ chip.label }}</span>\n <button\n type=\"button\"\n class=\"wm-cb-chip-remove\"\n tabindex=\"-1\"\n [attr.aria-label]=\"'Remove ' + chip.label\"\n (mousedown)=\"$event.preventDefault(); $event.stopPropagation()\"\n (click)=\"$event.stopPropagation(); removeChip(chip.value)\"\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M18 6L6 18M6 6l12 12\"\n stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </button>\n </span>\n }\n }\n\n <!-- Text input -->\n <input\n #inputEl\n type=\"text\"\n class=\"wm-cb-input\"\n role=\"combobox\"\n autocomplete=\"off\"\n [attr.placeholder]=\"chips().length ? '' : placeholder()\"\n [attr.aria-label]=\"ariaLabelledby() ? null : ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledby()\"\n [attr.aria-expanded]=\"isOpen()\"\n aria-haspopup=\"listbox\"\n [attr.aria-autocomplete]=\"allowFreeform() ? 'both' : 'list'\"\n [attr.aria-activedescendant]=\"activeDescendant()\"\n [attr.aria-controls]=\"isOpen() ? panelListboxId() : null\"\n [disabled]=\"disabled() || null\"\n [value]=\"inputText()\"\n (input)=\"onInput($event)\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onBlur()\"\n />\n\n <!-- Chevron -->\n <svg\n class=\"wm-cb-chevron\"\n [class.is-open]=\"isOpen()\"\n width=\"16\" height=\"16\" viewBox=\"0 0 24 24\"\n fill=\"none\" aria-hidden=\"true\"\n >\n <path d=\"M6 9l6 6 6-6\"\n stroke=\"currentColor\" stroke-width=\"2\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n</div>\n\n<!-- Live region for screen readers -->\n<span class=\"wm-cb-sr-only\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ liveText() }}\n</span>\n\n<!-- Dropdown panel in CDK overlay -->\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayWidth]=\"overlayWidth\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n cdkConnectedOverlayBackdropClass=\"wm-cb-backdrop\"\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n>\n <div class=\"wm-cb-panel\">\n <wm-combobox-panel\n [options]=\"filteredOptions()\"\n [highlightIndex]=\"highlightIndex()\"\n [selectedValues]=\"selectedValues()\"\n [multiple]=\"multiple()\"\n [itemHeight]=\"itemHeight()\"\n [maxHeight]=\"maxPanelHeight()\"\n [filterQuery]=\"inputText()\"\n [loading]=\"asyncLoading()\"\n [freeformHint]=\"freeformHint()\"\n (optionClicked)=\"onOptionClicked($event)\"\n />\n </div>\n</ng-template>\n", styles: [":host{display:block}.wm-cb-trigger{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;width:100%;min-height:36px;padding:.25rem .5rem;background:var(--wm-bg-base);border:1px solid var(--wm-border-input);border-radius:var(--wm-radius-sm);color:var(--wm-text-primary);font-size:.875rem;cursor:text;transition:border-color var(--wm-transition-fast),box-shadow var(--wm-transition-fast)}.wm-cb-trigger:hover:not(.is-disabled){border-color:var(--wm-color-accent-readable)}.wm-cb-trigger:focus-within:not(.is-disabled){border-color:var(--wm-color-accent-readable);box-shadow:0 0 0 3px color-mix(in srgb,var(--wm-color-accent) 25%,transparent)}.wm-cb-trigger.is-open{border-color:var(--wm-color-accent-readable);box-shadow:0 0 0 3px color-mix(in srgb,var(--wm-color-accent) 20%,transparent)}.wm-cb-trigger.is-disabled{opacity:.45;cursor:not-allowed}.wm-cb-input{flex:1 1 60px;min-width:60px;border:none;outline:none;background:transparent;color:inherit;font:inherit;padding:.125rem 0}.wm-cb-input::placeholder{color:var(--wm-text-placeholder)}.wm-cb-input:disabled{cursor:not-allowed}.wm-cb-chevron{flex-shrink:0;color:var(--wm-text-muted);transition:transform var(--wm-transition-fast);pointer-events:none}.wm-cb-chevron.is-open{transform:rotate(180deg)}.wm-cb-chip{display:inline-flex;align-items:center;gap:.25rem;max-width:100%;padding:.125rem .375rem;background:color-mix(in srgb,var(--wm-color-accent) 15%,transparent);border:1px solid color-mix(in srgb,var(--wm-color-accent) 30%,transparent);border-radius:var(--wm-radius-sm);font-size:.8125rem;line-height:1.4;color:var(--wm-text-primary);-webkit-user-select:none;user-select:none}.wm-cb-chip-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wm-cb-chip-remove{display:inline-flex;align-items:center;justify-content:center;padding:0;border:none;background:transparent;color:var(--wm-text-muted);cursor:pointer;border-radius:var(--wm-radius-sm);transition:color var(--wm-transition-fast)}.wm-cb-chip-remove:hover{color:var(--wm-text-primary)}.wm-cb-backdrop{position:fixed;inset:0}.wm-cb-panel{width:100%;background:var(--wm-bg-float);border:1px solid var(--wm-border);border-radius:var(--wm-radius-lg);box-shadow:0 4px 6px -1px #00000014,0 10px 20px -4px #0000001f;overflow:hidden;padding:.25rem}.wm-cb-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
1401
+ }], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], values: [{ type: i0.Input, args: [{ isSignal: true, alias: "values", required: false }] }, { type: i0.Output, args: ["valuesChange"] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], allowFreeform: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowFreeform", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelledby", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], filterFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterFn", required: false }] }], itemHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemHeight", required: false }] }], maxPanelHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxPanelHeight", required: false }] }], query: [{ type: i0.Output, args: ["query"] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], inputRef: [{ type: i0.ViewChild, args: ['inputEl', { isSignal: true }] }], panel: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ComboboxPanel), { isSignal: true }] }] } });
1355
1402
 
1356
1403
  let nextId = 0;
1357
1404
  /**