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

The builder function used to create the menubar component.

Props

Prop Default Type / Description
closeOnEscape true
boolean

Whether or not to close the menubar when the escape key is pressed.

loop false
boolean

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

preventScroll true
boolean

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

ids -
Record<'menubar', string>

Override the internally generated ids for the elements.

Builders

Builder Description
createMenu

Creates a menu inside the menubar

Options

Option Description
closeOnEscape

Whether or not to close the menubar when the escape key is pressed.

loop

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

preventScroll

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

IDs

Option Description
menubar

The writable store that represents the id of the menubar element.

createMenu

The builder function used to create the dropdown menu component.

Props

Prop Default Type / Description
arrowSize 8
number

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

dir 'ltr'
'ltr' | 'rtl'

The direction of the text in the dropdown menu .

closeOnEscape true
boolean

Whether or not to close the dropdown menu when the escape key is pressed.

portal body
string | HTMLElement | null

The element or selector to render the dropdown menu into. Nested floating elements are automatically rendered into their parent if not specified. Pass in null to disable portalling.

closeOnOutsideClick true
boolean

Whether or not to close the dropdown menu when the user clicks outside of it.

loop false
boolean

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

forceVisible false
boolean

Whether or not to force the dropdown menu to always be visible. This is useful for custom transitions and animations using conditional blocks.

defaultOpen false
boolean

Whether the dropdown menu is open by default or not.

open -
Writable<boolean>

A writable store that controls whether or not the dropdown menu is open.

See Bring Your Own Store

onOpenChange -
ChangeFn<boolean>

A callback called when the value of the open store should be changed.

See Change Functions

closeFocus -

Override the default focus behavior on close

ids -
Record<'trigger' | 'menu', string>

Override the internally generated ids for the elements.

positioning placement: 'bottom'

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

Elements

Element Description

The builder store used to create the dropdown menu.

The builder store used to create the dropdown menu trigger.

The builder store used to create a separator menu item.

The builder store used to create the dropdown menu arrow.

The builder store used to create the dropdown menu item

The builder store used to group menu items together. It takes in a unique key to group menu items together.

The builder store used to create the group label for the dropdown menu.

Builders

Builder Description
createSubmenu

A builder function used to create a submenu for the dropdown menu.

createRadioGroup

A builder function used to create a radio group for the dropdown menu.

createCheckboxItem

A builder function used to create a checkbox menu item for the dropdown menu.

States

State Description
open

A writable store that indicates whether the dropdown menu is open.

Options

Option Description
positioning

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

arrowSize

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

dir

The direction of the text in the dropdown menu .

closeOnEscape

Whether or not to close the dropdown menu when the escape key is pressed.

portal

The element or selector to render the dropdown menu into. Nested floating elements are automatically rendered into their parent if not specified. Pass in null to disable portalling.

closeOnOutsideClick

Whether or not to close the dropdown menu when the user clicks outside of it.

loop

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

forceVisible

Whether or not to force the dropdown menu to always be visible. This is useful for custom transitions and animations using conditional blocks.

closeFocus

Override the default focus behavior on close

trigger

The button which toggles the dropdown menu.

Data Attributes

Data Attribute Value
[data-state]

'open' | 'closed'

[data-melt-menubar-menu-trigger]

Present on all trigger elements.

Custom Events

Event Value
m-click (e: ) => void
m-keydown (e: ) => void
m-pointerenter (e: ) => void

The element which wraps the entire menu.

Data Attributes

Data Attribute Value
[data-state]

'open' | 'closed'

[data-melt-menubar-menu]

Present on all menubar menu elements.

Custom Events

Event Value
m-keydown (e: ) => void

item

A basic menu item.

Props

Prop Default Type / Description
disabled false
boolean

Whether or not the item is disabled.

Data Attributes

Data Attribute Value
[data-orientation]

'vertical' | 'horizontal'

[data-menubar-menu-item]

Present on all item elements.

[data-highlighted]

Present when the item is highlighted.

Custom Events

Event Value
m-pointerdown (e: ) => void
m-click (e: ) => void
m-keydown (e: ) => void
m-pointermove (e: ) => void
m-pointerleave (e: ) => void
m-focusin (e: ) => void
m-focusout (e: ) => void

checkboxItem

A checkbox menu item.

Props

Prop Default Type / Description
disabled false
boolean

Whether or not the checkboxItem is disabled.

Data Attributes

Data Attribute Value
[data-orientation]

'vertical' | 'horizontal'

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

Present on all checkbox item elements.

[data-highlighted]

Present when the checkbox item is highlighted.

Custom Events

Event Value
m-pointerdown (e: ) => void
m-click (e: ) => void
m-keydown (e: ) => void
m-pointermove (e: ) => void
m-pointerleave (e: ) => void
m-focusin (e: ) => void
m-focusout (e: ) => void

createRadioGroup

The builder function used to create the radio group component.

Props

Prop Default Type / Description
defaultValue -
string

The value of the radio item to be selected by default.

value -
Writable<string | null>

A writable store which controls the value of the selected radio item. This will override the defaultValue prop if both are provided, so ensure to set your preferred default value as the default value of the store.

See Bring Your Own Store

onValueChange -
ChangeFn<string | null>

A callback called when the value of thevaluestore should be changed.

See Change Functions

Elements

Element Description

The builder store used to create the radio group.

The builder store used to create a radio menu item.

States

State Description
value

A writable store containing the current value of the radio group.

Helpers

Helper Description
isChecked

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

radioGroup

A group of radio menu items.

Data Attributes

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

Present on all radio group elements.

radioItem

A radiogroup menu item.

Props

Prop Default Type / Description
value * -
string

The value of the radio item.

disabled false
boolean

Whether or not the radioItem is disabled.

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.

Custom Events

Event Value
m-pointerdown (e: ) => void
m-click (e: ) => void
m-keydown (e: ) => void
m-pointermove (e: ) => void
m-pointerleave (e: ) => void
m-focusin (e: ) => void
m-focusout (e: ) => void

group

A function which takes in a unique key to group menu items together.

Props

Prop Default Type / Description
key -
string

A unique key for the group.

Data Attributes

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

Present on all group elements.

groupLabel

A function which takes in a unique key to group menu items together.

Props

Prop Default Type / Description
key -
string

A unique key for the group.

Data Attributes

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

Present on all group-label elements.

createSubMenu

The builder function used to create submenus for context & dropdown menus.

Props

Prop Default Type / Description
positioning placement: 'right-start'

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.

disabled false
boolean

Whether or not the submenu is disabled.

open -
Writable<boolean>

A writable store that controls whether or not the submenu is open.

See Bring Your Own Store

onOpenChange -
ChangeFn<boolean>

A callback called when the value of the open store should be changed.

See Change Functions

ids -
Record<'trigger' | 'menu', string>

Override the internally generated ids for the elements.

Elements

Element Description

The builder store used to create the submenu.

The builder store used to create the submenu trigger.

The builder store used to create the submenu arrow.

States

State Description
subOpen

A writable store with the open state of the submenu.

Options

Option Description
positioning

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

arrowSize

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

disabled

Whether or not the submenu is disabled.

subTrigger

A button which opens its associated submenu.

Props

Prop Default Type / Description
disabled false
boolean

Whether or not the subTrigger is disabled.

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-highlighted]

Present when the subtrigger is highlighted.

Custom Events

Event Value
m-click (e: ) => void
m-keydown (e: ) => void
m-pointermove (e: ) => void
m-pointerleave (e: ) => void
m-focusin (e: ) => void
m-focusout (e: ) => void

A submenu element displayed when its trigger is selected.

Data Attributes

Data Attribute Value
[data-state]

'open' | 'closed'

[data-melt-menubar-menu-submenu]

Present on all submenu elements.

Custom Events

Event Value
m-keydown (e: ) => void
m-pointermove (e: ) => void
m-focusout (e: ) => void

separator

A horizontal line which separates menu items.

Data Attributes

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

Present on all separator elements.

arrow

An optional arrow element which points to the menu's trigger.

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