Menu Bar
Menu Bar is a horizontal button bar with hierarchical dropdown menus. Menu items can trigger an action, open a menu, or work as a toggle.
new tab
@state()
private items = [
{ text: 'View' },
{ text: 'Edit' },
{
text: 'Share',
children: [
{
text: 'On social media',
children: [{ text: 'Facebook' }, { text: 'Twitter' }, { text: 'Instagram' }],
},
{ text: 'By email' },
{ text: 'Get link' },
],
},
{
text: 'Move',
children: [{ text: 'To folder' }, { text: 'To trash' }],
},
{ text: 'Duplicate' },
];
@state()
private selectedItem?: MenuBarItem;
<vaadin-menu-bar
.items="${this.items}"
@item-selected="${this.itemSelected}"
></vaadin-menu-bar>
<div>Clicked item: ${this.selectedItem?.text}</div>
Styles
Default Variants
The following variants are available to adjust the appearance of the component:
new tab
<vaadin-menu-bar
.items="${[{ text: 'Default', children: [{ text: 'Item' }] }]}"
></vaadin-menu-bar>
<vaadin-menu-bar
theme="tertiary"
.items="${[{ text: 'Tertiary', children: [{ text: 'Item' }] }]}"
></vaadin-menu-bar>
<vaadin-menu-bar
theme="primary"
.items="${[{ text: 'Primary', children: [{ text: 'Item' }] }]}"
></vaadin-menu-bar>
<vaadin-menu-bar
theme="small"
.items="${[{ text: 'Small', children: [{ text: 'Item' }] }]}"
></vaadin-menu-bar>
Variant | Usage recommendations |
---|---|
Tertiary | Corresponds to the tertiary button variant, omitting the background color. |
Primary | Corresponds to the primary button variant. As only one primary action should be presented in the same part of the UI, this should be used only for dropdown button use cases. |
Small | Compact variant. Can be combined with Tertiary and Primary. |
Tip | Default menu button styles can be customized
Note that the standard Menu Button styles can be adjusted using theme features, so these variants should be used only to differentiate special instances of the component.
|
Styling Menu Items
An individual menu item can be styled using a custom variant.
To style a root-level item, create a custom variant for the vaadin-menu-bar-button
component.
To style a sub-menu item, create a custom variant for the vaadin-context-menu-item
component.
See Vaadin Component Variants for details of how to add style sheets for these components.
new tab
@state()
private items = [
{ text: 'View', theme: 'custom-theme' },
{ text: 'Edit' },
{
text: 'Share',
children: [{ text: 'By email', theme: 'custom-theme' }, { text: 'Get link' }],
},
];
render() {
return html`<vaadin-menu-bar .items="${this.items}"></vaadin-menu-bar>`;
}
Overflow
Items that do not fit into the current width of the menu bar automatically collapse into an overflow menu at the end:
new tab
@state()
private items = [
{ text: 'View' },
{ text: 'Edit' },
{
text: 'Share',
children: [
{
text: 'On social media',
children: [{ text: 'Facebook' }, { text: 'Twitter' }, { text: 'Instagram' }],
},
{ text: 'By email' },
{ text: 'Get link' },
],
},
{
text: 'Move',
children: [{ text: 'To folder' }, { text: 'To trash' }],
},
{ text: 'Duplicate' },
];
<vaadin-split-layout>
<vaadin-menu-bar .items="${this.items}"></vaadin-menu-bar>
<div>Move the splitter to see overflow feature</div>
</vaadin-split-layout>
Menu Item Features
Icons
Menu items can have icons in addition to, or instead of, text.
new tab
@state()
private items = [
{
component: this.createItem('share', 'Share'),
children: [
{ component: this.createItem('share', 'By email', true) },
{ component: this.createItem('link', 'Get link', true) },
],
},
{
component: this.createItem('copy', ''),
},
];
<vaadin-menu-bar theme="icon" .items="${this.items}"></vaadin-menu-bar>
Usage recommendations:
Use icons sparingly. Most actions are difficult to represent reliably with icons, and the benefit of icons in addition to text should be weighed against the additional visual noise this creates.
Menu items in dropdown menus should always have text labels.
Icon-only menu buttons should be used primarily for extremely common recurring actions with highly standardized, universally understood icons (for example, a cross for "close").
Icon-only menu buttons should provide a textual alternative for screen readers using the
aria-label
attribute.
Menu Bars with icon-only top-level items can use the Tertiary Inline style variant to reduce the horizontal padding around the icons.
new tab
@state()
private items = [
{ component: this.createItem('eye', 'View') },
{ component: this.createItem('pencil', 'Edit') },
{
component: this.createItem('share', 'Share'),
children: [
{
text: 'On social media',
children: [{ text: 'Facebook' }, { text: 'Twitter' }, { text: 'Instagram' }],
},
{ text: 'By email' },
{ text: 'Get link' },
],
},
{
component: this.createItem('folder', 'Move'),
children: [{ text: 'To folder' }, { text: 'To trash' }],
},
{ component: this.createItem('copy', 'Duplicate') },
];
<vaadin-menu-bar theme="tertiary-inline" .items="${this.items}"></vaadin-menu-bar>
Warning | Other components in menu items
While it is technically possible to put any UI element in a menu item, this can cause problems in terms of accessibility, as it may not be possible to focus them, and they may not be correctly interpreted by assistive technologies.
|
Disabled Items
Menu items can be disabled to indicate that they are currently unavailable.
new tab
@state()
private items = [
{ text: 'View' },
{ text: 'Edit', disabled: true },
{
text: 'Share',
children: [{ text: 'By email', disabled: true }, { text: 'Get link' }],
},
];
Checkable Menu Items
Menu items in dropdown menus can be configured as checkable, to toggle options on and off.
new tab
@state()
private items = [
{
text: 'Options',
children: [{ text: 'Save automatically', checked: true }, { text: 'Notify watchers' }],
},
];
<vaadin-menu-bar
.items="${this.items}"
@item-selected="${this.itemSelected}"
></vaadin-menu-bar>
itemSelected(e: MenuBarItemSelectedEvent) {
const item = e.detail.value;
(item as SubMenuItem).checked = !(item as SubMenuItem).checked;
}
Note | Not a replacement for radio buttons
A Menu Bar with checkable items should not be used as a replacement for radio buttons in a form.
|
Dividers
You can use dividers to separate and group related content.
new tab
@state()
private items = [
{
text: 'Share',
children: [
{ text: 'Facebook' },
{ text: 'Twitter' },
{ text: 'Instagram' },
{ component: 'hr' },
{ text: 'By email' },
{ text: 'Get link' },
{ component: 'hr' },
{ text: 'Set permissions' },
],
},
];
<vaadin-menu-bar .items="${this.items}"></vaadin-menu-bar>
Use dividers sparingly to avoid creating unnecessary visual clutter.
Warning | Content other than menu items not accessible
While it is technically possible to put any UI element in a dropdown menu, including interactive components, they will not be accessible by keyboard or assistive technologies.
|
Open on Hover
The component can be configured to open dropdown menus on hover, instead of on click.
new tab
@state()
private items = [
{ text: 'View' },
{ text: 'Edit' },
{
text: 'Share',
children: [
{
text: 'On social media',
children: [{ text: 'Facebook' }, { text: 'Twitter' }, { text: 'Instagram' }],
},
{ text: 'By email' },
{ text: 'Get link' },
],
},
{
text: 'Move',
children: [{ text: 'To folder' }, { text: 'To trash' }],
},
{ text: 'Duplicate' },
];
<vaadin-menu-bar .items="${this.items}" open-on-hover></vaadin-menu-bar>
Keyboard Usage
Dropdown and "Combo" Buttons
A Menu Bar with a single top-level item is essentially a dropdown button. This solution provides a better user experience and better accessibility than a regular Button paired with a Context Menu.
new tab
@state()
private items = [
{
text: 'John Smith',
children: [
{ text: 'Profile' },
{ text: 'Account' },
{ text: 'Preferences' },
{ component: 'hr' },
{ text: 'Sign out' },
],
},
];
<vaadin-menu-bar .items="${this.items}"></vaadin-menu-bar>
So-called “combo buttons” can be created in a similar way, for example to provide a set of variations on an action.
new tab
@state()
private items = [
{ text: 'Save' },
{
component: this.createItem(),
children: [{ text: 'Save as draft' }, { text: 'Save as copy' }, { text: 'Save and publish' }],
},
];
<vaadin-menu-bar theme="icon primary" .items="${this.items}"></vaadin-menu-bar>
Internationalization (i18n)
Menu Bar provides an API for localization. Currently, only the accessible label for the overflow menu button can be customized.
const customI18n: MenuBarI18n = {
// Provide accessible label for the overflow menu button
// to screen readers
moreOptions: 'More actions',
};
return html`<vaadin-menu-bar .i18n="${customI18n}" .items="${this.items}"></vaadin-menu-bar>`;
Best Practices
Menu Bar should not be used for navigation. Use tabs to switch between content, or anchor elements for regular navigation.
Menu Bar is not an input field. Use Select, Combo Box, or Radio Button instead.
Related Components
Component | Usage recommendations |
---|---|
Regular Button component for individual actions. | |
Dropdown input field. | |
Tabs should be used to split content into sections that the user can switch between. | |
A generic dropdown menu that can be triggered from any component. |
BCC76FD2-FB02-4F71-A6DF-7574CAC1C662