@koobiq/components 20.1.0 → 20.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/accordion/_accordion-theme.scss +6 -2
  2. package/accordion/accordion-tokens.scss +3 -0
  3. package/accordion/{accordion-trigger.component.scss → accordion-trigger.scss} +10 -0
  4. package/accordion/accordion.scss +71 -0
  5. package/accordion/index.d.ts +264 -121
  6. package/actions-panel/index.d.ts +25 -13
  7. package/alert/_alert-theme.scss +14 -0
  8. package/alert/alert.component.scss +24 -13
  9. package/alert/index.d.ts +63 -29
  10. package/app-switcher/app-switcher-dropdown-app.scss +7 -5
  11. package/app-switcher/app-switcher-dropdown-site.scss +6 -4
  12. package/app-switcher/index.d.ts +41 -4
  13. package/app-switcher/kbq-app-switcher-list-item.scss +6 -8
  14. package/autocomplete/autocomplete.scss +2 -1
  15. package/autocomplete/index.d.ts +58 -37
  16. package/badge/index.d.ts +2 -3
  17. package/breadcrumbs/index.d.ts +1 -1
  18. package/button/index.d.ts +2 -2
  19. package/button-toggle/button-toggle-tokens.scss +2 -0
  20. package/button-toggle/button-toggle.scss +9 -0
  21. package/button-toggle/index.d.ts +5 -0
  22. package/checkbox/index.d.ts +33 -29
  23. package/clamped-text/index.d.ts +3 -2
  24. package/code-block/index.d.ts +24 -19
  25. package/content-panel/index.d.ts +1 -1
  26. package/core/index.d.ts +1217 -186
  27. package/core/option/_action-container-mixins.scss +28 -0
  28. package/core/option/_option-theme.scss +24 -0
  29. package/core/option/action.scss +7 -0
  30. package/core/styles/_core.scss +2 -0
  31. package/core/styles/_koobiq-theme.scss +2 -0
  32. package/core/styles/_tokens.scss +1 -0
  33. package/core/styles/common/_animation.scss +31 -24
  34. package/core/styles/common/_connected-overlay.scss +39 -0
  35. package/core/styles/common/_select.scss +19 -2
  36. package/core/styles/common/_tokens.scss +0 -9
  37. package/core/styles/theming/_index.scss +0 -1
  38. package/core/styles/theming/_theming.scss +34 -5
  39. package/datepicker/index.d.ts +46 -15
  40. package/dl/dl.scss +26 -0
  41. package/dl/index.d.ts +8 -1
  42. package/dropdown/_dropdown-theme.scss +28 -2
  43. package/dropdown/dropdown-item.scss +29 -0
  44. package/dropdown/dropdown-tokens.scss +2 -1
  45. package/dropdown/dropdown.scss +16 -1
  46. package/dropdown/index.d.ts +331 -17
  47. package/dynamic-translation/index.d.ts +1 -1
  48. package/fesm2022/koobiq-components-accordion.mjs +480 -317
  49. package/fesm2022/koobiq-components-accordion.mjs.map +1 -1
  50. package/fesm2022/koobiq-components-actions-panel.mjs +57 -46
  51. package/fesm2022/koobiq-components-actions-panel.mjs.map +1 -1
  52. package/fesm2022/koobiq-components-alert.mjs +98 -58
  53. package/fesm2022/koobiq-components-alert.mjs.map +1 -1
  54. package/fesm2022/koobiq-components-app-switcher.mjs +233 -38
  55. package/fesm2022/koobiq-components-app-switcher.mjs.map +1 -1
  56. package/fesm2022/koobiq-components-autocomplete.mjs +89 -52
  57. package/fesm2022/koobiq-components-autocomplete.mjs.map +1 -1
  58. package/fesm2022/koobiq-components-badge.mjs +18 -17
  59. package/fesm2022/koobiq-components-badge.mjs.map +1 -1
  60. package/fesm2022/koobiq-components-breadcrumbs.mjs +25 -25
  61. package/fesm2022/koobiq-components-breadcrumbs.mjs.map +1 -1
  62. package/fesm2022/koobiq-components-button-toggle.mjs +17 -12
  63. package/fesm2022/koobiq-components-button-toggle.mjs.map +1 -1
  64. package/fesm2022/koobiq-components-button.mjs +25 -25
  65. package/fesm2022/koobiq-components-checkbox.mjs +69 -92
  66. package/fesm2022/koobiq-components-checkbox.mjs.map +1 -1
  67. package/fesm2022/koobiq-components-clamped-text.mjs +18 -13
  68. package/fesm2022/koobiq-components-clamped-text.mjs.map +1 -1
  69. package/fesm2022/koobiq-components-code-block.mjs +56 -69
  70. package/fesm2022/koobiq-components-code-block.mjs.map +1 -1
  71. package/fesm2022/koobiq-components-content-panel.mjs +29 -29
  72. package/fesm2022/koobiq-components-core.mjs +2485 -735
  73. package/fesm2022/koobiq-components-core.mjs.map +1 -1
  74. package/fesm2022/koobiq-components-datepicker.mjs +168 -126
  75. package/fesm2022/koobiq-components-datepicker.mjs.map +1 -1
  76. package/fesm2022/koobiq-components-divider.mjs +7 -7
  77. package/fesm2022/koobiq-components-dl.mjs +23 -15
  78. package/fesm2022/koobiq-components-dl.mjs.map +1 -1
  79. package/fesm2022/koobiq-components-dropdown.mjs +814 -136
  80. package/fesm2022/koobiq-components-dropdown.mjs.map +1 -1
  81. package/fesm2022/koobiq-components-dynamic-translation.mjs +13 -13
  82. package/fesm2022/koobiq-components-ellipsis-center.mjs +7 -7
  83. package/fesm2022/koobiq-components-empty-state.mjs +19 -19
  84. package/fesm2022/koobiq-components-file-upload.mjs +74 -42
  85. package/fesm2022/koobiq-components-file-upload.mjs.map +1 -1
  86. package/fesm2022/koobiq-components-filter-bar.mjs +783 -199
  87. package/fesm2022/koobiq-components-filter-bar.mjs.map +1 -1
  88. package/fesm2022/koobiq-components-flag.mjs +7 -7
  89. package/fesm2022/koobiq-components-form-field.mjs +350 -162
  90. package/fesm2022/koobiq-components-form-field.mjs.map +1 -1
  91. package/fesm2022/koobiq-components-icon.mjs +52 -25
  92. package/fesm2022/koobiq-components-icon.mjs.map +1 -1
  93. package/fesm2022/koobiq-components-inline-edit.mjs +175 -28
  94. package/fesm2022/koobiq-components-inline-edit.mjs.map +1 -1
  95. package/fesm2022/koobiq-components-input.mjs +41 -24
  96. package/fesm2022/koobiq-components-input.mjs.map +1 -1
  97. package/fesm2022/koobiq-components-link.mjs +8 -8
  98. package/fesm2022/koobiq-components-list.mjs +657 -143
  99. package/fesm2022/koobiq-components-list.mjs.map +1 -1
  100. package/fesm2022/koobiq-components-loader-overlay.mjs +16 -16
  101. package/fesm2022/koobiq-components-markdown.mjs +14 -11
  102. package/fesm2022/koobiq-components-markdown.mjs.map +1 -1
  103. package/fesm2022/koobiq-components-modal.mjs +59 -35
  104. package/fesm2022/koobiq-components-modal.mjs.map +1 -1
  105. package/fesm2022/koobiq-components-navbar.mjs +177 -67
  106. package/fesm2022/koobiq-components-navbar.mjs.map +1 -1
  107. package/fesm2022/koobiq-components-notification-center.mjs +40 -24
  108. package/fesm2022/koobiq-components-notification-center.mjs.map +1 -1
  109. package/fesm2022/koobiq-components-overflow-items.mjs +16 -17
  110. package/fesm2022/koobiq-components-overflow-items.mjs.map +1 -1
  111. package/fesm2022/koobiq-components-popover.mjs +31 -21
  112. package/fesm2022/koobiq-components-popover.mjs.map +1 -1
  113. package/fesm2022/koobiq-components-progress-bar.mjs +13 -13
  114. package/fesm2022/koobiq-components-progress-spinner.mjs +13 -13
  115. package/fesm2022/koobiq-components-radio.mjs +10 -10
  116. package/fesm2022/koobiq-components-resizer.mjs +33 -14
  117. package/fesm2022/koobiq-components-resizer.mjs.map +1 -1
  118. package/fesm2022/koobiq-components-scrollbar.mjs +10 -10
  119. package/fesm2022/koobiq-components-search-expandable.mjs +49 -14
  120. package/fesm2022/koobiq-components-search-expandable.mjs.map +1 -1
  121. package/fesm2022/koobiq-components-select.mjs +450 -146
  122. package/fesm2022/koobiq-components-select.mjs.map +1 -1
  123. package/fesm2022/koobiq-components-sidebar.mjs +14 -14
  124. package/fesm2022/koobiq-components-sidepanel.mjs +26 -26
  125. package/fesm2022/koobiq-components-skeleton.mjs +10 -10
  126. package/fesm2022/koobiq-components-split-button.mjs +10 -17
  127. package/fesm2022/koobiq-components-split-button.mjs.map +1 -1
  128. package/fesm2022/koobiq-components-splitter.mjs +17 -17
  129. package/fesm2022/koobiq-components-table.mjs +15 -13
  130. package/fesm2022/koobiq-components-table.mjs.map +1 -1
  131. package/fesm2022/koobiq-components-tabs.mjs +80 -68
  132. package/fesm2022/koobiq-components-tabs.mjs.map +1 -1
  133. package/fesm2022/koobiq-components-tags.mjs +283 -122
  134. package/fesm2022/koobiq-components-tags.mjs.map +1 -1
  135. package/fesm2022/koobiq-components-textarea.mjs +13 -8
  136. package/fesm2022/koobiq-components-textarea.mjs.map +1 -1
  137. package/fesm2022/koobiq-components-time-range.mjs +29 -24
  138. package/fesm2022/koobiq-components-time-range.mjs.map +1 -1
  139. package/fesm2022/koobiq-components-timepicker.mjs +61 -30
  140. package/fesm2022/koobiq-components-timepicker.mjs.map +1 -1
  141. package/fesm2022/koobiq-components-timezone.mjs +77 -42
  142. package/fesm2022/koobiq-components-timezone.mjs.map +1 -1
  143. package/fesm2022/koobiq-components-title.mjs +7 -7
  144. package/fesm2022/koobiq-components-toast.mjs +51 -26
  145. package/fesm2022/koobiq-components-toast.mjs.map +1 -1
  146. package/fesm2022/koobiq-components-toggle.mjs +72 -64
  147. package/fesm2022/koobiq-components-toggle.mjs.map +1 -1
  148. package/fesm2022/koobiq-components-tooltip.mjs +219 -28
  149. package/fesm2022/koobiq-components-tooltip.mjs.map +1 -1
  150. package/fesm2022/koobiq-components-top-bar.mjs +13 -13
  151. package/fesm2022/koobiq-components-tree-select.mjs +222 -80
  152. package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
  153. package/fesm2022/koobiq-components-tree.mjs +302 -81
  154. package/fesm2022/koobiq-components-tree.mjs.map +1 -1
  155. package/fesm2022/koobiq-components-username.mjs +27 -27
  156. package/file-upload/index.d.ts +25 -6
  157. package/file-upload/multiple-file-upload.component.scss +14 -0
  158. package/filter-bar/_filter-bar-theme.scss +0 -10
  159. package/filter-bar/filter-bar-tokens.scss +3 -0
  160. package/filter-bar/filters.scss +3 -2
  161. package/filter-bar/index.d.ts +281 -9
  162. package/filter-bar/pipes/base-pipe.scss +0 -11
  163. package/filter-bar/pipes/pipe-input.scss +10 -0
  164. package/filter-bar/pipes/pipe-multi-tree-select.scss +0 -6
  165. package/filter-bar/pipes/pipe-multiselect.scss +0 -6
  166. package/filter-bar/pipes/pipe-tree-select.scss +0 -6
  167. package/form-field/_form-field-theme.scss +76 -20
  168. package/form-field/fieldset.scss +10 -0
  169. package/form-field/form-field-tokens.scss +15 -1
  170. package/form-field/form-field.scss +15 -19
  171. package/form-field/index.d.ts +147 -65
  172. package/icon/icon-button.scss +3 -1
  173. package/icon/index.d.ts +45 -7
  174. package/inline-edit/index.d.ts +57 -4
  175. package/inline-edit/inline-edit.scss +10 -0
  176. package/input/index.d.ts +17 -2
  177. package/list/_list-theme.scss +42 -10
  178. package/list/index.d.ts +326 -79
  179. package/list/list-tokens.scss +43 -8
  180. package/list/list.scss +186 -12
  181. package/markdown/index.d.ts +1 -1
  182. package/modal/index.d.ts +21 -4
  183. package/modal/modal-tokens.scss +1 -1
  184. package/navbar/_navbar-item_vertical.scss +7 -5
  185. package/navbar/index.d.ts +54 -5
  186. package/navbar/navbar-brand.scss +23 -7
  187. package/navbar/vertical-navbar.scss +6 -0
  188. package/notification-center/index.d.ts +2 -1
  189. package/notification-center/notification-item.scss +6 -0
  190. package/package.json +3 -6
  191. package/popover/index.d.ts +2 -2
  192. package/prebuilt-themes/dark-theme.css +1 -1
  193. package/prebuilt-themes/light-theme.css +1 -1
  194. package/prebuilt-themes/theme.css +1 -1
  195. package/resizer/index.d.ts +12 -0
  196. package/schematics/collection.json +10 -0
  197. package/schematics/migrations/alert-signals/README.md +64 -0
  198. package/schematics/migrations/alert-signals/data.js +70 -0
  199. package/schematics/migrations/alert-signals/index.js +350 -0
  200. package/schematics/migrations/alert-signals/schema.json +20 -0
  201. package/schematics/migrations/autocomplete-panel-width-auto/README.md +68 -0
  202. package/schematics/migrations/autocomplete-panel-width-auto/index.js +70 -0
  203. package/schematics/migrations/autocomplete-panel-width-auto/schema.json +15 -0
  204. package/schematics/migrations/deprecated-icons/README.md +29 -4
  205. package/schematics/migrations/deprecated-icons/data.js +7 -0
  206. package/schematics/migrations/deprecated-icons/index.js +62 -35
  207. package/schematics/migrations/filter-bar-signals/README.md +1 -1
  208. package/schematics/migrations/new-icons-pack/README.md +37 -2
  209. package/schematics/migrations/new-icons-pack/data.js +8 -0
  210. package/schematics/migrations/new-icons-pack/index.js +144 -53
  211. package/schematics/migrations.json +11 -1
  212. package/schematics/ng-add/index.js +3 -3
  213. package/schematics/utils/angular-parsing.js +41 -14
  214. package/schematics/utils/ast.js +31 -0
  215. package/schematics/utils/icon-migration.js +530 -0
  216. package/schematics/utils/typescript.js +44 -0
  217. package/scrollbar/index.d.ts +1 -1
  218. package/search-expandable/index.d.ts +3 -0
  219. package/select/index.d.ts +212 -40
  220. package/select/select-tokens.scss +0 -1
  221. package/select/select.scss +0 -2
  222. package/splitter/index.d.ts +1 -1
  223. package/table/_table-theme.scss +4 -0
  224. package/table/index.d.ts +2 -1
  225. package/table/table.scss +8 -0
  226. package/tabs/_tabs-common.scss +60 -31
  227. package/tabs/_tabs-theme.scss +12 -0
  228. package/tabs/index.d.ts +2 -2
  229. package/tabs/tab-header.scss +14 -0
  230. package/tabs/tab-nav-bar.scss +4 -0
  231. package/tabs/tabs-tokens.scss +1 -0
  232. package/tags/index.d.ts +128 -29
  233. package/textarea/index.d.ts +5 -0
  234. package/time-range/index.d.ts +1 -1
  235. package/timepicker/index.d.ts +4 -0
  236. package/timezone/index.d.ts +10 -8
  237. package/toast/index.d.ts +26 -3
  238. package/toggle/index.d.ts +34 -14
  239. package/tooltip/index.d.ts +119 -7
  240. package/tree/_tree-theme.scss +25 -5
  241. package/tree/index.d.ts +71 -3
  242. package/tree/tree-option.scss +2 -8
  243. package/tree-select/_tree-select-theme.scss +22 -0
  244. package/tree-select/index.d.ts +127 -36
  245. package/accordion/accordion.component.scss +0 -50
  246. package/core/styles/_tokens.kbq.import.scss +0 -4
  247. package/core/styles/theming/_components-theming.scss +0 -1927
  248. package/filter-bar/pipes/pipe-select.scss +0 -5
  249. package/overflow-items/overflow-items.scss +0 -20
@@ -1,11 +1,11 @@
1
1
  import * as i0 from '@angular/core';
2
- import { ChangeDetectionStrategy, Component, input, booleanAttribute, Directive, inject, InjectionToken, ChangeDetectorRef, NgZone, Renderer2, ElementRef, DestroyRef, viewChild, contentChild, TemplateRef, contentChildren, EventEmitter, output, numberAttribute, afterNextRender, isDevMode, Input, Output, ContentChildren, ViewChildren, ViewChild, ViewEncapsulation, NgModule } from '@angular/core';
2
+ import { ChangeDetectionStrategy, Component, input, booleanAttribute, Directive, inject, InjectionToken, ChangeDetectorRef, NgZone, Renderer2, ElementRef, DestroyRef, viewChild, contentChild, TemplateRef, QueryList, contentChildren, EventEmitter, output, numberAttribute, computed, effect, afterNextRender, Input, Output, ContentChildren, ViewChildren, ViewChild, ViewEncapsulation, NgModule } from '@angular/core';
3
3
  import * as i1 from '@koobiq/components/progress-spinner';
4
4
  import { KbqProgressSpinnerModule } from '@koobiq/components/progress-spinner';
5
5
  import { ContentObserver } from '@angular/cdk/observers';
6
6
  import { SharedResizeObserver } from '@angular/cdk/observers/private';
7
7
  import { Platform } from '@angular/cdk/platform';
8
- import { KbqOption, KbqAbstractSelect, getKbqSelectDynamicMultipleError, getKbqSelectNonFunctionValueError, KbqComponentColors, ErrorStateMatcher, KBQ_SELECT_SCROLL_STRATEGY, KBQ_LOCALE_SERVICE, KBQ_WINDOW, defaultOffsetY, KbqSelectFooter, KbqSelectTrigger, KbqSelectMatcher, KbqOptgroup, KbqSelectSearch, KbqSelectSearchEmptyResult, isUndefined, DOWN_ARROW, UP_ARROW, LEFT_ARROW, RIGHT_ARROW, ENTER, SPACE, ESCAPE, TAB, HOME, END, PAGE_UP, PAGE_DOWN, isSelectAll, BACKSPACE, DELETE, getKbqSelectNonArrayValueError, KbqVirtualOption, ActiveDescendantKeyManager, isInput, shouldSelectSearchText, toggleSelectAll, KbqSelectAllEvent, kbqSelectAnimations, KBQ_OPTION_PARENT_COMPONENT, KBQ_PARENT_POPUP, KbqOptionModule, KBQ_SELECT_SCROLL_STRATEGY_PROVIDER } from '@koobiq/components/core';
8
+ import { KbqOption, KbqAbstractSelect, getKbqSelectDynamicMultipleError, getKbqSelectNonFunctionValueError, getSelectAllState, KbqComponentColors, ErrorStateMatcher, KBQ_SELECT_SCROLL_STRATEGY, KBQ_LOCALE_SERVICE, defaultOffsetY, KBQ_CONNECTED_OVERLAY_BELOW_CLASS, KBQ_CONNECTED_OVERLAY_ABOVE_CLASS, KbqSelectFooter, KbqSelectTrigger, KbqSelectMatcher, KbqOptgroup, KbqSelectSearch, KbqSelectSearchEmptyResult, ruRULocaleData, KBQ_PANEL_DEFAULT_MIN_WIDTH, kbqResolvePanelMaxHeightToken, toggleSelectAll, KbqSelectAllEvent, isUndefined, DOWN_ARROW, UP_ARROW, LEFT_ARROW, RIGHT_ARROW, ENTER, SPACE, ESCAPE, TAB, HOME, END, PAGE_UP, PAGE_DOWN, isSelectAll, BACKSPACE, DELETE, getKbqSelectNonArrayValueError, runCompareWith, KbqVirtualOption, ActiveDescendantKeyManager, isInput, shouldSelectSearchText, kbqSelectAnimations, KbqPseudoCheckbox, KBQ_OPTION_PARENT_COMPONENT, KBQ_PARENT_POPUP, kbqSiblingPopupProvider, KbqOptionModule } from '@koobiq/components/core';
9
9
  import { KbqTooltipTrigger, KbqToolTipModule } from '@koobiq/components/tooltip';
10
10
  import { Subscription, throttleTime, Subject, defer, merge, EMPTY, BehaviorSubject, fromEvent } from 'rxjs';
11
11
  import { debounceTime, switchMap, startWith, take, filter, map, delay, distinctUntilChanged, auditTime, takeUntil } from 'rxjs/operators';
@@ -18,15 +18,15 @@ import { CdkVirtualForOf, CdkVirtualScrollViewport } from '@angular/cdk/scrollin
18
18
  import { NgTemplateOutlet } from '@angular/common';
19
19
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
20
20
  import { NgForm, FormGroupDirective, NgControl } from '@angular/forms';
21
- import { KbqFormField, KbqFormFieldControl, KbqFormFieldModule } from '@koobiq/components/form-field';
21
+ import { KBQ_FORM_FIELD, KbqCleaner, KbqFormFieldControl, kbqCleanerFactoryProvider, KbqFormFieldModule } from '@koobiq/components/form-field';
22
22
  import * as i1$1 from '@koobiq/components/icon';
23
23
  import { KbqIconModule } from '@koobiq/components/icon';
24
24
  import { KbqTag, KbqTagsModule } from '@koobiq/components/tags';
25
25
  import { SizeXxs } from '@koobiq/design-tokens';
26
26
 
27
27
  class KbqSelectLoading {
28
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: KbqSelectLoading, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
29
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.25", type: KbqSelectLoading, isStandalone: true, selector: "kbq-select-loading, [kbq-select-loading]", host: { classAttribute: "kbq-select-loading" }, exportAs: ["kbqSelectLoading"], ngImport: i0, template: `
28
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectLoading, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
29
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.30", type: KbqSelectLoading, isStandalone: true, selector: "kbq-select-loading, [kbq-select-loading]", host: { classAttribute: "kbq-select-loading" }, exportAs: ["kbqSelectLoading"], ngImport: i0, template: `
30
30
  <ng-content select="kbq-progress-spinner">
31
31
  <div class="layout-row layout-margin-top-4xl layout-margin-bottom-4xl layout-align-center-center">
32
32
  <kbq-progress-spinner [mode]="'indeterminate'" />
@@ -34,7 +34,7 @@ class KbqSelectLoading {
34
34
  </ng-content>
35
35
  `, isInline: true, dependencies: [{ kind: "ngmodule", type: KbqProgressSpinnerModule }, { kind: "component", type: i1.KbqProgressSpinner, selector: "kbq-progress-spinner", inputs: ["id", "value", "mode", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
36
36
  }
37
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: KbqSelectLoading, decorators: [{
37
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectLoading, decorators: [{
38
38
  type: Component,
39
39
  args: [{
40
40
  selector: 'kbq-select-loading, [kbq-select-loading]',
@@ -65,12 +65,12 @@ class KbqSelectError {
65
65
  /** Indicates whether styles for pagination controls should be used. */
66
66
  this.paging = input(false, ...(ngDevMode ? [{ debugName: "paging", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
67
67
  }
68
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: KbqSelectError, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
69
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.25", type: KbqSelectError, isStandalone: true, selector: "kbq-select-error, [kbq-select-error]", inputs: { paging: { classPropertyName: "paging", publicName: "paging", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.kbq-select-error_default": "!paging()", "class.kbq-select-error_paging": "paging()" }, classAttribute: "kbq-select-error" }, exportAs: ["kbqSelectError"], ngImport: i0, template: `
68
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectError, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
69
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.30", type: KbqSelectError, isStandalone: true, selector: "kbq-select-error, [kbq-select-error]", inputs: { paging: { classPropertyName: "paging", publicName: "paging", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.kbq-select-error_default": "!paging()", "class.kbq-select-error_paging": "paging()" }, classAttribute: "kbq-select-error" }, exportAs: ["kbqSelectError"], ngImport: i0, template: `
70
70
  <ng-content />
71
71
  `, isInline: true, styles: [":host{display:flex;flex-direction:column}:host.kbq-select-error_default{align-items:center;justify-content:center;margin-bottom:var(--kbq-size-3xl);margin-top:var(--kbq-size-3xl)}:host.kbq-select-error_paging{justify-content:start}:host.kbq-select-error_paging ::ng-deep .kbq-select-error__text{padding-left:var(--kbq-size-l)}::ng-deep .kbq-select-error__text{margin-top:var(--kbq-size-xs);margin-bottom:var(--kbq-size-3xs);color:var(--kbq-foreground-error)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
72
72
  }
73
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: KbqSelectError, decorators: [{
73
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectError, decorators: [{
74
74
  type: Component,
75
75
  args: [{ selector: 'kbq-select-error, [kbq-select-error]', template: `
76
76
  <ng-content />
@@ -84,10 +84,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
84
84
  * Marks an element as the error text container for a *KbqSelect* component.
85
85
  */
86
86
  class KbqSelectErrorText {
87
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: KbqSelectErrorText, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
88
- /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.25", type: KbqSelectErrorText, isStandalone: true, selector: "[kbq-select-error-text]", host: { classAttribute: "kbq-select-error__text" }, exportAs: ["kbqSelectErrorText"], ngImport: i0 }); }
87
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectErrorText, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
88
+ /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.30", type: KbqSelectErrorText, isStandalone: true, selector: "[kbq-select-error-text]", host: { classAttribute: "kbq-select-error__text" }, exportAs: ["kbqSelectErrorText"], ngImport: i0 }); }
89
89
  }
90
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: KbqSelectErrorText, decorators: [{
90
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectErrorText, decorators: [{
91
91
  type: Directive,
92
92
  args: [{
93
93
  selector: '[kbq-select-error-text]',
@@ -101,12 +101,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
101
101
  * Component that represents the empty state of a select dropdown.
102
102
  */
103
103
  class KbqSelectNoOptions {
104
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: KbqSelectNoOptions, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
105
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.25", type: KbqSelectNoOptions, isStandalone: true, selector: "kbq-select-no-options, [kbq-select-no-options]", host: { classAttribute: "kbq-select-no-options" }, exportAs: ["kbqSelectNoOptions"], ngImport: i0, template: `
104
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectNoOptions, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
105
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.30", type: KbqSelectNoOptions, isStandalone: true, selector: "kbq-select-no-options, [kbq-select-no-options]", host: { classAttribute: "kbq-select-no-options" }, exportAs: ["kbqSelectNoOptions"], ngImport: i0, template: `
106
106
  <ng-content />
107
107
  `, isInline: true, styles: [":host{display:flex;flex-direction:column;align-items:center;justify-content:center;padding-bottom:var(--kbq-size-3xl);padding-top:var(--kbq-size-3xl);color:var(--kbq-foreground-contrast-secondary)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
108
108
  }
109
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: KbqSelectNoOptions, decorators: [{
109
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectNoOptions, decorators: [{
110
110
  type: Component,
111
111
  args: [{ selector: 'kbq-select-no-options, [kbq-select-no-options]', template: `
112
112
  <ng-content />
@@ -166,10 +166,10 @@ class KbqOptionTooltip extends KbqTooltipTrigger {
166
166
  handleElementLeave() {
167
167
  this.disabled = true;
168
168
  }
169
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: KbqOptionTooltip, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
170
- /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.25", type: KbqOptionTooltip, isStandalone: true, selector: "kbq-option", host: { listeners: { "mouseenter": "handleElementEnter()", "mouseleave": "handleElementLeave()" } }, usesInheritance: true, ngImport: i0 }); }
169
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqOptionTooltip, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
170
+ /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.30", type: KbqOptionTooltip, isStandalone: true, selector: "kbq-option", host: { listeners: { "mouseenter": "handleElementEnter()", "mouseleave": "handleElementLeave()" } }, usesInheritance: true, ngImport: i0 }); }
171
171
  }
172
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: KbqOptionTooltip, decorators: [{
172
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqOptionTooltip, decorators: [{
173
173
  type: Directive,
174
174
  args: [{
175
175
  selector: 'kbq-option',
@@ -380,31 +380,86 @@ class KbqSelect extends KbqAbstractSelect {
380
380
  set focused(value) {
381
381
  this._focused = value;
382
382
  }
383
+ /** Whether the overlay panel is currently on screen. Part of the `KbqSiblingPopup` contract. */
384
+ get isAttached() {
385
+ return this.panelOpen;
386
+ }
383
387
  /** Whether the search returned no results. */
384
388
  get isEmptySearchResult() {
385
389
  const search = this.search();
386
390
  return !!search && this.options?.filter((option) => option.selectable()).length === 0 && !!search.value();
387
391
  }
388
- /** Whether the cleaner (clear button) should be shown. */
392
+ /**
393
+ * Whether the "select all" row is currently rendered.
394
+ *
395
+ * Unsupported whenever a selected value can exist as a synthetic `KbqVirtualOption` instead of a
396
+ * real, projected `KbqOption` (see `selectValue`) — under `withVirtualScroll` or
397
+ * `showPreselectedValues`. `selectAllTargets` can only see `this.options`, the currently-rendered
398
+ * `KbqOption`s, so a checkbox built on top of it would misreport "everything selected" after only
399
+ * touching the values that happen to have a rendered option.
400
+ */
401
+ get showSelectAll() {
402
+ return (this.selectAll() &&
403
+ this.multiSelection &&
404
+ !this.isEmptySearchResult &&
405
+ !this.withVirtualScroll &&
406
+ !this.showPreselectedValues());
407
+ }
408
+ /** Whether every option "select all" can act on is selected. */
409
+ get allOptionsSelected() {
410
+ const targets = this.selectAllTargets;
411
+ // `[].every()` is `true`: with nothing for "select all" to act on, claiming "all selected" would
412
+ // send the toggle down the deselect branch and check the master checkbox over an untouchable list.
413
+ return targets.length > 0 && targets.every((option) => option.selected);
414
+ }
415
+ /** State of the "select all" master checkbox. */
416
+ get selectAllState() {
417
+ return getSelectAllState(this.selectAllAdapter);
418
+ }
419
+ /**
420
+ * Options "select all" acts on, and the ones its checkbox state is derived from.
421
+ *
422
+ * `KbqOption.select()` and `deselect()` do not consult `disabled` or `selectable()`, so the
423
+ * filtering has to happen here rather than being left to the options themselves.
424
+ */
425
+ get selectAllTargets() {
426
+ return this.options?.filter((option) => option.selectable() && !option.disabled) ?? [];
427
+ }
428
+ /** Adapter shared by the master checkbox and the Ctrl/Cmd + A handler, so the two cannot drift apart. */
429
+ get selectAllAdapter() {
430
+ return {
431
+ items: this.selectAllTargets,
432
+ isSelectable: () => true,
433
+ isSelected: (option) => option.selected,
434
+ setSelected: (option, selected) => (selected ? option.select() : option.deselect())
435
+ };
436
+ }
437
+ /**
438
+ * Whether the cleaner (clear button) should be shown.
439
+ * @docs-private
440
+ */
389
441
  get canShowCleaner() {
390
- return !this.disabled && !!this.cleaner() && this.selectionModel.hasValue();
442
+ return !!this.cleaner()?.canShow;
391
443
  }
392
444
  /** Returns the currently selected option(s). Single value or array for multiple selection. */
393
445
  get selected() {
394
- return this.multiSelection ? this.selectionModel.selected : this.selectionModel.selected[0];
446
+ const selected = this.selectionModel.selected;
447
+ return this.multiSelection
448
+ ? selected.map((option) => this.resolveSelectedOption(option))
449
+ : selected[0] && this.resolveSelectedOption(selected[0]);
395
450
  }
396
451
  /** Returns the display value for the trigger element. */
397
452
  get triggerValue() {
398
453
  if (this.empty)
399
454
  return '';
400
- return this.selectionModel.selected[0].viewValue;
455
+ return this.resolveSelectedOption(this.selectionModel.selected[0]).viewValue;
401
456
  }
402
457
  /** Returns all selected options in display order. */
403
458
  get triggerValues() {
404
459
  if (this.empty) {
405
460
  return [];
406
461
  }
407
- const selectedOptions = this.selectionModel.selected;
462
+ const selectedOptions = this.selectionModel.selected.map((option) => this.resolveSelectedOption(option));
408
463
  if (this.isRtl()) {
409
464
  selectedOptions.reverse();
410
465
  }
@@ -420,7 +475,9 @@ class KbqSelect extends KbqAbstractSelect {
420
475
  }
421
476
  /** Returns the first selected option that is not disabled. */
422
477
  get firstSelected() {
423
- return this.selectionModel.selected.filter((option) => !option.disabled)[0] || null;
478
+ return (this.selectionModel.selected
479
+ .map((option) => this.resolveSelectedOption(option))
480
+ .find((option) => !option.disabled) || null);
424
481
  }
425
482
  /** Whether the first selected option is filtered (not visible in the list). */
426
483
  get firstFiltered() {
@@ -450,7 +507,7 @@ class KbqSelect extends KbqAbstractSelect {
450
507
  this._dir = inject(Directionality, { optional: true });
451
508
  this.parentForm = inject(NgForm, { optional: true });
452
509
  this.parentFormGroup = inject(FormGroupDirective, { optional: true });
453
- this.parentFormField = inject(KbqFormField, { host: true, optional: true });
510
+ this.parentFormField = inject(KBQ_FORM_FIELD, { host: true, optional: true });
454
511
  this.ngControl = inject(NgControl, { self: true, optional: true });
455
512
  this.scrollStrategyFactory = inject(KBQ_SELECT_SCROLL_STRATEGY);
456
513
  this.localeService = inject(KBQ_LOCALE_SERVICE, { optional: true });
@@ -458,7 +515,6 @@ class KbqSelect extends KbqAbstractSelect {
458
515
  this.destroyRef = inject(DestroyRef);
459
516
  this.isBrowser = inject(Platform).isBrowser;
460
517
  this.defaultOptions = inject(KBQ_SELECT_OPTIONS, { optional: true });
461
- this.window = inject(KBQ_WINDOW);
462
518
  /** Whether the component is in an error state. */
463
519
  this.errorState = false;
464
520
  /**
@@ -474,6 +530,12 @@ class KbqSelect extends KbqAbstractSelect {
474
530
  this.triggerFontSize = 0;
475
531
  /** Previously selected options before the current selection was made. */
476
532
  this.previousSelectionModelSelected = [];
533
+ /**
534
+ * Detached copies of the selected options, captured while the option was still rendered.
535
+ * `cdk-virtual-scroll` recycles option views, so a `KbqOption` kept in `selectionModel` can
536
+ * silently start carrying another item's value and label — the copy preserves the original ones.
537
+ */
538
+ this.selectedOptionCopies = new WeakMap();
477
539
  /** The value of the select panel's transform-origin property for animations. */
478
540
  this.transformOrigin = 'top';
479
541
  /** Emits when the panel element is finished transforming in. */
@@ -481,16 +543,25 @@ class KbqSelect extends KbqAbstractSelect {
481
543
  /** Strategy that will be used to handle scrolling while the select panel is open. */
482
544
  this.scrollStrategy = this.scrollStrategyFactory();
483
545
  /**
484
- * The y-offset of the overlay panel in relation to the trigger's top start corner.
485
- * This must be adjusted to align the selected option text over the trigger text
486
- * when the panel opens. Will change based on the y-position of the selected option.
546
+ * The y-offset of the overlay panel in relation to the trigger.
547
+ *
548
+ * @deprecated noop. The trigger↔panel gap is now controlled by the `--kbq-connected-overlay-gap` CSS
549
+ * variable (transparent padding inside the pane via the `kbq-connected-overlay_below/_above` panel
550
+ * classes), not by a physical overlay offset — so setting this has no effect. Will be removed in 21.0.0.
487
551
  */
488
- this.offsetY = defaultOffsetY;
552
+ this.offsetY = 0;
489
553
  /**
490
- * This position config ensures that the top "start" corner of the overlay
491
- * is aligned with the top "start" of the origin by default (overlapping
492
- * the trigger completely). If the panel cannot fit below the trigger, it
493
- * will fall back to a position above the trigger.
554
+ * Minimum space to keep between the overlay and the viewport edge.
555
+ * At least `defaultOffsetY` so CDK's fit check which runs before the `kbq-connected-overlay_below/_above`
556
+ * gap padding is applied to the pane stays conservative enough to absorb that padding instead of
557
+ * letting the panel overflow the viewport by the size of the gap.
558
+ */
559
+ this.viewportMargin = defaultOffsetY;
560
+ /**
561
+ * Opens the panel below the trigger, falling back to above it when it does not fit.
562
+ *
563
+ * A third position is appended at runtime by `updatePanelAnchor`: a multiline trigger that has grown
564
+ * taller than the panel gets it anchored to its first row and drawn over the rest of it.
494
565
  */
495
566
  this.positions = [
496
567
  {
@@ -498,14 +569,14 @@ class KbqSelect extends KbqAbstractSelect {
498
569
  originY: 'bottom',
499
570
  overlayX: 'start',
500
571
  overlayY: 'top',
501
- offsetY: this.offsetY
572
+ panelClass: KBQ_CONNECTED_OVERLAY_BELOW_CLASS
502
573
  },
503
574
  {
504
575
  originX: 'start',
505
576
  originY: 'top',
506
577
  overlayX: 'start',
507
578
  overlayY: 'bottom',
508
- offsetY: -this.offsetY
579
+ panelClass: KBQ_CONNECTED_OVERLAY_ABOVE_CLASS
509
580
  }
510
581
  ];
511
582
  /**
@@ -516,6 +587,8 @@ class KbqSelect extends KbqAbstractSelect {
516
587
  this.panel = viewChild('panel', ...(ngDevMode ? [{ debugName: "panel" }] : []));
517
588
  /** Reference to the container element that holds the options. */
518
589
  this.optionsContainer = viewChild.required('optionsContainer');
590
+ /** Reference to the built-in "select all" row, rendered only while `selectAll` is on. */
591
+ this.selectAllOption = viewChild(KbqOption, ...(ngDevMode ? [{ debugName: "selectAllOption" }] : []));
519
592
  /** Reference to the optional footer element in the panel. */
520
593
  this.footer = contentChild(KbqSelectFooter, ...(ngDevMode ? [{ debugName: "footer", read: ElementRef }] : [{ read: ElementRef }]));
521
594
  /** Reference to the CDK virtual scroll directive for virtual scrolling support. */
@@ -528,8 +601,21 @@ class KbqSelect extends KbqAbstractSelect {
528
601
  this.customMatcher = contentChild(KbqSelectMatcher, ...(ngDevMode ? [{ debugName: "customMatcher" }] : []));
529
602
  /** Custom template reference for rendering tag content. */
530
603
  this.customTagTemplateRef = contentChild('kbqSelectTagContent', ...(ngDevMode ? [{ debugName: "customTagTemplateRef", read: TemplateRef }] : [{ read: TemplateRef }]));
531
- /** Reference to the optional cleaner element for clearing selection. */
532
- this.cleaner = contentChild('kbqSelectCleaner', ...(ngDevMode ? [{ debugName: "cleaner" }] : []));
604
+ /**
605
+ * Reference to the optional cleaner element for clearing selection.
606
+ * @docs-private
607
+ */
608
+ this.cleaner = contentChild(KbqCleaner, ...(ngDevMode ? [{ debugName: "cleaner", descendants: false }] : [{ descendants: false }]));
609
+ /**
610
+ * Everything the key manager navigates: the built-in "select all" row first, then `options`.
611
+ *
612
+ * The row is rendered by the select's own template, so it never reaches the `options` content query.
613
+ * Kept as a separate list rather than folded into `options` because `options` is public API — the
614
+ * filter-bar pipes, `firstFiltered` and the tallies below all mean "the options the consumer
615
+ * projected", and a synthetic entry there would quietly corrupt every one of them.
616
+ * @docs-private
617
+ */
618
+ this.navigableOptions = new QueryList();
533
619
  /** All of the defined groups of options. */
534
620
  this.optionGroups = contentChildren(KbqOptgroup, ...(ngDevMode ? [{ debugName: "optionGroups" }] : []));
535
621
  /** Reference to the optional search component. */
@@ -540,6 +626,8 @@ class KbqSelect extends KbqAbstractSelect {
540
626
  // TODO: Skipped for migration because:
541
627
  // Your application code writes to the input. This prevents migration.
542
628
  this.hiddenItemsText = '+{{ number }}';
629
+ /** Label of the "select all" row. Kept in step with the locale service. */
630
+ this.selectAllText = ruRULocaleData.select.selectAll;
543
631
  /** Determines whether preselected values are displayed. */
544
632
  this.showPreselectedValues = input(false, ...(ngDevMode ? [{ debugName: "showPreselectedValues" }] : []));
545
633
  /**
@@ -577,7 +665,12 @@ class KbqSelect extends KbqAbstractSelect {
577
665
  }
578
666
  return this._ngZone.onStable.asObservable().pipe(take(1), switchMap(() => this.optionSelectionChanges));
579
667
  });
580
- /** Event emitted when the select panel has been toggled. Emits true when opened, false when closed. */
668
+ /**
669
+ * Event emitted when the select panel has been toggled. Emits true when opened, false when closed.
670
+ * Also serves as the `openedChange` member of the `KbqSiblingPopup` contract — a tooltip sharing
671
+ * this element's host reacts to it, so its emission timing (gated on `panelDoneAnimatingStream`, see
672
+ * `ngOnInit`) matters beyond this output's original consumers.
673
+ */
581
674
  this.openedChange = new EventEmitter();
582
675
  /** Event emitted before the select panel starts opening. */
583
676
  this.beforeOpened = output();
@@ -625,29 +718,60 @@ class KbqSelect extends KbqAbstractSelect {
625
718
  /** When `true`, a repeated Ctrl/Cmd+A deselects all options. Off by default (Ctrl+A only selects). */
626
719
  this.selectAllToggle = input(false, ...(ngDevMode ? [{ debugName: "selectAllToggle", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
627
720
  /**
628
- * Width of the panel. If set to `auto`, the panel will match the trigger width.
629
- * If set to null or an empty string, the panel will grow to match the longest option's text.
721
+ * Whether to render the "select all" master checkbox above the options. Multiple selection only.
722
+ *
723
+ * The row acts on the options the user can actually toggle — rendered, enabled and selectable. Since
724
+ * search filtering removes options from the DOM, "select all" under an active query selects only the
725
+ * matches. Enabling it also makes Ctrl/Cmd + A a two-way toggle, so the shortcut and the checkbox
726
+ * never disagree (`selectAllToggle` is implied).
630
727
  */
631
- // TODO: Skipped for migration because:
632
- // The input cannot be migrated because the field is overridden by a subclass.
633
- this.panelWidth = this.defaultOptions?.panelWidth || null;
728
+ this.selectAll = input(false, ...(ngDevMode ? [{ debugName: "selectAll", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
729
+ /**
730
+ * Width of the panel. If set to `auto`, the panel will match the trigger width, but will never be
731
+ * narrower than `panelMinWidth`. If set to null or an empty string, the panel will grow to match the
732
+ * longest option's text. Any other value is used as an exact width, and `panelMinWidth` is not applied.
733
+ */
734
+ this.panelWidth = input(this.defaultOptions?.panelWidth || null, ...(ngDevMode ? [{ debugName: "panelWidth" }] : []));
634
735
  /**
635
736
  * Minimum width of the panel in pixels.
636
737
  * If minWidth is larger than window width, it will be ignored.
637
738
  */
638
- // TODO: Skipped for migration because:
639
- // The input cannot be migrated because the field is overridden by a subclass.
640
- this.panelMinWidth = this.defaultOptions?.panelMinWidth ?? 200;
739
+ this.panelMinWidth = input(this.defaultOptions?.panelMinWidth === undefined
740
+ ? KBQ_PANEL_DEFAULT_MIN_WIDTH
741
+ : this.defaultOptions.panelMinWidth, ...(ngDevMode ? [{ debugName: "panelMinWidth", transform: numberAttribute }] : [{ transform: numberAttribute }]));
742
+ /**
743
+ * Maximum width of the panel in pixels. Caps how far the panel grows with its content — it never makes
744
+ * the panel narrower than the trigger, and never clamps an explicit `panelWidth`.
745
+ * When null, the `--kbq-panel-size-width-max` token applies.
746
+ */
747
+ this.panelMaxWidth = input(this.defaultOptions?.panelMaxWidth === undefined ? null : this.defaultOptions.panelMaxWidth, ...(ngDevMode ? [{ debugName: "panelMaxWidth", transform: numberAttribute }] : [{ transform: numberAttribute }]));
748
+ /**
749
+ * Maximum height of the panel's scrollable option list, in pixels. Applied as the
750
+ * `--kbq-select-panel-size-max-height` custom property on the panel, so it also drives the pinned height
751
+ * of a `cdk-virtual-scroll-viewport` — with virtual scroll the value is an exact height, not a cap.
752
+ *
753
+ * The search field and the footer sit outside the scrollable area and add to the panel's total height.
754
+ * When null, the token default (256px) applies.
755
+ */
756
+ this.panelMaxHeight = input(this.defaultOptions?.panelMaxHeight === undefined ? null : this.defaultOptions.panelMaxHeight, ...(ngDevMode ? [{ debugName: "panelMaxHeight", transform: numberAttribute }] : [{ transform: numberAttribute }]));
757
+ /**
758
+ * `panelMaxHeight` rendered as a CSS length for the `--kbq-select-panel-size-max-height` token.
759
+ * A non-finite value (e.g. `null`) leaves the stylesheet default in place.
760
+ * @docs-private
761
+ */
762
+ this.panelMaxHeightToken = computed(() => kbqResolvePanelMaxHeightToken(this.panelMaxHeight()), ...(ngDevMode ? [{ debugName: "panelMaxHeightToken" }] : []));
641
763
  this._tabIndex = 0;
642
764
  this._disabled = false;
643
765
  /** Whether the select panel is currently open. */
644
766
  this.panelOpen = false;
645
767
  this._focused = false;
768
+ /** Whether a "select all" batch is running, so the per-option changes propagate only once. */
769
+ this.selectAllInProgress = false;
646
770
  /** Subscription to the close event of the overlay. */
647
771
  this.closeSubscription = Subscription.EMPTY;
648
772
  /** Subscription to the options panel scroll event used by `scrolledToBottom`. */
649
773
  this.scrollSubscription = Subscription.EMPTY;
650
- /** The scroll position of the overlay panel, calculated to center the selected option. */
774
+ /** The scroll offset the panel is restored to when it attaches — the list always opens at the top. */
651
775
  this.scrollTop = 0;
652
776
  /** Unique id for this input. Auto-incremented for each instance. */
653
777
  this.uid = `kbq-select-${nextUniqueId++}`;
@@ -700,12 +824,23 @@ class KbqSelect extends KbqAbstractSelect {
700
824
  };
701
825
  /** Updates locale parameters from the locale service. */
702
826
  this.updateLocaleParams = () => {
703
- this.hiddenItemsText = this.localeService?.getParams('select').hiddenItemsText;
827
+ // A consumer-supplied locale (`KBQ_LOCALE_DATA`/`addLocale`) may predate the `select` section
828
+ // entirely, not just the `selectAll` key within it — guard the lookup itself, not just its fields.
829
+ const params = this.localeService?.getParams('select');
830
+ this.hiddenItemsText = params?.hiddenItemsText ?? this.hiddenItemsText;
831
+ this.selectAllText = params?.selectAll ?? ruRULocaleData.select.selectAll;
704
832
  this._changeDetectorRef.markForCheck();
705
833
  };
706
834
  /** Comparison function to specify which option is displayed. Defaults to object equality. */
707
835
  this._compareWith = (o1, o2) => o1 === o2;
708
- this.localeService?.changes.subscribe(this.updateLocaleParams);
836
+ this.localeService?.changes.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(this.updateLocaleParams);
837
+ // The "select all" row only exists while the panel is attached, so the key manager's list has to
838
+ // be rebuilt whenever the view query resolves or drops it — `options.changes` alone never fires
839
+ // for it.
840
+ effect(() => {
841
+ this.selectAllOption();
842
+ this.syncNavigableOptions();
843
+ });
709
844
  if (this.ngControl) {
710
845
  // Note: we provide the value accessor through here, instead of
711
846
  // the `providers` to avoid running into a circular import.
@@ -745,13 +880,20 @@ class KbqSelect extends KbqAbstractSelect {
745
880
  }
746
881
  });
747
882
  merge(this.optionSelectionChanges, this.visibleChanges)
748
- .pipe(distinctUntilChanged(), takeUntilDestroyed(this.destroyRef))
749
- .subscribe(() => setTimeout(() => {
883
+ // `delay(0)` rather than a `setTimeout` inside the subscriber: `takeUntilDestroyed` cancels a
884
+ // scheduled emission, but not a timer the subscriber has already started, which would then run
885
+ // its measurements against a destroyed view.
886
+ .pipe(distinctUntilChanged(), delay(0), takeUntilDestroyed(this.destroyRef))
887
+ .subscribe(() => {
750
888
  this.calculateHiddenItems();
751
889
  if (this.multiline()) {
890
+ // A multiline trigger grows with every selected option, and this is the one signal
891
+ // guaranteed to arrive for it. The trigger's height has changed whatever the anchor
892
+ // decides, so the panel is repositioned either way.
893
+ this.updatePanelAnchor();
752
894
  this.setOverlayPosition();
753
895
  }
754
- }, 0));
896
+ });
755
897
  }
756
898
  /** Lifecycle hook for change detection. Updates visibility and error state. */
757
899
  ngDoCheck() {
@@ -769,20 +911,24 @@ class KbqSelect extends KbqAbstractSelect {
769
911
  event.removed.forEach((option) => option.deselect());
770
912
  });
771
913
  this.options.changes.pipe(startWith(null), takeUntilDestroyed(this.destroyRef)).subscribe(() => {
914
+ this.syncNavigableOptions();
772
915
  this.resetOptions();
773
916
  this.initializeSelection();
774
917
  });
775
918
  this.search()
776
- ?.changes.pipe(takeUntilDestroyed(this.destroyRef), delay(0), filter(() => {
777
- const activeItem = this.keyManager.activeItem;
778
- return !activeItem || !this.options.toArray().includes(activeItem);
779
- }))
919
+ ?.changes.pipe(takeUntilDestroyed(this.destroyRef), delay(0),
920
+ // Only while the panel is open. `beforeOpened` gives consumers a chance to (re)load
921
+ // options, and with no options the panel itself opens with a delay, so search changes
922
+ // can land while the panel is still closed. Moving the highlight then is read as
923
+ // keyboard navigation of a closed select and silently overwrites the value.
924
+ filter(() => this.panelOpen && this.isActiveItemStale()))
780
925
  .subscribe(() => this.keyManager.setFirstItemActive());
781
926
  }
782
927
  /** Lifecycle hook when component is destroyed. Cleans up subscriptions. */
783
928
  ngOnDestroy() {
784
929
  this.stateChanges.complete();
785
930
  this.closeSubscription.unsubscribe();
931
+ this.unsubscribeFromPanelResize();
786
932
  clearTimeout(this.openPanelTimeout);
787
933
  }
788
934
  /** Updates the error state based on the error state matcher. */
@@ -806,19 +952,55 @@ class KbqSelect extends KbqAbstractSelect {
806
952
  hiddenItemsTextFormatter(hiddenItemsText, hiddenItems) {
807
953
  return hiddenItemsText.replace('{{ number }}', hiddenItems.toString());
808
954
  }
955
+ /**
956
+ * Selects every option "select all" can act on, or deselects them all when they are already selected.
957
+ *
958
+ * Backs both the master checkbox and Ctrl/Cmd + A while `selectAll` is on. Emits a single
959
+ * `selectionChange` for the whole batch, followed by `onSelectAll`.
960
+ */
961
+ toggleSelectAll() {
962
+ const targets = this.selectAllTargets;
963
+ if (!targets.length)
964
+ return;
965
+ // The per-option selection events are what keep `selectionModel` in step, but each of them would
966
+ // otherwise propagate a value of its own. Suppressing that and propagating once at the end turns
967
+ // N events into the single change the user actually performed.
968
+ this.selectAllInProgress = true;
969
+ try {
970
+ toggleSelectAll(this.selectAllAdapter, { allowDeselect: true });
971
+ }
972
+ finally {
973
+ this.selectAllInProgress = false;
974
+ }
975
+ this.propagateChanges();
976
+ this.stateChanges.next();
977
+ this.onSelectAll.emit(new KbqSelectAllEvent(this, targets, this.allOptionsSelected));
978
+ }
809
979
  /**
810
980
  * Clears the current selection.
811
- * @param $event Mouse event to prevent default behavior.
981
+ * @docs-private
812
982
  */
813
- clearValue($event) {
814
- // need to prevent opening
815
- $event.stopPropagation();
816
- // need to prevent scrolling
817
- $event.preventDefault();
983
+ clear() {
818
984
  this.selectionModel.clear();
819
985
  this.keyManager.setActiveItem(-1);
820
986
  this.propagateChanges();
821
- this.focus();
987
+ }
988
+ /**
989
+ * Clears the current selection.
990
+ * @deprecated Activate the projected `KbqCleaner` instead.
991
+ * @docs-private
992
+ */
993
+ clearValue(event) {
994
+ const cleaner = this.cleaner();
995
+ if (cleaner) {
996
+ cleaner.clear(event);
997
+ }
998
+ else {
999
+ event.stopPropagation();
1000
+ event.preventDefault();
1001
+ this.clear();
1002
+ this.focus();
1003
+ }
822
1004
  }
823
1005
  /** Resets the search component if present. */
824
1006
  resetSearch() {
@@ -881,14 +1063,7 @@ class KbqSelect extends KbqAbstractSelect {
881
1063
  if (this.parentFormField) {
882
1064
  this.overlayOrigin = this.parentFormField.getConnectedOverlayOrigin();
883
1065
  }
884
- this.overlayWidth = this.getOverlayWidth(this.overlayOrigin);
885
- // set overlayMinWidth to the largest of `panelMinWidth` and `triggerRect.width`
886
- // only if `overlayWidth` falsy and `panelMinWidth` not provided.
887
- // This ensures panel isn't narrow.
888
- this.overlayMinWidth =
889
- this.panelMinWidth !== null && !this.overlayWidth
890
- ? Math.max(this.panelMinWidth, this.triggerRect.width)
891
- : '';
1066
+ this.updateOverlayWidth(this.panelWidth(), this.panelMinWidth(), this.overlayOrigin ?? this.elementRef);
892
1067
  this.panelOpen = true;
893
1068
  this.keyManager.withHorizontalOrientation(null);
894
1069
  this.highlightCorrectOption();
@@ -903,11 +1078,8 @@ class KbqSelect extends KbqAbstractSelect {
903
1078
  this.overlayDir.overlayRef.overlayElement.style.fontSize = `${this.triggerFontSize}px`;
904
1079
  }
905
1080
  this.addClassToOverlayContainer();
906
- if (this.search() && !this.overlayWidth) {
907
- const measuredPanelWidth = this.panel()?.nativeElement.getBoundingClientRect().width;
908
- if (measuredPanelWidth) {
909
- this.overlayWidth = measuredPanelWidth;
910
- }
1081
+ if (this.search()) {
1082
+ this.lockOverlayWidthForSearch(this.panel());
911
1083
  }
912
1084
  });
913
1085
  }
@@ -918,6 +1090,10 @@ class KbqSelect extends KbqAbstractSelect {
918
1090
  // the order of calls is important
919
1091
  this.resetSearch();
920
1092
  this.panelOpen = false;
1093
+ this.unsubscribeFromPanelResize();
1094
+ // Back to the two default sides, so the next open is not resolved against a first row that has since
1095
+ // changed height.
1096
+ this.positions = this.withOverlapPosition(this.positions, null) ?? this.positions;
921
1097
  this.keyManager.withHorizontalOrientation(this.isRtl() ? 'rtl' : 'ltr');
922
1098
  this._changeDetectorRef.markForCheck();
923
1099
  this.onTouched();
@@ -1018,12 +1194,32 @@ class KbqSelect extends KbqAbstractSelect {
1018
1194
  this.optionsContainer().nativeElement.scrollTop = this.scrollTop;
1019
1195
  this.updateScrollSize();
1020
1196
  this.subscribeToScrolledToBottom();
1197
+ // Deliberately out of this frame — see `reanchorPanel`. A microtask still lands before paint.
1198
+ queueMicrotask(() => this.reanchorPanel());
1021
1199
  });
1022
- this.options.changes
1023
- .pipe(delay(1), takeUntilDestroyed(this.destroyRef))
1024
- .subscribe(() => this.setOverlayPosition());
1200
+ // The option list drives the panel's height, so a change to it can settle the anchor question
1201
+ // differently — and the panel is realigned on every such change regardless.
1202
+ this.options.changes.pipe(delay(1), takeUntilDestroyed(this.destroyRef)).subscribe(() => {
1203
+ this.updatePanelAnchor();
1204
+ this.setOverlayPosition();
1205
+ });
1206
+ this.subscribeToPanelResize();
1025
1207
  this.closeSubscription = this.closingActions().subscribe(() => this.close());
1026
1208
  }
1209
+ /** Element the overlay is positioned and sized against. */
1210
+ getOverlayOriginElement() {
1211
+ return this.parentFormField?.getConnectedOverlayOrigin().nativeElement ?? this.trigger()?.nativeElement;
1212
+ }
1213
+ isPanelOpen() {
1214
+ return this.panelOpen;
1215
+ }
1216
+ /**
1217
+ * A `cdk-virtual-scroll-viewport` pins its height to `--kbq-select-panel-size-max-height` in both
1218
+ * directions, so its `scrollHeight` follows the cap rather than the content.
1219
+ */
1220
+ isListHeightPinnedToCap() {
1221
+ return this.withVirtualScroll;
1222
+ }
1027
1223
  /** Returns the theme to be used on the panel based on parent form field color. */
1028
1224
  getPanelTheme() {
1029
1225
  return this.parentFormField ? `kbq-${this.parentFormField.color}` : '';
@@ -1082,12 +1278,22 @@ class KbqSelect extends KbqAbstractSelect {
1082
1278
  }
1083
1279
  /** @docs-private */
1084
1280
  setSelectedOptionsByClick(option) {
1281
+ // `KbqOption.handleClick` routes a shift-click straight here, skipping the `disabled`/`selectable`
1282
+ // check that `selectViaInteraction` applies to a plain click — so the guard has to live here.
1283
+ // It precedes `setActiveItem` deliberately: the range anchor must not come to rest on an option
1284
+ // the user cannot toggle, or the next shift-range would take its direction from that option's
1285
+ // (unchangeable) selected state. Mirrors `KbqTreeSelection.setSelectedOptionsByClick`.
1286
+ if (option.disabled || !option.selectable()) {
1287
+ return;
1288
+ }
1085
1289
  if (this.multiple || this.multiline()) {
1086
1290
  this.keyManager.setActiveItem(option);
1087
- const options = this.options.toArray();
1291
+ // The key manager's list, not `options`: with the "select all" row rendered the two are offset
1292
+ // by one, and a range read off `options` would land on the wrong options entirely.
1293
+ const options = this.navigableOptions.toArray();
1088
1294
  let fromIndex = this.keyManager.previousActiveItemIndex;
1089
1295
  let toIndex = (this.keyManager.previousActiveItemIndex = this.keyManager.activeItemIndex);
1090
- const selectedOptionState = options[fromIndex].selected;
1296
+ const selectedOptionState = options[fromIndex]?.selected;
1091
1297
  if (toIndex === fromIndex) {
1092
1298
  this.selectionModel.toggle(option);
1093
1299
  return;
@@ -1097,7 +1303,7 @@ class KbqSelect extends KbqAbstractSelect {
1097
1303
  }
1098
1304
  options
1099
1305
  .slice(fromIndex, toIndex + 1)
1100
- .filter((item) => !item.disabled)
1306
+ .filter((item) => !item.disabled && item.selectable())
1101
1307
  .forEach((option) => {
1102
1308
  if (selectedOptionState) {
1103
1309
  option.select();
@@ -1198,14 +1404,20 @@ class KbqSelect extends KbqAbstractSelect {
1198
1404
  }
1199
1405
  /**
1200
1406
  * Calculates the width of a single item including margins.
1407
+ *
1408
+ * The elements measured here are `kbq-tag`s, which are `border-box` and carry horizontal
1409
+ * padding. `getComputedStyle().width` resolves to the used content-box width whatever
1410
+ * `box-sizing` says, so it dropped that padding from every tag and the matcher believed more
1411
+ * tags fit than actually do. `getBoundingClientRect()` is always the border box — the same fix
1412
+ * `kbqGetPanelWidthOrigin()` carries for the dropdown trigger.
1201
1413
  * @param element The DOM element to measure.
1202
1414
  * @returns Total width including margins and gap.
1203
1415
  */
1204
1416
  getItemWidth(element) {
1205
1417
  const computedStyle = this.window.getComputedStyle(element);
1206
- const width = parseInt(computedStyle.width);
1207
- const marginLeft = parseInt(computedStyle.marginLeft);
1208
- const marginRight = parseInt(computedStyle.marginRight);
1418
+ const width = element.getBoundingClientRect().width;
1419
+ const marginLeft = parseFloat(computedStyle.marginLeft) || 0;
1420
+ const marginRight = parseFloat(computedStyle.marginRight) || 0;
1209
1421
  return width + marginLeft + marginRight + parseInt(SizeXxs);
1210
1422
  }
1211
1423
  /** Handles keyboard events while the select is closed. */
@@ -1229,6 +1441,10 @@ class KbqSelect extends KbqAbstractSelect {
1229
1441
  if ((isArrowKey && event.altKey) || keyCode === ESCAPE || keyCode === TAB) {
1230
1442
  // Close the select on ALT + arrow key to match the native <select>
1231
1443
  event.preventDefault();
1444
+ // Prevent ESCAPE from bubbling to ancestor (when inside overlay)
1445
+ if (keyCode === ESCAPE) {
1446
+ event.stopPropagation();
1447
+ }
1232
1448
  this.close();
1233
1449
  this.focus();
1234
1450
  }
@@ -1250,7 +1466,15 @@ class KbqSelect extends KbqAbstractSelect {
1250
1466
  }
1251
1467
  else if ((keyCode === ENTER || keyCode === SPACE) && this.keyManager.activeItem) {
1252
1468
  event.preventDefault();
1253
- this.keyManager.activeItem.selectViaInteraction();
1469
+ // The row is not selectable, so `selectViaInteraction()` would be a no-op on it. Handling it
1470
+ // here covers both focus positions — the row itself and the search field the panel keeps
1471
+ // focus in while the row is merely active.
1472
+ if (this.keyManager.activeItem === this.selectAllOption()) {
1473
+ this.toggleSelectAll();
1474
+ }
1475
+ else {
1476
+ this.keyManager.activeItem.selectViaInteraction();
1477
+ }
1254
1478
  }
1255
1479
  else if (this.multiSelection && isSelectAll(event)) {
1256
1480
  this.selectAllHandler(event, this);
@@ -1291,6 +1515,32 @@ class KbqSelect extends KbqAbstractSelect {
1291
1515
  this.setSelectionByValue(this.ngControl ? this.ngControl.value : this._value);
1292
1516
  });
1293
1517
  }
1518
+ /** Whether the key manager has no active item, or its active item is missing from the current options list. */
1519
+ isActiveItemStale() {
1520
+ const activeItem = this.keyManager.activeItem;
1521
+ return !activeItem || !this.navigableOptions.some((option) => option === activeItem);
1522
+ }
1523
+ /**
1524
+ * Rebuilds the key manager's list — the "select all" row first, then the projected options — and
1525
+ * re-applies the panel's initial highlight whenever the row is what just joined that list.
1526
+ *
1527
+ * Both callers have to be able to do the second part: whichever of the view query and
1528
+ * `options.changes` runs first is the one that brings the row in, and the other then sees a list
1529
+ * it is already part of.
1530
+ */
1531
+ syncNavigableOptions() {
1532
+ const selectAllOption = this.selectAllOption();
1533
+ const options = this.options?.toArray() ?? [];
1534
+ // The row is created together with the overlay, so the highlight `openPanel()` applies is
1535
+ // computed against a list that does not hold it yet and lands on the option below it instead.
1536
+ // Re-apply it the moment the row takes the lead — the call is idempotent for every other case.
1537
+ const selectAllOptionAppeared = !!selectAllOption && this.navigableOptions.first !== selectAllOption;
1538
+ this.navigableOptions.reset(selectAllOption ? [selectAllOption, ...options] : options);
1539
+ this.navigableOptions.notifyOnChanges();
1540
+ if (selectAllOptionAppeared && this.panelOpen) {
1541
+ this.highlightCorrectOption();
1542
+ }
1543
+ }
1294
1544
  /**
1295
1545
  * Sets the selected option based on a value.
1296
1546
  * If no option can be found with the designated value, the select trigger is cleared.
@@ -1311,7 +1561,11 @@ class KbqSelect extends KbqAbstractSelect {
1311
1561
  const correspondingOption = this.selectValue(value);
1312
1562
  // Shift focus to the active item. Note that we shouldn't do this in multiple
1313
1563
  // mode, because we don't know what option the user interacted with last.
1314
- if (correspondingOption && !this.withVirtualScroll) {
1564
+ // While the panel is open and the user is already navigating a still-present
1565
+ // active item, keep it as is: `options.changes` re-runs this method on every
1566
+ // appended chunk (e.g. paging), and re-activating the selected option would
1567
+ // focus it and scroll the list back to it.
1568
+ if (correspondingOption && !this.withVirtualScroll && (!this.panelOpen || this.isActiveItemStale())) {
1315
1569
  this.keyManager.setActiveItem(correspondingOption);
1316
1570
  }
1317
1571
  }
@@ -1325,42 +1579,49 @@ class KbqSelect extends KbqAbstractSelect {
1325
1579
  getCorrespondOption(value) {
1326
1580
  return [
1327
1581
  ...this.options.toArray(),
1328
- ...this.previousSelectionModelSelected
1329
- ].find((option) => {
1330
- try {
1331
- // Treat null as a special reset value.
1332
- return option.value != null && this.compareWith(option.value, value);
1333
- }
1334
- catch (error) {
1335
- if (isDevMode()) {
1336
- // Notify developers of errors in their comparator.
1337
- // eslint-disable-next-line no-console
1338
- console.warn(error);
1339
- }
1340
- return false;
1341
- }
1342
- });
1582
+ ...this.previousSelectionModelSelected.map((option) => this.resolveSelectedOption(option))
1583
+ // Treat null as a special reset value.
1584
+ ].find((option) => option.value != null && runCompareWith(this.compareWith, option.value, value));
1343
1585
  }
1344
1586
  /**
1345
- * Finds and selects and option based on its value.
1346
- * @returns Option that has the corresponding value.
1587
+ * Finds and selects an option based on its value.
1588
+ * @returns Option that has the corresponding value, when it is currently rendered.
1347
1589
  */
1348
1590
  selectValue(value) {
1349
1591
  const correspondingOption = this.getCorrespondOption(value);
1350
1592
  if (correspondingOption) {
1351
1593
  this.selectionModel.select(correspondingOption);
1594
+ this.captureSelectedOptionCopy(correspondingOption);
1595
+ // Only a currently rendered option can be activated in the key manager.
1596
+ return this.options.find((option) => option === correspondingOption);
1597
+ }
1598
+ const virtualOption = this.createVirtualOptionForValue(value);
1599
+ if (virtualOption) {
1600
+ this.selectionModel.select(virtualOption);
1352
1601
  }
1353
- else if (this.withVirtualScroll) {
1602
+ return undefined;
1603
+ }
1604
+ /**
1605
+ * Builds a detached option for a value whose `KbqOption` is not rendered, or returns `undefined`
1606
+ * when the value cannot be resolved and the consumer gave no way to render it.
1607
+ */
1608
+ createVirtualOptionForValue(value) {
1609
+ // Treat null as a special reset value, the same way `getCorrespondOption` does.
1610
+ if (value == null)
1611
+ return undefined;
1612
+ if (this.withVirtualScroll) {
1354
1613
  const source = this.cdkVirtualForOf()?.cdkVirtualForOf;
1355
1614
  const correspondingOptionVirtual = source instanceof Array ? source.find((item) => this.compareWith(item, value)) : undefined;
1356
1615
  if (correspondingOptionVirtual) {
1357
- this.selectionModel.select(this.createVirtualOption(correspondingOptionVirtual));
1616
+ return this.createVirtualOption(correspondingOptionVirtual);
1358
1617
  }
1618
+ // The value is missing from the currently loaded data (server-side search, a narrowed down
1619
+ // source) — it can still be rendered when a `virtualOptionFactory` maps it to a label.
1620
+ return this.virtualOptionFactory() ? this.createVirtualOption(value) : undefined;
1359
1621
  }
1360
- else if (this.showPreselectedValues()) {
1361
- this.selectionModel.select(this.createVirtualOption(value));
1362
- }
1363
- return correspondingOption;
1622
+ // Without virtual scroll the whole list is rendered, so a value that matched nothing is only
1623
+ // kept in the selection when the consumer opted into unresolved values.
1624
+ return this.showPreselectedValues() ? this.createVirtualOption(value) : undefined;
1364
1625
  }
1365
1626
  /**
1366
1627
  * Single entry point for building a `KbqVirtualOption` from a raw value.
@@ -1371,10 +1632,28 @@ class KbqSelect extends KbqAbstractSelect {
1371
1632
  const virtualOptionFactory = this.virtualOptionFactory();
1372
1633
  return virtualOptionFactory ? virtualOptionFactory(value) : new KbqVirtualOption(value, this.disabled);
1373
1634
  }
1635
+ /**
1636
+ * Remembers the value and the label of a selected option while its view is still live, so that the
1637
+ * selection survives the view being recycled by `cdk-virtual-scroll` for another item.
1638
+ */
1639
+ captureSelectedOptionCopy(option) {
1640
+ if (option instanceof KbqVirtualOption)
1641
+ return;
1642
+ this.selectedOptionCopies.set(option, new KbqVirtualOption(option.value, option.disabled, option.viewValue));
1643
+ }
1644
+ /** Copy of `option` when its view has been recycled for another item, otherwise `option` itself. */
1645
+ resolveSelectedOption(option) {
1646
+ const copy = this.selectedOptionCopies.get(option);
1647
+ if (!copy)
1648
+ return option;
1649
+ // A value that no longer matches the copy means the view was recycled for another item. A
1650
+ // comparator that throws reads as "no match" here too, falling back to the value actually selected.
1651
+ return runCompareWith(this.compareWith, option.value, copy.value) ? option : copy;
1652
+ }
1374
1653
  /** Sets up a key manager to listen to keyboard events on the overlay panel. */
1375
1654
  initKeyManager() {
1376
1655
  const typeAheadDebounce = 200;
1377
- this.keyManager = new ActiveDescendantKeyManager(this.options)
1656
+ this.keyManager = new ActiveDescendantKeyManager(this.navigableOptions)
1378
1657
  .withTypeAhead(typeAheadDebounce, this.search() ? -1 : 0)
1379
1658
  .withVerticalOrientation()
1380
1659
  .withHorizontalOrientation(this.isRtl() ? 'rtl' : 'ltr');
@@ -1419,6 +1698,7 @@ class KbqSelect extends KbqAbstractSelect {
1419
1698
  else {
1420
1699
  if (option.selected) {
1421
1700
  this.selectionModel.select(option);
1701
+ this.captureSelectedOptionCopy(option);
1422
1702
  }
1423
1703
  else {
1424
1704
  this.selectionModel.deselect(option);
@@ -1430,7 +1710,8 @@ class KbqSelect extends KbqAbstractSelect {
1430
1710
  this.sortValues();
1431
1711
  }
1432
1712
  }
1433
- if (wasSelected !== this.selectionModel.isSelected(option)) {
1713
+ // `toggleSelectAll` propagates once for the whole batch instead.
1714
+ if (!this.selectAllInProgress && wasSelected !== this.selectionModel.isSelected(option)) {
1434
1715
  this.propagateChanges();
1435
1716
  }
1436
1717
  this.stateChanges.next();
@@ -1475,18 +1756,9 @@ class KbqSelect extends KbqAbstractSelect {
1475
1756
  }
1476
1757
  }
1477
1758
  }
1478
- /** Scrolls the active option into view. */
1479
1759
  scrollActiveOptionIntoView() {
1480
1760
  this.keyManager.activeItem?.focus();
1481
1761
  }
1482
- /** Gets how wide the overlay panel should be. */
1483
- getOverlayWidth(origin) {
1484
- if (this.panelWidth === 'auto') {
1485
- const elementRef = origin instanceof CdkOverlayOrigin ? origin.elementRef : origin || this.elementRef;
1486
- return elementRef.nativeElement.getBoundingClientRect().width;
1487
- }
1488
- return this.panelWidth ?? '';
1489
- }
1490
1762
  /** Function for handling the combination Ctrl + A (select all). By default, the internal handler is used. */
1491
1763
  _selectAllHandler(event, select) {
1492
1764
  const searchInput = isInput(event) ? event.target : null;
@@ -1496,11 +1768,19 @@ class KbqSelect extends KbqAbstractSelect {
1496
1768
  return;
1497
1769
  }
1498
1770
  event.preventDefault();
1771
+ // With the master checkbox on screen the shortcut has to behave exactly like clicking it,
1772
+ // otherwise the same action would leave the checkbox showing something the selection contradicts.
1773
+ if (select.selectAll()) {
1774
+ select.toggleSelectAll();
1775
+ return;
1776
+ }
1499
1777
  const options = select.options.toArray();
1500
- const selectableOptions = options.filter((option) => !option.disabled);
1778
+ const selectableOptions = options.filter((option) => !option.disabled && option.selectable());
1501
1779
  toggleSelectAll({
1502
1780
  items: options,
1503
- isSelectable: (option) => !option.disabled,
1781
+ // A non-selectable option is not one the user could ever toggle by hand — sweeping it up
1782
+ // here would select the consumer's own "select all" row along with the real options.
1783
+ isSelectable: (option) => !option.disabled && option.selectable(),
1504
1784
  isSelected: (option) => option.selected,
1505
1785
  setSelected: (option, selected) => (selected ? option.select() : option.deselect())
1506
1786
  }, { allowDeselect: select.selectAllToggle() });
@@ -1559,17 +1839,31 @@ class KbqSelect extends KbqAbstractSelect {
1559
1839
  this._renderer.removeClass(this.overlayContainer.getContainerElement(), 'cdk-overlay-container_dropdown');
1560
1840
  }
1561
1841
  }
1562
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: KbqSelect, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1563
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: KbqSelect, isStandalone: true, selector: "kbq-select", inputs: { hiddenItemsText: { classPropertyName: "hiddenItemsText", publicName: "hiddenItemsText", isSignal: false, isRequired: false, transformFunction: null }, showPreselectedValues: { classPropertyName: "showPreselectedValues", publicName: "showPreselectedValues", isSignal: true, isRequired: false, transformFunction: null }, triggerValuesLimit: { classPropertyName: "triggerValuesLimit", publicName: "triggerValuesLimit", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, backdropClass: { classPropertyName: "backdropClass", publicName: "backdropClass", isSignal: true, isRequired: false, transformFunction: null }, errorStateMatcher: { classPropertyName: "errorStateMatcher", publicName: "errorStateMatcher", isSignal: false, isRequired: false, transformFunction: null }, sortComparator: { classPropertyName: "sortComparator", publicName: "sortComparator", isSignal: true, isRequired: false, transformFunction: null }, multiline: { classPropertyName: "multiline", publicName: "multiline", isSignal: true, isRequired: false, transformFunction: null }, searchMinOptionsThreshold: { classPropertyName: "searchMinOptionsThreshold", publicName: "searchMinOptionsThreshold", isSignal: false, isRequired: false, transformFunction: null }, scrolledToBottomOffset: { classPropertyName: "scrolledToBottomOffset", publicName: "scrolledToBottomOffset", isSignal: true, isRequired: false, transformFunction: null }, hasBackdrop: { classPropertyName: "hasBackdrop", publicName: "hasBackdrop", isSignal: false, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: false, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: false, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: false, isRequired: false, transformFunction: null }, virtualOptionFactory: { classPropertyName: "virtualOptionFactory", publicName: "virtualOptionFactory", isSignal: true, isRequired: false, transformFunction: null }, selectAllToggle: { classPropertyName: "selectAllToggle", publicName: "selectAllToggle", isSignal: true, isRequired: false, transformFunction: null }, selectAllHandler: { classPropertyName: "selectAllHandler", publicName: "selectAllHandler", isSignal: false, isRequired: false, transformFunction: null }, panelWidth: { classPropertyName: "panelWidth", publicName: "panelWidth", isSignal: false, isRequired: false, transformFunction: null }, panelMinWidth: { classPropertyName: "panelMinWidth", publicName: "panelMinWidth", isSignal: false, isRequired: false, transformFunction: numberAttribute }, value: { classPropertyName: "value", publicName: "value", isSignal: false, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: false, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: false, isRequired: false, transformFunction: numberAttribute }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, hiddenItemsTextFormatter: { classPropertyName: "hiddenItemsTextFormatter", publicName: "hiddenItemsTextFormatter", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { openedChange: "openedChange", beforeOpened: "beforeOpened", openedStream: "opened", closedStream: "closed", selectionChange: "selectionChange", onSelectAll: "onSelectAll", valueChange: "valueChange", scrolledToBottom: "scrolledToBottom" }, host: { listeners: { "click": "toggle()", "keydown": "handleKeydown($event)", "focus": "onFocus()", "blur": "onBlur()" }, properties: { "attr.tabindex": "tabIndex", "attr.disabled": "disabled || null", "class.kbq-select_multiple": "multiple", "class.kbq-select_multiline": "multiline()", "class.kbq-disabled": "disabled", "class.kbq-invalid": "errorState" }, classAttribute: "kbq-select" }, providers: [
1842
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelect, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1843
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.30", type: KbqSelect, isStandalone: true, selector: "kbq-select", inputs: { hiddenItemsText: { classPropertyName: "hiddenItemsText", publicName: "hiddenItemsText", isSignal: false, isRequired: false, transformFunction: null }, showPreselectedValues: { classPropertyName: "showPreselectedValues", publicName: "showPreselectedValues", isSignal: true, isRequired: false, transformFunction: null }, triggerValuesLimit: { classPropertyName: "triggerValuesLimit", publicName: "triggerValuesLimit", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null }, backdropClass: { classPropertyName: "backdropClass", publicName: "backdropClass", isSignal: true, isRequired: false, transformFunction: null }, errorStateMatcher: { classPropertyName: "errorStateMatcher", publicName: "errorStateMatcher", isSignal: false, isRequired: false, transformFunction: null }, sortComparator: { classPropertyName: "sortComparator", publicName: "sortComparator", isSignal: true, isRequired: false, transformFunction: null }, multiline: { classPropertyName: "multiline", publicName: "multiline", isSignal: true, isRequired: false, transformFunction: null }, searchMinOptionsThreshold: { classPropertyName: "searchMinOptionsThreshold", publicName: "searchMinOptionsThreshold", isSignal: false, isRequired: false, transformFunction: null }, scrolledToBottomOffset: { classPropertyName: "scrolledToBottomOffset", publicName: "scrolledToBottomOffset", isSignal: true, isRequired: false, transformFunction: null }, hasBackdrop: { classPropertyName: "hasBackdrop", publicName: "hasBackdrop", isSignal: false, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: false, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: false, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: false, isRequired: false, transformFunction: null }, virtualOptionFactory: { classPropertyName: "virtualOptionFactory", publicName: "virtualOptionFactory", isSignal: true, isRequired: false, transformFunction: null }, selectAllToggle: { classPropertyName: "selectAllToggle", publicName: "selectAllToggle", isSignal: true, isRequired: false, transformFunction: null }, selectAll: { classPropertyName: "selectAll", publicName: "selectAll", isSignal: true, isRequired: false, transformFunction: null }, selectAllHandler: { classPropertyName: "selectAllHandler", publicName: "selectAllHandler", isSignal: false, isRequired: false, transformFunction: null }, panelWidth: { classPropertyName: "panelWidth", publicName: "panelWidth", isSignal: true, isRequired: false, transformFunction: null }, panelMinWidth: { classPropertyName: "panelMinWidth", publicName: "panelMinWidth", isSignal: true, isRequired: false, transformFunction: null }, panelMaxWidth: { classPropertyName: "panelMaxWidth", publicName: "panelMaxWidth", isSignal: true, isRequired: false, transformFunction: null }, panelMaxHeight: { classPropertyName: "panelMaxHeight", publicName: "panelMaxHeight", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: false, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: false, isRequired: false, transformFunction: null }, tabIndex: { classPropertyName: "tabIndex", publicName: "tabIndex", isSignal: false, isRequired: false, transformFunction: numberAttribute }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, hiddenItemsTextFormatter: { classPropertyName: "hiddenItemsTextFormatter", publicName: "hiddenItemsTextFormatter", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { openedChange: "openedChange", beforeOpened: "beforeOpened", openedStream: "opened", closedStream: "closed", selectionChange: "selectionChange", onSelectAll: "onSelectAll", valueChange: "valueChange", scrolledToBottom: "scrolledToBottom" }, host: { listeners: { "click": "toggle()", "keydown": "handleKeydown($event)", "focus": "onFocus()", "blur": "onBlur()" }, properties: { "attr.tabindex": "tabIndex", "attr.disabled": "disabled || null", "class.kbq-select_multiple": "multiple", "class.kbq-select_multiline": "multiline()", "class.kbq-disabled": "disabled", "class.kbq-invalid": "errorState" }, classAttribute: "kbq-select" }, providers: [
1564
1844
  { provide: KbqFormFieldControl, useExisting: KbqSelect },
1845
+ kbqCleanerFactoryProvider((() => {
1846
+ const select = inject(KbqSelect);
1847
+ return {
1848
+ get control() {
1849
+ return select;
1850
+ },
1851
+ get keydownTarget() {
1852
+ return select.elementRef.nativeElement;
1853
+ },
1854
+ clearByEscape: false,
1855
+ clear: (() => select.clear())
1856
+ };
1857
+ })),
1565
1858
  { provide: KBQ_OPTION_PARENT_COMPONENT, useExisting: KbqSelect },
1566
- { provide: KBQ_PARENT_POPUP, useExisting: KbqSelect }
1567
- ], queries: [{ propertyName: "footer", first: true, predicate: KbqSelectFooter, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "cdkVirtualForOf", first: true, predicate: CdkVirtualForOf, descendants: true, isSignal: true }, { propertyName: "virtualScrollViewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true, isSignal: true }, { propertyName: "customTrigger", first: true, predicate: KbqSelectTrigger, descendants: true, isSignal: true }, { propertyName: "customMatcher", first: true, predicate: KbqSelectMatcher, descendants: true, isSignal: true }, { propertyName: "customTagTemplateRef", first: true, predicate: ["kbqSelectTagContent"], descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "cleaner", first: true, predicate: ["kbqSelectCleaner"], descendants: true, isSignal: true }, { propertyName: "optionGroups", predicate: KbqOptgroup, isSignal: true }, { propertyName: "search", first: true, predicate: KbqSelectSearch, descendants: true, isSignal: true }, { propertyName: "searchEmpty", first: true, predicate: KbqSelectSearchEmptyResult, descendants: true, isSignal: true }, { propertyName: "options", predicate: KbqOption, descendants: true }], viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "panel", first: true, predicate: ["panel"], descendants: true, isSignal: true }, { propertyName: "optionsContainer", first: true, predicate: ["optionsContainer"], descendants: true, isSignal: true }, { propertyName: "overlayDir", first: true, predicate: CdkConnectedOverlay, descendants: true }, { propertyName: "tags", predicate: KbqTag, descendants: true }], exportAs: ["kbqSelect"], usesInheritance: true, ngImport: i0, template: "<div\n #fallbackOverlayOrigin=\"cdkOverlayOrigin\"\n #trigger\n cdkOverlayOrigin\n class=\"kbq-select__trigger\"\n [class.kbq-select__trigger_empty]=\"empty\"\n [class.kbq-select__trigger_multiline]=\"multiline()\"\n [class.kbq-select__trigger_multiple]=\"multiple\"\n [class.kbq-select__trigger_single]=\"!multiple\"\n>\n @if (!!customMatcher()) {\n <ng-content select=\"kbq-select-matcher, [kbq-select-matcher]\" />\n } @else {\n <div class=\"kbq-select__matcher\">\n @if (empty) {\n <span class=\"kbq-select__placeholder\">\n {{ placeholder || '\\u00A0' }}\n </span>\n } @else {\n @if (!!customTrigger()) {\n <ng-content select=\"kbq-select-trigger, [kbq-select-trigger]\" />\n } @else {\n <div class=\"kbq-select__match-container\">\n @if (multiSelection) {\n <div\n [class.kbq-select__match-list]=\"!multiline()\"\n [class.kbq-select__multiline-match-list]=\"multiline()\"\n >\n @if (!customTagTemplateRef()) {\n @for (option of triggerValues; track option) {\n <kbq-tag\n [color]=\"colorForState\"\n [disabled]=\"option.disabled || disabled\"\n [selectable]=\"false\"\n >\n {{ option.viewValue }}\n @if (!option.disabled && !disabled) {\n <i\n kbq-icon=\"kbq-xmark-s_16\"\n kbqTagRemove\n (click)=\"onRemoveMatcherItem(option, $event)\"\n ></i>\n }\n </kbq-tag>\n }\n } @else {\n @for (option of triggerValues; track option) {\n <ng-container\n [ngTemplateOutlet]=\"$any(customTagTemplateRef())\"\n [ngTemplateOutletContext]=\"{ $implicit: option, select: this }\"\n />\n }\n }\n </div>\n\n @if (!multiline()) {\n <div\n class=\"kbq-select__match-hidden-text\"\n [style.display]=\"hiddenItems > 0 ? 'block' : 'none'\"\n >\n {{ hiddenItemsTextFormatter(hiddenItemsText, hiddenItems) }}\n </div>\n }\n } @else {\n <span class=\"kbq-select__matcher-text\">\n {{ triggerValue }}\n </span>\n }\n </div>\n }\n }\n\n @if (canShowCleaner) {\n <div\n class=\"kbq-select__cleaner\"\n (click)=\"clearValue($event)\"\n (keydown.enter)=\"clearValue($event)\"\n (keydown.space)=\"clearValue($event)\"\n >\n <ng-content select=\"kbq-cleaner\" />\n </div>\n }\n\n <div class=\"kbq-select__arrow-wrapper\">\n <i kbq-icon=\"kbq-chevron-down-s_16\" class=\"kbq-select__arrow\" [color]=\"colorForState\"></i>\n </div>\n </div>\n }\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayLockPosition\n [cdkConnectedOverlayBackdropClass]=\"backdropClass()\"\n [cdkConnectedOverlayHasBackdrop]=\"hasBackdrop\"\n [cdkConnectedOverlayMinWidth]=\"overlayMinWidth\"\n [cdkConnectedOverlayOffsetY]=\"offsetY\"\n [cdkConnectedOverlayOpen]=\"panelOpen\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin || fallbackOverlayOrigin\"\n [cdkConnectedOverlayPanelClass]=\"overlayPanelClass\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n [cdkConnectedOverlayWidth]=\"overlayWidth\"\n (attach)=\"onAttached()\"\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n>\n <div\n #panel\n cdkMonitorSubtreeFocus\n [class]=\"getPanelClasses()\"\n [style.font-size.px]=\"triggerFontSize\"\n [style.transformOrigin]=\"transformOrigin\"\n (click)=\"handleClick($event)\"\n (keydown)=\"handleKeydown($event)\"\n >\n @if (search() && shouldShowSearch()) {\n <div class=\"kbq-select__search-container\">\n <ng-content select=\"[kbqSelectSearch]\" />\n </div>\n }\n\n <div\n #optionsContainer\n class=\"kbq-select__content\"\n [class.kbq-scrollbar]=\"!withVirtualScroll\"\n [@fadeInContent]=\"'showing'\"\n (@fadeInContent.done)=\"panelDoneAnimatingStream.next($event.toState)\"\n >\n @if (isEmptySearchResult) {\n <ng-content select=\"[kbq-select-search-empty-result]\" />\n }\n <ng-content />\n </div>\n\n <ng-content select=\"kbq-select-footer,[kbq-select-footer]\" />\n </div>\n</ng-template>\n", styles: [".kbq-select{box-sizing:border-box;display:inline-block;width:100%;outline:none}.kbq-select .kbq-select__trigger{display:flex;box-sizing:border-box;position:relative;cursor:pointer;min-height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-border-width) * 2)}.kbq-select .kbq-select__trigger:not(.kbq-select__trigger_multiline){height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-border-width) * 2)}.kbq-select .kbq-select__trigger:not(.kbq-select__trigger_multiline) .kbq-select__matcher{overflow:hidden;white-space:nowrap}.kbq-select .kbq-select__matcher{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-grow:1;align-items:center}.kbq-select .kbq-select__matcher>span{flex:1;overflow:hidden}.kbq-select .kbq-select__trigger.kbq-select__trigger_single .kbq-select__matcher,.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple.kbq-select__trigger_empty .kbq-select__matcher{padding:var(--kbq-select-size-single-padding-vertical) var(--kbq-select-size-single-padding-right) var(--kbq-select-size-single-padding-vertical) var(--kbq-select-size-single-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher{padding:var(--kbq-select-size-multiple-padding-vertical) var(--kbq-select-size-multiple-padding-right) var(--kbq-select-size-multiple-padding-vertical) var(--kbq-select-size-multiple-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher .kbq-select__match-container{display:flex}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher .kbq-select__match-list{display:flex;flex-wrap:wrap;overflow:hidden;height:calc(var(--kbq-form-field-size-height) - var(--kbq-select-size-multiple-padding-vertical) * 2);max-height:calc(var(--kbq-form-field-size-height) - var(--kbq-select-size-multiple-padding-vertical) * 2);gap:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));margin-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs))}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__match-container{flex-direction:column}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__matcher{max-width:100%;padding:calc(var(--kbq-select-size-multiple-padding-vertical) - var(--kbq-size-border-width)) var(--kbq-select-size-multiple-padding-right) calc(var(--kbq-select-size-multiple-padding-vertical) - var(--kbq-size-border-width)) var(--kbq-select-size-multiple-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__cleaner,.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__arrow-wrapper{align-self:flex-start;align-items:center;height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-s));min-width:var(--kbq-form-field-size-addon-width)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__multiline-match-list{display:flex;flex-direction:row;flex-wrap:wrap;margin-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));gap:var(--kbq-size-xxs)}.kbq-select .kbq-select__match-container{width:100%;text-overflow:ellipsis;overflow:hidden}.kbq-select .kbq-select__match-container .kbq-select__match-hidden-text{flex:0 0 40px;align-self:center;padding-left:4px;padding-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));text-align:right}.kbq-select kbq-select-trigger,.kbq-select [kbq-select-trigger]{width:100%}.kbq-select .kbq-select__arrow-wrapper{display:flex;align-self:center;justify-content:center;min-width:var(--kbq-form-field-size-addon-width)}.kbq-form-field-appearance-fill .kbq-select .kbq-select__arrow-wrapper,.kbq-form-field-appearance-standard .kbq-select .kbq-select__arrow-wrapper{transform:translateY(-50%)}.kbq-form-field-appearance-outline .kbq-select .kbq-select__arrow-wrapper{transform:translateY(-25%)}.kbq-disabled.kbq-select .kbq-select__trigger{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.kbq-select__panel{min-width:100%;overflow:hidden;border-radius:var(--kbq-select-panel-size-border-radius, var(--kbq-size-border-radius))}.kbq-select__panel .kbq-option{font-size:inherit}.kbq-select__panel .kbq-select__no-options-message{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-direction:row;align-items:center;justify-content:center;box-sizing:border-box;position:relative;margin-bottom:var(--kbq-size-3xl);margin-top:var(--kbq-size-3xl);max-width:100%;height:var(--kbq-option-size-height, var(--kbq-size-3xl));cursor:default;outline:none;padding-left:var(--kbq-option-size-horizontal-padding, var(--kbq-size-m));padding-right:var(--kbq-option-size-horizontal-padding, var(--kbq-size-m));border:var(--kbq-option-size-border-width, var(--kbq-size-3xs)) solid transparent}.kbq-select__panel .kbq-select__search-container{padding:var(--kbq-size-xxs);border-bottom-width:1px;border-bottom-style:solid}.kbq-select__content{max-height:var(--kbq-select-panel-size-max-height, 256px);padding:var(--kbq-size-xxs);overflow:hidden auto}.kbq-select__panel .kbq-select__footer{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;align-items:center;box-sizing:border-box;min-height:40px;border-top-width:1px;border-top-style:solid;padding:var(--kbq-size-xxs) var(--kbq-size-l)}.kbq-select__content{box-sizing:initial}.kbq-select__content .kbq-option{position:relative}.kbq-select__content .kbq-option:before,.kbq-select__content .kbq-option:after{position:absolute;content:\"\";width:var(--kbq-size-xxs);height:calc(100% + var(--kbq-size-3xs) * 2)}.kbq-select__content .kbq-option:before{right:calc(100% + var(--kbq-size-3xs))}.kbq-select__content .kbq-option:after{left:calc(100% + var(--kbq-size-3xs))}.kbq-select__content:not(:has(>.kbq-select__no-options-message)) .cdk-virtual-scroll-viewport{min-height:var(--kbq-select-panel-size-max-height, 256px);max-height:var(--kbq-select-panel-size-max-height, 256px)}.kbq-select__content:not(:has(>.kbq-select__no-options-message)) .cdk-virtual-scroll-viewport.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper{max-width:100%}.kbq-form-field-type-select:not(.kbq-disabled) .kbq-form-field-flex{cursor:pointer}.kbq-select{color:var(--kbq-foreground-contrast)}.kbq-select.kbq-control_has-validate-directive.ng-invalid,.kbq-select.kbq-invalid{color:var(--kbq-foreground-error)}.kbq-select.kbq-control_has-validate-directive.ng-invalid .kbq-select__placeholder,.kbq-select.kbq-invalid .kbq-select__placeholder{color:var(--kbq-form-field-states-error-placeholder)}.kbq-select.kbq-disabled{color:var(--kbq-states-foreground-disabled)}.kbq-select.kbq-disabled .kbq-select__placeholder{color:var(--kbq-form-field-states-disabled-placeholder)}.kbq-select__placeholder{text-overflow:ellipsis;color:var(--kbq-form-field-default-placeholder)}.kbq-select__panel{box-shadow:var(--kbq-select-panel-dropdown-shadow);background:var(--kbq-select-panel-dropdown-background)}.kbq-select__panel .kbq-select__footer{border-color:var(--kbq-divider-color, var(--kbq-line-contrast-less))}.kbq-select__search-container{border-bottom-color:var(--kbq-divider-color, var(--kbq-line-contrast-less))}.kbq-select__no-options-message{color:var(--kbq-foreground-contrast-secondary)}.kbq-select,.kbq-select__panel{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}\n", ".kbq-select,.kbq-tree-select,.kbq-select__panel{--kbq-select-size-single-padding-left: 0;--kbq-select-size-single-padding-right: 0;--kbq-select-size-single-padding-vertical: var(--kbq-size-xs);--kbq-select-size-single-content-gap: var(--kbq-size-xxs);--kbq-select-size-multiple-padding-left: 0;--kbq-select-size-multiple-padding-right: 0;--kbq-select-size-multiple-padding-vertical: var(--kbq-size-xxs);--kbq-select-size-multiple-content-gap: var(--kbq-size-xxs);--kbq-select-panel-size-border-radius: var(--kbq-size-border-radius);--kbq-select-panel-size-max-height: 256px;--kbq-select-panel-dropdown-background: var(--kbq-background-card);--kbq-select-panel-dropdown-shadow: var(--kbq-shadow-popup)}\n"], dependencies: [{ kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: KbqTag, selector: "kbq-tag, [kbq-tag], kbq-basic-tag, [kbq-basic-tag]", inputs: ["editable", "preventEditSubmit", "selected", "value", "selectable", "removable", "tabindex", "disabled"], outputs: ["editChange", "selectionChange", "destroyed", "removed"], exportAs: ["kbqTag"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdkMonitorFocus, selector: "[cdkMonitorElementFocus], [cdkMonitorSubtreeFocus]", outputs: ["cdkFocusChange"], exportAs: ["cdkMonitorFocus"] }, { kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "ngmodule", type: KbqIconModule }, { kind: "component", type: i1$1.KbqIcon, selector: "[kbq-icon]", inputs: ["small", "autoColor", "kbq-icon"] }], animations: [
1859
+ { provide: KBQ_PARENT_POPUP, useExisting: KbqSelect },
1860
+ kbqSiblingPopupProvider(KbqSelect)
1861
+ ], queries: [{ propertyName: "footer", first: true, predicate: KbqSelectFooter, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "cdkVirtualForOf", first: true, predicate: CdkVirtualForOf, descendants: true, isSignal: true }, { propertyName: "virtualScrollViewport", first: true, predicate: CdkVirtualScrollViewport, descendants: true, isSignal: true }, { propertyName: "customTrigger", first: true, predicate: KbqSelectTrigger, descendants: true, isSignal: true }, { propertyName: "customMatcher", first: true, predicate: KbqSelectMatcher, descendants: true, isSignal: true }, { propertyName: "customTagTemplateRef", first: true, predicate: ["kbqSelectTagContent"], descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "cleaner", first: true, predicate: KbqCleaner, isSignal: true }, { propertyName: "optionGroups", predicate: KbqOptgroup, isSignal: true }, { propertyName: "search", first: true, predicate: KbqSelectSearch, descendants: true, isSignal: true }, { propertyName: "searchEmpty", first: true, predicate: KbqSelectSearchEmptyResult, descendants: true, isSignal: true }, { propertyName: "options", predicate: KbqOption, descendants: true }], viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }, { propertyName: "panel", first: true, predicate: ["panel"], descendants: true, isSignal: true }, { propertyName: "optionsContainer", first: true, predicate: ["optionsContainer"], descendants: true, isSignal: true }, { propertyName: "selectAllOption", first: true, predicate: KbqOption, descendants: true, isSignal: true }, { propertyName: "overlayDir", first: true, predicate: CdkConnectedOverlay, descendants: true }, { propertyName: "tags", predicate: KbqTag, descendants: true }], exportAs: ["kbqSelect"], usesInheritance: true, ngImport: i0, template: "<div\n #fallbackOverlayOrigin=\"cdkOverlayOrigin\"\n #trigger\n cdkOverlayOrigin\n class=\"kbq-select__trigger\"\n [class.kbq-select__trigger_empty]=\"empty\"\n [class.kbq-select__trigger_multiline]=\"multiline()\"\n [class.kbq-select__trigger_multiple]=\"multiple\"\n [class.kbq-select__trigger_single]=\"!multiple\"\n>\n @if (!!customMatcher()) {\n <ng-content select=\"kbq-select-matcher, [kbq-select-matcher]\" />\n } @else {\n <div class=\"kbq-select__matcher\">\n @if (empty) {\n <span class=\"kbq-select__placeholder\">\n {{ placeholder || '\\u00A0' }}\n </span>\n } @else {\n @if (!!customTrigger()) {\n <ng-content select=\"kbq-select-trigger, [kbq-select-trigger]\" />\n } @else {\n <div class=\"kbq-select__match-container\">\n @if (multiSelection) {\n <div\n #multilineMatchList\n [class.kbq-select__match-list]=\"!multiline()\"\n [class.kbq-select__multiline-match-list]=\"multiline()\"\n >\n @if (!customTagTemplateRef()) {\n @for (option of triggerValues; track option) {\n <kbq-tag\n [color]=\"colorForState\"\n [disabled]=\"option.disabled || disabled\"\n [selectable]=\"false\"\n >\n {{ option.viewValue }}\n @if (!option.disabled && !disabled) {\n <i\n kbq-icon=\"kbq-xmark-s_16\"\n kbqTagRemove\n (click)=\"onRemoveMatcherItem(option, $event)\"\n ></i>\n }\n </kbq-tag>\n }\n } @else {\n @for (option of triggerValues; track option) {\n <ng-container\n [ngTemplateOutlet]=\"$any(customTagTemplateRef())\"\n [ngTemplateOutletContext]=\"{ $implicit: option, select: this }\"\n />\n }\n }\n </div>\n\n @if (!multiline()) {\n <div\n class=\"kbq-select__match-hidden-text\"\n [style.display]=\"hiddenItems > 0 ? 'block' : 'none'\"\n >\n {{ hiddenItemsTextFormatter(hiddenItemsText, hiddenItems) }}\n </div>\n }\n } @else {\n <span class=\"kbq-select__matcher-text\">\n {{ triggerValue }}\n </span>\n }\n </div>\n }\n }\n\n @if (canShowCleaner) {\n <div class=\"kbq-select__cleaner\">\n <ng-content select=\"kbq-cleaner\" />\n </div>\n }\n\n <div class=\"kbq-select__arrow-wrapper\">\n <i kbq-icon=\"kbq-chevron-down-s_16\" class=\"kbq-select__arrow\" [color]=\"colorForState\"></i>\n </div>\n </div>\n }\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayLockPosition\n [cdkConnectedOverlayBackdropClass]=\"backdropClass()\"\n [cdkConnectedOverlayHasBackdrop]=\"hasBackdrop\"\n [cdkConnectedOverlayMinWidth]=\"overlayMinWidth\"\n [cdkConnectedOverlayOpen]=\"panelOpen\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin || fallbackOverlayOrigin\"\n [cdkConnectedOverlayPanelClass]=\"overlayPanelClass\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n [cdkConnectedOverlayViewportMargin]=\"viewportMargin\"\n [cdkConnectedOverlayWidth]=\"overlayWidth\"\n (attach)=\"onAttached()\"\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n>\n <div\n #panel\n cdkMonitorSubtreeFocus\n [class]=\"getPanelClasses()\"\n [style.--kbq-select-panel-size-max-height]=\"panelMaxHeightToken()\"\n [style.font-size.px]=\"triggerFontSize\"\n [style.max-width.px]=\"panelMaxWidth()\"\n [style.transformOrigin]=\"transformOrigin\"\n (click)=\"handleClick($event)\"\n (keydown)=\"handleKeydown($event)\"\n >\n @if (search() && shouldShowSearch()) {\n <div class=\"kbq-select__search-container\">\n <ng-content select=\"[kbqSelectSearch]\" />\n </div>\n }\n\n <div\n #optionsContainer\n class=\"kbq-select__content\"\n [class.kbq-scrollbar]=\"!withVirtualScroll\"\n [@fadeInContent]=\"'showing'\"\n (@fadeInContent.done)=\"panelDoneAnimatingStream.next($event.toState)\"\n >\n @if (isEmptySearchResult) {\n <ng-content select=\"[kbq-select-search-empty-result]\" />\n }\n @if (showSelectAll) {\n <!-- Every read of selectAllState re-filters the whole option list, and allOptionsSelected\n is that same walk asking whether the state is \"checked\" \u2014 one read covers all four. -->\n @let selectAllCheckboxState = selectAllState;\n\n <kbq-option\n class=\"kbq-select__select-all\"\n [selectable]=\"false\"\n [class.kbq-selected]=\"selectAllCheckboxState === 'checked'\"\n [attr.role]=\"'checkbox'\"\n [attr.aria-checked]=\"\n selectAllCheckboxState === 'indeterminate' ? 'mixed' : selectAllCheckboxState === 'checked'\n \"\n (click)=\"toggleSelectAll()\"\n >\n <kbq-pseudo-checkbox [state]=\"selectAllCheckboxState\" />\n {{ selectAllText }}\n </kbq-option>\n }\n <ng-content />\n </div>\n\n <ng-content select=\"kbq-select-footer,[kbq-select-footer]\" />\n </div>\n</ng-template>\n", styles: [".kbq-select{box-sizing:border-box;display:inline-block;width:100%;outline:none}.kbq-select .kbq-select__trigger{display:flex;box-sizing:border-box;position:relative;cursor:pointer;min-height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-border-width) * 2)}.kbq-select .kbq-select__trigger:not(.kbq-select__trigger_multiline){height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-border-width) * 2)}.kbq-select .kbq-select__trigger:not(.kbq-select__trigger_multiline) .kbq-select__matcher{overflow:hidden;white-space:nowrap}.kbq-select .kbq-select__matcher{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-grow:1;align-items:center}.kbq-select .kbq-select__matcher>span{flex:1;overflow:hidden}.kbq-select .kbq-select__trigger.kbq-select__trigger_single .kbq-select__matcher,.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple.kbq-select__trigger_empty .kbq-select__matcher{padding:var(--kbq-select-size-single-padding-vertical) var(--kbq-select-size-single-padding-right) var(--kbq-select-size-single-padding-vertical) var(--kbq-select-size-single-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher{padding:var(--kbq-select-size-multiple-padding-vertical) var(--kbq-select-size-multiple-padding-right) var(--kbq-select-size-multiple-padding-vertical) var(--kbq-select-size-multiple-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher .kbq-select__match-container{display:flex}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher .kbq-select__match-list{display:flex;flex-wrap:wrap;overflow:hidden;height:calc(var(--kbq-form-field-size-height) - var(--kbq-select-size-multiple-padding-vertical) * 2);max-height:calc(var(--kbq-form-field-size-height) - var(--kbq-select-size-multiple-padding-vertical) * 2);gap:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));margin-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs))}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__match-container{flex-direction:column}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__matcher{max-width:100%;padding:calc(var(--kbq-select-size-multiple-padding-vertical) - var(--kbq-size-border-width)) var(--kbq-select-size-multiple-padding-right) calc(var(--kbq-select-size-multiple-padding-vertical) - var(--kbq-size-border-width)) var(--kbq-select-size-multiple-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__cleaner,.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__arrow-wrapper{align-self:flex-start;align-items:center;height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-s));min-width:var(--kbq-form-field-size-addon-width)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__multiline-match-list{display:flex;flex-direction:row;flex-wrap:wrap;margin-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));gap:var(--kbq-size-xxs)}.kbq-select .kbq-select__match-container{width:100%;text-overflow:ellipsis;overflow:hidden}.kbq-select .kbq-select__match-container .kbq-select__match-hidden-text{box-sizing:content-box;flex:0 0 var(--kbq-form-field-size-addon-width);align-self:center;padding-left:var(--kbq-size-xxs);padding-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));text-align:right}.kbq-select kbq-select-trigger,.kbq-select [kbq-select-trigger]{width:100%}.kbq-select .kbq-select__arrow-wrapper{display:flex;align-self:center;justify-content:center;min-width:var(--kbq-form-field-size-addon-width)}.kbq-form-field-appearance-fill .kbq-select .kbq-select__arrow-wrapper,.kbq-form-field-appearance-standard .kbq-select .kbq-select__arrow-wrapper{transform:translateY(-50%)}.kbq-form-field-appearance-outline .kbq-select .kbq-select__arrow-wrapper{transform:translateY(-25%)}.kbq-disabled.kbq-select .kbq-select__trigger{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.kbq-select__panel{min-width:100%;max-width:var(--kbq-panel-size-width-max, 640px);overflow:hidden;border-radius:var(--kbq-select-panel-size-border-radius, var(--kbq-size-border-radius))}.kbq-select__panel .kbq-option{font-size:inherit}.kbq-select__panel .kbq-select__no-options-message{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-direction:row;align-items:center;justify-content:center;box-sizing:border-box;position:relative;margin-bottom:var(--kbq-size-3xl);margin-top:var(--kbq-size-3xl);max-width:100%;height:var(--kbq-option-size-height, var(--kbq-size-3xl));cursor:default;outline:none;padding-left:var(--kbq-option-size-horizontal-padding, var(--kbq-size-m));padding-right:var(--kbq-option-size-horizontal-padding, var(--kbq-size-m));border:var(--kbq-option-size-border-width, var(--kbq-size-3xs)) solid transparent}.kbq-select__panel .kbq-select__search-container{padding:var(--kbq-size-xxs);border-bottom-width:1px;border-bottom-style:solid}.kbq-select__content{box-sizing:initial;max-height:var(--kbq-select-panel-size-max-height, 256px);padding:var(--kbq-size-xxs);overflow:hidden auto}.kbq-select__panel .kbq-select__footer{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;align-items:center;box-sizing:border-box;min-height:40px;border-top-width:1px;border-top-style:solid;padding:var(--kbq-size-xxs) var(--kbq-size-l)}.kbq-select__content .kbq-option{position:relative}.kbq-select__content .kbq-option:before,.kbq-select__content .kbq-option:after{position:absolute;content:\"\";width:var(--kbq-size-xxs);height:calc(100% + var(--kbq-size-3xs) * 2)}.kbq-select__content .kbq-option:before{right:calc(100% + var(--kbq-size-3xs))}.kbq-select__content .kbq-option:after{left:calc(100% + var(--kbq-size-3xs))}.kbq-select__content:not(:has(>.kbq-select__no-options-message)) .cdk-virtual-scroll-viewport{min-height:var(--kbq-select-panel-size-max-height, 256px);max-height:var(--kbq-select-panel-size-max-height, 256px)}.kbq-select__content:not(:has(>.kbq-select__no-options-message)) .cdk-virtual-scroll-viewport.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper{max-width:100%}.kbq-form-field-type-select:not(.kbq-disabled) .kbq-form-field-flex{cursor:pointer}.kbq-select{color:var(--kbq-foreground-contrast)}.kbq-select.kbq-control_has-validate-directive.ng-invalid,.kbq-select.kbq-invalid{color:var(--kbq-foreground-error)}.kbq-select.kbq-control_has-validate-directive.ng-invalid .kbq-select__placeholder,.kbq-select.kbq-invalid .kbq-select__placeholder{color:var(--kbq-form-field-states-error-placeholder)}.kbq-select.kbq-disabled{color:var(--kbq-states-foreground-disabled)}.kbq-select.kbq-disabled .kbq-select__placeholder{color:var(--kbq-form-field-states-disabled-placeholder)}.kbq-select__placeholder{text-overflow:ellipsis;color:var(--kbq-form-field-default-placeholder)}.kbq-select__panel{box-shadow:var(--kbq-select-panel-dropdown-shadow);background:var(--kbq-select-panel-dropdown-background)}.kbq-select__panel .kbq-select__footer{border-color:var(--kbq-divider-color, var(--kbq-line-contrast-less))}.kbq-select__search-container{border-bottom-color:var(--kbq-divider-color, var(--kbq-line-contrast-less))}.kbq-select__no-options-message{color:var(--kbq-foreground-contrast-secondary)}.kbq-select,.kbq-select__panel{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}\n", ".kbq-select,.kbq-tree-select,.kbq-select__panel{--kbq-select-size-single-padding-left: 0;--kbq-select-size-single-padding-right: 0;--kbq-select-size-single-padding-vertical: var(--kbq-size-xs);--kbq-select-size-single-content-gap: var(--kbq-size-xxs);--kbq-select-size-multiple-padding-left: 0;--kbq-select-size-multiple-padding-right: 0;--kbq-select-size-multiple-padding-vertical: var(--kbq-size-xxs);--kbq-select-size-multiple-content-gap: var(--kbq-size-xxs);--kbq-select-panel-size-border-radius: var(--kbq-size-border-radius);--kbq-select-panel-dropdown-background: var(--kbq-background-card);--kbq-select-panel-dropdown-shadow: var(--kbq-shadow-popup)}\n"], dependencies: [{ kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: KbqTag, selector: "kbq-tag, [kbq-tag], kbq-basic-tag, [kbq-basic-tag]", inputs: ["editable", "preventEditSubmit", "selected", "value", "selectable", "removable", "tabindex", "disabled"], outputs: ["editChange", "selectionChange", "destroyed", "removed"], exportAs: ["kbqTag"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: CdkMonitorFocus, selector: "[cdkMonitorElementFocus], [cdkMonitorSubtreeFocus]", outputs: ["cdkFocusChange"], exportAs: ["cdkMonitorFocus"] }, { kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "ngmodule", type: KbqIconModule }, { kind: "component", type: i1$1.KbqIcon, selector: "[kbq-icon]", inputs: ["small", "autoColor", "kbq-icon"] }, { kind: "component", type: KbqOption, selector: "kbq-option", inputs: ["value", "selectable", "userSelect", "showCheckbox", "viewValue", "disabled"], outputs: ["onSelectionChange"], exportAs: ["kbqOption"] }, { kind: "component", type: KbqPseudoCheckbox, selector: "kbq-pseudo-checkbox", inputs: ["big", "state", "disabled"] }], animations: [
1568
1862
  kbqSelectAnimations.transformPanel,
1569
1863
  kbqSelectAnimations.fadeInContent
1570
1864
  ], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
1571
1865
  }
1572
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: KbqSelect, decorators: [{
1866
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelect, decorators: [{
1573
1867
  type: Component,
1574
1868
  args: [{ selector: 'kbq-select', imports: [
1575
1869
  CdkOverlayOrigin,
@@ -1577,11 +1871,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
1577
1871
  NgTemplateOutlet,
1578
1872
  CdkMonitorFocus,
1579
1873
  CdkConnectedOverlay,
1580
- KbqIconModule
1874
+ KbqIconModule,
1875
+ KbqOption,
1876
+ KbqPseudoCheckbox
1581
1877
  ], providers: [
1582
1878
  { provide: KbqFormFieldControl, useExisting: KbqSelect },
1879
+ kbqCleanerFactoryProvider((() => {
1880
+ const select = inject(KbqSelect);
1881
+ return {
1882
+ get control() {
1883
+ return select;
1884
+ },
1885
+ get keydownTarget() {
1886
+ return select.elementRef.nativeElement;
1887
+ },
1888
+ clearByEscape: false,
1889
+ clear: (() => select.clear())
1890
+ };
1891
+ })),
1583
1892
  { provide: KBQ_OPTION_PARENT_COMPONENT, useExisting: KbqSelect },
1584
- { provide: KBQ_PARENT_POPUP, useExisting: KbqSelect }
1893
+ { provide: KBQ_PARENT_POPUP, useExisting: KbqSelect },
1894
+ kbqSiblingPopupProvider(KbqSelect)
1585
1895
  ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
1586
1896
  '[attr.tabindex]': 'tabIndex',
1587
1897
  '[attr.disabled]': 'disabled || null',
@@ -1597,14 +1907,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
1597
1907
  }, animations: [
1598
1908
  kbqSelectAnimations.transformPanel,
1599
1909
  kbqSelectAnimations.fadeInContent
1600
- ], exportAs: 'kbqSelect', template: "<div\n #fallbackOverlayOrigin=\"cdkOverlayOrigin\"\n #trigger\n cdkOverlayOrigin\n class=\"kbq-select__trigger\"\n [class.kbq-select__trigger_empty]=\"empty\"\n [class.kbq-select__trigger_multiline]=\"multiline()\"\n [class.kbq-select__trigger_multiple]=\"multiple\"\n [class.kbq-select__trigger_single]=\"!multiple\"\n>\n @if (!!customMatcher()) {\n <ng-content select=\"kbq-select-matcher, [kbq-select-matcher]\" />\n } @else {\n <div class=\"kbq-select__matcher\">\n @if (empty) {\n <span class=\"kbq-select__placeholder\">\n {{ placeholder || '\\u00A0' }}\n </span>\n } @else {\n @if (!!customTrigger()) {\n <ng-content select=\"kbq-select-trigger, [kbq-select-trigger]\" />\n } @else {\n <div class=\"kbq-select__match-container\">\n @if (multiSelection) {\n <div\n [class.kbq-select__match-list]=\"!multiline()\"\n [class.kbq-select__multiline-match-list]=\"multiline()\"\n >\n @if (!customTagTemplateRef()) {\n @for (option of triggerValues; track option) {\n <kbq-tag\n [color]=\"colorForState\"\n [disabled]=\"option.disabled || disabled\"\n [selectable]=\"false\"\n >\n {{ option.viewValue }}\n @if (!option.disabled && !disabled) {\n <i\n kbq-icon=\"kbq-xmark-s_16\"\n kbqTagRemove\n (click)=\"onRemoveMatcherItem(option, $event)\"\n ></i>\n }\n </kbq-tag>\n }\n } @else {\n @for (option of triggerValues; track option) {\n <ng-container\n [ngTemplateOutlet]=\"$any(customTagTemplateRef())\"\n [ngTemplateOutletContext]=\"{ $implicit: option, select: this }\"\n />\n }\n }\n </div>\n\n @if (!multiline()) {\n <div\n class=\"kbq-select__match-hidden-text\"\n [style.display]=\"hiddenItems > 0 ? 'block' : 'none'\"\n >\n {{ hiddenItemsTextFormatter(hiddenItemsText, hiddenItems) }}\n </div>\n }\n } @else {\n <span class=\"kbq-select__matcher-text\">\n {{ triggerValue }}\n </span>\n }\n </div>\n }\n }\n\n @if (canShowCleaner) {\n <div\n class=\"kbq-select__cleaner\"\n (click)=\"clearValue($event)\"\n (keydown.enter)=\"clearValue($event)\"\n (keydown.space)=\"clearValue($event)\"\n >\n <ng-content select=\"kbq-cleaner\" />\n </div>\n }\n\n <div class=\"kbq-select__arrow-wrapper\">\n <i kbq-icon=\"kbq-chevron-down-s_16\" class=\"kbq-select__arrow\" [color]=\"colorForState\"></i>\n </div>\n </div>\n }\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayLockPosition\n [cdkConnectedOverlayBackdropClass]=\"backdropClass()\"\n [cdkConnectedOverlayHasBackdrop]=\"hasBackdrop\"\n [cdkConnectedOverlayMinWidth]=\"overlayMinWidth\"\n [cdkConnectedOverlayOffsetY]=\"offsetY\"\n [cdkConnectedOverlayOpen]=\"panelOpen\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin || fallbackOverlayOrigin\"\n [cdkConnectedOverlayPanelClass]=\"overlayPanelClass\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n [cdkConnectedOverlayWidth]=\"overlayWidth\"\n (attach)=\"onAttached()\"\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n>\n <div\n #panel\n cdkMonitorSubtreeFocus\n [class]=\"getPanelClasses()\"\n [style.font-size.px]=\"triggerFontSize\"\n [style.transformOrigin]=\"transformOrigin\"\n (click)=\"handleClick($event)\"\n (keydown)=\"handleKeydown($event)\"\n >\n @if (search() && shouldShowSearch()) {\n <div class=\"kbq-select__search-container\">\n <ng-content select=\"[kbqSelectSearch]\" />\n </div>\n }\n\n <div\n #optionsContainer\n class=\"kbq-select__content\"\n [class.kbq-scrollbar]=\"!withVirtualScroll\"\n [@fadeInContent]=\"'showing'\"\n (@fadeInContent.done)=\"panelDoneAnimatingStream.next($event.toState)\"\n >\n @if (isEmptySearchResult) {\n <ng-content select=\"[kbq-select-search-empty-result]\" />\n }\n <ng-content />\n </div>\n\n <ng-content select=\"kbq-select-footer,[kbq-select-footer]\" />\n </div>\n</ng-template>\n", styles: [".kbq-select{box-sizing:border-box;display:inline-block;width:100%;outline:none}.kbq-select .kbq-select__trigger{display:flex;box-sizing:border-box;position:relative;cursor:pointer;min-height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-border-width) * 2)}.kbq-select .kbq-select__trigger:not(.kbq-select__trigger_multiline){height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-border-width) * 2)}.kbq-select .kbq-select__trigger:not(.kbq-select__trigger_multiline) .kbq-select__matcher{overflow:hidden;white-space:nowrap}.kbq-select .kbq-select__matcher{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-grow:1;align-items:center}.kbq-select .kbq-select__matcher>span{flex:1;overflow:hidden}.kbq-select .kbq-select__trigger.kbq-select__trigger_single .kbq-select__matcher,.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple.kbq-select__trigger_empty .kbq-select__matcher{padding:var(--kbq-select-size-single-padding-vertical) var(--kbq-select-size-single-padding-right) var(--kbq-select-size-single-padding-vertical) var(--kbq-select-size-single-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher{padding:var(--kbq-select-size-multiple-padding-vertical) var(--kbq-select-size-multiple-padding-right) var(--kbq-select-size-multiple-padding-vertical) var(--kbq-select-size-multiple-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher .kbq-select__match-container{display:flex}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher .kbq-select__match-list{display:flex;flex-wrap:wrap;overflow:hidden;height:calc(var(--kbq-form-field-size-height) - var(--kbq-select-size-multiple-padding-vertical) * 2);max-height:calc(var(--kbq-form-field-size-height) - var(--kbq-select-size-multiple-padding-vertical) * 2);gap:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));margin-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs))}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__match-container{flex-direction:column}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__matcher{max-width:100%;padding:calc(var(--kbq-select-size-multiple-padding-vertical) - var(--kbq-size-border-width)) var(--kbq-select-size-multiple-padding-right) calc(var(--kbq-select-size-multiple-padding-vertical) - var(--kbq-size-border-width)) var(--kbq-select-size-multiple-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__cleaner,.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__arrow-wrapper{align-self:flex-start;align-items:center;height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-s));min-width:var(--kbq-form-field-size-addon-width)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__multiline-match-list{display:flex;flex-direction:row;flex-wrap:wrap;margin-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));gap:var(--kbq-size-xxs)}.kbq-select .kbq-select__match-container{width:100%;text-overflow:ellipsis;overflow:hidden}.kbq-select .kbq-select__match-container .kbq-select__match-hidden-text{flex:0 0 40px;align-self:center;padding-left:4px;padding-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));text-align:right}.kbq-select kbq-select-trigger,.kbq-select [kbq-select-trigger]{width:100%}.kbq-select .kbq-select__arrow-wrapper{display:flex;align-self:center;justify-content:center;min-width:var(--kbq-form-field-size-addon-width)}.kbq-form-field-appearance-fill .kbq-select .kbq-select__arrow-wrapper,.kbq-form-field-appearance-standard .kbq-select .kbq-select__arrow-wrapper{transform:translateY(-50%)}.kbq-form-field-appearance-outline .kbq-select .kbq-select__arrow-wrapper{transform:translateY(-25%)}.kbq-disabled.kbq-select .kbq-select__trigger{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.kbq-select__panel{min-width:100%;overflow:hidden;border-radius:var(--kbq-select-panel-size-border-radius, var(--kbq-size-border-radius))}.kbq-select__panel .kbq-option{font-size:inherit}.kbq-select__panel .kbq-select__no-options-message{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-direction:row;align-items:center;justify-content:center;box-sizing:border-box;position:relative;margin-bottom:var(--kbq-size-3xl);margin-top:var(--kbq-size-3xl);max-width:100%;height:var(--kbq-option-size-height, var(--kbq-size-3xl));cursor:default;outline:none;padding-left:var(--kbq-option-size-horizontal-padding, var(--kbq-size-m));padding-right:var(--kbq-option-size-horizontal-padding, var(--kbq-size-m));border:var(--kbq-option-size-border-width, var(--kbq-size-3xs)) solid transparent}.kbq-select__panel .kbq-select__search-container{padding:var(--kbq-size-xxs);border-bottom-width:1px;border-bottom-style:solid}.kbq-select__content{max-height:var(--kbq-select-panel-size-max-height, 256px);padding:var(--kbq-size-xxs);overflow:hidden auto}.kbq-select__panel .kbq-select__footer{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;align-items:center;box-sizing:border-box;min-height:40px;border-top-width:1px;border-top-style:solid;padding:var(--kbq-size-xxs) var(--kbq-size-l)}.kbq-select__content{box-sizing:initial}.kbq-select__content .kbq-option{position:relative}.kbq-select__content .kbq-option:before,.kbq-select__content .kbq-option:after{position:absolute;content:\"\";width:var(--kbq-size-xxs);height:calc(100% + var(--kbq-size-3xs) * 2)}.kbq-select__content .kbq-option:before{right:calc(100% + var(--kbq-size-3xs))}.kbq-select__content .kbq-option:after{left:calc(100% + var(--kbq-size-3xs))}.kbq-select__content:not(:has(>.kbq-select__no-options-message)) .cdk-virtual-scroll-viewport{min-height:var(--kbq-select-panel-size-max-height, 256px);max-height:var(--kbq-select-panel-size-max-height, 256px)}.kbq-select__content:not(:has(>.kbq-select__no-options-message)) .cdk-virtual-scroll-viewport.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper{max-width:100%}.kbq-form-field-type-select:not(.kbq-disabled) .kbq-form-field-flex{cursor:pointer}.kbq-select{color:var(--kbq-foreground-contrast)}.kbq-select.kbq-control_has-validate-directive.ng-invalid,.kbq-select.kbq-invalid{color:var(--kbq-foreground-error)}.kbq-select.kbq-control_has-validate-directive.ng-invalid .kbq-select__placeholder,.kbq-select.kbq-invalid .kbq-select__placeholder{color:var(--kbq-form-field-states-error-placeholder)}.kbq-select.kbq-disabled{color:var(--kbq-states-foreground-disabled)}.kbq-select.kbq-disabled .kbq-select__placeholder{color:var(--kbq-form-field-states-disabled-placeholder)}.kbq-select__placeholder{text-overflow:ellipsis;color:var(--kbq-form-field-default-placeholder)}.kbq-select__panel{box-shadow:var(--kbq-select-panel-dropdown-shadow);background:var(--kbq-select-panel-dropdown-background)}.kbq-select__panel .kbq-select__footer{border-color:var(--kbq-divider-color, var(--kbq-line-contrast-less))}.kbq-select__search-container{border-bottom-color:var(--kbq-divider-color, var(--kbq-line-contrast-less))}.kbq-select__no-options-message{color:var(--kbq-foreground-contrast-secondary)}.kbq-select,.kbq-select__panel{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}\n", ".kbq-select,.kbq-tree-select,.kbq-select__panel{--kbq-select-size-single-padding-left: 0;--kbq-select-size-single-padding-right: 0;--kbq-select-size-single-padding-vertical: var(--kbq-size-xs);--kbq-select-size-single-content-gap: var(--kbq-size-xxs);--kbq-select-size-multiple-padding-left: 0;--kbq-select-size-multiple-padding-right: 0;--kbq-select-size-multiple-padding-vertical: var(--kbq-size-xxs);--kbq-select-size-multiple-content-gap: var(--kbq-size-xxs);--kbq-select-panel-size-border-radius: var(--kbq-size-border-radius);--kbq-select-panel-size-max-height: 256px;--kbq-select-panel-dropdown-background: var(--kbq-background-card);--kbq-select-panel-dropdown-shadow: var(--kbq-shadow-popup)}\n"] }]
1601
- }], ctorParameters: () => [], propDecorators: { trigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], panel: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }], optionsContainer: [{ type: i0.ViewChild, args: ['optionsContainer', { isSignal: true }] }], overlayDir: [{
1910
+ ], exportAs: 'kbqSelect', template: "<div\n #fallbackOverlayOrigin=\"cdkOverlayOrigin\"\n #trigger\n cdkOverlayOrigin\n class=\"kbq-select__trigger\"\n [class.kbq-select__trigger_empty]=\"empty\"\n [class.kbq-select__trigger_multiline]=\"multiline()\"\n [class.kbq-select__trigger_multiple]=\"multiple\"\n [class.kbq-select__trigger_single]=\"!multiple\"\n>\n @if (!!customMatcher()) {\n <ng-content select=\"kbq-select-matcher, [kbq-select-matcher]\" />\n } @else {\n <div class=\"kbq-select__matcher\">\n @if (empty) {\n <span class=\"kbq-select__placeholder\">\n {{ placeholder || '\\u00A0' }}\n </span>\n } @else {\n @if (!!customTrigger()) {\n <ng-content select=\"kbq-select-trigger, [kbq-select-trigger]\" />\n } @else {\n <div class=\"kbq-select__match-container\">\n @if (multiSelection) {\n <div\n #multilineMatchList\n [class.kbq-select__match-list]=\"!multiline()\"\n [class.kbq-select__multiline-match-list]=\"multiline()\"\n >\n @if (!customTagTemplateRef()) {\n @for (option of triggerValues; track option) {\n <kbq-tag\n [color]=\"colorForState\"\n [disabled]=\"option.disabled || disabled\"\n [selectable]=\"false\"\n >\n {{ option.viewValue }}\n @if (!option.disabled && !disabled) {\n <i\n kbq-icon=\"kbq-xmark-s_16\"\n kbqTagRemove\n (click)=\"onRemoveMatcherItem(option, $event)\"\n ></i>\n }\n </kbq-tag>\n }\n } @else {\n @for (option of triggerValues; track option) {\n <ng-container\n [ngTemplateOutlet]=\"$any(customTagTemplateRef())\"\n [ngTemplateOutletContext]=\"{ $implicit: option, select: this }\"\n />\n }\n }\n </div>\n\n @if (!multiline()) {\n <div\n class=\"kbq-select__match-hidden-text\"\n [style.display]=\"hiddenItems > 0 ? 'block' : 'none'\"\n >\n {{ hiddenItemsTextFormatter(hiddenItemsText, hiddenItems) }}\n </div>\n }\n } @else {\n <span class=\"kbq-select__matcher-text\">\n {{ triggerValue }}\n </span>\n }\n </div>\n }\n }\n\n @if (canShowCleaner) {\n <div class=\"kbq-select__cleaner\">\n <ng-content select=\"kbq-cleaner\" />\n </div>\n }\n\n <div class=\"kbq-select__arrow-wrapper\">\n <i kbq-icon=\"kbq-chevron-down-s_16\" class=\"kbq-select__arrow\" [color]=\"colorForState\"></i>\n </div>\n </div>\n }\n</div>\n\n<ng-template\n cdkConnectedOverlay\n cdkConnectedOverlayLockPosition\n [cdkConnectedOverlayBackdropClass]=\"backdropClass()\"\n [cdkConnectedOverlayHasBackdrop]=\"hasBackdrop\"\n [cdkConnectedOverlayMinWidth]=\"overlayMinWidth\"\n [cdkConnectedOverlayOpen]=\"panelOpen\"\n [cdkConnectedOverlayOrigin]=\"overlayOrigin || fallbackOverlayOrigin\"\n [cdkConnectedOverlayPanelClass]=\"overlayPanelClass\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n [cdkConnectedOverlayViewportMargin]=\"viewportMargin\"\n [cdkConnectedOverlayWidth]=\"overlayWidth\"\n (attach)=\"onAttached()\"\n (backdropClick)=\"close()\"\n (detach)=\"close()\"\n>\n <div\n #panel\n cdkMonitorSubtreeFocus\n [class]=\"getPanelClasses()\"\n [style.--kbq-select-panel-size-max-height]=\"panelMaxHeightToken()\"\n [style.font-size.px]=\"triggerFontSize\"\n [style.max-width.px]=\"panelMaxWidth()\"\n [style.transformOrigin]=\"transformOrigin\"\n (click)=\"handleClick($event)\"\n (keydown)=\"handleKeydown($event)\"\n >\n @if (search() && shouldShowSearch()) {\n <div class=\"kbq-select__search-container\">\n <ng-content select=\"[kbqSelectSearch]\" />\n </div>\n }\n\n <div\n #optionsContainer\n class=\"kbq-select__content\"\n [class.kbq-scrollbar]=\"!withVirtualScroll\"\n [@fadeInContent]=\"'showing'\"\n (@fadeInContent.done)=\"panelDoneAnimatingStream.next($event.toState)\"\n >\n @if (isEmptySearchResult) {\n <ng-content select=\"[kbq-select-search-empty-result]\" />\n }\n @if (showSelectAll) {\n <!-- Every read of selectAllState re-filters the whole option list, and allOptionsSelected\n is that same walk asking whether the state is \"checked\" \u2014 one read covers all four. -->\n @let selectAllCheckboxState = selectAllState;\n\n <kbq-option\n class=\"kbq-select__select-all\"\n [selectable]=\"false\"\n [class.kbq-selected]=\"selectAllCheckboxState === 'checked'\"\n [attr.role]=\"'checkbox'\"\n [attr.aria-checked]=\"\n selectAllCheckboxState === 'indeterminate' ? 'mixed' : selectAllCheckboxState === 'checked'\n \"\n (click)=\"toggleSelectAll()\"\n >\n <kbq-pseudo-checkbox [state]=\"selectAllCheckboxState\" />\n {{ selectAllText }}\n </kbq-option>\n }\n <ng-content />\n </div>\n\n <ng-content select=\"kbq-select-footer,[kbq-select-footer]\" />\n </div>\n</ng-template>\n", styles: [".kbq-select{box-sizing:border-box;display:inline-block;width:100%;outline:none}.kbq-select .kbq-select__trigger{display:flex;box-sizing:border-box;position:relative;cursor:pointer;min-height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-border-width) * 2)}.kbq-select .kbq-select__trigger:not(.kbq-select__trigger_multiline){height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-border-width) * 2)}.kbq-select .kbq-select__trigger:not(.kbq-select__trigger_multiline) .kbq-select__matcher{overflow:hidden;white-space:nowrap}.kbq-select .kbq-select__matcher{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-grow:1;align-items:center}.kbq-select .kbq-select__matcher>span{flex:1;overflow:hidden}.kbq-select .kbq-select__trigger.kbq-select__trigger_single .kbq-select__matcher,.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple.kbq-select__trigger_empty .kbq-select__matcher{padding:var(--kbq-select-size-single-padding-vertical) var(--kbq-select-size-single-padding-right) var(--kbq-select-size-single-padding-vertical) var(--kbq-select-size-single-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher{padding:var(--kbq-select-size-multiple-padding-vertical) var(--kbq-select-size-multiple-padding-right) var(--kbq-select-size-multiple-padding-vertical) var(--kbq-select-size-multiple-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher .kbq-select__match-container{display:flex}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiple:not(.kbq-select__trigger_empty) .kbq-select__matcher .kbq-select__match-list{display:flex;flex-wrap:wrap;overflow:hidden;height:calc(var(--kbq-form-field-size-height) - var(--kbq-select-size-multiple-padding-vertical) * 2);max-height:calc(var(--kbq-form-field-size-height) - var(--kbq-select-size-multiple-padding-vertical) * 2);gap:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));margin-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs))}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__match-container{flex-direction:column}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__matcher{max-width:100%;padding:calc(var(--kbq-select-size-multiple-padding-vertical) - var(--kbq-size-border-width)) var(--kbq-select-size-multiple-padding-right) calc(var(--kbq-select-size-multiple-padding-vertical) - var(--kbq-size-border-width)) var(--kbq-select-size-multiple-padding-left)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__cleaner,.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__arrow-wrapper{align-self:flex-start;align-items:center;height:calc(var(--kbq-form-field-size-height) - var(--kbq-size-s));min-width:var(--kbq-form-field-size-addon-width)}.kbq-select .kbq-select__trigger.kbq-select__trigger_multiline:not(.kbq-select__trigger_empty) .kbq-select__multiline-match-list{display:flex;flex-direction:row;flex-wrap:wrap;margin-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));gap:var(--kbq-size-xxs)}.kbq-select .kbq-select__match-container{width:100%;text-overflow:ellipsis;overflow:hidden}.kbq-select .kbq-select__match-container .kbq-select__match-hidden-text{box-sizing:content-box;flex:0 0 var(--kbq-form-field-size-addon-width);align-self:center;padding-left:var(--kbq-size-xxs);padding-right:var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));text-align:right}.kbq-select kbq-select-trigger,.kbq-select [kbq-select-trigger]{width:100%}.kbq-select .kbq-select__arrow-wrapper{display:flex;align-self:center;justify-content:center;min-width:var(--kbq-form-field-size-addon-width)}.kbq-form-field-appearance-fill .kbq-select .kbq-select__arrow-wrapper,.kbq-form-field-appearance-standard .kbq-select .kbq-select__arrow-wrapper{transform:translateY(-50%)}.kbq-form-field-appearance-outline .kbq-select .kbq-select__arrow-wrapper{transform:translateY(-25%)}.kbq-disabled.kbq-select .kbq-select__trigger{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.kbq-select__panel{min-width:100%;max-width:var(--kbq-panel-size-width-max, 640px);overflow:hidden;border-radius:var(--kbq-select-panel-size-border-radius, var(--kbq-size-border-radius))}.kbq-select__panel .kbq-option{font-size:inherit}.kbq-select__panel .kbq-select__no-options-message{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;flex-direction:row;align-items:center;justify-content:center;box-sizing:border-box;position:relative;margin-bottom:var(--kbq-size-3xl);margin-top:var(--kbq-size-3xl);max-width:100%;height:var(--kbq-option-size-height, var(--kbq-size-3xl));cursor:default;outline:none;padding-left:var(--kbq-option-size-horizontal-padding, var(--kbq-size-m));padding-right:var(--kbq-option-size-horizontal-padding, var(--kbq-size-m));border:var(--kbq-option-size-border-width, var(--kbq-size-3xs)) solid transparent}.kbq-select__panel .kbq-select__search-container{padding:var(--kbq-size-xxs);border-bottom-width:1px;border-bottom-style:solid}.kbq-select__content{box-sizing:initial;max-height:var(--kbq-select-panel-size-max-height, 256px);padding:var(--kbq-size-xxs);overflow:hidden auto}.kbq-select__panel .kbq-select__footer{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;align-items:center;box-sizing:border-box;min-height:40px;border-top-width:1px;border-top-style:solid;padding:var(--kbq-size-xxs) var(--kbq-size-l)}.kbq-select__content .kbq-option{position:relative}.kbq-select__content .kbq-option:before,.kbq-select__content .kbq-option:after{position:absolute;content:\"\";width:var(--kbq-size-xxs);height:calc(100% + var(--kbq-size-3xs) * 2)}.kbq-select__content .kbq-option:before{right:calc(100% + var(--kbq-size-3xs))}.kbq-select__content .kbq-option:after{left:calc(100% + var(--kbq-size-3xs))}.kbq-select__content:not(:has(>.kbq-select__no-options-message)) .cdk-virtual-scroll-viewport{min-height:var(--kbq-select-panel-size-max-height, 256px);max-height:var(--kbq-select-panel-size-max-height, 256px)}.kbq-select__content:not(:has(>.kbq-select__no-options-message)) .cdk-virtual-scroll-viewport.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper{max-width:100%}.kbq-form-field-type-select:not(.kbq-disabled) .kbq-form-field-flex{cursor:pointer}.kbq-select{color:var(--kbq-foreground-contrast)}.kbq-select.kbq-control_has-validate-directive.ng-invalid,.kbq-select.kbq-invalid{color:var(--kbq-foreground-error)}.kbq-select.kbq-control_has-validate-directive.ng-invalid .kbq-select__placeholder,.kbq-select.kbq-invalid .kbq-select__placeholder{color:var(--kbq-form-field-states-error-placeholder)}.kbq-select.kbq-disabled{color:var(--kbq-states-foreground-disabled)}.kbq-select.kbq-disabled .kbq-select__placeholder{color:var(--kbq-form-field-states-disabled-placeholder)}.kbq-select__placeholder{text-overflow:ellipsis;color:var(--kbq-form-field-default-placeholder)}.kbq-select__panel{box-shadow:var(--kbq-select-panel-dropdown-shadow);background:var(--kbq-select-panel-dropdown-background)}.kbq-select__panel .kbq-select__footer{border-color:var(--kbq-divider-color, var(--kbq-line-contrast-less))}.kbq-select__search-container{border-bottom-color:var(--kbq-divider-color, var(--kbq-line-contrast-less))}.kbq-select__no-options-message{color:var(--kbq-foreground-contrast-secondary)}.kbq-select,.kbq-select__panel{font-size:var(--kbq-typography-text-normal-font-size);font-style:var(--kbq-typography-text-normal-font-style);font-weight:var(--kbq-typography-text-normal-font-weight);line-height:var(--kbq-typography-text-normal-line-height);font-family:var(--kbq-typography-text-normal-font-family);text-transform:var(--kbq-typography-text-normal-text-transform);font-feature-settings:var(--kbq-typography-text-normal-font-feature-settings);letter-spacing:var(--kbq-typography-text-normal-letter-spacing)}\n", ".kbq-select,.kbq-tree-select,.kbq-select__panel{--kbq-select-size-single-padding-left: 0;--kbq-select-size-single-padding-right: 0;--kbq-select-size-single-padding-vertical: var(--kbq-size-xs);--kbq-select-size-single-content-gap: var(--kbq-size-xxs);--kbq-select-size-multiple-padding-left: 0;--kbq-select-size-multiple-padding-right: 0;--kbq-select-size-multiple-padding-vertical: var(--kbq-size-xxs);--kbq-select-size-multiple-content-gap: var(--kbq-size-xxs);--kbq-select-panel-size-border-radius: var(--kbq-size-border-radius);--kbq-select-panel-dropdown-background: var(--kbq-background-card);--kbq-select-panel-dropdown-shadow: var(--kbq-shadow-popup)}\n"] }]
1911
+ }], ctorParameters: () => [], propDecorators: { trigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }], panel: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }], optionsContainer: [{ type: i0.ViewChild, args: ['optionsContainer', { isSignal: true }] }], selectAllOption: [{ type: i0.ViewChild, args: [i0.forwardRef(() => KbqOption), { isSignal: true }] }], overlayDir: [{
1602
1912
  type: ViewChild,
1603
1913
  args: [CdkConnectedOverlay, { static: false }]
1604
1914
  }], footer: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqSelectFooter), { ...{ read: ElementRef }, isSignal: true }] }], cdkVirtualForOf: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CdkVirtualForOf), { isSignal: true }] }], virtualScrollViewport: [{ type: i0.ContentChild, args: [i0.forwardRef(() => CdkVirtualScrollViewport), { isSignal: true }] }], tags: [{
1605
1915
  type: ViewChildren,
1606
1916
  args: [KbqTag]
1607
- }], customTrigger: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqSelectTrigger), { isSignal: true }] }], customMatcher: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqSelectMatcher), { isSignal: true }] }], customTagTemplateRef: [{ type: i0.ContentChild, args: ['kbqSelectTagContent', { ...{ read: TemplateRef }, isSignal: true }] }], cleaner: [{ type: i0.ContentChild, args: ['kbqSelectCleaner', { isSignal: true }] }], options: [{
1917
+ }], customTrigger: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqSelectTrigger), { isSignal: true }] }], customMatcher: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqSelectMatcher), { isSignal: true }] }], customTagTemplateRef: [{ type: i0.ContentChild, args: ['kbqSelectTagContent', { ...{ read: TemplateRef }, isSignal: true }] }], cleaner: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqCleaner), { ...{ descendants: false }, isSignal: true }] }], options: [{
1608
1918
  type: ContentChildren,
1609
1919
  args: [KbqOption, { descendants: true }]
1610
1920
  }], optionGroups: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => KbqOptgroup), { isSignal: true }] }], search: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqSelectSearch), { isSignal: true }] }], searchEmpty: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KbqSelectSearchEmptyResult), { isSignal: true }] }], hiddenItemsText: [{
@@ -1632,14 +1942,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
1632
1942
  args: [{ transform: booleanAttribute }]
1633
1943
  }], compareWith: [{
1634
1944
  type: Input
1635
- }], virtualOptionFactory: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualOptionFactory", required: false }] }], selectAllToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAllToggle", required: false }] }], selectAllHandler: [{
1945
+ }], virtualOptionFactory: [{ type: i0.Input, args: [{ isSignal: true, alias: "virtualOptionFactory", required: false }] }], selectAllToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAllToggle", required: false }] }], selectAll: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAll", required: false }] }], selectAllHandler: [{
1636
1946
  type: Input
1637
- }], panelWidth: [{
1638
- type: Input
1639
- }], panelMinWidth: [{
1640
- type: Input,
1641
- args: [{ transform: numberAttribute }]
1642
- }], value: [{
1947
+ }], panelWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelWidth", required: false }] }], panelMinWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelMinWidth", required: false }] }], panelMaxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelMaxWidth", required: false }] }], panelMaxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelMaxHeight", required: false }] }], value: [{
1643
1948
  type: Input
1644
1949
  }], id: [{
1645
1950
  type: Input
@@ -1654,8 +1959,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
1654
1959
  }] } });
1655
1960
 
1656
1961
  class KbqSelectModule {
1657
- /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: KbqSelectModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1658
- /** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.25", ngImport: i0, type: KbqSelectModule, imports: [OverlayModule,
1962
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1963
+ /** @nocollapse */ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectModule, imports: [OverlayModule,
1659
1964
  KbqOptionModule,
1660
1965
  KbqIconModule,
1661
1966
  KbqTagsModule,
@@ -1685,7 +1990,7 @@ class KbqSelectModule {
1685
1990
  KbqSelectError,
1686
1991
  KbqSelectNoOptions,
1687
1992
  KbqSelectErrorText] }); }
1688
- /** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: KbqSelectModule, providers: [KBQ_SELECT_SCROLL_STRATEGY_PROVIDER], imports: [OverlayModule,
1993
+ /** @nocollapse */ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectModule, imports: [OverlayModule,
1689
1994
  KbqOptionModule,
1690
1995
  KbqIconModule,
1691
1996
  KbqTagsModule,
@@ -1695,7 +2000,7 @@ class KbqSelectModule {
1695
2000
  KbqSelectLoading, KbqOptionModule,
1696
2001
  KbqFormFieldModule] }); }
1697
2002
  }
1698
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: KbqSelectModule, decorators: [{
2003
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.30", ngImport: i0, type: KbqSelectModule, decorators: [{
1699
2004
  type: NgModule,
1700
2005
  args: [{
1701
2006
  imports: [
@@ -1718,7 +2023,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
1718
2023
  KbqSelectNoOptions,
1719
2024
  KbqSelectErrorText
1720
2025
  ],
1721
- providers: [KBQ_SELECT_SCROLL_STRATEGY_PROVIDER],
1722
2026
  exports: [
1723
2027
  KbqSelect,
1724
2028
  KbqOptionTooltip,