Menubar

Displays a menu to the user, which can consist of links or functions, triggered by a button.

Features

  • Can be controlled or uncontrolled.
  • Supports submenus with configurable reading direction.
  • Customize menu positioning.
  • Optionally render a pointing arrow.
  • Fully managed focus.
  • Full keyboard navigation.
  • Typeahead support

Anatomy

  • Trigger: The button which toggles the menu's open state.
  • Menu: The root container for the popover menu
  • Item: A menuitem which can be a link or a function.
  • Checkbox Item: A menu item which can be checked or unchecked.
  • Radio Group: A group of radio items.
  • Radio Item: A menu item which can be selected from a group of items.
  • Sub Trigger: A button which toggles the submenu's open state.
  • Sub Menu: A menu which is nested inside another menu.
  • Separator: A visual divider between menu items.

Usage

The first thing you'll need to do is create a menubar using the createMenubar builder function.

    <script lang="ts">
  import { createMenubar } from '@melt-ui/svelte'
 
  const { menubar, createMenu } = createMenubar()
</script>

This function returns an object containing the menubar attributes object, and a createMenu function. The createMenu function is used the same way as the createDropdownMenu builder from the Dropdown Menu builder. The only difference is that using this function keeps the menu scoped to the menubar which happens behind the scenes.

Now that we have a menubar and menu builder function, we can create a menu using the createMenu function and wrap it in a menubar element.

    <script lang="ts">
  import { createMenubar } from '@melt-ui/svelte'
 
  const { menubar, createMenu } = createMenubar()
  const { menu, item, trigger } = createMenu()
</script>
 
<div {...menubar}>
  <button {...$trigger} use:trigger>Open Menu</button>
  <div {...$menu} use:menu>
    <div {...$item} use:item>...</div>
    <div {...$item} use:item>...</div>
    <div {...$item} use:item>...</div>
  </div>
</div>

This isn't much of a "menubar" though, as typically a menubar consists of multiple menus, so let's add a couple more.

Since each menu needs to have it's own "scope", we'll need to call the createMenu function again for each menu we want to create. If you're doing this all in one file, it can get a bit messy, so I'd recommend componentizing each menu. But for the sake of this example, we'll just rename the returned variables to prevent any naming conflicts.

    <script lang="ts">
  import { createMenubar } from '@melt-ui/svelte'
 
  const { menubar, createMenu } = createMenubar()
  const { menu, item, trigger } = createMenu()
  const { menu: menuA, item: itemA, trigger: triggerA } = createMenu()
  const { menu: menuB, item: itemB, trigger: triggerB } = createMenu()
</script>
 
<div {...menubar}>
  <button {...$trigger} use:trigger>File</button>
  <div {...$menu} use:menu>
    <div {...$item} use:item>...</div>
    <div {...$item} use:item>...</div>
    <div {...$item} use:item>...</div>
  </div>
 
  <button {...$triggerA} use:triggerA>Edit</button>
  <div {...$menuA} use:menuA>
    <div {...$itemA} use:itemA>...</div>
    <div {...$itemA} use:itemA>...</div>
    <div {...$itemA} use:itemA>...</div>
  </div>
 
  <button {...$triggerB} use:triggerB>Help</button>
  <div {...$menuB} use:menuB>
    <div {...$itemB} use:itemB>...</div>
    <div {...$itemB} use:itemB>...</div>
    <div {...$itemB} use:itemB>...</div>
  </div>
</div>

Now we have a menubar with three menus, each with their own items and scopes. As mentioned previously, the functionality of createMenu is the exact same as createDropdownMenu, so you can refer to the Dropdown Menu documentation for more information on how to use it.

API Reference

createMenubar

Props

Prop Default Type / Description
loop true
boolean

Whether or not the focus should loop back to the first item when the last item is reached.

createMenu

Props

Prop Default Type / Description
positioning placement: 'bottom'
FloatingConfig

A configuration object which determines how the floating element is positioned relative to the trigger.

arrowSize 8
number

The size of the arrow which points to the trigger in pixels.

preventScroll true
boolean

Whether or not to prevent scrolling of the document when the menu is open.

loop false
boolean

Whether or not the focus should loop back to the first item when the last item is reached.

Returned Props

Returned Prop Type Description
open
Writable<boolean>

A writable store that controls the open state of the menubar menu.

options
Writable<CreateMenubarMenuProps>

A writable store that controls the options of the menubar menu.

menu
-

The builder store used to create the menubar menu.

trigger
-

The builder store used to create the menubar menu trigger.

checkboxItem
-

The builder store used to create a checkbox menu item.

separator
-

The builder store used to create a separator menu item.

arrow
-

The builder store used to create the menubar menu arrow.

trigger

Data Attributes

Data Attribute Value
[data-state]

'open' | 'closed'

[data-melt-menubar-menu-trigger]

Present on all trigger elements.

Data Attributes

Data Attribute Value
[data-state]

'open' | 'closed'

[data-melt-menubar-menu]

Present on all menu elements.

item

Props

Prop Default Type / Description
onSelect undefined
(e: Event) => void | undefined

A callback which is called when the item is selected. To prevent the default behavior, call e.preventDefault() in the callback.

Data Attributes

Data Attribute Value
[data-orientation]

'vertical' | 'horizontal'

[data-melt-menubar-menu-item]

Present on all item elements.

checkboxItem

Props

Prop Default Type / Description
checked Writable<false>
Writable<boolean>

A writable boolean which determines whether or not the checkbox is checked.

onSelect undefined
(e: Event) => void | undefined

A callback which is called when the item is selected. To prevent the default behavior, call e.preventDefault() in the callback.

Data Attributes

Data Attribute Value
[data-orientation]

'vertical' | 'horizontal'

[data-melt-menubar-menu-checkbox-item]

Present on all checkbox item elements.

createMenuRadioGroup

Props

Prop Default Type / Description
value -
string

The value of the selected radio item.

Returned Props

Returned Prop Type Description
value
Writable<string | null>

A writable store which controls the value of the selected radio item.

isChecked
Readable<(itemValue: string) => boolean>

A derived store which returns a function that checks if a radio item is selected.

radioGroup
-

The builder store used to create the radio group.

radioItem
-

The builder store used to create a radio menu item.

radioGroup

Data Attributes

Data Attribute Value
[data-melt-menubar-menu-radio-group]

Present on all radio group elements.

radioItem

Props

Prop Default Type / Description
value * -
string

The value of the radio item.

disabled false
boolean

Whether the radio item is disabled.

onSelect -
(e: Event) => void

A callback which is called when the item is selected. To prevent the default behavior, call e.preventDefault() in the callback.

Data Attributes

Data Attribute Value
[data-checked]

'checked' | 'unchecked'

[data-disabled]

Present when the radio item is disabled.

[data-value]

The value of the radio item.

[data-orientation]

'vertical' | 'horizontal'

[data-melt-menubar-menu-radio-item]

Present on all radio item elements.

[data-highlighted]

Present when the radio item is highlighted.

createSubmenu

Props

Prop Default Type / Description
positioning placement: 'right'
FloatingConfig

A configuration object which determines how the floating element is positioned relative to the trigger.

disabled false
boolean

Whether or not the submenu is disabled.

Returned Props

Returned Prop Type Description
subOpen
Writable<boolean>

A writable store that controls the open state of the submenu.

options
Writable<CreateMenubarSubmenuProps>

A writable store that controls the options of the submenu.

subMenu
-

The store used to create the submenu.

subTrigger
-

The builder store used to create the submenu trigger.

arrow
-

The builder store used to create the submenumenu arrow.

subTrigger

Data Attributes

Data Attribute Value
[data-state]

'open' | 'closed'

[data-disabled]

Present when the subtrigger is disabled.

[data-melt-menubar-menu-subtrigger]

Present on all subtrigger elements.

Data Attributes

Data Attribute Value
[data-state]

'open' | 'closed'

[data-melt-menubar-menu-submenu]

Present on all submenu elements.

separator

Data Attributes

Data Attribute Value
[data-melt-menubar-menu-separator]

Present on all separator elements.

arrow

Data Attributes

Data Attribute Value
[data-arrow]

'true'

[data-melt-menubar-menu-arrow]

Present on all arrow elements.

Accessibility

Adheres to the Menu WAI-ARIA design pattern & Menu Button WAI-ARIA design pattern

Key Behavior
Space

When focused on the trigger, opens the associated menu. When focused on an item, selects the item.

Enter

When focused on the trigger, opens the associated menu. When focused on an item, selects the item.

ArrowDown

When focused on a trigger, opens the associated menu. When focused on an item, shifts focus to the next item.

ArrowUp

When focused on an item, shifts focus to the next item..

ArrowRight

When focused on a subTrigger, opens the subMenu and focuses the first item. When focus is within the menu, opens the next menu in the menubar

ArrowLeft

When focused on within a subMenu, closes the submenu and shifts focus to that submenu's subTrigger. When focus is within the menu, opens the previous menu in the menubar

Esc

Closes the open menu and focuses that menu's trigger.