@lhacenmed/react-native-dropdown-menu
v0.1.2
Published
This an expo module that exposes the native android popup menu api for usage in a react native (Expo) app, it uses Cascade Popup Menu (saket/cascade) to create nice transitions between sub-menus, it's currently for Android users only.
Maintainers
Readme
react-native-dropdown-menu
A native Android dropdown menu component for React Native (Expo).
It bridges the Android Cascade Popup Menu API (saket/cascade) to React Native, providing smooth submenu transitions and a native look and feel.
Currently supported on Android only.
⚠️ Status: This module is currently in beta.
Contributions and feedback are welcome.
📸 Demo
📦 Installation
npm install @lhacenmed/react-native-dropdown-menuor
yarn add @lhacenmed/react-native-dropdown-menu🚀 Usage
Here’s a complete example using expo-router and icons:
import DropdownMenu from "@lhacenmed/react-native-dropdown-menu";
import { Stack } from "expo-router";
import { Text, View } from "react-native";
import { Ionicons } from "@expo/vector-icons";
export default function Index() {
const menuGroups = [
{
items: [
{
id: "export",
title: "Export",
icon: { resource: "ic_menu_save" },
items: [
{
id: "video",
title: "Video",
icon: { resource: "ic_video" },
onSelect: () => console.log("Video"),
},
{
id: "gif",
title: "Gif",
icon: { resource: "ic_gif" },
onSelect: () => console.log("Gif"),
},
],
},
{
id: "share",
title: "Share",
icon: { resource: "ic_menu_share" },
onSelect: () => console.log("Share"),
},
],
},
{
items: [
{
id: "settings",
title: "Settings",
enabled: false,
icon: { resource: "ic_menu_settings" },
},
{
id: "help",
title: "Help",
icon: { resource: "ic_menu_help" },
onSelect: () => console.log("Help"),
},
],
},
];
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Stack.Screen
options={{
title: "Home",
headerRight: () => (
<DropdownMenu
backgroundColor="#161618"
cornerRadius={10}
groups={menuGroups}
>
<View style={{ padding: 8 }}>
<Ionicons name="ellipsis-vertical" size={20} color="#8D8D8D" />
</View>
</DropdownMenu>
),
}}
/>
<Text>Edit app/index.tsx to modify this screen.</Text>
</View>
);
}⚙️ API
<DropdownMenu /> Props
| Prop | Type | Description |
| ----------------- | ---------------------------------------------------------------- | --------------------------------------------------------------- |
| groups | MenuGroupSpec[] | The list of menu groups containing menu items. (Required) |
| header | string | Optional header text shown at the top of the menu. |
| backgroundColor | string | Background color of the popup menu. |
| cornerRadius | number | Corner radius for the popup background. |
| onSelect | (info: { id?: string; title: string; path: string[] }) => void | Called when a menu item is selected. |
| trigger | "press" \| "longPress" \| "none" | Defines how the menu opens — by press, long press, or manually. |
| anchorTag | number \| null | (Advanced) Native anchor tag reference for manual positioning. |
| wrapperStyle | ViewStyle | Custom style for the wrapper around the trigger element. |
| children | React.ReactNode | The trigger element (button, icon, etc.) that opens the menu. |
| disabled | boolean | Disables interaction with the trigger. |
Menu Group & Item Structure
MenuGroupSpec
type MenuGroupSpec = {
items: MenuItemSpec[];
};MenuItemSpec
type MenuItemSpec = {
id?: string;
title: string;
icon?: {
resource?: string;
base64?: string;
};
enabled?: boolean;
items?: MenuItemSpec[];
onSelect?: (info: { id?: string; title: string; path: string[] }) => void;
};Each item may have:
- A unique
id - A visible
title - An optional
icon(Android resource name or Base64 image) - Nested
itemsfor submenus onSelectcallback for individual actionsenabledflag for disabling items
🧠 How It Works (Under the Hood)
The native Android module (DropdownMenuModule.kt) uses
CascadePopupMenu to render cascading menus.
It:
- Receives your menu structure from JS via Expo’s module bridge
- Dynamically builds Android
MenuandSubMenuhierarchies - Supports nested items, disabled states, and icons (from resource names or Base64)
- Emits
onItemSelectedevents back to JS when a user selects an item
Internal flow:
DropdownMenu (JS)
↓
Expo Native Module (Kotlin)
↓
CascadePopupMenu → Android View hierarchy🧩 Notes
- Platform: Android only (no-op on iOS/web)
- Icon source: Use Android built-in icons (
ic_menu_*) or custom base64 icons - Styling:
backgroundColorandcornerRadiusmap directly to native popup styles
🤝 Contributing
We’re open to contributors! To improve this module or add new features:
- Fork the repository on GitHub
- Clone your fork locally
- Create a new branch for your feature or fix
- Run the example project to test your changes (
cd example && npx expo start) - Submit a pull request with a clear description of your changes
Ensure your code follows existing style and passes lint checks.
📄 License
MIT © [Lhacen Med]
