> Markdown version of [Menu Bar](https://vaadin.com/docs/latest/components/menu-bar). Section index: [llms.txt](https://vaadin.com/docs/latest/components/llms.txt)

# Menu Bar

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.

**Lit** — `menu-bar-basic.ts`

```typescript
@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 | undefined;
    <vaadin-menu-bar
      .items="${this.items}"
      @item-selected="${this.itemSelected}"
    ></vaadin-menu-bar>

    <div>Clicked item: ${this.selectedItem?.text}</div>
```

**Flow** — `MenuBarBasic.java`

```java
MenuBar menuBar = new MenuBar();
Text selected = new Text("");
ComponentEventListener<ClickEvent<MenuItem>> listener = e -> selected
        .setText(e.getSource().getText());
Div message = new Div(new Text("Clicked item: "), selected);

menuBar.addItem("View", listener);
menuBar.addItem("Edit", listener);

MenuItem share = menuBar.addItem("Share");
SubMenu shareSubMenu = share.getSubMenu();
MenuItem onSocialMedia = shareSubMenu.addItem("On social media");
SubMenu socialMediaSubMenu = onSocialMedia.getSubMenu();
socialMediaSubMenu.addItem("Facebook", listener);
socialMediaSubMenu.addItem("Twitter", listener);
socialMediaSubMenu.addItem("Instagram", listener);
shareSubMenu.addItem("By email", listener);
shareSubMenu.addItem("Get Link", listener);

MenuItem move = menuBar.addItem("Move");
SubMenu moveSubMenu = move.getSubMenu();
moveSubMenu.addItem("To folder", listener);
moveSubMenu.addItem("To trash", listener);

menuBar.addItem("Duplicate", listener);
```

**React** — `menu-bar-basic.tsx`

```tsx
const selectedItem = useSignal<MenuBarItem | undefined>(undefined);

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' },
];

return (
  <>
    <MenuBar
      items={items}
      onItemSelected={(event) => {
        selectedItem.value = event.detail.value;
      }}
    />
    <div>Clicked item: {selectedItem.value?.text}</div>
  </>
);
```

## <a id="overflow"></a>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.

**Lit** — `menu-bar-overflow.ts`

```typescript
@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>
```

**Flow** — `MenuBarOverflow.java`

```java
MenuBar menuBar = new MenuBar();
addItems(menuBar);
Div div = new Div();
div.setText("Move the splitter to see overflow feature");

SplitLayout splitLayout = new SplitLayout(menuBar, div);
```

**React** — `menu-bar-overflow.tsx`

```tsx
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' },
];

return (
  <SplitLayout>
    <MenuBar items={items} />
    <div>Move the splitter to see overflow feature</div>
  </SplitLayout>
);
```

## <a id="menu-item-features"></a>Menu Item Features

Several features are available for menu items. They’re described in the following sub-sections.

### <a id="icons"></a>Icons

Menu items can have icons in addition to text — or instead of text.

**Lit** — `menu-bar-icons.ts`

```typescript
@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>
```

**Flow** — `MenuBarIcons.java`

```java
MenuBar menuBar = new MenuBar();
menuBar.addThemeVariants(MenuBarVariant.LUMO_ICON);
MenuItem share = createIconItem(menuBar, VaadinIcon.SHARE, "Share",
        null);
SubMenu shareSubMenu = share.getSubMenu();
createIconItem(shareSubMenu, VaadinIcon.SHARE, "By Email", null, true);
createIconItem(shareSubMenu, VaadinIcon.LINK, "Get link", null, true);
createIconItem(menuBar, VaadinIcon.COPY, null, "duplicate");

...

private MenuItem createIconItem(HasMenuItems menu, VaadinIcon iconName,
        String label, String ariaLabel) {
    return createIconItem(menu, iconName, label, ariaLabel, false);
}

private MenuItem createIconItem(HasMenuItems menu, VaadinIcon iconName,
        String label, String ariaLabel, boolean isChild) {
    Icon icon = new Icon(iconName);

    if (isChild) {
        icon.getStyle().setWidth("1.25rem");
        icon.getStyle().setHeight("1.25rem");
        icon.getStyle().setMarginRight("var(--vaadin-gap-s)");
    }

    MenuItem item = menu.addItem(icon, e -> {
    });

    if (ariaLabel != null) {
        item.setAriaLabel(ariaLabel);
    }

    if (label != null) {
        item.add(new Text(label));
    }

    return item;
}
```

**React** — `menu-bar-icons.tsx`

```tsx
const items: MenuBarItem[] = [
  {
    component: createItem('share', 'Share'),
    children: [
      { component: createItem('share', 'By email', true) },
      { component: createItem('link', 'Get link', true) },
    ],
  },
  {
    component: createItem('copy', ''),
  },
];

return <MenuBar theme="icon" items={items} />;
```

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. Top-level items that open a drop-down menu are easier to recognize with the [`dropdown-indicators`](https://vaadin.com/docs/latest/components/menu-bar/styling.md#drop-down-indicators) theme variant.

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](#tooltips). Menu Bars with icon-only top-level items can use the **Tertiary Inline** style variant or the `icon` theme variant (both Lumo only) to reduce the horizontal padding around the icons. The `icon` variant also hides drop-down indicators, even when the `dropdown-indicators` variant is applied, so avoid combining the two if the indicators are needed.

**Lit** — `menu-bar-icon-only.ts`

```typescript
@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>
```

**Flow** — `MenuBarIconOnly.java`

```java
MenuBar menuBar = new MenuBar();
menuBar.addThemeVariants(MenuBarVariant.LUMO_TERTIARY_INLINE);

createIconItem(menuBar, VaadinIcon.EYE, "View");
createIconItem(menuBar, VaadinIcon.PENCIL, "Edit");

MenuItem share = createIconItem(menuBar, VaadinIcon.SHARE, "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 = createIconItem(menuBar, VaadinIcon.FOLDER, "Move");
SubMenu moveSubMenu = move.getSubMenu();
moveSubMenu.addItem("To folder");
moveSubMenu.addItem("To trash");

createIconItem(menuBar, VaadinIcon.COPY, "Duplicate");

...

private MenuItem createIconItem(MenuBar menu, VaadinIcon iconName,
        String ariaLabel) {
    Icon icon = new Icon(iconName);
    MenuItem item = menu.addItem(icon);
    item.setAriaLabel(ariaLabel);

    return item;
}
```

**React** — `menu-bar-icon-only.tsx`

```tsx
const items: MenuBarItem[] = [
  { component: createItem('eye', 'View') },
  { component: createItem('pencil', 'Edit') },
  {
    component: createItem('share', 'Share'),
    children: [
      {
        text: 'On social media',
        children: [{ text: 'Facebook' }, { text: 'Twitter' }, { text: 'Instagram' }],
      },
      { text: 'By email' },
      { text: 'Get link' },
    ],
  },
  {
    component: createItem('folder', 'Move'),
    children: [{ text: 'To folder' }, { text: 'To trash' }],
  },
  { component: createItem('copy', 'Duplicate') },
];

return <MenuBar theme="icon" items={items} />;
```

> **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.

### <a id="disabled-items"></a>Disabled Items

Menu items can be disabled to show that they are unavailable currently.

**Lit** — `menu-bar-disabled.ts`

```typescript
@state()
private items = [
  { text: 'View' },
  { text: 'Edit', disabled: true },
  {
    text: 'Share',
    children: [{ text: 'By email', disabled: true }, { text: 'Get link' }],
  },
];
```

**Flow** — `MenuBarDisabled.java`

```java
MenuBar menuBar = new MenuBar();

menuBar.addItem("View");
MenuItem edit = menuBar.addItem("Edit");
edit.setEnabled(false);

MenuItem share = menuBar.addItem("Share");
SubMenu shareSubMenu = share.getSubMenu();
shareSubMenu.addItem("By email").setEnabled(false);
shareSubMenu.addItem("Get Link");
```

**React** — `menu-bar-disabled.tsx`

```tsx
const items: MenuBarItem[] = [
  { text: 'View' },
  { text: 'Edit', disabled: true },
  {
    text: 'Share',
    children: [{ text: 'By email', disabled: true }, { text: 'Get link' }],
  },
];

return <MenuBar items={items} />;
```

By default, disabled buttons (i.e., root-level items) aren’t focusable or hoverable, which hides them from assistive technologies and prevents Tooltips on disabled buttons from showing. The `accessibleDisabledButtons` feature flag can be enabled to make them focusable and hoverable without allowing them to be triggered:

`Flow`

```properties
# Add this line to src/main/resources/vaadin-featureflags.properties
com.vaadin.experimental.accessibleDisabledButtons=true
```

`Lit & React`

```js
// Set before any button is added to the DOM
window.Vaadin.featureFlags.accessibleDisabledButtons = true;
```

Similarly, the `accessibleDisabledMenuItems` (since V25.2) feature flag can be enabled to make disabled sub-menu items focusable and hoverable without allowing them to be triggered:

`Flow`

```properties
# Add this line to src/main/resources/vaadin-featureflags.properties
com.vaadin.experimental.accessibleDisabledMenuItems=true
```

`Lit & React`

```js
// Set before any menu is added to the DOM
window.Vaadin.featureFlags.accessibleDisabledMenuItems = true;
```

### <a id="checkable-menu-items"></a>Checkable Menu Items

Menu items in drop-down menus can be configured as checkable to toggle options on and off.

**Lit** — `menu-bar-checkable.ts`

```typescript
@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;
}
```

**Flow** — `MenuBarCheckable.java`

```java
MenuBar menuBar = new MenuBar();
MenuItem options = menuBar.addItem("Options");
SubMenu subItems = options.getSubMenu();

MenuItem saveItem = subItems.addItem("Save automatically");
saveItem.setCheckable(true);
saveItem.setChecked(true);
MenuItem notifyItem = subItems.addItem("Notify watchers");
notifyItem.setCheckable(true);
notifyItem.setChecked(false);

ComponentEventListener<ClickEvent<MenuItem>> listener = event -> {
    // System.out.println(event.getSource().isChecked());
};

saveItem.addClickListener(listener);
notifyItem.addClickListener(listener);
```

**React** — `menu-bar-checkable.tsx`

```tsx
const items = useSignal<MenuBarItem[]>([
  {
    text: 'Options',
    children: [{ text: 'Save automatically', checked: true }, { text: 'Notify watchers' }],
  },
]);

const itemSelected = (e: MenuBarItemSelectedEvent) => {
  const item = e.detail.value;
  (item as SubMenuItem).checked = !(item as SubMenuItem).checked;
  items.value = [...items.value];
};

return <MenuBar items={items.value} onItemSelected={itemSelected} />;
```

> **Note: Not a Radio Button Replacement**
>
> A Menu Bar with checkable items shouldn’t be used as a replacement for [radio buttons](https://vaadin.com/docs/latest/components/radio-button.md) in a form.

## <a id="dividers"></a>Dividers

You can use dividers to separate and group related content. However, use dividers sparingly to avoid creating unnecessary visual clutter.

**Lit** — `menu-bar-dividers.ts`

```typescript
@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>
```

**Flow** — `MenuBarDividers.java`

```java
MenuBar menuBar = new MenuBar();
MenuItem item = menuBar.addItem("Share");
SubMenu subMenu = item.getSubMenu();
subMenu.addItem("Facebook");
subMenu.addItem("Twitter");
subMenu.addItem("Instagram");
subMenu.addSeparator();
subMenu.addItem("By email");
subMenu.addItem("Get link");
subMenu.addSeparator();
subMenu.addItem("Set permissions");
```

**React** — `menu-bar-dividers.tsx`

```tsx
const items: MenuBarItem[] = [
  {
    text: 'Share',
    children: [
      { text: 'Facebook' },
      { text: 'Twitter' },
      { text: 'Instagram' },
      { component: 'hr' },
      { text: 'By email' },
      { text: 'Get link' },
      { component: 'hr' },
      { text: 'Set permissions' },
    ],
  },
];

return <MenuBar items={items} />;
```

> **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.

## <a id="open-on-hover"></a>Open on Hover

A component can be configured to open drop-down menus on hover, instead of on click.

**Lit** — `menu-bar-open-on-hover.ts`

```typescript
@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>
```

**Flow** — `MenuBarOpenOnHover.java`

```java
MenuBar menuBar = new MenuBar();
menuBar.setOpenOnHover(true);
addItems(menuBar);
```

**React** — `menu-bar-open-on-hover.tsx`

```tsx
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' },
];

return <MenuBar items={items} openOnHover />;
```

## <a id="tooltips"></a>Tooltips

Both top-level and sub-menu items (since V25.2) can be configured with tooltips to provide additional context, such as labels for icon-only menu buttons.

**Lit** — `menu-bar-tooltip.ts`

```typescript
@state()
private items = [
  {
    component: this.createItem('eye'),
    tooltip: 'View',
  },
  {
    component: this.createItem('pencil'),
    tooltip: 'Edit',
  },
  {
    component: this.createItem('folder'),
    tooltip: 'Move',
    children: [
      { text: 'To folder…', tooltip: 'Choose a destination folder' },
      { text: 'To archive', tooltip: 'Move to archive', tooltipPosition: 'end' },
    ],
  },
  {
    component: this.createItem('copy'),
    tooltip: 'Duplicate',
  },
  {
    component: this.createItem('trash'),
    tooltip: 'Delete',
    disabled: true,
  },
];

...

<vaadin-menu-bar .items="${this.items}" theme="icon">
  <vaadin-tooltip slot="tooltip"></vaadin-tooltip>
</vaadin-menu-bar>
```

**Flow** — `MenuBarTooltip.java`

```java
MenuBar menuBar = new MenuBar();
menuBar.addThemeVariants(MenuBarVariant.LUMO_ICON);

createIconItem(menuBar, VaadinIcon.EYE, "View");
createIconItem(menuBar, VaadinIcon.PENCIL, "Edit");

MenuItem move = createIconItem(menuBar, VaadinIcon.FOLDER, "Move");
SubMenu moveSubMenu = move.getSubMenu();
moveSubMenu.addItem("To folder…")
        .setTooltipText("Choose a destination folder");
MenuItem toArchive = moveSubMenu.addItem("To archive");
toArchive.setTooltipText("Move to archive");
toArchive.setTooltipPosition(TooltipPosition.END);

createIconItem(menuBar, VaadinIcon.COPY, "Duplicate");
MenuItem delete = createIconItem(menuBar, VaadinIcon.TRASH, "Delete");
delete.setEnabled(false);

...

private MenuItem createIconItem(MenuBar menu, VaadinIcon iconName,
        String tooltipText) {
    Icon icon = new Icon(iconName);
    MenuItem item = menu.addItem(icon);
    item.setTooltipText(tooltipText);
    return item;
}
```

**React** — `menu-bar-tooltip.tsx`

```tsx
const items: MenuBarItem[] = [
  { component: createItem('eye'), tooltip: 'View' },
  { component: createItem('pencil'), tooltip: 'Edit' },
  {
    component: createItem('folder'),
    tooltip: 'Move',
    children: [
      { text: 'To folder…', tooltip: 'Choose a destination folder' },
      { text: 'To archive', tooltip: 'Move to archive', tooltipPosition: 'end' },
    ],
  },
  { component: createItem('copy'), tooltip: 'Duplicate' },
  { component: createItem('trash'), tooltip: 'Delete', disabled: true },
];

return (
  <MenuBar items={items} theme="icon">
    <Tooltip slot="tooltip" />
  </MenuBar>
);
```

See the [Tooltips documentation page](https://vaadin.com/docs/latest/components/tooltip.md) for details on tooltip configuration.

Tooltips are also useful on disabled menu items to explain why an action is unavailable, but they are not shown by default. See [Disabled Items](#disabled-items) for how to enable them.

## <a id="keyboard-usage"></a>Keyboard Usage

### <a id="top-level-items"></a>Top-Level Items

| Interaction                         | Keyboard Shortcut             |
| ----------------------------------- | ----------------------------- |
| Navigate between top-level items.   | `Left` and `Right` arrow keys |
| Open top-level menu.                | `Down` / `Space` / `Enter`    |
| Trigger top-level item with a menu. | `Space` / `Enter`             |

### <a id="menu-items"></a>Menu-Items

| Interaction                                 | Keyboard Shortcut           |
| ------------------------------------------- | --------------------------- |
| Navigate between items in a drop-down menu. | `Up` and `Down` arrow keys  |
| Open sub-menu.                              | `Right` / `Space` / `Enter` |
| Trigger menu item without a sub-menu.       | `Space` / `Enter`           |
| Return to previous menu.                    | `Left`                      |
| Close the drop-down menu.                   | `Esc`                       |

## <a id="dropdown-buttons"></a>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](https://vaadin.com/docs/latest/components/button.md) paired with a [Context Menu](https://vaadin.com/docs/latest/components/context-menu.md).

**Lit** — `menu-bar-drop-down.ts`

```typescript
@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>
```

**Flow** — `MenuBarDropDown.java`

```java
MenuBar menuBar = new MenuBar();
MenuItem item = menuBar.addItem("John Smith");
SubMenu subMenu = item.getSubMenu();
subMenu.addItem("Profile");
subMenu.addItem("Account");
subMenu.addItem("Preferences");
subMenu.addSeparator();
subMenu.addItem("Sign out");
```

**React** — `menu-bar-drop-down.tsx`

```tsx
const items: MenuBarItem[] = [
  {
    text: 'John Smith',
    children: [
      { text: 'Profile' },
      { text: 'Account' },
      { text: 'Preferences' },
      { component: 'hr' },
      { text: 'Sign out' },
    ],
  },
];

return <MenuBar items={items} />;
```

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.

**Lit** — `menu-bar-combo-buttons.ts`

```typescript
@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}"
      style="--vaadin-icon-size: 0; --vaadin-button-gap: var(--vaadin-gap-xs);"
    ></vaadin-menu-bar>
```

**Flow** — `MenuBarComboButtons.java`

```java
MenuBar menuBar = new MenuBar();
menuBar.addThemeVariants(MenuBarVariant.PRIMARY);
// Only for Lumo
menuBar.addThemeVariants(MenuBarVariant.LUMO_ICON,
        MenuBarVariant.LUMO_DROPDOWN_INDICATORS);
menuBar.getStyle().set("--vaadin-icon-size", "0")
        .set("--vaadin-button-gap", "var(--vaadin-gap-xs)");
menuBar.addItem("Save");
Icon icon = new Icon(VaadinIcon.CHEVRON_DOWN);
icon.getStyle().set("--vaadin-icon-size", "1lh");
MenuItem item = menuBar.addItem(icon);
SubMenu subItems = item.getSubMenu();
subItems.addItem("Save as draft");
subItems.addItem("Save as copy");
subItems.addItem("Save and publish");
```

**React** — `menu-bar-combo-buttons.tsx`

```tsx
const items: MenuBarItem[] = [
  { text: 'Save' },
  {
    component: (
      <Icon
        icon="vaadin:chevron-down"
        aria-label="Other save options"
        style={{ '--vaadin-icon-size': '1lh' }}
      />
    ),
    children: [{ text: 'Save as draft' }, { text: 'Save as copy' }, { text: 'Save and publish' }],
  },
];

return (
  <MenuBar
    theme="icon primary"
    items={items}
    style={{ '--vaadin-icon-size': '0', '--vaadin-button-gap': 'var(--vaadin-gap-xs)' }}
  />
);
```

## <a id="internationalization-i18n"></a>Internationalization (i18n)

Menu Bar provides an API for localization. Currently, only the accessible label for the overflow menu button can be customized.

**Lit** — `menu-bar-internationalization.ts`

```typescript
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>`;
```

**Flow** — `MenuBarInternationalization.java`

```java
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);
```

**React** — `menu-bar-internationalization.tsx`

```tsx
const customI18n: MenuBarI18n = {
  // Provide accessible label for the overflow menu button
  // to screen readers
  moreOptions: 'More actions',
};

return <MenuBar i18n={customI18n} items={items} />;
```

## <a id="custom-item-data"></a>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.

**Lit** — `menu-bar-custom-item-data.ts`

```typescript
@state()
private items: Array<MenuBarItem<{ value?: string }>> = [
  {
    text: 'Copy',
    children: [
      {
        text: 'Copy as plain text',
        value:
          'Menu Bar\n\nMenu Bar is a horizontal button bar with hierarchical drop-down menus.',
      },
      {
        text: 'Copy as HTML',
        value:
          '<h1>Menu Bar</h1><p>Menu Bar is a horizontal button bar with hierarchical drop-down menus.</p>',
      },
      {
        text: 'Copy as Markdown',
        value:
          '# Menu Bar\n\nMenu Bar is a horizontal button bar with hierarchical drop-down menus.',
      },
    ],
  },
];

protected override render() {
  return html`
    <vaadin-menu-bar
      .items="${this.items}"
      @item-selected="${this.itemSelected}"
    ></vaadin-menu-bar>
  `;
}

itemSelected(e: MenuBarItemSelectedEvent<MenuBarItem<{ value?: string }>>) {
  const { value } = e.detail.value;
  if (value) {
    navigator.clipboard.writeText(value);
  }
}
```

**Flow** — `MenuBarCustomItemData.java`

```java
MenuBar menuBar = new MenuBar();
MenuItem copy = menuBar.addItem("Copy");
SubMenu copySubMenu = copy.getSubMenu();

copySubMenu.addItem("Copy as plain text", event -> {
    // Provide a custom value by adding a click listener that holds a
    // reference to that value
    String value = "Menu Bar\n\nMenu Bar is a horizontal button bar with hierarchical drop-down menus.";
    copyToClipboard(value);
});

copySubMenu.addItem("Copy as HTML", event -> {
    String value = "<h1>Menu Bar</h1><p>Menu Bar is a horizontal button bar with hierarchical drop-down menus.</p>";
    copyToClipboard(value);
});

copySubMenu.addItem("Copy as Markdown", event -> {
    String value = "# Menu Bar\n\nMenu Bar is a horizontal button bar with hierarchical drop-down menus.";
    copyToClipboard(value);
});
```

**React** — `menu-bar-custom-item-data.tsx`

```tsx
const items: Array<MenuBarItem<{ value?: string }>> = [
  {
    text: 'Copy',
    children: [
      {
        text: 'Copy as plain text',
        value:
          'Menu Bar\n\nMenu Bar is a horizontal button bar with hierarchical drop-down menus.',
      },
      {
        text: 'Copy as HTML',
        value:
          '<h1>Menu Bar</h1><p>Menu Bar is a horizontal button bar with hierarchical drop-down menus.</p>',
      },
      {
        text: 'Copy as Markdown',
        value:
          '# Menu Bar\n\nMenu Bar is a horizontal button bar with hierarchical drop-down menus.',
      },
    ],
  },
];

return (
  <MenuBar
    items={items}
    onItemSelected={(event) => {
      const { value } = event.detail.value;
      if (value) {
        navigator.clipboard.writeText(value);
      }
    }}
  />
);
```

## <a id="best-practices"></a>Best Practices

Menu Bar shouldn’t be used for navigation. Use [Tabs](https://vaadin.com/docs/latest/components/tabs.md) to switch between content, or anchor elements for regular navigation. It isn’t an input field. Use instead [Select](https://vaadin.com/docs/latest/components/select.md), [Combo Box](https://vaadin.com/docs/latest/components/combo-box.md), or [Radio Button Group](https://vaadin.com/docs/latest/components/radio-button.md).

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.

## <a id="related-components"></a>Related Components

| Component                                                                 | Usage Recommendation                                                                 |
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| [Button](https://vaadin.com/docs/latest/components/button.md)             | Regular Button component for individual actions.                                     |
| [Select](https://vaadin.com/docs/latest/components/select.md)             | Drop-down input field.                                                               |
| [Tabs](https://vaadin.com/docs/latest/components/tabs.md)                 | Tabs should be used to split content into sections that the user can switch between. |
| [Context Menu](https://vaadin.com/docs/latest/components/context-menu.md) | A generic drop-down menu that can be triggered from any component.                   |
| [Popover](https://vaadin.com/docs/latest/components/popover.md)           | A generic overlay whose position is anchored to an element in the UI.                |

`BCC76FD2-FB02-4F71-A6DF-7574CAC1C662`
