@truenas/ui-components 0.1.16 → 0.1.18
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.
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, ChangeDetectionStrategy, Component, inject, Injectable, viewChild, signal, effect, computed, ViewEncapsulation, Directive, contentChildren, output, forwardRef, ElementRef, ViewContainerRef, contentChild, ChangeDetectorRef, HostListener, TemplateRef, IterableDiffers, Pipe, model, PLATFORM_ID } from '@angular/core';
|
|
2
|
+
import { input, ChangeDetectionStrategy, Component, inject, Injectable, viewChild, signal, effect, computed, ViewEncapsulation, Directive, contentChildren, output, forwardRef, ElementRef, ViewContainerRef, contentChild, ChangeDetectorRef, HostListener, TemplateRef, IterableDiffers, Pipe, model, afterNextRender, PLATFORM_ID } from '@angular/core';
|
|
3
3
|
import * as i1$1 from '@angular/common';
|
|
4
4
|
import { CommonModule, DOCUMENT, isPlatformBrowser } from '@angular/common';
|
|
5
|
-
import { mdiCheckCircle, mdiAlertCircle, mdiAlert, mdiInformation, mdiDotsVertical, mdiFolderOpen, mdiLock, mdiLoading, mdiFolderPlus, mdiFolderNetwork, mdiHarddisk, mdiDatabase, mdiFile, mdiFolder } from '@mdi/js';
|
|
5
|
+
import { mdiCheckCircle, mdiAlertCircle, mdiAlert, mdiInformation, mdiDotsVertical, mdiClose, mdiFolderOpen, mdiLock, mdiLoading, mdiFolderPlus, mdiFolderNetwork, mdiHarddisk, mdiDatabase, mdiFile, mdiFolder } from '@mdi/js';
|
|
6
6
|
import * as i1 from '@angular/platform-browser';
|
|
7
7
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
8
8
|
import { HttpClient } from '@angular/common/http';
|
|
9
9
|
import { firstValueFrom, BehaviorSubject, merge, Subject } from 'rxjs';
|
|
10
10
|
import { ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
|
|
11
|
+
import * as i1$4 from '@angular/cdk/a11y';
|
|
11
12
|
import { FocusMonitor, A11yModule } from '@angular/cdk/a11y';
|
|
12
13
|
import * as i1$3 from '@angular/forms';
|
|
13
14
|
import { FormsModule, NG_VALUE_ACCESSOR, NgControl } from '@angular/forms';
|
|
@@ -7821,6 +7822,200 @@ var confirmDialog_component = /*#__PURE__*/Object.freeze({
|
|
|
7821
7822
|
TnConfirmDialogComponent: TnConfirmDialogComponent
|
|
7822
7823
|
});
|
|
7823
7824
|
|
|
7825
|
+
/**
|
|
7826
|
+
* Directive to mark an element as a side-panel footer action.
|
|
7827
|
+
*
|
|
7828
|
+
* @example
|
|
7829
|
+
* ```html
|
|
7830
|
+
* <tn-side-panel [(open)]="isOpen" title="Edit">
|
|
7831
|
+
* <tn-button tnSidePanelAction label="Save" />
|
|
7832
|
+
* </tn-side-panel>
|
|
7833
|
+
* ```
|
|
7834
|
+
*/
|
|
7835
|
+
class TnSidePanelActionDirective {
|
|
7836
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnSidePanelActionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
7837
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.0", type: TnSidePanelActionDirective, isStandalone: true, selector: "[tnSidePanelAction]", ngImport: i0 });
|
|
7838
|
+
}
|
|
7839
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnSidePanelActionDirective, decorators: [{
|
|
7840
|
+
type: Directive,
|
|
7841
|
+
args: [{
|
|
7842
|
+
selector: '[tnSidePanelAction]',
|
|
7843
|
+
standalone: true,
|
|
7844
|
+
}]
|
|
7845
|
+
}] });
|
|
7846
|
+
/**
|
|
7847
|
+
* Directive to mark an element as a side-panel header action.
|
|
7848
|
+
*
|
|
7849
|
+
* @example
|
|
7850
|
+
* ```html
|
|
7851
|
+
* <tn-side-panel [(open)]="isOpen" title="Edit">
|
|
7852
|
+
* <tn-icon-button tnSidePanelHeaderAction name="fullscreen" />
|
|
7853
|
+
* Content here
|
|
7854
|
+
* </tn-side-panel>
|
|
7855
|
+
* ```
|
|
7856
|
+
*/
|
|
7857
|
+
class TnSidePanelHeaderActionDirective {
|
|
7858
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnSidePanelHeaderActionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
7859
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.0", type: TnSidePanelHeaderActionDirective, isStandalone: true, selector: "[tnSidePanelHeaderAction]", ngImport: i0 });
|
|
7860
|
+
}
|
|
7861
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnSidePanelHeaderActionDirective, decorators: [{
|
|
7862
|
+
type: Directive,
|
|
7863
|
+
args: [{
|
|
7864
|
+
selector: '[tnSidePanelHeaderAction]',
|
|
7865
|
+
standalone: true,
|
|
7866
|
+
}]
|
|
7867
|
+
}] });
|
|
7868
|
+
class TnSidePanelComponent {
|
|
7869
|
+
iconRegistry = inject(TnIconRegistryService);
|
|
7870
|
+
document = inject(DOCUMENT);
|
|
7871
|
+
overlayRef = viewChild.required('overlay');
|
|
7872
|
+
initialized = signal(false, ...(ngDevMode ? [{ debugName: "initialized" }] : []));
|
|
7873
|
+
// Two-way bindable via [(open)]
|
|
7874
|
+
open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : []));
|
|
7875
|
+
// Inputs
|
|
7876
|
+
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
7877
|
+
width = input('480px', ...(ngDevMode ? [{ debugName: "width" }] : []));
|
|
7878
|
+
hasBackdrop = input(true, ...(ngDevMode ? [{ debugName: "hasBackdrop" }] : []));
|
|
7879
|
+
closeOnBackdropClick = input(true, ...(ngDevMode ? [{ debugName: "closeOnBackdropClick" }] : []));
|
|
7880
|
+
closeOnEscape = input(true, ...(ngDevMode ? [{ debugName: "closeOnEscape" }] : []));
|
|
7881
|
+
// Outputs
|
|
7882
|
+
opened = output();
|
|
7883
|
+
closed = output();
|
|
7884
|
+
// Content projection queries
|
|
7885
|
+
actionContent = contentChildren(TnSidePanelActionDirective, ...(ngDevMode ? [{ debugName: "actionContent" }] : []));
|
|
7886
|
+
hasActions = computed(() => this.actionContent().length > 0, ...(ngDevMode ? [{ debugName: "hasActions" }] : []));
|
|
7887
|
+
// Unique IDs for aria-labelledby and portal correlation
|
|
7888
|
+
panelId = `tn-side-panel-${Math.random().toString(36).substring(2, 9)}`;
|
|
7889
|
+
titleId = `${this.panelId}-title`;
|
|
7890
|
+
// Focus restoration
|
|
7891
|
+
previouslyFocusedElement = null;
|
|
7892
|
+
constructor() {
|
|
7893
|
+
this.registerMdiIcons();
|
|
7894
|
+
effect(() => {
|
|
7895
|
+
if (this.open()) {
|
|
7896
|
+
this.previouslyFocusedElement = this.document.activeElement;
|
|
7897
|
+
}
|
|
7898
|
+
});
|
|
7899
|
+
afterNextRender(() => {
|
|
7900
|
+
this.document.body.appendChild(this.overlayRef().nativeElement);
|
|
7901
|
+
this.initialized.set(true);
|
|
7902
|
+
});
|
|
7903
|
+
}
|
|
7904
|
+
ngOnDestroy() {
|
|
7905
|
+
this.overlayRef().nativeElement.remove();
|
|
7906
|
+
}
|
|
7907
|
+
dismiss() {
|
|
7908
|
+
this.open.set(false);
|
|
7909
|
+
}
|
|
7910
|
+
onBackdropClick() {
|
|
7911
|
+
if (this.closeOnBackdropClick()) {
|
|
7912
|
+
this.dismiss();
|
|
7913
|
+
}
|
|
7914
|
+
}
|
|
7915
|
+
onKeydown(event) {
|
|
7916
|
+
if (event.key === 'Escape' && this.closeOnEscape() && this.open()) {
|
|
7917
|
+
event.stopPropagation();
|
|
7918
|
+
this.dismiss();
|
|
7919
|
+
}
|
|
7920
|
+
}
|
|
7921
|
+
onTransitionEnd(event) {
|
|
7922
|
+
if (event.propertyName !== 'transform' || event.target !== event.currentTarget) {
|
|
7923
|
+
return;
|
|
7924
|
+
}
|
|
7925
|
+
if (this.open()) {
|
|
7926
|
+
this.opened.emit();
|
|
7927
|
+
}
|
|
7928
|
+
else {
|
|
7929
|
+
this.closed.emit();
|
|
7930
|
+
this.restoreFocus();
|
|
7931
|
+
}
|
|
7932
|
+
}
|
|
7933
|
+
restoreFocus() {
|
|
7934
|
+
if (this.previouslyFocusedElement && typeof this.previouslyFocusedElement.focus === 'function') {
|
|
7935
|
+
this.previouslyFocusedElement.focus();
|
|
7936
|
+
this.previouslyFocusedElement = null;
|
|
7937
|
+
}
|
|
7938
|
+
}
|
|
7939
|
+
registerMdiIcons() {
|
|
7940
|
+
const mdiIcons = {
|
|
7941
|
+
'close': mdiClose,
|
|
7942
|
+
};
|
|
7943
|
+
this.iconRegistry.registerLibrary({
|
|
7944
|
+
name: 'mdi',
|
|
7945
|
+
resolver: (iconName) => {
|
|
7946
|
+
const pathData = mdiIcons[iconName];
|
|
7947
|
+
if (!pathData) {
|
|
7948
|
+
return null;
|
|
7949
|
+
}
|
|
7950
|
+
return `<svg viewBox="0 0 24 24"><path fill="currentColor" d="${pathData}"/></svg>`;
|
|
7951
|
+
},
|
|
7952
|
+
});
|
|
7953
|
+
}
|
|
7954
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnSidePanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7955
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnSidePanelComponent, isStandalone: true, selector: "tn-side-panel", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, hasBackdrop: { classPropertyName: "hasBackdrop", publicName: "hasBackdrop", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdropClick: { classPropertyName: "closeOnBackdropClick", publicName: "closeOnBackdropClick", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", opened: "opened", closed: "closed" }, host: { properties: { "attr.data-tn-panel": "panelId" }, classAttribute: "tn-side-panel" }, queries: [{ propertyName: "actionContent", predicate: TnSidePanelActionDirective, isSignal: true }], viewQueries: [{ propertyName: "overlayRef", first: true, predicate: ["overlay"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Overlay wrapper: portaled to document.body -->\n<div\n #overlay\n class=\"tn-side-panel__overlay\"\n role=\"dialog\"\n [attr.data-tn-panel]=\"panelId\"\n [class.tn-side-panel__overlay--initialized]=\"initialized()\"\n [class.tn-side-panel__overlay--open]=\"open()\"\n [attr.aria-modal]=\"open() ? 'true' : null\"\n [attr.aria-labelledby]=\"open() ? titleId : null\"\n [attr.aria-hidden]=\"!open() ? 'true' : null\">\n\n <!-- Backdrop -->\n @if (hasBackdrop()) {\n <div\n class=\"tn-side-panel__backdrop\"\n aria-hidden=\"true\"\n (click)=\"onBackdropClick()\">\n </div>\n }\n\n <!-- Panel -->\n <div\n class=\"tn-side-panel__panel\"\n tabindex=\"-1\"\n cdkTrapFocus\n [style.width]=\"width()\"\n [cdkTrapFocusAutoCapture]=\"open()\"\n (transitionend)=\"onTransitionEnd($event)\"\n (keydown)=\"onKeydown($event)\">\n\n <!-- Header -->\n <header class=\"tn-side-panel__header\">\n <h2 class=\"tn-side-panel__title\" [id]=\"titleId\">{{ title() }}</h2>\n <div class=\"tn-side-panel__header-actions\">\n <ng-content select=\"[tnSidePanelHeaderAction]\" />\n <tn-icon-button\n name=\"close\"\n library=\"mdi\"\n size=\"sm\"\n ariaLabel=\"Dismiss\"\n (onClick)=\"dismiss()\" />\n </div>\n </header>\n\n <!-- Content -->\n <section class=\"tn-side-panel__content\">\n <ng-content />\n </section>\n\n <!-- Actions -->\n @if (hasActions()) {\n <footer class=\"tn-side-panel__actions\">\n <ng-content select=\"[tnSidePanelAction]\" />\n </footer>\n }\n </div>\n</div>\n", styles: [":host{display:contents}.tn-side-panel__overlay{position:fixed;inset:0;z-index:1000;pointer-events:none}.tn-side-panel__overlay--open{pointer-events:auto}.tn-side-panel__overlay--open .tn-side-panel__backdrop{opacity:1}.tn-side-panel__overlay--open .tn-side-panel__panel{transform:translate(0)}.tn-side-panel__backdrop{position:absolute;inset:0;background:#00000080;opacity:0}.tn-side-panel__overlay--initialized .tn-side-panel__backdrop{transition:opacity .2s ease}.tn-side-panel__panel{position:absolute;top:0;right:0;bottom:0;display:flex;flex-direction:column;max-width:100vw;background:var(--tn-bg2, #282828);color:var(--tn-fg1, #ffffff);box-shadow:-4px 0 24px #0000004d;outline:none;transform:translate(100%)}.tn-side-panel__overlay--initialized .tn-side-panel__panel{transition:transform .3s cubic-bezier(.4,0,.2,1)}.tn-side-panel__header{flex:0 0 auto;display:flex;align-items:center;gap:16px;padding:16px 24px;border-bottom:1px solid var(--tn-lines, #383838)}.tn-side-panel__title{margin:0;font-size:1.25rem;font-weight:600;line-height:1.5;color:var(--tn-fg1, #ffffff);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tn-side-panel__header-actions{display:flex;align-items:center;gap:8px;flex-shrink:0}.tn-side-panel__content{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;padding:var(--tn-content-padding, 24px);-webkit-overflow-scrolling:touch}.tn-side-panel__actions{flex:0 0 auto;display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid var(--tn-lines, #383838)}@media(max-width:640px){.tn-side-panel__panel{width:100vw!important}}@media(prefers-reduced-motion:reduce){.tn-side-panel__panel,.tn-side-panel__backdrop{transition-duration:0ms!important}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i1$4.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: TnIconButtonComponent, selector: "tn-icon-button", inputs: ["disabled", "ariaLabel", "name", "size", "color", "tooltip", "library"], outputs: ["onClick"] }] });
|
|
7956
|
+
}
|
|
7957
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnSidePanelComponent, decorators: [{
|
|
7958
|
+
type: Component,
|
|
7959
|
+
args: [{ selector: 'tn-side-panel', standalone: true, imports: [CommonModule, A11yModule, TnIconButtonComponent], host: {
|
|
7960
|
+
'class': 'tn-side-panel',
|
|
7961
|
+
'[attr.data-tn-panel]': 'panelId',
|
|
7962
|
+
}, template: "<!-- Overlay wrapper: portaled to document.body -->\n<div\n #overlay\n class=\"tn-side-panel__overlay\"\n role=\"dialog\"\n [attr.data-tn-panel]=\"panelId\"\n [class.tn-side-panel__overlay--initialized]=\"initialized()\"\n [class.tn-side-panel__overlay--open]=\"open()\"\n [attr.aria-modal]=\"open() ? 'true' : null\"\n [attr.aria-labelledby]=\"open() ? titleId : null\"\n [attr.aria-hidden]=\"!open() ? 'true' : null\">\n\n <!-- Backdrop -->\n @if (hasBackdrop()) {\n <div\n class=\"tn-side-panel__backdrop\"\n aria-hidden=\"true\"\n (click)=\"onBackdropClick()\">\n </div>\n }\n\n <!-- Panel -->\n <div\n class=\"tn-side-panel__panel\"\n tabindex=\"-1\"\n cdkTrapFocus\n [style.width]=\"width()\"\n [cdkTrapFocusAutoCapture]=\"open()\"\n (transitionend)=\"onTransitionEnd($event)\"\n (keydown)=\"onKeydown($event)\">\n\n <!-- Header -->\n <header class=\"tn-side-panel__header\">\n <h2 class=\"tn-side-panel__title\" [id]=\"titleId\">{{ title() }}</h2>\n <div class=\"tn-side-panel__header-actions\">\n <ng-content select=\"[tnSidePanelHeaderAction]\" />\n <tn-icon-button\n name=\"close\"\n library=\"mdi\"\n size=\"sm\"\n ariaLabel=\"Dismiss\"\n (onClick)=\"dismiss()\" />\n </div>\n </header>\n\n <!-- Content -->\n <section class=\"tn-side-panel__content\">\n <ng-content />\n </section>\n\n <!-- Actions -->\n @if (hasActions()) {\n <footer class=\"tn-side-panel__actions\">\n <ng-content select=\"[tnSidePanelAction]\" />\n </footer>\n }\n </div>\n</div>\n", styles: [":host{display:contents}.tn-side-panel__overlay{position:fixed;inset:0;z-index:1000;pointer-events:none}.tn-side-panel__overlay--open{pointer-events:auto}.tn-side-panel__overlay--open .tn-side-panel__backdrop{opacity:1}.tn-side-panel__overlay--open .tn-side-panel__panel{transform:translate(0)}.tn-side-panel__backdrop{position:absolute;inset:0;background:#00000080;opacity:0}.tn-side-panel__overlay--initialized .tn-side-panel__backdrop{transition:opacity .2s ease}.tn-side-panel__panel{position:absolute;top:0;right:0;bottom:0;display:flex;flex-direction:column;max-width:100vw;background:var(--tn-bg2, #282828);color:var(--tn-fg1, #ffffff);box-shadow:-4px 0 24px #0000004d;outline:none;transform:translate(100%)}.tn-side-panel__overlay--initialized .tn-side-panel__panel{transition:transform .3s cubic-bezier(.4,0,.2,1)}.tn-side-panel__header{flex:0 0 auto;display:flex;align-items:center;gap:16px;padding:16px 24px;border-bottom:1px solid var(--tn-lines, #383838)}.tn-side-panel__title{margin:0;font-size:1.25rem;font-weight:600;line-height:1.5;color:var(--tn-fg1, #ffffff);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tn-side-panel__header-actions{display:flex;align-items:center;gap:8px;flex-shrink:0}.tn-side-panel__content{flex:1 1 auto;min-height:0;overflow-y:auto;overflow-x:hidden;padding:var(--tn-content-padding, 24px);-webkit-overflow-scrolling:touch}.tn-side-panel__actions{flex:0 0 auto;display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid var(--tn-lines, #383838)}@media(max-width:640px){.tn-side-panel__panel{width:100vw!important}}@media(prefers-reduced-motion:reduce){.tn-side-panel__panel,.tn-side-panel__backdrop{transition-duration:0ms!important}}\n"] }]
|
|
7963
|
+
}], ctorParameters: () => [], propDecorators: { overlayRef: [{ type: i0.ViewChild, args: ['overlay', { isSignal: true }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], hasBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasBackdrop", required: false }] }], closeOnBackdropClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnBackdropClick", required: false }] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], actionContent: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TnSidePanelActionDirective), { isSignal: true }] }] } });
|
|
7964
|
+
|
|
7965
|
+
/**
|
|
7966
|
+
* Harness for interacting with `TnSidePanelComponent` in tests.
|
|
7967
|
+
*
|
|
7968
|
+
* @example
|
|
7969
|
+
* ```typescript
|
|
7970
|
+
* const panel = await loader.getHarness(TnSidePanelHarness);
|
|
7971
|
+
* expect(await panel.isOpen()).toBe(true);
|
|
7972
|
+
* expect(await panel.getTitle()).toBe('Edit User');
|
|
7973
|
+
* await panel.dismiss();
|
|
7974
|
+
* ```
|
|
7975
|
+
*/
|
|
7976
|
+
class TnSidePanelHarness extends ComponentHarness {
|
|
7977
|
+
static hostSelector = 'tn-side-panel';
|
|
7978
|
+
static with(options = {}) {
|
|
7979
|
+
return new HarnessPredicate(TnSidePanelHarness, options)
|
|
7980
|
+
.addOption('title', options.title, (harness, title) => HarnessPredicate.stringMatches(harness.getTitle(), title));
|
|
7981
|
+
}
|
|
7982
|
+
/**
|
|
7983
|
+
* Locate the overlay wrapper, which may be portaled to document.body.
|
|
7984
|
+
* Uses the data-tn-panel attribute to correlate the host with its overlay.
|
|
7985
|
+
*/
|
|
7986
|
+
async getOverlay() {
|
|
7987
|
+
const host = await this.host();
|
|
7988
|
+
const panelId = await host.getAttribute('data-tn-panel');
|
|
7989
|
+
return this.documentRootLocatorFactory().locatorFor(`[data-tn-panel="${panelId}"].tn-side-panel__overlay`)();
|
|
7990
|
+
}
|
|
7991
|
+
/** Get the panel title text. */
|
|
7992
|
+
async getTitle() {
|
|
7993
|
+
const host = await this.host();
|
|
7994
|
+
const panelId = await host.getAttribute('data-tn-panel');
|
|
7995
|
+
const titleEl = await this.documentRootLocatorFactory().locatorFor(`[data-tn-panel="${panelId}"] .tn-side-panel__title`)();
|
|
7996
|
+
return (await titleEl.text()).trim();
|
|
7997
|
+
}
|
|
7998
|
+
/** Whether the panel is currently open. */
|
|
7999
|
+
async isOpen() {
|
|
8000
|
+
const overlay = await this.getOverlay();
|
|
8001
|
+
return overlay.hasClass('tn-side-panel__overlay--open');
|
|
8002
|
+
}
|
|
8003
|
+
/** Click the dismiss button to close the panel. */
|
|
8004
|
+
async dismiss() {
|
|
8005
|
+
const host = await this.host();
|
|
8006
|
+
const panelId = await host.getAttribute('data-tn-panel');
|
|
8007
|
+
const button = await this.documentRootLocatorFactory().locatorFor(`[data-tn-panel="${panelId}"] .tn-side-panel__header-actions tn-icon-button`)();
|
|
8008
|
+
await button.click();
|
|
8009
|
+
}
|
|
8010
|
+
/** Get the text content of the scrollable body area. */
|
|
8011
|
+
async getContentText() {
|
|
8012
|
+
const host = await this.host();
|
|
8013
|
+
const panelId = await host.getAttribute('data-tn-panel');
|
|
8014
|
+
const content = await this.documentRootLocatorFactory().locatorFor(`[data-tn-panel="${panelId}"] .tn-side-panel__content`)();
|
|
8015
|
+
return (await content.text()).trim();
|
|
8016
|
+
}
|
|
8017
|
+
}
|
|
8018
|
+
|
|
7824
8019
|
class TnStepComponent {
|
|
7825
8020
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
7826
8021
|
icon = input(undefined, ...(ngDevMode ? [{ debugName: "icon" }] : []));
|
|
@@ -8792,6 +8987,134 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
|
|
|
8792
8987
|
}, template: "<div class=\"tn-file-picker-container\">\n <div #wrapper ixInput class=\"tn-file-picker-wrapper\" style=\"padding-right: 40px;\">\n <input\n type=\"text\"\n class=\"tn-file-picker-input\"\n [class.error]=\"hasError()\"\n [value]=\"selectedPath() | tnStripMntPrefix\"\n [placeholder]=\"placeholder()\"\n [readonly]=\"!allowManualInput()\"\n [disabled]=\"isDisabled()\"\n (input)=\"onPathInput($event)\">\n\n <button\n type=\"button\"\n class=\"tn-file-picker-toggle\"\n aria-label=\"Open file picker\"\n [disabled]=\"isDisabled()\"\n (click)=\"openFilePicker()\">\n <tn-icon name=\"folder\" library=\"mdi\" />\n </button>\n </div>\n \n <ng-template #filePickerTemplate>\n <tn-file-picker-popup\n class=\"tn-file-picker-popup\"\n [mode]=\"mode()\"\n [multiSelect]=\"multiSelect()\"\n [allowCreate]=\"allowCreate()\"\n [allowDatasetCreate]=\"allowDatasetCreate()\"\n [allowZvolCreate]=\"allowZvolCreate()\"\n [currentPath]=\"currentPath()\"\n [fileItems]=\"fileItems()\"\n [selectedItems]=\"selectedItems()\"\n [loading]=\"loading()\"\n [creationLoading]=\"creationLoading()\"\n [fileExtensions]=\"fileExtensions()\"\n (itemClick)=\"onItemClick($event)\"\n (itemDoubleClick)=\"onItemDoubleClick($event)\"\n (pathNavigate)=\"navigateToPath($event)\"\n (createFolder)=\"onCreateFolder()\"\n (submitFolderName)=\"onSubmitFolderName($event.name, $event.tempId)\"\n (cancelFolderCreation)=\"onCancelFolderCreation($event)\"\n (clearSelection)=\"onClearSelection()\"\n (submit)=\"onSubmit()\"\n (cancel)=\"onCancel()\"\n (close)=\"close()\" />\n </ng-template>\n</div>", styles: [":host{display:block;width:100%;font-family:var(--tn-font-family-body, \"Inter\"),sans-serif}.tn-file-picker-container{position:relative;display:flex;align-items:center;width:100%}.tn-file-picker-wrapper{display:flex;align-items:center;width:100%;position:relative}.tn-file-picker-input{display:block;width:100%;min-height:2.5rem;padding:.5rem .75rem;font-size:1rem;line-height:1.5;color:var(--tn-fg1, #212529);background-color:var(--tn-bg1, #ffffff);border:1px solid var(--tn-lines, #d1d5db);border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;outline:none;box-sizing:border-box;font-family:inherit}.tn-file-picker-input::placeholder{color:var(--tn-alt-fg1, #999);opacity:1}.tn-file-picker-input:focus{border-color:var(--tn-primary, #007bff);box-shadow:0 0 0 2px #007bff40}.tn-file-picker-input:disabled{background-color:var(--tn-alt-bg1, #f8f9fa);color:var(--tn-fg2, #6c757d);cursor:not-allowed;opacity:.6}.tn-file-picker-input.error{border-color:var(--tn-error, #dc3545)}.tn-file-picker-input.error:focus{border-color:var(--tn-error, #dc3545);box-shadow:0 0 0 2px #dc354540}.tn-file-picker-toggle{position:absolute;right:8px;z-index:2;pointer-events:auto;background:transparent;border:none;cursor:pointer;padding:4px;color:var(--tn-fg1);border-radius:4px}.tn-file-picker-toggle:hover{background:var(--tn-bg2, #f0f0f0)}.tn-file-picker-toggle:focus{outline:2px solid var(--tn-primary);outline-offset:2px}.tn-file-picker-toggle:disabled{cursor:not-allowed;opacity:.5}.tn-file-picker-toggle tn-icon{font-size:var(--tn-icon-md, 20px)}:host:focus-within .tn-file-picker-input{border-color:var(--tn-primary, #007bff);box-shadow:0 0 0 2px #007bff40}:host.error .tn-file-picker-input{border-color:var(--tn-error, #dc3545)}:host.error .tn-file-picker-input:focus{border-color:var(--tn-error, #dc3545);box-shadow:0 0 0 2px #dc354540}@media(prefers-reduced-motion:reduce){.tn-file-picker-input,.tn-file-picker-toggle,.file-item,.breadcrumb-segment{transition:none}.tn-file-picker-loading tn-icon{animation:none}}@media(prefers-contrast:high){.tn-file-picker-input{border-width:2px}.file-item:hover,.file-item.selected{border:2px solid var(--tn-fg1)}.zfs-badge{border:1px solid var(--tn-fg1)}}@media(max-width:768px){:host ::ng-deep .tn-file-picker-overlay .tn-file-picker-dialog{min-width:300px;max-width:calc(100vw - 32px);max-height:calc(100vh - 64px)}.tn-file-picker-header{flex-direction:column;gap:12px;align-items:stretch}.tn-file-picker-breadcrumb{overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none}.tn-file-picker-breadcrumb::-webkit-scrollbar{display:none}.file-item{padding:12px;min-height:56px}.file-info{font-size:.875rem}}\n"] }]
|
|
8793
8988
|
}], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], multiSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiSelect", required: false }] }], allowCreate: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowCreate", required: false }] }], allowDatasetCreate: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowDatasetCreate", required: false }] }], allowZvolCreate: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowZvolCreate", required: false }] }], allowManualInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowManualInput", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], startPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "startPath", required: false }] }], rootPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "rootPath", required: false }] }], fileExtensions: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileExtensions", required: false }] }], callbacks: [{ type: i0.Input, args: [{ isSignal: true, alias: "callbacks", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], pathChange: [{ type: i0.Output, args: ["pathChange"] }], createFolder: [{ type: i0.Output, args: ["createFolder"] }], error: [{ type: i0.Output, args: ["error"] }], wrapperEl: [{ type: i0.ViewChild, args: ['wrapper', { isSignal: true }] }], filePickerTemplate: [{ type: i0.ViewChild, args: ['filePickerTemplate', { isSignal: true }] }] } });
|
|
8794
8989
|
|
|
8990
|
+
class TnEmptyComponent {
|
|
8991
|
+
title = input.required(...(ngDevMode ? [{ debugName: "title" }] : []));
|
|
8992
|
+
description = input(...(ngDevMode ? [undefined, { debugName: "description" }] : []));
|
|
8993
|
+
icon = input(...(ngDevMode ? [undefined, { debugName: "icon" }] : []));
|
|
8994
|
+
iconLibrary = input('mdi', ...(ngDevMode ? [{ debugName: "iconLibrary" }] : []));
|
|
8995
|
+
actionText = input(...(ngDevMode ? [undefined, { debugName: "actionText" }] : []));
|
|
8996
|
+
size = input('default', ...(ngDevMode ? [{ debugName: "size" }] : []));
|
|
8997
|
+
onAction = output();
|
|
8998
|
+
hasAction = computed(() => !!this.actionText(), ...(ngDevMode ? [{ debugName: "hasAction" }] : []));
|
|
8999
|
+
iconSize = computed(() => {
|
|
9000
|
+
return this.size() === 'compact' ? 'lg' : 'xl';
|
|
9001
|
+
}, ...(ngDevMode ? [{ debugName: "iconSize" }] : []));
|
|
9002
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnEmptyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9003
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnEmptyComponent, isStandalone: true, selector: "tn-empty", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconLibrary: { classPropertyName: "iconLibrary", publicName: "iconLibrary", isSignal: true, isRequired: false, transformFunction: null }, actionText: { classPropertyName: "actionText", publicName: "actionText", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onAction: "onAction" }, host: { attributes: { "role": "status" }, properties: { "class.tn-empty--compact": "size() === \"compact\"" }, classAttribute: "tn-empty" }, ngImport: i0, template: "@if (icon()) {\n <div class=\"tn-empty__icon\">\n <tn-icon\n aria-hidden=\"true\"\n [name]=\"icon()!\"\n [library]=\"iconLibrary()\"\n [size]=\"iconSize()\"\n />\n </div>\n}\n\n<div class=\"tn-empty__title\">\n {{ title() }}\n</div>\n\n@if (description()) {\n <div class=\"tn-empty__description\">\n {{ description() }}\n </div>\n}\n\n@if (hasAction()) {\n <div class=\"tn-empty__action\">\n <tn-button\n color=\"primary\"\n variant=\"outline\"\n [label]=\"actionText()!\"\n (onClick)=\"onAction.emit()\"\n />\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:8px;padding:48px 24px}:host(.tn-empty--compact){padding:24px 16px}:host(.tn-empty--compact) .tn-empty__title{font-size:1rem}:host(.tn-empty--compact) .tn-empty__description{font-size:.8125rem}:host(.tn-empty--compact) .tn-empty__icon{margin-bottom:4px}:host(.tn-empty--compact) .tn-empty__action{margin-top:4px}.tn-empty__icon{color:var(--tn-fg2, #6b7280);margin-bottom:8px}.tn-empty__title{font-size:1.125rem;font-weight:600;color:var(--tn-fg1, #e5e7eb);line-height:1.4}.tn-empty__description{font-size:.875rem;color:var(--tn-fg2, #6b7280);line-height:1.5;max-width:420px}.tn-empty__action{margin-top:8px}\n"], dependencies: [{ kind: "component", type: TnIconComponent, selector: "tn-icon", inputs: ["name", "size", "color", "tooltip", "ariaLabel", "library", "fullSize", "customSize"] }, { kind: "component", type: TnButtonComponent, selector: "tn-button", inputs: ["primary", "color", "variant", "backgroundColor", "label", "disabled"], outputs: ["onClick"] }] });
|
|
9004
|
+
}
|
|
9005
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnEmptyComponent, decorators: [{
|
|
9006
|
+
type: Component,
|
|
9007
|
+
args: [{ selector: 'tn-empty', standalone: true, imports: [TnIconComponent, TnButtonComponent], host: {
|
|
9008
|
+
'class': 'tn-empty',
|
|
9009
|
+
'[class.tn-empty--compact]': 'size() === "compact"',
|
|
9010
|
+
'role': 'status',
|
|
9011
|
+
}, template: "@if (icon()) {\n <div class=\"tn-empty__icon\">\n <tn-icon\n aria-hidden=\"true\"\n [name]=\"icon()!\"\n [library]=\"iconLibrary()\"\n [size]=\"iconSize()\"\n />\n </div>\n}\n\n<div class=\"tn-empty__title\">\n {{ title() }}\n</div>\n\n@if (description()) {\n <div class=\"tn-empty__description\">\n {{ description() }}\n </div>\n}\n\n@if (hasAction()) {\n <div class=\"tn-empty__action\">\n <tn-button\n color=\"primary\"\n variant=\"outline\"\n [label]=\"actionText()!\"\n (onClick)=\"onAction.emit()\"\n />\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:8px;padding:48px 24px}:host(.tn-empty--compact){padding:24px 16px}:host(.tn-empty--compact) .tn-empty__title{font-size:1rem}:host(.tn-empty--compact) .tn-empty__description{font-size:.8125rem}:host(.tn-empty--compact) .tn-empty__icon{margin-bottom:4px}:host(.tn-empty--compact) .tn-empty__action{margin-top:4px}.tn-empty__icon{color:var(--tn-fg2, #6b7280);margin-bottom:8px}.tn-empty__title{font-size:1.125rem;font-weight:600;color:var(--tn-fg1, #e5e7eb);line-height:1.4}.tn-empty__description{font-size:.875rem;color:var(--tn-fg2, #6b7280);line-height:1.5;max-width:420px}.tn-empty__action{margin-top:8px}\n"] }]
|
|
9012
|
+
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], iconLibrary: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconLibrary", required: false }] }], actionText: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionText", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], onAction: [{ type: i0.Output, args: ["onAction"] }] } });
|
|
9013
|
+
|
|
9014
|
+
/**
|
|
9015
|
+
* Harness for interacting with tn-empty in tests.
|
|
9016
|
+
* Provides text-based querying for verifying empty state content.
|
|
9017
|
+
*
|
|
9018
|
+
* @example
|
|
9019
|
+
* ```typescript
|
|
9020
|
+
* // Check for existence
|
|
9021
|
+
* const empty = await loader.getHarness(TnEmptyHarness);
|
|
9022
|
+
*
|
|
9023
|
+
* // Find empty state by title
|
|
9024
|
+
* const noItems = await loader.getHarness(
|
|
9025
|
+
* TnEmptyHarness.with({ title: 'No items found' })
|
|
9026
|
+
* );
|
|
9027
|
+
*
|
|
9028
|
+
* // Check if empty state exists with specific text
|
|
9029
|
+
* const hasEmpty = await loader.hasHarness(
|
|
9030
|
+
* TnEmptyHarness.with({ title: /no.*found/i })
|
|
9031
|
+
* );
|
|
9032
|
+
* ```
|
|
9033
|
+
*/
|
|
9034
|
+
class TnEmptyHarness extends ComponentHarness {
|
|
9035
|
+
/**
|
|
9036
|
+
* The selector for the host element of a `TnEmptyComponent` instance.
|
|
9037
|
+
*/
|
|
9038
|
+
static hostSelector = 'tn-empty';
|
|
9039
|
+
_title = this.locatorFor('.tn-empty__title');
|
|
9040
|
+
_description = this.locatorForOptional('.tn-empty__description');
|
|
9041
|
+
/**
|
|
9042
|
+
* Gets a `HarnessPredicate` that can be used to search for an empty state
|
|
9043
|
+
* with specific attributes.
|
|
9044
|
+
*
|
|
9045
|
+
* @param options Options for filtering which empty state instances are considered a match.
|
|
9046
|
+
* @returns A `HarnessPredicate` configured with the given options.
|
|
9047
|
+
*
|
|
9048
|
+
* @example
|
|
9049
|
+
* ```typescript
|
|
9050
|
+
* // Find by title
|
|
9051
|
+
* const empty = await loader.getHarness(
|
|
9052
|
+
* TnEmptyHarness.with({ title: 'No results' })
|
|
9053
|
+
* );
|
|
9054
|
+
*
|
|
9055
|
+
* // Find by title regex
|
|
9056
|
+
* const empty = await loader.getHarness(
|
|
9057
|
+
* TnEmptyHarness.with({ title: /empty/i })
|
|
9058
|
+
* );
|
|
9059
|
+
* ```
|
|
9060
|
+
*/
|
|
9061
|
+
static with(options = {}) {
|
|
9062
|
+
return new HarnessPredicate(TnEmptyHarness, options)
|
|
9063
|
+
.addOption('title', options.title, (harness, title) => HarnessPredicate.stringMatches(harness.getTitle(), title));
|
|
9064
|
+
}
|
|
9065
|
+
/**
|
|
9066
|
+
* Gets the title text.
|
|
9067
|
+
*
|
|
9068
|
+
* @returns Promise resolving to the empty state's title text.
|
|
9069
|
+
*
|
|
9070
|
+
* @example
|
|
9071
|
+
* ```typescript
|
|
9072
|
+
* const empty = await loader.getHarness(TnEmptyHarness);
|
|
9073
|
+
* const title = await empty.getTitle();
|
|
9074
|
+
* expect(title).toBe('No items found');
|
|
9075
|
+
* ```
|
|
9076
|
+
*/
|
|
9077
|
+
async getTitle() {
|
|
9078
|
+
const title = await this._title();
|
|
9079
|
+
return (await title.text()).trim();
|
|
9080
|
+
}
|
|
9081
|
+
/**
|
|
9082
|
+
* Gets the description text, or null if no description is rendered.
|
|
9083
|
+
*
|
|
9084
|
+
* @returns Promise resolving to the description text, or null.
|
|
9085
|
+
*
|
|
9086
|
+
* @example
|
|
9087
|
+
* ```typescript
|
|
9088
|
+
* const empty = await loader.getHarness(TnEmptyHarness);
|
|
9089
|
+
* const desc = await empty.getDescription();
|
|
9090
|
+
* expect(desc).toBe('Try adjusting your filters');
|
|
9091
|
+
* ```
|
|
9092
|
+
*/
|
|
9093
|
+
async getDescription() {
|
|
9094
|
+
const desc = await this._description();
|
|
9095
|
+
if (!desc) {
|
|
9096
|
+
return null;
|
|
9097
|
+
}
|
|
9098
|
+
return (await desc.text()).trim();
|
|
9099
|
+
}
|
|
9100
|
+
/**
|
|
9101
|
+
* Gets all text content from the empty state (title + description combined).
|
|
9102
|
+
*
|
|
9103
|
+
* @returns Promise resolving to the full text content, trimmed of whitespace.
|
|
9104
|
+
*
|
|
9105
|
+
* @example
|
|
9106
|
+
* ```typescript
|
|
9107
|
+
* const empty = await loader.getHarness(TnEmptyHarness);
|
|
9108
|
+
* const text = await empty.getText();
|
|
9109
|
+
* expect(text).toContain('No items');
|
|
9110
|
+
* ```
|
|
9111
|
+
*/
|
|
9112
|
+
async getText() {
|
|
9113
|
+
const host = await this.host();
|
|
9114
|
+
return (await host.text()).trim();
|
|
9115
|
+
}
|
|
9116
|
+
}
|
|
9117
|
+
|
|
8795
9118
|
class TnKeyboardShortcutService {
|
|
8796
9119
|
shortcuts = new Map();
|
|
8797
9120
|
globalEnabled = true;
|
|
@@ -9310,5 +9633,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
|
|
|
9310
9633
|
* Generated bundle index. Do not edit.
|
|
9311
9634
|
*/
|
|
9312
9635
|
|
|
9313
|
-
export { CommonShortcuts, DEFAULT_THEME, DiskIconComponent, DiskType, FileSizePipe, InputType, LinuxModifierKeys, LinuxShortcuts, ModifierKeys, QuickShortcuts, ShortcutBuilder, StripMntPrefixPipe, THEME_MAP, THEME_STORAGE_KEY, TN_THEME_DEFINITIONS, TnBannerActionDirective, TnBannerComponent, TnBannerHarness, TnBrandedSpinnerComponent, TnButtonComponent, TnButtonHarness, TnButtonToggleComponent, TnButtonToggleGroupComponent, TnCalendarComponent, TnCalendarHeaderComponent, TnCardComponent, TnCellDefDirective, TnCheckboxComponent, TnChipComponent, TnConfirmDialogComponent, TnDateInputComponent, TnDateRangeInputComponent, TnDialog, TnDialogShellComponent, TnDividerComponent, TnDividerDirective, TnExpansionPanelComponent, TnFilePickerComponent, TnFilePickerPopupComponent, TnFormFieldComponent, TnHeaderCellDefDirective, TnIconButtonComponent, TnIconButtonHarness, TnIconComponent, TnIconHarness, TnIconRegistryService, TnIconTesting, TnInputComponent, TnInputDirective, TnInputHarness, TnKeyboardShortcutComponent, TnKeyboardShortcutService, TnListAvatarDirective, TnListComponent, TnListIconDirective, TnListItemComponent, TnListItemLineDirective, TnListItemPrimaryDirective, TnListItemSecondaryDirective, TnListItemTitleDirective, TnListItemTrailingDirective, TnListOptionComponent, TnListSubheaderComponent, TnMenuComponent, TnMenuTriggerDirective, TnMonthViewComponent, TnMultiYearViewComponent, TnNestedTreeNodeComponent, TnParticleProgressBarComponent, TnProgressBarComponent, TnRadioComponent, TnSelectComponent, TnSelectHarness, TnSelectionListComponent, TnSlideToggleComponent, TnSliderComponent, TnSliderThumbDirective, TnSliderWithLabelDirective, TnSpinnerComponent, TnSpriteLoaderService, TnStepComponent, TnStepperComponent, TnTabComponent, TnTabHarness, TnTabPanelComponent, TnTabPanelHarness, TnTableColumnDirective, TnTableComponent, TnTabsComponent, TnTabsHarness, TnTheme, TnThemeService, TnTimeInputComponent, TnTooltipComponent, TnTooltipDirective, TnTreeComponent, TnTreeFlatDataSource, TnTreeFlattener, TnTreeNodeComponent, TnTreeNodeOutletDirective, TruncatePathPipe, WindowsModifierKeys, WindowsShortcuts, createLucideLibrary, createShortcut, defaultSpriteBasePath, defaultSpriteConfigPath, libIconMarker, registerLucideIcons, setupLucideIntegration, tnIconMarker };
|
|
9636
|
+
export { CommonShortcuts, DEFAULT_THEME, DiskIconComponent, DiskType, FileSizePipe, InputType, LinuxModifierKeys, LinuxShortcuts, ModifierKeys, QuickShortcuts, ShortcutBuilder, StripMntPrefixPipe, THEME_MAP, THEME_STORAGE_KEY, TN_THEME_DEFINITIONS, TnBannerActionDirective, TnBannerComponent, TnBannerHarness, TnBrandedSpinnerComponent, TnButtonComponent, TnButtonHarness, TnButtonToggleComponent, TnButtonToggleGroupComponent, TnCalendarComponent, TnCalendarHeaderComponent, TnCardComponent, TnCellDefDirective, TnCheckboxComponent, TnChipComponent, TnConfirmDialogComponent, TnDateInputComponent, TnDateRangeInputComponent, TnDialog, TnDialogShellComponent, TnDividerComponent, TnDividerDirective, TnEmptyComponent, TnEmptyHarness, TnExpansionPanelComponent, TnFilePickerComponent, TnFilePickerPopupComponent, TnFormFieldComponent, TnHeaderCellDefDirective, TnIconButtonComponent, TnIconButtonHarness, TnIconComponent, TnIconHarness, TnIconRegistryService, TnIconTesting, TnInputComponent, TnInputDirective, TnInputHarness, TnKeyboardShortcutComponent, TnKeyboardShortcutService, TnListAvatarDirective, TnListComponent, TnListIconDirective, TnListItemComponent, TnListItemLineDirective, TnListItemPrimaryDirective, TnListItemSecondaryDirective, TnListItemTitleDirective, TnListItemTrailingDirective, TnListOptionComponent, TnListSubheaderComponent, TnMenuComponent, TnMenuTriggerDirective, TnMonthViewComponent, TnMultiYearViewComponent, TnNestedTreeNodeComponent, TnParticleProgressBarComponent, TnProgressBarComponent, TnRadioComponent, TnSelectComponent, TnSelectHarness, TnSelectionListComponent, TnSidePanelActionDirective, TnSidePanelComponent, TnSidePanelHarness, TnSidePanelHeaderActionDirective, TnSlideToggleComponent, TnSliderComponent, TnSliderThumbDirective, TnSliderWithLabelDirective, TnSpinnerComponent, TnSpriteLoaderService, TnStepComponent, TnStepperComponent, TnTabComponent, TnTabHarness, TnTabPanelComponent, TnTabPanelHarness, TnTableColumnDirective, TnTableComponent, TnTabsComponent, TnTabsHarness, TnTheme, TnThemeService, TnTimeInputComponent, TnTooltipComponent, TnTooltipDirective, TnTreeComponent, TnTreeFlatDataSource, TnTreeFlattener, TnTreeNodeComponent, TnTreeNodeOutletDirective, TruncatePathPipe, WindowsModifierKeys, WindowsShortcuts, createLucideLibrary, createShortcut, defaultSpriteBasePath, defaultSpriteConfigPath, libIconMarker, registerLucideIcons, setupLucideIntegration, tnIconMarker };
|
|
9314
9637
|
//# sourceMappingURL=truenas-ui-components.mjs.map
|