Menu Bar
- Usage
- Styling
- Styles
- Overflow
- Menu Item Features
- Dividers
- Open on Hover
- Tooltips
- Keyboard Usage
- Drop-Down & Combo Buttons
- Internationalization (i18n)
- Custom Item Data
- Best Practices
- Related Components
Menu Bar is a horizontal button bar with hierarchical drop-down menus. Menu items can trigger an action, open a menu, or work as a toggle.
new tab
Source code
MenuBarBasic.java
menu-bar-basic.tsx
menu-bar-basic.ts
Styles
Default Variants
The following variants are available to adjust the appearance of the component:
new tab
Source code
MenuBarStyles.java
menu-bar-styles.tsx
menu-bar-styles.ts
Variant | Usage Recommendation |
---|---|
Tertiary | Corresponds to the tertiary button variant, omitting the background color. |
Primary | Corresponds to the primary button variant. Since only one primary action should be presented in the same part of the UI, this should be used only for drop-down button use cases. |
Small | Compact variant. Can be combined with Tertiary and Primary. |
Tip
|
Customize Default Menu Button Styles
The standard Menu Button styles can be adjusted using the Lumo style properties. These variants should be used only to differentiate special instances of the component.
|
Alignment
Top-level items are aligned by default to the start of the Menu Bar. Use instead the end-aligned
theme variant to align them to the end.
new tab
Source code
MenuBarRightAligned.java
menu-bar-right-aligned.tsx
menu-bar-right-aligned.ts
Styling Menu Items
Individual menu items can be styled by applying custom class names to them, and writing CSS style blocks targeting those class names. Notice that root-level menu items in the Menu Bar are wrapped in vaadin-menu-bar-button
elements, which inherit the class names from the items within them.
new tab
Source code
MenuBarCustomStyling.java
menu-bar-custom-styling.tsx
menu-bar-custom-styling.ts
Note
|
Use Theme Names, Not Class Names pre-V24.3
In versions prior to 24.3, theme names must be used instead of class names (theme property / addThemeNames Java method). The CSS syntax for targeting a theme name is [theme~="custom-theme"]
|
Drop-down Indicators
Menu buttons with sub-menu can be visually identified from items that trigger an action immediately using dropdown-indicators
theme variant.
new tab
Source code
MenuBarDropDownIndicators.java
menu-bar-drop-down-indicators.tsx
menu-bar-drop-down-indicators.ts
Overflow
Items that don’t fit into the current width of the menu bar collapse into an overflow menu at the end.
By default, collapsed items are removed from the end of the menu bar, but the component can be configured to remove items from the start instead.
new tab
Source code
MenuBarOverflow.java
menu-bar-overflow.tsx
menu-bar-overflow.ts
Menu Item Features
Several features are available for menu items. They’re described in the following sub-sections.
Icons
Menu items can have icons in addition to text — or instead of text.
new tab
Source code
MenuBarIcons.java
menu-bar-icons.tsx
menu-bar-icons.ts
Most actions are difficult to represent reliably with icons, so use them sparingly. The benefit of icons in addition to text should be weighed against the visual distractions they may create. Menu items in drop-down menus should always have text labels.
Icon-only menu buttons should be used primarily for common recurring actions with highly standardized, universally understood icons. Menu buttons should include a textual alternative for screen readers using the aria-label
attribute or tooltips. 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
Source code
MenuBarIconOnly.java
menu-bar-icon-only.tsx
menu-bar-icon-only.ts
Warning
|
Other Components in Menu Items
While it’s technically possible to put any UI element in a menu item, this can cause problems for accessibility as it may not be possible to focus them, and they may not be interpreted correctly by assistive technologies.
|
Disabled Items
Menu items can be disabled to show that they are unavailable currently.
new tab
Source code
MenuBarDisabled.java
menu-bar-disabled.tsx
menu-bar-disabled.ts
By default, disabled buttons (i.e., root-level items) are not focusable and cannot react to hover events. This can cause accessibility issues by making them entirely invisible to assistive technologies, and prevents the use of Tooltips to explain why the action is not available. This can be addressed by enabling the feature flag accessibleDisabledButtons
, which allows focusing and hovering on disabled buttons, while preventing them from being triggered:
Source code
Flow
Flow
# Add this line to src/main/resources/vaadin-featureflags.properties
com.vaadin.experimental.accessibleDisabledButtons=true
Lit & React
Lit & React
// Set before any button is added to the DOM
window.Vaadin.featureFlags.accessibleDisabledButtons = true;
Checkable Menu Items
Menu items in drop-down menus can be configured as checkable to toggle options on and off.
new tab
Source code
MenuBarCheckable.java
menu-bar-checkable.tsx
menu-bar-checkable.ts
Note
|
Not a Radio Button Replacement
A Menu Bar with checkable items shouldn’t be used as a replacement for radio buttons in a form.
|
Dividers
You can use dividers to separate and group related content. However, use dividers sparingly to avoid creating unnecessary visual clutter.
new tab
Source code
MenuBarDividers.java
menu-bar-dividers.tsx
menu-bar-dividers.ts
Warning
|
Other Content Not Accessible
While it’s technically possible to put any UI element in a drop-down menu — including interactive components — they’re not accessible by keyboard or assistive technologies.
|
Open on Hover
A component can be configured to open drop-down menus on hover, instead of on click.
new tab
Source code
MenuBarOpenOnHover.java
menu-bar-open-on-hover.tsx
menu-bar-open-on-hover.ts
Tooltips
Tooltips can be configured on top-level items to provide additional information, especially for icon-only items. When a top-level item is disabled, the corresponding tooltip isn’t shown.
new tab
Source code
MenuBarTooltip.java
menu-bar-tooltip.tsx
menu-bar-tooltip.ts
See the Tooltips documentation page for details on tooltip configuration.
Keyboard Usage
Drop-Down & Combo Buttons
A Menu Bar with a single top-level item is essentially a drop-down button. This solution provides a better user experience and better accessibility than a regular Button paired with a Context Menu.
new tab
Source code
MenuBarDropDown.java
menu-bar-drop-down.tsx
menu-bar-drop-down.ts
So-called combo buttons can be created in a similar way. For example, they can be created to provide a set of variations on an action.
new tab
Source code
MenuBarComboButtons.java
menu-bar-combo-buttons.tsx
menu-bar-combo-buttons.ts
Internationalization (i18n)
Menu Bar provides an API for localization. Currently, only the accessible label for the overflow menu button can be customized.
Source code
MenuBarInternationalization.java
package com.vaadin.demo.component.menubar;
import com.vaadin.flow.component.contextmenu.MenuItem;
import com.vaadin.flow.component.contextmenu.SubMenu;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.menubar.MenuBar;
import com.vaadin.flow.router.Route;
@Route("menu-bar-internationalization")
public class MenuBarInternationalization extends Div {
public MenuBarInternationalization() {
MenuBar menuBar = new MenuBar();
MenuBar.MenuBarI18n customI18n = new MenuBar.MenuBarI18n()
// Provide accessible label for the overflow menu button
// to screen readers
.setMoreOptions("More actions");
menuBar.setI18n(customI18n);
menuBar.addItem("View");
menuBar.addItem("Edit");
MenuItem share = menuBar.addItem("Share");
SubMenu shareSubMenu = share.getSubMenu();
MenuItem onSocialMedia = shareSubMenu.addItem("On social media");
SubMenu socialMediaSubMenu = onSocialMedia.getSubMenu();
socialMediaSubMenu.addItem("Facebook");
socialMediaSubMenu.addItem("Twitter");
socialMediaSubMenu.addItem("Instagram");
shareSubMenu.addItem("By email");
shareSubMenu.addItem("Get Link");
MenuItem move = menuBar.addItem("Move");
SubMenu moveSubMenu = move.getSubMenu();
moveSubMenu.addItem("To folder");
moveSubMenu.addItem("To trash");
menuBar.addItem("Duplicate");
add(menuBar);
}
}
menu-bar-internationalization.tsx
import React from 'react';
import { MenuBar, type MenuBarI18n, type MenuBarItem } from '@vaadin/react-components/MenuBar.js';
function Example() {
const items: MenuBarItem[] = [
{ 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' },
];
const customI18n: MenuBarI18n = {
// Provide accessible label for the overflow menu button
// to screen readers
moreOptions: 'More actions',
};
return <MenuBar i18n={customI18n} items={items} />;
}
menu-bar-internationalization.ts
import '@vaadin/menu-bar';
import '@vaadin/split-layout';
import { html, LitElement } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import type { MenuBarI18n } from '@vaadin/menu-bar';
import { applyTheme } from 'Frontend/generated/theme';
@customElement('menu-bar-internationalization')
export class Example extends LitElement {
protected override createRenderRoot() {
const root = super.createRenderRoot();
// Apply custom theme (only supported if your app uses one)
applyTheme(root);
return root;
}
@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' },
];
protected override render() {
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>`;
}
}
Custom Item Data
Menu Bar allows you to associate custom data with menu items. This can be useful for storing additional information about the item, such as an item type or a value. The data can then be used to trigger actions when an item is selected.
new tab
Source code
MenuBarCustomItemData.java
menu-bar-custom-item-data.tsx
menu-bar-custom-item-data.ts
Best Practices
Menu Bar shouldn’t be used for navigation. Use tabs to switch between content, or anchor elements for regular navigation. It isn’t an input field. Use instead Select, Combo Box, or Radio Button.
Menu Bar is an interactive component. Using other interactive components like Combo Box as menu items is not advised as this may produce conflicts in keyboard navigation and interaction. Although items are children of Menu Bar, it’s not supposed to act as a layout component.
Related Components
Component | Usage Recommendation |
---|---|
Regular Button component for individual actions. | |
Drop-down input field. | |
Tabs should be used to split content into sections that the user can switch between. | |
A generic drop-down menu that can be triggered from any component. | |
A generic overlay whose position is anchored to an element in the UI. |
BCC76FD2-FB02-4F71-A6DF-7574CAC1C662