Context Menu
A menu component triggered by right-click on web and long press on touch devices
Features
Full keyboard navigation.
Supports items, icons, images, checkboxes, groups, and more.
Supports submenus.
Supports modal and non-modal modes.
Supports native menus on native platforms.
Customizable alignment, offsets, and positioning.
Support for native iOS and Android icons.
Supports previews on iOS.
Installation
ContextMenu is already installed in tamagui, or you can install it independently:
yarn
npm
bun
pnpm
yarn add @tamagui/context-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 { ContextMenu } from 'tamagui' // or '@tamagui/context-menu'export default () => (<ContextMenu><ContextMenu.Trigger asChild><YStack><Text>Right Click or longPress</Text></YStack></ContextMenu.Trigger><ContextMenu.Portal zIndex={100}><ContextMenu.Content><ContextMenu.Item><ContextMenu.ItemTitle>About Notes</ContextMenu.ItemTitle></ContextMenu.Item><ContextMenu.Item><ContextMenu.ItemTitle>Settings</ContextMenu.ItemTitle></ContextMenu.Item>{/* when title is nested inside a React element then you need to use `textValue` */}<ContextMenu.Item textValue="Calendar"><ContextMenu.ItemTitle><Text>Calendar</Text></ContextMenu.ItemTitle><ContextMenu.ItemIcon><Calendar color="gray" size="$1" /></ContextMenu.ItemIcon></ContextMenu.Item><ContextMenu.Separator /><ContextMenu.Sub><ContextMenu.SubTrigger><ContextMenu.ItemTitle>Actions</ContextMenu.ItemTitle></ContextMenu.SubTrigger><ContextMenu.Portal zIndex={200}><ContextMenu.SubContent><ContextMenu.Label fontSize={'$1'}>Note settings</ContextMenu.Label><ContextMenu.Item onSelect={onSelect} key="create-note"><ContextMenu.ItemTitle>Create note</ContextMenu.ItemTitle></ContextMenu.Item><ContextMenu.Item onSelect={onSelect} key="delete-all"><ContextMenu.ItemTitle>Delete all notes</ContextMenu.ItemTitle></ContextMenu.Item><ContextMenu.Item onSelect={onSelect} key="sync-all"><ContextMenu.ItemTitle>Sync notes</ContextMenu.ItemTitle></ContextMenu.Item></ContextMenu.SubContent></ContextMenu.Portal></ContextMenu.Sub></ContextMenu.Content></ContextMenu.Portal></ContextMenu>)
API Reference
ContextMenu
Contains every component for the ContextMenu.
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.
ContextMenu.Portal
This is necessary for the ContextMenu.
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.
ContextMenu.Trigger
The ContextMenu 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 ContextMenu.
ContextMenu.Content
Contains the content of the ContextMenu.
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.
ContextMenu.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.
ContextMenu.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.
ContextMenu.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/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.
<ContextMenu.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 /></ContextMenu.ItemIcon>
ContextMenu.ItemImage
A component to render an item image. For native menus, it only works on iOS. It
takes the same properties as @tamagui/image.
ContextMenu.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.
ContextMenu.Group
A component that groups multiple menu items together.
Props
children (required)
React.ReactNode
Menu items to group together.
ContextMenu.CheckboxItem
A menu item with a checkbox that can be toggled on/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.
ContextMenu.ItemIndicator
Use inside CheckboxItem or RadioItem to indicate when an item is checked.
This allows you to conditionally render a checkmark.
<ContextMenu.ItemIndicator><CheckmarkIcon /> {/* This does not work with the native prop. */}</ContextMenu.ItemIndicator>
Props
children
React.ReactNode
Custom checkmark icon. Only works on web.
forceMount
true
Forces the indicator to stay mounted for animation control.
ContextMenu.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.
ContextMenu.Arrow
Renders an arrow pointing to the trigger.
Props
size
number | SizeToken
Width and height of the arrow.
unstyled
boolean
Removes default arrow styles.
ContextMenu.Separator
Renders a visual divider between menu items. Web only.
ContextMenu.Sub
A container for nested sub-menu components.
Props
children (required)
React.ReactNode
SubTrigger, Portal, and SubContent components.
open
boolean
Controlled open state for the sub-menu.
onOpenChange
(open: boolean) => void
Called when the sub-menu opens or closes.
ContextMenu.SubContent
Renders the content of a sub-menu. Same props as Content, excluding side and
align.
ContextMenu.SubTrigger
A menu item that opens a sub-menu on hover/focus. Accepts the same props as
Item.
ContextMenu.Preview
When the ContextMenu is visible, this renders a custom preview component. Only works with native iOS menus.
Should be rendered as a child of ContextMenu.Content.
Props
children (required)
React.ReactNode | (() => React.ReactNode)
The preview content to render. Can be a function for lazy rendering.
size
{ width?: number, height?: number }
Dimensions of the preview.
onPress
() => void
Called when the preview is pressed.
backgroundColor
string | { dark: string, light: string }
Background color of the preview.
borderRadius
number
Border radius of the preview.
preferredCommitStyle
'pop' | 'dismiss'
Default:
'dismiss'Exit transition when preview is tapped. Use 'pop' when navigating to another screen.
<ContextMenu.Preview // optional props: preferredCommitStyle="pop" // or "dismiss" backgroundColor={{ // or a color string directly dark: 'black', light: 'white', }} >{() => <Preview />}</ContextMenu.Preview>