@truenas/ui-components 0.1.2

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.
Files changed (62) hide show
  1. package/README.md +335 -0
  2. package/assets/tn-icons/custom/cloud-off.svg +1 -0
  3. package/assets/tn-icons/custom/dataset-root.svg +3 -0
  4. package/assets/tn-icons/custom/dataset.svg +3 -0
  5. package/assets/tn-icons/custom/enclosure.svg +21 -0
  6. package/assets/tn-icons/custom/ha-disabled.svg +10 -0
  7. package/assets/tn-icons/custom/ha-enabled.svg +1 -0
  8. package/assets/tn-icons/custom/ha-reconnecting.svg +10 -0
  9. package/assets/tn-icons/custom/hdd-mirror.svg +3 -0
  10. package/assets/tn-icons/custom/hdd.svg +3 -0
  11. package/assets/tn-icons/custom/iscsi-share.svg +3 -0
  12. package/assets/tn-icons/custom/layout-full.svg +8 -0
  13. package/assets/tn-icons/custom/layout-half-and-quarters.svg +7 -0
  14. package/assets/tn-icons/custom/layout-halves.svg +6 -0
  15. package/assets/tn-icons/custom/layout-quarters-and-half.svg +7 -0
  16. package/assets/tn-icons/custom/layout-quarters.svg +8 -0
  17. package/assets/tn-icons/custom/network-upload-download-both.svg +4 -0
  18. package/assets/tn-icons/custom/network-upload-download-disabled.svg +7 -0
  19. package/assets/tn-icons/custom/network-upload-download-down.svg +4 -0
  20. package/assets/tn-icons/custom/network-upload-download-up.svg +4 -0
  21. package/assets/tn-icons/custom/network-upload-download.svg +4 -0
  22. package/assets/tn-icons/custom/nfs-share.svg +3 -0
  23. package/assets/tn-icons/custom/nvme-share.svg +7 -0
  24. package/assets/tn-icons/custom/replication.svg +14 -0
  25. package/assets/tn-icons/custom/smb-share.svg +3 -0
  26. package/assets/tn-icons/custom/ssd-mirror.svg +3 -0
  27. package/assets/tn-icons/custom/ssd.svg +3 -0
  28. package/assets/tn-icons/custom/true-cloud.svg +10 -0
  29. package/assets/tn-icons/custom/truecommand-logo-mark-color.svg +14 -0
  30. package/assets/tn-icons/custom/truecommand-logo-mark.svg +10 -0
  31. package/assets/tn-icons/custom/truenas-connect-logo.svg +1 -0
  32. package/assets/tn-icons/custom/truenas-logo-ce-color.svg +1 -0
  33. package/assets/tn-icons/custom/truenas-logo-ce.svg +4 -0
  34. package/assets/tn-icons/custom/truenas-logo-enterprise-color.svg +19 -0
  35. package/assets/tn-icons/custom/truenas-logo-enterprise.svg +13 -0
  36. package/assets/tn-icons/custom/truenas-logo-mark-color.svg +7 -0
  37. package/assets/tn-icons/custom/truenas-logo-mark.svg +4 -0
  38. package/assets/tn-icons/custom/truenas-logo-type-color.svg +4 -0
  39. package/assets/tn-icons/custom/truenas-logo-type.svg +4 -0
  40. package/assets/tn-icons/custom/truenas-logo.svg +4 -0
  41. package/assets/tn-icons/custom/two-factor-auth.svg +1 -0
  42. package/assets/tn-icons/sprite-config.json +78 -0
  43. package/assets/tn-icons/sprite.svg +1 -0
  44. package/fesm2022/truenas-ui-components.mjs +8063 -0
  45. package/fesm2022/truenas-ui-components.mjs.map +1 -0
  46. package/package.json +45 -0
  47. package/scripts/icon-sprite/cli-main.ts +174 -0
  48. package/scripts/icon-sprite/cli-wrapper.js +32 -0
  49. package/scripts/icon-sprite/cli.js +30 -0
  50. package/scripts/icon-sprite/generate-sprite.ts +171 -0
  51. package/scripts/icon-sprite/lib/add-custom-icons.ts +33 -0
  52. package/scripts/icon-sprite/lib/build-sprite.ts +25 -0
  53. package/scripts/icon-sprite/lib/find-icons-in-templates.ts +108 -0
  54. package/scripts/icon-sprite/lib/find-icons-with-marker.ts +63 -0
  55. package/scripts/icon-sprite/lib/get-icon-paths.ts +95 -0
  56. package/scripts/icon-sprite/lib/warn-about-duplicates.ts +13 -0
  57. package/scripts/icon-sprite/make-sprite.ts +26 -0
  58. package/scripts/icon-sprite/sprite-config-interface.ts +72 -0
  59. package/src/assets/icons/dataset.svg +3 -0
  60. package/src/styles/dialog.css +150 -0
  61. package/src/styles/themes.css +665 -0
  62. package/types/truenas-ui-components.d.ts +2687 -0
@@ -0,0 +1,2687 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { AfterViewInit, ElementRef, OnDestroy, TemplateRef, AfterContentInit, ChangeDetectorRef, PipeTransform, OnInit, ViewContainerRef, AfterViewChecked } from '@angular/core';
3
+ import { ComponentHarness, BaseHarnessFilters, HarnessPredicate } from '@angular/cdk/testing';
4
+ import { SafeHtml, SafeResourceUrl, DomSanitizer } from '@angular/platform-browser';
5
+ import { ControlValueAccessor, NgControl } from '@angular/forms';
6
+ import { DataSource } from '@angular/cdk/collections';
7
+ import * as i1 from '@angular/cdk/tree';
8
+ import { CdkTree, FlatTreeControl, CdkTreeNode, CdkNestedTreeNode } from '@angular/cdk/tree';
9
+ export { FlatTreeControl } from '@angular/cdk/tree';
10
+ import { Observable } from 'rxjs';
11
+ import { Overlay } from '@angular/cdk/overlay';
12
+ import { DialogConfig, DialogRef } from '@angular/cdk/dialog';
13
+ import { ComponentType } from '@angular/cdk/portal';
14
+
15
+ declare enum DiskType {
16
+ Hdd = "HDD",
17
+ Ssd = "SSD"
18
+ }
19
+
20
+ declare class DiskIconComponent {
21
+ readonly size: _angular_core.InputSignal<string>;
22
+ readonly type: _angular_core.InputSignal<DiskType>;
23
+ readonly name: _angular_core.InputSignal<string>;
24
+ protected readonly DiskType: typeof DiskType;
25
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DiskIconComponent, never>;
26
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DiskIconComponent, "tn-disk-icon", never, { "size": { "alias": "size"; "required": true; "isSignal": true; }; "type": { "alias": "type"; "required": true; "isSignal": true; }; "name": { "alias": "name"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
27
+ }
28
+
29
+ type TnBannerType = 'info' | 'warning' | 'error' | 'success';
30
+ declare class TnBannerComponent {
31
+ private iconRegistry;
32
+ heading: _angular_core.InputSignal<string>;
33
+ message: _angular_core.InputSignal<string | undefined>;
34
+ type: _angular_core.InputSignal<TnBannerType>;
35
+ constructor();
36
+ /**
37
+ * Register all MDI icons used by the banner component
38
+ * Makes component self-contained with zero external configuration
39
+ */
40
+ private registerMdiIcons;
41
+ /**
42
+ * Get the appropriate icon name based on banner type
43
+ */
44
+ iconName: _angular_core.Signal<"information" | "alert" | "alert-circle" | "check-circle">;
45
+ /**
46
+ * Get ARIA role based on banner type
47
+ * Error/warning use 'alert' for immediate attention
48
+ * Info/success use 'status' for polite announcements
49
+ */
50
+ ariaRole: _angular_core.Signal<"alert" | "status">;
51
+ /**
52
+ * Generate CSS classes using BEM methodology
53
+ */
54
+ classes: _angular_core.Signal<string[]>;
55
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnBannerComponent, never>;
56
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnBannerComponent, "tn-banner", never, { "heading": { "alias": "heading"; "required": true; "isSignal": true; }; "message": { "alias": "message"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
57
+ }
58
+
59
+ /**
60
+ * Harness for interacting with tn-banner in tests.
61
+ * Provides simple text-based querying for existence checks.
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * // Check for existence
66
+ * const banner = await loader.getHarness(TnBannerHarness);
67
+ *
68
+ * // Find banner containing specific text
69
+ * const errorBanner = await loader.getHarness(
70
+ * TnBannerHarness.with({ textContains: 'network error' })
71
+ * );
72
+ *
73
+ * // Check if banner exists with text
74
+ * const hasBanner = await loader.hasHarness(
75
+ * TnBannerHarness.with({ textContains: /success/i })
76
+ * );
77
+ * ```
78
+ */
79
+ declare class TnBannerHarness extends ComponentHarness {
80
+ /**
81
+ * The selector for the host element of an `TnBannerComponent` instance.
82
+ */
83
+ static hostSelector: string;
84
+ /**
85
+ * Gets a `HarnessPredicate` that can be used to search for a banner
86
+ * with specific text content.
87
+ *
88
+ * @param options Options for filtering which banner instances are considered a match.
89
+ * @returns A `HarnessPredicate` configured with the given options.
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * // Find banner containing specific text
94
+ * const banner = await loader.getHarness(
95
+ * TnBannerHarness.with({ textContains: 'error occurred' })
96
+ * );
97
+ *
98
+ * // Find banner with regex pattern
99
+ * const banner = await loader.getHarness(
100
+ * TnBannerHarness.with({ textContains: /Error:/ })
101
+ * );
102
+ * ```
103
+ */
104
+ static with(options?: BannerHarnessFilters): HarnessPredicate<TnBannerHarness>;
105
+ /**
106
+ * Gets all text content from the banner (heading + message combined).
107
+ *
108
+ * @returns Promise resolving to the banner's text content, trimmed of whitespace.
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * const banner = await loader.getHarness(TnBannerHarness);
113
+ * const text = await banner.getText();
114
+ * expect(text).toContain('Success');
115
+ * ```
116
+ */
117
+ getText(): Promise<string>;
118
+ }
119
+ /**
120
+ * A set of criteria that can be used to filter a list of `TnBannerHarness` instances.
121
+ */
122
+ interface BannerHarnessFilters extends BaseHarnessFilters {
123
+ /** Filters by text content within banner. Supports string or regex matching. */
124
+ textContains?: string | RegExp;
125
+ }
126
+
127
+ declare class TnButtonComponent {
128
+ size: string;
129
+ primary: _angular_core.InputSignal<boolean>;
130
+ color: _angular_core.InputSignal<"primary" | "secondary" | "warn" | "default">;
131
+ variant: _angular_core.InputSignal<"filled" | "outline">;
132
+ backgroundColor: _angular_core.InputSignal<string | undefined>;
133
+ label: _angular_core.InputSignal<string>;
134
+ disabled: _angular_core.InputSignal<boolean>;
135
+ onClick: _angular_core.OutputEmitterRef<MouseEvent>;
136
+ classes: _angular_core.Signal<string[]>;
137
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnButtonComponent, never>;
138
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnButtonComponent, "tn-button", never, { "primary": { "alias": "primary"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "backgroundColor": { "alias": "backgroundColor"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "onClick": "onClick"; }, never, never, true, never>;
139
+ }
140
+
141
+ type IconSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
142
+ type IconSource = 'svg' | 'css' | 'unicode' | 'text' | 'sprite';
143
+ type IconLibraryType = 'material' | 'mdi' | 'custom' | 'lucide';
144
+ interface IconResult {
145
+ source: IconSource;
146
+ content: string | SafeHtml;
147
+ spriteUrl?: string;
148
+ }
149
+ declare class TnIconComponent implements AfterViewInit {
150
+ name: _angular_core.InputSignal<string>;
151
+ size: _angular_core.InputSignal<IconSize>;
152
+ color: _angular_core.InputSignal<string | undefined>;
153
+ tooltip: _angular_core.InputSignal<string | undefined>;
154
+ ariaLabel: _angular_core.InputSignal<string | undefined>;
155
+ library: _angular_core.InputSignal<IconLibraryType | undefined>;
156
+ svgContainer: _angular_core.Signal<ElementRef<HTMLDivElement> | undefined>;
157
+ iconResult: IconResult;
158
+ private iconRegistry;
159
+ private cdr;
160
+ private sanitizer;
161
+ constructor();
162
+ ngAfterViewInit(): void;
163
+ effectiveAriaLabel: _angular_core.Signal<string>;
164
+ sanitizedContent: _angular_core.Signal<SafeHtml>;
165
+ private updateSvgContent;
166
+ private resolveIcon;
167
+ private tryThirdPartyIcon;
168
+ private tryCssIcon;
169
+ private tryUnicodeIcon;
170
+ private generateTextAbbreviation;
171
+ private cssClassExists;
172
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnIconComponent, never>;
173
+ 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; }; }, {}, never, never, true, never>;
174
+ }
175
+
176
+ declare class TnIconButtonComponent {
177
+ disabled: _angular_core.InputSignal<boolean>;
178
+ ariaLabel: _angular_core.InputSignal<string | undefined>;
179
+ name: _angular_core.InputSignal<string>;
180
+ size: _angular_core.InputSignal<IconSize>;
181
+ color: _angular_core.InputSignal<string | undefined>;
182
+ tooltip: _angular_core.InputSignal<string | undefined>;
183
+ library: _angular_core.InputSignal<IconLibraryType | undefined>;
184
+ onClick: _angular_core.OutputEmitterRef<MouseEvent>;
185
+ classes: _angular_core.Signal<string[]>;
186
+ effectiveAriaLabel: _angular_core.Signal<string>;
187
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnIconButtonComponent, never>;
188
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnIconButtonComponent, "tn-icon-button", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "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; }; "library": { "alias": "library"; "required": false; "isSignal": true; }; }, { "onClick": "onClick"; }, never, never, true, never>;
189
+ }
190
+
191
+ declare enum InputType {
192
+ Email = "email",
193
+ Password = "password",
194
+ PlainText = "text"
195
+ }
196
+
197
+ declare class TnInputComponent implements AfterViewInit, ControlValueAccessor {
198
+ inputEl: _angular_core.Signal<ElementRef<HTMLInputElement | HTMLTextAreaElement>>;
199
+ inputType: _angular_core.InputSignal<InputType>;
200
+ placeholder: _angular_core.InputSignal<string>;
201
+ testId: _angular_core.InputSignal<string | undefined>;
202
+ disabled: _angular_core.InputSignal<boolean>;
203
+ multiline: _angular_core.InputSignal<boolean>;
204
+ rows: _angular_core.InputSignal<number>;
205
+ id: string;
206
+ value: string;
207
+ private formDisabled;
208
+ isDisabled: _angular_core.Signal<boolean>;
209
+ private onChange;
210
+ private onTouched;
211
+ private focusMonitor;
212
+ ngAfterViewInit(): void;
213
+ writeValue(value: string): void;
214
+ registerOnChange(fn: (value: string) => void): void;
215
+ registerOnTouched(fn: () => void): void;
216
+ setDisabledState(isDisabled: boolean): void;
217
+ onValueChange(event: Event): void;
218
+ onBlur(): void;
219
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnInputComponent, never>;
220
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnInputComponent, "tn-input", never, { "inputType": { "alias": "inputType"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "multiline": { "alias": "multiline"; "required": false; "isSignal": true; }; "rows": { "alias": "rows"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
221
+ }
222
+
223
+ declare class TnInputDirective {
224
+ constructor();
225
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnInputDirective, never>;
226
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnInputDirective, "input[tnInput], textarea[tnInput], div[tnInput]", never, {}, {}, never, never, true, never>;
227
+ }
228
+
229
+ type ChipColor = 'primary' | 'secondary' | 'accent';
230
+ declare class TnChipComponent implements AfterViewInit, OnDestroy {
231
+ chipEl: _angular_core.Signal<ElementRef<HTMLElement>>;
232
+ label: _angular_core.InputSignal<string>;
233
+ icon: _angular_core.InputSignal<string | undefined>;
234
+ closable: _angular_core.InputSignal<boolean>;
235
+ disabled: _angular_core.InputSignal<boolean>;
236
+ color: _angular_core.InputSignal<ChipColor>;
237
+ testId: _angular_core.InputSignal<string | undefined>;
238
+ onClose: _angular_core.OutputEmitterRef<void>;
239
+ onClick: _angular_core.OutputEmitterRef<MouseEvent>;
240
+ private focusMonitor;
241
+ ngAfterViewInit(): void;
242
+ ngOnDestroy(): void;
243
+ classes: _angular_core.Signal<string[]>;
244
+ handleClick(event: MouseEvent): void;
245
+ handleClose(event: MouseEvent): void;
246
+ handleKeyDown(event: KeyboardEvent): void;
247
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnChipComponent, never>;
248
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnChipComponent, "tn-chip", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "closable": { "alias": "closable"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; }, { "onClose": "onClose"; "onClick": "onClick"; }, never, never, true, never>;
249
+ }
250
+
251
+ interface TnCardAction {
252
+ label: string;
253
+ handler: () => void;
254
+ disabled?: boolean;
255
+ icon?: string;
256
+ }
257
+ interface TnCardControl {
258
+ label: string;
259
+ checked: boolean;
260
+ handler: (checked: boolean) => void;
261
+ disabled?: boolean;
262
+ }
263
+ interface TnCardHeaderStatus {
264
+ label: string;
265
+ type?: 'success' | 'warning' | 'error' | 'info' | 'neutral';
266
+ }
267
+ interface TnCardFooterLink {
268
+ label: string;
269
+ handler: () => void;
270
+ }
271
+
272
+ interface TnMenuItem {
273
+ id: string;
274
+ label: string;
275
+ icon?: string;
276
+ iconLibrary?: 'material' | 'mdi' | 'custom' | 'lucide';
277
+ disabled?: boolean;
278
+ separator?: boolean;
279
+ action?: () => void;
280
+ children?: TnMenuItem[];
281
+ shortcut?: string;
282
+ }
283
+ declare class TnMenuComponent {
284
+ items: _angular_core.InputSignal<TnMenuItem[]>;
285
+ contextMenu: _angular_core.InputSignal<boolean>;
286
+ menuItemClick: _angular_core.OutputEmitterRef<TnMenuItem>;
287
+ menuOpen: _angular_core.OutputEmitterRef<void>;
288
+ menuClose: _angular_core.OutputEmitterRef<void>;
289
+ menuTemplate: _angular_core.Signal<TemplateRef<unknown>>;
290
+ contextMenuTemplate: _angular_core.Signal<TemplateRef<unknown>>;
291
+ private contextOverlayRef?;
292
+ private overlay;
293
+ private viewContainerRef;
294
+ onMenuItemClick(item: TnMenuItem): void;
295
+ hasChildren: _angular_core.Signal<(item: TnMenuItem) => boolean>;
296
+ onMenuOpen(): void;
297
+ onMenuClose(): void;
298
+ /**
299
+ * Get the menu template for use by the trigger directive
300
+ */
301
+ getMenuTemplate(): TemplateRef<unknown> | null;
302
+ openContextMenuAt(x: number, y: number): void;
303
+ private closeContextMenu;
304
+ onContextMenu(event: MouseEvent): void;
305
+ trackByItemId(index: number, item: TnMenuItem): string;
306
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnMenuComponent, never>;
307
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnMenuComponent, "tn-menu", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "contextMenu": { "alias": "contextMenu"; "required": false; "isSignal": true; }; }, { "menuItemClick": "menuItemClick"; "menuOpen": "menuOpen"; "menuClose": "menuClose"; }, never, ["*"], true, never>;
308
+ }
309
+
310
+ declare class TnCardComponent {
311
+ private iconRegistry;
312
+ constructor();
313
+ title: _angular_core.InputSignal<string | undefined>;
314
+ titleLink: _angular_core.InputSignal<string | undefined>;
315
+ elevation: _angular_core.InputSignal<"none" | "low" | "medium" | "high">;
316
+ padding: _angular_core.InputSignal<"large" | "medium" | "small">;
317
+ padContent: _angular_core.InputSignal<boolean>;
318
+ bordered: _angular_core.InputSignal<boolean>;
319
+ background: _angular_core.InputSignal<boolean>;
320
+ headerStatus: _angular_core.InputSignal<TnCardHeaderStatus | undefined>;
321
+ headerControl: _angular_core.InputSignal<TnCardControl | undefined>;
322
+ headerMenu: _angular_core.InputSignal<TnMenuItem[] | undefined>;
323
+ primaryAction: _angular_core.InputSignal<TnCardAction | undefined>;
324
+ secondaryAction: _angular_core.InputSignal<TnCardAction | undefined>;
325
+ footerLink: _angular_core.InputSignal<TnCardFooterLink | undefined>;
326
+ /**
327
+ * Register MDI icon library with all icons used by the card component
328
+ * This makes the component self-contained with zero configuration required
329
+ */
330
+ private registerMdiIcons;
331
+ classes: _angular_core.Signal<string[]>;
332
+ hasHeader: _angular_core.Signal<boolean>;
333
+ hasFooter: _angular_core.Signal<boolean>;
334
+ onTitleClick(): void;
335
+ onControlChange(checked: boolean): void;
336
+ onHeaderMenuItemClick(_item: TnMenuItem): void;
337
+ getStatusClass(type?: string): string;
338
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnCardComponent, never>;
339
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnCardComponent, "tn-card", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "titleLink": { "alias": "titleLink"; "required": false; "isSignal": true; }; "elevation": { "alias": "elevation"; "required": false; "isSignal": true; }; "padding": { "alias": "padding"; "required": false; "isSignal": true; }; "padContent": { "alias": "padContent"; "required": false; "isSignal": true; }; "bordered": { "alias": "bordered"; "required": false; "isSignal": true; }; "background": { "alias": "background"; "required": false; "isSignal": true; }; "headerStatus": { "alias": "headerStatus"; "required": false; "isSignal": true; }; "headerControl": { "alias": "headerControl"; "required": false; "isSignal": true; }; "headerMenu": { "alias": "headerMenu"; "required": false; "isSignal": true; }; "primaryAction": { "alias": "primaryAction"; "required": false; "isSignal": true; }; "secondaryAction": { "alias": "secondaryAction"; "required": false; "isSignal": true; }; "footerLink": { "alias": "footerLink"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
340
+ }
341
+
342
+ declare class TnExpansionPanelComponent {
343
+ title: _angular_core.InputSignal<string | undefined>;
344
+ elevation: _angular_core.InputSignal<"none" | "low" | "medium" | "high">;
345
+ padding: _angular_core.InputSignal<"large" | "medium" | "small">;
346
+ bordered: _angular_core.InputSignal<boolean>;
347
+ background: _angular_core.InputSignal<boolean>;
348
+ expanded: _angular_core.InputSignal<boolean>;
349
+ disabled: _angular_core.InputSignal<boolean>;
350
+ titleStyle: _angular_core.InputSignal<"link" | "header" | "body">;
351
+ expandedChange: _angular_core.OutputEmitterRef<boolean>;
352
+ toggleEvent: _angular_core.OutputEmitterRef<void>;
353
+ private internalExpanded;
354
+ effectiveExpanded: _angular_core.Signal<boolean>;
355
+ readonly contentId: string;
356
+ toggle(): void;
357
+ classes: _angular_core.Signal<string[]>;
358
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnExpansionPanelComponent, never>;
359
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnExpansionPanelComponent, "tn-expansion-panel", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "elevation": { "alias": "elevation"; "required": false; "isSignal": true; }; "padding": { "alias": "padding"; "required": false; "isSignal": true; }; "bordered": { "alias": "bordered"; "required": false; "isSignal": true; }; "background": { "alias": "background"; "required": false; "isSignal": true; }; "expanded": { "alias": "expanded"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "titleStyle": { "alias": "titleStyle"; "required": false; "isSignal": true; }; }, { "expandedChange": "expandedChange"; "toggleEvent": "toggleEvent"; }, never, ["[slot=title]", "*"], true, never>;
360
+ }
361
+
362
+ declare class TnCheckboxComponent implements AfterViewInit, OnDestroy, ControlValueAccessor {
363
+ checkboxEl: _angular_core.Signal<ElementRef<HTMLInputElement>>;
364
+ label: _angular_core.InputSignal<string>;
365
+ hideLabel: _angular_core.InputSignal<boolean>;
366
+ disabled: _angular_core.InputSignal<boolean>;
367
+ required: _angular_core.InputSignal<boolean>;
368
+ indeterminate: _angular_core.InputSignal<boolean>;
369
+ testId: _angular_core.InputSignal<string | undefined>;
370
+ error: _angular_core.InputSignal<string | null>;
371
+ checked: _angular_core.InputSignal<boolean>;
372
+ change: _angular_core.OutputEmitterRef<boolean>;
373
+ id: string;
374
+ private internalChecked;
375
+ private formDisabled;
376
+ isDisabled: _angular_core.Signal<boolean>;
377
+ private focusMonitor;
378
+ private onChange;
379
+ private onTouched;
380
+ ngAfterViewInit(): void;
381
+ ngOnDestroy(): void;
382
+ effectiveChecked: _angular_core.Signal<boolean>;
383
+ writeValue(value: boolean): void;
384
+ registerOnChange(fn: (value: boolean) => void): void;
385
+ registerOnTouched(fn: () => void): void;
386
+ setDisabledState(isDisabled: boolean): void;
387
+ onCheckboxChange(event: Event): void;
388
+ classes: _angular_core.Signal<string[]>;
389
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnCheckboxComponent, never>;
390
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnCheckboxComponent, "tn-checkbox", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "hideLabel": { "alias": "hideLabel"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "indeterminate": { "alias": "indeterminate"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "checked": { "alias": "checked"; "required": false; "isSignal": true; }; }, { "change": "change"; }, never, never, true, never>;
391
+ }
392
+
393
+ declare class TnRadioComponent implements AfterViewInit, OnDestroy, ControlValueAccessor {
394
+ radioEl: _angular_core.Signal<ElementRef<HTMLInputElement>>;
395
+ label: _angular_core.InputSignal<string>;
396
+ value: _angular_core.InputSignal<unknown>;
397
+ name: _angular_core.InputSignal<string | undefined>;
398
+ disabled: _angular_core.InputSignal<boolean>;
399
+ required: _angular_core.InputSignal<boolean>;
400
+ testId: _angular_core.InputSignal<string | undefined>;
401
+ error: _angular_core.InputSignal<string | null>;
402
+ change: _angular_core.OutputEmitterRef<unknown>;
403
+ id: string;
404
+ checked: boolean;
405
+ private formDisabled;
406
+ isDisabled: _angular_core.Signal<boolean>;
407
+ private focusMonitor;
408
+ private onChange;
409
+ private onTouched;
410
+ ngAfterViewInit(): void;
411
+ ngOnDestroy(): void;
412
+ writeValue(value: unknown): void;
413
+ registerOnChange(fn: (value: unknown) => void): void;
414
+ registerOnTouched(fn: () => void): void;
415
+ setDisabledState(isDisabled: boolean): void;
416
+ onRadioChange(event: Event): void;
417
+ classes: _angular_core.Signal<string[]>;
418
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnRadioComponent, never>;
419
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnRadioComponent, "tn-radio", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; }, { "change": "change"; }, never, never, true, never>;
420
+ }
421
+
422
+ type SlideToggleColor = 'primary' | 'accent' | 'warn';
423
+ declare class TnSlideToggleComponent implements AfterViewInit, OnDestroy, ControlValueAccessor {
424
+ toggleEl: _angular_core.Signal<ElementRef<HTMLInputElement>>;
425
+ labelPosition: _angular_core.InputSignal<"after" | "before">;
426
+ label: _angular_core.InputSignal<string | undefined>;
427
+ disabled: _angular_core.InputSignal<boolean>;
428
+ required: _angular_core.InputSignal<boolean>;
429
+ color: _angular_core.InputSignal<SlideToggleColor>;
430
+ testId: _angular_core.InputSignal<string | undefined>;
431
+ ariaLabel: _angular_core.InputSignal<string | undefined>;
432
+ ariaLabelledby: _angular_core.InputSignal<string | undefined>;
433
+ checked: _angular_core.InputSignal<boolean>;
434
+ change: _angular_core.OutputEmitterRef<boolean>;
435
+ toggleChange: _angular_core.OutputEmitterRef<boolean>;
436
+ id: string;
437
+ private internalChecked;
438
+ private formDisabled;
439
+ isDisabled: _angular_core.Signal<boolean>;
440
+ private focusMonitor;
441
+ private onChange;
442
+ private onTouched;
443
+ ngAfterViewInit(): void;
444
+ ngOnDestroy(): void;
445
+ effectiveChecked: _angular_core.Signal<boolean>;
446
+ writeValue(value: boolean): void;
447
+ registerOnChange(fn: (value: boolean) => void): void;
448
+ registerOnTouched(fn: () => void): void;
449
+ setDisabledState(isDisabled: boolean): void;
450
+ onToggleChange(event: Event): void;
451
+ onLabelClick(): void;
452
+ classes: _angular_core.Signal<string[]>;
453
+ effectiveAriaLabel: _angular_core.Signal<string | undefined>;
454
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnSlideToggleComponent, never>;
455
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnSlideToggleComponent, "tn-slide-toggle", never, { "labelPosition": { "alias": "labelPosition"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "ariaLabelledby"; "required": false; "isSignal": true; }; "checked": { "alias": "checked"; "required": false; "isSignal": true; }; }, { "change": "change"; "toggleChange": "toggleChange"; }, never, never, true, never>;
456
+ }
457
+
458
+ declare class TnTabComponent implements AfterContentInit {
459
+ label: _angular_core.InputSignal<string>;
460
+ disabled: _angular_core.InputSignal<boolean>;
461
+ icon: _angular_core.InputSignal<string | undefined>;
462
+ iconTemplate: _angular_core.InputSignal<TemplateRef<unknown> | undefined>;
463
+ testId: _angular_core.InputSignal<string | undefined>;
464
+ selected: _angular_core.OutputEmitterRef<void>;
465
+ iconContent: _angular_core.Signal<TemplateRef<unknown> | undefined>;
466
+ index: _angular_core.WritableSignal<number>;
467
+ isActive: _angular_core.WritableSignal<boolean>;
468
+ tabsComponent?: {
469
+ onKeydown: (event: KeyboardEvent, index: number) => void;
470
+ };
471
+ elementRef: ElementRef<any>;
472
+ protected hasIconContent: _angular_core.WritableSignal<boolean>;
473
+ ngAfterContentInit(): void;
474
+ onClick(): void;
475
+ onKeydown(event: KeyboardEvent): void;
476
+ classes: _angular_core.Signal<string>;
477
+ tabIndex: _angular_core.Signal<0 | -1>;
478
+ hasIcon: _angular_core.Signal<boolean>;
479
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnTabComponent, never>;
480
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnTabComponent, "tn-tab", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "iconTemplate": { "alias": "iconTemplate"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; }, { "selected": "selected"; }, ["iconContent"], ["*"], true, never>;
481
+ }
482
+
483
+ declare class TnTabPanelComponent {
484
+ label: _angular_core.InputSignal<string>;
485
+ lazyLoad: _angular_core.InputSignal<boolean>;
486
+ testId: _angular_core.InputSignal<string | undefined>;
487
+ content: _angular_core.Signal<TemplateRef<unknown>>;
488
+ index: _angular_core.WritableSignal<number>;
489
+ isActive: _angular_core.WritableSignal<boolean>;
490
+ hasBeenActive: _angular_core.WritableSignal<boolean>;
491
+ elementRef: ElementRef<any>;
492
+ classes: _angular_core.Signal<string>;
493
+ shouldRender: _angular_core.Signal<boolean>;
494
+ onActivate(): void;
495
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnTabPanelComponent, never>;
496
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnTabPanelComponent, "tn-tab-panel", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "lazyLoad": { "alias": "lazyLoad"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
497
+ }
498
+
499
+ interface TabChangeEvent {
500
+ index: number;
501
+ tab: TnTabComponent;
502
+ previousIndex: number;
503
+ }
504
+ declare class TnTabsComponent implements AfterContentInit, AfterViewInit, OnDestroy {
505
+ tabs: _angular_core.Signal<readonly TnTabComponent[]>;
506
+ panels: _angular_core.Signal<readonly TnTabPanelComponent[]>;
507
+ tabHeader: _angular_core.Signal<ElementRef<HTMLElement>>;
508
+ selectedIndex: _angular_core.InputSignal<number>;
509
+ orientation: _angular_core.InputSignal<"horizontal" | "vertical">;
510
+ highlightPosition: _angular_core.InputSignal<"top" | "bottom" | "left" | "right">;
511
+ selectedIndexChange: _angular_core.OutputEmitterRef<number>;
512
+ tabChange: _angular_core.OutputEmitterRef<TabChangeEvent>;
513
+ private internalSelectedIndex;
514
+ highlightBarLeft: _angular_core.WritableSignal<number>;
515
+ highlightBarWidth: _angular_core.WritableSignal<number>;
516
+ highlightBarTop: _angular_core.WritableSignal<number>;
517
+ highlightBarHeight: _angular_core.WritableSignal<number>;
518
+ highlightBarVisible: _angular_core.WritableSignal<boolean>;
519
+ private focusMonitor;
520
+ private cdr;
521
+ constructor();
522
+ ngAfterContentInit(): void;
523
+ ngAfterViewInit(): void;
524
+ ngOnDestroy(): void;
525
+ private initializeTabs;
526
+ selectTab(index: number): void;
527
+ private updateHighlightBar;
528
+ onKeydown(event: KeyboardEvent, currentIndex: number): void;
529
+ private getPreviousEnabledTabIndex;
530
+ private getNextEnabledTabIndex;
531
+ private getFirstEnabledTabIndex;
532
+ private getLastEnabledTabIndex;
533
+ private focusTab;
534
+ classes: _angular_core.Signal<string>;
535
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnTabsComponent, never>;
536
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnTabsComponent, "tn-tabs", never, { "selectedIndex": { "alias": "selectedIndex"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "highlightPosition": { "alias": "highlightPosition"; "required": false; "isSignal": true; }; }, { "selectedIndexChange": "selectedIndexChange"; "tabChange": "tabChange"; }, ["tabs", "panels"], ["tn-tab", "tn-tab-panel"], true, never>;
537
+ }
538
+
539
+ /**
540
+ * Directive that attaches a menu to any element.
541
+ * Usage: <button [tnMenuTriggerFor]="menu">Open Menu</button>
542
+ */
543
+ declare class TnMenuTriggerDirective {
544
+ menu: _angular_core.InputSignal<TnMenuComponent>;
545
+ tnMenuPosition: _angular_core.InputSignal<"after" | "before" | "above" | "below">;
546
+ private overlayRef?;
547
+ private isMenuOpen;
548
+ private elementRef;
549
+ private overlay;
550
+ private viewContainerRef;
551
+ onClick(): void;
552
+ openMenu(): void;
553
+ closeMenu(): void;
554
+ private getPositions;
555
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnMenuTriggerDirective, never>;
556
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnMenuTriggerDirective, "[tnMenuTriggerFor]", ["tnMenuTrigger"], { "menu": { "alias": "tnMenuTriggerFor"; "required": true; "isSignal": true; }; "tnMenuPosition": { "alias": "tnMenuPosition"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
557
+ }
558
+
559
+ declare enum ModifierKeys {
560
+ COMMAND = "\u2318",
561
+ CMD = "\u2318",
562
+ CTRL = "Ctrl",
563
+ CONTROL = "Ctrl",
564
+ ALT = "\u2325",
565
+ OPTION = "\u2325",
566
+ OPT = "\u2325",
567
+ SHIFT = "\u21E7",
568
+ META = "\u2318",
569
+ SUPER = "\u2318"
570
+ }
571
+ declare enum WindowsModifierKeys {
572
+ CTRL = "Ctrl",
573
+ CONTROL = "Ctrl",
574
+ ALT = "Alt",
575
+ SHIFT = "Shift",
576
+ WIN = "Win",
577
+ WINDOWS = "Win"
578
+ }
579
+ declare enum LinuxModifierKeys {
580
+ CTRL = "Ctrl",
581
+ CONTROL = "Ctrl",
582
+ ALT = "Alt",
583
+ SHIFT = "Shift",
584
+ SUPER = "Super",
585
+ META = "Meta"
586
+ }
587
+ type PlatformType = 'mac' | 'windows' | 'linux' | 'auto';
588
+
589
+ declare class TnKeyboardShortcutComponent {
590
+ shortcut: _angular_core.InputSignal<string>;
591
+ platform: _angular_core.InputSignal<PlatformType>;
592
+ separator: _angular_core.InputSignal<string>;
593
+ displayShortcut: _angular_core.Signal<string>;
594
+ private formatShortcut;
595
+ private detectPlatform;
596
+ private convertToWindows;
597
+ shortcutKeys: _angular_core.Signal<string[]>;
598
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnKeyboardShortcutComponent, never>;
599
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnKeyboardShortcutComponent, "tn-keyboard-shortcut", never, { "shortcut": { "alias": "shortcut"; "required": false; "isSignal": true; }; "platform": { "alias": "platform"; "required": false; "isSignal": true; }; "separator": { "alias": "separator"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
600
+ }
601
+
602
+ declare class TnFormFieldComponent implements AfterContentInit {
603
+ label: _angular_core.InputSignal<string>;
604
+ hint: _angular_core.InputSignal<string>;
605
+ required: _angular_core.InputSignal<boolean>;
606
+ testId: _angular_core.InputSignal<string>;
607
+ control: _angular_core.Signal<NgControl | undefined>;
608
+ protected hasError: _angular_core.WritableSignal<boolean>;
609
+ protected errorMessage: _angular_core.WritableSignal<string>;
610
+ ngAfterContentInit(): void;
611
+ private updateErrorState;
612
+ private getErrorMessage;
613
+ showError: _angular_core.Signal<boolean>;
614
+ showHint: _angular_core.Signal<boolean>;
615
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnFormFieldComponent, never>;
616
+ 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; }; }, {}, ["control"], ["*"], true, never>;
617
+ }
618
+
619
+ interface TnSelectOption<T = unknown> {
620
+ value: T;
621
+ label: string;
622
+ disabled?: boolean;
623
+ }
624
+ interface TnSelectOptionGroup<T = unknown> {
625
+ label: string;
626
+ options: TnSelectOption<T>[];
627
+ disabled?: boolean;
628
+ }
629
+ declare class TnSelectComponent<T = unknown> implements ControlValueAccessor {
630
+ options: _angular_core.InputSignal<TnSelectOption<T>[]>;
631
+ optionGroups: _angular_core.InputSignal<TnSelectOptionGroup<T>[]>;
632
+ placeholder: _angular_core.InputSignal<string>;
633
+ disabled: _angular_core.InputSignal<boolean>;
634
+ testId: _angular_core.InputSignal<string>;
635
+ selectionChange: _angular_core.OutputEmitterRef<T>;
636
+ protected isOpen: _angular_core.WritableSignal<boolean>;
637
+ protected selectedValue: _angular_core.WritableSignal<T | null>;
638
+ private formDisabled;
639
+ isDisabled: _angular_core.Signal<boolean>;
640
+ private onChange;
641
+ private onTouched;
642
+ private elementRef;
643
+ private cdr;
644
+ constructor();
645
+ writeValue(value: T | null): void;
646
+ registerOnChange(fn: (value: T | null) => void): void;
647
+ registerOnTouched(fn: () => void): void;
648
+ setDisabledState(isDisabled: boolean): void;
649
+ toggleDropdown(): void;
650
+ closeDropdown(): void;
651
+ onOptionClick(option: TnSelectOption<T>): void;
652
+ selectOption(option: TnSelectOption<T>): void;
653
+ isSelected: _angular_core.Signal<(option: TnSelectOption<T>) => boolean>;
654
+ getDisplayText: _angular_core.Signal<string | (T & {})>;
655
+ private findOptionByValue;
656
+ hasAnyOptions: _angular_core.Signal<boolean>;
657
+ private compareValues;
658
+ onKeydown(event: KeyboardEvent): void;
659
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnSelectComponent<any>, never>;
660
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnSelectComponent<any>, "tn-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "optionGroups": { "alias": "optionGroups"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; }, never, never, true, never>;
661
+ }
662
+
663
+ /**
664
+ * Harness for interacting with tn-icon in tests.
665
+ * Provides filtering by icon name and library for existence checks.
666
+ *
667
+ * @example
668
+ * ```typescript
669
+ * // Check for existence
670
+ * const icon = await loader.getHarness(TnIconHarness);
671
+ *
672
+ * // Find icon by name
673
+ * const folderIcon = await loader.getHarness(
674
+ * TnIconHarness.with({ name: 'folder' })
675
+ * );
676
+ *
677
+ * // Find icon by name and library
678
+ * const mdiIcon = await loader.getHarness(
679
+ * TnIconHarness.with({ name: 'account-circle', library: 'mdi' })
680
+ * );
681
+ *
682
+ * // Check if icon exists
683
+ * const hasIcon = await loader.hasHarness(
684
+ * TnIconHarness.with({ name: 'check' })
685
+ * );
686
+ * ```
687
+ */
688
+ declare class TnIconHarness extends ComponentHarness {
689
+ /**
690
+ * The selector for the host element of a `TnIconComponent` instance.
691
+ */
692
+ static hostSelector: string;
693
+ /**
694
+ * Gets a `HarnessPredicate` that can be used to search for an icon
695
+ * with specific attributes.
696
+ *
697
+ * @param options Options for filtering which icon instances are considered a match.
698
+ * @returns A `HarnessPredicate` configured with the given options.
699
+ *
700
+ * @example
701
+ * ```typescript
702
+ * // Find icon by name
703
+ * const icon = await loader.getHarness(
704
+ * TnIconHarness.with({ name: 'home' })
705
+ * );
706
+ *
707
+ * // Find icon by library
708
+ * const customIcon = await loader.getHarness(
709
+ * TnIconHarness.with({ library: 'custom' })
710
+ * );
711
+ *
712
+ * // Find icon with specific size
713
+ * const largeIcon = await loader.getHarness(
714
+ * TnIconHarness.with({ size: 'lg' })
715
+ * );
716
+ * ```
717
+ */
718
+ static with(options?: IconHarnessFilters): HarnessPredicate<TnIconHarness>;
719
+ /**
720
+ * Gets the icon name.
721
+ *
722
+ * @returns Promise resolving to the icon name.
723
+ *
724
+ * @example
725
+ * ```typescript
726
+ * const icon = await loader.getHarness(TnIconHarness);
727
+ * const name = await icon.getName();
728
+ * expect(name).toBe('folder');
729
+ * ```
730
+ */
731
+ getName(): Promise<string | null>;
732
+ /**
733
+ * Gets the icon library.
734
+ *
735
+ * @returns Promise resolving to the icon library.
736
+ *
737
+ * @example
738
+ * ```typescript
739
+ * const icon = await loader.getHarness(TnIconHarness);
740
+ * const library = await icon.getLibrary();
741
+ * expect(library).toBe('mdi');
742
+ * ```
743
+ */
744
+ getLibrary(): Promise<string | null>;
745
+ /**
746
+ * Gets the icon size.
747
+ *
748
+ * @returns Promise resolving to the icon size.
749
+ *
750
+ * @example
751
+ * ```typescript
752
+ * const icon = await loader.getHarness(TnIconHarness);
753
+ * const size = await icon.getSize();
754
+ * expect(size).toBe('lg');
755
+ * ```
756
+ */
757
+ getSize(): Promise<string | null>;
758
+ /**
759
+ * Gets the icon color.
760
+ *
761
+ * @returns Promise resolving to the icon color.
762
+ *
763
+ * @example
764
+ * ```typescript
765
+ * const icon = await loader.getHarness(TnIconHarness);
766
+ * const color = await icon.getColor();
767
+ * expect(color).toBe('primary');
768
+ * ```
769
+ */
770
+ getColor(): Promise<string | null>;
771
+ }
772
+ /**
773
+ * A set of criteria that can be used to filter a list of `TnIconHarness` instances.
774
+ */
775
+ interface IconHarnessFilters extends BaseHarnessFilters {
776
+ /** Filters by icon name. */
777
+ name?: string;
778
+ /** Filters by icon library (material, mdi, custom, lucide). */
779
+ library?: string;
780
+ /** Filters by icon size (xs, sm, md, lg, xl). */
781
+ size?: string;
782
+ }
783
+
784
+ /**
785
+ * Default base path for sprite assets (namespaced to avoid collisions with consumer apps)
786
+ * This should match the value in sprite-config-interface.ts
787
+ */
788
+ declare const defaultSpriteBasePath = "assets/tn-icons";
789
+ /**
790
+ * Default path for the sprite configuration file.
791
+ */
792
+ declare const defaultSpriteConfigPath = "assets/tn-icons/sprite-config.json";
793
+ interface SpriteConfig {
794
+ iconUrl: string;
795
+ icons?: string[];
796
+ }
797
+ /**
798
+ * Service for loading and managing icon sprites.
799
+ * This is a custom implementation that does NOT depend on Angular Material.
800
+ *
801
+ * The sprite system works by:
802
+ * 1. Loads the application's sprite (generated via `yarn icons` command)
803
+ * 2. The sprite includes both consumer icons and library-internal icons (chevrons, folder, etc.)
804
+ * 3. Icons are resolved as SVG fragment identifiers (e.g., sprite.svg#icon-name)
805
+ */
806
+ declare class TnSpriteLoaderService {
807
+ private spriteConfig?;
808
+ private spriteLoaded;
809
+ private spriteLoadPromise?;
810
+ private http;
811
+ private sanitizer;
812
+ constructor();
813
+ /**
814
+ * Load the sprite configuration
815
+ */
816
+ private loadSpriteConfig;
817
+ /**
818
+ * Ensure the sprite is loaded before resolving icons
819
+ */
820
+ ensureSpriteLoaded(): Promise<boolean>;
821
+ /**
822
+ * Get the full URL for an icon in the sprite
823
+ * Returns a URL like: assets/icons/sprite.svg?v=hash#icon-name
824
+ *
825
+ * @param iconName The icon name (e.g., 'folder', 'mdi-server', 'tn-dataset')
826
+ * @returns The fragment identifier URL for the icon, or null if sprite not loaded or icon not in sprite
827
+ */
828
+ getIconUrl(iconName: string): string | null;
829
+ /**
830
+ * Get a sanitized resource URL for an icon
831
+ * This is used when binding to [src] or similar attributes
832
+ *
833
+ * @param iconName The icon name
834
+ * @returns Sanitized resource URL or null
835
+ */
836
+ getSafeIconUrl(iconName: string): SafeResourceUrl | null;
837
+ /**
838
+ * Check if the sprite is loaded
839
+ */
840
+ isSpriteLoaded(): boolean;
841
+ /**
842
+ * Get the sprite config if loaded
843
+ */
844
+ getSpriteConfig(): SpriteConfig | undefined;
845
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnSpriteLoaderService, never>;
846
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<TnSpriteLoaderService>;
847
+ }
848
+
849
+ interface IconLibrary {
850
+ name: string;
851
+ resolver: (iconName: string, options?: unknown) => string | HTMLElement | null;
852
+ defaultOptions?: unknown;
853
+ }
854
+ interface ResolvedIcon {
855
+ source: 'svg' | 'css' | 'unicode' | 'text' | 'sprite';
856
+ content: string | SafeHtml;
857
+ spriteUrl?: string;
858
+ }
859
+ declare class TnIconRegistryService {
860
+ private libraries;
861
+ private customIcons;
862
+ private sanitizer;
863
+ private spriteLoader;
864
+ constructor(sanitizer?: DomSanitizer, spriteLoader?: TnSpriteLoaderService);
865
+ /**
866
+ * Register an icon library (like Lucide, Heroicons, etc.)
867
+ *
868
+ * @example
869
+ * ```typescript
870
+ * // Register Lucide
871
+ * import * as LucideIcons from 'lucide';
872
+ *
873
+ * iconRegistry.registerLibrary({
874
+ * name: 'lucide',
875
+ * resolver: (iconName: string, options = {}) => {
876
+ * const pascalCase = iconName.split('-').map(part =>
877
+ * part.charAt(0).toUpperCase() + part.slice(1)
878
+ * ).join('');
879
+ *
880
+ * const iconFunction = (LucideIcons as any)[pascalCase];
881
+ * if (iconFunction && typeof iconFunction === 'function') {
882
+ * return iconFunction({
883
+ * size: 24,
884
+ * color: 'currentColor',
885
+ * strokeWidth: 2,
886
+ * ...options
887
+ * });
888
+ * }
889
+ * return null;
890
+ * },
891
+ * defaultOptions: { size: 24, strokeWidth: 2 }
892
+ * });
893
+ * ```
894
+ */
895
+ registerLibrary(library: IconLibrary): void;
896
+ /**
897
+ * Register a custom SVG icon
898
+ *
899
+ * @example
900
+ * ```typescript
901
+ * iconRegistry.registerIcon('my-logo', `
902
+ * <svg viewBox="0 0 24 24">
903
+ * <path d="M12 2L2 7v10c0 5.55 3.84 10 9 11 1.16-.08 2-.35 3-.82z"/>
904
+ * </svg>
905
+ * `);
906
+ * ```
907
+ */
908
+ registerIcon(name: string, svgContent: string): void;
909
+ /**
910
+ * Register multiple custom icons at once
911
+ */
912
+ registerIcons(icons: Record<string, string>): void;
913
+ /**
914
+ * Resolve an icon from the sprite
915
+ * Returns the sprite URL if the sprite is loaded
916
+ */
917
+ private resolveSpriteIcon;
918
+ /**
919
+ * Resolve an icon using sprite, registered libraries, and custom icons
920
+ *
921
+ * Resolution order:
922
+ * 1. Sprite icons (Material, MDI, custom TrueNAS icons)
923
+ * 2. Registered libraries (with prefix, e.g., "lucide:home")
924
+ * 3. Custom registered icons
925
+ *
926
+ * Format: "library:icon-name" or just "icon-name"
927
+ *
928
+ * @example
929
+ * ```typescript
930
+ * // Sprite icons (automatic from sprite.svg)
931
+ * registry.resolveIcon('folder') // Material Design icon
932
+ * registry.resolveIcon('mdi-server') // MDI icon
933
+ * registry.resolveIcon('tn-dataset') // Custom TrueNAS icon
934
+ *
935
+ * // Library icons
936
+ * registry.resolveIcon('lucide:home')
937
+ * registry.resolveIcon('heroicons:user-circle')
938
+ *
939
+ * // Custom registered icons
940
+ * registry.resolveIcon('my-logo')
941
+ * ```
942
+ */
943
+ resolveIcon(name: string, options?: unknown): ResolvedIcon | null;
944
+ /**
945
+ * Check if a library is registered
946
+ */
947
+ hasLibrary(libraryName: string): boolean;
948
+ /**
949
+ * Check if a custom icon is registered
950
+ */
951
+ hasIcon(iconName: string): boolean;
952
+ /**
953
+ * Get list of registered libraries
954
+ */
955
+ getRegisteredLibraries(): string[];
956
+ /**
957
+ * Get list of registered custom icons
958
+ */
959
+ getRegisteredIcons(): string[];
960
+ /**
961
+ * Remove a library
962
+ */
963
+ unregisterLibrary(libraryName: string): void;
964
+ /**
965
+ * Remove a custom icon
966
+ */
967
+ unregisterIcon(iconName: string): void;
968
+ /**
969
+ * Clear all registered libraries and icons
970
+ */
971
+ clear(): void;
972
+ /**
973
+ * Get the sprite loader service
974
+ * Useful for checking sprite status or manually resolving sprite icons
975
+ */
976
+ getSpriteLoader(): TnSpriteLoaderService;
977
+ private resolveLibraryIcon;
978
+ private resolveCustomIcon;
979
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnIconRegistryService, never>;
980
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<TnIconRegistryService>;
981
+ }
982
+
983
+ /**
984
+ * Marks an icon name for inclusion in the TrueNAS UI sprite generation.
985
+ *
986
+ * This function serves two purposes:
987
+ * 1. At runtime: Applies library-specific prefixes (e.g., mdi-, app-)
988
+ * 2. At build time: Marker for the scanner to detect icons for sprite inclusion
989
+ *
990
+ * Use this when icon names are computed dynamically or come from variables,
991
+ * to ensure they're included in the sprite at build time.
992
+ *
993
+ * @example
994
+ * // Static icon name - automatically detected from template
995
+ * <tn-icon name="folder"></tn-icon>
996
+ *
997
+ * @example
998
+ * // Dynamic MDI icon
999
+ * const iconName = condition ? tnIconMarker("pencil", "mdi") : tnIconMarker("delete", "mdi");
1000
+ * <tn-icon [name]="iconName"></tn-icon>
1001
+ *
1002
+ * @example
1003
+ * // Dynamic custom icon (consumer's own icon)
1004
+ * const logo = tnIconMarker("your-logo-name", "custom");
1005
+ * <tn-icon [name]="logo"></tn-icon>
1006
+ *
1007
+ * @example
1008
+ * // Array of dynamic icons
1009
+ * const actions = [
1010
+ * { name: "Save", icon: tnIconMarker("content-save", "mdi") },
1011
+ * { name: "Cancel", icon: tnIconMarker("close", "mdi") }
1012
+ * ];
1013
+ *
1014
+ * @param iconName - The icon name to mark for sprite inclusion
1015
+ * @param library - Optional library type: 'mdi', 'material', or 'custom'
1016
+ * @returns The icon name with appropriate prefix applied
1017
+ * @public
1018
+ */
1019
+ declare function tnIconMarker(iconName: string, library?: 'mdi' | 'material' | 'custom'): string;
1020
+ /**
1021
+ * INTERNAL LIBRARY USE ONLY
1022
+ *
1023
+ * Marks an icon name for inclusion in the sprite generation with library namespace.
1024
+ * This function MUST be used by library component code for custom icons.
1025
+ *
1026
+ * The TypeScript type enforces that the icon name starts with 'tn-' prefix,
1027
+ * which reserves this namespace exclusively for library-provided custom icons.
1028
+ *
1029
+ * @example
1030
+ * ```typescript
1031
+ * // ✅ Correct - Library component code
1032
+ * const icon = libIconMarker('tn-dataset');
1033
+ *
1034
+ * // ❌ Wrong - Will cause TypeScript error
1035
+ * const icon = libIconMarker('dataset');
1036
+ * ```
1037
+ *
1038
+ * @param iconName - The icon name with 'tn-' prefix (enforced by TypeScript)
1039
+ * @returns The same icon name (identity function)
1040
+ * @internal
1041
+ */
1042
+ declare function libIconMarker(iconName: `tn-${string}`): string;
1043
+
1044
+ /**
1045
+ * Lucide Icons Integration Helper
1046
+ *
1047
+ * This helper provides easy integration with Lucide icons.
1048
+ * Usage:
1049
+ *
1050
+ * ```typescript
1051
+ * import { setupLucideIntegration } from '@truenas/ui-components';
1052
+ * import * as LucideIcons from 'lucide';
1053
+ *
1054
+ * // In your app.module.ts or main.ts
1055
+ * setupLucideIntegration(LucideIcons);
1056
+ *
1057
+ * // Now you can use lucide icons in templates:
1058
+ * // <tn-icon name="lucide:home"></tn-icon>
1059
+ * // <tn-icon name="lucide:user-circle"></tn-icon>
1060
+ * ```
1061
+ */
1062
+
1063
+ interface LucideIconOptions {
1064
+ size?: number;
1065
+ color?: string;
1066
+ strokeWidth?: number;
1067
+ fill?: string;
1068
+ stroke?: string;
1069
+ }
1070
+ /**
1071
+ * Set up Lucide icons integration with the icon registry
1072
+ *
1073
+ * @param lucideIcons - The Lucide icons object (import * as LucideIcons from 'lucide')
1074
+ * @param defaultOptions - Default options for all Lucide icons
1075
+ *
1076
+ * @example
1077
+ * ```typescript
1078
+ * import * as LucideIcons from 'lucide';
1079
+ * import { setupLucideIntegration } from '@truenas/ui-components';
1080
+ *
1081
+ * setupLucideIntegration(LucideIcons, {
1082
+ * size: 24,
1083
+ * strokeWidth: 2,
1084
+ * color: 'currentColor'
1085
+ * });
1086
+ * ```
1087
+ */
1088
+ declare function setupLucideIntegration(lucideIcons: Record<string, unknown>, defaultOptions?: LucideIconOptions): void;
1089
+ /**
1090
+ * Alternative setup function that allows manual registration
1091
+ * Use this if you want more control over which icons are available
1092
+ *
1093
+ * @example
1094
+ * ```typescript
1095
+ * import { Home, User, Settings } from 'lucide';
1096
+ * import { createLucideLibrary } from '@truenas/ui-components';
1097
+ *
1098
+ * const lucideLibrary = createLucideLibrary({
1099
+ * home: Home,
1100
+ * user: User,
1101
+ * settings: Settings
1102
+ * });
1103
+ *
1104
+ * // Register manually
1105
+ * iconRegistry.registerLibrary(lucideLibrary);
1106
+ * ```
1107
+ */
1108
+ declare function createLucideLibrary(icons: Record<string, unknown>, defaultOptions?: LucideIconOptions): IconLibrary;
1109
+ /**
1110
+ * Register common Lucide icons individually
1111
+ * Useful when you only want specific icons to reduce bundle size
1112
+ *
1113
+ * @example
1114
+ * ```typescript
1115
+ * import { Home, User, Settings, Heart, Star } from 'lucide';
1116
+ * import { registerLucideIcons } from '@truenas/ui-components';
1117
+ *
1118
+ * registerLucideIcons({
1119
+ * home: Home,
1120
+ * user: User,
1121
+ * settings: Settings,
1122
+ * heart: Heart,
1123
+ * star: Star
1124
+ * });
1125
+ * ```
1126
+ */
1127
+ declare function registerLucideIcons(icons: Record<string, unknown>): void;
1128
+
1129
+ declare class TnListComponent {
1130
+ dense: _angular_core.InputSignal<boolean>;
1131
+ disabled: _angular_core.InputSignal<boolean>;
1132
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnListComponent, never>;
1133
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnListComponent, "tn-list", never, { "dense": { "alias": "dense"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
1134
+ }
1135
+
1136
+ declare class TnListItemComponent implements AfterContentInit {
1137
+ disabled: _angular_core.InputSignal<boolean>;
1138
+ clickable: _angular_core.InputSignal<boolean>;
1139
+ itemClick: _angular_core.OutputEmitterRef<Event>;
1140
+ protected hasLeadingContent: _angular_core.WritableSignal<boolean>;
1141
+ protected hasSecondaryTextContent: _angular_core.WritableSignal<boolean>;
1142
+ protected hasTrailingContent: _angular_core.WritableSignal<boolean>;
1143
+ protected hasPrimaryTextDirective: _angular_core.WritableSignal<boolean>;
1144
+ private elementRef;
1145
+ ngAfterContentInit(): void;
1146
+ private checkContentProjection;
1147
+ hasSecondaryText: _angular_core.Signal<boolean>;
1148
+ hasThirdText: _angular_core.Signal<boolean>;
1149
+ onClick(event: Event): void;
1150
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnListItemComponent, never>;
1151
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnListItemComponent, "tn-list-item", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; }, { "itemClick": "itemClick"; }, never, ["[tnListIcon], [tnListAvatar]", "[tnListItemTitle], [tnListItemPrimary]", "*", "[tnListItemLine], [tnListItemSecondary]", "[tnListItemTrailing]"], true, never>;
1152
+ }
1153
+
1154
+ declare class TnListSubheaderComponent {
1155
+ inset: _angular_core.InputSignal<boolean>;
1156
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnListSubheaderComponent, never>;
1157
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnListSubheaderComponent, "tn-list-subheader", never, { "inset": { "alias": "inset"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
1158
+ }
1159
+
1160
+ declare class TnListIconDirective {
1161
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnListIconDirective, never>;
1162
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnListIconDirective, "[tnListIcon]", never, {}, {}, never, never, true, never>;
1163
+ }
1164
+ declare class TnListAvatarDirective {
1165
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnListAvatarDirective, never>;
1166
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnListAvatarDirective, "[tnListAvatar]", never, {}, {}, never, never, true, never>;
1167
+ }
1168
+ declare class TnListItemTitleDirective {
1169
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnListItemTitleDirective, never>;
1170
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnListItemTitleDirective, "[tnListItemTitle]", never, {}, {}, never, never, true, never>;
1171
+ }
1172
+ declare class TnListItemLineDirective {
1173
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnListItemLineDirective, never>;
1174
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnListItemLineDirective, "[tnListItemLine]", never, {}, {}, never, never, true, never>;
1175
+ }
1176
+ declare class TnListItemPrimaryDirective {
1177
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnListItemPrimaryDirective, never>;
1178
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnListItemPrimaryDirective, "[tnListItemPrimary]", never, {}, {}, never, never, true, never>;
1179
+ }
1180
+ declare class TnListItemSecondaryDirective {
1181
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnListItemSecondaryDirective, never>;
1182
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnListItemSecondaryDirective, "[tnListItemSecondary]", never, {}, {}, never, never, true, never>;
1183
+ }
1184
+ declare class TnListItemTrailingDirective {
1185
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnListItemTrailingDirective, never>;
1186
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnListItemTrailingDirective, "[tnListItemTrailing]", never, {}, {}, never, never, true, never>;
1187
+ }
1188
+ declare class TnDividerDirective {
1189
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnDividerDirective, never>;
1190
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnDividerDirective, "tn-divider, [tnDivider]", never, {}, {}, never, never, true, never>;
1191
+ }
1192
+
1193
+ declare class TnDividerComponent {
1194
+ vertical: _angular_core.InputSignal<boolean>;
1195
+ inset: _angular_core.InputSignal<boolean>;
1196
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnDividerComponent, never>;
1197
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnDividerComponent, "tn-divider", never, { "vertical": { "alias": "vertical"; "required": false; "isSignal": true; }; "inset": { "alias": "inset"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1198
+ }
1199
+
1200
+ declare class TnListOptionComponent implements AfterContentInit {
1201
+ cdr: ChangeDetectorRef;
1202
+ elementRef: ElementRef<any>;
1203
+ value: _angular_core.InputSignal<unknown>;
1204
+ selected: _angular_core.InputSignal<boolean>;
1205
+ disabled: _angular_core.InputSignal<boolean>;
1206
+ color: _angular_core.InputSignal<"primary" | "warn" | "accent">;
1207
+ selectionChange: _angular_core.OutputEmitterRef<boolean>;
1208
+ selectionList?: {
1209
+ onOptionSelectionChange: () => void;
1210
+ };
1211
+ internalSelected: _angular_core.WritableSignal<boolean | null>;
1212
+ internalDisabled: _angular_core.WritableSignal<boolean | null>;
1213
+ internalColor: _angular_core.WritableSignal<"primary" | "warn" | "accent" | null>;
1214
+ effectiveSelected: _angular_core.Signal<boolean>;
1215
+ effectiveDisabled: _angular_core.Signal<boolean>;
1216
+ effectiveColor: _angular_core.Signal<"primary" | "warn" | "accent">;
1217
+ protected hasLeadingContent: _angular_core.WritableSignal<boolean>;
1218
+ protected hasSecondaryTextContent: _angular_core.WritableSignal<boolean>;
1219
+ protected hasPrimaryTextDirective: _angular_core.WritableSignal<boolean>;
1220
+ ngAfterContentInit(): void;
1221
+ private checkContentProjection;
1222
+ onClick(_event: Event): void;
1223
+ onKeydown(event: Event): void;
1224
+ toggle(): void;
1225
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnListOptionComponent, never>;
1226
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnListOptionComponent, "tn-list-option", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; }, never, ["[tnListIcon], [tnListAvatar]", "[tnListItemTitle], [tnListItemPrimary]", "*", "[tnListItemLine], [tnListItemSecondary]"], true, never>;
1227
+ }
1228
+
1229
+ interface TnSelectionChange {
1230
+ source: TnSelectionListComponent;
1231
+ options: TnListOptionComponent[];
1232
+ }
1233
+ declare class TnSelectionListComponent implements ControlValueAccessor {
1234
+ dense: _angular_core.InputSignal<boolean>;
1235
+ disabled: _angular_core.InputSignal<boolean>;
1236
+ multiple: _angular_core.InputSignal<boolean>;
1237
+ color: _angular_core.InputSignal<"primary" | "warn" | "accent">;
1238
+ selectionChange: _angular_core.OutputEmitterRef<TnSelectionChange>;
1239
+ options: _angular_core.Signal<readonly TnListOptionComponent[]>;
1240
+ private formDisabled;
1241
+ isDisabled: _angular_core.Signal<boolean>;
1242
+ private onChange;
1243
+ private onTouched;
1244
+ constructor();
1245
+ writeValue(value: unknown[]): void;
1246
+ registerOnChange(fn: (value: unknown[]) => void): void;
1247
+ registerOnTouched(fn: () => void): void;
1248
+ setDisabledState(isDisabled: boolean): void;
1249
+ onOptionSelectionChange(): void;
1250
+ get selectedOptions(): TnListOptionComponent[];
1251
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnSelectionListComponent, never>;
1252
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnSelectionListComponent, "tn-selection-list", never, { "dense": { "alias": "dense"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; }, ["options"], ["*"], true, never>;
1253
+ }
1254
+
1255
+ declare class TnHeaderCellDefDirective {
1256
+ template: TemplateRef<any>;
1257
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnHeaderCellDefDirective, never>;
1258
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnHeaderCellDefDirective, "[tnHeaderCellDef]", never, {}, {}, never, never, true, never>;
1259
+ }
1260
+ declare class TnCellDefDirective {
1261
+ template: TemplateRef<any>;
1262
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnCellDefDirective, never>;
1263
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnCellDefDirective, "[tnCellDef]", never, {}, {}, never, never, true, never>;
1264
+ }
1265
+ declare class TnTableColumnDirective {
1266
+ name: _angular_core.InputSignal<string>;
1267
+ headerTemplate: _angular_core.Signal<TemplateRef<any> | undefined>;
1268
+ cellTemplate: _angular_core.Signal<TemplateRef<any> | undefined>;
1269
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnTableColumnDirective, never>;
1270
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnTableColumnDirective, "[tnColumnDef]", ["tnColumnDef"], { "name": { "alias": "tnColumnDef"; "required": true; "isSignal": true; }; }, {}, ["headerTemplate", "cellTemplate"], never, true, never>;
1271
+ }
1272
+
1273
+ interface TnTableDataSource<T = unknown> {
1274
+ data?: T[];
1275
+ connect?(): T[];
1276
+ disconnect?(): void;
1277
+ }
1278
+ declare class TnTableComponent<T = unknown> {
1279
+ dataSource: _angular_core.InputSignal<TnTableDataSource<T> | T[]>;
1280
+ displayedColumns: _angular_core.InputSignal<string[]>;
1281
+ columnDefs: _angular_core.Signal<readonly TnTableColumnDirective[]>;
1282
+ private columnDefMap;
1283
+ private cdr;
1284
+ constructor();
1285
+ private processColumnDefs;
1286
+ data: _angular_core.Signal<T[]>;
1287
+ getColumnDef(columnName: string): TnTableColumnDirective | undefined;
1288
+ trackByIndex(index: number): number;
1289
+ getCellValue(row: T, column: string): unknown;
1290
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnTableComponent<any>, never>;
1291
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnTableComponent<any>, "tn-table", never, { "dataSource": { "alias": "dataSource"; "required": false; "isSignal": true; }; "displayedColumns": { "alias": "displayedColumns"; "required": false; "isSignal": true; }; }, {}, ["columnDefs"], never, true, never>;
1292
+ }
1293
+
1294
+ /** Flat node with expandable and level information */
1295
+ interface TnFlatTreeNode<T = unknown> {
1296
+ data: T;
1297
+ expandable: boolean;
1298
+ level: number;
1299
+ }
1300
+ /**
1301
+ * Tree flattener to convert normal type of node to node with children & level information.
1302
+ */
1303
+ declare class TnTreeFlattener<T, F> {
1304
+ transformFunction: (node: T, level: number) => F;
1305
+ getLevel: (node: F) => number;
1306
+ isExpandable: (node: F) => boolean;
1307
+ getChildren: (node: T) => T[] | null | undefined;
1308
+ constructor(transformFunction: (node: T, level: number) => F, getLevel: (node: F) => number, isExpandable: (node: F) => boolean, getChildren: (node: T) => T[] | null | undefined);
1309
+ flattenNodes(structuredData: T[]): F[];
1310
+ private _flattenNode;
1311
+ }
1312
+ /**
1313
+ * Data source for flat tree.
1314
+ */
1315
+ declare class TnTreeFlatDataSource<T, F> extends DataSource<F> {
1316
+ private _treeControl;
1317
+ private _treeFlattener;
1318
+ private _flattenedData;
1319
+ private _expandedData;
1320
+ private _data;
1321
+ constructor(_treeControl: FlatTreeControl<F>, _treeFlattener: TnTreeFlattener<T, F>);
1322
+ get data(): T[];
1323
+ set data(value: T[]);
1324
+ connect(): Observable<F[]>;
1325
+ disconnect(): void;
1326
+ private _getExpandedNodesWithLevel;
1327
+ }
1328
+ declare class TnTreeComponent<T, K = T> extends CdkTree<T, K> {
1329
+ constructor();
1330
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnTreeComponent<any, any>, never>;
1331
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnTreeComponent<any, any>, "tn-tree", ["tnTree"], {}, {}, never, never, true, never>;
1332
+ }
1333
+
1334
+ declare class TnTreeNodeComponent<T, K = T> extends CdkTreeNode<T, K> {
1335
+ constructor();
1336
+ /** The tree node's level in the tree */
1337
+ get level(): number;
1338
+ /** Whether the tree node is expandable */
1339
+ get isExpandable(): boolean;
1340
+ /** Whether the tree node is expanded */
1341
+ get isExpanded(): boolean;
1342
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnTreeNodeComponent<any, any>, never>;
1343
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnTreeNodeComponent<any, any>, "tn-tree-node", ["tnTreeNode"], {}, {}, never, ["*"], true, never>;
1344
+ }
1345
+
1346
+ declare class TnNestedTreeNodeComponent<T, K = T> extends CdkNestedTreeNode<T, K> {
1347
+ constructor();
1348
+ /** The tree node's level in the tree */
1349
+ get level(): number;
1350
+ /** Whether the tree node is expandable */
1351
+ get isExpandable(): boolean;
1352
+ /** Whether the tree node is expanded */
1353
+ get isExpanded(): boolean;
1354
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnNestedTreeNodeComponent<any, any>, never>;
1355
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnNestedTreeNodeComponent<any, any>, "tn-nested-tree-node", ["tnNestedTreeNode"], {}, {}, never, ["*", "[slot=children]"], true, never>;
1356
+ }
1357
+
1358
+ declare class TnTreeNodeOutletDirective {
1359
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnTreeNodeOutletDirective, never>;
1360
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnTreeNodeOutletDirective, "[tnTreeNodeOutlet]", never, {}, {}, never, never, true, [{ directive: typeof i1.CdkTreeNodeOutlet; inputs: {}; outputs: {}; }]>;
1361
+ }
1362
+
1363
+ declare enum CommonShortcuts {
1364
+ NEW = "\u2318N",
1365
+ OPEN = "\u2318O",
1366
+ SAVE = "\u2318S",
1367
+ SAVE_AS = "\u21E7\u2318S",
1368
+ PRINT = "\u2318P",
1369
+ CLOSE = "\u2318W",
1370
+ QUIT = "\u2318Q",
1371
+ UNDO = "\u2318Z",
1372
+ REDO = "\u21E7\u2318Z",
1373
+ CUT = "\u2318X",
1374
+ COPY = "\u2318C",
1375
+ PASTE = "\u2318V",
1376
+ SELECT_ALL = "\u2318A",
1377
+ FIND = "\u2318F",
1378
+ FIND_NEXT = "\u2318G",
1379
+ FIND_PREVIOUS = "\u21E7\u2318G",
1380
+ REPLACE = "\u2325\u2318F",
1381
+ ZOOM_IN = "\u2318=",
1382
+ ZOOM_OUT = "\u2318-",
1383
+ ZOOM_RESET = "\u23180",
1384
+ FULL_SCREEN = "\u2303\u2318F",
1385
+ BACK = "\u2318[",
1386
+ FORWARD = "\u2318]",
1387
+ RELOAD = "\u2318R",
1388
+ HOME = "\u2318H",
1389
+ NEW_WINDOW = "\u21E7\u2318N",
1390
+ NEW_TAB = "\u2318T",
1391
+ CLOSE_TAB = "\u2318W",
1392
+ MINIMIZE = "\u2318M",
1393
+ PREFERENCES = "\u2318,",
1394
+ HELP = "\u2318?",
1395
+ ABOUT = "\u2318I"
1396
+ }
1397
+ declare enum WindowsShortcuts {
1398
+ NEW = "Ctrl+N",
1399
+ OPEN = "Ctrl+O",
1400
+ SAVE = "Ctrl+S",
1401
+ SAVE_AS = "Ctrl+Shift+S",
1402
+ PRINT = "Ctrl+P",
1403
+ CLOSE = "Ctrl+W",
1404
+ QUIT = "Alt+F4",
1405
+ UNDO = "Ctrl+Z",
1406
+ REDO = "Ctrl+Y",
1407
+ CUT = "Ctrl+X",
1408
+ COPY = "Ctrl+C",
1409
+ PASTE = "Ctrl+V",
1410
+ SELECT_ALL = "Ctrl+A",
1411
+ FIND = "Ctrl+F",
1412
+ FIND_NEXT = "F3",
1413
+ FIND_PREVIOUS = "Shift+F3",
1414
+ REPLACE = "Ctrl+H",
1415
+ ZOOM_IN = "Ctrl+=",
1416
+ ZOOM_OUT = "Ctrl+-",
1417
+ ZOOM_RESET = "Ctrl+0",
1418
+ FULL_SCREEN = "F11",
1419
+ BACK = "Alt+Left",
1420
+ FORWARD = "Alt+Right",
1421
+ RELOAD = "Ctrl+R",
1422
+ HOME = "Alt+Home",
1423
+ NEW_WINDOW = "Ctrl+Shift+N",
1424
+ NEW_TAB = "Ctrl+T",
1425
+ CLOSE_TAB = "Ctrl+W",
1426
+ MINIMIZE = "Win+M",
1427
+ PREFERENCES = "Ctrl+,",
1428
+ HELP = "F1",
1429
+ ABOUT = "Alt+H+A"
1430
+ }
1431
+ declare enum LinuxShortcuts {
1432
+ NEW = "Ctrl+N",
1433
+ OPEN = "Ctrl+O",
1434
+ SAVE = "Ctrl+S",
1435
+ SAVE_AS = "Ctrl+Shift+S",
1436
+ PRINT = "Ctrl+P",
1437
+ CLOSE = "Ctrl+W",
1438
+ QUIT = "Ctrl+Q",
1439
+ UNDO = "Ctrl+Z",
1440
+ REDO = "Ctrl+Shift+Z",
1441
+ CUT = "Ctrl+X",
1442
+ COPY = "Ctrl+C",
1443
+ PASTE = "Ctrl+V",
1444
+ SELECT_ALL = "Ctrl+A",
1445
+ FIND = "Ctrl+F",
1446
+ FIND_NEXT = "Ctrl+G",
1447
+ FIND_PREVIOUS = "Ctrl+Shift+G",
1448
+ REPLACE = "Ctrl+H",
1449
+ ZOOM_IN = "Ctrl+=",
1450
+ ZOOM_OUT = "Ctrl+-",
1451
+ ZOOM_RESET = "Ctrl+0",
1452
+ FULL_SCREEN = "F11",
1453
+ BACK = "Alt+Left",
1454
+ FORWARD = "Alt+Right",
1455
+ RELOAD = "Ctrl+R",
1456
+ HOME = "Alt+Home",
1457
+ NEW_WINDOW = "Ctrl+Shift+N",
1458
+ NEW_TAB = "Ctrl+T",
1459
+ CLOSE_TAB = "Ctrl+W",
1460
+ MINIMIZE = "Ctrl+H",
1461
+ PREFERENCES = "Ctrl+,",
1462
+ HELP = "F1",
1463
+ ABOUT = "Ctrl+I"
1464
+ }
1465
+
1466
+ declare class ShortcutBuilder {
1467
+ private keysList;
1468
+ private targetPlatform;
1469
+ constructor(platform?: PlatformType);
1470
+ /**
1471
+ * Add Command key (⌘ on Mac, Ctrl on Windows/Linux)
1472
+ */
1473
+ command(): ShortcutBuilder;
1474
+ /**
1475
+ * Add Ctrl key
1476
+ */
1477
+ ctrl(): ShortcutBuilder;
1478
+ /**
1479
+ * Add Shift key (⇧ on Mac, Shift on Windows/Linux)
1480
+ */
1481
+ shift(): ShortcutBuilder;
1482
+ /**
1483
+ * Add Alt/Option key (⌥ on Mac, Alt on Windows/Linux)
1484
+ */
1485
+ alt(): ShortcutBuilder;
1486
+ /**
1487
+ * Add Option key (alias for alt on Mac)
1488
+ */
1489
+ option(): ShortcutBuilder;
1490
+ /**
1491
+ * Add Windows/Super key
1492
+ */
1493
+ windows(): ShortcutBuilder;
1494
+ /**
1495
+ * Add a regular key (letter, number, or special key)
1496
+ */
1497
+ key(key: string): ShortcutBuilder;
1498
+ /**
1499
+ * Add multiple keys at once
1500
+ */
1501
+ keys(...keys: string[]): ShortcutBuilder;
1502
+ /**
1503
+ * Reset the builder to start over
1504
+ */
1505
+ reset(): ShortcutBuilder;
1506
+ /**
1507
+ * Build the final shortcut string
1508
+ */
1509
+ build(): string;
1510
+ /**
1511
+ * Get the current keys array (for debugging)
1512
+ */
1513
+ getKeys(): string[];
1514
+ /**
1515
+ * Get the current platform
1516
+ */
1517
+ getPlatform(): PlatformType;
1518
+ /**
1519
+ * Change the target platform
1520
+ */
1521
+ setPlatform(platform: PlatformType): ShortcutBuilder;
1522
+ }
1523
+ /**
1524
+ * Create a new ShortcutBuilder instance
1525
+ */
1526
+ declare function createShortcut(platform?: PlatformType): ShortcutBuilder;
1527
+ /**
1528
+ * Quick builder functions for common patterns
1529
+ */
1530
+ declare const QuickShortcuts: {
1531
+ /**
1532
+ * Create a simple Command+Key shortcut
1533
+ */
1534
+ cmd(key: string, platform?: PlatformType): string;
1535
+ /**
1536
+ * Create a Shift+Command+Key shortcut
1537
+ */
1538
+ shiftCmd(key: string, platform?: PlatformType): string;
1539
+ /**
1540
+ * Create an Alt+Command+Key shortcut
1541
+ */
1542
+ altCmd(key: string, platform?: PlatformType): string;
1543
+ /**
1544
+ * Create a Ctrl+Key shortcut
1545
+ */
1546
+ ctrl(key: string, platform?: PlatformType): string;
1547
+ /**
1548
+ * Create an Alt+Key shortcut
1549
+ */
1550
+ alt(key: string, platform?: PlatformType): string;
1551
+ };
1552
+
1553
+ declare class FileSizePipe implements PipeTransform {
1554
+ transform(value: number): string;
1555
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<FileSizePipe, never>;
1556
+ static ɵpipe: _angular_core.ɵɵPipeDeclaration<FileSizePipe, "tnFileSize", true>;
1557
+ }
1558
+
1559
+ declare class StripMntPrefixPipe implements PipeTransform {
1560
+ transform(path: string | null | undefined): string;
1561
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<StripMntPrefixPipe, never>;
1562
+ static ɵpipe: _angular_core.ɵɵPipeDeclaration<StripMntPrefixPipe, "tnStripMntPrefix", true>;
1563
+ }
1564
+
1565
+ interface FileSystemItem {
1566
+ path: string;
1567
+ name: string;
1568
+ type: 'file' | 'folder' | 'dataset' | 'zvol' | 'mountpoint';
1569
+ size?: number;
1570
+ modified?: Date;
1571
+ permissions?: 'read' | 'write' | 'none';
1572
+ icon?: string;
1573
+ disabled?: boolean;
1574
+ isCreating?: boolean;
1575
+ tempId?: string;
1576
+ creationError?: string;
1577
+ }
1578
+ interface FilePickerCallbacks {
1579
+ getChildren?: (path: string) => Promise<FileSystemItem[]>;
1580
+ validatePath?: (path: string) => Promise<boolean>;
1581
+ createFolder?: (parentPath: string, name: string) => Promise<string>;
1582
+ createDataset?: (parentPath: string) => Promise<string>;
1583
+ createZvol?: (parentPath: string) => Promise<string>;
1584
+ }
1585
+ interface CreateFolderEvent {
1586
+ parentPath: string;
1587
+ folderName: string;
1588
+ }
1589
+ interface FilePickerError {
1590
+ type: 'navigation' | 'permission' | 'creation' | 'validation';
1591
+ message: string;
1592
+ path?: string;
1593
+ }
1594
+ interface PathSegment {
1595
+ name: string;
1596
+ path: string;
1597
+ }
1598
+ type FilePickerMode = 'file' | 'folder' | 'dataset' | 'zvol' | 'any';
1599
+
1600
+ declare class TruncatePathPipe implements PipeTransform {
1601
+ transform(path: string): PathSegment[];
1602
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TruncatePathPipe, never>;
1603
+ static ɵpipe: _angular_core.ɵɵPipeDeclaration<TruncatePathPipe, "tnTruncatePath", true>;
1604
+ }
1605
+
1606
+ type SpinnerMode = 'determinate' | 'indeterminate';
1607
+ declare class TnSpinnerComponent {
1608
+ mode: _angular_core.InputSignal<SpinnerMode>;
1609
+ value: _angular_core.InputSignal<number>;
1610
+ diameter: _angular_core.InputSignal<number>;
1611
+ strokeWidth: _angular_core.InputSignal<number>;
1612
+ ariaLabel: _angular_core.InputSignal<string | null>;
1613
+ ariaLabelledby: _angular_core.InputSignal<string | null>;
1614
+ radius: _angular_core.Signal<number>;
1615
+ circumference: _angular_core.Signal<number>;
1616
+ strokeDasharray: _angular_core.Signal<string>;
1617
+ strokeDashoffset: _angular_core.Signal<number>;
1618
+ viewBox: _angular_core.Signal<string>;
1619
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnSpinnerComponent, never>;
1620
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnSpinnerComponent, "tn-spinner", never, { "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "diameter": { "alias": "diameter"; "required": false; "isSignal": true; }; "strokeWidth": { "alias": "strokeWidth"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "ariaLabelledby"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1621
+ }
1622
+
1623
+ declare class TnBrandedSpinnerComponent implements OnInit, OnDestroy, AfterViewInit {
1624
+ ariaLabel: _angular_core.InputSignal<string | null>;
1625
+ private paths;
1626
+ private animationId;
1627
+ private isAnimating;
1628
+ private readonly duration;
1629
+ private readonly delayStep;
1630
+ private readonly cyclePause;
1631
+ private readonly emptyPause;
1632
+ private elementRef;
1633
+ ngOnInit(): void;
1634
+ ngAfterViewInit(): void;
1635
+ ngOnDestroy(): void;
1636
+ private startProgressLoop;
1637
+ private animateSequence;
1638
+ private tween;
1639
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnBrandedSpinnerComponent, never>;
1640
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnBrandedSpinnerComponent, "tn-branded-spinner", never, { "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1641
+ }
1642
+
1643
+ type ProgressBarMode = 'determinate' | 'indeterminate' | 'buffer';
1644
+ declare class TnProgressBarComponent {
1645
+ mode: _angular_core.InputSignal<ProgressBarMode>;
1646
+ value: _angular_core.InputSignal<number>;
1647
+ bufferValue: _angular_core.InputSignal<number>;
1648
+ ariaLabel: _angular_core.InputSignal<string | null>;
1649
+ ariaLabelledby: _angular_core.InputSignal<string | null>;
1650
+ /**
1651
+ * Gets the transform value for the primary progress bar
1652
+ */
1653
+ primaryTransform: _angular_core.Signal<string>;
1654
+ /**
1655
+ * Gets the positioning and size for the buffer dots animation
1656
+ */
1657
+ bufferStyles: _angular_core.Signal<{
1658
+ width: string;
1659
+ right: string;
1660
+ }>;
1661
+ /**
1662
+ * Gets the transform value for the buffer progress bar (deprecated - use bufferStyles)
1663
+ */
1664
+ bufferTransform: _angular_core.Signal<string>;
1665
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnProgressBarComponent, never>;
1666
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnProgressBarComponent, "tn-progress-bar", never, { "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "bufferValue": { "alias": "bufferValue"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "ariaLabelledby"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1667
+ }
1668
+
1669
+ declare class TnParticleProgressBarComponent implements AfterViewInit, OnDestroy {
1670
+ speed: _angular_core.InputSignal<"medium" | "slow" | "fast" | "ludicrous">;
1671
+ color: _angular_core.InputSignal<string>;
1672
+ height: _angular_core.InputSignal<number>;
1673
+ width: _angular_core.InputSignal<number>;
1674
+ fill: _angular_core.InputSignal<number>;
1675
+ canvasRef: _angular_core.Signal<ElementRef<HTMLCanvasElement>>;
1676
+ private ctx;
1677
+ private particles;
1678
+ private shades;
1679
+ private animationId?;
1680
+ private speedConfig;
1681
+ /**
1682
+ * Calculate the gradient offset so the transition only happens in the last 100px
1683
+ */
1684
+ gradientTransitionStart: _angular_core.Signal<number>;
1685
+ /**
1686
+ * Get the color for the progress bar (uses the exact same color as input)
1687
+ */
1688
+ progressBarColor: _angular_core.Signal<string>;
1689
+ ngAfterViewInit(): void;
1690
+ ngOnDestroy(): void;
1691
+ private animate;
1692
+ private spawnParticle;
1693
+ private parseHSLA;
1694
+ /**
1695
+ * Convert any color format to HSLA
1696
+ */
1697
+ private convertToHSLA;
1698
+ /**
1699
+ * Generate darker shades of the input color for particle depth effect
1700
+ */
1701
+ private generateDarkerShades;
1702
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnParticleProgressBarComponent, never>;
1703
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnParticleProgressBarComponent, "tn-particle-progress-bar", never, { "speed": { "alias": "speed"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "fill": { "alias": "fill"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1704
+ }
1705
+
1706
+ interface DateRange {
1707
+ start: Date | null;
1708
+ end: Date | null;
1709
+ }
1710
+ declare class TnDateRangeInputComponent implements ControlValueAccessor, OnInit, OnDestroy {
1711
+ disabled: _angular_core.InputSignal<boolean>;
1712
+ placeholder: _angular_core.InputSignal<string>;
1713
+ private formDisabled;
1714
+ isDisabled: _angular_core.Signal<boolean>;
1715
+ startMonthRef: _angular_core.Signal<ElementRef<HTMLInputElement>>;
1716
+ startDayRef: _angular_core.Signal<ElementRef<HTMLInputElement>>;
1717
+ startYearRef: _angular_core.Signal<ElementRef<HTMLInputElement>>;
1718
+ endMonthRef: _angular_core.Signal<ElementRef<HTMLInputElement>>;
1719
+ endDayRef: _angular_core.Signal<ElementRef<HTMLInputElement>>;
1720
+ endYearRef: _angular_core.Signal<ElementRef<HTMLInputElement>>;
1721
+ calendarTemplate: _angular_core.Signal<TemplateRef<unknown>>;
1722
+ calendar: _angular_core.Signal<TnCalendarComponent>;
1723
+ wrapperEl: _angular_core.Signal<ElementRef<HTMLDivElement>>;
1724
+ private destroy$;
1725
+ private overlayRef?;
1726
+ private portal?;
1727
+ isOpen: _angular_core.WritableSignal<boolean>;
1728
+ private onChange;
1729
+ private onTouched;
1730
+ value: _angular_core.WritableSignal<DateRange>;
1731
+ startMonth: _angular_core.WritableSignal<string>;
1732
+ startDay: _angular_core.WritableSignal<string>;
1733
+ startYear: _angular_core.WritableSignal<string>;
1734
+ endMonth: _angular_core.WritableSignal<string>;
1735
+ endDay: _angular_core.WritableSignal<string>;
1736
+ endYear: _angular_core.WritableSignal<string>;
1737
+ private currentFocus;
1738
+ initialRange: _angular_core.Signal<DateRange>;
1739
+ private overlay;
1740
+ private viewContainerRef;
1741
+ ngOnInit(): void;
1742
+ ngOnDestroy(): void;
1743
+ writeValue(value: DateRange): void;
1744
+ registerOnChange(fn: (value: DateRange) => void): void;
1745
+ registerOnTouched(fn: () => void): void;
1746
+ setDisabledState(isDisabled: boolean): void;
1747
+ onSegmentFocus(range: 'start' | 'end', _segment: 'month' | 'day' | 'year'): void;
1748
+ onSegmentBlur(range: 'start' | 'end', _segment: 'month' | 'day' | 'year'): void;
1749
+ onSegmentKeydown(event: KeyboardEvent, range: 'start' | 'end', segment: 'month' | 'day' | 'year'): void;
1750
+ onRangeSelected(range: DateRange): void;
1751
+ private updateRange;
1752
+ private updateDisplayValues;
1753
+ private setSegmentValue;
1754
+ private updateDateFromSegments;
1755
+ private focusNextSegment;
1756
+ private focusPrevSegment;
1757
+ openDatepicker(): void;
1758
+ close(): void;
1759
+ private createOverlay;
1760
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnDateRangeInputComponent, never>;
1761
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnDateRangeInputComponent, "tn-date-range-input", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1762
+ }
1763
+
1764
+ declare class TnCalendarComponent implements OnInit {
1765
+ startView: _angular_core.InputSignal<"month" | "year">;
1766
+ selected: _angular_core.InputSignal<Date | null | undefined>;
1767
+ minDate: _angular_core.InputSignal<Date | undefined>;
1768
+ maxDate: _angular_core.InputSignal<Date | undefined>;
1769
+ dateFilter: _angular_core.InputSignal<((date: Date) => boolean) | undefined>;
1770
+ rangeMode: _angular_core.InputSignal<boolean>;
1771
+ selectedRange: _angular_core.InputSignal<DateRange | undefined>;
1772
+ selectedChange: _angular_core.OutputEmitterRef<Date>;
1773
+ activeDateChange: _angular_core.OutputEmitterRef<Date>;
1774
+ viewChanged: _angular_core.OutputEmitterRef<"month" | "year">;
1775
+ selectedRangeChange: _angular_core.OutputEmitterRef<DateRange>;
1776
+ currentDate: _angular_core.WritableSignal<Date>;
1777
+ currentView: _angular_core.WritableSignal<"month" | "year">;
1778
+ rangeState: _angular_core.WritableSignal<{
1779
+ start: Date | null;
1780
+ end: Date | null;
1781
+ selecting: "start" | "end";
1782
+ }>;
1783
+ private userHasInteracted;
1784
+ constructor();
1785
+ ngOnInit(): void;
1786
+ private initializeRangeState;
1787
+ onMonthSelected(month: number): void;
1788
+ onYearSelected(year: number): void;
1789
+ onViewChanged(view: 'month' | 'year'): void;
1790
+ onPreviousClicked(): void;
1791
+ onNextClicked(): void;
1792
+ onSelectedChange(date: Date): void;
1793
+ private handleRangeSelection;
1794
+ onActiveDateChange(date: Date): void;
1795
+ onYearSelectedFromView(date: Date): void;
1796
+ /**
1797
+ * Reset the calendar to accept external range values - called when calendar reopens
1798
+ */
1799
+ resetInteractionState(): void;
1800
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnCalendarComponent, never>;
1801
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnCalendarComponent, "tn-calendar", never, { "startView": { "alias": "startView"; "required": false; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "minDate": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxDate": { "alias": "maxDate"; "required": false; "isSignal": true; }; "dateFilter": { "alias": "dateFilter"; "required": false; "isSignal": true; }; "rangeMode": { "alias": "rangeMode"; "required": false; "isSignal": true; }; "selectedRange": { "alias": "selectedRange"; "required": false; "isSignal": true; }; }, { "selectedChange": "selectedChange"; "activeDateChange": "activeDateChange"; "viewChanged": "viewChanged"; "selectedRangeChange": "selectedRangeChange"; }, never, never, true, never>;
1802
+ }
1803
+
1804
+ declare class TnCalendarHeaderComponent {
1805
+ currentDate: _angular_core.InputSignal<Date>;
1806
+ currentView: _angular_core.InputSignal<"month" | "year">;
1807
+ monthSelected: _angular_core.OutputEmitterRef<number>;
1808
+ yearSelected: _angular_core.OutputEmitterRef<number>;
1809
+ viewChanged: _angular_core.OutputEmitterRef<"month" | "year">;
1810
+ previousClicked: _angular_core.OutputEmitterRef<void>;
1811
+ nextClicked: _angular_core.OutputEmitterRef<void>;
1812
+ private months;
1813
+ periodLabelId: string;
1814
+ periodLabel: _angular_core.Signal<string>;
1815
+ previousLabel: _angular_core.Signal<"Previous month" | "Previous 24 years">;
1816
+ nextLabel: _angular_core.Signal<"Next month" | "Next 24 years">;
1817
+ toggleView(): void;
1818
+ onPreviousClick(): void;
1819
+ onNextClick(): void;
1820
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnCalendarHeaderComponent, never>;
1821
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnCalendarHeaderComponent, "tn-calendar-header", never, { "currentDate": { "alias": "currentDate"; "required": false; "isSignal": true; }; "currentView": { "alias": "currentView"; "required": false; "isSignal": true; }; }, { "monthSelected": "monthSelected"; "yearSelected": "yearSelected"; "viewChanged": "viewChanged"; "previousClicked": "previousClicked"; "nextClicked": "nextClicked"; }, never, never, true, never>;
1822
+ }
1823
+
1824
+ interface CalendarCell {
1825
+ value: number;
1826
+ date: Date;
1827
+ label: string;
1828
+ ariaLabel: string;
1829
+ enabled: boolean;
1830
+ selected: boolean;
1831
+ today: boolean;
1832
+ compareStart?: boolean;
1833
+ compareEnd?: boolean;
1834
+ rangeStart?: boolean;
1835
+ rangeEnd?: boolean;
1836
+ inRange?: boolean;
1837
+ }
1838
+ declare class TnMonthViewComponent {
1839
+ activeDate: _angular_core.InputSignal<Date>;
1840
+ selected: _angular_core.InputSignal<Date | null | undefined>;
1841
+ minDate: _angular_core.InputSignal<Date | undefined>;
1842
+ maxDate: _angular_core.InputSignal<Date | undefined>;
1843
+ dateFilter: _angular_core.InputSignal<((date: Date) => boolean) | undefined>;
1844
+ rangeMode: _angular_core.InputSignal<boolean>;
1845
+ selectedRange: _angular_core.InputSignal<{
1846
+ start: Date | null;
1847
+ end: Date | null;
1848
+ selecting: "start" | "end";
1849
+ } | undefined>;
1850
+ selectedChange: _angular_core.OutputEmitterRef<Date>;
1851
+ activeDateChange: _angular_core.OutputEmitterRef<Date>;
1852
+ readonly weekdays: {
1853
+ long: string;
1854
+ short: string;
1855
+ }[];
1856
+ calendarRows: _angular_core.Signal<CalendarCell[][]>;
1857
+ private createCell;
1858
+ private createEmptyCell;
1859
+ private isDateEnabled;
1860
+ private isSameDate;
1861
+ private formatAriaLabel;
1862
+ trackByDate(index: number, cell: CalendarCell): string;
1863
+ trackByRow(index: number, row: CalendarCell[]): string;
1864
+ onCellClicked(cell: CalendarCell): void;
1865
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnMonthViewComponent, never>;
1866
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnMonthViewComponent, "tn-month-view", never, { "activeDate": { "alias": "activeDate"; "required": false; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "minDate": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxDate": { "alias": "maxDate"; "required": false; "isSignal": true; }; "dateFilter": { "alias": "dateFilter"; "required": false; "isSignal": true; }; "rangeMode": { "alias": "rangeMode"; "required": false; "isSignal": true; }; "selectedRange": { "alias": "selectedRange"; "required": false; "isSignal": true; }; }, { "selectedChange": "selectedChange"; "activeDateChange": "activeDateChange"; }, never, never, true, never>;
1867
+ }
1868
+
1869
+ interface YearCell {
1870
+ value: number;
1871
+ year: number;
1872
+ label: string;
1873
+ ariaLabel: string;
1874
+ enabled: boolean;
1875
+ selected: boolean;
1876
+ today: boolean;
1877
+ }
1878
+ declare class TnMultiYearViewComponent {
1879
+ activeDate: _angular_core.InputSignal<Date>;
1880
+ selected: _angular_core.InputSignal<Date | null | undefined>;
1881
+ minDate: _angular_core.InputSignal<Date | undefined>;
1882
+ maxDate: _angular_core.InputSignal<Date | undefined>;
1883
+ dateFilter: _angular_core.InputSignal<((date: Date) => boolean) | undefined>;
1884
+ selectedChange: _angular_core.OutputEmitterRef<Date>;
1885
+ activeDateChange: _angular_core.OutputEmitterRef<Date>;
1886
+ readonly cellWidth = 25;
1887
+ readonly cellAspectRatio = 7.14286;
1888
+ readonly yearsPerRow = 4;
1889
+ readonly yearRowCount = 6;
1890
+ yearRange: _angular_core.Signal<{
1891
+ start: number;
1892
+ end: number;
1893
+ }>;
1894
+ yearRows: _angular_core.Signal<YearCell[][]>;
1895
+ private createYearCell;
1896
+ private isYearEnabled;
1897
+ private formatYearAriaLabel;
1898
+ trackByYear(index: number, cell: YearCell): number;
1899
+ trackByRow(index: number, row: YearCell[]): string;
1900
+ onYearClicked(cell: YearCell): void;
1901
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnMultiYearViewComponent, never>;
1902
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnMultiYearViewComponent, "tn-multi-year-view", never, { "activeDate": { "alias": "activeDate"; "required": false; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "minDate": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxDate": { "alias": "maxDate"; "required": false; "isSignal": true; }; "dateFilter": { "alias": "dateFilter"; "required": false; "isSignal": true; }; }, { "selectedChange": "selectedChange"; "activeDateChange": "activeDateChange"; }, never, never, true, never>;
1903
+ }
1904
+
1905
+ declare class TnDateInputComponent implements ControlValueAccessor, OnInit, OnDestroy {
1906
+ overlay: Overlay;
1907
+ viewContainerRef: ViewContainerRef;
1908
+ disabled: _angular_core.InputSignal<boolean>;
1909
+ placeholder: _angular_core.InputSignal<string>;
1910
+ min: _angular_core.InputSignal<Date | undefined>;
1911
+ max: _angular_core.InputSignal<Date | undefined>;
1912
+ dateFilter: _angular_core.InputSignal<((date: Date) => boolean) | undefined>;
1913
+ private formDisabled;
1914
+ isDisabled: _angular_core.Signal<boolean>;
1915
+ monthRef: _angular_core.Signal<ElementRef<HTMLInputElement>>;
1916
+ dayRef: _angular_core.Signal<ElementRef<HTMLInputElement>>;
1917
+ yearRef: _angular_core.Signal<ElementRef<HTMLInputElement>>;
1918
+ calendarTemplate: _angular_core.Signal<TemplateRef<unknown>>;
1919
+ calendar: _angular_core.Signal<TnCalendarComponent>;
1920
+ wrapperEl: _angular_core.Signal<ElementRef<HTMLDivElement>>;
1921
+ private destroy$;
1922
+ private overlayRef?;
1923
+ private portal?;
1924
+ isOpen: _angular_core.WritableSignal<boolean>;
1925
+ private onChange;
1926
+ private onTouched;
1927
+ value: _angular_core.WritableSignal<Date | null>;
1928
+ month: _angular_core.WritableSignal<string>;
1929
+ day: _angular_core.WritableSignal<string>;
1930
+ year: _angular_core.WritableSignal<string>;
1931
+ ngOnInit(): void;
1932
+ ngOnDestroy(): void;
1933
+ writeValue(value: Date | null): void;
1934
+ registerOnChange(fn: (value: Date | null) => void): void;
1935
+ registerOnTouched(fn: () => void): void;
1936
+ setDisabledState(isDisabled: boolean): void;
1937
+ onSegmentFocus(_segment: 'month' | 'day' | 'year'): void;
1938
+ onSegmentBlur(_segment: 'month' | 'day' | 'year'): void;
1939
+ onSegmentKeydown(event: KeyboardEvent, segment: 'month' | 'day' | 'year'): void;
1940
+ onDateSelected(date: Date): void;
1941
+ private updateDate;
1942
+ private updateDisplayValues;
1943
+ private updateDateFromSegments;
1944
+ private focusNextSegment;
1945
+ private focusPrevSegment;
1946
+ openDatepicker(): void;
1947
+ close(): void;
1948
+ private createOverlay;
1949
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnDateInputComponent, never>;
1950
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnDateInputComponent, "tn-date-input", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "dateFilter": { "alias": "dateFilter"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1951
+ }
1952
+
1953
+ declare class TnTimeInputComponent implements ControlValueAccessor {
1954
+ disabled: _angular_core.InputSignal<boolean>;
1955
+ format: _angular_core.InputSignal<"12h" | "24h">;
1956
+ granularity: _angular_core.InputSignal<"15m" | "30m" | "1h">;
1957
+ placeholder: _angular_core.InputSignal<string>;
1958
+ testId: _angular_core.InputSignal<string>;
1959
+ private formDisabled;
1960
+ isDisabled: _angular_core.Signal<boolean>;
1961
+ private step;
1962
+ private onChange;
1963
+ private onTouched;
1964
+ _value: string | null;
1965
+ timeSelectOptions: _angular_core.Signal<TnSelectOption<string>[]>;
1966
+ writeValue(value: string): void;
1967
+ registerOnChange(fn: (value: string) => void): void;
1968
+ registerOnTouched(fn: () => void): void;
1969
+ setDisabledState(isDisabled: boolean): void;
1970
+ onSelectionChange(value: string): void;
1971
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnTimeInputComponent, never>;
1972
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnTimeInputComponent, "tn-time-input", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "format": { "alias": "format"; "required": false; "isSignal": true; }; "granularity": { "alias": "granularity"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1973
+ }
1974
+
1975
+ declare class TnSliderThumbDirective implements ControlValueAccessor, OnInit, OnDestroy {
1976
+ disabled: _angular_core.WritableSignal<boolean>;
1977
+ slider?: {
1978
+ isDisabled: () => boolean;
1979
+ min: () => number;
1980
+ max: () => number;
1981
+ step: () => number;
1982
+ value: () => number;
1983
+ updateValue: (value: number) => void;
1984
+ getSliderRect: () => DOMRect;
1985
+ };
1986
+ onTouched: () => void;
1987
+ private onChangeCallback;
1988
+ private isDragging;
1989
+ private elementRef;
1990
+ ngOnInit(): void;
1991
+ ngOnDestroy(): void;
1992
+ writeValue(value: number): void;
1993
+ registerOnChange(fn: (value: number) => void): void;
1994
+ registerOnTouched(fn: () => void): void;
1995
+ setDisabledState(isDisabled: boolean): void;
1996
+ onInput(event: Event): void;
1997
+ onChange(_event: Event): void;
1998
+ onMouseDown(event: MouseEvent): void;
1999
+ onTouchStart(event: TouchEvent): void;
2000
+ private addGlobalListeners;
2001
+ private removeGlobalListeners;
2002
+ private onGlobalMouseMove;
2003
+ private onGlobalMouseUp;
2004
+ private onGlobalTouchMove;
2005
+ private onGlobalTouchEnd;
2006
+ private updateValueFromPosition;
2007
+ private cleanup;
2008
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnSliderThumbDirective, never>;
2009
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnSliderThumbDirective, "input[tnSliderThumb]", never, {}, {}, never, never, true, never>;
2010
+ }
2011
+
2012
+ type LabelType = 'none' | 'handle' | 'track' | 'both';
2013
+ declare class TnSliderComponent implements ControlValueAccessor, OnDestroy, AfterViewInit {
2014
+ min: _angular_core.InputSignal<number>;
2015
+ max: _angular_core.InputSignal<number>;
2016
+ step: _angular_core.InputSignal<number>;
2017
+ disabled: _angular_core.InputSignal<boolean>;
2018
+ labelPrefix: _angular_core.InputSignal<string>;
2019
+ labelSuffix: _angular_core.InputSignal<string>;
2020
+ labelType: _angular_core.InputSignal<LabelType>;
2021
+ thumbDirective: _angular_core.Signal<TnSliderThumbDirective>;
2022
+ sliderContainer: _angular_core.Signal<ElementRef<HTMLDivElement>>;
2023
+ thumbVisual: _angular_core.Signal<ElementRef<HTMLDivElement>>;
2024
+ private onChange;
2025
+ private onTouched;
2026
+ value: _angular_core.WritableSignal<number>;
2027
+ private _showLabel;
2028
+ private _labelVisible;
2029
+ private formDisabled;
2030
+ isDisabled: _angular_core.Signal<boolean>;
2031
+ fillPercentage: _angular_core.Signal<number>;
2032
+ fillScale: _angular_core.Signal<number>;
2033
+ thumbPosition: _angular_core.Signal<number>;
2034
+ showLabel: _angular_core.Signal<boolean>;
2035
+ labelVisible: _angular_core.Signal<boolean>;
2036
+ constructor();
2037
+ ngAfterViewInit(): void;
2038
+ ngOnDestroy(): void;
2039
+ writeValue(value: number): void;
2040
+ registerOnChange(fn: (value: number) => void): void;
2041
+ registerOnTouched(fn: () => void): void;
2042
+ setDisabledState(isDisabled: boolean): void;
2043
+ updateValue(newValue: number): void;
2044
+ enableLabel(): void;
2045
+ showThumbLabel(): void;
2046
+ hideThumbLabel(): void;
2047
+ getSliderRect(): DOMRect;
2048
+ onTrackClick(event: MouseEvent | TouchEvent): void;
2049
+ private updateThumbPosition;
2050
+ private clampValue;
2051
+ private setupHandleInteractionListeners;
2052
+ private cleanupHandleInteractionListeners;
2053
+ private onInteractionStart;
2054
+ private onInteractionEnd;
2055
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnSliderComponent, never>;
2056
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnSliderComponent, "tn-slider", never, { "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "labelPrefix": { "alias": "labelPrefix"; "required": false; "isSignal": true; }; "labelSuffix": { "alias": "labelSuffix"; "required": false; "isSignal": true; }; "labelType": { "alias": "labelType"; "required": false; "isSignal": true; }; }, {}, ["thumbDirective"], ["*"], true, never>;
2057
+ }
2058
+
2059
+ declare class TnSliderWithLabelDirective implements OnInit, OnDestroy {
2060
+ enabled: _angular_core.InputSignal<string | boolean>;
2061
+ private _elementRef;
2062
+ private _slider;
2063
+ ngOnInit(): void;
2064
+ private _setupInteractionListeners;
2065
+ ngOnDestroy(): void;
2066
+ private _onInteractionStart;
2067
+ private _onInteractionEnd;
2068
+ private _cleanup;
2069
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnSliderWithLabelDirective, never>;
2070
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnSliderWithLabelDirective, "tn-slider[tnSliderWithLabel]", never, { "enabled": { "alias": "tnSliderWithLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2071
+ }
2072
+
2073
+ type TnButtonToggleType = 'checkbox' | 'radio';
2074
+ declare class TnButtonToggleGroupComponent implements ControlValueAccessor {
2075
+ buttonToggles: _angular_core.Signal<readonly TnButtonToggleComponent[]>;
2076
+ multiple: _angular_core.InputSignal<boolean>;
2077
+ disabled: _angular_core.InputSignal<boolean>;
2078
+ name: _angular_core.InputSignal<string>;
2079
+ ariaLabel: _angular_core.InputSignal<string>;
2080
+ ariaLabelledby: _angular_core.InputSignal<string>;
2081
+ change: _angular_core.OutputEmitterRef<{
2082
+ source: TnButtonToggleComponent;
2083
+ value: unknown;
2084
+ }>;
2085
+ private selectedValue;
2086
+ private selectedValues;
2087
+ private formDisabled;
2088
+ isDisabled: _angular_core.Signal<boolean>;
2089
+ private onChange;
2090
+ private onTouched;
2091
+ constructor();
2092
+ writeValue(value: unknown): void;
2093
+ registerOnChange(fn: (value: unknown) => void): void;
2094
+ registerOnTouched(fn: () => void): void;
2095
+ setDisabledState(isDisabled: boolean): void;
2096
+ _onButtonToggleClick(clickedToggle: TnButtonToggleComponent): void;
2097
+ private handleSingleSelection;
2098
+ private handleMultipleSelection;
2099
+ private updateTogglesFromValue;
2100
+ private updateTogglesFromValues;
2101
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnButtonToggleGroupComponent, never>;
2102
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnButtonToggleGroupComponent, "tn-button-toggle-group", never, { "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "ariaLabelledby"; "required": false; "isSignal": true; }; }, { "change": "change"; }, ["buttonToggles"], ["*"], true, never>;
2103
+ }
2104
+
2105
+ declare class TnButtonToggleComponent implements ControlValueAccessor {
2106
+ cdr: ChangeDetectorRef;
2107
+ private static _uniqueIdCounter;
2108
+ id: _angular_core.InputSignal<string>;
2109
+ value: _angular_core.InputSignal<unknown>;
2110
+ disabled: _angular_core.InputSignal<boolean>;
2111
+ checked: _angular_core.WritableSignal<boolean>;
2112
+ ariaLabel: _angular_core.InputSignal<string>;
2113
+ ariaLabelledby: _angular_core.InputSignal<string>;
2114
+ change: _angular_core.OutputEmitterRef<{
2115
+ source: TnButtonToggleComponent;
2116
+ value: unknown;
2117
+ }>;
2118
+ buttonId: _angular_core.Signal<string>;
2119
+ buttonToggleGroup?: TnButtonToggleGroupComponent;
2120
+ private formDisabled;
2121
+ isDisabled: _angular_core.Signal<boolean>;
2122
+ private onChange;
2123
+ private onTouched;
2124
+ writeValue(value: boolean): void;
2125
+ registerOnChange(fn: (value: boolean) => void): void;
2126
+ registerOnTouched(fn: () => void): void;
2127
+ setDisabledState(isDisabled: boolean): void;
2128
+ toggle(): void;
2129
+ onFocus(): void;
2130
+ _markForCheck(): void;
2131
+ _markForUncheck(): void;
2132
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnButtonToggleComponent, never>;
2133
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnButtonToggleComponent, "tn-button-toggle", never, { "id": { "alias": "id"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "ariaLabelledby"; "required": false; "isSignal": true; }; }, { "change": "change"; }, never, ["*"], true, never>;
2134
+ }
2135
+
2136
+ type TooltipPosition = 'above' | 'below' | 'left' | 'right' | 'before' | 'after';
2137
+ declare class TnTooltipDirective implements OnInit, OnDestroy {
2138
+ message: _angular_core.InputSignal<string>;
2139
+ position: _angular_core.InputSignal<TooltipPosition>;
2140
+ disabled: _angular_core.InputSignal<boolean>;
2141
+ showDelay: _angular_core.InputSignal<number>;
2142
+ hideDelay: _angular_core.InputSignal<number>;
2143
+ tooltipClass: _angular_core.InputSignal<string>;
2144
+ private _overlayRef;
2145
+ private _tooltipInstance;
2146
+ private _showTimeout;
2147
+ private _hideTimeout;
2148
+ private _isTooltipVisible;
2149
+ protected _ariaDescribedBy: string | null;
2150
+ private _overlay;
2151
+ private _elementRef;
2152
+ private _viewContainerRef;
2153
+ private _overlayPositionBuilder;
2154
+ ngOnInit(): void;
2155
+ ngOnDestroy(): void;
2156
+ _onMouseEnter(): void;
2157
+ _onMouseLeave(): void;
2158
+ _onFocus(): void;
2159
+ _onBlur(): void;
2160
+ _onKeydown(event: KeyboardEvent): void;
2161
+ /** Shows the tooltip */
2162
+ show(delay?: number): void;
2163
+ /** Hides the tooltip */
2164
+ hide(delay?: number): void;
2165
+ /** Toggle the tooltip visibility */
2166
+ toggle(): void;
2167
+ private _createOverlay;
2168
+ private _attachTooltip;
2169
+ private _getPositions;
2170
+ private _clearTimeouts;
2171
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnTooltipDirective, never>;
2172
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<TnTooltipDirective, "[tnTooltip]", never, { "message": { "alias": "tnTooltip"; "required": false; "isSignal": true; }; "position": { "alias": "tnTooltipPosition"; "required": false; "isSignal": true; }; "disabled": { "alias": "tnTooltipDisabled"; "required": false; "isSignal": true; }; "showDelay": { "alias": "tnTooltipShowDelay"; "required": false; "isSignal": true; }; "hideDelay": { "alias": "tnTooltipHideDelay"; "required": false; "isSignal": true; }; "tooltipClass": { "alias": "tnTooltipClass"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2173
+ }
2174
+
2175
+ declare class TnTooltipComponent {
2176
+ message: _angular_core.InputSignal<string>;
2177
+ id: _angular_core.InputSignal<string>;
2178
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnTooltipComponent, never>;
2179
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnTooltipComponent, "tn-tooltip", never, { "message": { "alias": "message"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2180
+ }
2181
+
2182
+ type TnDialogOpenTarget<C> = ComponentType<C> | TemplateRef<unknown>;
2183
+ interface TnDialogDefaults {
2184
+ panelClass?: string | string[];
2185
+ maxWidth?: string;
2186
+ maxHeight?: string;
2187
+ width?: string;
2188
+ height?: string;
2189
+ disableClose?: boolean;
2190
+ role?: 'dialog' | 'alertdialog';
2191
+ fullscreen?: boolean;
2192
+ }
2193
+ declare class TnDialog {
2194
+ private dialog;
2195
+ /**
2196
+ * Open a dialog with the given component or template.
2197
+ * Applies default configuration for panel class, max dimensions, and focus behavior.
2198
+ */
2199
+ open<C, D = unknown, R = unknown>(target: ComponentType<C> | TemplateRef<C>, config?: DialogConfig<D, DialogRef<R, C>>): DialogRef<R, C>;
2200
+ /**
2201
+ * Open a fullscreen dialog that takes over the entire viewport.
2202
+ * Automatically applies fullscreen styling and dimensions.
2203
+ */
2204
+ openFullscreen<C, D = unknown, R = unknown>(target: ComponentType<C> | TemplateRef<C>, config?: DialogConfig<D, DialogRef<R, C>>): DialogRef<R, C>;
2205
+ /**
2206
+ * Open a confirmation dialog with customizable title, message, and button labels.
2207
+ * Returns a promise that resolves to an Observable of the user's choice.
2208
+ */
2209
+ confirm(opts: {
2210
+ title: string;
2211
+ message?: string;
2212
+ confirmText?: string;
2213
+ cancelText?: string;
2214
+ destructive?: boolean;
2215
+ }): Promise<Observable<boolean | undefined>>;
2216
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnDialog, never>;
2217
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<TnDialog>;
2218
+ }
2219
+
2220
+ declare class TnDialogShellComponent implements OnInit {
2221
+ title: _angular_core.InputSignal<string>;
2222
+ showFullscreenButton: _angular_core.InputSignal<boolean>;
2223
+ isFullscreen: _angular_core.WritableSignal<boolean>;
2224
+ private originalStyles;
2225
+ private ref;
2226
+ private document;
2227
+ private data;
2228
+ ngOnInit(): void;
2229
+ close(result?: unknown): void;
2230
+ toggleFullscreen(): void;
2231
+ private enterFullscreen;
2232
+ private exitFullscreen;
2233
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnDialogShellComponent, never>;
2234
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnDialogShellComponent, "tn-dialog-shell", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "showFullscreenButton": { "alias": "showFullscreenButton"; "required": false; "isSignal": true; }; }, {}, never, ["*", "[tnDialogAction]"], true, never>;
2235
+ }
2236
+
2237
+ interface TnConfirmDialogData {
2238
+ title: string;
2239
+ message?: string;
2240
+ confirmText?: string;
2241
+ cancelText?: string;
2242
+ destructive?: boolean;
2243
+ }
2244
+ declare class TnConfirmDialogComponent {
2245
+ ref: DialogRef<boolean, unknown>;
2246
+ data: TnConfirmDialogData;
2247
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnConfirmDialogComponent, never>;
2248
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnConfirmDialogComponent, "tn-confirm-dialog", never, {}, {}, never, never, true, never>;
2249
+ }
2250
+
2251
+ declare class TnStepComponent {
2252
+ label: _angular_core.InputSignal<string>;
2253
+ icon: _angular_core.InputSignal<string | undefined>;
2254
+ optional: _angular_core.InputSignal<boolean>;
2255
+ completed: _angular_core.InputSignal<boolean>;
2256
+ hasError: _angular_core.InputSignal<boolean>;
2257
+ data: _angular_core.InputSignal<unknown>;
2258
+ content: _angular_core.Signal<TemplateRef<unknown>>;
2259
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnStepComponent, never>;
2260
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnStepComponent, "tn-step", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "optional": { "alias": "optional"; "required": false; "isSignal": true; }; "completed": { "alias": "completed"; "required": false; "isSignal": true; }; "hasError": { "alias": "hasError"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
2261
+ }
2262
+
2263
+ declare class TnStepperComponent {
2264
+ orientation: _angular_core.InputSignal<"auto" | "horizontal" | "vertical">;
2265
+ linear: _angular_core.InputSignal<boolean>;
2266
+ selectedIndex: _angular_core.ModelSignal<number>;
2267
+ selectionChange: _angular_core.OutputEmitterRef<{
2268
+ selectedIndex: number;
2269
+ previouslySelectedIndex: number;
2270
+ }>;
2271
+ completed: _angular_core.OutputEmitterRef<{
2272
+ label: string;
2273
+ completed: boolean;
2274
+ data: unknown;
2275
+ }[]>;
2276
+ steps: _angular_core.Signal<readonly TnStepComponent[]>;
2277
+ private cdr;
2278
+ constructor();
2279
+ onWindowResize(_event: Event): void;
2280
+ private _getStepData;
2281
+ isWideScreen: _angular_core.Signal<boolean>;
2282
+ selectStep(index: number): void;
2283
+ canSelectStep(index: number): boolean;
2284
+ next(): void;
2285
+ previous(): void;
2286
+ _trackByStepIndex(index: number): number;
2287
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnStepperComponent, never>;
2288
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnStepperComponent, "tn-stepper", never, { "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "linear": { "alias": "linear"; "required": false; "isSignal": true; }; "selectedIndex": { "alias": "selectedIndex"; "required": false; "isSignal": true; }; }, { "selectedIndex": "selectedIndexChange"; "selectionChange": "selectionChange"; "completed": "completed"; }, ["steps"], never, true, never>;
2289
+ }
2290
+
2291
+ declare class TnFilePickerComponent implements ControlValueAccessor, OnInit, OnDestroy {
2292
+ mode: _angular_core.InputSignal<FilePickerMode>;
2293
+ multiSelect: _angular_core.InputSignal<boolean>;
2294
+ allowCreate: _angular_core.InputSignal<boolean>;
2295
+ allowDatasetCreate: _angular_core.InputSignal<boolean>;
2296
+ allowZvolCreate: _angular_core.InputSignal<boolean>;
2297
+ allowManualInput: _angular_core.InputSignal<boolean>;
2298
+ placeholder: _angular_core.InputSignal<string>;
2299
+ disabled: _angular_core.InputSignal<boolean>;
2300
+ startPath: _angular_core.InputSignal<string>;
2301
+ rootPath: _angular_core.InputSignal<string | undefined>;
2302
+ fileExtensions: _angular_core.InputSignal<string[] | undefined>;
2303
+ callbacks: _angular_core.InputSignal<FilePickerCallbacks | undefined>;
2304
+ selectionChange: _angular_core.OutputEmitterRef<string | string[]>;
2305
+ pathChange: _angular_core.OutputEmitterRef<string>;
2306
+ createFolder: _angular_core.OutputEmitterRef<CreateFolderEvent>;
2307
+ error: _angular_core.OutputEmitterRef<FilePickerError>;
2308
+ wrapperEl: _angular_core.Signal<ElementRef<HTMLDivElement>>;
2309
+ filePickerTemplate: _angular_core.Signal<TemplateRef<unknown>>;
2310
+ private destroy$;
2311
+ private overlayRef?;
2312
+ private portal?;
2313
+ isOpen: _angular_core.WritableSignal<boolean>;
2314
+ selectedPath: _angular_core.WritableSignal<string>;
2315
+ currentPath: _angular_core.WritableSignal<string>;
2316
+ fileItems: _angular_core.WritableSignal<FileSystemItem[]>;
2317
+ selectedItems: _angular_core.WritableSignal<string[]>;
2318
+ loading: _angular_core.WritableSignal<boolean>;
2319
+ hasError: _angular_core.WritableSignal<boolean>;
2320
+ creatingItemTempId: _angular_core.WritableSignal<string | null>;
2321
+ creationLoading: _angular_core.WritableSignal<boolean>;
2322
+ private formDisabled;
2323
+ isDisabled: _angular_core.Signal<boolean>;
2324
+ private onChange;
2325
+ private onTouched;
2326
+ private overlay;
2327
+ private elementRef;
2328
+ private viewContainerRef;
2329
+ ngOnInit(): void;
2330
+ ngOnDestroy(): void;
2331
+ writeValue(value: string | string[]): void;
2332
+ registerOnChange(fn: (value: string | string[]) => void): void;
2333
+ registerOnTouched(fn: () => void): void;
2334
+ setDisabledState(isDisabled: boolean): void;
2335
+ onPathInput(event: Event): void;
2336
+ openFilePicker(): void;
2337
+ close(): void;
2338
+ onItemClick(item: FileSystemItem): void;
2339
+ onItemDoubleClick(item: FileSystemItem): void;
2340
+ onSubmit(): void;
2341
+ onCancel(): void;
2342
+ navigateToPath(path: string): void;
2343
+ onCreateFolder(): void;
2344
+ onClearSelection(): void;
2345
+ onSubmitFolderName(name: string, tempId: string): Promise<void>;
2346
+ onCancelFolderCreation(tempId: string): void;
2347
+ private removePendingItem;
2348
+ private updateCreatingItemError;
2349
+ private validateFolderName;
2350
+ private loadDirectory;
2351
+ private getMockFileItems;
2352
+ private updateSelection;
2353
+ private updateSelectionFromItems;
2354
+ private toFullPath;
2355
+ private emitError;
2356
+ private createOverlay;
2357
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnFilePickerComponent, never>;
2358
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnFilePickerComponent, "tn-file-picker", never, { "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "multiSelect": { "alias": "multiSelect"; "required": false; "isSignal": true; }; "allowCreate": { "alias": "allowCreate"; "required": false; "isSignal": true; }; "allowDatasetCreate": { "alias": "allowDatasetCreate"; "required": false; "isSignal": true; }; "allowZvolCreate": { "alias": "allowZvolCreate"; "required": false; "isSignal": true; }; "allowManualInput": { "alias": "allowManualInput"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "startPath": { "alias": "startPath"; "required": false; "isSignal": true; }; "rootPath": { "alias": "rootPath"; "required": false; "isSignal": true; }; "fileExtensions": { "alias": "fileExtensions"; "required": false; "isSignal": true; }; "callbacks": { "alias": "callbacks"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; "pathChange": "pathChange"; "createFolder": "createFolder"; "error": "error"; }, never, never, true, never>;
2359
+ }
2360
+
2361
+ declare class TnFilePickerPopupComponent implements OnInit, AfterViewInit, AfterViewChecked {
2362
+ mode: _angular_core.InputSignal<FilePickerMode>;
2363
+ multiSelect: _angular_core.InputSignal<boolean>;
2364
+ allowCreate: _angular_core.InputSignal<boolean>;
2365
+ allowDatasetCreate: _angular_core.InputSignal<boolean>;
2366
+ allowZvolCreate: _angular_core.InputSignal<boolean>;
2367
+ currentPath: _angular_core.InputSignal<string>;
2368
+ fileItems: _angular_core.InputSignal<FileSystemItem[]>;
2369
+ selectedItems: _angular_core.InputSignal<string[]>;
2370
+ loading: _angular_core.InputSignal<boolean>;
2371
+ creationLoading: _angular_core.InputSignal<boolean>;
2372
+ fileExtensions: _angular_core.InputSignal<string[] | undefined>;
2373
+ private iconRegistry;
2374
+ constructor();
2375
+ /**
2376
+ * Register MDI icon library with all icons used by the file picker component
2377
+ * This makes the component self-contained with zero configuration required
2378
+ */
2379
+ private registerMdiIcons;
2380
+ ngOnInit(): void;
2381
+ ngAfterViewInit(): void;
2382
+ ngAfterViewChecked(): void;
2383
+ itemClick: _angular_core.OutputEmitterRef<FileSystemItem>;
2384
+ itemDoubleClick: _angular_core.OutputEmitterRef<FileSystemItem>;
2385
+ pathNavigate: _angular_core.OutputEmitterRef<string>;
2386
+ createFolder: _angular_core.OutputEmitterRef<CreateFolderEvent>;
2387
+ clearSelection: _angular_core.OutputEmitterRef<void>;
2388
+ close: _angular_core.OutputEmitterRef<void>;
2389
+ submit: _angular_core.OutputEmitterRef<void>;
2390
+ cancel: _angular_core.OutputEmitterRef<void>;
2391
+ submitFolderName: _angular_core.OutputEmitterRef<{
2392
+ name: string;
2393
+ tempId: string;
2394
+ }>;
2395
+ cancelFolderCreation: _angular_core.OutputEmitterRef<string>;
2396
+ displayedColumns: string[];
2397
+ filteredFileItems: _angular_core.Signal<{
2398
+ disabled: boolean;
2399
+ path: string;
2400
+ name: string;
2401
+ type: "file" | "folder" | "dataset" | "zvol" | "mountpoint";
2402
+ size?: number;
2403
+ modified?: Date;
2404
+ permissions?: "read" | "write" | "none";
2405
+ icon?: string;
2406
+ isCreating?: boolean;
2407
+ tempId?: string;
2408
+ creationError?: string;
2409
+ }[]>;
2410
+ onItemClick(item: FileSystemItem): void;
2411
+ onItemDoubleClick(item: FileSystemItem): void;
2412
+ navigateToPath(path: string): void;
2413
+ onCreateFolder(): void;
2414
+ onClearSelection(): void;
2415
+ onSubmit(): void;
2416
+ onCancel(): void;
2417
+ onFolderNameSubmit(event: Event, item: FileSystemItem): void;
2418
+ onFolderNameCancel(item: FileSystemItem): void;
2419
+ onFolderNameInputBlur(event: Event, item: FileSystemItem): void;
2420
+ onFolderNameKeyDown(event: KeyboardEvent, item: FileSystemItem): void;
2421
+ isCreateDisabled(): boolean;
2422
+ isNavigatable(item: FileSystemItem): boolean;
2423
+ getItemIcon(item: FileSystemItem): string;
2424
+ getFileIcon(filename: string): string;
2425
+ /**
2426
+ * Get the library type for the icon
2427
+ * @param item FileSystemItem
2428
+ * @returns 'custom' for TrueNAS custom icons, 'mdi' for Material Design Icons
2429
+ */
2430
+ getItemIconLibrary(item: FileSystemItem): 'mdi' | 'custom';
2431
+ getZfsBadge(item: FileSystemItem): string;
2432
+ isZfsObject(item: FileSystemItem): boolean;
2433
+ isSelected(item: FileSystemItem): boolean;
2434
+ getRowClass: (row: FileSystemItem) => string | string[];
2435
+ getFileInfo(item: FileSystemItem): string;
2436
+ formatFileSize(bytes: number): string;
2437
+ getTypeDisplayName(type: string): string;
2438
+ formatDate(date: Date): string;
2439
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnFilePickerPopupComponent, never>;
2440
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<TnFilePickerPopupComponent, "tn-file-picker-popup", never, { "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "multiSelect": { "alias": "multiSelect"; "required": false; "isSignal": true; }; "allowCreate": { "alias": "allowCreate"; "required": false; "isSignal": true; }; "allowDatasetCreate": { "alias": "allowDatasetCreate"; "required": false; "isSignal": true; }; "allowZvolCreate": { "alias": "allowZvolCreate"; "required": false; "isSignal": true; }; "currentPath": { "alias": "currentPath"; "required": false; "isSignal": true; }; "fileItems": { "alias": "fileItems"; "required": false; "isSignal": true; }; "selectedItems": { "alias": "selectedItems"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "creationLoading": { "alias": "creationLoading"; "required": false; "isSignal": true; }; "fileExtensions": { "alias": "fileExtensions"; "required": false; "isSignal": true; }; }, { "itemClick": "itemClick"; "itemDoubleClick": "itemDoubleClick"; "pathNavigate": "pathNavigate"; "createFolder": "createFolder"; "clearSelection": "clearSelection"; "close": "close"; "submit": "submit"; "cancel": "cancel"; "submitFolderName": "submitFolderName"; "cancelFolderCreation": "cancelFolderCreation"; }, never, never, true, never>;
2441
+ }
2442
+
2443
+ interface KeyCombination {
2444
+ ctrlKey: boolean;
2445
+ altKey: boolean;
2446
+ shiftKey: boolean;
2447
+ metaKey: boolean;
2448
+ key: string;
2449
+ }
2450
+ interface ShortcutHandler {
2451
+ id: string;
2452
+ combination: KeyCombination;
2453
+ callback: () => void;
2454
+ context?: string;
2455
+ enabled: boolean;
2456
+ }
2457
+ declare class TnKeyboardShortcutService {
2458
+ private shortcuts;
2459
+ private globalEnabled;
2460
+ /**
2461
+ * Register a keyboard shortcut
2462
+ */
2463
+ registerShortcut(id: string, shortcut: string, callback: () => void, context?: string): void;
2464
+ /**
2465
+ * Unregister a keyboard shortcut
2466
+ */
2467
+ unregisterShortcut(id: string): void;
2468
+ /**
2469
+ * Unregister all shortcuts for a given context
2470
+ */
2471
+ unregisterContext(context: string): void;
2472
+ /**
2473
+ * Enable/disable a specific shortcut
2474
+ */
2475
+ setShortcutEnabled(id: string, enabled: boolean): void;
2476
+ /**
2477
+ * Enable/disable all shortcuts globally
2478
+ */
2479
+ setGlobalEnabled(enabled: boolean): void;
2480
+ /**
2481
+ * Check if shortcuts are globally enabled
2482
+ */
2483
+ isGlobalEnabled(): boolean;
2484
+ /**
2485
+ * Handle keyboard events
2486
+ */
2487
+ handleKeyboardEvent(event: KeyboardEvent): boolean;
2488
+ /**
2489
+ * Parse a shortcut string into a KeyCombination
2490
+ */
2491
+ parseShortcut(shortcut: string): KeyCombination;
2492
+ /**
2493
+ * Check if two key combinations match
2494
+ */
2495
+ private matchesCombination;
2496
+ /**
2497
+ * Get the current platform
2498
+ */
2499
+ getCurrentPlatform(): PlatformType;
2500
+ /**
2501
+ * Format a shortcut for display on the current platform
2502
+ */
2503
+ formatShortcutForPlatform(shortcut: string, platform?: PlatformType): string;
2504
+ /**
2505
+ * Convert Mac-style shortcut to Windows display format
2506
+ */
2507
+ private convertToWindowsDisplay;
2508
+ /**
2509
+ * Convert Mac-style shortcut to Linux display format
2510
+ */
2511
+ private convertToLinuxDisplay;
2512
+ /**
2513
+ * Get platform-specific shortcut enum
2514
+ */
2515
+ getPlatformShortcuts(platform?: PlatformType): typeof CommonShortcuts | typeof WindowsShortcuts | typeof LinuxShortcuts;
2516
+ /**
2517
+ * Get all registered shortcuts
2518
+ */
2519
+ getAllShortcuts(): ShortcutHandler[];
2520
+ /**
2521
+ * Get shortcuts for a specific context
2522
+ */
2523
+ getShortcutsForContext(context: string): ShortcutHandler[];
2524
+ /**
2525
+ * Clear all shortcuts
2526
+ */
2527
+ clearAllShortcuts(): void;
2528
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnKeyboardShortcutService, never>;
2529
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<TnKeyboardShortcutService>;
2530
+ }
2531
+
2532
+ /**
2533
+ * Enum of available theme names.
2534
+ * Use these constants instead of hardcoded strings.
2535
+ *
2536
+ * @example
2537
+ * ```typescript
2538
+ * themeService.setTheme(TnTheme.Dracula);
2539
+ * ```
2540
+ */
2541
+ declare enum TnTheme {
2542
+ Dark = "tn-dark",
2543
+ Blue = "tn-blue",
2544
+ Dracula = "tn-dracula",
2545
+ Nord = "tn-nord",
2546
+ Paper = "tn-paper",
2547
+ SolarizedDark = "tn-solarized-dark",
2548
+ Midnight = "tn-midnight",
2549
+ HighContrast = "tn-high-contrast"
2550
+ }
2551
+ /**
2552
+ * Represents a theme definition/configuration.
2553
+ */
2554
+ interface TnThemeDefinition {
2555
+ /** Unique identifier/name for the theme (from TnTheme enum) */
2556
+ name: TnTheme;
2557
+ /** Human-readable display name */
2558
+ label: string;
2559
+ /** CSS class name to apply to document root */
2560
+ className: string;
2561
+ /** Optional description of the theme */
2562
+ description?: string;
2563
+ }
2564
+
2565
+ /**
2566
+ * Service for managing themes in the TrueNAS UI Components library.
2567
+ *
2568
+ * Features:
2569
+ * - Signal-based reactive theme state
2570
+ * - LocalStorage persistence (key: 'tn-theme')
2571
+ * - Automatic CSS class application to document root
2572
+ * - SSR-safe (checks for browser platform)
2573
+ *
2574
+ * @example
2575
+ * ```typescript
2576
+ * import { Component, inject, effect } from '@angular/core';
2577
+ * import { TnThemeService, TnTheme } from '@truenas/ui-components';
2578
+ *
2579
+ * @Component({...})
2580
+ * export class MyComponent {
2581
+ * private themeService = inject(TnThemeService);
2582
+ *
2583
+ * constructor() {
2584
+ * // Get available theme definitions
2585
+ * const themes = this.themeService.availableThemes;
2586
+ *
2587
+ * // Get current theme (signal)
2588
+ * const currentTheme = this.themeService.currentTheme();
2589
+ *
2590
+ * // Set theme using enum (recommended)
2591
+ * this.themeService.setTheme(TnTheme.Blue);
2592
+ *
2593
+ * // React to theme changes
2594
+ * effect(() => {
2595
+ * console.log('Theme changed to:', this.themeService.currentTheme()?.label);
2596
+ * });
2597
+ * }
2598
+ * }
2599
+ * ```
2600
+ */
2601
+ declare class TnThemeService {
2602
+ private readonly platformId;
2603
+ private readonly isBrowser;
2604
+ /**
2605
+ * Internal signal holding the current theme enum value
2606
+ */
2607
+ private readonly currentThemeSignal;
2608
+ /**
2609
+ * Computed signal that returns the full theme definition for the current theme
2610
+ */
2611
+ readonly currentTheme: _angular_core.Signal<TnThemeDefinition | undefined>;
2612
+ /**
2613
+ * Computed signal that returns the current theme's CSS class name
2614
+ */
2615
+ readonly currentThemeClass: _angular_core.Signal<string>;
2616
+ /**
2617
+ * All available theme definitions in the library (readonly array)
2618
+ */
2619
+ readonly availableThemes: readonly TnThemeDefinition[];
2620
+ constructor();
2621
+ /**
2622
+ * Set the current theme.
2623
+ * Updates the signal, which triggers effects to apply CSS and save to localStorage.
2624
+ *
2625
+ * @param theme - The theme to set (use TnTheme enum)
2626
+ * @returns true if theme was found and set, false otherwise
2627
+ *
2628
+ * @example
2629
+ * ```typescript
2630
+ * themeService.setTheme(TnTheme.Dracula);
2631
+ * ```
2632
+ */
2633
+ setTheme(theme: TnTheme): boolean;
2634
+ /**
2635
+ * Get the current theme enum value (reactive signal value)
2636
+ */
2637
+ getCurrentTheme(): TnTheme;
2638
+ /**
2639
+ * Reset theme to default
2640
+ */
2641
+ resetToDefault(): void;
2642
+ /**
2643
+ * Check if a theme exists
2644
+ */
2645
+ hasTheme(theme: TnTheme): boolean;
2646
+ /**
2647
+ * Initialize theme from localStorage or use default
2648
+ */
2649
+ private initializeTheme;
2650
+ /**
2651
+ * Apply theme CSS class to document root.
2652
+ * Removes all other theme classes first to avoid conflicts.
2653
+ *
2654
+ * @param themeClass - CSS class name to apply (e.g., 'tn-dark')
2655
+ */
2656
+ private applyThemeToDOM;
2657
+ /**
2658
+ * Persist theme to localStorage.
2659
+ * Colors are applied automatically via CSS classes from themes.css.
2660
+ *
2661
+ * @param theme - Theme definition to persist
2662
+ */
2663
+ private persistThemeToStorage;
2664
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<TnThemeService, never>;
2665
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<TnThemeService>;
2666
+ }
2667
+
2668
+ /**
2669
+ * Default theme used when no theme is set
2670
+ */
2671
+ declare const DEFAULT_THEME = TnTheme.Dark;
2672
+ /**
2673
+ * localStorage key for storing the current theme name
2674
+ */
2675
+ declare const THEME_STORAGE_KEY = "tn-theme";
2676
+ /**
2677
+ * All available theme definitions in the TrueNAS UI Components library.
2678
+ * These themes correspond to CSS classes defined in themes.css
2679
+ */
2680
+ declare const TN_THEME_DEFINITIONS: readonly TnThemeDefinition[];
2681
+ /**
2682
+ * Map of theme enum values to theme definition objects for quick lookup
2683
+ */
2684
+ declare const THEME_MAP: Map<TnTheme, TnThemeDefinition>;
2685
+
2686
+ export { CommonShortcuts, DEFAULT_THEME, DiskIconComponent, DiskType, FileSizePipe, InputType, LinuxModifierKeys, LinuxShortcuts, ModifierKeys, QuickShortcuts, ShortcutBuilder, StripMntPrefixPipe, THEME_MAP, THEME_STORAGE_KEY, TN_THEME_DEFINITIONS, TnBannerComponent, TnBannerHarness, TnBrandedSpinnerComponent, TnButtonComponent, TnButtonToggleComponent, TnButtonToggleGroupComponent, TnCalendarComponent, TnCalendarHeaderComponent, TnCardComponent, TnCellDefDirective, TnCheckboxComponent, TnChipComponent, TnConfirmDialogComponent, TnDateInputComponent, TnDateRangeInputComponent, TnDialog, TnDialogShellComponent, TnDividerComponent, TnDividerDirective, TnExpansionPanelComponent, TnFilePickerComponent, TnFilePickerPopupComponent, TnFormFieldComponent, TnHeaderCellDefDirective, TnIconButtonComponent, TnIconComponent, TnIconHarness, TnIconRegistryService, TnInputComponent, TnInputDirective, TnKeyboardShortcutComponent, TnKeyboardShortcutService, TnListAvatarDirective, TnListComponent, TnListIconDirective, TnListItemComponent, TnListItemLineDirective, TnListItemPrimaryDirective, TnListItemSecondaryDirective, TnListItemTitleDirective, TnListItemTrailingDirective, TnListOptionComponent, TnListSubheaderComponent, TnMenuComponent, TnMenuTriggerDirective, TnMonthViewComponent, TnMultiYearViewComponent, TnNestedTreeNodeComponent, TnParticleProgressBarComponent, TnProgressBarComponent, TnRadioComponent, TnSelectComponent, TnSelectionListComponent, TnSlideToggleComponent, TnSliderComponent, TnSliderThumbDirective, TnSliderWithLabelDirective, TnSpinnerComponent, TnSpriteLoaderService, TnStepComponent, TnStepperComponent, TnTabComponent, TnTabPanelComponent, TnTableColumnDirective, TnTableComponent, TnTabsComponent, TnTheme, TnThemeService, TnTimeInputComponent, TnTooltipComponent, TnTooltipDirective, TnTreeComponent, TnTreeFlatDataSource, TnTreeFlattener, TnTreeNodeComponent, TnTreeNodeOutletDirective, TruncatePathPipe, WindowsModifierKeys, WindowsShortcuts, createLucideLibrary, createShortcut, defaultSpriteBasePath, defaultSpriteConfigPath, libIconMarker, registerLucideIcons, setupLucideIntegration, tnIconMarker };
2687
+ export type { BannerHarnessFilters, CalendarCell, ChipColor, CreateFolderEvent, DateRange, FilePickerCallbacks, FilePickerError, FilePickerMode, FileSystemItem, IconHarnessFilters, IconLibrary, IconLibraryType, IconResult, IconSize, IconSource, KeyCombination, LabelType, LucideIconOptions, PathSegment, PlatformType, ProgressBarMode, ResolvedIcon, ShortcutHandler, SlideToggleColor, SpinnerMode, SpriteConfig, TabChangeEvent, TnBannerType, TnButtonToggleType, TnCardAction, TnCardControl, TnCardFooterLink, TnCardHeaderStatus, TnConfirmDialogData, TnDialogDefaults, TnDialogOpenTarget, TnFlatTreeNode, TnMenuItem, TnSelectOption, TnSelectOptionGroup, TnSelectionChange, TnTableDataSource, TnThemeDefinition, TooltipPosition, YearCell };