@vaadin/menu-bar 24.8.0-alpha8 → 24.8.0-beta1

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-alpha8",
3
+ "version": "24.8.0-beta1",
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-alpha8",
41
- "@vaadin/button": "24.8.0-alpha8",
42
- "@vaadin/component-base": "24.8.0-alpha8",
43
- "@vaadin/context-menu": "24.8.0-alpha8",
44
- "@vaadin/item": "24.8.0-alpha8",
45
- "@vaadin/list-box": "24.8.0-alpha8",
46
- "@vaadin/overlay": "24.8.0-alpha8",
47
- "@vaadin/vaadin-lumo-styles": "24.8.0-alpha8",
48
- "@vaadin/vaadin-material-styles": "24.8.0-alpha8",
49
- "@vaadin/vaadin-themable-mixin": "24.8.0-alpha8",
40
+ "@vaadin/a11y-base": "24.8.0-beta1",
41
+ "@vaadin/button": "24.8.0-beta1",
42
+ "@vaadin/component-base": "24.8.0-beta1",
43
+ "@vaadin/context-menu": "24.8.0-beta1",
44
+ "@vaadin/item": "24.8.0-beta1",
45
+ "@vaadin/list-box": "24.8.0-beta1",
46
+ "@vaadin/overlay": "24.8.0-beta1",
47
+ "@vaadin/vaadin-lumo-styles": "24.8.0-beta1",
48
+ "@vaadin/vaadin-material-styles": "24.8.0-beta1",
49
+ "@vaadin/vaadin-themable-mixin": "24.8.0-beta1",
50
50
  "lit": "^3.0.0"
51
51
  },
52
52
  "devDependencies": {
53
- "@vaadin/chai-plugins": "24.8.0-alpha8",
54
- "@vaadin/icon": "24.8.0-alpha8",
55
- "@vaadin/test-runner-commands": "24.8.0-alpha8",
53
+ "@vaadin/chai-plugins": "24.8.0-beta1",
54
+ "@vaadin/icon": "24.8.0-beta1",
55
+ "@vaadin/test-runner-commands": "24.8.0-beta1",
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": "d914bb8f669d7e3d1981feb8eac05688ab9870b4"
63
+ "gitHead": "57ce3a90de99e49049312b0ba4041d3e7542e9d8"
64
64
  }
@@ -3,15 +3,53 @@
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, noChange, nothing, render } from 'lit';
7
+ import { Directive, directive } from 'lit/directive.js';
8
+ import { ifDefined } from 'lit/directives/if-defined.js';
6
9
  import { DisabledMixin } from '@vaadin/a11y-base/src/disabled-mixin.js';
7
10
  import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
8
- import { isElementFocused, isElementHidden, isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js';
11
+ import { isElementFocused, isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js';
9
12
  import { KeyboardDirectionMixin } from '@vaadin/a11y-base/src/keyboard-direction-mixin.js';
10
13
  import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
11
14
  import { I18nMixin } from '@vaadin/component-base/src/i18n-mixin.js';
12
15
  import { ResizeMixin } from '@vaadin/component-base/src/resize-mixin.js';
13
16
  import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
14
17
 
18
+ /**
19
+ * Custom Lit directive for rendering item components
20
+ * inspired by the `flowComponentDirective` logic.
21
+ */
22
+ class ItemComponentDirective extends Directive {
23
+ update(part, [{ component, text }]) {
24
+ const { parentNode, startNode } = part;
25
+
26
+ const newNode = component || (text ? document.createTextNode(text) : null);
27
+ const oldNode = this.getOldNode(part);
28
+
29
+ if (oldNode === newNode) {
30
+ return noChange;
31
+ } else if (oldNode && newNode) {
32
+ parentNode.replaceChild(newNode, oldNode);
33
+ } else if (oldNode) {
34
+ parentNode.removeChild(oldNode);
35
+ } else if (newNode) {
36
+ startNode.after(newNode);
37
+ }
38
+
39
+ return noChange;
40
+ }
41
+
42
+ getOldNode(part) {
43
+ const { startNode, endNode } = part;
44
+ if (startNode.nextSibling === endNode) {
45
+ return null;
46
+ }
47
+ return startNode.nextSibling;
48
+ }
49
+ }
50
+
51
+ const componentDirective = directive(ItemComponentDirective);
52
+
15
53
  const DEFAULT_I18N = {
16
54
  moreOptions: 'More options',
17
55
  };
@@ -112,6 +150,7 @@ export const MenuBarMixin = (superClass) =>
112
150
  */
113
151
  items: {
114
152
  type: Array,
153
+ sync: true,
115
154
  value: () => [],
116
155
  },
117
156
 
@@ -140,6 +179,7 @@ export const MenuBarMixin = (superClass) =>
140
179
  */
141
180
  reverseCollapse: {
142
181
  type: Boolean,
182
+ sync: true,
143
183
  },
144
184
 
145
185
  /**
@@ -149,6 +189,7 @@ export const MenuBarMixin = (superClass) =>
149
189
  */
150
190
  tabNavigation: {
151
191
  type: Boolean,
192
+ sync: true,
152
193
  },
153
194
 
154
195
  /**
@@ -169,6 +210,7 @@ export const MenuBarMixin = (superClass) =>
169
210
  /** @protected */
170
211
  _container: {
171
212
  type: Object,
213
+ sync: true,
172
214
  },
173
215
  };
174
216
  }
@@ -178,7 +220,7 @@ export const MenuBarMixin = (superClass) =>
178
220
  '_themeChanged(_theme, _overflow, _container)',
179
221
  '__hasOverflowChanged(_hasOverflow, _overflow)',
180
222
  '__i18nChanged(__effectiveI18n, _overflow)',
181
- '_menuItemsChanged(items, _overflow, _container)',
223
+ '__updateButtons(items, disabled, _overflow, _container)',
182
224
  '_reverseCollapseChanged(reverseCollapse, _overflow, _container)',
183
225
  '_tabNavigationChanged(tabNavigation, _overflow, _container)',
184
226
  ];
@@ -235,6 +277,17 @@ export const MenuBarMixin = (superClass) =>
235
277
  return false;
236
278
  }
237
279
 
280
+ /**
281
+ * Override getter from `KeyboardDirectionMixin`.
282
+ *
283
+ * @return {boolean}
284
+ * @protected
285
+ * @override
286
+ */
287
+ get _tabNavigation() {
288
+ return this.tabNavigation;
289
+ }
290
+
238
291
  /**
239
292
  * Override getter from `ResizeMixin` to observe parent.
240
293
  *
@@ -273,8 +326,11 @@ export const MenuBarMixin = (superClass) =>
273
326
  dots.innerHTML = '·'.repeat(3);
274
327
  btn.appendChild(dots);
275
328
 
329
+ btn.setAttribute('aria-haspopup', 'true');
330
+ btn.setAttribute('aria-expanded', 'false');
331
+ btn.setAttribute('role', this.tabNavigation ? 'button' : 'menuitem');
332
+
276
333
  this._overflow = btn;
277
- this._initButtonAttrs(btn);
278
334
  },
279
335
  });
280
336
  this.addController(this._overflowController);
@@ -329,23 +385,6 @@ export const MenuBarMixin = (superClass) =>
329
385
  this.__detectOverflow();
330
386
  }
331
387
 
332
- /**
333
- * Override method inherited from `DisabledMixin`
334
- * to update the `disabled` property for the buttons
335
- * whenever the property changes on the menu bar.
336
- *
337
- * @param {boolean} newValue the new disabled value
338
- * @param {boolean} oldValue the previous disabled value
339
- * @override
340
- * @protected
341
- */
342
- _disabledChanged(newValue, oldValue) {
343
- super._disabledChanged(newValue, oldValue);
344
- if (oldValue !== newValue) {
345
- this.__updateButtonsDisabled(newValue);
346
- }
347
- }
348
-
349
388
  /**
350
389
  * A callback for the `_theme` property observer.
351
390
  * It propagates the host theme to the buttons and the sub menu.
@@ -355,14 +394,16 @@ export const MenuBarMixin = (superClass) =>
355
394
  */
356
395
  _themeChanged(theme, overflow, container) {
357
396
  if (overflow && container) {
358
- this._buttons.forEach((btn) => this._setButtonTheme(btn, theme));
397
+ this.__renderButtons(this.items);
359
398
  this.__detectOverflow();
360
- }
361
399
 
362
- if (theme) {
363
- this._subMenu.setAttribute('theme', theme);
364
- } else {
365
- this._subMenu.removeAttribute('theme');
400
+ if (theme) {
401
+ overflow.setAttribute('theme', theme);
402
+ this._subMenu.setAttribute('theme', theme);
403
+ } else {
404
+ overflow.removeAttribute('theme');
405
+ this._subMenu.removeAttribute('theme');
406
+ }
366
407
  }
367
408
  }
368
409
 
@@ -402,7 +443,7 @@ export const MenuBarMixin = (superClass) =>
402
443
  }
403
444
 
404
445
  /** @private */
405
- _menuItemsChanged(items, overflow, container) {
446
+ __updateButtons(items, disabled, overflow, container) {
406
447
  if (!overflow || !container) {
407
448
  return;
408
449
  }
@@ -410,11 +451,24 @@ export const MenuBarMixin = (superClass) =>
410
451
  if (items !== this._oldItems) {
411
452
  this._oldItems = items;
412
453
  this.__renderButtons(items);
454
+ this.__detectOverflow();
455
+ }
456
+
457
+ if (disabled !== this._oldDisabled) {
458
+ this._oldDisabled = disabled;
459
+ this.__renderButtons(items);
460
+ overflow.toggleAttribute('disabled', disabled);
413
461
  }
414
462
 
415
463
  const subMenu = this._subMenu;
416
464
  if (subMenu && subMenu.opened) {
417
- subMenu.close();
465
+ const button = subMenu._overlayElement.positionTarget;
466
+
467
+ // Close sub-menu if the corresponding button is no longer in the DOM,
468
+ // or if the item on it has been changed to no longer have children.
469
+ if (!button.isConnected || !Array.isArray(button.item.children) || button.item.children.length === 0) {
470
+ subMenu.close();
471
+ }
418
472
  }
419
473
  }
420
474
 
@@ -438,9 +492,9 @@ export const MenuBarMixin = (superClass) =>
438
492
  /** @private */
439
493
  __restoreButtons(buttons) {
440
494
  buttons.forEach((button) => {
441
- button.disabled = (button.item && button.item.disabled) || this.disabled;
442
495
  button.style.visibility = '';
443
496
  button.style.position = '';
497
+ button.style.width = '';
444
498
 
445
499
  // Teleport item component back from "overflow" sub-menu
446
500
  const item = button.item && button.item.component;
@@ -460,14 +514,6 @@ export const MenuBarMixin = (superClass) =>
460
514
  item.removeAttribute('tabindex');
461
515
  }
462
516
 
463
- /** @private */
464
- __updateButtonsDisabled(disabled) {
465
- this._buttons.forEach((btn) => {
466
- // Disable the button if the entire menu-bar is disabled or the item alone is disabled
467
- btn.disabled = disabled || (btn.item && btn.item.disabled);
468
- });
469
- }
470
-
471
517
  /** @private */
472
518
  __updateOverflow(items) {
473
519
  this._overflow.item = { children: items };
@@ -501,7 +547,6 @@ export const MenuBarMixin = (superClass) =>
501
547
 
502
548
  // Save width for buttons with component
503
549
  btn.style.width = getComputedStyle(btn).width;
504
- btn.disabled = true;
505
550
  btn.style.visibility = 'hidden';
506
551
  btn.style.position = 'absolute';
507
552
  }
@@ -550,66 +595,17 @@ export const MenuBarMixin = (superClass) =>
550
595
  });
551
596
  }
552
597
 
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) {
598
+ /** @private */
599
+ __getButtonTheme(item, hostTheme) {
600
600
  let theme = hostTheme;
601
601
 
602
602
  // Item theme takes precedence over host theme even if it's empty, as long as it's not undefined or null
603
- const itemTheme = btn.item && btn.item.theme;
603
+ const itemTheme = item && item.theme;
604
604
  if (itemTheme != null) {
605
605
  theme = Array.isArray(itemTheme) ? itemTheme.join(' ') : itemTheme;
606
606
  }
607
607
 
608
- if (theme) {
609
- btn.setAttribute('theme', theme);
610
- } else {
611
- btn.removeAttribute('theme');
612
- }
608
+ return theme;
613
609
  }
614
610
 
615
611
  /** @private */
@@ -634,21 +630,47 @@ export const MenuBarMixin = (superClass) =>
634
630
 
635
631
  /** @private */
636
632
  __renderButtons(items = []) {
637
- this._removeButtons();
638
-
639
- /* Empty array, do nothing */
640
- if (items.length === 0) {
641
- return;
642
- }
633
+ render(
634
+ html`
635
+ ${items.map((item) => {
636
+ const itemCopy = { ...item };
637
+ const hasChildren = Boolean(item && item.children);
638
+
639
+ if (itemCopy.component) {
640
+ const component = this.__getComponent(itemCopy);
641
+ itemCopy.component = component;
642
+ component.item = itemCopy;
643
+ }
643
644
 
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
- });
645
+ return html`
646
+ <vaadin-menu-bar-button
647
+ .item="${itemCopy}"
648
+ .disabled="${this.disabled || item.disabled}"
649
+ role="${this.tabNavigation ? 'button' : 'menuitem'}"
650
+ aria-haspopup="${ifDefined(hasChildren ? 'true' : nothing)}"
651
+ aria-expanded="${ifDefined(hasChildren ? 'false' : nothing)}"
652
+ class="${ifDefined(item.className || nothing)}"
653
+ theme="${ifDefined(this.__getButtonTheme(item, this._theme) || nothing)}"
654
+ @click="${this.__onRootButtonClick}"
655
+ >${componentDirective(itemCopy)}</vaadin-menu-bar-button
656
+ >
657
+ `;
658
+ })}
659
+ `,
660
+ this,
661
+ { renderBefore: this._overflow },
662
+ );
663
+ }
650
664
 
651
- this.__detectOverflow();
665
+ /** @private */
666
+ __onRootButtonClick(event) {
667
+ const button = event.target;
668
+ // Propagate click event from button to the item component if it was outside
669
+ // it e.g. by calling `click()` on the button (used by the Flow counterpart).
670
+ if (button.item && button.item.component && !event.composedPath().includes(button.item.component)) {
671
+ event.stopPropagation();
672
+ button.item.component.click();
673
+ }
652
674
  }
653
675
 
654
676
  /**
@@ -759,12 +781,7 @@ export const MenuBarMixin = (superClass) =>
759
781
  */
760
782
  _setFocused(focused) {
761
783
  if (focused) {
762
- let target = this.querySelector('[tabindex="0"]');
763
- if (this.tabNavigation) {
764
- // Switch submenu on menu button Tab / Shift Tab
765
- target = this.querySelector('[focused]');
766
- this.__switchSubMenu(target);
767
- }
784
+ const target = this.tabNavigation ? this.querySelector('[focused]') : this.querySelector('[tabindex="0"]');
768
785
  if (target) {
769
786
  this._buttons.forEach((btn) => {
770
787
  this._setTabindex(btn, btn === target);
@@ -883,30 +900,15 @@ export const MenuBarMixin = (superClass) =>
883
900
  if (e.keyCode === 38 && item === list.items[0]) {
884
901
  this._close(true);
885
902
  }
886
- // ArrowLeft, or ArrowRight on non-parent submenu item
903
+ // ArrowLeft, or ArrowRight on non-parent submenu item,
887
904
  if (e.keyCode === 37 || (e.keyCode === 39 && !item._item.children)) {
888
905
  // Prevent ArrowLeft from being handled in context-menu
889
906
  e.stopImmediatePropagation();
890
907
  this._onKeyDown(e);
891
- } else if (e.keyCode === 9 && this.tabNavigation) {
892
- // Switch opened submenu on submenu item Tab / Shift Tab
893
- const items = this._getItems() || [];
894
- const currentIdx = items.indexOf(this.focused);
895
- const increment = e.shiftKey ? -1 : 1;
896
- let idx = currentIdx + increment;
897
- idx = this._getAvailableIndex(items, idx, increment, (item) => !isElementHidden(item));
898
- this.__switchSubMenu(items[idx]);
899
908
  }
900
- }
901
- }
902
909
 
903
- /** @private */
904
- __switchSubMenu(target) {
905
- const wasExpanded = this._expandedButton != null && this._expandedButton !== target;
906
- if (wasExpanded) {
907
- this._close();
908
- if (target.item && target.item.children) {
909
- this.__openSubMenu(target, true, { keepFocus: true });
910
+ if (e.key === 'Tab' && this.tabNavigation) {
911
+ this._onKeyDown(e);
910
912
  }
911
913
  }
912
914
  }
@@ -951,31 +953,21 @@ export const MenuBarMixin = (superClass) =>
951
953
  const overlay = subMenu._overlayElement;
952
954
  overlay.noVerticalOverlap = true;
953
955
 
954
- this._expandedButton = button;
955
-
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
-
964
- button.dispatchEvent(
965
- new CustomEvent('opensubmenu', {
966
- detail: {
967
- children: items,
968
- },
969
- }),
970
- );
971
- this._hideTooltip(true);
972
-
973
- this._setExpanded(button, true);
956
+ this._hideTooltip(true);
974
957
 
975
- overlay.positionTarget = button;
976
- });
958
+ this._expandedButton = button;
959
+ this._setExpanded(button, true);
977
960
 
978
961
  this.style.pointerEvents = 'auto';
962
+ overlay.positionTarget = button;
963
+
964
+ button.dispatchEvent(
965
+ new CustomEvent('opensubmenu', {
966
+ detail: {
967
+ children: items,
968
+ },
969
+ }),
970
+ );
979
971
 
980
972
  overlay.addEventListener(
981
973
  'vaadin-overlay-open',
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-alpha8",
4
+ "version": "24.8.0-beta1",
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-alpha8/#/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-alpha8/#/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-alpha8/#/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-alpha8/#/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-alpha8/#/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-beta1/#/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-beta1/#/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-beta1/#/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-beta1/#/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-beta1/#/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-alpha8",
4
+ "version": "24.8.0-beta1",
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-alpha8/#/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-alpha8/#/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-alpha8/#/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-alpha8/#/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-alpha8/#/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-beta1/#/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-beta1/#/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-beta1/#/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-beta1/#/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-beta1/#/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
  {