Skip to main content

Menu

Menu is a versatile component for navigation and selection. It should contain MenuItem or MenuGroup components to provide a useful interface.

Import

import { Menu, MenuItem, MenuGroup, IndexPath } from '@ui-kitten/components';

Basic Usage

import React from 'react';
import { Menu, MenuItem, IndexPath } from '@ui-kitten/components';

export const MenuSimple = () => {
  const [selectedIndex, setSelectedIndex] = React.useState(new IndexPath(0));

  return (
    <Menu
      selectedIndex={selectedIndex}
      onSelect={index => setSelectedIndex(index)}>
      <MenuItem title='Users'/>
      <MenuItem title='Orders'/>
      <MenuItem title='Transactions'/>
    </Menu>
  );
};

Props

children
ReactElement<MenuItemProps> | ReactElement<MenuItemProps>[]
Items to be rendered within the menu. Should contain MenuItem or MenuGroup components.
selectedIndex
IndexPath
Index of the selected item. For non-grouped items, use new IndexPath(row). For grouped items, use new IndexPath(row, section).
onSelect
(index: IndexPath) => void
Callback called when an item is pressed. Receives an IndexPath object with row and optional section properties.
appearance
'default' | 'noDivider'
default:"'default'"
Appearance of the component. Use 'noDivider' to hide dividers between items.
...ListProps
ListProps
Accepts all React Native FlatList component props, excluding renderItem and data.
title
RenderProp<TextProps> | ReactText
String, number, or a function component to render within the item. If it is a function, it should return a Text component.
accessoryLeft
RenderProp<Partial<ImageProps>>
Function component to render at the start of the title. Expected to return an Image or icon component.
accessoryRight
RenderProp<Partial<ImageProps>>
Function component to render at the end of the title. Expected to return an Image or icon component.
selected
boolean
Whether the item is selected. Automatically controlled by the parent Menu component.
disabled
boolean
Whether the item is disabled and cannot be interacted with.
appearance
'default' | 'grouped'
default:"'default'"
Appearance of the item. Use 'grouped' for items within a MenuGroup.
...TouchableOpacityProps
TouchableOpacityProps
Accepts all React Native TouchableOpacity component props.
children
ReactElement<MenuItemProps> | ReactElement<MenuItemProps>[]
Items to be rendered within the group.
title
RenderProp<TextProps> | ReactText
String, number, or a function component to render as the group title.
accessoryLeft
RenderProp<Partial<ImageProps>>
Function component to render at the start of the title.
accessoryRight
RenderProp<Partial<ImageProps>>
Function component to render at the end of the title.
initiallyExpanded
boolean
Whether the group should be initially expanded.
...TouchableOpacityProps
TouchableOpacityProps
Accepts all React Native TouchableOpacity component props.

IndexPath

Menu uses a special IndexPath object to identify items:
interface IndexPath {
  row: number;      // Index of item
  section?: number; // Index of group (optional)
}
  • For non-grouped items: new IndexPath(0) - only row is used
  • For grouped items: new IndexPath(1, 2) - row is the item index within the group, section is the group index

Examples

With Icons

Add icons to menu items for better visual identification.
import React from 'react';
import { Menu, MenuItem, IndexPath, Icon } from '@ui-kitten/components';

const PersonIcon = (props) => (
  <Icon {...props} name='person-outline'/>
);

const ShoppingCartIcon = (props) => (
  <Icon {...props} name='shopping-cart-outline'/>
);

const BellIcon = (props) => (
  <Icon {...props} name='bell-outline'/>
);

const ForwardIcon = (props) => (
  <Icon {...props} name='arrow-ios-forward'/>
);

export const MenuWithIcons = () => {
  const [selectedIndex, setSelectedIndex] = React.useState(new IndexPath(0));

  return (
    <Menu
      selectedIndex={selectedIndex}
      onSelect={index => setSelectedIndex(index)}>
      <MenuItem
        title='Users'
        accessoryLeft={PersonIcon}
        accessoryRight={ForwardIcon}
      />
      <MenuItem
        title='Orders'
        accessoryLeft={ShoppingCartIcon}
        accessoryRight={ForwardIcon}
      />
      <MenuItem
        title='Notifications'
        accessoryLeft={BellIcon}
        accessoryRight={ForwardIcon}
      />
    </Menu>
  );
};

Without Selection Markers

Handle item presses without showing selection state.
import React from 'react';
import { Menu, MenuItem } from '@ui-kitten/components';

export const MenuNoMarkers = () => {
  const handleSelect = (index) => {
    console.log('Selected:', index.row);
    // Navigate or perform action
  };

  return (
    <Menu onSelect={handleSelect}>
      <MenuItem title='Profile'/>
      <MenuItem title='Settings'/>
      <MenuItem title='Logout'/>
    </Menu>
  );
};

With Groups

Organize items into expandable groups.
import React from 'react';
import { Menu, MenuItem, MenuGroup, IndexPath, Icon } from '@ui-kitten/components';

const PersonIcon = (props) => (
  <Icon {...props} name='person-outline'/>
);

const SettingsIcon = (props) => (
  <Icon {...props} name='settings-outline'/>
);

const FileIcon = (props) => (
  <Icon {...props} name='file-text-outline'/>
);

export const MenuWithGroups = () => {
  const [selectedIndex, setSelectedIndex] = React.useState(new IndexPath(0, 0));

  return (
    <Menu
      selectedIndex={selectedIndex}
      onSelect={index => setSelectedIndex(index)}>
      <MenuGroup title='Account' accessoryLeft={PersonIcon}>
        <MenuItem title='Profile'/>
        <MenuItem title='Change Password'/>
        <MenuItem title='Privacy'/>
      </MenuGroup>
      <MenuGroup title='Settings' accessoryLeft={SettingsIcon}>
        <MenuItem title='General'/>
        <MenuItem title='Notifications'/>
        <MenuItem title='Appearance'/>
      </MenuGroup>
      <MenuGroup title='Documents' accessoryLeft={FileIcon} initiallyExpanded={false}>
        <MenuItem title='Invoices'/>
        <MenuItem title='Reports'/>
        <MenuItem title='Receipts'/>
      </MenuGroup>
    </Menu>
  );
};

Disabled Items

Disable specific menu items to prevent interaction.
import React from 'react';
import { Menu, MenuItem, IndexPath } from '@ui-kitten/components';

export const MenuWithDisabledItems = () => {
  const [selectedIndex, setSelectedIndex] = React.useState(new IndexPath(0));

  return (
    <Menu
      selectedIndex={selectedIndex}
      onSelect={index => setSelectedIndex(index)}>
      <MenuItem title='Dashboard'/>
      <MenuItem title='Analytics'/>
      <MenuItem title='Reports' disabled/>
      <MenuItem title='Settings'/>
    </Menu>
  );
};

Without Dividers

Remove dividers between items using the noDivider appearance.
import React from 'react';
import { Menu, MenuItem, IndexPath } from '@ui-kitten/components';

export const MenuNoDividers = () => {
  const [selectedIndex, setSelectedIndex] = React.useState(new IndexPath(0));

  return (
    <Menu
      appearance='noDivider'
      selectedIndex={selectedIndex}
      onSelect={index => setSelectedIndex(index)}>
      <MenuItem title='Home'/>
      <MenuItem title='Profile'/>
      <MenuItem title='Settings'/>
    </Menu>
  );
};

Custom Styling

Customize the appearance of menu items.
import React from 'react';
import { Menu, MenuItem, IndexPath, Text } from '@ui-kitten/components';

export const CustomStyledMenu = () => {
  const [selectedIndex, setSelectedIndex] = React.useState(new IndexPath(0));

  return (
    <Menu
      selectedIndex={selectedIndex}
      onSelect={index => setSelectedIndex(index)}
      style={{ backgroundColor: '#F7F9FC' }}>
      <MenuItem
        title={evaProps => (
          <Text {...evaProps} style={[evaProps.style, { fontWeight: 'bold', fontSize: 16 }]}>
            Dashboard
          </Text>
        )}
      />
      <MenuItem
        title={evaProps => (
          <Text {...evaProps} style={[evaProps.style, { fontWeight: 'bold', fontSize: 16 }]}>
            Analytics
          </Text>
        )}
      />
    </Menu>
  );
};

As Dropdown Menu

Combine Menu with Popover or Modal for dropdown functionality.
import React from 'react';
import { Button, Menu, MenuItem, Popover } from '@ui-kitten/components';

export const MenuAsDropdown = () => {
  const [visible, setVisible] = React.useState(false);

  const renderToggleButton = () => (
    <Button onPress={() => setVisible(true)}>
      TOGGLE MENU
    </Button>
  );

  return (
    <Popover
      visible={visible}
      anchor={renderToggleButton}
      onBackdropPress={() => setVisible(false)}>
      <Menu
        onSelect={index => {
          console.log('Selected:', index.row);
          setVisible(false);
        }}>
        <MenuItem title='Edit'/>
        <MenuItem title='Share'/>
        <MenuItem title='Delete'/>
      </Menu>
    </Popover>
  );
};
Menu is the base component for Drawer and OverflowMenu. It provides the core functionality for item selection and navigation.

Theming

Menu can be themed using Eva Design System:
{
  "Menu": {
    "meta": {},
    "appearances": {
      "default": {
        "mapping": {},
        "variantGroups": {}
      },
      "noDivider": {
        "mapping": {},
        "variantGroups": {}
      }
    }
  },
  "MenuItem": {
    "meta": {},
    "appearances": {
      "default": {
        "mapping": {},
        "variantGroups": {}
      },
      "grouped": {
        "mapping": {
          "paddingLeft": 32
        }
      }
    }
  }
}
For detailed theming instructions, refer to the Branding Guide.

Build docs developers (and LLMs) love