@vaadin/menu-bar 25.0.0-alpha9 → 25.0.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.
Files changed (39) hide show
  1. package/package.json +15 -18
  2. package/src/styles/vaadin-menu-bar-base-styles.js +7 -6
  3. package/src/styles/vaadin-menu-bar-button-base-styles.js +1 -1
  4. package/src/vaadin-menu-bar-button.d.ts +19 -0
  5. package/src/vaadin-menu-bar-button.js +3 -1
  6. package/src/vaadin-menu-bar-item.js +1 -1
  7. package/src/vaadin-menu-bar-list-box.js +1 -1
  8. package/src/vaadin-menu-bar-mixin.d.ts +5 -12
  9. package/src/vaadin-menu-bar-mixin.js +20 -35
  10. package/src/vaadin-menu-bar-overlay.js +1 -1
  11. package/src/vaadin-menu-bar-submenu.d.ts +20 -0
  12. package/src/vaadin-menu-bar-submenu.js +69 -3
  13. package/src/vaadin-menu-bar.js +1 -1
  14. package/vaadin-menu-bar.js +1 -1
  15. package/web-types.json +4 -26
  16. package/web-types.lit.json +4 -11
  17. package/src/styles/vaadin-menu-bar-button-core-styles.d.ts +0 -8
  18. package/src/styles/vaadin-menu-bar-button-core-styles.js +0 -16
  19. package/src/styles/vaadin-menu-bar-core-styles.d.ts +0 -8
  20. package/src/styles/vaadin-menu-bar-core-styles.js +0 -24
  21. package/src/styles/vaadin-menu-bar-item-core-styles.d.ts +0 -8
  22. package/src/styles/vaadin-menu-bar-item-core-styles.js +0 -8
  23. package/src/styles/vaadin-menu-bar-overlay-core-styles.d.ts +0 -8
  24. package/src/styles/vaadin-menu-bar-overlay-core-styles.js +0 -9
  25. package/src/vaadin-menu-bar-submenu-mixin.js +0 -66
  26. package/theme/lumo/vaadin-menu-bar-button-styles.d.ts +0 -1
  27. package/theme/lumo/vaadin-menu-bar-button-styles.js +0 -128
  28. package/theme/lumo/vaadin-menu-bar-button.d.ts +0 -2
  29. package/theme/lumo/vaadin-menu-bar-button.js +0 -2
  30. package/theme/lumo/vaadin-menu-bar-item-styles.d.ts +0 -2
  31. package/theme/lumo/vaadin-menu-bar-item-styles.js +0 -27
  32. package/theme/lumo/vaadin-menu-bar-list-box-styles.d.ts +0 -1
  33. package/theme/lumo/vaadin-menu-bar-list-box-styles.js +0 -5
  34. package/theme/lumo/vaadin-menu-bar-overlay-styles.d.ts +0 -1
  35. package/theme/lumo/vaadin-menu-bar-overlay-styles.js +0 -13
  36. package/theme/lumo/vaadin-menu-bar-styles.d.ts +0 -1
  37. package/theme/lumo/vaadin-menu-bar-styles.js +0 -17
  38. package/theme/lumo/vaadin-menu-bar.d.ts +0 -6
  39. package/theme/lumo/vaadin-menu-bar.js +0 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/menu-bar",
3
- "version": "25.0.0-alpha9",
3
+ "version": "25.0.0-beta1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -21,9 +21,6 @@
21
21
  "type": "module",
22
22
  "files": [
23
23
  "src",
24
- "!src/styles/*-base-styles.d.ts",
25
- "!src/styles/*-base-styles.js",
26
- "theme",
27
24
  "vaadin-*.d.ts",
28
25
  "vaadin-*.js",
29
26
  "web-types.json",
@@ -37,27 +34,27 @@
37
34
  ],
38
35
  "dependencies": {
39
36
  "@open-wc/dedupe-mixin": "^1.3.0",
40
- "@vaadin/a11y-base": "25.0.0-alpha9",
41
- "@vaadin/button": "25.0.0-alpha9",
42
- "@vaadin/component-base": "25.0.0-alpha9",
43
- "@vaadin/context-menu": "25.0.0-alpha9",
44
- "@vaadin/item": "25.0.0-alpha9",
45
- "@vaadin/list-box": "25.0.0-alpha9",
46
- "@vaadin/overlay": "25.0.0-alpha9",
47
- "@vaadin/vaadin-lumo-styles": "25.0.0-alpha9",
48
- "@vaadin/vaadin-themable-mixin": "25.0.0-alpha9",
37
+ "@vaadin/a11y-base": "25.0.0-beta1",
38
+ "@vaadin/button": "25.0.0-beta1",
39
+ "@vaadin/component-base": "25.0.0-beta1",
40
+ "@vaadin/context-menu": "25.0.0-beta1",
41
+ "@vaadin/item": "25.0.0-beta1",
42
+ "@vaadin/list-box": "25.0.0-beta1",
43
+ "@vaadin/overlay": "25.0.0-beta1",
44
+ "@vaadin/vaadin-themable-mixin": "25.0.0-beta1",
49
45
  "lit": "^3.0.0"
50
46
  },
51
47
  "devDependencies": {
52
- "@vaadin/chai-plugins": "25.0.0-alpha9",
53
- "@vaadin/icon": "25.0.0-alpha9",
54
- "@vaadin/test-runner-commands": "25.0.0-alpha9",
48
+ "@vaadin/chai-plugins": "25.0.0-beta1",
49
+ "@vaadin/icon": "25.0.0-beta1",
50
+ "@vaadin/test-runner-commands": "25.0.0-beta1",
55
51
  "@vaadin/testing-helpers": "^2.0.0",
56
- "sinon": "^18.0.0"
52
+ "@vaadin/vaadin-lumo-styles": "25.0.0-beta1",
53
+ "sinon": "^21.0.0"
57
54
  },
58
55
  "web-types": [
59
56
  "web-types.json",
60
57
  "web-types.lit.json"
61
58
  ],
62
- "gitHead": "bbe4720721e0955ffc87a79b412bee38b1f0eb1e"
59
+ "gitHead": "1d20cf54e582d1f2e209126d4586f8b4c01c50e0"
63
60
  }
@@ -17,16 +17,15 @@ export const menuBarStyles = css`
17
17
  [part='container'] {
18
18
  display: flex;
19
19
  flex-wrap: nowrap;
20
- margin: calc((var(--vaadin-focus-ring-width) + 1px) * -1);
20
+ margin: calc((var(--vaadin-focus-ring-width) + 2px) * -1);
21
21
  overflow: hidden;
22
- padding: calc(var(--vaadin-focus-ring-width) + 1px);
22
+ padding: calc(var(--vaadin-focus-ring-width) + 2px);
23
23
  position: relative;
24
24
  width: 100%;
25
25
  --_gap: var(--vaadin-menu-bar-gap, 0px);
26
26
  --_bw: var(--vaadin-button-border-width, 1px);
27
27
  gap: var(--_gap);
28
28
  --_rad-button: var(--vaadin-button-border-radius, var(--vaadin-radius-m));
29
- --_rad: min(var(--_gap) * 1000, var(--_rad-button));
30
29
  }
31
30
 
32
31
  ::slotted(vaadin-menu-bar-button:not(:first-of-type)) {
@@ -34,16 +33,18 @@ export const menuBarStyles = css`
34
33
  }
35
34
 
36
35
  ::slotted(vaadin-menu-bar-button) {
37
- border-radius: var(--_rad);
36
+ border-radius: 0;
38
37
  }
39
38
 
40
39
  ::slotted([first-visible]),
41
- :host([has-single-button]) ::slotted([slot='overflow']) {
40
+ :host([has-single-button]) ::slotted([slot='overflow']),
41
+ ::slotted(vaadin-menu-bar-button[theme~='tertiary']) {
42
42
  border-start-start-radius: var(--_rad-button);
43
43
  border-end-start-radius: var(--_rad-button);
44
44
  }
45
45
 
46
- ::slotted(:is([last-visible], [slot='overflow'])) {
46
+ ::slotted(:is([last-visible], [slot='overflow'])),
47
+ ::slotted(vaadin-menu-bar-button[theme~='tertiary']) {
47
48
  border-start-end-radius: var(--_rad-button);
48
49
  border-end-end-radius: var(--_rad-button);
49
50
  }
@@ -32,7 +32,7 @@ export const menuBarButtonStyles = css`
32
32
  background: currentColor;
33
33
  content: '';
34
34
  height: var(--vaadin-icon-size, 1lh);
35
- mask-image: var(--_vaadin-icon-chevron-down);
35
+ mask: var(--_vaadin-icon-chevron-down) 50% / var(--vaadin-icon-visual-size, 100%) no-repeat;
36
36
  width: var(--vaadin-icon-size, 1lh);
37
37
  }
38
38
 
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2019 - 2025 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { Button } from '@vaadin/button/src/vaadin-button.js';
7
+
8
+ /**
9
+ * An element used internally by `<vaadin-menu-bar>`. Not intended to be used separately.
10
+ */
11
+ declare class MenuBarButton extends Button {}
12
+
13
+ declare global {
14
+ interface HTMLElementTagNameMap {
15
+ 'vaadin-menu-bar-button': MenuBarButton;
16
+ }
17
+ }
18
+
19
+ export { MenuBarButton };
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { Button } from '@vaadin/button/src/vaadin-button.js';
7
7
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
8
- import { menuBarButtonStyles } from './styles/vaadin-menu-bar-button-core-styles.js';
8
+ import { menuBarButtonStyles } from './styles/vaadin-menu-bar-button-base-styles.js';
9
9
 
10
10
  /**
11
11
  * An element used internally by `<vaadin-menu-bar>`. Not intended to be used separately.
@@ -54,3 +54,5 @@ class MenuBarButton extends Button {
54
54
  }
55
55
 
56
56
  defineCustomElement(MenuBarButton);
57
+
58
+ export { MenuBarButton };
@@ -10,7 +10,7 @@ import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
10
10
  import { ItemMixin } from '@vaadin/item/src/vaadin-item-mixin.js';
11
11
  import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
12
12
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
13
- import { menuBarItemStyles } from './styles/vaadin-menu-bar-item-core-styles.js';
13
+ import { menuBarItemStyles } from './styles/vaadin-menu-bar-item-base-styles.js';
14
14
 
15
15
  /**
16
16
  * An element used internally by `<vaadin-menu-bar>`. Not intended to be used separately.
@@ -8,7 +8,7 @@ import { ListMixin } from '@vaadin/a11y-base/src/list-mixin.js';
8
8
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
9
9
  import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
10
10
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
11
- import { listBoxStyles } from '@vaadin/list-box/src/styles/vaadin-list-box-core-styles.js';
11
+ import { listBoxStyles } from '@vaadin/list-box/src/styles/vaadin-list-box-base-styles.js';
12
12
  import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
13
13
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
14
14
 
@@ -10,6 +10,7 @@ import type { KeyboardDirectionMixinClass } from '@vaadin/a11y-base/src/keyboard
10
10
  import type { KeyboardMixinClass } from '@vaadin/a11y-base/src/keyboard-mixin.js';
11
11
  import type { I18nMixinClass } from '@vaadin/component-base/src/i18n-mixin.js';
12
12
  import type { ResizeMixinClass } from '@vaadin/component-base/src/resize-mixin.js';
13
+ import type { MenuBarButton } from './vaadin-menu-bar-button.js';
13
14
 
14
15
  export type MenuBarItem<TItemData extends object = object> = {
15
16
  /**
@@ -113,7 +114,7 @@ export declare class MenuBarMixinClass<TItem extends MenuBarItem = MenuBarItem>
113
114
  * which makes disabled buttons focusable and hoverable, while still
114
115
  * preventing them from being triggered:
115
116
  *
116
- * ```
117
+ * ```js
117
118
  * // Set before any menu bar is attached to the DOM.
118
119
  * window.Vaadin.featureFlags.accessibleDisabledButtons = true;
119
120
  * ```
@@ -126,7 +127,7 @@ export declare class MenuBarMixinClass<TItem extends MenuBarItem = MenuBarItem>
126
127
  * just the individual properties you want to change.
127
128
  *
128
129
  * The object has the following JSON structure and default values:
129
- * ```
130
+ * ```js
130
131
  * {
131
132
  * moreOptions: 'More options'
132
133
  * }
@@ -134,14 +135,6 @@ export declare class MenuBarMixinClass<TItem extends MenuBarItem = MenuBarItem>
134
135
  */
135
136
  i18n: MenuBarI18n;
136
137
 
137
- /**
138
- * A space-delimited list of CSS class names
139
- * to set on each sub-menu overlay element.
140
- *
141
- * @attr {string} overlay-class
142
- */
143
- overlayClass: string;
144
-
145
138
  /**
146
139
  * If true, the submenu will open on hover (mouseover) instead of click.
147
140
  * @attr {boolean} open-on-hover
@@ -167,11 +160,11 @@ export declare class MenuBarMixinClass<TItem extends MenuBarItem = MenuBarItem>
167
160
  */
168
161
  close(): void;
169
162
 
170
- protected readonly _buttons: HTMLElement[];
163
+ protected readonly _buttons: MenuBarButton[];
171
164
 
172
165
  protected readonly _container: HTMLElement;
173
166
 
174
- protected readonly _overflow: HTMLElement;
167
+ protected readonly _overflow: MenuBarButton;
175
168
 
176
169
  protected _hasOverflow: boolean;
177
170
  }
@@ -76,10 +76,10 @@ export const MenuBarMixin = (superClass) =>
76
76
  * @property {string} text - Text to be set as the menu button component's textContent.
77
77
  * @property {string} tooltip - Text to be set as the menu button's tooltip.
78
78
  * Requires a `<vaadin-tooltip slot="tooltip">` element to be added inside the `<vaadin-menu-bar>`.
79
- * @property {union: string | object} component - The component to represent the button content.
79
+ * @property {string | HTMLElement} component - The component to represent the button content.
80
80
  * Either a tagName or an element instance. Defaults to "vaadin-menu-bar-item".
81
81
  * @property {boolean} disabled - If true, the button is disabled and cannot be activated.
82
- * @property {union: string | string[]} theme - Theme(s) to be set as the theme attribute of the button, overriding any theme set on the menu bar.
82
+ * @property {string | string[]} theme - Theme(s) to be set as the theme attribute of the button, overriding any theme set on the menu bar.
83
83
  * @property {SubMenuItem[]} children - Array of submenu items.
84
84
  */
85
85
 
@@ -87,7 +87,7 @@ export const MenuBarMixin = (superClass) =>
87
87
  * @typedef SubMenuItem
88
88
  * @type {object}
89
89
  * @property {string} text - Text to be set as the menu item component's textContent.
90
- * @property {union: string | object} component - The component to represent the item.
90
+ * @property {string | HTMLElement} component - The component to represent the item.
91
91
  * Either a tagName or an element instance. Defaults to "vaadin-menu-bar-item".
92
92
  * @property {boolean} disabled - If true, the item is disabled and cannot be selected.
93
93
  * @property {boolean} checked - If true, the item shows a checkmark next to it.
@@ -136,12 +136,7 @@ export const MenuBarMixin = (superClass) =>
136
136
  * which makes disabled buttons focusable and hoverable, while still
137
137
  * preventing them from being triggered:
138
138
  *
139
- * ```
140
- * // Set before any menu bar is attached to the DOM.
141
- * window.Vaadin.featureFlags.accessibleDisabledButtons = true;
142
- * ```
143
- *
144
- * ```
139
+ * ```js
145
140
  * // Set before any menu bar is attached to the DOM.
146
141
  * window.Vaadin.featureFlags.accessibleDisabledButtons = true;
147
142
  * ```
@@ -154,16 +149,6 @@ export const MenuBarMixin = (superClass) =>
154
149
  value: () => [],
155
150
  },
156
151
 
157
- /**
158
- * A space-delimited list of CSS class names
159
- * to set on each sub-menu overlay element.
160
- *
161
- * @attr {string} overlay-class
162
- */
163
- overlayClass: {
164
- type: String,
165
- },
166
-
167
152
  /**
168
153
  * If true, the submenu will open on hover (mouseover) instead of click.
169
154
  * @attr {boolean} open-on-hover
@@ -200,7 +185,7 @@ export const MenuBarMixin = (superClass) =>
200
185
  * just the individual properties you want to change.
201
186
  *
202
187
  * The object has the following JSON structure and default values:
203
- * ```
188
+ * ```js
204
189
  * {
205
190
  * moreOptions: 'More options'
206
191
  * }
@@ -348,10 +333,6 @@ export const MenuBarMixin = (superClass) =>
348
333
  this.__updateSubMenu();
349
334
  }
350
335
 
351
- if (props.has('overlayClass')) {
352
- this._subMenu.overlayClass = this.overlayClass;
353
- }
354
-
355
336
  if (props.has('_theme')) {
356
337
  this._themeChanged(this._theme);
357
338
  }
@@ -428,7 +409,7 @@ export const MenuBarMixin = (superClass) =>
428
409
  __updateSubMenu() {
429
410
  const subMenu = this._subMenu;
430
411
  if (subMenu && subMenu.opened) {
431
- const button = subMenu._overlayElement.positionTarget;
412
+ const button = subMenu._positionTarget;
432
413
 
433
414
  // Close sub-menu if the corresponding button is no longer in the DOM,
434
415
  // or if the item on it has been changed to no longer have children.
@@ -712,17 +693,18 @@ export const MenuBarMixin = (superClass) =>
712
693
  * and open another one for the newly focused button.
713
694
  *
714
695
  * @param {Element} item
696
+ * @param {FocusOptions=} options
715
697
  * @param {boolean} navigating
716
698
  * @protected
717
699
  * @override
718
700
  */
719
- _focusItem(item, navigating) {
701
+ _focusItem(item, options, navigating) {
720
702
  const wasExpanded = navigating && this.focused === this._expandedButton;
721
703
  if (wasExpanded) {
722
704
  this._close();
723
705
  }
724
706
 
725
- super._focusItem(item, navigating);
707
+ super._focusItem(item, options, navigating);
726
708
 
727
709
  this._buttons.forEach((btn) => {
728
710
  this._setTabindex(btn, btn === item);
@@ -779,7 +761,8 @@ export const MenuBarMixin = (superClass) =>
779
761
  */
780
762
  _setFocused(focused) {
781
763
  if (focused) {
782
- const target = this.tabNavigation ? this.querySelector('[focused]') : this.querySelector('[tabindex="0"]');
764
+ const selector = this.tabNavigation ? '[focused]' : '[tabindex="0"]';
765
+ const target = this.querySelector(`vaadin-menu-bar-button${selector}`);
783
766
  if (target) {
784
767
  this._buttons.forEach((btn) => {
785
768
  this._setTabindex(btn, btn === target);
@@ -890,11 +873,11 @@ export const MenuBarMixin = (superClass) =>
890
873
  // Hide tooltip on mouseover to disabled button
891
874
  this._hideTooltip();
892
875
  } else if (button !== this._expandedButton) {
893
- const isOpened = this._subMenu.opened;
894
- if (button.item.children && (this.openOnHover || isOpened)) {
876
+ // Switch sub-menu when moving cursor over another button
877
+ // with children, regardless of whether openOnHover is set.
878
+ // If the button has no children, keep the sub-menu opened.
879
+ if (button.item.children && (this.openOnHover || this._subMenu.opened)) {
895
880
  this.__openSubMenu(button, false);
896
- } else if (isOpened) {
897
- this._close();
898
881
  }
899
882
 
900
883
  if (button === this._overflow || (this.openOnHover && button.item.children)) {
@@ -963,6 +946,7 @@ export const MenuBarMixin = (superClass) =>
963
946
 
964
947
  subMenu.items = items;
965
948
  subMenu.listenOn = button;
949
+ subMenu._positionTarget = button;
966
950
  const overlay = subMenu._overlayElement;
967
951
  overlay.noVerticalOverlap = true;
968
952
 
@@ -972,7 +956,6 @@ export const MenuBarMixin = (superClass) =>
972
956
  this._setExpanded(button, true);
973
957
 
974
958
  this.style.pointerEvents = 'auto';
975
- overlay.positionTarget = button;
976
959
 
977
960
  button.dispatchEvent(
978
961
  new CustomEvent('opensubmenu', {
@@ -990,7 +973,8 @@ export const MenuBarMixin = (superClass) =>
990
973
  }
991
974
 
992
975
  if (options.keepFocus) {
993
- this._focusItem(this._expandedButton, false);
976
+ const focusOptions = { focusVisible: isKeyboardActive() };
977
+ this._focusItem(this._expandedButton, focusOptions, false);
994
978
  }
995
979
 
996
980
  // Do not focus item when open not from keyboard
@@ -1034,7 +1018,8 @@ export const MenuBarMixin = (superClass) =>
1034
1018
  if (button && button.hasAttribute('expanded')) {
1035
1019
  this._setExpanded(button, false);
1036
1020
  if (restoreFocus) {
1037
- this._focusItem(button, false);
1021
+ const focusOptions = { focusVisible: isKeyboardActive() };
1022
+ this._focusItem(button, focusOptions, false);
1038
1023
  }
1039
1024
  this._expandedButton = null;
1040
1025
  }
@@ -11,7 +11,7 @@ import { MenuOverlayMixin } from '@vaadin/context-menu/src/vaadin-menu-overlay-m
11
11
  import { OverlayMixin } from '@vaadin/overlay/src/vaadin-overlay-mixin.js';
12
12
  import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
13
13
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
14
- import { menuBarOverlayStyles } from './styles/vaadin-menu-bar-overlay-core-styles.js';
14
+ import { menuBarOverlayStyles } from './styles/vaadin-menu-bar-overlay-base-styles.js';
15
15
 
16
16
  /**
17
17
  * An element used internally by `<vaadin-menu-bar>`. Not intended to be used separately.
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2019 - 2025 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { ContextMenuMixin } from '@vaadin/context-menu/src/vaadin-context-menu-mixin.js';
7
+ import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
8
+
9
+ /**
10
+ * An element used internally by `<vaadin-menu-bar>`. Not intended to be used separately.
11
+ */
12
+ declare class MenuBarSubmenu extends ContextMenuMixin(ThemePropertyMixin(HTMLElement)) {}
13
+
14
+ declare global {
15
+ interface HTMLElementTagNameMap {
16
+ 'vaadin-menu-bar-submenu': MenuBarSubmenu;
17
+ }
18
+ }
19
+
20
+ export { MenuBarSubmenu };
@@ -10,19 +10,19 @@ 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
12
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
13
+ import { ContextMenuMixin } from '@vaadin/context-menu/src/vaadin-context-menu-mixin.js';
13
14
  import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
14
- import { SubMenuMixin } from './vaadin-menu-bar-submenu-mixin.js';
15
15
 
16
16
  /**
17
17
  * An element used internally by `<vaadin-menu-bar>`. Not intended to be used separately.
18
18
  *
19
19
  * @customElement
20
20
  * @extends HTMLElement
21
- * @mixes SubMenuMixin
21
+ * @mixes ContextMenuMixin
22
22
  * @mixes ThemePropertyMixin
23
23
  * @protected
24
24
  */
25
- class MenuBarSubmenu extends SubMenuMixin(ThemePropertyMixin(PolylitMixin(LitElement))) {
25
+ class MenuBarSubmenu extends ContextMenuMixin(ThemePropertyMixin(PolylitMixin(LitElement))) {
26
26
  static get is() {
27
27
  return 'vaadin-menu-bar-submenu';
28
28
  }
@@ -39,6 +39,31 @@ class MenuBarSubmenu extends SubMenuMixin(ThemePropertyMixin(PolylitMixin(LitEle
39
39
  `;
40
40
  }
41
41
 
42
+ static get properties() {
43
+ return {
44
+ isRoot: {
45
+ type: Boolean,
46
+ reflectToAttribute: true,
47
+ sync: true,
48
+ },
49
+ };
50
+ }
51
+
52
+ constructor() {
53
+ super();
54
+
55
+ this.openOn = 'opensubmenu';
56
+ }
57
+
58
+ /**
59
+ * Tag name prefix used by overlay, list-box and items.
60
+ * @protected
61
+ * @return {string}
62
+ */
63
+ get _tagNamePrefix() {
64
+ return 'vaadin-menu-bar';
65
+ }
66
+
42
67
  /** @protected */
43
68
  render() {
44
69
  return html`
@@ -50,6 +75,8 @@ class MenuBarSubmenu extends SubMenuMixin(ThemePropertyMixin(PolylitMixin(LitEle
50
75
  .modeless="${this._modeless}"
51
76
  .renderer="${this.__itemsRenderer}"
52
77
  .withBackdrop="${this._phone}"
78
+ .positionTarget="${this._positionTarget}"
79
+ ?no-horizontal-overlap="${!this.isRoot}"
53
80
  ?phone="${this._phone}"
54
81
  theme="${ifDefined(this._theme)}"
55
82
  exportparts="backdrop, overlay, content"
@@ -61,6 +88,45 @@ class MenuBarSubmenu extends SubMenuMixin(ThemePropertyMixin(PolylitMixin(LitEle
61
88
  </vaadin-menu-bar-overlay>
62
89
  `;
63
90
  }
91
+
92
+ /**
93
+ * Overriding the observer to not add global "contextmenu" listener.
94
+ * @override
95
+ */
96
+ _openedChanged() {
97
+ // Do nothing
98
+ }
99
+
100
+ /**
101
+ * Overriding the public method to reset expanded button state.
102
+ */
103
+ close() {
104
+ super.close();
105
+
106
+ // Only handle 1st level submenu
107
+ if (this.hasAttribute('is-root')) {
108
+ this.parentElement._close();
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Override method from `ContextMenuMixin` to prevent closing
114
+ * sub-menu on the same click event that was used to open it.
115
+ *
116
+ * @param {Event} event
117
+ * @return {boolean}
118
+ * @protected
119
+ * @override
120
+ */
121
+ _shouldCloseOnOutsideClick(event) {
122
+ if (this.hasAttribute('is-root') && event.composedPath().includes(this.listenOn)) {
123
+ return false;
124
+ }
125
+
126
+ return super._shouldCloseOnOutsideClick(event);
127
+ }
64
128
  }
65
129
 
66
130
  defineCustomElement(MenuBarSubmenu);
131
+
132
+ export { MenuBarSubmenu };
@@ -12,7 +12,7 @@ import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
12
12
  import { TooltipController } from '@vaadin/component-base/src/tooltip-controller.js';
13
13
  import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
14
14
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
15
- import { menuBarStyles } from './styles/vaadin-menu-bar-core-styles.js';
15
+ import { menuBarStyles } from './styles/vaadin-menu-bar-base-styles.js';
16
16
  import { MenuBarMixin } from './vaadin-menu-bar-mixin.js';
17
17
 
18
18
  /**
@@ -1,2 +1,2 @@
1
- import './theme/lumo/vaadin-menu-bar.js';
1
+ import './src/vaadin-menu-bar.js';
2
2
  export * from './src/vaadin-menu-bar.js';
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.0.0-alpha9",
4
+ "version": "25.0.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```html\n<vaadin-menu-bar></vaadin-menu-bar>\n```\n\nAnd then use [`items`](https://cdn.vaadin.com/vaadin-web-components/25.0.0-alpha9/#/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.0.0-alpha9/#/elements/vaadin-button).\n- `<vaadin-menu-bar-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.0.0-alpha9/#/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.0.0-alpha9/#/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.0.0-alpha9/#/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.0.0-beta1/#/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.0.0-beta1/#/elements/vaadin-button).\n- `<vaadin-menu-bar-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.0.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/25.0.0-beta1/#/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.0.0-beta1/#/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",
@@ -30,17 +30,6 @@
30
30
  ]
31
31
  }
32
32
  },
33
- {
34
- "name": "overlay-class",
35
- "description": "A space-delimited list of CSS class names\nto set on each sub-menu overlay element.",
36
- "value": {
37
- "type": [
38
- "string",
39
- "null",
40
- "undefined"
41
- ]
42
- }
43
- },
44
33
  {
45
34
  "name": "open-on-hover",
46
35
  "description": "If true, the submenu will open on hover (mouseover) instead of click.",
@@ -101,7 +90,7 @@
101
90
  },
102
91
  {
103
92
  "name": "i18n",
104
- "description": "The object used to localize this component. To change the default\nlocalization, replace this with an object that provides all properties, or\njust the individual properties you want to change.\n\nThe object has the following JSON structure and default values:\n```\n{\n moreOptions: 'More options'\n}\n```",
93
+ "description": "The object used to localize this component. To change the default\nlocalization, replace this with an object that provides all properties, or\njust the individual properties you want to change.\n\nThe object has the following JSON structure and default values:\n```js\n{\n moreOptions: 'More options'\n}\n```",
105
94
  "value": {
106
95
  "type": [
107
96
  "MenuBarI18n"
@@ -110,24 +99,13 @@
110
99
  },
111
100
  {
112
101
  "name": "items",
113
- "description": "Defines a hierarchical structure, where root level items represent menu bar buttons,\nand `children` property configures a submenu with items to be opened below\nthe button on click, Enter, Space, Up and Down arrow keys.\n\n#### Example\n\n```js\nmenubar.items = [\n {\n text: 'File',\n className: 'file',\n children: [\n {text: 'Open', className: 'file open'}\n {text: 'Auto Save', checked: true},\n ]\n },\n {component: 'hr'},\n {\n text: 'Edit',\n children: [\n {text: 'Undo', disabled: true},\n {text: 'Redo'}\n ]\n },\n {text: 'Help'}\n];\n```\n\n#### Disabled buttons\n\nWhen disabled, menu bar buttons (root-level items) are rendered\nas \"dimmed\" and prevent all user interactions (mouse and keyboard).\n\nSince disabled buttons are not focusable and cannot react to hover\nevents by default, it can cause accessibility issues by making them\nentirely invisible to assistive technologies, and prevents the use\nof Tooltips to explain why the action is not available. This can be\naddressed by enabling the feature flag `accessibleDisabledButtons`,\nwhich makes disabled buttons focusable and hoverable, while still\npreventing them from being triggered:\n\n```\n// Set before any menu bar is attached to the DOM.\nwindow.Vaadin.featureFlags.accessibleDisabledButtons = true;\n```\n```\n// Set before any menu bar is attached to the DOM.\nwindow.Vaadin.featureFlags.accessibleDisabledButtons = true;\n```",
102
+ "description": "Defines a hierarchical structure, where root level items represent menu bar buttons,\nand `children` property configures a submenu with items to be opened below\nthe button on click, Enter, Space, Up and Down arrow keys.\n\n#### Example\n\n```js\nmenubar.items = [\n {\n text: 'File',\n className: 'file',\n children: [\n {text: 'Open', className: 'file open'}\n {text: 'Auto Save', checked: true},\n ]\n },\n {component: 'hr'},\n {\n text: 'Edit',\n children: [\n {text: 'Undo', disabled: true},\n {text: 'Redo'}\n ]\n },\n {text: 'Help'}\n];\n```\n\n#### Disabled buttons\n\nWhen disabled, menu bar buttons (root-level items) are rendered\nas \"dimmed\" and prevent all user interactions (mouse and keyboard).\n\nSince disabled buttons are not focusable and cannot react to hover\nevents by default, it can cause accessibility issues by making them\nentirely invisible to assistive technologies, and prevents the use\nof Tooltips to explain why the action is not available. This can be\naddressed by enabling the feature flag `accessibleDisabledButtons`,\nwhich makes disabled buttons focusable and hoverable, while still\npreventing them from being triggered:\n\n```js\n// Set before any menu bar is attached to the DOM.\nwindow.Vaadin.featureFlags.accessibleDisabledButtons = true;\n```",
114
103
  "value": {
115
104
  "type": [
116
105
  "Array.<MenuBarItem>"
117
106
  ]
118
107
  }
119
108
  },
120
- {
121
- "name": "overlayClass",
122
- "description": "A space-delimited list of CSS class names\nto set on each sub-menu overlay element.",
123
- "value": {
124
- "type": [
125
- "string",
126
- "null",
127
- "undefined"
128
- ]
129
- }
130
- },
131
109
  {
132
110
  "name": "openOnHover",
133
111
  "description": "If true, the submenu will open on hover (mouseover) instead of click.",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/menu-bar",
4
- "version": "25.0.0-alpha9",
4
+ "version": "25.0.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```html\n<vaadin-menu-bar></vaadin-menu-bar>\n```\n\nAnd then use [`items`](https://cdn.vaadin.com/vaadin-web-components/25.0.0-alpha9/#/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.0.0-alpha9/#/elements/vaadin-button).\n- `<vaadin-menu-bar-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.0.0-alpha9/#/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.0.0-alpha9/#/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.0.0-alpha9/#/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.0.0-beta1/#/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.0.0-beta1/#/elements/vaadin-button).\n- `<vaadin-menu-bar-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.0.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/25.0.0-beta1/#/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.0.0-beta1/#/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
  {
@@ -49,21 +49,14 @@
49
49
  },
50
50
  {
51
51
  "name": ".i18n",
52
- "description": "The object used to localize this component. To change the default\nlocalization, replace this with an object that provides all properties, or\njust the individual properties you want to change.\n\nThe object has the following JSON structure and default values:\n```\n{\n moreOptions: 'More options'\n}\n```",
52
+ "description": "The object used to localize this component. To change the default\nlocalization, replace this with an object that provides all properties, or\njust the individual properties you want to change.\n\nThe object has the following JSON structure and default values:\n```js\n{\n moreOptions: 'More options'\n}\n```",
53
53
  "value": {
54
54
  "kind": "expression"
55
55
  }
56
56
  },
57
57
  {
58
58
  "name": ".items",
59
- "description": "Defines a hierarchical structure, where root level items represent menu bar buttons,\nand `children` property configures a submenu with items to be opened below\nthe button on click, Enter, Space, Up and Down arrow keys.\n\n#### Example\n\n```js\nmenubar.items = [\n {\n text: 'File',\n className: 'file',\n children: [\n {text: 'Open', className: 'file open'}\n {text: 'Auto Save', checked: true},\n ]\n },\n {component: 'hr'},\n {\n text: 'Edit',\n children: [\n {text: 'Undo', disabled: true},\n {text: 'Redo'}\n ]\n },\n {text: 'Help'}\n];\n```\n\n#### Disabled buttons\n\nWhen disabled, menu bar buttons (root-level items) are rendered\nas \"dimmed\" and prevent all user interactions (mouse and keyboard).\n\nSince disabled buttons are not focusable and cannot react to hover\nevents by default, it can cause accessibility issues by making them\nentirely invisible to assistive technologies, and prevents the use\nof Tooltips to explain why the action is not available. This can be\naddressed by enabling the feature flag `accessibleDisabledButtons`,\nwhich makes disabled buttons focusable and hoverable, while still\npreventing them from being triggered:\n\n```\n// Set before any menu bar is attached to the DOM.\nwindow.Vaadin.featureFlags.accessibleDisabledButtons = true;\n```\n```\n// Set before any menu bar is attached to the DOM.\nwindow.Vaadin.featureFlags.accessibleDisabledButtons = true;\n```",
60
- "value": {
61
- "kind": "expression"
62
- }
63
- },
64
- {
65
- "name": ".overlayClass",
66
- "description": "A space-delimited list of CSS class names\nto set on each sub-menu overlay element.",
59
+ "description": "Defines a hierarchical structure, where root level items represent menu bar buttons,\nand `children` property configures a submenu with items to be opened below\nthe button on click, Enter, Space, Up and Down arrow keys.\n\n#### Example\n\n```js\nmenubar.items = [\n {\n text: 'File',\n className: 'file',\n children: [\n {text: 'Open', className: 'file open'}\n {text: 'Auto Save', checked: true},\n ]\n },\n {component: 'hr'},\n {\n text: 'Edit',\n children: [\n {text: 'Undo', disabled: true},\n {text: 'Redo'}\n ]\n },\n {text: 'Help'}\n];\n```\n\n#### Disabled buttons\n\nWhen disabled, menu bar buttons (root-level items) are rendered\nas \"dimmed\" and prevent all user interactions (mouse and keyboard).\n\nSince disabled buttons are not focusable and cannot react to hover\nevents by default, it can cause accessibility issues by making them\nentirely invisible to assistive technologies, and prevents the use\nof Tooltips to explain why the action is not available. This can be\naddressed by enabling the feature flag `accessibleDisabledButtons`,\nwhich makes disabled buttons focusable and hoverable, while still\npreventing them from being triggered:\n\n```js\n// Set before any menu bar is attached to the DOM.\nwindow.Vaadin.featureFlags.accessibleDisabledButtons = true;\n```",
67
60
  "value": {
68
61
  "kind": "expression"
69
62
  }
@@ -1,8 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2019 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import type { CSSResult } from 'lit';
7
-
8
- export const menuBarButtonStyles: CSSResult;
@@ -1,16 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2019 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import { css } from 'lit';
7
-
8
- export const menuBarButtonStyles = css`
9
- :host {
10
- flex-shrink: 0;
11
- }
12
-
13
- :host([slot='overflow']) {
14
- margin-inline-end: 0;
15
- }
16
- `;
@@ -1,8 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2019 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import type { CSSResult } from 'lit';
7
-
8
- export const menuBarStyles: CSSResult;
@@ -1,24 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2019 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import { css } from 'lit';
7
-
8
- export const menuBarStyles = css`
9
- :host {
10
- display: block;
11
- }
12
-
13
- :host([hidden]) {
14
- display: none !important;
15
- }
16
-
17
- [part='container'] {
18
- position: relative;
19
- display: flex;
20
- width: 100%;
21
- flex-wrap: nowrap;
22
- overflow: hidden;
23
- }
24
- `;
@@ -1,8 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2019 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import type { CSSResult } from 'lit';
7
-
8
- export const menuBarItemStyles: CSSResult;
@@ -1,8 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2019 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import { itemStyles } from '@vaadin/item/src/styles/vaadin-item-core-styles.js';
7
-
8
- export const menuBarItemStyles = [itemStyles];
@@ -1,8 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2019 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import type { CSSResult } from 'lit';
7
-
8
- export const menuBarOverlayStyles: CSSResult;
@@ -1,9 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2019 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import { menuOverlayStyles } from '@vaadin/context-menu/src/styles/vaadin-menu-overlay-core-styles.js';
7
- import { overlayStyles } from '@vaadin/overlay/src/styles/vaadin-overlay-core-styles.js';
8
-
9
- export const menuBarOverlayStyles = [overlayStyles, menuOverlayStyles];
@@ -1,66 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright (c) 2019 - 2025 Vaadin Ltd.
4
- * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
- */
6
- import { OverlayClassMixin } from '@vaadin/component-base/src/overlay-class-mixin.js';
7
- import { ContextMenuMixin } from '@vaadin/context-menu/src/vaadin-context-menu-mixin.js';
8
-
9
- /**
10
- * @polymerMixin
11
- * @mixes ContextMenuMixin
12
- * @mixes OverlayClassMixin
13
- */
14
- export const SubMenuMixin = (superClass) =>
15
- class SubMenuMixinClass extends ContextMenuMixin(OverlayClassMixin(superClass)) {
16
- constructor() {
17
- super();
18
-
19
- this.openOn = 'opensubmenu';
20
- }
21
-
22
- /**
23
- * Tag name prefix used by overlay, list-box and items.
24
- * @protected
25
- * @return {string}
26
- */
27
- get _tagNamePrefix() {
28
- return 'vaadin-menu-bar';
29
- }
30
-
31
- /**
32
- * Overriding the observer to not add global "contextmenu" listener.
33
- */
34
- _openedChanged() {
35
- // Do nothing
36
- }
37
-
38
- /**
39
- * Overriding the public method to reset expanded button state.
40
- */
41
- close() {
42
- super.close();
43
-
44
- // Only handle 1st level submenu
45
- if (this.hasAttribute('is-root')) {
46
- this.parentElement._close();
47
- }
48
- }
49
-
50
- /**
51
- * Override method from `ContextMenuMixin` to prevent closing
52
- * sub-menu on the same click event that was used to open it.
53
- *
54
- * @param {Event} event
55
- * @return {boolean}
56
- * @protected
57
- * @override
58
- */
59
- _shouldCloseOnOutsideClick(event) {
60
- if (this.hasAttribute('is-root') && event.composedPath().includes(this.listenOn)) {
61
- return false;
62
- }
63
-
64
- return super._shouldCloseOnOutsideClick(event);
65
- }
66
- };
@@ -1 +0,0 @@
1
- export {};
@@ -1,128 +0,0 @@
1
- import { button } from '@vaadin/button/theme/lumo/vaadin-button-styles.js';
2
- import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
3
-
4
- const menuBarButton = css`
5
- :host {
6
- margin: calc(var(--lumo-space-xs) / 2);
7
- margin-left: 0;
8
- border-radius: 0;
9
- }
10
-
11
- [part='label'] {
12
- width: 100%;
13
- }
14
-
15
- /* NOTE(web-padawan): avoid using shorthand padding property for IE11 */
16
- [part='label'] ::slotted(vaadin-menu-bar-item) {
17
- justify-content: center;
18
- background-color: transparent;
19
- height: var(--lumo-button-size);
20
- margin: 0 calc((var(--lumo-size-m) / 3 + var(--lumo-border-radius-m) / 2) * -1);
21
- padding-left: calc(var(--lumo-size-m) / 3 + var(--lumo-border-radius-m) / 2);
22
- padding-right: calc(var(--lumo-size-m) / 3 + var(--lumo-border-radius-m) / 2);
23
- }
24
-
25
- :host([theme~='small']) [part='label'] ::slotted(vaadin-menu-bar-item) {
26
- min-height: var(--lumo-size-s);
27
- margin: 0 calc((var(--lumo-size-s) / 3 + var(--lumo-border-radius-m) / 2) * -1);
28
- padding-left: calc(var(--lumo-size-s) / 3 + var(--lumo-border-radius-m) / 2);
29
- padding-right: calc(var(--lumo-size-s) / 3 + var(--lumo-border-radius-m) / 2);
30
- }
31
-
32
- :host([theme~='tertiary']) [part='label'] ::slotted(vaadin-menu-bar-item) {
33
- margin: 0 calc((var(--lumo-button-size) / 6) * -1);
34
- padding-left: calc(var(--lumo-button-size) / 6);
35
- padding-right: calc(var(--lumo-button-size) / 6);
36
- }
37
-
38
- :host([theme~='tertiary-inline']) {
39
- margin-top: calc(var(--lumo-space-xs) / 2);
40
- margin-bottom: calc(var(--lumo-space-xs) / 2);
41
- margin-right: calc(var(--lumo-space-xs) / 2);
42
- }
43
-
44
- :host([theme~='tertiary-inline']) [part='label'] ::slotted(vaadin-menu-bar-item) {
45
- margin: 0;
46
- padding: 0;
47
- }
48
-
49
- :host([first-visible]) {
50
- border-radius: var(--lumo-border-radius-m) 0 0 var(--lumo-border-radius-m);
51
-
52
- /* Needed to retain the focus-ring with border-radius */
53
- margin-left: calc(var(--lumo-space-xs) / 2);
54
- }
55
-
56
- :host([last-visible]),
57
- :host([slot='overflow']) {
58
- border-radius: 0 var(--lumo-border-radius-m) var(--lumo-border-radius-m) 0;
59
- }
60
-
61
- :host([theme~='tertiary']),
62
- :host([theme~='tertiary-inline']) {
63
- border-radius: var(--lumo-border-radius-m);
64
- }
65
-
66
- :host([slot='overflow']) {
67
- min-width: var(--lumo-button-size);
68
- padding-left: calc(var(--lumo-button-size) / 4);
69
- padding-right: calc(var(--lumo-button-size) / 4);
70
- }
71
-
72
- :host([slot='overflow']) ::slotted(*) {
73
- font-size: var(--lumo-font-size-xl);
74
- }
75
-
76
- :host([slot='overflow']) [part='prefix'],
77
- :host([slot='overflow']) [part='suffix'] {
78
- margin-left: 0;
79
- margin-right: 0;
80
- }
81
-
82
- :host([theme~='dropdown-indicators']:not([slot='overflow']):not([theme~='icon'])[aria-haspopup]) [part='suffix'] {
83
- margin-inline-start: 0;
84
- width: 1em;
85
- height: 1em;
86
- line-height: 1;
87
- font-size: var(--lumo-icon-size-s);
88
- position: relative;
89
- inset-inline-start: 0.15em;
90
- }
91
-
92
- /* prettier-ignore */
93
- :host([theme~='dropdown-indicators']:not([slot='overflow']):not([theme~='icon'])[aria-haspopup]) [part='suffix']::after {
94
- font-family: lumo-icons;
95
- content: var(--lumo-icons-dropdown);
96
- }
97
-
98
- /* prettier-ignore */
99
- :host([theme~='dropdown-indicators']:not([slot='overflow']):not([theme~='icon'])[theme~='tertiary'][aria-haspopup]) [part='suffix'] {
100
- inset-inline-start: 0.05em;
101
- }
102
-
103
- /* prettier-ignore */
104
- :host([theme~='dropdown-indicators']:not([slot='overflow']):not([theme~='icon'])[theme~='tertiary-inline'][aria-haspopup]) [part='suffix'] {
105
- inset-inline-start: 0;
106
- }
107
-
108
- /* RTL styles */
109
- :host([dir='rtl']) {
110
- margin-left: calc(var(--lumo-space-xs) / 2);
111
- margin-right: 0;
112
- border-radius: 0;
113
- }
114
-
115
- :host([dir='rtl'][first-visible]) {
116
- border-radius: 0 var(--lumo-border-radius-m) var(--lumo-border-radius-m) 0;
117
- margin-right: calc(var(--lumo-space-xs) / 2);
118
- }
119
-
120
- :host([dir='rtl'][last-visible]),
121
- :host([dir='rtl'][slot='overflow']) {
122
- border-radius: var(--lumo-border-radius-m) 0 0 var(--lumo-border-radius-m);
123
- }
124
- `;
125
-
126
- registerStyles('vaadin-menu-bar-button', [button, menuBarButton], {
127
- moduleId: 'lumo-menu-bar-button',
128
- });
@@ -1,2 +0,0 @@
1
- import './vaadin-menu-bar-button-styles.js';
2
- import '../../src/vaadin-menu-bar-button.js';
@@ -1,2 +0,0 @@
1
- import './vaadin-menu-bar-button-styles.js';
2
- import '../../src/vaadin-menu-bar-button.js';
@@ -1,2 +0,0 @@
1
- import '@vaadin/vaadin-lumo-styles/sizing.js';
2
- import '@vaadin/vaadin-lumo-styles/spacing.js';
@@ -1,27 +0,0 @@
1
- import '@vaadin/vaadin-lumo-styles/sizing.js';
2
- import '@vaadin/vaadin-lumo-styles/spacing.js';
3
- import { contextMenuItem } from '@vaadin/context-menu/theme/lumo/vaadin-context-menu-item-styles.js';
4
- import { item } from '@vaadin/item/theme/lumo/vaadin-item-styles.js';
5
- import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
6
-
7
- const menuBarItem = css`
8
- [part='content'] {
9
- display: flex;
10
- /* tweak to inherit centering from menu bar button */
11
- align-items: inherit;
12
- justify-content: inherit;
13
- }
14
-
15
- [part='content'] ::slotted(vaadin-icon) {
16
- display: inline-block;
17
- width: var(--lumo-icon-size-m);
18
- height: var(--lumo-icon-size-m);
19
- }
20
-
21
- [part='content'] ::slotted(vaadin-icon[icon^='vaadin:']) {
22
- padding: var(--lumo-space-xs);
23
- box-sizing: border-box !important;
24
- }
25
- `;
26
-
27
- registerStyles('vaadin-menu-bar-item', [item, contextMenuItem, menuBarItem], { moduleId: 'lumo-menu-bar-item' });
@@ -1 +0,0 @@
1
- export {};
@@ -1,5 +0,0 @@
1
- import { contextMenuListBox } from '@vaadin/context-menu/theme/lumo/vaadin-context-menu-list-box-styles.js';
2
- import { listBox } from '@vaadin/list-box/theme/lumo/vaadin-list-box-styles.js';
3
- import { registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
4
-
5
- registerStyles('vaadin-menu-bar-list-box', [listBox, contextMenuListBox], { moduleId: 'lumo-menu-bar-list-box' });
@@ -1 +0,0 @@
1
- export {};
@@ -1,13 +0,0 @@
1
- import { contextMenuOverlay } from '@vaadin/context-menu/theme/lumo/vaadin-context-menu-overlay-styles.js';
2
- import { menuOverlay } from '@vaadin/vaadin-lumo-styles/mixins/menu-overlay.js';
3
- import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
4
-
5
- const menuBarOverlay = css`
6
- :host(:first-of-type) {
7
- padding-top: var(--lumo-space-xs);
8
- }
9
- `;
10
-
11
- registerStyles('vaadin-menu-bar-overlay', [menuOverlay, contextMenuOverlay, menuBarOverlay], {
12
- moduleId: 'lumo-menu-bar-overlay',
13
- });
@@ -1 +0,0 @@
1
- import '@vaadin/vaadin-lumo-styles/style.js';
@@ -1,17 +0,0 @@
1
- import '@vaadin/vaadin-lumo-styles/style.js';
2
- import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
3
-
4
- registerStyles(
5
- 'vaadin-menu-bar',
6
- css`
7
- :host([has-single-button]) ::slotted(vaadin-menu-bar-button) {
8
- border-radius: var(--lumo-border-radius-m);
9
- }
10
-
11
- :host([theme~='end-aligned']) ::slotted(vaadin-menu-bar-button[first-visible]),
12
- :host([theme~='end-aligned'][has-single-button]) ::slotted(vaadin-menu-bar-button) {
13
- margin-inline-start: auto;
14
- }
15
- `,
16
- { moduleId: 'lumo-menu-bar' },
17
- );
@@ -1,6 +0,0 @@
1
- import './vaadin-menu-bar-button.js';
2
- import './vaadin-menu-bar-item-styles.js';
3
- import './vaadin-menu-bar-list-box-styles.js';
4
- import './vaadin-menu-bar-overlay-styles.js';
5
- import './vaadin-menu-bar-styles.js';
6
- import '../../src/vaadin-menu-bar.js';
@@ -1,6 +0,0 @@
1
- import './vaadin-menu-bar-button.js';
2
- import './vaadin-menu-bar-item-styles.js';
3
- import './vaadin-menu-bar-list-box-styles.js';
4
- import './vaadin-menu-bar-overlay-styles.js';
5
- import './vaadin-menu-bar-styles.js';
6
- import '../../src/vaadin-menu-bar.js';