@momentum-design/components 0.100.0 → 0.100.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 (91) hide show
  1. package/dist/browser/index.js +1440 -1210
  2. package/dist/browser/index.js.map +4 -4
  3. package/dist/components/accordion/accordion.component.d.ts +74 -0
  4. package/dist/components/accordion/accordion.component.js +128 -0
  5. package/dist/components/accordion/accordion.constants.d.ts +2 -0
  6. package/dist/components/accordion/accordion.constants.js +3 -0
  7. package/dist/components/accordion/accordion.styles.d.ts +2 -0
  8. package/dist/components/accordion/accordion.styles.js +17 -0
  9. package/dist/components/accordion/index.d.ts +10 -0
  10. package/dist/components/accordion/index.js +7 -0
  11. package/dist/components/accordionbutton/accordionbutton.component.d.ts +119 -0
  12. package/dist/components/accordionbutton/accordionbutton.component.js +238 -0
  13. package/dist/components/accordionbutton/accordionbutton.constants.d.ts +17 -0
  14. package/dist/components/accordionbutton/accordionbutton.constants.js +19 -0
  15. package/dist/components/accordionbutton/accordionbutton.styles.d.ts +2 -0
  16. package/dist/components/accordionbutton/accordionbutton.styles.js +121 -0
  17. package/dist/components/accordionbutton/accordionbutton.types.d.ts +8 -0
  18. package/dist/components/accordionbutton/accordionbutton.types.js +1 -0
  19. package/dist/components/accordionbutton/index.d.ts +10 -0
  20. package/dist/components/accordionbutton/index.js +7 -0
  21. package/dist/components/accordiongroup/accordiongroup.component.d.ts +71 -0
  22. package/dist/components/accordiongroup/accordiongroup.component.js +132 -0
  23. package/dist/components/accordiongroup/accordiongroup.constants.d.ts +15 -0
  24. package/dist/components/accordiongroup/accordiongroup.constants.js +16 -0
  25. package/dist/components/accordiongroup/accordiongroup.styles.d.ts +2 -0
  26. package/dist/components/accordiongroup/accordiongroup.styles.js +48 -0
  27. package/dist/components/accordiongroup/accordiongroup.types.d.ts +5 -0
  28. package/dist/components/accordiongroup/accordiongroup.types.js +1 -0
  29. package/dist/components/accordiongroup/index.d.ts +7 -0
  30. package/dist/components/accordiongroup/index.js +4 -0
  31. package/dist/components/animation/animation.component.d.ts +1 -0
  32. package/dist/components/animation/animation.component.js +9 -0
  33. package/dist/components/cardcheckbox/cardcheckbox.component.js +3 -3
  34. package/dist/components/cardradio/cardradio.component.js +3 -3
  35. package/dist/components/dialog/dialog.component.js +5 -0
  36. package/dist/components/formfieldwrapper/formfieldwrapper.styles.js +1 -0
  37. package/dist/components/icon/icon.component.d.ts +2 -1
  38. package/dist/components/icon/icon.component.js +9 -1
  39. package/dist/components/linksimple/linksimple.component.js +11 -11
  40. package/dist/components/listitem/listitem.component.js +6 -6
  41. package/dist/components/listitem/listitem.events.js +3 -1
  42. package/dist/components/menubar/menubar.component.d.ts +9 -0
  43. package/dist/components/menubar/menubar.component.js +38 -4
  44. package/dist/components/menuitem/menuitem.component.js +1 -1
  45. package/dist/components/menuitemcheckbox/menuitemcheckbox.component.js +12 -12
  46. package/dist/components/menuitemradio/menuitemradio.component.js +13 -13
  47. package/dist/components/menupopover/menupopover.component.d.ts +30 -12
  48. package/dist/components/menupopover/menupopover.component.js +231 -179
  49. package/dist/components/menupopover/menupopover.utils.d.ts +2 -2
  50. package/dist/components/menupopover/menupopover.utils.js +2 -2
  51. package/dist/components/navmenuitem/navmenuitem.component.js +1 -1
  52. package/dist/components/popover/popover.component.d.ts +29 -9
  53. package/dist/components/popover/popover.component.js +277 -212
  54. package/dist/components/popover/popover.constants.d.ts +1 -0
  55. package/dist/components/popover/popover.constants.js +1 -0
  56. package/dist/components/popover/popover.types.d.ts +19 -6
  57. package/dist/components/popover/popover.utils.d.ts +7 -2
  58. package/dist/components/popover/popover.utils.js +19 -8
  59. package/dist/components/select/select.component.js +2 -0
  60. package/dist/components/select/select.styles.js +1 -1
  61. package/dist/components/select/select.types.d.ts +5 -1
  62. package/dist/components/sidenavigation/sidenavigation.component.js +1 -1
  63. package/dist/components/spinner/spinner.component.d.ts +1 -1
  64. package/dist/components/spinner/spinner.component.js +1 -1
  65. package/dist/components/tablist/tablist.component.d.ts +1 -0
  66. package/dist/components/tablist/tablist.component.js +284 -273
  67. package/dist/components/textarea/textarea.component.d.ts +2 -2
  68. package/dist/components/textarea/textarea.component.js +2 -2
  69. package/dist/components/tooltip/tooltip.component.d.ts +1 -1
  70. package/dist/components/tooltip/tooltip.component.js +14 -15
  71. package/dist/custom-elements.json +7364 -6056
  72. package/dist/index.d.ts +10 -7
  73. package/dist/index.js +10 -7
  74. package/dist/react/accordion/index.d.ts +53 -0
  75. package/dist/react/accordion/index.js +61 -0
  76. package/dist/react/accordionbutton/index.d.ts +50 -0
  77. package/dist/react/accordionbutton/index.js +58 -0
  78. package/dist/react/accordiongroup/index.d.ts +30 -0
  79. package/dist/react/accordiongroup/index.js +39 -0
  80. package/dist/react/coachmark/index.d.ts +12 -4
  81. package/dist/react/index.d.ts +9 -6
  82. package/dist/react/index.js +9 -6
  83. package/dist/react/menupopover/index.d.ts +12 -4
  84. package/dist/react/popover/index.d.ts +12 -4
  85. package/dist/react/toggletip/index.d.ts +12 -4
  86. package/dist/react/tooltip/index.d.ts +12 -4
  87. package/dist/utils/keys.d.ts +1 -0
  88. package/dist/utils/keys.js +1 -0
  89. package/dist/utils/roles.d.ts +2 -0
  90. package/dist/utils/roles.js +2 -0
  91. package/package.json +2 -2
@@ -19,7 +19,7 @@ import { COLOR } from '../popover/popover.constants';
19
19
  import { popoverStack } from '../popover/popover.stack';
20
20
  import { DEFAULTS, TAG_NAME as MENU_POPOVER } from './menupopover.constants';
21
21
  import styles from './menupopover.styles';
22
- import { isValidMenuItem, isValidPopover } from './menupopover.utils';
22
+ import { isValidMenuItem, isValidMenuPopover } from './menupopover.utils';
23
23
  /**
24
24
  * A popover menu component that displays a list of menu items in a floating container.
25
25
  * It's designed to work in conjunction with `mdc-menubar` and `mdc-menuitem` to create
@@ -85,6 +85,7 @@ class MenuPopover extends Popover {
85
85
  */
86
86
  this.placement = DEFAULTS.PLACEMENT;
87
87
  this.menuItems = [];
88
+ this.menuItemsWithSubMenus = [];
88
89
  /**
89
90
  * Handles outside click events to close the popover.
90
91
  * This method checks if the click occurred outside the popover and its trigger element.
@@ -95,29 +96,41 @@ class MenuPopover extends Popover {
95
96
  this.onOutsidePopoverClick = (event) => {
96
97
  if (popoverStack.peek() !== this)
97
98
  return;
98
- const popoverOfTarget = this.findClosestPopover(event.target);
99
- // If the click occurred on a submenu, close all popovers until the submenu
100
- if (popoverOfTarget && popoverStack.has(popoverOfTarget)) {
101
- this.closeAllMenuPopovers(popoverOfTarget);
102
- return;
103
- }
104
99
  const path = event.composedPath();
105
- const insidePopoverClick = this.contains(event.target) || path.includes(this.triggerElement);
100
+ const insidePopoverClick = this.contains(event.target) || path.includes(this.triggerElement) || path.includes(this);
106
101
  const clickedOnBackdrop = this.backdropElement ? path.includes(this.backdropElement) : false;
107
102
  if (!insidePopoverClick || clickedOnBackdrop) {
108
103
  this.closeAllMenuPopovers();
109
104
  }
110
105
  };
106
+ /**
107
+ * Toggles the visibility of the popover.
108
+ * This method checks if the trigger element has the `soft-disabled` attribute.
109
+ * If it does, the popover will not be toggled.
110
+ * If the popover is currently visible, it hides the popover; otherwise, it shows the popover.
111
+ * @returns - This method does not return anything.
112
+ */
111
113
  this.togglePopoverVisible = () => {
112
114
  var _a;
113
115
  if ((_a = this.triggerElement) === null || _a === void 0 ? void 0 : _a.hasAttribute('soft-disabled'))
114
116
  return;
115
- if (this.isTriggerClicked) {
116
- this.hidePopover();
117
+ if (this.visible) {
118
+ this.hide();
117
119
  }
118
120
  else {
119
- this.showPopover();
120
- this.isTriggerClicked = true;
121
+ this.show();
122
+ }
123
+ };
124
+ this.handleItemCreation = (event) => {
125
+ const item = event.target;
126
+ if (isValidMenuItem(item)) {
127
+ // Parent menu popover should not listen on nested menu items
128
+ event.stopImmediatePropagation();
129
+ // `destroyed` triggered in the `disconnectedCallback` of the item which executed when the item is removed from the DOM
130
+ // because of that the event does not bubble up to menupopover, and we need to capture the `destroyed` event on the item itself
131
+ item.addEventListener('destroyed', this.handleItemChangeEvent);
132
+ // `disabled` could bubble up, but it is more consistent to handle it the same way as `destroyed`
133
+ item.addEventListener('disabled', this.handleItemChangeEvent);
121
134
  }
122
135
  };
123
136
  this.handleItemChangeEvent = (event) => {
@@ -137,11 +150,158 @@ class MenuPopover extends Popover {
137
150
  this.resetTabIndexes(0);
138
151
  }
139
152
  };
153
+ /**
154
+ * Handles keydown events for keyboard navigation within the menu popover.
155
+ * This method allows users to navigate through the menu items using the keyboard.
156
+ * It supports Home, End, Arrow Up, Arrow Down, Arrow Left, Arrow Right, and Escape keys.
157
+ *
158
+ * Also, it handles Enter key to close the menu popover
159
+ *
160
+ * @param event - The keyboard event that triggered the keydown action.
161
+ * @returns - This method does not return anything.
162
+ */
163
+ this.handleKeyDown = (event) => {
164
+ let isKeyHandled = false;
165
+ this.collectMenuItems();
166
+ const target = event.target;
167
+ const currentIndex = this.getCurrentIndex(target);
168
+ if (currentIndex === -1)
169
+ return;
170
+ this.resetTabIndexes(currentIndex);
171
+ const isRtl = window.getComputedStyle(this).direction === 'rtl';
172
+ const targetKey = this.resolveDirectionKey(event.key, isRtl);
173
+ switch (targetKey) {
174
+ case KEYS.HOME: {
175
+ // Move focus to the first menu item
176
+ this.resetTabIndexAndSetFocus(0, currentIndex);
177
+ isKeyHandled = true;
178
+ break;
179
+ }
180
+ case KEYS.END: {
181
+ // Move focus to the last menu item
182
+ this.resetTabIndexAndSetFocus(this.menuItems.length - 1, currentIndex);
183
+ isKeyHandled = true;
184
+ break;
185
+ }
186
+ case KEYS.ARROW_DOWN: {
187
+ // Move focus to the next menu item
188
+ const newIndex = currentIndex + 1 === this.menuItems.length ? 0 : currentIndex + 1;
189
+ this.resetTabIndexAndSetFocus(newIndex, currentIndex);
190
+ isKeyHandled = true;
191
+ break;
192
+ }
193
+ case KEYS.ARROW_UP: {
194
+ // Move focus to the prev menu item
195
+ const newIndex = currentIndex - 1 === -1 ? this.menuItems.length - 1 : currentIndex - 1;
196
+ this.resetTabIndexAndSetFocus(newIndex, currentIndex);
197
+ isKeyHandled = true;
198
+ break;
199
+ }
200
+ case KEYS.ARROW_RIGHT: {
201
+ // If there is a submenu, open it.
202
+ const subMenu = this.getSubMenuPopoverOfTarget(target);
203
+ if (subMenu) {
204
+ subMenu.show();
205
+ isKeyHandled = true;
206
+ }
207
+ break;
208
+ }
209
+ case KEYS.ARROW_LEFT: {
210
+ // If the current popover is a submenu then close this popover.
211
+ if (isValidMenuPopover(this.parentElement)) {
212
+ this.hide();
213
+ this.resetTabIndexAndSetFocus(0, currentIndex);
214
+ isKeyHandled = true;
215
+ }
216
+ break;
217
+ }
218
+ case KEYS.ESCAPE: {
219
+ this.resetTabIndexAndSetFocus(0, currentIndex);
220
+ isKeyHandled = true;
221
+ break;
222
+ }
223
+ case KEYS.ENTER: {
224
+ if (!this.getSubMenuPopoverOfTarget(target)) {
225
+ this.closeAllMenuPopovers();
226
+ this.fireMenuItemAction(target);
227
+ isKeyHandled = true;
228
+ }
229
+ break;
230
+ }
231
+ case KEYS.SPACE: {
232
+ // Prevent page scroll when space is pressed down
233
+ isKeyHandled = true;
234
+ break;
235
+ }
236
+ default:
237
+ break;
238
+ }
239
+ // When menu consume any of the pressed key, we need to stop propagation
240
+ // to prevent the event from bubbling up and being handled by parent components which might use the same key.
241
+ if (isKeyHandled) {
242
+ event.stopPropagation();
243
+ event.preventDefault();
244
+ }
245
+ };
246
+ /**
247
+ * Handles keyup events for keyboard navigation within the menu popover.
248
+ *
249
+ * Some keys must be handled with keyup event to prevent default action.
250
+ *
251
+ * Space key closes the menu when the user presses it on a menu item,
252
+ * but the same key will trigger a click on the menu opener button.
253
+ * The button uses the keyup event so we have to handle it here as well
254
+ * to prevent the meu opener action which would re-open the menu.
255
+ *
256
+ * @param event - The keyboard event that triggered the keydown action.
257
+ * @returns - This method does not return anything.
258
+ */
259
+ this.handleKeyUp = (event) => {
260
+ let isKeyHandled = false;
261
+ const target = event.target;
262
+ switch (event.key) {
263
+ case KEYS.SPACE: {
264
+ // If the target is a menu item, trigger its click event
265
+ if (!target.matches(`${MENUITEMRADIO_TAGNAME}, ${MENUITEMCHECKBOX_TAGNAME}`)) {
266
+ // only close all menu popovers if the target is not opening a menu popover
267
+ if (!this.getSubMenuPopoverOfTarget(target)) {
268
+ this.closeAllMenuPopovers();
269
+ this.fireMenuItemAction(target);
270
+ isKeyHandled = true;
271
+ }
272
+ }
273
+ break;
274
+ }
275
+ default:
276
+ break;
277
+ }
278
+ // When menu consume any of the pressed key, we need to stop propagation
279
+ // to prevent the event from bubbling up and being handled by parent components which might use the same key.
280
+ if (isKeyHandled) {
281
+ event.stopPropagation();
282
+ event.preventDefault();
283
+ }
284
+ };
140
285
  this.addEventListener('keydown', this.handleKeyDown);
141
286
  this.addEventListener('keyup', this.handleKeyUp);
142
287
  this.addEventListener('click', this.handleMouseClick);
143
288
  this.addEventListener('created', this.handleItemCreation);
144
289
  }
290
+ /**
291
+ * Retrieves the submenu popover associated with a given target element.
292
+ * This method checks if the target element has an `id` attribute and uses it to find the corresponding submenu popover.
293
+ * If a submenu popover is found, it returns it; otherwise, it returns `undefined` or `null`.
294
+ * @param target - The target element for which to find the submenu popover.
295
+ * @returns - The submenu popover instance or `undefined`/`null` if not found.
296
+ * @internal
297
+ */
298
+ getSubMenuPopoverOfTarget(target) {
299
+ var _a, _b;
300
+ const id = target.getAttribute('id');
301
+ if (!id)
302
+ return null;
303
+ return (_b = (_a = this.parentElement) === null || _a === void 0 ? void 0 : _a.querySelector) === null || _b === void 0 ? void 0 : _b.call(_a, `${MENU_POPOVER}[triggerid="${id}"]`);
304
+ }
145
305
  /** @internal */
146
306
  collectMenuItems() {
147
307
  var _a;
@@ -156,6 +316,23 @@ class MenuPopover extends Popover {
156
316
  })
157
317
  .flat()
158
318
  .filter(node => !!node && !node.hasAttribute('disabled'));
319
+ this.menuItemsWithSubMenus = this.menuItems.filter(item => {
320
+ const submenu = this.getSubMenuPopoverOfTarget(item);
321
+ return submenu;
322
+ });
323
+ }
324
+ /** @internal */
325
+ getOpenSubMenusOfItems(items) {
326
+ const subMenus = [];
327
+ if (!items || items.length === 0)
328
+ return subMenus;
329
+ items.forEach(item => {
330
+ const submenu = this.getSubMenuPopoverOfTarget(item);
331
+ if (submenu && submenu.visible) {
332
+ subMenus.push(submenu);
333
+ }
334
+ });
335
+ return subMenus;
159
336
  }
160
337
  connectedCallback() {
161
338
  super.connectedCallback();
@@ -183,6 +360,15 @@ class MenuPopover extends Popover {
183
360
  if (newValue) {
184
361
  this.backdrop = !(this.triggerElement.tagName.toLowerCase() === MENUITEM_TAGNAME);
185
362
  }
363
+ // if the current menupopover is closed, close all submenus
364
+ if (newValue === false) {
365
+ this.menuItemsWithSubMenus.forEach(item => {
366
+ const submenu = this.getSubMenuPopoverOfTarget(item);
367
+ if (submenu) {
368
+ submenu.hide();
369
+ }
370
+ });
371
+ }
186
372
  this.resetMenuNavigation();
187
373
  return super.isOpenUpdated(oldValue, newValue);
188
374
  }
@@ -236,9 +422,11 @@ class MenuPopover extends Popover {
236
422
  */
237
423
  closeAllMenuPopovers(until) {
238
424
  while (popoverStack.peek() !== until) {
425
+ if (!isValidMenuPopover(popoverStack.peek()))
426
+ break;
239
427
  const popover = popoverStack.pop();
240
428
  if (popover) {
241
- popover.hidePopover();
429
+ popover.hide();
242
430
  }
243
431
  else {
244
432
  break;
@@ -246,32 +434,27 @@ class MenuPopover extends Popover {
246
434
  }
247
435
  }
248
436
  /**
249
- * Checks if the menu popover has a submenu with the specified trigger ID.
250
- * This method is used to determine if a menu item has a submenu associated with it,
251
- * which is indicated by the presence of a `triggerid` attribute in the submenu popover.
252
- * It queries the parent element for any popover with the specified trigger ID.
253
- * @param id - The ID of the menu item to check for a submenu.
254
- * @returns - A boolean indicating whether a submenu with the specified trigger ID exists.
437
+ * Closes all other submenus on the same level as the target menu item.
438
+ * This method is used to ensure that only one submenu is open at a time.
439
+ * It finds all other menu items with submenus and closes their submenus.
440
+ * @param target - The target menu item that was clicked.
255
441
  */
256
- hasSubmenuWithTriggerId(id) {
257
- var _a, _b;
258
- return !!id && ((_b = (_a = this.parentElement) === null || _a === void 0 ? void 0 : _a.querySelector) === null || _b === void 0 ? void 0 : _b.call(_a, `${MENU_POPOVER}[triggerid="${id}"]`)) !== null;
442
+ closeOtherSubMenusOnSameLevel(target) {
443
+ const otherMenuItemsOnSameLevel = this.menuItemsWithSubMenus.filter(item => item !== target);
444
+ const otherOpenSubMenus = this.getOpenSubMenusOfItems(otherMenuItemsOnSameLevel);
445
+ otherOpenSubMenus.forEach(subMenu => {
446
+ subMenu.hide();
447
+ });
259
448
  }
260
449
  /**
261
- * Determines whether to close the menu based on the clicked target.
262
- *
263
- * @param target - The target element that was clicked.
450
+ * Fires the 'action' event on the target menu item.
451
+ * This method is used to trigger the action associated with a menu item when it is clicked or activated.
452
+ * It checks if the target element matches the `MENUITEM_TAGNAME` and dispatches an 'action' event.
453
+ * @param target - The target menu item that was clicked or activated.
264
454
  */
265
- closeMenu(target) {
266
- const triggerId = target.getAttribute('id');
267
- if (isValidMenuItem(target) &&
268
- !this.hasSubmenuWithTriggerId(triggerId) &&
269
- this === target.closest(MENU_POPOVER) // Ensure close all popover called only once
270
- ) {
271
- this.closeAllMenuPopovers();
272
- if (target.matches(MENUITEM_TAGNAME)) {
273
- target.dispatchEvent(new Event('action', { bubbles: true, composed: true }));
274
- }
455
+ fireMenuItemAction(target) {
456
+ if (target.matches(MENUITEM_TAGNAME)) {
457
+ target.dispatchEvent(new Event('action', { bubbles: true, composed: true }));
275
458
  }
276
459
  }
277
460
  /**
@@ -282,22 +465,20 @@ class MenuPopover extends Popover {
282
465
  */
283
466
  handleMouseClick(event) {
284
467
  const target = event.target;
285
- if (event.isTrusted) {
286
- // skip manually dispatched clicks from listItem
287
- this.closeMenu(target);
288
- }
289
- }
290
- handleItemCreation(event) {
291
- const item = event.target;
292
- if (isValidMenuItem(item)) {
293
- // Parent menu popover should not listen on nested menu items
294
- event.stopImmediatePropagation();
295
- // `destroyed` triggered in the `disconnectedCallback` of the item which executed when the item is removed from the DOM
296
- // because of that the event does not bubble up to menupopover, and we need to capture the `destroyed` event on the item itself
297
- item.addEventListener('destroyed', this.handleItemChangeEvent);
298
- // `disabled` could bubble up, but it is more consistent to handle it the same way as `destroyed`
299
- item.addEventListener('disabled', this.handleItemChangeEvent);
468
+ // stopPropagation to prevent the click from bubbling up to parent elements
469
+ event.stopPropagation();
470
+ // if the target is not a valid menu item or if the event is not trusted (
471
+ // e.g., triggered by keydown originally), do nothing. Pressing space and enter
472
+ // is handled separately in the respective handler.
473
+ if (!isValidMenuItem(target) || !event.isTrusted)
474
+ return;
475
+ // If the target has a submenu, show it and close other submenus on the same level
476
+ if (this.getSubMenuPopoverOfTarget(target)) {
477
+ this.closeOtherSubMenusOnSameLevel(target);
478
+ return;
300
479
  }
480
+ this.closeAllMenuPopovers();
481
+ this.fireMenuItemAction(target);
301
482
  }
302
483
  /**
303
484
  * Resolves the key pressed by the user based on the direction of the layout.
@@ -320,135 +501,6 @@ class MenuPopover extends Popover {
320
501
  return key;
321
502
  }
322
503
  }
323
- /**
324
- * Handles keydown events for keyboard navigation within the menu popover.
325
- * This method allows users to navigate through the menu items using the keyboard.
326
- * It supports Home, End, Arrow Up, Arrow Down, Arrow Left, Arrow Right, and Escape keys.
327
- *
328
- * Also, it handles Enter key to close the menu popover
329
- *
330
- * @param event - The keyboard event that triggered the keydown action.
331
- * @returns - This method does not return anything.
332
- */
333
- handleKeyDown(event) {
334
- var _a, _b;
335
- let isKeyHandled = false;
336
- this.collectMenuItems();
337
- const target = event.target;
338
- const currentIndex = this.getCurrentIndex(target);
339
- if (currentIndex === -1)
340
- return;
341
- this.resetTabIndexes(currentIndex);
342
- const isRtl = window.getComputedStyle(this).direction === 'rtl';
343
- const targetKey = this.resolveDirectionKey(event.key, isRtl);
344
- switch (targetKey) {
345
- case KEYS.HOME: {
346
- // Move focus to the first menu item
347
- this.resetTabIndexAndSetFocus(0, currentIndex);
348
- isKeyHandled = true;
349
- break;
350
- }
351
- case KEYS.END: {
352
- // Move focus to the last menu item
353
- this.resetTabIndexAndSetFocus(this.menuItems.length - 1, currentIndex);
354
- isKeyHandled = true;
355
- break;
356
- }
357
- case KEYS.ARROW_DOWN: {
358
- // Move focus to the next menu item
359
- const newIndex = currentIndex + 1 === this.menuItems.length ? 0 : currentIndex + 1;
360
- this.resetTabIndexAndSetFocus(newIndex, currentIndex);
361
- isKeyHandled = true;
362
- break;
363
- }
364
- case KEYS.ARROW_UP: {
365
- // Move focus to the prev menu item
366
- const newIndex = currentIndex - 1 === -1 ? this.menuItems.length - 1 : currentIndex - 1;
367
- this.resetTabIndexAndSetFocus(newIndex, currentIndex);
368
- isKeyHandled = true;
369
- break;
370
- }
371
- case KEYS.ARROW_RIGHT: {
372
- // If there is a submenu, open it.
373
- const triggerId = (_a = this.menuItems[currentIndex]) === null || _a === void 0 ? void 0 : _a.getAttribute('id');
374
- if (this.hasSubmenuWithTriggerId(triggerId)) {
375
- const submenu = (_b = this.parentElement) === null || _b === void 0 ? void 0 : _b.querySelector(`${MENU_POPOVER}[triggerid="${triggerId}"]`);
376
- if (submenu) {
377
- submenu.showPopover();
378
- isKeyHandled = true;
379
- }
380
- }
381
- break;
382
- }
383
- case KEYS.ARROW_LEFT: {
384
- // If the current popover is a submenu then close this popover.
385
- if (isValidPopover(this.parentElement)) {
386
- this.hidePopover();
387
- this.resetTabIndexAndSetFocus(0, currentIndex);
388
- isKeyHandled = true;
389
- }
390
- break;
391
- }
392
- case KEYS.ESCAPE: {
393
- this.resetTabIndexAndSetFocus(0, currentIndex);
394
- isKeyHandled = true;
395
- break;
396
- }
397
- case KEYS.ENTER: {
398
- this.closeMenu(target);
399
- isKeyHandled = true;
400
- break;
401
- }
402
- case KEYS.SPACE: {
403
- // Prevent page scroll when space is pressed down
404
- isKeyHandled = true;
405
- break;
406
- }
407
- default:
408
- break;
409
- }
410
- // When menu consume any of the pressed key, we need to stop propagation
411
- // to prevent the event from bubbling up and being handled by parent components which might use the same key.
412
- if (isKeyHandled) {
413
- event.stopPropagation();
414
- event.preventDefault();
415
- }
416
- }
417
- /**
418
- * Handles keyup events for keyboard navigation within the menu popover.
419
- *
420
- * Some keys must be handled with keyup event to prevent default action.
421
- *
422
- * Space key closes the menu when the user presses it on a menu item,
423
- * but the same key will trigger a click on the menu opener button.
424
- * The button uses the keyup event so we have to handle it here as well
425
- * to prevent the meu opener action which would re-open the menu.
426
- *
427
- * @param event - The keyboard event that triggered the keydown action.
428
- * @returns - This method does not return anything.
429
- */
430
- handleKeyUp(event) {
431
- let isKeyHandled = false;
432
- const target = event.target;
433
- switch (event.key) {
434
- case KEYS.SPACE: {
435
- // If the target is a menu item, trigger its click event
436
- if (!target.matches(`${MENUITEMRADIO_TAGNAME}, ${MENUITEMCHECKBOX_TAGNAME}`)) {
437
- this.closeMenu(target);
438
- isKeyHandled = true;
439
- }
440
- break;
441
- }
442
- default:
443
- break;
444
- }
445
- // When menu consume any of the pressed key, we need to stop propagation
446
- // to prevent the event from bubbling up and being handled by parent components which might use the same key.
447
- if (isKeyHandled) {
448
- event.stopPropagation();
449
- event.preventDefault();
450
- }
451
- }
452
504
  }
453
505
  MenuPopover.styles = [...Popover.styles, ...styles];
454
506
  __decorate([
@@ -5,5 +5,5 @@ import type MenuPopover from './menupopover.component';
5
5
  * @returns True if the menu item is a valid menu item, false otherwise.
6
6
  */
7
7
  declare const isValidMenuItem: (menuItem: Element | null) => boolean;
8
- declare const isValidPopover: (el: Element | null) => el is MenuPopover;
9
- export { isValidMenuItem, isValidPopover };
8
+ declare const isValidMenuPopover: (el: Element | null) => el is MenuPopover;
9
+ export { isValidMenuItem, isValidMenuPopover };
@@ -12,5 +12,5 @@ const isValidMenuItem = (menuItem) => {
12
12
  const role = (_a = menuItem.getAttribute('role')) === null || _a === void 0 ? void 0 : _a.toLowerCase();
13
13
  return role === ROLE.MENUITEM || role === ROLE.MENUITEMCHECKBOX || role === ROLE.MENUITEMRADIO;
14
14
  };
15
- const isValidPopover = (el) => { var _a; return ((_a = el === null || el === void 0 ? void 0 : el.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === MENUPOPOVER_TAGNAME; };
16
- export { isValidMenuItem, isValidPopover };
15
+ const isValidMenuPopover = (el) => { var _a; return ((_a = el === null || el === void 0 ? void 0 : el.tagName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === MENUPOPOVER_TAGNAME; };
16
+ export { isValidMenuItem, isValidMenuPopover };
@@ -81,7 +81,7 @@ class NavMenuItem extends IconNameMixin(MenuItem) {
81
81
  });
82
82
  this.dispatchEvent(event);
83
83
  };
84
- this.addEventListener('click', this.handleClickEvent);
84
+ this.addEventListener('click', this.handleClickEvent.bind(this));
85
85
  }
86
86
  connectedCallback() {
87
87
  super.connectedCallback();
@@ -50,6 +50,7 @@ declare class Popover extends Popover_base {
50
50
  * - **mouseenter**
51
51
  * - **focusin**
52
52
  * - **manual**
53
+ *
53
54
  * @default click
54
55
  */
55
56
  trigger: PopoverTrigger;
@@ -246,6 +247,13 @@ declare class Popover extends Popover_base {
246
247
  * @default false
247
248
  */
248
249
  disableAriaHasPopup: boolean;
250
+ /**
251
+ * If a tooltip is connected to the same trigger element,
252
+ * this property will keep the connected tooltip closed if this popover is open.
253
+ * This is useful when you want to show a popover with a tooltip
254
+ * but you don't want the tooltip to be shown at the same time.
255
+ */
256
+ keepConnectedTooltipClosed: boolean;
249
257
  arrowElement: HTMLElement | null;
250
258
  triggerElement: HTMLElement | null;
251
259
  /** @internal */
@@ -255,26 +263,38 @@ declare class Popover extends Popover_base {
255
263
  /** @internal */
256
264
  private isHovered;
257
265
  /** @internal */
258
- protected isTriggerClicked: boolean;
259
- /** @internal */
260
266
  private openDelay;
261
267
  /** @internal */
262
268
  protected closeDelay: number;
263
269
  /** @internal */
264
270
  private utils;
265
271
  /** @internal */
272
+ private floatingUICleanupFunction;
273
+ /** @internal */
274
+ protected shouldSupressOpening: boolean;
275
+ /** @internal */
266
276
  backdropElement: HTMLElement | null;
277
+ /** @internal */
278
+ private connectedTooltip;
267
279
  constructor();
280
+ private storeConnectedTooltip;
281
+ private setupTriggerRelatedElement;
282
+ private cleanupTrigger;
268
283
  protected firstUpdated(changedProperties: PropertyValues): Promise<void>;
269
284
  disconnectedCallback(): Promise<void>;
270
285
  /**
271
- * Sets up the trigger event listeners based on the trigger type.
286
+ * Sets up the trigger related event listeners, based on the trigger type.
287
+ * Includes fallback for mouseenter trigger to also handle focusin for non-interactive popovers.
288
+ */
289
+ private setupTriggerListeners;
290
+ /**
291
+ * Removes the trigger related event listeners.
272
292
  */
273
- private setupTriggerListener;
293
+ private removeTriggerListeners;
274
294
  /**
275
- * Removes the trigger event listeners.
295
+ * Removes all event listeners related to the popover.
276
296
  */
277
- private removeEventListeners;
297
+ private removeAllListeners;
278
298
  protected updated(changedProperties: PropertyValues): Promise<void>;
279
299
  /**
280
300
  * Handles the outside click event to close the popover.
@@ -333,11 +353,11 @@ declare class Popover extends Popover_base {
333
353
  /**
334
354
  * Shows the popover.
335
355
  */
336
- showPopover: () => void;
356
+ show: () => void;
337
357
  /**
338
358
  * Hides the popover.
339
359
  */
340
- hidePopover: () => void;
360
+ hide: () => void;
341
361
  /**
342
362
  * Toggles the popover visibility.
343
363
  */
@@ -355,7 +375,7 @@ declare class Popover extends Popover_base {
355
375
  *
356
376
  * @param element - The element to start searching from.
357
377
  */
358
- protected findClosestPopover(element: Element): Popover | null;
378
+ protected findClosestPopover: (element: Element) => Popover | null;
359
379
  render(): import("lit-html").TemplateResult<1>;
360
380
  static styles: Array<CSSResult>;
361
381
  }