@koobiq/components 20.2.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 (212) hide show
  1. package/accordion/_accordion-theme.scss +5 -1
  2. package/accordion/accordion-tokens.scss +2 -0
  3. package/accordion/accordion-trigger.scss +6 -0
  4. package/accordion/accordion.scss +21 -0
  5. package/accordion/index.d.ts +55 -8
  6. package/actions-panel/index.d.ts +25 -13
  7. package/app-switcher/app-switcher-dropdown-app.scss +7 -5
  8. package/app-switcher/app-switcher-dropdown-site.scss +6 -4
  9. package/app-switcher/index.d.ts +41 -4
  10. package/app-switcher/kbq-app-switcher-list-item.scss +6 -8
  11. package/autocomplete/index.d.ts +24 -9
  12. package/breadcrumbs/index.d.ts +1 -1
  13. package/button/index.d.ts +2 -2
  14. package/button-toggle/button-toggle-tokens.scss +2 -0
  15. package/button-toggle/button-toggle.scss +9 -0
  16. package/button-toggle/index.d.ts +5 -0
  17. package/checkbox/index.d.ts +33 -29
  18. package/clamped-text/index.d.ts +1 -1
  19. package/code-block/index.d.ts +24 -19
  20. package/content-panel/index.d.ts +1 -1
  21. package/core/index.d.ts +1125 -199
  22. package/core/option/_action-container-mixins.scss +28 -0
  23. package/core/option/_option-theme.scss +24 -0
  24. package/core/option/action.scss +7 -0
  25. package/core/styles/_koobiq-theme.scss +2 -0
  26. package/core/styles/_tokens.scss +1 -0
  27. package/core/styles/common/_connected-overlay.scss +6 -3
  28. package/core/styles/common/_select.scss +12 -0
  29. package/core/styles/common/_tokens.scss +0 -9
  30. package/core/styles/theming/_index.scss +0 -1
  31. package/core/styles/theming/_theming.scss +34 -5
  32. package/datepicker/index.d.ts +46 -15
  33. package/dl/dl.scss +26 -0
  34. package/dl/index.d.ts +8 -1
  35. package/dropdown/_dropdown-theme.scss +28 -2
  36. package/dropdown/dropdown-item.scss +13 -0
  37. package/dropdown/dropdown.scss +7 -1
  38. package/dropdown/index.d.ts +264 -17
  39. package/dynamic-translation/index.d.ts +1 -1
  40. package/fesm2022/koobiq-components-accordion.mjs +106 -46
  41. package/fesm2022/koobiq-components-accordion.mjs.map +1 -1
  42. package/fesm2022/koobiq-components-actions-panel.mjs +57 -46
  43. package/fesm2022/koobiq-components-actions-panel.mjs.map +1 -1
  44. package/fesm2022/koobiq-components-alert.mjs +16 -16
  45. package/fesm2022/koobiq-components-app-switcher.mjs +233 -38
  46. package/fesm2022/koobiq-components-app-switcher.mjs.map +1 -1
  47. package/fesm2022/koobiq-components-autocomplete.mjs +54 -31
  48. package/fesm2022/koobiq-components-autocomplete.mjs.map +1 -1
  49. package/fesm2022/koobiq-components-badge.mjs +13 -13
  50. package/fesm2022/koobiq-components-breadcrumbs.mjs +25 -25
  51. package/fesm2022/koobiq-components-breadcrumbs.mjs.map +1 -1
  52. package/fesm2022/koobiq-components-button-toggle.mjs +17 -12
  53. package/fesm2022/koobiq-components-button-toggle.mjs.map +1 -1
  54. package/fesm2022/koobiq-components-button.mjs +25 -25
  55. package/fesm2022/koobiq-components-checkbox.mjs +69 -92
  56. package/fesm2022/koobiq-components-checkbox.mjs.map +1 -1
  57. package/fesm2022/koobiq-components-clamped-text.mjs +13 -13
  58. package/fesm2022/koobiq-components-code-block.mjs +56 -69
  59. package/fesm2022/koobiq-components-code-block.mjs.map +1 -1
  60. package/fesm2022/koobiq-components-content-panel.mjs +29 -29
  61. package/fesm2022/koobiq-components-core.mjs +2445 -789
  62. package/fesm2022/koobiq-components-core.mjs.map +1 -1
  63. package/fesm2022/koobiq-components-datepicker.mjs +160 -121
  64. package/fesm2022/koobiq-components-datepicker.mjs.map +1 -1
  65. package/fesm2022/koobiq-components-divider.mjs +7 -7
  66. package/fesm2022/koobiq-components-dl.mjs +23 -15
  67. package/fesm2022/koobiq-components-dl.mjs.map +1 -1
  68. package/fesm2022/koobiq-components-dropdown.mjs +754 -155
  69. package/fesm2022/koobiq-components-dropdown.mjs.map +1 -1
  70. package/fesm2022/koobiq-components-dynamic-translation.mjs +13 -13
  71. package/fesm2022/koobiq-components-ellipsis-center.mjs +7 -7
  72. package/fesm2022/koobiq-components-empty-state.mjs +19 -19
  73. package/fesm2022/koobiq-components-file-upload.mjs +74 -42
  74. package/fesm2022/koobiq-components-file-upload.mjs.map +1 -1
  75. package/fesm2022/koobiq-components-filter-bar.mjs +605 -192
  76. package/fesm2022/koobiq-components-filter-bar.mjs.map +1 -1
  77. package/fesm2022/koobiq-components-flag.mjs +7 -7
  78. package/fesm2022/koobiq-components-form-field.mjs +346 -158
  79. package/fesm2022/koobiq-components-form-field.mjs.map +1 -1
  80. package/fesm2022/koobiq-components-icon.mjs +39 -21
  81. package/fesm2022/koobiq-components-icon.mjs.map +1 -1
  82. package/fesm2022/koobiq-components-inline-edit.mjs +172 -27
  83. package/fesm2022/koobiq-components-inline-edit.mjs.map +1 -1
  84. package/fesm2022/koobiq-components-input.mjs +41 -24
  85. package/fesm2022/koobiq-components-input.mjs.map +1 -1
  86. package/fesm2022/koobiq-components-link.mjs +8 -8
  87. package/fesm2022/koobiq-components-list.mjs +657 -143
  88. package/fesm2022/koobiq-components-list.mjs.map +1 -1
  89. package/fesm2022/koobiq-components-loader-overlay.mjs +16 -16
  90. package/fesm2022/koobiq-components-markdown.mjs +14 -11
  91. package/fesm2022/koobiq-components-markdown.mjs.map +1 -1
  92. package/fesm2022/koobiq-components-modal.mjs +59 -35
  93. package/fesm2022/koobiq-components-modal.mjs.map +1 -1
  94. package/fesm2022/koobiq-components-navbar.mjs +69 -54
  95. package/fesm2022/koobiq-components-navbar.mjs.map +1 -1
  96. package/fesm2022/koobiq-components-notification-center.mjs +23 -22
  97. package/fesm2022/koobiq-components-notification-center.mjs.map +1 -1
  98. package/fesm2022/koobiq-components-overflow-items.mjs +16 -17
  99. package/fesm2022/koobiq-components-overflow-items.mjs.map +1 -1
  100. package/fesm2022/koobiq-components-popover.mjs +26 -21
  101. package/fesm2022/koobiq-components-popover.mjs.map +1 -1
  102. package/fesm2022/koobiq-components-progress-bar.mjs +13 -13
  103. package/fesm2022/koobiq-components-progress-spinner.mjs +13 -13
  104. package/fesm2022/koobiq-components-radio.mjs +10 -10
  105. package/fesm2022/koobiq-components-resizer.mjs +33 -14
  106. package/fesm2022/koobiq-components-resizer.mjs.map +1 -1
  107. package/fesm2022/koobiq-components-scrollbar.mjs +10 -10
  108. package/fesm2022/koobiq-components-search-expandable.mjs +7 -7
  109. package/fesm2022/koobiq-components-search-expandable.mjs.map +1 -1
  110. package/fesm2022/koobiq-components-select.mjs +419 -106
  111. package/fesm2022/koobiq-components-select.mjs.map +1 -1
  112. package/fesm2022/koobiq-components-sidebar.mjs +14 -14
  113. package/fesm2022/koobiq-components-sidepanel.mjs +26 -26
  114. package/fesm2022/koobiq-components-skeleton.mjs +10 -10
  115. package/fesm2022/koobiq-components-split-button.mjs +7 -7
  116. package/fesm2022/koobiq-components-splitter.mjs +17 -17
  117. package/fesm2022/koobiq-components-table.mjs +15 -13
  118. package/fesm2022/koobiq-components-table.mjs.map +1 -1
  119. package/fesm2022/koobiq-components-tabs.mjs +54 -54
  120. package/fesm2022/koobiq-components-tabs.mjs.map +1 -1
  121. package/fesm2022/koobiq-components-tags.mjs +283 -122
  122. package/fesm2022/koobiq-components-tags.mjs.map +1 -1
  123. package/fesm2022/koobiq-components-textarea.mjs +13 -8
  124. package/fesm2022/koobiq-components-textarea.mjs.map +1 -1
  125. package/fesm2022/koobiq-components-time-range.mjs +29 -24
  126. package/fesm2022/koobiq-components-time-range.mjs.map +1 -1
  127. package/fesm2022/koobiq-components-timepicker.mjs +58 -26
  128. package/fesm2022/koobiq-components-timepicker.mjs.map +1 -1
  129. package/fesm2022/koobiq-components-timezone.mjs +76 -39
  130. package/fesm2022/koobiq-components-timezone.mjs.map +1 -1
  131. package/fesm2022/koobiq-components-title.mjs +7 -7
  132. package/fesm2022/koobiq-components-toast.mjs +51 -26
  133. package/fesm2022/koobiq-components-toast.mjs.map +1 -1
  134. package/fesm2022/koobiq-components-toggle.mjs +72 -64
  135. package/fesm2022/koobiq-components-toggle.mjs.map +1 -1
  136. package/fesm2022/koobiq-components-tooltip.mjs +115 -36
  137. package/fesm2022/koobiq-components-tooltip.mjs.map +1 -1
  138. package/fesm2022/koobiq-components-top-bar.mjs +13 -13
  139. package/fesm2022/koobiq-components-tree-select.mjs +189 -55
  140. package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
  141. package/fesm2022/koobiq-components-tree.mjs +302 -81
  142. package/fesm2022/koobiq-components-tree.mjs.map +1 -1
  143. package/fesm2022/koobiq-components-username.mjs +27 -27
  144. package/file-upload/index.d.ts +25 -6
  145. package/file-upload/multiple-file-upload.component.scss +14 -0
  146. package/filter-bar/_filter-bar-theme.scss +0 -6
  147. package/filter-bar/index.d.ts +222 -9
  148. package/filter-bar/pipes/pipe-multi-tree-select.scss +0 -6
  149. package/filter-bar/pipes/pipe-multiselect.scss +0 -6
  150. package/filter-bar/pipes/pipe-tree-select.scss +0 -6
  151. package/form-field/_form-field-theme.scss +76 -20
  152. package/form-field/fieldset.scss +10 -0
  153. package/form-field/form-field-tokens.scss +15 -1
  154. package/form-field/form-field.scss +15 -19
  155. package/form-field/index.d.ts +147 -65
  156. package/icon/index.d.ts +31 -6
  157. package/inline-edit/index.d.ts +57 -4
  158. package/inline-edit/inline-edit.scss +10 -0
  159. package/input/index.d.ts +17 -2
  160. package/list/_list-theme.scss +42 -10
  161. package/list/index.d.ts +326 -79
  162. package/list/list-tokens.scss +43 -8
  163. package/list/list.scss +186 -12
  164. package/markdown/index.d.ts +1 -1
  165. package/modal/index.d.ts +21 -4
  166. package/modal/modal-tokens.scss +1 -1
  167. package/navbar/index.d.ts +16 -1
  168. package/navbar/navbar-brand.scss +6 -0
  169. package/navbar/vertical-navbar.scss +6 -0
  170. package/notification-center/notification-item.scss +6 -0
  171. package/package.json +3 -6
  172. package/popover/index.d.ts +2 -2
  173. package/prebuilt-themes/dark-theme.css +1 -1
  174. package/prebuilt-themes/light-theme.css +1 -1
  175. package/prebuilt-themes/theme.css +1 -1
  176. package/resizer/index.d.ts +12 -0
  177. package/schematics/migrations/deprecated-icons/README.md +29 -4
  178. package/schematics/migrations/deprecated-icons/data.js +7 -0
  179. package/schematics/migrations/deprecated-icons/index.js +62 -35
  180. package/schematics/migrations/new-icons-pack/README.md +37 -2
  181. package/schematics/migrations/new-icons-pack/data.js +8 -0
  182. package/schematics/migrations/new-icons-pack/index.js +144 -53
  183. package/schematics/ng-add/index.js +3 -3
  184. package/schematics/utils/angular-parsing.js +30 -12
  185. package/schematics/utils/ast.js +31 -0
  186. package/schematics/utils/icon-migration.js +530 -0
  187. package/schematics/utils/typescript.js +44 -0
  188. package/scrollbar/index.d.ts +1 -1
  189. package/select/index.d.ts +163 -18
  190. package/select/select-tokens.scss +0 -1
  191. package/select/select.scss +0 -2
  192. package/splitter/index.d.ts +1 -1
  193. package/table/_table-theme.scss +4 -0
  194. package/table/index.d.ts +2 -1
  195. package/table/table.scss +8 -0
  196. package/tags/index.d.ts +128 -29
  197. package/textarea/index.d.ts +5 -0
  198. package/time-range/index.d.ts +1 -1
  199. package/timepicker/index.d.ts +4 -0
  200. package/timezone/index.d.ts +9 -5
  201. package/toast/index.d.ts +26 -3
  202. package/toggle/index.d.ts +34 -14
  203. package/tooltip/index.d.ts +54 -11
  204. package/tree/_tree-theme.scss +25 -5
  205. package/tree/index.d.ts +71 -3
  206. package/tree/tree-option.scss +2 -8
  207. package/tree-select/_tree-select-theme.scss +22 -0
  208. package/tree-select/index.d.ts +83 -16
  209. package/core/styles/_tokens.kbq.import.scss +0 -4
  210. package/core/styles/theming/_components-theming.scss +0 -1927
  211. package/filter-bar/pipes/pipe-select.scss +0 -5
  212. package/overflow-items/overflow-items.scss +0 -20
@@ -1,12 +1,13 @@
1
1
  import { AnimationTriggerMetadata, AnimationEvent } from '@angular/animations';
2
2
  import * as i0 from '@angular/core';
3
- import { OnDestroy, TemplateRef, EventEmitter, Signal, QueryList, InjectionToken, AfterViewInit, ElementRef, AfterContentInit, OnInit } from '@angular/core';
3
+ import { OnDestroy, Signal, InjectionToken, TemplateRef, EventEmitter, QueryList, ElementRef, AfterContentInit, OnInit } from '@angular/core';
4
4
  import { Subject, Observable } from 'rxjs';
5
5
  import { FocusOrigin } from '@angular/cdk/a11y';
6
- import { KbqPanelWidth, KbqPanelMinWidth, KbqPanelMaxWidth, KbqTitleTextRef, IFocusableOption, KbqComponentColors, KbqPanelWidthOrigin } from '@koobiq/components/core';
6
+ import { KbqPanelWidth, KbqPanelMinWidth, KbqPanelMaxWidth, KbqTitleTextRef, IFocusableOption, Highlightable, KbqComponentColors, KbqSiblingPopup, KbqPanelWidthOrigin, KbqTriangle } from '@koobiq/components/core';
7
7
  import * as i2 from '@koobiq/components/icon';
8
8
  import { KbqIcon } from '@koobiq/components/icon';
9
9
  import { Direction } from '@angular/cdk/bidi';
10
+ import * as _angular_forms from '@angular/forms';
10
11
  import * as i1 from '@angular/cdk/overlay';
11
12
  import { ScrollStrategy, Overlay } from '@angular/cdk/overlay';
12
13
 
@@ -66,6 +67,62 @@ declare function throwKbqDropdownInvalidPositionX(): void;
66
67
  * @docs-private
67
68
  */
68
69
  declare function throwKbqDropdownInvalidPositionY(): void;
70
+ /**
71
+ * Throws an exception for the case when `kbqDropdownSearch` is applied to a form field that doesn't
72
+ * host a `kbqInput`.
73
+ * @docs-private
74
+ */
75
+ declare function throwKbqDropdownSearchMissingInputError(): void;
76
+ /**
77
+ * Throws an exception for the case when `kbqDropdownSearch`'s input isn't bound to a form control, so
78
+ * there is no query to react to.
79
+ * @docs-private
80
+ */
81
+ declare function throwKbqDropdownSearchMissingNgControlError(): void;
82
+
83
+ /**
84
+ * Narrow view of `KbqDropdownItem` that `KbqDropdownItemAction` needs. Read through
85
+ * `KBQ_DROPDOWN_ITEM_ACTION_HOST` instead of importing `KbqDropdownItem` directly: the item
86
+ * imports `KbqDropdownItemAction` for its `contentChild` query, so an import back from here would
87
+ * form a circular dependency between the two files, which breaks the query at runtime (the
88
+ * predicate ends up captured as `undefined`).
89
+ * @docs-private
90
+ */
91
+ interface KbqDropdownItemActionHost {
92
+ readonly disabled: boolean;
93
+ readonly progress: Signal<boolean>;
94
+ }
95
+ /**
96
+ * Marks a secondary, independently-focusable/clickable element (e.g. a settings link) projected
97
+ * inside a `kbq-dropdown-item` alongside the item's own primary action. Requires the item's host
98
+ * element to be non-interactive (e.g. `<div kbq-dropdown-item>`), since interactive content
99
+ * cannot validly nest inside another interactive element.
100
+ */
101
+ declare class KbqDropdownItemAction {
102
+ private readonly elementRef;
103
+ private readonly dropdownItem;
104
+ /**
105
+ * The `tabindex` this element had before `isInactive()` first forced it to `-1`, so it can be
106
+ * restored instead of left removed. Plain `[attr.tabindex]` can't do this: co-located host
107
+ * bindings for the same attribute (e.g. `KbqIconButton`'s own `tabindex`) apply in directive
108
+ * order and the last one always wins outright, so writing `null` here on the active branch
109
+ * would strip whatever tabindex the host component set, not just leave it alone.
110
+ */
111
+ private originalTabindex;
112
+ constructor();
113
+ /** Returns the host DOM element. */
114
+ getHostElement(): HTMLElement;
115
+ /** `progress` takes priority over the action, same as `disabled`. */
116
+ protected isInactive(): boolean;
117
+ /**
118
+ * Always stops the click from bubbling to the item's own primary click handler.
119
+ * Additionally, blocks the action's own default behavior when the parent item is
120
+ * disabled/loading — `<a>` has no native `disabled`.
121
+ */
122
+ protected onClick(event: MouseEvent): void;
123
+ static ɵfac: i0.ɵɵFactoryDeclaration<KbqDropdownItemAction, never>;
124
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KbqDropdownItemAction, "[kbqDropdownItemAction]", never, {}, {}, never, never, true, never>;
125
+ }
69
126
 
70
127
  /** Position of the dropdown panel along the x-axis. */
71
128
  type KbqDropdownPositionX = 'before' | 'after' | 'center';
@@ -108,6 +165,8 @@ interface KbqDropdownPanel {
108
165
  backdropClass?: string;
109
166
  hasBackdrop?: boolean;
110
167
  items: QueryList<KbqDropdownItem>;
168
+ /** Whether the panel highlights the active item instead of focusing it, see `KbqDropdownSearch`. */
169
+ readonly inSearchMode?: Signal<boolean>;
111
170
  focusFirstItem(origin?: FocusOrigin): void;
112
171
  resetActiveItem(): void;
113
172
  setPositionClasses?(x: KbqDropdownPositionX, y: KbqDropdownPositionY): void;
@@ -126,6 +185,12 @@ interface KbqDropdownDefaultOptions {
126
185
  backdropClass: string;
127
186
  /** Whether the dropdown has a backdrop. */
128
187
  hasBackdrop: boolean;
188
+ /**
189
+ * Whether nested dropdowns opened from this dropdown's items use a "safe area": while the
190
+ * pointer moves from a trigger toward its open submenu, sibling items it crosses over on the way
191
+ * don't prematurely close the submenu.
192
+ */
193
+ safeArea?: boolean;
129
194
  /**
130
195
  * Width of the panel. If set to `auto`, the panel will match the trigger width.
131
196
  * If set to null, the panel will grow to match its content.
@@ -153,12 +218,14 @@ declare function KBQ_DROPDOWN_DEFAULT_OPTIONS_FACTORY(): KbqDropdownDefaultOptio
153
218
  * This directive is intended to be used inside an kbq-dropdown tag.
154
219
  * It exists mostly to set the role attribute.
155
220
  */
156
- declare class KbqDropdownItem implements KbqTitleTextRef, IFocusableOption, AfterViewInit, OnDestroy {
221
+ declare class KbqDropdownItem implements KbqTitleTextRef, KbqDropdownItemActionHost, IFocusableOption, Highlightable, OnDestroy {
157
222
  private elementRef;
158
223
  private focusMonitor;
159
224
  parentDropdownPanel?: KbqDropdownPanel | null | undefined;
160
225
  textElement: ElementRef;
161
226
  icon: KbqIcon;
227
+ /** Secondary, independently-focusable icon action projected into the item (e.g. a settings link). */
228
+ readonly itemAction: i0.Signal<KbqDropdownItemAction | undefined>;
162
229
  get disabled(): boolean;
163
230
  set disabled(value: boolean);
164
231
  private _disabled;
@@ -170,14 +237,26 @@ declare class KbqDropdownItem implements KbqTitleTextRef, IFocusableOption, Afte
170
237
  readonly focused: Subject<KbqDropdownItem>;
171
238
  /** Whether the dropdown item is highlighted. */
172
239
  highlighted: boolean;
240
+ /** Whether the item is the panel's active item while DOM focus is held elsewhere. */
241
+ protected readonly active: i0.WritableSignal<boolean>;
173
242
  /** Whether the dropdown item acts as a trigger for a nested dropdown. */
174
243
  isNested: boolean;
175
244
  /** @docs-private */
176
245
  protected readonly componentColors: typeof KbqComponentColors;
177
- ngAfterViewInit(): void;
246
+ constructor();
178
247
  ngOnDestroy(): void;
179
248
  resetStyles(): void;
180
- /** Focuses the dropdown item. */
249
+ /** Styles the item as active without focusing it. */
250
+ setActiveStyles(): void;
251
+ /** Removes the styles applied by `setActiveStyles`. */
252
+ setInactiveStyles(): void;
253
+ /**
254
+ * Focuses the dropdown item and reveals it.
255
+ *
256
+ * The reveal is explicit because the one `focus()` performs implicitly is not portable: WebKit defers
257
+ * it to a later rendering update, where it lands after — and undoes — any scrolling the reader did in
258
+ * the meantime. `preventScroll` is therefore always forced on, overriding `options`.
259
+ */
181
260
  focus(origin?: FocusOrigin, options?: FocusOptions): void;
182
261
  /** Returns the host DOM element. */
183
262
  getHostElement(): HTMLElement;
@@ -187,15 +266,58 @@ declare class KbqDropdownItem implements KbqTitleTextRef, IFocusableOption, Afte
187
266
  checkDisabled(event: Event): void;
188
267
  /** Emits to the hover stream. Bound via `host` metadata. */
189
268
  handleMouseEnter(): void;
269
+ /**
270
+ * Lets Tab move focus between the host and `itemAction` without leaving the dropdown
271
+ * (`stopPropagation` only — the browser's native focus move still happens). Any other Tab
272
+ * press, i.e. actually leaving the item, is left untouched and still closes the dropdown via
273
+ * the panel's `FocusKeyManager.tabOut`. Bound via `host` metadata.
274
+ */
275
+ protected handleActionKeydown(event: KeyboardEvent): void;
190
276
  /** Gets the label to be used when determining whether the option should be focused. */
191
277
  getLabel(): string;
192
278
  haltDisabledEvents(event: Event): void;
193
279
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqDropdownItem, never>;
194
- static ɵcmp: i0.ɵɵComponentDeclaration<KbqDropdownItem, "kbq-dropdown-item, [kbq-dropdown-item]", ["kbqDropdownItem"], { "disabled": { "alias": "disabled"; "required": false; }; "progress": { "alias": "progress"; "required": false; "isSignal": true; }; }, {}, ["icon"], ["[kbq-icon]", "*"], true, never>;
280
+ static ɵcmp: i0.ɵɵComponentDeclaration<KbqDropdownItem, "kbq-dropdown-item, [kbq-dropdown-item]", ["kbqDropdownItem"], { "disabled": { "alias": "disabled"; "required": false; }; "progress": { "alias": "progress"; "required": false; "isSignal": true; }; }, {}, ["itemAction", "icon"], ["[kbq-icon]", "*", "[kbqDropdownItemAction]"], true, never>;
195
281
  static ngAcceptInputType_disabled: unknown;
196
282
  }
197
283
 
198
- /** Injection token that determines the scroll handling while the dropdown is open. */
284
+ /**
285
+ * Marks a `kbq-form-field` projected into a `kbq-dropdown` as the panel's search field.
286
+ *
287
+ * The panel keeps DOM focus in the field, so arrow keys move the highlighted item while the query
288
+ * stays editable.
289
+ */
290
+ declare class KbqDropdownSearch implements AfterContentInit {
291
+ private readonly formField;
292
+ /**
293
+ * Panel this field searches. A nested panel declared inside its parent's content shares the view with
294
+ * it, so the parent has to be able to tell which of the projected fields is its own.
295
+ * @docs-private
296
+ */
297
+ readonly panel: KbqDropdownPanel | null;
298
+ /** The form control the query is bound to. */
299
+ get ngControl(): _angular_forms.NgControl | null;
300
+ ngAfterContentInit(): void;
301
+ /** Focuses the search field. */
302
+ focus(): void;
303
+ /** Clears the search query. */
304
+ reset(): void;
305
+ /** The current search query. */
306
+ value(): string;
307
+ /** @docs-private */
308
+ protected handleClick(event: MouseEvent): void;
309
+ /** @docs-private */
310
+ protected handleKeydown(event: KeyboardEvent): void;
311
+ /** Whether the key still has caret to travel inside the field, rather than acting on the panel. */
312
+ private movesCaret;
313
+ static ɵfac: i0.ɵɵFactoryDeclaration<KbqDropdownSearch, never>;
314
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KbqDropdownSearch, "[kbqDropdownSearch]", ["kbqDropdownSearch"], {}, {}, never, never, true, never>;
315
+ }
316
+
317
+ /**
318
+ * Injection token that determines the scroll handling while the dropdown is open. The root default keeps the
319
+ * trigger usable outside `KbqDropdownModule`'s injector; providing the token anywhere still wins over it.
320
+ */
199
321
  declare const KBQ_DROPDOWN_SCROLL_STRATEGY: InjectionToken<() => ScrollStrategy>;
200
322
  /** @docs-private */
201
323
  declare function KBQ_DROPDOWN_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy;
@@ -222,7 +344,7 @@ declare const NESTED_PANEL_LEFT_PADDING = 8;
222
344
  * This directive is intended to be used in conjunction with an kbq-dropdown tag. It is
223
345
  * responsible for toggling the display of the provided dropdown instance.
224
346
  */
225
- declare class KbqDropdownTrigger implements AfterContentInit, OnDestroy {
347
+ declare class KbqDropdownTrigger implements AfterContentInit, OnDestroy, KbqSiblingPopup {
226
348
  private overlay;
227
349
  private elementRef;
228
350
  private viewContainerRef;
@@ -275,11 +397,21 @@ declare class KbqDropdownTrigger implements AfterContentInit, OnDestroy {
275
397
  * KBQ_OPTION_ACTION_PARENT contract, which an `OutputEmitterRef` does not support — see #DS-5079.
276
398
  */
277
399
  readonly dropdownClosed: EventEmitter<void>;
400
+ /** Emits `true` when the dropdown opens and `false` when it closes. Part of the `KbqSiblingPopup` contract. */
401
+ readonly openedChange: Observable<boolean>;
278
402
  openedBy: Exclude<FocusOrigin, 'program' | null> | undefined;
279
403
  /** The text direction of the containing app. */
280
404
  get dir(): Direction;
281
405
  /** Whether the dropdown is open. */
282
406
  get opened(): boolean;
407
+ /**
408
+ * Whether the dropdown overlay is currently attached. Part of the `KbqSiblingPopup` contract.
409
+ *
410
+ * `opened` is set synchronously right after the overlay is attached and, on close, only once the exit
411
+ * animation is done — i.e. it stays `true` for the whole time the trigger is busy with its panel,
412
+ * including the moment `destroy()` restores focus to the trigger.
413
+ */
414
+ get isAttached(): boolean;
283
415
  private _opened;
284
416
  private portal;
285
417
  private overlayRef;
@@ -304,6 +436,11 @@ declare class KbqDropdownTrigger implements AfterContentInit, OnDestroy {
304
436
  focus(origin?: FocusOrigin, options?: FocusOptions): void;
305
437
  /** Handles mouse presses on the trigger. */
306
438
  handleMousedown(event: MouseEvent): void;
439
+ /**
440
+ * Starts safe-area protection when the pointer leaves a trigger whose submenu is open, so a
441
+ * sibling item crossed on the way to the submenu doesn't prematurely close it.
442
+ */
443
+ handleMouseLeave(event: MouseEvent): void;
307
444
  /** Handles key presses on the trigger. */
308
445
  handleKeydown(event: KeyboardEvent): void;
309
446
  /** Handles click events on the trigger. */
@@ -376,17 +513,39 @@ declare class KbqDropdownTrigger implements AfterContentInit, OnDestroy {
376
513
  static ngAcceptInputType_demoteOverlay: unknown;
377
514
  }
378
515
 
516
+ /**
517
+ * Grace period before switching to a different nested trigger hovered while a safe area is
518
+ * protecting the currently open submenu. Without it, sweeping the pointer down a long list of
519
+ * nested triggers on the way to the submenu would flicker each row's submenu open and closed.
520
+ */
521
+ declare const NESTED_HOVER_SWITCH_DELAY = 50;
379
522
  declare class KbqDropdownStaticContent {
380
523
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqDropdownStaticContent, never>;
381
524
  static ɵdir: i0.ɵɵDirectiveDeclaration<KbqDropdownStaticContent, "[kbqDropdownStaticContent]", never, {}, {}, never, never, true, never>;
382
525
  }
526
+ /** Footer that is rendered below the dropdown options panel. */
527
+ declare class KbqDropdownFooter {
528
+ static ɵfac: i0.ɵɵFactoryDeclaration<KbqDropdownFooter, never>;
529
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KbqDropdownFooter, "[kbqDropdownFooter], kbq-dropdown-footer", never, {}, {}, never, never, true, never>;
530
+ }
383
531
  declare class KbqDropdown implements AfterContentInit, KbqDropdownPanel, OnInit, OnDestroy {
384
532
  private elementRef;
385
533
  private ngZone;
534
+ private document;
386
535
  private defaultOptions;
536
+ private readonly destroyRef;
537
+ private readonly panelFormField;
538
+ /**
539
+ * Signal content queries carry `descendants: true`, and a nested panel declared inside this one's
540
+ * content is part of the same view — so the match has to be narrowed to the fields this panel owns,
541
+ * the way `updateDirectDescendants` narrows the items.
542
+ */
543
+ private readonly searches;
387
544
  private readonly search;
388
545
  /** Whether the dropdown projects a search form-field. @docs-private */
389
- readonly hasSearch: i0.Signal<boolean>;
546
+ readonly hasSearch: Signal<boolean>;
547
+ /** Whether the panel highlights the active item instead of focusing it. @docs-private */
548
+ readonly inSearchMode: Signal<boolean>;
390
549
  readonly navigationWithWrap: i0.InputSignal<boolean>;
391
550
  /** Position of the dropdown in the X axis. */
392
551
  get xPosition(): KbqDropdownPositionX;
@@ -452,13 +611,19 @@ declare class KbqDropdown implements AfterContentInit, KbqDropdownPanel, OnInit,
452
611
  * When null, the `--kbq-dropdown-size-container-width-max` token applies.
453
612
  */
454
613
  readonly panelMaxWidth: i0.InputSignalWithTransform<KbqPanelMaxWidth, unknown>;
614
+ /**
615
+ * Whether nested dropdowns opened from this dropdown's items use a "safe area": while the
616
+ * pointer moves from a trigger toward its open submenu, sibling items it crosses over on the way
617
+ * don't prematurely close the submenu.
618
+ */
619
+ readonly safeArea: i0.InputSignalWithTransform<boolean, unknown>;
455
620
  /**
456
621
  * `panelMinWidth` rendered as a CSS length for the `--kbq-dropdown-size-container-width-min`
457
622
  * token, so the panel's CSS `min-width` floor tracks the input — mirroring how `panelMaxWidth`
458
623
  * drives `max-width`. Non-finite input (e.g. `null`) leaves the token's static default in place.
459
624
  * @docs-private
460
625
  */
461
- protected readonly panelMinWidthToken: i0.Signal<string | null>;
626
+ protected readonly panelMinWidthToken: Signal<string | null>;
462
627
  /** @docs-private */
463
628
  templateRef: TemplateRef<any>;
464
629
  /**
@@ -474,28 +639,95 @@ declare class KbqDropdown implements AfterContentInit, KbqDropdownPanel, OnInit,
474
639
  readonly closed: EventEmitter<void | "click" | "keydown" | "tab">;
475
640
  private previousPanelClass;
476
641
  private keyManager;
642
+ private activeDescendantKeyManager?;
643
+ private focusKeyManager?;
644
+ private focusOrigin;
477
645
  /** Only the direct descendant menu items. */
478
646
  private directDescendantItems;
479
647
  /** Subscription to tab events on the dropdown panel */
480
648
  private tabSubscription;
649
+ /** Cleans up the safe-area `mousemove` listener. `null` when no safe area is being tracked. */
650
+ private safeAreaCleanup;
651
+ /** The nested trigger currently protected by the active safe area, if any. */
652
+ private safeAreaOwner;
653
+ /**
654
+ * The most recently hovered item, tracked independently of the safe area so that leaving it
655
+ * straight onto a sibling's nested trigger can switch to it immediately instead of waiting for a
656
+ * `mouseenter` that already happened.
657
+ */
658
+ private currentHovered;
659
+ /** Emits when the pointer reaches the panel the active safe area protects. */
660
+ private readonly panelReached;
661
+ /** Emits the sibling trigger that should open once a forced switch has closed the current one. */
662
+ private readonly switchTarget;
663
+ /** Watches for a forced switch to a sibling trigger while a safe area is active. */
664
+ private switchTargetSubscription;
665
+ constructor();
481
666
  ngOnInit(): void;
482
667
  ngAfterContentInit(): void;
483
668
  ngOnDestroy(): void;
484
669
  /** Stream that emits whenever the hovered dropdown item changes. */
485
670
  hovered(): Observable<KbqDropdownItem>;
671
+ /**
672
+ * Tracks the pointer against `triangle` to protect `owner`'s open submenu, closing it via
673
+ * `onExit` if the pointer leaves the triangle without first reaching `panelRect`. Meanwhile, if a
674
+ * different nested trigger is hovered, `switchTarget()` emits it — immediately if it's outside
675
+ * the triangle, otherwise after a grace period (see `NESTED_HOVER_SWITCH_DELAY`). Replaces any
676
+ * safe area already being tracked.
677
+ * @docs-private
678
+ */
679
+ activateSafeArea(owner: KbqDropdownItem, triangle: KbqTriangle, panelRect: DOMRect, onExit: () => void): void;
680
+ /**
681
+ * Stops tracking the current safe area, if any.
682
+ * @docs-private
683
+ */
684
+ deactivateSafeArea(): void;
685
+ /**
686
+ * Whether a safe area is currently being tracked.
687
+ * @docs-private
688
+ */
689
+ isSafeAreaActive(): boolean;
690
+ /**
691
+ * Whether `item` is the nested trigger currently protected by an active safe area.
692
+ * @docs-private
693
+ */
694
+ isSafeAreaOwner(item: KbqDropdownItem): boolean;
695
+ /**
696
+ * Stream that emits when the pointer reaches the panel the active safe area protects (as opposed
697
+ * to leaving the safe area, which closes the panel instead).
698
+ * @docs-private
699
+ */
700
+ onPanelReached(): Observable<void>;
701
+ /**
702
+ * Stream that emits the sibling trigger that should open once a forced safe-area switch has
703
+ * closed the trigger it was protecting.
704
+ * @docs-private
705
+ */
706
+ onSwitchTarget(): Observable<KbqDropdownItem>;
486
707
  /** Handle a keyboard event from the dropdown, delegating to the appropriate action. */
487
708
  handleKeydown(event: KeyboardEvent): void;
488
709
  /**
489
- * Focus the first item in the dropdown.
710
+ * Applies the panel's initial focus, see `applyInitialFocus`.
490
711
  * @param origin Action from which the focus originated. Used to set the correct styling.
491
712
  */
492
713
  focusFirstItem(origin?: FocusOrigin): void;
493
714
  /**
494
- * Applies focus when the dropdown is opened. When opened by mouse or touch, the first item
495
- * should not be highlighted, so the panel itself is focused instead — keyboard events still
496
- * reach the panel and the first arrow key press will highlight the first item.
715
+ * Applies focus when the dropdown is opened.
716
+ *
717
+ * A projected search field takes the caret for every origin and keeps it: the first arrow key press
718
+ * only highlights an item. Without one, opening by mouse or touch focuses the panel rather than an
719
+ * item, so that nothing is highlighted while keyboard events still reach the panel; any other origin
720
+ * highlights the first item. A submenu of a search panel focuses nothing at all, so that hovering it
721
+ * does not pull the caret out of the query.
497
722
  */
498
723
  private applyInitialFocus;
724
+ /**
725
+ * Moves focus back into the projected search field, reporting whether there was one. A nested panel
726
+ * restores focus through this instead of onto its trigger item, which would strand the caret outside
727
+ * the query.
728
+ * @docs-private
729
+ */
730
+ restoreFocus(): boolean;
499
731
  /** Moves DOM focus onto the dropdown panel so that keydown events keep being handled. */
500
732
  private focusPanel;
501
733
  /**
@@ -519,6 +751,21 @@ declare class KbqDropdown implements AfterContentInit, KbqDropdownPanel, OnInit,
519
751
  onAnimationDone(event: AnimationEvent): void;
520
752
  onAnimationStart(event: AnimationEvent): void;
521
753
  close(): void;
754
+ /**
755
+ * With a search field the caret has to stay in the input, so the active item is only highlighted and
756
+ * typeahead is left off — it would race the query the user is typing.
757
+ */
758
+ private initKeyManager;
759
+ /** Which mode the installed key manager serves; the wanted one is `inSearchMode()`. */
760
+ private keyManagerInstalledForSearch;
761
+ private configureKeyManager;
762
+ private setFocusOrigin;
763
+ private isActiveItemStale;
764
+ /**
765
+ * Reveals the highlighted item, which the browser only does on its own for real focus. Mirrors the
766
+ * reveal `kbqFocusAndReveal` performs for focused elements.
767
+ */
768
+ private revealActiveItem;
522
769
  /**
523
770
  * Sets up a stream that will keep track of any newly-added menu items and will update the list
524
771
  * of direct descendants. We collect the descendants this way, because `items` can include
@@ -527,14 +774,14 @@ declare class KbqDropdown implements AfterContentInit, KbqDropdownPanel, OnInit,
527
774
  */
528
775
  private updateDirectDescendants;
529
776
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqDropdown, never>;
530
- static ɵcmp: i0.ɵɵComponentDeclaration<KbqDropdown, "kbq-dropdown", ["kbqDropdown"], { "navigationWithWrap": { "alias": "navigationWithWrap"; "required": false; "isSignal": true; }; "xPosition": { "alias": "xPosition"; "required": false; }; "yPosition": { "alias": "yPosition"; "required": false; }; "overlapTriggerY": { "alias": "overlapTriggerY"; "required": false; }; "overlapTriggerX": { "alias": "overlapTriggerX"; "required": false; }; "hasBackdrop": { "alias": "hasBackdrop"; "required": false; }; "panelClass": { "alias": "class"; "required": false; }; "backdropClass": { "alias": "backdropClass"; "required": false; }; "panelWidth": { "alias": "panelWidth"; "required": false; "isSignal": true; }; "panelMinWidth": { "alias": "panelMinWidth"; "required": false; "isSignal": true; }; "panelMaxWidth": { "alias": "panelMaxWidth"; "required": false; "isSignal": true; }; }, { "closed": "closed"; }, ["search", "lazyContent", "items"], ["*", "[kbqDropdownStaticContent]"], true, never>;
777
+ static ɵcmp: i0.ɵɵComponentDeclaration<KbqDropdown, "kbq-dropdown", ["kbqDropdown"], { "navigationWithWrap": { "alias": "navigationWithWrap"; "required": false; "isSignal": true; }; "xPosition": { "alias": "xPosition"; "required": false; }; "yPosition": { "alias": "yPosition"; "required": false; }; "overlapTriggerY": { "alias": "overlapTriggerY"; "required": false; }; "overlapTriggerX": { "alias": "overlapTriggerX"; "required": false; }; "hasBackdrop": { "alias": "hasBackdrop"; "required": false; }; "panelClass": { "alias": "class"; "required": false; }; "backdropClass": { "alias": "backdropClass"; "required": false; }; "panelWidth": { "alias": "panelWidth"; "required": false; "isSignal": true; }; "panelMinWidth": { "alias": "panelMinWidth"; "required": false; "isSignal": true; }; "panelMaxWidth": { "alias": "panelMaxWidth"; "required": false; "isSignal": true; }; "safeArea": { "alias": "safeArea"; "required": false; "isSignal": true; }; }, { "closed": "closed"; }, ["panelFormField", "searches", "lazyContent", "items"], ["*", "[kbqDropdownFooter], kbq-dropdown-footer", "[kbqDropdownStaticContent]"], true, never>;
531
778
  }
532
779
 
533
780
  declare class KbqDropdownModule {
534
781
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqDropdownModule, never>;
535
- static ɵmod: i0.ɵɵNgModuleDeclaration<KbqDropdownModule, never, [typeof i1.OverlayModule, typeof i2.KbqIconModule, typeof KbqDropdownStaticContent, typeof KbqDropdown, typeof KbqDropdownItem, typeof KbqDropdownTrigger, typeof KbqDropdownContent], [typeof KbqDropdown, typeof KbqDropdownItem, typeof KbqDropdownTrigger, typeof KbqDropdownContent, typeof KbqDropdownStaticContent]>;
782
+ static ɵmod: i0.ɵɵNgModuleDeclaration<KbqDropdownModule, never, [typeof i1.OverlayModule, typeof i2.KbqIconModule, typeof KbqDropdownStaticContent, typeof KbqDropdown, typeof KbqDropdownItem, typeof KbqDropdownItemAction, typeof KbqDropdownTrigger, typeof KbqDropdownContent, typeof KbqDropdownFooter, typeof KbqDropdownSearch], [typeof KbqDropdown, typeof KbqDropdownItem, typeof KbqDropdownItemAction, typeof KbqDropdownTrigger, typeof KbqDropdownContent, typeof KbqDropdownStaticContent, typeof KbqDropdownFooter, typeof KbqDropdownSearch]>;
536
783
  static ɵinj: i0.ɵɵInjectorDeclaration<KbqDropdownModule>;
537
784
  }
538
785
 
539
- export { KBQ_DROPDOWN_DEFAULT_OPTIONS, KBQ_DROPDOWN_DEFAULT_OPTIONS_FACTORY, KBQ_DROPDOWN_HOST, KBQ_DROPDOWN_PANEL, KBQ_DROPDOWN_SCROLL_STRATEGY, KBQ_DROPDOWN_SCROLL_STRATEGY_FACTORY, KBQ_DROPDOWN_SCROLL_STRATEGY_FACTORY_PROVIDER, KbqDropdown, KbqDropdownContent, KbqDropdownItem, KbqDropdownModule, KbqDropdownStaticContent, KbqDropdownTrigger, NESTED_PANEL_LEFT_PADDING, NESTED_PANEL_TOP_PADDING, fadeInItems, kbqDropdownAnimations, throwKbqDropdownInvalidPositionX, throwKbqDropdownInvalidPositionY, throwKbqDropdownMissingError, transformDropdown };
786
+ export { KBQ_DROPDOWN_DEFAULT_OPTIONS, KBQ_DROPDOWN_DEFAULT_OPTIONS_FACTORY, KBQ_DROPDOWN_HOST, KBQ_DROPDOWN_PANEL, KBQ_DROPDOWN_SCROLL_STRATEGY, KBQ_DROPDOWN_SCROLL_STRATEGY_FACTORY, KBQ_DROPDOWN_SCROLL_STRATEGY_FACTORY_PROVIDER, KbqDropdown, KbqDropdownContent, KbqDropdownFooter, KbqDropdownItem, KbqDropdownItemAction, KbqDropdownModule, KbqDropdownSearch, KbqDropdownStaticContent, KbqDropdownTrigger, NESTED_HOVER_SWITCH_DELAY, NESTED_PANEL_LEFT_PADDING, NESTED_PANEL_TOP_PADDING, fadeInItems, kbqDropdownAnimations, throwKbqDropdownInvalidPositionX, throwKbqDropdownInvalidPositionY, throwKbqDropdownMissingError, throwKbqDropdownSearchMissingInputError, throwKbqDropdownSearchMissingNgControlError, transformDropdown };
540
787
  export type { DropdownCloseReason, DropdownPositionX, DropdownPositionY, KbqDropdownDefaultOptions, KbqDropdownPanel, KbqDropdownPositionX, KbqDropdownPositionY };
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { TemplateRef, Signal } from '@angular/core';
2
+ import { Signal, TemplateRef } from '@angular/core';
3
3
 
4
4
  /**
5
5
  * @docs-private