@wildmason/aegis 1.16.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +113 -2
- package/dist/fesm2022/wildmason-aegis-license.mjs +153 -0
- package/dist/fesm2022/wildmason-aegis-license.mjs.map +1 -0
- package/dist/fesm2022/wildmason-aegis.mjs +626 -294
- package/dist/fesm2022/wildmason-aegis.mjs.map +1 -1
- package/dist/types/wildmason-aegis-license.d.ts +73 -0
- package/dist/types/wildmason-aegis.d.ts +110 -71
- package/fonts/CascadiaCode-OFL.txt +94 -94
- package/inputs.css +43 -26
- package/package.json +27 -13
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CdkTrapFocus } from '@angular/cdk/a11y';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { input, output, HostListener, ChangeDetectionStrategy, Component, model, signal, computed, inject, ElementRef, Renderer2, ChangeDetectorRef, viewChild, effect, ViewEncapsulation, Input, Directive, contentChildren, forwardRef, ViewChild, Injectable, Injector, DestroyRef } from '@angular/core';
|
|
3
|
+
import { input, output, HostListener, ChangeDetectionStrategy, Component, model, signal, computed, inject, ElementRef, Renderer2, ChangeDetectorRef, viewChild, effect, ViewEncapsulation, Input, Directive, contentChildren, forwardRef, ViewChild, Injectable, Injector, DestroyRef, TemplateRef, contentChild } from '@angular/core';
|
|
4
4
|
import { CdkConnectedOverlay, CdkOverlayOrigin, createFlexibleConnectedPositionStrategy, createOverlayRef, createRepositionScrollStrategy } from '@angular/cdk/overlay';
|
|
5
5
|
import { NgTemplateOutlet } from '@angular/common';
|
|
6
6
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
@@ -8,7 +8,6 @@ import { Subject, debounceTime, switchMap, of, catchError, finalize } from 'rxjs
|
|
|
8
8
|
import * as i1 from '@angular/cdk/scrolling';
|
|
9
9
|
import { ScrollingModule, CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
|
|
10
10
|
import { ComponentPortal } from '@angular/cdk/portal';
|
|
11
|
-
import { invoke } from '@tauri-apps/api/core';
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
13
|
* WmModal — Lightweight modal backdrop with Escape key and click-outside dismissal.
|
|
@@ -47,7 +46,7 @@ import { invoke } from '@tauri-apps/api/core';
|
|
|
47
46
|
*/
|
|
48
47
|
class WmModal {
|
|
49
48
|
/** Whether the modal is currently open. */
|
|
50
|
-
visible = input.required(...(ngDevMode ? [{ debugName: "visible" }] : []));
|
|
49
|
+
visible = input.required(...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
51
50
|
/** Emitted when the user requests the modal to close (Escape or backdrop click). */
|
|
52
51
|
dismiss = output();
|
|
53
52
|
/**
|
|
@@ -55,17 +54,17 @@ class WmModal {
|
|
|
55
54
|
* - 'center' (default): panel is vertically centered (items-center)
|
|
56
55
|
* - 'top': panel appears near the top (items-start pt-20), for search/command overlays
|
|
57
56
|
*/
|
|
58
|
-
align = input('center', ...(ngDevMode ? [{ debugName: "align" }] : []));
|
|
57
|
+
align = input('center', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
|
|
59
58
|
onEscape() {
|
|
60
59
|
if (this.visible())
|
|
61
60
|
this.dismiss.emit();
|
|
62
61
|
}
|
|
63
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
64
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
62
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmModal, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
63
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.23", 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 });
|
|
65
64
|
}
|
|
66
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
65
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmModal, decorators: [{
|
|
67
66
|
type: Component,
|
|
68
|
-
args: [{ selector: 'wm-modal', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CdkTrapFocus], template: "@if (visible()) {\
|
|
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" }]
|
|
69
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: [{
|
|
70
69
|
type: HostListener,
|
|
71
70
|
args: ['document:keydown.escape']
|
|
@@ -100,22 +99,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
|
|
|
100
99
|
*/
|
|
101
100
|
class WmDialog {
|
|
102
101
|
/** Two-way binding for open/closed state. */
|
|
103
|
-
isOpen = model(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
|
|
102
|
+
isOpen = model(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
104
103
|
/** Dialog heading text. When set, aria-labelledby is applied automatically. */
|
|
105
|
-
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
104
|
+
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
106
105
|
/** Panel width preset. sm = 360px, md = 480px (default), lg = 640px. */
|
|
107
|
-
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
106
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
108
107
|
close() { this.isOpen.set(false); }
|
|
109
108
|
onEscape() {
|
|
110
109
|
if (this.isOpen())
|
|
111
110
|
this.close();
|
|
112
111
|
}
|
|
113
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
114
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
112
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
113
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.23", 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"] }] });
|
|
115
114
|
}
|
|
116
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
115
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmDialog, decorators: [{
|
|
117
116
|
type: Component,
|
|
118
|
-
args: [{ selector: 'wm-dialog', imports: [CdkTrapFocus], template: "@if (isOpen()) {\
|
|
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"] }]
|
|
119
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: [{
|
|
120
119
|
type: HostListener,
|
|
121
120
|
args: ['document:keydown.escape']
|
|
@@ -259,15 +258,15 @@ class WmSelect {
|
|
|
259
258
|
*/
|
|
260
259
|
scrollStrategy = new WmAnchoredScrollStrategy();
|
|
261
260
|
/** Array of options to display. */
|
|
262
|
-
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
|
|
261
|
+
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
263
262
|
/** The currently selected value. Two-way bindable. */
|
|
264
|
-
value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
263
|
+
value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
265
264
|
/** Placeholder text shown when no option is selected. */
|
|
266
|
-
placeholder = input('Select…', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
|
|
265
|
+
placeholder = input('Select…', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
267
266
|
/** Disables the trigger and prevents the panel from opening. */
|
|
268
|
-
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
269
|
-
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
|
|
270
|
-
selectedOption = computed(() => this.options().find((o) => o.value === this.value()) ?? null, ...(ngDevMode ? [{ debugName: "selectedOption" }] : []));
|
|
267
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
268
|
+
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
269
|
+
selectedOption = computed(() => this.options().find((o) => o.value === this.value()) ?? null, ...(ngDevMode ? [{ debugName: "selectedOption" }] : /* istanbul ignore next */ []));
|
|
271
270
|
hostEl = inject((ElementRef));
|
|
272
271
|
get overlayWidth() {
|
|
273
272
|
return this.hostEl.nativeElement.offsetWidth || 200;
|
|
@@ -287,10 +286,10 @@ class WmSelect {
|
|
|
287
286
|
this.isOpen.set(false);
|
|
288
287
|
}
|
|
289
288
|
}
|
|
290
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
291
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
289
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmSelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
290
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.23", 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 [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\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"] }] });
|
|
292
291
|
}
|
|
293
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
292
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmSelect, decorators: [{
|
|
294
293
|
type: Component,
|
|
295
294
|
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 [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\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"] }]
|
|
296
295
|
}], 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 }] }] } });
|
|
@@ -346,11 +345,11 @@ class WmPopover {
|
|
|
346
345
|
*/
|
|
347
346
|
scrollStrategy = new WmAnchoredScrollStrategy();
|
|
348
347
|
/** Whether the panel is currently open. */
|
|
349
|
-
isOpen = input(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
|
|
348
|
+
isOpen = input(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
350
349
|
/** Panel width in pixels, or 'auto' to match content. */
|
|
351
|
-
width = input('auto', ...(ngDevMode ? [{ debugName: "width" }] : []));
|
|
350
|
+
width = input('auto', ...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
|
|
352
351
|
/** ARIA role for the floating panel element. Use 'menu', 'listbox', 'dialog', etc. */
|
|
353
|
-
role = input('dialog', ...(ngDevMode ? [{ debugName: "role" }] : []));
|
|
352
|
+
role = input('dialog', ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
|
|
354
353
|
/**
|
|
355
354
|
* Accessible name applied to the floating panel element.
|
|
356
355
|
*
|
|
@@ -358,11 +357,11 @@ class WmPopover {
|
|
|
358
357
|
* equivalent labelling relationship. Keeping the name on the panel shell
|
|
359
358
|
* ensures the trigger's aria-controls points to the named semantic surface.
|
|
360
359
|
*/
|
|
361
|
-
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
360
|
+
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
362
361
|
/** Value for aria-haspopup on the trigger element. */
|
|
363
|
-
hasPopup = input('dialog', ...(ngDevMode ? [{ debugName: "hasPopup" }] : []));
|
|
362
|
+
hasPopup = input('dialog', ...(ngDevMode ? [{ debugName: "hasPopup" }] : /* istanbul ignore next */ []));
|
|
364
363
|
/** Horizontal alignment: 'start' aligns left edges, 'end' aligns right edges. */
|
|
365
|
-
align = input('start', ...(ngDevMode ? [{ debugName: "align" }] : []));
|
|
364
|
+
align = input('start', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
|
|
366
365
|
/**
|
|
367
366
|
* Whether the focus trap auto-captures focus into the panel on attach
|
|
368
367
|
* and restores it on detach. Defaults to `true`, which is right for
|
|
@@ -378,14 +377,14 @@ class WmPopover {
|
|
|
378
377
|
* panel when it has focus; this only opts out of the auto-capture and
|
|
379
378
|
* auto-restore.
|
|
380
379
|
*/
|
|
381
|
-
trapFocusAutoCapture = input(true, ...(ngDevMode ? [{ debugName: "trapFocusAutoCapture" }] : []));
|
|
380
|
+
trapFocusAutoCapture = input(true, ...(ngDevMode ? [{ debugName: "trapFocusAutoCapture" }] : /* istanbul ignore next */ []));
|
|
382
381
|
/** Emitted when the panel should close (backdrop click, Escape key, CDK detach). */
|
|
383
382
|
closed = output();
|
|
384
383
|
renderer = inject(Renderer2);
|
|
385
384
|
hostEl = inject(ElementRef);
|
|
386
385
|
cdr = inject(ChangeDetectorRef);
|
|
387
386
|
panelId = 'wm-popover-' + Math.random().toString(36).substring(2, 9);
|
|
388
|
-
panel = viewChild('panel', ...(ngDevMode ? [{ debugName: "panel" }] : []));
|
|
387
|
+
panel = viewChild('panel', ...(ngDevMode ? [{ debugName: "panel" }] : /* istanbul ignore next */ []));
|
|
389
388
|
constructor() {
|
|
390
389
|
effect(() => {
|
|
391
390
|
const open = this.isOpen();
|
|
@@ -432,10 +431,10 @@ class WmPopover {
|
|
|
432
431
|
onClose() {
|
|
433
432
|
this.closed.emit();
|
|
434
433
|
}
|
|
435
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
436
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.
|
|
434
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmPopover, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
435
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.23", type: WmPopover, isStandalone: true, selector: "wm-popover", inputs: { isOpen: { classPropertyName: "isOpen", publicName: "isOpen", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, hasPopup: { classPropertyName: "hasPopup", publicName: "hasPopup", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, trapFocusAutoCapture: { classPropertyName: "trapFocusAutoCapture", publicName: "trapFocusAutoCapture", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, viewQueries: [{ propertyName: "panel", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Trigger anchor -->\n<div cdkOverlayOrigin #origin=\"cdkOverlayOrigin\" class=\"wm-popover-trigger\">\n <ng-content select=\"[trigger]\"></ng-content>\n</div>\n\n<!-- Floating panel -->\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n (backdropClick)=\"onClose()\"\n (detach)=\"onClose()\"\n (attach)=\"onAttach()\"\n>\n <div\n #panel\n [id]=\"panelId\"\n [attr.role]=\"role()\"\n [attr.aria-label]=\"ariaLabel()\"\n class=\"wm-popover-panel\"\n [style.width]=\"width() === 'auto' ? 'auto' : width() + 'px'\"\n cdkTrapFocus\n [cdkTrapFocusAutoCapture]=\"trapFocusAutoCapture()\"\n (keydown.escape)=\"onClose()\"\n >\n <ng-content select=\"[content]\"></ng-content>\n </div>\n</ng-template>\n", styles: ["wm-popover{display:inline-flex;align-items:center}.wm-popover-trigger{display:block;width:100%}.wm-popover-panel{background:var(--wm-bg-raised);border:1px solid var(--wm-border);border-radius:var(--wm-radius-lg);box-shadow:0 4px 6px -1px #00000014,0 10px 20px -4px #00000024;overflow:hidden;outline:none}\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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
437
436
|
}
|
|
438
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
437
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmPopover, decorators: [{
|
|
439
438
|
type: Component,
|
|
440
439
|
args: [{ selector: 'wm-popover', imports: [CdkConnectedOverlay, CdkOverlayOrigin, CdkTrapFocus], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<!-- Trigger anchor -->\n<div cdkOverlayOrigin #origin=\"cdkOverlayOrigin\" class=\"wm-popover-trigger\">\n <ng-content select=\"[trigger]\"></ng-content>\n</div>\n\n<!-- Floating panel -->\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n (backdropClick)=\"onClose()\"\n (detach)=\"onClose()\"\n (attach)=\"onAttach()\"\n>\n <div\n #panel\n [id]=\"panelId\"\n [attr.role]=\"role()\"\n [attr.aria-label]=\"ariaLabel()\"\n class=\"wm-popover-panel\"\n [style.width]=\"width() === 'auto' ? 'auto' : width() + 'px'\"\n cdkTrapFocus\n [cdkTrapFocusAutoCapture]=\"trapFocusAutoCapture()\"\n (keydown.escape)=\"onClose()\"\n >\n <ng-content select=\"[content]\"></ng-content>\n </div>\n</ng-template>\n", styles: ["wm-popover{display:inline-flex;align-items:center}.wm-popover-trigger{display:block;width:100%}.wm-popover-panel{background:var(--wm-bg-raised);border:1px solid var(--wm-border);border-radius:var(--wm-radius-lg);box-shadow:0 4px 6px -1px #00000014,0 10px 20px -4px #00000024;overflow:hidden;outline:none}\n"] }]
|
|
441
440
|
}], ctorParameters: () => [], propDecorators: { isOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOpen", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hasPopup: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasPopup", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], trapFocusAutoCapture: [{ type: i0.Input, args: [{ isSignal: true, alias: "trapFocusAutoCapture", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], panel: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }] } });
|
|
@@ -474,10 +473,10 @@ class WmAutoFocus {
|
|
|
474
473
|
}
|
|
475
474
|
}, 50);
|
|
476
475
|
}
|
|
477
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
478
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.
|
|
476
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmAutoFocus, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
477
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.23", type: WmAutoFocus, isStandalone: true, selector: "[wmAutoFocus]", inputs: { enabled: ["wmAutoFocus", "enabled"] }, ngImport: i0 });
|
|
479
478
|
}
|
|
480
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
479
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmAutoFocus, decorators: [{
|
|
481
480
|
type: Directive,
|
|
482
481
|
args: [{
|
|
483
482
|
selector: '[wmAutoFocus]',
|
|
@@ -488,23 +487,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
|
|
|
488
487
|
}] } });
|
|
489
488
|
|
|
490
489
|
class WmTab {
|
|
491
|
-
value = input.required(...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
490
|
+
value = input.required(...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
492
491
|
/**
|
|
493
492
|
* Keeps a prerequisite-gated tab discoverable while preventing activation.
|
|
494
493
|
* Unlike a native disabled button, unavailable tabs remain in the roving
|
|
495
494
|
* focus order so keyboard and assistive-technology users can learn why the
|
|
496
495
|
* destination cannot be opened yet.
|
|
497
496
|
*/
|
|
498
|
-
unavailable = input(false, ...(ngDevMode ? [{ debugName: "unavailable" }] : []));
|
|
497
|
+
unavailable = input(false, ...(ngDevMode ? [{ debugName: "unavailable" }] : /* istanbul ignore next */ []));
|
|
499
498
|
/** Exact prerequisite guidance exposed to both pointer and AT users. */
|
|
500
|
-
unavailableReason = input('', ...(ngDevMode ? [{ debugName: "unavailableReason" }] : []));
|
|
499
|
+
unavailableReason = input('', ...(ngDevMode ? [{ debugName: "unavailableReason" }] : /* istanbul ignore next */ []));
|
|
501
500
|
/** Render a non-interactive group divider immediately before this tab. */
|
|
502
|
-
separatorBefore = input(false, ...(ngDevMode ? [{ debugName: "separatorBefore" }] : []));
|
|
501
|
+
separatorBefore = input(false, ...(ngDevMode ? [{ debugName: "separatorBefore" }] : /* istanbul ignore next */ []));
|
|
503
502
|
tmpl = viewChild.required('tmpl');
|
|
504
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
505
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.
|
|
503
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmTab, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
504
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.23", 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 });
|
|
506
505
|
}
|
|
507
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
506
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmTab, decorators: [{
|
|
508
507
|
type: Component,
|
|
509
508
|
args: [{
|
|
510
509
|
selector: 'wm-tab',
|
|
@@ -515,11 +514,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
|
|
|
515
514
|
}], 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 }] }] } });
|
|
516
515
|
|
|
517
516
|
class WmTabs {
|
|
518
|
-
activeValue = input.required(...(ngDevMode ? [{ debugName: "activeValue" }] : []));
|
|
519
|
-
variant = input('line', ...(ngDevMode ? [{ debugName: "variant" }] : []));
|
|
517
|
+
activeValue = input.required(...(ngDevMode ? [{ debugName: "activeValue" }] : /* istanbul ignore next */ []));
|
|
518
|
+
variant = input('line', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
520
519
|
select = output();
|
|
521
|
-
tabs = contentChildren(WmTab, ...(ngDevMode ? [{ debugName: "tabs" }] : []));
|
|
522
|
-
focusedIndex = signal(null, ...(ngDevMode ? [{ debugName: "focusedIndex" }] : []));
|
|
520
|
+
tabs = contentChildren(WmTab, ...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
|
|
521
|
+
focusedIndex = signal(null, ...(ngDevMode ? [{ debugName: "focusedIndex" }] : /* istanbul ignore next */ []));
|
|
523
522
|
selectTab(tab, index) {
|
|
524
523
|
this.focusedIndex.set(index);
|
|
525
524
|
if (!tab.unavailable())
|
|
@@ -562,35 +561,35 @@ class WmTabs {
|
|
|
562
561
|
btns[nextIndex]?.focus();
|
|
563
562
|
}
|
|
564
563
|
}
|
|
565
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
566
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
564
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmTabs, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
565
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.23", 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\n class=\"wm-tab-separator\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n ></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:color-mix(in srgb,var(--wm-text-muted) 52%,transparent);box-shadow:none}.wm-tab.is-unavailable:hover{background:transparent;color:color-mix(in srgb,var(--wm-text-muted) 52%,transparent)}.wm-tab-separator{flex:0 0 1px;align-self:center;width:1px;height:1.25rem;margin:0 .375rem;background: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:color-mix(in srgb,var(--wm-text-muted) 52%,transparent);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 });
|
|
567
566
|
}
|
|
568
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
567
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmTabs, decorators: [{
|
|
569
568
|
type: Component,
|
|
570
|
-
args: [{ selector: 'wm-tabs', imports: [NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\
|
|
569
|
+
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\n class=\"wm-tab-separator\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n ></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:color-mix(in srgb,var(--wm-text-muted) 52%,transparent);box-shadow:none}.wm-tab.is-unavailable:hover{background:transparent;color:color-mix(in srgb,var(--wm-text-muted) 52%,transparent)}.wm-tab-separator{flex:0 0 1px;align-self:center;width:1px;height:1.25rem;margin:0 .375rem;background: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:color-mix(in srgb,var(--wm-text-muted) 52%,transparent);box-shadow:none}@media(prefers-reduced-motion:reduce){.wm-tab{transition:none}}\n"] }]
|
|
571
570
|
}], 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 }] }] } });
|
|
572
571
|
|
|
573
572
|
class WmButton {
|
|
574
|
-
variant = input('primary', ...(ngDevMode ? [{ debugName: "variant" }] : []));
|
|
575
|
-
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
576
|
-
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
577
|
-
type = input('button', ...(ngDevMode ? [{ debugName: "type" }] : []));
|
|
573
|
+
variant = input('primary', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
574
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
575
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
576
|
+
type = input('button', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
578
577
|
/** Makes the button square (equal width/height). Use for icon-only buttons. */
|
|
579
|
-
iconOnly = input(false, ...(ngDevMode ? [{ debugName: "iconOnly" }] : []));
|
|
578
|
+
iconOnly = input(false, ...(ngDevMode ? [{ debugName: "iconOnly" }] : /* istanbul ignore next */ []));
|
|
580
579
|
/** Accessible label forwarded to the inner <button>. Required for icon-only buttons. */
|
|
581
|
-
ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
580
|
+
ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
582
581
|
/** Tooltip text forwarded to the inner <button>. Named btnTitle to avoid native attribute conflict. */
|
|
583
|
-
btnTitle = input('', ...(ngDevMode ? [{ debugName: "btnTitle" }] : []));
|
|
582
|
+
btnTitle = input('', ...(ngDevMode ? [{ debugName: "btnTitle" }] : /* istanbul ignore next */ []));
|
|
584
583
|
btnClass = computed(() => {
|
|
585
584
|
const base = `wm-btn wm-btn--${this.variant()} wm-btn--${this.size()}`;
|
|
586
585
|
return this.iconOnly() ? `${base} btn-icon-only` : base;
|
|
587
|
-
}, ...(ngDevMode ? [{ debugName: "btnClass" }] : []));
|
|
588
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
589
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.
|
|
586
|
+
}, ...(ngDevMode ? [{ debugName: "btnClass" }] : /* istanbul ignore next */ []));
|
|
587
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
588
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.23", 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"] });
|
|
590
589
|
}
|
|
591
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
590
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmButton, decorators: [{
|
|
592
591
|
type: Component,
|
|
593
|
-
args: [{ selector: 'wm-button', template: "<button\
|
|
592
|
+
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"] }]
|
|
594
593
|
}], 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 }] }] } });
|
|
595
594
|
|
|
596
595
|
/**
|
|
@@ -615,33 +614,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
|
|
|
615
614
|
*/
|
|
616
615
|
class Checkbox {
|
|
617
616
|
/** Two-way bindable checked state. */
|
|
618
|
-
checked = model(false, ...(ngDevMode ? [{ debugName: "checked" }] : []));
|
|
617
|
+
checked = model(false, ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
|
|
619
618
|
/**
|
|
620
619
|
* Shows a dash icon instead of a checkmark. Typically used for a "select all"
|
|
621
620
|
* checkbox when only some child items are selected.
|
|
622
621
|
* Note: indeterminate is display-only — clicking always toggles to true/false.
|
|
623
622
|
*/
|
|
624
|
-
indeterminate = input(false, ...(ngDevMode ? [{ debugName: "indeterminate" }] : []));
|
|
623
|
+
indeterminate = input(false, ...(ngDevMode ? [{ debugName: "indeterminate" }] : /* istanbul ignore next */ []));
|
|
625
624
|
/** Visible text label rendered next to the checkbox box. */
|
|
626
|
-
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
627
|
-
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
625
|
+
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
626
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
628
627
|
/** Maps to aria-checked: true, false, or "mixed" (for indeterminate). */
|
|
629
628
|
ariaChecked = computed(() => {
|
|
630
629
|
if (this.indeterminate() && !this.checked())
|
|
631
630
|
return 'mixed';
|
|
632
631
|
return this.checked();
|
|
633
|
-
}, ...(ngDevMode ? [{ debugName: "ariaChecked" }] : []));
|
|
632
|
+
}, ...(ngDevMode ? [{ debugName: "ariaChecked" }] : /* istanbul ignore next */ []));
|
|
634
633
|
toggle() {
|
|
635
634
|
if (!this.disabled()) {
|
|
636
635
|
this.checked.update(v => !v);
|
|
637
636
|
}
|
|
638
637
|
}
|
|
639
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
640
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
638
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: Checkbox, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
639
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.23", 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"] });
|
|
641
640
|
}
|
|
642
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
641
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: Checkbox, decorators: [{
|
|
643
642
|
type: Component,
|
|
644
|
-
args: [{ selector: 'wm-checkbox', template: "<label class=\"wm-checkbox-wrap\" [class.is-disabled]=\"disabled()\">\
|
|
643
|
+
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"] }]
|
|
645
644
|
}], 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 }] }] } });
|
|
646
645
|
|
|
647
646
|
/**
|
|
@@ -674,17 +673,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
|
|
|
674
673
|
*/
|
|
675
674
|
class NumberInput {
|
|
676
675
|
/** Minimum allowed value. */
|
|
677
|
-
min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : []));
|
|
676
|
+
min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
|
|
678
677
|
/** Maximum allowed value. */
|
|
679
|
-
max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : []));
|
|
678
|
+
max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
|
|
680
679
|
/** Amount to increment/decrement per step. Defaults to 1. */
|
|
681
|
-
step = input(1, ...(ngDevMode ? [{ debugName: "step" }] : []));
|
|
680
|
+
step = input(1, ...(ngDevMode ? [{ debugName: "step" }] : /* istanbul ignore next */ []));
|
|
682
681
|
/** Placeholder text shown when the field is empty. */
|
|
683
|
-
placeholder = input('0', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
|
|
682
|
+
placeholder = input('0', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
684
683
|
/** Disables the control from the template. Also set automatically by reactive forms. */
|
|
685
|
-
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
686
|
-
inputRef = viewChild('inputEl', ...(ngDevMode ? [{ debugName: "inputRef" }] : []));
|
|
687
|
-
internalValue = signal(null, ...(ngDevMode ? [{ debugName: "internalValue" }] : []));
|
|
684
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
685
|
+
inputRef = viewChild('inputEl', ...(ngDevMode ? [{ debugName: "inputRef" }] : /* istanbul ignore next */ []));
|
|
686
|
+
internalValue = signal(null, ...(ngDevMode ? [{ debugName: "internalValue" }] : /* istanbul ignore next */ []));
|
|
688
687
|
onChangeFn = () => { };
|
|
689
688
|
onTouchedFn = () => { };
|
|
690
689
|
/** CVA interface — called when the form model changes programmatically. */
|
|
@@ -731,16 +730,16 @@ class NumberInput {
|
|
|
731
730
|
if (el)
|
|
732
731
|
el.nativeElement.value = String(val);
|
|
733
732
|
}
|
|
734
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
735
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.
|
|
733
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: NumberInput, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
734
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.23", type: NumberInput, isStandalone: true, selector: "wm-number-input", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", 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 } }, providers: [
|
|
736
735
|
{
|
|
737
736
|
provide: NG_VALUE_ACCESSOR,
|
|
738
737
|
useExisting: forwardRef(() => NumberInput),
|
|
739
738
|
multi: true,
|
|
740
739
|
},
|
|
741
|
-
], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<!--\
|
|
740
|
+
], 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"] });
|
|
742
741
|
}
|
|
743
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
742
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: NumberInput, decorators: [{
|
|
744
743
|
type: Component,
|
|
745
744
|
args: [{ selector: 'wm-number-input', providers: [
|
|
746
745
|
{
|
|
@@ -748,7 +747,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
|
|
|
748
747
|
useExisting: forwardRef(() => NumberInput),
|
|
749
748
|
multi: true,
|
|
750
749
|
},
|
|
751
|
-
], template: "<!--\
|
|
750
|
+
], 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"] }]
|
|
752
751
|
}], 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 }] }] } });
|
|
753
752
|
|
|
754
753
|
/**
|
|
@@ -766,22 +765,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
|
|
|
766
765
|
*/
|
|
767
766
|
class Toggle {
|
|
768
767
|
/** Two-way bindable state. Use [(checked)]="mySignal" or [checked]="val" (changeChecked)="val=$event". */
|
|
769
|
-
checked = model(false, ...(ngDevMode ? [{ debugName: "checked" }] : []));
|
|
768
|
+
checked = model(false, ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
|
|
770
769
|
/** Visually and functionally disables the toggle. State is still readable by assistive tech. */
|
|
771
|
-
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
770
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
772
771
|
/** Accessible label. Required if no visible label text surrounds the toggle in the DOM. */
|
|
773
|
-
ariaLabel = input('Toggle', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
772
|
+
ariaLabel = input('Toggle', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
774
773
|
toggle() {
|
|
775
774
|
if (!this.disabled()) {
|
|
776
775
|
this.checked.update(v => !v);
|
|
777
776
|
}
|
|
778
777
|
}
|
|
779
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
780
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.
|
|
778
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: Toggle, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
779
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.23", 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"] });
|
|
781
780
|
}
|
|
782
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
781
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: Toggle, decorators: [{
|
|
783
782
|
type: Component,
|
|
784
|
-
args: [{ selector: 'wm-toggle', template: "<button\
|
|
783
|
+
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"] }]
|
|
785
784
|
}], 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 }] }] } });
|
|
786
785
|
|
|
787
786
|
/**
|
|
@@ -797,10 +796,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
|
|
|
797
796
|
* </wm-ghost-field>
|
|
798
797
|
*/
|
|
799
798
|
class GhostField {
|
|
800
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
801
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.
|
|
799
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: GhostField, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
800
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.23", type: GhostField, isStandalone: true, selector: "wm-ghost-field", ngImport: i0, template: `<div class="wm-ghost-field"><ng-content /></div>`, isInline: true, encapsulation: i0.ViewEncapsulation.None });
|
|
802
801
|
}
|
|
803
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
802
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: GhostField, decorators: [{
|
|
804
803
|
type: Component,
|
|
805
804
|
args: [{
|
|
806
805
|
selector: 'wm-ghost-field',
|
|
@@ -827,16 +826,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
|
|
|
827
826
|
* </wm-page-header>
|
|
828
827
|
*/
|
|
829
828
|
class PageHeader {
|
|
830
|
-
flavourText = input.required(...(ngDevMode ? [{ debugName: "flavourText" }] : []));
|
|
831
|
-
title = input.required(...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
832
|
-
subtitle = input(...(ngDevMode ? [undefined, { debugName: "subtitle" }] : []));
|
|
833
|
-
badgeLabel = input(...(ngDevMode ? [undefined, { debugName: "badgeLabel" }] : []));
|
|
834
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
835
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
829
|
+
flavourText = input.required(...(ngDevMode ? [{ debugName: "flavourText" }] : /* istanbul ignore next */ []));
|
|
830
|
+
title = input.required(...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
831
|
+
subtitle = input(...(ngDevMode ? [undefined, { debugName: "subtitle" }] : /* istanbul ignore next */ []));
|
|
832
|
+
badgeLabel = input(...(ngDevMode ? [undefined, { debugName: "badgeLabel" }] : /* istanbul ignore next */ []));
|
|
833
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: PageHeader, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
834
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.23", 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:var(--wm-font-mono, 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 });
|
|
836
835
|
}
|
|
837
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
836
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: PageHeader, decorators: [{
|
|
838
837
|
type: Component,
|
|
839
|
-
args: [{ selector: 'wm-page-header', standalone: true, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"wm-page-header\">\
|
|
838
|
+
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:var(--wm-font-mono, 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"] }]
|
|
840
839
|
}], 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 }] }] } });
|
|
841
840
|
|
|
842
841
|
/** Module-level counter for unique panel instance IDs. */
|
|
@@ -847,23 +846,23 @@ let nextPanelId = 0;
|
|
|
847
846
|
*/
|
|
848
847
|
class ComboboxPanel {
|
|
849
848
|
/** Filtered options to display. */
|
|
850
|
-
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
|
|
849
|
+
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
851
850
|
/** Index of the keyboard-highlighted option (-1 = none). */
|
|
852
|
-
highlightIndex = input(-1, ...(ngDevMode ? [{ debugName: "highlightIndex" }] : []));
|
|
851
|
+
highlightIndex = input(-1, ...(ngDevMode ? [{ debugName: "highlightIndex" }] : /* istanbul ignore next */ []));
|
|
853
852
|
/** Values currently selected (for checkmark display). */
|
|
854
|
-
selectedValues = input(new Set(), ...(ngDevMode ? [{ debugName: "selectedValues" }] : []));
|
|
853
|
+
selectedValues = input(new Set(), ...(ngDevMode ? [{ debugName: "selectedValues" }] : /* istanbul ignore next */ []));
|
|
855
854
|
/** Whether the parent is multi-select. */
|
|
856
|
-
multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : []));
|
|
855
|
+
multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
|
|
857
856
|
/** Pixel height per row. */
|
|
858
|
-
itemHeight = input(36, ...(ngDevMode ? [{ debugName: "itemHeight" }] : []));
|
|
857
|
+
itemHeight = input(36, ...(ngDevMode ? [{ debugName: "itemHeight" }] : /* istanbul ignore next */ []));
|
|
859
858
|
/** Max panel height in pixels. */
|
|
860
|
-
maxHeight = input(256, ...(ngDevMode ? [{ debugName: "maxHeight" }] : []));
|
|
859
|
+
maxHeight = input(256, ...(ngDevMode ? [{ debugName: "maxHeight" }] : /* istanbul ignore next */ []));
|
|
861
860
|
/** Current filter text — used for match highlighting in labels. */
|
|
862
|
-
filterQuery = input('', ...(ngDevMode ? [{ debugName: "filterQuery" }] : []));
|
|
861
|
+
filterQuery = input('', ...(ngDevMode ? [{ debugName: "filterQuery" }] : /* istanbul ignore next */ []));
|
|
863
862
|
/** Show spinner when async filter is pending. */
|
|
864
|
-
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
863
|
+
loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
865
864
|
/** Shown in empty state when freeform input is enabled. */
|
|
866
|
-
freeformHint = input('', ...(ngDevMode ? [{ debugName: "freeformHint" }] : []));
|
|
865
|
+
freeformHint = input('', ...(ngDevMode ? [{ debugName: "freeformHint" }] : /* istanbul ignore next */ []));
|
|
867
866
|
/** Emitted on mousedown (not click) to prevent focus steal. */
|
|
868
867
|
optionClicked = output();
|
|
869
868
|
viewport;
|
|
@@ -875,11 +874,11 @@ class ComboboxPanel {
|
|
|
875
874
|
viewportHeight = computed(() => {
|
|
876
875
|
const count = this.options().length;
|
|
877
876
|
return Math.min(count * this.itemHeight(), this.maxHeight());
|
|
878
|
-
}, ...(ngDevMode ? [{ debugName: "viewportHeight" }] : []));
|
|
877
|
+
}, ...(ngDevMode ? [{ debugName: "viewportHeight" }] : /* istanbul ignore next */ []));
|
|
879
878
|
/** Whether to show the empty state. */
|
|
880
|
-
showEmpty = computed(() => this.options().length === 0 && !this.loading(), ...(ngDevMode ? [{ debugName: "showEmpty" }] : []));
|
|
879
|
+
showEmpty = computed(() => this.options().length === 0 && !this.loading(), ...(ngDevMode ? [{ debugName: "showEmpty" }] : /* istanbul ignore next */ []));
|
|
881
880
|
/** Text for the empty state. */
|
|
882
|
-
emptyText = computed(() => this.freeformHint() || 'No matches', ...(ngDevMode ? [{ debugName: "emptyText" }] : []));
|
|
881
|
+
emptyText = computed(() => this.freeformHint() || 'No matches', ...(ngDevMode ? [{ debugName: "emptyText" }] : /* istanbul ignore next */ []));
|
|
883
882
|
/**
|
|
884
883
|
* Precomputed label segments for each option, split by the current filter query.
|
|
885
884
|
* Recomputes whenever options or filterQuery changes.
|
|
@@ -887,7 +886,7 @@ class ComboboxPanel {
|
|
|
887
886
|
segmentedLabels = computed(() => {
|
|
888
887
|
const query = this.filterQuery().trim();
|
|
889
888
|
return this.options().map(opt => this.splitLabel(opt.label, query));
|
|
890
|
-
}, ...(ngDevMode ? [{ debugName: "segmentedLabels" }] : []));
|
|
889
|
+
}, ...(ngDevMode ? [{ debugName: "segmentedLabels" }] : /* istanbul ignore next */ []));
|
|
891
890
|
/** Map from option value to a stable key for DOM IDs. */
|
|
892
891
|
optionKeyMap = new Map();
|
|
893
892
|
nextObjectIndex = 0;
|
|
@@ -967,10 +966,10 @@ class ComboboxPanel {
|
|
|
967
966
|
}
|
|
968
967
|
return segments;
|
|
969
968
|
}
|
|
970
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
971
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
969
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: ComboboxPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
970
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.23", type: ComboboxPanel, isStandalone: true, selector: "wm-combobox-panel", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, highlightIndex: { classPropertyName: "highlightIndex", publicName: "highlightIndex", isSignal: true, isRequired: false, transformFunction: null }, selectedValues: { classPropertyName: "selectedValues", publicName: "selectedValues", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, itemHeight: { classPropertyName: "itemHeight", publicName: "itemHeight", isSignal: true, isRequired: false, transformFunction: null }, maxHeight: { classPropertyName: "maxHeight", publicName: "maxHeight", isSignal: true, isRequired: false, transformFunction: null }, filterQuery: { classPropertyName: "filterQuery", publicName: "filterQuery", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, freeformHint: { classPropertyName: "freeformHint", publicName: "freeformHint", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { optionClicked: "optionClicked" }, viewQueries: [{ propertyName: "viewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }], ngImport: i0, template: "@if (loading()) {\n <div class=\"wm-cb-loading\" aria-live=\"polite\">\n <svg\n class=\"wm-cb-spinner\"\n width=\"20\" height=\"20\" viewBox=\"0 0 20 20\"\n fill=\"none\" aria-hidden=\"true\"\n >\n <circle\n cx=\"10\" cy=\"10\" r=\"8\"\n stroke=\"currentColor\" stroke-width=\"2\"\n stroke-dasharray=\"40 60\"\n stroke-linecap=\"round\"\n />\n </svg>\n <span class=\"wm-cb-loading-text\">Loading\u2026</span>\n </div>\n} @else if (showEmpty()) {\n <div class=\"wm-cb-empty\" aria-live=\"polite\">{{ emptyText() }}</div>\n} @else {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"itemHeight()\"\n [style.height.px]=\"viewportHeight()\"\n class=\"wm-cb-viewport\"\n >\n <div\n [id]=\"listboxId\"\n role=\"listbox\"\n [attr.aria-multiselectable]=\"multiple() ? true : null\"\n >\n <div\n *cdkVirtualFor=\"let opt of options(); let i = index\"\n role=\"option\"\n class=\"wm-cb-option\"\n [id]=\"optionIdAt(i)\"\n [class.is-highlighted]=\"i === highlightIndex()\"\n [class.is-selected]=\"isSelected(opt.value)\"\n [class.is-disabled]=\"!!opt.disabled\"\n [attr.aria-selected]=\"isSelected(opt.value)\"\n [attr.aria-disabled]=\"opt.disabled ? true : null\"\n (mousedown)=\"onOptionMousedown($event, opt, i)\"\n >\n <span class=\"wm-cb-option-label\">\n @for (seg of segmentsAt(i); track $index) {\n @if (seg.match) {\n <b class=\"wm-cb-match\">{{ seg.text }}</b>\n } @else {\n {{ seg.text }}\n }\n }\n </span>\n @if (isSelected(opt.value)) {\n <svg\n class=\"wm-cb-check\"\n width=\"14\" height=\"14\" viewBox=\"0 0 24 24\"\n fill=\"none\" aria-hidden=\"true\"\n >\n <polyline\n points=\"20 6 9 17 4 12\"\n stroke=\"currentColor\" stroke-width=\"2.5\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"\n />\n </svg>\n }\n </div>\n </div>\n </cdk-virtual-scroll-viewport>\n}\n", styles: [":host{display:block}.wm-cb-viewport{width:100%}.wm-cb-option{display:flex;align-items:center;justify-content:space-between;gap:.5rem;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);-webkit-user-select:none;user-select:none}.wm-cb-option:hover:not(.is-disabled):not(.is-highlighted){background:var(--wm-bg-active)}.wm-cb-option.is-highlighted{background:color-mix(in srgb,var(--wm-color-accent) 15%,transparent)}.wm-cb-option.is-selected{background:color-mix(in srgb,var(--wm-color-accent) 10%,transparent);color:var(--wm-color-accent-readable);font-weight:500}.wm-cb-option.is-disabled{opacity:.4;cursor:not-allowed}.wm-cb-option-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wm-cb-match{font-weight:700;color:var(--wm-color-accent-readable)}.wm-cb-check{flex-shrink:0;color:var(--wm-color-accent-readable)}.wm-cb-empty{padding:.75rem .625rem;color:var(--wm-text-muted);font-size:.875rem;text-align:center}.wm-cb-loading{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.75rem .625rem;color:var(--wm-text-muted);font-size:.875rem}.wm-cb-spinner{animation:wm-cb-spin .8s linear infinite}@keyframes wm-cb-spin{to{transform:rotate(360deg)}}.wm-cb-loading-text{color:var(--wm-text-muted)}\n"], dependencies: [{ kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i1.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
972
971
|
}
|
|
973
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
972
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: ComboboxPanel, decorators: [{
|
|
974
973
|
type: Component,
|
|
975
974
|
args: [{ selector: 'wm-combobox-panel', imports: [ScrollingModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (loading()) {\n <div class=\"wm-cb-loading\" aria-live=\"polite\">\n <svg\n class=\"wm-cb-spinner\"\n width=\"20\" height=\"20\" viewBox=\"0 0 20 20\"\n fill=\"none\" aria-hidden=\"true\"\n >\n <circle\n cx=\"10\" cy=\"10\" r=\"8\"\n stroke=\"currentColor\" stroke-width=\"2\"\n stroke-dasharray=\"40 60\"\n stroke-linecap=\"round\"\n />\n </svg>\n <span class=\"wm-cb-loading-text\">Loading\u2026</span>\n </div>\n} @else if (showEmpty()) {\n <div class=\"wm-cb-empty\" aria-live=\"polite\">{{ emptyText() }}</div>\n} @else {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"itemHeight()\"\n [style.height.px]=\"viewportHeight()\"\n class=\"wm-cb-viewport\"\n >\n <div\n [id]=\"listboxId\"\n role=\"listbox\"\n [attr.aria-multiselectable]=\"multiple() ? true : null\"\n >\n <div\n *cdkVirtualFor=\"let opt of options(); let i = index\"\n role=\"option\"\n class=\"wm-cb-option\"\n [id]=\"optionIdAt(i)\"\n [class.is-highlighted]=\"i === highlightIndex()\"\n [class.is-selected]=\"isSelected(opt.value)\"\n [class.is-disabled]=\"!!opt.disabled\"\n [attr.aria-selected]=\"isSelected(opt.value)\"\n [attr.aria-disabled]=\"opt.disabled ? true : null\"\n (mousedown)=\"onOptionMousedown($event, opt, i)\"\n >\n <span class=\"wm-cb-option-label\">\n @for (seg of segmentsAt(i); track $index) {\n @if (seg.match) {\n <b class=\"wm-cb-match\">{{ seg.text }}</b>\n } @else {\n {{ seg.text }}\n }\n }\n </span>\n @if (isSelected(opt.value)) {\n <svg\n class=\"wm-cb-check\"\n width=\"14\" height=\"14\" viewBox=\"0 0 24 24\"\n fill=\"none\" aria-hidden=\"true\"\n >\n <polyline\n points=\"20 6 9 17 4 12\"\n stroke=\"currentColor\" stroke-width=\"2.5\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\"\n />\n </svg>\n }\n </div>\n </div>\n </cdk-virtual-scroll-viewport>\n}\n", styles: [":host{display:block}.wm-cb-viewport{width:100%}.wm-cb-option{display:flex;align-items:center;justify-content:space-between;gap:.5rem;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);-webkit-user-select:none;user-select:none}.wm-cb-option:hover:not(.is-disabled):not(.is-highlighted){background:var(--wm-bg-active)}.wm-cb-option.is-highlighted{background:color-mix(in srgb,var(--wm-color-accent) 15%,transparent)}.wm-cb-option.is-selected{background:color-mix(in srgb,var(--wm-color-accent) 10%,transparent);color:var(--wm-color-accent-readable);font-weight:500}.wm-cb-option.is-disabled{opacity:.4;cursor:not-allowed}.wm-cb-option-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wm-cb-match{font-weight:700;color:var(--wm-color-accent-readable)}.wm-cb-check{flex-shrink:0;color:var(--wm-color-accent-readable)}.wm-cb-empty{padding:.75rem .625rem;color:var(--wm-text-muted);font-size:.875rem;text-align:center}.wm-cb-loading{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.75rem .625rem;color:var(--wm-text-muted);font-size:.875rem}.wm-cb-spinner{animation:wm-cb-spin .8s linear infinite}@keyframes wm-cb-spin{to{transform:rotate(360deg)}}.wm-cb-loading-text{color:var(--wm-text-muted)}\n"] }]
|
|
976
975
|
}], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], highlightIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlightIndex", required: false }] }], selectedValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedValues", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], itemHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemHeight", required: false }] }], maxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxHeight", required: false }] }], filterQuery: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterQuery", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], freeformHint: [{ type: i0.Input, args: [{ isSignal: true, alias: "freeformHint", required: false }] }], optionClicked: [{ type: i0.Output, args: ["optionClicked"] }], viewport: [{
|
|
@@ -1014,17 +1013,17 @@ class WmCombobox {
|
|
|
1014
1013
|
scrollStrategy = new WmAnchoredScrollStrategy();
|
|
1015
1014
|
// ── Public inputs ──────────────────────────────────────────────────────
|
|
1016
1015
|
/** Full option list (before filtering). */
|
|
1017
|
-
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
|
|
1016
|
+
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
1018
1017
|
/** Selected value (single-select). Two-way bindable. */
|
|
1019
|
-
value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
1018
|
+
value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
1020
1019
|
/** Selected values (multi-select). Two-way bindable. */
|
|
1021
|
-
values = model([], ...(ngDevMode ? [{ debugName: "values" }] : []));
|
|
1020
|
+
values = model([], ...(ngDevMode ? [{ debugName: "values" }] : /* istanbul ignore next */ []));
|
|
1022
1021
|
/** Enable multi-select mode with chips. */
|
|
1023
|
-
multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : []));
|
|
1022
|
+
multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
|
|
1024
1023
|
/** Allow typed text to be accepted as a freeform value. */
|
|
1025
|
-
allowFreeform = input(false, ...(ngDevMode ? [{ debugName: "allowFreeform" }] : []));
|
|
1024
|
+
allowFreeform = input(false, ...(ngDevMode ? [{ debugName: "allowFreeform" }] : /* istanbul ignore next */ []));
|
|
1026
1025
|
/** Placeholder text for the input. */
|
|
1027
|
-
placeholder = input('Search\u2026', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
|
|
1026
|
+
placeholder = input('Search\u2026', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
1028
1027
|
/**
|
|
1029
1028
|
* Accessible name for the combobox input.
|
|
1030
1029
|
*
|
|
@@ -1034,21 +1033,21 @@ class WmCombobox {
|
|
|
1034
1033
|
* so in multi-select mode there is otherwise no accessible name at all once
|
|
1035
1034
|
* the user picks anything.
|
|
1036
1035
|
*/
|
|
1037
|
-
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
1036
|
+
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
1038
1037
|
/**
|
|
1039
1038
|
* ID of a visible element that names this combobox. Prefer this over
|
|
1040
1039
|
* `ariaLabel` when a visible caption exists, so the accessible name matches
|
|
1041
1040
|
* the visible text (WCAG 2.5.3, Label in Name).
|
|
1042
1041
|
*/
|
|
1043
|
-
ariaLabelledby = input(null, ...(ngDevMode ? [{ debugName: "ariaLabelledby" }] : []));
|
|
1042
|
+
ariaLabelledby = input(null, ...(ngDevMode ? [{ debugName: "ariaLabelledby" }] : /* istanbul ignore next */ []));
|
|
1044
1043
|
/** Disable the combobox. */
|
|
1045
|
-
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
1044
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
1046
1045
|
/** Custom async filter function. Overrides default substring matching. */
|
|
1047
|
-
filterFn = input(null, ...(ngDevMode ? [{ debugName: "filterFn" }] : []));
|
|
1046
|
+
filterFn = input(null, ...(ngDevMode ? [{ debugName: "filterFn" }] : /* istanbul ignore next */ []));
|
|
1048
1047
|
/** Pixel height of each option row. */
|
|
1049
|
-
itemHeight = input(36, ...(ngDevMode ? [{ debugName: "itemHeight" }] : []));
|
|
1048
|
+
itemHeight = input(36, ...(ngDevMode ? [{ debugName: "itemHeight" }] : /* istanbul ignore next */ []));
|
|
1050
1049
|
/** Max panel height in pixels. */
|
|
1051
|
-
maxPanelHeight = input(256, ...(ngDevMode ? [{ debugName: "maxPanelHeight" }] : []));
|
|
1050
|
+
maxPanelHeight = input(256, ...(ngDevMode ? [{ debugName: "maxPanelHeight" }] : /* istanbul ignore next */ []));
|
|
1052
1051
|
// ── Public outputs ─────────────────────────────────────────────────────
|
|
1053
1052
|
/** Emitted when the input text changes. */
|
|
1054
1053
|
query = output();
|
|
@@ -1057,14 +1056,14 @@ class WmCombobox {
|
|
|
1057
1056
|
/** Emitted when the panel closes. */
|
|
1058
1057
|
closed = output();
|
|
1059
1058
|
// ── View children ──────────────────────────────────────────────────────
|
|
1060
|
-
inputRef = viewChild('inputEl', ...(ngDevMode ? [{ debugName: "inputRef" }] : []));
|
|
1061
|
-
panel = viewChild(ComboboxPanel, ...(ngDevMode ? [{ debugName: "panel" }] : []));
|
|
1059
|
+
inputRef = viewChild('inputEl', ...(ngDevMode ? [{ debugName: "inputRef" }] : /* istanbul ignore next */ []));
|
|
1060
|
+
panel = viewChild(ComboboxPanel, ...(ngDevMode ? [{ debugName: "panel" }] : /* istanbul ignore next */ []));
|
|
1062
1061
|
// ── Internal state ─────────────────────────────────────────────────────
|
|
1063
|
-
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
|
|
1064
|
-
inputText = signal('', ...(ngDevMode ? [{ debugName: "inputText" }] : []));
|
|
1065
|
-
highlightIndex = signal(-1, ...(ngDevMode ? [{ debugName: "highlightIndex" }] : []));
|
|
1066
|
-
asyncLoading = signal(false, ...(ngDevMode ? [{ debugName: "asyncLoading" }] : []));
|
|
1067
|
-
asyncResults = signal(null, ...(ngDevMode ? [{ debugName: "asyncResults" }] : []));
|
|
1062
|
+
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
1063
|
+
inputText = signal('', ...(ngDevMode ? [{ debugName: "inputText" }] : /* istanbul ignore next */ []));
|
|
1064
|
+
highlightIndex = signal(-1, ...(ngDevMode ? [{ debugName: "highlightIndex" }] : /* istanbul ignore next */ []));
|
|
1065
|
+
asyncLoading = signal(false, ...(ngDevMode ? [{ debugName: "asyncLoading" }] : /* istanbul ignore next */ []));
|
|
1066
|
+
asyncResults = signal(null, ...(ngDevMode ? [{ debugName: "asyncResults" }] : /* istanbul ignore next */ []));
|
|
1068
1067
|
/** Text the input had when the panel opened — restored on Escape. */
|
|
1069
1068
|
savedText = '';
|
|
1070
1069
|
hostEl = inject((ElementRef));
|
|
@@ -1075,7 +1074,7 @@ class WmCombobox {
|
|
|
1075
1074
|
filterSubject = new Subject();
|
|
1076
1075
|
filterSub = null;
|
|
1077
1076
|
// ── Live region debounce ───────────────────────────────────────────────
|
|
1078
|
-
liveText = signal('', ...(ngDevMode ? [{ debugName: "liveText" }] : []));
|
|
1077
|
+
liveText = signal('', ...(ngDevMode ? [{ debugName: "liveText" }] : /* istanbul ignore next */ []));
|
|
1079
1078
|
liveTimer = null;
|
|
1080
1079
|
// ── Computed ───────────────────────────────────────────────────────────
|
|
1081
1080
|
/** Set of currently selected values for the panel. */
|
|
@@ -1085,7 +1084,7 @@ class WmCombobox {
|
|
|
1085
1084
|
}
|
|
1086
1085
|
const v = this.value();
|
|
1087
1086
|
return v != null ? new Set([v]) : new Set();
|
|
1088
|
-
}, ...(ngDevMode ? [{ debugName: "selectedValues" }] : []));
|
|
1087
|
+
}, ...(ngDevMode ? [{ debugName: "selectedValues" }] : /* istanbul ignore next */ []));
|
|
1089
1088
|
/** Filtered options shown in the panel. */
|
|
1090
1089
|
filteredOptions = computed(() => {
|
|
1091
1090
|
// If async filterFn is set and we have results, use those.
|
|
@@ -1098,7 +1097,7 @@ class WmCombobox {
|
|
|
1098
1097
|
if (!query)
|
|
1099
1098
|
return opts;
|
|
1100
1099
|
return opts.filter(o => o.label.toLowerCase().includes(query));
|
|
1101
|
-
}, ...(ngDevMode ? [{ debugName: "filteredOptions" }] : []));
|
|
1100
|
+
}, ...(ngDevMode ? [{ debugName: "filteredOptions" }] : /* istanbul ignore next */ []));
|
|
1102
1101
|
/** Chips for multi-select mode. */
|
|
1103
1102
|
chips = computed(() => {
|
|
1104
1103
|
if (!this.multiple())
|
|
@@ -1109,7 +1108,7 @@ class WmCombobox {
|
|
|
1109
1108
|
const opt = opts.find(o => o.value === v);
|
|
1110
1109
|
return { value: v, label: opt?.label ?? String(v) };
|
|
1111
1110
|
});
|
|
1112
|
-
}, ...(ngDevMode ? [{ debugName: "chips" }] : []));
|
|
1111
|
+
}, ...(ngDevMode ? [{ debugName: "chips" }] : /* istanbul ignore next */ []));
|
|
1113
1112
|
/** The aria-activedescendant value. */
|
|
1114
1113
|
activeDescendant = computed(() => {
|
|
1115
1114
|
const idx = this.highlightIndex();
|
|
@@ -1117,19 +1116,19 @@ class WmCombobox {
|
|
|
1117
1116
|
if (idx < 0 || !p)
|
|
1118
1117
|
return null;
|
|
1119
1118
|
return p.optionIdAt(idx) || null;
|
|
1120
|
-
}, ...(ngDevMode ? [{ debugName: "activeDescendant" }] : []));
|
|
1119
|
+
}, ...(ngDevMode ? [{ debugName: "activeDescendant" }] : /* istanbul ignore next */ []));
|
|
1121
1120
|
/** The listbox ID from the panel (for aria-controls). */
|
|
1122
1121
|
panelListboxId = computed(() => {
|
|
1123
1122
|
const p = this.panel();
|
|
1124
1123
|
return p ? p.listboxId : null;
|
|
1125
|
-
}, ...(ngDevMode ? [{ debugName: "panelListboxId" }] : []));
|
|
1124
|
+
}, ...(ngDevMode ? [{ debugName: "panelListboxId" }] : /* istanbul ignore next */ []));
|
|
1126
1125
|
/** Freeform hint for empty state. */
|
|
1127
1126
|
freeformHint = computed(() => {
|
|
1128
1127
|
if (!this.allowFreeform())
|
|
1129
1128
|
return '';
|
|
1130
1129
|
const text = this.inputText().trim();
|
|
1131
1130
|
return text ? `Press Enter to add "${text}"` : '';
|
|
1132
|
-
}, ...(ngDevMode ? [{ debugName: "freeformHint" }] : []));
|
|
1131
|
+
}, ...(ngDevMode ? [{ debugName: "freeformHint" }] : /* istanbul ignore next */ []));
|
|
1133
1132
|
/** Overlay width tracks host element width. */
|
|
1134
1133
|
get overlayWidth() {
|
|
1135
1134
|
return this.hostEl.nativeElement.offsetWidth || 200;
|
|
@@ -1520,8 +1519,8 @@ class WmCombobox {
|
|
|
1520
1519
|
const opt = this.options().find(o => o.value === v);
|
|
1521
1520
|
this.inputText.set(opt?.label ?? (typeof v === 'string' ? v : ''));
|
|
1522
1521
|
}
|
|
1523
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1524
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
1522
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmCombobox, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1523
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.23", 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: [
|
|
1525
1524
|
{
|
|
1526
1525
|
provide: NG_VALUE_ACCESSOR,
|
|
1527
1526
|
useExisting: forwardRef(() => WmCombobox),
|
|
@@ -1529,7 +1528,7 @@ class WmCombobox {
|
|
|
1529
1528
|
},
|
|
1530
1529
|
], 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 [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\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 });
|
|
1531
1530
|
}
|
|
1532
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1531
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmCombobox, decorators: [{
|
|
1533
1532
|
type: Component,
|
|
1534
1533
|
args: [{ selector: 'wm-combobox', imports: [CdkConnectedOverlay, CdkOverlayOrigin, ComboboxPanel], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
1535
1534
|
{
|
|
@@ -1552,7 +1551,7 @@ let nextId$1 = 0;
|
|
|
1552
1551
|
* Custom duration via show(message, type, durationMs).
|
|
1553
1552
|
*/
|
|
1554
1553
|
class WmToastService {
|
|
1555
|
-
toasts = signal([], ...(ngDevMode ? [{ debugName: "toasts" }] : []));
|
|
1554
|
+
toasts = signal([], ...(ngDevMode ? [{ debugName: "toasts" }] : /* istanbul ignore next */ []));
|
|
1556
1555
|
show(message, type = 'info', duration) {
|
|
1557
1556
|
const id = ++nextId$1;
|
|
1558
1557
|
this.toasts.update(list => [...list, { id, message, type }]);
|
|
@@ -1582,10 +1581,10 @@ class WmToastService {
|
|
|
1582
1581
|
dismiss(id) {
|
|
1583
1582
|
this.toasts.update(list => list.filter(t => t.id !== id));
|
|
1584
1583
|
}
|
|
1585
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1586
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
1584
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1585
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmToastService, providedIn: 'root' });
|
|
1587
1586
|
}
|
|
1588
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1587
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmToastService, decorators: [{
|
|
1589
1588
|
type: Injectable,
|
|
1590
1589
|
args: [{ providedIn: 'root' }]
|
|
1591
1590
|
}] });
|
|
@@ -1604,7 +1603,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
|
|
|
1604
1603
|
class WmToastContainer {
|
|
1605
1604
|
toastService = inject(WmToastService);
|
|
1606
1605
|
/** Tick signal that updates every second — drives the elapsed time display. */
|
|
1607
|
-
tick = signal(Date.now(), ...(ngDevMode ? [{ debugName: "tick" }] : []));
|
|
1606
|
+
tick = signal(Date.now(), ...(ngDevMode ? [{ debugName: "tick" }] : /* istanbul ignore next */ []));
|
|
1608
1607
|
tickInterval = setInterval(() => {
|
|
1609
1608
|
// Only tick when there are progress toasts with createdAt
|
|
1610
1609
|
if (this.toastService.toasts().some(t => t.type === 'progress' && t.createdAt)) {
|
|
@@ -1633,10 +1632,10 @@ class WmToastContainer {
|
|
|
1633
1632
|
const secs = diff % 60;
|
|
1634
1633
|
return `${mins}m ${secs.toString().padStart(2, '0')}s`;
|
|
1635
1634
|
}
|
|
1636
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1637
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
1635
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmToastContainer, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1636
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.23", type: WmToastContainer, isStandalone: true, selector: "wm-toast-container", ngImport: i0, template: "<div class=\"wm-toast-container\" role=\"log\" aria-live=\"polite\" aria-label=\"Notifications\">\n @for (toast of toastService.toasts(); track toast.id) {\n <div [class]=\"typeClass(toast)\" role=\"status\">\n <!-- Success icon (check-circle) -->\n @if (toast.type === 'success') {\n <svg class=\"wm-toast-icon\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\"\n fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"/>\n <polyline points=\"22 4 12 14.01 9 11.01\"/>\n </svg>\n }\n <!-- Error icon (x-circle) -->\n @if (toast.type === 'error') {\n <svg class=\"wm-toast-icon\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\"\n fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\n <line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"/>\n <line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"/>\n </svg>\n }\n <!-- Info icon -->\n @if (toast.type === 'info') {\n <svg class=\"wm-toast-icon\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\"\n fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\n <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"/>\n </svg>\n }\n <!-- Progress spinner -->\n @if (toast.type === 'progress') {\n <span class=\"wm-toast-spinner\" aria-hidden=\"true\"></span>\n }\n\n <span class=\"wm-toast-message\">\n {{ toast.message }}\n @if (toast.type === 'progress' && toast.createdAt) {\n <span class=\"wm-toast-elapsed\"> ({{ elapsed(toast.createdAt) }})</span>\n }\n </span>\n\n <!-- Cancel button for progress toasts with an onCancel callback -->\n @if (toast.type === 'progress' && toast.onCancel) {\n <button class=\"wm-toast-cancel\" (click)=\"cancel(toast)\" aria-label=\"Cancel operation\">Cancel</button>\n }\n\n <!-- Dismiss button \u2014 always shown -->\n <button class=\"wm-toast-dismiss\" (click)=\"dismiss(toast.id)\" aria-label=\"Dismiss notification\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\"\n fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n 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>\n", styles: [".wm-toast-container{position:fixed;bottom:1rem;right:1rem;display:flex;flex-direction:column;gap:.5rem;z-index:9999;pointer-events:none}.wm-toast{display:flex;align-items:flex-start;gap:.625rem;padding:.625rem .875rem;border-radius:var(--wm-radius-sm, 4px);box-shadow:var(--wm-shadow-md, 0 4px 12px rgba(0,0,0,.25));font-size:.8125rem;line-height:1.4;min-width:220px;max-width:360px;pointer-events:auto;animation:wm-toast-slide-in .15s ease-out both}.wm-toast--success{background:var(--wm-color-success-bg);color:var(--wm-color-success-readable);border:1px solid var(--wm-color-success-border)}.wm-toast--error{background:var(--wm-color-danger-bg);color:var(--wm-color-danger-readable);border:1px solid var(--wm-color-danger-border)}.wm-toast--info{background:var(--wm-bg-raised);color:var(--wm-text-primary);border:1px solid var(--wm-border)}.wm-toast--progress{background:var(--wm-bg-raised);color:var(--wm-text-primary);border:1px solid var(--wm-color-accent-border)}.wm-toast-icon{flex-shrink:0;margin-top:1px}.wm-toast-message{flex:1;line-height:1.4}.wm-toast-dismiss{flex-shrink:0;background:none;border:none;color:inherit;opacity:.6;cursor:pointer;padding:0;margin-left:.25rem;transition:opacity .15s ease}.wm-toast-dismiss:hover{opacity:1}.wm-toast-spinner{width:14px;height:14px;border:2px solid color-mix(in srgb,var(--wm-color-accent) 30%,transparent);border-top-color:var(--wm-color-accent-readable);border-radius:50%;flex-shrink:0;margin-top:1px;animation:wm-toast-spin .7s linear infinite}.wm-toast-elapsed{opacity:.6;font-size:.75rem;font-variant-numeric:tabular-nums}.wm-toast-cancel{flex-shrink:0;background:none;border:1px solid color-mix(in srgb,currentColor 30%,transparent);border-radius:var(--wm-radius-sm, 4px);color:inherit;opacity:.7;cursor:pointer;padding:.125rem .5rem;font-size:.75rem;transition:opacity .15s ease,border-color .15s ease}.wm-toast-cancel:hover{opacity:1;border-color:currentColor}@keyframes wm-toast-spin{to{transform:rotate(360deg)}}@keyframes wm-toast-slide-in{0%{opacity:0;transform:translate(1rem)}to{opacity:1;transform:translate(0)}}@media(prefers-reduced-motion:reduce){.wm-toast{animation:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1638
1637
|
}
|
|
1639
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1638
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmToastContainer, decorators: [{
|
|
1640
1639
|
type: Component,
|
|
1641
1640
|
args: [{ selector: 'wm-toast-container', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"wm-toast-container\" role=\"log\" aria-live=\"polite\" aria-label=\"Notifications\">\n @for (toast of toastService.toasts(); track toast.id) {\n <div [class]=\"typeClass(toast)\" role=\"status\">\n <!-- Success icon (check-circle) -->\n @if (toast.type === 'success') {\n <svg class=\"wm-toast-icon\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\"\n fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"/>\n <polyline points=\"22 4 12 14.01 9 11.01\"/>\n </svg>\n }\n <!-- Error icon (x-circle) -->\n @if (toast.type === 'error') {\n <svg class=\"wm-toast-icon\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\"\n fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\n <line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"/>\n <line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"/>\n </svg>\n }\n <!-- Info icon -->\n @if (toast.type === 'info') {\n <svg class=\"wm-toast-icon\" width=\"15\" height=\"15\" viewBox=\"0 0 24 24\"\n fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"/>\n <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"/>\n <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"/>\n </svg>\n }\n <!-- Progress spinner -->\n @if (toast.type === 'progress') {\n <span class=\"wm-toast-spinner\" aria-hidden=\"true\"></span>\n }\n\n <span class=\"wm-toast-message\">\n {{ toast.message }}\n @if (toast.type === 'progress' && toast.createdAt) {\n <span class=\"wm-toast-elapsed\"> ({{ elapsed(toast.createdAt) }})</span>\n }\n </span>\n\n <!-- Cancel button for progress toasts with an onCancel callback -->\n @if (toast.type === 'progress' && toast.onCancel) {\n <button class=\"wm-toast-cancel\" (click)=\"cancel(toast)\" aria-label=\"Cancel operation\">Cancel</button>\n }\n\n <!-- Dismiss button \u2014 always shown -->\n <button class=\"wm-toast-dismiss\" (click)=\"dismiss(toast.id)\" aria-label=\"Dismiss notification\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\"\n fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\n 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>\n", styles: [".wm-toast-container{position:fixed;bottom:1rem;right:1rem;display:flex;flex-direction:column;gap:.5rem;z-index:9999;pointer-events:none}.wm-toast{display:flex;align-items:flex-start;gap:.625rem;padding:.625rem .875rem;border-radius:var(--wm-radius-sm, 4px);box-shadow:var(--wm-shadow-md, 0 4px 12px rgba(0,0,0,.25));font-size:.8125rem;line-height:1.4;min-width:220px;max-width:360px;pointer-events:auto;animation:wm-toast-slide-in .15s ease-out both}.wm-toast--success{background:var(--wm-color-success-bg);color:var(--wm-color-success-readable);border:1px solid var(--wm-color-success-border)}.wm-toast--error{background:var(--wm-color-danger-bg);color:var(--wm-color-danger-readable);border:1px solid var(--wm-color-danger-border)}.wm-toast--info{background:var(--wm-bg-raised);color:var(--wm-text-primary);border:1px solid var(--wm-border)}.wm-toast--progress{background:var(--wm-bg-raised);color:var(--wm-text-primary);border:1px solid var(--wm-color-accent-border)}.wm-toast-icon{flex-shrink:0;margin-top:1px}.wm-toast-message{flex:1;line-height:1.4}.wm-toast-dismiss{flex-shrink:0;background:none;border:none;color:inherit;opacity:.6;cursor:pointer;padding:0;margin-left:.25rem;transition:opacity .15s ease}.wm-toast-dismiss:hover{opacity:1}.wm-toast-spinner{width:14px;height:14px;border:2px solid color-mix(in srgb,var(--wm-color-accent) 30%,transparent);border-top-color:var(--wm-color-accent-readable);border-radius:50%;flex-shrink:0;margin-top:1px;animation:wm-toast-spin .7s linear infinite}.wm-toast-elapsed{opacity:.6;font-size:.75rem;font-variant-numeric:tabular-nums}.wm-toast-cancel{flex-shrink:0;background:none;border:1px solid color-mix(in srgb,currentColor 30%,transparent);border-radius:var(--wm-radius-sm, 4px);color:inherit;opacity:.7;cursor:pointer;padding:.125rem .5rem;font-size:.75rem;transition:opacity .15s ease,border-color .15s ease}.wm-toast-cancel:hover{opacity:1;border-color:currentColor}@keyframes wm-toast-spin{to{transform:rotate(360deg)}}@keyframes wm-toast-slide-in{0%{opacity:0;transform:translate(1rem)}to{opacity:1;transform:translate(0)}}@media(prefers-reduced-motion:reduce){.wm-toast{animation:none}}\n"] }]
|
|
1642
1641
|
}] });
|
|
@@ -1656,9 +1655,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
|
|
|
1656
1655
|
*/
|
|
1657
1656
|
class WmTooltipPanel {
|
|
1658
1657
|
/** Tooltip body. Newlines are preserved — see `white-space` in tooltip.css. */
|
|
1659
|
-
text = input('', ...(ngDevMode ? [{ debugName: "text" }] : []));
|
|
1658
|
+
text = input('', ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
|
|
1660
1659
|
/** Id the host points at with aria-describedby / aria-labelledby. */
|
|
1661
|
-
panelId = input('', ...(ngDevMode ? [{ debugName: "panelId" }] : []));
|
|
1660
|
+
panelId = input('', ...(ngDevMode ? [{ debugName: "panelId" }] : /* istanbul ignore next */ []));
|
|
1662
1661
|
/**
|
|
1663
1662
|
* Drives the enter transition.
|
|
1664
1663
|
*
|
|
@@ -1666,23 +1665,23 @@ class WmTooltipPanel {
|
|
|
1666
1665
|
* fade has two states to move between. Attaching straight to the visible
|
|
1667
1666
|
* state would give the browser nothing to interpolate from.
|
|
1668
1667
|
*/
|
|
1669
|
-
visible = input(false, ...(ngDevMode ? [{ debugName: "visible" }] : []));
|
|
1670
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1671
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.
|
|
1668
|
+
visible = input(false, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
1669
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmTooltipPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1670
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.23", type: WmTooltipPanel, isStandalone: true, selector: "wm-tooltip-panel", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: false, transformFunction: null }, panelId: { classPropertyName: "panelId", publicName: "panelId", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `<div
|
|
1672
1671
|
class="wm-tooltip-panel"
|
|
1673
1672
|
[class.wm-tooltip-panel--visible]="visible()"
|
|
1674
1673
|
[id]="panelId()"
|
|
1675
1674
|
role="tooltip"
|
|
1676
|
-
>{{ text() }}</div>`, isInline: true, styles: [".wm-tooltip-panel{max-width:var(--wm-tooltip-max-width, 260px);padding:6px 9px;background:var(--wm-text-primary);color:var(--wm-bg-base);border-radius:var(--wm-radius-md);box-shadow:var(--wm-shadow-md);font-family:var(--wm-font-sans);font-size:11.5px;font-weight:500;line-height:1.5;text-align:left;white-space:pre-line;overflow-wrap:break-word;opacity:0;transform:translateY(-2px);transition:opacity var(--wm-transition-fast),transform var(--wm-transition-fast)}.wm-tooltip-panel--visible{opacity:1;transform:translateY(0)}.wm-tooltip-above .wm-tooltip-panel{transform:translateY(2px)}.wm-tooltip-above .wm-tooltip-panel--visible{transform:translateY(0)}@media(prefers-reduced-motion:reduce){.wm-tooltip-panel,.wm-tooltip-above .wm-tooltip-panel{transition:none;transform:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1675
|
+
>{{ text() }}</div>`, isInline: true, styles: [".wm-tooltip-panel{max-width:var(--wm-tooltip-max-width, 260px);padding:6px 9px;background:var(--wm-text-primary);color:var(--wm-bg-base);border-radius:var(--wm-radius-md);box-shadow:var(--wm-shadow-md);font-family:var(--wm-font-sans);font-size:11.5px;font-weight:500;line-height:1.5;text-align:left;white-space:pre-line;overflow-wrap:break-word;opacity:0;transform:translateY(-2px);transition:opacity var(--wm-transition-fast),transform var(--wm-transition-fast)}.wm-tooltip-panel--visible{opacity:1;transform:translateY(0)}.wm-rich-tooltip-panel{max-width:var(--wm-rich-tooltip-max-width, 320px);white-space:normal}.wm-tooltip-above .wm-tooltip-panel{transform:translateY(2px)}.wm-tooltip-above .wm-tooltip-panel--visible{transform:translateY(0)}@media(prefers-reduced-motion:reduce){.wm-tooltip-panel,.wm-tooltip-above .wm-tooltip-panel{transition:none;transform:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1677
1676
|
}
|
|
1678
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1677
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmTooltipPanel, decorators: [{
|
|
1679
1678
|
type: Component,
|
|
1680
1679
|
args: [{ selector: 'wm-tooltip-panel', template: `<div
|
|
1681
1680
|
class="wm-tooltip-panel"
|
|
1682
1681
|
[class.wm-tooltip-panel--visible]="visible()"
|
|
1683
1682
|
[id]="panelId()"
|
|
1684
1683
|
role="tooltip"
|
|
1685
|
-
>{{ text() }}</div>`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, styles: [".wm-tooltip-panel{max-width:var(--wm-tooltip-max-width, 260px);padding:6px 9px;background:var(--wm-text-primary);color:var(--wm-bg-base);border-radius:var(--wm-radius-md);box-shadow:var(--wm-shadow-md);font-family:var(--wm-font-sans);font-size:11.5px;font-weight:500;line-height:1.5;text-align:left;white-space:pre-line;overflow-wrap:break-word;opacity:0;transform:translateY(-2px);transition:opacity var(--wm-transition-fast),transform var(--wm-transition-fast)}.wm-tooltip-panel--visible{opacity:1;transform:translateY(0)}.wm-tooltip-above .wm-tooltip-panel{transform:translateY(2px)}.wm-tooltip-above .wm-tooltip-panel--visible{transform:translateY(0)}@media(prefers-reduced-motion:reduce){.wm-tooltip-panel,.wm-tooltip-above .wm-tooltip-panel{transition:none;transform:none}}\n"] }]
|
|
1684
|
+
>{{ text() }}</div>`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, styles: [".wm-tooltip-panel{max-width:var(--wm-tooltip-max-width, 260px);padding:6px 9px;background:var(--wm-text-primary);color:var(--wm-bg-base);border-radius:var(--wm-radius-md);box-shadow:var(--wm-shadow-md);font-family:var(--wm-font-sans);font-size:11.5px;font-weight:500;line-height:1.5;text-align:left;white-space:pre-line;overflow-wrap:break-word;opacity:0;transform:translateY(-2px);transition:opacity var(--wm-transition-fast),transform var(--wm-transition-fast)}.wm-tooltip-panel--visible{opacity:1;transform:translateY(0)}.wm-rich-tooltip-panel{max-width:var(--wm-rich-tooltip-max-width, 320px);white-space:normal}.wm-tooltip-above .wm-tooltip-panel{transform:translateY(2px)}.wm-tooltip-above .wm-tooltip-panel--visible{transform:translateY(0)}@media(prefers-reduced-motion:reduce){.wm-tooltip-panel,.wm-tooltip-above .wm-tooltip-panel{transition:none;transform:none}}\n"] }]
|
|
1686
1685
|
}], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: false }] }], panelId: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelId", required: false }] }], visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }] } });
|
|
1687
1686
|
|
|
1688
1687
|
/**
|
|
@@ -1731,7 +1730,7 @@ function withoutIdToken(value, id) {
|
|
|
1731
1730
|
}
|
|
1732
1731
|
|
|
1733
1732
|
/** Grace period before a pointer leaving the host closes the tooltip. */
|
|
1734
|
-
const HIDE_DELAY_MS = 120;
|
|
1733
|
+
const HIDE_DELAY_MS$1 = 120;
|
|
1735
1734
|
let nextId = 0;
|
|
1736
1735
|
/**
|
|
1737
1736
|
* WmTooltip — accessible floating explanation for any element.
|
|
@@ -1771,21 +1770,21 @@ let nextId = 0;
|
|
|
1771
1770
|
*/
|
|
1772
1771
|
class WmTooltip {
|
|
1773
1772
|
/** Tooltip body. Blank or absent means the tooltip never opens. */
|
|
1774
|
-
wmTooltip = input('', ...(ngDevMode ? [{ debugName: "wmTooltip" }] : []));
|
|
1773
|
+
wmTooltip = input('', ...(ngDevMode ? [{ debugName: "wmTooltip" }] : /* istanbul ignore next */ []));
|
|
1775
1774
|
/** Preferred side. Flips automatically when the viewport has no room. */
|
|
1776
|
-
wmTooltipPosition = input('bottom', ...(ngDevMode ? [{ debugName: "wmTooltipPosition" }] : []));
|
|
1775
|
+
wmTooltipPosition = input('bottom', ...(ngDevMode ? [{ debugName: "wmTooltipPosition" }] : /* istanbul ignore next */ []));
|
|
1777
1776
|
/** Milliseconds a pointer must rest on the host before the panel opens. */
|
|
1778
|
-
wmTooltipDelay = input(250, ...(ngDevMode ? [{ debugName: "wmTooltipDelay" }] : []));
|
|
1777
|
+
wmTooltipDelay = input(250, ...(ngDevMode ? [{ debugName: "wmTooltipDelay" }] : /* istanbul ignore next */ []));
|
|
1779
1778
|
/** Suppress the tooltip without unbinding it — for a control whose explanation only applies in some states. */
|
|
1780
|
-
wmTooltipDisabled = input(false, ...(ngDevMode ? [{ debugName: "wmTooltipDisabled" }] : []));
|
|
1779
|
+
wmTooltipDisabled = input(false, ...(ngDevMode ? [{ debugName: "wmTooltipDisabled" }] : /* istanbul ignore next */ []));
|
|
1781
1780
|
/** Whether the panel describes the host or names it. See WmTooltipRelation. */
|
|
1782
|
-
wmTooltipRelation = input('description', ...(ngDevMode ? [{ debugName: "wmTooltipRelation" }] : []));
|
|
1781
|
+
wmTooltipRelation = input('description', ...(ngDevMode ? [{ debugName: "wmTooltipRelation" }] : /* istanbul ignore next */ []));
|
|
1783
1782
|
/**
|
|
1784
1783
|
* Make a non-focusable host a tab stop so a keyboard user can reach the
|
|
1785
1784
|
* tooltip. Only applied when the host is not already focusable, and never
|
|
1786
1785
|
* safe inside a roving-tabindex container — see the class comment.
|
|
1787
1786
|
*/
|
|
1788
|
-
wmTooltipFocusable = input(false, ...(ngDevMode ? [{ debugName: "wmTooltipFocusable" }] : []));
|
|
1787
|
+
wmTooltipFocusable = input(false, ...(ngDevMode ? [{ debugName: "wmTooltipFocusable" }] : /* istanbul ignore next */ []));
|
|
1789
1788
|
host = inject(ElementRef).nativeElement;
|
|
1790
1789
|
injector = inject(Injector);
|
|
1791
1790
|
renderer = inject(Renderer2);
|
|
@@ -1919,7 +1918,7 @@ class WmTooltip {
|
|
|
1919
1918
|
if (this.pointerOnHost || this.pointerOnPanel || this.hostFocused)
|
|
1920
1919
|
return;
|
|
1921
1920
|
this.hideNow();
|
|
1922
|
-
}, HIDE_DELAY_MS);
|
|
1921
|
+
}, HIDE_DELAY_MS$1);
|
|
1923
1922
|
}
|
|
1924
1923
|
clearTimer(which) {
|
|
1925
1924
|
const timer = which === 'show' ? this.showTimer : this.hideTimer;
|
|
@@ -2120,10 +2119,10 @@ class WmTooltip {
|
|
|
2120
2119
|
this.overlayRef = null;
|
|
2121
2120
|
this.portal = null;
|
|
2122
2121
|
}
|
|
2123
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2124
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.
|
|
2122
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmTooltip, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2123
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.23", type: WmTooltip, isStandalone: true, selector: "[wmTooltip]", inputs: { wmTooltip: { classPropertyName: "wmTooltip", publicName: "wmTooltip", isSignal: true, isRequired: false, transformFunction: null }, wmTooltipPosition: { classPropertyName: "wmTooltipPosition", publicName: "wmTooltipPosition", isSignal: true, isRequired: false, transformFunction: null }, wmTooltipDelay: { classPropertyName: "wmTooltipDelay", publicName: "wmTooltipDelay", isSignal: true, isRequired: false, transformFunction: null }, wmTooltipDisabled: { classPropertyName: "wmTooltipDisabled", publicName: "wmTooltipDisabled", isSignal: true, isRequired: false, transformFunction: null }, wmTooltipRelation: { classPropertyName: "wmTooltipRelation", publicName: "wmTooltipRelation", isSignal: true, isRequired: false, transformFunction: null }, wmTooltipFocusable: { classPropertyName: "wmTooltipFocusable", publicName: "wmTooltipFocusable", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "onPointerEnterHost()", "mouseleave": "onPointerLeaveHost()", "focusin": "onFocusHost()", "focusout": "onBlurHost()", "click": "hideNow()" } }, exportAs: ["wmTooltip"], ngImport: i0 });
|
|
2125
2124
|
}
|
|
2126
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2125
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmTooltip, decorators: [{
|
|
2127
2126
|
type: Directive,
|
|
2128
2127
|
args: [{
|
|
2129
2128
|
selector: '[wmTooltip]',
|
|
@@ -2138,139 +2137,472 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
|
|
|
2138
2137
|
}]
|
|
2139
2138
|
}], ctorParameters: () => [], propDecorators: { wmTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "wmTooltip", required: false }] }], wmTooltipPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "wmTooltipPosition", required: false }] }], wmTooltipDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "wmTooltipDelay", required: false }] }], wmTooltipDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "wmTooltipDisabled", required: false }] }], wmTooltipRelation: [{ type: i0.Input, args: [{ isSignal: true, alias: "wmTooltipRelation", required: false }] }], wmTooltipFocusable: [{ type: i0.Input, args: [{ isSignal: true, alias: "wmTooltipFocusable", required: false }] }] } });
|
|
2140
2139
|
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2140
|
+
/**
|
|
2141
|
+
* The floating surface a `wm-rich-tooltip` renders into.
|
|
2142
|
+
*
|
|
2143
|
+
* This is deliberately a separate panel from `WmTooltipPanel`: the latter's
|
|
2144
|
+
* text node owns `white-space: pre-line`, while this panel must leave the
|
|
2145
|
+
* projected template's markup and layout intact.
|
|
2146
|
+
*/
|
|
2147
|
+
class WmRichTooltipPanel {
|
|
2148
|
+
/** The caller-owned Angular template rendered as the tooltip body. */
|
|
2149
|
+
content = input(null, ...(ngDevMode ? [{ debugName: "content" }] : /* istanbul ignore next */ []));
|
|
2150
|
+
/** Id the trigger points at with aria-describedby / aria-labelledby. */
|
|
2151
|
+
panelId = input('', ...(ngDevMode ? [{ debugName: "panelId" }] : /* istanbul ignore next */ []));
|
|
2152
|
+
/** Drives the enter transition after the overlay has attached. */
|
|
2153
|
+
visible = input(false, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
2154
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmRichTooltipPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2155
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.23", type: WmRichTooltipPanel, isStandalone: true, selector: "wm-rich-tooltip-panel", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, panelId: { classPropertyName: "panelId", publicName: "panelId", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `<div
|
|
2156
|
+
class="wm-tooltip-panel wm-rich-tooltip-panel"
|
|
2157
|
+
[class.wm-tooltip-panel--visible]="visible()"
|
|
2158
|
+
[id]="panelId()"
|
|
2159
|
+
role="tooltip"
|
|
2160
|
+
>
|
|
2161
|
+
<ng-container [ngTemplateOutlet]="content()"></ng-container>
|
|
2162
|
+
</div>`, isInline: true, styles: [".wm-tooltip-panel{max-width:var(--wm-tooltip-max-width, 260px);padding:6px 9px;background:var(--wm-text-primary);color:var(--wm-bg-base);border-radius:var(--wm-radius-md);box-shadow:var(--wm-shadow-md);font-family:var(--wm-font-sans);font-size:11.5px;font-weight:500;line-height:1.5;text-align:left;white-space:pre-line;overflow-wrap:break-word;opacity:0;transform:translateY(-2px);transition:opacity var(--wm-transition-fast),transform var(--wm-transition-fast)}.wm-tooltip-panel--visible{opacity:1;transform:translateY(0)}.wm-rich-tooltip-panel{max-width:var(--wm-rich-tooltip-max-width, 320px);white-space:normal}.wm-tooltip-above .wm-tooltip-panel{transform:translateY(2px)}.wm-tooltip-above .wm-tooltip-panel--visible{transform:translateY(0)}@media(prefers-reduced-motion:reduce){.wm-tooltip-panel,.wm-tooltip-above .wm-tooltip-panel{transition:none;transform:none}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2163
|
+
}
|
|
2164
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmRichTooltipPanel, decorators: [{
|
|
2165
|
+
type: Component,
|
|
2166
|
+
args: [{ selector: 'wm-rich-tooltip-panel', imports: [NgTemplateOutlet], template: `<div
|
|
2167
|
+
class="wm-tooltip-panel wm-rich-tooltip-panel"
|
|
2168
|
+
[class.wm-tooltip-panel--visible]="visible()"
|
|
2169
|
+
[id]="panelId()"
|
|
2170
|
+
role="tooltip"
|
|
2171
|
+
>
|
|
2172
|
+
<ng-container [ngTemplateOutlet]="content()"></ng-container>
|
|
2173
|
+
</div>`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, styles: [".wm-tooltip-panel{max-width:var(--wm-tooltip-max-width, 260px);padding:6px 9px;background:var(--wm-text-primary);color:var(--wm-bg-base);border-radius:var(--wm-radius-md);box-shadow:var(--wm-shadow-md);font-family:var(--wm-font-sans);font-size:11.5px;font-weight:500;line-height:1.5;text-align:left;white-space:pre-line;overflow-wrap:break-word;opacity:0;transform:translateY(-2px);transition:opacity var(--wm-transition-fast),transform var(--wm-transition-fast)}.wm-tooltip-panel--visible{opacity:1;transform:translateY(0)}.wm-rich-tooltip-panel{max-width:var(--wm-rich-tooltip-max-width, 320px);white-space:normal}.wm-tooltip-above .wm-tooltip-panel{transform:translateY(2px)}.wm-tooltip-above .wm-tooltip-panel--visible{transform:translateY(0)}@media(prefers-reduced-motion:reduce){.wm-tooltip-panel,.wm-tooltip-above .wm-tooltip-panel{transition:none;transform:none}}\n"] }]
|
|
2174
|
+
}], propDecorators: { content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }], panelId: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelId", required: false }] }], visible: [{ type: i0.Input, args: [{ isSignal: true, alias: "visible", required: false }] }] } });
|
|
2175
|
+
|
|
2176
|
+
/** Marks the projected element that owns a rich tooltip. */
|
|
2177
|
+
class WmRichTooltipTrigger {
|
|
2178
|
+
elementRef = inject((ElementRef));
|
|
2179
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmRichTooltipTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2180
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.23", type: WmRichTooltipTrigger, isStandalone: true, selector: "[wmRichTooltipTrigger]", ngImport: i0 });
|
|
2181
|
+
}
|
|
2182
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmRichTooltipTrigger, decorators: [{
|
|
2183
|
+
type: Directive,
|
|
2184
|
+
args: [{
|
|
2185
|
+
selector: '[wmRichTooltipTrigger]',
|
|
2186
|
+
}]
|
|
2187
|
+
}] });
|
|
2188
|
+
/** Marks the projected Angular template used as a rich tooltip's body. */
|
|
2189
|
+
class WmRichTooltipContent {
|
|
2190
|
+
templateRef = inject((TemplateRef));
|
|
2191
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmRichTooltipContent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
2192
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.23", type: WmRichTooltipContent, isStandalone: true, selector: "ng-template[wmRichTooltipContent]", ngImport: i0 });
|
|
2193
|
+
}
|
|
2194
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmRichTooltipContent, decorators: [{
|
|
2195
|
+
type: Directive,
|
|
2196
|
+
args: [{
|
|
2197
|
+
selector: 'ng-template[wmRichTooltipContent]',
|
|
2198
|
+
}]
|
|
2199
|
+
}] });
|
|
2200
|
+
let nextRichTooltipId = 0;
|
|
2201
|
+
const HIDE_DELAY_MS = 120;
|
|
2202
|
+
/**
|
|
2203
|
+
* `wm-rich-tooltip` — a tooltip-shaped CDK overlay with projected Angular
|
|
2204
|
+
* template content.
|
|
2205
|
+
*
|
|
2206
|
+
* ```html
|
|
2207
|
+
* <wm-rich-tooltip position="top">
|
|
2208
|
+
* <span wmRichTooltipTrigger>feature/checkout</span>
|
|
2209
|
+
* <ng-template wmRichTooltipContent>
|
|
2210
|
+
* <strong>feature/checkout</strong>
|
|
2211
|
+
* <div class="legend-row">
|
|
2212
|
+
* <span class="swatch" aria-hidden="true"></span>
|
|
2213
|
+
* <span>Pull request linked</span>
|
|
2214
|
+
* </div>
|
|
2215
|
+
* </ng-template>
|
|
2216
|
+
* </wm-rich-tooltip>
|
|
2217
|
+
* ```
|
|
2218
|
+
*
|
|
2219
|
+
* The body is an Angular `TemplateRef`, not an HTML string. Consumers can use
|
|
2220
|
+
* normal Angular markup, bindings, loops, and components; callers should not
|
|
2221
|
+
* use this as a path for unsanitized user HTML. If a caller explicitly uses
|
|
2222
|
+
* Angular's `[innerHTML]`, Angular's normal sanitizer remains the boundary.
|
|
2223
|
+
*
|
|
2224
|
+
* The interaction contract matches `WmTooltip`: hover and keyboard focus,
|
|
2225
|
+
* Escape dismissal, a hoverable panel, scroll/resize re-anchoring, clipping
|
|
2226
|
+
* detection, and an `aria-describedby` relationship by default. Rich tooltip
|
|
2227
|
+
* content should remain non-interactive; use `WmPopover` for menus, links,
|
|
2228
|
+
* forms, or other content that needs focus and interaction.
|
|
2229
|
+
*/
|
|
2230
|
+
class WmRichTooltip {
|
|
2231
|
+
/** Preferred side. Flips automatically when the viewport has no room. */
|
|
2232
|
+
position = input('bottom', ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
|
|
2233
|
+
/** Milliseconds a pointer must rest on the trigger before opening. */
|
|
2234
|
+
delay = input(250, ...(ngDevMode ? [{ debugName: "delay" }] : /* istanbul ignore next */ []));
|
|
2235
|
+
/** Suppress the tooltip without removing its projected content. */
|
|
2236
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
2237
|
+
/** Whether the panel describes the trigger or names it. */
|
|
2238
|
+
relation = input('description', ...(ngDevMode ? [{ debugName: "relation" }] : /* istanbul ignore next */ []));
|
|
2239
|
+
/** Make a non-focusable projected trigger reachable by keyboard when needed. */
|
|
2240
|
+
focusable = input(false, ...(ngDevMode ? [{ debugName: "focusable" }] : /* istanbul ignore next */ []));
|
|
2241
|
+
injector = inject(Injector);
|
|
2242
|
+
renderer = inject(Renderer2);
|
|
2243
|
+
triggerQuery = contentChild(WmRichTooltipTrigger, ...(ngDevMode ? [{ debugName: "triggerQuery" }] : /* istanbul ignore next */ []));
|
|
2244
|
+
contentQuery = contentChild(WmRichTooltipContent, ...(ngDevMode ? [{ debugName: "contentQuery" }] : /* istanbul ignore next */ []));
|
|
2245
|
+
panelId = `wm-rich-tooltip-${nextRichTooltipId++}`;
|
|
2246
|
+
triggerElement = null;
|
|
2247
|
+
contentTemplate = null;
|
|
2248
|
+
triggerCleanups = [];
|
|
2249
|
+
addedTabIndex = false;
|
|
2250
|
+
overlayRef = null;
|
|
2251
|
+
panelRef = null;
|
|
2252
|
+
portal = null;
|
|
2253
|
+
positionChanges = null;
|
|
2254
|
+
showTimer = null;
|
|
2255
|
+
hideTimer = null;
|
|
2256
|
+
raiseFrame = null;
|
|
2257
|
+
pointerOnTrigger = false;
|
|
2258
|
+
pointerOnPanel = false;
|
|
2259
|
+
triggerFocused = false;
|
|
2260
|
+
detachDocumentListeners = null;
|
|
2261
|
+
clippingAncestors = [];
|
|
2262
|
+
constructor() {
|
|
2263
|
+
inject(DestroyRef).onDestroy(() => this.teardown());
|
|
2264
|
+
effect(() => {
|
|
2265
|
+
const trigger = this.triggerQuery();
|
|
2266
|
+
const content = this.contentQuery();
|
|
2267
|
+
const focusable = this.focusable();
|
|
2268
|
+
if (!trigger || !content) {
|
|
2269
|
+
this.hideNow();
|
|
2270
|
+
this.unbindTrigger();
|
|
2271
|
+
this.contentTemplate = null;
|
|
2272
|
+
return;
|
|
2273
|
+
}
|
|
2274
|
+
const element = trigger.elementRef.nativeElement;
|
|
2275
|
+
if (element !== this.triggerElement)
|
|
2276
|
+
this.bindTrigger(element);
|
|
2277
|
+
this.contentTemplate = content.templateRef;
|
|
2278
|
+
this.updateFocusable(element, focusable);
|
|
2279
|
+
if (this.panelRef) {
|
|
2280
|
+
this.panelRef.setInput('content', this.contentTemplate);
|
|
2281
|
+
this.panelRef.changeDetectorRef.detectChanges();
|
|
2155
2282
|
}
|
|
2283
|
+
});
|
|
2284
|
+
effect(() => {
|
|
2285
|
+
if (this.disabled())
|
|
2286
|
+
this.hideNow();
|
|
2287
|
+
});
|
|
2288
|
+
}
|
|
2289
|
+
/** Open the rich tooltip immediately, bypassing the hover delay. */
|
|
2290
|
+
show() {
|
|
2291
|
+
this.clearTimer('show');
|
|
2292
|
+
this.clearTimer('hide');
|
|
2293
|
+
const trigger = this.triggerElement;
|
|
2294
|
+
const content = this.contentTemplate ?? this.contentQuery()?.templateRef ?? null;
|
|
2295
|
+
if (this.overlayRef?.hasAttached())
|
|
2296
|
+
return;
|
|
2297
|
+
if (!trigger || !content || this.disabled())
|
|
2298
|
+
return;
|
|
2299
|
+
const overlayRef = this.ensureOverlay(trigger);
|
|
2300
|
+
this.panelRef = overlayRef.attach(this.portal);
|
|
2301
|
+
this.panelRef.setInput('content', content);
|
|
2302
|
+
this.panelRef.setInput('panelId', this.panelId);
|
|
2303
|
+
this.panelRef.changeDetectorRef.detectChanges();
|
|
2304
|
+
this.linkTriggerToPanel(trigger);
|
|
2305
|
+
this.clippingAncestors = this.resolveClippingAncestors(trigger);
|
|
2306
|
+
this.attachDocumentListeners();
|
|
2307
|
+
this.raiseFrame = requestAnimationFrame(() => {
|
|
2308
|
+
this.raiseFrame = null;
|
|
2309
|
+
this.panelRef?.setInput('visible', true);
|
|
2310
|
+
this.panelRef?.changeDetectorRef.detectChanges();
|
|
2311
|
+
});
|
|
2312
|
+
}
|
|
2313
|
+
/** Close the rich tooltip immediately, without the pointer grace period. */
|
|
2314
|
+
hideNow() {
|
|
2315
|
+
this.clearTimer('show');
|
|
2316
|
+
this.clearTimer('hide');
|
|
2317
|
+
if (this.raiseFrame !== null) {
|
|
2318
|
+
cancelAnimationFrame(this.raiseFrame);
|
|
2319
|
+
this.raiseFrame = null;
|
|
2156
2320
|
}
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2321
|
+
this.releaseDocumentListeners();
|
|
2322
|
+
this.unlinkTriggerFromPanel();
|
|
2323
|
+
this.clippingAncestors = [];
|
|
2324
|
+
if (this.overlayRef?.hasAttached())
|
|
2325
|
+
this.overlayRef.detach();
|
|
2326
|
+
this.panelRef = null;
|
|
2327
|
+
}
|
|
2328
|
+
/** True while the rich tooltip panel is attached. */
|
|
2329
|
+
get isOpen() {
|
|
2330
|
+
return this.overlayRef?.hasAttached() === true;
|
|
2331
|
+
}
|
|
2332
|
+
bindTrigger(element) {
|
|
2333
|
+
if (this.triggerElement === element && this.triggerCleanups.length > 0)
|
|
2334
|
+
return;
|
|
2335
|
+
this.hideNow();
|
|
2336
|
+
this.unbindTrigger();
|
|
2337
|
+
this.triggerElement = element;
|
|
2338
|
+
this.triggerCleanups = [
|
|
2339
|
+
this.renderer.listen(element, 'mouseenter', () => this.onPointerEnterTrigger()),
|
|
2340
|
+
this.renderer.listen(element, 'mouseleave', () => this.onPointerLeaveTrigger()),
|
|
2341
|
+
this.renderer.listen(element, 'focusin', () => this.onFocusTrigger()),
|
|
2342
|
+
this.renderer.listen(element, 'focusout', () => this.onBlurTrigger()),
|
|
2343
|
+
this.renderer.listen(element, 'click', () => this.hideNow()),
|
|
2344
|
+
];
|
|
2345
|
+
}
|
|
2346
|
+
unbindTrigger() {
|
|
2347
|
+
for (const cleanup of this.triggerCleanups)
|
|
2348
|
+
cleanup();
|
|
2349
|
+
this.triggerCleanups = [];
|
|
2350
|
+
if (this.addedTabIndex && this.triggerElement?.getAttribute('tabindex') === '0') {
|
|
2351
|
+
this.renderer.removeAttribute(this.triggerElement, 'tabindex');
|
|
2352
|
+
}
|
|
2353
|
+
this.addedTabIndex = false;
|
|
2354
|
+
this.triggerElement = null;
|
|
2355
|
+
}
|
|
2356
|
+
updateFocusable(element, focusable) {
|
|
2357
|
+
if (focusable && !this.isNativelyFocusable(element)) {
|
|
2358
|
+
if (!element.hasAttribute('tabindex')) {
|
|
2359
|
+
this.renderer.setAttribute(element, 'tabindex', '0');
|
|
2360
|
+
this.addedTabIndex = true;
|
|
2361
|
+
}
|
|
2362
|
+
return;
|
|
2363
|
+
}
|
|
2364
|
+
if (this.addedTabIndex && element.getAttribute('tabindex') === '0') {
|
|
2365
|
+
this.renderer.removeAttribute(element, 'tabindex');
|
|
2366
|
+
this.addedTabIndex = false;
|
|
2160
2367
|
}
|
|
2161
2368
|
}
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
this.
|
|
2165
|
-
return status;
|
|
2369
|
+
onPointerEnterTrigger() {
|
|
2370
|
+
this.pointerOnTrigger = true;
|
|
2371
|
+
this.scheduleShow();
|
|
2166
2372
|
}
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2373
|
+
onPointerLeaveTrigger() {
|
|
2374
|
+
this.pointerOnTrigger = false;
|
|
2375
|
+
this.scheduleHide();
|
|
2376
|
+
}
|
|
2377
|
+
onFocusTrigger() {
|
|
2378
|
+
if (!this.matchesFocusVisible())
|
|
2379
|
+
return;
|
|
2380
|
+
this.triggerFocused = true;
|
|
2381
|
+
this.show();
|
|
2382
|
+
}
|
|
2383
|
+
onBlurTrigger() {
|
|
2384
|
+
this.triggerFocused = false;
|
|
2385
|
+
this.scheduleHide();
|
|
2386
|
+
}
|
|
2387
|
+
scheduleShow() {
|
|
2388
|
+
if (this.isOpen) {
|
|
2389
|
+
this.clearTimer('hide');
|
|
2390
|
+
return;
|
|
2391
|
+
}
|
|
2392
|
+
if (this.disabled() || !this.triggerElement || !this.contentTemplate)
|
|
2393
|
+
return;
|
|
2394
|
+
this.clearTimer('hide');
|
|
2395
|
+
this.clearTimer('show');
|
|
2396
|
+
const delay = Math.max(0, this.delay());
|
|
2397
|
+
this.showTimer = setTimeout(() => {
|
|
2398
|
+
this.showTimer = null;
|
|
2399
|
+
this.show();
|
|
2400
|
+
}, delay);
|
|
2401
|
+
}
|
|
2402
|
+
scheduleHide() {
|
|
2403
|
+
this.clearTimer('show');
|
|
2404
|
+
this.clearTimer('hide');
|
|
2405
|
+
this.hideTimer = setTimeout(() => {
|
|
2406
|
+
this.hideTimer = null;
|
|
2407
|
+
if (this.pointerOnTrigger || this.pointerOnPanel || this.triggerFocused)
|
|
2408
|
+
return;
|
|
2409
|
+
this.hideNow();
|
|
2410
|
+
}, HIDE_DELAY_MS);
|
|
2411
|
+
}
|
|
2412
|
+
clearTimer(which) {
|
|
2413
|
+
const timer = which === 'show' ? this.showTimer : this.hideTimer;
|
|
2414
|
+
if (timer === null)
|
|
2415
|
+
return;
|
|
2416
|
+
clearTimeout(timer);
|
|
2417
|
+
if (which === 'show')
|
|
2418
|
+
this.showTimer = null;
|
|
2419
|
+
else
|
|
2420
|
+
this.hideTimer = null;
|
|
2421
|
+
}
|
|
2422
|
+
ensureOverlay(trigger) {
|
|
2423
|
+
if (this.overlayRef)
|
|
2424
|
+
return this.overlayRef;
|
|
2425
|
+
const positionStrategy = createFlexibleConnectedPositionStrategy(this.injector, trigger)
|
|
2426
|
+
.withFlexibleDimensions(false)
|
|
2427
|
+
.withPush(true)
|
|
2428
|
+
.withPositions(this.positions());
|
|
2429
|
+
this.overlayRef = createOverlayRef(this.injector, {
|
|
2430
|
+
positionStrategy,
|
|
2431
|
+
scrollStrategy: createRepositionScrollStrategy(this.injector),
|
|
2432
|
+
panelClass: ['wm-tooltip-overlay', 'wm-rich-tooltip-overlay'],
|
|
2433
|
+
hasBackdrop: false,
|
|
2434
|
+
});
|
|
2435
|
+
const overlayEl = this.overlayRef.overlayElement;
|
|
2436
|
+
overlayEl.addEventListener('mouseenter', this.onPointerEnterPanel);
|
|
2437
|
+
overlayEl.addEventListener('mouseleave', this.onPointerLeavePanel);
|
|
2438
|
+
this.positionChanges = positionStrategy.positionChanges.subscribe((change) => {
|
|
2439
|
+
const above = change.connectionPair.overlayY === 'bottom';
|
|
2440
|
+
overlayEl.classList.toggle('wm-tooltip-above', above);
|
|
2441
|
+
});
|
|
2442
|
+
this.portal = new ComponentPortal(WmRichTooltipPanel, null, this.injector);
|
|
2443
|
+
return this.overlayRef;
|
|
2444
|
+
}
|
|
2445
|
+
positions() {
|
|
2446
|
+
const offset = 6;
|
|
2447
|
+
const below = {
|
|
2448
|
+
originX: 'center', originY: 'bottom',
|
|
2449
|
+
overlayX: 'center', overlayY: 'top', offsetY: offset,
|
|
2450
|
+
};
|
|
2451
|
+
const above = {
|
|
2452
|
+
originX: 'center', originY: 'top',
|
|
2453
|
+
overlayX: 'center', overlayY: 'bottom', offsetY: -offset,
|
|
2454
|
+
};
|
|
2455
|
+
const after = {
|
|
2456
|
+
originX: 'end', originY: 'center',
|
|
2457
|
+
overlayX: 'start', overlayY: 'center', offsetX: offset,
|
|
2458
|
+
};
|
|
2459
|
+
const before = {
|
|
2460
|
+
originX: 'start', originY: 'center',
|
|
2461
|
+
overlayX: 'end', overlayY: 'center', offsetX: -offset,
|
|
2462
|
+
};
|
|
2463
|
+
switch (this.position()) {
|
|
2464
|
+
case 'top': return [above, below, after, before];
|
|
2465
|
+
case 'left': return [before, after, above, below];
|
|
2466
|
+
case 'right': return [after, before, above, below];
|
|
2467
|
+
default: return [below, above, after, before];
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
onPointerEnterPanel = () => {
|
|
2471
|
+
this.pointerOnPanel = true;
|
|
2472
|
+
this.clearTimer('hide');
|
|
2200
2473
|
};
|
|
2201
|
-
|
|
2202
|
-
this.
|
|
2474
|
+
onPointerLeavePanel = () => {
|
|
2475
|
+
this.pointerOnPanel = false;
|
|
2476
|
+
this.scheduleHide();
|
|
2477
|
+
};
|
|
2478
|
+
attachDocumentListeners() {
|
|
2479
|
+
if (this.detachDocumentListeners)
|
|
2480
|
+
return;
|
|
2481
|
+
const onKeydown = (event) => {
|
|
2482
|
+
if (event.key === 'Escape')
|
|
2483
|
+
this.hideNow();
|
|
2484
|
+
};
|
|
2485
|
+
const onPointerDown = () => this.hideNow();
|
|
2486
|
+
const stopFollowing = onViewportChange(() => this.reanchor());
|
|
2487
|
+
document.addEventListener('keydown', onKeydown, true);
|
|
2488
|
+
document.addEventListener('pointerdown', onPointerDown, true);
|
|
2489
|
+
this.detachDocumentListeners = () => {
|
|
2490
|
+
document.removeEventListener('keydown', onKeydown, true);
|
|
2491
|
+
document.removeEventListener('pointerdown', onPointerDown, true);
|
|
2492
|
+
stopFollowing();
|
|
2493
|
+
};
|
|
2203
2494
|
}
|
|
2204
|
-
|
|
2205
|
-
this.
|
|
2495
|
+
releaseDocumentListeners() {
|
|
2496
|
+
this.detachDocumentListeners?.();
|
|
2497
|
+
this.detachDocumentListeners = null;
|
|
2206
2498
|
}
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
args: [{ selector: 'wm-license-nudge', standalone: true, imports: [WmButton], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (shouldShow()) {\n <div class=\"wm-license-nudge\">\n <span class=\"wm-license-nudge__text\">\n Using this at work? Organizations require a commercial license.\n </span>\n <div class=\"wm-license-nudge__actions\">\n <wm-button variant=\"ghost\" size=\"sm\" (click)=\"onEnterLicense()\">Enter License Key</wm-button>\n <wm-button variant=\"ghost\" size=\"sm\" (click)=\"dismiss()\">Dismiss</wm-button>\n </div>\n </div>\n}\n", styles: [".wm-license-nudge{display:flex;align-items:center;justify-content:space-between;gap:var(--wm-space-md, 12px);padding:var(--wm-space-sm, 8px) var(--wm-space-md, 12px);background:var(--wm-bg-subtle, #2a2a2a);border-bottom:1px solid var(--wm-border, #3a3a3a);font-size:var(--wm-font-sm, 13px);color:var(--wm-fg-secondary, #999)}.wm-license-nudge__text{flex:1}.wm-license-nudge__actions{display:flex;gap:var(--wm-space-xs, 4px);flex-shrink:0}\n"] }]
|
|
2213
|
-
}], propDecorators: { declaredUseType: [{ type: i0.Input, args: [{ isSignal: true, alias: "declaredUseType", required: false }] }], enterLicense: [{ type: i0.Output, args: ["enterLicense"] }] } });
|
|
2214
|
-
|
|
2215
|
-
class WmLicenseDialog {
|
|
2216
|
-
licenseService = inject(WmLicenseService);
|
|
2217
|
-
visible = input.required(...(ngDevMode ? [{ debugName: "visible" }] : []));
|
|
2218
|
-
dismiss = output();
|
|
2219
|
-
keyInput = signal('', ...(ngDevMode ? [{ debugName: "keyInput" }] : []));
|
|
2220
|
-
validationResult = signal(null, ...(ngDevMode ? [{ debugName: "validationResult" }] : []));
|
|
2221
|
-
validating = signal(false, ...(ngDevMode ? [{ debugName: "validating" }] : []));
|
|
2222
|
-
installed = signal(false, ...(ngDevMode ? [{ debugName: "installed" }] : []));
|
|
2223
|
-
onDismiss() {
|
|
2224
|
-
this.reset();
|
|
2225
|
-
this.dismiss.emit();
|
|
2226
|
-
}
|
|
2227
|
-
onKeyInput(event) {
|
|
2228
|
-
const value = event.target.value;
|
|
2229
|
-
this.keyInput.set(value);
|
|
2230
|
-
this.validationResult.set(null);
|
|
2231
|
-
this.installed.set(false);
|
|
2232
|
-
}
|
|
2233
|
-
async validate() {
|
|
2234
|
-
const jwt = this.keyInput().trim();
|
|
2235
|
-
if (!jwt)
|
|
2499
|
+
reanchor() {
|
|
2500
|
+
if (!this.overlayRef?.hasAttached())
|
|
2501
|
+
return;
|
|
2502
|
+
if (this.isTriggerClipped()) {
|
|
2503
|
+
this.hideNow();
|
|
2236
2504
|
return;
|
|
2237
|
-
this.validating.set(true);
|
|
2238
|
-
try {
|
|
2239
|
-
const status = await this.licenseService.installKey(jwt);
|
|
2240
|
-
this.validationResult.set(status);
|
|
2241
|
-
if (status.valid) {
|
|
2242
|
-
this.installed.set(true);
|
|
2243
|
-
}
|
|
2244
2505
|
}
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2506
|
+
this.overlayRef.updatePosition();
|
|
2507
|
+
}
|
|
2508
|
+
resolveClippingAncestors(trigger) {
|
|
2509
|
+
const clipping = [];
|
|
2510
|
+
let node = trigger.parentElement;
|
|
2511
|
+
while (node) {
|
|
2512
|
+
const style = getComputedStyle(node);
|
|
2513
|
+
const clips = [style.overflow, style.overflowX, style.overflowY].some((value) => value === 'auto' || value === 'scroll' || value === 'hidden');
|
|
2514
|
+
if (clips)
|
|
2515
|
+
clipping.push(node);
|
|
2516
|
+
node = node.parentElement;
|
|
2517
|
+
}
|
|
2518
|
+
return clipping;
|
|
2519
|
+
}
|
|
2520
|
+
isTriggerClipped() {
|
|
2521
|
+
if (!this.triggerElement)
|
|
2522
|
+
return true;
|
|
2523
|
+
const trigger = this.triggerElement.getBoundingClientRect();
|
|
2524
|
+
const outside = (bounds) => trigger.bottom < bounds.top ||
|
|
2525
|
+
trigger.top > bounds.bottom ||
|
|
2526
|
+
trigger.right < bounds.left ||
|
|
2527
|
+
trigger.left > bounds.right;
|
|
2528
|
+
const viewport = {
|
|
2529
|
+
top: 0,
|
|
2530
|
+
left: 0,
|
|
2531
|
+
bottom: window.innerHeight || document.documentElement.clientHeight,
|
|
2532
|
+
right: window.innerWidth || document.documentElement.clientWidth,
|
|
2533
|
+
};
|
|
2534
|
+
if (outside(viewport))
|
|
2535
|
+
return true;
|
|
2536
|
+
return this.clippingAncestors.some((ancestor) => outside(ancestor.getBoundingClientRect()));
|
|
2537
|
+
}
|
|
2538
|
+
relationAttribute() {
|
|
2539
|
+
return this.relation() === 'label' ? 'aria-labelledby' : 'aria-describedby';
|
|
2540
|
+
}
|
|
2541
|
+
linkTriggerToPanel(trigger) {
|
|
2542
|
+
const attribute = this.relationAttribute();
|
|
2543
|
+
const next = withIdToken(trigger.getAttribute(attribute), this.panelId);
|
|
2544
|
+
this.renderer.setAttribute(trigger, attribute, next);
|
|
2545
|
+
}
|
|
2546
|
+
unlinkTriggerFromPanel() {
|
|
2547
|
+
if (!this.triggerElement)
|
|
2548
|
+
return;
|
|
2549
|
+
for (const attribute of ['aria-describedby', 'aria-labelledby']) {
|
|
2550
|
+
const current = this.triggerElement.getAttribute(attribute);
|
|
2551
|
+
if (current === null)
|
|
2552
|
+
continue;
|
|
2553
|
+
const next = withoutIdToken(current, this.panelId);
|
|
2554
|
+
if (next === null)
|
|
2555
|
+
this.renderer.removeAttribute(this.triggerElement, attribute);
|
|
2556
|
+
else if (next !== current)
|
|
2557
|
+
this.renderer.setAttribute(this.triggerElement, attribute, next);
|
|
2256
2558
|
}
|
|
2257
|
-
|
|
2258
|
-
|
|
2559
|
+
}
|
|
2560
|
+
isNativelyFocusable(element) {
|
|
2561
|
+
if (element.hasAttribute('tabindex'))
|
|
2562
|
+
return true;
|
|
2563
|
+
return ['a', 'button', 'input', 'select', 'textarea', 'summary'].includes(element.tagName.toLowerCase());
|
|
2564
|
+
}
|
|
2565
|
+
matchesFocusVisible() {
|
|
2566
|
+
if (!this.triggerElement)
|
|
2567
|
+
return false;
|
|
2568
|
+
try {
|
|
2569
|
+
return this.triggerElement.matches(':focus-visible');
|
|
2570
|
+
}
|
|
2571
|
+
catch {
|
|
2572
|
+
return true;
|
|
2259
2573
|
}
|
|
2260
2574
|
}
|
|
2261
|
-
|
|
2262
|
-
this.
|
|
2263
|
-
this.
|
|
2264
|
-
this.
|
|
2265
|
-
this.
|
|
2575
|
+
teardown() {
|
|
2576
|
+
this.hideNow();
|
|
2577
|
+
this.unbindTrigger();
|
|
2578
|
+
const overlayEl = this.overlayRef?.overlayElement;
|
|
2579
|
+
overlayEl?.removeEventListener('mouseenter', this.onPointerEnterPanel);
|
|
2580
|
+
overlayEl?.removeEventListener('mouseleave', this.onPointerLeavePanel);
|
|
2581
|
+
this.positionChanges?.unsubscribe();
|
|
2582
|
+
this.positionChanges = null;
|
|
2583
|
+
this.overlayRef?.dispose();
|
|
2584
|
+
this.overlayRef = null;
|
|
2585
|
+
this.portal = null;
|
|
2266
2586
|
}
|
|
2267
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2268
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
2587
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmRichTooltip, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2588
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.23", type: WmRichTooltip, isStandalone: true, selector: "wm-rich-tooltip", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, delay: { classPropertyName: "delay", publicName: "delay", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, relation: { classPropertyName: "relation", publicName: "relation", isSignal: true, isRequired: false, transformFunction: null }, focusable: { classPropertyName: "focusable", publicName: "focusable", isSignal: true, isRequired: false, transformFunction: null } }, host: { styleAttribute: "display: contents" }, queries: [{ propertyName: "triggerQuery", first: true, predicate: WmRichTooltipTrigger, descendants: true, isSignal: true }, { propertyName: "contentQuery", first: true, predicate: WmRichTooltipContent, descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
2589
|
+
<ng-content select="[wmRichTooltipTrigger]"></ng-content>
|
|
2590
|
+
<ng-content select="ng-template[wmRichTooltipContent]"></ng-content>
|
|
2591
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2269
2592
|
}
|
|
2270
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2593
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: WmRichTooltip, decorators: [{
|
|
2271
2594
|
type: Component,
|
|
2272
|
-
args: [{
|
|
2273
|
-
|
|
2595
|
+
args: [{
|
|
2596
|
+
selector: 'wm-rich-tooltip',
|
|
2597
|
+
template: `
|
|
2598
|
+
<ng-content select="[wmRichTooltipTrigger]"></ng-content>
|
|
2599
|
+
<ng-content select="ng-template[wmRichTooltipContent]"></ng-content>
|
|
2600
|
+
`,
|
|
2601
|
+
host: { style: 'display: contents' },
|
|
2602
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
2603
|
+
encapsulation: ViewEncapsulation.None,
|
|
2604
|
+
}]
|
|
2605
|
+
}], ctorParameters: () => [], propDecorators: { position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], delay: [{ type: i0.Input, args: [{ isSignal: true, alias: "delay", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], relation: [{ type: i0.Input, args: [{ isSignal: true, alias: "relation", required: false }] }], focusable: [{ type: i0.Input, args: [{ isSignal: true, alias: "focusable", required: false }] }], triggerQuery: [{ type: i0.ContentChild, args: [i0.forwardRef(() => WmRichTooltipTrigger), { isSignal: true }] }], contentQuery: [{ type: i0.ContentChild, args: [i0.forwardRef(() => WmRichTooltipContent), { isSignal: true }] }] } });
|
|
2274
2606
|
|
|
2275
2607
|
// Components
|
|
2276
2608
|
|
|
@@ -2278,5 +2610,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.1", ngImpor
|
|
|
2278
2610
|
* Generated bundle index. Do not edit.
|
|
2279
2611
|
*/
|
|
2280
2612
|
|
|
2281
|
-
export { Checkbox, GhostField, NumberInput, PageHeader, Toggle, WmAnchoredScrollStrategy, WmAutoFocus, WmButton, WmCombobox, WmDialog,
|
|
2613
|
+
export { Checkbox, GhostField, NumberInput, PageHeader, Toggle, WmAnchoredScrollStrategy, WmAutoFocus, WmButton, WmCombobox, WmDialog, WmModal, WmPopover, WmRichTooltip, WmRichTooltipContent, WmRichTooltipTrigger, WmSelect, WmTab, WmTabs, WmToastContainer, WmToastService, WmTooltip, onViewportChange };
|
|
2282
2614
|
//# sourceMappingURL=wildmason-aegis.mjs.map
|