Skip to content

Commit

Permalink
Merge pull request #29991 from margelo/perf/native-stack-navigation
Browse files Browse the repository at this point in the history
Perf/native stack navigation
  • Loading branch information
Julesssss authored Feb 22, 2024
2 parents d33bf6e + 2382538 commit 5f84683
Show file tree
Hide file tree
Showing 18 changed files with 173 additions and 36 deletions.
39 changes: 28 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
"@react-native-picker/picker": "2.5.1",
"@react-navigation/material-top-tabs": "^6.6.3",
"@react-navigation/native": "6.1.8",
"@react-navigation/native-stack": "^6.9.17",
"@react-navigation/stack": "6.3.16",
"@react-ng/bounds-observer": "^0.2.1",
"@rnmapbox/maps": "^10.1.11",
Expand Down
39 changes: 39 additions & 0 deletions patches/@react-navigation+native-stack+6.9.17.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
diff --git a/node_modules/@react-navigation/native-stack/src/types.tsx b/node_modules/@react-navigation/native-stack/src/types.tsx
index 206fb0b..7a34a8e 100644
--- a/node_modules/@react-navigation/native-stack/src/types.tsx
+++ b/node_modules/@react-navigation/native-stack/src/types.tsx
@@ -490,6 +490,14 @@ export type NativeStackNavigationOptions = {
* Only supported on iOS and Android.
*/
freezeOnBlur?: boolean;
+ // partial changes from https://github.com/react-navigation/react-navigation/commit/90cfbf23bcc5259f3262691a9eec6c5b906e5262
+ // patch can be removed when new version of `native-stack` will be released
+ /**
+ * Whether the keyboard should hide when swiping to the previous screen. Defaults to `false`.
+ *
+ * Only supported on iOS
+ */
+ keyboardHandlingEnabled?: boolean;
};

export type NativeStackNavigatorProps = DefaultNavigatorOptions<
diff --git a/node_modules/@react-navigation/native-stack/src/views/NativeStackView.native.tsx b/node_modules/@react-navigation/native-stack/src/views/NativeStackView.native.tsx
index a005c43..03d8b50 100644
--- a/node_modules/@react-navigation/native-stack/src/views/NativeStackView.native.tsx
+++ b/node_modules/@react-navigation/native-stack/src/views/NativeStackView.native.tsx
@@ -161,6 +161,7 @@ const SceneView = ({
statusBarTranslucent,
statusBarColor,
freezeOnBlur,
+ keyboardHandlingEnabled,
} = options;

let {
@@ -289,6 +290,7 @@ const SceneView = ({
onNativeDismissCancelled={onNativeDismissCancelled}
// this prop is available since rn-screens 3.16
freezeOnBlur={freezeOnBlur}
+ hideKeyboardOnSwipe={keyboardHandlingEnabled}
>
<NavigationContext.Provider value={navigation}>
<NavigationRouteContext.Provider value={route}>
8 changes: 4 additions & 4 deletions src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type {ParamListBase} from '@react-navigation/routers';
import type {StackNavigationOptions} from '@react-navigation/stack';
import {CardStyleInterpolators, createStackNavigator} from '@react-navigation/stack';
import React, {useMemo} from 'react';
import useThemeStyles from '@hooks/useThemeStyles';
import createPlatformStackNavigator from '@libs/Navigation/PlatformStackNavigation/createPlatformStackNavigator';
import type {
AddPersonalBankAccountNavigatorParamList,
DetailsNavigatorParamList,
Expand Down Expand Up @@ -35,6 +35,7 @@ import type {
import type {ThemeStyles} from '@styles/index';
import type {Screen} from '@src/SCREENS';
import SCREENS from '@src/SCREENS';
import subRouteOptions from './modalStackNavigatorOptions';

type Screens = Partial<Record<Screen, () => React.ComponentType>>;

Expand All @@ -45,16 +46,15 @@ type Screens = Partial<Record<Screen, () => React.ComponentType>>;
* @param getScreenOptions optional function that returns the screen options, override the default options
*/
function createModalStackNavigator<TStackParams extends ParamListBase>(screens: Screens, getScreenOptions?: (styles: ThemeStyles) => StackNavigationOptions): React.ComponentType {
const ModalStackNavigator = createStackNavigator<TStackParams>();
const ModalStackNavigator = createPlatformStackNavigator<TStackParams>();

function ModalStack() {
const styles = useThemeStyles();

const defaultSubRouteOptions = useMemo(
(): StackNavigationOptions => ({
...subRouteOptions,
cardStyle: styles.navigationScreenCardStyle,
headerShown: false,
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
}),
[styles],
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {createStackNavigator} from '@react-navigation/stack';
import React from 'react';
import useThemeStyles from '@hooks/useThemeStyles';
import ReportScreenWrapper from '@libs/Navigation/AppNavigator/ReportScreenWrapper';
import getCurrentUrl from '@libs/Navigation/currentUrl';
import createPlatformStackNavigator from '@libs/Navigation/PlatformStackNavigation/createPlatformStackNavigator';
import type {CentralPaneNavigatorParamList} from '@navigation/types';
import SCREENS from '@src/SCREENS';

const Stack = createStackNavigator<CentralPaneNavigatorParamList>();
const Stack = createPlatformStackNavigator<CentralPaneNavigatorParamList>();

const url = getCurrentUrl();
const openOnAdminRoom = url ? new URL(url).searchParams.get('openOnAdminRoom') : undefined;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function Overlay() {
return null;
}

Overlay.displayName = 'Overlay';

export default Overlay;
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import type {StackScreenProps} from '@react-navigation/stack';
import {createStackNavigator} from '@react-navigation/stack';
import React, {useMemo, useRef} from 'react';
import {View} from 'react-native';
import NoDropZone from '@components/DragAndDrop/NoDropZone';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import ModalNavigatorScreenOptions from '@libs/Navigation/AppNavigator/ModalNavigatorScreenOptions';
import * as ModalStackNavigators from '@libs/Navigation/AppNavigator/ModalStackNavigators';
import createPlatformStackNavigator from '@libs/Navigation/PlatformStackNavigation/createPlatformStackNavigator';
import type {AuthScreensParamList, RightModalNavigatorParamList} from '@navigation/types';
import type NAVIGATORS from '@src/NAVIGATORS';
import SCREENS from '@src/SCREENS';
import Overlay from './Overlay';

type RightModalNavigatorProps = StackScreenProps<AuthScreensParamList, typeof NAVIGATORS.RIGHT_MODAL_NAVIGATOR>;

const Stack = createStackNavigator<RightModalNavigatorParamList>();
const Stack = createPlatformStackNavigator<RightModalNavigatorParamList>();

function RightModalNavigator({navigation}: RightModalNavigatorProps) {
const styles = useThemeStyles();
Expand Down
4 changes: 2 additions & 2 deletions src/libs/Navigation/AppNavigator/PublicScreens.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {createStackNavigator} from '@react-navigation/stack';
import React from 'react';
import createPlatformStackNavigator from '@libs/Navigation/PlatformStackNavigation/createPlatformStackNavigator';
import type {PublicScreensParamList} from '@navigation/types';
import LogInWithShortLivedAuthTokenPage from '@pages/LogInWithShortLivedAuthTokenPage';
import AppleSignInDesktopPage from '@pages/signin/AppleSignInDesktopPage';
Expand All @@ -12,7 +12,7 @@ import NAVIGATORS from '@src/NAVIGATORS';
import SCREENS from '@src/SCREENS';
import defaultScreenOptions from './defaultScreenOptions';

const RootStack = createStackNavigator<PublicScreensParamList>();
const RootStack = createPlatformStackNavigator<PublicScreensParamList>();

function PublicScreens() {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const defaultScreenOptions = {
contentStyle: {
overflow: 'visible',
flex: 1,
},
headerShown: false,
animationTypeForReplace: 'push',
animation: 'slide_from_right',
};

export default defaultScreenOptions;
12 changes: 12 additions & 0 deletions src/libs/Navigation/AppNavigator/defaultScreenOptions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type {StackNavigationOptions} from '@react-navigation/stack';

const defaultScreenOptions: StackNavigationOptions = {
cardStyle: {
overflow: 'visible',
flex: 1,
},
headerShown: false,
animationTypeForReplace: 'push',
};

export default defaultScreenOptions;
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type {NativeStackNavigationOptions} from '@react-navigation/native-stack';

const rightModalNavigatorOptions = (): NativeStackNavigationOptions => ({
presentation: 'card',
animation: 'slide_from_right',
});

export default rightModalNavigatorOptions;
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type {StackNavigationOptions} from '@react-navigation/stack';
// eslint-disable-next-line no-restricted-imports
import getNavigationModalCardStyle from '@styles/utils/getNavigationModalCardStyles';

const rightModalNavigatorOptions = (isSmallScreenWidth: boolean): StackNavigationOptions => ({
presentation: 'transparentModal',

// We want pop in RHP since there are some flows that would work weird otherwise
animationTypeForReplace: 'pop',
cardStyle: {
...getNavigationModalCardStyle(),

// This is necessary to cover translated sidebar with overlay.
width: isSmallScreenWidth ? '100%' : '200%',
// Excess space should be on the left so we need to position from right.
right: 0,
},
});

export default rightModalNavigatorOptions;
23 changes: 8 additions & 15 deletions src/libs/Navigation/AppNavigator/getRootNavigatorScreenOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {StyleUtilsType} from '@styles/utils';
import variables from '@styles/variables';
import CONFIG from '@src/CONFIG';
import createModalCardStyleInterpolator from './createModalCardStyleInterpolator';
import getRightModalNavigatorOptions from './getRightModalNavigatorOptions';

type ScreenOptions = Record<string, StackNavigationOptions>;

Expand All @@ -25,23 +26,12 @@ const getRootNavigatorScreenOptions: GetRootNavigatorScreenOptions = (isSmallScr
return {
rightModalNavigator: {
...commonScreenOptions,
...getRightModalNavigatorOptions(isSmallScreenWidth),
cardStyleInterpolator: (props: StackCardInterpolationProps) => modalCardStyleInterpolator(isSmallScreenWidth, false, props),
presentation: 'transparentModal',

// We want pop in RHP since there are some flows that would work weird otherwise
animationTypeForReplace: 'pop',
cardStyle: {
...StyleUtils.getNavigationModalCardStyle(),

// This is necessary to cover translated sidebar with overlay.
width: isSmallScreenWidth ? '100%' : '200%',
// Excess space should be on the left so we need to position from right.
right: 0,
},
},
leftModalNavigator: {
...commonScreenOptions,
cardStyleInterpolator: (props) => modalCardStyleInterpolator(isSmallScreenWidth, false, props, SLIDE_LEFT_OUTPUT_RANGE_MULTIPLIER),
cardStyleInterpolator: (props: StackCardInterpolationProps) => modalCardStyleInterpolator(isSmallScreenWidth, false, props, SLIDE_LEFT_OUTPUT_RANGE_MULTIPLIER),
presentation: 'transparentModal',

// We want pop in LHP since there are some flows that would work weird otherwise
Expand All @@ -59,8 +49,8 @@ const getRootNavigatorScreenOptions: GetRootNavigatorScreenOptions = (isSmallScr
homeScreen: {
title: CONFIG.SITE_TITLE,
...commonScreenOptions,
// Note: The card* properties won't be applied on mobile platforms, as they use the native defaults.
cardStyleInterpolator: (props: StackCardInterpolationProps) => modalCardStyleInterpolator(isSmallScreenWidth, false, props),

cardStyle: {
...StyleUtils.getNavigationModalCardStyle(),
width: isSmallScreenWidth ? '100%' : variables.sideBarWidth,
Expand All @@ -73,6 +63,7 @@ const getRootNavigatorScreenOptions: GetRootNavigatorScreenOptions = (isSmallScr

fullScreen: {
...commonScreenOptions,

cardStyleInterpolator: (props: StackCardInterpolationProps) => modalCardStyleInterpolator(isSmallScreenWidth, true, props),
cardStyle: {
...StyleUtils.getNavigationModalCardStyle(),
Expand All @@ -87,7 +78,9 @@ const getRootNavigatorScreenOptions: GetRootNavigatorScreenOptions = (isSmallScr
...commonScreenOptions,
animationEnabled: isSmallScreenWidth,
cardStyleInterpolator: (props: StackCardInterpolationProps) => modalCardStyleInterpolator(isSmallScreenWidth, true, props),

// temporary solution - better to hide a keyboard than see keyboard flickering
// see https://github.com/software-mansion/react-native-screens/issues/2021 for more details
keyboardHandlingEnabled: true,
cardStyle: {
...StyleUtils.getNavigationModalCardStyle(),
paddingRight: isSmallScreenWidth ? 0 : variables.sideBarWidth,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type {NativeStackNavigationOptions} from '@react-navigation/native-stack';

const defaultSubRouteOptions: NativeStackNavigationOptions = {
headerShown: false,
animation: 'slide_from_right',
};

export default defaultSubRouteOptions;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type {StackNavigationOptions} from '@react-navigation/stack';
import {CardStyleInterpolators} from '@react-navigation/stack';

const defaultSubRouteOptions: StackNavigationOptions = {
headerShown: false,
cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
};

export default defaultSubRouteOptions;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {createNativeStackNavigator} from '@react-navigation/native-stack';

function createPlatformStackNavigator() {
return createNativeStackNavigator();
}

export default createPlatformStackNavigator;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import {createStackNavigator} from '@react-navigation/stack';

const createPlatformStackNavigator: typeof createStackNavigator = () => createStackNavigator();

export default createPlatformStackNavigator;

0 comments on commit 5f84683

Please sign in to comment.