
Product
Introducing Webhook Events for Alert Changes
Add real-time Socket webhook events to your workflows to automatically receive software supply chain alert changes in real time.
react-native-menus
Advanced tools
A native menu component for React Native that provides platform-specific context menus for both Android and iOS. Pass any custom component as a child to trigger native menus.
iOS (Native UIMenu) |
Android (Modal Dialog) |
npm install react-native-menus
# or
yarn add react-native-menus
For iOS, run:
cd ios && pod install
No additional setup required for Android.
import React, { useState } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { MenuView } from 'react-native-menus';
const App = () => {
const [selectedTheme, setSelectedTheme] = useState('system');
const handleMenuSelect = (event: {
nativeEvent: { identifier: string; title: string };
}) => {
setSelectedTheme(event.nativeEvent.identifier);
console.log('Selected:', event.nativeEvent.title);
};
return (
<View style={styles.container}>
<MenuView
checkedColor="#007AFF"
uncheckedColor="#8E8E93"
menuItems={[
{ identifier: 'light', title: 'Light Mode' },
{ identifier: 'dark', title: 'Dark Mode' },
{ identifier: 'system', title: 'System Default' },
]}
onMenuSelect={handleMenuSelect}
>
<View style={styles.menuButton}>
<Text style={styles.menuButtonText}>
🌓 Theme: {selectedTheme}
</Text>
</View>
</MenuView>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
menuButton: {
backgroundColor: '#fff',
paddingHorizontal: 20,
paddingVertical: 12,
borderRadius: 8,
borderWidth: 1,
borderColor: '#ddd',
},
menuButtonText: {
fontSize: 16,
color: '#333',
},
});
export default App;
Use the selectedIdentifier prop to fully control which item is marked as selected. Update it in your onMenuSelect handler to keep iOS and Android behavior consistent.
const [selectedSort, setSelectedSort] = useState('date');
<MenuView
selectedIdentifier={selectedSort}
menuItems={[
{ identifier: 'date', title: 'Date' },
{ identifier: 'name', title: 'Name' },
{ identifier: 'size', title: 'Size' },
]}
onMenuSelect={({ nativeEvent }) => setSelectedSort(nativeEvent.identifier)}
>
<View style={styles.menuButton}>
<Text>📊 Sort by: {selectedSort}</Text>
</View>
</MenuView>
<MenuView
menuItems={[
{ identifier: 'profile', title: 'View Profile' },
{ identifier: 'settings', title: 'Settings' },
{ identifier: 'logout', title: 'Logout' },
]}
onMenuSelect={handleMenuSelect}
>
<View style={styles.customButton}>
<Text style={styles.customButtonText}>👤 Account Menu</Text>
</View>
</MenuView>
<MenuView
checkedColor="#5856D6"
menuItems={[
{ identifier: 'opt1', title: 'Option 1' },
{ identifier: 'opt2', title: 'Option 2' },
// ... many more items
{ identifier: 'opt20', title: 'Option 20' },
]}
onMenuSelect={handleMenuSelect}
>
<View style={styles.menuButton}>
<Text>đź“‹ Select Option</Text>
</View>
</MenuView>
const [isDisabled, setIsDisabled] = useState(false);
<MenuView
disabled={isDisabled}
menuItems={[
{ identifier: 'enable', title: 'Enable Menu' },
{ identifier: 'disable', title: 'Disable Menu' },
]}
onMenuSelect={({ nativeEvent }) => {
setIsDisabled(nativeEvent.identifier === 'disable');
}}
>
<View style={[styles.menuButton, isDisabled && styles.disabledButton]}>
<Text style={[styles.menuButtonText, isDisabled && styles.disabledText]}>
{isDisabled ? '🔒 Menu Disabled' : '🔓 Menu Enabled'}
</Text>
</View>
</MenuView>
// Add these styles
const styles = StyleSheet.create({
// ... other styles
disabledButton: {
opacity: 0.6,
},
disabledText: {
color: '#999',
},
});
import { MenuView } from 'react-native-menus';
<MenuView
menuItems={[
{ identifier: 'profile', title: 'View Profile', iosSymbol: 'person.circle' },
{ identifier: 'settings', title: 'Settings', iosSymbol: 'gear' },
{ identifier: 'logout', title: 'Logout', iosSymbol: 'arrow.right.square' },
]}
onMenuSelect={handleMenuSelect}
>
<View style={styles.menuButton}>
<Text>👤 Account Menu with SF Symbols</Text>
</View>
</MenuView>
For a list of available SF Symbols, refer to Apple's SF Symbols app or use common names like:
"arrow.up", "arrow.down", "arrow.left", "arrow.right""gear", "heart", "trash", "checkmark", "xmark".fill suffix for filled variants: "heart.fill", "gear.fill"| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | ReactNode | Yes | - | The trigger component that opens the menu when tapped |
menuItems | MenuItem[] | Yes | [] | Array of menu items to display |
onMenuSelect | (event: MenuSelectEvent) => void | No | - | Callback fired when a menu item is selected |
selectedIdentifier | string | No | - | Controlled selected item identifier; shows a native checkmark for the matching item |
checkedColor | string | No | #007AFF | Color for checked/selected menu items (Android only) |
uncheckedColor | string | No | #8E8E93 | Color for unchecked/unselected menu items (Android only) |
color | string | No | - | Reserved for future use |
disabled | boolean | No | false | Disables the menu interaction when set to true |
style | ViewStyle | No | - | Style applied to the container view |
interface MenuItem {
identifier: string; // Unique identifier for the menu item
title: string; // Display text for the menu item
iosSymbol?: string; // iOS-only: SF Symbol name to show beside the title (e.g., "gear", "heart.fill")
}
interface MenuSelectEvent {
identifier: string; // The identifier of the selected menu item
title: string; // The title of the selected menu item
}
The MenuView component accepts any React Native component as a child, which becomes the trigger for opening the menu. When tapped, a native context menu appears with the specified menu items.
File: android/src/main/java/com/menu/MenuView.kt
FrameLayout that accepts child views from React NativeonInterceptTouchEvent()RadioButton elements with custom stylingcheckedColor and uncheckedColor customizationKey Implementation Details:
ViewGroupManager to support child viewsFile: ios/MenuView.mm
RCTViewComponentView (Fabric architecture)mountChildComponentView and unmountChildComponentView for Fabric compatibilityUIMenu attached to an invisible UIButton overlayUIAction elements with system stylingselectedIdentifier and rendered using UIMenuElementStateOnonMenuSelect without mutating native state; update selectedIdentifier in React to reflect changesKey Implementation Details:
UIMenu on tap| Feature | iOS | Android |
|---|---|---|
| Menu Style | Native UIMenu popover | Modal dialog at bottom |
| SF Symbols | ✅ Full support via iosSymbol property | ❌ Not supported |
| Checkmark Color | System default (not customizable) | Fully customizable |
| Unchecked Color | System default | Fully customizable |
| Animation | Native iOS animation | Slide up animation |
| Scrolling | Native UIMenu scrolling | Custom ScrollView (max 40% screen) |
| Selection State | Controlled via selectedIdentifier | use selectedIdentifier for cross-platform parity |
| Appearance | iOS system theme | White background with rounded corners |
The repository includes a complete example project with 6 different use cases:
cd example
yarn install
# For iOS
cd ios && pod install && cd ..
yarn ios
# For Android
yarn android
iOS: Make sure you're running iOS 14 or later, as UIMenu is only available from iOS 14+.
Android: Ensure your child component doesn't have onPress or other touch handlers that might interfere. The MenuView intercepts all touch events at the parent level.
Pass and update selectedIdentifier. iOS does not shift the checkmark automatically—reflect selection in props via your onMenuSelect handler.
The MenuView component requires a child component to act as the trigger. Always wrap your trigger in the MenuView:
// âś… Correct
<MenuView menuItems={items}>
<View><Text>Open Menu</Text></View>
</MenuView>
// ❌ Wrong - no children
<MenuView menuItems={items} />
MIT
Made with create-react-native-library
FAQs
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Add real-time Socket webhook events to your workflows to automatically receive software supply chain alert changes in real time.

Security News
ENISA has become a CVE Program Root, giving the EU a central authority for coordinating vulnerability reporting, disclosure, and cross-border response.

Product
Socket now scans OpenVSX extensions, giving teams early detection of risky behaviors, hidden capabilities, and supply chain threats in developer tools.