Compare commits

...

6 Commits

Author SHA1 Message Date
Satyajit Sahoo
e00c63e32b chore: publish
- react-navigation-stack@2.7.0
2020-06-08 11:35:08 +02:00
Satyajit Sahoo
ba6d7dcbed feat: sync latest stack 2020-06-08 11:31:03 +02:00
Satyajit Sahoo
2ca8c34b2d chore: publish
- react-navigation-stack@2.6.0
2020-06-06 22:38:25 +02:00
Satyajit Sahoo
03f9f8cd8e feat: sync latest stack 2020-06-06 02:28:20 +02:00
Satyajit Sahoo
1ee8c76df3 chore: publish
- react-navigation-stack@2.5.1
2020-05-15 22:02:17 +02:00
Satyajit Sahoo
bc1313b61d fix: sync latest stack 2020-05-15 22:00:38 +02:00
17 changed files with 724 additions and 683 deletions

View File

@@ -64,7 +64,7 @@ class ListScreen extends React.Component {
flex: 1, flex: 1,
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
backgroundColor: '#fff', // backgroundColor: '#fff',
}} }}
> >
<Text>List Screen</Text> <Text>List Screen</Text>
@@ -96,7 +96,7 @@ class DetailsScreen extends React.Component<NavigationStackScreenProps> {
flex: 1, flex: 1,
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
backgroundColor: '#fff', // backgroundColor: '#fff',
}} }}
> >
<Text>Details Screen</Text> <Text>Details Screen</Text>
@@ -119,7 +119,7 @@ class HeaderlessScreen extends React.Component {
flex: 1, flex: 1,
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
backgroundColor: '#fff', // backgroundColor: '#fff',
}} }}
> >
<Text>Headerless Screen</Text> <Text>Headerless Screen</Text>

View File

@@ -3,6 +3,39 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
# [2.7.0](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.6.0...react-navigation-stack@2.7.0) (2020-06-08)
### Features
* sync latest stack ([ba6d7dc](https://github.com/react-navigation/react-navigation-stack/commit/ba6d7dcbedcfca774a53de32f92acc45140bb1fe))
# [2.6.0](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.5.1...react-navigation-stack@2.6.0) (2020-06-06)
### Features
* sync latest stack ([03f9f8c](https://github.com/react-navigation/react-navigation-stack/commit/03f9f8cd8ec3b5fe9dc2ed1ed2024e79dd06f854))
## [2.5.1](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.5.0...react-navigation-stack@2.5.1) (2020-05-15)
### Bug Fixes
* sync latest stack ([bc1313b](https://github.com/react-navigation/react-navigation-stack/commit/bc1313b61da6134255adff477ded2ed8f632bf4a))
# [2.5.0](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.4.0...react-navigation-stack@2.5.0) (2020-05-11) # [2.5.0](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.4.0...react-navigation-stack@2.5.0) (2020-05-11)

View File

@@ -1,6 +1,6 @@
{ {
"name": "react-navigation-stack", "name": "react-navigation-stack",
"version": "2.5.0", "version": "2.7.0",
"description": "Stack navigator component for React Navigation", "description": "Stack navigator component for React Navigation",
"main": "lib/commonjs/index.js", "main": "lib/commonjs/index.js",
"module": "lib/module/index.js", "module": "lib/module/index.js",
@@ -45,7 +45,7 @@
"devDependencies": { "devDependencies": {
"@react-native-community/bob": "^0.10.0", "@react-native-community/bob": "^0.10.0",
"@react-native-community/masked-view": "^0.1.7", "@react-native-community/masked-view": "^0.1.7",
"@react-navigation/stack": "^5.3.3", "@react-navigation/stack": "^5.5.1",
"@types/color": "^3.0.1", "@types/color": "^3.0.1",
"@types/react": "^16.9.23", "@types/react": "^16.9.23",
"@types/react-native": "^0.61.22", "@types/react-native": "^0.61.22",

View File

@@ -1,6 +1,6 @@
diff -Naur ../../node_modules/@react-navigation/stack/src/index.tsx src/vendor/index.tsx diff -Naur ../../node_modules/@react-navigation/stack/src/index.tsx src/vendor/index.tsx
--- ../../node_modules/@react-navigation/stack/src/index.tsx 2020-05-11 17:55:45.000000000 +0200 --- ../../node_modules/@react-navigation/stack/src/index.tsx 2020-06-08 11:22:56.000000000 +0200
+++ src/vendor/index.tsx 2020-05-11 18:29:57.000000000 +0200 +++ src/vendor/index.tsx 2020-06-08 11:23:27.000000000 +0200
@@ -3,11 +3,6 @@ @@ -3,11 +3,6 @@
import * as TransitionSpecs from './TransitionConfigs/TransitionSpecs'; import * as TransitionSpecs from './TransitionConfigs/TransitionSpecs';
import * as TransitionPresets from './TransitionConfigs/TransitionPresets'; import * as TransitionPresets from './TransitionConfigs/TransitionPresets';
@@ -28,7 +28,7 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/index.tsx src/vendor/i
StackHeaderLeftButtonProps, StackHeaderLeftButtonProps,
StackHeaderTitleProps, StackHeaderTitleProps,
diff -Naur ../../node_modules/@react-navigation/stack/src/navigators/createStackNavigator.tsx src/vendor/navigators/createStackNavigator.tsx diff -Naur ../../node_modules/@react-navigation/stack/src/navigators/createStackNavigator.tsx src/vendor/navigators/createStackNavigator.tsx
--- ../../node_modules/@react-navigation/stack/src/navigators/createStackNavigator.tsx 2020-05-11 17:55:45.000000000 +0200 --- ../../node_modules/@react-navigation/stack/src/navigators/createStackNavigator.tsx 2020-06-08 11:22:56.000000000 +0200
+++ src/vendor/navigators/createStackNavigator.tsx 1970-01-01 01:00:00.000000000 +0100 +++ src/vendor/navigators/createStackNavigator.tsx 1970-01-01 01:00:00.000000000 +0100
@@ -1,96 +0,0 @@ @@ -1,96 +0,0 @@
-import * as React from 'react'; -import * as React from 'react';
@@ -128,8 +128,8 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/navigators/createStack
- typeof StackNavigator - typeof StackNavigator
->(StackNavigator); ->(StackNavigator);
diff -Naur ../../node_modules/@react-navigation/stack/src/types.tsx src/vendor/types.tsx diff -Naur ../../node_modules/@react-navigation/stack/src/types.tsx src/vendor/types.tsx
--- ../../node_modules/@react-navigation/stack/src/types.tsx 2020-05-11 17:55:45.000000000 +0200 --- ../../node_modules/@react-navigation/stack/src/types.tsx 2020-06-08 11:22:56.000000000 +0200
+++ src/vendor/types.tsx 2020-05-11 18:29:52.000000000 +0200 +++ src/vendor/types.tsx 2020-06-08 11:23:27.000000000 +0200
@@ -8,15 +8,28 @@ @@ -8,15 +8,28 @@
} from 'react-native'; } from 'react-native';
import { EdgeInsets } from 'react-native-safe-area-context'; import { EdgeInsets } from 'react-native-safe-area-context';
@@ -218,7 +218,7 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/types.tsx src/vendor/t
}; };
export type Layout = { width: number; height: number }; export type Layout = { width: number; height: number };
@@ -227,24 +239,27 @@ @@ -228,24 +240,27 @@
/** /**
* Navigation prop for the header. * Navigation prop for the header.
*/ */
@@ -252,7 +252,7 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/types.tsx src/vendor/t
export type StackNavigationOptions = StackHeaderOptions & export type StackNavigationOptions = StackHeaderOptions &
Partial<TransitionPreset> & { Partial<TransitionPreset> & {
/** /**
@@ -329,6 +344,8 @@ @@ -330,6 +345,8 @@
bottom?: number; bottom?: number;
left?: number; left?: number;
}; };
@@ -262,8 +262,8 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/types.tsx src/vendor/t
export type StackNavigationConfig = { export type StackNavigationConfig = {
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/Header.tsx src/vendor/views/Header/Header.tsx diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/Header.tsx src/vendor/views/Header/Header.tsx
--- ../../node_modules/@react-navigation/stack/src/views/Header/Header.tsx 2020-05-11 17:55:45.000000000 +0200 --- ../../node_modules/@react-navigation/stack/src/views/Header/Header.tsx 2020-06-08 11:22:56.000000000 +0200
+++ src/vendor/views/Header/Header.tsx 2020-05-11 18:16:24.000000000 +0200 +++ src/vendor/views/Header/Header.tsx 2020-06-08 11:23:27.000000000 +0200
@@ -1,12 +1,14 @@ @@ -1,12 +1,14 @@
import * as React from 'react'; import * as React from 'react';
-import { StackActions } from '@react-navigation/native'; -import { StackActions } from '@react-navigation/native';
@@ -344,8 +344,8 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/Header.ts
+ +
+export default Header; +export default Header;
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderBackButton.tsx src/vendor/views/Header/HeaderBackButton.tsx diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderBackButton.tsx src/vendor/views/Header/HeaderBackButton.tsx
--- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderBackButton.tsx 2020-05-11 17:55:45.000000000 +0200 --- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderBackButton.tsx 2020-06-08 11:22:56.000000000 +0200
+++ src/vendor/views/Header/HeaderBackButton.tsx 2020-05-11 18:05:10.000000000 +0200 +++ src/vendor/views/Header/HeaderBackButton.tsx 2020-06-08 11:23:27.000000000 +0200
@@ -8,9 +8,9 @@ @@ -8,9 +8,9 @@
StyleSheet, StyleSheet,
LayoutChangeEvent, LayoutChangeEvent,
@@ -358,19 +358,20 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderBac
type Props = StackHeaderLeftButtonProps; type Props = StackHeaderLeftButtonProps;
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderBackground.tsx src/vendor/views/Header/HeaderBackground.tsx diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderBackground.tsx src/vendor/views/Header/HeaderBackground.tsx
--- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderBackground.tsx 2020-05-11 17:55:45.000000000 +0200 --- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderBackground.tsx 2020-06-08 11:22:56.000000000 +0200
+++ src/vendor/views/Header/HeaderBackground.tsx 2020-05-11 18:05:10.000000000 +0200 +++ src/vendor/views/Header/HeaderBackground.tsx 2020-06-08 11:23:27.000000000 +0200
@@ -1,6 +1,6 @@ @@ -7,7 +7,7 @@
import * as React from 'react'; StyleProp,
import { Animated, StyleSheet, Platform, ViewProps } from 'react-native'; ViewStyle,
} from 'react-native';
-import { useTheme } from '@react-navigation/native'; -import { useTheme } from '@react-navigation/native';
+import useTheme from '../../../utils/useTheme'; +import useTheme from '../../../utils/useTheme';
type Props = ViewProps & { type Props = ViewProps & {
children?: React.ReactNode; style?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderContainer.tsx src/vendor/views/Header/HeaderContainer.tsx diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderContainer.tsx src/vendor/views/Header/HeaderContainer.tsx
--- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderContainer.tsx 2020-05-11 17:55:45.000000000 +0200 --- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderContainer.tsx 2020-06-08 11:22:56.000000000 +0200
+++ src/vendor/views/Header/HeaderContainer.tsx 2020-05-11 18:05:10.000000000 +0200 +++ src/vendor/views/Header/HeaderContainer.tsx 2020-06-08 11:23:27.000000000 +0200
@@ -1,11 +1,6 @@ @@ -1,11 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import { View, StyleSheet, StyleProp, ViewStyle } from 'react-native'; import { View, StyleSheet, StyleProp, ViewStyle } from 'react-native';
@@ -384,15 +385,15 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderCon
import { EdgeInsets } from 'react-native-safe-area-context'; import { EdgeInsets } from 'react-native-safe-area-context';
import Header from './Header'; import Header from './Header';
@@ -16,6 +11,7 @@ @@ -17,6 +12,7 @@
forSlideRight,
} from '../../TransitionConfigs/HeaderStyleInterpolators'; } from '../../TransitionConfigs/HeaderStyleInterpolators';
import HeaderShownContext from '../../utils/HeaderShownContext';
import { import {
+ Route, + Route,
Layout, Layout,
Scene, Scene,
StackHeaderStyleInterpolator, StackHeaderStyleInterpolator,
@@ -99,9 +95,7 @@ @@ -117,9 +113,7 @@
insets, insets,
scene, scene,
previous, previous,
@@ -403,7 +404,7 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderCon
styleInterpolator: styleInterpolator:
mode === 'float' mode === 'float'
? isHeaderStatic ? isHeaderStatic
@@ -120,7 +114,7 @@ @@ -138,7 +132,7 @@
key={scene.route.key} key={scene.route.key}
value={scene.descriptor.navigation} value={scene.descriptor.navigation}
> >
@@ -412,9 +413,9 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderCon
<View <View
onLayout={ onLayout={
onContentHeightChange onContentHeightChange
@@ -152,7 +146,7 @@ @@ -164,7 +158,7 @@
) >
) : null} {header !== undefined ? header(props) : <Header {...props} />}
</View> </View>
- </NavigationRouteContext.Provider> - </NavigationRouteContext.Provider>
+ </> + </>
@@ -422,8 +423,8 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderCon
); );
})} })}
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderSegment.tsx src/vendor/views/Header/HeaderSegment.tsx diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderSegment.tsx src/vendor/views/Header/HeaderSegment.tsx
--- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderSegment.tsx 2020-05-11 17:55:45.000000000 +0200 --- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderSegment.tsx 2020-06-08 11:22:56.000000000 +0200
+++ src/vendor/views/Header/HeaderSegment.tsx 2020-05-11 18:17:37.000000000 +0200 +++ src/vendor/views/Header/HeaderSegment.tsx 2020-06-08 11:23:27.000000000 +0200
@@ -8,7 +8,7 @@ @@ -8,7 +8,7 @@
ViewStyle, ViewStyle,
} from 'react-native'; } from 'react-native';
@@ -443,8 +444,8 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderSeg
}; };
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderTitle.tsx src/vendor/views/Header/HeaderTitle.tsx diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderTitle.tsx src/vendor/views/Header/HeaderTitle.tsx
--- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderTitle.tsx 2020-05-11 17:55:45.000000000 +0200 --- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderTitle.tsx 2020-06-08 11:22:56.000000000 +0200
+++ src/vendor/views/Header/HeaderTitle.tsx 2020-05-11 18:17:37.000000000 +0200 +++ src/vendor/views/Header/HeaderTitle.tsx 2020-06-08 11:23:27.000000000 +0200
@@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import { Animated, StyleSheet, Platform } from 'react-native'; import { Animated, StyleSheet, Platform } from 'react-native';
@@ -454,9 +455,9 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderTit
type Props = Omit<React.ComponentProps<typeof Animated.Text>, 'key'> & { type Props = Omit<React.ComponentProps<typeof Animated.Text>, 'key'> & {
tintColor?: string; tintColor?: string;
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/Card.tsx src/vendor/views/Stack/Card.tsx diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/Card.tsx src/vendor/views/Stack/Card.tsx
--- ../../node_modules/@react-navigation/stack/src/views/Stack/Card.tsx 2020-05-11 17:55:45.000000000 +0200 --- ../../node_modules/@react-navigation/stack/src/views/Stack/Card.tsx 2020-06-08 11:22:56.000000000 +0200
+++ src/vendor/views/Stack/Card.tsx 2020-05-11 18:05:10.000000000 +0200 +++ src/vendor/views/Stack/Card.tsx 2020-06-08 11:23:27.000000000 +0200
@@ -140,7 +140,7 @@ @@ -146,7 +146,7 @@
private interactionHandle: number | undefined; private interactionHandle: number | undefined;
@@ -466,33 +467,25 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/Card.tsx s
private animate = ({ private animate = ({
closing, closing,
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/CardContainer.tsx src/vendor/views/Stack/CardContainer.tsx diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/CardContainer.tsx src/vendor/views/Stack/CardContainer.tsx
--- ../../node_modules/@react-navigation/stack/src/views/Stack/CardContainer.tsx 2020-05-11 17:55:45.000000000 +0200 --- ../../node_modules/@react-navigation/stack/src/views/Stack/CardContainer.tsx 2020-06-08 11:22:56.000000000 +0200
+++ src/vendor/views/Stack/CardContainer.tsx 2020-05-11 18:33:41.000000000 +0200 +++ src/vendor/views/Stack/CardContainer.tsx 2020-06-08 11:23:27.000000000 +0200
@@ -1,10 +1,11 @@ @@ -1,11 +1,12 @@
import * as React from 'react'; import * as React from 'react';
import { Animated, View, StyleSheet, StyleProp, ViewStyle } from 'react-native'; import { Animated, View, StyleSheet, StyleProp, ViewStyle } from 'react-native';
-import { Route, useTheme } from '@react-navigation/native'; -import { Route, useTheme } from '@react-navigation/native';
import { Props as HeaderContainerProps } from '../Header/HeaderContainer'; import { Props as HeaderContainerProps } from '../Header/HeaderContainer';
import Card from './Card'; import Card from './Card';
import HeaderHeightContext from '../../utils/HeaderHeightContext'; import HeaderHeightContext from '../../utils/HeaderHeightContext';
import HeaderShownContext from '../../utils/HeaderShownContext';
+import useTheme from '../../../utils/useTheme'; +import useTheme from '../../../utils/useTheme';
import { import {
+ Route, + Route,
Scene, Scene,
Layout, Layout,
StackHeaderMode, StackHeaderMode,
@@ -192,7 +193,7 @@
? { marginTop: headerHeight }
: null
}
- contentStyle={[{ backgroundColor: colors.background }, cardStyle]}
+ contentStyle={[{ backgroundColor: colors.background }, cardStyle] as any}
style={StyleSheet.absoluteFill}
>
<View style={styles.container}>
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/CardStack.tsx src/vendor/views/Stack/CardStack.tsx diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/CardStack.tsx src/vendor/views/Stack/CardStack.tsx
--- ../../node_modules/@react-navigation/stack/src/views/Stack/CardStack.tsx 2020-05-11 17:55:45.000000000 +0200 --- ../../node_modules/@react-navigation/stack/src/views/Stack/CardStack.tsx 2020-06-08 11:22:56.000000000 +0200
+++ src/vendor/views/Stack/CardStack.tsx 2020-05-11 18:05:10.000000000 +0200 +++ src/vendor/views/Stack/CardStack.tsx 2020-06-08 11:23:27.000000000 +0200
@@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
Platform, Platform,
} from 'react-native'; } from 'react-native';
@@ -502,8 +495,8 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/CardStack.
import { MaybeScreenContainer, MaybeScreen } from '../Screens'; import { MaybeScreenContainer, MaybeScreen } from '../Screens';
import { getDefaultHeaderHeight } from '../Header/HeaderSegment'; import { getDefaultHeaderHeight } from '../Header/HeaderSegment';
@@ -21,6 +21,7 @@ @@ -22,6 +22,7 @@
import { forNoAnimation as forNoAnimationCard } from '../../TransitionConfigs/CardStyleInterpolators'; import HeaderShownContext from '../../utils/HeaderShownContext';
import getDistanceForDirection from '../../utils/getDistanceForDirection'; import getDistanceForDirection from '../../utils/getDistanceForDirection';
import { import {
+ Route, + Route,
@@ -511,8 +504,8 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/CardStack.
StackHeaderMode, StackHeaderMode,
StackCardMode, StackCardMode,
diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/StackView.tsx src/vendor/views/Stack/StackView.tsx diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/StackView.tsx src/vendor/views/Stack/StackView.tsx
--- ../../node_modules/@react-navigation/stack/src/views/Stack/StackView.tsx 2020-05-11 17:55:45.000000000 +0200 --- ../../node_modules/@react-navigation/stack/src/views/Stack/StackView.tsx 2020-06-08 11:22:56.000000000 +0200
+++ src/vendor/views/Stack/StackView.tsx 2020-05-11 18:30:19.000000000 +0200 +++ src/vendor/views/Stack/StackView.tsx 2020-06-08 11:23:40.000000000 +0200
@@ -2,11 +2,11 @@ @@ -2,11 +2,11 @@
import { View, Platform, StyleSheet } from 'react-native'; import { View, Platform, StyleSheet } from 'react-native';
import { SafeAreaConsumer, EdgeInsets } from 'react-native-safe-area-context'; import { SafeAreaConsumer, EdgeInsets } from 'react-native-safe-area-context';
@@ -556,7 +549,7 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/StackView.
} }
return false; return false;
@@ -321,24 +325,47 @@ @@ -321,26 +325,49 @@
return null; return null;
} }
@@ -592,22 +585,24 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/StackView.
+ +
private handleOpenRoute = ({ route }: { route: Route<string> }) => { private handleOpenRoute = ({ route }: { route: Route<string> }) => {
const { state, navigation } = this.props; const { state, navigation } = this.props;
const { closingRouteKeys, replacingRouteKeys } = this.state;
+ this.handleTransitionComplete(); + this.handleTransitionComplete();
+ +
if ( if (
this.state.replacingRouteKeys.every((key) => key !== route.key) && closingRouteKeys.some((key) => key === route.key) &&
replacingRouteKeys.every((key) => key !== route.key) &&
- state.routeNames.includes(route.name) && - state.routeNames.includes(route.name) &&
!state.routes.some((r) => r.key === route.key) !state.routes.some((r) => r.key === route.key)
) { ) {
// If route isn't present in current state, assume that a close animation was cancelled // If route isn't present in current state, but was closing, assume that a close animation was cancelled
// So we need to add this route back to the state // So we need to add this route back to the state
- navigation.navigate(route); - navigation.navigate(route);
+ navigation.dispatch(NavigationActions.navigate(route)); + navigation.dispatch(NavigationActions.navigate(route));
} else { } else {
this.setState((state) => ({ this.setState((state) => ({
routes: state.replacingRouteKeys.length routes: state.replacingRouteKeys.length
@@ -364,12 +391,11 @@ @@ -366,12 +393,11 @@
// If a route exists in state, trigger a pop // If a route exists in state, trigger a pop
// This will happen in when the route was closed from the card component // This will happen in when the route was closed from the card component
// e.g. When the close animation triggered from a gesture ends // e.g. When the close animation triggered from a gesture ends
@@ -624,7 +619,7 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/StackView.
// We need to clean up any state tracking the route and pop it immediately // We need to clean up any state tracking the route and pop it immediately
this.setState((state) => ({ this.setState((state) => ({
routes: state.routes.filter((r) => r.key !== route.key), routes: state.routes.filter((r) => r.key !== route.key),
@@ -386,26 +412,29 @@ @@ -388,26 +414,29 @@
private handleTransitionStart = ( private handleTransitionStart = (
{ route }: { route: Route<string> }, { route }: { route: Route<string> },
closing: boolean closing: boolean
@@ -666,8 +661,8 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/StackView.
navigation, navigation,
keyboardHandlingEnabled, keyboardHandlingEnabled,
mode = 'card', mode = 'card',
@@ -423,7 +452,7 @@ @@ -425,7 +454,7 @@
mode === 'card' && Platform.OS === 'ios' ? 'float' : 'screen'; } = this.state;
return ( return (
- <NavigationHelpersContext.Provider value={navigation}> - <NavigationHelpersContext.Provider value={navigation}>
@@ -675,7 +670,7 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/StackView.
<GestureHandlerWrapper style={styles.container}> <GestureHandlerWrapper style={styles.container}>
<SafeAreaProviderCompat> <SafeAreaProviderCompat>
<SafeAreaConsumer> <SafeAreaConsumer>
@@ -456,7 +485,7 @@ @@ -458,7 +487,7 @@
</SafeAreaConsumer> </SafeAreaConsumer>
</SafeAreaProviderCompat> </SafeAreaProviderCompat>
</GestureHandlerWrapper> </GestureHandlerWrapper>

View File

@@ -8,6 +8,114 @@ exports[`Nested navigators renders succesfully as direct child 1`] = `
} }
} }
> >
<View
pointerEvents="box-none"
style={
Array [
Object {
"zIndex": 1,
},
false,
]
}
>
<View
accessibilityElementsHidden={false}
importantForAccessibility="auto"
onLayout={[Function]}
pointerEvents="box-none"
style={null}
>
<View
pointerEvents="box-none"
style={
Object {
"bottom": 0,
"left": 0,
"opacity": 1,
"position": "absolute",
"right": 0,
"top": 0,
"zIndex": 0,
}
}
>
<View
style={
Object {
"backgroundColor": "#fff",
"borderBottomColor": "#a7a7aa",
"flex": 1,
"shadowColor": "#a7a7aa",
"shadowOffset": Object {
"height": 0.5,
"width": 0,
},
"shadowOpacity": 0.85,
"shadowRadius": 0,
}
}
/>
</View>
<View
pointerEvents="box-none"
style={
Object {
"height": 44,
"maxHeight": undefined,
"minHeight": undefined,
"opacity": undefined,
"transform": undefined,
}
}
>
<View
pointerEvents="none"
style={
Object {
"height": 0,
}
}
/>
<View
pointerEvents="box-none"
style={
Object {
"alignItems": "center",
"flex": 1,
"flexDirection": "row",
"justifyContent": "center",
}
}
>
<View
pointerEvents="box-none"
style={
Object {
"marginHorizontal": 16,
"opacity": 1,
}
}
>
<Text
accessibilityRole="header"
numberOfLines={1}
onLayout={[Function]}
style={
Object {
"color": "rgba(0, 0, 0, 0.9)",
"fontSize": 17,
"fontWeight": "600",
}
}
>
Sub
</Text>
</View>
</View>
</View>
</View>
</View>
<View <View
onLayout={[Function]} onLayout={[Function]}
style={ style={
@@ -80,7 +188,7 @@ exports[`Nested navigators renders succesfully as direct child 1`] = `
style={ style={
Object { Object {
"flex": 1, "flex": 1,
"marginTop": 44, "opacity": 1,
} }
} }
> >
@@ -240,7 +348,8 @@ exports[`Nested navigators renders succesfully as direct child 1`] = `
style={ style={
Object { Object {
"flex": 1, "flex": 1,
"marginTop": 44, "marginTop": 0,
"opacity": 1,
} }
} }
> >
@@ -332,110 +441,19 @@ exports[`Nested navigators renders succesfully as direct child 1`] = `
<View <View
pointerEvents="box-none" pointerEvents="box-none"
style={ style={
Object { Array [
"left": 0, Object {
"position": "absolute", "zIndex": 1,
"right": 0, },
"top": 0, Object {
} "left": 0,
"position": "absolute",
"right": 0,
"top": 0,
},
]
} }
> />
<View
accessibilityElementsHidden={false}
importantForAccessibility="auto"
onLayout={[Function]}
pointerEvents="box-none"
style={null}
>
<View
pointerEvents="none"
style={
Object {
"bottom": 0,
"left": 0,
"opacity": 1,
"position": "absolute",
"right": 0,
"top": 0,
}
}
>
<View
style={
Object {
"backgroundColor": "#fff",
"borderBottomColor": "#a7a7aa",
"flex": 1,
"shadowColor": "#a7a7aa",
"shadowOffset": Object {
"height": 0.5,
"width": 0,
},
"shadowOpacity": 0.85,
"shadowRadius": 0,
}
}
/>
</View>
<View
pointerEvents="box-none"
style={
Object {
"height": 44,
"maxHeight": undefined,
"minHeight": undefined,
"opacity": undefined,
"transform": undefined,
}
}
>
<View
pointerEvents="none"
style={
Object {
"height": 0,
}
}
/>
<View
pointerEvents="box-none"
style={
Object {
"alignItems": "center",
"flex": 1,
"flexDirection": "row",
"justifyContent": "center",
}
}
>
<View
pointerEvents="box-none"
style={
Object {
"marginHorizontal": 16,
"opacity": 1,
}
}
>
<Text
accessibilityRole="header"
numberOfLines={1}
onLayout={[Function]}
style={
Object {
"color": "rgba(0, 0, 0, 0.9)",
"fontSize": 17,
"fontWeight": "600",
}
}
>
Home
</Text>
</View>
</View>
</View>
</View>
</View>
</View> </View>
</View> </View>
</View> </View>
@@ -446,113 +464,6 @@ exports[`Nested navigators renders succesfully as direct child 1`] = `
</View> </View>
</View> </View>
</View> </View>
<View
pointerEvents="box-none"
style={
Object {
"left": 0,
"position": "absolute",
"right": 0,
"top": 0,
}
}
>
<View
accessibilityElementsHidden={false}
importantForAccessibility="auto"
onLayout={[Function]}
pointerEvents="box-none"
style={null}
>
<View
pointerEvents="none"
style={
Object {
"bottom": 0,
"left": 0,
"opacity": 1,
"position": "absolute",
"right": 0,
"top": 0,
}
}
>
<View
style={
Object {
"backgroundColor": "#fff",
"borderBottomColor": "#a7a7aa",
"flex": 1,
"shadowColor": "#a7a7aa",
"shadowOffset": Object {
"height": 0.5,
"width": 0,
},
"shadowOpacity": 0.85,
"shadowRadius": 0,
}
}
/>
</View>
<View
pointerEvents="box-none"
style={
Object {
"height": 44,
"maxHeight": undefined,
"minHeight": undefined,
"opacity": undefined,
"transform": undefined,
}
}
>
<View
pointerEvents="none"
style={
Object {
"height": 0,
}
}
/>
<View
pointerEvents="box-none"
style={
Object {
"alignItems": "center",
"flex": 1,
"flexDirection": "row",
"justifyContent": "center",
}
}
>
<View
pointerEvents="box-none"
style={
Object {
"marginHorizontal": 16,
"opacity": 1,
}
}
>
<Text
accessibilityRole="header"
numberOfLines={1}
onLayout={[Function]}
style={
Object {
"color": "rgba(0, 0, 0, 0.9)",
"fontSize": 17,
"fontWeight": "600",
}
}
>
Sub
</Text>
</View>
</View>
</View>
</View>
</View>
</View> </View>
`; `;

View File

@@ -8,176 +8,15 @@ exports[`StackNavigator applies correct values when headerRight is present 1`] =
} }
} }
> >
<View
onLayout={[Function]}
style={
Object {
"flex": 1,
}
}
>
<View
pointerEvents="box-none"
style={
Object {
"bottom": 0,
"left": 0,
"position": "absolute",
"right": 0,
"top": 0,
}
}
>
<View
accessibilityElementsHidden={false}
closing={false}
gestureVelocityImpact={0.3}
importantForAccessibility="auto"
onClose={[Function]}
onGestureBegin={[Function]}
onGestureCanceled={[Function]}
onOpen={[Function]}
onTransitionStart={[Function]}
pointerEvents="box-none"
style={
Object {
"bottom": 0,
"left": 0,
"position": "absolute",
"right": 0,
"top": 0,
}
}
transitionSpec={
Object {
"close": Object {
"animation": "spring",
"config": Object {
"damping": 500,
"mass": 3,
"overshootClamping": true,
"restDisplacementThreshold": 10,
"restSpeedThreshold": 10,
"stiffness": 1000,
},
},
"open": Object {
"animation": "spring",
"config": Object {
"damping": 500,
"mass": 3,
"overshootClamping": true,
"restDisplacementThreshold": 10,
"restSpeedThreshold": 10,
"stiffness": 1000,
},
},
}
}
>
<View
pointerEvents="box-none"
style={
Object {
"flex": 1,
"marginTop": 44,
}
}
>
<PanGestureHandler
enabled={false}
hitSlop={
Object {
"right": -700,
}
}
maxDeltaY={20}
minOffsetX={5}
onHandlerStateChange={[Function]}
>
<View
style={
Object {
"flex": 1,
"transform": Array [
Object {
"translateX": 0,
},
Object {
"translateX": 0,
},
],
}
}
>
<View
pointerEvents="none"
style={
Object {
"backgroundColor": "rgb(242, 242, 242)",
"bottom": 0,
"left": 0,
"position": "absolute",
"shadowColor": "#000",
"shadowOffset": Object {
"height": 1,
"width": -1,
},
"shadowOpacity": 0.3,
"shadowRadius": 5,
"top": 0,
"width": 3,
}
}
/>
<View
style={
Array [
Object {
"flex": 1,
"overflow": "hidden",
},
Array [
Object {
"backgroundColor": "rgb(242, 242, 242)",
},
undefined,
],
]
}
>
<View
style={
Object {
"flex": 1,
"flexDirection": "column-reverse",
}
}
>
<View
style={
Object {
"flex": 1,
}
}
/>
</View>
</View>
</View>
</PanGestureHandler>
</View>
</View>
</View>
</View>
<View <View
pointerEvents="box-none" pointerEvents="box-none"
style={ style={
Object { Array [
"left": 0, Object {
"position": "absolute", "zIndex": 1,
"right": 0, },
"top": 0, false,
} ]
} }
> >
<View <View
@@ -188,7 +27,7 @@ exports[`StackNavigator applies correct values when headerRight is present 1`] =
style={null} style={null}
> >
<View <View
pointerEvents="none" pointerEvents="box-none"
style={ style={
Object { Object {
"bottom": 0, "bottom": 0,
@@ -197,6 +36,7 @@ exports[`StackNavigator applies correct values when headerRight is present 1`] =
"position": "absolute", "position": "absolute",
"right": 0, "right": 0,
"top": 0, "top": 0,
"zIndex": 0,
} }
} }
> >
@@ -293,17 +133,6 @@ exports[`StackNavigator applies correct values when headerRight is present 1`] =
</View> </View>
</View> </View>
</View> </View>
</View>
`;
exports[`StackNavigator renders successfully 1`] = `
<View
style={
Object {
"flex": 1,
}
}
>
<View <View
onLayout={[Function]} onLayout={[Function]}
style={ style={
@@ -376,7 +205,7 @@ exports[`StackNavigator renders successfully 1`] = `
style={ style={
Object { Object {
"flex": 1, "flex": 1,
"marginTop": 44, "opacity": 1,
} }
} }
> >
@@ -465,15 +294,26 @@ exports[`StackNavigator renders successfully 1`] = `
</View> </View>
</View> </View>
</View> </View>
</View>
`;
exports[`StackNavigator renders successfully 1`] = `
<View
style={
Object {
"flex": 1,
}
}
>
<View <View
pointerEvents="box-none" pointerEvents="box-none"
style={ style={
Object { Array [
"left": 0, Object {
"position": "absolute", "zIndex": 1,
"right": 0, },
"top": 0, false,
} ]
} }
> >
<View <View
@@ -484,7 +324,7 @@ exports[`StackNavigator renders successfully 1`] = `
style={null} style={null}
> >
<View <View
pointerEvents="none" pointerEvents="box-none"
style={ style={
Object { Object {
"bottom": 0, "bottom": 0,
@@ -493,6 +333,7 @@ exports[`StackNavigator renders successfully 1`] = `
"position": "absolute", "position": "absolute",
"right": 0, "right": 0,
"top": 0, "top": 0,
"zIndex": 0,
} }
} }
> >
@@ -573,5 +414,166 @@ exports[`StackNavigator renders successfully 1`] = `
</View> </View>
</View> </View>
</View> </View>
<View
onLayout={[Function]}
style={
Object {
"flex": 1,
}
}
>
<View
pointerEvents="box-none"
style={
Object {
"bottom": 0,
"left": 0,
"position": "absolute",
"right": 0,
"top": 0,
}
}
>
<View
accessibilityElementsHidden={false}
closing={false}
gestureVelocityImpact={0.3}
importantForAccessibility="auto"
onClose={[Function]}
onGestureBegin={[Function]}
onGestureCanceled={[Function]}
onOpen={[Function]}
onTransitionStart={[Function]}
pointerEvents="box-none"
style={
Object {
"bottom": 0,
"left": 0,
"position": "absolute",
"right": 0,
"top": 0,
}
}
transitionSpec={
Object {
"close": Object {
"animation": "spring",
"config": Object {
"damping": 500,
"mass": 3,
"overshootClamping": true,
"restDisplacementThreshold": 10,
"restSpeedThreshold": 10,
"stiffness": 1000,
},
},
"open": Object {
"animation": "spring",
"config": Object {
"damping": 500,
"mass": 3,
"overshootClamping": true,
"restDisplacementThreshold": 10,
"restSpeedThreshold": 10,
"stiffness": 1000,
},
},
}
}
>
<View
pointerEvents="box-none"
style={
Object {
"flex": 1,
"opacity": 1,
}
}
>
<PanGestureHandler
enabled={false}
hitSlop={
Object {
"right": -700,
}
}
maxDeltaY={20}
minOffsetX={5}
onHandlerStateChange={[Function]}
>
<View
style={
Object {
"flex": 1,
"transform": Array [
Object {
"translateX": 0,
},
Object {
"translateX": 0,
},
],
}
}
>
<View
pointerEvents="none"
style={
Object {
"backgroundColor": "rgb(242, 242, 242)",
"bottom": 0,
"left": 0,
"position": "absolute",
"shadowColor": "#000",
"shadowOffset": Object {
"height": 1,
"width": -1,
},
"shadowOpacity": 0.3,
"shadowRadius": 5,
"top": 0,
"width": 3,
}
}
/>
<View
style={
Array [
Object {
"flex": 1,
"overflow": "hidden",
},
Array [
Object {
"backgroundColor": "rgb(242, 242, 242)",
},
undefined,
],
]
}
>
<View
style={
Object {
"flex": 1,
"flexDirection": "column-reverse",
}
}
>
<View
style={
Object {
"flex": 1,
}
}
/>
</View>
</View>
</View>
</PanGestureHandler>
</View>
</View>
</View>
</View>
</View> </View>
`; `;

View File

@@ -131,7 +131,7 @@ export type StackHeaderOptions = {
* This may lead to white space or overlap between `headerLeft` and `headerTitle` if a customized `headerLeft` is used. * This may lead to white space or overlap between `headerLeft` and `headerTitle` if a customized `headerLeft` is used.
* It can be solved by adjusting `left` and `right` style in `headerTitleContainerStyle` and `marginHorizontal` in `headerTitleStyle`. * It can be solved by adjusting `left` and `right` style in `headerTitleContainerStyle` and `marginHorizontal` in `headerTitleStyle`.
*/ */
headerTitleContainerStyle?: StyleProp<ViewStyle>; headerTitleContainerStyle?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
/** /**
* Tint color for the header. * Tint color for the header.
*/ */
@@ -145,7 +145,8 @@ export type StackHeaderOptions = {
*/ */
headerBackAllowFontScaling?: boolean; headerBackAllowFontScaling?: boolean;
/** /**
* Title string used by the back button on iOS, or `null` to disable label. Defaults to the previous scene's `headerTitle`. * Title string used by the back button on iOS. Defaults to the previous scene's `headerTitle`.
* Use `headerBackTitleVisible: false` to hide it.
*/ */
headerBackTitle?: string; headerBackTitle?: string;
/** /**
@@ -169,7 +170,7 @@ export type StackHeaderOptions = {
/** /**
* Style object for the container of the `headerLeft` component, for example to add padding. * Style object for the container of the `headerLeft` component, for example to add padding.
*/ */
headerLeftContainerStyle?: StyleProp<ViewStyle>; headerLeftContainerStyle?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
/** /**
* Function which returns a React Element to display on the right side of the header. * Function which returns a React Element to display on the right side of the header.
*/ */
@@ -177,7 +178,7 @@ export type StackHeaderOptions = {
/** /**
* Style object for the container of the `headerRight` component, for example to add padding. * Style object for the container of the `headerRight` component, for example to add padding.
*/ */
headerRightContainerStyle?: StyleProp<ViewStyle>; headerRightContainerStyle?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
/** /**
* Function which returns a React Element to display custom image in header's back button. * Function which returns a React Element to display custom image in header's back button.
* It receives the `tintColor` in in the options object as an argument. object. * It receives the `tintColor` in in the options object as an argument. object.
@@ -199,7 +200,7 @@ export type StackHeaderOptions = {
/** /**
* Style object for the header. You can specify a custom background color here, for example. * Style object for the header. You can specify a custom background color here, for example.
*/ */
headerStyle?: StyleProp<ViewStyle>; headerStyle?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
/** /**
* Defaults to `false`. If `true`, the header will not have a background unless you explicitly provide it with `headerBackground`. * Defaults to `false`. If `true`, the header will not have a background unless you explicitly provide it with `headerBackground`.
* The header will also float over the screen so that it overlaps the content underneath. * The header will also float over the screen so that it overlaps the content underneath.
@@ -397,7 +398,7 @@ export type StackHeaderLeftButtonProps = {
/** /**
* Style object for the label. * Style object for the label.
*/ */
labelStyle?: React.ComponentProps<typeof Animated.Text>['style']; labelStyle?: Animated.WithAnimatedValue<StyleProp<TextStyle>>;
/** /**
* Whether label font should scale to respect Text Size accessibility settings. * Whether label font should scale to respect Text Size accessibility settings.
*/ */

View File

@@ -0,0 +1,5 @@
import * as React from 'react';
const HeaderShownContext = React.createContext(false);
export default HeaderShownContext;

View File

@@ -10,7 +10,7 @@ export function PanGestureHandler(props: PanGestureHandlerProperties) {
return ( return (
<GestureHandlerRefContext.Provider value={gestureRef}> <GestureHandlerRefContext.Provider value={gestureRef}>
<PanGestureHandlerNative {...props} /> <PanGestureHandlerNative {...props} ref={gestureRef} />
</GestureHandlerRefContext.Provider> </GestureHandlerRefContext.Provider>
); );
} }

View File

@@ -1,8 +1,16 @@
import * as React from 'react'; import * as React from 'react';
import { Animated, StyleSheet, Platform, ViewProps } from 'react-native'; import {
Animated,
StyleSheet,
Platform,
ViewProps,
StyleProp,
ViewStyle,
} from 'react-native';
import useTheme from '../../../utils/useTheme'; import useTheme from '../../../utils/useTheme';
type Props = ViewProps & { type Props = ViewProps & {
style?: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
children?: React.ReactNode; children?: React.ReactNode;
}; };

View File

@@ -10,6 +10,7 @@ import {
forNoAnimation, forNoAnimation,
forSlideRight, forSlideRight,
} from '../../TransitionConfigs/HeaderStyleInterpolators'; } from '../../TransitionConfigs/HeaderStyleInterpolators';
import HeaderShownContext from '../../utils/HeaderShownContext';
import { import {
Route, Route,
Layout, Layout,
@@ -50,6 +51,7 @@ export default function HeaderContainer({
style, style,
}: Props) { }: Props) {
const focusedRoute = getFocusedRoute(); const focusedRoute = getFocusedRoute();
const isParentHeaderShown = React.useContext(HeaderShownContext);
return ( return (
<View pointerEvents="box-none" style={style}> <View pointerEvents="box-none" style={style}>
@@ -58,7 +60,16 @@ export default function HeaderContainer({
return null; return null;
} }
const { options } = scene.descriptor; const {
header,
headerShown = isParentHeaderShown === false,
headerTransparent,
} = scene.descriptor.options || {};
if (!headerShown) {
return null;
}
const isFocused = focusedRoute.key === scene.route.key; const isFocused = focusedRoute.key === scene.route.key;
const previousRoute = getPreviousRoute({ route: scene.route }); const previousRoute = getPreviousRoute({ route: scene.route });
@@ -81,13 +92,20 @@ export default function HeaderContainer({
// This makes the header look like it's moving with the screen // This makes the header look like it's moving with the screen
const previousScene = self[i - 1]; const previousScene = self[i - 1];
const nextScene = self[i + 1]; const nextScene = self[i + 1];
const {
headerShown: previousHeaderShown = isParentHeaderShown === false,
} = previousScene?.descriptor.options || {};
const { headerShown: nextHeaderShown = isParentHeaderShown === false } =
nextScene?.descriptor.options || {};
const isHeaderStatic = const isHeaderStatic =
(previousScene && (previousHeaderShown === false &&
previousScene.descriptor.options.headerShown === false &&
// We still need to animate when coming back from next scene // We still need to animate when coming back from next scene
// A hacky way to check this is if the next scene exists // A hacky way to check this is if the next scene exists
!nextScene) || !nextScene) ||
(nextScene && nextScene.descriptor.options.headerShown === false); nextHeaderShown === false;
const props = { const props = {
mode, mode,
@@ -133,18 +151,12 @@ export default function HeaderContainer({
style={ style={
// Avoid positioning the focused header absolutely // Avoid positioning the focused header absolutely
// Otherwise accessibility tools don't seem to be able to find it // Otherwise accessibility tools don't seem to be able to find it
(mode === 'float' && !isFocused) || options.headerTransparent (mode === 'float' && !isFocused) || headerTransparent
? styles.header ? styles.header
: null : null
} }
> >
{options.headerShown !== false ? ( {header !== undefined ? header(props) : <Header {...props} />}
options.header !== undefined ? (
options.header(props)
) : (
<Header {...props} />
)
) : null}
</View> </View>
</> </>
</NavigationContext.Provider> </NavigationContext.Provider>

View File

@@ -312,8 +312,8 @@ export default class HeaderSegment extends React.Component<Props, State> {
return ( return (
<React.Fragment> <React.Fragment>
<Animated.View <Animated.View
pointerEvents="none" pointerEvents="box-none"
style={[StyleSheet.absoluteFill, backgroundStyle]} style={[StyleSheet.absoluteFill, { zIndex: 0 }, backgroundStyle]}
> >
{headerBackground ? ( {headerBackground ? (
headerBackground({ style: safeStyles }) headerBackground({ style: safeStyles })
@@ -355,7 +355,9 @@ export default class HeaderSegment extends React.Component<Props, State> {
: { : {
marginHorizontal: marginHorizontal:
(leftButton ? 32 : 16) + (leftButton ? 32 : 16) +
(leftLabelLayout?.width || 0) + (leftButton && headerBackTitleVisible !== false
? 40
: 0) +
Math.max(insets.left, insets.right), Math.max(insets.left, insets.right),
}, },
titleStyle, titleStyle,

View File

@@ -46,7 +46,9 @@ type Props = ViewProps & {
onGestureCanceled?: () => void; onGestureCanceled?: () => void;
onGestureEnd?: () => void; onGestureEnd?: () => void;
children: React.ReactNode; children: React.ReactNode;
overlay: (props: { style: StyleProp<ViewStyle> }) => React.ReactNode; overlay: (props: {
style: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
}) => React.ReactNode;
overlayEnabled: boolean; overlayEnabled: boolean;
shadowEnabled: boolean; shadowEnabled: boolean;
gestureEnabled: boolean; gestureEnabled: boolean;
@@ -83,7 +85,11 @@ export default class Card extends React.Component<Props> {
shadowEnabled: true, shadowEnabled: true,
gestureEnabled: true, gestureEnabled: true,
gestureVelocityImpact: GESTURE_VELOCITY_IMPACT, gestureVelocityImpact: GESTURE_VELOCITY_IMPACT,
overlay: ({ style }: { style: StyleProp<ViewStyle> }) => overlay: ({
style,
}: {
style: Animated.WithAnimatedValue<StyleProp<ViewStyle>>;
}) =>
style ? ( style ? (
<Animated.View pointerEvents="none" style={[styles.overlay, style]} /> <Animated.View pointerEvents="none" style={[styles.overlay, style]} />
) : null, ) : null,
@@ -487,6 +493,12 @@ export default class Card extends React.Component<Props> {
? Color(backgroundColor).alpha() === 0 ? Color(backgroundColor).alpha() === 0
: false; : false;
// This is a dummy style that doesn't actually change anything visually.
// Animated needs the animated value to be used somewhere, otherwise things don't update properly.
// If we disable animations and hide header, it could end up making the value unused.
// So we have this dummy style that will always be used regardless of what else changed.
const dummyStyle = { opacity: Animated.diffClamp(current, 1, 1) };
return ( return (
<CardAnimationContext.Provider value={animationContext}> <CardAnimationContext.Provider value={animationContext}>
<View pointerEvents="box-none" {...rest}> <View pointerEvents="box-none" {...rest}>
@@ -496,7 +508,12 @@ export default class Card extends React.Component<Props> {
</View> </View>
) : null} ) : null}
<Animated.View <Animated.View
style={[styles.container, containerStyle, customContainerStyle]} style={[
styles.container,
dummyStyle,
containerStyle,
customContainerStyle,
]}
pointerEvents="box-none" pointerEvents="box-none"
> >
<PanGestureHandler <PanGestureHandler

View File

@@ -3,6 +3,7 @@ import { Animated, View, StyleSheet, StyleProp, ViewStyle } from 'react-native';
import { Props as HeaderContainerProps } from '../Header/HeaderContainer'; import { Props as HeaderContainerProps } from '../Header/HeaderContainer';
import Card from './Card'; import Card from './Card';
import HeaderHeightContext from '../../utils/HeaderHeightContext'; import HeaderHeightContext from '../../utils/HeaderHeightContext';
import HeaderShownContext from '../../utils/HeaderShownContext';
import useTheme from '../../../utils/useTheme'; import useTheme from '../../../utils/useTheme';
import { import {
Route, Route,
@@ -54,8 +55,8 @@ type Props = TransitionPreset & {
gestureVelocityImpact?: number; gestureVelocityImpact?: number;
mode: StackCardMode; mode: StackCardMode;
headerMode: StackHeaderMode; headerMode: StackHeaderMode;
headerShown?: boolean; headerShown: boolean;
headerTransparent?: boolean; hasAbsoluteHeader: boolean;
headerHeight: number; headerHeight: number;
onHeaderHeightChange: (props: { onHeaderHeightChange: (props: {
route: Route<string>; route: Route<string>;
@@ -85,7 +86,7 @@ function CardContainer({
headerMode, headerMode,
headerShown, headerShown,
headerStyleInterpolator, headerStyleInterpolator,
headerTransparent, hasAbsoluteHeader,
headerHeight, headerHeight,
onHeaderHeightChange, onHeaderHeightChange,
index, index,
@@ -161,6 +162,9 @@ function CardContainer({
}; };
}, [pointerEvents, scene.progress.next]); }, [pointerEvents, scene.progress.next]);
const isParentHeaderShown = React.useContext(HeaderShownContext);
const isCurrentHeaderShown = headerMode !== 'none' && headerShown !== false;
return ( return (
<Card <Card
index={index} index={index}
@@ -188,19 +192,19 @@ function CardContainer({
importantForAccessibility={focused ? 'auto' : 'no-hide-descendants'} importantForAccessibility={focused ? 'auto' : 'no-hide-descendants'}
pointerEvents={active ? 'box-none' : pointerEvents} pointerEvents={active ? 'box-none' : pointerEvents}
pageOverflowEnabled={headerMode === 'screen' && mode === 'card'} pageOverflowEnabled={headerMode === 'screen' && mode === 'card'}
containerStyle={ containerStyle={hasAbsoluteHeader ? { marginTop: headerHeight } : null}
headerMode === 'float' && !headerTransparent && headerShown !== false contentStyle={[{ backgroundColor: colors.background }, cardStyle]}
? { marginTop: headerHeight }
: null
}
contentStyle={[{ backgroundColor: colors.background }, cardStyle] as any}
style={StyleSheet.absoluteFill} style={StyleSheet.absoluteFill}
> >
<View style={styles.container}> <View style={styles.container}>
<View style={styles.scene}> <View style={styles.scene}>
<HeaderHeightContext.Provider value={headerHeight}> <HeaderShownContext.Provider
{renderScene({ route: scene.route })} value={isParentHeaderShown || isCurrentHeaderShown}
</HeaderHeightContext.Provider> >
<HeaderHeightContext.Provider value={headerHeight}>
{renderScene({ route: scene.route })}
</HeaderHeightContext.Provider>
</HeaderShownContext.Provider>
</View> </View>
{headerMode === 'screen' {headerMode === 'screen'
? renderHeader({ ? renderHeader({

View File

@@ -19,6 +19,7 @@ import {
} from '../../TransitionConfigs/TransitionPresets'; } from '../../TransitionConfigs/TransitionPresets';
import { forNoAnimation as forNoAnimationHeader } from '../../TransitionConfigs/HeaderStyleInterpolators'; import { forNoAnimation as forNoAnimationHeader } from '../../TransitionConfigs/HeaderStyleInterpolators';
import { forNoAnimation as forNoAnimationCard } from '../../TransitionConfigs/CardStyleInterpolators'; import { forNoAnimation as forNoAnimationCard } from '../../TransitionConfigs/CardStyleInterpolators';
import HeaderShownContext from '../../utils/HeaderShownContext';
import getDistanceForDirection from '../../utils/getDistanceForDirection'; import getDistanceForDirection from '../../utils/getDistanceForDirection';
import { import {
Route, Route,
@@ -84,9 +85,10 @@ const getHeaderHeights = (
) => { ) => {
return routes.reduce<Record<string, number>>((acc, curr) => { return routes.reduce<Record<string, number>>((acc, curr) => {
const { options = {} } = descriptors[curr.key] || {}; const { options = {} } = descriptors[curr.key] || {};
const { height = previous[curr.key] } = StyleSheet.flatten( const style: any = StyleSheet.flatten(options.headerStyle || {});
options.headerStyle || {}
); const height =
typeof style.height === 'number' ? style.height : previous[curr.key];
const safeAreaInsets = { const safeAreaInsets = {
...insets, ...insets,
@@ -300,7 +302,7 @@ export default class CardStack extends React.Component<Props, State> {
props.insets, props.insets,
state.descriptors, state.descriptors,
layout, layout,
{} state.headerHeights
), ),
}; };
}); });
@@ -385,180 +387,224 @@ export default class CardStack extends React.Component<Props, State> {
const isScreensEnabled = Platform.OS !== 'ios' && mode !== 'modal'; const isScreensEnabled = Platform.OS !== 'ios' && mode !== 'modal';
return ( return (
<React.Fragment> <HeaderShownContext.Consumer>
<MaybeScreenContainer {(isParentHeaderShown) => {
enabled={isScreensEnabled} const isFloatHeaderAbsolute =
style={styles.container} headerMode === 'float'
onLayout={this.handleLayout} ? this.state.scenes.slice(-2).some((scene) => {
> const { descriptor } = scene;
{routes.map((route, index, self) => { const options = descriptor ? descriptor.options : {};
const focused = focusedRoute.key === route.key; const {
const gesture = gestures[route.key]; headerTransparent,
const scene = scenes[index]; headerShown = isParentHeaderShown === false,
} = options;
const isScreenActive = scene.progress.next if (headerTransparent || headerShown === false) {
? scene.progress.next.interpolate({ return true;
inputRange: [0, 1 - EPSILON, 1], }
outputRange: [1, 1, 0],
extrapolate: 'clamp', return false;
}) })
: 1; : false;
const { const floatingHeader =
safeAreaInsets, headerMode === 'float' ? (
headerShown, <React.Fragment key="header">
headerTransparent, {renderHeader({
cardShadowEnabled, mode: 'float',
cardOverlayEnabled, layout,
cardOverlay, insets: { top, right, bottom, left },
cardStyle, scenes,
animationEnabled, getPreviousRoute,
gestureResponseDistance, getFocusedRoute: this.getFocusedRoute,
gestureVelocityImpact, onContentHeightChange: this.handleHeaderLayout,
gestureDirection = defaultTransitionPreset.gestureDirection, gestureDirection:
transitionSpec = defaultTransitionPreset.transitionSpec, focusedOptions.gestureDirection !== undefined
cardStyleInterpolator = animationEnabled === false ? focusedOptions.gestureDirection
? forNoAnimationCard : defaultTransitionPreset.gestureDirection,
: defaultTransitionPreset.cardStyleInterpolator, styleInterpolator:
headerStyleInterpolator = defaultTransitionPreset.headerStyleInterpolator, focusedOptions.headerStyleInterpolator !== undefined
} = scene.descriptor ? focusedOptions.headerStyleInterpolator
? scene.descriptor.options : defaultTransitionPreset.headerStyleInterpolator,
: ({} as StackNavigationOptions); style: [
styles.floating,
isFloatHeaderAbsolute && styles.absolute,
],
})}
</React.Fragment>
) : null;
let transitionConfig = { return (
gestureDirection, <React.Fragment>
transitionSpec, {isFloatHeaderAbsolute ? null : floatingHeader}
cardStyleInterpolator, <MaybeScreenContainer
headerStyleInterpolator,
};
// When a screen is not the last, it should use next screen's transition config
// Many transitions also animate the previous screen, so using 2 different transitions doesn't look right
// For example combining a slide and a modal transition would look wrong otherwise
// With this approach, combining different transition styles in the same navigator mostly looks right
// This will still be broken when 2 transitions have different idle state (e.g. modal presentation),
// but majority of the transitions look alright
if (index !== self.length - 1) {
const nextScene = scenes[index + 1];
if (nextScene) {
const {
animationEnabled,
gestureDirection = defaultTransitionPreset.gestureDirection,
transitionSpec = defaultTransitionPreset.transitionSpec,
cardStyleInterpolator = animationEnabled === false
? forNoAnimationCard
: defaultTransitionPreset.cardStyleInterpolator,
headerStyleInterpolator = defaultTransitionPreset.headerStyleInterpolator,
} = nextScene.descriptor
? nextScene.descriptor.options
: ({} as StackNavigationOptions);
transitionConfig = {
gestureDirection,
transitionSpec,
cardStyleInterpolator,
headerStyleInterpolator,
};
}
}
const {
top: safeAreaInsetTop = insets.top,
right: safeAreaInsetRight = insets.right,
bottom: safeAreaInsetBottom = insets.bottom,
left: safeAreaInsetLeft = insets.left,
} = safeAreaInsets || {};
const previousRoute = getPreviousRoute({ route: scene.route });
let previousScene = scenes[index - 1];
if (previousRoute) {
// The previous scene will be shortly before the current scene in the array
// So loop back from current index to avoid looping over the full array
for (let j = index - 1; j >= 0; j--) {
const s = scenes[j];
if (s && s.route.key === previousRoute.key) {
previousScene = s;
break;
}
}
}
return (
<MaybeScreen
key={route.key}
style={StyleSheet.absoluteFill}
enabled={isScreensEnabled} enabled={isScreensEnabled}
active={isScreenActive} style={styles.container}
pointerEvents="box-none" onLayout={this.handleLayout}
> >
<CardContainer {routes.map((route, index, self) => {
index={index} const focused = focusedRoute.key === route.key;
active={index === self.length - 1} const gesture = gestures[route.key];
focused={focused} const scene = scenes[index];
closing={closingRouteKeys.includes(route.key)}
layout={layout} const isScreenActive = scene.progress.next
gesture={gesture} ? scene.progress.next.interpolate({
scene={scene} inputRange: [0, 1 - EPSILON, 1],
previousScene={previousScene} outputRange: [1, 1, 0],
safeAreaInsetTop={safeAreaInsetTop} extrapolate: 'clamp',
safeAreaInsetRight={safeAreaInsetRight} })
safeAreaInsetBottom={safeAreaInsetBottom} : 1;
safeAreaInsetLeft={safeAreaInsetLeft}
cardOverlay={cardOverlay} const {
cardOverlayEnabled={cardOverlayEnabled} safeAreaInsets,
cardShadowEnabled={cardShadowEnabled} headerShown = isParentHeaderShown === false,
cardStyle={cardStyle} headerTransparent,
onPageChangeStart={onPageChangeStart} cardShadowEnabled,
onPageChangeConfirm={onPageChangeConfirm} cardOverlayEnabled,
onPageChangeCancel={onPageChangeCancel} cardOverlay,
gestureResponseDistance={gestureResponseDistance} cardStyle,
headerHeight={headerHeights[route.key]} animationEnabled,
onHeaderHeightChange={this.handleHeaderLayout} gestureResponseDistance,
getPreviousRoute={getPreviousRoute} gestureVelocityImpact,
getFocusedRoute={this.getFocusedRoute} gestureDirection = defaultTransitionPreset.gestureDirection,
mode={mode} transitionSpec = defaultTransitionPreset.transitionSpec,
headerMode={headerMode} cardStyleInterpolator = animationEnabled === false
headerShown={headerShown} ? forNoAnimationCard
headerTransparent={headerTransparent} : defaultTransitionPreset.cardStyleInterpolator,
renderHeader={renderHeader} headerStyleInterpolator = defaultTransitionPreset.headerStyleInterpolator,
renderScene={renderScene} } = scene.descriptor
onOpenRoute={onOpenRoute} ? scene.descriptor.options
onCloseRoute={onCloseRoute} : ({} as StackNavigationOptions);
onTransitionStart={onTransitionStart}
onTransitionEnd={onTransitionEnd} let transitionConfig = {
gestureEnabled={index !== 0 && getGesturesEnabled({ route })} gestureDirection,
gestureVelocityImpact={gestureVelocityImpact} transitionSpec,
{...transitionConfig} cardStyleInterpolator,
/> headerStyleInterpolator,
</MaybeScreen> };
);
})} // When a screen is not the last, it should use next screen's transition config
</MaybeScreenContainer> // Many transitions also animate the previous screen, so using 2 different transitions doesn't look right
{headerMode === 'float' // For example combining a slide and a modal transition would look wrong otherwise
? renderHeader({ // With this approach, combining different transition styles in the same navigator mostly looks right
mode: 'float', // This will still be broken when 2 transitions have different idle state (e.g. modal presentation),
layout, // but majority of the transitions look alright
insets: { top, right, bottom, left }, if (index !== self.length - 1) {
scenes, const nextScene = scenes[index + 1];
getPreviousRoute,
getFocusedRoute: this.getFocusedRoute, if (nextScene) {
onContentHeightChange: this.handleHeaderLayout, const {
gestureDirection: animationEnabled,
focusedOptions.gestureDirection !== undefined gestureDirection = defaultTransitionPreset.gestureDirection,
? focusedOptions.gestureDirection transitionSpec = defaultTransitionPreset.transitionSpec,
: defaultTransitionPreset.gestureDirection, cardStyleInterpolator = animationEnabled === false
styleInterpolator: ? forNoAnimationCard
focusedOptions.headerStyleInterpolator !== undefined : defaultTransitionPreset.cardStyleInterpolator,
? focusedOptions.headerStyleInterpolator headerStyleInterpolator = defaultTransitionPreset.headerStyleInterpolator,
: defaultTransitionPreset.headerStyleInterpolator, } = nextScene.descriptor
style: styles.floating, ? nextScene.descriptor.options
}) : ({} as StackNavigationOptions);
: null}
</React.Fragment> transitionConfig = {
gestureDirection,
transitionSpec,
cardStyleInterpolator,
headerStyleInterpolator,
};
}
}
const {
top: safeAreaInsetTop = insets.top,
right: safeAreaInsetRight = insets.right,
bottom: safeAreaInsetBottom = insets.bottom,
left: safeAreaInsetLeft = insets.left,
} = safeAreaInsets || {};
const previousRoute = getPreviousRoute({
route: scene.route,
});
let previousScene = scenes[index - 1];
if (previousRoute) {
// The previous scene will be shortly before the current scene in the array
// So loop back from current index to avoid looping over the full array
for (let j = index - 1; j >= 0; j--) {
const s = scenes[j];
if (s && s.route.key === previousRoute.key) {
previousScene = s;
break;
}
}
}
const headerHeight =
headerMode !== 'none' && headerShown !== false
? headerHeights[route.key]
: 0;
return (
<MaybeScreen
key={route.key}
style={StyleSheet.absoluteFill}
enabled={isScreensEnabled}
active={isScreenActive}
pointerEvents="box-none"
>
<CardContainer
index={index}
active={index === self.length - 1}
focused={focused}
closing={closingRouteKeys.includes(route.key)}
layout={layout}
gesture={gesture}
scene={scene}
previousScene={previousScene}
safeAreaInsetTop={safeAreaInsetTop}
safeAreaInsetRight={safeAreaInsetRight}
safeAreaInsetBottom={safeAreaInsetBottom}
safeAreaInsetLeft={safeAreaInsetLeft}
cardOverlay={cardOverlay}
cardOverlayEnabled={cardOverlayEnabled}
cardShadowEnabled={cardShadowEnabled}
cardStyle={cardStyle}
onPageChangeStart={onPageChangeStart}
onPageChangeConfirm={onPageChangeConfirm}
onPageChangeCancel={onPageChangeCancel}
gestureResponseDistance={gestureResponseDistance}
headerHeight={headerHeight}
onHeaderHeightChange={this.handleHeaderLayout}
getPreviousRoute={getPreviousRoute}
getFocusedRoute={this.getFocusedRoute}
mode={mode}
headerMode={headerMode}
headerShown={headerShown}
hasAbsoluteHeader={
isFloatHeaderAbsolute && !headerTransparent
}
renderHeader={renderHeader}
renderScene={renderScene}
onOpenRoute={onOpenRoute}
onCloseRoute={onCloseRoute}
onTransitionStart={onTransitionStart}
onTransitionEnd={onTransitionEnd}
gestureEnabled={
index !== 0 && getGesturesEnabled({ route })
}
gestureVelocityImpact={gestureVelocityImpact}
{...transitionConfig}
/>
</MaybeScreen>
);
})}
</MaybeScreenContainer>
{isFloatHeaderAbsolute ? floatingHeader : null}
</React.Fragment>
);
}}
</HeaderShownContext.Consumer>
); );
} }
} }
@@ -567,10 +613,13 @@ const styles = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
}, },
floating: { absolute: {
position: 'absolute', position: 'absolute',
top: 0, top: 0,
left: 0, left: 0,
right: 0, right: 0,
}, },
floating: {
zIndex: 1,
},
}); });

View File

@@ -356,14 +356,16 @@ export default class StackView extends React.Component<Props, State> {
private handleOpenRoute = ({ route }: { route: Route<string> }) => { private handleOpenRoute = ({ route }: { route: Route<string> }) => {
const { state, navigation } = this.props; const { state, navigation } = this.props;
const { closingRouteKeys, replacingRouteKeys } = this.state;
this.handleTransitionComplete(); this.handleTransitionComplete();
if ( if (
this.state.replacingRouteKeys.every((key) => key !== route.key) && closingRouteKeys.some((key) => key === route.key) &&
replacingRouteKeys.every((key) => key !== route.key) &&
!state.routes.some((r) => r.key === route.key) !state.routes.some((r) => r.key === route.key)
) { ) {
// If route isn't present in current state, assume that a close animation was cancelled // If route isn't present in current state, but was closing, assume that a close animation was cancelled
// So we need to add this route back to the state // So we need to add this route back to the state
navigation.dispatch(NavigationActions.navigate(route)); navigation.dispatch(NavigationActions.navigate(route));
} else { } else {
@@ -438,6 +440,9 @@ export default class StackView extends React.Component<Props, State> {
navigation, navigation,
keyboardHandlingEnabled, keyboardHandlingEnabled,
mode = 'card', mode = 'card',
headerMode = mode === 'card' && Platform.OS === 'ios'
? 'float'
: 'screen',
...rest ...rest
} = this.props; } = this.props;
@@ -448,9 +453,6 @@ export default class StackView extends React.Component<Props, State> {
closingRouteKeys, closingRouteKeys,
} = this.state; } = this.state;
const headerMode =
mode === 'card' && Platform.OS === 'ios' ? 'float' : 'screen';
return ( return (
<> <>
<GestureHandlerWrapper style={styles.container}> <GestureHandlerWrapper style={styles.container}>

View File

@@ -3202,10 +3202,10 @@
resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.7.tgz#a65ce0702f55cb67fd777995de6fc7b3e5781903" resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.7.tgz#a65ce0702f55cb67fd777995de6fc7b3e5781903"
integrity sha512-9KbP7LTLFz9dx1heURJbO6nuVMdSjDez8znlrUzaB1nUwKVsTTwlKRuHxGUYIIkReLWrJQeCv9tidy+84z2eCw== integrity sha512-9KbP7LTLFz9dx1heURJbO6nuVMdSjDez8znlrUzaB1nUwKVsTTwlKRuHxGUYIIkReLWrJQeCv9tidy+84z2eCw==
"@react-navigation/stack@^5.3.3": "@react-navigation/stack@^5.5.1":
version "5.3.3" version "5.5.1"
resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-5.3.3.tgz#8189160ad4be6a9ddc8a01af100ad5b737e0c2e1" resolved "https://registry.yarnpkg.com/@react-navigation/stack/-/stack-5.5.1.tgz#95efa28edbfd1323e5ad9f01f539d43ffad8decc"
integrity sha512-UZqplwGnu1X3sSWTIERUG1NMK2cr6ER7ibYVMKNMY5a06t/hq4o2vgAG2ZNXKcNpgl0K2DR08EFhgeJLcP0mgg== integrity sha512-oU2FEm+Ba6jMd5VA2WnuNfCO2HlZmGhrEX9yjBCyFj7fFCG1SB7WJdKLhZShtx3KxG/qWKphICeTLlYvkHdSpQ==
dependencies: dependencies:
color "^3.1.2" color "^3.1.2"
react-native-iphone-x-helper "^1.2.1" react-native-iphone-x-helper "^1.2.1"