@tedi-design-system/angular 8.1.0-rc.7 → 8.1.0-rc.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, signal, inject, ElementRef, Directive, booleanAttribute, output, ViewContainerRef, Renderer2, effect, HostListener, Injectable, InjectionToken, model, isDevMode, forwardRef, contentChild, contentChildren, PLATFORM_ID, REQUEST, isSignal, Pipe, Injector, DestroyRef, HostAttributeToken, viewChild, NgZone, viewChildren, afterNextRender, afterRenderEffect, Optional, SkipSelf, untracked, ViewChild, TemplateRef, linkedSignal, HostBinding, runInInjectionContext, ContentChildren, RendererStyleFlags2, ContentChild, makeEnvironmentProviders } from '@angular/core';
2
+ import { input, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, signal, inject, ElementRef, Directive, booleanAttribute, output, ViewContainerRef, Renderer2, effect, HostListener, Injectable, InjectionToken, model, isDevMode, forwardRef, contentChild, contentChildren, PLATFORM_ID, REQUEST, isSignal, Pipe, Injector, DestroyRef, HostAttributeToken, viewChild, NgZone, viewChildren, afterNextRender, afterRenderEffect, Optional, SkipSelf, untracked, ViewChild, TemplateRef, numberAttribute, linkedSignal, HostBinding, runInInjectionContext, ContentChildren, RendererStyleFlags2, ContentChild, makeEnvironmentProviders } from '@angular/core';
3
3
  import { BreakpointObserver } from '@angular/cdk/layout';
4
4
  import * as i1 from '@angular/cdk/overlay';
5
5
  import { CdkOverlayOrigin, OverlayModule, Overlay, OverlayConfig, CdkConnectedOverlay } from '@angular/cdk/overlay';
@@ -8,7 +8,7 @@ import { DOCUMENT, isPlatformBrowser, isPlatformServer, NgTemplateOutlet, Common
8
8
  import { NG_VALUE_ACCESSOR, NgControl, Validators, FormsModule } from '@angular/forms';
9
9
  import { ComponentPortal } from '@angular/cdk/portal';
10
10
  import * as i2 from '@angular/cdk/a11y';
11
- import { _IdGenerator, CdkTrapFocus, A11yModule, LiveAnnouncer } from '@angular/cdk/a11y';
11
+ import { _IdGenerator, CdkTrapFocus, A11yModule, LiveAnnouncer, ActiveDescendantKeyManager } from '@angular/cdk/a11y';
12
12
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
13
13
  import { Dialog } from '@angular/cdk/dialog';
14
14
  import * as i1$2 from '@angular/cdk/scrolling';
@@ -1680,11 +1680,32 @@ const translationsMap = {
1680
1680
  },
1681
1681
  search: {
1682
1682
  description: "For searching",
1683
- components: ["TableFilter"],
1683
+ components: ["TableFilter", "Search"],
1684
1684
  et: "Otsi",
1685
1685
  en: "Search",
1686
1686
  ru: "Поиск",
1687
1687
  },
1688
+ "search.no-results": {
1689
+ description: "Shown in the search suggestions panel when nothing matched",
1690
+ components: ["Search"],
1691
+ et: "Tulemusi ei leitud",
1692
+ en: "No results found",
1693
+ ru: "Результаты не найдены",
1694
+ },
1695
+ "search.loading": {
1696
+ description: "Shown in the search suggestions panel while results load",
1697
+ components: ["Search"],
1698
+ et: "Otsin...",
1699
+ en: "Searching...",
1700
+ ru: "Поиск...",
1701
+ },
1702
+ "search.results-count": {
1703
+ description: "Announced politely to screen readers when the number of Search suggestions changes",
1704
+ components: ["Search"],
1705
+ et: (count) => `${count} ${count === 1 ? "vaste" : "vastet"}`,
1706
+ en: (count) => `${count} ${count === 1 ? "result" : "results"}`,
1707
+ ru: (count) => `Совпадений: ${count}`,
1708
+ },
1688
1709
  required: {
1689
1710
  description: "Required field",
1690
1711
  components: ["TableFilter"],
@@ -2346,7 +2367,7 @@ const translationsMap = {
2346
2367
  components: ["Table", "Pagination"],
2347
2368
  et: (count) => `${count ?? 0} ${count === 1 ? "tulemus" : "tulemust"}`,
2348
2369
  en: (count) => `${count ?? 0} ${count === 1 ? "result" : "results"}`,
2349
- ru: (count) => `${count ?? 0} ${count === 1 ? "результат" : "результа"}`,
2370
+ ru: (count) => `Результатов: ${count ?? 0}`,
2350
2371
  },
2351
2372
  "pagination.page-size": {
2352
2373
  description: "Label of page size select",
@@ -4988,6 +5009,72 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImpo
4988
5009
  }, template: "<ng-content></ng-content>\n", styles: ["@charset \"UTF-8\";.tedi-card-header--background--accent{background-color:var(--card-background-accent)}.tedi-card-header--background--brand-primary{background-color:var(--card-background-brand-primary)}.tedi-card-header--background--brand-secondary{background-color:var(--card-background-brand-secondary)}.tedi-card-header--background--brand-tertiary{background-color:var(--card-background-brand-tertiary)}.tedi-card-header--background--brand-quaternary{background-color:var(--card-background-brand-quaternary)}.tedi-card-header--background--primary{background-color:var(--card-background-primary)}.tedi-card-header--background--secondary{background-color:var(--card-background-secondary)}.tedi-card-header--background--tertiary{background-color:var(--card-background-tertiary)}.tedi-card-header--background--info-primary{background-color:var(--general-status-info-background-light)}.tedi-card-header--background--info-secondary{background-color:var(--general-status-info-background-dark)}.tedi-card-header--background--neutral-primary{background-color:var(--general-status-neutral-background-light)}.tedi-card-header--background--neutral-secondary{background-color:var(--general-status-neutral-background-dark)}.tedi-card-header--background--success-primary{background-color:var(--card-background-success)}.tedi-card-header--background--success-secondary{background-color:var(--general-status-success-background-secondary)}.tedi-card-header--background--danger-primary{background-color:var(--general-status-danger-background-primary)}.tedi-card-header--background--danger-secondary{background-color:var(--general-status-danger-background-secondary)}.tedi-card-header--background--warning-primary{background-color:var(--general-status-warning-background-light)}.tedi-card-header--background--warning-secondary{background-color:var(--general-status-warning-background-dark)}.tedi-card-header--background--brand-primary,.tedi-card-header--background--brand-secondary{color:var(--general-text-white)}.tedi-card-header{display:block;flex:0 0 auto;padding:var(--card-content-padding-top) var(--card-content-padding-right) var(--card-content-padding-bottom) var(--card-content-padding-left)}@media print{.tedi-card-header{color:var(--general-text-primary);background:var(--card-background-primary);border-bottom:1px solid var(--card-border-primary)}}\n"] }]
4989
5010
  }] });
4990
5011
 
5012
+ const isHeadingModifier = (modifier) => /^h[1-6]$/.test(modifier);
5013
+ class HeadingWithIconComponent {
5014
+ /**
5015
+ * Name of the Material Icon
5016
+ * https://fonts.google.com/icons
5017
+ *
5018
+ * Rendered as decorative and hidden from assistive technology — the
5019
+ * projected text is the accessible heading name.
5020
+ */
5021
+ icon = input.required(...(ngDevMode ? [{ debugName: "icon" }] : []));
5022
+ /**
5023
+ * Semantic heading tag. Also sets the typography unless a heading modifier
5024
+ * overrides it, so pick the tag that fits the surrounding document outline.
5025
+ * @default h4
5026
+ */
5027
+ element = input("h4", ...(ngDevMode ? [{ debugName: "element" }] : []));
5028
+ /**
5029
+ * Single or multiple modifiers to change the heading behavior. A heading
5030
+ * modifier here styles the heading as that level while `element` keeps the
5031
+ * semantics — e.g. an `h2` that looks like an `h4`.
5032
+ */
5033
+ modifiers = input(...(ngDevMode ? [undefined, { debugName: "modifiers" }] : []));
5034
+ /**
5035
+ * Heading text color.
5036
+ * @default primary
5037
+ */
5038
+ headingColor = input("primary", ...(ngDevMode ? [{ debugName: "headingColor" }] : []));
5039
+ /**
5040
+ * Color of the icon.
5041
+ * @default primary
5042
+ */
5043
+ iconColor = input("primary", ...(ngDevMode ? [{ debugName: "iconColor" }] : []));
5044
+ /**
5045
+ * Size of the icon in pixels.
5046
+ * @default 24
5047
+ */
5048
+ iconSize = input(24, ...(ngDevMode ? [{ debugName: "iconSize" }] : []));
5049
+ /**
5050
+ * Whether the icon should be filled or outlined.
5051
+ * @default outlined
5052
+ */
5053
+ iconVariant = input("outlined", ...(ngDevMode ? [{ debugName: "iconVariant" }] : []));
5054
+ // A heading modifier wins on specificity over the `element` tag in core's CSS,
5055
+ // so `element="h2" modifiers="h4"` renders at h4's line height — which is what
5056
+ // the icon has to be centered against.
5057
+ visualLevel = computed(() => {
5058
+ const modifiers = this.modifiers();
5059
+ const modifierList = Array.isArray(modifiers)
5060
+ ? modifiers
5061
+ : modifiers
5062
+ ? [modifiers]
5063
+ : [];
5064
+ return modifierList.find(isHeadingModifier) ?? this.element();
5065
+ }, ...(ngDevMode ? [{ debugName: "visualLevel" }] : []));
5066
+ lineHeightVar = computed(() => `var(--heading-${this.visualLevel()}-line-height)`, ...(ngDevMode ? [{ debugName: "lineHeightVar" }] : []));
5067
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: HeadingWithIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5068
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: HeadingWithIconComponent, isStandalone: true, selector: "tedi-heading-with-icon", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, element: { classPropertyName: "element", publicName: "element", isSignal: true, isRequired: false, transformFunction: null }, modifiers: { classPropertyName: "modifiers", publicName: "modifiers", isSignal: true, isRequired: false, transformFunction: null }, headingColor: { classPropertyName: "headingColor", publicName: "headingColor", isSignal: true, isRequired: false, transformFunction: null }, iconColor: { classPropertyName: "iconColor", publicName: "iconColor", isSignal: true, isRequired: false, transformFunction: null }, iconSize: { classPropertyName: "iconSize", publicName: "iconSize", isSignal: true, isRequired: false, transformFunction: null }, iconVariant: { classPropertyName: "iconVariant", publicName: "iconVariant", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.--_tedi-heading-with-icon-line-height": "lineHeightVar()" }, classAttribute: "tedi-heading-with-icon" }, ngImport: i0, template: "<tedi-icon\n class=\"tedi-heading-with-icon__icon\"\n [name]=\"icon()\"\n [color]=\"iconColor()\"\n [size]=\"iconSize()\"\n [variant]=\"iconVariant()\"\n/>\n\n@switch (element()) {\n @case (\"h1\") {\n <h1\n tedi-text\n class=\"tedi-heading-with-icon__heading\"\n [color]=\"headingColor()\"\n [modifiers]=\"modifiers()\"\n >\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n </h1>\n }\n @case (\"h2\") {\n <h2\n tedi-text\n class=\"tedi-heading-with-icon__heading\"\n [color]=\"headingColor()\"\n [modifiers]=\"modifiers()\"\n >\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n </h2>\n }\n @case (\"h3\") {\n <h3\n tedi-text\n class=\"tedi-heading-with-icon__heading\"\n [color]=\"headingColor()\"\n [modifiers]=\"modifiers()\"\n >\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n </h3>\n }\n @case (\"h4\") {\n <h4\n tedi-text\n class=\"tedi-heading-with-icon__heading\"\n [color]=\"headingColor()\"\n [modifiers]=\"modifiers()\"\n >\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n </h4>\n }\n @case (\"h5\") {\n <h5\n tedi-text\n class=\"tedi-heading-with-icon__heading\"\n [color]=\"headingColor()\"\n [modifiers]=\"modifiers()\"\n >\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n </h5>\n }\n @case (\"h6\") {\n <h6\n tedi-text\n class=\"tedi-heading-with-icon__heading\"\n [color]=\"headingColor()\"\n [modifiers]=\"modifiers()\"\n >\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n </h6>\n }\n}\n\n<ng-template #heading><ng-content></ng-content></ng-template>\n", styles: [".tedi-heading-with-icon{display:flex;gap:var(--content-heading-inner-spacing-x);align-items:flex-start}.tedi-heading-with-icon__icon{height:var(--_tedi-heading-with-icon-line-height)}.tedi-heading-with-icon__heading{flex:1;min-width:0;overflow-wrap:break-word}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "tedi-icon", inputs: ["name", "size", "color", "background", "variant", "type", "label"] }, { kind: "component", type: TextComponent, selector: "[tedi-text]", inputs: ["modifiers", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
5069
+ }
5070
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: HeadingWithIconComponent, decorators: [{
5071
+ type: Component,
5072
+ args: [{ selector: "tedi-heading-with-icon", standalone: true, imports: [NgTemplateOutlet, IconComponent, TextComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
5073
+ class: "tedi-heading-with-icon",
5074
+ "[style.--_tedi-heading-with-icon-line-height]": "lineHeightVar()",
5075
+ }, template: "<tedi-icon\n class=\"tedi-heading-with-icon__icon\"\n [name]=\"icon()\"\n [color]=\"iconColor()\"\n [size]=\"iconSize()\"\n [variant]=\"iconVariant()\"\n/>\n\n@switch (element()) {\n @case (\"h1\") {\n <h1\n tedi-text\n class=\"tedi-heading-with-icon__heading\"\n [color]=\"headingColor()\"\n [modifiers]=\"modifiers()\"\n >\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n </h1>\n }\n @case (\"h2\") {\n <h2\n tedi-text\n class=\"tedi-heading-with-icon__heading\"\n [color]=\"headingColor()\"\n [modifiers]=\"modifiers()\"\n >\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n </h2>\n }\n @case (\"h3\") {\n <h3\n tedi-text\n class=\"tedi-heading-with-icon__heading\"\n [color]=\"headingColor()\"\n [modifiers]=\"modifiers()\"\n >\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n </h3>\n }\n @case (\"h4\") {\n <h4\n tedi-text\n class=\"tedi-heading-with-icon__heading\"\n [color]=\"headingColor()\"\n [modifiers]=\"modifiers()\"\n >\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n </h4>\n }\n @case (\"h5\") {\n <h5\n tedi-text\n class=\"tedi-heading-with-icon__heading\"\n [color]=\"headingColor()\"\n [modifiers]=\"modifiers()\"\n >\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n </h5>\n }\n @case (\"h6\") {\n <h6\n tedi-text\n class=\"tedi-heading-with-icon__heading\"\n [color]=\"headingColor()\"\n [modifiers]=\"modifiers()\"\n >\n <ng-container *ngTemplateOutlet=\"heading\"></ng-container>\n </h6>\n }\n}\n\n<ng-template #heading><ng-content></ng-content></ng-template>\n", styles: [".tedi-heading-with-icon{display:flex;gap:var(--content-heading-inner-spacing-x);align-items:flex-start}.tedi-heading-with-icon__icon{height:var(--_tedi-heading-with-icon-line-height)}.tedi-heading-with-icon__heading{flex:1;min-width:0;overflow-wrap:break-word}\n"] }]
5076
+ }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: true }] }], element: [{ type: i0.Input, args: [{ isSignal: true, alias: "element", required: false }] }], modifiers: [{ type: i0.Input, args: [{ isSignal: true, alias: "modifiers", required: false }] }], headingColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "headingColor", required: false }] }], iconColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconColor", required: false }] }], iconSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconSize", required: false }] }], iconVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconVariant", required: false }] }] } });
5077
+
4991
5078
  class ListComponent {
4992
5079
  /**
4993
5080
  * Is list styled?
@@ -11196,6 +11283,159 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImpo
11196
11283
  descendants: true,
11197
11284
  }, isSignal: true }] }] } });
11198
11285
 
11286
+ /** Splits `text` so the segment matching `query` can be emphasised. */
11287
+ function highlightParts(text, query) {
11288
+ const trimmed = query.trim();
11289
+ const index = trimmed
11290
+ ? text.toLowerCase().indexOf(trimmed.toLowerCase())
11291
+ : -1;
11292
+ if (index === -1) {
11293
+ return [{ text, match: false }];
11294
+ }
11295
+ const parts = [];
11296
+ if (index > 0) {
11297
+ parts.push({ text: text.slice(0, index), match: false });
11298
+ }
11299
+ parts.push({
11300
+ text: text.slice(index, index + trimmed.length),
11301
+ match: true,
11302
+ });
11303
+ if (index + trimmed.length < text.length) {
11304
+ parts.push({ text: text.slice(index + trimmed.length), match: false });
11305
+ }
11306
+ return parts;
11307
+ }
11308
+
11309
+ class SearchSuggestionComponent {
11310
+ /** Resolved display label. */
11311
+ label = input("", ...(ngDevMode ? [{ debugName: "label" }] : []));
11312
+ /** Secondary line under the label. */
11313
+ description = input("", ...(ngDevMode ? [{ debugName: "description" }] : []));
11314
+ /** Current field value, used to bold the matching segment. */
11315
+ query = input("", ...(ngDevMode ? [{ debugName: "query" }] : []));
11316
+ /** Whether a custom suggestion template supplies the row content. */
11317
+ custom = input(false, ...(ngDevMode ? [{ debugName: "custom", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
11318
+ disabledInput = input(false, ...(ngDevMode ? [{ debugName: "disabledInput",
11319
+ // eslint-disable-next-line @angular-eslint/no-input-rename
11320
+ alias: "disabled",
11321
+ transform: booleanAttribute }] : [{
11322
+ // eslint-disable-next-line @angular-eslint/no-input-rename
11323
+ alias: "disabled",
11324
+ transform: booleanAttribute,
11325
+ }]));
11326
+ host = inject(ElementRef);
11327
+ active = signal(false, ...(ngDevMode ? [{ debugName: "active" }] : []));
11328
+ isActive = this.active.asReadonly();
11329
+ parts = computed(() => highlightParts(this.label(), this.query()), ...(ngDevMode ? [{ debugName: "parts" }] : []));
11330
+ /**
11331
+ * `Highlightable` requires a plain boolean, so the signal input is aliased and
11332
+ * this getter satisfies the CDK contract — a signal would always read truthy.
11333
+ */
11334
+ get disabled() {
11335
+ return this.disabledInput();
11336
+ }
11337
+ setActiveStyles() {
11338
+ this.active.set(true);
11339
+ }
11340
+ setInactiveStyles() {
11341
+ this.active.set(false);
11342
+ }
11343
+ getLabel() {
11344
+ return this.label();
11345
+ }
11346
+ scrollIntoView() {
11347
+ this.host.nativeElement.scrollIntoView({
11348
+ block: "nearest",
11349
+ inline: "nearest",
11350
+ });
11351
+ }
11352
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SearchSuggestionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11353
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: SearchSuggestionComponent, isStandalone: true, selector: "li[tedi-search-suggestion]", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, query: { classPropertyName: "query", publicName: "query", isSignal: true, isRequired: false, transformFunction: null }, custom: { classPropertyName: "custom", publicName: "custom", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "option", "tabindex": "-1" }, properties: { "class.tedi-search-suggestion--active": "isActive()", "class.tedi-search-suggestion--custom": "custom()", "class.tedi-search-suggestion--disabled": "disabledInput()", "attr.aria-selected": "isActive()", "attr.aria-disabled": "disabledInput() || null" }, classAttribute: "tedi-search-suggestion" }, ngImport: i0, template: "@if (custom()) {\n <ng-content />\n} @else {\n <span class=\"tedi-search-suggestion__label\">\n @for (part of parts(); track $index) {\n <span tedi-text [modifiers]=\"part.match ? 'bold' : undefined\">{{\n part.text\n }}</span>\n }\n </span>\n\n @if (description()) {\n <span\n tedi-text\n class=\"tedi-search-suggestion__description\"\n color=\"tertiary\"\n modifiers=\"small\"\n >{{ description() }}</span\n >\n }\n}\n", styles: [".tedi-search-suggestion{display:block;padding:var(--dropdown-item-padding-y) var(--dropdown-item-padding-x);color:inherit;cursor:pointer;background:transparent}.tedi-search-suggestion:hover,.tedi-search-suggestion--active{background:var(--dropdown-item-hover-background)}.tedi-search-suggestion--custom{display:flex;gap:var(--dropdown-item-inner-spacing);align-items:center}.tedi-search-suggestion--disabled,.tedi-search-suggestion--disabled:hover{color:var(--general-text-disabled);cursor:not-allowed;background:var(--dropdown-item-disabled-background)}.tedi-search-suggestion--disabled [class*=tedi-text--]{color:inherit}.tedi-search-suggestion__label,.tedi-search-suggestion__description{display:block}\n"], dependencies: [{ kind: "component", type: TextComponent, selector: "[tedi-text]", inputs: ["modifiers", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
11354
+ }
11355
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SearchSuggestionComponent, decorators: [{
11356
+ type: Component,
11357
+ args: [{ selector: "li[tedi-search-suggestion]", standalone: true, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TextComponent], host: {
11358
+ class: "tedi-search-suggestion",
11359
+ role: "option",
11360
+ tabindex: "-1",
11361
+ "[class.tedi-search-suggestion--active]": "isActive()",
11362
+ "[class.tedi-search-suggestion--custom]": "custom()",
11363
+ "[class.tedi-search-suggestion--disabled]": "disabledInput()",
11364
+ "[attr.aria-selected]": "isActive()",
11365
+ "[attr.aria-disabled]": "disabledInput() || null",
11366
+ }, template: "@if (custom()) {\n <ng-content />\n} @else {\n <span class=\"tedi-search-suggestion__label\">\n @for (part of parts(); track $index) {\n <span tedi-text [modifiers]=\"part.match ? 'bold' : undefined\">{{\n part.text\n }}</span>\n }\n </span>\n\n @if (description()) {\n <span\n tedi-text\n class=\"tedi-search-suggestion__description\"\n color=\"tertiary\"\n modifiers=\"small\"\n >{{ description() }}</span\n >\n }\n}\n", styles: [".tedi-search-suggestion{display:block;padding:var(--dropdown-item-padding-y) var(--dropdown-item-padding-x);color:inherit;cursor:pointer;background:transparent}.tedi-search-suggestion:hover,.tedi-search-suggestion--active{background:var(--dropdown-item-hover-background)}.tedi-search-suggestion--custom{display:flex;gap:var(--dropdown-item-inner-spacing);align-items:center}.tedi-search-suggestion--disabled,.tedi-search-suggestion--disabled:hover{color:var(--general-text-disabled);cursor:not-allowed;background:var(--dropdown-item-disabled-background)}.tedi-search-suggestion--disabled [class*=tedi-text--]{color:inherit}.tedi-search-suggestion__label,.tedi-search-suggestion__description{display:block}\n"] }]
11367
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], query: [{ type: i0.Input, args: [{ isSignal: true, alias: "query", required: false }] }], custom: [{ type: i0.Input, args: [{ isSignal: true, alias: "custom", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
11368
+
11369
+ /**
11370
+ * Renders each suggestion row. Without it, rows show the resolved label with the
11371
+ * matched substring bolded.
11372
+ *
11373
+ * @example
11374
+ * ```html
11375
+ * <tedi-search [suggestions]="people" bindLabel="name">
11376
+ * <ng-template tediSearchSuggestion let-item>
11377
+ * <span tedi-text modifiers="bold">{{ item.name }}</span>
11378
+ * <span tedi-text color="tertiary">{{ item.code }}</span>
11379
+ * </ng-template>
11380
+ * </tedi-search>
11381
+ * ```
11382
+ */
11383
+ class SearchSuggestionTemplateDirective {
11384
+ template = inject(TemplateRef);
11385
+ static ngTemplateContextGuard(_dir, _ctx) {
11386
+ return true;
11387
+ }
11388
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SearchSuggestionTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
11389
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.24", type: SearchSuggestionTemplateDirective, isStandalone: true, selector: "[tediSearchSuggestion]", ngImport: i0 });
11390
+ }
11391
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SearchSuggestionTemplateDirective, decorators: [{
11392
+ type: Directive,
11393
+ args: [{
11394
+ selector: "[tediSearchSuggestion]",
11395
+ standalone: true,
11396
+ }]
11397
+ }] });
11398
+ /**
11399
+ * Extra content pinned below the suggestions — fallback actions and a hint, for
11400
+ * example. It shows whenever the panel is open, including the no-results state,
11401
+ * which is what makes it useful for "nothing matched, try this instead".
11402
+ *
11403
+ * Suggestions keep behaving exactly as they do without it: filtering, arrow-key
11404
+ * navigation and Enter to select are unchanged. Tab moves from the field into the
11405
+ * footer's controls.
11406
+ *
11407
+ * @example
11408
+ * ```html
11409
+ * <tedi-search [suggestions]="matches()">
11410
+ * <ng-template tediSearchFooter>
11411
+ * <tedi-search-footer-actions>
11412
+ * <button tedi-button variant="secondary">Isik teadmata</button>
11413
+ * </tedi-search-footer-actions>
11414
+ * </ng-template>
11415
+ * </tedi-search>
11416
+ * ```
11417
+ */
11418
+ class SearchFooterTemplateDirective {
11419
+ template = inject(TemplateRef);
11420
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SearchFooterTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
11421
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.24", type: SearchFooterTemplateDirective, isStandalone: true, selector: "[tediSearchFooter]", ngImport: i0 });
11422
+ }
11423
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SearchFooterTemplateDirective, decorators: [{
11424
+ type: Directive,
11425
+ args: [{
11426
+ selector: "[tediSearchFooter]",
11427
+ standalone: true,
11428
+ }]
11429
+ }] });
11430
+
11431
+ /**
11432
+ * Flush against the field, flipping above when it would overflow. The panel
11433
+ * border meets the field border, so there is no offset.
11434
+ */
11435
+ const SEARCH_OVERLAY_POSITIONS = [
11436
+ { originX: "start", originY: "bottom", overlayX: "start", overlayY: "top" },
11437
+ { originX: "start", originY: "top", overlayX: "start", overlayY: "bottom" },
11438
+ ];
11199
11439
  class SearchComponent {
11200
11440
  /**
11201
11441
  * Unique identifier for the input element, used to associate the label.
@@ -11246,6 +11486,62 @@ class SearchComponent {
11246
11486
  * `placeholder`, then the translated "search" label.
11247
11487
  */
11248
11488
  ariaLabel = input(...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : []));
11489
+ /**
11490
+ * Suggestions to show in the panel, already filtered by the consumer. Bind an
11491
+ * empty array to keep the combobox behaviour while nothing matches; leave it
11492
+ * unbound for a plain search field.
11493
+ */
11494
+ suggestions = input(undefined, ...(ngDevMode ? [{ debugName: "suggestions" }] : []));
11495
+ /**
11496
+ * Property holding the display label when suggestions are objects.
11497
+ * @default "label"
11498
+ */
11499
+ bindLabel = input("label", ...(ngDevMode ? [{ debugName: "bindLabel" }] : []));
11500
+ /**
11501
+ * Property holding a secondary line shown under the label. Unset by default,
11502
+ * so rows are a single line unless asked for.
11503
+ */
11504
+ bindDescription = input(...(ngDevMode ? [undefined, { debugName: "bindDescription" }] : []));
11505
+ /**
11506
+ * Property marking a suggestion as unselectable. Disabled rows are greyed out
11507
+ * and skipped by keyboard navigation.
11508
+ * @default "disabled"
11509
+ */
11510
+ bindDisabled = input("disabled", ...(ngDevMode ? [{ debugName: "bindDisabled" }] : []));
11511
+ /**
11512
+ * Characters required before the panel opens. Below it nothing is shown, not
11513
+ * even the no-results row, so short queries stay quiet.
11514
+ * @default 0
11515
+ */
11516
+ minQueryLength = input(0, ...(ngDevMode ? [{ debugName: "minQueryLength", transform: numberAttribute }] : [{ transform: numberAttribute }]));
11517
+ /**
11518
+ * Shows a loading row instead of results.
11519
+ * @default false
11520
+ */
11521
+ loading = input(false, ...(ngDevMode ? [{ debugName: "loading", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
11522
+ /**
11523
+ * Closes the suggestion panel when the page (or a scrollable ancestor)
11524
+ * scrolls. Scrolling the option list itself keeps the panel open.
11525
+ * @default false
11526
+ */
11527
+ hideOnScroll = input(false, ...(ngDevMode ? [{ debugName: "hideOnScroll", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
11528
+ /**
11529
+ * Whether the suggestion panel is open.
11530
+ * @default false
11531
+ */
11532
+ panelOpen = model(false, ...(ngDevMode ? [{ debugName: "panelOpen" }] : []));
11533
+ /**
11534
+ * Overrides the translated "no results" row.
11535
+ */
11536
+ noResultsText = input(...(ngDevMode ? [undefined, { debugName: "noResultsText" }] : []));
11537
+ /**
11538
+ * Overrides the translated loading row.
11539
+ */
11540
+ loadingText = input(...(ngDevMode ? [undefined, { debugName: "loadingText" }] : []));
11541
+ /**
11542
+ * Overrides the translated screen-reader result count.
11543
+ */
11544
+ resultsCountText = input(...(ngDevMode ? [undefined, { debugName: "resultsCountText" }] : []));
11249
11545
  /**
11250
11546
  * Emitted when the search is executed (Enter key or button click).
11251
11547
  */
@@ -11254,11 +11550,41 @@ class SearchComponent {
11254
11550
  * Emitted when the clear button is clicked.
11255
11551
  */
11256
11552
  clear = output();
11553
+ /**
11554
+ * Emitted when a suggestion is accepted. The field is filled with its label.
11555
+ */
11556
+ suggestionSelect = output();
11557
+ suggestionTemplate = contentChild(SearchSuggestionTemplateDirective, ...(ngDevMode ? [{ debugName: "suggestionTemplate" }] : []));
11558
+ footerTemplate = contentChild(SearchFooterTemplateDirective, ...(ngDevMode ? [{ debugName: "footerTemplate" }] : []));
11257
11559
  inputRef = viewChild("searchInput", ...(ngDevMode ? [{ debugName: "inputRef", read: ElementRef }] : [{ read: ElementRef }]));
11560
+ overlayOrigin = viewChild.required(CdkOverlayOrigin);
11561
+ connectedOverlay = viewChild(CdkConnectedOverlay, ...(ngDevMode ? [{ debugName: "connectedOverlay" }] : []));
11562
+ suggestionRows = viewChildren(SearchSuggestionComponent, ...(ngDevMode ? [{ debugName: "suggestionRows" }] : []));
11258
11563
  formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "formDisabled" }] : []));
11564
+ hostElement = inject(ElementRef);
11259
11565
  translationService = inject(TediTranslationService);
11566
+ renderer = inject(Renderer2);
11567
+ document = inject(DOCUMENT);
11568
+ injector = inject(Injector);
11569
+ scrollListener;
11260
11570
  onChange = () => { };
11261
11571
  onTouched = () => { };
11572
+ /** Suppresses the focus-driven reopen after a selection, until the next edit. */
11573
+ justSelected = false;
11574
+ /**
11575
+ * Navigation is driven from `event.key` via the explicit `set*ItemActive`
11576
+ * methods rather than `keyManager.onKeydown`, which switches on the deprecated
11577
+ * `event.keyCode` and so ignores synthesised events.
11578
+ */
11579
+ keyManager = new ActiveDescendantKeyManager(this.suggestionRows, this.injector).withWrap();
11580
+ activeIndex = signal(-1, ...(ngDevMode ? [{ debugName: "activeIndex" }] : []));
11581
+ overlayPositions = SEARCH_OVERLAY_POSITIONS;
11582
+ panelWidth = signal(0, ...(ngDevMode ? [{ debugName: "panelWidth" }] : []));
11583
+ /**
11584
+ * True while the panel sits above the field on the fallback position, so the
11585
+ * rounded edge can move to the side that is not joined to the field.
11586
+ */
11587
+ panelAbove = signal(false, ...(ngDevMode ? [{ debugName: "panelAbove" }] : []));
11262
11588
  isDisabled = computed(() => this.disabled() || this.formDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
11263
11589
  fieldIcon = computed(() => this.button() ? undefined : this.searchIcon(), ...(ngDevMode ? [{ debugName: "fieldIcon" }] : []));
11264
11590
  fieldHeight = computed(() => {
@@ -11290,9 +11616,90 @@ class SearchComponent {
11290
11616
  * otherwise `aria-label` would silently override the visible text.
11291
11617
  */
11292
11618
  inputAriaLabel = computed(() => this.label() ? null : this.searchAriaLabel(), ...(ngDevMode ? [{ debugName: "inputAriaLabel" }] : []));
11619
+ /**
11620
+ * Derived from capability, never from current content — an empty
11621
+ * `suggestions` array still means the consumer opted into the combobox.
11622
+ */
11623
+ autocomplete = computed(() => this.suggestions() !== undefined, ...(ngDevMode ? [{ debugName: "autocomplete" }] : []));
11624
+ resolvedSuggestions = computed(() => {
11625
+ const items = this.suggestions() ?? [];
11626
+ const bindLabel = this.bindLabel();
11627
+ const bindDescription = this.bindDescription();
11628
+ const bindDisabled = this.bindDisabled();
11629
+ return items.map((item) => {
11630
+ const record = item !== null && typeof item === "object"
11631
+ ? item
11632
+ : undefined;
11633
+ return {
11634
+ item,
11635
+ label: record ? String(record[bindLabel] ?? item) : String(item),
11636
+ description: record && bindDescription
11637
+ ? String(record[bindDescription] ?? "")
11638
+ : "",
11639
+ disabled: !!record?.[bindDisabled],
11640
+ };
11641
+ });
11642
+ }, ...(ngDevMode ? [{ debugName: "resolvedSuggestions" }] : []));
11643
+ query = computed(() => this.value().trim(), ...(ngDevMode ? [{ debugName: "query" }] : []));
11644
+ hasSuggestions = computed(() => !this.loading() && this.resolvedSuggestions().length > 0, ...(ngDevMode ? [{ debugName: "hasSuggestions" }] : []));
11645
+ listboxId = computed(() => `${this.inputId()}-listbox`, ...(ngDevMode ? [{ debugName: "listboxId" }] : []));
11646
+ meetsMinQueryLength = computed(() => this.query().length >= this.minQueryLength(), ...(ngDevMode ? [{ debugName: "meetsMinQueryLength" }] : []));
11647
+ panelVisible = computed(() => {
11648
+ if (!this.autocomplete() || !this.panelOpen())
11649
+ return false;
11650
+ if (!this.meetsMinQueryLength())
11651
+ return false;
11652
+ return this.loading() || this.hasSuggestions() || this.query().length > 0;
11653
+ }, ...(ngDevMode ? [{ debugName: "panelVisible" }] : []));
11654
+ inputRole = computed(() => this.autocomplete() ? "combobox" : "searchbox", ...(ngDevMode ? [{ debugName: "inputRole" }] : []));
11655
+ ariaAutocomplete = computed(() => this.autocomplete() ? "list" : null, ...(ngDevMode ? [{ debugName: "ariaAutocomplete" }] : []));
11656
+ ariaExpanded = computed(() => this.autocomplete() ? this.panelVisible() : null, ...(ngDevMode ? [{ debugName: "ariaExpanded" }] : []));
11657
+ ariaControls = computed(() => this.panelVisible() && this.hasSuggestions() ? this.listboxId() : null, ...(ngDevMode ? [{ debugName: "ariaControls" }] : []));
11658
+ activeOptionId = computed(() => {
11659
+ const index = this.activeIndex();
11660
+ return index >= 0 ? this.optionId(index) : null;
11661
+ }, ...(ngDevMode ? [{ debugName: "activeOptionId" }] : []));
11662
+ resolvedNoResultsText = computed(() => this.noResultsText() ??
11663
+ this.translationService.translate("search.no-results"), ...(ngDevMode ? [{ debugName: "resolvedNoResultsText" }] : []));
11664
+ resolvedLoadingText = computed(() => this.loadingText() ?? this.translationService.translate("search.loading"), ...(ngDevMode ? [{ debugName: "resolvedLoadingText" }] : []));
11665
+ announcement = computed(() => {
11666
+ if (!this.panelVisible())
11667
+ return "";
11668
+ if (this.loading())
11669
+ return this.resolvedLoadingText();
11670
+ const count = this.resolvedSuggestions().length;
11671
+ if (!count)
11672
+ return this.resolvedNoResultsText();
11673
+ const override = this.resultsCountText();
11674
+ return override
11675
+ ? override(count)
11676
+ : this.translationService.translate("search.results-count", count);
11677
+ }, ...(ngDevMode ? [{ debugName: "announcement" }] : []));
11678
+ constructor() {
11679
+ this.keyManager.change.pipe(takeUntilDestroyed()).subscribe((index) => {
11680
+ this.activeIndex.set(index);
11681
+ this.keyManager.activeItem?.scrollIntoView();
11682
+ });
11683
+ // A stale active index would point at a different item once results change.
11684
+ // The reset runs untracked because `setActiveItem` reads the option query,
11685
+ // which would otherwise make this effect re-run on every render and clear
11686
+ // the option the user just highlighted.
11687
+ effect(() => {
11688
+ this.resolvedSuggestions();
11689
+ untracked(() => this.resetActiveOption());
11690
+ });
11691
+ inject(DestroyRef).onDestroy(() => this.cleanupScrollListener());
11692
+ }
11693
+ optionId(index) {
11694
+ return `${this.inputId()}-opt-${index}`;
11695
+ }
11293
11696
  onInputValue(value) {
11697
+ this.justSelected = false;
11294
11698
  this.value.set(value);
11295
11699
  this.onChange(value);
11700
+ if (this.autocomplete()) {
11701
+ this.openPanel();
11702
+ }
11296
11703
  }
11297
11704
  onClear() {
11298
11705
  this.clear.emit();
@@ -11301,6 +11708,170 @@ class SearchComponent {
11301
11708
  onBlur() {
11302
11709
  this.onTouched();
11303
11710
  }
11711
+ onInputFocus() {
11712
+ if (this.justSelected) {
11713
+ this.justSelected = false;
11714
+ return;
11715
+ }
11716
+ this.openPanel();
11717
+ }
11718
+ openPanel() {
11719
+ if (!this.autocomplete())
11720
+ return;
11721
+ this.panelWidth.set(this.hostElement.nativeElement.offsetWidth);
11722
+ this.panelOpen.set(true);
11723
+ }
11724
+ closePanel() {
11725
+ this.cleanupScrollListener();
11726
+ this.panelOpen.set(false);
11727
+ // The options leave the DOM with the panel, so a lingering active index
11728
+ // would leave `aria-activedescendant` pointing at a removed element.
11729
+ this.resetActiveOption();
11730
+ }
11731
+ onPositionChange(change) {
11732
+ this.panelAbove.set(change.connectionPair.overlayY === "bottom");
11733
+ }
11734
+ onOverlayAttach() {
11735
+ if (this.hideOnScroll()) {
11736
+ this.setupScrollListener();
11737
+ }
11738
+ }
11739
+ onOverlayDetach() {
11740
+ this.cleanupScrollListener();
11741
+ }
11742
+ /**
11743
+ * Listens on the document in the capture phase so scrolls in any ancestor are
11744
+ * seen — a scroll event does not bubble past the element that scrolled.
11745
+ */
11746
+ setupScrollListener() {
11747
+ this.cleanupScrollListener();
11748
+ this.scrollListener = this.renderer.listen(this.document, "scroll", (event) => {
11749
+ if (!this.panelVisible())
11750
+ return;
11751
+ // Scrolling inside the component is not the page moving away from it:
11752
+ // the option list scrolls its own rows.
11753
+ const target = event.target;
11754
+ const insideSearch = !!target &&
11755
+ (this.hostElement.nativeElement.contains(target) ||
11756
+ !!this.panelElement()?.contains(target));
11757
+ if (insideSearch)
11758
+ return;
11759
+ this.closePanel();
11760
+ }, { capture: true, passive: true });
11761
+ }
11762
+ cleanupScrollListener() {
11763
+ if (this.scrollListener) {
11764
+ this.scrollListener();
11765
+ this.scrollListener = undefined;
11766
+ }
11767
+ }
11768
+ /** Closes the panel and hands focus back to the input. */
11769
+ closeAndRestoreFocus() {
11770
+ this.closePanel();
11771
+ this.justSelected = true;
11772
+ this.focus();
11773
+ }
11774
+ onKeydown(event) {
11775
+ if (!this.autocomplete()) {
11776
+ if (event.key === "Enter")
11777
+ this.emitSearch();
11778
+ return;
11779
+ }
11780
+ switch (event.key) {
11781
+ case "Escape":
11782
+ this.closePanel();
11783
+ return;
11784
+ case "ArrowDown":
11785
+ case "ArrowUp":
11786
+ event.preventDefault();
11787
+ this.onArrowKey(event);
11788
+ return;
11789
+ case "Tab":
11790
+ this.onTabFromInput(event);
11791
+ return;
11792
+ case "Enter":
11793
+ this.onEnter(event);
11794
+ return;
11795
+ }
11796
+ }
11797
+ /**
11798
+ * Footer controls live in the overlay, which sits at the end of the document,
11799
+ * so they are not next in tab order. Tab reaches them explicitly; without this
11800
+ * they would be mouse-only.
11801
+ */
11802
+ onTabFromInput(event) {
11803
+ if (event.shiftKey || !this.panelVisible())
11804
+ return;
11805
+ const first = this.footerFocusables()[0];
11806
+ if (!first)
11807
+ return;
11808
+ event.preventDefault();
11809
+ first.focus();
11810
+ }
11811
+ /**
11812
+ * Tabbing past the footer leaves the component: close the panel and continue to
11813
+ * whatever follows the field in document order, so the footer is not a trap.
11814
+ */
11815
+ onFooterKeydown(event) {
11816
+ if (event.key === "Escape") {
11817
+ event.preventDefault();
11818
+ this.closeAndRestoreFocus();
11819
+ return;
11820
+ }
11821
+ if (event.key !== "Tab")
11822
+ return;
11823
+ const focusables = this.footerFocusables();
11824
+ const index = focusables.indexOf(event.target);
11825
+ if (event.shiftKey && index === 0) {
11826
+ event.preventDefault();
11827
+ this.justSelected = true;
11828
+ this.focus();
11829
+ return;
11830
+ }
11831
+ if (!event.shiftKey && index === focusables.length - 1) {
11832
+ event.preventDefault();
11833
+ this.closePanel();
11834
+ this.focusAfterField();
11835
+ }
11836
+ }
11837
+ footerFocusables() {
11838
+ const footer = this.panelElement()?.querySelector(".tedi-search__footer");
11839
+ return footer ? getFocusableElements(footer) : [];
11840
+ }
11841
+ focusAfterField() {
11842
+ const input = this.inputRef()?.nativeElement;
11843
+ if (!input)
11844
+ return;
11845
+ const panel = this.panelElement();
11846
+ const focusables = getFocusableElements(this.hostElement.nativeElement.ownerDocument.body).filter((el) => !panel?.contains(el));
11847
+ const next = focusables[focusables.indexOf(input) + 1];
11848
+ next?.focus();
11849
+ }
11850
+ selectSuggestion(suggestion) {
11851
+ if (suggestion.disabled)
11852
+ return;
11853
+ this.justSelected = true;
11854
+ this.value.set(suggestion.label);
11855
+ this.onChange(suggestion.label);
11856
+ this.suggestionSelect.emit(suggestion.item);
11857
+ this.closePanel();
11858
+ }
11859
+ /**
11860
+ * The panel is portalled into the overlay container, so it is not a descendant
11861
+ * of the host — both roots have to be consulted before deciding focus left.
11862
+ */
11863
+ onFocusOut(event) {
11864
+ const next = event.relatedTarget;
11865
+ if (!next) {
11866
+ this.closePanel();
11867
+ return;
11868
+ }
11869
+ const stillInside = this.hostElement.nativeElement.contains(next) ||
11870
+ !!this.panelElement()?.contains(next);
11871
+ if (!stillInside) {
11872
+ this.closePanel();
11873
+ }
11874
+ }
11304
11875
  emitSearch() {
11305
11876
  this.searchEvent.emit(this.value());
11306
11877
  }
@@ -11320,14 +11891,47 @@ class SearchComponent {
11320
11891
  setDisabledState(isDisabled) {
11321
11892
  this.formDisabled.set(isDisabled);
11322
11893
  }
11894
+ onArrowKey(event) {
11895
+ if (!this.panelVisible()) {
11896
+ this.openPanel();
11897
+ return;
11898
+ }
11899
+ if (!this.hasSuggestions())
11900
+ return;
11901
+ if (event.key === "ArrowDown") {
11902
+ this.keyManager.setNextItemActive();
11903
+ }
11904
+ else {
11905
+ this.keyManager.setPreviousItemActive();
11906
+ }
11907
+ }
11908
+ onEnter(event) {
11909
+ const active = this.keyManager.activeItem;
11910
+ const index = this.activeIndex();
11911
+ if (this.panelVisible() && active && index >= 0) {
11912
+ event.preventDefault();
11913
+ const suggestion = this.resolvedSuggestions()[index];
11914
+ if (suggestion)
11915
+ this.selectSuggestion(suggestion);
11916
+ return;
11917
+ }
11918
+ this.emitSearch();
11919
+ }
11920
+ panelElement() {
11921
+ return this.connectedOverlay()?.overlayRef?.overlayElement;
11922
+ }
11923
+ resetActiveOption() {
11924
+ this.keyManager.setActiveItem(-1);
11925
+ this.activeIndex.set(-1);
11926
+ }
11323
11927
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11324
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: SearchComponent, isStandalone: true, selector: "tedi-search", inputs: { inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, searchIcon: { classPropertyName: "searchIcon", publicName: "searchIcon", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, button: { classPropertyName: "button", publicName: "button", isSignal: true, isRequired: false, transformFunction: null }, feedbackText: { classPropertyName: "feedbackText", publicName: "feedbackText", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", searchEvent: "searchEvent", clear: "clear" }, host: { attributes: { "role": "search" }, properties: { "attr.aria-label": "searchAriaLabel()", "style.--tedi-search-field-height": "fieldHeight()", "class.tedi-search--button-icon-only": "!!button() && !button()?.text", "class.tedi-search--has-button": "!!button()" }, classAttribute: "tedi-search" }, providers: [
11928
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: SearchComponent, isStandalone: true, selector: "tedi-search", inputs: { inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, searchIcon: { classPropertyName: "searchIcon", publicName: "searchIcon", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, button: { classPropertyName: "button", publicName: "button", isSignal: true, isRequired: false, transformFunction: null }, feedbackText: { classPropertyName: "feedbackText", publicName: "feedbackText", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, suggestions: { classPropertyName: "suggestions", publicName: "suggestions", isSignal: true, isRequired: false, transformFunction: null }, bindLabel: { classPropertyName: "bindLabel", publicName: "bindLabel", isSignal: true, isRequired: false, transformFunction: null }, bindDescription: { classPropertyName: "bindDescription", publicName: "bindDescription", isSignal: true, isRequired: false, transformFunction: null }, bindDisabled: { classPropertyName: "bindDisabled", publicName: "bindDisabled", isSignal: true, isRequired: false, transformFunction: null }, minQueryLength: { classPropertyName: "minQueryLength", publicName: "minQueryLength", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, hideOnScroll: { classPropertyName: "hideOnScroll", publicName: "hideOnScroll", isSignal: true, isRequired: false, transformFunction: null }, panelOpen: { classPropertyName: "panelOpen", publicName: "panelOpen", isSignal: true, isRequired: false, transformFunction: null }, noResultsText: { classPropertyName: "noResultsText", publicName: "noResultsText", isSignal: true, isRequired: false, transformFunction: null }, loadingText: { classPropertyName: "loadingText", publicName: "loadingText", isSignal: true, isRequired: false, transformFunction: null }, resultsCountText: { classPropertyName: "resultsCountText", publicName: "resultsCountText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", panelOpen: "panelOpenChange", searchEvent: "searchEvent", clear: "clear", suggestionSelect: "suggestionSelect" }, host: { attributes: { "role": "search" }, listeners: { "focusout": "onFocusOut($event)" }, properties: { "attr.aria-label": "searchAriaLabel()", "style.--tedi-search-field-height": "fieldHeight()", "class.tedi-search--button-icon-only": "!!button() && !button()?.text", "class.tedi-search--has-button": "!!button()" }, classAttribute: "tedi-search" }, providers: [
11325
11929
  {
11326
11930
  provide: NG_VALUE_ACCESSOR,
11327
11931
  useExisting: forwardRef(() => SearchComponent),
11328
11932
  multi: true,
11329
11933
  },
11330
- ], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["searchInput"], descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "<tedi-form-field\n class=\"tedi-search__field\"\n [size]=\"size()\"\n [icon]=\"fieldIcon()\"\n [clearable]=\"clearable() && !isDisabled()\"\n>\n @if (label()) {\n <label tedi-label [for]=\"inputId()\">\n {{ label() }}\n </label>\n }\n\n <input\n #searchInput\n tedi-text-field\n type=\"text\"\n role=\"searchbox\"\n [id]=\"inputId()\"\n [value]=\"value()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"inputAriaLabel()\"\n (valueChange)=\"onInputValue($event)\"\n (clear)=\"onClear()\"\n (keydown.enter)=\"emitSearch()\"\n (blur)=\"onBlur()\"\n />\n\n @if (feedbackText(); as feedback) {\n <tedi-feedback-text\n [id]=\"feedbackId()\"\n [text]=\"feedback.text\"\n [type]=\"feedback.type\"\n [position]=\"feedback.position\"\n />\n }\n</tedi-form-field>\n\n@if (button(); as btn) {\n <button\n tedi-button\n type=\"button\"\n class=\"tedi-search__button\"\n [variant]=\"btn.variant ?? 'primary'\"\n [size]=\"buttonSize()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"buttonAriaLabel()\"\n (click)=\"emitSearch()\"\n >\n <tedi-icon [name]=\"btn.icon ?? 'search'\" [size]=\"buttonIconSize()\" />\n @if (btn.text) {\n {{ btn.text }}\n }\n </button>\n}\n", styles: [".tedi-search{display:flex;align-items:flex-end;width:100%}.tedi-search__field{flex:1 1 auto;min-width:0}.tedi-search__button{flex:0 0 auto;align-self:flex-end;white-space:nowrap}.tedi-search .tedi-search__button{height:var(--tedi-search-field-height);min-height:0;border-radius:0 var(--button-radius-sm) var(--button-radius-sm) 0}.tedi-search--button-icon-only .tedi-search__button{width:var(--tedi-search-field-height);padding-right:0;padding-left:0}.tedi-search--has-button .tedi-field-surface{border-right-width:0;border-top-right-radius:0;border-bottom-right-radius:0}\n"], dependencies: [{ kind: "component", type: FormFieldComponent, selector: "tedi-form-field", inputs: ["size", "icon", "clearable", "inputClass", "characterLimit"] }, { kind: "component", type: TextFieldComponent, selector: "input[tedi-text-field]", inputs: ["value", "size", "invalid", "arrowsHidden", "disabled"], outputs: ["valueChange", "clear"] }, { kind: "component", type: LabelComponent, selector: "[tedi-label]", inputs: ["size", "required", "color", "visuallyHidden"] }, { kind: "component", type: FeedbackTextComponent, selector: "tedi-feedback-text", inputs: ["id", "text", "type", "position"] }, { kind: "component", type: ButtonComponent, selector: "[tedi-button]", inputs: ["variant", "size"] }, { kind: "component", type: IconComponent, selector: "tedi-icon", inputs: ["name", "size", "color", "background", "variant", "type", "label"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
11934
+ ], queries: [{ propertyName: "suggestionTemplate", first: true, predicate: SearchSuggestionTemplateDirective, descendants: true, isSignal: true }, { propertyName: "footerTemplate", first: true, predicate: SearchFooterTemplateDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["searchInput"], descendants: true, read: ElementRef, isSignal: true }, { propertyName: "overlayOrigin", first: true, predicate: CdkOverlayOrigin, descendants: true, isSignal: true }, { propertyName: "connectedOverlay", first: true, predicate: CdkConnectedOverlay, descendants: true, isSignal: true }, { propertyName: "suggestionRows", predicate: SearchSuggestionComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<tedi-form-field\n class=\"tedi-search__field\"\n cdkOverlayOrigin\n #origin=\"cdkOverlayOrigin\"\n [size]=\"size()\"\n [icon]=\"fieldIcon()\"\n [clearable]=\"clearable() && !isDisabled()\"\n>\n @if (label()) {\n <label tedi-label [for]=\"inputId()\">\n {{ label() }}\n </label>\n }\n\n <input\n #searchInput\n tedi-text-field\n type=\"text\"\n [attr.role]=\"inputRole()\"\n [attr.aria-autocomplete]=\"ariaAutocomplete()\"\n [attr.aria-expanded]=\"ariaExpanded()\"\n [attr.aria-controls]=\"ariaControls()\"\n [attr.aria-activedescendant]=\"activeOptionId()\"\n [id]=\"inputId()\"\n [value]=\"value()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"inputAriaLabel()\"\n (valueChange)=\"onInputValue($event)\"\n (clear)=\"onClear()\"\n (focus)=\"onInputFocus()\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onBlur()\"\n />\n\n @if (feedbackText(); as feedback) {\n <tedi-feedback-text\n [id]=\"feedbackId()\"\n [text]=\"feedback.text\"\n [type]=\"feedback.type\"\n [position]=\"feedback.position\"\n />\n }\n</tedi-form-field>\n\n@if (button(); as btn) {\n <button\n tedi-button\n type=\"button\"\n class=\"tedi-search__button\"\n [variant]=\"btn.variant ?? 'primary'\"\n [size]=\"buttonSize()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"buttonAriaLabel()\"\n (click)=\"emitSearch()\"\n >\n <tedi-icon [name]=\"btn.icon ?? 'search'\" [size]=\"buttonIconSize()\" />\n @if (btn.text) {\n {{ btn.text }}\n }\n </button>\n}\n\n<div\n class=\"tedi-search__announcement sr-only\"\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n>\n {{ announcement() }}\n</div>\n\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"panelVisible()\"\n [cdkConnectedOverlayWidth]=\"panelWidth()\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayDisableClose]=\"true\"\n (overlayOutsideClick)=\"closePanel()\"\n (positionChange)=\"onPositionChange($event)\"\n (attach)=\"onOverlayAttach()\"\n (detach)=\"onOverlayDetach()\"\n>\n <div\n class=\"tedi-search__panel\"\n [class.tedi-search__panel--above]=\"panelAbove()\"\n >\n @if (loading()) {\n <div class=\"tedi-search__panel-status\">\n <tedi-spinner [size]=\"16\" />\n <span tedi-text color=\"tertiary\">{{ resolvedLoadingText() }}</span>\n </div>\n } @else if (hasSuggestions()) {\n <ul class=\"tedi-search__panel-list\" role=\"listbox\" [id]=\"listboxId()\">\n @for (\n suggestion of resolvedSuggestions();\n track suggestion.label + $index;\n let i = $index\n ) {\n <li\n tedi-search-suggestion\n [label]=\"suggestion.label\"\n [description]=\"suggestion.description\"\n [disabled]=\"suggestion.disabled\"\n [query]=\"query()\"\n [custom]=\"!!suggestionTemplate()\"\n [id]=\"optionId(i)\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"selectSuggestion(suggestion)\"\n >\n @if (suggestionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: suggestion.item,\n item: suggestion.item,\n index: i,\n label: suggestion.label,\n description: suggestion.description,\n disabled: suggestion.disabled,\n query: query(),\n }\"\n />\n }\n </li>\n }\n </ul>\n } @else {\n <div class=\"tedi-search__panel-status\">\n <span tedi-text color=\"tertiary\">{{ resolvedNoResultsText() }}</span>\n </div>\n }\n\n @if (footerTemplate(); as footer) {\n <div\n class=\"tedi-search__footer\"\n (keydown)=\"onFooterKeydown($event)\"\n (focusout)=\"onFocusOut($event)\"\n >\n <ng-container [ngTemplateOutlet]=\"footer.template\" />\n </div>\n }\n </div>\n</ng-template>\n", styles: [".tedi-search{display:flex;align-items:flex-end;width:100%}.tedi-search__field{flex:1 1 auto;min-width:0}.tedi-search__button{flex:0 0 auto;align-self:flex-end;white-space:nowrap}.tedi-search .tedi-search__button{height:var(--tedi-search-field-height);min-height:0;border-radius:0 var(--button-radius-sm) var(--button-radius-sm) 0}.tedi-search--button-icon-only .tedi-search__button{width:var(--tedi-search-field-height);padding-right:0;padding-left:0}.tedi-search--has-button .tedi-field-surface{border-right-width:0;border-top-right-radius:0;border-bottom-right-radius:0}.tedi-search__panel{display:flex;flex-direction:column;width:100%;max-height:var(--form-select-area-max-height);overflow:hidden;background:var(--dropdown-item-default-background);border:1px solid var(--card-border-primary);border-radius:0 0 var(--form-select-area-radius) var(--form-select-area-radius);box-shadow:0 1px 5px 0 var(--general-effect-colors-elevation-dropdown-area-drop-shadow)}.tedi-search__panel--above{border-radius:var(--form-select-area-radius) var(--form-select-area-radius) 0 0}.tedi-search__panel-list{min-height:0;padding:0;margin:0;overflow-y:auto;list-style:none}.tedi-search__footer{display:flex;flex:0 0 auto;flex-direction:column;gap:var(--dropdown-item-inner-spacing);align-items:center;padding:var(--card-padding-md-default);background:var(--dropdown-item-default-background);border-top:1px solid var(--card-border-primary)}.tedi-search-footer-actions{display:flex;flex-wrap:wrap;gap:var(--button-gutter-x);justify-content:center}.tedi-search__panel-status{display:flex;gap:var(--dropdown-item-inner-spacing);align-items:center;justify-content:center;padding:var(--dropdown-item-padding-y) var(--dropdown-item-padding-x)}\n"], dependencies: [{ kind: "component", type: FormFieldComponent, selector: "tedi-form-field", inputs: ["size", "icon", "clearable", "inputClass", "characterLimit"] }, { kind: "component", type: TextFieldComponent, selector: "input[tedi-text-field]", inputs: ["value", "size", "invalid", "arrowsHidden", "disabled"], outputs: ["valueChange", "clear"] }, { kind: "component", type: LabelComponent, selector: "[tedi-label]", inputs: ["size", "required", "color", "visuallyHidden"] }, { kind: "component", type: FeedbackTextComponent, selector: "tedi-feedback-text", inputs: ["id", "text", "type", "position"] }, { kind: "component", type: ButtonComponent, selector: "[tedi-button]", inputs: ["variant", "size"] }, { kind: "component", type: IconComponent, selector: "tedi-icon", inputs: ["name", "size", "color", "background", "variant", "type", "label"] }, { kind: "component", type: TextComponent, selector: "[tedi-text]", inputs: ["modifiers", "color"] }, { kind: "component", type: SpinnerComponent, selector: "tedi-spinner", inputs: ["size", "color", "label"] }, { kind: "component", type: SearchSuggestionComponent, selector: "li[tedi-search-suggestion]", inputs: ["label", "description", "query", "custom", "disabled"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
11331
11935
  }
11332
11936
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SearchComponent, decorators: [{
11333
11937
  type: Component,
@@ -11338,6 +11942,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImpo
11338
11942
  FeedbackTextComponent,
11339
11943
  ButtonComponent,
11340
11944
  IconComponent,
11945
+ TextComponent,
11946
+ SpinnerComponent,
11947
+ SearchSuggestionComponent,
11948
+ OverlayModule,
11949
+ NgTemplateOutlet,
11341
11950
  ], providers: [
11342
11951
  {
11343
11952
  provide: NG_VALUE_ACCESSOR,
@@ -11347,12 +11956,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImpo
11347
11956
  ], host: {
11348
11957
  role: "search",
11349
11958
  class: "tedi-search",
11959
+ "(focusout)": "onFocusOut($event)",
11350
11960
  "[attr.aria-label]": "searchAriaLabel()",
11351
11961
  "[style.--tedi-search-field-height]": "fieldHeight()",
11352
11962
  "[class.tedi-search--button-icon-only]": "!!button() && !button()?.text",
11353
11963
  "[class.tedi-search--has-button]": "!!button()",
11354
- }, template: "<tedi-form-field\n class=\"tedi-search__field\"\n [size]=\"size()\"\n [icon]=\"fieldIcon()\"\n [clearable]=\"clearable() && !isDisabled()\"\n>\n @if (label()) {\n <label tedi-label [for]=\"inputId()\">\n {{ label() }}\n </label>\n }\n\n <input\n #searchInput\n tedi-text-field\n type=\"text\"\n role=\"searchbox\"\n [id]=\"inputId()\"\n [value]=\"value()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"inputAriaLabel()\"\n (valueChange)=\"onInputValue($event)\"\n (clear)=\"onClear()\"\n (keydown.enter)=\"emitSearch()\"\n (blur)=\"onBlur()\"\n />\n\n @if (feedbackText(); as feedback) {\n <tedi-feedback-text\n [id]=\"feedbackId()\"\n [text]=\"feedback.text\"\n [type]=\"feedback.type\"\n [position]=\"feedback.position\"\n />\n }\n</tedi-form-field>\n\n@if (button(); as btn) {\n <button\n tedi-button\n type=\"button\"\n class=\"tedi-search__button\"\n [variant]=\"btn.variant ?? 'primary'\"\n [size]=\"buttonSize()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"buttonAriaLabel()\"\n (click)=\"emitSearch()\"\n >\n <tedi-icon [name]=\"btn.icon ?? 'search'\" [size]=\"buttonIconSize()\" />\n @if (btn.text) {\n {{ btn.text }}\n }\n </button>\n}\n", styles: [".tedi-search{display:flex;align-items:flex-end;width:100%}.tedi-search__field{flex:1 1 auto;min-width:0}.tedi-search__button{flex:0 0 auto;align-self:flex-end;white-space:nowrap}.tedi-search .tedi-search__button{height:var(--tedi-search-field-height);min-height:0;border-radius:0 var(--button-radius-sm) var(--button-radius-sm) 0}.tedi-search--button-icon-only .tedi-search__button{width:var(--tedi-search-field-height);padding-right:0;padding-left:0}.tedi-search--has-button .tedi-field-surface{border-right-width:0;border-top-right-radius:0;border-bottom-right-radius:0}\n"] }]
11355
- }], propDecorators: { inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], 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 }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], searchIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchIcon", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], button: [{ type: i0.Input, args: [{ isSignal: true, alias: "button", required: false }] }], feedbackText: [{ type: i0.Input, args: [{ isSignal: true, alias: "feedbackText", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], searchEvent: [{ type: i0.Output, args: ["searchEvent"] }], clear: [{ type: i0.Output, args: ["clear"] }], inputRef: [{ type: i0.ViewChild, args: ["searchInput", { ...{ read: ElementRef }, isSignal: true }] }] } });
11964
+ }, template: "<tedi-form-field\n class=\"tedi-search__field\"\n cdkOverlayOrigin\n #origin=\"cdkOverlayOrigin\"\n [size]=\"size()\"\n [icon]=\"fieldIcon()\"\n [clearable]=\"clearable() && !isDisabled()\"\n>\n @if (label()) {\n <label tedi-label [for]=\"inputId()\">\n {{ label() }}\n </label>\n }\n\n <input\n #searchInput\n tedi-text-field\n type=\"text\"\n [attr.role]=\"inputRole()\"\n [attr.aria-autocomplete]=\"ariaAutocomplete()\"\n [attr.aria-expanded]=\"ariaExpanded()\"\n [attr.aria-controls]=\"ariaControls()\"\n [attr.aria-activedescendant]=\"activeOptionId()\"\n [id]=\"inputId()\"\n [value]=\"value()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"inputAriaLabel()\"\n (valueChange)=\"onInputValue($event)\"\n (clear)=\"onClear()\"\n (focus)=\"onInputFocus()\"\n (keydown)=\"onKeydown($event)\"\n (blur)=\"onBlur()\"\n />\n\n @if (feedbackText(); as feedback) {\n <tedi-feedback-text\n [id]=\"feedbackId()\"\n [text]=\"feedback.text\"\n [type]=\"feedback.type\"\n [position]=\"feedback.position\"\n />\n }\n</tedi-form-field>\n\n@if (button(); as btn) {\n <button\n tedi-button\n type=\"button\"\n class=\"tedi-search__button\"\n [variant]=\"btn.variant ?? 'primary'\"\n [size]=\"buttonSize()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"buttonAriaLabel()\"\n (click)=\"emitSearch()\"\n >\n <tedi-icon [name]=\"btn.icon ?? 'search'\" [size]=\"buttonIconSize()\" />\n @if (btn.text) {\n {{ btn.text }}\n }\n </button>\n}\n\n<div\n class=\"tedi-search__announcement sr-only\"\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n>\n {{ announcement() }}\n</div>\n\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayOpen]=\"panelVisible()\"\n [cdkConnectedOverlayWidth]=\"panelWidth()\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayDisableClose]=\"true\"\n (overlayOutsideClick)=\"closePanel()\"\n (positionChange)=\"onPositionChange($event)\"\n (attach)=\"onOverlayAttach()\"\n (detach)=\"onOverlayDetach()\"\n>\n <div\n class=\"tedi-search__panel\"\n [class.tedi-search__panel--above]=\"panelAbove()\"\n >\n @if (loading()) {\n <div class=\"tedi-search__panel-status\">\n <tedi-spinner [size]=\"16\" />\n <span tedi-text color=\"tertiary\">{{ resolvedLoadingText() }}</span>\n </div>\n } @else if (hasSuggestions()) {\n <ul class=\"tedi-search__panel-list\" role=\"listbox\" [id]=\"listboxId()\">\n @for (\n suggestion of resolvedSuggestions();\n track suggestion.label + $index;\n let i = $index\n ) {\n <li\n tedi-search-suggestion\n [label]=\"suggestion.label\"\n [description]=\"suggestion.description\"\n [disabled]=\"suggestion.disabled\"\n [query]=\"query()\"\n [custom]=\"!!suggestionTemplate()\"\n [id]=\"optionId(i)\"\n (mousedown)=\"$event.preventDefault()\"\n (click)=\"selectSuggestion(suggestion)\"\n >\n @if (suggestionTemplate(); as tpl) {\n <ng-container\n [ngTemplateOutlet]=\"tpl.template\"\n [ngTemplateOutletContext]=\"{\n $implicit: suggestion.item,\n item: suggestion.item,\n index: i,\n label: suggestion.label,\n description: suggestion.description,\n disabled: suggestion.disabled,\n query: query(),\n }\"\n />\n }\n </li>\n }\n </ul>\n } @else {\n <div class=\"tedi-search__panel-status\">\n <span tedi-text color=\"tertiary\">{{ resolvedNoResultsText() }}</span>\n </div>\n }\n\n @if (footerTemplate(); as footer) {\n <div\n class=\"tedi-search__footer\"\n (keydown)=\"onFooterKeydown($event)\"\n (focusout)=\"onFocusOut($event)\"\n >\n <ng-container [ngTemplateOutlet]=\"footer.template\" />\n </div>\n }\n </div>\n</ng-template>\n", styles: [".tedi-search{display:flex;align-items:flex-end;width:100%}.tedi-search__field{flex:1 1 auto;min-width:0}.tedi-search__button{flex:0 0 auto;align-self:flex-end;white-space:nowrap}.tedi-search .tedi-search__button{height:var(--tedi-search-field-height);min-height:0;border-radius:0 var(--button-radius-sm) var(--button-radius-sm) 0}.tedi-search--button-icon-only .tedi-search__button{width:var(--tedi-search-field-height);padding-right:0;padding-left:0}.tedi-search--has-button .tedi-field-surface{border-right-width:0;border-top-right-radius:0;border-bottom-right-radius:0}.tedi-search__panel{display:flex;flex-direction:column;width:100%;max-height:var(--form-select-area-max-height);overflow:hidden;background:var(--dropdown-item-default-background);border:1px solid var(--card-border-primary);border-radius:0 0 var(--form-select-area-radius) var(--form-select-area-radius);box-shadow:0 1px 5px 0 var(--general-effect-colors-elevation-dropdown-area-drop-shadow)}.tedi-search__panel--above{border-radius:var(--form-select-area-radius) var(--form-select-area-radius) 0 0}.tedi-search__panel-list{min-height:0;padding:0;margin:0;overflow-y:auto;list-style:none}.tedi-search__footer{display:flex;flex:0 0 auto;flex-direction:column;gap:var(--dropdown-item-inner-spacing);align-items:center;padding:var(--card-padding-md-default);background:var(--dropdown-item-default-background);border-top:1px solid var(--card-border-primary)}.tedi-search-footer-actions{display:flex;flex-wrap:wrap;gap:var(--button-gutter-x);justify-content:center}.tedi-search__panel-status{display:flex;gap:var(--dropdown-item-inner-spacing);align-items:center;justify-content:center;padding:var(--dropdown-item-padding-y) var(--dropdown-item-padding-x)}\n"] }]
11965
+ }], ctorParameters: () => [], propDecorators: { inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], 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 }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], searchIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchIcon", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], button: [{ type: i0.Input, args: [{ isSignal: true, alias: "button", required: false }] }], feedbackText: [{ type: i0.Input, args: [{ isSignal: true, alias: "feedbackText", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], suggestions: [{ type: i0.Input, args: [{ isSignal: true, alias: "suggestions", required: false }] }], bindLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindLabel", required: false }] }], bindDescription: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindDescription", required: false }] }], bindDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindDisabled", required: false }] }], minQueryLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "minQueryLength", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], hideOnScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideOnScroll", required: false }] }], panelOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelOpen", required: false }] }, { type: i0.Output, args: ["panelOpenChange"] }], noResultsText: [{ type: i0.Input, args: [{ isSignal: true, alias: "noResultsText", required: false }] }], loadingText: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingText", required: false }] }], resultsCountText: [{ type: i0.Input, args: [{ isSignal: true, alias: "resultsCountText", required: false }] }], searchEvent: [{ type: i0.Output, args: ["searchEvent"] }], clear: [{ type: i0.Output, args: ["clear"] }], suggestionSelect: [{ type: i0.Output, args: ["suggestionSelect"] }], suggestionTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SearchSuggestionTemplateDirective), { isSignal: true }] }], footerTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SearchFooterTemplateDirective), { isSignal: true }] }], inputRef: [{ type: i0.ViewChild, args: ["searchInput", { ...{ read: ElementRef }, isSignal: true }] }], overlayOrigin: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CdkOverlayOrigin), { isSignal: true }] }], connectedOverlay: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CdkConnectedOverlay), { isSignal: true }] }], suggestionRows: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => SearchSuggestionComponent), { isSignal: true }] }] } });
11966
+
11967
+ /**
11968
+ * Row of buttons inside a `tediSearchFooter`. Centres them and wraps to a new
11969
+ * line when they no longer fit side by side.
11970
+ */
11971
+ class SearchFooterActionsComponent {
11972
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SearchFooterActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11973
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.24", type: SearchFooterActionsComponent, isStandalone: true, selector: "tedi-search-footer-actions", host: { classAttribute: "tedi-search-footer-actions" }, ngImport: i0, template: "<ng-content />", isInline: true, styles: [".tedi-search{display:flex;align-items:flex-end;width:100%}.tedi-search__field{flex:1 1 auto;min-width:0}.tedi-search__button{flex:0 0 auto;align-self:flex-end;white-space:nowrap}.tedi-search .tedi-search__button{height:var(--tedi-search-field-height);min-height:0;border-radius:0 var(--button-radius-sm) var(--button-radius-sm) 0}.tedi-search--button-icon-only .tedi-search__button{width:var(--tedi-search-field-height);padding-right:0;padding-left:0}.tedi-search--has-button .tedi-field-surface{border-right-width:0;border-top-right-radius:0;border-bottom-right-radius:0}.tedi-search__panel{display:flex;flex-direction:column;width:100%;max-height:var(--form-select-area-max-height);overflow:hidden;background:var(--dropdown-item-default-background);border:1px solid var(--card-border-primary);border-radius:0 0 var(--form-select-area-radius) var(--form-select-area-radius);box-shadow:0 1px 5px 0 var(--general-effect-colors-elevation-dropdown-area-drop-shadow)}.tedi-search__panel--above{border-radius:var(--form-select-area-radius) var(--form-select-area-radius) 0 0}.tedi-search__panel-list{min-height:0;padding:0;margin:0;overflow-y:auto;list-style:none}.tedi-search__footer{display:flex;flex:0 0 auto;flex-direction:column;gap:var(--dropdown-item-inner-spacing);align-items:center;padding:var(--card-padding-md-default);background:var(--dropdown-item-default-background);border-top:1px solid var(--card-border-primary)}.tedi-search-footer-actions{display:flex;flex-wrap:wrap;gap:var(--button-gutter-x);justify-content:center}.tedi-search__panel-status{display:flex;gap:var(--dropdown-item-inner-spacing);align-items:center;justify-content:center;padding:var(--dropdown-item-padding-y) var(--dropdown-item-padding-x)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
11974
+ }
11975
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SearchFooterActionsComponent, decorators: [{
11976
+ type: Component,
11977
+ args: [{ standalone: true, selector: "tedi-search-footer-actions", template: "<ng-content />", encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
11978
+ class: "tedi-search-footer-actions",
11979
+ }, styles: [".tedi-search{display:flex;align-items:flex-end;width:100%}.tedi-search__field{flex:1 1 auto;min-width:0}.tedi-search__button{flex:0 0 auto;align-self:flex-end;white-space:nowrap}.tedi-search .tedi-search__button{height:var(--tedi-search-field-height);min-height:0;border-radius:0 var(--button-radius-sm) var(--button-radius-sm) 0}.tedi-search--button-icon-only .tedi-search__button{width:var(--tedi-search-field-height);padding-right:0;padding-left:0}.tedi-search--has-button .tedi-field-surface{border-right-width:0;border-top-right-radius:0;border-bottom-right-radius:0}.tedi-search__panel{display:flex;flex-direction:column;width:100%;max-height:var(--form-select-area-max-height);overflow:hidden;background:var(--dropdown-item-default-background);border:1px solid var(--card-border-primary);border-radius:0 0 var(--form-select-area-radius) var(--form-select-area-radius);box-shadow:0 1px 5px 0 var(--general-effect-colors-elevation-dropdown-area-drop-shadow)}.tedi-search__panel--above{border-radius:var(--form-select-area-radius) var(--form-select-area-radius) 0 0}.tedi-search__panel-list{min-height:0;padding:0;margin:0;overflow-y:auto;list-style:none}.tedi-search__footer{display:flex;flex:0 0 auto;flex-direction:column;gap:var(--dropdown-item-inner-spacing);align-items:center;padding:var(--card-padding-md-default);background:var(--dropdown-item-default-background);border-top:1px solid var(--card-border-primary)}.tedi-search-footer-actions{display:flex;flex-wrap:wrap;gap:var(--button-gutter-x);justify-content:center}.tedi-search__panel-status{display:flex;gap:var(--dropdown-item-inner-spacing);align-items:center;justify-content:center;padding:var(--dropdown-item-padding-y) var(--dropdown-item-padding-x)}\n"] }]
11980
+ }] });
11356
11981
 
11357
11982
  class InfoTooltipComponent {
11358
11983
  /**
@@ -20461,7 +21086,7 @@ class HeaderRoleComponent {
20461
21086
  return { name: icon.name, size: icon.size ?? 24 };
20462
21087
  }
20463
21088
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: HeaderRoleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
20464
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: HeaderRoleComponent, isStandalone: true, selector: "tedi-header-role", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, searchClearable: { classPropertyName: "searchClearable", publicName: "searchClearable", isSignal: true, isRequired: false, transformFunction: null }, clearSearchOnSelect: { classPropertyName: "clearSearchOnSelect", publicName: "clearSearchOnSelect", isSignal: true, isRequired: false, transformFunction: null }, isOrganization: { classPropertyName: "isOrganization", publicName: "isOrganization", isSignal: true, isRequired: false, transformFunction: null }, searchLabel: { classPropertyName: "searchLabel", publicName: "searchLabel", isSignal: true, isRequired: false, transformFunction: null }, organizationSearchLabel: { classPropertyName: "organizationSearchLabel", publicName: "organizationSearchLabel", isSignal: true, isRequired: false, transformFunction: null }, showRoleSwitch: { classPropertyName: "showRoleSwitch", publicName: "showRoleSwitch", isSignal: true, isRequired: false, transformFunction: null }, representatives: { classPropertyName: "representatives", publicName: "representatives", isSignal: true, isRequired: true, transformFunction: null }, currentRepresentative: { classPropertyName: "currentRepresentative", publicName: "currentRepresentative", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { currentRepresentative: "currentRepresentativeChange", roleSelectionToggle: "roleSelectionToggle" }, host: { classAttribute: "tedi-header-role" }, queries: [{ propertyName: "titleContent", first: true, predicate: HeaderRoleTitleDirective, descendants: true, isSignal: true }, { propertyName: "customContent", first: true, predicate: HeaderRoleContentDirective, descendants: true, isSignal: true }, { propertyName: "noResultsContent", first: true, predicate: HeaderRoleNoResultsDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "popover", first: true, predicate: PopoverComponent, descendants: true, isSignal: true }, { propertyName: "searchInput", first: true, predicate: SearchComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container *hideAt=\"'lg'\">\n <div\n class=\"tedi-header-role__head\"\n [class.tedi-header-role__head--open]=\"mobileOpen() && hasRoleSelection()\"\n >\n <div\n tedi-text\n color=\"secondary\"\n class=\"tedi-header-role__info\"\n [class.tedi-header-role__info--inline]=\"!hasRoleSelection()\"\n >\n <div class=\"tedi-header-role__info-title\">\n <ng-container *ngTemplateOutlet=\"roleTitle\"></ng-container>\n <p tedi-text modifiers=\"bold\" color=\"secondary\">\n {{ currentRepresentative().name }}\n </p>\n </div>\n @if (description()) {\n @if (!hasRoleSelection()) {\n <tedi-separator axis=\"vertical\" size=\"1rem\" />\n }\n <span class=\"tedi-header-role__description\">{{ description() }}</span>\n }\n </div>\n @if (hasRoleSelection()) {\n <button\n type=\"button\"\n tedi-button\n variant=\"neutral\"\n (click)=\"handleMobileOpen()\"\n >\n {{ collapseText() }}\n <tedi-icon name=\"expand_more\" [attr.data-open]=\"mobileOpen()\" />\n </button>\n }\n </div>\n @if (hasRoleSelection()) {\n <div class=\"tedi-header-role__collapse\" [attr.data-open]=\"mobileOpen()\">\n <div class=\"tedi-header-role__collapse--items\">\n @if (hasCustomContent()) {\n <ng-container\n *ngTemplateOutlet=\"customContentTemplate()\"\n ></ng-container>\n } @else {\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n }\n </div>\n </div>\n }\n</ng-container>\n\n<ng-container *showAt=\"'lg'\">\n @if (label() || description() || hasTitle()) {\n <div\n tedi-text\n color=\"secondary\"\n modifiers=\"small\"\n class=\"tedi-header-role__head\"\n [class.tedi-header-role__head--open]=\"hasRoleSelection() && mobileOpen()\"\n >\n <ng-container *ngTemplateOutlet=\"roleTitle\"></ng-container>\n\n @if (description()) {\n <span class=\"tedi-header-role__description\">{{ description() }}</span>\n }\n </div>\n }\n\n @if (hasRoleSelection()) {\n <tedi-popover\n [withBorder]=\"true\"\n position=\"bottom\"\n [preventOverflow]=\"true\"\n >\n <button\n type=\"button\"\n tedi-popover-trigger\n class=\"tedi-link tedi-header__link-button\"\n >\n <span>{{ currentRepresentative().name }}</span>\n <tedi-icon\n name=\"expand_more\"\n [size]=\"16\"\n class=\"tedi-header-role__chevron\"\n />\n </button>\n <tedi-popover-content maxWidth=\"small\" class=\"tedi-header-role__dropdown\">\n @if (hasCustomContent()) {\n <ng-container\n *ngTemplateOutlet=\"customContentTemplate()\"\n ></ng-container>\n } @else {\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n }\n </tedi-popover-content>\n </tedi-popover>\n } @else {\n <div class=\"tedi-header-role__value\">\n {{ currentRepresentative().name }}\n </div>\n }\n</ng-container>\n\n<ng-template #content>\n @if (showSearch()) {\n <tedi-search\n [inputId]=\"inputId\"\n [label]=\"searchText()\"\n [value]=\"inputValue()\"\n [clearable]=\"searchClearable()\"\n (valueChange)=\"handleInputChange($event)\"\n />\n }\n @if (filteredRepresentatives().length === 0) {\n @if (hasNoResultsContent()) {\n <ng-container *ngTemplateOutlet=\"noResultsTemplate()\"></ng-container>\n } @else {\n <span class=\"tedi-header-role__no-results\">{{ noResultsText() }}</span>\n }\n }\n @for (r of filteredRepresentatives(); track r.id) {\n <button\n type=\"button\"\n class=\"tedi-header-role__representative\"\n [attr.data-selected]=\"r.id === currentRepresentative().id\"\n (click)=\"handleSelectRepresentative(r)\"\n >\n @if (resolveIcon(r.icon); as icon) {\n <tedi-icon [name]=\"icon.name\" [size]=\"icon.size\" />\n }\n <div>\n <div>{{ r.name }}</div>\n @if (r.description) {\n <div tedi-text modifiers=\"small\">\n {{ r.description }}\n </div>\n }\n </div>\n </button>\n }\n</ng-template>\n\n<ng-template #roleTitle>\n <ng-content select=\"[tedi-header-role-title]\">\n @if (label(); as labelText) {\n <p\n tedi-text\n [modifiers]=\"isTabletView() ? ['bold'] : ['small', 'bold']\"\n color=\"secondary\"\n >\n {{ labelText }}\n </p>\n }\n </ng-content>\n</ng-template>\n", styles: [":root{--_header-role-transition-duration: .3s}.tedi-header-role{display:flex;flex-direction:column;align-items:flex-start;justify-content:center;height:unset;background-color:var(--general-surface-secondary);border-bottom:var(--tedi-borders-04) solid var(--general-border-brand)}@media(min-width:62rem){.tedi-header-role{background-color:transparent;border-bottom:0}}.tedi-header-role [tedi-popover-trigger] .tedi-header-role__chevron{margin:0;transition:transform .2s ease-in-out}.tedi-header-role [tedi-popover-trigger][aria-expanded=true] .tedi-header-role__chevron{transform:rotate(-180deg)}.tedi-header-role__head{display:flex;gap:var(--layout-grid-gutters-04);align-items:center;justify-content:space-between;width:100%;padding:var(--card-padding-md-default);transition:padding var(--_header-role-transition-duration) ease}@media(min-width:62rem){.tedi-header-role__head{justify-content:flex-start;padding:0}}.tedi-header-role__head .tedi-header-role__info{display:flex;flex-direction:column;align-items:flex-start}.tedi-header-role__head .tedi-header-role__info--inline{flex-direction:row;gap:var(--layout-grid-gutters-08);align-items:center}.tedi-header-role__head .tedi-header-role__info-title{display:flex;flex-wrap:wrap;gap:var(--layout-grid-gutters-04);align-items:center}.tedi-header-role__head button{gap:var(--link-inner-spacing-x);padding:0;border:none}.tedi-header-role__head button tedi-icon{transition:transform .2s ease-in-out}.tedi-header-role__head button tedi-icon[data-open=true]{transform:rotate(-180deg)}.tedi-header-role__dropdown{display:flex;flex-direction:column;gap:var(--layout-grid-gutters-16)}.tedi-header-role__dropdown>*:not(:first-child){position:relative}.tedi-header-role__dropdown>*:not(:first-child):after{position:absolute;top:calc(-1 * (var(--layout-grid-gutters-16) / 2 + 1px));left:0;width:100%;height:1px;content:\"\";background-color:var(--general-border-primary)}.tedi-header-role__value{min-width:max-content}.tedi-header-role__representative{display:flex;gap:var(--layout-grid-gutters-08);align-items:center;width:100%;padding:var(--card-padding-xs);font-size:var(--body-regular-size);color:var(--general-text-secondary);text-align:start;cursor:pointer;background:transparent;border:0;border-radius:var(--card-radius-rounded)}.tedi-header-role__representative:not([data-selected=true]):hover{color:var(--general-text-primary);background:var(--header-popover-item-hover)}.tedi-header-role__representative:not([data-selected=true]):active{color:var(--general-text-white);background:var(--header-popover-item-active)}.tedi-header-role__representative:focus-visible{outline:var(--tedi-borders-02) solid var(--tedi-primary-500);outline-offset:var(--tedi-borders-01)}.tedi-header-role__representative[data-selected=true]{color:var(--general-text-white);background:var(--header-popover-item-selected)}.tedi-header-role__representative tedi-icon{color:inherit}.tedi-header-role__representative [tedi-text]{color:inherit}.tedi-header-role__no-results{padding-top:var(--layout-grid-gutters-08);color:var(--general-text-secondary);text-align:center}.tedi-header-role__collapse{display:grid;visibility:hidden;grid-template-rows:minmax(0,0fr);width:100%;overflow:hidden;transition:grid-template-rows var(--_header-role-transition-duration) ease}.tedi-header-role__collapse[data-open=true]{visibility:visible;grid-template-rows:minmax(0,1fr)}.tedi-header-role__collapse[data-open=true] .tedi-header-role__collapse--items{visibility:visible}.tedi-header-role__collapse--items{display:flex;visibility:hidden;flex-direction:column;gap:var(--layout-grid-gutters-16);min-height:0;padding:0 var(--card-padding-md-default) var(--card-padding-md-default) var(--card-padding-md-default);overflow:hidden;transition:visibility var(--_header-role-transition-duration) ease}.tedi-header-role__collapse--items>*:not(:first-child){position:relative}.tedi-header-role__collapse--items>*:not(:first-child):after{position:absolute;top:calc(-1 * (var(--layout-grid-gutters-16) / 2 + 1px));left:0;width:100%;height:1px;content:\"\";background-color:var(--general-border-primary)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: PopoverComponent, selector: "tedi-popover", inputs: ["position", "preventOverflow", "dismissible", "hideOnScroll", "withBorder", "withArrow", "lockScroll", "timeoutDelay"] }, { kind: "directive", type: PopoverTriggerDirective, selector: "[tedi-popover-trigger]", inputs: ["underline", "interactive"] }, { kind: "component", type: PopoverContentComponent, selector: "tedi-popover-content", inputs: ["maxWidth", "title", "showClose"] }, { kind: "component", type: IconComponent, selector: "tedi-icon", inputs: ["name", "size", "color", "background", "variant", "type", "label"] }, { kind: "component", type: ButtonComponent, selector: "[tedi-button]", inputs: ["variant", "size"] }, { kind: "component", type: TextComponent, selector: "[tedi-text]", inputs: ["modifiers", "color"] }, { kind: "directive", type: ShowAtDirective, selector: "[showAt]", inputs: ["showAt"] }, { kind: "directive", type: HideAtDirective, selector: "[hideAt]", inputs: ["hideAt"] }, { kind: "component", type: SeparatorComponent, selector: "tedi-separator", inputs: ["axis", "color", "variant", "dotSize", "dotFilled", "thickness", "spacing", "size"] }, { kind: "component", type: SearchComponent, selector: "tedi-search", inputs: ["inputId", "label", "value", "placeholder", "size", "clearable", "searchIcon", "disabled", "button", "feedbackText", "ariaLabel"], outputs: ["valueChange", "searchEvent", "clear"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
21089
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: HeaderRoleComponent, isStandalone: true, selector: "tedi-header-role", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, searchClearable: { classPropertyName: "searchClearable", publicName: "searchClearable", isSignal: true, isRequired: false, transformFunction: null }, clearSearchOnSelect: { classPropertyName: "clearSearchOnSelect", publicName: "clearSearchOnSelect", isSignal: true, isRequired: false, transformFunction: null }, isOrganization: { classPropertyName: "isOrganization", publicName: "isOrganization", isSignal: true, isRequired: false, transformFunction: null }, searchLabel: { classPropertyName: "searchLabel", publicName: "searchLabel", isSignal: true, isRequired: false, transformFunction: null }, organizationSearchLabel: { classPropertyName: "organizationSearchLabel", publicName: "organizationSearchLabel", isSignal: true, isRequired: false, transformFunction: null }, showRoleSwitch: { classPropertyName: "showRoleSwitch", publicName: "showRoleSwitch", isSignal: true, isRequired: false, transformFunction: null }, representatives: { classPropertyName: "representatives", publicName: "representatives", isSignal: true, isRequired: true, transformFunction: null }, currentRepresentative: { classPropertyName: "currentRepresentative", publicName: "currentRepresentative", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { currentRepresentative: "currentRepresentativeChange", roleSelectionToggle: "roleSelectionToggle" }, host: { classAttribute: "tedi-header-role" }, queries: [{ propertyName: "titleContent", first: true, predicate: HeaderRoleTitleDirective, descendants: true, isSignal: true }, { propertyName: "customContent", first: true, predicate: HeaderRoleContentDirective, descendants: true, isSignal: true }, { propertyName: "noResultsContent", first: true, predicate: HeaderRoleNoResultsDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "popover", first: true, predicate: PopoverComponent, descendants: true, isSignal: true }, { propertyName: "searchInput", first: true, predicate: SearchComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container *hideAt=\"'lg'\">\n <div\n class=\"tedi-header-role__head\"\n [class.tedi-header-role__head--open]=\"mobileOpen() && hasRoleSelection()\"\n >\n <div\n tedi-text\n color=\"secondary\"\n class=\"tedi-header-role__info\"\n [class.tedi-header-role__info--inline]=\"!hasRoleSelection()\"\n >\n <div class=\"tedi-header-role__info-title\">\n <ng-container *ngTemplateOutlet=\"roleTitle\"></ng-container>\n <p tedi-text modifiers=\"bold\" color=\"secondary\">\n {{ currentRepresentative().name }}\n </p>\n </div>\n @if (description()) {\n @if (!hasRoleSelection()) {\n <tedi-separator axis=\"vertical\" size=\"1rem\" />\n }\n <span class=\"tedi-header-role__description\">{{ description() }}</span>\n }\n </div>\n @if (hasRoleSelection()) {\n <button\n type=\"button\"\n tedi-button\n variant=\"neutral\"\n (click)=\"handleMobileOpen()\"\n >\n {{ collapseText() }}\n <tedi-icon name=\"expand_more\" [attr.data-open]=\"mobileOpen()\" />\n </button>\n }\n </div>\n @if (hasRoleSelection()) {\n <div class=\"tedi-header-role__collapse\" [attr.data-open]=\"mobileOpen()\">\n <div class=\"tedi-header-role__collapse--items\">\n @if (hasCustomContent()) {\n <ng-container\n *ngTemplateOutlet=\"customContentTemplate()\"\n ></ng-container>\n } @else {\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n }\n </div>\n </div>\n }\n</ng-container>\n\n<ng-container *showAt=\"'lg'\">\n @if (label() || description() || hasTitle()) {\n <div\n tedi-text\n color=\"secondary\"\n modifiers=\"small\"\n class=\"tedi-header-role__head\"\n [class.tedi-header-role__head--open]=\"hasRoleSelection() && mobileOpen()\"\n >\n <ng-container *ngTemplateOutlet=\"roleTitle\"></ng-container>\n\n @if (description()) {\n <span class=\"tedi-header-role__description\">{{ description() }}</span>\n }\n </div>\n }\n\n @if (hasRoleSelection()) {\n <tedi-popover\n [withBorder]=\"true\"\n position=\"bottom\"\n [preventOverflow]=\"true\"\n >\n <button\n type=\"button\"\n tedi-popover-trigger\n class=\"tedi-link tedi-header__link-button\"\n >\n <span>{{ currentRepresentative().name }}</span>\n <tedi-icon\n name=\"expand_more\"\n [size]=\"16\"\n class=\"tedi-header-role__chevron\"\n />\n </button>\n <tedi-popover-content maxWidth=\"small\" class=\"tedi-header-role__dropdown\">\n @if (hasCustomContent()) {\n <ng-container\n *ngTemplateOutlet=\"customContentTemplate()\"\n ></ng-container>\n } @else {\n <ng-container *ngTemplateOutlet=\"content\"></ng-container>\n }\n </tedi-popover-content>\n </tedi-popover>\n } @else {\n <div class=\"tedi-header-role__value\">\n {{ currentRepresentative().name }}\n </div>\n }\n</ng-container>\n\n<ng-template #content>\n @if (showSearch()) {\n <tedi-search\n [inputId]=\"inputId\"\n [label]=\"searchText()\"\n [value]=\"inputValue()\"\n [clearable]=\"searchClearable()\"\n (valueChange)=\"handleInputChange($event)\"\n />\n }\n @if (filteredRepresentatives().length === 0) {\n @if (hasNoResultsContent()) {\n <ng-container *ngTemplateOutlet=\"noResultsTemplate()\"></ng-container>\n } @else {\n <span class=\"tedi-header-role__no-results\">{{ noResultsText() }}</span>\n }\n }\n @for (r of filteredRepresentatives(); track r.id) {\n <button\n type=\"button\"\n class=\"tedi-header-role__representative\"\n [attr.data-selected]=\"r.id === currentRepresentative().id\"\n (click)=\"handleSelectRepresentative(r)\"\n >\n @if (resolveIcon(r.icon); as icon) {\n <tedi-icon [name]=\"icon.name\" [size]=\"icon.size\" />\n }\n <div>\n <div>{{ r.name }}</div>\n @if (r.description) {\n <div tedi-text modifiers=\"small\">\n {{ r.description }}\n </div>\n }\n </div>\n </button>\n }\n</ng-template>\n\n<ng-template #roleTitle>\n <ng-content select=\"[tedi-header-role-title]\">\n @if (label(); as labelText) {\n <p\n tedi-text\n [modifiers]=\"isTabletView() ? ['bold'] : ['small', 'bold']\"\n color=\"secondary\"\n >\n {{ labelText }}\n </p>\n }\n </ng-content>\n</ng-template>\n", styles: [":root{--_header-role-transition-duration: .3s}.tedi-header-role{display:flex;flex-direction:column;align-items:flex-start;justify-content:center;height:unset;background-color:var(--general-surface-secondary);border-bottom:var(--tedi-borders-04) solid var(--general-border-brand)}@media(min-width:62rem){.tedi-header-role{background-color:transparent;border-bottom:0}}.tedi-header-role [tedi-popover-trigger] .tedi-header-role__chevron{margin:0;transition:transform .2s ease-in-out}.tedi-header-role [tedi-popover-trigger][aria-expanded=true] .tedi-header-role__chevron{transform:rotate(-180deg)}.tedi-header-role__head{display:flex;gap:var(--layout-grid-gutters-04);align-items:center;justify-content:space-between;width:100%;padding:var(--card-padding-md-default);transition:padding var(--_header-role-transition-duration) ease}@media(min-width:62rem){.tedi-header-role__head{justify-content:flex-start;padding:0}}.tedi-header-role__head .tedi-header-role__info{display:flex;flex-direction:column;align-items:flex-start}.tedi-header-role__head .tedi-header-role__info--inline{flex-direction:row;gap:var(--layout-grid-gutters-08);align-items:center}.tedi-header-role__head .tedi-header-role__info-title{display:flex;flex-wrap:wrap;gap:var(--layout-grid-gutters-04);align-items:center}.tedi-header-role__head button{gap:var(--link-inner-spacing-x);padding:0;border:none}.tedi-header-role__head button tedi-icon{transition:transform .2s ease-in-out}.tedi-header-role__head button tedi-icon[data-open=true]{transform:rotate(-180deg)}.tedi-header-role__dropdown{display:flex;flex-direction:column;gap:var(--layout-grid-gutters-16)}.tedi-header-role__dropdown>*:not(:first-child){position:relative}.tedi-header-role__dropdown>*:not(:first-child):after{position:absolute;top:calc(-1 * (var(--layout-grid-gutters-16) / 2 + 1px));left:0;width:100%;height:1px;content:\"\";background-color:var(--general-border-primary)}.tedi-header-role__value{min-width:max-content}.tedi-header-role__representative{display:flex;gap:var(--layout-grid-gutters-08);align-items:center;width:100%;padding:var(--card-padding-xs);font-size:var(--body-regular-size);color:var(--general-text-secondary);text-align:start;cursor:pointer;background:transparent;border:0;border-radius:var(--card-radius-rounded)}.tedi-header-role__representative:not([data-selected=true]):hover{color:var(--general-text-primary);background:var(--header-popover-item-hover)}.tedi-header-role__representative:not([data-selected=true]):active{color:var(--general-text-white);background:var(--header-popover-item-active)}.tedi-header-role__representative:focus-visible{outline:var(--tedi-borders-02) solid var(--tedi-primary-500);outline-offset:var(--tedi-borders-01)}.tedi-header-role__representative[data-selected=true]{color:var(--general-text-white);background:var(--header-popover-item-selected)}.tedi-header-role__representative tedi-icon{color:inherit}.tedi-header-role__representative [tedi-text]{color:inherit}.tedi-header-role__no-results{padding-top:var(--layout-grid-gutters-08);color:var(--general-text-secondary);text-align:center}.tedi-header-role__collapse{display:grid;visibility:hidden;grid-template-rows:minmax(0,0fr);width:100%;overflow:hidden;transition:grid-template-rows var(--_header-role-transition-duration) ease}.tedi-header-role__collapse[data-open=true]{visibility:visible;grid-template-rows:minmax(0,1fr)}.tedi-header-role__collapse[data-open=true] .tedi-header-role__collapse--items{visibility:visible}.tedi-header-role__collapse--items{display:flex;visibility:hidden;flex-direction:column;gap:var(--layout-grid-gutters-16);min-height:0;padding:0 var(--card-padding-md-default) var(--card-padding-md-default) var(--card-padding-md-default);overflow:hidden;transition:visibility var(--_header-role-transition-duration) ease}.tedi-header-role__collapse--items>*:not(:first-child){position:relative}.tedi-header-role__collapse--items>*:not(:first-child):after{position:absolute;top:calc(-1 * (var(--layout-grid-gutters-16) / 2 + 1px));left:0;width:100%;height:1px;content:\"\";background-color:var(--general-border-primary)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: PopoverComponent, selector: "tedi-popover", inputs: ["position", "preventOverflow", "dismissible", "hideOnScroll", "withBorder", "withArrow", "lockScroll", "timeoutDelay"] }, { kind: "directive", type: PopoverTriggerDirective, selector: "[tedi-popover-trigger]", inputs: ["underline", "interactive"] }, { kind: "component", type: PopoverContentComponent, selector: "tedi-popover-content", inputs: ["maxWidth", "title", "showClose"] }, { kind: "component", type: IconComponent, selector: "tedi-icon", inputs: ["name", "size", "color", "background", "variant", "type", "label"] }, { kind: "component", type: ButtonComponent, selector: "[tedi-button]", inputs: ["variant", "size"] }, { kind: "component", type: TextComponent, selector: "[tedi-text]", inputs: ["modifiers", "color"] }, { kind: "directive", type: ShowAtDirective, selector: "[showAt]", inputs: ["showAt"] }, { kind: "directive", type: HideAtDirective, selector: "[hideAt]", inputs: ["hideAt"] }, { kind: "component", type: SeparatorComponent, selector: "tedi-separator", inputs: ["axis", "color", "variant", "dotSize", "dotFilled", "thickness", "spacing", "size"] }, { kind: "component", type: SearchComponent, selector: "tedi-search", inputs: ["inputId", "label", "value", "placeholder", "size", "clearable", "searchIcon", "disabled", "button", "feedbackText", "ariaLabel", "suggestions", "bindLabel", "bindDescription", "bindDisabled", "minQueryLength", "loading", "hideOnScroll", "panelOpen", "noResultsText", "loadingText", "resultsCountText"], outputs: ["valueChange", "panelOpenChange", "searchEvent", "clear", "suggestionSelect"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
20465
21090
  }
20466
21091
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: HeaderRoleComponent, decorators: [{
20467
21092
  type: Component,
@@ -21910,5 +22535,5 @@ function provideTedi(config = {}) {
21910
22535
  * Generated bundle index. Do not edit.
21911
22536
  */
21912
22537
 
21913
- export { AVAILABLE_LANGUAGES, AccordionComponent, AccordionItemComponent, AccordionItemContentComponent, AccordionItemHeaderComponent, AlertComponent, AttachmentActionsComponent, AttachmentComponent, BREAKPOINTS, BaseButtonDirective, BreadcrumbItemDirective, BreadcrumbSeparatorDirective, BreadcrumbsComponent, BreakpointService, ButtonComponent, ButtonGroupButtonDirective, ButtonGroupComponent, COUNTER_TAG_WIDTH, CalendarComponent, CardButtonComponent, CardComponent, CardContentComponent, CardHeaderComponent, CardIconComponent, CardRowComponent, CarouselComponent, CarouselContentComponent, CarouselFooterComponent, CarouselHeaderComponent, CarouselIndicatorsComponent, CarouselNavigationComponent, CarouselSlideDirective, CheckboxCardComponent, CheckboxCardGroupComponent, CheckboxComponent, CheckboxGroupComponent, ClosingButtonComponent, ColComponent, CollapseButtonComponent, CollapseComponent, DROPDOWN_API, DROPDOWN_CONTENT_API, DateFieldComponent, DatePickerComponent, DropdownComponent, DropdownContentComponent, DropdownItemComponent, DropdownItemValueComponent, DropdownItemValueLabelComponent, DropdownItemValueMetaComponent, DropdownTriggerDirective, EllipsisComponent, EmptyStateComponent, FeedbackTextComponent, FilterComponent, FilterContentDirective, FilterGroupComponent, FilterPrependDirective, FooterBodyComponent, FooterBottomComponent, FooterComponent, FooterSectionComponent, FooterSideComponent, FormFieldComponent, FormFieldExtraDirective, HeaderActionsComponent, HeaderBottomComponent, HeaderComponent, HeaderContentComponent, HeaderLanguageComponent, HeaderLoginComponent, HeaderLogoComponent, HeaderLogoDarkDirective, HeaderLogoutComponent, HeaderMobileButtonComponent, HeaderProfileComponent, HeaderRoleComponent, HeaderRoleContentDirective, HeaderRoleNoResultsDirective, HeaderRoleTitleDirective, HeaderSearchComponent, HeaderTopComponent, HideAtDirective, HorizontalPushHandler, HorizontalStepperComponent, HorizontalStepperItemComponent, IconComponent, InfoButtonComponent, InfoTooltipComponent, InputGroupComponent, InputGroupPrefixDirective, InputGroupSuffixDirective, LANGUAGE_COOKIE_NAME, LANGUAGE_FALLBACK_VALUE, LabelComponent, LabelRowComponent, LinkComponent, ListComponent, MODAL_DATA, MODAL_SIZE, ModalComponent, ModalContentComponent, ModalFooterComponent, ModalHeaderComponent, ModalRef, ModalService, NumberFieldComponent, PaginationComponent, PopoverComponent, PopoverContentComponent, PopoverTriggerDirective, ProgressBarComponent, RadioCardComponent, RadioCardGroupComponent, RadioComponent, RadioGroupComponent, RowComponent, ScrollFadeComponent, SearchComponent, SelectComponent, SelectOptionTemplateDirective, SelectTooltipTemplateDirective, SelectValueTemplateDirective, SeparatorComponent, ShowAtDirective, SideNavComponent, SideNavDropdownComponent, SideNavDropdownGroupComponent, SideNavDropdownItemComponent, SideNavGroupTitleComponent, SideNavItemComponent, SideNavOverlayComponent, SideNavToggleComponent, SkeletonBlockComponent, SkeletonComponent, SliderComponent, SpecialOptionControls, SpinnerComponent, StatusBadgeComponent, StatusIndicatorComponent, TAG_GAP, TEDI_FIELD_CONTEXT, TEDI_FORM_FIELD_CONTROL, TEDI_INPUT_GROUP, TEDI_TABLE_CONTEXT, TEDI_THEME_DEFAULT_TOKEN, TEDI_TRANSLATION_DEFAULT_TOKEN, THEME_CLASS_PREFIX, THEME_COOKIE_NAME, THEME_FALLBACK_VALUE, TOAST_DEFAULT_DURATION, TabsComponent, TabsContentComponent, TabsListComponent, TabsTriggerComponent, TagComponent, TediPaginationResultsDirective, TediTableColumnsMenuComponent, TediTableComponent, TediTableHeaderButtonComponent, TediTableToolbarComponent, TediTranslationPipe, TediTranslationService, TextComponent, TextFieldComponent, TextGroupComponent, TextGroupLabelComponent, TextGroupValueComponent, TextareaComponent, ThemeService, TimeFieldComponent, TimePickerComponent, TimelineComponent, TimelineDescriptionComponent, TimelineItemComponent, TimelineTimingsBottomDirective, TimelineTitleComponent, ToastComponent, ToastService, ToggleComponent, TooltipComponent, TooltipContentComponent, TooltipTriggerComponent, TruncateComponent, VerticalSpacingDirective, VerticalSpacingItemDirective, addDays, addMonths, addYears, breakpointInput, buildMonthGrid, calculateArrowOffset, calculateVisibleTagCount, computeGroupSpans, controlDescribedBy, cookieSignal, createTablePersistence, deriveControlState, endOfMonth, formatDate, formatLocaleDate, formatLocaleDateHint, formatLocaleDateLong, formatMonthYear, generateUUID, getCardBorderPlacementColor, getDaysInMonth, getFirstDayOfWeek, getFocusableElements, getISOWeek, getMonthNames, getPaddingCssVariables, getPlacementFromPositionChange, getWeekdayNames, groupRowSpan, injectTediTableContext, isAfterDay, isBeforeDay, isDateInRange, isSameDay, isSameMonth, isSameYear, isValidTime, matchAny, matchDate, normalizeTime, parseDate, parseLocaleDate, provideTedi, resolveCardBorderRadius, startOfMonth, startOfWeek, toConnectedPositions, toggleDateInArray, usePagination };
22538
+ export { AVAILABLE_LANGUAGES, AccordionComponent, AccordionItemComponent, AccordionItemContentComponent, AccordionItemHeaderComponent, AlertComponent, AttachmentActionsComponent, AttachmentComponent, BREAKPOINTS, BaseButtonDirective, BreadcrumbItemDirective, BreadcrumbSeparatorDirective, BreadcrumbsComponent, BreakpointService, ButtonComponent, ButtonGroupButtonDirective, ButtonGroupComponent, COUNTER_TAG_WIDTH, CalendarComponent, CardButtonComponent, CardComponent, CardContentComponent, CardHeaderComponent, CardIconComponent, CardRowComponent, CarouselComponent, CarouselContentComponent, CarouselFooterComponent, CarouselHeaderComponent, CarouselIndicatorsComponent, CarouselNavigationComponent, CarouselSlideDirective, CheckboxCardComponent, CheckboxCardGroupComponent, CheckboxComponent, CheckboxGroupComponent, ClosingButtonComponent, ColComponent, CollapseButtonComponent, CollapseComponent, DROPDOWN_API, DROPDOWN_CONTENT_API, DateFieldComponent, DatePickerComponent, DropdownComponent, DropdownContentComponent, DropdownItemComponent, DropdownItemValueComponent, DropdownItemValueLabelComponent, DropdownItemValueMetaComponent, DropdownTriggerDirective, EllipsisComponent, EmptyStateComponent, FeedbackTextComponent, FilterComponent, FilterContentDirective, FilterGroupComponent, FilterPrependDirective, FooterBodyComponent, FooterBottomComponent, FooterComponent, FooterSectionComponent, FooterSideComponent, FormFieldComponent, FormFieldExtraDirective, HeaderActionsComponent, HeaderBottomComponent, HeaderComponent, HeaderContentComponent, HeaderLanguageComponent, HeaderLoginComponent, HeaderLogoComponent, HeaderLogoDarkDirective, HeaderLogoutComponent, HeaderMobileButtonComponent, HeaderProfileComponent, HeaderRoleComponent, HeaderRoleContentDirective, HeaderRoleNoResultsDirective, HeaderRoleTitleDirective, HeaderSearchComponent, HeaderTopComponent, HeadingWithIconComponent, HideAtDirective, HorizontalPushHandler, HorizontalStepperComponent, HorizontalStepperItemComponent, IconComponent, InfoButtonComponent, InfoTooltipComponent, InputGroupComponent, InputGroupPrefixDirective, InputGroupSuffixDirective, LANGUAGE_COOKIE_NAME, LANGUAGE_FALLBACK_VALUE, LabelComponent, LabelRowComponent, LinkComponent, ListComponent, MODAL_DATA, MODAL_SIZE, ModalComponent, ModalContentComponent, ModalFooterComponent, ModalHeaderComponent, ModalRef, ModalService, NumberFieldComponent, PaginationComponent, PopoverComponent, PopoverContentComponent, PopoverTriggerDirective, ProgressBarComponent, RadioCardComponent, RadioCardGroupComponent, RadioComponent, RadioGroupComponent, RowComponent, ScrollFadeComponent, SearchComponent, SearchFooterActionsComponent, SearchFooterTemplateDirective, SearchSuggestionComponent, SearchSuggestionTemplateDirective, SelectComponent, SelectOptionTemplateDirective, SelectTooltipTemplateDirective, SelectValueTemplateDirective, SeparatorComponent, ShowAtDirective, SideNavComponent, SideNavDropdownComponent, SideNavDropdownGroupComponent, SideNavDropdownItemComponent, SideNavGroupTitleComponent, SideNavItemComponent, SideNavOverlayComponent, SideNavToggleComponent, SkeletonBlockComponent, SkeletonComponent, SliderComponent, SpecialOptionControls, SpinnerComponent, StatusBadgeComponent, StatusIndicatorComponent, TAG_GAP, TEDI_FIELD_CONTEXT, TEDI_FORM_FIELD_CONTROL, TEDI_INPUT_GROUP, TEDI_TABLE_CONTEXT, TEDI_THEME_DEFAULT_TOKEN, TEDI_TRANSLATION_DEFAULT_TOKEN, THEME_CLASS_PREFIX, THEME_COOKIE_NAME, THEME_FALLBACK_VALUE, TOAST_DEFAULT_DURATION, TabsComponent, TabsContentComponent, TabsListComponent, TabsTriggerComponent, TagComponent, TediPaginationResultsDirective, TediTableColumnsMenuComponent, TediTableComponent, TediTableHeaderButtonComponent, TediTableToolbarComponent, TediTranslationPipe, TediTranslationService, TextComponent, TextFieldComponent, TextGroupComponent, TextGroupLabelComponent, TextGroupValueComponent, TextareaComponent, ThemeService, TimeFieldComponent, TimePickerComponent, TimelineComponent, TimelineDescriptionComponent, TimelineItemComponent, TimelineTimingsBottomDirective, TimelineTitleComponent, ToastComponent, ToastService, ToggleComponent, TooltipComponent, TooltipContentComponent, TooltipTriggerComponent, TruncateComponent, VerticalSpacingDirective, VerticalSpacingItemDirective, addDays, addMonths, addYears, breakpointInput, buildMonthGrid, calculateArrowOffset, calculateVisibleTagCount, computeGroupSpans, controlDescribedBy, cookieSignal, createTablePersistence, deriveControlState, endOfMonth, formatDate, formatLocaleDate, formatLocaleDateHint, formatLocaleDateLong, formatMonthYear, generateUUID, getCardBorderPlacementColor, getDaysInMonth, getFirstDayOfWeek, getFocusableElements, getISOWeek, getMonthNames, getPaddingCssVariables, getPlacementFromPositionChange, getWeekdayNames, groupRowSpan, highlightParts, injectTediTableContext, isAfterDay, isBeforeDay, isDateInRange, isSameDay, isSameMonth, isSameYear, isValidTime, matchAny, matchDate, normalizeTime, parseDate, parseLocaleDate, provideTedi, resolveCardBorderRadius, startOfMonth, startOfWeek, toConnectedPositions, toggleDateInArray, usePagination };
21914
22539
  //# sourceMappingURL=tedi-design-system-angular-tedi.mjs.map