@momentum-design/components 0.129.45 → 0.129.47

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 (37) hide show
  1. package/dist/browser/index.js +300 -300
  2. package/dist/browser/index.js.map +4 -4
  3. package/dist/components/button/button.component.d.ts +9 -1
  4. package/dist/components/button/button.component.js +13 -2
  5. package/dist/components/combobox/combobox.component.d.ts +1 -1
  6. package/dist/components/combobox/combobox.component.js +2 -5
  7. package/dist/components/dialog/dialog.component.d.ts +19 -7
  8. package/dist/components/dialog/dialog.component.js +40 -14
  9. package/dist/components/menubar/menubar.component.d.ts +6 -0
  10. package/dist/components/menubar/menubar.component.js +30 -26
  11. package/dist/components/menupopover/menupopover.component.d.ts +1 -1
  12. package/dist/components/menupopover/menupopover.component.js +19 -24
  13. package/dist/components/popover/popover.component.d.ts +15 -26
  14. package/dist/components/popover/popover.component.js +46 -54
  15. package/dist/components/searchpopover/searchpopover.component.d.ts +1 -1
  16. package/dist/components/searchpopover/searchpopover.component.js +2 -2
  17. package/dist/components/select/select.component.d.ts +1 -1
  18. package/dist/components/select/select.component.js +5 -3
  19. package/dist/components/text/text.component.d.ts +11 -2
  20. package/dist/components/text/text.component.js +17 -2
  21. package/dist/components/tooltip/tooltip.component.d.ts +13 -1
  22. package/dist/components/tooltip/tooltip.component.js +40 -0
  23. package/dist/components/tooltip/tooltip.constants.d.ts +1 -0
  24. package/dist/components/tooltip/tooltip.constants.js +1 -0
  25. package/dist/custom-elements.json +187 -68
  26. package/dist/utils/controllers/DepthManager.d.ts +202 -0
  27. package/dist/utils/controllers/DepthManager.js +259 -0
  28. package/dist/utils/dom.d.ts +8 -0
  29. package/dist/utils/dom.js +7 -0
  30. package/dist/utils/mixins/BackdropMixin.js +19 -2
  31. package/dist/utils/mixins/FocusTrapMixin.d.ts +0 -0
  32. package/dist/utils/mixins/FocusTrapMixin.js +1 -0
  33. package/dist/utils/mixins/OverflowMixin.d.ts +7 -0
  34. package/dist/utils/mixins/OverflowMixin.js +23 -0
  35. package/package.json +1 -1
  36. package/dist/components/popover/popover.stack.d.ts +0 -53
  37. package/dist/components/popover/popover.stack.js +0 -66
@@ -3,7 +3,7 @@ import { CSSResult } from 'lit';
3
3
  import type { RoleType } from '../../utils/roles';
4
4
  import Buttonsimple from '../buttonsimple/buttonsimple.component';
5
5
  import type { IconButtonSize, PillButtonSize } from './button.types';
6
- declare const Button_base: import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/ButtonComponentMixin").ButtonComponentMixinInterface> & typeof Buttonsimple;
6
+ declare const Button_base: import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/OverflowMixin").OverflowMixinInterface> & import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/ButtonComponentMixin").ButtonComponentMixinInterface> & typeof Buttonsimple;
7
7
  /**
8
8
  * `mdc-button` is a component that can be configured in various ways to suit different use cases.
9
9
  *
@@ -68,6 +68,10 @@ declare const Button_base: import("../../utils/mixins/index.types").Constructor<
68
68
  * @cssproperty --mdc-button-line-height - Line height of the button text
69
69
  */
70
70
  declare class Button extends Button_base {
71
+ /**
72
+ * @internal
73
+ */
74
+ protected buttonTextPart: HTMLSlotElement;
71
75
  /**
72
76
  * Specifies the size of the button in pixels. Available sizes depend on the button type:
73
77
  *
@@ -119,6 +123,10 @@ declare class Button extends Button_base {
119
123
  * @internal
120
124
  */
121
125
  private postfixFilledIconName?;
126
+ /**
127
+ * @internal
128
+ */
129
+ protected get overflowElement(): HTMLElement;
122
130
  update(changedProperties: PropertyValues): void;
123
131
  /**
124
132
  * Modifies the icon name based on the active state.
@@ -8,10 +8,11 @@ var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
10
  import { html } from 'lit';
11
- import { property, state } from 'lit/decorators.js';
11
+ import { property, query, state } from 'lit/decorators.js';
12
12
  import { ButtonComponentMixin } from '../../utils/mixins/ButtonComponentMixin';
13
13
  import { ROLE } from '../../utils/roles';
14
14
  import Buttonsimple from '../buttonsimple/buttonsimple.component';
15
+ import { OverflowMixin } from '../../utils/mixins/OverflowMixin';
15
16
  import { DEFAULTS } from './button.constants';
16
17
  import styles from './button.styles';
17
18
  import { getIconNameWithoutStyle } from './button.utils';
@@ -78,7 +79,7 @@ import { getIconNameWithoutStyle } from './button.utils';
78
79
  * @cssproperty --mdc-button-postfix-icon-size - Size of the postfix icon
79
80
  * @cssproperty --mdc-button-line-height - Line height of the button text
80
81
  */
81
- class Button extends ButtonComponentMixin(Buttonsimple) {
82
+ class Button extends OverflowMixin(ButtonComponentMixin(Buttonsimple)) {
82
83
  constructor() {
83
84
  super(...arguments);
84
85
  /**
@@ -125,6 +126,12 @@ class Button extends ButtonComponentMixin(Buttonsimple) {
125
126
  */
126
127
  this.role = ROLE.BUTTON;
127
128
  }
129
+ /**
130
+ * @internal
131
+ */
132
+ get overflowElement() {
133
+ return this.buttonTextPart;
134
+ }
128
135
  update(changedProperties) {
129
136
  super.update(changedProperties);
130
137
  if (changedProperties.has('active')) {
@@ -195,6 +202,10 @@ class Button extends ButtonComponentMixin(Buttonsimple) {
195
202
  }
196
203
  }
197
204
  Button.styles = [...Buttonsimple.styles, ...styles];
205
+ __decorate([
206
+ query('slot[part="button-text"]'),
207
+ __metadata("design:type", HTMLSlotElement)
208
+ ], Button.prototype, "buttonTextPart", void 0);
198
209
  __decorate([
199
210
  property({ type: Number }),
200
211
  __metadata("design:type", Number)
@@ -136,7 +136,7 @@ declare class Combobox extends Combobox_base implements AssociatedFormControl {
136
136
  * Override this to make sure this stays on top of other components.
137
137
  * @default 1000
138
138
  */
139
- popoverZIndex: number;
139
+ popoverZIndex?: number;
140
140
  /**
141
141
  * ID of the element where the backdrop will be appended to.
142
142
  * This is useful to ensure that the backdrop is appended to the correct element in the DOM.
@@ -152,7 +152,7 @@ class Combobox extends KeyToActionMixin(CaptureDestroyEventForChildElement(AutoF
152
152
  * Override this to make sure this stays on top of other components.
153
153
  * @default 1000
154
154
  */
155
- this.popoverZIndex = POPOVER_DEFAULTS.Z_INDEX;
155
+ this.popoverZIndex = undefined;
156
156
  /** @internal */
157
157
  this.isOpen = false;
158
158
  /** @internal */
@@ -468,10 +468,7 @@ class Combobox extends KeyToActionMixin(CaptureDestroyEventForChildElement(AutoF
468
468
  if (activeIndex !== -1) {
469
469
  this.updateOptionAttributes(options[activeIndex], false);
470
470
  }
471
- if (options.length && this.shouldDisplayPopover(options.length)) {
472
- this.closePopover();
473
- }
474
- else {
471
+ if (!(options.length && this.shouldDisplayPopover(options.length))) {
475
472
  this.resetSelectedValue();
476
473
  // clear the visible value
477
474
  this.filteredValue = '';
@@ -1,5 +1,6 @@
1
1
  import { CSSResult, PropertyValues, nothing } from 'lit';
2
2
  import { Component } from '../../models';
3
+ import { StackChange, type StackedOverlayComponent } from '../../utils/controllers/DepthManager';
3
4
  import type { DialogRole, DialogSize, DialogVariant } from './dialog.types';
4
5
  declare const Dialog_base: import("../../utils/mixins/index.types").Constructor<Component & import("../../utils/mixins/BackdropMixin").BackdropMixinInterface> & import("../../utils/mixins/index.types").Constructor<Component & import("../../utils/mixins/PreventScrollMixin").PreventScrollMixinInterface> & import("../../utils/mixins/index.types").Constructor<Component & import("../../utils/mixins/focus/FocusTrapMixin").FocusTrapClassInterface> & import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/FooterMixin").FooterMixinInterface> & typeof Component;
5
6
  /**
@@ -74,11 +75,15 @@ declare const Dialog_base: import("../../utils/mixins/index.types").Constructor<
74
75
  * @slot footer - This slot is for passing custom footer content. Only use this if really needed,
75
76
  * using the footer-link and footer-button slots is preferred
76
77
  */
77
- declare class Dialog extends Dialog_base {
78
+ declare class Dialog extends Dialog_base implements StackedOverlayComponent {
78
79
  /** @internal */
79
80
  protected readonly responsiveSettingsContext: import("@lit/context").ContextConsumer<{
80
81
  __context__: import("../responsivesettingsprovider/responsivesettingsprovider.types").ResponsiveSettings;
81
82
  }, import("lit").ReactiveElement>;
83
+ /** track the depth of the popover for z-index calculation
84
+ * @internal
85
+ */
86
+ private depthManager;
82
87
  /**
83
88
  * The unique ID of the dialog
84
89
  */
@@ -97,12 +102,18 @@ declare class Dialog extends Dialog_base {
97
102
  */
98
103
  visible: boolean;
99
104
  /**
100
- * The z-index of the dialog
105
+ * The internal z-index of the dialog.
106
+ * @internal
107
+ */
108
+ private internalZIndex?;
109
+ /**
110
+ * The effective z-index of the dialog.
101
111
  *
102
- * The backdrop will have z-index of `zIndex - 1`
103
- * @default 1000
112
+ * If no explicit `z-index` value is provided, then it automatically calculated
113
+ * to ensure proper stacking order among multiple overlays.
104
114
  */
105
- zIndex: number;
115
+ get zIndex(): number;
116
+ set zIndex(value: number);
106
117
  /**
107
118
  * The internal value helps to restore original size when responsive settings disabled.
108
119
  *
@@ -203,8 +214,7 @@ declare class Dialog extends Dialog_base {
203
214
  connectedCallback(): void;
204
215
  disconnectedCallback(): void;
205
216
  /**
206
- * Applies the z-index to the dialog and backdrop elements.
207
- * The dialog will have a z-index of `zIndex` and the backdrop will have a z-index of `zIndex - 1`.
217
+ * Applies the z-index to the dialog element.
208
218
  *
209
219
  * @internal
210
220
  */
@@ -239,6 +249,8 @@ declare class Dialog extends Dialog_base {
239
249
  * @param event - The keyboard event.
240
250
  */
241
251
  private onEscapeKeydown;
252
+ /** @internal */
253
+ onComponentStackChanged(changed: StackChange): void;
242
254
  /**
243
255
  * Handles the dialog visibility change.
244
256
  * Handles the exit event to close the dialog.
@@ -19,6 +19,7 @@ import { FooterMixin } from '../../utils/mixins/FooterMixin';
19
19
  import { BackdropMixin } from '../../utils/mixins/BackdropMixin';
20
20
  import providerUtils from '../../utils/provider';
21
21
  import ResponsiveSettingsProvider from '../responsivesettingsprovider';
22
+ import { DepthManager } from '../../utils/controllers/DepthManager';
22
23
  import { DEFAULTS } from './dialog.constants';
23
24
  import { DialogEventManager } from './dialog.events';
24
25
  import styles from './dialog.styles';
@@ -104,6 +105,10 @@ class Dialog extends BackdropMixin(PreventScrollMixin(FocusTrapMixin(FooterMixin
104
105
  subscribe: true,
105
106
  syncProperties: ['size'],
106
107
  });
108
+ /** track the depth of the popover for z-index calculation
109
+ * @internal
110
+ */
111
+ this.depthManager = new DepthManager(this);
107
112
  /**
108
113
  * The unique ID of the dialog
109
114
  */
@@ -115,13 +120,6 @@ class Dialog extends BackdropMixin(PreventScrollMixin(FocusTrapMixin(FooterMixin
115
120
  * @default false
116
121
  */
117
122
  this.visible = DEFAULTS.VISIBLE;
118
- /**
119
- * The z-index of the dialog
120
- *
121
- * The backdrop will have z-index of `zIndex - 1`
122
- * @default 1000
123
- */
124
- this.zIndex = DEFAULTS.Z_INDEX;
125
123
  /**
126
124
  * The internal value helps to restore original size when responsive settings disabled.
127
125
  *
@@ -211,7 +209,7 @@ class Dialog extends BackdropMixin(PreventScrollMixin(FocusTrapMixin(FooterMixin
211
209
  * @param event - The keyboard event.
212
210
  */
213
211
  this.onEscapeKeydown = (event) => {
214
- if (!this.visible || event.code !== 'Escape') {
212
+ if (!this.visible || event.code !== 'Escape' || !this.depthManager.isHostOnTop()) {
215
213
  return;
216
214
  }
217
215
  event.preventDefault();
@@ -221,6 +219,21 @@ class Dialog extends BackdropMixin(PreventScrollMixin(FocusTrapMixin(FooterMixin
221
219
  this.closeDialog();
222
220
  };
223
221
  }
222
+ /**
223
+ * The effective z-index of the dialog.
224
+ *
225
+ * If no explicit `z-index` value is provided, then it automatically calculated
226
+ * to ensure proper stacking order among multiple overlays.
227
+ */
228
+ get zIndex() {
229
+ if (!Number.isInteger(this.internalZIndex)) {
230
+ return this.depthManager.getHostZIndex();
231
+ }
232
+ return this.internalZIndex;
233
+ }
234
+ set zIndex(value) {
235
+ this.internalZIndex = value;
236
+ }
224
237
  /**
225
238
  * The size of the dialog, can be 'small' (432px width), 'medium' (656px width), 'large' (992px width), 'xlarge' (90% width) or 'fullscreen' (100% width).
226
239
  * @default small
@@ -251,15 +264,12 @@ class Dialog extends BackdropMixin(PreventScrollMixin(FocusTrapMixin(FooterMixin
251
264
  DialogEventManager.onDestroyedDialog(this);
252
265
  }
253
266
  /**
254
- * Applies the z-index to the dialog and backdrop elements.
255
- * The dialog will have a z-index of `zIndex` and the backdrop will have a z-index of `zIndex - 1`.
267
+ * Applies the z-index to the dialog element.
256
268
  *
257
269
  * @internal
258
270
  */
259
271
  applyZIndex() {
260
- var _a;
261
272
  this.style.setProperty('z-index', `${this.zIndex}`);
262
- (_a = this.backdropElement) === null || _a === void 0 ? void 0 : _a.style.setProperty('z-index', `${this.zIndex - 1}`);
263
273
  }
264
274
  async firstUpdated(changedProperties) {
265
275
  super.firstUpdated(changedProperties);
@@ -350,8 +360,18 @@ class Dialog extends BackdropMixin(PreventScrollMixin(FocusTrapMixin(FooterMixin
350
360
  * has to be done by the consumer of the component.
351
361
  */
352
362
  closeDialog() {
363
+ this.depthManager.popHost();
353
364
  DialogEventManager.onCloseDialog(this, false);
354
365
  }
366
+ /** @internal */
367
+ onComponentStackChanged(changed) {
368
+ if (changed === 'removed') {
369
+ this.visible = false;
370
+ }
371
+ else if (changed === 'moved') {
372
+ this.requestUpdate('zIndex');
373
+ }
374
+ }
355
375
  /**
356
376
  * Handles the dialog visibility change.
357
377
  * Handles the exit event to close the dialog.
@@ -365,6 +385,10 @@ class Dialog extends BackdropMixin(PreventScrollMixin(FocusTrapMixin(FooterMixin
365
385
  return;
366
386
  }
367
387
  if (newValue && !oldValue) {
388
+ if (this.depthManager.pushHost()) {
389
+ // request update to trigger zIndex recalculation
390
+ this.requestUpdate('zIndex');
391
+ }
368
392
  // Store the currently focused element before opening the dialog
369
393
  this.lastActiveElement = document.activeElement;
370
394
  // create backdrop if enabled
@@ -384,6 +408,7 @@ class Dialog extends BackdropMixin(PreventScrollMixin(FocusTrapMixin(FooterMixin
384
408
  DialogEventManager.onShowDialog(this);
385
409
  }
386
410
  else if (!newValue && oldValue) {
411
+ this.depthManager.popHost();
387
412
  // Always remove backdrop if it exists, regardless of current hideBackdrop value
388
413
  // This handles the case where hideBackdrop was changed while dialog was open
389
414
  this.removeBackdrop();
@@ -481,8 +506,9 @@ __decorate([
481
506
  ], Dialog.prototype, "visible", void 0);
482
507
  __decorate([
483
508
  property({ type: Number, reflect: true, attribute: 'z-index' }),
484
- __metadata("design:type", Number)
485
- ], Dialog.prototype, "zIndex", void 0);
509
+ __metadata("design:type", Number),
510
+ __metadata("design:paramtypes", [Number])
511
+ ], Dialog.prototype, "zIndex", null);
486
512
  __decorate([
487
513
  property({ type: String, reflect: true }),
488
514
  __metadata("design:type", String),
@@ -1,5 +1,6 @@
1
1
  import type { CSSResult, PropertyValues } from 'lit';
2
2
  import { Component } from '../../models';
3
+ import { DepthManager } from '../../utils/controllers/DepthManager';
3
4
  declare const MenuBar_base: import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/KeyToActionMixin").KeyToActionInterface> & typeof Component;
4
5
  /**
5
6
  * Menubar is a navigational menu component that provides a vertical fixed list of menu items,
@@ -25,9 +26,14 @@ declare const MenuBar_base: import("../../utils/mixins/index.types").Constructor
25
26
  * @slot default - Contains the menu items and their associated popovers
26
27
  */
27
28
  declare class MenuBar extends MenuBar_base {
29
+ /** track the depth of the popover for z-index calculation
30
+ * @internal
31
+ */
32
+ protected depthManager: DepthManager;
28
33
  menusections: Array<HTMLElement>;
29
34
  constructor();
30
35
  connectedCallback(): Promise<void>;
36
+ disconnectedCallback(): Promise<void>;
31
37
  /**
32
38
  * Returns all menuitem elements, including those nested inside menusection.
33
39
  */
@@ -15,7 +15,7 @@ import { POPOVER_PLACEMENT } from '../popover/popover.constants';
15
15
  import { TAG_NAME as MENUPOPOVER_TAGNAME } from '../menupopover/menupopover.constants';
16
16
  import { TAG_NAME as MENUSECTION_TAGNAME } from '../menusection/menusection.constants';
17
17
  import { TAG_NAME as SIDENAV_TAGNAME } from '../sidenavigation/sidenavigation.constants';
18
- import { popoverStack } from '../popover/popover.stack';
18
+ import { DepthManager } from '../../utils/controllers/DepthManager';
19
19
  import { ACTIONS, KeyToActionMixin } from '../../utils/mixins/KeyToActionMixin';
20
20
  import { DEFAULTS, TAG_NAME as MENUBAR_TAGNAME } from './menubar.constants';
21
21
  import styles from './menubar.styles';
@@ -45,7 +45,29 @@ import styles from './menubar.styles';
45
45
  class MenuBar extends KeyToActionMixin(Component) {
46
46
  constructor() {
47
47
  super();
48
- this.addEventListener('click', this.handleClick.bind(this));
48
+ /** track the depth of the popover for z-index calculation
49
+ * @internal
50
+ */
51
+ this.depthManager = new DepthManager(this);
52
+ /**
53
+ * Closes all other submenus on the top level.
54
+ * This method is used to ensure that only one topolevel submenu is open at a time.
55
+ * It finds all other menu items with submenus and closes their submenus.
56
+ * @param target - The target menu item that was clicked.
57
+ */
58
+ this.handleClick = (event) => {
59
+ // Event is triggered from within the menubar
60
+ if (event.composed && event.composedPath().find(el => el === this)) {
61
+ const target = event.target;
62
+ if (!target || !this.isTopLevelMenuItem(target))
63
+ return;
64
+ const otherMenuItemsOnTop = this.menuItems.filter(item => item !== target);
65
+ const otherOpenSubMenus = this.getVisibleSubMenusOfItems(otherMenuItemsOnTop);
66
+ otherOpenSubMenus.forEach(subMenu => {
67
+ subMenu.hide();
68
+ });
69
+ }
70
+ };
49
71
  this.addEventListener('keydown', this.handleKeyDown.bind(this));
50
72
  }
51
73
  async connectedCallback() {
@@ -53,12 +75,17 @@ class MenuBar extends KeyToActionMixin(Component) {
53
75
  super.connectedCallback();
54
76
  this.role = ROLE.MENUBAR;
55
77
  this.ariaOrientation = DEFAULTS.ORIENTATION;
78
+ document.addEventListener('click', this.handleClick, { capture: true });
56
79
  await this.updateComplete;
57
80
  // to make sure menusection dividers have the correct divider variant
58
81
  (_a = this.menusections) === null || _a === void 0 ? void 0 : _a.forEach(section => {
59
82
  section.setAttribute('divider-variant', 'gradient');
60
83
  });
61
84
  }
85
+ async disconnectedCallback() {
86
+ super.disconnectedCallback();
87
+ document.removeEventListener('click', this.handleClick, { capture: true });
88
+ }
62
89
  /**
63
90
  * Returns all menuitem elements, including those nested inside menusection.
64
91
  */
@@ -128,22 +155,6 @@ class MenuBar extends KeyToActionMixin(Component) {
128
155
  this.resetTabIndexAndSetActiveTabIndex(this.menuItems);
129
156
  this.updatePopoverPlacement();
130
157
  }
131
- /**
132
- * Closes all other submenus on the top level.
133
- * This method is used to ensure that only one topolevel submenu is open at a time.
134
- * It finds all other menu items with submenus and closes their submenus.
135
- * @param target - The target menu item that was clicked.
136
- */
137
- handleClick(event) {
138
- const target = event.target;
139
- if (!target || !this.isTopLevelMenuItem(target))
140
- return;
141
- const otherMenuItemsOnTop = this.menuItems.filter(item => item !== target);
142
- const otherOpenSubMenus = this.getVisibleSubMenusOfItems(otherMenuItemsOnTop);
143
- otherOpenSubMenus.forEach(subMenu => {
144
- subMenu.hide();
145
- });
146
- }
147
158
  /**
148
159
  * Resets all list items tabindex to -1 and sets the tabindex of the
149
160
  * element at the given index to 0, effectively setting the active
@@ -228,14 +239,7 @@ class MenuBar extends KeyToActionMixin(Component) {
228
239
  return !!element.closest(MENUPOPOVER_TAGNAME) && element.role === ROLE.MENUITEM;
229
240
  }
230
241
  async closeAllMenuPopovers() {
231
- const popovers = [];
232
- while (popoverStack.peek()) {
233
- const popover = popoverStack.pop();
234
- if (popover) {
235
- popover.hide();
236
- popovers.push(popover);
237
- }
238
- }
242
+ const popovers = this.depthManager.popUntil(item => this.contains(item));
239
243
  await Promise.all(popovers.map(popover => popover.updateComplete));
240
244
  }
241
245
  async crossMenubarNavigationOnLeft(element) {
@@ -109,7 +109,7 @@ declare class MenuPopover extends Popover {
109
109
  * Closes all menu popovers in the stack.
110
110
  * This method is used to ensure that when a menu item is clicked,
111
111
  * all other open popovers are closed, maintaining a clean user interface.
112
- * It iterates through the `popoverStack` and hides each popover until the stack is empty.
112
+ * It iterates through the overlay stack and hides each popover until the stack is empty.
113
113
  *
114
114
  * @param until - The popover to close until.
115
115
  */
@@ -16,7 +16,6 @@ import { TAG_NAME as MENUITEMCHECKBOX_TAGNAME } from '../menuitemcheckbox/menuit
16
16
  import { TAG_NAME as MENUITEMRADIO_TAGNAME } from '../menuitemradio/menuitemradio.constants';
17
17
  import Popover from '../popover/popover.component';
18
18
  import { COLOR } from '../popover/popover.constants';
19
- import { popoverStack } from '../popover/popover.stack';
20
19
  import { ACTIONS } from '../../utils/mixins/KeyToActionMixin';
21
20
  import { DEFAULTS, TAG_NAME as MENU_POPOVER } from './menupopover.constants';
22
21
  import styles from './menupopover.styles';
@@ -99,7 +98,7 @@ class MenuPopover extends Popover {
99
98
  * @param event - The mouse event that triggered the outside click.
100
99
  */
101
100
  this.onOutsidePopoverClick = (event) => {
102
- if (popoverStack.peek() !== this)
101
+ if (!this.depthManager.isHostOnTop())
103
102
  return;
104
103
  const path = event.composedPath();
105
104
  const insidePopoverClick = this.contains(event.target) || path.includes(this.triggerElement) || path.includes(this);
@@ -117,13 +116,20 @@ class MenuPopover extends Popover {
117
116
  */
118
117
  this.togglePopoverVisible = (event) => {
119
118
  var _a;
120
- if (((_a = this.triggerElement) === null || _a === void 0 ? void 0 : _a.hasAttribute('soft-disabled')) || !this.isEventFromTrigger(event))
119
+ if ((_a = this.triggerElement) === null || _a === void 0 ? void 0 : _a.hasAttribute('soft-disabled'))
121
120
  return;
122
- if (this.visible) {
123
- this.hide();
121
+ // Handle mouse click in the parent menupopover to hide open sibling submenus
122
+ if (event.composedPath().find(el => el.tagName === this.tagName) === this) {
123
+ this.handleMouseClick(event);
124
124
  }
125
- else {
126
- this.show();
125
+ // Toggle visibility of the current menupopover
126
+ if (this.isEventFromTrigger(event)) {
127
+ if (this.visible) {
128
+ this.hide();
129
+ }
130
+ else {
131
+ this.show();
132
+ }
127
133
  }
128
134
  };
129
135
  this.handleItemCreation = (event) => {
@@ -220,8 +226,10 @@ class MenuPopover extends Popover {
220
226
  break;
221
227
  }
222
228
  case ACTIONS.ESCAPE: {
223
- this.resetTabIndexAndSetFocus(0, currentIndex);
224
- isKeyHandled = true;
229
+ if (this.depthManager.isHostOnTop()) {
230
+ this.resetTabIndexAndSetFocus(0, currentIndex);
231
+ isKeyHandled = true;
232
+ }
225
233
  break;
226
234
  }
227
235
  case ACTIONS.ENTER: {
@@ -289,7 +297,6 @@ class MenuPopover extends Popover {
289
297
  };
290
298
  this.addEventListener('keydown', this.handleKeyDown);
291
299
  this.addEventListener('keyup', this.handleKeyUp);
292
- this.addEventListener('click', this.handleMouseClick);
293
300
  this.addEventListener('created', this.handleItemCreation);
294
301
  }
295
302
  /**
@@ -419,22 +426,12 @@ class MenuPopover extends Popover {
419
426
  * Closes all menu popovers in the stack.
420
427
  * This method is used to ensure that when a menu item is clicked,
421
428
  * all other open popovers are closed, maintaining a clean user interface.
422
- * It iterates through the `popoverStack` and hides each popover until the stack is empty.
429
+ * It iterates through the overlay stack and hides each popover until the stack is empty.
423
430
  *
424
431
  * @param until - The popover to close until.
425
432
  */
426
433
  closeAllMenuPopovers(until) {
427
- while (popoverStack.peek() !== until) {
428
- if (!isValidMenuPopover(popoverStack.peek()))
429
- break;
430
- const popover = popoverStack.pop();
431
- if (popover) {
432
- popover.hide();
433
- }
434
- else {
435
- break;
436
- }
437
- }
434
+ this.depthManager.popUntil(item => item !== until && isValidMenuPopover(item));
438
435
  }
439
436
  /**
440
437
  * Closes all other submenus on the same level as the target menu item.
@@ -468,8 +465,6 @@ class MenuPopover extends Popover {
468
465
  */
469
466
  handleMouseClick(event) {
470
467
  const target = event.target;
471
- // stopPropagation to prevent the click from bubbling up to parent elements
472
- event.stopPropagation();
473
468
  // if the target is not a valid menu item or if the event is not trusted (
474
469
  // e.g., triggered by keydown originally), do nothing. Pressing space and enter
475
470
  // is handled separately in the respective handler.
@@ -1,5 +1,6 @@
1
1
  import { CSSResult, PropertyValues } from 'lit';
2
2
  import { Component } from '../../models';
3
+ import { DepthManager, StackChange } from '../../utils/controllers/DepthManager';
3
4
  import type { PopoverBoundaryRoot, PopoverColor, PopoverPlacement, PopoverStrategy, PopoverTrigger } from './popover.types';
4
5
  declare const Popover_base: import("../../utils/mixins/index.types").Constructor<import("../../utils/mixins/KeyToActionMixin").KeyToActionInterface> & import("../../utils/mixins/index.types").Constructor<Component & import("../../utils/mixins/BackdropMixin").BackdropMixinInterface> & import("../../utils/mixins/index.types").Constructor<Component & import("../../utils/mixins/PreventScrollMixin").PreventScrollMixinInterface> & import("../../utils/mixins/index.types").Constructor<Component & import("../../utils/mixins/focus/FocusTrapMixin").FocusTrapClassInterface> & typeof Component;
5
6
  /**
@@ -77,6 +78,10 @@ declare const Popover_base: import("../../utils/mixins/index.types").Constructor
77
78
  * @csspart popover-hover-bridge - The hover bridge of the popover.
78
79
  */
79
80
  declare class Popover extends Popover_base {
81
+ /** track the depth of the popover for z-index calculation
82
+ * @internal
83
+ */
84
+ protected depthManager: DepthManager;
80
85
  /**
81
86
  * The unique ID of the popover.
82
87
  */
@@ -261,20 +266,16 @@ declare class Popover extends Popover_base {
261
266
  * @default false
262
267
  */
263
268
  size: boolean;
269
+ /**
270
+ * The internal z-index of the popovere.
271
+ * @internal
272
+ */
273
+ private internalZIndex?;
264
274
  /**
265
275
  * The effective z-index of the popover.
266
276
  *
267
- * If no explicit `z-index` value is provided, then we calculate
268
- * z-index based on the popover’s nesting depth (`popoverDepth`)
269
- * to ensure proper stacking order among multiple popovers.
270
- *
271
- * The formula used is: `DEFAULTS.Z_INDEX + (popoverDepth * 3)`.
272
- * This approach guarantees that each nested popover appears above its parent.
273
- * Ex: A root-level popover has a z-index of 1000,
274
- * its first-level child popover will have a z-index of 1003,
275
- * and a second-level child popover will have a z-index of 1006, and so on.
276
- *
277
- * When a value is explicitly set, it overrides the internally computed value.
277
+ * If no explicit `z-index` value is provided, then it automatically calculated
278
+ * to ensure proper stacking order among multiple overlays.
278
279
  */
279
280
  get zIndex(): number;
280
281
  set zIndex(value: number);
@@ -355,20 +356,6 @@ declare class Popover extends Popover_base {
355
356
  private floatingUICleanupFunction;
356
357
  /** @internal */
357
358
  protected shouldSuppressOpening: boolean;
358
- /**
359
- * The internal z-index of the popover.
360
- * @internal
361
- */
362
- private internalZIndex?;
363
- /**
364
- * At root-level popover starts with a depth of `0`. Each subsequent
365
- * child popover increases the depth by one.
366
- *
367
- * This value is used to compute stacking order (z-index) dynamically,
368
- * ensuring that nested popovers appear above their parent popovers.
369
- * @internal
370
- */
371
- private popoverDepth;
372
359
  /** @internal */
373
360
  private get connectedTooltip();
374
361
  /**
@@ -427,6 +414,8 @@ declare class Popover extends Popover_base {
427
414
  * @internal
428
415
  */
429
416
  private onPopoverFocusOut;
417
+ /** @internal */
418
+ onComponentStackChanged(changed: StackChange): void;
430
419
  /**
431
420
  * Handles the popover visibility change and position the popover.
432
421
  * Handles the exit event to close the popover.
@@ -478,7 +467,7 @@ declare class Popover extends Popover_base {
478
467
  /**
479
468
  * Shows the popover.
480
469
  */
481
- show: () => void;
470
+ show(): void;
482
471
  /**
483
472
  * Hides the popover.
484
473
  */