@vaadin/menu-bar 25.0.0-alpha2 → 25.0.0-alpha20

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 (38) hide show
  1. package/package.json +15 -16
  2. package/src/styles/vaadin-menu-bar-base-styles.d.ts +8 -0
  3. package/src/styles/vaadin-menu-bar-base-styles.js +56 -0
  4. package/src/styles/vaadin-menu-bar-button-base-styles.d.ts +8 -0
  5. package/src/styles/vaadin-menu-bar-button-base-styles.js +47 -0
  6. package/src/styles/vaadin-menu-bar-item-base-styles.d.ts +8 -0
  7. package/src/styles/vaadin-menu-bar-item-base-styles.js +8 -0
  8. package/src/styles/vaadin-menu-bar-overlay-base-styles.d.ts +8 -0
  9. package/src/styles/vaadin-menu-bar-overlay-base-styles.js +9 -0
  10. package/src/vaadin-menu-bar-button.d.ts +19 -0
  11. package/src/vaadin-menu-bar-button.js +4 -13
  12. package/src/vaadin-menu-bar-item.js +5 -11
  13. package/src/vaadin-menu-bar-list-box.js +5 -18
  14. package/src/vaadin-menu-bar-mixin.d.ts +5 -12
  15. package/src/vaadin-menu-bar-mixin.js +155 -156
  16. package/src/vaadin-menu-bar-overlay.js +7 -4
  17. package/src/vaadin-menu-bar-submenu.d.ts +20 -0
  18. package/src/vaadin-menu-bar-submenu.js +83 -8
  19. package/src/vaadin-menu-bar.d.ts +3 -6
  20. package/src/vaadin-menu-bar.js +11 -27
  21. package/vaadin-menu-bar.js +1 -1
  22. package/web-types.json +4 -26
  23. package/web-types.lit.json +4 -11
  24. package/src/vaadin-menu-bar-submenu-mixin.js +0 -66
  25. package/theme/lumo/vaadin-menu-bar-button-styles.d.ts +0 -1
  26. package/theme/lumo/vaadin-menu-bar-button-styles.js +0 -128
  27. package/theme/lumo/vaadin-menu-bar-button.d.ts +0 -2
  28. package/theme/lumo/vaadin-menu-bar-button.js +0 -2
  29. package/theme/lumo/vaadin-menu-bar-item-styles.d.ts +0 -2
  30. package/theme/lumo/vaadin-menu-bar-item-styles.js +0 -27
  31. package/theme/lumo/vaadin-menu-bar-list-box-styles.d.ts +0 -1
  32. package/theme/lumo/vaadin-menu-bar-list-box-styles.js +0 -5
  33. package/theme/lumo/vaadin-menu-bar-overlay-styles.d.ts +0 -1
  34. package/theme/lumo/vaadin-menu-bar-overlay-styles.js +0 -13
  35. package/theme/lumo/vaadin-menu-bar-styles.d.ts +0 -1
  36. package/theme/lumo/vaadin-menu-bar-styles.js +0 -17
  37. package/theme/lumo/vaadin-menu-bar.d.ts +0 -6
  38. package/theme/lumo/vaadin-menu-bar.js +0 -6
@@ -10,6 +10,8 @@ import { DisabledMixin } from '@vaadin/a11y-base/src/disabled-mixin.js';
10
10
  import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
11
11
  import { isElementFocused, isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js';
12
12
  import { KeyboardDirectionMixin } from '@vaadin/a11y-base/src/keyboard-direction-mixin.js';
13
+ import { microTask } from '@vaadin/component-base/src/async.js';
14
+ import { Debouncer } from '@vaadin/component-base/src/debounce.js';
13
15
  import { I18nMixin } from '@vaadin/component-base/src/i18n-mixin.js';
14
16
  import { ResizeMixin } from '@vaadin/component-base/src/resize-mixin.js';
15
17
  import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
@@ -74,10 +76,10 @@ export const MenuBarMixin = (superClass) =>
74
76
  * @property {string} text - Text to be set as the menu button component's textContent.
75
77
  * @property {string} tooltip - Text to be set as the menu button's tooltip.
76
78
  * Requires a `<vaadin-tooltip slot="tooltip">` element to be added inside the `<vaadin-menu-bar>`.
77
- * @property {union: string | object} component - The component to represent the button content.
79
+ * @property {string | HTMLElement} component - The component to represent the button content.
78
80
  * Either a tagName or an element instance. Defaults to "vaadin-menu-bar-item".
79
81
  * @property {boolean} disabled - If true, the button is disabled and cannot be activated.
80
- * @property {union: string | string[]} theme - Theme(s) to be set as the theme attribute of the button, overriding any theme set on the menu bar.
82
+ * @property {string | string[]} theme - Theme(s) to be set as the theme attribute of the button, overriding any theme set on the menu bar.
81
83
  * @property {SubMenuItem[]} children - Array of submenu items.
82
84
  */
83
85
 
@@ -85,7 +87,7 @@ export const MenuBarMixin = (superClass) =>
85
87
  * @typedef SubMenuItem
86
88
  * @type {object}
87
89
  * @property {string} text - Text to be set as the menu item component's textContent.
88
- * @property {union: string | object} component - The component to represent the item.
90
+ * @property {string | HTMLElement} component - The component to represent the item.
89
91
  * Either a tagName or an element instance. Defaults to "vaadin-menu-bar-item".
90
92
  * @property {boolean} disabled - If true, the item is disabled and cannot be selected.
91
93
  * @property {boolean} checked - If true, the item shows a checkmark next to it.
@@ -134,12 +136,7 @@ export const MenuBarMixin = (superClass) =>
134
136
  * which makes disabled buttons focusable and hoverable, while still
135
137
  * preventing them from being triggered:
136
138
  *
137
- * ```
138
- * // Set before any menu bar is attached to the DOM.
139
- * window.Vaadin.featureFlags.accessibleDisabledButtons = true;
140
- * ```
141
- *
142
- * ```
139
+ * ```js
143
140
  * // Set before any menu bar is attached to the DOM.
144
141
  * window.Vaadin.featureFlags.accessibleDisabledButtons = true;
145
142
  * ```
@@ -152,16 +149,6 @@ export const MenuBarMixin = (superClass) =>
152
149
  value: () => [],
153
150
  },
154
151
 
155
- /**
156
- * A space-delimited list of CSS class names
157
- * to set on each sub-menu overlay element.
158
- *
159
- * @attr {string} overlay-class
160
- */
161
- overlayClass: {
162
- type: String,
163
- },
164
-
165
152
  /**
166
153
  * If true, the submenu will open on hover (mouseover) instead of click.
167
154
  * @attr {boolean} open-on-hover
@@ -189,48 +176,16 @@ export const MenuBarMixin = (superClass) =>
189
176
  type: Boolean,
190
177
  sync: true,
191
178
  },
192
-
193
- /**
194
- * @type {boolean}
195
- * @protected
196
- */
197
- _hasOverflow: {
198
- type: Boolean,
199
- value: false,
200
- sync: true,
201
- },
202
-
203
- /** @protected */
204
- _overflow: {
205
- type: Object,
206
- },
207
-
208
- /** @protected */
209
- _container: {
210
- type: Object,
211
- sync: true,
212
- },
213
179
  };
214
180
  }
215
181
 
216
- static get observers() {
217
- return [
218
- '_themeChanged(_theme, _overflow, _container)',
219
- '__hasOverflowChanged(_hasOverflow, _overflow)',
220
- '__i18nChanged(__effectiveI18n, _overflow)',
221
- '__updateButtons(items, disabled, _overflow, _container)',
222
- '_reverseCollapseChanged(reverseCollapse, _overflow, _container)',
223
- '_tabNavigationChanged(tabNavigation, _overflow, _container)',
224
- ];
225
- }
226
-
227
182
  /**
228
183
  * The object used to localize this component. To change the default
229
184
  * localization, replace this with an object that provides all properties, or
230
185
  * just the individual properties you want to change.
231
186
  *
232
187
  * The object has the following JSON structure and default values:
233
- * ```
188
+ * ```js
234
189
  * {
235
190
  * moreOptions: 'More options'
236
191
  * }
@@ -305,8 +260,15 @@ export const MenuBarMixin = (superClass) =>
305
260
  }
306
261
 
307
262
  /** @private */
308
- get _subMenu() {
309
- return this.shadowRoot.querySelector('vaadin-menu-bar-submenu');
263
+ get _hasOverflow() {
264
+ return this._overflow && !this._overflow.hasAttribute('hidden');
265
+ }
266
+
267
+ /** @private */
268
+ set _hasOverflow(hasOverflow) {
269
+ if (this._overflow) {
270
+ this._overflow.toggleAttribute('hidden', !hasOverflow);
271
+ }
310
272
  }
311
273
 
312
274
  /** @protected */
@@ -315,6 +277,20 @@ export const MenuBarMixin = (superClass) =>
315
277
 
316
278
  this.setAttribute('role', 'menubar');
317
279
 
280
+ this._subMenuController = new SlotController(this, 'submenu', 'vaadin-menu-bar-submenu', {
281
+ initializer: (menu) => {
282
+ menu.setAttribute('is-root', '');
283
+
284
+ menu.addEventListener('item-selected', this.__onItemSelected.bind(this));
285
+ menu.addEventListener('close-all-menus', this.__onEscapeClose.bind(this));
286
+
287
+ const overlay = menu._overlayElement;
288
+ overlay._contentRoot.addEventListener('keydown', this.__boundOnContextMenuKeydown);
289
+
290
+ this._subMenu = menu;
291
+ },
292
+ });
293
+
318
294
  this._overflowController = new SlotController(this, 'overflow', 'vaadin-menu-bar-button', {
319
295
  initializer: (btn) => {
320
296
  btn.setAttribute('hidden', '');
@@ -331,27 +307,47 @@ export const MenuBarMixin = (superClass) =>
331
307
  this._overflow = btn;
332
308
  },
333
309
  });
310
+
311
+ this.addController(this._subMenuController);
334
312
  this.addController(this._overflowController);
335
313
 
336
314
  this.addEventListener('mousedown', () => this._hideTooltip(true));
337
315
  this.addEventListener('mouseleave', () => this._hideTooltip());
338
316
 
339
- this._subMenu.addEventListener('item-selected', this.__onItemSelected.bind(this));
340
- this._subMenu.addEventListener('close-all-menus', this.__onEscapeClose.bind(this));
317
+ this._container = this.shadowRoot.querySelector('[part="container"]');
318
+ }
341
319
 
342
- const overlay = this._subMenu._overlayElement;
343
- overlay.addEventListener('keydown', this.__boundOnContextMenuKeydown);
320
+ /** @protected */
321
+ updated(props) {
322
+ super.updated(props);
344
323
 
345
- const container = this.shadowRoot.querySelector('[part="container"]');
346
- container.addEventListener('click', this.__onButtonClick.bind(this));
347
- container.addEventListener('mouseover', (e) => this._onMouseOver(e));
324
+ if (props.has('items') || props.has('_theme') || props.has('disabled')) {
325
+ this.__renderButtons(this.items);
326
+ }
348
327
 
349
- // Delay setting container to avoid rendering buttons immediately,
350
- // which would also trigger detecting overflow and force re-layout
351
- // See https://github.com/vaadin/web-components/issues/7271
352
- queueMicrotask(() => {
353
- this._container = container;
354
- });
328
+ if (props.has('items') || props.has('_theme') || props.has('reverseCollapse')) {
329
+ this.__scheduleOverflow();
330
+ }
331
+
332
+ if (props.has('items')) {
333
+ this.__updateSubMenu();
334
+ }
335
+
336
+ if (props.has('_theme')) {
337
+ this._themeChanged(this._theme);
338
+ }
339
+
340
+ if (props.has('disabled')) {
341
+ this._overflow.toggleAttribute('disabled', this.disabled);
342
+ }
343
+
344
+ if (props.has('tabNavigation')) {
345
+ this._tabNavigationChanged(this.tabNavigation);
346
+ }
347
+
348
+ if (props.has('__effectiveI18n')) {
349
+ this.__i18nChanged(this.__effectiveI18n);
350
+ }
355
351
  }
356
352
 
357
353
  /**
@@ -380,87 +376,40 @@ export const MenuBarMixin = (superClass) =>
380
376
  * @override
381
377
  */
382
378
  _onResize() {
383
- this.__detectOverflow();
384
- }
385
-
386
- /**
387
- * A callback for the `_theme` property observer.
388
- * It propagates the host theme to the buttons and the sub menu.
389
- *
390
- * @param {string | null} theme
391
- * @private
392
- */
393
- _themeChanged(theme, overflow, container) {
394
- if (overflow && container) {
395
- this.__renderButtons(this.items);
396
- this.__detectOverflow();
397
-
398
- if (theme) {
399
- overflow.setAttribute('theme', theme);
400
- this._subMenu.setAttribute('theme', theme);
401
- } else {
402
- overflow.removeAttribute('theme');
403
- this._subMenu.removeAttribute('theme');
404
- }
405
- }
406
- }
407
-
408
- /**
409
- * A callback for the 'reverseCollapse' property observer.
410
- *
411
- * @param {boolean | null} _reverseCollapse
412
- * @private
413
- */
414
- _reverseCollapseChanged(_reverseCollapse, overflow, container) {
415
- if (overflow && container) {
416
- this.__detectOverflow();
417
- }
379
+ this.__scheduleOverflow();
418
380
  }
419
381
 
420
382
  /** @private */
421
- _tabNavigationChanged(tabNavigation, overflow, container) {
422
- if (overflow && container) {
423
- const target = this.querySelector('[tabindex="0"]');
424
- this._buttons.forEach((btn) => {
425
- if (target) {
426
- this._setTabindex(btn, btn === target);
427
- } else {
428
- this._setTabindex(btn, false);
429
- }
430
- btn.setAttribute('role', tabNavigation ? 'button' : 'menuitem');
431
- });
383
+ _themeChanged(theme) {
384
+ if (theme) {
385
+ this._overflow.setAttribute('theme', theme);
386
+ this._subMenu.setAttribute('theme', theme);
387
+ } else {
388
+ this._overflow.removeAttribute('theme');
389
+ this._subMenu.removeAttribute('theme');
432
390
  }
433
- this.setAttribute('role', tabNavigation ? 'group' : 'menubar');
434
391
  }
435
392
 
436
393
  /** @private */
437
- __hasOverflowChanged(hasOverflow, overflow) {
438
- if (overflow) {
439
- overflow.toggleAttribute('hidden', !hasOverflow);
440
- }
394
+ _tabNavigationChanged(tabNavigation) {
395
+ const target = this.querySelector('[tabindex="0"]');
396
+ this._buttons.forEach((btn) => {
397
+ if (target) {
398
+ this._setTabindex(btn, btn === target);
399
+ } else {
400
+ this._setTabindex(btn, false);
401
+ }
402
+ btn.setAttribute('role', tabNavigation ? 'button' : 'menuitem');
403
+ });
404
+
405
+ this.setAttribute('role', tabNavigation ? 'group' : 'menubar');
441
406
  }
442
407
 
443
408
  /** @private */
444
- __updateButtons(items, disabled, overflow, container) {
445
- if (!overflow || !container) {
446
- return;
447
- }
448
-
449
- if (items !== this._oldItems) {
450
- this._oldItems = items;
451
- this.__renderButtons(items);
452
- this.__detectOverflow();
453
- }
454
-
455
- if (disabled !== this._oldDisabled) {
456
- this._oldDisabled = disabled;
457
- this.__renderButtons(items);
458
- overflow.toggleAttribute('disabled', disabled);
459
- }
460
-
409
+ __updateSubMenu() {
461
410
  const subMenu = this._subMenu;
462
411
  if (subMenu && subMenu.opened) {
463
- const button = subMenu._overlayElement.positionTarget;
412
+ const button = subMenu._positionTarget;
464
413
 
465
414
  // Close sub-menu if the corresponding button is no longer in the DOM,
466
415
  // or if the item on it has been changed to no longer have children.
@@ -471,12 +420,12 @@ export const MenuBarMixin = (superClass) =>
471
420
  }
472
421
 
473
422
  /** @private */
474
- __i18nChanged(effectiveI18n, overflow) {
475
- if (overflow && effectiveI18n && effectiveI18n.moreOptions !== undefined) {
423
+ __i18nChanged(effectiveI18n) {
424
+ if (effectiveI18n && effectiveI18n.moreOptions !== undefined) {
476
425
  if (effectiveI18n.moreOptions) {
477
- overflow.setAttribute('aria-label', effectiveI18n.moreOptions);
426
+ this._overflow.setAttribute('aria-label', effectiveI18n.moreOptions);
478
427
  } else {
479
- overflow.removeAttribute('aria-label');
428
+ this._overflow.removeAttribute('aria-label');
480
429
  }
481
430
  }
482
431
  }
@@ -561,11 +510,14 @@ export const MenuBarMixin = (superClass) =>
561
510
  }
562
511
 
563
512
  /** @private */
564
- __detectOverflow() {
565
- if (!this._container) {
566
- return;
567
- }
513
+ __scheduleOverflow() {
514
+ this._overflowDebouncer = Debouncer.debounce(this._overflowDebouncer, microTask, () => {
515
+ this.__detectOverflow();
516
+ });
517
+ }
568
518
 
519
+ /** @private */
520
+ __detectOverflow() {
569
521
  const overflow = this._overflow;
570
522
  const buttons = this._buttons.filter((btn) => btn !== overflow);
571
523
  const oldOverflowCount = this.__getOverflowCount(overflow);
@@ -707,6 +659,7 @@ export const MenuBarMixin = (superClass) =>
707
659
  _hideTooltip(immediate) {
708
660
  const tooltip = this._tooltipController && this._tooltipController.node;
709
661
  if (tooltip) {
662
+ this._tooltipController.setContext({ item: null });
710
663
  tooltip._stateController.close(immediate);
711
664
  }
712
665
  }
@@ -740,17 +693,18 @@ export const MenuBarMixin = (superClass) =>
740
693
  * and open another one for the newly focused button.
741
694
  *
742
695
  * @param {Element} item
696
+ * @param {FocusOptions=} options
743
697
  * @param {boolean} navigating
744
698
  * @protected
745
699
  * @override
746
700
  */
747
- _focusItem(item, navigating) {
701
+ _focusItem(item, options, navigating) {
748
702
  const wasExpanded = navigating && this.focused === this._expandedButton;
749
703
  if (wasExpanded) {
750
704
  this._close();
751
705
  }
752
706
 
753
- super._focusItem(item, navigating);
707
+ super._focusItem(item, options, navigating);
754
708
 
755
709
  this._buttons.forEach((btn) => {
756
710
  this._setTabindex(btn, btn === item);
@@ -770,6 +724,34 @@ export const MenuBarMixin = (superClass) =>
770
724
  return Array.from(e.composedPath()).find((el) => el.localName === 'vaadin-menu-bar-button');
771
725
  }
772
726
 
727
+ /**
728
+ * Override method inherited from `FocusMixin`
729
+ *
730
+ * @override
731
+ * @protected
732
+ */
733
+ _shouldSetFocus(event) {
734
+ // Ignore events from the submenu
735
+ if (event.composedPath().includes(this._subMenu)) {
736
+ return false;
737
+ }
738
+ return super._shouldSetFocus(event);
739
+ }
740
+
741
+ /**
742
+ * Override method inherited from `FocusMixin`
743
+ *
744
+ * @override
745
+ * @protected
746
+ */
747
+ _shouldRemoveFocus(event) {
748
+ // Ignore events from the submenu
749
+ if (event.composedPath().includes(this._subMenu)) {
750
+ return false;
751
+ }
752
+ return super._shouldRemoveFocus(event);
753
+ }
754
+
773
755
  /**
774
756
  * Override method inherited from `FocusMixin`
775
757
  *
@@ -852,6 +834,16 @@ export const MenuBarMixin = (superClass) =>
852
834
  * @override
853
835
  */
854
836
  _onKeyDown(event) {
837
+ // Ignore events from the submenu
838
+ if (event.composedPath().includes(this._subMenu)) {
839
+ return;
840
+ }
841
+
842
+ this._handleKeyDown(event);
843
+ }
844
+
845
+ /** @private */
846
+ _handleKeyDown(event) {
855
847
  switch (event.key) {
856
848
  case 'ArrowDown':
857
849
  this._onArrowDown(event);
@@ -866,11 +858,16 @@ export const MenuBarMixin = (superClass) =>
866
858
  }
867
859
 
868
860
  /**
869
- * @param {!MouseEvent} e
861
+ * @param {!MouseEvent} event
870
862
  * @protected
871
863
  */
872
- _onMouseOver(e) {
873
- const button = this._getButtonFromEvent(e);
864
+ _onMouseOver(event) {
865
+ // Ignore events from the submenu
866
+ if (event.composedPath().includes(this._subMenu)) {
867
+ return;
868
+ }
869
+
870
+ const button = this._getButtonFromEvent(event);
874
871
  if (!button) {
875
872
  // Hide tooltip on mouseover to disabled button
876
873
  this._hideTooltip();
@@ -902,11 +899,11 @@ export const MenuBarMixin = (superClass) =>
902
899
  if (e.keyCode === 37 || (e.keyCode === 39 && !item._item.children)) {
903
900
  // Prevent ArrowLeft from being handled in context-menu
904
901
  e.stopImmediatePropagation();
905
- this._onKeyDown(e);
902
+ this._handleKeyDown(e);
906
903
  }
907
904
 
908
905
  if (e.key === 'Tab' && this.tabNavigation) {
909
- this._onKeyDown(e);
906
+ this._handleKeyDown(e);
910
907
  }
911
908
  }
912
909
  }
@@ -948,6 +945,7 @@ export const MenuBarMixin = (superClass) =>
948
945
 
949
946
  subMenu.items = items;
950
947
  subMenu.listenOn = button;
948
+ subMenu._positionTarget = button;
951
949
  const overlay = subMenu._overlayElement;
952
950
  overlay.noVerticalOverlap = true;
953
951
 
@@ -957,7 +955,6 @@ export const MenuBarMixin = (superClass) =>
957
955
  this._setExpanded(button, true);
958
956
 
959
957
  this.style.pointerEvents = 'auto';
960
- overlay.positionTarget = button;
961
958
 
962
959
  button.dispatchEvent(
963
960
  new CustomEvent('opensubmenu', {
@@ -975,7 +972,8 @@ export const MenuBarMixin = (superClass) =>
975
972
  }
976
973
 
977
974
  if (options.keepFocus) {
978
- this._focusItem(this._expandedButton, false);
975
+ const focusOptions = { focusVisible: isKeyboardActive() };
976
+ this._focusItem(this._expandedButton, focusOptions, false);
979
977
  }
980
978
 
981
979
  // Do not focus item when open not from keyboard
@@ -989,13 +987,13 @@ export const MenuBarMixin = (superClass) =>
989
987
 
990
988
  /** @private */
991
989
  _focusFirstItem() {
992
- const list = this._subMenu._overlayElement.firstElementChild;
990
+ const list = this._subMenu._overlayElement._contentRoot.firstElementChild;
993
991
  list.focus();
994
992
  }
995
993
 
996
994
  /** @private */
997
995
  _focusLastItem() {
998
- const list = this._subMenu._overlayElement.firstElementChild;
996
+ const list = this._subMenu._overlayElement._contentRoot.firstElementChild;
999
997
  const item = list.items[list.items.length - 1];
1000
998
  if (item) {
1001
999
  item.focus();
@@ -1019,7 +1017,8 @@ export const MenuBarMixin = (superClass) =>
1019
1017
  if (button && button.hasAttribute('expanded')) {
1020
1018
  this._setExpanded(button, false);
1021
1019
  if (restoreFocus) {
1022
- this._focusItem(button, false);
1020
+ const focusOptions = { focusVisible: isKeyboardActive() };
1021
+ this._focusItem(button, focusOptions, false);
1023
1022
  }
1024
1023
  this._expandedButton = null;
1025
1024
  }
@@ -8,10 +8,10 @@ import { defineCustomElement } from '@vaadin/component-base/src/define.js';
8
8
  import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
9
9
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
10
10
  import { MenuOverlayMixin } from '@vaadin/context-menu/src/vaadin-menu-overlay-mixin.js';
11
- import { styles } from '@vaadin/context-menu/src/vaadin-menu-overlay-styles.js';
12
11
  import { OverlayMixin } from '@vaadin/overlay/src/vaadin-overlay-mixin.js';
13
- import { overlayStyles } from '@vaadin/overlay/src/vaadin-overlay-styles.js';
12
+ import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
14
13
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
14
+ import { menuBarOverlayStyles } from './styles/vaadin-menu-bar-overlay-base-styles.js';
15
15
 
16
16
  /**
17
17
  * An element used internally by `<vaadin-menu-bar>`. Not intended to be used separately.
@@ -24,13 +24,15 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
24
24
  * @mixes ThemableMixin
25
25
  * @protected
26
26
  */
27
- export class MenuBarOverlay extends MenuOverlayMixin(OverlayMixin(DirMixin(ThemableMixin(PolylitMixin(LitElement))))) {
27
+ export class MenuBarOverlay extends MenuOverlayMixin(
28
+ OverlayMixin(DirMixin(ThemableMixin(PolylitMixin(LumoInjectionMixin(LitElement))))),
29
+ ) {
28
30
  static get is() {
29
31
  return 'vaadin-menu-bar-overlay';
30
32
  }
31
33
 
32
34
  static get styles() {
33
- return [overlayStyles, styles];
35
+ return menuBarOverlayStyles;
34
36
  }
35
37
 
36
38
  /** @protected */
@@ -40,6 +42,7 @@ export class MenuBarOverlay extends MenuOverlayMixin(OverlayMixin(DirMixin(Thema
40
42
  <div part="overlay" id="overlay" tabindex="0">
41
43
  <div part="content" id="content">
42
44
  <slot></slot>
45
+ <slot name="submenu"></slot>
43
46
  </div>
44
47
  </div>
45
48
  `;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2019 - 2025 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { ContextMenuMixin } from '@vaadin/context-menu/src/vaadin-context-menu-mixin.js';
7
+ import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
8
+
9
+ /**
10
+ * An element used internally by `<vaadin-menu-bar>`. Not intended to be used separately.
11
+ */
12
+ declare class MenuBarSubmenu extends ContextMenuMixin(ThemePropertyMixin(HTMLElement)) {}
13
+
14
+ declare global {
15
+ interface HTMLElementTagNameMap {
16
+ 'vaadin-menu-bar-submenu': MenuBarSubmenu;
17
+ }
18
+ }
19
+
20
+ export { MenuBarSubmenu };