@koobiq/components 19.8.5 → 19.8.7

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 (204) 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/app-switcher/app-switcher.d.ts +9 -2
  6. package/autocomplete/autocomplete-trigger.directive.d.ts +10 -5
  7. package/breadcrumbs/breadcrumbs.d.ts +2 -0
  8. package/breadcrumbs/breadcrumbs.scss +4 -0
  9. package/button/button-group.scss +42 -2
  10. package/button-toggle/button-toggle-tokens.scss +16 -0
  11. package/button-toggle/button-toggle.component.d.ts +3 -1
  12. package/button-toggle/button-toggle.scss +105 -1
  13. package/checkbox/checkbox.scss +5 -4
  14. package/clamped-text/clamped-text.d.ts +1 -0
  15. package/core/form-field/field-sizing-content.d.ts +0 -1
  16. package/core/form-field/form-field-ref.d.ts +1 -0
  17. package/core/form-field/index.d.ts +1 -0
  18. package/core/form-field/text-field-selection.d.ts +18 -0
  19. package/core/form-field/text-ruler.d.ts +16 -0
  20. package/core/navbar/rectangle-item.d.ts +8 -0
  21. package/core/option/_action-container-mixins.scss +28 -0
  22. package/core/option/_option-theme.scss +8 -0
  23. package/core/option/action.d.ts +9 -0
  24. package/core/option/action.scss +7 -0
  25. package/core/option/option.d.ts +10 -6
  26. package/core/pop-up/pop-up-trigger.d.ts +6 -0
  27. package/core/select/constants.d.ts +8 -1
  28. package/core/services/measure-scrollbar.service.d.ts +1 -0
  29. package/core/styles/common/_animation.scss +35 -24
  30. package/core/styles/common/_select.scss +21 -3
  31. package/core/styles/theming/_scrollbar-theme.scss +4 -0
  32. package/core/styles/typography/_typography.scss +8 -0
  33. package/core/utils/dom.d.ts +12 -0
  34. package/datepicker/datepicker-input.directive.d.ts +20 -5
  35. package/datepicker/datepicker.component.d.ts +4 -1
  36. package/dl/dl.component.d.ts +1 -0
  37. package/dl/dl.scss +10 -0
  38. package/dropdown/dropdown-item.component.d.ts +10 -2
  39. package/dropdown/dropdown-item.scss +16 -0
  40. package/dropdown/dropdown-trigger.directive.d.ts +6 -1
  41. package/dropdown/dropdown.component.d.ts +6 -1
  42. package/dropdown/dropdown.module.d.ts +1 -1
  43. package/dropdown/dropdown.scss +18 -3
  44. package/ellipsis-center/ellipsis-center.directive.d.ts +40 -2
  45. package/fesm2022/koobiq-components-accordion.mjs +104 -16
  46. package/fesm2022/koobiq-components-accordion.mjs.map +1 -1
  47. package/fesm2022/koobiq-components-alert.mjs +2 -2
  48. package/fesm2022/koobiq-components-app-switcher.mjs +8 -8
  49. package/fesm2022/koobiq-components-app-switcher.mjs.map +1 -1
  50. package/fesm2022/koobiq-components-autocomplete.mjs +21 -9
  51. package/fesm2022/koobiq-components-autocomplete.mjs.map +1 -1
  52. package/fesm2022/koobiq-components-breadcrumbs.mjs +10 -5
  53. package/fesm2022/koobiq-components-breadcrumbs.mjs.map +1 -1
  54. package/fesm2022/koobiq-components-button-toggle.mjs +8 -5
  55. package/fesm2022/koobiq-components-button-toggle.mjs.map +1 -1
  56. package/fesm2022/koobiq-components-button.mjs +4 -4
  57. package/fesm2022/koobiq-components-button.mjs.map +1 -1
  58. package/fesm2022/koobiq-components-checkbox.mjs +2 -2
  59. package/fesm2022/koobiq-components-checkbox.mjs.map +1 -1
  60. package/fesm2022/koobiq-components-clamped-text.mjs +4 -0
  61. package/fesm2022/koobiq-components-clamped-text.mjs.map +1 -1
  62. package/fesm2022/koobiq-components-code-block.mjs +14 -5
  63. package/fesm2022/koobiq-components-code-block.mjs.map +1 -1
  64. package/fesm2022/koobiq-components-content-panel.mjs +5 -4
  65. package/fesm2022/koobiq-components-content-panel.mjs.map +1 -1
  66. package/fesm2022/koobiq-components-core.mjs +244 -67
  67. package/fesm2022/koobiq-components-core.mjs.map +1 -1
  68. package/fesm2022/koobiq-components-datepicker.mjs +73 -49
  69. package/fesm2022/koobiq-components-datepicker.mjs.map +1 -1
  70. package/fesm2022/koobiq-components-dl.mjs +5 -4
  71. package/fesm2022/koobiq-components-dl.mjs.map +1 -1
  72. package/fesm2022/koobiq-components-dropdown.mjs +65 -22
  73. package/fesm2022/koobiq-components-dropdown.mjs.map +1 -1
  74. package/fesm2022/koobiq-components-ellipsis-center.mjs +82 -22
  75. package/fesm2022/koobiq-components-ellipsis-center.mjs.map +1 -1
  76. package/fesm2022/koobiq-components-file-upload.mjs +12 -12
  77. package/fesm2022/koobiq-components-file-upload.mjs.map +1 -1
  78. package/fesm2022/koobiq-components-filter-bar.mjs +152 -46
  79. package/fesm2022/koobiq-components-filter-bar.mjs.map +1 -1
  80. package/fesm2022/koobiq-components-form-field.mjs +27 -6
  81. package/fesm2022/koobiq-components-form-field.mjs.map +1 -1
  82. package/fesm2022/koobiq-components-icon.mjs +1 -1
  83. package/fesm2022/koobiq-components-icon.mjs.map +1 -1
  84. package/fesm2022/koobiq-components-inline-edit.mjs +26 -5
  85. package/fesm2022/koobiq-components-inline-edit.mjs.map +1 -1
  86. package/fesm2022/koobiq-components-list.mjs +12 -22
  87. package/fesm2022/koobiq-components-list.mjs.map +1 -1
  88. package/fesm2022/koobiq-components-markdown.mjs +4 -1
  89. package/fesm2022/koobiq-components-markdown.mjs.map +1 -1
  90. package/fesm2022/koobiq-components-modal.mjs +53 -12
  91. package/fesm2022/koobiq-components-modal.mjs.map +1 -1
  92. package/fesm2022/koobiq-components-navbar.mjs +69 -21
  93. package/fesm2022/koobiq-components-navbar.mjs.map +1 -1
  94. package/fesm2022/koobiq-components-notification-center.mjs +45 -7
  95. package/fesm2022/koobiq-components-notification-center.mjs.map +1 -1
  96. package/fesm2022/koobiq-components-overflow-items.mjs +4 -0
  97. package/fesm2022/koobiq-components-overflow-items.mjs.map +1 -1
  98. package/fesm2022/koobiq-components-popover.mjs +39 -19
  99. package/fesm2022/koobiq-components-popover.mjs.map +1 -1
  100. package/fesm2022/koobiq-components-radio.mjs +3 -7
  101. package/fesm2022/koobiq-components-radio.mjs.map +1 -1
  102. package/fesm2022/koobiq-components-resizer.mjs +23 -4
  103. package/fesm2022/koobiq-components-resizer.mjs.map +1 -1
  104. package/fesm2022/koobiq-components-search-expandable.mjs +2 -1
  105. package/fesm2022/koobiq-components-search-expandable.mjs.map +1 -1
  106. package/fesm2022/koobiq-components-select.mjs +174 -40
  107. package/fesm2022/koobiq-components-select.mjs.map +1 -1
  108. package/fesm2022/koobiq-components-sidebar.mjs +10 -0
  109. package/fesm2022/koobiq-components-sidebar.mjs.map +1 -1
  110. package/fesm2022/koobiq-components-sidepanel.mjs +34 -10
  111. package/fesm2022/koobiq-components-sidepanel.mjs.map +1 -1
  112. package/fesm2022/koobiq-components-splitter.mjs +4 -0
  113. package/fesm2022/koobiq-components-splitter.mjs.map +1 -1
  114. package/fesm2022/koobiq-components-tabs.mjs +27 -7
  115. package/fesm2022/koobiq-components-tabs.mjs.map +1 -1
  116. package/fesm2022/koobiq-components-tags.mjs +3 -1
  117. package/fesm2022/koobiq-components-tags.mjs.map +1 -1
  118. package/fesm2022/koobiq-components-textarea.mjs +7 -14
  119. package/fesm2022/koobiq-components-textarea.mjs.map +1 -1
  120. package/fesm2022/koobiq-components-time-range.mjs +20 -2
  121. package/fesm2022/koobiq-components-time-range.mjs.map +1 -1
  122. package/fesm2022/koobiq-components-timepicker.mjs +44 -19
  123. package/fesm2022/koobiq-components-timepicker.mjs.map +1 -1
  124. package/fesm2022/koobiq-components-timezone.mjs +17 -6
  125. package/fesm2022/koobiq-components-timezone.mjs.map +1 -1
  126. package/fesm2022/koobiq-components-title.mjs +50 -7
  127. package/fesm2022/koobiq-components-title.mjs.map +1 -1
  128. package/fesm2022/koobiq-components-toast.mjs +31 -3
  129. package/fesm2022/koobiq-components-toast.mjs.map +1 -1
  130. package/fesm2022/koobiq-components-toggle.mjs +2 -2
  131. package/fesm2022/koobiq-components-toggle.mjs.map +1 -1
  132. package/fesm2022/koobiq-components-tooltip.mjs +46 -6
  133. package/fesm2022/koobiq-components-tooltip.mjs.map +1 -1
  134. package/fesm2022/koobiq-components-tree-select.mjs +56 -14
  135. package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
  136. package/fesm2022/koobiq-components-tree.mjs +41 -37
  137. package/fesm2022/koobiq-components-tree.mjs.map +1 -1
  138. package/fesm2022/koobiq-components-username.mjs +2 -2
  139. package/fesm2022/koobiq-components-username.mjs.map +1 -1
  140. package/file-upload/dropzone.d.ts +0 -1
  141. package/file-upload/file-upload.scss +11 -0
  142. package/file-upload/multiple-file-upload.component.scss +29 -3
  143. package/file-upload/primitives/file-picker.d.ts +1 -1
  144. package/file-upload/single-file-upload.component.scss +10 -2
  145. package/filter-bar/filter-bar.d.ts +1 -1
  146. package/filter-bar/pipes/base-pipe.d.ts +31 -0
  147. package/filter-bar/pipes/pipe-date.d.ts +1 -1
  148. package/filter-bar/pipes/pipe-datetime.d.ts +1 -1
  149. package/form-field/fieldset.scss +10 -0
  150. package/form-field/form-field-control.d.ts +10 -0
  151. package/form-field/form-field.d.ts +17 -0
  152. package/inline-edit/inline-edit.d.ts +5 -0
  153. package/inline-edit/inline-edit.scss +7 -7
  154. package/link/_link-theme.scss +50 -15
  155. package/list/_list-theme.scss +12 -0
  156. package/list/list-selection.component.d.ts +1 -0
  157. package/list/list.scss +2 -9
  158. package/modal/modal-tokens.scss +1 -1
  159. package/modal/modal.component.d.ts +9 -1
  160. package/modal/modal.directive.d.ts +11 -0
  161. package/modal/modal.type.d.ts +7 -0
  162. package/navbar/_navbar-item_horizontal.scss +5 -0
  163. package/navbar/_navbar-item_vertical.scss +7 -5
  164. package/navbar/navbar-brand.component.d.ts +1 -0
  165. package/navbar/navbar-brand.scss +12 -5
  166. package/navbar/navbar-item.component.d.ts +33 -1
  167. package/navbar/navbar.component.d.ts +1 -0
  168. package/navbar/vertical-navbar.scss +6 -0
  169. package/notification-center/notification-center.d.ts +13 -1
  170. package/notification-center/notification-center.scss +12 -0
  171. package/notification-center/notification-item.scss +10 -1
  172. package/overflow-items/overflow-items.d.ts +1 -0
  173. package/package.json +8 -8
  174. package/prebuilt-themes/dark-theme.css +1 -1
  175. package/prebuilt-themes/light-theme.css +1 -1
  176. package/prebuilt-themes/theme.css +1 -1
  177. package/radio/radio.component.d.ts +1 -5
  178. package/radio/radio.scss +18 -4
  179. package/resizer/resizer.d.ts +12 -0
  180. package/schematics/ng-add/index.js +2 -2
  181. package/select/select-option.directive.d.ts +6 -0
  182. package/select/select.component.d.ts +51 -4
  183. package/sidebar/sidebar.component.d.ts +3 -0
  184. package/sidepanel/sidepanel-directives.d.ts +2 -0
  185. package/sidepanel/sidepanel.service.d.ts +8 -0
  186. package/splitter/splitter.component.d.ts +1 -0
  187. package/tabs/tab-body.component.d.ts +2 -0
  188. package/tabs/tab-header.component.d.ts +1 -0
  189. package/tabs/tab-header.scss +1 -0
  190. package/tabs/tab-nav-bar.d.ts +1 -0
  191. package/tabs/tabs-tokens.scss +1 -1
  192. package/textarea/textarea.component.d.ts +0 -1
  193. package/time-range/time-range-title-as-form-field.d.ts +11 -0
  194. package/timepicker/timepicker.directive.d.ts +3 -0
  195. package/timezone/timezone-option.directive.d.ts +6 -0
  196. package/title/title.directive.d.ts +26 -0
  197. package/toast/toast-container.component.d.ts +25 -0
  198. package/tooltip/tooltip.component.d.ts +25 -1
  199. package/tree/_tree-theme.scss +5 -11
  200. package/tree/toggle.scss +4 -0
  201. package/tree/tree-option.component.d.ts +3 -0
  202. package/tree/tree-option.scss +2 -12
  203. package/tree/tree-selection.component.d.ts +1 -0
  204. package/tree-select/tree-select.component.d.ts +24 -2
@@ -1,7 +1,33 @@
1
+ @use 'sass:string';
2
+
1
3
  @use '../core/styles/common/tokens' as *;
2
4
 
3
5
  @use './link-tokens';
4
6
 
7
+ // Unquoted, so that the joiner reaches the CSS as an escape rather than as an invisible character
8
+ $_kbq-link-word-joiner: string.unquote('"\\2060"');
9
+
10
+ // The width of a 16px icon less half a pixel: Chromium lays out a line that ends in negative letter-spacing a
11
+ // fraction wider than the max-content size it reports, so the full width would push the last word to the next
12
+ // line in a shrink-to-fit container.
13
+ $_kbq-link-trailing-icon-reserve: 15.5px;
14
+
15
+ // The gap after the text. Before an icon it is part of the reserve instead of a margin: Firefox does not always
16
+ // keep a margin together with the last word, and the icon could wrap alone again.
17
+ @mixin _kbq-link-text-end-gap($gap) {
18
+ &:not(:last-child) {
19
+ margin-right: $gap;
20
+ }
21
+
22
+ &:has(+ .kbq-icon) {
23
+ margin-right: 0;
24
+
25
+ &::after {
26
+ padding-inline-end: calc($gap + $_kbq-link-trailing-icon-reserve);
27
+ }
28
+ }
29
+ }
30
+
5
31
  @mixin kbq-link-geometry() {
6
32
  display: inline;
7
33
 
@@ -38,6 +64,21 @@
38
64
  line-height: 0;
39
65
  }
40
66
  }
67
+
68
+ // A line may break right before an icon, as before any inline-block, and neither a no-break character
69
+ // nor white-space stops that in every engine. So the text reserves room for the icon after its last
70
+ // word, glued to it by a word joiner kept out of the accessible name, and the icon moves back into that
71
+ // room: the last word and the icon fit on the line together or wrap together.
72
+ .kbq-link__text:has(+ .kbq-icon) {
73
+ &::after {
74
+ content: $_kbq-link-word-joiner;
75
+ content: $_kbq-link-word-joiner / '';
76
+ }
77
+
78
+ + .kbq-icon {
79
+ margin-inline-start: -$_kbq-link-trailing-icon-reserve;
80
+ }
81
+ }
41
82
  }
42
83
 
43
84
  &.kbq-text-with-icon .kbq-link__text {
@@ -45,9 +86,7 @@
45
86
  margin-left: var(--kbq-link-size-normal-content-padding);
46
87
  }
47
88
 
48
- &:not(:last-child) {
49
- margin-right: var(--kbq-link-size-normal-content-padding);
50
- }
89
+ @include _kbq-link-text-end-gap(var(--kbq-link-size-normal-content-padding));
51
90
  }
52
91
 
53
92
  &.kbq-link_compact {
@@ -65,9 +104,7 @@
65
104
  margin-left: var(--kbq-link-size-compact-content-padding);
66
105
  }
67
106
 
68
- &:not(:last-child) {
69
- margin-right: var(--kbq-link-size-compact-content-padding);
70
- }
107
+ @include _kbq-link-text-end-gap(var(--kbq-link-size-compact-content-padding));
71
108
  }
72
109
  }
73
110
  }
@@ -78,20 +115,18 @@
78
115
  margin-left: var(--kbq-link-size-big-content-padding);
79
116
  }
80
117
 
81
- &:not(:last-child) {
82
- margin-right: var(--kbq-link-size-big-content-padding);
83
- }
118
+ @include _kbq-link-text-end-gap(var(--kbq-link-size-big-content-padding));
84
119
  }
85
120
  }
86
121
 
87
122
  &.kbq-text-with-icon.kbq-link_external {
88
- .kbq-link__text:not(:last-child) {
89
- margin-right: 1px;
123
+ .kbq-link__text {
124
+ @include _kbq-link-text-end-gap(1px);
90
125
  }
91
126
 
92
127
  &.kbq-link_compact {
93
- .kbq-link__text:not(:last-child) {
94
- margin-right: 0;
128
+ .kbq-link__text {
129
+ @include _kbq-link-text-end-gap(0px);
95
130
  }
96
131
 
97
132
  .kbq-icon {
@@ -100,8 +135,8 @@
100
135
  }
101
136
 
102
137
  &.kbq-link_big {
103
- .kbq-link__text:not(:last-child) {
104
- margin-right: 2px;
138
+ .kbq-link__text {
139
+ @include _kbq-link-text-end-gap(2px);
105
140
  }
106
141
  }
107
142
  }
@@ -54,6 +54,12 @@
54
54
  &.kbq-disabled {
55
55
  @include _kbq-list-item(states-disabled);
56
56
  }
57
+
58
+ &.kbq-selected.kbq-disabled {
59
+ --kbq-option-background: var(--kbq-list-states-selected-container-background);
60
+
61
+ background: var(--kbq-list-states-selected-container-background);
62
+ }
57
63
  }
58
64
 
59
65
  .kbq-list-option.kbq-list-option_multiple {
@@ -70,6 +76,12 @@
70
76
  @include _kbq-list-item(multiple-states-selected-active);
71
77
  }
72
78
  }
79
+
80
+ &.kbq-selected.kbq-disabled {
81
+ --kbq-option-background: var(--kbq-list-multiple-states-selected-container-background);
82
+
83
+ background: var(--kbq-list-multiple-states-selected-container-background);
84
+ }
73
85
  }
74
86
 
75
87
  .kbq-list-selection.cdk-keyboard-focused {
@@ -75,6 +75,7 @@ export declare class KbqListSelection implements AfterContentInit, AfterViewInit
75
75
  get optionBlurChanges(): Observable<KbqOptionEvent>;
76
76
  _value: string[] | null;
77
77
  private readonly destroyRef;
78
+ private readonly platform;
78
79
  private optionFocusSubscription;
79
80
  private optionBlurSubscription;
80
81
  constructor(elementRef: ElementRef<HTMLElement>, changeDetectorRef: ChangeDetectorRef, multiple: MultipleMode, clipboard: Clipboard);
package/list/list.scss CHANGED
@@ -1,3 +1,4 @@
1
+ @use '../core/option/action-container-mixins' as action-container;
1
2
  @use '../core/styles/common/list';
2
3
  @use '../core/styles/common/vendor-prefixes';
3
4
  @use './list-theme' as theme;
@@ -29,18 +30,10 @@
29
30
  @include vendor-prefixes.user-select(none);
30
31
  @include list.kbq-list-item-base();
31
32
  @include _kbq-list-item-border-radius();
33
+ @include action-container.kbq-option-action-visibility('.kbq-list-selection.cdk-keyboard-focused');
32
34
 
33
35
  &:not(.kbq-disabled) {
34
36
  cursor: pointer;
35
-
36
- &.kbq-hovered,
37
- &:hover,
38
- &.kbq-focused,
39
- &.kbq-action-button-focused {
40
- & .kbq-action-container {
41
- display: flex;
42
- }
43
- }
44
37
  }
45
38
  }
46
39
 
@@ -2,7 +2,7 @@
2
2
  --kbq-modal-size-small-width: 400px;
3
3
  --kbq-modal-size-medium-width: 640px;
4
4
  --kbq-modal-size-large-width: 960px;
5
- --kbq-modal-size-border-radius: var(--kbq-size-s);
5
+ --kbq-modal-size-border-radius: var(--kbq-size-m);
6
6
  --kbq-modal-size-header-padding-vertical: var(--kbq-size-l);
7
7
  --kbq-modal-size-header-padding-left: var(--kbq-size-xxl);
8
8
  --kbq-modal-size-header-padding-right: var(--kbq-size-6xl);
@@ -5,7 +5,7 @@ import { KbqComponentColors } from '@koobiq/components/core';
5
5
  import { Observable } from 'rxjs';
6
6
  import { KbqModalControlService } from './modal-control.service';
7
7
  import { KbqModalRef } from './modal-ref.class';
8
- import { IModalButtonOptions, ModalOptions, ModalSize, ModalType, OnClickCallback } from './modal.type';
8
+ import { IModalButtonOptions, KbqOverflowShadowState, ModalOptions, ModalSize, ModalType, OnClickCallback } from './modal.type';
9
9
  import * as i0 from "@angular/core";
10
10
  type AnimationState = 'enter' | 'leave' | null;
11
11
  export declare class KbqModalComponent<T = any, R = any> extends KbqModalRef<T, R> implements OnInit, OnChanges, AfterViewInit, OnDestroy, ModalOptions {
@@ -18,6 +18,7 @@ export declare class KbqModalComponent<T = any, R = any> extends KbqModalRef<T,
18
18
  private changeDetector;
19
19
  private focusMonitor;
20
20
  protected readonly document: Document;
21
+ private readonly destroyRef;
21
22
  componentColors: typeof KbqComponentColors;
22
23
  kbqModalType: ModalType;
23
24
  kbqComponent: Type<T>;
@@ -68,6 +69,13 @@ export declare class KbqModalComponent<T = any, R = any> extends KbqModalRef<T,
68
69
  modalBody: ElementRef;
69
70
  isTopOverflow: boolean;
70
71
  isBottomOverflow: boolean;
72
+ /**
73
+ * Scroll-shadow state published by `KbqModalBody` when the modal content is composed
74
+ * manually (`kbq-modal-title`/`kbq-modal-body`/`kbq-modal-footer`), so the header/footer
75
+ * can render matching shadows without a direct template reference between them.
76
+ * @docs-private
77
+ */
78
+ readonly bodyOverflow: import("@angular/core").WritableSignal<KbqOverflowShadowState>;
71
79
  maskAnimationClassMap: object | null;
72
80
  modalAnimationClassMap: object | null;
73
81
  transformOrigin: string;
@@ -6,11 +6,22 @@ export declare class KbqModalTitle {
6
6
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqModalTitle, never>;
7
7
  static ɵcmp: i0.ɵɵComponentDeclaration<KbqModalTitle, "[kbq-modal-title], kbq-modal-title, [kbqModalTitle]", never, {}, {}, never, ["*"], true, never>;
8
8
  }
9
+ /**
10
+ * Scrollable body of a manually composed modal (`kbqComponent`). Publishes its scroll-shadow
11
+ * state onto the modal instance so a sibling `KbqModalTitle`/`KbqModalFooter` can render the
12
+ * matching shadow, since they have no direct template reference to this element.
13
+ */
9
14
  export declare class KbqModalBody {
15
+ private readonly modal;
16
+ private readonly elementRef;
17
+ constructor();
18
+ /** @docs-private */
19
+ protected checkOverflow(): void;
10
20
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqModalBody, never>;
11
21
  static ɵdir: i0.ɵɵDirectiveDeclaration<KbqModalBody, "[kbq-modal-body], kbq-modal-body, [kbqModalBody]", never, {}, {}, never, never, true, never>;
12
22
  }
13
23
  export declare class KbqModalFooter {
24
+ protected modal: KbqModalComponent<any, any>;
14
25
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqModalFooter, never>;
15
26
  static ɵdir: i0.ɵɵDirectiveDeclaration<KbqModalFooter, "[kbq-modal-footer], kbq-modal-footer, [kbqModalFooter]", never, {}, {}, never, never, true, never>;
16
27
  }
@@ -3,6 +3,13 @@ import { EventEmitter, Injector, TemplateRef, Type } from '@angular/core';
3
3
  export type OnClickCallback<T> = (instance: T) => (false | void | {}) | Promise<false | void | {}>;
4
4
  export type ModalType = 'default' | 'confirm' | 'custom';
5
5
  export type ConfirmType = 'confirm' | 'success' | 'warn';
6
+ /** Shadow visibility state — which of the two overflow shadows should be rendered. */
7
+ export interface KbqOverflowShadowState {
8
+ /** Whether the top (header) shadow should be visible — content is scrolled past the top. */
9
+ top: boolean;
10
+ /** Whether the bottom (footer) shadow should be visible — more content remains below the fold. */
11
+ bottom: boolean;
12
+ }
6
13
  export declare enum ModalSize {
7
14
  Small = "small",
8
15
  Medium = "medium",
@@ -19,6 +19,11 @@
19
19
 
20
20
  justify-content: center;
21
21
 
22
+ // Hit area over the margin this item is spaced with, so the highlight does not drop out between
23
+ // items (DS-2558) — the transparent pseudo-element is hit-tested as part of the item, so hover and
24
+ // click both reach it. `:after` below paints the highlight, at the item's own box. The same
25
+ // technique is written twice more: `select.item-active-area()` for a plain vertical list, and
26
+ // `--kbq-button-toggle-size-item-hit-area-*` for a group whose `gap` two neighbours have to tile.
22
27
  &:before {
23
28
  top: calc(-1 * #{var(--kbq-size-s)});
24
29
  left: calc(-1 * #{var(--kbq-size-s)});
@@ -55,17 +55,19 @@
55
55
  &.kbq-navbar-bento .kbq-navbar-item__title {
56
56
  margin-left: -8px;
57
57
  opacity: 0;
58
+
59
+ transition:
60
+ opacity 150ms ease-out,
61
+ margin-left 150ms ease-out;
58
62
  }
59
63
 
60
64
  &.kbq-navbar-bento:hover,
61
- &.kbq-navbar-bento.cdk-keyboard-focused {
65
+ &.kbq-navbar-bento.cdk-keyboard-focused,
66
+ &.kbq-navbar-bento.kbq-active,
67
+ &.kbq-navbar-bento.kbq-pressed {
62
68
  & .kbq-navbar-item__title {
63
69
  margin-left: 0;
64
70
  opacity: 1;
65
-
66
- transition:
67
- opacity 150ms ease-out,
68
- margin-left 150ms ease-out;
69
71
  }
70
72
  }
71
73
  }
@@ -35,6 +35,7 @@ export declare class KbqNavbarBrand extends KbqTooltipTrigger implements AfterCo
35
35
  private _collapsed;
36
36
  constructor();
37
37
  ngAfterContentInit(): void;
38
+ private preventDisabledActivation;
38
39
  private updateTooltip;
39
40
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqNavbarBrand, never>;
40
41
  static ɵcmp: i0.ɵɵComponentDeclaration<KbqNavbarBrand, "kbq-navbar-brand, [kbq-navbar-brand]", ["kbqNavbarBrand"], { "longTitle": { "alias": "longTitle"; "required": false; }; "collapsedText": { "alias": "collapsedText"; "required": false; }; }, {}, ["title"], ["*"], true, never>;
@@ -22,7 +22,7 @@
22
22
  border-radius: var(--kbq-navbar-item-size-content-border-radius);
23
23
  }
24
24
 
25
- & .kbq-navbar-title {
25
+ &:not(.kbq-disabled) .kbq-navbar-title {
26
26
  cursor: pointer;
27
27
  }
28
28
  }
@@ -99,14 +99,21 @@ a.kbq-navbar-brand {
99
99
  .kbq-navbar-brand {
100
100
  @include navbar-theme.kbq-navbar-item(default);
101
101
 
102
+ // Explicit, or the text of an `<a>` without `href` falls back to the I-beam.
103
+ &.kbq-disabled {
104
+ cursor: default;
105
+ }
106
+
102
107
  &.kbq-navbar-brand_link {
103
- cursor: pointer;
108
+ &:not(.kbq-disabled) {
109
+ cursor: pointer;
110
+ }
104
111
 
105
112
  &:hover:not(.kbq-disabled) {
106
113
  @include navbar-theme.kbq-navbar-item(states-hover);
107
114
  }
108
115
 
109
- &.cdk-focused.cdk-keyboard-focused {
116
+ &.cdk-focused.cdk-keyboard-focused:not(.kbq-disabled) {
110
117
  outline: none;
111
118
 
112
119
  &:after {
@@ -120,13 +127,13 @@ a.kbq-navbar-brand {
120
127
  @include navbar-theme.kbq-navbar-item(states-selected);
121
128
  }
122
129
 
123
- &.kbq-vertical:hover {
130
+ &.kbq-vertical:hover:not(.kbq-disabled) {
124
131
  .kbq-navbar-logo {
125
132
  transform: scale(1.06);
126
133
  }
127
134
  }
128
135
 
129
- &.kbq-horizontal:hover {
136
+ &.kbq-horizontal:hover:not(.kbq-disabled) {
130
137
  .kbq-navbar-logo {
131
138
  z-index: 1;
132
139
  }
@@ -29,6 +29,12 @@ export declare class KbqNavbarTitle implements AfterViewInit {
29
29
  isTextOverflown: boolean;
30
30
  get text(): string;
31
31
  get isOverflown(): boolean;
32
+ /**
33
+ * Outer width of the title: its border box plus horizontal margins.
34
+ *
35
+ * Measured with `getBoundingClientRect()` rather than `getComputedStyle().width`, which resolves
36
+ * to the used content-box width whatever `box-sizing` says and would drop the title's padding.
37
+ */
32
38
  getOuterElementWidth(): number;
33
39
  checkTextOverflown(): void;
34
40
  ngAfterViewInit(): void;
@@ -55,10 +61,27 @@ export declare class KbqNavbarFocusableItem implements AfterContentInit, AfterVi
55
61
  get hasFocus(): boolean;
56
62
  set hasFocus(value: boolean);
57
63
  private _hasFocus;
58
- /** Whether the item is disabled. */
64
+ /**
65
+ * Whether the item is disabled.
66
+ *
67
+ * Also reads `true` for a decorative element, which the key manager has to skip just the same.
68
+ */
59
69
  get disabled(): boolean;
60
70
  set disabled(value: boolean);
61
71
  private _disabled;
72
+ /**
73
+ * Keeps an element with nothing to interact with out of the roving focus order, without announcing or
74
+ * styling it as disabled.
75
+ *
76
+ * @internal
77
+ */
78
+ decorative: boolean;
79
+ /**
80
+ * Whether the item was disabled through `disabled`, as opposed to being decorative.
81
+ *
82
+ * @internal
83
+ */
84
+ get explicitlyDisabled(): boolean;
62
85
  get tabIndex(): number;
63
86
  constructor(elementRef: ElementRef<HTMLElement>, changeDetector: ChangeDetectorRef, focusMonitor: FocusMonitor, ngZone: NgZone);
64
87
  ngAfterViewInit(): void;
@@ -89,6 +112,15 @@ export declare class KbqNavbarRectangleElement {
89
112
  set collapsed(value: boolean);
90
113
  private _collapsed;
91
114
  button: KbqButtonCssStyler;
115
+ /**
116
+ * Outer width of the item: its border box plus horizontal margins.
117
+ *
118
+ * Measured with `getBoundingClientRect()` rather than `getComputedStyle().width`, which resolves
119
+ * to the used content-box width whatever `box-sizing` says. `.kbq-navbar-item` is `border-box`
120
+ * with horizontal padding, so the computed value dropped that padding from every item, while
121
+ * `KbqNavbar.width` — the figure this sum is compared against — has always been a border box.
122
+ * The navbar therefore under-counted its own content and collapsed later than it should.
123
+ */
92
124
  getOuterElementWidth(): number;
93
125
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqNavbarRectangleElement, never>;
94
126
  static ɵdir: i0.ɵɵDirectiveDeclaration<KbqNavbarRectangleElement, "kbq-navbar-item, [kbq-navbar-item], kbq-navbar-divider, kbq-navbar-brand, [kbq-navbar-brand]", never, {}, {}, ["button"], never, true, never>;
@@ -43,6 +43,7 @@ export declare class KbqNavbar extends KbqFocusableComponent implements AfterVie
43
43
  protected readonly elementRef: ElementRef<HTMLElement>;
44
44
  protected readonly changeDetectorRef: ChangeDetectorRef;
45
45
  protected readonly focusMonitor: FocusMonitor;
46
+ private readonly platform;
46
47
  readonly rectangleElements: import("@angular/core").Signal<readonly any[]>;
47
48
  navbarItems: QueryList<KbqNavbarItem>;
48
49
  readonly resizeStream: Subject<Event>;
@@ -26,6 +26,12 @@
26
26
  }
27
27
 
28
28
  & .kbq-vertical-navbar__container {
29
+ // The 1px `border-right` the theme adds belongs inside these widths, not beside them: the
30
+ // collapsed rail is `--kbq-size-6xl`, the same token this component's own `min-width` above
31
+ // is written in, so rendering it a pixel wider overshot that contract. Under `content-box`
32
+ // it measured 57px collapsed and 241px expanded.
33
+ box-sizing: border-box;
34
+
29
35
  position: relative;
30
36
 
31
37
  display: flex;
@@ -81,10 +81,22 @@ export declare class KbqNotificationCenterComponent extends KbqPopUp implements
81
81
  * stall. Suppressed while a load is in flight, errored, or when there is nothing more to load.
82
82
  */
83
83
  private subscribeToScrolledToBottom;
84
- /** Whether the list is scrolled to within `scrolledToBottomOffset` pixels of the bottom. */
84
+ /** Whether the list is scrolled to within `scrolledToBottomOffset` pixels of the bottom.
85
+ * Sub-pixel measurement error is absorbed by `SCROLLED_TO_BOTTOM_TOLERANCE`. */
85
86
  private isScrolledToBottom;
86
87
  /** Emits `onNextPage` unless a load is already in flight, errored, or there is nothing more to load. */
87
88
  private requestNextPage;
89
+ /**
90
+ * Reveals the bottom "load more" spinner / error row when it first appears. Both rows are appended
91
+ * below the last item and can land outside the viewport (the next page is requested while the user
92
+ * is up to `scrolledToBottomOffset` px above the true bottom). Only a genuine false->true transition
93
+ * reveals the row: the BehaviorSubject's replayed current value is ignored (`pairwise` needs two
94
+ * emissions), so the panel always opens scrolled to the top — reopening it while a load-more error
95
+ * is still set never jumps to the bottom.
96
+ */
97
+ private subscribeToRevealLoadMoreRow;
98
+ /** Scrolls the list container to its bottom so a freshly-appended bottom row becomes visible. */
99
+ private scrollToBottom;
88
100
  private focusScrollContainer;
89
101
  /** @docs-private */
90
102
  updateClassMap(placement: string, customClass: string, size: KbqPopUpSizeValues): void;
@@ -94,6 +94,18 @@
94
94
 
95
95
  padding-bottom: var(--kbq-size-xl);
96
96
 
97
+ // Smoothly reveal the just-appended "load more" spinner / error row. The row is scrolled into
98
+ // view via KbqScrollbar.scrollTo(), which calls a behavior-less scroll on the overlayscrollbars
99
+ // viewport — so `scroll-behavior` on the viewport controls the animation. Disabled for users who
100
+ // prefer reduced motion.
101
+ & [data-overlayscrollbars-viewport] {
102
+ scroll-behavior: smooth;
103
+
104
+ @media (prefers-reduced-motion: reduce) {
105
+ scroll-behavior: auto;
106
+ }
107
+ }
108
+
97
109
  & .kbq-loader-overlay_parent {
98
110
  border-radius: inherit;
99
111
  }
@@ -27,6 +27,12 @@
27
27
  .kbq-notification-item__icon-container {
28
28
  flex-shrink: 0;
29
29
 
30
+ // The size below is the icon itself and the padding only positions it, so the two must not share
31
+ // a box. Under a global `border-box` reset in a consuming application the padding would be
32
+ // subtracted from the icon instead of added around it, and `max-width`/`max-height` would clamp
33
+ // what is left — a 16px icon squeezed into 4px wide and 2px tall.
34
+ box-sizing: content-box;
35
+
30
36
  width: var(--kbq-size-l);
31
37
  max-width: var(--kbq-size-l);
32
38
 
@@ -86,8 +92,11 @@
86
92
  margin-right: var(--kbq-size-3xs);
87
93
  }
88
94
 
95
+ // The dot keeps its width once read, or the title gains that width and rewraps under the pointer.
96
+ // Placed before the time, so the time keeps the position it had before the dot was hidden.
89
97
  &.kbq-notification-item-time_read .kbq-notification-item-time__state {
90
- display: none;
98
+ visibility: hidden;
99
+ order: -1;
91
100
  }
92
101
  }
93
102
 
@@ -74,6 +74,7 @@ export declare class KbqOverflowItems {
74
74
  private readonly renderer;
75
75
  private readonly document;
76
76
  private readonly window;
77
+ private readonly platform;
77
78
  /**
78
79
  * `KbqOverflowItem` directive references.
79
80
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koobiq/components",
3
- "version": "19.8.5",
3
+ "version": "19.8.7",
4
4
  "description": "koobiq",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,9 +25,9 @@
25
25
  "@angular/cdk": ">=19.0.0",
26
26
  "@angular/core": ">=19.0.0",
27
27
  "@angular/forms": ">=19.0.0",
28
- "@koobiq/cdk": "19.8.5",
29
- "@koobiq/angular-moment-adapter": "19.8.5",
30
- "@koobiq/angular-luxon-adapter": "19.8.5",
28
+ "@koobiq/cdk": "19.8.7",
29
+ "@koobiq/angular-moment-adapter": "19.8.7",
30
+ "@koobiq/angular-luxon-adapter": "19.8.7",
31
31
  "@koobiq/date-formatter": "^3.2.3",
32
32
  "@koobiq/icons": "^11.1.3",
33
33
  "@koobiq/design-tokens": "^3.14.0"
@@ -81,14 +81,14 @@
81
81
  "types": "./autocomplete/index.d.ts",
82
82
  "default": "./fesm2022/koobiq-components-autocomplete.mjs"
83
83
  },
84
- "./badge": {
85
- "types": "./badge/index.d.ts",
86
- "default": "./fesm2022/koobiq-components-badge.mjs"
87
- },
88
84
  "./breadcrumbs": {
89
85
  "types": "./breadcrumbs/index.d.ts",
90
86
  "default": "./fesm2022/koobiq-components-breadcrumbs.mjs"
91
87
  },
88
+ "./badge": {
89
+ "types": "./badge/index.d.ts",
90
+ "default": "./fesm2022/koobiq-components-badge.mjs"
91
+ },
92
92
  "./button": {
93
93
  "types": "./button/index.d.ts",
94
94
  "default": "./fesm2022/koobiq-components-button.mjs"