@vaadin/menu-bar 25.2.0-alpha8 → 25.2.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.
@@ -31,6 +31,20 @@
31
31
  "name": "close",
32
32
  "description": "Closes the current submenu."
33
33
  },
34
+ {
35
+ "kind": "field",
36
+ "name": "disabled",
37
+ "privacy": "public",
38
+ "type": {
39
+ "text": "boolean"
40
+ },
41
+ "description": "If true, the user cannot interact with this element.",
42
+ "attribute": "disabled",
43
+ "inheritedFrom": {
44
+ "name": "DisabledMixin",
45
+ "package": "@vaadin/a11y-base/src/disabled-mixin.js"
46
+ }
47
+ },
34
48
  {
35
49
  "kind": "field",
36
50
  "name": "i18n",
@@ -52,7 +66,7 @@
52
66
  "type": {
53
67
  "text": "!Array<!MenuBarItem>"
54
68
  },
55
- "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```",
69
+ "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 items\n\nWhen disabled, menu bar items are rendered as \"dimmed\".\n\nBy default, disabled items are not focusable and don't react to hover.\nAs a result, they are hidden from assistive technologies, and it's not\npossible to show a tooltip to explain why they are disabled. This can be\naddressed by enabling several feature flags, which makes disabled items\nfocusable and hoverable, while still preventing them from being activated:\n\n```js\n// Allow focus and hover interactions with disabled menu bar root items (buttons)\nwindow.Vaadin.featureFlags.accessibleDisabledButtons = true;\n\n// Allow focus and hover interactions with disabled menu bar sub-menu items\nwindow.Vaadin.featureFlags.accessibleDisabledMenuItems = true;\n```\n\nBoth flags must be set before any menu bar is attached to the DOM.\n\n#### Item tooltips\n\nButtons and sub-menu items can have tooltips that are shown on\nhover and keyboard focus. To enable them, add a slotted\n`<vaadin-tooltip>` element and set the `tooltip` property on\neach item that should have one:\n\n```html\n<vaadin-menu-bar>\n <vaadin-tooltip slot=\"tooltip\"></vaadin-tooltip>\n</vaadin-menu-bar>\n```",
56
70
  "attribute": "items"
57
71
  },
58
72
  {
@@ -95,6 +109,18 @@
95
109
  }
96
110
  ],
97
111
  "attributes": [
112
+ {
113
+ "name": "disabled",
114
+ "type": {
115
+ "text": "boolean"
116
+ },
117
+ "description": "If true, the user cannot interact with this element.",
118
+ "fieldName": "disabled",
119
+ "inheritedFrom": {
120
+ "name": "DisabledMixin",
121
+ "package": "@vaadin/a11y-base/src/disabled-mixin.js"
122
+ }
123
+ },
98
124
  {
99
125
  "name": "i18n",
100
126
  "type": {
@@ -137,14 +163,6 @@
137
163
  "name": "I18nMixin",
138
164
  "package": "@vaadin/component-base/src/i18n-mixin.js"
139
165
  },
140
- {
141
- "name": "DisabledMixin",
142
- "package": "@vaadin/a11y-base/src/disabled-mixin.js"
143
- },
144
- {
145
- "name": "FocusMixin",
146
- "package": "@vaadin/a11y-base/src/focus-mixin.js"
147
- },
148
166
  {
149
167
  "name": "KeyboardDirectionMixin",
150
168
  "package": "@vaadin/a11y-base/src/keyboard-direction-mixin.js"
@@ -152,6 +170,14 @@
152
170
  {
153
171
  "name": "ResizeMixin",
154
172
  "package": "@vaadin/component-base/src/resize-mixin.js"
173
+ },
174
+ {
175
+ "name": "FocusMixin",
176
+ "package": "@vaadin/a11y-base/src/focus-mixin.js"
177
+ },
178
+ {
179
+ "name": "DisabledMixin",
180
+ "package": "@vaadin/a11y-base/src/disabled-mixin.js"
155
181
  }
156
182
  ],
157
183
  "parameters": [
@@ -172,6 +198,105 @@
172
198
  }
173
199
  ]
174
200
  },
201
+ {
202
+ "kind": "javascript-module",
203
+ "path": "src/vaadin-menu-bar-tooltip-controller.js",
204
+ "declarations": [
205
+ {
206
+ "kind": "class",
207
+ "description": "Controller for the tooltip slotted into `<vaadin-menu-bar>`. Extends\n`ContextMenuTooltipController` to also support menu-bar buttons as\ntargets, in addition to sub-menu items.",
208
+ "name": "MenuBarTooltipController",
209
+ "members": [
210
+ {
211
+ "kind": "method",
212
+ "name": "bringToFront",
213
+ "inheritedFrom": {
214
+ "name": "ContextMenuTooltipController",
215
+ "package": "@vaadin/context-menu/src/vaadin-context-menu-tooltip-controller.js"
216
+ }
217
+ },
218
+ {
219
+ "kind": "method",
220
+ "name": "close",
221
+ "parameters": [
222
+ {
223
+ "name": "immediate",
224
+ "type": {
225
+ "text": "boolean"
226
+ }
227
+ }
228
+ ],
229
+ "inheritedFrom": {
230
+ "name": "ContextMenuTooltipController",
231
+ "package": "@vaadin/context-menu/src/vaadin-context-menu-tooltip-controller.js"
232
+ }
233
+ },
234
+ {
235
+ "kind": "method",
236
+ "name": "initCustomNode",
237
+ "parameters": [
238
+ {
239
+ "name": "tooltipNode"
240
+ }
241
+ ],
242
+ "inheritedFrom": {
243
+ "name": "ContextMenuTooltipController",
244
+ "package": "@vaadin/context-menu/src/vaadin-context-menu-tooltip-controller.js"
245
+ }
246
+ },
247
+ {
248
+ "kind": "method",
249
+ "name": "open",
250
+ "parameters": [
251
+ {
252
+ "name": "{ trigger }"
253
+ },
254
+ {
255
+ "name": "options",
256
+ "type": {
257
+ "text": "{ trigger: 'hover' | 'focus' }"
258
+ }
259
+ }
260
+ ],
261
+ "inheritedFrom": {
262
+ "name": "ContextMenuTooltipController",
263
+ "package": "@vaadin/context-menu/src/vaadin-context-menu-tooltip-controller.js"
264
+ }
265
+ },
266
+ {
267
+ "kind": "method",
268
+ "name": "setTarget",
269
+ "parameters": [
270
+ {
271
+ "name": "target",
272
+ "type": {
273
+ "text": "HTMLElement | null"
274
+ }
275
+ }
276
+ ],
277
+ "inheritedFrom": {
278
+ "name": "ContextMenuTooltipController",
279
+ "package": "@vaadin/context-menu/src/vaadin-context-menu-tooltip-controller.js"
280
+ }
281
+ }
282
+ ],
283
+ "superclass": {
284
+ "name": "ContextMenuTooltipController",
285
+ "package": "@vaadin/context-menu/src/vaadin-context-menu-tooltip-controller.js"
286
+ }
287
+ }
288
+ ],
289
+ "exports": [
290
+ {
291
+ "kind": "js",
292
+ "name": "MenuBarTooltipController",
293
+ "declaration": {
294
+ "name": "MenuBarTooltipController",
295
+ "module": "src/vaadin-menu-bar-tooltip-controller.js"
296
+ }
297
+ }
298
+ ]
299
+ },
175
300
  {
176
301
  "kind": "javascript-module",
177
302
  "path": "src/vaadin-menu-bar.js",
@@ -190,6 +315,20 @@
190
315
  "module": "src/vaadin-menu-bar-mixin.js"
191
316
  }
192
317
  },
318
+ {
319
+ "kind": "field",
320
+ "name": "disabled",
321
+ "privacy": "public",
322
+ "type": {
323
+ "text": "boolean"
324
+ },
325
+ "description": "If true, the user cannot interact with this element.",
326
+ "attribute": "disabled",
327
+ "inheritedFrom": {
328
+ "name": "DisabledMixin",
329
+ "package": "@vaadin/a11y-base/src/disabled-mixin.js"
330
+ }
331
+ },
193
332
  {
194
333
  "kind": "field",
195
334
  "name": "i18n",
@@ -211,7 +350,7 @@
211
350
  "type": {
212
351
  "text": "!Array<!MenuBarItem>"
213
352
  },
214
- "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```",
353
+ "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 items\n\nWhen disabled, menu bar items are rendered as \"dimmed\".\n\nBy default, disabled items are not focusable and don't react to hover.\nAs a result, they are hidden from assistive technologies, and it's not\npossible to show a tooltip to explain why they are disabled. This can be\naddressed by enabling several feature flags, which makes disabled items\nfocusable and hoverable, while still preventing them from being activated:\n\n```js\n// Allow focus and hover interactions with disabled menu bar root items (buttons)\nwindow.Vaadin.featureFlags.accessibleDisabledButtons = true;\n\n// Allow focus and hover interactions with disabled menu bar sub-menu items\nwindow.Vaadin.featureFlags.accessibleDisabledMenuItems = true;\n```\n\nBoth flags must be set before any menu bar is attached to the DOM.\n\n#### Item tooltips\n\nButtons and sub-menu items can have tooltips that are shown on\nhover and keyboard focus. To enable them, add a slotted\n`<vaadin-tooltip>` element and set the `tooltip` property on\neach item that should have one:\n\n```html\n<vaadin-menu-bar>\n <vaadin-tooltip slot=\"tooltip\"></vaadin-tooltip>\n</vaadin-menu-bar>\n```",
215
354
  "attribute": "items",
216
355
  "inheritedFrom": {
217
356
  "name": "MenuBarMixin",
@@ -303,6 +442,18 @@
303
442
  "tagName": "vaadin-menu-bar",
304
443
  "customElement": true,
305
444
  "attributes": [
445
+ {
446
+ "name": "disabled",
447
+ "type": {
448
+ "text": "boolean"
449
+ },
450
+ "description": "If true, the user cannot interact with this element.",
451
+ "fieldName": "disabled",
452
+ "inheritedFrom": {
453
+ "name": "DisabledMixin",
454
+ "package": "@vaadin/a11y-base/src/disabled-mixin.js"
455
+ }
456
+ },
306
457
  {
307
458
  "name": "i18n",
308
459
  "type": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/menu-bar",
3
- "version": "25.2.0-alpha8",
3
+ "version": "25.2.0-beta1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -35,23 +35,23 @@
35
35
  ],
36
36
  "dependencies": {
37
37
  "@open-wc/dedupe-mixin": "^1.3.0",
38
- "@vaadin/a11y-base": "25.2.0-alpha8",
39
- "@vaadin/button": "25.2.0-alpha8",
40
- "@vaadin/component-base": "25.2.0-alpha8",
41
- "@vaadin/context-menu": "25.2.0-alpha8",
42
- "@vaadin/item": "25.2.0-alpha8",
43
- "@vaadin/list-box": "25.2.0-alpha8",
44
- "@vaadin/overlay": "25.2.0-alpha8",
45
- "@vaadin/vaadin-themable-mixin": "25.2.0-alpha8",
38
+ "@vaadin/a11y-base": "25.2.0-beta1",
39
+ "@vaadin/button": "25.2.0-beta1",
40
+ "@vaadin/component-base": "25.2.0-beta1",
41
+ "@vaadin/context-menu": "25.2.0-beta1",
42
+ "@vaadin/item": "25.2.0-beta1",
43
+ "@vaadin/list-box": "25.2.0-beta1",
44
+ "@vaadin/overlay": "25.2.0-beta1",
45
+ "@vaadin/vaadin-themable-mixin": "25.2.0-beta1",
46
46
  "lit": "^3.0.0"
47
47
  },
48
48
  "devDependencies": {
49
- "@vaadin/aura": "25.2.0-alpha8",
50
- "@vaadin/chai-plugins": "25.2.0-alpha8",
51
- "@vaadin/icon": "25.2.0-alpha8",
52
- "@vaadin/test-runner-commands": "25.2.0-alpha8",
49
+ "@vaadin/aura": "25.2.0-beta1",
50
+ "@vaadin/chai-plugins": "25.2.0-beta1",
51
+ "@vaadin/icon": "25.2.0-beta1",
52
+ "@vaadin/test-runner-commands": "25.2.0-beta1",
53
53
  "@vaadin/testing-helpers": "^2.0.0",
54
- "@vaadin/vaadin-lumo-styles": "25.2.0-alpha8",
54
+ "@vaadin/vaadin-lumo-styles": "25.2.0-beta1",
55
55
  "sinon": "^21.0.2"
56
56
  },
57
57
  "customElements": "custom-elements.json",
@@ -59,5 +59,5 @@
59
59
  "web-types.json",
60
60
  "web-types.lit.json"
61
61
  ],
62
- "gitHead": "2b82e20cdfc605b1187e9a24ae42869e1500ab68"
62
+ "gitHead": "471a23f60d1eb725f98a33f62cb9664d9c0a4163"
63
63
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * Copyright (c) 2016 - 2026 Vaadin Ltd.
3
+ * Copyright (c) 2019 - 2026 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
6
  import { menuOverlayStyles } from '@vaadin/context-menu/src/styles/vaadin-menu-overlay-base-styles.js';
@@ -17,9 +17,6 @@ import { menuBarItemStyles } from './styles/vaadin-menu-bar-item-base-styles.js'
17
17
  *
18
18
  * @customElement vaadin-menu-bar-item
19
19
  * @extends HTMLElement
20
- * @mixes DirMixin
21
- * @mixes ItemMixin
22
- * @mixes ThemableMixin
23
20
  * @protected
24
21
  */
25
22
  class MenuBarItem extends ItemMixin(ThemableMixin(DirMixin(PolylitMixin(LumoInjectionMixin(LitElement))))) {
@@ -49,6 +46,11 @@ class MenuBarItem extends ItemMixin(ThemableMixin(DirMixin(PolylitMixin(LumoInje
49
46
  // because the role is removed when teleporting to button.
50
47
  this.setAttribute('role', 'menuitem');
51
48
  }
49
+
50
+ /** @override */
51
+ __shouldAllowFocusWhenDisabled() {
52
+ return window.Vaadin.featureFlags.accessibleDisabledMenuItems;
53
+ }
52
54
  }
53
55
 
54
56
  defineCustomElement(MenuBarItem);
@@ -17,9 +17,6 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
17
17
  *
18
18
  * @customElement vaadin-menu-bar-list-box
19
19
  * @extends HTMLElement
20
- * @mixes DirMixin
21
- * @mixes ListMixin
22
- * @mixes ThemableMixin
23
20
  * @protected
24
21
  */
25
22
  class MenuBarListBox extends ListMixin(ThemableMixin(DirMixin(PolylitMixin(LumoInjectionMixin(LitElement))))) {
@@ -22,6 +22,13 @@ export type MenuBarItem<TItemData extends object = object> = {
22
22
  * Requires a `<vaadin-tooltip slot="tooltip">` element to be added inside the `<vaadin-menu-bar>`.
23
23
  */
24
24
  tooltip?: string;
25
+ /**
26
+ * Position of the button's tooltip relative to the button
27
+ * (e.g. `bottom`, `top-start`). Defaults to `bottom`. If the slotted
28
+ * `<vaadin-tooltip>` has its `position` property set, that value is
29
+ * used instead.
30
+ */
31
+ tooltipPosition?: string;
25
32
  /**
26
33
  * The component to represent the button content.
27
34
  * Either a tagName or an element instance. Defaults to "vaadin-menu-bar-item".
@@ -48,6 +55,19 @@ export type MenuBarItem<TItemData extends object = object> = {
48
55
 
49
56
  export type SubMenuItem<TItemData extends object = object> = {
50
57
  text?: string;
58
+ /**
59
+ * Text to be set as the menu item's tooltip.
60
+ * Requires a `<vaadin-tooltip slot="tooltip">` element to be added inside the `<vaadin-menu-bar>`.
61
+ */
62
+ tooltip?: string;
63
+ /**
64
+ * Position of the item's tooltip relative to the item
65
+ * (e.g. `end`, `top`, `bottom-start`). Items with a sub-menu default to `start` to
66
+ * avoid overlap with the opening sub-menu; all other items, including disabled ones
67
+ * (whose sub-menus cannot be opened), default to `end`. If the slotted
68
+ * `<vaadin-tooltip>` has its `position` property set, that value is used instead.
69
+ */
70
+ tooltipPosition?: string;
51
71
  component?: HTMLElement | string;
52
72
  disabled?: boolean;
53
73
  theme?: string[] | string;
@@ -101,22 +121,37 @@ export declare class MenuBarMixinClass<TItem extends MenuBarItem = MenuBarItem>
101
121
  * ];
102
122
  * ```
103
123
  *
104
- * #### Disabled buttons
124
+ * #### Disabled items
105
125
  *
106
- * When disabled, menu bar buttons (root-level items) are rendered
107
- * as "dimmed" and prevent all user interactions (mouse and keyboard).
126
+ * When disabled, menu bar items are rendered as "dimmed".
108
127
  *
109
- * Since disabled buttons are not focusable and cannot react to hover
110
- * events by default, it can cause accessibility issues by making them
111
- * entirely invisible to assistive technologies, and prevents the use
112
- * of Tooltips to explain why the action is not available. This can be
113
- * addressed by enabling the feature flag `accessibleDisabledButtons`,
114
- * which makes disabled buttons focusable and hoverable, while still
115
- * preventing them from being triggered:
128
+ * By default, disabled items are not focusable and don't react to hover.
129
+ * As a result, they are hidden from assistive technologies, and it's not
130
+ * possible to show a tooltip to explain why they are disabled. This can be
131
+ * addressed by enabling several feature flags, which makes disabled items
132
+ * focusable and hoverable, while still preventing them from being activated:
116
133
  *
117
134
  * ```js
118
- * // Set before any menu bar is attached to the DOM.
135
+ * // Allow focus and hover interactions with disabled menu bar root items (buttons)
119
136
  * window.Vaadin.featureFlags.accessibleDisabledButtons = true;
137
+ *
138
+ * // Allow focus and hover interactions with disabled menu bar sub-menu items
139
+ * window.Vaadin.featureFlags.accessibleDisabledMenuItems = true;
140
+ * ```
141
+ *
142
+ * Both flags must be set before any menu bar is attached to the DOM.
143
+ *
144
+ * #### Item tooltips
145
+ *
146
+ * Buttons and sub-menu items can have tooltips that are shown on
147
+ * hover and keyboard focus. To enable them, add a slotted
148
+ * `<vaadin-tooltip>` element and set the `tooltip` property on
149
+ * each item that should have one:
150
+ *
151
+ * ```html
152
+ * <vaadin-menu-bar>
153
+ * <vaadin-tooltip slot="tooltip"></vaadin-tooltip>
154
+ * </vaadin-menu-bar>
120
155
  * ```
121
156
  */
122
157
  items: TItem[];
@@ -15,6 +15,7 @@ import { Debouncer } from '@vaadin/component-base/src/debounce.js';
15
15
  import { I18nMixin } from '@vaadin/component-base/src/i18n-mixin.js';
16
16
  import { ResizeMixin } from '@vaadin/component-base/src/resize-mixin.js';
17
17
  import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
18
+ import { MenuBarTooltipController } from './vaadin-menu-bar-tooltip-controller.js';
18
19
 
19
20
  /**
20
21
  * Custom Lit directive for rendering item components
@@ -55,17 +56,8 @@ const DEFAULT_I18N = {
55
56
  moreOptions: 'More options',
56
57
  };
57
58
 
58
- /**
59
- * @polymerMixin
60
- * @mixes DisabledMixin
61
- * @mixes FocusMixin
62
- * @mixes I18nMixin
63
- * @mixes KeyboardDirectionMixin
64
- * @mixes ResizeMixin
65
- */
66
59
  export const MenuBarMixin = (superClass) =>
67
60
  class MenuBarMixinClass extends I18nMixin(
68
- DEFAULT_I18N,
69
61
  KeyboardDirectionMixin(ResizeMixin(FocusMixin(DisabledMixin(superClass)))),
70
62
  ) {
71
63
  static get properties() {
@@ -76,6 +68,9 @@ export const MenuBarMixin = (superClass) =>
76
68
  * @property {string} text - Text to be set as the menu button component's textContent.
77
69
  * @property {string} tooltip - Text to be set as the menu button's tooltip.
78
70
  * Requires a `<vaadin-tooltip slot="tooltip">` element to be added inside the `<vaadin-menu-bar>`.
71
+ * @property {string} tooltipPosition - Position of the button's tooltip relative to
72
+ * the button (e.g. `bottom`, `top-start`). Defaults to `bottom`. If the slotted
73
+ * `<vaadin-tooltip>` has its `position` property set, that value is used instead.
79
74
  * @property {string | HTMLElement} component - The component to represent the button content.
80
75
  * Either a tagName or an element instance. Defaults to "vaadin-menu-bar-item".
81
76
  * @property {boolean} disabled - If true, the button is disabled and cannot be activated.
@@ -87,6 +82,13 @@ export const MenuBarMixin = (superClass) =>
87
82
  * @typedef SubMenuItem
88
83
  * @type {object}
89
84
  * @property {string} text - Text to be set as the menu item component's textContent.
85
+ * @property {string} tooltip - Text to be set as the menu item's tooltip.
86
+ * Requires a `<vaadin-tooltip slot="tooltip">` element to be added inside the `<vaadin-menu-bar>`.
87
+ * @property {string} tooltipPosition - Position of the item's tooltip relative to the
88
+ * item (e.g. `end`, `top`, `bottom-start`). Items with a sub-menu default to `start`
89
+ * to avoid overlap with the opening sub-menu; all other items, including disabled
90
+ * ones (whose sub-menus cannot be opened), default to `end`. If the slotted
91
+ * `<vaadin-tooltip>` has its `position` property set, that value is used instead.
90
92
  * @property {string | HTMLElement} component - The component to represent the item.
91
93
  * Either a tagName or an element instance. Defaults to "vaadin-menu-bar-item".
92
94
  * @property {boolean} disabled - If true, the item is disabled and cannot be selected.
@@ -123,22 +125,37 @@ export const MenuBarMixin = (superClass) =>
123
125
  * ];
124
126
  * ```
125
127
  *
126
- * #### Disabled buttons
128
+ * #### Disabled items
127
129
  *
128
- * When disabled, menu bar buttons (root-level items) are rendered
129
- * as "dimmed" and prevent all user interactions (mouse and keyboard).
130
+ * When disabled, menu bar items are rendered as "dimmed".
130
131
  *
131
- * Since disabled buttons are not focusable and cannot react to hover
132
- * events by default, it can cause accessibility issues by making them
133
- * entirely invisible to assistive technologies, and prevents the use
134
- * of Tooltips to explain why the action is not available. This can be
135
- * addressed by enabling the feature flag `accessibleDisabledButtons`,
136
- * which makes disabled buttons focusable and hoverable, while still
137
- * preventing them from being triggered:
132
+ * By default, disabled items are not focusable and don't react to hover.
133
+ * As a result, they are hidden from assistive technologies, and it's not
134
+ * possible to show a tooltip to explain why they are disabled. This can be
135
+ * addressed by enabling several feature flags, which makes disabled items
136
+ * focusable and hoverable, while still preventing them from being activated:
138
137
  *
139
138
  * ```js
140
- * // Set before any menu bar is attached to the DOM.
139
+ * // Allow focus and hover interactions with disabled menu bar root items (buttons)
141
140
  * window.Vaadin.featureFlags.accessibleDisabledButtons = true;
141
+ *
142
+ * // Allow focus and hover interactions with disabled menu bar sub-menu items
143
+ * window.Vaadin.featureFlags.accessibleDisabledMenuItems = true;
144
+ * ```
145
+ *
146
+ * Both flags must be set before any menu bar is attached to the DOM.
147
+ *
148
+ * #### Item tooltips
149
+ *
150
+ * Buttons and sub-menu items can have tooltips that are shown on
151
+ * hover and keyboard focus. To enable them, add a slotted
152
+ * `<vaadin-tooltip>` element and set the `tooltip` property on
153
+ * each item that should have one:
154
+ *
155
+ * ```html
156
+ * <vaadin-menu-bar>
157
+ * <vaadin-tooltip slot="tooltip"></vaadin-tooltip>
158
+ * </vaadin-menu-bar>
142
159
  * ```
143
160
  *
144
161
  * @type {!Array<!MenuBarItem>}
@@ -179,6 +196,10 @@ export const MenuBarMixin = (superClass) =>
179
196
  };
180
197
  }
181
198
 
199
+ static get defaultI18n() {
200
+ return DEFAULT_I18N;
201
+ }
202
+
182
203
  /**
183
204
  * The object used to localize this component. To change the default
184
205
  * localization, replace this with an object that provides all properties, or
@@ -203,7 +224,6 @@ export const MenuBarMixin = (superClass) =>
203
224
  constructor() {
204
225
  super();
205
226
  this.__boundOnContextMenuKeydown = this.__onContextMenuKeydown.bind(this);
206
- this.__boundOnTooltipMouseLeave = this.__onTooltipOverlayMouseLeave.bind(this);
207
227
  }
208
228
 
209
229
  /**
@@ -308,12 +328,15 @@ export const MenuBarMixin = (superClass) =>
308
328
  },
309
329
  });
310
330
 
331
+ this._tooltipController = new MenuBarTooltipController(this);
332
+
333
+ this.addEventListener('mousedown', () => this._tooltipController.close(true));
334
+ this.addEventListener('mouseleave', () => this._tooltipController.close());
335
+
336
+ this.addController(this._tooltipController);
311
337
  this.addController(this._subMenuController);
312
338
  this.addController(this._overflowController);
313
339
 
314
- this.addEventListener('mousedown', () => this._hideTooltip(true));
315
- this.addEventListener('mouseleave', () => this._hideTooltip());
316
-
317
340
  this._container = this.shadowRoot.querySelector('[part="container"]');
318
341
  }
319
342
 
@@ -365,7 +388,7 @@ export const MenuBarMixin = (superClass) =>
365
388
  /** @protected */
366
389
  disconnectedCallback() {
367
390
  super.disconnectedCallback();
368
- this._hideTooltip(true);
391
+ this._tooltipController.setTarget(null);
369
392
  }
370
393
 
371
394
  /**
@@ -408,7 +431,7 @@ export const MenuBarMixin = (superClass) =>
408
431
  /** @private */
409
432
  __updateSubMenu() {
410
433
  const subMenu = this._subMenu;
411
- if (subMenu && subMenu.opened) {
434
+ if (subMenu?.opened) {
412
435
  const button = subMenu._positionTarget;
413
436
 
414
437
  // Close sub-menu if the corresponding button is no longer in the DOM,
@@ -421,7 +444,7 @@ export const MenuBarMixin = (superClass) =>
421
444
 
422
445
  /** @private */
423
446
  __i18nChanged(effectiveI18n) {
424
- if (effectiveI18n && effectiveI18n.moreOptions !== undefined) {
447
+ if (effectiveI18n?.moreOptions !== undefined) {
425
448
  if (effectiveI18n.moreOptions) {
426
449
  this._overflow.setAttribute('aria-label', effectiveI18n.moreOptions);
427
450
  } else {
@@ -563,7 +586,7 @@ export const MenuBarMixin = (superClass) =>
563
586
  let theme = hostTheme;
564
587
 
565
588
  // Item theme takes precedence over host theme even if it's empty, as long as it's not undefined or null
566
- const itemTheme = item && item.theme;
589
+ const itemTheme = item?.theme;
567
590
  if (itemTheme != null) {
568
591
  theme = Array.isArray(itemTheme) ? itemTheme.join(' ') : itemTheme;
569
592
  }
@@ -597,7 +620,7 @@ export const MenuBarMixin = (superClass) =>
597
620
  html`
598
621
  ${items.map((item) => {
599
622
  const itemCopy = { ...item };
600
- const hasChildren = Boolean(item && item.children);
623
+ const hasChildren = Boolean(item?.children);
601
624
 
602
625
  if (itemCopy.component) {
603
626
  const component = this.__getComponent(itemCopy);
@@ -636,54 +659,6 @@ export const MenuBarMixin = (superClass) =>
636
659
  }
637
660
  }
638
661
 
639
- /**
640
- * @param {HTMLElement} button
641
- * @protected
642
- */
643
- _showTooltip(button, isHover) {
644
- // Check if there is a slotted vaadin-tooltip element.
645
- const tooltip = this._tooltipController.node;
646
- if (tooltip && tooltip.isConnected) {
647
- // If the tooltip element doesn't have a generator assigned, use a default one
648
- // that reads the `tooltip` property of an item.
649
- if (tooltip.generator === undefined) {
650
- tooltip.generator = ({ item }) => item && item.tooltip;
651
- }
652
-
653
- if (!tooltip._mouseLeaveListenerAdded) {
654
- tooltip._overlayElement.addEventListener('mouseleave', this.__boundOnTooltipMouseLeave);
655
- tooltip._mouseLeaveListenerAdded = true;
656
- }
657
-
658
- if (!this._subMenu.opened) {
659
- this._tooltipController.setTarget(button);
660
- this._tooltipController.setContext({ item: button.item });
661
-
662
- // Trigger opening using the corresponding delay.
663
- tooltip._stateController.open({
664
- hover: isHover,
665
- focus: !isHover,
666
- });
667
- }
668
- }
669
- }
670
-
671
- /** @protected */
672
- _hideTooltip(immediate) {
673
- const tooltip = this._tooltipController && this._tooltipController.node;
674
- if (tooltip) {
675
- this._tooltipController.setContext({ item: null });
676
- tooltip._stateController.close(immediate);
677
- }
678
- }
679
-
680
- /** @private */
681
- __onTooltipOverlayMouseLeave(event) {
682
- if (event.relatedTarget !== this._tooltipController.target) {
683
- this._hideTooltip();
684
- }
685
- }
686
-
687
662
  /** @protected */
688
663
  _setExpanded(button, expanded) {
689
664
  button.toggleAttribute('expanded', expanded);
@@ -711,24 +686,24 @@ export const MenuBarMixin = (superClass) =>
711
686
  * @protected
712
687
  * @override
713
688
  */
714
- _focusItem(item, options, navigating) {
689
+ _focusItem(button, options, navigating) {
715
690
  const wasExpanded = navigating && this.focused === this._expandedButton;
716
691
  if (wasExpanded) {
717
692
  this._close();
718
693
  }
719
694
 
720
- super._focusItem(item, options, navigating);
695
+ super._focusItem(button, options, navigating);
721
696
 
722
697
  this._buttons.forEach((btn) => {
723
- this._setTabindex(btn, btn === item);
698
+ this._setTabindex(btn, btn === button);
724
699
  });
725
700
 
726
- if (wasExpanded && item.item && item.item.children) {
727
- this.__openSubMenu(item, true, { keepFocus: true });
728
- } else if (item === this._overflow) {
729
- this._hideTooltip();
730
- } else {
731
- this._showTooltip(item);
701
+ this._tooltipController.setTarget(button);
702
+
703
+ if (wasExpanded && button.item && button.item.children) {
704
+ this.__openSubMenu(button, true, { keepFocus: true });
705
+ } else if (!this._subMenu.opened) {
706
+ this._tooltipController.open({ trigger: 'focus' });
732
707
  }
733
708
  }
734
709
 
@@ -773,18 +748,19 @@ export const MenuBarMixin = (superClass) =>
773
748
  * @protected
774
749
  */
775
750
  _setFocused(focused) {
776
- if (focused) {
777
- const target = this.__getFocusTarget();
778
- if (target) {
779
- this._buttons.forEach((btn) => {
780
- this._setTabindex(btn, btn === target);
781
- if (btn === target && btn !== this._overflow && isKeyboardActive()) {
782
- this._showTooltip(btn);
783
- }
784
- });
751
+ const target = focused ? this.__getFocusTarget() : null;
752
+ if (target) {
753
+ this._tooltipController.setTarget(target);
754
+
755
+ this._buttons.forEach((btn) => {
756
+ this._setTabindex(btn, btn === target);
757
+ });
758
+
759
+ if (!this._subMenu.opened && isKeyboardActive()) {
760
+ this._tooltipController.open({ trigger: 'focus' });
785
761
  }
786
762
  } else {
787
- this._hideTooltip();
763
+ this._tooltipController.close(true);
788
764
  }
789
765
  }
790
766
 
@@ -854,7 +830,7 @@ export const MenuBarMixin = (superClass) =>
854
830
  this._close(true);
855
831
  }
856
832
 
857
- this._hideTooltip(true);
833
+ this._tooltipController.close(true);
858
834
  }
859
835
 
860
836
  /**
@@ -899,22 +875,19 @@ export const MenuBarMixin = (superClass) =>
899
875
  }
900
876
 
901
877
  const button = this._getButtonFromEvent(event);
902
- if (!button) {
903
- // Hide tooltip on mouseover to disabled button
904
- this._hideTooltip();
905
- } else if (button !== this._expandedButton) {
878
+ this._tooltipController.setTarget(button);
879
+
880
+ if (button && button !== this._expandedButton) {
906
881
  // Switch sub-menu when moving cursor over another button
907
882
  // with children, regardless of whether openOnHover is set.
908
883
  // If the button has no children, keep the sub-menu opened.
909
884
  if (button.item.children && (this.openOnHover || this._subMenu.opened)) {
910
885
  this.__openSubMenu(button, false);
911
886
  }
887
+ }
912
888
 
913
- if (button === this._overflow || (this.openOnHover && button.item.children)) {
914
- this._hideTooltip();
915
- } else {
916
- this._showTooltip(button, true);
917
- }
889
+ if (!this._subMenu.opened) {
890
+ this._tooltipController.open({ trigger: 'hover' });
918
891
  }
919
892
  }
920
893
 
@@ -968,7 +941,7 @@ export const MenuBarMixin = (superClass) =>
968
941
  }
969
942
  }
970
943
 
971
- const items = item && item.children;
944
+ const items = item?.children;
972
945
  if (!items || items.length === 0) {
973
946
  this.__fireItemSelected(item);
974
947
  return;
@@ -980,7 +953,7 @@ export const MenuBarMixin = (superClass) =>
980
953
  const overlay = subMenu._overlayElement;
981
954
  overlay.noVerticalOverlap = true;
982
955
 
983
- this._hideTooltip(true);
956
+ this._tooltipController.close(true);
984
957
 
985
958
  this._expandedButton = button;
986
959
  this._setExpanded(button, true);
@@ -1045,11 +1018,13 @@ export const MenuBarMixin = (superClass) =>
1045
1018
  /** @private */
1046
1019
  __deactivateButton(restoreFocus) {
1047
1020
  const button = this._expandedButton;
1048
- if (button && button.hasAttribute('expanded')) {
1021
+ if (button?.hasAttribute('expanded')) {
1049
1022
  this._setExpanded(button, false);
1050
1023
  if (restoreFocus) {
1051
1024
  const focusOptions = { focusVisible: isKeyboardActive() };
1052
1025
  this._focusItem(button, focusOptions, false);
1026
+ } else {
1027
+ this._tooltipController.close(true);
1053
1028
  }
1054
1029
  this._expandedButton = null;
1055
1030
  }
@@ -18,10 +18,6 @@ import { menuBarOverlayStyles } from './styles/vaadin-menu-bar-overlay-base-styl
18
18
  *
19
19
  * @customElement vaadin-menu-bar-overlay
20
20
  * @extends HTMLElement
21
- * @mixes DirMixin
22
- * @mixes MenuOverlayMixin
23
- * @mixes OverlayMixin
24
- * @mixes ThemableMixin
25
21
  * @protected
26
22
  */
27
23
  export class MenuBarOverlay extends MenuOverlayMixin(
@@ -18,8 +18,6 @@ import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-p
18
18
  *
19
19
  * @customElement vaadin-menu-bar-submenu
20
20
  * @extends HTMLElement
21
- * @mixes ContextMenuMixin
22
- * @mixes ThemePropertyMixin
23
21
  * @protected
24
22
  */
25
23
  class MenuBarSubmenu extends ContextMenuMixin(ThemePropertyMixin(PolylitMixin(LitElement))) {
@@ -55,6 +53,17 @@ class MenuBarSubmenu extends ContextMenuMixin(ThemePropertyMixin(PolylitMixin(Li
55
53
  this.openOn = 'opensubmenu';
56
54
  }
57
55
 
56
+ /** @protected */
57
+ firstUpdated(props) {
58
+ // Tooltip lives on the parent `<vaadin-menu-bar>`. Reuse its controller
59
+ // so the same tooltip element serves items at every nesting level.
60
+ // Assigned before `super.firstUpdated()` so `ContextMenuMixin` skips
61
+ // creating its own controller (we don't render a tooltip slot).
62
+ this._tooltipController = this.parentElement._tooltipController;
63
+
64
+ super.firstUpdated(props);
65
+ }
66
+
58
67
  /**
59
68
  * Tag name prefix used by overlay, list-box and items.
60
69
  * @protected
@@ -90,13 +99,21 @@ class MenuBarSubmenu extends ContextMenuMixin(ThemePropertyMixin(PolylitMixin(Li
90
99
  }
91
100
 
92
101
  /**
93
- * Overriding the observer to not add global "contextmenu" listener.
102
+ * Overriding the observer to not toggle user-select on the host.
94
103
  * @override
95
104
  */
96
105
  _openedChanged() {
97
106
  // Do nothing
98
107
  }
99
108
 
109
+ /**
110
+ * Overriding the handler to not react to global "contextmenu" events.
111
+ * @override
112
+ */
113
+ __onGlobalContextMenu() {
114
+ // Do nothing
115
+ }
116
+
100
117
  /**
101
118
  * Overriding the public method to reset expanded button state.
102
119
  */
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2019 - 2026 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { ContextMenuTooltipController } from '@vaadin/context-menu/src/vaadin-context-menu-tooltip-controller.js';
7
+
8
+ /**
9
+ * Controller for the tooltip slotted into `<vaadin-menu-bar>`. Extends
10
+ * `ContextMenuTooltipController` to also support menu-bar buttons as
11
+ * targets, in addition to sub-menu items.
12
+ */
13
+ export class MenuBarTooltipController extends ContextMenuTooltipController {
14
+ /** @override */
15
+ _getItem(target) {
16
+ if (target.localName === 'vaadin-menu-bar-button') {
17
+ return target.item;
18
+ }
19
+
20
+ return super._getItem(target);
21
+ }
22
+
23
+ /** @override */
24
+ _getDefaultPosition(target) {
25
+ if (target.localName === 'vaadin-menu-bar-button') {
26
+ return 'bottom';
27
+ }
28
+
29
+ return super._getDefaultPosition(target);
30
+ }
31
+ }
@@ -9,7 +9,6 @@ import { html, LitElement } from 'lit';
9
9
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
10
10
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
11
11
  import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
12
- import { TooltipController } from '@vaadin/component-base/src/tooltip-controller.js';
13
12
  import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
14
13
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
15
14
  import { menuBarStyles } from './styles/vaadin-menu-bar-base-styles.js';
@@ -70,9 +69,6 @@ import { MenuBarMixin } from './vaadin-menu-bar-mixin.js';
70
69
  *
71
70
  * @customElement vaadin-menu-bar
72
71
  * @extends HTMLElement
73
- * @mixes ElementMixin
74
- * @mixes MenuBarMixin
75
- * @mixes ThemableMixin
76
72
  */
77
73
  class MenuBar extends MenuBarMixin(ElementMixin(ThemableMixin(PolylitMixin(LumoInjectionMixin(LitElement))))) {
78
74
  static get is() {
@@ -96,23 +92,6 @@ class MenuBar extends MenuBarMixin(ElementMixin(ThemableMixin(PolylitMixin(LumoI
96
92
  <slot name="tooltip"></slot>
97
93
  `;
98
94
  }
99
-
100
- /** @protected */
101
- ready() {
102
- super.ready();
103
-
104
- this._tooltipController = new TooltipController(this);
105
- this._tooltipController.setManual(true);
106
- this.addController(this._tooltipController);
107
- }
108
-
109
- /**
110
- * Fired when either a submenu item or menu bar button without nested children is clicked.
111
- *
112
- * @event item-selected
113
- * @param {Object} detail
114
- * @param {Object} detail.value the selected menu bar item
115
- */
116
95
  }
117
96
 
118
97
  defineCustomElement(MenuBar);
package/web-types.json CHANGED
@@ -1,34 +1,21 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/menu-bar",
4
- "version": "25.2.0-alpha8",
4
+ "version": "25.2.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.2.0-alpha8/#/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.2.0-alpha8/#/elements/vaadin-button).\n- `<vaadin-menu-bar-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.2.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/25.2.0-alpha8/#/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.2.0-alpha8/#/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.2.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.2.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.2.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.2.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.2.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",
15
15
  "description": "If true, the user cannot interact with this element.",
16
16
  "value": {
17
17
  "type": [
18
- "boolean",
19
- "null",
20
- "undefined"
21
- ]
22
- }
23
- },
24
- {
25
- "name": "i18n",
26
- "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\nShould be overridden by subclasses to provide a custom JSDoc with the\ndefault I18N properties.",
27
- "value": {
28
- "type": [
29
- "Object",
30
- "null",
31
- "undefined"
18
+ "boolean"
32
19
  ]
33
20
  }
34
21
  },
@@ -37,9 +24,7 @@
37
24
  "description": "If true, the submenu will open on hover (mouseover) instead of click.",
38
25
  "value": {
39
26
  "type": [
40
- "boolean",
41
- "null",
42
- "undefined"
27
+ "boolean"
43
28
  ]
44
29
  }
45
30
  },
@@ -48,9 +33,7 @@
48
33
  "description": "If true, the buttons will be collapsed into the overflow menu\nstarting from the \"start\" end of the bar instead of the \"end\".",
49
34
  "value": {
50
35
  "type": [
51
- "boolean",
52
- "null",
53
- "undefined"
36
+ "boolean"
54
37
  ]
55
38
  }
56
39
  },
@@ -59,9 +42,7 @@
59
42
  "description": "If true, the top-level menu items is traversable by tab\ninstead of arrow keys (i.e. disabling roving tabindex)",
60
43
  "value": {
61
44
  "type": [
62
- "boolean",
63
- "null",
64
- "undefined"
45
+ "boolean"
65
46
  ]
66
47
  }
67
48
  },
@@ -84,9 +65,7 @@
84
65
  "description": "If true, the user cannot interact with this element.",
85
66
  "value": {
86
67
  "type": [
87
- "boolean",
88
- "null",
89
- "undefined"
68
+ "boolean"
90
69
  ]
91
70
  }
92
71
  },
@@ -95,16 +74,16 @@
95
74
  "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```",
96
75
  "value": {
97
76
  "type": [
98
- "?"
77
+ "Object"
99
78
  ]
100
79
  }
101
80
  },
102
81
  {
103
82
  "name": "items",
104
- "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```",
83
+ "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 items\n\nWhen disabled, menu bar items are rendered as \"dimmed\".\n\nBy default, disabled items are not focusable and don't react to hover.\nAs a result, they are hidden from assistive technologies, and it's not\npossible to show a tooltip to explain why they are disabled. This can be\naddressed by enabling several feature flags, which makes disabled items\nfocusable and hoverable, while still preventing them from being activated:\n\n```js\n// Allow focus and hover interactions with disabled menu bar root items (buttons)\nwindow.Vaadin.featureFlags.accessibleDisabledButtons = true;\n\n// Allow focus and hover interactions with disabled menu bar sub-menu items\nwindow.Vaadin.featureFlags.accessibleDisabledMenuItems = true;\n```\n\nBoth flags must be set before any menu bar is attached to the DOM.\n\n#### Item tooltips\n\nButtons and sub-menu items can have tooltips that are shown on\nhover and keyboard focus. To enable them, add a slotted\n`<vaadin-tooltip>` element and set the `tooltip` property on\neach item that should have one:\n\n```html\n<vaadin-menu-bar>\n <vaadin-tooltip slot=\"tooltip\"></vaadin-tooltip>\n</vaadin-menu-bar>\n```",
105
84
  "value": {
106
85
  "type": [
107
- "Array.<MenuBarItem>"
86
+ "Array<MenuBarItem>"
108
87
  ]
109
88
  }
110
89
  },
@@ -113,9 +92,7 @@
113
92
  "description": "If true, the submenu will open on hover (mouseover) instead of click.",
114
93
  "value": {
115
94
  "type": [
116
- "boolean",
117
- "null",
118
- "undefined"
95
+ "boolean"
119
96
  ]
120
97
  }
121
98
  },
@@ -124,9 +101,7 @@
124
101
  "description": "If true, the buttons will be collapsed into the overflow menu\nstarting from the \"start\" end of the bar instead of the \"end\".",
125
102
  "value": {
126
103
  "type": [
127
- "boolean",
128
- "null",
129
- "undefined"
104
+ "boolean"
130
105
  ]
131
106
  }
132
107
  },
@@ -135,9 +110,7 @@
135
110
  "description": "If true, the top-level menu items is traversable by tab\ninstead of arrow keys (i.e. disabling roving tabindex)",
136
111
  "value": {
137
112
  "type": [
138
- "boolean",
139
- "null",
140
- "undefined"
113
+ "boolean"
141
114
  ]
142
115
  }
143
116
  }
@@ -145,7 +118,7 @@
145
118
  "events": [
146
119
  {
147
120
  "name": "item-selected",
148
- "description": "Fired when either a submenu item or menu bar button without nested children is clicked."
121
+ "description": "Fired when a submenu item or menu bar button without children is clicked."
149
122
  }
150
123
  ]
151
124
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/menu-bar",
4
- "version": "25.2.0-alpha8",
4
+ "version": "25.2.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.2.0-alpha8/#/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.2.0-alpha8/#/elements/vaadin-button).\n- `<vaadin-menu-bar-item>` - has the same API as [`<vaadin-item>`](https://cdn.vaadin.com/vaadin-web-components/25.2.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/25.2.0-alpha8/#/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.2.0-alpha8/#/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.2.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.2.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.2.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.2.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.2.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
  {
@@ -27,43 +27,43 @@
27
27
  }
28
28
  },
29
29
  {
30
- "name": "?openOnHover",
31
- "description": "If true, the submenu will open on hover (mouseover) instead of click.",
30
+ "name": ".i18n",
31
+ "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```",
32
32
  "value": {
33
33
  "kind": "expression"
34
34
  }
35
35
  },
36
36
  {
37
- "name": "?reverseCollapse",
38
- "description": "If true, the buttons will be collapsed into the overflow menu\nstarting from the \"start\" end of the bar instead of the \"end\".",
37
+ "name": ".items",
38
+ "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 items\n\nWhen disabled, menu bar items are rendered as \"dimmed\".\n\nBy default, disabled items are not focusable and don't react to hover.\nAs a result, they are hidden from assistive technologies, and it's not\npossible to show a tooltip to explain why they are disabled. This can be\naddressed by enabling several feature flags, which makes disabled items\nfocusable and hoverable, while still preventing them from being activated:\n\n```js\n// Allow focus and hover interactions with disabled menu bar root items (buttons)\nwindow.Vaadin.featureFlags.accessibleDisabledButtons = true;\n\n// Allow focus and hover interactions with disabled menu bar sub-menu items\nwindow.Vaadin.featureFlags.accessibleDisabledMenuItems = true;\n```\n\nBoth flags must be set before any menu bar is attached to the DOM.\n\n#### Item tooltips\n\nButtons and sub-menu items can have tooltips that are shown on\nhover and keyboard focus. To enable them, add a slotted\n`<vaadin-tooltip>` element and set the `tooltip` property on\neach item that should have one:\n\n```html\n<vaadin-menu-bar>\n <vaadin-tooltip slot=\"tooltip\"></vaadin-tooltip>\n</vaadin-menu-bar>\n```",
39
39
  "value": {
40
40
  "kind": "expression"
41
41
  }
42
42
  },
43
43
  {
44
- "name": "?tabNavigation",
45
- "description": "If true, the top-level menu items is traversable by tab\ninstead of arrow keys (i.e. disabling roving tabindex)",
44
+ "name": "?openOnHover",
45
+ "description": "If true, the submenu will open on hover (mouseover) instead of click.",
46
46
  "value": {
47
47
  "kind": "expression"
48
48
  }
49
49
  },
50
50
  {
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```js\n{\n moreOptions: 'More options'\n}\n```",
51
+ "name": "?reverseCollapse",
52
+ "description": "If true, the buttons will be collapsed into the overflow menu\nstarting from the \"start\" end of the bar instead of the \"end\".",
53
53
  "value": {
54
54
  "kind": "expression"
55
55
  }
56
56
  },
57
57
  {
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```js\n// Set before any menu bar is attached to the DOM.\nwindow.Vaadin.featureFlags.accessibleDisabledButtons = true;\n```",
58
+ "name": "?tabNavigation",
59
+ "description": "If true, the top-level menu items is traversable by tab\ninstead of arrow keys (i.e. disabling roving tabindex)",
60
60
  "value": {
61
61
  "kind": "expression"
62
62
  }
63
63
  },
64
64
  {
65
65
  "name": "@item-selected",
66
- "description": "Fired when either a submenu item or menu bar button without nested children is clicked.",
66
+ "description": "Fired when a submenu item or menu bar button without children is clicked.",
67
67
  "value": {
68
68
  "kind": "expression"
69
69
  }