Dropdown Menu

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 element which when clicked, opens the dropdown menu.
  • 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

Basic

The first thing you need to do is create a dropdown menu using the createDropdownMenu function.

    <script lang="ts">
  import { createDropdownMenu, melt } from '@melt-ui/svelte'
  const {
    elements: { menu, item, trigger, arrow }
  } = createDropdownMenu()
</script>
	
    <script lang="ts">
  import { createDropdownMenu, melt } from '@melt-ui/svelte'
  const {
    elements: { menu, item, trigger, arrow }
  } = createDropdownMenu()
</script>
	

Then you can use the menu, item, and trigger to construct a dropdown menu. A high level example of how to structure the menu is shown below.

    <script lang="ts">
  import { createDropdownMenu, melt } from '@melt-ui/svelte'
  const {
    elements: { menu, item, trigger, arrow }
  } = createDropdownMenu()
</script>
 
<button use:melt={$trigger}>Click me</button>
<div use:melt={$menu}>
  <div use:melt={$item}>...</div>
  <div use:melt={$item}>...</div>
  <div use:melt={$item}>...</div>
  <div use:melt={$arrow} />
</div>
	
    <script lang="ts">
  import { createDropdownMenu, melt } from '@melt-ui/svelte'
  const {
    elements: { menu, item, trigger, arrow }
  } = createDropdownMenu()
</script>
 
<button {...$trigger} use:trigger>Click me</button>
<div {...$menu} use:menu>
  <div {...$item} use:item>...</div>
  <div {...$item} use:item>...</div>
  <div {...$item} use:item>...</div>
  <div {...$arrow} use:arrow />
</div>
	

The trigger sits outside of the menu and is used to toggle the menu's open state. The item elements go inside the menu element. The arrow element is optional and can be used to render an arrow which points to the trigger.

At this point, our menu doesn't really do much except open and close. To add functionality, we could turn the item elements into links, or we could pass a m-click listener function to the item action, which will be called when that item is pressed (Space and Enter keys also trigger the click event for items).

    <a href="/1" use:melt={$item}>Item 1</a>
<div use:melt={$item} on:m-click={(e) => console.log('Item 2!')}>Item 2</div>
<div use:melt={$item} on:m-click={(e) => console.log('Item 3!')}>Item 3</div>
	
    <a href="/1" {...$item} use:item>Item 1</a>
<div {...$item} use:item on:m-click={(e) => console.log('Item 2!')}>Item 2</div>
<div {...$item} use:item on:m-click={(e) => console.log('Item 3!')}>Item 3</div>
	

If you wanted to prevent the default behavior that occurs when you select an item, you can call e.preventDefault() in your on:m-click listener, which will prevent the default behavior from occurring.

    <div
  use:melt={$item}
  on:m-click={(e) => {
    e.preventDefault()
  }}>
  Item 2
</div>
	
    <div
  {...$item} use:item
  on:m-click={(e) => {
    e.preventDefault()
  }}>
  Item 2
</div>
	

Modal Behavior

To give the dropdown menu complete modal behavior, where an overlay is rendered behind the menu to prevent interaction with the rest of the page while open, use the overlay builder element.

    <script lang="ts">
  import { createDropdownMenu, melt } from '@melt-ui/svelte'
  const {
    elements: { trigger, menu, item, separator, arrow, overlay }
  } = createDropdownMenu()
</script>
 
<button type="button" use:melt={$trigger}> Open </button>
<div use:melt={$overlay} />
<div use:melt={$menu}>
  <div use:melt={$arrow} />
  <div use:melt={$item} />
</div>
	
    <script lang="ts">
  import { createDropdownMenu, melt } from '@melt-ui/svelte'
  const {
    elements: { trigger, menu, item, separator, arrow, overlay }
  } = createDropdownMenu()
</script>
 
<button type="button" {...$trigger} use:trigger> Open </button>
<div {...$overlay} use:overlay />
<div {...$menu} use:menu>
  <div {...$arrow} use:arrow />
  <div {...$item} use:item />
</div>
	

The Modal Dropdown example below demonstrates this behavior in action.

Example Components

Modal Dropdown

An example using the overlay builder element to prevent interaction with the rest of the page while the menu is open.

API Reference

createDropdownMenu

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 .

preventScroll true
boolean

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

escapeBehavior 'close'
'close' | 'ignore' | 'defer-otherwise-close' | 'defer-otherwise-ignore'

Defines how the dropdown menu reacts when the Escape key is pressed.

  • close: Closes the dropdown menu immediately.
  • ignore: Prevents the dropdown menu from closing and also blocks the parent element from closing in response to the Escape key.
  • defer-otherwise-close: Delegates the action to the parent element. If no parent is found, it closes the element.
  • defer-otherwise-ignore: Delegates the action to the parent element. If no parent is found, nothing is done.
  • preventTextSelectionOverflow true
    boolean

    Whether to prevent text selection overflowing the dropdown menu when it is the top layer.

    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 .

    preventScroll

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

    escapeBehavior

    Defines how the dropdown menu reacts when the Escape key is pressed.

  • close: Closes the dropdown menu immediately.
  • ignore: Prevents the dropdown menu from closing and also blocks the parent element from closing in response to the Escape key.
  • defer-otherwise-close: Delegates the action to the parent element. If no parent is found, it closes the element.
  • defer-otherwise-ignore: Delegates the action to the parent element. If no parent is found, nothing is done.
  • preventTextSelectionOverflow

    Whether to prevent text selection overflowing the dropdown menu when it is the top layer.

    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-dropdown-menu-trigger]

    Present on all trigger elements.

    Custom Events

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

    The element which wraps the entire menu.

    Data Attributes

    Data Attribute Value
    [data-side]

    'top' | 'right' | 'bottom' | 'left'

    [data-align]

    'start' | 'center' | 'end'

    [data-state]

    'open' | 'closed'

    [data-melt-dropdown-menu]

    Present on all dropdown menu elements.

    Custom Events

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

    item

    A basic menu item.

    Data Attributes

    Data Attribute Value
    [data-orientation]

    'vertical' | 'horizontal'

    [data-dropdown-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

    overlay

    An optional overlay element to prevent interaction with the rest of the page while the menu is open

    Data Attributes

    Data Attribute Value
    [data-state]

    'open' | 'closed'

    [data-melt-dropdown-menu-overlay]

    Present on all overlay elements.

    separator

    A horizontal line which separates menu items.

    Data Attributes

    Data Attribute Value
    [data-melt-dropdown-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-side]

    'top' | 'right' | 'bottom' | 'left'

    [data-arrow]

    'true'

    [data-melt-dropdown-menu-arrow]

    Present on all arrow elements.

    createCheckboxItem

    The builder function used to create checkbox items for menu elements

    Props

    Prop Default Type / Description
    disabled false
    boolean

    Whether or not the menu checkbox item is disabled.

    defaultChecked -
    boolean

    Whether the checkbox is checked by default.

    checked -
    Writable<boolean>

    A writable store that controls the checked state of the checkbox.

    See Bring Your Own Store

    onCheckedChange -
    ChangeFn<boolean>

    A function that is called when the checked state of the checkbox changes.

    See Bring Your Own Store

    Elements

    Element Description

    The builder store used to create a menu checkbox item.

    States

    State Description
    checked

    A writable store with the checked state of the checkbox item.

    Options

    Option Description
    disabled

    Whether or not the submenu is disabled.

    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-dropdown-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-dropdown-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-dropdown-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-dropdown-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-dropdown-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-dropdown-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-side]

    'top' | 'right' | 'bottom' | 'left'

    [data-align]

    'start' | 'center' | 'end'

    [data-state]

    'open' | 'closed'

    [data-melt-dropdown-menu-submenu]

    Present on all submenu elements.

    Custom Events

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

    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 dropdown and focuses the first item. When focused on an item, selects the item.

    Enter

    When focused on the trigger, opens the dropdown and focuses the first item. When focused on an item, selects the item.

    ArrowDown

    When focused on the trigger, opens the dropdown and focuses the first item. 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.

    ArrowLeft

    When focused on within a subMenu, closes the submenu and shifts focus to that submenu's subTrigger.

    Esc

    Closes the dropdown menu and focuses the trigger.