Top Related Projects
Material Design for React Native (Android & iOS)
Cross-Platform React Native UI Toolkit
UI Components Library for React Native
Mobile-first, accessible components for React Native & Web to build consistent UI across Android, iOS and Web.
:boom: React Native UI Library based on Eva Design System :new_moon_with_face::sparkles:Dark Mode
An enhanced, animated, customizable Modal for React Native.
Quick Overview
React Native Menu is a flexible and customizable menu component for React Native applications. It provides a simple way to create dropdown menus, context menus, and other menu-based UI elements with native performance and a consistent look across platforms.
Pros
- Easy to integrate and use in React Native projects
- Highly customizable with support for custom styling and animations
- Cross-platform compatibility (iOS and Android)
- Good performance due to native implementation
Cons
- Limited documentation and examples
- Some reported issues with complex nested menus
- Occasional compatibility issues with certain React Native versions
- Relatively small community compared to some other UI libraries
Code Examples
- Basic Menu Usage:
import Menu, { MenuItem } from 'react-native-menu';
const MyComponent = () => (
<Menu>
<MenuItem onPress={() => console.log('Item 1 pressed')}>Item 1</MenuItem>
<MenuItem onPress={() => console.log('Item 2 pressed')}>Item 2</MenuItem>
<MenuItem onPress={() => console.log('Item 3 pressed')}>Item 3</MenuItem>
</Menu>
);
- Custom Trigger Component:
import Menu, { MenuTrigger, MenuOptions, MenuOption } from 'react-native-menu';
const CustomTrigger = () => (
<View style={styles.triggerView}>
<Text>Open Menu</Text>
</View>
);
const MyComponent = () => (
<Menu>
<MenuTrigger customStyles={triggerStyles} CustomTrigger={CustomTrigger} />
<MenuOptions>
<MenuOption onSelect={() => alert('Option 1')}>
<Text>Option 1</Text>
</MenuOption>
<MenuOption onSelect={() => alert('Option 2')}>
<Text>Option 2</Text>
</MenuOption>
</MenuOptions>
</Menu>
);
- Nested Menu:
import Menu, { MenuOptions, MenuOption, MenuTrigger } from 'react-native-menu';
const NestedMenu = () => (
<Menu>
<MenuTrigger text='Main Menu' />
<MenuOptions>
<MenuOption value={1} text='Option 1' />
<Menu>
<MenuTrigger text='Submenu' />
<MenuOptions>
<MenuOption value={2} text='Submenu Option 1' />
<MenuOption value={3} text='Submenu Option 2' />
</MenuOptions>
</Menu>
</MenuOptions>
</Menu>
);
Getting Started
-
Install the package:
npm install react-native-menu
-
Import the components in your React Native file:
import Menu, { MenuItem, MenuDivider } from 'react-native-menu';
-
Use the Menu component in your JSX:
<Menu> <MenuItem onPress={() => {}}>Menu Item 1</MenuItem> <MenuItem onPress={() => {}}>Menu Item 2</MenuItem> <MenuDivider /> <MenuItem onPress={() => {}}>Menu Item 3</MenuItem> </Menu>
-
Customize the menu appearance and behavior using props and custom styles as needed.
Competitor Comparisons
Material Design for React Native (Android & iOS)
Pros of react-native-paper
- Comprehensive UI component library with a wide range of pre-built components
- Follows Material Design guidelines, ensuring a consistent and modern look
- Active development and regular updates, with good community support
Cons of react-native-paper
- Larger bundle size due to the extensive component library
- May require additional configuration for custom theming and styling
- Some components might be overly complex for simple use cases
Code Comparison
react-native-paper:
import { Menu } from 'react-native-paper';
<Menu
visible={visible}
onDismiss={closeMenu}
anchor={<Button onPress={openMenu}>Show menu</Button>}
>
<Menu.Item onPress={() => {}} title="Item 1" />
<Menu.Item onPress={() => {}} title="Item 2" />
</Menu>
react-native-menu:
import Menu, { MenuItem } from 'react-native-menu';
<Menu onSelect={value => alert(`Selected ${value}`)}>
<MenuItem value="item1">Item 1</MenuItem>
<MenuItem value="item2">Item 2</MenuItem>
</Menu>
Summary
react-native-paper offers a more comprehensive set of components and follows Material Design guidelines, making it suitable for larger projects requiring a consistent UI. However, it may be overkill for simpler applications. react-native-menu provides a more focused solution for menu components, with a simpler API and potentially smaller bundle size, but lacks the broader component ecosystem of react-native-paper.
Cross-Platform React Native UI Toolkit
Pros of react-native-elements
- Comprehensive UI toolkit with a wide range of pre-built components
- Active development and community support
- Customizable themes and consistent styling across components
Cons of react-native-elements
- Larger package size due to the extensive component library
- May require more setup and configuration for specific use cases
- Potential performance impact when using many complex components
Code Comparison
react-native-elements:
import { Button, Icon } from 'react-native-elements';
<Button
icon={<Icon name="arrow-right" size={15} color="white" />}
title="Button with Icon"
/>
react-native-menu:
import Menu, { MenuItem } from 'react-native-menu';
<Menu>
<MenuItem onPress={() => {}}>Menu Item 1</MenuItem>
<MenuItem onPress={() => {}}>Menu Item 2</MenuItem>
</Menu>
Summary
react-native-elements offers a comprehensive UI toolkit with a wide range of components, making it suitable for larger projects requiring consistent styling. However, it may have a larger package size and potential performance impact.
react-native-menu focuses specifically on menu components, providing a lightweight solution for implementing menus in React Native applications. It's more suitable for projects that only need menu functionality without the overhead of a full UI toolkit.
Choose react-native-elements for comprehensive UI needs and consistent styling across your app. Opt for react-native-menu if you only require menu functionality and prefer a lightweight solution.
UI Components Library for React Native
Pros of react-native-ui-lib
- Comprehensive UI component library with a wide range of pre-built components
- Customizable theming system for consistent design across the app
- Active development and regular updates
Cons of react-native-ui-lib
- Larger package size due to the extensive component library
- Steeper learning curve for developers new to the library
Code Comparison
react-native-menu/menu:
import Menu, { MenuItem } from 'react-native-menu';
<Menu>
<MenuItem onPress={() => {}}>Item 1</MenuItem>
<MenuItem onPress={() => {}}>Item 2</MenuItem>
</Menu>
react-native-ui-lib:
import { View, Button, Dialog } from 'react-native-ui-lib';
<View>
<Button label="Open Dialog" onPress={() => this.dialog.show()} />
<Dialog visible={this.state.showDialog} onDismiss={() => this.setState({showDialog: false})}>
<Dialog.Content>
<Text>Dialog content</Text>
</Dialog.Content>
</Dialog>
</View>
Summary
react-native-ui-lib offers a more comprehensive set of UI components and theming options compared to react-native-menu/menu, which focuses specifically on menu functionality. While react-native-ui-lib provides greater flexibility and customization, it comes with a larger package size and potentially steeper learning curve. The choice between the two depends on the specific needs of the project and the desired level of control over UI components.
Mobile-first, accessible components for React Native & Web to build consistent UI across Android, iOS and Web.
Pros of NativeBase
- Comprehensive UI component library with a wide range of pre-built components
- Customizable theme system for consistent styling across the app
- Active development and community support
Cons of NativeBase
- Larger bundle size due to the extensive component library
- Steeper learning curve for developers new to the framework
- May require additional configuration for optimal performance
Code Comparison
NativeBase example:
import { Box, Text, Button } from 'native-base';
const MyComponent = () => (
<Box>
<Text>Hello, NativeBase!</Text>
<Button>Click me</Button>
</Box>
);
Menu example:
import { Menu, MenuOptions, MenuOption, MenuTrigger } from 'react-native-menu';
const MyMenu = () => (
<Menu>
<MenuTrigger text='Select option' />
<MenuOptions>
<MenuOption value={1} text='Option 1' />
<MenuOption value={2} text='Option 2' />
</MenuOptions>
</Menu>
);
While NativeBase provides a more comprehensive set of UI components and theming capabilities, Menu focuses specifically on creating customizable dropdown menus. NativeBase may be better suited for larger projects requiring a consistent design system, while Menu offers a lightweight solution for implementing menu functionality in React Native applications.
:boom: React Native UI Library based on Eva Design System :new_moon_with_face::sparkles:Dark Mode
Pros of react-native-ui-kitten
- Comprehensive UI library with a wide range of pre-built components
- Customizable theming system for easy styling
- Active development and community support
Cons of react-native-ui-kitten
- Larger bundle size due to extensive component library
- Steeper learning curve for customization
- May require more setup and configuration
Code Comparison
react-native-ui-kitten:
import { Button, Text } from '@ui-kitten/components';
const MyButton = () => (
<Button onPress={() => console.log('Pressed')}>
<Text>Click me</Text>
</Button>
);
react-native-menu:
import Menu from 'react-native-menu';
const MyMenu = () => (
<Menu>
<Menu.Item onPress={() => console.log('Option 1')}>Option 1</Menu.Item>
<Menu.Item onPress={() => console.log('Option 2')}>Option 2</Menu.Item>
</Menu>
);
Summary
react-native-ui-kitten offers a more comprehensive UI solution with extensive theming capabilities, while react-native-menu focuses specifically on menu components. UI Kitten provides a wider range of components but may have a larger footprint and learning curve. react-native-menu is more lightweight and specialized for menu functionality. The choice between the two depends on project requirements and the desired level of UI customization.
An enhanced, animated, customizable Modal for React Native.
Pros of react-native-modal
- More comprehensive and feature-rich modal solution
- Highly customizable with various animation options
- Actively maintained with frequent updates and bug fixes
Cons of react-native-modal
- Larger package size due to additional features
- Steeper learning curve for advanced customizations
- May introduce performance overhead for simple use cases
Code Comparison
react-native-modal:
import Modal from 'react-native-modal';
<Modal isVisible={isModalVisible} onBackdropPress={toggleModal}>
<View style={styles.modalContent}>
<Text>Modal Content</Text>
<Button title="Close" onPress={toggleModal} />
</View>
</Modal>
react-native-menu:
import Menu from 'react-native-menu';
<Menu>
<Menu.Item onPress={handlePress}>Menu Item 1</Menu.Item>
<Menu.Item onPress={handlePress}>Menu Item 2</Menu.Item>
</Menu>
While react-native-modal provides a full-featured modal solution with extensive customization options, react-native-menu focuses specifically on creating menu components. The choice between the two depends on the specific requirements of your project. If you need a versatile modal system with animations and customization options, react-native-modal is the better choice. However, if you're looking for a simpler, menu-specific solution, react-native-menu might be more suitable.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
@react-native-menu/menu
Android PopupMenu and iOS14+ UIMenu components for react-native. Falls back to ActionSheet for versions below iOS14.
Android | iOS 14+ | iOS 13 |
---|---|---|
![]() | ![]() | ![]() |
Installation
via npm:
npm install @react-native-menu/menu
via yarn:
yarn add @react-native-menu/menu
Installing on iOS with React Native 0.63 and above
There is an issue(https://github.com/facebook/react-native/issues/29246) causing projects with this module to fail on build on React Native 0.63 and above.
This issue may be fixed in future versions of react native.
As a work around, look for lines in [YourPrject].xcodeproj
under LIBRARY_SEARCH_PATHS
with "\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"",
and change swift-5.0
to swift-5.3
.
Linking
The package is automatically linked when building the app. All you need to do is:
npx pod-install
Usage
import { MenuView, MenuComponentRef } from '@react-native-menu/menu';
// ...
const App = () => {
const menuRef = useRef<MenuComponentRef>(null);
return (
<View style={styles.container}>
<Button
title="Show Menu with ref (Android only)"
onPress={() => menuRef.current?.show()}
/>
<MenuView
ref={menuRef}
title="Menu Title"
onPressAction={({ nativeEvent }) => {
console.warn(JSON.stringify(nativeEvent));
}}
actions={[
{
id: 'add',
title: 'Add',
titleColor: '#2367A2',
image: Platform.select({
ios: 'plus',
android: 'ic_menu_add',
}),
imageColor: '#2367A2',
subactions: [
{
id: 'nested1',
title: 'Nested action',
titleColor: 'rgba(250,180,100,0.5)',
subtitle: 'State is mixed',
image: Platform.select({
ios: 'heart.fill',
android: 'ic_menu_today',
}),
imageColor: 'rgba(100,200,250,0.3)',
state: 'mixed',
},
{
id: 'nestedDestructive',
title: 'Destructive Action',
attributes: {
destructive: true,
},
image: Platform.select({
ios: 'trash',
android: 'ic_menu_delete',
}),
},
],
},
{
id: 'share',
title: 'Share Action',
titleColor: '#46F289',
subtitle: 'Share action on SNS',
image: Platform.select({
ios: 'square.and.arrow.up',
android: 'ic_menu_share',
}),
imageColor: '#46F289',
state: 'on',
},
{
id: 'destructive',
title: 'Destructive Action',
attributes: {
destructive: true,
},
image: Platform.select({
ios: 'trash',
android: 'ic_menu_delete',
}),
},
]}
shouldOpenOnLongPress={false}
>
<View style={styles.button}>
<Text style={styles.buttonText}>Test</Text>
</View>
</MenuView>
</View>
);
};
Declarative usage
It's also possible to obtain the action
is a more React-ish, declarative fashion. Refer to the react-to-imperative
package, and see an example here.
Reference
Props
ref
(Android only)
Ref to the menu component.
Type | Required |
---|---|
ref | No |
title
(iOS only)
The title of the menu.
Type | Required |
---|---|
string | Yes |
isAnchoredToRight
(Android only)
Boolean determining if menu should anchored to right or left corner of parent view.
Type | Required |
---|---|
boolean | No |
shouldOpenOnLongPress
Boolean determining if menu should open after long press or on normal press
Type | Required |
---|---|
boolean | No |
actions
Actions to be displayed in the menu.
Type | Required |
---|---|
MenuAction[] | Yes |
themeVariant
(iOS only)
String to override theme of the menu. If you want to control theme universally across your app, see this package.
Type | Required |
---|---|
enum('light', 'dark') | No |
MenuAction
Object representing Menu Action.
export type MenuAction = {
/**
* Identifier of the menu action.
* The value set in this id will be returned when menu is selected.
*/
id?: string;
/**
* The action's title.
*/
title: string;
/**
* (Android only)
* The action's title color.
* @platform Android
*/
titleColor?: number | ColorValue;
/**
* (iOS14+ only)
* An elaborated title that explains the purpose of the action.
* @platform iOS
*/
subtitle?: string;
/**
* The attributes indicating the style of the action.
*/
attributes?: MenuAttributes;
/**
* (iOS14+ only)
* The state of the action.
* @platform iOS
*/
state?: MenuState;
/**
* (Android and iOS13+ only)
* - The action's image.
* - Allows icon name included in project or system (Android) resources drawables and
* in SF Symbol (iOS)
* @example // (iOS)
* image="plus"
* @example // (Android)
* image="ic_menu_add"
*/
image?: string;
/**
* (Android and iOS13+ only)
* - The action's image color.
*/
imageColor?: number | ColorValue;
/**
* (Android and iOS14+ only)
* - Actions to be displayed in the sub menu
* - On Android it does not support nesting next sub menus in sub menu item
*/
subactions?: MenuAction[];
};
MenuAttributes
The attributes indicating the style of the action.
type MenuAttributes = {
/**
* An attribute indicating the destructive style.
*/
destructive?: boolean;
/**
* An attribute indicating the disabled style.
*/
disabled?: boolean;
/**
* An attribute indicating the hidden style.
*/
hidden?: boolean;
};
MenuState
The state of the action.
/**
* The state of the action.
* - off: A constant indicating the menu element is in the âoffâ state.
* - on: A constant indicating the menu element is in the âonâ state.
* - mixed: A constant indicating the menu element is in the âmixedâ state.
*/
type MenuState = 'off' | 'on' | 'mixed';
onPressAction
Callback function that will be called when selecting a menu item. It will contain id of the given action.
Type | Required |
---|---|
({nativeEvent}) => void | No |
Events
onCloseMenu
Callback function that will be called when the menu is dismissed. This event fires at the start of the dismissal, before any animations complete.
Type | Required |
---|---|
() => void | No |
onOpenMenu
Callback function that will be called when the menu is opened. This event fires right before the menu is displayed.
Type | Required |
---|---|
() => void | No |
Example usage:
<MenuView
onOpenMenu={() => {
console.log('Menu was opened');
}}
onCloseMenu={() => {
console.log('Menu was closed');
}}
// ... other props
>
<View>
<Text>Open Menu</Text>
</View>
</MenuView>
Testing with Jest
In some cases, you might want to mock the package to test your components. You can do this by using the jest.mock
function.
import type { MenuComponentProps } from '@react-native-menu/menu';
jest.mock('@react-native-menu/menu', () => ({
MenuView: jest.fn((props: MenuComponentProps) => {
const React = require('react');
class MockMenuView extends React.Component {
render() {
return React.createElement(
'View',
{ testID: props.testID },
// Dynamically mock each action
props.actions.map(action =>
React.createElement('Button', {
key: action.id,
title: action.title,
onPress: () => {
if (action.id && props?.onPressAction) {
props.onPressAction({ nativeEvent: { event: action.id } });
}
},
testID: action.id
})
),
this.props.children
);
}
}
return React.createElement(MockMenuView, props);
})
}));
Contributing
See the contributing guide to learn how to contribute to the repository and the development workflow.
License
MIT
Top Related Projects
Material Design for React Native (Android & iOS)
Cross-Platform React Native UI Toolkit
UI Components Library for React Native
Mobile-first, accessible components for React Native & Web to build consistent UI across Android, iOS and Web.
:boom: React Native UI Library based on Eva Design System :new_moon_with_face::sparkles:Dark Mode
An enhanced, animated, customizable Modal for React Native.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot