@vaadin/menu-bar 24.8.0-alpha4 → 24.8.0-alpha6

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": "24.8.0-alpha4",
3
+ "version": "24.8.0-alpha6",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -37,22 +37,22 @@
37
37
  "dependencies": {
38
38
  "@open-wc/dedupe-mixin": "^1.3.0",
39
39
  "@polymer/polymer": "^3.0.0",
40
- "@vaadin/a11y-base": "24.8.0-alpha4",
41
- "@vaadin/button": "24.8.0-alpha4",
42
- "@vaadin/component-base": "24.8.0-alpha4",
43
- "@vaadin/context-menu": "24.8.0-alpha4",
44
- "@vaadin/item": "24.8.0-alpha4",
45
- "@vaadin/list-box": "24.8.0-alpha4",
46
- "@vaadin/overlay": "24.8.0-alpha4",
47
- "@vaadin/vaadin-lumo-styles": "24.8.0-alpha4",
48
- "@vaadin/vaadin-material-styles": "24.8.0-alpha4",
49
- "@vaadin/vaadin-themable-mixin": "24.8.0-alpha4",
40
+ "@vaadin/a11y-base": "24.8.0-alpha6",
41
+ "@vaadin/button": "24.8.0-alpha6",
42
+ "@vaadin/component-base": "24.8.0-alpha6",
43
+ "@vaadin/context-menu": "24.8.0-alpha6",
44
+ "@vaadin/item": "24.8.0-alpha6",
45
+ "@vaadin/list-box": "24.8.0-alpha6",
46
+ "@vaadin/overlay": "24.8.0-alpha6",
47
+ "@vaadin/vaadin-lumo-styles": "24.8.0-alpha6",
48
+ "@vaadin/vaadin-material-styles": "24.8.0-alpha6",
49
+ "@vaadin/vaadin-themable-mixin": "24.8.0-alpha6",
50
50
  "lit": "^3.0.0"
51
51
  },
52
52
  "devDependencies": {
53
- "@vaadin/chai-plugins": "24.8.0-alpha4",
54
- "@vaadin/icon": "24.8.0-alpha4",
55
- "@vaadin/test-runner-commands": "24.8.0-alpha4",
53
+ "@vaadin/chai-plugins": "24.8.0-alpha6",
54
+ "@vaadin/icon": "24.8.0-alpha6",
55
+ "@vaadin/test-runner-commands": "24.8.0-alpha6",
56
56
  "@vaadin/testing-helpers": "^1.1.0",
57
57
  "sinon": "^18.0.0"
58
58
  },
@@ -60,5 +60,5 @@
60
60
  "web-types.json",
61
61
  "web-types.lit.json"
62
62
  ],
63
- "gitHead": "88251b4c84ebb8849dde982acb62cc2b20eeec31"
63
+ "gitHead": "be9ac1686511f20dad4adf9303597c5eaa687df3"
64
64
  }
@@ -3,8 +3,6 @@
3
3
  * Copyright (c) 2019 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { html, nothing, render } from 'lit';
7
- import { ifDefined } from 'lit/directives/if-defined.js';
8
6
  import { DisabledMixin } from '@vaadin/a11y-base/src/disabled-mixin.js';
9
7
  import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
10
8
  import { isElementFocused, isElementHidden, isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js';
@@ -275,11 +273,8 @@ export const MenuBarMixin = (superClass) =>
275
273
  dots.innerHTML = '·'.repeat(3);
276
274
  btn.appendChild(dots);
277
275
 
278
- btn.setAttribute('aria-haspopup', 'true');
279
- btn.setAttribute('aria-expanded', 'false');
280
- btn.setAttribute('role', this.tabNavigation ? 'button' : 'menuitem');
281
-
282
276
  this._overflow = btn;
277
+ this._initButtonAttrs(btn);
283
278
  },
284
279
  });
285
280
  this.addController(this._overflowController);
@@ -360,16 +355,14 @@ export const MenuBarMixin = (superClass) =>
360
355
  */
361
356
  _themeChanged(theme, overflow, container) {
362
357
  if (overflow && container) {
363
- this.__renderButtons(this.items);
358
+ this._buttons.forEach((btn) => this._setButtonTheme(btn, theme));
364
359
  this.__detectOverflow();
360
+ }
365
361
 
366
- if (theme) {
367
- overflow.setAttribute('theme', theme);
368
- this._subMenu.setAttribute('theme', theme);
369
- } else {
370
- overflow.removeAttribute('theme');
371
- this._subMenu.removeAttribute('theme');
372
- }
362
+ if (theme) {
363
+ this._subMenu.setAttribute('theme', theme);
364
+ } else {
365
+ this._subMenu.removeAttribute('theme');
373
366
  }
374
367
  }
375
368
 
@@ -421,13 +414,7 @@ export const MenuBarMixin = (superClass) =>
421
414
 
422
415
  const subMenu = this._subMenu;
423
416
  if (subMenu && subMenu.opened) {
424
- const button = subMenu._overlayElement.positionTarget;
425
-
426
- // Close sub-menu if the corresponding button is no longer in the DOM,
427
- // or if the item on it has been changed to no longer have children.
428
- if (!button.isConnected || !Array.isArray(button.item.children) || button.item.children.length === 0) {
429
- subMenu.close();
430
- }
417
+ subMenu.close();
431
418
  }
432
419
  }
433
420
 
@@ -563,17 +550,66 @@ export const MenuBarMixin = (superClass) =>
563
550
  });
564
551
  }
565
552
 
566
- /** @private */
567
- __getButtonTheme(item, hostTheme) {
553
+ /** @protected */
554
+ _removeButtons() {
555
+ this._buttons.forEach((button) => {
556
+ if (button !== this._overflow) {
557
+ this.removeChild(button);
558
+ }
559
+ });
560
+ }
561
+
562
+ /** @protected */
563
+ _initButton(item) {
564
+ const button = document.createElement('vaadin-menu-bar-button');
565
+
566
+ const itemCopy = { ...item };
567
+ button.item = itemCopy;
568
+
569
+ if (item.component) {
570
+ const component = this.__getComponent(itemCopy);
571
+ itemCopy.component = component;
572
+ // Save item for overflow menu
573
+ component.item = itemCopy;
574
+ button.appendChild(component);
575
+ } else if (item.text) {
576
+ button.textContent = item.text;
577
+ }
578
+
579
+ if (item.className) {
580
+ button.className = item.className;
581
+ }
582
+
583
+ button.disabled = item.disabled;
584
+
585
+ return button;
586
+ }
587
+
588
+ /** @protected */
589
+ _initButtonAttrs(button) {
590
+ button.setAttribute('role', this.tabNavigation ? 'button' : 'menuitem');
591
+
592
+ if (button === this._overflow || (button.item && button.item.children)) {
593
+ button.setAttribute('aria-haspopup', 'true');
594
+ button.setAttribute('aria-expanded', 'false');
595
+ }
596
+ }
597
+
598
+ /** @protected */
599
+ _setButtonTheme(btn, hostTheme) {
568
600
  let theme = hostTheme;
569
601
 
570
602
  // Item theme takes precedence over host theme even if it's empty, as long as it's not undefined or null
571
- const itemTheme = item && item.theme;
603
+ const itemTheme = btn.item && btn.item.theme;
572
604
  if (itemTheme != null) {
573
605
  theme = Array.isArray(itemTheme) ? itemTheme.join(' ') : itemTheme;
574
606
  }
575
607
 
576
- return theme;
608
+ if (theme) {
609
+ btn.setAttribute('theme', theme);
610
+ } else {
611
+ btn.removeAttribute('theme');
612
+ }
577
613
  }
578
614
 
579
615
  /** @private */
@@ -598,41 +634,19 @@ export const MenuBarMixin = (superClass) =>
598
634
 
599
635
  /** @private */
600
636
  __renderButtons(items = []) {
601
- const renderContent = (item) => {
602
- if (item.component) {
603
- const component = this.__getComponent(item);
604
- item.component = component;
605
- // Save item for overflow menu
606
- component.item = item;
607
- return component;
608
- } else if (item.text) {
609
- return item.text;
610
- }
611
- };
637
+ this._removeButtons();
612
638
 
613
- render(
614
- html`
615
- ${items.map((item) => {
616
- const itemCopy = { ...item };
617
- const hasChildren = Boolean(item && item.children);
618
-
619
- return html`
620
- <vaadin-menu-bar-button
621
- .item="${itemCopy}"
622
- .disabled="${item.disabled}"
623
- role="${this.tabNavigation ? 'button' : 'menuitem'}"
624
- aria-haspopup="${ifDefined(hasChildren ? 'true' : nothing)}"
625
- aria-expanded="${ifDefined(hasChildren ? 'false' : nothing)}"
626
- class="${ifDefined(item.className)}"
627
- theme="${ifDefined(this.__getButtonTheme(itemCopy, this._theme) || nothing)}"
628
- >${renderContent(itemCopy)}</vaadin-menu-bar-button
629
- >
630
- `;
631
- })}
632
- `,
633
- this,
634
- { renderBefore: this._overflow },
635
- );
639
+ /* Empty array, do nothing */
640
+ if (items.length === 0) {
641
+ return;
642
+ }
643
+
644
+ items.forEach((item) => {
645
+ const button = this._initButton(item);
646
+ this.insertBefore(button, this._overflow);
647
+ this._initButtonAttrs(button);
648
+ this._setButtonTheme(button, this._theme);
649
+ });
636
650
 
637
651
  this.__detectOverflow();
638
652
  }
@@ -940,6 +954,13 @@ export const MenuBarMixin = (superClass) =>
940
954
  this._expandedButton = button;
941
955
 
942
956
  requestAnimationFrame(() => {
957
+ // After changing items, buttons are recreated so the old button is
958
+ // no longer in the DOM. Reset position target to null to prevent
959
+ // overlay from closing due to target width / height equal to 0.
960
+ if (overlay.positionTarget && !overlay.positionTarget.isConnected) {
961
+ overlay.positionTarget = null;
962
+ }
963
+
943
964
  button.dispatchEvent(
944
965
  new CustomEvent('opensubmenu', {
945
966
  detail: {
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": "24.8.0-alpha4",
4
+ "version": "24.8.0-alpha6",
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```\n<vaadin-menu-bar></vaadin-menu-bar>\n```\n\nAnd then use [`items`](https://cdn.vaadin.com/vaadin-web-components/24.8.0-alpha4/#/elements/vaadin-menu-bar#property-items) property to initialize the structure:\n\n```\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/24.8.0-alpha4/#/elements/vaadin-button).\n- `<vaadin-menu-bar-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/24.8.0-alpha4/#/elements/vaadin-item).\n- `<vaadin-menu-bar-list-box>` - has the same API as [`<vaadin-list-box>`](https://cdn.vaadin.com/vaadin-web-components/24.8.0-alpha4/#/elements/vaadin-list-box).\n- `<vaadin-menu-bar-overlay>` - has the same API as [`<vaadin-overlay>`](https://cdn.vaadin.com/vaadin-web-components/24.8.0-alpha4/#/elements/vaadin-overlay).\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.\n\nNote: the `theme` attribute value set on `<vaadin-menu-bar>` is\npropagated to the internal components listed above.",
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```\n<vaadin-menu-bar></vaadin-menu-bar>\n```\n\nAnd then use [`items`](https://cdn.vaadin.com/vaadin-web-components/24.8.0-alpha6/#/elements/vaadin-menu-bar#property-items) property to initialize the structure:\n\n```\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/24.8.0-alpha6/#/elements/vaadin-button).\n- `<vaadin-menu-bar-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/24.8.0-alpha6/#/elements/vaadin-item).\n- `<vaadin-menu-bar-list-box>` - has the same API as [`<vaadin-list-box>`](https://cdn.vaadin.com/vaadin-web-components/24.8.0-alpha6/#/elements/vaadin-list-box).\n- `<vaadin-menu-bar-overlay>` - has the same API as [`<vaadin-overlay>`](https://cdn.vaadin.com/vaadin-web-components/24.8.0-alpha6/#/elements/vaadin-overlay).\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.\n\nNote: the `theme` attribute value set on `<vaadin-menu-bar>` is\npropagated to the internal components listed above.",
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": "24.8.0-alpha4",
4
+ "version": "24.8.0-alpha6",
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```\n<vaadin-menu-bar></vaadin-menu-bar>\n```\n\nAnd then use [`items`](https://cdn.vaadin.com/vaadin-web-components/24.8.0-alpha4/#/elements/vaadin-menu-bar#property-items) property to initialize the structure:\n\n```\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/24.8.0-alpha4/#/elements/vaadin-button).\n- `<vaadin-menu-bar-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/24.8.0-alpha4/#/elements/vaadin-item).\n- `<vaadin-menu-bar-list-box>` - has the same API as [`<vaadin-list-box>`](https://cdn.vaadin.com/vaadin-web-components/24.8.0-alpha4/#/elements/vaadin-list-box).\n- `<vaadin-menu-bar-overlay>` - has the same API as [`<vaadin-overlay>`](https://cdn.vaadin.com/vaadin-web-components/24.8.0-alpha4/#/elements/vaadin-overlay).\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.\n\nNote: the `theme` attribute value set on `<vaadin-menu-bar>` is\npropagated to the internal components listed above.",
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```\n<vaadin-menu-bar></vaadin-menu-bar>\n```\n\nAnd then use [`items`](https://cdn.vaadin.com/vaadin-web-components/24.8.0-alpha6/#/elements/vaadin-menu-bar#property-items) property to initialize the structure:\n\n```\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/24.8.0-alpha6/#/elements/vaadin-button).\n- `<vaadin-menu-bar-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/24.8.0-alpha6/#/elements/vaadin-item).\n- `<vaadin-menu-bar-list-box>` - has the same API as [`<vaadin-list-box>`](https://cdn.vaadin.com/vaadin-web-components/24.8.0-alpha6/#/elements/vaadin-list-box).\n- `<vaadin-menu-bar-overlay>` - has the same API as [`<vaadin-overlay>`](https://cdn.vaadin.com/vaadin-web-components/24.8.0-alpha6/#/elements/vaadin-overlay).\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.\n\nNote: the `theme` attribute value set on `<vaadin-menu-bar>` is\npropagated to the internal components listed above.",
20
20
  "extension": true,
21
21
  "attributes": [
22
22
  {