Skip to content

Menubar

Menubar Primitive Text Component

Demo


A menu that stays visible on the screen, often seen in desktop apps, offering easy access to a standard set of commands.

Installation

Terminal window
npx @react-native-reusables/cli@latest add menubar

Usage

import { useNavigation } from 'expo-router';
import * as React from 'react';
import { Pressable, StyleSheet, View } from 'react-native';
import Animated, { FadeIn } from 'react-native-reanimated';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import {
Menubar,
MenubarCheckboxItem,
MenubarContent,
MenubarItem,
MenubarMenu,
MenubarRadioGroup,
MenubarRadioItem,
MenubarSeparator,
MenubarShortcut,
MenubarSub,
MenubarSubContent,
MenubarSubTrigger,
MenubarTrigger,
} from '~/components/ui/menubar';
import { Text } from '~/components/ui/text';
function Example() {
const insets = useSafeAreaInsets();
const contentInsets = {
top: insets.top,
bottom: insets.bottom,
left: 12,
right: 12,
};
const [value, setValue] = React.useState<string | undefined>();
const [isSubOpen, setIsSubOpen] = React.useState(false);
const [isSubOpen2, setIsSubOpen2] = React.useState(false);
const [isChecked, setIsChecked] = React.useState(false);
const [isChecked2, setIsChecked2] = React.useState(false);
const [radio, setRadio] = React.useState('michael');
const navigation = useNavigation();
React.useEffect(() => {
const sub = navigation.addListener('blur', () => {
onValueChange(undefined);
});
return sub;
}, []);
function closeSubs() {
setIsSubOpen(false);
setIsSubOpen2(false);
}
function onValueChange(val: string | undefined) {
if (typeof val === 'string') {
setValue(val);
return;
}
closeSubs();
setValue(undefined);
}
return (
<View className='flex-1 items-center p-4'>
{!!value && (
<Pressable
onPress={() => {
onValueChange(undefined);
}}
style={StyleSheet.absoluteFill}
/>
)}
<Menubar value={value} onValueChange={onValueChange}>
<MenubarMenu value='file'>
<MenubarTrigger onPress={closeSubs}>
<Text>File</Text>
</MenubarTrigger>
<MenubarContent insets={contentInsets}>
<MenubarItem>
<Text>New Tab</Text>
<MenubarShortcut>⌘T</MenubarShortcut>
</MenubarItem>
<MenubarItem>
<Text>New Window</Text>
<MenubarShortcut>⌘N</MenubarShortcut>
</MenubarItem>
<MenubarItem disabled>
<Text>New Incognito Window</Text>
</MenubarItem>
<MenubarSeparator />
<MenubarSub open={isSubOpen} onOpenChange={setIsSubOpen}>
<MenubarSubTrigger>
<Text>Share</Text>
</MenubarSubTrigger>
<MenubarSubContent>
<Animated.View entering={FadeIn.duration(200)}>
<MenubarItem>
<Text>Email link</Text>
</MenubarItem>
<MenubarItem>
<Text>Messages</Text>
</MenubarItem>
<MenubarItem>
<Text>Notes</Text>
</MenubarItem>
</Animated.View>
</MenubarSubContent>
</MenubarSub>
<MenubarSeparator />
<MenubarItem>
<Text>Print...</Text>
<MenubarShortcut>⌘P</MenubarShortcut>
</MenubarItem>
</MenubarContent>
</MenubarMenu>
<MenubarMenu value='edit'>
<MenubarTrigger onPress={closeSubs}>
<Text>Edit</Text>
</MenubarTrigger>
<MenubarContent insets={contentInsets} className='native:w-48'>
<MenubarItem>
<Text>Undo</Text>
<MenubarShortcut>⌘Z</MenubarShortcut>
</MenubarItem>
<MenubarItem>
<Text>Redo</Text>
<MenubarShortcut>⇧⌘Z</MenubarShortcut>
</MenubarItem>
<MenubarSeparator />
<MenubarSub open={isSubOpen2} onOpenChange={setIsSubOpen2}>
<MenubarSubTrigger>
<Text>Find</Text>
</MenubarSubTrigger>
<MenubarSubContent>
<Animated.View entering={FadeIn.duration(200)}>
<MenubarItem>
<Text>Search the web</Text>
</MenubarItem>
<MenubarSeparator />
<MenubarItem>
<Text>Find...</Text>
</MenubarItem>
<MenubarItem>
<Text>Find Next</Text>
</MenubarItem>
<MenubarItem>
<Text>Find Previous</Text>
</MenubarItem>
</Animated.View>
</MenubarSubContent>
</MenubarSub>
<MenubarSeparator />
<MenubarItem>
<Text>Cut</Text>
</MenubarItem>
<MenubarItem>
<Text>Copy</Text>
</MenubarItem>
<MenubarItem>
<Text>Paste</Text>
</MenubarItem>
</MenubarContent>
</MenubarMenu>
<MenubarMenu value='view'>
<MenubarTrigger onPress={closeSubs}>
<Text>View</Text>
</MenubarTrigger>
<MenubarContent insets={contentInsets}>
<MenubarCheckboxItem
checked={isChecked}
onCheckedChange={setIsChecked}
closeOnPress={false}
>
<Text>Always Show Bookmarks Bar</Text>
</MenubarCheckboxItem>
<MenubarCheckboxItem
checked={isChecked2}
onCheckedChange={setIsChecked2}
closeOnPress={false}
>
<Text>Always Show Full URLs</Text>
</MenubarCheckboxItem>
<MenubarSeparator />
<MenubarItem inset>
<Text>Reload</Text>
<MenubarShortcut>⌘R</MenubarShortcut>
</MenubarItem>
<MenubarItem disabled inset>
<Text>Force Reload</Text>
<MenubarShortcut>⇧⌘R</MenubarShortcut>
</MenubarItem>
<MenubarSeparator />
<MenubarItem inset>
<Text>Toggle Fullscreen</Text>
</MenubarItem>
<MenubarSeparator />
<MenubarItem inset>
<Text>Hide Sidebar</Text>
</MenubarItem>
</MenubarContent>
</MenubarMenu>
<MenubarMenu value='profile'>
<MenubarTrigger onPress={closeSubs}>
<Text>Profiles</Text>
</MenubarTrigger>
<MenubarContent insets={contentInsets}>
<MenubarRadioGroup value={radio} onValueChange={setRadio}>
<MenubarRadioItem closeOnPress={false} value='andy'>
<Text>Andy</Text>
</MenubarRadioItem>
<MenubarRadioItem closeOnPress={false} value='michael'>
<Text>Michael</Text>
</MenubarRadioItem>
<MenubarRadioItem closeOnPress={false} value='creed'>
<Text>Creed</Text>
</MenubarRadioItem>
</MenubarRadioGroup>
<MenubarSeparator />
<MenubarItem inset>
<Text>Edit...</Text>
</MenubarItem>
<MenubarSeparator />
<MenubarItem inset>
<Text>Add Profile...</Text>
</MenubarItem>
</MenubarContent>
</MenubarMenu>
</Menubar>
</View>
);
}

Props

Extends View props

PropTypeNote
open*boolean
onOpenChange*(value: boolean) => void
asChildboolean(optional)

Extends View props

PropTypeNote
value*string
asChildboolean(optional)

Extends Pressable props

PropTypeNote
asChildboolean(optional)
insetboolean(optional)
PropTypeNote
children*React.ReactNode
forceMounttrue | undefined(optional)
hostNamestringWeb Only (optional)
containerHTMLElement | null | undefinedWeb Only (optional)

Extends View props

PropTypeNote
asChildboolean(optional)
overlayStyleStyleProp<ViewStyle>(optional)
overlayClassNamestring(optional)
forceMounttrue | undefined(optional)
alignOffsetnumber(optional)
insetsInsets(optional)
avoidCollisionsboolean(optional)
align’start’ | ‘center’ | ‘end’(optional)
side’top’ | ‘bottom’(optional)
sideOffsetnumber(optional)
disablePositioningStylebooleanNative Only (optional)
loopbooleanWeb Only (optional)
onCloseAutoFocus(event: Event) => voidWeb Only (optional)
onEscapeKeyDown(event: KeyboardEvent) => voidWeb Only (optional)
onPointerDownOutside(event: PointerDownOutsideEvent) => voidWeb Only (optional)
onFocusOutside(event: FocusOutsideEvent) => voidWeb Only (optional)
onInteractOutsidePointerDownOutsideEvent | FocusOutsideEventWeb Only (optional)
collisionBoundaryElement | null | Array<Element | null>Web Only (optional)
sticky’partial’ | ‘always’Web Only (optional)
hideWhenDetachedbooleanWeb Only (optional)

Extends Text props

PropTypeNote
asChildboolean(optional)

Extends Text props

PropTypeNote
asChildboolean(optional)

Extends Pressable props

PropTypeNote
asChildboolean(optional)
textValueboolean(optional)
closeOnPressboolean(optional)

Extends Pressable props

PropTypeNote
checked*boolean
onCheckedChange*(value: boolean) => void
textValue*string
asChildboolean(optional)
closeOnPressbooleanNative Only (optional)

Extends View props

PropTypeNote
value*boolean
onValueChange*(value: boolean) => void
asChildboolean(optional)

Extends Pressable props

PropTypeNote
value*boolean
onCheckedChange*(value: boolean) => void
asChildboolean(optional)
closeOnPressbooleanNative Only (optional)

Extends View props

PropTypeNote
asChildboolean(optional)
decorativeboolean(optional)

Extends View props

PropTypeNote
asChildboolean(optional)
defaultOpenboolean(optional)
openboolean(optional)
onOpenChange(value: boolean) => void(optional)

Extends Pressable props

PropTypeNote
textValuestring(optional)
asChildboolean(optional)

Extends Pressable props

PropTypeNote
asChildboolean(optional)
forceMounttrue /undefined

Extends Text props