@truenas/ui-components 0.3.12 → 0.3.13

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.
@@ -4199,6 +4199,262 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
4199
4199
  }]
4200
4200
  }], ctorParameters: () => [] });
4201
4201
 
4202
+ /**
4203
+ * A minimal file-selection form control. Renders a styled "Choose File" button
4204
+ * that opens the native file dialog and exposes the picked `File`(s) both as a
4205
+ * `(change)` output and as the value of an Angular form control.
4206
+ *
4207
+ * The selected file name(s) are shown next to the button (toggle with
4208
+ * `showFileName`). Use inside a `<tn-form-field>` to get a label, required
4209
+ * asterisk and help tooltip.
4210
+ *
4211
+ * Like every native file input, the browser forbids programmatically setting
4212
+ * the chosen files for security reasons. Writing a non-empty value via a form
4213
+ * control therefore only updates the displayed name; writing `null` (or an empty
4214
+ * array) clears the control. User selection is the only way to populate real
4215
+ * `File` objects.
4216
+ *
4217
+ * @example
4218
+ * ```html
4219
+ * <tn-form-field label="Update File" [required]="true" tooltip="Upload a .tar file">
4220
+ * <tn-file-input accept=".tar" formControlName="update" (change)="onFile($event)" />
4221
+ * </tn-form-field>
4222
+ * ```
4223
+ */
4224
+ class TnFileInputComponent {
4225
+ fileInputEl = viewChild.required('fileInput');
4226
+ /** Label rendered inside the trigger button. */
4227
+ buttonLabel = input('Choose File', ...(ngDevMode ? [{ debugName: "buttonLabel" }] : []));
4228
+ /**
4229
+ * Native `accept` attribute forwarded to the file input — a comma-separated
4230
+ * list of extensions and/or MIME types (e.g. `".tar,.txt"`, `"image/*"`).
4231
+ */
4232
+ accept = input(undefined, ...(ngDevMode ? [{ debugName: "accept" }] : []));
4233
+ /** Allow selecting more than one file. The value becomes a `File[]`. */
4234
+ multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : []));
4235
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
4236
+ /** Whether to render the selected file name(s) beside the button. */
4237
+ showFileName = input(true, ...(ngDevMode ? [{ debugName: "showFileName" }] : []));
4238
+ /** Text shown beside the button when no file is selected. */
4239
+ noFileText = input('No file chosen', ...(ngDevMode ? [{ debugName: "noFileText" }] : []));
4240
+ /**
4241
+ * Accessible label for the trigger button, forwarded to `tn-button`. Set this
4242
+ * when the visible "Choose File" text alone doesn't convey what is being
4243
+ * uploaded — e.g. pass the field label so a screen reader announces
4244
+ * "Update File" rather than just "Choose File". (`tn-form-field`'s `<label>`
4245
+ * is not programmatically associated with the projected control.)
4246
+ */
4247
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
4248
+ /**
4249
+ * Semantic test-id base. Rendered under whichever attribute name is configured
4250
+ * via `TN_TEST_ATTR` (default `data-testid`).
4251
+ */
4252
+ testId = input(undefined, ...(ngDevMode ? [{ debugName: "testId" }] : []));
4253
+ /**
4254
+ * Emitted whenever the selection changes. `null` when the input is cleared.
4255
+ * Named `selectionChange` (not `change`) to avoid colliding with the native
4256
+ * `change` event bubbling from the inner file input.
4257
+ */
4258
+ selectionChange = output();
4259
+ // Selected files, kept for display and for the form value.
4260
+ selectedFiles = signal([], ...(ngDevMode ? [{ debugName: "selectedFiles" }] : []));
4261
+ formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "formDisabled" }] : []));
4262
+ isDisabled = computed(() => this.disabled() || this.formDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
4263
+ fileNames = computed(() => this.selectedFiles().map(file => file.name).join(', '), ...(ngDevMode ? [{ debugName: "fileNames" }] : []));
4264
+ hasFiles = computed(() => this.selectedFiles().length > 0, ...(ngDevMode ? [{ debugName: "hasFiles" }] : []));
4265
+ onChange = (_value) => { };
4266
+ onTouched = () => { };
4267
+ // ControlValueAccessor
4268
+ writeValue(value) {
4269
+ // Native file inputs cannot be populated programmatically; we only mirror
4270
+ // the value for display and treat null/empty as a clear of the control.
4271
+ if (value == null || (Array.isArray(value) && value.length === 0)) {
4272
+ this.selectedFiles.set([]);
4273
+ this.fileInputEl().nativeElement.value = '';
4274
+ }
4275
+ else {
4276
+ this.selectedFiles.set(Array.isArray(value) ? value : [value]);
4277
+ }
4278
+ }
4279
+ registerOnChange(fn) {
4280
+ this.onChange = fn;
4281
+ }
4282
+ registerOnTouched(fn) {
4283
+ this.onTouched = fn;
4284
+ }
4285
+ setDisabledState(isDisabled) {
4286
+ this.formDisabled.set(isDisabled);
4287
+ }
4288
+ openFileDialog() {
4289
+ if (this.isDisabled()) {
4290
+ return;
4291
+ }
4292
+ // Clear the native value first so re-picking the same file still fires
4293
+ // `change` (browsers suppress it when the selection is identical).
4294
+ this.fileInputEl().nativeElement.value = '';
4295
+ this.fileInputEl().nativeElement.click();
4296
+ }
4297
+ /** Marks the control as touched when focus leaves it (e.g. for validation). */
4298
+ onBlur() {
4299
+ this.onTouched();
4300
+ }
4301
+ onFilesSelected(event) {
4302
+ const target = event.target;
4303
+ const files = target.files ? Array.from(target.files) : [];
4304
+ this.selectedFiles.set(files);
4305
+ const value = this.toValue(files);
4306
+ this.onChange(value);
4307
+ this.onTouched();
4308
+ this.selectionChange.emit(value);
4309
+ }
4310
+ toValue(files) {
4311
+ if (files.length === 0) {
4312
+ return null;
4313
+ }
4314
+ return this.multiple() ? files : files[0];
4315
+ }
4316
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnFileInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4317
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnFileInputComponent, isStandalone: true, selector: "tn-file-input", inputs: { buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, showFileName: { classPropertyName: "showFileName", publicName: "showFileName", isSignal: true, isRequired: false, transformFunction: null }, noFileText: { classPropertyName: "noFileText", publicName: "noFileText", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, host: { classAttribute: "tn-file-input" }, providers: [
4318
+ {
4319
+ provide: NG_VALUE_ACCESSOR,
4320
+ useExisting: forwardRef(() => TnFileInputComponent),
4321
+ multi: true
4322
+ }
4323
+ ], viewQueries: [{ propertyName: "fileInputEl", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"tn-file-input__container\" tnTestIdType=\"file-input\" [tnTestId]=\"testId()\" (focusout)=\"onBlur()\">\n <input\n #fileInput\n type=\"file\"\n class=\"tn-file-input__native\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n [accept]=\"accept()\"\n [multiple]=\"multiple()\"\n [disabled]=\"isDisabled()\"\n (change)=\"onFilesSelected($event)\">\n\n <tn-button\n class=\"tn-file-input__button\"\n color=\"default\"\n [label]=\"buttonLabel()\"\n [disabled]=\"isDisabled()\"\n [ariaLabel]=\"ariaLabel()\"\n (onClick)=\"openFileDialog()\" />\n\n @if (showFileName()) {\n <span class=\"tn-file-input__filename\" [class.tn-file-input__filename--empty]=\"!hasFiles()\">\n {{ hasFiles() ? fileNames() : noFileText() }}\n </span>\n }\n\n <!--\n Always-present live region so screen readers are told what was picked even\n when the visible file name is suppressed (showFileName=false).\n -->\n <span class=\"tn-file-input__announcer\" aria-live=\"polite\">\n {{ hasFiles() ? fileNames() : '' }}\n </span>\n</div>\n", styles: [":host{display:inline-block}.tn-file-input__container{display:inline-flex;align-items:center;gap:12px}.tn-file-input__native,.tn-file-input__announcer{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.tn-file-input__button{flex-shrink:0}.tn-file-input__filename{font-size:14px;color:var(--tn-fg1);max-width:30ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tn-file-input__filename--empty{color:var(--tn-fg2)}\n"], dependencies: [{ kind: "component", type: TnButtonComponent, selector: "tn-button", inputs: ["primary", "color", "variant", "backgroundColor", "label", "icon", "iconPosition", "disabled", "type", "testId", "href", "routerLink", "queryParams", "fragment", "target", "rel", "ariaLabel"], outputs: ["onClick"] }, { kind: "directive", type: TnTestIdDirective, selector: "[tnTestId]", inputs: ["tnTestId", "tnTestIdType"] }] });
4324
+ }
4325
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnFileInputComponent, decorators: [{
4326
+ type: Component,
4327
+ args: [{ selector: 'tn-file-input', standalone: true, imports: [TnButtonComponent, TnTestIdDirective], providers: [
4328
+ {
4329
+ provide: NG_VALUE_ACCESSOR,
4330
+ useExisting: forwardRef(() => TnFileInputComponent),
4331
+ multi: true
4332
+ }
4333
+ ], host: {
4334
+ 'class': 'tn-file-input'
4335
+ }, template: "<div class=\"tn-file-input__container\" tnTestIdType=\"file-input\" [tnTestId]=\"testId()\" (focusout)=\"onBlur()\">\n <input\n #fileInput\n type=\"file\"\n class=\"tn-file-input__native\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n [accept]=\"accept()\"\n [multiple]=\"multiple()\"\n [disabled]=\"isDisabled()\"\n (change)=\"onFilesSelected($event)\">\n\n <tn-button\n class=\"tn-file-input__button\"\n color=\"default\"\n [label]=\"buttonLabel()\"\n [disabled]=\"isDisabled()\"\n [ariaLabel]=\"ariaLabel()\"\n (onClick)=\"openFileDialog()\" />\n\n @if (showFileName()) {\n <span class=\"tn-file-input__filename\" [class.tn-file-input__filename--empty]=\"!hasFiles()\">\n {{ hasFiles() ? fileNames() : noFileText() }}\n </span>\n }\n\n <!--\n Always-present live region so screen readers are told what was picked even\n when the visible file name is suppressed (showFileName=false).\n -->\n <span class=\"tn-file-input__announcer\" aria-live=\"polite\">\n {{ hasFiles() ? fileNames() : '' }}\n </span>\n</div>\n", styles: [":host{display:inline-block}.tn-file-input__container{display:inline-flex;align-items:center;gap:12px}.tn-file-input__native,.tn-file-input__announcer{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.tn-file-input__button{flex-shrink:0}.tn-file-input__filename{font-size:14px;color:var(--tn-fg1);max-width:30ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tn-file-input__filename--empty{color:var(--tn-fg2)}\n"] }]
4336
+ }], propDecorators: { fileInputEl: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }], buttonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonLabel", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], showFileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFileName", required: false }] }], noFileText: [{ type: i0.Input, args: [{ isSignal: true, alias: "noFileText", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], testId: [{ type: i0.Input, args: [{ isSignal: true, alias: "testId", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }] } });
4337
+
4338
+ /**
4339
+ * Harness for interacting with `tn-file-input` in tests.
4340
+ *
4341
+ * @example
4342
+ * ```typescript
4343
+ * const fileInput = await loader.getHarness(TnFileInputHarness.with({ testId: 'update' }));
4344
+ * expect(await fileInput.getButtonText()).toBe('Choose File');
4345
+ * expect(await fileInput.hasFile()).toBe(false);
4346
+ * expect(await fileInput.getFileName()).toBe('No file chosen');
4347
+ * ```
4348
+ */
4349
+ class TnFileInputHarness extends ComponentHarness {
4350
+ /** The selector for the host element of a `TnFileInputComponent` instance. */
4351
+ static hostSelector = 'tn-file-input';
4352
+ // The trigger is a `tn-button`; target its rendered `<button>` element.
4353
+ _button = this.locatorFor('.tn-file-input__button .storybook-button');
4354
+ _native = this.locatorFor('input[type="file"]');
4355
+ _filename = this.locatorForOptional('.tn-file-input__filename');
4356
+ /**
4357
+ * Gets a `HarnessPredicate` to search for a file input with specific attributes.
4358
+ *
4359
+ * @param options Options for filtering which instances are considered a match.
4360
+ * @returns A `HarnessPredicate` configured with the given options.
4361
+ *
4362
+ * @example
4363
+ * ```typescript
4364
+ * const fileInput = await loader.getHarness(TnFileInputHarness.with({ testId: 'update' }));
4365
+ * ```
4366
+ */
4367
+ static with(options = {}) {
4368
+ return new HarnessPredicate(TnFileInputHarness, options)
4369
+ .addOption('buttonText', options.buttonText, (harness, text) => HarnessPredicate.stringMatches(harness.getButtonText(), text))
4370
+ .addOption('testId', options.testId, async (harness, testId) => (await harness.getTestId()) === testId);
4371
+ }
4372
+ /**
4373
+ * Gets the trigger button's text.
4374
+ *
4375
+ * @returns Promise resolving to the button label.
4376
+ *
4377
+ * @example
4378
+ * ```typescript
4379
+ * expect(await fileInput.getButtonText()).toBe('Choose File');
4380
+ * ```
4381
+ */
4382
+ async getButtonText() {
4383
+ return (await (await this._button()).text()).trim();
4384
+ }
4385
+ /**
4386
+ * Gets the displayed file-name text (or the empty-state text).
4387
+ *
4388
+ * @returns Promise resolving to the text, or null when the name is hidden.
4389
+ *
4390
+ * @example
4391
+ * ```typescript
4392
+ * expect(await fileInput.getFileName()).toBe('No file chosen');
4393
+ * ```
4394
+ */
4395
+ async getFileName() {
4396
+ const filename = await this._filename();
4397
+ return filename ? (await filename.text()).trim() : null;
4398
+ }
4399
+ /**
4400
+ * Whether a file is currently selected. A native file input reports an empty
4401
+ * `value` until the user picks a file, so this reflects real user selection.
4402
+ *
4403
+ * @returns Promise resolving to true when a file has been chosen.
4404
+ *
4405
+ * @example
4406
+ * ```typescript
4407
+ * expect(await fileInput.hasFile()).toBe(false);
4408
+ * ```
4409
+ */
4410
+ async hasFile() {
4411
+ const native = await this._native();
4412
+ const value = (await native.getProperty('value')) ?? '';
4413
+ return value !== '';
4414
+ }
4415
+ /**
4416
+ * Whether the control is disabled.
4417
+ *
4418
+ * @returns Promise resolving to true if the button is disabled.
4419
+ *
4420
+ * @example
4421
+ * ```typescript
4422
+ * expect(await fileInput.isDisabled()).toBe(true);
4423
+ * ```
4424
+ */
4425
+ async isDisabled() {
4426
+ const button = await this._button();
4427
+ return (await button.getProperty('disabled')) ?? false;
4428
+ }
4429
+ /**
4430
+ * Opens the native file dialog by clicking the trigger button. The browser
4431
+ * does not let tests pick a real file, so this is mainly useful for asserting
4432
+ * click handling and focus behaviour.
4433
+ *
4434
+ * @example
4435
+ * ```typescript
4436
+ * await fileInput.open();
4437
+ * ```
4438
+ */
4439
+ async open() {
4440
+ await (await this._button()).click();
4441
+ }
4442
+ /**
4443
+ * Gets the test-id attribute value from the container.
4444
+ *
4445
+ * @returns Promise resolving to the test-id, or null when unset.
4446
+ *
4447
+ * @example
4448
+ * ```typescript
4449
+ * expect(await fileInput.getTestId()).toBe('file-input-update');
4450
+ * ```
4451
+ */
4452
+ async getTestId() {
4453
+ const container = await this.locatorFor('.tn-file-input__container')();
4454
+ return (await container.getAttribute('data-testid')) ?? (await container.getAttribute('data-test'));
4455
+ }
4456
+ }
4457
+
4202
4458
  /**
4203
4459
  * Strips lightweight label markup (**bold**, *italic*, `code`), returning
4204
4460
  * plain text for attribute contexts such as aria-label and title.
@@ -17345,5 +17601,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
17345
17601
  * Generated bundle index. Do not edit.
17346
17602
  */
17347
17603
 
17348
- export { CommonShortcuts, DEFAULT_THEME, DiskIconComponent, DiskType, FileSizePipe, InputType, LIGHT_THEME, LabelMarkupPipe, LabelTextPipe, LinuxModifierKeys, LinuxShortcuts, ModifierKeys, QuickShortcuts, ShortcutBuilder, StripMntPrefixPipe, THEME_MAP, THEME_STORAGE_KEY, TN_FORM_FIELD_ERRORS, TN_TABLE_PAGER_DEFAULT_LABELS, TN_TABLE_PAGER_LABELS, TN_TEST_ATTR, TN_THEME_DEFINITIONS, TnAutocompleteComponent, TnAutocompleteHarness, TnBannerActionDirective, TnBannerComponent, TnBannerHarness, TnBrandedSpinnerComponent, TnButtonComponent, TnButtonHarness, TnButtonToggleComponent, TnButtonToggleGroupComponent, TnButtonToggleGroupHarness, TnButtonToggleHarness, TnCalendarComponent, TnCalendarHeaderComponent, TnCardComponent, TnCardFooterActionsDirective, TnCardHeaderActionsDirective, TnCardHeaderDirective, TnCellDefDirective, TnCheckboxComponent, TnCheckboxHarness, TnCheckboxLabelDirective, TnChipComponent, TnChipHarness, TnChipInputComponent, TnChipInputHarness, TnConfirmDialogComponent, TnDateInputComponent, TnDateInputHarness, TnDateRangeInputComponent, TnDateRangeInputHarness, TnDetailRowDefDirective, TnDialog, TnDialogHarness, TnDialogShellComponent, TnDialogTesting, TnDividerComponent, TnDividerDirective, TnDrawerComponent, TnDrawerContainerComponent, TnDrawerContainerHarness, TnDrawerContentComponent, TnDrawerHarness, TnEmptyComponent, TnEmptyHarness, TnExpansionPanelComponent, TnExpansionPanelHarness, TnFilePickerComponent, TnFilePickerPopupComponent, TnFormFieldComponent, TnFormFieldHarness, TnFormSectionComponent, TnFormSectionHarness, TnHeaderCellDefDirective, TnIconButtonComponent, TnIconButtonHarness, TnIconComponent, TnIconHarness, TnIconRegistryService, TnIconTesting, TnInputComponent, TnInputDirective, TnInputHarness, TnKeyboardShortcutComponent, TnKeyboardShortcutService, TnListAvatarDirective, TnListComponent, TnListIconDirective, TnListItemComponent, TnListItemLineDirective, TnListItemPrimaryDirective, TnListItemSecondaryDirective, TnListItemTitleDirective, TnListItemTrailingDirective, TnListOptionComponent, TnListSubheaderComponent, TnMenuActivateHoverDirective, TnMenuComponent, TnMenuHarness, TnMenuItemComponent, TnMenuTesting, TnMenuTriggerDirective, TnMonthViewComponent, TnMultiYearViewComponent, TnNestedTreeNodeComponent, TnParticleProgressBarComponent, TnProgressBarComponent, TnRadioComponent, TnRadioHarness, TnSelectComponent, TnSelectHarness, TnSelectionListComponent, TnSidePanelActionDirective, TnSidePanelComponent, TnSidePanelHarness, TnSidePanelHeaderActionDirective, TnSlideToggleComponent, TnSlideToggleHarness, TnSliderComponent, TnSliderThumbDirective, TnSliderWithLabelDirective, TnSpinnerComponent, TnSpriteLoaderService, TnStepComponent, TnStepperComponent, TnTabComponent, TnTabHarness, TnTabPanelComponent, TnTabPanelHarness, TnTableColumnDirective, TnTableComponent, TnTableHarness, TnTablePagerComponent, TnTablePagerHarness, TnTabsComponent, TnTabsHarness, TnTestIdDirective, TnTheme, TnThemeService, TnTimeInputComponent, TnToastComponent, TnToastMock, TnToastPosition, TnToastRef, TnToastService, TnToastTesting, TnToastType, TnTooltipComponent, TnTooltipDirective, TnTreeComponent, TnTreeFlatDataSource, TnTreeFlattener, TnTreeNodeComponent, TnTreeNodeOutletDirective, TruncatePathPipe, WindowsModifierKeys, WindowsShortcuts, composeTestId, createLucideLibrary, createShortcut, defaultSpriteBasePath, defaultSpriteConfigPath, formatSize, kebabTestSegment, labelMarkupToHtml, labelMarkupToText, libIconMarker, parseLabelMarkup, parseSize, registerLucideIcons, scopeTestId, setupLucideIntegration, tnIconMarker, writeTestId };
17604
+ export { CommonShortcuts, DEFAULT_THEME, DiskIconComponent, DiskType, FileSizePipe, InputType, LIGHT_THEME, LabelMarkupPipe, LabelTextPipe, LinuxModifierKeys, LinuxShortcuts, ModifierKeys, QuickShortcuts, ShortcutBuilder, StripMntPrefixPipe, THEME_MAP, THEME_STORAGE_KEY, TN_FORM_FIELD_ERRORS, TN_TABLE_PAGER_DEFAULT_LABELS, TN_TABLE_PAGER_LABELS, TN_TEST_ATTR, TN_THEME_DEFINITIONS, TnAutocompleteComponent, TnAutocompleteHarness, TnBannerActionDirective, TnBannerComponent, TnBannerHarness, TnBrandedSpinnerComponent, TnButtonComponent, TnButtonHarness, TnButtonToggleComponent, TnButtonToggleGroupComponent, TnButtonToggleGroupHarness, TnButtonToggleHarness, TnCalendarComponent, TnCalendarHeaderComponent, TnCardComponent, TnCardFooterActionsDirective, TnCardHeaderActionsDirective, TnCardHeaderDirective, TnCellDefDirective, TnCheckboxComponent, TnCheckboxHarness, TnCheckboxLabelDirective, TnChipComponent, TnChipHarness, TnChipInputComponent, TnChipInputHarness, TnConfirmDialogComponent, TnDateInputComponent, TnDateInputHarness, TnDateRangeInputComponent, TnDateRangeInputHarness, TnDetailRowDefDirective, TnDialog, TnDialogHarness, TnDialogShellComponent, TnDialogTesting, TnDividerComponent, TnDividerDirective, TnDrawerComponent, TnDrawerContainerComponent, TnDrawerContainerHarness, TnDrawerContentComponent, TnDrawerHarness, TnEmptyComponent, TnEmptyHarness, TnExpansionPanelComponent, TnExpansionPanelHarness, TnFileInputComponent, TnFileInputHarness, TnFilePickerComponent, TnFilePickerPopupComponent, TnFormFieldComponent, TnFormFieldHarness, TnFormSectionComponent, TnFormSectionHarness, TnHeaderCellDefDirective, TnIconButtonComponent, TnIconButtonHarness, TnIconComponent, TnIconHarness, TnIconRegistryService, TnIconTesting, TnInputComponent, TnInputDirective, TnInputHarness, TnKeyboardShortcutComponent, TnKeyboardShortcutService, TnListAvatarDirective, TnListComponent, TnListIconDirective, TnListItemComponent, TnListItemLineDirective, TnListItemPrimaryDirective, TnListItemSecondaryDirective, TnListItemTitleDirective, TnListItemTrailingDirective, TnListOptionComponent, TnListSubheaderComponent, TnMenuActivateHoverDirective, TnMenuComponent, TnMenuHarness, TnMenuItemComponent, TnMenuTesting, TnMenuTriggerDirective, TnMonthViewComponent, TnMultiYearViewComponent, TnNestedTreeNodeComponent, TnParticleProgressBarComponent, TnProgressBarComponent, TnRadioComponent, TnRadioHarness, TnSelectComponent, TnSelectHarness, TnSelectionListComponent, TnSidePanelActionDirective, TnSidePanelComponent, TnSidePanelHarness, TnSidePanelHeaderActionDirective, TnSlideToggleComponent, TnSlideToggleHarness, TnSliderComponent, TnSliderThumbDirective, TnSliderWithLabelDirective, TnSpinnerComponent, TnSpriteLoaderService, TnStepComponent, TnStepperComponent, TnTabComponent, TnTabHarness, TnTabPanelComponent, TnTabPanelHarness, TnTableColumnDirective, TnTableComponent, TnTableHarness, TnTablePagerComponent, TnTablePagerHarness, TnTabsComponent, TnTabsHarness, TnTestIdDirective, TnTheme, TnThemeService, TnTimeInputComponent, TnToastComponent, TnToastMock, TnToastPosition, TnToastRef, TnToastService, TnToastTesting, TnToastType, TnTooltipComponent, TnTooltipDirective, TnTreeComponent, TnTreeFlatDataSource, TnTreeFlattener, TnTreeNodeComponent, TnTreeNodeOutletDirective, TruncatePathPipe, WindowsModifierKeys, WindowsShortcuts, composeTestId, createLucideLibrary, createShortcut, defaultSpriteBasePath, defaultSpriteConfigPath, formatSize, kebabTestSegment, labelMarkupToHtml, labelMarkupToText, libIconMarker, parseLabelMarkup, parseSize, registerLucideIcons, scopeTestId, setupLucideIntegration, tnIconMarker, writeTestId };
17349
17605
  //# sourceMappingURL=truenas-ui-components.mjs.map