@vaadin/menu-bar 25.3.0-beta2 → 25.3.0-beta3

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/menu-bar",
3
- "version": "25.3.0-beta2",
3
+ "version": "25.3.0-beta3",
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-beta2",
39
- "@vaadin/button": "25.3.0-beta2",
40
- "@vaadin/component-base": "25.3.0-beta2",
41
- "@vaadin/context-menu": "25.3.0-beta2",
42
- "@vaadin/item": "25.3.0-beta2",
43
- "@vaadin/list-box": "25.3.0-beta2",
44
- "@vaadin/overlay": "25.3.0-beta2",
45
- "@vaadin/vaadin-themable-mixin": "25.3.0-beta2",
38
+ "@vaadin/a11y-base": "25.3.0-beta3",
39
+ "@vaadin/button": "25.3.0-beta3",
40
+ "@vaadin/component-base": "25.3.0-beta3",
41
+ "@vaadin/context-menu": "25.3.0-beta3",
42
+ "@vaadin/item": "25.3.0-beta3",
43
+ "@vaadin/list-box": "25.3.0-beta3",
44
+ "@vaadin/overlay": "25.3.0-beta3",
45
+ "@vaadin/vaadin-themable-mixin": "25.3.0-beta3",
46
46
  "lit": "^3.0.0"
47
47
  },
48
48
  "devDependencies": {
49
- "@vaadin/aura": "25.3.0-beta2",
50
- "@vaadin/chai-plugins": "25.3.0-beta2",
51
- "@vaadin/icon": "25.3.0-beta2",
52
- "@vaadin/test-runner-commands": "25.3.0-beta2",
49
+ "@vaadin/aura": "25.3.0-beta3",
50
+ "@vaadin/chai-plugins": "25.3.0-beta3",
51
+ "@vaadin/icon": "25.3.0-beta3",
52
+ "@vaadin/test-runner-commands": "25.3.0-beta3",
53
53
  "@vaadin/testing-helpers": "^2.0.0",
54
- "@vaadin/vaadin-lumo-styles": "25.3.0-beta2",
54
+ "@vaadin/vaadin-lumo-styles": "25.3.0-beta3",
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": "d97ccbec217b60c39f3c8b2dd52473c79a48c8c1"
62
+ "gitHead": "1ea43188e1297f6898cbf9d3610b85a7a2cca6f0"
63
63
  }
@@ -361,6 +361,10 @@ export const MenuBarMixin = (superClass) =>
361
361
  this._themeChanged(this._theme);
362
362
  }
363
363
 
364
+ if (props.has('dir')) {
365
+ setOrRemoveAttribute(this._subMenu, 'dir', this.dir);
366
+ }
367
+
364
368
  if (props.has('disabled')) {
365
369
  this._overflow.toggleAttribute('disabled', this.disabled);
366
370
  }
@@ -447,8 +451,7 @@ export const MenuBarMixin = (superClass) =>
447
451
 
448
452
  /** @private */
449
453
  __getOverflowCount(overflow) {
450
- // We can't use optional chaining due to webpack 4
451
- return (overflow.item && overflow.item.children && overflow.item.children.length) || 0;
454
+ return overflow.item?.children?.length ?? 0;
452
455
  }
453
456
 
454
457
  /** @private */
@@ -459,12 +462,11 @@ export const MenuBarMixin = (superClass) =>
459
462
  button.style.width = '';
460
463
 
461
464
  // Teleport item component back from "overflow" sub-menu
462
- const item = button.item && button.item.component;
465
+ const item = button.item?.component;
463
466
  if (item instanceof HTMLElement && item.getAttribute('role') === 'menuitem') {
464
467
  this.__restoreItem(button, item);
465
468
  }
466
469
  });
467
- this.__updateOverflow([]);
468
470
  }
469
471
 
470
472
  /** @private */
@@ -542,6 +544,7 @@ export const MenuBarMixin = (superClass) =>
542
544
 
543
545
  // Reset all buttons in the menu bar and the overflow button
544
546
  this.__restoreButtons(buttons);
547
+ this.__updateOverflow([]);
545
548
 
546
549
  // Hide any overflowing buttons and put them in the 'overflow' button
547
550
  this.__setOverflowItems(buttons, overflow);
@@ -554,7 +557,11 @@ export const MenuBarMixin = (superClass) =>
554
557
  const isSingleButton = newOverflowCount === buttons.length || (newOverflowCount === 0 && buttons.length === 1);
555
558
  this.toggleAttribute('has-single-button', isSingleButton);
556
559
 
557
- // Collect visible buttons to detect if tabindex should be updated
560
+ this.__updateVisibleButtons(buttons);
561
+ }
562
+
563
+ /** @private */
564
+ __updateVisibleButtons(buttons) {
558
565
  const visibleButtons = buttons.filter((btn) => btn.style.visibility !== 'hidden');
559
566
 
560
567
  if (!visibleButtons.length) {
@@ -566,8 +573,7 @@ export const MenuBarMixin = (superClass) =>
566
573
  this._setTabindex(visibleButtons[visibleButtons.length - 1], true);
567
574
  }
568
575
 
569
- // Apply first/last visible attributes to the visible buttons
570
- visibleButtons.forEach((btn, index, visibleButtons) => {
576
+ visibleButtons.forEach((btn, index) => {
571
577
  btn.toggleAttribute('first-visible', index === 0);
572
578
  btn.toggleAttribute('last-visible', !this._hasOverflow && index === visibleButtons.length - 1);
573
579
  });
@@ -615,9 +621,7 @@ export const MenuBarMixin = (superClass) =>
615
621
  const hasChildren = Boolean(item?.children);
616
622
 
617
623
  if (itemCopy.component) {
618
- const component = this.__getComponent(itemCopy);
619
- itemCopy.component = component;
620
- component.item = itemCopy;
624
+ itemCopy.component = this.__getComponent(itemCopy);
621
625
  }
622
626
 
623
627
  return html`
@@ -645,7 +649,7 @@ export const MenuBarMixin = (superClass) =>
645
649
  const button = event.target;
646
650
  // Propagate click event from button to the item component if it was outside
647
651
  // it e.g. by calling `click()` on the button (used by the Flow counterpart).
648
- if (button.item && button.item.component && !event.composedPath().includes(button.item.component)) {
652
+ if (button.item?.component && !event.composedPath().includes(button.item.component)) {
649
653
  event.stopPropagation();
650
654
  button.item.component.click();
651
655
  }
@@ -692,7 +696,7 @@ export const MenuBarMixin = (superClass) =>
692
696
 
693
697
  this._tooltipController.setTarget(button);
694
698
 
695
- if (wasExpanded && button.item && button.item.children) {
699
+ if (wasExpanded && button.item?.children) {
696
700
  this.__openSubMenu(button, true, { keepFocus: true });
697
701
  } else if (!this._subMenu.opened) {
698
702
  this._tooltipController.open({ trigger: 'focus' });
@@ -888,12 +892,16 @@ export const MenuBarMixin = (superClass) =>
888
892
  const item = Array.from(e.composedPath()).find((el) => el._item);
889
893
  if (item) {
890
894
  const list = item.parentNode;
891
- if (e.keyCode === 38 && item === list.items[0]) {
895
+ if (e.key === 'ArrowUp' && item === list.items[0]) {
892
896
  this._close(true);
893
897
  }
894
- // ArrowLeft, or ArrowRight on non-parent submenu item,
895
- if (e.keyCode === 37 || (e.keyCode === 39 && !item._item.children)) {
896
- // 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
897
905
  e.stopImmediatePropagation();
898
906
  this._handleKeyDown(e);
899
907
  }
@@ -983,13 +991,12 @@ export const MenuBarMixin = (superClass) =>
983
991
 
984
992
  /** @private */
985
993
  _focusFirstItem() {
986
- const list = this._subMenu._overlayElement._contentRoot.firstElementChild;
987
- list.focus();
994
+ this._subMenu._menuListBox.focus();
988
995
  }
989
996
 
990
997
  /** @private */
991
998
  _focusLastItem() {
992
- const list = this._subMenu._overlayElement._contentRoot.firstElementChild;
999
+ const list = this._subMenu._menuListBox;
993
1000
  const item = list.items[list.items.length - 1];
994
1001
  if (item) {
995
1002
  item.focus();
@@ -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';
@@ -21,7 +22,7 @@ import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-p
21
22
  * @extends HTMLElement
22
23
  * @protected
23
24
  */
24
- class MenuBarSubmenu extends ContextMenuMixin(ThemePropertyMixin(PolylitMixin(LitElement))) {
25
+ class MenuBarSubmenu extends ContextMenuMixin(DirMixin(ThemePropertyMixin(PolylitMixin(LitElement)))) {
25
26
  static get is() {
26
27
  return 'vaadin-menu-bar-submenu';
27
28
  }
@@ -122,7 +123,7 @@ class MenuBarSubmenu extends ContextMenuMixin(ThemePropertyMixin(PolylitMixin(Li
122
123
  super.close();
123
124
 
124
125
  // Only handle 1st level submenu
125
- if (this.hasAttribute('is-root')) {
126
+ if (this.isRoot) {
126
127
  this.parentElement._close();
127
128
  }
128
129
  }
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-beta2",
4
+ "version": "25.3.0-beta3",
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-beta2/#/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-beta2/#/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-beta2/#/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-beta2/#/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-beta2/#/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-beta3/#/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-beta3/#/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-beta3/#/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-beta3/#/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-beta3/#/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",
@@ -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-beta2",
4
+ "version": "25.3.0-beta3",
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-beta2/#/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-beta2/#/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-beta2/#/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-beta2/#/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-beta2/#/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-beta3/#/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-beta3/#/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-beta3/#/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-beta3/#/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-beta3/#/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
  {