Open kitchen drawer
Photo by Jarek Ceborski on Unsplash

How to Create a Scaling Drawer Using React Navigation 6

Paul Greve
the peak lab.
Published in
3 min readJan 26, 2022

--

We needed a drawer that scales down the content page when opened for one of our recently developed apps. We were already using the react-navigation/drawer package, so this should easily be possible by setting some props, right? Unfortunately, the API slightly changed with react-navigation v6, and most of the examples and tutorials online were outdated and did not work. So, to save you some headache, I will show you how to create a content-scaling drawer without any third-party packages, just simple react navigation.

While researching, we found the npm package react-native-scaling-drawer, which you might be happy to use. However, this is the last option if you want to avoid additional third-party packages for features that you might expect are already included in comprehensive packages like react-navigation. So we went on and read our way through the react navigation docs only to find out that the drawerContents' progress property was removed in v6. Instead, the new useDrawerStatus and useDrawerProgress hooks should be used. I will show you an example.

This old example is deprecated because the progress property was removed in v6.

Setup

We will create a blank react native project using Expo for the example project.

$ expo init react-navigation-6-scaling-drawer

We now have a blank app running. Next up, we add the navigation packages and the animation packages.

$ npm install -S @react-navigation/native @react-navigation/drawer $ expo install react-native-screens react-native-safe-area-context react-native-reanimated react-native-gesture-handler

We start by adding two simple screen components to simulate the page navigation.

After that, we create our drawer component based on the react-navigation/drawer and place it in the App component.

As intended, this already provides us with the basic drawer functionality. Now we have to adjust the behavior and styling to make it scale.

Scale it!

The key feature of our scaling behavior will be a reusable wrapper component for our plain home and profile screens. The wrapper adds an abstraction layer for the scaling animation to be used with any other (existing) screen component without knowing anything about its implementation details. The screen component does not have to know about the drawer navigator either.

So here’s our animated scaling wrapper using the new useDrawerStatus hook.

As you can see, we use the useDrawerStatus hook to keep track of the open/closed status. We scale the content page to 80% if the drawer is opened to achieve the desired effect. You might want to play around with this value according to the needs of your app.

To use our new behavior component, we wrap it around our content screens.

From here on, it’s just about adjusting the styles of the drawer, like setting a background color and styling the menu entries.

Optional: Dynamic status bar color for dark background drawers

If you want to use a dark background, the status bar color has to be set dynamically based on the open/closed state of the drawer. To achieve this, we first install an additional Expo package.

$ expo install expo-status-bar

We can then use its exported method to dynamically update the status bar color in the ScalableScreen wrapper component.

Wrapping up

And there you have it, a scaling drawer using nothing but React navigation v6! Pretty easy to use as a starting point for your custom implementation. The working example can be found here.

Please note that this is only one possible solution for this effect. Some people also implemented the behavior using useDrawerProgress which might work just as well.

Thank you for reading; hopefully I can help you with this tutorial. Happy coding! 🤓

--

--