@koobiq/components 19.8.4 → 19.8.6

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 (199) hide show
  1. package/accordion/accordion-content.directive.d.ts +23 -3
  2. package/accordion/accordion-trigger.component.d.ts +1 -0
  3. package/accordion/accordion.component.scss +4 -1
  4. package/alert/alert-tokens.scss +4 -4
  5. package/autocomplete/autocomplete-trigger.directive.d.ts +10 -5
  6. package/breadcrumbs/breadcrumbs.d.ts +2 -0
  7. package/breadcrumbs/breadcrumbs.scss +4 -0
  8. package/button/button-group.scss +42 -2
  9. package/button-toggle/button-toggle-tokens.scss +16 -0
  10. package/button-toggle/button-toggle.component.d.ts +3 -1
  11. package/button-toggle/button-toggle.scss +105 -1
  12. package/checkbox/checkbox.scss +5 -4
  13. package/clamped-text/clamped-text.d.ts +4 -2
  14. package/core/form-field/field-sizing-content.d.ts +0 -1
  15. package/core/form-field/form-field-ref.d.ts +1 -0
  16. package/core/form-field/index.d.ts +1 -0
  17. package/core/form-field/text-field-selection.d.ts +18 -0
  18. package/core/form-field/text-ruler.d.ts +16 -0
  19. package/core/navbar/rectangle-item.d.ts +8 -0
  20. package/core/option/_action-container-mixins.scss +28 -0
  21. package/core/option/_option-theme.scss +8 -0
  22. package/core/option/action.d.ts +9 -0
  23. package/core/option/action.scss +7 -0
  24. package/core/option/option.d.ts +10 -6
  25. package/core/pop-up/pop-up-trigger.d.ts +6 -0
  26. package/core/select/constants.d.ts +8 -1
  27. package/core/services/measure-scrollbar.service.d.ts +1 -0
  28. package/core/styles/common/_animation.scss +35 -24
  29. package/core/styles/common/_select.scss +17 -2
  30. package/core/styles/theming/_scrollbar-theme.scss +4 -0
  31. package/core/styles/typography/_typography.scss +8 -0
  32. package/core/utils/dom.d.ts +12 -0
  33. package/datepicker/datepicker-input.directive.d.ts +20 -5
  34. package/datepicker/datepicker.component.d.ts +4 -1
  35. package/dl/dl.component.d.ts +1 -0
  36. package/dl/dl.scss +10 -0
  37. package/dropdown/dropdown-item.component.d.ts +10 -2
  38. package/dropdown/dropdown-item.scss +16 -0
  39. package/dropdown/dropdown-trigger.directive.d.ts +6 -1
  40. package/dropdown/dropdown.component.d.ts +6 -1
  41. package/dropdown/dropdown.module.d.ts +1 -1
  42. package/dropdown/dropdown.scss +18 -3
  43. package/ellipsis-center/ellipsis-center.directive.d.ts +35 -2
  44. package/fesm2022/koobiq-components-accordion.mjs +104 -16
  45. package/fesm2022/koobiq-components-accordion.mjs.map +1 -1
  46. package/fesm2022/koobiq-components-alert.mjs +2 -2
  47. package/fesm2022/koobiq-components-app-switcher.mjs +6 -6
  48. package/fesm2022/koobiq-components-app-switcher.mjs.map +1 -1
  49. package/fesm2022/koobiq-components-autocomplete.mjs +21 -9
  50. package/fesm2022/koobiq-components-autocomplete.mjs.map +1 -1
  51. package/fesm2022/koobiq-components-breadcrumbs.mjs +10 -5
  52. package/fesm2022/koobiq-components-breadcrumbs.mjs.map +1 -1
  53. package/fesm2022/koobiq-components-button-toggle.mjs +8 -5
  54. package/fesm2022/koobiq-components-button-toggle.mjs.map +1 -1
  55. package/fesm2022/koobiq-components-button.mjs +4 -4
  56. package/fesm2022/koobiq-components-button.mjs.map +1 -1
  57. package/fesm2022/koobiq-components-checkbox.mjs +2 -2
  58. package/fesm2022/koobiq-components-checkbox.mjs.map +1 -1
  59. package/fesm2022/koobiq-components-clamped-text.mjs +9 -0
  60. package/fesm2022/koobiq-components-clamped-text.mjs.map +1 -1
  61. package/fesm2022/koobiq-components-code-block.mjs +14 -5
  62. package/fesm2022/koobiq-components-code-block.mjs.map +1 -1
  63. package/fesm2022/koobiq-components-content-panel.mjs +5 -4
  64. package/fesm2022/koobiq-components-content-panel.mjs.map +1 -1
  65. package/fesm2022/koobiq-components-core.mjs +234 -64
  66. package/fesm2022/koobiq-components-core.mjs.map +1 -1
  67. package/fesm2022/koobiq-components-datepicker.mjs +73 -49
  68. package/fesm2022/koobiq-components-datepicker.mjs.map +1 -1
  69. package/fesm2022/koobiq-components-dl.mjs +5 -4
  70. package/fesm2022/koobiq-components-dl.mjs.map +1 -1
  71. package/fesm2022/koobiq-components-dropdown.mjs +65 -22
  72. package/fesm2022/koobiq-components-dropdown.mjs.map +1 -1
  73. package/fesm2022/koobiq-components-ellipsis-center.mjs +77 -22
  74. package/fesm2022/koobiq-components-ellipsis-center.mjs.map +1 -1
  75. package/fesm2022/koobiq-components-file-upload.mjs +12 -12
  76. package/fesm2022/koobiq-components-file-upload.mjs.map +1 -1
  77. package/fesm2022/koobiq-components-filter-bar.mjs +295 -46
  78. package/fesm2022/koobiq-components-filter-bar.mjs.map +1 -1
  79. package/fesm2022/koobiq-components-form-field.mjs +2 -2
  80. package/fesm2022/koobiq-components-form-field.mjs.map +1 -1
  81. package/fesm2022/koobiq-components-icon.mjs +1 -1
  82. package/fesm2022/koobiq-components-icon.mjs.map +1 -1
  83. package/fesm2022/koobiq-components-inline-edit.mjs +26 -5
  84. package/fesm2022/koobiq-components-inline-edit.mjs.map +1 -1
  85. package/fesm2022/koobiq-components-list.mjs +12 -22
  86. package/fesm2022/koobiq-components-list.mjs.map +1 -1
  87. package/fesm2022/koobiq-components-markdown.mjs +4 -1
  88. package/fesm2022/koobiq-components-markdown.mjs.map +1 -1
  89. package/fesm2022/koobiq-components-modal.mjs +53 -12
  90. package/fesm2022/koobiq-components-modal.mjs.map +1 -1
  91. package/fesm2022/koobiq-components-navbar.mjs +29 -13
  92. package/fesm2022/koobiq-components-navbar.mjs.map +1 -1
  93. package/fesm2022/koobiq-components-notification-center.mjs +45 -7
  94. package/fesm2022/koobiq-components-notification-center.mjs.map +1 -1
  95. package/fesm2022/koobiq-components-overflow-items.mjs +4 -0
  96. package/fesm2022/koobiq-components-overflow-items.mjs.map +1 -1
  97. package/fesm2022/koobiq-components-popover.mjs +35 -18
  98. package/fesm2022/koobiq-components-popover.mjs.map +1 -1
  99. package/fesm2022/koobiq-components-radio.mjs +3 -7
  100. package/fesm2022/koobiq-components-radio.mjs.map +1 -1
  101. package/fesm2022/koobiq-components-resizer.mjs +23 -4
  102. package/fesm2022/koobiq-components-resizer.mjs.map +1 -1
  103. package/fesm2022/koobiq-components-select.mjs +126 -29
  104. package/fesm2022/koobiq-components-select.mjs.map +1 -1
  105. package/fesm2022/koobiq-components-sidebar.mjs +10 -0
  106. package/fesm2022/koobiq-components-sidebar.mjs.map +1 -1
  107. package/fesm2022/koobiq-components-sidepanel.mjs +34 -10
  108. package/fesm2022/koobiq-components-sidepanel.mjs.map +1 -1
  109. package/fesm2022/koobiq-components-splitter.mjs +4 -0
  110. package/fesm2022/koobiq-components-splitter.mjs.map +1 -1
  111. package/fesm2022/koobiq-components-tabs.mjs +27 -7
  112. package/fesm2022/koobiq-components-tabs.mjs.map +1 -1
  113. package/fesm2022/koobiq-components-tags.mjs +4 -2
  114. package/fesm2022/koobiq-components-tags.mjs.map +1 -1
  115. package/fesm2022/koobiq-components-textarea.mjs +7 -14
  116. package/fesm2022/koobiq-components-textarea.mjs.map +1 -1
  117. package/fesm2022/koobiq-components-timepicker.mjs +44 -19
  118. package/fesm2022/koobiq-components-timepicker.mjs.map +1 -1
  119. package/fesm2022/koobiq-components-timezone.mjs +10 -4
  120. package/fesm2022/koobiq-components-timezone.mjs.map +1 -1
  121. package/fesm2022/koobiq-components-title.mjs +41 -3
  122. package/fesm2022/koobiq-components-title.mjs.map +1 -1
  123. package/fesm2022/koobiq-components-toast.mjs +31 -3
  124. package/fesm2022/koobiq-components-toast.mjs.map +1 -1
  125. package/fesm2022/koobiq-components-toggle.mjs +2 -2
  126. package/fesm2022/koobiq-components-toggle.mjs.map +1 -1
  127. package/fesm2022/koobiq-components-tooltip.mjs +4 -1
  128. package/fesm2022/koobiq-components-tooltip.mjs.map +1 -1
  129. package/fesm2022/koobiq-components-tree-select.mjs +36 -12
  130. package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
  131. package/fesm2022/koobiq-components-tree.mjs +41 -37
  132. package/fesm2022/koobiq-components-tree.mjs.map +1 -1
  133. package/fesm2022/koobiq-components-username.mjs +2 -2
  134. package/fesm2022/koobiq-components-username.mjs.map +1 -1
  135. package/file-upload/dropzone.d.ts +0 -1
  136. package/file-upload/file-upload.scss +11 -0
  137. package/file-upload/multiple-file-upload.component.scss +29 -3
  138. package/file-upload/primitives/file-picker.d.ts +1 -1
  139. package/file-upload/single-file-upload.component.scss +10 -2
  140. package/filter-bar/filter-bar.d.ts +1 -1
  141. package/filter-bar/filter-bar.types.d.ts +2 -0
  142. package/filter-bar/filters.scss +3 -2
  143. package/filter-bar/pipes/base-pipe.d.ts +31 -0
  144. package/filter-bar/pipes/base-pipe.scss +0 -13
  145. package/filter-bar/pipes/pipe-date.d.ts +1 -1
  146. package/filter-bar/pipes/pipe-datetime.d.ts +1 -1
  147. package/filter-bar/pipes/pipe-input.d.ts +42 -0
  148. package/filter-bar/pipes/pipe-input.scss +10 -0
  149. package/filter-bar/public-api.d.ts +1 -0
  150. package/form-field/fieldset.scss +10 -0
  151. package/inline-edit/inline-edit.d.ts +5 -0
  152. package/inline-edit/inline-edit.scss +7 -7
  153. package/link/_link-theme.scss +50 -15
  154. package/list/_list-theme.scss +12 -0
  155. package/list/list-selection.component.d.ts +1 -0
  156. package/list/list.scss +2 -9
  157. package/modal/modal-tokens.scss +1 -1
  158. package/modal/modal.component.d.ts +9 -1
  159. package/modal/modal.directive.d.ts +11 -0
  160. package/modal/modal.type.d.ts +7 -0
  161. package/navbar/_navbar-item_horizontal.scss +5 -0
  162. package/navbar/_navbar-item_vertical.scss +7 -5
  163. package/navbar/navbar-item.component.d.ts +15 -0
  164. package/navbar/navbar.component.d.ts +1 -0
  165. package/navbar/vertical-navbar.scss +6 -0
  166. package/notification-center/notification-center.d.ts +13 -1
  167. package/notification-center/notification-center.scss +12 -0
  168. package/notification-center/notification-item.scss +6 -0
  169. package/overflow-items/overflow-items.d.ts +1 -0
  170. package/package.json +4 -4
  171. package/prebuilt-themes/dark-theme.css +1 -1
  172. package/prebuilt-themes/light-theme.css +1 -1
  173. package/prebuilt-themes/theme.css +1 -1
  174. package/radio/radio.component.d.ts +1 -5
  175. package/radio/radio.scss +18 -4
  176. package/resizer/resizer.d.ts +12 -0
  177. package/schematics/ng-add/index.js +2 -2
  178. package/select/select-option.directive.d.ts +1 -0
  179. package/select/select.component.d.ts +29 -4
  180. package/sidebar/sidebar.component.d.ts +3 -0
  181. package/sidepanel/sidepanel-directives.d.ts +2 -0
  182. package/sidepanel/sidepanel.service.d.ts +8 -0
  183. package/splitter/splitter.component.d.ts +1 -0
  184. package/tabs/tab-body.component.d.ts +2 -0
  185. package/tabs/tab-header.component.d.ts +1 -0
  186. package/tabs/tab-header.scss +1 -0
  187. package/tabs/tab-nav-bar.d.ts +1 -0
  188. package/tabs/tabs-tokens.scss +1 -1
  189. package/textarea/textarea.component.d.ts +0 -1
  190. package/timepicker/timepicker.directive.d.ts +3 -0
  191. package/timezone/timezone-option.directive.d.ts +1 -0
  192. package/title/title.directive.d.ts +21 -0
  193. package/toast/toast-container.component.d.ts +25 -0
  194. package/tree/_tree-theme.scss +5 -11
  195. package/tree/toggle.scss +4 -0
  196. package/tree/tree-option.component.d.ts +3 -0
  197. package/tree/tree-option.scss +2 -12
  198. package/tree/tree-selection.component.d.ts +1 -0
  199. package/tree-select/tree-select.component.d.ts +9 -2
@@ -104,13 +104,11 @@ export declare class KbqOption extends KbqOptionBase implements AfterViewChecked
104
104
  private _active;
105
105
  private mostRecentViewValue;
106
106
  /**
107
- * Flag that indicates whether the component is currently focused by a mouse interaction.
108
- *
109
- * When set to `true`, the component has focus resulting from a mouse click or
110
- * other pointer event. It is automatically cleared when the component loses
111
- * focus or if focus is obtained through keyboard navigation or programmatic means.
107
+ * Whether the pointer is currently over this option. Cleared on `mouseleave` rather than when the
108
+ * option is focused: hovering the option that is already active does not move the key manager's
109
+ * index, so no focus follows and a flag cleared only there would stay armed indefinitely.
112
110
  */
113
- private isFocusedByMouse;
111
+ private hoveredByPointer;
114
112
  constructor(elementRef: ElementRef<HTMLElement>, changeDetectorRef: ChangeDetectorRef, parent: KbqOptionParentComponent, group: KbqOptgroup);
115
113
  ngAfterViewChecked(): void;
116
114
  ngOnDestroy(): void;
@@ -118,6 +116,7 @@ export declare class KbqOption extends KbqOptionBase implements AfterViewChecked
118
116
  getHeight(): number;
119
117
  select(emitEvent?: boolean): void;
120
118
  deselect(emitEvent?: boolean): void;
119
+ /** Moves keyboard focus to this option and reveals it — see {@link kbqFocusAndReveal}. */
121
120
  focus(): void;
122
121
  /**
123
122
  * This method sets display styles on the option to make it appear
@@ -146,6 +145,8 @@ export declare class KbqOption extends KbqOptionBase implements AfterViewChecked
146
145
  getHostElement(): HTMLElement;
147
146
  /** @docs-private */
148
147
  protected onMouseenter(): void;
148
+ /** @docs-private */
149
+ protected onMouseleave(): void;
149
150
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqOption, [null, null, { optional: true; }, { optional: true; }]>;
150
151
  static ɵcmp: i0.ɵɵComponentDeclaration<KbqOption, "kbq-option", ["kbqOption"], { "value": { "alias": "value"; "required": false; }; "selectable": { "alias": "selectable"; "required": false; }; "userSelect": { "alias": "userSelect"; "required": false; }; "showCheckbox": { "alias": "showCheckbox"; "required": false; }; "viewValue": { "alias": "viewValue"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; }, { "onSelectionChange": "onSelectionChange"; }, never, ["kbq-pseudo-checkbox", "*"], true, never>;
151
152
  static ngAcceptInputType_selectable: unknown;
@@ -166,5 +167,8 @@ export declare function countGroupLabelsBeforeOption(optionIndex: number, option
166
167
  * @param currentScrollPosition Current scroll position of the panel.
167
168
  * @param panelHeight Height of the panel.
168
169
  * @docs-private
170
+ * @deprecated Unused — an option reveals itself on focus through `KbqOption.focus`, which lets the
171
+ * browser resolve the scroll container instead of computing an offset from a uniform row height. Will be
172
+ * removed in the next major release.
169
173
  */
170
174
  export declare function getOptionScrollPosition(optionIndex: number, optionHeight: number, currentScrollPosition: number, panelHeight: number): number;
@@ -1,6 +1,7 @@
1
1
  import { Directionality } from '@angular/cdk/bidi';
2
2
  import { CdkScrollable, ConnectedOverlayPositionChange, ConnectionPositionPair, FlexibleConnectedPositionStrategy, Overlay, OverlayConfig, OverlayRef, ScrollDispatcher, ScrollStrategy } from '@angular/cdk/overlay';
3
3
  import { ComponentPortal } from '@angular/cdk/portal';
4
+ import { ViewportRuler } from '@angular/cdk/scrolling';
4
5
  import { DestroyRef, ElementRef, EventEmitter, NgZone, OnDestroy, OnInit, TemplateRef, Type, ViewContainerRef } from '@angular/core';
5
6
  import { BehaviorSubject, Observable, Subscription } from 'rxjs';
6
7
  import { AsyncScheduler } from 'rxjs/internal/scheduler/AsyncScheduler';
@@ -14,6 +15,11 @@ export declare abstract class KbqPopUpTrigger<T> implements OnInit, OnDestroy {
14
15
  protected readonly elementRef: ElementRef<HTMLElement>;
15
16
  protected readonly ngZone: NgZone;
16
17
  protected readonly scrollDispatcher: ScrollDispatcher;
18
+ /** CDK ViewportRuler, used to re-apply the stick-to-window position on window resize.
19
+ * @docs-private */
20
+ protected readonly viewportRuler: ViewportRuler;
21
+ /** View container the pop-up component portal is attached to.
22
+ * @docs-private */
17
23
  protected readonly hostView: ViewContainerRef;
18
24
  protected readonly direction: Directionality | null;
19
25
  protected readonly destroyRef: DestroyRef;
@@ -10,7 +10,14 @@ export declare const KBQ_SELECT_SEARCH_MIN_OPTIONS_THRESHOLD = 10;
10
10
  * this value or more away from the viewport boundary.
11
11
  */
12
12
  export declare const SELECT_PANEL_VIEWPORT_PADDING = 8;
13
- /** Injection token that determines the scroll handling while a select is open. */
13
+ /**
14
+ * Injection token that determines the scroll handling while a select is open.
15
+ *
16
+ * The root default keeps the select usable when it is reached outside `KbqSelectModule`'s injector - imported
17
+ * as a bare standalone component, pulled in through another standalone component (`KbqTimezoneSelect`,
18
+ * `KbqCalendarHeader`), or rendered in a component built from the root injector, as `KbqModalService` does.
19
+ * Providing the token anywhere still wins over this default.
20
+ */
14
21
  export declare const KBQ_SELECT_SCROLL_STRATEGY: InjectionToken<() => ScrollStrategy>;
15
22
  /** @docs-private */
16
23
  export declare function kbqSelectScrollStrategyProviderFactory(overlay: Overlay): () => RepositionScrollStrategy;
@@ -1,6 +1,7 @@
1
1
  import * as i0 from "@angular/core";
2
2
  export declare class KbqMeasureScrollbarService {
3
3
  protected readonly document: Document;
4
+ private readonly platform;
4
5
  get scrollBarWidth(): number;
5
6
  private _scrollBarWidth;
6
7
  private scrollbarMeasure;
@@ -8,33 +8,44 @@
8
8
  }
9
9
  }
10
10
 
11
+ // Renders the striped "loading" shimmer used by .kbq-progress. Extracted into a mixin so
12
+ // components whose `::before`/`::after` pseudo-elements are already spoken for (e.g. kbq-dropdown-item's
13
+ // hit-area extension) can apply the same overlay to a real element instead.
14
+ @mixin kbq-progress-overlay() {
15
+ content: '';
16
+ position: absolute;
17
+ border-radius: inherit;
18
+
19
+ top: 0;
20
+ right: 0;
21
+ bottom: 0;
22
+ left: 0;
23
+
24
+ $lighter: rgba(255, 255, 255, 0.1);
25
+ $darker: rgba(0, 0, 0, 0.04);
26
+
27
+ background: linear-gradient(
28
+ 135deg,
29
+ $darker 12px,
30
+ $lighter 12px,
31
+ $lighter 22px,
32
+ $darker 22px,
33
+ $darker 34px,
34
+ $lighter 34px
35
+ )
36
+ repeat;
37
+ background-size: 32px 32px;
38
+ animation: kbq-progress 1s linear infinite;
39
+ }
40
+
11
41
  .kbq-progress {
12
42
  position: relative;
13
43
 
14
44
  &:after {
15
- content: '';
16
- position: absolute;
17
- border-radius: inherit;
18
-
19
- top: 0;
20
- right: 0;
21
- bottom: 0;
22
- left: 0;
23
-
24
- $lighter: rgba(255, 255, 255, 0.1);
25
- $darker: rgba(0, 0, 0, 0.04);
26
-
27
- background: linear-gradient(
28
- 135deg,
29
- $darker 12px,
30
- $lighter 12px,
31
- $lighter 22px,
32
- $darker 22px,
33
- $darker 34px,
34
- $lighter 34px
35
- )
36
- repeat;
37
- background-size: 32px 32px;
38
- animation: kbq-progress 1s linear infinite;
45
+ @include kbq-progress-overlay();
46
+
47
+ @media (prefers-reduced-motion: reduce) {
48
+ animation: none;
49
+ }
39
50
  }
40
51
  }
@@ -122,9 +122,16 @@
122
122
  overflow: hidden;
123
123
 
124
124
  & .kbq-select__match-hidden-text {
125
- flex: 0 0 40px;
125
+ // This is the box the matcher reserves for the "+N" counter, and `flex-basis` obeys
126
+ // `box-sizing` exactly as `width` does. Under a global `border-box` reset in a consuming
127
+ // application the padding would come out of the reserved width, so the counter would get
128
+ // 8px less room than `KbqSelect` measured for it and the tag count would be off by one
129
+ // at the boundary.
130
+ box-sizing: content-box;
131
+
132
+ flex: 0 0 var(--kbq-form-field-size-addon-width);
126
133
  align-self: center;
127
- padding-left: 4px;
134
+ padding-left: var(--kbq-size-xxs);
128
135
  padding-right: var(--kbq-select-size-multiple-content-gap, var(--kbq-size-xxs));
129
136
 
130
137
  text-align: right;
@@ -232,6 +239,14 @@
232
239
  padding: var(--kbq-size-xxs) var(--kbq-size-l);
233
240
  }
234
241
 
242
+ // Extends an item's hit area past the box it paints, with a transparent pseudo-element on the element
243
+ // that owns the click handler — a pseudo-element is hit-tested as part of that element, so hover and
244
+ // click both reach the gutter with no TS and no `z-index`. This one claims a fixed strip either side of
245
+ // a plain vertical list. The same technique, sized differently, is hand-rolled where the geometry does
246
+ // not fit: `.kbq-navbar-item`'s `:before` cancels the item's own margin (DS-2558), and
247
+ // `--kbq-button-toggle-size-item-hit-area-*` tiles a group's `gap` between two neighbours and hands the
248
+ // group's padding to the outermost items, per orientation (DS-4164). Any clipping ancestor eats all of
249
+ // them — see the note on `.kbq-button-toggle`'s `overflow`.
235
250
  @mixin item-active-area($outline) {
236
251
  position: relative;
237
252
 
@@ -73,7 +73,11 @@
73
73
 
74
74
  &::-webkit-scrollbar-track,
75
75
  &::-webkit-scrollbar-corner,
76
+ &::-webkit-resizer,
76
77
  &::-webkit-scrollbar,
78
+ ::-webkit-scrollbar-track,
79
+ ::-webkit-scrollbar-corner,
80
+ ::-webkit-resizer,
77
81
  ::-webkit-scrollbar {
78
82
  background-color: transparent;
79
83
  }
@@ -239,6 +239,10 @@
239
239
  @include kbq-typography-level-to-styles-css-variables(typography, mono-normal-strong);
240
240
  }
241
241
 
242
+ .kbq-mono-normal-medium {
243
+ @include kbq-typography-level-to-styles-css-variables(typography, mono-normal-medium);
244
+ }
245
+
242
246
  .kbq-mono-compact {
243
247
  @include kbq-typography-level-to-styles-css-variables(typography, mono-compact);
244
248
  }
@@ -247,6 +251,10 @@
247
251
  @include kbq-typography-level-to-styles-css-variables(typography, mono-compact-strong);
248
252
  }
249
253
 
254
+ .kbq-mono-codeblock {
255
+ @include kbq-typography-level-to-styles-css-variables(typography, mono-codeblock);
256
+ }
257
+
250
258
  .kbq-tabular-big {
251
259
  @include kbq-typography-level-to-styles-css-variables(typography, tabular-big);
252
260
  }
@@ -2,3 +2,15 @@
2
2
  * Injects the native element for the current component.
3
3
  */
4
4
  export declare const kbqInjectNativeElement: <T extends Element = HTMLElement>() => T;
5
+ /**
6
+ * Focuses `element` and scrolls it into view by the shortest distance, leaving a visible one alone.
7
+ *
8
+ * The reveal is explicit because the one `focus()` performs implicitly is not portable: WebKit defers it
9
+ * to a later rendering update, where it lands after — and undoes — any scrolling the reader did in the
10
+ * meantime. Letting the element reveal itself keeps every consumer working, whatever it uses as a scroll
11
+ * container, and the browser resolves that container rather than the caller guessing at it.
12
+ *
13
+ * Pass `skipReveal` when the pointer caused the focus: the element is already under the cursor, so
14
+ * revealing it would shift the list out from under it.
15
+ */
16
+ export declare const kbqFocusAndReveal: (element: HTMLElement, skipReveal?: boolean) => void;
@@ -82,11 +82,27 @@ export declare class KbqDatepickerInput<D> implements KbqFormFieldControl<D>, Co
82
82
  get value(): D | null;
83
83
  set value(value: D | null);
84
84
  private _value;
85
- /** The minimum valid date. */
85
+ /**
86
+ * The minimum valid date. Drives validation only — including dates typed or pasted into the
87
+ * input — and reports `kbqDatepickerMin`. The calendar is restricted separately, by `minDate`
88
+ * on the associated `<kbq-datepicker>`.
89
+ *
90
+ * Compared down to the millisecond, not by calendar day: the input keeps the time part of the
91
+ * value it parses, and the comparison is made on wall-clock components rather than on absolute
92
+ * time.
93
+ */
86
94
  get min(): D | null;
87
95
  set min(value: D | null);
88
96
  private _min;
89
- /** The maximum valid date. */
97
+ /**
98
+ * The maximum valid date. Drives validation only — including dates typed or pasted into the
99
+ * input — and reports `kbqDatepickerMax`. The calendar is restricted separately, by `maxDate`
100
+ * on the associated `<kbq-datepicker>`.
101
+ *
102
+ * Compared down to the millisecond, not by calendar day: the input keeps the time part of the
103
+ * value it parses, so an upper bound meant to include its whole day has to be the end of that
104
+ * day.
105
+ */
90
106
  get max(): D | null;
91
107
  set max(value: D | null);
92
108
  private _max;
@@ -112,9 +128,7 @@ export declare class KbqDatepickerInput<D> implements KbqFormFieldControl<D>, Co
112
128
  set errorState(value: boolean);
113
129
  private get readyForParse();
114
130
  private get selectionStart();
115
- private set selectionStart(value);
116
131
  private get selectionEnd();
117
- private set selectionEnd(value);
118
132
  private control;
119
133
  private readonly uid;
120
134
  private datepickerSubscription;
@@ -168,6 +182,7 @@ export declare class KbqDatepickerInput<D> implements KbqFormFieldControl<D>, Co
168
182
  private spaceKeyHandler;
169
183
  private getNewValue;
170
184
  private setViewValue;
185
+ private setSelection;
171
186
  private replaceSymbols;
172
187
  private getDateFromString;
173
188
  private getDefaultValue;
@@ -215,7 +230,7 @@ export declare class KbqDatepickerInput<D> implements KbqFormFieldControl<D>, Co
215
230
  private getDigitPositions;
216
231
  private createDate;
217
232
  private createDateTime;
218
- private correctCursorPosition;
233
+ private correctedCursorPosition;
219
234
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqDatepickerInput<any>, [null, null, { optional: true; }, { optional: true; }]>;
220
235
  static ɵdir: i0.ɵɵDirectiveDeclaration<KbqDatepickerInput<any>, "input[kbqDatepicker], input[kbqCalendar]", ["kbqDatepickerInput"], { "errorStateMatcher": { "alias": "errorStateMatcher"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "required": { "alias": "required"; "required": false; }; "kbqDatepicker": { "alias": "kbqDatepicker"; "required": false; }; "kbqCalendar": { "alias": "kbqCalendar"; "required": false; }; "kbqDatepickerFilter": { "alias": "kbqDatepickerFilter"; "required": false; }; "value": { "alias": "value"; "required": false; }; "min": { "alias": "min"; "required": false; }; "max": { "alias": "max"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "id": { "alias": "id"; "required": false; }; "kbqValidationTooltip": { "alias": "kbqValidationTooltip"; "required": false; }; }, { "incorrectInput": "incorrectInput"; "dateChange": "dateChange"; "dateInput": "dateInput"; }, never, never, true, never>;
221
236
  }
@@ -7,7 +7,10 @@ import { KbqCalendarCellCssClasses } from './calendar-body.component';
7
7
  import { KbqCalendar } from './calendar.component';
8
8
  import { KbqDatepickerInput } from './datepicker-input.directive';
9
9
  import * as i0 from "@angular/core";
10
- /** Injection token that determines the scroll handling while the calendar is open. */
10
+ /**
11
+ * Injection token that determines the scroll handling while the calendar is open. The root default keeps the
12
+ * datepicker usable outside `KbqDatepickerModule`'s injector; providing the token anywhere still wins over it.
13
+ */
11
14
  export declare const KBQ_DATEPICKER_SCROLL_STRATEGY: InjectionToken<() => ScrollStrategy>;
12
15
  /** @docs-private */
13
16
  export declare function KBQ_DATEPICKER_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy;
@@ -10,6 +10,7 @@ export declare class KbqDlComponent implements AfterContentInit, OnDestroy {
10
10
  private resizeSubscription;
11
11
  private readonly elementRef;
12
12
  private readonly changeDetectorRef;
13
+ private readonly platform;
13
14
  ngAfterContentInit(): void;
14
15
  ngOnDestroy(): void;
15
16
  private readonly updateState;
package/dl/dl.scss CHANGED
@@ -7,6 +7,16 @@
7
7
 
8
8
  grid-template-columns: repeat(4, 1fr);
9
9
 
10
+ // Let the columns keep their `1fr` ratio instead of being stretched by an unbreakable string: `min-width: 0`
11
+ // drops the grid item's content-based automatic minimum, and `break-word` breaks such a string only when it
12
+ // does not fit. `anywhere` is deliberately avoided — it would also shrink the min-content size to a single
13
+ // character and leak that to any ancestor that sizes itself to content.
14
+ .kbq-dt,
15
+ .kbq-dd {
16
+ min-width: 0;
17
+ overflow-wrap: break-word;
18
+ }
19
+
10
20
  .kbq-dt {
11
21
  grid-column: 1;
12
22
  }
@@ -19,6 +19,8 @@ export declare class KbqDropdownItem implements KbqTitleTextRef, IFocusableOptio
19
19
  get disabled(): boolean;
20
20
  set disabled(value: boolean);
21
21
  private _disabled;
22
+ /** Whether the dropdown item is in a loading state. */
23
+ readonly progress: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
22
24
  /** Stream that emits when the dropdown item is hovered. */
23
25
  readonly hovered: Subject<KbqDropdownItem>;
24
26
  /** Stream that emits when the menu item is focused. */
@@ -33,7 +35,13 @@ export declare class KbqDropdownItem implements KbqTitleTextRef, IFocusableOptio
33
35
  ngAfterViewInit(): void;
34
36
  ngOnDestroy(): void;
35
37
  resetStyles(): void;
36
- /** Focuses the dropdown item. */
38
+ /**
39
+ * Focuses the dropdown item and reveals it.
40
+ *
41
+ * The reveal is explicit because the one `focus()` performs implicitly is not portable: WebKit defers
42
+ * it to a later rendering update, where it lands after — and undoes — any scrolling the reader did in
43
+ * the meantime. `preventScroll` is therefore always forced on, overriding `options`.
44
+ */
37
45
  focus(origin?: FocusOrigin, options?: FocusOptions): void;
38
46
  /** Returns the host DOM element. */
39
47
  getHostElement(): HTMLElement;
@@ -47,6 +55,6 @@ export declare class KbqDropdownItem implements KbqTitleTextRef, IFocusableOptio
47
55
  getLabel(): string;
48
56
  haltDisabledEvents(event: Event): void;
49
57
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqDropdownItem, [null, null, { optional: true; }]>;
50
- static ɵcmp: i0.ɵɵComponentDeclaration<KbqDropdownItem, "kbq-dropdown-item, [kbq-dropdown-item]", ["kbqDropdownItem"], { "disabled": { "alias": "disabled"; "required": false; }; }, {}, ["icon"], ["[kbq-icon]", "*"], true, never>;
58
+ 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>;
51
59
  static ngAcceptInputType_disabled: unknown;
52
60
  }
@@ -1,3 +1,4 @@
1
+ @use '../core/styles/common/animation';
1
2
  @use '../core/styles/common/list';
2
3
  @use '../core/styles/common/vendor-prefixes';
3
4
 
@@ -47,6 +48,21 @@
47
48
  border-radius: inherit;
48
49
  }
49
50
 
51
+ // kbq-dropdown-item's :before/:after are already used for the hit-area extension (see
52
+ // select.item-active-area() in dropdown.scss), so the .kbq-progress shimmer is rendered on the
53
+ // existing overlay element instead of the usual ::after.
54
+ .kbq-dropdown-item.kbq-progress .kbq-dropdown-item-overlay {
55
+ @include animation.kbq-progress-overlay();
56
+
57
+ // .kbq-dropdown-item-overlay's default inset (-1px) only bleeds past the padding box, leaving
58
+ // the item's own border uncovered. Flush the shimmer to the item's outer edge instead.
59
+ inset: calc(-1 * var(--kbq-size-3xs));
60
+
61
+ @media (prefers-reduced-motion: reduce) {
62
+ animation: none;
63
+ }
64
+ }
65
+
50
66
  .kbq-dropdown__group-header {
51
67
  @include vendor-prefixes.user-select(none);
52
68
  @include list.kbq-list-header-base();
@@ -6,7 +6,10 @@ import { KbqDropdownItem } from './dropdown-item.component';
6
6
  import { KbqDropdown } from './dropdown.component';
7
7
  import { DropdownCloseReason, KbqDropdownPanel } from './dropdown.types';
8
8
  import * as i0 from "@angular/core";
9
- /** Injection token that determines the scroll handling while the dropdown is open. */
9
+ /**
10
+ * Injection token that determines the scroll handling while the dropdown is open. The root default keeps the
11
+ * trigger usable outside `KbqDropdownModule`'s injector; providing the token anywhere still wins over it.
12
+ */
10
13
  export declare const KBQ_DROPDOWN_SCROLL_STRATEGY: InjectionToken<() => ScrollStrategy>;
11
14
  /** @docs-private */
12
15
  export declare function KBQ_DROPDOWN_SCROLL_STRATEGY_FACTORY(overlay: Overlay): () => ScrollStrategy;
@@ -86,6 +89,8 @@ export declare class KbqDropdownTrigger implements AfterContentInit, OnDestroy {
86
89
  private overlayRef;
87
90
  private closeSubscription;
88
91
  private hoverSubscription;
92
+ /** Waits for the exit animation to finish a close; must not outlive the trigger, or it emits once destroyed. */
93
+ private readonly closeAnimationSubscriptions;
89
94
  private classAddedToOverlayContainer;
90
95
  constructor(overlay: Overlay, elementRef: ElementRef<HTMLElement>, viewContainerRef: ViewContainerRef, scrollStrategy: any, parent: KbqDropdown, dropdownItemInstance: KbqDropdownItem, _dir: Directionality, changeDetectorRef: ChangeDetectorRef, focusMonitor?: FocusMonitor | undefined);
91
96
  ngAfterContentInit(): void;
@@ -11,6 +11,11 @@ export declare class KbqDropdownStaticContent {
11
11
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqDropdownStaticContent, never>;
12
12
  static ɵdir: i0.ɵɵDirectiveDeclaration<KbqDropdownStaticContent, "[kbqDropdownStaticContent]", never, {}, {}, never, never, true, never>;
13
13
  }
14
+ /** Footer that is rendered below the dropdown options panel. */
15
+ export declare class KbqDropdownFooter {
16
+ static ɵfac: i0.ɵɵFactoryDeclaration<KbqDropdownFooter, never>;
17
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KbqDropdownFooter, "[kbqDropdownFooter], kbq-dropdown-footer", never, {}, {}, never, never, true, never>;
18
+ }
14
19
  export declare class KbqDropdown implements AfterContentInit, KbqDropdownPanel, OnInit, OnDestroy {
15
20
  private elementRef;
16
21
  private ngZone;
@@ -130,5 +135,5 @@ export declare class KbqDropdown implements AfterContentInit, KbqDropdownPanel,
130
135
  */
131
136
  private updateDirectDescendants;
132
137
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqDropdown, never>;
133
- static ɵcmp: i0.ɵɵComponentDeclaration<KbqDropdown, "kbq-dropdown", ["kbqDropdown"], { "navigationWithWrap": { "alias": "navigationWithWrap"; "required": false; }; "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; }; }, { "closed": "closed"; }, ["search", "lazyContent", "items"], ["*", "[kbqDropdownStaticContent]"], true, never>;
138
+ static ɵcmp: i0.ɵɵComponentDeclaration<KbqDropdown, "kbq-dropdown", ["kbqDropdown"], { "navigationWithWrap": { "alias": "navigationWithWrap"; "required": false; }; "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; }; }, { "closed": "closed"; }, ["search", "lazyContent", "items"], ["*", "[kbqDropdownFooter], kbq-dropdown-footer", "[kbqDropdownStaticContent]"], true, never>;
134
139
  }
@@ -8,6 +8,6 @@ import * as i6 from "./dropdown-trigger.directive";
8
8
  import * as i7 from "./dropdown-content.directive";
9
9
  export declare class KbqDropdownModule {
10
10
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqDropdownModule, never>;
11
- static ɵmod: i0.ɵɵNgModuleDeclaration<KbqDropdownModule, never, [typeof i1.OverlayModule, typeof i2.KbqIconModule, typeof i3.NgClass, typeof i4.KbqDropdownStaticContent, typeof i4.KbqDropdown, typeof i5.KbqDropdownItem, typeof i6.KbqDropdownTrigger, typeof i7.KbqDropdownContent], [typeof i4.KbqDropdown, typeof i5.KbqDropdownItem, typeof i6.KbqDropdownTrigger, typeof i7.KbqDropdownContent, typeof i4.KbqDropdownStaticContent]>;
11
+ static ɵmod: i0.ɵɵNgModuleDeclaration<KbqDropdownModule, never, [typeof i1.OverlayModule, typeof i2.KbqIconModule, typeof i3.NgClass, typeof i4.KbqDropdownStaticContent, typeof i4.KbqDropdown, typeof i5.KbqDropdownItem, typeof i6.KbqDropdownTrigger, typeof i7.KbqDropdownContent, typeof i4.KbqDropdownFooter], [typeof i4.KbqDropdown, typeof i5.KbqDropdownItem, typeof i6.KbqDropdownTrigger, typeof i7.KbqDropdownContent, typeof i4.KbqDropdownStaticContent, typeof i4.KbqDropdownFooter]>;
12
12
  static ɵinj: i0.ɵɵInjectorDeclaration<KbqDropdownModule>;
13
13
  }
@@ -3,8 +3,8 @@
3
3
 
4
4
  .kbq-dropdown-trigger {
5
5
  &.kbq-button {
6
- padding-left: calc(10px - var(--kbq-size-border-width));
7
- padding-right: calc(10px - var(--kbq-size-border-width));
6
+ padding-left: calc(var(--kbq-dropdown-trigger-horizontal-padding, 10px) - var(--kbq-size-border-width));
7
+ padding-right: calc(var(--kbq-dropdown-trigger-horizontal-padding, 10px) - var(--kbq-size-border-width));
8
8
 
9
9
  & .kbq-icon_left {
10
10
  margin-right: var(--kbq-size-xs);
@@ -45,7 +45,6 @@
45
45
  border-radius: var(--kbq-dropdown-size-container-border-radius);
46
46
 
47
47
  box-sizing: border-box;
48
- padding: var(--kbq-size-xxs);
49
48
 
50
49
  // Prevent users from interacting with the panel while it's animating. Note that
51
50
  // people won't be able to click through it, because the overlay pane will catch the click.
@@ -66,6 +65,15 @@
66
65
  top: calc(-1 * var(--kbq-size-3xs));
67
66
  bottom: calc(-1 * var(--kbq-size-3xs));
68
67
  }
68
+
69
+ // The generic .kbq-progress::after rule (see _animation.scss) would otherwise paint the
70
+ // shimmer onto this hit-area pseudo-element. The shimmer is rendered on
71
+ // .kbq-dropdown-item-overlay instead (see dropdown-item.scss), so just neutralize it here
72
+ // without touching content/position/width/height/left, which the hit-area still needs.
73
+ &.kbq-progress:after {
74
+ background: none;
75
+ animation: none;
76
+ }
69
77
  }
70
78
 
71
79
  .kbq-divider {
@@ -77,6 +85,13 @@
77
85
  .kbq-dropdown__content {
78
86
  display: flex;
79
87
  flex-direction: column;
88
+
89
+ padding: var(--kbq-size-xxs);
90
+ }
91
+
92
+ .kbq-dropdown-footer {
93
+ @extend %kbq-select-footer;
94
+ border-color: var(--kbq-line-contrast-less);
80
95
  }
81
96
 
82
97
  @include theme.kbq-dropdown-theme();
@@ -2,20 +2,53 @@ import { AfterViewInit, OnDestroy, OnInit } from '@angular/core';
2
2
  import { KbqTooltipTrigger } from '@koobiq/components/tooltip';
3
3
  import { Subject } from 'rxjs';
4
4
  import * as i0 from "@angular/core";
5
+ /**
6
+ * Renders text as two spans and moves the ellipsis into the middle, so the tail — a file extension, the
7
+ * digits that tell two reports apart — stays readable when the host is too narrow for the whole string. A
8
+ * tooltip spells out the full text, and is enabled only while something is actually hidden.
9
+ *
10
+ * The host needs the layout contract the consuming component ships (see `.kbq-ellipsis-center` in
11
+ * `file-upload.scss`): the two spans have no styles of their own.
12
+ */
5
13
  export declare class KbqEllipsisCenterDirective extends KbqTooltipTrigger implements OnInit, AfterViewInit, OnDestroy {
6
14
  private cdr;
15
+ /**
16
+ * Application-wide `ResizeObserver` shared by every consumer, as `KbqTitleDirective` uses. Unlike the
17
+ * `window:resize` listener this directive used to carry, it also reacts to container-only resizes — a
18
+ * splitter drag, a sidebar collapse, or the vertical scrollbar that appears once a file list fills up —
19
+ * none of which resize the window, all of which change where the text has to be split.
20
+ */
21
+ private readonly resizeObserver;
7
22
  set kbqEllipsisCenter(value: string);
23
+ /**
24
+ * Shortest text worth splitting in the middle. Anything below it keeps its natural order and is cut off
25
+ * at the end by the host's own `text-overflow`.
26
+ *
27
+ * Defaults to `0` — every overflowing text is split — because that is what the directive has always
28
+ * done: the input was declared but never read, so any other default would silently end-truncate labels
29
+ * that consumers expect to see split.
30
+ */
8
31
  minVisibleLength: number;
32
+ /**
33
+ * Lower bound, in pixels, for the average glyph width used to decide how many characters fit in the
34
+ * tail. The rendered text is measured as well and the wider of the two wins, so an underestimate here
35
+ * can no longer push the extension out of the tail — raising it only shortens the tail further.
36
+ */
9
37
  charWidth: number;
10
38
  /**
11
39
  * Debounce time (ms) for resize events before recalculating ellipsis position.
12
40
  * @default 50
13
41
  */
14
42
  debounceInterval: number;
15
- /** @docs-private */
43
+ /**
44
+ * @deprecated No longer read. Resizes now come from the shared `ResizeObserver`, which also catches the
45
+ * container-only ones a `window:resize` listener cannot see; the host listener that used to feed this
46
+ * subject is gone, and nothing subscribes to it. Kept as a no-op and removed in the next major version.
47
+ * @docs-private */
16
48
  readonly resizeStream: Subject<Event>;
17
49
  private _kbqEllipsisCenter;
18
- private resizeSubscription;
50
+ private lastMeasuredWidth;
51
+ private refreshTimeoutId;
19
52
  ngOnInit(): void;
20
53
  ngAfterViewInit(): void;
21
54
  ngOnDestroy(): void;