How to Create a Scaling Drawer Using React Navigation 6
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.
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! 🤓