@truenas/ui-components 0.6.2 → 0.7.1
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,7 +1,7 @@
|
|
|
1
1
|
import { Overlay, OverlayPositionBuilder, OverlayModule } from '@angular/cdk/overlay';
|
|
2
2
|
import { TemplatePortal, ComponentPortal, PortalModule } from '@angular/cdk/portal';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { InjectionToken, inject, computed, isDevMode, effect, input, ViewEncapsulation, ChangeDetectionStrategy, Component, Injector, Renderer2, ElementRef, Directive,
|
|
4
|
+
import { InjectionToken, inject, computed, isSignal, isDevMode, effect, signal, input, ViewEncapsulation, ChangeDetectionStrategy, Component, Injector, Renderer2, ElementRef, Directive, ViewContainerRef, output, viewChild, untracked, forwardRef, DestroyRef, NgZone, afterNextRender, model, Injectable, contentChildren, Pipe, HostListener, linkedSignal, contentChild, TemplateRef, viewChildren, ChangeDetectorRef, afterEveryRender, IterableDiffers, booleanAttribute, LOCALE_ID, ApplicationRef, EnvironmentInjector, createComponent, PLATFORM_ID } from '@angular/core';
|
|
5
5
|
import * as i1$3 from '@angular/forms';
|
|
6
6
|
import { NgControl, NG_VALUE_ACCESSOR, FormsModule, Validators } from '@angular/forms';
|
|
7
7
|
import { ComponentHarness, HarnessPredicate, parallel, TestKey } from '@angular/cdk/testing';
|
|
@@ -73,18 +73,20 @@ function tnAccessibleName(config) {
|
|
|
73
73
|
// raises the warning rather than being treated as an answer.
|
|
74
74
|
const hasLabelledby = computed(() => (config.ariaLabelledby() ?? '').trim() !== '', ...(ngDevMode ? [{ debugName: "hasLabelledby" }] : []));
|
|
75
75
|
const named = computed(() => (config.ariaLabel() ?? '').trim() !== '' || hasLabelledby(), ...(ngDevMode ? [{ debugName: "named" }] : []));
|
|
76
|
+
const fallback = config.fallback;
|
|
77
|
+
const fallbackName = computed(() => (isSignal(fallback) ? fallback() : fallback), ...(ngDevMode ? [{ debugName: "fallbackName" }] : []));
|
|
76
78
|
const resolved = computed(() => {
|
|
77
79
|
const label = config.ariaLabel();
|
|
78
80
|
if ((label ?? '').trim() !== '') {
|
|
79
81
|
return label;
|
|
80
82
|
}
|
|
81
|
-
return hasLabelledby() ? null :
|
|
83
|
+
return hasLabelledby() ? null : fallbackName();
|
|
82
84
|
}, ...(ngDevMode ? [{ debugName: "resolved" }] : []));
|
|
83
|
-
if (isDevMode()) {
|
|
85
|
+
if (isDevMode() && !config.fallbackIsConfigured) {
|
|
84
86
|
effect(() => {
|
|
85
87
|
if (!named()) {
|
|
86
88
|
console.warn(`[${config.selector}] No ariaLabel or ariaLabelledby was set, so it falls back to `
|
|
87
|
-
+ `"${
|
|
89
|
+
+ `"${fallbackName()}". Assistive technology cannot say WHAT is ${config.activity} `
|
|
88
90
|
+ `— pass ariaLabel, or ariaLabelledby pointing at visible text.`
|
|
89
91
|
+ (config.hint ? ` ${config.hint}` : ''));
|
|
90
92
|
}
|
|
@@ -96,17 +98,175 @@ function tnAccessibleName(config) {
|
|
|
96
98
|
/**
|
|
97
99
|
* The accessible name a spinner falls back to when the caller names neither
|
|
98
100
|
* `ariaLabel` nor `ariaLabelledby` (#202). Same reasoning as
|
|
99
|
-
*
|
|
100
|
-
* defaults to indeterminate mode, so its unnamed default rendering
|
|
101
|
-
* assistive technology as a progressbar with neither a name nor a
|
|
101
|
+
* {@link TN_PROGRESS_BAR_DEFAULT_LABEL}, and the case is sharper here: the
|
|
102
|
+
* spinner defaults to indeterminate mode, so its unnamed default rendering
|
|
103
|
+
* reached assistive technology as a progressbar with neither a name nor a
|
|
104
|
+
* value.
|
|
102
105
|
*
|
|
103
|
-
* `branded-spinner.component.ts`
|
|
106
|
+
* `branded-spinner.component.ts` already fell back this way —
|
|
104
107
|
* `ariaLabel() || "Loading..."` inline — so a fallback is the shape this
|
|
105
108
|
* library had already settled on; what it lacked was the warning. It has both
|
|
106
|
-
* since #206, through the same `tnAccessibleName`
|
|
109
|
+
* since #206, through the same `tnAccessibleName` that component uses, which is
|
|
107
110
|
* why the two constants sit side by side and differ.
|
|
108
111
|
*/
|
|
109
112
|
const TN_SPINNER_DEFAULT_LABEL = 'Loading';
|
|
113
|
+
/**
|
|
114
|
+
* The name `tn-branded-spinner` falls back to when the caller names neither
|
|
115
|
+
* `ariaLabel` nor `ariaLabelledby`. Same reasoning as
|
|
116
|
+
* {@link TN_SPINNER_DEFAULT_LABEL} and {@link TN_PROGRESS_BAR_DEFAULT_LABEL}.
|
|
117
|
+
*
|
|
118
|
+
* It differs from `TN_SPINNER_DEFAULT_LABEL` — `"Loading..."` against
|
|
119
|
+
* `"Loading"` — only because this is the string the component already rendered,
|
|
120
|
+
* inline in its host binding, before #206 gave it the shared resolver. Aligning
|
|
121
|
+
* the two would change what a screen reader announces for every unnamed branded
|
|
122
|
+
* spinner already in the wild, which is a louder change than the consistency
|
|
123
|
+
* fix it would be part of. Exported so specs assert against it by name rather
|
|
124
|
+
* than by a copied string literal.
|
|
125
|
+
*/
|
|
126
|
+
const TN_BRANDED_SPINNER_DEFAULT_LABEL = 'Loading...';
|
|
127
|
+
/**
|
|
128
|
+
* The accessible name a bar falls back to when the caller names neither
|
|
129
|
+
* `ariaLabel` nor `ariaLabelledby` (#202).
|
|
130
|
+
*
|
|
131
|
+
* Deliberately generic, and deliberately not silent: the host carries
|
|
132
|
+
* `role="progressbar"` unconditionally, so without a fallback the default
|
|
133
|
+
* rendering is a progressbar assistive technology announces with no name at all
|
|
134
|
+
* — "progress bar, 40%", with nothing to say what is progressing. The
|
|
135
|
+
* alternative fix, withholding the role until there is a name for it, trades
|
|
136
|
+
* that for no announcement whatever, which is worse: a screen reader would not
|
|
137
|
+
* learn that anything is in progress, and on a determinate bar it would lose
|
|
138
|
+
* the value too.
|
|
139
|
+
*
|
|
140
|
+
* A generic name is still a poor one, so it is paired with the dev-mode warning
|
|
141
|
+
* `tnAccessibleName` raises. Exported so specs assert against it by name rather
|
|
142
|
+
* than by a copied string literal.
|
|
143
|
+
*/
|
|
144
|
+
const TN_PROGRESS_BAR_DEFAULT_LABEL = 'Progress';
|
|
145
|
+
/**
|
|
146
|
+
* The accessible name `tn-particle-progress-bar` falls back to when the caller
|
|
147
|
+
* names neither `ariaLabel` nor `ariaLabelledby` (#209).
|
|
148
|
+
*
|
|
149
|
+
* The same string and the same reasoning as
|
|
150
|
+
* {@link TN_PROGRESS_BAR_DEFAULT_LABEL} next door, and deliberately a separate
|
|
151
|
+
* constant rather than an alias of it: `tnAccessibleName` takes a fallback PER
|
|
152
|
+
* COMPONENT because the least-bad generic name differs by what the component is
|
|
153
|
+
* ("Progress" for a bar, "Loading" for a spinner), and sharing the binding would
|
|
154
|
+
* make a future divergence in one a silent change to the other. Exported so
|
|
155
|
+
* specs assert against it by name rather than by a copied string literal.
|
|
156
|
+
*/
|
|
157
|
+
const TN_PARTICLE_PROGRESS_BAR_DEFAULT_LABEL = 'Progress';
|
|
158
|
+
/**
|
|
159
|
+
* The accessible name a dialog falls back to when it renders no `title` and the
|
|
160
|
+
* caller named it through neither this component nor the `DialogConfig` (#219).
|
|
161
|
+
*
|
|
162
|
+
* `title` defaults to `''`, so the DEFAULT rendering of this component put an
|
|
163
|
+
* empty `<h2>` in the header and left the CDK container with no naming
|
|
164
|
+
* attribute at all — measured as `empty-heading` on the heading and
|
|
165
|
+
* `aria-dialog-name` on the dialog. A dialog with no name is announced as
|
|
166
|
+
* "dialog" and nothing else, which is the whole of what a screen-reader user is
|
|
167
|
+
* told about a surface that just took over the page and trapped their focus.
|
|
168
|
+
*
|
|
169
|
+
* "Dialog" is a poor name, and says almost exactly what the role already says.
|
|
170
|
+
* It is still better than the two alternatives: leaving the surface unnamed, or
|
|
171
|
+
* withholding `role="dialog"` until there is a name — the latter would move a
|
|
172
|
+
* listener into a focus trap with no announcement that anything had opened. So
|
|
173
|
+
* it is paired with the dev-mode warning `tnAccessibleName` raises, which is
|
|
174
|
+
* what keeps the fallback from becoming a quiet way to ship a nameless dialog.
|
|
175
|
+
*
|
|
176
|
+
* Exported so specs assert against it by name rather than by a copied literal.
|
|
177
|
+
*/
|
|
178
|
+
const TN_DIALOG_SHELL_DEFAULT_LABEL = 'Dialog';
|
|
179
|
+
/**
|
|
180
|
+
* The accessible name an open panel falls back to when it has no `title` and the
|
|
181
|
+
* caller named neither `ariaLabel` nor `ariaLabelledby` (#214).
|
|
182
|
+
*
|
|
183
|
+
* `title` defaults to `''`, so the DEFAULT rendering of this component was a
|
|
184
|
+
* `role="dialog"` with `aria-labelledby` pointing at an empty `<h2>` — measured
|
|
185
|
+
* as an `aria-dialog-name` violation, alongside `empty-heading`. A dialog with no
|
|
186
|
+
* name is announced as "dialog" and nothing else, which is the whole of what a
|
|
187
|
+
* screen-reader user gets told about a surface that just covered the page.
|
|
188
|
+
*
|
|
189
|
+
* Withholding `role="dialog"` until there is a name would be the other way to
|
|
190
|
+
* clear the rule, and it is worse: the panel traps focus either way, so a
|
|
191
|
+
* listener would be moved into a region with no announcement that anything had
|
|
192
|
+
* opened. A generic name is still a poor one, so it is paired with the dev-mode
|
|
193
|
+
* warning `tnAccessibleName` raises.
|
|
194
|
+
*
|
|
195
|
+
* Exported so specs assert against it by name rather than by a copied literal.
|
|
196
|
+
*/
|
|
197
|
+
const TN_SIDE_PANEL_DEFAULT_LABEL = 'Side panel';
|
|
198
|
+
/**
|
|
199
|
+
* The accessible name a drawer falls back to when the caller names neither
|
|
200
|
+
* `ariaLabel` nor `ariaLabelledby` (#214).
|
|
201
|
+
*
|
|
202
|
+
* `ariaLabel` defaults to `undefined`, so the DEFAULT rendering in `over` mode
|
|
203
|
+
* was a `role="dialog"` with `aria-modal="true"` and no name — measured as an
|
|
204
|
+
* `aria-dialog-name` violation. In `side` mode the same omission leaves a
|
|
205
|
+
* `role="navigation"` landmark unnamed, which axe does not report while there is
|
|
206
|
+
* only one of them on the page, and which stops telling them apart the moment
|
|
207
|
+
* there are two.
|
|
208
|
+
*
|
|
209
|
+
* One fallback for both modes rather than one per mode: the drawer is the same
|
|
210
|
+
* surface either way, the name answers the same question ("what is this?"), and
|
|
211
|
+
* a rule that changes with the mode is one more thing for a caller to be wrong
|
|
212
|
+
* about. A generic name is still a poor one, so it is paired with the dev-mode
|
|
213
|
+
* warning `tnAccessibleName` raises.
|
|
214
|
+
*
|
|
215
|
+
* Exported so specs assert against it by name rather than by a copied literal.
|
|
216
|
+
*/
|
|
217
|
+
const TN_DRAWER_DEFAULT_LABEL = 'Drawer';
|
|
218
|
+
/** English defaults used when no {@link TN_FALLBACK_LABELS} provider is registered. */
|
|
219
|
+
const TN_DEFAULT_FALLBACK_LABELS = {
|
|
220
|
+
spinner: TN_SPINNER_DEFAULT_LABEL,
|
|
221
|
+
brandedSpinner: TN_BRANDED_SPINNER_DEFAULT_LABEL,
|
|
222
|
+
progressBar: TN_PROGRESS_BAR_DEFAULT_LABEL,
|
|
223
|
+
particleProgressBar: TN_PARTICLE_PROGRESS_BAR_DEFAULT_LABEL,
|
|
224
|
+
dialog: TN_DIALOG_SHELL_DEFAULT_LABEL,
|
|
225
|
+
sidePanel: TN_SIDE_PANEL_DEFAULT_LABEL,
|
|
226
|
+
drawer: TN_DRAWER_DEFAULT_LABEL,
|
|
227
|
+
};
|
|
228
|
+
/**
|
|
229
|
+
* What the token resolves to when nobody provided it — a COPY of
|
|
230
|
+
* {@link TN_DEFAULT_FALLBACK_LABELS} rather than that object itself, and the
|
|
231
|
+
* difference is the whole of how `configured` below is decided.
|
|
232
|
+
*
|
|
233
|
+
* Comparing against the exported constant would make a consumer who provides it
|
|
234
|
+
* deliberately — `{ provide: TN_FALLBACK_LABELS, useValue: TN_DEFAULT_FALLBACK_LABELS }`,
|
|
235
|
+
* which is what a test environment mirroring an app's providers writes — read as
|
|
236
|
+
* nobody having provided anything. Held privately, this object is reachable only
|
|
237
|
+
* by not providing one, so identity answers exactly the question being asked.
|
|
238
|
+
*/
|
|
239
|
+
const builtInLabels = { ...TN_DEFAULT_FALLBACK_LABELS };
|
|
240
|
+
/**
|
|
241
|
+
* DI token for the app-wide fallback names above. Provide either a static
|
|
242
|
+
* object or a `Signal<TnFallbackLabels>` — the latter lets every component
|
|
243
|
+
* react to language changes when the consumer wires it up to an i18n service.
|
|
244
|
+
*
|
|
245
|
+
* An `ariaLabel` on a particular instance still wins over these, and is still
|
|
246
|
+
* what to reach for when a name can say what is loading or what is open.
|
|
247
|
+
*/
|
|
248
|
+
const TN_FALLBACK_LABELS = new InjectionToken('TN_FALLBACK_LABELS', { providedIn: 'root', factory: () => builtInLabels });
|
|
249
|
+
/**
|
|
250
|
+
* Reads one component's fallback name out of {@link TN_FALLBACK_LABELS}.
|
|
251
|
+
*
|
|
252
|
+
* Not `injectTnLabels`, which normalizes the token to a Signal and drops the
|
|
253
|
+
* value it started from: telling a configured bundle from the built-in one is an
|
|
254
|
+
* identity check against `builtInLabels`, so this needs the raw injected value.
|
|
255
|
+
* A consumer who provides a bundle equal to the defaults — the exported constant
|
|
256
|
+
* included — still counts as configured, which is the right way round: they said
|
|
257
|
+
* so on purpose.
|
|
258
|
+
*
|
|
259
|
+
* **Must be called from an injection context.**
|
|
260
|
+
*/
|
|
261
|
+
function injectTnFallbackName(key) {
|
|
262
|
+
const provided = inject(TN_FALLBACK_LABELS);
|
|
263
|
+
const labels = isSignal(provided) ? provided : signal(provided).asReadonly();
|
|
264
|
+
return {
|
|
265
|
+
label: computed(() => labels()[key]),
|
|
266
|
+
configured: provided !== builtInLabels,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
110
270
|
class TnSpinnerComponent {
|
|
111
271
|
mode = input('indeterminate', ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
112
272
|
value = input(0, ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
@@ -114,6 +274,7 @@ class TnSpinnerComponent {
|
|
|
114
274
|
strokeWidth = input(4, ...(ngDevMode ? [{ debugName: "strokeWidth" }] : []));
|
|
115
275
|
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
116
276
|
ariaLabelledby = input(null, ...(ngDevMode ? [{ debugName: "ariaLabelledby" }] : []));
|
|
277
|
+
fallbackName = injectTnFallbackName('spinner');
|
|
117
278
|
/**
|
|
118
279
|
* The name to render, or `null` to render no `aria-label` attribute — and the
|
|
119
280
|
* dev-mode warning when the caller named neither input.
|
|
@@ -127,7 +288,8 @@ class TnSpinnerComponent {
|
|
|
127
288
|
*/
|
|
128
289
|
resolvedAriaLabel = tnAccessibleName({
|
|
129
290
|
selector: 'tn-spinner',
|
|
130
|
-
fallback:
|
|
291
|
+
fallback: this.fallbackName.label,
|
|
292
|
+
fallbackIsConfigured: this.fallbackName.configured,
|
|
131
293
|
activity: 'loading',
|
|
132
294
|
ariaLabel: this.ariaLabel,
|
|
133
295
|
ariaLabelledby: this.ariaLabelledby
|
|
@@ -2126,26 +2288,6 @@ function tnScrollableRegion(region) {
|
|
|
2126
2288
|
return reachable.asReadonly();
|
|
2127
2289
|
}
|
|
2128
2290
|
|
|
2129
|
-
/**
|
|
2130
|
-
* The accessible name a drawer falls back to when the caller names neither
|
|
2131
|
-
* `ariaLabel` nor `ariaLabelledby` (#214).
|
|
2132
|
-
*
|
|
2133
|
-
* `ariaLabel` defaults to `undefined`, so the DEFAULT rendering in `over` mode
|
|
2134
|
-
* was a `role="dialog"` with `aria-modal="true"` and no name — measured as an
|
|
2135
|
-
* `aria-dialog-name` violation. In `side` mode the same omission leaves a
|
|
2136
|
-
* `role="navigation"` landmark unnamed, which axe does not report while there is
|
|
2137
|
-
* only one of them on the page, and which stops telling them apart the moment
|
|
2138
|
-
* there are two.
|
|
2139
|
-
*
|
|
2140
|
-
* One fallback for both modes rather than one per mode: the drawer is the same
|
|
2141
|
-
* surface either way, the name answers the same question ("what is this?"), and
|
|
2142
|
-
* a rule that changes with the mode is one more thing for a caller to be wrong
|
|
2143
|
-
* about. A generic name is still a poor one, so it is paired with the dev-mode
|
|
2144
|
-
* warning `tnAccessibleName` raises.
|
|
2145
|
-
*
|
|
2146
|
-
* Exported so specs assert against it by name rather than by a copied literal.
|
|
2147
|
-
*/
|
|
2148
|
-
const TN_DRAWER_DEFAULT_LABEL = 'Drawer';
|
|
2149
2291
|
/**
|
|
2150
2292
|
* A drawer, which is two different things by `mode`: in `side` it is
|
|
2151
2293
|
* persistent navigation beside the page's content, and in `over` it is a modal
|
|
@@ -2255,6 +2397,7 @@ class TnDrawerComponent {
|
|
|
2255
2397
|
trapFocus = computed(() => this.mode() === 'over' && this.opened(), ...(ngDevMode ? [{ debugName: "trapFocus" }] : []));
|
|
2256
2398
|
/** Role depends on mode: navigation for side, dialog for over */
|
|
2257
2399
|
panelRole = computed(() => this.mode() === 'over' ? 'dialog' : 'navigation', ...(ngDevMode ? [{ debugName: "panelRole" }] : []));
|
|
2400
|
+
fallbackName = injectTnFallbackName('drawer');
|
|
2258
2401
|
/**
|
|
2259
2402
|
* The name to render as `aria-label`, or `null` to render none — and the
|
|
2260
2403
|
* dev-mode warning when the caller named neither input.
|
|
@@ -2269,7 +2412,8 @@ class TnDrawerComponent {
|
|
|
2269
2412
|
*/
|
|
2270
2413
|
resolvedAriaLabel = tnAccessibleName({
|
|
2271
2414
|
selector: 'tn-drawer',
|
|
2272
|
-
fallback:
|
|
2415
|
+
fallback: this.fallbackName.label,
|
|
2416
|
+
fallbackIsConfigured: this.fallbackName.configured,
|
|
2273
2417
|
activity: 'open',
|
|
2274
2418
|
ariaLabel: computed(() => this.ariaLabel() ?? null),
|
|
2275
2419
|
ariaLabelledby: this.ariaLabelledby,
|
|
@@ -9634,6 +9778,12 @@ class TnRadioComponent {
|
|
|
9634
9778
|
name = input(undefined, ...(ngDevMode ? [{ debugName: "name" }] : []));
|
|
9635
9779
|
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
9636
9780
|
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : []));
|
|
9781
|
+
/**
|
|
9782
|
+
* Test-id base. The element type this composes with is `radio-button`, not `radio`: the id
|
|
9783
|
+
* identifies one radio BUTTON within a `radio-group`, matching the `radio-group`/`radio-button`
|
|
9784
|
+
* pair every other grouped control in this library uses (`button-toggle-group`/`button-toggle`).
|
|
9785
|
+
* So `testId="email"` yields `radio-button-email`.
|
|
9786
|
+
*/
|
|
9637
9787
|
testId = input(undefined, ...(ngDevMode ? [{ debugName: "testId" }] : []));
|
|
9638
9788
|
/** Test-id base, falling back to the bound control name when `testId` is unset. */
|
|
9639
9789
|
resolvedTestId = controlTestId(this.testId);
|
|
@@ -9747,7 +9897,7 @@ class TnRadioComponent {
|
|
|
9747
9897
|
useExisting: forwardRef(() => TnRadioComponent),
|
|
9748
9898
|
multi: true
|
|
9749
9899
|
}
|
|
9750
|
-
], viewQueries: [{ propertyName: "radioEl", first: true, predicate: ["radioEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [ngClass]=\"classes()\">\n <label class=\"tn-radio__label\" tnTestIdType=\"radio\" [for]=\"id\" [tnTestId]=\"resolvedTestId()\">\n <input\n #radioEl\n type=\"radio\"\n class=\"tn-radio__input\"\n [id]=\"id\"\n [name]=\"resolvedName()\"\n [value]=\"value()\"\n [checked]=\"checked()\"\n [disabled]=\"isDisabled()\"\n [required]=\"isRequired()\"\n [attr.aria-describedby]=\"error() ? id + '-error' : null\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n (change)=\"onRadioChange($event)\"\n />\n <span class=\"tn-radio__checkmark\"></span>\n <span class=\"tn-radio__text\" [innerHTML]=\"label() | tnLabelMarkup\"></span>\n </label>\n\n @if (error()) {\n <div\n class=\"tn-radio__error\"\n role=\"alert\"\n [id]=\"id + '-error'\"\n >\n {{ error() }}\n </div>\n }\n</div>", styles: [".tn-radio{display:inline-block;margin-bottom:.5rem}.tn-radio__label{display:flex;align-items:center;cursor:pointer;-webkit-user-select:none;user-select:none;gap:.5rem}.tn-radio__label:hover .tn-radio__checkmark{border-color:var(--tn-primary, #007cba)}.tn-radio__input{position:absolute;opacity:0;cursor:pointer;height:0;width:0}.tn-radio__input:focus+.tn-radio__checkmark{outline:2px solid var(--tn-primary, #007cba);outline-offset:2px}.tn-radio__input:checked+.tn-radio__checkmark{border-color:var(--tn-primary, #007cba);background-color:var(--tn-primary, #007cba)}.tn-radio__input:checked+.tn-radio__checkmark:after{display:block}.tn-radio__input:disabled+.tn-radio__checkmark{border-color:var(--tn-lines, #e5e7eb);background-color:var(--tn-alt-bg1, #f8f9fa);cursor:not-allowed}.tn-radio__checkmark{position:relative;height:18px;width:18px;border:2px solid var(--tn-lines, #e5e7eb);border-radius:50%;background-color:transparent;transition:all .2s ease;flex-shrink:0}.tn-radio__checkmark:after{content:\"\";position:absolute;display:none;top:50%;left:50%;width:8px;height:8px;border-radius:50%;background-color:#fff;transform:translate(-50%,-50%)}.tn-radio__text ::ng-deep code{font-family:var(--tn-font-family-monospace, monospace);font-size:.875em;background:var(--tn-bg2, #f5f5f5);border:1px solid var(--tn-lines, #ccc);border-radius:4px;padding:.125em .45em}.tn-radio__text{color:var(--tn-fg1, #000000);font-size:14px;line-height:1.4}.tn-radio__error{margin-top:.25rem;font-size:12px;color:var(--tn-error-text, var(--tn-red, #b91c1c))}.tn-radio--disabled .tn-radio__label{cursor:not-allowed;opacity:.6}.tn-radio--disabled .tn-radio__text{color:var(--tn-fg2, #6c757d)}.tn-radio--error .tn-radio__checkmark{border-color:var(--tn-red, #dc3545)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: TnTestIdDirective, selector: "[tnTestId]", inputs: ["tnTestId", "tnTestIdType"] }, { kind: "pipe", type: LabelMarkupPipe, name: "tnLabelMarkup" }] });
|
|
9900
|
+
], viewQueries: [{ propertyName: "radioEl", first: true, predicate: ["radioEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [ngClass]=\"classes()\">\n <label class=\"tn-radio__label\" tnTestIdType=\"radio-button\" [for]=\"id\" [tnTestId]=\"resolvedTestId()\">\n <input\n #radioEl\n type=\"radio\"\n class=\"tn-radio__input\"\n [id]=\"id\"\n [name]=\"resolvedName()\"\n [value]=\"value()\"\n [checked]=\"checked()\"\n [disabled]=\"isDisabled()\"\n [required]=\"isRequired()\"\n [attr.aria-describedby]=\"error() ? id + '-error' : null\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n (change)=\"onRadioChange($event)\"\n />\n <span class=\"tn-radio__checkmark\"></span>\n <span class=\"tn-radio__text\" [innerHTML]=\"label() | tnLabelMarkup\"></span>\n </label>\n\n @if (error()) {\n <div\n class=\"tn-radio__error\"\n role=\"alert\"\n [id]=\"id + '-error'\"\n >\n {{ error() }}\n </div>\n }\n</div>", styles: [".tn-radio{display:inline-block;margin-bottom:.5rem}.tn-radio__label{display:flex;align-items:center;cursor:pointer;-webkit-user-select:none;user-select:none;gap:.5rem}.tn-radio__label:hover .tn-radio__checkmark{border-color:var(--tn-primary, #007cba)}.tn-radio__input{position:absolute;opacity:0;cursor:pointer;height:0;width:0}.tn-radio__input:focus+.tn-radio__checkmark{outline:2px solid var(--tn-primary, #007cba);outline-offset:2px}.tn-radio__input:checked+.tn-radio__checkmark{border-color:var(--tn-primary, #007cba);background-color:var(--tn-primary, #007cba)}.tn-radio__input:checked+.tn-radio__checkmark:after{display:block}.tn-radio__input:disabled+.tn-radio__checkmark{border-color:var(--tn-lines, #e5e7eb);background-color:var(--tn-alt-bg1, #f8f9fa);cursor:not-allowed}.tn-radio__checkmark{position:relative;height:18px;width:18px;border:2px solid var(--tn-lines, #e5e7eb);border-radius:50%;background-color:transparent;transition:all .2s ease;flex-shrink:0}.tn-radio__checkmark:after{content:\"\";position:absolute;display:none;top:50%;left:50%;width:8px;height:8px;border-radius:50%;background-color:#fff;transform:translate(-50%,-50%)}.tn-radio__text ::ng-deep code{font-family:var(--tn-font-family-monospace, monospace);font-size:.875em;background:var(--tn-bg2, #f5f5f5);border:1px solid var(--tn-lines, #ccc);border-radius:4px;padding:.125em .45em}.tn-radio__text{color:var(--tn-fg1, #000000);font-size:14px;line-height:1.4}.tn-radio__error{margin-top:.25rem;font-size:12px;color:var(--tn-error-text, var(--tn-red, #b91c1c))}.tn-radio--disabled .tn-radio__label{cursor:not-allowed;opacity:.6}.tn-radio--disabled .tn-radio__text{color:var(--tn-fg2, #6c757d)}.tn-radio--error .tn-radio__checkmark{border-color:var(--tn-red, #dc3545)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: TnTestIdDirective, selector: "[tnTestId]", inputs: ["tnTestId", "tnTestIdType"] }, { kind: "pipe", type: LabelMarkupPipe, name: "tnLabelMarkup" }] });
|
|
9751
9901
|
}
|
|
9752
9902
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: TnRadioComponent, decorators: [{
|
|
9753
9903
|
type: Component,
|
|
@@ -9757,7 +9907,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
|
|
|
9757
9907
|
useExisting: forwardRef(() => TnRadioComponent),
|
|
9758
9908
|
multi: true
|
|
9759
9909
|
}
|
|
9760
|
-
], template: "<div [ngClass]=\"classes()\">\n <label class=\"tn-radio__label\" tnTestIdType=\"radio\" [for]=\"id\" [tnTestId]=\"resolvedTestId()\">\n <input\n #radioEl\n type=\"radio\"\n class=\"tn-radio__input\"\n [id]=\"id\"\n [name]=\"resolvedName()\"\n [value]=\"value()\"\n [checked]=\"checked()\"\n [disabled]=\"isDisabled()\"\n [required]=\"isRequired()\"\n [attr.aria-describedby]=\"error() ? id + '-error' : null\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n (change)=\"onRadioChange($event)\"\n />\n <span class=\"tn-radio__checkmark\"></span>\n <span class=\"tn-radio__text\" [innerHTML]=\"label() | tnLabelMarkup\"></span>\n </label>\n\n @if (error()) {\n <div\n class=\"tn-radio__error\"\n role=\"alert\"\n [id]=\"id + '-error'\"\n >\n {{ error() }}\n </div>\n }\n</div>", styles: [".tn-radio{display:inline-block;margin-bottom:.5rem}.tn-radio__label{display:flex;align-items:center;cursor:pointer;-webkit-user-select:none;user-select:none;gap:.5rem}.tn-radio__label:hover .tn-radio__checkmark{border-color:var(--tn-primary, #007cba)}.tn-radio__input{position:absolute;opacity:0;cursor:pointer;height:0;width:0}.tn-radio__input:focus+.tn-radio__checkmark{outline:2px solid var(--tn-primary, #007cba);outline-offset:2px}.tn-radio__input:checked+.tn-radio__checkmark{border-color:var(--tn-primary, #007cba);background-color:var(--tn-primary, #007cba)}.tn-radio__input:checked+.tn-radio__checkmark:after{display:block}.tn-radio__input:disabled+.tn-radio__checkmark{border-color:var(--tn-lines, #e5e7eb);background-color:var(--tn-alt-bg1, #f8f9fa);cursor:not-allowed}.tn-radio__checkmark{position:relative;height:18px;width:18px;border:2px solid var(--tn-lines, #e5e7eb);border-radius:50%;background-color:transparent;transition:all .2s ease;flex-shrink:0}.tn-radio__checkmark:after{content:\"\";position:absolute;display:none;top:50%;left:50%;width:8px;height:8px;border-radius:50%;background-color:#fff;transform:translate(-50%,-50%)}.tn-radio__text ::ng-deep code{font-family:var(--tn-font-family-monospace, monospace);font-size:.875em;background:var(--tn-bg2, #f5f5f5);border:1px solid var(--tn-lines, #ccc);border-radius:4px;padding:.125em .45em}.tn-radio__text{color:var(--tn-fg1, #000000);font-size:14px;line-height:1.4}.tn-radio__error{margin-top:.25rem;font-size:12px;color:var(--tn-error-text, var(--tn-red, #b91c1c))}.tn-radio--disabled .tn-radio__label{cursor:not-allowed;opacity:.6}.tn-radio--disabled .tn-radio__text{color:var(--tn-fg2, #6c757d)}.tn-radio--error .tn-radio__checkmark{border-color:var(--tn-red, #dc3545)}\n"] }]
|
|
9910
|
+
], template: "<div [ngClass]=\"classes()\">\n <label class=\"tn-radio__label\" tnTestIdType=\"radio-button\" [for]=\"id\" [tnTestId]=\"resolvedTestId()\">\n <input\n #radioEl\n type=\"radio\"\n class=\"tn-radio__input\"\n [id]=\"id\"\n [name]=\"resolvedName()\"\n [value]=\"value()\"\n [checked]=\"checked()\"\n [disabled]=\"isDisabled()\"\n [required]=\"isRequired()\"\n [attr.aria-describedby]=\"error() ? id + '-error' : null\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n (change)=\"onRadioChange($event)\"\n />\n <span class=\"tn-radio__checkmark\"></span>\n <span class=\"tn-radio__text\" [innerHTML]=\"label() | tnLabelMarkup\"></span>\n </label>\n\n @if (error()) {\n <div\n class=\"tn-radio__error\"\n role=\"alert\"\n [id]=\"id + '-error'\"\n >\n {{ error() }}\n </div>\n }\n</div>", styles: [".tn-radio{display:inline-block;margin-bottom:.5rem}.tn-radio__label{display:flex;align-items:center;cursor:pointer;-webkit-user-select:none;user-select:none;gap:.5rem}.tn-radio__label:hover .tn-radio__checkmark{border-color:var(--tn-primary, #007cba)}.tn-radio__input{position:absolute;opacity:0;cursor:pointer;height:0;width:0}.tn-radio__input:focus+.tn-radio__checkmark{outline:2px solid var(--tn-primary, #007cba);outline-offset:2px}.tn-radio__input:checked+.tn-radio__checkmark{border-color:var(--tn-primary, #007cba);background-color:var(--tn-primary, #007cba)}.tn-radio__input:checked+.tn-radio__checkmark:after{display:block}.tn-radio__input:disabled+.tn-radio__checkmark{border-color:var(--tn-lines, #e5e7eb);background-color:var(--tn-alt-bg1, #f8f9fa);cursor:not-allowed}.tn-radio__checkmark{position:relative;height:18px;width:18px;border:2px solid var(--tn-lines, #e5e7eb);border-radius:50%;background-color:transparent;transition:all .2s ease;flex-shrink:0}.tn-radio__checkmark:after{content:\"\";position:absolute;display:none;top:50%;left:50%;width:8px;height:8px;border-radius:50%;background-color:#fff;transform:translate(-50%,-50%)}.tn-radio__text ::ng-deep code{font-family:var(--tn-font-family-monospace, monospace);font-size:.875em;background:var(--tn-bg2, #f5f5f5);border:1px solid var(--tn-lines, #ccc);border-radius:4px;padding:.125em .45em}.tn-radio__text{color:var(--tn-fg1, #000000);font-size:14px;line-height:1.4}.tn-radio__error{margin-top:.25rem;font-size:12px;color:var(--tn-error-text, var(--tn-red, #b91c1c))}.tn-radio--disabled .tn-radio__label{cursor:not-allowed;opacity:.6}.tn-radio--disabled .tn-radio__text{color:var(--tn-fg2, #6c757d)}.tn-radio--error .tn-radio__checkmark{border-color:var(--tn-red, #dc3545)}\n"] }]
|
|
9761
9911
|
}], propDecorators: { radioEl: [{ type: i0.ViewChild, args: ['radioEl', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], testId: [{ type: i0.Input, args: [{ isSignal: true, alias: "testId", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], change: [{ type: i0.Output, args: ["change"] }] } });
|
|
9762
9912
|
|
|
9763
9913
|
/**
|
|
@@ -9955,7 +10105,7 @@ class TnRadioGroupComponent {
|
|
|
9955
10105
|
/**
|
|
9956
10106
|
* Test-id base for the group and, scoped by the option label, for every option rendered from
|
|
9957
10107
|
* `options`: base `encryption` yields `radio-group-encryption` on the group and
|
|
9958
|
-
* `radio-encryption-passphrase` on its options. Falls back to the bound control name.
|
|
10108
|
+
* `radio-button-encryption-passphrase` on its options. Falls back to the bound control name.
|
|
9959
10109
|
*
|
|
9960
10110
|
* Projected `<tn-radio>` children keep their own test-id resolution — the group does not reach
|
|
9961
10111
|
* into content it did not render — so give each one a `testId` of its own.
|
|
@@ -20135,23 +20285,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
|
|
|
20135
20285
|
}]
|
|
20136
20286
|
}] });
|
|
20137
20287
|
|
|
20138
|
-
/**
|
|
20139
|
-
* The name this spinner falls back to when the caller names neither `ariaLabel`
|
|
20140
|
-
* nor `ariaLabelledby`. Same reasoning as `TN_SPINNER_DEFAULT_LABEL` and
|
|
20141
|
-
* `TN_PROGRESS_BAR_DEFAULT_LABEL`.
|
|
20142
|
-
*
|
|
20143
|
-
* It differs from `TN_SPINNER_DEFAULT_LABEL` — `"Loading..."` against
|
|
20144
|
-
* `"Loading"` — only because this is the string the component already rendered,
|
|
20145
|
-
* inline in its host binding, before #206 gave it the shared resolver. Aligning
|
|
20146
|
-
* the two would change what a screen reader announces for every unnamed branded
|
|
20147
|
-
* spinner already in the wild, which is a louder change than the consistency
|
|
20148
|
-
* fix it would be part of. Exported so specs assert against it by name rather
|
|
20149
|
-
* than by a copied string literal.
|
|
20150
|
-
*/
|
|
20151
|
-
const TN_BRANDED_SPINNER_DEFAULT_LABEL = 'Loading...';
|
|
20152
20288
|
class TnBrandedSpinnerComponent {
|
|
20153
20289
|
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
20154
20290
|
ariaLabelledby = input(null, ...(ngDevMode ? [{ debugName: "ariaLabelledby" }] : []));
|
|
20291
|
+
fallbackName = injectTnFallbackName('brandedSpinner');
|
|
20155
20292
|
/**
|
|
20156
20293
|
* The name to render, or `null` to render no `aria-label` attribute — and the
|
|
20157
20294
|
* dev-mode warning when the caller named neither input.
|
|
@@ -20165,7 +20302,8 @@ class TnBrandedSpinnerComponent {
|
|
|
20165
20302
|
*/
|
|
20166
20303
|
resolvedAriaLabel = tnAccessibleName({
|
|
20167
20304
|
selector: 'tn-branded-spinner',
|
|
20168
|
-
fallback:
|
|
20305
|
+
fallback: this.fallbackName.label,
|
|
20306
|
+
fallbackIsConfigured: this.fallbackName.configured,
|
|
20169
20307
|
activity: 'loading',
|
|
20170
20308
|
ariaLabel: this.ariaLabel,
|
|
20171
20309
|
ariaLabelledby: this.ariaLabelledby
|
|
@@ -20278,30 +20416,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
|
|
|
20278
20416
|
}, template: "<div class=\"tn-branded-spinner-container\">\n <svg \n viewBox=\"0 -7 62 62\" \n preserveAspectRatio=\"xMidYMid meet\" \n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"tn-branded-spinner-logo\">\n \n <!-- EXPLODED LOGO PATHS -->\n <path class=\"exploded center\" fill=\"#AFADAE\" d=\"m41.79 24.13-11.26 6.51-11.28-6.51 11.28-6.51 11.26 6.51Z\" />\n <path class=\"exploded top-left\" fill=\"#35BEEB\" d=\"M27.86 0v13.01l-13.93 8.04-11.28-6.5L27.86 0Z\" />\n <path class=\"exploded bottom-right\" fill=\"#35BEEB\" d=\"M61.03 19.16v13.01L33.19 48.25V35.24l27.84-16.08Z\" />\n <path class=\"exploded bottom-left\" fill=\"#0A95D3\" d=\"M27.86 35.24v13L0 32.17v-13l12.59 7.26s.03.02.05.03l15.23 8.79-.01-.01Z\" />\n <path class=\"exploded top-right\" fill=\"#0A95D3\" d=\"m58.38 14.55-11.27 6.51-13.92-8.05V0l25.19 14.55Z\" />\n </svg>\n</div>", styles: [".tn-branded-spinner{display:inline-block;vertical-align:middle}.tn-branded-spinner-container{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100px;min-height:100px}.tn-branded-spinner-logo{width:100px;height:100px}.tn-branded-spinner-logo path.exploded{fill-opacity:0;stroke-width:1px;stroke:var(--tn-primary, #007bff)}.tn-branded-spinner-logo path#morph-target{fill-opacity:0;fill:var(--tn-primary, #007bff)}\n"] }]
|
|
20279
20417
|
}], propDecorators: { ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelledby", required: false }] }] } });
|
|
20280
20418
|
|
|
20281
|
-
/**
|
|
20282
|
-
* The accessible name a bar falls back to when the caller names neither
|
|
20283
|
-
* `ariaLabel` nor `ariaLabelledby` (#202).
|
|
20284
|
-
*
|
|
20285
|
-
* Deliberately generic, and deliberately not silent: the host carries
|
|
20286
|
-
* `role="progressbar"` unconditionally, so without a fallback the default
|
|
20287
|
-
* rendering is a progressbar assistive technology announces with no name at all
|
|
20288
|
-
* — "progress bar, 40%", with nothing to say what is progressing. The
|
|
20289
|
-
* alternative fix, withholding the role until there is a name for it, trades
|
|
20290
|
-
* that for no announcement whatever, which is worse: a screen reader would not
|
|
20291
|
-
* learn that anything is in progress, and on a determinate bar it would lose
|
|
20292
|
-
* the value too.
|
|
20293
|
-
*
|
|
20294
|
-
* A generic name is still a poor one, so it is paired with the dev-mode warning
|
|
20295
|
-
* `tnAccessibleName` raises. Exported so specs assert against it by name rather
|
|
20296
|
-
* than by a copied string literal.
|
|
20297
|
-
*/
|
|
20298
|
-
const TN_PROGRESS_BAR_DEFAULT_LABEL = 'Progress';
|
|
20299
20419
|
class TnProgressBarComponent {
|
|
20300
20420
|
mode = input('determinate', ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
20301
20421
|
value = input(0, ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
20302
20422
|
bufferValue = input(0, ...(ngDevMode ? [{ debugName: "bufferValue" }] : []));
|
|
20303
20423
|
ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
|
|
20304
20424
|
ariaLabelledby = input(null, ...(ngDevMode ? [{ debugName: "ariaLabelledby" }] : []));
|
|
20425
|
+
fallbackName = injectTnFallbackName('progressBar');
|
|
20305
20426
|
/**
|
|
20306
20427
|
* The name to render, or `null` to render no `aria-label` attribute — and the
|
|
20307
20428
|
* dev-mode warning when the caller named neither input.
|
|
@@ -20317,7 +20438,8 @@ class TnProgressBarComponent {
|
|
|
20317
20438
|
*/
|
|
20318
20439
|
resolvedAriaLabel = tnAccessibleName({
|
|
20319
20440
|
selector: 'tn-progress-bar',
|
|
20320
|
-
fallback:
|
|
20441
|
+
fallback: this.fallbackName.label,
|
|
20442
|
+
fallbackIsConfigured: this.fallbackName.configured,
|
|
20321
20443
|
activity: 'progressing',
|
|
20322
20444
|
ariaLabel: this.ariaLabel,
|
|
20323
20445
|
ariaLabelledby: this.ariaLabelledby
|
|
@@ -20376,19 +20498,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
|
|
|
20376
20498
|
}, template: "<!-- Background/buffer layer -->\n<div class=\"tn-progress-bar-buffer\" aria-hidden=\"true\">\n <!-- Buffer bar hidden in new implementation -->\n <!-- Buffer dots for buffer mode -->\n @if (mode() === 'buffer') {\n <div class=\"tn-progress-bar-buffer-dots\"\n [style.width]=\"bufferStyles().width\"\n [style.right]=\"bufferStyles().right\"></div>\n }\n</div>\n\n<!-- Primary bar -->\n<div class=\"tn-progress-bar-bar tn-progress-bar-primary-bar\" aria-hidden=\"true\">\n <span class=\"tn-progress-bar-bar-inner\"\n [style.transform]=\"primaryTransform()\"></span>\n</div>\n\n<!-- Secondary bar (for indeterminate mode) -->\n@if (mode() === 'indeterminate') {\n <div class=\"tn-progress-bar-bar tn-progress-bar-secondary-bar\" aria-hidden=\"true\">\n <span class=\"tn-progress-bar-bar-inner\"></span>\n </div>\n}\n\n", styles: [":host{display:block;height:4px;overflow:hidden;position:relative;transition:opacity .25s linear;width:100%}.tn-progress-bar-buffer{position:absolute;top:0;bottom:0;width:100%;background-color:var(--tn-bg2, #e5e7eb)}.tn-progress-bar-buffer-bar{display:none}.tn-progress-bar-buffer-dots{position:absolute;top:0;bottom:0;width:100%;background-image:radial-gradient(circle at center,var(--tn-alt-bg2) 2px,transparent 2px);background-size:10px 4px;background-repeat:repeat-x;animation:tn-progress-bar-buffer-dots .25s infinite linear}@keyframes tn-progress-bar-buffer-dots{0%{background-position-x:0}to{background-position-x:-10px}}.tn-progress-bar-bar{position:absolute;top:0;bottom:0;left:0;width:100%;transform-origin:left center}.tn-progress-bar-bar-inner{display:block;position:absolute;top:0;bottom:0;left:0;width:100%;background-color:var(--tn-primary, #3b82f6);transform-origin:left center;height:100%}.tn-progress-bar-primary-bar{z-index:1}.tn-progress-bar-secondary-bar{z-index:0;display:none}.tn-progress-bar-secondary-bar .tn-progress-bar-bar-inner{background-color:var(--tn-primary, #3b82f6)}:host(.tn-progress-bar-indeterminate) .tn-progress-bar-primary-bar .tn-progress-bar-bar-inner{animation:tn-progress-bar-indeterminate 2s infinite linear;background-color:var(--tn-primary, #3b82f6);opacity:1!important;z-index:999!important}@keyframes tn-progress-bar-indeterminate{0%{transform:translate(-100%) scaleX(.3)}to{transform:translate(100%) scaleX(.3)}}:host(.tn-progress-bar-buffer) .tn-progress-bar-buffer-bar{opacity:1}:host(.tn-progress-bar-buffer) .tn-progress-bar-buffer-dots{opacity:1}:host(.tn-progress-bar-determinate) .tn-progress-bar-buffer-dots{display:none}:host(.tn-progress-bar-determinate) .tn-progress-bar-secondary-bar{display:none}:host(.tn-progress-bar-buffer) .tn-progress-bar-secondary-bar{display:none}:host(.tn-progress-bar-indeterminate) .tn-progress-bar-buffer-dots{display:none}:host(.tn-progress-bar-indeterminate) .tn-progress-bar-buffer-bar{display:none}\n"] }]
|
|
20377
20499
|
}], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], bufferValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "bufferValue", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelledby", required: false }] }] } });
|
|
20378
20500
|
|
|
20379
|
-
/**
|
|
20380
|
-
* The accessible name this bar falls back to when the caller names neither
|
|
20381
|
-
* `ariaLabel` nor `ariaLabelledby` (#209).
|
|
20382
|
-
*
|
|
20383
|
-
* The same string and the same reasoning as `TN_PROGRESS_BAR_DEFAULT_LABEL`
|
|
20384
|
-
* next door, and deliberately a separate constant rather than an import of it:
|
|
20385
|
-
* `tnAccessibleName` takes a fallback PER COMPONENT because the least-bad
|
|
20386
|
-
* generic name differs by what the component is ("Progress" for a bar,
|
|
20387
|
-
* "Loading" for a spinner), and sharing the binding would make a future
|
|
20388
|
-
* divergence in one a silent change to the other. Exported so specs assert
|
|
20389
|
-
* against it by name rather than by a copied string literal.
|
|
20390
|
-
*/
|
|
20391
|
-
const TN_PARTICLE_PROGRESS_BAR_DEFAULT_LABEL = 'Progress';
|
|
20392
20501
|
/**
|
|
20393
20502
|
* The gap in px between the edge of the SVG and each end of the track, on both
|
|
20394
20503
|
* sides — the `x` the two rects are drawn at, and half of what is subtracted
|
|
@@ -20460,6 +20569,7 @@ class TnParticleProgressBarComponent {
|
|
|
20460
20569
|
canvasRef = viewChild.required('canvas');
|
|
20461
20570
|
/** Exposed to the template so the rects and the ARIA value share one inset. */
|
|
20462
20571
|
trackInset = TRACK_INSET;
|
|
20572
|
+
fallbackName = injectTnFallbackName('particleProgressBar');
|
|
20463
20573
|
/**
|
|
20464
20574
|
* The name to render, or `null` to render no `aria-label` at all — and the
|
|
20465
20575
|
* dev-mode warning when the caller named neither input.
|
|
@@ -20477,7 +20587,8 @@ class TnParticleProgressBarComponent {
|
|
|
20477
20587
|
*/
|
|
20478
20588
|
resolvedAriaLabel = tnAccessibleName({
|
|
20479
20589
|
selector: 'tn-particle-progress-bar',
|
|
20480
|
-
fallback:
|
|
20590
|
+
fallback: this.fallbackName.label,
|
|
20591
|
+
fallbackIsConfigured: this.fallbackName.configured,
|
|
20481
20592
|
activity: 'progressing',
|
|
20482
20593
|
ariaLabel: this.ariaLabel,
|
|
20483
20594
|
ariaLabelledby: this.ariaLabelledby
|
|
@@ -24400,27 +24511,6 @@ const TN_DIALOG_DEFAULT_CHROME_LABELS = {
|
|
|
24400
24511
|
*/
|
|
24401
24512
|
const TN_DIALOG_CHROME_LABELS = new InjectionToken('TN_DIALOG_CHROME_LABELS', { providedIn: 'root', factory: () => TN_DIALOG_DEFAULT_CHROME_LABELS });
|
|
24402
24513
|
let nextUniqueId = 0;
|
|
24403
|
-
/**
|
|
24404
|
-
* The accessible name a dialog falls back to when it renders no `title` and the
|
|
24405
|
-
* caller named it through neither this component nor the `DialogConfig` (#219).
|
|
24406
|
-
*
|
|
24407
|
-
* `title` defaults to `''`, so the DEFAULT rendering of this component put an
|
|
24408
|
-
* empty `<h2>` in the header and left the CDK container with no naming
|
|
24409
|
-
* attribute at all — measured as `empty-heading` on the heading and
|
|
24410
|
-
* `aria-dialog-name` on the dialog. A dialog with no name is announced as
|
|
24411
|
-
* "dialog" and nothing else, which is the whole of what a screen-reader user is
|
|
24412
|
-
* told about a surface that just took over the page and trapped their focus.
|
|
24413
|
-
*
|
|
24414
|
-
* "Dialog" is a poor name, and says almost exactly what the role already says.
|
|
24415
|
-
* It is still better than the two alternatives: leaving the surface unnamed, or
|
|
24416
|
-
* withholding `role="dialog"` until there is a name — the latter would move a
|
|
24417
|
-
* listener into a focus trap with no announcement that anything had opened. So
|
|
24418
|
-
* it is paired with the dev-mode warning `tnAccessibleName` raises, which is
|
|
24419
|
-
* what keeps the fallback from becoming a quiet way to ship a nameless dialog.
|
|
24420
|
-
*
|
|
24421
|
-
* Exported so specs assert against it by name rather than by a copied literal.
|
|
24422
|
-
*/
|
|
24423
|
-
const TN_DIALOG_SHELL_DEFAULT_LABEL = 'Dialog';
|
|
24424
24514
|
/**
|
|
24425
24515
|
* The first value that is a name, or `null` if none of them is one.
|
|
24426
24516
|
*
|
|
@@ -24538,6 +24628,7 @@ class TnDialogShellComponent {
|
|
|
24538
24628
|
resolvedAriaLabelledby = computed(() => (this.hasTitle() ? this.titleId : firstNonBlank(this.ariaLabelledby(), this.ref.config?.ariaLabelledBy)), ...(ngDevMode ? [{ debugName: "resolvedAriaLabelledby" }] : []));
|
|
24539
24629
|
/** An explicit label, from this component's input or from the `DialogConfig`. */
|
|
24540
24630
|
explicitAriaLabel = computed(() => firstNonBlank(this.ariaLabel(), this.ref.config?.ariaLabel), ...(ngDevMode ? [{ debugName: "explicitAriaLabel" }] : []));
|
|
24631
|
+
fallbackName = injectTnFallbackName('dialog');
|
|
24541
24632
|
/**
|
|
24542
24633
|
* The name to render as `aria-label`, or `null` to render none — and the
|
|
24543
24634
|
* dev-mode warning when the dialog has no name from any route.
|
|
@@ -24549,7 +24640,8 @@ class TnDialogShellComponent {
|
|
|
24549
24640
|
*/
|
|
24550
24641
|
resolvedAriaLabel = tnAccessibleName({
|
|
24551
24642
|
selector: 'tn-dialog-shell',
|
|
24552
|
-
fallback:
|
|
24643
|
+
fallback: this.fallbackName.label,
|
|
24644
|
+
fallbackIsConfigured: this.fallbackName.configured,
|
|
24553
24645
|
activity: 'open',
|
|
24554
24646
|
hint: 'On this component the usual route is title, which is also the visible heading.',
|
|
24555
24647
|
ariaLabel: this.explicitAriaLabel,
|
|
@@ -24971,25 +25063,6 @@ class TnDialogTesting {
|
|
|
24971
25063
|
}
|
|
24972
25064
|
}
|
|
24973
25065
|
|
|
24974
|
-
/**
|
|
24975
|
-
* The accessible name an open panel falls back to when it has no `title` and the
|
|
24976
|
-
* caller named neither `ariaLabel` nor `ariaLabelledby` (#214).
|
|
24977
|
-
*
|
|
24978
|
-
* `title` defaults to `''`, so the DEFAULT rendering of this component was a
|
|
24979
|
-
* `role="dialog"` with `aria-labelledby` pointing at an empty `<h2>` — measured
|
|
24980
|
-
* as an `aria-dialog-name` violation, alongside `empty-heading`. A dialog with no
|
|
24981
|
-
* name is announced as "dialog" and nothing else, which is the whole of what a
|
|
24982
|
-
* screen-reader user gets told about a surface that just covered the page.
|
|
24983
|
-
*
|
|
24984
|
-
* Withholding `role="dialog"` until there is a name would be the other way to
|
|
24985
|
-
* clear the rule, and it is worse: the panel traps focus either way, so a
|
|
24986
|
-
* listener would be moved into a region with no announcement that anything had
|
|
24987
|
-
* opened. A generic name is still a poor one, so it is paired with the dev-mode
|
|
24988
|
-
* warning `tnAccessibleName` raises.
|
|
24989
|
-
*
|
|
24990
|
-
* Exported so specs assert against it by name rather than by a copied literal.
|
|
24991
|
-
*/
|
|
24992
|
-
const TN_SIDE_PANEL_DEFAULT_LABEL = 'Side panel';
|
|
24993
25066
|
/**
|
|
24994
25067
|
* The name given to the scrolling content region once it becomes focusable
|
|
24995
25068
|
* (#248).
|
|
@@ -25196,6 +25269,7 @@ class TnSidePanelComponent {
|
|
|
25196
25269
|
* when there is one, the caller's IDREF otherwise.
|
|
25197
25270
|
*/
|
|
25198
25271
|
resolvedAriaLabelledby = computed(() => (this.hasTitle() ? this.titleId : this.ariaLabelledby()), ...(ngDevMode ? [{ debugName: "resolvedAriaLabelledby" }] : []));
|
|
25272
|
+
fallbackName = injectTnFallbackName('sidePanel');
|
|
25199
25273
|
/**
|
|
25200
25274
|
* The name to render as `aria-label`, or `null` to render none — and the
|
|
25201
25275
|
* dev-mode warning when the panel has no name from any route.
|
|
@@ -25207,7 +25281,8 @@ class TnSidePanelComponent {
|
|
|
25207
25281
|
*/
|
|
25208
25282
|
resolvedAriaLabel = tnAccessibleName({
|
|
25209
25283
|
selector: 'tn-side-panel',
|
|
25210
|
-
fallback:
|
|
25284
|
+
fallback: this.fallbackName.label,
|
|
25285
|
+
fallbackIsConfigured: this.fallbackName.configured,
|
|
25211
25286
|
activity: 'open',
|
|
25212
25287
|
hint: 'On this component the usual route is title, which is also the visible heading.',
|
|
25213
25288
|
ariaLabel: this.ariaLabel,
|
|
@@ -28144,5 +28219,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
|
|
|
28144
28219
|
* Generated bundle index. Do not edit.
|
|
28145
28220
|
*/
|
|
28146
28221
|
|
|
28147
|
-
export { CommonShortcuts, DEFAULT_THEME, DiskIconComponent, DiskType, FileSizePipe, InputType, LIGHT_THEME, LabelMarkupPipe, LabelTextPipe, LinuxModifierKeys, LinuxShortcuts, ModifierKeys, QuickShortcuts, ShortcutBuilder, THEME_MAP, THEME_STORAGE_KEY, TN_AUTOCOMPLETE_DEFAULT_LABELS, TN_AUTOCOMPLETE_LABELS, TN_BRANDED_SPINNER_DEFAULT_LABEL, TN_CALENDAR_INTL, TN_CALENDAR_INTL_DEFAULTS, TN_DIALOG_CHROME_LABELS, TN_DIALOG_DEFAULT_CHROME_LABELS, TN_DIALOG_SHELL_DEFAULT_LABEL, TN_DRAWER_CONTENT_LABEL, TN_DRAWER_DEFAULT_LABEL, TN_FORM_FIELD_CONTEXT, TN_FORM_FIELD_DISMISSIBLE_ERRORS, TN_FORM_FIELD_ERRORS, TN_FORM_LIST_CONTEXT, TN_PARTICLE_PROGRESS_BAR_DEFAULT_LABEL, TN_PROGRESS_BAR_DEFAULT_LABEL, TN_RADIO_GROUP, TN_SELECT_DEFAULT_LABELS, TN_SELECT_LABELS, TN_SIDE_PANEL_CONTENT_LABEL, TN_SIDE_PANEL_DEFAULT_LABEL, TN_SIDE_PANEL_OVERFLOW_TOLERANCE_PX, TN_SPINNER_DEFAULT_LABEL, TN_STEPPER_STATUS_COMPLETED, TN_STEPPER_STATUS_ERROR, TN_TABLE_DEFAULT_LABELS, TN_TABLE_LABELS, TN_TABLE_PAGER_DEFAULT_LABELS, TN_TABLE_PAGER_LABELS, TN_TABLE_SCROLL_REGION_LABEL, TN_TAB_PANEL_CONTENT_LABEL, TN_TEST_ATTR, TN_THEME_DEFINITIONS, TN_TOAST_ANNOUNCE_DELAY_MS, TnAutocompleteComponent, TnAutocompleteHarness, TnBannerActionDirective, TnBannerActionHarness, TnBannerComponent, TnBannerHarness, TnBrandedSpinnerComponent, TnButtonComponent, TnButtonHarness, TnButtonToggleComponent, TnButtonToggleGroupComponent, TnButtonToggleGroupHarness, TnButtonToggleHarness, TnCalendarCellHarness, TnCalendarComponent, TnCalendarHarness, 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, TnFilePickerHarness, TnFilePickerPopupComponent, TnFormErrorsComponent, TnFormErrorsHarness, TnFormFieldComponent, TnFormFieldHarness, TnFormListComponent, TnFormListHarness, TnFormListItemComponent, TnFormListItemHarness, 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, TnNestedTreeDataSource, TnNestedTreeNodeComponent, TnParticleProgressBarComponent, TnProgressBarComponent, TnRadioComponent, TnRadioGroupComponent, TnRadioGroupHarness, TnRadioHarness, TnRowActionsDefDirective, TnSelectComponent, TnSelectHarness, TnSelectionListComponent, TnSidePanelActionDirective, TnSidePanelComponent, TnSidePanelHarness, TnSidePanelHeaderActionDirective, TnSlideToggleComponent, TnSlideToggleHarness, TnSliderComponent, TnSliderThumbDirective, TnSliderWithLabelDirective, TnSpinnerComponent, TnSpriteLoaderService, TnStepComponent, TnStepperComponent, TnStepperHarness, TnStepperNextDirective, TnStepperPreviousDirective, TnTabComponent, TnTabHarness, TnTabPanelComponent, TnTabPanelHarness, TnTableColumnDirective, TnTableComponent, TnTableHarness, TnTablePagerComponent, TnTablePagerHarness, TnTableTesting, TnTabsComponent, TnTabsHarness, TnTestIdDirective, TnTheme, TnThemeService, TnTimeInputComponent, TnToastComponent, TnToastMock, TnToastPosition, TnToastRef, TnToastService, TnToastTesting, TnToastType, TnTooltipComponent, TnTooltipDirective, TnTooltipHarness, TnTooltipTesting, TnTreeComponent, TnTreeFlatDataSource, TnTreeFlattener, TnTreeHarness, TnTreeNodeComponent, TnTreeNodeHarness, TnTreeNodeOutletDirective, TnTreeVirtualScrollNodeOutletDirective, TnTreeVirtualScrollViewComponent, TnTreeVirtualScrollViewHarness, TruncatePathPipe, WindowsModifierKeys, WindowsShortcuts, allowsCurrentDirectorySelection, canonicalizeSize, composeTestId, controlTestId, createFlatTreeControl, createLucideLibrary, createNestedTreeControl, createShortcut, defaultSpriteBasePath, defaultSpriteConfigPath, defaultTreeItemSize, formatSize, formatSizeExact, formatSizeForEditing, getSelectableTypes, injectTnCalendarIntl, injectTnFormFieldAria, injectTnLabels, isPathWithinRoot, kebabTestSegment, labelMarkupToHtml, labelMarkupToText, libIconMarker, normalizeRootPath, optionTestId, parseLabelMarkup, parseSize, parseSizeParts, registerLucideIcons, resolveErrorMessage, scopeTestId, setupLucideIntegration, tnIconMarker, writeTestId };
|
|
28222
|
+
export { CommonShortcuts, DEFAULT_THEME, DiskIconComponent, DiskType, FileSizePipe, InputType, LIGHT_THEME, LabelMarkupPipe, LabelTextPipe, LinuxModifierKeys, LinuxShortcuts, ModifierKeys, QuickShortcuts, ShortcutBuilder, THEME_MAP, THEME_STORAGE_KEY, TN_AUTOCOMPLETE_DEFAULT_LABELS, TN_AUTOCOMPLETE_LABELS, TN_BRANDED_SPINNER_DEFAULT_LABEL, TN_CALENDAR_INTL, TN_CALENDAR_INTL_DEFAULTS, TN_DEFAULT_FALLBACK_LABELS, TN_DIALOG_CHROME_LABELS, TN_DIALOG_DEFAULT_CHROME_LABELS, TN_DIALOG_SHELL_DEFAULT_LABEL, TN_DRAWER_CONTENT_LABEL, TN_DRAWER_DEFAULT_LABEL, TN_FALLBACK_LABELS, TN_FORM_FIELD_CONTEXT, TN_FORM_FIELD_DISMISSIBLE_ERRORS, TN_FORM_FIELD_ERRORS, TN_FORM_LIST_CONTEXT, TN_PARTICLE_PROGRESS_BAR_DEFAULT_LABEL, TN_PROGRESS_BAR_DEFAULT_LABEL, TN_RADIO_GROUP, TN_SELECT_DEFAULT_LABELS, TN_SELECT_LABELS, TN_SIDE_PANEL_CONTENT_LABEL, TN_SIDE_PANEL_DEFAULT_LABEL, TN_SIDE_PANEL_OVERFLOW_TOLERANCE_PX, TN_SPINNER_DEFAULT_LABEL, TN_STEPPER_STATUS_COMPLETED, TN_STEPPER_STATUS_ERROR, TN_TABLE_DEFAULT_LABELS, TN_TABLE_LABELS, TN_TABLE_PAGER_DEFAULT_LABELS, TN_TABLE_PAGER_LABELS, TN_TABLE_SCROLL_REGION_LABEL, TN_TAB_PANEL_CONTENT_LABEL, TN_TEST_ATTR, TN_THEME_DEFINITIONS, TN_TOAST_ANNOUNCE_DELAY_MS, TnAutocompleteComponent, TnAutocompleteHarness, TnBannerActionDirective, TnBannerActionHarness, TnBannerComponent, TnBannerHarness, TnBrandedSpinnerComponent, TnButtonComponent, TnButtonHarness, TnButtonToggleComponent, TnButtonToggleGroupComponent, TnButtonToggleGroupHarness, TnButtonToggleHarness, TnCalendarCellHarness, TnCalendarComponent, TnCalendarHarness, 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, TnFilePickerHarness, TnFilePickerPopupComponent, TnFormErrorsComponent, TnFormErrorsHarness, TnFormFieldComponent, TnFormFieldHarness, TnFormListComponent, TnFormListHarness, TnFormListItemComponent, TnFormListItemHarness, 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, TnNestedTreeDataSource, TnNestedTreeNodeComponent, TnParticleProgressBarComponent, TnProgressBarComponent, TnRadioComponent, TnRadioGroupComponent, TnRadioGroupHarness, TnRadioHarness, TnRowActionsDefDirective, TnSelectComponent, TnSelectHarness, TnSelectionListComponent, TnSidePanelActionDirective, TnSidePanelComponent, TnSidePanelHarness, TnSidePanelHeaderActionDirective, TnSlideToggleComponent, TnSlideToggleHarness, TnSliderComponent, TnSliderThumbDirective, TnSliderWithLabelDirective, TnSpinnerComponent, TnSpriteLoaderService, TnStepComponent, TnStepperComponent, TnStepperHarness, TnStepperNextDirective, TnStepperPreviousDirective, TnTabComponent, TnTabHarness, TnTabPanelComponent, TnTabPanelHarness, TnTableColumnDirective, TnTableComponent, TnTableHarness, TnTablePagerComponent, TnTablePagerHarness, TnTableTesting, TnTabsComponent, TnTabsHarness, TnTestIdDirective, TnTheme, TnThemeService, TnTimeInputComponent, TnToastComponent, TnToastMock, TnToastPosition, TnToastRef, TnToastService, TnToastTesting, TnToastType, TnTooltipComponent, TnTooltipDirective, TnTooltipHarness, TnTooltipTesting, TnTreeComponent, TnTreeFlatDataSource, TnTreeFlattener, TnTreeHarness, TnTreeNodeComponent, TnTreeNodeHarness, TnTreeNodeOutletDirective, TnTreeVirtualScrollNodeOutletDirective, TnTreeVirtualScrollViewComponent, TnTreeVirtualScrollViewHarness, TruncatePathPipe, WindowsModifierKeys, WindowsShortcuts, allowsCurrentDirectorySelection, canonicalizeSize, composeTestId, controlTestId, createFlatTreeControl, createLucideLibrary, createNestedTreeControl, createShortcut, defaultSpriteBasePath, defaultSpriteConfigPath, defaultTreeItemSize, formatSize, formatSizeExact, formatSizeForEditing, getSelectableTypes, injectTnCalendarIntl, injectTnFallbackName, injectTnFormFieldAria, injectTnLabels, isPathWithinRoot, kebabTestSegment, labelMarkupToHtml, labelMarkupToText, libIconMarker, normalizeRootPath, optionTestId, parseLabelMarkup, parseSize, parseSizeParts, registerLucideIcons, resolveErrorMessage, scopeTestId, setupLucideIntegration, tnIconMarker, writeTestId };
|
|
28148
28223
|
//# sourceMappingURL=truenas-ui-components.mjs.map
|