@testgorilla/tgo-ui 11.22.2 → 12.0.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 (227) hide show
  1. package/fesm2022/testgorilla-tgo-ui-components-accordion.mjs +335 -229
  2. package/fesm2022/testgorilla-tgo-ui-components-accordion.mjs.map +1 -1
  3. package/fesm2022/testgorilla-tgo-ui-components-ai-audio-circle.mjs +547 -465
  4. package/fesm2022/testgorilla-tgo-ui-components-ai-audio-circle.mjs.map +1 -1
  5. package/fesm2022/testgorilla-tgo-ui-components-ai-caveat.mjs +160 -75
  6. package/fesm2022/testgorilla-tgo-ui-components-ai-caveat.mjs.map +1 -1
  7. package/fesm2022/testgorilla-tgo-ui-components-ai-feedback.mjs +678 -278
  8. package/fesm2022/testgorilla-tgo-ui-components-ai-feedback.mjs.map +1 -1
  9. package/fesm2022/testgorilla-tgo-ui-components-alert-banner.mjs +337 -274
  10. package/fesm2022/testgorilla-tgo-ui-components-alert-banner.mjs.map +1 -1
  11. package/fesm2022/testgorilla-tgo-ui-components-audio-waveform.mjs +351 -192
  12. package/fesm2022/testgorilla-tgo-ui-components-audio-waveform.mjs.map +1 -1
  13. package/fesm2022/testgorilla-tgo-ui-components-autocomplete-v2.mjs +1950 -960
  14. package/fesm2022/testgorilla-tgo-ui-components-autocomplete-v2.mjs.map +1 -1
  15. package/fesm2022/testgorilla-tgo-ui-components-autocomplete.mjs +1206 -1044
  16. package/fesm2022/testgorilla-tgo-ui-components-autocomplete.mjs.map +1 -1
  17. package/fesm2022/testgorilla-tgo-ui-components-avatar.mjs +328 -182
  18. package/fesm2022/testgorilla-tgo-ui-components-avatar.mjs.map +1 -1
  19. package/fesm2022/testgorilla-tgo-ui-components-badge.mjs +383 -203
  20. package/fesm2022/testgorilla-tgo-ui-components-badge.mjs.map +1 -1
  21. package/fesm2022/testgorilla-tgo-ui-components-breadcrumb.mjs +553 -261
  22. package/fesm2022/testgorilla-tgo-ui-components-breadcrumb.mjs.map +1 -1
  23. package/fesm2022/testgorilla-tgo-ui-components-button.mjs +709 -739
  24. package/fesm2022/testgorilla-tgo-ui-components-button.mjs.map +1 -1
  25. package/fesm2022/testgorilla-tgo-ui-components-card.mjs +219 -184
  26. package/fesm2022/testgorilla-tgo-ui-components-card.mjs.map +1 -1
  27. package/fesm2022/testgorilla-tgo-ui-components-checkbox.mjs +515 -458
  28. package/fesm2022/testgorilla-tgo-ui-components-checkbox.mjs.map +1 -1
  29. package/fesm2022/testgorilla-tgo-ui-components-checklist.mjs +423 -162
  30. package/fesm2022/testgorilla-tgo-ui-components-checklist.mjs.map +1 -1
  31. package/fesm2022/testgorilla-tgo-ui-components-core.mjs +10784 -10996
  32. package/fesm2022/testgorilla-tgo-ui-components-core.mjs.map +1 -1
  33. package/fesm2022/testgorilla-tgo-ui-components-datepicker.mjs +810 -533
  34. package/fesm2022/testgorilla-tgo-ui-components-datepicker.mjs.map +1 -1
  35. package/fesm2022/testgorilla-tgo-ui-components-device-control.mjs +473 -116
  36. package/fesm2022/testgorilla-tgo-ui-components-device-control.mjs.map +1 -1
  37. package/fesm2022/testgorilla-tgo-ui-components-dialog.mjs +1149 -540
  38. package/fesm2022/testgorilla-tgo-ui-components-dialog.mjs.map +1 -1
  39. package/fesm2022/testgorilla-tgo-ui-components-divider.mjs +148 -84
  40. package/fesm2022/testgorilla-tgo-ui-components-divider.mjs.map +1 -1
  41. package/fesm2022/testgorilla-tgo-ui-components-donut-chart.mjs +239 -142
  42. package/fesm2022/testgorilla-tgo-ui-components-donut-chart.mjs.map +1 -1
  43. package/fesm2022/testgorilla-tgo-ui-components-dropdown.mjs +599 -467
  44. package/fesm2022/testgorilla-tgo-ui-components-dropdown.mjs.map +1 -1
  45. package/fesm2022/testgorilla-tgo-ui-components-elevation-shadow.mjs +126 -70
  46. package/fesm2022/testgorilla-tgo-ui-components-elevation-shadow.mjs.map +1 -1
  47. package/fesm2022/testgorilla-tgo-ui-components-empty-state.mjs +324 -329
  48. package/fesm2022/testgorilla-tgo-ui-components-empty-state.mjs.map +1 -1
  49. package/fesm2022/testgorilla-tgo-ui-components-field.mjs +969 -648
  50. package/fesm2022/testgorilla-tgo-ui-components-field.mjs.map +1 -1
  51. package/fesm2022/testgorilla-tgo-ui-components-file-upload.mjs +553 -419
  52. package/fesm2022/testgorilla-tgo-ui-components-file-upload.mjs.map +1 -1
  53. package/fesm2022/testgorilla-tgo-ui-components-filter-button.mjs +847 -452
  54. package/fesm2022/testgorilla-tgo-ui-components-filter-button.mjs.map +1 -1
  55. package/fesm2022/testgorilla-tgo-ui-components-gaussian-chart.mjs +398 -302
  56. package/fesm2022/testgorilla-tgo-ui-components-gaussian-chart.mjs.map +1 -1
  57. package/fesm2022/testgorilla-tgo-ui-components-icon-label.mjs +162 -95
  58. package/fesm2022/testgorilla-tgo-ui-components-icon-label.mjs.map +1 -1
  59. package/fesm2022/testgorilla-tgo-ui-components-icon.mjs +1825 -1789
  60. package/fesm2022/testgorilla-tgo-ui-components-icon.mjs.map +1 -1
  61. package/fesm2022/testgorilla-tgo-ui-components-infinite-scroll-table.mjs +1018 -672
  62. package/fesm2022/testgorilla-tgo-ui-components-infinite-scroll-table.mjs.map +1 -1
  63. package/fesm2022/testgorilla-tgo-ui-components-inline-field.mjs +758 -368
  64. package/fesm2022/testgorilla-tgo-ui-components-inline-field.mjs.map +1 -1
  65. package/fesm2022/testgorilla-tgo-ui-components-logo.mjs +204 -212
  66. package/fesm2022/testgorilla-tgo-ui-components-logo.mjs.map +1 -1
  67. package/fesm2022/testgorilla-tgo-ui-components-media-card.mjs +183 -48
  68. package/fesm2022/testgorilla-tgo-ui-components-media-card.mjs.map +1 -1
  69. package/fesm2022/testgorilla-tgo-ui-components-media-dialog.mjs +243 -79
  70. package/fesm2022/testgorilla-tgo-ui-components-media-dialog.mjs.map +1 -1
  71. package/fesm2022/testgorilla-tgo-ui-components-multi-input.mjs +751 -361
  72. package/fesm2022/testgorilla-tgo-ui-components-multi-input.mjs.map +1 -1
  73. package/fesm2022/testgorilla-tgo-ui-components-navbar.mjs +1122 -385
  74. package/fesm2022/testgorilla-tgo-ui-components-navbar.mjs.map +1 -1
  75. package/fesm2022/testgorilla-tgo-ui-components-overflow-menu.mjs +689 -413
  76. package/fesm2022/testgorilla-tgo-ui-components-overflow-menu.mjs.map +1 -1
  77. package/fesm2022/testgorilla-tgo-ui-components-page-header.mjs +227 -92
  78. package/fesm2022/testgorilla-tgo-ui-components-page-header.mjs.map +1 -1
  79. package/fesm2022/testgorilla-tgo-ui-components-paginator.mjs +174 -113
  80. package/fesm2022/testgorilla-tgo-ui-components-paginator.mjs.map +1 -1
  81. package/fesm2022/testgorilla-tgo-ui-components-password-criteria.mjs +367 -165
  82. package/fesm2022/testgorilla-tgo-ui-components-password-criteria.mjs.map +1 -1
  83. package/fesm2022/testgorilla-tgo-ui-components-password-strength.mjs +253 -118
  84. package/fesm2022/testgorilla-tgo-ui-components-password-strength.mjs.map +1 -1
  85. package/fesm2022/testgorilla-tgo-ui-components-phone-input.mjs +730 -444
  86. package/fesm2022/testgorilla-tgo-ui-components-phone-input.mjs.map +1 -1
  87. package/fesm2022/testgorilla-tgo-ui-components-popover.mjs +533 -221
  88. package/fesm2022/testgorilla-tgo-ui-components-popover.mjs.map +1 -1
  89. package/fesm2022/testgorilla-tgo-ui-components-popup-tip.mjs +274 -76
  90. package/fesm2022/testgorilla-tgo-ui-components-popup-tip.mjs.map +1 -1
  91. package/fesm2022/testgorilla-tgo-ui-components-progress-bar.mjs +184 -124
  92. package/fesm2022/testgorilla-tgo-ui-components-progress-bar.mjs.map +1 -1
  93. package/fesm2022/testgorilla-tgo-ui-components-prompt.mjs +1223 -574
  94. package/fesm2022/testgorilla-tgo-ui-components-prompt.mjs.map +1 -1
  95. package/fesm2022/testgorilla-tgo-ui-components-radial-progress.mjs +249 -160
  96. package/fesm2022/testgorilla-tgo-ui-components-radial-progress.mjs.map +1 -1
  97. package/fesm2022/testgorilla-tgo-ui-components-radio-button.mjs +447 -439
  98. package/fesm2022/testgorilla-tgo-ui-components-radio-button.mjs.map +1 -1
  99. package/fesm2022/testgorilla-tgo-ui-components-rating.mjs +226 -150
  100. package/fesm2022/testgorilla-tgo-ui-components-rating.mjs.map +1 -1
  101. package/fesm2022/testgorilla-tgo-ui-components-scale-table.mjs +255 -67
  102. package/fesm2022/testgorilla-tgo-ui-components-scale-table.mjs.map +1 -1
  103. package/fesm2022/testgorilla-tgo-ui-components-scale.mjs +205 -162
  104. package/fesm2022/testgorilla-tgo-ui-components-scale.mjs.map +1 -1
  105. package/fesm2022/testgorilla-tgo-ui-components-segmented-bar.mjs +245 -153
  106. package/fesm2022/testgorilla-tgo-ui-components-segmented-bar.mjs.map +1 -1
  107. package/fesm2022/testgorilla-tgo-ui-components-segmented-button.mjs +274 -140
  108. package/fesm2022/testgorilla-tgo-ui-components-segmented-button.mjs.map +1 -1
  109. package/fesm2022/testgorilla-tgo-ui-components-segmented-toggle.mjs +319 -147
  110. package/fesm2022/testgorilla-tgo-ui-components-segmented-toggle.mjs.map +1 -1
  111. package/fesm2022/testgorilla-tgo-ui-components-selectable-card.mjs +286 -84
  112. package/fesm2022/testgorilla-tgo-ui-components-selectable-card.mjs.map +1 -1
  113. package/fesm2022/testgorilla-tgo-ui-components-side-navigation.mjs +660 -208
  114. package/fesm2022/testgorilla-tgo-ui-components-side-navigation.mjs.map +1 -1
  115. package/fesm2022/testgorilla-tgo-ui-components-side-panel.mjs +579 -320
  116. package/fesm2022/testgorilla-tgo-ui-components-side-panel.mjs.map +1 -1
  117. package/fesm2022/testgorilla-tgo-ui-components-side-sheet.mjs +419 -200
  118. package/fesm2022/testgorilla-tgo-ui-components-side-sheet.mjs.map +1 -1
  119. package/fesm2022/testgorilla-tgo-ui-components-skeleton.mjs +132 -80
  120. package/fesm2022/testgorilla-tgo-ui-components-skeleton.mjs.map +1 -1
  121. package/fesm2022/testgorilla-tgo-ui-components-slider.mjs +741 -390
  122. package/fesm2022/testgorilla-tgo-ui-components-slider.mjs.map +1 -1
  123. package/fesm2022/testgorilla-tgo-ui-components-snackbar.mjs +455 -329
  124. package/fesm2022/testgorilla-tgo-ui-components-snackbar.mjs.map +1 -1
  125. package/fesm2022/testgorilla-tgo-ui-components-spider-chart.mjs +543 -514
  126. package/fesm2022/testgorilla-tgo-ui-components-spider-chart.mjs.map +1 -1
  127. package/fesm2022/testgorilla-tgo-ui-components-spinner.mjs +193 -104
  128. package/fesm2022/testgorilla-tgo-ui-components-spinner.mjs.map +1 -1
  129. package/fesm2022/testgorilla-tgo-ui-components-stepper.mjs +760 -524
  130. package/fesm2022/testgorilla-tgo-ui-components-stepper.mjs.map +1 -1
  131. package/fesm2022/testgorilla-tgo-ui-components-table.mjs +714 -415
  132. package/fesm2022/testgorilla-tgo-ui-components-table.mjs.map +1 -1
  133. package/fesm2022/testgorilla-tgo-ui-components-tabs.mjs +847 -438
  134. package/fesm2022/testgorilla-tgo-ui-components-tabs.mjs.map +1 -1
  135. package/fesm2022/testgorilla-tgo-ui-components-tag.mjs +535 -275
  136. package/fesm2022/testgorilla-tgo-ui-components-tag.mjs.map +1 -1
  137. package/fesm2022/testgorilla-tgo-ui-components-toggle.mjs +316 -246
  138. package/fesm2022/testgorilla-tgo-ui-components-toggle.mjs.map +1 -1
  139. package/fesm2022/testgorilla-tgo-ui-components-tooltip.mjs +404 -284
  140. package/fesm2022/testgorilla-tgo-ui-components-tooltip.mjs.map +1 -1
  141. package/fesm2022/testgorilla-tgo-ui-components-universal-skills.mjs +664 -383
  142. package/fesm2022/testgorilla-tgo-ui-components-universal-skills.mjs.map +1 -1
  143. package/fesm2022/testgorilla-tgo-ui-components-validation-error.mjs +201 -112
  144. package/fesm2022/testgorilla-tgo-ui-components-validation-error.mjs.map +1 -1
  145. package/fesm2022/testgorilla-tgo-ui-components-write-with-ai.mjs +1014 -458
  146. package/fesm2022/testgorilla-tgo-ui-components-write-with-ai.mjs.map +1 -1
  147. package/fesm2022/testgorilla-tgo-ui.mjs +147 -155
  148. package/fesm2022/testgorilla-tgo-ui.mjs.map +1 -1
  149. package/mcp/catalog.json +1 -1
  150. package/package.json +16 -17
  151. package/projects/tgo-canopy-ui/assets/icons/rebrand/Sequences-filled.svg +3 -0
  152. package/projects/tgo-canopy-ui/assets/icons/rebrand/Sequences-in-line.svg +3 -0
  153. package/projects/tgo-canopy-ui/theme/_palette.scss +23 -18
  154. package/types/testgorilla-tgo-ui-components-accordion.d.ts +214 -158
  155. package/types/testgorilla-tgo-ui-components-ai-audio-circle.d.ts +93 -69
  156. package/types/testgorilla-tgo-ui-components-ai-caveat.d.ts +37 -34
  157. package/types/testgorilla-tgo-ui-components-ai-feedback.d.ts +126 -86
  158. package/types/testgorilla-tgo-ui-components-alert-banner.d.ts +260 -185
  159. package/types/testgorilla-tgo-ui-components-audio-waveform.d.ts +96 -67
  160. package/types/testgorilla-tgo-ui-components-autocomplete-v2.d.ts +455 -256
  161. package/types/testgorilla-tgo-ui-components-autocomplete.d.ts +545 -390
  162. package/types/testgorilla-tgo-ui-components-avatar.d.ts +128 -102
  163. package/types/testgorilla-tgo-ui-components-badge.d.ts +191 -139
  164. package/types/testgorilla-tgo-ui-components-breadcrumb.d.ts +100 -62
  165. package/types/testgorilla-tgo-ui-components-button.d.ts +479 -340
  166. package/types/testgorilla-tgo-ui-components-card.d.ts +153 -114
  167. package/types/testgorilla-tgo-ui-components-checkbox.d.ts +299 -223
  168. package/types/testgorilla-tgo-ui-components-checklist.d.ts +149 -97
  169. package/types/testgorilla-tgo-ui-components-core.d.ts +307 -295
  170. package/types/testgorilla-tgo-ui-components-datepicker.d.ts +404 -299
  171. package/types/testgorilla-tgo-ui-components-device-control.d.ts +151 -81
  172. package/types/testgorilla-tgo-ui-components-dialog.d.ts +442 -329
  173. package/types/testgorilla-tgo-ui-components-divider.d.ts +64 -51
  174. package/types/testgorilla-tgo-ui-components-donut-chart.d.ts +41 -37
  175. package/types/testgorilla-tgo-ui-components-dropdown.d.ts +335 -241
  176. package/types/testgorilla-tgo-ui-components-elevation-shadow.d.ts +48 -43
  177. package/types/testgorilla-tgo-ui-components-empty-state.d.ts +317 -215
  178. package/types/testgorilla-tgo-ui-components-field.d.ts +559 -388
  179. package/types/testgorilla-tgo-ui-components-file-upload.d.ts +230 -168
  180. package/types/testgorilla-tgo-ui-components-filter-button.d.ts +263 -206
  181. package/types/testgorilla-tgo-ui-components-gaussian-chart.d.ts +107 -94
  182. package/types/testgorilla-tgo-ui-components-icon-label.d.ts +84 -61
  183. package/types/testgorilla-tgo-ui-components-icon.d.ts +137 -110
  184. package/types/testgorilla-tgo-ui-components-infinite-scroll-table.d.ts +429 -303
  185. package/types/testgorilla-tgo-ui-components-inline-field.d.ts +338 -254
  186. package/types/testgorilla-tgo-ui-components-logo.d.ts +119 -101
  187. package/types/testgorilla-tgo-ui-components-media-card.d.ts +51 -35
  188. package/types/testgorilla-tgo-ui-components-media-dialog.d.ts +40 -45
  189. package/types/testgorilla-tgo-ui-components-multi-input.d.ts +283 -194
  190. package/types/testgorilla-tgo-ui-components-navbar.d.ts +326 -208
  191. package/types/testgorilla-tgo-ui-components-overflow-menu.d.ts +276 -204
  192. package/types/testgorilla-tgo-ui-components-page-header.d.ts +67 -50
  193. package/types/testgorilla-tgo-ui-components-paginator.d.ts +103 -70
  194. package/types/testgorilla-tgo-ui-components-password-criteria.d.ts +67 -58
  195. package/types/testgorilla-tgo-ui-components-password-strength.d.ts +66 -57
  196. package/types/testgorilla-tgo-ui-components-phone-input.d.ts +217 -175
  197. package/types/testgorilla-tgo-ui-components-popover.d.ts +94 -53
  198. package/types/testgorilla-tgo-ui-components-popup-tip.d.ts +81 -44
  199. package/types/testgorilla-tgo-ui-components-progress-bar.d.ts +115 -84
  200. package/types/testgorilla-tgo-ui-components-prompt.d.ts +315 -219
  201. package/types/testgorilla-tgo-ui-components-radial-progress.d.ts +146 -107
  202. package/types/testgorilla-tgo-ui-components-radio-button.d.ts +296 -219
  203. package/types/testgorilla-tgo-ui-components-rating.d.ts +134 -95
  204. package/types/testgorilla-tgo-ui-components-scale-table.d.ts +67 -47
  205. package/types/testgorilla-tgo-ui-components-scale.d.ts +91 -66
  206. package/types/testgorilla-tgo-ui-components-segmented-bar.d.ts +118 -89
  207. package/types/testgorilla-tgo-ui-components-segmented-button.d.ts +107 -80
  208. package/types/testgorilla-tgo-ui-components-segmented-toggle.d.ts +138 -105
  209. package/types/testgorilla-tgo-ui-components-selectable-card.d.ts +90 -56
  210. package/types/testgorilla-tgo-ui-components-side-navigation.d.ts +183 -107
  211. package/types/testgorilla-tgo-ui-components-side-panel.d.ts +156 -145
  212. package/types/testgorilla-tgo-ui-components-side-sheet.d.ts +98 -89
  213. package/types/testgorilla-tgo-ui-components-skeleton.d.ts +50 -33
  214. package/types/testgorilla-tgo-ui-components-slider.d.ts +278 -198
  215. package/types/testgorilla-tgo-ui-components-snackbar.d.ts +211 -159
  216. package/types/testgorilla-tgo-ui-components-spider-chart.d.ts +140 -121
  217. package/types/testgorilla-tgo-ui-components-spinner.d.ts +93 -72
  218. package/types/testgorilla-tgo-ui-components-stepper.d.ts +480 -338
  219. package/types/testgorilla-tgo-ui-components-table.d.ts +280 -233
  220. package/types/testgorilla-tgo-ui-components-tabs.d.ts +282 -183
  221. package/types/testgorilla-tgo-ui-components-tag.d.ts +266 -193
  222. package/types/testgorilla-tgo-ui-components-toggle.d.ts +180 -132
  223. package/types/testgorilla-tgo-ui-components-tooltip.d.ts +142 -105
  224. package/types/testgorilla-tgo-ui-components-universal-skills.d.ts +165 -144
  225. package/types/testgorilla-tgo-ui-components-validation-error.d.ts +70 -51
  226. package/types/testgorilla-tgo-ui-components-write-with-ai.d.ts +210 -133
  227. package/types/testgorilla-tgo-ui.d.ts +52 -45
@@ -1,965 +1,1955 @@
1
- import { FocusMonitor } from '@angular/cdk/a11y';
2
- import { CdkVirtualScrollViewport, CdkVirtualForOf, CdkFixedSizeVirtualScroll } from '@angular/cdk/scrolling';
3
- import * as i1 from '@angular/common';
4
- import { CommonModule } from '@angular/common';
5
- import * as i0 from '@angular/core';
6
- import { input, signal, inject, ElementRef, NgZone, Directive, TemplateRef, Injectable, computed, DestroyRef, booleanAttribute, output, contentChild, ChangeDetectorRef, effect, isDevMode, untracked, ViewChild, ChangeDetectionStrategy, Component } from '@angular/core';
7
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
8
- import * as i2 from '@angular/forms';
9
- import { NgControl, FormsModule } from '@angular/forms';
10
- import * as i3 from '@angular/material/autocomplete';
11
- import { MatAutocompleteModule } from '@angular/material/autocomplete';
12
- import { MatChipsModule } from '@angular/material/chips';
13
- import * as i4 from '@angular/material/form-field';
14
- import { MatFormFieldModule } from '@angular/material/form-field';
15
- import * as i5 from '@angular/material/input';
16
- import { MatInputModule } from '@angular/material/input';
17
- import * as i10 from '@angular/material/tooltip';
18
- import { MatTooltipModule } from '@angular/material/tooltip';
19
- import { IKeyboardEvent, PreventInputDirective, SelectTextDirective, UiTranslatePipe, TransformItemPipe, IncludesPipe } from '@testgorilla/tgo-ui/components/core';
20
- import * as i7 from '@testgorilla/tgo-ui/components/icon';
21
- import { IconComponentModule } from '@testgorilla/tgo-ui/components/icon';
22
- import * as i8 from '@testgorilla/tgo-ui/components/spinner';
23
- import { SpinnerComponentModule } from '@testgorilla/tgo-ui/components/spinner';
24
- import * as i6 from '@testgorilla/tgo-ui/components/tag';
25
- import { TagComponentModule } from '@testgorilla/tgo-ui/components/tag';
26
- import * as i9 from '@testgorilla/tgo-ui/components/validation-error';
27
- import { ValidationErrorModule } from '@testgorilla/tgo-ui/components/validation-error';
28
- import { BehaviorSubject, ReplaySubject, map, startWith, filter, throttleTime } from 'rxjs';
29
-
30
- class AutocompleteOverflowDetectDirective {
31
- constructor() {
32
- this.measureContainer = input(undefined, ...(ngDevMode ? [{ debugName: "measureContainer" }] : /* istanbul ignore next */ []));
33
- this.itemSelector = input('.value-tag', ...(ngDevMode ? [{ debugName: "itemSelector" }] : /* istanbul ignore next */ []));
34
- this.reserveWidth = input(100, ...(ngDevMode ? [{ debugName: "reserveWidth" }] : /* istanbul ignore next */ []));
35
- this.visibleCount = signal(Infinity, ...(ngDevMode ? [{ debugName: "visibleCount" }] : /* istanbul ignore next */ []));
36
- this.overflowCount = signal(0, ...(ngDevMode ? [{ debugName: "overflowCount" }] : /* istanbul ignore next */ []));
37
- this.hasMeasured = signal(false, ...(ngDevMode ? [{ debugName: "hasMeasured" }] : /* istanbul ignore next */ []));
38
- this.tagMaxWidth = signal(null, ...(ngDevMode ? [{ debugName: "tagMaxWidth" }] : /* istanbul ignore next */ []));
39
- this.resizeObserver = null;
40
- this.rafId = null;
41
- this.el = inject(ElementRef);
42
- this.ngZone = inject(NgZone);
43
- }
44
- ngAfterViewInit() {
45
- // Self-measure when the directive enters the DOM (e.g., after @if condition becomes true)
46
- this.measure();
47
- }
48
- setupObserver(containerSelector) {
49
- const parentContainer = this.el.nativeElement.closest(containerSelector);
50
- if (!parentContainer || typeof ResizeObserver === 'undefined') {
51
- return;
52
- }
53
- this.resizeObserver = new ResizeObserver(() => {
54
- this.ngZone.run(() => this.measure());
55
- });
56
- this.resizeObserver.observe(parentContainer);
57
- }
58
- measure() {
59
- const container = this.measureContainer();
60
- if (!container) {
61
- return;
62
- }
63
- this.rafId = requestAnimationFrame(() => {
64
- const infix = container.closest('.mat-mdc-form-field-infix');
65
- if (!infix) {
66
- return;
67
- } // Can't measure yet — stay hidden until next attempt
68
- const tags = Array.from(container.querySelectorAll(this.itemSelector()));
69
- if (!tags.length) {
70
- this.visibleCount.set(Infinity);
71
- this.hasMeasured.set(true);
72
- this.overflowCount.set(0);
73
- return;
74
- }
75
- // Measure actual icon widths (clear button + chevron) that share the form field space
76
- const formField = container.closest('mat-form-field');
77
- let iconsWidth = 0;
78
- if (formField) {
79
- formField.querySelectorAll('.remove-selected, .arrow-state').forEach((icon) => {
80
- iconsWidth += icon.getBoundingClientRect().width;
81
- });
82
- }
83
- const inputReserve = 48;
84
- const counterWidth = 52;
85
- const availableWidth = infix.getBoundingClientRect().width - inputReserve - iconsWidth;
86
- let totalWidth = 0;
87
- let visibleCount = tags.length;
88
- for (let i = 0; i < tags.length; i++) {
89
- totalWidth += tags[i].getBoundingClientRect().width;
90
- const remainingTags = tags.length - (i + 1);
91
- const spaceForCounter = remainingTags > 0 ? counterWidth : 0;
92
- if (totalWidth + spaceForCounter > availableWidth && i > 0) {
93
- visibleCount = i;
94
- break;
95
- }
96
- }
97
- const total = container.querySelectorAll(this.itemSelector()).length;
98
- const visible = Math.min(visibleCount, total);
99
- const overflow = Math.max(0, total - visible);
100
- // Compute max width for each tag so wide tags truncate with ellipsis
101
- // Single tag: full available width. Multiple visible: account for counter width.
102
- const padding = overflow >= 10 ? 16 : 8;
103
- this.tagMaxWidth.set(visible === 1 ? availableWidth - padding : availableWidth - (overflow > 0 ? counterWidth : 0) - padding);
104
- this.visibleCount.set(visibleCount);
105
- this.hasMeasured.set(true);
106
- this.overflowCount.set(overflow);
107
- });
108
- }
109
- ngOnDestroy() {
110
- this.resizeObserver?.disconnect();
111
- if (this.rafId !== null) {
112
- cancelAnimationFrame(this.rafId);
113
- }
114
- }
115
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AutocompleteOverflowDetectDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
116
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.25", type: AutocompleteOverflowDetectDirective, isStandalone: true, selector: "[uiAutocompleteOverflowDetect]", inputs: { measureContainer: { classPropertyName: "measureContainer", publicName: "measureContainer", isSignal: true, isRequired: false, transformFunction: null }, itemSelector: { classPropertyName: "itemSelector", publicName: "itemSelector", isSignal: true, isRequired: false, transformFunction: null }, reserveWidth: { classPropertyName: "reserveWidth", publicName: "reserveWidth", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["autocompleteOverflowDetect"], ngImport: i0 }); }
117
- }
118
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AutocompleteOverflowDetectDirective, decorators: [{
119
- type: Directive,
120
- args: [{
121
- selector: '[uiAutocompleteOverflowDetect]',
122
- standalone: true,
123
- exportAs: 'autocompleteOverflowDetect',
124
- }]
125
- }], propDecorators: { measureContainer: [{ type: i0.Input, args: [{ isSignal: true, alias: "measureContainer", required: false }] }], itemSelector: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemSelector", required: false }] }], reserveWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "reserveWidth", required: false }] }] } });
126
-
127
- /**
128
- * Marks an `ng-template` whose content is rendered inside each selected tag, after its label.
129
- * Only applies with `tagsPosition="below"`.
130
- *
131
- * ```html
132
- * <ui-autocomplete-v2 tagsPosition="below" ...>
133
- * <ng-template uiAutocompleteTagSuffix let-item>{{ item.radius }}</ng-template>
134
- * </ui-autocomplete-v2>
135
- * ```
136
- */
137
- class AutocompleteTagSuffixDirective {
138
- constructor() {
139
- this.templateRef = inject(TemplateRef);
140
- }
141
- static ngTemplateContextGuard(_dir, ctx) {
142
- return true;
143
- }
144
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AutocompleteTagSuffixDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
145
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.25", type: AutocompleteTagSuffixDirective, isStandalone: true, selector: "ng-template[uiAutocompleteTagSuffix]", ngImport: i0 }); }
146
- }
147
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AutocompleteTagSuffixDirective, decorators: [{
148
- type: Directive,
149
- args: [{
150
- selector: 'ng-template[uiAutocompleteTagSuffix]',
151
- }]
152
- }] });
153
-
154
- class AutocompleteV2Utils {
155
- static transformDisplayValue(value, textField) {
156
- return value?.[textField] ?? '';
157
- }
158
- static filterItems(items, inputValue, textField) {
159
- return items.filter(item => {
160
- const text = item[textField];
161
- return typeof text === 'string' && text.toLowerCase().includes(inputValue.toLowerCase());
162
- });
163
- }
164
- static filterGroupedItems(groups, inputValue, textField) {
165
- return groups
166
- .map(group => ({
167
- ...group,
168
- filteredItems: AutocompleteV2Utils.filterItems(group.items, inputValue, textField),
169
- }))
170
- .filter(group => group.filteredItems.length > 0);
171
- }
172
- static excludeSuggestions(items, excludeItems, valueField) {
173
- if (!valueField || !excludeItems.length) {
174
- return items ?? [];
175
- }
176
- return (items ?? []).filter(item => !excludeItems.find(exclude => exclude[valueField] === item[valueField]));
177
- }
178
- static createValueItem(value, textField, valueField) {
179
- if (typeof value === 'string') {
180
- return { [textField]: value, [valueField]: value };
181
- }
182
- return value;
183
- }
184
- static findDuplicate(items, selectedValue, lookupKey) {
185
- return items.find(v => (lookupKey ? v[lookupKey] === selectedValue[lookupKey] : v === selectedValue));
186
- }
187
- /**
188
- * True when the typed text exactly matches the label of any displayed option
189
- * (case-insensitive, trimmed). Used to suppress the "Add …" option when the
190
- * value already exists among the options being shown.
191
- */
192
- static hasExactMatch(items, suggestions, inputValue, textField) {
193
- const normalized = inputValue.trim().toLowerCase();
194
- if (!normalized) {
195
- return false;
196
- }
197
- const isMatch = (item) => {
198
- const text = textField ? item[textField] : item;
199
- return typeof text === 'string' && text.toLowerCase() === normalized;
200
- };
201
- return (items ?? []).some(isMatch) || (suggestions ?? []).some(isMatch);
202
- }
203
- static isArray(value) {
204
- return Array.isArray(value);
205
- }
206
- }
207
-
208
- class AutocompleteFilterService {
209
- constructor() {
210
- // Configuration
211
- this.textField = signal('', ...(ngDevMode ? [{ debugName: "textField" }] : /* istanbul ignore next */ []));
212
- // Data sources (fed by component via effects)
213
- this.flatItems = signal([], ...(ngDevMode ? [{ debugName: "flatItems" }] : /* istanbul ignore next */ []));
214
- this.groupsList = signal([], ...(ngDevMode ? [{ debugName: "groupsList" }] : /* istanbul ignore next */ []));
215
- this.suggestions = signal([], ...(ngDevMode ? [{ debugName: "suggestions" }] : /* istanbul ignore next */ []));
216
- // Search state
217
- this.searchText$ = new BehaviorSubject('');
218
- this.userInput$ = new ReplaySubject(1);
219
- this.isSearching$ = this.searchText$.pipe(map(v => Boolean(v.trim())));
220
- // Dynamic filtering
221
- this.dynamicSource$ = new BehaviorSubject(null);
222
- this.isDynamicMode = false;
223
- // Filtered results
224
- this.filteredItems$ = this.searchText$.pipe(startWith(''), map(inputValue => {
225
- if (!inputValue.length) {
226
- return null;
227
- }
228
- return AutocompleteV2Utils.filterItems(this.flatItems(), inputValue, this.textField());
229
- }));
230
- this.filteredGroupedItems$ = this.searchText$.pipe(startWith(''), map(inputValue => {
231
- if (!inputValue.length || !this.groupsList().length) {
232
- return null;
233
- }
234
- return AutocompleteV2Utils.filterGroupedItems(this.groupsList(), inputValue, this.textField());
235
- }));
236
- this.filteredSuggestions$ = this.searchText$.pipe(map(inputValue => inputValue.length ? AutocompleteV2Utils.filterItems(this.suggestions(), inputValue, this.textField()) : null));
237
- }
238
- search(text, minChars) {
239
- this.userInput$.next(text);
240
- if (text.length >= minChars) {
241
- this.searchText$.next(text);
242
- }
243
- else {
244
- this.searchText$.next('');
245
- this.userInput$.next('');
246
- }
247
- }
248
- clearSearch() {
249
- this.searchText$.next('');
250
- this.userInput$.next('');
251
- }
252
- ngOnDestroy() {
253
- this.searchText$.complete();
254
- this.userInput$.complete();
255
- this.dynamicSource$.complete();
256
- }
257
- setDynamicResults(list, loading) {
258
- if ((list !== null || loading) && !this.isDynamicMode) {
259
- this.isDynamicMode = true;
260
- this.filteredItems$ = this.dynamicSource$;
261
- }
262
- if (list !== null) {
263
- this.dynamicSource$.next(list);
264
- }
265
- else if (loading) {
266
- this.dynamicSource$.next([]);
267
- }
268
- }
269
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AutocompleteFilterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
270
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AutocompleteFilterService }); }
271
- }
272
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AutocompleteFilterService, decorators: [{
273
- type: Injectable
274
- }] });
275
-
1
+ import { FocusMonitor } from "@angular/cdk/a11y";
2
+ import { CdkFixedSizeVirtualScroll, CdkVirtualForOf, CdkVirtualScrollViewport } from "@angular/cdk/scrolling";
3
+ import * as i1 from "@angular/common";
4
+ import { CommonModule } from "@angular/common";
5
+ import * as i0 from "@angular/core";
6
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, Directive, ElementRef, Injectable, NgZone, TemplateRef, ViewChild, booleanAttribute, computed, contentChild, effect, inject, input, isDevMode, output, signal, untracked } from "@angular/core";
7
+ import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
8
+ import * as i2 from "@angular/forms";
9
+ import { FormsModule, NgControl } from "@angular/forms";
10
+ import * as i3 from "@angular/material/autocomplete";
11
+ import { MatAutocompleteModule } from "@angular/material/autocomplete";
12
+ import { MatChipsModule } from "@angular/material/chips";
13
+ import * as i4 from "@angular/material/form-field";
14
+ import { MatFormFieldModule } from "@angular/material/form-field";
15
+ import * as i5 from "@angular/material/input";
16
+ import { MatInputModule } from "@angular/material/input";
17
+ import * as i10 from "@angular/material/tooltip";
18
+ import { MatTooltipModule } from "@angular/material/tooltip";
19
+ import { IKeyboardEvent, IncludesPipe, PreventInputDirective, SelectTextDirective, TransformItemPipe, UiTranslatePipe } from "@testgorilla/tgo-ui/components/core";
20
+ import * as i7 from "@testgorilla/tgo-ui/components/icon";
21
+ import { IconComponentModule } from "@testgorilla/tgo-ui/components/icon";
22
+ import * as i8 from "@testgorilla/tgo-ui/components/spinner";
23
+ import { SpinnerComponentModule } from "@testgorilla/tgo-ui/components/spinner";
24
+ import * as i6 from "@testgorilla/tgo-ui/components/tag";
25
+ import { TagComponentModule } from "@testgorilla/tgo-ui/components/tag";
26
+ import * as i9 from "@testgorilla/tgo-ui/components/validation-error";
27
+ import { ValidationErrorModule } from "@testgorilla/tgo-ui/components/validation-error";
28
+ import { BehaviorSubject, ReplaySubject, filter, map, startWith, throttleTime } from "rxjs";
29
+ var AutocompleteOverflowDetectDirective = class AutocompleteOverflowDetectDirective {
30
+ constructor() {
31
+ this.measureContainer = input(void 0, ...ngDevMode ? [{ debugName: "measureContainer" }] : /* istanbul ignore next */ []);
32
+ this.itemSelector = input(".value-tag", ...ngDevMode ? [{ debugName: "itemSelector" }] : /* istanbul ignore next */ []);
33
+ this.reserveWidth = input(100, ...ngDevMode ? [{ debugName: "reserveWidth" }] : /* istanbul ignore next */ []);
34
+ this.visibleCount = signal(Infinity, ...ngDevMode ? [{ debugName: "visibleCount" }] : /* istanbul ignore next */ []);
35
+ this.overflowCount = signal(0, ...ngDevMode ? [{ debugName: "overflowCount" }] : /* istanbul ignore next */ []);
36
+ this.hasMeasured = signal(false, ...ngDevMode ? [{ debugName: "hasMeasured" }] : /* istanbul ignore next */ []);
37
+ this.tagMaxWidth = signal(null, ...ngDevMode ? [{ debugName: "tagMaxWidth" }] : /* istanbul ignore next */ []);
38
+ this.resizeObserver = null;
39
+ this.rafId = null;
40
+ this.el = inject(ElementRef);
41
+ this.ngZone = inject(NgZone);
42
+ }
43
+ ngAfterViewInit() {
44
+ this.measure();
45
+ }
46
+ setupObserver(containerSelector) {
47
+ const parentContainer = this.el.nativeElement.closest(containerSelector);
48
+ if (!parentContainer || typeof ResizeObserver === "undefined") return;
49
+ this.resizeObserver = new ResizeObserver(() => {
50
+ this.ngZone.run(() => this.measure());
51
+ });
52
+ this.resizeObserver.observe(parentContainer);
53
+ }
54
+ measure() {
55
+ const container = this.measureContainer();
56
+ if (!container) return;
57
+ this.rafId = requestAnimationFrame(() => {
58
+ const infix = container.closest(".mat-mdc-form-field-infix");
59
+ if (!infix) return;
60
+ const tags = Array.from(container.querySelectorAll(this.itemSelector()));
61
+ if (!tags.length) {
62
+ this.visibleCount.set(Infinity);
63
+ this.hasMeasured.set(true);
64
+ this.overflowCount.set(0);
65
+ return;
66
+ }
67
+ const formField = container.closest("mat-form-field");
68
+ let iconsWidth = 0;
69
+ if (formField) formField.querySelectorAll(".remove-selected, .arrow-state").forEach((icon) => {
70
+ iconsWidth += icon.getBoundingClientRect().width;
71
+ });
72
+ const inputReserve = 48;
73
+ const counterWidth = 52;
74
+ const availableWidth = infix.getBoundingClientRect().width - inputReserve - iconsWidth;
75
+ let totalWidth = 0;
76
+ let visibleCount = tags.length;
77
+ for (let i = 0; i < tags.length; i++) {
78
+ totalWidth += tags[i].getBoundingClientRect().width;
79
+ const spaceForCounter = tags.length - (i + 1) > 0 ? counterWidth : 0;
80
+ if (totalWidth + spaceForCounter > availableWidth && i > 0) {
81
+ visibleCount = i;
82
+ break;
83
+ }
84
+ }
85
+ const total = container.querySelectorAll(this.itemSelector()).length;
86
+ const visible = Math.min(visibleCount, total);
87
+ const overflow = Math.max(0, total - visible);
88
+ const padding = overflow >= 10 ? 16 : 8;
89
+ this.tagMaxWidth.set(visible === 1 ? availableWidth - padding : availableWidth - (overflow > 0 ? counterWidth : 0) - padding);
90
+ this.visibleCount.set(visibleCount);
91
+ this.hasMeasured.set(true);
92
+ this.overflowCount.set(overflow);
93
+ });
94
+ }
95
+ ngOnDestroy() {
96
+ this.resizeObserver?.disconnect();
97
+ if (this.rafId !== null) cancelAnimationFrame(this.rafId);
98
+ }
99
+ static {
100
+ this.ɵfac = i0.ɵɵngDeclareFactory({
101
+ minVersion: "12.0.0",
102
+ version: "22.2.4",
103
+ ngImport: i0,
104
+ type: AutocompleteOverflowDetectDirective,
105
+ deps: [],
106
+ target: i0.ɵɵFactoryTarget.Directive
107
+ });
108
+ }
109
+ static {
110
+ this.ɵdir = i0.ɵɵngDeclareDirective({
111
+ minVersion: "17.1.0",
112
+ version: "22.2.4",
113
+ type: AutocompleteOverflowDetectDirective,
114
+ isStandalone: true,
115
+ selector: "[uiAutocompleteOverflowDetect]",
116
+ inputs: {
117
+ measureContainer: {
118
+ classPropertyName: "measureContainer",
119
+ publicName: "measureContainer",
120
+ isSignal: true,
121
+ isRequired: false,
122
+ transformFunction: null
123
+ },
124
+ itemSelector: {
125
+ classPropertyName: "itemSelector",
126
+ publicName: "itemSelector",
127
+ isSignal: true,
128
+ isRequired: false,
129
+ transformFunction: null
130
+ },
131
+ reserveWidth: {
132
+ classPropertyName: "reserveWidth",
133
+ publicName: "reserveWidth",
134
+ isSignal: true,
135
+ isRequired: false,
136
+ transformFunction: null
137
+ }
138
+ },
139
+ exportAs: ["autocompleteOverflowDetect"],
140
+ ngImport: i0
141
+ });
142
+ }
143
+ };
144
+ i0.ɵɵngDeclareClassMetadata({
145
+ minVersion: "12.0.0",
146
+ version: "22.2.4",
147
+ ngImport: i0,
148
+ type: AutocompleteOverflowDetectDirective,
149
+ decorators: [{
150
+ type: Directive,
151
+ args: [{
152
+ selector: "[uiAutocompleteOverflowDetect]",
153
+ standalone: true,
154
+ exportAs: "autocompleteOverflowDetect"
155
+ }]
156
+ }],
157
+ propDecorators: {
158
+ measureContainer: [{
159
+ type: i0.Input,
160
+ args: [{
161
+ isSignal: true,
162
+ alias: "measureContainer",
163
+ required: false
164
+ }]
165
+ }],
166
+ itemSelector: [{
167
+ type: i0.Input,
168
+ args: [{
169
+ isSignal: true,
170
+ alias: "itemSelector",
171
+ required: false
172
+ }]
173
+ }],
174
+ reserveWidth: [{
175
+ type: i0.Input,
176
+ args: [{
177
+ isSignal: true,
178
+ alias: "reserveWidth",
179
+ required: false
180
+ }]
181
+ }]
182
+ }
183
+ });
184
+ var AutocompleteTagSuffixDirective = class AutocompleteTagSuffixDirective {
185
+ constructor() {
186
+ this.templateRef = inject(TemplateRef);
187
+ }
188
+ static ngTemplateContextGuard(_dir, _ctx) {
189
+ return true;
190
+ }
191
+ static {
192
+ this.ɵfac = i0.ɵɵngDeclareFactory({
193
+ minVersion: "12.0.0",
194
+ version: "22.2.4",
195
+ ngImport: i0,
196
+ type: AutocompleteTagSuffixDirective,
197
+ deps: [],
198
+ target: i0.ɵɵFactoryTarget.Directive
199
+ });
200
+ }
201
+ static {
202
+ this.ɵdir = i0.ɵɵngDeclareDirective({
203
+ minVersion: "14.0.0",
204
+ version: "22.2.4",
205
+ type: AutocompleteTagSuffixDirective,
206
+ isStandalone: true,
207
+ selector: "ng-template[uiAutocompleteTagSuffix]",
208
+ ngImport: i0
209
+ });
210
+ }
211
+ };
212
+ i0.ɵɵngDeclareClassMetadata({
213
+ minVersion: "12.0.0",
214
+ version: "22.2.4",
215
+ ngImport: i0,
216
+ type: AutocompleteTagSuffixDirective,
217
+ decorators: [{
218
+ type: Directive,
219
+ args: [{ selector: "ng-template[uiAutocompleteTagSuffix]" }]
220
+ }]
221
+ });
222
+ var AutocompleteV2Utils = class AutocompleteV2Utils {
223
+ static transformDisplayValue(value, textField) {
224
+ return value?.[textField] ?? "";
225
+ }
226
+ static filterItems(items, inputValue, textField) {
227
+ return items.filter((item) => {
228
+ const text = item[textField];
229
+ return typeof text === "string" && text.toLowerCase().includes(inputValue.toLowerCase());
230
+ });
231
+ }
232
+ static filterGroupedItems(groups, inputValue, textField) {
233
+ return groups.map((group) => ({
234
+ ...group,
235
+ filteredItems: AutocompleteV2Utils.filterItems(group.items, inputValue, textField)
236
+ })).filter((group) => group.filteredItems.length > 0);
237
+ }
238
+ static excludeSuggestions(items, excludeItems, valueField) {
239
+ if (!valueField || !excludeItems.length) return items ?? [];
240
+ return (items ?? []).filter((item) => !excludeItems.find((exclude) => exclude[valueField] === item[valueField]));
241
+ }
242
+ static createValueItem(value, textField, valueField) {
243
+ if (typeof value === "string") return {
244
+ [textField]: value,
245
+ [valueField]: value
246
+ };
247
+ return value;
248
+ }
249
+ static findDuplicate(items, selectedValue, lookupKey) {
250
+ return items.find((v) => lookupKey ? v[lookupKey] === selectedValue[lookupKey] : v === selectedValue);
251
+ }
252
+ static hasExactMatch(items, suggestions, inputValue, textField) {
253
+ const normalized = inputValue.trim().toLowerCase();
254
+ if (!normalized) return false;
255
+ const isMatch = (item) => {
256
+ const text = textField ? item[textField] : item;
257
+ return typeof text === "string" && text.toLowerCase() === normalized;
258
+ };
259
+ return (items ?? []).some(isMatch) || (suggestions ?? []).some(isMatch);
260
+ }
261
+ static isArray(value) {
262
+ return Array.isArray(value);
263
+ }
264
+ };
265
+ var AutocompleteFilterService = class AutocompleteFilterService {
266
+ constructor() {
267
+ this.textField = signal("", ...ngDevMode ? [{ debugName: "textField" }] : /* istanbul ignore next */ []);
268
+ this.flatItems = signal([], ...ngDevMode ? [{ debugName: "flatItems" }] : /* istanbul ignore next */ []);
269
+ this.groupsList = signal([], ...ngDevMode ? [{ debugName: "groupsList" }] : /* istanbul ignore next */ []);
270
+ this.suggestions = signal([], ...ngDevMode ? [{ debugName: "suggestions" }] : /* istanbul ignore next */ []);
271
+ this.searchText$ = new BehaviorSubject("");
272
+ this.userInput$ = new ReplaySubject(1);
273
+ this.isSearching$ = this.searchText$.pipe(map((v) => Boolean(v.trim())));
274
+ this.dynamicSource$ = new BehaviorSubject(null);
275
+ this.isDynamicMode = false;
276
+ this.filteredItems$ = this.searchText$.pipe(startWith(""), map((inputValue) => {
277
+ if (!inputValue.length) return null;
278
+ return AutocompleteV2Utils.filterItems(this.flatItems(), inputValue, this.textField());
279
+ }));
280
+ this.filteredGroupedItems$ = this.searchText$.pipe(startWith(""), map((inputValue) => {
281
+ if (!inputValue.length || !this.groupsList().length) return null;
282
+ return AutocompleteV2Utils.filterGroupedItems(this.groupsList(), inputValue, this.textField());
283
+ }));
284
+ this.filteredSuggestions$ = this.searchText$.pipe(map((inputValue) => inputValue.length ? AutocompleteV2Utils.filterItems(this.suggestions(), inputValue, this.textField()) : null));
285
+ }
286
+ search(text, minChars) {
287
+ this.userInput$.next(text);
288
+ if (text.length >= minChars) this.searchText$.next(text);
289
+ else {
290
+ this.searchText$.next("");
291
+ this.userInput$.next("");
292
+ }
293
+ }
294
+ clearSearch() {
295
+ this.searchText$.next("");
296
+ this.userInput$.next("");
297
+ }
298
+ ngOnDestroy() {
299
+ this.searchText$.complete();
300
+ this.userInput$.complete();
301
+ this.dynamicSource$.complete();
302
+ }
303
+ setDynamicResults(list, loading) {
304
+ if ((list !== null || loading) && !this.isDynamicMode) {
305
+ this.isDynamicMode = true;
306
+ this.filteredItems$ = this.dynamicSource$;
307
+ }
308
+ if (list !== null) this.dynamicSource$.next(list);
309
+ else if (loading) this.dynamicSource$.next([]);
310
+ }
311
+ static {
312
+ this.ɵfac = i0.ɵɵngDeclareFactory({
313
+ minVersion: "12.0.0",
314
+ version: "22.2.4",
315
+ ngImport: i0,
316
+ type: AutocompleteFilterService,
317
+ deps: [],
318
+ target: i0.ɵɵFactoryTarget.Injectable
319
+ });
320
+ }
321
+ static {
322
+ this.ɵprov = i0.ɵɵngDeclareInjectable({
323
+ minVersion: "12.0.0",
324
+ version: "22.2.4",
325
+ ngImport: i0,
326
+ type: AutocompleteFilterService
327
+ });
328
+ }
329
+ };
330
+ i0.ɵɵngDeclareClassMetadata({
331
+ minVersion: "12.0.0",
332
+ version: "22.2.4",
333
+ ngImport: i0,
334
+ type: AutocompleteFilterService,
335
+ decorators: [{ type: Injectable }]
336
+ });
276
337
  var Autocomplete;
277
- (function (Autocomplete) {
278
- Autocomplete["SINGLE"] = "single";
279
- Autocomplete["MULTI"] = "multi";
280
- Autocomplete["LARGE"] = "large";
338
+ (function(Autocomplete) {
339
+ Autocomplete["SINGLE"] = "single";
340
+ Autocomplete["MULTI"] = "multi";
341
+ Autocomplete["LARGE"] = "large";
281
342
  })(Autocomplete || (Autocomplete = {}));
282
343
  var DropdownVariation;
283
- (function (DropdownVariation) {
284
- DropdownVariation["AUTOCOMPLETE"] = "autocomplete";
285
- DropdownVariation["DROPDOWN"] = "dropdown";
344
+ (function(DropdownVariation) {
345
+ DropdownVariation["AUTOCOMPLETE"] = "autocomplete";
346
+ DropdownVariation["DROPDOWN"] = "dropdown";
286
347
  })(DropdownVariation || (DropdownVariation = {}));
287
-
288
- class AutocompleteValueManager {
289
- constructor() {
290
- // ── Configuration signals (set by the component via effects) ────────────────
291
- this.type = signal('multi', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
292
- this.textField = signal('', ...(ngDevMode ? [{ debugName: "textField" }] : /* istanbul ignore next */ []));
293
- this.valueField = signal('', ...(ngDevMode ? [{ debugName: "valueField" }] : /* istanbul ignore next */ []));
294
- this.compareWith = signal(undefined, ...(ngDevMode ? [{ debugName: "compareWith" }] : /* istanbul ignore next */ []));
295
- // ── Value signal ─────────────────────────────────────────────────────────────
296
- this.value = signal(null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
297
- // ── Derived ──────────────────────────────────────────────────────────────────
298
- this.isSingle = computed(() => this.type() === Autocomplete.SINGLE, ...(ngDevMode ? [{ debugName: "isSingle" }] : /* istanbul ignore next */ []));
299
- this.displayValue = computed(() => {
300
- const type = this.type();
301
- const value = this.value();
302
- const textField = this.textField();
303
- const isSingle = type === Autocomplete.SINGLE;
304
- const isEmpty = !value || (AutocompleteV2Utils.isArray(value) && !value.length);
305
- if (isEmpty) {
306
- return '';
307
- }
308
- if (isSingle) {
309
- const display = AutocompleteV2Utils.isArray(value) ? value[0] : value;
310
- return AutocompleteV2Utils.transformDisplayValue(display, textField);
311
- }
312
- // Multi with values — space placeholder (tags are visible instead)
313
- return ' ';
314
- }, ...(ngDevMode ? [{ debugName: "displayValue" }] : /* istanbul ignore next */ []));
315
- // ── CVA callbacks ────────────────────────────────────────────────────────────
316
- this.onChangeFn = () => { };
317
- this.onTouchedFn = () => { };
318
- }
319
- registerOnChange(fn) {
320
- this.onChangeFn = fn;
321
- }
322
- registerOnTouched(fn) {
323
- this.onTouchedFn = fn;
324
- }
325
- notifyChange() {
326
- this.onChangeFn(this.value());
327
- }
328
- markAsTouched() {
329
- this.onTouchedFn();
330
- }
331
- writeValue(v) {
332
- if (v === null || v === undefined) {
333
- this.value.set(this.isSingle() ? null : []);
334
- }
335
- else {
336
- this.value.set(v);
337
- }
338
- }
339
- // ── Selection ─────────────────────────────────────────────────────────────────
340
- addValue(newValue) {
341
- if (!this.isSingle() && !this.value()) {
342
- this.value.set([]);
343
- }
344
- const compareWith = this.compareWith();
345
- const currentArray = AutocompleteV2Utils.isArray(this.value()) ? this.value() : [];
346
- const foundDuplicate = compareWith
347
- ? currentArray.find((v) => compareWith(v, newValue))
348
- : AutocompleteV2Utils.findDuplicate(currentArray, newValue, this.textField());
349
- if (!this.isSingle()) {
350
- this.value.set(foundDuplicate
351
- ? currentArray.filter((v) => (compareWith ? !compareWith(v, foundDuplicate) : v !== foundDuplicate))
352
- : [...currentArray, newValue]);
353
- }
354
- else {
355
- this.value.set(newValue);
356
- }
357
- }
358
- /**
359
- * Removes `option` from the value array.
360
- * Returns the found item (so the caller can deselect the mat-option), or undefined if not found.
361
- */
362
- removeValue(option) {
363
- const compareWith = this.compareWith();
364
- const currentValue = AutocompleteV2Utils.isArray(this.value()) ? this.value() : [];
365
- const foundValue = currentValue.find((v) => (compareWith ? compareWith(v, option) : v === option));
366
- if (foundValue) {
367
- this.value.set(currentValue.filter((v) => (compareWith ? !compareWith(v, option) : v !== option)));
368
- }
369
- return foundValue;
370
- }
371
- clear() {
372
- this.value.set(AutocompleteV2Utils.isArray(this.value()) ? [] : null);
373
- }
374
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AutocompleteValueManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
375
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AutocompleteValueManager }); }
376
- }
377
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AutocompleteValueManager, decorators: [{
378
- type: Injectable
379
- }] });
380
-
381
- class InfiniteScrollDirective {
382
- constructor() {
383
- this.viewport = null;
384
- this.scrollSub = null;
385
- this.destroyRef = inject(DestroyRef);
386
- this.scrollListener = (event) => {
387
- const target = event.target;
388
- const trigger = this.panelTrigger;
389
- if (!trigger) {
390
- return;
391
- }
392
- const isNotAutocompleteScroll = !target?.id?.includes('mat-autocomplete-') &&
393
- !target?.parentElement?.id?.includes('mat-autocomplete-') &&
394
- !target?.classList?.contains('mat-mdc-autocomplete-trigger');
395
- if (trigger.panelOpen && isNotAutocompleteScroll) {
396
- trigger.closePanel();
397
- }
398
- };
399
- this.enabled = false;
400
- this.closeOnScroll = false;
401
- this.panelTrigger = null;
402
- this.onBottomReached = null;
403
- }
404
- attachViewport(viewport) {
405
- this.detachViewport();
406
- if (!viewport) {
407
- return;
408
- }
409
- this.viewport = viewport;
410
- if (this.enabled) {
411
- this.scrollSub = viewport
412
- .elementScrolled()
413
- .pipe(map(() => viewport.measureScrollOffset('bottom')), filter(offset => offset < viewport.getViewportSize() * 0.2), throttleTime(200), takeUntilDestroyed(this.destroyRef))
414
- .subscribe(() => {
415
- this.onBottomReached?.();
416
- });
417
- }
418
- }
419
- detachViewport() {
420
- this.scrollSub?.unsubscribe();
421
- this.scrollSub = null;
422
- this.viewport = null;
423
- }
424
- scrollToTop() {
425
- if (this.viewport) {
426
- this.viewport.scrollToIndex(0);
427
- this.viewport.checkViewportSize();
428
- }
429
- }
430
- startCloseOnScroll() {
431
- if (this.closeOnScroll) {
432
- window.addEventListener('scroll', this.scrollListener, true);
433
- }
434
- }
435
- ngOnDestroy() {
436
- this.detachViewport();
437
- window.removeEventListener('scroll', this.scrollListener, true);
438
- }
439
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: InfiniteScrollDirective, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
440
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: InfiniteScrollDirective }); }
441
- }
442
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: InfiniteScrollDirective, decorators: [{
443
- type: Injectable
444
- }] });
445
-
446
- /* eslint-disable no-underscore-dangle */
447
- class AutocompleteV2Component {
448
- set cdkViewport(viewport) {
449
- // Ensure enabled is set before attaching (ViewChild resolves before ngAfterViewInit)
450
- this.scrollManager.enabled = this.infiniteScroll();
451
- this.scrollManager.attachViewport(viewport);
452
- }
453
- constructor() {
454
- // ── Inputs ──────────────────────────────────────────────────────────────────
455
- this.itemsList = input([], ...(ngDevMode ? [{ debugName: "itemsList" }] : /* istanbul ignore next */ []));
456
- this.suggestionsList = input([], ...(ngDevMode ? [{ debugName: "suggestionsList" }] : /* istanbul ignore next */ []));
457
- this.groupsList = input([], ...(ngDevMode ? [{ debugName: "groupsList" }] : /* istanbul ignore next */ []));
458
- this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
459
- this.allowAdd = input(true, ...(ngDevMode ? [{ debugName: "allowAdd" }] : /* istanbul ignore next */ []));
460
- this.textField = input('', ...(ngDevMode ? [{ debugName: "textField" }] : /* istanbul ignore next */ []));
461
- this.valueField = input('', ...(ngDevMode ? [{ debugName: "valueField" }] : /* istanbul ignore next */ []));
462
- this.imageField = input('', ...(ngDevMode ? [{ debugName: "imageField" }] : /* istanbul ignore next */ []));
463
- this.label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
464
- this.placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
465
- this.testId = input(null, ...(ngDevMode ? [{ debugName: "testId" }] : /* istanbul ignore next */ []));
466
- this.type = input('multi', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
467
- this.minCharactersSearch = input(3, ...(ngDevMode ? [{ debugName: "minCharactersSearch" }] : /* istanbul ignore next */ []));
468
- this.variant = input.required(...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
469
- this.showBottomContent = input(true, ...(ngDevMode ? [{ debugName: "showBottomContent" }] : /* istanbul ignore next */ []));
470
- this.required = input(undefined, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
471
- this.virtualScroll = input(false, { ...(ngDevMode ? { debugName: "virtualScroll" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
472
- this.compareWith = input(undefined, ...(ngDevMode ? [{ debugName: "compareWith" }] : /* istanbul ignore next */ []));
473
- this.dropdownPanelClass = input('', ...(ngDevMode ? [{ debugName: "dropdownPanelClass" }] : /* istanbul ignore next */ []));
474
- this.panelPosition = input('auto', ...(ngDevMode ? [{ debugName: "panelPosition" }] : /* istanbul ignore next */ []));
475
- this.hideSelectedSection = input(false, { ...(ngDevMode ? { debugName: "hideSelectedSection" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
476
- this.userAdditionsGroupLabel = input('', ...(ngDevMode ? [{ debugName: "userAdditionsGroupLabel" }] : /* istanbul ignore next */ []));
477
- this.closeOnScroll = input(false, ...(ngDevMode ? [{ debugName: "closeOnScroll" }] : /* istanbul ignore next */ []));
478
- this.size = input('medium', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
479
- this.allowUserInput = input(true, ...(ngDevMode ? [{ debugName: "allowUserInput" }] : /* istanbul ignore next */ []));
480
- this.clearable = input(true, ...(ngDevMode ? [{ debugName: "clearable" }] : /* istanbul ignore next */ []));
481
- this.maxLength = input(undefined, ...(ngDevMode ? [{ debugName: "maxLength" }] : /* istanbul ignore next */ []));
482
- this.dynamicFilterLoading = input(false, ...(ngDevMode ? [{ debugName: "dynamicFilterLoading" }] : /* istanbul ignore next */ []));
483
- this.dynamicFilteredList = input(null, ...(ngDevMode ? [{ debugName: "dynamicFilteredList" }] : /* istanbul ignore next */ []));
484
- this.infiniteScroll = input(false, ...(ngDevMode ? [{ debugName: "infiniteScroll" }] : /* istanbul ignore next */ []));
485
- this.hasMoreOptionsForInfiniteScroll = input(true, ...(ngDevMode ? [{ debugName: "hasMoreOptionsForInfiniteScroll" }] : /* istanbul ignore next */ []));
486
- this.itemValue = input(null, ...(ngDevMode ? [{ debugName: "itemValue" }] : /* istanbul ignore next */ []));
487
- this.formErrorConfig = input({}, ...(ngDevMode ? [{ debugName: "formErrorConfig" }] : /* istanbul ignore next */ []));
488
- this.errors = input([], ...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
489
- this.addOptionPosition = input('bottom', ...(ngDevMode ? [{ debugName: "addOptionPosition" }] : /* istanbul ignore next */ []));
490
- this.tagsPosition = input('inside', ...(ngDevMode ? [{ debugName: "tagsPosition" }] : /* istanbul ignore next */ []));
491
- /**
492
- * Icon shown before the label of each selected tag: one icon for every tag, or a function that picks
493
- * it per item (return `''` for no icon). Only applies with `tagsPosition="below"`.
494
- */
495
- this.tagIcon = input('', ...(ngDevMode ? [{ debugName: "tagIcon" }] : /* istanbul ignore next */ []));
496
- // ── Outputs ─────────────────────────────────────────────────────────────────
497
- this.selectionChange = output();
498
- this.searchTextChange = output();
499
- // eslint-disable-next-line @angular-eslint/no-output-native -- output shadows a native event; rename is breaking, deferred to the breaking-change MAJOR (see plan)
500
- this.blur = output();
501
- // eslint-disable-next-line @angular-eslint/no-output-native -- output shadows a native event; rename is breaking, deferred to the breaking-change MAJOR (see plan)
502
- this.focus = output();
503
- this.scrollViewportBottomReached = output();
504
- this.scrollViewportBottomReachedFiltered = output();
505
- this.tagSuffix = contentChild(AutocompleteTagSuffixDirective, ...(ngDevMode ? [{ debugName: "tagSuffix" }] : /* istanbul ignore next */ []));
506
- // ── Injected services ──────────────────────────────────────────────────────
507
- this.valueManager = inject((AutocompleteValueManager));
508
- this.filterService = inject((AutocompleteFilterService));
509
- this.scrollManager = inject(InfiniteScrollDirective);
510
- this.cdr = inject(ChangeDetectorRef);
511
- this.focusMonitor = inject(FocusMonitor);
512
- this.destroyRef = inject(DestroyRef);
513
- this.ngZone = inject(NgZone);
514
- this.ngControl = inject(NgControl, { optional: true, self: true });
515
- this.applicationTheme = inject('CANOPYUI_DEFAULT_APPLICATION_THEME', {
516
- optional: true,
517
- }) ?? 'light';
518
- // ── Internal state ──────────────────────────────────────────────────────────
519
- this.inputValue = signal('', ...(ngDevMode ? [{ debugName: "inputValue" }] : /* istanbul ignore next */ []));
520
- this.isInputFocus = signal(false, ...(ngDevMode ? [{ debugName: "isInputFocus" }] : /* istanbul ignore next */ []));
521
- this.autocompleteType = Autocomplete;
522
- /** Flat list for default (ungrouped) rendering and virtual scroll */
523
- this.flatItemsList = computed(() => {
524
- const suggestions = this.suggestionsList();
525
- const valField = this.valueField();
526
- const flat = AutocompleteV2Utils.excludeSuggestions(this.itemsList(), suggestions, valField);
527
- const grouped = this.groupsList().flatMap(g => AutocompleteV2Utils.excludeSuggestions(g.items, suggestions, valField));
528
- return [...flat, ...grouped];
529
- }, ...(ngDevMode ? [{ debugName: "flatItemsList" }] : /* istanbul ignore next */ []));
530
- /** Grouped list — only used when isGrouped is true */
531
- this.groupedItemsList = computed(() => {
532
- const suggestions = this.suggestionsList();
533
- const valField = this.valueField();
534
- return this.groupsList().map(group => ({
535
- groupName: group.groupName,
536
- items: AutocompleteV2Utils.excludeSuggestions(group.items, suggestions, valField),
537
- }));
538
- }, ...(ngDevMode ? [{ debugName: "groupedItemsList" }] : /* istanbul ignore next */ []));
539
- this._isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "_isDisabled" }] : /* istanbul ignore next */ []));
540
- this.userAddedItems = signal([], ...(ngDevMode ? [{ debugName: "userAddedItems" }] : /* istanbul ignore next */ []));
541
- this.translationContext = 'AUTOCOMPLETE.';
542
- this.utils = AutocompleteV2Utils;
543
- this.keyboardFocused = signal(false, ...(ngDevMode ? [{ debugName: "keyboardFocused" }] : /* istanbul ignore next */ []));
544
- this.isAlreadyAdded = computed(() => {
545
- const compareWith = this.compareWith();
546
- const val = this.valueManager.value();
547
- const inputVal = this.inputValue();
548
- if (!inputVal || inputVal === ' ') {
549
- return false;
550
- }
551
- const valArray = AutocompleteV2Utils.isArray(val) ? val : [];
552
- return Boolean(compareWith
553
- ? valArray.find((v) => compareWith(v, inputVal))
554
- : AutocompleteV2Utils.findDuplicate(valArray, inputVal, this.textField()));
555
- }, ...(ngDevMode ? [{ debugName: "isAlreadyAdded" }] : /* istanbul ignore next */ []));
556
- this.tagsBelow = computed(() => this.tagsPosition() === 'below' && this.type() === Autocomplete.MULTI, ...(ngDevMode ? [{ debugName: "tagsBelow" }] : /* istanbul ignore next */ []));
557
- this.suppressPlaceholder = computed(() => !this.tagsBelow() && Boolean(this.valueManager.value()?.length), ...(ngDevMode ? [{ debugName: "suppressPlaceholder" }] : /* istanbul ignore next */ []));
558
- this.showClearButton = computed(() => {
559
- if (this.tagsBelow()) {
560
- return false;
561
- }
562
- const type = this.type();
563
- const val = this.valueManager.value();
564
- if (type === Autocomplete.SINGLE) {
565
- const hasValue = Array.isArray(val) ? val.length > 0 : val ? Object.keys(val).length > 0 : false;
566
- return this.clearable() && hasValue;
567
- }
568
- return Array.isArray(val) && val.length > 1;
569
- }, ...(ngDevMode ? [{ debugName: "showClearButton" }] : /* istanbul ignore next */ []));
570
- /** Icon per below-tag, in selection order */
571
- this.tagIcons = computed(() => {
572
- const icon = this.tagIcon();
573
- const value = this.valueManager.value();
574
- if (!AutocompleteV2Utils.isArray(value)) {
575
- return [];
576
- }
577
- return value.map(item => (typeof icon === 'function' ? icon(item) : icon));
578
- }, ...(ngDevMode ? [{ debugName: "tagIcons" }] : /* istanbul ignore next */ []));
579
- this.safeErrors = computed(() => this.errors()?.filter(Boolean) ?? [], ...(ngDevMode ? [{ debugName: "safeErrors" }] : /* istanbul ignore next */ []));
580
- this.controlInvalid = signal(false, ...(ngDevMode ? [{ debugName: "controlInvalid" }] : /* istanbul ignore next */ []));
581
- this.hasError = computed(() => {
582
- if (this.ngControl) {
583
- return this.controlInvalid();
584
- }
585
- return this.safeErrors().length > 0;
586
- }, ...(ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []));
587
- this.hiddenItemsTooltip = computed(() => {
588
- const value = this.valueManager.value();
589
- const visibleCount = this.overflowDir?.visibleCount() ?? Infinity;
590
- if (!AutocompleteV2Utils.isArray(value)) {
591
- return '';
592
- }
593
- const tf = this.textField();
594
- return value
595
- .slice(visibleCount)
596
- .map(item => (tf ? item[tf] : item))
597
- .join('\n');
598
- }, ...(ngDevMode ? [{ debugName: "hiddenItemsTooltip" }] : /* istanbul ignore next */ []));
599
- this.trackByFn = (index, value) => value;
600
- this.trackByItem = (_index, item) => {
601
- const vf = this.valueField();
602
- return vf ? item?.[vf] : item;
603
- };
604
- // Assign valueAccessor manually to avoid circular DI
605
- // (providing NG_VALUE_ACCESSOR + injecting NgControl creates a cycle)
606
- if (this.ngControl) {
607
- this.ngControl.valueAccessor = this;
608
- }
609
- effect(() => {
610
- this.filterService.setDynamicResults(this.dynamicFilteredList(), this.dynamicFilterLoading());
611
- });
612
- effect(() => {
613
- const disabled = this.disabled();
614
- // In CVA mode, setDisabledState() owns the disabled state — the [disabled] input must not
615
- // override it, otherwise this effect's initial run clobbers a control that starts disabled.
616
- if (this.ngControl) {
617
- if (isDevMode() && disabled) {
618
- console.warn('[ui-autocomplete-v2] [disabled] is set alongside a form control. ' +
619
- 'Use the form control disabled state (disable()/enable()) instead.');
620
- }
621
- return;
622
- }
623
- this._isDisabled.set(disabled);
624
- });
625
- effect(() => this.valueManager.type.set(this.type()));
626
- effect(() => this.valueManager.textField.set(this.textField()));
627
- effect(() => this.valueManager.valueField.set(this.valueField()));
628
- effect(() => this.valueManager.compareWith.set(this.compareWith()));
629
- effect(() => this.filterService.textField.set(this.textField()));
630
- effect(() => this.filterService.flatItems.set(this.flatItemsList()));
631
- effect(() => this.filterService.groupsList.set(this.groupsList()));
632
- effect(() => this.filterService.suggestions.set(this.suggestionsList()));
633
- effect(() => {
634
- const v = this.itemValue();
635
- // In CVA mode, writeValue() owns the value — itemValue should not override it
636
- if (this.ngControl) {
637
- if (isDevMode() && v !== null) {
638
- console.warn('[ui-autocomplete-v2] [itemValue] is set alongside a form control. Use ngModel or formControl instead.');
639
- }
640
- return;
641
- }
642
- this.valueManager.value.set(AutocompleteV2Utils.isArray(v) ? v : v ? [v] : []);
643
- untracked(() => {
644
- if (!this.tagsBelow()) {
645
- this.inputValue.set(this.valueManager.displayValue());
646
- }
647
- });
648
- this.cdr.markForCheck();
649
- });
650
- effect(() => {
651
- this.valueManager.value(); // track value changes
652
- untracked(() => {
653
- if (this.type() !== Autocomplete.LARGE) {
654
- this.overflowDir?.measure();
655
- }
656
- });
657
- });
658
- }
659
- /**
660
- * Used to mark component view as dirty when touched programmatically with markAsTouched/markAllAsTouched or errors
661
- * to display validation errors that might happen (e.g. required)
662
- */
663
- ngDoCheck() {
664
- if (this.ngControl) {
665
- const invalid = Boolean(this.ngControl.invalid && this.ngControl.touched);
666
- if (this.controlInvalid() !== invalid) {
667
- this.controlInvalid.set(invalid);
668
- }
669
- if (this.ngControl.touched || this.ngControl.errors) {
670
- this.cdr.markForCheck();
671
- }
672
- }
673
- }
674
- ngAfterViewInit() {
675
- // Set default hover color for the autocomplete panel (overlay is outside component scope)
676
- if (!document.body.style.getPropertyValue('--ui-autocomplete-option-color')) {
677
- document.body.style.setProperty('--ui-autocomplete-option-color', '#FFF2FC');
678
- }
679
- if (this.type() !== Autocomplete.LARGE) {
680
- this.overflowDir?.setupObserver('.input-container');
681
- }
682
- this.scrollManager.enabled = this.infiniteScroll();
683
- this.scrollManager.closeOnScroll = this.closeOnScroll();
684
- this.scrollManager.panelTrigger = this.autocomplete;
685
- this.scrollManager.onBottomReached = () => this.onScrollBottom();
686
- this.scrollManager.startCloseOnScroll();
687
- this.focusMonitor
688
- .monitor(this.matInput)
689
- .pipe(takeUntilDestroyed(this.destroyRef))
690
- .subscribe(origin => this.ngZone.run(() => {
691
- this.keyboardFocused.set(origin === 'keyboard');
692
- }));
693
- this.matInput.nativeElement.onkeydown = this.onKeydown.bind(this);
694
- }
695
- ngOnDestroy() {
696
- this.scrollManager.ngOnDestroy();
697
- this.focusMonitor.stopMonitoring(this.matInput);
698
- if (this.matInput?.nativeElement) {
699
- this.matInput.nativeElement.onkeydown = null;
700
- }
701
- }
702
- registerOnChange(fn) {
703
- this.valueManager.registerOnChange(fn);
704
- }
705
- registerOnTouched(fn) {
706
- this.valueManager.registerOnTouched(fn);
707
- }
708
- setDisabledState(isDisabled) {
709
- this._isDisabled.set(isDisabled);
710
- this.cdr.markForCheck();
711
- }
712
- writeValue(value) {
713
- // Eagerly sync config so displayValue() computes correctly even if
714
- // constructor effects haven't run yet (e.g. first writeValue from a
715
- // FormControl with an initial value).
716
- this.valueManager.type.set(this.type());
717
- this.valueManager.textField.set(this.textField());
718
- this.valueManager.valueField.set(this.valueField());
719
- this.valueManager.compareWith.set(this.compareWith());
720
- this.valueManager.writeValue(value);
721
- // Drop tracked user-additions that are no longer in the externally-written value.
722
- if (this.userAdditionsGroupLabel()) {
723
- this.userAddedItems.update(items => {
724
- const v = this.valueManager.value();
725
- if (!AutocompleteV2Utils.isArray(v) || v.length === 0) {
726
- return [];
727
- }
728
- const vf = this.valueField();
729
- const tf = this.textField();
730
- return items.filter(i => v.some(x => (vf ? x[vf] === i[vf] : tf ? x[tf] === i[tf] : x === i)));
731
- });
732
- }
733
- this.inputValue.set(this.tagsBelow() ? '' : this.valueManager.displayValue());
734
- this.cdr.markForCheck();
735
- }
736
- get isGrouped() {
737
- return this.groupsList().length > 0;
738
- }
739
- onOptionSelected(event) {
740
- const inputValue = event.option.value;
741
- const itemValue = AutocompleteV2Utils.createValueItem(inputValue, this.textField(), this.valueField());
742
- const lengthBefore = AutocompleteV2Utils.isArray(this.valueManager.value())
743
- ? this.valueManager.value().length
744
- : 0;
745
- this.valueManager.addValue(itemValue);
746
- const lengthAfter = AutocompleteV2Utils.isArray(this.valueManager.value())
747
- ? this.valueManager.value().length
748
- : 0;
749
- const wasAdded = lengthAfter > lengthBefore;
750
- if (wasAdded && typeof event.option.value === 'string' && this.userAdditionsGroupLabel()) {
751
- const vf = this.valueField();
752
- const tf = this.textField();
753
- const alreadyTracked = vf
754
- ? this.userAddedItems().some(i => i[vf] === itemValue[vf])
755
- : tf
756
- ? this.userAddedItems().some(i => i[tf] === itemValue[tf])
757
- : this.userAddedItems().some(i => i === itemValue);
758
- if (!alreadyTracked) {
759
- this.userAddedItems.update(items => [...items, itemValue]);
760
- }
761
- }
762
- queueMicrotask(() => {
763
- if (this.type() !== this.autocompleteType.SINGLE) {
764
- // Multi: clear input so tags are visible while focused
765
- this.inputValue.set('');
766
- }
767
- else {
768
- this.inputValue.set(this.valueManager.displayValue());
769
- }
770
- this.cdr.markForCheck();
771
- });
772
- this.onUpdate();
773
- this.valueManager.markAsTouched();
774
- }
775
- onOptionRemoved(option) {
776
- setTimeout(() => this.autocomplete.closePanel(), 0);
777
- const foundValue = this.valueManager.removeValue(option);
778
- if (foundValue) {
779
- this.matAutocomplete.options.forEach(matOption => {
780
- const vf = this.valueField();
781
- if (vf && matOption.value?.[vf] === foundValue[vf]) {
782
- matOption.deselect();
783
- }
784
- });
785
- }
786
- if (this.userAdditionsGroupLabel()) {
787
- const vf = this.valueField();
788
- this.userAddedItems.update(items => items.filter(item => (vf ? item[vf] !== option[vf] : item !== option)));
789
- }
790
- if (!this.valueManager.value()?.length) {
791
- this.inputValue.set('');
792
- }
793
- this.onUpdate();
794
- this.valueManager.markAsTouched();
795
- }
796
- /**
797
- * Makes the whole below-tag a hit area for the control in its `uiAutocompleteTagSuffix` content
798
- * (e.g. a menu trigger). The remove icon keeps its own behavior, and presses inside the suffix never
799
- * reach here because the tag stops them.
800
- */
801
- onTagActivate(event) {
802
- const target = event.target;
803
- if (this._isDisabled() || target.closest('.delete-icon')) {
804
- return;
805
- }
806
- // Keyboard activation only from the tag itself, not from a focused child.
807
- if (event instanceof KeyboardEvent && !target.classList.contains('tag-container')) {
808
- return;
809
- }
810
- const control = event.currentTarget.querySelector('.tag-suffix button, .tag-suffix [role="button"], .tag-suffix a[href]');
811
- if (control) {
812
- event.preventDefault();
813
- control.click();
814
- }
815
- }
816
- onInputChange(event) {
817
- const text = event.target.value;
818
- this.filterService.search(text, this.minCharactersSearch());
819
- if (text.length >= this.minCharactersSearch()) {
820
- this.searchTextChange.emit(text);
821
- }
822
- }
823
- onClear() {
824
- this.inputValue.set('');
825
- this.valueManager.clear();
826
- this.userAddedItems.set([]);
827
- this.onUpdate();
828
- this.matAutocomplete?.options.forEach(option => option.deselect());
829
- this.valueManager.markAsTouched();
830
- }
831
- onBlur() {
832
- setTimeout(() => {
833
- this.filterService.clearSearch();
834
- this.isInputFocus.set(false);
835
- this.inputValue.set(this.tagsBelow() ? '' : this.valueManager.displayValue());
836
- this.valueManager.markAsTouched();
837
- this.blur.emit();
838
- this.cdr.markForCheck();
839
- }, 0);
840
- }
841
- onPanelOpened() {
842
- this.scrollManager.scrollToTop();
843
- }
844
- onScrollBottom() {
845
- if (this.filterService.searchText$.value) {
846
- this.scrollViewportBottomReachedFiltered.emit();
847
- }
848
- else {
849
- this.scrollViewportBottomReached.emit();
850
- }
851
- }
852
- onFocus() {
853
- this.isInputFocus.set(true);
854
- const val = this.inputValue();
855
- if (typeof val === 'string' && val.match(/^\s+/gm)) {
856
- this.inputValue.set(val.trimStart());
857
- }
858
- this.focus.emit();
859
- }
860
- onUpdate() {
861
- this.filterService.clearSearch();
862
- this.valueManager.notifyChange();
863
- const val = this.valueManager.value();
864
- if (val !== null) {
865
- this.selectionChange.emit(val);
866
- }
867
- }
868
- get isDropdown() {
869
- return this.variant() === DropdownVariation.DROPDOWN;
870
- }
871
- onChevronClick(autocomplete) {
872
- if (autocomplete.isOpen) {
873
- setTimeout(() => {
874
- this.autocomplete.closePanel();
875
- }, 0);
876
- }
877
- }
878
- onKeydown($event) {
879
- const optionHeight = 48;
880
- if ($event.key === IKeyboardEvent.HOME) {
881
- this.matAutocomplete._keyManager.setFirstItemActive();
882
- }
883
- else if ($event.key === IKeyboardEvent.END) {
884
- this.matAutocomplete._keyManager.setLastItemActive();
885
- }
886
- else if ($event.key === IKeyboardEvent.PAGE_DOWN) {
887
- this.matAutocomplete._keyManager.setNextItemActive();
888
- this.matAutocomplete._keyManager.setNextItemActive();
889
- this.matAutocomplete._keyManager.setNextItemActive();
890
- }
891
- else if ($event.key === IKeyboardEvent.PAGE_UP) {
892
- this.matAutocomplete._keyManager.setPreviousItemActive();
893
- this.matAutocomplete._keyManager.setPreviousItemActive();
894
- this.matAutocomplete._keyManager.setPreviousItemActive();
895
- }
896
- this.matAutocomplete._setScrollTop((this.matAutocomplete._keyManager.activeItemIndex ?? 0) * optionHeight);
897
- }
898
- getVirtualScrollHeight(itemCount) {
899
- const itemHeight = 48;
900
- const maxHeight = 200;
901
- const minHeight = 48;
902
- const calculatedHeight = itemCount * itemHeight;
903
- return Math.min(Math.max(calculatedHeight, minHeight), maxHeight);
904
- }
905
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AutocompleteV2Component, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
906
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: AutocompleteV2Component, isStandalone: true, selector: "ui-autocomplete-v2", inputs: { itemsList: { classPropertyName: "itemsList", publicName: "itemsList", isSignal: true, isRequired: false, transformFunction: null }, suggestionsList: { classPropertyName: "suggestionsList", publicName: "suggestionsList", isSignal: true, isRequired: false, transformFunction: null }, groupsList: { classPropertyName: "groupsList", publicName: "groupsList", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, allowAdd: { classPropertyName: "allowAdd", publicName: "allowAdd", isSignal: true, isRequired: false, transformFunction: null }, textField: { classPropertyName: "textField", publicName: "textField", isSignal: true, isRequired: false, transformFunction: null }, valueField: { classPropertyName: "valueField", publicName: "valueField", isSignal: true, isRequired: false, transformFunction: null }, imageField: { classPropertyName: "imageField", publicName: "imageField", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, testId: { classPropertyName: "testId", publicName: "testId", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, minCharactersSearch: { classPropertyName: "minCharactersSearch", publicName: "minCharactersSearch", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: true, transformFunction: null }, showBottomContent: { classPropertyName: "showBottomContent", publicName: "showBottomContent", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null }, dropdownPanelClass: { classPropertyName: "dropdownPanelClass", publicName: "dropdownPanelClass", isSignal: true, isRequired: false, transformFunction: null }, panelPosition: { classPropertyName: "panelPosition", publicName: "panelPosition", isSignal: true, isRequired: false, transformFunction: null }, hideSelectedSection: { classPropertyName: "hideSelectedSection", publicName: "hideSelectedSection", isSignal: true, isRequired: false, transformFunction: null }, userAdditionsGroupLabel: { classPropertyName: "userAdditionsGroupLabel", publicName: "userAdditionsGroupLabel", isSignal: true, isRequired: false, transformFunction: null }, closeOnScroll: { classPropertyName: "closeOnScroll", publicName: "closeOnScroll", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, allowUserInput: { classPropertyName: "allowUserInput", publicName: "allowUserInput", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, dynamicFilterLoading: { classPropertyName: "dynamicFilterLoading", publicName: "dynamicFilterLoading", isSignal: true, isRequired: false, transformFunction: null }, dynamicFilteredList: { classPropertyName: "dynamicFilteredList", publicName: "dynamicFilteredList", isSignal: true, isRequired: false, transformFunction: null }, infiniteScroll: { classPropertyName: "infiniteScroll", publicName: "infiniteScroll", isSignal: true, isRequired: false, transformFunction: null }, hasMoreOptionsForInfiniteScroll: { classPropertyName: "hasMoreOptionsForInfiniteScroll", publicName: "hasMoreOptionsForInfiniteScroll", isSignal: true, isRequired: false, transformFunction: null }, itemValue: { classPropertyName: "itemValue", publicName: "itemValue", isSignal: true, isRequired: false, transformFunction: null }, formErrorConfig: { classPropertyName: "formErrorConfig", publicName: "formErrorConfig", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, addOptionPosition: { classPropertyName: "addOptionPosition", publicName: "addOptionPosition", isSignal: true, isRequired: false, transformFunction: null }, tagsPosition: { classPropertyName: "tagsPosition", publicName: "tagsPosition", isSignal: true, isRequired: false, transformFunction: null }, tagIcon: { classPropertyName: "tagIcon", publicName: "tagIcon", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", searchTextChange: "searchTextChange", blur: "blur", focus: "focus", scrollViewportBottomReached: "scrollViewportBottomReached", scrollViewportBottomReachedFiltered: "scrollViewportBottomReachedFiltered" }, host: { properties: { "attr.theme": "applicationTheme" } }, providers: [AutocompleteValueManager, AutocompleteFilterService, InfiniteScrollDirective], queries: [{ propertyName: "tagSuffix", first: true, predicate: AutocompleteTagSuffixDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "formFieldElement", first: true, predicate: ["formField"], descendants: true }, { propertyName: "tagContainer", first: true, predicate: ["tagContainer"], descendants: true }, { propertyName: "measureElRef", first: true, predicate: ["measureEl"], descendants: true }, { propertyName: "overflowDir", first: true, predicate: ["overflow"], descendants: true }, { propertyName: "autocomplete", first: true, predicate: ["trigger"], descendants: true }, { propertyName: "cdkViewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true }, { propertyName: "matAutocomplete", first: true, predicate: ["autocomplete"], descendants: true }, { propertyName: "matInput", first: true, predicate: ["matInput"], descendants: true }], ngImport: i0, template: "<ng-container>\n <div class=\"autocomplete-wrapper\" [ngClass]=\"{ disabled: _isDisabled() }\">\n <mat-form-field\n [color]=\"hasError() ? 'warn' : 'accent'\"\n [appearance]=\"'outline'\"\n [ngClass]=\"{\n 'large-size': type() === autocompleteType.LARGE,\n 'hide-bottom-content': !showBottomContent(),\n 'keyboard-focused': keyboardFocused(),\n 'has-label': !!label(),\n }\"\n >\n @if (label()) {\n <mat-label\n >{{ label() }}\n @if (required()) {\n <span>*</span>\n }\n </mat-label>\n }\n <div\n #formField\n class=\"input-container\"\n [class.has-multiple-selections]=\"\n type() === autocompleteType.LARGE &&\n utils.isArray(valueManager.value()) &&\n $any(valueManager.value()).length > 1\n \"\n [class.autocomplete-variant]=\"type() === autocompleteType.LARGE && !isDropdown\"\n >\n @if (textField() ? $any(valueManager.value())?.[textField()] : $any(valueManager.value()) === inputValue()) {\n <span style=\"position: absolute; left: -9999px\" aria-live=\"polite\">{{\n ('SELECTED' | uiTranslate | async) + ' ' + inputValue()\n }}</span>\n }\n\n <input\n [attr.data-testid]=\"testId() ?? 'autocomplete-v2-input'\"\n #trigger=\"matAutocompleteTrigger\"\n #matInput\n [attr.maxlength]=\"maxLength() !== null && maxLength() !== undefined ? maxLength() : null\"\n [uiPreventInput]=\"!allowUserInput()\"\n [disabled]=\"_isDisabled()\"\n [ngClass]=\"{\n 'unset-margin': valueManager.value() && type() === autocompleteType.LARGE,\n 'no-caret': !allowUserInput(),\n }\"\n (blur)=\"onBlur()\"\n (focusin)=\"onFocus()\"\n [attr.aria-label]=\"\n (translationContext + 'SELECTED' | uiTranslate | async) +\n ' ' +\n (valueManager.value() | transformItem: textField() : true)\n \"\n matInput\n [placeholder]=\"suppressPlaceholder() ? '' : placeholder()\"\n [type]=\"'text'\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"panelPosition()\"\n (input)=\"onInputChange($event)\"\n [ngModel]=\"inputValue()\"\n (ngModelChange)=\"inputValue.set($event)\"\n />\n <!-- Hidden measurement container: always in DOM, renders ALL tags for width measurement -->\n @if (!tagsBelow() && type() !== autocompleteType.SINGLE && utils.isArray(valueManager.value())) {\n <div class=\"selected-items measurement-container\" #measureEl>\n @for (valueItem of $any(valueManager.value()); track valueItem[valueField()] || i; let i = $index) {\n <ui-tag\n class=\"value-tag\"\n [id]=\"'measure-tag-' + i\"\n [label]=\"valueItem | transformItem: textField()\"\n [allowClose]=\"true\"\n [isDisabled]=\"disabled()\"\n [applicationTheme]=\"applicationTheme\"\n ></ui-tag>\n }\n </div>\n }\n\n @if (\n !tagsBelow() &&\n ((type() === autocompleteType.LARGE && valueManager.value()) ||\n (!(inputValue() && isInputFocus()) && valueManager.value() && type() !== autocompleteType.SINGLE))\n ) {\n <!-- Visible container: only renders tags that fit. Hidden until first measurement to prevent flash. -->\n <div\n class=\"selected-items\"\n #tagContainer\n uiAutocompleteOverflowDetect\n #overflow=\"autocompleteOverflowDetect\"\n [measureContainer]=\"measureElRef?.nativeElement\"\n [class.measured]=\"\n type() === autocompleteType.LARGE || type() === autocompleteType.SINGLE || overflow.hasMeasured()\n \"\n >\n @if (size() === 'small' && $any(valueManager.value()).length > 1) {\n <div class=\"selected-count\">\n {{\n translationContext + 'SELECTED_AMOUNT'\n | uiTranslate: { numberSelected: valueManager.value()!.length }\n | async\n }}\n </div>\n } @else {\n @for (valueItem of $any(valueManager.value()); track valueItem[valueField()] || i; let i = $index) {\n @if (i < overflow.visibleCount()) {\n <ui-tag\n class=\"value-tag\"\n [id]=\"'ui-tag-' + i\"\n [label]=\"valueItem | transformItem: textField()\"\n [allowClose]=\"true\"\n [isDisabled]=\"disabled()\"\n [applicationTheme]=\"applicationTheme\"\n [ngStyle]=\"\n type() !== autocompleteType.LARGE\n ? { '--tag-max-width': overflow.tagMaxWidth() ? overflow.tagMaxWidth() + 'px' : 'fit-content' }\n : {}\n \"\n (close)=\"onOptionRemoved(valueItem)\"\n ></ui-tag>\n }\n }\n @if (overflow.overflowCount() > 0) {\n <div class=\"overlap-count\" [matTooltip]=\"hiddenItemsTooltip()\">\n <ui-tag\n [applicationTheme]=\"applicationTheme\"\n [isDisabled]=\"disabled()\"\n [label]=\"'+' + overflow.overflowCount()\"\n ></ui-tag>\n </div>\n }\n }\n </div>\n }\n </div>\n\n @if (showClearButton()) {\n <ui-icon\n class=\"remove-selected\"\n [tabIndex]=\"_isDisabled() ? -1 : 0\"\n (keydown.enter)=\"onClear(); $event.preventDefault(); $event.stopPropagation()\"\n (keydown.space)=\"onClear(); $event.preventDefault(); $event.stopPropagation()\"\n [ngClass]=\"{ 'large-input-icon': type() === autocompleteType.LARGE }\"\n (click)=\"onClear(); $event.preventDefault(); $event.stopPropagation()\"\n [size]=\"'24'\"\n [color]=\"applicationTheme === 'classic' ? 'inherit' : 'rebrand-black'\"\n [attr.aria-label]=\"'COMMON.CLEAR' | uiTranslate | async\"\n [name]=\"applicationTheme === 'classic' ? 'Close' : 'Close-in-line'\"\n ></ui-icon>\n }\n\n @if (isDropdown) {\n <ui-icon\n class=\"arrow-state\"\n [ngClass]=\"{ opened: autocomplete.isOpen, 'large-input-icon': type() === autocompleteType.LARGE }\"\n [size]=\"'24'\"\n [name]=\"applicationTheme !== 'classic' ? 'Arrow-chevron-down-in-line' : 'Arrow_down'\"\n (click)=\"onChevronClick(autocomplete)\"\n ></ui-icon>\n }\n\n <mat-autocomplete\n #autocomplete\n [class]=\"applicationTheme + ' ' + dropdownPanelClass()\"\n (optionSelected)=\"onOptionSelected($event)\"\n [disableRipple]=\"applicationTheme !== 'classic'\"\n [hideSingleSelectionIndicator]=\"false\"\n (opened)=\"onPanelOpened()\"\n >\n <ng-template #optionContentTpl let-item=\"item\" let-highlight=\"highlight\">\n @if (imageField() && item?.[imageField()]) {\n <img class=\"option-image\" [src]=\"item[imageField()]\" alt=\"\" />\n }\n <span [selectText]=\"highlight ? (filterService.userInput$ | async) : null\">{{\n item | transformItem: textField()\n }}</span>\n <ui-icon\n [applicationTheme]=\"applicationTheme\"\n [name]=\"applicationTheme === 'classic' ? 'Check' : 'Check-in-line'\"\n ></ui-icon>\n </ng-template>\n\n <!-- Reusable option template \u2014 must be inside mat-autocomplete for @ContentChildren to find mat-options -->\n <ng-template #optionTpl let-item=\"item\" let-highlight=\"highlight\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: highlight }\"\n ></ng-container>\n </mat-option>\n </ng-template>\n\n <!-- Reusable \"Add\"/no-results/loading option for the filtered view -->\n <ng-template #addOptionTpl let-items=\"items\" let-suggestions=\"suggestions\">\n @if (dynamicFilterLoading()) {\n <mat-option class=\"loading-option\" [style.pointer-events]=\"'none'\">\n <div class=\"loading-container\">\n <ui-spinner size=\"small\" [isLoader]=\"false\"></ui-spinner>\n </div>\n </mat-option>\n } @else if (inputValue()) {\n @if (\n allowAdd() && !isAlreadyAdded() && !utils.hasExactMatch(items, suggestions, inputValue(), textField())\n ) {\n <mat-option (mousedown)=\"$event.preventDefault()\" [value]=\"inputValue()\">\n <span>{{ 'COMMON.ADD' | uiTranslate | async }}</span>\n <span class=\"add-suggestion\">\"{{ inputValue() }}\"</span>\n </mat-option>\n } @else if (!items.length && !suggestions.length) {\n <mat-option [style.pointer-events]=\"'none'\">\n <span>{{ translationContext + 'NO_RESULTS_FOUND' | uiTranslate | async }}</span>\n </mat-option>\n }\n }\n </ng-template>\n\n <!-- \u2500\u2500 Unfiltered \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if ((filterService.isSearching$ | async) === false) {\n @if (!isDropdown) {\n <!-- Suggestions -->\n @if (suggestionsList().length) {\n <mat-optgroup [label]=\"(translationContext + 'SUGGESTED' | uiTranslate | async)! | uppercase\">\n @for (suggested of suggestionsList(); track suggested) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: suggested, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n }\n\n <!-- Selected items (multi) -->\n @if (valueManager.value()?.length && type() !== autocompleteType.SINGLE && !hideSelectedSection()) {\n <mat-optgroup [label]=\"(translationContext + 'SELECTED' | uiTranslate | async)! | uppercase\">\n @for (item of $any(valueManager.value()); track item) {\n <ng-container *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: false }\"></ng-container>\n }\n </mat-optgroup>\n }\n\n <!-- Main items (normalized groups) -->\n @if (virtualScroll() || infiniteScroll()) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"48\"\n [style.height.px]=\"getVirtualScrollHeight(flatItemsList().length)\"\n class=\"virtual-scroll\"\n >\n @if (!isGrouped) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of flatItemsList(); trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n } @else {\n @for (group of groupedItemsList(); track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n *cdkVirtualFor=\"let item of group.items; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n </mat-optgroup>\n } @else {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of group.items; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n }\n }\n\n @if (infiniteScroll() && hasMoreOptionsForInfiniteScroll()) {\n <mat-option class=\"loading-option\" [style.pointer-events]=\"'none'\">\n <div class=\"loading-container\">\n <ui-spinner size=\"small\" [isLoader]=\"false\"></ui-spinner>\n </div>\n </mat-option>\n }\n </cdk-virtual-scroll-viewport>\n } @else {\n @if (isGrouped) {\n @for (group of groupedItemsList(); track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n @for (item of group.items; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n } @else {\n @for (item of group.items; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n }\n }\n } @else {\n @for (item of flatItemsList(); track item) {\n <ng-container *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"></ng-container>\n }\n }\n }\n\n <!-- Selected item (single) -->\n @if (valueManager.value()?.length && type() === autocompleteType.SINGLE && !hideSelectedSection()) {\n <mat-optgroup [label]=\"(translationContext + 'SELECTED' | uiTranslate | async)! | uppercase\">\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: valueManager.value(), highlight: true }\"\n ></ng-container>\n </mat-optgroup>\n }\n } @else {\n <!-- \u2500\u2500 Dropdown (unfiltered) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (virtualScroll() || infiniteScroll()) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"48\"\n [style.height.px]=\"getVirtualScrollHeight(flatItemsList().length)\"\n class=\"virtual-scroll\"\n >\n @if (!isGrouped) {\n <!-- Ungrouped: flat cdkVirtualFor directly in viewport -->\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of flatItemsList(); trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n } @else {\n <!-- Grouped: nested cdkVirtualFor per group -->\n @for (group of groupedItemsList(); track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n *cdkVirtualFor=\"let item of group.items; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n </mat-optgroup>\n } @else {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of group.items; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n }\n }\n\n @if (infiniteScroll() && hasMoreOptionsForInfiniteScroll()) {\n <mat-option class=\"loading-option\" [style.pointer-events]=\"'none'\">\n <div class=\"loading-container\">\n <ui-spinner size=\"small\" [isLoader]=\"false\"></ui-spinner>\n </div>\n </mat-option>\n }\n </cdk-virtual-scroll-viewport>\n } @else {\n @if (isGrouped) {\n @for (group of groupedItemsList(); track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n @for (item of group.items; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n } @else {\n @for (item of group.items; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n }\n }\n } @else {\n @for (item of flatItemsList(); track item) {\n <ng-container *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"></ng-container>\n }\n }\n }\n }\n\n @if (userAdditionsGroupLabel() && userAddedItems().length) {\n <mat-optgroup [label]=\"userAdditionsGroupLabel()\">\n @for (item of userAddedItems(); track item) {\n <ng-container *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"></ng-container>\n }\n </mat-optgroup>\n }\n }\n\n <!-- \u2500\u2500 Filtered \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (filterService.filteredSuggestions$ | async; as filteredSuggestionList) {\n @if (filterService.filteredItems$ | async; as filteredItemsList) {\n @if (virtualScroll() || infiniteScroll()) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"48\"\n [style.height.px]=\"getVirtualScrollHeight(filteredItemsList.length)\"\n class=\"virtual-scroll\"\n >\n @if (addOptionPosition() === 'top') {\n <ng-container\n *ngTemplateOutlet=\"\n addOptionTpl;\n context: { items: filteredItemsList, suggestions: filteredSuggestionList }\n \"\n ></ng-container>\n }\n <!-- Filtered suggestions -->\n @if (filteredSuggestionList.length) {\n <mat-optgroup [label]=\"(translationContext + 'SUGGESTED' | uiTranslate | async)! | uppercase\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of filteredSuggestionList; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n </mat-optgroup>\n }\n\n <!-- Filtered items: grouped -->\n @if (isGrouped && (filterService.filteredGroupedItems$ | async); as filteredGroups) {\n @if (filteredGroups.length) {\n @for (group of filteredGroups; track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n *cdkVirtualFor=\"let item of group.filteredItems; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n </mat-optgroup>\n } @else {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n *cdkVirtualFor=\"let item of group.filteredItems; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n }\n }\n }\n\n <!-- Filtered items: ungrouped (no suggestions) -->\n @if (!filteredSuggestionList.length && !isGrouped) {\n @for (item of filteredItemsList; let idx = $index; track item[valueField()] || idx) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n } @else {\n <!-- Filtered items: ungrouped with suggestions present (ALL_ITEMS group) -->\n @if (filteredItemsList.length && !isGrouped) {\n <mat-optgroup [label]=\"(translationContext + 'ALL_ITEMS' | uiTranslate | async)! | uppercase\">\n @for (item of filteredItemsList; let idx = $index; track item[valueField()] || idx) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n </mat-optgroup>\n }\n }\n\n @if (addOptionPosition() === 'bottom') {\n <ng-container\n *ngTemplateOutlet=\"\n addOptionTpl;\n context: { items: filteredItemsList, suggestions: filteredSuggestionList }\n \"\n ></ng-container>\n }\n </cdk-virtual-scroll-viewport>\n } @else {\n @if (addOptionPosition() === 'top') {\n <ng-container\n *ngTemplateOutlet=\"\n addOptionTpl;\n context: { items: filteredItemsList, suggestions: filteredSuggestionList }\n \"\n ></ng-container>\n }\n <!-- Filtered items: grouped -->\n @if (isGrouped && (filterService.filteredGroupedItems$ | async); as filteredGroups) {\n @if (filteredGroups.length) {\n @for (group of filteredGroups; track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n @for (item of group.filteredItems; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n } @else {\n @for (item of group.filteredItems; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n }\n }\n }\n }\n\n <!-- Filtered suggestions -->\n @if (filteredSuggestionList.length) {\n <mat-optgroup [label]=\"(translationContext + 'SUGGESTED' | uiTranslate | async)! | uppercase\">\n @for (item of filteredSuggestionList; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n }\n\n <!-- Filtered items: ungrouped (no suggestions) -->\n @if (!filteredSuggestionList.length && !isGrouped) {\n @for (item of filteredItemsList; let idx = $index; track item[valueField()] || idx) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n } @else {\n <!-- Filtered items: ungrouped with suggestions present (ALL_ITEMS group) -->\n @if (filteredItemsList.length && !isGrouped) {\n <mat-optgroup [label]=\"(translationContext + 'ALL_ITEMS' | uiTranslate | async)! | uppercase\">\n @for (item of filteredItemsList; let idx = $index; track item[valueField()] || idx) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n </mat-optgroup>\n }\n }\n\n @if (addOptionPosition() === 'bottom') {\n <ng-container\n *ngTemplateOutlet=\"\n addOptionTpl;\n context: { items: filteredItemsList, suggestions: filteredSuggestionList }\n \"\n ></ng-container>\n }\n }\n }\n }\n </mat-autocomplete>\n @if (hasError()) {\n <mat-hint class=\"error\">\n @if (ngControl) {\n <ui-validation-error\n [ngControl]=\"ngControl\"\n [customErrors]=\"formErrorConfig()\"\n [label]=\"label()\"\n ></ui-validation-error>\n } @else {\n @for (error of safeErrors(); track error) {\n <div class=\"errors\">\n <ui-icon [applicationTheme]=\"applicationTheme\" [name]=\"'Error'\"></ui-icon>\n <span>{{ error }}</span>\n </div>\n }\n }\n </mat-hint>\n }\n </mat-form-field>\n @if (tagsBelow() && valueManager.value()?.length) {\n <div class=\"selected-items--below\">\n @for (valueItem of $any(valueManager.value()); track valueItem[valueField()] || i; let i = $index) {\n <ui-tag\n class=\"value-tag\"\n [id]=\"'below-tag-' + i\"\n [label]=\"valueItem | transformItem: textField()\"\n [icon]=\"tagIcons()[i]\"\n [allowClose]=\"true\"\n [isDisabled]=\"disabled()\"\n [constrainWidth]=\"true\"\n [applicationTheme]=\"applicationTheme\"\n (close)=\"onOptionRemoved(valueItem)\"\n (click)=\"onTagActivate($event)\"\n (keydown.enter)=\"onTagActivate($event)\"\n (keydown.space)=\"onTagActivate($event)\"\n >\n @if (tagSuffix(); as suffix) {\n <span class=\"value-tag__suffix\" uiTagSuffix>\n <ng-container *ngTemplateOutlet=\"suffix.templateRef; context: { $implicit: valueItem, index: i }\" />\n </span>\n }\n </ui-tag>\n }\n <!-- Consumer content rendered as a sibling of the selected tags, before the clear button -->\n <ng-content select=\"[autocompleteTagsSuffix]\"></ng-content>\n @if (clearable()) {\n <button type=\"button\" class=\"clear-all\" [disabled]=\"_isDisabled()\" (click)=\"onClear()\">\n {{ 'COMMON.CLEAR' | uiTranslate | async }}\n </button>\n }\n </div>\n }\n </div>\n</ng-container>\n", styles: [".bg-teal-60b{background:#1c443c}.bg-teal-30b{background:#31766a}.bg-teal-default{background:#46a997}.bg-teal-30w{background:#7ec3b6}.bg-teal-60w{background:#b5ddd5}.bg-teal-secondary{background:#cbd6cb}.bg-teal-90w{background:#ecf6f5}.bg-petrol-60b{background:#102930}.bg-petrol-30b{background:#1b4754}.bg-petrol-default{background:#276678}.bg-petrol-30w{background:#6894a0}.bg-petrol-60w{background:#a9c2c9}.bg-petrol-secondary{background:#c8d7de}.bg-petrol-90w{background:#e9f0f1}.bg-error-60b{background:#513131}.bg-error-30b{background:#8e5655}.bg-error-60w{background:#e3c3c6}.bg-error-secondary{background:#f0dad9}.bg-error-default{background:#cb7b7a}.bg-warning-secondary{background:#f0d6bb}.bg-warning-default{background:#cca45f}.bg-black{background:#000}.bg-dark{background:#888}.bg-medium{background:#e0e0e0}.bg-grey{background:#ededed}.bg-light{background:#f6f6f6}.bg-white{background:#fff}.bg-box-shadow{background:#00000014}.bg-navigation-subtitle{background:#528593}.bgc-teal-60b{background-color:#1c443c}.bgc-teal-30b{background-color:#31766a}.bgc-teal-default{background-color:#46a997}.bgc-teal-30w{background-color:#7ec3b6}.bgc-teal-60w{background-color:#b5ddd5}.bgc-teal-secondary{background-color:#cbd6cb}.bgc-teal-90w{background-color:#ecf6f5}.bgc-petrol-60b{background-color:#102930}.bgc-petrol-30b{background-color:#1b4754}.bgc-petrol-default{background-color:#276678}.bgc-petrol-30w{background-color:#6894a0}.bgc-petrol-60w{background-color:#a9c2c9}.bgc-petrol-secondary{background-color:#c8d7de}.bgc-petrol-90w{background-color:#e9f0f1}.bgc-error-60b{background-color:#513131}.bgc-error-30b{background-color:#8e5655}.bgc-error-60w{background-color:#e3c3c6}.bgc-error-secondary{background-color:#f0dad9}.bgc-error-default{background-color:#cb7b7a}.bgc-warning-secondary{background-color:#f0d6bb}.bgc-warning-default{background-color:#cca45f}.bgc-black{background-color:#000}.bgc-dark{background-color:#888}.bgc-medium{background-color:#e0e0e0}.bgc-grey{background-color:#ededed}.bgc-light{background-color:#f6f6f6}.bgc-white{background-color:#fff}.bgc-box-shadow{background-color:#00000014}.bgc-navigation-subtitle{background-color:#528593}:host{width:320px;display:block}:host.full-width{width:100%}:host ui-tag{height:32px;margin:4px}:host ui-tag ::ng-deep .tag-container{margin:0!important}:host ui-tag ::ng-deep .tag-wrapper{max-width:fit-content}.large-size input{margin:10px 0}.large-size .selected-items{margin:5px 0;flex-wrap:wrap;--tag-max-width: calc(100% - 8px) }.large-size .selected-items .value-tag ::ng-deep .tag-container{max-width:100%!important}.large-size .input-container{margin:auto 0;width:calc(100% - 25px);display:flex;flex-direction:column-reverse}.large-size .input-container.has-multiple-selections{width:calc(100% - 50px)}.large-size .input-container.autocomplete-variant{width:100%}.large-size .input-container.autocomplete-variant.has-multiple-selections{width:calc(100% - 26px)}.large-size ::ng-deep .mat-mdc-form-field-infix,.large-size .mat-mdc-form-field-flex{align-items:unset!important}.disabled *{pointer-events:none}.input-container{width:100%;margin:auto;display:flex;flex-direction:row-reverse}.input-container .selected-items{display:flex;padding-left:4px;visibility:hidden}.input-container .selected-items.measured{visibility:visible}.input-container .selected-items .value-tag{max-width:var(--tag-max-width, fit-content)}.input-container .selected-items .value-tag ::ng-deep .tag-container{max-width:var(--tag-max-width, fit-content)}.input-container .selected-items .selected-count{white-space:nowrap}.input-container .selected-items.measurement-container{visibility:hidden;position:absolute;height:0;overflow:hidden;pointer-events:none}.input-container .overlap-count{font-size:14px;line-height:20px}.input-container .overlap-count ui-tag{display:block}.input-container input{margin-left:6px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.input-container input.unset-margin{margin-top:unset}.input-container input.no-caret{cursor:pointer;caret-color:transparent!important}.add-suggestion{margin:0 5px;color:#000;font-weight:700}.remove-selected{cursor:pointer;margin-right:2px;border-radius:50px;height:fit-content}.remove-selected.large-input-icon{margin-top:10px}.arrow-state{height:24px;cursor:pointer}.arrow-state.large-input-icon{margin-top:10px}.arrow-state.opened{transform:rotateX(180deg)}::ng-deep .autocomplete-wrapper .mat-mdc-form-field{width:100%}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error,::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error svg{color:#cb7b7a}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error{display:flex}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error{display:flex;flex-flow:column;row-gap:4px}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error .errors ui-icon{margin-right:8px}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error .errors{display:flex}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error{color:#e02800!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error svg{color:#e02800!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-bottom-align:before{height:0}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint-wrapper{padding:0 0 12px;font-size:12px;line-height:16px;position:relative}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint-wrapper .mat-form-field-hint-spacer{display:none}::ng-deep .autocomplete-wrapper .mat-mdc-form-field.hide-bottom-content .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-text-field-wrapper.mdc-text-field--outlined .mdc-notched-outline--upgraded .mdc-floating-label--float-above{top:28px!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-floating-label{top:22px!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-text-field-wrapper{padding-left:12px!important;height:unset!important;max-height:unset!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-focused .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-floating-label{color:#276678!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mdc-text-field--outlined:not(.mdc-text-field--disabled).mdc-text-field--focused .mdc-notched-outline__notch{border-bottom:2px solid #276678!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mdc-text-field--outlined:not(.mdc-text-field--disabled).mdc-text-field--focused .mdc-notched-outline__leading{border-left:2px solid #276678!important;border-bottom:2px solid #276678!important;border-top:2px solid #276678!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mdc-text-field--outlined:not(.mdc-text-field--disabled).mdc-text-field--focused .mdc-notched-outline__trailing{border:2px solid #276678!important;border-left:unset!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-infix,::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-flex{min-height:48px!important;max-height:184px!important;overflow-y:auto;overflow-x:hidden;padding:0!important;display:flex;justify-content:center;text-align:center;align-items:center;flex-direction:row;width:100%}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mdc-line-ripple{display:none!important}::ng-deep .mat-mdc-autocomplete-panel{box-shadow:0 8px 24px 4px #00000014;max-height:312px!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option:hover:not(.mdc-list-item--disabled),::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option:focus:not(.mdc-list-item--disabled),::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.mat-mdc-option-active,::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.mdc-list-item--selected:not(.mat-mdc-option-multiple):not(.mdc-list-item--disabled){background:#e9f0f1!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option{padding-right:32px;padding-left:12px!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .option-image{width:24px;height:24px;margin-right:8px;object-fit:cover;flex-shrink:0}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option ui-icon{display:none;position:absolute;right:0;bottom:calc(50% - 8px);margin:0 10px}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.selected-option{background:#e9f0f1}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.selected-option ui-icon{display:block}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.mdc-list-item--selected .mdc-list-item__primary-text,::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .mdc-list-item--activated .mdc-list-item__primary-text{color:#000!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .mdc-list-item__primary-text{display:flex;align-items:center}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .mat-pseudo-checkbox{display:none}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-optgroup .mat-mdc-optgroup-label{font-weight:700!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-optgroup .mat-mdc-optgroup-label .mdc-list-item__primary-text{color:#000;font-size:12px;line-height:16px;font-weight:700}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-optgroup .mat-mdc-option{padding-left:16px!important}.active-field .mdc-notched-outline__leading{border-left-width:2px;border-top-width:2px;border-bottom-width:2px}.active-field .mdc-notched-outline__notch{border-top-width:2px;border-bottom-width:2px}.active-field .mdc-notched-outline__trailing{border-top-width:2px;border-bottom-width:2px;border-right-width:2px}.loading-option{display:flex}.loading-option .loading-container{display:flex;justify-content:center;align-items:center;width:100%;height:100%;position:absolute;top:0;left:0}.selected-items--below{display:flex;flex-wrap:wrap;align-items:center;gap:4px;margin-top:8px}.selected-items--below ui-tag{margin:0;--ui-tag-max-width: 400px}.selected-items--below .clear-all{background:none;border:none;padding:4px 8px;cursor:pointer;color:#000;font-weight:500;font-size:12px;line-height:16px;text-decoration:underline}.selected-items--below .clear-all:disabled{cursor:not-allowed;opacity:.5}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i3.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i3.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "directive", type: i3.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: TagComponentModule }, { kind: "component", type: i6.TagComponent, selector: "ui-tag", inputs: ["label", "icon", "allowClose", "readOnly", "isSelected", "showIconWhenSelected", "pinnedBackground", "constrainWidth", "isDisabled", "applicationTheme", "ariaLabel", "testId", "ariaRequired", "showBadge", "notificationsAmount"], outputs: ["isSelectedChange", "close", "press"] }, { kind: "ngmodule", type: IconComponentModule }, { kind: "component", type: i7.IconComponent, selector: "ui-icon", inputs: ["size", "cssClass", "name", "color", "filled", "toggleIconStyle", "applicationTheme", "useFullIconName"] }, { kind: "ngmodule", type: SpinnerComponentModule }, { kind: "component", type: i8.SpinnerComponent, selector: "ui-spinner", inputs: ["size", "isLoader", "text", "applicationTheme", "iconName", "iconSize"] }, { kind: "component", type: CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "directive", type: CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "directive", type: CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: PreventInputDirective, selector: "[uiPreventInput]", inputs: ["uiPreventInput"] }, { kind: "directive", type: SelectTextDirective, selector: "[selectText]", inputs: ["selectText"] }, { kind: "directive", type: AutocompleteOverflowDetectDirective, selector: "[uiAutocompleteOverflowDetect]", inputs: ["measureContainer", "itemSelector", "reserveWidth"], exportAs: ["autocompleteOverflowDetect"] }, { kind: "ngmodule", type: ValidationErrorModule }, { kind: "component", type: i9.ValidationErrorComponent, selector: "ui-validation-error", inputs: ["ngControl", "touchedOn", "errorMessage", "label", "applicationTheme", "customErrors"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i10.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: UiTranslatePipe, name: "uiTranslate" }, { kind: "pipe", type: TransformItemPipe, name: "transformItem" }, { kind: "pipe", type: IncludesPipe, name: "includes" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
907
- }
908
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: AutocompleteV2Component, decorators: [{
909
- type: Component,
910
- args: [{ selector: 'ui-autocomplete-v2', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
911
- CommonModule,
912
- FormsModule,
913
- MatAutocompleteModule,
914
- MatChipsModule,
915
- MatFormFieldModule,
916
- MatInputModule,
917
- TagComponentModule,
918
- IconComponentModule,
919
- SpinnerComponentModule,
920
- CdkVirtualScrollViewport,
921
- CdkVirtualForOf,
922
- CdkFixedSizeVirtualScroll,
923
- PreventInputDirective,
924
- UiTranslatePipe,
925
- TransformItemPipe,
926
- IncludesPipe,
927
- SelectTextDirective,
928
- AutocompleteOverflowDetectDirective,
929
- ValidationErrorModule,
930
- MatTooltipModule,
931
- ], host: {
932
- '[attr.theme]': 'applicationTheme',
933
- }, providers: [AutocompleteValueManager, AutocompleteFilterService, InfiniteScrollDirective], template: "<ng-container>\n <div class=\"autocomplete-wrapper\" [ngClass]=\"{ disabled: _isDisabled() }\">\n <mat-form-field\n [color]=\"hasError() ? 'warn' : 'accent'\"\n [appearance]=\"'outline'\"\n [ngClass]=\"{\n 'large-size': type() === autocompleteType.LARGE,\n 'hide-bottom-content': !showBottomContent(),\n 'keyboard-focused': keyboardFocused(),\n 'has-label': !!label(),\n }\"\n >\n @if (label()) {\n <mat-label\n >{{ label() }}\n @if (required()) {\n <span>*</span>\n }\n </mat-label>\n }\n <div\n #formField\n class=\"input-container\"\n [class.has-multiple-selections]=\"\n type() === autocompleteType.LARGE &&\n utils.isArray(valueManager.value()) &&\n $any(valueManager.value()).length > 1\n \"\n [class.autocomplete-variant]=\"type() === autocompleteType.LARGE && !isDropdown\"\n >\n @if (textField() ? $any(valueManager.value())?.[textField()] : $any(valueManager.value()) === inputValue()) {\n <span style=\"position: absolute; left: -9999px\" aria-live=\"polite\">{{\n ('SELECTED' | uiTranslate | async) + ' ' + inputValue()\n }}</span>\n }\n\n <input\n [attr.data-testid]=\"testId() ?? 'autocomplete-v2-input'\"\n #trigger=\"matAutocompleteTrigger\"\n #matInput\n [attr.maxlength]=\"maxLength() !== null && maxLength() !== undefined ? maxLength() : null\"\n [uiPreventInput]=\"!allowUserInput()\"\n [disabled]=\"_isDisabled()\"\n [ngClass]=\"{\n 'unset-margin': valueManager.value() && type() === autocompleteType.LARGE,\n 'no-caret': !allowUserInput(),\n }\"\n (blur)=\"onBlur()\"\n (focusin)=\"onFocus()\"\n [attr.aria-label]=\"\n (translationContext + 'SELECTED' | uiTranslate | async) +\n ' ' +\n (valueManager.value() | transformItem: textField() : true)\n \"\n matInput\n [placeholder]=\"suppressPlaceholder() ? '' : placeholder()\"\n [type]=\"'text'\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"panelPosition()\"\n (input)=\"onInputChange($event)\"\n [ngModel]=\"inputValue()\"\n (ngModelChange)=\"inputValue.set($event)\"\n />\n <!-- Hidden measurement container: always in DOM, renders ALL tags for width measurement -->\n @if (!tagsBelow() && type() !== autocompleteType.SINGLE && utils.isArray(valueManager.value())) {\n <div class=\"selected-items measurement-container\" #measureEl>\n @for (valueItem of $any(valueManager.value()); track valueItem[valueField()] || i; let i = $index) {\n <ui-tag\n class=\"value-tag\"\n [id]=\"'measure-tag-' + i\"\n [label]=\"valueItem | transformItem: textField()\"\n [allowClose]=\"true\"\n [isDisabled]=\"disabled()\"\n [applicationTheme]=\"applicationTheme\"\n ></ui-tag>\n }\n </div>\n }\n\n @if (\n !tagsBelow() &&\n ((type() === autocompleteType.LARGE && valueManager.value()) ||\n (!(inputValue() && isInputFocus()) && valueManager.value() && type() !== autocompleteType.SINGLE))\n ) {\n <!-- Visible container: only renders tags that fit. Hidden until first measurement to prevent flash. -->\n <div\n class=\"selected-items\"\n #tagContainer\n uiAutocompleteOverflowDetect\n #overflow=\"autocompleteOverflowDetect\"\n [measureContainer]=\"measureElRef?.nativeElement\"\n [class.measured]=\"\n type() === autocompleteType.LARGE || type() === autocompleteType.SINGLE || overflow.hasMeasured()\n \"\n >\n @if (size() === 'small' && $any(valueManager.value()).length > 1) {\n <div class=\"selected-count\">\n {{\n translationContext + 'SELECTED_AMOUNT'\n | uiTranslate: { numberSelected: valueManager.value()!.length }\n | async\n }}\n </div>\n } @else {\n @for (valueItem of $any(valueManager.value()); track valueItem[valueField()] || i; let i = $index) {\n @if (i < overflow.visibleCount()) {\n <ui-tag\n class=\"value-tag\"\n [id]=\"'ui-tag-' + i\"\n [label]=\"valueItem | transformItem: textField()\"\n [allowClose]=\"true\"\n [isDisabled]=\"disabled()\"\n [applicationTheme]=\"applicationTheme\"\n [ngStyle]=\"\n type() !== autocompleteType.LARGE\n ? { '--tag-max-width': overflow.tagMaxWidth() ? overflow.tagMaxWidth() + 'px' : 'fit-content' }\n : {}\n \"\n (close)=\"onOptionRemoved(valueItem)\"\n ></ui-tag>\n }\n }\n @if (overflow.overflowCount() > 0) {\n <div class=\"overlap-count\" [matTooltip]=\"hiddenItemsTooltip()\">\n <ui-tag\n [applicationTheme]=\"applicationTheme\"\n [isDisabled]=\"disabled()\"\n [label]=\"'+' + overflow.overflowCount()\"\n ></ui-tag>\n </div>\n }\n }\n </div>\n }\n </div>\n\n @if (showClearButton()) {\n <ui-icon\n class=\"remove-selected\"\n [tabIndex]=\"_isDisabled() ? -1 : 0\"\n (keydown.enter)=\"onClear(); $event.preventDefault(); $event.stopPropagation()\"\n (keydown.space)=\"onClear(); $event.preventDefault(); $event.stopPropagation()\"\n [ngClass]=\"{ 'large-input-icon': type() === autocompleteType.LARGE }\"\n (click)=\"onClear(); $event.preventDefault(); $event.stopPropagation()\"\n [size]=\"'24'\"\n [color]=\"applicationTheme === 'classic' ? 'inherit' : 'rebrand-black'\"\n [attr.aria-label]=\"'COMMON.CLEAR' | uiTranslate | async\"\n [name]=\"applicationTheme === 'classic' ? 'Close' : 'Close-in-line'\"\n ></ui-icon>\n }\n\n @if (isDropdown) {\n <ui-icon\n class=\"arrow-state\"\n [ngClass]=\"{ opened: autocomplete.isOpen, 'large-input-icon': type() === autocompleteType.LARGE }\"\n [size]=\"'24'\"\n [name]=\"applicationTheme !== 'classic' ? 'Arrow-chevron-down-in-line' : 'Arrow_down'\"\n (click)=\"onChevronClick(autocomplete)\"\n ></ui-icon>\n }\n\n <mat-autocomplete\n #autocomplete\n [class]=\"applicationTheme + ' ' + dropdownPanelClass()\"\n (optionSelected)=\"onOptionSelected($event)\"\n [disableRipple]=\"applicationTheme !== 'classic'\"\n [hideSingleSelectionIndicator]=\"false\"\n (opened)=\"onPanelOpened()\"\n >\n <ng-template #optionContentTpl let-item=\"item\" let-highlight=\"highlight\">\n @if (imageField() && item?.[imageField()]) {\n <img class=\"option-image\" [src]=\"item[imageField()]\" alt=\"\" />\n }\n <span [selectText]=\"highlight ? (filterService.userInput$ | async) : null\">{{\n item | transformItem: textField()\n }}</span>\n <ui-icon\n [applicationTheme]=\"applicationTheme\"\n [name]=\"applicationTheme === 'classic' ? 'Check' : 'Check-in-line'\"\n ></ui-icon>\n </ng-template>\n\n <!-- Reusable option template \u2014 must be inside mat-autocomplete for @ContentChildren to find mat-options -->\n <ng-template #optionTpl let-item=\"item\" let-highlight=\"highlight\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: highlight }\"\n ></ng-container>\n </mat-option>\n </ng-template>\n\n <!-- Reusable \"Add\"/no-results/loading option for the filtered view -->\n <ng-template #addOptionTpl let-items=\"items\" let-suggestions=\"suggestions\">\n @if (dynamicFilterLoading()) {\n <mat-option class=\"loading-option\" [style.pointer-events]=\"'none'\">\n <div class=\"loading-container\">\n <ui-spinner size=\"small\" [isLoader]=\"false\"></ui-spinner>\n </div>\n </mat-option>\n } @else if (inputValue()) {\n @if (\n allowAdd() && !isAlreadyAdded() && !utils.hasExactMatch(items, suggestions, inputValue(), textField())\n ) {\n <mat-option (mousedown)=\"$event.preventDefault()\" [value]=\"inputValue()\">\n <span>{{ 'COMMON.ADD' | uiTranslate | async }}</span>\n <span class=\"add-suggestion\">\"{{ inputValue() }}\"</span>\n </mat-option>\n } @else if (!items.length && !suggestions.length) {\n <mat-option [style.pointer-events]=\"'none'\">\n <span>{{ translationContext + 'NO_RESULTS_FOUND' | uiTranslate | async }}</span>\n </mat-option>\n }\n }\n </ng-template>\n\n <!-- \u2500\u2500 Unfiltered \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if ((filterService.isSearching$ | async) === false) {\n @if (!isDropdown) {\n <!-- Suggestions -->\n @if (suggestionsList().length) {\n <mat-optgroup [label]=\"(translationContext + 'SUGGESTED' | uiTranslate | async)! | uppercase\">\n @for (suggested of suggestionsList(); track suggested) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: suggested, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n }\n\n <!-- Selected items (multi) -->\n @if (valueManager.value()?.length && type() !== autocompleteType.SINGLE && !hideSelectedSection()) {\n <mat-optgroup [label]=\"(translationContext + 'SELECTED' | uiTranslate | async)! | uppercase\">\n @for (item of $any(valueManager.value()); track item) {\n <ng-container *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: false }\"></ng-container>\n }\n </mat-optgroup>\n }\n\n <!-- Main items (normalized groups) -->\n @if (virtualScroll() || infiniteScroll()) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"48\"\n [style.height.px]=\"getVirtualScrollHeight(flatItemsList().length)\"\n class=\"virtual-scroll\"\n >\n @if (!isGrouped) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of flatItemsList(); trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n } @else {\n @for (group of groupedItemsList(); track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n *cdkVirtualFor=\"let item of group.items; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n </mat-optgroup>\n } @else {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of group.items; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n }\n }\n\n @if (infiniteScroll() && hasMoreOptionsForInfiniteScroll()) {\n <mat-option class=\"loading-option\" [style.pointer-events]=\"'none'\">\n <div class=\"loading-container\">\n <ui-spinner size=\"small\" [isLoader]=\"false\"></ui-spinner>\n </div>\n </mat-option>\n }\n </cdk-virtual-scroll-viewport>\n } @else {\n @if (isGrouped) {\n @for (group of groupedItemsList(); track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n @for (item of group.items; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n } @else {\n @for (item of group.items; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n }\n }\n } @else {\n @for (item of flatItemsList(); track item) {\n <ng-container *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"></ng-container>\n }\n }\n }\n\n <!-- Selected item (single) -->\n @if (valueManager.value()?.length && type() === autocompleteType.SINGLE && !hideSelectedSection()) {\n <mat-optgroup [label]=\"(translationContext + 'SELECTED' | uiTranslate | async)! | uppercase\">\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: valueManager.value(), highlight: true }\"\n ></ng-container>\n </mat-optgroup>\n }\n } @else {\n <!-- \u2500\u2500 Dropdown (unfiltered) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (virtualScroll() || infiniteScroll()) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"48\"\n [style.height.px]=\"getVirtualScrollHeight(flatItemsList().length)\"\n class=\"virtual-scroll\"\n >\n @if (!isGrouped) {\n <!-- Ungrouped: flat cdkVirtualFor directly in viewport -->\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of flatItemsList(); trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n } @else {\n <!-- Grouped: nested cdkVirtualFor per group -->\n @for (group of groupedItemsList(); track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n *cdkVirtualFor=\"let item of group.items; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n </mat-optgroup>\n } @else {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of group.items; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n }\n }\n\n @if (infiniteScroll() && hasMoreOptionsForInfiniteScroll()) {\n <mat-option class=\"loading-option\" [style.pointer-events]=\"'none'\">\n <div class=\"loading-container\">\n <ui-spinner size=\"small\" [isLoader]=\"false\"></ui-spinner>\n </div>\n </mat-option>\n }\n </cdk-virtual-scroll-viewport>\n } @else {\n @if (isGrouped) {\n @for (group of groupedItemsList(); track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n @for (item of group.items; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n } @else {\n @for (item of group.items; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n }\n }\n } @else {\n @for (item of flatItemsList(); track item) {\n <ng-container *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"></ng-container>\n }\n }\n }\n }\n\n @if (userAdditionsGroupLabel() && userAddedItems().length) {\n <mat-optgroup [label]=\"userAdditionsGroupLabel()\">\n @for (item of userAddedItems(); track item) {\n <ng-container *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"></ng-container>\n }\n </mat-optgroup>\n }\n }\n\n <!-- \u2500\u2500 Filtered \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (filterService.filteredSuggestions$ | async; as filteredSuggestionList) {\n @if (filterService.filteredItems$ | async; as filteredItemsList) {\n @if (virtualScroll() || infiniteScroll()) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"48\"\n [style.height.px]=\"getVirtualScrollHeight(filteredItemsList.length)\"\n class=\"virtual-scroll\"\n >\n @if (addOptionPosition() === 'top') {\n <ng-container\n *ngTemplateOutlet=\"\n addOptionTpl;\n context: { items: filteredItemsList, suggestions: filteredSuggestionList }\n \"\n ></ng-container>\n }\n <!-- Filtered suggestions -->\n @if (filteredSuggestionList.length) {\n <mat-optgroup [label]=\"(translationContext + 'SUGGESTED' | uiTranslate | async)! | uppercase\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of filteredSuggestionList; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n </mat-optgroup>\n }\n\n <!-- Filtered items: grouped -->\n @if (isGrouped && (filterService.filteredGroupedItems$ | async); as filteredGroups) {\n @if (filteredGroups.length) {\n @for (group of filteredGroups; track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n *cdkVirtualFor=\"let item of group.filteredItems; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n </mat-optgroup>\n } @else {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n *cdkVirtualFor=\"let item of group.filteredItems; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n }\n }\n }\n\n <!-- Filtered items: ungrouped (no suggestions) -->\n @if (!filteredSuggestionList.length && !isGrouped) {\n @for (item of filteredItemsList; let idx = $index; track item[valueField()] || idx) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n } @else {\n <!-- Filtered items: ungrouped with suggestions present (ALL_ITEMS group) -->\n @if (filteredItemsList.length && !isGrouped) {\n <mat-optgroup [label]=\"(translationContext + 'ALL_ITEMS' | uiTranslate | async)! | uppercase\">\n @for (item of filteredItemsList; let idx = $index; track item[valueField()] || idx) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n </mat-optgroup>\n }\n }\n\n @if (addOptionPosition() === 'bottom') {\n <ng-container\n *ngTemplateOutlet=\"\n addOptionTpl;\n context: { items: filteredItemsList, suggestions: filteredSuggestionList }\n \"\n ></ng-container>\n }\n </cdk-virtual-scroll-viewport>\n } @else {\n @if (addOptionPosition() === 'top') {\n <ng-container\n *ngTemplateOutlet=\"\n addOptionTpl;\n context: { items: filteredItemsList, suggestions: filteredSuggestionList }\n \"\n ></ng-container>\n }\n <!-- Filtered items: grouped -->\n @if (isGrouped && (filterService.filteredGroupedItems$ | async); as filteredGroups) {\n @if (filteredGroups.length) {\n @for (group of filteredGroups; track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n @for (item of group.filteredItems; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n } @else {\n @for (item of group.filteredItems; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n }\n }\n }\n }\n\n <!-- Filtered suggestions -->\n @if (filteredSuggestionList.length) {\n <mat-optgroup [label]=\"(translationContext + 'SUGGESTED' | uiTranslate | async)! | uppercase\">\n @for (item of filteredSuggestionList; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n }\n\n <!-- Filtered items: ungrouped (no suggestions) -->\n @if (!filteredSuggestionList.length && !isGrouped) {\n @for (item of filteredItemsList; let idx = $index; track item[valueField()] || idx) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n } @else {\n <!-- Filtered items: ungrouped with suggestions present (ALL_ITEMS group) -->\n @if (filteredItemsList.length && !isGrouped) {\n <mat-optgroup [label]=\"(translationContext + 'ALL_ITEMS' | uiTranslate | async)! | uppercase\">\n @for (item of filteredItemsList; let idx = $index; track item[valueField()] || idx) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n </mat-optgroup>\n }\n }\n\n @if (addOptionPosition() === 'bottom') {\n <ng-container\n *ngTemplateOutlet=\"\n addOptionTpl;\n context: { items: filteredItemsList, suggestions: filteredSuggestionList }\n \"\n ></ng-container>\n }\n }\n }\n }\n </mat-autocomplete>\n @if (hasError()) {\n <mat-hint class=\"error\">\n @if (ngControl) {\n <ui-validation-error\n [ngControl]=\"ngControl\"\n [customErrors]=\"formErrorConfig()\"\n [label]=\"label()\"\n ></ui-validation-error>\n } @else {\n @for (error of safeErrors(); track error) {\n <div class=\"errors\">\n <ui-icon [applicationTheme]=\"applicationTheme\" [name]=\"'Error'\"></ui-icon>\n <span>{{ error }}</span>\n </div>\n }\n }\n </mat-hint>\n }\n </mat-form-field>\n @if (tagsBelow() && valueManager.value()?.length) {\n <div class=\"selected-items--below\">\n @for (valueItem of $any(valueManager.value()); track valueItem[valueField()] || i; let i = $index) {\n <ui-tag\n class=\"value-tag\"\n [id]=\"'below-tag-' + i\"\n [label]=\"valueItem | transformItem: textField()\"\n [icon]=\"tagIcons()[i]\"\n [allowClose]=\"true\"\n [isDisabled]=\"disabled()\"\n [constrainWidth]=\"true\"\n [applicationTheme]=\"applicationTheme\"\n (close)=\"onOptionRemoved(valueItem)\"\n (click)=\"onTagActivate($event)\"\n (keydown.enter)=\"onTagActivate($event)\"\n (keydown.space)=\"onTagActivate($event)\"\n >\n @if (tagSuffix(); as suffix) {\n <span class=\"value-tag__suffix\" uiTagSuffix>\n <ng-container *ngTemplateOutlet=\"suffix.templateRef; context: { $implicit: valueItem, index: i }\" />\n </span>\n }\n </ui-tag>\n }\n <!-- Consumer content rendered as a sibling of the selected tags, before the clear button -->\n <ng-content select=\"[autocompleteTagsSuffix]\"></ng-content>\n @if (clearable()) {\n <button type=\"button\" class=\"clear-all\" [disabled]=\"_isDisabled()\" (click)=\"onClear()\">\n {{ 'COMMON.CLEAR' | uiTranslate | async }}\n </button>\n }\n </div>\n }\n </div>\n</ng-container>\n", styles: [".bg-teal-60b{background:#1c443c}.bg-teal-30b{background:#31766a}.bg-teal-default{background:#46a997}.bg-teal-30w{background:#7ec3b6}.bg-teal-60w{background:#b5ddd5}.bg-teal-secondary{background:#cbd6cb}.bg-teal-90w{background:#ecf6f5}.bg-petrol-60b{background:#102930}.bg-petrol-30b{background:#1b4754}.bg-petrol-default{background:#276678}.bg-petrol-30w{background:#6894a0}.bg-petrol-60w{background:#a9c2c9}.bg-petrol-secondary{background:#c8d7de}.bg-petrol-90w{background:#e9f0f1}.bg-error-60b{background:#513131}.bg-error-30b{background:#8e5655}.bg-error-60w{background:#e3c3c6}.bg-error-secondary{background:#f0dad9}.bg-error-default{background:#cb7b7a}.bg-warning-secondary{background:#f0d6bb}.bg-warning-default{background:#cca45f}.bg-black{background:#000}.bg-dark{background:#888}.bg-medium{background:#e0e0e0}.bg-grey{background:#ededed}.bg-light{background:#f6f6f6}.bg-white{background:#fff}.bg-box-shadow{background:#00000014}.bg-navigation-subtitle{background:#528593}.bgc-teal-60b{background-color:#1c443c}.bgc-teal-30b{background-color:#31766a}.bgc-teal-default{background-color:#46a997}.bgc-teal-30w{background-color:#7ec3b6}.bgc-teal-60w{background-color:#b5ddd5}.bgc-teal-secondary{background-color:#cbd6cb}.bgc-teal-90w{background-color:#ecf6f5}.bgc-petrol-60b{background-color:#102930}.bgc-petrol-30b{background-color:#1b4754}.bgc-petrol-default{background-color:#276678}.bgc-petrol-30w{background-color:#6894a0}.bgc-petrol-60w{background-color:#a9c2c9}.bgc-petrol-secondary{background-color:#c8d7de}.bgc-petrol-90w{background-color:#e9f0f1}.bgc-error-60b{background-color:#513131}.bgc-error-30b{background-color:#8e5655}.bgc-error-60w{background-color:#e3c3c6}.bgc-error-secondary{background-color:#f0dad9}.bgc-error-default{background-color:#cb7b7a}.bgc-warning-secondary{background-color:#f0d6bb}.bgc-warning-default{background-color:#cca45f}.bgc-black{background-color:#000}.bgc-dark{background-color:#888}.bgc-medium{background-color:#e0e0e0}.bgc-grey{background-color:#ededed}.bgc-light{background-color:#f6f6f6}.bgc-white{background-color:#fff}.bgc-box-shadow{background-color:#00000014}.bgc-navigation-subtitle{background-color:#528593}:host{width:320px;display:block}:host.full-width{width:100%}:host ui-tag{height:32px;margin:4px}:host ui-tag ::ng-deep .tag-container{margin:0!important}:host ui-tag ::ng-deep .tag-wrapper{max-width:fit-content}.large-size input{margin:10px 0}.large-size .selected-items{margin:5px 0;flex-wrap:wrap;--tag-max-width: calc(100% - 8px) }.large-size .selected-items .value-tag ::ng-deep .tag-container{max-width:100%!important}.large-size .input-container{margin:auto 0;width:calc(100% - 25px);display:flex;flex-direction:column-reverse}.large-size .input-container.has-multiple-selections{width:calc(100% - 50px)}.large-size .input-container.autocomplete-variant{width:100%}.large-size .input-container.autocomplete-variant.has-multiple-selections{width:calc(100% - 26px)}.large-size ::ng-deep .mat-mdc-form-field-infix,.large-size .mat-mdc-form-field-flex{align-items:unset!important}.disabled *{pointer-events:none}.input-container{width:100%;margin:auto;display:flex;flex-direction:row-reverse}.input-container .selected-items{display:flex;padding-left:4px;visibility:hidden}.input-container .selected-items.measured{visibility:visible}.input-container .selected-items .value-tag{max-width:var(--tag-max-width, fit-content)}.input-container .selected-items .value-tag ::ng-deep .tag-container{max-width:var(--tag-max-width, fit-content)}.input-container .selected-items .selected-count{white-space:nowrap}.input-container .selected-items.measurement-container{visibility:hidden;position:absolute;height:0;overflow:hidden;pointer-events:none}.input-container .overlap-count{font-size:14px;line-height:20px}.input-container .overlap-count ui-tag{display:block}.input-container input{margin-left:6px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.input-container input.unset-margin{margin-top:unset}.input-container input.no-caret{cursor:pointer;caret-color:transparent!important}.add-suggestion{margin:0 5px;color:#000;font-weight:700}.remove-selected{cursor:pointer;margin-right:2px;border-radius:50px;height:fit-content}.remove-selected.large-input-icon{margin-top:10px}.arrow-state{height:24px;cursor:pointer}.arrow-state.large-input-icon{margin-top:10px}.arrow-state.opened{transform:rotateX(180deg)}::ng-deep .autocomplete-wrapper .mat-mdc-form-field{width:100%}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error,::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error svg{color:#cb7b7a}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error{display:flex}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error{display:flex;flex-flow:column;row-gap:4px}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error .errors ui-icon{margin-right:8px}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error .errors{display:flex}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error{color:#e02800!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error svg{color:#e02800!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-bottom-align:before{height:0}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint-wrapper{padding:0 0 12px;font-size:12px;line-height:16px;position:relative}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint-wrapper .mat-form-field-hint-spacer{display:none}::ng-deep .autocomplete-wrapper .mat-mdc-form-field.hide-bottom-content .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-text-field-wrapper.mdc-text-field--outlined .mdc-notched-outline--upgraded .mdc-floating-label--float-above{top:28px!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-floating-label{top:22px!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-text-field-wrapper{padding-left:12px!important;height:unset!important;max-height:unset!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-focused .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-floating-label{color:#276678!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mdc-text-field--outlined:not(.mdc-text-field--disabled).mdc-text-field--focused .mdc-notched-outline__notch{border-bottom:2px solid #276678!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mdc-text-field--outlined:not(.mdc-text-field--disabled).mdc-text-field--focused .mdc-notched-outline__leading{border-left:2px solid #276678!important;border-bottom:2px solid #276678!important;border-top:2px solid #276678!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mdc-text-field--outlined:not(.mdc-text-field--disabled).mdc-text-field--focused .mdc-notched-outline__trailing{border:2px solid #276678!important;border-left:unset!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-infix,::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-flex{min-height:48px!important;max-height:184px!important;overflow-y:auto;overflow-x:hidden;padding:0!important;display:flex;justify-content:center;text-align:center;align-items:center;flex-direction:row;width:100%}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mdc-line-ripple{display:none!important}::ng-deep .mat-mdc-autocomplete-panel{box-shadow:0 8px 24px 4px #00000014;max-height:312px!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option:hover:not(.mdc-list-item--disabled),::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option:focus:not(.mdc-list-item--disabled),::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.mat-mdc-option-active,::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.mdc-list-item--selected:not(.mat-mdc-option-multiple):not(.mdc-list-item--disabled){background:#e9f0f1!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option{padding-right:32px;padding-left:12px!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .option-image{width:24px;height:24px;margin-right:8px;object-fit:cover;flex-shrink:0}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option ui-icon{display:none;position:absolute;right:0;bottom:calc(50% - 8px);margin:0 10px}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.selected-option{background:#e9f0f1}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.selected-option ui-icon{display:block}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.mdc-list-item--selected .mdc-list-item__primary-text,::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .mdc-list-item--activated .mdc-list-item__primary-text{color:#000!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .mdc-list-item__primary-text{display:flex;align-items:center}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .mat-pseudo-checkbox{display:none}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-optgroup .mat-mdc-optgroup-label{font-weight:700!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-optgroup .mat-mdc-optgroup-label .mdc-list-item__primary-text{color:#000;font-size:12px;line-height:16px;font-weight:700}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-optgroup .mat-mdc-option{padding-left:16px!important}.active-field .mdc-notched-outline__leading{border-left-width:2px;border-top-width:2px;border-bottom-width:2px}.active-field .mdc-notched-outline__notch{border-top-width:2px;border-bottom-width:2px}.active-field .mdc-notched-outline__trailing{border-top-width:2px;border-bottom-width:2px;border-right-width:2px}.loading-option{display:flex}.loading-option .loading-container{display:flex;justify-content:center;align-items:center;width:100%;height:100%;position:absolute;top:0;left:0}.selected-items--below{display:flex;flex-wrap:wrap;align-items:center;gap:4px;margin-top:8px}.selected-items--below ui-tag{margin:0;--ui-tag-max-width: 400px}.selected-items--below .clear-all{background:none;border:none;padding:4px 8px;cursor:pointer;color:#000;font-weight:500;font-size:12px;line-height:16px;text-decoration:underline}.selected-items--below .clear-all:disabled{cursor:not-allowed;opacity:.5}\n"] }]
934
- }], ctorParameters: () => [], propDecorators: { itemsList: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemsList", required: false }] }], suggestionsList: [{ type: i0.Input, args: [{ isSignal: true, alias: "suggestionsList", required: false }] }], groupsList: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupsList", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], allowAdd: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowAdd", required: false }] }], textField: [{ type: i0.Input, args: [{ isSignal: true, alias: "textField", required: false }] }], valueField: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueField", required: false }] }], imageField: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageField", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], testId: [{ type: i0.Input, args: [{ isSignal: true, alias: "testId", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], minCharactersSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "minCharactersSearch", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: true }] }], showBottomContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "showBottomContent", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], virtualScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualScroll", required: false }] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "compareWith", required: false }] }], dropdownPanelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropdownPanelClass", required: false }] }], panelPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelPosition", required: false }] }], hideSelectedSection: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideSelectedSection", required: false }] }], userAdditionsGroupLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "userAdditionsGroupLabel", required: false }] }], closeOnScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnScroll", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], allowUserInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowUserInput", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], dynamicFilterLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "dynamicFilterLoading", required: false }] }], dynamicFilteredList: [{ type: i0.Input, args: [{ isSignal: true, alias: "dynamicFilteredList", required: false }] }], infiniteScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "infiniteScroll", required: false }] }], hasMoreOptionsForInfiniteScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasMoreOptionsForInfiniteScroll", required: false }] }], itemValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemValue", required: false }] }], formErrorConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "formErrorConfig", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], addOptionPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "addOptionPosition", required: false }] }], tagsPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "tagsPosition", required: false }] }], tagIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "tagIcon", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], searchTextChange: [{ type: i0.Output, args: ["searchTextChange"] }], blur: [{ type: i0.Output, args: ["blur"] }], focus: [{ type: i0.Output, args: ["focus"] }], scrollViewportBottomReached: [{ type: i0.Output, args: ["scrollViewportBottomReached"] }], scrollViewportBottomReachedFiltered: [{ type: i0.Output, args: ["scrollViewportBottomReachedFiltered"] }], formFieldElement: [{
935
- type: ViewChild,
936
- args: ['formField']
937
- }], tagContainer: [{
938
- type: ViewChild,
939
- args: ['tagContainer']
940
- }], measureElRef: [{
941
- type: ViewChild,
942
- args: ['measureEl']
943
- }], overflowDir: [{
944
- type: ViewChild,
945
- args: ['overflow']
946
- }], autocomplete: [{
947
- type: ViewChild,
948
- args: ['trigger']
949
- }], cdkViewport: [{
950
- type: ViewChild,
951
- args: [CdkVirtualScrollViewport, { static: false }]
952
- }], matAutocomplete: [{
953
- type: ViewChild,
954
- args: ['autocomplete']
955
- }], matInput: [{
956
- type: ViewChild,
957
- args: ['matInput']
958
- }], tagSuffix: [{ type: i0.ContentChild, args: [i0.forwardRef(() => AutocompleteTagSuffixDirective), { isSignal: true }] }] } });
959
-
960
- /**
961
- * Generated bundle index. Do not edit.
962
- */
963
-
348
+ var AutocompleteValueManager = class AutocompleteValueManager {
349
+ constructor() {
350
+ this.type = signal("multi", ...ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []);
351
+ this.textField = signal("", ...ngDevMode ? [{ debugName: "textField" }] : /* istanbul ignore next */ []);
352
+ this.valueField = signal("", ...ngDevMode ? [{ debugName: "valueField" }] : /* istanbul ignore next */ []);
353
+ this.compareWith = signal(void 0, ...ngDevMode ? [{ debugName: "compareWith" }] : /* istanbul ignore next */ []);
354
+ this.value = signal(null, ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
355
+ this.isSingle = computed(() => this.type() === Autocomplete.SINGLE, ...ngDevMode ? [{ debugName: "isSingle" }] : /* istanbul ignore next */ []);
356
+ this.displayValue = computed(() => {
357
+ const type = this.type();
358
+ const value = this.value();
359
+ const textField = this.textField();
360
+ const isSingle = type === Autocomplete.SINGLE;
361
+ if (!value || AutocompleteV2Utils.isArray(value) && !value.length) return "";
362
+ if (isSingle) {
363
+ const display = AutocompleteV2Utils.isArray(value) ? value[0] : value;
364
+ return AutocompleteV2Utils.transformDisplayValue(display, textField);
365
+ }
366
+ return " ";
367
+ }, ...ngDevMode ? [{ debugName: "displayValue" }] : /* istanbul ignore next */ []);
368
+ this.onChangeFn = () => {};
369
+ this.onTouchedFn = () => {};
370
+ }
371
+ registerOnChange(fn) {
372
+ this.onChangeFn = fn;
373
+ }
374
+ registerOnTouched(fn) {
375
+ this.onTouchedFn = fn;
376
+ }
377
+ notifyChange() {
378
+ this.onChangeFn(this.value());
379
+ }
380
+ markAsTouched() {
381
+ this.onTouchedFn();
382
+ }
383
+ writeValue(v) {
384
+ if (v === null || v === void 0) this.value.set(this.isSingle() ? null : []);
385
+ else this.value.set(v);
386
+ }
387
+ addValue(newValue) {
388
+ if (!this.isSingle() && !this.value()) this.value.set([]);
389
+ const compareWith = this.compareWith();
390
+ const currentArray = AutocompleteV2Utils.isArray(this.value()) ? this.value() : [];
391
+ const foundDuplicate = compareWith ? currentArray.find((v) => compareWith(v, newValue)) : AutocompleteV2Utils.findDuplicate(currentArray, newValue, this.textField());
392
+ if (!this.isSingle()) this.value.set(foundDuplicate ? currentArray.filter((v) => compareWith ? !compareWith(v, foundDuplicate) : v !== foundDuplicate) : [...currentArray, newValue]);
393
+ else this.value.set(newValue);
394
+ }
395
+ removeValue(option) {
396
+ const compareWith = this.compareWith();
397
+ const currentValue = AutocompleteV2Utils.isArray(this.value()) ? this.value() : [];
398
+ const foundValue = currentValue.find((v) => compareWith ? compareWith(v, option) : v === option);
399
+ if (foundValue) this.value.set(currentValue.filter((v) => compareWith ? !compareWith(v, option) : v !== option));
400
+ return foundValue;
401
+ }
402
+ clear() {
403
+ this.value.set(AutocompleteV2Utils.isArray(this.value()) ? [] : null);
404
+ }
405
+ static {
406
+ this.ɵfac = i0.ɵɵngDeclareFactory({
407
+ minVersion: "12.0.0",
408
+ version: "22.2.4",
409
+ ngImport: i0,
410
+ type: AutocompleteValueManager,
411
+ deps: [],
412
+ target: i0.ɵɵFactoryTarget.Injectable
413
+ });
414
+ }
415
+ static {
416
+ this.ɵprov = i0.ɵɵngDeclareInjectable({
417
+ minVersion: "12.0.0",
418
+ version: "22.2.4",
419
+ ngImport: i0,
420
+ type: AutocompleteValueManager
421
+ });
422
+ }
423
+ };
424
+ i0.ɵɵngDeclareClassMetadata({
425
+ minVersion: "12.0.0",
426
+ version: "22.2.4",
427
+ ngImport: i0,
428
+ type: AutocompleteValueManager,
429
+ decorators: [{ type: Injectable }]
430
+ });
431
+ var InfiniteScrollDirective = class InfiniteScrollDirective {
432
+ constructor() {
433
+ this.viewport = null;
434
+ this.scrollSub = null;
435
+ this.destroyRef = inject(DestroyRef);
436
+ this.scrollListener = (event) => {
437
+ const target = event.target;
438
+ const trigger = this.panelTrigger;
439
+ if (!trigger) return;
440
+ const isNotAutocompleteScroll = !target?.id?.includes("mat-autocomplete-") && !target?.parentElement?.id?.includes("mat-autocomplete-") && !target?.classList?.contains("mat-mdc-autocomplete-trigger");
441
+ if (trigger.panelOpen && isNotAutocompleteScroll) trigger.closePanel();
442
+ };
443
+ this.enabled = false;
444
+ this.closeOnScroll = false;
445
+ this.panelTrigger = null;
446
+ this.onBottomReached = null;
447
+ }
448
+ attachViewport(viewport) {
449
+ this.detachViewport();
450
+ if (!viewport) return;
451
+ this.viewport = viewport;
452
+ if (this.enabled) this.scrollSub = viewport.elementScrolled().pipe(map(() => viewport.measureScrollOffset("bottom")), filter((offset) => offset < viewport.getViewportSize() * .2), throttleTime(200), takeUntilDestroyed(this.destroyRef)).subscribe(() => {
453
+ this.onBottomReached?.();
454
+ });
455
+ }
456
+ detachViewport() {
457
+ this.scrollSub?.unsubscribe();
458
+ this.scrollSub = null;
459
+ this.viewport = null;
460
+ }
461
+ scrollToTop() {
462
+ if (this.viewport) {
463
+ this.viewport.scrollToIndex(0);
464
+ this.viewport.checkViewportSize();
465
+ }
466
+ }
467
+ startCloseOnScroll() {
468
+ if (this.closeOnScroll) window.addEventListener("scroll", this.scrollListener, true);
469
+ }
470
+ ngOnDestroy() {
471
+ this.detachViewport();
472
+ window.removeEventListener("scroll", this.scrollListener, true);
473
+ }
474
+ static {
475
+ this.ɵfac = i0.ɵɵngDeclareFactory({
476
+ minVersion: "12.0.0",
477
+ version: "22.2.4",
478
+ ngImport: i0,
479
+ type: InfiniteScrollDirective,
480
+ deps: [],
481
+ target: i0.ɵɵFactoryTarget.Injectable
482
+ });
483
+ }
484
+ static {
485
+ this.ɵprov = i0.ɵɵngDeclareInjectable({
486
+ minVersion: "12.0.0",
487
+ version: "22.2.4",
488
+ ngImport: i0,
489
+ type: InfiniteScrollDirective
490
+ });
491
+ }
492
+ };
493
+ i0.ɵɵngDeclareClassMetadata({
494
+ minVersion: "12.0.0",
495
+ version: "22.2.4",
496
+ ngImport: i0,
497
+ type: InfiniteScrollDirective,
498
+ decorators: [{ type: Injectable }]
499
+ });
500
+ var AutocompleteV2Component = class AutocompleteV2Component {
501
+ set cdkViewport(viewport) {
502
+ this.scrollManager.enabled = this.infiniteScroll();
503
+ this.scrollManager.attachViewport(viewport);
504
+ }
505
+ constructor() {
506
+ this.itemsList = input([], ...ngDevMode ? [{ debugName: "itemsList" }] : /* istanbul ignore next */ []);
507
+ this.suggestionsList = input([], ...ngDevMode ? [{ debugName: "suggestionsList" }] : /* istanbul ignore next */ []);
508
+ this.groupsList = input([], ...ngDevMode ? [{ debugName: "groupsList" }] : /* istanbul ignore next */ []);
509
+ this.disabled = input(false, ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
510
+ this.allowAdd = input(true, ...ngDevMode ? [{ debugName: "allowAdd" }] : /* istanbul ignore next */ []);
511
+ this.textField = input("", ...ngDevMode ? [{ debugName: "textField" }] : /* istanbul ignore next */ []);
512
+ this.valueField = input("", ...ngDevMode ? [{ debugName: "valueField" }] : /* istanbul ignore next */ []);
513
+ this.imageField = input("", ...ngDevMode ? [{ debugName: "imageField" }] : /* istanbul ignore next */ []);
514
+ this.label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
515
+ this.placeholder = input("", ...ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []);
516
+ this.testId = input(null, ...ngDevMode ? [{ debugName: "testId" }] : /* istanbul ignore next */ []);
517
+ this.type = input("multi", ...ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []);
518
+ this.minCharactersSearch = input(3, ...ngDevMode ? [{ debugName: "minCharactersSearch" }] : /* istanbul ignore next */ []);
519
+ this.variant = input.required(...ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []);
520
+ this.showBottomContent = input(true, ...ngDevMode ? [{ debugName: "showBottomContent" }] : /* istanbul ignore next */ []);
521
+ this.required = input(void 0, ...ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []);
522
+ this.virtualScroll = input(false, {
523
+ ...ngDevMode ? { debugName: "virtualScroll" } : /* istanbul ignore next */ {},
524
+ transform: booleanAttribute
525
+ });
526
+ this.compareWith = input(void 0, ...ngDevMode ? [{ debugName: "compareWith" }] : /* istanbul ignore next */ []);
527
+ this.dropdownPanelClass = input("", ...ngDevMode ? [{ debugName: "dropdownPanelClass" }] : /* istanbul ignore next */ []);
528
+ this.panelPosition = input("auto", ...ngDevMode ? [{ debugName: "panelPosition" }] : /* istanbul ignore next */ []);
529
+ this.hideSelectedSection = input(false, {
530
+ ...ngDevMode ? { debugName: "hideSelectedSection" } : /* istanbul ignore next */ {},
531
+ transform: booleanAttribute
532
+ });
533
+ this.userAdditionsGroupLabel = input("", ...ngDevMode ? [{ debugName: "userAdditionsGroupLabel" }] : /* istanbul ignore next */ []);
534
+ this.closeOnScroll = input(false, ...ngDevMode ? [{ debugName: "closeOnScroll" }] : /* istanbul ignore next */ []);
535
+ this.size = input("medium", ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
536
+ this.allowUserInput = input(true, ...ngDevMode ? [{ debugName: "allowUserInput" }] : /* istanbul ignore next */ []);
537
+ this.clearable = input(true, ...ngDevMode ? [{ debugName: "clearable" }] : /* istanbul ignore next */ []);
538
+ this.maxLength = input(void 0, ...ngDevMode ? [{ debugName: "maxLength" }] : /* istanbul ignore next */ []);
539
+ this.dynamicFilterLoading = input(false, ...ngDevMode ? [{ debugName: "dynamicFilterLoading" }] : /* istanbul ignore next */ []);
540
+ this.dynamicFilteredList = input(null, ...ngDevMode ? [{ debugName: "dynamicFilteredList" }] : /* istanbul ignore next */ []);
541
+ this.infiniteScroll = input(false, ...ngDevMode ? [{ debugName: "infiniteScroll" }] : /* istanbul ignore next */ []);
542
+ this.hasMoreOptionsForInfiniteScroll = input(true, ...ngDevMode ? [{ debugName: "hasMoreOptionsForInfiniteScroll" }] : /* istanbul ignore next */ []);
543
+ this.itemValue = input(null, ...ngDevMode ? [{ debugName: "itemValue" }] : /* istanbul ignore next */ []);
544
+ this.formErrorConfig = input({}, ...ngDevMode ? [{ debugName: "formErrorConfig" }] : /* istanbul ignore next */ []);
545
+ this.errors = input([], ...ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []);
546
+ this.addOptionPosition = input("bottom", ...ngDevMode ? [{ debugName: "addOptionPosition" }] : /* istanbul ignore next */ []);
547
+ this.tagsPosition = input("inside", ...ngDevMode ? [{ debugName: "tagsPosition" }] : /* istanbul ignore next */ []);
548
+ this.tagIcon = input("", ...ngDevMode ? [{ debugName: "tagIcon" }] : /* istanbul ignore next */ []);
549
+ this.selectionChange = output();
550
+ this.searchTextChange = output();
551
+ this.blur = output();
552
+ this.focus = output();
553
+ this.scrollViewportBottomReached = output();
554
+ this.scrollViewportBottomReachedFiltered = output();
555
+ this.tagSuffix = contentChild(AutocompleteTagSuffixDirective, ...ngDevMode ? [{ debugName: "tagSuffix" }] : /* istanbul ignore next */ []);
556
+ this.valueManager = inject(AutocompleteValueManager);
557
+ this.filterService = inject(AutocompleteFilterService);
558
+ this.scrollManager = inject(InfiniteScrollDirective);
559
+ this.cdr = inject(ChangeDetectorRef);
560
+ this.focusMonitor = inject(FocusMonitor);
561
+ this.destroyRef = inject(DestroyRef);
562
+ this.ngZone = inject(NgZone);
563
+ this.ngControl = inject(NgControl, {
564
+ optional: true,
565
+ self: true
566
+ });
567
+ this.applicationTheme = inject("CANOPYUI_DEFAULT_APPLICATION_THEME", { optional: true }) ?? "light";
568
+ this.inputValue = signal("", ...ngDevMode ? [{ debugName: "inputValue" }] : /* istanbul ignore next */ []);
569
+ this.isInputFocus = signal(false, ...ngDevMode ? [{ debugName: "isInputFocus" }] : /* istanbul ignore next */ []);
570
+ this.autocompleteType = Autocomplete;
571
+ this.flatItemsList = computed(() => {
572
+ const suggestions = this.suggestionsList();
573
+ const valField = this.valueField();
574
+ const flat = AutocompleteV2Utils.excludeSuggestions(this.itemsList(), suggestions, valField);
575
+ const grouped = this.groupsList().flatMap((g) => AutocompleteV2Utils.excludeSuggestions(g.items, suggestions, valField));
576
+ return [...flat, ...grouped];
577
+ }, ...ngDevMode ? [{ debugName: "flatItemsList" }] : /* istanbul ignore next */ []);
578
+ this.groupedItemsList = computed(() => {
579
+ const suggestions = this.suggestionsList();
580
+ const valField = this.valueField();
581
+ return this.groupsList().map((group) => ({
582
+ groupName: group.groupName,
583
+ items: AutocompleteV2Utils.excludeSuggestions(group.items, suggestions, valField)
584
+ }));
585
+ }, ...ngDevMode ? [{ debugName: "groupedItemsList" }] : /* istanbul ignore next */ []);
586
+ this._isDisabled = signal(false, ...ngDevMode ? [{ debugName: "_isDisabled" }] : /* istanbul ignore next */ []);
587
+ this.userAddedItems = signal([], ...ngDevMode ? [{ debugName: "userAddedItems" }] : /* istanbul ignore next */ []);
588
+ this.translationContext = "AUTOCOMPLETE.";
589
+ this.utils = AutocompleteV2Utils;
590
+ this.keyboardFocused = signal(false, ...ngDevMode ? [{ debugName: "keyboardFocused" }] : /* istanbul ignore next */ []);
591
+ this.isAlreadyAdded = computed(() => {
592
+ const compareWith = this.compareWith();
593
+ const val = this.valueManager.value();
594
+ const inputVal = this.inputValue();
595
+ if (!inputVal || inputVal === " ") return false;
596
+ const valArray = AutocompleteV2Utils.isArray(val) ? val : [];
597
+ return Boolean(compareWith ? valArray.find((v) => compareWith(v, inputVal)) : AutocompleteV2Utils.findDuplicate(valArray, inputVal, this.textField()));
598
+ }, ...ngDevMode ? [{ debugName: "isAlreadyAdded" }] : /* istanbul ignore next */ []);
599
+ this.tagsBelow = computed(() => this.tagsPosition() === "below" && this.type() === Autocomplete.MULTI, ...ngDevMode ? [{ debugName: "tagsBelow" }] : /* istanbul ignore next */ []);
600
+ this.suppressPlaceholder = computed(() => !this.tagsBelow() && Boolean(this.valueManager.value()?.length), ...ngDevMode ? [{ debugName: "suppressPlaceholder" }] : /* istanbul ignore next */ []);
601
+ this.showClearButton = computed(() => {
602
+ if (this.tagsBelow()) return false;
603
+ const type = this.type();
604
+ const val = this.valueManager.value();
605
+ if (type === Autocomplete.SINGLE) {
606
+ const hasValue = Array.isArray(val) ? val.length > 0 : val ? Object.keys(val).length > 0 : false;
607
+ return this.clearable() && hasValue;
608
+ }
609
+ return Array.isArray(val) && val.length > 1;
610
+ }, ...ngDevMode ? [{ debugName: "showClearButton" }] : /* istanbul ignore next */ []);
611
+ this.tagIcons = computed(() => {
612
+ const icon = this.tagIcon();
613
+ const value = this.valueManager.value();
614
+ if (!AutocompleteV2Utils.isArray(value)) return [];
615
+ return value.map((item) => typeof icon === "function" ? icon(item) : icon);
616
+ }, ...ngDevMode ? [{ debugName: "tagIcons" }] : /* istanbul ignore next */ []);
617
+ this.safeErrors = computed(() => this.errors()?.filter(Boolean) ?? [], ...ngDevMode ? [{ debugName: "safeErrors" }] : /* istanbul ignore next */ []);
618
+ this.controlInvalid = signal(false, ...ngDevMode ? [{ debugName: "controlInvalid" }] : /* istanbul ignore next */ []);
619
+ this.hasError = computed(() => {
620
+ if (this.ngControl) return this.controlInvalid();
621
+ return this.safeErrors().length > 0;
622
+ }, ...ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []);
623
+ this.hiddenItemsTooltip = computed(() => {
624
+ const value = this.valueManager.value();
625
+ const visibleCount = this.overflowDir?.visibleCount() ?? Infinity;
626
+ if (!AutocompleteV2Utils.isArray(value)) return "";
627
+ const tf = this.textField();
628
+ return value.slice(visibleCount).map((item) => tf ? item[tf] : item).join("\n");
629
+ }, ...ngDevMode ? [{ debugName: "hiddenItemsTooltip" }] : /* istanbul ignore next */ []);
630
+ this.trackByFn = (index, value) => value;
631
+ this.trackByItem = (_index, item) => {
632
+ const vf = this.valueField();
633
+ return vf ? item?.[vf] : item;
634
+ };
635
+ if (this.ngControl) this.ngControl.valueAccessor = this;
636
+ effect(() => {
637
+ this.filterService.setDynamicResults(this.dynamicFilteredList(), this.dynamicFilterLoading());
638
+ });
639
+ effect(() => {
640
+ const disabled = this.disabled();
641
+ if (this.ngControl) {
642
+ if (isDevMode() && disabled) console.warn("[ui-autocomplete-v2] [disabled] is set alongside a form control. Use the form control disabled state (disable()/enable()) instead.");
643
+ return;
644
+ }
645
+ this._isDisabled.set(disabled);
646
+ });
647
+ effect(() => this.valueManager.type.set(this.type()));
648
+ effect(() => this.valueManager.textField.set(this.textField()));
649
+ effect(() => this.valueManager.valueField.set(this.valueField()));
650
+ effect(() => this.valueManager.compareWith.set(this.compareWith()));
651
+ effect(() => this.filterService.textField.set(this.textField()));
652
+ effect(() => this.filterService.flatItems.set(this.flatItemsList()));
653
+ effect(() => this.filterService.groupsList.set(this.groupsList()));
654
+ effect(() => this.filterService.suggestions.set(this.suggestionsList()));
655
+ effect(() => {
656
+ const v = this.itemValue();
657
+ if (this.ngControl) {
658
+ if (isDevMode() && v !== null) console.warn("[ui-autocomplete-v2] [itemValue] is set alongside a form control. Use ngModel or formControl instead.");
659
+ return;
660
+ }
661
+ this.valueManager.value.set(AutocompleteV2Utils.isArray(v) ? v : v ? [v] : []);
662
+ untracked(() => {
663
+ if (!this.tagsBelow()) this.inputValue.set(this.valueManager.displayValue());
664
+ });
665
+ this.cdr.markForCheck();
666
+ });
667
+ effect(() => {
668
+ this.valueManager.value();
669
+ untracked(() => {
670
+ if (this.type() !== Autocomplete.LARGE) this.overflowDir?.measure();
671
+ });
672
+ });
673
+ }
674
+ ngDoCheck() {
675
+ if (this.ngControl) {
676
+ const invalid = Boolean(this.ngControl.invalid && this.ngControl.touched);
677
+ if (this.controlInvalid() !== invalid) this.controlInvalid.set(invalid);
678
+ if (this.ngControl.touched || this.ngControl.errors) this.cdr.markForCheck();
679
+ }
680
+ }
681
+ ngAfterViewInit() {
682
+ if (!document.body.style.getPropertyValue("--ui-autocomplete-option-color")) document.body.style.setProperty("--ui-autocomplete-option-color", "#FFF2FC");
683
+ if (this.type() !== Autocomplete.LARGE) this.overflowDir?.setupObserver(".input-container");
684
+ this.scrollManager.enabled = this.infiniteScroll();
685
+ this.scrollManager.closeOnScroll = this.closeOnScroll();
686
+ this.scrollManager.panelTrigger = this.autocomplete;
687
+ this.scrollManager.onBottomReached = () => this.onScrollBottom();
688
+ this.scrollManager.startCloseOnScroll();
689
+ this.focusMonitor.monitor(this.matInput).pipe(takeUntilDestroyed(this.destroyRef)).subscribe((origin) => this.ngZone.run(() => {
690
+ this.keyboardFocused.set(origin === "keyboard");
691
+ }));
692
+ this.matInput.nativeElement.onkeydown = this.onKeydown.bind(this);
693
+ }
694
+ ngOnDestroy() {
695
+ this.scrollManager.ngOnDestroy();
696
+ this.focusMonitor.stopMonitoring(this.matInput);
697
+ if (this.matInput?.nativeElement) this.matInput.nativeElement.onkeydown = null;
698
+ }
699
+ registerOnChange(fn) {
700
+ this.valueManager.registerOnChange(fn);
701
+ }
702
+ registerOnTouched(fn) {
703
+ this.valueManager.registerOnTouched(fn);
704
+ }
705
+ setDisabledState(isDisabled) {
706
+ this._isDisabled.set(isDisabled);
707
+ this.cdr.markForCheck();
708
+ }
709
+ writeValue(value) {
710
+ this.valueManager.type.set(this.type());
711
+ this.valueManager.textField.set(this.textField());
712
+ this.valueManager.valueField.set(this.valueField());
713
+ this.valueManager.compareWith.set(this.compareWith());
714
+ this.valueManager.writeValue(value);
715
+ if (this.userAdditionsGroupLabel()) this.userAddedItems.update((items) => {
716
+ const v = this.valueManager.value();
717
+ if (!AutocompleteV2Utils.isArray(v) || v.length === 0) return [];
718
+ const vf = this.valueField();
719
+ const tf = this.textField();
720
+ return items.filter((i) => v.some((x) => vf ? x[vf] === i[vf] : tf ? x[tf] === i[tf] : x === i));
721
+ });
722
+ this.inputValue.set(this.tagsBelow() ? "" : this.valueManager.displayValue());
723
+ this.cdr.markForCheck();
724
+ }
725
+ get isGrouped() {
726
+ return this.groupsList().length > 0;
727
+ }
728
+ onOptionSelected(event) {
729
+ const inputValue = event.option.value;
730
+ const itemValue = AutocompleteV2Utils.createValueItem(inputValue, this.textField(), this.valueField());
731
+ const lengthBefore = AutocompleteV2Utils.isArray(this.valueManager.value()) ? this.valueManager.value().length : 0;
732
+ this.valueManager.addValue(itemValue);
733
+ if ((AutocompleteV2Utils.isArray(this.valueManager.value()) ? this.valueManager.value().length : 0) > lengthBefore && typeof event.option.value === "string" && this.userAdditionsGroupLabel()) {
734
+ const vf = this.valueField();
735
+ const tf = this.textField();
736
+ if (!(vf ? this.userAddedItems().some((i) => i[vf] === itemValue[vf]) : tf ? this.userAddedItems().some((i) => i[tf] === itemValue[tf]) : this.userAddedItems().some((i) => i === itemValue))) this.userAddedItems.update((items) => [...items, itemValue]);
737
+ }
738
+ queueMicrotask(() => {
739
+ if (this.type() !== this.autocompleteType.SINGLE) this.inputValue.set("");
740
+ else this.inputValue.set(this.valueManager.displayValue());
741
+ this.cdr.markForCheck();
742
+ });
743
+ this.onUpdate();
744
+ this.valueManager.markAsTouched();
745
+ }
746
+ onOptionRemoved(option) {
747
+ setTimeout(() => this.autocomplete.closePanel(), 0);
748
+ const foundValue = this.valueManager.removeValue(option);
749
+ if (foundValue) this.matAutocomplete.options.forEach((matOption) => {
750
+ const vf = this.valueField();
751
+ if (vf && matOption.value?.[vf] === foundValue[vf]) matOption.deselect();
752
+ });
753
+ if (this.userAdditionsGroupLabel()) {
754
+ const vf = this.valueField();
755
+ this.userAddedItems.update((items) => items.filter((item) => vf ? item[vf] !== option[vf] : item !== option));
756
+ }
757
+ if (!this.valueManager.value()?.length) this.inputValue.set("");
758
+ this.onUpdate();
759
+ this.valueManager.markAsTouched();
760
+ }
761
+ onTagActivate(event) {
762
+ const target = event.target;
763
+ if (this._isDisabled() || target.closest(".delete-icon")) return;
764
+ if (event instanceof KeyboardEvent && !target.classList.contains("tag-container")) return;
765
+ const control = event.currentTarget.querySelector(".tag-suffix button, .tag-suffix [role=\"button\"], .tag-suffix a[href]");
766
+ if (control) {
767
+ event.preventDefault();
768
+ control.click();
769
+ }
770
+ }
771
+ onInputChange(event) {
772
+ const text = event.target.value;
773
+ this.filterService.search(text, this.minCharactersSearch());
774
+ if (text.length >= this.minCharactersSearch()) this.searchTextChange.emit(text);
775
+ }
776
+ onClear() {
777
+ this.inputValue.set("");
778
+ this.valueManager.clear();
779
+ this.userAddedItems.set([]);
780
+ this.onUpdate();
781
+ this.matAutocomplete?.options.forEach((option) => option.deselect());
782
+ this.valueManager.markAsTouched();
783
+ }
784
+ onBlur() {
785
+ setTimeout(() => {
786
+ this.filterService.clearSearch();
787
+ this.isInputFocus.set(false);
788
+ this.inputValue.set(this.tagsBelow() ? "" : this.valueManager.displayValue());
789
+ this.valueManager.markAsTouched();
790
+ this.blur.emit();
791
+ this.cdr.markForCheck();
792
+ }, 0);
793
+ }
794
+ onPanelOpened() {
795
+ this.scrollManager.scrollToTop();
796
+ }
797
+ onScrollBottom() {
798
+ if (this.filterService.searchText$.value) this.scrollViewportBottomReachedFiltered.emit();
799
+ else this.scrollViewportBottomReached.emit();
800
+ }
801
+ onFocus() {
802
+ this.isInputFocus.set(true);
803
+ const val = this.inputValue();
804
+ if (typeof val === "string" && val.match(/^\s+/gm)) this.inputValue.set(val.trimStart());
805
+ this.focus.emit();
806
+ }
807
+ onUpdate() {
808
+ this.filterService.clearSearch();
809
+ this.valueManager.notifyChange();
810
+ const val = this.valueManager.value();
811
+ if (val !== null) this.selectionChange.emit(val);
812
+ }
813
+ get isDropdown() {
814
+ return this.variant() === DropdownVariation.DROPDOWN;
815
+ }
816
+ onChevronClick(autocomplete) {
817
+ if (autocomplete.isOpen) setTimeout(() => {
818
+ this.autocomplete.closePanel();
819
+ }, 0);
820
+ }
821
+ onKeydown($event) {
822
+ const optionHeight = 48;
823
+ if ($event.key === IKeyboardEvent.HOME) this.matAutocomplete._keyManager.setFirstItemActive();
824
+ else if ($event.key === IKeyboardEvent.END) this.matAutocomplete._keyManager.setLastItemActive();
825
+ else if ($event.key === IKeyboardEvent.PAGE_DOWN) {
826
+ this.matAutocomplete._keyManager.setNextItemActive();
827
+ this.matAutocomplete._keyManager.setNextItemActive();
828
+ this.matAutocomplete._keyManager.setNextItemActive();
829
+ } else if ($event.key === IKeyboardEvent.PAGE_UP) {
830
+ this.matAutocomplete._keyManager.setPreviousItemActive();
831
+ this.matAutocomplete._keyManager.setPreviousItemActive();
832
+ this.matAutocomplete._keyManager.setPreviousItemActive();
833
+ }
834
+ this.matAutocomplete._setScrollTop((this.matAutocomplete._keyManager.activeItemIndex ?? 0) * optionHeight);
835
+ }
836
+ getVirtualScrollHeight(itemCount) {
837
+ const itemHeight = 48;
838
+ const maxHeight = 200;
839
+ const minHeight = 48;
840
+ const calculatedHeight = itemCount * itemHeight;
841
+ return Math.min(Math.max(calculatedHeight, minHeight), maxHeight);
842
+ }
843
+ static {
844
+ this.ɵfac = i0.ɵɵngDeclareFactory({
845
+ minVersion: "12.0.0",
846
+ version: "22.2.4",
847
+ ngImport: i0,
848
+ type: AutocompleteV2Component,
849
+ deps: [],
850
+ target: i0.ɵɵFactoryTarget.Component
851
+ });
852
+ }
853
+ static {
854
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
855
+ minVersion: "17.0.0",
856
+ version: "22.2.4",
857
+ type: AutocompleteV2Component,
858
+ isStandalone: true,
859
+ selector: "ui-autocomplete-v2",
860
+ inputs: {
861
+ itemsList: {
862
+ classPropertyName: "itemsList",
863
+ publicName: "itemsList",
864
+ isSignal: true,
865
+ isRequired: false,
866
+ transformFunction: null
867
+ },
868
+ suggestionsList: {
869
+ classPropertyName: "suggestionsList",
870
+ publicName: "suggestionsList",
871
+ isSignal: true,
872
+ isRequired: false,
873
+ transformFunction: null
874
+ },
875
+ groupsList: {
876
+ classPropertyName: "groupsList",
877
+ publicName: "groupsList",
878
+ isSignal: true,
879
+ isRequired: false,
880
+ transformFunction: null
881
+ },
882
+ disabled: {
883
+ classPropertyName: "disabled",
884
+ publicName: "disabled",
885
+ isSignal: true,
886
+ isRequired: false,
887
+ transformFunction: null
888
+ },
889
+ allowAdd: {
890
+ classPropertyName: "allowAdd",
891
+ publicName: "allowAdd",
892
+ isSignal: true,
893
+ isRequired: false,
894
+ transformFunction: null
895
+ },
896
+ textField: {
897
+ classPropertyName: "textField",
898
+ publicName: "textField",
899
+ isSignal: true,
900
+ isRequired: false,
901
+ transformFunction: null
902
+ },
903
+ valueField: {
904
+ classPropertyName: "valueField",
905
+ publicName: "valueField",
906
+ isSignal: true,
907
+ isRequired: false,
908
+ transformFunction: null
909
+ },
910
+ imageField: {
911
+ classPropertyName: "imageField",
912
+ publicName: "imageField",
913
+ isSignal: true,
914
+ isRequired: false,
915
+ transformFunction: null
916
+ },
917
+ label: {
918
+ classPropertyName: "label",
919
+ publicName: "label",
920
+ isSignal: true,
921
+ isRequired: false,
922
+ transformFunction: null
923
+ },
924
+ placeholder: {
925
+ classPropertyName: "placeholder",
926
+ publicName: "placeholder",
927
+ isSignal: true,
928
+ isRequired: false,
929
+ transformFunction: null
930
+ },
931
+ testId: {
932
+ classPropertyName: "testId",
933
+ publicName: "testId",
934
+ isSignal: true,
935
+ isRequired: false,
936
+ transformFunction: null
937
+ },
938
+ type: {
939
+ classPropertyName: "type",
940
+ publicName: "type",
941
+ isSignal: true,
942
+ isRequired: false,
943
+ transformFunction: null
944
+ },
945
+ minCharactersSearch: {
946
+ classPropertyName: "minCharactersSearch",
947
+ publicName: "minCharactersSearch",
948
+ isSignal: true,
949
+ isRequired: false,
950
+ transformFunction: null
951
+ },
952
+ variant: {
953
+ classPropertyName: "variant",
954
+ publicName: "variant",
955
+ isSignal: true,
956
+ isRequired: true,
957
+ transformFunction: null
958
+ },
959
+ showBottomContent: {
960
+ classPropertyName: "showBottomContent",
961
+ publicName: "showBottomContent",
962
+ isSignal: true,
963
+ isRequired: false,
964
+ transformFunction: null
965
+ },
966
+ required: {
967
+ classPropertyName: "required",
968
+ publicName: "required",
969
+ isSignal: true,
970
+ isRequired: false,
971
+ transformFunction: null
972
+ },
973
+ virtualScroll: {
974
+ classPropertyName: "virtualScroll",
975
+ publicName: "virtualScroll",
976
+ isSignal: true,
977
+ isRequired: false,
978
+ transformFunction: null
979
+ },
980
+ compareWith: {
981
+ classPropertyName: "compareWith",
982
+ publicName: "compareWith",
983
+ isSignal: true,
984
+ isRequired: false,
985
+ transformFunction: null
986
+ },
987
+ dropdownPanelClass: {
988
+ classPropertyName: "dropdownPanelClass",
989
+ publicName: "dropdownPanelClass",
990
+ isSignal: true,
991
+ isRequired: false,
992
+ transformFunction: null
993
+ },
994
+ panelPosition: {
995
+ classPropertyName: "panelPosition",
996
+ publicName: "panelPosition",
997
+ isSignal: true,
998
+ isRequired: false,
999
+ transformFunction: null
1000
+ },
1001
+ hideSelectedSection: {
1002
+ classPropertyName: "hideSelectedSection",
1003
+ publicName: "hideSelectedSection",
1004
+ isSignal: true,
1005
+ isRequired: false,
1006
+ transformFunction: null
1007
+ },
1008
+ userAdditionsGroupLabel: {
1009
+ classPropertyName: "userAdditionsGroupLabel",
1010
+ publicName: "userAdditionsGroupLabel",
1011
+ isSignal: true,
1012
+ isRequired: false,
1013
+ transformFunction: null
1014
+ },
1015
+ closeOnScroll: {
1016
+ classPropertyName: "closeOnScroll",
1017
+ publicName: "closeOnScroll",
1018
+ isSignal: true,
1019
+ isRequired: false,
1020
+ transformFunction: null
1021
+ },
1022
+ size: {
1023
+ classPropertyName: "size",
1024
+ publicName: "size",
1025
+ isSignal: true,
1026
+ isRequired: false,
1027
+ transformFunction: null
1028
+ },
1029
+ allowUserInput: {
1030
+ classPropertyName: "allowUserInput",
1031
+ publicName: "allowUserInput",
1032
+ isSignal: true,
1033
+ isRequired: false,
1034
+ transformFunction: null
1035
+ },
1036
+ clearable: {
1037
+ classPropertyName: "clearable",
1038
+ publicName: "clearable",
1039
+ isSignal: true,
1040
+ isRequired: false,
1041
+ transformFunction: null
1042
+ },
1043
+ maxLength: {
1044
+ classPropertyName: "maxLength",
1045
+ publicName: "maxLength",
1046
+ isSignal: true,
1047
+ isRequired: false,
1048
+ transformFunction: null
1049
+ },
1050
+ dynamicFilterLoading: {
1051
+ classPropertyName: "dynamicFilterLoading",
1052
+ publicName: "dynamicFilterLoading",
1053
+ isSignal: true,
1054
+ isRequired: false,
1055
+ transformFunction: null
1056
+ },
1057
+ dynamicFilteredList: {
1058
+ classPropertyName: "dynamicFilteredList",
1059
+ publicName: "dynamicFilteredList",
1060
+ isSignal: true,
1061
+ isRequired: false,
1062
+ transformFunction: null
1063
+ },
1064
+ infiniteScroll: {
1065
+ classPropertyName: "infiniteScroll",
1066
+ publicName: "infiniteScroll",
1067
+ isSignal: true,
1068
+ isRequired: false,
1069
+ transformFunction: null
1070
+ },
1071
+ hasMoreOptionsForInfiniteScroll: {
1072
+ classPropertyName: "hasMoreOptionsForInfiniteScroll",
1073
+ publicName: "hasMoreOptionsForInfiniteScroll",
1074
+ isSignal: true,
1075
+ isRequired: false,
1076
+ transformFunction: null
1077
+ },
1078
+ itemValue: {
1079
+ classPropertyName: "itemValue",
1080
+ publicName: "itemValue",
1081
+ isSignal: true,
1082
+ isRequired: false,
1083
+ transformFunction: null
1084
+ },
1085
+ formErrorConfig: {
1086
+ classPropertyName: "formErrorConfig",
1087
+ publicName: "formErrorConfig",
1088
+ isSignal: true,
1089
+ isRequired: false,
1090
+ transformFunction: null
1091
+ },
1092
+ errors: {
1093
+ classPropertyName: "errors",
1094
+ publicName: "errors",
1095
+ isSignal: true,
1096
+ isRequired: false,
1097
+ transformFunction: null
1098
+ },
1099
+ addOptionPosition: {
1100
+ classPropertyName: "addOptionPosition",
1101
+ publicName: "addOptionPosition",
1102
+ isSignal: true,
1103
+ isRequired: false,
1104
+ transformFunction: null
1105
+ },
1106
+ tagsPosition: {
1107
+ classPropertyName: "tagsPosition",
1108
+ publicName: "tagsPosition",
1109
+ isSignal: true,
1110
+ isRequired: false,
1111
+ transformFunction: null
1112
+ },
1113
+ tagIcon: {
1114
+ classPropertyName: "tagIcon",
1115
+ publicName: "tagIcon",
1116
+ isSignal: true,
1117
+ isRequired: false,
1118
+ transformFunction: null
1119
+ }
1120
+ },
1121
+ outputs: {
1122
+ selectionChange: "selectionChange",
1123
+ searchTextChange: "searchTextChange",
1124
+ blur: "blur",
1125
+ focus: "focus",
1126
+ scrollViewportBottomReached: "scrollViewportBottomReached",
1127
+ scrollViewportBottomReachedFiltered: "scrollViewportBottomReachedFiltered"
1128
+ },
1129
+ host: { properties: { "attr.theme": "applicationTheme" } },
1130
+ providers: [
1131
+ AutocompleteValueManager,
1132
+ AutocompleteFilterService,
1133
+ InfiniteScrollDirective
1134
+ ],
1135
+ queries: [{
1136
+ propertyName: "tagSuffix",
1137
+ first: true,
1138
+ predicate: AutocompleteTagSuffixDirective,
1139
+ descendants: true,
1140
+ isSignal: true
1141
+ }],
1142
+ viewQueries: [
1143
+ {
1144
+ propertyName: "formFieldElement",
1145
+ first: true,
1146
+ predicate: ["formField"],
1147
+ descendants: true
1148
+ },
1149
+ {
1150
+ propertyName: "tagContainer",
1151
+ first: true,
1152
+ predicate: ["tagContainer"],
1153
+ descendants: true
1154
+ },
1155
+ {
1156
+ propertyName: "measureElRef",
1157
+ first: true,
1158
+ predicate: ["measureEl"],
1159
+ descendants: true
1160
+ },
1161
+ {
1162
+ propertyName: "overflowDir",
1163
+ first: true,
1164
+ predicate: ["overflow"],
1165
+ descendants: true
1166
+ },
1167
+ {
1168
+ propertyName: "autocomplete",
1169
+ first: true,
1170
+ predicate: ["trigger"],
1171
+ descendants: true
1172
+ },
1173
+ {
1174
+ propertyName: "cdkViewport",
1175
+ first: true,
1176
+ predicate: CdkVirtualScrollViewport,
1177
+ descendants: true
1178
+ },
1179
+ {
1180
+ propertyName: "matAutocomplete",
1181
+ first: true,
1182
+ predicate: ["autocomplete"],
1183
+ descendants: true
1184
+ },
1185
+ {
1186
+ propertyName: "matInput",
1187
+ first: true,
1188
+ predicate: ["matInput"],
1189
+ descendants: true
1190
+ }
1191
+ ],
1192
+ ngImport: i0,
1193
+ template: "<ng-container>\n <div class=\"autocomplete-wrapper\" [ngClass]=\"{ disabled: _isDisabled() }\">\n <mat-form-field\n [color]=\"hasError() ? 'warn' : 'accent'\"\n [appearance]=\"'outline'\"\n [ngClass]=\"{\n 'large-size': type() === autocompleteType.LARGE,\n 'hide-bottom-content': !showBottomContent(),\n 'keyboard-focused': keyboardFocused(),\n 'has-label': !!label(),\n }\"\n >\n @if (label()) {\n <mat-label\n >{{ label() }}\n @if (required()) {\n <span>*</span>\n }\n </mat-label>\n }\n <div\n #formField\n class=\"input-container\"\n [class.has-multiple-selections]=\"\n type() === autocompleteType.LARGE &&\n utils.isArray(valueManager.value()) &&\n $any(valueManager.value()).length > 1\n \"\n [class.autocomplete-variant]=\"type() === autocompleteType.LARGE && !isDropdown\"\n >\n @if (textField() ? $any(valueManager.value())?.[textField()] : $any(valueManager.value()) === inputValue()) {\n <span style=\"position: absolute; left: -9999px\" aria-live=\"polite\">{{\n ('SELECTED' | uiTranslate | async) + ' ' + inputValue()\n }}</span>\n }\n\n <input\n [attr.data-testid]=\"testId() ?? 'autocomplete-v2-input'\"\n #trigger=\"matAutocompleteTrigger\"\n #matInput\n [attr.maxlength]=\"maxLength() !== null && maxLength() !== undefined ? maxLength() : null\"\n [uiPreventInput]=\"!allowUserInput()\"\n [disabled]=\"_isDisabled()\"\n [ngClass]=\"{\n 'unset-margin': valueManager.value() && type() === autocompleteType.LARGE,\n 'no-caret': !allowUserInput(),\n }\"\n (blur)=\"onBlur()\"\n (focusin)=\"onFocus()\"\n [attr.aria-label]=\"\n (translationContext + 'SELECTED' | uiTranslate | async) +\n ' ' +\n (valueManager.value() | transformItem: textField() : true)\n \"\n matInput\n [placeholder]=\"suppressPlaceholder() ? '' : placeholder()\"\n [type]=\"'text'\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"panelPosition()\"\n (input)=\"onInputChange($event)\"\n [ngModel]=\"inputValue()\"\n (ngModelChange)=\"inputValue.set($event)\"\n />\n <!-- Hidden measurement container: always in DOM, renders ALL tags for width measurement -->\n @if (!tagsBelow() && type() !== autocompleteType.SINGLE && utils.isArray(valueManager.value())) {\n <div class=\"selected-items measurement-container\" #measureEl>\n @for (valueItem of $any(valueManager.value()); track valueItem[valueField()] || i; let i = $index) {\n <ui-tag\n class=\"value-tag\"\n [id]=\"'measure-tag-' + i\"\n [label]=\"valueItem | transformItem: textField()\"\n [allowClose]=\"true\"\n [isDisabled]=\"disabled()\"\n [applicationTheme]=\"applicationTheme\"\n ></ui-tag>\n }\n </div>\n }\n\n @if (\n !tagsBelow() &&\n ((type() === autocompleteType.LARGE && valueManager.value()) ||\n (!(inputValue() && isInputFocus()) && valueManager.value() && type() !== autocompleteType.SINGLE))\n ) {\n <!-- Visible container: only renders tags that fit. Hidden until first measurement to prevent flash. -->\n <div\n class=\"selected-items\"\n #tagContainer\n uiAutocompleteOverflowDetect\n #overflow=\"autocompleteOverflowDetect\"\n [measureContainer]=\"$safeNavigationMigration(measureElRef?.nativeElement)\"\n [class.measured]=\"\n type() === autocompleteType.LARGE || type() === autocompleteType.SINGLE || overflow.hasMeasured()\n \"\n >\n @if (size() === 'small' && $any(valueManager.value()).length > 1) {\n <div class=\"selected-count\">\n {{\n translationContext + 'SELECTED_AMOUNT'\n | uiTranslate: { numberSelected: valueManager.value()!.length }\n | async\n }}\n </div>\n } @else {\n @for (valueItem of $any(valueManager.value()); track valueItem[valueField()] || i; let i = $index) {\n @if (i < overflow.visibleCount()) {\n <ui-tag\n class=\"value-tag\"\n [id]=\"'ui-tag-' + i\"\n [label]=\"valueItem | transformItem: textField()\"\n [allowClose]=\"true\"\n [isDisabled]=\"disabled()\"\n [applicationTheme]=\"applicationTheme\"\n [ngStyle]=\"\n type() !== autocompleteType.LARGE\n ? { '--tag-max-width': overflow.tagMaxWidth() ? overflow.tagMaxWidth() + 'px' : 'fit-content' }\n : {}\n \"\n (close)=\"onOptionRemoved(valueItem)\"\n ></ui-tag>\n }\n }\n @if (overflow.overflowCount() > 0) {\n <div class=\"overlap-count\" [matTooltip]=\"hiddenItemsTooltip()\">\n <ui-tag\n [applicationTheme]=\"applicationTheme\"\n [isDisabled]=\"disabled()\"\n [label]=\"'+' + overflow.overflowCount()\"\n ></ui-tag>\n </div>\n }\n }\n </div>\n }\n </div>\n\n @if (showClearButton()) {\n <ui-icon\n class=\"remove-selected\"\n [tabIndex]=\"_isDisabled() ? -1 : 0\"\n (keydown.enter)=\"onClear(); $event.preventDefault(); $event.stopPropagation()\"\n (keydown.space)=\"onClear(); $event.preventDefault(); $event.stopPropagation()\"\n [ngClass]=\"{ 'large-input-icon': type() === autocompleteType.LARGE }\"\n (click)=\"onClear(); $event.preventDefault(); $event.stopPropagation()\"\n [size]=\"'24'\"\n [color]=\"applicationTheme === 'classic' ? 'inherit' : 'rebrand-black'\"\n [attr.aria-label]=\"'COMMON.CLEAR' | uiTranslate | async\"\n [name]=\"applicationTheme === 'classic' ? 'Close' : 'Close-in-line'\"\n ></ui-icon>\n }\n\n @if (isDropdown) {\n <ui-icon\n class=\"arrow-state\"\n [ngClass]=\"{ opened: autocomplete.isOpen, 'large-input-icon': type() === autocompleteType.LARGE }\"\n [size]=\"'24'\"\n [name]=\"applicationTheme !== 'classic' ? 'Arrow-chevron-down-in-line' : 'Arrow_down'\"\n (click)=\"onChevronClick(autocomplete)\"\n ></ui-icon>\n }\n\n <mat-autocomplete\n #autocomplete\n [class]=\"applicationTheme + ' ' + dropdownPanelClass()\"\n (optionSelected)=\"onOptionSelected($event)\"\n [disableRipple]=\"applicationTheme !== 'classic'\"\n [hideSingleSelectionIndicator]=\"false\"\n (opened)=\"onPanelOpened()\"\n >\n <ng-template #optionContentTpl let-item=\"item\" let-highlight=\"highlight\">\n @if (imageField() && item?.[imageField()]) {\n <img class=\"option-image\" [src]=\"item[imageField()]\" alt=\"\" />\n }\n <span [selectText]=\"highlight ? (filterService.userInput$ | async) : null\">{{\n item | transformItem: textField()\n }}</span>\n <ui-icon\n [applicationTheme]=\"applicationTheme\"\n [name]=\"applicationTheme === 'classic' ? 'Check' : 'Check-in-line'\"\n ></ui-icon>\n </ng-template>\n\n <!-- Reusable option template — must be inside mat-autocomplete for @ContentChildren to find mat-options -->\n <ng-template #optionTpl let-item=\"item\" let-highlight=\"highlight\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: highlight }\"\n ></ng-container>\n </mat-option>\n </ng-template>\n\n <!-- Reusable \"Add\"/no-results/loading option for the filtered view -->\n <ng-template #addOptionTpl let-items=\"items\" let-suggestions=\"suggestions\">\n @if (dynamicFilterLoading()) {\n <mat-option class=\"loading-option\" [style.pointer-events]=\"'none'\">\n <div class=\"loading-container\">\n <ui-spinner size=\"small\" [isLoader]=\"false\"></ui-spinner>\n </div>\n </mat-option>\n } @else if (inputValue()) {\n @if (\n allowAdd() && !isAlreadyAdded() && !utils.hasExactMatch(items, suggestions, inputValue(), textField())\n ) {\n <mat-option (mousedown)=\"$event.preventDefault()\" [value]=\"inputValue()\">\n <span>{{ 'COMMON.ADD' | uiTranslate | async }}</span>\n <span class=\"add-suggestion\">\"{{ inputValue() }}\"</span>\n </mat-option>\n } @else if (!items.length && !suggestions.length) {\n <mat-option [style.pointer-events]=\"'none'\">\n <span>{{ translationContext + 'NO_RESULTS_FOUND' | uiTranslate | async }}</span>\n </mat-option>\n }\n }\n </ng-template>\n\n <!-- ── Unfiltered ───────────────────────────────────────────────── -->\n @if ((filterService.isSearching$ | async) === false) {\n @if (!isDropdown) {\n <!-- Suggestions -->\n @if (suggestionsList().length) {\n <mat-optgroup [label]=\"(translationContext + 'SUGGESTED' | uiTranslate | async)! | uppercase\">\n @for (suggested of suggestionsList(); track suggested) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: suggested, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n }\n\n <!-- Selected items (multi) -->\n @if (valueManager.value()?.length && type() !== autocompleteType.SINGLE && !hideSelectedSection()) {\n <mat-optgroup [label]=\"(translationContext + 'SELECTED' | uiTranslate | async)! | uppercase\">\n @for (item of $any(valueManager.value()); track item) {\n <ng-container *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: false }\"></ng-container>\n }\n </mat-optgroup>\n }\n\n <!-- Main items (normalized groups) -->\n @if (virtualScroll() || infiniteScroll()) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"48\"\n [style.height.px]=\"getVirtualScrollHeight(flatItemsList().length)\"\n class=\"virtual-scroll\"\n >\n @if (!isGrouped) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of flatItemsList(); trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n } @else {\n @for (group of groupedItemsList(); track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n *cdkVirtualFor=\"let item of group.items; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n </mat-optgroup>\n } @else {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of group.items; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n }\n }\n\n @if (infiniteScroll() && hasMoreOptionsForInfiniteScroll()) {\n <mat-option class=\"loading-option\" [style.pointer-events]=\"'none'\">\n <div class=\"loading-container\">\n <ui-spinner size=\"small\" [isLoader]=\"false\"></ui-spinner>\n </div>\n </mat-option>\n }\n </cdk-virtual-scroll-viewport>\n } @else {\n @if (isGrouped) {\n @for (group of groupedItemsList(); track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n @for (item of group.items; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n } @else {\n @for (item of group.items; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n }\n }\n } @else {\n @for (item of flatItemsList(); track item) {\n <ng-container *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"></ng-container>\n }\n }\n }\n\n <!-- Selected item (single) -->\n @if (valueManager.value()?.length && type() === autocompleteType.SINGLE && !hideSelectedSection()) {\n <mat-optgroup [label]=\"(translationContext + 'SELECTED' | uiTranslate | async)! | uppercase\">\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: valueManager.value(), highlight: true }\"\n ></ng-container>\n </mat-optgroup>\n }\n } @else {\n <!-- ── Dropdown (unfiltered) ────────────────────────────────── -->\n @if (virtualScroll() || infiniteScroll()) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"48\"\n [style.height.px]=\"getVirtualScrollHeight(flatItemsList().length)\"\n class=\"virtual-scroll\"\n >\n @if (!isGrouped) {\n <!-- Ungrouped: flat cdkVirtualFor directly in viewport -->\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of flatItemsList(); trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n } @else {\n <!-- Grouped: nested cdkVirtualFor per group -->\n @for (group of groupedItemsList(); track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n *cdkVirtualFor=\"let item of group.items; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n </mat-optgroup>\n } @else {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of group.items; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n }\n }\n\n @if (infiniteScroll() && hasMoreOptionsForInfiniteScroll()) {\n <mat-option class=\"loading-option\" [style.pointer-events]=\"'none'\">\n <div class=\"loading-container\">\n <ui-spinner size=\"small\" [isLoader]=\"false\"></ui-spinner>\n </div>\n </mat-option>\n }\n </cdk-virtual-scroll-viewport>\n } @else {\n @if (isGrouped) {\n @for (group of groupedItemsList(); track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n @for (item of group.items; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n } @else {\n @for (item of group.items; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n }\n }\n } @else {\n @for (item of flatItemsList(); track item) {\n <ng-container *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"></ng-container>\n }\n }\n }\n }\n\n @if (userAdditionsGroupLabel() && userAddedItems().length) {\n <mat-optgroup [label]=\"userAdditionsGroupLabel()\">\n @for (item of userAddedItems(); track item) {\n <ng-container *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"></ng-container>\n }\n </mat-optgroup>\n }\n }\n\n <!-- ── Filtered ────────────────────────────────────────────────── -->\n @if (filterService.filteredSuggestions$ | async; as filteredSuggestionList) {\n @if (filterService.filteredItems$ | async; as filteredItemsList) {\n @if (virtualScroll() || infiniteScroll()) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"48\"\n [style.height.px]=\"getVirtualScrollHeight(filteredItemsList.length)\"\n class=\"virtual-scroll\"\n >\n @if (addOptionPosition() === 'top') {\n <ng-container\n *ngTemplateOutlet=\"\n addOptionTpl;\n context: { items: filteredItemsList, suggestions: filteredSuggestionList }\n \"\n ></ng-container>\n }\n <!-- Filtered suggestions -->\n @if (filteredSuggestionList.length) {\n <mat-optgroup [label]=\"(translationContext + 'SUGGESTED' | uiTranslate | async)! | uppercase\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of filteredSuggestionList; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n </mat-optgroup>\n }\n\n <!-- Filtered items: grouped -->\n @if (isGrouped && (filterService.filteredGroupedItems$ | async); as filteredGroups) {\n @if (filteredGroups.length) {\n @for (group of filteredGroups; track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n *cdkVirtualFor=\"let item of group.filteredItems; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n </mat-optgroup>\n } @else {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n *cdkVirtualFor=\"let item of group.filteredItems; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n }\n }\n }\n\n <!-- Filtered items: ungrouped (no suggestions) -->\n @if (!filteredSuggestionList.length && !isGrouped) {\n @for (item of filteredItemsList; let idx = $index; track item[valueField()] || idx) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n } @else {\n <!-- Filtered items: ungrouped with suggestions present (ALL_ITEMS group) -->\n @if (filteredItemsList.length && !isGrouped) {\n <mat-optgroup [label]=\"(translationContext + 'ALL_ITEMS' | uiTranslate | async)! | uppercase\">\n @for (item of filteredItemsList; let idx = $index; track item[valueField()] || idx) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n </mat-optgroup>\n }\n }\n\n @if (addOptionPosition() === 'bottom') {\n <ng-container\n *ngTemplateOutlet=\"\n addOptionTpl;\n context: { items: filteredItemsList, suggestions: filteredSuggestionList }\n \"\n ></ng-container>\n }\n </cdk-virtual-scroll-viewport>\n } @else {\n @if (addOptionPosition() === 'top') {\n <ng-container\n *ngTemplateOutlet=\"\n addOptionTpl;\n context: { items: filteredItemsList, suggestions: filteredSuggestionList }\n \"\n ></ng-container>\n }\n <!-- Filtered items: grouped -->\n @if (isGrouped && (filterService.filteredGroupedItems$ | async); as filteredGroups) {\n @if (filteredGroups.length) {\n @for (group of filteredGroups; track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n @for (item of group.filteredItems; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n } @else {\n @for (item of group.filteredItems; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n }\n }\n }\n }\n\n <!-- Filtered suggestions -->\n @if (filteredSuggestionList.length) {\n <mat-optgroup [label]=\"(translationContext + 'SUGGESTED' | uiTranslate | async)! | uppercase\">\n @for (item of filteredSuggestionList; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n }\n\n <!-- Filtered items: ungrouped (no suggestions) -->\n @if (!filteredSuggestionList.length && !isGrouped) {\n @for (item of filteredItemsList; let idx = $index; track item[valueField()] || idx) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n } @else {\n <!-- Filtered items: ungrouped with suggestions present (ALL_ITEMS group) -->\n @if (filteredItemsList.length && !isGrouped) {\n <mat-optgroup [label]=\"(translationContext + 'ALL_ITEMS' | uiTranslate | async)! | uppercase\">\n @for (item of filteredItemsList; let idx = $index; track item[valueField()] || idx) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n </mat-optgroup>\n }\n }\n\n @if (addOptionPosition() === 'bottom') {\n <ng-container\n *ngTemplateOutlet=\"\n addOptionTpl;\n context: { items: filteredItemsList, suggestions: filteredSuggestionList }\n \"\n ></ng-container>\n }\n }\n }\n }\n </mat-autocomplete>\n @if (hasError()) {\n <mat-hint class=\"error\">\n @if (ngControl) {\n <ui-validation-error\n [ngControl]=\"ngControl\"\n [customErrors]=\"formErrorConfig()\"\n [label]=\"label()\"\n ></ui-validation-error>\n } @else {\n @for (error of safeErrors(); track error) {\n <div class=\"errors\">\n <ui-icon [applicationTheme]=\"applicationTheme\" [name]=\"'Error'\"></ui-icon>\n <span>{{ error }}</span>\n </div>\n }\n }\n </mat-hint>\n }\n </mat-form-field>\n @if (tagsBelow() && valueManager.value()?.length) {\n <div class=\"selected-items--below\">\n @for (valueItem of $any(valueManager.value()); track valueItem[valueField()] || i; let i = $index) {\n <ui-tag\n class=\"value-tag\"\n [id]=\"'below-tag-' + i\"\n [label]=\"valueItem | transformItem: textField()\"\n [icon]=\"tagIcons()[i]\"\n [allowClose]=\"true\"\n [isDisabled]=\"disabled()\"\n [constrainWidth]=\"true\"\n [applicationTheme]=\"applicationTheme\"\n (close)=\"onOptionRemoved(valueItem)\"\n (click)=\"onTagActivate($event)\"\n (keydown.enter)=\"onTagActivate($event)\"\n (keydown.space)=\"onTagActivate($event)\"\n >\n @if (tagSuffix(); as suffix) {\n <span class=\"value-tag__suffix\" uiTagSuffix>\n <ng-container *ngTemplateOutlet=\"suffix.templateRef; context: { $implicit: valueItem, index: i }\" />\n </span>\n }\n </ui-tag>\n }\n <!-- Consumer content rendered as a sibling of the selected tags, before the clear button -->\n <ng-content select=\"[autocompleteTagsSuffix]\"></ng-content>\n @if (clearable()) {\n <button type=\"button\" class=\"clear-all\" [disabled]=\"_isDisabled()\" (click)=\"onClear()\">\n {{ 'COMMON.CLEAR' | uiTranslate | async }}\n </button>\n }\n </div>\n }\n </div>\n</ng-container>\n",
1194
+ styles: [".bg-teal-60b{background:#1c443c}.bg-teal-30b{background:#31766a}.bg-teal-default{background:#46a997}.bg-teal-30w{background:#7ec3b6}.bg-teal-60w{background:#b5ddd5}.bg-teal-secondary{background:#cbd6cb}.bg-teal-90w{background:#ecf6f5}.bg-petrol-60b{background:#102930}.bg-petrol-30b{background:#1b4754}.bg-petrol-default{background:#276678}.bg-petrol-30w{background:#6894a0}.bg-petrol-60w{background:#a9c2c9}.bg-petrol-secondary{background:#c8d7de}.bg-petrol-90w{background:#e9f0f1}.bg-error-60b{background:#513131}.bg-error-30b{background:#8e5655}.bg-error-60w{background:#e3c3c6}.bg-error-secondary{background:#f0dad9}.bg-error-default{background:#cb7b7a}.bg-warning-secondary{background:#f0d6bb}.bg-warning-default{background:#cca45f}.bg-black{background:#000}.bg-dark{background:#888}.bg-medium{background:#e0e0e0}.bg-grey{background:#ededed}.bg-light{background:#f6f6f6}.bg-white{background:#fff}.bg-box-shadow{background:#00000014}.bg-navigation-subtitle{background:#528593}.bgc-teal-60b{background-color:#1c443c}.bgc-teal-30b{background-color:#31766a}.bgc-teal-default{background-color:#46a997}.bgc-teal-30w{background-color:#7ec3b6}.bgc-teal-60w{background-color:#b5ddd5}.bgc-teal-secondary{background-color:#cbd6cb}.bgc-teal-90w{background-color:#ecf6f5}.bgc-petrol-60b{background-color:#102930}.bgc-petrol-30b{background-color:#1b4754}.bgc-petrol-default{background-color:#276678}.bgc-petrol-30w{background-color:#6894a0}.bgc-petrol-60w{background-color:#a9c2c9}.bgc-petrol-secondary{background-color:#c8d7de}.bgc-petrol-90w{background-color:#e9f0f1}.bgc-error-60b{background-color:#513131}.bgc-error-30b{background-color:#8e5655}.bgc-error-60w{background-color:#e3c3c6}.bgc-error-secondary{background-color:#f0dad9}.bgc-error-default{background-color:#cb7b7a}.bgc-warning-secondary{background-color:#f0d6bb}.bgc-warning-default{background-color:#cca45f}.bgc-black{background-color:#000}.bgc-dark{background-color:#888}.bgc-medium{background-color:#e0e0e0}.bgc-grey{background-color:#ededed}.bgc-light{background-color:#f6f6f6}.bgc-white{background-color:#fff}.bgc-box-shadow{background-color:#00000014}.bgc-navigation-subtitle{background-color:#528593}:host{width:320px;display:block}:host.full-width{width:100%}:host ui-tag{height:32px;margin:4px}:host ui-tag ::ng-deep .tag-container{margin:0!important}:host ui-tag ::ng-deep .tag-wrapper{max-width:fit-content}.large-size input{margin:10px 0}.large-size .selected-items{margin:5px 0;flex-wrap:wrap;--tag-max-width: calc(100% - 8px) }.large-size .selected-items .value-tag ::ng-deep .tag-container{max-width:100%!important}.large-size .input-container{margin:auto 0;width:calc(100% - 25px);display:flex;flex-direction:column-reverse}.large-size .input-container.has-multiple-selections{width:calc(100% - 50px)}.large-size .input-container.autocomplete-variant{width:100%}.large-size .input-container.autocomplete-variant.has-multiple-selections{width:calc(100% - 26px)}.large-size ::ng-deep .mat-mdc-form-field-infix,.large-size .mat-mdc-form-field-flex{align-items:unset!important}.disabled *{pointer-events:none}.input-container{width:100%;margin:auto;display:flex;flex-direction:row-reverse}.input-container .selected-items{display:flex;padding-left:4px;visibility:hidden}.input-container .selected-items.measured{visibility:visible}.input-container .selected-items .value-tag{max-width:var(--tag-max-width, fit-content)}.input-container .selected-items .value-tag ::ng-deep .tag-container{max-width:var(--tag-max-width, fit-content)}.input-container .selected-items .selected-count{white-space:nowrap}.input-container .selected-items.measurement-container{visibility:hidden;position:absolute;height:0;overflow:hidden;pointer-events:none}.input-container .overlap-count{font-size:14px;line-height:20px}.input-container .overlap-count ui-tag{display:block}.input-container input{margin-left:6px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.input-container input.unset-margin{margin-top:unset}.input-container input.no-caret{cursor:pointer;caret-color:transparent!important}.add-suggestion{margin:0 5px;color:#000;font-weight:700}.remove-selected{cursor:pointer;margin-right:2px;border-radius:50px;height:fit-content}.remove-selected.large-input-icon{margin-top:10px}.arrow-state{height:24px;cursor:pointer}.arrow-state.large-input-icon{margin-top:10px}.arrow-state.opened{transform:rotateX(180deg)}::ng-deep .autocomplete-wrapper .mat-mdc-form-field{width:100%}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error,::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error svg{color:#cb7b7a}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error{display:flex}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error{display:flex;flex-flow:column;row-gap:4px}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error .errors ui-icon{margin-right:8px}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error .errors{display:flex}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error{color:#e02800!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error svg{color:#e02800!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-bottom-align:before{height:0}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint-wrapper{padding:0 0 12px;font-size:12px;line-height:16px;position:relative}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint-wrapper .mat-form-field-hint-spacer{display:none}::ng-deep .autocomplete-wrapper .mat-mdc-form-field.hide-bottom-content .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-text-field-wrapper.mdc-text-field--outlined .mdc-notched-outline--upgraded .mdc-floating-label--float-above{top:28px!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-floating-label{top:22px!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-text-field-wrapper{padding-left:12px!important;height:unset!important;max-height:unset!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-focused .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-floating-label{color:#276678!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mdc-text-field--outlined:not(.mdc-text-field--disabled).mdc-text-field--focused .mdc-notched-outline__notch{border-bottom:2px solid #276678!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mdc-text-field--outlined:not(.mdc-text-field--disabled).mdc-text-field--focused .mdc-notched-outline__leading{border-left:2px solid #276678!important;border-bottom:2px solid #276678!important;border-top:2px solid #276678!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mdc-text-field--outlined:not(.mdc-text-field--disabled).mdc-text-field--focused .mdc-notched-outline__trailing{border:2px solid #276678!important;border-left:unset!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-infix,::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-flex{min-height:48px!important;max-height:184px!important;overflow-y:auto;overflow-x:hidden;padding:0!important;display:flex;justify-content:center;text-align:center;align-items:center;flex-direction:row;width:100%}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mdc-line-ripple{display:none!important}::ng-deep .mat-mdc-autocomplete-panel{box-shadow:0 8px 24px 4px #00000014;max-height:312px!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option:hover:not(.mdc-list-item--disabled),::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option:focus:not(.mdc-list-item--disabled),::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.mat-mdc-option-active,::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.mdc-list-item--selected:not(.mat-mdc-option-multiple):not(.mdc-list-item--disabled){background:#e9f0f1!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option{padding-right:32px;padding-left:12px!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .option-image{width:24px;height:24px;margin-right:8px;object-fit:cover;flex-shrink:0}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option ui-icon{display:none;position:absolute;right:0;bottom:calc(50% - 8px);margin:0 10px}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.selected-option{background:#e9f0f1}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.selected-option ui-icon{display:block}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.mdc-list-item--selected .mdc-list-item__primary-text,::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .mdc-list-item--activated .mdc-list-item__primary-text{color:#000!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .mdc-list-item__primary-text{display:flex;align-items:center}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .mat-pseudo-checkbox{display:none}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-optgroup .mat-mdc-optgroup-label{font-weight:700!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-optgroup .mat-mdc-optgroup-label .mdc-list-item__primary-text{color:#000;font-size:12px;line-height:16px;font-weight:700}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-optgroup .mat-mdc-option{padding-left:16px!important}.active-field .mdc-notched-outline__leading{border-left-width:2px;border-top-width:2px;border-bottom-width:2px}.active-field .mdc-notched-outline__notch{border-top-width:2px;border-bottom-width:2px}.active-field .mdc-notched-outline__trailing{border-top-width:2px;border-bottom-width:2px;border-right-width:2px}.loading-option{display:flex}.loading-option .loading-container{display:flex;justify-content:center;align-items:center;width:100%;height:100%;position:absolute;top:0;left:0}.selected-items--below{display:flex;flex-wrap:wrap;align-items:center;gap:4px;margin-top:8px}.selected-items--below ui-tag{margin:0;--ui-tag-max-width: 400px}.selected-items--below .clear-all{background:none;border:none;padding:4px 8px;cursor:pointer;color:#000;font-weight:500;font-size:12px;line-height:16px;text-decoration:underline}.selected-items--below .clear-all:disabled{cursor:not-allowed;opacity:.5}\n"],
1195
+ dependencies: [
1196
+ {
1197
+ kind: "ngmodule",
1198
+ type: CommonModule
1199
+ },
1200
+ {
1201
+ kind: "directive",
1202
+ type: i1.NgClass,
1203
+ selector: "[ngClass]",
1204
+ inputs: ["class", "ngClass"]
1205
+ },
1206
+ {
1207
+ kind: "directive",
1208
+ type: i1.NgTemplateOutlet,
1209
+ selector: "[ngTemplateOutlet]",
1210
+ inputs: [
1211
+ "ngTemplateOutletContext",
1212
+ "ngTemplateOutlet",
1213
+ "ngTemplateOutletInjector"
1214
+ ]
1215
+ },
1216
+ {
1217
+ kind: "directive",
1218
+ type: i1.NgStyle,
1219
+ selector: "[ngStyle]",
1220
+ inputs: ["ngStyle"]
1221
+ },
1222
+ {
1223
+ kind: "ngmodule",
1224
+ type: FormsModule
1225
+ },
1226
+ {
1227
+ kind: "directive",
1228
+ type: i2.DefaultValueAccessor,
1229
+ selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]"
1230
+ },
1231
+ {
1232
+ kind: "directive",
1233
+ type: i2.NgControlStatus,
1234
+ selector: "[formControlName],[ngModel],[formControl]"
1235
+ },
1236
+ {
1237
+ kind: "directive",
1238
+ type: i2.NgModel,
1239
+ selector: "[ngModel]:not([formControlName]):not([formControl])",
1240
+ inputs: [
1241
+ "name",
1242
+ "disabled",
1243
+ "ngModel",
1244
+ "ngModelOptions"
1245
+ ],
1246
+ outputs: ["ngModelChange"],
1247
+ exportAs: ["ngModel"]
1248
+ },
1249
+ {
1250
+ kind: "ngmodule",
1251
+ type: MatAutocompleteModule
1252
+ },
1253
+ {
1254
+ kind: "component",
1255
+ type: i3.MatAutocomplete,
1256
+ selector: "mat-autocomplete",
1257
+ inputs: [
1258
+ "aria-label",
1259
+ "aria-labelledby",
1260
+ "displayWith",
1261
+ "autoActiveFirstOption",
1262
+ "autoSelectActiveOption",
1263
+ "requireSelection",
1264
+ "panelWidth",
1265
+ "disableRipple",
1266
+ "class",
1267
+ "hideSingleSelectionIndicator"
1268
+ ],
1269
+ outputs: [
1270
+ "optionSelected",
1271
+ "opened",
1272
+ "closed",
1273
+ "optionActivated"
1274
+ ],
1275
+ exportAs: ["matAutocomplete"]
1276
+ },
1277
+ {
1278
+ kind: "component",
1279
+ type: i3.MatOption,
1280
+ selector: "mat-option",
1281
+ inputs: [
1282
+ "value",
1283
+ "id",
1284
+ "disabled"
1285
+ ],
1286
+ outputs: ["onSelectionChange"],
1287
+ exportAs: ["matOption"]
1288
+ },
1289
+ {
1290
+ kind: "component",
1291
+ type: i3.MatOptgroup,
1292
+ selector: "mat-optgroup",
1293
+ inputs: ["label", "disabled"],
1294
+ exportAs: ["matOptgroup"]
1295
+ },
1296
+ {
1297
+ kind: "directive",
1298
+ type: i3.MatAutocompleteTrigger,
1299
+ selector: "input[matAutocomplete], textarea[matAutocomplete]",
1300
+ inputs: [
1301
+ "matAutocomplete",
1302
+ "matAutocompletePosition",
1303
+ "matAutocompleteConnectedTo",
1304
+ "autocomplete",
1305
+ "matAutocompleteDisabled"
1306
+ ],
1307
+ exportAs: ["matAutocompleteTrigger"]
1308
+ },
1309
+ {
1310
+ kind: "ngmodule",
1311
+ type: MatChipsModule
1312
+ },
1313
+ {
1314
+ kind: "ngmodule",
1315
+ type: MatFormFieldModule
1316
+ },
1317
+ {
1318
+ kind: "component",
1319
+ type: i4.MatFormField,
1320
+ selector: "mat-form-field",
1321
+ inputs: [
1322
+ "hideRequiredMarker",
1323
+ "color",
1324
+ "floatLabel",
1325
+ "appearance",
1326
+ "subscriptSizing",
1327
+ "hintLabel"
1328
+ ],
1329
+ exportAs: ["matFormField"]
1330
+ },
1331
+ {
1332
+ kind: "directive",
1333
+ type: i4.MatLabel,
1334
+ selector: "mat-label"
1335
+ },
1336
+ {
1337
+ kind: "directive",
1338
+ type: i4.MatHint,
1339
+ selector: "mat-hint",
1340
+ inputs: ["align", "id"]
1341
+ },
1342
+ {
1343
+ kind: "ngmodule",
1344
+ type: MatInputModule
1345
+ },
1346
+ {
1347
+ kind: "directive",
1348
+ type: i5.MatInput,
1349
+ selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]",
1350
+ inputs: [
1351
+ "disabled",
1352
+ "id",
1353
+ "placeholder",
1354
+ "name",
1355
+ "required",
1356
+ "type",
1357
+ "errorStateMatcher",
1358
+ "aria-describedby",
1359
+ "value",
1360
+ "readonly",
1361
+ "disabledInteractive"
1362
+ ],
1363
+ exportAs: ["matInput"]
1364
+ },
1365
+ {
1366
+ kind: "ngmodule",
1367
+ type: TagComponentModule
1368
+ },
1369
+ {
1370
+ kind: "component",
1371
+ type: i6.TagComponent,
1372
+ selector: "ui-tag",
1373
+ inputs: [
1374
+ "label",
1375
+ "icon",
1376
+ "allowClose",
1377
+ "readOnly",
1378
+ "isSelected",
1379
+ "showIconWhenSelected",
1380
+ "pinnedBackground",
1381
+ "constrainWidth",
1382
+ "isDisabled",
1383
+ "applicationTheme",
1384
+ "ariaLabel",
1385
+ "testId",
1386
+ "ariaRequired",
1387
+ "showBadge",
1388
+ "notificationsAmount"
1389
+ ],
1390
+ outputs: [
1391
+ "isSelectedChange",
1392
+ "close",
1393
+ "press"
1394
+ ]
1395
+ },
1396
+ {
1397
+ kind: "ngmodule",
1398
+ type: IconComponentModule
1399
+ },
1400
+ {
1401
+ kind: "component",
1402
+ type: i7.IconComponent,
1403
+ selector: "ui-icon",
1404
+ inputs: [
1405
+ "size",
1406
+ "cssClass",
1407
+ "name",
1408
+ "color",
1409
+ "filled",
1410
+ "toggleIconStyle",
1411
+ "applicationTheme",
1412
+ "useFullIconName"
1413
+ ]
1414
+ },
1415
+ {
1416
+ kind: "ngmodule",
1417
+ type: SpinnerComponentModule
1418
+ },
1419
+ {
1420
+ kind: "component",
1421
+ type: i8.SpinnerComponent,
1422
+ selector: "ui-spinner",
1423
+ inputs: [
1424
+ "size",
1425
+ "isLoader",
1426
+ "text",
1427
+ "applicationTheme",
1428
+ "iconName",
1429
+ "iconSize"
1430
+ ]
1431
+ },
1432
+ {
1433
+ kind: "component",
1434
+ type: CdkVirtualScrollViewport,
1435
+ selector: "cdk-virtual-scroll-viewport",
1436
+ inputs: ["orientation", "appendOnly"],
1437
+ outputs: ["scrolledIndexChange"]
1438
+ },
1439
+ {
1440
+ kind: "directive",
1441
+ type: CdkVirtualForOf,
1442
+ selector: "[cdkVirtualFor][cdkVirtualForOf]",
1443
+ inputs: [
1444
+ "cdkVirtualForOf",
1445
+ "cdkVirtualForTrackBy",
1446
+ "cdkVirtualForTemplate",
1447
+ "cdkVirtualForTemplateCacheSize"
1448
+ ]
1449
+ },
1450
+ {
1451
+ kind: "directive",
1452
+ type: CdkFixedSizeVirtualScroll,
1453
+ selector: "cdk-virtual-scroll-viewport[itemSize]",
1454
+ inputs: [
1455
+ "itemSize",
1456
+ "minBufferPx",
1457
+ "maxBufferPx"
1458
+ ]
1459
+ },
1460
+ {
1461
+ kind: "directive",
1462
+ type: PreventInputDirective,
1463
+ selector: "[uiPreventInput]",
1464
+ inputs: ["uiPreventInput"]
1465
+ },
1466
+ {
1467
+ kind: "directive",
1468
+ type: SelectTextDirective,
1469
+ selector: "[selectText]",
1470
+ inputs: ["selectText"]
1471
+ },
1472
+ {
1473
+ kind: "directive",
1474
+ type: AutocompleteOverflowDetectDirective,
1475
+ selector: "[uiAutocompleteOverflowDetect]",
1476
+ inputs: [
1477
+ "measureContainer",
1478
+ "itemSelector",
1479
+ "reserveWidth"
1480
+ ],
1481
+ exportAs: ["autocompleteOverflowDetect"]
1482
+ },
1483
+ {
1484
+ kind: "ngmodule",
1485
+ type: ValidationErrorModule
1486
+ },
1487
+ {
1488
+ kind: "component",
1489
+ type: i9.ValidationErrorComponent,
1490
+ selector: "ui-validation-error",
1491
+ inputs: [
1492
+ "ngControl",
1493
+ "touchedOn",
1494
+ "errorMessage",
1495
+ "label",
1496
+ "applicationTheme",
1497
+ "customErrors"
1498
+ ]
1499
+ },
1500
+ {
1501
+ kind: "ngmodule",
1502
+ type: MatTooltipModule
1503
+ },
1504
+ {
1505
+ kind: "directive",
1506
+ type: i10.MatTooltip,
1507
+ selector: "[matTooltip]",
1508
+ inputs: [
1509
+ "matTooltipPosition",
1510
+ "matTooltipPositionAtOrigin",
1511
+ "matTooltipDisabled",
1512
+ "matTooltipShowDelay",
1513
+ "matTooltipHideDelay",
1514
+ "matTooltipTouchGestures",
1515
+ "matTooltip",
1516
+ "matTooltipClass"
1517
+ ],
1518
+ exportAs: ["matTooltip"]
1519
+ },
1520
+ {
1521
+ kind: "pipe",
1522
+ type: i1.AsyncPipe,
1523
+ name: "async"
1524
+ },
1525
+ {
1526
+ kind: "pipe",
1527
+ type: i1.UpperCasePipe,
1528
+ name: "uppercase"
1529
+ },
1530
+ {
1531
+ kind: "pipe",
1532
+ type: UiTranslatePipe,
1533
+ name: "uiTranslate"
1534
+ },
1535
+ {
1536
+ kind: "pipe",
1537
+ type: TransformItemPipe,
1538
+ name: "transformItem"
1539
+ },
1540
+ {
1541
+ kind: "pipe",
1542
+ type: IncludesPipe,
1543
+ name: "includes"
1544
+ }
1545
+ ],
1546
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
1547
+ });
1548
+ }
1549
+ };
1550
+ i0.ɵɵngDeclareClassMetadata({
1551
+ minVersion: "12.0.0",
1552
+ version: "22.2.4",
1553
+ ngImport: i0,
1554
+ type: AutocompleteV2Component,
1555
+ decorators: [{
1556
+ type: Component,
1557
+ args: [{
1558
+ selector: "ui-autocomplete-v2",
1559
+ changeDetection: ChangeDetectionStrategy.OnPush,
1560
+ standalone: true,
1561
+ imports: [
1562
+ CommonModule,
1563
+ FormsModule,
1564
+ MatAutocompleteModule,
1565
+ MatChipsModule,
1566
+ MatFormFieldModule,
1567
+ MatInputModule,
1568
+ TagComponentModule,
1569
+ IconComponentModule,
1570
+ SpinnerComponentModule,
1571
+ CdkVirtualScrollViewport,
1572
+ CdkVirtualForOf,
1573
+ CdkFixedSizeVirtualScroll,
1574
+ PreventInputDirective,
1575
+ UiTranslatePipe,
1576
+ TransformItemPipe,
1577
+ IncludesPipe,
1578
+ SelectTextDirective,
1579
+ AutocompleteOverflowDetectDirective,
1580
+ ValidationErrorModule,
1581
+ MatTooltipModule
1582
+ ],
1583
+ host: { "[attr.theme]": "applicationTheme" },
1584
+ providers: [
1585
+ AutocompleteValueManager,
1586
+ AutocompleteFilterService,
1587
+ InfiniteScrollDirective
1588
+ ],
1589
+ template: "<ng-container>\n <div class=\"autocomplete-wrapper\" [ngClass]=\"{ disabled: _isDisabled() }\">\n <mat-form-field\n [color]=\"hasError() ? 'warn' : 'accent'\"\n [appearance]=\"'outline'\"\n [ngClass]=\"{\n 'large-size': type() === autocompleteType.LARGE,\n 'hide-bottom-content': !showBottomContent(),\n 'keyboard-focused': keyboardFocused(),\n 'has-label': !!label(),\n }\"\n >\n @if (label()) {\n <mat-label\n >{{ label() }}\n @if (required()) {\n <span>*</span>\n }\n </mat-label>\n }\n <div\n #formField\n class=\"input-container\"\n [class.has-multiple-selections]=\"\n type() === autocompleteType.LARGE &&\n utils.isArray(valueManager.value()) &&\n $any(valueManager.value()).length > 1\n \"\n [class.autocomplete-variant]=\"type() === autocompleteType.LARGE && !isDropdown\"\n >\n @if (textField() ? $any(valueManager.value())?.[textField()] : $any(valueManager.value()) === inputValue()) {\n <span style=\"position: absolute; left: -9999px\" aria-live=\"polite\">{{\n ('SELECTED' | uiTranslate | async) + ' ' + inputValue()\n }}</span>\n }\n\n <input\n [attr.data-testid]=\"testId() ?? 'autocomplete-v2-input'\"\n #trigger=\"matAutocompleteTrigger\"\n #matInput\n [attr.maxlength]=\"maxLength() !== null && maxLength() !== undefined ? maxLength() : null\"\n [uiPreventInput]=\"!allowUserInput()\"\n [disabled]=\"_isDisabled()\"\n [ngClass]=\"{\n 'unset-margin': valueManager.value() && type() === autocompleteType.LARGE,\n 'no-caret': !allowUserInput(),\n }\"\n (blur)=\"onBlur()\"\n (focusin)=\"onFocus()\"\n [attr.aria-label]=\"\n (translationContext + 'SELECTED' | uiTranslate | async) +\n ' ' +\n (valueManager.value() | transformItem: textField() : true)\n \"\n matInput\n [placeholder]=\"suppressPlaceholder() ? '' : placeholder()\"\n [type]=\"'text'\"\n [matAutocomplete]=\"autocomplete\"\n [matAutocompletePosition]=\"panelPosition()\"\n (input)=\"onInputChange($event)\"\n [ngModel]=\"inputValue()\"\n (ngModelChange)=\"inputValue.set($event)\"\n />\n <!-- Hidden measurement container: always in DOM, renders ALL tags for width measurement -->\n @if (!tagsBelow() && type() !== autocompleteType.SINGLE && utils.isArray(valueManager.value())) {\n <div class=\"selected-items measurement-container\" #measureEl>\n @for (valueItem of $any(valueManager.value()); track valueItem[valueField()] || i; let i = $index) {\n <ui-tag\n class=\"value-tag\"\n [id]=\"'measure-tag-' + i\"\n [label]=\"valueItem | transformItem: textField()\"\n [allowClose]=\"true\"\n [isDisabled]=\"disabled()\"\n [applicationTheme]=\"applicationTheme\"\n ></ui-tag>\n }\n </div>\n }\n\n @if (\n !tagsBelow() &&\n ((type() === autocompleteType.LARGE && valueManager.value()) ||\n (!(inputValue() && isInputFocus()) && valueManager.value() && type() !== autocompleteType.SINGLE))\n ) {\n <!-- Visible container: only renders tags that fit. Hidden until first measurement to prevent flash. -->\n <div\n class=\"selected-items\"\n #tagContainer\n uiAutocompleteOverflowDetect\n #overflow=\"autocompleteOverflowDetect\"\n [measureContainer]=\"$safeNavigationMigration(measureElRef?.nativeElement)\"\n [class.measured]=\"\n type() === autocompleteType.LARGE || type() === autocompleteType.SINGLE || overflow.hasMeasured()\n \"\n >\n @if (size() === 'small' && $any(valueManager.value()).length > 1) {\n <div class=\"selected-count\">\n {{\n translationContext + 'SELECTED_AMOUNT'\n | uiTranslate: { numberSelected: valueManager.value()!.length }\n | async\n }}\n </div>\n } @else {\n @for (valueItem of $any(valueManager.value()); track valueItem[valueField()] || i; let i = $index) {\n @if (i < overflow.visibleCount()) {\n <ui-tag\n class=\"value-tag\"\n [id]=\"'ui-tag-' + i\"\n [label]=\"valueItem | transformItem: textField()\"\n [allowClose]=\"true\"\n [isDisabled]=\"disabled()\"\n [applicationTheme]=\"applicationTheme\"\n [ngStyle]=\"\n type() !== autocompleteType.LARGE\n ? { '--tag-max-width': overflow.tagMaxWidth() ? overflow.tagMaxWidth() + 'px' : 'fit-content' }\n : {}\n \"\n (close)=\"onOptionRemoved(valueItem)\"\n ></ui-tag>\n }\n }\n @if (overflow.overflowCount() > 0) {\n <div class=\"overlap-count\" [matTooltip]=\"hiddenItemsTooltip()\">\n <ui-tag\n [applicationTheme]=\"applicationTheme\"\n [isDisabled]=\"disabled()\"\n [label]=\"'+' + overflow.overflowCount()\"\n ></ui-tag>\n </div>\n }\n }\n </div>\n }\n </div>\n\n @if (showClearButton()) {\n <ui-icon\n class=\"remove-selected\"\n [tabIndex]=\"_isDisabled() ? -1 : 0\"\n (keydown.enter)=\"onClear(); $event.preventDefault(); $event.stopPropagation()\"\n (keydown.space)=\"onClear(); $event.preventDefault(); $event.stopPropagation()\"\n [ngClass]=\"{ 'large-input-icon': type() === autocompleteType.LARGE }\"\n (click)=\"onClear(); $event.preventDefault(); $event.stopPropagation()\"\n [size]=\"'24'\"\n [color]=\"applicationTheme === 'classic' ? 'inherit' : 'rebrand-black'\"\n [attr.aria-label]=\"'COMMON.CLEAR' | uiTranslate | async\"\n [name]=\"applicationTheme === 'classic' ? 'Close' : 'Close-in-line'\"\n ></ui-icon>\n }\n\n @if (isDropdown) {\n <ui-icon\n class=\"arrow-state\"\n [ngClass]=\"{ opened: autocomplete.isOpen, 'large-input-icon': type() === autocompleteType.LARGE }\"\n [size]=\"'24'\"\n [name]=\"applicationTheme !== 'classic' ? 'Arrow-chevron-down-in-line' : 'Arrow_down'\"\n (click)=\"onChevronClick(autocomplete)\"\n ></ui-icon>\n }\n\n <mat-autocomplete\n #autocomplete\n [class]=\"applicationTheme + ' ' + dropdownPanelClass()\"\n (optionSelected)=\"onOptionSelected($event)\"\n [disableRipple]=\"applicationTheme !== 'classic'\"\n [hideSingleSelectionIndicator]=\"false\"\n (opened)=\"onPanelOpened()\"\n >\n <ng-template #optionContentTpl let-item=\"item\" let-highlight=\"highlight\">\n @if (imageField() && item?.[imageField()]) {\n <img class=\"option-image\" [src]=\"item[imageField()]\" alt=\"\" />\n }\n <span [selectText]=\"highlight ? (filterService.userInput$ | async) : null\">{{\n item | transformItem: textField()\n }}</span>\n <ui-icon\n [applicationTheme]=\"applicationTheme\"\n [name]=\"applicationTheme === 'classic' ? 'Check' : 'Check-in-line'\"\n ></ui-icon>\n </ng-template>\n\n <!-- Reusable option template — must be inside mat-autocomplete for @ContentChildren to find mat-options -->\n <ng-template #optionTpl let-item=\"item\" let-highlight=\"highlight\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: highlight }\"\n ></ng-container>\n </mat-option>\n </ng-template>\n\n <!-- Reusable \"Add\"/no-results/loading option for the filtered view -->\n <ng-template #addOptionTpl let-items=\"items\" let-suggestions=\"suggestions\">\n @if (dynamicFilterLoading()) {\n <mat-option class=\"loading-option\" [style.pointer-events]=\"'none'\">\n <div class=\"loading-container\">\n <ui-spinner size=\"small\" [isLoader]=\"false\"></ui-spinner>\n </div>\n </mat-option>\n } @else if (inputValue()) {\n @if (\n allowAdd() && !isAlreadyAdded() && !utils.hasExactMatch(items, suggestions, inputValue(), textField())\n ) {\n <mat-option (mousedown)=\"$event.preventDefault()\" [value]=\"inputValue()\">\n <span>{{ 'COMMON.ADD' | uiTranslate | async }}</span>\n <span class=\"add-suggestion\">\"{{ inputValue() }}\"</span>\n </mat-option>\n } @else if (!items.length && !suggestions.length) {\n <mat-option [style.pointer-events]=\"'none'\">\n <span>{{ translationContext + 'NO_RESULTS_FOUND' | uiTranslate | async }}</span>\n </mat-option>\n }\n }\n </ng-template>\n\n <!-- ── Unfiltered ───────────────────────────────────────────────── -->\n @if ((filterService.isSearching$ | async) === false) {\n @if (!isDropdown) {\n <!-- Suggestions -->\n @if (suggestionsList().length) {\n <mat-optgroup [label]=\"(translationContext + 'SUGGESTED' | uiTranslate | async)! | uppercase\">\n @for (suggested of suggestionsList(); track suggested) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: suggested, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n }\n\n <!-- Selected items (multi) -->\n @if (valueManager.value()?.length && type() !== autocompleteType.SINGLE && !hideSelectedSection()) {\n <mat-optgroup [label]=\"(translationContext + 'SELECTED' | uiTranslate | async)! | uppercase\">\n @for (item of $any(valueManager.value()); track item) {\n <ng-container *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: false }\"></ng-container>\n }\n </mat-optgroup>\n }\n\n <!-- Main items (normalized groups) -->\n @if (virtualScroll() || infiniteScroll()) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"48\"\n [style.height.px]=\"getVirtualScrollHeight(flatItemsList().length)\"\n class=\"virtual-scroll\"\n >\n @if (!isGrouped) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of flatItemsList(); trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n } @else {\n @for (group of groupedItemsList(); track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n *cdkVirtualFor=\"let item of group.items; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n </mat-optgroup>\n } @else {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of group.items; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n }\n }\n\n @if (infiniteScroll() && hasMoreOptionsForInfiniteScroll()) {\n <mat-option class=\"loading-option\" [style.pointer-events]=\"'none'\">\n <div class=\"loading-container\">\n <ui-spinner size=\"small\" [isLoader]=\"false\"></ui-spinner>\n </div>\n </mat-option>\n }\n </cdk-virtual-scroll-viewport>\n } @else {\n @if (isGrouped) {\n @for (group of groupedItemsList(); track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n @for (item of group.items; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n } @else {\n @for (item of group.items; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n }\n }\n } @else {\n @for (item of flatItemsList(); track item) {\n <ng-container *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"></ng-container>\n }\n }\n }\n\n <!-- Selected item (single) -->\n @if (valueManager.value()?.length && type() === autocompleteType.SINGLE && !hideSelectedSection()) {\n <mat-optgroup [label]=\"(translationContext + 'SELECTED' | uiTranslate | async)! | uppercase\">\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: valueManager.value(), highlight: true }\"\n ></ng-container>\n </mat-optgroup>\n }\n } @else {\n <!-- ── Dropdown (unfiltered) ────────────────────────────────── -->\n @if (virtualScroll() || infiniteScroll()) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"48\"\n [style.height.px]=\"getVirtualScrollHeight(flatItemsList().length)\"\n class=\"virtual-scroll\"\n >\n @if (!isGrouped) {\n <!-- Ungrouped: flat cdkVirtualFor directly in viewport -->\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of flatItemsList(); trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n } @else {\n <!-- Grouped: nested cdkVirtualFor per group -->\n @for (group of groupedItemsList(); track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n *cdkVirtualFor=\"let item of group.items; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n </mat-optgroup>\n } @else {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of group.items; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n }\n }\n\n @if (infiniteScroll() && hasMoreOptionsForInfiniteScroll()) {\n <mat-option class=\"loading-option\" [style.pointer-events]=\"'none'\">\n <div class=\"loading-container\">\n <ui-spinner size=\"small\" [isLoader]=\"false\"></ui-spinner>\n </div>\n </mat-option>\n }\n </cdk-virtual-scroll-viewport>\n } @else {\n @if (isGrouped) {\n @for (group of groupedItemsList(); track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n @for (item of group.items; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n } @else {\n @for (item of group.items; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n }\n }\n } @else {\n @for (item of flatItemsList(); track item) {\n <ng-container *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"></ng-container>\n }\n }\n }\n }\n\n @if (userAdditionsGroupLabel() && userAddedItems().length) {\n <mat-optgroup [label]=\"userAdditionsGroupLabel()\">\n @for (item of userAddedItems(); track item) {\n <ng-container *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"></ng-container>\n }\n </mat-optgroup>\n }\n }\n\n <!-- ── Filtered ────────────────────────────────────────────────── -->\n @if (filterService.filteredSuggestions$ | async; as filteredSuggestionList) {\n @if (filterService.filteredItems$ | async; as filteredItemsList) {\n @if (virtualScroll() || infiniteScroll()) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"48\"\n [style.height.px]=\"getVirtualScrollHeight(filteredItemsList.length)\"\n class=\"virtual-scroll\"\n >\n @if (addOptionPosition() === 'top') {\n <ng-container\n *ngTemplateOutlet=\"\n addOptionTpl;\n context: { items: filteredItemsList, suggestions: filteredSuggestionList }\n \"\n ></ng-container>\n }\n <!-- Filtered suggestions -->\n @if (filteredSuggestionList.length) {\n <mat-optgroup [label]=\"(translationContext + 'SUGGESTED' | uiTranslate | async)! | uppercase\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n *cdkVirtualFor=\"let item of filteredSuggestionList; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n </mat-optgroup>\n }\n\n <!-- Filtered items: grouped -->\n @if (isGrouped && (filterService.filteredGroupedItems$ | async); as filteredGroups) {\n @if (filteredGroups.length) {\n @for (group of filteredGroups; track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n *cdkVirtualFor=\"let item of group.filteredItems; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n </mat-optgroup>\n } @else {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n *cdkVirtualFor=\"let item of group.filteredItems; trackBy: trackByItem\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n }\n }\n }\n\n <!-- Filtered items: ungrouped (no suggestions) -->\n @if (!filteredSuggestionList.length && !isGrouped) {\n @for (item of filteredItemsList; let idx = $index; track item[valueField()] || idx) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n } @else {\n <!-- Filtered items: ungrouped with suggestions present (ALL_ITEMS group) -->\n @if (filteredItemsList.length && !isGrouped) {\n <mat-optgroup [label]=\"(translationContext + 'ALL_ITEMS' | uiTranslate | async)! | uppercase\">\n @for (item of filteredItemsList; let idx = $index; track item[valueField()] || idx) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{\n 'selected-option': item | includes: valueManager.value() ?? [] : valueField(),\n }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n </mat-optgroup>\n }\n }\n\n @if (addOptionPosition() === 'bottom') {\n <ng-container\n *ngTemplateOutlet=\"\n addOptionTpl;\n context: { items: filteredItemsList, suggestions: filteredSuggestionList }\n \"\n ></ng-container>\n }\n </cdk-virtual-scroll-viewport>\n } @else {\n @if (addOptionPosition() === 'top') {\n <ng-container\n *ngTemplateOutlet=\"\n addOptionTpl;\n context: { items: filteredItemsList, suggestions: filteredSuggestionList }\n \"\n ></ng-container>\n }\n <!-- Filtered items: grouped -->\n @if (isGrouped && (filterService.filteredGroupedItems$ | async); as filteredGroups) {\n @if (filteredGroups.length) {\n @for (group of filteredGroups; track group) {\n @if (group.groupName) {\n <mat-optgroup [label]=\"group.groupName\">\n @for (item of group.filteredItems; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n } @else {\n @for (item of group.filteredItems; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n }\n }\n }\n }\n\n <!-- Filtered suggestions -->\n @if (filteredSuggestionList.length) {\n <mat-optgroup [label]=\"(translationContext + 'SUGGESTED' | uiTranslate | async)! | uppercase\">\n @for (item of filteredSuggestionList; track item) {\n <ng-container\n *ngTemplateOutlet=\"optionTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n }\n </mat-optgroup>\n }\n\n <!-- Filtered items: ungrouped (no suggestions) -->\n @if (!filteredSuggestionList.length && !isGrouped) {\n @for (item of filteredItemsList; let idx = $index; track item[valueField()] || idx) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n } @else {\n <!-- Filtered items: ungrouped with suggestions present (ALL_ITEMS group) -->\n @if (filteredItemsList.length && !isGrouped) {\n <mat-optgroup [label]=\"(translationContext + 'ALL_ITEMS' | uiTranslate | async)! | uppercase\">\n @for (item of filteredItemsList; let idx = $index; track item[valueField()] || idx) {\n <mat-option\n (mousedown)=\"$event.preventDefault()\"\n [ngClass]=\"{ 'selected-option': item | includes: valueManager.value() ?? [] : valueField() }\"\n [value]=\"item\"\n >\n <ng-container\n *ngTemplateOutlet=\"optionContentTpl; context: { item: item, highlight: true }\"\n ></ng-container>\n </mat-option>\n }\n </mat-optgroup>\n }\n }\n\n @if (addOptionPosition() === 'bottom') {\n <ng-container\n *ngTemplateOutlet=\"\n addOptionTpl;\n context: { items: filteredItemsList, suggestions: filteredSuggestionList }\n \"\n ></ng-container>\n }\n }\n }\n }\n </mat-autocomplete>\n @if (hasError()) {\n <mat-hint class=\"error\">\n @if (ngControl) {\n <ui-validation-error\n [ngControl]=\"ngControl\"\n [customErrors]=\"formErrorConfig()\"\n [label]=\"label()\"\n ></ui-validation-error>\n } @else {\n @for (error of safeErrors(); track error) {\n <div class=\"errors\">\n <ui-icon [applicationTheme]=\"applicationTheme\" [name]=\"'Error'\"></ui-icon>\n <span>{{ error }}</span>\n </div>\n }\n }\n </mat-hint>\n }\n </mat-form-field>\n @if (tagsBelow() && valueManager.value()?.length) {\n <div class=\"selected-items--below\">\n @for (valueItem of $any(valueManager.value()); track valueItem[valueField()] || i; let i = $index) {\n <ui-tag\n class=\"value-tag\"\n [id]=\"'below-tag-' + i\"\n [label]=\"valueItem | transformItem: textField()\"\n [icon]=\"tagIcons()[i]\"\n [allowClose]=\"true\"\n [isDisabled]=\"disabled()\"\n [constrainWidth]=\"true\"\n [applicationTheme]=\"applicationTheme\"\n (close)=\"onOptionRemoved(valueItem)\"\n (click)=\"onTagActivate($event)\"\n (keydown.enter)=\"onTagActivate($event)\"\n (keydown.space)=\"onTagActivate($event)\"\n >\n @if (tagSuffix(); as suffix) {\n <span class=\"value-tag__suffix\" uiTagSuffix>\n <ng-container *ngTemplateOutlet=\"suffix.templateRef; context: { $implicit: valueItem, index: i }\" />\n </span>\n }\n </ui-tag>\n }\n <!-- Consumer content rendered as a sibling of the selected tags, before the clear button -->\n <ng-content select=\"[autocompleteTagsSuffix]\"></ng-content>\n @if (clearable()) {\n <button type=\"button\" class=\"clear-all\" [disabled]=\"_isDisabled()\" (click)=\"onClear()\">\n {{ 'COMMON.CLEAR' | uiTranslate | async }}\n </button>\n }\n </div>\n }\n </div>\n</ng-container>\n",
1590
+ styles: [".bg-teal-60b{background:#1c443c}.bg-teal-30b{background:#31766a}.bg-teal-default{background:#46a997}.bg-teal-30w{background:#7ec3b6}.bg-teal-60w{background:#b5ddd5}.bg-teal-secondary{background:#cbd6cb}.bg-teal-90w{background:#ecf6f5}.bg-petrol-60b{background:#102930}.bg-petrol-30b{background:#1b4754}.bg-petrol-default{background:#276678}.bg-petrol-30w{background:#6894a0}.bg-petrol-60w{background:#a9c2c9}.bg-petrol-secondary{background:#c8d7de}.bg-petrol-90w{background:#e9f0f1}.bg-error-60b{background:#513131}.bg-error-30b{background:#8e5655}.bg-error-60w{background:#e3c3c6}.bg-error-secondary{background:#f0dad9}.bg-error-default{background:#cb7b7a}.bg-warning-secondary{background:#f0d6bb}.bg-warning-default{background:#cca45f}.bg-black{background:#000}.bg-dark{background:#888}.bg-medium{background:#e0e0e0}.bg-grey{background:#ededed}.bg-light{background:#f6f6f6}.bg-white{background:#fff}.bg-box-shadow{background:#00000014}.bg-navigation-subtitle{background:#528593}.bgc-teal-60b{background-color:#1c443c}.bgc-teal-30b{background-color:#31766a}.bgc-teal-default{background-color:#46a997}.bgc-teal-30w{background-color:#7ec3b6}.bgc-teal-60w{background-color:#b5ddd5}.bgc-teal-secondary{background-color:#cbd6cb}.bgc-teal-90w{background-color:#ecf6f5}.bgc-petrol-60b{background-color:#102930}.bgc-petrol-30b{background-color:#1b4754}.bgc-petrol-default{background-color:#276678}.bgc-petrol-30w{background-color:#6894a0}.bgc-petrol-60w{background-color:#a9c2c9}.bgc-petrol-secondary{background-color:#c8d7de}.bgc-petrol-90w{background-color:#e9f0f1}.bgc-error-60b{background-color:#513131}.bgc-error-30b{background-color:#8e5655}.bgc-error-60w{background-color:#e3c3c6}.bgc-error-secondary{background-color:#f0dad9}.bgc-error-default{background-color:#cb7b7a}.bgc-warning-secondary{background-color:#f0d6bb}.bgc-warning-default{background-color:#cca45f}.bgc-black{background-color:#000}.bgc-dark{background-color:#888}.bgc-medium{background-color:#e0e0e0}.bgc-grey{background-color:#ededed}.bgc-light{background-color:#f6f6f6}.bgc-white{background-color:#fff}.bgc-box-shadow{background-color:#00000014}.bgc-navigation-subtitle{background-color:#528593}:host{width:320px;display:block}:host.full-width{width:100%}:host ui-tag{height:32px;margin:4px}:host ui-tag ::ng-deep .tag-container{margin:0!important}:host ui-tag ::ng-deep .tag-wrapper{max-width:fit-content}.large-size input{margin:10px 0}.large-size .selected-items{margin:5px 0;flex-wrap:wrap;--tag-max-width: calc(100% - 8px) }.large-size .selected-items .value-tag ::ng-deep .tag-container{max-width:100%!important}.large-size .input-container{margin:auto 0;width:calc(100% - 25px);display:flex;flex-direction:column-reverse}.large-size .input-container.has-multiple-selections{width:calc(100% - 50px)}.large-size .input-container.autocomplete-variant{width:100%}.large-size .input-container.autocomplete-variant.has-multiple-selections{width:calc(100% - 26px)}.large-size ::ng-deep .mat-mdc-form-field-infix,.large-size .mat-mdc-form-field-flex{align-items:unset!important}.disabled *{pointer-events:none}.input-container{width:100%;margin:auto;display:flex;flex-direction:row-reverse}.input-container .selected-items{display:flex;padding-left:4px;visibility:hidden}.input-container .selected-items.measured{visibility:visible}.input-container .selected-items .value-tag{max-width:var(--tag-max-width, fit-content)}.input-container .selected-items .value-tag ::ng-deep .tag-container{max-width:var(--tag-max-width, fit-content)}.input-container .selected-items .selected-count{white-space:nowrap}.input-container .selected-items.measurement-container{visibility:hidden;position:absolute;height:0;overflow:hidden;pointer-events:none}.input-container .overlap-count{font-size:14px;line-height:20px}.input-container .overlap-count ui-tag{display:block}.input-container input{margin-left:6px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.input-container input.unset-margin{margin-top:unset}.input-container input.no-caret{cursor:pointer;caret-color:transparent!important}.add-suggestion{margin:0 5px;color:#000;font-weight:700}.remove-selected{cursor:pointer;margin-right:2px;border-radius:50px;height:fit-content}.remove-selected.large-input-icon{margin-top:10px}.arrow-state{height:24px;cursor:pointer}.arrow-state.large-input-icon{margin-top:10px}.arrow-state.opened{transform:rotateX(180deg)}::ng-deep .autocomplete-wrapper .mat-mdc-form-field{width:100%}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error,::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error svg{color:#cb7b7a}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error{display:flex}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error{display:flex;flex-flow:column;row-gap:4px}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error .errors ui-icon{margin-right:8px}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error .errors{display:flex}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error{color:#e02800!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint.error svg{color:#e02800!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-bottom-align:before{height:0}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint-wrapper{padding:0 0 12px;font-size:12px;line-height:16px;position:relative}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-hint-wrapper .mat-form-field-hint-spacer{display:none}::ng-deep .autocomplete-wrapper .mat-mdc-form-field.hide-bottom-content .mat-mdc-form-field-subscript-wrapper{display:none}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-text-field-wrapper.mdc-text-field--outlined .mdc-notched-outline--upgraded .mdc-floating-label--float-above{top:28px!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-floating-label{top:22px!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-text-field-wrapper{padding-left:12px!important;height:unset!important;max-height:unset!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-focused .mat-mdc-text-field-wrapper .mat-mdc-form-field-flex .mat-mdc-floating-label{color:#276678!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mdc-text-field--outlined:not(.mdc-text-field--disabled).mdc-text-field--focused .mdc-notched-outline__notch{border-bottom:2px solid #276678!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mdc-text-field--outlined:not(.mdc-text-field--disabled).mdc-text-field--focused .mdc-notched-outline__leading{border-left:2px solid #276678!important;border-bottom:2px solid #276678!important;border-top:2px solid #276678!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mdc-text-field--outlined:not(.mdc-text-field--disabled).mdc-text-field--focused .mdc-notched-outline__trailing{border:2px solid #276678!important;border-left:unset!important}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-infix,::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mat-mdc-form-field-flex{min-height:48px!important;max-height:184px!important;overflow-y:auto;overflow-x:hidden;padding:0!important;display:flex;justify-content:center;text-align:center;align-items:center;flex-direction:row;width:100%}::ng-deep .autocomplete-wrapper .mat-mdc-form-field .mdc-line-ripple{display:none!important}::ng-deep .mat-mdc-autocomplete-panel{box-shadow:0 8px 24px 4px #00000014;max-height:312px!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option:hover:not(.mdc-list-item--disabled),::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option:focus:not(.mdc-list-item--disabled),::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.mat-mdc-option-active,::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.mdc-list-item--selected:not(.mat-mdc-option-multiple):not(.mdc-list-item--disabled){background:#e9f0f1!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option{padding-right:32px;padding-left:12px!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .option-image{width:24px;height:24px;margin-right:8px;object-fit:cover;flex-shrink:0}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option ui-icon{display:none;position:absolute;right:0;bottom:calc(50% - 8px);margin:0 10px}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.selected-option{background:#e9f0f1}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.selected-option ui-icon{display:block}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option.mdc-list-item--selected .mdc-list-item__primary-text,::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .mdc-list-item--activated .mdc-list-item__primary-text{color:#000!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .mdc-list-item__primary-text{display:flex;align-items:center}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-option .mat-pseudo-checkbox{display:none}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-optgroup .mat-mdc-optgroup-label{font-weight:700!important}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-optgroup .mat-mdc-optgroup-label .mdc-list-item__primary-text{color:#000;font-size:12px;line-height:16px;font-weight:700}::ng-deep .mat-mdc-autocomplete-panel .mat-mdc-optgroup .mat-mdc-option{padding-left:16px!important}.active-field .mdc-notched-outline__leading{border-left-width:2px;border-top-width:2px;border-bottom-width:2px}.active-field .mdc-notched-outline__notch{border-top-width:2px;border-bottom-width:2px}.active-field .mdc-notched-outline__trailing{border-top-width:2px;border-bottom-width:2px;border-right-width:2px}.loading-option{display:flex}.loading-option .loading-container{display:flex;justify-content:center;align-items:center;width:100%;height:100%;position:absolute;top:0;left:0}.selected-items--below{display:flex;flex-wrap:wrap;align-items:center;gap:4px;margin-top:8px}.selected-items--below ui-tag{margin:0;--ui-tag-max-width: 400px}.selected-items--below .clear-all{background:none;border:none;padding:4px 8px;cursor:pointer;color:#000;font-weight:500;font-size:12px;line-height:16px;text-decoration:underline}.selected-items--below .clear-all:disabled{cursor:not-allowed;opacity:.5}\n"]
1591
+ }]
1592
+ }],
1593
+ ctorParameters: () => [],
1594
+ propDecorators: {
1595
+ itemsList: [{
1596
+ type: i0.Input,
1597
+ args: [{
1598
+ isSignal: true,
1599
+ alias: "itemsList",
1600
+ required: false
1601
+ }]
1602
+ }],
1603
+ suggestionsList: [{
1604
+ type: i0.Input,
1605
+ args: [{
1606
+ isSignal: true,
1607
+ alias: "suggestionsList",
1608
+ required: false
1609
+ }]
1610
+ }],
1611
+ groupsList: [{
1612
+ type: i0.Input,
1613
+ args: [{
1614
+ isSignal: true,
1615
+ alias: "groupsList",
1616
+ required: false
1617
+ }]
1618
+ }],
1619
+ disabled: [{
1620
+ type: i0.Input,
1621
+ args: [{
1622
+ isSignal: true,
1623
+ alias: "disabled",
1624
+ required: false
1625
+ }]
1626
+ }],
1627
+ allowAdd: [{
1628
+ type: i0.Input,
1629
+ args: [{
1630
+ isSignal: true,
1631
+ alias: "allowAdd",
1632
+ required: false
1633
+ }]
1634
+ }],
1635
+ textField: [{
1636
+ type: i0.Input,
1637
+ args: [{
1638
+ isSignal: true,
1639
+ alias: "textField",
1640
+ required: false
1641
+ }]
1642
+ }],
1643
+ valueField: [{
1644
+ type: i0.Input,
1645
+ args: [{
1646
+ isSignal: true,
1647
+ alias: "valueField",
1648
+ required: false
1649
+ }]
1650
+ }],
1651
+ imageField: [{
1652
+ type: i0.Input,
1653
+ args: [{
1654
+ isSignal: true,
1655
+ alias: "imageField",
1656
+ required: false
1657
+ }]
1658
+ }],
1659
+ label: [{
1660
+ type: i0.Input,
1661
+ args: [{
1662
+ isSignal: true,
1663
+ alias: "label",
1664
+ required: false
1665
+ }]
1666
+ }],
1667
+ placeholder: [{
1668
+ type: i0.Input,
1669
+ args: [{
1670
+ isSignal: true,
1671
+ alias: "placeholder",
1672
+ required: false
1673
+ }]
1674
+ }],
1675
+ testId: [{
1676
+ type: i0.Input,
1677
+ args: [{
1678
+ isSignal: true,
1679
+ alias: "testId",
1680
+ required: false
1681
+ }]
1682
+ }],
1683
+ type: [{
1684
+ type: i0.Input,
1685
+ args: [{
1686
+ isSignal: true,
1687
+ alias: "type",
1688
+ required: false
1689
+ }]
1690
+ }],
1691
+ minCharactersSearch: [{
1692
+ type: i0.Input,
1693
+ args: [{
1694
+ isSignal: true,
1695
+ alias: "minCharactersSearch",
1696
+ required: false
1697
+ }]
1698
+ }],
1699
+ variant: [{
1700
+ type: i0.Input,
1701
+ args: [{
1702
+ isSignal: true,
1703
+ alias: "variant",
1704
+ required: true
1705
+ }]
1706
+ }],
1707
+ showBottomContent: [{
1708
+ type: i0.Input,
1709
+ args: [{
1710
+ isSignal: true,
1711
+ alias: "showBottomContent",
1712
+ required: false
1713
+ }]
1714
+ }],
1715
+ required: [{
1716
+ type: i0.Input,
1717
+ args: [{
1718
+ isSignal: true,
1719
+ alias: "required",
1720
+ required: false
1721
+ }]
1722
+ }],
1723
+ virtualScroll: [{
1724
+ type: i0.Input,
1725
+ args: [{
1726
+ isSignal: true,
1727
+ alias: "virtualScroll",
1728
+ required: false
1729
+ }]
1730
+ }],
1731
+ compareWith: [{
1732
+ type: i0.Input,
1733
+ args: [{
1734
+ isSignal: true,
1735
+ alias: "compareWith",
1736
+ required: false
1737
+ }]
1738
+ }],
1739
+ dropdownPanelClass: [{
1740
+ type: i0.Input,
1741
+ args: [{
1742
+ isSignal: true,
1743
+ alias: "dropdownPanelClass",
1744
+ required: false
1745
+ }]
1746
+ }],
1747
+ panelPosition: [{
1748
+ type: i0.Input,
1749
+ args: [{
1750
+ isSignal: true,
1751
+ alias: "panelPosition",
1752
+ required: false
1753
+ }]
1754
+ }],
1755
+ hideSelectedSection: [{
1756
+ type: i0.Input,
1757
+ args: [{
1758
+ isSignal: true,
1759
+ alias: "hideSelectedSection",
1760
+ required: false
1761
+ }]
1762
+ }],
1763
+ userAdditionsGroupLabel: [{
1764
+ type: i0.Input,
1765
+ args: [{
1766
+ isSignal: true,
1767
+ alias: "userAdditionsGroupLabel",
1768
+ required: false
1769
+ }]
1770
+ }],
1771
+ closeOnScroll: [{
1772
+ type: i0.Input,
1773
+ args: [{
1774
+ isSignal: true,
1775
+ alias: "closeOnScroll",
1776
+ required: false
1777
+ }]
1778
+ }],
1779
+ size: [{
1780
+ type: i0.Input,
1781
+ args: [{
1782
+ isSignal: true,
1783
+ alias: "size",
1784
+ required: false
1785
+ }]
1786
+ }],
1787
+ allowUserInput: [{
1788
+ type: i0.Input,
1789
+ args: [{
1790
+ isSignal: true,
1791
+ alias: "allowUserInput",
1792
+ required: false
1793
+ }]
1794
+ }],
1795
+ clearable: [{
1796
+ type: i0.Input,
1797
+ args: [{
1798
+ isSignal: true,
1799
+ alias: "clearable",
1800
+ required: false
1801
+ }]
1802
+ }],
1803
+ maxLength: [{
1804
+ type: i0.Input,
1805
+ args: [{
1806
+ isSignal: true,
1807
+ alias: "maxLength",
1808
+ required: false
1809
+ }]
1810
+ }],
1811
+ dynamicFilterLoading: [{
1812
+ type: i0.Input,
1813
+ args: [{
1814
+ isSignal: true,
1815
+ alias: "dynamicFilterLoading",
1816
+ required: false
1817
+ }]
1818
+ }],
1819
+ dynamicFilteredList: [{
1820
+ type: i0.Input,
1821
+ args: [{
1822
+ isSignal: true,
1823
+ alias: "dynamicFilteredList",
1824
+ required: false
1825
+ }]
1826
+ }],
1827
+ infiniteScroll: [{
1828
+ type: i0.Input,
1829
+ args: [{
1830
+ isSignal: true,
1831
+ alias: "infiniteScroll",
1832
+ required: false
1833
+ }]
1834
+ }],
1835
+ hasMoreOptionsForInfiniteScroll: [{
1836
+ type: i0.Input,
1837
+ args: [{
1838
+ isSignal: true,
1839
+ alias: "hasMoreOptionsForInfiniteScroll",
1840
+ required: false
1841
+ }]
1842
+ }],
1843
+ itemValue: [{
1844
+ type: i0.Input,
1845
+ args: [{
1846
+ isSignal: true,
1847
+ alias: "itemValue",
1848
+ required: false
1849
+ }]
1850
+ }],
1851
+ formErrorConfig: [{
1852
+ type: i0.Input,
1853
+ args: [{
1854
+ isSignal: true,
1855
+ alias: "formErrorConfig",
1856
+ required: false
1857
+ }]
1858
+ }],
1859
+ errors: [{
1860
+ type: i0.Input,
1861
+ args: [{
1862
+ isSignal: true,
1863
+ alias: "errors",
1864
+ required: false
1865
+ }]
1866
+ }],
1867
+ addOptionPosition: [{
1868
+ type: i0.Input,
1869
+ args: [{
1870
+ isSignal: true,
1871
+ alias: "addOptionPosition",
1872
+ required: false
1873
+ }]
1874
+ }],
1875
+ tagsPosition: [{
1876
+ type: i0.Input,
1877
+ args: [{
1878
+ isSignal: true,
1879
+ alias: "tagsPosition",
1880
+ required: false
1881
+ }]
1882
+ }],
1883
+ tagIcon: [{
1884
+ type: i0.Input,
1885
+ args: [{
1886
+ isSignal: true,
1887
+ alias: "tagIcon",
1888
+ required: false
1889
+ }]
1890
+ }],
1891
+ selectionChange: [{
1892
+ type: i0.Output,
1893
+ args: ["selectionChange"]
1894
+ }],
1895
+ searchTextChange: [{
1896
+ type: i0.Output,
1897
+ args: ["searchTextChange"]
1898
+ }],
1899
+ blur: [{
1900
+ type: i0.Output,
1901
+ args: ["blur"]
1902
+ }],
1903
+ focus: [{
1904
+ type: i0.Output,
1905
+ args: ["focus"]
1906
+ }],
1907
+ scrollViewportBottomReached: [{
1908
+ type: i0.Output,
1909
+ args: ["scrollViewportBottomReached"]
1910
+ }],
1911
+ scrollViewportBottomReachedFiltered: [{
1912
+ type: i0.Output,
1913
+ args: ["scrollViewportBottomReachedFiltered"]
1914
+ }],
1915
+ formFieldElement: [{
1916
+ type: ViewChild,
1917
+ args: ["formField"]
1918
+ }],
1919
+ tagContainer: [{
1920
+ type: ViewChild,
1921
+ args: ["tagContainer"]
1922
+ }],
1923
+ measureElRef: [{
1924
+ type: ViewChild,
1925
+ args: ["measureEl"]
1926
+ }],
1927
+ overflowDir: [{
1928
+ type: ViewChild,
1929
+ args: ["overflow"]
1930
+ }],
1931
+ autocomplete: [{
1932
+ type: ViewChild,
1933
+ args: ["trigger"]
1934
+ }],
1935
+ cdkViewport: [{
1936
+ type: ViewChild,
1937
+ args: [CdkVirtualScrollViewport, { static: false }]
1938
+ }],
1939
+ matAutocomplete: [{
1940
+ type: ViewChild,
1941
+ args: ["autocomplete"]
1942
+ }],
1943
+ matInput: [{
1944
+ type: ViewChild,
1945
+ args: ["matInput"]
1946
+ }],
1947
+ tagSuffix: [{
1948
+ type: i0.ContentChild,
1949
+ args: [i0.forwardRef(() => AutocompleteTagSuffixDirective), { isSignal: true }]
1950
+ }]
1951
+ }
1952
+ });
964
1953
  export { Autocomplete, AutocompleteFilterService, AutocompleteOverflowDetectDirective, AutocompleteTagSuffixDirective, AutocompleteV2Component, AutocompleteV2Utils, AutocompleteValueManager, DropdownVariation };
965
- //# sourceMappingURL=testgorilla-tgo-ui-components-autocomplete-v2.mjs.map
1954
+
1955
+ //# sourceMappingURL=testgorilla-tgo-ui-components-autocomplete-v2.mjs.map