Bottom Sheet with React Native

Let’s build ourselves a basic bottom sheet in react native.

Arbaz Ajaz
4 min readJan 22, 2024

Github: https://github.com/arbaz52/react-native-bottom-sheet

Demo of implementation.

We’ll start with a bare react-native project. Start with following react native’s documentation on how to setup a project. Once you have the project all set. Open it in your editor of choice. I go with VSCode.

Imports

Constants

The reason we’re using Dimension of window instead of screen is because we’ll be displaying an overlay behind the bottom sheet and over the actual content, and we want it to draw over the status bar as well, otherwise status bar will look odd.

Styles

Bottom Sheet Component

The reason we’re using forwardRef is we want our bottom sheet to be opened/closed by outside as well so we’ll be exposing functions that will let us do that.

We’ll use the state expanded to render/not-render our overlay so it does not render over the content if the bottom sheet is closed.

We’re starting with bottom sheet closed that is why the opacity that we will use for our overlay is set to 0

The reason we’re doing WINDOW_HEIGHT — BOTTOM_SHEET_HEIGHT.min is because we’re starting from the top, we move to the window’s bottom and then moving up the same amount as the minimum height for the bottom sheet. Notice that we’re not chaging our bottom sheet’s height, that would always be the max height we’ve set it, we’re just moving it so the rest goes out of screen.

I’ll explain why we’re using translateY.flattenOffset once I show you the implementation of PanResponder but other than that, we’re just writing two animations, one for overlay and the other for our bottom sheet and then playing them in parallel.

Also, we’re now exposing these functions that will be used externally (outside the component) to open/close the bottom sheet.

Butter (Using PanResponder)

onMoveShouldSetPanResponder : We’re returning true so we get access to events when a gesture is performed.

onPanResponderGrant : When the gesture begins, we extract the current value of our translateY, use it as its offset and set its value to 0. Otherwise, when the user will perform the gesture, the bottom sheet will stutter.

onPanResponderMove : During the time when the gesture is being performed, we’re getting its change in y/vertical axis and using it as value for our translateY

onPanResponderRelease : When the gesture ends, we extract the value of how much was dragged in y/vertical axis and if it’s less than our threshold value, we ignore the drag and animate our translateY value to 0 . If it’s greater, we’re checking the gesture direction, if it’s upwards or -ive, we open the sheet, otherwise we close it using functions we’ve defined earlier.

Final piece in the puzzle is the rendering:

  • Status bar is translucent because we want to draw our overlay on top of it.
  • We do not render the overlay if the bottom sheet is closed.
  • We’re using Animted.View instead of simple View because we want to animate its transform property.
  • We’re attaching panResponder.panHandlers responsible for accessing/handling gesture events to allow user to drag the bottom sheet vertically.
  • We’re rendering the content of the bottom sheet passed by the parent after the drag handle.

Usage

--

--

Arbaz Ajaz

Arbaz is a MERN Stack developer, aiming to make learning programming accessible and straight forward