@truenas/ui-components 0.1.71 → 0.1.73

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truenas/ui-components",
3
- "version": "0.1.71",
3
+ "version": "0.1.73",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org",
6
6
  "access": "public"
@@ -1,9 +1,10 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { OnDestroy, ElementRef, InjectionToken, AfterViewInit, OnInit, TemplateRef, AfterContentInit, Provider, ChangeDetectorRef, Signal, PipeTransform, ViewContainerRef, AfterViewChecked, ComponentRef } from '@angular/core';
3
- import { ControlValueAccessor, NgControl } from '@angular/forms';
2
+ import { InjectionToken, Renderer2, OnDestroy, ElementRef, AfterViewInit, OnInit, TemplateRef, AfterContentInit, Provider, ChangeDetectorRef, Signal, PipeTransform, ViewContainerRef, AfterViewChecked, ComponentRef } from '@angular/core';
3
+ import { ControlValueAccessor, NgControl, AbstractControl } from '@angular/forms';
4
4
  import { ComponentHarness, BaseHarnessFilters, HarnessPredicate, HarnessLoader } from '@angular/cdk/testing';
5
5
  import { SafeHtml, SafeResourceUrl, DomSanitizer } from '@angular/platform-browser';
6
6
  import { ComponentFixture } from '@angular/core/testing';
7
+ import * as _truenas_ui_components from '@truenas/ui-components';
7
8
  import { SelectionModel, DataSource } from '@angular/cdk/collections';
8
9
  import * as rxjs from 'rxjs';
9
10
  import { Observable } from 'rxjs';
@@ -14,6 +15,147 @@ import { Overlay } from '@angular/cdk/overlay';
14
15
  import { DialogRef, DialogConfig } from '@angular/cdk/dialog';
15
16
  import { ComponentType } from '@angular/cdk/portal';
16
17
 
18
+ /**
19
+ * Value shapes accepted as a test-id base.
20
+ *
21
+ * A consumer supplies the *semantic* part of a test id — a single token
22
+ * (`'save'`, `'username'`) or an ordered list of segments
23
+ * (`['username', option.value]`). The library owns the element-type prefix and
24
+ * the final string assembly; consumers never hand-craft the full id.
25
+ */
26
+ type TnTestIdValue = string | number | (string | number | null | undefined)[] | null | undefined;
27
+ /**
28
+ * Normalize one segment to a kebab-case token: split camelCase, lower-case,
29
+ * collapse any run of non-alphanumeric characters to a single hyphen, and trim
30
+ * leading/trailing hyphens.
31
+ *
32
+ * Mirrors the normalization webui's legacy `ixTest` directive applied via
33
+ * lodash `kebabCase`, so migrated values stay stable (`sshPort` → `ssh-port`,
34
+ * `addr_trtype` → `addr-trtype`, `'My Label'` → `my-label`).
35
+ */
36
+ declare function kebabTestSegment(part: string | number): string;
37
+ /**
38
+ * Scope a test-id base with one or more trailing suffix segments.
39
+ *
40
+ * Normalizes the base — a single token or an array of segments — into a flat
41
+ * segment array and appends the suffixes, producing a value that is itself a
42
+ * valid {@link TnTestIdValue}. This is the canonical "derive a per-child id from
43
+ * a parent base" operation, e.g. a dialog's close button (`[base, 'close']`) or
44
+ * a select's per-option id (`[base, option.label]`). Centralizing it keeps the
45
+ * `string | array` flattening contract in one place rather than re-implemented
46
+ * at each call site.
47
+ *
48
+ * Falsy segments are preserved here (not filtered) so `composeTestId` can apply
49
+ * its own drop/scoping rules — `scopeTestId(undefined, 'close')` yields
50
+ * `[undefined, 'close']`, which `composeTestId('button', …)` renders as the
51
+ * unscoped `button-close`.
52
+ *
53
+ * @example
54
+ * scopeTestId('actions', 'edit') // ['actions', 'edit']
55
+ * scopeTestId(['menu', 'main'], 'edit') // ['menu', 'main', 'edit']
56
+ * scopeTestId(undefined, 'close') // [undefined, 'close']
57
+ */
58
+ declare function scopeTestId(base: TnTestIdValue, ...suffix: (string | number | null | undefined)[]): (string | number | null | undefined)[];
59
+ /**
60
+ * Compose the canonical test-id string: `${type}-${...segments}`.
61
+ *
62
+ * - `type` is the element-type prefix the component declares (e.g. `'button'`,
63
+ * `'option'`, `'menu-item'`). Pass `null`/`undefined` for no prefix.
64
+ * - `value` is the consumer-provided base — a single token or an array of
65
+ * segments (used to scope dynamic/repeated children, e.g. `[base, item.id]`).
66
+ *
67
+ * Falsy/empty parts are dropped, every part is kebab-normalized, and parts are
68
+ * joined with `-`. Returns `''` when nothing usable remains — callers treat
69
+ * `''` as "render no attribute" (avoids `data-testid=""`).
70
+ *
71
+ * @example
72
+ * composeTestId('button', 'save') // 'button-save'
73
+ * composeTestId('option', ['username', 'Jane Doe'])// 'option-username-jane-doe'
74
+ * composeTestId('menu-item', [undefined, 'edit']) // 'menu-item-edit' (no base → unscoped)
75
+ * composeTestId('menu-item', ['actions', 'edit']) // 'menu-item-actions-edit'
76
+ * composeTestId(undefined, 'already-made') // 'already-made' (verbatim passthrough)
77
+ * composeTestId('button', 'button-first-page') // 'button-first-page' (idempotent — not doubled)
78
+ */
79
+ declare function composeTestId(type: string | null | undefined, value: TnTestIdValue): string;
80
+
81
+ /**
82
+ * Test-id attribute names supported by the library.
83
+ *
84
+ * - `'data-testid'` is the modern industry default and the library's out-of-the-box behavior.
85
+ * - `'data-test'` exists for consumers that have an established convention they don't want to disrupt
86
+ * (notably webui, which has thousands of selectors targeting `data-test`).
87
+ */
88
+ type TnTestAttrName = 'data-test' | 'data-testid';
89
+ /**
90
+ * Controls which attribute name the library renders `testId` values to.
91
+ *
92
+ * Defaults to `'data-testid'`. Consumers can override at the application root:
93
+ *
94
+ * ```ts
95
+ * bootstrapApplication(AppComponent, {
96
+ * providers: [
97
+ * { provide: TN_TEST_ATTR, useValue: 'data-test' },
98
+ * ],
99
+ * });
100
+ * ```
101
+ *
102
+ * Every component-level `testId` input and every `[tnTestId]` directive usage reads this token
103
+ * so that a single override switches the entire library consistently.
104
+ */
105
+ declare const TN_TEST_ATTR: InjectionToken<TnTestAttrName>;
106
+
107
+ /**
108
+ * Writes a composed `testId` value to whichever attribute name is configured via
109
+ * {@link TN_TEST_ATTR} (default `data-testid`).
110
+ *
111
+ * The library owns the whole id: the consumer passes only the *semantic* base
112
+ * (`tnTestId`), the component declares its element type (`tnTestIdType`), and
113
+ * this directive assembles `${type}-${base}` (kebab-cased, see
114
+ * {@link composeTestId}). When no `tnTestIdType` is set the value is written
115
+ * verbatim, so existing call sites are unaffected.
116
+ *
117
+ * @example
118
+ * ```html
119
+ * <!-- component-owned prefix: emits data-testid="button-save" -->
120
+ * <button [tnTestId]="'save'" tnTestIdType="button">Save</button>
121
+ *
122
+ * <!-- array base scopes a dynamic child: emits data-testid="option-username-jane-doe" -->
123
+ * <li [tnTestId]="['username', option.label]" tnTestIdType="option"></li>
124
+ *
125
+ * <!-- no type: written verbatim (legacy behavior) -->
126
+ * <button [tnTestId]="myTestId()">Click me</button>
127
+ * ```
128
+ *
129
+ * Falsy / empty results remove the attribute entirely (avoids `data-testid=""`).
130
+ */
131
+ declare class TnTestIdDirective {
132
+ private readonly renderer;
133
+ private readonly host;
134
+ private readonly attrName;
135
+ /** The semantic base value (token or ordered segments). Falsy parts are dropped. */
136
+ readonly testId: _angular_core.InputSignal<TnTestIdValue>;
137
+ /**
138
+ * Element-type prefix the component declares (e.g. `'button'`, `'option'`).
139
+ * Omit to write the base verbatim with no prefix.
140
+ */
141
+ readonly tnTestIdType: _angular_core.InputSignal<string | null | undefined>;
142
+ constructor();
143
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnTestIdDirective, never>;
144
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnTestIdDirective, "[tnTestId]", never, { "testId": { "alias": "tnTestId"; "required": false; "isSignal": true; }; "tnTestIdType": { "alias": "tnTestIdType"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
145
+ }
146
+
147
+ /**
148
+ * Apply a composed test-id string to `element`'s `attrName`, removing the
149
+ * attribute entirely when `composed` is empty (avoids `attr=""`).
150
+ *
151
+ * Shared by {@link TnTestIdDirective} and by components that must write the
152
+ * attribute imperatively because they also read their base back — notably
153
+ * `tn-table-pager`, where injecting a host directive to read its input signal
154
+ * is unreliable in the AOT-linked package build. Centralizing the set/remove
155
+ * branch keeps those write semantics in one place so they can't drift.
156
+ */
157
+ declare function writeTestId(renderer: Renderer2, element: Element, attrName: string, composed: string): void;
158
+
17
159
  declare class TnAutocompleteComponent<T = unknown> implements ControlValueAccessor, OnDestroy {
18
160
  private readonly elementRef;
19
161
  private readonly overlay;
@@ -50,7 +192,7 @@ declare class TnAutocompleteComponent<T = unknown> implements ControlValueAccess
50
192
  */
51
193
  panelMaxHeight: _angular_core.InputSignal<string | number>;
52
194
  /** Test ID attribute */
53
- testId: _angular_core.InputSignal<string>;
195
+ testId: _angular_core.InputSignal<TnTestIdValue>;
54
196
  /** Emits when an option is selected */
55
197
  optionSelected: _angular_core.OutputEmitterRef<T>;
56
198
  /** Reference to the input element */
@@ -289,113 +431,6 @@ interface AutocompleteHarnessFilters extends BaseHarnessFilters {
289
431
  placeholder?: string;
290
432
  }
291
433
 
292
- /**
293
- * Value shapes accepted as a test-id base.
294
- *
295
- * A consumer supplies the *semantic* part of a test id — a single token
296
- * (`'save'`, `'username'`) or an ordered list of segments
297
- * (`['username', option.value]`). The library owns the element-type prefix and
298
- * the final string assembly; consumers never hand-craft the full id.
299
- */
300
- type TnTestIdValue = string | number | (string | number | null | undefined)[] | null | undefined;
301
- /**
302
- * Normalize one segment to a kebab-case token: split camelCase, lower-case,
303
- * collapse any run of non-alphanumeric characters to a single hyphen, and trim
304
- * leading/trailing hyphens.
305
- *
306
- * Mirrors the normalization webui's legacy `ixTest` directive applied via
307
- * lodash `kebabCase`, so migrated values stay stable (`sshPort` → `ssh-port`,
308
- * `addr_trtype` → `addr-trtype`, `'My Label'` → `my-label`).
309
- */
310
- declare function kebabTestSegment(part: string | number): string;
311
- /**
312
- * Compose the canonical test-id string: `${type}-${...segments}`.
313
- *
314
- * - `type` is the element-type prefix the component declares (e.g. `'button'`,
315
- * `'option'`, `'menu-item'`). Pass `null`/`undefined` for no prefix.
316
- * - `value` is the consumer-provided base — a single token or an array of
317
- * segments (used to scope dynamic/repeated children, e.g. `[base, item.id]`).
318
- *
319
- * Falsy/empty parts are dropped, every part is kebab-normalized, and parts are
320
- * joined with `-`. Returns `''` when nothing usable remains — callers treat
321
- * `''` as "render no attribute" (avoids `data-testid=""`).
322
- *
323
- * @example
324
- * composeTestId('button', 'save') // 'button-save'
325
- * composeTestId('option', ['username', 'Jane Doe'])// 'option-username-jane-doe'
326
- * composeTestId('menu-item', [undefined, 'edit']) // 'menu-item-edit' (no base → unscoped)
327
- * composeTestId('menu-item', ['actions', 'edit']) // 'menu-item-actions-edit'
328
- * composeTestId(undefined, 'already-made') // 'already-made' (verbatim passthrough)
329
- * composeTestId('button', 'button-first-page') // 'button-first-page' (idempotent — not doubled)
330
- */
331
- declare function composeTestId(type: string | null | undefined, value: TnTestIdValue): string;
332
-
333
- /**
334
- * Test-id attribute names supported by the library.
335
- *
336
- * - `'data-testid'` is the modern industry default and the library's out-of-the-box behavior.
337
- * - `'data-test'` exists for consumers that have an established convention they don't want to disrupt
338
- * (notably webui, which has thousands of selectors targeting `data-test`).
339
- */
340
- type TnTestAttrName = 'data-test' | 'data-testid';
341
- /**
342
- * Controls which attribute name the library renders `testId` values to.
343
- *
344
- * Defaults to `'data-testid'`. Consumers can override at the application root:
345
- *
346
- * ```ts
347
- * bootstrapApplication(AppComponent, {
348
- * providers: [
349
- * { provide: TN_TEST_ATTR, useValue: 'data-test' },
350
- * ],
351
- * });
352
- * ```
353
- *
354
- * Every component-level `testId` input and every `[tnTestId]` directive usage reads this token
355
- * so that a single override switches the entire library consistently.
356
- */
357
- declare const TN_TEST_ATTR: InjectionToken<TnTestAttrName>;
358
-
359
- /**
360
- * Writes a composed `testId` value to whichever attribute name is configured via
361
- * {@link TN_TEST_ATTR} (default `data-testid`).
362
- *
363
- * The library owns the whole id: the consumer passes only the *semantic* base
364
- * (`tnTestId`), the component declares its element type (`tnTestIdType`), and
365
- * this directive assembles `${type}-${base}` (kebab-cased, see
366
- * {@link composeTestId}). When no `tnTestIdType` is set the value is written
367
- * verbatim, so existing call sites are unaffected.
368
- *
369
- * @example
370
- * ```html
371
- * <!-- component-owned prefix: emits data-testid="button-save" -->
372
- * <button [tnTestId]="'save'" tnTestIdType="button">Save</button>
373
- *
374
- * <!-- array base scopes a dynamic child: emits data-testid="option-username-jane-doe" -->
375
- * <li [tnTestId]="['username', option.label]" tnTestIdType="option"></li>
376
- *
377
- * <!-- no type: written verbatim (legacy behavior) -->
378
- * <button [tnTestId]="myTestId()">Click me</button>
379
- * ```
380
- *
381
- * Falsy / empty results remove the attribute entirely (avoids `data-testid=""`).
382
- */
383
- declare class TnTestIdDirective {
384
- private readonly renderer;
385
- private readonly host;
386
- private readonly attrName;
387
- /** The semantic base value (token or ordered segments). Falsy parts are dropped. */
388
- readonly testId: _angular_core.InputSignal<TnTestIdValue>;
389
- /**
390
- * Element-type prefix the component declares (e.g. `'button'`, `'option'`).
391
- * Omit to write the base verbatim with no prefix.
392
- */
393
- readonly tnTestIdType: _angular_core.InputSignal<string | null | undefined>;
394
- constructor();
395
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnTestIdDirective, never>;
396
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnTestIdDirective, "[tnTestId]", never, { "testId": { "alias": "tnTestId"; "required": false; "isSignal": true; }; "tnTestIdType": { "alias": "tnTestIdType"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
397
- }
398
-
399
434
  type TnDrawerMode = 'side' | 'over';
400
435
  type TnDrawerPosition = 'start' | 'end';
401
436
  declare class TnDrawerComponent implements OnDestroy {
@@ -828,6 +863,14 @@ declare class TnIconComponent {
828
863
  tooltip: _angular_core.InputSignal<string | undefined>;
829
864
  ariaLabel: _angular_core.InputSignal<string | undefined>;
830
865
  library: _angular_core.InputSignal<IconLibraryType | undefined>;
866
+ /**
867
+ * Semantic test-id base for the icon. The library prepends the element type
868
+ * (`icon`) and renders the result under whichever attribute name is configured
869
+ * via `TN_TEST_ATTR` (default `data-testid`) — e.g. `testId="close"` →
870
+ * `icon-close`. Accepts an array of segments to scope the id (e.g.
871
+ * `['tooltip', header()]`). Unset emits no attribute.
872
+ */
873
+ testId: _angular_core.InputSignal<TnTestIdValue>;
831
874
  /**
832
875
  * When true, the icon will expand to fill its container (100% width and height)
833
876
  * instead of using the fixed size from the `size` input.
@@ -859,7 +902,7 @@ declare class TnIconComponent {
859
902
  */
860
903
  private warnMissingSpriteIcon;
861
904
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnIconComponent, never>;
862
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnIconComponent, "tn-icon", never, { "name": { "alias": "name"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "tooltip": { "alias": "tooltip"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "library": { "alias": "library"; "required": false; "isSignal": true; }; "fullSize": { "alias": "fullSize"; "required": false; "isSignal": true; }; "customSize": { "alias": "customSize"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
905
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnIconComponent, "tn-icon", never, { "name": { "alias": "name"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "tooltip": { "alias": "tooltip"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "library": { "alias": "library"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; "fullSize": { "alias": "fullSize"; "required": false; "isSignal": true; }; "customSize": { "alias": "customSize"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
863
906
  }
864
907
 
865
908
  type TooltipPosition = 'above' | 'below' | 'left' | 'right' | 'before' | 'after';
@@ -1234,6 +1277,7 @@ declare class TnIconHarness extends ComponentHarness {
1234
1277
  * ```
1235
1278
  */
1236
1279
  static with(options?: IconHarnessFilters): HarnessPredicate<TnIconHarness>;
1280
+ private root;
1237
1281
  /**
1238
1282
  * Gets the icon name.
1239
1283
  *
@@ -1337,6 +1381,18 @@ declare class TnIconHarness extends ComponentHarness {
1337
1381
  * ```
1338
1382
  */
1339
1383
  click(): Promise<void>;
1384
+ /**
1385
+ * Gets the composed test-id attribute value (e.g. `icon-close`).
1386
+ *
1387
+ * @returns Promise resolving to the test-id string, or null when unset.
1388
+ *
1389
+ * @example
1390
+ * ```typescript
1391
+ * const icon = await loader.getHarness(TnIconHarness);
1392
+ * expect(await icon.getTestId()).toBe('icon-close');
1393
+ * ```
1394
+ */
1395
+ getTestId(): Promise<string | null>;
1340
1396
  }
1341
1397
  /**
1342
1398
  * A set of criteria that can be used to filter a list of `TnIconHarness` instances.
@@ -1352,6 +1408,8 @@ interface IconHarnessFilters extends BaseHarnessFilters {
1352
1408
  fullSize?: boolean;
1353
1409
  /** Filters by custom size value. */
1354
1410
  customSize?: string;
1411
+ /** Filters by composed test-id value (e.g. `icon-close`). */
1412
+ testId?: string;
1355
1413
  }
1356
1414
 
1357
1415
  /**
@@ -1628,7 +1686,12 @@ declare class TnMenuItemComponent {
1628
1686
  shortcut: _angular_core.InputSignal<string | undefined>;
1629
1687
  disabled: _angular_core.InputSignal<boolean>;
1630
1688
  selected: _angular_core.InputSignal<boolean>;
1631
- testId: _angular_core.InputSignal<string | undefined>;
1689
+ /**
1690
+ * Semantic test-id base. Accepts a single token or an array of segments
1691
+ * (e.g. `['format', format]`) to scope dynamic/repeated items. The owning
1692
+ * `<tn-menu-panel>` prepends the `button` element type.
1693
+ */
1694
+ testId: _angular_core.InputSignal<TnTestIdValue>;
1632
1695
  itemClick: _angular_core.OutputEmitterRef<MouseEvent>;
1633
1696
  /** Template capturing whatever the consumer projected as item content. */
1634
1697
  content: _angular_core.Signal<TemplateRef<unknown>>;
@@ -1639,7 +1702,7 @@ declare class TnMenuItemComponent {
1639
1702
  * an already-`button-`-prefixed value is not doubled). Returns `undefined`
1640
1703
  * when neither is set, which composes to no attribute.
1641
1704
  */
1642
- resolvedTestId: _angular_core.Signal<string | undefined>;
1705
+ resolvedTestId: _angular_core.Signal<string | number | (string | number | null | undefined)[] | undefined>;
1643
1706
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnMenuItemComponent, never>;
1644
1707
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnMenuItemComponent, "tn-menu-item", never, { "id": { "alias": "id"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "iconLibrary": { "alias": "iconLibrary"; "required": false; "isSignal": true; }; "shortcut": { "alias": "shortcut"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; }, { "itemClick": "itemClick"; }, never, ["*"], true, never>;
1645
1708
  }
@@ -1671,7 +1734,7 @@ declare class TnMenuActivateHoverDirective implements AfterContentInit {
1671
1734
  interface TnMenuItem {
1672
1735
  id: string;
1673
1736
  label: string;
1674
- testId?: string;
1737
+ testId?: TnTestIdValue;
1675
1738
  icon?: string;
1676
1739
  iconLibrary?: 'material' | 'mdi' | 'custom' | 'lucide';
1677
1740
  disabled?: boolean;
@@ -1698,7 +1761,7 @@ declare class TnMenuComponent implements OnDestroy {
1698
1761
  * composed with the same `button-` prefix (idempotently, so an already
1699
1762
  * `button-`-prefixed value is not doubled).
1700
1763
  */
1701
- testId: _angular_core.InputSignal<string | undefined>;
1764
+ testId: _angular_core.InputSignal<TnTestIdValue>;
1702
1765
  menuItemClick: _angular_core.OutputEmitterRef<TnMenuItem>;
1703
1766
  menuOpen: _angular_core.OutputEmitterRef<void>;
1704
1767
  menuClose: _angular_core.OutputEmitterRef<void>;
@@ -3098,19 +3161,106 @@ declare class TnFormFieldComponent implements AfterContentInit {
3098
3161
  tooltip: _angular_core.InputSignal<string>;
3099
3162
  /** Placement of the tooltip relative to its help icon. */
3100
3163
  tooltipPosition: _angular_core.InputSignal<TooltipPosition>;
3164
+ /**
3165
+ * Per-field overrides for validation messages, keyed by error key. Values may
3166
+ * be a string or a function that receives the error's detail value. Takes
3167
+ * precedence over the app-wide {@link TN_FORM_FIELD_ERRORS} resolver and the
3168
+ * built-in defaults.
3169
+ */
3170
+ errorMessages: _angular_core.InputSignal<Partial<Record<string, _truenas_ui_components.TnFormFieldErrorMessage>>>;
3101
3171
  control: _angular_core.Signal<NgControl | undefined>;
3102
- protected hasError: _angular_core.WritableSignal<boolean>;
3103
- protected errorMessage: _angular_core.WritableSignal<string>;
3172
+ private destroyRef;
3173
+ /**
3174
+ * App-wide message resolver, captured once at construction. Unlike the
3175
+ * `errorMessages` input it is not reactive — swapping the provided function at
3176
+ * runtime will not be picked up by an already-created field.
3177
+ */
3178
+ private errorResolver;
3179
+ /**
3180
+ * Snapshot of the relevant control state. Updated from the control's status
3181
+ * stream because `NgControl` itself is not signal-based; downstream `computed`s
3182
+ * read this so the derived state stays reactive.
3183
+ */
3184
+ private controlState;
3185
+ protected hasError: _angular_core.Signal<boolean>;
3186
+ protected errorMessage: _angular_core.Signal<string>;
3104
3187
  ngAfterContentInit(): void;
3105
- private updateErrorState;
3106
- private getErrorMessage;
3188
+ private syncControlState;
3189
+ /**
3190
+ * Resolves a user-facing message for the active error. Reads the
3191
+ * `errorMessages` input (and the injected resolver), so it is reactive: the
3192
+ * displayed message updates when either the control errors or the overrides
3193
+ * change — e.g. a runtime locale switch.
3194
+ */
3195
+ private resolveErrorMessage;
3196
+ /**
3197
+ * Runs a caller-supplied message provider, swallowing any throw so a buggy
3198
+ * override or resolver cannot break change detection. Logs in dev mode and
3199
+ * returns null so resolution falls through to the next layer.
3200
+ */
3201
+ private runGuarded;
3107
3202
  showError: _angular_core.Signal<boolean>;
3108
3203
  showHint: _angular_core.Signal<boolean>;
3109
3204
  protected showSubscript: _angular_core.Signal<boolean>;
3110
3205
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnFormFieldComponent, never>;
3111
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnFormFieldComponent, "tn-form-field", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; "subscriptSizing": { "alias": "subscriptSizing"; "required": false; "isSignal": true; }; "tooltip": { "alias": "tooltip"; "required": false; "isSignal": true; }; "tooltipPosition": { "alias": "tooltipPosition"; "required": false; "isSignal": true; }; }, {}, ["control"], ["*"], true, never>;
3206
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnFormFieldComponent, "tn-form-field", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; "subscriptSizing": { "alias": "subscriptSizing"; "required": false; "isSignal": true; }; "tooltip": { "alias": "tooltip"; "required": false; "isSignal": true; }; "tooltipPosition": { "alias": "tooltipPosition"; "required": false; "isSignal": true; }; "errorMessages": { "alias": "errorMessages"; "required": false; "isSignal": true; }; }, {}, ["control"], ["*"], true, never>;
3112
3207
  }
3113
3208
 
3209
+ /**
3210
+ * A user-friendly message for a single validation error, or a function that
3211
+ * builds one from the error's detail value.
3212
+ *
3213
+ * The function form receives the error value Angular stored for that key, which
3214
+ * lets you interpolate validator metadata, e.g.
3215
+ * `minlength: (e) => \`At least ${e.requiredLength} characters\``.
3216
+ */
3217
+ type TnFormFieldErrorMessage = string | ((errorValue: unknown) => string);
3218
+ /**
3219
+ * A per-field map of validation error key -> message (or message factory).
3220
+ *
3221
+ * @example
3222
+ * ```html
3223
+ * <tn-form-field [errorMessages]="{
3224
+ * required: 'Please enter a name',
3225
+ * pattern: 'Letters only',
3226
+ * minlength: messageFn
3227
+ * }">
3228
+ * ```
3229
+ */
3230
+ type TnFormFieldErrorMessages = Partial<Record<string, TnFormFieldErrorMessage>>;
3231
+ /**
3232
+ * App-wide resolver for validation messages. Register one with the
3233
+ * {@link TN_FORM_FIELD_ERRORS} token to centralize wording and i18n.
3234
+ *
3235
+ * Return a string to provide a message, or `null`/`undefined` to defer to the
3236
+ * next layer (built-in defaults, then the raw error key).
3237
+ *
3238
+ * @param errorKey The active validation error key (e.g. `'required'`).
3239
+ * @param errorValue The value Angular stored for that key.
3240
+ * @param control The control that failed validation, if available.
3241
+ */
3242
+ type TnFormFieldErrorResolver = (errorKey: string, errorValue: unknown, control: AbstractControl | null) => string | null | undefined;
3243
+ /**
3244
+ * Injection token for an app-wide {@link TnFormFieldErrorResolver}.
3245
+ *
3246
+ * Because the library ships no localized strings, this is the recommended hook
3247
+ * for wiring a translation service so every `tn-form-field` resolves messages
3248
+ * consistently. Per-field `errorMessages` still take precedence over it.
3249
+ *
3250
+ * @example
3251
+ * ```ts
3252
+ * providers: [
3253
+ * {
3254
+ * provide: TN_FORM_FIELD_ERRORS,
3255
+ * useFactory: (translate: TranslateService): TnFormFieldErrorResolver =>
3256
+ * (key, value) => translate.instant(`errors.${key}`, value as object),
3257
+ * deps: [TranslateService],
3258
+ * },
3259
+ * ];
3260
+ * ```
3261
+ */
3262
+ declare const TN_FORM_FIELD_ERRORS: InjectionToken<TnFormFieldErrorResolver>;
3263
+
3114
3264
  /**
3115
3265
  * Harness for interacting with `tn-form-field` in tests.
3116
3266
  * Provides methods for querying label, hint, error state, and accessing
@@ -3322,7 +3472,7 @@ declare class TnSelectComponent<T = unknown> implements ControlValueAccessor, On
3322
3472
  */
3323
3473
  noOptionsLabel: _angular_core.InputSignal<string>;
3324
3474
  disabled: _angular_core.InputSignal<boolean>;
3325
- testId: _angular_core.InputSignal<string>;
3475
+ testId: _angular_core.InputSignal<TnTestIdValue>;
3326
3476
  multiple: _angular_core.InputSignal<boolean>;
3327
3477
  /**
3328
3478
  * Optional extractor for the per-option test-id discriminator. Defaults to
@@ -4610,7 +4760,22 @@ interface TnTableDataProvider {
4610
4760
  */
4611
4761
  declare class TnTablePagerComponent {
4612
4762
  private destroyRef;
4613
- private readonly testIdDirective;
4763
+ private renderer;
4764
+ private hostRef;
4765
+ private testAttrName;
4766
+ /**
4767
+ * Semantic base applied to the host (via the `tnTestId` host directive) and
4768
+ * used to scope each child control, so multiple pagers on one page don't
4769
+ * collide on `select-page-size` / `button-first-page`. With a base of
4770
+ * `storage` the children become `select-storage-page-size`,
4771
+ * `button-storage-first-page`, etc.; with no base they stay
4772
+ * `select-page-size` / `button-first-page`.
4773
+ *
4774
+ * The page-size dropdown also scopes each option by its value, so individual
4775
+ * sizes are addressable: `option-page-size-10` / `-20` / `-50` / `-100` (or
4776
+ * `option-storage-page-size-10` under a base).
4777
+ */
4778
+ testId: _angular_core.InputSignal<TnTestIdValue>;
4614
4779
  /**
4615
4780
  * Build a child control's test-id base by joining the pager's `testId` with
4616
4781
  * `suffix` into a single string (kebab-joined). Returning a string keeps it
@@ -4709,7 +4874,7 @@ declare class TnTablePagerComponent {
4709
4874
  /** Forwards the current page/size to the data provider, if one is bound. */
4710
4875
  private pushToProvider;
4711
4876
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnTablePagerComponent, never>;
4712
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnTablePagerComponent, "tn-table-pager", never, { "currentPage": { "alias": "currentPage"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "totalItems": { "alias": "totalItems"; "required": false; "isSignal": true; }; "dataProvider": { "alias": "dataProvider"; "required": false; "isSignal": true; }; "itemsPerPageLabel": { "alias": "itemsPerPageLabel"; "required": false; "isSignal": true; }; "ofLabel": { "alias": "ofLabel"; "required": false; "isSignal": true; }; "firstPageLabel": { "alias": "firstPageLabel"; "required": false; "isSignal": true; }; "previousPageLabel": { "alias": "previousPageLabel"; "required": false; "isSignal": true; }; "nextPageLabel": { "alias": "nextPageLabel"; "required": false; "isSignal": true; }; "lastPageLabel": { "alias": "lastPageLabel"; "required": false; "isSignal": true; }; "tablePaginationLabel": { "alias": "tablePaginationLabel"; "required": false; "isSignal": true; }; }, { "currentPage": "currentPageChange"; "pageSize": "pageSizeChange"; "pageChange": "pageChange"; "pageSizeChange": "pageSizeChange"; }, never, never, true, [{ directive: typeof TnTestIdDirective; inputs: { "tnTestId": "testId"; }; outputs: {}; }]>;
4877
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnTablePagerComponent, "tn-table-pager", never, { "testId": { "alias": "testId"; "required": false; "isSignal": true; }; "currentPage": { "alias": "currentPage"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "totalItems": { "alias": "totalItems"; "required": false; "isSignal": true; }; "dataProvider": { "alias": "dataProvider"; "required": false; "isSignal": true; }; "itemsPerPageLabel": { "alias": "itemsPerPageLabel"; "required": false; "isSignal": true; }; "ofLabel": { "alias": "ofLabel"; "required": false; "isSignal": true; }; "firstPageLabel": { "alias": "firstPageLabel"; "required": false; "isSignal": true; }; "previousPageLabel": { "alias": "previousPageLabel"; "required": false; "isSignal": true; }; "nextPageLabel": { "alias": "nextPageLabel"; "required": false; "isSignal": true; }; "lastPageLabel": { "alias": "lastPageLabel"; "required": false; "isSignal": true; }; "tablePaginationLabel": { "alias": "tablePaginationLabel"; "required": false; "isSignal": true; }; }, { "currentPage": "currentPageChange"; "pageSize": "pageSizeChange"; "pageChange": "pageChange"; "pageSizeChange": "pageSizeChange"; }, never, never, true, never>;
4713
4878
  }
4714
4879
 
4715
4880
  /**
@@ -5176,7 +5341,7 @@ declare class TnDateRangeInputComponent implements ControlValueAccessor, OnInit,
5176
5341
  * Test-id applied to the date-range-input container. Rendered under whichever attribute name
5177
5342
  * is configured via `TN_TEST_ATTR` (default `data-testid`).
5178
5343
  */
5179
- testId: _angular_core.InputSignal<string | undefined>;
5344
+ testId: _angular_core.InputSignal<TnTestIdValue>;
5180
5345
  private formDisabled;
5181
5346
  isDisabled: _angular_core.Signal<boolean>;
5182
5347
  startMonthRef: _angular_core.Signal<ElementRef<HTMLInputElement>>;
@@ -5381,7 +5546,7 @@ declare class TnDateInputComponent implements ControlValueAccessor, OnInit, OnDe
5381
5546
  * Test-id applied to the date-input container. Rendered under whichever attribute name
5382
5547
  * is configured via `TN_TEST_ATTR` (default `data-testid`).
5383
5548
  */
5384
- testId: _angular_core.InputSignal<string | undefined>;
5549
+ testId: _angular_core.InputSignal<TnTestIdValue>;
5385
5550
  private formDisabled;
5386
5551
  isDisabled: _angular_core.Signal<boolean>;
5387
5552
  monthRef: _angular_core.Signal<ElementRef<HTMLInputElement>>;
@@ -5621,7 +5786,7 @@ declare class TnTimeInputComponent implements ControlValueAccessor {
5621
5786
  format: _angular_core.InputSignal<"12h" | "24h">;
5622
5787
  granularity: _angular_core.InputSignal<"15m" | "30m" | "1h">;
5623
5788
  placeholder: _angular_core.InputSignal<string>;
5624
- testId: _angular_core.InputSignal<string>;
5789
+ testId: _angular_core.InputSignal<TnTestIdValue>;
5625
5790
  private formDisabled;
5626
5791
  isDisabled: _angular_core.Signal<boolean>;
5627
5792
  private step;
@@ -6061,7 +6226,11 @@ declare class TnDialogShellComponent implements OnInit {
6061
6226
  * or `button-<testId>-close` / `-fullscreen` when a base is provided (useful
6062
6227
  * when more than one dialog can be open).
6063
6228
  */
6064
- testId: _angular_core.InputSignal<string | undefined>;
6229
+ testId: _angular_core.InputSignal<TnTestIdValue>;
6230
+ /** Scoped test-id segments for the close button (`button-[<base>-]close`). */
6231
+ protected closeTestId: _angular_core.Signal<(string | number | null | undefined)[]>;
6232
+ /** Scoped test-id segments for the fullscreen button (`button-[<base>-]fullscreen`). */
6233
+ protected fullscreenTestId: _angular_core.Signal<(string | number | null | undefined)[]>;
6065
6234
  /** Stable id for the title heading, referenced by the dialog's aria-labelledby. */
6066
6235
  readonly titleId: string;
6067
6236
  isFullscreen: _angular_core.WritableSignal<boolean>;
@@ -6324,7 +6493,7 @@ declare class TnSidePanelComponent implements OnDestroy {
6324
6493
  * Test-id applied to the panel's root overlay element. Rendered under whichever attribute
6325
6494
  * name is configured via `TN_TEST_ATTR` (default `data-testid`).
6326
6495
  */
6327
- testId: _angular_core.InputSignal<string | undefined>;
6496
+ testId: _angular_core.InputSignal<TnTestIdValue>;
6328
6497
  /**
6329
6498
  * Test-id applied to the panel's close (×) button.
6330
6499
  */
@@ -6439,7 +6608,7 @@ declare class TnFilePickerComponent implements ControlValueAccessor, OnInit, OnD
6439
6608
  * Test-id applied to the file-picker container. Rendered under whichever attribute name
6440
6609
  * is configured via `TN_TEST_ATTR` (default `data-testid`).
6441
6610
  */
6442
- testId: _angular_core.InputSignal<string | undefined>;
6611
+ testId: _angular_core.InputSignal<TnTestIdValue>;
6443
6612
  startPath: _angular_core.InputSignal<string>;
6444
6613
  rootPath: _angular_core.InputSignal<string | undefined>;
6445
6614
  fileExtensions: _angular_core.InputSignal<string[] | undefined>;
@@ -7144,5 +7313,5 @@ declare const TN_THEME_DEFINITIONS: readonly TnThemeDefinition[];
7144
7313
  */
7145
7314
  declare const THEME_MAP: Map<TnTheme, TnThemeDefinition>;
7146
7315
 
7147
- export { CommonShortcuts, DEFAULT_THEME, DiskIconComponent, DiskType, FileSizePipe, InputType, LIGHT_THEME, LinuxModifierKeys, LinuxShortcuts, ModifierKeys, QuickShortcuts, ShortcutBuilder, StripMntPrefixPipe, THEME_MAP, THEME_STORAGE_KEY, TN_TABLE_PAGER_DEFAULT_LABELS, TN_TABLE_PAGER_LABELS, TN_TEST_ATTR, TN_THEME_DEFINITIONS, TnAutocompleteComponent, TnAutocompleteHarness, TnBannerActionDirective, TnBannerComponent, TnBannerHarness, TnBrandedSpinnerComponent, TnButtonComponent, TnButtonHarness, TnButtonToggleComponent, TnButtonToggleGroupComponent, TnButtonToggleGroupHarness, TnButtonToggleHarness, TnCalendarComponent, TnCalendarHeaderComponent, TnCardComponent, TnCardHeaderDirective, TnCellDefDirective, TnCheckboxComponent, TnCheckboxHarness, TnCheckboxLabelDirective, TnChipComponent, TnConfirmDialogComponent, TnDateInputComponent, TnDateInputHarness, TnDateRangeInputComponent, TnDateRangeInputHarness, TnDetailRowDefDirective, TnDialog, TnDialogHarness, TnDialogShellComponent, TnDialogTesting, TnDividerComponent, TnDividerDirective, TnDrawerComponent, TnDrawerContainerComponent, TnDrawerContainerHarness, TnDrawerContentComponent, TnDrawerHarness, TnEmptyComponent, TnEmptyHarness, TnExpansionPanelComponent, TnExpansionPanelHarness, TnFilePickerComponent, TnFilePickerPopupComponent, TnFormFieldComponent, TnFormFieldHarness, TnHeaderCellDefDirective, TnIconButtonComponent, TnIconButtonHarness, TnIconComponent, TnIconHarness, TnIconRegistryService, TnIconTesting, TnInputComponent, TnInputDirective, TnInputHarness, TnKeyboardShortcutComponent, TnKeyboardShortcutService, TnListAvatarDirective, TnListComponent, TnListIconDirective, TnListItemComponent, TnListItemLineDirective, TnListItemPrimaryDirective, TnListItemSecondaryDirective, TnListItemTitleDirective, TnListItemTrailingDirective, TnListOptionComponent, TnListSubheaderComponent, TnMenuActivateHoverDirective, TnMenuComponent, TnMenuHarness, TnMenuItemComponent, TnMenuTesting, TnMenuTriggerDirective, TnMonthViewComponent, TnMultiYearViewComponent, TnNestedTreeNodeComponent, TnParticleProgressBarComponent, TnProgressBarComponent, TnRadioComponent, TnRadioHarness, TnSelectComponent, TnSelectHarness, TnSelectionListComponent, TnSidePanelActionDirective, TnSidePanelComponent, TnSidePanelHarness, TnSidePanelHeaderActionDirective, TnSlideToggleComponent, TnSlideToggleHarness, TnSliderComponent, TnSliderThumbDirective, TnSliderWithLabelDirective, TnSpinnerComponent, TnSpriteLoaderService, TnStepComponent, TnStepperComponent, TnTabComponent, TnTabHarness, TnTabPanelComponent, TnTabPanelHarness, TnTableColumnDirective, TnTableComponent, TnTableHarness, TnTablePagerComponent, TnTablePagerHarness, TnTabsComponent, TnTabsHarness, TnTestIdDirective, TnTheme, TnThemeService, TnTimeInputComponent, TnToastComponent, TnToastMock, TnToastPosition, TnToastRef, TnToastService, TnToastTesting, TnToastType, TnTooltipComponent, TnTooltipDirective, TnTreeComponent, TnTreeFlatDataSource, TnTreeFlattener, TnTreeNodeComponent, TnTreeNodeOutletDirective, TruncatePathPipe, WindowsModifierKeys, WindowsShortcuts, composeTestId, createLucideLibrary, createShortcut, defaultSpriteBasePath, defaultSpriteConfigPath, kebabTestSegment, libIconMarker, registerLucideIcons, setupLucideIntegration, tnIconMarker };
7148
- export type { AutocompleteHarnessFilters, BannerHarnessFilters, ButtonHarnessFilters, ButtonToggleHarnessFilters, CalendarCell, CheckboxHarnessFilters, ChipColor, CreateFolderEvent, DateInputHarnessFilters, DateRange, DateRangeInputHarnessFilters, DialogHarnessFilters, EmptyHarnessFilters, ExpansionPanelHarnessFilters, FilePickerCallbacks, FilePickerError, FilePickerMode, FileSystemItem, FormFieldHarnessFilters, IconButtonHarnessFilters, IconHarnessFilters, IconLibrary, IconLibraryType, IconResult, IconSize, IconSource, IconTestingMockOverrides, InputHarnessFilters, KeyCombination, LabelType, LucideIconOptions, MenuHarnessFilters, MockIconRegistry, MockSpriteLoader, PathSegment, PlatformType, ProgressBarMode, RadioHarnessFilters, ResolvedIcon, SelectHarnessFilters, ShortcutHandler, SidePanelHarnessFilters, SlideToggleColor, SlideToggleHarnessFilters, SpinnerMode, SpriteConfig, SubscriptSizing, TabChangeEvent, TabHarnessFilters, TabPanelHarnessFilters, TabsHarnessFilters, TnBannerType, TnButtonToggleType, TnCardAction, TnCardControl, TnCardFooterLink, TnCardHeaderStatus, TnConfirmDialogData, TnDialogDefaults, TnDialogOpenTarget, TnDrawerMode, TnDrawerPosition, TnEmptySize, TnFlatTreeNode, TnMenuItem, TnSelectOption, TnSelectOptionGroup, TnSelectionChange, TnSortEvent, TnTableDataProvider, TnTableDataSource, TnTableHarnessFilters, TnTablePagerHarnessFilters, TnTablePagerLabels, TnTablePagination, TnTestAttrName, TnTestIdValue, TnThemeDefinition, TnToastCall, TnToastConfig, TooltipPosition, YearCell };
7316
+ export { CommonShortcuts, DEFAULT_THEME, DiskIconComponent, DiskType, FileSizePipe, InputType, LIGHT_THEME, LinuxModifierKeys, LinuxShortcuts, ModifierKeys, QuickShortcuts, ShortcutBuilder, StripMntPrefixPipe, THEME_MAP, THEME_STORAGE_KEY, TN_FORM_FIELD_ERRORS, TN_TABLE_PAGER_DEFAULT_LABELS, TN_TABLE_PAGER_LABELS, TN_TEST_ATTR, TN_THEME_DEFINITIONS, TnAutocompleteComponent, TnAutocompleteHarness, TnBannerActionDirective, TnBannerComponent, TnBannerHarness, TnBrandedSpinnerComponent, TnButtonComponent, TnButtonHarness, TnButtonToggleComponent, TnButtonToggleGroupComponent, TnButtonToggleGroupHarness, TnButtonToggleHarness, TnCalendarComponent, TnCalendarHeaderComponent, TnCardComponent, TnCardHeaderDirective, TnCellDefDirective, TnCheckboxComponent, TnCheckboxHarness, TnCheckboxLabelDirective, TnChipComponent, TnConfirmDialogComponent, TnDateInputComponent, TnDateInputHarness, TnDateRangeInputComponent, TnDateRangeInputHarness, TnDetailRowDefDirective, TnDialog, TnDialogHarness, TnDialogShellComponent, TnDialogTesting, TnDividerComponent, TnDividerDirective, TnDrawerComponent, TnDrawerContainerComponent, TnDrawerContainerHarness, TnDrawerContentComponent, TnDrawerHarness, TnEmptyComponent, TnEmptyHarness, TnExpansionPanelComponent, TnExpansionPanelHarness, TnFilePickerComponent, TnFilePickerPopupComponent, TnFormFieldComponent, TnFormFieldHarness, TnHeaderCellDefDirective, TnIconButtonComponent, TnIconButtonHarness, TnIconComponent, TnIconHarness, TnIconRegistryService, TnIconTesting, TnInputComponent, TnInputDirective, TnInputHarness, TnKeyboardShortcutComponent, TnKeyboardShortcutService, TnListAvatarDirective, TnListComponent, TnListIconDirective, TnListItemComponent, TnListItemLineDirective, TnListItemPrimaryDirective, TnListItemSecondaryDirective, TnListItemTitleDirective, TnListItemTrailingDirective, TnListOptionComponent, TnListSubheaderComponent, TnMenuActivateHoverDirective, TnMenuComponent, TnMenuHarness, TnMenuItemComponent, TnMenuTesting, TnMenuTriggerDirective, TnMonthViewComponent, TnMultiYearViewComponent, TnNestedTreeNodeComponent, TnParticleProgressBarComponent, TnProgressBarComponent, TnRadioComponent, TnRadioHarness, TnSelectComponent, TnSelectHarness, TnSelectionListComponent, TnSidePanelActionDirective, TnSidePanelComponent, TnSidePanelHarness, TnSidePanelHeaderActionDirective, TnSlideToggleComponent, TnSlideToggleHarness, TnSliderComponent, TnSliderThumbDirective, TnSliderWithLabelDirective, TnSpinnerComponent, TnSpriteLoaderService, TnStepComponent, TnStepperComponent, TnTabComponent, TnTabHarness, TnTabPanelComponent, TnTabPanelHarness, TnTableColumnDirective, TnTableComponent, TnTableHarness, TnTablePagerComponent, TnTablePagerHarness, TnTabsComponent, TnTabsHarness, TnTestIdDirective, TnTheme, TnThemeService, TnTimeInputComponent, TnToastComponent, TnToastMock, TnToastPosition, TnToastRef, TnToastService, TnToastTesting, TnToastType, TnTooltipComponent, TnTooltipDirective, TnTreeComponent, TnTreeFlatDataSource, TnTreeFlattener, TnTreeNodeComponent, TnTreeNodeOutletDirective, TruncatePathPipe, WindowsModifierKeys, WindowsShortcuts, composeTestId, createLucideLibrary, createShortcut, defaultSpriteBasePath, defaultSpriteConfigPath, kebabTestSegment, libIconMarker, registerLucideIcons, scopeTestId, setupLucideIntegration, tnIconMarker, writeTestId };
7317
+ export type { AutocompleteHarnessFilters, BannerHarnessFilters, ButtonHarnessFilters, ButtonToggleHarnessFilters, CalendarCell, CheckboxHarnessFilters, ChipColor, CreateFolderEvent, DateInputHarnessFilters, DateRange, DateRangeInputHarnessFilters, DialogHarnessFilters, EmptyHarnessFilters, ExpansionPanelHarnessFilters, FilePickerCallbacks, FilePickerError, FilePickerMode, FileSystemItem, FormFieldHarnessFilters, IconButtonHarnessFilters, IconHarnessFilters, IconLibrary, IconLibraryType, IconResult, IconSize, IconSource, IconTestingMockOverrides, InputHarnessFilters, KeyCombination, LabelType, LucideIconOptions, MenuHarnessFilters, MockIconRegistry, MockSpriteLoader, PathSegment, PlatformType, ProgressBarMode, RadioHarnessFilters, ResolvedIcon, SelectHarnessFilters, ShortcutHandler, SidePanelHarnessFilters, SlideToggleColor, SlideToggleHarnessFilters, SpinnerMode, SpriteConfig, SubscriptSizing, TabChangeEvent, TabHarnessFilters, TabPanelHarnessFilters, TabsHarnessFilters, TnBannerType, TnButtonToggleType, TnCardAction, TnCardControl, TnCardFooterLink, TnCardHeaderStatus, TnConfirmDialogData, TnDialogDefaults, TnDialogOpenTarget, TnDrawerMode, TnDrawerPosition, TnEmptySize, TnFlatTreeNode, TnFormFieldErrorMessage, TnFormFieldErrorMessages, TnFormFieldErrorResolver, TnMenuItem, TnSelectOption, TnSelectOptionGroup, TnSelectionChange, TnSortEvent, TnTableDataProvider, TnTableDataSource, TnTableHarnessFilters, TnTablePagerHarnessFilters, TnTablePagerLabels, TnTablePagination, TnTestAttrName, TnTestIdValue, TnThemeDefinition, TnToastCall, TnToastConfig, TooltipPosition, YearCell };