@koobiq/components 19.8.1 → 19.8.2

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 (57) hide show
  1. package/breadcrumbs/breadcrumbs.d.ts +22 -29
  2. package/breadcrumbs/breadcrumbs.scss +7 -0
  3. package/button/_button-base.scss +20 -0
  4. package/button/_button-theme.scss +3 -11
  5. package/button/button-slots.d.ts +11 -0
  6. package/button/button.component.d.ts +28 -13
  7. package/button/button.module.d.ts +3 -2
  8. package/button/button.scss +0 -11
  9. package/button/public-api.d.ts +1 -0
  10. package/core/option/_option-theme.scss +5 -14
  11. package/core/pop-up/constants.d.ts +2 -2
  12. package/dropdown/_dropdown-theme.scss +4 -8
  13. package/dropdown/dropdown-trigger.directive.d.ts +11 -0
  14. package/dropdown/dropdown.component.d.ts +8 -0
  15. package/dropdown/dropdown.scss +4 -0
  16. package/fesm2022/koobiq-components-breadcrumbs.mjs +101 -88
  17. package/fesm2022/koobiq-components-breadcrumbs.mjs.map +1 -1
  18. package/fesm2022/koobiq-components-button.mjs +176 -68
  19. package/fesm2022/koobiq-components-button.mjs.map +1 -1
  20. package/fesm2022/koobiq-components-core.mjs +4 -5
  21. package/fesm2022/koobiq-components-core.mjs.map +1 -1
  22. package/fesm2022/koobiq-components-dropdown.mjs +46 -10
  23. package/fesm2022/koobiq-components-dropdown.mjs.map +1 -1
  24. package/fesm2022/koobiq-components-filter-bar.mjs +8 -8
  25. package/fesm2022/koobiq-components-filter-bar.mjs.map +1 -1
  26. package/fesm2022/koobiq-components-icon.mjs +2 -2
  27. package/fesm2022/koobiq-components-icon.mjs.map +1 -1
  28. package/fesm2022/koobiq-components-navbar.mjs +7 -3
  29. package/fesm2022/koobiq-components-navbar.mjs.map +1 -1
  30. package/fesm2022/koobiq-components-popover.mjs +1 -1
  31. package/fesm2022/koobiq-components-popover.mjs.map +1 -1
  32. package/fesm2022/koobiq-components-select.mjs +3 -1
  33. package/fesm2022/koobiq-components-select.mjs.map +1 -1
  34. package/fesm2022/koobiq-components-tabs.mjs +31 -10
  35. package/fesm2022/koobiq-components-tabs.mjs.map +1 -1
  36. package/fesm2022/koobiq-components-timezone.mjs +2 -2
  37. package/fesm2022/koobiq-components-timezone.mjs.map +1 -1
  38. package/fesm2022/koobiq-components-top-bar.mjs +7 -2
  39. package/fesm2022/koobiq-components-top-bar.mjs.map +1 -1
  40. package/fesm2022/koobiq-components-tree-select.mjs +2 -2
  41. package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
  42. package/fesm2022/koobiq-components-tree.mjs +6 -6
  43. package/fesm2022/koobiq-components-tree.mjs.map +1 -1
  44. package/filter-bar/_filter-bar-theme.scss +0 -4
  45. package/icon/icon-item-tokens.scss +1 -1
  46. package/package.json +8 -8
  47. package/prebuilt-themes/dark-theme.css +1 -1
  48. package/prebuilt-themes/light-theme.css +1 -1
  49. package/prebuilt-themes/theme.css +1 -1
  50. package/schematics/ng-add/index.js +2 -2
  51. package/tabs/_tabs-common.scss +27 -0
  52. package/tabs/_tabs-theme.scss +2 -2
  53. package/tabs/tab-header.component.d.ts +2 -0
  54. package/tabs/tab-label.directive.d.ts +3 -1
  55. package/tabs/tab.component.d.ts +2 -0
  56. package/tree/_tree-theme.scss +4 -0
  57. package/tree-select/_tree-select-theme.scss +39 -0
@@ -1,4 +1,4 @@
1
- import { AfterContentInit, InjectionToken, OnInit, Provider, QueryList, TemplateRef } from '@angular/core';
1
+ import { InjectionToken, OnInit, Provider, TemplateRef } from '@angular/core';
2
2
  import { RouterLink } from '@angular/router';
3
3
  import { KbqButtonStyles } from '@koobiq/components/button';
4
4
  import { KbqComponentColors, KbqDefaultSizes, PopUpPlacements } from '@koobiq/components/core';
@@ -43,63 +43,63 @@ export declare class KbqBreadcrumbItem {
43
43
  * The text displayed for the breadcrumb item.
44
44
  * This text will be shown if breadcrumb item is hidden in dropdown.
45
45
  */
46
- text: string;
46
+ readonly text: import("@angular/core").InputSignal<string>;
47
47
  /**
48
48
  * Indicates whether the breadcrumb item is disabled.
49
49
  */
50
- disabled: boolean;
50
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
51
51
  /**
52
52
  * Indicates whether the breadcrumb item is the current/active item.
53
53
  * Defaults to `false`.
54
54
  */
55
- current: boolean;
55
+ readonly current: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
56
56
  /**
57
57
  * A reference to a custom template provided for the breadcrumb item content.
58
58
  * The template can be used to override the default appearance of the breadcrumb.
59
59
  */
60
- customTemplateRef: TemplateRef<any>;
60
+ readonly customTemplateRef: import("@angular/core").Signal<TemplateRef<any> | undefined>;
61
61
  /**
62
62
  * An optional `RouterLink` instance for navigating to a specific route.
63
63
  * Injected from the host element, if available and projecting to the hidden breadcrumb item in dropdown.
64
64
  */
65
65
  readonly routerLink: RouterLink | null;
66
66
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqBreadcrumbItem, never>;
67
- static ɵcmp: i0.ɵɵComponentDeclaration<KbqBreadcrumbItem, "kbq-breadcrumb-item", never, { "text": { "alias": "text"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "current": { "alias": "current"; "required": false; }; }, {}, ["customTemplateRef"], ["*"], true, never>;
68
- static ngAcceptInputType_disabled: unknown;
69
- static ngAcceptInputType_current: unknown;
67
+ static ɵcmp: i0.ɵɵComponentDeclaration<KbqBreadcrumbItem, "kbq-breadcrumb-item", never, { "text": { "alias": "text"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "current": { "alias": "current"; "required": false; "isSignal": true; }; }, {}, ["customTemplateRef"], ["*"], true, never>;
70
68
  }
71
- export declare class KbqBreadcrumbs implements AfterContentInit {
69
+ export declare class KbqBreadcrumbs {
72
70
  protected readonly configuration: KbqBreadcrumbsConfiguration;
73
71
  /**
74
72
  * Determines if a negative margin should be applied to the first breadcrumb item.
75
73
  *
76
74
  * @see KbqBreadcrumbsConfiguration
77
75
  */
78
- firstItemNegativeMargin: boolean;
76
+ readonly firstItemNegativeMargin: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
79
77
  /**
80
78
  * Size of the breadcrumbs. Affects font size.
81
79
  * Default value is taken from the global configuration.
82
80
  */
83
- size: KbqDefaultSizes;
81
+ readonly size: import("@angular/core").InputSignal<KbqDefaultSizes>;
84
82
  /**
85
83
  * Maximum number of visible breadcrumb items.
86
84
  * Remaining items are collapsed into a dropdown if the total exceeds this value.
87
85
  * Default value is taken from the global configuration.
88
86
  */
89
- max: number | null;
87
+ readonly max: import("@angular/core").InputSignal<number | null>;
90
88
  /**
91
89
  * Indicates whether the breadcrumbs are disabled.
92
90
  * When disabled, user interactions are blocked.
93
91
  */
94
- disabled: boolean;
92
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
95
93
  /**
96
94
  * Wrapping behavior of the breadcrumb items.
97
95
  */
98
- wrapMode: KbqBreadcrumbsWrapMode;
96
+ readonly wrapMode: import("@angular/core").InputSignal<KbqBreadcrumbsWrapMode>;
99
97
  protected readonly separator?: TemplateRef<any>;
100
- protected readonly items: QueryList<KbqBreadcrumbItem>;
98
+ protected readonly items: import("@angular/core").Signal<readonly KbqBreadcrumbItem[]>;
99
+ private readonly breadcrumbsResult;
101
100
  private readonly result;
102
101
  private readonly overflowItems;
102
+ private readonly overflowItemsDir;
103
103
  /**
104
104
  * Ensures at least minimum number of breadcrumb items are shown.
105
105
  */
@@ -107,21 +107,14 @@ export declare class KbqBreadcrumbs implements AfterContentInit {
107
107
  protected readonly KbqComponentColors: typeof KbqComponentColors;
108
108
  protected readonly KbqButtonStyles: typeof KbqButtonStyles;
109
109
  protected readonly PopUpPlacements: typeof PopUpPlacements;
110
- private readonly cdr;
111
- private readonly destroyRef;
112
110
  /** @docs-private */
113
- protected get itemsExcludingEdges(): KbqBreadcrumbItem[];
114
- /**
115
- * Calculates the total width of visible items based on the `max` value and overflow items.
116
- * @returns {number | null} The computed max width for overflow items or null if conditions are not met.
117
- * @docs-private
118
- */
119
- protected get maxWidth(): number | null;
111
+ protected readonly itemsExcludingEdges: import("@angular/core").Signal<KbqBreadcrumbItem[]>;
112
+ protected readonly hiddenItemIDs: import("@angular/core").Signal<Set<unknown>>;
113
+ /** @docs-private */
114
+ protected readonly maxVisibleItems: import("@angular/core").Signal<number | null>;
115
+ private readonly maxHiddenItems;
120
116
  constructor();
121
- ngAfterContentInit(): void;
122
- private getItemWidth;
117
+ private enforceMaxVisible;
123
118
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqBreadcrumbs, never>;
124
- static ɵcmp: i0.ɵɵComponentDeclaration<KbqBreadcrumbs, "kbq-breadcrumbs,[kbq-breadcrumbs]", never, { "firstItemNegativeMargin": { "alias": "firstItemNegativeMargin"; "required": false; }; "size": { "alias": "size"; "required": false; }; "max": { "alias": "max"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "wrapMode": { "alias": "wrapMode"; "required": false; }; }, {}, ["separator", "items"], ["*"], true, [{ directive: typeof i2.RdxRovingFocusGroupDirective; inputs: {}; outputs: {}; }]>;
125
- static ngAcceptInputType_firstItemNegativeMargin: unknown;
126
- static ngAcceptInputType_disabled: unknown;
119
+ static ɵcmp: i0.ɵɵComponentDeclaration<KbqBreadcrumbs, "kbq-breadcrumbs,[kbq-breadcrumbs]", never, { "firstItemNegativeMargin": { "alias": "firstItemNegativeMargin"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "wrapMode": { "alias": "wrapMode"; "required": false; "isSignal": true; }; }, {}, ["items", "separator"], ["*"], true, [{ directive: typeof i2.RdxRovingFocusGroupDirective; inputs: {}; outputs: {}; }]>;
127
120
  }
@@ -7,6 +7,13 @@
7
7
  gap: var(--kbq-breadcrumbs-gap);
8
8
  flex-grow: 1;
9
9
 
10
+ kbq-breadcrumb-item {
11
+ display: none;
12
+ position: absolute;
13
+ top: 0;
14
+ left: 0;
15
+ }
16
+
10
17
  .kbq-overflow-items {
11
18
  // add space not to cut focus outline
12
19
  padding: 1px;
@@ -1,4 +1,5 @@
1
1
  @use '../core/styles/common/button';
2
+ @use '../core/styles/common/list';
2
3
 
3
4
  @use '../core/styles/common/tokens' as *;
4
5
 
@@ -47,6 +48,17 @@
47
48
  & .kbq-button-wrapper {
48
49
  display: flex;
49
50
  align-items: center;
51
+
52
+ min-width: 0;
53
+ }
54
+
55
+ & .kbq-button-text {
56
+ @include list.kbq-truncate-line();
57
+
58
+ display: flex;
59
+ align-items: center;
60
+
61
+ min-width: 0;
50
62
  }
51
63
 
52
64
  & .kbq-icon_left {
@@ -56,4 +68,12 @@
56
68
  & .kbq-icon_right {
57
69
  margin-left: var(--kbq-button-size-content-padding);
58
70
  }
71
+
72
+ & .kbq-button-prefix {
73
+ margin-right: var(--kbq-button-size-content-padding);
74
+ }
75
+
76
+ & .kbq-button-suffix {
77
+ margin-left: var(--kbq-button-size-content-padding);
78
+ }
59
79
  }
@@ -46,10 +46,6 @@
46
46
  }
47
47
 
48
48
  @mixin kbq-button-theme() {
49
- .kbq-button-overlay {
50
- display: none;
51
- }
52
-
53
49
  .kbq-button,
54
50
  .kbq-button-icon {
55
51
  -webkit-font-smoothing: antialiased;
@@ -87,7 +83,9 @@
87
83
  &.kbq-button_filled,
88
84
  &.kbq-button_outline,
89
85
  &.kbq-button_transparent {
90
- &.cdk-keyboard-focused {
86
+ // :not(.kbq-disabled): a disabled <a kbq-button> can keep DOM focus (tabindex=-1 does
87
+ // not blur it), and FocusMonitor stays attached for the whole component lifetime.
88
+ &.cdk-keyboard-focused:not(.kbq-disabled) {
91
89
  $focused-color: var(--kbq-states-line-focus-theme);
92
90
  outline: 1px solid $focused-color;
93
91
  border-color: $focused-color;
@@ -101,10 +99,4 @@
101
99
  .kbq-button-icon {
102
100
  @include kbq-typography-level-to-styles-css-variables(typography, text-normal-medium);
103
101
  }
104
-
105
- .kbq-button-icon.kbq-button-wrapper {
106
- .kbq-icon {
107
- @include kbq-css-font-variable(typography, body, line-height, '');
108
- }
109
- }
110
102
  }
@@ -0,0 +1,11 @@
1
+ import * as i0 from "@angular/core";
2
+ /** Marks content to be projected into the prefix (leading) slot of a button. */
3
+ export declare class KbqButtonPrefix {
4
+ static ɵfac: i0.ɵɵFactoryDeclaration<KbqButtonPrefix, never>;
5
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KbqButtonPrefix, "[kbqButtonPrefix]", never, {}, {}, never, never, true, never>;
6
+ }
7
+ /** Marks content to be projected into the suffix (trailing) slot of a button. */
8
+ export declare class KbqButtonSuffix {
9
+ static ɵfac: i0.ɵɵFactoryDeclaration<KbqButtonSuffix, never>;
10
+ static ɵdir: i0.ɵɵDirectiveDeclaration<KbqButtonSuffix, "[kbqButtonSuffix]", never, {}, {}, never, never, true, never>;
11
+ }
@@ -1,7 +1,6 @@
1
1
  import { FocusMonitor } from '@angular/cdk/a11y';
2
- import { AfterContentInit, AfterViewInit, ChangeDetectorRef, ElementRef, OnDestroy, QueryList, Renderer2 } from '@angular/core';
2
+ import { AfterContentInit, AfterViewInit, ElementRef, OnDestroy, Renderer2 } from '@angular/core';
3
3
  import { KbqColorDirective, KbqTitleTextRef } from '@koobiq/components/core';
4
- import { KbqIcon } from '@koobiq/components/icon';
5
4
  import * as i0 from "@angular/core";
6
5
  export declare enum KbqButtonStyles {
7
6
  Filled = "filled",
@@ -10,31 +9,46 @@ export declare enum KbqButtonStyles {
10
9
  }
11
10
  export declare const buttonLeftIconClassName = "kbq-button-icon_left";
12
11
  export declare const buttonRightIconClassName = "kbq-button-icon_right";
12
+ /**
13
+ * Applies the `kbq-button`/`kbq-button-icon` host class and the left/right icon modifier classes.
14
+ *
15
+ * A button is treated as an icon button when its projected content consists only of `KbqIcon`s
16
+ * and there are at most 2 of them. When icons are mixed with other content, only the outermost
17
+ * icons receive the left/right classes.
18
+ *
19
+ * Must be used together with `KbqButton` (both match `[kbq-button]`): icon detection relies on
20
+ * the `.kbq-button-wrapper` element rendered by the component's template.
21
+ */
13
22
  export declare class KbqButtonCssStyler implements AfterContentInit {
14
23
  private renderer;
15
- private cdr;
16
- icons: QueryList<KbqIcon>;
24
+ readonly icons: import("@angular/core").Signal<readonly any[]>;
17
25
  nativeElement: HTMLElement;
18
- isIconButton: boolean;
19
- constructor(elementRef: ElementRef<HTMLElement>, renderer: Renderer2, cdr: ChangeDetectorRef);
26
+ /** Whether the button contains only icons (at most 2). */
27
+ get isIconButton(): boolean;
28
+ private readonly _isIconButton;
29
+ private leftIcon;
30
+ private rightIcon;
31
+ constructor(elementRef: ElementRef<HTMLElement>, renderer: Renderer2);
20
32
  ngAfterContentInit(): void;
21
33
  updateClassModifierForIcons(): void;
22
- static ɵfac: i0.ɵɵFactoryDeclaration<KbqButtonCssStyler, [null, null, { skipSelf: true; }]>;
34
+ private updateIconClass;
35
+ static ɵfac: i0.ɵɵFactoryDeclaration<KbqButtonCssStyler, never>;
23
36
  static ɵdir: i0.ɵɵDirectiveDeclaration<KbqButtonCssStyler, "[kbq-button]", never, {}, {}, ["icons"], never, true, never>;
24
37
  }
25
38
  export declare class KbqButton extends KbqColorDirective implements OnDestroy, AfterViewInit, KbqTitleTextRef {
26
39
  private focusMonitor;
27
- private styler;
40
+ protected styler: KbqButtonCssStyler;
28
41
  private readonly changeDetectorRef;
29
42
  hasFocus: boolean;
30
- textElement: ElementRef;
43
+ textElement: ElementRef<HTMLElement>;
44
+ /** The flex row that lays out the icons and text, used as the overflow width constraint. */
45
+ parentTextElement: ElementRef<HTMLElement>;
31
46
  get kbqStyle(): string;
32
47
  set kbqStyle(value: string | KbqButtonStyles);
33
48
  private _kbqStyle;
34
49
  /** Whether the button is disabled. */
35
50
  get disabled(): boolean;
36
51
  set disabled(value: boolean);
37
- private _disabled;
38
52
  /** @docs-private */
39
53
  readonly disabledSignal: import("@angular/core").WritableSignal<boolean>;
40
54
  get tabIndex(): number;
@@ -43,17 +57,18 @@ export declare class KbqButton extends KbqColorDirective implements OnDestroy, A
43
57
  constructor(focusMonitor: FocusMonitor, styler: KbqButtonCssStyler);
44
58
  ngAfterViewInit(): void;
45
59
  ngOnDestroy(): void;
46
- onFocus($event: any): void;
60
+ onFocus(): void;
47
61
  onBlur(): void;
48
62
  getHostElement(): HTMLElement;
49
63
  focus(): void;
50
64
  focusViaKeyboard(): void;
51
- haltDisabledEvents(event: Event): void;
65
+ haltDisabledEvents: (event: Event) => void;
66
+ private haltDisabledKeydownEvents;
52
67
  projectContentChanged(): void;
53
68
  private runFocusMonitor;
54
69
  private stopFocusMonitor;
55
70
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqButton, never>;
56
- static ɵcmp: i0.ɵɵComponentDeclaration<KbqButton, "[kbq-button]", never, { "kbqStyle": { "alias": "kbqStyle"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "tabIndex": { "alias": "tabIndex"; "required": false; }; }, {}, never, ["*"], true, never>;
71
+ static ɵcmp: i0.ɵɵComponentDeclaration<KbqButton, "[kbq-button]", never, { "kbqStyle": { "alias": "kbqStyle"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "tabIndex": { "alias": "tabIndex"; "required": false; }; }, {}, never, ["[kbqButtonPrefix]", "*", "[kbqButtonSuffix]"], true, never>;
57
72
  static ngAcceptInputType_disabled: unknown;
58
73
  static ngAcceptInputType_tabIndex: unknown;
59
74
  }
@@ -4,9 +4,10 @@ import * as i2 from "@angular/cdk/platform";
4
4
  import * as i3 from "@angular/cdk/observers";
5
5
  import * as i4 from "./button.dropdown-trigger.directive";
6
6
  import * as i5 from "./button.component";
7
- import * as i6 from "./button-group";
7
+ import * as i6 from "./button-slots";
8
+ import * as i7 from "./button-group";
8
9
  export declare class KbqButtonModule {
9
10
  static ɵfac: i0.ɵɵFactoryDeclaration<KbqButtonModule, never>;
10
- static ɵmod: i0.ɵɵNgModuleDeclaration<KbqButtonModule, never, [typeof i1.A11yModule, typeof i2.PlatformModule, typeof i3.ObserversModule, typeof i4.KbqButtonDropdownTrigger, typeof i5.KbqButton, typeof i5.KbqButtonCssStyler, typeof i6.KbqButtonGroup, typeof i6.KbqButtonGroupRoot], [typeof i5.KbqButton, typeof i5.KbqButtonCssStyler, typeof i4.KbqButtonDropdownTrigger, typeof i6.KbqButtonGroup, typeof i6.KbqButtonGroupRoot]>;
11
+ static ɵmod: i0.ɵɵNgModuleDeclaration<KbqButtonModule, never, [typeof i1.A11yModule, typeof i2.PlatformModule, typeof i3.ObserversModule, typeof i4.KbqButtonDropdownTrigger, typeof i5.KbqButton, typeof i5.KbqButtonCssStyler, typeof i6.KbqButtonPrefix, typeof i6.KbqButtonSuffix, typeof i7.KbqButtonGroup, typeof i7.KbqButtonGroupRoot], [typeof i5.KbqButton, typeof i5.KbqButtonCssStyler, typeof i6.KbqButtonPrefix, typeof i6.KbqButtonSuffix, typeof i4.KbqButtonDropdownTrigger, typeof i7.KbqButtonGroup, typeof i7.KbqButtonGroupRoot]>;
11
12
  static ɵinj: i0.ɵɵInjectorDeclaration<KbqButtonModule>;
12
13
  }
@@ -24,16 +24,5 @@
24
24
  padding-right: kbq-difference-series-css-variables([button-icon-size-horizontal-padding, button-size-border-width]);
25
25
  }
26
26
 
27
- .kbq-button-overlay {
28
- position: absolute;
29
-
30
- top: calc(-1 * #{var(--kbq-button-size-border-width)});
31
- left: calc(-1 * #{var(--kbq-button-size-border-width)});
32
- right: calc(-1 * #{var(--kbq-button-size-border-width)});
33
- bottom: calc(-1 * #{var(--kbq-button-size-border-width)});
34
-
35
- border-radius: inherit;
36
- }
37
-
38
27
  @include kbq-button-theme();
39
28
  @include kbq-button-typography();
@@ -1,4 +1,5 @@
1
1
  export * from './button-group';
2
+ export * from './button-slots';
2
3
  export * from './button.component';
3
4
  export * from './button.dropdown-trigger.directive';
4
5
  export * from './button.module';
@@ -20,16 +20,14 @@
20
20
  .kbq-option {
21
21
  @include kbq-option(default);
22
22
 
23
- &.kbq-hovered:not(.kbq-disabled),
24
- &:hover:not(.kbq-disabled) {
23
+ &.kbq-active:not(.kbq-disabled) {
25
24
  @include kbq-option(states-hover);
26
25
  }
27
26
 
28
27
  &.kbq-selected:not(.kbq-disabled) {
29
28
  @include kbq-option(states-selected);
30
29
 
31
- &.kbq-hovered,
32
- &:hover {
30
+ &.kbq-active {
33
31
  @include kbq-option(states-selected-hover);
34
32
  }
35
33
  }
@@ -38,12 +36,12 @@
38
36
  @include kbq-option(states-disabled);
39
37
  }
40
38
 
41
- &:is(.kbq-selected, .kbq-focused):has(+ :is(.kbq-selected, .kbq-focused)) {
39
+ &:is(.kbq-selected, .kbq-active):has(+ :is(.kbq-selected, .kbq-active)) {
42
40
  border-bottom-left-radius: 0;
43
41
  border-bottom-right-radius: 0;
44
42
  }
45
43
 
46
- &:is(.kbq-selected, .kbq-focused) + :is(.kbq-selected, .kbq-focused) {
44
+ &:is(.kbq-selected, .kbq-active) + :is(.kbq-selected, .kbq-active) {
47
45
  border-top-left-radius: 0;
48
46
  border-top-right-radius: 0;
49
47
  }
@@ -53,18 +51,11 @@
53
51
  &.kbq-selected:not(.kbq-disabled) {
54
52
  @include kbq-option(multiple-states-selected);
55
53
 
56
- &.kbq-hovered,
57
- &:hover {
54
+ &.kbq-active {
58
55
  @include kbq-option(multiple-states-selected-hover);
59
56
  }
60
57
  }
61
58
  }
62
-
63
- .cdk-keyboard-focused {
64
- .kbq-option.kbq-active {
65
- border-color: var(--kbq-list-states-focused-focus-outline-color);
66
- }
67
- }
68
59
  }
69
60
 
70
61
  @mixin kbq-option-typography() {
@@ -39,8 +39,8 @@ export declare enum PopUpTriggers {
39
39
  export declare enum PopUpSizes {
40
40
  Small = "small",
41
41
  Medium = "medium",
42
- Normal = "medium",
43
- Large = "large"
42
+ Large = "large",
43
+ Custom = "custom"
44
44
  }
45
45
  export type KbqPopUpSizeValues = KbqEnumValues<PopUpSizes>;
46
46
  /**
@@ -23,18 +23,14 @@
23
23
  }
24
24
 
25
25
  &.kbq-dropdown-item_highlighted,
26
- &:hover:not(.kbq-disabled) {
26
+ &.cdk-focused:not(.kbq-disabled) {
27
27
  @include _kbq-dropdown-item-state(states-hover);
28
28
  }
29
29
 
30
- &.cdk-keyboard-focused {
31
- border-color: var(--kbq-list-states-focused-focus-outline-color);
32
- }
33
-
34
30
  &.kbq-selected {
35
31
  @include _kbq-dropdown-item-state(states-selected);
36
32
 
37
- &:hover:not(.kbq-disabled) {
33
+ &.cdk-focused:not(.kbq-disabled) {
38
34
  @include _kbq-dropdown-item-state(states-selected-hover);
39
35
  }
40
36
  }
@@ -43,12 +39,12 @@
43
39
  @include _kbq-dropdown-item-state(states-disabled);
44
40
  }
45
41
 
46
- &:is(.kbq-selected, .cdk-keyboard-focused):has(+ :is(.kbq-selected, .cdk-keyboard-focused)) {
42
+ &:is(.kbq-selected, .cdk-focused):has(+ :is(.kbq-selected, .cdk-focused)) {
47
43
  border-bottom-left-radius: 0;
48
44
  border-bottom-right-radius: 0;
49
45
  }
50
46
 
51
- &:is(.kbq-selected, .cdk-keyboard-focused) + :is(.kbq-selected, .cdk-keyboard-focused) {
47
+ &:is(.kbq-selected, .cdk-focused) + :is(.kbq-selected, .cdk-focused) {
52
48
  border-top-left-radius: 0;
53
49
  border-top-right-radius: 0;
54
50
  }
@@ -16,6 +16,16 @@ export declare const KBQ_DROPDOWN_SCROLL_STRATEGY_FACTORY_PROVIDER: {
16
16
  deps: (typeof Overlay)[];
17
17
  useFactory: typeof KBQ_DROPDOWN_SCROLL_STRATEGY_FACTORY;
18
18
  };
19
+ /**
20
+ * Marker provided by host components that create their own stacking context at
21
+ * the default overlay z-index (e.g. `KbqTopBar`, `KbqNavbar` use
22
+ * `position: sticky` + `z-index: $overlay-z-index`). When this token is
23
+ * available in the injector tree, `KbqDropdownTrigger` defaults `demoteOverlay`
24
+ * to `false` so the dropdown overlay is not lowered below the host.
25
+ *
26
+ * An explicit `[demoteOverlay]` binding on the trigger still wins.
27
+ */
28
+ export declare const KBQ_DROPDOWN_HOST: InjectionToken<unknown>;
19
29
  /** Default top padding of the nested dropdown panel. */
20
30
  export declare const NESTED_PANEL_TOP_PADDING = 4;
21
31
  export declare const NESTED_PANEL_LEFT_PADDING = 8;
@@ -37,6 +47,7 @@ export declare class KbqDropdownTrigger implements AfterContentInit, OnDestroy {
37
47
  private readonly renderer;
38
48
  protected readonly isBrowser: boolean;
39
49
  private readonly window;
50
+ private readonly host;
40
51
  lastDestroyReason: DropdownCloseReason;
41
52
  /** Position offset of the dropdown in the X axis. */
42
53
  offsetX: number;
@@ -93,6 +93,14 @@ export declare class KbqDropdown implements AfterContentInit, KbqDropdownPanel,
93
93
  * @param origin Action from which the focus originated. Used to set the correct styling.
94
94
  */
95
95
  focusFirstItem(origin?: FocusOrigin): void;
96
+ /**
97
+ * Applies focus when the dropdown is opened. When opened by mouse or touch, the first item
98
+ * should not be highlighted, so the panel itself is focused instead — keyboard events still
99
+ * reach the panel and the first arrow key press will highlight the first item.
100
+ */
101
+ private applyInitialFocus;
102
+ /** Moves DOM focus onto the dropdown panel so that keydown events keep being handled. */
103
+ private focusPanel;
96
104
  /**
97
105
  * Resets the active item in the dropdown. This is used when the dropdown is opened, allowing
98
106
  * the user to start from the first option when pressing the down arrow.
@@ -32,6 +32,10 @@
32
32
  }
33
33
 
34
34
  .kbq-dropdown__panel {
35
+ // The panel receives programmatic focus when the dropdown is opened by mouse or touch,
36
+ // so the focus outline should never be rendered on it.
37
+ outline: none;
38
+
35
39
  overflow-x: hidden;
36
40
  overflow-y: auto;
37
41