@siemens/element-ng 47.2.0 → 47.3.0

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.
Files changed (172) hide show
  1. package/README.md +18 -6
  2. package/autocomplete/index.d.ts +8 -0
  3. package/autocomplete/package.json +3 -0
  4. package/autocomplete/si-autocomplete-listbox.directive.d.ts +31 -0
  5. package/autocomplete/si-autocomplete-option.directive.d.ts +31 -0
  6. package/autocomplete/si-autocomplete.directive.d.ts +14 -0
  7. package/autocomplete/si-autocomplete.model.d.ts +7 -0
  8. package/autocomplete/si-autocomplete.module.d.ts +9 -0
  9. package/badge/index.d.ts +5 -0
  10. package/badge/package.json +3 -0
  11. package/badge/si-badge.component.d.ts +17 -0
  12. package/content-action-bar/index.d.ts +7 -0
  13. package/content-action-bar/package.json +3 -0
  14. package/content-action-bar/si-content-action-bar-toggle.component.d.ts +6 -0
  15. package/content-action-bar/si-content-action-bar.component.d.ts +72 -0
  16. package/content-action-bar/si-content-action-bar.model.d.ts +9 -0
  17. package/content-action-bar/si-content-action-bar.module.d.ts +7 -0
  18. package/fesm2022/siemens-element-ng-application-header.mjs +2 -2
  19. package/fesm2022/siemens-element-ng-application-header.mjs.map +1 -1
  20. package/fesm2022/siemens-element-ng-autocomplete.mjs +235 -0
  21. package/fesm2022/siemens-element-ng-autocomplete.mjs.map +1 -0
  22. package/fesm2022/siemens-element-ng-badge.mjs +59 -0
  23. package/fesm2022/siemens-element-ng-badge.mjs.map +1 -0
  24. package/fesm2022/siemens-element-ng-common.mjs +1 -1
  25. package/fesm2022/siemens-element-ng-common.mjs.map +1 -1
  26. package/fesm2022/siemens-element-ng-content-action-bar.mjs +200 -0
  27. package/fesm2022/siemens-element-ng-content-action-bar.mjs.map +1 -0
  28. package/fesm2022/siemens-element-ng-form.mjs +827 -0
  29. package/fesm2022/siemens-element-ng-form.mjs.map +1 -0
  30. package/fesm2022/siemens-element-ng-icon-status.mjs +65 -0
  31. package/fesm2022/siemens-element-ng-icon-status.mjs.map +1 -0
  32. package/fesm2022/siemens-element-ng-icon.mjs +12 -2
  33. package/fesm2022/siemens-element-ng-icon.mjs.map +1 -1
  34. package/fesm2022/siemens-element-ng-language-switcher.mjs +90 -0
  35. package/fesm2022/siemens-element-ng-language-switcher.mjs.map +1 -0
  36. package/fesm2022/siemens-element-ng-number-input.mjs +267 -0
  37. package/fesm2022/siemens-element-ng-number-input.mjs.map +1 -0
  38. package/fesm2022/siemens-element-ng-password-strength.mjs +177 -0
  39. package/fesm2022/siemens-element-ng-password-strength.mjs.map +1 -0
  40. package/fesm2022/siemens-element-ng-pills-input.mjs +397 -0
  41. package/fesm2022/siemens-element-ng-pills-input.mjs.map +1 -0
  42. package/fesm2022/siemens-element-ng-popover-next.mjs +259 -0
  43. package/fesm2022/siemens-element-ng-popover-next.mjs.map +1 -0
  44. package/fesm2022/siemens-element-ng-popover.mjs +256 -0
  45. package/fesm2022/siemens-element-ng-popover.mjs.map +1 -0
  46. package/fesm2022/siemens-element-ng-progressbar.mjs +83 -0
  47. package/fesm2022/siemens-element-ng-progressbar.mjs.map +1 -0
  48. package/fesm2022/siemens-element-ng-select.mjs +1166 -0
  49. package/fesm2022/siemens-element-ng-select.mjs.map +1 -0
  50. package/fesm2022/siemens-element-ng-skip-links.mjs +117 -0
  51. package/fesm2022/siemens-element-ng-skip-links.mjs.map +1 -0
  52. package/fesm2022/siemens-element-ng-summary-widget.mjs +77 -0
  53. package/fesm2022/siemens-element-ng-summary-widget.mjs.map +1 -0
  54. package/fesm2022/siemens-element-ng-toast-notification.mjs +227 -0
  55. package/fesm2022/siemens-element-ng-toast-notification.mjs.map +1 -0
  56. package/fesm2022/siemens-element-ng-translate.mjs.map +1 -1
  57. package/fesm2022/siemens-element-ng-typeahead.mjs +746 -0
  58. package/fesm2022/siemens-element-ng-typeahead.mjs.map +1 -0
  59. package/fesm2022/siemens-element-ng-wizard.mjs +465 -0
  60. package/fesm2022/siemens-element-ng-wizard.mjs.map +1 -0
  61. package/form/form-fieldset/si-form-fieldset.component.d.ts +40 -0
  62. package/form/index.d.ts +14 -0
  63. package/form/package.json +3 -0
  64. package/form/si-form-container/si-form-container.component.d.ts +155 -0
  65. package/form/si-form-item/si-form-field-native.control.d.ts +22 -0
  66. package/form/si-form-item/si-form-item.component.d.ts +90 -0
  67. package/form/si-form-item-control-input.directive.d.ts +18 -0
  68. package/form/si-form-item.control.d.ts +35 -0
  69. package/form/si-form-validation-error.model.d.ts +55 -0
  70. package/form/si-form-validation-error.provider.d.ts +11 -0
  71. package/form/si-form-validation-error.service.d.ts +42 -0
  72. package/form/si-form-validation-tooltip/si-form-validation-tooltip.component.d.ts +13 -0
  73. package/form/si-form-validation-tooltip/si-form-validation-tooltip.directive.d.ts +42 -0
  74. package/form/si-form.module.d.ts +25 -0
  75. package/icon/element-icons.d.ts +10 -0
  76. package/icon-status/index.d.ts +6 -0
  77. package/icon-status/package.json +3 -0
  78. package/icon-status/si-icon-status.component.d.ts +24 -0
  79. package/icon-status/si-icon-status.module.d.ts +7 -0
  80. package/language-switcher/index.d.ts +7 -0
  81. package/language-switcher/iso-language-value.d.ts +14 -0
  82. package/language-switcher/package.json +3 -0
  83. package/language-switcher/si-language-switcher.component.d.ts +32 -0
  84. package/language-switcher/si-language-switcher.module.d.ts +7 -0
  85. package/number-input/index.d.ts +6 -0
  86. package/number-input/package.json +3 -0
  87. package/number-input/si-number-input.component.d.ts +106 -0
  88. package/number-input/si-number-input.module.d.ts +7 -0
  89. package/package.json +75 -3
  90. package/password-strength/index.d.ts +7 -0
  91. package/password-strength/package.json +3 -0
  92. package/password-strength/si-password-strength.component.d.ts +25 -0
  93. package/password-strength/si-password-strength.directive.d.ts +54 -0
  94. package/password-strength/si-password-strength.module.d.ts +8 -0
  95. package/pills-input/index.d.ts +9 -0
  96. package/pills-input/package.json +3 -0
  97. package/pills-input/si-input-pill.component.d.ts +9 -0
  98. package/pills-input/si-pills-input-csv.directive.d.ts +8 -0
  99. package/pills-input/si-pills-input-email.directive.d.ts +10 -0
  100. package/pills-input/si-pills-input-pattern-base.d.ts +19 -0
  101. package/pills-input/si-pills-input-value-handler.d.ts +12 -0
  102. package/pills-input/si-pills-input.component.d.ts +87 -0
  103. package/pills-input/si-pills-input.module.d.ts +9 -0
  104. package/popover/index.d.ts +6 -0
  105. package/popover/package.json +3 -0
  106. package/popover/si-popover.component.d.ts +26 -0
  107. package/popover/si-popover.directive.d.ts +89 -0
  108. package/popover/si-popover.module.d.ts +7 -0
  109. package/popover-next/index.d.ts +7 -0
  110. package/popover-next/package.json +3 -0
  111. package/popover-next/si-popover-description.directive.d.ts +7 -0
  112. package/popover-next/si-popover-next.directive.d.ts +61 -0
  113. package/popover-next/si-popover-title.directive.d.ts +7 -0
  114. package/popover-next/si-popover.component.d.ts +27 -0
  115. package/progressbar/index.d.ts +6 -0
  116. package/progressbar/package.json +3 -0
  117. package/progressbar/si-progressbar.component.d.ts +43 -0
  118. package/progressbar/si-progressbar.module.d.ts +7 -0
  119. package/select/index.d.ts +18 -0
  120. package/select/options/si-select-complex-options.directive.d.ts +69 -0
  121. package/select/options/si-select-lazy-options.directive.d.ts +38 -0
  122. package/select/options/si-select-option.source.d.ts +49 -0
  123. package/select/options/si-select-options-strategy.base.d.ts +35 -0
  124. package/select/options/si-select-options-strategy.d.ts +37 -0
  125. package/select/options/si-select-simple-options.directive.d.ts +34 -0
  126. package/select/package.json +3 -0
  127. package/select/select-input/si-select-input.component.d.ts +43 -0
  128. package/select/select-list/si-select-list-has-filter.component.d.ts +20 -0
  129. package/select/select-list/si-select-list.base.d.ts +37 -0
  130. package/select/select-list/si-select-list.component.d.ts +15 -0
  131. package/select/select-option/si-select-option-row.component.d.ts +16 -0
  132. package/select/select-option/si-select-option.component.d.ts +9 -0
  133. package/select/selection/si-select-multi-value.directive.d.ts +26 -0
  134. package/select/selection/si-select-selection-strategy.d.ts +58 -0
  135. package/select/selection/si-select-single-value.directive.d.ts +26 -0
  136. package/select/si-select-action.directive.d.ts +12 -0
  137. package/select/si-select-actions.directive.d.ts +5 -0
  138. package/select/si-select-group-template.directive.d.ts +20 -0
  139. package/select/si-select-option-row-template.directive.d.ts +9 -0
  140. package/select/si-select-option-template.directive.d.ts +21 -0
  141. package/select/si-select.component.d.ts +96 -0
  142. package/select/si-select.module.d.ts +15 -0
  143. package/select/si-select.types.d.ts +65 -0
  144. package/skip-links/index.d.ts +5 -0
  145. package/skip-links/package.json +3 -0
  146. package/skip-links/si-skip-link-target.directive.d.ts +27 -0
  147. package/skip-links/si-skip-links.component.d.ts +9 -0
  148. package/skip-links/skip-link.service.d.ts +14 -0
  149. package/summary-widget/index.d.ts +5 -0
  150. package/summary-widget/package.json +3 -0
  151. package/summary-widget/si-summary-widget.component.d.ts +44 -0
  152. package/template-i18n.json +29 -1
  153. package/toast-notification/index.d.ts +6 -0
  154. package/toast-notification/package.json +3 -0
  155. package/toast-notification/si-toast-notification/si-toast-notification.component.d.ts +17 -0
  156. package/toast-notification/si-toast-notification-drawer/si-toast-notification-drawer.component.d.ts +9 -0
  157. package/toast-notification/si-toast-notification.service.d.ts +41 -0
  158. package/toast-notification/si-toast.model.d.ts +25 -0
  159. package/translate/si-translatable-keys.interface.d.ts +28 -0
  160. package/typeahead/index.d.ts +8 -0
  161. package/typeahead/package.json +3 -0
  162. package/typeahead/si-typeahead-item-template.directive.d.ts +7 -0
  163. package/typeahead/si-typeahead.component.d.ts +22 -0
  164. package/typeahead/si-typeahead.directive.d.ts +196 -0
  165. package/typeahead/si-typeahead.model.d.ts +60 -0
  166. package/typeahead/si-typeahead.module.d.ts +8 -0
  167. package/typeahead/si-typeahead.sorting.d.ts +10 -0
  168. package/wizard/index.d.ts +7 -0
  169. package/wizard/package.json +3 -0
  170. package/wizard/si-wizard-step.component.d.ts +21 -0
  171. package/wizard/si-wizard.component.d.ts +196 -0
  172. package/wizard/si-wizard.module.d.ts +8 -0
@@ -0,0 +1,746 @@
1
+ import { Overlay } from '@angular/cdk/overlay';
2
+ import { ComponentPortal } from '@angular/cdk/portal';
3
+ import * as i0 from '@angular/core';
4
+ import { inject, computed, viewChild, ElementRef, HostListener, ChangeDetectionStrategy, Component, input, booleanAttribute, numberAttribute, output, signal, Injector, Directive, NgModule } from '@angular/core';
5
+ import * as i1$1 from '@siemens/element-ng/autocomplete';
6
+ import { SiAutocompleteDirective, SiAutocompleteListboxDirective, SiAutocompleteOptionDirective } from '@siemens/element-ng/autocomplete';
7
+ import { ReplaySubject, isObservable, of } from 'rxjs';
8
+ import { map } from 'rxjs/operators';
9
+ import { NgTemplateOutlet } from '@angular/common';
10
+ import { SiIconNextComponent } from '@siemens/element-ng/icon';
11
+ import * as i1 from '@siemens/element-translate-ng/translate';
12
+ import { SiTranslateModule } from '@siemens/element-translate-ng/translate';
13
+
14
+ /**
15
+ * Copyright Siemens 2016 - 2025.
16
+ * SPDX-License-Identifier: MIT
17
+ */
18
+ class SiTypeaheadComponent {
19
+ parent = inject(SiTypeaheadDirective);
20
+ matches = computed(() => this.parent.typeaheadOptionsLimit()
21
+ ? this.parent.foundMatches().slice(0, this.parent.typeaheadOptionsLimit())
22
+ : this.parent.foundMatches());
23
+ multiselect = false;
24
+ // Store the number of rendered matches to know if the height needs to be recalculated.
25
+ renderedMatchesLength = 0;
26
+ subscription;
27
+ typeaheadElement = viewChild.required('typeahead', {
28
+ read: ElementRef
29
+ });
30
+ autocompleteDirective = inject(SiAutocompleteDirective);
31
+ ngOnInit() {
32
+ this.multiselect = !!this.parent.typeaheadMultiSelect();
33
+ }
34
+ ngAfterViewInit() {
35
+ this.setHeight(this.typeaheadElement());
36
+ this.renderedMatchesLength = this.matches().length;
37
+ }
38
+ ngOnDestroy() {
39
+ if (this.subscription) {
40
+ this.subscription.unsubscribe();
41
+ }
42
+ }
43
+ onMouseDown(event) {
44
+ event.preventDefault();
45
+ }
46
+ /*
47
+ * Set the height of the element passed to it (typeahead) if there are items displayed,
48
+ * the number of displayed items changed and it is scrollable.
49
+ */
50
+ setHeight(element) {
51
+ if (this.matches().length !== 0 && this.matches().length !== this.renderedMatchesLength) {
52
+ if (this.parent.typeaheadScrollable() &&
53
+ this.parent.typeaheadOptionsInScrollableView() < this.matches().length) {
54
+ const computedStyle = getComputedStyle(element.nativeElement);
55
+ const matchComputedStyle = getComputedStyle(element.nativeElement.firstElementChild);
56
+ const matchHeight = parseFloat(matchComputedStyle.height || '0');
57
+ const paddingTop = parseFloat(computedStyle.paddingTop || '0');
58
+ const paddingBottom = parseFloat(computedStyle.paddingBottom || '');
59
+ const height = this.parent.typeaheadOptionsInScrollableView() * matchHeight;
60
+ element.nativeElement.style.maxBlockSize = `${height + paddingTop + paddingBottom + this.parent.typeaheadScrollableAdditionalHeight()}px`;
61
+ }
62
+ else {
63
+ element.nativeElement.style.maxBlockSize = 'auto';
64
+ }
65
+ }
66
+ }
67
+ // Gets called when a match is selected by clicking on it.
68
+ selectMatch(match) {
69
+ this.parent.selectMatch(match);
70
+ }
71
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiTypeaheadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
72
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: SiTypeaheadComponent, isStandalone: true, selector: "si-typeahead", host: { listeners: { "mousedown": "onMouseDown($event)" }, classAttribute: "w-100" }, viewQueries: [{ propertyName: "typeaheadElement", first: true, predicate: ["typeahead"], descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "<!-- Template to be used for every match, can be replaced using an input. -->\n<ng-template #defaultItemTemplate let-match=\"match\" siTypeaheadTemplate>\n @if (multiselect) {\n <div class=\"d-flex pe-4\" aria-hidden=\"true\">\n <span class=\"form-check-input si-form-checkbox\" [class.checked]=\"match.itemSelected\"></span>\n </div>\n }\n @if (match.iconClass) {\n <si-icon-next class=\"icon me-2\" [icon]=\"match.iconClass\" />\n }\n @for (segment of match.result; track $index) {\n <span [class.typeahead-match-segment-matching]=\"segment.isMatching\">{{ segment.text }}</span>\n }\n</ng-template>\n\n<!-- Only display the component if there are any matches and set the CSS transform to properly position the typeahead -->\n<ul\n #typeahead\n class=\"typeahead dropdown-menu\"\n [siAutocompleteListboxFor]=\"autocompleteDirective\"\n [siAutocompleteDefaultIndex]=\"parent.typeaheadAutoSelectIndex()\"\n [attr.aria-label]=\"parent.typeaheadAutocompleteListLabel() | translate\"\n [class.d-none]=\"!matches().length\"\n (siAutocompleteOptionSubmitted)=\"selectMatch($event)\"\n>\n <!-- Loop through every match and bind events, the mousedown prevent default is to prevent the host from losing focus on click -->\n @for (match of matches(); track $index) {\n <li\n #typeaheadMatch\n class=\"dropdown-item me-4\"\n [siAutocompleteOption]=\"match\"\n [attr.aria-label]=\"match.text\"\n [attr.aria-selected]=\"multiselect ? match.itemSelected : null\"\n (click)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.preventDefault()\"\n >\n <!-- Display either a template set as the input or the template above -->\n <ng-template\n [ngTemplateOutlet]=\"parent.typeaheadItemTemplate() || defaultItemTemplate\"\n [ngTemplateOutletContext]=\"{\n item: match.option,\n index: $index,\n match: match,\n query: parent.query()\n }\"\n />\n </li>\n }\n</ul>\n", styles: [".dropdown-menu{display:block;position:relative;inset-block-start:0;inset-inline-start:0;margin-block-start:1px;overflow-y:auto;overflow-x:hidden;max-block-size:100%}.typeahead-match-segment-matching{font-weight:700}.dropdown-item *{flex-shrink:0}.dropdown-item span{white-space:pre-wrap}\n"], dependencies: [{ kind: "directive", type: SiAutocompleteListboxDirective, selector: "[siAutocompleteListboxFor]", inputs: ["id", "siAutocompleteListboxFor", "siAutocompleteDefaultIndex"], outputs: ["siAutocompleteOptionSubmitted"], exportAs: ["siAutocompleteListbox"] }, { kind: "directive", type: SiAutocompleteOptionDirective, selector: "[siAutocompleteOption]", inputs: ["id", "disabled", "siAutocompleteOption"], exportAs: ["siAutocompleteOption"] }, { kind: "component", type: SiIconNextComponent, selector: "si-icon-next", inputs: ["icon"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: SiTranslateModule }, { kind: "pipe", type: i1.SiTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
73
+ }
74
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiTypeaheadComponent, decorators: [{
75
+ type: Component,
76
+ args: [{ selector: 'si-typeahead', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
77
+ SiAutocompleteListboxDirective,
78
+ SiAutocompleteOptionDirective,
79
+ SiIconNextComponent,
80
+ NgTemplateOutlet,
81
+ SiTranslateModule
82
+ ], host: { class: 'w-100' }, template: "<!-- Template to be used for every match, can be replaced using an input. -->\n<ng-template #defaultItemTemplate let-match=\"match\" siTypeaheadTemplate>\n @if (multiselect) {\n <div class=\"d-flex pe-4\" aria-hidden=\"true\">\n <span class=\"form-check-input si-form-checkbox\" [class.checked]=\"match.itemSelected\"></span>\n </div>\n }\n @if (match.iconClass) {\n <si-icon-next class=\"icon me-2\" [icon]=\"match.iconClass\" />\n }\n @for (segment of match.result; track $index) {\n <span [class.typeahead-match-segment-matching]=\"segment.isMatching\">{{ segment.text }}</span>\n }\n</ng-template>\n\n<!-- Only display the component if there are any matches and set the CSS transform to properly position the typeahead -->\n<ul\n #typeahead\n class=\"typeahead dropdown-menu\"\n [siAutocompleteListboxFor]=\"autocompleteDirective\"\n [siAutocompleteDefaultIndex]=\"parent.typeaheadAutoSelectIndex()\"\n [attr.aria-label]=\"parent.typeaheadAutocompleteListLabel() | translate\"\n [class.d-none]=\"!matches().length\"\n (siAutocompleteOptionSubmitted)=\"selectMatch($event)\"\n>\n <!-- Loop through every match and bind events, the mousedown prevent default is to prevent the host from losing focus on click -->\n @for (match of matches(); track $index) {\n <li\n #typeaheadMatch\n class=\"dropdown-item me-4\"\n [siAutocompleteOption]=\"match\"\n [attr.aria-label]=\"match.text\"\n [attr.aria-selected]=\"multiselect ? match.itemSelected : null\"\n (click)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.preventDefault()\"\n >\n <!-- Display either a template set as the input or the template above -->\n <ng-template\n [ngTemplateOutlet]=\"parent.typeaheadItemTemplate() || defaultItemTemplate\"\n [ngTemplateOutletContext]=\"{\n item: match.option,\n index: $index,\n match: match,\n query: parent.query()\n }\"\n />\n </li>\n }\n</ul>\n", styles: [".dropdown-menu{display:block;position:relative;inset-block-start:0;inset-inline-start:0;margin-block-start:1px;overflow-y:auto;overflow-x:hidden;max-block-size:100%}.typeahead-match-segment-matching{font-weight:700}.dropdown-item *{flex-shrink:0}.dropdown-item span{white-space:pre-wrap}\n"] }]
83
+ }], propDecorators: { onMouseDown: [{
84
+ type: HostListener,
85
+ args: ['mousedown', ['$event']]
86
+ }] } });
87
+
88
+ class SiTypeaheadSorting {
89
+ sortMatches(matches) {
90
+ // Sort the matches,
91
+ // first is the option and query an exact match.
92
+ // then according to whether it is matching in the beginning,
93
+ // then whether it matches the entire untokenized query.
94
+ // then according to how many unique separate matches it contains.
95
+ // then according to how many unique matches it contains.
96
+ // then according to how many matches it contains.
97
+ return matches.sort((matchA, matchB) => {
98
+ if (matchA.stringMatch || matchB.stringMatch) {
99
+ return matchA.stringMatch ? -1 : 1;
100
+ }
101
+ if (matchA.atBeginning) {
102
+ return !matchB.atBeginning ? -1 : this.compareMatches(matchA, matchB);
103
+ }
104
+ else {
105
+ return matchB.atBeginning ? 1 : this.compareMatches(matchA, matchB);
106
+ }
107
+ });
108
+ }
109
+ compareMatchesNumbers(matchA, matchB) {
110
+ return (matchB.uniqueSeparateMatches - matchA.uniqueSeparateMatches ||
111
+ matchB.uniqueMatches - matchA.uniqueMatches ||
112
+ matchB.matches - matchA.matches);
113
+ }
114
+ compareMatches(matchA, matchB) {
115
+ if (matchA.matchesEntireQuery) {
116
+ return !matchB.matchesEntireQuery ? -1 : this.compareMatchesNumbers(matchA, matchB);
117
+ }
118
+ else {
119
+ return matchB.matchesEntireQuery ? 1 : this.compareMatchesNumbers(matchA, matchB);
120
+ }
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Copyright Siemens 2016 - 2025.
126
+ * SPDX-License-Identifier: MIT
127
+ */
128
+ class SiTypeaheadDirective {
129
+ static overlayPositions = [
130
+ {
131
+ overlayX: 'start',
132
+ overlayY: 'top',
133
+ originX: 'start',
134
+ originY: 'bottom',
135
+ offsetY: 2
136
+ },
137
+ {
138
+ overlayX: 'start',
139
+ overlayY: 'bottom',
140
+ originX: 'start',
141
+ originY: 'top',
142
+ offsetY: -4
143
+ },
144
+ {
145
+ overlayX: 'end',
146
+ overlayY: 'top',
147
+ originX: 'end',
148
+ originY: 'bottom',
149
+ offsetY: 2
150
+ },
151
+ {
152
+ overlayX: 'end',
153
+ overlayY: 'bottom',
154
+ originX: 'end',
155
+ originY: 'top',
156
+ offsetY: -4
157
+ }
158
+ ];
159
+ /**
160
+ * Set the options of the typeahead.
161
+ * Has to be either an Array or an Observable of an Array
162
+ * of options (string or object)
163
+ */
164
+ siTypeahead = input.required();
165
+ /**
166
+ * Turns on/off the processing (searching and sorting) of the typeahead options.
167
+ * Is used when searching and sorting is done externally.
168
+ *
169
+ * @defaultValue true
170
+ */
171
+ typeaheadProcess = input(true, {
172
+ transform: booleanAttribute
173
+ });
174
+ /**
175
+ * Makes the typeahead scrollable and sets its height.
176
+ * Uses {@link typeaheadOptionsInScrollableView} and {@link typeaheadScrollableAdditionalHeight}.
177
+ *
178
+ * @defaultValue false
179
+ */
180
+ typeaheadScrollable = input(false, { transform: booleanAttribute });
181
+ /**
182
+ * If {@link typeaheadScrollable} is `true`, defines the number of items visible at once.
183
+ *
184
+ * @defaultValue 10
185
+ */
186
+ typeaheadOptionsInScrollableView = input(10);
187
+ /**
188
+ * Defines the maximum number of items added into the DOM. Default is 20 and 0 means unlimited.
189
+ *
190
+ * @defaultValue 20
191
+ */
192
+ typeaheadOptionsLimit = input(20);
193
+ /**
194
+ * If {@link typeaheadScrollable} is `true`, defines the number of additional pixels
195
+ * to be added the the bottom of the typeahead to show users that it is scrollable.
196
+ *
197
+ * @defaultValue 13
198
+ */
199
+ typeaheadScrollableAdditionalHeight = input(13);
200
+ /**
201
+ * Defines the index of the item which should automatically be selected.
202
+ *
203
+ * @defaultValue 0
204
+ */
205
+ typeaheadAutoSelectIndex = input(0, { transform: numberAttribute });
206
+ /**
207
+ * Defines whether the typeahead can be closed using escape.
208
+ *
209
+ * @defaultValue true
210
+ */
211
+ typeaheadCloseOnEsc = input(true, { transform: booleanAttribute });
212
+ /**
213
+ * Defines whether the host value should be cleared when a value is selected.
214
+ *
215
+ * @defaultValue false
216
+ */
217
+ typeaheadClearValueOnSelect = input(false, { transform: booleanAttribute });
218
+ /**
219
+ * Defines the number of milliseconds to wait before displaying a typeahead after the host was
220
+ * focused or a value inputted.
221
+ *
222
+ * @defaultValue 0
223
+ */
224
+ typeaheadWaitMs = input(0);
225
+ /**
226
+ * Defines the number of characters the value of the host needs to be before a typeahead is displayed.
227
+ * Use `0` to have it display when focussing the host (clicking or tabbing into it).
228
+ *
229
+ * @defaultValue 1
230
+ */
231
+ typeaheadMinLength = input(1);
232
+ /**
233
+ * Defines the name of the field/property the option string is in when the typeahead options are objects.
234
+ *
235
+ * @defaultValue 'name'
236
+ */
237
+ typeaheadOptionField = input('name');
238
+ /**
239
+ * Defines whether multiselection of typeahead is possible with checkboxes.
240
+ *
241
+ * @defaultValue false
242
+ */
243
+ typeaheadMultiSelect = input(false, { transform: booleanAttribute });
244
+ /**
245
+ * Defines whether to tokenize the search or match the whole search.
246
+ *
247
+ * @defaultValue true
248
+ */
249
+ typeaheadTokenize = input(true, { transform: booleanAttribute });
250
+ /**
251
+ * Defines whether and how to require to match with all the tokens if {@link typeaheadTokenize} is enabled.
252
+ * - `no` does not require all of the tokens to match.
253
+ * - `once` requires all of the parts to be found in the search.
254
+ * - `separately` requires all of the parts to be found in the search where there is not an overlapping different result.
255
+ * - `independently` requires all of the parts to be found in the search where there is not an overlapping or adjacent different result.
256
+ * ('independently' also slightly changes sorting behavior in the same way.)
257
+ *
258
+ * @defaultValue 'separately'
259
+ */
260
+ typeaheadMatchAllTokens = input('separately');
261
+ /**
262
+ * Defines an optional template to use as the typeahead match item instead of the one built in.
263
+ * Gets the {@link TypeaheadOptionItemContext} passed to it.
264
+ */
265
+ typeaheadItemTemplate = input();
266
+ /**
267
+ * Skip the sorting of matches.
268
+ * If the value is `true`, the matches are sorted according to {@link SiTypeaheadSorting}.
269
+ *
270
+ * @defaultValue false
271
+ */
272
+ typeaheadSkipSortingMatches = input(false, { transform: booleanAttribute });
273
+ /**
274
+ * Screen reader only label for the autocomplete list.
275
+ *
276
+ * @defaultValue
277
+ * ```
278
+ * $localize`:@@SI_TYPEAHEAD.AUTOCOMPLETE_LIST_LABEL:Suggestions`
279
+ * ```
280
+ */
281
+ typeaheadAutocompleteListLabel = input($localize `:@@SI_TYPEAHEAD.AUTOCOMPLETE_LIST_LABEL:Suggestions`);
282
+ /**
283
+ * If set, the typeahead will at minium have the width of the connected input field.
284
+ *
285
+ * @defaultValue false
286
+ */
287
+ typeaheadFullWidth = input(false, { transform: booleanAttribute });
288
+ /**
289
+ * Emits an Event when the input field is changed.
290
+ */
291
+ typeaheadOnInput = output();
292
+ /**
293
+ * Emits an Event when a typeahead match is selected.
294
+ * The event is a {@link TypeaheadMatch}
295
+ */
296
+ typeaheadOnSelect = output();
297
+ /** @deprecated Never emits. Use {@link typeaheadOpenChange} instead. */
298
+ typeaheadOnMultiselectClose = output();
299
+ /**
300
+ * Emits an Event when a typeahead full match exists. A full match occurs when the entered text
301
+ * is equal to one of the typeahead options.
302
+ * The event is a {@link TypeaheadMatch}
303
+ */
304
+ typeaheadOnFullMatch = output();
305
+ /** @deprecated Use {@link typeaheadOpenChange} instead. */
306
+ typeaheadClosed = output();
307
+ /** Emits whenever the typeahead overlay is opened or closed. */
308
+ typeaheadOpenChange = output();
309
+ /** @internal */
310
+ foundMatches = signal([]);
311
+ /** @internal */
312
+ query = signal('');
313
+ /**
314
+ * Indicates whether the typeahead is shown.
315
+ */
316
+ get typeaheadOpen() {
317
+ return !!this.componentRef;
318
+ }
319
+ overlay = inject(Overlay);
320
+ elementRef = inject(ElementRef);
321
+ injector = inject(Injector);
322
+ autoComplete = inject(SiAutocompleteDirective);
323
+ $typeahead = new ReplaySubject(1);
324
+ componentRef;
325
+ component;
326
+ inputTimer;
327
+ sourceSubscription;
328
+ subscription;
329
+ matchSorter = new SiTypeaheadSorting();
330
+ overlayRef;
331
+ // Every time the main input changes, detect whether it is async and if it is not make an observable out of the array.
332
+ ngOnChanges(changes) {
333
+ if (changes.siTypeahead) {
334
+ this.sourceSubscription?.unsubscribe();
335
+ const typeahead = this.siTypeahead();
336
+ if (isObservable(typeahead)) {
337
+ this.sourceSubscription = typeahead.subscribe(this.$typeahead);
338
+ }
339
+ else {
340
+ this.$typeahead.next(typeahead);
341
+ }
342
+ }
343
+ }
344
+ // Clear the current input timeout (if set) and remove the component when the focus of the host is lost.
345
+ onBlur() {
346
+ this.clearTimer();
347
+ if (this.component) {
348
+ this.removeComponent();
349
+ }
350
+ this.subscription?.unsubscribe();
351
+ }
352
+ // Start the input timeout to display the typeahead when the host is focussed or a value is inputted into it.
353
+ onInput(event) {
354
+ const target = event.target;
355
+ if (!target) {
356
+ return;
357
+ }
358
+ // Get the value or otherwise textContent of the host element now, because later it could be reset.
359
+ const firstValue = target.value || target.textContent;
360
+ this.inputTimer ??= setTimeout(() => {
361
+ this.inputTimer = undefined;
362
+ const value = (target.value || target.textContent) ?? firstValue ?? '';
363
+ this.query.set(value);
364
+ this.subscription?.unsubscribe();
365
+ // The value needs to fulfil the minimum length requirement set.
366
+ if (value.length >= this.typeaheadMinLength()) {
367
+ this.subscription = this.getMatches(this.$typeahead, value).subscribe(matches => {
368
+ this.foundMatches.set(matches);
369
+ const escapedQuery = this.escapeRegex(value);
370
+ const equalsExp = new RegExp(`^${escapedQuery}$`, 'i');
371
+ const fullMatches = matches.filter(match => match.result.length === 1 && equalsExp.test(match.text));
372
+ if (fullMatches.length > 0) {
373
+ this.typeaheadOnFullMatch.emit(fullMatches[0]);
374
+ }
375
+ if (matches.length) {
376
+ this.loadComponent();
377
+ }
378
+ else {
379
+ this.removeComponent();
380
+ }
381
+ });
382
+ }
383
+ else {
384
+ this.removeComponent();
385
+ }
386
+ this.typeaheadOnInput.emit(value ?? '');
387
+ }, this.typeaheadWaitMs());
388
+ }
389
+ onKeydownEscape() {
390
+ if (this.typeaheadCloseOnEsc()) {
391
+ this.subscription?.unsubscribe();
392
+ this.clearTimer();
393
+ this.removeComponent();
394
+ }
395
+ }
396
+ onKeydownSpace(event) {
397
+ if (this.typeaheadMultiSelect()) {
398
+ // Avoid space character to be inserted into the input field
399
+ event.preventDefault();
400
+ const value = this.autoComplete.active?.value();
401
+ if (value) {
402
+ this.selectMatch(value);
403
+ // this forces change detection in the typeahead component.
404
+ this.foundMatches.update(matches => [...matches]);
405
+ }
406
+ }
407
+ }
408
+ ngOnDestroy() {
409
+ this.clearTimer();
410
+ this.sourceSubscription?.unsubscribe();
411
+ this.subscription?.unsubscribe();
412
+ this.overlayRef?.dispose();
413
+ }
414
+ // Dynamically create the typeahead component and then set the matches and the query.
415
+ loadComponent() {
416
+ if (!this.overlayRef?.hasAttached()) {
417
+ this.overlayRef?.dispose();
418
+ this.overlayRef = this.overlay.create({
419
+ positionStrategy: this.overlay
420
+ .position()
421
+ .flexibleConnectedTo(this.elementRef.nativeElement)
422
+ .withPositions(SiTypeaheadDirective.overlayPositions),
423
+ minWidth: this.typeaheadFullWidth()
424
+ ? this.elementRef.nativeElement.getBoundingClientRect().width + 2 // 2px border
425
+ : 0
426
+ });
427
+ }
428
+ if (this.overlayRef.hasAttached()) {
429
+ return;
430
+ }
431
+ const typeaheadPortal = new ComponentPortal(SiTypeaheadComponent, null, this.injector);
432
+ this.componentRef = this.overlayRef.attach(typeaheadPortal);
433
+ this.component = this.componentRef.instance;
434
+ this.typeaheadOpenChange.emit(true);
435
+ }
436
+ // Get the matches and push them to the subject of the component, then set the query of the component.
437
+ // If the typeahead options are objects, pick the specified field/property.
438
+ getOptionValue(option, field) {
439
+ return typeof option !== 'object' ? option.toString() : (option[field] ?? '');
440
+ }
441
+ // If enabled, process the matches and sort through them.
442
+ getMatches(observableList, query) {
443
+ try {
444
+ const entireQueryRegex = new RegExp(this.escapeRegex(query), 'gi');
445
+ const queryParts = this.typeaheadTokenize()
446
+ ? query.split(/\s+/g).filter(queryPart => queryPart)
447
+ : query
448
+ ? [query]
449
+ : [];
450
+ const queryRegexes = queryParts.map(queryPart => new RegExp(this.escapeRegex(queryPart), 'gi'));
451
+ return observableList.pipe(map(options => {
452
+ // Check if the options need to be processed, if not just return an unprocessed object.
453
+ if (!this.typeaheadProcess()) {
454
+ return options.map(option => {
455
+ const optionValue = this.getOptionValue(option, this.typeaheadOptionField());
456
+ const itemSelected = this.typeaheadMultiSelect()
457
+ ? this.getOptionValue(option, 'selected')
458
+ : false;
459
+ const iconClass = this.getOptionValue(option, 'iconClass');
460
+ return {
461
+ option,
462
+ itemSelected,
463
+ text: optionValue,
464
+ iconClass,
465
+ result: optionValue
466
+ ? [{ text: optionValue, isMatching: false, matches: 0, uniqueMatches: 0 }]
467
+ : [],
468
+ stringMatch: false,
469
+ atBeginning: false,
470
+ matches: 0,
471
+ uniqueMatches: 0,
472
+ uniqueSeparateMatches: 0,
473
+ matchesEntireQuery: false,
474
+ matchesAllParts: false,
475
+ matchesAllPartsSeparately: false,
476
+ active: false
477
+ };
478
+ });
479
+ }
480
+ else {
481
+ // Process the options.
482
+ const matches = [];
483
+ options.forEach(option => {
484
+ const optionValue = this.getOptionValue(option, this.typeaheadOptionField());
485
+ const stringMatch = optionValue.toLocaleLowerCase().trim() === query.toLocaleLowerCase().trim();
486
+ const itemSelected = this.typeaheadMultiSelect()
487
+ ? option['selected']
488
+ : false;
489
+ const iconClass = this.getOptionValue(option, 'iconClass');
490
+ const candidate = {
491
+ option,
492
+ itemSelected,
493
+ text: optionValue,
494
+ iconClass,
495
+ result: [],
496
+ stringMatch,
497
+ atBeginning: false,
498
+ matches: 0,
499
+ uniqueMatches: 0,
500
+ uniqueSeparateMatches: 0,
501
+ matchesEntireQuery: false,
502
+ matchesAllParts: false,
503
+ matchesAllPartsSeparately: false
504
+ };
505
+ // Only search the options if a part of the query is at least one character long to prevent an endless loop.
506
+ if (queryParts.length === 0) {
507
+ if (optionValue) {
508
+ candidate.result.push({
509
+ text: optionValue,
510
+ isMatching: false,
511
+ matches: 0,
512
+ uniqueMatches: 0
513
+ });
514
+ }
515
+ matches.push(candidate);
516
+ }
517
+ else {
518
+ const allResults = [];
519
+ const allIndexes = [];
520
+ candidate.matchesEntireQuery = !!optionValue.match(entireQueryRegex);
521
+ // Loop through the option value to find multiple matches, then store every segment (matching or non-matching) in the results.
522
+ queryRegexes.forEach((queryRegex, index) => {
523
+ let regexMatch = queryRegex.exec(optionValue);
524
+ while (regexMatch) {
525
+ allResults.push({
526
+ index,
527
+ start: regexMatch.index,
528
+ end: regexMatch.index + regexMatch[0].length,
529
+ result: regexMatch[0]
530
+ });
531
+ if (!regexMatch.index) {
532
+ candidate.atBeginning = true;
533
+ }
534
+ if (!allIndexes.includes(index)) {
535
+ allIndexes.push(index);
536
+ }
537
+ regexMatch = queryRegex.exec(optionValue);
538
+ }
539
+ });
540
+ candidate.matchesAllParts = allIndexes.length === queryParts.length;
541
+ // Check if all parts of the query match at least once (if required).
542
+ if (this.typeaheadMatchAllTokens() === 'no' || candidate.matchesAllParts) {
543
+ const combinedResults = [];
544
+ // First combine intersecting (or if set to independently adjacent) results to combined results.
545
+ // We achieve this by first sorting them by the starting index, then by the ending index and then looking for overlaps.
546
+ allResults
547
+ .sort((a, b) => a.start - b.start || a.end - b.end)
548
+ .forEach(result => {
549
+ if (combinedResults.length) {
550
+ const foundPreviousResult = combinedResults.find(previousResult => this.typeaheadMatchAllTokens() === 'independently'
551
+ ? result.start <= previousResult.end
552
+ : result.start < previousResult.end);
553
+ if (foundPreviousResult) {
554
+ foundPreviousResult.result += result.result.slice(foundPreviousResult.end - result.start, result.result.length);
555
+ if (result.end > foundPreviousResult.end) {
556
+ foundPreviousResult.end = result.end;
557
+ }
558
+ foundPreviousResult.indexes.push(result.index);
559
+ if (!foundPreviousResult.uniqueIndexes.includes(result.index)) {
560
+ foundPreviousResult.uniqueIndexes.push(result.index);
561
+ }
562
+ return;
563
+ }
564
+ }
565
+ combinedResults.push({
566
+ ...result,
567
+ indexes: [result.index],
568
+ uniqueIndexes: [result.index]
569
+ });
570
+ });
571
+ // Recursively go through all unique combinations of the unique indexes to get the option which has the most indexes.
572
+ const countUniqueSubindexes = (indexIndex = 0, previousIndexes = []) => indexIndex === combinedResults.length
573
+ ? previousIndexes.length
574
+ : Math.max(previousIndexes.length, ...combinedResults[indexIndex].uniqueIndexes
575
+ .filter(index => !previousIndexes.includes(index))
576
+ .map(index => countUniqueSubindexes(indexIndex + 1, [index, ...previousIndexes])));
577
+ candidate.uniqueSeparateMatches = countUniqueSubindexes();
578
+ candidate.matchesAllPartsSeparately =
579
+ candidate.uniqueSeparateMatches === queryParts.length;
580
+ let currentPreviousEnd = 0;
581
+ // Add the combined results to the candidate including the non-matching parts in between.
582
+ combinedResults.forEach(result => {
583
+ const textBefore = optionValue.slice(currentPreviousEnd, result.start);
584
+ if (textBefore) {
585
+ candidate.result.push({
586
+ text: textBefore,
587
+ isMatching: false,
588
+ matches: 0,
589
+ uniqueMatches: 0
590
+ });
591
+ }
592
+ candidate.result.push({
593
+ text: result.result,
594
+ isMatching: true,
595
+ matches: result.indexes.length,
596
+ uniqueMatches: result.uniqueIndexes.length
597
+ });
598
+ currentPreviousEnd = result.end;
599
+ candidate.matches += result.indexes.length;
600
+ candidate.uniqueMatches += result.uniqueIndexes.length;
601
+ });
602
+ // Check if there are result segments and all parts are matched independently (if required).
603
+ if (candidate.result.length !== 0 &&
604
+ ((this.typeaheadMatchAllTokens() !== 'separately' &&
605
+ this.typeaheadMatchAllTokens() !== 'independently') ||
606
+ candidate.matchesAllPartsSeparately)) {
607
+ const textAtEnd = optionValue.slice(currentPreviousEnd);
608
+ if (textAtEnd) {
609
+ candidate.result.push({
610
+ text: textAtEnd,
611
+ isMatching: false,
612
+ matches: 0,
613
+ uniqueMatches: 0
614
+ });
615
+ }
616
+ matches.push(candidate);
617
+ }
618
+ }
619
+ }
620
+ });
621
+ if (this.typeaheadSkipSortingMatches()) {
622
+ return matches;
623
+ }
624
+ else {
625
+ return this.matchSorter.sortMatches(matches);
626
+ }
627
+ }
628
+ }));
629
+ }
630
+ catch {
631
+ // Could not create regex (only in extremely rare cases, maybe even impossible), so return an empty array.
632
+ return of([]);
633
+ }
634
+ }
635
+ // Select a match, either gets called due to a enter keypress or from the component due to a click.
636
+ /** @internal */
637
+ selectMatch(match) {
638
+ match.itemSelected = !match.itemSelected;
639
+ if (!this.typeaheadMultiSelect()) {
640
+ const inputElement = this.elementRef.nativeElement.querySelector('input') ?? this.elementRef.nativeElement;
641
+ inputElement.value = this.typeaheadClearValueOnSelect() ? '' : match.text;
642
+ inputElement.dispatchEvent(new Event('input'));
643
+ }
644
+ // Clear the current input timeout (if set) and remove the typeahead.
645
+ this.clearTimer();
646
+ this.typeaheadOnSelect.emit(match);
647
+ if (!this.typeaheadMultiSelect()) {
648
+ this.removeComponent();
649
+ }
650
+ }
651
+ // Remove the component by clearing the viewContainerRef
652
+ removeComponent() {
653
+ if (this.overlayRef?.hasAttached()) {
654
+ this.overlayRef?.detach();
655
+ this.typeaheadClosed.emit();
656
+ this.typeaheadOpenChange.emit(false);
657
+ }
658
+ this.componentRef?.destroy();
659
+ this.componentRef = undefined;
660
+ this.component = undefined;
661
+ }
662
+ clearTimer() {
663
+ if (this.inputTimer) {
664
+ clearTimeout(this.inputTimer);
665
+ this.inputTimer = undefined;
666
+ }
667
+ }
668
+ escapeRegex(query) {
669
+ return query.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
670
+ }
671
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiTypeaheadDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
672
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.6", type: SiTypeaheadDirective, isStandalone: true, selector: "[siTypeahead]", inputs: { siTypeahead: { classPropertyName: "siTypeahead", publicName: "siTypeahead", isSignal: true, isRequired: true, transformFunction: null }, typeaheadProcess: { classPropertyName: "typeaheadProcess", publicName: "typeaheadProcess", isSignal: true, isRequired: false, transformFunction: null }, typeaheadScrollable: { classPropertyName: "typeaheadScrollable", publicName: "typeaheadScrollable", isSignal: true, isRequired: false, transformFunction: null }, typeaheadOptionsInScrollableView: { classPropertyName: "typeaheadOptionsInScrollableView", publicName: "typeaheadOptionsInScrollableView", isSignal: true, isRequired: false, transformFunction: null }, typeaheadOptionsLimit: { classPropertyName: "typeaheadOptionsLimit", publicName: "typeaheadOptionsLimit", isSignal: true, isRequired: false, transformFunction: null }, typeaheadScrollableAdditionalHeight: { classPropertyName: "typeaheadScrollableAdditionalHeight", publicName: "typeaheadScrollableAdditionalHeight", isSignal: true, isRequired: false, transformFunction: null }, typeaheadAutoSelectIndex: { classPropertyName: "typeaheadAutoSelectIndex", publicName: "typeaheadAutoSelectIndex", isSignal: true, isRequired: false, transformFunction: null }, typeaheadCloseOnEsc: { classPropertyName: "typeaheadCloseOnEsc", publicName: "typeaheadCloseOnEsc", isSignal: true, isRequired: false, transformFunction: null }, typeaheadClearValueOnSelect: { classPropertyName: "typeaheadClearValueOnSelect", publicName: "typeaheadClearValueOnSelect", isSignal: true, isRequired: false, transformFunction: null }, typeaheadWaitMs: { classPropertyName: "typeaheadWaitMs", publicName: "typeaheadWaitMs", isSignal: true, isRequired: false, transformFunction: null }, typeaheadMinLength: { classPropertyName: "typeaheadMinLength", publicName: "typeaheadMinLength", isSignal: true, isRequired: false, transformFunction: null }, typeaheadOptionField: { classPropertyName: "typeaheadOptionField", publicName: "typeaheadOptionField", isSignal: true, isRequired: false, transformFunction: null }, typeaheadMultiSelect: { classPropertyName: "typeaheadMultiSelect", publicName: "typeaheadMultiSelect", isSignal: true, isRequired: false, transformFunction: null }, typeaheadTokenize: { classPropertyName: "typeaheadTokenize", publicName: "typeaheadTokenize", isSignal: true, isRequired: false, transformFunction: null }, typeaheadMatchAllTokens: { classPropertyName: "typeaheadMatchAllTokens", publicName: "typeaheadMatchAllTokens", isSignal: true, isRequired: false, transformFunction: null }, typeaheadItemTemplate: { classPropertyName: "typeaheadItemTemplate", publicName: "typeaheadItemTemplate", isSignal: true, isRequired: false, transformFunction: null }, typeaheadSkipSortingMatches: { classPropertyName: "typeaheadSkipSortingMatches", publicName: "typeaheadSkipSortingMatches", isSignal: true, isRequired: false, transformFunction: null }, typeaheadAutocompleteListLabel: { classPropertyName: "typeaheadAutocompleteListLabel", publicName: "typeaheadAutocompleteListLabel", isSignal: true, isRequired: false, transformFunction: null }, typeaheadFullWidth: { classPropertyName: "typeaheadFullWidth", publicName: "typeaheadFullWidth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { typeaheadOnInput: "typeaheadOnInput", typeaheadOnSelect: "typeaheadOnSelect", typeaheadOnMultiselectClose: "typeaheadOnMultiselectClose", typeaheadOnFullMatch: "typeaheadOnFullMatch", typeaheadClosed: "typeaheadClosed", typeaheadOpenChange: "typeaheadOpenChange" }, host: { listeners: { "focusout": "onBlur()", "focusin": "onInput($event)", "input": "onInput($event)", "keydown.escape": "onKeydownEscape()", "keydown.space": "onKeydownSpace($event)" }, classAttribute: "si-typeahead" }, exportAs: ["si-typeahead"], usesOnChanges: true, hostDirectives: [{ directive: i1$1.SiAutocompleteDirective }], ngImport: i0 });
673
+ }
674
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiTypeaheadDirective, decorators: [{
675
+ type: Directive,
676
+ args: [{
677
+ selector: '[siTypeahead]',
678
+ exportAs: 'si-typeahead',
679
+ hostDirectives: [SiAutocompleteDirective],
680
+ host: {
681
+ class: 'si-typeahead'
682
+ }
683
+ }]
684
+ }], propDecorators: { onBlur: [{
685
+ type: HostListener,
686
+ args: ['focusout']
687
+ }], onInput: [{
688
+ type: HostListener,
689
+ args: ['focusin', ['$event']]
690
+ }, {
691
+ type: HostListener,
692
+ args: ['input', ['$event']]
693
+ }], onKeydownEscape: [{
694
+ type: HostListener,
695
+ args: ['keydown.escape']
696
+ }], onKeydownSpace: [{
697
+ type: HostListener,
698
+ args: ['keydown.space', ['$event']]
699
+ }] } });
700
+
701
+ /**
702
+ * Copyright Siemens 2016 - 2025.
703
+ * SPDX-License-Identifier: MIT
704
+ */
705
+ class SiTypeaheadItemTemplateDirective {
706
+ static ngTemplateContextGuard(dir, ctx) {
707
+ return true;
708
+ }
709
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiTypeaheadItemTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
710
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.6", type: SiTypeaheadItemTemplateDirective, isStandalone: true, selector: "[siTypeaheadItemTemplate]", ngImport: i0 });
711
+ }
712
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiTypeaheadItemTemplateDirective, decorators: [{
713
+ type: Directive,
714
+ args: [{
715
+ selector: '[siTypeaheadItemTemplate]'
716
+ }]
717
+ }] });
718
+
719
+ /**
720
+ * Copyright Siemens 2016 - 2025.
721
+ * SPDX-License-Identifier: MIT
722
+ */
723
+ class SiTypeaheadModule {
724
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiTypeaheadModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
725
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.6", ngImport: i0, type: SiTypeaheadModule, imports: [SiTypeaheadDirective, SiTypeaheadItemTemplateDirective], exports: [SiTypeaheadDirective, SiTypeaheadItemTemplateDirective] });
726
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiTypeaheadModule });
727
+ }
728
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiTypeaheadModule, decorators: [{
729
+ type: NgModule,
730
+ args: [{
731
+ imports: [SiTypeaheadDirective, SiTypeaheadItemTemplateDirective],
732
+ exports: [SiTypeaheadDirective, SiTypeaheadItemTemplateDirective]
733
+ }]
734
+ }] });
735
+
736
+ /**
737
+ * Copyright Siemens 2016 - 2025.
738
+ * SPDX-License-Identifier: MIT
739
+ */
740
+
741
+ /**
742
+ * Generated bundle index. Do not edit.
743
+ */
744
+
745
+ export { SiTypeaheadDirective, SiTypeaheadItemTemplateDirective, SiTypeaheadModule };
746
+ //# sourceMappingURL=siemens-element-ng-typeahead.mjs.map