@koobiq/components 20.4.1 → 21.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 (771) hide show
  1. package/accordion/accordion-trigger.scss +3 -10
  2. package/accordion/accordion.scss +4 -6
  3. package/actions-panel/actions-panel-container.scss +45 -1
  4. package/alert/alert.component.scss +3 -2
  5. package/app-switcher/_app-switcher-theme.scss +0 -4
  6. package/app-switcher/app-switcher-dropdown-app.scss +3 -2
  7. package/app-switcher/app-switcher-dropdown-site.scss +2 -1
  8. package/app-switcher/{kbq-app-switcher-list-item.scss → app-switcher-list-item.scss} +18 -4
  9. package/app-switcher/app-switcher-tokens.scss +15 -0
  10. package/app-switcher/app-switcher.scss +14 -4
  11. package/autocomplete/autocomplete.scss +7 -6
  12. package/badge/badge.component.scss +5 -8
  13. package/breadcrumbs/breadcrumbs.scss +25 -10
  14. package/button/_button-base.scss +30 -7
  15. package/button/_button-theme.scss +16 -0
  16. package/button/button-group.scss +7 -0
  17. package/button/button-tokens.scss +0 -2
  18. package/button/button.scss +34 -2
  19. package/button-toggle/_button-toggle-theme.scss +7 -2
  20. package/button-toggle/button-toggle.scss +65 -15
  21. package/checkbox/_checkbox-theme.scss +4 -3
  22. package/checkbox/checkbox.scss +3 -6
  23. package/clamped-text/clamped-text.scss +6 -2
  24. package/code-block/code-block-tokens.scss +0 -224
  25. package/code-block/code-block.scss +20 -9
  26. package/content-panel/content-panel-aside.scss +3 -2
  27. package/content-panel/content-panel-container.scss +37 -0
  28. package/content-panel/content-panel.scss +4 -3
  29. package/core/highlight/_highlight-theme.scss +3 -1
  30. package/core/option/action-container.scss +2 -2
  31. package/core/option/action.scss +2 -1
  32. package/core/option/option.scss +2 -1
  33. package/core/pop-up/_pop-up.scss +0 -37
  34. package/core/selection/pseudo-checkbox/pseudo-checkbox.scss +5 -10
  35. package/core/styles/_core.scss +3 -0
  36. package/core/styles/_koobiq-theme.scss +5 -6
  37. package/core/styles/common/_animation.scss +44 -16
  38. package/core/styles/common/_groups-mixins.scss +21 -19
  39. package/core/styles/common/_groups.scss +4 -32
  40. package/core/styles/common/_index.scss +0 -2
  41. package/core/styles/common/_link.scss +117 -0
  42. package/core/styles/common/_list.scss +0 -26
  43. package/core/styles/common/_overlay.scss +8 -10
  44. package/core/styles/common/_rtl.scss +0 -14
  45. package/core/styles/common/_select.scss +33 -15
  46. package/core/styles/common/_squircle.scss +63 -0
  47. package/core/styles/common/_tokens.scss +0 -11
  48. package/core/styles/common/_vendor-prefixes.scss +0 -20
  49. package/core/styles/functions/_timing.scss +0 -22
  50. package/core/styles/theming/_scrollbar-theme.scss +6 -1
  51. package/core/styles/theming/_theming.scss +13 -65
  52. package/core/styles/typography/_index.scss +0 -1
  53. package/core/styles/typography/_typography.scss +0 -143
  54. package/core/styles/visual/_body.scss +1 -6
  55. package/core/styles/visual/_layout.scss +0 -12
  56. package/datepicker/calendar-body.scss +3 -1
  57. package/datepicker/calendar-header.scss +0 -1
  58. package/datepicker/datepicker-content.scss +33 -1
  59. package/datepicker/datepicker-toggle.scss +0 -38
  60. package/dl/dl-tokens.scss +10 -0
  61. package/dl/dl.scss +113 -13
  62. package/dropdown/_dropdown-theme.scss +4 -16
  63. package/dropdown/dropdown-item.scss +4 -10
  64. package/dropdown/dropdown.scss +2 -1
  65. package/empty-state/_empty-state-theme.scss +10 -4
  66. package/empty-state/empty-state-tokens.scss +4 -4
  67. package/empty-state/empty-state.scss +4 -0
  68. package/fesm2022/koobiq-components-accordion.mjs +347 -229
  69. package/fesm2022/koobiq-components-accordion.mjs.map +1 -1
  70. package/fesm2022/koobiq-components-actions-panel.mjs +302 -187
  71. package/fesm2022/koobiq-components-actions-panel.mjs.map +1 -1
  72. package/fesm2022/koobiq-components-alert.mjs +39 -39
  73. package/fesm2022/koobiq-components-alert.mjs.map +1 -1
  74. package/fesm2022/koobiq-components-app-switcher.mjs +677 -367
  75. package/fesm2022/koobiq-components-app-switcher.mjs.map +1 -1
  76. package/fesm2022/koobiq-components-autocomplete.mjs +620 -253
  77. package/fesm2022/koobiq-components-autocomplete.mjs.map +1 -1
  78. package/fesm2022/koobiq-components-badge.mjs +46 -48
  79. package/fesm2022/koobiq-components-badge.mjs.map +1 -1
  80. package/fesm2022/koobiq-components-breadcrumbs.mjs +221 -169
  81. package/fesm2022/koobiq-components-breadcrumbs.mjs.map +1 -1
  82. package/fesm2022/koobiq-components-button-toggle.mjs +565 -196
  83. package/fesm2022/koobiq-components-button-toggle.mjs.map +1 -1
  84. package/fesm2022/koobiq-components-button.mjs +332 -116
  85. package/fesm2022/koobiq-components-button.mjs.map +1 -1
  86. package/fesm2022/koobiq-components-checkbox.mjs +172 -132
  87. package/fesm2022/koobiq-components-checkbox.mjs.map +1 -1
  88. package/fesm2022/koobiq-components-clamped-text.mjs +165 -158
  89. package/fesm2022/koobiq-components-clamped-text.mjs.map +1 -1
  90. package/fesm2022/koobiq-components-code-block.mjs +755 -601
  91. package/fesm2022/koobiq-components-code-block.mjs.map +1 -1
  92. package/fesm2022/koobiq-components-content-panel.mjs +260 -143
  93. package/fesm2022/koobiq-components-content-panel.mjs.map +1 -1
  94. package/fesm2022/koobiq-components-core.mjs +4342 -1595
  95. package/fesm2022/koobiq-components-core.mjs.map +1 -1
  96. package/fesm2022/koobiq-components-datepicker.mjs +1713 -1606
  97. package/fesm2022/koobiq-components-datepicker.mjs.map +1 -1
  98. package/fesm2022/koobiq-components-divider.mjs +73 -36
  99. package/fesm2022/koobiq-components-divider.mjs.map +1 -1
  100. package/fesm2022/koobiq-components-dl.mjs +447 -89
  101. package/fesm2022/koobiq-components-dl.mjs.map +1 -1
  102. package/fesm2022/koobiq-components-dropdown.mjs +703 -599
  103. package/fesm2022/koobiq-components-dropdown.mjs.map +1 -1
  104. package/fesm2022/koobiq-components-dynamic-translation.mjs +20 -20
  105. package/fesm2022/koobiq-components-dynamic-translation.mjs.map +1 -1
  106. package/fesm2022/koobiq-components-ellipsis-center.mjs +46 -31
  107. package/fesm2022/koobiq-components-ellipsis-center.mjs.map +1 -1
  108. package/fesm2022/koobiq-components-empty-state.mjs +116 -60
  109. package/fesm2022/koobiq-components-empty-state.mjs.map +1 -1
  110. package/fesm2022/koobiq-components-file-upload.mjs +550 -290
  111. package/fesm2022/koobiq-components-file-upload.mjs.map +1 -1
  112. package/fesm2022/koobiq-components-filter-bar.mjs +2810 -2538
  113. package/fesm2022/koobiq-components-filter-bar.mjs.map +1 -1
  114. package/fesm2022/koobiq-components-flag.mjs +79 -24
  115. package/fesm2022/koobiq-components-flag.mjs.map +1 -1
  116. package/fesm2022/koobiq-components-form-field.mjs +389 -525
  117. package/fesm2022/koobiq-components-form-field.mjs.map +1 -1
  118. package/fesm2022/koobiq-components-icon.mjs +366 -136
  119. package/fesm2022/koobiq-components-icon.mjs.map +1 -1
  120. package/fesm2022/koobiq-components-inline-edit.mjs +429 -212
  121. package/fesm2022/koobiq-components-inline-edit.mjs.map +1 -1
  122. package/fesm2022/koobiq-components-input.mjs +601 -459
  123. package/fesm2022/koobiq-components-input.mjs.map +1 -1
  124. package/fesm2022/koobiq-components-link-deprecated.mjs +196 -0
  125. package/fesm2022/koobiq-components-link-deprecated.mjs.map +1 -0
  126. package/fesm2022/koobiq-components-link.mjs +328 -125
  127. package/fesm2022/koobiq-components-link.mjs.map +1 -1
  128. package/fesm2022/koobiq-components-list.mjs +583 -433
  129. package/fesm2022/koobiq-components-list.mjs.map +1 -1
  130. package/fesm2022/koobiq-components-loader-overlay.mjs +167 -68
  131. package/fesm2022/koobiq-components-loader-overlay.mjs.map +1 -1
  132. package/fesm2022/koobiq-components-markdown.mjs +55 -78
  133. package/fesm2022/koobiq-components-markdown.mjs.map +1 -1
  134. package/fesm2022/koobiq-components-modal.mjs +853 -475
  135. package/fesm2022/koobiq-components-modal.mjs.map +1 -1
  136. package/fesm2022/koobiq-components-navbar.mjs +895 -556
  137. package/fesm2022/koobiq-components-navbar.mjs.map +1 -1
  138. package/fesm2022/koobiq-components-notification-center.mjs +680 -310
  139. package/fesm2022/koobiq-components-notification-center.mjs.map +1 -1
  140. package/fesm2022/koobiq-components-overflow-items.mjs +46 -64
  141. package/fesm2022/koobiq-components-overflow-items.mjs.map +1 -1
  142. package/fesm2022/koobiq-components-popover.mjs +684 -285
  143. package/fesm2022/koobiq-components-popover.mjs.map +1 -1
  144. package/fesm2022/koobiq-components-progress-bar.mjs +87 -33
  145. package/fesm2022/koobiq-components-progress-bar.mjs.map +1 -1
  146. package/fesm2022/koobiq-components-progress-spinner.mjs +52 -43
  147. package/fesm2022/koobiq-components-progress-spinner.mjs.map +1 -1
  148. package/fesm2022/koobiq-components-radio.mjs +450 -231
  149. package/fesm2022/koobiq-components-radio.mjs.map +1 -1
  150. package/fesm2022/koobiq-components-resizer.mjs +127 -21
  151. package/fesm2022/koobiq-components-resizer.mjs.map +1 -1
  152. package/fesm2022/koobiq-components-scrollbar-deprecated.mjs +299 -0
  153. package/fesm2022/koobiq-components-scrollbar-deprecated.mjs.map +1 -0
  154. package/fesm2022/koobiq-components-scrollbar.mjs +745 -222
  155. package/fesm2022/koobiq-components-scrollbar.mjs.map +1 -1
  156. package/fesm2022/koobiq-components-search-expandable.mjs +288 -126
  157. package/fesm2022/koobiq-components-search-expandable.mjs.map +1 -1
  158. package/fesm2022/koobiq-components-select.mjs +883 -693
  159. package/fesm2022/koobiq-components-select.mjs.map +1 -1
  160. package/fesm2022/koobiq-components-sidebar.mjs +207 -88
  161. package/fesm2022/koobiq-components-sidebar.mjs.map +1 -1
  162. package/fesm2022/koobiq-components-sidepanel.mjs +689 -296
  163. package/fesm2022/koobiq-components-sidepanel.mjs.map +1 -1
  164. package/fesm2022/koobiq-components-skeleton.mjs +815 -41
  165. package/fesm2022/koobiq-components-skeleton.mjs.map +1 -1
  166. package/fesm2022/koobiq-components-split-button.mjs +109 -88
  167. package/fesm2022/koobiq-components-split-button.mjs.map +1 -1
  168. package/fesm2022/koobiq-components-splitter-deprecated.mjs +591 -0
  169. package/fesm2022/koobiq-components-splitter-deprecated.mjs.map +1 -0
  170. package/fesm2022/koobiq-components-splitter.mjs +890 -501
  171. package/fesm2022/koobiq-components-splitter.mjs.map +1 -1
  172. package/fesm2022/koobiq-components-table.mjs +63 -49
  173. package/fesm2022/koobiq-components-table.mjs.map +1 -1
  174. package/fesm2022/koobiq-components-tabs.mjs +1062 -603
  175. package/fesm2022/koobiq-components-tabs.mjs.map +1 -1
  176. package/fesm2022/koobiq-components-tags.mjs +886 -733
  177. package/fesm2022/koobiq-components-tags.mjs.map +1 -1
  178. package/fesm2022/koobiq-components-textarea.mjs +213 -185
  179. package/fesm2022/koobiq-components-textarea.mjs.map +1 -1
  180. package/fesm2022/koobiq-components-time-range.mjs +299 -147
  181. package/fesm2022/koobiq-components-time-range.mjs.map +1 -1
  182. package/fesm2022/koobiq-components-timepicker.mjs +233 -245
  183. package/fesm2022/koobiq-components-timepicker.mjs.map +1 -1
  184. package/fesm2022/koobiq-components-timezone.mjs +344 -142
  185. package/fesm2022/koobiq-components-timezone.mjs.map +1 -1
  186. package/fesm2022/koobiq-components-title.mjs +229 -145
  187. package/fesm2022/koobiq-components-title.mjs.map +1 -1
  188. package/fesm2022/koobiq-components-toast.mjs +486 -165
  189. package/fesm2022/koobiq-components-toast.mjs.map +1 -1
  190. package/fesm2022/koobiq-components-toggle.mjs +177 -130
  191. package/fesm2022/koobiq-components-toggle.mjs.map +1 -1
  192. package/fesm2022/koobiq-components-tooltip.mjs +657 -214
  193. package/fesm2022/koobiq-components-tooltip.mjs.map +1 -1
  194. package/fesm2022/koobiq-components-top-bar.mjs +61 -32
  195. package/fesm2022/koobiq-components-top-bar.mjs.map +1 -1
  196. package/fesm2022/koobiq-components-tree-select.mjs +719 -488
  197. package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
  198. package/fesm2022/koobiq-components-tree.mjs +1506 -558
  199. package/fesm2022/koobiq-components-tree.mjs.map +1 -1
  200. package/fesm2022/koobiq-components-username.mjs +290 -135
  201. package/fesm2022/koobiq-components-username.mjs.map +1 -1
  202. package/file-upload/dropzone.scss +31 -3
  203. package/file-upload/file-upload-tokens.scss +2 -22
  204. package/file-upload/file-upload.scss +6 -0
  205. package/file-upload/multiple-file-upload.component.scss +14 -12
  206. package/file-upload/single-file-upload.component.scss +3 -2
  207. package/filter-bar/filters.scss +7 -0
  208. package/filter-bar/pipes/base-pipe.scss +3 -3
  209. package/filter-bar/pipes/pipe-date.scss +8 -1
  210. package/flag/flag-tokens.scss +22 -0
  211. package/flag/flag.scss +34 -21
  212. package/form-field/{_fiedset-theme.scss → _fieldset-theme.scss} +1 -5
  213. package/form-field/_form-field-theme.scss +4 -9
  214. package/form-field/cleaner.scss +3 -1
  215. package/form-field/fieldset.scss +3 -4
  216. package/form-field/form-field.scss +26 -21
  217. package/form-field/password-toggle.scss +3 -1
  218. package/icon/_icon-button-theme.scss +7 -0
  219. package/icon/_icon-theme.scss +10 -7
  220. package/icon/icon-button.scss +0 -2
  221. package/icon/icon-tokens.scss +12 -9
  222. package/inline-edit/inline-edit.scss +40 -54
  223. package/input/input.scss +4 -0
  224. package/link/{_link-theme.scss → deprecated/_link-theme.scss} +11 -6
  225. package/link/deprecated/link-tokens.scss +27 -0
  226. package/link/link-tokens.scss +6 -25
  227. package/link/link.scss +137 -0
  228. package/list/list.scss +3 -2
  229. package/loader-overlay/_loader-overlay-theme.scss +19 -10
  230. package/loader-overlay/loader-overlay-tokens.scss +0 -2
  231. package/loader-overlay/loader-overlay.scss +7 -1
  232. package/markdown/_markdown-theme.scss +16 -0
  233. package/markdown/markdown-tokens.scss +5 -0
  234. package/markdown/markdown.scss +2 -1
  235. package/modal/_modal-animation.scss +23 -14
  236. package/modal/modal-tokens.scss +2 -1
  237. package/modal/modal.scss +35 -31
  238. package/navbar/_navbar-item_horizontal.scss +8 -6
  239. package/navbar/_navbar-item_vertical.scss +18 -6
  240. package/navbar/_navbar-theme.scss +9 -1
  241. package/navbar/navbar-brand.scss +8 -6
  242. package/navbar/navbar-divider.scss +1 -1
  243. package/navbar/navbar-item.scss +8 -9
  244. package/navbar/navbar-toggle.scss +3 -3
  245. package/navbar/navbar-tokens.scss +14 -0
  246. package/navbar/navbar.scss +1 -2
  247. package/navbar/vertical-navbar.scss +2 -2
  248. package/notification-center/_notification-center-theme.scss +11 -6
  249. package/notification-center/notification-center-tokens.scss +33 -0
  250. package/notification-center/notification-center.scss +58 -20
  251. package/notification-center/notification-item.scss +15 -6
  252. package/package.json +112 -81
  253. package/popover/popover-tokens.scss +0 -2
  254. package/popover/popover.scss +41 -19
  255. package/prebuilt-themes/theme.css +1 -1
  256. package/progress-bar/_progress-bar-theme.scss +20 -3
  257. package/progress-bar/progress-bar-tokens.scss +3 -0
  258. package/progress-bar/progress-bar.scss +36 -8
  259. package/progress-spinner/progress-spinner.scss +4 -3
  260. package/radio/_radio-theme.scss +21 -4
  261. package/radio/radio-tokens.scss +7 -3
  262. package/radio/radio.scss +55 -8
  263. package/schematics/collection.json +399 -7
  264. package/schematics/migrations/accordion-state-saving-default/README.md +60 -0
  265. package/schematics/migrations/accordion-state-saving-default/data.js +75 -0
  266. package/schematics/migrations/accordion-state-saving-default/index.js +60 -0
  267. package/schematics/migrations/accordion-state-saving-default/schema.json +15 -0
  268. package/schematics/migrations/actions-panel-overlay-container/README.md +35 -0
  269. package/schematics/migrations/actions-panel-overlay-container/data.js +47 -0
  270. package/schematics/migrations/actions-panel-overlay-container/index.js +54 -0
  271. package/schematics/migrations/actions-panel-overlay-container/schema.json +15 -0
  272. package/schematics/migrations/alert-signals/README.md +13 -7
  273. package/schematics/migrations/alert-signals/data.js +3 -0
  274. package/schematics/migrations/alert-signals/index.js +70 -203
  275. package/schematics/migrations/angular-animations-removal/README.md +46 -0
  276. package/schematics/migrations/angular-animations-removal/data.js +150 -0
  277. package/schematics/migrations/angular-animations-removal/index.js +20 -0
  278. package/schematics/migrations/angular-animations-removal/schema.json +15 -0
  279. package/schematics/migrations/app-switcher-signals/README.md +88 -0
  280. package/schematics/migrations/app-switcher-signals/data.js +136 -0
  281. package/schematics/migrations/app-switcher-signals/index.js +365 -0
  282. package/schematics/migrations/app-switcher-signals/schema.json +20 -0
  283. package/schematics/migrations/autocomplete-panel-width-auto/README.md +2 -2
  284. package/schematics/migrations/autocomplete-panel-width-auto/index.js +1 -1
  285. package/schematics/migrations/autocomplete-signals/README.md +92 -0
  286. package/schematics/migrations/autocomplete-signals/data.js +149 -0
  287. package/schematics/migrations/autocomplete-signals/index.js +706 -0
  288. package/schematics/migrations/autocomplete-signals/schema.json +20 -0
  289. package/schematics/migrations/badge-signals/README.md +77 -0
  290. package/schematics/migrations/badge-signals/data.js +109 -0
  291. package/schematics/migrations/badge-signals/index.js +693 -0
  292. package/schematics/migrations/badge-signals/schema.json +20 -0
  293. package/schematics/migrations/button-state-and-styles/README.md +129 -0
  294. package/schematics/migrations/button-state-and-styles/data.js +136 -0
  295. package/schematics/migrations/button-state-and-styles/index.js +220 -0
  296. package/schematics/migrations/button-state-and-styles/schema.json +20 -0
  297. package/schematics/migrations/button-supported-colors/README.md +73 -0
  298. package/schematics/migrations/button-supported-colors/data.js +106 -0
  299. package/schematics/migrations/button-supported-colors/index.js +260 -0
  300. package/schematics/migrations/button-supported-colors/schema.json +20 -0
  301. package/schematics/migrations/button-toggle-signals-and-aria/README.md +137 -0
  302. package/schematics/migrations/button-toggle-signals-and-aria/data.js +200 -0
  303. package/schematics/migrations/button-toggle-signals-and-aria/index.js +496 -0
  304. package/schematics/migrations/button-toggle-signals-and-aria/schema.json +20 -0
  305. package/schematics/migrations/button-truncation/README.md +110 -0
  306. package/schematics/migrations/button-truncation/data.js +88 -0
  307. package/schematics/migrations/button-truncation/index.js +269 -0
  308. package/schematics/migrations/button-truncation/schema.json +20 -0
  309. package/schematics/migrations/checkbox-signals/README.md +76 -0
  310. package/schematics/migrations/checkbox-signals/data.js +114 -0
  311. package/schematics/migrations/checkbox-signals/index.js +634 -0
  312. package/schematics/migrations/checkbox-signals/schema.json +20 -0
  313. package/schematics/migrations/clamped-text-disclosure/README.md +62 -0
  314. package/schematics/migrations/clamped-text-disclosure/data.js +101 -0
  315. package/schematics/migrations/clamped-text-disclosure/index.js +59 -0
  316. package/schematics/migrations/clamped-text-disclosure/schema.json +15 -0
  317. package/schematics/migrations/code-block-signals/README.md +84 -0
  318. package/schematics/migrations/code-block-signals/data.js +121 -0
  319. package/schematics/migrations/code-block-signals/index.js +700 -0
  320. package/schematics/migrations/code-block-signals/schema.json +20 -0
  321. package/schematics/migrations/color-signals/README.md +46 -0
  322. package/schematics/migrations/color-signals/data.js +131 -0
  323. package/schematics/migrations/color-signals/index.js +19 -0
  324. package/schematics/migrations/color-signals/schema.json +20 -0
  325. package/schematics/migrations/core-mixins-removal/README.md +20 -0
  326. package/schematics/migrations/core-mixins-removal/data.js +27 -0
  327. package/schematics/migrations/core-mixins-removal/index.js +17 -0
  328. package/schematics/migrations/core-mixins-removal/schema.json +15 -0
  329. package/schematics/migrations/css-selectors/README.md +2 -2
  330. package/schematics/migrations/css-selectors/index.js +1 -1
  331. package/schematics/migrations/datepicker-signals/README.md +24 -0
  332. package/schematics/migrations/datepicker-signals/data.js +49 -0
  333. package/schematics/migrations/datepicker-signals/index.js +17 -0
  334. package/schematics/migrations/datepicker-signals/schema.json +15 -0
  335. package/schematics/migrations/deprecated-icons/README.md +2 -2
  336. package/schematics/migrations/deprecated-icons/index.js +1 -1
  337. package/schematics/migrations/design-tokens-v4/README.md +75 -0
  338. package/schematics/migrations/design-tokens-v4/index.js +59 -0
  339. package/schematics/migrations/design-tokens-v4/schema.json +15 -0
  340. package/schematics/migrations/divider-signals-and-aria/README.md +47 -0
  341. package/schematics/migrations/divider-signals-and-aria/data.js +62 -0
  342. package/schematics/migrations/divider-signals-and-aria/index.js +211 -0
  343. package/schematics/migrations/divider-signals-and-aria/schema.json +15 -0
  344. package/schematics/migrations/dl-attribute-coercion/README.md +59 -0
  345. package/schematics/migrations/dl-attribute-coercion/data.js +85 -0
  346. package/schematics/migrations/dl-attribute-coercion/index.js +161 -0
  347. package/schematics/migrations/dl-attribute-coercion/schema.json +15 -0
  348. package/schematics/migrations/dl-standalone-names/README.md +49 -0
  349. package/schematics/migrations/dl-standalone-names/data.js +44 -0
  350. package/schematics/migrations/dl-standalone-names/index.js +321 -0
  351. package/schematics/migrations/dl-standalone-names/schema.json +20 -0
  352. package/schematics/migrations/dropdown-demote-overlay/README.md +137 -0
  353. package/schematics/migrations/dropdown-demote-overlay/data.js +84 -0
  354. package/schematics/migrations/dropdown-demote-overlay/index.js +288 -0
  355. package/schematics/migrations/dropdown-demote-overlay/schema.json +20 -0
  356. package/schematics/migrations/dropdown-signals/README.md +83 -0
  357. package/schematics/migrations/dropdown-signals/data.js +152 -0
  358. package/schematics/migrations/dropdown-signals/index.js +19 -0
  359. package/schematics/migrations/dropdown-signals/schema.json +20 -0
  360. package/schematics/migrations/empty-state-error-color/README.md +84 -0
  361. package/schematics/migrations/empty-state-error-color/data.js +85 -0
  362. package/schematics/migrations/empty-state-error-color/index.js +71 -0
  363. package/schematics/migrations/empty-state-error-color/schema.json +15 -0
  364. package/schematics/migrations/empty-state-size-attr/README.md +2 -2
  365. package/schematics/migrations/empty-state-size-attr/index.js +1 -1
  366. package/schematics/migrations/file-upload-cva-and-primitives/README.md +70 -0
  367. package/schematics/migrations/file-upload-cva-and-primitives/data.js +97 -0
  368. package/schematics/migrations/file-upload-cva-and-primitives/index.js +60 -0
  369. package/schematics/migrations/file-upload-cva-and-primitives/schema.json +15 -0
  370. package/schematics/migrations/file-upload-deprecated-outputs/README.md +90 -0
  371. package/schematics/migrations/file-upload-deprecated-outputs/data.js +20 -0
  372. package/schematics/migrations/file-upload-deprecated-outputs/index.js +70 -0
  373. package/schematics/migrations/file-upload-deprecated-outputs/schema.json +20 -0
  374. package/schematics/migrations/filter-bar-rename-action/README.md +183 -0
  375. package/schematics/migrations/filter-bar-rename-action/data.js +151 -0
  376. package/schematics/migrations/filter-bar-rename-action/index.js +177 -0
  377. package/schematics/migrations/filter-bar-rename-action/schema.json +20 -0
  378. package/schematics/migrations/filter-bar-signals/README.md +27 -16
  379. package/schematics/migrations/filter-bar-signals/data.js +1 -2
  380. package/schematics/migrations/filter-bar-signals/index.js +100 -195
  381. package/schematics/migrations/filter-bar-state-saving-default/README.md +53 -0
  382. package/schematics/migrations/filter-bar-state-saving-default/data.js +87 -0
  383. package/schematics/migrations/filter-bar-state-saving-default/index.js +61 -0
  384. package/schematics/migrations/filter-bar-state-saving-default/schema.json +15 -0
  385. package/schematics/migrations/flag-inner-html/README.md +67 -0
  386. package/schematics/migrations/flag-inner-html/data.js +58 -0
  387. package/schematics/migrations/flag-inner-html/index.js +61 -0
  388. package/schematics/migrations/flag-inner-html/schema.json +15 -0
  389. package/schematics/migrations/form-field-signals/README.md +125 -0
  390. package/schematics/migrations/form-field-signals/data.js +288 -0
  391. package/schematics/migrations/form-field-signals/index.js +382 -0
  392. package/schematics/migrations/form-field-signals/schema.json +20 -0
  393. package/schematics/migrations/icon-semantics-and-api/README.md +65 -0
  394. package/schematics/migrations/icon-semantics-and-api/data.js +97 -0
  395. package/schematics/migrations/icon-semantics-and-api/index.js +64 -0
  396. package/schematics/migrations/icon-semantics-and-api/schema.json +15 -0
  397. package/schematics/migrations/icons-replacement/README.md +5 -5
  398. package/schematics/migrations/icons-replacement/index.js +1 -1
  399. package/schematics/migrations/inline-edit-a11y-and-types/README.md +82 -0
  400. package/schematics/migrations/inline-edit-a11y-and-types/data.js +117 -0
  401. package/schematics/migrations/inline-edit-a11y-and-types/index.js +97 -0
  402. package/schematics/migrations/inline-edit-a11y-and-types/schema.json +20 -0
  403. package/schematics/migrations/input-number-surface/README.md +140 -0
  404. package/schematics/migrations/input-number-surface/data.js +135 -0
  405. package/schematics/migrations/input-number-surface/index.js +292 -0
  406. package/schematics/migrations/input-number-surface/schema.json +20 -0
  407. package/schematics/migrations/input-signals/README.md +20 -0
  408. package/schematics/migrations/input-signals/data.js +30 -0
  409. package/schematics/migrations/input-signals/index.js +17 -0
  410. package/schematics/migrations/input-signals/schema.json +15 -0
  411. package/schematics/migrations/link-deprecated-path/README.md +144 -0
  412. package/schematics/migrations/link-deprecated-path/index.js +19 -0
  413. package/schematics/migrations/link-deprecated-path/schema.json +20 -0
  414. package/schematics/migrations/link-signals/README.md +71 -0
  415. package/schematics/migrations/link-signals/data.js +116 -0
  416. package/schematics/migrations/link-signals/index.js +415 -0
  417. package/schematics/migrations/link-signals/schema.json +20 -0
  418. package/schematics/migrations/list-signals/README.md +22 -0
  419. package/schematics/migrations/list-signals/data.js +35 -0
  420. package/schematics/migrations/list-signals/index.js +17 -0
  421. package/schematics/migrations/list-signals/schema.json +15 -0
  422. package/schematics/migrations/list-tree-multiple-input/README.md +105 -0
  423. package/schematics/migrations/list-tree-multiple-input/data.js +74 -0
  424. package/schematics/migrations/list-tree-multiple-input/index.js +221 -0
  425. package/schematics/migrations/list-tree-multiple-input/schema.json +20 -0
  426. package/schematics/migrations/loader-overlay-signals/README.md +62 -0
  427. package/schematics/migrations/loader-overlay-signals/data.js +101 -0
  428. package/schematics/migrations/loader-overlay-signals/index.js +697 -0
  429. package/schematics/migrations/loader-overlay-signals/schema.json +20 -0
  430. package/schematics/migrations/loader-overlay-size-attr/README.md +2 -2
  431. package/schematics/migrations/loader-overlay-size-attr/index.js +1 -1
  432. package/schematics/migrations/locale-configuration-providers/README.md +163 -0
  433. package/schematics/migrations/locale-configuration-providers/data.js +257 -0
  434. package/schematics/migrations/locale-configuration-providers/index.js +294 -0
  435. package/schematics/migrations/locale-configuration-providers/schema.json +20 -0
  436. package/schematics/migrations/mandatory-peer-dependencies/README.md +70 -0
  437. package/schematics/migrations/mandatory-peer-dependencies/index.js +42 -0
  438. package/schematics/migrations/mandatory-peer-dependencies/schema.json +15 -0
  439. package/schematics/migrations/markdown-signals/README.md +58 -0
  440. package/schematics/migrations/markdown-signals/data.js +79 -0
  441. package/schematics/migrations/markdown-signals/index.js +639 -0
  442. package/schematics/migrations/markdown-signals/schema.json +20 -0
  443. package/schematics/migrations/modal-dialog-semantics/README.md +106 -0
  444. package/schematics/migrations/modal-dialog-semantics/data.js +110 -0
  445. package/schematics/migrations/modal-dialog-semantics/index.js +58 -0
  446. package/schematics/migrations/modal-dialog-semantics/schema.json +15 -0
  447. package/schematics/migrations/modal-signals/README.md +88 -0
  448. package/schematics/migrations/modal-signals/data.js +132 -0
  449. package/schematics/migrations/modal-signals/index.js +19 -0
  450. package/schematics/migrations/modal-signals/schema.json +20 -0
  451. package/schematics/migrations/navbar-signals-and-aria/README.md +111 -0
  452. package/schematics/migrations/navbar-signals-and-aria/data.js +198 -0
  453. package/schematics/migrations/navbar-signals-and-aria/index.js +568 -0
  454. package/schematics/migrations/navbar-signals-and-aria/schema.json +20 -0
  455. package/schematics/migrations/new-icons-pack/README.md +10 -10
  456. package/schematics/migrations/new-icons-pack/index.js +1 -1
  457. package/schematics/migrations/notification-center-signals/README.md +67 -0
  458. package/schematics/migrations/notification-center-signals/data.js +66 -0
  459. package/schematics/migrations/notification-center-signals/index.js +61 -0
  460. package/schematics/migrations/notification-center-signals/schema.json +15 -0
  461. package/schematics/migrations/option-signals/README.md +37 -0
  462. package/schematics/migrations/option-signals/data.js +86 -0
  463. package/schematics/migrations/option-signals/index.js +19 -0
  464. package/schematics/migrations/option-signals/schema.json +20 -0
  465. package/schematics/migrations/popover-leave-delay/README.md +51 -0
  466. package/schematics/migrations/popover-leave-delay/data.js +61 -0
  467. package/schematics/migrations/popover-leave-delay/index.js +54 -0
  468. package/schematics/migrations/popover-leave-delay/schema.json +15 -0
  469. package/schematics/migrations/progress-bar-percentage-and-aria/README.md +54 -0
  470. package/schematics/migrations/progress-bar-percentage-and-aria/data.js +76 -0
  471. package/schematics/migrations/progress-bar-percentage-and-aria/index.js +58 -0
  472. package/schematics/migrations/progress-bar-percentage-and-aria/schema.json +15 -0
  473. package/schematics/migrations/progress-spinner-signals/README.md +72 -0
  474. package/schematics/migrations/progress-spinner-signals/data.js +83 -0
  475. package/schematics/migrations/progress-spinner-signals/index.js +694 -0
  476. package/schematics/migrations/progress-spinner-signals/schema.json +20 -0
  477. package/schematics/migrations/query-list-signals/README.md +32 -0
  478. package/schematics/migrations/query-list-signals/data.js +70 -0
  479. package/schematics/migrations/query-list-signals/index.js +17 -0
  480. package/schematics/migrations/query-list-signals/schema.json +15 -0
  481. package/schematics/migrations/radio-signals-and-aria/README.md +82 -0
  482. package/schematics/migrations/radio-signals-and-aria/data.js +163 -0
  483. package/schematics/migrations/radio-signals-and-aria/index.js +39 -0
  484. package/schematics/migrations/radio-signals-and-aria/schema.json +20 -0
  485. package/schematics/migrations/read-state-dwell-handlers/README.md +125 -0
  486. package/schematics/migrations/read-state-dwell-handlers/data.js +45 -0
  487. package/schematics/migrations/read-state-dwell-handlers/index.js +215 -0
  488. package/schematics/migrations/read-state-dwell-handlers/schema.json +20 -0
  489. package/schematics/migrations/scrollbar-deprecated-path/README.md +128 -0
  490. package/schematics/migrations/scrollbar-deprecated-path/index.js +20 -0
  491. package/schematics/migrations/scrollbar-deprecated-path/schema.json +20 -0
  492. package/schematics/migrations/select-signal-inputs/README.md +61 -0
  493. package/schematics/migrations/select-signal-inputs/data.js +99 -0
  494. package/schematics/migrations/select-signal-inputs/index.js +57 -0
  495. package/schematics/migrations/select-signal-inputs/schema.json +15 -0
  496. package/schematics/migrations/sidepanel-non-modal-behavior/README.md +57 -0
  497. package/schematics/migrations/sidepanel-non-modal-behavior/data.js +111 -0
  498. package/schematics/migrations/sidepanel-non-modal-behavior/index.js +57 -0
  499. package/schematics/migrations/sidepanel-non-modal-behavior/schema.json +15 -0
  500. package/schematics/migrations/signal-inputs-subclasses/README.md +28 -0
  501. package/schematics/migrations/signal-inputs-subclasses/data.js +69 -0
  502. package/schematics/migrations/signal-inputs-subclasses/index.js +17 -0
  503. package/schematics/migrations/signal-inputs-subclasses/schema.json +15 -0
  504. package/schematics/migrations/split-button-optional-disabled/README.md +47 -0
  505. package/schematics/migrations/split-button-optional-disabled/data.js +53 -0
  506. package/schematics/migrations/split-button-optional-disabled/index.js +57 -0
  507. package/schematics/migrations/split-button-optional-disabled/schema.json +15 -0
  508. package/schematics/migrations/splitter-deprecated-path/README.md +136 -0
  509. package/schematics/migrations/splitter-deprecated-path/index.js +20 -0
  510. package/schematics/migrations/splitter-deprecated-path/schema.json +20 -0
  511. package/schematics/migrations/state-saving-default/README.md +67 -0
  512. package/schematics/migrations/state-saving-default/data.js +88 -0
  513. package/schematics/migrations/state-saving-default/index.js +62 -0
  514. package/schematics/migrations/state-saving-default/schema.json +15 -0
  515. package/schematics/migrations/table-cell-content/README.md +55 -0
  516. package/schematics/migrations/table-cell-content/data.js +66 -0
  517. package/schematics/migrations/table-cell-content/index.js +66 -0
  518. package/schematics/migrations/table-cell-content/schema.json +15 -0
  519. package/schematics/migrations/tabs-signals-and-aria/README.md +93 -0
  520. package/schematics/migrations/tabs-signals-and-aria/data.js +139 -0
  521. package/schematics/migrations/tabs-signals-and-aria/index.js +65 -0
  522. package/schematics/migrations/tabs-signals-and-aria/schema.json +15 -0
  523. package/schematics/migrations/tag-list-cleaner/README.md +58 -0
  524. package/schematics/migrations/tag-list-cleaner/data.js +42 -0
  525. package/schematics/migrations/tag-list-cleaner/index.js +196 -0
  526. package/schematics/migrations/tag-list-cleaner/schema.json +20 -0
  527. package/schematics/migrations/tag-slots/README.md +41 -0
  528. package/schematics/migrations/tag-slots/index.js +190 -0
  529. package/schematics/migrations/tag-slots/schema.json +20 -0
  530. package/schematics/migrations/tags-signals/README.md +85 -0
  531. package/schematics/migrations/tags-signals/data.js +103 -0
  532. package/schematics/migrations/tags-signals/index.js +673 -0
  533. package/schematics/migrations/tags-signals/schema.json +20 -0
  534. package/schematics/migrations/textarea-signals/README.md +72 -0
  535. package/schematics/migrations/textarea-signals/data.js +121 -0
  536. package/schematics/migrations/textarea-signals/index.js +379 -0
  537. package/schematics/migrations/textarea-signals/schema.json +20 -0
  538. package/schematics/migrations/time-range-title-for/README.md +164 -0
  539. package/schematics/migrations/time-range-title-for/data.js +139 -0
  540. package/schematics/migrations/time-range-title-for/index.js +163 -0
  541. package/schematics/migrations/time-range-title-for/schema.json +20 -0
  542. package/schematics/migrations/timepicker-signals/README.md +78 -0
  543. package/schematics/migrations/timepicker-signals/data.js +82 -0
  544. package/schematics/migrations/timepicker-signals/index.js +709 -0
  545. package/schematics/migrations/timepicker-signals/schema.json +20 -0
  546. package/schematics/migrations/timezone-grouping-utils/README.md +73 -0
  547. package/schematics/migrations/timezone-grouping-utils/data.js +101 -0
  548. package/schematics/migrations/timezone-grouping-utils/index.js +64 -0
  549. package/schematics/migrations/timezone-grouping-utils/schema.json +15 -0
  550. package/schematics/migrations/title-encapsulation/README.md +49 -0
  551. package/schematics/migrations/title-encapsulation/data.js +69 -0
  552. package/schematics/migrations/title-encapsulation/index.js +57 -0
  553. package/schematics/migrations/title-encapsulation/schema.json +15 -0
  554. package/schematics/migrations/toast-stack-and-defaults/README.md +102 -0
  555. package/schematics/migrations/toast-stack-and-defaults/data.js +79 -0
  556. package/schematics/migrations/toast-stack-and-defaults/index.js +53 -0
  557. package/schematics/migrations/toast-stack-and-defaults/schema.json +15 -0
  558. package/schematics/migrations/tooltip-pointer-events-and-types/README.md +53 -0
  559. package/schematics/migrations/tooltip-pointer-events-and-types/data.js +89 -0
  560. package/schematics/migrations/tooltip-pointer-events-and-types/index.js +60 -0
  561. package/schematics/migrations/tooltip-pointer-events-and-types/schema.json +15 -0
  562. package/schematics/migrations/top-bar-container-selectors/README.md +111 -0
  563. package/schematics/migrations/top-bar-container-selectors/data.js +56 -0
  564. package/schematics/migrations/top-bar-container-selectors/index.js +84 -0
  565. package/schematics/migrations/top-bar-container-selectors/schema.json +20 -0
  566. package/schematics/migrations/tree-select-signals/README.md +61 -0
  567. package/schematics/migrations/tree-select-signals/data.js +106 -0
  568. package/schematics/migrations/tree-select-signals/index.js +58 -0
  569. package/schematics/migrations/tree-select-signals/schema.json +15 -0
  570. package/schematics/migrations/tree-signals/README.md +82 -0
  571. package/schematics/migrations/tree-signals/data.js +123 -0
  572. package/schematics/migrations/tree-signals/index.js +54 -0
  573. package/schematics/migrations/tree-signals/schema.json +15 -0
  574. package/schematics/migrations/tree-state-saving-default/README.md +66 -0
  575. package/schematics/migrations/tree-state-saving-default/data.js +78 -0
  576. package/schematics/migrations/tree-state-saving-default/index.js +60 -0
  577. package/schematics/migrations/tree-state-saving-default/schema.json +15 -0
  578. package/schematics/migrations/username-pipe-injection/README.md +59 -0
  579. package/schematics/migrations/username-pipe-injection/data.js +78 -0
  580. package/schematics/migrations/username-pipe-injection/index.js +58 -0
  581. package/schematics/migrations/username-pipe-injection/schema.json +15 -0
  582. package/schematics/migrations/v20-upgrade/README.md +36 -16
  583. package/schematics/migrations/v20-upgrade/data.js +124 -77
  584. package/schematics/migrations/v20-upgrade/index.js +6 -213
  585. package/schematics/migrations/v21-upgrade/README.md +271 -0
  586. package/schematics/migrations/v21-upgrade/data.js +1371 -0
  587. package/schematics/migrations/v21-upgrade/index.js +94 -0
  588. package/schematics/migrations/v21-upgrade/schema.json +20 -0
  589. package/schematics/migrations/zoneless-change-detection/README.md +30 -0
  590. package/schematics/migrations/zoneless-change-detection/data.js +29 -0
  591. package/schematics/migrations/zoneless-change-detection/index.js +20 -0
  592. package/schematics/migrations/zoneless-change-detection/schema.json +15 -0
  593. package/schematics/migrations.json +392 -2
  594. package/schematics/ng-add/index.js +515 -14
  595. package/schematics/ng-add/schema.json +15 -0
  596. package/schematics/utils/deprecated-path-migration.js +61 -0
  597. package/schematics/utils/package-config.js +9 -105
  598. package/scrollbar/{_scrollbar-component-theme.scss → deprecated/_scrollbar-component-theme.scss} +1 -1
  599. package/scrollbar/{scrollbar.component.scss → deprecated/scrollbar.component.scss} +1 -1
  600. package/scrollbar/native-scrollbar.scss +68 -0
  601. package/scrollbar/scrollbar-tokens.scss +13 -22
  602. package/scrollbar/scrollbar-track.scss +94 -0
  603. package/scrollbar/scrollbar-viewport.scss +33 -0
  604. package/scrollbar/scrollbar.scss +24 -0
  605. package/search-expandable/search-expandable-tokens.scss +4 -0
  606. package/search-expandable/search-expandable.scss +4 -2
  607. package/select/_select-theme.scss +3 -16
  608. package/select/select.scss +0 -6
  609. package/sidebar/sidebar.scss +20 -0
  610. package/sidepanel/_sidepanel-theme.scss +1 -1
  611. package/sidepanel/sidepanel-tokens.scss +7 -1
  612. package/sidepanel/sidepanel.scss +41 -5
  613. package/skeleton/skeleton-presets.scss +350 -0
  614. package/skeleton/skeleton-tokens.scss +127 -0
  615. package/skeleton/skeleton.scss +53 -45
  616. package/split-button/_split-button-theme.scss +4 -4
  617. package/split-button/split-button.scss +2 -6
  618. package/splitter/{_splitter-theme.scss → deprecated/_splitter-theme.scss} +1 -1
  619. package/splitter/deprecated/splitter.scss +51 -0
  620. package/splitter/splitter-tokens.scss +19 -0
  621. package/splitter/splitter.scss +148 -28
  622. package/table/_table-theme.scss +13 -12
  623. package/table/table-tokens.scss +8 -0
  624. package/table/table.scss +47 -22
  625. package/tabs/_tabs-common.scss +14 -14
  626. package/tabs/_tabs-theme.scss +4 -5
  627. package/tabs/tab-body.scss +49 -1
  628. package/tabs/tab-header.scss +2 -1
  629. package/tags/tag-list.scss +4 -0
  630. package/tags/tag.scss +19 -1
  631. package/time-range/time-range.scss +9 -0
  632. package/timezone/timezone-option.component.scss +4 -7
  633. package/timezone/timezone-select.component.scss +3 -0
  634. package/toast/_toast-theme.scss +1 -4
  635. package/toast/toast-container.component.scss +19 -13
  636. package/toast/toast-tokens.scss +12 -6
  637. package/toast/toast.component.scss +42 -19
  638. package/toggle/_toggle-theme.scss +4 -10
  639. package/toggle/toggle.scss +67 -26
  640. package/tooltip/_tooltip-theme.scss +7 -1
  641. package/tooltip/tooltip-tokens.scss +1 -2
  642. package/tooltip/tooltip.scss +55 -9
  643. package/top-bar/top-bar-tokens.scss +13 -2
  644. package/top-bar/top-bar.scss +24 -19
  645. package/tree/_tree-theme.scss +0 -1
  646. package/tree/toggle.scss +5 -9
  647. package/tree/tree-option.scss +2 -4
  648. package/tree/tree-tokens.scss +2 -1
  649. package/tree/tree.scss +3 -5
  650. package/tree-select/_tree-select-theme.scss +4 -15
  651. package/tree-select/tree-select-tokens.scss +16 -0
  652. package/tree-select/tree-select.scss +0 -6
  653. package/{accordion/index.d.ts → types/koobiq-components-accordion.d.ts} +102 -84
  654. package/{actions-panel/index.d.ts → types/koobiq-components-actions-panel.d.ts} +44 -59
  655. package/{alert/index.d.ts → types/koobiq-components-alert.d.ts} +8 -3
  656. package/types/koobiq-components-app-switcher.d.ts +406 -0
  657. package/types/koobiq-components-autocomplete.d.ts +443 -0
  658. package/{badge/index.d.ts → types/koobiq-components-badge.d.ts} +25 -20
  659. package/{breadcrumbs/index.d.ts → types/koobiq-components-breadcrumbs.d.ts} +97 -46
  660. package/types/koobiq-components-button-toggle.d.ts +340 -0
  661. package/types/koobiq-components-button.d.ts +296 -0
  662. package/types/koobiq-components-checkbox.d.ts +172 -0
  663. package/types/koobiq-components-clamped-text.d.ts +184 -0
  664. package/{code-block/index.d.ts → types/koobiq-components-code-block.d.ts} +114 -79
  665. package/{content-panel/index.d.ts → types/koobiq-components-content-panel.d.ts} +81 -25
  666. package/{core/index.d.ts → types/koobiq-components-core.d.ts} +2827 -865
  667. package/{datepicker/index.d.ts → types/koobiq-components-datepicker.d.ts} +161 -116
  668. package/types/koobiq-components-divider.d.ts +43 -0
  669. package/types/koobiq-components-dl.d.ts +235 -0
  670. package/{dropdown/index.d.ts → types/koobiq-components-dropdown.d.ts} +245 -239
  671. package/types/koobiq-components-ellipsis-center.d.ts +85 -0
  672. package/types/koobiq-components-empty-state.d.ts +106 -0
  673. package/{file-upload/index.d.ts → types/koobiq-components-file-upload.d.ts} +214 -107
  674. package/{filter-bar/index.d.ts → types/koobiq-components-filter-bar.d.ts} +410 -495
  675. package/types/koobiq-components-flag.d.ts +68 -0
  676. package/{form-field/index.d.ts → types/koobiq-components-form-field.d.ts} +167 -191
  677. package/types/koobiq-components-icon.d.ts +333 -0
  678. package/{inline-edit/index.d.ts → types/koobiq-components-inline-edit.d.ts} +109 -46
  679. package/types/koobiq-components-input.d.ts +477 -0
  680. package/types/koobiq-components-link-deprecated.d.ts +101 -0
  681. package/types/koobiq-components-link.d.ts +176 -0
  682. package/{list/index.d.ts → types/koobiq-components-list.d.ts} +162 -99
  683. package/types/koobiq-components-loader-overlay.d.ts +101 -0
  684. package/{markdown/index.d.ts → types/koobiq-components-markdown.d.ts} +16 -24
  685. package/types/koobiq-components-modal.d.ts +666 -0
  686. package/types/koobiq-components-navbar.d.ts +569 -0
  687. package/types/koobiq-components-notification-center.d.ts +500 -0
  688. package/{overflow-items/index.d.ts → types/koobiq-components-overflow-items.d.ts} +8 -22
  689. package/types/koobiq-components-popover.d.ts +468 -0
  690. package/types/koobiq-components-progress-bar.d.ts +67 -0
  691. package/{progress-spinner/index.d.ts → types/koobiq-components-progress-spinner.d.ts} +33 -10
  692. package/types/koobiq-components-radio.d.ts +294 -0
  693. package/{resizer/index.d.ts → types/koobiq-components-resizer.d.ts} +37 -2
  694. package/{scrollbar/index.d.ts → types/koobiq-components-scrollbar-deprecated.d.ts} +18 -1
  695. package/types/koobiq-components-scrollbar.d.ts +154 -0
  696. package/types/koobiq-components-search-expandable.d.ts +164 -0
  697. package/{select/index.d.ts → types/koobiq-components-select.d.ts} +360 -167
  698. package/types/koobiq-components-sidebar.d.ts +152 -0
  699. package/types/koobiq-components-sidepanel.d.ts +436 -0
  700. package/types/koobiq-components-skeleton.d.ts +234 -0
  701. package/types/koobiq-components-split-button.d.ts +65 -0
  702. package/{splitter/index.d.ts → types/koobiq-components-splitter-deprecated.d.ts} +44 -1
  703. package/types/koobiq-components-splitter.d.ts +406 -0
  704. package/types/koobiq-components-table.d.ts +44 -0
  705. package/types/koobiq-components-tabs.d.ts +888 -0
  706. package/{tags/index.d.ts → types/koobiq-components-tags.d.ts} +249 -133
  707. package/types/koobiq-components-textarea.d.ts +178 -0
  708. package/{time-range/index.d.ts → types/koobiq-components-time-range.d.ts} +135 -62
  709. package/types/koobiq-components-timepicker.d.ts +223 -0
  710. package/types/koobiq-components-timezone.d.ts +266 -0
  711. package/types/koobiq-components-title.d.ts +184 -0
  712. package/types/koobiq-components-toast.d.ts +289 -0
  713. package/types/koobiq-components-toggle.d.ts +121 -0
  714. package/types/koobiq-components-tooltip.d.ts +610 -0
  715. package/types/koobiq-components-top-bar.d.ts +61 -0
  716. package/types/koobiq-components-tree-select.d.ts +667 -0
  717. package/types/koobiq-components-tree.d.ts +1290 -0
  718. package/types/koobiq-components-username.d.ts +340 -0
  719. package/username/_username-theme.scss +35 -0
  720. package/username/username.scss +10 -34
  721. package/app-switcher/index.d.ts +0 -276
  722. package/autocomplete/index.d.ts +0 -286
  723. package/button/index.d.ts +0 -153
  724. package/button-toggle/index.d.ts +0 -162
  725. package/checkbox/index.d.ts +0 -163
  726. package/clamped-text/index.d.ts +0 -146
  727. package/core/styles/_tokens.scss +0 -7
  728. package/core/styles/common/_clearfix.scss +0 -13
  729. package/core/styles/common/_popup.scss +0 -6
  730. package/core/styles/functions/_index.scss +0 -3
  731. package/core/styles/functions/_number.scss +0 -60
  732. package/core/styles/functions/_string.scss +0 -18
  733. package/core/styles/theming/scrollbar-tokens.scss +0 -25
  734. package/core/styles/typography/_typography-utils.scss +0 -84
  735. package/divider/index.d.ts +0 -20
  736. package/dl/index.d.ts +0 -45
  737. package/ellipsis-center/index.d.ts +0 -71
  738. package/empty-state/index.d.ts +0 -45
  739. package/flag/index.d.ts +0 -44
  740. package/icon/index.d.ts +0 -200
  741. package/input/index.d.ts +0 -354
  742. package/link/index.d.ts +0 -56
  743. package/loader-overlay/index.d.ts +0 -57
  744. package/modal/index.d.ts +0 -339
  745. package/navbar/index.d.ts +0 -372
  746. package/notification-center/index.d.ts +0 -323
  747. package/popover/index.d.ts +0 -182
  748. package/prebuilt-themes/dark-theme.css +0 -1
  749. package/prebuilt-themes/light-theme.css +0 -1
  750. package/progress-bar/index.d.ts +0 -31
  751. package/radio/index.d.ts +0 -203
  752. package/search-expandable/index.d.ts +0 -101
  753. package/sidebar/index.d.ts +0 -94
  754. package/sidepanel/index.d.ts +0 -272
  755. package/skeleton/index.d.ts +0 -26
  756. package/split-button/index.d.ts +0 -46
  757. package/table/index.d.ts +0 -25
  758. package/tabs/index.d.ts +0 -677
  759. package/textarea/index.d.ts +0 -138
  760. package/timepicker/index.d.ts +0 -197
  761. package/timezone/index.d.ts +0 -125
  762. package/title/index.d.ts +0 -139
  763. package/toast/index.d.ts +0 -187
  764. package/toggle/index.d.ts +0 -104
  765. package/tooltip/index.d.ts +0 -335
  766. package/top-bar/index.d.ts +0 -33
  767. package/tree/index.d.ts +0 -802
  768. package/tree-select/index.d.ts +0 -475
  769. package/username/index.d.ts +0 -194
  770. /package/{dynamic-translation/index.d.ts → types/koobiq-components-dynamic-translation.d.ts} +0 -0
  771. /package/{index.d.ts → types/koobiq-components.d.ts} +0 -0
@@ -1,59 +1,141 @@
1
1
  import * as i0 from '@angular/core';
2
- import { ChangeDetectionStrategy, Component, input, booleanAttribute, Directive, inject, InjectionToken, ChangeDetectorRef, NgZone, Renderer2, ElementRef, DestroyRef, viewChild, contentChild, TemplateRef, QueryList, contentChildren, EventEmitter, output, numberAttribute, computed, signal, effect, afterNextRender, Input, Output, ContentChildren, ViewChildren, ViewChild, ViewEncapsulation, NgModule } from '@angular/core';
2
+ import { inject, Renderer2, Injectable, ChangeDetectionStrategy, Component, input, booleanAttribute, Directive, InjectionToken, ChangeDetectorRef, NgZone, Injector, ElementRef, DestroyRef, signal, viewChild, contentChild, viewChildren, TemplateRef, contentChildren, QueryList, computed, EventEmitter, output, numberAttribute, linkedSignal, untracked, effect, afterNextRender, ViewEncapsulation, NgModule } from '@angular/core';
3
+ import * as i1$1 from '@koobiq/components/core';
4
+ import { KBQ_WINDOW, KbqOption, KbqAbstractSelect, getSelectAllState, runClearPredicate, KbqComponentColors, ErrorStateMatcher, KBQ_OVERLAY_LAYERS, KBQ_SELECT_SCROLL_STRATEGY, KbqLocaleOverridesDirective, KBQ_SELECT_LOCALE_CONFIGURATION, KbqErrorStateTracker, defaultOffsetY, KBQ_CONNECTED_OVERLAY_BELOW_CLASS, KBQ_CONNECTED_OVERLAY_ABOVE_CLASS, KbqSelectFooter, kbqQueryListFrom, KbqSelectTrigger, KbqSelectMatcher, KbqOptgroup, KbqSelectSearch, KbqSelectSearchEmptyResult, getKbqSelectNonFunctionValueError, kbqSelectAllHandlerTransform, KBQ_PANEL_DEFAULT_MIN_WIDTH, kbqResolvePanelMaxHeightToken, KBQ_A11Y_LOCALE_CONFIGURATION, getKbqSelectDynamicMultipleError, toggleSelectAll, KbqSelectAllEvent, isUndefined, kbqGetElementHeight, DOWN_ARROW, UP_ARROW, LEFT_ARROW, RIGHT_ARROW, ENTER, SPACE, ESCAPE, TAB, HOME, END, PAGE_UP, PAGE_DOWN, isSelectAll, BACKSPACE, DELETE, getKbqSelectNonArrayValueError, runCompareWith, KbqVirtualOption, ActiveDescendantKeyManager, isInput, shouldSelectSearchText, KbqPseudoCheckbox, KBQ_OPTION_PARENT_COMPONENT, KBQ_PARENT_POPUP, kbqSiblingPopupProvider, KbqOptionModule, KbqSelectFooterItem } from '@koobiq/components/core';
5
+ import { SizeXxs } from '@koobiq/design-tokens';
3
6
  import * as i1 from '@koobiq/components/progress-spinner';
4
7
  import { KbqProgressSpinnerModule } from '@koobiq/components/progress-spinner';
5
8
  import { ContentObserver } from '@angular/cdk/observers';
6
9
  import { SharedResizeObserver } from '@angular/cdk/observers/private';
7
- import { Platform, _getFocusedElementPierceShadowDom } from '@angular/cdk/platform';
8
- import { KbqOption, KBQ_WINDOW, KbqAbstractSelect, getKbqSelectDynamicMultipleError, getKbqSelectNonFunctionValueError, getSelectAllState, KbqComponentColors, ErrorStateMatcher, KBQ_SELECT_SCROLL_STRATEGY, KBQ_LOCALE_SERVICE, defaultOffsetY, KBQ_CONNECTED_OVERLAY_BELOW_CLASS, KBQ_CONNECTED_OVERLAY_ABOVE_CLASS, KbqSelectFooter, KbqSelectTrigger, KbqSelectMatcher, KbqOptgroup, KbqSelectSearch, KbqSelectSearchEmptyResult, ruRULocaleData, KBQ_PANEL_DEFAULT_MIN_WIDTH, kbqResolvePanelMaxHeightToken, toggleSelectAll, KbqSelectAllEvent, isUndefined, kbqGetElementHeight, DOWN_ARROW, UP_ARROW, LEFT_ARROW, RIGHT_ARROW, ENTER, SPACE, ESCAPE, TAB, HOME, END, PAGE_UP, PAGE_DOWN, isSelectAll, BACKSPACE, DELETE, getKbqSelectNonArrayValueError, runCompareWith, KbqVirtualOption, ActiveDescendantKeyManager, isInput, shouldSelectSearchText, kbqSelectAnimations, KbqPseudoCheckbox, KBQ_OPTION_PARENT_COMPONENT, KBQ_PARENT_POPUP, kbqSiblingPopupProvider, KbqOptionModule, KbqSelectFooterItem } from '@koobiq/components/core';
10
+ import { Platform, _getEventTarget, _getFocusedElementPierceShadowDom } from '@angular/cdk/platform';
9
11
  import { KbqTooltipTrigger, KbqToolTipModule } from '@koobiq/components/tooltip';
10
12
  import { Subscription, throttleTime, Subject, defer, merge, EMPTY, BehaviorSubject, fromEvent } from 'rxjs';
11
- import { debounceTime, switchMap, startWith, take, filter, map, delay, distinctUntilChanged, auditTime, takeUntil } from 'rxjs/operators';
13
+ import { debounceTime, switchMap, startWith, filter, map, delay, distinctUntilChanged, take, takeUntil, auditTime } from 'rxjs/operators';
12
14
  import { InteractivityChecker, CdkMonitorFocus, A11yModule } from '@angular/cdk/a11y';
13
15
  import { Directionality } from '@angular/cdk/bidi';
14
- import { coerceBooleanProperty } from '@angular/cdk/coercion';
15
16
  import { SelectionModel } from '@angular/cdk/collections';
16
- import { OverlayContainer, CdkOverlayOrigin, CdkConnectedOverlay, OverlayModule } from '@angular/cdk/overlay';
17
+ import { OverlayContainer, CdkConnectedOverlay, CdkOverlayOrigin, OverlayModule } from '@angular/cdk/overlay';
17
18
  import { CdkVirtualForOf, CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
18
19
  import { NgTemplateOutlet } from '@angular/common';
19
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
20
+ import { outputFromObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
20
21
  import { NgForm, FormGroupDirective, NgControl } from '@angular/forms';
21
22
  import { KBQ_FORM_FIELD, KbqCleaner, KbqFormFieldControl, kbqCleanerFactoryProvider, KbqFormFieldModule } from '@koobiq/components/form-field';
22
- import * as i1$1 from '@koobiq/components/icon';
23
+ import * as i2 from '@koobiq/components/icon';
23
24
  import { KbqIconModule } from '@koobiq/components/icon';
24
- import { KbqTag, KbqTagsModule } from '@koobiq/components/tags';
25
- import { SizeXxs } from '@koobiq/design-tokens';
25
+ import { KBQ_SCROLLBAR_OPTIONS, KbqScrollbarViewport } from '@koobiq/components/scrollbar';
26
+ import { KbqTag, KbqTagRemove, KbqTagsModule } from '@koobiq/components/tags';
27
+
28
+ /** Class that reveals the "+N" counter the matcher reserves room for. */
29
+ const KBQ_SELECT_HIDDEN_TEXT_VISIBLE_CLASS = 'kbq-select__match-hidden-text_visible';
30
+ /**
31
+ * Measures how much room the selected values take in a multiple select's trigger.
32
+ *
33
+ * Provided by the select rather than injected globally: it writes into (and reads back from) that
34
+ * select's own trigger element. Kept apart from the component because it is pure DOM geometry with no
35
+ * bearing on the select's state — and because the two measurements it makes have to share a single
36
+ * layout pass, which is easy to lose sight of when they live among the component's other concerns.
37
+ *
38
+ * @docs-private
39
+ */
40
+ class KbqSelectHiddenItemsMeasurer {
41
+ constructor() {
42
+ this.renderer = inject(Renderer2);
43
+ this.window = inject(KBQ_WINDOW);
44
+ }
45
+ /**
46
+ * Measures the trigger against two layouts: one without the "+N" counter and one with it.
47
+ *
48
+ * Both clones are attached before either is read, so the browser resolves layout once for the pair
49
+ * instead of once per clone.
50
+ *
51
+ * @param trigger Trigger element of the select, used both as the source of the clones and as their host.
52
+ */
53
+ measure(trigger) {
54
+ const withoutCounter = this.buildTriggerClone(trigger);
55
+ const withCounter = this.buildTriggerClone(trigger);
56
+ withoutCounter.querySelector('.kbq-select__match-hidden-text')?.remove();
57
+ const counter = withCounter.querySelector('.kbq-select__match-hidden-text');
58
+ if (counter) {
59
+ this.renderer.addClass(counter, KBQ_SELECT_HIDDEN_TEXT_VISIBLE_CLASS);
60
+ }
61
+ this.renderer.appendChild(trigger, withoutCounter);
62
+ this.renderer.appendChild(trigger, withCounter);
63
+ let totalItemsWidth = 0;
64
+ let totalVisibleItemsWidth = 0;
65
+ let visibleItems = 0;
66
+ withoutCounter.querySelectorAll('kbq-tag').forEach((item) => {
67
+ totalItemsWidth += this.getItemWidth(item);
68
+ });
69
+ withCounter.querySelectorAll('kbq-tag').forEach((item) => {
70
+ if (item.offsetTop < item.offsetHeight) {
71
+ totalVisibleItemsWidth += this.getItemWidth(item);
72
+ visibleItems++;
73
+ }
74
+ });
75
+ withoutCounter.remove();
76
+ withCounter.remove();
77
+ return { totalItemsWidth, totalVisibleItemsWidth, visibleItems };
78
+ }
79
+ /**
80
+ * Calculates the width of a single item including margins.
81
+ *
82
+ * The elements measured here are `kbq-tag`s, which are `border-box` and carry horizontal
83
+ * padding. `getComputedStyle().width` resolves to the used content-box width whatever
84
+ * `box-sizing` says, so it dropped that padding from every tag and the matcher believed more
85
+ * tags fit than actually do. `getBoundingClientRect()` is always the border box — the same fix
86
+ * `kbqGetPanelWidthOrigin()` carries.
87
+ */
88
+ getItemWidth(element) {
89
+ const { marginLeft, marginRight } = this.window.getComputedStyle(element);
90
+ return (element.getBoundingClientRect().width +
91
+ (parseFloat(marginLeft) || 0) +
92
+ (parseFloat(marginRight) || 0) +
93
+ parseInt(SizeXxs));
94
+ }
95
+ /** Creates a hidden clone of the trigger element, positioned so that it cannot affect the layout. */
96
+ buildTriggerClone(trigger) {
97
+ const triggerClone = trigger.cloneNode(true);
98
+ this.renderer.setStyle(triggerClone, 'position', 'absolute');
99
+ this.renderer.setStyle(triggerClone, 'visibility', 'hidden');
100
+ this.renderer.setStyle(triggerClone, 'top', '-100%');
101
+ this.renderer.setStyle(triggerClone, 'left', '0');
102
+ this.renderer.setStyle(triggerClone, 'max-width', '100%');
103
+ return triggerClone;
104
+ }
105
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqSelectHiddenItemsMeasurer, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
106
+ /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqSelectHiddenItemsMeasurer }); }
107
+ }
108
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqSelectHiddenItemsMeasurer, decorators: [{
109
+ type: Injectable
110
+ }] });
26
111
 
27
112
  class KbqSelectLoading {
28
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectLoading, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
29
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.30", type: KbqSelectLoading, isStandalone: true, selector: "kbq-select-loading, [kbq-select-loading]", host: { classAttribute: "kbq-select-loading" }, exportAs: ["kbqSelectLoading"], ngImport: i0, template: `
113
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqSelectLoading, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
114
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.25", type: KbqSelectLoading, isStandalone: true, selector: "kbq-select-loading, [kbq-select-loading]", host: { classAttribute: "kbq-select-loading" }, exportAs: ["kbqSelectLoading"], ngImport: i0, template: `
115
+ <!-- Scoped styles rather than the global layout utilities: the fallback has to look right in an
116
+ application that does not ship them. -->
30
117
  <ng-content select="kbq-progress-spinner">
31
- <div class="layout-row layout-margin-top-4xl layout-margin-bottom-4xl layout-align-center-center">
118
+ <div class="kbq-select-loading__spinner">
32
119
  <kbq-progress-spinner [mode]="'indeterminate'" />
33
120
  </div>
34
121
  </ng-content>
35
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: KbqProgressSpinnerModule }, { kind: "component", type: i1.KbqProgressSpinner, selector: "kbq-progress-spinner", inputs: ["id", "value", "mode", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
122
+ `, isInline: true, styles: [".kbq-select-loading__spinner{display:flex;align-items:center;justify-content:center;margin-top:var(--kbq-size-4xl);margin-bottom:var(--kbq-size-4xl)}\n"], dependencies: [{ kind: "ngmodule", type: KbqProgressSpinnerModule }, { kind: "component", type: i1.KbqProgressSpinner, selector: "kbq-progress-spinner", inputs: ["id", "value", "mode", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
36
123
  }
37
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectLoading, decorators: [{
124
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqSelectLoading, decorators: [{
38
125
  type: Component,
39
- args: [{
40
- selector: 'kbq-select-loading, [kbq-select-loading]',
41
- imports: [
126
+ args: [{ selector: 'kbq-select-loading, [kbq-select-loading]', imports: [
42
127
  KbqProgressSpinnerModule
43
- ],
44
- template: `
128
+ ], template: `
129
+ <!-- Scoped styles rather than the global layout utilities: the fallback has to look right in an
130
+ application that does not ship them. -->
45
131
  <ng-content select="kbq-progress-spinner">
46
- <div class="layout-row layout-margin-top-4xl layout-margin-bottom-4xl layout-align-center-center">
132
+ <div class="kbq-select-loading__spinner">
47
133
  <kbq-progress-spinner [mode]="'indeterminate'" />
48
134
  </div>
49
135
  </ng-content>
50
- `,
51
- changeDetection: ChangeDetectionStrategy.OnPush,
52
- host: {
136
+ `, changeDetection: ChangeDetectionStrategy.OnPush, host: {
53
137
  class: 'kbq-select-loading'
54
- },
55
- exportAs: 'kbqSelectLoading'
56
- }]
138
+ }, exportAs: 'kbqSelectLoading', styles: [".kbq-select-loading__spinner{display:flex;align-items:center;justify-content:center;margin-top:var(--kbq-size-4xl);margin-bottom:var(--kbq-size-4xl)}\n"] }]
57
139
  }] });
58
140
  /**
59
141
  * This component renders the error for a Select component.
@@ -63,14 +145,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
63
145
  class KbqSelectError {
64
146
  constructor() {
65
147
  /** Indicates whether styles for pagination controls should be used. */
66
- this.paging = input(false, ...(ngDevMode ? [{ debugName: "paging", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
148
+ this.paging = input(false, { ...(ngDevMode ? { debugName: "paging" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
67
149
  }
68
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectError, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
69
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.30", type: KbqSelectError, isStandalone: true, selector: "kbq-select-error, [kbq-select-error]", inputs: { paging: { classPropertyName: "paging", publicName: "paging", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.kbq-select-error_default": "!paging()", "class.kbq-select-error_paging": "paging()" }, classAttribute: "kbq-select-error" }, exportAs: ["kbqSelectError"], ngImport: i0, template: `
150
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqSelectError, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
151
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.25", type: KbqSelectError, isStandalone: true, selector: "kbq-select-error, [kbq-select-error]", inputs: { paging: { classPropertyName: "paging", publicName: "paging", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.kbq-select-error_default": "!paging()", "class.kbq-select-error_paging": "paging()" }, classAttribute: "kbq-select-error" }, exportAs: ["kbqSelectError"], ngImport: i0, template: `
70
152
  <ng-content />
71
- `, isInline: true, styles: [":host{display:flex;flex-direction:column}:host.kbq-select-error_default{align-items:center;justify-content:center;margin-bottom:var(--kbq-size-3xl);margin-top:var(--kbq-size-3xl)}:host.kbq-select-error_paging{justify-content:start}:host.kbq-select-error_paging ::ng-deep .kbq-select-error__text{padding-left:var(--kbq-size-l)}::ng-deep .kbq-select-error__text{margin-top:var(--kbq-size-xs);margin-bottom:var(--kbq-size-3xs);color:var(--kbq-foreground-error)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
153
+ `, isInline: true, styles: [":host{display:flex;flex-direction:column}:host.kbq-select-error_default{align-items:center;justify-content:center;margin-bottom:var(--kbq-size-3xl);margin-top:var(--kbq-size-3xl)}:host.kbq-select-error_paging{justify-content:start}:host.kbq-select-error_paging ::ng-deep .kbq-select-error__text{padding-left:var(--kbq-size-l)}:host ::ng-deep .kbq-select-error__text{margin-top:var(--kbq-size-xs);margin-bottom:var(--kbq-size-3xs);color:var(--kbq-foreground-error)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
72
154
  }
73
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectError, decorators: [{
155
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqSelectError, decorators: [{
74
156
  type: Component,
75
157
  args: [{ selector: 'kbq-select-error, [kbq-select-error]', template: `
76
158
  <ng-content />
@@ -78,16 +160,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
78
160
  class: 'kbq-select-error',
79
161
  '[class.kbq-select-error_default]': '!paging()',
80
162
  '[class.kbq-select-error_paging]': 'paging()'
81
- }, exportAs: 'kbqSelectError', styles: [":host{display:flex;flex-direction:column}:host.kbq-select-error_default{align-items:center;justify-content:center;margin-bottom:var(--kbq-size-3xl);margin-top:var(--kbq-size-3xl)}:host.kbq-select-error_paging{justify-content:start}:host.kbq-select-error_paging ::ng-deep .kbq-select-error__text{padding-left:var(--kbq-size-l)}::ng-deep .kbq-select-error__text{margin-top:var(--kbq-size-xs);margin-bottom:var(--kbq-size-3xs);color:var(--kbq-foreground-error)}\n"] }]
163
+ }, exportAs: 'kbqSelectError', styles: [":host{display:flex;flex-direction:column}:host.kbq-select-error_default{align-items:center;justify-content:center;margin-bottom:var(--kbq-size-3xl);margin-top:var(--kbq-size-3xl)}:host.kbq-select-error_paging{justify-content:start}:host.kbq-select-error_paging ::ng-deep .kbq-select-error__text{padding-left:var(--kbq-size-l)}:host ::ng-deep .kbq-select-error__text{margin-top:var(--kbq-size-xs);margin-bottom:var(--kbq-size-3xs);color:var(--kbq-foreground-error)}\n"] }]
82
164
  }], propDecorators: { paging: [{ type: i0.Input, args: [{ isSignal: true, alias: "paging", required: false }] }] } });
83
165
  /**
84
166
  * Marks an element as the error text container for a *KbqSelect* component.
85
167
  */
86
168
  class KbqSelectErrorText {
87
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectErrorText, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
88
- /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.30", type: KbqSelectErrorText, isStandalone: true, selector: "[kbq-select-error-text]", host: { classAttribute: "kbq-select-error__text" }, exportAs: ["kbqSelectErrorText"], ngImport: i0 }); }
169
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqSelectErrorText, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
170
+ /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.25", type: KbqSelectErrorText, isStandalone: true, selector: "[kbq-select-error-text]", host: { classAttribute: "kbq-select-error__text" }, exportAs: ["kbqSelectErrorText"], ngImport: i0 }); }
89
171
  }
90
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectErrorText, decorators: [{
172
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqSelectErrorText, decorators: [{
91
173
  type: Directive,
92
174
  args: [{
93
175
  selector: '[kbq-select-error-text]',
@@ -101,12 +183,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
101
183
  * Component that represents the empty state of a select dropdown.
102
184
  */
103
185
  class KbqSelectNoOptions {
104
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectNoOptions, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
105
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.30", type: KbqSelectNoOptions, isStandalone: true, selector: "kbq-select-no-options, [kbq-select-no-options]", host: { classAttribute: "kbq-select-no-options" }, exportAs: ["kbqSelectNoOptions"], ngImport: i0, template: `
186
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqSelectNoOptions, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
187
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.25", type: KbqSelectNoOptions, isStandalone: true, selector: "kbq-select-no-options, [kbq-select-no-options]", host: { classAttribute: "kbq-select-no-options" }, exportAs: ["kbqSelectNoOptions"], ngImport: i0, template: `
106
188
  <ng-content />
107
189
  `, isInline: true, styles: [":host{display:flex;flex-direction:column;align-items:center;justify-content:center;padding-bottom:var(--kbq-size-3xl);padding-top:var(--kbq-size-3xl);color:var(--kbq-foreground-contrast-secondary)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
108
190
  }
109
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectNoOptions, decorators: [{
191
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqSelectNoOptions, decorators: [{
110
192
  type: Component,
111
193
  args: [{ selector: 'kbq-select-no-options, [kbq-select-no-options]', template: `
112
194
  <ng-content />
@@ -152,20 +234,32 @@ class KbqOptionTooltip extends KbqTooltipTrigger {
152
234
  this.resizeSubscription = Subscription.EMPTY;
153
235
  this.contentObserverSubscription = Subscription.EMPTY;
154
236
  this.focusMonitorSubscription = Subscription.EMPTY;
237
+ /**
238
+ * Overrides the tooltip's hoverable default. The overflow hint floats over the neighbouring options of a
239
+ * scrolling list, so a pointer-capturing pane would swallow the click that selects them.
240
+ */
241
+ this.ignoreTooltipPointerEvents = input(true, ...(ngDevMode ? [{ debugName: "ignoreTooltipPointerEvents" }] : /* istanbul ignore next */ []));
242
+ /**
243
+ * The hint repeats text the option had to clip, so `kbqTooltipDisabled="false"` cannot conjure one for an
244
+ * option that fits.
245
+ *
246
+ * @docs-private
247
+ */
248
+ this.derivedDisabledWins = true;
155
249
  }
156
250
  ngAfterViewInit() {
157
251
  super.ngAfterViewInit();
158
252
  this.content = this.option.viewValue;
159
- this.disabled = !this.isOverflown;
253
+ this.setDerivedDisabled(!this.isOverflown);
160
254
  this.resizeSubscription = this.resizeObserver
161
255
  .observe(this.textElement)
162
256
  .pipe(debounceTime(this.debounceInterval))
163
- .subscribe(() => (this.disabled = !this.isOverflown));
257
+ .subscribe(() => this.setDerivedDisabled(!this.isOverflown));
164
258
  this.contentObserverSubscription = this.contentObserver
165
259
  .observe(this.textElement)
166
260
  .pipe(throttleTime(this.debounceInterval))
167
261
  .subscribe(() => {
168
- this.disabled = !this.isOverflown;
262
+ this.setDerivedDisabled(!this.isOverflown);
169
263
  this.content = this.option.viewValue;
170
264
  });
171
265
  this.focusMonitorSubscription = this.focusMonitor
@@ -179,15 +273,15 @@ class KbqOptionTooltip extends KbqTooltipTrigger {
179
273
  super.ngOnDestroy();
180
274
  }
181
275
  handleElementEnter() {
182
- this.disabled = !this.isOverflown;
276
+ this.setDerivedDisabled(!this.isOverflown);
183
277
  }
184
278
  handleElementLeave() {
185
- this.disabled = true;
279
+ this.setDerivedDisabled(true);
186
280
  }
187
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqOptionTooltip, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
188
- /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.30", type: KbqOptionTooltip, isStandalone: true, selector: "kbq-option", host: { listeners: { "mouseenter": "handleElementEnter()", "mouseleave": "handleElementLeave()" } }, usesInheritance: true, ngImport: i0 }); }
281
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqOptionTooltip, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
282
+ /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.25", type: KbqOptionTooltip, isStandalone: true, selector: "kbq-option", inputs: { ignoreTooltipPointerEvents: { classPropertyName: "ignoreTooltipPointerEvents", publicName: "ignoreTooltipPointerEvents", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "handleElementEnter()", "mouseleave": "handleElementLeave()" } }, usesInheritance: true, ngImport: i0 }); }
189
283
  }
190
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqOptionTooltip, decorators: [{
284
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqOptionTooltip, decorators: [{
191
285
  type: Directive,
192
286
  args: [{
193
287
  selector: 'kbq-option',
@@ -196,7 +290,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
196
290
  '(mouseleave)': 'handleElementLeave()'
197
291
  }
198
292
  }]
199
- }], ctorParameters: () => [] });
293
+ }], ctorParameters: () => [], propDecorators: { ignoreTooltipPointerEvents: [{ type: i0.Input, args: [{ isSignal: true, alias: "ignoreTooltipPointerEvents", required: false }] }] } });
200
294
 
201
295
  let nextUniqueId = 0;
202
296
  /** Marks a footer control the consumer has disabled without the `disabled` attribute, which an `a` cannot carry. */
@@ -223,187 +317,59 @@ const delayBeforeDisplayingResultWithoutOptions = 101;
223
317
  /** Minimum time in milliseconds to display the loading state. */
224
318
  const minimumTimeToDisplayLoading = 300;
225
319
  class KbqSelect extends KbqAbstractSelect {
226
- /**
227
- * Controls when the search functionality is displayed based on the number of available options.
228
- *
229
- * Automatically enables search hiding if value provided, even if `defaultOptions.searchMinOptionsThreshold` is provided.
230
- * @default undefined
231
- */
232
- // TODO: Skipped for migration because:
233
- // Accessor inputs cannot be migrated as they are too complex.
234
- set searchMinOptionsThreshold(value) {
235
- this._searchMinOptionsThreshold =
236
- this.resolveSearchMinOptionsThreshold(value) ??
237
- this.resolveSearchMinOptionsThreshold(this.defaultOptions?.searchMinOptionsThreshold);
238
- }
239
- get searchMinOptionsThreshold() {
240
- return this._searchMinOptionsThreshold;
241
- }
242
- /**
243
- * Whether the overlay should have a backdrop.
244
- * When true, clicking the backdrop will close the select.
245
- */
246
- // TODO: Skipped for migration because:
247
- // Accessor inputs cannot be migrated as they are too complex.
248
- get hasBackdrop() {
249
- return this._hasBackdrop;
320
+ /** Reference to the CDK connected overlay directive. */
321
+ get overlayDir() {
322
+ return this.overlayDirQuery();
250
323
  }
251
- set hasBackdrop(value) {
252
- this._hasBackdrop = coerceBooleanProperty(value);
324
+ /** Query list of tags displayed in multiple selection mode. */
325
+ get tags() {
326
+ return this.tagsList();
253
327
  }
254
- /**
255
- * Placeholder text to be shown when no value is selected.
256
- * Displayed in the trigger when the select is closed and no value is selected.
257
- */
258
- // TODO: Skipped for migration because:
259
- // Accessor inputs cannot be migrated as they are too complex.
260
- get placeholder() {
261
- return this._placeholder;
262
- }
263
- set placeholder(value) {
264
- this._placeholder = value;
265
- this.stateChanges.next();
328
+ /** All of the defined select options. */
329
+ get options() {
330
+ return this.optionsList();
266
331
  }
267
- /**
268
- * Whether the select is required. Affects validation and display of placeholder.
269
- */
270
- // TODO: Skipped for migration because:
271
- // Accessor inputs cannot be migrated as they are too complex.
272
- get required() {
273
- return this._required;
332
+ /** Rendered hidden items counter. */
333
+ get hiddenItemsLabel() {
334
+ const template = this.hiddenItemsText() ?? this.localeConfiguration().hiddenItemsText;
335
+ return this.hiddenItemsTextFormatter()(template, this.hiddenItems());
274
336
  }
275
- set required(value) {
276
- this._required = coerceBooleanProperty(value);
277
- this.stateChanges.next();
337
+ /** Label of the "select all" row. Follows the active locale. */
338
+ get selectAllText() {
339
+ return this.localeConfiguration().selectAll;
278
340
  }
279
341
  /**
280
342
  * Whether multiple options can be selected.
281
343
  * Note: This cannot be changed dynamically after initialization.
282
344
  */
283
- // TODO: Skipped for migration because:
284
- // Accessor inputs cannot be migrated as they are too complex.
285
345
  get multiple() {
286
- return this._multiple;
287
- }
288
- set multiple(value) {
289
- if (this.selectionModel) {
290
- throw getKbqSelectDynamicMultipleError();
291
- }
292
- this._multiple = value;
293
- }
294
- /**
295
- * Function to compare the option values with the selected values.
296
- * The first argument is a value from an option.
297
- * The second is a value from the selection.
298
- * Should return true if the values match.
299
- * Defaults to strict equality comparison.
300
- */
301
- // TODO: Skipped for migration because:
302
- // Accessor inputs cannot be migrated as they are too complex.
303
- get compareWith() {
304
- return this._compareWith;
305
- }
306
- set compareWith(fn) {
307
- if (typeof fn !== 'function') {
308
- throw getKbqSelectNonFunctionValueError();
309
- }
310
- this._compareWith = fn;
311
- if (this.selectionModel) {
312
- // A different comparator means the selection could change.
313
- this.initializeSelection();
314
- }
346
+ return this.multipleValue ?? this.multipleInput();
315
347
  }
316
348
  /**
317
349
  * Function for handling the Ctrl + A (select all) keyboard combination.
318
350
  * By default, the internal handler selects all options.
319
- * @param event The keyboard event that triggered the handler.
320
- * @param select Reference to this select component.
351
+ * It is called with the keyboard event that triggered it and a reference to this select component.
321
352
  */
322
- // TODO: Skipped for migration because:
323
- // Accessor inputs cannot be migrated as they are too complex.
324
353
  get selectAllHandler() {
325
- return this._selectAllHandler;
326
- }
327
- set selectAllHandler(fn) {
328
- if (typeof fn !== 'function') {
329
- throw Error('`selectAllHandler` must be a function.');
330
- }
331
- this._selectAllHandler = fn;
332
- }
333
- /** Value of the select control. Can be a single value or array of values for multiple selection. */
334
- // TODO: Skipped for migration because:
335
- // Accessor inputs cannot be migrated as they are too complex.
336
- get value() {
337
- return this._value;
338
- }
339
- set value(newValue) {
340
- if (newValue !== this._value) {
341
- this.writeValue(newValue);
342
- this._value = newValue;
343
- }
354
+ return this.selectAllHandlerInput() ?? this.defaultSelectAllHandler;
344
355
  }
345
- /**
346
- * Unique identifier for the select component.
347
- * Auto-generates an ID if not provided.
348
- */
349
- // TODO: Skipped for migration because:
350
- // Accessor inputs cannot be migrated as they are too complex.
351
- get id() {
352
- return this._id;
353
- }
354
- set id(value) {
355
- this._id = value || this.uid;
356
- this.stateChanges.next();
357
- }
358
- /**
359
- * Sets the tabIndex of the select element.
360
- * Automatically set to -1 when disabled.
361
- */
362
- // TODO: Skipped for migration because:
363
- // Accessor inputs cannot be migrated as they are too complex.
364
356
  get tabIndex() {
365
- return this.disabled ? -1 : this._tabIndex;
366
- }
367
- set tabIndex(value) {
368
- this._tabIndex = value;
357
+ return this.resolvedTabIndex();
369
358
  }
370
- /**
371
- * Whether the select is disabled.
372
- * When disabled, the select cannot be opened and its value cannot be changed.
373
- */
374
- // TODO: Skipped for migration because:
375
- // Accessor inputs cannot be migrated as they are too complex.
376
- get disabled() {
377
- return this._disabled;
378
- }
379
- set disabled(value) {
380
- if (value !== this.disabled) {
381
- this._disabled = value;
382
- if (this.parentFormField) {
383
- Promise.resolve().then(() => {
384
- if (this._disabled) {
385
- this.parentFormField.stopFocusMonitor();
386
- }
387
- else {
388
- this.parentFormField.runFocusMonitor();
389
- }
390
- });
391
- }
392
- // Let the parent form field know to run change detection when the disabled state changes.
393
- this.stateChanges.next();
394
- }
359
+ /** Whether the select panel is currently open. */
360
+ get panelOpen() {
361
+ return this.panelOpenValue();
395
362
  }
396
- /** Whether the select is focused. */
397
- get focused() {
398
- return this._focused || this.panelOpen;
399
- }
400
- set focused(value) {
401
- this._focused = value;
363
+ set panelOpen(value) {
364
+ this.panelOpenValue.set(value);
402
365
  }
403
366
  /** Whether the overlay panel is currently on screen. Part of the `KbqSiblingPopup` contract. */
404
367
  get isAttached() {
405
368
  return this.panelOpen;
406
369
  }
370
+ get scrollbarMode() {
371
+ return this.withVirtualScroll ? 'native' : this.scrollbarOptions.mode;
372
+ }
407
373
  /** Whether the search returned no results. */
408
374
  get isEmptySearchResult() {
409
375
  const search = this.search();
@@ -456,11 +422,31 @@ class KbqSelect extends KbqAbstractSelect {
456
422
  }
457
423
  /**
458
424
  * Whether the cleaner (clear button) should be shown.
425
+ *
459
426
  * @docs-private
460
427
  */
461
428
  get canShowCleaner() {
462
429
  return !!this.cleaner()?.canShow;
463
430
  }
431
+ /**
432
+ * Whether the cleaner still has an option to remove.
433
+ *
434
+ * @docs-private
435
+ */
436
+ get canClear() {
437
+ return !!this.selectionModel?.selected.some((option) => this.shouldClear(option));
438
+ }
439
+ /** Selected options the cleaner removes, in selection order. */
440
+ get clearTargets() {
441
+ return this.selectionModel?.selected.filter((option) => this.shouldClear(option)) ?? [];
442
+ }
443
+ /**
444
+ * Passes the resolved option, so a view recycled by `cdk-virtual-scroll` cannot answer for another
445
+ * item.
446
+ */
447
+ shouldClear(option) {
448
+ return runClearPredicate(this.clearPredicate(), this.resolveSelectedOption(option));
449
+ }
464
450
  /** Returns the currently selected option(s). Single value or array for multiple selection. */
465
451
  get selected() {
466
452
  const selected = this.selectionModel.selected;
@@ -470,24 +456,36 @@ class KbqSelect extends KbqAbstractSelect {
470
456
  }
471
457
  /** Returns the display value for the trigger element. */
472
458
  get triggerValue() {
473
- if (this.empty)
459
+ if (this.empty())
474
460
  return '';
475
461
  return this.resolveSelectedOption(this.selectionModel.selected[0]).viewValue;
476
462
  }
477
463
  /** Returns all selected options in display order. */
478
464
  get triggerValues() {
479
- if (this.empty) {
465
+ if (this.empty()) {
480
466
  return [];
481
467
  }
468
+ // `map` also makes the copy that the in-place `reverse()` below needs: `SelectionModel.selected`
469
+ // is memoised by CDK, and reversing it would reorder the selection itself.
482
470
  const selectedOptions = this.selectionModel.selected.map((option) => this.resolveSelectedOption(option));
483
471
  if (this.isRtl()) {
484
472
  selectedOptions.reverse();
485
473
  }
486
474
  return this.triggerValuesLimit() > 0 ? selectedOptions.slice(0, this.triggerValuesLimit()) : selectedOptions;
487
475
  }
488
- /** Whether no option is currently selected. */
489
- get empty() {
490
- return !!this.selectionModel?.isEmpty();
476
+ /**
477
+ * Whether the tag at `index` is one the trigger actually shows.
478
+ *
479
+ * The trigger renders every selected value and clips the overflow with `overflow: hidden`, so a tag
480
+ * that wrapped past the single line is still in the DOM. Its remove control has to leave the tab order
481
+ * with it, or focus lands on something the user cannot see — and the browser scrolls the clipped list
482
+ * to reveal it, shifting the row that is on screen.
483
+ *
484
+ * @docs-private
485
+ */
486
+ isTriggerValueVisible(index) {
487
+ const visibleTriggerItems = this.visibleTriggerItems();
488
+ return visibleTriggerItems === null || index < visibleTriggerItems;
491
489
  }
492
490
  /** Whether there are no options available. */
493
491
  get noOptions() {
@@ -505,69 +503,115 @@ class KbqSelect extends KbqAbstractSelect {
505
503
  }
506
504
  /** @docs-private */
507
505
  get colorForState() {
508
- if (this.disabled)
506
+ if (this.disabled())
509
507
  return KbqComponentColors.Empty;
510
- return this.invalidState() ? KbqComponentColors.Error : KbqComponentColors.ContrastFade;
508
+ return this.errorState() ? KbqComponentColors.Error : KbqComponentColors.ContrastFade;
511
509
  }
512
510
  /** Whether multiple choice is enabled. True if multiple or multiline mode is active. */
513
511
  get multiSelection() {
514
512
  return this.multiple || this.multiline();
515
513
  }
514
+ /**
515
+ * Id of the `kbq-form-field` label naming this select, when it has one.
516
+ *
517
+ * A `<label for>` does not associate with a custom element, so the relationship is expressed the
518
+ * other way around — from the control to the label.
519
+ *
520
+ * @docs-private
521
+ */
522
+ get ariaLabelledby() {
523
+ return this.parentFormField?.labelId() ?? null;
524
+ }
525
+ /**
526
+ * Accessible name put on the trigger and on the option list.
527
+ *
528
+ * Both a `combobox` and a `listbox` are required to have one, and neither takes its name from its
529
+ * contents — the placeholder is rendered as a plain `<span>`, so it names nothing. Falling back to it
530
+ * keeps the ordinary label-less select named. A form-field label still wins: it names the select
531
+ * through `aria-labelledby`, which takes precedence over `aria-label`.
532
+ *
533
+ * @docs-private
534
+ */
535
+ get resolvedAriaLabel() {
536
+ return this.resolvedAriaLabelValue();
537
+ }
538
+ /**
539
+ * Whether the option list is currently showing something other than options — the loading, error or
540
+ * empty state, or an empty search result.
541
+ *
542
+ * The same container is both the `listbox` and the projection target for those states, and a `listbox`
543
+ * is required to own `option` children. `aria-busy` says the list is still being filled in rather than
544
+ * malformed, and keeps it from being announced as an option list with nothing in it.
545
+ *
546
+ * @docs-private
547
+ */
548
+ get isOptionsListBusy() {
549
+ return this.noOptions && !this.showSelectAll;
550
+ }
516
551
  constructor() {
517
552
  super();
518
553
  this._changeDetectorRef = inject(ChangeDetectorRef);
519
554
  this._ngZone = inject(NgZone);
520
- this._renderer = inject(Renderer2);
555
+ this.injector = inject(Injector);
556
+ this.hiddenItemsMeasurer = inject(KbqSelectHiddenItemsMeasurer);
521
557
  this.interactivityChecker = inject(InteractivityChecker);
522
558
  this.defaultErrorStateMatcher = inject(ErrorStateMatcher);
523
559
  this.elementRef = inject(ElementRef);
524
560
  this.overlayContainer = inject(OverlayContainer);
561
+ this.overlayLayers = inject(KBQ_OVERLAY_LAYERS);
525
562
  this._dir = inject(Directionality, { optional: true });
526
563
  this.parentForm = inject(NgForm, { optional: true });
527
564
  this.parentFormGroup = inject(FormGroupDirective, { optional: true });
528
565
  this.parentFormField = inject(KBQ_FORM_FIELD, { host: true, optional: true });
529
566
  this.ngControl = inject(NgControl, { self: true, optional: true });
530
567
  this.scrollStrategyFactory = inject(KBQ_SELECT_SCROLL_STRATEGY);
531
- this.localeService = inject(KBQ_LOCALE_SERVICE, { optional: true });
568
+ this.carrier = inject(KbqLocaleOverridesDirective, { self: true });
569
+ /** Localized strings of the select, following the active locale. */
570
+ this.localeConfiguration = this.carrier.read('select', KBQ_SELECT_LOCALE_CONFIGURATION);
532
571
  /** @docs-private */
533
572
  this.destroyRef = inject(DestroyRef);
534
573
  this.isBrowser = inject(Platform).isBrowser;
535
574
  this.defaultOptions = inject(KBQ_SELECT_OPTIONS, { optional: true });
575
+ this.scrollbarOptions = inject(KBQ_SCROLLBAR_OPTIONS);
576
+ this.errorStateTracker = new KbqErrorStateTracker(this.defaultErrorStateMatcher, this.ngControl, this.parentFormGroup, this.parentForm);
536
577
  /** Whether the component is in an error state. */
537
- this.errorState = false;
538
- /**
539
- * Emits whenever the component state changes and should cause the parent
540
- * form-field to update. Implemented as part of `KbqFormFieldControl`.
541
- * @docs-private
542
- */
543
- this.stateChanges = new Subject();
578
+ this.errorState = this.errorStateTracker.errorState;
544
579
  /** A name for this control that can be used by `kbq-form-field`. */
545
580
  this.controlType = 'select';
546
- this.hiddenItems = 0;
581
+ /**
582
+ * A `kbq-select` is not a native labelable element, so the form-field's `<label for>` cannot
583
+ * associate with it. The select is named through `aria-labelledby` instead.
584
+ */
585
+ this.isNativeLabelSupported = false;
586
+ this.hiddenItemsCount = signal(0, ...(ngDevMode ? [{ debugName: "hiddenItemsCount" }] : /* istanbul ignore next */ []));
587
+ /** Number of the selected items that do not fit into the trigger. */
588
+ this.hiddenItems = this.hiddenItemsCount.asReadonly();
589
+ /**
590
+ * How many of the rendered tags stay on the trigger's single line.
591
+ *
592
+ * `null` while the answer is unknown — the trigger has not been measured yet, or the measurement found
593
+ * no tag on the first line at all, which a laid-out trigger never does and so means there was no layout
594
+ * to measure. Both cases leave every tag treated as visible.
595
+ */
596
+ this.visibleTriggerItems = signal(null, ...(ngDevMode ? [{ debugName: "visibleTriggerItems" }] : /* istanbul ignore next */ []));
547
597
  /** The cached font-size of the trigger element in pixels. */
548
598
  this.triggerFontSize = 0;
549
599
  /** Previously selected options before the current selection was made. */
550
600
  this.previousSelectionModelSelected = [];
601
+ /** Whether the selection is being set to a written value, which is no selection of the user. */
602
+ this.writingValue = false;
551
603
  /**
552
604
  * Detached copies of the selected options, captured while the option was still rendered.
553
605
  * `cdk-virtual-scroll` recycles option views, so a `KbqOption` kept in `selectionModel` can
554
606
  * silently start carrying another item's value and label — the copy preserves the original ones.
555
607
  */
556
608
  this.selectedOptionCopies = new WeakMap();
557
- /** The value of the select panel's transform-origin property for animations. */
609
+ /** The value of the select panel's transform-origin property. */
558
610
  this.transformOrigin = 'top';
559
- /** Emits when the panel element is finished transforming in. */
611
+ /** Emits once the panel has rendered (`'showing'`) or has been removed (`'void'`). */
560
612
  this.panelDoneAnimatingStream = new Subject();
561
613
  /** Strategy that will be used to handle scrolling while the select panel is open. */
562
614
  this.scrollStrategy = this.scrollStrategyFactory();
563
- /**
564
- * The y-offset of the overlay panel in relation to the trigger.
565
- *
566
- * @deprecated noop. The trigger↔panel gap is now controlled by the `--kbq-connected-overlay-gap` CSS
567
- * variable (transparent padding inside the pane via the `kbq-connected-overlay_below/_above` panel
568
- * classes), not by a physical overlay offset — so setting this has no effect. Will be removed in 21.0.0.
569
- */
570
- this.offsetY = 0;
571
615
  /**
572
616
  * Minimum space to keep between the overlay and the viewport edge.
573
617
  * At least `defaultOffsetY` so CDK's fit check — which runs before the `kbq-connected-overlay_below/_above`
@@ -600,30 +644,41 @@ class KbqSelect extends KbqAbstractSelect {
600
644
  /**
601
645
  * Trigger - is a clickable field to open select dropdown panel
602
646
  */
603
- this.trigger = viewChild('trigger', ...(ngDevMode ? [{ debugName: "trigger" }] : []));
647
+ this.trigger = viewChild('trigger', ...(ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []));
604
648
  /** Reference to the overlay panel element. */
605
- this.panel = viewChild('panel', ...(ngDevMode ? [{ debugName: "panel" }] : []));
649
+ this.panel = viewChild('panel', ...(ngDevMode ? [{ debugName: "panel" }] : /* istanbul ignore next */ []));
606
650
  /** Reference to the container element that holds the options. */
607
651
  this.optionsContainer = viewChild.required('optionsContainer');
652
+ this.scrollbarViewport = viewChild(KbqScrollbarViewport, ...(ngDevMode ? [{ debugName: "scrollbarViewport" }] : /* istanbul ignore next */ []));
653
+ // Virtual scroll projects its own viewport, which is the actual scrolling element.
654
+ this.projectedScrollbarViewport = contentChild(KbqScrollbarViewport, { ...(ngDevMode ? { debugName: "projectedScrollbarViewport" } : /* istanbul ignore next */ {}), descendants: true });
608
655
  /** Reference to the built-in "select all" row, rendered only while `selectAll` is on. */
609
- this.selectAllOption = viewChild(KbqOption, ...(ngDevMode ? [{ debugName: "selectAllOption" }] : []));
656
+ this.selectAllOption = viewChild(KbqOption, ...(ngDevMode ? [{ debugName: "selectAllOption" }] : /* istanbul ignore next */ []));
657
+ this.overlayDirQuery = viewChild(CdkConnectedOverlay, ...(ngDevMode ? [{ debugName: "overlayDirQuery" }] : /* istanbul ignore next */ []));
610
658
  /** Reference to the optional footer element in the panel. */
611
- this.footer = contentChild(KbqSelectFooter, ...(ngDevMode ? [{ debugName: "footer", read: ElementRef }] : [{ read: ElementRef }]));
659
+ this.footer = contentChild(KbqSelectFooter, { ...(ngDevMode ? { debugName: "footer" } : /* istanbul ignore next */ {}), read: ElementRef });
612
660
  /** Reference to the CDK virtual scroll directive for virtual scrolling support. */
613
- this.cdkVirtualForOf = contentChild(CdkVirtualForOf, ...(ngDevMode ? [{ debugName: "cdkVirtualForOf" }] : []));
661
+ this.cdkVirtualForOf = contentChild(CdkVirtualForOf, ...(ngDevMode ? [{ debugName: "cdkVirtualForOf" }] : /* istanbul ignore next */ []));
614
662
  /** Reference to the CDK virtual scroll viewport for tracking scroll position in virtual mode. */
615
- this.virtualScrollViewport = contentChild(CdkVirtualScrollViewport, ...(ngDevMode ? [{ debugName: "virtualScrollViewport" }] : []));
663
+ this.virtualScrollViewport = contentChild(CdkVirtualScrollViewport, ...(ngDevMode ? [{ debugName: "virtualScrollViewport" }] : /* istanbul ignore next */ []));
664
+ this.tagsQuery = viewChildren(KbqTag, ...(ngDevMode ? [{ debugName: "tagsQuery" }] : /* istanbul ignore next */ []));
665
+ this.tagsList = kbqQueryListFrom(this.tagsQuery);
616
666
  /** User-supplied override of the trigger element for custom rendering. */
617
- this.customTrigger = contentChild(KbqSelectTrigger, ...(ngDevMode ? [{ debugName: "customTrigger" }] : []));
667
+ this.customTrigger = contentChild(KbqSelectTrigger, ...(ngDevMode ? [{ debugName: "customTrigger" }] : /* istanbul ignore next */ []));
618
668
  /** User-supplied matcher component for custom value matching logic. */
619
- this.customMatcher = contentChild(KbqSelectMatcher, ...(ngDevMode ? [{ debugName: "customMatcher" }] : []));
669
+ this.customMatcher = contentChild(KbqSelectMatcher, ...(ngDevMode ? [{ debugName: "customMatcher" }] : /* istanbul ignore next */ []));
620
670
  /** Custom template reference for rendering tag content. */
621
- this.customTagTemplateRef = contentChild('kbqSelectTagContent', ...(ngDevMode ? [{ debugName: "customTagTemplateRef", read: TemplateRef }] : [{ read: TemplateRef }]));
671
+ this.customTagTemplateRef = contentChild('kbqSelectTagContent', { ...(ngDevMode ? { debugName: "customTagTemplateRef" } : /* istanbul ignore next */ {}), read: TemplateRef });
622
672
  /**
623
673
  * Reference to the optional cleaner element for clearing selection.
674
+ *
624
675
  * @docs-private
625
676
  */
626
- this.cleaner = contentChild(KbqCleaner, ...(ngDevMode ? [{ debugName: "cleaner", descendants: false }] : [{ descendants: false }]));
677
+ this.cleaner = contentChild(KbqCleaner, { ...(ngDevMode ? { debugName: "cleaner" } : /* istanbul ignore next */ {}), descendants: false });
678
+ this.optionsQuery = contentChildren(KbqOption, { ...(ngDevMode ? { debugName: "optionsQuery" } : /* istanbul ignore next */ {}), descendants: true });
679
+ this.optionsList = kbqQueryListFrom(this.optionsQuery);
680
+ /** Whether `ngAfterContentInit` has run. The options are not settled before that, so nothing reads them. */
681
+ this.contentReady = false;
627
682
  /**
628
683
  * Everything the key manager navigates: the built-in "select all" row first, then `options`.
629
684
  *
@@ -631,48 +686,80 @@ class KbqSelect extends KbqAbstractSelect {
631
686
  * Kept as a separate list rather than folded into `options` because `options` is public API — the
632
687
  * filter-bar pipes, `firstFiltered` and the tallies below all mean "the options the consumer
633
688
  * projected", and a synthetic entry there would quietly corrupt every one of them.
689
+ *
634
690
  * @docs-private
635
691
  */
636
692
  this.navigableOptions = new QueryList();
637
693
  /** All of the defined groups of options. */
638
- this.optionGroups = contentChildren(KbqOptgroup, ...(ngDevMode ? [{ debugName: "optionGroups" }] : []));
694
+ this.optionGroups = contentChildren(KbqOptgroup, ...(ngDevMode ? [{ debugName: "optionGroups" }] : /* istanbul ignore next */ []));
639
695
  /** Reference to the optional search component. */
640
- this.search = contentChild(KbqSelectSearch, ...(ngDevMode ? [{ debugName: "search" }] : []));
696
+ this.search = contentChild(KbqSelectSearch, ...(ngDevMode ? [{ debugName: "search" }] : /* istanbul ignore next */ []));
641
697
  /** Reference to the optional empty search result component. */
642
- this.searchEmpty = contentChild(KbqSelectSearchEmptyResult, ...(ngDevMode ? [{ debugName: "searchEmpty" }] : []));
643
- /** Template string for hidden items text. Supports {{ number }} placeholder. */
644
- // TODO: Skipped for migration because:
645
- // Your application code writes to the input. This prevents migration.
646
- this.hiddenItemsText = '+{{ number }}';
647
- /** Label of the "select all" row. Kept in step with the locale service. */
648
- this.selectAllText = ruRULocaleData.select.selectAll;
698
+ this.searchEmpty = contentChild(KbqSelectSearchEmptyResult, ...(ngDevMode ? [{ debugName: "searchEmpty" }] : /* istanbul ignore next */ []));
699
+ /**
700
+ * Template string for the hidden items counter. Supports the `{{ number }}` placeholder.
701
+ *
702
+ * Takes precedence over the value the locale service provides, and keeps it for the whole lifetime of
703
+ * the select — switching the locale no longer overwrites what the consumer asked for.
704
+ */
705
+ this.hiddenItemsText = input(...(ngDevMode ? [undefined, { debugName: "hiddenItemsText" }] : /* istanbul ignore next */ []));
706
+ /**
707
+ * Formats the hidden items counter.
708
+ *
709
+ * @param hiddenItemsText Template string with the `{{ number }}` placeholder.
710
+ * @param hiddenItems Number of hidden items to display.
711
+ */
712
+ this.hiddenItemsTextFormatter = input((hiddenItemsText, hiddenItems) => hiddenItemsText.replace('{{ number }}', hiddenItems.toString()), ...(ngDevMode ? [{ debugName: "hiddenItemsTextFormatter" }] : /* istanbul ignore next */ []));
713
+ /**
714
+ * Accessible name of the trigger and of the option list.
715
+ *
716
+ * Only needed for a select rendered without a `kbq-form-field` label — with one, the label names both.
717
+ */
718
+ this.ariaLabel = input(null, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
649
719
  /** Determines whether preselected values are displayed. */
650
- this.showPreselectedValues = input(false, ...(ngDevMode ? [{ debugName: "showPreselectedValues" }] : []));
720
+ this.showPreselectedValues = input(false, ...(ngDevMode ? [{ debugName: "showPreselectedValues" }] : /* istanbul ignore next */ []));
651
721
  /**
652
722
  * Specifies the maximum number of trigger values allowed.
653
723
  * This constant limits the size of the trigger values array to ensure performance
654
724
  * and prevent excessive memory usage.
655
725
  * A value of `0` indicates that there is no limit.
656
726
  */
657
- this.triggerValuesLimit = input(0, ...(ngDevMode ? [{ debugName: "triggerValuesLimit" }] : []));
727
+ this.triggerValuesLimit = input(0, ...(ngDevMode ? [{ debugName: "triggerValuesLimit" }] : /* istanbul ignore next */ []));
658
728
  /** Classes to be passed to the select panel. Supports the same syntax as the `[class]` binding. */
659
- this.panelClass = input(undefined, ...(ngDevMode ? [{ debugName: "panelClass" }] : []));
729
+ this.panelClass = input(undefined, ...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
660
730
  /** Classes to be passed to the overlay backdrop. */
661
- this.backdropClass = input('cdk-overlay-transparent-backdrop', ...(ngDevMode ? [{ debugName: "backdropClass" }] : []));
731
+ this.backdropClass = input('cdk-overlay-transparent-backdrop', ...(ngDevMode ? [{ debugName: "backdropClass" }] : /* istanbul ignore next */ []));
732
+ /** Object used to control when error messages are shown. */
733
+ this.errorStateMatcher = input(...(ngDevMode ? [undefined, { debugName: "errorStateMatcher" }] : /* istanbul ignore next */ []));
662
734
  /**
663
735
  * Function used to sort the values in a select in multiple mode.
664
736
  * Follows the same logic as `Array.prototype.sort`.
737
+ *
738
+ * Without one the values are emitted in panel order — the order the options are declared in, not the
739
+ * order they were picked in. A value whose option is not rendered (a `KbqVirtualOption` under virtual
740
+ * scroll or `showPreselectedValues`) has no place in that order and sorts after everything that has.
665
741
  */
666
- this.sortComparator = input(undefined, ...(ngDevMode ? [{ debugName: "sortComparator" }] : []));
742
+ this.sortComparator = input(undefined, ...(ngDevMode ? [{ debugName: "sortComparator" }] : /* istanbul ignore next */ []));
667
743
  /**
668
744
  * Whether to use a multiline matcher or not. Default is false.
669
745
  * When true, allows multiple lines of text in the selected value display.
670
746
  */
671
- this.multiline = input(false, ...(ngDevMode ? [{ debugName: "multiline", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
672
- this._searchMinOptionsThreshold = this.resolveSearchMinOptionsThreshold(this.defaultOptions?.searchMinOptionsThreshold);
747
+ this.multiline = input(false, { ...(ngDevMode ? { debugName: "multiline" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
748
+ /**
749
+ * Controls when the search functionality is displayed based on the number of available options.
750
+ *
751
+ * Automatically enables search hiding if value provided, even if `defaultOptions.searchMinOptionsThreshold` is provided.
752
+ *
753
+ * Accepts `'auto'`, which resolves to `KBQ_SELECT_SEARCH_MIN_OPTIONS_THRESHOLD`; the getter therefore
754
+ * reports the resolved number, never `'auto'`. Defaults to `undefined`.
755
+ */
756
+ this.searchMinOptionsThreshold = computed(() => this.resolveSearchMinOptionsThreshold(this.searchMinOptionsThresholdInput()) ??
757
+ this.resolveSearchMinOptionsThreshold(this.defaultOptions?.searchMinOptionsThreshold), ...(ngDevMode ? [{ debugName: "searchMinOptionsThreshold" }] : /* istanbul ignore next */ []));
758
+ /** @docs-private */
759
+ this.searchMinOptionsThresholdInput = input(undefined, { ...(ngDevMode ? { debugName: "searchMinOptionsThresholdInput" } : /* istanbul ignore next */ {}), alias: 'searchMinOptionsThreshold' });
673
760
  /** Combined stream of all of the child options' change events. */
674
761
  this.optionSelectionChanges = defer(() => {
675
- if (this.options) {
762
+ if (this.contentReady) {
676
763
  return merge(...this.options.map((option) => option.onSelectionChange), this.options.changes.pipe(switchMap((list) => list.length ? merge(...list.map((option) => option.onSelectionChange)) : EMPTY)), this.selectionModel.changed.pipe(startWith(null), switchMap(() => {
677
764
  const optionsSet = new Set(this.options.toArray());
678
765
  const virtualSelected = this.selectionModel.selected.filter((option) => !optionsSet.has(option));
@@ -681,8 +768,10 @@ class KbqSelect extends KbqAbstractSelect {
681
768
  : EMPTY;
682
769
  })));
683
770
  }
684
- return this._ngZone.onStable.asObservable().pipe(take(1), switchMap(() => this.optionSelectionChanges));
771
+ return this.contentInitialized.pipe(switchMap(() => this.optionSelectionChanges));
685
772
  });
773
+ /** Emits once the content queries are resolved, for subscribers that arrive before `options` exist. */
774
+ this.contentInitialized = new Subject();
686
775
  /**
687
776
  * Event emitted when the select panel has been toggled. Emits true when opened, false when closed.
688
777
  * Also serves as the `openedChange` member of the `KbqSiblingPopup` contract — a tooltip sharing
@@ -690,12 +779,18 @@ class KbqSelect extends KbqAbstractSelect {
690
779
  * `ngOnInit`) matters beyond this output's original consumers.
691
780
  */
692
781
  this.openedChange = new EventEmitter();
782
+ /** @docs-private */
783
+ this.openedChangeOutput = outputFromObservable(this.openedChange, { alias: 'openedChange' });
693
784
  /** Event emitted before the select panel starts opening. */
694
785
  this.beforeOpened = output();
695
786
  /** Event emitted when the select has been opened. */
696
787
  this.openedStream = this.openedChange.pipe(filter((o) => o), map(() => { }));
788
+ /** @docs-private */
789
+ this.openedOutput = outputFromObservable(this.openedStream, { alias: 'opened' });
697
790
  /** Event emitted when the select has been closed. */
698
791
  this.closedStream = this.openedChange.pipe(filter((o) => !o), map(() => { }));
792
+ /** @docs-private */
793
+ this.closedOutput = outputFromObservable(this.closedStream, { alias: 'closed' });
699
794
  /** Event emitted when the selected value has been changed by the user. */
700
795
  this.selectionChange = output();
701
796
  /**
@@ -706,6 +801,7 @@ class KbqSelect extends KbqAbstractSelect {
706
801
  /**
707
802
  * Event that emits whenever the raw value of the select changes. This is here primarily
708
803
  * to facilitate the two-way binding for the `value` input.
804
+ *
709
805
  * @docs-private
710
806
  */
711
807
  this.valueChange = output();
@@ -713,12 +809,39 @@ class KbqSelect extends KbqAbstractSelect {
713
809
  * Distance in pixels from the bottom of the options panel at which `scrolledToBottom` fires.
714
810
  * Default `0` — emits only when the panel is fully scrolled to the bottom.
715
811
  */
716
- this.scrolledToBottomOffset = input(0, ...(ngDevMode ? [{ debugName: "scrolledToBottomOffset", transform: numberAttribute }] : [{ transform: numberAttribute }]));
812
+ this.scrolledToBottomOffset = input(0, { ...(ngDevMode ? { debugName: "scrolledToBottomOffset" } : /* istanbul ignore next */ {}), transform: numberAttribute });
717
813
  /** Emits when the options panel is scrolled to (or within `scrolledToBottomOffset` of) the bottom. */
718
814
  this.scrolledToBottom = output();
719
- this._hasBackdrop = false;
720
- this._required = false;
721
- this._multiple = false;
815
+ /**
816
+ * Whether the overlay should have a backdrop.
817
+ * When true, clicking the backdrop will close the select.
818
+ */
819
+ this.hasBackdrop = input(false, { ...(ngDevMode ? { debugName: "hasBackdrop" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
820
+ /**
821
+ * Placeholder text to be shown when no value is selected.
822
+ * Displayed in the trigger when the select is closed and no value is selected.
823
+ */
824
+ this.placeholder = input(...(ngDevMode ? [undefined, { debugName: "placeholder" }] : /* istanbul ignore next */ []));
825
+ /**
826
+ * Whether the select is required. Affects validation and display of placeholder.
827
+ */
828
+ this.required = input(false, { ...(ngDevMode ? { debugName: "required" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
829
+ /** @docs-private */
830
+ this.multipleInput = input(false, { ...(ngDevMode ? { debugName: "multipleInput" } : /* istanbul ignore next */ {}), alias: 'multiple',
831
+ transform: booleanAttribute });
832
+ /**
833
+ * Function to compare the option values with the selected values.
834
+ * The first argument is a value from an option.
835
+ * The second is a value from the selection.
836
+ * Should return true if the values match.
837
+ * Defaults to strict equality comparison.
838
+ */
839
+ this.compareWith = input((o1, o2) => o1 === o2, { ...(ngDevMode ? { debugName: "compareWith" } : /* istanbul ignore next */ {}), transform: (fn) => {
840
+ if (typeof fn !== 'function') {
841
+ throw getKbqSelectNonFunctionValueError();
842
+ }
843
+ return fn;
844
+ } });
722
845
  /**
723
846
  * Factory used to construct a `KbqVirtualOption` for selected values whose
724
847
  * `KbqOption` is not currently rendered (e.g. virtual scroll out of viewport,
@@ -729,12 +852,25 @@ class KbqSelect extends KbqAbstractSelect {
729
852
  * customise per-value `disabled` state or any future `KbqVirtualOption`
730
853
  * fields without adding new `@Input`s.
731
854
  *
732
- * Defaults to `new KbqVirtualOption(value, this.disabled)`, which is correct
855
+ * Defaults to `new KbqVirtualOption(value, this.disabled())`, which is correct
733
856
  * for primitive values where `value` itself is the display label.
734
857
  */
735
- this.virtualOptionFactory = input(...(ngDevMode ? [undefined, { debugName: "virtualOptionFactory" }] : []));
858
+ this.virtualOptionFactory = input(...(ngDevMode ? [undefined, { debugName: "virtualOptionFactory" }] : /* istanbul ignore next */ []));
859
+ /**
860
+ * Decides which selected options the projected `KbqCleaner` removes: return `true` to clear the
861
+ * option, `false` to keep it. Disabled options are kept by default. Bind a stable reference — a new
862
+ * function on every change detection re-runs the predicate over the whole selection.
863
+ *
864
+ * Not consulted by `writeValue` / `reset()`, which always clear everything.
865
+ */
866
+ this.clearPredicate = input(this.defaultOptions?.clearPredicate ?? ((option) => !option.disabled), { ...(ngDevMode ? { debugName: "clearPredicate" } : /* istanbul ignore next */ {}), transform: (fn) => {
867
+ if (typeof fn !== 'function') {
868
+ throw Error('`clearPredicate` must be a function.');
869
+ }
870
+ return fn;
871
+ } });
736
872
  /** When `true`, a repeated Ctrl/Cmd+A deselects all options. Off by default (Ctrl+A only selects). */
737
- this.selectAllToggle = input(false, ...(ngDevMode ? [{ debugName: "selectAllToggle", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
873
+ this.selectAllToggle = input(false, { ...(ngDevMode ? { debugName: "selectAllToggle" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
738
874
  /**
739
875
  * Whether to render the "select all" master checkbox above the options. Multiple selection only.
740
876
  *
@@ -743,26 +879,29 @@ class KbqSelect extends KbqAbstractSelect {
743
879
  * matches. Enabling it also makes Ctrl/Cmd + A a two-way toggle, so the shortcut and the checkbox
744
880
  * never disagree (`selectAllToggle` is implied).
745
881
  */
746
- this.selectAll = input(false, ...(ngDevMode ? [{ debugName: "selectAll", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
882
+ this.selectAll = input(false, { ...(ngDevMode ? { debugName: "selectAll" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
883
+ /** @docs-private */
884
+ this.selectAllHandlerInput = input(undefined, { ...(ngDevMode ? { debugName: "selectAllHandlerInput" } : /* istanbul ignore next */ {}), alias: 'selectAllHandler',
885
+ transform: kbqSelectAllHandlerTransform });
747
886
  /**
748
887
  * Width of the panel. If set to `auto`, the panel will match the trigger width, but will never be
749
888
  * narrower than `panelMinWidth`. If set to null or an empty string, the panel will grow to match the
750
889
  * longest option's text. Any other value is used as an exact width, and `panelMinWidth` is not applied.
751
890
  */
752
- this.panelWidth = input(this.defaultOptions?.panelWidth ?? null, ...(ngDevMode ? [{ debugName: "panelWidth" }] : []));
891
+ this.panelWidth = input(this.defaultOptions?.panelWidth ?? null, ...(ngDevMode ? [{ debugName: "panelWidth" }] : /* istanbul ignore next */ []));
753
892
  /**
754
893
  * Minimum width of the panel in pixels.
755
894
  * If minWidth is larger than window width, it will be ignored.
756
895
  */
757
896
  this.panelMinWidth = input(this.defaultOptions?.panelMinWidth === undefined
758
897
  ? KBQ_PANEL_DEFAULT_MIN_WIDTH
759
- : this.defaultOptions.panelMinWidth, ...(ngDevMode ? [{ debugName: "panelMinWidth", transform: numberAttribute }] : [{ transform: numberAttribute }]));
898
+ : this.defaultOptions.panelMinWidth, { ...(ngDevMode ? { debugName: "panelMinWidth" } : /* istanbul ignore next */ {}), transform: numberAttribute });
760
899
  /**
761
900
  * Maximum width of the panel in pixels. Caps how far the panel grows with its content — it never makes
762
901
  * the panel narrower than the trigger, and never clamps an explicit `panelWidth`.
763
902
  * When null, the `--kbq-panel-size-width-max` token applies.
764
903
  */
765
- this.panelMaxWidth = input(this.defaultOptions?.panelMaxWidth === undefined ? null : this.defaultOptions.panelMaxWidth, ...(ngDevMode ? [{ debugName: "panelMaxWidth", transform: numberAttribute }] : [{ transform: numberAttribute }]));
904
+ this.panelMaxWidth = input(this.defaultOptions?.panelMaxWidth === undefined ? null : this.defaultOptions.panelMaxWidth, { ...(ngDevMode ? { debugName: "panelMaxWidth" } : /* istanbul ignore next */ {}), transform: numberAttribute });
766
905
  /**
767
906
  * Maximum height of the panel's scrollable option list, in pixels. Applied as the
768
907
  * `--kbq-select-panel-size-max-height` custom property on the panel, so it also drives the pinned height
@@ -771,26 +910,75 @@ class KbqSelect extends KbqAbstractSelect {
771
910
  * The search field and the footer sit outside the scrollable area and add to the panel's total height.
772
911
  * When null, the token default (256px) applies.
773
912
  */
774
- this.panelMaxHeight = input(this.defaultOptions?.panelMaxHeight === undefined ? null : this.defaultOptions.panelMaxHeight, ...(ngDevMode ? [{ debugName: "panelMaxHeight", transform: numberAttribute }] : [{ transform: numberAttribute }]));
913
+ this.panelMaxHeight = input(this.defaultOptions?.panelMaxHeight === undefined ? null : this.defaultOptions.panelMaxHeight, { ...(ngDevMode ? { debugName: "panelMaxHeight" } : /* istanbul ignore next */ {}), transform: numberAttribute });
775
914
  /**
776
915
  * `panelMaxHeight` rendered as a CSS length for the `--kbq-select-panel-size-max-height` token.
777
916
  * A non-finite value (e.g. `null`) leaves the stylesheet default in place.
917
+ *
778
918
  * @docs-private
779
919
  */
780
- this.panelMaxHeightToken = computed(() => kbqResolvePanelMaxHeightToken(this.panelMaxHeight()), ...(ngDevMode ? [{ debugName: "panelMaxHeightToken" }] : []));
781
- this._tabIndex = 0;
782
- this._disabled = false;
783
- /** Whether the select panel is currently open. */
784
- this.panelOpen = false;
785
- this._focused = false;
920
+ this.panelMaxHeightToken = computed(() => kbqResolvePanelMaxHeightToken(this.panelMaxHeight()), ...(ngDevMode ? [{ debugName: "panelMaxHeightToken" }] : /* istanbul ignore next */ []));
921
+ /** @docs-private */
922
+ this.valueInput = input(undefined, { ...(ngDevMode ? { debugName: "valueInput" } : /* istanbul ignore next */ {}), alias: 'value' });
923
+ /**
924
+ * Value of the select control. Can be a single value or array of values for multiple selection. Follows
925
+ * `[value]`, the form control and the user's selection. A value set in code selects its options on the next
926
+ * change detection, without emitting `valueChange`.
927
+ */
928
+ this.value = linkedSignal(() => this.valueInput(), ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
929
+ /** @docs-private */
930
+ this.idInput = input(undefined, { ...(ngDevMode ? { debugName: "idInput" } : /* istanbul ignore next */ {}), alias: 'id' });
931
+ /**
932
+ * Unique identifier for the select component.
933
+ * Auto-generates an ID if not provided.
934
+ */
935
+ this.id = computed(() => this.idInput() || this.uid, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
936
+ /**
937
+ * Sets the tabIndex of the select element.
938
+ * Automatically set to -1 when disabled.
939
+ */
940
+ /** @docs-private */
941
+ this.tabIndexInput = input(0, { ...(ngDevMode ? { debugName: "tabIndexInput" } : /* istanbul ignore next */ {}), alias: 'tabIndex',
942
+ transform: numberAttribute });
943
+ /** @docs-private */
944
+ this.disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {}), alias: 'disabled',
945
+ transform: booleanAttribute });
786
946
  /**
787
- * Whether the legacy `KbqValidateDirective` marks this control. The class it writes never changes
788
- * after the host is created, so it is probed once instead of on every change detection pass.
947
+ * Whether the select is disabled.
948
+ * When disabled, the select cannot be opened and its value cannot be changed. Also set by the bound form
949
+ * control.
789
950
  */
790
- this.hasLegacyValidateDirective = false;
791
- // Mirror of the state the error colour is derived from. That state changes in `ngDoCheck`, while the
792
- // parent is checked, and nothing marks this OnPush view for it — the signal is what repaints the trigger.
793
- this.invalidState = signal(false, ...(ngDevMode ? [{ debugName: "invalidState" }] : []));
951
+ this.disabled = linkedSignal(() => this.disabledInput(), ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
952
+ // One signal per host value. The host bindings of every select in a view run in that view's reactive consumer,
953
+ // where a signal read again by another binding costs a scan of everything the view has read.
954
+ this.resolvedTabIndex = computed(() => (this.disabled() ? -1 : this.tabIndexInput()), ...(ngDevMode ? [{ debugName: "resolvedTabIndex" }] : /* istanbul ignore next */ []));
955
+ this.resolvedAriaLabelValue = computed(() => this.ariaLabel() ?? (this.ariaLabelledby ? null : this.placeholder() || null), ...(ngDevMode ? [{ debugName: "resolvedAriaLabelValue" }] : /* istanbul ignore next */ []));
956
+ /** @internal */
957
+ this.disabledAttribute = computed(() => this.disabled() || null, ...(ngDevMode ? [{ debugName: "disabledAttribute" }] : /* istanbul ignore next */ []));
958
+ /** @internal */
959
+ this.disabledClass = computed(() => this.disabled(), ...(ngDevMode ? [{ debugName: "disabledClass" }] : /* istanbul ignore next */ []));
960
+ /** @internal */
961
+ this.invalidClass = computed(() => this.errorState(), ...(ngDevMode ? [{ debugName: "invalidClass" }] : /* istanbul ignore next */ []));
962
+ this.focusedValue = signal(false, ...(ngDevMode ? [{ debugName: "focusedValue" }] : /* istanbul ignore next */ []));
963
+ this.panelOpenValue = signal(false, ...(ngDevMode ? [{ debugName: "panelOpenValue" }] : /* istanbul ignore next */ []));
964
+ /** Whether the select is focused. */
965
+ this.focused = computed(() => this.focusedValue() || this.panelOpenValue(), ...(ngDevMode ? [{ debugName: "focused" }] : /* istanbul ignore next */ []));
966
+ this.emptyValue = signal(false, ...(ngDevMode ? [{ debugName: "emptyValue" }] : /* istanbul ignore next */ []));
967
+ /** Whether no option is currently selected. */
968
+ this.empty = this.emptyValue.asReadonly();
969
+ /** `panelClass` flattened into a class string. */
970
+ this.customPanelClasses = computed(() => {
971
+ const panelClass = this.panelClass();
972
+ if (!panelClass)
973
+ return '';
974
+ if (typeof panelClass === 'string')
975
+ return panelClass;
976
+ if (Array.isArray(panelClass) || panelClass instanceof Set)
977
+ return [...panelClass].filter(Boolean).join(' ');
978
+ return Object.keys(panelClass)
979
+ .filter((key) => panelClass[key])
980
+ .join(' ');
981
+ }, ...(ngDevMode ? [{ debugName: "customPanelClasses" }] : /* istanbul ignore next */ []));
794
982
  /** Whether a "select all" batch is running, so the per-option changes propagate only once. */
795
983
  this.selectAllInProgress = false;
796
984
  /** Subscription to the close event of the overlay. */
@@ -801,82 +989,83 @@ class KbqSelect extends KbqAbstractSelect {
801
989
  this.scrollTop = 0;
802
990
  /** Unique id for this input. Auto-incremented for each instance. */
803
991
  this.uid = `kbq-select-${nextUniqueId++}`;
992
+ /**
993
+ * Id of the listbox the trigger owns, referenced by `aria-controls` while the panel is open.
994
+ *
995
+ * @docs-private
996
+ */
997
+ this.panelId = `${this.uid}-panel`;
804
998
  /** Subject that emits when the component visibility changes. */
805
999
  this.visibleChanges = new BehaviorSubject(false);
806
- /** Flag indicating if the dropdown class has been added to the overlay container. */
807
- this.classAddedToOverlayContainer = false;
808
- /** `View -> model callback called when value changes` */
1000
+ /** Accessible names of the controls the select renders itself. */
1001
+ this.a11yLocaleConfiguration = this.carrier.read('a11y', KBQ_A11Y_LOCALE_CONFIGURATION);
1002
+ /**
1003
+ * Called when the value changes. Needed to properly implement `ControlValueAccessor`.
1004
+ *
1005
+ * @docs-private
1006
+ */
809
1007
  this.onChange = () => { };
810
- /** `View -> model callback called when select has been touched` */
811
- this.onTouched = () => { };
812
1008
  /**
813
- * Calculates the number of hidden items in multiple selection mode.
814
- * Updates the hiddenItems property and triggers change detection.
1009
+ * Called when the control is blurred. Needed to properly implement `ControlValueAccessor`.
1010
+ *
1011
+ * @docs-private
815
1012
  */
816
- this.calculateHiddenItems = () => {
817
- if (!this.isBrowser ||
818
- this.customTrigger() ||
819
- this.customMatcher() ||
820
- this.empty ||
821
- !this.multiple ||
822
- this.multiline())
823
- return;
824
- const totalItemsWidth = this.getTotalItemsWidthInMatcher();
825
- const [totalVisibleItemsWidth, visibleItems] = this.getTotalVisibleItems();
826
- this.hiddenItems = this.selected.length - visibleItems;
827
- this._changeDetectorRef.detectChanges();
828
- if (this.hiddenItems) {
829
- const itemsCounter = this.trigger().nativeElement.querySelector('.kbq-select__match-hidden-text');
830
- const matcherList = this.trigger().nativeElement.querySelector('.kbq-select__match-list');
831
- if (!itemsCounter || !matcherList) {
832
- this._changeDetectorRef.markForCheck();
833
- return;
834
- }
835
- const itemsCounterShowed = itemsCounter.offsetTop < itemsCounter.offsetHeight;
836
- const itemsCounterWidth = Math.floor(itemsCounter.getBoundingClientRect().width);
837
- const matcherListWidth = Math.floor(matcherList.getBoundingClientRect().width);
838
- const matcherWidth = matcherListWidth + (itemsCounterShowed ? itemsCounterWidth : 0);
839
- if (itemsCounterShowed && totalItemsWidth < matcherWidth) {
840
- this.hiddenItems = 0;
841
- this._changeDetectorRef.detectChanges();
842
- }
843
- if (totalVisibleItemsWidth === matcherListWidth ||
844
- totalVisibleItemsWidth + itemsCounterWidth < matcherListWidth) {
845
- this._changeDetectorRef.markForCheck();
846
- return;
1013
+ this.onTouched = () => { };
1014
+ /** Calculates the number of hidden items in multiple selection mode and updates `hiddenItems`. */
1015
+ this.calculateHiddenItems = () => untracked(() => this.measureHiddenItems());
1016
+ // A different comparator means a different set of options can match the value.
1017
+ let comparatorBound = false;
1018
+ effect(() => {
1019
+ this.compareWith();
1020
+ untracked(() => {
1021
+ if (comparatorBound && this.selectionModel)
1022
+ this.initializeSelection();
1023
+ comparatorBound = true;
1024
+ });
1025
+ });
1026
+ // The selection model is created with the multiplicity of the first binding and cannot follow a change.
1027
+ effect(() => {
1028
+ const multiple = this.multipleInput();
1029
+ if (this.multipleValue !== undefined && multiple !== this.multipleValue) {
1030
+ throw getKbqSelectDynamicMultipleError();
1031
+ }
1032
+ });
1033
+ // A value bound or set in code selects its options, as long as it differs from the one the selection holds.
1034
+ effect(() => {
1035
+ const value = this.value();
1036
+ untracked(() => {
1037
+ if (value !== this.selectionValue) {
1038
+ this.applyValue(value);
847
1039
  }
1040
+ });
1041
+ });
1042
+ // A disabled select reports no focus to its form field.
1043
+ let wasDisabled = false;
1044
+ effect(() => {
1045
+ const disabled = this.disabled();
1046
+ if (disabled === wasDisabled)
1047
+ return;
1048
+ wasDisabled = disabled;
1049
+ const formField = this.parentFormField;
1050
+ if (formField) {
1051
+ Promise.resolve().then(() => this.disabled() ? formField.stopFocusMonitor() : formField.runFocusMonitor());
848
1052
  }
849
- this._changeDetectorRef.markForCheck();
850
- };
851
- /** Updates locale parameters from the locale service. */
852
- this.updateLocaleParams = () => {
853
- // A consumer-supplied locale (`KBQ_LOCALE_DATA`/`addLocale`) may predate the `select` section
854
- // entirely, not just the `selectAll` key within it — guard the lookup itself, not just its fields.
855
- const params = this.localeService?.getParams('select');
856
- this.hiddenItemsText = params?.hiddenItemsText ?? this.hiddenItemsText;
857
- this.selectAllText = params?.selectAll ?? ruRULocaleData.select.selectAll;
858
- this._changeDetectorRef.markForCheck();
859
- };
860
- /** Comparison function to specify which option is displayed. Defaults to object equality. */
861
- this._compareWith = (o1, o2) => o1 === o2;
862
- this.localeService?.changes.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(this.updateLocaleParams);
1053
+ });
863
1054
  // The "select all" row only exists while the panel is attached, so the key manager's list has to
864
1055
  // be rebuilt whenever the view query resolves or drops it — `options.changes` alone never fires
865
1056
  // for it.
866
1057
  effect(() => {
867
1058
  this.selectAllOption();
868
- this.syncNavigableOptions();
1059
+ // Untracked: the options are read here too, and their changes are handled by `options.changes`.
1060
+ untracked(() => this.syncNavigableOptions());
869
1061
  });
870
1062
  if (this.ngControl) {
871
1063
  // Note: we provide the value accessor through here, instead of
872
1064
  // the `providers` to avoid running into a circular import.
873
1065
  this.ngControl.valueAccessor = this;
874
1066
  }
875
- // Force setter to be called in case id was not specified.
876
- this.id = this.id;
877
1067
  afterNextRender(() => {
878
- this.hasLegacyValidateDirective = this.elementRef.nativeElement.classList.contains('kbq-control_has-validate-directive');
879
- this.syncInvalidState();
1068
+ this.observeVisibility();
880
1069
  if (this.multiple && !this.multiline()) {
881
1070
  merge(fromEvent(this.window, 'resize'), this.tags.changes)
882
1071
  .pipe(delay(0), debounceTime(50), takeUntilDestroyed(this.destroyRef))
@@ -886,11 +1075,14 @@ class KbqSelect extends KbqAbstractSelect {
886
1075
  }
887
1076
  /** Lifecycle hook called after component initialization. Initializes selection model and subscriptions. */
888
1077
  ngOnInit() {
1078
+ this.multipleValue = this.multipleInput();
889
1079
  this.selectionModel = new SelectionModel(this.multiSelection);
890
- this.stateChanges.next();
891
- // We need `distinctUntilChanged` here, because some browsers will
892
- // fire the animation end event twice for the same animation. See:
893
- // https://github.com/angular/angular/issues/24084
1080
+ this.emptyValue.set(this.selectionModel.isEmpty());
1081
+ this.selectionModel.changed
1082
+ .pipe(takeUntilDestroyed(this.destroyRef))
1083
+ .subscribe(() => this.emptyValue.set(this.selectionModel.isEmpty()));
1084
+ // Only the latest report of a frame is delivered, so a close and a reopen within one frame repeat the
1085
+ // state delivered before; `distinctUntilChanged` keeps `openedChange` from emitting it twice.
894
1086
  this.panelDoneAnimatingStream
895
1087
  .pipe(distinctUntilChanged(), takeUntilDestroyed(this.destroyRef))
896
1088
  .subscribe(() => {
@@ -900,13 +1092,17 @@ class KbqSelect extends KbqAbstractSelect {
900
1092
  if (search) {
901
1093
  search.focus();
902
1094
  }
1095
+ this.scrollbarViewport()?.flashScrollIndicators();
1096
+ this.projectedScrollbarViewport()?.flashScrollIndicators();
903
1097
  this.openedChange.emit(true);
904
1098
  }
905
1099
  else {
906
1100
  this.openedChange.emit(false);
907
- this._changeDetectorRef.markForCheck();
908
1101
  }
909
1102
  });
1103
+ // `debounceTime(0)` rather than a `setTimeout` per event: a burst (Ctrl + A over a long list) then
1104
+ // costs one measurement instead of one per option, and the pending work is owned by the pipe —
1105
+ // `takeUntilDestroyed` cancels it instead of leaving a timer to run against a destroyed view.
910
1106
  merge(this.optionSelectionChanges, this.visibleChanges)
911
1107
  // `delay(0)` rather than a `setTimeout` inside the subscriber: `takeUntilDestroyed` cancels a
912
1108
  // scheduled emission, but not a timer the subscriber has already started, which would then run
@@ -923,18 +1119,15 @@ class KbqSelect extends KbqAbstractSelect {
923
1119
  }
924
1120
  });
925
1121
  }
926
- /** Lifecycle hook for change detection. Updates visibility and error state. */
1122
+ /** Lifecycle hook for change detection. Updates the error state. */
927
1123
  ngDoCheck() {
928
- this.visibleChanges.next(this.isVisible());
929
1124
  if (this.ngControl) {
930
1125
  this.updateErrorState();
931
1126
  }
932
- else {
933
- this.syncInvalidState();
934
- }
935
1127
  }
936
1128
  /** Lifecycle hook after content initialization. Sets up key manager and option subscriptions. */
937
1129
  ngAfterContentInit() {
1130
+ this.contentReady = true;
938
1131
  this.withVirtualScroll = !!this.cdkVirtualForOf();
939
1132
  this.initKeyManager();
940
1133
  this.selectionModel.changed.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((event) => {
@@ -954,38 +1147,32 @@ class KbqSelect extends KbqAbstractSelect {
954
1147
  // keyboard navigation of a closed select and silently overwrites the value.
955
1148
  filter(() => this.panelOpen && this.isActiveItemStale()))
956
1149
  .subscribe(() => this.keyManager.setFirstItemActive());
1150
+ this.contentInitialized.next();
1151
+ this.contentInitialized.complete();
1152
+ }
1153
+ ngAfterContentChecked() {
1154
+ // Syncs the list here so `changes` emits after the projected items are bound and before the host bindings.
1155
+ this.optionsList();
1156
+ }
1157
+ ngAfterViewChecked() {
1158
+ // Syncs the list here so `changes` emits once this view is checked.
1159
+ this.tagsList();
957
1160
  }
958
1161
  /** Lifecycle hook when component is destroyed. Cleans up subscriptions. */
959
1162
  ngOnDestroy() {
960
- this.stateChanges.complete();
1163
+ this.visibleChanges.complete();
1164
+ // Before `openedChange`: the panel stream is what emits into it.
1165
+ this.panelDoneAnimatingStream.complete();
1166
+ this.openedChange.complete();
961
1167
  this.closeSubscription.unsubscribe();
962
1168
  this.unsubscribeFromPanelResize();
963
1169
  clearTimeout(this.openPanelTimeout);
1170
+ clearTimeout(this.highlightOptionTimeout);
964
1171
  }
965
1172
  /** Updates the error state based on the error state matcher. */
966
1173
  updateErrorState() {
967
- const oldState = this.errorState;
968
- const parent = this.parentFormGroup || this.parentForm;
969
- const matcher = this.errorStateMatcher || this.defaultErrorStateMatcher;
970
- const control = this.ngControl ? this.ngControl.control : null;
971
- const newState = matcher.isErrorState(control, parent);
972
- if (newState !== oldState) {
973
- this.errorState = newState;
974
- this.stateChanges.next();
975
- }
976
- this.syncInvalidState();
977
- }
978
- syncInvalidState() {
979
- this.invalidState.set((this.hasLegacyValidateDirective && !!this.ngControl?.invalid) || this.errorState);
980
- }
981
- /**
982
- * Formats the hidden items text with the number of hidden items.
983
- * @param hiddenItemsText Template string with {{ number }} placeholder.
984
- * @param hiddenItems Number of hidden items to display.
985
- * @returns Formatted string with the number of hidden items.
986
- */
987
- hiddenItemsTextFormatter(hiddenItemsText, hiddenItems) {
988
- return hiddenItemsText.replace('{{ number }}', hiddenItems.toString());
1174
+ this.errorStateTracker.errorStateMatcher = this.errorStateMatcher();
1175
+ this.errorStateTracker.updateErrorState();
989
1176
  }
990
1177
  /**
991
1178
  * Selects every option "select all" can act on, or deselects them all when they are already selected.
@@ -1008,57 +1195,49 @@ class KbqSelect extends KbqAbstractSelect {
1008
1195
  this.selectAllInProgress = false;
1009
1196
  }
1010
1197
  this.propagateChanges();
1011
- this.stateChanges.next();
1012
1198
  this.onSelectAll.emit(new KbqSelectAllEvent(this, targets, this.allOptionsSelected));
1013
1199
  }
1014
1200
  /**
1015
- * Clears the current selection.
1201
+ * Clears the options `clearPredicate` accepts, which by default leaves the disabled ones selected.
1202
+ *
1016
1203
  * @docs-private
1017
1204
  */
1018
1205
  clear() {
1019
- this.selectionModel.clear();
1020
- this.keyManager.setActiveItem(-1);
1021
- this.propagateChanges();
1022
- }
1023
- /**
1024
- * Clears the current selection.
1025
- * @deprecated Activate the projected `KbqCleaner` instead.
1026
- * @docs-private
1027
- */
1028
- clearValue(event) {
1029
- const cleaner = this.cleaner();
1030
- if (cleaner) {
1031
- cleaner.clear(event);
1032
- }
1033
- else {
1034
- event.stopPropagation();
1035
- event.preventDefault();
1036
- this.clear();
1037
- this.focus();
1038
- }
1206
+ untracked(() => {
1207
+ this.selectionModel.deselect(...this.clearTargets);
1208
+ this.keyManager.setActiveItem(-1);
1209
+ this.propagateChanges();
1210
+ });
1039
1211
  }
1040
1212
  /** Resets the search component if present. */
1041
1213
  resetSearch() {
1042
- const search = this.search();
1043
- if (!search) {
1044
- return;
1045
- }
1046
- search.reset();
1047
- /*
1048
- todo the incorrect behaviour of keyManager is possible here
1049
- to avoid first item selection (to provide correct options flipping on closed select)
1050
- we should process options update like it is the first options appearance
1051
- */
1052
- search.isSearchChanged = false;
1214
+ untracked(() => {
1215
+ const search = this.search();
1216
+ if (!search) {
1217
+ return;
1218
+ }
1219
+ search.reset();
1220
+ /*
1221
+ todo the incorrect behaviour of keyManager is possible here
1222
+ to avoid first item selection (to provide correct options flipping on closed select)
1223
+ we should process options update like it is the first options appearance
1224
+ */
1225
+ search.isSearchChanged = false;
1226
+ });
1053
1227
  }
1054
1228
  /** Toggles the overlay panel open or closed. */
1055
1229
  toggle() {
1056
- if (this.panelOpen) {
1057
- this.close();
1058
- }
1059
- else {
1060
- this.open();
1061
- }
1230
+ // Untracked, like the other imperative methods: called from a consumer's `effect()`, the state read on the
1231
+ // way — `panelOpen`, `disabled`, the options, the inputs — would make the effect run again on every open
1232
+ // and close.
1233
+ untracked(() => {
1234
+ if (this.panelOpen) {
1235
+ this.close();
1236
+ }
1237
+ else {
1238
+ this.open();
1239
+ }
1240
+ });
1062
1241
  }
1063
1242
  /**
1064
1243
  * Triggers the opening of the panel component.
@@ -1068,22 +1247,27 @@ class KbqSelect extends KbqAbstractSelect {
1068
1247
  * if options exist, it opens immediately.
1069
1248
  */
1070
1249
  open() {
1071
- if (this.disabled || this.panelOpen)
1072
- return;
1073
- this.beforeOpened.emit();
1074
- if (this.noOptions) {
1075
- clearTimeout(this.openPanelTimeout);
1076
- this.openPanelTimeout = setTimeout(() => this.openPanel(), delayBeforeDisplayingResultWithoutOptions);
1077
- }
1078
- else {
1079
- this.openPanel();
1080
- }
1250
+ untracked(() => {
1251
+ if (this.disabled() || this.panelOpen)
1252
+ return;
1253
+ this.beforeOpened.emit();
1254
+ if (this.noOptions) {
1255
+ clearTimeout(this.openPanelTimeout);
1256
+ this.openPanelTimeout = setTimeout(() => this.openPanel(), delayBeforeDisplayingResultWithoutOptions);
1257
+ }
1258
+ else {
1259
+ this.openPanel();
1260
+ }
1261
+ });
1081
1262
  }
1082
1263
  /**
1083
1264
  * Internal method to open the panel. Handles overlay positioning and sizing.
1084
1265
  * Sets up the overlay dimensions based on trigger size and configured options.
1085
1266
  */
1086
1267
  openPanel() {
1268
+ untracked(() => this.attachPanel());
1269
+ }
1270
+ attachPanel() {
1087
1271
  const trigger = this.trigger();
1088
1272
  if (!trigger || !this.keyManager)
1089
1273
  return;
@@ -1104,35 +1288,47 @@ class KbqSelect extends KbqAbstractSelect {
1104
1288
  this.highlightCorrectOption();
1105
1289
  this._changeDetectorRef.markForCheck();
1106
1290
  // Set the font size on the panel element once it exists.
1107
- this._ngZone.onStable
1108
- .asObservable()
1109
- .pipe(take(1))
1110
- .subscribe(() => {
1291
+ afterNextRender(() => {
1111
1292
  this.scrollActiveOptionIntoView();
1112
1293
  if (this.triggerFontSize && this.overlayDir.overlayRef && this.overlayDir.overlayRef.overlayElement) {
1113
1294
  this.overlayDir.overlayRef.overlayElement.style.fontSize = `${this.triggerFontSize}px`;
1114
1295
  }
1115
- this.addClassToOverlayContainer();
1116
1296
  if (this.search()) {
1117
1297
  this.lockOverlayWidthForSearch(this.panel());
1118
1298
  }
1119
- });
1299
+ }, { injector: this.injector });
1300
+ this.reportPanelRendered('showing');
1120
1301
  }
1121
1302
  /** Closes the overlay panel. */
1122
1303
  close() {
1123
- if (!this.panelOpen)
1304
+ untracked(() => {
1305
+ if (!this.panelOpen)
1306
+ return;
1307
+ // the order of calls is important
1308
+ this.resetSearch();
1309
+ this.panelOpen = false;
1310
+ this.unsubscribeFromPanelResize();
1311
+ // Back to the two default sides, so the next open is not resolved against a first row that has since
1312
+ // changed height.
1313
+ this.positions = this.withOverlapPosition(this.positions, null) ?? this.positions;
1314
+ this.keyManager.withHorizontalOrientation(this.isRtl() ? 'rtl' : 'ltr');
1315
+ this._changeDetectorRef.markForCheck();
1316
+ this.onTouched();
1317
+ this.reportPanelRendered('void');
1318
+ });
1319
+ }
1320
+ /**
1321
+ * Reports the panel rendered or removed once the next render has applied `panelOpen`; only the latest
1322
+ * report of a frame is delivered.
1323
+ */
1324
+ reportPanelRendered(state) {
1325
+ this.panelRender?.destroy();
1326
+ // The overlay detaching while the select is destroyed closes it too.
1327
+ if (this.destroyRef.destroyed)
1124
1328
  return;
1125
- // the order of calls is important
1126
- this.resetSearch();
1127
- this.panelOpen = false;
1128
- this.unsubscribeFromPanelResize();
1129
- // Back to the two default sides, so the next open is not resolved against a first row that has since
1130
- // changed height.
1131
- this.positions = this.withOverlapPosition(this.positions, null) ?? this.positions;
1132
- this.keyManager.withHorizontalOrientation(this.isRtl() ? 'rtl' : 'ltr');
1133
- this._changeDetectorRef.markForCheck();
1134
- this.onTouched();
1135
- this.removeClassFromOverlayContainer();
1329
+ this.panelRender = afterNextRender(() => this.panelDoneAnimatingStream.next(state), {
1330
+ injector: this.injector
1331
+ });
1136
1332
  }
1137
1333
  /**
1138
1334
  * Sets the select's value. Part of the ControlValueAccessor interface
@@ -1141,9 +1337,9 @@ class KbqSelect extends KbqAbstractSelect {
1141
1337
  * @param value New value to be written to the model.
1142
1338
  */
1143
1339
  writeValue(value) {
1144
- if (this.options) {
1145
- this.setSelectionByValue(value);
1146
- }
1340
+ // Untracked: a form control set from an `effect()` writes here synchronously.
1341
+ untracked(() => this.applyValue(value));
1342
+ this.value.set(value);
1147
1343
  }
1148
1344
  /**
1149
1345
  * Saves a callback function to be invoked when the select's value
@@ -1173,12 +1369,11 @@ class KbqSelect extends KbqAbstractSelect {
1173
1369
  * @param isDisabled Sets whether the component is disabled.
1174
1370
  */
1175
1371
  setDisabledState(isDisabled) {
1176
- this.disabled = isDisabled;
1177
- this._changeDetectorRef.markForCheck();
1178
- this.stateChanges.next();
1372
+ this.disabled.set(isDisabled);
1179
1373
  }
1180
1374
  /**
1181
1375
  * Checks if the current direction is RTL (right-to-left).
1376
+ *
1182
1377
  * @returns True if RTL mode is active, false otherwise.
1183
1378
  */
1184
1379
  isRtl() {
@@ -1187,10 +1382,11 @@ class KbqSelect extends KbqAbstractSelect {
1187
1382
  /**
1188
1383
  * Handles all keyboard events for the select.
1189
1384
  * Delegates to appropriate handler based on panel state.
1385
+ *
1190
1386
  * @param event The keyboard event to handle.
1191
1387
  */
1192
1388
  handleKeydown(event) {
1193
- if (this.disabled)
1389
+ if (this.disabled())
1194
1390
  return;
1195
1391
  if (this.panelOpen) {
1196
1392
  this.handleOpenKeydown(event);
@@ -1201,9 +1397,8 @@ class KbqSelect extends KbqAbstractSelect {
1201
1397
  }
1202
1398
  /** Handles focus event on the select element. */
1203
1399
  onFocus() {
1204
- if (!this.disabled) {
1205
- this._focused = true;
1206
- this.stateChanges.next();
1400
+ if (!this.disabled()) {
1401
+ this.focusedValue.set(true);
1207
1402
  }
1208
1403
  }
1209
1404
  /**
@@ -1211,11 +1406,9 @@ class KbqSelect extends KbqAbstractSelect {
1211
1406
  * "blur" to the panel when it opens, causing a false positive.
1212
1407
  */
1213
1408
  onBlur() {
1214
- this._focused = false;
1215
- if (!this.disabled && !this.panelOpen) {
1409
+ this.focusedValue.set(false);
1410
+ if (!this.disabled() && !this.panelOpen) {
1216
1411
  this.onTouched();
1217
- this._changeDetectorRef.markForCheck();
1218
- this.stateChanges.next();
1219
1412
  }
1220
1413
  }
1221
1414
  /**
@@ -1223,10 +1416,12 @@ class KbqSelect extends KbqAbstractSelect {
1223
1416
  * Sets up position change subscription and closing actions.
1224
1417
  */
1225
1418
  onAttached() {
1419
+ // `cdkConnectedOverlay` creates and attaches the overlay in one go, so this is the first point it exists.
1420
+ this.overlayLayers.adopt(this.overlayDir.overlayRef, this.elementRef.nativeElement);
1226
1421
  this.overlayDir.positionChange.pipe(take(1)).subscribe(() => {
1227
1422
  this._changeDetectorRef.detectChanges();
1228
1423
  this.setOverlayPosition();
1229
- this.optionsContainer().nativeElement.scrollTop = this.scrollTop;
1424
+ this.scrollbarViewport()?.scrollTo({ top: this.scrollTop });
1230
1425
  this.updateScrollSize();
1231
1426
  this.subscribeToScrolledToBottom();
1232
1427
  // Deliberately out of this frame — see `reanchorPanel`. A microtask still lands before paint.
@@ -1234,11 +1429,19 @@ class KbqSelect extends KbqAbstractSelect {
1234
1429
  });
1235
1430
  // The option list drives the panel's height, so a change to it can settle the anchor question
1236
1431
  // differently — and the panel is realigned on every such change regardless.
1237
- this.options.changes.pipe(delay(1), takeUntilDestroyed(this.destroyRef)).subscribe(() => {
1432
+ //
1433
+ // Both subscriptions belong to this panel session: `onAttached` runs again on every open, and
1434
+ // without the per-session teardown each one would be layered on top of the previous ones. The
1435
+ // teardown sits after `delay(1)`, so closing also drops a repositioning that was scheduled but
1436
+ // has not fired yet — by then there is no overlay left to position.
1437
+ this.options.changes
1438
+ .pipe(delay(1), takeUntilDestroyed(this.destroyRef), takeUntil(this.closedStream))
1439
+ .subscribe(() => {
1238
1440
  this.updatePanelAnchor();
1239
1441
  this.setOverlayPosition();
1240
1442
  });
1241
1443
  this.subscribeToPanelResize();
1444
+ this.closeSubscription.unsubscribe();
1242
1445
  this.closeSubscription = this.closingActions().subscribe(() => this.close());
1243
1446
  }
1244
1447
  /** Element the overlay is positioned and sized against. */
@@ -1257,22 +1460,16 @@ class KbqSelect extends KbqAbstractSelect {
1257
1460
  }
1258
1461
  /** Returns the theme to be used on the panel based on parent form field color. */
1259
1462
  getPanelTheme() {
1260
- return this.parentFormField ? `kbq-${this.parentFormField.color}` : '';
1463
+ return this.parentFormField ? `kbq-${this.parentFormField.color()}` : '';
1261
1464
  }
1262
- /** Returns the full set of classes for the panel: base class, theme and custom `panelClass`. */
1465
+ /**
1466
+ * Returns the full set of classes for the panel: base class, theme and custom `panelClass`.
1467
+ *
1468
+ * Only the theme is read per change detection — it comes from the form field, which does not expose
1469
+ * its color as a signal — while the `panelClass` expansion is memoised.
1470
+ */
1263
1471
  getPanelClasses() {
1264
- const panelClass = this.panelClass();
1265
- const classes = ['kbq-select__panel', this.getPanelTheme()];
1266
- if (typeof panelClass === 'string') {
1267
- classes.push(panelClass);
1268
- }
1269
- else if (Array.isArray(panelClass) || panelClass instanceof Set) {
1270
- classes.push(...panelClass);
1271
- }
1272
- else if (panelClass) {
1273
- classes.push(...Object.keys(panelClass).filter((key) => panelClass[key]));
1274
- }
1275
- return classes.filter(Boolean).join(' ');
1472
+ return ['kbq-select__panel', this.getPanelTheme(), this.customPanelClasses()].filter(Boolean).join(' ');
1276
1473
  }
1277
1474
  /** Focuses the select element. */
1278
1475
  focus() {
@@ -1280,30 +1477,76 @@ class KbqSelect extends KbqAbstractSelect {
1280
1477
  }
1281
1478
  /**
1282
1479
  * Implemented as part of KbqFormFieldControl.
1480
+ *
1283
1481
  * @docs-private
1284
1482
  */
1285
- onContainerClick() {
1483
+ onContainerClick(event) {
1484
+ // The click that opened the panel reaches the form field after the select. In an application with zone.js
1485
+ // the panel has rendered and focused its active option by then, so the focus is left to the panel. Any
1486
+ // other click on the field, such as one on a prefix that blurred the panel to the body, brings the focus back.
1487
+ const target = event && _getEventTarget(event);
1488
+ if (this.panelOpen && target instanceof Node && this.elementRef.nativeElement.contains(target))
1489
+ return;
1286
1490
  this.focus();
1287
1491
  }
1288
1492
  /**
1289
1493
  * Handles removal of a matched item in the trigger.
1494
+ *
1290
1495
  * @param option The option to remove from selection.
1291
- * @param $event The mouse event that triggered the removal.
1496
+ * @param $event The mouse or keyboard event that triggered the removal.
1292
1497
  */
1293
1498
  onRemoveMatcherItem(option, $event) {
1499
+ // The trigger toggles the panel on click and on Enter/Space — neither belongs to this control.
1294
1500
  $event.stopPropagation();
1501
+ $event.preventDefault();
1295
1502
  option.deselect();
1296
1503
  }
1504
+ /** Accessible name of the control that removes a selected value from the trigger. */
1505
+ removeItemAriaLabel(option) {
1506
+ return `${this.a11yLocaleConfiguration().remove} ${option.viewValue}`.trim();
1507
+ }
1508
+ measureHiddenItems() {
1509
+ if (!this.isBrowser ||
1510
+ this.customTrigger() ||
1511
+ this.customMatcher() ||
1512
+ this.empty() ||
1513
+ !this.multiple ||
1514
+ this.multiline())
1515
+ return;
1516
+ const { totalItemsWidth, visibleItems } = this.hiddenItemsMeasurer.measure(this.trigger().nativeElement);
1517
+ this.hiddenItemsCount.set(this.selected.length - visibleItems);
1518
+ this.visibleTriggerItems.set(visibleItems || null);
1519
+ if (!this.hiddenItems())
1520
+ return;
1521
+ // The counter is measured below, so it has to be rendered with the new count first.
1522
+ this._changeDetectorRef.detectChanges();
1523
+ const itemsCounter = this.trigger().nativeElement.querySelector('.kbq-select__match-hidden-text');
1524
+ const matcherList = this.trigger().nativeElement.querySelector('.kbq-select__match-list');
1525
+ if (!itemsCounter || !matcherList)
1526
+ return;
1527
+ const itemsCounterShowed = itemsCounter.offsetTop < itemsCounter.offsetHeight;
1528
+ const itemsCounterWidth = Math.floor(itemsCounter.getBoundingClientRect().width);
1529
+ const matcherListWidth = Math.floor(matcherList.getBoundingClientRect().width);
1530
+ const matcherWidth = matcherListWidth + (itemsCounterShowed ? itemsCounterWidth : 0);
1531
+ if (itemsCounterShowed && totalItemsWidth < matcherWidth) {
1532
+ // Everything fits once the counter goes away, so nothing is clipped after all.
1533
+ this.hiddenItemsCount.set(0);
1534
+ this.visibleTriggerItems.set(null);
1535
+ }
1536
+ }
1297
1537
  /**
1298
1538
  * Gets the height of a single option item.
1539
+ *
1299
1540
  * @returns The height in pixels of the first option, or 0 if no options exist.
1300
1541
  */
1301
1542
  getItemHeight() {
1543
+ // TODO: nothing in the library uses it; kept as public API at the DS-2196 review. Document or deprecate it.
1302
1544
  return this.options.first ? this.options.first.getHeight() : 0;
1303
1545
  }
1304
1546
  /**
1305
1547
  * Handles click events on the select.
1306
1548
  * Closes the panel if click is inside the footer.
1549
+ *
1307
1550
  * @param $event The mouse event to handle.
1308
1551
  */
1309
1552
  handleClick($event) {
@@ -1379,9 +1622,15 @@ class KbqSelect extends KbqAbstractSelect {
1379
1622
  const options = this.navigableOptions.toArray();
1380
1623
  let fromIndex = this.keyManager.previousActiveItemIndex;
1381
1624
  let toIndex = (this.keyManager.previousActiveItemIndex = this.keyManager.activeItemIndex);
1625
+ // There is no anchor to build a range from — `clear()` resets the active item to `-1`, and
1626
+ // `slice(-1, …)` would silently resolve to an empty range and select nothing at all.
1627
+ if (fromIndex < 0) {
1628
+ this.toggleOption(option);
1629
+ return;
1630
+ }
1382
1631
  const selectedOptionState = options[fromIndex]?.selected;
1383
1632
  if (toIndex === fromIndex) {
1384
- this.selectionModel.toggle(option);
1633
+ this.toggleOption(option);
1385
1634
  return;
1386
1635
  }
1387
1636
  if (fromIndex > toIndex) {
@@ -1400,31 +1649,57 @@ class KbqSelect extends KbqAbstractSelect {
1400
1649
  });
1401
1650
  }
1402
1651
  else {
1403
- this.selectionModel.toggle(option);
1652
+ this.toggleOption(option);
1653
+ }
1654
+ }
1655
+ /**
1656
+ * Flips the selected state of a single option through the option itself.
1657
+ *
1658
+ * Toggling the selection model directly would not do: only the option's own selection change reaches
1659
+ * `onSelect`, which is what writes the value back to the form control — every branch above relies on
1660
+ * the same path.
1661
+ */
1662
+ toggleOption(option) {
1663
+ if (option.selected) {
1664
+ option.deselect();
1665
+ }
1666
+ else {
1667
+ option.select();
1404
1668
  }
1405
1669
  }
1406
1670
  /** @docs-private */
1407
1671
  shouldShowSearch() {
1408
- return (isUndefined(this.searchMinOptionsThreshold) ||
1672
+ return (isUndefined(this.searchMinOptionsThreshold()) ||
1409
1673
  !!this.search()?.value() ||
1410
- this.options.length >= this.searchMinOptionsThreshold);
1674
+ this.options.length >= this.searchMinOptionsThreshold());
1411
1675
  }
1412
- /** Checks if the component is currently visible in the viewport. */
1413
- isVisible() {
1414
- if (!this.isBrowser)
1676
+ /**
1677
+ * Reports whether the trigger is on screen, so the hidden items are re-measured once it appears.
1678
+ *
1679
+ * An `IntersectionObserver` rather than a geometry probe in `ngDoCheck`: reading `offsetTop` forces a
1680
+ * synchronous layout, and `ngDoCheck` runs on every change detection cycle of every ancestor.
1681
+ */
1682
+ observeVisibility() {
1683
+ // TypeScript declares the observer constructors on `globalThis` rather than on `Window`, so the
1684
+ // injected window has to be widened before one of them can be read off it.
1685
+ const view = this.window;
1686
+ if (!this.isBrowser || typeof view.IntersectionObserver !== 'function')
1687
+ return;
1688
+ const observer = new view.IntersectionObserver(([entry]) => this.visibleChanges.next(entry.isIntersecting));
1689
+ observer.observe(this.elementRef.nativeElement);
1690
+ this.destroyRef.onDestroy(() => observer.disconnect());
1691
+ }
1692
+ /** Whether a modal paints over the panel, so that clicks inside the modal leave the panel open. */
1693
+ isCoveredByModal() {
1694
+ const host = this.overlayDir.overlayRef.hostElement;
1695
+ const overlays = Array.from(this.overlayContainer.getContainerElement().children);
1696
+ const modalIndex = overlays.findIndex((overlay) => overlay.classList.contains('kbq-modal-overlay'));
1697
+ if (modalIndex === -1) {
1415
1698
  return false;
1416
- return this.elementRef.nativeElement.offsetTop < this.elementRef.nativeElement.offsetHeight;
1417
- }
1418
- /** Gets the current overlay position index in the container. */
1419
- currentOverlayPosition() {
1420
- const element = this.overlayDir.overlayRef.hostElement;
1421
- return Array.from(this.overlayContainer.getContainerElement().childNodes).findIndex((node) => {
1422
- return node.firstChild?.['id'] === element.firstChild?.['id'];
1423
- });
1424
- }
1425
- /** Gets the position index of modal overlay in the container. */
1426
- modalOverlayPosition() {
1427
- return Array.from(this.overlayContainer.getContainerElement().childNodes).findIndex((childNode) => childNode.classList.contains('kbq-modal-overlay'));
1699
+ }
1700
+ const panelIndex = overlays.indexOf(host);
1701
+ // A panel on an overlay layer paints under the whole application-wide container.
1702
+ return panelIndex === -1 || panelIndex < modalIndex;
1428
1703
  }
1429
1704
  /**
1430
1705
  * Creates an observable of actions that should close the select panel.
@@ -1435,12 +1710,7 @@ class KbqSelect extends KbqAbstractSelect {
1435
1710
  const outsidePointerEvents = this.overlayDir
1436
1711
  .overlayRef.outsidePointerEvents()
1437
1712
  .pipe(delay(0))
1438
- .pipe(filter(() => {
1439
- if (this.overlayContainer.getContainerElement().childElementCount > 1) {
1440
- return this.currentOverlayPosition() > this.modalOverlayPosition();
1441
- }
1442
- return true;
1443
- }));
1713
+ .pipe(filter(() => !this.isCoveredByModal()));
1444
1714
  return merge(outsidePointerEvents, this.overlayDir.overlayRef.detachments());
1445
1715
  }
1446
1716
  /** Gets the height of the options container element. */
@@ -1483,35 +1753,6 @@ class KbqSelect extends KbqAbstractSelect {
1483
1753
  .subscribe(() => this._ngZone.run(() => this.scrolledToBottom.emit()));
1484
1754
  });
1485
1755
  }
1486
- /** Calculates the total width of all selected items in the matcher. */
1487
- getTotalItemsWidthInMatcher() {
1488
- const triggerClone = this.buildTriggerClone();
1489
- triggerClone.querySelector('.kbq-select__match-hidden-text')?.remove();
1490
- this._renderer.appendChild(this.trigger().nativeElement, triggerClone);
1491
- let totalItemsWidth = 0;
1492
- const selectedItemsViewValueContainers = triggerClone.querySelectorAll('kbq-tag');
1493
- selectedItemsViewValueContainers.forEach((item) => (totalItemsWidth += this.getItemWidth(item)));
1494
- triggerClone.remove();
1495
- return totalItemsWidth;
1496
- }
1497
- /**
1498
- * Calculates the width of a single item including margins.
1499
- *
1500
- * The elements measured here are `kbq-tag`s, which are `border-box` and carry horizontal
1501
- * padding. `getComputedStyle().width` resolves to the used content-box width whatever
1502
- * `box-sizing` says, so it dropped that padding from every tag and the matcher believed more
1503
- * tags fit than actually do. `getBoundingClientRect()` is always the border box — the same fix
1504
- * `kbqGetPanelWidthOrigin()` carries for the dropdown trigger.
1505
- * @param element The DOM element to measure.
1506
- * @returns Total width including margins and gap.
1507
- */
1508
- getItemWidth(element) {
1509
- const computedStyle = this.window.getComputedStyle(element);
1510
- const width = element.getBoundingClientRect().width;
1511
- const marginLeft = parseFloat(computedStyle.marginLeft) || 0;
1512
- const marginRight = parseFloat(computedStyle.marginRight) || 0;
1513
- return width + marginLeft + marginRight + parseInt(SizeXxs);
1514
- }
1515
1756
  /** Handles keyboard events while the select is closed. */
1516
1757
  handleClosedKeydown(event) {
1517
1758
  const keyCode = event.keyCode;
@@ -1615,7 +1856,8 @@ class KbqSelect extends KbqAbstractSelect {
1615
1856
  search.focus();
1616
1857
  }
1617
1858
  if (search && (this.keyManager.isTyping() || [BACKSPACE, DELETE].includes(keyCode))) {
1618
- setTimeout(() => this.highlightCorrectOption());
1859
+ clearTimeout(this.highlightOptionTimeout);
1860
+ this.highlightOptionTimeout = setTimeout(() => this.highlightCorrectOption());
1619
1861
  }
1620
1862
  }
1621
1863
  }
@@ -1627,7 +1869,7 @@ class KbqSelect extends KbqAbstractSelect {
1627
1869
  // Defer setting the value in order to avoid the "Expression
1628
1870
  // has changed after it was checked" errors from Angular.
1629
1871
  Promise.resolve().then(() => {
1630
- this.setSelectionByValue(this.ngControl ? this.ngControl.value : this._value);
1872
+ this.setSelectionByValue(this.ngControl ? this.ngControl.value : this.value());
1631
1873
  });
1632
1874
  }
1633
1875
  /** Whether the key manager has no active item, or its active item is missing from the current options list. */
@@ -1656,38 +1898,55 @@ class KbqSelect extends KbqAbstractSelect {
1656
1898
  this.highlightCorrectOption();
1657
1899
  }
1658
1900
  }
1901
+ /** Selects the options of `value` once the options are settled; until then `initializeSelection` does. */
1902
+ applyValue(value) {
1903
+ this.selectionValue = value;
1904
+ if (this.contentReady) {
1905
+ this.setSelectionByValue(value);
1906
+ }
1907
+ }
1659
1908
  /**
1660
1909
  * Sets the selected option based on a value.
1661
1910
  * If no option can be found with the designated value, the select trigger is cleared.
1911
+ *
1662
1912
  * @param value The value to select. Can be a single value or array for multiple selection.
1663
1913
  */
1664
1914
  setSelectionByValue(value) {
1665
- this.previousSelectionModelSelected = this.selectionModel.selected;
1666
- if (this.multiSelection && value) {
1667
- if (!Array.isArray(value)) {
1668
- throw getKbqSelectNonArrayValueError();
1915
+ // Restored rather than cleared: a value written while this one is applied must not end the outer write.
1916
+ const wasWritingValue = this.writingValue;
1917
+ this.writingValue = true;
1918
+ try {
1919
+ this.previousSelectionModelSelected = this.selectionModel.selected;
1920
+ if (this.multiSelection && value) {
1921
+ if (!Array.isArray(value)) {
1922
+ throw getKbqSelectNonArrayValueError();
1923
+ }
1924
+ this.selectionModel.clear();
1925
+ value.forEach((currentValue) => this.selectValue(currentValue));
1926
+ this.sortValues();
1669
1927
  }
1670
- this.selectionModel.clear();
1671
- value.forEach((currentValue) => this.selectValue(currentValue));
1672
- this.sortValues();
1673
- }
1674
- else {
1675
- this.selectionModel.clear();
1676
- const correspondingOption = this.selectValue(value);
1677
- // Shift focus to the active item. Note that we shouldn't do this in multiple
1678
- // mode, because we don't know what option the user interacted with last.
1679
- // While the panel is open and the user is already navigating a still-present
1680
- // active item, keep it as is: `options.changes` re-runs this method on every
1681
- // appended chunk (e.g. paging), and re-activating the selected option would
1682
- // focus it and scroll the list back to it.
1683
- if (correspondingOption && !this.withVirtualScroll && (!this.panelOpen || this.isActiveItemStale())) {
1684
- this.keyManager.setActiveItem(correspondingOption);
1928
+ else {
1929
+ this.selectionModel.clear();
1930
+ const correspondingOption = this.selectValue(value);
1931
+ // Shift focus to the active item. Note that we shouldn't do this in multiple
1932
+ // mode, because we don't know what option the user interacted with last.
1933
+ // While the panel is open and the user is already navigating a still-present
1934
+ // active item, keep it as is: `options.changes` re-runs this method on every
1935
+ // appended chunk (e.g. paging), and re-activating the selected option would
1936
+ // focus it and scroll the list back to it.
1937
+ if (correspondingOption && !this.withVirtualScroll && (!this.panelOpen || this.isActiveItemStale())) {
1938
+ this.keyManager.setActiveItem(correspondingOption);
1939
+ }
1685
1940
  }
1686
1941
  }
1942
+ finally {
1943
+ this.writingValue = wasWritingValue;
1944
+ }
1687
1945
  this._changeDetectorRef.markForCheck();
1688
1946
  }
1689
1947
  /**
1690
1948
  * Finds the option that corresponds to the given value.
1949
+ *
1691
1950
  * @param value The value to find.
1692
1951
  * @returns The matching option or undefined if not found.
1693
1952
  */
@@ -1696,10 +1955,11 @@ class KbqSelect extends KbqAbstractSelect {
1696
1955
  ...this.options.toArray(),
1697
1956
  ...this.previousSelectionModelSelected.map((option) => this.resolveSelectedOption(option))
1698
1957
  // Treat null as a special reset value.
1699
- ].find((option) => option.value != null && runCompareWith(this.compareWith, option.value, value));
1958
+ ].find((option) => option.value != null && runCompareWith(this.compareWith(), option.value, value));
1700
1959
  }
1701
1960
  /**
1702
1961
  * Finds and selects an option based on its value.
1962
+ *
1703
1963
  * @returns Option that has the corresponding value, when it is currently rendered.
1704
1964
  */
1705
1965
  selectValue(value) {
@@ -1726,7 +1986,7 @@ class KbqSelect extends KbqAbstractSelect {
1726
1986
  return undefined;
1727
1987
  if (this.withVirtualScroll) {
1728
1988
  const source = this.cdkVirtualForOf()?.cdkVirtualForOf;
1729
- const correspondingOptionVirtual = source instanceof Array ? source.find((item) => this.compareWith(item, value)) : undefined;
1989
+ const correspondingOptionVirtual = source instanceof Array ? source.find((item) => this.compareWith()(item, value)) : undefined;
1730
1990
  if (correspondingOptionVirtual) {
1731
1991
  return this.createVirtualOption(correspondingOptionVirtual);
1732
1992
  }
@@ -1745,7 +2005,7 @@ class KbqSelect extends KbqAbstractSelect {
1745
2005
  */
1746
2006
  createVirtualOption(value) {
1747
2007
  const virtualOptionFactory = this.virtualOptionFactory();
1748
- return virtualOptionFactory ? virtualOptionFactory(value) : new KbqVirtualOption(value, this.disabled);
2008
+ return virtualOptionFactory ? virtualOptionFactory(value) : new KbqVirtualOption(value, this.disabled());
1749
2009
  }
1750
2010
  /**
1751
2011
  * Remembers the value and the label of a selected option while its view is still live, so that the
@@ -1763,7 +2023,7 @@ class KbqSelect extends KbqAbstractSelect {
1763
2023
  return option;
1764
2024
  // A value that no longer matches the copy means the view was recycled for another item. A
1765
2025
  // comparator that throws reads as "no match" here too, falling back to the value actually selected.
1766
- return runCompareWith(this.compareWith, option.value, copy.value) ? option : copy;
2026
+ return runCompareWith(this.compareWith(), option.value, copy.value) ? option : copy;
1767
2027
  }
1768
2028
  /** Sets up a key manager to listen to keyboard events on the overlay panel. */
1769
2029
  initKeyManager() {
@@ -1777,7 +2037,11 @@ class KbqSelect extends KbqAbstractSelect {
1777
2037
  this.scrollActiveOptionIntoView();
1778
2038
  this.search()?.focus();
1779
2039
  }
1780
- else if (!this.panelOpen && !this.multiSelection && this.keyManager.activeItem) {
2040
+ else if (!this.panelOpen &&
2041
+ !this.multiSelection &&
2042
+ this.keyManager.activeItem &&
2043
+ // The active option follows a written value; selecting it again would report it as the user's.
2044
+ !this.writingValue) {
1781
2045
  this.keyManager.activeItem.selectViaInteraction();
1782
2046
  }
1783
2047
  });
@@ -1797,10 +2061,7 @@ class KbqSelect extends KbqAbstractSelect {
1797
2061
  // Handles cases like the labels of the selected options changing.
1798
2062
  (this.options.length ? merge(...this.options.map((option) => option.stateChanges)) : EMPTY)
1799
2063
  .pipe(takeUntilDestroyed(this.destroyRef), takeUntil(this.options.changes))
1800
- .subscribe(() => {
1801
- this._changeDetectorRef.markForCheck();
1802
- this.stateChanges.next();
1803
- });
2064
+ .subscribe(() => this._changeDetectorRef.markForCheck());
1804
2065
  }
1805
2066
  /** Invoked when an option is clicked. */
1806
2067
  onSelect(option, isUserInput) {
@@ -1829,17 +2090,35 @@ class KbqSelect extends KbqAbstractSelect {
1829
2090
  if (!this.selectAllInProgress && wasSelected !== this.selectionModel.isSelected(option)) {
1830
2091
  this.propagateChanges();
1831
2092
  }
1832
- this.stateChanges.next();
2093
+ this._changeDetectorRef.markForCheck();
1833
2094
  }
1834
2095
  /** Sorts the selected values based on their order in the panel. */
1835
2096
  sortValues() {
1836
2097
  if (this.multiSelection) {
1837
2098
  const options = this.options.toArray();
1838
- this.selectionModel.sort((a, b) => {
1839
- const sortComparator = this.sortComparator();
1840
- return sortComparator ? sortComparator(a, b, options) : a.value - b.value;
1841
- });
1842
- this.stateChanges.next();
2099
+ const sortComparator = this.sortComparator();
2100
+ if (sortComparator) {
2101
+ this.selectionModel.sort((a, b) => sortComparator(a, b, options));
2102
+ }
2103
+ else {
2104
+ // Panel order is fixed for the whole sort, so it is indexed once rather than rescanned
2105
+ // by an `indexOf` on each of the comparator's O(n log n) calls.
2106
+ const panelOrder = new Map(options.map((option, index) => [option, index]));
2107
+ this.selectionModel.sort((a, b) => {
2108
+ // See `sortComparator`. A selected value with no rendered option — a
2109
+ // `KbqVirtualOption` under virtual scroll or `showPreselectedValues` — is not in
2110
+ // `options` at all, and sorts after everything that is.
2111
+ const indexA = panelOrder.get(a) ?? -1;
2112
+ const indexB = panelOrder.get(b) ?? -1;
2113
+ if (indexA === indexB)
2114
+ return 0;
2115
+ if (indexA === -1)
2116
+ return 1;
2117
+ if (indexB === -1)
2118
+ return -1;
2119
+ return indexA - indexB;
2120
+ });
2121
+ }
1843
2122
  }
1844
2123
  }
1845
2124
  /** Emits change event to set the model value. */
@@ -1851,7 +2130,8 @@ class KbqSelect extends KbqAbstractSelect {
1851
2130
  else {
1852
2131
  valueToEmit = this.selected ? this.selected.value : fallbackValue;
1853
2132
  }
1854
- this._value = valueToEmit;
2133
+ this.selectionValue = valueToEmit;
2134
+ this.value.set(valueToEmit);
1855
2135
  this.valueChange.emit(valueToEmit);
1856
2136
  this.onChange(valueToEmit);
1857
2137
  this.selectionChange.emit(new KbqSelectChange(this, valueToEmit));
@@ -1863,7 +2143,7 @@ class KbqSelect extends KbqAbstractSelect {
1863
2143
  */
1864
2144
  highlightCorrectOption() {
1865
2145
  if (this.keyManager) {
1866
- if (this.empty || !this.firstSelected || this.firstFiltered) {
2146
+ if (this.empty() || !this.firstSelected || this.firstFiltered) {
1867
2147
  this.keyManager.setFirstItemActive();
1868
2148
  }
1869
2149
  else {
@@ -1875,7 +2155,7 @@ class KbqSelect extends KbqAbstractSelect {
1875
2155
  this.keyManager.activeItem?.focus();
1876
2156
  }
1877
2157
  /** Function for handling the combination Ctrl + A (select all). By default, the internal handler is used. */
1878
- _selectAllHandler(event, select) {
2158
+ defaultSelectAllHandler(event, select) {
1879
2159
  const searchInput = isInput(event) ? event.target : null;
1880
2160
  if (shouldSelectSearchText(searchInput)) {
1881
2161
  searchInput.select();
@@ -1905,57 +2185,8 @@ class KbqSelect extends KbqAbstractSelect {
1905
2185
  const selected = selectableOptions.length > 0 && selectableOptions.every((option) => option.selected);
1906
2186
  select.onSelectAll.emit(new KbqSelectAllEvent(select, selectableOptions, selected));
1907
2187
  }
1908
- /**
1909
- * Calculates the total width and count of visible items.
1910
- * @returns Tuple of [totalVisibleItemsWidth, visibleItemsCount].
1911
- */
1912
- getTotalVisibleItems() {
1913
- const triggerClone = this.buildTriggerClone();
1914
- const hiddenText = triggerClone.querySelector('.kbq-select__match-hidden-text');
1915
- if (hiddenText) {
1916
- this._renderer.setStyle(hiddenText, 'display', 'block');
1917
- }
1918
- this._renderer.appendChild(this.trigger().nativeElement, triggerClone);
1919
- let visibleItemsCount = 0;
1920
- let totalVisibleItemsWidth = 0;
1921
- triggerClone.querySelectorAll('kbq-tag').forEach((item) => {
1922
- if (item.offsetTop < item.offsetHeight) {
1923
- totalVisibleItemsWidth += this.getItemWidth(item);
1924
- visibleItemsCount++;
1925
- }
1926
- });
1927
- triggerClone.remove();
1928
- return [totalVisibleItemsWidth, visibleItemsCount];
1929
- }
1930
- /**
1931
- * Creates a hidden clone of the trigger element for width calculations.
1932
- * @returns Clone of the trigger element positioned off-screen.
1933
- */
1934
- buildTriggerClone() {
1935
- const triggerClone = this.trigger().nativeElement.cloneNode(true);
1936
- this._renderer.setStyle(triggerClone, 'position', 'absolute');
1937
- this._renderer.setStyle(triggerClone, 'visibility', 'hidden');
1938
- this._renderer.setStyle(triggerClone, 'top', '-100%');
1939
- this._renderer.setStyle(triggerClone, 'left', '0');
1940
- this._renderer.setStyle(triggerClone, 'max-width', '100%');
1941
- return triggerClone;
1942
- }
1943
- /** Adds the dropdown class to the overlay container when first select opens. */
1944
- addClassToOverlayContainer() {
1945
- const overlayContainer = this.overlayContainer?.getContainerElement();
1946
- if (overlayContainer.childNodes.length === 1) {
1947
- this.classAddedToOverlayContainer = true;
1948
- this._renderer.addClass(overlayContainer, 'cdk-overlay-container_dropdown');
1949
- }
1950
- }
1951
- /** Removes the dropdown class from the overlay container when select closes. */
1952
- removeClassFromOverlayContainer() {
1953
- if (this.classAddedToOverlayContainer) {
1954
- this._renderer.removeClass(this.overlayContainer.getContainerElement(), 'cdk-overlay-container_dropdown');
1955
- }
1956
- }
1957
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelect, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1958
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: KbqSelect, isStandalone: true, selector: "kbq-select", inputs: { hiddenItemsText: { classPropertyName: "hiddenItemsText", publicName: "hiddenItemsText", isSignal: false, isRequired: false, transformFunction: null }, showPreselectedValues: { classPropertyName: "showPreselectedValues", publicName: "showPreselectedValues", isSignal: true, isRequired: false, transformFunction: null }, triggerValuesLimit: { classPropertyName: "triggerValuesLimit", publicName: "triggerValuesLimit", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, backdropClass: { classPropertyName: "backdropClass", publicName: "backdropClass", isSignal: true, isRequired: false, transformFunction: null }, errorStateMatcher: { classPropertyName: "errorStateMatcher", publicName: "errorStateMatcher", isSignal: false, isRequired: false, transformFunction: null }, sortComparator: { classPropertyName: "sortComparator", publicName: "sortComparator", isSignal: true, isRequired: false, transformFunction: null }, multiline: { classPropertyName: "multiline", publicName: "multiline", isSignal: true, isRequired: false, transformFunction: null }, searchMinOptionsThreshold: { classPropertyName: "searchMinOptionsThreshold", publicName: "searchMinOptionsThreshold", isSignal: false, isRequired: false, transformFunction: null }, scrolledToBottomOffset: { classPropertyName: "scrolledToBottomOffset", publicName: "scrolledToBottomOffset", isSignal: true, isRequired: false, transformFunction: null }, hasBackdrop: { classPropertyName: "hasBackdrop", publicName: "hasBackdrop", isSignal: false, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: false, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: false, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: false, isRequired: false, transformFunction: null }, virtualOptionFactory: { classPropertyName: "virtualOptionFactory", publicName: "virtualOptionFactory", isSignal: true, isRequired: false, transformFunction: null }, selectAllToggle: { classPropertyName: "selectAllToggle", publicName: "selectAllToggle", isSignal: true, isRequired: false, transformFunction: null }, selectAll: { classPropertyName: "selectAll", publicName: "selectAll", isSignal: true, isRequired: false, transformFunction: null }, selectAllHandler: { classPropertyName: "selectAllHandler", publicName: "selectAllHandler", isSignal: false, isRequired: false, transformFunction: null }, panelWidth: { classPropertyName: "panelWidth", publicName: "panelWidth", isSignal: true, isRequired: false, transformFunction: null }, panelMinWidth: { classPropertyName: "panelMinWidth", publicName: "panelMinWidth", isSignal: true, isRequired: false, transformFunction: null }, panelMaxWidth: { classPropertyName: "panelMaxWidth", publicName: "panelMaxWidth", isSignal: true, isRequired: false, transformFunction: null }, panelMaxHeight: { classPropertyName: "panelMaxHeight", publicName: "panelMaxHeight", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: false, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: false, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: false, isRequired: false, transformFunction: numberAttribute }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, hiddenItemsTextFormatter: { classPropertyName: "hiddenItemsTextFormatter", publicName: "hiddenItemsTextFormatter", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { openedChange: "openedChange", beforeOpened: "beforeOpened", openedStream: "opened", closedStream: "closed", selectionChange: "selectionChange", onSelectAll: "onSelectAll", valueChange: "valueChange", scrolledToBottom: "scrolledToBottom" }, host: { listeners: { "click": "toggle()", "keydown": "handleKeydown($event)", "focus": "onFocus()", "blur": "onBlur()" }, properties: { "attr.tabindex": "tabIndex", "attr.disabled": "disabled || null", "class.kbq-select_multiple": "multiple", "class.kbq-select_multiline": "multiline()", "class.kbq-disabled": "disabled", "class.kbq-invalid": "errorState" }, classAttribute: "kbq-select" }, providers: [
2188
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqSelect, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2189
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.25", type: KbqSelect, isStandalone: true, selector: "kbq-select", inputs: { hiddenItemsText: { classPropertyName: "hiddenItemsText", publicName: "hiddenItemsText", isSignal: true, isRequired: false, transformFunction: null }, hiddenItemsTextFormatter: { classPropertyName: "hiddenItemsTextFormatter", publicName: "hiddenItemsTextFormatter", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, showPreselectedValues: { classPropertyName: "showPreselectedValues", publicName: "showPreselectedValues", isSignal: true, isRequired: false, transformFunction: null }, triggerValuesLimit: { classPropertyName: "triggerValuesLimit", publicName: "triggerValuesLimit", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, backdropClass: { classPropertyName: "backdropClass", publicName: "backdropClass", isSignal: true, isRequired: false, transformFunction: null }, errorStateMatcher: { classPropertyName: "errorStateMatcher", publicName: "errorStateMatcher", isSignal: true, isRequired: false, transformFunction: null }, sortComparator: { classPropertyName: "sortComparator", publicName: "sortComparator", isSignal: true, isRequired: false, transformFunction: null }, multiline: { classPropertyName: "multiline", publicName: "multiline", isSignal: true, isRequired: false, transformFunction: null }, searchMinOptionsThresholdInput: { classPropertyName: "searchMinOptionsThresholdInput", publicName: "searchMinOptionsThreshold", isSignal: true, isRequired: false, transformFunction: null }, scrolledToBottomOffset: { classPropertyName: "scrolledToBottomOffset", publicName: "scrolledToBottomOffset", isSignal: true, isRequired: false, transformFunction: null }, hasBackdrop: { classPropertyName: "hasBackdrop", publicName: "hasBackdrop", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, multipleInput: { classPropertyName: "multipleInput", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null }, virtualOptionFactory: { classPropertyName: "virtualOptionFactory", publicName: "virtualOptionFactory", isSignal: true, isRequired: false, transformFunction: null }, clearPredicate: { classPropertyName: "clearPredicate", publicName: "clearPredicate", isSignal: true, isRequired: false, transformFunction: null }, selectAllToggle: { classPropertyName: "selectAllToggle", publicName: "selectAllToggle", isSignal: true, isRequired: false, transformFunction: null }, selectAll: { classPropertyName: "selectAll", publicName: "selectAll", isSignal: true, isRequired: false, transformFunction: null }, selectAllHandlerInput: { classPropertyName: "selectAllHandlerInput", publicName: "selectAllHandler", isSignal: true, isRequired: false, transformFunction: null }, panelWidth: { classPropertyName: "panelWidth", publicName: "panelWidth", isSignal: true, isRequired: false, transformFunction: null }, panelMinWidth: { classPropertyName: "panelMinWidth", publicName: "panelMinWidth", isSignal: true, isRequired: false, transformFunction: null }, panelMaxWidth: { classPropertyName: "panelMaxWidth", publicName: "panelMaxWidth", isSignal: true, isRequired: false, transformFunction: null }, panelMaxHeight: { classPropertyName: "panelMaxHeight", publicName: "panelMaxHeight", isSignal: true, isRequired: false, transformFunction: null }, valueInput: { classPropertyName: "valueInput", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, idInput: { classPropertyName: "idInput", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, tabIndexInput: { classPropertyName: "tabIndexInput", publicName: "tabIndex", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openedChangeOutput: "openedChange", beforeOpened: "beforeOpened", openedOutput: "opened", closedOutput: "closed", selectionChange: "selectionChange", onSelectAll: "onSelectAll", valueChange: "valueChange", scrolledToBottom: "scrolledToBottom" }, host: { attributes: { "role": "combobox", "aria-haspopup": "listbox" }, listeners: { "click": "toggle()", "keydown": "handleKeydown($event)", "focus": "onFocus()", "blur": "onBlur()" }, properties: { "attr.tabindex": "tabIndex", "attr.disabled": "disabledAttribute()", "attr.aria-expanded": "panelOpen", "attr.aria-controls": "panelOpen ? panelId : null", "attr.aria-labelledby": "ariaLabelledby", "attr.aria-label": "resolvedAriaLabel", "attr.aria-invalid": "errorState()", "attr.aria-required": "required()", "attr.aria-disabled": "disabled()", "class.kbq-select_multiple": "multiple", "class.kbq-select_multiline": "multiline()", "class.kbq-disabled": "disabledClass()", "class.kbq-invalid": "invalidClass()" }, classAttribute: "kbq-select" }, providers: [
1959
2190
  { provide: KbqFormFieldControl, useExisting: KbqSelect },
1960
2191
  kbqCleanerFactoryProvider((() => {
1961
2192
  const select = inject(KbqSelect);
@@ -1963,32 +2194,30 @@ class KbqSelect extends KbqAbstractSelect {
1963
2194
  get control() {
1964
2195
  return select;
1965
2196
  },
1966
- get keydownTarget() {
1967
- return select.elementRef.nativeElement;
1968
- },
1969
2197
  clearByEscape: false,
1970
- clear: (() => select.clear())
2198
+ clear: (() => select.clear()),
2199
+ canClear: (() => select.canClear)
1971
2200
  };
1972
2201
  })),
1973
2202
  { provide: KBQ_OPTION_PARENT_COMPONENT, useExisting: KbqSelect },
1974
2203
  { provide: KBQ_PARENT_POPUP, useExisting: KbqSelect },
1975
- kbqSiblingPopupProvider(KbqSelect)
1976
- ], queries: [{ propertyName: "footer", first: true, predicate: KbqSelectFooter, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "cdkVirtualForOf", first: true, predicate: CdkVirtualForOf, descendants: true, isSignal: true }, { propertyName: "virtualScrollViewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true, isSignal: true }, { propertyName: "customTrigger", first: true, predicate: KbqSelectTrigger, descendants: true, isSignal: true }, { propertyName: "customMatcher", first: true, predicate: KbqSelectMatcher, descendants: true, isSignal: true }, { propertyName: "customTagTemplateRef", first: true, predicate: ["kbqSelectTagContent"], descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "cleaner", first: true, predicate: KbqCleaner, isSignal: true }, { propertyName: "optionGroups", predicate: KbqOptgroup, isSignal: true }, { propertyName: "search", first: true, predicate: KbqSelectSearch, descendants: true, isSignal: true }, { propertyName: "searchEmpty", first: true, predicate: KbqSelectSearchEmptyResult, descendants: true, isSignal: true }, { propertyName: "options", predicate: KbqOption, descendants: true }], viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "panel", first: true, predicate: ["panel"], descendants: true, isSignal: true }, { propertyName: "optionsContainer", first: true, predicate: ["optionsContainer"], descendants: true, isSignal: true }, { propertyName: "selectAllOption", first: true, predicate: KbqOption, descendants: true, isSignal: true }, { propertyName: "overlayDir", first: true, predicate: CdkConnectedOverlay, descendants: true }, { propertyName: "tags", predicate: KbqTag, descendants: true }], exportAs: ["kbqSelect"], usesInheritance: true, ngImport: i0, template: "<div\n #fallbackOverlayOrigin=\"cdkOverlayOrigin\"\n #trigger\n cdkOverlayOrigin\n class=\"kbq-select__trigger\"\n [class.kbq-select__trigger_empty]=\"empty\"\n [class.kbq-select__trigger_multiline]=\"multiline()\"\n [class.kbq-select__trigger_multiple]=\"multiple\"\n [class.kbq-select__trigger_single]=\"!multiple\"\n>\n @if (!!customMatcher()) {\n <ng-content select=\"kbq-select-matcher, [kbq-select-matcher]\" />\n } @else {\n <div class=\"kbq-select__matcher\">\n @if (empty) {\n <span class=\"kbq-select__placeholder\">\n {{ placeholder || '\\u00A0' }}\n </span>\n } @else {\n @if (!!customTrigger()) {\n <ng-content select=\"kbq-select-trigger, [kbq-select-trigger]\" />\n } @else {\n <div class=\"kbq-select__match-container\">\n @if (multiSelection) {\n <div\n #multilineMatchList\n [class.kbq-select__match-list]=\"!multiline()\"\n [class.kbq-select__multiline-match-list]=\"multiline()\"\n >\n @if (!customTagTemplateRef()) {\n @for (option of triggerValues; track option) {\n <kbq-tag\n [color]=\"colorForState\"\n [disabled]=\"option.disabled || disabled\"\n [selectable]=\"false\"\n >\n {{ option.viewValue }}\n @if (!option.disabled && !disabled) {\n <i\n kbq-icon=\"kbq-xmark-s_16\"\n kbqTagRemove\n (click)=\"onRemoveMatcherItem(option, $event)\"\n ></i>\n }\n </kbq-tag>\n }\n } @else {\n @for (option of triggerValues; track option) {\n <ng-container\n [ngTemplateOutlet]=\"$any(customTagTemplateRef())\"\n [ngTemplateOutletContext]=\"{ $implicit: option, select: this }\"\n />\n }\n }\n </div>\n\n @if (!multiline()) {\n <div\n class=\"kbq-select__match-hidden-text\"\n [style.display]=\"hiddenItems > 0 ? 'block' : 'none'\"\n >\n {{ hiddenItemsTextFormatter(hiddenItemsText, hiddenItems) }}\n </div>\n }\n } @else {\n <span class=\"kbq-select__matcher-text\">\n {{ triggerValue }}\n </span>\n }\n </div>\n }\n }\n\n @if (canShowCleaner) {\n <div class=\"kbq-select__cleaner\">\n <ng-content select=\"kbq-cleaner\" />\n </div>\n }\n\n <div class=\"kbq-select__arrow-wrapper\">\n <i kbq-icon=\"kbq-chevron-down-s_16\" class=\"kbq-select__arrow\" [color]=\"colorForState\"></i>\n </div>\n </div>\n }\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayLockPosition\n [cdkConnectedOverlayBackdropClass]=\"backdropClass()\"\n [cdkConnectedOverlayHasBackdrop]=\"hasBackdrop\"\n [cdkConnectedOverlayMinWidth]=\"overlayMinWidth\"\n [cdkConnectedOverlayOpen]=\"panelOpen\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin || fallbackOverlayOrigin\"\n [cdkConnectedOverlayPanelClass]=\"overlayPanelClass\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n [cdkConnectedOverlayViewportMargin]=\"viewportMargin\"\n [cdkConnectedOverlayWidth]=\"overlayWidth\"\n (attach)=\"onAttached()\"\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n>\n <div\n #panel\n cdkMonitorSubtreeFocus\n [class]=\"getPanelClasses()\"\n [style.--kbq-select-panel-size-max-height]=\"panelMaxHeightToken()\"\n [style.font-size.px]=\"triggerFontSize\"\n [style.max-width.px]=\"panelMaxWidth()\"\n [style.transformOrigin]=\"transformOrigin\"\n (click)=\"handleClick($event)\"\n (keydown)=\"handleKeydown($event)\"\n >\n @if (search() && shouldShowSearch()) {\n <div class=\"kbq-select__search-container\">\n <ng-content select=\"[kbqSelectSearch]\" />\n </div>\n }\n\n <div\n #optionsContainer\n class=\"kbq-select__content\"\n [class.kbq-scrollbar]=\"!withVirtualScroll\"\n [@fadeInContent]=\"'showing'\"\n (@fadeInContent.done)=\"panelDoneAnimatingStream.next($event.toState)\"\n >\n @if (isEmptySearchResult) {\n <ng-content select=\"[kbq-select-search-empty-result]\" />\n }\n @if (showSelectAll) {\n <!-- Every read of selectAllState re-filters the whole option list, and allOptionsSelected\n is that same walk asking whether the state is \"checked\" \u2014 one read covers all four. -->\n @let selectAllCheckboxState = selectAllState;\n\n <kbq-option\n class=\"kbq-select__select-all\"\n [selectable]=\"false\"\n [class.kbq-selected]=\"selectAllCheckboxState === 'checked'\"\n [attr.role]=\"'checkbox'\"\n [attr.aria-checked]=\"\n selectAllCheckboxState === 'indeterminate' ? 'mixed' : selectAllCheckboxState === 'checked'\n \"\n (click)=\"toggleSelectAll()\"\n >\n <kbq-pseudo-checkbox [state]=\"selectAllCheckboxState\" />\n {{ selectAllText }}\n </kbq-option>\n }\n <ng-content />\n </div>\n\n <ng-content select=\"kbq-select-footer,[kbq-select-footer]\" />\n </div>\n</ng-template>\n", styles: [".kbq-select{box-sizing:border-box;display:inline-block;width:100%;outline:none}.kbq-select .kbq-select__trigger{display:flex;box-sizing:border-box;position:relative;cursor:pointer;min-height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-border-width) * 2)}.kbq-select .kbq-select__trigger:not(.kbq-select__trigger_multiline),.kbq-select .kbq-select__trigger.kbq-select__trigger_empty{height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-border-width) * 2)}.kbq-select .kbq-select__trigger:not(.kbq-select__trigger_multiline) .kbq-select__matcher,.kbq-select .kbq-select__trigger.kbq-select__trigger_empty .kbq-select__matcher{overflow:hidden;white-space:nowrap}.kbq-select .kbq-select__matcher{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-grow:1;align-items:center}.kbq-select .kbq-select__matcher>span{flex:1;overflow:hidden}.kbq-select .kbq-select__trigger.kbq-select__trigger_single .kbq-select__matcher,.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple.kbq-select__trigger_empty .kbq-select__matcher{padding:var(--kbq-select-size-single-padding-vertical) var(--kbq-select-size-single-padding-right) var(--kbq-select-size-single-padding-vertical) var(--kbq-select-size-single-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher{padding:var(--kbq-select-size-multiple-padding-vertical) var(--kbq-select-size-multiple-padding-right) var(--kbq-select-size-multiple-padding-vertical) var(--kbq-select-size-multiple-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher .kbq-select__match-container{display:flex}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher .kbq-select__match-list{display:flex;flex-wrap:wrap;overflow:hidden;height:calc(var(--kbq-form-field-size-height) - var(--kbq-select-size-multiple-padding-vertical) * 2);max-height:calc(var(--kbq-form-field-size-height) - var(--kbq-select-size-multiple-padding-vertical) * 2);gap:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));margin-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs))}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__match-container{flex-direction:column}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__matcher{max-width:100%;padding:calc(var(--kbq-select-size-multiple-padding-vertical) - var(--kbq-size-border-width)) var(--kbq-select-size-multiple-padding-right) calc(var(--kbq-select-size-multiple-padding-vertical) - var(--kbq-size-border-width)) var(--kbq-select-size-multiple-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__cleaner,.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__arrow-wrapper{align-self:flex-start;align-items:center;height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-s));min-width:var(--kbq-form-field-size-addon-width)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__multiline-match-list{display:flex;flex-direction:row;flex-wrap:wrap;margin-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));gap:var(--kbq-size-xxs)}.kbq-select .kbq-select__match-container{width:100%;text-overflow:ellipsis;overflow:hidden}.kbq-select .kbq-select__match-container .kbq-select__match-hidden-text{box-sizing:content-box;flex:0 0 var(--kbq-form-field-size-addon-width);align-self:center;padding-left:var(--kbq-size-xxs);padding-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));text-align:right}.kbq-select kbq-select-trigger,.kbq-select [kbq-select-trigger]{width:100%}.kbq-select .kbq-select__arrow-wrapper{display:flex;align-self:center;justify-content:center;min-width:var(--kbq-form-field-size-addon-width)}.kbq-form-field-appearance-fill .kbq-select .kbq-select__arrow-wrapper,.kbq-form-field-appearance-standard .kbq-select .kbq-select__arrow-wrapper{transform:translateY(-50%)}.kbq-form-field-appearance-outline .kbq-select .kbq-select__arrow-wrapper{transform:translateY(-25%)}.kbq-disabled.kbq-select .kbq-select__trigger{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.kbq-select__panel{min-width:100%;max-width:var(--kbq-panel-size-width-max, 640px);overflow:hidden;border-radius:var(--kbq-select-panel-size-border-radius, var(--kbq-size-border-radius))}.kbq-select__panel .kbq-option{font-size:inherit}.kbq-select__panel .kbq-select__no-options-message{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-direction:row;align-items:center;justify-content:center;box-sizing:border-box;position:relative;margin-bottom:var(--kbq-size-3xl);margin-top:var(--kbq-size-3xl);max-width:100%;height:var(--kbq-option-size-height, var(--kbq-size-3xl));cursor:default;outline:none;padding-left:var(--kbq-option-size-horizontal-padding, var(--kbq-size-m));padding-right:var(--kbq-option-size-horizontal-padding, var(--kbq-size-m));border:var(--kbq-option-size-border-width, var(--kbq-size-3xs)) solid transparent}.kbq-select__panel .kbq-select__search-container{padding:var(--kbq-size-xxs);border-bottom-width:1px;border-bottom-style:solid}.kbq-select__content{box-sizing:initial;max-height:var(--kbq-select-panel-size-max-height, 256px);padding:var(--kbq-size-xxs);overflow:hidden auto}.kbq-select__panel .kbq-select__footer{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;align-items:center;box-sizing:border-box;min-height:var(--kbq-select-footer-size-min-height, var(--kbq-size-4xl));border-top-width:var(--kbq-select-footer-size-border-width, var(--kbq-size-border-width));border-top-style:solid;padding:var(--kbq-select-footer-size-padding-vertical, var(--kbq-size-xxs)) var(--kbq-select-footer-size-padding-horizontal, var(--kbq-size-l))}.kbq-select__panel .kbq-select__footer-item{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;display:flex;flex-direction:row;align-items:center;box-sizing:border-box;outline:none;flex:1 1 auto;min-height:var(--kbq-select-footer-item-size-height, var(--kbq-size-3xl));gap:var(--kbq-size-s);border:var(--kbq-size-3xs) solid transparent;border-radius:var(--kbq-select-footer-item-size-border-radius, var(--kbq-size-xxs));padding:0 calc(var(--kbq-size-m) - var(--kbq-size-3xs));background:transparent;cursor:pointer;text-align:left;text-decoration:none}.kbq-select__panel .kbq-select__footer:has(.kbq-select__footer-item){--kbq-select-footer-size-padding-horizontal: var(--kbq-size-xxs)}.kbq-select__content .kbq-option{position:relative}.kbq-select__content .kbq-option:before,.kbq-select__content .kbq-option:after{position:absolute;content:\"\";width:var(--kbq-size-xxs);height:calc(100% + var(--kbq-size-3xs) * 2)}.kbq-select__content .kbq-option:before{right:calc(100% + var(--kbq-size-3xs))}.kbq-select__content .kbq-option:after{left:calc(100% + var(--kbq-size-3xs))}.kbq-select__content:not(:has(>.kbq-select__no-options-message)) .cdk-virtual-scroll-viewport{min-height:var(--kbq-select-panel-size-max-height, 256px);max-height:var(--kbq-select-panel-size-max-height, 256px)}.kbq-select__content:not(:has(>.kbq-select__no-options-message)) .cdk-virtual-scroll-viewport.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper{max-width:100%}.kbq-form-field-type-select:not(.kbq-disabled) .kbq-form-field-flex{cursor:pointer}.kbq-select{color:var(--kbq-foreground-contrast)}.kbq-select.kbq-control_has-validate-directive.ng-invalid,.kbq-select.kbq-invalid{color:var(--kbq-foreground-error)}.kbq-select.kbq-control_has-validate-directive.ng-invalid .kbq-select__placeholder,.kbq-select.kbq-invalid .kbq-select__placeholder{color:var(--kbq-form-field-states-error-placeholder)}.kbq-select.kbq-disabled{color:var(--kbq-states-foreground-disabled)}.kbq-select.kbq-disabled .kbq-select__placeholder{color:var(--kbq-form-field-states-disabled-placeholder)}.kbq-select__placeholder{text-overflow:ellipsis;color:var(--kbq-form-field-default-placeholder)}.kbq-select__panel{box-shadow:var(--kbq-select-panel-dropdown-shadow);background:var(--kbq-select-panel-dropdown-background)}.kbq-select__panel .kbq-select__footer{border-color:var(--kbq-divider-color, var(--kbq-line-contrast-less))}.kbq-select__panel .kbq-select__footer-item{color:var(--kbq-foreground-contrast)}.kbq-select__panel .kbq-select__footer-item:focus-visible{border-color:var(--kbq-states-line-focus-theme)}.kbq-select__panel .kbq-select__footer-item:hover:not(:disabled,.kbq-disabled){background:var(--kbq-states-background-transparent-hover)}.kbq-select__panel .kbq-select__footer-item:active:not(:disabled,.kbq-disabled){background:var(--kbq-states-background-transparent-active)}.kbq-select__panel .kbq-select__footer-item:disabled,.kbq-select__panel .kbq-select__footer-item.kbq-disabled{color:var(--kbq-states-foreground-disabled);cursor:default;pointer-events:none}.kbq-select__panel .kbq-select__footer-item:disabled .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item),.kbq-select__panel .kbq-select__footer-item.kbq-disabled .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item){color:var(--kbq-states-foreground-disabled)}.kbq-select__search-container{border-bottom-color:var(--kbq-divider-color, var(--kbq-line-contrast-less))}.kbq-select__no-options-message{color:var(--kbq-foreground-contrast-secondary)}.kbq-select,.kbq-select__panel,.kbq-select__footer-item{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}\n", ".kbq-select,.kbq-tree-select,.kbq-select__panel{--kbq-select-size-single-padding-left: 0;--kbq-select-size-single-padding-right: 0;--kbq-select-size-single-padding-vertical: var(--kbq-size-xs);--kbq-select-size-single-content-gap: var(--kbq-size-xxs);--kbq-select-size-multiple-padding-left: 0;--kbq-select-size-multiple-padding-right: 0;--kbq-select-size-multiple-padding-vertical: var(--kbq-size-xxs);--kbq-select-size-multiple-content-gap: var(--kbq-size-xxs);--kbq-select-panel-size-border-radius: var(--kbq-size-border-radius);--kbq-select-panel-dropdown-background: var(--kbq-background-card);--kbq-select-panel-dropdown-shadow: var(--kbq-shadow-popup)}\n"], dependencies: [{ kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: KbqTag, selector: "kbq-tag, [kbq-tag], kbq-basic-tag, [kbq-basic-tag]", inputs: ["editable", "preventEditSubmit", "selected", "value", "selectable", "removable", "tabindex", "disabled"], outputs: ["editChange", "selectionChange", "destroyed", "removed"], exportAs: ["kbqTag"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdkMonitorFocus, selector: "[cdkMonitorElementFocus], [cdkMonitorSubtreeFocus]", outputs: ["cdkFocusChange"], exportAs: ["cdkMonitorFocus"] }, { kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "ngmodule", type: KbqIconModule }, { kind: "component", type: i1$1.KbqIcon, selector: "[kbq-icon]", inputs: ["small", "autoColor", "kbq-icon"] }, { kind: "component", type: KbqOption, selector: "kbq-option", inputs: ["value", "selectable", "userSelect", "showCheckbox", "viewValue", "disabled"], outputs: ["onSelectionChange"], exportAs: ["kbqOption"] }, { kind: "component", type: KbqPseudoCheckbox, selector: "kbq-pseudo-checkbox", inputs: ["big", "state", "disabled"] }], animations: [
1977
- kbqSelectAnimations.transformPanel,
1978
- kbqSelectAnimations.fadeInContent
1979
- ], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
2204
+ kbqSiblingPopupProvider(KbqSelect),
2205
+ KbqSelectHiddenItemsMeasurer
2206
+ ], queries: [{ propertyName: "projectedScrollbarViewport", first: true, predicate: KbqScrollbarViewport, descendants: true, isSignal: true }, { propertyName: "footer", first: true, predicate: KbqSelectFooter, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "cdkVirtualForOf", first: true, predicate: CdkVirtualForOf, descendants: true, isSignal: true }, { propertyName: "virtualScrollViewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true, isSignal: true }, { propertyName: "customTrigger", first: true, predicate: KbqSelectTrigger, descendants: true, isSignal: true }, { propertyName: "customMatcher", first: true, predicate: KbqSelectMatcher, descendants: true, isSignal: true }, { propertyName: "customTagTemplateRef", first: true, predicate: ["kbqSelectTagContent"], descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "cleaner", first: true, predicate: KbqCleaner, isSignal: true }, { propertyName: "optionsQuery", predicate: KbqOption, descendants: true, isSignal: true }, { propertyName: "optionGroups", predicate: KbqOptgroup, isSignal: true }, { propertyName: "search", first: true, predicate: KbqSelectSearch, descendants: true, isSignal: true }, { propertyName: "searchEmpty", first: true, predicate: KbqSelectSearchEmptyResult, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "panel", first: true, predicate: ["panel"], descendants: true, isSignal: true }, { propertyName: "optionsContainer", first: true, predicate: ["optionsContainer"], descendants: true, isSignal: true }, { propertyName: "scrollbarViewport", first: true, predicate: KbqScrollbarViewport, descendants: true, isSignal: true }, { propertyName: "selectAllOption", first: true, predicate: KbqOption, descendants: true, isSignal: true }, { propertyName: "overlayDirQuery", first: true, predicate: CdkConnectedOverlay, descendants: true, isSignal: true }, { propertyName: "tagsQuery", predicate: KbqTag, descendants: true, isSignal: true }], exportAs: ["kbqSelect"], usesInheritance: true, hostDirectives: [{ directive: i1$1.KbqLocaleOverridesDirective, inputs: ["kbqLocaleOverrides", "localeOverrides"] }], ngImport: i0, template: "<div\n #fallbackOverlayOrigin=\"cdkOverlayOrigin\"\n #trigger\n cdkOverlayOrigin\n class=\"kbq-select__trigger\"\n [class.kbq-select__trigger_empty]=\"empty()\"\n [class.kbq-select__trigger_multiline]=\"multiline()\"\n [class.kbq-select__trigger_multiple]=\"multiple\"\n [class.kbq-select__trigger_single]=\"!multiple\"\n>\n @if (!!customMatcher()) {\n <ng-content select=\"kbq-select-matcher, [kbq-select-matcher]\" />\n } @else {\n <div class=\"kbq-select__matcher\">\n @if (empty()) {\n <span class=\"kbq-select__placeholder\">\n {{ placeholder() || '\\u00A0' }}\n </span>\n } @else {\n @if (!!customTrigger()) {\n <ng-content select=\"kbq-select-trigger, [kbq-select-trigger]\" />\n } @else {\n <div class=\"kbq-select__match-container\">\n @if (multiSelection) {\n <div\n #multilineMatchList\n [class.kbq-select__match-list]=\"!multiline()\"\n [class.kbq-select__multiline-match-list]=\"multiline()\"\n >\n @if (customTagTemplateRef(); as tagTemplate) {\n @for (option of triggerValues; track option) {\n <ng-container\n [ngTemplateOutlet]=\"tagTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: option, select: this }\"\n />\n }\n } @else {\n @for (option of triggerValues; track option) {\n <kbq-tag\n [color]=\"colorForState\"\n [disabled]=\"option.disabled || disabled()\"\n [selectable]=\"false\"\n >\n {{ option.viewValue }}\n @if (!option.disabled && !disabled()) {\n <!--\n `kbqTagRemove` now carries the role, the accessible\n name and keyboard activation itself, so this binds\n only what is select-specific. The name goes through\n the `aria-label` input rather than `[attr.aria-label]`\n \u2014 the directive renders the attribute, so writing it\n here would be overwritten by its default.\n -->\n <i\n kbq-icon=\"kbq-xmark-s_16\"\n kbqTagRemove\n [aria-label]=\"removeItemAriaLabel(option)\"\n [tabIndex]=\"isTriggerValueVisible($index) ? 0 : -1\"\n (click)=\"onRemoveMatcherItem(option, $event)\"\n ></i>\n }\n </kbq-tag>\n }\n }\n </div>\n\n @if (!multiline()) {\n <div\n class=\"kbq-select__match-hidden-text\"\n [class.kbq-select__match-hidden-text_visible]=\"hiddenItems() > 0\"\n >\n {{ hiddenItemsLabel }}\n </div>\n }\n } @else {\n <span class=\"kbq-select__matcher-text\">\n {{ triggerValue }}\n </span>\n }\n </div>\n }\n }\n\n @if (canShowCleaner) {\n <div class=\"kbq-select__cleaner\">\n <ng-content select=\"kbq-cleaner\" />\n </div>\n }\n\n <div class=\"kbq-select__arrow-wrapper\">\n <i kbq-icon=\"kbq-chevron-down-s_16\" class=\"kbq-select__arrow\" [color]=\"colorForState\"></i>\n </div>\n </div>\n }\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayLockPosition\n [cdkConnectedOverlayBackdropClass]=\"backdropClass()\"\n [cdkConnectedOverlayHasBackdrop]=\"hasBackdrop()\"\n [cdkConnectedOverlayMinWidth]=\"overlayMinWidth\"\n [cdkConnectedOverlayOpen]=\"panelOpen\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin || fallbackOverlayOrigin\"\n [cdkConnectedOverlayPanelClass]=\"overlayPanelClass\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n [cdkConnectedOverlayViewportMargin]=\"viewportMargin\"\n [cdkConnectedOverlayWidth]=\"overlayWidth\"\n (attach)=\"onAttached()\"\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n>\n <div\n #panel\n cdkMonitorSubtreeFocus\n [class]=\"getPanelClasses()\"\n [style.--kbq-select-panel-size-max-height]=\"panelMaxHeightToken()\"\n [style.font-size.px]=\"triggerFontSize\"\n [style.max-width.px]=\"panelMaxWidth()\"\n [style.transformOrigin]=\"transformOrigin\"\n (click)=\"handleClick($event)\"\n (keydown)=\"handleKeydown($event)\"\n >\n @if (search() && shouldShowSearch()) {\n <div class=\"kbq-select__search-container\">\n <ng-content select=\"[kbqSelectSearch]\" />\n </div>\n }\n\n <div\n #optionsContainer\n kbqScrollbarViewport\n role=\"listbox\"\n class=\"kbq-select__content\"\n [kbqScrollbarMode]=\"scrollbarMode\"\n [id]=\"panelId\"\n [attr.aria-multiselectable]=\"multiSelection\"\n [attr.aria-labelledby]=\"ariaLabelledby\"\n [attr.aria-label]=\"resolvedAriaLabel\"\n [attr.aria-busy]=\"isOptionsListBusy || null\"\n >\n @if (isEmptySearchResult) {\n <ng-content select=\"[kbq-select-search-empty-result]\" />\n }\n @if (showSelectAll) {\n <!-- Every read of selectAllState re-filters the whole option list, and allOptionsSelected\n is that same walk asking whether the state is \"checked\" \u2014 one read covers all four. -->\n @let selectAllCheckboxState = selectAllState;\n\n <!--\n The row stays an `option`: a `checkbox` is not a valid child of the listbox it lives in,\n and `option` carries the tri-state on `aria-checked` just as well.\n -->\n <kbq-option\n class=\"kbq-select__select-all\"\n [selectable]=\"false\"\n [class.kbq-selected]=\"selectAllCheckboxState === 'checked'\"\n [attr.aria-checked]=\"\n selectAllCheckboxState === 'indeterminate' ? 'mixed' : selectAllCheckboxState === 'checked'\n \"\n (click)=\"toggleSelectAll()\"\n >\n <kbq-pseudo-checkbox aria-hidden=\"true\" [state]=\"selectAllCheckboxState\" />\n {{ selectAllText }}\n </kbq-option>\n }\n <ng-content />\n </div>\n\n <ng-content select=\"kbq-select-footer,[kbq-select-footer]\" />\n </div>\n</ng-template>\n", styles: [".kbq-select{box-sizing:border-box;display:inline-block;width:100%;outline:none}.kbq-select .kbq-select__trigger{display:flex;box-sizing:border-box;position:relative;cursor:pointer;min-height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-border-width) * 2)}.kbq-select .kbq-select__trigger:not(.kbq-select__trigger_multiline),.kbq-select .kbq-select__trigger.kbq-select__trigger_empty{height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-border-width) * 2)}.kbq-select .kbq-select__trigger:not(.kbq-select__trigger_multiline) .kbq-select__matcher,.kbq-select .kbq-select__trigger.kbq-select__trigger_empty .kbq-select__matcher{overflow:hidden;white-space:nowrap}.kbq-select .kbq-select__matcher{-webkit-user-select:none;user-select:none;display:flex;flex-grow:1;align-items:center}.kbq-select .kbq-select__matcher>span{flex:1;overflow:hidden}.kbq-select .kbq-select__trigger.kbq-select__trigger_single .kbq-select__matcher,.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple.kbq-select__trigger_empty .kbq-select__matcher{padding:var(--kbq-select-size-single-padding-vertical) var(--kbq-select-size-single-padding-right) var(--kbq-select-size-single-padding-vertical) var(--kbq-select-size-single-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher{padding:var(--kbq-select-size-multiple-padding-vertical) var(--kbq-select-size-multiple-padding-right) var(--kbq-select-size-multiple-padding-vertical) var(--kbq-select-size-multiple-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher .kbq-select__match-container{display:flex}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher .kbq-select__match-list{display:flex;flex-wrap:wrap;overflow:hidden;height:calc(var(--kbq-form-field-size-height) - var(--kbq-select-size-multiple-padding-vertical) * 2);max-height:calc(var(--kbq-form-field-size-height) - var(--kbq-select-size-multiple-padding-vertical) * 2);gap:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));margin-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs))}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__match-container{flex-direction:column}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__matcher{max-width:100%;padding:calc(var(--kbq-select-size-multiple-padding-vertical) - var(--kbq-size-border-width)) var(--kbq-select-size-multiple-padding-right) calc(var(--kbq-select-size-multiple-padding-vertical) - var(--kbq-size-border-width)) var(--kbq-select-size-multiple-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__cleaner,.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__arrow-wrapper{align-self:flex-start;align-items:center;height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-s));min-width:var(--kbq-form-field-size-addon-width)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__multiline-match-list{display:flex;flex-direction:row;flex-wrap:wrap;margin-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));gap:var(--kbq-size-xxs)}.kbq-select .kbq-select__match-container{width:100%;text-overflow:ellipsis;overflow:hidden}.kbq-select .kbq-select__match-container .kbq-select__match-hidden-text{box-sizing:content-box;display:none;flex:0 0 var(--kbq-form-field-size-addon-width);align-self:center;padding-left:var(--kbq-size-xxs);padding-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));text-align:right}.kbq-select .kbq-select__match-container .kbq-select__match-hidden-text.kbq-select__match-hidden-text_visible{display:block}.kbq-select kbq-select-trigger,.kbq-select [kbq-select-trigger]{width:100%}.kbq-select .kbq-select__arrow-wrapper{display:flex;align-self:center;justify-content:center;min-width:var(--kbq-form-field-size-addon-width)}.kbq-disabled.kbq-select .kbq-select__trigger{-webkit-user-select:none;user-select:none;cursor:default}.kbq-select__panel{min-width:100%;max-width:var(--kbq-panel-size-width-max, 640px);overflow:hidden;border-radius:var(--kbq-select-panel-size-border-radius, var(--kbq-size-border-radius))}@supports (corner-shape: squircle){.kbq-select__panel{corner-shape:squircle;border-radius:clamp(var(--kbq-select-panel-size-border-radius, var(--kbq-size-border-radius)) * 1.85,var(--kbq-select-panel-size-border-radius, var(--kbq-size-border-radius)) * 2.3 - 3.6px,var(--kbq-select-panel-size-border-radius, var(--kbq-size-border-radius)) * 2)}}.kbq-select__panel .kbq-option{font-size:inherit}.kbq-select__panel .kbq-select__no-options-message{-webkit-user-select:none;user-select:none;display:flex;flex-direction:row;align-items:center;justify-content:center;box-sizing:border-box;position:relative;margin-bottom:var(--kbq-size-3xl);margin-top:var(--kbq-size-3xl);max-width:100%;height:var(--kbq-option-size-height, var(--kbq-size-3xl));cursor:default;outline:none;padding-left:var(--kbq-option-size-horizontal-padding, var(--kbq-size-m));padding-right:var(--kbq-option-size-horizontal-padding, var(--kbq-size-m));border:var(--kbq-option-size-border-width, var(--kbq-size-3xs)) solid transparent}.kbq-select__panel .kbq-select__search-container{padding:var(--kbq-size-xxs);border-bottom-width:1px;border-bottom-style:solid}.kbq-select__content{box-sizing:initial;max-height:var(--kbq-select-panel-size-max-height, 256px);padding:var(--kbq-size-xxs);overflow:hidden auto}.kbq-select__panel .kbq-select__footer{-webkit-user-select:none;user-select:none;display:flex;align-items:center;box-sizing:border-box;min-height:var(--kbq-select-footer-size-min-height, var(--kbq-size-4xl));border-top-width:var(--kbq-select-footer-size-border-width, var(--kbq-size-border-width));border-top-style:solid;padding:var(--kbq-select-footer-size-padding-vertical, var(--kbq-size-xxs)) var(--kbq-select-footer-size-padding-horizontal, var(--kbq-size-l))}.kbq-select__panel .kbq-select__footer-item{-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;display:flex;flex-direction:row;align-items:center;box-sizing:border-box;outline:none;flex:1 1 auto;min-height:var(--kbq-select-footer-item-size-height, var(--kbq-size-3xl));gap:var(--kbq-size-s);border:var(--kbq-size-3xs) solid transparent;border-radius:var(--kbq-select-footer-item-size-border-radius, var(--kbq-size-xxs))}@supports (corner-shape: squircle){.kbq-select__panel .kbq-select__footer-item{corner-shape:squircle;border-radius:clamp(var(--kbq-select-footer-item-size-border-radius, var(--kbq-size-xxs)) * 1.85,var(--kbq-select-footer-item-size-border-radius, var(--kbq-size-xxs)) * 2.3 - 3.6px,var(--kbq-select-footer-item-size-border-radius, var(--kbq-size-xxs)) * 2)}}.kbq-select__panel .kbq-select__footer-item{padding:0 calc(var(--kbq-size-m) - var(--kbq-size-3xs));background:transparent;cursor:pointer;text-align:left;text-decoration:none}.kbq-select__panel .kbq-select__footer:has(.kbq-select__footer-item){--kbq-select-footer-size-padding-horizontal: var(--kbq-size-xxs)}.kbq-select__content .kbq-option{position:relative}.kbq-select__content .kbq-option:before,.kbq-select__content .kbq-option:after{position:absolute;content:\"\";width:var(--kbq-size-xxs);height:calc(100% + var(--kbq-size-3xs) * 2)}.kbq-select__content .kbq-option:before{right:calc(100% + var(--kbq-size-3xs))}.kbq-select__content .kbq-option:after{left:calc(100% + var(--kbq-size-3xs))}.kbq-select__content:not(:has(>.kbq-select__no-options-message)) .cdk-virtual-scroll-viewport{min-height:var(--kbq-select-panel-size-max-height, 256px);max-height:var(--kbq-select-panel-size-max-height, 256px)}.kbq-select__content:not(:has(>.kbq-select__no-options-message)) .cdk-virtual-scroll-viewport.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper{max-width:100%}.kbq-select{color:var(--kbq-foreground-contrast)}.kbq-select.kbq-invalid{color:var(--kbq-foreground-error)}.kbq-select.kbq-invalid .kbq-select__placeholder{color:var(--kbq-form-field-states-error-placeholder)}.kbq-select.kbq-disabled{color:var(--kbq-states-foreground-disabled)}.kbq-select.kbq-disabled .kbq-select__placeholder{color:var(--kbq-form-field-states-disabled-placeholder)}.kbq-select__placeholder{text-overflow:ellipsis;color:var(--kbq-form-field-default-placeholder)}.kbq-select__search-container{border-bottom-color:var(--kbq-divider-color, var(--kbq-line-contrast-less))}.kbq-select__no-options-message{color:var(--kbq-foreground-contrast-secondary)}.kbq-select__panel{box-shadow:var(--kbq-select-panel-dropdown-shadow);background:var(--kbq-select-panel-dropdown-background)}.kbq-select__panel .kbq-select__footer{border-color:var(--kbq-divider-color, var(--kbq-line-contrast-less))}.kbq-select__panel .kbq-select__footer-item{color:var(--kbq-foreground-contrast)}.kbq-select__panel .kbq-select__footer-item:focus-visible{border-color:var(--kbq-states-line-focus-theme)}.kbq-select__panel .kbq-select__footer-item:hover:not(:disabled,.kbq-disabled){background:var(--kbq-states-background-transparent-hover)}.kbq-select__panel .kbq-select__footer-item:active:not(:disabled,.kbq-disabled){background:var(--kbq-states-background-transparent-active)}.kbq-select__panel .kbq-select__footer-item:disabled,.kbq-select__panel .kbq-select__footer-item.kbq-disabled{color:var(--kbq-states-foreground-disabled);cursor:default;pointer-events:none}.kbq-select__panel .kbq-select__footer-item:disabled .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item),.kbq-select__panel .kbq-select__footer-item.kbq-disabled .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item){color:var(--kbq-states-foreground-disabled)}.kbq-select,.kbq-select__panel,.kbq-select__footer-item{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}\n", ".kbq-select,.kbq-tree-select,.kbq-select__panel{--kbq-select-size-single-padding-left: 0;--kbq-select-size-single-padding-right: 0;--kbq-select-size-single-padding-vertical: var(--kbq-size-xs);--kbq-select-size-single-content-gap: var(--kbq-size-xxs);--kbq-select-size-multiple-padding-left: 0;--kbq-select-size-multiple-padding-right: 0;--kbq-select-size-multiple-padding-vertical: var(--kbq-size-xxs);--kbq-select-size-multiple-content-gap: var(--kbq-size-xxs);--kbq-select-panel-size-border-radius: var(--kbq-size-border-radius);--kbq-select-panel-dropdown-background: var(--kbq-background-card);--kbq-select-panel-dropdown-shadow: var(--kbq-shadow-popup)}\n"], dependencies: [{ kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: KbqTag, selector: "kbq-tag, [kbq-tag], kbq-basic-tag, [kbq-basic-tag]", inputs: ["editable", "preventEditSubmit", "selected", "selectable", "removable", "value", "tabindex", "disabled"], outputs: ["editChange", "selectionChange", "destroyed", "removed"], exportAs: ["kbqTag"] }, { kind: "directive", type: KbqTagRemove, selector: "[kbqTagRemove]", inputs: ["aria-label", "tabIndex"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdkMonitorFocus, selector: "[cdkMonitorElementFocus], [cdkMonitorSubtreeFocus]", outputs: ["cdkFocusChange"], exportAs: ["cdkMonitorFocus"] }, { kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "ngmodule", type: KbqIconModule }, { kind: "component", type: i2.KbqIcon, selector: "[kbq-icon]", inputs: ["aria-hidden", "iconSize", "autoColor", "kbq-icon"] }, { kind: "component", type: KbqOption, selector: "kbq-option", inputs: ["value", "selectable", "userSelect", "showCheckbox", "viewValue", "disabled"], outputs: ["onSelectionChange"], exportAs: ["kbqOption"] }, { kind: "component", type: KbqPseudoCheckbox, selector: "kbq-pseudo-checkbox", inputs: ["big", "state", "disabled"] }, { kind: "directive", type: KbqScrollbarViewport, selector: "[kbqScrollbarViewport]", inputs: ["kbqScrollbarMode", "kbqScrollbarHideDelay"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1980
2207
  }
1981
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelect, decorators: [{
2208
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqSelect, decorators: [{
1982
2209
  type: Component,
1983
2210
  args: [{ selector: 'kbq-select', imports: [
1984
2211
  CdkOverlayOrigin,
1985
2212
  KbqTag,
2213
+ KbqTagRemove,
1986
2214
  NgTemplateOutlet,
1987
2215
  CdkMonitorFocus,
1988
2216
  CdkConnectedOverlay,
1989
2217
  KbqIconModule,
1990
2218
  KbqOption,
1991
- KbqPseudoCheckbox
2219
+ KbqPseudoCheckbox,
2220
+ KbqScrollbarViewport
1992
2221
  ], providers: [
1993
2222
  { provide: KbqFormFieldControl, useExisting: KbqSelect },
1994
2223
  kbqCleanerFactoryProvider((() => {
@@ -1997,85 +2226,46 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
1997
2226
  get control() {
1998
2227
  return select;
1999
2228
  },
2000
- get keydownTarget() {
2001
- return select.elementRef.nativeElement;
2002
- },
2003
2229
  clearByEscape: false,
2004
- clear: (() => select.clear())
2230
+ clear: (() => select.clear()),
2231
+ canClear: (() => select.canClear)
2005
2232
  };
2006
2233
  })),
2007
2234
  { provide: KBQ_OPTION_PARENT_COMPONENT, useExisting: KbqSelect },
2008
2235
  { provide: KBQ_PARENT_POPUP, useExisting: KbqSelect },
2009
- kbqSiblingPopupProvider(KbqSelect)
2236
+ kbqSiblingPopupProvider(KbqSelect),
2237
+ KbqSelectHiddenItemsMeasurer
2010
2238
  ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
2011
2239
  '[attr.tabindex]': 'tabIndex',
2012
- '[attr.disabled]': 'disabled || null',
2240
+ '[attr.disabled]': 'disabledAttribute()',
2241
+ // The select is not a native control, so its role, states and the relationship with the panel it
2242
+ // owns have to be exposed explicitly.
2243
+ role: 'combobox',
2244
+ 'aria-haspopup': 'listbox',
2245
+ '[attr.aria-expanded]': 'panelOpen',
2246
+ '[attr.aria-controls]': 'panelOpen ? panelId : null',
2247
+ '[attr.aria-labelledby]': 'ariaLabelledby',
2248
+ '[attr.aria-label]': 'resolvedAriaLabel',
2249
+ '[attr.aria-invalid]': 'errorState()',
2250
+ '[attr.aria-required]': 'required()',
2251
+ '[attr.aria-disabled]': 'disabled()',
2013
2252
  class: 'kbq-select',
2014
2253
  '[class.kbq-select_multiple]': 'multiple',
2015
2254
  '[class.kbq-select_multiline]': 'multiline()',
2016
- '[class.kbq-disabled]': 'disabled',
2017
- '[class.kbq-invalid]': 'errorState',
2255
+ '[class.kbq-disabled]': 'disabledClass()',
2256
+ '[class.kbq-invalid]': 'invalidClass()',
2018
2257
  '(click)': 'toggle()',
2019
2258
  '(keydown)': 'handleKeydown($event)',
2020
2259
  '(focus)': 'onFocus()',
2021
2260
  '(blur)': 'onBlur()'
2022
- }, animations: [
2023
- kbqSelectAnimations.transformPanel,
2024
- kbqSelectAnimations.fadeInContent
2025
- ], exportAs: 'kbqSelect', template: "<div\n #fallbackOverlayOrigin=\"cdkOverlayOrigin\"\n #trigger\n cdkOverlayOrigin\n class=\"kbq-select__trigger\"\n [class.kbq-select__trigger_empty]=\"empty\"\n [class.kbq-select__trigger_multiline]=\"multiline()\"\n [class.kbq-select__trigger_multiple]=\"multiple\"\n [class.kbq-select__trigger_single]=\"!multiple\"\n>\n @if (!!customMatcher()) {\n <ng-content select=\"kbq-select-matcher, [kbq-select-matcher]\" />\n } @else {\n <div class=\"kbq-select__matcher\">\n @if (empty) {\n <span class=\"kbq-select__placeholder\">\n {{ placeholder || '\\u00A0' }}\n </span>\n } @else {\n @if (!!customTrigger()) {\n <ng-content select=\"kbq-select-trigger, [kbq-select-trigger]\" />\n } @else {\n <div class=\"kbq-select__match-container\">\n @if (multiSelection) {\n <div\n #multilineMatchList\n [class.kbq-select__match-list]=\"!multiline()\"\n [class.kbq-select__multiline-match-list]=\"multiline()\"\n >\n @if (!customTagTemplateRef()) {\n @for (option of triggerValues; track option) {\n <kbq-tag\n [color]=\"colorForState\"\n [disabled]=\"option.disabled || disabled\"\n [selectable]=\"false\"\n >\n {{ option.viewValue }}\n @if (!option.disabled && !disabled) {\n <i\n kbq-icon=\"kbq-xmark-s_16\"\n kbqTagRemove\n (click)=\"onRemoveMatcherItem(option, $event)\"\n ></i>\n }\n </kbq-tag>\n }\n } @else {\n @for (option of triggerValues; track option) {\n <ng-container\n [ngTemplateOutlet]=\"$any(customTagTemplateRef())\"\n [ngTemplateOutletContext]=\"{ $implicit: option, select: this }\"\n />\n }\n }\n </div>\n\n @if (!multiline()) {\n <div\n class=\"kbq-select__match-hidden-text\"\n [style.display]=\"hiddenItems > 0 ? 'block' : 'none'\"\n >\n {{ hiddenItemsTextFormatter(hiddenItemsText, hiddenItems) }}\n </div>\n }\n } @else {\n <span class=\"kbq-select__matcher-text\">\n {{ triggerValue }}\n </span>\n }\n </div>\n }\n }\n\n @if (canShowCleaner) {\n <div class=\"kbq-select__cleaner\">\n <ng-content select=\"kbq-cleaner\" />\n </div>\n }\n\n <div class=\"kbq-select__arrow-wrapper\">\n <i kbq-icon=\"kbq-chevron-down-s_16\" class=\"kbq-select__arrow\" [color]=\"colorForState\"></i>\n </div>\n </div>\n }\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayLockPosition\n [cdkConnectedOverlayBackdropClass]=\"backdropClass()\"\n [cdkConnectedOverlayHasBackdrop]=\"hasBackdrop\"\n [cdkConnectedOverlayMinWidth]=\"overlayMinWidth\"\n [cdkConnectedOverlayOpen]=\"panelOpen\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin || fallbackOverlayOrigin\"\n [cdkConnectedOverlayPanelClass]=\"overlayPanelClass\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n [cdkConnectedOverlayViewportMargin]=\"viewportMargin\"\n [cdkConnectedOverlayWidth]=\"overlayWidth\"\n (attach)=\"onAttached()\"\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n>\n <div\n #panel\n cdkMonitorSubtreeFocus\n [class]=\"getPanelClasses()\"\n [style.--kbq-select-panel-size-max-height]=\"panelMaxHeightToken()\"\n [style.font-size.px]=\"triggerFontSize\"\n [style.max-width.px]=\"panelMaxWidth()\"\n [style.transformOrigin]=\"transformOrigin\"\n (click)=\"handleClick($event)\"\n (keydown)=\"handleKeydown($event)\"\n >\n @if (search() && shouldShowSearch()) {\n <div class=\"kbq-select__search-container\">\n <ng-content select=\"[kbqSelectSearch]\" />\n </div>\n }\n\n <div\n #optionsContainer\n class=\"kbq-select__content\"\n [class.kbq-scrollbar]=\"!withVirtualScroll\"\n [@fadeInContent]=\"'showing'\"\n (@fadeInContent.done)=\"panelDoneAnimatingStream.next($event.toState)\"\n >\n @if (isEmptySearchResult) {\n <ng-content select=\"[kbq-select-search-empty-result]\" />\n }\n @if (showSelectAll) {\n <!-- Every read of selectAllState re-filters the whole option list, and allOptionsSelected\n is that same walk asking whether the state is \"checked\" \u2014 one read covers all four. -->\n @let selectAllCheckboxState = selectAllState;\n\n <kbq-option\n class=\"kbq-select__select-all\"\n [selectable]=\"false\"\n [class.kbq-selected]=\"selectAllCheckboxState === 'checked'\"\n [attr.role]=\"'checkbox'\"\n [attr.aria-checked]=\"\n selectAllCheckboxState === 'indeterminate' ? 'mixed' : selectAllCheckboxState === 'checked'\n \"\n (click)=\"toggleSelectAll()\"\n >\n <kbq-pseudo-checkbox [state]=\"selectAllCheckboxState\" />\n {{ selectAllText }}\n </kbq-option>\n }\n <ng-content />\n </div>\n\n <ng-content select=\"kbq-select-footer,[kbq-select-footer]\" />\n </div>\n</ng-template>\n", styles: [".kbq-select{box-sizing:border-box;display:inline-block;width:100%;outline:none}.kbq-select .kbq-select__trigger{display:flex;box-sizing:border-box;position:relative;cursor:pointer;min-height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-border-width) * 2)}.kbq-select .kbq-select__trigger:not(.kbq-select__trigger_multiline),.kbq-select .kbq-select__trigger.kbq-select__trigger_empty{height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-border-width) * 2)}.kbq-select .kbq-select__trigger:not(.kbq-select__trigger_multiline) .kbq-select__matcher,.kbq-select .kbq-select__trigger.kbq-select__trigger_empty .kbq-select__matcher{overflow:hidden;white-space:nowrap}.kbq-select .kbq-select__matcher{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-grow:1;align-items:center}.kbq-select .kbq-select__matcher>span{flex:1;overflow:hidden}.kbq-select .kbq-select__trigger.kbq-select__trigger_single .kbq-select__matcher,.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple.kbq-select__trigger_empty .kbq-select__matcher{padding:var(--kbq-select-size-single-padding-vertical) var(--kbq-select-size-single-padding-right) var(--kbq-select-size-single-padding-vertical) var(--kbq-select-size-single-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher{padding:var(--kbq-select-size-multiple-padding-vertical) var(--kbq-select-size-multiple-padding-right) var(--kbq-select-size-multiple-padding-vertical) var(--kbq-select-size-multiple-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher .kbq-select__match-container{display:flex}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher .kbq-select__match-list{display:flex;flex-wrap:wrap;overflow:hidden;height:calc(var(--kbq-form-field-size-height) - var(--kbq-select-size-multiple-padding-vertical) * 2);max-height:calc(var(--kbq-form-field-size-height) - var(--kbq-select-size-multiple-padding-vertical) * 2);gap:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));margin-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs))}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__match-container{flex-direction:column}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__matcher{max-width:100%;padding:calc(var(--kbq-select-size-multiple-padding-vertical) - var(--kbq-size-border-width)) var(--kbq-select-size-multiple-padding-right) calc(var(--kbq-select-size-multiple-padding-vertical) - var(--kbq-size-border-width)) var(--kbq-select-size-multiple-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__cleaner,.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__arrow-wrapper{align-self:flex-start;align-items:center;height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-s));min-width:var(--kbq-form-field-size-addon-width)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__multiline-match-list{display:flex;flex-direction:row;flex-wrap:wrap;margin-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));gap:var(--kbq-size-xxs)}.kbq-select .kbq-select__match-container{width:100%;text-overflow:ellipsis;overflow:hidden}.kbq-select .kbq-select__match-container .kbq-select__match-hidden-text{box-sizing:content-box;flex:0 0 var(--kbq-form-field-size-addon-width);align-self:center;padding-left:var(--kbq-size-xxs);padding-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));text-align:right}.kbq-select kbq-select-trigger,.kbq-select [kbq-select-trigger]{width:100%}.kbq-select .kbq-select__arrow-wrapper{display:flex;align-self:center;justify-content:center;min-width:var(--kbq-form-field-size-addon-width)}.kbq-form-field-appearance-fill .kbq-select .kbq-select__arrow-wrapper,.kbq-form-field-appearance-standard .kbq-select .kbq-select__arrow-wrapper{transform:translateY(-50%)}.kbq-form-field-appearance-outline .kbq-select .kbq-select__arrow-wrapper{transform:translateY(-25%)}.kbq-disabled.kbq-select .kbq-select__trigger{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.kbq-select__panel{min-width:100%;max-width:var(--kbq-panel-size-width-max, 640px);overflow:hidden;border-radius:var(--kbq-select-panel-size-border-radius, var(--kbq-size-border-radius))}.kbq-select__panel .kbq-option{font-size:inherit}.kbq-select__panel .kbq-select__no-options-message{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-direction:row;align-items:center;justify-content:center;box-sizing:border-box;position:relative;margin-bottom:var(--kbq-size-3xl);margin-top:var(--kbq-size-3xl);max-width:100%;height:var(--kbq-option-size-height, var(--kbq-size-3xl));cursor:default;outline:none;padding-left:var(--kbq-option-size-horizontal-padding, var(--kbq-size-m));padding-right:var(--kbq-option-size-horizontal-padding, var(--kbq-size-m));border:var(--kbq-option-size-border-width, var(--kbq-size-3xs)) solid transparent}.kbq-select__panel .kbq-select__search-container{padding:var(--kbq-size-xxs);border-bottom-width:1px;border-bottom-style:solid}.kbq-select__content{box-sizing:initial;max-height:var(--kbq-select-panel-size-max-height, 256px);padding:var(--kbq-size-xxs);overflow:hidden auto}.kbq-select__panel .kbq-select__footer{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;align-items:center;box-sizing:border-box;min-height:var(--kbq-select-footer-size-min-height, var(--kbq-size-4xl));border-top-width:var(--kbq-select-footer-size-border-width, var(--kbq-size-border-width));border-top-style:solid;padding:var(--kbq-select-footer-size-padding-vertical, var(--kbq-size-xxs)) var(--kbq-select-footer-size-padding-horizontal, var(--kbq-size-l))}.kbq-select__panel .kbq-select__footer-item{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;display:flex;flex-direction:row;align-items:center;box-sizing:border-box;outline:none;flex:1 1 auto;min-height:var(--kbq-select-footer-item-size-height, var(--kbq-size-3xl));gap:var(--kbq-size-s);border:var(--kbq-size-3xs) solid transparent;border-radius:var(--kbq-select-footer-item-size-border-radius, var(--kbq-size-xxs));padding:0 calc(var(--kbq-size-m) - var(--kbq-size-3xs));background:transparent;cursor:pointer;text-align:left;text-decoration:none}.kbq-select__panel .kbq-select__footer:has(.kbq-select__footer-item){--kbq-select-footer-size-padding-horizontal: var(--kbq-size-xxs)}.kbq-select__content .kbq-option{position:relative}.kbq-select__content .kbq-option:before,.kbq-select__content .kbq-option:after{position:absolute;content:\"\";width:var(--kbq-size-xxs);height:calc(100% + var(--kbq-size-3xs) * 2)}.kbq-select__content .kbq-option:before{right:calc(100% + var(--kbq-size-3xs))}.kbq-select__content .kbq-option:after{left:calc(100% + var(--kbq-size-3xs))}.kbq-select__content:not(:has(>.kbq-select__no-options-message)) .cdk-virtual-scroll-viewport{min-height:var(--kbq-select-panel-size-max-height, 256px);max-height:var(--kbq-select-panel-size-max-height, 256px)}.kbq-select__content:not(:has(>.kbq-select__no-options-message)) .cdk-virtual-scroll-viewport.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper{max-width:100%}.kbq-form-field-type-select:not(.kbq-disabled) .kbq-form-field-flex{cursor:pointer}.kbq-select{color:var(--kbq-foreground-contrast)}.kbq-select.kbq-control_has-validate-directive.ng-invalid,.kbq-select.kbq-invalid{color:var(--kbq-foreground-error)}.kbq-select.kbq-control_has-validate-directive.ng-invalid .kbq-select__placeholder,.kbq-select.kbq-invalid .kbq-select__placeholder{color:var(--kbq-form-field-states-error-placeholder)}.kbq-select.kbq-disabled{color:var(--kbq-states-foreground-disabled)}.kbq-select.kbq-disabled .kbq-select__placeholder{color:var(--kbq-form-field-states-disabled-placeholder)}.kbq-select__placeholder{text-overflow:ellipsis;color:var(--kbq-form-field-default-placeholder)}.kbq-select__panel{box-shadow:var(--kbq-select-panel-dropdown-shadow);background:var(--kbq-select-panel-dropdown-background)}.kbq-select__panel .kbq-select__footer{border-color:var(--kbq-divider-color, var(--kbq-line-contrast-less))}.kbq-select__panel .kbq-select__footer-item{color:var(--kbq-foreground-contrast)}.kbq-select__panel .kbq-select__footer-item:focus-visible{border-color:var(--kbq-states-line-focus-theme)}.kbq-select__panel .kbq-select__footer-item:hover:not(:disabled,.kbq-disabled){background:var(--kbq-states-background-transparent-hover)}.kbq-select__panel .kbq-select__footer-item:active:not(:disabled,.kbq-disabled){background:var(--kbq-states-background-transparent-active)}.kbq-select__panel .kbq-select__footer-item:disabled,.kbq-select__panel .kbq-select__footer-item.kbq-disabled{color:var(--kbq-states-foreground-disabled);cursor:default;pointer-events:none}.kbq-select__panel .kbq-select__footer-item:disabled .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item),.kbq-select__panel .kbq-select__footer-item.kbq-disabled .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item){color:var(--kbq-states-foreground-disabled)}.kbq-select__search-container{border-bottom-color:var(--kbq-divider-color, var(--kbq-line-contrast-less))}.kbq-select__no-options-message{color:var(--kbq-foreground-contrast-secondary)}.kbq-select,.kbq-select__panel,.kbq-select__footer-item{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}\n", ".kbq-select,.kbq-tree-select,.kbq-select__panel{--kbq-select-size-single-padding-left: 0;--kbq-select-size-single-padding-right: 0;--kbq-select-size-single-padding-vertical: var(--kbq-size-xs);--kbq-select-size-single-content-gap: var(--kbq-size-xxs);--kbq-select-size-multiple-padding-left: 0;--kbq-select-size-multiple-padding-right: 0;--kbq-select-size-multiple-padding-vertical: var(--kbq-size-xxs);--kbq-select-size-multiple-content-gap: var(--kbq-size-xxs);--kbq-select-panel-size-border-radius: var(--kbq-size-border-radius);--kbq-select-panel-dropdown-background: var(--kbq-background-card);--kbq-select-panel-dropdown-shadow: var(--kbq-shadow-popup)}\n"] }]
2026
- }], ctorParameters: () => [], propDecorators: { trigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], panel: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }], optionsContainer: [{ type: i0.ViewChild, args: ['optionsContainer', { isSignal: true }] }], selectAllOption: [{ type: i0.ViewChild, args: [i0.forwardRef(() => KbqOption), { isSignal: true }] }], overlayDir: [{
2027
- type: ViewChild,
2028
- args: [CdkConnectedOverlay, { static: false }]
2029
- }], footer: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqSelectFooter), { ...{ read: ElementRef }, isSignal: true }] }], cdkVirtualForOf: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CdkVirtualForOf), { isSignal: true }] }], virtualScrollViewport: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CdkVirtualScrollViewport), { isSignal: true }] }], tags: [{
2030
- type: ViewChildren,
2031
- args: [KbqTag]
2032
- }], customTrigger: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqSelectTrigger), { isSignal: true }] }], customMatcher: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqSelectMatcher), { isSignal: true }] }], customTagTemplateRef: [{ type: i0.ContentChild, args: ['kbqSelectTagContent', { ...{ read: TemplateRef }, isSignal: true }] }], cleaner: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqCleaner), { ...{ descendants: false }, isSignal: true }] }], options: [{
2033
- type: ContentChildren,
2034
- args: [KbqOption, { descendants: true }]
2035
- }], optionGroups: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => KbqOptgroup), { isSignal: true }] }], search: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqSelectSearch), { isSignal: true }] }], searchEmpty: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqSelectSearchEmptyResult), { isSignal: true }] }], hiddenItemsText: [{
2036
- type: Input
2037
- }], showPreselectedValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPreselectedValues", required: false }] }], triggerValuesLimit: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerValuesLimit", required: false }] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], backdropClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "backdropClass", required: false }] }], errorStateMatcher: [{
2038
- type: Input
2039
- }], sortComparator: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortComparator", required: false }] }], multiline: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiline", required: false }] }], searchMinOptionsThreshold: [{
2040
- type: Input
2041
- }], openedChange: [{
2042
- type: Output
2043
- }], beforeOpened: [{ type: i0.Output, args: ["beforeOpened"] }], openedStream: [{
2044
- type: Output,
2045
- args: ['opened']
2046
- }], closedStream: [{
2047
- type: Output,
2048
- args: ['closed']
2049
- }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], onSelectAll: [{ type: i0.Output, args: ["onSelectAll"] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], scrolledToBottomOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrolledToBottomOffset", required: false }] }], scrolledToBottom: [{ type: i0.Output, args: ["scrolledToBottom"] }], hasBackdrop: [{
2050
- type: Input
2051
- }], placeholder: [{
2052
- type: Input
2053
- }], required: [{
2054
- type: Input
2055
- }], multiple: [{
2056
- type: Input,
2057
- args: [{ transform: booleanAttribute }]
2058
- }], compareWith: [{
2059
- type: Input
2060
- }], virtualOptionFactory: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualOptionFactory", required: false }] }], selectAllToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAllToggle", required: false }] }], selectAll: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAll", required: false }] }], selectAllHandler: [{
2061
- type: Input
2062
- }], panelWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelWidth", required: false }] }], panelMinWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelMinWidth", required: false }] }], panelMaxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelMaxWidth", required: false }] }], panelMaxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelMaxHeight", required: false }] }], value: [{
2063
- type: Input
2064
- }], id: [{
2065
- type: Input
2066
- }], tabIndex: [{
2067
- type: Input,
2068
- args: [{ transform: numberAttribute }]
2069
- }], disabled: [{
2070
- type: Input,
2071
- args: [{ transform: booleanAttribute }]
2072
- }], hiddenItemsTextFormatter: [{
2073
- type: Input
2074
- }] } });
2261
+ }, hostDirectives: [
2262
+ { directive: KbqLocaleOverridesDirective, inputs: ['kbqLocaleOverrides: localeOverrides'] }
2263
+ ], exportAs: 'kbqSelect', template: "<div\n #fallbackOverlayOrigin=\"cdkOverlayOrigin\"\n #trigger\n cdkOverlayOrigin\n class=\"kbq-select__trigger\"\n [class.kbq-select__trigger_empty]=\"empty()\"\n [class.kbq-select__trigger_multiline]=\"multiline()\"\n [class.kbq-select__trigger_multiple]=\"multiple\"\n [class.kbq-select__trigger_single]=\"!multiple\"\n>\n @if (!!customMatcher()) {\n <ng-content select=\"kbq-select-matcher, [kbq-select-matcher]\" />\n } @else {\n <div class=\"kbq-select__matcher\">\n @if (empty()) {\n <span class=\"kbq-select__placeholder\">\n {{ placeholder() || '\\u00A0' }}\n </span>\n } @else {\n @if (!!customTrigger()) {\n <ng-content select=\"kbq-select-trigger, [kbq-select-trigger]\" />\n } @else {\n <div class=\"kbq-select__match-container\">\n @if (multiSelection) {\n <div\n #multilineMatchList\n [class.kbq-select__match-list]=\"!multiline()\"\n [class.kbq-select__multiline-match-list]=\"multiline()\"\n >\n @if (customTagTemplateRef(); as tagTemplate) {\n @for (option of triggerValues; track option) {\n <ng-container\n [ngTemplateOutlet]=\"tagTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: option, select: this }\"\n />\n }\n } @else {\n @for (option of triggerValues; track option) {\n <kbq-tag\n [color]=\"colorForState\"\n [disabled]=\"option.disabled || disabled()\"\n [selectable]=\"false\"\n >\n {{ option.viewValue }}\n @if (!option.disabled && !disabled()) {\n <!--\n `kbqTagRemove` now carries the role, the accessible\n name and keyboard activation itself, so this binds\n only what is select-specific. The name goes through\n the `aria-label` input rather than `[attr.aria-label]`\n \u2014 the directive renders the attribute, so writing it\n here would be overwritten by its default.\n -->\n <i\n kbq-icon=\"kbq-xmark-s_16\"\n kbqTagRemove\n [aria-label]=\"removeItemAriaLabel(option)\"\n [tabIndex]=\"isTriggerValueVisible($index) ? 0 : -1\"\n (click)=\"onRemoveMatcherItem(option, $event)\"\n ></i>\n }\n </kbq-tag>\n }\n }\n </div>\n\n @if (!multiline()) {\n <div\n class=\"kbq-select__match-hidden-text\"\n [class.kbq-select__match-hidden-text_visible]=\"hiddenItems() > 0\"\n >\n {{ hiddenItemsLabel }}\n </div>\n }\n } @else {\n <span class=\"kbq-select__matcher-text\">\n {{ triggerValue }}\n </span>\n }\n </div>\n }\n }\n\n @if (canShowCleaner) {\n <div class=\"kbq-select__cleaner\">\n <ng-content select=\"kbq-cleaner\" />\n </div>\n }\n\n <div class=\"kbq-select__arrow-wrapper\">\n <i kbq-icon=\"kbq-chevron-down-s_16\" class=\"kbq-select__arrow\" [color]=\"colorForState\"></i>\n </div>\n </div>\n }\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayLockPosition\n [cdkConnectedOverlayBackdropClass]=\"backdropClass()\"\n [cdkConnectedOverlayHasBackdrop]=\"hasBackdrop()\"\n [cdkConnectedOverlayMinWidth]=\"overlayMinWidth\"\n [cdkConnectedOverlayOpen]=\"panelOpen\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin || fallbackOverlayOrigin\"\n [cdkConnectedOverlayPanelClass]=\"overlayPanelClass\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n [cdkConnectedOverlayViewportMargin]=\"viewportMargin\"\n [cdkConnectedOverlayWidth]=\"overlayWidth\"\n (attach)=\"onAttached()\"\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n>\n <div\n #panel\n cdkMonitorSubtreeFocus\n [class]=\"getPanelClasses()\"\n [style.--kbq-select-panel-size-max-height]=\"panelMaxHeightToken()\"\n [style.font-size.px]=\"triggerFontSize\"\n [style.max-width.px]=\"panelMaxWidth()\"\n [style.transformOrigin]=\"transformOrigin\"\n (click)=\"handleClick($event)\"\n (keydown)=\"handleKeydown($event)\"\n >\n @if (search() && shouldShowSearch()) {\n <div class=\"kbq-select__search-container\">\n <ng-content select=\"[kbqSelectSearch]\" />\n </div>\n }\n\n <div\n #optionsContainer\n kbqScrollbarViewport\n role=\"listbox\"\n class=\"kbq-select__content\"\n [kbqScrollbarMode]=\"scrollbarMode\"\n [id]=\"panelId\"\n [attr.aria-multiselectable]=\"multiSelection\"\n [attr.aria-labelledby]=\"ariaLabelledby\"\n [attr.aria-label]=\"resolvedAriaLabel\"\n [attr.aria-busy]=\"isOptionsListBusy || null\"\n >\n @if (isEmptySearchResult) {\n <ng-content select=\"[kbq-select-search-empty-result]\" />\n }\n @if (showSelectAll) {\n <!-- Every read of selectAllState re-filters the whole option list, and allOptionsSelected\n is that same walk asking whether the state is \"checked\" \u2014 one read covers all four. -->\n @let selectAllCheckboxState = selectAllState;\n\n <!--\n The row stays an `option`: a `checkbox` is not a valid child of the listbox it lives in,\n and `option` carries the tri-state on `aria-checked` just as well.\n -->\n <kbq-option\n class=\"kbq-select__select-all\"\n [selectable]=\"false\"\n [class.kbq-selected]=\"selectAllCheckboxState === 'checked'\"\n [attr.aria-checked]=\"\n selectAllCheckboxState === 'indeterminate' ? 'mixed' : selectAllCheckboxState === 'checked'\n \"\n (click)=\"toggleSelectAll()\"\n >\n <kbq-pseudo-checkbox aria-hidden=\"true\" [state]=\"selectAllCheckboxState\" />\n {{ selectAllText }}\n </kbq-option>\n }\n <ng-content />\n </div>\n\n <ng-content select=\"kbq-select-footer,[kbq-select-footer]\" />\n </div>\n</ng-template>\n", styles: [".kbq-select{box-sizing:border-box;display:inline-block;width:100%;outline:none}.kbq-select .kbq-select__trigger{display:flex;box-sizing:border-box;position:relative;cursor:pointer;min-height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-border-width) * 2)}.kbq-select .kbq-select__trigger:not(.kbq-select__trigger_multiline),.kbq-select .kbq-select__trigger.kbq-select__trigger_empty{height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-border-width) * 2)}.kbq-select .kbq-select__trigger:not(.kbq-select__trigger_multiline) .kbq-select__matcher,.kbq-select .kbq-select__trigger.kbq-select__trigger_empty .kbq-select__matcher{overflow:hidden;white-space:nowrap}.kbq-select .kbq-select__matcher{-webkit-user-select:none;user-select:none;display:flex;flex-grow:1;align-items:center}.kbq-select .kbq-select__matcher>span{flex:1;overflow:hidden}.kbq-select .kbq-select__trigger.kbq-select__trigger_single .kbq-select__matcher,.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple.kbq-select__trigger_empty .kbq-select__matcher{padding:var(--kbq-select-size-single-padding-vertical) var(--kbq-select-size-single-padding-right) var(--kbq-select-size-single-padding-vertical) var(--kbq-select-size-single-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher{padding:var(--kbq-select-size-multiple-padding-vertical) var(--kbq-select-size-multiple-padding-right) var(--kbq-select-size-multiple-padding-vertical) var(--kbq-select-size-multiple-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher .kbq-select__match-container{display:flex}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher .kbq-select__match-list{display:flex;flex-wrap:wrap;overflow:hidden;height:calc(var(--kbq-form-field-size-height) - var(--kbq-select-size-multiple-padding-vertical) * 2);max-height:calc(var(--kbq-form-field-size-height) - var(--kbq-select-size-multiple-padding-vertical) * 2);gap:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));margin-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs))}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__match-container{flex-direction:column}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__matcher{max-width:100%;padding:calc(var(--kbq-select-size-multiple-padding-vertical) - var(--kbq-size-border-width)) var(--kbq-select-size-multiple-padding-right) calc(var(--kbq-select-size-multiple-padding-vertical) - var(--kbq-size-border-width)) var(--kbq-select-size-multiple-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__cleaner,.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__arrow-wrapper{align-self:flex-start;align-items:center;height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-s));min-width:var(--kbq-form-field-size-addon-width)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__multiline-match-list{display:flex;flex-direction:row;flex-wrap:wrap;margin-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));gap:var(--kbq-size-xxs)}.kbq-select .kbq-select__match-container{width:100%;text-overflow:ellipsis;overflow:hidden}.kbq-select .kbq-select__match-container .kbq-select__match-hidden-text{box-sizing:content-box;display:none;flex:0 0 var(--kbq-form-field-size-addon-width);align-self:center;padding-left:var(--kbq-size-xxs);padding-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));text-align:right}.kbq-select .kbq-select__match-container .kbq-select__match-hidden-text.kbq-select__match-hidden-text_visible{display:block}.kbq-select kbq-select-trigger,.kbq-select [kbq-select-trigger]{width:100%}.kbq-select .kbq-select__arrow-wrapper{display:flex;align-self:center;justify-content:center;min-width:var(--kbq-form-field-size-addon-width)}.kbq-disabled.kbq-select .kbq-select__trigger{-webkit-user-select:none;user-select:none;cursor:default}.kbq-select__panel{min-width:100%;max-width:var(--kbq-panel-size-width-max, 640px);overflow:hidden;border-radius:var(--kbq-select-panel-size-border-radius, var(--kbq-size-border-radius))}@supports (corner-shape: squircle){.kbq-select__panel{corner-shape:squircle;border-radius:clamp(var(--kbq-select-panel-size-border-radius, var(--kbq-size-border-radius)) * 1.85,var(--kbq-select-panel-size-border-radius, var(--kbq-size-border-radius)) * 2.3 - 3.6px,var(--kbq-select-panel-size-border-radius, var(--kbq-size-border-radius)) * 2)}}.kbq-select__panel .kbq-option{font-size:inherit}.kbq-select__panel .kbq-select__no-options-message{-webkit-user-select:none;user-select:none;display:flex;flex-direction:row;align-items:center;justify-content:center;box-sizing:border-box;position:relative;margin-bottom:var(--kbq-size-3xl);margin-top:var(--kbq-size-3xl);max-width:100%;height:var(--kbq-option-size-height, var(--kbq-size-3xl));cursor:default;outline:none;padding-left:var(--kbq-option-size-horizontal-padding, var(--kbq-size-m));padding-right:var(--kbq-option-size-horizontal-padding, var(--kbq-size-m));border:var(--kbq-option-size-border-width, var(--kbq-size-3xs)) solid transparent}.kbq-select__panel .kbq-select__search-container{padding:var(--kbq-size-xxs);border-bottom-width:1px;border-bottom-style:solid}.kbq-select__content{box-sizing:initial;max-height:var(--kbq-select-panel-size-max-height, 256px);padding:var(--kbq-size-xxs);overflow:hidden auto}.kbq-select__panel .kbq-select__footer{-webkit-user-select:none;user-select:none;display:flex;align-items:center;box-sizing:border-box;min-height:var(--kbq-select-footer-size-min-height, var(--kbq-size-4xl));border-top-width:var(--kbq-select-footer-size-border-width, var(--kbq-size-border-width));border-top-style:solid;padding:var(--kbq-select-footer-size-padding-vertical, var(--kbq-size-xxs)) var(--kbq-select-footer-size-padding-horizontal, var(--kbq-size-l))}.kbq-select__panel .kbq-select__footer-item{-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;display:flex;flex-direction:row;align-items:center;box-sizing:border-box;outline:none;flex:1 1 auto;min-height:var(--kbq-select-footer-item-size-height, var(--kbq-size-3xl));gap:var(--kbq-size-s);border:var(--kbq-size-3xs) solid transparent;border-radius:var(--kbq-select-footer-item-size-border-radius, var(--kbq-size-xxs))}@supports (corner-shape: squircle){.kbq-select__panel .kbq-select__footer-item{corner-shape:squircle;border-radius:clamp(var(--kbq-select-footer-item-size-border-radius, var(--kbq-size-xxs)) * 1.85,var(--kbq-select-footer-item-size-border-radius, var(--kbq-size-xxs)) * 2.3 - 3.6px,var(--kbq-select-footer-item-size-border-radius, var(--kbq-size-xxs)) * 2)}}.kbq-select__panel .kbq-select__footer-item{padding:0 calc(var(--kbq-size-m) - var(--kbq-size-3xs));background:transparent;cursor:pointer;text-align:left;text-decoration:none}.kbq-select__panel .kbq-select__footer:has(.kbq-select__footer-item){--kbq-select-footer-size-padding-horizontal: var(--kbq-size-xxs)}.kbq-select__content .kbq-option{position:relative}.kbq-select__content .kbq-option:before,.kbq-select__content .kbq-option:after{position:absolute;content:\"\";width:var(--kbq-size-xxs);height:calc(100% + var(--kbq-size-3xs) * 2)}.kbq-select__content .kbq-option:before{right:calc(100% + var(--kbq-size-3xs))}.kbq-select__content .kbq-option:after{left:calc(100% + var(--kbq-size-3xs))}.kbq-select__content:not(:has(>.kbq-select__no-options-message)) .cdk-virtual-scroll-viewport{min-height:var(--kbq-select-panel-size-max-height, 256px);max-height:var(--kbq-select-panel-size-max-height, 256px)}.kbq-select__content:not(:has(>.kbq-select__no-options-message)) .cdk-virtual-scroll-viewport.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper{max-width:100%}.kbq-select{color:var(--kbq-foreground-contrast)}.kbq-select.kbq-invalid{color:var(--kbq-foreground-error)}.kbq-select.kbq-invalid .kbq-select__placeholder{color:var(--kbq-form-field-states-error-placeholder)}.kbq-select.kbq-disabled{color:var(--kbq-states-foreground-disabled)}.kbq-select.kbq-disabled .kbq-select__placeholder{color:var(--kbq-form-field-states-disabled-placeholder)}.kbq-select__placeholder{text-overflow:ellipsis;color:var(--kbq-form-field-default-placeholder)}.kbq-select__search-container{border-bottom-color:var(--kbq-divider-color, var(--kbq-line-contrast-less))}.kbq-select__no-options-message{color:var(--kbq-foreground-contrast-secondary)}.kbq-select__panel{box-shadow:var(--kbq-select-panel-dropdown-shadow);background:var(--kbq-select-panel-dropdown-background)}.kbq-select__panel .kbq-select__footer{border-color:var(--kbq-divider-color, var(--kbq-line-contrast-less))}.kbq-select__panel .kbq-select__footer-item{color:var(--kbq-foreground-contrast)}.kbq-select__panel .kbq-select__footer-item:focus-visible{border-color:var(--kbq-states-line-focus-theme)}.kbq-select__panel .kbq-select__footer-item:hover:not(:disabled,.kbq-disabled){background:var(--kbq-states-background-transparent-hover)}.kbq-select__panel .kbq-select__footer-item:active:not(:disabled,.kbq-disabled){background:var(--kbq-states-background-transparent-active)}.kbq-select__panel .kbq-select__footer-item:disabled,.kbq-select__panel .kbq-select__footer-item.kbq-disabled{color:var(--kbq-states-foreground-disabled);cursor:default;pointer-events:none}.kbq-select__panel .kbq-select__footer-item:disabled .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item),.kbq-select__panel .kbq-select__footer-item.kbq-disabled .kbq-icon.kbq-empty:not(.kbq-icon-button,.kbq-icon-item){color:var(--kbq-states-foreground-disabled)}.kbq-select,.kbq-select__panel,.kbq-select__footer-item{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}\n", ".kbq-select,.kbq-tree-select,.kbq-select__panel{--kbq-select-size-single-padding-left: 0;--kbq-select-size-single-padding-right: 0;--kbq-select-size-single-padding-vertical: var(--kbq-size-xs);--kbq-select-size-single-content-gap: var(--kbq-size-xxs);--kbq-select-size-multiple-padding-left: 0;--kbq-select-size-multiple-padding-right: 0;--kbq-select-size-multiple-padding-vertical: var(--kbq-size-xxs);--kbq-select-size-multiple-content-gap: var(--kbq-size-xxs);--kbq-select-panel-size-border-radius: var(--kbq-size-border-radius);--kbq-select-panel-dropdown-background: var(--kbq-background-card);--kbq-select-panel-dropdown-shadow: var(--kbq-shadow-popup)}\n"] }]
2264
+ }], ctorParameters: () => [], propDecorators: { trigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], panel: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }], optionsContainer: [{ type: i0.ViewChild, args: ['optionsContainer', { isSignal: true }] }], scrollbarViewport: [{ type: i0.ViewChild, args: [i0.forwardRef(() => KbqScrollbarViewport), { isSignal: true }] }], projectedScrollbarViewport: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqScrollbarViewport), { ...{ descendants: true }, isSignal: true }] }], selectAllOption: [{ type: i0.ViewChild, args: [i0.forwardRef(() => KbqOption), { isSignal: true }] }], overlayDirQuery: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CdkConnectedOverlay), { isSignal: true }] }], footer: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqSelectFooter), { ...{ read: ElementRef }, isSignal: true }] }], cdkVirtualForOf: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CdkVirtualForOf), { isSignal: true }] }], virtualScrollViewport: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CdkVirtualScrollViewport), { isSignal: true }] }], tagsQuery: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => KbqTag), { isSignal: true }] }], customTrigger: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqSelectTrigger), { isSignal: true }] }], customMatcher: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqSelectMatcher), { isSignal: true }] }], customTagTemplateRef: [{ type: i0.ContentChild, args: ['kbqSelectTagContent', { ...{ read: TemplateRef }, isSignal: true }] }], cleaner: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqCleaner), { ...{ descendants: false }, isSignal: true }] }], optionsQuery: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => KbqOption), { ...{ descendants: true }, isSignal: true }] }], optionGroups: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => KbqOptgroup), { isSignal: true }] }], search: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqSelectSearch), { isSignal: true }] }], searchEmpty: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqSelectSearchEmptyResult), { isSignal: true }] }], hiddenItemsText: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenItemsText", required: false }] }], hiddenItemsTextFormatter: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenItemsTextFormatter", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], showPreselectedValues: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPreselectedValues", required: false }] }], triggerValuesLimit: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerValuesLimit", required: false }] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], backdropClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "backdropClass", required: false }] }], errorStateMatcher: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorStateMatcher", required: false }] }], sortComparator: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortComparator", required: false }] }], multiline: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiline", required: false }] }], searchMinOptionsThresholdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchMinOptionsThreshold", required: false }] }], openedChangeOutput: [{ type: i0.Output, args: ["openedChange"] }], beforeOpened: [{ type: i0.Output, args: ["beforeOpened"] }], openedOutput: [{ type: i0.Output, args: ["opened"] }], closedOutput: [{ type: i0.Output, args: ["closed"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], onSelectAll: [{ type: i0.Output, args: ["onSelectAll"] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], scrolledToBottomOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrolledToBottomOffset", required: false }] }], scrolledToBottom: [{ type: i0.Output, args: ["scrolledToBottom"] }], hasBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasBackdrop", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], multipleInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "compareWith", required: false }] }], virtualOptionFactory: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualOptionFactory", required: false }] }], clearPredicate: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearPredicate", required: false }] }], selectAllToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAllToggle", required: false }] }], selectAll: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAll", required: false }] }], selectAllHandlerInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAllHandler", required: false }] }], panelWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelWidth", required: false }] }], panelMinWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelMinWidth", required: false }] }], panelMaxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelMaxWidth", required: false }] }], panelMaxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelMaxHeight", required: false }] }], valueInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], idInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], tabIndexInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabIndex", required: false }] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
2075
2265
 
2076
2266
  class KbqSelectModule {
2077
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2078
- /** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectModule, imports: [OverlayModule,
2267
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqSelectModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2268
+ /** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.25", ngImport: i0, type: KbqSelectModule, imports: [OverlayModule,
2079
2269
  KbqOptionModule,
2080
2270
  KbqIconModule,
2081
2271
  KbqTagsModule,
@@ -2107,7 +2297,7 @@ class KbqSelectModule {
2107
2297
  KbqSelectError,
2108
2298
  KbqSelectNoOptions,
2109
2299
  KbqSelectErrorText] }); }
2110
- /** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectModule, imports: [OverlayModule,
2300
+ /** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqSelectModule, imports: [OverlayModule,
2111
2301
  KbqOptionModule,
2112
2302
  KbqIconModule,
2113
2303
  KbqTagsModule,
@@ -2117,7 +2307,7 @@ class KbqSelectModule {
2117
2307
  KbqSelectLoading, KbqOptionModule,
2118
2308
  KbqFormFieldModule] }); }
2119
2309
  }
2120
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectModule, decorators: [{
2310
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqSelectModule, decorators: [{
2121
2311
  type: NgModule,
2122
2312
  args: [{
2123
2313
  imports: [
@@ -2164,5 +2354,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
2164
2354
  * Generated bundle index. Do not edit.
2165
2355
  */
2166
2356
 
2167
- export { KBQ_SELECT_OPTIONS, KbqOptionTooltip, KbqSelect, KbqSelectChange, KbqSelectError, KbqSelectErrorText, KbqSelectLoading, KbqSelectModule, KbqSelectNoOptions, delayBeforeDisplayingResultWithoutOptions, kbqSelectOptionsProvider, minimumTimeToDisplayLoading };
2357
+ export { KBQ_SELECT_HIDDEN_TEXT_VISIBLE_CLASS, KBQ_SELECT_OPTIONS, KbqOptionTooltip, KbqSelect, KbqSelectChange, KbqSelectError, KbqSelectErrorText, KbqSelectHiddenItemsMeasurer, KbqSelectLoading, KbqSelectModule, KbqSelectNoOptions, delayBeforeDisplayingResultWithoutOptions, kbqSelectOptionsProvider, minimumTimeToDisplayLoading };
2168
2358
  //# sourceMappingURL=koobiq-components-select.mjs.map