@truenas/ui-components 0.1.74 → 0.1.76
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.
|
@@ -15,6 +15,7 @@ import { DomSanitizer } from '@angular/platform-browser';
|
|
|
15
15
|
import { HttpClient } from '@angular/common/http';
|
|
16
16
|
import { firstValueFrom, BehaviorSubject, merge, Subject, take } from 'rxjs';
|
|
17
17
|
import { RouterLink } from '@angular/router';
|
|
18
|
+
import { filesize } from 'filesize';
|
|
18
19
|
import { CdkMenu, CdkMenuItem, CdkMenuTrigger } from '@angular/cdk/menu';
|
|
19
20
|
import { trigger, state, transition, style, animate } from '@angular/animations';
|
|
20
21
|
import { SPACE, ENTER, END, HOME, DOWN_ARROW, UP_ARROW, RIGHT_ARROW, LEFT_ARROW } from '@angular/cdk/keycodes';
|
|
@@ -2002,13 +2003,13 @@ class TnTooltipComponent {
|
|
|
2002
2003
|
message = input('', ...(ngDevMode ? [{ debugName: "message" }] : []));
|
|
2003
2004
|
id = input('', ...(ngDevMode ? [{ debugName: "id" }] : []));
|
|
2004
2005
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2005
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.0", type: TnTooltipComponent, isStandalone: true, selector: "tn-tooltip", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "tn-tooltip-component" }, ngImport: i0, template: "<div\n class=\"tn-tooltip\"\n role=\"tooltip\"\n [id]=\"id()\"\n [attr.aria-hidden]=\"false\"
|
|
2006
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.0", type: TnTooltipComponent, isStandalone: true, selector: "tn-tooltip", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "tn-tooltip-component" }, ngImport: i0, template: "<div\n class=\"tn-tooltip\"\n role=\"tooltip\"\n [id]=\"id()\"\n [attr.aria-hidden]=\"false\"\n [innerHTML]=\"message()\">\n</div>\n", styles: [":host{display:block;pointer-events:none;z-index:1200}.tn-tooltip{background:#373737e6;color:#fff;padding:6px 8px;border-radius:4px;font-size:12px;font-weight:500;line-height:1.4;max-width:200px;word-wrap:break-word;white-space:pre-line;box-shadow:0 2px 8px #0003;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);animation:tn-tooltip-show .15s cubic-bezier(0,0,.2,1) forwards;transform-origin:center bottom}@keyframes tn-tooltip-show{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}.tn-tooltip{position:relative}.tn-tooltip:after{content:\"\";position:absolute;width:0;height:0;border-style:solid;z-index:1}:host-context(.tn-tooltip-panel-above) .tn-tooltip:after{top:100%;left:50%;transform:translate(-50%);border-width:6px 6px 0 6px;border-color:rgba(55,55,55,.9) transparent transparent transparent}:host-context(.tn-tooltip-panel-below) .tn-tooltip:after{bottom:100%;left:50%;transform:translate(-50%);border-width:0 6px 6px 6px;border-color:transparent transparent rgba(55,55,55,.9) transparent}:host-context(.tn-tooltip-panel-left) .tn-tooltip:after,:host-context(.tn-tooltip-panel-before) .tn-tooltip:after{top:50%;left:100%;transform:translateY(-50%);border-width:6px 0 6px 6px;border-color:transparent transparent transparent rgba(55,55,55,.9)}:host-context(.tn-tooltip-panel-right) .tn-tooltip:after,:host-context(.tn-tooltip-panel-after) .tn-tooltip:after{top:50%;right:100%;transform:translateY(-50%);border-width:6px 6px 6px 0;border-color:transparent rgba(55,55,55,.9) transparent transparent}@media(prefers-contrast:high){.tn-tooltip{background:var(--tn-fg1, #000);color:var(--tn-bg1, #fff);border:1px solid var(--tn-lines, #999)}:host-context(.tn-tooltip-panel-above) .tn-tooltip:after{border-top-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-below) .tn-tooltip:after{border-bottom-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-left) .tn-tooltip:after,:host-context(.tn-tooltip-panel-before) .tn-tooltip:after{border-left-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-right) .tn-tooltip:after,:host-context(.tn-tooltip-panel-after) .tn-tooltip:after{border-right-color:var(--tn-fg1, #000)}}:host-context(.tn-slider-thumb-label) .tn-tooltip{font-size:11px;padding:4px 6px;font-weight:600;min-width:24px;text-align:center;background:#373737f2}@media(prefers-reduced-motion:reduce){.tn-tooltip{animation:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2006
2007
|
}
|
|
2007
2008
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnTooltipComponent, decorators: [{
|
|
2008
2009
|
type: Component,
|
|
2009
2010
|
args: [{ selector: 'tn-tooltip', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
2010
2011
|
'class': 'tn-tooltip-component'
|
|
2011
|
-
}, template: "<div\n class=\"tn-tooltip\"\n role=\"tooltip\"\n [id]=\"id()\"\n [attr.aria-hidden]=\"false\"
|
|
2012
|
+
}, template: "<div\n class=\"tn-tooltip\"\n role=\"tooltip\"\n [id]=\"id()\"\n [attr.aria-hidden]=\"false\"\n [innerHTML]=\"message()\">\n</div>\n", styles: [":host{display:block;pointer-events:none;z-index:1200}.tn-tooltip{background:#373737e6;color:#fff;padding:6px 8px;border-radius:4px;font-size:12px;font-weight:500;line-height:1.4;max-width:200px;word-wrap:break-word;white-space:pre-line;box-shadow:0 2px 8px #0003;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);animation:tn-tooltip-show .15s cubic-bezier(0,0,.2,1) forwards;transform-origin:center bottom}@keyframes tn-tooltip-show{0%{opacity:0;transform:scale(.8)}to{opacity:1;transform:scale(1)}}.tn-tooltip{position:relative}.tn-tooltip:after{content:\"\";position:absolute;width:0;height:0;border-style:solid;z-index:1}:host-context(.tn-tooltip-panel-above) .tn-tooltip:after{top:100%;left:50%;transform:translate(-50%);border-width:6px 6px 0 6px;border-color:rgba(55,55,55,.9) transparent transparent transparent}:host-context(.tn-tooltip-panel-below) .tn-tooltip:after{bottom:100%;left:50%;transform:translate(-50%);border-width:0 6px 6px 6px;border-color:transparent transparent rgba(55,55,55,.9) transparent}:host-context(.tn-tooltip-panel-left) .tn-tooltip:after,:host-context(.tn-tooltip-panel-before) .tn-tooltip:after{top:50%;left:100%;transform:translateY(-50%);border-width:6px 0 6px 6px;border-color:transparent transparent transparent rgba(55,55,55,.9)}:host-context(.tn-tooltip-panel-right) .tn-tooltip:after,:host-context(.tn-tooltip-panel-after) .tn-tooltip:after{top:50%;right:100%;transform:translateY(-50%);border-width:6px 6px 6px 0;border-color:transparent rgba(55,55,55,.9) transparent transparent}@media(prefers-contrast:high){.tn-tooltip{background:var(--tn-fg1, #000);color:var(--tn-bg1, #fff);border:1px solid var(--tn-lines, #999)}:host-context(.tn-tooltip-panel-above) .tn-tooltip:after{border-top-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-below) .tn-tooltip:after{border-bottom-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-left) .tn-tooltip:after,:host-context(.tn-tooltip-panel-before) .tn-tooltip:after{border-left-color:var(--tn-fg1, #000)}:host-context(.tn-tooltip-panel-right) .tn-tooltip:after,:host-context(.tn-tooltip-panel-after) .tn-tooltip:after{border-right-color:var(--tn-fg1, #000)}}:host-context(.tn-slider-thumb-label) .tn-tooltip{font-size:11px;padding:4px 6px;font-weight:600;min-width:24px;text-align:center;background:#373737f2}@media(prefers-reduced-motion:reduce){.tn-tooltip{animation:none}}\n"] }]
|
|
2012
2013
|
}], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }] } });
|
|
2013
2014
|
|
|
2014
2015
|
/* eslint-disable @angular-eslint/no-input-rename */
|
|
@@ -2478,8 +2479,109 @@ var InputType;
|
|
|
2478
2479
|
InputType["Number"] = "number";
|
|
2479
2480
|
InputType["Password"] = "password";
|
|
2480
2481
|
InputType["PlainText"] = "text";
|
|
2482
|
+
/**
|
|
2483
|
+
* Data-size field: the form model holds a raw byte count (a number), while the
|
|
2484
|
+
* field displays/accepts a human-readable string (e.g. `2 GiB`, `500M`, `2 TB`).
|
|
2485
|
+
* See `tn-input`'s `sizeStandard` / `sizeDefaultUnit` inputs to tune formatting
|
|
2486
|
+
* and bare-number parsing.
|
|
2487
|
+
*/
|
|
2488
|
+
InputType["Size"] = "size";
|
|
2481
2489
|
})(InputType || (InputType = {}));
|
|
2482
2490
|
|
|
2491
|
+
// Ordered binary/decimal prefixes; the array index doubles as the power applied
|
|
2492
|
+
// to the base (B = base^0, K = base^1, M = base^2, ...).
|
|
2493
|
+
const UNIT_PREFIXES = ['B', 'K', 'M', 'G', 'T', 'P', 'E'];
|
|
2494
|
+
/**
|
|
2495
|
+
* Formats a raw byte count into a human-readable string (e.g. `2 GiB`).
|
|
2496
|
+
*
|
|
2497
|
+
* Returns an empty string for `null`/`undefined`/empty/non-numeric input so the
|
|
2498
|
+
* field renders blank rather than `NaN`.
|
|
2499
|
+
*
|
|
2500
|
+
* @param bytes The byte count to format.
|
|
2501
|
+
* @param standard Unit standard (defaults to IEC base-2).
|
|
2502
|
+
* @param round Decimal places to round to (defaults to 2).
|
|
2503
|
+
*/
|
|
2504
|
+
function formatSize(bytes, standard = 'iec', round = 2) {
|
|
2505
|
+
if (bytes === null || bytes === undefined || bytes === '') {
|
|
2506
|
+
return '';
|
|
2507
|
+
}
|
|
2508
|
+
const num = Number(bytes);
|
|
2509
|
+
if (Number.isNaN(num)) {
|
|
2510
|
+
return '';
|
|
2511
|
+
}
|
|
2512
|
+
// `standard: 'iec'` implies base 2 and KiB-style symbols; `'si'` implies base
|
|
2513
|
+
// 10 and kB-style symbols. filesize derives the base from the standard.
|
|
2514
|
+
return filesize(num, { standard, round });
|
|
2515
|
+
}
|
|
2516
|
+
/**
|
|
2517
|
+
* Parses a human-readable size string into a raw byte count.
|
|
2518
|
+
*
|
|
2519
|
+
* Lenient by design: accepts IEC (`KiB`), short (`KB`), and human (`K`) unit
|
|
2520
|
+
* spellings, optional whitespace, and a bare number (which is interpreted using
|
|
2521
|
+
* `defaultUnit`). The chosen `standard` decides the multiplier — under `iec`,
|
|
2522
|
+
* `MB`/`M`/`MiB` are all treated as 1024-based; under `si` they are 1000-based.
|
|
2523
|
+
*
|
|
2524
|
+
* Returns `null` for empty, malformed, or unrecognized-unit input so callers can
|
|
2525
|
+
* map invalid entries to a null form-model value (never `0`).
|
|
2526
|
+
*
|
|
2527
|
+
* @param raw The human-readable string to parse.
|
|
2528
|
+
* @param defaultUnit Unit assumed when the input carries no unit (defaults to `MiB`).
|
|
2529
|
+
* @param standard Unit standard (defaults to IEC base-2).
|
|
2530
|
+
*/
|
|
2531
|
+
function parseSize(raw, defaultUnit = 'MiB', standard = 'iec') {
|
|
2532
|
+
if (raw === null || raw === undefined) {
|
|
2533
|
+
return null;
|
|
2534
|
+
}
|
|
2535
|
+
const str = String(raw).trim();
|
|
2536
|
+
if (str === '') {
|
|
2537
|
+
return null;
|
|
2538
|
+
}
|
|
2539
|
+
// Leading non-negative number (sizes are never negative), optional whitespace,
|
|
2540
|
+
// then an optional unit. Anything trailing the unit makes the whole match fail.
|
|
2541
|
+
const match = str.match(/^(\d+(?:\.\d+)?)\s*([a-zA-Z]*)$/);
|
|
2542
|
+
if (!match) {
|
|
2543
|
+
return null;
|
|
2544
|
+
}
|
|
2545
|
+
const num = parseFloat(match[1]);
|
|
2546
|
+
if (Number.isNaN(num)) {
|
|
2547
|
+
return null;
|
|
2548
|
+
}
|
|
2549
|
+
const exponent = unitExponent(match[2] || defaultUnit);
|
|
2550
|
+
if (exponent === null) {
|
|
2551
|
+
return null;
|
|
2552
|
+
}
|
|
2553
|
+
const base = standard === 'si' ? 1000 : 1024;
|
|
2554
|
+
// Round to whole bytes: a byte count is an integer, and rounding absorbs the
|
|
2555
|
+
// floating-point drift of e.g. 1.1 * 1024.
|
|
2556
|
+
return Math.round(num * base ** exponent);
|
|
2557
|
+
}
|
|
2558
|
+
/**
|
|
2559
|
+
* Resolves a unit spelling to its prefix power (B → 0, K → 1, M → 2, ...).
|
|
2560
|
+
*
|
|
2561
|
+
* Accepts the prefix alone (`K`), the short form (`KB`), or the IEC form (`KiB`),
|
|
2562
|
+
* case-insensitively. Returns `null` for anything unrecognized.
|
|
2563
|
+
*/
|
|
2564
|
+
function unitExponent(unit) {
|
|
2565
|
+
const normalized = unit.trim().toUpperCase();
|
|
2566
|
+
if (normalized === '') {
|
|
2567
|
+
return null;
|
|
2568
|
+
}
|
|
2569
|
+
if (normalized === 'B' || normalized === 'BYTE' || normalized === 'BYTES') {
|
|
2570
|
+
return 0;
|
|
2571
|
+
}
|
|
2572
|
+
const index = UNIT_PREFIXES.indexOf(normalized.charAt(0));
|
|
2573
|
+
// index 0 is 'B', already handled above; a leading 'B' here (e.g. "BB") is invalid.
|
|
2574
|
+
if (index <= 0) {
|
|
2575
|
+
return null;
|
|
2576
|
+
}
|
|
2577
|
+
// Allow the bare prefix ("K"), the short unit ("KB"), or the IEC unit ("KIB").
|
|
2578
|
+
const suffix = normalized.slice(1);
|
|
2579
|
+
if (suffix === '' || suffix === 'B' || suffix === 'IB') {
|
|
2580
|
+
return index;
|
|
2581
|
+
}
|
|
2582
|
+
return null;
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2483
2585
|
// Module-level counter for deterministic, unique instance ids (matches the
|
|
2484
2586
|
// tn-autocomplete convention). Deterministic ids are SSR/hydration-safe and
|
|
2485
2587
|
// stable across snapshots, unlike a Math.random() seed.
|
|
@@ -2511,6 +2613,24 @@ class TnInputComponent {
|
|
|
2511
2613
|
* (e.g. `Validators.min`/`max`), which work because the control emits real numbers.
|
|
2512
2614
|
*/
|
|
2513
2615
|
allowDecimals = input(true, ...(ngDevMode ? [{ debugName: "allowDecimals" }] : []));
|
|
2616
|
+
/**
|
|
2617
|
+
* Unit standard for the `Size` input type — `iec` (base-2, `KiB`/`MiB`) or
|
|
2618
|
+
* `si` (base-10, `kB`/`MB`). Drives both the formatted display and how bare
|
|
2619
|
+
* numbers are scaled when parsing. Ignored unless `inputType` is `Size`.
|
|
2620
|
+
*/
|
|
2621
|
+
sizeStandard = input('iec', ...(ngDevMode ? [{ debugName: "sizeStandard" }] : []));
|
|
2622
|
+
/**
|
|
2623
|
+
* Unit assumed when a user types a bare number (no unit) into a `Size` field —
|
|
2624
|
+
* e.g. with the default `MiB`, typing `200` yields 200 MiB. Accepts IEC
|
|
2625
|
+
* (`KiB`), short (`KB`), or human (`K`) spellings. Ignored unless `inputType`
|
|
2626
|
+
* is `Size`.
|
|
2627
|
+
*/
|
|
2628
|
+
sizeDefaultUnit = input('MiB', ...(ngDevMode ? [{ debugName: "sizeDefaultUnit" }] : []));
|
|
2629
|
+
/**
|
|
2630
|
+
* Decimal places used when formatting a `Size` field's value for display
|
|
2631
|
+
* (e.g. `1.5 GiB`). Ignored unless `inputType` is `Size`.
|
|
2632
|
+
*/
|
|
2633
|
+
sizeRound = input(2, ...(ngDevMode ? [{ debugName: "sizeRound" }] : []));
|
|
2514
2634
|
// Icon inputs
|
|
2515
2635
|
prefixIcon = input(undefined, ...(ngDevMode ? [{ debugName: "prefixIcon" }] : []));
|
|
2516
2636
|
prefixIconLibrary = input(undefined, ...(ngDevMode ? [{ debugName: "prefixIconLibrary" }] : []));
|
|
@@ -2522,19 +2642,21 @@ class TnInputComponent {
|
|
|
2522
2642
|
hasSuffixIcon = computed(() => !!this.suffixIcon(), ...(ngDevMode ? [{ debugName: "hasSuffixIcon" }] : []));
|
|
2523
2643
|
// Numeric mode state
|
|
2524
2644
|
isNumeric = computed(() => this.inputType() === InputType.Number, ...(ngDevMode ? [{ debugName: "isNumeric" }] : []));
|
|
2645
|
+
/** True when the field is in data-size mode (human-readable string ⇄ byte-count model). */
|
|
2646
|
+
isSize = computed(() => this.inputType() === InputType.Size, ...(ngDevMode ? [{ debugName: "isSize" }] : []));
|
|
2525
2647
|
/** True when the field only accepts whole numbers (i.e. `allowDecimals` is false). */
|
|
2526
2648
|
integerOnly = computed(() => !this.allowDecimals(), ...(ngDevMode ? [{ debugName: "integerOnly" }] : []));
|
|
2527
|
-
/** The `type` attribute actually rendered. Number
|
|
2528
|
-
resolvedType = computed(() => (this.isNumeric() ? InputType.PlainText : this.inputType()), ...(ngDevMode ? [{ debugName: "resolvedType" }] : []));
|
|
2529
|
-
/** `inputmode` hint: numeric keypad for integers, decimal keypad otherwise. Null (omitted)
|
|
2649
|
+
/** The `type` attribute actually rendered. Number and size modes use a text input: number avoids the native type="number" footguns, size must accept unit letters. */
|
|
2650
|
+
resolvedType = computed(() => (this.isNumeric() || this.isSize() ? InputType.PlainText : this.inputType()), ...(ngDevMode ? [{ debugName: "resolvedType" }] : []));
|
|
2651
|
+
/** `inputmode` hint: numeric keypad for integers, decimal keypad otherwise. Null (omitted) outside number mode — size fields accept unit letters, so they keep the full keyboard. */
|
|
2530
2652
|
numericInputMode = computed(() => {
|
|
2531
2653
|
if (!this.isNumeric()) {
|
|
2532
2654
|
return null;
|
|
2533
2655
|
}
|
|
2534
2656
|
return this.integerOnly() ? 'numeric' : 'decimal';
|
|
2535
2657
|
}, ...(ngDevMode ? [{ debugName: "numericInputMode" }] : []));
|
|
2536
|
-
/** Number
|
|
2537
|
-
showTextarea = computed(() => this.multiline() && !this.isNumeric(), ...(ngDevMode ? [{ debugName: "showTextarea" }] : []));
|
|
2658
|
+
/** Number and size modes are always single-line; they win over `multiline` if both are set. */
|
|
2659
|
+
showTextarea = computed(() => this.multiline() && !this.isNumeric() && !this.isSize(), ...(ngDevMode ? [{ debugName: "showTextarea" }] : []));
|
|
2538
2660
|
// Unique per instance: a hard-coded id produced duplicate ids when multiple
|
|
2539
2661
|
// tn-inputs share a page (invalid HTML, and it breaks any future label `for=`,
|
|
2540
2662
|
// aria-describedby, or getElementById targeting this input).
|
|
@@ -2567,6 +2689,12 @@ class TnInputComponent {
|
|
|
2567
2689
|
// Accepts undefined as well as the declared types: Angular may hand writeValue an
|
|
2568
2690
|
// undefined model at init, and it maps to the empty display like null.
|
|
2569
2691
|
writeValue(value) {
|
|
2692
|
+
if (this.isSize()) {
|
|
2693
|
+
// The model is a byte count; show it as a human-readable string. Empty/null
|
|
2694
|
+
// stays blank, and a non-numeric model maps to blank (formatSize returns '').
|
|
2695
|
+
this.value = formatSize(value, this.sizeStandard(), this.sizeRound());
|
|
2696
|
+
return;
|
|
2697
|
+
}
|
|
2570
2698
|
// Display the model verbatim via String(); do NOT sanitize here. Sanitizing a
|
|
2571
2699
|
// canonical number string would corrupt fractions in integer mode (3.5 -> "35"),
|
|
2572
2700
|
// silently diverging the display from the form model.
|
|
@@ -2587,6 +2715,13 @@ class TnInputComponent {
|
|
|
2587
2715
|
// Component methods (template-bound; protected — not part of the public API)
|
|
2588
2716
|
onValueChange(event) {
|
|
2589
2717
|
const target = event.target;
|
|
2718
|
+
if (this.isSize()) {
|
|
2719
|
+
// Keep the raw text in the field as the user types (unit letters and all);
|
|
2720
|
+
// emit the parsed byte count, mapping invalid/partial input to null (never 0).
|
|
2721
|
+
this.value = target.value;
|
|
2722
|
+
this.onChange(parseSize(this.value, this.sizeDefaultUnit(), this.sizeStandard()));
|
|
2723
|
+
return;
|
|
2724
|
+
}
|
|
2590
2725
|
if (this.isNumeric()) {
|
|
2591
2726
|
const el = target;
|
|
2592
2727
|
const sanitized = this.sanitizeNumeric(el.value);
|
|
@@ -2607,6 +2742,26 @@ class TnInputComponent {
|
|
|
2607
2742
|
this.onChange(this.value);
|
|
2608
2743
|
}
|
|
2609
2744
|
onBlur() {
|
|
2745
|
+
if (this.isSize() && this.value !== '') {
|
|
2746
|
+
// Canonicalize the display on blur: "2048 KiB" -> "2 MiB", "200tib" -> "200 TiB".
|
|
2747
|
+
// Leave unparseable text in place so the consumer's validators can flag it.
|
|
2748
|
+
const bytes = parseSize(this.value, this.sizeDefaultUnit(), this.sizeStandard());
|
|
2749
|
+
if (bytes !== null) {
|
|
2750
|
+
const canonical = formatSize(bytes, this.sizeStandard(), this.sizeRound());
|
|
2751
|
+
// Only rewrite + re-emit when the canonical form actually differs from what
|
|
2752
|
+
// the user left in the field. This both:
|
|
2753
|
+
// (a) skips a no-op onChange that would mark an untouched, pre-filled
|
|
2754
|
+
// control dirty (falsely tripping "unsaved changes" guards), and
|
|
2755
|
+
// (b) still re-syncs the model when rounding is lossy — e.g. an edited
|
|
2756
|
+
// "1.755 GiB" canonicalizes to a different string, so it emits the
|
|
2757
|
+
// byte count parsed back from the rounded display, keeping
|
|
2758
|
+
// parseSize(display) === model.
|
|
2759
|
+
if (canonical !== this.value) {
|
|
2760
|
+
this.value = canonical;
|
|
2761
|
+
this.onChange(parseSize(canonical, this.sizeDefaultUnit(), this.sizeStandard()));
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2610
2765
|
this.onTouched();
|
|
2611
2766
|
}
|
|
2612
2767
|
/** Strips any character that can't appear in the current numeric mode (single leading '-', single '.' for decimals). */
|
|
@@ -2637,7 +2792,7 @@ class TnInputComponent {
|
|
|
2637
2792
|
return Number.isNaN(parsed) ? null : parsed;
|
|
2638
2793
|
}
|
|
2639
2794
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2640
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnInputComponent, isStandalone: true, selector: "tn-input", inputs: { inputType: { classPropertyName: "inputType", publicName: "inputType", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, multiline: { classPropertyName: "multiline", publicName: "multiline", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, allowDecimals: { classPropertyName: "allowDecimals", publicName: "allowDecimals", isSignal: true, isRequired: false, transformFunction: null }, prefixIcon: { classPropertyName: "prefixIcon", publicName: "prefixIcon", isSignal: true, isRequired: false, transformFunction: null }, prefixIconLibrary: { classPropertyName: "prefixIconLibrary", publicName: "prefixIconLibrary", isSignal: true, isRequired: false, transformFunction: null }, suffixIcon: { classPropertyName: "suffixIcon", publicName: "suffixIcon", isSignal: true, isRequired: false, transformFunction: null }, suffixIconLibrary: { classPropertyName: "suffixIconLibrary", publicName: "suffixIconLibrary", isSignal: true, isRequired: false, transformFunction: null }, suffixIconAriaLabel: { classPropertyName: "suffixIconAriaLabel", publicName: "suffixIconAriaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSuffixAction: "onSuffixAction" }, providers: [
|
|
2795
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.0", type: TnInputComponent, isStandalone: true, selector: "tn-input", inputs: { inputType: { classPropertyName: "inputType", publicName: "inputType", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, multiline: { classPropertyName: "multiline", publicName: "multiline", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, allowDecimals: { classPropertyName: "allowDecimals", publicName: "allowDecimals", isSignal: true, isRequired: false, transformFunction: null }, sizeStandard: { classPropertyName: "sizeStandard", publicName: "sizeStandard", isSignal: true, isRequired: false, transformFunction: null }, sizeDefaultUnit: { classPropertyName: "sizeDefaultUnit", publicName: "sizeDefaultUnit", isSignal: true, isRequired: false, transformFunction: null }, sizeRound: { classPropertyName: "sizeRound", publicName: "sizeRound", isSignal: true, isRequired: false, transformFunction: null }, prefixIcon: { classPropertyName: "prefixIcon", publicName: "prefixIcon", isSignal: true, isRequired: false, transformFunction: null }, prefixIconLibrary: { classPropertyName: "prefixIconLibrary", publicName: "prefixIconLibrary", isSignal: true, isRequired: false, transformFunction: null }, suffixIcon: { classPropertyName: "suffixIcon", publicName: "suffixIcon", isSignal: true, isRequired: false, transformFunction: null }, suffixIconLibrary: { classPropertyName: "suffixIconLibrary", publicName: "suffixIconLibrary", isSignal: true, isRequired: false, transformFunction: null }, suffixIconAriaLabel: { classPropertyName: "suffixIconAriaLabel", publicName: "suffixIconAriaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSuffixAction: "onSuffixAction" }, providers: [
|
|
2641
2796
|
{
|
|
2642
2797
|
provide: NG_VALUE_ACCESSOR,
|
|
2643
2798
|
useExisting: forwardRef(() => TnInputComponent),
|
|
@@ -2654,7 +2809,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
|
|
|
2654
2809
|
multi: true
|
|
2655
2810
|
}
|
|
2656
2811
|
], template: "<div\n class=\"tn-input-container\"\n [class.tn-input-container--has-prefix]=\"hasPrefixIcon()\"\n [class.tn-input-container--has-suffix]=\"hasSuffixIcon()\"\n>\n <!-- Prefix icon -->\n @if (hasPrefixIcon()) {\n <tn-icon\n class=\"tn-input__prefix-icon\"\n size=\"sm\"\n aria-hidden=\"true\"\n [name]=\"prefixIcon()!\"\n [library]=\"prefixIconLibrary()\"\n />\n }\n\n <!-- Regular input field -->\n @if (!showTextarea()) {\n <input\n #inputEl\n class=\"tn-input\"\n tnTestIdType=\"input\"\n [id]=\"id\"\n [value]=\"value\"\n [type]=\"resolvedType()\"\n [attr.inputmode]=\"numericInputMode()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.placeholder]=\"placeholder()\"\n [tnTestId]=\"testId()\"\n [disabled]=\"isDisabled()\"\n (input)=\"onValueChange($event)\"\n (blur)=\"onBlur()\"\n />\n }\n\n <!-- Textarea field -->\n @if (showTextarea()) {\n <textarea\n #inputEl\n class=\"tn-input tn-textarea\"\n tnTestIdType=\"textarea\"\n [id]=\"id\"\n [value]=\"value\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.placeholder]=\"placeholder()\"\n [tnTestId]=\"testId()\"\n [rows]=\"rows()\"\n [disabled]=\"isDisabled()\"\n (input)=\"onValueChange($event)\"\n (blur)=\"onBlur()\"\n ></textarea>\n }\n\n <!-- Suffix icon action button -->\n @if (hasSuffixIcon()) {\n <button\n type=\"button\"\n class=\"tn-input__suffix-action\"\n [attr.aria-label]=\"suffixIconAriaLabel()\"\n [disabled]=\"isDisabled()\"\n (click)=\"onSuffixAction.emit($event)\"\n >\n <tn-icon\n size=\"sm\"\n [name]=\"suffixIcon()!\"\n [library]=\"suffixIconLibrary()\"\n />\n </button>\n }\n</div>\n", styles: [".tn-input-container{position:relative;display:flex;align-items:center;width:100%;font-family:var(--tn-font-family-body, \"Inter\"),sans-serif;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}.tn-input-container:focus-within{border-color:var(--tn-primary, #007bff);box-shadow:0 0 0 2px #007bff40}.tn-input-container:has(.tn-input:disabled){background-color:var(--tn-alt-bg1, #f8f9fa);opacity:.6;cursor:not-allowed}.tn-input-container:has(.tn-input.error){border-color:var(--tn-error, #dc3545)}.tn-input-container:has(.tn-input.error):focus-within{border-color:var(--tn-error, #dc3545);box-shadow:0 0 0 2px #dc354540}.tn-input{display:block;flex:1;min-width:0;min-height:2.5rem;padding:.5rem .75rem;font-size:1rem;line-height:1.5;color:var(--tn-fg1, #212529);background:transparent;border:none;border-radius:.375rem;outline:none;box-sizing:border-box}.tn-input::placeholder{color:var(--tn-alt-fg1, #999);opacity:1}.tn-input:disabled{color:var(--tn-fg2, #6c757d);cursor:not-allowed}.tn-input-container--has-prefix .tn-input{padding-left:.75rem;border-left:1px solid var(--tn-lines, #d1d5db);border-top-left-radius:0;border-bottom-left-radius:0}.tn-input-container--has-suffix .tn-input{padding-right:.25rem}.tn-input__prefix-icon{flex-shrink:0;margin-left:.75rem;margin-right:.75rem;color:var(--tn-fg2, #6c757d);pointer-events:none}.tn-input__suffix-action{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;margin-right:.375rem;padding:.25rem;border:none;border-radius:.25rem;background:transparent;color:var(--tn-fg2, #6c757d);cursor:pointer;transition:background-color .15s ease-in-out,color .15s ease-in-out}.tn-input__suffix-action:hover:not(:disabled){background-color:var(--tn-bg3, #f3f4f6);color:var(--tn-fg1, #1f2937)}.tn-input__suffix-action:focus-visible{outline:2px solid var(--tn-primary, #2563eb);outline-offset:1px}.tn-input__suffix-action:disabled{cursor:not-allowed;pointer-events:none}.tn-textarea{min-height:6rem;resize:vertical;line-height:1.4}@media(prefers-reduced-motion:reduce){.tn-input-container,.tn-input__suffix-action{transition:none}}@media(prefers-contrast:high){.tn-input-container{border-width:2px}}\n"] }]
|
|
2657
|
-
}], propDecorators: { inputEl: [{ type: i0.ViewChild, args: ['inputEl', { isSignal: true }] }], inputType: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputType", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], testId: [{ type: i0.Input, args: [{ isSignal: true, alias: "testId", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], multiline: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiline", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], allowDecimals: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowDecimals", required: false }] }], prefixIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefixIcon", required: false }] }], prefixIconLibrary: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefixIconLibrary", required: false }] }], suffixIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffixIcon", required: false }] }], suffixIconLibrary: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffixIconLibrary", required: false }] }], suffixIconAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffixIconAriaLabel", required: false }] }], onSuffixAction: [{ type: i0.Output, args: ["onSuffixAction"] }] } });
|
|
2812
|
+
}], propDecorators: { inputEl: [{ type: i0.ViewChild, args: ['inputEl', { isSignal: true }] }], inputType: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputType", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], testId: [{ type: i0.Input, args: [{ isSignal: true, alias: "testId", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], multiline: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiline", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], allowDecimals: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowDecimals", required: false }] }], sizeStandard: [{ type: i0.Input, args: [{ isSignal: true, alias: "sizeStandard", required: false }] }], sizeDefaultUnit: [{ type: i0.Input, args: [{ isSignal: true, alias: "sizeDefaultUnit", required: false }] }], sizeRound: [{ type: i0.Input, args: [{ isSignal: true, alias: "sizeRound", required: false }] }], prefixIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefixIcon", required: false }] }], prefixIconLibrary: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefixIconLibrary", required: false }] }], suffixIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffixIcon", required: false }] }], suffixIconLibrary: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffixIconLibrary", required: false }] }], suffixIconAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffixIconAriaLabel", required: false }] }], onSuffixAction: [{ type: i0.Output, args: ["onSuffixAction"] }] } });
|
|
2658
2813
|
|
|
2659
2814
|
/**
|
|
2660
2815
|
* Harness for interacting with tn-icon in tests.
|
|
@@ -2976,6 +3131,22 @@ class TnInputHarness extends ComponentHarness {
|
|
|
2976
3131
|
const parsed = integerMode ? parseInt(raw, 10) : parseFloat(raw);
|
|
2977
3132
|
return Number.isNaN(parsed) ? null : parsed;
|
|
2978
3133
|
}
|
|
3134
|
+
/**
|
|
3135
|
+
* Gets the displayed value of a `Size`-type input parsed into a byte count,
|
|
3136
|
+
* mirroring what the control emits to the form model.
|
|
3137
|
+
*
|
|
3138
|
+
* The harness reads only the DOM, so it can't see the component's configured
|
|
3139
|
+
* `sizeStandard`/`sizeDefaultUnit` — pass them here to match the field under
|
|
3140
|
+
* test. Defaults to IEC base-2 with a `MiB` default unit (the component
|
|
3141
|
+
* defaults). Empty/invalid input resolves to `null`.
|
|
3142
|
+
*
|
|
3143
|
+
* @param standard Unit standard the field uses (defaults to `'iec'`).
|
|
3144
|
+
* @param defaultUnit Unit assumed for bare numbers (defaults to `'MiB'`).
|
|
3145
|
+
* @returns Promise resolving to the byte count, or null.
|
|
3146
|
+
*/
|
|
3147
|
+
async getByteValue(standard = 'iec', defaultUnit = 'MiB') {
|
|
3148
|
+
return parseSize(await this.getValue(), defaultUnit, standard);
|
|
3149
|
+
}
|
|
2979
3150
|
/**
|
|
2980
3151
|
* Gets the `inputmode` attribute (e.g. 'numeric' or 'decimal' in number mode).
|
|
2981
3152
|
*
|
|
@@ -15177,5 +15348,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
|
|
|
15177
15348
|
* Generated bundle index. Do not edit.
|
|
15178
15349
|
*/
|
|
15179
15350
|
|
|
15180
|
-
export { CommonShortcuts, DEFAULT_THEME, DiskIconComponent, DiskType, FileSizePipe, InputType, LIGHT_THEME, LinuxModifierKeys, LinuxShortcuts, ModifierKeys, QuickShortcuts, ShortcutBuilder, StripMntPrefixPipe, THEME_MAP, THEME_STORAGE_KEY, TN_FORM_FIELD_ERRORS, TN_TABLE_PAGER_DEFAULT_LABELS, TN_TABLE_PAGER_LABELS, TN_TEST_ATTR, TN_THEME_DEFINITIONS, TnAutocompleteComponent, TnAutocompleteHarness, TnBannerActionDirective, TnBannerComponent, TnBannerHarness, TnBrandedSpinnerComponent, TnButtonComponent, TnButtonHarness, TnButtonToggleComponent, TnButtonToggleGroupComponent, TnButtonToggleGroupHarness, TnButtonToggleHarness, TnCalendarComponent, TnCalendarHeaderComponent, TnCardComponent, TnCardHeaderDirective, TnCellDefDirective, TnCheckboxComponent, TnCheckboxHarness, TnCheckboxLabelDirective, TnChipComponent, TnConfirmDialogComponent, TnDateInputComponent, TnDateInputHarness, TnDateRangeInputComponent, TnDateRangeInputHarness, TnDetailRowDefDirective, TnDialog, TnDialogHarness, TnDialogShellComponent, TnDialogTesting, TnDividerComponent, TnDividerDirective, TnDrawerComponent, TnDrawerContainerComponent, TnDrawerContainerHarness, TnDrawerContentComponent, TnDrawerHarness, TnEmptyComponent, TnEmptyHarness, TnExpansionPanelComponent, TnExpansionPanelHarness, TnFilePickerComponent, TnFilePickerPopupComponent, TnFormFieldComponent, TnFormFieldHarness, TnHeaderCellDefDirective, TnIconButtonComponent, TnIconButtonHarness, TnIconComponent, TnIconHarness, TnIconRegistryService, TnIconTesting, TnInputComponent, TnInputDirective, TnInputHarness, TnKeyboardShortcutComponent, TnKeyboardShortcutService, TnListAvatarDirective, TnListComponent, TnListIconDirective, TnListItemComponent, TnListItemLineDirective, TnListItemPrimaryDirective, TnListItemSecondaryDirective, TnListItemTitleDirective, TnListItemTrailingDirective, TnListOptionComponent, TnListSubheaderComponent, TnMenuActivateHoverDirective, TnMenuComponent, TnMenuHarness, TnMenuItemComponent, TnMenuTesting, TnMenuTriggerDirective, TnMonthViewComponent, TnMultiYearViewComponent, TnNestedTreeNodeComponent, TnParticleProgressBarComponent, TnProgressBarComponent, TnRadioComponent, TnRadioHarness, TnSelectComponent, TnSelectHarness, TnSelectionListComponent, TnSidePanelActionDirective, TnSidePanelComponent, TnSidePanelHarness, TnSidePanelHeaderActionDirective, TnSlideToggleComponent, TnSlideToggleHarness, TnSliderComponent, TnSliderThumbDirective, TnSliderWithLabelDirective, TnSpinnerComponent, TnSpriteLoaderService, TnStepComponent, TnStepperComponent, TnTabComponent, TnTabHarness, TnTabPanelComponent, TnTabPanelHarness, TnTableColumnDirective, TnTableComponent, TnTableHarness, TnTablePagerComponent, TnTablePagerHarness, TnTabsComponent, TnTabsHarness, TnTestIdDirective, TnTheme, TnThemeService, TnTimeInputComponent, TnToastComponent, TnToastMock, TnToastPosition, TnToastRef, TnToastService, TnToastTesting, TnToastType, TnTooltipComponent, TnTooltipDirective, TnTreeComponent, TnTreeFlatDataSource, TnTreeFlattener, TnTreeNodeComponent, TnTreeNodeOutletDirective, TruncatePathPipe, WindowsModifierKeys, WindowsShortcuts, composeTestId, createLucideLibrary, createShortcut, defaultSpriteBasePath, defaultSpriteConfigPath, kebabTestSegment, libIconMarker, registerLucideIcons, scopeTestId, setupLucideIntegration, tnIconMarker, writeTestId };
|
|
15351
|
+
export { CommonShortcuts, DEFAULT_THEME, DiskIconComponent, DiskType, FileSizePipe, InputType, LIGHT_THEME, LinuxModifierKeys, LinuxShortcuts, ModifierKeys, QuickShortcuts, ShortcutBuilder, StripMntPrefixPipe, THEME_MAP, THEME_STORAGE_KEY, TN_FORM_FIELD_ERRORS, TN_TABLE_PAGER_DEFAULT_LABELS, TN_TABLE_PAGER_LABELS, TN_TEST_ATTR, TN_THEME_DEFINITIONS, TnAutocompleteComponent, TnAutocompleteHarness, TnBannerActionDirective, TnBannerComponent, TnBannerHarness, TnBrandedSpinnerComponent, TnButtonComponent, TnButtonHarness, TnButtonToggleComponent, TnButtonToggleGroupComponent, TnButtonToggleGroupHarness, TnButtonToggleHarness, TnCalendarComponent, TnCalendarHeaderComponent, TnCardComponent, TnCardHeaderDirective, TnCellDefDirective, TnCheckboxComponent, TnCheckboxHarness, TnCheckboxLabelDirective, TnChipComponent, TnConfirmDialogComponent, TnDateInputComponent, TnDateInputHarness, TnDateRangeInputComponent, TnDateRangeInputHarness, TnDetailRowDefDirective, TnDialog, TnDialogHarness, TnDialogShellComponent, TnDialogTesting, TnDividerComponent, TnDividerDirective, TnDrawerComponent, TnDrawerContainerComponent, TnDrawerContainerHarness, TnDrawerContentComponent, TnDrawerHarness, TnEmptyComponent, TnEmptyHarness, TnExpansionPanelComponent, TnExpansionPanelHarness, TnFilePickerComponent, TnFilePickerPopupComponent, TnFormFieldComponent, TnFormFieldHarness, TnHeaderCellDefDirective, TnIconButtonComponent, TnIconButtonHarness, TnIconComponent, TnIconHarness, TnIconRegistryService, TnIconTesting, TnInputComponent, TnInputDirective, TnInputHarness, TnKeyboardShortcutComponent, TnKeyboardShortcutService, TnListAvatarDirective, TnListComponent, TnListIconDirective, TnListItemComponent, TnListItemLineDirective, TnListItemPrimaryDirective, TnListItemSecondaryDirective, TnListItemTitleDirective, TnListItemTrailingDirective, TnListOptionComponent, TnListSubheaderComponent, TnMenuActivateHoverDirective, TnMenuComponent, TnMenuHarness, TnMenuItemComponent, TnMenuTesting, TnMenuTriggerDirective, TnMonthViewComponent, TnMultiYearViewComponent, TnNestedTreeNodeComponent, TnParticleProgressBarComponent, TnProgressBarComponent, TnRadioComponent, TnRadioHarness, TnSelectComponent, TnSelectHarness, TnSelectionListComponent, TnSidePanelActionDirective, TnSidePanelComponent, TnSidePanelHarness, TnSidePanelHeaderActionDirective, TnSlideToggleComponent, TnSlideToggleHarness, TnSliderComponent, TnSliderThumbDirective, TnSliderWithLabelDirective, TnSpinnerComponent, TnSpriteLoaderService, TnStepComponent, TnStepperComponent, TnTabComponent, TnTabHarness, TnTabPanelComponent, TnTabPanelHarness, TnTableColumnDirective, TnTableComponent, TnTableHarness, TnTablePagerComponent, TnTablePagerHarness, TnTabsComponent, TnTabsHarness, TnTestIdDirective, TnTheme, TnThemeService, TnTimeInputComponent, TnToastComponent, TnToastMock, TnToastPosition, TnToastRef, TnToastService, TnToastTesting, TnToastType, TnTooltipComponent, TnTooltipDirective, TnTreeComponent, TnTreeFlatDataSource, TnTreeFlattener, TnTreeNodeComponent, TnTreeNodeOutletDirective, TruncatePathPipe, WindowsModifierKeys, WindowsShortcuts, composeTestId, createLucideLibrary, createShortcut, defaultSpriteBasePath, defaultSpriteConfigPath, formatSize, kebabTestSegment, libIconMarker, parseSize, registerLucideIcons, scopeTestId, setupLucideIntegration, tnIconMarker, writeTestId };
|
|
15181
15352
|
//# sourceMappingURL=truenas-ui-components.mjs.map
|