Skip to content

Commit

Permalink
refactor: drop unmountOnBlur in favor of popToTopOnBlur
Browse files Browse the repository at this point in the history
  • Loading branch information
satya164 committed Mar 15, 2024
1 parent b1ed6b0 commit 4d84436
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 17 deletions.
4 changes: 2 additions & 2 deletions packages/bottom-tabs/src/types.tsx
Expand Up @@ -259,10 +259,10 @@ export type BottomTabNavigationOptions = HeaderOptions & {
headerShown?: boolean;

/**
* Whether this screen should be unmounted when navigating away from it.
* Whether any nested stack should be popped to top when navigating away from it.
* Defaults to `false`.
*/
unmountOnBlur?: boolean;
popToTopOnBlur?: boolean;

/**
* Whether inactive screens should be suspended from re-rendering. Defaults to `false`.
Expand Down
34 changes: 26 additions & 8 deletions packages/bottom-tabs/src/views/BottomTabView.tsx
Expand Up @@ -4,9 +4,10 @@ import {
SafeAreaProviderCompat,
Screen,
} from '@react-navigation/elements';
import type {
ParamListBase,
TabNavigationState,
import {
type ParamListBase,
StackActions,
type TabNavigationState,
} from '@react-navigation/native';
import * as React from 'react';
import { Animated, Platform, StyleSheet } from 'react-native';
Expand Down Expand Up @@ -137,6 +138,28 @@ export function BottomTabView(props: Props) {
animateToIndex();
}, [descriptors, focusedRouteKey, state.index, state.routes, tabAnims]);

// TODO: make sure this looks right of tab switching has animations
React.useEffect(() => {
const previousRouteKey = previousRouteKeyRef.current;
const popToTopOnBlur =
descriptors[previousRouteKey]?.options.popToTopOnBlur;

if (previousRouteKey !== focusedRouteKey && popToTopOnBlur) {
const prevRoute = state.routes.find(
(route) => route.key === previousRouteKey
);

if (prevRoute?.state?.type === 'stack' && prevRoute.state.key) {
navigation.dispatch({
...StackActions.popToTop(),
target: prevRoute.state.key,
});
}
}

previousRouteKeyRef.current = focusedRouteKey;
}, [descriptors, focusedRouteKey, navigation, state.routes]);

const dimensions = SafeAreaProviderCompat.initialMetrics.frame;
const [tabBarHeight, setTabBarHeight] = React.useState(() =>
getTabBarHeight({
Expand Down Expand Up @@ -205,17 +228,12 @@ export function BottomTabView(props: Props) {
const descriptor = descriptors[route.key];
const {
lazy = true,
unmountOnBlur,
animation = 'none',
sceneStyleInterpolator = NAMED_TRANSITIONS_PRESETS[animation]
.sceneStyleInterpolator,
} = descriptor.options;
const isFocused = state.index === index;

if (unmountOnBlur && !isFocused) {
return null;
}

if (
lazy &&
!loaded.includes(route.key) &&
Expand Down
4 changes: 2 additions & 2 deletions packages/drawer/src/types.tsx
Expand Up @@ -204,10 +204,10 @@ export type DrawerNavigationOptions = HeaderOptions & {
keyboardDismissMode?: 'on-drag' | 'none';

/**
* Whether this screen should be unmounted when navigating away from it.
* Whether any nested stack should be popped to top when navigating away from it.
* Defaults to `false`.
*/
unmountOnBlur?: boolean;
popToTopOnBlur?: boolean;

/**
* Whether inactive screens should be suspended from re-rendering. Defaults to `false`.
Expand Down
30 changes: 25 additions & 5 deletions packages/drawer/src/views/DrawerView.tsx
Expand Up @@ -10,6 +10,7 @@ import {
type DrawerNavigationState,
type DrawerStatus,
type ParamListBase,
StackActions,
useLocale,
useTheme,
} from '@react-navigation/native';
Expand Down Expand Up @@ -82,6 +83,29 @@ function DrawerViewBase({
setLoaded([...loaded, focusedRouteKey]);
}

const previousRouteKeyRef = React.useRef(focusedRouteKey);

React.useEffect(() => {
const previousRouteKey = previousRouteKeyRef.current;
const popToTopOnBlur =
descriptors[previousRouteKey]?.options.popToTopOnBlur;

if (previousRouteKey !== focusedRouteKey && popToTopOnBlur) {
const prevRoute = state.routes.find(
(route) => route.key === previousRouteKey
);

if (prevRoute?.state?.type === 'stack' && prevRoute.state.key) {
navigation.dispatch({
...StackActions.popToTop(),
target: prevRoute.state.key,
});
}
}

previousRouteKeyRef.current = focusedRouteKey;
}, [descriptors, focusedRouteKey, navigation, state.routes]);

const dimensions = useSafeAreaFrame();

const { colors } = useTheme();
Expand Down Expand Up @@ -194,13 +218,9 @@ function DrawerViewBase({
>
{state.routes.map((route, index) => {
const descriptor = descriptors[route.key];
const { lazy = true, unmountOnBlur } = descriptor.options;
const { lazy = true } = descriptor.options;
const isFocused = state.index === index;

if (unmountOnBlur && !isFocused) {
return null;
}

if (
lazy &&
!loaded.includes(route.key) &&
Expand Down

0 comments on commit 4d84436

Please sign in to comment.