Problem
You are tasked to create a full-page
bottom-sheet like experience to display some content within your React Native app. You wanted to use @gorhom/bottom-sheet
for this use case, however there are some bugs and you need to swap @gorhom/bottom-sheet
out for other libraries or find other techniques to achieve the same UI.
Today, we will explore how you can use react-navigation
to achieve similar experience.
Solution
To achieve what we want of a full-page
bottom-sheet, you can use react-navigation
with some params configured such that the page itself becomes a modal
.
This will be crucial to the user experience because it provides the user with the ability to swipe to dismiss the page.
Apart from being a modal
, you also need to provide some form of "darkened" background that is translucent, so that it indicates to the user it is a "bottom-sheet".
That is where the cardOverlay: Overlay
comes into play. We will provide a component that is this "darkened" view.
Here is a snippet of how you should configure your Screen
:
<Stack.Screen
name="Modal"
component={ModalScreen}
options={{
...TransitionPresets.ModalSlideFromBottomIOS, // provides bottom-up animation when launching page.
presentation: 'transparentModal',
cardOverlayEnabled: true,
headerTitleAlign: 'center',
headerShown: false,
cardOverlay: Overlay,
}}
/>
To let the user see the Overlay
background, you have to have a transparent view within your page. Since we are doing a full-page
bottom-sheet, we need set the height of this transparent view to be the safe area height.
Here is a snippet of the modal page:
const ModalScreen = () => {
const navigation = useNavigation<any>();
const onClose = () => {
navigation.canGoBack() && navigation.navigate('Home');
};
const top = useSafeAreaInsets().top;
return (
<View style={styles.root}>
<View style={[{ height: top }, styles.emptyContainer]} />
<View style={styles.contentContainer}>
<View style={styles.modalHeaderContainer}>
<Button title="close" onPress={onClose} />
<Text>Hello World</Text>
<Button title="save"></Button>
</View>
<Text>Hello</Text>
</View>
</View>
);
};
Here is how the full-page
bottom-sheet looks like: