Menu
A selectable list in a popover with nested submenus
Features
Full keyboard navigation.
Submenus, items, icons, images, checkboxes, groups, and more.
Modal and non-modal modes.
Native menus on native platforms.
Installation
Menu is already installed in tamagui, or you can install it independently:
yarn
npm
bun
pnpm
yarn add @tamagui/menu
If you want to use native menus, add these dependencies:
yarn add @react-native-menu/menuyarn add react-native-ios-context-menuyarn add react-native-ios-utilitiesyarn add zeego
Anatomy
Import all parts and piece them together.
import { Menu } from 'tamagui' // or '@tamagui/menu'export default () => (<Menu><Menu.Trigger asChild><Button /></Menu.Trigger><Menu.Portal zIndex={100}><Menu.Content><Menu.Item><Menu.ItemTitle>About Notes</Menu.ItemTitle></Menu.Item><Menu.Item><Menu.ItemTitle>Settings</Menu.ItemTitle></Menu.Item>{/* when title is nested inside a React element then you need to use `textValue` */}<Menu.Item textValue="Calendar"><Menu.ItemTitle><Text>Calendar</Text></Menu.ItemTitle><Menu.ItemIcon><Calendar color="gray" size="$1" /></Menu.ItemIcon></Menu.Item><Menu.Separator /><Menu.Sub><Menu.SubTrigger><Menu.ItemTitle>Actions</Menu.ItemTitle></Menu.SubTrigger><Menu.Portal zIndex={200}><Menu.SubContent><Menu.Label fontSize={'$1'}>Note settings</Menu.Label><Menu.Item onSelect={onSelect} key="create-note"><Menu.ItemTitle>Create note</Menu.ItemTitle></Menu.Item><Menu.Item onSelect={onSelect} key="delete-all"><Menu.ItemTitle>Delete all notes</Menu.ItemTitle></Menu.Item><Menu.Item onSelect={onSelect} key="sync-all"><Menu.ItemTitle>Sync notes</Menu.ItemTitle></Menu.Item></Menu.SubContent></Menu.Portal></Menu.Sub></Menu.Content></Menu.Portal></Menu>)
API Reference
Menu
Contains every component for the Menu.
Props
children (required)
React.ReactNode
Menu parts: Trigger, Portal, Content, Items, etc.
placement
Placement
Where the menu appears relative to the trigger. Options: 'top' | 'right' | 'bottom' | 'left' with optional '-start' | '-end' alignment.
open
boolean
Controlled open state for the menu.
defaultOpen
boolean
Initial open state when uncontrolled.
onOpenChange
(open: boolean) => void
Called when the menu opens or closes.
onOpenWillChange
(open: boolean) => void
Called before the open/close animation begins.
modal
boolean
Default:
trueWhen true, traps focus inside the menu and blocks outside scroll/interactions.
stayInFrame
ShiftProps | boolean
Shifts the menu to stay within viewport bounds.
allowFlip
FlipProps | boolean
Flips the menu to the opposite side if there is insufficient space.
offset
OffsetOptions
Distance between the menu and its trigger.
unstyled
boolean
Removes all default Tamagui styles.
Menu.Portal
Required for rendering the menu content.
Props
zIndex
number
Stacking order of the portal layer.
children (required)
React.ReactNode
Content to render inside the portal.
forceMount
true
Forces the portal to stay mounted, useful for controlling animations.
Menu.Trigger
The menu will only be triggered when the user right-clicks or long-presses within the trigger area.
Props
action
press|longPress
Default:
longPressWorks with the native prop and accepts 'press' or 'longPress'. The default is 'longPress' for Menu.
Menu.Content
Contains the content of the menu.
Props
children (required)
React.ReactNode
Menu items, groups, labels, separators, and submenus.
loop
boolean
Default:
falseWhether keyboard navigation wraps from last to first item.
forceMount
true
Forces the content to stay mounted, useful for controlling animations.
onCloseAutoFocus
(event: Event) => void
Called when focus returns to the trigger after closing.
onEscapeKeyDown
(event: KeyboardEvent) => void
Called when the escape key is pressed. Can be prevented.
onPointerDownOutside
(event: PointerEvent) => void
Called when a pointer event occurs outside the content.
onInteractOutside
(event: Event) => void
Called when any interaction occurs outside the content.
Menu.Item
A selectable menu item that triggers an action when selected.
Props
key (required)
string
Unique identifier for the item.
disabled
boolean
Default:
falsePrevents interaction and dims the item.
destructive
boolean
Renders the item in red on iOS to indicate a dangerous action (e.g. delete). No effect on web.
hidden
boolean
Hides the item from the menu.
onSelect
(event?: Event) => void
Called when the item is selected via click or keyboard.
onFocus
() => void
Called when the item receives focus.
onBlur
() => void
Called when the item loses focus.
textValue
string
Text used for typeahead and native menus. Required when ItemTitle contains a React node instead of a string.
Menu.ItemTitle
Renders the title of the menu item.
Props
children (required)
string | React.ReactNode
The title text or element to display.
You can directly pass a text node to the ItemTitle. However, if you use a nested
React node like <Text>, you need to pass textValue to the <Item> so that it
works with native menus.
Menu.ItemIcon
A component to render an icon. For non-native menus, you can pass an icon
component. For native menus, you can pass platform-specific icons to the
android and ios props.
On iOS, it renders the native SF Symbols icons.
Props
children
React.ReactNode
Fallback icon for web when native icons are not available.
ios
object
SF Symbol configuration: name, weight, scale, hierarchicalColor, paletteColors.
android
object
Android resource drawable name.
<Menu.ItemIcon ios={{ name: '0.circle.fill', // required pointSize: 5, weight: 'semibold', scale: 'medium', // can also be a color string. Requires iOS 15+ hierarchicalColor: { dark: 'blue', light: 'green', }, // alternative to hierarchical color. Requires iOS 15+ paletteColors: [ { dark: 'blue', light: 'green', }, ], }} ><CircleIcon /></Menu.ItemIcon>
Menu.ItemImage
A component to render an item image. For native menus, it only works on iOS. It
takes the same props as @tamagui/image.
Menu.ItemSubtitle
A component to render a subtitle for the menu item. For native menus, it only works on iOS.
Props
children (required)
string
The subtitle text to display below the title.
Menu.Group
A component that groups multiple menu items together.
Props
children (required)
React.ReactNode
Menu items to group together.
Menu.CheckboxItem
A menu item with a checkbox that can be toggled on and off.
Props
key (required)
string
Unique identifier for the checkbox item.
disabled
boolean
Default:
falsePrevents interaction and dims the item.
destructive
boolean
Renders the item in red on iOS to indicate a dangerous action. No effect on web.
hidden
boolean
Hides the item from the menu.
onFocus
() => void
Called when the item receives focus.
onBlur
() => void
Called when the item loses focus.
textValue
string
Text for native menus. Required when ItemTitle contains a React node.
value
'on' | 'off' | 'mixed'
Controlled checked state for native menus.
onValueChange
(state, prevState) => void
Called when checked state changes on native menus.
checked
boolean
Controlled checked state for web menus.
onCheckedChange
(checked: boolean) => void
Called when checked state changes on web.
Menu.ItemIndicator
Use inside Menu.CheckboxItem or Menu.RadioItem to indicate when an item is checked.
This allows you to conditionally render a checkmark.
<Menu.ItemIndicator><CheckmarkIcon /> {/* This does not work with the native prop. */}</Menu.ItemIndicator>
Props
children
React.ReactNode
Custom checkmark icon. Only works on web.
forceMount
true
Forces the indicator to stay mounted for animation control.
Menu.Label
Renders a non-focusable label for a group of items. On native menus, only one label is supported per menu and submenu.
Props
children (required)
string
The label text.
textValue
string
Text for native menus when children is a React node.
Menu.Arrow
Renders an arrow pointing to the trigger.
Props
size
number | SizeToken
Width and height of the arrow.
unstyled
boolean
Removes default arrow styles.
Menu.Separator
Renders a visual divider between menu items. Web only.
Menu.Sub
A container for nested submenu components.
Props
children (required)
React.ReactNode
SubTrigger, Portal, and SubContent components.
open
boolean
Controlled open state for the submenu.
onOpenChange
(open: boolean) => void
Called when the submenu opens or closes.
Menu.SubContent
Renders the content of a submenu. Same props as Menu.Content, excluding side and
align.
Menu.SubTrigger
A menu item that opens a submenu on hover or focus. Accepts the same props as
Menu.Item.
Styling
Item Highlight Behavior
Menu items use focusStyle for highlighting rather than hoverStyle. This ensures a unified highlight experience when switching between mouse and keyboard navigation - only one item is ever highlighted at a time.
When you hover over an item, it receives focus, which triggers the focusStyle. When you use arrow keys to navigate, focus moves to the new item, removing the highlight from the previous one.
// Default behavior - uses focusStyle for highlight<Menu.Item><Menu.ItemTitle>Settings</Menu.ItemTitle></Menu.Item>// Custom highlight styling - use focusStyle, not hoverStyle<Menu.Item focusStyle={{ backgroundColor: '$blue5' }} ><Menu.ItemTitle>Custom Highlight</Menu.ItemTitle></Menu.Item>
Avoid using hoverStyle for background highlights on Menu.Item. This can cause “double
highlighting” when switching between mouse and keyboard - where both the hovered item
and the focused item appear highlighted simultaneously.