ProComponents, templates & AI tooling
2.3k

Menu

A floating context menu with positioning, selection groups, and multiple presentation modes.

Import

import { Menu, SubMenu } from 'heroui-native';

Anatomy

<Menu>
  <Menu.Trigger>...</Menu.Trigger>
  <Menu.Portal>
    <Menu.Overlay />
    <Menu.Content presentation="popover">
      <Menu.Close />
      <Menu.Label>...</Menu.Label>
      <Menu.Group>
        <Menu.Item>
          <Menu.ItemIndicator />
          <Menu.ItemTitle>...</Menu.ItemTitle>
          <Menu.ItemDescription>...</Menu.ItemDescription>
        </Menu.Item>
      </Menu.Group>
      <SubMenu>
        <SubMenu.Trigger textValue="...">
          <SubMenu.TriggerIndicator />
          ...
        </SubMenu.Trigger>
        <SubMenu.Content>
          <Menu.Item>...</Menu.Item>
          <Menu.Item>...</Menu.Item>
        </SubMenu.Content>
      </SubMenu>
    </Menu.Content>
  </Menu.Portal>
</Menu>
  • Menu: Main container that manages open/close state, positioning, and provides context to child components.
  • Menu.Trigger: Clickable element that toggles the menu visibility.
  • Menu.Portal: Renders menu content in a portal layer above other content.
  • Menu.Overlay: Optional background overlay to capture outside clicks and close the menu.
  • Menu.Content: Container for menu content with two presentation modes: floating popover with positioning and collision detection, or bottom sheet modal.
  • Menu.Close: Close button that dismisses the menu when pressed.
  • Menu.Label: Non-interactive section heading text within the menu.
  • Menu.Group: Groups menu items with optional selection state (none, single, multiple).
  • Menu.Item: Pressable menu item with animated press feedback. Standalone or within a Group for selection.
  • Menu.ItemTitle: Primary label text for a menu item.
  • Menu.ItemDescription: Secondary description text for a menu item.
  • Menu.ItemIndicator: Visual selection indicator (checkmark or dot) for a menu item.
  • SubMenu: Root container that manages the expand/collapse state and provides animation context to children.
  • SubMenu.Trigger: Pressable row that toggles the submenu open/closed. Styled like a regular menu item.
  • SubMenu.TriggerIndicator: Animated chevron icon (default: chevron-right) that rotates when the submenu opens/closes. Place inside SubMenu.Trigger.
  • SubMenu.Content: Absolutely positioned container that animates its height when the submenu opens/closes. Place Menu.Item elements inside.

Usage

Basic Usage

The Menu component uses compound parts to create a floating context menu.

<Menu>
  <Menu.Trigger>...</Menu.Trigger>
  <Menu.Portal>
    <Menu.Overlay />
    <Menu.Content presentation="popover" width={220}>
      <Menu.Item>
        <Menu.ItemTitle>View Profile</Menu.ItemTitle>
      </Menu.Item>
      <Menu.Item>
        <Menu.ItemTitle>Settings</Menu.ItemTitle>
      </Menu.Item>
    </Menu.Content>
  </Menu.Portal>
</Menu>

With Item Descriptions

Add secondary description text to menu items alongside titles.

<Menu>
  <Menu.Trigger>...</Menu.Trigger>
  <Menu.Portal>
    <Menu.Overlay />
    <Menu.Content presentation="popover" width={260}>
      <Menu.Item className="items-start">
        <View className="flex-1">
          <Menu.ItemTitle>New file</Menu.ItemTitle>
          <Menu.ItemDescription>Create a new file</Menu.ItemDescription>
        </View>
      </Menu.Item>
      <Menu.Item className="items-start">
        <View className="flex-1">
          <Menu.ItemTitle>Copy link</Menu.ItemTitle>
          <Menu.ItemDescription>Copy the file link</Menu.ItemDescription>
        </View>
      </Menu.Item>
    </Menu.Content>
  </Menu.Portal>
</Menu>

Single Selection

Use Menu.Group with selectionMode="single" to allow one selected item at a time.

const [theme, setTheme] = useState<Set<MenuKey>>(() => new Set(['system']));

<Menu>
  <Menu.Trigger>...</Menu.Trigger>
  <Menu.Portal>
    <Menu.Overlay />
    <Menu.Content presentation="popover" width={180}>
      <Menu.Label>Appearance</Menu.Label>
      <Menu.Group
        selectionMode="single"
        selectedKeys={theme}
        onSelectionChange={setTheme}
      >
        <Menu.Item id="light">
          <Menu.ItemIndicator />
          <Menu.ItemTitle>Light</Menu.ItemTitle>
        </Menu.Item>
        <Menu.Item id="dark">
          <Menu.ItemIndicator />
          <Menu.ItemTitle>Dark</Menu.ItemTitle>
        </Menu.Item>
        <Menu.Item id="system">
          <Menu.ItemIndicator />
          <Menu.ItemTitle>System</Menu.ItemTitle>
        </Menu.Item>
      </Menu.Group>
    </Menu.Content>
  </Menu.Portal>
</Menu>;

Multiple Selection

Use selectionMode="multiple" to allow selecting multiple items simultaneously.

const [textStyles, setTextStyles] = useState<Set<MenuKey>>(
  () => new Set(['bold', 'italic'])
);

<Menu>
  <Menu.Trigger>...</Menu.Trigger>
  <Menu.Portal>
    <Menu.Overlay />
    <Menu.Content presentation="popover" width={250}>
      <Menu.Label>Text Style</Menu.Label>
      <Menu.Group
        selectionMode="multiple"
        selectedKeys={textStyles}
        onSelectionChange={setTextStyles}
      >
        <Menu.Item id="bold">
          <Menu.ItemIndicator />
          <Menu.ItemTitle>Bold</Menu.ItemTitle>
        </Menu.Item>
        <Menu.Item id="italic">
          <Menu.ItemIndicator />
          <Menu.ItemTitle>Italic</Menu.ItemTitle>
        </Menu.Item>
        <Menu.Item id="underline">
          <Menu.ItemIndicator />
          <Menu.ItemTitle>Underline</Menu.ItemTitle>
        </Menu.Item>
      </Menu.Group>
    </Menu.Content>
  </Menu.Portal>
</Menu>;

With SubMenu

Nest a SubMenu inside Menu.Content to reveal additional items on press.

<Menu>
  <Menu.Trigger asChild>
    <Button variant="secondary">Editor Menu</Button>
  </Menu.Trigger>
  <Menu.Portal>
    <Menu.Overlay />
    <Menu.Content presentation="popover" width={240}>
      <Menu.Item>
        <Menu.ItemTitle>New Space</Menu.ItemTitle>
      </Menu.Item>
      <SubMenu>
        <SubMenu.Trigger textValue="Focus">
          <SubMenu.TriggerIndicator />
          <Text className="flex-1 text-base font-medium text-foreground">
            Focus
          </Text>
        </SubMenu.Trigger>
        <SubMenu.Content>
          <Menu.Item>
            <Menu.ItemTitle>Zen Mode</Menu.ItemTitle>
          </Menu.Item>
          <Menu.Item>
            <Menu.ItemTitle>Reader Mode</Menu.ItemTitle>
          </Menu.Item>
          <Menu.Item>
            <Menu.ItemTitle>Lock Tab</Menu.ItemTitle>
          </Menu.Item>
        </SubMenu.Content>
      </SubMenu>
      <Menu.Item>
        <Menu.ItemTitle>Heading 1</Menu.ItemTitle>
      </Menu.Item>
    </Menu.Content>
  </Menu.Portal>
</Menu>

Danger Variant

Use variant="danger" on a menu item for destructive actions.

<Menu>
  <Menu.Trigger>...</Menu.Trigger>
  <Menu.Portal>
    <Menu.Overlay />
    <Menu.Content presentation="popover" width={220}>
      <Menu.Item>
        <Menu.ItemTitle>Edit</Menu.ItemTitle>
      </Menu.Item>
      <Menu.Item variant="danger">
        <Menu.ItemTitle>Delete</Menu.ItemTitle>
      </Menu.Item>
    </Menu.Content>
  </Menu.Portal>
</Menu>

Placements

Control where the menu appears relative to the trigger.

<Menu>
  <Menu.Trigger>...</Menu.Trigger>
  <Menu.Portal>
    <Menu.Overlay />
    <Menu.Content presentation="popover" placement="right" width={200}>
      <Menu.Item>
        <Menu.ItemTitle>Option A</Menu.ItemTitle>
      </Menu.Item>
      <Menu.Item>
        <Menu.ItemTitle>Option B</Menu.ItemTitle>
      </Menu.Item>
    </Menu.Content>
  </Menu.Portal>
</Menu>

Bottom Sheet Presentation

Use presentation="bottom-sheet" to display menu content as a bottom sheet modal.

<Menu presentation="bottom-sheet">
  <Menu.Trigger>...</Menu.Trigger>
  <Menu.Portal>
    <Menu.Overlay />
    <Menu.Content presentation="bottom-sheet">
      <Menu.Item>
        <Menu.ItemTitle>Option A</Menu.ItemTitle>
      </Menu.Item>
      <Menu.Item>
        <Menu.ItemTitle>Option B</Menu.ItemTitle>
      </Menu.Item>
    </Menu.Content>
  </Menu.Portal>
</Menu>

Dot Indicator

Use variant="dot" on Menu.ItemIndicator to show a filled circle instead of a checkmark.

<Menu>
  <Menu.Trigger>...</Menu.Trigger>
  <Menu.Portal>
    <Menu.Overlay />
    <Menu.Content presentation="popover" width={180}>
      <Menu.Group
        selectionMode="single"
        selectedKeys={alignment}
        onSelectionChange={setAlignment}
      >
        <Menu.Item id="left">
          <Menu.ItemIndicator variant="dot" />
          <Menu.ItemTitle>Left</Menu.ItemTitle>
        </Menu.Item>
        <Menu.Item id="center">
          <Menu.ItemIndicator variant="dot" />
          <Menu.ItemTitle>Center</Menu.ItemTitle>
        </Menu.Item>
        <Menu.Item id="right">
          <Menu.ItemIndicator variant="dot" />
          <Menu.ItemTitle>Right</Menu.ItemTitle>
        </Menu.Item>
      </Menu.Group>
    </Menu.Content>
  </Menu.Portal>
</Menu>

Example

import type { MenuKey } from 'heroui-native';
import { Button, Menu, Separator } from 'heroui-native';
import { useState } from 'react';
import { Text, View } from 'react-native';

export default function MenuExample() {
  const [textStyles, setTextStyles] = useState<Set<MenuKey>>(
    () => new Set(['bold', 'italic'])
  );
  const [alignment, setAlignment] = useState<Set<MenuKey>>(
    () => new Set(['left'])
  );

  return (
    <Menu>
      <Menu.Trigger asChild>
        <Button variant="secondary">Styles</Button>
      </Menu.Trigger>
      <Menu.Portal>
        <Menu.Overlay />
        <Menu.Content presentation="popover" width={250}>
          <Menu.Label className="mb-1">Text Style</Menu.Label>
          <Menu.Group
            selectionMode="multiple"
            selectedKeys={textStyles}
            onSelectionChange={setTextStyles}
          >
            <Menu.Item id="bold">
              <Menu.ItemIndicator />
              <Menu.ItemTitle>Bold</Menu.ItemTitle>
              <Text className="text-sm text-muted">⌘ B</Text>
            </Menu.Item>
            <Menu.Item id="italic">
              <Menu.ItemIndicator />
              <Menu.ItemTitle>Italic</Menu.ItemTitle>
              <Text className="text-sm text-muted">⌘ I</Text>
            </Menu.Item>
            <Menu.Item id="underline">
              <Menu.ItemIndicator />
              <Menu.ItemTitle>Underline</Menu.ItemTitle>
              <Text className="text-sm text-muted">⌘ U</Text>
            </Menu.Item>
          </Menu.Group>
          <Separator className="mx-2 my-2 opacity-75" />
          <Menu.Label className="mb-1">Text Alignment</Menu.Label>
          <Menu.Group
            selectionMode="single"
            selectedKeys={alignment}
            onSelectionChange={setAlignment}
          >
            <Menu.Item id="left">
              <Menu.ItemIndicator variant="dot" />
              <Menu.ItemTitle>Left</Menu.ItemTitle>
            </Menu.Item>
            <Menu.Item id="center">
              <Menu.ItemIndicator variant="dot" />
              <Menu.ItemTitle>Center</Menu.ItemTitle>
            </Menu.Item>
            <Menu.Item id="right">
              <Menu.ItemIndicator variant="dot" />
              <Menu.ItemTitle>Right</Menu.ItemTitle>
            </Menu.Item>
          </Menu.Group>
        </Menu.Content>
      </Menu.Portal>
    </Menu>
  );
}

You can find more examples in the GitHub repository.

API Reference

proptypedefaultdescription
childrenReact.ReactNode-The content of the menu
presentation'popover' | 'bottom-sheet''popover'Presentation mode for the menu content
isOpenboolean-Controlled open state of the menu
isDefaultOpenboolean-Open state when initially rendered (uncontrolled)
isDisabledboolean-Whether the menu is disabled
animationMenuRootAnimation-Animation configuration for menu root
onOpenChange(open: boolean) => void-Callback fired when the menu open state changes
...ViewPropsViewProps-All standard React Native View props are supported

Animation configuration for menu root component. Can be:

  • "disable-all": Disable all animations including children
  • true or undefined: Use default animations
proptypedefaultdescription
childrenReact.ReactNode-The trigger element content
classNamestring-Additional CSS class for the trigger
isDisabledbooleanfalseWhether the trigger is disabled
asChildboolean-Render as child element using Slot pattern
...PressablePropsPressableProps-All standard React Native Pressable props are supported
proptypedefaultdescription
childrenReact.ReactNode-The portal content
classNamestring-Additional CSS class for the portal container
disableFullWindowOverlaybooleanfalseUse a regular View instead of FullWindowOverlay on iOS
unstable_accessibilityContainerViewIsModalbooleanfalseControls whether VoiceOver treats the overlay window as a modal container. When true, VoiceOver is restricted to elements inside the overlay. iOS only. Unstable: may change with react-native-screens updates
hostNamestring-Optional name of the host element for the portal
forceMountboolean-Force mount the portal regardless of open state
proptypedefaultdescription
classNamestring-Additional CSS class for the overlay
closeOnPressbooleantrueWhether to close the menu when the overlay is pressed
animationMenuOverlayAnimation-Animation configuration for overlay
isAnimatedStyleActivebooleantrueWhether animated styles (react-native-reanimated) are active
forceMountboolean-Force mount the overlay regardless of open state
...PressablePropsPressableProps-All standard React Native Pressable props are supported

Animation configuration for menu overlay component. Can be:

  • false or "disabled": Disable all animations
  • true or undefined: Use default animations
  • object: Custom animation configuration
proptypedefaultdescription
state'disabled' | boolean-Disable animations while customizing properties
opacity.entering.valueEntryOrExitLayoutTypeFadeIn.duration(200)Custom entering animation for overlay
opacity.exiting.valueEntryOrExitLayoutTypeFadeOut.duration(150)Custom exiting animation for overlay

Props when presentation="popover".

proptypedefaultdescription
childrenReact.ReactNode-The menu content
presentation'popover'-Presentation mode (must match Menu root)
placement'top' | 'bottom' | 'left' | 'right''bottom'Where the menu appears relative to the trigger
align'start' | 'center' | 'end''center'Alignment of the menu relative to the trigger
avoidCollisionsbooleantrueWhether to reposition to avoid screen edges
offsetnumber9Distance from the trigger element in pixels
alignOffsetnumber0Offset along the alignment axis in pixels
width'content-fit' | 'trigger' | 'full' | number'content-fit'Content width sizing strategy
classNamestring-Additional CSS class for the content container
animationMenuContentAnimation-Animation configuration for content
...ViewPropsViewProps-All standard React Native View props are supported

Animation configuration for menu popover content component. Can be:

  • false or "disabled": Disable all animations
  • true or undefined: Use default animations
  • object: Custom animation configuration
proptypedefaultdescription
state'disabled' | boolean-Disable animations while customizing properties
entering.valueEntryOrExitLayoutTypeScale + fade entering animationCustom entering animation for content
exiting.valueEntryOrExitLayoutTypeScale + fade exiting animationCustom exiting animation for content

Props when presentation="bottom-sheet". Extends @gorhom/bottom-sheet BottomSheet props.

proptypedefaultdescription
childrenReact.ReactNode-The bottom sheet content
presentation'bottom-sheet'-Presentation mode (must match Menu root)
classNamestring-Additional CSS class for the bottom sheet
backgroundClassNamestring-Additional CSS class for the background
handleIndicatorClassNamestring-Additional CSS class for the handle indicator
contentContainerClassNamestring-Additional CSS class for the content container
contentContainerPropsOmit<BottomSheetViewProps, 'children'>-Props for the content container
animationAnimationDisabled-Set to false or "disabled" to disable animations
...BottomSheetPropsPartial<BottomSheetProps>-All @gorhom/bottom-sheet props are supported

Extends CloseButtonProps. Automatically closes the menu when pressed.

proptypedefaultdescription
iconPropsCloseButtonIconProps-Props for customizing the close icon
...ButtonPropsButtonRootProps-All Button root props are supported
proptypedefaultdescription
childrenReact.ReactNode-The group content (Menu.Item elements)
selectionMode'none' | 'single' | 'multiple''none'The type of selection allowed in the group
selectedKeysIterable<MenuKey>-Currently selected keys (controlled)
defaultSelectedKeysIterable<MenuKey>-Initially selected keys (uncontrolled)
isDisabledbooleanfalseWhether the entire group is disabled
disabledKeysIterable<MenuKey>-Keys of items that should be disabled
shouldCloseOnSelectboolean-Whether selecting an item should close the menu
classNamestring-Additional CSS class for the group container
onSelectionChange(keys: Set<MenuKey>) => void-Callback fired when the selection changes
...ViewPropsViewProps-All standard React Native View props are supported
proptypedefaultdescription
childrenReact.ReactNode-The label text content
classNamestring-Additional CSS class for the label
...TextPropsTextProps-All standard React Native Text props are supported
proptypedefaultdescription
childrenReact.ReactNode | ((props: MenuItemRenderProps) => ReactNode)-Child elements or a render function
idMenuKey-Unique identifier, required when inside a Menu.Group
variant'default' | 'danger''default'Visual variant of the menu item
isDisabledbooleanfalseWhether the item is disabled
isSelectedboolean-Controlled selected state for standalone items
shouldCloseOnSelectbooleantrueWhether pressing this item should close the menu
classNamestring-Additional CSS class for the item
animationMenuItemAnimation-Animation configuration for press feedback
isAnimatedStyleActivebooleantrueWhether animated styles (react-native-reanimated) are active
onSelectedChange(selected: boolean) => void-Callback when standalone item's selected state changes
...PressablePropsPressableProps-All standard React Native Pressable props are supported

Props passed to the render function when children is a function.

proptypedescription
isSelectedbooleanWhether this item is currently selected
isDisabledbooleanWhether the item is disabled
isPressedSharedValue<boolean>Whether the item is currently pressed
variant'default' | 'danger'Visual variant of the item

Animation configuration for menu item press feedback. Can be:

  • false or "disabled": Disable all item animations
  • true or undefined: Use default animations
  • object: Custom animation configuration
proptypedefaultdescription
scale.valuenumber0.98Scale value when pressed
scale.timingConfigWithTimingConfig{ duration: 150 }Spring animation configuration for scale
backgroundColor.valuestringuseThemeColor('default')Background color shown while pressed
backgroundColor.timingConfigWithTimingConfig{ duration: 150 }Animation timing for background color
proptypedefaultdescription
childrenReact.ReactNode-The title text content
classNamestring-Additional CSS class for the item title
...TextPropsTextProps-All standard React Native Text props are supported
proptypedefaultdescription
childrenReact.ReactNode-The description text content
classNamestring-Additional CSS class for the item description
...TextPropsTextProps-All standard React Native Text props are supported
proptypedefaultdescription
childrenReact.ReactNode-Custom indicator content, defaults to checkmark or dot
variant'checkmark' | 'dot''checkmark'Visual variant of the indicator
iconPropsMenuItemIndicatorIconProps-Icon configuration (checkmark variant)
forceMountbooleantrueForce mount the indicator regardless of selected state
classNamestring-Additional CSS class for the item indicator
...ViewPropsViewProps-All standard React Native View props are supported
proptypedefaultdescription
sizenumber16Size of the indicator icon (8 for dot variant)
colorstringmutedColor of the indicator icon
proptypedefaultdescription
childrenReact.ReactNode-The sub-menu content (trigger, content, and other items)
isOpenboolean-Controlled open state of the sub-menu
isDefaultOpenboolean-Open state when initially rendered (uncontrolled)
isDisabledbooleanfalseWhether the sub-menu is disabled
classNamestring-Additional CSS class for the root container
animationSubMenuRootAnimation-Animation configuration for the sub-menu
onOpenChange(open: boolean) => void-Callback fired when the sub-menu open state changes
...ViewPropsViewProps-All standard React Native View props are supported

Animation configuration for the SubMenu root component. Can be:

  • "disable-all": Disable all animations including children
  • false or "disabled": Disable only root animations
  • true or undefined: Use default animations
  • object: Custom animation configuration
proptypedefaultdescription
state'disabled' | boolean-Disable animations while customizing properties
rootContent.marginHorizontalnumber-16Margin horizontal when sub-menu is open
rootContent.marginVerticalnumber-16Margin vertical when sub-menu is open
rootContent.paddingHorizontalnumber6Padding horizontal when sub-menu is open
rootContent.paddingTopnumber12Padding top when sub-menu is open
rootContent.springConfigWithSpringConfig{ damping: 100, stiffness: 950, mass: 3 }Spring configuration for expand/collapse
proptypedefaultdescription
childrenReact.ReactNode-The trigger content (title, icons, indicator, etc.)
textValuestring-Accessible text value announced by screen readers
classNamestring-Additional CSS class for the trigger
isDisabledbooleanfalseWhether the trigger is disabled
asChildboolean-Render as child element using Slot pattern
...PressablePropsPressableProps-All standard React Native Pressable props are supported

Animated indicator icon that rotates when the submenu opens/closes. Defaults to a chevron-right icon.

proptypedefaultdescription
childrenReact.ReactNode-Custom indicator content (replaces default chevron)
classNamestring-Additional CSS class for the indicator
iconPropsSubMenuTriggerIndicatorIconProps-Icon configuration for the default chevron
animationSubMenuTriggerIndicatorAnimation-Animation configuration for indicator rotation
isAnimatedStyleActivebooleantrueWhether animated styles (react-native-reanimated) are active
...ViewPropsViewProps-All standard React Native View props are supported
proptypedefaultdescription
sizenumber14Size of the indicator icon
colorstringmutedColor of the indicator icon

Animation configuration for the trigger indicator rotation. Can be:

  • false or "disabled": Disable all animations
  • true or undefined: Use default animations
  • object: Custom animation configuration
proptypedefaultdescription
state'disabled' | boolean-Disable animations while customizing properties
rotation.value[number, number][0, 90]Rotation values [collapsed, expanded] in degrees
rotation.springConfigWithSpringConfig{ damping: 140, stiffness: 1000, mass: 4 }Spring configuration for rotation
proptypedefaultdescription
childrenReact.ReactNode-The submenu items (Menu.Item, Menu.Group, etc.)
classNamestring-Additional CSS class for the content container
...PressablePropsPressableProps-All standard React Native Pressable props are supported

Hooks

useMenu

Hook to access the menu root context. Must be used within a Menu component.

import { useMenu } from 'heroui-native';

const { isOpen, onOpenChange, presentation, isDisabled } = useMenu();

Returns

propertytypedescription
isOpenbooleanWhether the menu is currently open
onOpenChange(open: boolean) => voidCallback to change the open state
presentation'popover' | 'bottom-sheet'Current presentation mode
isDisabledboolean | undefinedWhether the menu is disabled
nativeIDstringUnique identifier for the menu instance

useMenuItem

Hook to access the menu item context. Must be used within a Menu.Item component.

import { useMenuItem } from 'heroui-native';

const { id, isSelected, isDisabled, variant } = useMenuItem();

Returns

propertytypedescription
idMenuKey | undefinedItem identifier
isSelectedbooleanWhether the item is currently selected
isDisabledbooleanWhether the item is disabled
variant'default' | 'danger'Visual variant of the item

useMenuAnimation

Hook to access the menu animation context. Must be used within a Menu component.

import { useMenuAnimation } from 'heroui-native';

const { progress, isDragging } = useMenuAnimation();

Returns

propertytypedescription
progressSharedValue<number>Animation progress shared value (0=idle, 1=open, 2=close)
isDraggingSharedValue<boolean>Whether the bottom sheet is currently being dragged

useSubMenu

Hook to access the sub-menu context. Must be used within a SubMenu component.

import { useSubMenu } from 'heroui-native';

const { isOpen, onOpenChange, isDisabled } = useSubMenu();

Returns

propertytypedescription
isOpenbooleanWhether the sub-menu is currently open
onOpenChange(open: boolean) => voidCallback to change the open state
isDisabledbooleanWhether the sub-menu is disabled
nativeIDstringUnique identifier for the sub-menu instance

Special Notes

Element Inspector (iOS)

Menu uses FullWindowOverlay on iOS. To enable the React Native element inspector during development, set disableFullWindowOverlay={true} on Menu.Portal. Tradeoff: the menu will not appear above native modals when disabled.

Native Modal (iOS)

When a Menu is opened inside a screen presented as a native modal (presentation: 'modal' | 'formSheet' | 'pageSheet'), the menu content may render shifted upward. In the new architecture (Fabric), react-native-screens marks RNSModalScreen as a Fabric root, so the trigger's position is reported relative to the modal's origin while FullWindowOverlay (where the menu is mounted) is anchored to the iOS application window. Compensate by adding safeAreaInsets.top to offset:

import { useSafeAreaInsets } from 'react-native-safe-area-context';

const insets = useSafeAreaInsets();

<Menu.Content presentation="popover" offset={insets.top}>
  ...
</Menu.Content>;

On this page