@ethlete/components 1.0.0-next.68 → 1.0.0-next.69

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.
@@ -7,7 +7,7 @@ import { DomSanitizer } from '@angular/platform-browser';
7
7
  import { queryStateSignal, isQueryStateLoading, withArgs, createQueryErrorResponse, isQueryStateSuccess, isQueryStateFailure, executeUntilSettled$, extractQuery, createPagedQueryStack, queryComputed, isLegacyQuery, parseHttpErrorCodeToMessageEn, parseHttpErrorCodeToTitleEn, parseHttpErrorCodeToMessageDe, parseHttpErrorCodeToTitleDe, queryErrorMessages } from '@ethlete/query';
8
8
  import { DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE, COMMON_BRACKET_ROUND_TYPE, BracketRuntimeError, BRACKET_ERROR_CODES, SWISS_BRACKET_ROUND_TYPE, SINGLE_ELIMINATION_BRACKET_ROUND_TYPE, TOURNAMENT_MODE, BRACKET_DATA_LAYOUT, resolveBracketLayout as resolveBracketLayout$1, createBracket, createPlaceholderBracketSource, drawMan, createDoubleEliminationGrid, ɵcreateStackedDoubleEliminationGrid as _createStackedDoubleEliminationGrid, createSingleEliminationGrid, generateBracketRoundSwissGroupMaps, createSwissGrid, drawSwissMan, standingPickStartOrder } from '@ethlete/bracket';
9
9
  export { BRACKET_DATA_LAYOUT, BRACKET_ERROR_CODES, BRACKET_ROUND_MIRROR_TYPE, BRACKET_SWISS_GROUP_COLOR_TYPE, BracketMap, BracketRuntimeError, COMMON_BRACKET_ROUND_TYPE, DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE, GROUP_BRACKET_ROUND_TYPE, SINGLE_ELIMINATION_BRACKET_ROUND_TYPE, SWISS_BRACKET_ROUND_TYPE, TOURNAMENT_MODE, bracketSlot, createBracket, createPlaceholderBracketSource, isBracketSlotPredictable, migrateBracketPicks, resolveBracketSlot, standingRankSides, swapStandingRank, validateBracketSource } from '@ethlete/bracket';
10
- import { isValid, format, startOfWeek, startOfDay, endOfWeek, isBefore, addDays, endOfMonth, startOfMonth, isSameYear, isSameMonth, isSameDay, startOfYear, isAfter, addYears, addMonths, setMonth, getDate, setDate, lastDayOfMonth, getWeek, endOfYear, setYear, parse, setSeconds, setMinutes, setHours, subDays, subWeeks, subMonths, setMilliseconds, differenceInCalendarDays, endOfDay, getDaysInMonth, eachDayOfInterval, addHours } from 'date-fns';
10
+ import { isValid, format, startOfWeek, startOfDay, endOfWeek, isBefore, addDays, endOfMonth, startOfMonth, isSameYear, isSameMonth, isSameDay, startOfYear, isAfter, addYears, addMonths, setMonth, getDate, setDate, lastDayOfMonth, getWeek, endOfYear, setYear, parse, setSeconds, setMinutes, setHours, subDays, subWeeks, subMonths, endOfDay, setMilliseconds, differenceInCalendarDays, getDaysInMonth, eachDayOfInterval, addHours } from 'date-fns';
11
11
  import { tap, Subject, take, filter, defer, map, finalize, timer, takeUntil, fromEvent, switchMap, observeOn, asapScheduler, combineLatest, distinctUntilChanged, EMPTY, startWith, debounceTime, merge, catchError, of, delay, isObservable, from, share, scan, concat, firstValueFrom, defaultIfEmpty, Subscription, Observable, interval, ignoreElements, skip, animationFrameScheduler, EmptyError, exhaustMap, shareReplay, throwError, expand, toArray, takeWhile, mergeMap } from 'rxjs';
12
12
  import { takeUntilDestroyed, toSignal, toObservable, outputFromObservable, outputToObservable, rxResource } from '@angular/core/rxjs-interop';
13
13
  import * as i1$1 from '@angular/router';
@@ -16,6 +16,7 @@ import { createMetadataKey, metadata, FORM_FIELD, validate, createManagedMetadat
16
16
  import { tz, TZDate } from '@date-fns/tz';
17
17
  import { enUS } from 'date-fns/locale/en-US';
18
18
  import { tap as tap$1 } from 'rxjs/operators';
19
+ import { HttpEventType } from '@angular/common/http';
19
20
 
20
21
  // codes 3600-3699
21
22
  const ACCORDION_ERROR_CODES = {
@@ -7361,6 +7362,7 @@ const createOverlayRef = (config) => {
7361
7362
  .pipe(take(1), tap((rawEvent) => {
7362
7363
  const event = withDismissResult(rawEvent);
7363
7364
  busyAttributeEffect.destroy();
7365
+ afterOpened$.complete();
7364
7366
  afterClosed$.next(event.result);
7365
7367
  afterClosed$.complete();
7366
7368
  afterClosedEvent$.next(event);
@@ -7403,6 +7405,10 @@ const createOverlayRef = (config) => {
7403
7405
  _componentInstanceOverride = getter;
7404
7406
  },
7405
7407
  closeVia: (source, result) => _runtimeRef?.close(result, source),
7408
+ isClosing: () => {
7409
+ const state = _runtimeRef?.state();
7410
+ return state === 'closing' || state === 'closed';
7411
+ },
7406
7412
  registerHeaderTemplate: (template) => {
7407
7413
  _headerTemplates.update((templates) => [...templates.filter((t) => t !== template), template]);
7408
7414
  return () => _headerTemplates.update((templates) => templates.filter((t) => t !== template));
@@ -11278,7 +11284,7 @@ const OVERLAY_SCROLL_BLOCKER_DEF = /* @__PURE__ */ defineRootProvider(() => {
11278
11284
  }
11279
11285
  return documents;
11280
11286
  }, { ...(ngDevMode ? { debugName: "blockedDocuments" } : /* istanbul ignore next */ {}), equal: (a, b) => a.size === b.size && [...a].every((entry) => b.has(entry)) });
11281
- const savedTops = new Map();
11287
+ const savedOffsets = new Map();
11282
11288
  const canScrollVertically = (target, mainDocumentCanScroll) => {
11283
11289
  if (target === document)
11284
11290
  return mainDocumentCanScroll;
@@ -11287,20 +11293,21 @@ const OVERLAY_SCROLL_BLOCKER_DEF = /* @__PURE__ */ defineRootProvider(() => {
11287
11293
  };
11288
11294
  const lock = (target) => {
11289
11295
  const top = target.defaultView?.scrollY ?? 0;
11290
- savedTops.set(target, top);
11296
+ const left = target.defaultView?.scrollX ?? 0;
11297
+ savedOffsets.set(target, { top, left });
11291
11298
  renderer.setStyle(target.documentElement, {
11292
11299
  position: 'fixed',
11293
11300
  top: `-${top}px`,
11294
- left: '0',
11295
- right: '0',
11301
+ left: `${-left}px`,
11302
+ right: `${left}px`,
11296
11303
  overflowY: 'scroll',
11297
11304
  });
11298
11305
  };
11299
11306
  const unlock = (target) => {
11300
- const top = savedTops.get(target);
11301
- if (top === undefined)
11307
+ const offsets = savedOffsets.get(target);
11308
+ if (!offsets)
11302
11309
  return;
11303
- savedTops.delete(target);
11310
+ savedOffsets.delete(target);
11304
11311
  const root = target.documentElement;
11305
11312
  renderer.setStyle(root, {
11306
11313
  position: null,
@@ -11310,18 +11317,18 @@ const OVERLAY_SCROLL_BLOCKER_DEF = /* @__PURE__ */ defineRootProvider(() => {
11310
11317
  overflowY: null,
11311
11318
  scrollBehavior: 'auto',
11312
11319
  });
11313
- target.defaultView?.scrollTo(0, top);
11320
+ target.defaultView?.scrollTo(offsets.left, offsets.top);
11314
11321
  renderer.setStyle(root, { scrollBehavior: null });
11315
11322
  };
11316
- inject(DestroyRef).onDestroy(() => [...savedTops.keys()].forEach(unlock));
11323
+ inject(DestroyRef).onDestroy(() => [...savedOffsets.keys()].forEach(unlock));
11317
11324
  combineLatest([toObservable(blockedDocuments), toObservable(documentScrollState)])
11318
11325
  .pipe(tap(([blocked, scrollState]) => {
11319
- for (const target of [...savedTops.keys()]) {
11326
+ for (const target of [...savedOffsets.keys()]) {
11320
11327
  if (!blocked.has(target))
11321
11328
  unlock(target);
11322
11329
  }
11323
11330
  for (const target of blocked) {
11324
- if (!savedTops.has(target) && canScrollVertically(target, scrollState.canScrollVertically)) {
11331
+ if (!savedOffsets.has(target) && canScrollVertically(target, scrollState.canScrollVertically)) {
11325
11332
  lock(target);
11326
11333
  }
11327
11334
  }
@@ -13715,7 +13722,7 @@ class CalendarDirective {
13715
13722
  const locale = this.effectiveLocale();
13716
13723
  const labelOptions = locale ? { locale } : undefined;
13717
13724
  const weekStartsOn = this.effectiveFirstDayOfWeek();
13718
- const firstWeekContainsDate = locale?.options?.firstWeekContainsDate ?? 1;
13725
+ const firstWeekContainsDate = locale ? (locale.options?.firstWeekContainsDate ?? 1) : 4;
13719
13726
  const readSelection = this.selectionReader('month');
13720
13727
  return Array.from({ length: this.monthsShown() }, (_, offset) => {
13721
13728
  const month = addMonths(firstMonth, offset);
@@ -16228,6 +16235,17 @@ const useCarouselLoop = (config) => {
16228
16235
  };
16229
16236
 
16230
16237
  const SCROLL_IDLE_DURATION = 140;
16238
+ const SCROLL_KEYS = /* @__PURE__ */ new Set([
16239
+ 'ArrowLeft',
16240
+ 'ArrowRight',
16241
+ 'ArrowUp',
16242
+ 'ArrowDown',
16243
+ 'PageUp',
16244
+ 'PageDown',
16245
+ 'Home',
16246
+ 'End',
16247
+ ' ',
16248
+ ]);
16231
16249
  /** In its own function so the `in` check doesn't narrow the element away for everything after it. */
16232
16250
  const supportsScrollEnd = (element) => 'onscrollend' in element;
16233
16251
  /**
@@ -16272,6 +16290,9 @@ const useCarouselScrollSettled = (config) => {
16272
16290
  return merge(settled$.pipe(tap(() => settle())), fromEvent(scrollContainer, 'pointerdown', { passive: true }).pipe(tap(() => {
16273
16291
  isPointerDown.set(true);
16274
16292
  config.onPointerDown?.();
16293
+ })), fromEvent(scrollContainer, 'wheel', { passive: true }).pipe(tap(() => config.onScrollInput?.())), fromEvent(scrollContainer, 'keydown').pipe(tap((event) => {
16294
+ if (SCROLL_KEYS.has(event.key))
16295
+ config.onScrollInput?.();
16275
16296
  })),
16276
16297
  // on the document, because a drag that starts on the track routinely ends off it
16277
16298
  fromEvent(document, 'pointerup', { passive: true }).pipe(tap(release)), fromEvent(document, 'pointercancel', { passive: true }).pipe(tap(release)));
@@ -16583,6 +16604,7 @@ class CarouselDirective {
16583
16604
  */
16584
16605
  this.requestedDomIndex = signal(null, /* @ts-ignore */
16585
16606
  ...(ngDevMode ? [{ debugName: "requestedDomIndex" }] : /* istanbul ignore next */ []));
16607
+ this.readSettled = null;
16586
16608
  /** @internal Which child the intersections say is in view - the truth, a frame or two late. */
16587
16609
  this.observedDomIndex = computed(() => {
16588
16610
  const scrollable = this.scrollable();
@@ -16677,7 +16699,9 @@ class CarouselDirective {
16677
16699
  slideProgress.flush();
16678
16700
  },
16679
16701
  onPointerDown: () => this.requestedDomIndex.set(null),
16702
+ onScrollInput: () => this.requestedDomIndex.set(null),
16680
16703
  });
16704
+ this.readSettled = loop.readSettled;
16681
16705
  let agreedIndex = null;
16682
16706
  effect(() => {
16683
16707
  const current = this.currentIndex();
@@ -16779,6 +16803,12 @@ class CarouselDirective {
16779
16803
  const scrollable = this.scrollable();
16780
16804
  if (!scrollable || domIndex < 0 || domIndex >= this.domCount())
16781
16805
  return;
16806
+ // The track does not scroll to where it already rests, so no settle would ever clear this request.
16807
+ if (this.requestedDomIndex() === null &&
16808
+ domIndex === this.observedDomIndex() &&
16809
+ this.readSettled?.()?.restsOn(domIndex)) {
16810
+ return;
16811
+ }
16782
16812
  const from = this.activeDomIndex();
16783
16813
  const origin = this.scrollOriginOf(scrollable);
16784
16814
  const distance = from < 0 ? 0 : domIndex - from;
@@ -21825,7 +21855,8 @@ class CommandPaletteShortcutDirective {
21825
21855
  toggle() {
21826
21856
  const openPalette = this.overlayManager
21827
21857
  .openOverlays()
21828
- .find((overlayRef) => overlayRef.componentInstance() instanceof CommandPaletteComponent);
21858
+ .find((overlayRef) => overlayRef.componentInstance() instanceof CommandPaletteComponent &&
21859
+ !getOverlayRefInternals(overlayRef)?.isClosing());
21829
21860
  if (openPalette) {
21830
21861
  openPalette.close();
21831
21862
  return;
@@ -24099,12 +24130,15 @@ class TextFieldControlDirective extends TextShellControlDirective {
24099
24130
  }
24100
24131
  /** @internal For a directive placed on the native element itself - a wrapper component binds these in its template. */
24101
24132
  mirrorOntoNativeHost(element, state) {
24102
- effect(() => {
24103
- const value = state.value();
24104
- if (!state.skip?.() && element.value !== value) {
24105
- this.nativeHostRenderer.setProperty(element, 'value', value);
24106
- }
24107
- });
24133
+ const readValue = state.value;
24134
+ if (readValue) {
24135
+ effect(() => {
24136
+ const value = readValue();
24137
+ if (!state.skip?.() && element.value !== value) {
24138
+ this.nativeHostRenderer.setProperty(element, 'value', value);
24139
+ }
24140
+ });
24141
+ }
24108
24142
  const type = state.type;
24109
24143
  if (type) {
24110
24144
  effect(() => this.nativeHostRenderer.setProperty(element, 'type', type()));
@@ -24224,6 +24258,7 @@ const toChildrenObservable$1 = (result) => toObservableResult(result);
24224
24258
  const toSearchObservable = (result) => toObservableResult(result);
24225
24259
  /** Normalizes a `resolvePath` result (array | null | Promise | Observable) into an Observable. */
24226
24260
  const toPathObservable = (result) => toObservableResult(result);
24261
+ const isPathDisabled = (path) => path.some((node) => node.disabled);
24227
24262
 
24228
24263
  const CASCADER_SELECTABLE_LEVELS = {
24229
24264
  /** Only terminal leaves commit a value (default). */
@@ -25049,7 +25084,7 @@ class CascaderDirective extends FieldStateControlDirective {
25049
25084
  /** Activates a search result: commits selectable nodes, jumps the browse state to branch-only matches. */
25050
25085
  activateSearchResult(path) {
25051
25086
  const node = path[path.length - 1];
25052
- if (!node || node.disabled || this.disabled() || this.readonly()) {
25087
+ if (!node || isPathDisabled(path) || this.disabled() || this.readonly()) {
25053
25088
  return;
25054
25089
  }
25055
25090
  if (canHaveChildren(node) && this.selectableLevels() !== CASCADER_SELECTABLE_LEVELS.ANY) {
@@ -25069,7 +25104,7 @@ class CascaderDirective extends FieldStateControlDirective {
25069
25104
  /** @internal Enter in the search input activates the focused result, or the first enabled one. */
25070
25105
  activateFocusedSearchResult() {
25071
25106
  const results = this.searchState().results;
25072
- const path = results[this.focusedSearchIndex()] ?? results.find((candidate) => !candidate[candidate.length - 1]?.disabled);
25107
+ const path = results[this.focusedSearchIndex()] ?? results.find((candidate) => !isPathDisabled(candidate));
25073
25108
  if (path) {
25074
25109
  this.activateSearchResult(path);
25075
25110
  }
@@ -25144,7 +25179,7 @@ class CascaderDirective extends FieldStateControlDirective {
25144
25179
  const results = this.searchState().results;
25145
25180
  for (let index = from; index >= 0 && index < results.length; index += step) {
25146
25181
  const path = results[index];
25147
- if (path && !path[path.length - 1]?.disabled) {
25182
+ if (path && !isPathDisabled(path)) {
25148
25183
  return index;
25149
25184
  }
25150
25185
  }
@@ -25506,7 +25541,7 @@ class CascaderSearchOptionDirective {
25506
25541
  /** The path's final node - the one an activation commits (or drills into). */
25507
25542
  this.node = computed(() => this.path()[this.path().length - 1] ?? null, /* @ts-ignore */
25508
25543
  ...(ngDevMode ? [{ debugName: "node" }] : /* istanbul ignore next */ []));
25509
- this.disabled = computed(() => this.node()?.disabled ?? false, /* @ts-ignore */
25544
+ this.disabled = computed(() => isPathDisabled(this.path()), /* @ts-ignore */
25510
25545
  ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
25511
25546
  this.selected = computed(() => {
25512
25547
  const node = this.node();
@@ -27721,6 +27756,7 @@ class InputDirective extends TextFieldControlDirective {
27721
27756
  value: this.displayValue,
27722
27757
  placeholder: this.effectivePlaceholder,
27723
27758
  type: this.type,
27759
+ attributes: () => ({ autocomplete: this.autocomplete() || null }),
27724
27760
  skip: () => this.nativeSyncSuppressed,
27725
27761
  });
27726
27762
  }
@@ -27896,16 +27932,45 @@ class NumberInputDirective extends TextFieldControlDirective {
27896
27932
  this.nativeControl.set(hostElement);
27897
27933
  this.focusTarget.set(hostElement);
27898
27934
  this.mirrorOntoNativeHost(hostElement, {
27899
- value: () => `${this.displayValue()}`,
27900
27935
  placeholder: this.effectivePlaceholder,
27901
27936
  attributes: () => ({
27902
27937
  min: this.min()?.toString() ?? null,
27903
27938
  max: this.max()?.toString() ?? null,
27904
27939
  step: this.step()?.toString() ?? null,
27905
27940
  inputmode: this.inputMode(),
27941
+ autocomplete: this.autocomplete() || null,
27906
27942
  }),
27907
27943
  });
27908
27944
  }
27945
+ effect(() => {
27946
+ const element = this.nativeControl();
27947
+ this.displayValue();
27948
+ if (element)
27949
+ untracked(() => this.writeNativeTextUnlessInSync(element));
27950
+ });
27951
+ effect(() => {
27952
+ if (this.touched())
27953
+ return;
27954
+ untracked(() => this.clearParseError());
27955
+ });
27956
+ }
27957
+ /**
27958
+ * @internal Rewrites the native text in the model's own form - `2.0` becomes `2` - once the user
27959
+ * leaves the input. Text that is not a number stays, so the parse error can name it.
27960
+ */
27961
+ normalizeNativeText() {
27962
+ const element = this.nativeControl();
27963
+ if (!element || this.mixed() || element.validity.badInput)
27964
+ return;
27965
+ const canonical = `${this.displayValue()}`;
27966
+ if (element.value !== canonical)
27967
+ element.value = canonical;
27968
+ }
27969
+ handleNativeBlur(event) {
27970
+ if (event.target !== this.focusTarget())
27971
+ return;
27972
+ super.handleNativeBlur(event);
27973
+ this.normalizeNativeText();
27909
27974
  }
27910
27975
  /**
27911
27976
  * Steps the value by `step` (an empty or mixed value starts from `0`), clamped to `min`/`max`.
@@ -28012,6 +28077,28 @@ class NumberInputDirective extends TextFieldControlDirective {
28012
28077
  this.value.set(Number.isNaN(parsed) ? null : parsed);
28013
28078
  this.parseError.set(inputElement.validity.badInput);
28014
28079
  }
28080
+ /** Writing on every keystroke would turn `2.0` into `2`, eat the `-` of `-0.5` and move the caret. */
28081
+ writeNativeTextUnlessInSync(element) {
28082
+ if (this.nativeTextMatchesModel(element))
28083
+ return;
28084
+ element.value = `${this.displayValue()}`;
28085
+ }
28086
+ nativeTextMatchesModel(element) {
28087
+ if (this.mixed())
28088
+ return element.value === '';
28089
+ const value = this.value();
28090
+ if (value === null)
28091
+ return element.value === '' || element.validity.badInput;
28092
+ return element.value !== '' && element.valueAsNumber === value;
28093
+ }
28094
+ clearParseError() {
28095
+ if (!this.parseError())
28096
+ return;
28097
+ const element = this.nativeControl();
28098
+ if (element)
28099
+ element.value = `${this.displayValue()}`;
28100
+ this.parseError.set(false);
28101
+ }
28015
28102
  exceedsDecimals(text) {
28016
28103
  const decimals = this.decimals();
28017
28104
  if (decimals === null)
@@ -28137,6 +28224,8 @@ class PasswordInputDirective extends TextFieldControlDirective {
28137
28224
  this.mirrorOntoNativeHost(hostElement, {
28138
28225
  value: this.displayValue,
28139
28226
  placeholder: this.effectivePlaceholder,
28227
+ type: this.inputType,
28228
+ attributes: () => ({ autocomplete: this.autocomplete() || null }),
28140
28229
  });
28141
28230
  }
28142
28231
  }
@@ -30044,79 +30133,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
30044
30133
  type: Directive
30045
30134
  }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }] } });
30046
30135
 
30047
- /**
30048
- * Strictly parses `value` against a date-fns format string. Returns `null` for
30049
- * empty input, leftover characters, or anything date-fns considers invalid.
30050
- */
30051
- const parseDateValue = (value, options) => {
30052
- const trimmed = value.trim();
30053
- if (!trimmed) {
30054
- return null;
30055
- }
30056
- const locale = options.locale ?? undefined;
30057
- const timeZone = options.timeZone ?? null;
30058
- const parsed = parse(trimmed, options.format, options.referenceDate ?? new Date(), {
30059
- locale,
30060
- in: timeZone === null ? undefined : tz(timeZone),
30061
- });
30062
- if (!isValid(parsed)) {
30063
- return null;
30064
- }
30065
- return timeZone === null ? parsed : new Date(parsed.getTime());
30066
- };
30067
- /** Formats a `Date` with a date-fns format string. Invalid dates yield `null`. */
30068
- const formatDateValue = (date, options) => {
30069
- if (!isValid(date)) {
30070
- return null;
30071
- }
30072
- const locale = options.locale;
30073
- return format(date, options.format, locale ? { locale } : undefined);
30074
- };
30075
-
30076
- /** The `displayFormat` a precision implies, when the consumer has not named one. */
30077
- const displayFormatForPrecision = (precision, locale) => {
30078
- if (precision === 'day') {
30079
- return 'P';
30080
- }
30081
- if (precision === 'year') {
30082
- return 'yyyy';
30083
- }
30084
- return monthYearFormat(locale?.formatLong?.date({ width: 'short' }) ?? 'MM/dd/yyyy');
30085
- };
30086
- const monthYearFormat = (shortDatePattern) => {
30087
- const stripped = shortDatePattern.replace(/(?:[^a-zA-Z']+d+|d+[^a-zA-Z']+)/, '');
30088
- if (stripped === shortDatePattern || /d/.test(stripped)) {
30089
- return 'MM/yyyy';
30090
- }
30091
- return widenYearToken(stripped);
30092
- };
30093
- /** `y` / `yy` / `yyy` → `yyyy`, so the pattern is fixed-width and a mask can be derived from it. */
30094
- const widenYearToken = (pattern) => pattern.replace(/y+/, 'yyyy');
30095
-
30096
- const EXAMPLE_DATE = /* @__PURE__ */ new Date(2026, 6, 16, 21, 30, 0);
30097
- /**
30098
- * Dev mode only: warns once per control when a non-empty wire value does not parse against the
30099
- * `valueFormat` in effect, since the field then renders blank. Call in an injection context.
30100
- */
30101
- const warnOnUnparsedValue = (options) => {
30102
- if (!ngDevMode)
30103
- return;
30104
- let warned = false;
30105
- effect(() => {
30106
- if (warned)
30107
- return;
30108
- const miss = options.readings().find((reading) => !!reading.value?.trim() && reading.parsed === null);
30109
- if (!miss)
30110
- return;
30111
- warned = true;
30112
- const format = options.format();
30113
- const example = formatDateValue(EXAMPLE_DATE, { format, locale: options.locale() });
30114
- console.warn(`[${options.selector}] The value "${miss.value}" does not match the valueFormat "${format}", so the field ` +
30115
- `renders blank. A matching value looks like "${example}". Set valueFormat on the control or ` +
30116
- `${options.formatProvider}() for the app.`);
30117
- });
30118
- };
30119
-
30120
30136
  /** date-fns' own pre-pass: the `P`/`p` locale formats are expanded before the format is tokenized. */
30121
30137
  const LONG_FORMAT_PATTERN = /P+p+|P+|p+|''|'(''|[^'])+('|$)|./g;
30122
30138
  /** date-fns' formatting tokenizer. */
@@ -30191,13 +30207,15 @@ const kindOf = (token) => {
30191
30207
  // `t`/`T` are whole epoch timestamps, and an unknown letter is date-fns' problem
30192
30208
  return /[a-zA-Z]/.test(first) ? 'unsplittable' : 'literal';
30193
30209
  };
30210
+ /** The format's date-fns tokens, with the `P`/`p` locale formats expanded. */
30211
+ const formatTokens = (format, locale) => expandLongFormats(format, locale ?? enUS).match(TOKEN_PATTERN) ?? [];
30194
30212
  /**
30195
30213
  * Splits a combined date & time format into the span carrying the time and the date format around
30196
30214
  * it. `null` when the format has no time half, no date half, or interleaves the two.
30197
30215
  */
30198
30216
  const splitDateTimeFormat = (format, locale) => {
30199
- const tokens = expandLongFormats(format, locale ?? enUS).match(TOKEN_PATTERN);
30200
- if (tokens === null) {
30217
+ const tokens = formatTokens(format, locale);
30218
+ if (tokens.length === 0) {
30201
30219
  return null;
30202
30220
  }
30203
30221
  const kinds = tokens.map(kindOf);
@@ -30216,6 +30234,88 @@ const splitDateTimeFormat = (format, locale) => {
30216
30234
  };
30217
30235
  };
30218
30236
 
30237
+ // date-fns' `y`/`yyyy` parsers take one to four digits as the literal year, so `1.2.26` would read as 0026
30238
+ const isShortYear = (parsed, { format, locale }) => {
30239
+ if (parsed.getFullYear() >= 1000) {
30240
+ return false;
30241
+ }
30242
+ const yearTokens = formatTokens(format, locale ?? null).filter((token) => token[0] === 'y');
30243
+ return yearTokens.length > 0 && !yearTokens.includes('yy');
30244
+ };
30245
+ /**
30246
+ * Strictly parses `value` against a date-fns format string. Returns `null` for
30247
+ * empty input, leftover characters, a year of fewer than four digits where the format
30248
+ * asks for a full one, or anything date-fns considers invalid.
30249
+ */
30250
+ const parseDateValue = (value, options) => {
30251
+ const trimmed = value.trim();
30252
+ if (!trimmed) {
30253
+ return null;
30254
+ }
30255
+ const locale = options.locale ?? undefined;
30256
+ const timeZone = options.timeZone ?? null;
30257
+ const parsed = parse(trimmed, options.format, options.referenceDate ?? new Date(), {
30258
+ locale,
30259
+ in: timeZone === null ? undefined : tz(timeZone),
30260
+ });
30261
+ if (!isValid(parsed) || isShortYear(parsed, options)) {
30262
+ return null;
30263
+ }
30264
+ return timeZone === null ? parsed : new Date(parsed.getTime());
30265
+ };
30266
+ /** Formats a `Date` with a date-fns format string. Invalid dates yield `null`. */
30267
+ const formatDateValue = (date, options) => {
30268
+ if (!isValid(date)) {
30269
+ return null;
30270
+ }
30271
+ const locale = options.locale;
30272
+ return format(date, options.format, locale ? { locale } : undefined);
30273
+ };
30274
+
30275
+ /** The `displayFormat` a precision implies, when the consumer has not named one. */
30276
+ const displayFormatForPrecision = (precision, locale) => {
30277
+ if (precision === 'day') {
30278
+ return 'P';
30279
+ }
30280
+ if (precision === 'year') {
30281
+ return 'yyyy';
30282
+ }
30283
+ return monthYearFormat(locale?.formatLong?.date({ width: 'short' }) ?? 'MM/dd/yyyy');
30284
+ };
30285
+ const monthYearFormat = (shortDatePattern) => {
30286
+ const stripped = shortDatePattern.replace(/(?:[^a-zA-Z']+d+|d+[^a-zA-Z']+)/, '');
30287
+ if (stripped === shortDatePattern || /d/.test(stripped)) {
30288
+ return 'MM/yyyy';
30289
+ }
30290
+ return widenYearToken(stripped);
30291
+ };
30292
+ /** `y` / `yy` / `yyy` → `yyyy`, so the pattern is fixed-width and a mask can be derived from it. */
30293
+ const widenYearToken = (pattern) => pattern.replace(/y+/, 'yyyy');
30294
+
30295
+ const EXAMPLE_DATE = /* @__PURE__ */ new Date(2026, 6, 16, 21, 30, 0);
30296
+ /**
30297
+ * Dev mode only: warns once per control when a non-empty wire value does not parse against the
30298
+ * `valueFormat` in effect, since the field then renders blank. Call in an injection context.
30299
+ */
30300
+ const warnOnUnparsedValue = (options) => {
30301
+ if (!ngDevMode)
30302
+ return;
30303
+ let warned = false;
30304
+ effect(() => {
30305
+ if (warned)
30306
+ return;
30307
+ const miss = options.readings().find((reading) => !!reading.value?.trim() && reading.parsed === null);
30308
+ if (!miss)
30309
+ return;
30310
+ warned = true;
30311
+ const format = options.format();
30312
+ const example = formatDateValue(EXAMPLE_DATE, { format, locale: options.locale() });
30313
+ console.warn(`[${options.selector}] The value "${miss.value}" does not match the valueFormat "${format}", so the field ` +
30314
+ `renders blank. A matching value looks like "${example}". Set valueFormat on the control or ` +
30315
+ `${options.formatProvider}() for the app.`);
30316
+ });
30317
+ };
30318
+
30219
30319
  /** The day of `day` carrying the time of day of `time`. */
30220
30320
  const withTimeOfDay = (day, time) => setSeconds(setMinutes(setHours(startOfDay(day), time.getHours()), time.getMinutes()), time.getSeconds());
30221
30321
 
@@ -31189,11 +31289,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
31189
31289
  }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], startPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "startPlaceholder", required: false }] }], endPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "endPlaceholder", required: false }] }], startAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "startAriaLabel", required: false }] }], endAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "endAriaLabel", required: false }] }] } });
31190
31290
 
31191
31291
  /** The preset state a range input shares with its styled component. Call in an injection context. */
31192
- const createDateRangePresets = ({ host, presets, labels, normalize }) => {
31292
+ const createDateRangePresets = ({ host, presets, labels, firstDayOfWeek, normalize, }) => {
31193
31293
  const resolveInstants = (preset) => {
31194
31294
  const timeZone = host.effectiveTimeZone();
31195
31295
  const now = timeZone === null ? new Date() : zonedProxy(new Date(), timeZone);
31196
- const range = preset.resolve(now, { locale: host.effectiveLocale() });
31296
+ const locale = host.effectiveLocale();
31297
+ const range = preset.resolve(now, {
31298
+ locale,
31299
+ weekStartsOn: firstDayOfWeek() ?? locale?.options?.weekStartsOn ?? 1,
31300
+ });
31197
31301
  return {
31198
31302
  start: reinterpretInZone(normalize(range.start), timeZone),
31199
31303
  end: reinterpretInZone(normalize(range.end), timeZone),
@@ -31326,6 +31430,7 @@ class DateRangeInputDirective extends DateRangePickerInputDirective {
31326
31430
  host: this,
31327
31431
  presets: this.presets,
31328
31432
  labels: this.dateTimeLabels,
31433
+ firstDayOfWeek: this.firstDayOfWeek,
31329
31434
  normalize: (date) => startOfCalendarUnit(date, this.precision()),
31330
31435
  });
31331
31436
  /** The format in effect: this instance's `displayFormat`, else the one `precision` implies. */
@@ -31548,7 +31653,10 @@ const dayRange = (start, end) => ({
31548
31653
  start: startOfDay(start),
31549
31654
  end: endOfDayMinute(end),
31550
31655
  });
31551
- const weekOptions = ({ locale }) => (locale ? { locale } : undefined);
31656
+ const weekOptions = ({ locale, weekStartsOn }) => ({
31657
+ locale: locale ?? undefined,
31658
+ weekStartsOn: weekStartsOn ?? locale?.options?.weekStartsOn ?? 1,
31659
+ });
31552
31660
  const createPreset = ({ defaultLabel, resolve, options }) => ({
31553
31661
  label: options.label ?? defaultLabel,
31554
31662
  resolve,
@@ -31573,7 +31681,7 @@ const nextDaysPreset = (count, options = {}) => createPreset({
31573
31681
  resolve: (now) => dayRange(addDays(now, 1), addDays(now, Math.max(1, count))),
31574
31682
  options,
31575
31683
  });
31576
- /** The current week, starting on the locale's first day of the week. */
31684
+ /** The current week, starting on the first day of the control's calendar rows. */
31577
31685
  const thisWeekPreset = (options = {}) => createPreset({
31578
31686
  defaultLabel: (labels) => labels.presetThisWeek,
31579
31687
  resolve: (now, context) => dayRange(startOfWeek(now, weekOptions(context)), endOfWeek(now, weekOptions(context))),
@@ -31613,6 +31721,14 @@ const DATE_TIME_INPUT_ERROR_CODES = {
31613
31721
  };
31614
31722
 
31615
31723
  const secondsOfDay$1 = (date) => date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds();
31724
+ /**
31725
+ * The start of `date`'s day, or of the same weekday a week earlier when the runtime's clocks change on it,
31726
+ * so every wall-clock time exists on the returned day.
31727
+ */
31728
+ const clockSafeDay = (date) => {
31729
+ const day = startOfDay(date);
31730
+ return day.getTimezoneOffset() === endOfDay(day).getTimezoneOffset() ? day : subWeeks(day, 1);
31731
+ };
31616
31732
  const setTimeOfDay = (day, candidate) => setSeconds(setMinutes(setHours(day, candidate.hour), candidate.minute), candidate.second);
31617
31733
  const isTimeSelectable = (candidate, options) => {
31618
31734
  const { min, max, filter, day } = options;
@@ -31885,9 +32001,11 @@ class TimePickerDirective {
31885
32001
  return spec.hourCycle === 12 ? `h:mm${spec.showSeconds ? ':ss' : ''} a` : `HH:mm${spec.showSeconds ? ':ss' : ''}`;
31886
32002
  }, /* @ts-ignore */
31887
32003
  ...(ngDevMode ? [{ debugName: "sideFormat" }] : /* istanbul ignore next */ []));
31888
- this.startRingDay = computed(() => startOfDay(this.ringValue('start') ?? this.now()).getTime(), /* @ts-ignore */
32004
+ this.emptyRingDay = computed(() => clockSafeDay(this.now()), /* @ts-ignore */
32005
+ ...(ngDevMode ? [{ debugName: "emptyRingDay" }] : /* istanbul ignore next */ []));
32006
+ this.startRingDay = computed(() => startOfDay(this.ringValue('start') ?? this.emptyRingDay()).getTime(), /* @ts-ignore */
31889
32007
  ...(ngDevMode ? [{ debugName: "startRingDay" }] : /* istanbul ignore next */ []));
31890
- this.endRingDay = computed(() => startOfDay(this.ringValue('end') ?? this.now()).getTime(), /* @ts-ignore */
32008
+ this.endRingDay = computed(() => startOfDay(this.ringValue('end') ?? this.emptyRingDay()).getTime(), /* @ts-ignore */
31891
32009
  ...(ngDevMode ? [{ debugName: "endRingDay" }] : /* istanbul ignore next */ []));
31892
32010
  this.sameDayRange = computed(() => {
31893
32011
  const days = this.rangeDays();
@@ -31938,7 +32056,7 @@ class TimePickerDirective {
31938
32056
  return false;
31939
32057
  }
31940
32058
  const current = this.ringValue(side);
31941
- const next = setMilliseconds(setTimeOfDay(current ?? startOfDay(this.now()), {
32059
+ const next = setMilliseconds(setTimeOfDay(current ?? this.emptyRingDay(), {
31942
32060
  hour: Math.floor(minute / 60),
31943
32061
  minute: minute % 60,
31944
32062
  second: 0,
@@ -33302,10 +33420,7 @@ const createPickerPanes = (order, pickerOpen) => {
33302
33420
  * The day time-only values are read on: today, or the same weekday a week earlier when the
33303
33421
  * runtime's clocks change today, so every wall-clock time exists on it.
33304
33422
  */
33305
- const timeReferenceDay = () => {
33306
- const today = startOfDay(new Date());
33307
- return today.getTimezoneOffset() === endOfDay(today).getTimezoneOffset() ? today : subWeeks(today, 1);
33308
- };
33423
+ const timeReferenceDay = () => clockSafeDay(new Date());
33309
33424
  const MERIDIEM_PATTERN = /\s*([ap])\.?\s*(?:m\.?)?$/i;
33310
33425
  const SEPARATED_PATTERN = /^(\d{1,2})(?:[:.\s](\d{1,2})(?:[:.\s](\d{1,2}))?)?$/;
33311
33426
  const COMPACT_PATTERN = /^\d{3,6}$/;
@@ -33988,6 +34103,7 @@ class DateTimeRangeInputDirective extends DateRangePickerInputDirective {
33988
34103
  host: this,
33989
34104
  presets: this.presets,
33990
34105
  labels: this.dateTimeLabels,
34106
+ firstDayOfWeek: this.firstDayOfWeek,
33991
34107
  normalize: (date) => date,
33992
34108
  });
33993
34109
  /** The two days the picker calendar highlights - committed, else picked with no time yet. */
@@ -34385,22 +34501,23 @@ const dateTimeRangeOrder = (path, options = {}) => rangeOrder({
34385
34501
  */
34386
34502
  const timeRangeOrder = (path, options = {}) => rangeOrder({ path, valueFormat: options.valueFormat ?? inject(TIME_FORMAT), options });
34387
34503
  const resolveBound = (bound, ctx) => typeof bound === 'function' ? bound(ctx) : (bound ?? null);
34388
- const bounds = ({ path, sidesOf, valueFormat, options, unit, label }) => {
34504
+ const bounds = ({ path, sidesOf, valueFormat, options, unit, onZoneCalendar, label }) => {
34389
34505
  const labels = injectDateTimeLabels();
34390
34506
  const locale = inject(DATE_LOCALE);
34391
34507
  const timeZone = knownTimeZone(options.timeZone);
34392
34508
  const formatBound = (bound) => formatInZone(bound, { format: label, locale, timeZone }) ?? '';
34509
+ const unitOf = (date) => unit(onZoneCalendar && timeZone !== null ? zonedProxy(date, timeZone) : date).getTime();
34393
34510
  validate(path, (ctx) => {
34394
34511
  const sides = sidesOf(ctx.value())
34395
34512
  .map((side) => parseSide(side, { valueFormat, timeZone }))
34396
34513
  .filter((side) => side !== null)
34397
- .map((side) => unit(side).getTime());
34514
+ .map(unitOf);
34398
34515
  const min = resolveBound(options.min, ctx);
34399
34516
  const max = resolveBound(options.max, ctx);
34400
- if (min !== null && sides.some((side) => side < unit(min).getTime())) {
34517
+ if (min !== null && sides.some((side) => side < unitOf(min))) {
34401
34518
  return { kind: 'rangeMin', min, message: options.message ?? labels().rangeMin(formatBound(min)) };
34402
34519
  }
34403
- if (max !== null && sides.some((side) => side > unit(max).getTime())) {
34520
+ if (max !== null && sides.some((side) => side > unitOf(max))) {
34404
34521
  return { kind: 'rangeMax', max, message: options.message ?? labels().rangeMax(formatBound(max)) };
34405
34522
  }
34406
34523
  return undefined;
@@ -34426,8 +34543,9 @@ const dateRangeBounds = (path, options) => {
34426
34543
  rangeBounds({
34427
34544
  path,
34428
34545
  valueFormat: options.valueFormat ?? inject(DATE_FORMAT),
34429
- options,
34546
+ options: withControlTimeZone(options),
34430
34547
  unit: (date) => startOfCalendarUnit(date, precision),
34548
+ onZoneCalendar: true,
34431
34549
  label: displayFormatForPrecision(precision, inject(DATE_LOCALE)),
34432
34550
  });
34433
34551
  };
@@ -34468,8 +34586,9 @@ const dateBounds = (path, options = {}) => {
34468
34586
  path,
34469
34587
  sidesOf: (value) => [value],
34470
34588
  valueFormat: options.valueFormat ?? inject(DATE_FORMAT),
34471
- options,
34589
+ options: withControlTimeZone(options),
34472
34590
  unit: (date) => startOfCalendarUnit(date, precision),
34591
+ onZoneCalendar: true,
34473
34592
  label: displayFormatForPrecision(precision, inject(DATE_LOCALE)),
34474
34593
  });
34475
34594
  };
@@ -35687,7 +35806,9 @@ const DROPZONE_FILE_CONSTRAINTS = /* @__PURE__ */ createManagedMetadataKey((_sta
35687
35806
  constraints: data,
35688
35807
  rejections: signal([]),
35689
35808
  labels: signal(DEFAULT_DROPZONE_LABELS),
35809
+ effectiveConstraints: signal(undefined),
35690
35810
  }));
35811
+ /** @internal */
35691
35812
  const rejectionMessage = (rejection, context) => {
35692
35813
  const name = rejection.file.name;
35693
35814
  const { constraints, labels } = context;
@@ -35732,7 +35853,7 @@ const dropzoneFiles = (path, constraints) => {
35732
35853
  return channel.rejections().map((rejection) => ({
35733
35854
  kind: DROPZONE_FILES_ERROR_KIND,
35734
35855
  message: currentConstraints?.message?.(rejection) ??
35735
- rejectionMessage(rejection, { constraints: currentConstraints, labels }),
35856
+ rejectionMessage(rejection, { constraints: channel.effectiveConstraints() ?? currentConstraints, labels }),
35736
35857
  }));
35737
35858
  });
35738
35859
  };
@@ -35831,6 +35952,10 @@ class DropzoneDirective extends FieldStateControlDirective {
35831
35952
  return state?.metadata(DROPZONE_FILE_CONSTRAINTS) ?? null;
35832
35953
  }, /* @ts-ignore */
35833
35954
  ...(ngDevMode ? [{ debugName: "fileValidation" }] : /* istanbul ignore next */ []));
35955
+ /** The rejections no bound `dropzoneFiles()` rule turns into field errors - the dropzone reports these itself. */
35956
+ this.unhandledRejections = computed(() => (this.fileValidation() ? [] : this.lastRejections()), /* @ts-ignore */
35957
+ ...(ngDevMode ? [{ debugName: "unhandledRejections" }] : /* istanbul ignore next */ []));
35958
+ /** @internal */
35834
35959
  this.fileConstraints = computed(() => {
35835
35960
  const schema = this.fileValidation()?.constraints();
35836
35961
  return {
@@ -35875,6 +36000,11 @@ class DropzoneDirective extends FieldStateControlDirective {
35875
36000
  const labels = this.dropzoneLabels();
35876
36001
  untracked(() => channel?.labels.set(labels));
35877
36002
  });
36003
+ effect(() => {
36004
+ const channel = this.fileValidation();
36005
+ const constraints = this.fileConstraints();
36006
+ untracked(() => channel?.effectiveConstraints.set(constraints));
36007
+ });
35878
36008
  effect(() => {
35879
36009
  const incoming = this.value();
35880
36010
  untracked(() => this.reconcileValue(incoming));
@@ -36259,6 +36389,11 @@ class DropzoneComponent {
36259
36389
  messages.push(this.uploadErrorMessage()?.(entry) ?? this.defaultUploadErrorMessage(entry));
36260
36390
  }
36261
36391
  }
36392
+ const labels = this.resolvedLabels();
36393
+ const constraints = this.dropzoneDir.fileConstraints();
36394
+ for (const rejection of this.dropzoneDir.unhandledRejections()) {
36395
+ messages.push(rejectionMessage(rejection, { constraints, labels }));
36396
+ }
36262
36397
  return messages;
36263
36398
  }, /* @ts-ignore */
36264
36399
  ...(ngDevMode ? [{ debugName: "internalErrorMessages" }] : /* istanbul ignore next */ []));
@@ -36739,22 +36874,25 @@ class CounterComponent {
36739
36874
  * The limit to count towards. Wins over the schema's `maxLength()` - use it for a control whose
36740
36875
  * length isn't schema-validated, or to count towards a softer limit than the one that validates.
36741
36876
  */
36742
- this.max = input(undefined, /* @ts-ignore */
36743
- ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
36877
+ this.max = input(undefined, { ...(ngDevMode ? { debugName: "max" } : /* istanbul ignore next */ {}), transform: optionalNumberAttribute$1 });
36744
36878
  /** Measures the control's value. Override for a value type the default can't count. */
36745
36879
  this.lengthOf = input(defaultLengthOf, /* @ts-ignore */
36746
36880
  ...(ngDevMode ? [{ debugName: "lengthOf" }] : /* istanbul ignore next */ []));
36747
36881
  /** The limit actually in effect: the explicit `[max]`, else the bound field's `maxLength()`. */
36748
36882
  this.resolvedMax = computed(() => this.max() ?? this.formField?.controlMaxLength(), /* @ts-ignore */
36749
36883
  ...(ngDevMode ? [{ debugName: "resolvedMax" }] : /* istanbul ignore next */ []));
36750
- /** The current length of the control's value. */
36751
- this.current = computed(() => this.lengthOf()(this.formField?.controlValue() ?? null), /* @ts-ignore */
36884
+ this.controlMixed = computed(() => this.formField?.registeredControl()?.mixed?.() ?? false, /* @ts-ignore */
36885
+ ...(ngDevMode ? [{ debugName: "controlMixed" }] : /* istanbul ignore next */ []));
36886
+ /** The current length of the control's value - `0` while mixed, so the hidden raw value never shows. */
36887
+ this.current = computed(() => (this.controlMixed() ? 0 : this.lengthOf()(this.formField?.controlValue() ?? null)), /* @ts-ignore */
36752
36888
  ...(ngDevMode ? [{ debugName: "current" }] : /* istanbul ignore next */ []));
36753
36889
  /**
36754
36890
  * Whether the value is past the limit. With a schema `maxLength()` this is the control's own
36755
36891
  * validation error.
36756
36892
  */
36757
36893
  this.isOverLimit = computed(() => {
36894
+ if (this.controlMixed())
36895
+ return false;
36758
36896
  const explicitMax = this.max();
36759
36897
  if (explicitMax !== undefined) {
36760
36898
  return this.current() > explicitMax;
@@ -36948,7 +37086,7 @@ class NumberInputComponent {
36948
37086
  .subscribe();
36949
37087
  }
36950
37088
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: NumberInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
36951
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: NumberInputComponent, isStandalone: true, selector: "et-number-input", inputs: { stepper: { classPropertyName: "stepper", publicName: "stepper", isSignal: true, isRequired: false, transformFunction: null }, incrementLabel: { classPropertyName: "incrementLabel", publicName: "incrementLabel", isSignal: true, isRequired: false, transformFunction: null }, decrementLabel: { classPropertyName: "decrementLabel", publicName: "decrementLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "numberInputDir.activate()" }, properties: { "attr.data-stepper": "stepper() || null" }, classAttribute: "et-number-input" }, providers: [provideIcons(MINUS_ICON, PLUS_ICON)], viewQueries: [{ propertyName: "nativeInput", first: true, predicate: ["nativeInput"], descendants: true, isSignal: true }], hostDirectives: [{ directive: NumberInputDirective, inputs: ["min", "min", "max", "max", "step", "step", "decimals", "decimals", "parseErrorMessage", "parseErrorMessage", "placeholder", "placeholder", "autocomplete", "autocomplete", "textAlign", "textAlign", "value", "value", "touched", "touched", "mixed", "mixed", "mixedLabel", "mixedLabel", "disabled", "disabled", "readonly", "readonly", "hidden", "hidden", "invalid", "invalid", "errors", "errors", "warnings", "warnings", "required", "required", "name", "name", "maxLength", "maxLength", "pending", "pending", "aria-label", "aria-label", "aria-labelledby", "aria-labelledby"], outputs: ["valueChange", "valueChange", "mixedChange", "mixedChange", "touchedChange", "touchedChange", "touch", "touch"] }, { directive: i1.ColorInteractiveDirective }], ngImport: i0, template: "<input\n #nativeInput\n [value]=\"numberInputDir.displayValue()\"\n [disabled]=\"numberInputDir.disabled()\"\n [readOnly]=\"numberInputDir.readonly()\"\n [required]=\"numberInputDir.required()\"\n [placeholder]=\"numberInputDir.effectivePlaceholder()\"\n [attr.autocomplete]=\"numberInputDir.autocomplete() || null\"\n [attr.min]=\"numberInputDir.min() ?? null\"\n [attr.max]=\"numberInputDir.max() ?? null\"\n [attr.step]=\"numberInputDir.step() ?? null\"\n [attr.inputmode]=\"numberInputDir.inputMode()\"\n [attr.name]=\"numberInputDir.name() || null\"\n [attr.aria-invalid]=\"numberInputDir.shouldDisplayError() || null\"\n [attr.aria-describedby]=\"numberInputDir.describedBy() || null\"\n [attr.aria-label]=\"numberInputDir.ariaLabel() || null\"\n [attr.aria-labelledby]=\"numberInputDir.labelId() || null\"\n [attr.data-text-align]=\"numberInputDir.textAlign()\"\n (focus)=\"numberInputDir.focused.set(true)\"\n (blur)=\"numberInputDir.focused.set(false); numberInputDir.touched.set(true)\"\n class=\"et-number-input-native\"\n type=\"number\"\n/>\n\n@if (stepper()) {\n <div class=\"et-number-input-stepper\">\n <button\n [attr.aria-label]=\"resolvedDecrementLabel()\"\n [disabled]=\"!numberInputDir.canStepDown()\"\n (pointerdown)=\"startStepRepeat($event, -1)\"\n (pointerup)=\"stopStepRepeat()\"\n (pointercancel)=\"stopStepRepeat()\"\n (lostpointercapture)=\"stopStepRepeat()\"\n class=\"et-number-input-stepper-button\"\n type=\"button\"\n tabindex=\"-1\"\n >\n <i aria-hidden=\"true\" etIcon=\"et-minus\"></i>\n </button>\n <button\n [attr.aria-label]=\"resolvedIncrementLabel()\"\n [disabled]=\"!numberInputDir.canStepUp()\"\n (pointerdown)=\"startStepRepeat($event, 1)\"\n (pointerup)=\"stopStepRepeat()\"\n (pointercancel)=\"stopStepRepeat()\"\n (lostpointercapture)=\"stopStepRepeat()\"\n class=\"et-number-input-stepper-button\"\n type=\"button\"\n tabindex=\"-1\"\n >\n <i aria-hidden=\"true\" etIcon=\"et-plus\"></i>\n </button>\n </div>\n}\n", styles: ["@layer components{html.et-number-input-scrubbing,html.et-number-input-scrubbing *{cursor:ew-resize!important}@property --et-number-input-stepper-size{syntax: \"<length>\"; inherits: true; initial-value: 16px;}et-number-input{display:block;flex:1;min-inline-size:0;color:inherit}et-number-input[data-stepper]{display:flex;align-items:center;gap:8px}et-number-input .et-number-input-stepper{display:flex;align-items:center;gap:2px;flex:none}et-number-input .et-number-input-stepper-button{display:flex;align-items:center;justify-content:center;flex:none;inline-size:calc(var(--et-number-input-stepper-size) + 8px);block-size:calc(var(--et-number-input-stepper-size) + 8px);padding:0;border:none;border-radius:4px;background:transparent;color:var(--et-surface-color-muted-solid, currentColor);cursor:pointer;outline:none;touch-action:none}@media(pointer:fine){et-number-input .et-number-input-stepper-button{cursor:ew-resize}}et-number-input .et-number-input-stepper-button .et-icon{inline-size:var(--et-number-input-stepper-size);block-size:var(--et-number-input-stepper-size)}@media(hover:hover){et-number-input .et-number-input-stepper-button:hover{background:color-mix(in srgb,var(--et-surface-interaction-solid, currentColor) 12%,transparent);color:var(--et-surface-color-solid, currentColor)}}et-number-input .et-number-input-stepper-button:active{background:color-mix(in srgb,var(--et-surface-interaction-solid, currentColor) 20%,transparent)}et-number-input .et-number-input-stepper-button:disabled{cursor:default;background:transparent;color:inherit;opacity:.4}et-number-input .et-number-input-native{display:block;inline-size:100%;border:none;outline:none;background:transparent;font:inherit;color:inherit;caret-color:var(--et-theme-color-primary-solid, currentColor);padding:0;min-width:0;appearance:textfield}et-number-input .et-number-input-native::-webkit-outer-spin-button,et-number-input .et-number-input-native::-webkit-inner-spin-button{appearance:none;margin:0}et-number-input .et-number-input-native:not(:focus){overflow:hidden;text-overflow:ellipsis}et-number-input .et-number-input-native::placeholder{color:color-mix(in srgb,currentColor 46%,transparent)}et-number-input .et-number-input-native[data-text-align=start]{text-align:start}et-number-input .et-number-input-native[data-text-align=center]{text-align:center}et-number-input .et-number-input-native[data-text-align=end]{text-align:end}et-number-input[data-mixed] .et-number-input-native::placeholder{font-style:italic;color:color-mix(in srgb,currentColor 72%,transparent)}}\n"], dependencies: [{ kind: "directive", type: IconDirective, selector: "[etIcon]", inputs: ["etIcon", "variant", "allowHardcodedColor", "label"] }], encapsulation: i0.ViewEncapsulation.None }); }
37089
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: NumberInputComponent, isStandalone: true, selector: "et-number-input", inputs: { stepper: { classPropertyName: "stepper", publicName: "stepper", isSignal: true, isRequired: false, transformFunction: null }, incrementLabel: { classPropertyName: "incrementLabel", publicName: "incrementLabel", isSignal: true, isRequired: false, transformFunction: null }, decrementLabel: { classPropertyName: "decrementLabel", publicName: "decrementLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "numberInputDir.activate()" }, properties: { "attr.data-stepper": "stepper() || null" }, classAttribute: "et-number-input" }, providers: [provideIcons(MINUS_ICON, PLUS_ICON)], viewQueries: [{ propertyName: "nativeInput", first: true, predicate: ["nativeInput"], descendants: true, isSignal: true }], hostDirectives: [{ directive: NumberInputDirective, inputs: ["min", "min", "max", "max", "step", "step", "decimals", "decimals", "parseErrorMessage", "parseErrorMessage", "placeholder", "placeholder", "autocomplete", "autocomplete", "textAlign", "textAlign", "value", "value", "touched", "touched", "mixed", "mixed", "mixedLabel", "mixedLabel", "disabled", "disabled", "readonly", "readonly", "hidden", "hidden", "invalid", "invalid", "errors", "errors", "warnings", "warnings", "required", "required", "name", "name", "maxLength", "maxLength", "pending", "pending", "aria-label", "aria-label", "aria-labelledby", "aria-labelledby"], outputs: ["valueChange", "valueChange", "mixedChange", "mixedChange", "touchedChange", "touchedChange", "touch", "touch"] }, { directive: i1.ColorInteractiveDirective }], ngImport: i0, template: "<input\n #nativeInput\n [disabled]=\"numberInputDir.disabled()\"\n [readOnly]=\"numberInputDir.readonly()\"\n [required]=\"numberInputDir.required()\"\n [placeholder]=\"numberInputDir.effectivePlaceholder()\"\n [attr.autocomplete]=\"numberInputDir.autocomplete() || null\"\n [attr.min]=\"numberInputDir.min() ?? null\"\n [attr.max]=\"numberInputDir.max() ?? null\"\n [attr.step]=\"numberInputDir.step() ?? null\"\n [attr.inputmode]=\"numberInputDir.inputMode()\"\n [attr.name]=\"numberInputDir.name() || null\"\n [attr.aria-invalid]=\"numberInputDir.shouldDisplayError() || null\"\n [attr.aria-describedby]=\"numberInputDir.describedBy() || null\"\n [attr.aria-label]=\"numberInputDir.ariaLabel() || null\"\n [attr.aria-labelledby]=\"numberInputDir.labelId() || null\"\n [attr.data-text-align]=\"numberInputDir.textAlign()\"\n (focus)=\"numberInputDir.focused.set(true)\"\n (blur)=\"numberInputDir.focused.set(false); numberInputDir.touched.set(true); numberInputDir.normalizeNativeText()\"\n class=\"et-number-input-native\"\n type=\"number\"\n/>\n\n@if (stepper()) {\n <div class=\"et-number-input-stepper\">\n <button\n [attr.aria-label]=\"resolvedDecrementLabel()\"\n [disabled]=\"!numberInputDir.canStepDown()\"\n (pointerdown)=\"startStepRepeat($event, -1)\"\n (pointerup)=\"stopStepRepeat()\"\n (pointercancel)=\"stopStepRepeat()\"\n (lostpointercapture)=\"stopStepRepeat()\"\n class=\"et-number-input-stepper-button\"\n type=\"button\"\n tabindex=\"-1\"\n >\n <i aria-hidden=\"true\" etIcon=\"et-minus\"></i>\n </button>\n <button\n [attr.aria-label]=\"resolvedIncrementLabel()\"\n [disabled]=\"!numberInputDir.canStepUp()\"\n (pointerdown)=\"startStepRepeat($event, 1)\"\n (pointerup)=\"stopStepRepeat()\"\n (pointercancel)=\"stopStepRepeat()\"\n (lostpointercapture)=\"stopStepRepeat()\"\n class=\"et-number-input-stepper-button\"\n type=\"button\"\n tabindex=\"-1\"\n >\n <i aria-hidden=\"true\" etIcon=\"et-plus\"></i>\n </button>\n </div>\n}\n", styles: ["@layer components{html.et-number-input-scrubbing,html.et-number-input-scrubbing *{cursor:ew-resize!important}@property --et-number-input-stepper-size{syntax: \"<length>\"; inherits: true; initial-value: 16px;}et-number-input{display:block;flex:1;min-inline-size:0;color:inherit}et-number-input[data-stepper]{display:flex;align-items:center;gap:8px}et-number-input .et-number-input-stepper{display:flex;align-items:center;gap:2px;flex:none}et-number-input .et-number-input-stepper-button{display:flex;align-items:center;justify-content:center;flex:none;inline-size:calc(var(--et-number-input-stepper-size) + 8px);block-size:calc(var(--et-number-input-stepper-size) + 8px);padding:0;border:none;border-radius:4px;background:transparent;color:var(--et-surface-color-muted-solid, currentColor);cursor:pointer;outline:none;touch-action:none}@media(pointer:fine){et-number-input .et-number-input-stepper-button{cursor:ew-resize}}et-number-input .et-number-input-stepper-button .et-icon{inline-size:var(--et-number-input-stepper-size);block-size:var(--et-number-input-stepper-size)}@media(hover:hover){et-number-input .et-number-input-stepper-button:hover{background:color-mix(in srgb,var(--et-surface-interaction-solid, currentColor) 12%,transparent);color:var(--et-surface-color-solid, currentColor)}}et-number-input .et-number-input-stepper-button:active{background:color-mix(in srgb,var(--et-surface-interaction-solid, currentColor) 20%,transparent)}et-number-input .et-number-input-stepper-button:disabled{cursor:default;background:transparent;color:inherit;opacity:.4}et-number-input .et-number-input-native{display:block;inline-size:100%;border:none;outline:none;background:transparent;font:inherit;color:inherit;caret-color:var(--et-theme-color-primary-solid, currentColor);padding:0;min-width:0;appearance:textfield}et-number-input .et-number-input-native::-webkit-outer-spin-button,et-number-input .et-number-input-native::-webkit-inner-spin-button{appearance:none;margin:0}et-number-input .et-number-input-native:not(:focus){overflow:hidden;text-overflow:ellipsis}et-number-input .et-number-input-native::placeholder{color:color-mix(in srgb,currentColor 46%,transparent)}et-number-input .et-number-input-native[data-text-align=start]{text-align:start}et-number-input .et-number-input-native[data-text-align=center]{text-align:center}et-number-input .et-number-input-native[data-text-align=end]{text-align:end}et-number-input[data-mixed] .et-number-input-native::placeholder{font-style:italic;color:color-mix(in srgb,currentColor 72%,transparent)}}\n"], dependencies: [{ kind: "directive", type: IconDirective, selector: "[etIcon]", inputs: ["etIcon", "variant", "allowHardcodedColor", "label"] }], encapsulation: i0.ViewEncapsulation.None }); }
36952
37090
  }
36953
37091
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: NumberInputComponent, decorators: [{
36954
37092
  type: Component,
@@ -36974,7 +37112,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
36974
37112
  class: 'et-number-input',
36975
37113
  '[attr.data-stepper]': 'stepper() || null',
36976
37114
  '(click)': 'numberInputDir.activate()',
36977
- }, template: "<input\n #nativeInput\n [value]=\"numberInputDir.displayValue()\"\n [disabled]=\"numberInputDir.disabled()\"\n [readOnly]=\"numberInputDir.readonly()\"\n [required]=\"numberInputDir.required()\"\n [placeholder]=\"numberInputDir.effectivePlaceholder()\"\n [attr.autocomplete]=\"numberInputDir.autocomplete() || null\"\n [attr.min]=\"numberInputDir.min() ?? null\"\n [attr.max]=\"numberInputDir.max() ?? null\"\n [attr.step]=\"numberInputDir.step() ?? null\"\n [attr.inputmode]=\"numberInputDir.inputMode()\"\n [attr.name]=\"numberInputDir.name() || null\"\n [attr.aria-invalid]=\"numberInputDir.shouldDisplayError() || null\"\n [attr.aria-describedby]=\"numberInputDir.describedBy() || null\"\n [attr.aria-label]=\"numberInputDir.ariaLabel() || null\"\n [attr.aria-labelledby]=\"numberInputDir.labelId() || null\"\n [attr.data-text-align]=\"numberInputDir.textAlign()\"\n (focus)=\"numberInputDir.focused.set(true)\"\n (blur)=\"numberInputDir.focused.set(false); numberInputDir.touched.set(true)\"\n class=\"et-number-input-native\"\n type=\"number\"\n/>\n\n@if (stepper()) {\n <div class=\"et-number-input-stepper\">\n <button\n [attr.aria-label]=\"resolvedDecrementLabel()\"\n [disabled]=\"!numberInputDir.canStepDown()\"\n (pointerdown)=\"startStepRepeat($event, -1)\"\n (pointerup)=\"stopStepRepeat()\"\n (pointercancel)=\"stopStepRepeat()\"\n (lostpointercapture)=\"stopStepRepeat()\"\n class=\"et-number-input-stepper-button\"\n type=\"button\"\n tabindex=\"-1\"\n >\n <i aria-hidden=\"true\" etIcon=\"et-minus\"></i>\n </button>\n <button\n [attr.aria-label]=\"resolvedIncrementLabel()\"\n [disabled]=\"!numberInputDir.canStepUp()\"\n (pointerdown)=\"startStepRepeat($event, 1)\"\n (pointerup)=\"stopStepRepeat()\"\n (pointercancel)=\"stopStepRepeat()\"\n (lostpointercapture)=\"stopStepRepeat()\"\n class=\"et-number-input-stepper-button\"\n type=\"button\"\n tabindex=\"-1\"\n >\n <i aria-hidden=\"true\" etIcon=\"et-plus\"></i>\n </button>\n </div>\n}\n", styles: ["@layer components{html.et-number-input-scrubbing,html.et-number-input-scrubbing *{cursor:ew-resize!important}@property --et-number-input-stepper-size{syntax: \"<length>\"; inherits: true; initial-value: 16px;}et-number-input{display:block;flex:1;min-inline-size:0;color:inherit}et-number-input[data-stepper]{display:flex;align-items:center;gap:8px}et-number-input .et-number-input-stepper{display:flex;align-items:center;gap:2px;flex:none}et-number-input .et-number-input-stepper-button{display:flex;align-items:center;justify-content:center;flex:none;inline-size:calc(var(--et-number-input-stepper-size) + 8px);block-size:calc(var(--et-number-input-stepper-size) + 8px);padding:0;border:none;border-radius:4px;background:transparent;color:var(--et-surface-color-muted-solid, currentColor);cursor:pointer;outline:none;touch-action:none}@media(pointer:fine){et-number-input .et-number-input-stepper-button{cursor:ew-resize}}et-number-input .et-number-input-stepper-button .et-icon{inline-size:var(--et-number-input-stepper-size);block-size:var(--et-number-input-stepper-size)}@media(hover:hover){et-number-input .et-number-input-stepper-button:hover{background:color-mix(in srgb,var(--et-surface-interaction-solid, currentColor) 12%,transparent);color:var(--et-surface-color-solid, currentColor)}}et-number-input .et-number-input-stepper-button:active{background:color-mix(in srgb,var(--et-surface-interaction-solid, currentColor) 20%,transparent)}et-number-input .et-number-input-stepper-button:disabled{cursor:default;background:transparent;color:inherit;opacity:.4}et-number-input .et-number-input-native{display:block;inline-size:100%;border:none;outline:none;background:transparent;font:inherit;color:inherit;caret-color:var(--et-theme-color-primary-solid, currentColor);padding:0;min-width:0;appearance:textfield}et-number-input .et-number-input-native::-webkit-outer-spin-button,et-number-input .et-number-input-native::-webkit-inner-spin-button{appearance:none;margin:0}et-number-input .et-number-input-native:not(:focus){overflow:hidden;text-overflow:ellipsis}et-number-input .et-number-input-native::placeholder{color:color-mix(in srgb,currentColor 46%,transparent)}et-number-input .et-number-input-native[data-text-align=start]{text-align:start}et-number-input .et-number-input-native[data-text-align=center]{text-align:center}et-number-input .et-number-input-native[data-text-align=end]{text-align:end}et-number-input[data-mixed] .et-number-input-native::placeholder{font-style:italic;color:color-mix(in srgb,currentColor 72%,transparent)}}\n"] }]
37115
+ }, template: "<input\n #nativeInput\n [disabled]=\"numberInputDir.disabled()\"\n [readOnly]=\"numberInputDir.readonly()\"\n [required]=\"numberInputDir.required()\"\n [placeholder]=\"numberInputDir.effectivePlaceholder()\"\n [attr.autocomplete]=\"numberInputDir.autocomplete() || null\"\n [attr.min]=\"numberInputDir.min() ?? null\"\n [attr.max]=\"numberInputDir.max() ?? null\"\n [attr.step]=\"numberInputDir.step() ?? null\"\n [attr.inputmode]=\"numberInputDir.inputMode()\"\n [attr.name]=\"numberInputDir.name() || null\"\n [attr.aria-invalid]=\"numberInputDir.shouldDisplayError() || null\"\n [attr.aria-describedby]=\"numberInputDir.describedBy() || null\"\n [attr.aria-label]=\"numberInputDir.ariaLabel() || null\"\n [attr.aria-labelledby]=\"numberInputDir.labelId() || null\"\n [attr.data-text-align]=\"numberInputDir.textAlign()\"\n (focus)=\"numberInputDir.focused.set(true)\"\n (blur)=\"numberInputDir.focused.set(false); numberInputDir.touched.set(true); numberInputDir.normalizeNativeText()\"\n class=\"et-number-input-native\"\n type=\"number\"\n/>\n\n@if (stepper()) {\n <div class=\"et-number-input-stepper\">\n <button\n [attr.aria-label]=\"resolvedDecrementLabel()\"\n [disabled]=\"!numberInputDir.canStepDown()\"\n (pointerdown)=\"startStepRepeat($event, -1)\"\n (pointerup)=\"stopStepRepeat()\"\n (pointercancel)=\"stopStepRepeat()\"\n (lostpointercapture)=\"stopStepRepeat()\"\n class=\"et-number-input-stepper-button\"\n type=\"button\"\n tabindex=\"-1\"\n >\n <i aria-hidden=\"true\" etIcon=\"et-minus\"></i>\n </button>\n <button\n [attr.aria-label]=\"resolvedIncrementLabel()\"\n [disabled]=\"!numberInputDir.canStepUp()\"\n (pointerdown)=\"startStepRepeat($event, 1)\"\n (pointerup)=\"stopStepRepeat()\"\n (pointercancel)=\"stopStepRepeat()\"\n (lostpointercapture)=\"stopStepRepeat()\"\n class=\"et-number-input-stepper-button\"\n type=\"button\"\n tabindex=\"-1\"\n >\n <i aria-hidden=\"true\" etIcon=\"et-plus\"></i>\n </button>\n </div>\n}\n", styles: ["@layer components{html.et-number-input-scrubbing,html.et-number-input-scrubbing *{cursor:ew-resize!important}@property --et-number-input-stepper-size{syntax: \"<length>\"; inherits: true; initial-value: 16px;}et-number-input{display:block;flex:1;min-inline-size:0;color:inherit}et-number-input[data-stepper]{display:flex;align-items:center;gap:8px}et-number-input .et-number-input-stepper{display:flex;align-items:center;gap:2px;flex:none}et-number-input .et-number-input-stepper-button{display:flex;align-items:center;justify-content:center;flex:none;inline-size:calc(var(--et-number-input-stepper-size) + 8px);block-size:calc(var(--et-number-input-stepper-size) + 8px);padding:0;border:none;border-radius:4px;background:transparent;color:var(--et-surface-color-muted-solid, currentColor);cursor:pointer;outline:none;touch-action:none}@media(pointer:fine){et-number-input .et-number-input-stepper-button{cursor:ew-resize}}et-number-input .et-number-input-stepper-button .et-icon{inline-size:var(--et-number-input-stepper-size);block-size:var(--et-number-input-stepper-size)}@media(hover:hover){et-number-input .et-number-input-stepper-button:hover{background:color-mix(in srgb,var(--et-surface-interaction-solid, currentColor) 12%,transparent);color:var(--et-surface-color-solid, currentColor)}}et-number-input .et-number-input-stepper-button:active{background:color-mix(in srgb,var(--et-surface-interaction-solid, currentColor) 20%,transparent)}et-number-input .et-number-input-stepper-button:disabled{cursor:default;background:transparent;color:inherit;opacity:.4}et-number-input .et-number-input-native{display:block;inline-size:100%;border:none;outline:none;background:transparent;font:inherit;color:inherit;caret-color:var(--et-theme-color-primary-solid, currentColor);padding:0;min-width:0;appearance:textfield}et-number-input .et-number-input-native::-webkit-outer-spin-button,et-number-input .et-number-input-native::-webkit-inner-spin-button{appearance:none;margin:0}et-number-input .et-number-input-native:not(:focus){overflow:hidden;text-overflow:ellipsis}et-number-input .et-number-input-native::placeholder{color:color-mix(in srgb,currentColor 46%,transparent)}et-number-input .et-number-input-native[data-text-align=start]{text-align:start}et-number-input .et-number-input-native[data-text-align=center]{text-align:center}et-number-input .et-number-input-native[data-text-align=end]{text-align:end}et-number-input[data-mixed] .et-number-input-native::placeholder{font-style:italic;color:color-mix(in srgb,currentColor 72%,transparent)}}\n"] }]
36978
37116
  }], ctorParameters: () => [], propDecorators: { stepper: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepper", required: false }] }], incrementLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "incrementLabel", required: false }] }], decrementLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "decrementLabel", required: false }] }], nativeInput: [{ type: i0.ViewChild, args: ['nativeInput', { isSignal: true }] }] } });
36979
37117
 
36980
37118
  class PasswordInputComponent {
@@ -37238,7 +37376,8 @@ const findLanguagesError = (languages) => {
37238
37376
  * ```
37239
37377
  */
37240
37378
  const requiredLanguages = (path, { codes, message }) => validate(path, ({ value }) => {
37241
- const missing = (typeof codes === 'function' ? codes() : codes).filter((code) => (value()[code] ?? '').trim().length === 0);
37379
+ const record = value() ?? {};
37380
+ const missing = (typeof codes === 'function' ? codes() : codes).filter((code) => (record[code] ?? '').trim().length === 0);
37242
37381
  if (missing.length === 0)
37243
37382
  return undefined;
37244
37383
  const text = typeof message === 'function' ? message(missing) : (message ?? `Missing translations: ${missing.join(', ')}`);
@@ -39318,6 +39457,31 @@ const HTML_ATTRIBUTE = /(\s+)([^\s/>=]+)((?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+))?
39318
39457
  const renameStyleAttribute = (attribute, ...[space, name, value]) => name?.toLowerCase() === 'style' ? `${space}${INERT_STYLE_ATTRIBUTE}${value}` : attribute;
39319
39458
  const renameStyleAttributes = (html) => html.replace(HTML_START_TAG, (tag) => tag.replace(HTML_ATTRIBUTE, renameStyleAttribute));
39320
39459
  const restoreStyleAttributes = (html) => html.replaceAll(` ${INERT_STYLE_ATTRIBUTE}="`, ' style="');
39460
+ const stripPastedAlignment = (body, renderer) => {
39461
+ // eslint-disable-next-line ethlete/no-dom-query -- parsed clipboard document, not the editor's DOM
39462
+ for (const el of body.querySelectorAll(`[${INERT_STYLE_ATTRIBUTE}], [class*="${ALIGN_CLASS_PREFIX}"]`)) {
39463
+ renderer.removeAttribute(el, INERT_STYLE_ATTRIBUTE);
39464
+ for (const name of [...el.classList]) {
39465
+ if (name.startsWith(ALIGN_CLASS_PREFIX))
39466
+ renderer.removeClass(el, name);
39467
+ }
39468
+ }
39469
+ };
39470
+ const takeTextBeforeCaret = (editable, text) => {
39471
+ if (!editable?.range.collapsed)
39472
+ return null;
39473
+ const { startContainer: node, startOffset: end } = editable.range;
39474
+ if (node.nodeType !== Node.TEXT_NODE || !node.data.slice(0, end).endsWith(text))
39475
+ return null;
39476
+ const start = end - text.length;
39477
+ node.deleteData(start, text.length);
39478
+ editable.selection.collapse(node, start);
39479
+ return () => {
39480
+ node.insertData(start, text);
39481
+ editable.selection.collapse(node, end);
39482
+ };
39483
+ };
39484
+ const AUTOFORMAT_CHARS = ' *_~`';
39321
39485
  const collectTextNodes = (root) => {
39322
39486
  const walker = root.ownerDocument.createTreeWalker(root, NodeFilter.SHOW_TEXT);
39323
39487
  const nodes = [];
@@ -39543,7 +39707,7 @@ class RichTextEditorDirective extends FieldStateControlDirective {
39543
39707
  const markdown = this.value() ?? '';
39544
39708
  if (markdown === this.lastEmittedMarkdown)
39545
39709
  return;
39546
- this.renderExternalValue(markdown);
39710
+ untracked(() => this.renderExternalValue(markdown));
39547
39711
  });
39548
39712
  }
39549
39713
  /**
@@ -39623,9 +39787,15 @@ class RichTextEditorDirective extends FieldStateControlDirective {
39623
39787
  }
39624
39788
  /** @internal Restarts the history: an outside write is a new document, so undo must not reach back into the previous one's states. */
39625
39789
  renderExternalValue(markdown = this.value() ?? '') {
39790
+ const root = this.editorDom.root();
39791
+ const caret = root && root.ownerDocument.activeElement === root ? this.editorDom.readSelectionOffsets() : null;
39626
39792
  if (!this.writeValueToDom(markdown))
39627
39793
  return;
39628
39794
  this.history.reset(markdown);
39795
+ this.pendingMarks.set(null);
39796
+ if (caret)
39797
+ this.editorDom.restoreSelectionOffsets(caret);
39798
+ this.refreshActiveMarks();
39629
39799
  }
39630
39800
  refreshActiveMarks() {
39631
39801
  const pending = this.pendingMarks();
@@ -39811,6 +39981,8 @@ class RichTextEditorDirective extends FieldStateControlDirective {
39811
39981
  const body = new DOMParser().parseFromString(renameStyleAttributes(html), 'text/html').body;
39812
39982
  // eslint-disable-next-line ethlete/no-dom-query -- clipboard HTML (e.g. from Word) embeds <style> blocks whose CSS text would survive the tag-strip as plain text
39813
39983
  body.querySelectorAll('style, script, noscript, meta, link, title').forEach((junk) => junk.remove());
39984
+ if (!this.toolDefs.has(RICH_TEXT_EDITOR_TOOLS.ALIGN))
39985
+ stripPastedAlignment(body, this.renderer);
39814
39986
  if (this.editorDom.markStates()?.codeBlock)
39815
39987
  return this.pasteIntoCodeBlock(clipboardPlainText(body));
39816
39988
  const codec = this.tokenCodec();
@@ -39891,7 +40063,11 @@ class RichTextEditorDirective extends FieldStateControlDirective {
39891
40063
  }
39892
40064
  listenToEditable(element) {
39893
40065
  const listeners = [
39894
- this.renderer.listen(element, 'input', () => this.syncFromDom()),
40066
+ this.renderer.listen(element, 'input', (event) => {
40067
+ if (!event.isComposing)
40068
+ this.syncFromDom();
40069
+ }),
40070
+ this.renderer.listen(element, 'compositionend', (event) => this.finishComposition(event.data)),
39895
40071
  this.renderer.listen(element, 'beforeinput', (event) => this.interceptBeforeInput(event)),
39896
40072
  this.renderer.listen(element, 'keydown', (event) => this.interceptKeydown(event)),
39897
40073
  this.renderer.listen(element, 'paste', (event) => this.interceptPaste(event)),
@@ -39908,6 +40084,9 @@ class RichTextEditorDirective extends FieldStateControlDirective {
39908
40084
  return () => listeners.forEach((off) => off());
39909
40085
  }
39910
40086
  interceptKeydown(event) {
40087
+ // The keystrokes of an IME composition (Safari reports its commit as Enter) belong to the IME.
40088
+ if (event.isComposing || event.keyCode === 229)
40089
+ return;
39911
40090
  // History first, and always prevented: the native contenteditable undo stack must never run,
39912
40091
  // since paste normalization and autoformat rewrite the DOM behind its back and it would restore
39913
40092
  // a state the value model never had. Ctrl/Cmd+Z undoes, Ctrl+Y and Ctrl/Cmd+Shift+Z redo.
@@ -40057,6 +40236,7 @@ class RichTextEditorDirective extends FieldStateControlDirective {
40057
40236
  this.redo();
40058
40237
  break;
40059
40238
  case 'insertText':
40239
+ case 'insertFromComposition':
40060
40240
  if (event.data !== null && this.handleAutoformat(event.data)) {
40061
40241
  event.preventDefault();
40062
40242
  break;
@@ -40067,6 +40247,23 @@ class RichTextEditorDirective extends FieldStateControlDirective {
40067
40247
  break;
40068
40248
  }
40069
40249
  }
40250
+ finishComposition(data) {
40251
+ if (!this.canEdit())
40252
+ return;
40253
+ const pending = this.pendingMarks();
40254
+ if (pending !== null && data && takeTextBeforeCaret(this.editorDom.getSelection(), data)) {
40255
+ this.pendingMarks.set(null);
40256
+ this.runCommand(() => this.editorDom.insertInlineText(data, pending));
40257
+ return;
40258
+ }
40259
+ const last = data.at(-1);
40260
+ const restore = last && AUTOFORMAT_CHARS.includes(last) && takeTextBeforeCaret(this.editorDom.getSelection(), last);
40261
+ if (restore && last && this.handleAutoformat(last))
40262
+ return;
40263
+ if (restore)
40264
+ restore();
40265
+ this.syncFromDom();
40266
+ }
40070
40267
  warnAboutMissingTools() {
40071
40268
  const warned = new Set();
40072
40269
  effect(() => {
@@ -40865,6 +41062,8 @@ class RichTextEditorTriggersDirective {
40865
41062
  this.openOrReposition();
40866
41063
  }
40867
41064
  interceptPopupKeys(event) {
41065
+ if (event.isComposing || event.keyCode === 229)
41066
+ return;
40868
41067
  if (event.key === 'Backspace' && this.deletePrecedingChip()) {
40869
41068
  event.preventDefault();
40870
41069
  event.stopPropagation();
@@ -41483,7 +41682,9 @@ class MenuDirective {
41483
41682
  if (this.parent?.openSubmenu() === this) {
41484
41683
  this.parent.openSubmenu.set(null);
41485
41684
  }
41486
- this.overlayRef()?.close();
41685
+ const overlayRef = this.overlayRef();
41686
+ this.overlayRef.set(null);
41687
+ overlayRef?.close();
41487
41688
  });
41488
41689
  if (ngDevMode) {
41489
41690
  afterNextRender(() => {
@@ -41636,7 +41837,8 @@ class MenuDirective {
41636
41837
  case 'ArrowLeft': {
41637
41838
  const opensSubmenu = (event.key === 'ArrowRight') !== this.isRtl();
41638
41839
  if (opensSubmenu) {
41639
- const submenu = this.activeItem()?.submenu ?? null;
41840
+ const activeItem = this.activeItem();
41841
+ const submenu = activeItem && !activeItem.isDisabled() ? activeItem.submenu : null;
41640
41842
  if (submenu) {
41641
41843
  event.preventDefault();
41642
41844
  submenu.show({ source: 'keyboard' });
@@ -41667,13 +41869,23 @@ class MenuDirective {
41667
41869
  if (searchFocused) {
41668
41870
  return;
41669
41871
  }
41872
+ if (event.key === ' ' && !search && this.typeahead.isRunning()) {
41873
+ const match = this.findTypeaheadMatch(this.typeahead.append(event.key));
41874
+ event.preventDefault();
41875
+ if (match) {
41876
+ this.setActiveItem(match);
41877
+ }
41878
+ return;
41879
+ }
41670
41880
  const item = this.activeItem();
41671
41881
  if (!item) {
41672
41882
  return;
41673
41883
  }
41674
41884
  event.preventDefault();
41675
41885
  if (item.submenu) {
41676
- item.submenu.show({ source: 'keyboard' });
41886
+ if (!item.isDisabled()) {
41887
+ item.submenu.show({ source: 'keyboard' });
41888
+ }
41677
41889
  }
41678
41890
  else {
41679
41891
  item.activateFromKeyboard(event.key === 'Enter' ? 'keyboard-enter' : 'keyboard-space');
@@ -41808,22 +42020,25 @@ class MenuDirective {
41808
42020
  return;
41809
42021
  }
41810
42022
  const current = this.activeItem();
41811
- const index = current ? items.indexOf(current) : -1;
41812
- if (index === -1) {
42023
+ const sorted = this.sortedItems();
42024
+ const position = current ? sorted.indexOf(current) : -1;
42025
+ if (position === -1) {
41813
42026
  this.setActiveToEdge(delta === 1 ? 'first' : 'last');
41814
42027
  return;
41815
42028
  }
41816
- const nextIndex = index + delta;
41817
- if (search && (nextIndex < 0 || nextIndex >= items.length)) {
42029
+ let next;
42030
+ for (let index = position + delta; index >= 0 && index < sorted.length && !next; index += delta) {
42031
+ next = sorted[index]?.isDisabled() ? undefined : sorted[index];
42032
+ }
42033
+ if (!next && search) {
41818
42034
  this.activeItem.set(null);
41819
42035
  search.focus();
41820
42036
  return;
41821
42037
  }
41822
- if (!this.loop() && (nextIndex < 0 || nextIndex >= items.length)) {
42038
+ if (!next && !this.loop()) {
41823
42039
  return;
41824
42040
  }
41825
- const wrappedIndex = (nextIndex + items.length) % items.length;
41826
- const next = items[wrappedIndex];
42041
+ next ??= delta === 1 ? items[0] : items.at(-1);
41827
42042
  if (next) {
41828
42043
  this.setActiveItem(next);
41829
42044
  }
@@ -41873,6 +42088,15 @@ class MenuDirective {
41873
42088
  };
41874
42089
  const overlayRef = this.overlayManager.open(OverlayTemplateHostComponent, config);
41875
42090
  this.overlayRef.set(overlayRef);
42091
+ overlayRef
42092
+ .beforeClosed()
42093
+ .pipe(take(1), tap(() => {
42094
+ if (this.overlayRef() === overlayRef && this.open()) {
42095
+ this.openSubmenu()?.hide();
42096
+ this.open.set(false);
42097
+ }
42098
+ }), takeUntilDestroyed(this.destroyRef))
42099
+ .subscribe();
41876
42100
  if (this.isRoot) {
41877
42101
  this.attachRootInteractionListeners();
41878
42102
  }
@@ -42310,7 +42534,7 @@ class MenuItemDirective {
42310
42534
  return -1;
42311
42535
  }
42312
42536
  const active = owner.activeItem();
42313
- if (active) {
42537
+ if (active && !active.isDisabled()) {
42314
42538
  return active === this ? 0 : -1;
42315
42539
  }
42316
42540
  return owner.enabledItems()[0] === this ? 0 : -1;
@@ -47420,6 +47644,34 @@ const createVirtualWindow = (config) => {
47420
47644
  const containerDimensions = signalElementDimensions(config.container);
47421
47645
  const viewportSize = computed(() => containerDimensions().client?.height ?? 0, /* @ts-ignore */
47422
47646
  ...(ngDevMode ? [{ debugName: "viewportSize" }] : /* istanbul ignore next */ []));
47647
+ const extras = computed(() => [...(config.extraItemHeights?.() ?? new Map())]
47648
+ .filter(([, height]) => height > 0)
47649
+ .sort(([a], [b]) => a - b), /* @ts-ignore */
47650
+ ...(ngDevMode ? [{ debugName: "extras" }] : /* istanbul ignore next */ []));
47651
+ const totalExtra = computed(() => extras().reduce((sum, [, height]) => sum + height, 0), /* @ts-ignore */
47652
+ ...(ngDevMode ? [{ debugName: "totalExtra" }] : /* istanbul ignore next */ []));
47653
+ const extraBefore = (index) => {
47654
+ let sum = 0;
47655
+ for (const [extraIndex, height] of extras()) {
47656
+ if (extraIndex >= index)
47657
+ break;
47658
+ sum += height;
47659
+ }
47660
+ return sum;
47661
+ };
47662
+ const topOf = (index) => index * itemHeight() + extraBefore(index);
47663
+ // `floor` finds the item an offset falls on, `ceil` the end of the range an edge at that offset closes.
47664
+ const indexAt = (offset, round) => {
47665
+ const height = itemHeight();
47666
+ let before = 0;
47667
+ for (const [extraIndex, extra] of extras()) {
47668
+ if (offset < extraIndex * height + before + height + extra) {
47669
+ return Math.min(round((offset - before) / height), round === Math.ceil ? extraIndex + 1 : extraIndex);
47670
+ }
47671
+ before += extra;
47672
+ }
47673
+ return round((offset - before) / height);
47674
+ };
47423
47675
  // a scroll request that arrived before the container existed (e.g. scrolling the selected
47424
47676
  // option into view while the panel is still mounting) - replayed once it does
47425
47677
  let pendingScrollIndex = null;
@@ -47429,10 +47681,9 @@ const createVirtualWindow = (config) => {
47429
47681
  pendingScrollIndex = index;
47430
47682
  return;
47431
47683
  }
47432
- const height = itemHeight();
47433
47684
  const viewport = viewportSize() || FALLBACK_VIEWPORT_SIZE;
47434
- const rowTop = index * height;
47435
- const rowBottom = rowTop + height;
47685
+ const rowTop = topOf(index);
47686
+ const rowBottom = rowTop + itemHeight();
47436
47687
  const current = container.scrollTop;
47437
47688
  let next = current;
47438
47689
  if (rowTop < current) {
@@ -47469,21 +47720,20 @@ const createVirtualWindow = (config) => {
47469
47720
  if (!count || !config.container()) {
47470
47721
  return { start: 0, end: count };
47471
47722
  }
47472
- const height = itemHeight();
47473
47723
  const viewport = viewportSize() || FALLBACK_VIEWPORT_SIZE;
47474
47724
  const offset = scrollOffset();
47475
47725
  // clamp into the item range: when the count shrinks while scrolled far down (filtering a
47476
47726
  // long list), the stale offset would otherwise start past the end - the browser's own
47477
47727
  // clamp-scroll event arrives a frame later, but the window must never be empty until then
47478
47728
  const rows = overscan();
47479
- const start = Math.min(Math.max(0, Math.floor(offset / height) - rows), Math.max(0, count - 1));
47480
- const end = Math.min(count, Math.max(Math.ceil((offset + viewport) / height) + rows, start + 1));
47729
+ const start = Math.min(Math.max(0, indexAt(offset, Math.floor) - rows), Math.max(0, count - 1));
47730
+ const end = Math.min(count, Math.max(indexAt(offset + viewport, Math.ceil) + rows, start + 1));
47481
47731
  return { start, end };
47482
47732
  }, /* @ts-ignore */
47483
47733
  ...(ngDevMode ? [{ debugName: "range" }] : /* istanbul ignore next */ []));
47484
- const paddingTop = computed(() => range().start * itemHeight(), /* @ts-ignore */
47734
+ const paddingTop = computed(() => topOf(range().start), /* @ts-ignore */
47485
47735
  ...(ngDevMode ? [{ debugName: "paddingTop" }] : /* istanbul ignore next */ []));
47486
- const paddingBottom = computed(() => Math.max(0, (config.itemCount() - range().end) * itemHeight()), /* @ts-ignore */
47736
+ const paddingBottom = computed(() => Math.max(0, config.itemCount() * itemHeight() + totalExtra() - topOf(range().end)), /* @ts-ignore */
47487
47737
  ...(ngDevMode ? [{ debugName: "paddingBottom" }] : /* istanbul ignore next */ []));
47488
47738
  const measureItem = (element) => {
47489
47739
  const height = element.offsetHeight;
@@ -47586,6 +47836,12 @@ class SelectDirective extends FieldStateControlDirective {
47586
47836
  */
47587
47837
  this.valueKey = input(null, /* @ts-ignore */
47588
47838
  ...(ngDevMode ? [{ debugName: "valueKey" }] : /* istanbul ignore next */ []));
47839
+ /**
47840
+ * Labels a value no loaded option carries (e.g. a stored id whose option is on a page not yet
47841
+ * fetched): the trigger text in single mode, the chip label in multi mode.
47842
+ */
47843
+ this.displayWith = input(null, /* @ts-ignore */
47844
+ ...(ngDevMode ? [{ debugName: "displayWith" }] : /* istanbul ignore next */ []));
47589
47845
  this.filterModeInput = input(SELECT_FILTER_MODES.INTERNAL, { ...(ngDevMode ? { debugName: "filterModeInput" } : /* istanbul ignore next */ {}), alias: 'filterMode' });
47590
47846
  /** Enter with a search query that matches no option commits the raw query string as the value. */
47591
47847
  this.allowCustomValues = input(false, { ...(ngDevMode ? { debugName: "allowCustomValues" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
@@ -47999,10 +48255,12 @@ class SelectDirective extends FieldStateControlDirective {
47999
48255
  const items = this.sortedItems();
48000
48256
  const cache = this.labelCache();
48001
48257
  const valuesMatch = this.valuesMatch();
48258
+ const displayWith = this.displayWith();
48002
48259
  return values.map((entryValue) => {
48003
48260
  const item = items.find((candidate) => valuesMatch(candidate.value(), entryValue)) ?? null;
48004
48261
  const label = item?.label() ||
48005
48262
  this.findCachedLabel(cache, entryValue) ||
48263
+ displayWith?.(entryValue) ||
48006
48264
  (typeof entryValue === 'string' && entryValue !== '' ? entryValue : null);
48007
48265
  return { value: entryValue, label, item };
48008
48266
  });
@@ -48379,7 +48637,7 @@ class SelectDirective extends FieldStateControlDirective {
48379
48637
  }
48380
48638
  /** @internal A rendered virtual row attaches its element to its item while it is windowed in. */
48381
48639
  attachVirtualOptionElement(item, element) {
48382
- const entry = this.dataItemRegistry.get(item.value());
48640
+ const entry = this.dataItemRegistry.get(this.valueIdentity()(item.value()));
48383
48641
  if (!entry || entry.item !== item) {
48384
48642
  return;
48385
48643
  }
@@ -48392,7 +48650,7 @@ class SelectDirective extends FieldStateControlDirective {
48392
48650
  }
48393
48651
  /** @internal */
48394
48652
  detachVirtualOptionElement(item, element) {
48395
- const entry = this.dataItemRegistry.get(item.value());
48653
+ const entry = this.dataItemRegistry.get(this.valueIdentity()(item.value()));
48396
48654
  if (!entry || entry.item !== item || entry.element() !== element) {
48397
48655
  return;
48398
48656
  }
@@ -48593,7 +48851,7 @@ class SelectDirective extends FieldStateControlDirective {
48593
48851
  return;
48594
48852
  }
48595
48853
  default: {
48596
- if (event.key.length !== 1 || searchFocused || this.multiple()) {
48854
+ if (event.key.length !== 1 || searchFocused || this.multiple() || this.pickOnly()) {
48597
48855
  return;
48598
48856
  }
48599
48857
  const match = this.findTypeaheadMatch(event.key, this.selectedItems()[0] ?? null);
@@ -48625,6 +48883,10 @@ class SelectDirective extends FieldStateControlDirective {
48625
48883
  if (value === null) {
48626
48884
  return false;
48627
48885
  }
48886
+ const matchingOption = this.findOptionByLabel(value);
48887
+ if (matchingOption) {
48888
+ return this.commitMatchingOption(matchingOption);
48889
+ }
48628
48890
  this.labelCache.update((cache) => new Map(cache).set(value, value));
48629
48891
  if (this.multiple()) {
48630
48892
  const current = this.value();
@@ -48642,6 +48904,37 @@ class SelectDirective extends FieldStateControlDirective {
48642
48904
  }
48643
48905
  return true;
48644
48906
  }
48907
+ findOptionByLabel(label) {
48908
+ const lowered = label.toLowerCase();
48909
+ return this.visibleItems().find((item) => !item.custom?.() && !item.disabled() && item.label().toLowerCase() === lowered);
48910
+ }
48911
+ commitMatchingOption(item) {
48912
+ if (this.mixed()) {
48913
+ const committed = this.commitMixedOption(item);
48914
+ if (committed && this.multiple()) {
48915
+ this.registeredSearch()?.clear();
48916
+ }
48917
+ return committed;
48918
+ }
48919
+ if (!this.multiple()) {
48920
+ this.pickSingleOption(item);
48921
+ return true;
48922
+ }
48923
+ const current = this.value();
48924
+ const values = Array.isArray(current) ? current : [];
48925
+ const itemValue = item.value();
48926
+ if (this.includesValue(values, itemValue)) {
48927
+ return false;
48928
+ }
48929
+ if (this.pickOnly()) {
48930
+ this.pickOption.emit(itemValue);
48931
+ }
48932
+ else {
48933
+ this.writeValue([...values, itemValue]);
48934
+ }
48935
+ this.registeredSearch()?.clear();
48936
+ return true;
48937
+ }
48645
48938
  commitOptionWhileClosed(item) {
48646
48939
  if (this.disabled() || this.readonly() || item.disabled()) {
48647
48940
  return;
@@ -48650,6 +48943,9 @@ class SelectDirective extends FieldStateControlDirective {
48650
48943
  this.commitMixedOption(item);
48651
48944
  return;
48652
48945
  }
48946
+ if (this.selectedItems()[0] === item) {
48947
+ return;
48948
+ }
48653
48949
  this.pickSingleOption(item);
48654
48950
  }
48655
48951
  findTypeaheadMatch(character, from) {
@@ -48780,7 +49076,7 @@ class SelectDirective extends FieldStateControlDirective {
48780
49076
  this.hide();
48781
49077
  }
48782
49078
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SelectDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
48783
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.6", type: SelectDirective, isStandalone: true, selector: "[etSelect]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, mixed: { classPropertyName: "mixed", publicName: "mixed", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, mixedLabel: { classPropertyName: "mixedLabel", publicName: "mixedLabel", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, pending: { classPropertyName: "pending", publicName: "pending", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null }, valueKey: { classPropertyName: "valueKey", publicName: "valueKey", isSignal: true, isRequired: false, transformFunction: null }, filterModeInput: { classPropertyName: "filterModeInput", publicName: "filterMode", isSignal: true, isRequired: false, transformFunction: null }, allowCustomValues: { classPropertyName: "allowCustomValues", publicName: "allowCustomValues", isSignal: true, isRequired: false, transformFunction: null }, separators: { classPropertyName: "separators", publicName: "separators", isSignal: true, isRequired: false, transformFunction: null }, normalizeValue: { classPropertyName: "normalizeValue", publicName: "normalizeValue", isSignal: true, isRequired: false, transformFunction: null }, commitCustomValueOnClose: { classPropertyName: "commitCustomValueOnClose", publicName: "commitCustomValueOnClose", isSignal: true, isRequired: false, transformFunction: null }, maxSelection: { classPropertyName: "maxSelection", publicName: "maxSelection", isSignal: true, isRequired: false, transformFunction: null }, allowAddNew: { classPropertyName: "allowAddNew", publicName: "allowAddNew", isSignal: true, isRequired: false, transformFunction: null }, loadingInput: { classPropertyName: "loadingInput", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadErrorInput: { classPropertyName: "loadErrorInput", publicName: "loadError", isSignal: true, isRequired: false, transformFunction: null }, hasMoreItemsInput: { classPropertyName: "hasMoreItemsInput", publicName: "hasMoreItems", isSignal: true, isRequired: false, transformFunction: null }, mirrorPanelWidth: { classPropertyName: "mirrorPanelWidth", publicName: "mirrorPanelWidth", isSignal: true, isRequired: false, transformFunction: null }, pickOnly: { classPropertyName: "pickOnly", publicName: "pickOnly", isSignal: true, isRequired: false, transformFunction: null }, selectAll: { classPropertyName: "selectAll", publicName: "selectAll", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", mixed: "mixedChange", touched: "touchedChange", open: "openChange", touch: "touch", queryChange: "queryChange", loadMore: "loadMore", addNew: "addNew", pickOption: "pickOption", afterOpen: "afterOpen", afterClose: "afterClose" }, host: { properties: { "attr.data-select-open": "open() || null", "attr.data-mixed": "mixed() || null" } }, exportAs: ["etSelect"], usesInheritance: true, ngImport: i0 }); }
49079
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.6", type: SelectDirective, isStandalone: true, selector: "[etSelect]", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, mixed: { classPropertyName: "mixed", publicName: "mixed", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, mixedLabel: { classPropertyName: "mixedLabel", publicName: "mixedLabel", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, pending: { classPropertyName: "pending", publicName: "pending", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null }, valueKey: { classPropertyName: "valueKey", publicName: "valueKey", isSignal: true, isRequired: false, transformFunction: null }, displayWith: { classPropertyName: "displayWith", publicName: "displayWith", isSignal: true, isRequired: false, transformFunction: null }, filterModeInput: { classPropertyName: "filterModeInput", publicName: "filterMode", isSignal: true, isRequired: false, transformFunction: null }, allowCustomValues: { classPropertyName: "allowCustomValues", publicName: "allowCustomValues", isSignal: true, isRequired: false, transformFunction: null }, separators: { classPropertyName: "separators", publicName: "separators", isSignal: true, isRequired: false, transformFunction: null }, normalizeValue: { classPropertyName: "normalizeValue", publicName: "normalizeValue", isSignal: true, isRequired: false, transformFunction: null }, commitCustomValueOnClose: { classPropertyName: "commitCustomValueOnClose", publicName: "commitCustomValueOnClose", isSignal: true, isRequired: false, transformFunction: null }, maxSelection: { classPropertyName: "maxSelection", publicName: "maxSelection", isSignal: true, isRequired: false, transformFunction: null }, allowAddNew: { classPropertyName: "allowAddNew", publicName: "allowAddNew", isSignal: true, isRequired: false, transformFunction: null }, loadingInput: { classPropertyName: "loadingInput", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, loadErrorInput: { classPropertyName: "loadErrorInput", publicName: "loadError", isSignal: true, isRequired: false, transformFunction: null }, hasMoreItemsInput: { classPropertyName: "hasMoreItemsInput", publicName: "hasMoreItems", isSignal: true, isRequired: false, transformFunction: null }, mirrorPanelWidth: { classPropertyName: "mirrorPanelWidth", publicName: "mirrorPanelWidth", isSignal: true, isRequired: false, transformFunction: null }, pickOnly: { classPropertyName: "pickOnly", publicName: "pickOnly", isSignal: true, isRequired: false, transformFunction: null }, selectAll: { classPropertyName: "selectAll", publicName: "selectAll", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", mixed: "mixedChange", touched: "touchedChange", open: "openChange", touch: "touch", queryChange: "queryChange", loadMore: "loadMore", addNew: "addNew", pickOption: "pickOption", afterOpen: "afterOpen", afterClose: "afterClose" }, host: { properties: { "attr.data-select-open": "open() || null", "attr.data-mixed": "mixed() || null" } }, exportAs: ["etSelect"], usesInheritance: true, ngImport: i0 }); }
48784
49080
  }
48785
49081
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SelectDirective, decorators: [{
48786
49082
  type: Directive,
@@ -48792,7 +49088,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
48792
49088
  '[attr.data-mixed]': 'mixed() || null',
48793
49089
  },
48794
49090
  }]
48795
- }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], mixed: [{ type: i0.Input, args: [{ isSignal: true, alias: "mixed", required: false }] }, { type: i0.Output, args: ["mixedChange"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], mixedLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "mixedLabel", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], pending: [{ type: i0.Input, args: [{ isSignal: true, alias: "pending", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "compareWith", required: false }] }], valueKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueKey", required: false }] }], filterModeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterMode", required: false }] }], allowCustomValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowCustomValues", required: false }] }], separators: [{ type: i0.Input, args: [{ isSignal: true, alias: "separators", required: false }] }], normalizeValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "normalizeValue", required: false }] }], commitCustomValueOnClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "commitCustomValueOnClose", required: false }] }], maxSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSelection", required: false }] }], allowAddNew: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowAddNew", required: false }] }], loadingInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadErrorInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadError", required: false }] }], hasMoreItemsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMoreItems", required: false }] }], mirrorPanelWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "mirrorPanelWidth", required: false }] }], pickOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "pickOnly", required: false }] }], selectAll: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAll", required: false }] }], touch: [{ type: i0.Output, args: ["touch"] }], queryChange: [{ type: i0.Output, args: ["queryChange"] }], loadMore: [{ type: i0.Output, args: ["loadMore"] }], addNew: [{ type: i0.Output, args: ["addNew"] }], pickOption: [{ type: i0.Output, args: ["pickOption"] }], afterOpen: [{ type: i0.Output, args: ["afterOpen"] }], afterClose: [{ type: i0.Output, args: ["afterClose"] }] } });
49091
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], mixed: [{ type: i0.Input, args: [{ isSignal: true, alias: "mixed", required: false }] }, { type: i0.Output, args: ["mixedChange"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], mixedLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "mixedLabel", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], pending: [{ type: i0.Input, args: [{ isSignal: true, alias: "pending", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "compareWith", required: false }] }], valueKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueKey", required: false }] }], displayWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayWith", required: false }] }], filterModeInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterMode", required: false }] }], allowCustomValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowCustomValues", required: false }] }], separators: [{ type: i0.Input, args: [{ isSignal: true, alias: "separators", required: false }] }], normalizeValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "normalizeValue", required: false }] }], commitCustomValueOnClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "commitCustomValueOnClose", required: false }] }], maxSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSelection", required: false }] }], allowAddNew: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowAddNew", required: false }] }], loadingInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], loadErrorInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadError", required: false }] }], hasMoreItemsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMoreItems", required: false }] }], mirrorPanelWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "mirrorPanelWidth", required: false }] }], pickOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "pickOnly", required: false }] }], selectAll: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAll", required: false }] }], touch: [{ type: i0.Output, args: ["touch"] }], queryChange: [{ type: i0.Output, args: ["queryChange"] }], loadMore: [{ type: i0.Output, args: ["loadMore"] }], addNew: [{ type: i0.Output, args: ["addNew"] }], pickOption: [{ type: i0.Output, args: ["pickOption"] }], afterOpen: [{ type: i0.Output, args: ["afterOpen"] }], afterClose: [{ type: i0.Output, args: ["afterClose"] }] } });
48796
49092
 
48797
49093
  /**
48798
49094
  * The "Select all" row of a multi select (`selectAll`). Place it first inside the listbox; it takes
@@ -49460,8 +49756,11 @@ class SelectSearchDirective {
49460
49756
  }
49461
49757
  event.preventDefault();
49462
49758
  this.clear();
49463
- for (const part of parts) {
49464
- select.commitCustomValue(part);
49759
+ const refused = parts.filter((part) => part.trim() && !select.commitCustomValue(part));
49760
+ const pending = refused.map((part) => part.trim()).join(' ');
49761
+ if (pending) {
49762
+ this.query.set(pending);
49763
+ select.queryChange.emit(pending);
49465
49764
  }
49466
49765
  }
49467
49766
  handleFocus() {
@@ -50443,7 +50742,7 @@ class SelectComponent {
50443
50742
  return () => injector.get(SelectDirective).focus({ preventScroll: true });
50444
50743
  },
50445
50744
  },
50446
- ], hostDirectives: [{ directive: SelectDirective, inputs: ["value", "value", "mixed", "mixed", "touched", "touched", "open", "open", "multiple", "multiple", "placeholder", "placeholder", "mixedLabel", "mixedLabel", "disabled", "disabled", "readonly", "readonly", "invalid", "invalid", "errors", "errors", "required", "required", "name", "name", "maxLength", "maxLength", "pending", "pending", "options", "options", "compareWith", "compareWith", "valueKey", "valueKey", "filterMode", "filterMode", "allowCustomValues", "allowCustomValues", "separators", "separators", "normalizeValue", "normalizeValue", "commitCustomValueOnClose", "commitCustomValueOnClose", "maxSelection", "maxSelection", "allowAddNew", "allowAddNew", "loading", "loading", "loadError", "loadError", "hasMoreItems", "hasMoreItems", "pickOnly", "pickOnly", "selectAll", "selectAll", "mirrorPanelWidth", "mirrorPanelWidth", "aria-label", "aria-label", "aria-labelledby", "aria-labelledby", "hidden", "hidden", "warnings", "warnings"], outputs: ["valueChange", "valueChange", "mixedChange", "mixedChange", "touchedChange", "touchedChange", "touch", "touch", "openChange", "openChange", "queryChange", "queryChange", "loadMore", "loadMore", "addNew", "addNew", "pickOption", "pickOption", "afterOpen", "afterOpen", "afterClose", "afterClose"] }, { directive: i1.ColorInteractiveDirective }], ngImport: i0, template: "<!-- a div, not a <button>: chips carry remove buttons and buttons cannot nest.\n The trigger directive manages tabindex/aria-disabled for non-button hosts. -->\n<div class=\"et-select-trigger\" etSelectTrigger>\n <div [class.et-select-trigger-content--stacked]=\"stackedValue()\" class=\"et-select-trigger-content\">\n @if (select.mixed()) {\n @if (showValueLabel()) {\n <span [id]=\"mixedLabelId\" class=\"et-select-value\">{{ select.displayValue() }}</span>\n }\n } @else if (select.registeredValueTemplate(); as valueTemplate) {\n @if (showCustomValue()) {\n <div class=\"et-select-value-custom\">\n <ng-template [ngTemplateOutlet]=\"valueTemplate.templateRef\" [ngTemplateOutletContext]=\"valueContext()\" />\n </div>\n }\n } @else if (select.multiple() && select.selectedEntries().length) {\n <div class=\"et-select-chips\">\n @for (entry of select.selectedEntries(); track entry.value) {\n <et-chip\n [disabled]=\"select.disabled()\"\n [removable]=\"!select.readonly() && !select.disabled()\"\n (remove)=\"select.deselectValue(entry.value)\"\n >\n {{ entry.label }}\n </et-chip>\n }\n </div>\n }\n\n @if (!select.mixed() && showValueLabel()) {\n <span [attr.data-placeholder]=\"select.displayValue() === null || null\" class=\"et-select-value\">\n {{ select.displayValue() ?? select.placeholder() }}\n </span>\n }\n\n <ng-content select=\"input[etSelectSearch]\" />\n </div>\n\n @if (select.showLoadingIndicator() && !select.open()) {\n <div class=\"et-select-trigger-busy\" animate.enter=\"et-select-trigger-busy--enter\">\n <et-spinner diameter=\"16\" strokeWidth=\"2\" />\n </div>\n }\n</div>\n\n<ng-template etControlSuffix>\n @if (showClear()) {\n <!-- pointer-only, out of the tab order \u2014 keyboard users clear via Backspace / erasing.\n mousedown is prevented so the trigger keeps focus: `showClear` reads `focused()`, so a\n blur would unmount this button before the click could land -->\n <button\n [attr.aria-label]=\"resolvedClearLabel()\"\n (click)=\"handleClearClick($event)\"\n (mousedown)=\"$event.preventDefault()\"\n class=\"et-input-clear\"\n animate.enter=\"et-input-clear--enter\"\n animate.leave=\"et-input-clear--leave\"\n tabindex=\"-1\"\n type=\"button\"\n >\n <i etIcon=\"et-times\"></i>\n </button>\n }\n\n <button\n [disabled]=\"select.disabled()\"\n (click)=\"handleArrowClick($event)\"\n (mousedown)=\"$event.preventDefault()\"\n class=\"et-input-picker-trigger et-select-arrow\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n type=\"button\"\n >\n <i etIcon=\"et-chevron\"></i>\n </button>\n</ng-template>\n\n<ng-template #optionContent>\n <ng-content />\n</ng-template>\n\n@if (!select.isMounted()) {\n <!-- keeps the projected options rendered (and their bindings live) while the panel is\n closed, so the trigger can resolve a preselected value's label and closed typeahead\n works \u2014 the same template moves into the overlay while it is open -->\n <div class=\"et-select-detached-options\" aria-hidden=\"true\" hidden>\n <ng-template [ngTemplateOutlet]=\"optionContent\" />\n </div>\n}\n\n<ng-template etSelectSurface>\n <et-select-panel #panelThemes=\"etSemanticThemes\" etSemanticThemes>\n @if (select.showSelectAll()) {\n <et-select-all-option>{{ resolvedSelectAllLabel() }}</et-select-all-option>\n }\n\n @if (select.options()) {\n <div\n [style.padding-block-start.px]=\"select.virtualWindow.paddingTop()\"\n [style.padding-block-end.px]=\"select.virtualWindow.paddingBottom()\"\n class=\"et-select-virtual-options\"\n role=\"none\"\n >\n @for (item of select.virtualizedItems(); track item.id()) {\n <et-select-virtual-option [item]=\"item\" />\n }\n </div>\n }\n\n <ng-template [ngTemplateOutlet]=\"optionContent\" />\n\n @if (select.customValueCandidate(); as candidate) {\n <et-select-option [value]=\"candidate\" [label]=\"candidate\" class=\"et-select-create-option\" customValueOption>\n <i class=\"et-select-create-option-icon\" etIcon=\"et-plus\" aria-hidden=\"true\"></i>\n {{ resolvedCreateLabel() }} \u201C{{ candidate }}\u201D\n </et-select-option>\n }\n\n <div class=\"et-select-panel-extras\" etSelectPanelExtras>\n @if (showBusyBar()) {\n <div class=\"et-select-busy-bar\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n\n @if (showLoadingRow()) {\n @if (select.registeredLoadingTemplate(); as loadingTemplate) {\n @if (select.showLoadingIndicator()) {\n <ng-template [ngTemplateOutlet]=\"loadingTemplate.templateRef\" />\n }\n } @else {\n <div class=\"et-select-state et-select-state--loading\">\n <span\n [class.et-select-state-content--visible]=\"select.showLoadingIndicator()\"\n [attr.aria-hidden]=\"!select.showLoadingIndicator() || null\"\n class=\"et-select-state-content\"\n >\n <et-spinner class=\"et-select-state-spinner\" diameter=\"16\" strokeWidth=\"2\" />\n {{ selectLabels().loading }}\n </span>\n </div>\n }\n } @else if (select.error(); as error) {\n @if (select.registeredErrorTemplate(); as errorTemplate) {\n <ng-template\n [ngTemplateOutlet]=\"errorTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: error }\"\n />\n } @else {\n <div\n [etProvideColor]=\"panelThemes.themes.error()\"\n class=\"et-select-state et-select-state--error\"\n role=\"alert\"\n >\n {{ error }}\n </div>\n }\n } @else if (!select.visibleItems().length) {\n @if (select.registeredEmptyTemplate(); as emptyTemplate) {\n <ng-template [ngTemplateOutlet]=\"emptyTemplate.templateRef\" />\n } @else {\n <div class=\"et-select-state et-select-state--empty\">{{ selectLabels().empty }}</div>\n }\n }\n\n @if (select.hasMoreItems() && !showLoadingRow()) {\n @if (showLoadMoreLoading()) {\n <div class=\"et-select-load-more et-select-load-more--loading\" aria-live=\"polite\">\n <et-spinner class=\"et-select-state-spinner\" diameter=\"16\" strokeWidth=\"2\" />\n {{ selectLabels().loading }}\n </div>\n } @else {\n <button\n [disabled]=\"select.loading()\"\n (click)=\"select.requestLoadMore()\"\n class=\"et-select-load-more\"\n tabindex=\"-1\"\n type=\"button\"\n >\n <i class=\"et-select-load-more-icon\" etIcon=\"et-chevron\" aria-hidden=\"true\"></i>\n {{ resolvedLoadMoreLabel() }}\n </button>\n }\n }\n\n @if (select.allowAddNew() && !showLoadingRow()) {\n <button (click)=\"select.requestAddNew()\" class=\"et-select-add-new\" tabindex=\"-1\" type=\"button\">\n <i class=\"et-select-add-new-icon\" etIcon=\"et-plus\" aria-hidden=\"true\"></i>\n {{ resolvedAddNewLabel() }}\n </button>\n }\n </div>\n </et-select-panel>\n</ng-template>\n", styles: ["@layer components{et-select{--_et-select-trigger-busy-fade: 24px;--_et-select-trigger-busy-cover: 16px;--_et-select-trigger-busy-mask-direction: to right;display:flex;align-items:center;gap:6px;flex:1;min-inline-size:0;color:inherit}et-select .et-select-trigger{display:flex;align-items:center;gap:6px;flex:1;outline:none;color:inherit;min-inline-size:0;text-align:start;cursor:pointer;-webkit-user-select:none;user-select:none;touch-action:manipulation}et-select .et-select-trigger[data-disabled]{cursor:not-allowed}et-select .et-select-trigger[data-readonly]{cursor:default}et-select .et-select-trigger .et-select-trigger-content{display:flex;flex-wrap:wrap;align-items:center;gap:6px;flex:1;min-inline-size:0}et-select .et-select-trigger .et-select-trigger-content.et-select-trigger-content--stacked{display:grid;grid-template-columns:minmax(0,1fr)}et-select .et-select-trigger .et-select-trigger-content.et-select-trigger-content--stacked>*{grid-area:1 / 1}et-select .et-select-trigger .et-select-trigger-content.et-select-trigger-content--stacked:has(.et-select-value-custom) input[etselectsearch]{caret-color:transparent}et-select .et-select-trigger input[etselectsearch]{flex:1 1 60px;min-inline-size:60px;border:none;outline:none;background:transparent;font:inherit;color:inherit;padding:0;caret-color:var(--et-theme-color-primary-solid, currentColor);cursor:text}et-select .et-select-trigger input[etselectsearch]::placeholder{color:var(--et-surface-color-muted-solid, color-mix(in srgb, currentColor 46%, transparent))}et-select .et-select-trigger input[etselectsearch]:read-only{cursor:default;caret-color:transparent}et-select .et-select-trigger input[etselectsearch]:disabled{cursor:not-allowed}et-select .et-select-trigger:has(input[etselectsearch]) .et-select-value{flex:0 1 auto}et-select .et-select-value{flex:1;min-block-size:1lh;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-inline-size:0}et-select .et-select-value[data-placeholder]{color:var(--et-surface-color-muted-solid, color-mix(in srgb, currentColor 46%, transparent))}et-select[data-mixed] .et-select-value,et-select[data-mixed] input[etselectsearch]:not(:focus){font-style:italic;color:color-mix(in srgb,currentColor 72%,transparent)}et-select .et-select-value-custom{display:flex;align-items:center;flex:1;min-inline-size:0}et-select .et-select-trigger-content:has(input[etselectsearch]) .et-select-value-custom{flex:0 1 auto}et-select .et-select-trigger-content:has(.et-select-value-custom) input[etselectsearch]::placeholder{color:transparent}et-select .et-select-chips{display:contents}et-select .et-select-trigger-busy{position:relative;display:flex;align-items:center;align-self:stretch;flex:none;padding-inline-start:var(--_et-select-trigger-busy-fade);margin-inline-start:calc(-1 * (var(--_et-select-trigger-busy-fade) + var(--_et-select-trigger-busy-cover) + 6px));color:var(--et-surface-color-muted-solid, currentColor)}et-select:dir(rtl){--_et-select-trigger-busy-mask-direction: to left}et-select .et-select-trigger:has(>.et-select-trigger-busy) .et-select-trigger-content{-webkit-mask-image:linear-gradient(var(--_et-select-trigger-busy-mask-direction),black calc(100% - var(--_et-select-trigger-busy-cover) - var(--_et-select-trigger-busy-fade)),transparent calc(100% - var(--_et-select-trigger-busy-cover)));mask-image:linear-gradient(var(--_et-select-trigger-busy-mask-direction),black calc(100% - var(--_et-select-trigger-busy-cover) - var(--_et-select-trigger-busy-fade)),transparent calc(100% - var(--_et-select-trigger-busy-cover)))}et-select .et-select-trigger-busy--enter{animation:et-select-busy-in .12s ease}@media(prefers-reduced-motion:reduce){et-select .et-select-trigger-busy--enter{animation:none}}.et-select-arrow .et-icon{rotate:180deg}@keyframes et-select-busy-in{0%{opacity:0}}}\n"], dependencies: [{ kind: "directive", type: SelectTriggerDirective, selector: "[etSelectTrigger]", exportAs: ["etSelectTrigger"] }, { kind: "directive", type: SelectSurfaceDirective, selector: "ng-template[etSelectSurface]", exportAs: ["etSelectSurface"] }, { kind: "directive", type: ControlSuffixDirective, selector: "ng-template[etControlSuffix]" }, { kind: "component", type: SelectPanelComponent, selector: "et-select-panel" }, { kind: "component", type: SelectOptionComponent, selector: "et-select-option" }, { kind: "component", type: SelectAllOptionComponent, selector: "et-select-all-option" }, { kind: "component", type: SelectVirtualOptionComponent, selector: "et-select-virtual-option" }, { kind: "directive", type: IconDirective, selector: "[etIcon]", inputs: ["etIcon", "variant", "allowHardcodedColor", "label"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ChipComponent, selector: "et-chip" }, { kind: "component", type: SpinnerComponent, selector: "et-spinner", inputs: ["diameter", "strokeWidth", "track", "value"] }, { kind: "directive", type: ProvideColorDirective, selector: "[etProvideColor]", inputs: ["etProvideColor"] }, { kind: "directive", type: SemanticThemesDirective, selector: "[etSemanticThemes]", exportAs: ["etSemanticThemes"] }], encapsulation: i0.ViewEncapsulation.None }); }
50745
+ ], hostDirectives: [{ directive: SelectDirective, inputs: ["value", "value", "mixed", "mixed", "touched", "touched", "open", "open", "multiple", "multiple", "placeholder", "placeholder", "mixedLabel", "mixedLabel", "disabled", "disabled", "readonly", "readonly", "invalid", "invalid", "errors", "errors", "required", "required", "name", "name", "maxLength", "maxLength", "pending", "pending", "options", "options", "compareWith", "compareWith", "valueKey", "valueKey", "displayWith", "displayWith", "filterMode", "filterMode", "allowCustomValues", "allowCustomValues", "separators", "separators", "normalizeValue", "normalizeValue", "commitCustomValueOnClose", "commitCustomValueOnClose", "maxSelection", "maxSelection", "allowAddNew", "allowAddNew", "loading", "loading", "loadError", "loadError", "hasMoreItems", "hasMoreItems", "pickOnly", "pickOnly", "selectAll", "selectAll", "mirrorPanelWidth", "mirrorPanelWidth", "aria-label", "aria-label", "aria-labelledby", "aria-labelledby", "hidden", "hidden", "warnings", "warnings"], outputs: ["valueChange", "valueChange", "mixedChange", "mixedChange", "touchedChange", "touchedChange", "touch", "touch", "openChange", "openChange", "queryChange", "queryChange", "loadMore", "loadMore", "addNew", "addNew", "pickOption", "pickOption", "afterOpen", "afterOpen", "afterClose", "afterClose"] }, { directive: i1.ColorInteractiveDirective }], ngImport: i0, template: "<!-- a div, not a <button>: chips carry remove buttons and buttons cannot nest.\n The trigger directive manages tabindex/aria-disabled for non-button hosts. -->\n<div class=\"et-select-trigger\" etSelectTrigger>\n <div [class.et-select-trigger-content--stacked]=\"stackedValue()\" class=\"et-select-trigger-content\">\n @if (select.mixed()) {\n @if (showValueLabel()) {\n <span [id]=\"mixedLabelId\" class=\"et-select-value\">{{ select.displayValue() }}</span>\n }\n } @else if (select.registeredValueTemplate(); as valueTemplate) {\n @if (showCustomValue()) {\n <div class=\"et-select-value-custom\">\n <ng-template [ngTemplateOutlet]=\"valueTemplate.templateRef\" [ngTemplateOutletContext]=\"valueContext()\" />\n </div>\n }\n } @else if (select.multiple() && select.selectedEntries().length) {\n <div class=\"et-select-chips\">\n @for (entry of select.selectedEntries(); track entry.value) {\n <et-chip\n [disabled]=\"select.disabled()\"\n [removable]=\"!select.readonly() && !select.disabled()\"\n (remove)=\"select.deselectValue(entry.value)\"\n >\n {{ entry.label }}\n </et-chip>\n }\n </div>\n }\n\n @if (!select.mixed() && showValueLabel()) {\n <span [attr.data-placeholder]=\"select.displayValue() === null || null\" class=\"et-select-value\">\n {{ select.displayValue() ?? select.placeholder() }}\n </span>\n }\n\n <ng-content select=\"input[etSelectSearch]\" />\n </div>\n\n @if (select.showLoadingIndicator() && !select.open()) {\n <div class=\"et-select-trigger-busy\" animate.enter=\"et-select-trigger-busy--enter\">\n <et-spinner diameter=\"16\" strokeWidth=\"2\" />\n </div>\n }\n</div>\n\n<ng-template etControlSuffix>\n @if (showClear()) {\n <!-- pointer-only, out of the tab order \u2014 keyboard users clear via Backspace / erasing.\n mousedown is prevented so the trigger keeps focus: `showClear` reads `focused()`, so a\n blur would unmount this button before the click could land -->\n <button\n [attr.aria-label]=\"resolvedClearLabel()\"\n (click)=\"handleClearClick($event)\"\n (mousedown)=\"$event.preventDefault()\"\n class=\"et-input-clear\"\n animate.enter=\"et-input-clear--enter\"\n animate.leave=\"et-input-clear--leave\"\n tabindex=\"-1\"\n type=\"button\"\n >\n <i etIcon=\"et-times\"></i>\n </button>\n }\n\n <button\n [disabled]=\"select.disabled()\"\n (click)=\"handleArrowClick($event)\"\n (mousedown)=\"$event.preventDefault()\"\n class=\"et-input-picker-trigger et-select-arrow\"\n aria-hidden=\"true\"\n tabindex=\"-1\"\n type=\"button\"\n >\n <i etIcon=\"et-chevron\"></i>\n </button>\n</ng-template>\n\n<ng-template #optionContent>\n <ng-content />\n</ng-template>\n\n@if (!select.isMounted()) {\n <!-- keeps the projected options rendered (and their bindings live) while the panel is\n closed, so the trigger can resolve a preselected value's label and closed typeahead\n works \u2014 the same template moves into the overlay while it is open -->\n <div class=\"et-select-detached-options\" aria-hidden=\"true\" hidden>\n <ng-template [ngTemplateOutlet]=\"optionContent\" />\n </div>\n}\n\n<ng-template etSelectSurface>\n <et-select-panel #panelThemes=\"etSemanticThemes\" etSemanticThemes>\n @if (select.showSelectAll()) {\n <et-select-all-option>{{ resolvedSelectAllLabel() }}</et-select-all-option>\n }\n\n @if (select.options()) {\n <div\n [style.padding-block-start.px]=\"select.virtualWindow.paddingTop()\"\n [style.padding-block-end.px]=\"select.virtualWindow.paddingBottom()\"\n class=\"et-select-virtual-options\"\n role=\"none\"\n >\n @for (item of select.virtualizedItems(); track item.id()) {\n <et-select-virtual-option [item]=\"item\" />\n }\n </div>\n }\n\n <ng-template [ngTemplateOutlet]=\"optionContent\" />\n\n @if (select.customValueCandidate(); as candidate) {\n <et-select-option [value]=\"candidate\" [label]=\"candidate\" class=\"et-select-create-option\" customValueOption>\n <i class=\"et-select-create-option-icon\" etIcon=\"et-plus\" aria-hidden=\"true\"></i>\n {{ resolvedCreateLabel() }} \u201C{{ candidate }}\u201D\n </et-select-option>\n }\n\n <div class=\"et-select-panel-extras\" etSelectPanelExtras>\n @if (showBusyBar()) {\n <div class=\"et-select-busy-bar\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n\n @if (showLoadingRow()) {\n @if (select.registeredLoadingTemplate(); as loadingTemplate) {\n @if (select.showLoadingIndicator()) {\n <ng-template [ngTemplateOutlet]=\"loadingTemplate.templateRef\" />\n }\n } @else {\n <div class=\"et-select-state et-select-state--loading\">\n <span\n [class.et-select-state-content--visible]=\"select.showLoadingIndicator()\"\n [attr.aria-hidden]=\"!select.showLoadingIndicator() || null\"\n class=\"et-select-state-content\"\n >\n <et-spinner class=\"et-select-state-spinner\" diameter=\"16\" strokeWidth=\"2\" />\n {{ selectLabels().loading }}\n </span>\n </div>\n }\n } @else if (select.error(); as error) {\n @if (select.registeredErrorTemplate(); as errorTemplate) {\n <ng-template\n [ngTemplateOutlet]=\"errorTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: error }\"\n />\n } @else {\n <div\n [etProvideColor]=\"panelThemes.themes.error()\"\n class=\"et-select-state et-select-state--error\"\n role=\"alert\"\n >\n {{ error }}\n </div>\n }\n } @else if (!select.visibleItems().length) {\n @if (select.registeredEmptyTemplate(); as emptyTemplate) {\n <ng-template [ngTemplateOutlet]=\"emptyTemplate.templateRef\" />\n } @else {\n <div class=\"et-select-state et-select-state--empty\">{{ selectLabels().empty }}</div>\n }\n }\n\n @if (select.hasMoreItems() && !showLoadingRow()) {\n @if (showLoadMoreLoading()) {\n <div class=\"et-select-load-more et-select-load-more--loading\" aria-live=\"polite\">\n <et-spinner class=\"et-select-state-spinner\" diameter=\"16\" strokeWidth=\"2\" />\n {{ selectLabels().loading }}\n </div>\n } @else {\n <button\n [disabled]=\"select.loading()\"\n (click)=\"select.requestLoadMore()\"\n class=\"et-select-load-more\"\n tabindex=\"-1\"\n type=\"button\"\n >\n <i class=\"et-select-load-more-icon\" etIcon=\"et-chevron\" aria-hidden=\"true\"></i>\n {{ resolvedLoadMoreLabel() }}\n </button>\n }\n }\n\n @if (select.allowAddNew() && !showLoadingRow()) {\n <button (click)=\"select.requestAddNew()\" class=\"et-select-add-new\" tabindex=\"-1\" type=\"button\">\n <i class=\"et-select-add-new-icon\" etIcon=\"et-plus\" aria-hidden=\"true\"></i>\n {{ resolvedAddNewLabel() }}\n </button>\n }\n </div>\n </et-select-panel>\n</ng-template>\n", styles: ["@layer components{et-select{--_et-select-trigger-busy-fade: 24px;--_et-select-trigger-busy-cover: 16px;--_et-select-trigger-busy-mask-direction: to right;display:flex;align-items:center;gap:6px;flex:1;min-inline-size:0;color:inherit}et-select .et-select-trigger{display:flex;align-items:center;gap:6px;flex:1;outline:none;color:inherit;min-inline-size:0;text-align:start;cursor:pointer;-webkit-user-select:none;user-select:none;touch-action:manipulation}et-select .et-select-trigger[data-disabled]{cursor:not-allowed}et-select .et-select-trigger[data-readonly]{cursor:default}et-select .et-select-trigger .et-select-trigger-content{display:flex;flex-wrap:wrap;align-items:center;gap:6px;flex:1;min-inline-size:0}et-select .et-select-trigger .et-select-trigger-content.et-select-trigger-content--stacked{display:grid;grid-template-columns:minmax(0,1fr)}et-select .et-select-trigger .et-select-trigger-content.et-select-trigger-content--stacked>*{grid-area:1 / 1}et-select .et-select-trigger .et-select-trigger-content.et-select-trigger-content--stacked:has(.et-select-value-custom) input[etselectsearch]{caret-color:transparent}et-select .et-select-trigger input[etselectsearch]{flex:1 1 60px;min-inline-size:60px;border:none;outline:none;background:transparent;font:inherit;color:inherit;padding:0;caret-color:var(--et-theme-color-primary-solid, currentColor);cursor:text}et-select .et-select-trigger input[etselectsearch]::placeholder{color:var(--et-surface-color-muted-solid, color-mix(in srgb, currentColor 46%, transparent))}et-select .et-select-trigger input[etselectsearch]:read-only{cursor:default;caret-color:transparent}et-select .et-select-trigger input[etselectsearch]:disabled{cursor:not-allowed}et-select .et-select-trigger:has(input[etselectsearch]) .et-select-value{flex:0 1 auto}et-select .et-select-value{flex:1;min-block-size:1lh;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-inline-size:0}et-select .et-select-value[data-placeholder]{color:var(--et-surface-color-muted-solid, color-mix(in srgb, currentColor 46%, transparent))}et-select[data-mixed] .et-select-value,et-select[data-mixed] input[etselectsearch]:not(:focus){font-style:italic;color:color-mix(in srgb,currentColor 72%,transparent)}et-select .et-select-value-custom{display:flex;align-items:center;flex:1;min-inline-size:0}et-select .et-select-trigger-content:has(input[etselectsearch]) .et-select-value-custom{flex:0 1 auto}et-select .et-select-trigger-content:has(.et-select-value-custom) input[etselectsearch]::placeholder{color:transparent}et-select .et-select-chips{display:contents}et-select .et-select-trigger-busy{position:relative;display:flex;align-items:center;align-self:stretch;flex:none;padding-inline-start:var(--_et-select-trigger-busy-fade);margin-inline-start:calc(-1 * (var(--_et-select-trigger-busy-fade) + var(--_et-select-trigger-busy-cover) + 6px));color:var(--et-surface-color-muted-solid, currentColor)}et-select:dir(rtl){--_et-select-trigger-busy-mask-direction: to left}et-select .et-select-trigger:has(>.et-select-trigger-busy) .et-select-trigger-content{-webkit-mask-image:linear-gradient(var(--_et-select-trigger-busy-mask-direction),black calc(100% - var(--_et-select-trigger-busy-cover) - var(--_et-select-trigger-busy-fade)),transparent calc(100% - var(--_et-select-trigger-busy-cover)));mask-image:linear-gradient(var(--_et-select-trigger-busy-mask-direction),black calc(100% - var(--_et-select-trigger-busy-cover) - var(--_et-select-trigger-busy-fade)),transparent calc(100% - var(--_et-select-trigger-busy-cover)))}et-select .et-select-trigger-busy--enter{animation:et-select-busy-in .12s ease}@media(prefers-reduced-motion:reduce){et-select .et-select-trigger-busy--enter{animation:none}}.et-select-arrow .et-icon{rotate:180deg}@keyframes et-select-busy-in{0%{opacity:0}}}\n"], dependencies: [{ kind: "directive", type: SelectTriggerDirective, selector: "[etSelectTrigger]", exportAs: ["etSelectTrigger"] }, { kind: "directive", type: SelectSurfaceDirective, selector: "ng-template[etSelectSurface]", exportAs: ["etSelectSurface"] }, { kind: "directive", type: ControlSuffixDirective, selector: "ng-template[etControlSuffix]" }, { kind: "component", type: SelectPanelComponent, selector: "et-select-panel" }, { kind: "component", type: SelectOptionComponent, selector: "et-select-option" }, { kind: "component", type: SelectAllOptionComponent, selector: "et-select-all-option" }, { kind: "component", type: SelectVirtualOptionComponent, selector: "et-select-virtual-option" }, { kind: "directive", type: IconDirective, selector: "[etIcon]", inputs: ["etIcon", "variant", "allowHardcodedColor", "label"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ChipComponent, selector: "et-chip" }, { kind: "component", type: SpinnerComponent, selector: "et-spinner", inputs: ["diameter", "strokeWidth", "track", "value"] }, { kind: "directive", type: ProvideColorDirective, selector: "[etProvideColor]", inputs: ["etProvideColor"] }, { kind: "directive", type: SemanticThemesDirective, selector: "[etSemanticThemes]", exportAs: ["etSemanticThemes"] }], encapsulation: i0.ViewEncapsulation.None }); }
50447
50746
  }
50448
50747
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SelectComponent, decorators: [{
50449
50748
  type: Component,
@@ -50493,6 +50792,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
50493
50792
  'options',
50494
50793
  'compareWith',
50495
50794
  'valueKey',
50795
+ 'displayWith',
50496
50796
  'filterMode',
50497
50797
  'allowCustomValues',
50498
50798
  'separators',
@@ -50625,7 +50925,7 @@ class PhoneInputComponent {
50625
50925
  this.phone.focus(options);
50626
50926
  }
50627
50927
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PhoneInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
50628
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: PhoneInputComponent, isStandalone: true, selector: "et-phone-input", inputs: { countryLabel: { classPropertyName: "countryLabel", publicName: "countryLabel", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "et-phone-input" }, providers: [provideIcons(TIMES_ICON)], hostDirectives: [{ directive: PhoneInputDirective, inputs: ["value", "value", "placeholder", "placeholder", "defaultCountry", "defaultCountry", "preferredCountries", "preferredCountries", "touched", "touched", "mixed", "mixed", "mixedLabel", "mixedLabel", "disabled", "disabled", "readonly", "readonly", "hidden", "hidden", "invalid", "invalid", "errors", "errors", "warnings", "warnings", "required", "required", "name", "name", "maxLength", "maxLength", "pending", "pending", "aria-label", "aria-label", "aria-labelledby", "aria-labelledby"], outputs: ["valueChange", "valueChange", "mixedChange", "mixedChange", "touchedChange", "touchedChange", "touch", "touch"] }, { directive: i1.ColorInteractiveDirective }], ngImport: i0, template: "<div\n [aria-labelledby]=\"countryLabelId\"\n [value]=\"phone.country()\"\n [readonly]=\"phone.readonly()\"\n (valueChange)=\"handleCountryChange($event)\"\n class=\"et-phone-input-country\"\n mirrorPanelWidth=\"false\"\n etFormFieldBarrier\n etSelect\n>\n <span [id]=\"countryLabelId\" hidden>{{ resolvedCountryLabel() }}</span>\n <button [disabled]=\"phone.disabled()\" class=\"et-phone-input-country-trigger\" etSelectTrigger type=\"button\">\n <span class=\"et-phone-input-country-flag\" aria-hidden=\"true\">\n @if (phone.registeredFlagTemplate(); as flagTemplate) {\n <ng-template [ngTemplateOutlet]=\"flagTemplate.templateRef\" [ngTemplateOutletContext]=\"activeFlagContext()\" />\n } @else {\n {{ activeFlag() }}\n }\n </span>\n <span class=\"et-visually-hidden et-phone-input-country-name\">{{ activeCountryName() }}</span>\n <span class=\"et-phone-input-dial-code\">+{{ phone.dialCode() }}</span>\n </button>\n\n <ng-template etSelectSurface let-select>\n <et-select-panel class=\"et-phone-input-country-panel\">\n <div class=\"et-select-panel-search\">\n <input [placeholder]=\"phoneInputLabels().searchCountries\" etSelectSearch />\n </div>\n\n <!-- the label carries the dial code too, so searching by \"+49\" / \"49\" works -->\n @for (country of countries(); track country.iso2) {\n <et-select-option [label]=\"country.name + ' +' + country.dialCode\" [value]=\"country.iso2\">\n <span class=\"et-phone-input-option-flag\" aria-hidden=\"true\">\n @if (phone.registeredFlagTemplate(); as flagTemplate) {\n <ng-template\n [ngTemplateOutlet]=\"flagTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: country }\"\n />\n } @else {\n {{ country.flag }}\n }\n </span>\n <span class=\"et-phone-input-option-name\">{{ country.name }}</span>\n <span class=\"et-phone-input-option-dial\">+{{ country.dialCode }}</span>\n </et-select-option>\n }\n\n @if (!select.visibleItems().length) {\n <div class=\"et-select-state et-select-state--empty\">{{ phoneInputLabels().noCountries }}</div>\n }\n </et-select-panel>\n </ng-template>\n</div>\n\n<input class=\"et-phone-input-field\" etPhoneInputField />\n\n<ng-template etControlSuffix>\n @if (showClear()) {\n <!-- pointer-only, out of the tab order \u2014 keyboard users clear by erasing the text.\n mousedown is prevented so the field keeps focus (its blur would unmount this\n button before the click could land) -->\n <button\n [attr.aria-label]=\"resolvedClearLabel()\"\n (click)=\"handleClearClick($event)\"\n (mousedown)=\"$event.preventDefault()\"\n class=\"et-input-clear\"\n animate.enter=\"et-input-clear--enter\"\n animate.leave=\"et-input-clear--leave\"\n tabindex=\"-1\"\n type=\"button\"\n >\n <i etIcon=\"et-times\"></i>\n </button>\n }\n</ng-template>\n", styles: ["@layer components{et-phone-input{display:flex;align-items:center;gap:8px;flex:1;min-inline-size:0;color:inherit}et-phone-input .et-phone-input-country-trigger{display:flex;align-items:center;gap:4px;border:none;outline:none;background:transparent;font:inherit;color:inherit;padding:0;margin:0;cursor:pointer;appearance:none;white-space:nowrap}et-phone-input .et-phone-input-country-trigger:disabled{cursor:not-allowed}et-phone-input .et-phone-input-country-trigger:focus-visible{outline:2px solid var(--et-theme-color-primary-solid, currentColor);outline-offset:2px;border-radius:4px}et-phone-input[data-readonly] .et-phone-input-country-trigger{cursor:default}et-phone-input .et-phone-input-country-flag{display:inline-flex;align-items:center}et-phone-input .et-phone-input-dial-code{color:var(--et-surface-color-muted-solid, currentColor);font-variant-numeric:tabular-nums}et-phone-input .et-phone-input-field{flex:1;min-inline-size:0;border:none;outline:none;background:transparent;font:inherit;color:inherit;padding:0;caret-color:var(--et-theme-color-primary-solid, currentColor);font-variant-numeric:tabular-nums}et-phone-input .et-phone-input-field::placeholder{color:color-mix(in srgb,currentColor 46%,transparent)}et-phone-input .et-phone-input-field:disabled{cursor:not-allowed}et-phone-input[data-mixed] .et-phone-input-field::placeholder{font-style:italic;color:color-mix(in srgb,currentColor 72%,transparent)}.et-phone-input-country-panel{inline-size:min(320px,calc(100vw - 24px))}.et-phone-input-country-panel .et-select-option-label{display:flex;align-items:center;gap:var(--et-select-option-gap, 8px);flex:1;min-inline-size:0}.et-phone-input-option-flag{flex:none;display:inline-flex;align-items:center;justify-content:center}.et-phone-input-option-name{flex:1;min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.et-phone-input-option-dial{flex:none;color:var(--et-surface-color-muted-solid, currentColor);font-variant-numeric:tabular-nums}.et-phone-input-country-flag :is(img,svg),.et-phone-input-option-flag :is(img,svg){display:block;inline-size:20px;block-size:auto}}\n"], dependencies: [{ kind: "directive", type: ControlSuffixDirective, selector: "ng-template[etControlSuffix]" }, { kind: "directive", type: FormFieldBarrierDirective, selector: "[etFormFieldBarrier]" }, { kind: "directive", type: SelectDirective, selector: "[etSelect]", inputs: ["value", "mixed", "touched", "open", "multiple", "disabled", "readonly", "invalid", "errors", "required", "name", "placeholder", "mixedLabel", "maxLength", "pending", "options", "compareWith", "valueKey", "filterMode", "allowCustomValues", "separators", "normalizeValue", "commitCustomValueOnClose", "maxSelection", "allowAddNew", "loading", "loadError", "hasMoreItems", "mirrorPanelWidth", "pickOnly", "selectAll"], outputs: ["valueChange", "mixedChange", "touchedChange", "openChange", "touch", "queryChange", "loadMore", "addNew", "pickOption", "afterOpen", "afterClose"], exportAs: ["etSelect"] }, { kind: "directive", type: SelectTriggerDirective, selector: "[etSelectTrigger]", exportAs: ["etSelectTrigger"] }, { kind: "directive", type: SelectSurfaceDirective, selector: "ng-template[etSelectSurface]", exportAs: ["etSelectSurface"] }, { kind: "component", type: SelectPanelComponent, selector: "et-select-panel" }, { kind: "component", type: SelectOptionComponent, selector: "et-select-option" }, { kind: "directive", type: SelectSearchDirective, selector: "input[etSelectSearch]", inputs: ["query"], outputs: ["queryChange"], exportAs: ["etSelectSearch"] }, { kind: "directive", type: PhoneInputFieldDirective, selector: "input[etPhoneInputField]", exportAs: ["etPhoneInputField"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: IconDirective, selector: "[etIcon]", inputs: ["etIcon", "variant", "allowHardcodedColor", "label"] }], encapsulation: i0.ViewEncapsulation.None }); }
50928
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: PhoneInputComponent, isStandalone: true, selector: "et-phone-input", inputs: { countryLabel: { classPropertyName: "countryLabel", publicName: "countryLabel", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "et-phone-input" }, providers: [provideIcons(TIMES_ICON)], hostDirectives: [{ directive: PhoneInputDirective, inputs: ["value", "value", "placeholder", "placeholder", "defaultCountry", "defaultCountry", "preferredCountries", "preferredCountries", "touched", "touched", "mixed", "mixed", "mixedLabel", "mixedLabel", "disabled", "disabled", "readonly", "readonly", "hidden", "hidden", "invalid", "invalid", "errors", "errors", "warnings", "warnings", "required", "required", "name", "name", "maxLength", "maxLength", "pending", "pending", "aria-label", "aria-label", "aria-labelledby", "aria-labelledby"], outputs: ["valueChange", "valueChange", "mixedChange", "mixedChange", "touchedChange", "touchedChange", "touch", "touch"] }, { directive: i1.ColorInteractiveDirective }], ngImport: i0, template: "<div\n [aria-labelledby]=\"countryLabelId\"\n [value]=\"phone.country()\"\n [readonly]=\"phone.readonly()\"\n (valueChange)=\"handleCountryChange($event)\"\n class=\"et-phone-input-country\"\n mirrorPanelWidth=\"false\"\n etFormFieldBarrier\n etSelect\n>\n <span [id]=\"countryLabelId\" hidden>{{ resolvedCountryLabel() }}</span>\n <button [disabled]=\"phone.disabled()\" class=\"et-phone-input-country-trigger\" etSelectTrigger type=\"button\">\n <span class=\"et-phone-input-country-flag\" aria-hidden=\"true\">\n @if (phone.registeredFlagTemplate(); as flagTemplate) {\n <ng-template [ngTemplateOutlet]=\"flagTemplate.templateRef\" [ngTemplateOutletContext]=\"activeFlagContext()\" />\n } @else {\n {{ activeFlag() }}\n }\n </span>\n <span class=\"et-visually-hidden et-phone-input-country-name\">{{ activeCountryName() }}</span>\n <span class=\"et-phone-input-dial-code\">+{{ phone.dialCode() }}</span>\n </button>\n\n <ng-template etSelectSurface let-select>\n <et-select-panel class=\"et-phone-input-country-panel\">\n <div class=\"et-select-panel-search\">\n <input [placeholder]=\"phoneInputLabels().searchCountries\" etSelectSearch />\n </div>\n\n <!-- the label carries the dial code too, so searching by \"+49\" / \"49\" works -->\n @for (country of countries(); track country.iso2) {\n <et-select-option [label]=\"country.name + ' +' + country.dialCode\" [value]=\"country.iso2\">\n <span class=\"et-phone-input-option-flag\" aria-hidden=\"true\">\n @if (phone.registeredFlagTemplate(); as flagTemplate) {\n <ng-template\n [ngTemplateOutlet]=\"flagTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: country }\"\n />\n } @else {\n {{ country.flag }}\n }\n </span>\n <span class=\"et-phone-input-option-name\">{{ country.name }}</span>\n <span class=\"et-phone-input-option-dial\">+{{ country.dialCode }}</span>\n </et-select-option>\n }\n\n @if (!select.visibleItems().length) {\n <div class=\"et-select-state et-select-state--empty\">{{ phoneInputLabels().noCountries }}</div>\n }\n </et-select-panel>\n </ng-template>\n</div>\n\n<input class=\"et-phone-input-field\" etPhoneInputField />\n\n<ng-template etControlSuffix>\n @if (showClear()) {\n <!-- pointer-only, out of the tab order \u2014 keyboard users clear by erasing the text.\n mousedown is prevented so the field keeps focus (its blur would unmount this\n button before the click could land) -->\n <button\n [attr.aria-label]=\"resolvedClearLabel()\"\n (click)=\"handleClearClick($event)\"\n (mousedown)=\"$event.preventDefault()\"\n class=\"et-input-clear\"\n animate.enter=\"et-input-clear--enter\"\n animate.leave=\"et-input-clear--leave\"\n tabindex=\"-1\"\n type=\"button\"\n >\n <i etIcon=\"et-times\"></i>\n </button>\n }\n</ng-template>\n", styles: ["@layer components{et-phone-input{display:flex;align-items:center;gap:8px;flex:1;min-inline-size:0;color:inherit}et-phone-input .et-phone-input-country-trigger{display:flex;align-items:center;gap:4px;border:none;outline:none;background:transparent;font:inherit;color:inherit;padding:0;margin:0;cursor:pointer;appearance:none;white-space:nowrap}et-phone-input .et-phone-input-country-trigger:disabled{cursor:not-allowed}et-phone-input .et-phone-input-country-trigger:focus-visible{outline:2px solid var(--et-theme-color-primary-solid, currentColor);outline-offset:2px;border-radius:4px}et-phone-input[data-readonly] .et-phone-input-country-trigger{cursor:default}et-phone-input .et-phone-input-country-flag{display:inline-flex;align-items:center}et-phone-input .et-phone-input-dial-code{color:var(--et-surface-color-muted-solid, currentColor);font-variant-numeric:tabular-nums}et-phone-input .et-phone-input-field{flex:1;min-inline-size:0;border:none;outline:none;background:transparent;font:inherit;color:inherit;padding:0;caret-color:var(--et-theme-color-primary-solid, currentColor);font-variant-numeric:tabular-nums}et-phone-input .et-phone-input-field::placeholder{color:color-mix(in srgb,currentColor 46%,transparent)}et-phone-input .et-phone-input-field:disabled{cursor:not-allowed}et-phone-input[data-mixed] .et-phone-input-field::placeholder{font-style:italic;color:color-mix(in srgb,currentColor 72%,transparent)}.et-phone-input-country-panel{inline-size:min(320px,calc(100vw - 24px))}.et-phone-input-country-panel .et-select-option-label{display:flex;align-items:center;gap:var(--et-select-option-gap, 8px);flex:1;min-inline-size:0}.et-phone-input-option-flag{flex:none;display:inline-flex;align-items:center;justify-content:center}.et-phone-input-option-name{flex:1;min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.et-phone-input-option-dial{flex:none;color:var(--et-surface-color-muted-solid, currentColor);font-variant-numeric:tabular-nums}.et-phone-input-country-flag :is(img,svg),.et-phone-input-option-flag :is(img,svg){display:block;inline-size:20px;block-size:auto}}\n"], dependencies: [{ kind: "directive", type: ControlSuffixDirective, selector: "ng-template[etControlSuffix]" }, { kind: "directive", type: FormFieldBarrierDirective, selector: "[etFormFieldBarrier]" }, { kind: "directive", type: SelectDirective, selector: "[etSelect]", inputs: ["value", "mixed", "touched", "open", "multiple", "disabled", "readonly", "invalid", "errors", "required", "name", "placeholder", "mixedLabel", "maxLength", "pending", "options", "compareWith", "valueKey", "displayWith", "filterMode", "allowCustomValues", "separators", "normalizeValue", "commitCustomValueOnClose", "maxSelection", "allowAddNew", "loading", "loadError", "hasMoreItems", "mirrorPanelWidth", "pickOnly", "selectAll"], outputs: ["valueChange", "mixedChange", "touchedChange", "openChange", "touch", "queryChange", "loadMore", "addNew", "pickOption", "afterOpen", "afterClose"], exportAs: ["etSelect"] }, { kind: "directive", type: SelectTriggerDirective, selector: "[etSelectTrigger]", exportAs: ["etSelectTrigger"] }, { kind: "directive", type: SelectSurfaceDirective, selector: "ng-template[etSelectSurface]", exportAs: ["etSelectSurface"] }, { kind: "component", type: SelectPanelComponent, selector: "et-select-panel" }, { kind: "component", type: SelectOptionComponent, selector: "et-select-option" }, { kind: "directive", type: SelectSearchDirective, selector: "input[etSelectSearch]", inputs: ["query"], outputs: ["queryChange"], exportAs: ["etSelectSearch"] }, { kind: "directive", type: PhoneInputFieldDirective, selector: "input[etPhoneInputField]", exportAs: ["etPhoneInputField"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: IconDirective, selector: "[etIcon]", inputs: ["etIcon", "variant", "allowHardcodedColor", "label"] }], encapsulation: i0.ViewEncapsulation.None }); }
50629
50929
  }
50630
50930
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PhoneInputComponent, decorators: [{
50631
50931
  type: Component,
@@ -51645,7 +51945,8 @@ class RangeSliderDirective extends FieldStateControlDirective {
51645
51945
  const min = this.effectiveMin();
51646
51946
  return [min, min];
51647
51947
  }
51648
- const snapped = this.value().map((end) => this.snapValue(end));
51948
+ const range = this.value() ?? [this.effectiveMin(), this.effectiveMax()];
51949
+ const snapped = range.map((end) => this.snapValue(end));
51649
51950
  return [Math.min(...snapped), Math.max(...snapped)];
51650
51951
  }, /* @ts-ignore */
51651
51952
  ...(ngDevMode ? [{ debugName: "thumbValues" }] : /* istanbul ignore next */ []));
@@ -52530,6 +52831,8 @@ const defaultNormalizeValue = (raw) => {
52530
52831
  const trimmed = raw.trim();
52531
52832
  return trimmed.length ? trimmed : null;
52532
52833
  };
52834
+ // a form model can hold `null` for a `string[]` field (a JSON `null` from an API)
52835
+ const tagsOf = (value) => value ?? [];
52533
52836
  class TagInputDirective extends TextShellControlDirective {
52534
52837
  constructor() {
52535
52838
  super(...arguments);
@@ -52564,7 +52867,7 @@ class TagInputDirective extends TextShellControlDirective {
52564
52867
  this.maxSelection = input(undefined, /* @ts-ignore */
52565
52868
  ...(ngDevMode ? [{ debugName: "maxSelection" }] : /* istanbul ignore next */ []));
52566
52869
  /** The raw value normalized to the tags the control currently shows. Mixed has no effective tags. */
52567
- this.effectiveValues = computed(() => (this.mixed() ? [] : this.value()), /* @ts-ignore */
52870
+ this.effectiveValues = computed(() => (this.mixed() ? [] : tagsOf(this.value())), /* @ts-ignore */
52568
52871
  ...(ngDevMode ? [{ debugName: "effectiveValues" }] : /* istanbul ignore next */ []));
52569
52872
  this.hasValue = computed(() => this.mixed() || this.effectiveValues().length > 0, /* @ts-ignore */
52570
52873
  ...(ngDevMode ? [{ debugName: "hasValue" }] : /* istanbul ignore next */ []));
@@ -52637,7 +52940,7 @@ class TagInputDirective extends TextShellControlDirective {
52637
52940
  if (!this.interactive() || this.mixed()) {
52638
52941
  return;
52639
52942
  }
52640
- const current = this.value();
52943
+ const current = tagsOf(this.value());
52641
52944
  // a no-op removal must not write: `filter` always allocates, so the model would notify with
52642
52945
  // an equal-but-new array and dirty the bound form field on a keystroke that changed nothing
52643
52946
  if (index < 0 || index >= current.length) {
@@ -54170,6 +54473,8 @@ class GridDirective {
54170
54473
  .join(', ')}. Configured breakpoints are ${known.map((name) => `"${name}"`).join(', ')}.`, state);
54171
54474
  }
54172
54475
  }
54476
+ for (const id of this.leavingIds())
54477
+ this.cancelLeave(id);
54173
54478
  const items = state.items.map((item) => ({
54174
54479
  id: item.id,
54175
54480
  type: item.type,
@@ -56815,8 +57120,21 @@ const runNotificationPromise = ({ content, open, injector, ...options }) => {
56815
57120
  const resolved = typeof source === 'function' ? source(result) : source;
56816
57121
  ref.replaceConfig({ ...toNotificationContent(resolved), status });
56817
57122
  };
57123
+ const cancel = () => {
57124
+ if (isReplacedByLaterOpen())
57125
+ return;
57126
+ ref.dismiss();
57127
+ };
56818
57128
  if (isQuery$1(work)) {
56819
- followQuery({ query: work, ref, settle, updateProgress, followProgress: loading.progress !== undefined, injector });
57129
+ followQuery({
57130
+ query: work,
57131
+ ref,
57132
+ settle,
57133
+ cancel,
57134
+ updateProgress,
57135
+ followProgress: loading.progress !== undefined,
57136
+ injector,
57137
+ });
56820
57138
  }
56821
57139
  else if (isObservable(work)) {
56822
57140
  let lastValue;
@@ -56848,18 +57166,39 @@ const runNotificationPromise = ({ content, open, injector, ...options }) => {
56848
57166
  * `QueryErrorResponse`, everything else an `unknown`), not to pick different code paths.
56849
57167
  */
56850
57168
  const createNotificationPromiseFn = (deps) => ((work, content) => runNotificationPromise({ ...deps, work, content }));
56851
- const followQuery = ({ query, ref, settle, updateProgress, followProgress, injector, }) => {
57169
+ const followQuery = ({ query, ref, settle, cancel, updateProgress, followProgress, injector, }) => {
56852
57170
  let effectRef = null;
56853
57171
  let hasSettled = false;
56854
57172
  const stopFollowing = () => {
56855
57173
  effectRef?.destroy();
56856
57174
  effectRef = null;
56857
57175
  };
57176
+ let hasSeenLoading = false;
57177
+ let eventBeforeLoading = null;
57178
+ const markLoading = () => {
57179
+ hasSeenLoading = true;
57180
+ eventBeforeLoading = untracked(() => query.latestHttpEvent());
57181
+ };
57182
+ // Read before the effect's first run, which an abort can beat.
57183
+ if (untracked(() => query.executionState())?.type === 'loading')
57184
+ markLoading();
56858
57185
  effectRef = effect(() => {
56859
57186
  const state = query.executionState();
56860
- if (!state || hasSettled)
57187
+ if (hasSettled)
56861
57188
  return;
57189
+ if (!state) {
57190
+ if (!hasSeenLoading)
57191
+ return;
57192
+ hasSettled = true;
57193
+ untracked(() => {
57194
+ cancel();
57195
+ stopFollowing();
57196
+ });
57197
+ return;
57198
+ }
56862
57199
  if (state.type === 'loading') {
57200
+ if (!hasSeenLoading)
57201
+ markLoading();
56863
57202
  const percentage = state.loading.progress?.percentage;
56864
57203
  if (followProgress && percentage !== undefined) {
56865
57204
  untracked(() => updateProgress(percentage));
@@ -56868,7 +57207,14 @@ const followQuery = ({ query, ref, settle, updateProgress, followProgress, injec
56868
57207
  }
56869
57208
  hasSettled = true;
56870
57209
  untracked(() => {
56871
- if (state.type === 'success') {
57210
+ const latestEvent = query.latestHttpEvent();
57211
+ // An aborted re-execution falls back to the previous round's response, which reads as a success.
57212
+ if (state.type === 'success' &&
57213
+ hasSeenLoading &&
57214
+ (latestEvent === eventBeforeLoading || latestEvent?.type !== HttpEventType.Response)) {
57215
+ cancel();
57216
+ }
57217
+ else if (state.type === 'success') {
56872
57218
  settle('success', state.response);
56873
57219
  }
56874
57220
  else {
@@ -59451,6 +59797,75 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
59451
59797
  args: [{ selector: 'et-scheduler-appointment-styles', template: '', encapsulation: ViewEncapsulation.None, styles: ["@layer components{.et-scheduler-appointment{display:flex;align-items:center;gap:6px;padding:2px 6px;border:none;border-radius:4px;background:color-mix(in srgb,var(--et-theme-color-primary-solid) 14%,transparent);color:var(--et-theme-color-ink-solid);font:inherit;font-size:12px;text-align:start;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent}@media(hover:hover){.et-scheduler-appointment:hover{background:color-mix(in srgb,var(--et-theme-color-primary-solid) 22%,transparent)}}.et-scheduler-appointment:focus-visible{outline:2px solid var(--et-theme-color-primary-solid);outline-offset:1px}.et-scheduler-appointment:where([data-selected]){background:var(--et-theme-color-primary-solid);color:var(--et-theme-color-on-primary)}.et-scheduler-appointment:where([data-draggable]){cursor:grab;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}.et-scheduler-appointment:where([data-dragging]){box-shadow:var(--et-scheduler-appointment-drag-shadow, 0 2px 8px rgb(var(--et-shadow-color-rgb, 0 0 0) / .25));cursor:grabbing}.et-scheduler-appointment-title{overflow:hidden;font-weight:600;min-inline-size:0;flex:1;text-overflow:ellipsis;white-space:nowrap}.et-scheduler-appointment-dot{flex-shrink:0;inline-size:6px;block-size:6px;border-radius:999px;background:var(--et-theme-color-primary-solid)}:where(.et-scheduler-appointment,.et-scheduler-time-grid-block):where([data-selected]) .et-scheduler-appointment-dot{background:var(--et-theme-color-on-primary)}.et-scheduler-appointment-time-range{flex-shrink:0;font-variant-numeric:tabular-nums;white-space:nowrap}.et-scheduler-appointment-location{display:flex;flex-shrink:0;align-items:center;gap:3px;max-inline-size:40%}.et-scheduler-appointment-location-icon{flex-shrink:0;inline-size:10px;block-size:10px}.et-scheduler-appointment-location-text{overflow:hidden;min-inline-size:0;text-overflow:ellipsis;white-space:nowrap}.et-scheduler-appointment-chain-count{display:flex;flex-shrink:0;align-items:center;gap:2px;font-variant-numeric:tabular-nums}.et-scheduler-appointment-chain-count-icon{inline-size:8px;block-size:8px;transform:rotate(90deg)}}\n"] }]
59452
59798
  }] });
59453
59799
 
59800
+ /**
59801
+ * The time-range piece of an appointment badge, stamped by `etSchedulerBadgeTimeRange`. Renders
59802
+ * nothing for an all-day appointment, which has no meaningful start/end time to show.
59803
+ *
59804
+ * @internal
59805
+ */
59806
+ class SchedulerBadgeTimeRangeComponent {
59807
+ constructor() {
59808
+ this.scheduler = inject(SchedulerDirective, { optional: true });
59809
+ this.node = input.required(/* @ts-ignore */
59810
+ ...(ngDevMode ? [{ debugName: "node" }] : /* istanbul ignore next */ []));
59811
+ this.range = computed(() => {
59812
+ const appointment = this.node().appointment;
59813
+ if (appointment.allDay) {
59814
+ return null;
59815
+ }
59816
+ const locale = this.scheduler?.effectiveLocale();
59817
+ const options = locale ? { locale } : undefined;
59818
+ return `${format(appointment.start, 'p', options)}–${format(appointment.end, 'p', options)}`;
59819
+ }, /* @ts-ignore */
59820
+ ...(ngDevMode ? [{ debugName: "range" }] : /* istanbul ignore next */ []));
59821
+ }
59822
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SchedulerBadgeTimeRangeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
59823
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SchedulerBadgeTimeRangeComponent, isStandalone: true, selector: "et-scheduler-badge-time-range", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
59824
+ @if (range(); as range) {
59825
+ <span class="et-scheduler-appointment-time-range">{{ range }}</span>
59826
+ }
59827
+ `, isInline: true, encapsulation: i0.ViewEncapsulation.None }); }
59828
+ }
59829
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SchedulerBadgeTimeRangeComponent, decorators: [{
59830
+ type: Component,
59831
+ args: [{
59832
+ selector: 'et-scheduler-badge-time-range',
59833
+ template: `
59834
+ @if (range(); as range) {
59835
+ <span class="et-scheduler-appointment-time-range">{{ range }}</span>
59836
+ }
59837
+ `,
59838
+ encapsulation: ViewEncapsulation.None,
59839
+ }]
59840
+ }], propDecorators: { node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: true }] }] } });
59841
+
59842
+ /**
59843
+ * The title piece of an appointment badge, stamped by `etSchedulerBadgeTitle`.
59844
+ *
59845
+ * @internal
59846
+ */
59847
+ class SchedulerBadgeTitleComponent {
59848
+ constructor() {
59849
+ this.node = input.required(/* @ts-ignore */
59850
+ ...(ngDevMode ? [{ debugName: "node" }] : /* istanbul ignore next */ []));
59851
+ }
59852
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SchedulerBadgeTitleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
59853
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: SchedulerBadgeTitleComponent, isStandalone: true, selector: "et-scheduler-badge-title", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `<span class="et-scheduler-appointment-title">{{ node().appointment.title }}</span>`, isInline: true, encapsulation: i0.ViewEncapsulation.None }); }
59854
+ }
59855
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SchedulerBadgeTitleComponent, decorators: [{
59856
+ type: Component,
59857
+ args: [{
59858
+ selector: 'et-scheduler-badge-title',
59859
+ template: `<span class="et-scheduler-appointment-title">{{ node().appointment.title }}</span>`,
59860
+ encapsulation: ViewEncapsulation.None,
59861
+ }]
59862
+ }], propDecorators: { node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: true }] }] } });
59863
+
59864
+ const SCHEDULER_FALLBACK_BADGE_ADORNMENTS = [
59865
+ { component: SchedulerBadgeTitleComponent, order: 0 },
59866
+ { component: SchedulerBadgeTimeRangeComponent, order: 10 },
59867
+ ];
59868
+
59454
59869
  /** The default agenda list: one section per visible day, appointments as full-width badges indented by chain depth. */
59455
59870
  class SchedulerAgendaViewComponent {
59456
59871
  constructor() {
@@ -59473,7 +59888,7 @@ class SchedulerAgendaViewComponent {
59473
59888
  injectStyleManager().mount(SchedulerAppointmentStylesComponent);
59474
59889
  }
59475
59890
  badgeAdornments() {
59476
- return this.featureHost?.badgeAdornments() ?? [];
59891
+ return this.featureHost?.badgeAdornments() ?? SCHEDULER_FALLBACK_BADGE_ADORNMENTS;
59477
59892
  }
59478
59893
  weekdayLabel(date) {
59479
59894
  const locale = this.scheduler?.effectiveLocale();
@@ -59754,48 +60169,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
59754
60169
  }]
59755
60170
  }], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "etSchedulerBadgeLocation", required: false }] }] } });
59756
60171
 
59757
- /**
59758
- * The time-range piece of an appointment badge, stamped by `etSchedulerBadgeTimeRange`. Renders
59759
- * nothing for an all-day appointment, which has no meaningful start/end time to show.
59760
- *
59761
- * @internal
59762
- */
59763
- class SchedulerBadgeTimeRangeComponent {
59764
- constructor() {
59765
- this.scheduler = inject(SchedulerDirective, { optional: true });
59766
- this.node = input.required(/* @ts-ignore */
59767
- ...(ngDevMode ? [{ debugName: "node" }] : /* istanbul ignore next */ []));
59768
- this.range = computed(() => {
59769
- const appointment = this.node().appointment;
59770
- if (appointment.allDay) {
59771
- return null;
59772
- }
59773
- const locale = this.scheduler?.effectiveLocale();
59774
- const options = locale ? { locale } : undefined;
59775
- return `${format(appointment.start, 'p', options)}–${format(appointment.end, 'p', options)}`;
59776
- }, /* @ts-ignore */
59777
- ...(ngDevMode ? [{ debugName: "range" }] : /* istanbul ignore next */ []));
59778
- }
59779
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SchedulerBadgeTimeRangeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
59780
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SchedulerBadgeTimeRangeComponent, isStandalone: true, selector: "et-scheduler-badge-time-range", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
59781
- @if (range(); as range) {
59782
- <span class="et-scheduler-appointment-time-range">{{ range }}</span>
59783
- }
59784
- `, isInline: true, encapsulation: i0.ViewEncapsulation.None }); }
59785
- }
59786
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SchedulerBadgeTimeRangeComponent, decorators: [{
59787
- type: Component,
59788
- args: [{
59789
- selector: 'et-scheduler-badge-time-range',
59790
- template: `
59791
- @if (range(); as range) {
59792
- <span class="et-scheduler-appointment-time-range">{{ range }}</span>
59793
- }
59794
- `,
59795
- encapsulation: ViewEncapsulation.None,
59796
- }]
59797
- }], propDecorators: { node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: true }] }] } });
59798
-
59799
60172
  /**
59800
60173
  * Built-in badge adornment: the appointment's `start`–`end` time, hidden for an all-day
59801
60174
  * appointment. One of the default pieces `<et-scheduler>` bundles - see `registerBadgeAdornment`.
@@ -59826,28 +60199,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
59826
60199
  }]
59827
60200
  }], ctorParameters: () => [], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "etSchedulerBadgeTimeRange", required: false }] }] } });
59828
60201
 
59829
- /**
59830
- * The title piece of an appointment badge, stamped by `etSchedulerBadgeTitle`.
59831
- *
59832
- * @internal
59833
- */
59834
- class SchedulerBadgeTitleComponent {
59835
- constructor() {
59836
- this.node = input.required(/* @ts-ignore */
59837
- ...(ngDevMode ? [{ debugName: "node" }] : /* istanbul ignore next */ []));
59838
- }
59839
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SchedulerBadgeTitleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
59840
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: SchedulerBadgeTitleComponent, isStandalone: true, selector: "et-scheduler-badge-title", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `<span class="et-scheduler-appointment-title">{{ node().appointment.title }}</span>`, isInline: true, encapsulation: i0.ViewEncapsulation.None }); }
59841
- }
59842
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SchedulerBadgeTitleComponent, decorators: [{
59843
- type: Component,
59844
- args: [{
59845
- selector: 'et-scheduler-badge-title',
59846
- template: `<span class="et-scheduler-appointment-title">{{ node().appointment.title }}</span>`,
59847
- encapsulation: ViewEncapsulation.None,
59848
- }]
59849
- }], propDecorators: { node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: true }] }] } });
59850
-
59851
60202
  /**
59852
60203
  * Built-in badge adornment: the appointment's title. One of the default pieces `<et-scheduler>`
59853
60204
  * bundles - see `registerBadgeAdornment`.
@@ -60843,7 +61194,7 @@ class SchedulerMonthViewComponent {
60843
61194
  injectStyleManager().mount(SchedulerAppointmentStylesComponent);
60844
61195
  }
60845
61196
  badgeAdornments() {
60846
- return this.featureHost?.badgeAdornments() ?? [];
61197
+ return this.featureHost?.badgeAdornments() ?? SCHEDULER_FALLBACK_BADGE_ADORNMENTS;
60847
61198
  }
60848
61199
  weekdays() {
60849
61200
  return this.scheduler?.weekdays() ?? [];
@@ -61195,7 +61546,7 @@ class SchedulerTimeGridViewComponent {
61195
61546
  });
61196
61547
  }
61197
61548
  badgeAdornments() {
61198
- return this.featureHost?.badgeAdornments() ?? [];
61549
+ return this.featureHost?.badgeAdornments() ?? SCHEDULER_FALLBACK_BADGE_ADORNMENTS;
61199
61550
  }
61200
61551
  weekdayLabel(date) {
61201
61552
  const locale = this.scheduler?.effectiveLocale();
@@ -61524,10 +61875,15 @@ class SchedulerComponent {
61524
61875
  */
61525
61876
  this.headless = inject(SchedulerDirective);
61526
61877
  this.elementRef = inject(ElementRef);
61878
+ /** Every appointment the scheduler knows about - not pre-filtered to the visible range. */
61879
+ this.appointments = input([], /* @ts-ignore */
61880
+ ...(ngDevMode ? [{ debugName: "appointments" }] : /* istanbul ignore next */ []));
61527
61881
  /** Emits the edited or newly-added appointment once the edit surface saves. */
61528
61882
  this.appointmentSave = output();
61529
61883
  /** Emits every id to remove once the edit surface deletes a chain. */
61530
61884
  this.appointmentsDelete = output();
61885
+ /** Emits when a move or resize lands an appointment somewhere else - see `SchedulerDirective.appointmentReschedule`. */
61886
+ this.appointmentReschedule = outputFromObservable(outputToObservable(this.headless.appointmentReschedule));
61531
61887
  this.dimensions = signalHostElementDimensions();
61532
61888
  this.isNarrow = computed(() => (this.dimensions().client?.width ?? Infinity) < NARROW_CONTAINER_WIDTH, /* @ts-ignore */
61533
61889
  ...(ngDevMode ? [{ debugName: "isNarrow" }] : /* istanbul ignore next */ []));
@@ -61620,7 +61976,7 @@ class SchedulerComponent {
61620
61976
  get selectedAppointment() {
61621
61977
  return this.headless.selectedAppointment;
61622
61978
  }
61623
- appointments() {
61979
+ visibleAppointments() {
61624
61980
  return this.headless.visibleAppointments();
61625
61981
  }
61626
61982
  registerBadgeAdornment(adornment) {
@@ -61725,10 +62081,10 @@ class SchedulerComponent {
61725
62081
  }
61726
62082
  }
61727
62083
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SchedulerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
61728
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SchedulerComponent, isStandalone: true, selector: "et-scheduler", outputs: { appointmentSave: "appointmentSave", appointmentsDelete: "appointmentsDelete" }, host: { classAttribute: "et-scheduler" }, providers: [
62084
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SchedulerComponent, isStandalone: true, selector: "et-scheduler", inputs: { appointments: { classPropertyName: "appointments", publicName: "appointments", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { appointmentSave: "appointmentSave", appointmentsDelete: "appointmentsDelete", appointmentReschedule: "appointmentReschedule" }, host: { classAttribute: "et-scheduler" }, providers: [
61729
62085
  provideIcons(CALENDAR_ICON, CHEVRON_ICON, PLUS_ICON),
61730
62086
  { provide: SCHEDULER_FEATURE_HOST, useExisting: SchedulerComponent },
61731
- ], hostDirectives: [{ directive: SchedulerDirective, inputs: ["appointments", "appointments", "view", "view", "focusedDate", "focusedDate", "selectedAppointmentId", "selectedAppointmentId", "locale", "locale", "firstDayOfWeek", "firstDayOfWeek", "agendaDays", "agendaDays", "businessHours", "businessHours", "nowIndicator", "nowIndicator"], outputs: ["viewChange", "viewChange", "focusedDateChange", "focusedDateChange", "selectedAppointmentIdChange", "selectedAppointmentIdChange", "appointmentReschedule", "appointmentReschedule"] }, { directive: SchedulerBadgeColorDotDirective, inputs: ["etSchedulerBadgeColorDot", "etSchedulerBadgeColorDot"] }, { directive: SchedulerBadgeTitleDirective, inputs: ["etSchedulerBadgeTitle", "etSchedulerBadgeTitle"] }, { directive: SchedulerBadgeTimeRangeDirective, inputs: ["etSchedulerBadgeTimeRange", "etSchedulerBadgeTimeRange"] }, { directive: SchedulerBadgeLocationDirective, inputs: ["etSchedulerBadgeLocation", "etSchedulerBadgeLocation"] }, { directive: SchedulerBadgeChainCountDirective, inputs: ["etSchedulerBadgeChainCount", "etSchedulerBadgeChainCount"] }, { directive: SchedulerActionAddAppointmentDirective, inputs: ["etSchedulerActionAddAppointment", "etSchedulerActionAddAppointment"] }, { directive: SchedulerSwipeNavigationDirective, inputs: ["etSchedulerSwipeNavigation", "etSchedulerSwipeNavigation"] }, { directive: SchedulerAppointmentDragDirective, inputs: ["etSchedulerAppointmentDrag", "etSchedulerAppointmentDrag"] }], ngImport: i0, template: "<div class=\"et-scheduler-header\">\n <button\n [attr.aria-label]=\"todayLabel()\"\n (click)=\"headless.goToToday()\"\n class=\"et-scheduler-today-button\"\n et-button\n size=\"sm\"\n variant=\"outline\"\n type=\"button\"\n >\n <i etIcon=\"et-calendar\" aria-hidden=\"true\"></i>\n <span class=\"et-scheduler-today-button-label\">{{ todayLabel() }}</span>\n </button>\n\n @if (isNarrow()) {\n <div class=\"et-scheduler-toolbar-fabs\" etFloatingAction>\n <div etFloatingActionAnchor>\n <div class=\"et-scheduler-toolbar-fab-stack\" etFloatingActionTrigger>\n @for (action of toolbarActions(); track $index) {\n @if (action.icon; as icon) {\n <button\n [attr.aria-label]=\"action.label()\"\n (click)=\"action.run()\"\n class=\"et-scheduler-toolbar-action\"\n et-fab\n type=\"button\"\n >\n <i [etIcon]=\"icon\" aria-hidden=\"true\"></i>\n </button>\n } @else {\n <button (click)=\"action.run()\" class=\"et-scheduler-toolbar-action\" et-fab expanded type=\"button\">\n {{ action.label() }}\n </button>\n }\n }\n </div>\n </div>\n </div>\n } @else {\n @for (action of toolbarActions(); track $index) {\n <button (click)=\"action.run()\" class=\"et-scheduler-toolbar-action\" et-button size=\"sm\" type=\"button\">\n @if (action.icon) {\n <i [etIcon]=\"action.icon\" aria-hidden=\"true\"></i>\n }\n {{ action.label() }}\n </button>\n }\n }\n\n <div class=\"et-scheduler-nav-buttons\">\n <button\n [attr.aria-label]=\"previousLabel()\"\n (click)=\"headless.previous()\"\n class=\"et-scheduler-nav-button et-scheduler-nav-button--previous\"\n et-icon-button\n size=\"sm\"\n type=\"button\"\n >\n <i etIcon=\"et-chevron\"></i>\n </button>\n\n <button\n [attr.aria-label]=\"nextLabel()\"\n (click)=\"headless.next()\"\n class=\"et-scheduler-nav-button et-scheduler-nav-button--next\"\n et-icon-button\n size=\"sm\"\n type=\"button\"\n >\n <i etIcon=\"et-chevron\"></i>\n </button>\n </div>\n\n <span class=\"et-scheduler-header-label\">{{ headerLabel() }}</span>\n\n <div class=\"et-scheduler-header-spacer\"></div>\n\n <et-segmented-button-group\n [value]=\"headless.view()\"\n (valueChange)=\"setView($event)\"\n class=\"et-scheduler-view-switch\"\n size=\"sm\"\n variant=\"tabs\"\n >\n <et-label class=\"et-visually-hidden et-scheduler-view-switch-label\">{{ switchViewLabel() }}</et-label>\n\n <et-segmented-button value=\"month\">{{ monthViewLabel() }}</et-segmented-button>\n <et-segmented-button value=\"week\">{{ weekViewLabel() }}</et-segmented-button>\n <et-segmented-button value=\"day\">{{ dayViewLabel() }}</et-segmented-button>\n <et-segmented-button value=\"agenda\">{{ agendaViewLabel() }}</et-segmented-button>\n </et-segmented-button-group>\n</div>\n\n<div class=\"et-scheduler-body\">\n @switch (headless.view()) {\n @case ('agenda') {\n <et-scheduler-agenda-view />\n }\n @case ('month') {\n <et-scheduler-month-view [attr.aria-label]=\"headerLabel()\" />\n }\n @default {\n <et-scheduler-time-grid-view [attr.aria-label]=\"headerLabel()\" />\n }\n }\n</div>\n", styles: ["@layer components{.et-scheduler{container-type:inline-size;container-name:et-scheduler;display:flex;flex-direction:column;gap:12px}.et-scheduler-header{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.et-scheduler-view-switch{flex-basis:100%}.et-scheduler-toolbar-fab-stack{display:flex;gap:8px}@container et-scheduler not (min-inline-size: 480px){.et-scheduler .et-scheduler-today-button{--et-button-padding: 0;inline-size:3.1rem;block-size:3.1rem;border-radius:9999px}.et-scheduler .et-scheduler-today-button-label{display:none}}@container et-scheduler (min-inline-size: 480px){.et-scheduler-header-spacer{display:block}.et-scheduler-view-switch{flex-basis:auto}.et-scheduler .et-scheduler-today-button .et-button-icon{display:none}}.et-scheduler-nav-buttons{display:flex;gap:2px}.et-scheduler-nav-button--previous .et-icon{rotate:-90deg}.et-scheduler-nav-button--next .et-icon{rotate:90deg}.et-scheduler-header-label{flex:1 1 auto;min-inline-size:0;overflow:hidden;font-size:15px;font-weight:600;color:var(--et-surface-color-solid);white-space:nowrap;text-overflow:ellipsis}.et-scheduler-header-spacer{display:none;flex:1}.et-scheduler-body{display:flex;flex:1;flex-direction:column}}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "[et-button]", inputs: ["variant", "size", "iconAlignment"] }, { kind: "component", type: FabComponent, selector: "[et-fab]", inputs: ["variant", "size", "expanded", "iconAlignment"] }, { kind: "component", type: IconButtonComponent, selector: "[et-icon-button]", inputs: ["variant", "size"] }, { kind: "directive", type: FloatingActionDirective, selector: "[etFloatingAction]", inputs: ["disabled"], exportAs: ["etFloatingAction"] }, { kind: "directive", type: FloatingActionAnchorDirective, selector: "[etFloatingActionAnchor]", exportAs: ["etFloatingActionAnchor"] }, { kind: "directive", type: FloatingActionTriggerDirective, selector: "[etFloatingActionTrigger]", exportAs: ["etFloatingActionTrigger"] }, { kind: "component", type: SegmentedButtonGroupComponent, selector: "et-segmented-button-group", inputs: ["size", "variant"] }, { kind: "component", type: SegmentedButtonComponent, selector: "et-segmented-button" }, { kind: "component", type: LabelDirective, selector: "et-label" }, { kind: "directive", type: IconDirective, selector: "[etIcon]", inputs: ["etIcon", "variant", "allowHardcodedColor", "label"] }, { kind: "component", type: SchedulerAgendaViewComponent, selector: "et-scheduler-agenda-view" }, { kind: "component", type: SchedulerMonthViewComponent, selector: "et-scheduler-month-view" }, { kind: "component", type: SchedulerTimeGridViewComponent, selector: "et-scheduler-time-grid-view" }], encapsulation: i0.ViewEncapsulation.None }); }
62087
+ ], hostDirectives: [{ directive: SchedulerDirective, inputs: ["appointments", "appointments", "view", "view", "focusedDate", "focusedDate", "selectedAppointmentId", "selectedAppointmentId", "locale", "locale", "firstDayOfWeek", "firstDayOfWeek", "agendaDays", "agendaDays", "businessHours", "businessHours", "nowIndicator", "nowIndicator"], outputs: ["viewChange", "viewChange", "focusedDateChange", "focusedDateChange", "selectedAppointmentIdChange", "selectedAppointmentIdChange"] }, { directive: SchedulerBadgeColorDotDirective, inputs: ["etSchedulerBadgeColorDot", "etSchedulerBadgeColorDot"] }, { directive: SchedulerBadgeTitleDirective, inputs: ["etSchedulerBadgeTitle", "etSchedulerBadgeTitle"] }, { directive: SchedulerBadgeTimeRangeDirective, inputs: ["etSchedulerBadgeTimeRange", "etSchedulerBadgeTimeRange"] }, { directive: SchedulerBadgeLocationDirective, inputs: ["etSchedulerBadgeLocation", "etSchedulerBadgeLocation"] }, { directive: SchedulerBadgeChainCountDirective, inputs: ["etSchedulerBadgeChainCount", "etSchedulerBadgeChainCount"] }, { directive: SchedulerActionAddAppointmentDirective, inputs: ["etSchedulerActionAddAppointment", "etSchedulerActionAddAppointment"] }, { directive: SchedulerSwipeNavigationDirective, inputs: ["etSchedulerSwipeNavigation", "etSchedulerSwipeNavigation"] }, { directive: SchedulerAppointmentDragDirective, inputs: ["etSchedulerAppointmentDrag", "etSchedulerAppointmentDrag"] }], ngImport: i0, template: "<div class=\"et-scheduler-header\">\n <button\n [attr.aria-label]=\"todayLabel()\"\n (click)=\"headless.goToToday()\"\n class=\"et-scheduler-today-button\"\n et-button\n size=\"sm\"\n variant=\"outline\"\n type=\"button\"\n >\n <i etIcon=\"et-calendar\" aria-hidden=\"true\"></i>\n <span class=\"et-scheduler-today-button-label\">{{ todayLabel() }}</span>\n </button>\n\n @if (isNarrow()) {\n <div class=\"et-scheduler-toolbar-fabs\" etFloatingAction>\n <div etFloatingActionAnchor>\n <div class=\"et-scheduler-toolbar-fab-stack\" etFloatingActionTrigger>\n @for (action of toolbarActions(); track $index) {\n @if (action.icon; as icon) {\n <button\n [attr.aria-label]=\"action.label()\"\n (click)=\"action.run()\"\n class=\"et-scheduler-toolbar-action\"\n et-fab\n type=\"button\"\n >\n <i [etIcon]=\"icon\" aria-hidden=\"true\"></i>\n </button>\n } @else {\n <button (click)=\"action.run()\" class=\"et-scheduler-toolbar-action\" et-fab expanded type=\"button\">\n {{ action.label() }}\n </button>\n }\n }\n </div>\n </div>\n </div>\n } @else {\n @for (action of toolbarActions(); track $index) {\n <button (click)=\"action.run()\" class=\"et-scheduler-toolbar-action\" et-button size=\"sm\" type=\"button\">\n @if (action.icon) {\n <i [etIcon]=\"action.icon\" aria-hidden=\"true\"></i>\n }\n {{ action.label() }}\n </button>\n }\n }\n\n <div class=\"et-scheduler-nav-buttons\">\n <button\n [attr.aria-label]=\"previousLabel()\"\n (click)=\"headless.previous()\"\n class=\"et-scheduler-nav-button et-scheduler-nav-button--previous\"\n et-icon-button\n size=\"sm\"\n type=\"button\"\n >\n <i etIcon=\"et-chevron\"></i>\n </button>\n\n <button\n [attr.aria-label]=\"nextLabel()\"\n (click)=\"headless.next()\"\n class=\"et-scheduler-nav-button et-scheduler-nav-button--next\"\n et-icon-button\n size=\"sm\"\n type=\"button\"\n >\n <i etIcon=\"et-chevron\"></i>\n </button>\n </div>\n\n <span class=\"et-scheduler-header-label\">{{ headerLabel() }}</span>\n\n <div class=\"et-scheduler-header-spacer\"></div>\n\n <et-segmented-button-group\n [value]=\"headless.view()\"\n (valueChange)=\"setView($event)\"\n class=\"et-scheduler-view-switch\"\n size=\"sm\"\n variant=\"tabs\"\n >\n <et-label class=\"et-visually-hidden et-scheduler-view-switch-label\">{{ switchViewLabel() }}</et-label>\n\n <et-segmented-button value=\"month\">{{ monthViewLabel() }}</et-segmented-button>\n <et-segmented-button value=\"week\">{{ weekViewLabel() }}</et-segmented-button>\n <et-segmented-button value=\"day\">{{ dayViewLabel() }}</et-segmented-button>\n <et-segmented-button value=\"agenda\">{{ agendaViewLabel() }}</et-segmented-button>\n </et-segmented-button-group>\n</div>\n\n<div class=\"et-scheduler-body\">\n @switch (headless.view()) {\n @case ('agenda') {\n <et-scheduler-agenda-view />\n }\n @case ('month') {\n <et-scheduler-month-view [attr.aria-label]=\"headerLabel()\" />\n }\n @default {\n <et-scheduler-time-grid-view [attr.aria-label]=\"headerLabel()\" />\n }\n }\n</div>\n", styles: ["@layer components{.et-scheduler{container-type:inline-size;container-name:et-scheduler;display:flex;flex-direction:column;gap:12px}.et-scheduler-header{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.et-scheduler-view-switch{flex-basis:100%}.et-scheduler-toolbar-fab-stack{display:flex;gap:8px}@container et-scheduler not (min-inline-size: 480px){.et-scheduler .et-scheduler-today-button{--et-button-padding: 0;inline-size:3.1rem;block-size:3.1rem;border-radius:9999px}.et-scheduler .et-scheduler-today-button-label{display:none}}@container et-scheduler (min-inline-size: 480px){.et-scheduler-header-spacer{display:block}.et-scheduler-view-switch{flex-basis:auto}.et-scheduler .et-scheduler-today-button .et-button-icon{display:none}}.et-scheduler-nav-buttons{display:flex;gap:2px}.et-scheduler-nav-button--previous .et-icon{rotate:-90deg}.et-scheduler-nav-button--next .et-icon{rotate:90deg}.et-scheduler-header-label{flex:1 1 auto;min-inline-size:0;overflow:hidden;font-size:15px;font-weight:600;color:var(--et-surface-color-solid);white-space:nowrap;text-overflow:ellipsis}.et-scheduler-header-spacer{display:none;flex:1}.et-scheduler-body{display:flex;flex:1;flex-direction:column}}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "[et-button]", inputs: ["variant", "size", "iconAlignment"] }, { kind: "component", type: FabComponent, selector: "[et-fab]", inputs: ["variant", "size", "expanded", "iconAlignment"] }, { kind: "component", type: IconButtonComponent, selector: "[et-icon-button]", inputs: ["variant", "size"] }, { kind: "directive", type: FloatingActionDirective, selector: "[etFloatingAction]", inputs: ["disabled"], exportAs: ["etFloatingAction"] }, { kind: "directive", type: FloatingActionAnchorDirective, selector: "[etFloatingActionAnchor]", exportAs: ["etFloatingActionAnchor"] }, { kind: "directive", type: FloatingActionTriggerDirective, selector: "[etFloatingActionTrigger]", exportAs: ["etFloatingActionTrigger"] }, { kind: "component", type: SegmentedButtonGroupComponent, selector: "et-segmented-button-group", inputs: ["size", "variant"] }, { kind: "component", type: SegmentedButtonComponent, selector: "et-segmented-button" }, { kind: "component", type: LabelDirective, selector: "et-label" }, { kind: "directive", type: IconDirective, selector: "[etIcon]", inputs: ["etIcon", "variant", "allowHardcodedColor", "label"] }, { kind: "component", type: SchedulerAgendaViewComponent, selector: "et-scheduler-agenda-view" }, { kind: "component", type: SchedulerMonthViewComponent, selector: "et-scheduler-month-view" }, { kind: "component", type: SchedulerTimeGridViewComponent, selector: "et-scheduler-time-grid-view" }], encapsulation: i0.ViewEncapsulation.None }); }
61732
62088
  }
61733
62089
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SchedulerComponent, decorators: [{
61734
62090
  type: Component,
@@ -61758,7 +62114,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
61758
62114
  'businessHours',
61759
62115
  'nowIndicator',
61760
62116
  ],
61761
- outputs: ['viewChange', 'focusedDateChange', 'selectedAppointmentIdChange', 'appointmentReschedule'],
62117
+ outputs: ['viewChange', 'focusedDateChange', 'selectedAppointmentIdChange'],
61762
62118
  },
61763
62119
  { directive: SchedulerBadgeColorDotDirective, inputs: ['etSchedulerBadgeColorDot'] },
61764
62120
  { directive: SchedulerBadgeTitleDirective, inputs: ['etSchedulerBadgeTitle'] },
@@ -61771,7 +62127,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
61771
62127
  ], host: {
61772
62128
  class: 'et-scheduler',
61773
62129
  }, template: "<div class=\"et-scheduler-header\">\n <button\n [attr.aria-label]=\"todayLabel()\"\n (click)=\"headless.goToToday()\"\n class=\"et-scheduler-today-button\"\n et-button\n size=\"sm\"\n variant=\"outline\"\n type=\"button\"\n >\n <i etIcon=\"et-calendar\" aria-hidden=\"true\"></i>\n <span class=\"et-scheduler-today-button-label\">{{ todayLabel() }}</span>\n </button>\n\n @if (isNarrow()) {\n <div class=\"et-scheduler-toolbar-fabs\" etFloatingAction>\n <div etFloatingActionAnchor>\n <div class=\"et-scheduler-toolbar-fab-stack\" etFloatingActionTrigger>\n @for (action of toolbarActions(); track $index) {\n @if (action.icon; as icon) {\n <button\n [attr.aria-label]=\"action.label()\"\n (click)=\"action.run()\"\n class=\"et-scheduler-toolbar-action\"\n et-fab\n type=\"button\"\n >\n <i [etIcon]=\"icon\" aria-hidden=\"true\"></i>\n </button>\n } @else {\n <button (click)=\"action.run()\" class=\"et-scheduler-toolbar-action\" et-fab expanded type=\"button\">\n {{ action.label() }}\n </button>\n }\n }\n </div>\n </div>\n </div>\n } @else {\n @for (action of toolbarActions(); track $index) {\n <button (click)=\"action.run()\" class=\"et-scheduler-toolbar-action\" et-button size=\"sm\" type=\"button\">\n @if (action.icon) {\n <i [etIcon]=\"action.icon\" aria-hidden=\"true\"></i>\n }\n {{ action.label() }}\n </button>\n }\n }\n\n <div class=\"et-scheduler-nav-buttons\">\n <button\n [attr.aria-label]=\"previousLabel()\"\n (click)=\"headless.previous()\"\n class=\"et-scheduler-nav-button et-scheduler-nav-button--previous\"\n et-icon-button\n size=\"sm\"\n type=\"button\"\n >\n <i etIcon=\"et-chevron\"></i>\n </button>\n\n <button\n [attr.aria-label]=\"nextLabel()\"\n (click)=\"headless.next()\"\n class=\"et-scheduler-nav-button et-scheduler-nav-button--next\"\n et-icon-button\n size=\"sm\"\n type=\"button\"\n >\n <i etIcon=\"et-chevron\"></i>\n </button>\n </div>\n\n <span class=\"et-scheduler-header-label\">{{ headerLabel() }}</span>\n\n <div class=\"et-scheduler-header-spacer\"></div>\n\n <et-segmented-button-group\n [value]=\"headless.view()\"\n (valueChange)=\"setView($event)\"\n class=\"et-scheduler-view-switch\"\n size=\"sm\"\n variant=\"tabs\"\n >\n <et-label class=\"et-visually-hidden et-scheduler-view-switch-label\">{{ switchViewLabel() }}</et-label>\n\n <et-segmented-button value=\"month\">{{ monthViewLabel() }}</et-segmented-button>\n <et-segmented-button value=\"week\">{{ weekViewLabel() }}</et-segmented-button>\n <et-segmented-button value=\"day\">{{ dayViewLabel() }}</et-segmented-button>\n <et-segmented-button value=\"agenda\">{{ agendaViewLabel() }}</et-segmented-button>\n </et-segmented-button-group>\n</div>\n\n<div class=\"et-scheduler-body\">\n @switch (headless.view()) {\n @case ('agenda') {\n <et-scheduler-agenda-view />\n }\n @case ('month') {\n <et-scheduler-month-view [attr.aria-label]=\"headerLabel()\" />\n }\n @default {\n <et-scheduler-time-grid-view [attr.aria-label]=\"headerLabel()\" />\n }\n }\n</div>\n", styles: ["@layer components{.et-scheduler{container-type:inline-size;container-name:et-scheduler;display:flex;flex-direction:column;gap:12px}.et-scheduler-header{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.et-scheduler-view-switch{flex-basis:100%}.et-scheduler-toolbar-fab-stack{display:flex;gap:8px}@container et-scheduler not (min-inline-size: 480px){.et-scheduler .et-scheduler-today-button{--et-button-padding: 0;inline-size:3.1rem;block-size:3.1rem;border-radius:9999px}.et-scheduler .et-scheduler-today-button-label{display:none}}@container et-scheduler (min-inline-size: 480px){.et-scheduler-header-spacer{display:block}.et-scheduler-view-switch{flex-basis:auto}.et-scheduler .et-scheduler-today-button .et-button-icon{display:none}}.et-scheduler-nav-buttons{display:flex;gap:2px}.et-scheduler-nav-button--previous .et-icon{rotate:-90deg}.et-scheduler-nav-button--next .et-icon{rotate:90deg}.et-scheduler-header-label{flex:1 1 auto;min-inline-size:0;overflow:hidden;font-size:15px;font-weight:600;color:var(--et-surface-color-solid);white-space:nowrap;text-overflow:ellipsis}.et-scheduler-header-spacer{display:none;flex:1}.et-scheduler-body{display:flex;flex:1;flex-direction:column}}\n"] }]
61774
- }], ctorParameters: () => [], propDecorators: { appointmentSave: [{ type: i0.Output, args: ["appointmentSave"] }], appointmentsDelete: [{ type: i0.Output, args: ["appointmentsDelete"] }] } });
62130
+ }], ctorParameters: () => [], propDecorators: { appointments: [{ type: i0.Input, args: [{ isSignal: true, alias: "appointments", required: false }] }], appointmentSave: [{ type: i0.Output, args: ["appointmentSave"] }], appointmentsDelete: [{ type: i0.Output, args: ["appointmentsDelete"] }], appointmentReschedule: [{ type: i0.Output, args: ["appointmentReschedule"] }] } });
61775
62131
 
61776
62132
  const SCHEDULER_IMPORTS = [
61777
62133
  SchedulerDirective,
@@ -67437,6 +67793,8 @@ const TABLE_ERROR_CODES = {
67437
67793
  MISSING_COLUMN_FEATURE: 3512,
67438
67794
  /** A CSV export read an object, list or function from a column that has no `exportValue`. */
67439
67795
  UNSERIALIZABLE_EXPORT_VALUE: 3513,
67796
+ /** Client sorting read an object, list or function from a sortable column that has no `sortValue`. */
67797
+ UNSORTABLE_COLUMN_VALUE: 3514,
67440
67798
  };
67441
67799
 
67442
67800
  // What tells Excel the file is UTF-8; see `bom`.
@@ -68036,6 +68394,17 @@ const isMissing = (value) => value === null ||
68036
68394
  value === undefined ||
68037
68395
  (typeof value === 'number' && Number.isNaN(value)) ||
68038
68396
  (value instanceof Date && Number.isNaN(value.getTime()));
68397
+ const isSortValue = (value) => value === null ||
68398
+ value === undefined ||
68399
+ value instanceof Date ||
68400
+ typeof value === 'string' ||
68401
+ typeof value === 'number' ||
68402
+ typeof value === 'boolean';
68403
+ const assertSortValue = (value, key) => {
68404
+ if (isSortValue(value))
68405
+ return;
68406
+ throw new RuntimeError(TABLE_ERROR_CODES.UNSORTABLE_COLUMN_VALUE, `[et-table] Sorting read a ${Array.isArray(value) ? 'list' : typeof value} from the "${key}" column's value, which cannot be compared. Add \`sortValue\` to the column.`);
68407
+ };
68039
68408
  const compare = (a, b) => {
68040
68409
  if (isMissing(a) && isMissing(b))
68041
68410
  return 0;
@@ -68056,7 +68425,8 @@ const compare = (a, b) => {
68056
68425
  * `value` accessor). Stable, multi-key, pure and tree-shakable - the base table
68057
68426
  * doesn't apply it unless in client sort mode; import it directly for custom flows.
68058
68427
  * Server-side callers ignore this and let the backend sort instead. Nullish values,
68059
- * `NaN` and invalid dates always sink to the bottom, regardless of direction.
68428
+ * `NaN` and invalid dates always sink to the bottom, regardless of direction. In dev mode, a column
68429
+ * without `sortValue` whose `value` returns an object, list or function throws `ET3514`.
68060
68430
  */
68061
68431
  const sortRows = ({ rows, sort, columns }) => {
68062
68432
  if (!sort.length)
@@ -68069,6 +68439,10 @@ const sortRows = ({ rows, sort, columns }) => {
68069
68439
  const accessor = column.sortValue ?? column.value;
68070
68440
  const valueA = accessor(rowA);
68071
68441
  const valueB = accessor(rowB);
68442
+ if (isDevMode$1() && !column.sortValue) {
68443
+ assertSortValue(valueA, key);
68444
+ assertSortValue(valueB, key);
68445
+ }
68072
68446
  if (isMissing(valueA) || isMissing(valueB)) {
68073
68447
  const nullCmp = compare(valueA, valueB);
68074
68448
  if (nullCmp !== 0)
@@ -69195,6 +69569,44 @@ class TableComponent {
69195
69569
  return { start: window.paddingStart(), end: window.paddingEnd() };
69196
69570
  }, /* @ts-ignore */
69197
69571
  ...(ngDevMode ? [{ debugName: "spacers" }] : /* istanbul ignore next */ []));
69572
+ this.openDetailIndices = computed(() => {
69573
+ const detail = this.rowDetail();
69574
+ if (!detail || !this.rowWindow())
69575
+ return [];
69576
+ const indices = [];
69577
+ this.rows().forEach((row, index) => {
69578
+ if (detail.isOpen(row))
69579
+ indices.push(index);
69580
+ });
69581
+ return indices;
69582
+ }, /* @ts-ignore */
69583
+ ...(ngDevMode ? [{ debugName: "openDetailIndices" }] : /* istanbul ignore next */ []));
69584
+ this.measuredDetailHeights = signal(new Map(), /* @ts-ignore */
69585
+ ...(ngDevMode ? [{ debugName: "measuredDetailHeights" }] : /* istanbul ignore next */ []));
69586
+ this.openDetailHeights = computed(() => {
69587
+ const open = this.openDetailIndices();
69588
+ if (!open.length)
69589
+ return new Map();
69590
+ const measured = this.measuredDetailHeights();
69591
+ const rows = this.rows();
69592
+ const fallback = measured.size
69593
+ ? [...measured.values()].reduce((sum, height) => sum + height, 0) / measured.size
69594
+ : 0;
69595
+ return new Map(open.map((index) => [index, measured.get(this.rowIdentity(rows[index])) ?? fallback]));
69596
+ }, /* @ts-ignore */
69597
+ ...(ngDevMode ? [{ debugName: "openDetailHeights" }] : /* istanbul ignore next */ []));
69598
+ this.headerRowCount = computed(() => this.headerRows().length + 1, /* @ts-ignore */
69599
+ ...(ngDevMode ? [{ debugName: "headerRowCount" }] : /* istanbul ignore next */ []));
69600
+ /**
69601
+ * The full row count a windowed table announces through `aria-rowcount` - header rows, every body row,
69602
+ * every open detail row and the footer row - or `null` while every row is in the DOM anyway.
69603
+ */
69604
+ this.ariaRowCount = computed(() => {
69605
+ if (!this.spacers())
69606
+ return null;
69607
+ return this.headerRowCount() + this.rows().length + this.openDetailIndices().length + (this.hasFooter() ? 1 : 0);
69608
+ }, /* @ts-ignore */
69609
+ ...(ngDevMode ? [{ debugName: "ariaRowCount" }] : /* istanbul ignore next */ []));
69198
69610
  this.bodyRows = computed(() => {
69199
69611
  const pinning = this.columnPinning();
69200
69612
  const templates = this.columnTemplates().cell;
@@ -69213,6 +69625,7 @@ class TableComponent {
69213
69625
  const rendered = this.renderedRows();
69214
69626
  // A footer row separates itself with this rule, and an end spacer stands in for rows still below.
69215
69627
  const endsWithRows = !this.hasFooter() && !this.spacers()?.end;
69628
+ const announcesIndex = this.ariaRowCount() !== null;
69216
69629
  return rendered.map((row, index) => {
69217
69630
  const key = this.rowIdentity(row);
69218
69631
  const link = rowLink?.(row) ?? null;
@@ -69233,6 +69646,7 @@ class TableComponent {
69233
69646
  stripe: (indexOffset + index) % 2 === 1,
69234
69647
  last: endsWithRows && index === rendered.length - 1,
69235
69648
  detail: detail?.isOpen(row) ? detail : null,
69649
+ ariaRowIndex: announcesIndex ? this.ariaRowIndexOf(indexOffset + index) : null,
69236
69650
  leads,
69237
69651
  trails,
69238
69652
  cells: columns.map((column) => {
@@ -69261,6 +69675,8 @@ class TableComponent {
69261
69675
  });
69262
69676
  }, /* @ts-ignore */
69263
69677
  ...(ngDevMode ? [{ debugName: "bodyRows" }] : /* istanbul ignore next */ []));
69678
+ this.detailAriaRowIndices = computed(() => new Map(this.bodyRows().flatMap((vm) => (vm.detail && vm.ariaRowIndex ? [[vm.row, vm.ariaRowIndex + 1]] : []))), /* @ts-ignore */
69679
+ ...(ngDevMode ? [{ debugName: "detailAriaRowIndices" }] : /* istanbul ignore next */ []));
69264
69680
  /**
69265
69681
  * The keys of the currently hidden columns, in declared order. Nothing in the table's own chrome
69266
69682
  * shows a hidden column - the column menu's "Hide column" takes one away and has no way back - so
@@ -69380,6 +69796,21 @@ class TableComponent {
69380
69796
  afterNextRender({ read: () => this.syncScrollState() }, { injector: this.injector });
69381
69797
  });
69382
69798
  }
69799
+ /** The `aria-rowindex` of an open row's detail row, or `null` while every row is in the DOM. Part of the feature contract. */
69800
+ detailAriaRowIndex(row) {
69801
+ return this.detailAriaRowIndices().get(row) ?? null;
69802
+ }
69803
+ /** Record a detail row's rendered height. Part of the feature contract. */
69804
+ setDetailRowHeight(row, height) {
69805
+ const key = this.rowIdentity(row);
69806
+ if (this.measuredDetailHeights().get(key) === height)
69807
+ return;
69808
+ this.measuredDetailHeights.update((heights) => new Map(heights).set(key, height));
69809
+ }
69810
+ /** The height each open detail row adds, by absolute row index. Part of the feature contract. */
69811
+ detailRowHeights() {
69812
+ return this.openDetailHeights();
69813
+ }
69383
69814
  syncScrollState() {
69384
69815
  const element = this.scrollElement();
69385
69816
  // `scrollLeft` counts down from 0 in RTL, so compare distances rather than raw offsets.
@@ -69739,10 +70170,16 @@ class TableComponent {
69739
70170
  /**
69740
70171
  * Set a column's sort direction outright, or clear it with `null` - what a column menu's explicit
69741
70172
  * "Sort ascending / descending / Clear" entries need, where {@link toggleSort}'s cycle would make
69742
- * the result depend on the column's current state. Layers like a plain header activation does.
70173
+ * the result depend on the column's current state. Layers like a plain header activation does;
70174
+ * clearing drops only this column's entry from a layered sort.
69743
70175
  */
69744
70176
  setSort(key, direction) {
69745
- this.applySort(this.nextSort({ key, direction, additive: false }));
70177
+ if (direction) {
70178
+ this.applySort(this.nextSort({ key, direction, additive: false }));
70179
+ }
70180
+ else if (this.sort().some((entry) => entry.key === key)) {
70181
+ this.applySort(this.sort().filter((entry) => entry.key !== key));
70182
+ }
69746
70183
  }
69747
70184
  activateSortHeader(key, event) {
69748
70185
  if (event instanceof KeyboardEvent)
@@ -70016,6 +70453,19 @@ class TableComponent {
70016
70453
  return next;
70017
70454
  });
70018
70455
  }
70456
+ ariaRowIndexOf(index) {
70457
+ const open = this.openDetailIndices();
70458
+ let low = 0;
70459
+ let high = open.length;
70460
+ while (low < high) {
70461
+ const mid = (low + high) >> 1;
70462
+ if ((open[mid] ?? Infinity) < index)
70463
+ low = mid + 1;
70464
+ else
70465
+ high = mid;
70466
+ }
70467
+ return this.headerRowCount() + index + low + 1;
70468
+ }
70019
70469
  // Must stay a same-tick write on the header grid. A requestAnimationFrame hop defers it past the
70020
70470
  // paint the body already moved in, so the header trails a whole frame; and the property inherits,
70021
70471
  // so writing it on the host recalculates style for every row cell, which only the header reads.
@@ -70116,10 +70566,10 @@ class TableComponent {
70116
70566
  return false;
70117
70567
  }
70118
70568
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
70119
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: TableComponent, isStandalone: true, selector: "et-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, rowsSource: { classPropertyName: "rowsSource", publicName: "rowsSource", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, rowKey: { classPropertyName: "rowKey", publicName: "rowKey", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, emptyTemplate: { classPropertyName: "emptyTemplate", publicName: "emptyTemplate", isSignal: true, isRequired: false, transformFunction: null }, errorTemplate: { classPropertyName: "errorTemplate", publicName: "errorTemplate", isSignal: true, isRequired: false, transformFunction: null }, cellState: { classPropertyName: "cellState", publicName: "cellState", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, sort: { classPropertyName: "sort", publicName: "sort", isSignal: true, isRequired: false, transformFunction: null }, multiSort: { classPropertyName: "multiSort", publicName: "multiSort", isSignal: true, isRequired: false, transformFunction: null }, sortMode: { classPropertyName: "sortMode", publicName: "sortMode", isSignal: true, isRequired: false, transformFunction: null }, filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, filterMode: { classPropertyName: "filterMode", publicName: "filterMode", isSignal: true, isRequired: false, transformFunction: null }, quickFilter: { classPropertyName: "quickFilter", publicName: "quickFilter", isSignal: true, isRequired: false, transformFunction: null }, expandedRowTemplate: { classPropertyName: "expandedRowTemplate", publicName: "expandedRowTemplate", isSignal: true, isRequired: false, transformFunction: null }, rowInteractive: { classPropertyName: "rowInteractive", publicName: "rowInteractive", isSignal: true, isRequired: false, transformFunction: null }, rowLink: { classPropertyName: "rowLink", publicName: "rowLink", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sort: "sortChange", filters: "filtersChange", rowClick: "rowClick" }, host: { listeners: { "scroll": "syncScrollState()" }, properties: { "attr.data-appearance": "appearance()", "attr.data-density": "density()", "attr.aria-busy": "resolvedLoading() ? \"true\" : null", "attr.role": "pageStickyHeader() ? tableRole() : null", "class.et-table-host--scrolled-block-start": "blockScrollShadows().blockStart", "class.et-table-host--scrolled-block-end": "blockScrollShadows().blockEnd", "class.et-table-host--scrolled-inline-start": "scrollFades().start", "class.et-table-host--scrolled-inline-end": "scrollFades().end", "class.et-table-host--header-adornments": "headerAdornments().length > 0", "style.--_et-table-viewport-inline-size.px": "viewportInlineSize()" }, classAttribute: "et-table-host" }, providers: [
70569
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: TableComponent, isStandalone: true, selector: "et-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, rowsSource: { classPropertyName: "rowsSource", publicName: "rowsSource", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, rowKey: { classPropertyName: "rowKey", publicName: "rowKey", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, emptyTemplate: { classPropertyName: "emptyTemplate", publicName: "emptyTemplate", isSignal: true, isRequired: false, transformFunction: null }, errorTemplate: { classPropertyName: "errorTemplate", publicName: "errorTemplate", isSignal: true, isRequired: false, transformFunction: null }, cellState: { classPropertyName: "cellState", publicName: "cellState", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, sort: { classPropertyName: "sort", publicName: "sort", isSignal: true, isRequired: false, transformFunction: null }, multiSort: { classPropertyName: "multiSort", publicName: "multiSort", isSignal: true, isRequired: false, transformFunction: null }, sortMode: { classPropertyName: "sortMode", publicName: "sortMode", isSignal: true, isRequired: false, transformFunction: null }, filters: { classPropertyName: "filters", publicName: "filters", isSignal: true, isRequired: false, transformFunction: null }, filterMode: { classPropertyName: "filterMode", publicName: "filterMode", isSignal: true, isRequired: false, transformFunction: null }, quickFilter: { classPropertyName: "quickFilter", publicName: "quickFilter", isSignal: true, isRequired: false, transformFunction: null }, expandedRowTemplate: { classPropertyName: "expandedRowTemplate", publicName: "expandedRowTemplate", isSignal: true, isRequired: false, transformFunction: null }, rowInteractive: { classPropertyName: "rowInteractive", publicName: "rowInteractive", isSignal: true, isRequired: false, transformFunction: null }, rowLink: { classPropertyName: "rowLink", publicName: "rowLink", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sort: "sortChange", filters: "filtersChange", rowClick: "rowClick" }, host: { listeners: { "scroll": "syncScrollState()" }, properties: { "attr.data-appearance": "appearance()", "attr.data-density": "density()", "attr.aria-busy": "resolvedLoading() ? \"true\" : null", "attr.role": "pageStickyHeader() ? tableRole() : null", "attr.aria-rowcount": "pageStickyHeader() ? ariaRowCount() : null", "class.et-table-host--scrolled-block-start": "blockScrollShadows().blockStart", "class.et-table-host--scrolled-block-end": "blockScrollShadows().blockEnd", "class.et-table-host--scrolled-inline-start": "scrollFades().start", "class.et-table-host--scrolled-inline-end": "scrollFades().end", "class.et-table-host--header-adornments": "headerAdornments().length > 0", "style.--_et-table-viewport-inline-size.px": "viewportInlineSize()" }, classAttribute: "et-table-host" }, providers: [
70120
70570
  { provide: TABLE_FEATURE_HOST, useExisting: TableComponent },
70121
70571
  provideIcons(ARROW_UP_ICON, TRIANGLE_EXCLAMATION_ICON),
70122
- ], queries: [{ propertyName: "footerSlot", first: true, predicate: TableFooterDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "gridRef", first: true, predicate: ["grid"], descendants: true, isSignal: true }, { propertyName: "headerGridRef", first: true, predicate: ["headerGrid"], descendants: true, isSignal: true }, { propertyName: "scrollerRef", first: true, predicate: ["scroller"], descendants: true, isSignal: true }, { propertyName: "headerCells", predicate: ["headerCell"], descendants: true, isSignal: true }, { propertyName: "bodyCells", predicate: ["bodyCell"], descendants: true, isSignal: true }, { propertyName: "gridCells", predicate: ["gridCell"], descendants: true, isSignal: true }, { propertyName: "leadHeaderCells", predicate: ["leadHeaderCell"], descendants: true, isSignal: true }, { propertyName: "trailHeaderCells", predicate: ["trailHeaderCell"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Every binding below reads a field off a render model (see the `\u2026Vm` types in the component):\n methods belong in event bindings, not in bindings the framework re-evaluates each pass. -->\n<ng-template #headerContent>\n <!-- Rows a feature renders above the column headers (etTableGroupHeaders' spanning group row). Each\n is display: contents and lays its own cells into these tracks \u2014 see registerHeaderRow. -->\n @for (headerRow of headerRows(); track $index) {\n <ng-container *ngComponentOutlet=\"headerRow.component; injector: headerRow.injector\" />\n }\n\n <div class=\"et-table-header-row\" role=\"row\">\n <!-- Leading utility columns (selection from a feature, the expander when expansion is on). The\n table owns the cell chrome; the feature only supplies what goes inside. -->\n @for (lead of leadCells(); track lead.key) {\n <div\n #leadHeaderCell\n [class]=\"lead.cellClass\"\n [class.et-table-sticky-start]=\"lead.sticky\"\n [style.inset-inline-start.px]=\"pageStickyHeader() ? null : lead.offset\"\n class=\"et-table-header-cell\"\n role=\"columnheader\"\n >\n @if (lead.lead.headerComponent; as headerComponent) {\n <ng-container *ngComponentOutlet=\"headerComponent; injector: lead.lead.injector\" />\n }\n </div>\n }\n @for (cell of headerCellVms(); track cell.key) {\n <div\n #headerCell\n [attr.data-align]=\"cell.align\"\n [attr.data-col-key]=\"cell.key\"\n [attr.data-disabled]=\"cell.disabled || null\"\n [attr.aria-sort]=\"cell.ariaSort\"\n [class.et-table-sticky-start]=\"cell.stickyStart\"\n [class.et-table-sticky-end]=\"cell.stickyEnd\"\n [style.inset-inline-start.px]=\"pageStickyHeader() ? null : cell.offsetStart\"\n [style.inset-inline-end.px]=\"pageStickyHeader() ? null : cell.offsetEnd\"\n class=\"et-table-header-cell\"\n role=\"columnheader\"\n >\n <!-- Sorting is the whole header's job, not a control's: the label plus everything around it is\n one button, and the only sort affordance is the direction arrow, which appears once the\n column is actually sorted. Adornments sit outside it so their own clicks don't sort. -->\n @if (cell.sortable) {\n <button\n [attr.aria-label]=\"cell.sortLabel\"\n [attr.aria-description]=\"cell.priorityLabel\"\n [disabled]=\"cell.disabled\"\n (click)=\"activateSortHeader(cell.key, $event)\"\n (keydown.shift.enter)=\"activateSortHeader(cell.key, $event)\"\n class=\"et-table-header-label et-table-header-label--sortable\"\n type=\"button\"\n >\n <span class=\"et-table-header-label-box\">\n @if (cell.template; as headerTemplate) {\n <ng-container *ngTemplateOutlet=\"headerTemplate; context: { $implicit: cell.column.header }\" />\n } @else {\n <span class=\"et-table-cell-text\">{{ cell.column.header }}</span>\n }\n @if (cell.direction; as direction) {\n <!-- Flipping direction keeps this element mounted, so the arrow turns over rather than\n swapping; only appearing and disappearing are the fade, and only for a sort the user\n just asked for (see sortIndicatorEnter). -->\n <i\n [attr.data-direction]=\"direction\"\n [animate.enter]=\"sortIndicatorEnter()\"\n [animate.leave]=\"sortIndicatorLeave()\"\n class=\"et-table-sort-indicator\"\n etIcon=\"et-arrow-up\"\n ></i>\n }\n @if (cell.priority; as priority) {\n <span class=\"et-table-sort-priority\" aria-hidden=\"true\">{{ priority }}</span>\n }\n </span>\n </button>\n } @else {\n <span class=\"et-table-header-label\">\n <span class=\"et-table-header-label-box\">\n @if (cell.template; as headerTemplate) {\n <ng-container *ngTemplateOutlet=\"headerTemplate; context: { $implicit: cell.column.header }\" />\n } @else {\n <span class=\"et-table-cell-text\">{{ cell.column.header }}</span>\n }\n </span>\n </span>\n }\n\n <!-- UI from opt-in features (filter menu, \u2026), each registered rather than referenced \u2014 see\n registerHeaderAdornment. Renders nothing when no feature is imported.\n\n Dropped once the column is covered by a pinned one: an adornment's menu is a portal, so it\n would go on floating over the pinned column, anchored to a cell nobody can see. Unmounting\n the trigger is what closes it. -->\n @if (!cell.obscured && headerAdornments().length) {\n <div class=\"et-table-header-adornments\">\n @for (adornment of headerAdornments(); track $index) {\n <ng-container\n *ngComponentOutlet=\"adornment.component; inputs: { column: cell.column }; injector: adornment.injector\"\n />\n }\n </div>\n }\n </div>\n }\n <!-- Filler cell for the trailing slack track (see hasFiller): carries the header band to the\n panel's edge when every column is a rigid width. -->\n @if (hasFiller()) {\n <div class=\"et-table-header-cell et-table-filler-cell\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n <!-- Trailing utility columns (a selection column moved to this edge). Same chrome as the leading\n ones, pinned to the trailing edge instead - see TableLeadColumn.side. -->\n @for (trail of trailCells(); track trail.key) {\n <div\n #trailHeaderCell\n [class]=\"trail.cellClass\"\n [class.et-table-sticky-end]=\"trail.sticky\"\n [style.inset-inline-end.px]=\"pageStickyHeader() ? null : trail.offset\"\n class=\"et-table-header-cell\"\n role=\"columnheader\"\n >\n @if (trail.lead.headerComponent; as headerComponent) {\n <ng-container *ngComponentOutlet=\"headerComponent; injector: trail.lead.injector\" />\n }\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #bodyContent>\n <!-- Refetching over rows that are already on screen: a 2px indeterminate bar right under the header,\n so the data stays readable and in place. Drawn here rather than with `et-progress-bar` \u2014 the base\n table takes no component dependencies, and this is 2px of chrome, not a control. -->\n @if (showBusyBar()) {\n <!-- Faded in and out: a refetch is often over in a few hundred ms, and a bar that pops in and\n vanishes reads as a flicker rather than as work happening. -->\n <div\n class=\"et-table-busy-bar\"\n animate.enter=\"et-table-busy-bar--enter\"\n animate.leave=\"et-table-busy-bar--leave\"\n role=\"presentation\"\n aria-hidden=\"true\"\n ></div>\n }\n\n @if (spacers(); as spacer) {\n <div [style.block-size.px]=\"spacer.start\" class=\"et-table-spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n\n @if (hasError()) {\n <!-- The error state stands in for the whole body: rows are either trustworthy or absent. -->\n <div class=\"et-table-message-row\" role=\"row\">\n <div [attr.role]=\"cellRole()\" class=\"et-table-error-cell\" aria-live=\"polite\">\n @if (showErrorMessage()) {\n @if (errorTemplate(); as template) {\n <ng-container *ngTemplateOutlet=\"template; context: { $implicit: resolvedError() }\" />\n } @else {\n <ng-content select=\"[etTableError]\">\n <i [etProvideColor]=\"errorColorTheme()\" class=\"et-table-error-icon\" etIcon=\"et-triangle-exclamation\"></i>\n <span>{{ resolvedLabels().error }}</span>\n </ng-content>\n }\n }\n </div>\n </div>\n } @else if (showPlaceholderRows()) {\n <!-- First load with nothing to show yet. What a loading body looks like belongs to a feature\n (etTableSkeleton draws placeholder rows in these tracks); with none the body stays blank rather\n than showing a misleading empty state \u2014 the host's `aria-busy` is the announcement. -->\n @if (bodyPlaceholder(); as placeholder) {\n <ng-container *ngComponentOutlet=\"placeholder.component; injector: placeholder.injector\" />\n }\n } @else {\n @for (rowVm of bodyRows(); track rowVm.key) {\n <!-- A linked row is not a tab stop of its own: its anchor is the one stop, and the one link. -->\n <div\n [class]=\"rowVm.classes\"\n [class.et-table-row--stripe]=\"rowVm.stripe\"\n [class.et-table-row--last]=\"rowVm.last\"\n [class.et-table-row--interactive]=\"rowInteractive()\"\n [class.et-table-row--box]=\"rowBox()\"\n [class.et-table-row--card]=\"cardRows()\"\n [class.et-table-row--link]=\"rowVm.href !== null\"\n [etTableCardSurface]=\"cardRows()\"\n [attr.tabindex]=\"rowInteractive() && !cellNavigation() && rowVm.href === null ? 0 : null\"\n (click)=\"activateRow(rowVm.row, $event)\"\n (keydown.enter)=\"activateRow(rowVm.row, $event)\"\n (keydown.space)=\"activateRow(rowVm.row, $event)\"\n class=\"et-table-row\"\n role=\"row\"\n >\n @for (lead of rowVm.leads; track lead.key) {\n <div\n #gridCell\n [class]=\"lead.cellClass\"\n [attr.tabindex]=\"cellNavigation() ? -1 : null\"\n [class.et-table-sticky-start]=\"lead.sticky\"\n [style.inset-inline-start.px]=\"lead.offset\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-cell\"\n >\n <ng-container\n *ngComponentOutlet=\"lead.lead.bodyComponent; inputs: { row: rowVm.row }; injector: lead.lead.injector\"\n />\n </div>\n }\n @for (cell of rowVm.cells; track cell.key) {\n <div\n #bodyCell\n #gridCell\n [attr.data-align]=\"cell.align\"\n [attr.data-col-key]=\"cell.key\"\n [attr.tabindex]=\"cellNavigation() ? -1 : null\"\n [attr.data-state]=\"cell.state\"\n [attr.id]=\"cell.linkHost ? rowVm.linkLabelId : null\"\n [class.et-table-cell--interactive]=\"cell.interactive\"\n [class.et-table-cell--editing]=\"cell.edit\"\n [class.et-skeleton--animated]=\"cell.state === 'loading'\"\n [class.et-table-sticky-start]=\"cell.stickyStart\"\n [class.et-table-sticky-end]=\"cell.stickyEnd\"\n [style.inset-inline-start.px]=\"cell.offsetStart\"\n [style.inset-inline-end.px]=\"cell.offsetEnd\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-cell\"\n >\n @if (cell.edit; as edit) {\n <!-- The one cell in edit mode: the column's etTableCellEdit template, rendered with the\n editing feature's own context (the draft field). See registerCellEditing. -->\n <ng-container *ngTemplateOutlet=\"edit.template; context: edit.context\" />\n } @else if (cell.state === 'loading' && cellPlaceholder(); as placeholder) {\n <!-- A cell that is loading on its own (an inline edit saving) shows a feature's placeholder\n instead of its value; the row around it stays readable. Without one the value stays put\n and `data-state` carries the cue \u2014 see registerCellPlaceholder. -->\n <ng-container *ngComponentOutlet=\"placeholder.component; injector: placeholder.injector\" />\n } @else {\n @if (cell.state === 'error') {\n @if (cellErrorMark(); as mark) {\n <!-- A feature (etTableCellErrorTooltip) draws the mark instead, so the overlay runtime\n only ships when a table actually wants a tooltip. -->\n <ng-container\n *ngComponentOutlet=\"mark.component; inputs: { message: cell.message }; injector: mark.injector\"\n />\n } @else {\n <!-- Color-scoped here rather than on the cell: the mark is the only part that must read\n as an error, and a provider per errored cell is cheap where one per cell would not\n be. The message rides along as `title`, which costs nothing. -->\n <i\n [etProvideColor]=\"errorColorTheme()\"\n [attr.title]=\"cell.message\"\n [label]=\"cell.message\"\n class=\"et-table-cell-error-icon\"\n etIcon=\"et-triangle-exclamation\"\n ></i>\n }\n }\n @if (cell.template; as bodyTemplate) {\n <ng-container *ngTemplateOutlet=\"bodyTemplate; context: cell.context\" />\n } @else {\n <span class=\"et-table-cell-text\">{{ cell.value }}</span>\n }\n }\n </div>\n }\n @if (hasFiller()) {\n <div class=\"et-table-cell et-table-filler-cell\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n @for (trail of rowVm.trails; track trail.key) {\n <div\n #gridCell\n [class]=\"trail.cellClass\"\n [attr.tabindex]=\"cellNavigation() ? -1 : null\"\n [class.et-table-sticky-end]=\"trail.sticky\"\n [style.inset-inline-end.px]=\"trail.offset\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-cell\"\n >\n <ng-container\n *ngComponentOutlet=\"trail.lead.bodyComponent; inputs: { row: rowVm.row }; injector: trail.lead.injector\"\n />\n </div>\n }\n\n @if (rowVm.href !== null) {\n <!-- The row's link: one real anchor, stretched over the row box (see rowBox) rather than\n wrapping any content, so the cells stay exactly as a table without links renders them.\n It carries no text of its own and is named by the identity cell instead - `aria-labelledby`\n resolves to that cell's content, which is the row's identity.\n\n A child of the row, not of a cell: a cell that is pinned is `position: sticky` and would\n therefore be the anchor's containing block, shrinking the row's hit area to that one\n column. The row box is the containing block that spans every cell. -->\n <a\n [attr.href]=\"rowVm.href\"\n [attr.aria-labelledby]=\"rowVm.linkLabelId\"\n (click)=\"activateRowLink(rowVm.link, $event)\"\n class=\"et-table-row-link\"\n ></a>\n }\n\n @if (cardRows()) {\n <div class=\"et-table-card-corners\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n </div>\n\n <!-- The detail row of an expanded row, from etTableRowExpansion \u2014 the whole row, its chrome and\n its animation belong to the feature, so a table that never expands carries none of them. -->\n @if (rowVm.detail; as detail) {\n <ng-container *ngComponentOutlet=\"detail.component; inputs: { row: rowVm.row }; injector: detail.injector\" />\n }\n } @empty {\n <div class=\"et-table-message-row\" role=\"row\">\n <div [attr.role]=\"cellRole()\" class=\"et-table-empty-cell\">\n @if (emptyTemplate(); as template) {\n <ng-container *ngTemplateOutlet=\"template; context: { $implicit: rows() }\" />\n } @else {\n <ng-content select=\"[etTableEmpty]\">{{ resolvedLabels().empty }}</ng-content>\n }\n </div>\n </div>\n }\n }\n\n @if (spacers(); as spacer) {\n <div [style.block-size.px]=\"spacer.end\" class=\"et-table-spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n\n <!-- Edge gradients marking rows scrolled out of view horizontally, on the edges no pinned column\n already marks (see visibleScrollFades). The layer is absolutely positioned over the whole grid \u2014\n the full scroll extent, not just the viewport \u2014 which is what lets the two fades inside it hold\n their place with `position: sticky` for the entire scroll range. -->\n <div class=\"et-table-scroll-fades\" role=\"presentation\" aria-hidden=\"true\">\n <div\n [style.inset-inline-start.px]=\"fadeInset().start\"\n [class.et-table-scroll-fade--visible]=\"visibleScrollFades().start\"\n class=\"et-table-scroll-fade et-table-scroll-fade--start\"\n ></div>\n <div\n [style.inset-inline-end.px]=\"fadeInset().end\"\n [class.et-table-scroll-fade--visible]=\"visibleScrollFades().end\"\n class=\"et-table-scroll-fade et-table-scroll-fade--end\"\n ></div>\n </div>\n\n @if (hasFooter()) {\n <div class=\"et-table-footer-row\" role=\"row\">\n @for (lead of leadCells(); track lead.key) {\n <div\n [class]=\"lead.cellClass\"\n [class.et-table-sticky-start]=\"lead.sticky\"\n [style.inset-inline-start.px]=\"lead.offset\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-footer-cell\"\n aria-hidden=\"true\"\n ></div>\n }\n @for (cell of footerCells(); track cell.key) {\n <div\n [attr.data-align]=\"cell.align\"\n [class.et-table-sticky-start]=\"cell.stickyStart\"\n [class.et-table-sticky-end]=\"cell.stickyEnd\"\n [style.inset-inline-start.px]=\"cell.offsetStart\"\n [style.inset-inline-end.px]=\"cell.offsetEnd\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-footer-cell\"\n >\n @if (cell.template; as footerTemplate) {\n <ng-container *ngTemplateOutlet=\"footerTemplate; context: { $implicit: rows() }\" />\n }\n </div>\n }\n @if (hasFiller()) {\n <div class=\"et-table-footer-cell et-table-filler-cell\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n @for (trail of trailCells(); track trail.key) {\n <div\n [class]=\"trail.cellClass\"\n [class.et-table-sticky-end]=\"trail.sticky\"\n [style.inset-inline-end.px]=\"trail.offset\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-footer-cell\"\n aria-hidden=\"true\"\n ></div>\n }\n </div>\n }\n</ng-template>\n\n@if (pageStickyHeader()) {\n <div class=\"et-table-header-strip\" role=\"presentation\">\n <div\n #headerGrid\n [style.grid-template-columns]=\"pageHeaderColumns()\"\n class=\"et-table et-table-header\"\n role=\"rowgroup\"\n >\n <ng-container *ngTemplateOutlet=\"headerContent\" />\n </div>\n </div>\n <div #scroller (scroll)=\"syncScrollState()\" class=\"et-table-scroller\" role=\"presentation\">\n <div #grid [style.grid-template-columns]=\"templateColumns()\" class=\"et-table\" role=\"rowgroup\">\n <ng-container *ngTemplateOutlet=\"bodyContent\" />\n </div>\n </div>\n} @else {\n <div #grid [style.grid-template-columns]=\"templateColumns()\" [attr.role]=\"tableRole()\" class=\"et-table\">\n <ng-container *ngTemplateOutlet=\"headerContent\" />\n <ng-container *ngTemplateOutlet=\"bodyContent\" />\n </div>\n}\n\n<!-- Full-width footer slot (paginator, page-size, etc.), pinned to the bottom of the scroll viewport.\n Rendered only when the consumer projects `[etTableFooter]`, so the chrome never shows empty. -->\n@if (footerSlot()) {\n <div class=\"et-table-footer\">\n <ng-content select=\"[etTableFooter]\" />\n </div>\n}\n\n<!-- Floating UI from opt-in features (the reorder drag ghost / drop indicator), stamped here so a\n feature can draw without having a view \u2014 or an element \u2014 of its own. -->\n@for (layer of layers(); track $index) {\n <ng-container *ngComponentOutlet=\"layer.component; injector: layer.injector\" />\n}\n", styles: ["@layer components{@property --et-table-cell-padding-block{syntax: \"<length>\"; inherits: true; initial-value: 10px;}@property --et-table-cell-padding-inline{syntax: \"<length>\"; inherits: true; initial-value: 12px;}@property --et-table-opacity-disabled{syntax: \"<number>\"; inherits: true; initial-value: .4;}:where(.et-table-host){display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:1fr auto;overflow:auto;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--et-surface-interaction-solid, gray) 35%,transparent) transparent;--_et-table-band: color-mix( in srgb, var(--et-surface-interaction-solid, gray) 7%, var(--et-surface-background-solid, Canvas) );--_et-table-header-bg: var(--et-table-header-background-color, var(--et-surface-background-solid, Canvas));--_et-table-header-border: var(--et-surface-border-solid, rgb(128 128 128 / .3));--_et-table-row-divider: transparent;--_et-table-header-adornment-size: 2.4rem;--_et-table-row-surface: var(--et-surface-background-solid, Canvas);--_et-table-stripe-bg: transparent;--_et-table-stripe-solid: var(--_et-table-row-surface);--_et-table-hover-tint: color-mix(in srgb, var(--et-surface-interaction-solid, gray) 8%, transparent);--_et-table-hover-tint-solid: color-mix( in srgb, var(--et-surface-interaction-solid, gray) 8%, var(--_et-table-row-surface) );--_et-table-row-hover: var(--_et-table-hover-tint);--_et-table-row-hover-solid: var(--_et-table-hover-tint-solid);--_et-table-pressed-tint: color-mix(in srgb, var(--et-surface-interaction-solid, gray) 16%, transparent);--_et-table-pressed-tint-solid: color-mix( in srgb, var(--et-surface-interaction-solid, gray) 16%, var(--_et-table-row-surface) );--_et-table-row-pressed: var(--_et-table-pressed-tint);--_et-table-row-pressed-solid: var(--_et-table-pressed-tint-solid);--_et-table-inert-row-hover: var(--_et-table-hover-tint);--_et-table-inert-row-hover-solid: var(--_et-table-hover-tint-solid);--_et-table-row-gap-block: 0px;--_et-table-row-paint: transparent;--_et-table-row-corner: 0px;--_et-table-header-gap-block: 0px;--_et-table-cell-rule: 0;--_et-table-sticky-clip: none;--_et-table-busy-margin-block-start: 0px;--_et-table-busy-margin-block-end: -2px;--_et-table-detail-rule: 1px solid var(--et-surface-border-solid, rgb(128 128 128 / .15));--_et-table-card-outside: var(--et-surface-background-solid, Canvas);--_et-table-pin-shadow: var( --et-table-pin-shadow-color, color-mix(in srgb, var(--et-surface-interaction-solid, black) 30%, transparent) );--_et-table-pin-shadow-inline: var(--et-table-pin-shadow-color-inline, var(--_et-table-pin-shadow));--_et-table-pin-shadow-block: var(--et-table-pin-shadow-color-block, var(--_et-table-pin-shadow));--_et-table-edge-none: 0 0 transparent;--_et-table-edge-start: var(--_et-table-edge-none);--_et-table-edge-end: var(--_et-table-edge-none);--_et-table-edge-block-start: var(--_et-table-edge-none);--_et-table-edge-block-end: var(--_et-table-edge-none)}.et-table-host--scrolled-inline-start{--_et-table-edge-start: 8px 0 10px -6px var(--_et-table-pin-shadow-inline)}.et-table-host--scrolled-inline-end{--_et-table-edge-end: -8px 0 10px -6px var(--_et-table-pin-shadow-inline)}.et-table-host--scrolled-block-start{--_et-table-edge-block-start: 0 8px 10px -6px var(--_et-table-pin-shadow-block)}.et-table-host--scrolled-block-end{--_et-table-edge-block-end: 0 -8px 10px -6px var(--_et-table-pin-shadow-block)}.et-table-host:where([data-density=sm]){--et-table-cell-padding-block: 6px;--et-table-cell-padding-inline: 10px}.et-table-host:where([data-density=md]){--et-table-cell-padding-block: 10px;--et-table-cell-padding-inline: 12px}.et-table-host:where([data-density=lg]){--et-table-cell-padding-block: 15px;--et-table-cell-padding-inline: 16px}.et-table-host:where([data-appearance=enclosed],[data-appearance=zebra],[data-appearance=grid]){border:1px solid var(--et-surface-border-solid, rgb(128 128 128 / .3));border-radius:var(--et-table-radius, 10px)}.et-table-host:where([data-appearance=enclosed]){--_et-table-header-bg: var(--et-table-header-background-color, var(--_et-table-band));--_et-table-row-divider: var(--et-surface-border-solid, rgb(128 128 128 / .15));box-shadow:0 1px 2px rgb(var(--et-shadow-color-rgb, 0 0 0) / .04),0 6px 16px rgb(var(--et-shadow-color-rgb, 0 0 0) / .06)}.et-table-host:where([data-appearance=divided]){--_et-table-row-divider: var(--et-surface-border-solid, rgb(128 128 128 / .15))}.et-table-host:where([data-appearance=zebra]){--_et-table-header-bg: var(--et-table-header-background-color, var(--_et-table-band));--_et-table-stripe-bg: color-mix(in srgb, var(--et-surface-interaction-solid, gray) 4%, transparent);--_et-table-stripe-solid: color-mix( in srgb, var(--et-surface-interaction-solid, gray) 4%, var(--_et-table-row-surface) )}.et-table-host:where([data-appearance=grid]){--_et-table-cell-rule: 1px solid var(--et-surface-border-solid, rgb(128 128 128 / .15));--_et-table-header-bg: var(--et-table-header-background-color, var(--_et-table-band));--_et-table-row-divider: var(--et-surface-border-solid, rgb(128 128 128 / .15))}.et-table-host:where([data-appearance=bare]){--_et-table-header-border: transparent}.et-table-host:where([data-appearance=cards]){--_et-table-row-gap-block: var(--et-table-row-gap, 8px);--_et-table-row-corner: var(--et-table-row-radius, 10px);--_et-table-header-gap-block: var(--et-table-row-gap, 8px);--_et-table-sticky-clip: inset(0 -24px);--_et-table-busy-margin-block-start: calc((var(--et-table-row-gap, 8px) + 2px) / -2);--_et-table-busy-margin-block-end: calc((var(--et-table-row-gap, 8px) - 2px) / 2);--_et-table-detail-rule: 0;--_et-table-inert-row-hover: transparent;--_et-table-header-bg: var(--et-table-header-background-color, var(--et-surface-background-solid, Canvas));--_et-table-row-divider: transparent}.et-table{display:grid;position:relative;align-content:start;inline-size:min-content;min-inline-size:100%;background:var(--et-surface-background-solid, Canvas);color:var(--et-surface-color-solid, CanvasText);font-size:14px;line-height:1.4}.et-table-header-cell.et-table-filler-cell,.et-table-cell.et-table-filler-cell,.et-table-footer-cell.et-table-filler-cell,.et-table-group-cell.et-table-filler-cell{padding-inline:0}.et-table-header-row,.et-table-row{display:contents}.et-table-header-cell,.et-table-cell{display:flex;align-items:center;min-inline-size:0;overflow:hidden;padding:var(--et-table-cell-padding-block) var(--et-table-cell-padding-inline)}.et-table-cell-text{min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.et-table-header-cell{position:sticky;inset-block-start:max(0px,calc(var(--_et-table-group-h, 0px) - 1px));gap:4px;z-index:1;font-weight:600;color:var(--et-table-header-color, var(--et-surface-color-muted-solid, CanvasText));background:var(--_et-table-header-bg);border-block-end:1px solid var(--_et-table-header-border)}.et-table-header-adornments{display:flex;align-items:center;flex:none}.et-table-header-cell .et-table-filter-trigger,.et-table-header-cell .et-table-column-menu-trigger{--et-icon-button-size: var(--_et-table-header-adornment-size);--et-icon-button-icon-size: 1.6rem;min-width:24px;min-height:24px}.et-table-host--header-adornments .et-table-header-cell{min-block-size:calc(max(var(--_et-table-header-adornment-size),24px) + 2 * var(--et-table-cell-padding-block) + 1px)}.et-table-cell{min-block-size:var(--et-table-row-min-block-size, auto);border-block-end:1px solid var(--_et-table-row-divider)}.et-table-header-cell{box-shadow:var(--_et-table-edge-block-start)}.et-table-footer,.et-table-footer-cell{box-shadow:var(--_et-table-edge-block-end)}.et-table-row--last:not(:has(+.et-table-detail-row)) .et-table-cell{border-block-end:0}.et-table-row--stripe .et-table-cell{background:var(--_et-table-stripe-bg)}.et-table-header-cell,.et-table-cell{border-inline-end:var(--_et-table-cell-rule)}.et-table-header-row .et-table-header-cell:last-child,.et-table-row .et-table-cell:nth-last-child(1 of.et-table-cell){border-inline-end:0}.et-table-footer-row{display:contents}.et-table-footer-cell{display:flex;align-items:center;min-inline-size:0;overflow:hidden;padding:var(--et-table-cell-padding-block) var(--et-table-cell-padding-inline);position:sticky;inset-block-end:0;z-index:1;font-weight:600;background:var(--_et-table-header-bg);border-block-start:1px solid var(--et-surface-border-solid, rgb(128 128 128 / .3))}.et-table-footer-cell:where([data-align=center]){justify-content:center;text-align:center}.et-table-footer-cell:where([data-align=end]){justify-content:flex-end;text-align:end}.et-table-scroll-fades{position:absolute;inset:0;display:flex;justify-content:space-between;z-index:3;pointer-events:none}.et-table-scroll-fade{position:sticky;flex:none;inline-size:var(--et-table-scroll-fade-size, 28px);opacity:0;transition:opacity .15s ease;--_et-table-scroll-fade-color: var( --et-table-scroll-fade-color, color-mix(in srgb, var(--et-surface-interaction-solid, black) 22%, transparent) )}.et-table-scroll-fade--visible{opacity:1}.et-table-scroll-fade--start{background:linear-gradient(to right,var(--_et-table-scroll-fade-color),transparent)}.et-table-scroll-fade--end{background:linear-gradient(to left,var(--_et-table-scroll-fade-color),transparent)}@media(prefers-reduced-motion:reduce){.et-table-scroll-fade{transition:none}}.et-table-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;position:sticky;inset-block-end:0;inset-inline-start:0;z-index:4;padding:var(--et-table-cell-padding-block) var(--et-table-cell-padding-inline);background:var(--_et-table-header-bg);border-block-start:1px solid var(--et-surface-border-solid, rgb(128 128 128 / .3))}.et-table-footer-label{margin:0;font-size:14px;color:var(--et-surface-color-muted-solid, CanvasText)}@media(pointer:coarse){.et-table-footer{gap:8px;padding:8px var(--et-table-cell-padding-inline)}}.et-table-header-cell:where([data-align=center]),.et-table-cell:where([data-align=center]){justify-content:center;text-align:center}.et-table-header-cell:where([data-align=end]),.et-table-cell:where([data-align=end]){justify-content:flex-end;text-align:end}.et-table-row--interactive .et-table-cell{cursor:pointer}@media(hover:hover){.et-table-row:hover .et-table-cell{background:var(--_et-table-row-hover)}}.et-table-row:where(.et-table-row--interactive,.et-table-row--link):active .et-table-cell{background:var(--_et-table-row-pressed)}.et-table-header-label:focus-visible,.et-table-expander:focus-visible,.et-table-cell:focus-visible{outline:2px solid var(--et-theme-color-primary-solid, currentColor);outline-offset:-2px}.et-table-header-label{border-radius:4px}.et-table-header-label{display:flex;align-items:center;flex:1;min-inline-size:0;margin:0;padding:0;font:inherit;color:inherit;text-align:inherit;background:none;border:none}.et-table-header-label-box{display:flex;align-items:center;gap:4px;min-inline-size:0;padding:4px;margin:-4px;border-radius:4px}.et-table-header-label:where(.et-table-header-label--sortable){cursor:pointer}.et-table-header-label--sortable .et-table-header-label-box{background-color:var(--_et-table-header-label-tint, transparent);transition:background-color .12s var(--ease-out-5, ease)}@media(hover:hover){.et-table-header-label--sortable:hover:not(:disabled){--_et-table-header-label-tint: var(--_et-table-hover-tint)}}.et-table-header-label--sortable:active:not(:disabled){--_et-table-header-label-tint: var(--_et-table-pressed-tint)}.et-table-header-cell:where([data-disabled]) .et-table-header-label{opacity:var(--et-table-opacity-disabled)}.et-table-header-label:where(.et-table-header-label--sortable:disabled){cursor:not-allowed}.et-table-header-cell:where([data-align=center]) .et-table-header-label{justify-content:center}.et-table-header-cell:where([data-align=end]) .et-table-header-label{justify-content:flex-end}.et-table-sort-indicator{flex:none;inline-size:1.15em;block-size:1.15em;transform:translateY(-.045em);color:var(--et-theme-color-primary-solid, currentColor);transition:transform .2s var(--ease-out-5, ease)}.et-table-sort-indicator:where([data-direction=desc]){transform:translateY(-.045em) rotate(180deg)}.et-table-sort-indicator.et-table-sort-indicator--enter{animation:et-table-sort-in .15s ease}.et-table-sort-indicator.et-table-sort-indicator--leave{animation:et-table-sort-in .12s ease reverse forwards}@keyframes et-table-sort-in{0%{opacity:0}to{opacity:1}}@media(prefers-reduced-motion:reduce){.et-table-sort-indicator{transition:none}.et-table-sort-indicator.et-table-sort-indicator--enter,.et-table-sort-indicator.et-table-sort-indicator--leave{animation:none}}.et-table-message-row{display:contents}.et-table-empty-cell,.et-table-error-cell{grid-column:1 / -1;position:sticky;inset-inline-start:0;inline-size:var(--_et-table-viewport-inline-size, 100%);padding:32px var(--et-table-cell-padding-inline);color:var(--et-surface-color-muted-solid, CanvasText);text-align:center}.et-table-empty-cell{display:grid;place-content:center;justify-items:center}.et-table-error-cell{display:flex;flex-wrap:wrap;align-items:center;align-content:center;justify-content:center;gap:8px}.et-table-error-icon{flex:none;inline-size:16px;block-size:16px;color:var(--et-theme-color-ink-solid, currentColor)}.et-table-cell:where([data-state=error]){gap:6px}.et-table-cell-error-icon{flex:none;inline-size:14px;block-size:14px;color:var(--et-theme-color-ink-solid, currentColor)}.et-table-cell:where([data-state=loading]){display:flex}.et-table-busy-bar{grid-column:1 / -1;block-size:2px;margin-block-start:var(--_et-table-busy-margin-block-start);margin-block-end:var(--_et-table-busy-margin-block-end);overflow:hidden;background:color-mix(in srgb,var(--et-surface-interaction-solid, gray) 10%,transparent)}.et-table-busy-bar.et-table-busy-bar--enter{animation:et-table-busy-fade .15s ease}.et-table-busy-bar.et-table-busy-bar--leave{animation:et-table-busy-fade .25s ease reverse forwards}@keyframes et-table-busy-fade{0%{opacity:0}to{opacity:1}}.et-table-busy-bar:after{content:\"\";display:block;inline-size:40%;block-size:100%;border-radius:999px;background:var(--et-theme-color-primary-solid, currentColor);animation:et-table-busy-sweep 1.1s ease-in-out infinite}@keyframes et-table-busy-sweep{0%{transform:translate(-100%)}to{transform:translate(250%)}}@media(prefers-reduced-motion:reduce){.et-table-busy-bar:after{inline-size:100%;animation:none}.et-table-busy-bar.et-table-busy-bar--enter,.et-table-busy-bar.et-table-busy-bar--leave{animation:none}}}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: IconDirective, selector: "[etIcon]", inputs: ["etIcon", "variant", "allowHardcodedColor", "label"] }, { kind: "directive", type: ProvideColorDirective, selector: "[etProvideColor]", inputs: ["etProvideColor"] }, { kind: "directive", type: TableCardSurfaceDirective, selector: "[etTableCardSurface]", inputs: ["etTableCardSurface"] }], encapsulation: i0.ViewEncapsulation.None }); }
70572
+ ], queries: [{ propertyName: "footerSlot", first: true, predicate: TableFooterDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "gridRef", first: true, predicate: ["grid"], descendants: true, isSignal: true }, { propertyName: "headerGridRef", first: true, predicate: ["headerGrid"], descendants: true, isSignal: true }, { propertyName: "scrollerRef", first: true, predicate: ["scroller"], descendants: true, isSignal: true }, { propertyName: "headerCells", predicate: ["headerCell"], descendants: true, isSignal: true }, { propertyName: "bodyCells", predicate: ["bodyCell"], descendants: true, isSignal: true }, { propertyName: "gridCells", predicate: ["gridCell"], descendants: true, isSignal: true }, { propertyName: "leadHeaderCells", predicate: ["leadHeaderCell"], descendants: true, isSignal: true }, { propertyName: "trailHeaderCells", predicate: ["trailHeaderCell"], descendants: true, isSignal: true }], ngImport: i0, template: "<!-- Every binding below reads a field off a render model (see the `\u2026Vm` types in the component):\n methods belong in event bindings, not in bindings the framework re-evaluates each pass. -->\n<ng-template #headerContent>\n <!-- Rows a feature renders above the column headers (etTableGroupHeaders' spanning group row). Each\n is display: contents and lays its own cells into these tracks \u2014 see registerHeaderRow. -->\n @for (headerRow of headerRows(); track $index) {\n <ng-container *ngComponentOutlet=\"headerRow.component; injector: headerRow.injector\" />\n }\n\n <div [attr.aria-rowindex]=\"ariaRowCount() === null ? null : headerRowCount()\" class=\"et-table-header-row\" role=\"row\">\n <!-- Leading utility columns (selection from a feature, the expander when expansion is on). The\n table owns the cell chrome; the feature only supplies what goes inside. -->\n @for (lead of leadCells(); track lead.key) {\n <div\n #leadHeaderCell\n [class]=\"lead.cellClass\"\n [class.et-table-sticky-start]=\"lead.sticky\"\n [style.inset-inline-start.px]=\"pageStickyHeader() ? null : lead.offset\"\n class=\"et-table-header-cell\"\n role=\"columnheader\"\n >\n @if (lead.lead.headerComponent; as headerComponent) {\n <ng-container *ngComponentOutlet=\"headerComponent; injector: lead.lead.injector\" />\n }\n </div>\n }\n @for (cell of headerCellVms(); track cell.key) {\n <div\n #headerCell\n [attr.data-align]=\"cell.align\"\n [attr.data-col-key]=\"cell.key\"\n [attr.data-disabled]=\"cell.disabled || null\"\n [attr.aria-sort]=\"cell.ariaSort\"\n [class.et-table-sticky-start]=\"cell.stickyStart\"\n [class.et-table-sticky-end]=\"cell.stickyEnd\"\n [style.inset-inline-start.px]=\"pageStickyHeader() ? null : cell.offsetStart\"\n [style.inset-inline-end.px]=\"pageStickyHeader() ? null : cell.offsetEnd\"\n class=\"et-table-header-cell\"\n role=\"columnheader\"\n >\n <!-- Sorting is the whole header's job, not a control's: the label plus everything around it is\n one button, and the only sort affordance is the direction arrow, which appears once the\n column is actually sorted. Adornments sit outside it so their own clicks don't sort. -->\n @if (cell.sortable) {\n <button\n [attr.aria-label]=\"cell.sortLabel\"\n [attr.aria-description]=\"cell.priorityLabel\"\n [disabled]=\"cell.disabled\"\n (click)=\"activateSortHeader(cell.key, $event)\"\n (keydown.shift.enter)=\"activateSortHeader(cell.key, $event)\"\n class=\"et-table-header-label et-table-header-label--sortable\"\n type=\"button\"\n >\n <span class=\"et-table-header-label-box\">\n @if (cell.template; as headerTemplate) {\n <ng-container *ngTemplateOutlet=\"headerTemplate; context: { $implicit: cell.column.header }\" />\n } @else {\n <span class=\"et-table-cell-text\">{{ cell.column.header }}</span>\n }\n @if (cell.direction; as direction) {\n <!-- Flipping direction keeps this element mounted, so the arrow turns over rather than\n swapping; only appearing and disappearing are the fade, and only for a sort the user\n just asked for (see sortIndicatorEnter). -->\n <i\n [attr.data-direction]=\"direction\"\n [animate.enter]=\"sortIndicatorEnter()\"\n [animate.leave]=\"sortIndicatorLeave()\"\n class=\"et-table-sort-indicator\"\n etIcon=\"et-arrow-up\"\n ></i>\n }\n @if (cell.priority; as priority) {\n <span class=\"et-table-sort-priority\" aria-hidden=\"true\">{{ priority }}</span>\n }\n </span>\n </button>\n } @else {\n <span class=\"et-table-header-label\">\n <span class=\"et-table-header-label-box\">\n @if (cell.template; as headerTemplate) {\n <ng-container *ngTemplateOutlet=\"headerTemplate; context: { $implicit: cell.column.header }\" />\n } @else {\n <span class=\"et-table-cell-text\">{{ cell.column.header }}</span>\n }\n </span>\n </span>\n }\n\n <!-- UI from opt-in features (filter menu, \u2026), each registered rather than referenced \u2014 see\n registerHeaderAdornment. Renders nothing when no feature is imported.\n\n Dropped once the column is covered by a pinned one: an adornment's menu is a portal, so it\n would go on floating over the pinned column, anchored to a cell nobody can see. Unmounting\n the trigger is what closes it. -->\n @if (!cell.obscured && headerAdornments().length) {\n <div class=\"et-table-header-adornments\">\n @for (adornment of headerAdornments(); track $index) {\n <ng-container\n *ngComponentOutlet=\"adornment.component; inputs: { column: cell.column }; injector: adornment.injector\"\n />\n }\n </div>\n }\n </div>\n }\n <!-- Filler cell for the trailing slack track (see hasFiller): carries the header band to the\n panel's edge when every column is a rigid width. -->\n @if (hasFiller()) {\n <div class=\"et-table-header-cell et-table-filler-cell\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n <!-- Trailing utility columns (a selection column moved to this edge). Same chrome as the leading\n ones, pinned to the trailing edge instead - see TableLeadColumn.side. -->\n @for (trail of trailCells(); track trail.key) {\n <div\n #trailHeaderCell\n [class]=\"trail.cellClass\"\n [class.et-table-sticky-end]=\"trail.sticky\"\n [style.inset-inline-end.px]=\"pageStickyHeader() ? null : trail.offset\"\n class=\"et-table-header-cell\"\n role=\"columnheader\"\n >\n @if (trail.lead.headerComponent; as headerComponent) {\n <ng-container *ngComponentOutlet=\"headerComponent; injector: trail.lead.injector\" />\n }\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #bodyContent>\n <!-- Refetching over rows that are already on screen: a 2px indeterminate bar right under the header,\n so the data stays readable and in place. Drawn here rather than with `et-progress-bar` \u2014 the base\n table takes no component dependencies, and this is 2px of chrome, not a control. -->\n @if (showBusyBar()) {\n <!-- Faded in and out: a refetch is often over in a few hundred ms, and a bar that pops in and\n vanishes reads as a flicker rather than as work happening. -->\n <div\n class=\"et-table-busy-bar\"\n animate.enter=\"et-table-busy-bar--enter\"\n animate.leave=\"et-table-busy-bar--leave\"\n role=\"presentation\"\n aria-hidden=\"true\"\n ></div>\n }\n\n @if (spacers(); as spacer) {\n <div [style.block-size.px]=\"spacer.start\" class=\"et-table-spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n\n @if (hasError()) {\n <!-- The error state stands in for the whole body: rows are either trustworthy or absent. -->\n <div class=\"et-table-message-row\" role=\"row\">\n <div [attr.role]=\"cellRole()\" class=\"et-table-error-cell\" aria-live=\"polite\">\n @if (showErrorMessage()) {\n @if (errorTemplate(); as template) {\n <ng-container *ngTemplateOutlet=\"template; context: { $implicit: resolvedError() }\" />\n } @else {\n <ng-content select=\"[etTableError]\">\n <i [etProvideColor]=\"errorColorTheme()\" class=\"et-table-error-icon\" etIcon=\"et-triangle-exclamation\"></i>\n <span>{{ resolvedLabels().error }}</span>\n </ng-content>\n }\n }\n </div>\n </div>\n } @else if (showPlaceholderRows()) {\n <!-- First load with nothing to show yet. What a loading body looks like belongs to a feature\n (etTableSkeleton draws placeholder rows in these tracks); with none the body stays blank rather\n than showing a misleading empty state \u2014 the host's `aria-busy` is the announcement. -->\n @if (bodyPlaceholder(); as placeholder) {\n <ng-container *ngComponentOutlet=\"placeholder.component; injector: placeholder.injector\" />\n }\n } @else {\n @for (rowVm of bodyRows(); track rowVm.key) {\n <!-- A linked row is not a tab stop of its own: its anchor is the one stop, and the one link. -->\n <div\n [class]=\"rowVm.classes\"\n [class.et-table-row--stripe]=\"rowVm.stripe\"\n [class.et-table-row--last]=\"rowVm.last\"\n [class.et-table-row--interactive]=\"rowInteractive()\"\n [class.et-table-row--box]=\"rowBox()\"\n [class.et-table-row--card]=\"cardRows()\"\n [class.et-table-row--link]=\"rowVm.href !== null\"\n [etTableCardSurface]=\"cardRows()\"\n [attr.tabindex]=\"rowInteractive() && !cellNavigation() && rowVm.href === null ? 0 : null\"\n [attr.aria-rowindex]=\"rowVm.ariaRowIndex\"\n (click)=\"activateRow(rowVm.row, $event)\"\n (keydown.enter)=\"activateRow(rowVm.row, $event)\"\n (keydown.space)=\"activateRow(rowVm.row, $event)\"\n class=\"et-table-row\"\n role=\"row\"\n >\n @for (lead of rowVm.leads; track lead.key) {\n <div\n #gridCell\n [class]=\"lead.cellClass\"\n [attr.tabindex]=\"cellNavigation() ? -1 : null\"\n [class.et-table-sticky-start]=\"lead.sticky\"\n [style.inset-inline-start.px]=\"lead.offset\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-cell\"\n >\n <ng-container\n *ngComponentOutlet=\"lead.lead.bodyComponent; inputs: { row: rowVm.row }; injector: lead.lead.injector\"\n />\n </div>\n }\n @for (cell of rowVm.cells; track cell.key) {\n <div\n #bodyCell\n #gridCell\n [attr.data-align]=\"cell.align\"\n [attr.data-col-key]=\"cell.key\"\n [attr.tabindex]=\"cellNavigation() ? -1 : null\"\n [attr.data-state]=\"cell.state\"\n [attr.id]=\"cell.linkHost ? rowVm.linkLabelId : null\"\n [class.et-table-cell--interactive]=\"cell.interactive\"\n [class.et-table-cell--editing]=\"cell.edit\"\n [class.et-skeleton--animated]=\"cell.state === 'loading'\"\n [class.et-table-sticky-start]=\"cell.stickyStart\"\n [class.et-table-sticky-end]=\"cell.stickyEnd\"\n [style.inset-inline-start.px]=\"cell.offsetStart\"\n [style.inset-inline-end.px]=\"cell.offsetEnd\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-cell\"\n >\n @if (cell.edit; as edit) {\n <!-- The one cell in edit mode: the column's etTableCellEdit template, rendered with the\n editing feature's own context (the draft field). See registerCellEditing. -->\n <ng-container *ngTemplateOutlet=\"edit.template; context: edit.context\" />\n } @else if (cell.state === 'loading' && cellPlaceholder(); as placeholder) {\n <!-- A cell that is loading on its own (an inline edit saving) shows a feature's placeholder\n instead of its value; the row around it stays readable. Without one the value stays put\n and `data-state` carries the cue \u2014 see registerCellPlaceholder. -->\n <ng-container *ngComponentOutlet=\"placeholder.component; injector: placeholder.injector\" />\n } @else {\n @if (cell.state === 'error') {\n @if (cellErrorMark(); as mark) {\n <!-- A feature (etTableCellErrorTooltip) draws the mark instead, so the overlay runtime\n only ships when a table actually wants a tooltip. -->\n <ng-container\n *ngComponentOutlet=\"mark.component; inputs: { message: cell.message }; injector: mark.injector\"\n />\n } @else {\n <!-- Color-scoped here rather than on the cell: the mark is the only part that must read\n as an error, and a provider per errored cell is cheap where one per cell would not\n be. The message rides along as `title`, which costs nothing. -->\n <i\n [etProvideColor]=\"errorColorTheme()\"\n [attr.title]=\"cell.message\"\n [label]=\"cell.message\"\n class=\"et-table-cell-error-icon\"\n etIcon=\"et-triangle-exclamation\"\n ></i>\n }\n }\n @if (cell.template; as bodyTemplate) {\n <ng-container *ngTemplateOutlet=\"bodyTemplate; context: cell.context\" />\n } @else {\n <span class=\"et-table-cell-text\">{{ cell.value }}</span>\n }\n }\n </div>\n }\n @if (hasFiller()) {\n <div class=\"et-table-cell et-table-filler-cell\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n @for (trail of rowVm.trails; track trail.key) {\n <div\n #gridCell\n [class]=\"trail.cellClass\"\n [attr.tabindex]=\"cellNavigation() ? -1 : null\"\n [class.et-table-sticky-end]=\"trail.sticky\"\n [style.inset-inline-end.px]=\"trail.offset\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-cell\"\n >\n <ng-container\n *ngComponentOutlet=\"trail.lead.bodyComponent; inputs: { row: rowVm.row }; injector: trail.lead.injector\"\n />\n </div>\n }\n\n @if (rowVm.href !== null) {\n <!-- The row's link: one real anchor, stretched over the row box (see rowBox) rather than\n wrapping any content, so the cells stay exactly as a table without links renders them.\n It carries no text of its own and is named by the identity cell instead - `aria-labelledby`\n resolves to that cell's content, which is the row's identity.\n\n A child of the row, not of a cell: a cell that is pinned is `position: sticky` and would\n therefore be the anchor's containing block, shrinking the row's hit area to that one\n column. The row box is the containing block that spans every cell. -->\n <a\n [attr.href]=\"rowVm.href\"\n [attr.aria-labelledby]=\"rowVm.linkLabelId\"\n (click)=\"activateRowLink(rowVm.link, $event)\"\n class=\"et-table-row-link\"\n ></a>\n }\n\n @if (cardRows()) {\n <div class=\"et-table-card-corners\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n </div>\n\n <!-- The detail row of an expanded row, from etTableRowExpansion \u2014 the whole row, its chrome and\n its animation belong to the feature, so a table that never expands carries none of them. -->\n @if (rowVm.detail; as detail) {\n <ng-container *ngComponentOutlet=\"detail.component; inputs: { row: rowVm.row }; injector: detail.injector\" />\n }\n } @empty {\n <div class=\"et-table-message-row\" role=\"row\">\n <div [attr.role]=\"cellRole()\" class=\"et-table-empty-cell\">\n @if (emptyTemplate(); as template) {\n <ng-container *ngTemplateOutlet=\"template; context: { $implicit: rows() }\" />\n } @else {\n <ng-content select=\"[etTableEmpty]\">{{ resolvedLabels().empty }}</ng-content>\n }\n </div>\n </div>\n }\n }\n\n @if (spacers(); as spacer) {\n <div [style.block-size.px]=\"spacer.end\" class=\"et-table-spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n\n <!-- Edge gradients marking rows scrolled out of view horizontally, on the edges no pinned column\n already marks (see visibleScrollFades). The layer is absolutely positioned over the whole grid \u2014\n the full scroll extent, not just the viewport \u2014 which is what lets the two fades inside it hold\n their place with `position: sticky` for the entire scroll range. -->\n <div class=\"et-table-scroll-fades\" role=\"presentation\" aria-hidden=\"true\">\n <div\n [style.inset-inline-start.px]=\"fadeInset().start\"\n [class.et-table-scroll-fade--visible]=\"visibleScrollFades().start\"\n class=\"et-table-scroll-fade et-table-scroll-fade--start\"\n ></div>\n <div\n [style.inset-inline-end.px]=\"fadeInset().end\"\n [class.et-table-scroll-fade--visible]=\"visibleScrollFades().end\"\n class=\"et-table-scroll-fade et-table-scroll-fade--end\"\n ></div>\n </div>\n\n @if (hasFooter()) {\n <div [attr.aria-rowindex]=\"ariaRowCount()\" class=\"et-table-footer-row\" role=\"row\">\n @for (lead of leadCells(); track lead.key) {\n <div\n [class]=\"lead.cellClass\"\n [class.et-table-sticky-start]=\"lead.sticky\"\n [style.inset-inline-start.px]=\"lead.offset\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-footer-cell\"\n aria-hidden=\"true\"\n ></div>\n }\n @for (cell of footerCells(); track cell.key) {\n <div\n [attr.data-align]=\"cell.align\"\n [class.et-table-sticky-start]=\"cell.stickyStart\"\n [class.et-table-sticky-end]=\"cell.stickyEnd\"\n [style.inset-inline-start.px]=\"cell.offsetStart\"\n [style.inset-inline-end.px]=\"cell.offsetEnd\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-footer-cell\"\n >\n @if (cell.template; as footerTemplate) {\n <ng-container *ngTemplateOutlet=\"footerTemplate; context: { $implicit: rows() }\" />\n }\n </div>\n }\n @if (hasFiller()) {\n <div class=\"et-table-footer-cell et-table-filler-cell\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n @for (trail of trailCells(); track trail.key) {\n <div\n [class]=\"trail.cellClass\"\n [class.et-table-sticky-end]=\"trail.sticky\"\n [style.inset-inline-end.px]=\"trail.offset\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-footer-cell\"\n aria-hidden=\"true\"\n ></div>\n }\n </div>\n }\n</ng-template>\n\n@if (pageStickyHeader()) {\n <div class=\"et-table-header-strip\" role=\"presentation\">\n <div\n #headerGrid\n [style.grid-template-columns]=\"pageHeaderColumns()\"\n class=\"et-table et-table-header\"\n role=\"rowgroup\"\n >\n <ng-container *ngTemplateOutlet=\"headerContent\" />\n </div>\n </div>\n <div #scroller (scroll)=\"syncScrollState()\" class=\"et-table-scroller\" role=\"presentation\">\n <div #grid [style.grid-template-columns]=\"templateColumns()\" class=\"et-table\" role=\"rowgroup\">\n <ng-container *ngTemplateOutlet=\"bodyContent\" />\n </div>\n </div>\n} @else {\n <div\n #grid\n [style.grid-template-columns]=\"templateColumns()\"\n [attr.role]=\"tableRole()\"\n [attr.aria-rowcount]=\"ariaRowCount()\"\n class=\"et-table\"\n >\n <ng-container *ngTemplateOutlet=\"headerContent\" />\n <ng-container *ngTemplateOutlet=\"bodyContent\" />\n </div>\n}\n\n<!-- Full-width footer slot (paginator, page-size, etc.), pinned to the bottom of the scroll viewport.\n Rendered only when the consumer projects `[etTableFooter]`, so the chrome never shows empty. -->\n@if (footerSlot()) {\n <div class=\"et-table-footer\">\n <ng-content select=\"[etTableFooter]\" />\n </div>\n}\n\n<!-- Floating UI from opt-in features (the reorder drag ghost / drop indicator), stamped here so a\n feature can draw without having a view \u2014 or an element \u2014 of its own. -->\n@for (layer of layers(); track $index) {\n <ng-container *ngComponentOutlet=\"layer.component; injector: layer.injector\" />\n}\n", styles: ["@layer components{@property --et-table-cell-padding-block{syntax: \"<length>\"; inherits: true; initial-value: 10px;}@property --et-table-cell-padding-inline{syntax: \"<length>\"; inherits: true; initial-value: 12px;}@property --et-table-opacity-disabled{syntax: \"<number>\"; inherits: true; initial-value: .4;}:where(.et-table-host){display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:1fr auto;overflow:auto;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--et-surface-interaction-solid, gray) 35%,transparent) transparent;--_et-table-band: color-mix( in srgb, var(--et-surface-interaction-solid, gray) 7%, var(--et-surface-background-solid, Canvas) );--_et-table-header-bg: var(--et-table-header-background-color, var(--et-surface-background-solid, Canvas));--_et-table-header-border: var(--et-surface-border-solid, rgb(128 128 128 / .3));--_et-table-row-divider: transparent;--_et-table-header-adornment-size: 2.4rem;--_et-table-row-surface: var(--et-surface-background-solid, Canvas);--_et-table-stripe-bg: transparent;--_et-table-stripe-solid: var(--_et-table-row-surface);--_et-table-hover-tint: color-mix(in srgb, var(--et-surface-interaction-solid, gray) 8%, transparent);--_et-table-hover-tint-solid: color-mix( in srgb, var(--et-surface-interaction-solid, gray) 8%, var(--_et-table-row-surface) );--_et-table-row-hover: var(--_et-table-hover-tint);--_et-table-row-hover-solid: var(--_et-table-hover-tint-solid);--_et-table-pressed-tint: color-mix(in srgb, var(--et-surface-interaction-solid, gray) 16%, transparent);--_et-table-pressed-tint-solid: color-mix( in srgb, var(--et-surface-interaction-solid, gray) 16%, var(--_et-table-row-surface) );--_et-table-row-pressed: var(--_et-table-pressed-tint);--_et-table-row-pressed-solid: var(--_et-table-pressed-tint-solid);--_et-table-inert-row-hover: var(--_et-table-hover-tint);--_et-table-inert-row-hover-solid: var(--_et-table-hover-tint-solid);--_et-table-row-gap-block: 0px;--_et-table-row-paint: transparent;--_et-table-row-corner: 0px;--_et-table-header-gap-block: 0px;--_et-table-cell-rule: 0;--_et-table-sticky-clip: none;--_et-table-busy-margin-block-start: 0px;--_et-table-busy-margin-block-end: -2px;--_et-table-detail-rule: 1px solid var(--et-surface-border-solid, rgb(128 128 128 / .15));--_et-table-card-outside: var(--et-surface-background-solid, Canvas);--_et-table-pin-shadow: var( --et-table-pin-shadow-color, color-mix(in srgb, var(--et-surface-interaction-solid, black) 30%, transparent) );--_et-table-pin-shadow-inline: var(--et-table-pin-shadow-color-inline, var(--_et-table-pin-shadow));--_et-table-pin-shadow-block: var(--et-table-pin-shadow-color-block, var(--_et-table-pin-shadow));--_et-table-edge-none: 0 0 transparent;--_et-table-edge-start: var(--_et-table-edge-none);--_et-table-edge-end: var(--_et-table-edge-none);--_et-table-edge-block-start: var(--_et-table-edge-none);--_et-table-edge-block-end: var(--_et-table-edge-none)}.et-table-host--scrolled-inline-start{--_et-table-edge-start: 8px 0 10px -6px var(--_et-table-pin-shadow-inline)}.et-table-host--scrolled-inline-end{--_et-table-edge-end: -8px 0 10px -6px var(--_et-table-pin-shadow-inline)}.et-table-host--scrolled-block-start{--_et-table-edge-block-start: 0 8px 10px -6px var(--_et-table-pin-shadow-block)}.et-table-host--scrolled-block-end{--_et-table-edge-block-end: 0 -8px 10px -6px var(--_et-table-pin-shadow-block)}.et-table-host:where([data-density=sm]){--et-table-cell-padding-block: 6px;--et-table-cell-padding-inline: 10px}.et-table-host:where([data-density=md]){--et-table-cell-padding-block: 10px;--et-table-cell-padding-inline: 12px}.et-table-host:where([data-density=lg]){--et-table-cell-padding-block: 15px;--et-table-cell-padding-inline: 16px}.et-table-host:where([data-appearance=enclosed],[data-appearance=zebra],[data-appearance=grid]){border:1px solid var(--et-surface-border-solid, rgb(128 128 128 / .3));border-radius:var(--et-table-radius, 10px)}.et-table-host:where([data-appearance=enclosed]){--_et-table-header-bg: var(--et-table-header-background-color, var(--_et-table-band));--_et-table-row-divider: var(--et-surface-border-solid, rgb(128 128 128 / .15));box-shadow:0 1px 2px rgb(var(--et-shadow-color-rgb, 0 0 0) / .04),0 6px 16px rgb(var(--et-shadow-color-rgb, 0 0 0) / .06)}.et-table-host:where([data-appearance=divided]){--_et-table-row-divider: var(--et-surface-border-solid, rgb(128 128 128 / .15))}.et-table-host:where([data-appearance=zebra]){--_et-table-header-bg: var(--et-table-header-background-color, var(--_et-table-band));--_et-table-stripe-bg: color-mix(in srgb, var(--et-surface-interaction-solid, gray) 4%, transparent);--_et-table-stripe-solid: color-mix( in srgb, var(--et-surface-interaction-solid, gray) 4%, var(--_et-table-row-surface) )}.et-table-host:where([data-appearance=grid]){--_et-table-cell-rule: 1px solid var(--et-surface-border-solid, rgb(128 128 128 / .15));--_et-table-header-bg: var(--et-table-header-background-color, var(--_et-table-band));--_et-table-row-divider: var(--et-surface-border-solid, rgb(128 128 128 / .15))}.et-table-host:where([data-appearance=bare]){--_et-table-header-border: transparent}.et-table-host:where([data-appearance=cards]){--_et-table-row-gap-block: var(--et-table-row-gap, 8px);--_et-table-row-corner: var(--et-table-row-radius, 10px);--_et-table-header-gap-block: var(--et-table-row-gap, 8px);--_et-table-sticky-clip: inset(0 -24px);--_et-table-busy-margin-block-start: calc((var(--et-table-row-gap, 8px) + 2px) / -2);--_et-table-busy-margin-block-end: calc((var(--et-table-row-gap, 8px) - 2px) / 2);--_et-table-detail-rule: 0;--_et-table-inert-row-hover: transparent;--_et-table-header-bg: var(--et-table-header-background-color, var(--et-surface-background-solid, Canvas));--_et-table-row-divider: transparent}.et-table{display:grid;position:relative;align-content:start;inline-size:min-content;min-inline-size:100%;background:var(--et-surface-background-solid, Canvas);color:var(--et-surface-color-solid, CanvasText);font-size:14px;line-height:1.4}.et-table-header-cell.et-table-filler-cell,.et-table-cell.et-table-filler-cell,.et-table-footer-cell.et-table-filler-cell,.et-table-group-cell.et-table-filler-cell{padding-inline:0}.et-table-header-row,.et-table-row{display:contents}.et-table-header-cell,.et-table-cell{display:flex;align-items:center;min-inline-size:0;overflow:hidden;padding:var(--et-table-cell-padding-block) var(--et-table-cell-padding-inline)}.et-table-cell-text{min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.et-table-header-cell{position:sticky;inset-block-start:max(0px,calc(var(--_et-table-group-h, 0px) - 1px));gap:4px;z-index:1;font-weight:600;color:var(--et-table-header-color, var(--et-surface-color-muted-solid, CanvasText));background:var(--_et-table-header-bg);border-block-end:1px solid var(--_et-table-header-border)}.et-table-header-adornments{display:flex;align-items:center;flex:none}.et-table-header-cell .et-table-filter-trigger,.et-table-header-cell .et-table-column-menu-trigger{--et-icon-button-size: var(--_et-table-header-adornment-size);--et-icon-button-icon-size: 1.6rem;min-width:24px;min-height:24px}.et-table-host--header-adornments .et-table-header-cell{min-block-size:calc(max(var(--_et-table-header-adornment-size),24px) + 2 * var(--et-table-cell-padding-block) + 1px)}.et-table-cell{min-block-size:var(--et-table-row-min-block-size, auto);border-block-end:1px solid var(--_et-table-row-divider)}.et-table-header-cell{box-shadow:var(--_et-table-edge-block-start)}.et-table-footer,.et-table-footer-cell{box-shadow:var(--_et-table-edge-block-end)}.et-table-row--last:not(:has(+.et-table-detail-row)) .et-table-cell{border-block-end:0}.et-table-row--stripe .et-table-cell{background:var(--_et-table-stripe-bg)}.et-table-header-cell,.et-table-cell{border-inline-end:var(--_et-table-cell-rule)}.et-table-header-row .et-table-header-cell:last-child,.et-table-row .et-table-cell:nth-last-child(1 of.et-table-cell){border-inline-end:0}.et-table-footer-row{display:contents}.et-table-footer-cell{display:flex;align-items:center;min-inline-size:0;overflow:hidden;padding:var(--et-table-cell-padding-block) var(--et-table-cell-padding-inline);position:sticky;inset-block-end:0;z-index:1;font-weight:600;background:var(--_et-table-header-bg);border-block-start:1px solid var(--et-surface-border-solid, rgb(128 128 128 / .3))}.et-table-footer-cell:where([data-align=center]){justify-content:center;text-align:center}.et-table-footer-cell:where([data-align=end]){justify-content:flex-end;text-align:end}.et-table-scroll-fades{position:absolute;inset:0;display:flex;justify-content:space-between;z-index:3;pointer-events:none}.et-table-scroll-fade{position:sticky;flex:none;inline-size:var(--et-table-scroll-fade-size, 28px);opacity:0;transition:opacity .15s ease;--_et-table-scroll-fade-color: var( --et-table-scroll-fade-color, color-mix(in srgb, var(--et-surface-interaction-solid, black) 22%, transparent) )}.et-table-scroll-fade--visible{opacity:1}.et-table-scroll-fade--start{background:linear-gradient(to right,var(--_et-table-scroll-fade-color),transparent)}.et-table-scroll-fade--end{background:linear-gradient(to left,var(--_et-table-scroll-fade-color),transparent)}@media(prefers-reduced-motion:reduce){.et-table-scroll-fade{transition:none}}.et-table-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;position:sticky;inset-block-end:0;inset-inline-start:0;z-index:4;padding:var(--et-table-cell-padding-block) var(--et-table-cell-padding-inline);background:var(--_et-table-header-bg);border-block-start:1px solid var(--et-surface-border-solid, rgb(128 128 128 / .3))}.et-table-footer-label{margin:0;font-size:14px;color:var(--et-surface-color-muted-solid, CanvasText)}@media(pointer:coarse){.et-table-footer{gap:8px;padding:8px var(--et-table-cell-padding-inline)}}.et-table-header-cell:where([data-align=center]),.et-table-cell:where([data-align=center]){justify-content:center;text-align:center}.et-table-header-cell:where([data-align=end]),.et-table-cell:where([data-align=end]){justify-content:flex-end;text-align:end}.et-table-row--interactive .et-table-cell{cursor:pointer}@media(hover:hover){.et-table-row:hover .et-table-cell{background:var(--_et-table-row-hover)}}.et-table-row:where(.et-table-row--interactive,.et-table-row--link):active .et-table-cell{background:var(--_et-table-row-pressed)}.et-table-header-label:focus-visible,.et-table-expander:focus-visible,.et-table-cell:focus-visible{outline:2px solid var(--et-theme-color-primary-solid, currentColor);outline-offset:-2px}.et-table-header-label{border-radius:4px}.et-table-header-label{display:flex;align-items:center;flex:1;min-inline-size:0;margin:0;padding:0;font:inherit;color:inherit;text-align:inherit;background:none;border:none}.et-table-header-label-box{display:flex;align-items:center;gap:4px;min-inline-size:0;padding:4px;margin:-4px;border-radius:4px}.et-table-header-label:where(.et-table-header-label--sortable){cursor:pointer}.et-table-header-label--sortable .et-table-header-label-box{background-color:var(--_et-table-header-label-tint, transparent);transition:background-color .12s var(--ease-out-5, ease)}@media(hover:hover){.et-table-header-label--sortable:hover:not(:disabled){--_et-table-header-label-tint: var(--_et-table-hover-tint)}}.et-table-header-label--sortable:active:not(:disabled){--_et-table-header-label-tint: var(--_et-table-pressed-tint)}.et-table-header-cell:where([data-disabled]) .et-table-header-label{opacity:var(--et-table-opacity-disabled)}.et-table-header-label:where(.et-table-header-label--sortable:disabled){cursor:not-allowed}.et-table-header-cell:where([data-align=center]) .et-table-header-label{justify-content:center}.et-table-header-cell:where([data-align=end]) .et-table-header-label{justify-content:flex-end}.et-table-sort-indicator{flex:none;inline-size:1.15em;block-size:1.15em;transform:translateY(-.045em);color:var(--et-theme-color-primary-solid, currentColor);transition:transform .2s var(--ease-out-5, ease)}.et-table-sort-indicator:where([data-direction=desc]){transform:translateY(-.045em) rotate(180deg)}.et-table-sort-indicator.et-table-sort-indicator--enter{animation:et-table-sort-in .15s ease}.et-table-sort-indicator.et-table-sort-indicator--leave{animation:et-table-sort-in .12s ease reverse forwards}@keyframes et-table-sort-in{0%{opacity:0}to{opacity:1}}@media(prefers-reduced-motion:reduce){.et-table-sort-indicator{transition:none}.et-table-sort-indicator.et-table-sort-indicator--enter,.et-table-sort-indicator.et-table-sort-indicator--leave{animation:none}}.et-table-message-row{display:contents}.et-table-empty-cell,.et-table-error-cell{grid-column:1 / -1;position:sticky;inset-inline-start:0;inline-size:var(--_et-table-viewport-inline-size, 100%);padding:32px var(--et-table-cell-padding-inline);color:var(--et-surface-color-muted-solid, CanvasText);text-align:center}.et-table-empty-cell{display:grid;place-content:center;justify-items:center}.et-table-error-cell{display:flex;flex-wrap:wrap;align-items:center;align-content:center;justify-content:center;gap:8px}.et-table-error-icon{flex:none;inline-size:16px;block-size:16px;color:var(--et-theme-color-ink-solid, currentColor)}.et-table-cell:where([data-state=error]){gap:6px}.et-table-cell-error-icon{flex:none;inline-size:14px;block-size:14px;color:var(--et-theme-color-ink-solid, currentColor)}.et-table-cell:where([data-state=loading]){display:flex}.et-table-busy-bar{grid-column:1 / -1;block-size:2px;margin-block-start:var(--_et-table-busy-margin-block-start);margin-block-end:var(--_et-table-busy-margin-block-end);overflow:hidden;background:color-mix(in srgb,var(--et-surface-interaction-solid, gray) 10%,transparent)}.et-table-busy-bar.et-table-busy-bar--enter{animation:et-table-busy-fade .15s ease}.et-table-busy-bar.et-table-busy-bar--leave{animation:et-table-busy-fade .25s ease reverse forwards}@keyframes et-table-busy-fade{0%{opacity:0}to{opacity:1}}.et-table-busy-bar:after{content:\"\";display:block;inline-size:40%;block-size:100%;border-radius:999px;background:var(--et-theme-color-primary-solid, currentColor);animation:et-table-busy-sweep 1.1s ease-in-out infinite}@keyframes et-table-busy-sweep{0%{transform:translate(-100%)}to{transform:translate(250%)}}@media(prefers-reduced-motion:reduce){.et-table-busy-bar:after{inline-size:100%;animation:none}.et-table-busy-bar.et-table-busy-bar--enter,.et-table-busy-bar.et-table-busy-bar--leave{animation:none}}}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: IconDirective, selector: "[etIcon]", inputs: ["etIcon", "variant", "allowHardcodedColor", "label"] }, { kind: "directive", type: ProvideColorDirective, selector: "[etProvideColor]", inputs: ["etProvideColor"] }, { kind: "directive", type: TableCardSurfaceDirective, selector: "[etTableCardSurface]", inputs: ["etTableCardSurface"] }], encapsulation: i0.ViewEncapsulation.None }); }
70123
70573
  }
70124
70574
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TableComponent, decorators: [{
70125
70575
  type: Component,
@@ -70132,6 +70582,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
70132
70582
  '[attr.data-density]': 'density()',
70133
70583
  '[attr.aria-busy]': 'resolvedLoading() ? "true" : null',
70134
70584
  '[attr.role]': 'pageStickyHeader() ? tableRole() : null',
70585
+ '[attr.aria-rowcount]': 'pageStickyHeader() ? ariaRowCount() : null',
70135
70586
  '[class.et-table-host--scrolled-block-start]': 'blockScrollShadows().blockStart',
70136
70587
  '[class.et-table-host--scrolled-block-end]': 'blockScrollShadows().blockEnd',
70137
70588
  '[class.et-table-host--scrolled-inline-start]': 'scrollFades().start',
@@ -70139,7 +70590,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
70139
70590
  '[class.et-table-host--header-adornments]': 'headerAdornments().length > 0',
70140
70591
  '[style.--_et-table-viewport-inline-size.px]': 'viewportInlineSize()',
70141
70592
  '(scroll)': 'syncScrollState()',
70142
- }, template: "<!-- Every binding below reads a field off a render model (see the `\u2026Vm` types in the component):\n methods belong in event bindings, not in bindings the framework re-evaluates each pass. -->\n<ng-template #headerContent>\n <!-- Rows a feature renders above the column headers (etTableGroupHeaders' spanning group row). Each\n is display: contents and lays its own cells into these tracks \u2014 see registerHeaderRow. -->\n @for (headerRow of headerRows(); track $index) {\n <ng-container *ngComponentOutlet=\"headerRow.component; injector: headerRow.injector\" />\n }\n\n <div class=\"et-table-header-row\" role=\"row\">\n <!-- Leading utility columns (selection from a feature, the expander when expansion is on). The\n table owns the cell chrome; the feature only supplies what goes inside. -->\n @for (lead of leadCells(); track lead.key) {\n <div\n #leadHeaderCell\n [class]=\"lead.cellClass\"\n [class.et-table-sticky-start]=\"lead.sticky\"\n [style.inset-inline-start.px]=\"pageStickyHeader() ? null : lead.offset\"\n class=\"et-table-header-cell\"\n role=\"columnheader\"\n >\n @if (lead.lead.headerComponent; as headerComponent) {\n <ng-container *ngComponentOutlet=\"headerComponent; injector: lead.lead.injector\" />\n }\n </div>\n }\n @for (cell of headerCellVms(); track cell.key) {\n <div\n #headerCell\n [attr.data-align]=\"cell.align\"\n [attr.data-col-key]=\"cell.key\"\n [attr.data-disabled]=\"cell.disabled || null\"\n [attr.aria-sort]=\"cell.ariaSort\"\n [class.et-table-sticky-start]=\"cell.stickyStart\"\n [class.et-table-sticky-end]=\"cell.stickyEnd\"\n [style.inset-inline-start.px]=\"pageStickyHeader() ? null : cell.offsetStart\"\n [style.inset-inline-end.px]=\"pageStickyHeader() ? null : cell.offsetEnd\"\n class=\"et-table-header-cell\"\n role=\"columnheader\"\n >\n <!-- Sorting is the whole header's job, not a control's: the label plus everything around it is\n one button, and the only sort affordance is the direction arrow, which appears once the\n column is actually sorted. Adornments sit outside it so their own clicks don't sort. -->\n @if (cell.sortable) {\n <button\n [attr.aria-label]=\"cell.sortLabel\"\n [attr.aria-description]=\"cell.priorityLabel\"\n [disabled]=\"cell.disabled\"\n (click)=\"activateSortHeader(cell.key, $event)\"\n (keydown.shift.enter)=\"activateSortHeader(cell.key, $event)\"\n class=\"et-table-header-label et-table-header-label--sortable\"\n type=\"button\"\n >\n <span class=\"et-table-header-label-box\">\n @if (cell.template; as headerTemplate) {\n <ng-container *ngTemplateOutlet=\"headerTemplate; context: { $implicit: cell.column.header }\" />\n } @else {\n <span class=\"et-table-cell-text\">{{ cell.column.header }}</span>\n }\n @if (cell.direction; as direction) {\n <!-- Flipping direction keeps this element mounted, so the arrow turns over rather than\n swapping; only appearing and disappearing are the fade, and only for a sort the user\n just asked for (see sortIndicatorEnter). -->\n <i\n [attr.data-direction]=\"direction\"\n [animate.enter]=\"sortIndicatorEnter()\"\n [animate.leave]=\"sortIndicatorLeave()\"\n class=\"et-table-sort-indicator\"\n etIcon=\"et-arrow-up\"\n ></i>\n }\n @if (cell.priority; as priority) {\n <span class=\"et-table-sort-priority\" aria-hidden=\"true\">{{ priority }}</span>\n }\n </span>\n </button>\n } @else {\n <span class=\"et-table-header-label\">\n <span class=\"et-table-header-label-box\">\n @if (cell.template; as headerTemplate) {\n <ng-container *ngTemplateOutlet=\"headerTemplate; context: { $implicit: cell.column.header }\" />\n } @else {\n <span class=\"et-table-cell-text\">{{ cell.column.header }}</span>\n }\n </span>\n </span>\n }\n\n <!-- UI from opt-in features (filter menu, \u2026), each registered rather than referenced \u2014 see\n registerHeaderAdornment. Renders nothing when no feature is imported.\n\n Dropped once the column is covered by a pinned one: an adornment's menu is a portal, so it\n would go on floating over the pinned column, anchored to a cell nobody can see. Unmounting\n the trigger is what closes it. -->\n @if (!cell.obscured && headerAdornments().length) {\n <div class=\"et-table-header-adornments\">\n @for (adornment of headerAdornments(); track $index) {\n <ng-container\n *ngComponentOutlet=\"adornment.component; inputs: { column: cell.column }; injector: adornment.injector\"\n />\n }\n </div>\n }\n </div>\n }\n <!-- Filler cell for the trailing slack track (see hasFiller): carries the header band to the\n panel's edge when every column is a rigid width. -->\n @if (hasFiller()) {\n <div class=\"et-table-header-cell et-table-filler-cell\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n <!-- Trailing utility columns (a selection column moved to this edge). Same chrome as the leading\n ones, pinned to the trailing edge instead - see TableLeadColumn.side. -->\n @for (trail of trailCells(); track trail.key) {\n <div\n #trailHeaderCell\n [class]=\"trail.cellClass\"\n [class.et-table-sticky-end]=\"trail.sticky\"\n [style.inset-inline-end.px]=\"pageStickyHeader() ? null : trail.offset\"\n class=\"et-table-header-cell\"\n role=\"columnheader\"\n >\n @if (trail.lead.headerComponent; as headerComponent) {\n <ng-container *ngComponentOutlet=\"headerComponent; injector: trail.lead.injector\" />\n }\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #bodyContent>\n <!-- Refetching over rows that are already on screen: a 2px indeterminate bar right under the header,\n so the data stays readable and in place. Drawn here rather than with `et-progress-bar` \u2014 the base\n table takes no component dependencies, and this is 2px of chrome, not a control. -->\n @if (showBusyBar()) {\n <!-- Faded in and out: a refetch is often over in a few hundred ms, and a bar that pops in and\n vanishes reads as a flicker rather than as work happening. -->\n <div\n class=\"et-table-busy-bar\"\n animate.enter=\"et-table-busy-bar--enter\"\n animate.leave=\"et-table-busy-bar--leave\"\n role=\"presentation\"\n aria-hidden=\"true\"\n ></div>\n }\n\n @if (spacers(); as spacer) {\n <div [style.block-size.px]=\"spacer.start\" class=\"et-table-spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n\n @if (hasError()) {\n <!-- The error state stands in for the whole body: rows are either trustworthy or absent. -->\n <div class=\"et-table-message-row\" role=\"row\">\n <div [attr.role]=\"cellRole()\" class=\"et-table-error-cell\" aria-live=\"polite\">\n @if (showErrorMessage()) {\n @if (errorTemplate(); as template) {\n <ng-container *ngTemplateOutlet=\"template; context: { $implicit: resolvedError() }\" />\n } @else {\n <ng-content select=\"[etTableError]\">\n <i [etProvideColor]=\"errorColorTheme()\" class=\"et-table-error-icon\" etIcon=\"et-triangle-exclamation\"></i>\n <span>{{ resolvedLabels().error }}</span>\n </ng-content>\n }\n }\n </div>\n </div>\n } @else if (showPlaceholderRows()) {\n <!-- First load with nothing to show yet. What a loading body looks like belongs to a feature\n (etTableSkeleton draws placeholder rows in these tracks); with none the body stays blank rather\n than showing a misleading empty state \u2014 the host's `aria-busy` is the announcement. -->\n @if (bodyPlaceholder(); as placeholder) {\n <ng-container *ngComponentOutlet=\"placeholder.component; injector: placeholder.injector\" />\n }\n } @else {\n @for (rowVm of bodyRows(); track rowVm.key) {\n <!-- A linked row is not a tab stop of its own: its anchor is the one stop, and the one link. -->\n <div\n [class]=\"rowVm.classes\"\n [class.et-table-row--stripe]=\"rowVm.stripe\"\n [class.et-table-row--last]=\"rowVm.last\"\n [class.et-table-row--interactive]=\"rowInteractive()\"\n [class.et-table-row--box]=\"rowBox()\"\n [class.et-table-row--card]=\"cardRows()\"\n [class.et-table-row--link]=\"rowVm.href !== null\"\n [etTableCardSurface]=\"cardRows()\"\n [attr.tabindex]=\"rowInteractive() && !cellNavigation() && rowVm.href === null ? 0 : null\"\n (click)=\"activateRow(rowVm.row, $event)\"\n (keydown.enter)=\"activateRow(rowVm.row, $event)\"\n (keydown.space)=\"activateRow(rowVm.row, $event)\"\n class=\"et-table-row\"\n role=\"row\"\n >\n @for (lead of rowVm.leads; track lead.key) {\n <div\n #gridCell\n [class]=\"lead.cellClass\"\n [attr.tabindex]=\"cellNavigation() ? -1 : null\"\n [class.et-table-sticky-start]=\"lead.sticky\"\n [style.inset-inline-start.px]=\"lead.offset\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-cell\"\n >\n <ng-container\n *ngComponentOutlet=\"lead.lead.bodyComponent; inputs: { row: rowVm.row }; injector: lead.lead.injector\"\n />\n </div>\n }\n @for (cell of rowVm.cells; track cell.key) {\n <div\n #bodyCell\n #gridCell\n [attr.data-align]=\"cell.align\"\n [attr.data-col-key]=\"cell.key\"\n [attr.tabindex]=\"cellNavigation() ? -1 : null\"\n [attr.data-state]=\"cell.state\"\n [attr.id]=\"cell.linkHost ? rowVm.linkLabelId : null\"\n [class.et-table-cell--interactive]=\"cell.interactive\"\n [class.et-table-cell--editing]=\"cell.edit\"\n [class.et-skeleton--animated]=\"cell.state === 'loading'\"\n [class.et-table-sticky-start]=\"cell.stickyStart\"\n [class.et-table-sticky-end]=\"cell.stickyEnd\"\n [style.inset-inline-start.px]=\"cell.offsetStart\"\n [style.inset-inline-end.px]=\"cell.offsetEnd\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-cell\"\n >\n @if (cell.edit; as edit) {\n <!-- The one cell in edit mode: the column's etTableCellEdit template, rendered with the\n editing feature's own context (the draft field). See registerCellEditing. -->\n <ng-container *ngTemplateOutlet=\"edit.template; context: edit.context\" />\n } @else if (cell.state === 'loading' && cellPlaceholder(); as placeholder) {\n <!-- A cell that is loading on its own (an inline edit saving) shows a feature's placeholder\n instead of its value; the row around it stays readable. Without one the value stays put\n and `data-state` carries the cue \u2014 see registerCellPlaceholder. -->\n <ng-container *ngComponentOutlet=\"placeholder.component; injector: placeholder.injector\" />\n } @else {\n @if (cell.state === 'error') {\n @if (cellErrorMark(); as mark) {\n <!-- A feature (etTableCellErrorTooltip) draws the mark instead, so the overlay runtime\n only ships when a table actually wants a tooltip. -->\n <ng-container\n *ngComponentOutlet=\"mark.component; inputs: { message: cell.message }; injector: mark.injector\"\n />\n } @else {\n <!-- Color-scoped here rather than on the cell: the mark is the only part that must read\n as an error, and a provider per errored cell is cheap where one per cell would not\n be. The message rides along as `title`, which costs nothing. -->\n <i\n [etProvideColor]=\"errorColorTheme()\"\n [attr.title]=\"cell.message\"\n [label]=\"cell.message\"\n class=\"et-table-cell-error-icon\"\n etIcon=\"et-triangle-exclamation\"\n ></i>\n }\n }\n @if (cell.template; as bodyTemplate) {\n <ng-container *ngTemplateOutlet=\"bodyTemplate; context: cell.context\" />\n } @else {\n <span class=\"et-table-cell-text\">{{ cell.value }}</span>\n }\n }\n </div>\n }\n @if (hasFiller()) {\n <div class=\"et-table-cell et-table-filler-cell\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n @for (trail of rowVm.trails; track trail.key) {\n <div\n #gridCell\n [class]=\"trail.cellClass\"\n [attr.tabindex]=\"cellNavigation() ? -1 : null\"\n [class.et-table-sticky-end]=\"trail.sticky\"\n [style.inset-inline-end.px]=\"trail.offset\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-cell\"\n >\n <ng-container\n *ngComponentOutlet=\"trail.lead.bodyComponent; inputs: { row: rowVm.row }; injector: trail.lead.injector\"\n />\n </div>\n }\n\n @if (rowVm.href !== null) {\n <!-- The row's link: one real anchor, stretched over the row box (see rowBox) rather than\n wrapping any content, so the cells stay exactly as a table without links renders them.\n It carries no text of its own and is named by the identity cell instead - `aria-labelledby`\n resolves to that cell's content, which is the row's identity.\n\n A child of the row, not of a cell: a cell that is pinned is `position: sticky` and would\n therefore be the anchor's containing block, shrinking the row's hit area to that one\n column. The row box is the containing block that spans every cell. -->\n <a\n [attr.href]=\"rowVm.href\"\n [attr.aria-labelledby]=\"rowVm.linkLabelId\"\n (click)=\"activateRowLink(rowVm.link, $event)\"\n class=\"et-table-row-link\"\n ></a>\n }\n\n @if (cardRows()) {\n <div class=\"et-table-card-corners\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n </div>\n\n <!-- The detail row of an expanded row, from etTableRowExpansion \u2014 the whole row, its chrome and\n its animation belong to the feature, so a table that never expands carries none of them. -->\n @if (rowVm.detail; as detail) {\n <ng-container *ngComponentOutlet=\"detail.component; inputs: { row: rowVm.row }; injector: detail.injector\" />\n }\n } @empty {\n <div class=\"et-table-message-row\" role=\"row\">\n <div [attr.role]=\"cellRole()\" class=\"et-table-empty-cell\">\n @if (emptyTemplate(); as template) {\n <ng-container *ngTemplateOutlet=\"template; context: { $implicit: rows() }\" />\n } @else {\n <ng-content select=\"[etTableEmpty]\">{{ resolvedLabels().empty }}</ng-content>\n }\n </div>\n </div>\n }\n }\n\n @if (spacers(); as spacer) {\n <div [style.block-size.px]=\"spacer.end\" class=\"et-table-spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n\n <!-- Edge gradients marking rows scrolled out of view horizontally, on the edges no pinned column\n already marks (see visibleScrollFades). The layer is absolutely positioned over the whole grid \u2014\n the full scroll extent, not just the viewport \u2014 which is what lets the two fades inside it hold\n their place with `position: sticky` for the entire scroll range. -->\n <div class=\"et-table-scroll-fades\" role=\"presentation\" aria-hidden=\"true\">\n <div\n [style.inset-inline-start.px]=\"fadeInset().start\"\n [class.et-table-scroll-fade--visible]=\"visibleScrollFades().start\"\n class=\"et-table-scroll-fade et-table-scroll-fade--start\"\n ></div>\n <div\n [style.inset-inline-end.px]=\"fadeInset().end\"\n [class.et-table-scroll-fade--visible]=\"visibleScrollFades().end\"\n class=\"et-table-scroll-fade et-table-scroll-fade--end\"\n ></div>\n </div>\n\n @if (hasFooter()) {\n <div class=\"et-table-footer-row\" role=\"row\">\n @for (lead of leadCells(); track lead.key) {\n <div\n [class]=\"lead.cellClass\"\n [class.et-table-sticky-start]=\"lead.sticky\"\n [style.inset-inline-start.px]=\"lead.offset\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-footer-cell\"\n aria-hidden=\"true\"\n ></div>\n }\n @for (cell of footerCells(); track cell.key) {\n <div\n [attr.data-align]=\"cell.align\"\n [class.et-table-sticky-start]=\"cell.stickyStart\"\n [class.et-table-sticky-end]=\"cell.stickyEnd\"\n [style.inset-inline-start.px]=\"cell.offsetStart\"\n [style.inset-inline-end.px]=\"cell.offsetEnd\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-footer-cell\"\n >\n @if (cell.template; as footerTemplate) {\n <ng-container *ngTemplateOutlet=\"footerTemplate; context: { $implicit: rows() }\" />\n }\n </div>\n }\n @if (hasFiller()) {\n <div class=\"et-table-footer-cell et-table-filler-cell\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n @for (trail of trailCells(); track trail.key) {\n <div\n [class]=\"trail.cellClass\"\n [class.et-table-sticky-end]=\"trail.sticky\"\n [style.inset-inline-end.px]=\"trail.offset\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-footer-cell\"\n aria-hidden=\"true\"\n ></div>\n }\n </div>\n }\n</ng-template>\n\n@if (pageStickyHeader()) {\n <div class=\"et-table-header-strip\" role=\"presentation\">\n <div\n #headerGrid\n [style.grid-template-columns]=\"pageHeaderColumns()\"\n class=\"et-table et-table-header\"\n role=\"rowgroup\"\n >\n <ng-container *ngTemplateOutlet=\"headerContent\" />\n </div>\n </div>\n <div #scroller (scroll)=\"syncScrollState()\" class=\"et-table-scroller\" role=\"presentation\">\n <div #grid [style.grid-template-columns]=\"templateColumns()\" class=\"et-table\" role=\"rowgroup\">\n <ng-container *ngTemplateOutlet=\"bodyContent\" />\n </div>\n </div>\n} @else {\n <div #grid [style.grid-template-columns]=\"templateColumns()\" [attr.role]=\"tableRole()\" class=\"et-table\">\n <ng-container *ngTemplateOutlet=\"headerContent\" />\n <ng-container *ngTemplateOutlet=\"bodyContent\" />\n </div>\n}\n\n<!-- Full-width footer slot (paginator, page-size, etc.), pinned to the bottom of the scroll viewport.\n Rendered only when the consumer projects `[etTableFooter]`, so the chrome never shows empty. -->\n@if (footerSlot()) {\n <div class=\"et-table-footer\">\n <ng-content select=\"[etTableFooter]\" />\n </div>\n}\n\n<!-- Floating UI from opt-in features (the reorder drag ghost / drop indicator), stamped here so a\n feature can draw without having a view \u2014 or an element \u2014 of its own. -->\n@for (layer of layers(); track $index) {\n <ng-container *ngComponentOutlet=\"layer.component; injector: layer.injector\" />\n}\n", styles: ["@layer components{@property --et-table-cell-padding-block{syntax: \"<length>\"; inherits: true; initial-value: 10px;}@property --et-table-cell-padding-inline{syntax: \"<length>\"; inherits: true; initial-value: 12px;}@property --et-table-opacity-disabled{syntax: \"<number>\"; inherits: true; initial-value: .4;}:where(.et-table-host){display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:1fr auto;overflow:auto;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--et-surface-interaction-solid, gray) 35%,transparent) transparent;--_et-table-band: color-mix( in srgb, var(--et-surface-interaction-solid, gray) 7%, var(--et-surface-background-solid, Canvas) );--_et-table-header-bg: var(--et-table-header-background-color, var(--et-surface-background-solid, Canvas));--_et-table-header-border: var(--et-surface-border-solid, rgb(128 128 128 / .3));--_et-table-row-divider: transparent;--_et-table-header-adornment-size: 2.4rem;--_et-table-row-surface: var(--et-surface-background-solid, Canvas);--_et-table-stripe-bg: transparent;--_et-table-stripe-solid: var(--_et-table-row-surface);--_et-table-hover-tint: color-mix(in srgb, var(--et-surface-interaction-solid, gray) 8%, transparent);--_et-table-hover-tint-solid: color-mix( in srgb, var(--et-surface-interaction-solid, gray) 8%, var(--_et-table-row-surface) );--_et-table-row-hover: var(--_et-table-hover-tint);--_et-table-row-hover-solid: var(--_et-table-hover-tint-solid);--_et-table-pressed-tint: color-mix(in srgb, var(--et-surface-interaction-solid, gray) 16%, transparent);--_et-table-pressed-tint-solid: color-mix( in srgb, var(--et-surface-interaction-solid, gray) 16%, var(--_et-table-row-surface) );--_et-table-row-pressed: var(--_et-table-pressed-tint);--_et-table-row-pressed-solid: var(--_et-table-pressed-tint-solid);--_et-table-inert-row-hover: var(--_et-table-hover-tint);--_et-table-inert-row-hover-solid: var(--_et-table-hover-tint-solid);--_et-table-row-gap-block: 0px;--_et-table-row-paint: transparent;--_et-table-row-corner: 0px;--_et-table-header-gap-block: 0px;--_et-table-cell-rule: 0;--_et-table-sticky-clip: none;--_et-table-busy-margin-block-start: 0px;--_et-table-busy-margin-block-end: -2px;--_et-table-detail-rule: 1px solid var(--et-surface-border-solid, rgb(128 128 128 / .15));--_et-table-card-outside: var(--et-surface-background-solid, Canvas);--_et-table-pin-shadow: var( --et-table-pin-shadow-color, color-mix(in srgb, var(--et-surface-interaction-solid, black) 30%, transparent) );--_et-table-pin-shadow-inline: var(--et-table-pin-shadow-color-inline, var(--_et-table-pin-shadow));--_et-table-pin-shadow-block: var(--et-table-pin-shadow-color-block, var(--_et-table-pin-shadow));--_et-table-edge-none: 0 0 transparent;--_et-table-edge-start: var(--_et-table-edge-none);--_et-table-edge-end: var(--_et-table-edge-none);--_et-table-edge-block-start: var(--_et-table-edge-none);--_et-table-edge-block-end: var(--_et-table-edge-none)}.et-table-host--scrolled-inline-start{--_et-table-edge-start: 8px 0 10px -6px var(--_et-table-pin-shadow-inline)}.et-table-host--scrolled-inline-end{--_et-table-edge-end: -8px 0 10px -6px var(--_et-table-pin-shadow-inline)}.et-table-host--scrolled-block-start{--_et-table-edge-block-start: 0 8px 10px -6px var(--_et-table-pin-shadow-block)}.et-table-host--scrolled-block-end{--_et-table-edge-block-end: 0 -8px 10px -6px var(--_et-table-pin-shadow-block)}.et-table-host:where([data-density=sm]){--et-table-cell-padding-block: 6px;--et-table-cell-padding-inline: 10px}.et-table-host:where([data-density=md]){--et-table-cell-padding-block: 10px;--et-table-cell-padding-inline: 12px}.et-table-host:where([data-density=lg]){--et-table-cell-padding-block: 15px;--et-table-cell-padding-inline: 16px}.et-table-host:where([data-appearance=enclosed],[data-appearance=zebra],[data-appearance=grid]){border:1px solid var(--et-surface-border-solid, rgb(128 128 128 / .3));border-radius:var(--et-table-radius, 10px)}.et-table-host:where([data-appearance=enclosed]){--_et-table-header-bg: var(--et-table-header-background-color, var(--_et-table-band));--_et-table-row-divider: var(--et-surface-border-solid, rgb(128 128 128 / .15));box-shadow:0 1px 2px rgb(var(--et-shadow-color-rgb, 0 0 0) / .04),0 6px 16px rgb(var(--et-shadow-color-rgb, 0 0 0) / .06)}.et-table-host:where([data-appearance=divided]){--_et-table-row-divider: var(--et-surface-border-solid, rgb(128 128 128 / .15))}.et-table-host:where([data-appearance=zebra]){--_et-table-header-bg: var(--et-table-header-background-color, var(--_et-table-band));--_et-table-stripe-bg: color-mix(in srgb, var(--et-surface-interaction-solid, gray) 4%, transparent);--_et-table-stripe-solid: color-mix( in srgb, var(--et-surface-interaction-solid, gray) 4%, var(--_et-table-row-surface) )}.et-table-host:where([data-appearance=grid]){--_et-table-cell-rule: 1px solid var(--et-surface-border-solid, rgb(128 128 128 / .15));--_et-table-header-bg: var(--et-table-header-background-color, var(--_et-table-band));--_et-table-row-divider: var(--et-surface-border-solid, rgb(128 128 128 / .15))}.et-table-host:where([data-appearance=bare]){--_et-table-header-border: transparent}.et-table-host:where([data-appearance=cards]){--_et-table-row-gap-block: var(--et-table-row-gap, 8px);--_et-table-row-corner: var(--et-table-row-radius, 10px);--_et-table-header-gap-block: var(--et-table-row-gap, 8px);--_et-table-sticky-clip: inset(0 -24px);--_et-table-busy-margin-block-start: calc((var(--et-table-row-gap, 8px) + 2px) / -2);--_et-table-busy-margin-block-end: calc((var(--et-table-row-gap, 8px) - 2px) / 2);--_et-table-detail-rule: 0;--_et-table-inert-row-hover: transparent;--_et-table-header-bg: var(--et-table-header-background-color, var(--et-surface-background-solid, Canvas));--_et-table-row-divider: transparent}.et-table{display:grid;position:relative;align-content:start;inline-size:min-content;min-inline-size:100%;background:var(--et-surface-background-solid, Canvas);color:var(--et-surface-color-solid, CanvasText);font-size:14px;line-height:1.4}.et-table-header-cell.et-table-filler-cell,.et-table-cell.et-table-filler-cell,.et-table-footer-cell.et-table-filler-cell,.et-table-group-cell.et-table-filler-cell{padding-inline:0}.et-table-header-row,.et-table-row{display:contents}.et-table-header-cell,.et-table-cell{display:flex;align-items:center;min-inline-size:0;overflow:hidden;padding:var(--et-table-cell-padding-block) var(--et-table-cell-padding-inline)}.et-table-cell-text{min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.et-table-header-cell{position:sticky;inset-block-start:max(0px,calc(var(--_et-table-group-h, 0px) - 1px));gap:4px;z-index:1;font-weight:600;color:var(--et-table-header-color, var(--et-surface-color-muted-solid, CanvasText));background:var(--_et-table-header-bg);border-block-end:1px solid var(--_et-table-header-border)}.et-table-header-adornments{display:flex;align-items:center;flex:none}.et-table-header-cell .et-table-filter-trigger,.et-table-header-cell .et-table-column-menu-trigger{--et-icon-button-size: var(--_et-table-header-adornment-size);--et-icon-button-icon-size: 1.6rem;min-width:24px;min-height:24px}.et-table-host--header-adornments .et-table-header-cell{min-block-size:calc(max(var(--_et-table-header-adornment-size),24px) + 2 * var(--et-table-cell-padding-block) + 1px)}.et-table-cell{min-block-size:var(--et-table-row-min-block-size, auto);border-block-end:1px solid var(--_et-table-row-divider)}.et-table-header-cell{box-shadow:var(--_et-table-edge-block-start)}.et-table-footer,.et-table-footer-cell{box-shadow:var(--_et-table-edge-block-end)}.et-table-row--last:not(:has(+.et-table-detail-row)) .et-table-cell{border-block-end:0}.et-table-row--stripe .et-table-cell{background:var(--_et-table-stripe-bg)}.et-table-header-cell,.et-table-cell{border-inline-end:var(--_et-table-cell-rule)}.et-table-header-row .et-table-header-cell:last-child,.et-table-row .et-table-cell:nth-last-child(1 of.et-table-cell){border-inline-end:0}.et-table-footer-row{display:contents}.et-table-footer-cell{display:flex;align-items:center;min-inline-size:0;overflow:hidden;padding:var(--et-table-cell-padding-block) var(--et-table-cell-padding-inline);position:sticky;inset-block-end:0;z-index:1;font-weight:600;background:var(--_et-table-header-bg);border-block-start:1px solid var(--et-surface-border-solid, rgb(128 128 128 / .3))}.et-table-footer-cell:where([data-align=center]){justify-content:center;text-align:center}.et-table-footer-cell:where([data-align=end]){justify-content:flex-end;text-align:end}.et-table-scroll-fades{position:absolute;inset:0;display:flex;justify-content:space-between;z-index:3;pointer-events:none}.et-table-scroll-fade{position:sticky;flex:none;inline-size:var(--et-table-scroll-fade-size, 28px);opacity:0;transition:opacity .15s ease;--_et-table-scroll-fade-color: var( --et-table-scroll-fade-color, color-mix(in srgb, var(--et-surface-interaction-solid, black) 22%, transparent) )}.et-table-scroll-fade--visible{opacity:1}.et-table-scroll-fade--start{background:linear-gradient(to right,var(--_et-table-scroll-fade-color),transparent)}.et-table-scroll-fade--end{background:linear-gradient(to left,var(--_et-table-scroll-fade-color),transparent)}@media(prefers-reduced-motion:reduce){.et-table-scroll-fade{transition:none}}.et-table-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;position:sticky;inset-block-end:0;inset-inline-start:0;z-index:4;padding:var(--et-table-cell-padding-block) var(--et-table-cell-padding-inline);background:var(--_et-table-header-bg);border-block-start:1px solid var(--et-surface-border-solid, rgb(128 128 128 / .3))}.et-table-footer-label{margin:0;font-size:14px;color:var(--et-surface-color-muted-solid, CanvasText)}@media(pointer:coarse){.et-table-footer{gap:8px;padding:8px var(--et-table-cell-padding-inline)}}.et-table-header-cell:where([data-align=center]),.et-table-cell:where([data-align=center]){justify-content:center;text-align:center}.et-table-header-cell:where([data-align=end]),.et-table-cell:where([data-align=end]){justify-content:flex-end;text-align:end}.et-table-row--interactive .et-table-cell{cursor:pointer}@media(hover:hover){.et-table-row:hover .et-table-cell{background:var(--_et-table-row-hover)}}.et-table-row:where(.et-table-row--interactive,.et-table-row--link):active .et-table-cell{background:var(--_et-table-row-pressed)}.et-table-header-label:focus-visible,.et-table-expander:focus-visible,.et-table-cell:focus-visible{outline:2px solid var(--et-theme-color-primary-solid, currentColor);outline-offset:-2px}.et-table-header-label{border-radius:4px}.et-table-header-label{display:flex;align-items:center;flex:1;min-inline-size:0;margin:0;padding:0;font:inherit;color:inherit;text-align:inherit;background:none;border:none}.et-table-header-label-box{display:flex;align-items:center;gap:4px;min-inline-size:0;padding:4px;margin:-4px;border-radius:4px}.et-table-header-label:where(.et-table-header-label--sortable){cursor:pointer}.et-table-header-label--sortable .et-table-header-label-box{background-color:var(--_et-table-header-label-tint, transparent);transition:background-color .12s var(--ease-out-5, ease)}@media(hover:hover){.et-table-header-label--sortable:hover:not(:disabled){--_et-table-header-label-tint: var(--_et-table-hover-tint)}}.et-table-header-label--sortable:active:not(:disabled){--_et-table-header-label-tint: var(--_et-table-pressed-tint)}.et-table-header-cell:where([data-disabled]) .et-table-header-label{opacity:var(--et-table-opacity-disabled)}.et-table-header-label:where(.et-table-header-label--sortable:disabled){cursor:not-allowed}.et-table-header-cell:where([data-align=center]) .et-table-header-label{justify-content:center}.et-table-header-cell:where([data-align=end]) .et-table-header-label{justify-content:flex-end}.et-table-sort-indicator{flex:none;inline-size:1.15em;block-size:1.15em;transform:translateY(-.045em);color:var(--et-theme-color-primary-solid, currentColor);transition:transform .2s var(--ease-out-5, ease)}.et-table-sort-indicator:where([data-direction=desc]){transform:translateY(-.045em) rotate(180deg)}.et-table-sort-indicator.et-table-sort-indicator--enter{animation:et-table-sort-in .15s ease}.et-table-sort-indicator.et-table-sort-indicator--leave{animation:et-table-sort-in .12s ease reverse forwards}@keyframes et-table-sort-in{0%{opacity:0}to{opacity:1}}@media(prefers-reduced-motion:reduce){.et-table-sort-indicator{transition:none}.et-table-sort-indicator.et-table-sort-indicator--enter,.et-table-sort-indicator.et-table-sort-indicator--leave{animation:none}}.et-table-message-row{display:contents}.et-table-empty-cell,.et-table-error-cell{grid-column:1 / -1;position:sticky;inset-inline-start:0;inline-size:var(--_et-table-viewport-inline-size, 100%);padding:32px var(--et-table-cell-padding-inline);color:var(--et-surface-color-muted-solid, CanvasText);text-align:center}.et-table-empty-cell{display:grid;place-content:center;justify-items:center}.et-table-error-cell{display:flex;flex-wrap:wrap;align-items:center;align-content:center;justify-content:center;gap:8px}.et-table-error-icon{flex:none;inline-size:16px;block-size:16px;color:var(--et-theme-color-ink-solid, currentColor)}.et-table-cell:where([data-state=error]){gap:6px}.et-table-cell-error-icon{flex:none;inline-size:14px;block-size:14px;color:var(--et-theme-color-ink-solid, currentColor)}.et-table-cell:where([data-state=loading]){display:flex}.et-table-busy-bar{grid-column:1 / -1;block-size:2px;margin-block-start:var(--_et-table-busy-margin-block-start);margin-block-end:var(--_et-table-busy-margin-block-end);overflow:hidden;background:color-mix(in srgb,var(--et-surface-interaction-solid, gray) 10%,transparent)}.et-table-busy-bar.et-table-busy-bar--enter{animation:et-table-busy-fade .15s ease}.et-table-busy-bar.et-table-busy-bar--leave{animation:et-table-busy-fade .25s ease reverse forwards}@keyframes et-table-busy-fade{0%{opacity:0}to{opacity:1}}.et-table-busy-bar:after{content:\"\";display:block;inline-size:40%;block-size:100%;border-radius:999px;background:var(--et-theme-color-primary-solid, currentColor);animation:et-table-busy-sweep 1.1s ease-in-out infinite}@keyframes et-table-busy-sweep{0%{transform:translate(-100%)}to{transform:translate(250%)}}@media(prefers-reduced-motion:reduce){.et-table-busy-bar:after{inline-size:100%;animation:none}.et-table-busy-bar.et-table-busy-bar--enter,.et-table-busy-bar.et-table-busy-bar--leave{animation:none}}}\n"] }]
70593
+ }, template: "<!-- Every binding below reads a field off a render model (see the `\u2026Vm` types in the component):\n methods belong in event bindings, not in bindings the framework re-evaluates each pass. -->\n<ng-template #headerContent>\n <!-- Rows a feature renders above the column headers (etTableGroupHeaders' spanning group row). Each\n is display: contents and lays its own cells into these tracks \u2014 see registerHeaderRow. -->\n @for (headerRow of headerRows(); track $index) {\n <ng-container *ngComponentOutlet=\"headerRow.component; injector: headerRow.injector\" />\n }\n\n <div [attr.aria-rowindex]=\"ariaRowCount() === null ? null : headerRowCount()\" class=\"et-table-header-row\" role=\"row\">\n <!-- Leading utility columns (selection from a feature, the expander when expansion is on). The\n table owns the cell chrome; the feature only supplies what goes inside. -->\n @for (lead of leadCells(); track lead.key) {\n <div\n #leadHeaderCell\n [class]=\"lead.cellClass\"\n [class.et-table-sticky-start]=\"lead.sticky\"\n [style.inset-inline-start.px]=\"pageStickyHeader() ? null : lead.offset\"\n class=\"et-table-header-cell\"\n role=\"columnheader\"\n >\n @if (lead.lead.headerComponent; as headerComponent) {\n <ng-container *ngComponentOutlet=\"headerComponent; injector: lead.lead.injector\" />\n }\n </div>\n }\n @for (cell of headerCellVms(); track cell.key) {\n <div\n #headerCell\n [attr.data-align]=\"cell.align\"\n [attr.data-col-key]=\"cell.key\"\n [attr.data-disabled]=\"cell.disabled || null\"\n [attr.aria-sort]=\"cell.ariaSort\"\n [class.et-table-sticky-start]=\"cell.stickyStart\"\n [class.et-table-sticky-end]=\"cell.stickyEnd\"\n [style.inset-inline-start.px]=\"pageStickyHeader() ? null : cell.offsetStart\"\n [style.inset-inline-end.px]=\"pageStickyHeader() ? null : cell.offsetEnd\"\n class=\"et-table-header-cell\"\n role=\"columnheader\"\n >\n <!-- Sorting is the whole header's job, not a control's: the label plus everything around it is\n one button, and the only sort affordance is the direction arrow, which appears once the\n column is actually sorted. Adornments sit outside it so their own clicks don't sort. -->\n @if (cell.sortable) {\n <button\n [attr.aria-label]=\"cell.sortLabel\"\n [attr.aria-description]=\"cell.priorityLabel\"\n [disabled]=\"cell.disabled\"\n (click)=\"activateSortHeader(cell.key, $event)\"\n (keydown.shift.enter)=\"activateSortHeader(cell.key, $event)\"\n class=\"et-table-header-label et-table-header-label--sortable\"\n type=\"button\"\n >\n <span class=\"et-table-header-label-box\">\n @if (cell.template; as headerTemplate) {\n <ng-container *ngTemplateOutlet=\"headerTemplate; context: { $implicit: cell.column.header }\" />\n } @else {\n <span class=\"et-table-cell-text\">{{ cell.column.header }}</span>\n }\n @if (cell.direction; as direction) {\n <!-- Flipping direction keeps this element mounted, so the arrow turns over rather than\n swapping; only appearing and disappearing are the fade, and only for a sort the user\n just asked for (see sortIndicatorEnter). -->\n <i\n [attr.data-direction]=\"direction\"\n [animate.enter]=\"sortIndicatorEnter()\"\n [animate.leave]=\"sortIndicatorLeave()\"\n class=\"et-table-sort-indicator\"\n etIcon=\"et-arrow-up\"\n ></i>\n }\n @if (cell.priority; as priority) {\n <span class=\"et-table-sort-priority\" aria-hidden=\"true\">{{ priority }}</span>\n }\n </span>\n </button>\n } @else {\n <span class=\"et-table-header-label\">\n <span class=\"et-table-header-label-box\">\n @if (cell.template; as headerTemplate) {\n <ng-container *ngTemplateOutlet=\"headerTemplate; context: { $implicit: cell.column.header }\" />\n } @else {\n <span class=\"et-table-cell-text\">{{ cell.column.header }}</span>\n }\n </span>\n </span>\n }\n\n <!-- UI from opt-in features (filter menu, \u2026), each registered rather than referenced \u2014 see\n registerHeaderAdornment. Renders nothing when no feature is imported.\n\n Dropped once the column is covered by a pinned one: an adornment's menu is a portal, so it\n would go on floating over the pinned column, anchored to a cell nobody can see. Unmounting\n the trigger is what closes it. -->\n @if (!cell.obscured && headerAdornments().length) {\n <div class=\"et-table-header-adornments\">\n @for (adornment of headerAdornments(); track $index) {\n <ng-container\n *ngComponentOutlet=\"adornment.component; inputs: { column: cell.column }; injector: adornment.injector\"\n />\n }\n </div>\n }\n </div>\n }\n <!-- Filler cell for the trailing slack track (see hasFiller): carries the header band to the\n panel's edge when every column is a rigid width. -->\n @if (hasFiller()) {\n <div class=\"et-table-header-cell et-table-filler-cell\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n <!-- Trailing utility columns (a selection column moved to this edge). Same chrome as the leading\n ones, pinned to the trailing edge instead - see TableLeadColumn.side. -->\n @for (trail of trailCells(); track trail.key) {\n <div\n #trailHeaderCell\n [class]=\"trail.cellClass\"\n [class.et-table-sticky-end]=\"trail.sticky\"\n [style.inset-inline-end.px]=\"pageStickyHeader() ? null : trail.offset\"\n class=\"et-table-header-cell\"\n role=\"columnheader\"\n >\n @if (trail.lead.headerComponent; as headerComponent) {\n <ng-container *ngComponentOutlet=\"headerComponent; injector: trail.lead.injector\" />\n }\n </div>\n }\n </div>\n</ng-template>\n\n<ng-template #bodyContent>\n <!-- Refetching over rows that are already on screen: a 2px indeterminate bar right under the header,\n so the data stays readable and in place. Drawn here rather than with `et-progress-bar` \u2014 the base\n table takes no component dependencies, and this is 2px of chrome, not a control. -->\n @if (showBusyBar()) {\n <!-- Faded in and out: a refetch is often over in a few hundred ms, and a bar that pops in and\n vanishes reads as a flicker rather than as work happening. -->\n <div\n class=\"et-table-busy-bar\"\n animate.enter=\"et-table-busy-bar--enter\"\n animate.leave=\"et-table-busy-bar--leave\"\n role=\"presentation\"\n aria-hidden=\"true\"\n ></div>\n }\n\n @if (spacers(); as spacer) {\n <div [style.block-size.px]=\"spacer.start\" class=\"et-table-spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n\n @if (hasError()) {\n <!-- The error state stands in for the whole body: rows are either trustworthy or absent. -->\n <div class=\"et-table-message-row\" role=\"row\">\n <div [attr.role]=\"cellRole()\" class=\"et-table-error-cell\" aria-live=\"polite\">\n @if (showErrorMessage()) {\n @if (errorTemplate(); as template) {\n <ng-container *ngTemplateOutlet=\"template; context: { $implicit: resolvedError() }\" />\n } @else {\n <ng-content select=\"[etTableError]\">\n <i [etProvideColor]=\"errorColorTheme()\" class=\"et-table-error-icon\" etIcon=\"et-triangle-exclamation\"></i>\n <span>{{ resolvedLabels().error }}</span>\n </ng-content>\n }\n }\n </div>\n </div>\n } @else if (showPlaceholderRows()) {\n <!-- First load with nothing to show yet. What a loading body looks like belongs to a feature\n (etTableSkeleton draws placeholder rows in these tracks); with none the body stays blank rather\n than showing a misleading empty state \u2014 the host's `aria-busy` is the announcement. -->\n @if (bodyPlaceholder(); as placeholder) {\n <ng-container *ngComponentOutlet=\"placeholder.component; injector: placeholder.injector\" />\n }\n } @else {\n @for (rowVm of bodyRows(); track rowVm.key) {\n <!-- A linked row is not a tab stop of its own: its anchor is the one stop, and the one link. -->\n <div\n [class]=\"rowVm.classes\"\n [class.et-table-row--stripe]=\"rowVm.stripe\"\n [class.et-table-row--last]=\"rowVm.last\"\n [class.et-table-row--interactive]=\"rowInteractive()\"\n [class.et-table-row--box]=\"rowBox()\"\n [class.et-table-row--card]=\"cardRows()\"\n [class.et-table-row--link]=\"rowVm.href !== null\"\n [etTableCardSurface]=\"cardRows()\"\n [attr.tabindex]=\"rowInteractive() && !cellNavigation() && rowVm.href === null ? 0 : null\"\n [attr.aria-rowindex]=\"rowVm.ariaRowIndex\"\n (click)=\"activateRow(rowVm.row, $event)\"\n (keydown.enter)=\"activateRow(rowVm.row, $event)\"\n (keydown.space)=\"activateRow(rowVm.row, $event)\"\n class=\"et-table-row\"\n role=\"row\"\n >\n @for (lead of rowVm.leads; track lead.key) {\n <div\n #gridCell\n [class]=\"lead.cellClass\"\n [attr.tabindex]=\"cellNavigation() ? -1 : null\"\n [class.et-table-sticky-start]=\"lead.sticky\"\n [style.inset-inline-start.px]=\"lead.offset\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-cell\"\n >\n <ng-container\n *ngComponentOutlet=\"lead.lead.bodyComponent; inputs: { row: rowVm.row }; injector: lead.lead.injector\"\n />\n </div>\n }\n @for (cell of rowVm.cells; track cell.key) {\n <div\n #bodyCell\n #gridCell\n [attr.data-align]=\"cell.align\"\n [attr.data-col-key]=\"cell.key\"\n [attr.tabindex]=\"cellNavigation() ? -1 : null\"\n [attr.data-state]=\"cell.state\"\n [attr.id]=\"cell.linkHost ? rowVm.linkLabelId : null\"\n [class.et-table-cell--interactive]=\"cell.interactive\"\n [class.et-table-cell--editing]=\"cell.edit\"\n [class.et-skeleton--animated]=\"cell.state === 'loading'\"\n [class.et-table-sticky-start]=\"cell.stickyStart\"\n [class.et-table-sticky-end]=\"cell.stickyEnd\"\n [style.inset-inline-start.px]=\"cell.offsetStart\"\n [style.inset-inline-end.px]=\"cell.offsetEnd\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-cell\"\n >\n @if (cell.edit; as edit) {\n <!-- The one cell in edit mode: the column's etTableCellEdit template, rendered with the\n editing feature's own context (the draft field). See registerCellEditing. -->\n <ng-container *ngTemplateOutlet=\"edit.template; context: edit.context\" />\n } @else if (cell.state === 'loading' && cellPlaceholder(); as placeholder) {\n <!-- A cell that is loading on its own (an inline edit saving) shows a feature's placeholder\n instead of its value; the row around it stays readable. Without one the value stays put\n and `data-state` carries the cue \u2014 see registerCellPlaceholder. -->\n <ng-container *ngComponentOutlet=\"placeholder.component; injector: placeholder.injector\" />\n } @else {\n @if (cell.state === 'error') {\n @if (cellErrorMark(); as mark) {\n <!-- A feature (etTableCellErrorTooltip) draws the mark instead, so the overlay runtime\n only ships when a table actually wants a tooltip. -->\n <ng-container\n *ngComponentOutlet=\"mark.component; inputs: { message: cell.message }; injector: mark.injector\"\n />\n } @else {\n <!-- Color-scoped here rather than on the cell: the mark is the only part that must read\n as an error, and a provider per errored cell is cheap where one per cell would not\n be. The message rides along as `title`, which costs nothing. -->\n <i\n [etProvideColor]=\"errorColorTheme()\"\n [attr.title]=\"cell.message\"\n [label]=\"cell.message\"\n class=\"et-table-cell-error-icon\"\n etIcon=\"et-triangle-exclamation\"\n ></i>\n }\n }\n @if (cell.template; as bodyTemplate) {\n <ng-container *ngTemplateOutlet=\"bodyTemplate; context: cell.context\" />\n } @else {\n <span class=\"et-table-cell-text\">{{ cell.value }}</span>\n }\n }\n </div>\n }\n @if (hasFiller()) {\n <div class=\"et-table-cell et-table-filler-cell\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n @for (trail of rowVm.trails; track trail.key) {\n <div\n #gridCell\n [class]=\"trail.cellClass\"\n [attr.tabindex]=\"cellNavigation() ? -1 : null\"\n [class.et-table-sticky-end]=\"trail.sticky\"\n [style.inset-inline-end.px]=\"trail.offset\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-cell\"\n >\n <ng-container\n *ngComponentOutlet=\"trail.lead.bodyComponent; inputs: { row: rowVm.row }; injector: trail.lead.injector\"\n />\n </div>\n }\n\n @if (rowVm.href !== null) {\n <!-- The row's link: one real anchor, stretched over the row box (see rowBox) rather than\n wrapping any content, so the cells stay exactly as a table without links renders them.\n It carries no text of its own and is named by the identity cell instead - `aria-labelledby`\n resolves to that cell's content, which is the row's identity.\n\n A child of the row, not of a cell: a cell that is pinned is `position: sticky` and would\n therefore be the anchor's containing block, shrinking the row's hit area to that one\n column. The row box is the containing block that spans every cell. -->\n <a\n [attr.href]=\"rowVm.href\"\n [attr.aria-labelledby]=\"rowVm.linkLabelId\"\n (click)=\"activateRowLink(rowVm.link, $event)\"\n class=\"et-table-row-link\"\n ></a>\n }\n\n @if (cardRows()) {\n <div class=\"et-table-card-corners\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n </div>\n\n <!-- The detail row of an expanded row, from etTableRowExpansion \u2014 the whole row, its chrome and\n its animation belong to the feature, so a table that never expands carries none of them. -->\n @if (rowVm.detail; as detail) {\n <ng-container *ngComponentOutlet=\"detail.component; inputs: { row: rowVm.row }; injector: detail.injector\" />\n }\n } @empty {\n <div class=\"et-table-message-row\" role=\"row\">\n <div [attr.role]=\"cellRole()\" class=\"et-table-empty-cell\">\n @if (emptyTemplate(); as template) {\n <ng-container *ngTemplateOutlet=\"template; context: { $implicit: rows() }\" />\n } @else {\n <ng-content select=\"[etTableEmpty]\">{{ resolvedLabels().empty }}</ng-content>\n }\n </div>\n </div>\n }\n }\n\n @if (spacers(); as spacer) {\n <div [style.block-size.px]=\"spacer.end\" class=\"et-table-spacer\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n\n <!-- Edge gradients marking rows scrolled out of view horizontally, on the edges no pinned column\n already marks (see visibleScrollFades). The layer is absolutely positioned over the whole grid \u2014\n the full scroll extent, not just the viewport \u2014 which is what lets the two fades inside it hold\n their place with `position: sticky` for the entire scroll range. -->\n <div class=\"et-table-scroll-fades\" role=\"presentation\" aria-hidden=\"true\">\n <div\n [style.inset-inline-start.px]=\"fadeInset().start\"\n [class.et-table-scroll-fade--visible]=\"visibleScrollFades().start\"\n class=\"et-table-scroll-fade et-table-scroll-fade--start\"\n ></div>\n <div\n [style.inset-inline-end.px]=\"fadeInset().end\"\n [class.et-table-scroll-fade--visible]=\"visibleScrollFades().end\"\n class=\"et-table-scroll-fade et-table-scroll-fade--end\"\n ></div>\n </div>\n\n @if (hasFooter()) {\n <div [attr.aria-rowindex]=\"ariaRowCount()\" class=\"et-table-footer-row\" role=\"row\">\n @for (lead of leadCells(); track lead.key) {\n <div\n [class]=\"lead.cellClass\"\n [class.et-table-sticky-start]=\"lead.sticky\"\n [style.inset-inline-start.px]=\"lead.offset\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-footer-cell\"\n aria-hidden=\"true\"\n ></div>\n }\n @for (cell of footerCells(); track cell.key) {\n <div\n [attr.data-align]=\"cell.align\"\n [class.et-table-sticky-start]=\"cell.stickyStart\"\n [class.et-table-sticky-end]=\"cell.stickyEnd\"\n [style.inset-inline-start.px]=\"cell.offsetStart\"\n [style.inset-inline-end.px]=\"cell.offsetEnd\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-footer-cell\"\n >\n @if (cell.template; as footerTemplate) {\n <ng-container *ngTemplateOutlet=\"footerTemplate; context: { $implicit: rows() }\" />\n }\n </div>\n }\n @if (hasFiller()) {\n <div class=\"et-table-footer-cell et-table-filler-cell\" role=\"presentation\" aria-hidden=\"true\"></div>\n }\n @for (trail of trailCells(); track trail.key) {\n <div\n [class]=\"trail.cellClass\"\n [class.et-table-sticky-end]=\"trail.sticky\"\n [style.inset-inline-end.px]=\"trail.offset\"\n [attr.role]=\"cellRole()\"\n class=\"et-table-footer-cell\"\n aria-hidden=\"true\"\n ></div>\n }\n </div>\n }\n</ng-template>\n\n@if (pageStickyHeader()) {\n <div class=\"et-table-header-strip\" role=\"presentation\">\n <div\n #headerGrid\n [style.grid-template-columns]=\"pageHeaderColumns()\"\n class=\"et-table et-table-header\"\n role=\"rowgroup\"\n >\n <ng-container *ngTemplateOutlet=\"headerContent\" />\n </div>\n </div>\n <div #scroller (scroll)=\"syncScrollState()\" class=\"et-table-scroller\" role=\"presentation\">\n <div #grid [style.grid-template-columns]=\"templateColumns()\" class=\"et-table\" role=\"rowgroup\">\n <ng-container *ngTemplateOutlet=\"bodyContent\" />\n </div>\n </div>\n} @else {\n <div\n #grid\n [style.grid-template-columns]=\"templateColumns()\"\n [attr.role]=\"tableRole()\"\n [attr.aria-rowcount]=\"ariaRowCount()\"\n class=\"et-table\"\n >\n <ng-container *ngTemplateOutlet=\"headerContent\" />\n <ng-container *ngTemplateOutlet=\"bodyContent\" />\n </div>\n}\n\n<!-- Full-width footer slot (paginator, page-size, etc.), pinned to the bottom of the scroll viewport.\n Rendered only when the consumer projects `[etTableFooter]`, so the chrome never shows empty. -->\n@if (footerSlot()) {\n <div class=\"et-table-footer\">\n <ng-content select=\"[etTableFooter]\" />\n </div>\n}\n\n<!-- Floating UI from opt-in features (the reorder drag ghost / drop indicator), stamped here so a\n feature can draw without having a view \u2014 or an element \u2014 of its own. -->\n@for (layer of layers(); track $index) {\n <ng-container *ngComponentOutlet=\"layer.component; injector: layer.injector\" />\n}\n", styles: ["@layer components{@property --et-table-cell-padding-block{syntax: \"<length>\"; inherits: true; initial-value: 10px;}@property --et-table-cell-padding-inline{syntax: \"<length>\"; inherits: true; initial-value: 12px;}@property --et-table-opacity-disabled{syntax: \"<number>\"; inherits: true; initial-value: .4;}:where(.et-table-host){display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:1fr auto;overflow:auto;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--et-surface-interaction-solid, gray) 35%,transparent) transparent;--_et-table-band: color-mix( in srgb, var(--et-surface-interaction-solid, gray) 7%, var(--et-surface-background-solid, Canvas) );--_et-table-header-bg: var(--et-table-header-background-color, var(--et-surface-background-solid, Canvas));--_et-table-header-border: var(--et-surface-border-solid, rgb(128 128 128 / .3));--_et-table-row-divider: transparent;--_et-table-header-adornment-size: 2.4rem;--_et-table-row-surface: var(--et-surface-background-solid, Canvas);--_et-table-stripe-bg: transparent;--_et-table-stripe-solid: var(--_et-table-row-surface);--_et-table-hover-tint: color-mix(in srgb, var(--et-surface-interaction-solid, gray) 8%, transparent);--_et-table-hover-tint-solid: color-mix( in srgb, var(--et-surface-interaction-solid, gray) 8%, var(--_et-table-row-surface) );--_et-table-row-hover: var(--_et-table-hover-tint);--_et-table-row-hover-solid: var(--_et-table-hover-tint-solid);--_et-table-pressed-tint: color-mix(in srgb, var(--et-surface-interaction-solid, gray) 16%, transparent);--_et-table-pressed-tint-solid: color-mix( in srgb, var(--et-surface-interaction-solid, gray) 16%, var(--_et-table-row-surface) );--_et-table-row-pressed: var(--_et-table-pressed-tint);--_et-table-row-pressed-solid: var(--_et-table-pressed-tint-solid);--_et-table-inert-row-hover: var(--_et-table-hover-tint);--_et-table-inert-row-hover-solid: var(--_et-table-hover-tint-solid);--_et-table-row-gap-block: 0px;--_et-table-row-paint: transparent;--_et-table-row-corner: 0px;--_et-table-header-gap-block: 0px;--_et-table-cell-rule: 0;--_et-table-sticky-clip: none;--_et-table-busy-margin-block-start: 0px;--_et-table-busy-margin-block-end: -2px;--_et-table-detail-rule: 1px solid var(--et-surface-border-solid, rgb(128 128 128 / .15));--_et-table-card-outside: var(--et-surface-background-solid, Canvas);--_et-table-pin-shadow: var( --et-table-pin-shadow-color, color-mix(in srgb, var(--et-surface-interaction-solid, black) 30%, transparent) );--_et-table-pin-shadow-inline: var(--et-table-pin-shadow-color-inline, var(--_et-table-pin-shadow));--_et-table-pin-shadow-block: var(--et-table-pin-shadow-color-block, var(--_et-table-pin-shadow));--_et-table-edge-none: 0 0 transparent;--_et-table-edge-start: var(--_et-table-edge-none);--_et-table-edge-end: var(--_et-table-edge-none);--_et-table-edge-block-start: var(--_et-table-edge-none);--_et-table-edge-block-end: var(--_et-table-edge-none)}.et-table-host--scrolled-inline-start{--_et-table-edge-start: 8px 0 10px -6px var(--_et-table-pin-shadow-inline)}.et-table-host--scrolled-inline-end{--_et-table-edge-end: -8px 0 10px -6px var(--_et-table-pin-shadow-inline)}.et-table-host--scrolled-block-start{--_et-table-edge-block-start: 0 8px 10px -6px var(--_et-table-pin-shadow-block)}.et-table-host--scrolled-block-end{--_et-table-edge-block-end: 0 -8px 10px -6px var(--_et-table-pin-shadow-block)}.et-table-host:where([data-density=sm]){--et-table-cell-padding-block: 6px;--et-table-cell-padding-inline: 10px}.et-table-host:where([data-density=md]){--et-table-cell-padding-block: 10px;--et-table-cell-padding-inline: 12px}.et-table-host:where([data-density=lg]){--et-table-cell-padding-block: 15px;--et-table-cell-padding-inline: 16px}.et-table-host:where([data-appearance=enclosed],[data-appearance=zebra],[data-appearance=grid]){border:1px solid var(--et-surface-border-solid, rgb(128 128 128 / .3));border-radius:var(--et-table-radius, 10px)}.et-table-host:where([data-appearance=enclosed]){--_et-table-header-bg: var(--et-table-header-background-color, var(--_et-table-band));--_et-table-row-divider: var(--et-surface-border-solid, rgb(128 128 128 / .15));box-shadow:0 1px 2px rgb(var(--et-shadow-color-rgb, 0 0 0) / .04),0 6px 16px rgb(var(--et-shadow-color-rgb, 0 0 0) / .06)}.et-table-host:where([data-appearance=divided]){--_et-table-row-divider: var(--et-surface-border-solid, rgb(128 128 128 / .15))}.et-table-host:where([data-appearance=zebra]){--_et-table-header-bg: var(--et-table-header-background-color, var(--_et-table-band));--_et-table-stripe-bg: color-mix(in srgb, var(--et-surface-interaction-solid, gray) 4%, transparent);--_et-table-stripe-solid: color-mix( in srgb, var(--et-surface-interaction-solid, gray) 4%, var(--_et-table-row-surface) )}.et-table-host:where([data-appearance=grid]){--_et-table-cell-rule: 1px solid var(--et-surface-border-solid, rgb(128 128 128 / .15));--_et-table-header-bg: var(--et-table-header-background-color, var(--_et-table-band));--_et-table-row-divider: var(--et-surface-border-solid, rgb(128 128 128 / .15))}.et-table-host:where([data-appearance=bare]){--_et-table-header-border: transparent}.et-table-host:where([data-appearance=cards]){--_et-table-row-gap-block: var(--et-table-row-gap, 8px);--_et-table-row-corner: var(--et-table-row-radius, 10px);--_et-table-header-gap-block: var(--et-table-row-gap, 8px);--_et-table-sticky-clip: inset(0 -24px);--_et-table-busy-margin-block-start: calc((var(--et-table-row-gap, 8px) + 2px) / -2);--_et-table-busy-margin-block-end: calc((var(--et-table-row-gap, 8px) - 2px) / 2);--_et-table-detail-rule: 0;--_et-table-inert-row-hover: transparent;--_et-table-header-bg: var(--et-table-header-background-color, var(--et-surface-background-solid, Canvas));--_et-table-row-divider: transparent}.et-table{display:grid;position:relative;align-content:start;inline-size:min-content;min-inline-size:100%;background:var(--et-surface-background-solid, Canvas);color:var(--et-surface-color-solid, CanvasText);font-size:14px;line-height:1.4}.et-table-header-cell.et-table-filler-cell,.et-table-cell.et-table-filler-cell,.et-table-footer-cell.et-table-filler-cell,.et-table-group-cell.et-table-filler-cell{padding-inline:0}.et-table-header-row,.et-table-row{display:contents}.et-table-header-cell,.et-table-cell{display:flex;align-items:center;min-inline-size:0;overflow:hidden;padding:var(--et-table-cell-padding-block) var(--et-table-cell-padding-inline)}.et-table-cell-text{min-inline-size:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.et-table-header-cell{position:sticky;inset-block-start:max(0px,calc(var(--_et-table-group-h, 0px) - 1px));gap:4px;z-index:1;font-weight:600;color:var(--et-table-header-color, var(--et-surface-color-muted-solid, CanvasText));background:var(--_et-table-header-bg);border-block-end:1px solid var(--_et-table-header-border)}.et-table-header-adornments{display:flex;align-items:center;flex:none}.et-table-header-cell .et-table-filter-trigger,.et-table-header-cell .et-table-column-menu-trigger{--et-icon-button-size: var(--_et-table-header-adornment-size);--et-icon-button-icon-size: 1.6rem;min-width:24px;min-height:24px}.et-table-host--header-adornments .et-table-header-cell{min-block-size:calc(max(var(--_et-table-header-adornment-size),24px) + 2 * var(--et-table-cell-padding-block) + 1px)}.et-table-cell{min-block-size:var(--et-table-row-min-block-size, auto);border-block-end:1px solid var(--_et-table-row-divider)}.et-table-header-cell{box-shadow:var(--_et-table-edge-block-start)}.et-table-footer,.et-table-footer-cell{box-shadow:var(--_et-table-edge-block-end)}.et-table-row--last:not(:has(+.et-table-detail-row)) .et-table-cell{border-block-end:0}.et-table-row--stripe .et-table-cell{background:var(--_et-table-stripe-bg)}.et-table-header-cell,.et-table-cell{border-inline-end:var(--_et-table-cell-rule)}.et-table-header-row .et-table-header-cell:last-child,.et-table-row .et-table-cell:nth-last-child(1 of.et-table-cell){border-inline-end:0}.et-table-footer-row{display:contents}.et-table-footer-cell{display:flex;align-items:center;min-inline-size:0;overflow:hidden;padding:var(--et-table-cell-padding-block) var(--et-table-cell-padding-inline);position:sticky;inset-block-end:0;z-index:1;font-weight:600;background:var(--_et-table-header-bg);border-block-start:1px solid var(--et-surface-border-solid, rgb(128 128 128 / .3))}.et-table-footer-cell:where([data-align=center]){justify-content:center;text-align:center}.et-table-footer-cell:where([data-align=end]){justify-content:flex-end;text-align:end}.et-table-scroll-fades{position:absolute;inset:0;display:flex;justify-content:space-between;z-index:3;pointer-events:none}.et-table-scroll-fade{position:sticky;flex:none;inline-size:var(--et-table-scroll-fade-size, 28px);opacity:0;transition:opacity .15s ease;--_et-table-scroll-fade-color: var( --et-table-scroll-fade-color, color-mix(in srgb, var(--et-surface-interaction-solid, black) 22%, transparent) )}.et-table-scroll-fade--visible{opacity:1}.et-table-scroll-fade--start{background:linear-gradient(to right,var(--_et-table-scroll-fade-color),transparent)}.et-table-scroll-fade--end{background:linear-gradient(to left,var(--_et-table-scroll-fade-color),transparent)}@media(prefers-reduced-motion:reduce){.et-table-scroll-fade{transition:none}}.et-table-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;position:sticky;inset-block-end:0;inset-inline-start:0;z-index:4;padding:var(--et-table-cell-padding-block) var(--et-table-cell-padding-inline);background:var(--_et-table-header-bg);border-block-start:1px solid var(--et-surface-border-solid, rgb(128 128 128 / .3))}.et-table-footer-label{margin:0;font-size:14px;color:var(--et-surface-color-muted-solid, CanvasText)}@media(pointer:coarse){.et-table-footer{gap:8px;padding:8px var(--et-table-cell-padding-inline)}}.et-table-header-cell:where([data-align=center]),.et-table-cell:where([data-align=center]){justify-content:center;text-align:center}.et-table-header-cell:where([data-align=end]),.et-table-cell:where([data-align=end]){justify-content:flex-end;text-align:end}.et-table-row--interactive .et-table-cell{cursor:pointer}@media(hover:hover){.et-table-row:hover .et-table-cell{background:var(--_et-table-row-hover)}}.et-table-row:where(.et-table-row--interactive,.et-table-row--link):active .et-table-cell{background:var(--_et-table-row-pressed)}.et-table-header-label:focus-visible,.et-table-expander:focus-visible,.et-table-cell:focus-visible{outline:2px solid var(--et-theme-color-primary-solid, currentColor);outline-offset:-2px}.et-table-header-label{border-radius:4px}.et-table-header-label{display:flex;align-items:center;flex:1;min-inline-size:0;margin:0;padding:0;font:inherit;color:inherit;text-align:inherit;background:none;border:none}.et-table-header-label-box{display:flex;align-items:center;gap:4px;min-inline-size:0;padding:4px;margin:-4px;border-radius:4px}.et-table-header-label:where(.et-table-header-label--sortable){cursor:pointer}.et-table-header-label--sortable .et-table-header-label-box{background-color:var(--_et-table-header-label-tint, transparent);transition:background-color .12s var(--ease-out-5, ease)}@media(hover:hover){.et-table-header-label--sortable:hover:not(:disabled){--_et-table-header-label-tint: var(--_et-table-hover-tint)}}.et-table-header-label--sortable:active:not(:disabled){--_et-table-header-label-tint: var(--_et-table-pressed-tint)}.et-table-header-cell:where([data-disabled]) .et-table-header-label{opacity:var(--et-table-opacity-disabled)}.et-table-header-label:where(.et-table-header-label--sortable:disabled){cursor:not-allowed}.et-table-header-cell:where([data-align=center]) .et-table-header-label{justify-content:center}.et-table-header-cell:where([data-align=end]) .et-table-header-label{justify-content:flex-end}.et-table-sort-indicator{flex:none;inline-size:1.15em;block-size:1.15em;transform:translateY(-.045em);color:var(--et-theme-color-primary-solid, currentColor);transition:transform .2s var(--ease-out-5, ease)}.et-table-sort-indicator:where([data-direction=desc]){transform:translateY(-.045em) rotate(180deg)}.et-table-sort-indicator.et-table-sort-indicator--enter{animation:et-table-sort-in .15s ease}.et-table-sort-indicator.et-table-sort-indicator--leave{animation:et-table-sort-in .12s ease reverse forwards}@keyframes et-table-sort-in{0%{opacity:0}to{opacity:1}}@media(prefers-reduced-motion:reduce){.et-table-sort-indicator{transition:none}.et-table-sort-indicator.et-table-sort-indicator--enter,.et-table-sort-indicator.et-table-sort-indicator--leave{animation:none}}.et-table-message-row{display:contents}.et-table-empty-cell,.et-table-error-cell{grid-column:1 / -1;position:sticky;inset-inline-start:0;inline-size:var(--_et-table-viewport-inline-size, 100%);padding:32px var(--et-table-cell-padding-inline);color:var(--et-surface-color-muted-solid, CanvasText);text-align:center}.et-table-empty-cell{display:grid;place-content:center;justify-items:center}.et-table-error-cell{display:flex;flex-wrap:wrap;align-items:center;align-content:center;justify-content:center;gap:8px}.et-table-error-icon{flex:none;inline-size:16px;block-size:16px;color:var(--et-theme-color-ink-solid, currentColor)}.et-table-cell:where([data-state=error]){gap:6px}.et-table-cell-error-icon{flex:none;inline-size:14px;block-size:14px;color:var(--et-theme-color-ink-solid, currentColor)}.et-table-cell:where([data-state=loading]){display:flex}.et-table-busy-bar{grid-column:1 / -1;block-size:2px;margin-block-start:var(--_et-table-busy-margin-block-start);margin-block-end:var(--_et-table-busy-margin-block-end);overflow:hidden;background:color-mix(in srgb,var(--et-surface-interaction-solid, gray) 10%,transparent)}.et-table-busy-bar.et-table-busy-bar--enter{animation:et-table-busy-fade .15s ease}.et-table-busy-bar.et-table-busy-bar--leave{animation:et-table-busy-fade .25s ease reverse forwards}@keyframes et-table-busy-fade{0%{opacity:0}to{opacity:1}}.et-table-busy-bar:after{content:\"\";display:block;inline-size:40%;block-size:100%;border-radius:999px;background:var(--et-theme-color-primary-solid, currentColor);animation:et-table-busy-sweep 1.1s ease-in-out infinite}@keyframes et-table-busy-sweep{0%{transform:translate(-100%)}to{transform:translate(250%)}}@media(prefers-reduced-motion:reduce){.et-table-busy-bar:after{inline-size:100%;animation:none}.et-table-busy-bar.et-table-busy-bar--enter,.et-table-busy-bar.et-table-busy-bar--leave{animation:none}}}\n"] }]
70143
70594
  }], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], rowsSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowsSource", required: false }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], rowKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowKey", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], emptyTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyTemplate", required: false }] }], errorTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorTemplate", required: false }] }], cellState: [{ type: i0.Input, args: [{ isSignal: true, alias: "cellState", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], sort: [{ type: i0.Input, args: [{ isSignal: true, alias: "sort", required: false }] }, { type: i0.Output, args: ["sortChange"] }], multiSort: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiSort", required: false }] }], sortMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortMode", required: false }] }], filters: [{ type: i0.Input, args: [{ isSignal: true, alias: "filters", required: false }] }, { type: i0.Output, args: ["filtersChange"] }], filterMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterMode", required: false }] }], quickFilter: [{ type: i0.Input, args: [{ isSignal: true, alias: "quickFilter", required: false }] }], expandedRowTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedRowTemplate", required: false }] }], rowInteractive: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowInteractive", required: false }] }], rowLink: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowLink", required: false }] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], footerSlot: [{ type: i0.ContentChild, args: [i0.forwardRef(() => TableFooterDirective), { isSignal: true }] }], gridRef: [{ type: i0.ViewChild, args: ['grid', { isSignal: true }] }], headerGridRef: [{ type: i0.ViewChild, args: ['headerGrid', { isSignal: true }] }], scrollerRef: [{ type: i0.ViewChild, args: ['scroller', { isSignal: true }] }], headerCells: [{ type: i0.ViewChildren, args: ['headerCell', { isSignal: true }] }], bodyCells: [{ type: i0.ViewChildren, args: ['bodyCell', { isSignal: true }] }], gridCells: [{ type: i0.ViewChildren, args: ['gridCell', { isSignal: true }] }], leadHeaderCells: [{ type: i0.ViewChildren, args: ['leadHeaderCell', { isSignal: true }] }], trailHeaderCells: [{ type: i0.ViewChildren, args: ['trailHeaderCell', { isSignal: true }] }] } });
70144
70595
 
70145
70596
  /**
@@ -70595,6 +71046,9 @@ class TableColumnMenuDirective {
70595
71046
  return (this.config().hideColumn ?? true) && this.table.visibleColumnsMeta().length > 1;
70596
71047
  }
70597
71048
  hide(column) {
71049
+ this.table.setSort(column.key, null);
71050
+ if (this.table.filterValuesFor(column.key).length)
71051
+ this.table.setFilterValues(column.key, []);
70598
71052
  this.table.setColumnVisible(column.key, false);
70599
71053
  }
70600
71054
  canPin() {
@@ -71216,9 +71670,16 @@ class TableRowDetailComponent {
71216
71670
  ...(ngDevMode ? [{ debugName: "row" }] : /* istanbul ignore next */ []));
71217
71671
  this.animated = computed(() => this.expansion.animates(this.row()), /* @ts-ignore */
71218
71672
  ...(ngDevMode ? [{ debugName: "animated" }] : /* istanbul ignore next */ []));
71673
+ this.dimensions = signalHostElementDimensions();
71674
+ effect(() => {
71675
+ const height = this.dimensions().offset?.height;
71676
+ const row = this.row();
71677
+ if (height !== undefined)
71678
+ untracked(() => this.table.setDetailRowHeight(row, height));
71679
+ });
71219
71680
  }
71220
71681
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TableRowDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
71221
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: TableRowDetailComponent, isStandalone: true, selector: "et-table-row-detail", inputs: { row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null } }, host: { attributes: { "role": "row" }, properties: { "animate.enter": "animated() ? 'et-table-detail--enter' : ''", "animate.leave": "animated() ? 'et-table-detail--leave' : ''" }, classAttribute: "et-table-detail-row" }, ngImport: i0, template: `
71682
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: TableRowDetailComponent, isStandalone: true, selector: "et-table-row-detail", inputs: { row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: true, transformFunction: null } }, host: { attributes: { "role": "row" }, properties: { "attr.aria-rowindex": "table.detailAriaRowIndex(row())", "animate.enter": "animated() ? 'et-table-detail--enter' : ''", "animate.leave": "animated() ? 'et-table-detail--leave' : ''" }, classAttribute: "et-table-detail-row" }, ngImport: i0, template: `
71222
71683
  <!-- The clip window the animating track squeezes to nothing, and the body that carries the padding.
71223
71684
  Two elements on purpose - see table-detail-styles.component.css. -->
71224
71685
  <div [attr.role]="table.cellRole()" class="et-table-detail-cell">
@@ -71246,13 +71707,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
71246
71707
  host: {
71247
71708
  class: 'et-table-detail-row',
71248
71709
  role: 'row',
71710
+ '[attr.aria-rowindex]': 'table.detailAriaRowIndex(row())',
71249
71711
  // Animated only for the row the user just toggled - a re-mount from paging/sorting must not replay
71250
71712
  // the reveal (see TableRowExpansionDirective.animates).
71251
71713
  '[animate.enter]': "animated() ? 'et-table-detail--enter' : ''",
71252
71714
  '[animate.leave]': "animated() ? 'et-table-detail--leave' : ''",
71253
71715
  },
71254
71716
  }]
71255
- }], propDecorators: { row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: true }] }] } });
71717
+ }], ctorParameters: () => [], propDecorators: { row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: true }] }] } });
71256
71718
 
71257
71719
  /** Covers the 0.18s detail-row enter/leave animations in the CSS - see {@link TableRowExpansionDirective.animates}. */
71258
71720
  const DETAIL_ANIMATION_MS = 200;
@@ -73537,6 +73999,7 @@ class TableVirtualScrollDirective {
73537
73999
  itemCount: computed(() => this.table.rows().length),
73538
74000
  estimateItemHeight: computed(() => this.config().estimateRowHeight ?? 48),
73539
74001
  overscan: computed(() => this.config().overscan ?? 6),
74002
+ extraItemHeights: computed(() => this.table.detailRowHeights()),
73540
74003
  });
73541
74004
  injectStyleManager().mount(TableVirtualScrollStylesComponent);
73542
74005
  this.table.registerRowWindow({
@@ -74452,9 +74915,17 @@ class TabGroupDirective {
74452
74915
  this.sessionMemoryKey = input(null, /* @ts-ignore */
74453
74916
  ...(ngDevMode ? [{ debugName: "sessionMemoryKey" }] : /* istanbul ignore next */ []));
74454
74917
  this.sessionMemoryAvailable = canUseSessionMemory();
74455
- /** @internal */
74456
- this.panels = signal([], /* @ts-ignore */
74457
- ...(ngDevMode ? [{ debugName: "panels" }] : /* istanbul ignore next */ []));
74918
+ this.registeredPanels = signal([], /* @ts-ignore */
74919
+ ...(ngDevMode ? [{ debugName: "registeredPanels" }] : /* istanbul ignore next */ []));
74920
+ this.childMutations = signalElementMutations(inject(ElementRef), {
74921
+ childList: true,
74922
+ subtree: true,
74923
+ });
74924
+ /** @internal The panels in DOM order, which a keyed `@for` can change without re-registering any. */
74925
+ this.panels = computed(() => {
74926
+ this.childMutations();
74927
+ return sortByDomOrder(this.registeredPanels(), (panel) => panel.hostElement);
74928
+ }, { ...(ngDevMode ? { debugName: "panels" } : /* istanbul ignore next */ {}), equal: isSameOrder$1 });
74458
74929
  /** @internal Set by composing components (e.g. et-tab-group) that render panel content themselves instead of registering [etTabPanel] directives. */
74459
74930
  this.managesPanelsInternally = signal(false, /* @ts-ignore */
74460
74931
  ...(ngDevMode ? [{ debugName: "managesPanelsInternally" }] : /* istanbul ignore next */ []));
@@ -74537,18 +75008,19 @@ class TabGroupDirective {
74537
75008
  }
74538
75009
  /** @internal */
74539
75010
  registerPanel(panel) {
74540
- this.panels.update((list) => [...list, panel]);
75011
+ this.registeredPanels.update((list) => [...list, panel]);
74541
75012
  }
74542
75013
  /** @internal */
74543
75014
  unregisterPanel(panel) {
74544
- this.panels.update((list) => list.filter((p) => p !== panel));
75015
+ this.registeredPanels.update((list) => list.filter((p) => p !== panel));
74545
75016
  }
74546
75017
  resolveSelectedIndex(index) {
74547
75018
  const triggers = this.tabBar.triggers();
74548
75019
  if (triggers.length === 0) {
74549
75020
  return null;
74550
75021
  }
74551
- const clampedIndex = Math.min(Math.max(index, 0), triggers.length - 1);
75022
+ const wholeIndex = Number.isFinite(index) ? Math.trunc(index) : 0;
75023
+ const clampedIndex = Math.min(Math.max(wholeIndex, 0), triggers.length - 1);
74552
75024
  const selectedTrigger = triggers[clampedIndex];
74553
75025
  if (selectedTrigger && !selectedTrigger.disabled()) {
74554
75026
  return clampedIndex;
@@ -74595,6 +75067,7 @@ let nextPanelId = 0;
74595
75067
  class TabPanelDirective {
74596
75068
  constructor() {
74597
75069
  this.tabGroup = inject(TAB_GROUP_TOKEN, { optional: true });
75070
+ /** @internal */
74598
75071
  this.hostElement = injectHostElement();
74599
75072
  this.triggerId = input(null, /* @ts-ignore */
74600
75073
  ...(ngDevMode ? [{ debugName: "triggerId" }] : /* istanbul ignore next */ []));
@@ -75919,11 +76392,11 @@ const provideUnsavedChangesAlertDialog = () => provideUnsavedChangesConfirm(() =
75919
76392
 
75920
76393
  // Generated from package.json by tools/scripts/generate-version.js - do not edit.
75921
76394
  /** The version of `@ethlete/components` this build was cut from. */
75922
- const COMPONENTS_VERSION = '1.0.0-next.68';
76395
+ const COMPONENTS_VERSION = '1.0.0-next.69';
75923
76396
 
75924
76397
  /**
75925
76398
  * Generated bundle index. Do not edit.
75926
76399
  */
75927
76400
 
75928
- export { ACCESSIBLE_NAME_INPUTS, ACCORDION_ERROR_CODES, ACCORDION_GROUP_TOKEN, ACCORDION_IMPORTS, ACCORDION_TOKEN, ALERT_DIALOG_LABELS, ALIGN_CENTER_ICON, ALIGN_JUSTIFY_ICON, ALIGN_LEFT_ICON, ALIGN_RIGHT_ICON, ARROWS_LEFT_RIGHT_ICON, ARROW_OUT_UP_RIGHT_ICON, ARROW_RIGHT_ICON, ARROW_UP_ICON, AVATAR_IMPORTS, AVATAR_LABELS, AVATAR_SHAPES, AVATAR_SIZES, AccessibleNameControlDirective, AccordionComponent, AccordionContentDirective, AccordionDirective, AccordionGroupComponent, AccordionGroupDirective, AccordionHintDirective, AccordionLabelDirective, AccordionPanelDirective, AccordionTriggerDirective, AvatarComponent, AvatarGroupComponent, BADGE_ICON_ALIGNMENTS, BADGE_IMPORTS, BADGE_SIZES, BADGE_VARIANTS, BANNER_IMPORTS, BANNER_LABELS, BANNER_TYPES, BOLD_ICON, BRACKET_CARD_CONTEXT, BRACKET_DEFAULTS, BRACKET_DEFAULT_CARDS, BRACKET_DENSITY, BRACKET_DENSITY_PRESETS, BRACKET_IMPORTS, BRACKET_LABELS, BRACKET_PARTICIPANTS_IMPORTS, BRACKET_PICK_CARD_IMPORTS, BRACKET_PICK_CARD_NOTE_TONE, BRACKET_ROUNDS_LIST_IMPORTS, BRACKET_ROUND_HEADER_ALIGN, BRACKET_SKELETON_IMPORTS, BREADCRUMB_COLLAPSE_IMPORTS, BREADCRUMB_COLLAPSE_TOKEN, BREADCRUMB_ERROR_CODES, BREADCRUMB_IMPORTS, BREADCRUMB_LABELS, BREADCRUMB_SEGMENT_TOKEN, BREADCRUMB_SEO_IMPORTS, BREADCRUMB_TOKEN, BUTTON_ICON_ALIGNMENTS, BUTTON_IMPORTS, BUTTON_SIZES, BUTTON_SPINNER_CONFIG, BUTTON_TYPES, BUTTON_VARIANTS, BadgeComponent, BannerComponent, BarChartComponent, BarChartDirective, BarChartPlotDirective, BracketComponent, BracketDefaultContinueComponent, BracketDefaultFinalMatchComponent, BracketDefaultMatchComponent, BracketDefaultRoundHeaderComponent, BracketParticipantsComponent, BracketPickCardComponent, BracketRoundsListComponent, BracketSkeletonComponent, BracketSkeletonContinueComponent, BracketSkeletonFinalMatchComponent, BracketSkeletonMatchComponent, BracketSkeletonRoundHeaderComponent, BrandLoaderComponent, BreadcrumbCollapseDirective, BreadcrumbComponent, BreadcrumbDirective, BreadcrumbItemDirective, BreadcrumbItemTemplateDirective, BreadcrumbOutletComponent, BreadcrumbOverflowComponent, BreadcrumbSegmentDirective, BreadcrumbSeoDirective, BreadcrumbSeparatorDirective, ButtonColorDirective, ButtonComponent, ButtonDirective, ButtonStylesDirective, CALENDAR_ERROR_CODES, CALENDAR_ICON, CALENDAR_IMPORTS, CALENDAR_LABELS, CARD_IMPORTS, CARD_VARIANTS, CAROUSEL_AUTOPLAY_TOKEN, CAROUSEL_ERROR_CODES, CAROUSEL_IMPORTS, CAROUSEL_LABELS, CAROUSEL_SLIDE_ALIGNMENTS, CAROUSEL_TOKEN, CAROUSEL_TRANSITIONS, CAROUSEL_TRANSITION_DRIVERS, CASCADER_ERROR_CODES, CASCADER_IMPORTS, CASCADER_LABELS, CASCADER_SELECTABLE_LEVELS, CHART_ERROR_CODES, CHART_IMPORTS, CHART_LABELS, CHART_PLOT_HOST, CHECKBOX_GROUP_IMPORTS, CHECKBOX_IMPORTS, CHECKBOX_OPTION_VARIANTS, CHECK_ICON, CHEVRON_ICON, CHIP_ERROR_CODES, CHIP_IMPORTS, CHIP_LABELS, CHIP_REMOVE_FOCUS_FALLBACK, CHIP_REMOVE_TAB_STOP, CHOICE_FIELD_IMPORTS, CHOICE_FIELD_VARIANTS, CIRCLE_CHECK_ICON, CIRCLE_INFO_ICON, CLIPBOARD_CHECK_ICON, CLOCK_ICON, CODE_BLOCK_ICON, CODE_ICON, COLOR_INPUT_ERROR_CODES, COLOR_INPUT_IMPORTS, COLOR_INPUT_LABELS, COLOR_INPUT_TOKEN, COLOR_NOTATIONS, COLOR_NOTATION_ORDER, COMMAND_PALETTE_ERROR_CODES, COMMAND_PALETTE_IMPORTS, COMMAND_PALETTE_LABELS, COMMAND_PALETTE_OVERLAY, COMMAND_PALETTE_REGISTRY, COMMAND_PALETTE_TOKEN, COMPONENTS_VERSION, COPY_BUTTON_IMPORTS, COPY_BUTTON_LABELS, CalendarCellDirective, CalendarComponent, CalendarDirective, CalendarGridDirective, CalendarHeaderDirective, CardComponent, CarouselAutoplayDirective, CarouselComponent, CarouselDirective, CarouselItemDirective, CarouselNextDirective, CarouselPlayToggleDirective, CarouselPreviousDirective, CarouselSlideDirective, CascaderColumnDirective, CascaderComponent, CascaderDirective, CascaderNodeDirective, CascaderPanelComponent, CascaderSearchDirective, CascaderSearchOptionDirective, CascaderSurfaceDirective, CascaderTriggerDirective, ChartPlotDirective, CheckboxComponent, CheckboxDirective, CheckboxGroupComponent, CheckboxGroupSelectAllComponent, CheckboxOptionComponent, ChipComponent, ChipDirective, ChipRemoveDirective, ChoiceFieldComponent, ColorInputComponent, ColorInputDirective, ColorPickerAreaDirective, ColorPickerChannelDirective, ColorPickerPanelComponent, ColorPickerSurfaceDirective, ColorPickerTriggerDirective, CommandPaletteComponent, CommandPaletteDirective, CommandPaletteItemComponent, CommandPaletteSearchDirective, CommandPaletteShortcutDirective, ControlSuffixDirective, CopyButtonDirective, CounterComponent, DAILYMOTION_PLAYER_TOKEN, DATE_FORMAT, DATE_INPUT_ERROR_CODES, DATE_INPUT_IMPORTS, DATE_LOCALE, DATE_PICKER_HOST, DATE_RANGE_INPUT_ERROR_CODES, DATE_RANGE_INPUT_IMPORTS, DATE_TIME_FORMAT, DATE_TIME_INPUT_ERROR_CODES, DATE_TIME_INPUT_IMPORTS, DATE_TIME_LABELS, DATE_TIME_RANGE_INPUT_ERROR_CODES, DATE_TIME_RANGE_INPUT_IMPORTS, DEFAULT_ALERT_DIALOG_LABELS, DEFAULT_AVATAR_LABELS, DEFAULT_BANNER_LABELS, DEFAULT_BRACKET_LABELS, DEFAULT_BREADCRUMB_LABELS, DEFAULT_BREAKPOINTS, DEFAULT_CALENDAR_LABELS, DEFAULT_CALENDAR_RANGE_STRATEGY, DEFAULT_CAROUSEL_LABELS, DEFAULT_CASCADER_LABELS, DEFAULT_CHART_LABELS, DEFAULT_CHIP_LABELS, DEFAULT_COLOR_INPUT_LABELS, DEFAULT_COMMAND_PALETTE_LABELS, DEFAULT_COPY_BUTTON_LABELS, DEFAULT_DATE_TIME_LABELS, DEFAULT_DROPZONE_LABELS, DEFAULT_DROPZONE_MAX_PREVIEW_FILE_SIZE, DEFAULT_FILTER_OVERLAY_LABELS, DEFAULT_FORM_FIELD_DEFAULTS, DEFAULT_FORM_FIELD_LABELS, DEFAULT_GRID_LABELS, DEFAULT_ICON_VARIANT, DEFAULT_INPUT_LABELS, DEFAULT_KBD_LABELS, DEFAULT_LOADER_LABELS, DEFAULT_MATCH_CARD_START_TIME_FORMAT, DEFAULT_MATCH_LABELS, DEFAULT_NOTIFICATION_LABELS, DEFAULT_NOTIFICATION_MANAGER_CONFIG, DEFAULT_NOTIFICATION_STATUS_ICONS, DEFAULT_PAGINATION_LABELS, DEFAULT_PHONE_INPUT_LABELS, DEFAULT_PROGRESS_STEP_LABELS, DEFAULT_QUERY_ERROR_LABELS, DEFAULT_RICH_TEXT_EDITOR_LABELS, DEFAULT_RICH_TEXT_EDITOR_TOOLS, DEFAULT_SCHEDULER_LABELS, DEFAULT_SELECT_LABELS, DEFAULT_SLIDER_LABELS, DEFAULT_STANDINGS_LABELS, DEFAULT_STAT_TILE_LABELS, DEFAULT_STREAM_LABELS, DEFAULT_STREAM_PLAYER_STATE, DEFAULT_TABLE_LABELS, DEFAULT_TIME_PICKER_LABELS, DEFAULT_TREE_LABELS, DEFAULT_UNSAVED_CHANGES_LABELS, DESCRIPTION_IMPORTS, DESCRIPTION_LIST_IMPORTS, DESCRIPTION_LIST_VARIANTS, DIVIDER_IMPORTS, DROPZONE_ENTRY_STATUSES, DROPZONE_ERROR_CODES, DROPZONE_FILES_ERROR_KIND, DROPZONE_FILE_CONSTRAINTS, DROPZONE_FILE_REJECTION_REASONS, DROPZONE_IMPORTS, DROPZONE_LABELS, DURATION_INPUT_ERROR_CODES, DURATION_INPUT_IMPORTS, DailymotionPlayerComponent, DailymotionPlayerDirective, DailymotionPlayerParamsDirective, DailymotionPlayerSlotComponent, DateInputComponent, DateInputDirective, DateInputFieldDirective, DatePickerPanelComponent, DatePickerSurfaceDirective, DatePickerTriggerDirective, DateRangeInputComponent, DateRangeInputDirective, DateRangeInputFieldDirective, DateTimeInputComponent, DateTimeInputDirective, DateTimeInputFieldDirective, DateTimeRangeInputComponent, DateTimeRangeInputDirective, DateTimeRangeInputFieldDirective, DescriptionComponent, DescriptionListComponent, DividerComponent, DropzoneComponent, DropzoneDirective, DurationInputComponent, DurationInputDirective, DurationInputFieldDirective, ELLIPSIS_ICON, ELLIPSIS_VERTICAL_ICON, EMPTY_STATE_IMPORTS, ET_BUILT_IN_ICON_NAMES, EYEDROPPER_ICON, EYE_ICON, EYE_SLASH_ICON, EmptyStateComponent, FACEBOOK_PLAYER_TOKEN, FIELD_WARNINGS, FIELD_WARNING_KIND, FILE_ICON, FILTER_ICON, FILTER_OVERLAY_ERROR_CODES, FILTER_OVERLAY_IMPORTS, FILTER_OVERLAY_LABELS, FILTER_OVERLAY_TOKEN, FLOATING_ACTION_ERROR_CODES, FLOATING_ACTION_IMPORTS, FLOATING_ACTION_STATES, FLOATING_ACTION_TOKEN, FLOPPY_DISK_ICON, FOCUS_FRAME_ICON, FORM_ERROR_MESSAGE_RESOLVER, FORM_FIELD_APPEARANCES, FORM_FIELD_CONTROL_TYPES, FORM_FIELD_ERROR_CODES, FORM_FIELD_FILLS, FORM_FIELD_IMPORTS, FORM_FIELD_LABELS, FORM_FIELD_LABEL_MODES, FORM_FIELD_SIZES, FORM_FIELD_TOKEN, FORM_IMPORTS, FORM_WARNING_MESSAGE_RESOLVER, FabComponent, FacebookPlayerComponent, FacebookPlayerDirective, FacebookPlayerParamsDirective, FacebookPlayerSlotComponent, FilterOverlayResetDirective, FilterOverlaySubmitDirective, FloatingActionAnchorDirective, FloatingActionDirective, FloatingActionScopeDirective, FloatingActionTopDirective, FloatingActionTriggerDirective, FocusRingDirective, FormDirective, FormErrorComponent, FormFieldBarrierDirective, FormFieldComponent, FormFieldDirective, FormWarningComponent, GERMAN_COMMAND_PALETTE_LABELS, GERMAN_FILTER_OVERLAY_LABELS, GERMAN_QUERY_ERROR_LABELS, GRID_2X2_ICON, GRID_DEBUG_IMPORTS, GRID_ERROR_CODES, GRID_IMPORTS, GRID_LABELS, GRID_TOKEN, GridComponent, GridDebugComponent, GridDirective, GridDragDirective, GridItemComponent, GridItemDefaultActionsComponent, GridItemDirective, GridItemToolbarComponent, GridResizeDirective, HEADING_1_ICON, HEADING_2_ICON, HEADING_3_ICON, HintComponent, ICONS_TOKEN, ICON_DIRECTIVE_TOKEN, ICON_ERROR_CODES, ICON_IMPORTS, ICON_OVERRIDES_TOKEN, IMAGE_ICON, INHERIT_COLOR, INITIAL_SUPPORT_PRESENTATION_STATE, INPUT_IMPORTS, INPUT_LABELS, INPUT_MASK_HOST, INPUT_TEXT_ALIGNMENTS, INPUT_TYPES, INTERACTIVE_TAGS$1 as INTERACTIVE_TAGS, ITALIC_ICON, IconButtonComponent, IconDirective, InputComponent, InputDirective, InputMaskDirective, InputPrefixDirective, InputSuffixDirective, KBD_IMPORTS, KBD_LABELS, KBD_PLATFORM, KICK_PLAYER_TOKEN, KbdComponent, KickPlayerComponent, KickPlayerDirective, KickPlayerParamsDirective, KickPlayerSlotComponent, LINE_CHART_ERROR_CODES, LINK_ICON, LIST_BULLETED_ICON, LIST_NUMBERED_ICON, LOADER_IMPORTS, LOADER_LABELS, LOCATION_ICON, LOCK_ICON, LabelDirective, LineChartComponent, LineChartDirective, LineChartSliceDirective, MASKED_INPUT_ERROR_CODES, MASKED_INPUT_IMPORTS, MASK_VALUE_MODES, MASONRY_ERROR_CODES, MASONRY_IMPORTS, MASONRY_TOKEN, MATCH_CARD_IMPORTS, MATCH_CARD_SIZES, MATCH_CARD_TOKEN, MATCH_ERROR_CODES, MATCH_LABELS, MATCH_PARTICIPANT_IMPORTS, MENU_ERROR_CODES, MENU_IMPORTS, MENU_ITEM_VARIANTS, MENU_SEARCH_IMPORTS, MENU_SELECTION_GROUP_MULTIPLE, MENU_SELECTION_GROUP_TOKEN, MENU_SELECTION_ITEM_KIND, MINUS_ICON, MULTI_LANGUAGE_RICH_TEXT_EDITOR_ERROR_CODES, MULTI_LANGUAGE_RICH_TEXT_EDITOR_IMPORTS, MasonryDirective, MasonryItemDirective, MatchCardComponent, MatchCardDirective, MatchCardGameScoresDirective, MatchCardMetaDirective, MatchCardScoreDirective, MatchParticipantComponent, MatchScoreComponent, MenuCheckboxGroupComponent, MenuCheckboxItemComponent, MenuComponent, MenuContextTriggerDirective, MenuDirective, MenuGroupLabelComponent, MenuItemComponent, MenuItemDirective, MenuItemShortcutComponent, MenuItemSubmenuIconComponent, MenuPanelDirective, MenuRadioGroupComponent, MenuRadioItemComponent, MenuSearchDirective, MenuSelectionGroupDirective, MenuSelectionItemDirective, MenuSeparatorComponent, MenuSurfaceDirective, MenuTriggerDirective, MultiLanguageRichTextEditorComponent, MultiLanguageRichTextEditorDirective, MultiLanguageRichTextEditorLanguageToolComponent, NAV_TABS_TOKEN, NAV_TAB_IMPORTS, NOTIFICATION_ACTION_SLOTS, NOTIFICATION_ERROR_CODES, NOTIFICATION_IMPORTS, NOTIFICATION_LABELS, NOTIFICATION_STACK_CONTEXT_TOKEN, NOTIFICATION_STACK_OVERLAY_LAYER, NOTIFICATION_STATUS, NO_STREAM_PLAYER_CAPABILITIES, NUMBER_INPUT_IMPORTS, NavTabLinkComponent, NavTabLinkDirective, NavTabLinkStylesComponent, NavTabsComponent, NavTabsDirective, NavTabsOutletComponent, NavTabsOutletDirective, NotificationActionDirective, NotificationComponent, NotificationDirective, NotificationDismissDirective, NotificationItemDirective, NotificationStackDirective, NotificationSwipeToDismissDirective, NumberInputComponent, NumberInputDirective, OTP_INPUT_IMPORTS, OVERLAY_BACK_OR_CLOSE_TOKEN, OVERLAY_BODY_TOKEN, OVERLAY_CONFIG_CLASS_KEYS, OVERLAY_CONTENT_IMPORTS, OVERLAY_ERROR_CODES, OVERLAY_FOOTER_TOKEN, OVERLAY_HAS_BACKDROP, OVERLAY_HEADER_TEMPLATE_TOKEN, OVERLAY_HEADER_TOKEN, OVERLAY_IMPORTS, OVERLAY_MAIN_TOKEN, OVERLAY_NAV_TAB_IMPORTS, OVERLAY_QUERY_PARAM_INPUT_NAME, OVERLAY_REF, OVERLAY_ROUTER_CONFIG_TOKEN, OVERLAY_ROUTER_LINK_TOKEN, OVERLAY_ROUTER_OUTLET_DISABLED_TEMPLATE_TOKEN, OVERLAY_ROUTER_OUTLET_TOKEN, OVERLAY_ROUTER_TOKEN, OVERLAY_SHARED_ROUTE_TEMPLATE_TOKEN, OtpInputComponent, OtpInputDirective, OverlayAnchorDirective, OverlayBackOrCloseDirective, OverlayBodyComponent, OverlayCloseDirective, OverlayContainerComponent, OverlayDirective, OverlayFooterDirective, OverlayHeaderDirective, OverlayHeaderTemplateDirective, OverlayMainDirective, OverlayNavTabLinkComponent, OverlayOriginCloneComponent, OverlayRouteHeaderTemplateOutletComponent, OverlayRouterLinkDirective, OverlayRouterOutletComponent, OverlayRouterOutletDisabledTemplateDirective, OverlaySharedRouteTemplateDirective, OverlaySharedRouteTemplateOutletComponent, OverlaySidebarComponent, OverlaySidebarPageComponent, OverlaySurfaceDirective, OverlayTitleDirective, OverlayTriggerDirective, PAGE_SIZE_SELECT_IMPORTS, PAGINATION_IMPORTS, PAGINATION_LABELS, PAGINATION_SIZES, PARAGRAPH_ICON, PASSWORD_INPUT_IMPORTS, PAUSE_ICON, PENCIL_ICON, PHONE_COUNTRIES, PHONE_INPUT_ERROR_CODES, PHONE_INPUT_IMPORTS, PHONE_INPUT_LABELS, PICTURE_IMPORTS, PICTURE_STATES, PIE_CHART_ERROR_CODES, PIP_CHROME_REF_TOKEN, PIP_ENTRY_TOKEN, PIP_WINDOW_ASPECT_RATIO_TOKEN, PLAY_ICON, PLUS_ICON, PROGRESS_STEPS_IMPORTS, PROGRESS_STEPS_ORIENTATIONS, PROGRESS_STEP_LABELS, PROGRESS_STEP_STATES, PageSizeSelectComponent, PagedQueryTriggerDirective, PaginationComponent, PaginationDirective, PaginationSeoDirective, PasswordInputComponent, PasswordInputDirective, PhoneInputComponent, PhoneInputDirective, PhoneInputFieldDirective, PhoneInputFlagDirective, PictureComponent, PictureErrorDirective, PicturePlaceholderDirective, PieChartComponent, PieChartDirective, PipBackDirective, PipBringBackDirective, PipCellDirective, PipCloseDirective, PipCollapseOverlayDirective, PipGridToggleDirective, PipPlayerComponent, PipSlotPlaceholderComponent, PipStageDirective, PipTitleBarDirective, PipTitleBarTemplateDirective, PipWindowComponent, PipWindowParamsDirective, ProgressBarComponent, ProgressStepComponent, ProgressStepsComponent, QUERY_ERROR_ERROR_CODES, QUERY_ERROR_IMPORTS, QUERY_ERROR_LABELS, QUERY_ERROR_TOKEN, QUOTE_ICON, QueryButtonDirective, QueryErrorActionsDirective, QueryErrorComponent, QueryErrorDirective, QueryErrorTitleDirective, QueryParamOverlayLinkDirective, RADIO_GROUP_IMPORTS, RADIO_VARIANTS, RATING_ERROR_CODES, RATING_IMPORTS, REDO_ICON, RICH_TEXT_EDITOR_FLOATING_TOOLBAR, RICH_TEXT_EDITOR_HEADING_OPTIONS, RICH_TEXT_EDITOR_IMPORTS, RICH_TEXT_EDITOR_INLINE_TOOLS, RICH_TEXT_EDITOR_LABELS, RICH_TEXT_EDITOR_LANGUAGE_TOOL, RICH_TEXT_EDITOR_LINK_EDITOR, RICH_TEXT_EDITOR_TOKEN_CODEC, RICH_TEXT_EDITOR_TOKEN_PALETTE_IMPORTS, RICH_TEXT_EDITOR_TOOL, RICH_TEXT_EDITOR_TOOLS, RICH_TEXT_EDITOR_TOOL_BUTTONS, RICH_TEXT_EDITOR_TRIGGERS_IMPORTS, ROTATE_RIGHT_ICON, RadioComponent, RadioGroupComponent, RangeSliderComponent, RangeSliderDirective, RatingComponent, RatingDirective, RatingIconDirective, RichTextEditorAlignToolComponent, RichTextEditorComponent, RichTextEditorDirective, RichTextEditorFloatingToolbarComponent, RichTextEditorFloatingToolbarDirective, RichTextEditorHeadingToolComponent, RichTextEditorImageEditorComponent, RichTextEditorImageToolComponent, RichTextEditorLinkEditorComponent, RichTextEditorLinkEditorDirective, RichTextEditorTableToolComponent, RichTextEditorTokenPaletteComponent, RichTextEditorTokenPopupComponent, RichTextEditorTriggersDirective, RichTextViewerComponent, SANKEY_CHART_ERROR_CODES, SCHEDULER_EDIT_SURFACE_IMPORTS, SCHEDULER_ERROR_CODES, SCHEDULER_FEATURE_HOST, SCHEDULER_IMPORTS, SCHEDULER_LABELS, SCROLLABLE_DARKEN_IMPORTS, SCROLLABLE_DRAG_IMPORTS, SCROLLABLE_ERROR_CODES, SCROLLABLE_IMPORTS, SCROLLABLE_NAVIGATION_IMPORTS, SCROLLBAR_ERROR_CODES, SCROLLBAR_IMPORTS, SEGMENTED_BUTTON_GROUP_VARIANTS, SEGMENTED_BUTTON_IMPORTS, SELECTION_CARD_CONTROL_POSITIONS, SELECTION_LIST_ERROR_CODES, SELECTION_LIST_IMPORTS, SELECTION_LIST_MULTIPLE, SELECTION_LIST_TOKEN, SELECT_ERROR_CODES, SELECT_FILTER_MODES, SELECT_IMPORTS, SELECT_LABELS, SIDEBAR_OVERLAY_CONFIG, SIDEBAR_OVERLAY_TOKEN, SKELETON_IMPORTS, SLIDER_ERROR_CODES, SLIDER_IMPORTS, SLIDER_LABELS, SLIDER_MARK_VALUE_ATTRIBUTE, SLIDER_TOKEN, SOOP_PLAYER_TOKEN, SPLIT_BUTTON_ERROR_CODES, STANDINGS_ERROR_CODES, STANDINGS_IMPORTS, STANDINGS_LABELS, STANDINGS_PICK_IMPORTS, STAR_ICON, STAT_TILE_IMPORTS, STAT_TILE_LABELS, STREAM_ALL_IMPORTS, STREAM_CONSENT_TOKEN, STREAM_DAILYMOTION_IMPORTS, STREAM_DEFAULT_COMPONENTS, STREAM_ERROR_CODES, STREAM_FACEBOOK_IMPORTS, STREAM_IMPORTS, STREAM_KICK_IMPORTS, STREAM_LABELS, STREAM_PIP_IMPORTS, STREAM_PLAYER_COMPONENT_TOKEN, STREAM_PLAYER_ERROR_CONTEXT_TOKEN, STREAM_PLAYER_ERROR_TOKEN, STREAM_PLAYER_PARAMS_TOKEN, STREAM_PLAYER_SLOT_TOKEN, STREAM_PLAYER_TOKEN, STREAM_SLOT_PLAYER_ID_TOKEN, STREAM_SOOP_IMPORTS, STREAM_TIKTOK_IMPORTS, STREAM_TWITCH_IMPORTS, STREAM_USER_CONSENT_PROVIDER_TOKEN, STREAM_VIMEO_IMPORTS, STREAM_YOUTUBE_IMPORTS, STRIKETHROUGH_ICON, SUPPORT_CONTENT_STATE, SUPPORT_TRANSITION_DIRECTION, SWITCH_IMPORTS, SankeyChartComponent, SankeyChartDirective, SankeyChartMarkDirective, SchedulerActionAddAppointmentDirective, SchedulerAgendaDirective, SchedulerAgendaViewComponent, SchedulerAppointmentDragDirective, SchedulerBadgeChainCountComponent, SchedulerBadgeChainCountDirective, SchedulerBadgeColorDotComponent, SchedulerBadgeColorDotDirective, SchedulerBadgeLocationComponent, SchedulerBadgeLocationDirective, SchedulerBadgeTimeRangeComponent, SchedulerBadgeTimeRangeDirective, SchedulerBadgeTitleComponent, SchedulerBadgeTitleDirective, SchedulerComponent, SchedulerDirective, SchedulerEditAddSubAppointmentItemComponent, SchedulerEditColorComponent, SchedulerEditDeleteItemComponent, SchedulerEditDescriptionComponent, SchedulerEditLocationComponent, SchedulerEditSurfaceActionsComponent, SchedulerEditSurfaceBreadcrumbComponent, SchedulerEditSurfaceChildrenComponent, SchedulerEditSurfaceComponent, SchedulerEditSurfaceDirective, SchedulerEditSurfaceFieldsComponent, SchedulerEditSurfaceFooterComponent, SchedulerEditSurfaceHeaderComponent, SchedulerEditTimeRangeComponent, SchedulerEditTitleComponent, SchedulerMonthDirective, SchedulerMonthViewComponent, SchedulerSwipeNavigationDirective, SchedulerTimeGridDirective, SchedulerTimeGridViewComponent, ScrollableActiveChildDirective, ScrollableButtonsComponent, ScrollableButtonsDirective, ScrollableComponent, ScrollableDarkenDirective, ScrollableDirective, ScrollableDragDirective, ScrollableIgnoreChildDirective, ScrollableLoadingTemplateDirective, ScrollableMasksComponent, ScrollableNavigationComponent, ScrollableNavigationDirective, ScrollableSnapDirective, ScrollbarComponent, ScrollbarDirective, ScrollbarThumbDirective, SegmentedButtonComponent, SegmentedButtonGroupComponent, SelectAllOptionComponent, SelectAllOptionDirective, SelectComponent, SelectDirective, SelectEmptyDirective, SelectErrorDirective, SelectListboxDirective, SelectLoadingDirective, SelectOptionComponent, SelectOptionDirective, SelectOptionGroupComponent, SelectOptionGroupDirective, SelectOptionTemplateDirective, SelectOptionsDirective, SelectPanelComponent, SelectSearchDirective, SelectSurfaceDirective, SelectTriggerDirective, SelectValueDirective, SelectViewportDirective, SelectVirtualOptionComponent, SelectVirtualOptionDirective, SelectionListControlDirective, SelectionListDirective, SelectionOptionDirective, SkeletonComponent, SkeletonItemComponent, SkeletonTextComponent, SliderComponent, SliderDirective, SliderThumbDirective, SliderThumbLabelDirective, SliderTrackDirective, SoopPlayerComponent, SoopPlayerDirective, SoopPlayerParamsDirective, SoopPlayerSlotComponent, SpinnerComponent, SplitButtonActionDirective, SplitButtonComponent, SplitButtonDirective, SplitButtonTriggerDirective, StandingsComponent, StandingsDirective, StandingsPickComponent, StandingsPickDirective, StandingsPickMarkDirective, StatTileComponent, StatTileSparklineComponent, StreamConsentAcceptDirective, StreamConsentComponent, StreamConsentDirective, StreamPipChromeComponent, StreamPlayerErrorComponent, StreamPlayerErrorDirective, StreamPlayerLoadingComponent, StreamPlayerSlotDirective, SwitchComponent, SwitchDirective, TABLE_CELL_ERROR_TOOLTIP_IMPORTS, TABLE_COLUMN_CHOOSER_IMPORTS, TABLE_COLUMN_MENU_IMPORTS, TABLE_CSV_EXPORT_IMPORTS, TABLE_DRAG_SCROLL_IMPORTS, TABLE_ERROR_CODES, TABLE_FEATURE_HOST, TABLE_FILTER_IMPORTS, TABLE_GROUP_HEADERS_IMPORTS, TABLE_ICON, TABLE_IMPORTS, TABLE_INLINE_EDIT_IMPORTS, TABLE_KEYBOARD_NAV_IMPORTS, TABLE_LABELS, TABLE_PAGE_STICKY_HEADER_IMPORTS, TABLE_REORDER_IMPORTS, TABLE_RESIZE_IMPORTS, TABLE_ROW_EXPANSION_IMPORTS, TABLE_ROW_ROUTER_LINK_IMPORTS, TABLE_SELECTION_IMPORTS, TABLE_SKELETON_IMPORTS, TABLE_STATE_PERSISTENCE_IMPORTS, TABLE_STICKY_COLUMNS_IMPORTS, TABLE_VIRTUAL_SCROLL_IMPORTS, TAB_BAR_FITS, TAB_BAR_ORIENTATIONS, TAB_BAR_TOKEN, TAB_BAR_TRIGGER_TOKEN, TAB_BAR_VARIANTS, TAB_ERROR_CODES, TAB_GROUP_TOKEN, TAB_IMPORTS, TAB_PANEL_TOKEN, TAB_SIZES, TAG_INPUT_ERROR_CODES, TAG_INPUT_IMPORTS, TEXTAREA_IMPORTS, TEXTAREA_RESIZE_MODES, TEXT_ALIGNS, TEXT_FIELD_CONTROL_INPUTS, THUMBTACK_ICON, TIKTOK_PLAYER_TOKEN, TIMELINE_IMPORTS, TIMES_ICON, TIME_FORMAT, TIME_INPUT_ERROR_CODES, TIME_INPUT_IMPORTS, TIME_PICKER_ERROR_CODES, TIME_PICKER_IMPORTS, TIME_PICKER_LABELS, TIME_RANGE_INPUT_ERROR_CODES, TIME_RANGE_INPUT_IMPORTS, TOGGLETIP_ERROR_CODES, TOGGLETIP_IMPORTS, TOOLBAR_IMPORTS, TOOLBAR_ORIENTATIONS, TOOLTIP_ERROR_CODES, TOOLTIP_IMPORTS, TRASH_ICON, TREE_ERROR_CODES, TREE_IMPORTS, TREE_LABELS, TREE_LEVEL_STATUSES, TREE_MARKERS, TREE_SELECTION_MODES, TRIANGLE_EXCLAMATION_ICON, TROPHY_ICON, TWITCH_PLAYER_TOKEN, TabBarDirective, TabBarTriggerDirective, TabBarUnderlineDirective, TabComponent, TabGroupComponent, TabGroupDirective, TabLabelDirective, TabPanelDirective, TabTriggerDirective, TableCardSurfaceDirective, TableCellDirective, TableCellEditDirective, TableCellErrorMarkComponent, TableCellErrorTooltipDirective, TableCellSkeletonDirective, TableColumnChooserComponent, TableColumnMenuDirective, TableColumnMenuTriggerComponent, TableComponent, TableCsvExportDirective, TableDetailStylesComponent, TableDragScrollDirective, TableDragScrollStylesComponent, TableExpanderCellComponent, TableFilterOptionDirective, TableFilterTriggerComponent, TableFiltersDirective, TableFooterCellDirective, TableFooterDirective, TableGroupHeaderRowComponent, TableGroupHeadersDirective, TableHeaderCellDirective, TableInlineEditDirective, TableInlineEditStylesComponent, TableKeyboardNavDirective, TablePageStickyHeaderDirective, TablePageStickyHeaderStylesComponent, TableReorderDirective, TableReorderOverlayComponent, TableResizeDirective, TableResizeGripComponent, TableRowBoxStylesComponent, TableRowDetailComponent, TableRowExpansionDirective, TableRowRouterLinkDirective, TableSelectAllCellComponent, TableSelectCellComponent, TableSelectionDirective, TableSkeletonDirective, TableSkeletonRowsComponent, TableStatePersistenceDirective, TableStickyColumnsDirective, TableStickyColumnsStylesComponent, TableVirtualScrollDirective, TableVirtualScrollStylesComponent, TagInputComponent, TagInputDirective, TagInputFieldDirective, TextButtonComponent, TextFieldControlDirective, TextareaComponent, TextareaDirective, TikTokPlayerComponent, TikTokPlayerDirective, TikTokPlayerParamsDirective, TikTokPlayerSlotComponent, TimeInputComponent, TimeInputDirective, TimeInputFieldDirective, TimePickerComponent, TimePickerDirective, TimePickerRingDirective, TimePickerRingHandleDirective, TimeRangeInputComponent, TimeRangeInputDirective, TimeRangeInputFieldDirective, TimelineComponent, TimelineItemComponent, ToggletipCloseDirective, ToggletipComponent, ToggletipDirective, ToggletipTriggerDirective, ToolbarComponent, ToolbarDirective, TooltipComponent, TooltipDirective, TreeComponent, TreeDirective, TreeMarkerComponent, TreeNodeDefDirective, TreeNodeDirective, TwitchPlayerComponent, TwitchPlayerDirective, TwitchPlayerParamsDirective, TwitchPlayerSlotComponent, UNDERLINE_ICON, UNDO_ICON, UNSAVED_CHANGES_LABELS, UPLOAD_ICON, VIMEO_PLAYER_TOKEN, VimeoPlayerComponent, VimeoPlayerDirective, VimeoPlayerParamsDirective, VimeoPlayerSlotComponent, WCAG_CONTRAST_RATIOS, WINDOW_CONTROL_BUTTON_KINDS, WINDOW_CONTROL_BUTTON_SIZES, WindowControlButtonComponent, YOUTUBE_PLAYER_TOKEN, YoutubePlayerComponent, YoutubePlayerDirective, YoutubePlayerParamsDirective, YoutubePlayerSlotComponent, anchoredDialogOverlayStrategy, anchoredOverlayStrategy, bottomSheetOverlayStrategy, bracketFitsWidth, bracketNaturalWidth, buildAnchoredRuntimePositionStrategy, canHaveChildren, canonicalKbdKey, cascaderFromQuery, centeredOverlayStrategy, clearLeavingSupportStateOnExit, colorContrast, commandPaletteLabelsForLocale, countDescendants, createAlertDialogOpener, createAnchoredPanelController, createCardMask, createCommandPaletteOpener, createCurrencyMask, createDefaultDropzoneArgs, createDropzoneUpload, createExistingDropzoneEntry, createFileDropzoneEntry, createFixedLengthRangeStrategy, createGridAdapter, createIbanMask, createNormalizedBracketMatch, createNotificationPromiseFn, createNotificationRef, createOverlayOpener, createOverlaySingleSlot, createOverlayStrategyController, createOverlayUnsavedChangesGuard, createPipChromeAnimations, createPipChromeState, createRichTextEditorTrigger, createRichTextEditorTriggerWithQuery, createSchedulerRegistry, createStreamConfig, createStreamPlayerSlot, createTableRowsSource, createTableRowsState, createTableStateStorage, createV2DropzoneUpload, createWeekRangeStrategy, dateBounds, dateRangeBounds, dateRangeOrder, dateTimeBounds, dateTimeRangeBounds, dateTimeRangeOrder, defaultCompareWith$1 as defaultCompareWith, defaultDropzoneRejectionMessage, defaultSankeyChartLinkKeyHint, defineOverlay, defineQueryParamOverlay, describeBracketSlot, deserializeGridLayout, deserializeTableState, detectKbdPlatform, dialogOverlayStrategy, disposeDropzoneEntry, doubleEliminationBracketLayout, dropzoneFiles, enableDragToDismiss, extractFirstImageUrl, filterOverlayLabelsForLocale, filterOverlayPreviewFromQuery, filterRows, filterValues, findNextRelevantHtmlElement, focusFirstInvalidField, formatFileSize, fromGridPosition, fullScreenDialogOverlayStrategy, generateBracketDataForEthlete, generateRoundTypeFromEthleteRoundType, generateTournamentModeFromEthleteRounds, getClosestOverlay, getColorContrastRatio, getOriginCoordinatesAndDimensions, hexColor, hitsInteractiveElement, iconRegistryKey, injectAlertDialogLabels, injectAnchoredDialogStrategy, injectAnchoredDialogStrategyDefaults, injectAvatarLabels, injectBannerLabels, injectBottomSheetStrategy, injectBottomSheetStrategyDefaults, injectBracketConfig, injectBracketLabels, injectBreadcrumbLabels, injectBreadcrumbManager, injectCalendarLabels, injectCarouselLabels, injectCascaderLabels, injectChartLabels, injectChipLabels, injectColorInputLabels, injectCommandPalette, injectCommandPaletteLabels, injectCommandPaletteRegistry, injectCopyButtonLabels, injectDateFormat, injectDateLocale, injectDateTimeFormat, injectDateTimeLabels, injectDateTimeZone, injectDialogStrategy, injectDialogStrategyDefaults, injectDropzoneLabels, injectFilterOverlay, injectFilterOverlayLabels, injectFormFieldDefaults, injectFormFieldLabels, injectFormSupport, injectFullscreenDialogStrategy, injectFullscreenDialogStrategyDefaults, injectGridConfig, injectGridLabels, injectInputLabels, injectKbdLabels, injectLeftSheetStrategy, injectLeftSheetStrategyDefaults, injectLoaderLabels, injectMatchLabels, injectNotificationLabels, injectNotificationManager, injectNotificationManagerConfig, injectOverlayManager, injectOverlayRouter, injectOverlayScrollBlocker, injectOverlaySurfaceContext, injectPaginationLabels, injectPhoneInputLabels, injectPictureConfig, injectPipChromeManager, injectPipManager, injectPipSlotPlaceholderConfig, injectProgressStepLabels, injectQueryErrorLabels, injectRichTextEditorLabels, injectRichTextEditorTools, injectRightSheetStrategy, injectRightSheetStrategyDefaults, injectSchedulerEditSurface, injectSchedulerEditSurfaceOpener, injectSchedulerFeatureHost, injectSchedulerLabels, injectSelectLabels, injectSidebarOverlay, injectSliderLabels, injectStandingsLabels, injectStatTileLabels, injectStreamConfig, injectStreamConsentConfig, injectStreamLabels, injectStreamManager, injectStreamPlayerErrorConfig, injectStreamPlayerLoadingConfig, injectStreamPlayerSlot, injectStreamScriptLoader, injectStreamUserConsentProvider, injectTableCsvExport, injectTableFeatureHost, injectTableLabels, injectTimeFormat, injectTimePickerLabels, injectTopSheetStrategy, injectTopSheetStrategyDefaults, injectTreeLabels, injectUnsavedChangesLabels, isFileAccepted, isHtmlElement, isInteractiveElement, isPointerEvent, isRestorableTableState, isTargetInsideOverlayTree, isTouchEvent, kbdKeyLabel, kbdKeyName, lastDaysPreset, lastMonthPreset, lastWeekPreset, leftSheetOverlayStrategy, legacyQueryErrorSource, mapGridLayout, matchCountryByDialCode, matchParticipantDisplayName, matchedDialPrefix, matchesKbdChord, mergeOverlayBreakpointConfigs, mergeOverlayConfigs, mergeTableCsvExportOptions, mirroredDoubleEliminationBracketLayout, mirroredSingleEliminationBracketLayout, missingStreamSourceError, mountNavTabLinkStyles, nextDaysPreset, normalizeEthleteBracketMatch, normalizeEthleteGroupRanking, normalizeEthleteMatch, normalizeEthleteMatchStatus, normalizeEthleteMedia, normalizeEthleteParticipant, normalizeEthletePlacement, normalizePictureSizes, normalizePictureSource, numberInputStepMultiplierFrom, overlayResult, paginate, parseKbdKeys, phoneCountryFlag, phoneCountryName, provideAlertDialogLabels, provideAnchoredDialogStrategy, provideAnchoredDialogStrategyDefaults, provideAvatarLabels, provideBannerLabels, provideBottomSheetStrategy, provideBottomSheetStrategyDefaults, provideBracketConfig, provideBracketLabels, provideBreadcrumbLabels, provideBreadcrumbManager, provideCalendarLabels, provideCarouselLabels, provideCascaderLabels, provideChartLabels, provideChipLabels, provideColorInputLabels, provideCommandPaletteLabels, provideCommandPaletteRegistry, provideCopyButtonLabels, provideDateFormat, provideDateLocale, provideDateTimeFormat, provideDateTimeLabels, provideDateTimeZone, provideDialogStrategy, provideDialogStrategyDefaults, provideDropzoneLabels, provideFilterOverlay, provideFilterOverlayLabels, provideFormErrorMessageResolver, provideFormFieldDefaults, provideFormFieldLabels, provideFormSupport, provideFormWarningMessageResolver, provideFullscreenDialogStrategy, provideFullscreenDialogStrategyDefaults, provideGridConfig, provideGridLabels, provideIconOverrides, provideIcons, provideInputLabels, provideKbdLabels, provideLeftSheetStrategy, provideLeftSheetStrategyDefaults, provideLoaderLabels, provideMatchLabels, provideNotificationLabels, provideNotificationManager, provideNotificationManagerConfig, provideNotificationManagerInstance, provideOverlay, provideOverlayManager, provideOverlayRouter, provideOverlayRouterConfig, provideOverlayRouterService, provideOverlayScrollBlocker, providePaginationLabels, providePhoneInputLabels, providePictureConfig, providePipChromeManager, providePipManager, providePipSlotPlaceholderConfig, provideProgressStepLabels, provideQueryErrorLabels, provideRichTextEditorAlignmentTool, provideRichTextEditorAutoformat, provideRichTextEditorBlockquoteTool, provideRichTextEditorCodeBlockTool, provideRichTextEditorDefaultTools, provideRichTextEditorFloatingToolbar, provideRichTextEditorHeadingTool, provideRichTextEditorImageTool, provideRichTextEditorLabels, provideRichTextEditorLanguageTool, provideRichTextEditorLinkEditor, provideRichTextEditorLinkTool, provideRichTextEditorTableTool, provideRichTextEditorTokenRendering, provideRichTextEditorTool, provideRichTextEditorTools, provideRightSheetStrategy, provideRightSheetStrategyDefaults, provideSchedulerEditSurface, provideSchedulerLabels, provideSelectLabels, provideSidebarOverlay, provideSidebarOverlayConfig, provideSidebarOverlayService, provideSliderLabels, provideStandingsLabels, provideStatTileLabels, provideStreamConfig, provideStreamConsentConfig, provideStreamLabels, provideStreamManager, provideStreamPip, provideStreamPlayerErrorConfig, provideStreamPlayerLoadingConfig, provideTableLabels, provideTimeFormat, provideTimePickerLabels, provideTopSheetStrategy, provideTopSheetStrategyDefaults, provideTreeLabels, provideUnsavedChangesAlertDialog, provideUnsavedChangesLabels, queryButtonSourceFromV2Query, queryErrorLabelsForLocale, queryErrorResponseFromLegacyError, quickFilterRows, reconcileColumnOrder, reconcileColumnWidths, reconcileHiddenColumns, reduceSupportPresentation, registerCommands, registerSingleton, requiredLanguages, resolveBracketLayout, resolveClosestOverlay, resolveFilterOverlaySubmitButton, resolveNormalizedMatchSideState, resolveNotificationStatusIcon, resolveOverlayHasBackdrop, resolveTableCsvRows, rgbColor, richTextEditorToolLabel, rightSheetOverlayStrategy, schedulerFeatureConfig, selectOptionsFromQuery, selectOptionsFromV2Query, serializeGridLayout, serializeTableState, singleEliminationBracketLayout, sortRows, startOfCalendarUnit, stripTrunkZero, supportPresentationIncludesState, swissBracketLayout, tableCsvRowsFromPages, tableFeatureConfig, tableRowsFromQuery, tableRowsFromV2Query, tableToCsv, thisMonthPreset, thisWeekPreset, thisYearPreset, timeBounds, timeRangeBounds, timeRangeOrder, toFieldWarnings, toGridPosition, toNotificationContent, toPictureDimension, todayPreset, topSheetOverlayStrategy, transformingBottomSheetToDialogOverlayStrategy, transformingFullScreenDialogToDialogOverlayStrategy, transformingFullScreenDialogToRightSheetOverlayStrategy, warn, wireFormSupport, withPictureBaseUrl, yesterdayPreset };
76401
+ export { ACCESSIBLE_NAME_INPUTS, ACCORDION_ERROR_CODES, ACCORDION_GROUP_TOKEN, ACCORDION_IMPORTS, ACCORDION_TOKEN, ALERT_DIALOG_LABELS, ALIGN_CENTER_ICON, ALIGN_JUSTIFY_ICON, ALIGN_LEFT_ICON, ALIGN_RIGHT_ICON, ARROWS_LEFT_RIGHT_ICON, ARROW_OUT_UP_RIGHT_ICON, ARROW_RIGHT_ICON, ARROW_UP_ICON, AVATAR_IMPORTS, AVATAR_LABELS, AVATAR_SHAPES, AVATAR_SIZES, AccessibleNameControlDirective, AccordionComponent, AccordionContentDirective, AccordionDirective, AccordionGroupComponent, AccordionGroupDirective, AccordionHintDirective, AccordionLabelDirective, AccordionPanelDirective, AccordionTriggerDirective, AvatarComponent, AvatarGroupComponent, BADGE_ICON_ALIGNMENTS, BADGE_IMPORTS, BADGE_SIZES, BADGE_VARIANTS, BANNER_IMPORTS, BANNER_LABELS, BANNER_TYPES, BOLD_ICON, BRACKET_CARD_CONTEXT, BRACKET_DEFAULTS, BRACKET_DEFAULT_CARDS, BRACKET_DENSITY, BRACKET_DENSITY_PRESETS, BRACKET_IMPORTS, BRACKET_LABELS, BRACKET_PARTICIPANTS_IMPORTS, BRACKET_PICK_CARD_IMPORTS, BRACKET_PICK_CARD_NOTE_TONE, BRACKET_ROUNDS_LIST_IMPORTS, BRACKET_ROUND_HEADER_ALIGN, BRACKET_SKELETON_IMPORTS, BREADCRUMB_COLLAPSE_IMPORTS, BREADCRUMB_COLLAPSE_TOKEN, BREADCRUMB_ERROR_CODES, BREADCRUMB_IMPORTS, BREADCRUMB_LABELS, BREADCRUMB_SEGMENT_TOKEN, BREADCRUMB_SEO_IMPORTS, BREADCRUMB_TOKEN, BUTTON_ICON_ALIGNMENTS, BUTTON_IMPORTS, BUTTON_SIZES, BUTTON_SPINNER_CONFIG, BUTTON_TYPES, BUTTON_VARIANTS, BadgeComponent, BannerComponent, BarChartComponent, BarChartDirective, BarChartPlotDirective, BracketComponent, BracketDefaultContinueComponent, BracketDefaultFinalMatchComponent, BracketDefaultMatchComponent, BracketDefaultRoundHeaderComponent, BracketParticipantsComponent, BracketPickCardComponent, BracketRoundsListComponent, BracketSkeletonComponent, BracketSkeletonContinueComponent, BracketSkeletonFinalMatchComponent, BracketSkeletonMatchComponent, BracketSkeletonRoundHeaderComponent, BrandLoaderComponent, BreadcrumbCollapseDirective, BreadcrumbComponent, BreadcrumbDirective, BreadcrumbItemDirective, BreadcrumbItemTemplateDirective, BreadcrumbOutletComponent, BreadcrumbOverflowComponent, BreadcrumbSegmentDirective, BreadcrumbSeoDirective, BreadcrumbSeparatorDirective, ButtonColorDirective, ButtonComponent, ButtonDirective, ButtonStylesDirective, CALENDAR_ERROR_CODES, CALENDAR_ICON, CALENDAR_IMPORTS, CALENDAR_LABELS, CARD_IMPORTS, CARD_VARIANTS, CAROUSEL_AUTOPLAY_TOKEN, CAROUSEL_ERROR_CODES, CAROUSEL_IMPORTS, CAROUSEL_LABELS, CAROUSEL_SLIDE_ALIGNMENTS, CAROUSEL_TOKEN, CAROUSEL_TRANSITIONS, CAROUSEL_TRANSITION_DRIVERS, CASCADER_ERROR_CODES, CASCADER_IMPORTS, CASCADER_LABELS, CASCADER_SELECTABLE_LEVELS, CHART_ERROR_CODES, CHART_IMPORTS, CHART_LABELS, CHART_PLOT_HOST, CHECKBOX_GROUP_IMPORTS, CHECKBOX_IMPORTS, CHECKBOX_OPTION_VARIANTS, CHECK_ICON, CHEVRON_ICON, CHIP_ERROR_CODES, CHIP_IMPORTS, CHIP_LABELS, CHIP_REMOVE_FOCUS_FALLBACK, CHIP_REMOVE_TAB_STOP, CHOICE_FIELD_IMPORTS, CHOICE_FIELD_VARIANTS, CIRCLE_CHECK_ICON, CIRCLE_INFO_ICON, CLIPBOARD_CHECK_ICON, CLOCK_ICON, CODE_BLOCK_ICON, CODE_ICON, COLOR_INPUT_ERROR_CODES, COLOR_INPUT_IMPORTS, COLOR_INPUT_LABELS, COLOR_INPUT_TOKEN, COLOR_NOTATIONS, COLOR_NOTATION_ORDER, COMMAND_PALETTE_ERROR_CODES, COMMAND_PALETTE_IMPORTS, COMMAND_PALETTE_LABELS, COMMAND_PALETTE_OVERLAY, COMMAND_PALETTE_REGISTRY, COMMAND_PALETTE_TOKEN, COMPONENTS_VERSION, COPY_BUTTON_IMPORTS, COPY_BUTTON_LABELS, CalendarCellDirective, CalendarComponent, CalendarDirective, CalendarGridDirective, CalendarHeaderDirective, CardComponent, CarouselAutoplayDirective, CarouselComponent, CarouselDirective, CarouselItemDirective, CarouselNextDirective, CarouselPlayToggleDirective, CarouselPreviousDirective, CarouselSlideDirective, CascaderColumnDirective, CascaderComponent, CascaderDirective, CascaderNodeDirective, CascaderPanelComponent, CascaderSearchDirective, CascaderSearchOptionDirective, CascaderSurfaceDirective, CascaderTriggerDirective, ChartPlotDirective, CheckboxComponent, CheckboxDirective, CheckboxGroupComponent, CheckboxGroupSelectAllComponent, CheckboxOptionComponent, ChipComponent, ChipDirective, ChipRemoveDirective, ChoiceFieldComponent, ColorInputComponent, ColorInputDirective, ColorPickerAreaDirective, ColorPickerChannelDirective, ColorPickerPanelComponent, ColorPickerSurfaceDirective, ColorPickerTriggerDirective, CommandPaletteComponent, CommandPaletteDirective, CommandPaletteItemComponent, CommandPaletteSearchDirective, CommandPaletteShortcutDirective, ControlSuffixDirective, CopyButtonDirective, CounterComponent, DAILYMOTION_PLAYER_TOKEN, DATE_FORMAT, DATE_INPUT_ERROR_CODES, DATE_INPUT_IMPORTS, DATE_LOCALE, DATE_PICKER_HOST, DATE_RANGE_INPUT_ERROR_CODES, DATE_RANGE_INPUT_IMPORTS, DATE_TIME_FORMAT, DATE_TIME_INPUT_ERROR_CODES, DATE_TIME_INPUT_IMPORTS, DATE_TIME_LABELS, DATE_TIME_RANGE_INPUT_ERROR_CODES, DATE_TIME_RANGE_INPUT_IMPORTS, DEFAULT_ALERT_DIALOG_LABELS, DEFAULT_AVATAR_LABELS, DEFAULT_BANNER_LABELS, DEFAULT_BRACKET_LABELS, DEFAULT_BREADCRUMB_LABELS, DEFAULT_BREAKPOINTS, DEFAULT_CALENDAR_LABELS, DEFAULT_CALENDAR_RANGE_STRATEGY, DEFAULT_CAROUSEL_LABELS, DEFAULT_CASCADER_LABELS, DEFAULT_CHART_LABELS, DEFAULT_CHIP_LABELS, DEFAULT_COLOR_INPUT_LABELS, DEFAULT_COMMAND_PALETTE_LABELS, DEFAULT_COPY_BUTTON_LABELS, DEFAULT_DATE_TIME_LABELS, DEFAULT_DROPZONE_LABELS, DEFAULT_DROPZONE_MAX_PREVIEW_FILE_SIZE, DEFAULT_FILTER_OVERLAY_LABELS, DEFAULT_FORM_FIELD_DEFAULTS, DEFAULT_FORM_FIELD_LABELS, DEFAULT_GRID_LABELS, DEFAULT_ICON_VARIANT, DEFAULT_INPUT_LABELS, DEFAULT_KBD_LABELS, DEFAULT_LOADER_LABELS, DEFAULT_MATCH_CARD_START_TIME_FORMAT, DEFAULT_MATCH_LABELS, DEFAULT_NOTIFICATION_LABELS, DEFAULT_NOTIFICATION_MANAGER_CONFIG, DEFAULT_NOTIFICATION_STATUS_ICONS, DEFAULT_PAGINATION_LABELS, DEFAULT_PHONE_INPUT_LABELS, DEFAULT_PROGRESS_STEP_LABELS, DEFAULT_QUERY_ERROR_LABELS, DEFAULT_RICH_TEXT_EDITOR_LABELS, DEFAULT_RICH_TEXT_EDITOR_TOOLS, DEFAULT_SCHEDULER_LABELS, DEFAULT_SELECT_LABELS, DEFAULT_SLIDER_LABELS, DEFAULT_STANDINGS_LABELS, DEFAULT_STAT_TILE_LABELS, DEFAULT_STREAM_LABELS, DEFAULT_STREAM_PLAYER_STATE, DEFAULT_TABLE_LABELS, DEFAULT_TIME_PICKER_LABELS, DEFAULT_TREE_LABELS, DEFAULT_UNSAVED_CHANGES_LABELS, DESCRIPTION_IMPORTS, DESCRIPTION_LIST_IMPORTS, DESCRIPTION_LIST_VARIANTS, DIVIDER_IMPORTS, DROPZONE_ENTRY_STATUSES, DROPZONE_ERROR_CODES, DROPZONE_FILES_ERROR_KIND, DROPZONE_FILE_CONSTRAINTS, DROPZONE_FILE_REJECTION_REASONS, DROPZONE_IMPORTS, DROPZONE_LABELS, DURATION_INPUT_ERROR_CODES, DURATION_INPUT_IMPORTS, DailymotionPlayerComponent, DailymotionPlayerDirective, DailymotionPlayerParamsDirective, DailymotionPlayerSlotComponent, DateInputComponent, DateInputDirective, DateInputFieldDirective, DatePickerPanelComponent, DatePickerSurfaceDirective, DatePickerTriggerDirective, DateRangeInputComponent, DateRangeInputDirective, DateRangeInputFieldDirective, DateTimeInputComponent, DateTimeInputDirective, DateTimeInputFieldDirective, DateTimeRangeInputComponent, DateTimeRangeInputDirective, DateTimeRangeInputFieldDirective, DescriptionComponent, DescriptionListComponent, DividerComponent, DropzoneComponent, DropzoneDirective, DurationInputComponent, DurationInputDirective, DurationInputFieldDirective, ELLIPSIS_ICON, ELLIPSIS_VERTICAL_ICON, EMPTY_STATE_IMPORTS, ET_BUILT_IN_ICON_NAMES, EYEDROPPER_ICON, EYE_ICON, EYE_SLASH_ICON, EmptyStateComponent, FACEBOOK_PLAYER_TOKEN, FIELD_WARNINGS, FIELD_WARNING_KIND, FILE_ICON, FILTER_ICON, FILTER_OVERLAY_ERROR_CODES, FILTER_OVERLAY_IMPORTS, FILTER_OVERLAY_LABELS, FILTER_OVERLAY_TOKEN, FLOATING_ACTION_ERROR_CODES, FLOATING_ACTION_IMPORTS, FLOATING_ACTION_STATES, FLOATING_ACTION_TOKEN, FLOPPY_DISK_ICON, FOCUS_FRAME_ICON, FORM_ERROR_MESSAGE_RESOLVER, FORM_FIELD_APPEARANCES, FORM_FIELD_CONTROL_TYPES, FORM_FIELD_ERROR_CODES, FORM_FIELD_FILLS, FORM_FIELD_IMPORTS, FORM_FIELD_LABELS, FORM_FIELD_LABEL_MODES, FORM_FIELD_SIZES, FORM_FIELD_TOKEN, FORM_IMPORTS, FORM_WARNING_MESSAGE_RESOLVER, FabComponent, FacebookPlayerComponent, FacebookPlayerDirective, FacebookPlayerParamsDirective, FacebookPlayerSlotComponent, FilterOverlayResetDirective, FilterOverlaySubmitDirective, FloatingActionAnchorDirective, FloatingActionDirective, FloatingActionScopeDirective, FloatingActionTopDirective, FloatingActionTriggerDirective, FocusRingDirective, FormDirective, FormErrorComponent, FormFieldBarrierDirective, FormFieldComponent, FormFieldDirective, FormWarningComponent, GERMAN_COMMAND_PALETTE_LABELS, GERMAN_FILTER_OVERLAY_LABELS, GERMAN_QUERY_ERROR_LABELS, GRID_2X2_ICON, GRID_DEBUG_IMPORTS, GRID_ERROR_CODES, GRID_IMPORTS, GRID_LABELS, GRID_TOKEN, GridComponent, GridDebugComponent, GridDirective, GridDragDirective, GridItemComponent, GridItemDefaultActionsComponent, GridItemDirective, GridItemToolbarComponent, GridResizeDirective, HEADING_1_ICON, HEADING_2_ICON, HEADING_3_ICON, HintComponent, ICONS_TOKEN, ICON_DIRECTIVE_TOKEN, ICON_ERROR_CODES, ICON_IMPORTS, ICON_OVERRIDES_TOKEN, IMAGE_ICON, INHERIT_COLOR, INITIAL_SUPPORT_PRESENTATION_STATE, INPUT_IMPORTS, INPUT_LABELS, INPUT_MASK_HOST, INPUT_TEXT_ALIGNMENTS, INPUT_TYPES, INTERACTIVE_TAGS$1 as INTERACTIVE_TAGS, ITALIC_ICON, IconButtonComponent, IconDirective, InputComponent, InputDirective, InputMaskDirective, InputPrefixDirective, InputSuffixDirective, KBD_IMPORTS, KBD_LABELS, KBD_PLATFORM, KICK_PLAYER_TOKEN, KbdComponent, KickPlayerComponent, KickPlayerDirective, KickPlayerParamsDirective, KickPlayerSlotComponent, LINE_CHART_ERROR_CODES, LINK_ICON, LIST_BULLETED_ICON, LIST_NUMBERED_ICON, LOADER_IMPORTS, LOADER_LABELS, LOCATION_ICON, LOCK_ICON, LabelDirective, LineChartComponent, LineChartDirective, LineChartSliceDirective, MASKED_INPUT_ERROR_CODES, MASKED_INPUT_IMPORTS, MASK_VALUE_MODES, MASONRY_ERROR_CODES, MASONRY_IMPORTS, MASONRY_TOKEN, MATCH_CARD_IMPORTS, MATCH_CARD_SIZES, MATCH_CARD_TOKEN, MATCH_ERROR_CODES, MATCH_LABELS, MATCH_PARTICIPANT_IMPORTS, MENU_ERROR_CODES, MENU_IMPORTS, MENU_ITEM_VARIANTS, MENU_SEARCH_IMPORTS, MENU_SELECTION_GROUP_MULTIPLE, MENU_SELECTION_GROUP_TOKEN, MENU_SELECTION_ITEM_KIND, MINUS_ICON, MULTI_LANGUAGE_RICH_TEXT_EDITOR_ERROR_CODES, MULTI_LANGUAGE_RICH_TEXT_EDITOR_IMPORTS, MasonryDirective, MasonryItemDirective, MatchCardComponent, MatchCardDirective, MatchCardGameScoresDirective, MatchCardMetaDirective, MatchCardScoreDirective, MatchParticipantComponent, MatchScoreComponent, MenuCheckboxGroupComponent, MenuCheckboxItemComponent, MenuComponent, MenuContextTriggerDirective, MenuDirective, MenuGroupLabelComponent, MenuItemComponent, MenuItemDirective, MenuItemShortcutComponent, MenuItemSubmenuIconComponent, MenuPanelDirective, MenuRadioGroupComponent, MenuRadioItemComponent, MenuSearchDirective, MenuSelectionGroupDirective, MenuSelectionItemDirective, MenuSeparatorComponent, MenuSurfaceDirective, MenuTriggerDirective, MultiLanguageRichTextEditorComponent, MultiLanguageRichTextEditorDirective, MultiLanguageRichTextEditorLanguageToolComponent, NAV_TABS_TOKEN, NAV_TAB_IMPORTS, NOTIFICATION_ACTION_SLOTS, NOTIFICATION_ERROR_CODES, NOTIFICATION_IMPORTS, NOTIFICATION_LABELS, NOTIFICATION_STACK_CONTEXT_TOKEN, NOTIFICATION_STACK_OVERLAY_LAYER, NOTIFICATION_STATUS, NO_STREAM_PLAYER_CAPABILITIES, NUMBER_INPUT_IMPORTS, NavTabLinkComponent, NavTabLinkDirective, NavTabLinkStylesComponent, NavTabsComponent, NavTabsDirective, NavTabsOutletComponent, NavTabsOutletDirective, NotificationActionDirective, NotificationComponent, NotificationDirective, NotificationDismissDirective, NotificationItemDirective, NotificationStackDirective, NotificationSwipeToDismissDirective, NumberInputComponent, NumberInputDirective, OTP_INPUT_IMPORTS, OVERLAY_BACK_OR_CLOSE_TOKEN, OVERLAY_BODY_TOKEN, OVERLAY_CONFIG_CLASS_KEYS, OVERLAY_CONTENT_IMPORTS, OVERLAY_ERROR_CODES, OVERLAY_FOOTER_TOKEN, OVERLAY_HAS_BACKDROP, OVERLAY_HEADER_TEMPLATE_TOKEN, OVERLAY_HEADER_TOKEN, OVERLAY_IMPORTS, OVERLAY_MAIN_TOKEN, OVERLAY_NAV_TAB_IMPORTS, OVERLAY_QUERY_PARAM_INPUT_NAME, OVERLAY_REF, OVERLAY_ROUTER_CONFIG_TOKEN, OVERLAY_ROUTER_LINK_TOKEN, OVERLAY_ROUTER_OUTLET_DISABLED_TEMPLATE_TOKEN, OVERLAY_ROUTER_OUTLET_TOKEN, OVERLAY_ROUTER_TOKEN, OVERLAY_SHARED_ROUTE_TEMPLATE_TOKEN, OtpInputComponent, OtpInputDirective, OverlayAnchorDirective, OverlayBackOrCloseDirective, OverlayBodyComponent, OverlayCloseDirective, OverlayContainerComponent, OverlayDirective, OverlayFooterDirective, OverlayHeaderDirective, OverlayHeaderTemplateDirective, OverlayMainDirective, OverlayNavTabLinkComponent, OverlayOriginCloneComponent, OverlayRouteHeaderTemplateOutletComponent, OverlayRouterLinkDirective, OverlayRouterOutletComponent, OverlayRouterOutletDisabledTemplateDirective, OverlaySharedRouteTemplateDirective, OverlaySharedRouteTemplateOutletComponent, OverlaySidebarComponent, OverlaySidebarPageComponent, OverlaySurfaceDirective, OverlayTitleDirective, OverlayTriggerDirective, PAGE_SIZE_SELECT_IMPORTS, PAGINATION_IMPORTS, PAGINATION_LABELS, PAGINATION_SIZES, PARAGRAPH_ICON, PASSWORD_INPUT_IMPORTS, PAUSE_ICON, PENCIL_ICON, PHONE_COUNTRIES, PHONE_INPUT_ERROR_CODES, PHONE_INPUT_IMPORTS, PHONE_INPUT_LABELS, PICTURE_IMPORTS, PICTURE_STATES, PIE_CHART_ERROR_CODES, PIP_CHROME_REF_TOKEN, PIP_ENTRY_TOKEN, PIP_WINDOW_ASPECT_RATIO_TOKEN, PLAY_ICON, PLUS_ICON, PROGRESS_STEPS_IMPORTS, PROGRESS_STEPS_ORIENTATIONS, PROGRESS_STEP_LABELS, PROGRESS_STEP_STATES, PageSizeSelectComponent, PagedQueryTriggerDirective, PaginationComponent, PaginationDirective, PaginationSeoDirective, PasswordInputComponent, PasswordInputDirective, PhoneInputComponent, PhoneInputDirective, PhoneInputFieldDirective, PhoneInputFlagDirective, PictureComponent, PictureErrorDirective, PicturePlaceholderDirective, PieChartComponent, PieChartDirective, PipBackDirective, PipBringBackDirective, PipCellDirective, PipCloseDirective, PipCollapseOverlayDirective, PipGridToggleDirective, PipPlayerComponent, PipSlotPlaceholderComponent, PipStageDirective, PipTitleBarDirective, PipTitleBarTemplateDirective, PipWindowComponent, PipWindowParamsDirective, ProgressBarComponent, ProgressStepComponent, ProgressStepsComponent, QUERY_ERROR_ERROR_CODES, QUERY_ERROR_IMPORTS, QUERY_ERROR_LABELS, QUERY_ERROR_TOKEN, QUOTE_ICON, QueryButtonDirective, QueryErrorActionsDirective, QueryErrorComponent, QueryErrorDirective, QueryErrorTitleDirective, QueryParamOverlayLinkDirective, RADIO_GROUP_IMPORTS, RADIO_VARIANTS, RATING_ERROR_CODES, RATING_IMPORTS, REDO_ICON, RICH_TEXT_EDITOR_FLOATING_TOOLBAR, RICH_TEXT_EDITOR_HEADING_OPTIONS, RICH_TEXT_EDITOR_IMPORTS, RICH_TEXT_EDITOR_INLINE_TOOLS, RICH_TEXT_EDITOR_LABELS, RICH_TEXT_EDITOR_LANGUAGE_TOOL, RICH_TEXT_EDITOR_LINK_EDITOR, RICH_TEXT_EDITOR_TOKEN_CODEC, RICH_TEXT_EDITOR_TOKEN_PALETTE_IMPORTS, RICH_TEXT_EDITOR_TOOL, RICH_TEXT_EDITOR_TOOLS, RICH_TEXT_EDITOR_TOOL_BUTTONS, RICH_TEXT_EDITOR_TRIGGERS_IMPORTS, ROTATE_RIGHT_ICON, RadioComponent, RadioGroupComponent, RangeSliderComponent, RangeSliderDirective, RatingComponent, RatingDirective, RatingIconDirective, RichTextEditorAlignToolComponent, RichTextEditorComponent, RichTextEditorDirective, RichTextEditorFloatingToolbarComponent, RichTextEditorFloatingToolbarDirective, RichTextEditorHeadingToolComponent, RichTextEditorImageEditorComponent, RichTextEditorImageToolComponent, RichTextEditorLinkEditorComponent, RichTextEditorLinkEditorDirective, RichTextEditorTableToolComponent, RichTextEditorTokenPaletteComponent, RichTextEditorTokenPopupComponent, RichTextEditorTriggersDirective, RichTextViewerComponent, SANKEY_CHART_ERROR_CODES, SCHEDULER_EDIT_SURFACE_IMPORTS, SCHEDULER_ERROR_CODES, SCHEDULER_FEATURE_HOST, SCHEDULER_IMPORTS, SCHEDULER_LABELS, SCROLLABLE_DARKEN_IMPORTS, SCROLLABLE_DRAG_IMPORTS, SCROLLABLE_ERROR_CODES, SCROLLABLE_IMPORTS, SCROLLABLE_NAVIGATION_IMPORTS, SCROLLBAR_ERROR_CODES, SCROLLBAR_IMPORTS, SEGMENTED_BUTTON_GROUP_VARIANTS, SEGMENTED_BUTTON_IMPORTS, SELECTION_CARD_CONTROL_POSITIONS, SELECTION_LIST_ERROR_CODES, SELECTION_LIST_IMPORTS, SELECTION_LIST_MULTIPLE, SELECTION_LIST_TOKEN, SELECT_ERROR_CODES, SELECT_FILTER_MODES, SELECT_IMPORTS, SELECT_LABELS, SIDEBAR_OVERLAY_CONFIG, SIDEBAR_OVERLAY_TOKEN, SKELETON_IMPORTS, SLIDER_ERROR_CODES, SLIDER_IMPORTS, SLIDER_LABELS, SLIDER_MARK_VALUE_ATTRIBUTE, SLIDER_TOKEN, SOOP_PLAYER_TOKEN, SPLIT_BUTTON_ERROR_CODES, STANDINGS_ERROR_CODES, STANDINGS_IMPORTS, STANDINGS_LABELS, STANDINGS_PICK_IMPORTS, STAR_ICON, STAT_TILE_IMPORTS, STAT_TILE_LABELS, STREAM_ALL_IMPORTS, STREAM_CONSENT_TOKEN, STREAM_DAILYMOTION_IMPORTS, STREAM_DEFAULT_COMPONENTS, STREAM_ERROR_CODES, STREAM_FACEBOOK_IMPORTS, STREAM_IMPORTS, STREAM_KICK_IMPORTS, STREAM_LABELS, STREAM_PIP_IMPORTS, STREAM_PLAYER_COMPONENT_TOKEN, STREAM_PLAYER_ERROR_CONTEXT_TOKEN, STREAM_PLAYER_ERROR_TOKEN, STREAM_PLAYER_PARAMS_TOKEN, STREAM_PLAYER_SLOT_TOKEN, STREAM_PLAYER_TOKEN, STREAM_SLOT_PLAYER_ID_TOKEN, STREAM_SOOP_IMPORTS, STREAM_TIKTOK_IMPORTS, STREAM_TWITCH_IMPORTS, STREAM_USER_CONSENT_PROVIDER_TOKEN, STREAM_VIMEO_IMPORTS, STREAM_YOUTUBE_IMPORTS, STRIKETHROUGH_ICON, SUPPORT_CONTENT_STATE, SUPPORT_TRANSITION_DIRECTION, SWITCH_IMPORTS, SankeyChartComponent, SankeyChartDirective, SankeyChartMarkDirective, SchedulerActionAddAppointmentDirective, SchedulerAgendaDirective, SchedulerAgendaViewComponent, SchedulerAppointmentDragDirective, SchedulerBadgeChainCountComponent, SchedulerBadgeChainCountDirective, SchedulerBadgeColorDotComponent, SchedulerBadgeColorDotDirective, SchedulerBadgeLocationComponent, SchedulerBadgeLocationDirective, SchedulerBadgeTimeRangeComponent, SchedulerBadgeTimeRangeDirective, SchedulerBadgeTitleComponent, SchedulerBadgeTitleDirective, SchedulerComponent, SchedulerDirective, SchedulerEditAddSubAppointmentItemComponent, SchedulerEditColorComponent, SchedulerEditDeleteItemComponent, SchedulerEditDescriptionComponent, SchedulerEditLocationComponent, SchedulerEditSurfaceActionsComponent, SchedulerEditSurfaceBreadcrumbComponent, SchedulerEditSurfaceChildrenComponent, SchedulerEditSurfaceComponent, SchedulerEditSurfaceDirective, SchedulerEditSurfaceFieldsComponent, SchedulerEditSurfaceFooterComponent, SchedulerEditSurfaceHeaderComponent, SchedulerEditTimeRangeComponent, SchedulerEditTitleComponent, SchedulerMonthDirective, SchedulerMonthViewComponent, SchedulerSwipeNavigationDirective, SchedulerTimeGridDirective, SchedulerTimeGridViewComponent, ScrollableActiveChildDirective, ScrollableButtonsComponent, ScrollableButtonsDirective, ScrollableComponent, ScrollableDarkenDirective, ScrollableDirective, ScrollableDragDirective, ScrollableIgnoreChildDirective, ScrollableLoadingTemplateDirective, ScrollableMasksComponent, ScrollableNavigationComponent, ScrollableNavigationDirective, ScrollableSnapDirective, ScrollbarComponent, ScrollbarDirective, ScrollbarThumbDirective, SegmentedButtonComponent, SegmentedButtonGroupComponent, SelectAllOptionComponent, SelectAllOptionDirective, SelectComponent, SelectDirective, SelectEmptyDirective, SelectErrorDirective, SelectListboxDirective, SelectLoadingDirective, SelectOptionComponent, SelectOptionDirective, SelectOptionGroupComponent, SelectOptionGroupDirective, SelectOptionTemplateDirective, SelectOptionsDirective, SelectPanelComponent, SelectSearchDirective, SelectSurfaceDirective, SelectTriggerDirective, SelectValueDirective, SelectViewportDirective, SelectVirtualOptionComponent, SelectVirtualOptionDirective, SelectionListControlDirective, SelectionListDirective, SelectionOptionDirective, SkeletonComponent, SkeletonItemComponent, SkeletonTextComponent, SliderComponent, SliderDirective, SliderThumbDirective, SliderThumbLabelDirective, SliderTrackDirective, SoopPlayerComponent, SoopPlayerDirective, SoopPlayerParamsDirective, SoopPlayerSlotComponent, SpinnerComponent, SplitButtonActionDirective, SplitButtonComponent, SplitButtonDirective, SplitButtonTriggerDirective, StandingsComponent, StandingsDirective, StandingsPickComponent, StandingsPickDirective, StandingsPickMarkDirective, StatTileComponent, StatTileSparklineComponent, StreamConsentAcceptDirective, StreamConsentComponent, StreamConsentDirective, StreamPipChromeComponent, StreamPlayerErrorComponent, StreamPlayerErrorDirective, StreamPlayerLoadingComponent, StreamPlayerSlotDirective, SwitchComponent, SwitchDirective, TABLE_CELL_ERROR_TOOLTIP_IMPORTS, TABLE_COLUMN_CHOOSER_IMPORTS, TABLE_COLUMN_MENU_IMPORTS, TABLE_CSV_EXPORT_IMPORTS, TABLE_DRAG_SCROLL_IMPORTS, TABLE_ERROR_CODES, TABLE_FEATURE_HOST, TABLE_FILTER_IMPORTS, TABLE_GROUP_HEADERS_IMPORTS, TABLE_ICON, TABLE_IMPORTS, TABLE_INLINE_EDIT_IMPORTS, TABLE_KEYBOARD_NAV_IMPORTS, TABLE_LABELS, TABLE_PAGE_STICKY_HEADER_IMPORTS, TABLE_REORDER_IMPORTS, TABLE_RESIZE_IMPORTS, TABLE_ROW_EXPANSION_IMPORTS, TABLE_ROW_ROUTER_LINK_IMPORTS, TABLE_SELECTION_IMPORTS, TABLE_SKELETON_IMPORTS, TABLE_STATE_PERSISTENCE_IMPORTS, TABLE_STICKY_COLUMNS_IMPORTS, TABLE_VIRTUAL_SCROLL_IMPORTS, TAB_BAR_FITS, TAB_BAR_ORIENTATIONS, TAB_BAR_TOKEN, TAB_BAR_TRIGGER_TOKEN, TAB_BAR_VARIANTS, TAB_ERROR_CODES, TAB_GROUP_TOKEN, TAB_IMPORTS, TAB_PANEL_TOKEN, TAB_SIZES, TAG_INPUT_ERROR_CODES, TAG_INPUT_IMPORTS, TEXTAREA_IMPORTS, TEXTAREA_RESIZE_MODES, TEXT_ALIGNS, TEXT_FIELD_CONTROL_INPUTS, THUMBTACK_ICON, TIKTOK_PLAYER_TOKEN, TIMELINE_IMPORTS, TIMES_ICON, TIME_FORMAT, TIME_INPUT_ERROR_CODES, TIME_INPUT_IMPORTS, TIME_PICKER_ERROR_CODES, TIME_PICKER_IMPORTS, TIME_PICKER_LABELS, TIME_RANGE_INPUT_ERROR_CODES, TIME_RANGE_INPUT_IMPORTS, TOGGLETIP_ERROR_CODES, TOGGLETIP_IMPORTS, TOOLBAR_IMPORTS, TOOLBAR_ORIENTATIONS, TOOLTIP_ERROR_CODES, TOOLTIP_IMPORTS, TRASH_ICON, TREE_ERROR_CODES, TREE_IMPORTS, TREE_LABELS, TREE_LEVEL_STATUSES, TREE_MARKERS, TREE_SELECTION_MODES, TRIANGLE_EXCLAMATION_ICON, TROPHY_ICON, TWITCH_PLAYER_TOKEN, TabBarDirective, TabBarTriggerDirective, TabBarUnderlineDirective, TabComponent, TabGroupComponent, TabGroupDirective, TabLabelDirective, TabPanelDirective, TabTriggerDirective, TableCardSurfaceDirective, TableCellDirective, TableCellEditDirective, TableCellErrorMarkComponent, TableCellErrorTooltipDirective, TableCellSkeletonDirective, TableColumnChooserComponent, TableColumnMenuDirective, TableColumnMenuTriggerComponent, TableComponent, TableCsvExportDirective, TableDetailStylesComponent, TableDragScrollDirective, TableDragScrollStylesComponent, TableExpanderCellComponent, TableFilterOptionDirective, TableFilterTriggerComponent, TableFiltersDirective, TableFooterCellDirective, TableFooterDirective, TableGroupHeaderRowComponent, TableGroupHeadersDirective, TableHeaderCellDirective, TableInlineEditDirective, TableInlineEditStylesComponent, TableKeyboardNavDirective, TablePageStickyHeaderDirective, TablePageStickyHeaderStylesComponent, TableReorderDirective, TableReorderOverlayComponent, TableResizeDirective, TableResizeGripComponent, TableRowBoxStylesComponent, TableRowDetailComponent, TableRowExpansionDirective, TableRowRouterLinkDirective, TableSelectAllCellComponent, TableSelectCellComponent, TableSelectionDirective, TableSkeletonDirective, TableSkeletonRowsComponent, TableStatePersistenceDirective, TableStickyColumnsDirective, TableStickyColumnsStylesComponent, TableVirtualScrollDirective, TableVirtualScrollStylesComponent, TagInputComponent, TagInputDirective, TagInputFieldDirective, TextButtonComponent, TextFieldControlDirective, TextareaComponent, TextareaDirective, TikTokPlayerComponent, TikTokPlayerDirective, TikTokPlayerParamsDirective, TikTokPlayerSlotComponent, TimeInputComponent, TimeInputDirective, TimeInputFieldDirective, TimePickerComponent, TimePickerDirective, TimePickerRingDirective, TimePickerRingHandleDirective, TimeRangeInputComponent, TimeRangeInputDirective, TimeRangeInputFieldDirective, TimelineComponent, TimelineItemComponent, ToggletipCloseDirective, ToggletipComponent, ToggletipDirective, ToggletipTriggerDirective, ToolbarComponent, ToolbarDirective, TooltipComponent, TooltipDirective, TreeComponent, TreeDirective, TreeMarkerComponent, TreeNodeDefDirective, TreeNodeDirective, TwitchPlayerComponent, TwitchPlayerDirective, TwitchPlayerParamsDirective, TwitchPlayerSlotComponent, UNDERLINE_ICON, UNDO_ICON, UNSAVED_CHANGES_LABELS, UPLOAD_ICON, VIMEO_PLAYER_TOKEN, VimeoPlayerComponent, VimeoPlayerDirective, VimeoPlayerParamsDirective, VimeoPlayerSlotComponent, WCAG_CONTRAST_RATIOS, WINDOW_CONTROL_BUTTON_KINDS, WINDOW_CONTROL_BUTTON_SIZES, WindowControlButtonComponent, YOUTUBE_PLAYER_TOKEN, YoutubePlayerComponent, YoutubePlayerDirective, YoutubePlayerParamsDirective, YoutubePlayerSlotComponent, anchoredDialogOverlayStrategy, anchoredOverlayStrategy, bottomSheetOverlayStrategy, bracketFitsWidth, bracketNaturalWidth, buildAnchoredRuntimePositionStrategy, canHaveChildren, canonicalKbdKey, cascaderFromQuery, centeredOverlayStrategy, clearLeavingSupportStateOnExit, colorContrast, commandPaletteLabelsForLocale, countDescendants, createAlertDialogOpener, createAnchoredPanelController, createCardMask, createCommandPaletteOpener, createCurrencyMask, createDefaultDropzoneArgs, createDropzoneUpload, createExistingDropzoneEntry, createFileDropzoneEntry, createFixedLengthRangeStrategy, createGridAdapter, createIbanMask, createNormalizedBracketMatch, createNotificationPromiseFn, createNotificationRef, createOverlayOpener, createOverlaySingleSlot, createOverlayStrategyController, createOverlayUnsavedChangesGuard, createPipChromeAnimations, createPipChromeState, createRichTextEditorTrigger, createRichTextEditorTriggerWithQuery, createSchedulerRegistry, createStreamConfig, createStreamPlayerSlot, createTableRowsSource, createTableRowsState, createTableStateStorage, createV2DropzoneUpload, createWeekRangeStrategy, dateBounds, dateRangeBounds, dateRangeOrder, dateTimeBounds, dateTimeRangeBounds, dateTimeRangeOrder, defaultCompareWith$1 as defaultCompareWith, defaultDropzoneRejectionMessage, defaultSankeyChartLinkKeyHint, defineOverlay, defineQueryParamOverlay, describeBracketSlot, deserializeGridLayout, deserializeTableState, detectKbdPlatform, dialogOverlayStrategy, disposeDropzoneEntry, doubleEliminationBracketLayout, dropzoneFiles, enableDragToDismiss, extractFirstImageUrl, filterOverlayLabelsForLocale, filterOverlayPreviewFromQuery, filterRows, filterValues, findNextRelevantHtmlElement, focusFirstInvalidField, formatFileSize, fromGridPosition, fullScreenDialogOverlayStrategy, generateBracketDataForEthlete, generateRoundTypeFromEthleteRoundType, generateTournamentModeFromEthleteRounds, getClosestOverlay, getColorContrastRatio, getOriginCoordinatesAndDimensions, hexColor, hitsInteractiveElement, iconRegistryKey, injectAlertDialogLabels, injectAnchoredDialogStrategy, injectAnchoredDialogStrategyDefaults, injectAvatarLabels, injectBannerLabels, injectBottomSheetStrategy, injectBottomSheetStrategyDefaults, injectBracketConfig, injectBracketLabels, injectBreadcrumbLabels, injectBreadcrumbManager, injectCalendarLabels, injectCarouselLabels, injectCascaderLabels, injectChartLabels, injectChipLabels, injectColorInputLabels, injectCommandPalette, injectCommandPaletteLabels, injectCommandPaletteRegistry, injectCopyButtonLabels, injectDateFormat, injectDateLocale, injectDateTimeFormat, injectDateTimeLabels, injectDateTimeZone, injectDialogStrategy, injectDialogStrategyDefaults, injectDropzoneLabels, injectFilterOverlay, injectFilterOverlayLabels, injectFormFieldDefaults, injectFormFieldLabels, injectFormSupport, injectFullscreenDialogStrategy, injectFullscreenDialogStrategyDefaults, injectGridConfig, injectGridLabels, injectInputLabels, injectKbdLabels, injectLeftSheetStrategy, injectLeftSheetStrategyDefaults, injectLoaderLabels, injectMatchLabels, injectNotificationLabels, injectNotificationManager, injectNotificationManagerConfig, injectOverlayManager, injectOverlayRouter, injectOverlayScrollBlocker, injectOverlaySurfaceContext, injectPaginationLabels, injectPhoneInputLabels, injectPictureConfig, injectPipChromeManager, injectPipManager, injectPipSlotPlaceholderConfig, injectProgressStepLabels, injectQueryErrorLabels, injectRichTextEditorLabels, injectRichTextEditorTools, injectRightSheetStrategy, injectRightSheetStrategyDefaults, injectSchedulerEditSurface, injectSchedulerEditSurfaceOpener, injectSchedulerFeatureHost, injectSchedulerLabels, injectSelectLabels, injectSidebarOverlay, injectSliderLabels, injectStandingsLabels, injectStatTileLabels, injectStreamConfig, injectStreamConsentConfig, injectStreamLabels, injectStreamManager, injectStreamPlayerErrorConfig, injectStreamPlayerLoadingConfig, injectStreamPlayerSlot, injectStreamScriptLoader, injectStreamUserConsentProvider, injectTableCsvExport, injectTableFeatureHost, injectTableLabels, injectTimeFormat, injectTimePickerLabels, injectTopSheetStrategy, injectTopSheetStrategyDefaults, injectTreeLabels, injectUnsavedChangesLabels, isFileAccepted, isHtmlElement, isInteractiveElement, isPointerEvent, isRestorableTableState, isTargetInsideOverlayTree, isTouchEvent, kbdKeyLabel, kbdKeyName, lastDaysPreset, lastMonthPreset, lastWeekPreset, leftSheetOverlayStrategy, legacyQueryErrorSource, mapGridLayout, matchCountryByDialCode, matchParticipantDisplayName, matchedDialPrefix, matchesKbdChord, mergeOverlayBreakpointConfigs, mergeOverlayConfigs, mergeTableCsvExportOptions, mirroredDoubleEliminationBracketLayout, mirroredSingleEliminationBracketLayout, missingStreamSourceError, mountNavTabLinkStyles, nextDaysPreset, normalizeEthleteBracketMatch, normalizeEthleteGroupRanking, normalizeEthleteMatch, normalizeEthleteMatchStatus, normalizeEthleteMedia, normalizeEthleteParticipant, normalizeEthletePlacement, normalizePictureSizes, normalizePictureSource, numberInputStepMultiplierFrom, overlayResult, paginate, parseKbdKeys, phoneCountryFlag, phoneCountryName, provideAlertDialogLabels, provideAnchoredDialogStrategy, provideAnchoredDialogStrategyDefaults, provideAvatarLabels, provideBannerLabels, provideBottomSheetStrategy, provideBottomSheetStrategyDefaults, provideBracketConfig, provideBracketLabels, provideBreadcrumbLabels, provideBreadcrumbManager, provideCalendarLabels, provideCarouselLabels, provideCascaderLabels, provideChartLabels, provideChipLabels, provideColorInputLabels, provideCommandPaletteLabels, provideCommandPaletteRegistry, provideCopyButtonLabels, provideDateFormat, provideDateLocale, provideDateTimeFormat, provideDateTimeLabels, provideDateTimeZone, provideDialogStrategy, provideDialogStrategyDefaults, provideDropzoneLabels, provideFilterOverlay, provideFilterOverlayLabels, provideFormErrorMessageResolver, provideFormFieldDefaults, provideFormFieldLabels, provideFormSupport, provideFormWarningMessageResolver, provideFullscreenDialogStrategy, provideFullscreenDialogStrategyDefaults, provideGridConfig, provideGridLabels, provideIconOverrides, provideIcons, provideInputLabels, provideKbdLabels, provideLeftSheetStrategy, provideLeftSheetStrategyDefaults, provideLoaderLabels, provideMatchLabels, provideNotificationLabels, provideNotificationManager, provideNotificationManagerConfig, provideNotificationManagerInstance, provideOverlay, provideOverlayManager, provideOverlayRouter, provideOverlayRouterConfig, provideOverlayRouterService, provideOverlayScrollBlocker, providePaginationLabels, providePhoneInputLabels, providePictureConfig, providePipChromeManager, providePipManager, providePipSlotPlaceholderConfig, provideProgressStepLabels, provideQueryErrorLabels, provideRichTextEditorAlignmentTool, provideRichTextEditorAutoformat, provideRichTextEditorBlockquoteTool, provideRichTextEditorCodeBlockTool, provideRichTextEditorDefaultTools, provideRichTextEditorFloatingToolbar, provideRichTextEditorHeadingTool, provideRichTextEditorImageTool, provideRichTextEditorLabels, provideRichTextEditorLanguageTool, provideRichTextEditorLinkEditor, provideRichTextEditorLinkTool, provideRichTextEditorTableTool, provideRichTextEditorTokenRendering, provideRichTextEditorTool, provideRichTextEditorTools, provideRightSheetStrategy, provideRightSheetStrategyDefaults, provideSchedulerEditSurface, provideSchedulerLabels, provideSelectLabels, provideSidebarOverlay, provideSidebarOverlayConfig, provideSidebarOverlayService, provideSliderLabels, provideStandingsLabels, provideStatTileLabels, provideStreamConfig, provideStreamConsentConfig, provideStreamLabels, provideStreamManager, provideStreamPip, provideStreamPlayerErrorConfig, provideStreamPlayerLoadingConfig, provideTableLabels, provideTimeFormat, provideTimePickerLabels, provideTopSheetStrategy, provideTopSheetStrategyDefaults, provideTreeLabels, provideUnsavedChangesAlertDialog, provideUnsavedChangesLabels, queryButtonSourceFromV2Query, queryErrorLabelsForLocale, queryErrorResponseFromLegacyError, quickFilterRows, reconcileColumnOrder, reconcileColumnWidths, reconcileHiddenColumns, reduceSupportPresentation, registerCommands, registerSingleton, rejectionMessage, requiredLanguages, resolveBracketLayout, resolveClosestOverlay, resolveFilterOverlaySubmitButton, resolveNormalizedMatchSideState, resolveNotificationStatusIcon, resolveOverlayHasBackdrop, resolveTableCsvRows, rgbColor, richTextEditorToolLabel, rightSheetOverlayStrategy, schedulerFeatureConfig, selectOptionsFromQuery, selectOptionsFromV2Query, serializeGridLayout, serializeTableState, singleEliminationBracketLayout, sortRows, startOfCalendarUnit, stripTrunkZero, supportPresentationIncludesState, swissBracketLayout, tableCsvRowsFromPages, tableFeatureConfig, tableRowsFromQuery, tableRowsFromV2Query, tableToCsv, thisMonthPreset, thisWeekPreset, thisYearPreset, timeBounds, timeRangeBounds, timeRangeOrder, toFieldWarnings, toGridPosition, toNotificationContent, toPictureDimension, todayPreset, topSheetOverlayStrategy, transformingBottomSheetToDialogOverlayStrategy, transformingFullScreenDialogToDialogOverlayStrategy, transformingFullScreenDialogToRightSheetOverlayStrategy, warn, wireFormSupport, withPictureBaseUrl, yesterdayPreset };
75929
76402
  //# sourceMappingURL=ethlete-components.mjs.map