@wildmason/aegis 1.5.4

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.
@@ -0,0 +1,545 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { ElementRef, AfterViewInit, TemplateRef, OnDestroy } from '@angular/core';
3
+ import { ConnectedPosition } from '@angular/cdk/overlay';
4
+ import { ControlValueAccessor } from '@angular/forms';
5
+
6
+ /**
7
+ * WmModal — Lightweight modal backdrop with Escape key and click-outside dismissal.
8
+ *
9
+ * Owns the fixed backdrop, centering, and keyboard/pointer dismissal so individual
10
+ * modal components don't need to repeat this logic or add their own HostListeners.
11
+ *
12
+ * Usage:
13
+ * <wm-modal [visible]="visible()" (dismiss)="close()">
14
+ * <div class="p-6 wm-r-md w-80" style="background: var(--wm-bg-raised)">
15
+ * <!-- modal panel content -->
16
+ * </div>
17
+ * </wm-modal>
18
+ *
19
+ * For top-aligned panels (e.g. search/command palettes), use align="top":
20
+ * <wm-modal [visible]="visible()" (dismiss)="close()" align="top">
21
+ *
22
+ * The projected content is wrapped in a stop-propagation container so clicks inside
23
+ * the panel do not bubble up to the backdrop and trigger a dismiss.
24
+ */
25
+ declare class WmModal {
26
+ /** Whether the modal is currently open. */
27
+ visible: _angular_core.InputSignal<boolean>;
28
+ /** Emitted when the user requests the modal to close (Escape or backdrop click). */
29
+ dismiss: _angular_core.OutputEmitterRef<void>;
30
+ /**
31
+ * Vertical alignment of the panel within the backdrop.
32
+ * - 'center' (default): panel is vertically centered (items-center)
33
+ * - 'top': panel appears near the top (items-start pt-20), for search/command overlays
34
+ */
35
+ align: _angular_core.InputSignal<"center" | "top">;
36
+ onEscape(): void;
37
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<WmModal, never>;
38
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WmModal, "wm-modal", never, { "visible": { "alias": "visible"; "required": true; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; }, { "dismiss": "dismiss"; }, never, ["*"], true, never>;
39
+ }
40
+
41
+ type DialogSize = 'sm' | 'md' | 'lg';
42
+ /**
43
+ * WmDialog — Modal dialog with backdrop, focus trap, and Escape key handling.
44
+ *
45
+ * Renders a fixed-position overlay that is always viewport-relative (not clipped
46
+ * by ancestor overflow:hidden). Do NOT place inside a container that uses
47
+ * CSS transform, perspective, or filter — fixed positioning breaks in that context.
48
+ *
49
+ * Usage:
50
+ * <wm-dialog [(isOpen)]="open" title="Confirm action">
51
+ * <div body>
52
+ * <p>Are you sure?</p>
53
+ * <div class="wm-dialog-footer">
54
+ * <wm-button variant="secondary" (click)="open.set(false)">Cancel</wm-button>
55
+ * <wm-button variant="primary" (click)="onConfirm()">Confirm</wm-button>
56
+ * </div>
57
+ * </div>
58
+ * </wm-dialog>
59
+ *
60
+ * Accessibility:
61
+ * - role="dialog" + aria-modal="true" on the panel
62
+ * - aria-labelledby wired to the title element (when title is set)
63
+ * - Focus is trapped inside the panel when open (cdkTrapFocus)
64
+ * - Escape key closes the dialog
65
+ * - Clicking the backdrop closes the dialog
66
+ * - On close, focus returns to the element that opened the dialog
67
+ * (browser default when focus trap is released)
68
+ */
69
+ declare class WmDialog {
70
+ /** Two-way binding for open/closed state. */
71
+ isOpen: _angular_core.ModelSignal<boolean>;
72
+ /** Dialog heading text. When set, aria-labelledby is applied automatically. */
73
+ title: _angular_core.InputSignal<string>;
74
+ /** Panel width preset. sm = 360px, md = 480px (default), lg = 640px. */
75
+ size: _angular_core.InputSignal<DialogSize>;
76
+ close(): void;
77
+ onEscape(): void;
78
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<WmDialog, never>;
79
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WmDialog, "wm-dialog", never, { "isOpen": { "alias": "isOpen"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, { "isOpen": "isOpenChange"; }, never, ["[body]"], true, never>;
80
+ }
81
+
82
+ /**
83
+ * SelectOption — data model for WmSelect options.
84
+ *
85
+ * Used as items in the [options] input on <wm-select>.
86
+ */
87
+ interface SelectOption {
88
+ /** The value that will be emitted when this option is selected. */
89
+ value: unknown;
90
+ /** The text label displayed in the trigger and in the dropdown list. */
91
+ label: string;
92
+ /** When true, the option is visible but cannot be selected. */
93
+ disabled?: boolean;
94
+ }
95
+
96
+ /**
97
+ * WmSelect — Accessible dropdown select built on Angular CDK Overlay.
98
+ *
99
+ * Provides a styled, keyboard-accessible alternative to the native <select> element
100
+ * when you need custom option rendering or consistent cross-platform appearance.
101
+ *
102
+ * When to use:
103
+ * - Single selection from a list of 4+ options
104
+ * - When option labels are complex (icons, descriptions, status badges)
105
+ * - When native <select> appearance is insufficient
106
+ *
107
+ * When NOT to use:
108
+ * - 3 or fewer options → use a radio group (more scannable, no extra click)
109
+ * - Multi-select → use a checkbox group or a combobox with chips
110
+ * - Yes/No choices → use a Toggle or two radio buttons
111
+ *
112
+ * Options API:
113
+ * options: SelectOption[] — Array of { value, label, disabled? } objects.
114
+ *
115
+ * Two-way binding:
116
+ * <wm-select [(value)]="selectedValue" [options]="myOptions" />
117
+ *
118
+ * Accessibility:
119
+ * - Trigger has role="combobox", aria-expanded, aria-haspopup="listbox"
120
+ * - Panel has role="listbox"; each option has role="option" + aria-selected
121
+ * - Disabled options have aria-disabled="true"
122
+ * - Focus is trapped inside the open panel (cdkTrapFocus)
123
+ * - Clicking the backdrop closes the panel and returns focus to the trigger
124
+ * - Keyboard: Enter/Space on trigger opens; Escape closes; arrow keys
125
+ * navigate options (relies on natural tab order within the panel)
126
+ * - Always pair with a visible label via <wm-label> or aria-label on the host
127
+ */
128
+ declare class WmSelect {
129
+ /** Array of options to display. */
130
+ options: _angular_core.InputSignal<SelectOption[]>;
131
+ /** The currently selected value. Two-way bindable. */
132
+ value: _angular_core.ModelSignal<unknown>;
133
+ /** Placeholder text shown when no option is selected. */
134
+ placeholder: _angular_core.InputSignal<string>;
135
+ /** Disables the trigger and prevents the panel from opening. */
136
+ disabled: _angular_core.InputSignal<boolean>;
137
+ protected isOpen: _angular_core.WritableSignal<boolean>;
138
+ protected selectedOption: _angular_core.Signal<SelectOption>;
139
+ private hostEl;
140
+ protected get overlayWidth(): number;
141
+ protected positions: ConnectedPosition[];
142
+ protected toggleOpen(): void;
143
+ protected selectOption(opt: SelectOption): void;
144
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<WmSelect, never>;
145
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WmSelect, "wm-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
146
+ }
147
+
148
+ /**
149
+ * WmPopover — general-purpose CDK-overlay floating panel.
150
+ *
151
+ * A low-level primitive for dropdowns, menus, pickers, and any floating UI.
152
+ * The parent controls open/close state; this component handles positioning,
153
+ * backdrop, focus-trapping, and ARIA attribute management.
154
+ *
155
+ * Slots:
156
+ * - [trigger] — the anchor element (button, icon, etc.)
157
+ * - [content] — the panel body (menu items, form, etc.)
158
+ *
159
+ * Usage:
160
+ * ```html
161
+ * <wm-popover [isOpen]="open()" (closed)="open.set(false)" role="menu" hasPopup="menu" align="end">
162
+ * <button trigger (click)="open.set(!open())">Options</button>
163
+ * <div content role="menu">
164
+ * <button role="menuitem" (click)="doThing()">Do thing</button>
165
+ * </div>
166
+ * </wm-popover>
167
+ * ```
168
+ *
169
+ * Accessibility:
170
+ * - Trigger element automatically receives aria-haspopup, aria-expanded, aria-controls
171
+ * - Panel receives the configured role
172
+ * - Focus is trapped inside the open panel (cdkTrapFocus)
173
+ * - Escape key closes the panel
174
+ * - Backdrop click closes the panel
175
+ *
176
+ * Auto-focus:
177
+ * - Add [wmAutoFocus] to any element inside [content] to focus it on open.
178
+ * Import WmAutoFocus from @wildmason/aegis/components and add it to your component's imports.
179
+ */
180
+ declare class WmPopover {
181
+ /** Whether the panel is currently open. */
182
+ readonly isOpen: _angular_core.InputSignal<boolean>;
183
+ /** Panel width in pixels, or 'auto' to match content. */
184
+ readonly width: _angular_core.InputSignal<string | number>;
185
+ /** ARIA role for the floating panel element. Use 'menu', 'listbox', 'dialog', etc. */
186
+ readonly role: _angular_core.InputSignal<string>;
187
+ /** Value for aria-haspopup on the trigger element. */
188
+ readonly hasPopup: _angular_core.InputSignal<string | boolean>;
189
+ /** Horizontal alignment: 'start' aligns left edges, 'end' aligns right edges. */
190
+ readonly align: _angular_core.InputSignal<"start" | "end">;
191
+ /** Emitted when the panel should close (backdrop click, Escape key, CDK detach). */
192
+ readonly closed: _angular_core.OutputEmitterRef<void>;
193
+ private readonly renderer;
194
+ private readonly hostEl;
195
+ private readonly cdr;
196
+ protected readonly panelId: string;
197
+ protected readonly panel: _angular_core.Signal<ElementRef<HTMLElement>>;
198
+ constructor();
199
+ protected get positions(): ConnectedPosition[];
200
+ protected onAttach(): void;
201
+ protected onClose(): void;
202
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<WmPopover, never>;
203
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WmPopover, "wm-popover", never, { "isOpen": { "alias": "isOpen"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "role": { "alias": "role"; "required": false; "isSignal": true; }; "hasPopup": { "alias": "hasPopup"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; }, { "closed": "closed"; }, never, ["[trigger]", "[content]"], true, never>;
204
+ }
205
+
206
+ /**
207
+ * WmAutoFocus — focuses an element when it enters the DOM.
208
+ *
209
+ * Usage: add [wmAutoFocus] to any focusable element inside a <wm-popover> panel.
210
+ * For date/time/color/select inputs, also attempts to open the native picker UI.
211
+ *
212
+ * @example
213
+ * <input wmAutoFocus type="text" />
214
+ * <input [wmAutoFocus]="shouldFocus" type="date" />
215
+ */
216
+ declare class WmAutoFocus implements AfterViewInit {
217
+ #private;
218
+ enabled: boolean | '';
219
+ ngAfterViewInit(): void;
220
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<WmAutoFocus, never>;
221
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<WmAutoFocus, "[wmAutoFocus]", never, { "enabled": { "alias": "wmAutoFocus"; "required": false; }; }, {}, never, never, true, never>;
222
+ }
223
+
224
+ declare class WmTab {
225
+ readonly value: _angular_core.InputSignal<string>;
226
+ readonly tmpl: _angular_core.Signal<TemplateRef<void>>;
227
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<WmTab, never>;
228
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WmTab, "wm-tab", never, { "value": { "alias": "value"; "required": true; "isSignal": true; }; }, {}, never, ["*"], true, never>;
229
+ }
230
+
231
+ declare class WmTabs {
232
+ activeValue: _angular_core.InputSignal<string>;
233
+ variant: _angular_core.InputSignal<"line" | "pill">;
234
+ readonly select: _angular_core.OutputEmitterRef<string>;
235
+ protected readonly tabs: _angular_core.Signal<readonly WmTab[]>;
236
+ protected focusedIndex: _angular_core.WritableSignal<number>;
237
+ protected selectTab(value: string, index: number): void;
238
+ protected onBlur(): void;
239
+ protected onKeyDown(event: KeyboardEvent, container: HTMLElement): void;
240
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<WmTabs, never>;
241
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WmTabs, "wm-tabs", never, { "activeValue": { "alias": "activeValue"; "required": true; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; }, { "select": "select"; }, ["tabs"], never, true, never>;
242
+ }
243
+
244
+ type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'destructive' | 'flat';
245
+ type ButtonSize = 'xs' | 'sm' | 'md' | 'lg';
246
+ declare class WmButton {
247
+ readonly variant: _angular_core.InputSignal<ButtonVariant>;
248
+ readonly size: _angular_core.InputSignal<ButtonSize>;
249
+ readonly disabled: _angular_core.InputSignal<boolean>;
250
+ readonly type: _angular_core.InputSignal<"button" | "submit" | "reset">;
251
+ /** Makes the button square (equal width/height). Use for icon-only buttons. */
252
+ readonly iconOnly: _angular_core.InputSignal<boolean>;
253
+ /** Accessible label forwarded to the inner <button>. Required for icon-only buttons. */
254
+ readonly ariaLabel: _angular_core.InputSignal<string>;
255
+ /** Tooltip text forwarded to the inner <button>. Named btnTitle to avoid native attribute conflict. */
256
+ readonly btnTitle: _angular_core.InputSignal<string>;
257
+ protected readonly btnClass: _angular_core.Signal<string>;
258
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<WmButton, never>;
259
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WmButton, "wm-button", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "iconOnly": { "alias": "iconOnly"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "btnTitle": { "alias": "btnTitle"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
260
+ }
261
+
262
+ /**
263
+ * WmCheckbox — Boolean selection control with optional indeterminate state.
264
+ *
265
+ * When to use:
266
+ * - Multi-select lists (each item is independent)
267
+ * - Form options that require explicit confirmation before taking effect
268
+ * - Parent/child hierarchical selection (use indeterminate for "some selected")
269
+ *
270
+ * When NOT to use:
271
+ * - Mutually exclusive choices → use radio buttons instead
272
+ * - Immediate-effect toggles (e.g. dark mode) → use Toggle instead
273
+ *
274
+ * Accessibility:
275
+ * - role="checkbox" with aria-checked="true|false|mixed"
276
+ * - "mixed" maps to the indeterminate state for screen readers
277
+ * - Space activates the checkbox (native button behaviour)
278
+ * - Focus ring uses a double-ring (canvas gap + accent) pattern for maximum visibility
279
+ * across all themes, meeting WCAG 2.1 SC 1.4.11 Non-text Contrast
280
+ * - When wrapping in a group, add role="group" + aria-labelledby to the container
281
+ */
282
+ declare class Checkbox {
283
+ /** Two-way bindable checked state. */
284
+ checked: _angular_core.ModelSignal<boolean>;
285
+ /**
286
+ * Shows a dash icon instead of a checkmark. Typically used for a "select all"
287
+ * checkbox when only some child items are selected.
288
+ * Note: indeterminate is display-only — clicking always toggles to true/false.
289
+ */
290
+ indeterminate: _angular_core.InputSignal<boolean>;
291
+ /** Visible text label rendered next to the checkbox box. */
292
+ label: _angular_core.InputSignal<string>;
293
+ disabled: _angular_core.InputSignal<boolean>;
294
+ /** Maps to aria-checked: true, false, or "mixed" (for indeterminate). */
295
+ protected ariaChecked: _angular_core.Signal<boolean | "mixed">;
296
+ toggle(): void;
297
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<Checkbox, never>;
298
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<Checkbox, "wm-checkbox", never, { "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "indeterminate": { "alias": "indeterminate"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "checked": "checkedChange"; }, never, never, true, never>;
299
+ }
300
+
301
+ /**
302
+ * WmNumberInput — Numeric input with stepper buttons.
303
+ *
304
+ * Implements ControlValueAccessor so it works with both template-driven forms
305
+ * (ngModel) and reactive forms (formControl / formControlName).
306
+ *
307
+ * When to use:
308
+ * - Quantity fields (items in cart, repetitions, page count)
309
+ * - Bounded numeric settings with a known min/max (timeout seconds, font size)
310
+ *
311
+ * When NOT to use:
312
+ * - Free-form numeric entry without bounds → plain <input type="number">
313
+ * - Currency or phone numbers → use a text input with masking
314
+ *
315
+ * Accessibility:
316
+ * - The underlying <input type="number"> is the focusable control.
317
+ * - Stepper buttons have tabindex="-1" — they are mouse/touch targets only.
318
+ * Keyboard users use the arrow keys on the input itself (native browser behaviour).
319
+ * - Always provide an aria-label or visible label via <wm-field> + <wm-label>.
320
+ * - The buttons use mousedown + preventDefault to avoid stealing focus from the input.
321
+ *
322
+ * Form integration:
323
+ * <!-- Template-driven -->
324
+ * <wm-number-input [(ngModel)]="count" [min]="0" [max]="100" />
325
+ *
326
+ * <!-- Reactive -->
327
+ * <wm-number-input formControlName="quantity" [step]="5" />
328
+ */
329
+ declare class NumberInput implements ControlValueAccessor {
330
+ /** Minimum allowed value. */
331
+ min: _angular_core.InputSignal<number>;
332
+ /** Maximum allowed value. */
333
+ max: _angular_core.InputSignal<number>;
334
+ /** Amount to increment/decrement per step. Defaults to 1. */
335
+ step: _angular_core.InputSignal<number>;
336
+ /** Placeholder text shown when the field is empty. */
337
+ placeholder: _angular_core.InputSignal<string>;
338
+ /** Disables the control from the template. Also set automatically by reactive forms. */
339
+ disabled: _angular_core.InputSignal<boolean>;
340
+ protected inputRef: _angular_core.Signal<ElementRef<HTMLInputElement>>;
341
+ protected internalValue: _angular_core.WritableSignal<number>;
342
+ private onChangeFn;
343
+ protected onTouchedFn: () => void;
344
+ /** CVA interface — called when the form model changes programmatically. */
345
+ writeValue(value: number | null): void;
346
+ registerOnChange(fn: (v: number | null) => void): void;
347
+ registerOnTouched(fn: () => void): void;
348
+ protected onInputChange(event: Event): void;
349
+ protected increment(): void;
350
+ protected decrement(): void;
351
+ /**
352
+ * Prevents the stepper buttons from stealing focus away from the input element.
353
+ * Without this, clicking a button would blur the input, hiding any validation state.
354
+ */
355
+ protected preventFocusSteal(event: MouseEvent): void;
356
+ private setValue;
357
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<NumberInput, never>;
358
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<NumberInput, "wm-number-input", never, { "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
359
+ }
360
+
361
+ /**
362
+ * WmToggle — Binary on/off control.
363
+ *
364
+ * Use for settings that take effect immediately without a form submit.
365
+ * For settings that need an explicit "Save" action, prefer a checkbox.
366
+ *
367
+ * Accessibility:
368
+ * - role="switch" communicates binary state to screen readers
369
+ * - aria-checked reflects true/false
370
+ * - aria-label required when no visible text label surrounds the toggle
371
+ * - Space and Enter activate the toggle (native button behaviour)
372
+ * - When disabled, aria state is preserved so SR users understand why it can't be changed
373
+ */
374
+ declare class Toggle {
375
+ /** Two-way bindable state. Use [(checked)]="mySignal" or [checked]="val" (changeChecked)="val=$event". */
376
+ checked: _angular_core.ModelSignal<boolean>;
377
+ /** Visually and functionally disables the toggle. State is still readable by assistive tech. */
378
+ disabled: _angular_core.InputSignal<boolean>;
379
+ /** Accessible label. Required if no visible label text surrounds the toggle in the DOM. */
380
+ ariaLabel: _angular_core.InputSignal<string>;
381
+ toggle(): void;
382
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<Toggle, never>;
383
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<Toggle, "wm-toggle", never, { "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "checked": "checkedChange"; }, never, never, true, never>;
384
+ }
385
+
386
+ /**
387
+ * GhostField — transparent-until-hover wrapper for inline-editable fields.
388
+ *
389
+ * Applies .wm-ghost-field to its content; all visual behaviour is CSS-driven
390
+ * (inputs.css). No inputs or outputs — interactivity belongs to the inner
391
+ * element projected via ng-content.
392
+ *
393
+ * Usage:
394
+ * <wm-ghost-field>
395
+ * <input class="wm-input-bare" [(ngModel)]="title" aria-label="Task title" />
396
+ * </wm-ghost-field>
397
+ */
398
+ declare class GhostField {
399
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<GhostField, never>;
400
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<GhostField, "wm-ghost-field", never, {}, {}, never, ["*"], true, never>;
401
+ }
402
+
403
+ /**
404
+ * PageHeader — standardised page-level heading with eyebrow label, title,
405
+ * optional subtitle, optional status badge, and projected action/back slots.
406
+ *
407
+ * Slots:
408
+ * [icon] — 12×12 icon projected into the eyebrow row (optional)
409
+ * [back] — back-navigation element (link or button) placed in the status row (optional)
410
+ * default — action buttons / controls placed below the status row
411
+ *
412
+ * Usage:
413
+ * <wm-page-header flavourText="Sprints" title="Active Sprint" [badgeLabel]="daysLeft">
414
+ * <svg icon .../>
415
+ * <a back href="...">← Board</a>
416
+ * <wm-button>New Sprint</wm-button>
417
+ * </wm-page-header>
418
+ */
419
+ declare class PageHeader {
420
+ readonly flavourText: _angular_core.InputSignal<string>;
421
+ readonly title: _angular_core.InputSignal<string>;
422
+ readonly subtitle: _angular_core.InputSignal<string>;
423
+ readonly badgeLabel: _angular_core.InputSignal<string>;
424
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<PageHeader, never>;
425
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<PageHeader, "wm-page-header", never, { "flavourText": { "alias": "flavourText"; "required": true; "isSignal": true; }; "title": { "alias": "title"; "required": true; "isSignal": true; }; "subtitle": { "alias": "subtitle"; "required": false; "isSignal": true; }; "badgeLabel": { "alias": "badgeLabel"; "required": false; "isSignal": true; }; }, {}, never, ["[icon]", "[back]", "*"], true, never>;
426
+ }
427
+
428
+ type ToastType = 'success' | 'error' | 'info' | 'progress';
429
+ interface Toast {
430
+ id: number;
431
+ message: string;
432
+ type: ToastType;
433
+ /** If true, toast does not auto-dismiss. Caller must dismiss it manually. */
434
+ persistent?: boolean;
435
+ /** Epoch ms when this toast was created (used for elapsed time display). */
436
+ createdAt?: number;
437
+ /** Callback invoked when the user clicks the Cancel button (progress toasts only). */
438
+ onCancel?: () => void;
439
+ }
440
+ /**
441
+ * WmToastService — Application-wide toast notification manager.
442
+ *
443
+ * Provided in root; inject anywhere and call success(), error(), info(), or progress().
444
+ * Render `<wm-toast-container>` once at the app root to display toasts.
445
+ *
446
+ * Auto-dismiss: success/info after 4 s, error after 6 s.
447
+ * Progress toasts persist until explicitly dismissed.
448
+ * Custom duration via show(message, type, durationMs).
449
+ */
450
+ declare class WmToastService {
451
+ readonly toasts: _angular_core.WritableSignal<Toast[]>;
452
+ show(message: string, type?: ToastType, duration?: number): number;
453
+ success(message: string): number;
454
+ error(message: string): number;
455
+ info(message: string): number;
456
+ /**
457
+ * Show a persistent progress toast with spinner and elapsed timer.
458
+ * Returns the toast ID — caller must call dismiss(id) when done.
459
+ *
460
+ * @param message - Display message (e.g. "Generating docs…")
461
+ * @param onCancel - Optional callback invoked when the user clicks Cancel.
462
+ * The caller should abort the operation and then dismiss the toast.
463
+ */
464
+ progress(message: string, onCancel?: () => void): number;
465
+ dismiss(id: number): void;
466
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<WmToastService, never>;
467
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<WmToastService>;
468
+ }
469
+
470
+ /**
471
+ * WmToastContainer — Renders the current stack of toasts.
472
+ *
473
+ * Place once at the application root (e.g. inside the shell or app component).
474
+ * Uses inline SVG icons — no external icon library dependency.
475
+ *
476
+ * Accessibility:
477
+ * - Container has role="log" + aria-live="polite" so new toasts are announced
478
+ * - Each toast has role="status"
479
+ * - Dismiss button has an accessible label
480
+ */
481
+ declare class WmToastContainer implements OnDestroy {
482
+ protected readonly toastService: WmToastService;
483
+ /** Tick signal that updates every second — drives the elapsed time display. */
484
+ protected readonly tick: _angular_core.WritableSignal<number>;
485
+ private tickInterval;
486
+ ngOnDestroy(): void;
487
+ protected dismiss(id: number): void;
488
+ protected cancel(toast: Toast): void;
489
+ protected typeClass(toast: Toast): string;
490
+ protected elapsed(createdAt: number): string;
491
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<WmToastContainer, never>;
492
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WmToastContainer, "wm-toast-container", never, {}, {}, never, never, true, never>;
493
+ }
494
+
495
+ interface LicenseStatus {
496
+ valid: boolean;
497
+ org: string | null;
498
+ product: string;
499
+ seats: number | null;
500
+ tier: string | null;
501
+ expires: string | null;
502
+ key_id: string | null;
503
+ error: string | null;
504
+ }
505
+
506
+ declare class WmLicenseService {
507
+ private toast;
508
+ readonly license: _angular_core.WritableSignal<LicenseStatus>;
509
+ readonly isLicensed: _angular_core.Signal<boolean>;
510
+ readonly orgName: _angular_core.Signal<string>;
511
+ checkLicense(): Promise<void>;
512
+ installKey(jwt: string): Promise<LicenseStatus>;
513
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<WmLicenseService, never>;
514
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<WmLicenseService>;
515
+ }
516
+
517
+ declare class WmLicenseNudge {
518
+ private licenseService;
519
+ dismissed: _angular_core.WritableSignal<boolean>;
520
+ enterLicense: _angular_core.OutputEmitterRef<void>;
521
+ protected readonly shouldShow: () => boolean;
522
+ dismiss(): void;
523
+ onEnterLicense(): void;
524
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<WmLicenseNudge, never>;
525
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WmLicenseNudge, "wm-license-nudge", never, {}, { "enterLicense": "enterLicense"; }, never, never, true, never>;
526
+ }
527
+
528
+ declare class WmLicenseDialog {
529
+ private licenseService;
530
+ visible: _angular_core.InputSignal<boolean>;
531
+ dismiss: _angular_core.OutputEmitterRef<void>;
532
+ keyInput: _angular_core.WritableSignal<string>;
533
+ validationResult: _angular_core.WritableSignal<LicenseStatus>;
534
+ validating: _angular_core.WritableSignal<boolean>;
535
+ installed: _angular_core.WritableSignal<boolean>;
536
+ onDismiss(): void;
537
+ onKeyInput(event: Event): void;
538
+ validate(): Promise<void>;
539
+ private reset;
540
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<WmLicenseDialog, never>;
541
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WmLicenseDialog, "wm-license-dialog", never, { "visible": { "alias": "visible"; "required": true; "isSignal": true; }; }, { "dismiss": "dismiss"; }, never, never, true, never>;
542
+ }
543
+
544
+ export { Checkbox, GhostField, NumberInput, PageHeader, Toggle, WmAutoFocus, WmButton, WmDialog, WmLicenseDialog, WmLicenseNudge, WmLicenseService, WmModal, WmPopover, WmSelect, WmTab, WmTabs, WmToastContainer, WmToastService };
545
+ export type { ButtonSize, ButtonVariant, DialogSize, LicenseStatus, SelectOption, Toast, ToastType };