A dropdown menu displays a menu of items or actions that directly relate to the button's purpose.
Pro component
Requires all-access to use the source code
import { Stack } from 'expo-router';
import * as React from 'react';
import { View } from 'react-native';
import { Text } from '~/components/nativewindui/Text';
import { AlertAnchor } from '~/components/nativewindui/Alert';
import { AlertRef } from '~/components/nativewindui/Alert/types';
import { Button } from '../~/components/nativewindui/Button';
import { DropdownMenu } from '~/components/nativewindui/DropdownMenu';
import { DropdownMenuRef } from '~/components/nativewindui/DropdownMenu/types';
import {
createDropdownItem,
createDropdownSubMenu,
} from '~/components/nativewindui/DropdownMenu/utils';
import { useColorScheme } from '~/lib/useColorScheme';
export default function DropdownMenuScreen() {
const [checked, setChecked] = React.useState(false);
const [isLoading, setIsLoading] = React.useState(true);
const { colors } = useColorScheme();
const ref = React.useRef<DropdownMenuRef>(null);
const alertRef = React.useRef<AlertRef>(null);
const dynamicItems = React.useMemo(() => {
return [
createDropdownSubMenu({ title: 'Sub Menu', iOSItemSize: 'small', loading: isLoading }, [
createDropdownSubMenu({ title: 'Submenu 2' }, [
{ actionKey: '1', title: 'Item 1' },
{ actionKey: '2', title: 'Item 2' },
]),
createDropdownItem({ actionKey: '43', title: 'Item 3' }),
]),
createDropdownItem({
actionKey: '4',
title: 'Checkbox Item',
state: { checked },
keepOpenOnPress: true,
icon: {
namingScheme: 'sfSymbol',
name: 'checkmark.seal',
color: colors.primary,
},
}),
createDropdownItem({
actionKey: '5',
title: 'Set to loading',
keepOpenOnPress: true,
disabled: isLoading,
}),
];
}, [checked, isLoading]);
return (
<>
<Stack.Screen options={{ title: 'Dropdown Menu' }} />
<View className="flex-1 flex-row justify-center gap-8 p-8">
<DropdownMenu
title="Dropdown Menu"
items={STATIC_ITEMS}
onItemPress={(item) => {
alertRef.current?.alert({
title: 'Item Pressed',
message: `Item ${item.actionKey} pressed`,
buttons: [{ text: 'OK' }],
materialWidth: 350,
});
}}>
<Button>
<Text>Open Dropdown</Text>
</Button>
</DropdownMenu>
<DropdownMenu
ref={ref}
items={dynamicItems}
onItemPress={(item) => {
if (item.actionKey === '4') {
setChecked((prev) => !prev);
return;
}
if (item.actionKey === '5') {
setIsLoading(true);
setTimeout(() => {
setIsLoading(false);
}, 1500);
return;
}
alertRef.current?.alert({
title: 'Item Pressed',
message: `Item ${item.actionKey} pressed`,
buttons: [{ text: 'OK' }],
materialWidth: 350,
});
}}>
<Button
variant="secondary"
onPress={() => {
if (isLoading) {
setTimeout(() => {
setIsLoading(false);
}, 1500);
}
}}>
<Text>With State</Text>
</Button>
</DropdownMenu>
</View>
<AlertAnchor ref={alertRef} />
</>
);
}
const STATIC_ITEMS = [
createDropdownSubMenu({ title: 'Submenu 1', iOSItemSize: 'small', loading: false }, [
createDropdownSubMenu({ title: 'Sub', iOSItemSize: 'small' }, [
{ actionKey: '10', title: 'Select Me' },
{ actionKey: '20', title: 'No! Select Me!' },
]),
createDropdownItem({
actionKey: '430',
title: 'Item 430',
icon: { name: 'checkmark.seal', namingScheme: 'sfSymbol' },
}),
]),
createDropdownSubMenu({ title: 'Hello', iOSItemSize: 'small' }, [
createDropdownItem({
actionKey: '30',
icon: { name: 'checkmark.seal', namingScheme: 'sfSymbol' },
}),
createDropdownItem({
actionKey: '31',
icon: { name: 'checkmark.seal', namingScheme: 'sfSymbol' },
}),
createDropdownItem({
actionKey: '32',
icon: { name: 'checkmark.seal', namingScheme: 'sfSymbol' },
}),
createDropdownItem({
actionKey: '33',
icon: { name: 'checkmark.seal', namingScheme: 'sfSymbol' },
}),
]),
createDropdownSubMenu({ title: '', iOSType: 'inline', iOSItemSize: 'small' }, [
createDropdownItem({
actionKey: '130',
title: '💧',
}),
createDropdownItem({
actionKey: '131',
title: '💧',
}),
createDropdownItem({
actionKey: '132',
title: '💧',
}),
createDropdownItem({
actionKey: '133',
title: '💧',
}),
]),
createDropdownItem({
actionKey: '40',
title: 'Delete Computer',
destructive: true,
image: { url: 'https://picsum.photos/id/2/100', cornerRadius: 30 },
}),
];
Unlock All Pro Screens & Components
Elevate your app with powerful, native-feeling components and templates. Build faster with beautiful ready-to-use designs.
The Dropdown-Menu is not compatible with the new architecture yet .
The child component needs to accept Pressable props to ensure compatibility on Android.
import { DropdownMenu } from '~/components/nativewindui/DropdownMenu';
import {
createDropdownItem,
createDropdownSubMenu,
} from '~/components/nativewindui/DropdownMenu/utils';
<DropdownMenu
items={[
createDropdownItem({
actionKey: 'first',
title: 'Item 1',
}),
createDropdownSubMenu({ title: 'Submenu 1', iOSItemSize: 'small' }, [
createDropdownItem({
actionKey: 'sub-first',
title: 'Sub Item 1',
}),
createDropdownItem({
actionKey: 'sub-second',
title: 'Sub Item 2',
}),
]),
]}
onItemPress={(item) => {
console.log('Item Pressed', item);
}}>
<Button>
<Text>Open Dropdown</Text>
</Button>
</DropdownMenu>
DropdownMenu
Inherits all the props from React Native's View component.
Prop | Type | Default | Description |
---|---|---|---|
title | string | The title of the dropdown menu. | |
items | (DropdownItem | DropdownSubMenu)[] | The items or submenus to display in the dropdown. | |
iOSItemSize | 'small' | 'medium' | 'large' | The preferred item size on iOS. | |
children | React.ReactNode | The child component to render inside the dropdown menu. It needs to accept Pressable props to ensure compatibility on Android | |
onItemPress | (item: Omit<DropdownItem, 'icon'>, isUsingActionSheetFallback?: boolean) => void | Callback function triggered when an item is pressed. | |
enabled | boolean | true | Whether the dropdown menu is enabled. |
materialPortalHost | string | The host for the Android portal. | |
materialSideOffset | number | 2 | Side offset for Android dropdown. |
materialAlignOffset | number | Alignment offset for Android dropdown. | |
materialAlign | 'start' | 'center' | 'end' | Alignment for Android dropdown. | |
materialWidth | number | Width for the Android dropdown. | |
materialMinWidth | number | Minimum width for the Android dropdown. | |
materialLoadingText | string | Text to display while the dropdown is loading. | |
materialSubMenuTitlePlaceholder | string | Placeholder title for the Android submenu. | |
materialOverlayClassName | string | Class name for the Android overlay. |
createDropdownSubMenu
: A utility function to create a dropdown sub-menu.
createDropdownItem
: A utility function to create a dropdown item.
import { createDropdownSubMenu, createDropdownItem } from '~/components/nativewindui/DropdownMenu/utils';
const MENU = [
createDropdownSubMenu({ title: 'Submenu' }, [
createDropdownItem({ actionKey: '1', title: 'Item 1' }),
createDropdownItem({ actionKey: '2', title: 'Item 2' }),
]),
];