@vaadin/menu-bar 25.3.0-dev.3a3c2d7d2a → 25.3.0

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.
@@ -303,7 +303,7 @@
303
303
  "declarations": [
304
304
  {
305
305
  "kind": "class",
306
- "description": "`<vaadin-menu-bar>` is a Web Component providing a set of horizontally stacked buttons offering\nthe user quick access to a consistent set of commands. Each button can toggle a submenu with\nsupport for additional levels of nested menus.\n\nTo create the menu bar, first add the component to the page:\n\n```html\n<vaadin-menu-bar></vaadin-menu-bar>\n```\n\nAnd then use [`items`](#/elements/vaadin-menu-bar#property-items) property to initialize the structure:\n\n```js\ndocument.querySelector('vaadin-menu-bar').items = [{text: 'File'}, {text: 'Edit'}];\n```\n\n### Styling\n\nThe following shadow DOM parts are exposed for styling:\n\nPart name | Description\n------------------|----------------\n`container` | The container wrapping menu bar buttons.\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n--------------------|----------------------------------\n`disabled` | Set when the menu bar is disabled\n`has-single-button` | Set when there is only one button visible\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Internal components\n\nIn addition to `<vaadin-menu-bar>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-menu-bar-button>` - has the same API as [`<vaadin-button>`](#/elements/vaadin-button).\n- `<vaadin-menu-bar-item>` - has the same API as [`<vaadin-item>`](#/elements/vaadin-item).\n- `<vaadin-menu-bar-list-box>` - has the same API as [`<vaadin-list-box>`](#/elements/vaadin-list-box).\n- `<vaadin-menu-bar-submenu>` - has the same API as [`<vaadin-context-menu>`](#/elements/vaadin-context-menu).\n\nThe `<vaadin-menu-bar-item>` sub-menu elements have the following additional state attributes\non top of the built-in `<vaadin-item>` state attributes:\n\nAttribute | Description\n---------- |-------------\n`expanded` | Expanded parent item.",
306
+ "description": "`<vaadin-menu-bar>` is a Web Component providing a set of horizontally stacked buttons offering\nthe user quick access to a consistent set of commands. Each button can toggle a submenu with\nsupport for additional levels of nested menus.\n\nTo create the menu bar, first add the component to the page:\n\n```html\n<vaadin-menu-bar></vaadin-menu-bar>\n```\n\nAnd then use [`items`](#/elements/vaadin-menu-bar#property-items) property to initialize the structure:\n\n```js\ndocument.querySelector('vaadin-menu-bar').items = [{text: 'File'}, {text: 'Edit'}];\n```\n\n### Styling\n\nThe following shadow DOM parts are exposed for styling:\n\nPart name | Description\n------------------|----------------\n`container` | The container wrapping menu bar buttons.\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n--------------------|----------------------------------\n`disabled` | Set when the menu bar is disabled\n`has-single-button` | Set when there is only one button visible\n\nThe following custom CSS properties are available for styling:\n\nCustom CSS property |\n:---------------------------|\n| `--vaadin-menu-bar-gap` |\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Internal components\n\nIn addition to `<vaadin-menu-bar>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-menu-bar-button>` - has the same API as [`<vaadin-button>`](#/elements/vaadin-button).\n- `<vaadin-menu-bar-item>` - has the same API as [`<vaadin-item>`](#/elements/vaadin-item).\n- `<vaadin-menu-bar-list-box>` - has the same API as [`<vaadin-list-box>`](#/elements/vaadin-list-box).\n- `<vaadin-menu-bar-submenu>` - has the same API as [`<vaadin-context-menu>`](#/elements/vaadin-context-menu).\n\nThe `<vaadin-menu-bar-item>` sub-menu elements have the following additional state attributes\non top of the built-in `<vaadin-item>` state attributes:\n\nAttribute | Description\n---------- |-------------\n`expanded` | Expanded parent item.",
307
307
  "name": "MenuBar",
308
308
  "members": [
309
309
  {
@@ -413,34 +413,6 @@
413
413
  }
414
414
  }
415
415
  ],
416
- "mixins": [
417
- {
418
- "name": "MenuBarMixin",
419
- "module": "src/vaadin-menu-bar-mixin.js"
420
- },
421
- {
422
- "name": "ElementMixin",
423
- "package": "@vaadin/component-base/src/element-mixin.js"
424
- },
425
- {
426
- "name": "ThemableMixin",
427
- "package": "@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js"
428
- },
429
- {
430
- "name": "PolylitMixin",
431
- "package": "@vaadin/component-base/src/polylit-mixin.js"
432
- },
433
- {
434
- "name": "LumoInjectionMixin",
435
- "package": "@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js"
436
- }
437
- ],
438
- "superclass": {
439
- "name": "LitElement",
440
- "package": "lit"
441
- },
442
- "tagName": "vaadin-menu-bar",
443
- "customElement": true,
444
416
  "attributes": [
445
417
  {
446
418
  "name": "disabled",
@@ -501,8 +473,43 @@
501
473
  "name": "MenuBarMixin",
502
474
  "module": "src/vaadin-menu-bar-mixin.js"
503
475
  }
476
+ },
477
+ {
478
+ "type": {
479
+ "text": "string"
480
+ },
481
+ "description": "The theme variants to apply to the component.",
482
+ "name": "theme"
504
483
  }
505
- ]
484
+ ],
485
+ "mixins": [
486
+ {
487
+ "name": "MenuBarMixin",
488
+ "module": "src/vaadin-menu-bar-mixin.js"
489
+ },
490
+ {
491
+ "name": "ElementMixin",
492
+ "package": "@vaadin/component-base/src/element-mixin.js"
493
+ },
494
+ {
495
+ "name": "ThemableMixin",
496
+ "package": "@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js"
497
+ },
498
+ {
499
+ "name": "PolylitMixin",
500
+ "package": "@vaadin/component-base/src/polylit-mixin.js"
501
+ },
502
+ {
503
+ "name": "LumoInjectionMixin",
504
+ "package": "@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js"
505
+ }
506
+ ],
507
+ "superclass": {
508
+ "name": "LitElement",
509
+ "package": "lit"
510
+ },
511
+ "tagName": "vaadin-menu-bar",
512
+ "customElement": true
506
513
  }
507
514
  ],
508
515
  "exports": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/menu-bar",
3
- "version": "25.3.0-dev.3a3c2d7d2a",
3
+ "version": "25.3.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -35,23 +35,23 @@
35
35
  ],
36
36
  "dependencies": {
37
37
  "@open-wc/dedupe-mixin": "^1.3.0",
38
- "@vaadin/a11y-base": "25.3.0-dev.3a3c2d7d2a",
39
- "@vaadin/button": "25.3.0-dev.3a3c2d7d2a",
40
- "@vaadin/component-base": "25.3.0-dev.3a3c2d7d2a",
41
- "@vaadin/context-menu": "25.3.0-dev.3a3c2d7d2a",
42
- "@vaadin/item": "25.3.0-dev.3a3c2d7d2a",
43
- "@vaadin/list-box": "25.3.0-dev.3a3c2d7d2a",
44
- "@vaadin/overlay": "25.3.0-dev.3a3c2d7d2a",
45
- "@vaadin/vaadin-themable-mixin": "25.3.0-dev.3a3c2d7d2a",
38
+ "@vaadin/a11y-base": "~25.3.0",
39
+ "@vaadin/button": "~25.3.0",
40
+ "@vaadin/component-base": "~25.3.0",
41
+ "@vaadin/context-menu": "~25.3.0",
42
+ "@vaadin/item": "~25.3.0",
43
+ "@vaadin/list-box": "~25.3.0",
44
+ "@vaadin/overlay": "~25.3.0",
45
+ "@vaadin/vaadin-themable-mixin": "~25.3.0",
46
46
  "lit": "^3.0.0"
47
47
  },
48
48
  "devDependencies": {
49
- "@vaadin/aura": "25.3.0-dev.3a3c2d7d2a",
50
- "@vaadin/chai-plugins": "25.3.0-dev.3a3c2d7d2a",
51
- "@vaadin/icon": "25.3.0-dev.3a3c2d7d2a",
52
- "@vaadin/test-runner-commands": "25.3.0-dev.3a3c2d7d2a",
49
+ "@vaadin/aura": "~25.3.0",
50
+ "@vaadin/chai-plugins": "~25.3.0",
51
+ "@vaadin/icon": "~25.3.0",
52
+ "@vaadin/test-runner-commands": "~25.3.0",
53
53
  "@vaadin/testing-helpers": "^2.0.0",
54
- "@vaadin/vaadin-lumo-styles": "25.3.0-dev.3a3c2d7d2a",
54
+ "@vaadin/vaadin-lumo-styles": "~25.3.0",
55
55
  "sinon": "^22.0.0"
56
56
  },
57
57
  "customElements": "custom-elements.json",
@@ -59,5 +59,5 @@
59
59
  "web-types.json",
60
60
  "web-types.lit.json"
61
61
  ],
62
- "gitHead": "ac506ca7800c23e05da55863c56bcedf12812d37"
62
+ "gitHead": "4133747243c03bf544f6e82cc2ec9f295aaccd65"
63
63
  }
@@ -15,6 +15,7 @@ import { menuBarItemStyles } from './styles/vaadin-menu-bar-item-base-styles.js'
15
15
  /**
16
16
  * An element used internally by `<vaadin-menu-bar>`. Not intended to be used separately.
17
17
  *
18
+ * @attr {string} theme - The theme variants to apply to the component.
18
19
  * @customElement vaadin-menu-bar-item
19
20
  * @extends HTMLElement
20
21
  * @protected
@@ -15,6 +15,7 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
15
15
  /**
16
16
  * An element used internally by `<vaadin-menu-bar>`. Not intended to be used separately.
17
17
  *
18
+ * @attr {string} theme - The theme variants to apply to the component.
18
19
  * @customElement vaadin-menu-bar-list-box
19
20
  * @extends HTMLElement
20
21
  * @protected
@@ -12,6 +12,7 @@ import { isElementFocused, isElementHidden, isKeyboardActive } from '@vaadin/a11
12
12
  import { KeyboardDirectionMixin } from '@vaadin/a11y-base/src/keyboard-direction-mixin.js';
13
13
  import { microTask } from '@vaadin/component-base/src/async.js';
14
14
  import { Debouncer } from '@vaadin/component-base/src/debounce.js';
15
+ import { setOrRemoveAttribute } from '@vaadin/component-base/src/dom-utils.js';
15
16
  import { I18nMixin } from '@vaadin/component-base/src/i18n-mixin.js';
16
17
  import { ResizeMixin } from '@vaadin/component-base/src/resize-mixin.js';
17
18
  import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
@@ -360,6 +361,10 @@ export const MenuBarMixin = (superClass) =>
360
361
  this._themeChanged(this._theme);
361
362
  }
362
363
 
364
+ if (props.has('dir')) {
365
+ setOrRemoveAttribute(this._subMenu, 'dir', this.dir);
366
+ }
367
+
363
368
  if (props.has('disabled')) {
364
369
  this._overflow.toggleAttribute('disabled', this.disabled);
365
370
  }
@@ -404,13 +409,8 @@ export const MenuBarMixin = (superClass) =>
404
409
 
405
410
  /** @private */
406
411
  _themeChanged(theme) {
407
- if (theme) {
408
- this._overflow.setAttribute('theme', theme);
409
- this._subMenu.setAttribute('theme', theme);
410
- } else {
411
- this._overflow.removeAttribute('theme');
412
- this._subMenu.removeAttribute('theme');
413
- }
412
+ setOrRemoveAttribute(this._overflow, 'theme', theme);
413
+ setOrRemoveAttribute(this._subMenu, 'theme', theme);
414
414
  }
415
415
 
416
416
  /** @private */
@@ -445,18 +445,13 @@ export const MenuBarMixin = (superClass) =>
445
445
  /** @private */
446
446
  __i18nChanged(effectiveI18n) {
447
447
  if (effectiveI18n?.moreOptions !== undefined) {
448
- if (effectiveI18n.moreOptions) {
449
- this._overflow.setAttribute('aria-label', effectiveI18n.moreOptions);
450
- } else {
451
- this._overflow.removeAttribute('aria-label');
452
- }
448
+ setOrRemoveAttribute(this._overflow, 'aria-label', effectiveI18n.moreOptions);
453
449
  }
454
450
  }
455
451
 
456
452
  /** @private */
457
453
  __getOverflowCount(overflow) {
458
- // We can't use optional chaining due to webpack 4
459
- return (overflow.item && overflow.item.children && overflow.item.children.length) || 0;
454
+ return overflow.item?.children?.length ?? 0;
460
455
  }
461
456
 
462
457
  /** @private */
@@ -467,12 +462,11 @@ export const MenuBarMixin = (superClass) =>
467
462
  button.style.width = '';
468
463
 
469
464
  // Teleport item component back from "overflow" sub-menu
470
- const item = button.item && button.item.component;
465
+ const item = button.item?.component;
471
466
  if (item instanceof HTMLElement && item.getAttribute('role') === 'menuitem') {
472
467
  this.__restoreItem(button, item);
473
468
  }
474
469
  });
475
- this.__updateOverflow([]);
476
470
  }
477
471
 
478
472
  /** @private */
@@ -506,17 +500,17 @@ export const MenuBarMixin = (superClass) =>
506
500
 
507
501
  const isRTL = this.__isRTL;
508
502
  const containerLeft = container.offsetLeft;
503
+ const containerWidth = container.offsetWidth;
509
504
 
510
505
  const remaining = [...buttons];
511
506
  while (remaining.length) {
512
- const lastButton = remaining[remaining.length - 1];
513
- const btnLeft = lastButton.offsetLeft - containerLeft;
514
-
515
- // If this button isn't overflowing, then the rest aren't either
516
- if (
517
- (!isRTL && btnLeft + lastButton.offsetWidth < container.offsetWidth - overflow.offsetWidth) ||
518
- (isRTL && btnLeft >= overflow.offsetWidth)
519
- ) {
507
+ // The overflow button follows the last remaining one, so its far edge is what has
508
+ // to fit. Auto margins move the whole row but cannot push that edge past the end.
509
+ const overflowEnd = isRTL
510
+ ? containerWidth - (overflow.offsetLeft - containerLeft)
511
+ : overflow.offsetLeft + overflow.offsetWidth - containerLeft;
512
+
513
+ if (overflowEnd <= containerWidth) {
520
514
  break;
521
515
  }
522
516
 
@@ -550,6 +544,7 @@ export const MenuBarMixin = (superClass) =>
550
544
 
551
545
  // Reset all buttons in the menu bar and the overflow button
552
546
  this.__restoreButtons(buttons);
547
+ this.__updateOverflow([]);
553
548
 
554
549
  // Hide any overflowing buttons and put them in the 'overflow' button
555
550
  this.__setOverflowItems(buttons, overflow);
@@ -562,7 +557,11 @@ export const MenuBarMixin = (superClass) =>
562
557
  const isSingleButton = newOverflowCount === buttons.length || (newOverflowCount === 0 && buttons.length === 1);
563
558
  this.toggleAttribute('has-single-button', isSingleButton);
564
559
 
565
- // Collect visible buttons to detect if tabindex should be updated
560
+ this.__updateVisibleButtons(buttons);
561
+ }
562
+
563
+ /** @private */
564
+ __updateVisibleButtons(buttons) {
566
565
  const visibleButtons = buttons.filter((btn) => btn.style.visibility !== 'hidden');
567
566
 
568
567
  if (!visibleButtons.length) {
@@ -574,8 +573,7 @@ export const MenuBarMixin = (superClass) =>
574
573
  this._setTabindex(visibleButtons[visibleButtons.length - 1], true);
575
574
  }
576
575
 
577
- // Apply first/last visible attributes to the visible buttons
578
- visibleButtons.forEach((btn, index, visibleButtons) => {
576
+ visibleButtons.forEach((btn, index) => {
579
577
  btn.toggleAttribute('first-visible', index === 0);
580
578
  btn.toggleAttribute('last-visible', !this._hasOverflow && index === visibleButtons.length - 1);
581
579
  });
@@ -623,9 +621,7 @@ export const MenuBarMixin = (superClass) =>
623
621
  const hasChildren = Boolean(item?.children);
624
622
 
625
623
  if (itemCopy.component) {
626
- const component = this.__getComponent(itemCopy);
627
- itemCopy.component = component;
628
- component.item = itemCopy;
624
+ itemCopy.component = this.__getComponent(itemCopy);
629
625
  }
630
626
 
631
627
  return html`
@@ -653,7 +649,7 @@ export const MenuBarMixin = (superClass) =>
653
649
  const button = event.target;
654
650
  // Propagate click event from button to the item component if it was outside
655
651
  // it e.g. by calling `click()` on the button (used by the Flow counterpart).
656
- if (button.item && button.item.component && !event.composedPath().includes(button.item.component)) {
652
+ if (button.item?.component && !event.composedPath().includes(button.item.component)) {
657
653
  event.stopPropagation();
658
654
  button.item.component.click();
659
655
  }
@@ -700,7 +696,7 @@ export const MenuBarMixin = (superClass) =>
700
696
 
701
697
  this._tooltipController.setTarget(button);
702
698
 
703
- if (wasExpanded && button.item && button.item.children) {
699
+ if (wasExpanded && button.item?.children) {
704
700
  this.__openSubMenu(button, true, { keepFocus: true });
705
701
  } else if (!this._subMenu.opened) {
706
702
  this._tooltipController.open({ trigger: 'focus' });
@@ -896,12 +892,16 @@ export const MenuBarMixin = (superClass) =>
896
892
  const item = Array.from(e.composedPath()).find((el) => el._item);
897
893
  if (item) {
898
894
  const list = item.parentNode;
899
- if (e.keyCode === 38 && item === list.items[0]) {
895
+ if (e.key === 'ArrowUp' && item === list.items[0]) {
900
896
  this._close(true);
901
897
  }
902
- // ArrowLeft, or ArrowRight on non-parent submenu item,
903
- if (e.keyCode === 37 || (e.keyCode === 39 && !item._item.children)) {
904
- // Prevent ArrowLeft from being handled in context-menu
898
+
899
+ // Switch menu-bar button or open sub-menu on item arrow key.
900
+ const prevKey = this.__isRTL ? 'ArrowRight' : 'ArrowLeft';
901
+ const nextKey = this.__isRTL ? 'ArrowLeft' : 'ArrowRight';
902
+
903
+ if (e.key === prevKey || (e.key === nextKey && !item._item.children)) {
904
+ // Prevent the key from being handled in context-menu
905
905
  e.stopImmediatePropagation();
906
906
  this._handleKeyDown(e);
907
907
  }
@@ -991,13 +991,12 @@ export const MenuBarMixin = (superClass) =>
991
991
 
992
992
  /** @private */
993
993
  _focusFirstItem() {
994
- const list = this._subMenu._overlayElement._contentRoot.firstElementChild;
995
- list.focus();
994
+ this._subMenu._menuListBox.focus();
996
995
  }
997
996
 
998
997
  /** @private */
999
998
  _focusLastItem() {
1000
- const list = this._subMenu._overlayElement._contentRoot.firstElementChild;
999
+ const list = this._subMenu._menuListBox;
1001
1000
  const item = list.items[list.items.length - 1];
1002
1001
  if (item) {
1003
1002
  item.focus();
@@ -16,11 +16,12 @@ import { menuBarOverlayStyles } from './styles/vaadin-menu-bar-overlay-base-styl
16
16
  /**
17
17
  * An element used internally by `<vaadin-menu-bar>`. Not intended to be used separately.
18
18
  *
19
+ * @attr {string} theme - The theme variants to apply to the component.
19
20
  * @customElement vaadin-menu-bar-overlay
20
21
  * @extends HTMLElement
21
22
  * @protected
22
23
  */
23
- export class MenuBarOverlay extends MenuOverlayMixin(
24
+ class MenuBarOverlay extends MenuOverlayMixin(
24
25
  OverlayMixin(DirMixin(ThemableMixin(PolylitMixin(LumoInjectionMixin(LitElement))))),
25
26
  ) {
26
27
  static get is() {
@@ -35,6 +36,25 @@ export class MenuBarOverlay extends MenuOverlayMixin(
35
36
  return { ...super.lumoInjector, includeBaseStyles: true };
36
37
  }
37
38
 
39
+ /**
40
+ * Override method from `MenuOverlayMixin` to prevent closing the menu on
41
+ * a click on the menu-bar button that opened it: the button is the
42
+ * `listenOn` target of the root sub-menu, and the menu-bar click handler
43
+ * closes the menu on that click.
44
+ *
45
+ * @param {Event} event
46
+ * @return {boolean}
47
+ * @protected
48
+ * @override
49
+ */
50
+ _shouldCloseOnOutsideClick(event) {
51
+ if (event.composedPath().includes(this.owner.listenOn)) {
52
+ return false;
53
+ }
54
+
55
+ return super._shouldCloseOnOutsideClick(event);
56
+ }
57
+
38
58
  /** @protected */
39
59
  render() {
40
60
  return html`
@@ -50,3 +70,5 @@ export class MenuBarOverlay extends MenuOverlayMixin(
50
70
  }
51
71
 
52
72
  defineCustomElement(MenuBarOverlay);
73
+
74
+ export { MenuBarOverlay };
@@ -3,13 +3,14 @@
3
3
  * Copyright (c) 2019 - 2026 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
+ import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
6
7
  import { ContextMenuMixin } from '@vaadin/context-menu/src/vaadin-context-menu-mixin.js';
7
8
  import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
8
9
 
9
10
  /**
10
11
  * An element used internally by `<vaadin-menu-bar>`. Not intended to be used separately.
11
12
  */
12
- declare class MenuBarSubmenu extends ContextMenuMixin(ThemePropertyMixin(HTMLElement)) {}
13
+ declare class MenuBarSubmenu extends ContextMenuMixin(DirMixin(ThemePropertyMixin(HTMLElement))) {}
13
14
 
14
15
  declare global {
15
16
  interface HTMLElementTagNameMap {
@@ -9,6 +9,7 @@ import './vaadin-menu-bar-overlay.js';
9
9
  import { css, html, LitElement } from 'lit';
10
10
  import { ifDefined } from 'lit/directives/if-defined.js';
11
11
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
12
+ import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
12
13
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
13
14
  import { ContextMenuMixin } from '@vaadin/context-menu/src/vaadin-context-menu-mixin.js';
14
15
  import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
@@ -16,11 +17,12 @@ import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-p
16
17
  /**
17
18
  * An element used internally by `<vaadin-menu-bar>`. Not intended to be used separately.
18
19
  *
20
+ * @attr {string} theme - The theme variants to apply to the component.
19
21
  * @customElement vaadin-menu-bar-submenu
20
22
  * @extends HTMLElement
21
23
  * @protected
22
24
  */
23
- class MenuBarSubmenu extends ContextMenuMixin(ThemePropertyMixin(PolylitMixin(LitElement))) {
25
+ class MenuBarSubmenu extends ContextMenuMixin(DirMixin(ThemePropertyMixin(PolylitMixin(LitElement)))) {
24
26
  static get is() {
25
27
  return 'vaadin-menu-bar-submenu';
26
28
  }
@@ -121,27 +123,10 @@ class MenuBarSubmenu extends ContextMenuMixin(ThemePropertyMixin(PolylitMixin(Li
121
123
  super.close();
122
124
 
123
125
  // Only handle 1st level submenu
124
- if (this.hasAttribute('is-root')) {
126
+ if (this.isRoot) {
125
127
  this.parentElement._close();
126
128
  }
127
129
  }
128
-
129
- /**
130
- * Override method from `ContextMenuMixin` to prevent closing
131
- * sub-menu on the same click event that was used to open it.
132
- *
133
- * @param {Event} event
134
- * @return {boolean}
135
- * @protected
136
- * @override
137
- */
138
- _shouldCloseOnOutsideClick(event) {
139
- if (this.hasAttribute('is-root') && event.composedPath().includes(this.listenOn)) {
140
- return false;
141
- }
142
-
143
- return super._shouldCloseOnOutsideClick(event);
144
- }
145
130
  }
146
131
 
147
132
  defineCustomElement(MenuBarSubmenu);
@@ -54,6 +54,12 @@ export interface MenuBarEventMap<TItem extends MenuBarItem = MenuBarItem>
54
54
  * `disabled` | Set when the menu bar is disabled
55
55
  * `has-single-button` | Set when there is only one button visible
56
56
  *
57
+ * The following custom CSS properties are available for styling:
58
+ *
59
+ * Custom CSS property |
60
+ * :---------------------------|
61
+ * | `--vaadin-menu-bar-gap` |
62
+ *
57
63
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
58
64
  *
59
65
  * ### Internal components
@@ -46,6 +46,12 @@ import { MenuBarMixin } from './vaadin-menu-bar-mixin.js';
46
46
  * `disabled` | Set when the menu bar is disabled
47
47
  * `has-single-button` | Set when there is only one button visible
48
48
  *
49
+ * The following custom CSS properties are available for styling:
50
+ *
51
+ * Custom CSS property |
52
+ * :---------------------------|
53
+ * | `--vaadin-menu-bar-gap` |
54
+ *
49
55
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
50
56
  *
51
57
  * ### Internal components
@@ -67,6 +73,7 @@ import { MenuBarMixin } from './vaadin-menu-bar-mixin.js';
67
73
  *
68
74
  * @fires {CustomEvent<boolean>} item-selected - Fired when a submenu item or menu bar button without children is clicked.
69
75
  *
76
+ * @attr {string} theme - The theme variants to apply to the component.
70
77
  * @customElement vaadin-menu-bar
71
78
  * @extends HTMLElement
72
79
  */
package/web-types.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/menu-bar",
4
- "version": "25.3.0-dev.3a3c2d7d2a",
4
+ "version": "25.3.0",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
8
8
  "elements": [
9
9
  {
10
10
  "name": "vaadin-menu-bar",
11
- "description": "`<vaadin-menu-bar>` is a Web Component providing a set of horizontally stacked buttons offering\nthe user quick access to a consistent set of commands. Each button can toggle a submenu with\nsupport for additional levels of nested menus.\n\nTo create the menu bar, first add the component to the page:\n\n```html\n<vaadin-menu-bar></vaadin-menu-bar>\n```\n\nAnd then use [`items`](https://cdn.vaadin.com/vaadin-web-components/25.3.0-dev.3a3c2d7d2a/#/elements/vaadin-menu-bar#property-items) property to initialize the structure:\n\n```js\ndocument.querySelector('vaadin-menu-bar').items = [{text: 'File'}, {text: 'Edit'}];\n```\n\n### Styling\n\nThe following shadow DOM parts are exposed for styling:\n\nPart name | Description\n------------------|----------------\n`container` | The container wrapping menu bar buttons.\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n--------------------|----------------------------------\n`disabled` | Set when the menu bar is disabled\n`has-single-button` | Set when there is only one button visible\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Internal components\n\nIn addition to `<vaadin-menu-bar>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-menu-bar-button>` - has the same API as [`<vaadin-button>`](https://cdn.vaadin.com/vaadin-web-components/25.3.0-dev.3a3c2d7d2a/#/elements/vaadin-button).\n- `<vaadin-menu-bar-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.3.0-dev.3a3c2d7d2a/#/elements/vaadin-item).\n- `<vaadin-menu-bar-list-box>` - has the same API as [`<vaadin-list-box>`](https://cdn.vaadin.com/vaadin-web-components/25.3.0-dev.3a3c2d7d2a/#/elements/vaadin-list-box).\n- `<vaadin-menu-bar-submenu>` - has the same API as [`<vaadin-context-menu>`](https://cdn.vaadin.com/vaadin-web-components/25.3.0-dev.3a3c2d7d2a/#/elements/vaadin-context-menu).\n\nThe `<vaadin-menu-bar-item>` sub-menu elements have the following additional state attributes\non top of the built-in `<vaadin-item>` state attributes:\n\nAttribute | Description\n---------- |-------------\n`expanded` | Expanded parent item.",
11
+ "description": "`<vaadin-menu-bar>` is a Web Component providing a set of horizontally stacked buttons offering\nthe user quick access to a consistent set of commands. Each button can toggle a submenu with\nsupport for additional levels of nested menus.\n\nTo create the menu bar, first add the component to the page:\n\n```html\n<vaadin-menu-bar></vaadin-menu-bar>\n```\n\nAnd then use [`items`](https://cdn.vaadin.com/vaadin-web-components/25.3.0/#/elements/vaadin-menu-bar#property-items) property to initialize the structure:\n\n```js\ndocument.querySelector('vaadin-menu-bar').items = [{text: 'File'}, {text: 'Edit'}];\n```\n\n### Styling\n\nThe following shadow DOM parts are exposed for styling:\n\nPart name | Description\n------------------|----------------\n`container` | The container wrapping menu bar buttons.\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n--------------------|----------------------------------\n`disabled` | Set when the menu bar is disabled\n`has-single-button` | Set when there is only one button visible\n\nThe following custom CSS properties are available for styling:\n\nCustom CSS property |\n:---------------------------|\n| `--vaadin-menu-bar-gap` |\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Internal components\n\nIn addition to `<vaadin-menu-bar>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-menu-bar-button>` - has the same API as [`<vaadin-button>`](https://cdn.vaadin.com/vaadin-web-components/25.3.0/#/elements/vaadin-button).\n- `<vaadin-menu-bar-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.3.0/#/elements/vaadin-item).\n- `<vaadin-menu-bar-list-box>` - has the same API as [`<vaadin-list-box>`](https://cdn.vaadin.com/vaadin-web-components/25.3.0/#/elements/vaadin-list-box).\n- `<vaadin-menu-bar-submenu>` - has the same API as [`<vaadin-context-menu>`](https://cdn.vaadin.com/vaadin-web-components/25.3.0/#/elements/vaadin-context-menu).\n\nThe `<vaadin-menu-bar-item>` sub-menu elements have the following additional state attributes\non top of the built-in `<vaadin-item>` state attributes:\n\nAttribute | Description\n---------- |-------------\n`expanded` | Expanded parent item.",
12
12
  "attributes": [
13
13
  {
14
14
  "name": "disabled",
@@ -51,9 +51,7 @@
51
51
  "description": "The theme variants to apply to the component.",
52
52
  "value": {
53
53
  "type": [
54
- "string",
55
- "null",
56
- "undefined"
54
+ "string"
57
55
  ]
58
56
  }
59
57
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/menu-bar",
4
- "version": "25.3.0-dev.3a3c2d7d2a",
4
+ "version": "25.3.0",
5
5
  "description-markup": "markdown",
6
6
  "framework": "lit",
7
7
  "framework-config": {
@@ -16,7 +16,7 @@
16
16
  "elements": [
17
17
  {
18
18
  "name": "vaadin-menu-bar",
19
- "description": "`<vaadin-menu-bar>` is a Web Component providing a set of horizontally stacked buttons offering\nthe user quick access to a consistent set of commands. Each button can toggle a submenu with\nsupport for additional levels of nested menus.\n\nTo create the menu bar, first add the component to the page:\n\n```html\n<vaadin-menu-bar></vaadin-menu-bar>\n```\n\nAnd then use [`items`](https://cdn.vaadin.com/vaadin-web-components/25.3.0-dev.3a3c2d7d2a/#/elements/vaadin-menu-bar#property-items) property to initialize the structure:\n\n```js\ndocument.querySelector('vaadin-menu-bar').items = [{text: 'File'}, {text: 'Edit'}];\n```\n\n### Styling\n\nThe following shadow DOM parts are exposed for styling:\n\nPart name | Description\n------------------|----------------\n`container` | The container wrapping menu bar buttons.\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n--------------------|----------------------------------\n`disabled` | Set when the menu bar is disabled\n`has-single-button` | Set when there is only one button visible\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Internal components\n\nIn addition to `<vaadin-menu-bar>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-menu-bar-button>` - has the same API as [`<vaadin-button>`](https://cdn.vaadin.com/vaadin-web-components/25.3.0-dev.3a3c2d7d2a/#/elements/vaadin-button).\n- `<vaadin-menu-bar-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.3.0-dev.3a3c2d7d2a/#/elements/vaadin-item).\n- `<vaadin-menu-bar-list-box>` - has the same API as [`<vaadin-list-box>`](https://cdn.vaadin.com/vaadin-web-components/25.3.0-dev.3a3c2d7d2a/#/elements/vaadin-list-box).\n- `<vaadin-menu-bar-submenu>` - has the same API as [`<vaadin-context-menu>`](https://cdn.vaadin.com/vaadin-web-components/25.3.0-dev.3a3c2d7d2a/#/elements/vaadin-context-menu).\n\nThe `<vaadin-menu-bar-item>` sub-menu elements have the following additional state attributes\non top of the built-in `<vaadin-item>` state attributes:\n\nAttribute | Description\n---------- |-------------\n`expanded` | Expanded parent item.",
19
+ "description": "`<vaadin-menu-bar>` is a Web Component providing a set of horizontally stacked buttons offering\nthe user quick access to a consistent set of commands. Each button can toggle a submenu with\nsupport for additional levels of nested menus.\n\nTo create the menu bar, first add the component to the page:\n\n```html\n<vaadin-menu-bar></vaadin-menu-bar>\n```\n\nAnd then use [`items`](https://cdn.vaadin.com/vaadin-web-components/25.3.0/#/elements/vaadin-menu-bar#property-items) property to initialize the structure:\n\n```js\ndocument.querySelector('vaadin-menu-bar').items = [{text: 'File'}, {text: 'Edit'}];\n```\n\n### Styling\n\nThe following shadow DOM parts are exposed for styling:\n\nPart name | Description\n------------------|----------------\n`container` | The container wrapping menu bar buttons.\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n--------------------|----------------------------------\n`disabled` | Set when the menu bar is disabled\n`has-single-button` | Set when there is only one button visible\n\nThe following custom CSS properties are available for styling:\n\nCustom CSS property |\n:---------------------------|\n| `--vaadin-menu-bar-gap` |\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Internal components\n\nIn addition to `<vaadin-menu-bar>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-menu-bar-button>` - has the same API as [`<vaadin-button>`](https://cdn.vaadin.com/vaadin-web-components/25.3.0/#/elements/vaadin-button).\n- `<vaadin-menu-bar-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.3.0/#/elements/vaadin-item).\n- `<vaadin-menu-bar-list-box>` - has the same API as [`<vaadin-list-box>`](https://cdn.vaadin.com/vaadin-web-components/25.3.0/#/elements/vaadin-list-box).\n- `<vaadin-menu-bar-submenu>` - has the same API as [`<vaadin-context-menu>`](https://cdn.vaadin.com/vaadin-web-components/25.3.0/#/elements/vaadin-context-menu).\n\nThe `<vaadin-menu-bar-item>` sub-menu elements have the following additional state attributes\non top of the built-in `<vaadin-item>` state attributes:\n\nAttribute | Description\n---------- |-------------\n`expanded` | Expanded parent item.",
20
20
  "extension": true,
21
21
  "attributes": [
22
22
  {