1import * as NavigationBar from 'expo-navigation-bar'; 2import * as React from 'react'; 3import { Platform, ScrollView, Text } from 'react-native'; 4import { useSafeAreaFrame, useSafeAreaInsets } from 'react-native-safe-area-context'; 5 6import Button from '../components/Button'; 7import { Page, Section } from '../components/Page'; 8import { getRandomColor } from '../utilities/getRandomColor'; 9 10function usePosition(): [ 11 NavigationBar.NavigationBarPosition | null, 12 (position: NavigationBar.NavigationBarPosition) => void, 13] { 14 const [position, setPosition] = React.useState<NavigationBar.NavigationBarPosition | null>(null); 15 16 React.useEffect(() => { 17 let isMounted = true; 18 NavigationBar.unstable_getPositionAsync().then((position) => { 19 if (isMounted) { 20 setPosition(position); 21 } 22 }); 23 24 return () => { 25 isMounted = false; 26 }; 27 }, []); 28 29 const setNewPosition = React.useCallback( 30 (position: NavigationBar.NavigationBarPosition) => { 31 NavigationBar.setPositionAsync(position); 32 setPosition(position); 33 }, 34 [setPosition] 35 ); 36 37 return [position, setNewPosition]; 38} 39 40export default function NavigationBarScreen() { 41 return ( 42 <ScrollView> 43 <Page> 44 {Platform.OS !== 'android' && ( 45 <Text style={{ marginVertical: 8, fontSize: 16 }}>⚠️ NavigationBar is Android-only</Text> 46 )} 47 <Section title="Visibility"> 48 <VisibilityExample /> 49 </Section> 50 <Section title="Appearance"> 51 <ButtonStyleExample /> 52 </Section> 53 <Section title="Background Color"> 54 <BackgroundColorExample /> 55 </Section> 56 <Section title="Border Color"> 57 <BorderColorExample /> 58 </Section> 59 <Section title="Position"> 60 <PositionExample /> 61 </Section> 62 <Section title="Behavior"> 63 <BehaviorExample /> 64 </Section> 65 </Page> 66 </ScrollView> 67 ); 68} 69 70NavigationBarScreen.navigationOptions = { 71 title: 'Navigation Bar', 72}; 73 74function VisibilityExample() { 75 const visibility = NavigationBar.useVisibility(); 76 const nextVisibility = visibility === 'visible' ? 'hidden' : 'visible'; 77 return ( 78 <Button 79 title={`Toggle Visibility: ${nextVisibility}`} 80 onPress={() => { 81 NavigationBar.setVisibilityAsync(nextVisibility); 82 }} 83 /> 84 ); 85} 86 87function BackgroundColorExample() { 88 return ( 89 <Button 90 onPress={() => NavigationBar.setBackgroundColorAsync(getRandomColor())} 91 title="Set background color to random color" 92 /> 93 ); 94} 95 96function BorderColorExample() { 97 return ( 98 <Button 99 onPress={() => NavigationBar.setBorderColorAsync(getRandomColor())} 100 title="Set border color to random color" 101 /> 102 ); 103} 104 105function ButtonStyleExample() { 106 const [style, setStyle] = React.useState<NavigationBar.NavigationBarButtonStyle>('light'); 107 const nextStyle = style === 'light' ? 'dark' : 'light'; 108 return ( 109 <Button 110 onPress={() => { 111 NavigationBar.setButtonStyleAsync(nextStyle); 112 setStyle(nextStyle); 113 }} 114 title={`Toggle bar style: ${nextStyle}`} 115 /> 116 ); 117} 118 119const NavigationBarBehaviors: NavigationBar.NavigationBarBehavior[] = [ 120 'inset-swipe', 121 'inset-touch', 122 'overlay-swipe', 123]; 124 125function PositionExample() { 126 const [position, setPosition] = usePosition(); 127 128 const insets = useSafeAreaInsets(); 129 const frame = useSafeAreaFrame(); 130 131 return ( 132 <> 133 <Button 134 onPress={() => setPosition(position === 'absolute' ? 'relative' : 'absolute')} 135 title={`Position: ${position === 'absolute' ? 'relative' : 'absolute'}`} 136 /> 137 <Text>insets: {JSON.stringify(insets)}</Text> 138 <Text>frame: {JSON.stringify(frame)}</Text> 139 </> 140 ); 141} 142 143function BehaviorExample() { 144 const [behavior, setBehavior] = 145 React.useState<NavigationBar.NavigationBarBehavior>('inset-swipe'); 146 147 const nextNavigationBarBehavior = React.useMemo(() => { 148 const index = NavigationBarBehaviors.indexOf(behavior); 149 const newIndex = (index + 1) % NavigationBarBehaviors.length; 150 return NavigationBarBehaviors[newIndex]; 151 }, [behavior]); 152 153 const onPressBehavior = React.useCallback(() => { 154 NavigationBar.setBehaviorAsync(nextNavigationBarBehavior); 155 setBehavior(nextNavigationBarBehavior); 156 }, [nextNavigationBarBehavior]); 157 158 return <Button onPress={onPressBehavior} title={`Behavior: ${nextNavigationBarBehavior}`} />; 159} 160