Skip to main content

How to create bottom sheet with react-navigation

· 2 min read
Marcus Koh

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:

Reference: