Components
Menu

Menu

A list of options that appears when a user interacts with a button.

Loading...

You can explore the menu component in the following curated examples.

Anatomy

<Menu.Root>
  <Menu.Trigger>
    <Menu.Indicator />
  </Menu.Trigger>
  <Menu.Positioner>
    <Menu.Content>
      <Menu.Arrow>
        <Menu.ArrowTip />
      </Menu.Arrow>
      <Menu.Item />
      <Menu.ItemGroup>
        <Menu.ItemGroupLabel />
        <Menu.Item />
      </Menu.ItemGroup>
      <Menu.Separator />
    </Menu.Content>
  </Menu.Positioner>
</Menu.Root>

Examples

Item Selection

Use onSelect to handle item selection. The callback receives the item's id.

Root Provider

An alternative way to control the menu is to use the RootProvider component and the useMenu hook. This way you can access the state and methods from outside the component.

Grouping

Use Menu.ItemGroup and Menu.ItemGroupLabel to organize related menu items.

To render menu items as links, use the asChild prop to replace the default element with an anchor tag.

Checkbox

To add a checkbox to a menu item, use the Menu.Checkbox component.

Radio Group

To group radio option items, use the Menu.RadioGroup component.

Context Menu

To show the menu when a trigger element is right-clicked, use the Menu.ContextTrigger component.

Context menus are also opened during a long-press of roughly 700ms when the pointer is pen or touch.

Nested

To show a nested menu, render another Menu component and use the Menu.TriggerItem component to open the submenu.

When rendering a menu inside a dialog, use lazyMount and unmountOnExit to ensure proper cleanup when the dialog closes.

Open a confirmation dialog from a menu item. This pattern is useful for destructive actions like delete that require user confirmation.

Guides

Custom IDs

Ark UI autogenerates ids for menu items internally. Passing a custom id prop breaks the internal getElementById functionality used by the component.

// ❌ Don't do this
<Menu.Item id="custom-id" value="custom-value">
  Custom Item
</Menu.Item>

// ✅ Do this
<Menu.Item value="custom-value">
  Custom Item
</Menu.Item>

To render a menu item as a link, render the link as the menu item itself using the asChild prop, not as a child of the menu item.

This pattern ensures the link element receives the correct ARIA attributes and keyboard interactions from the menu item.

Here's an example of a reusable MenuItemLink component:

interface MenuItemLinkProps extends Menu.ItemProps {
  href?: string
  target?: string
}

export const MenuItemLink = (props: MenuItemLinkProps) => {
  const { href, target, children, ...rest } = props
  return (
    <Menu.Item {...rest} asChild>
      <a href={href} target={target}>
        {children}
      </a>
    </Menu.Item>
  )
}

API Reference

Props

Root

PropDefaultType
anchorPoint
Point

The positioning point for the menu. Can be set by the context menu trigger or the button trigger.

aria-label
string

The accessibility label for the menu

closeOnSelecttrue
boolean

Whether to close the menu when an option is selected

compositetrue
boolean

Whether the menu is a composed with other composite widgets like a combobox or tabs

defaultHighlightedValue
string

The initial highlighted value of the menu item when rendered. Use when you don't need to control the highlighted value of the menu item.

defaultOpen
boolean

The initial open state of the menu when rendered. Use when you don't need to control the open state of the menu.

highlightedValue
string

The controlled highlighted value of the menu item.

id
string

The unique identifier of the machine.

ids
Partial<{ trigger: string contextTrigger: string content: string groupLabel: (id: string) => string group: (id: string) => string positioner: string arrow: string }>

The ids of the elements in the menu. Useful for composition.

immediate
boolean

Whether to synchronize the present change immediately or defer it to the next frame

lazyMountfalse
boolean

Whether to enable lazy mounting

loopFocusfalse
boolean

Whether to loop the keyboard navigation.

navigate
(details: NavigateDetails) => void

Function to navigate to the selected item if it's an anchor element

onEscapeKeyDown
(event: KeyboardEvent) => void

Function called when the escape key is pressed

onExitComplete
VoidFunction

Function called when the animation ends in the closed state

onFocusOutside
(event: FocusOutsideEvent) => void

Function called when the focus is moved outside the component

onHighlightChange
(details: HighlightChangeDetails) => void

Function called when the highlighted menu item changes.

onInteractOutside
(event: InteractOutsideEvent) => void

Function called when an interaction happens outside the component

onOpenChange
(details: OpenChangeDetails) => void

Function called when the menu opens or closes

onPointerDownOutside
(event: PointerDownOutsideEvent) => void

Function called when the pointer is pressed down outside the component

onRequestDismiss
(event: LayerDismissEvent) => void

Function called when this layer is closed due to a parent layer being closed

onSelect
(details: SelectionDetails) => void

Function called when a menu item is selected.

open
boolean

The controlled open state of the menu

positioning
PositioningOptions

The options used to dynamically position the menu

present
boolean

Whether the node is present (controlled by the user)

skipAnimationOnMountfalse
boolean

Whether to allow the initial presence animation.

typeaheadtrue
boolean

Whether the pressing printable characters should trigger typeahead navigation

unmountOnExitfalse
boolean

Whether to unmount on exit.

Arrow

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
CSS VariableDescription
--arrow-sizeThe size of the arrow
--arrow-size-halfHalf the size of the arrow
--arrow-backgroundUse this variable to style the arrow background
--arrow-offsetThe offset position of the arrow

ArrowTip

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

CheckboxItem

Renders a <div> element.

PropDefaultType
checked
boolean

Whether the option is checked

value
string

The value of the option

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
closeOnSelect
boolean

Whether the menu should be closed when the option is selected.

disabled
boolean

Whether the menu item is disabled

onCheckedChange
(checked: boolean) => void

Function called when the option state is changed

valueText
string

The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used.

Content

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]menu
[data-part]content
[data-state]"open" | "closed"
[data-nested]menu
[data-has-nested]menu
[data-placement]The placement of the content
CSS VariableDescription
--layer-indexThe index of the dismissable in the layer stack
--nested-layer-countThe number of nested menus

ContextTrigger

Renders a <button> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]menu
[data-part]context-trigger
[data-state]"open" | "closed"

Indicator

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]menu
[data-part]indicator
[data-state]"open" | "closed"

ItemGroupLabel

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

ItemGroup

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

ItemIndicator

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]menu
[data-part]item-indicator
[data-disabled]Present when disabled
[data-highlighted]Present when highlighted
[data-state]"checked"

Item

Renders a <div> element.

PropDefaultType
value
string

The unique value of the menu item option.

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
closeOnSelect
boolean

Whether the menu should be closed when the option is selected.

disabled
boolean

Whether the menu item is disabled

onSelect
VoidFunction

The function to call when the item is selected

valueText
string

The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used.

AttributeDescription
[data-scope]menu
[data-part]item
[data-disabled]Present when disabled
[data-highlighted]Present when highlighted
[data-value]The value of the item
[data-valuetext]The human-readable value

ItemText

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]menu
[data-part]item-text
[data-disabled]Present when disabled
[data-highlighted]Present when highlighted
[data-state]"checked"

Positioner

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
CSS VariableDescription
--reference-widthThe width of the reference element
--reference-heightThe height of the root
--available-widthThe available width in viewport
--available-heightThe available height in viewport
--xThe x position for transform
--yThe y position for transform
--z-indexThe z-index value
--transform-originThe transform origin for animations

RadioItemGroup

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
onValueChange
(e: ValueChangeDetails) => void

value
string

RadioItem

Renders a <div> element.

PropDefaultType
value
string

The value of the option

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
closeOnSelect
boolean

Whether the menu should be closed when the option is selected.

disabled
boolean

Whether the menu item is disabled

valueText
string

The textual value of the option. Used in typeahead navigation of the menu. If not provided, the text content of the menu item will be used.

RootProvider

PropDefaultType
value
UseMenuReturn

immediate
boolean

Whether to synchronize the present change immediately or defer it to the next frame

lazyMountfalse
boolean

Whether to enable lazy mounting

onExitComplete
VoidFunction

Function called when the animation ends in the closed state

present
boolean

Whether the node is present (controlled by the user)

skipAnimationOnMountfalse
boolean

Whether to allow the initial presence animation.

unmountOnExitfalse
boolean

Whether to unmount on exit.

Separator

Renders a <hr> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

TriggerItem

Renders a <div> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Trigger

Renders a <button> element.

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
AttributeDescription
[data-scope]menu
[data-part]trigger
[data-placement]The placement of the trigger
[data-state]"open" | "closed"

Context

API

PropertyType
open
boolean

Whether the menu is open

setOpen
(open: boolean) => void

Function to open or close the menu

highlightedValue
string

The id of the currently highlighted menuitem

setHighlightedValue
(value: string) => void

Function to set the highlighted menuitem

setParent
(parent: ParentMenuService) => void

Function to register a parent menu. This is used for submenus

setChild
(child: ChildMenuService) => void

Function to register a child menu. This is used for submenus

reposition
(options?: Partial<PositioningOptions>) => void

Function to reposition the popover

getOptionItemState
(props: OptionItemProps) => OptionItemState

Returns the state of the option item

getItemState
(props: ItemProps) => ItemState

Returns the state of the menu item

addItemListener
(props: ItemListenerProps) => VoidFunction

Setup the custom event listener for item selection event

Accessibility

Complies with the Menu WAI-ARIA design pattern.

Keyboard Support

KeyDescription
Space
Activates/Selects the highlighted item
Enter
Activates/Selects the highlighted item
ArrowDown
Highlights the next item in the menu
ArrowUp
Highlights the previous item in the menu
ArrowRightArrowLeft
When focus is on trigger, opens or closes the submenu depending on reading direction.
Esc
Closes the menu and moves focus to the trigger