@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,18 +1,19 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ElementRef, Directive, InjectionToken, forwardRef, ViewContainerRef, ChangeDetectorRef, NgZone, input, afterNextRender, Input, DestroyRef, viewChild, TemplateRef, contentChildren, numberAttribute, output, ContentChildren, ViewEncapsulation, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
2
+ import { inject, ElementRef, Directive, InjectionToken, forwardRef, ViewContainerRef, ChangeDetectorRef, NgZone, Injector, input, booleanAttribute, output, Renderer2, signal, afterNextRender, effect, untracked, isWritableSignal, DestroyRef, viewChild, TemplateRef, contentChildren, numberAttribute, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
3
3
  import { Directionality } from '@angular/cdk/bidi';
4
- import { coerceBooleanProperty } from '@angular/cdk/coercion';
5
- import { Overlay, OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
4
+ import { ScrollDispatcher, Overlay, OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
6
5
  import { _getFocusedElementPierceShadowDom, _getEventTarget } from '@angular/cdk/platform';
7
6
  import { TemplatePortal } from '@angular/cdk/portal';
8
7
  import { ViewportRuler } from '@angular/cdk/scrolling';
9
8
  import { DOCUMENT } from '@angular/common';
10
9
  import { toObservable, outputToObservable, takeUntilDestroyed } from '@angular/core/rxjs-interop';
11
10
  import { NG_VALUE_ACCESSOR } from '@angular/forms';
12
- import { KBQ_WINDOW, KbqOptionSelectionChange, ESCAPE, ENTER, TAB, DOWN_ARROW, UP_ARROW, defaultOffsetY, KBQ_CONNECTED_OVERLAY_BELOW_CLASS, KBQ_CONNECTED_OVERLAY_ABOVE_CLASS, kbqResolvePanelWidth, kbqGetPanelWidthOrigin, kbqSiblingPopupProvider, KbqOptgroup, KBQ_PANEL_DEFAULT_MIN_WIDTH, ActiveDescendantKeyManager, KbqOption, KBQ_OPTION_PARENT_COMPONENT, KbqOptionModule } from '@koobiq/components/core';
13
- import { KBQ_FORM_FIELD } from '@koobiq/components/form-field';
14
- import { defer, merge, Subscription, Subject, of, fromEvent } from 'rxjs';
15
- import { take, switchMap, filter, map, tap, delay } from 'rxjs/operators';
11
+ import { kbqRepositionScrollStrategyFactory, KBQ_OVERLAY_LAYERS, kbqOptionalNumberAttribute, kbqCreateCaretOrigin, KBQ_WINDOW, KbqOptionSelectionChange, ESCAPE, UP_ARROW, DOWN_ARROW, ENTER, TAB, defaultOffsetY, KBQ_CONNECTED_OVERLAY_BELOW_CLASS, KBQ_CONNECTED_OVERLAY_ABOVE_CLASS, kbqGetCaretRect, kbqResolvePanelWidth, kbqGetPanelWidthOrigin, kbqGetTextQuery, kbqListenForCaretMoves, hasModifierKey, RIGHT_ARROW, kbqCreateTextMirror, kbqIsTextLaidOutFromStart, kbqSiblingPopupProvider, kbqInjectNativeElement, KbqOption, kbqQueryListFrom, KbqOptgroup, KBQ_PANEL_DEFAULT_MIN_WIDTH, ActiveDescendantKeyManager, KBQ_OPTION_PARENT_COMPONENT, KbqOptionModule } from '@koobiq/components/core';
12
+ import { KBQ_FORM_FIELD, KbqFormFieldControl } from '@koobiq/components/form-field';
13
+ import { merge, EMPTY, Subscription, Subject, of, fromEvent, Observable } from 'rxjs';
14
+ import { filter, switchMap, map, startWith, tap, delay, take } from 'rxjs/operators';
15
+ import { _IdGenerator } from '@angular/cdk/a11y';
16
+ import { KbqScrollbarViewport } from '@koobiq/components/scrollbar';
16
17
 
17
18
  /**
18
19
  * Directive applied to an element to make it usable
@@ -22,10 +23,10 @@ class KbqAutocompleteOrigin {
22
23
  constructor() {
23
24
  this.elementRef = inject(ElementRef);
24
25
  }
25
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqAutocompleteOrigin, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
26
- /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.30", type: KbqAutocompleteOrigin, isStandalone: true, selector: "[kbqAutocompleteOrigin]", exportAs: ["kbqAutocompleteOrigin"], ngImport: i0 }); }
26
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqAutocompleteOrigin, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
27
+ /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.25", type: KbqAutocompleteOrigin, isStandalone: true, selector: "[kbqAutocompleteOrigin]", exportAs: ["kbqAutocompleteOrigin"], ngImport: i0 }); }
27
28
  }
28
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqAutocompleteOrigin, decorators: [{
29
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqAutocompleteOrigin, decorators: [{
29
30
  type: Directive,
30
31
  args: [{
31
32
  selector: '[kbqAutocompleteOrigin]',
@@ -33,14 +34,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
33
34
  }]
34
35
  }] });
35
36
 
36
- /**
37
- * The total height of the autocomplete panel.
38
- *
39
- * @deprecated Unused — the panel is capped by `--kbq-autocomplete-size-panel-max-height` and reveals its
40
- * active option through `KbqOption.focus`, so nothing computes a scroll offset from this. Will be removed
41
- * in the next major release.
42
- */
43
- const AUTOCOMPLETE_PANEL_HEIGHT = 256;
44
37
  /**
45
38
  * Injection token that determines the scroll handling while the autocomplete panel is open. The root default
46
39
  * keeps the trigger usable outside `KbqAutocompleteModule`'s injector; providing the token anywhere still wins
@@ -48,18 +41,25 @@ const AUTOCOMPLETE_PANEL_HEIGHT = 256;
48
41
  */
49
42
  const KBQ_AUTOCOMPLETE_SCROLL_STRATEGY = new InjectionToken('kbq-autocomplete-scroll-strategy', {
50
43
  providedIn: 'root',
51
- factory: () => KBQ_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY(inject(Overlay))
44
+ factory: () => KBQ_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY(inject(ScrollDispatcher))
52
45
  });
53
- function KBQ_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY(overlay) {
54
- return () => overlay.scrollStrategies.reposition();
46
+ /** @docs-private */
47
+ function KBQ_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY(scrollDispatcher) {
48
+ return kbqRepositionScrollStrategyFactory(scrollDispatcher);
55
49
  }
50
+ /**
51
+ * Redundant to the root factory of the token; kept so an app can restore the default under its own override (#DS-2196).
52
+ *
53
+ * @docs-private
54
+ */
56
55
  const KBQ_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY_PROVIDER = {
57
56
  provide: KBQ_AUTOCOMPLETE_SCROLL_STRATEGY,
58
- deps: [Overlay],
57
+ deps: [ScrollDispatcher],
59
58
  useFactory: KBQ_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY
60
59
  };
61
60
  /**
62
61
  * Provider that allows the autocomplete to register as a ControlValueAccessor.
62
+ *
63
63
  * @docs-private
64
64
  */
65
65
  const KBQ_AUTOCOMPLETE_VALUE_ACCESSOR = {
@@ -67,9 +67,17 @@ const KBQ_AUTOCOMPLETE_VALUE_ACCESSOR = {
67
67
  useExisting: forwardRef(() => KbqAutocompleteTrigger),
68
68
  multi: true
69
69
  };
70
+ /** Class of the layer that draws the inline hint over the field. */
71
+ const INLINE_HINT_CLASS = 'kbq-autocomplete-inline-hint';
72
+ /**
73
+ * `type` of the fields whose native role, `textbox` or `searchbox`, supports `aria-autocomplete` and
74
+ * `aria-activedescendant`. A textarea reports `textarea`.
75
+ */
76
+ const TEXT_FIELD_TYPES = new Set(['text', 'search', 'email', 'tel', 'url', 'textarea']);
70
77
  /**
71
78
  * Creates an error to be thrown when attempting to use an autocomplete trigger without a panel.
72
- * @docs-private
79
+ *
80
+ * @internal
73
81
  */
74
82
  function getKbqAutocompleteMissingPanelError() {
75
83
  return Error('Attempting to open an undefined instance of `kbq-autocomplete`. ' +
@@ -82,45 +90,42 @@ class KbqAutocompleteTrigger {
82
90
  return this.autocomplete()?.keyManager?.activeItem;
83
91
  }
84
92
  get panelOpen() {
85
- return this.overlayAttached && this.autocomplete().showPanel;
93
+ return this.overlayAttached() && this.autocomplete().showPanel();
86
94
  }
87
95
  /** Whether the autocomplete panel is currently on screen. Part of the `KbqSiblingPopup` contract. */
88
96
  get isAttached() {
89
- return this.overlayAttached;
97
+ return this.overlayAttached();
90
98
  }
91
99
  /**
92
- * Whether the autocomplete is disabled. When disabled, the element will
93
- * act as a regular input and the user won't be able to open the panel.
100
+ * Whether the host takes the `combobox` role. ARIA in HTML allows it on a text input only: a textarea and the
101
+ * other text fields keep their native role.
94
102
  */
95
- // TODO: Skipped for migration because:
96
- // Accessor inputs cannot be migrated as they are too complex.
97
- get autocompleteDisabled() {
98
- return this._autocompleteDisabled;
103
+ get isCombobox() {
104
+ return this.exposesPanel && this.elementRef.nativeElement.type === 'text';
99
105
  }
100
- set autocompleteDisabled(value) {
101
- this._autocompleteDisabled = coerceBooleanProperty(value);
106
+ /**
107
+ * Whether the host exposes the panel to assistive technology: a text field with the autocomplete enabled. Other
108
+ * fields, such as a number input, keep their native semantics.
109
+ */
110
+ get exposesPanel() {
111
+ return !this.autocompleteDisabled() && TEXT_FIELD_TYPES.has(this.elementRef.nativeElement.type);
102
112
  }
103
113
  constructor() {
104
114
  this.elementRef = inject(ElementRef);
105
115
  this.viewContainerRef = inject(ViewContainerRef);
106
116
  this.changeDetectorRef = inject(ChangeDetectorRef);
107
117
  this.overlay = inject(Overlay);
118
+ this.overlayLayers = inject(KBQ_OVERLAY_LAYERS);
108
119
  this.zone = inject(NgZone);
120
+ this.injector = inject(Injector);
109
121
  this.dir = inject(Directionality, { optional: true });
110
122
  this.formField = inject(KBQ_FORM_FIELD, { optional: true, host: true });
111
123
  this.viewportRuler = inject(ViewportRuler);
112
124
  this.document = inject(DOCUMENT);
113
- this.optionSelections = defer(() => {
114
- const autocomplete = this.autocomplete();
115
- if (autocomplete && autocomplete.options) {
116
- return merge(...autocomplete.options.map((option) => option.onSelectionChange));
117
- }
118
- // If there are any subscribers before `ngAfterViewInit`, the `autocomplete` will be undefined.
119
- // Return a stream that we'll replace with the real one once everything is in place.
120
- return this.zone.onStable.asObservable().pipe(take(1), switchMap(() => this.optionSelections));
121
- });
122
125
  /** The autocomplete panel to be attached to this trigger. */
123
- this.autocomplete = input(undefined, ...(ngDevMode ? [{ debugName: "autocomplete", alias: 'kbqAutocomplete' }] : [{ alias: 'kbqAutocomplete' }]));
126
+ this.autocomplete = input(undefined, { ...(ngDevMode ? { debugName: "autocomplete" } : /* istanbul ignore next */ {}), alias: 'kbqAutocomplete' });
127
+ /** The bound panel, replayed to every subscriber: it may be bound, or rendered, after they subscribe. */
128
+ this.autocompleteChanges = toObservable(this.autocomplete);
124
129
  /**
125
130
  * Emits `true` when the panel opens and `false` when it closes. Part of the `KbqSiblingPopup`
126
131
  * contract.
@@ -128,29 +133,85 @@ class KbqAutocompleteTrigger {
128
133
  * Built on top of the `autocomplete` signal rather than read once: the panel is bound after the consumers
129
134
  * of this stream are created (a tooltip on the same element subscribes in its constructor).
130
135
  */
131
- this.openedChange = toObservable(this.autocomplete).pipe(filter(Boolean), switchMap((autocomplete) => merge(outputToObservable(autocomplete.opened).pipe(map(() => true)), outputToObservable(autocomplete.closed).pipe(map(() => false)))));
136
+ this.openedChange = this.autocompleteChanges.pipe(filter(Boolean), switchMap((autocomplete) => merge(outputToObservable(autocomplete.opened).pipe(map(() => true)), outputToObservable(autocomplete.closed).pipe(map(() => false)))));
137
+ // Follows the bound panel and its options rather than reading them once: either may arrive after a subscriber.
138
+ this.optionSelections = this.autocompleteChanges.pipe(switchMap((autocomplete) => {
139
+ if (!autocomplete)
140
+ return EMPTY;
141
+ const { options } = autocomplete;
142
+ return options.changes.pipe(startWith(options), switchMap(() => merge(...options.map((option) => option.onSelectionChange))));
143
+ }));
132
144
  /**
133
145
  * Reference relative to which to position the autocomplete panel.
134
146
  * Defaults to the autocomplete trigger element.
135
147
  */
136
- this.connectedTo = input(undefined, ...(ngDevMode ? [{ debugName: "connectedTo", alias: 'kbqAutocompleteConnectedTo' }] : [{ alias: 'kbqAutocompleteConnectedTo' }]));
148
+ this.connectedTo = input(undefined, { ...(ngDevMode ? { debugName: "connectedTo" } : /* istanbul ignore next */ {}), alias: 'kbqAutocompleteConnectedTo' });
137
149
  /**
138
150
  * `autocomplete` attribute to be set on the input element.
151
+ *
139
152
  * @docs-private
140
153
  */
141
- this.autocompleteAttribute = input('off', ...(ngDevMode ? [{ debugName: "autocompleteAttribute", alias: 'autocomplete' }] : [{ alias: 'autocomplete' }]));
154
+ this.autocompleteAttribute = input('off', { ...(ngDevMode ? { debugName: "autocompleteAttribute" } : /* istanbul ignore next */ {}), alias: 'autocomplete' });
155
+ /**
156
+ * Whether the autocomplete is disabled. When disabled, the element will
157
+ * act as a regular input and the user won't be able to open the panel.
158
+ */
159
+ this.autocompleteDisabled = input(false, { ...(ngDevMode ? { debugName: "autocompleteDisabled" } : /* istanbul ignore next */ {}), alias: 'kbqAutocompleteDisabled',
160
+ transform: booleanAttribute });
142
161
  /**
143
162
  * Event handler for input blur events.
144
163
  * Determines whether the blur event is triggered outside the specific target
164
+ *
145
165
  * @returns A boolean indicating if the blur event happened outside the target element
146
166
  */
147
167
  this.onInputBlur = input((event) => {
148
168
  const target = event.relatedTarget;
149
169
  return !target || target.tagName !== 'KBQ-OPTION';
150
- }, ...(ngDevMode ? [{ debugName: "onInputBlur", alias: 'kbqAutocompleteOnBlur' }] : [{ alias: 'kbqAutocompleteOnBlur' }]));
151
- this._autocompleteDisabled = false;
152
- this.overlayAttached = false;
153
- this.componentDestroyed = false;
170
+ }, { ...(ngDevMode ? { debugName: "onInputBlur" } : /* istanbul ignore next */ {}), alias: 'kbqAutocompleteOnBlur' });
171
+ /**
172
+ * Whether the panel opens from the text caret instead of the field: its left edge at the caret, right below the
173
+ * caret's line, following the caret while it moves. The panel is only as wide as its options — `panelMinWidth`
174
+ * does not apply there, an explicit `panelWidth` still does.
175
+ */
176
+ this.relativeToCaret = input(false, { ...(ngDevMode ? { debugName: "relativeToCaret" } : /* istanbul ignore next */ {}), alias: 'kbqAutocompleteRelativeToCaret',
177
+ transform: booleanAttribute });
178
+ /**
179
+ * Whether the autocomplete completes the text at the caret instead of the whole value. The query is the word
180
+ * before the caret, or the text after one of `kbqAutocompleteTriggers`; choosing an option replaces the query,
181
+ * trigger included, with the option. The form value stays the whole text.
182
+ */
183
+ this.textMode = input(false, { ...(ngDevMode ? { debugName: "textMode" } : /* istanbul ignore next */ {}), alias: 'kbqAutocompleteTextMode',
184
+ transform: booleanAttribute });
185
+ /** Strings that start a query in text mode, such as `/` or `@`. When empty, the query is the word before the caret. */
186
+ this.queryTriggers = input([], { ...(ngDevMode ? { debugName: "queryTriggers" } : /* istanbul ignore next */ {}), alias: 'kbqAutocompleteTriggers' });
187
+ /** Shortest query that opens the panel in text mode. Defaults to `1` for a word and to `0` after a trigger. */
188
+ this.queryMinLength = input(undefined, { ...(ngDevMode ? { debugName: "queryMinLength" } : /* istanbul ignore next */ {}), alias: 'kbqAutocompleteMinLength',
189
+ transform: kbqOptionalNumberAttribute });
190
+ /**
191
+ * Whether text mode draws the rest of the active option after the caret, to be accepted with `Tab` or `→`. The
192
+ * field has to be inside `kbq-form-field`.
193
+ */
194
+ this.inlineHint = input(true, { ...(ngDevMode ? { debugName: "inlineHint" } : /* istanbul ignore next */ {}), alias: 'kbqAutocompleteInlineHint',
195
+ transform: booleanAttribute });
196
+ /**
197
+ * Emits the query at the caret in text mode whenever it changes, or `null` once there is none. The query is read
198
+ * again as the user types or clicks in the field, and as the caret moves while the panel is open. It carries the
199
+ * trigger it starts with, which tells apart the options to show for each trigger.
200
+ */
201
+ this.queryChange = output({ alias: 'kbqAutocompleteQueryChange' });
202
+ this.renderer = inject(Renderer2);
203
+ /** Origin of a caret-anchored panel, measured again whenever the panel is positioned. */
204
+ this.caretOrigin = kbqCreateCaretOrigin(() => this.measureCaretOrigin());
205
+ /** Query at the caret in text mode, or `null` while there is none. */
206
+ this.query = null;
207
+ /** Stops the listeners that follow the caret while the panel is open. */
208
+ this.stopCaretListeners = null;
209
+ /** Layer that draws the inline hint, created the first time there is a hint to draw. */
210
+ this.textMirror = null;
211
+ /** Inline hint drawn after the caret, or `''` while there is none. */
212
+ this.inlineHintText = '';
213
+ /** Whether the overlay is attached. A signal: host bindings read it, and it changes outside any listener. */
214
+ this.overlayAttached = signal(false, ...(ngDevMode ? [{ debugName: "overlayAttached" }] : /* istanbul ignore next */ []));
154
215
  /** Subscription to viewport size changes. */
155
216
  this.viewportSubscription = Subscription.EMPTY;
156
217
  /**
@@ -162,9 +223,17 @@ class KbqAutocompleteTrigger {
162
223
  /** Stream of keyboard events that can close the panel. */
163
224
  this.closeKeyEventStream = new Subject();
164
225
  this.window = inject(KBQ_WINDOW);
165
- /** `View -> model callback called when value changes` */
226
+ /**
227
+ * Called when the value changes. Needed to properly implement `ControlValueAccessor`.
228
+ *
229
+ * @docs-private
230
+ */
166
231
  this.onChange = () => { };
167
- /** `View -> model callback called when autocomplete has been touched` */
232
+ /**
233
+ * Called when the control is blurred. Needed to properly implement `ControlValueAccessor`.
234
+ *
235
+ * @docs-private
236
+ */
168
237
  this.onTouched = () => { };
169
238
  /**
170
239
  * Event handler for when the window is blurred. Needs to be an
@@ -181,6 +250,13 @@ class KbqAutocompleteTrigger {
181
250
  afterNextRender(() => {
182
251
  zone.runOutsideAngular(() => this.window.addEventListener('blur', this.windowBlurHandler));
183
252
  });
253
+ // A hint drawn before text mode, the hint or the autocomplete itself was switched off must not stay behind.
254
+ effect(() => {
255
+ this.textMode();
256
+ this.inlineHint();
257
+ this.autocompleteDisabled();
258
+ untracked(() => this.updateInlineHint());
259
+ });
184
260
  this.scrollStrategy = scrollStrategy;
185
261
  }
186
262
  ngAfterViewInit() {
@@ -188,10 +264,13 @@ class KbqAutocompleteTrigger {
188
264
  if (autocomplete) {
189
265
  autocomplete.keyManager?.change.subscribe(() => {
190
266
  const autocompleteValue = this.autocomplete();
267
+ // The host binding that announces the active option is not checked otherwise when this view is OnPush.
268
+ this.changeDetectorRef.markForCheck();
191
269
  if (this.panelOpen) {
192
270
  this.scrollActiveOptionIntoView();
193
271
  // Focus returns to the input on every arrow key; it must not drag the scroll with it.
194
272
  this.elementRef.nativeElement.focus({ preventScroll: true });
273
+ this.updateInlineHint();
195
274
  }
196
275
  else if (!this.panelOpen && autocompleteValue.keyManager.activeItem) {
197
276
  autocompleteValue.keyManager.activeItem?.selectViaInteraction();
@@ -202,58 +281,66 @@ class KbqAutocompleteTrigger {
202
281
  ngOnDestroy() {
203
282
  this.window.removeEventListener('blur', this.windowBlurHandler);
204
283
  this.viewportSubscription.unsubscribe();
205
- this.componentDestroyed = true;
206
284
  this.destroyPanel();
285
+ this.textMirror?.destroy();
207
286
  this.closeKeyEventStream.complete();
208
287
  }
209
288
  /** Opens the autocomplete suggestion panel. */
210
289
  open() {
211
- this.attachOverlay();
290
+ // Untracked, like `closePanel()` and `updatePosition()`: called from a consumer's `effect()`, the state read
291
+ // on the way — whether the overlay is attached, the panel's options, the inputs — would make the effect run
292
+ // again on every open and close.
293
+ untracked(() => this.attachOverlay());
212
294
  }
213
295
  closePanel() {
214
- if (!this.overlayAttached) {
215
- return;
216
- }
217
- if (this.panelOpen) {
218
- // TODO: The 'emit' function requires a mandatory void argument
219
- this.autocomplete().closed.emit();
220
- }
221
- this.autocomplete().isOpen = this.overlayAttached = false;
222
- if (this.overlayRef && this.overlayRef.hasAttached()) {
223
- this.overlayRef.detach();
224
- this.closingActionsSubscription.unsubscribe();
225
- }
226
- // Note that in some cases this can end up being called after the component is destroyed.
227
- // Add a check to ensure that we don't try to run change detection on a destroyed view.
228
- if (!this.componentDestroyed) {
229
- // We need to trigger change detection manually, because
230
- // `fromEvent` doesn't seem to do it at the proper time.
231
- // This ensures that the label is reset when the
232
- // user clicks outside.
233
- this.changeDetectorRef.detectChanges();
234
- }
296
+ untracked(() => {
297
+ if (!this.overlayAttached()) {
298
+ return;
299
+ }
300
+ if (this.panelOpen) {
301
+ this.autocomplete().closed.emit();
302
+ }
303
+ this.stopFollowingCaret();
304
+ this.inlineHintText = '';
305
+ this.textMirror?.hide();
306
+ this.overlayAttached.set(false);
307
+ this.autocomplete().attached.set(false);
308
+ if (this.overlayRef && this.overlayRef.hasAttached()) {
309
+ this.overlayRef.detach();
310
+ this.closingActionsSubscription.unsubscribe();
311
+ }
312
+ });
235
313
  }
236
314
  /**
237
315
  * Updates the position of the autocomplete suggestion panel to ensure that it fits all options
238
316
  * within the viewport.
239
317
  */
240
318
  updatePosition() {
241
- if (this.overlayAttached) {
242
- this.overlayRef.updatePosition();
243
- }
319
+ untracked(() => {
320
+ if (this.overlayAttached()) {
321
+ this.overlayRef.updatePosition();
322
+ }
323
+ });
244
324
  }
245
325
  /**
246
326
  * A stream of actions that should close the autocomplete panel, including
247
327
  * when an option is selected, on blur, and when TAB is pressed.
248
328
  */
249
329
  get panelClosingActions() {
250
- return merge(this.optionSelections, this.autocomplete().keyManager.tabOut.pipe(filter(() => this.overlayAttached)), this.closeKeyEventStream, this.getOutsideClickStream(), this.overlayRef ? this.overlayRef.detachments().pipe(filter(() => this.overlayAttached)) : of()).pipe(
330
+ return merge(this.optionSelections, this.autocomplete().keyManager.tabOut.pipe(filter(() => this.overlayAttached())), this.closeKeyEventStream, this.getOutsideClickStream(), this.overlayRef ? this.overlayRef.detachments().pipe(filter(() => this.overlayAttached())) : of()).pipe(
251
331
  // Normalize the output so we return a consistent type.
252
332
  map((event) => (event instanceof KbqOptionSelectionChange ? event : null)));
253
333
  }
254
334
  // Implemented as part of ControlValueAccessor.
255
335
  writeValue(value) {
256
- Promise.resolve(null).then(() => this.setTriggerValue(value));
336
+ Promise.resolve(null).then(() => {
337
+ this.setTriggerValue(value);
338
+ // The text changed without an input event: the query, its options and its hint belong to the old text.
339
+ if (this.textMode()) {
340
+ this.setQuery(null);
341
+ this.closePanel();
342
+ }
343
+ });
257
344
  }
258
345
  // Implemented as part of ControlValueAccessor.
259
346
  // eslint-disable-next-line @typescript-eslint/no-empty-object-type
@@ -271,14 +358,28 @@ class KbqAutocompleteTrigger {
271
358
  }
272
359
  handleKeydown(event) {
273
360
  const keyCode = event.keyCode;
274
- // Prevent the default action on all escape key presses. This is here primarily to bring IE
275
- // in line with other browsers. By default, pressing escape on IE will cause it to revert
276
- // the input value to the one that it had on focus, however it won't dispatch any events
277
- // which means that the model value will be out of sync with the view.
278
- if (keyCode === ESCAPE) {
361
+ // The overlay closes the panel once the key reaches `body`. Consumed only when there is a panel
362
+ // to close, so a dialog around the input still takes the key.
363
+ if (keyCode === ESCAPE && this.panelOpen) {
279
364
  event.preventDefault();
280
365
  }
281
366
  const autocomplete = this.autocomplete();
367
+ // In text mode Shift with an arrow selects text, as in any other text, instead of walking the options.
368
+ if (this.textMode() && event.shiftKey && (keyCode === UP_ARROW || keyCode === DOWN_ARROW))
369
+ return;
370
+ if (this.acceptsInlineHint(event)) {
371
+ event.preventDefault();
372
+ this.activeOption.selectViaInteraction();
373
+ return;
374
+ }
375
+ // The active option is re-resolved a task after the options change, so an Enter right after a keystroke can
376
+ // find it pointing at an option the new query filtered out: resolve it now rather than pick a stale one.
377
+ if (keyCode === ENTER &&
378
+ this.panelOpen &&
379
+ this.activeOption &&
380
+ !autocomplete.options.toArray().includes(this.activeOption)) {
381
+ this.resetActiveItem();
382
+ }
282
383
  if (this.activeOption && keyCode === ENTER && this.panelOpen) {
283
384
  this.activeOption.selectViaInteraction();
284
385
  this.resetActiveItem();
@@ -289,7 +390,8 @@ class KbqAutocompleteTrigger {
289
390
  if (this.panelOpen || keyCode === TAB) {
290
391
  autocomplete.onKeydown(event);
291
392
  }
292
- else if (!this.panelOpen && keyCode === DOWN_ARROW && this.canOpen()) {
393
+ else if (!this.panelOpen && keyCode === DOWN_ARROW && this.canOpen() && !this.textMode()) {
394
+ // In text mode the arrow moves the caret to the next line, as it does in any other text.
293
395
  this.open();
294
396
  }
295
397
  const isArrowKey = keyCode === UP_ARROW || keyCode === DOWN_ARROW;
@@ -313,22 +415,44 @@ class KbqAutocompleteTrigger {
313
415
  if (this.previousValue !== value) {
314
416
  this.previousValue = value;
315
417
  this.onChange(value);
316
- if (this.canOpen() && _getFocusedElementPierceShadowDom() === target) {
418
+ if (this.textMode()) {
419
+ this.refreshQuery(true);
420
+ }
421
+ else if (this.canOpen() && _getFocusedElementPierceShadowDom() === target) {
317
422
  this.open();
318
423
  }
319
424
  }
320
425
  }
426
+ /**
427
+ * Keeps `openOnFocus` from opening the panel the next time the input is focused. Lets a host that
428
+ * restores focus itself — after clearing, say — do so without the panel springing open.
429
+ *
430
+ * @docs-private
431
+ */
432
+ suppressOpenOnNextFocus() {
433
+ this.canOpenOnNextFocus = false;
434
+ }
321
435
  handleFocus() {
322
436
  if (!this.canOpenOnNextFocus) {
323
437
  this.canOpenOnNextFocus = true;
324
438
  }
325
- else if (!this.panelOpen && this.canOpen() && this.autocomplete().openOnFocus) {
439
+ else if (!this.panelOpen && this.canOpen() && this.autocomplete().openOnFocus()) {
326
440
  this.previousValue = this.elementRef.nativeElement.value;
327
- this.attachOverlay();
441
+ if (this.textMode()) {
442
+ this.refreshQuery(true);
443
+ }
444
+ else {
445
+ this.attachOverlay();
446
+ }
328
447
  }
329
448
  }
330
449
  handleClick($event) {
331
- if (!this.panelOpen && this.canOpen() && _getFocusedElementPierceShadowDom() === $event.target) {
450
+ if (_getFocusedElementPierceShadowDom() !== $event.target)
451
+ return;
452
+ if (this.textMode()) {
453
+ this.refreshQuery(true);
454
+ }
455
+ else if (!this.panelOpen && this.canOpen()) {
332
456
  this.open();
333
457
  }
334
458
  }
@@ -342,7 +466,7 @@ class KbqAutocompleteTrigger {
342
466
  const formField = this.formField ? this.formField.elementRef.nativeElement : null;
343
467
  const connectedTo = this.connectedTo();
344
468
  const customOrigin = connectedTo ? connectedTo.elementRef.nativeElement : null;
345
- return (this.overlayAttached &&
469
+ return (this.overlayAttached() &&
346
470
  clickTarget !== this.elementRef.nativeElement &&
347
471
  (!formField || !formField.contains(clickTarget)) &&
348
472
  (!customOrigin || !customOrigin.contains(clickTarget)) &&
@@ -355,20 +479,30 @@ class KbqAutocompleteTrigger {
355
479
  * stream every time the option list changes.
356
480
  */
357
481
  subscribeToClosingActions() {
358
- const firstStable = this.zone.onStable.asObservable().pipe(take(1));
482
+ const firstRender = new Observable((subscriber) => {
483
+ const ref = afterNextRender(() => subscriber.next(), { injector: this.injector });
484
+ return () => ref.destroy();
485
+ });
359
486
  const optionChanges = this.autocomplete().options.changes.pipe(tap(() => this.positionStrategy.reapplyLastPosition()),
360
487
  // Defer emitting to the stream until the next tick, because changing
361
488
  // bindings in here will cause "changed after checked" errors.
362
489
  delay(0));
363
- // When the zone is stable initially, and when the option list changes...
364
- return (merge(firstStable, optionChanges)
490
+ // When the options are initially rendered, and when the option list changes...
491
+ return (merge(firstRender, optionChanges)
365
492
  .pipe(
366
493
  // create a new stream of panelClosingActions, replacing any previous streams
367
494
  // that were created, and flatten it so our stream only emits closing events...
368
495
  switchMap(() => {
369
496
  const wasOpen = this.panelOpen;
370
- this.resetActiveItem();
497
+ // Visibility first: the key manager reports the new active option to a handler that selects
498
+ // it whenever the panel is not open, and a panel whose options arrived after it was attached
499
+ // is not open until the visibility is updated.
371
500
  this.autocomplete().setVisibility();
501
+ this.resetActiveItem();
502
+ // The active option can stay at the same index while the option behind it changes, which
503
+ // the key manager does not report.
504
+ this.changeDetectorRef.markForCheck();
505
+ this.updateInlineHint();
372
506
  if (this.panelOpen) {
373
507
  this.overlayRef.updatePosition();
374
508
  // If the `panelOpen` state changed, we need to make sure to emit the `opened`
@@ -376,7 +510,6 @@ class KbqAutocompleteTrigger {
376
510
  // can happen if the users opens the panel and there are no options, but the
377
511
  // options come in slightly later or as a result of the value changing.
378
512
  if (wasOpen !== this.panelOpen) {
379
- // TODO: The 'emit' function requires a mandatory void argument
380
513
  this.autocomplete().opened.emit();
381
514
  }
382
515
  }
@@ -397,29 +530,38 @@ class KbqAutocompleteTrigger {
397
530
  }
398
531
  setTriggerValue(value) {
399
532
  const autocomplete = this.autocomplete();
400
- const toDisplay = autocomplete && autocomplete.displayWith ? autocomplete.displayWith(value) : value;
533
+ const displayWith = autocomplete?.displayWith();
534
+ // In text mode the value is the text itself, and `displayWith` maps options, not the text around them.
535
+ const toDisplay = displayWith && !this.textMode() ? displayWith(value) : value;
401
536
  // Simply falling back to an empty string if the display value is falsy does not work properly.
402
537
  // The display value can also be the number zero and shouldn't fall back to an empty string.
403
538
  const inputValue = toDisplay != null ? toDisplay : '';
404
- // If it's used within a `MatFormField`, we should set it through the property so it can go
405
- // through change detection.
406
- if (this.formField) {
407
- this.formField.control().value = inputValue;
408
- }
409
- else {
410
- this.elementRef.nativeElement.value = inputValue;
539
+ // Written at once, because the text is read back from the element right after. The control on the element is
540
+ // told as well: it would otherwise pick the change up only at its next check. Not the control of the form
541
+ // field, which is the tag list when the input adds tags. Looked up here: `KbqInput` injects the `NgControl`
542
+ // that injects this directive.
543
+ this.elementRef.nativeElement.value = inputValue;
544
+ const controlValue = this.injector.get(KbqFormFieldControl, null, { self: true })?.value;
545
+ if (isWritableSignal(controlValue)) {
546
+ controlValue.set(inputValue);
411
547
  }
412
548
  this.previousValue = inputValue;
413
549
  }
414
- /** This method closes the panel, and if a value is specified, also sets the associated
550
+ /**
551
+ * This method closes the panel, and if a value is specified, also sets the associated
415
552
  * control to that value. It will also mark the control as dirty if this interaction
416
553
  * stemmed from the user.
417
554
  */
418
555
  setValueAndClose(event) {
419
556
  if (event?.source) {
420
557
  this.clearPreviousSelectedOption(event.source);
421
- this.setTriggerValue(event.source.value);
422
- this.onChange(event.source.value);
558
+ if (this.textMode()) {
559
+ this.insertOption(event.source);
560
+ }
561
+ else {
562
+ this.setTriggerValue(event.source.value);
563
+ this.onChange(event.source.value);
564
+ }
423
565
  this.elementRef.nativeElement.focus();
424
566
  this.autocomplete().emitSelectEvent(event.source);
425
567
  }
@@ -443,6 +585,7 @@ class KbqAutocompleteTrigger {
443
585
  this.portal = new TemplatePortal(autocomplete.template(), this.viewContainerRef);
444
586
  overlayRef = this.overlay.create(this.getOverlayConfig());
445
587
  this.overlayRef = overlayRef;
588
+ this.overlayLayers.adopt(overlayRef, this.elementRef.nativeElement);
446
589
  // Use the `keydownEvents` in order to take advantage of
447
590
  // the overlay event targeting provided by the CDK overlay.
448
591
  overlayRef.keydownEvents().subscribe((event) => {
@@ -464,32 +607,34 @@ class KbqAutocompleteTrigger {
464
607
  else {
465
608
  const position = overlayRef.getConfig().positionStrategy;
466
609
  // Update the trigger, panel width and direction, in case anything has changed.
467
- position.setOrigin(this.getConnectedElement());
610
+ position.setOrigin(this.getPositionOrigin()).withPositions(this.getPanelPositions());
468
611
  overlayRef.updateSize(this.getOverlaySize());
469
612
  }
470
613
  if (overlayRef && !overlayRef.hasAttached()) {
471
614
  overlayRef.attach(this.portal);
472
615
  this.closingActionsSubscription = this.subscribeToClosingActions();
616
+ this.startFollowingCaret();
473
617
  }
474
618
  const wasOpen = this.panelOpen;
619
+ autocomplete.listboxName.set(this.getListboxName());
475
620
  autocomplete.setVisibility();
476
- autocomplete.isOpen = this.overlayAttached = true;
621
+ this.overlayAttached.set(true);
622
+ autocomplete.attached.set(true);
477
623
  // We need to do an extra `panelOpen` check in here, because the
478
624
  // autocomplete won't be shown if there are no options.
479
625
  if (this.panelOpen && wasOpen !== this.panelOpen) {
480
- // TODO: The 'emit' function requires a mandatory void argument
481
626
  autocomplete.opened.emit();
482
627
  }
483
- this.zone.onStable
484
- .asObservable()
485
- .pipe(take(1))
486
- .subscribe(() => {
628
+ afterNextRender(() => {
629
+ // Closed before the render: the key manager selects an option made active on a closed panel.
630
+ if (!this.overlayAttached())
631
+ return;
487
632
  this.resetActiveItem();
488
- // Overlay width may not be final on first open, so re-measure when the layout is stable.
633
+ // Overlay width may not be final on first open, so re-measure once the panel is rendered.
489
634
  if (this.panelOpen && this.overlayRef) {
490
635
  this.overlayRef.updateSize(this.getOverlaySize());
491
636
  }
492
- });
637
+ }, { injector: this.injector });
493
638
  }
494
639
  getOverlayConfig() {
495
640
  return new OverlayConfig({
@@ -502,7 +647,7 @@ class KbqAutocompleteTrigger {
502
647
  getOverlayPosition() {
503
648
  this.positionStrategy = this.overlay
504
649
  .position()
505
- .flexibleConnectedTo(this.getConnectedElement())
650
+ .flexibleConnectedTo(this.getPositionOrigin())
506
651
  .withFlexibleDimensions(false)
507
652
  .withPush(false)
508
653
  // CDK measures the pane before the trigger↔panel gap padding (kbq-connected-overlay-gap) is
@@ -510,22 +655,7 @@ class KbqAutocompleteTrigger {
510
655
  // it a margin at least as big as the gap (defaultOffsetY) keeps the fit check conservative
511
656
  // enough to absorb the padding that lands afterwards.
512
657
  .withViewportMargin(defaultOffsetY)
513
- .withPositions([
514
- {
515
- originX: 'start',
516
- originY: 'bottom',
517
- overlayX: 'start',
518
- overlayY: 'top',
519
- panelClass: KBQ_CONNECTED_OVERLAY_BELOW_CLASS
520
- },
521
- {
522
- originX: 'start',
523
- originY: 'top',
524
- overlayX: 'start',
525
- overlayY: 'bottom',
526
- panelClass: KBQ_CONNECTED_OVERLAY_ABOVE_CLASS
527
- }
528
- ]);
658
+ .withPositions(this.getPanelPositions());
529
659
  return this.positionStrategy;
530
660
  }
531
661
  getConnectedElement() {
@@ -535,34 +665,250 @@ class KbqAutocompleteTrigger {
535
665
  }
536
666
  return this.formField ? this.formField.getConnectedOverlayOrigin() : this.elementRef;
537
667
  }
668
+ /**
669
+ * Positions of the panel, below and then above its origin, starting where the origin starts. A panel opened from
670
+ * the caret may also end at the caret: nothing else holds it on screen when the caret is near the right edge.
671
+ */
672
+ getPanelPositions() {
673
+ const below = {
674
+ originX: 'start',
675
+ originY: 'bottom',
676
+ overlayX: 'start',
677
+ overlayY: 'top',
678
+ panelClass: KBQ_CONNECTED_OVERLAY_BELOW_CLASS
679
+ };
680
+ const above = {
681
+ originX: 'start',
682
+ originY: 'top',
683
+ overlayX: 'start',
684
+ overlayY: 'bottom',
685
+ panelClass: KBQ_CONNECTED_OVERLAY_ABOVE_CLASS
686
+ };
687
+ return this.relativeToCaret()
688
+ ? [below, above, { ...below, overlayX: 'end' }, { ...above, overlayX: 'end' }]
689
+ : [below, above];
690
+ }
691
+ /** What the panel is positioned against: the caret when anchored to the caret, otherwise the field. */
692
+ getPositionOrigin() {
693
+ return this.relativeToCaret() ? this.caretOrigin : this.getConnectedElement();
694
+ }
695
+ /** The caret's line, or the field when the caret cannot be located. */
696
+ measureCaretOrigin() {
697
+ const caret = kbqGetCaretRect(this.elementRef.nativeElement);
698
+ if (caret)
699
+ return caret;
700
+ const { left, top, width, height } = this.getConnectedElement().nativeElement.getBoundingClientRect();
701
+ return { x: left, y: top, width, height };
702
+ }
538
703
  getOverlaySize() {
539
704
  const autocomplete = this.autocomplete();
705
+ // A caret has no width to match, and a panel opened from it is meant to be only as wide as its options.
706
+ if (this.relativeToCaret()) {
707
+ return kbqResolvePanelWidth(autocomplete.panelWidth(), 0, 0);
708
+ }
540
709
  return kbqResolvePanelWidth(autocomplete.panelWidth(), autocomplete.panelMinWidth(), this.getHostWidth());
541
710
  }
542
711
  getHostWidth() {
543
712
  return kbqGetPanelWidthOrigin(this.getConnectedElement());
544
713
  }
714
+ /**
715
+ * Name of the option list, taken from what names the field, in the order its own name is computed:
716
+ * `aria-labelledby`, `aria-label`, its labels, `title`, the placeholder.
717
+ */
718
+ getListboxName() {
719
+ const element = this.elementRef.nativeElement;
720
+ const ariaLabelledby = element.getAttribute('aria-labelledby')?.trim();
721
+ if (ariaLabelledby)
722
+ return { labelledby: ariaLabelledby, label: null };
723
+ const ariaLabel = element.getAttribute('aria-label')?.trim();
724
+ if (ariaLabel)
725
+ return { labelledby: null, label: ariaLabel };
726
+ const labels = Array.from(element.labels ?? []);
727
+ // Labels are referenced when every one of them can be; a label without an id, which a plain `<label for>` or
728
+ // a wrapping label may be, lends its text instead.
729
+ if (labels.length && labels.every(({ id }) => id)) {
730
+ return { labelledby: labels.map(({ id }) => id).join(' '), label: null };
731
+ }
732
+ const labelText = labels
733
+ .map(({ textContent }) => textContent?.trim())
734
+ .filter(Boolean)
735
+ .join(' ');
736
+ return { labelledby: null, label: labelText || element.title || element.placeholder || null };
737
+ }
545
738
  /**
546
739
  * Resets the active item to -1 so arrow events will activate the
547
740
  * correct options, or to 0 if the consumer opted into it.
548
741
  */
549
742
  resetActiveItem() {
550
743
  const autocomplete = this.autocomplete();
551
- if (autocomplete.autoActiveFirstOption) {
744
+ if (autocomplete.autoActiveFirstOption()) {
552
745
  autocomplete.keyManager.setFirstItemActive();
553
746
  }
554
747
  else {
555
748
  autocomplete.keyManager.setActiveItem(-1);
556
749
  }
557
750
  }
751
+ /**
752
+ * Re-reads the query at the caret in text mode and closes the panel once there is none. `open` lets a query open
753
+ * the panel: typing, focusing and clicking do, moving the caret through the text does not.
754
+ */
755
+ refreshQuery(open) {
756
+ const query = this.readQuery();
757
+ this.setQuery(query);
758
+ if (!query) {
759
+ this.closePanel();
760
+ return;
761
+ }
762
+ if (open &&
763
+ !this.overlayAttached() &&
764
+ this.canOpen() &&
765
+ _getFocusedElementPierceShadowDom() === this.elementRef.nativeElement) {
766
+ this.attachOverlay();
767
+ }
768
+ this.updateInlineHint();
769
+ }
770
+ /** Query at the caret, or `null` when there is none — including while text is selected, which is no caret. */
771
+ readQuery() {
772
+ const { selectionStart, selectionEnd, value } = this.elementRef.nativeElement;
773
+ if (selectionStart === null || selectionStart !== selectionEnd)
774
+ return null;
775
+ return kbqGetTextQuery(value, selectionStart, {
776
+ triggers: this.queryTriggers(),
777
+ minLength: this.queryMinLength()
778
+ });
779
+ }
780
+ /** Stores the query and reports it when it differs from the stored one. */
781
+ setQuery(query) {
782
+ const previous = this.query;
783
+ this.query = query;
784
+ if (query?.text !== previous?.text ||
785
+ query?.trigger !== previous?.trigger ||
786
+ query?.start !== previous?.start) {
787
+ this.queryChange.emit(query);
788
+ }
789
+ }
790
+ /**
791
+ * Follows the caret while the panel is open, outside the zone and at most once per attach: text mode re-reads the
792
+ * query, and a caret-anchored panel is positioned again, which measures the caret anew.
793
+ */
794
+ startFollowingCaret() {
795
+ if (this.stopCaretListeners || !(this.relativeToCaret() || this.textMode()))
796
+ return;
797
+ this.zone.runOutsideAngular(() => {
798
+ this.stopCaretListeners = kbqListenForCaretMoves(this.renderer, this.elementRef.nativeElement, () => {
799
+ if (this.textMode()) {
800
+ this.zone.run(() => this.refreshQuery(false));
801
+ }
802
+ if (this.relativeToCaret() && this.overlayAttached()) {
803
+ this.overlayRef?.updatePosition();
804
+ }
805
+ });
806
+ });
807
+ }
808
+ stopFollowingCaret() {
809
+ this.stopCaretListeners?.();
810
+ this.stopCaretListeners = null;
811
+ }
812
+ /**
813
+ * Replaces the query at the caret, trigger included, with the option, and puts the caret right after it. Without a
814
+ * query — the panel was opened with `open()`, or text is selected — the option goes in at the caret, over the
815
+ * selection. The query is read from the field again: the text may have changed since it was last read.
816
+ *
817
+ * `setRangeText` dispatches no `input`, and `KbqTextarea` grows on that event, so it is dispatched by hand — with
818
+ * `previousValue` already updated, so that `handleInput` does not take it for the user typing a new query.
819
+ */
820
+ insertOption(option) {
821
+ const element = this.elementRef.nativeElement;
822
+ const text = this.getOptionText(option);
823
+ const { selectionStart, selectionEnd } = element;
824
+ if (selectionStart === null || selectionEnd === null) {
825
+ // A field without a text selection, such as an `email` input, has no position to insert at.
826
+ this.setTriggerValue(text);
827
+ }
828
+ else {
829
+ const query = this.readQuery();
830
+ element.setRangeText(text, query?.start ?? selectionStart, query?.end ?? selectionEnd, 'end');
831
+ }
832
+ this.setQuery(null);
833
+ this.previousValue = element.value;
834
+ this.onChange(element.value);
835
+ // Selection state means nothing for an option that was inserted into the text, and a selected option would
836
+ // look chosen the next time the panel opens.
837
+ option.deselect(false);
838
+ // The panel closes right after; following the caret into the inserted text would read it as a new query.
839
+ this.stopFollowingCaret();
840
+ element.dispatchEvent(new Event('input', { bubbles: true }));
841
+ }
842
+ /** Text the option puts into the field. */
843
+ getOptionText(option) {
844
+ const displayWith = this.autocomplete().displayWith();
845
+ const text = displayWith ? displayWith(option.value) : option.value;
846
+ return text != null ? `${text}` : '';
847
+ }
848
+ /**
849
+ * Whether `event` accepts the inline hint. The hint is checked against the field again first: the text can change
850
+ * without an input event, and a hint drawn for the old text would write the option into the new one.
851
+ */
852
+ acceptsInlineHint(event) {
853
+ if (!this.inlineHintText || hasModifierKey(event) || (event.keyCode !== TAB && event.keyCode !== RIGHT_ARROW)) {
854
+ return false;
855
+ }
856
+ this.refreshQuery(false);
857
+ return !!this.inlineHintText;
858
+ }
859
+ /** Draws the rest of the active option after the caret, or hides the hint when there is none to draw. */
860
+ updateInlineHint() {
861
+ const hint = this.resolveInlineHint();
862
+ this.inlineHintText = hint;
863
+ if (!hint) {
864
+ this.textMirror?.hide();
865
+ return;
866
+ }
867
+ const element = this.elementRef.nativeElement;
868
+ const { value } = element;
869
+ const caret = this.query.end;
870
+ this.textMirror ??= kbqCreateTextMirror(element, INLINE_HINT_CLASS);
871
+ // A hint the field would lay out elsewhere, or outside the part of the field in view, is not a hint to accept.
872
+ if (!this.textMirror.update(value.slice(0, caret), hint, value.slice(caret))) {
873
+ this.inlineHintText = '';
874
+ }
875
+ }
876
+ /**
877
+ * Rest of the active option to draw after the caret, or `''`. A hint is only drawn where accepting it produces the
878
+ * text drawn: the option has to continue the text it replaces, and nothing may follow the caret on its line, where
879
+ * the hint would be drawn over it.
880
+ */
881
+ resolveInlineHint() {
882
+ const query = this.query;
883
+ const option = this.activeOption;
884
+ if (!this.textMode() ||
885
+ !this.inlineHint() ||
886
+ this.autocompleteDisabled() ||
887
+ !this.formField ||
888
+ !query ||
889
+ !option ||
890
+ !this.panelOpen) {
891
+ return '';
892
+ }
893
+ const element = this.elementRef.nativeElement;
894
+ const { value } = element;
895
+ const nextCharacter = value.charAt(query.end);
896
+ if ((nextCharacter && nextCharacter !== '\n') ||
897
+ !kbqIsTextLaidOutFromStart(this.window.getComputedStyle(element))) {
898
+ return '';
899
+ }
900
+ const text = this.getOptionText(option);
901
+ const replaced = value.slice(query.start, query.end);
902
+ return text.toLocaleLowerCase().startsWith(replaced.toLocaleLowerCase()) ? text.slice(replaced.length) : '';
903
+ }
558
904
  canOpen() {
559
905
  const element = this.elementRef.nativeElement;
560
- return !element.readOnly && !element.disabled && !this._autocompleteDisabled;
906
+ return !element.readOnly && !element.disabled && !this.autocompleteDisabled();
561
907
  }
562
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqAutocompleteTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
563
- /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.3.30", type: KbqAutocompleteTrigger, isStandalone: true, selector: "input[kbqAutocomplete], textarea[kbqAutocomplete]", inputs: { autocomplete: { classPropertyName: "autocomplete", publicName: "kbqAutocomplete", isSignal: true, isRequired: false, transformFunction: null }, connectedTo: { classPropertyName: "connectedTo", publicName: "kbqAutocompleteConnectedTo", isSignal: true, isRequired: false, transformFunction: null }, autocompleteAttribute: { classPropertyName: "autocompleteAttribute", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null }, autocompleteDisabled: { classPropertyName: "autocompleteDisabled", publicName: "kbqAutocompleteDisabled", isSignal: false, isRequired: false, transformFunction: null }, onInputBlur: { classPropertyName: "onInputBlur", publicName: "kbqAutocompleteOnBlur", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "focusin": "handleFocus()", "blur": "onTouched()", "input": "handleInput($event)", "keydown": "handleKeydown($event)", "click": "handleClick($event)" }, properties: { "attr.autocomplete": "autocompleteAttribute()" }, classAttribute: "kbq-autocomplete-trigger" }, providers: [KBQ_AUTOCOMPLETE_VALUE_ACCESSOR, kbqSiblingPopupProvider(KbqAutocompleteTrigger)], exportAs: ["kbqAutocompleteTrigger"], ngImport: i0 }); }
908
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqAutocompleteTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
909
+ /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.25", type: KbqAutocompleteTrigger, isStandalone: true, selector: "input[kbqAutocomplete], textarea[kbqAutocomplete]", inputs: { autocomplete: { classPropertyName: "autocomplete", publicName: "kbqAutocomplete", isSignal: true, isRequired: false, transformFunction: null }, connectedTo: { classPropertyName: "connectedTo", publicName: "kbqAutocompleteConnectedTo", isSignal: true, isRequired: false, transformFunction: null }, autocompleteAttribute: { classPropertyName: "autocompleteAttribute", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null }, autocompleteDisabled: { classPropertyName: "autocompleteDisabled", publicName: "kbqAutocompleteDisabled", isSignal: true, isRequired: false, transformFunction: null }, onInputBlur: { classPropertyName: "onInputBlur", publicName: "kbqAutocompleteOnBlur", isSignal: true, isRequired: false, transformFunction: null }, relativeToCaret: { classPropertyName: "relativeToCaret", publicName: "kbqAutocompleteRelativeToCaret", isSignal: true, isRequired: false, transformFunction: null }, textMode: { classPropertyName: "textMode", publicName: "kbqAutocompleteTextMode", isSignal: true, isRequired: false, transformFunction: null }, queryTriggers: { classPropertyName: "queryTriggers", publicName: "kbqAutocompleteTriggers", isSignal: true, isRequired: false, transformFunction: null }, queryMinLength: { classPropertyName: "queryMinLength", publicName: "kbqAutocompleteMinLength", isSignal: true, isRequired: false, transformFunction: null }, inlineHint: { classPropertyName: "inlineHint", publicName: "kbqAutocompleteInlineHint", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { queryChange: "kbqAutocompleteQueryChange" }, host: { listeners: { "focusin": "handleFocus()", "blur": "onTouched()", "input": "handleInput($event)", "keydown": "handleKeydown($any($event))", "click": "handleClick($event)" }, properties: { "attr.autocomplete": "autocompleteAttribute()", "attr.role": "isCombobox ? \"combobox\" : null", "attr.aria-expanded": "isCombobox ? panelOpen : null", "attr.aria-autocomplete": "exposesPanel ? (textMode() && inlineHint() ? \"both\" : \"list\") : null", "attr.aria-controls": "exposesPanel && panelOpen ? autocomplete().listboxId : null", "attr.aria-activedescendant": "exposesPanel && panelOpen ? activeOption?.id : null" }, classAttribute: "kbq-autocomplete-trigger" }, providers: [KBQ_AUTOCOMPLETE_VALUE_ACCESSOR, kbqSiblingPopupProvider(KbqAutocompleteTrigger)], exportAs: ["kbqAutocompleteTrigger"], ngImport: i0 }); }
564
910
  }
565
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqAutocompleteTrigger, decorators: [{
911
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqAutocompleteTrigger, decorators: [{
566
912
  type: Directive,
567
913
  args: [{
568
914
  selector: `input[kbqAutocomplete], textarea[kbqAutocomplete]`,
@@ -570,32 +916,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
570
916
  host: {
571
917
  class: 'kbq-autocomplete-trigger',
572
918
  '[attr.autocomplete]': 'autocompleteAttribute()',
919
+ // WAI-ARIA 1.2 combobox. A field that cannot take the role (see `isCombobox`) keeps its native one, which does
920
+ // not support `aria-expanded`.
921
+ '[attr.role]': 'isCombobox ? "combobox" : null',
922
+ '[attr.aria-expanded]': 'isCombobox ? panelOpen : null',
923
+ '[attr.aria-autocomplete]': 'exposesPanel ? (textMode() && inlineHint() ? "both" : "list") : null',
924
+ '[attr.aria-controls]': 'exposesPanel && panelOpen ? autocomplete().listboxId : null',
925
+ '[attr.aria-activedescendant]': 'exposesPanel && panelOpen ? activeOption?.id : null',
573
926
  // Note: we use `focusin`, as opposed to `focus`, in order to open the panel
574
927
  // a little earlier. This avoids issues where IE delays the focusing of the input.
575
928
  '(focusin)': 'handleFocus()',
576
929
  '(blur)': 'onTouched()',
577
930
  '(input)': 'handleInput($event)',
578
- '(keydown)': 'handleKeydown($event)',
931
+ '(keydown)': 'handleKeydown($any($event))',
579
932
  '(click)': 'handleClick($event)'
580
933
  },
581
934
  exportAs: 'kbqAutocompleteTrigger'
582
935
  }]
583
- }], ctorParameters: () => [], propDecorators: { autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqAutocomplete", required: false }] }], connectedTo: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqAutocompleteConnectedTo", required: false }] }], autocompleteAttribute: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], autocompleteDisabled: [{
584
- type: Input,
585
- args: ['kbqAutocompleteDisabled']
586
- }], onInputBlur: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqAutocompleteOnBlur", required: false }] }] } });
936
+ }], ctorParameters: () => [], propDecorators: { autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqAutocomplete", required: false }] }], connectedTo: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqAutocompleteConnectedTo", required: false }] }], autocompleteAttribute: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], autocompleteDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqAutocompleteDisabled", required: false }] }], onInputBlur: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqAutocompleteOnBlur", required: false }] }], relativeToCaret: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqAutocompleteRelativeToCaret", required: false }] }], textMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqAutocompleteTextMode", required: false }] }], queryTriggers: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqAutocompleteTriggers", required: false }] }], queryMinLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqAutocompleteMinLength", required: false }] }], inlineHint: [{ type: i0.Input, args: [{ isSignal: true, alias: "kbqAutocompleteInlineHint", required: false }] }], queryChange: [{ type: i0.Output, args: ["kbqAutocompleteQueryChange"] }] } });
587
937
 
588
- /**
589
- * Autocomplete IDs need to be unique across components, so this counter exists outside of
590
- * the component definition.
591
- */
592
- let uniqueAutocompleteIdCounter = 0;
593
938
  /** Footer that is rendered below the autocomplete options panel. */
594
939
  class KbqAutocompleteFooter {
595
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqAutocompleteFooter, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
596
- /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.30", type: KbqAutocompleteFooter, isStandalone: true, selector: "[kbqAutocompleteFooter], kbq-autocomplete-footer", host: { classAttribute: "kbq-autocomplete-footer" }, ngImport: i0 }); }
940
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqAutocompleteFooter, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
941
+ /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.25", type: KbqAutocompleteFooter, isStandalone: true, selector: "[kbqAutocompleteFooter], kbq-autocomplete-footer", host: { classAttribute: "kbq-autocomplete-footer" }, ngImport: i0 }); }
597
942
  }
598
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqAutocompleteFooter, decorators: [{
943
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqAutocompleteFooter, decorators: [{
599
944
  type: Directive,
600
945
  args: [{
601
946
  selector: '[kbqAutocompleteFooter], kbq-autocomplete-footer',
@@ -616,96 +961,134 @@ const KBQ_AUTOCOMPLETE_DEFAULT_OPTIONS = new InjectionToken('kbq-autocomplete-de
616
961
  function KBQ_AUTOCOMPLETE_DEFAULT_OPTIONS_FACTORY() {
617
962
  return { autoActiveFirstOption: true };
618
963
  }
964
+ /** Everything Angular's `[class]` binding accepts, flattened to the space-separated string form. */
965
+ function normalizeClassInput(value) {
966
+ if (!value)
967
+ return '';
968
+ if (typeof value === 'string')
969
+ return value;
970
+ if (Array.isArray(value))
971
+ return value.join(' ');
972
+ if (value instanceof Set)
973
+ return [...value].join(' ');
974
+ return Object.entries(value)
975
+ .filter(([, present]) => present)
976
+ .map(([className]) => className)
977
+ .join(' ');
978
+ }
619
979
  class KbqAutocomplete {
620
- /**
621
- * Takes classes set on the host kbq-autocomplete element and applies them to the panel
622
- * inside the overlay container to allow for easy styling.
623
- */
624
- // TODO: Skipped for migration because:
625
- // Accessor inputs cannot be migrated as they are too complex.
626
- get classList() {
627
- return this._classList;
628
- }
629
- set classList(value) {
630
- if (value && value.length) {
631
- const classList = { ...this._classList };
632
- value.split(' ').forEach((className) => (classList[className.trim()] = true));
633
- // Reassign a new object reference so the native `[class]` binding picks up the change.
634
- this._classList = classList;
635
- this.elementRef.nativeElement.className = '';
636
- }
637
- }
638
- /**
639
- * Whether the first option should be highlighted when the autocomplete panel is opened.
640
- * Can be configured globally through the `KBQ_AUTOCOMPLETE_DEFAULT_OPTIONS` token.
641
- */
642
- // TODO: Skipped for migration because:
643
- // Accessor inputs cannot be migrated as they are too complex.
644
- get autoActiveFirstOption() {
645
- return this._autoActiveFirstOption;
646
- }
647
- set autoActiveFirstOption(value) {
648
- this._autoActiveFirstOption = coerceBooleanProperty(value);
649
- }
650
- get isOpen() {
651
- return this._isOpen && this.showPanel;
652
- }
653
- set isOpen(value) {
654
- this._isOpen = value;
655
- }
656
- // TODO: Skipped for migration because:
657
- // Accessor inputs cannot be migrated as they are too complex.
658
- get openOnFocus() {
659
- return this._openOnFocus;
660
- }
661
- set openOnFocus(value) {
662
- this._openOnFocus = value;
980
+ get options() {
981
+ return this.optionsList();
663
982
  }
664
983
  constructor() {
665
- this.changeDetectorRef = inject(ChangeDetectorRef);
666
- this.elementRef = inject(ElementRef);
984
+ this.nativeElement = kbqInjectNativeElement();
667
985
  this.parentFormField = inject(KBQ_FORM_FIELD, { host: true, optional: true });
668
986
  this.destroyRef = inject(DestroyRef);
669
- /** Unique ID to be used by autocomplete trigger's "aria-owns" property. */
670
- this.id = `kbq-autocomplete-${uniqueAutocompleteIdCounter++}`;
671
- /** Whether the autocomplete panel should be visible, depending on option length. */
672
- this.showPanel = false;
987
+ this.defaultOptions = inject(KBQ_AUTOCOMPLETE_DEFAULT_OPTIONS);
988
+ /** Unique id, rendered as the panel element's `id`. */
989
+ this.id = inject(_IdGenerator).getId('kbq-autocomplete-');
990
+ /**
991
+ * Id of the option list, which the trigger's `aria-controls` points at while the panel is open.
992
+ *
993
+ * @docs-private
994
+ */
995
+ this.listboxId = `${this.id}-listbox`;
996
+ /**
997
+ * Whether the autocomplete panel should be visible, depending on option length.
998
+ *
999
+ * @docs-private
1000
+ */
1001
+ this.showPanel = signal(false, ...(ngDevMode ? [{ debugName: "showPanel" }] : /* istanbul ignore next */ []));
673
1002
  this.template = viewChild.required(TemplateRef);
674
1003
  this.panel = viewChild.required('panel');
675
- this.optionGroups = contentChildren(KbqOptgroup, ...(ngDevMode ? [{ debugName: "optionGroups" }] : []));
1004
+ this.scrollbarViewport = viewChild(KbqScrollbarViewport, ...(ngDevMode ? [{ debugName: "scrollbarViewport" }] : /* istanbul ignore next */ []));
1005
+ this.optionsQuery = contentChildren(KbqOption, { ...(ngDevMode ? { debugName: "optionsQuery" } : /* istanbul ignore next */ {}), descendants: true });
1006
+ this.optionsList = kbqQueryListFrom(this.optionsQuery);
1007
+ this.optionGroups = contentChildren(KbqOptgroup, ...(ngDevMode ? [{ debugName: "optionGroups" }] : /* istanbul ignore next */ []));
676
1008
  /** Function that maps an option's control value to its display value in the trigger. */
677
- // TODO: Skipped for migration because:
678
- // Your application code writes to the input. This prevents migration.
679
- this.displayWith = null;
1009
+ this.displayWith = input(null, ...(ngDevMode ? [{ debugName: "displayWith" }] : /* istanbul ignore next */ []));
680
1010
  /**
681
1011
  * Specify the width of the autocomplete panel. If set to `auto`, the panel will match the width of
682
1012
  * its host, but will never be narrower than `panelMinWidth`. Any other CSS sizing value is used as an
683
1013
  * exact width, and `panelMinWidth` is not applied. When not set, the panel sizes to its content and is
684
1014
  * at least as wide as its host.
685
1015
  */
686
- this.panelWidth = input(undefined, ...(ngDevMode ? [{ debugName: "panelWidth" }] : []));
1016
+ this.panelWidth = input(undefined, ...(ngDevMode ? [{ debugName: "panelWidth" }] : /* istanbul ignore next */ []));
687
1017
  /**
688
1018
  * Minimum width of the panel in pixels.
689
1019
  * When panelWidth is not set, the panel will be at least as wide as its host and no less than panelMinWidth.
690
1020
  */
691
- this.panelMinWidth = input(KBQ_PANEL_DEFAULT_MIN_WIDTH, ...(ngDevMode ? [{ debugName: "panelMinWidth", transform: numberAttribute }] : [{ transform: numberAttribute }]));
1021
+ this.panelMinWidth = input(KBQ_PANEL_DEFAULT_MIN_WIDTH, { ...(ngDevMode ? { debugName: "panelMinWidth" } : /* istanbul ignore next */ {}), transform: numberAttribute });
692
1022
  /**
693
1023
  * Maximum width of the panel in pixels. Caps how far the panel grows with its content — it never makes
694
1024
  * the panel narrower than its host, and never clamps an explicit `panelWidth`.
695
1025
  * When null, the `--kbq-panel-size-width-max` token applies.
696
1026
  */
697
- this.panelMaxWidth = input(null, ...(ngDevMode ? [{ debugName: "panelMaxWidth", transform: numberAttribute }] : [{ transform: numberAttribute }]));
1027
+ this.panelMaxWidth = input(null, { ...(ngDevMode ? { debugName: "panelMaxWidth" } : /* istanbul ignore next */ {}), transform: numberAttribute });
698
1028
  /** Event that is emitted whenever an option from the list is selected. */
699
1029
  this.optionSelected = output();
700
1030
  /** Event that is emitted when the autocomplete panel is opened. */
701
1031
  this.opened = output();
702
1032
  /** Event that is emitted when the autocomplete panel is closed. */
703
1033
  this.closed = output();
704
- this._classList = {};
705
- this._isOpen = false;
706
- this._openOnFocus = true;
707
- const defaults = inject(KBQ_AUTOCOMPLETE_DEFAULT_OPTIONS);
708
- this._autoActiveFirstOption = !!defaults.autoActiveFirstOption;
1034
+ /**
1035
+ * Classes set on the host `kbq-autocomplete` element. They are applied to the panel inside the
1036
+ * overlay container instead, to allow for easy styling.
1037
+ *
1038
+ * Accepts every shape Angular's own `[class]` binding does. The binding value arrives here raw:
1039
+ * Angular converts it to a string before handing it to a styling-shadowing input only when the element
1040
+ * carries a static `class` attribute, which `<kbq-autocomplete>` does not.
1041
+ */
1042
+ this.hostClass = input('', { ...(ngDevMode ? { debugName: "hostClass" } : /* istanbul ignore next */ {}), alias: 'class', transform: normalizeClassInput });
1043
+ /**
1044
+ * Whether the first option should be highlighted when the autocomplete panel is opened.
1045
+ * Can be configured globally through the `KBQ_AUTOCOMPLETE_DEFAULT_OPTIONS` token.
1046
+ */
1047
+ this.autoActiveFirstOption = input(!!this.defaultOptions.autoActiveFirstOption, { ...(ngDevMode ? { debugName: "autoActiveFirstOption" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1048
+ /** Whether the panel opens as soon as the trigger receives focus. */
1049
+ this.openOnFocus = input(true, { ...(ngDevMode ? { debugName: "openOnFocus" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1050
+ /**
1051
+ * Whether the trigger has attached the panel overlay. It is not the same thing as the panel being
1052
+ * visible — see `isOpen`.
1053
+ *
1054
+ * @docs-private
1055
+ */
1056
+ this.attached = signal(false, ...(ngDevMode ? [{ debugName: "attached" }] : /* istanbul ignore next */ []));
1057
+ /**
1058
+ * Accessible name of the option list: the ids of the elements that name it, or the name itself. The trigger
1059
+ * copies it from its field on attaching the panel, so the list is announced under the field's name.
1060
+ *
1061
+ * @docs-private
1062
+ */
1063
+ this.listboxName = signal({
1064
+ labelledby: null,
1065
+ label: null
1066
+ }, ...(ngDevMode ? [{ debugName: "listboxName" }] : /* istanbul ignore next */ []));
1067
+ /** Whether the panel is visible: attached by the trigger and holding at least one option. */
1068
+ this.isOpen = computed(() => this.attached() && this.showPanel(), ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
1069
+ /** Whether the trigger's form field currently holds keyboard focus. */
1070
+ this.keyboardFocused = signal(false, ...(ngDevMode ? [{ debugName: "keyboardFocused" }] : /* istanbul ignore next */ []));
1071
+ /** @docs-private */
1072
+ this.classList = computed(() => ({
1073
+ ...Object.fromEntries(this.hostClass()
1074
+ .split(' ')
1075
+ .map((className) => className.trim())
1076
+ .filter(Boolean)
1077
+ .map((className) => [className, true])),
1078
+ 'kbq-autocomplete_visible': this.showPanel(),
1079
+ 'kbq-autocomplete_hidden': !this.showPanel(),
1080
+ 'cdk-keyboard-focused': this.keyboardFocused()
1081
+ }), ...(ngDevMode ? [{ debugName: "classList" }] : /* istanbul ignore next */ []));
1082
+ // The host is `display: none` and only carries the template portal, so the classes written on it
1083
+ // belong to the panel inside the overlay. Move them off the host once they have been read.
1084
+ effect(() => {
1085
+ if (this.hostClass()) {
1086
+ this.nativeElement.className = '';
1087
+ }
1088
+ });
1089
+ outputToObservable(this.opened)
1090
+ .pipe(takeUntilDestroyed())
1091
+ .subscribe(() => this.scrollbarViewport()?.flashScrollIndicators());
709
1092
  }
710
1093
  ngAfterContentInit() {
711
1094
  this.keyManager = new ActiveDescendantKeyManager(this.options);
@@ -717,51 +1100,47 @@ class KbqAutocomplete {
717
1100
  this.options.filter(({ selected }) => selected).forEach((option) => option.deselect(false));
718
1101
  });
719
1102
  }
1103
+ ngAfterContentChecked() {
1104
+ // Syncs the list here so `changes` emits after the projected items are bound and before the host bindings.
1105
+ this.optionsList();
1106
+ }
1107
+ /** @docs-private */
720
1108
  setScrollTop(scrollTop) {
721
- const panel = this.panel();
722
- if (panel) {
723
- panel.nativeElement.scrollTop = scrollTop;
724
- }
1109
+ this.scrollbarViewport()?.scrollTo({ top: scrollTop });
725
1110
  }
1111
+ /** @docs-private */
726
1112
  getScrollTop() {
727
- const panel = this.panel();
728
- return panel ? panel.nativeElement.scrollTop : 0;
1113
+ return this.scrollbarViewport()?.getNativeElement().scrollTop ?? 0;
729
1114
  }
1115
+ /** @docs-private */
730
1116
  setVisibility() {
731
- this.showPanel = !!this.options.length;
732
- this._classList = {
733
- ...this._classList,
734
- 'kbq-autocomplete_visible': this.showPanel,
735
- 'kbq-autocomplete_hidden': !this.showPanel
736
- };
1117
+ this.showPanel.set(!!this.options.length);
737
1118
  this.updateFocusClass();
738
- this.changeDetectorRef.markForCheck();
739
1119
  }
1120
+ /** @docs-private */
740
1121
  emitSelectEvent(option) {
741
1122
  const event = new KbqAutocompleteSelectedEvent(this, option);
742
1123
  this.optionSelected.emit(event);
743
1124
  }
1125
+ /** @docs-private */
744
1126
  onKeydown(event) {
745
1127
  this.keyManager.onKeydown(event);
746
1128
  this.updateFocusClass();
747
1129
  }
748
1130
  updateFocusClass() {
749
- this._classList = {
750
- ...this._classList,
751
- 'cdk-keyboard-focused': this.parentFormField?.focusOrigin === 'keyboard'
752
- };
1131
+ this.keyboardFocused.set(this.parentFormField?.focusOrigin === 'keyboard');
753
1132
  }
754
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqAutocomplete, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
755
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "20.3.30", type: KbqAutocomplete, isStandalone: true, selector: "kbq-autocomplete", inputs: { displayWith: { classPropertyName: "displayWith", publicName: "displayWith", 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 }, classList: { classPropertyName: "classList", publicName: "class", isSignal: false, isRequired: false, transformFunction: null }, autoActiveFirstOption: { classPropertyName: "autoActiveFirstOption", publicName: "autoActiveFirstOption", isSignal: false, isRequired: false, transformFunction: null }, openOnFocus: { classPropertyName: "openOnFocus", publicName: "openOnFocus", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { optionSelected: "optionSelected", opened: "opened", closed: "closed" }, host: { styleAttribute: "display: none", classAttribute: "kbq-autocomplete" }, providers: [
1133
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqAutocomplete, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1134
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.25", type: KbqAutocomplete, isStandalone: true, selector: "kbq-autocomplete", inputs: { displayWith: { classPropertyName: "displayWith", publicName: "displayWith", 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 }, hostClass: { classPropertyName: "hostClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, autoActiveFirstOption: { classPropertyName: "autoActiveFirstOption", publicName: "autoActiveFirstOption", isSignal: true, isRequired: false, transformFunction: null }, openOnFocus: { classPropertyName: "openOnFocus", publicName: "openOnFocus", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { optionSelected: "optionSelected", opened: "opened", closed: "closed" }, host: { styleAttribute: "display: none", classAttribute: "kbq-autocomplete" }, providers: [
756
1135
  {
757
1136
  provide: KBQ_OPTION_PARENT_COMPONENT,
758
1137
  useExisting: KbqAutocomplete
759
1138
  }
760
- ], queries: [{ propertyName: "optionGroups", predicate: KbqOptgroup, isSignal: true }, { propertyName: "options", predicate: KbqOption, descendants: true }], viewQueries: [{ propertyName: "template", first: true, predicate: TemplateRef, descendants: true, isSignal: true }, { propertyName: "panel", first: true, predicate: ["panel"], descendants: true, isSignal: true }], exportAs: ["kbqAutocomplete"], ngImport: i0, template: "<ng-template>\n <div class=\"kbq-autocomplete-panel\" [id]=\"id\" [class]=\"classList\" [style.max-width.px]=\"panelMaxWidth()\">\n <div #panel role=\"listbox\" class=\"kbq-autocomplete-panel__content kbq-scrollbar\">\n <ng-content />\n </div>\n <ng-content select=\"[kbqAutocompleteFooter], kbq-autocomplete-footer\" />\n </div>\n</ng-template>\n", styles: [".kbq-autocomplete-panel .kbq-autocomplete-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-autocomplete-panel{visibility:hidden;position:relative;display:flex;flex-direction:column;box-sizing:border-box;min-width:100%;width:100%;max-width:var(--kbq-panel-size-width-max, 640px);border-radius:var(--kbq-autocomplete-size-panel-border-radius, var(--kbq-size-border-radius));max-height:var(--kbq-autocomplete-size-panel-max-height)}.kbq-autocomplete-panel .kbq-autocomplete-panel__content{flex:1;padding:var(--kbq-size-xxs);overflow-x:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch}.kbq-autocomplete-panel .kbq-autocomplete-footer{border-color:var(--kbq-line-contrast-less)}.kbq-autocomplete-panel.kbq-autocomplete_visible{visibility:visible}.kbq-autocomplete-panel.kbq-autocomplete_hidden{visibility:hidden}.kbq-autocomplete-panel .kbq-option{position:relative}.kbq-autocomplete-panel .kbq-option:before,.kbq-autocomplete-panel .kbq-option:after{position:absolute;content:\"\";width:var(--kbq-size-xxs);height:calc(100% + var(--kbq-size-3xs) * 2)}.kbq-autocomplete-panel .kbq-option:before{right:calc(100% + var(--kbq-size-3xs))}.kbq-autocomplete-panel .kbq-option:after{left:calc(100% + var(--kbq-size-3xs))}.kbq-autocomplete-panel .kbq-divider-horizontal{margin-top:-1px}.kbq-autocomplete-panel{box-shadow:var(--kbq-select-panel-dropdown-shadow);background:var(--kbq-select-panel-dropdown-background)}\n", ".kbq-autocomplete-panel{--kbq-autocomplete-size-panel-padding: var(--kbq-size-xxs) 0;--kbq-autocomplete-size-panel-max-height: 256px;--kbq-autocomplete-size-panel-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"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1139
+ ], queries: [{ propertyName: "optionsQuery", predicate: KbqOption, descendants: true, isSignal: true }, { propertyName: "optionGroups", predicate: KbqOptgroup, isSignal: true }], viewQueries: [{ propertyName: "template", first: true, predicate: TemplateRef, descendants: true, isSignal: true }, { propertyName: "panel", first: true, predicate: ["panel"], descendants: true, isSignal: true }, { propertyName: "scrollbarViewport", first: true, predicate: KbqScrollbarViewport, descendants: true, isSignal: true }], exportAs: ["kbqAutocomplete"], ngImport: i0, template: "<ng-template>\n <div class=\"kbq-autocomplete-panel\" [id]=\"id\" [class]=\"classList()\" [style.max-width.px]=\"panelMaxWidth()\">\n <div #panel kbqScrollbarViewport class=\"kbq-autocomplete-panel__content\">\n <!-- Keep the injected scrollbar outside the listbox's permitted option/group children. -->\n <div\n role=\"listbox\"\n class=\"kbq-autocomplete-panel__listbox\"\n [id]=\"listboxId\"\n [attr.aria-labelledby]=\"listboxName().labelledby\"\n [attr.aria-label]=\"listboxName().label\"\n >\n <ng-content />\n </div>\n </div>\n <ng-content select=\"[kbqAutocompleteFooter], kbq-autocomplete-footer\" />\n </div>\n</ng-template>\n", styles: [".kbq-autocomplete-panel .kbq-autocomplete-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-autocomplete-panel{visibility:hidden;position:relative;display:flex;flex-direction:column;box-sizing:border-box;min-width:100%;width:100%;max-width:var(--kbq-panel-size-width-max, 640px);border-radius:var(--kbq-autocomplete-size-panel-border-radius, var(--kbq-size-border-radius))}@supports (corner-shape: squircle){.kbq-autocomplete-panel{corner-shape:squircle;border-radius:clamp(var(--kbq-autocomplete-size-panel-border-radius, var(--kbq-size-border-radius)) * 1.85,var(--kbq-autocomplete-size-panel-border-radius, var(--kbq-size-border-radius)) * 2.3 - 3.6px,var(--kbq-autocomplete-size-panel-border-radius, var(--kbq-size-border-radius)) * 2)}}.kbq-autocomplete-panel{max-height:var(--kbq-autocomplete-size-panel-max-height)}.kbq-autocomplete-panel .kbq-autocomplete-panel__content{flex:1;padding:var(--kbq-size-xxs);overflow-x:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch}.kbq-autocomplete-panel .kbq-autocomplete-footer{border-color:var(--kbq-line-contrast-less)}.kbq-autocomplete-panel.kbq-autocomplete_visible{visibility:visible}.kbq-autocomplete-panel.kbq-autocomplete_hidden{visibility:hidden}.kbq-autocomplete-panel .kbq-option{position:relative}.kbq-autocomplete-panel .kbq-option:before,.kbq-autocomplete-panel .kbq-option:after{position:absolute;content:\"\";width:var(--kbq-size-xxs);height:calc(100% + var(--kbq-size-3xs) * 2)}.kbq-autocomplete-panel .kbq-option:before{right:calc(100% + var(--kbq-size-3xs))}.kbq-autocomplete-panel .kbq-option:after{left:calc(100% + var(--kbq-size-3xs))}.kbq-autocomplete-inline-hint__hint{color:var(--kbq-form-field-default-placeholder)}.kbq-autocomplete-panel{box-shadow:var(--kbq-select-panel-dropdown-shadow);background:var(--kbq-select-panel-dropdown-background)}\n", ".kbq-autocomplete-panel{--kbq-autocomplete-size-panel-padding: var(--kbq-size-xxs) 0;--kbq-autocomplete-size-panel-max-height: 256px;--kbq-autocomplete-size-panel-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: KbqScrollbarViewport, selector: "[kbqScrollbarViewport]", inputs: ["kbqScrollbarMode", "kbqScrollbarHideDelay"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
761
1140
  }
762
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqAutocomplete, decorators: [{
1141
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqAutocomplete, decorators: [{
763
1142
  type: Component,
764
- args: [{ selector: 'kbq-autocomplete', imports: [], providers: [
1143
+ args: [{ selector: 'kbq-autocomplete', imports: [KbqScrollbarViewport], providers: [
765
1144
  {
766
1145
  provide: KBQ_OPTION_PARENT_COMPONENT,
767
1146
  useExisting: KbqAutocomplete
@@ -771,24 +1150,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
771
1150
  // Remove the empty TemplatePortal host from layout entirely — it would otherwise contribute an
772
1151
  // inline box in normal flow, or a phantom item in a flex/grid container.
773
1152
  style: 'display: none'
774
- }, exportAs: 'kbqAutocomplete', template: "<ng-template>\n <div class=\"kbq-autocomplete-panel\" [id]=\"id\" [class]=\"classList\" [style.max-width.px]=\"panelMaxWidth()\">\n <div #panel role=\"listbox\" class=\"kbq-autocomplete-panel__content kbq-scrollbar\">\n <ng-content />\n </div>\n <ng-content select=\"[kbqAutocompleteFooter], kbq-autocomplete-footer\" />\n </div>\n</ng-template>\n", styles: [".kbq-autocomplete-panel .kbq-autocomplete-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-autocomplete-panel{visibility:hidden;position:relative;display:flex;flex-direction:column;box-sizing:border-box;min-width:100%;width:100%;max-width:var(--kbq-panel-size-width-max, 640px);border-radius:var(--kbq-autocomplete-size-panel-border-radius, var(--kbq-size-border-radius));max-height:var(--kbq-autocomplete-size-panel-max-height)}.kbq-autocomplete-panel .kbq-autocomplete-panel__content{flex:1;padding:var(--kbq-size-xxs);overflow-x:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch}.kbq-autocomplete-panel .kbq-autocomplete-footer{border-color:var(--kbq-line-contrast-less)}.kbq-autocomplete-panel.kbq-autocomplete_visible{visibility:visible}.kbq-autocomplete-panel.kbq-autocomplete_hidden{visibility:hidden}.kbq-autocomplete-panel .kbq-option{position:relative}.kbq-autocomplete-panel .kbq-option:before,.kbq-autocomplete-panel .kbq-option:after{position:absolute;content:\"\";width:var(--kbq-size-xxs);height:calc(100% + var(--kbq-size-3xs) * 2)}.kbq-autocomplete-panel .kbq-option:before{right:calc(100% + var(--kbq-size-3xs))}.kbq-autocomplete-panel .kbq-option:after{left:calc(100% + var(--kbq-size-3xs))}.kbq-autocomplete-panel .kbq-divider-horizontal{margin-top:-1px}.kbq-autocomplete-panel{box-shadow:var(--kbq-select-panel-dropdown-shadow);background:var(--kbq-select-panel-dropdown-background)}\n", ".kbq-autocomplete-panel{--kbq-autocomplete-size-panel-padding: var(--kbq-size-xxs) 0;--kbq-autocomplete-size-panel-max-height: 256px;--kbq-autocomplete-size-panel-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"] }]
775
- }], ctorParameters: () => [], propDecorators: { template: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }], panel: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }], options: [{
776
- type: ContentChildren,
777
- args: [KbqOption, { descendants: true }]
778
- }], optionGroups: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => KbqOptgroup), { isSignal: true }] }], displayWith: [{
779
- type: Input
780
- }], 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 }] }], optionSelected: [{ type: i0.Output, args: ["optionSelected"] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], classList: [{
781
- type: Input,
782
- args: ['class']
783
- }], autoActiveFirstOption: [{
784
- type: Input
785
- }], openOnFocus: [{
786
- type: Input
787
- }] } });
1153
+ }, exportAs: 'kbqAutocomplete', template: "<ng-template>\n <div class=\"kbq-autocomplete-panel\" [id]=\"id\" [class]=\"classList()\" [style.max-width.px]=\"panelMaxWidth()\">\n <div #panel kbqScrollbarViewport class=\"kbq-autocomplete-panel__content\">\n <!-- Keep the injected scrollbar outside the listbox's permitted option/group children. -->\n <div\n role=\"listbox\"\n class=\"kbq-autocomplete-panel__listbox\"\n [id]=\"listboxId\"\n [attr.aria-labelledby]=\"listboxName().labelledby\"\n [attr.aria-label]=\"listboxName().label\"\n >\n <ng-content />\n </div>\n </div>\n <ng-content select=\"[kbqAutocompleteFooter], kbq-autocomplete-footer\" />\n </div>\n</ng-template>\n", styles: [".kbq-autocomplete-panel .kbq-autocomplete-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-autocomplete-panel{visibility:hidden;position:relative;display:flex;flex-direction:column;box-sizing:border-box;min-width:100%;width:100%;max-width:var(--kbq-panel-size-width-max, 640px);border-radius:var(--kbq-autocomplete-size-panel-border-radius, var(--kbq-size-border-radius))}@supports (corner-shape: squircle){.kbq-autocomplete-panel{corner-shape:squircle;border-radius:clamp(var(--kbq-autocomplete-size-panel-border-radius, var(--kbq-size-border-radius)) * 1.85,var(--kbq-autocomplete-size-panel-border-radius, var(--kbq-size-border-radius)) * 2.3 - 3.6px,var(--kbq-autocomplete-size-panel-border-radius, var(--kbq-size-border-radius)) * 2)}}.kbq-autocomplete-panel{max-height:var(--kbq-autocomplete-size-panel-max-height)}.kbq-autocomplete-panel .kbq-autocomplete-panel__content{flex:1;padding:var(--kbq-size-xxs);overflow-x:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch}.kbq-autocomplete-panel .kbq-autocomplete-footer{border-color:var(--kbq-line-contrast-less)}.kbq-autocomplete-panel.kbq-autocomplete_visible{visibility:visible}.kbq-autocomplete-panel.kbq-autocomplete_hidden{visibility:hidden}.kbq-autocomplete-panel .kbq-option{position:relative}.kbq-autocomplete-panel .kbq-option:before,.kbq-autocomplete-panel .kbq-option:after{position:absolute;content:\"\";width:var(--kbq-size-xxs);height:calc(100% + var(--kbq-size-3xs) * 2)}.kbq-autocomplete-panel .kbq-option:before{right:calc(100% + var(--kbq-size-3xs))}.kbq-autocomplete-panel .kbq-option:after{left:calc(100% + var(--kbq-size-3xs))}.kbq-autocomplete-inline-hint__hint{color:var(--kbq-form-field-default-placeholder)}.kbq-autocomplete-panel{box-shadow:var(--kbq-select-panel-dropdown-shadow);background:var(--kbq-select-panel-dropdown-background)}\n", ".kbq-autocomplete-panel{--kbq-autocomplete-size-panel-padding: var(--kbq-size-xxs) 0;--kbq-autocomplete-size-panel-max-height: 256px;--kbq-autocomplete-size-panel-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"] }]
1154
+ }], ctorParameters: () => [], propDecorators: { template: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TemplateRef), { isSignal: true }] }], panel: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }], scrollbarViewport: [{ type: i0.ViewChild, args: [i0.forwardRef(() => KbqScrollbarViewport), { isSignal: true }] }], optionsQuery: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => KbqOption), { ...{ descendants: true }, isSignal: true }] }], optionGroups: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => KbqOptgroup), { isSignal: true }] }], displayWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayWith", 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 }] }], optionSelected: [{ type: i0.Output, args: ["optionSelected"] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], hostClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], autoActiveFirstOption: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoActiveFirstOption", required: false }] }], openOnFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "openOnFocus", required: false }] }] } });
788
1155
 
789
1156
  class KbqAutocompleteModule {
790
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqAutocompleteModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
791
- /** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.30", ngImport: i0, type: KbqAutocompleteModule, imports: [KbqOptionModule,
1157
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqAutocompleteModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1158
+ /** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.25", ngImport: i0, type: KbqAutocompleteModule, imports: [KbqOptionModule,
792
1159
  OverlayModule,
793
1160
  KbqAutocomplete,
794
1161
  KbqAutocompleteTrigger,
@@ -798,10 +1165,10 @@ class KbqAutocompleteModule {
798
1165
  KbqAutocompleteTrigger,
799
1166
  KbqAutocompleteOrigin,
800
1167
  KbqAutocompleteFooter] }); }
801
- /** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqAutocompleteModule, imports: [KbqOptionModule,
1168
+ /** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqAutocompleteModule, imports: [KbqOptionModule,
802
1169
  OverlayModule, KbqOptionModule] }); }
803
1170
  }
804
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqAutocompleteModule, decorators: [{
1171
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.25", ngImport: i0, type: KbqAutocompleteModule, decorators: [{
805
1172
  type: NgModule,
806
1173
  args: [{
807
1174
  imports: [
@@ -826,5 +1193,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImpo
826
1193
  * Generated bundle index. Do not edit.
827
1194
  */
828
1195
 
829
- export { AUTOCOMPLETE_PANEL_HEIGHT, KBQ_AUTOCOMPLETE_DEFAULT_OPTIONS, KBQ_AUTOCOMPLETE_DEFAULT_OPTIONS_FACTORY, KBQ_AUTOCOMPLETE_SCROLL_STRATEGY, KBQ_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY, KBQ_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY_PROVIDER, KBQ_AUTOCOMPLETE_VALUE_ACCESSOR, KbqAutocomplete, KbqAutocompleteFooter, KbqAutocompleteModule, KbqAutocompleteOrigin, KbqAutocompleteSelectedEvent, KbqAutocompleteTrigger, getKbqAutocompleteMissingPanelError };
1196
+ export { KBQ_AUTOCOMPLETE_DEFAULT_OPTIONS, KBQ_AUTOCOMPLETE_DEFAULT_OPTIONS_FACTORY, KBQ_AUTOCOMPLETE_SCROLL_STRATEGY, KBQ_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY, KBQ_AUTOCOMPLETE_SCROLL_STRATEGY_FACTORY_PROVIDER, KBQ_AUTOCOMPLETE_VALUE_ACCESSOR, KbqAutocomplete, KbqAutocompleteFooter, KbqAutocompleteModule, KbqAutocompleteOrigin, KbqAutocompleteSelectedEvent, KbqAutocompleteTrigger, getKbqAutocompleteMissingPanelError };
830
1197
  //# sourceMappingURL=koobiq-components-autocomplete.mjs.map