mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-01-18 18:08:17 +08:00
Compare commits
73 Commits
react-navi
...
react-navi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10c6c3280f | ||
|
|
e5856dae79 | ||
|
|
db24639445 | ||
|
|
f10543f9fc | ||
|
|
a3e3fa2cfd | ||
|
|
ec25edd658 | ||
|
|
09d4bc24e9 | ||
|
|
8d0e0f48ad | ||
|
|
8411e6f764 | ||
|
|
dff6c3ee7c | ||
|
|
ffe3bddcb2 | ||
|
|
9b55493e76 | ||
|
|
ebe70f51fb | ||
|
|
256e5aec2a | ||
|
|
707bea3cba | ||
|
|
6bdc1e9e5f | ||
|
|
b3db099a00 | ||
|
|
1f5000e86b | ||
|
|
6390aacd07 | ||
|
|
20e2625f35 | ||
|
|
162e225fa4 | ||
|
|
ce9991ffff | ||
|
|
3bb21e256f | ||
|
|
f1a06e2f92 | ||
|
|
c0763fca16 | ||
|
|
62da341b67 | ||
|
|
09a10faa44 | ||
|
|
b9ecbd222d | ||
|
|
a57e47786c | ||
|
|
424923019a | ||
|
|
06a69f1bfd | ||
|
|
1fa2edd9f2 | ||
|
|
fcd7d83c4c | ||
|
|
4f7983134b | ||
|
|
46b797dd29 | ||
|
|
1a6f4a581f | ||
|
|
2e7f4a6d10 | ||
|
|
6515fbe2dc | ||
|
|
454e05b02e | ||
|
|
442ca3e700 | ||
|
|
e00c63e32b | ||
|
|
ba6d7dcbed | ||
|
|
2ca8c34b2d | ||
|
|
03f9f8cd8e | ||
|
|
1ee8c76df3 | ||
|
|
bc1313b61d | ||
|
|
28982ffca0 | ||
|
|
bb82d5000f | ||
|
|
1f30227049 | ||
|
|
f34ec46111 | ||
|
|
8b79e9bee6 | ||
|
|
e09906a423 | ||
|
|
ed7ffb98f4 | ||
|
|
90eff6a5e2 | ||
|
|
b4691d7de2 | ||
|
|
f99f523a37 | ||
|
|
05b47dbb09 | ||
|
|
4c4e66f05c | ||
|
|
720d1f970d | ||
|
|
66a4dbccd8 | ||
|
|
7925f0c8a3 | ||
|
|
b3d77b79b7 | ||
|
|
1d527ce16a | ||
|
|
3bec1c964a | ||
|
|
a7e0c193cd | ||
|
|
ac98c0a668 | ||
|
|
14a6538cc8 | ||
|
|
c9313a1419 | ||
|
|
ec39721a74 | ||
|
|
a54d48b650 | ||
|
|
8a9a9cd7d1 | ||
|
|
cd08338186 | ||
|
|
d2433f0ab8 |
@@ -14,5 +14,8 @@
|
|||||||
"react-native-screens"
|
"react-native-screens"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"env": { "browser": true, "node": true }
|
"env": { "browser": true, "node": true },
|
||||||
|
"rules": {
|
||||||
|
"import/named": "off"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { registerRootComponent } from 'expo';
|
import { registerRootComponent } from 'expo';
|
||||||
import {
|
import {
|
||||||
Animated,
|
Animated,
|
||||||
@@ -41,7 +41,7 @@ import StackWithTranslucentHeader from './src/StackWithTranslucentHeader';
|
|||||||
import SwitchWithStacks from './src/SwitchWithStacks';
|
import SwitchWithStacks from './src/SwitchWithStacks';
|
||||||
import TabsInDrawer from './src/TabsInDrawer';
|
import TabsInDrawer from './src/TabsInDrawer';
|
||||||
import DragLimitedToModal from './src/DragLimitedToModal';
|
import DragLimitedToModal from './src/DragLimitedToModal';
|
||||||
import EventsStack from './src/EventsStack';
|
import FocusEvents from './src/FocusEvents';
|
||||||
import FullScreen from './src/FullScreen';
|
import FullScreen from './src/FullScreen';
|
||||||
import GestureInteraction from './src/GestureInteraction';
|
import GestureInteraction from './src/GestureInteraction';
|
||||||
import {
|
import {
|
||||||
@@ -144,7 +144,7 @@ const ExampleInfo = {
|
|||||||
name: 'Drag limited to modal',
|
name: 'Drag limited to modal',
|
||||||
screen: DragLimitedToModal,
|
screen: DragLimitedToModal,
|
||||||
},
|
},
|
||||||
EventsStack: { name: 'Events Stack', screen: EventsStack },
|
EventsStack: { name: 'Focus Events', screen: FocusEvents },
|
||||||
FullScreen: { name: 'Fullscreen Stack', screen: FullScreen },
|
FullScreen: { name: 'Fullscreen Stack', screen: FullScreen },
|
||||||
GestureInteraction: {
|
GestureInteraction: {
|
||||||
name: 'Gesture interaction',
|
name: 'Gesture interaction',
|
||||||
@@ -346,6 +346,7 @@ class MainScreen extends React.Component<any, State> {
|
|||||||
if (route.screen || route.path || route.params) {
|
if (route.screen || route.path || route.params) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const { path, params, screen } = route;
|
const { path, params, screen } = route;
|
||||||
|
// @ts-ignore
|
||||||
const { router } = screen;
|
const { router } = screen;
|
||||||
const action =
|
const action =
|
||||||
path &&
|
path &&
|
||||||
@@ -386,6 +387,7 @@ class MainScreen extends React.Component<any, State> {
|
|||||||
|
|
||||||
const Navigation = createAppContainer(
|
const Navigation = createAppContainer(
|
||||||
createStackNavigator(
|
createStackNavigator(
|
||||||
|
// @ts-ignore
|
||||||
{
|
{
|
||||||
...ExampleInfo,
|
...ExampleInfo,
|
||||||
Index: {
|
Index: {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
"slug": "react-navigation-4-example",
|
"slug": "react-navigation-4-example",
|
||||||
"description": "Demo app to showcase various functionality of React Navigation",
|
"description": "Demo app to showcase various functionality of React Navigation",
|
||||||
"privacy": "public",
|
"privacy": "public",
|
||||||
"sdkVersion": "36.0.0",
|
|
||||||
"platforms": [
|
"platforms": [
|
||||||
"ios",
|
"ios",
|
||||||
"android",
|
"android",
|
||||||
|
|||||||
@@ -8,29 +8,29 @@
|
|||||||
"ios": "expo start --ios"
|
"ios": "expo start --ios"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.8.7",
|
"@babel/runtime": "^7.12.1",
|
||||||
"@expo/vector-icons": "^10.0.6",
|
"@expo/vector-icons": "^10.0.0",
|
||||||
"@react-native-community/masked-view": "0.1.7",
|
"@react-native-community/masked-view": "0.1.10",
|
||||||
"expo": "^36.0.0",
|
"expo": "^39.0.0",
|
||||||
"expo-asset": "~8.0.0",
|
"expo-asset": "~8.2.0",
|
||||||
"expo-barcode-scanner": "^8.0.0",
|
"expo-barcode-scanner": "~9.0.0",
|
||||||
"expo-blur": "~8.0.0",
|
"expo-blur": "~8.2.0",
|
||||||
"expo-constants": "~8.0.0",
|
"expo-constants": "~9.2.0",
|
||||||
"hoist-non-react-statics": "^3.3.1",
|
"hoist-non-react-statics": "^3.3.1",
|
||||||
"react": "16.9.0",
|
"react": "~16.13.1",
|
||||||
"react-native": "https://github.com/expo/react-native/archive/sdk-36.0.1.tar.gz",
|
"react-native": "~0.63.2",
|
||||||
"react-native-gesture-handler": "~1.6.0",
|
"react-native-gesture-handler": "~1.7.0",
|
||||||
"react-native-iphone-x-helper": "^1.2.1",
|
"react-native-iphone-x-helper": "^1.3.0",
|
||||||
"react-native-maps": "0.27.0",
|
"react-native-maps": "0.27.1",
|
||||||
"react-native-paper": "^3.4.0",
|
"react-native-paper": "^4.0.1",
|
||||||
"react-native-reanimated": "~1.7.0",
|
"react-native-reanimated": "~1.13.0",
|
||||||
"react-native-safe-area-context": "0.7.3",
|
"react-native-safe-area-context": "3.1.4",
|
||||||
"react-native-screens": "2.3.0",
|
"react-native-screens": "~2.10.1",
|
||||||
"react-native-webview": "8.1.2",
|
"react-native-webview": "10.7.0",
|
||||||
"react-navigation-header-buttons": "^3.0.5"
|
"react-navigation-header-buttons": "^6.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-plugin-module-resolver": "^4.0.0",
|
"babel-plugin-module-resolver": "^4.0.0",
|
||||||
"expo-cli": "^3.13.8"
|
"expo-cli": "^3.28.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import {
|
import {
|
||||||
Alert,
|
Alert,
|
||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { ScrollView, StyleSheet } from 'react-native';
|
import { ScrollView, StyleSheet } from 'react-native';
|
||||||
import { BorderlessButton } from 'react-native-gesture-handler';
|
import { BorderlessButton } from 'react-native-gesture-handler';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { View, Text, StyleSheet, Dimensions } from 'react-native';
|
import { View, Text, StyleSheet, Dimensions } from 'react-native';
|
||||||
import { NavigationStackScreenComponent } from 'react-navigation-stack';
|
import { NavigationStackScreenComponent } from 'react-navigation-stack';
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { ScrollView, StyleProp, TextStyle } from 'react-native';
|
import { ScrollView, StyleProp, TextStyle } from 'react-native';
|
||||||
import { MaterialIcons } from '@expo/vector-icons';
|
import { MaterialIcons } from '@expo/vector-icons';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { Button, ScrollView, View, Text } from 'react-native';
|
import { Button, ScrollView, View, Text } from 'react-native';
|
||||||
|
import { createBottomTabNavigator } from 'react-navigation-tabs';
|
||||||
import {
|
import {
|
||||||
createStackNavigator,
|
createStackNavigator,
|
||||||
NavigationStackProp,
|
NavigationStackProp,
|
||||||
@@ -22,24 +23,36 @@ class FocusTag extends React.Component<NavigationStackScreenProps> {
|
|||||||
state = { mode: 'didBlur' };
|
state = { mode: 'didBlur' };
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.navigation.addListener('willFocus', () => {
|
this._willFocusSub = this.props.navigation.addListener('willFocus', () => {
|
||||||
this.setMode('willFocus');
|
this._handleEvent('willFocus');
|
||||||
});
|
});
|
||||||
|
|
||||||
this.props.navigation.addListener('willBlur', () => {
|
this._willBlurSub = this.props.navigation.addListener('willBlur', () => {
|
||||||
this.setMode('willBlur');
|
this._handleEvent('willBlur');
|
||||||
});
|
});
|
||||||
|
|
||||||
this.props.navigation.addListener('didFocus', () => {
|
this._didFocusSub = this.props.navigation.addListener('didFocus', () => {
|
||||||
this.setMode('didFocus');
|
this._handleEvent('didFocus');
|
||||||
});
|
});
|
||||||
|
|
||||||
this.props.navigation.addListener('didBlur', () => {
|
this._didBlurSub = this.props.navigation.addListener('didBlur', () => {
|
||||||
this.setMode('didBlur');
|
this._handleEvent('didBlur');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setMode = (mode: string) => {
|
componentWillUnmount() {
|
||||||
|
this._willFocusSub?.remove();
|
||||||
|
this._willBlurSub?.remove();
|
||||||
|
this._didFocusSub?.remove();
|
||||||
|
this._didBlurSub?.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
_willFocusSub: { remove: () => void } | undefined;
|
||||||
|
_willBlurSub: { remove: () => void } | undefined;
|
||||||
|
_didFocusSub: { remove: () => void } | undefined;
|
||||||
|
_didBlurSub: { remove: () => void } | undefined;
|
||||||
|
|
||||||
|
_handleEvent = (mode: string) => {
|
||||||
this.setState({ mode });
|
this.setState({ mode });
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -119,18 +132,19 @@ class SampleScreen extends React.Component<NavigationStackScreenProps> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const SimpleStack = createStackNavigator(
|
const Stack = createStackNavigator(
|
||||||
{
|
{
|
||||||
PageOne: {
|
PageOne: SampleScreen,
|
||||||
screen: SampleScreen,
|
PageTwo: SampleScreen,
|
||||||
},
|
|
||||||
PageTwo: {
|
|
||||||
screen: SampleScreen,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
initialRouteName: 'PageOne',
|
initialRouteName: 'PageOne',
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export default SimpleStack;
|
const Tabs = createBottomTabNavigator({
|
||||||
|
A: Stack,
|
||||||
|
B: Stack,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Tabs;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Dimensions,
|
Dimensions,
|
||||||
@@ -114,7 +114,7 @@ const MyNavScreen = ({
|
|||||||
title="Set unlocked"
|
title="Set unlocked"
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
unlocked: (
|
'unlocked': (
|
||||||
<Button
|
<Button
|
||||||
onPress={() =>
|
onPress={() =>
|
||||||
navigation.setParams({ drawerLockMode: 'locked-open' })
|
navigation.setParams({ drawerLockMode: 'locked-open' })
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import {
|
import {
|
||||||
AccessibilityStates,
|
|
||||||
Platform,
|
Platform,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
Text,
|
Text,
|
||||||
@@ -88,11 +87,9 @@ export default class Button extends React.Component<ButtonProps> {
|
|||||||
buttonStyles.push({ backgroundColor: color });
|
buttonStyles.push({ backgroundColor: color });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const accessibilityStates: AccessibilityStates[] = [];
|
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
buttonStyles.push(styles.buttonDisabled);
|
buttonStyles.push(styles.buttonDisabled);
|
||||||
textStyles.push(styles.textDisabled);
|
textStyles.push(styles.textDisabled);
|
||||||
accessibilityStates.push('disabled');
|
|
||||||
}
|
}
|
||||||
const formattedTitle =
|
const formattedTitle =
|
||||||
Platform.OS === 'android' ? title.toUpperCase() : title;
|
Platform.OS === 'android' ? title.toUpperCase() : title;
|
||||||
@@ -100,7 +97,7 @@ export default class Button extends React.Component<ButtonProps> {
|
|||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
accessibilityLabel={accessibilityLabel}
|
accessibilityLabel={accessibilityLabel}
|
||||||
accessibilityRole="button"
|
accessibilityRole="button"
|
||||||
accessibilityStates={accessibilityStates}
|
accessibilityState={{ disabled }}
|
||||||
testID={testID}
|
testID={testID}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onPress={onPress}
|
onPress={onPress}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { Platform, StyleSheet, View } from 'react-native';
|
import { Platform, StyleSheet, View } from 'react-native';
|
||||||
import BaseButton, { ButtonProps } from './Button';
|
import BaseButton, { ButtonProps } from './Button';
|
||||||
|
|
||||||
|
|||||||
@@ -23,13 +23,13 @@ class NavigationAwareScrollViewBase extends React.Component<{
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.subscription = this.props.navigation.addListener('refocus', () => {
|
this.subscription = this.props.navigation.addListener('refocus', () => {
|
||||||
if (this.props.navigation.isFocused()) {
|
if (this.props.navigation.isFocused()) {
|
||||||
this.root.current && this.root.current.scrollTo({ x: 0, y: 0 });
|
this.root.current?.scrollTo({ x: 0, y: 0 });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.subscription && this.subscription.remove();
|
this.subscription?.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
setNativeProps(props: ScrollViewProperties) {
|
setNativeProps(props: ScrollViewProperties) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { Button, ScrollView, StyleSheet, View } from 'react-native';
|
import { Button, ScrollView, StyleSheet, View } from 'react-native';
|
||||||
import {
|
import {
|
||||||
ThemeColors,
|
ThemeColors,
|
||||||
@@ -106,7 +106,7 @@ const MyNavScreen = ({
|
|||||||
title="Set unlocked"
|
title="Set unlocked"
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
unlocked: (
|
'unlocked': (
|
||||||
<Button
|
<Button
|
||||||
onPress={() =>
|
onPress={() =>
|
||||||
navigation.setParams({ drawerLockMode: 'locked-open' })
|
navigation.setParams({ drawerLockMode: 'locked-open' })
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { Text, View } from 'react-native';
|
import { Text, View } from 'react-native';
|
||||||
import { Themed } from 'react-navigation';
|
import { Themed } from 'react-navigation';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { Text } from 'react-native';
|
import { Text } from 'react-native';
|
||||||
import {
|
import {
|
||||||
Themed,
|
Themed,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { ScrollView, StatusBar } from 'react-native';
|
import { ScrollView, StatusBar } from 'react-native';
|
||||||
import { Ionicons } from '@expo/vector-icons';
|
import { Ionicons } from '@expo/vector-icons';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import {
|
import {
|
||||||
ScrollView,
|
ScrollView,
|
||||||
StatusBar,
|
StatusBar,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { Button, ScrollView } from 'react-native';
|
import { Button, ScrollView } from 'react-native';
|
||||||
import { Themed, SafeAreaView } from 'react-navigation';
|
import { Themed, SafeAreaView } from 'react-navigation';
|
||||||
import {
|
import {
|
||||||
@@ -91,8 +91,4 @@ const DrawerExample = createDrawerNavigator(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
DrawerExample.navigationOptions = {
|
|
||||||
headerShown: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DrawerExample;
|
export default DrawerExample;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { MaterialIcons } from '@expo/vector-icons';
|
import { MaterialIcons } from '@expo/vector-icons';
|
||||||
import { createDrawerNavigator } from 'react-navigation-drawer';
|
import { createDrawerNavigator } from 'react-navigation-drawer';
|
||||||
import SimpleTabs from './SimpleTabs';
|
import SimpleTabs from './SimpleTabs';
|
||||||
|
|||||||
41
package.json
41
package.json
@@ -18,34 +18,35 @@
|
|||||||
"author": "Adam Miskiewicz <adam@sk3vy.com>, Eric Vicenti <ericvicenti@gmail.com>, Brent Vatne <brent@expo.io>, Satyajit Sahoo <satyajit.happy@gmail.com>",
|
"author": "Adam Miskiewicz <adam@sk3vy.com>, Eric Vicenti <ericvicenti@gmail.com>, Brent Vatne <brent@expo.io>, Satyajit Sahoo <satyajit.happy@gmail.com>",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint --ext '.js,.ts,.tsx' .",
|
"lint": "eslint --ext '.js,.ts,.tsx' .",
|
||||||
"typescript": "tsc --noEmit",
|
"typescript": "tsc --noEmit --composite false",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"prerelease": "yarn lerna run clean",
|
"prerelease": "yarn lerna run clean",
|
||||||
"release": "yarn lerna publish",
|
"release": "yarn lerna publish",
|
||||||
"example": "yarn --cwd example"
|
"example": "yarn --cwd example"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
"@babel/plugin-proposal-class-properties": "^7.12.1",
|
||||||
"@babel/plugin-proposal-optional-chaining": "^7.8.3",
|
"@babel/plugin-proposal-optional-chaining": "^7.12.1",
|
||||||
"@babel/preset-env": "^7.8.7",
|
"@babel/preset-env": "^7.12.1",
|
||||||
"@babel/preset-react": "^7.8.3",
|
"@babel/preset-react": "^7.12.1",
|
||||||
"@babel/preset-typescript": "^7.8.3",
|
"@babel/preset-typescript": "^7.12.1",
|
||||||
"@babel/runtime": "^7.8.7",
|
"@babel/runtime": "^7.12.1",
|
||||||
"@commitlint/config-conventional": "^8.3.4",
|
"@commitlint/config-conventional": "^11.0.0",
|
||||||
"@types/jest": "^25.1.4",
|
"@types/jest": "^26.0.15",
|
||||||
"commitlint": "^8.3.5",
|
"babel-jest": "^26.6.1",
|
||||||
"core-js": "^3.6.4",
|
"commitlint": "^11.0.0",
|
||||||
"eslint": "^6.8.0",
|
"core-js": "^3.6.5",
|
||||||
"eslint-config-satya164": "^3.1.5",
|
"eslint": "^7.12.0",
|
||||||
"husky": "^4.2.1",
|
"eslint-config-satya164": "^3.1.8",
|
||||||
"jest": "^25.1.0",
|
"husky": "^4.2.5",
|
||||||
"lerna": "^3.20.2",
|
"jest": "^26.6.1",
|
||||||
"prettier": "^2.0.1",
|
"lerna": "^3.22.1",
|
||||||
"typescript": "~3.7.5"
|
"prettier": "^2.1.2",
|
||||||
|
"typescript": "^4.0.3"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"react": "~16.9.0",
|
"react": "~16.13.1",
|
||||||
"react-native": "~0.61.5"
|
"react-native": "~0.63.2"
|
||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
|
|||||||
@@ -3,6 +3,89 @@
|
|||||||
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.
|
||||||
|
|
||||||
|
## [0.6.3](https://github.com/react-navigation/react-navigation/compare/react-navigation-animated-switch@0.6.2...react-navigation-animated-switch@0.6.3) (2020-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-animated-switch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.6.2](https://github.com/react-navigation/react-navigation/compare/react-navigation-animated-switch@0.6.1...react-navigation-animated-switch@0.6.2) (2020-10-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-animated-switch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.6.1](https://github.com/react-navigation/react-navigation/compare/react-navigation-animated-switch@0.6.0...react-navigation-animated-switch@0.6.1) (2020-09-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-animated-switch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [0.6.0](https://github.com/react-navigation/react-navigation/compare/react-navigation-animated-switch@0.5.12...react-navigation-animated-switch@0.6.0) (2020-06-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* sync latest stack and upgrade typescript ([454e05b](https://github.com/react-navigation/react-navigation/commit/454e05b02ec97f053b381fdc801df899d8c93cb6))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.5.12](https://github.com/react-navigation/react-navigation/compare/react-navigation-animated-switch@0.5.11...react-navigation-animated-switch@0.5.12) (2020-04-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-animated-switch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.5.11](https://github.com/react-navigation/react-navigation/compare/react-navigation-animated-switch@0.5.10...react-navigation-animated-switch@0.5.11) (2020-04-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-animated-switch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.5.10](https://github.com/react-navigation/react-navigation/compare/react-navigation-animated-switch@0.5.9...react-navigation-animated-switch@0.5.10) (2020-04-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-animated-switch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.5.9](https://github.com/react-navigation/react-navigation/compare/react-navigation-animated-switch@0.5.8...react-navigation-animated-switch@0.5.9) (2020-03-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-animated-switch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.5.8](https://github.com/react-navigation/react-navigation/compare/react-navigation-animated-switch@0.5.6...react-navigation-animated-switch@0.5.8) (2020-03-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-animated-switch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.5.7](https://github.com/react-navigation/react-navigation/compare/react-navigation-animated-switch@0.5.6...react-navigation-animated-switch@0.5.7) (2020-03-27)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-animated-switch
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.5.6](https://github.com/react-navigation/react-navigation/compare/react-navigation-animated-switch@0.5.5...react-navigation-animated-switch@0.5.6) (2020-03-22)
|
## [0.5.6](https://github.com/react-navigation/react-navigation/compare/react-navigation-animated-switch@0.5.5...react-navigation-animated-switch@0.5.6) (2020-03-22)
|
||||||
|
|
||||||
**Note:** Version bump only for package react-navigation-animated-switch
|
**Note:** Version bump only for package react-navigation-animated-switch
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-navigation-animated-switch",
|
"name": "react-navigation-animated-switch",
|
||||||
"version": "0.5.6",
|
"version": "0.6.3",
|
||||||
"description": "Animated switch for React Navigation",
|
"description": "Animated switch for React Navigation",
|
||||||
"main": "lib/commonjs/index.js",
|
"main": "lib/commonjs/index.js",
|
||||||
"react-native": "lib/module/index.js",
|
"react-native": "lib/module/index.js",
|
||||||
@@ -21,15 +21,15 @@
|
|||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "0.10.0",
|
"@react-native-community/bob": "0.16.2",
|
||||||
"@types/react": "16.9.23",
|
"@types/react": "16.9.53",
|
||||||
"@types/react-native": "0.61.22",
|
"@types/react-native": "0.63.30",
|
||||||
"del-cli": "^3.0.0",
|
"del-cli": "^3.0.1",
|
||||||
"react": "~16.9.0",
|
"react": "~16.13.1",
|
||||||
"react-native": "~0.61.5",
|
"react-native": "~0.63.2",
|
||||||
"react-native-reanimated": "~1.7.0",
|
"react-native-reanimated": "~1.13.0",
|
||||||
"react-navigation": "^4.3.3",
|
"react-navigation": "^4.4.3",
|
||||||
"typescript": "~3.7.5"
|
"typescript": "^4.0.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "*",
|
"react": "*",
|
||||||
|
|||||||
@@ -3,6 +3,92 @@
|
|||||||
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.
|
||||||
|
|
||||||
|
## [3.7.9](https://github.com/react-navigation/react-navigation-core/compare/@react-navigation/core@3.7.8...@react-navigation/core@3.7.9) (2020-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [3.7.8](https://github.com/react-navigation/react-navigation-core/compare/@react-navigation/core@3.7.7...@react-navigation/core@3.7.8) (2020-10-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* NavigationEvents subscribe events on new nav state ([#8920](https://github.com/react-navigation/react-navigation-core/issues/8920)) ([6390aac](https://github.com/react-navigation/react-navigation-core/commit/6390aacd07fd647d925dfec842a766c8aad5272f))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [3.7.7](https://github.com/react-navigation/react-navigation-core/compare/@react-navigation/core@3.7.6...@react-navigation/core@3.7.7) (2020-09-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [3.7.6](https://github.com/react-navigation/react-navigation-core/compare/@react-navigation/core@3.7.5...@react-navigation/core@3.7.6) (2020-04-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* change old docUrl to new docUrl due v5 ([e09906a](https://github.com/react-navigation/react-navigation-core/commit/e09906a4235a0fca09140923ebe7af34b50b491a))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [3.7.5](https://github.com/react-navigation/react-navigation-core/compare/@react-navigation/core@3.7.4...@react-navigation/core@3.7.5) (2020-04-02)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* emit refocus for child navigators ([66a4dbc](https://github.com/react-navigation/react-navigation-core/commit/66a4dbccd8e7b3cda51a1d9c7e9397dfc58d6b9e))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [3.7.4](https://github.com/react-navigation/react-navigation-core/compare/@react-navigation/core@3.7.3...@react-navigation/core@3.7.4) (2020-03-31)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* remove isTransitioning from SwitchRouter state ([3bec1c9](https://github.com/react-navigation/react-navigation-core/commit/3bec1c964a49136c0ead8e8ba8a8c66c556bbcba))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [3.7.3](https://github.com/react-navigation/react-navigation-core/compare/@react-navigation/core@3.7.1...@react-navigation/core@3.7.3) (2020-03-28)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* always emit didFocus/didBlur for root navigator ([ac98c0a](https://github.com/react-navigation/react-navigation-core/commit/ac98c0a668fe21200d0c6f62ae3043f92cc5aa7e))
|
||||||
|
* don't handle prune if there's only one route ([d2433f0](https://github.com/react-navigation/react-navigation-core/commit/d2433f0ab8f9791df8169de4ddfdeed9bc699e3e))
|
||||||
|
* emit didFocus and didBlur events based on parent's transition ([14a6538](https://github.com/react-navigation/react-navigation-core/commit/14a6538cc8e12c50d5d10722d75c9395a0a281ec))
|
||||||
|
* rework focus and blur events to make them more reliable ([cd08338](https://github.com/react-navigation/react-navigation-core/commit/cd083381866506a192f1ec842ac169f2b4277ca5)), closes [#4867](https://github.com/react-navigation/react-navigation-core/issues/4867) [#6187](https://github.com/react-navigation/react-navigation-core/issues/6187) [#6451](https://github.com/react-navigation/react-navigation-core/issues/6451) [#7628](https://github.com/react-navigation/react-navigation-core/issues/7628) [#7749](https://github.com/react-navigation/react-navigation-core/issues/7749)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [3.7.2](https://github.com/react-navigation/react-navigation-core/compare/@react-navigation/core@3.7.1...@react-navigation/core@3.7.2) (2020-03-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* don't handle prune if there's only one route ([d2433f0](https://github.com/react-navigation/react-navigation-core/commit/d2433f0ab8f9791df8169de4ddfdeed9bc699e3e))
|
||||||
|
* rework focus and blur events to make them more reliable ([cd08338](https://github.com/react-navigation/react-navigation-core/commit/cd083381866506a192f1ec842ac169f2b4277ca5)), closes [#4867](https://github.com/react-navigation/react-navigation-core/issues/4867) [#6187](https://github.com/react-navigation/react-navigation-core/issues/6187) [#6451](https://github.com/react-navigation/react-navigation-core/issues/6451) [#7628](https://github.com/react-navigation/react-navigation-core/issues/7628) [#7749](https://github.com/react-navigation/react-navigation-core/issues/7749)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [3.7.1](https://github.com/react-navigation/react-navigation-core/compare/@react-navigation/core@3.7.0...@react-navigation/core@3.7.1) (2020-03-22)
|
## [3.7.1](https://github.com/react-navigation/react-navigation-core/compare/@react-navigation/core@3.7.0...@react-navigation/core@3.7.1) (2020-03-22)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/core
|
**Note:** Version bump only for package @react-navigation/core
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@react-navigation/core",
|
"name": "@react-navigation/core",
|
||||||
"version": "3.7.1",
|
"version": "3.7.9",
|
||||||
"description": "Core utilities for the react-navigation framework",
|
"description": "Core utilities for the react-navigation framework",
|
||||||
"main": "lib/commonjs/index.js",
|
"main": "lib/commonjs/index.js",
|
||||||
"react-native": "lib/module/index.js",
|
"react-native": "lib/module/index.js",
|
||||||
@@ -37,16 +37,16 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"hoist-non-react-statics": "^3.3.2",
|
"hoist-non-react-statics": "^3.3.2",
|
||||||
"path-to-regexp": "^1.8.0",
|
"path-to-regexp": "^1.8.0",
|
||||||
"query-string": "^6.11.1",
|
"query-string": "^6.13.6",
|
||||||
"react-is": "^16.13.0"
|
"react-is": "^16.13.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.10.0",
|
"@react-native-community/bob": "^0.16.2",
|
||||||
"del-cli": "^3.0.0",
|
"del-cli": "^3.0.1",
|
||||||
"react": "~16.9.0",
|
"react": "~16.13.1",
|
||||||
"react-native": "~0.61.5",
|
"react-native": "~0.63.2",
|
||||||
"react-native-testing-library": "^1.12.0",
|
"react-native-testing-library": "^6.0.0",
|
||||||
"react-test-renderer": "^16.9.2"
|
"react-test-renderer": "~16.13.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "*"
|
"react": "*"
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ const StateUtils = {
|
|||||||
*/
|
*/
|
||||||
jumpTo(state, key) {
|
jumpTo(state, key) {
|
||||||
const index = StateUtils.indexOf(state, key);
|
const index = StateUtils.indexOf(state, key);
|
||||||
|
invariant(index !== -1, 'attempt to jump to unknown key "%s"', key);
|
||||||
return StateUtils.jumpToIndex(state, index);
|
return StateUtils.jumpToIndex(state, index);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
148
packages/core/src/__fixtures__/createNavigationContainer.js
Normal file
148
packages/core/src/__fixtures__/createNavigationContainer.js
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
/* eslint-disable react/sort-comp */
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import { NavigationActions, getNavigation, NavigationProvider } from '../index';
|
||||||
|
|
||||||
|
export default function createNavigationContainer(Component) {
|
||||||
|
class NavigationContainer extends React.Component {
|
||||||
|
static router = Component.router;
|
||||||
|
static navigationOptions = null;
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this._initialAction = NavigationActions.init();
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
nav: !props.loadNavigationState
|
||||||
|
? Component.router.getStateForAction(this._initialAction)
|
||||||
|
: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_actionEventSubscribers = new Set();
|
||||||
|
|
||||||
|
_onNavigationStateChange(prevNav, nav, action) {
|
||||||
|
if (typeof this.props.onNavigationStateChange === 'function') {
|
||||||
|
this.props.onNavigationStateChange(prevNav, nav, action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
// Clear cached _navState every tick
|
||||||
|
if (this._navState === this.state.nav) {
|
||||||
|
this._navState = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async componentDidMount() {
|
||||||
|
// Initialize state. This must be done *after* any async code
|
||||||
|
// so we don't end up with a different value for this.state.nav
|
||||||
|
// due to changes while async function was resolving
|
||||||
|
let action = this._initialAction;
|
||||||
|
// eslint-disable-next-line react/no-access-state-in-setstate
|
||||||
|
let startupState = this.state.nav;
|
||||||
|
if (!startupState) {
|
||||||
|
startupState = Component.router.getStateForAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
const dispatchActions = () =>
|
||||||
|
this._actionEventSubscribers.forEach((subscriber) =>
|
||||||
|
subscriber({
|
||||||
|
type: 'action',
|
||||||
|
action,
|
||||||
|
state: this.state.nav,
|
||||||
|
lastState: null,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
if (startupState === this.state.nav) {
|
||||||
|
dispatchActions();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line react/no-did-mount-set-state
|
||||||
|
this.setState({ nav: startupState }, () => {
|
||||||
|
dispatchActions();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch = (action) => {
|
||||||
|
if (this.props.navigation) {
|
||||||
|
return this.props.navigation.dispatch(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
// navState will have the most up-to-date value, because setState sometimes behaves asyncronously
|
||||||
|
this._navState = this._navState || this.state.nav;
|
||||||
|
const lastNavState = this._navState;
|
||||||
|
|
||||||
|
const reducedState = Component.router.getStateForAction(
|
||||||
|
action,
|
||||||
|
lastNavState
|
||||||
|
);
|
||||||
|
const navState = reducedState === null ? lastNavState : reducedState;
|
||||||
|
|
||||||
|
const dispatchActionEvents = () => {
|
||||||
|
this._actionEventSubscribers.forEach((subscriber) =>
|
||||||
|
subscriber({
|
||||||
|
type: 'action',
|
||||||
|
action,
|
||||||
|
state: navState,
|
||||||
|
lastState: lastNavState,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (reducedState === null) {
|
||||||
|
// The router will return null when action has been handled and the state hasn't changed.
|
||||||
|
// dispatch returns true when something has been handled.
|
||||||
|
dispatchActionEvents();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (navState !== lastNavState) {
|
||||||
|
// Cache updates to state.nav during the tick to ensure that subsequent calls will not discard this change
|
||||||
|
this._navState = navState;
|
||||||
|
this.setState({ nav: navState }, () => {
|
||||||
|
this._onNavigationStateChange(lastNavState, navState, action);
|
||||||
|
dispatchActionEvents();
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatchActionEvents();
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let navigation = this.props.navigation;
|
||||||
|
|
||||||
|
const navState = this.state.nav;
|
||||||
|
|
||||||
|
if (!navState) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._navigation || this._navigation.state !== navState) {
|
||||||
|
this._navigation = getNavigation(
|
||||||
|
Component.router,
|
||||||
|
navState,
|
||||||
|
this.dispatch,
|
||||||
|
this._actionEventSubscribers,
|
||||||
|
this._getScreenProps,
|
||||||
|
() => this._navigation
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
navigation = this._navigation;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NavigationProvider value={navigation}>
|
||||||
|
<Component {...this.props} navigation={navigation} />
|
||||||
|
</NavigationProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NavigationContainer;
|
||||||
|
}
|
||||||
241
packages/core/src/__tests__/NavigationFocusEvents.test.js
Normal file
241
packages/core/src/__tests__/NavigationFocusEvents.test.js
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { render, act } from 'react-native-testing-library';
|
||||||
|
import { navigate } from '../NavigationActions';
|
||||||
|
import TabRouter from '../routers/TabRouter';
|
||||||
|
import createNavigator from '../navigators/createNavigator';
|
||||||
|
import createNavigationContainer from '../__fixtures__/createNavigationContainer';
|
||||||
|
|
||||||
|
it('fires focus and blur events in root navigator', async () => {
|
||||||
|
function createTestNavigator(routeConfigMap, config = {}) {
|
||||||
|
const router = TabRouter(routeConfigMap, config);
|
||||||
|
|
||||||
|
return createNavigator(
|
||||||
|
({ descriptors, navigation }) =>
|
||||||
|
navigation.state.routes.map((route) => {
|
||||||
|
const Comp = descriptors[route.key].getComponent();
|
||||||
|
return (
|
||||||
|
<Comp
|
||||||
|
key={route.key}
|
||||||
|
navigation={descriptors[route.key].navigation}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
router,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstFocusCallback = jest.fn();
|
||||||
|
const firstBlurCallback = jest.fn();
|
||||||
|
|
||||||
|
const secondFocusCallback = jest.fn();
|
||||||
|
const secondBlurCallback = jest.fn();
|
||||||
|
|
||||||
|
const thirdFocusCallback = jest.fn();
|
||||||
|
const thirdBlurCallback = jest.fn();
|
||||||
|
|
||||||
|
const fourthFocusCallback = jest.fn();
|
||||||
|
const fourthBlurCallback = jest.fn();
|
||||||
|
|
||||||
|
const createComponent = (focusCallback, blurCallback) =>
|
||||||
|
class TestComponent extends React.Component {
|
||||||
|
componentDidMount() {
|
||||||
|
const { navigation } = this.props;
|
||||||
|
|
||||||
|
this.focusSub = navigation.addListener('willFocus', focusCallback);
|
||||||
|
this.blurSub = navigation.addListener('willBlur', blurCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.focusSub?.remove();
|
||||||
|
this.blurSub?.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const navigation = React.createRef();
|
||||||
|
|
||||||
|
const Navigator = createNavigationContainer(
|
||||||
|
createTestNavigator({
|
||||||
|
first: createComponent(firstFocusCallback, firstBlurCallback),
|
||||||
|
second: createComponent(secondFocusCallback, secondBlurCallback),
|
||||||
|
third: createComponent(thirdFocusCallback, thirdBlurCallback),
|
||||||
|
fourth: createComponent(fourthFocusCallback, fourthBlurCallback),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const element = <Navigator ref={navigation} />;
|
||||||
|
|
||||||
|
render(element);
|
||||||
|
|
||||||
|
expect(firstFocusCallback).toBeCalledTimes(1);
|
||||||
|
expect(firstBlurCallback).toBeCalledTimes(0);
|
||||||
|
expect(secondFocusCallback).toBeCalledTimes(0);
|
||||||
|
expect(secondBlurCallback).toBeCalledTimes(0);
|
||||||
|
expect(thirdFocusCallback).toBeCalledTimes(0);
|
||||||
|
expect(thirdBlurCallback).toBeCalledTimes(0);
|
||||||
|
expect(fourthFocusCallback).toBeCalledTimes(0);
|
||||||
|
expect(fourthBlurCallback).toBeCalledTimes(0);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
navigation.current.dispatch(navigate({ routeName: 'second' }));
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(firstBlurCallback).toBeCalledTimes(1);
|
||||||
|
expect(secondFocusCallback).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
navigation.current.dispatch(navigate({ routeName: 'fourth' }));
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(firstFocusCallback).toBeCalledTimes(1);
|
||||||
|
expect(firstBlurCallback).toBeCalledTimes(1);
|
||||||
|
expect(secondFocusCallback).toBeCalledTimes(1);
|
||||||
|
expect(secondBlurCallback).toBeCalledTimes(1);
|
||||||
|
expect(thirdFocusCallback).toBeCalledTimes(0);
|
||||||
|
expect(thirdBlurCallback).toBeCalledTimes(0);
|
||||||
|
expect(fourthFocusCallback).toBeCalledTimes(1);
|
||||||
|
expect(fourthBlurCallback).toBeCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fires focus and blur events in nested navigator', () => {
|
||||||
|
function createTestNavigator(routeConfigMap, config = {}) {
|
||||||
|
const router = TabRouter(routeConfigMap, config);
|
||||||
|
|
||||||
|
return createNavigator(
|
||||||
|
({ descriptors, navigation }) =>
|
||||||
|
navigation.state.routes.map((route) => {
|
||||||
|
const Comp = descriptors[route.key].getComponent();
|
||||||
|
return (
|
||||||
|
<Comp
|
||||||
|
key={route.key}
|
||||||
|
navigation={descriptors[route.key].navigation}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
router,
|
||||||
|
config
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstFocusCallback = jest.fn();
|
||||||
|
const firstBlurCallback = jest.fn();
|
||||||
|
|
||||||
|
const secondFocusCallback = jest.fn();
|
||||||
|
const secondBlurCallback = jest.fn();
|
||||||
|
|
||||||
|
const thirdFocusCallback = jest.fn();
|
||||||
|
const thirdBlurCallback = jest.fn();
|
||||||
|
|
||||||
|
const fourthFocusCallback = jest.fn();
|
||||||
|
const fourthBlurCallback = jest.fn();
|
||||||
|
|
||||||
|
const createComponent = (focusCallback, blurCallback) =>
|
||||||
|
class TestComponent extends React.Component {
|
||||||
|
componentDidMount() {
|
||||||
|
const { navigation } = this.props;
|
||||||
|
|
||||||
|
this.focusSub = navigation.addListener('willFocus', focusCallback);
|
||||||
|
this.blurSub = navigation.addListener('willBlur', blurCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.focusSub?.remove();
|
||||||
|
this.blurSub?.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const Navigator = createNavigationContainer(
|
||||||
|
createTestNavigator({
|
||||||
|
first: createComponent(firstFocusCallback, firstBlurCallback),
|
||||||
|
second: createComponent(secondFocusCallback, secondBlurCallback),
|
||||||
|
nested: createTestNavigator({
|
||||||
|
third: createComponent(thirdFocusCallback, thirdBlurCallback),
|
||||||
|
fourth: createComponent(fourthFocusCallback, fourthBlurCallback),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const navigation = React.createRef();
|
||||||
|
|
||||||
|
const element = <Navigator ref={navigation} />;
|
||||||
|
|
||||||
|
render(element);
|
||||||
|
|
||||||
|
expect(thirdFocusCallback).toBeCalledTimes(0);
|
||||||
|
expect(firstFocusCallback).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
navigation.current.dispatch(navigate({ routeName: 'nested' }));
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(firstFocusCallback).toBeCalledTimes(1);
|
||||||
|
expect(fourthFocusCallback).toBeCalledTimes(0);
|
||||||
|
expect(thirdFocusCallback).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
navigation.current.dispatch(navigate({ routeName: 'second' }));
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(thirdFocusCallback).toBeCalledTimes(1);
|
||||||
|
expect(secondFocusCallback).toBeCalledTimes(1);
|
||||||
|
expect(fourthBlurCallback).toBeCalledTimes(0);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
navigation.current.dispatch(navigate({ routeName: 'nested' }));
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(firstBlurCallback).toBeCalledTimes(1);
|
||||||
|
expect(secondBlurCallback).toBeCalledTimes(1);
|
||||||
|
expect(thirdFocusCallback).toBeCalledTimes(2);
|
||||||
|
expect(fourthFocusCallback).toBeCalledTimes(0);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
navigation.current.dispatch(navigate({ routeName: 'third' }));
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(fourthBlurCallback).toBeCalledTimes(0);
|
||||||
|
expect(thirdFocusCallback).toBeCalledTimes(2);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
navigation.current.dispatch(navigate({ routeName: 'first' }));
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(firstFocusCallback).toBeCalledTimes(2);
|
||||||
|
expect(thirdBlurCallback).toBeCalledTimes(2);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
navigation.current.dispatch(navigate({ routeName: 'fourth' }));
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(fourthFocusCallback).toBeCalledTimes(1);
|
||||||
|
expect(thirdBlurCallback).toBeCalledTimes(2);
|
||||||
|
expect(firstBlurCallback).toBeCalledTimes(2);
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
navigation.current.dispatch(navigate({ routeName: 'third' }));
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(thirdFocusCallback).toBeCalledTimes(3);
|
||||||
|
expect(fourthBlurCallback).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
// Make sure nothing else has changed
|
||||||
|
expect(firstFocusCallback).toBeCalledTimes(2);
|
||||||
|
expect(firstBlurCallback).toBeCalledTimes(2);
|
||||||
|
|
||||||
|
expect(secondFocusCallback).toBeCalledTimes(1);
|
||||||
|
expect(secondBlurCallback).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
expect(thirdFocusCallback).toBeCalledTimes(3);
|
||||||
|
expect(thirdBlurCallback).toBeCalledTimes(2);
|
||||||
|
|
||||||
|
expect(fourthFocusCallback).toBeCalledTimes(1);
|
||||||
|
expect(fourthBlurCallback).toBeCalledTimes(1);
|
||||||
|
});
|
||||||
@@ -3,32 +3,51 @@ import NavigationStateUtils from '../StateUtils';
|
|||||||
const routeName = 'Anything';
|
const routeName = 'Anything';
|
||||||
|
|
||||||
describe('StateUtils', () => {
|
describe('StateUtils', () => {
|
||||||
// Getters
|
describe('get', () => {
|
||||||
it('gets route', () => {
|
it('gets route', () => {
|
||||||
const state = {
|
const state = {
|
||||||
index: 0,
|
index: 0,
|
||||||
routes: [{ key: 'a', routeName }],
|
routes: [{ key: 'a', routeName }],
|
||||||
isTransitioning: false,
|
isTransitioning: false,
|
||||||
};
|
};
|
||||||
expect(NavigationStateUtils.get(state, 'a')).toEqual({
|
expect(NavigationStateUtils.get(state, 'a')).toEqual({
|
||||||
key: 'a',
|
key: 'a',
|
||||||
routeName,
|
routeName,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns null when getting an unknown route', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [{ key: 'a', routeName }],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(NavigationStateUtils.get(state, 'b')).toBe(null);
|
||||||
});
|
});
|
||||||
expect(NavigationStateUtils.get(state, 'b')).toBe(null);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('gets route index', () => {
|
describe('indexOf', () => {
|
||||||
const state = {
|
it('gets route index', () => {
|
||||||
index: 1,
|
const state = {
|
||||||
routes: [
|
index: 1,
|
||||||
{ key: 'a', routeName },
|
routes: [
|
||||||
{ key: 'b', routeName },
|
{ key: 'a', routeName },
|
||||||
],
|
{ key: 'b', routeName },
|
||||||
isTransitioning: false,
|
],
|
||||||
};
|
isTransitioning: false,
|
||||||
expect(NavigationStateUtils.indexOf(state, 'a')).toBe(0);
|
};
|
||||||
expect(NavigationStateUtils.indexOf(state, 'b')).toBe(1);
|
expect(NavigationStateUtils.indexOf(state, 'a')).toBe(0);
|
||||||
expect(NavigationStateUtils.indexOf(state, 'c')).toBe(-1);
|
expect(NavigationStateUtils.indexOf(state, 'b')).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns -1 when getting an unknown route index', () => {
|
||||||
|
const state = {
|
||||||
|
index: 1,
|
||||||
|
routes: [{ key: 'a', routeName }],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(NavigationStateUtils.indexOf(state, 'b')).toBe(-1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has a route', () => {
|
it('has a route', () => {
|
||||||
@@ -44,303 +63,390 @@ describe('StateUtils', () => {
|
|||||||
expect(NavigationStateUtils.has(state, 'c')).toBe(false);
|
expect(NavigationStateUtils.has(state, 'c')).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Push
|
describe('push', () => {
|
||||||
it('pushes a route', () => {
|
it('pushes a route', () => {
|
||||||
const state = {
|
const state = {
|
||||||
index: 0,
|
index: 0,
|
||||||
routes: [{ key: 'a', routeName }],
|
routes: [{ key: 'a', routeName }],
|
||||||
isTransitioning: false,
|
isTransitioning: false,
|
||||||
};
|
};
|
||||||
const newState = {
|
const newState = {
|
||||||
index: 1,
|
index: 1,
|
||||||
isTransitioning: false,
|
isTransitioning: false,
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'a', routeName },
|
{ key: 'a', routeName },
|
||||||
{ key: 'b', routeName },
|
{ key: 'b', routeName },
|
||||||
],
|
|
||||||
};
|
|
||||||
expect(NavigationStateUtils.push(state, { key: 'b', routeName })).toEqual(
|
|
||||||
newState
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not push duplicated route', () => {
|
|
||||||
const state = {
|
|
||||||
index: 0,
|
|
||||||
routes: [{ key: 'a', routeName }],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
expect(() =>
|
|
||||||
NavigationStateUtils.push(state, { key: 'a', routeName })
|
|
||||||
).toThrow('should not push route with duplicated key a');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Pop
|
|
||||||
it('pops route', () => {
|
|
||||||
const state = {
|
|
||||||
index: 1,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'b', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
const newState = {
|
|
||||||
index: 0,
|
|
||||||
routes: [{ key: 'a', routeName }],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
expect(NavigationStateUtils.pop(state)).toEqual(newState);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not pop route if not applicable', () => {
|
|
||||||
const state = {
|
|
||||||
index: 0,
|
|
||||||
routes: [{ key: 'a', routeName }],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
expect(NavigationStateUtils.pop(state)).toBe(state);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Jump
|
|
||||||
it('jumps to new index', () => {
|
|
||||||
const state = {
|
|
||||||
index: 0,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'b', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
const newState = {
|
|
||||||
index: 1,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'b', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
expect(NavigationStateUtils.jumpToIndex(state, 0)).toBe(state);
|
|
||||||
expect(NavigationStateUtils.jumpToIndex(state, 1)).toEqual(newState);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws if jumps to invalid index', () => {
|
|
||||||
const state = {
|
|
||||||
index: 0,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'b', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
expect(() => NavigationStateUtils.jumpToIndex(state, 2)).toThrow(
|
|
||||||
'invalid index 2 to jump to'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('jumps to new key', () => {
|
|
||||||
const state = {
|
|
||||||
index: 0,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'b', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
const newState = {
|
|
||||||
index: 1,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'b', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
expect(NavigationStateUtils.jumpTo(state, 'a')).toBe(state);
|
|
||||||
expect(NavigationStateUtils.jumpTo(state, 'b')).toEqual(newState);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws if jumps to invalid key', () => {
|
|
||||||
const state = {
|
|
||||||
index: 0,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'b', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
expect(() => NavigationStateUtils.jumpTo(state, 'c')).toThrow(
|
|
||||||
'invalid index -1 to jump to'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('move backwards', () => {
|
|
||||||
const state = {
|
|
||||||
index: 1,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'b', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
const newState = {
|
|
||||||
index: 0,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'b', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
expect(NavigationStateUtils.back(state)).toEqual(newState);
|
|
||||||
expect(NavigationStateUtils.back(newState)).toBe(newState);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('move forwards', () => {
|
|
||||||
const state = {
|
|
||||||
index: 0,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'b', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
const newState = {
|
|
||||||
index: 1,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'b', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
expect(NavigationStateUtils.forward(state)).toEqual(newState);
|
|
||||||
expect(NavigationStateUtils.forward(newState)).toBe(newState);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Replace
|
|
||||||
it('Replaces by key', () => {
|
|
||||||
const state = {
|
|
||||||
index: 0,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'b', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
const newState = {
|
|
||||||
index: 1,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'c', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
expect(
|
|
||||||
NavigationStateUtils.replaceAt(state, 'b', { key: 'c', routeName })
|
|
||||||
).toEqual(newState);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Replaces by index', () => {
|
|
||||||
const state = {
|
|
||||||
index: 0,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'b', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
const newState = {
|
|
||||||
index: 1,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'c', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
expect(
|
|
||||||
NavigationStateUtils.replaceAtIndex(state, 1, { key: 'c', routeName })
|
|
||||||
).toEqual(newState);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Returns the state with updated index if route is unchanged but index changes', () => {
|
|
||||||
const state = {
|
|
||||||
index: 0,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'b', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
expect(
|
|
||||||
NavigationStateUtils.replaceAtIndex(state, 1, state.routes[1])
|
|
||||||
).toEqual({ ...state, index: 1 });
|
|
||||||
});
|
|
||||||
|
|
||||||
// Reset
|
|
||||||
it('Resets routes', () => {
|
|
||||||
const state = {
|
|
||||||
index: 0,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'b', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
const newState = {
|
|
||||||
index: 1,
|
|
||||||
routes: [
|
|
||||||
{ key: 'x', routeName },
|
|
||||||
{ key: 'y', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
expect(
|
|
||||||
NavigationStateUtils.reset(state, [
|
|
||||||
{ key: 'x', routeName },
|
|
||||||
{ key: 'y', routeName },
|
|
||||||
])
|
|
||||||
).toEqual(newState);
|
|
||||||
|
|
||||||
expect(() => {
|
|
||||||
NavigationStateUtils.reset(state, []);
|
|
||||||
}).toThrow('invalid routes to replace');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Resets routes with index', () => {
|
|
||||||
const state = {
|
|
||||||
index: 0,
|
|
||||||
routes: [
|
|
||||||
{ key: 'a', routeName },
|
|
||||||
{ key: 'b', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
const newState = {
|
|
||||||
index: 0,
|
|
||||||
routes: [
|
|
||||||
{ key: 'x', routeName },
|
|
||||||
{ key: 'y', routeName },
|
|
||||||
],
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
expect(
|
|
||||||
NavigationStateUtils.reset(
|
|
||||||
state,
|
|
||||||
[
|
|
||||||
{ key: 'x', routeName },
|
|
||||||
{ key: 'y', routeName },
|
|
||||||
],
|
],
|
||||||
0
|
};
|
||||||
)
|
expect(NavigationStateUtils.push(state, { key: 'b', routeName })).toEqual(
|
||||||
).toEqual(newState);
|
newState
|
||||||
|
|
||||||
expect(() => {
|
|
||||||
NavigationStateUtils.reset(
|
|
||||||
state,
|
|
||||||
[
|
|
||||||
{ key: 'x', routeName },
|
|
||||||
{ key: 'y', routeName },
|
|
||||||
],
|
|
||||||
100
|
|
||||||
);
|
);
|
||||||
}).toThrow('invalid index 100 to reset');
|
});
|
||||||
|
|
||||||
|
it('does not push duplicated route', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [{ key: 'a', routeName }],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(() =>
|
||||||
|
NavigationStateUtils.push(state, { key: 'a', routeName })
|
||||||
|
).toThrow('should not push route with duplicated key a');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('pop', () => {
|
||||||
|
it('pops route', () => {
|
||||||
|
const state = {
|
||||||
|
index: 1,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
const newState = {
|
||||||
|
index: 0,
|
||||||
|
routes: [{ key: 'a', routeName }],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(NavigationStateUtils.pop(state)).toEqual(newState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not pop route if not applicable with single route config', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [{ key: 'a', routeName }],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(NavigationStateUtils.pop(state)).toBe(state);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not pop route if not applicable with multiple route config', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(NavigationStateUtils.pop(state)).toBe(state);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('jumpToIndex', () => {
|
||||||
|
it('jumps to new index', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
const newState = {
|
||||||
|
index: 1,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(NavigationStateUtils.jumpToIndex(state, 0)).toBe(state);
|
||||||
|
expect(NavigationStateUtils.jumpToIndex(state, 1)).toEqual(newState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws if jumps to invalid index', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(() => NavigationStateUtils.jumpToIndex(state, 2)).toThrow(
|
||||||
|
'invalid index 2 to jump to'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('jumpTo', () => {
|
||||||
|
it('jumps to the current key', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(NavigationStateUtils.jumpTo(state, 'a')).toBe(state);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('jumps to new key', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
const newState = {
|
||||||
|
index: 1,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(NavigationStateUtils.jumpTo(state, 'b')).toEqual(newState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws if jumps to invalid key', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(() => NavigationStateUtils.jumpTo(state, 'c')).toThrow(
|
||||||
|
'attempt to jump to unknown key "c"'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('back', () => {
|
||||||
|
it('move backwards', () => {
|
||||||
|
const state = {
|
||||||
|
index: 1,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
const newState = {
|
||||||
|
index: 0,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(NavigationStateUtils.back(state)).toEqual(newState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not move backwards when the active route is the first', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(NavigationStateUtils.back(state)).toBe(state);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('forward', () => {
|
||||||
|
it('move forwards', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
const newState = {
|
||||||
|
index: 1,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(NavigationStateUtils.forward(state)).toEqual(newState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not move forward when active route is already the top-most', () => {
|
||||||
|
const state = {
|
||||||
|
index: 1,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(NavigationStateUtils.forward(state)).toEqual(state);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('replace', () => {
|
||||||
|
it('Replaces by key', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
const newState = {
|
||||||
|
index: 1,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'c', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(
|
||||||
|
NavigationStateUtils.replaceAt(state, 'b', { key: 'c', routeName })
|
||||||
|
).toEqual(newState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Replaces by index', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
const newState = {
|
||||||
|
index: 1,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'c', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(
|
||||||
|
NavigationStateUtils.replaceAtIndex(state, 1, { key: 'c', routeName })
|
||||||
|
).toEqual(newState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Returns the state with updated index if route is unchanged but index changes', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(
|
||||||
|
NavigationStateUtils.replaceAtIndex(state, 1, state.routes[1])
|
||||||
|
).toEqual({ ...state, index: 1 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('reset', () => {
|
||||||
|
it('Resets routes', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
const newState = {
|
||||||
|
index: 1,
|
||||||
|
routes: [
|
||||||
|
{ key: 'x', routeName },
|
||||||
|
{ key: 'y', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(
|
||||||
|
NavigationStateUtils.reset(state, [
|
||||||
|
{ key: 'x', routeName },
|
||||||
|
{ key: 'y', routeName },
|
||||||
|
])
|
||||||
|
).toEqual(newState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws when attempting to set empty state', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(() => {
|
||||||
|
NavigationStateUtils.reset(state, []);
|
||||||
|
}).toThrow('invalid routes to replace');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Resets routes with index', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
const newState = {
|
||||||
|
index: 0,
|
||||||
|
routes: [
|
||||||
|
{ key: 'x', routeName },
|
||||||
|
{ key: 'y', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(
|
||||||
|
NavigationStateUtils.reset(
|
||||||
|
state,
|
||||||
|
[
|
||||||
|
{ key: 'x', routeName },
|
||||||
|
{ key: 'y', routeName },
|
||||||
|
],
|
||||||
|
0
|
||||||
|
)
|
||||||
|
).toEqual(newState);
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
NavigationStateUtils.reset(
|
||||||
|
state,
|
||||||
|
[
|
||||||
|
{ key: 'x', routeName },
|
||||||
|
{ key: 'y', routeName },
|
||||||
|
],
|
||||||
|
100
|
||||||
|
);
|
||||||
|
}).toThrow('invalid index 100 to reset');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws when attempting to set an out of range route index', () => {
|
||||||
|
const state = {
|
||||||
|
index: 0,
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName },
|
||||||
|
{ key: 'b', routeName },
|
||||||
|
],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
expect(() => {
|
||||||
|
NavigationStateUtils.reset(
|
||||||
|
state,
|
||||||
|
[
|
||||||
|
{ key: 'x', routeName },
|
||||||
|
{ key: 'y', routeName },
|
||||||
|
],
|
||||||
|
100
|
||||||
|
);
|
||||||
|
}).toThrow('invalid index 100 to reset');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,543 +0,0 @@
|
|||||||
import getChildEventSubscriber from '../getChildEventSubscriber';
|
|
||||||
|
|
||||||
it('child action events only flow when focused', () => {
|
|
||||||
const parentSubscriber = jest.fn();
|
|
||||||
const emitParentAction = (payload) => {
|
|
||||||
parentSubscriber.mock.calls.forEach((subs) => {
|
|
||||||
if (subs[0] === payload.type) {
|
|
||||||
subs[1](payload);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const subscriptionRemove = () => {};
|
|
||||||
parentSubscriber.mockReturnValueOnce({ remove: subscriptionRemove });
|
|
||||||
const childEventSubscriber = getChildEventSubscriber(parentSubscriber, 'key1')
|
|
||||||
.addListener;
|
|
||||||
const testState = {
|
|
||||||
key: 'foo',
|
|
||||||
routeName: 'FooRoute',
|
|
||||||
routes: [{ key: 'key0' }, { key: 'key1' }],
|
|
||||||
index: 0,
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
const focusedTestState = {
|
|
||||||
...testState,
|
|
||||||
index: 1,
|
|
||||||
};
|
|
||||||
const childActionHandler = jest.fn();
|
|
||||||
const childWillFocusHandler = jest.fn();
|
|
||||||
const childDidFocusHandler = jest.fn();
|
|
||||||
childEventSubscriber('action', childActionHandler);
|
|
||||||
childEventSubscriber('willFocus', childWillFocusHandler);
|
|
||||||
childEventSubscriber('didFocus', childDidFocusHandler);
|
|
||||||
emitParentAction({
|
|
||||||
type: 'action',
|
|
||||||
state: focusedTestState,
|
|
||||||
lastState: testState,
|
|
||||||
action: { type: 'FooAction' },
|
|
||||||
});
|
|
||||||
expect(childActionHandler.mock.calls.length).toBe(0);
|
|
||||||
expect(childWillFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childDidFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
emitParentAction({
|
|
||||||
type: 'action',
|
|
||||||
state: focusedTestState,
|
|
||||||
lastState: focusedTestState,
|
|
||||||
action: { type: 'FooAction' },
|
|
||||||
});
|
|
||||||
expect(childActionHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childWillFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childDidFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('grandchildren subscription', () => {
|
|
||||||
const grandParentSubscriber = jest.fn();
|
|
||||||
const emitGrandParentAction = (payload) => {
|
|
||||||
grandParentSubscriber.mock.calls.forEach((subs) => {
|
|
||||||
if (subs[0] === payload.type) {
|
|
||||||
subs[1](payload);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const subscriptionRemove = () => {};
|
|
||||||
grandParentSubscriber.mockReturnValueOnce({ remove: subscriptionRemove });
|
|
||||||
const parentSubscriber = getChildEventSubscriber(
|
|
||||||
grandParentSubscriber,
|
|
||||||
'parent'
|
|
||||||
).addListener;
|
|
||||||
const childEventSubscriber = getChildEventSubscriber(parentSubscriber, 'key1')
|
|
||||||
.addListener;
|
|
||||||
const parentBlurState = {
|
|
||||||
key: 'foo',
|
|
||||||
routeName: 'FooRoute',
|
|
||||||
routes: [
|
|
||||||
{ key: 'aunt' },
|
|
||||||
{
|
|
||||||
key: 'parent',
|
|
||||||
routes: [{ key: 'key0' }, { key: 'key1' }],
|
|
||||||
index: 1,
|
|
||||||
isTransitioning: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
index: 0,
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
const parentTransitionState = {
|
|
||||||
...parentBlurState,
|
|
||||||
index: 1,
|
|
||||||
isTransitioning: true,
|
|
||||||
};
|
|
||||||
const parentFocusState = {
|
|
||||||
...parentTransitionState,
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
const childActionHandler = jest.fn();
|
|
||||||
const childWillFocusHandler = jest.fn();
|
|
||||||
const childDidFocusHandler = jest.fn();
|
|
||||||
childEventSubscriber('action', childActionHandler);
|
|
||||||
childEventSubscriber('willFocus', childWillFocusHandler);
|
|
||||||
childEventSubscriber('didFocus', childDidFocusHandler);
|
|
||||||
emitGrandParentAction({
|
|
||||||
type: 'action',
|
|
||||||
state: parentTransitionState,
|
|
||||||
lastState: parentBlurState,
|
|
||||||
action: { type: 'FooAction' },
|
|
||||||
});
|
|
||||||
expect(childActionHandler.mock.calls.length).toBe(0);
|
|
||||||
expect(childWillFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childDidFocusHandler.mock.calls.length).toBe(0);
|
|
||||||
emitGrandParentAction({
|
|
||||||
type: 'action',
|
|
||||||
state: parentFocusState,
|
|
||||||
lastState: parentTransitionState,
|
|
||||||
action: { type: 'FooAction' },
|
|
||||||
});
|
|
||||||
expect(childActionHandler.mock.calls.length).toBe(0);
|
|
||||||
expect(childWillFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childDidFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('grandchildren transitions', () => {
|
|
||||||
const grandParentSubscriber = jest.fn();
|
|
||||||
const emitGrandParentAction = (payload) => {
|
|
||||||
grandParentSubscriber.mock.calls.forEach((subs) => {
|
|
||||||
if (subs[0] === payload.type) {
|
|
||||||
subs[1](payload);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const subscriptionRemove = () => {};
|
|
||||||
grandParentSubscriber.mockReturnValueOnce({ remove: subscriptionRemove });
|
|
||||||
const parentSubscriber = getChildEventSubscriber(
|
|
||||||
grandParentSubscriber,
|
|
||||||
'parent'
|
|
||||||
).addListener;
|
|
||||||
const childEventSubscriber = getChildEventSubscriber(parentSubscriber, 'key1')
|
|
||||||
.addListener;
|
|
||||||
const makeFakeState = (childIndex, childIsTransitioning) => ({
|
|
||||||
index: 1,
|
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
|
||||||
{ key: 'nothing' },
|
|
||||||
{
|
|
||||||
key: 'parent',
|
|
||||||
index: childIndex,
|
|
||||||
isTransitioning: childIsTransitioning,
|
|
||||||
routes: [{ key: 'key0' }, { key: 'key1' }, { key: 'key2' }],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
const blurredState = makeFakeState(0, false);
|
|
||||||
const transitionState = makeFakeState(1, true);
|
|
||||||
const focusState = makeFakeState(1, false);
|
|
||||||
const transition2State = makeFakeState(2, true);
|
|
||||||
const blurred2State = makeFakeState(2, false);
|
|
||||||
|
|
||||||
const childActionHandler = jest.fn();
|
|
||||||
const childWillFocusHandler = jest.fn();
|
|
||||||
const childDidFocusHandler = jest.fn();
|
|
||||||
const childWillBlurHandler = jest.fn();
|
|
||||||
const childDidBlurHandler = jest.fn();
|
|
||||||
childEventSubscriber('action', childActionHandler);
|
|
||||||
childEventSubscriber('willFocus', childWillFocusHandler);
|
|
||||||
childEventSubscriber('didFocus', childDidFocusHandler);
|
|
||||||
childEventSubscriber('willBlur', childWillBlurHandler);
|
|
||||||
childEventSubscriber('didBlur', childDidBlurHandler);
|
|
||||||
emitGrandParentAction({
|
|
||||||
type: 'action',
|
|
||||||
state: transitionState,
|
|
||||||
lastState: blurredState,
|
|
||||||
action: { type: 'FooAction' },
|
|
||||||
});
|
|
||||||
expect(childActionHandler.mock.calls.length).toBe(0);
|
|
||||||
expect(childWillFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childDidFocusHandler.mock.calls.length).toBe(0);
|
|
||||||
emitGrandParentAction({
|
|
||||||
type: 'action',
|
|
||||||
state: focusState,
|
|
||||||
lastState: transitionState,
|
|
||||||
action: { type: 'FooAction' },
|
|
||||||
});
|
|
||||||
expect(childActionHandler.mock.calls.length).toBe(0);
|
|
||||||
expect(childWillFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childDidFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
emitGrandParentAction({
|
|
||||||
type: 'action',
|
|
||||||
state: focusState,
|
|
||||||
lastState: focusState,
|
|
||||||
action: { type: 'TestAction' },
|
|
||||||
});
|
|
||||||
expect(childWillFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childDidFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childActionHandler.mock.calls.length).toBe(1);
|
|
||||||
emitGrandParentAction({
|
|
||||||
type: 'action',
|
|
||||||
state: transition2State,
|
|
||||||
lastState: focusState,
|
|
||||||
action: { type: 'CauseWillBlurAction' },
|
|
||||||
});
|
|
||||||
expect(childWillBlurHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childDidBlurHandler.mock.calls.length).toBe(0);
|
|
||||||
expect(childActionHandler.mock.calls.length).toBe(1);
|
|
||||||
emitGrandParentAction({
|
|
||||||
type: 'action',
|
|
||||||
state: blurred2State,
|
|
||||||
lastState: transition2State,
|
|
||||||
action: { type: 'CauseDidBlurAction' },
|
|
||||||
});
|
|
||||||
expect(childWillBlurHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childDidBlurHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childActionHandler.mock.calls.length).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('grandchildren pass through transitions', () => {
|
|
||||||
const grandParentSubscriber = jest.fn();
|
|
||||||
const emitGrandParentAction = (payload) => {
|
|
||||||
grandParentSubscriber.mock.calls.forEach((subs) => {
|
|
||||||
if (subs[0] === payload.type) {
|
|
||||||
subs[1](payload);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const subscriptionRemove = () => {};
|
|
||||||
grandParentSubscriber.mockReturnValueOnce({ remove: subscriptionRemove });
|
|
||||||
const parentSubscriber = getChildEventSubscriber(
|
|
||||||
grandParentSubscriber,
|
|
||||||
'parent'
|
|
||||||
).addListener;
|
|
||||||
const childEventSubscriber = getChildEventSubscriber(parentSubscriber, 'key1')
|
|
||||||
.addListener;
|
|
||||||
const makeFakeState = (childIndex, childIsTransitioning) => ({
|
|
||||||
index: childIndex,
|
|
||||||
isTransitioning: childIsTransitioning,
|
|
||||||
routes: [
|
|
||||||
{ key: 'nothing' },
|
|
||||||
{
|
|
||||||
key: 'parent',
|
|
||||||
index: 1,
|
|
||||||
isTransitioning: false,
|
|
||||||
routes: [{ key: 'key0' }, { key: 'key1' }, { key: 'key2' }],
|
|
||||||
},
|
|
||||||
].slice(0, childIndex + 1),
|
|
||||||
});
|
|
||||||
const blurredState = makeFakeState(0, false);
|
|
||||||
const transitionState = makeFakeState(1, true);
|
|
||||||
const focusState = makeFakeState(1, false);
|
|
||||||
const transition2State = makeFakeState(0, true);
|
|
||||||
const blurred2State = makeFakeState(0, false);
|
|
||||||
|
|
||||||
const childActionHandler = jest.fn();
|
|
||||||
const childWillFocusHandler = jest.fn();
|
|
||||||
const childDidFocusHandler = jest.fn();
|
|
||||||
const childWillBlurHandler = jest.fn();
|
|
||||||
const childDidBlurHandler = jest.fn();
|
|
||||||
childEventSubscriber('action', childActionHandler);
|
|
||||||
childEventSubscriber('willFocus', childWillFocusHandler);
|
|
||||||
childEventSubscriber('didFocus', childDidFocusHandler);
|
|
||||||
childEventSubscriber('willBlur', childWillBlurHandler);
|
|
||||||
childEventSubscriber('didBlur', childDidBlurHandler);
|
|
||||||
emitGrandParentAction({
|
|
||||||
type: 'action',
|
|
||||||
state: transitionState,
|
|
||||||
lastState: blurredState,
|
|
||||||
action: { type: 'FooAction' },
|
|
||||||
});
|
|
||||||
expect(childActionHandler.mock.calls.length).toBe(0);
|
|
||||||
expect(childWillFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childDidFocusHandler.mock.calls.length).toBe(0);
|
|
||||||
emitGrandParentAction({
|
|
||||||
type: 'action',
|
|
||||||
state: focusState,
|
|
||||||
lastState: transitionState,
|
|
||||||
action: { type: 'FooAction' },
|
|
||||||
});
|
|
||||||
expect(childActionHandler.mock.calls.length).toBe(0);
|
|
||||||
expect(childWillFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childDidFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
emitGrandParentAction({
|
|
||||||
type: 'action',
|
|
||||||
state: focusState,
|
|
||||||
lastState: focusState,
|
|
||||||
action: { type: 'TestAction' },
|
|
||||||
});
|
|
||||||
expect(childWillFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childDidFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childActionHandler.mock.calls.length).toBe(1);
|
|
||||||
emitGrandParentAction({
|
|
||||||
type: 'action',
|
|
||||||
state: transition2State,
|
|
||||||
lastState: focusState,
|
|
||||||
action: { type: 'CauseWillBlurAction' },
|
|
||||||
});
|
|
||||||
expect(childWillBlurHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childDidBlurHandler.mock.calls.length).toBe(0);
|
|
||||||
expect(childActionHandler.mock.calls.length).toBe(1);
|
|
||||||
emitGrandParentAction({
|
|
||||||
type: 'action',
|
|
||||||
state: blurred2State,
|
|
||||||
lastState: transition2State,
|
|
||||||
action: { type: 'CauseDidBlurAction' },
|
|
||||||
});
|
|
||||||
expect(childWillBlurHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childDidBlurHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childActionHandler.mock.calls.length).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('child focus with transition', () => {
|
|
||||||
const parentSubscriber = jest.fn();
|
|
||||||
const emitParentAction = (payload) => {
|
|
||||||
parentSubscriber.mock.calls.forEach((subs) => {
|
|
||||||
if (subs[0] === payload.type) {
|
|
||||||
subs[1](payload);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const subscriptionRemove = () => {};
|
|
||||||
parentSubscriber.mockReturnValueOnce({ remove: subscriptionRemove });
|
|
||||||
const childEventSubscriber = getChildEventSubscriber(parentSubscriber, 'key1')
|
|
||||||
.addListener;
|
|
||||||
const randomAction = { type: 'FooAction' };
|
|
||||||
const testState = {
|
|
||||||
key: 'foo',
|
|
||||||
routeName: 'FooRoute',
|
|
||||||
routes: [{ key: 'key0' }, { key: 'key1' }],
|
|
||||||
index: 0,
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
const childWillFocusHandler = jest.fn();
|
|
||||||
const childDidFocusHandler = jest.fn();
|
|
||||||
const childWillBlurHandler = jest.fn();
|
|
||||||
const childDidBlurHandler = jest.fn();
|
|
||||||
childEventSubscriber('willFocus', childWillFocusHandler);
|
|
||||||
childEventSubscriber('didFocus', childDidFocusHandler);
|
|
||||||
childEventSubscriber('willBlur', childWillBlurHandler);
|
|
||||||
childEventSubscriber('didBlur', childDidBlurHandler);
|
|
||||||
emitParentAction({
|
|
||||||
type: 'didFocus',
|
|
||||||
action: randomAction,
|
|
||||||
lastState: testState,
|
|
||||||
state: testState,
|
|
||||||
});
|
|
||||||
emitParentAction({
|
|
||||||
type: 'action',
|
|
||||||
action: randomAction,
|
|
||||||
lastState: testState,
|
|
||||||
state: {
|
|
||||||
...testState,
|
|
||||||
index: 1,
|
|
||||||
isTransitioning: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(childWillFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
emitParentAction({
|
|
||||||
type: 'action',
|
|
||||||
action: randomAction,
|
|
||||||
lastState: {
|
|
||||||
...testState,
|
|
||||||
index: 1,
|
|
||||||
isTransitioning: true,
|
|
||||||
},
|
|
||||||
state: {
|
|
||||||
...testState,
|
|
||||||
index: 1,
|
|
||||||
isTransitioning: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(childDidFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
emitParentAction({
|
|
||||||
type: 'action',
|
|
||||||
action: randomAction,
|
|
||||||
lastState: {
|
|
||||||
...testState,
|
|
||||||
index: 1,
|
|
||||||
isTransitioning: false,
|
|
||||||
},
|
|
||||||
state: {
|
|
||||||
...testState,
|
|
||||||
index: 0,
|
|
||||||
isTransitioning: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(childWillBlurHandler.mock.calls.length).toBe(1);
|
|
||||||
emitParentAction({
|
|
||||||
type: 'action',
|
|
||||||
action: randomAction,
|
|
||||||
lastState: {
|
|
||||||
...testState,
|
|
||||||
index: 0,
|
|
||||||
isTransitioning: true,
|
|
||||||
},
|
|
||||||
state: {
|
|
||||||
...testState,
|
|
||||||
index: 0,
|
|
||||||
isTransitioning: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(childDidBlurHandler.mock.calls.length).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('child focus with immediate transition', () => {
|
|
||||||
const parentSubscriber = jest.fn();
|
|
||||||
const emitParentAction = (payload) => {
|
|
||||||
parentSubscriber.mock.calls.forEach((subs) => {
|
|
||||||
if (subs[0] === payload.type) {
|
|
||||||
subs[1](payload);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const subscriptionRemove = () => {};
|
|
||||||
parentSubscriber.mockReturnValueOnce({ remove: subscriptionRemove });
|
|
||||||
const childEventSubscriber = getChildEventSubscriber(parentSubscriber, 'key1')
|
|
||||||
.addListener;
|
|
||||||
const randomAction = { type: 'FooAction' };
|
|
||||||
const testState = {
|
|
||||||
key: 'foo',
|
|
||||||
routeName: 'FooRoute',
|
|
||||||
routes: [{ key: 'key0' }, { key: 'key1' }],
|
|
||||||
index: 0,
|
|
||||||
isTransitioning: false,
|
|
||||||
};
|
|
||||||
const childWillFocusHandler = jest.fn();
|
|
||||||
const childDidFocusHandler = jest.fn();
|
|
||||||
const childWillBlurHandler = jest.fn();
|
|
||||||
const childDidBlurHandler = jest.fn();
|
|
||||||
childEventSubscriber('willFocus', childWillFocusHandler);
|
|
||||||
childEventSubscriber('didFocus', childDidFocusHandler);
|
|
||||||
childEventSubscriber('willBlur', childWillBlurHandler);
|
|
||||||
childEventSubscriber('didBlur', childDidBlurHandler);
|
|
||||||
emitParentAction({
|
|
||||||
type: 'didFocus',
|
|
||||||
action: randomAction,
|
|
||||||
lastState: testState,
|
|
||||||
state: testState,
|
|
||||||
});
|
|
||||||
emitParentAction({
|
|
||||||
type: 'action',
|
|
||||||
action: randomAction,
|
|
||||||
lastState: testState,
|
|
||||||
state: {
|
|
||||||
...testState,
|
|
||||||
index: 1,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(childWillFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childDidFocusHandler.mock.calls.length).toBe(1);
|
|
||||||
|
|
||||||
emitParentAction({
|
|
||||||
type: 'action',
|
|
||||||
action: randomAction,
|
|
||||||
lastState: {
|
|
||||||
...testState,
|
|
||||||
index: 1,
|
|
||||||
},
|
|
||||||
state: {
|
|
||||||
...testState,
|
|
||||||
index: 0,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
expect(childWillBlurHandler.mock.calls.length).toBe(1);
|
|
||||||
expect(childDidBlurHandler.mock.calls.length).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
const setupEventTest = (subscriptionKey, initialLastFocusEvent) => {
|
|
||||||
const parentSubscriber = jest.fn();
|
|
||||||
const emitEvent = (payload) => {
|
|
||||||
parentSubscriber.mock.calls.forEach((subs) => {
|
|
||||||
if (subs[0] === payload.type) {
|
|
||||||
subs[1](payload);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const subscriptionRemove = () => {};
|
|
||||||
parentSubscriber.mockReturnValueOnce({ remove: subscriptionRemove });
|
|
||||||
const evtProvider = getChildEventSubscriber(
|
|
||||||
parentSubscriber,
|
|
||||||
subscriptionKey,
|
|
||||||
initialLastFocusEvent
|
|
||||||
);
|
|
||||||
const handlers = {};
|
|
||||||
evtProvider.addListener('action', (handlers.action = jest.fn()));
|
|
||||||
evtProvider.addListener('willFocus', (handlers.willFocus = jest.fn()));
|
|
||||||
evtProvider.addListener('didFocus', (handlers.didFocus = jest.fn()));
|
|
||||||
evtProvider.addListener('willBlur', (handlers.willBlur = jest.fn()));
|
|
||||||
evtProvider.addListener('didBlur', (handlers.didBlur = jest.fn()));
|
|
||||||
return { emitEvent, handlers, evtProvider };
|
|
||||||
};
|
|
||||||
|
|
||||||
it('immediate back with uncompleted transition will focus first screen again', () => {
|
|
||||||
const { handlers, emitEvent } = setupEventTest('key0', 'didFocus');
|
|
||||||
emitEvent({
|
|
||||||
type: 'action',
|
|
||||||
state: {
|
|
||||||
index: 1,
|
|
||||||
routes: [{ key: 'key0' }, { key: 'key1' }],
|
|
||||||
isTransitioning: true,
|
|
||||||
},
|
|
||||||
lastState: {
|
|
||||||
index: 0,
|
|
||||||
routes: [{ key: 'key0' }],
|
|
||||||
isTransitioning: false,
|
|
||||||
},
|
|
||||||
action: { type: 'Any action, does not matter here' },
|
|
||||||
});
|
|
||||||
expect(handlers.willFocus.mock.calls.length).toBe(0);
|
|
||||||
expect(handlers.didFocus.mock.calls.length).toBe(0);
|
|
||||||
expect(handlers.willBlur.mock.calls.length).toBe(1);
|
|
||||||
expect(handlers.didBlur.mock.calls.length).toBe(0);
|
|
||||||
emitEvent({
|
|
||||||
type: 'action',
|
|
||||||
state: {
|
|
||||||
index: 0,
|
|
||||||
routes: [{ key: 'key0' }],
|
|
||||||
isTransitioning: true,
|
|
||||||
},
|
|
||||||
lastState: {
|
|
||||||
index: 1,
|
|
||||||
routes: [{ key: 'key0' }, { key: 'key1' }],
|
|
||||||
isTransitioning: true,
|
|
||||||
},
|
|
||||||
action: { type: 'Any action, does not matter here' },
|
|
||||||
});
|
|
||||||
expect(handlers.willFocus.mock.calls.length).toBe(1);
|
|
||||||
expect(handlers.didFocus.mock.calls.length).toBe(0);
|
|
||||||
expect(handlers.willBlur.mock.calls.length).toBe(1);
|
|
||||||
expect(handlers.didBlur.mock.calls.length).toBe(0);
|
|
||||||
emitEvent({
|
|
||||||
type: 'action',
|
|
||||||
state: {
|
|
||||||
index: 0,
|
|
||||||
routes: [{ key: 'key0' }],
|
|
||||||
isTransitioning: false,
|
|
||||||
},
|
|
||||||
lastState: {
|
|
||||||
index: 0,
|
|
||||||
routes: [{ key: 'key0' }],
|
|
||||||
isTransitioning: true,
|
|
||||||
},
|
|
||||||
action: { type: 'Any action, does not matter here' },
|
|
||||||
});
|
|
||||||
expect(handlers.willFocus.mock.calls.length).toBe(1);
|
|
||||||
expect(handlers.didFocus.mock.calls.length).toBe(1);
|
|
||||||
expect(handlers.willBlur.mock.calls.length).toBe(1);
|
|
||||||
expect(handlers.didBlur.mock.calls.length).toBe(0);
|
|
||||||
});
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import getChildrenNavigationCache from '../getChildrenNavigationCache';
|
||||||
|
|
||||||
|
it('should return empty table if navigation arg not provided', () => {
|
||||||
|
expect(getChildrenNavigationCache()._childrenNavigation).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should populate navigation._childrenNavigation as a side-effect', () => {
|
||||||
|
const navigation = {
|
||||||
|
state: {
|
||||||
|
routes: [{ key: 'one' }],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = getChildrenNavigationCache(navigation);
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
expect(navigation._childrenNavigation).toBe(result);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should delete children cache keys that are no longer valid', () => {
|
||||||
|
const navigation = {
|
||||||
|
state: {
|
||||||
|
routes: [{ key: 'one' }, { key: 'two' }, { key: 'three' }],
|
||||||
|
},
|
||||||
|
_childrenNavigation: {
|
||||||
|
one: {},
|
||||||
|
two: {},
|
||||||
|
three: {},
|
||||||
|
four: {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = getChildrenNavigationCache(navigation);
|
||||||
|
expect(result).toEqual({
|
||||||
|
one: {},
|
||||||
|
two: {},
|
||||||
|
three: {},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not delete children cache keys if in transitioning state', () => {
|
||||||
|
const navigation = {
|
||||||
|
state: {
|
||||||
|
routes: [{ key: 'one' }, { key: 'two' }, { key: 'three' }],
|
||||||
|
isTransitioning: true,
|
||||||
|
},
|
||||||
|
_childrenNavigation: {
|
||||||
|
one: {},
|
||||||
|
two: {},
|
||||||
|
three: {},
|
||||||
|
four: {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = getChildrenNavigationCache(navigation);
|
||||||
|
expect(result).toEqual({
|
||||||
|
one: {},
|
||||||
|
two: {},
|
||||||
|
three: {},
|
||||||
|
four: {},
|
||||||
|
});
|
||||||
|
});
|
||||||
48
packages/core/src/__tests__/getEventManager.test.js
Normal file
48
packages/core/src/__tests__/getEventManager.test.js
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import getEventManager from '../getEventManager';
|
||||||
|
|
||||||
|
const TARGET = 'target';
|
||||||
|
|
||||||
|
it('calls listeners to emitted event', () => {
|
||||||
|
const eventManager = getEventManager(TARGET);
|
||||||
|
const callback = jest.fn();
|
||||||
|
eventManager.addListener('didFocus', callback);
|
||||||
|
|
||||||
|
eventManager.emit('didFocus');
|
||||||
|
|
||||||
|
expect(callback).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not call listeners connected to a different event', () => {
|
||||||
|
const eventManager = getEventManager(TARGET);
|
||||||
|
const callback = jest.fn();
|
||||||
|
eventManager.addListener('didFocus', callback);
|
||||||
|
|
||||||
|
eventManager.emit('didBlur');
|
||||||
|
|
||||||
|
expect(callback).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not call removed listeners', () => {
|
||||||
|
const eventManager = getEventManager(TARGET);
|
||||||
|
const callback = jest.fn();
|
||||||
|
const { remove } = eventManager.addListener('didFocus', callback);
|
||||||
|
|
||||||
|
eventManager.emit('didFocus');
|
||||||
|
expect(callback).toHaveBeenCalled();
|
||||||
|
|
||||||
|
remove();
|
||||||
|
|
||||||
|
eventManager.emit('didFocus');
|
||||||
|
expect(callback).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls the listeners with the given payload', () => {
|
||||||
|
const eventManager = getEventManager(TARGET);
|
||||||
|
const callback = jest.fn();
|
||||||
|
eventManager.addListener('didFocus', callback);
|
||||||
|
|
||||||
|
const payload = { foo: 0 };
|
||||||
|
eventManager.emit('didFocus', payload);
|
||||||
|
|
||||||
|
expect(callback).toHaveBeenCalledWith(payload);
|
||||||
|
});
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import getNavigation from '../getNavigation';
|
import getNavigation from '../getNavigation';
|
||||||
|
import * as NavigationActions from '../NavigationActions';
|
||||||
|
|
||||||
it('getNavigation provides default action helpers', () => {
|
it('getNavigation provides default action helpers', () => {
|
||||||
const router = {
|
const router = {
|
||||||
@@ -22,12 +23,11 @@ it('getNavigation provides default action helpers', () => {
|
|||||||
topNav.navigate('GreatRoute');
|
topNav.navigate('GreatRoute');
|
||||||
|
|
||||||
expect(dispatch.mock.calls.length).toBe(1);
|
expect(dispatch.mock.calls.length).toBe(1);
|
||||||
expect(dispatch.mock.calls[0][0].type).toBe('Navigation/NAVIGATE');
|
expect(dispatch.mock.calls[0][0].type).toBe(NavigationActions.NAVIGATE);
|
||||||
expect(dispatch.mock.calls[0][0].routeName).toBe('GreatRoute');
|
expect(dispatch.mock.calls[0][0].routeName).toBe('GreatRoute');
|
||||||
});
|
});
|
||||||
|
|
||||||
// eslint-disable-next-line jest/no-disabled-tests
|
it('getNavigation provides router action helpers', () => {
|
||||||
it.skip('getNavigation provides router action helpers', () => {
|
|
||||||
const router = {
|
const router = {
|
||||||
getActionCreators: () => ({
|
getActionCreators: () => ({
|
||||||
foo: (bar) => ({ type: 'FooBarAction', bar }),
|
foo: (bar) => ({ type: 'FooBarAction', bar }),
|
||||||
@@ -39,7 +39,8 @@ it.skip('getNavigation provides router action helpers', () => {
|
|||||||
|
|
||||||
const dispatch = jest.fn();
|
const dispatch = jest.fn();
|
||||||
|
|
||||||
const topNav = getNavigation(
|
let topNav;
|
||||||
|
topNav = getNavigation(
|
||||||
router,
|
router,
|
||||||
{},
|
{},
|
||||||
dispatch,
|
dispatch,
|
||||||
|
|||||||
@@ -1,196 +0,0 @@
|
|||||||
/*
|
|
||||||
* This is used to extract one children's worth of events from a stream of navigation action events
|
|
||||||
*
|
|
||||||
* Based on the 'action' events that get fired for this navigation state, this utility will fire
|
|
||||||
* focus and blur events for this child
|
|
||||||
*/
|
|
||||||
export default function getChildEventSubscriber(
|
|
||||||
addListener,
|
|
||||||
key,
|
|
||||||
initialLastFocusEvent = 'didBlur'
|
|
||||||
) {
|
|
||||||
const actionSubscribers = new Set();
|
|
||||||
const willFocusSubscribers = new Set();
|
|
||||||
const didFocusSubscribers = new Set();
|
|
||||||
const willBlurSubscribers = new Set();
|
|
||||||
const didBlurSubscribers = new Set();
|
|
||||||
const refocusSubscribers = new Set();
|
|
||||||
|
|
||||||
const removeAll = () => {
|
|
||||||
[
|
|
||||||
actionSubscribers,
|
|
||||||
willFocusSubscribers,
|
|
||||||
didFocusSubscribers,
|
|
||||||
willBlurSubscribers,
|
|
||||||
didBlurSubscribers,
|
|
||||||
refocusSubscribers,
|
|
||||||
].forEach((set) => set.clear());
|
|
||||||
|
|
||||||
upstreamSubscribers.forEach((subs) => subs && subs.remove());
|
|
||||||
};
|
|
||||||
|
|
||||||
const getChildSubscribers = (evtName) => {
|
|
||||||
switch (evtName) {
|
|
||||||
case 'action':
|
|
||||||
return actionSubscribers;
|
|
||||||
case 'willFocus':
|
|
||||||
return willFocusSubscribers;
|
|
||||||
case 'didFocus':
|
|
||||||
return didFocusSubscribers;
|
|
||||||
case 'willBlur':
|
|
||||||
return willBlurSubscribers;
|
|
||||||
case 'didBlur':
|
|
||||||
return didBlurSubscribers;
|
|
||||||
case 'refocus':
|
|
||||||
return refocusSubscribers;
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const emit = (type, payload) => {
|
|
||||||
const payloadWithType = { ...payload, type };
|
|
||||||
const subscribers = getChildSubscribers(type);
|
|
||||||
subscribers &&
|
|
||||||
subscribers.forEach((subs) => {
|
|
||||||
subs(payloadWithType);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// lastFocusEvent keeps track of focus state for one route. First we assume
|
|
||||||
// we are blurred. If we are focused on initialization, the first 'action'
|
|
||||||
// event will cause onFocus+willFocus events because we had previously been
|
|
||||||
// considered blurred
|
|
||||||
let lastFocusEvent = initialLastFocusEvent;
|
|
||||||
|
|
||||||
const upstreamEvents = [
|
|
||||||
'willFocus',
|
|
||||||
'didFocus',
|
|
||||||
'willBlur',
|
|
||||||
'didBlur',
|
|
||||||
'refocus',
|
|
||||||
'action',
|
|
||||||
];
|
|
||||||
|
|
||||||
const upstreamSubscribers = upstreamEvents.map((eventName) =>
|
|
||||||
addListener(eventName, (payload) => {
|
|
||||||
if (eventName === 'refocus') {
|
|
||||||
emit(eventName, payload);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { state, lastState, action } = payload;
|
|
||||||
const lastRoutes = lastState && lastState.routes;
|
|
||||||
const routes = state && state.routes;
|
|
||||||
|
|
||||||
// const lastFocusKey =
|
|
||||||
// lastState && lastState.routes && lastState.routes[lastState.index].key;
|
|
||||||
const focusKey = routes && routes[state.index].key;
|
|
||||||
|
|
||||||
const isChildFocused = focusKey === key;
|
|
||||||
const lastRoute =
|
|
||||||
lastRoutes && lastRoutes.find((route) => route.key === key);
|
|
||||||
const newRoute = routes && routes.find((route) => route.key === key);
|
|
||||||
const childPayload = {
|
|
||||||
context: `${key}:${action.type}_${payload.context || 'Root'}`,
|
|
||||||
state: newRoute,
|
|
||||||
lastState: lastRoute,
|
|
||||||
action,
|
|
||||||
type: eventName,
|
|
||||||
};
|
|
||||||
const isTransitioning = !!state && state.isTransitioning;
|
|
||||||
|
|
||||||
const previouslylastFocusEvent = lastFocusEvent;
|
|
||||||
|
|
||||||
if (lastFocusEvent === 'didBlur') {
|
|
||||||
// The child is currently blurred. Look for willFocus conditions
|
|
||||||
if (eventName === 'willFocus' && isChildFocused) {
|
|
||||||
emit((lastFocusEvent = 'willFocus'), childPayload);
|
|
||||||
} else if (eventName === 'action' && isChildFocused) {
|
|
||||||
emit((lastFocusEvent = 'willFocus'), childPayload);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lastFocusEvent === 'willFocus') {
|
|
||||||
// We are currently mid-focus. Look for didFocus conditions.
|
|
||||||
// If state.isTransitioning is false, this child event happens immediately after willFocus
|
|
||||||
if (eventName === 'didFocus' && isChildFocused && !isTransitioning) {
|
|
||||||
emit((lastFocusEvent = 'didFocus'), childPayload);
|
|
||||||
} else if (
|
|
||||||
eventName === 'action' &&
|
|
||||||
isChildFocused &&
|
|
||||||
!isTransitioning
|
|
||||||
) {
|
|
||||||
emit((lastFocusEvent = 'didFocus'), childPayload);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastFocusEvent === 'didFocus') {
|
|
||||||
// The child is currently focused. Look for blurring events
|
|
||||||
if (!isChildFocused) {
|
|
||||||
// The child is no longer focused within this navigation state
|
|
||||||
emit((lastFocusEvent = 'willBlur'), childPayload);
|
|
||||||
} else if (eventName === 'willBlur') {
|
|
||||||
// The parent is getting a willBlur event
|
|
||||||
emit((lastFocusEvent = 'willBlur'), childPayload);
|
|
||||||
} else if (
|
|
||||||
eventName === 'action' &&
|
|
||||||
previouslylastFocusEvent === 'didFocus'
|
|
||||||
) {
|
|
||||||
// While focused, pass action events to children for grandchildren focus
|
|
||||||
emit('action', childPayload);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastFocusEvent === 'willBlur') {
|
|
||||||
// The child is mid-blur. Wait for transition to end
|
|
||||||
if (eventName === 'action' && !isChildFocused && !isTransitioning) {
|
|
||||||
// The child is done blurring because transitioning is over, or isTransitioning
|
|
||||||
// never began and didBlur fires immediately after willBlur
|
|
||||||
emit((lastFocusEvent = 'didBlur'), childPayload);
|
|
||||||
} else if (eventName === 'didBlur') {
|
|
||||||
// Pass through the parent didBlur event if it happens
|
|
||||||
emit((lastFocusEvent = 'didBlur'), childPayload);
|
|
||||||
} else if (
|
|
||||||
eventName === 'action' &&
|
|
||||||
isChildFocused &&
|
|
||||||
!isTransitioning
|
|
||||||
) {
|
|
||||||
emit((lastFocusEvent = 'didFocus'), childPayload);
|
|
||||||
} else if (
|
|
||||||
eventName === 'action' &&
|
|
||||||
isChildFocused &&
|
|
||||||
isTransitioning
|
|
||||||
) {
|
|
||||||
emit((lastFocusEvent = 'willFocus'), childPayload);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastFocusEvent === 'didBlur' && !newRoute) {
|
|
||||||
removeAll();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
addListener(eventName, eventHandler) {
|
|
||||||
const subscribers = getChildSubscribers(eventName);
|
|
||||||
if (!subscribers) {
|
|
||||||
throw new Error(`Invalid event name "${eventName}"`);
|
|
||||||
}
|
|
||||||
subscribers.add(eventHandler);
|
|
||||||
const remove = () => {
|
|
||||||
subscribers.delete(eventHandler);
|
|
||||||
};
|
|
||||||
return { remove };
|
|
||||||
},
|
|
||||||
emit(eventName, payload) {
|
|
||||||
if (eventName !== 'refocus') {
|
|
||||||
console.error(
|
|
||||||
`navigation.emit only supports the 'refocus' event currently.`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
emit(eventName, payload);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import getChildEventSubscriber from './getChildEventSubscriber';
|
|
||||||
import getChildRouter from './getChildRouter';
|
import getChildRouter from './getChildRouter';
|
||||||
import getNavigationActionCreators from './routers/getNavigationActionCreators';
|
import getNavigationActionCreators from './routers/getNavigationActionCreators';
|
||||||
import getChildrenNavigationCache from './getChildrenNavigationCache';
|
import getChildrenNavigationCache from './getChildrenNavigationCache';
|
||||||
|
import getEventManager from './getEventManager';
|
||||||
|
|
||||||
const createParamGetter = (route) => (paramName, defaultValue) => {
|
const createParamGetter = (route) => (paramName, defaultValue) => {
|
||||||
const params = route.params;
|
const params = route.params;
|
||||||
@@ -78,10 +78,7 @@ function getChildNavigation(navigation, childKey, getCurrentParentNavigation) {
|
|||||||
};
|
};
|
||||||
return children[childKey];
|
return children[childKey];
|
||||||
} else {
|
} else {
|
||||||
const childSubscriber = getChildEventSubscriber(
|
const { addListener, emit } = getEventManager(childKey);
|
||||||
navigation.addListener,
|
|
||||||
childKey
|
|
||||||
);
|
|
||||||
|
|
||||||
children[childKey] = {
|
children[childKey] = {
|
||||||
...actionHelpers,
|
...actionHelpers,
|
||||||
@@ -115,9 +112,10 @@ function getChildNavigation(navigation, childKey, getCurrentParentNavigation) {
|
|||||||
dispatch: navigation.dispatch,
|
dispatch: navigation.dispatch,
|
||||||
getScreenProps: navigation.getScreenProps,
|
getScreenProps: navigation.getScreenProps,
|
||||||
dangerouslyGetParent: getCurrentParentNavigation,
|
dangerouslyGetParent: getCurrentParentNavigation,
|
||||||
addListener: childSubscriber.addListener,
|
addListener,
|
||||||
emit: childSubscriber.emit,
|
emit,
|
||||||
};
|
};
|
||||||
|
|
||||||
return children[childKey];
|
return children[childKey];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default function getChildRouter(router: any, routeName: string) {
|
export default function getChildRouter(router: any, routeName: string) {
|
||||||
if (router.childRouters && router.childRouters[routeName]) {
|
if (router.childRouters?.[routeName]) {
|
||||||
return router.childRouters[routeName];
|
return router.childRouters[routeName];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
61
packages/core/src/getEventManager.js
Normal file
61
packages/core/src/getEventManager.js
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} target
|
||||||
|
*/
|
||||||
|
export default function getEventManager(target) {
|
||||||
|
/**
|
||||||
|
* @type {Record<string, Record<string, ((e: any) => void)[]>>}
|
||||||
|
*/
|
||||||
|
const listeners = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} type
|
||||||
|
* @param {() => void} callback
|
||||||
|
*/
|
||||||
|
const removeListener = (type, callback) => {
|
||||||
|
const callbacks = listeners[type] ? listeners[type][target] : undefined;
|
||||||
|
|
||||||
|
if (!callbacks) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const index = callbacks.indexOf(callback);
|
||||||
|
|
||||||
|
callbacks.splice(index, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} type
|
||||||
|
* @param {() => void} callback
|
||||||
|
*/
|
||||||
|
const addListener = (type, callback) => {
|
||||||
|
listeners[type] = listeners[type] || {};
|
||||||
|
listeners[type][target] = listeners[type][target] || [];
|
||||||
|
listeners[type][target].push(callback);
|
||||||
|
|
||||||
|
return {
|
||||||
|
remove: () => removeListener(type, callback),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
addListener,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} type
|
||||||
|
* @param {any} [data]
|
||||||
|
*/
|
||||||
|
emit: (type, data) => {
|
||||||
|
const items = listeners[type] || {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy the current list of callbacks in case they are mutated during execution
|
||||||
|
* @type {((data: any) => void)[] | undefined}
|
||||||
|
*/
|
||||||
|
const callbacks = items[target] && items[target].slice();
|
||||||
|
|
||||||
|
callbacks?.forEach((cb) => cb(data));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import invariant from '../utils/invariant';
|
import invariant from '../utils/invariant';
|
||||||
import ThemeContext from '../views/ThemeContext';
|
import ThemeContext from '../views/ThemeContext';
|
||||||
|
import NavigationFocusEvents from '../views/NavigationFocusEvents';
|
||||||
|
|
||||||
function createNavigator(NavigatorView, router, navigationConfig) {
|
function createNavigator(NavigatorView, router, navigationConfig) {
|
||||||
class Navigator extends React.Component {
|
class Navigator extends React.Component {
|
||||||
@@ -35,7 +36,7 @@ function createNavigator(NavigatorView, router, navigationConfig) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const descriptors = routes.reduce((acc, route) => {
|
const descriptors = routes.reduce((descriptors, route) => {
|
||||||
if (
|
if (
|
||||||
prevDescriptors &&
|
prevDescriptors &&
|
||||||
prevDescriptors[route.key] &&
|
prevDescriptors[route.key] &&
|
||||||
@@ -43,8 +44,8 @@ function createNavigator(NavigatorView, router, navigationConfig) {
|
|||||||
screenProps === currentState.screenProps &&
|
screenProps === currentState.screenProps &&
|
||||||
currentState.themeContext === currentState.theme
|
currentState.themeContext === currentState.theme
|
||||||
) {
|
) {
|
||||||
acc[route.key] = prevDescriptors[route.key];
|
descriptors[route.key] = prevDescriptors[route.key];
|
||||||
return acc;
|
return descriptors;
|
||||||
}
|
}
|
||||||
const getComponent = router.getComponentForRouteName.bind(
|
const getComponent = router.getComponentForRouteName.bind(
|
||||||
null,
|
null,
|
||||||
@@ -56,14 +57,14 @@ function createNavigator(NavigatorView, router, navigationConfig) {
|
|||||||
screenProps,
|
screenProps,
|
||||||
currentState.themeContext
|
currentState.themeContext
|
||||||
);
|
);
|
||||||
acc[route.key] = {
|
descriptors[route.key] = {
|
||||||
key: route.key,
|
key: route.key,
|
||||||
getComponent,
|
getComponent,
|
||||||
options,
|
options,
|
||||||
state: route,
|
state: route,
|
||||||
navigation: childNavigation,
|
navigation: childNavigation,
|
||||||
};
|
};
|
||||||
return acc;
|
return descriptors;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
return { descriptors, screenProps, theme: state.themeContext };
|
return { descriptors, screenProps, theme: state.themeContext };
|
||||||
@@ -78,13 +79,21 @@ function createNavigator(NavigatorView, router, navigationConfig) {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<NavigatorView
|
<React.Fragment>
|
||||||
{...this.props}
|
<NavigationFocusEvents
|
||||||
screenProps={this.state.screenProps}
|
navigation={this.props.navigation}
|
||||||
navigation={this.props.navigation}
|
onEvent={(target, type, data) => {
|
||||||
navigationConfig={navigationConfig}
|
this.state.descriptors[target]?.navigation.emit(type, data);
|
||||||
descriptors={this.state.descriptors}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<NavigatorView
|
||||||
|
{...this.props}
|
||||||
|
screenProps={this.state.screenProps}
|
||||||
|
navigation={this.props.navigation}
|
||||||
|
navigationConfig={navigationConfig}
|
||||||
|
descriptors={this.state.descriptors}
|
||||||
|
/>
|
||||||
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -536,18 +536,21 @@ export default (routeConfigs, stackConfig = {}) => {
|
|||||||
|
|
||||||
if (action.type === StackActions.POP && prune === false && key) {
|
if (action.type === StackActions.POP && prune === false && key) {
|
||||||
const index = state.routes.findIndex((r) => r.key === key);
|
const index = state.routes.findIndex((r) => r.key === key);
|
||||||
const count = Math.max(index - (n == null ? 1 : n) + 1, 1);
|
|
||||||
const routes = state.routes
|
|
||||||
.slice(0, count)
|
|
||||||
.concat(state.routes.slice(index + 1));
|
|
||||||
|
|
||||||
if (routes.length) {
|
if (index > 0) {
|
||||||
return {
|
const count = Math.max(index - (n ?? 1) + 1, 1);
|
||||||
...state,
|
const routes = state.routes
|
||||||
routes,
|
.slice(0, count)
|
||||||
index: routes.length - 1,
|
.concat(state.routes.slice(index + 1));
|
||||||
isTransitioning: immediate !== true,
|
|
||||||
};
|
if (routes.length) {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
routes,
|
||||||
|
index: routes.length - 1,
|
||||||
|
isTransitioning: immediate !== true,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let backRouteIndex = state.index;
|
let backRouteIndex = state.index;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export default (routeConfigs, config = {}) => {
|
|||||||
const getCustomActionCreators =
|
const getCustomActionCreators =
|
||||||
config.getCustomActionCreators || defaultActionCreators;
|
config.getCustomActionCreators || defaultActionCreators;
|
||||||
|
|
||||||
const initialRouteParams = config.initialRouteParams;
|
const { initialRouteParams } = config;
|
||||||
const initialRouteName = config.initialRouteName || order[0];
|
const initialRouteName = config.initialRouteName || order[0];
|
||||||
const backBehavior = config.backBehavior || 'none';
|
const backBehavior = config.backBehavior || 'none';
|
||||||
const resetOnBlur = config.hasOwnProperty('resetOnBlur')
|
const resetOnBlur = config.hasOwnProperty('resetOnBlur')
|
||||||
@@ -59,7 +59,7 @@ export default (routeConfigs, config = {}) => {
|
|||||||
|
|
||||||
function resetChildRoute(routeName) {
|
function resetChildRoute(routeName) {
|
||||||
let initialParams =
|
let initialParams =
|
||||||
routeName === initialRouteName ? initialRouteParams : undefined;
|
routeName === initialRouteName ? initialRouteParams : null;
|
||||||
// note(brentvatne): merging initialRouteParams *on top* of default params
|
// note(brentvatne): merging initialRouteParams *on top* of default params
|
||||||
// on the route seems incorrect but it's consistent with existing behavior
|
// on the route seems incorrect but it's consistent with existing behavior
|
||||||
// in stackrouter
|
// in stackrouter
|
||||||
@@ -71,13 +71,13 @@ export default (routeConfigs, config = {}) => {
|
|||||||
...childRouter.getStateForAction(childAction),
|
...childRouter.getStateForAction(childAction),
|
||||||
key: routeName,
|
key: routeName,
|
||||||
routeName,
|
routeName,
|
||||||
params,
|
...(params ? { params } : {}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
key: routeName,
|
key: routeName,
|
||||||
routeName,
|
routeName,
|
||||||
params,
|
...(params ? { params } : {}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,8 +128,8 @@ export default (routeConfigs, config = {}) => {
|
|||||||
const initialState = {
|
const initialState = {
|
||||||
routes,
|
routes,
|
||||||
index: initialRouteIndex,
|
index: initialRouteIndex,
|
||||||
isTransitioning: false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (backBehavior === 'history') {
|
if (backBehavior === 'history') {
|
||||||
const initialKey = routes[initialRouteIndex].key;
|
const initialKey = routes[initialRouteIndex].key;
|
||||||
initialState['routeKeyHistory'] = [initialKey];
|
initialState['routeKeyHistory'] = [initialKey];
|
||||||
|
|||||||
12
packages/core/src/routers/__tests__/KeyGenerator.test.js
Normal file
12
packages/core/src/routers/__tests__/KeyGenerator.test.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { _TESTING_ONLY_normalize_keys, generateKey } from '../KeyGenerator';
|
||||||
|
|
||||||
|
it('should generate a new string key when called', () => {
|
||||||
|
_TESTING_ONLY_normalize_keys();
|
||||||
|
|
||||||
|
expect(generateKey()).toBe('id-0');
|
||||||
|
expect(generateKey()).toBe('id-1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should generate unique string keys without being normalized', () => {
|
||||||
|
expect(generateKey()).not.toBe(generateKey());
|
||||||
|
});
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/* eslint no-shadow:0, react/no-multi-comp:0, react/display-name:0 */
|
/* eslint no-shadow:0, react/no-multi-comp:0, react/display-name:0 */
|
||||||
|
|
||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import SwitchRouter from '../SwitchRouter';
|
import SwitchRouter from '../SwitchRouter';
|
||||||
import StackRouter from '../StackRouter';
|
import StackRouter from '../StackRouter';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* eslint react/no-multi-comp:0, react/display-name:0 */
|
/* eslint react/no-multi-comp:0, react/display-name:0 */
|
||||||
|
|
||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import StackRouter from '../StackRouter';
|
import StackRouter from '../StackRouter';
|
||||||
import TabRouter from '../TabRouter';
|
import TabRouter from '../TabRouter';
|
||||||
@@ -114,6 +114,51 @@ Object.keys(ROUTERS).forEach((routerName) => {
|
|||||||
);
|
);
|
||||||
expect(state0.routes[state0.index].params.foo).toEqual(42);
|
expect(state0.routes[state0.index].params.foo).toEqual(42);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('merges existing params when set params on existing state', () => {
|
||||||
|
const Screen = () => <div />;
|
||||||
|
|
||||||
|
const router = Router({
|
||||||
|
Foo: {
|
||||||
|
screen: Screen,
|
||||||
|
params: { a: 1 },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const key = 'Foo';
|
||||||
|
const state = router.getStateForAction({
|
||||||
|
type: NavigationActions.INIT,
|
||||||
|
key,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(state).toMatchObject({
|
||||||
|
index: 0,
|
||||||
|
routes: [{ key, params: { a: 1 } }],
|
||||||
|
});
|
||||||
|
|
||||||
|
const newState = router.getStateForAction(
|
||||||
|
NavigationActions.setParams({ key, params: { b: 2 } }),
|
||||||
|
state
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(newState.routes[newState.index].params).toEqual({ a: 1, b: 2 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('merges params when setting params during init', () => {
|
||||||
|
const Screen = () => <div />;
|
||||||
|
|
||||||
|
const router = Router({
|
||||||
|
Foo: {
|
||||||
|
screen: Screen,
|
||||||
|
params: { a: 1 },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const newState = router.getStateForAction(
|
||||||
|
NavigationActions.setParams({ key: 'Foo', params: { b: 2 } })
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(newState.routes[newState.index].params).toEqual({ a: 1, b: 2 });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* eslint no-shadow:0, react/no-multi-comp:0, react/display-name:0 */
|
/* eslint no-shadow:0, react/no-multi-comp:0, react/display-name:0 */
|
||||||
|
|
||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import StackRouter from '../StackRouter';
|
import StackRouter from '../StackRouter';
|
||||||
import * as StackActions from '../StackActions';
|
import * as StackActions from '../StackActions';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* eslint react/display-name:0 */
|
/* eslint react/display-name:0 */
|
||||||
|
|
||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import SwitchRouter from '../SwitchRouter';
|
import SwitchRouter from '../SwitchRouter';
|
||||||
import StackRouter from '../StackRouter';
|
import StackRouter from '../StackRouter';
|
||||||
import * as NavigationActions from '../../NavigationActions';
|
import * as NavigationActions from '../../NavigationActions';
|
||||||
@@ -158,7 +158,7 @@ describe('SwitchRouter', () => {
|
|||||||
expect(getSubState(1).routeName).toEqual('A');
|
expect(getSubState(1).routeName).toEqual('A');
|
||||||
|
|
||||||
// The back action should not switch to B. It should stay on A
|
// The back action should not switch to B. It should stay on A
|
||||||
back({ key: null });
|
back(null);
|
||||||
expect(getSubState(1).routeName).toEqual('A');
|
expect(getSubState(1).routeName).toEqual('A');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* eslint react/display-name:0 */
|
/* eslint react/display-name:0 */
|
||||||
|
|
||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import TabRouter from '../TabRouter';
|
import TabRouter from '../TabRouter';
|
||||||
|
|
||||||
import * as NavigationActions from '../../NavigationActions';
|
import * as NavigationActions from '../../NavigationActions';
|
||||||
@@ -26,7 +26,6 @@ describe('TabRouter', () => {
|
|||||||
{ key: 'Foo', routeName: 'Foo' },
|
{ key: 'Foo', routeName: 'Foo' },
|
||||||
{ key: 'Bar', routeName: 'Bar' },
|
{ key: 'Bar', routeName: 'Bar' },
|
||||||
],
|
],
|
||||||
isTransitioning: false,
|
|
||||||
};
|
};
|
||||||
expect(state).toEqual(expectedState);
|
expect(state).toEqual(expectedState);
|
||||||
const state2 = router.getStateForAction(
|
const state2 = router.getStateForAction(
|
||||||
@@ -39,7 +38,6 @@ describe('TabRouter', () => {
|
|||||||
{ key: 'Foo', routeName: 'Foo' },
|
{ key: 'Foo', routeName: 'Foo' },
|
||||||
{ key: 'Bar', routeName: 'Bar' },
|
{ key: 'Bar', routeName: 'Bar' },
|
||||||
],
|
],
|
||||||
isTransitioning: false,
|
|
||||||
};
|
};
|
||||||
expect(state2).toEqual(expectedState2);
|
expect(state2).toEqual(expectedState2);
|
||||||
expect(router.getComponentForState(expectedState)).toEqual(ScreenA);
|
expect(router.getComponentForState(expectedState)).toEqual(ScreenA);
|
||||||
@@ -65,7 +63,6 @@ describe('TabRouter', () => {
|
|||||||
{ key: 'Foo', routeName: 'Foo' },
|
{ key: 'Foo', routeName: 'Foo' },
|
||||||
{ key: 'Bar', routeName: 'Bar' },
|
{ key: 'Bar', routeName: 'Bar' },
|
||||||
],
|
],
|
||||||
isTransitioning: false,
|
|
||||||
};
|
};
|
||||||
expect(state).toEqual(expectedState);
|
expect(state).toEqual(expectedState);
|
||||||
const state2 = router.getStateForAction(
|
const state2 = router.getStateForAction(
|
||||||
@@ -78,7 +75,6 @@ describe('TabRouter', () => {
|
|||||||
{ key: 'Foo', routeName: 'Foo' },
|
{ key: 'Foo', routeName: 'Foo' },
|
||||||
{ key: 'Bar', routeName: 'Bar' },
|
{ key: 'Bar', routeName: 'Bar' },
|
||||||
],
|
],
|
||||||
isTransitioning: false,
|
|
||||||
};
|
};
|
||||||
expect(state2).toEqual(expectedState2);
|
expect(state2).toEqual(expectedState2);
|
||||||
expect(router.getComponentForState(expectedState)).toEqual(ScreenA);
|
expect(router.getComponentForState(expectedState)).toEqual(ScreenA);
|
||||||
@@ -102,7 +98,6 @@ describe('TabRouter', () => {
|
|||||||
{ key: 'Foo', routeName: 'Foo' },
|
{ key: 'Foo', routeName: 'Foo' },
|
||||||
{ key: 'Bar', routeName: 'Bar' },
|
{ key: 'Bar', routeName: 'Bar' },
|
||||||
],
|
],
|
||||||
isTransitioning: false,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -118,7 +113,6 @@ describe('TabRouter', () => {
|
|||||||
{ key: 'Foo', routeName: 'Foo' },
|
{ key: 'Foo', routeName: 'Foo' },
|
||||||
{ key: 'Bar', routeName: 'Bar', params: { name: 'Qux' } },
|
{ key: 'Bar', routeName: 'Bar', params: { name: 'Qux' } },
|
||||||
],
|
],
|
||||||
isTransitioning: false,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -230,7 +224,7 @@ describe('TabRouter', () => {
|
|||||||
const state = router.getStateForAction(navAction);
|
const state = router.getStateForAction(navAction);
|
||||||
expect(state).toEqual({
|
expect(state).toEqual({
|
||||||
index: 1,
|
index: 1,
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
key: 'Foo',
|
key: 'Foo',
|
||||||
@@ -238,7 +232,7 @@ describe('TabRouter', () => {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
index: 1,
|
index: 1,
|
||||||
isTransitioning: false,
|
|
||||||
key: 'Baz',
|
key: 'Baz',
|
||||||
routeName: 'Baz',
|
routeName: 'Baz',
|
||||||
params: { foo: '42' },
|
params: { foo: '42' },
|
||||||
@@ -281,14 +275,14 @@ describe('TabRouter', () => {
|
|||||||
let state = router.getStateForAction(navAction);
|
let state = router.getStateForAction(navAction);
|
||||||
expect(state).toEqual({
|
expect(state).toEqual({
|
||||||
index: 1,
|
index: 1,
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'Foo', routeName: 'Foo' },
|
{ key: 'Foo', routeName: 'Foo' },
|
||||||
{
|
{
|
||||||
index: 0,
|
index: 0,
|
||||||
key: 'Baz',
|
key: 'Baz',
|
||||||
routeName: 'Baz',
|
routeName: 'Baz',
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'Boo', routeName: 'Boo' },
|
{ key: 'Boo', routeName: 'Boo' },
|
||||||
{ key: 'Bar', routeName: 'Bar' },
|
{ key: 'Bar', routeName: 'Bar' },
|
||||||
@@ -308,7 +302,7 @@ describe('TabRouter', () => {
|
|||||||
);
|
);
|
||||||
expect(state && state.routes[1]).toEqual({
|
expect(state && state.routes[1]).toEqual({
|
||||||
index: 0,
|
index: 0,
|
||||||
isTransitioning: false,
|
|
||||||
key: 'Baz',
|
key: 'Baz',
|
||||||
routeName: 'Baz',
|
routeName: 'Baz',
|
||||||
routes: [
|
routes: [
|
||||||
@@ -335,14 +329,14 @@ describe('TabRouter', () => {
|
|||||||
});
|
});
|
||||||
expect(state).toEqual({
|
expect(state).toEqual({
|
||||||
index: 1,
|
index: 1,
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'Foo', routeName: 'Foo' },
|
{ key: 'Foo', routeName: 'Foo' },
|
||||||
{
|
{
|
||||||
index: 1,
|
index: 1,
|
||||||
key: 'Baz',
|
key: 'Baz',
|
||||||
routeName: 'Baz',
|
routeName: 'Baz',
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'Foo', routeName: 'Foo' },
|
{ key: 'Foo', routeName: 'Foo' },
|
||||||
{ key: 'Bar', routeName: 'Bar' },
|
{ key: 'Bar', routeName: 'Bar' },
|
||||||
@@ -357,14 +351,14 @@ describe('TabRouter', () => {
|
|||||||
);
|
);
|
||||||
expect(state2).toEqual({
|
expect(state2).toEqual({
|
||||||
index: 1,
|
index: 1,
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'Foo', routeName: 'Foo' },
|
{ key: 'Foo', routeName: 'Foo' },
|
||||||
{
|
{
|
||||||
index: 0,
|
index: 0,
|
||||||
key: 'Baz',
|
key: 'Baz',
|
||||||
routeName: 'Baz',
|
routeName: 'Baz',
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'Foo', routeName: 'Foo' },
|
{ key: 'Foo', routeName: 'Foo' },
|
||||||
{ key: 'Bar', routeName: 'Bar' },
|
{ key: 'Bar', routeName: 'Bar' },
|
||||||
@@ -403,19 +397,19 @@ describe('TabRouter', () => {
|
|||||||
const state = router.getStateForAction(INIT_ACTION);
|
const state = router.getStateForAction(INIT_ACTION);
|
||||||
expect(state).toEqual({
|
expect(state).toEqual({
|
||||||
index: 0,
|
index: 0,
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
index: 0,
|
index: 0,
|
||||||
key: 'Foo',
|
key: 'Foo',
|
||||||
routeName: 'Foo',
|
routeName: 'Foo',
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
index: 0,
|
index: 0,
|
||||||
key: 'Fee',
|
key: 'Fee',
|
||||||
routeName: 'Fee',
|
routeName: 'Fee',
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'Boo', routeName: 'Boo' },
|
{ key: 'Boo', routeName: 'Boo' },
|
||||||
{ key: 'Baz', routeName: 'Baz' },
|
{ key: 'Baz', routeName: 'Baz' },
|
||||||
@@ -425,7 +419,7 @@ describe('TabRouter', () => {
|
|||||||
index: 0,
|
index: 0,
|
||||||
key: 'Bar',
|
key: 'Bar',
|
||||||
routeName: 'Bar',
|
routeName: 'Bar',
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'Zoo', routeName: 'Zoo' },
|
{ key: 'Zoo', routeName: 'Zoo' },
|
||||||
{ key: 'Zap', routeName: 'Zap' },
|
{ key: 'Zap', routeName: 'Zap' },
|
||||||
@@ -442,19 +436,19 @@ describe('TabRouter', () => {
|
|||||||
);
|
);
|
||||||
expect(state2).toEqual({
|
expect(state2).toEqual({
|
||||||
index: 0,
|
index: 0,
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
index: 1,
|
index: 1,
|
||||||
key: 'Foo',
|
key: 'Foo',
|
||||||
routeName: 'Foo',
|
routeName: 'Foo',
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
index: 0,
|
index: 0,
|
||||||
key: 'Fee',
|
key: 'Fee',
|
||||||
routeName: 'Fee',
|
routeName: 'Fee',
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'Boo', routeName: 'Boo' },
|
{ key: 'Boo', routeName: 'Boo' },
|
||||||
{ key: 'Baz', routeName: 'Baz' },
|
{ key: 'Baz', routeName: 'Baz' },
|
||||||
@@ -464,7 +458,7 @@ describe('TabRouter', () => {
|
|||||||
index: 1,
|
index: 1,
|
||||||
key: 'Bar',
|
key: 'Bar',
|
||||||
routeName: 'Bar',
|
routeName: 'Bar',
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'Zoo', routeName: 'Zoo' },
|
{ key: 'Zoo', routeName: 'Zoo' },
|
||||||
{ key: 'Zap', routeName: 'Zap' },
|
{ key: 'Zap', routeName: 'Zap' },
|
||||||
@@ -494,19 +488,19 @@ describe('TabRouter', () => {
|
|||||||
});
|
});
|
||||||
expect(state4).toEqual({
|
expect(state4).toEqual({
|
||||||
index: 0,
|
index: 0,
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
index: 1,
|
index: 1,
|
||||||
key: 'Foo',
|
key: 'Foo',
|
||||||
routeName: 'Foo',
|
routeName: 'Foo',
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
index: 0,
|
index: 0,
|
||||||
key: 'Fee',
|
key: 'Fee',
|
||||||
routeName: 'Fee',
|
routeName: 'Fee',
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'Boo', routeName: 'Boo' },
|
{ key: 'Boo', routeName: 'Boo' },
|
||||||
{ key: 'Baz', routeName: 'Baz' },
|
{ key: 'Baz', routeName: 'Baz' },
|
||||||
@@ -516,7 +510,7 @@ describe('TabRouter', () => {
|
|||||||
index: 1,
|
index: 1,
|
||||||
key: 'Bar',
|
key: 'Bar',
|
||||||
routeName: 'Bar',
|
routeName: 'Bar',
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'Zoo', routeName: 'Zoo' },
|
{ key: 'Zoo', routeName: 'Zoo' },
|
||||||
{ key: 'Zap', routeName: 'Zap' },
|
{ key: 'Zap', routeName: 'Zap' },
|
||||||
@@ -557,7 +551,7 @@ describe('TabRouter', () => {
|
|||||||
const state = router.getStateForAction({ type: NavigationActions.INIT });
|
const state = router.getStateForAction({ type: NavigationActions.INIT });
|
||||||
const expectedState = {
|
const expectedState = {
|
||||||
index: 0,
|
index: 0,
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'Foo', routeName: 'Foo' },
|
{ key: 'Foo', routeName: 'Foo' },
|
||||||
{ key: 'Bar', routeName: 'Bar' },
|
{ key: 'Bar', routeName: 'Bar' },
|
||||||
@@ -567,7 +561,7 @@ describe('TabRouter', () => {
|
|||||||
const state2 = router.getStateForAction(expectedAction, state);
|
const state2 = router.getStateForAction(expectedAction, state);
|
||||||
const expectedState2 = {
|
const expectedState2 = {
|
||||||
index: 1,
|
index: 1,
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'Foo', routeName: 'Foo', params: undefined },
|
{ key: 'Foo', routeName: 'Foo', params: undefined },
|
||||||
{
|
{
|
||||||
@@ -628,13 +622,13 @@ describe('TabRouter', () => {
|
|||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
index: 0,
|
index: 0,
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
index: 1,
|
index: 1,
|
||||||
key: 'Foo',
|
key: 'Foo',
|
||||||
routeName: 'Foo',
|
routeName: 'Foo',
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'Boo', routeName: 'Boo' },
|
{ key: 'Boo', routeName: 'Boo' },
|
||||||
{ key: 'Baz', routeName: 'Baz' },
|
{ key: 'Baz', routeName: 'Baz' },
|
||||||
@@ -660,7 +654,7 @@ describe('TabRouter', () => {
|
|||||||
|
|
||||||
expect(state0).toEqual({
|
expect(state0).toEqual({
|
||||||
index: 0,
|
index: 0,
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'a', routeName: 'a' },
|
{ key: 'a', routeName: 'a' },
|
||||||
{ key: 'b', routeName: 'b' },
|
{ key: 'b', routeName: 'b' },
|
||||||
@@ -676,7 +670,7 @@ describe('TabRouter', () => {
|
|||||||
|
|
||||||
expect(state1).toEqual({
|
expect(state1).toEqual({
|
||||||
index: 1,
|
index: 1,
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'a', routeName: 'a' },
|
{ key: 'a', routeName: 'a' },
|
||||||
{ key: 'b', routeName: 'b', params },
|
{ key: 'b', routeName: 'b', params },
|
||||||
@@ -765,13 +759,13 @@ describe('TabRouter', () => {
|
|||||||
const screenApreState = {
|
const screenApreState = {
|
||||||
index: 0,
|
index: 0,
|
||||||
key: 'Foo',
|
key: 'Foo',
|
||||||
isTransitioning: false,
|
|
||||||
routeName: 'Foo',
|
routeName: 'Foo',
|
||||||
routes: [{ key: 'Bar', routeName: 'Bar' }],
|
routes: [{ key: 'Bar', routeName: 'Bar' }],
|
||||||
};
|
};
|
||||||
const preState = {
|
const preState = {
|
||||||
index: 0,
|
index: 0,
|
||||||
isTransitioning: false,
|
|
||||||
routes: [screenApreState],
|
routes: [screenApreState],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import validateRouteConfigMap from '../validateRouteConfigMap';
|
import validateRouteConfigMap from '../validateRouteConfigMap';
|
||||||
import StackRouter from '../StackRouter';
|
import StackRouter from '../StackRouter';
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
export default function docsUrl(path: string) {
|
export default function docsUrl(path: string) {
|
||||||
return `https://reactnavigation.org/docs/${path}`;
|
return `https://reactnavigation.org/docs/4.x/${path}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import withNavigation from './withNavigation';
|
import withNavigation from './withNavigation';
|
||||||
|
|
||||||
const EventNameToPropName = {
|
const EventNameToPropName = {
|
||||||
@@ -12,11 +12,28 @@ const EventNames = Object.keys(EventNameToPropName);
|
|||||||
|
|
||||||
class NavigationEvents extends React.Component {
|
class NavigationEvents extends React.Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.subscriptions = {};
|
|
||||||
|
|
||||||
// We register all navigation listeners on mount to ensure listener stability across re-render
|
// We register all navigation listeners on mount to ensure listener stability across re-render
|
||||||
// A former implementation was replacing (removing/adding) listeners on all update (if prop provided)
|
// A former implementation was replacing (removing/adding) listeners on all update (if prop provided)
|
||||||
// but there were issues (see https://github.com/react-navigation/react-navigation/issues/5058)
|
// but there were issues (see https://github.com/react-navigation/react-navigation/issues/5058)
|
||||||
|
this.subscribeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps) {
|
||||||
|
if (this.props.navigation !== prevProps.navigation) {
|
||||||
|
this.removeAll();
|
||||||
|
this.subscribeAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.removeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
getPropListener = (eventName) => this.props[EventNameToPropName[eventName]];
|
||||||
|
|
||||||
|
subscribeAll() {
|
||||||
|
this.subscriptions = {};
|
||||||
|
|
||||||
EventNames.forEach((eventName) => {
|
EventNames.forEach((eventName) => {
|
||||||
this.subscriptions[eventName] = this.props.navigation.addListener(
|
this.subscriptions[eventName] = this.props.navigation.addListener(
|
||||||
eventName,
|
eventName,
|
||||||
@@ -28,14 +45,12 @@ class NavigationEvents extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
removeAll() {
|
||||||
EventNames.forEach((eventName) => {
|
EventNames.forEach((eventName) => {
|
||||||
this.subscriptions[eventName].remove();
|
this.subscriptions[eventName].remove();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getPropListener = (eventName) => this.props[EventNameToPropName[eventName]];
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
360
packages/core/src/views/NavigationFocusEvents.js
Normal file
360
packages/core/src/views/NavigationFocusEvents.js
Normal file
@@ -0,0 +1,360 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} State
|
||||||
|
* @prop {number} index
|
||||||
|
* @prop {({ key: string } & (State | {}))[]} routes
|
||||||
|
* @prop {boolean} [isTransitioning]
|
||||||
|
*
|
||||||
|
* @typedef {object} ParentPayload
|
||||||
|
* @prop {string} type
|
||||||
|
* @prop {object} action
|
||||||
|
* @prop {State} state
|
||||||
|
* @prop {State | {key: string, routes?: undefined, index?: undefined, isTransitioning?: undefined} | undefined | null} lastState
|
||||||
|
* @prop {string} [context]
|
||||||
|
*
|
||||||
|
* @typedef {object} Payload
|
||||||
|
* @prop {string} type
|
||||||
|
* @prop {object} action
|
||||||
|
* @prop {State | {key: string}} state
|
||||||
|
* @prop {State | {key: string} | undefined | null} lastState
|
||||||
|
* @prop {string} [context]
|
||||||
|
*
|
||||||
|
* @typedef {object} Props
|
||||||
|
* @prop {object} navigation
|
||||||
|
* @prop {Function} navigation.addListener
|
||||||
|
* @prop {Function} navigation.removeListener
|
||||||
|
* @prop {() => boolean} navigation.isFocused
|
||||||
|
* @prop {() => object | undefined} navigation.dangerouslyGetParent
|
||||||
|
* @prop {State} navigation.state
|
||||||
|
* @prop {(target: string, type: string, data: any) => void} onEvent
|
||||||
|
*
|
||||||
|
* @extends {React.Component<Props>}
|
||||||
|
*/
|
||||||
|
export default class NavigationEventManager extends React.Component {
|
||||||
|
componentDidMount() {
|
||||||
|
const { navigation } = this.props;
|
||||||
|
|
||||||
|
this._actionSubscription = navigation.addListener(
|
||||||
|
'action',
|
||||||
|
this._handleAction
|
||||||
|
);
|
||||||
|
|
||||||
|
this._willFocusSubscription = navigation.addListener(
|
||||||
|
'willFocus',
|
||||||
|
this._handleWillFocus
|
||||||
|
);
|
||||||
|
|
||||||
|
this._willBlurSubscription = navigation.addListener(
|
||||||
|
'willBlur',
|
||||||
|
this._handleWillBlur
|
||||||
|
);
|
||||||
|
|
||||||
|
this._didFocusSubscription = navigation.addListener(
|
||||||
|
'didFocus',
|
||||||
|
this._handleDidFocus
|
||||||
|
);
|
||||||
|
|
||||||
|
this._didBlurSubscription = navigation.addListener(
|
||||||
|
'didBlur',
|
||||||
|
this._handleDidBlur
|
||||||
|
);
|
||||||
|
|
||||||
|
this._refocusSubscription = navigation.addListener(
|
||||||
|
'refocus',
|
||||||
|
this._handleRefocus
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this._actionSubscription?.remove();
|
||||||
|
this._willFocusSubscription?.remove();
|
||||||
|
this._willBlurSubscription?.remove();
|
||||||
|
this._didFocusSubscription?.remove();
|
||||||
|
this._didBlurSubscription?.remove();
|
||||||
|
this._refocusSubscription?.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {{ remove(): void } | undefined}
|
||||||
|
*/
|
||||||
|
_actionSubscription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {{ remove(): void } | undefined}
|
||||||
|
*/
|
||||||
|
_willFocusSubscription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {{ remove(): void } | undefined}
|
||||||
|
*/
|
||||||
|
_willBlurSubscription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {{ remove(): void } | undefined}
|
||||||
|
*/
|
||||||
|
_didFocusSubscription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {{ remove(): void } | undefined}
|
||||||
|
*/
|
||||||
|
_didBlurSubscription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {{ remove(): void } | undefined}
|
||||||
|
*/
|
||||||
|
_refocusSubscription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {string | undefined}
|
||||||
|
*/
|
||||||
|
_lastWillBlurKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {string | undefined}
|
||||||
|
*/
|
||||||
|
_lastWillFocusKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {string | undefined}
|
||||||
|
*/
|
||||||
|
_lastDidBlurKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {string | undefined}
|
||||||
|
*/
|
||||||
|
_lastDidFocusKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The 'action' event will fire when navigation state changes.
|
||||||
|
* Detect if the focused route changed here and emit appropriate events.
|
||||||
|
*
|
||||||
|
* @param {ParentPayload} payload
|
||||||
|
*/
|
||||||
|
_handleAction = ({ state, lastState, action, type, context }) => {
|
||||||
|
const { navigation, onEvent } = this.props;
|
||||||
|
|
||||||
|
// We should only emit events when the navigator is focused
|
||||||
|
// When navigator is not focused, screens inside shouldn't receive focused status either
|
||||||
|
if (!navigation.isFocused()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const previous = lastState
|
||||||
|
? lastState.routes?.[lastState.index]
|
||||||
|
: undefined;
|
||||||
|
const current = state.routes[state.index];
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
context: `${current.key}:${action.type}_${context || 'Root'}`,
|
||||||
|
state: current,
|
||||||
|
lastState: previous,
|
||||||
|
action,
|
||||||
|
type,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (previous?.key !== current.key) {
|
||||||
|
this._emitWillFocus(current.key, payload);
|
||||||
|
|
||||||
|
if (previous?.key) {
|
||||||
|
this._emitWillBlur(previous.key, payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
lastState?.isTransitioning !== state.isTransitioning &&
|
||||||
|
state.isTransitioning === false
|
||||||
|
) {
|
||||||
|
if (this._lastWillBlurKey) {
|
||||||
|
this._emitDidBlur(this._lastWillBlurKey, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._lastWillFocusKey) {
|
||||||
|
this._emitDidFocus(this._lastWillFocusKey, payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onEvent(current.key, 'action', payload);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ParentPayload} payload
|
||||||
|
*/
|
||||||
|
_handleWillFocus = ({ lastState, action, context, type }) => {
|
||||||
|
const { navigation } = this.props;
|
||||||
|
const route = navigation.state.routes[navigation.state.index];
|
||||||
|
|
||||||
|
this._emitWillFocus(route.key, {
|
||||||
|
context: `${route.key}:${action.type}_${context || 'Root'}`,
|
||||||
|
state: route,
|
||||||
|
lastState: lastState?.routes?.find((r) => r.key === route.key),
|
||||||
|
action,
|
||||||
|
type,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ParentPayload} payload
|
||||||
|
*/
|
||||||
|
_handleWillBlur = ({ lastState, action, context, type }) => {
|
||||||
|
const { navigation } = this.props;
|
||||||
|
const route = navigation.state.routes[navigation.state.index];
|
||||||
|
|
||||||
|
this._emitWillBlur(route.key, {
|
||||||
|
context: `${route.key}:${action.type}_${context || 'Root'}`,
|
||||||
|
state: route,
|
||||||
|
lastState: lastState?.routes?.find((r) => r.key === route.key),
|
||||||
|
action,
|
||||||
|
type,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ParentPayload} payload
|
||||||
|
*/
|
||||||
|
_handleDidFocus = ({ lastState, action, context, type }) => {
|
||||||
|
const { navigation } = this.props;
|
||||||
|
|
||||||
|
if (this._lastWillFocusKey) {
|
||||||
|
const route = navigation.state.routes.find(
|
||||||
|
(r) => r.key === this._lastWillFocusKey
|
||||||
|
);
|
||||||
|
|
||||||
|
if (route) {
|
||||||
|
this._emitDidFocus(route.key, {
|
||||||
|
context: `${route.key}:${action.type}_${context || 'Root'}`,
|
||||||
|
state: route,
|
||||||
|
lastState: lastState?.routes?.find((r) => r.key === route.key),
|
||||||
|
action,
|
||||||
|
type,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ParentPayload} payload
|
||||||
|
*/
|
||||||
|
_handleDidBlur = ({ lastState, action, context, type }) => {
|
||||||
|
const { navigation } = this.props;
|
||||||
|
|
||||||
|
if (this._lastWillBlurKey) {
|
||||||
|
const route = navigation.state.routes.find(
|
||||||
|
(r) => r.key === this._lastWillBlurKey
|
||||||
|
);
|
||||||
|
|
||||||
|
if (route) {
|
||||||
|
this._emitDidBlur(route.key, {
|
||||||
|
context: `${route.key}:${action.type}_${context || 'Root'}`,
|
||||||
|
state: route,
|
||||||
|
lastState: lastState?.routes?.find((r) => r.key === route.key),
|
||||||
|
action,
|
||||||
|
type,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_handleRefocus = () => {
|
||||||
|
const { onEvent, navigation } = this.props;
|
||||||
|
const route = navigation.state.routes[navigation.state.index];
|
||||||
|
|
||||||
|
onEvent(route.key, 'refocus');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} target
|
||||||
|
* @param {Payload} payload
|
||||||
|
*/
|
||||||
|
_emitWillFocus = (target, payload) => {
|
||||||
|
if (this._lastWillBlurKey === target) {
|
||||||
|
this._lastWillBlurKey = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._lastWillFocusKey === target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._lastDidFocusKey = undefined;
|
||||||
|
this._lastWillFocusKey = target;
|
||||||
|
|
||||||
|
const { navigation, onEvent } = this.props;
|
||||||
|
|
||||||
|
onEvent(target, 'willFocus', payload);
|
||||||
|
|
||||||
|
if (
|
||||||
|
typeof navigation.state.isTransitioning !== 'boolean' ||
|
||||||
|
(navigation.state.isTransitioning !== true &&
|
||||||
|
!navigation.dangerouslyGetParent())
|
||||||
|
) {
|
||||||
|
this._emitDidFocus(target, payload);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} target
|
||||||
|
* @param {Payload} payload
|
||||||
|
*/
|
||||||
|
_emitWillBlur = (target, payload) => {
|
||||||
|
if (this._lastWillFocusKey === target) {
|
||||||
|
this._lastWillFocusKey = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._lastWillBlurKey === target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._lastDidBlurKey = undefined;
|
||||||
|
this._lastWillBlurKey = target;
|
||||||
|
|
||||||
|
const { navigation, onEvent } = this.props;
|
||||||
|
|
||||||
|
onEvent(target, 'willBlur', payload);
|
||||||
|
|
||||||
|
if (
|
||||||
|
typeof navigation.state.isTransitioning !== 'boolean' ||
|
||||||
|
(navigation.state.isTransitioning !== true &&
|
||||||
|
!navigation.dangerouslyGetParent())
|
||||||
|
) {
|
||||||
|
this._emitDidBlur(target, payload);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} target
|
||||||
|
* @param {Payload} payload
|
||||||
|
*/
|
||||||
|
_emitDidFocus = (target, payload) => {
|
||||||
|
if (this._lastWillFocusKey !== target || this._lastDidFocusKey === target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._lastDidFocusKey = target;
|
||||||
|
|
||||||
|
const { onEvent } = this.props;
|
||||||
|
|
||||||
|
onEvent(target, 'didFocus', payload);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} target
|
||||||
|
* @param {Payload} payload
|
||||||
|
*/
|
||||||
|
_emitDidBlur = (target, payload) => {
|
||||||
|
if (this._lastWillBlurKey !== target || this._lastDidBlurKey === target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._lastDidBlurKey = target;
|
||||||
|
|
||||||
|
const { onEvent } = this.props;
|
||||||
|
|
||||||
|
onEvent(target, 'didBlur', payload);
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import NavigationContext from './NavigationContext';
|
import NavigationContext from './NavigationContext';
|
||||||
|
|
||||||
export default class SceneView extends React.PureComponent {
|
export default class SceneView extends React.PureComponent {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import SceneView from '../SceneView';
|
import SceneView from '../SceneView';
|
||||||
|
|
||||||
export default class SwitchView extends React.Component {
|
export default class SwitchView extends React.Component {
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import renderer from 'react-test-renderer';
|
import renderer from 'react-test-renderer';
|
||||||
import NavigationEvents from '../NavigationEvents';
|
import NavigationEvents from '../NavigationEvents';
|
||||||
import NavigationContext from '../NavigationContext';
|
import NavigationContext from '../NavigationContext';
|
||||||
|
|
||||||
const createPropListener = () => jest.fn();
|
const createPropListener = () => jest.fn();
|
||||||
|
|
||||||
|
const EVENT_TO_PROP_NAME = {
|
||||||
|
willFocus: 'onWillFocus',
|
||||||
|
didFocus: 'onDidFocus',
|
||||||
|
willBlur: 'onWillBlur',
|
||||||
|
didBlur: 'onDidBlur',
|
||||||
|
};
|
||||||
|
|
||||||
// An easy way to create the 4 listeners prop
|
// An easy way to create the 4 listeners prop
|
||||||
const createEventListenersProp = () => ({
|
const createEventListenersProp = () => ({
|
||||||
onWillFocus: createPropListener(),
|
onWillFocus: createPropListener(),
|
||||||
@@ -122,6 +129,39 @@ describe('NavigationEvents', () => {
|
|||||||
checkPropListenerIsCalled('didBlur', 'onDidBlur');
|
checkPropListenerIsCalled('didBlur', 'onDidBlur');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('wires props listeners to latest navigation updates', () => {
|
||||||
|
const {
|
||||||
|
navigation,
|
||||||
|
NavigationListenersAPI,
|
||||||
|
} = createTestNavigationAndHelpers();
|
||||||
|
const {
|
||||||
|
navigation: nextNavigation,
|
||||||
|
NavigationListenersAPI: nextNavigationListenersAPI,
|
||||||
|
} = createTestNavigationAndHelpers();
|
||||||
|
|
||||||
|
const eventListenerProps = createEventListenersProp();
|
||||||
|
const component = renderer.create(
|
||||||
|
<NavigationEvents navigation={navigation} {...eventListenerProps} />
|
||||||
|
);
|
||||||
|
|
||||||
|
Object.entries(EVENT_TO_PROP_NAME).forEach(([eventName, propName]) => {
|
||||||
|
expect(eventListenerProps[propName]).toHaveBeenCalledTimes(0);
|
||||||
|
NavigationListenersAPI.call(eventName);
|
||||||
|
expect(eventListenerProps[propName]).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
component.update(
|
||||||
|
<NavigationEvents navigation={nextNavigation} {...eventListenerProps} />
|
||||||
|
);
|
||||||
|
|
||||||
|
Object.entries(EVENT_TO_PROP_NAME).forEach(([eventName, propName]) => {
|
||||||
|
NavigationListenersAPI.call(eventName);
|
||||||
|
expect(eventListenerProps[propName]).toHaveBeenCalledTimes(1);
|
||||||
|
nextNavigationListenersAPI.call(eventName);
|
||||||
|
expect(eventListenerProps[propName]).toHaveBeenCalledTimes(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('wire latest props listener to navigation listeners on updates (support closure/arrow functions update)', () => {
|
it('wire latest props listener to navigation listeners on updates (support closure/arrow functions update)', () => {
|
||||||
const {
|
const {
|
||||||
navigation,
|
navigation,
|
||||||
|
|||||||
307
packages/core/src/views/__tests__/NavigationFocusEvents.test.js
Normal file
307
packages/core/src/views/__tests__/NavigationFocusEvents.test.js
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import renderer from 'react-test-renderer';
|
||||||
|
import NavigationFocusEvents from '../NavigationFocusEvents';
|
||||||
|
import getEventManager from '../../getEventManager';
|
||||||
|
import { NavigationActions, StackActions } from '@react-navigation/core';
|
||||||
|
|
||||||
|
const getNavigationMock = (mock = {}) => {
|
||||||
|
const { addListener, emit } = getEventManager('target');
|
||||||
|
|
||||||
|
return {
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{ key: 'a', routeName: 'foo' },
|
||||||
|
{ key: 'b', routeName: 'bar' },
|
||||||
|
],
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
isFocused: () => true,
|
||||||
|
addListener: jest.fn(addListener),
|
||||||
|
emit: emit,
|
||||||
|
dangerouslyGetParent: () => null,
|
||||||
|
...mock,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
it('emits refocus event with current route key on refocus', () => {
|
||||||
|
const navigation = getNavigationMock();
|
||||||
|
const onEvent = jest.fn();
|
||||||
|
|
||||||
|
renderer.create(
|
||||||
|
<NavigationFocusEvents navigation={navigation} onEvent={onEvent} />
|
||||||
|
);
|
||||||
|
|
||||||
|
navigation.emit('refocus');
|
||||||
|
|
||||||
|
expect(onEvent).toHaveBeenCalledTimes(1);
|
||||||
|
const key = navigation.state.routes[navigation.state.index].key;
|
||||||
|
expect(onEvent).toHaveBeenCalledWith(key, 'refocus');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('on navigation action emitted', () => {
|
||||||
|
it('does not emit if navigation is not focused', () => {
|
||||||
|
const navigation = getNavigationMock({
|
||||||
|
isFocused: () => false,
|
||||||
|
});
|
||||||
|
const onEvent = jest.fn();
|
||||||
|
|
||||||
|
renderer.create(
|
||||||
|
<NavigationFocusEvents navigation={navigation} onEvent={onEvent} />
|
||||||
|
);
|
||||||
|
|
||||||
|
navigation.emit('action', {
|
||||||
|
state: navigation.state,
|
||||||
|
action: NavigationActions.init(),
|
||||||
|
type: 'action',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(onEvent).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('emits only willFocus and willBlur if state is transitioning', () => {
|
||||||
|
const state = {
|
||||||
|
routes: [
|
||||||
|
{ key: 'First', routeName: 'First' },
|
||||||
|
{ key: 'Second', routeName: 'Second' },
|
||||||
|
],
|
||||||
|
index: 1,
|
||||||
|
routeKeyHistory: ['First', 'Second'],
|
||||||
|
isTransitioning: true,
|
||||||
|
};
|
||||||
|
const action = NavigationActions.init();
|
||||||
|
|
||||||
|
const navigation = getNavigationMock({
|
||||||
|
state: state,
|
||||||
|
});
|
||||||
|
const onEvent = jest.fn();
|
||||||
|
|
||||||
|
renderer.create(
|
||||||
|
<NavigationFocusEvents navigation={navigation} onEvent={onEvent} />
|
||||||
|
);
|
||||||
|
|
||||||
|
const lastState = {
|
||||||
|
routes: [
|
||||||
|
{ key: 'First', routeName: 'First' },
|
||||||
|
{ key: 'Second', routeName: 'Second' },
|
||||||
|
],
|
||||||
|
index: 0,
|
||||||
|
routeKeyHistory: ['First'],
|
||||||
|
};
|
||||||
|
navigation.emit('action', {
|
||||||
|
state,
|
||||||
|
lastState,
|
||||||
|
action,
|
||||||
|
type: 'action',
|
||||||
|
});
|
||||||
|
|
||||||
|
const expectedPayload = {
|
||||||
|
action,
|
||||||
|
state: { key: 'Second', routeName: 'Second' },
|
||||||
|
lastState: { key: 'First', routeName: 'First' },
|
||||||
|
context: 'Second:Navigation/INIT_Root',
|
||||||
|
type: 'action',
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(onEvent.mock.calls).toEqual([
|
||||||
|
['Second', 'willFocus', expectedPayload],
|
||||||
|
['First', 'willBlur', expectedPayload],
|
||||||
|
['Second', 'action', expectedPayload],
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('emits didFocus after willFocus and didBlur after willBlur if no transitions', () => {
|
||||||
|
const state = {
|
||||||
|
routes: [
|
||||||
|
{ key: 'First', routeName: 'First' },
|
||||||
|
{ key: 'Second', routeName: 'Second' },
|
||||||
|
],
|
||||||
|
index: 1,
|
||||||
|
routeKeyHistory: ['First', 'Second'],
|
||||||
|
};
|
||||||
|
const action = NavigationActions.navigate({
|
||||||
|
routeName: 'Second',
|
||||||
|
});
|
||||||
|
|
||||||
|
const navigation = getNavigationMock({
|
||||||
|
state: state,
|
||||||
|
});
|
||||||
|
const onEvent = jest.fn();
|
||||||
|
|
||||||
|
renderer.create(
|
||||||
|
<NavigationFocusEvents navigation={navigation} onEvent={onEvent} />
|
||||||
|
);
|
||||||
|
|
||||||
|
const lastState = {
|
||||||
|
routes: [
|
||||||
|
{ key: 'First', routeName: 'First' },
|
||||||
|
{ key: 'Second', routeName: 'Second' },
|
||||||
|
],
|
||||||
|
index: 0,
|
||||||
|
routeKeyHistory: ['First'],
|
||||||
|
};
|
||||||
|
navigation.emit('action', {
|
||||||
|
state,
|
||||||
|
lastState,
|
||||||
|
action,
|
||||||
|
type: 'action',
|
||||||
|
});
|
||||||
|
|
||||||
|
const expectedPayload = {
|
||||||
|
action,
|
||||||
|
state: { key: 'Second', routeName: 'Second' },
|
||||||
|
lastState: { key: 'First', routeName: 'First' },
|
||||||
|
context: 'Second:Navigation/NAVIGATE_Root',
|
||||||
|
type: 'action',
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(onEvent.mock.calls).toEqual([
|
||||||
|
['Second', 'willFocus', expectedPayload],
|
||||||
|
['Second', 'didFocus', expectedPayload],
|
||||||
|
['First', 'willBlur', expectedPayload],
|
||||||
|
['First', 'didBlur', expectedPayload],
|
||||||
|
['Second', 'action', expectedPayload],
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('emits didBlur and didFocus when transition ends', () => {
|
||||||
|
const initialState = {
|
||||||
|
routes: [
|
||||||
|
{ key: 'First', routeName: 'First' },
|
||||||
|
{ key: 'Second', routeName: 'Second' },
|
||||||
|
],
|
||||||
|
index: 0,
|
||||||
|
routeKeyHistory: ['First'],
|
||||||
|
isTransitioning: true,
|
||||||
|
};
|
||||||
|
const intermediateState = {
|
||||||
|
routes: [
|
||||||
|
{ key: 'First', routeName: 'First' },
|
||||||
|
{ key: 'Second', routeName: 'Second' },
|
||||||
|
],
|
||||||
|
index: 1,
|
||||||
|
routeKeyHistory: ['First', 'Second'],
|
||||||
|
isTransitioning: true,
|
||||||
|
};
|
||||||
|
const finalState = {
|
||||||
|
routes: [
|
||||||
|
{ key: 'First', routeName: 'First' },
|
||||||
|
{ key: 'Second', routeName: 'Second' },
|
||||||
|
],
|
||||||
|
index: 1,
|
||||||
|
routeKeyHistory: ['First', 'Second'],
|
||||||
|
isTransitioning: false,
|
||||||
|
};
|
||||||
|
const actionNavigate = NavigationActions.navigate({ routeName: 'Second' });
|
||||||
|
const actionEndTransition = StackActions.completeTransition({
|
||||||
|
key: 'Second',
|
||||||
|
});
|
||||||
|
|
||||||
|
const navigation = getNavigationMock({
|
||||||
|
state: intermediateState,
|
||||||
|
});
|
||||||
|
const onEvent = jest.fn();
|
||||||
|
|
||||||
|
renderer.create(
|
||||||
|
<NavigationFocusEvents navigation={navigation} onEvent={onEvent} />
|
||||||
|
);
|
||||||
|
|
||||||
|
navigation.emit('action', {
|
||||||
|
state: intermediateState,
|
||||||
|
lastState: initialState,
|
||||||
|
action: actionNavigate,
|
||||||
|
type: 'action',
|
||||||
|
});
|
||||||
|
|
||||||
|
const expectedPayloadNavigate = {
|
||||||
|
action: actionNavigate,
|
||||||
|
state: { key: 'Second', routeName: 'Second' },
|
||||||
|
lastState: { key: 'First', routeName: 'First' },
|
||||||
|
context: 'Second:Navigation/NAVIGATE_Root',
|
||||||
|
type: 'action',
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(onEvent.mock.calls).toEqual([
|
||||||
|
['Second', 'willFocus', expectedPayloadNavigate],
|
||||||
|
['First', 'willBlur', expectedPayloadNavigate],
|
||||||
|
['Second', 'action', expectedPayloadNavigate],
|
||||||
|
]);
|
||||||
|
onEvent.mockClear();
|
||||||
|
|
||||||
|
navigation.emit('action', {
|
||||||
|
state: finalState,
|
||||||
|
lastState: intermediateState,
|
||||||
|
action: actionEndTransition,
|
||||||
|
type: 'action',
|
||||||
|
});
|
||||||
|
|
||||||
|
const expectedPayloadEndTransition = {
|
||||||
|
action: actionEndTransition,
|
||||||
|
state: { key: 'Second', routeName: 'Second' },
|
||||||
|
lastState: { key: 'Second', routeName: 'Second' },
|
||||||
|
context: 'Second:Navigation/COMPLETE_TRANSITION_Root',
|
||||||
|
type: 'action',
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(onEvent.mock.calls).toEqual([
|
||||||
|
['First', 'didBlur', expectedPayloadEndTransition],
|
||||||
|
['Second', 'didFocus', expectedPayloadEndTransition],
|
||||||
|
['Second', 'action', expectedPayloadEndTransition],
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('on willFocus emitted', () => {
|
||||||
|
it('emits didFocus after willFocus if no transition', () => {
|
||||||
|
const navigation = getNavigationMock({
|
||||||
|
state: {
|
||||||
|
routes: [
|
||||||
|
{ key: 'FirstLanding', routeName: 'FirstLanding' },
|
||||||
|
{ key: 'Second', routeName: 'Second' },
|
||||||
|
],
|
||||||
|
index: 0,
|
||||||
|
key: 'First',
|
||||||
|
routeName: 'First',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const onEvent = jest.fn();
|
||||||
|
|
||||||
|
renderer.create(
|
||||||
|
<NavigationFocusEvents navigation={navigation} onEvent={onEvent} />
|
||||||
|
);
|
||||||
|
|
||||||
|
const lastState = { key: 'Third', routeName: 'Third' };
|
||||||
|
const action = NavigationActions.navigate({ routeName: 'First' });
|
||||||
|
|
||||||
|
navigation.emit('willFocus', {
|
||||||
|
lastState,
|
||||||
|
action,
|
||||||
|
context: 'First:Navigation/NAVIGATE_Root',
|
||||||
|
type: 'action',
|
||||||
|
});
|
||||||
|
|
||||||
|
const expectedPayload = {
|
||||||
|
action,
|
||||||
|
state: { key: 'FirstLanding', routeName: 'FirstLanding' },
|
||||||
|
context:
|
||||||
|
'FirstLanding:Navigation/NAVIGATE_First:Navigation/NAVIGATE_Root',
|
||||||
|
type: 'action',
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(onEvent.mock.calls).toEqual([
|
||||||
|
['FirstLanding', 'willFocus', expectedPayload],
|
||||||
|
['FirstLanding', 'didFocus', expectedPayload],
|
||||||
|
]);
|
||||||
|
|
||||||
|
onEvent.mockClear();
|
||||||
|
|
||||||
|
// the nested navigator might emit a didFocus that should be ignored
|
||||||
|
navigation.emit('didFocus', {
|
||||||
|
lastState,
|
||||||
|
action,
|
||||||
|
context: 'First:Navigation/NAVIGATE_Root',
|
||||||
|
type: 'action',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(onEvent).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import hoistStatics from 'hoist-non-react-statics';
|
import hoistStatics from 'hoist-non-react-statics';
|
||||||
import invariant from '../utils/invariant';
|
import invariant from '../utils/invariant';
|
||||||
import NavigationContext from './NavigationContext';
|
import NavigationContext from './NavigationContext';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import hoistStatics from 'hoist-non-react-statics';
|
import hoistStatics from 'hoist-non-react-statics';
|
||||||
import withNavigation from './withNavigation';
|
import withNavigation from './withNavigation';
|
||||||
|
|
||||||
@@ -8,25 +8,25 @@ export default function withNavigationFocus(Component) {
|
|||||||
Component.displayName || Component.name
|
Component.displayName || Component.name
|
||||||
})`;
|
})`;
|
||||||
|
|
||||||
constructor(props) {
|
state = {
|
||||||
super(props);
|
isFocused: this.props.navigation.isFocused(),
|
||||||
|
};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const { navigation } = this.props;
|
||||||
|
|
||||||
this.subscriptions = [
|
this.subscriptions = [
|
||||||
props.navigation.addListener('didFocus', () =>
|
navigation.addListener('willFocus', () =>
|
||||||
this.setState({ isFocused: true })
|
this.setState({ isFocused: true })
|
||||||
),
|
),
|
||||||
props.navigation.addListener('willBlur', () =>
|
navigation.addListener('willBlur', () =>
|
||||||
this.setState({ isFocused: false })
|
this.setState({ isFocused: false })
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
this.state = {
|
|
||||||
isFocused: props.navigation ? props.navigation.isFocused() : false,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.subscriptions.forEach((sub) => sub.remove());
|
this.subscriptions?.forEach((sub) => sub.remove());
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
6
packages/core/tsconfig.json
Normal file
6
packages/core/tsconfig.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig",
|
||||||
|
"compilerOptions": {
|
||||||
|
"allowJs": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,95 @@
|
|||||||
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.6.0](https://github.com/react-navigation/drawer/compare/react-navigation-drawer@2.5.2...react-navigation-drawer@2.6.0) (2020-10-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add detachInactiveScreens prop for bottom tabs and drawer ([#8816](https://github.com/react-navigation/drawer/issues/8816)) ([707bea3](https://github.com/react-navigation/drawer/commit/707bea3cba1aa1f7b1eb5884dd1d129dcc2bbdc2))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.5.2](https://github.com/react-navigation/drawer/compare/react-navigation-drawer@2.5.1...react-navigation-drawer@2.5.2) (2020-10-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-drawer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.5.1](https://github.com/react-navigation/drawer/compare/react-navigation-drawer@2.5.0...react-navigation-drawer@2.5.1) (2020-09-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-drawer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [2.5.0](https://github.com/react-navigation/drawer/compare/react-navigation-drawer@2.4.13...react-navigation-drawer@2.5.0) (2020-06-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* sync latest stack and upgrade typescript ([454e05b](https://github.com/react-navigation/drawer/commit/454e05b02ec97f053b381fdc801df899d8c93cb6))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.4.13](https://github.com/react-navigation/drawer/compare/react-navigation-drawer@2.4.12...react-navigation-drawer@2.4.13) (2020-04-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-drawer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.4.12](https://github.com/react-navigation/drawer/compare/react-navigation-drawer@2.4.11...react-navigation-drawer@2.4.12) (2020-04-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-drawer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.4.11](https://github.com/react-navigation/drawer/compare/react-navigation-drawer@2.4.10...react-navigation-drawer@2.4.11) (2020-04-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-drawer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.4.10](https://github.com/react-navigation/drawer/compare/react-navigation-drawer@2.4.9...react-navigation-drawer@2.4.10) (2020-03-31)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* remove isTransitioning from SwitchRouter state ([3bec1c9](https://github.com/react-navigation/drawer/commit/3bec1c964a49136c0ead8e8ba8a8c66c556bbcba))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.4.9](https://github.com/react-navigation/drawer/compare/react-navigation-drawer@2.4.7...react-navigation-drawer@2.4.9) (2020-03-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-drawer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.4.8](https://github.com/react-navigation/drawer/compare/react-navigation-drawer@2.4.7...react-navigation-drawer@2.4.8) (2020-03-27)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-drawer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [2.4.7](https://github.com/react-navigation/drawer/compare/react-navigation-drawer@2.4.6...react-navigation-drawer@2.4.7) (2020-03-22)
|
## [2.4.7](https://github.com/react-navigation/drawer/compare/react-navigation-drawer@2.4.6...react-navigation-drawer@2.4.7) (2020-03-22)
|
||||||
|
|
||||||
**Note:** Version bump only for package react-navigation-drawer
|
**Note:** Version bump only for package react-navigation-drawer
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-navigation-drawer",
|
"name": "react-navigation-drawer",
|
||||||
"version": "2.4.7",
|
"version": "2.6.0",
|
||||||
"description": "Drawer navigator component for React Navigation",
|
"description": "Drawer navigator component for React Navigation",
|
||||||
"main": "lib/commonjs/index.js",
|
"main": "lib/commonjs/index.js",
|
||||||
"react-native": "lib/module/index.js",
|
"react-native": "lib/module/index.js",
|
||||||
@@ -38,19 +38,19 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/react-navigation/drawer#readme",
|
"homepage": "https://github.com/react-navigation/drawer#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.10.0",
|
"@react-native-community/bob": "^0.16.2",
|
||||||
"@types/react": "^16.9.23",
|
"@types/react": "^16.9.53",
|
||||||
"@types/react-native": "^0.61.22",
|
"@types/react-native": "^0.63.30",
|
||||||
"del-cli": "^3.0.0",
|
"del-cli": "^3.0.1",
|
||||||
"react": "~16.9.0",
|
"react": "~16.13.1",
|
||||||
"react-lifecycles-compat": "^3.0.4",
|
"react-lifecycles-compat": "^3.0.4",
|
||||||
"react-native": "~0.61.5",
|
"react-native": "~0.63.2",
|
||||||
"react-native-gesture-handler": "^1.6.0",
|
"react-native-gesture-handler": "~1.7.0",
|
||||||
"react-native-reanimated": "^1.2.0",
|
"react-native-reanimated": "~1.13.0",
|
||||||
"react-native-screens": "^2.3.0",
|
"react-native-screens": "~2.10.1",
|
||||||
"react-native-testing-library": "^1.12.0",
|
"react-native-testing-library": "^6.0.0",
|
||||||
"react-navigation": "^4.3.3",
|
"react-navigation": "^4.4.3",
|
||||||
"typescript": "~3.7.5"
|
"typescript": "^4.0.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "*",
|
"react": "*",
|
||||||
|
|||||||
@@ -75,8 +75,11 @@ const DrawerNavigator = (
|
|||||||
const drawerRouter = DrawerRouter(routeConfigs, mergedConfig);
|
const drawerRouter = DrawerRouter(routeConfigs, mergedConfig);
|
||||||
|
|
||||||
// TODO: don't have time to fix it right now
|
// TODO: don't have time to fix it right now
|
||||||
// @ts-ignore
|
const navigator = createNavigator(
|
||||||
const navigator = createNavigator(DrawerView, drawerRouter, mergedConfig);
|
DrawerView as any,
|
||||||
|
drawerRouter,
|
||||||
|
mergedConfig
|
||||||
|
);
|
||||||
return navigator;
|
return navigator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ it('handles basic drawer logic and fires close on switch', () => {
|
|||||||
const state = router.getStateForAction(INIT_ACTION);
|
const state = router.getStateForAction(INIT_ACTION);
|
||||||
const expectedState = {
|
const expectedState = {
|
||||||
index: 0,
|
index: 0,
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'Foo', routeName: 'Foo', params: undefined },
|
{ key: 'Foo', routeName: 'Foo', params: undefined },
|
||||||
{ key: 'Bar', routeName: 'Bar', params: undefined },
|
{ key: 'Bar', routeName: 'Bar', params: undefined },
|
||||||
@@ -32,7 +32,7 @@ it('handles basic drawer logic and fires close on switch', () => {
|
|||||||
);
|
);
|
||||||
const expectedState2 = {
|
const expectedState2 = {
|
||||||
index: 1,
|
index: 1,
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{ key: 'Foo', routeName: 'Foo', params: undefined },
|
{ key: 'Foo', routeName: 'Foo', params: undefined },
|
||||||
{ key: 'Bar', routeName: 'Bar', params: undefined },
|
{ key: 'Bar', routeName: 'Bar', params: undefined },
|
||||||
@@ -65,7 +65,7 @@ it('handles initial route navigation', () => {
|
|||||||
expect(state).toEqual({
|
expect(state).toEqual({
|
||||||
index: 0,
|
index: 0,
|
||||||
isDrawerOpen: false,
|
isDrawerOpen: false,
|
||||||
isTransitioning: false,
|
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
key: 'Foo',
|
key: 'Foo',
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ export type NavigationDrawerConfig = {
|
|||||||
drawerBackgroundColor?: ThemedColor;
|
drawerBackgroundColor?: ThemedColor;
|
||||||
overlayColor?: ThemedColor;
|
overlayColor?: ThemedColor;
|
||||||
screenContainerStyle?: StyleProp<ViewStyle>;
|
screenContainerStyle?: StyleProp<ViewStyle>;
|
||||||
|
detachInactiveScreens?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type NavigationDrawerRouterConfig = {
|
export type NavigationDrawerRouterConfig = {
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ type Props = {
|
|||||||
contentOptions?: object;
|
contentOptions?: object;
|
||||||
};
|
};
|
||||||
screenProps: unknown;
|
screenProps: unknown;
|
||||||
|
detachInactiveScreens: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
@@ -160,17 +161,13 @@ export default class DrawerView extends React.PureComponent<Props, State> {
|
|||||||
drawerOpenProgress={progress}
|
drawerOpenProgress={progress}
|
||||||
navigation={this.props.navigation}
|
navigation={this.props.navigation}
|
||||||
descriptors={this.props.descriptors}
|
descriptors={this.props.descriptors}
|
||||||
contentComponent={this.props.navigationConfig.contentComponent}
|
|
||||||
contentOptions={this.props.navigationConfig.contentOptions}
|
|
||||||
drawerPosition={this.props.navigationConfig.drawerPosition}
|
|
||||||
style={this.props.navigationConfig.style}
|
|
||||||
{...this.props.navigationConfig}
|
{...this.props.navigationConfig}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
private renderContent = () => {
|
private renderContent = () => {
|
||||||
let { lazy, navigation } = this.props;
|
let { lazy, navigation, detachInactiveScreens = true } = this.props;
|
||||||
let { loaded } = this.state;
|
let { loaded } = this.state;
|
||||||
let { routes } = navigation.state;
|
let { routes } = navigation.state;
|
||||||
|
|
||||||
@@ -187,7 +184,8 @@ export default class DrawerView extends React.PureComponent<Props, State> {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<ScreenContainer style={styles.content}>
|
// @ts-ignore
|
||||||
|
<ScreenContainer enabled={detachInactiveScreens} style={styles.content}>
|
||||||
{routes.map((route, index) => {
|
{routes.map((route, index) => {
|
||||||
if (lazy && !loaded.includes(index)) {
|
if (lazy && !loaded.includes(index)) {
|
||||||
// Don't render a screen if we've never navigated to it
|
// Don't render a screen if we've never navigated to it
|
||||||
@@ -205,6 +203,7 @@ export default class DrawerView extends React.PureComponent<Props, State> {
|
|||||||
{ opacity: isFocused ? 1 : 0 },
|
{ opacity: isFocused ? 1 : 0 },
|
||||||
]}
|
]}
|
||||||
isVisible={isFocused}
|
isVisible={isFocused}
|
||||||
|
enabled={detachInactiveScreens}
|
||||||
>
|
>
|
||||||
<SceneView
|
<SceneView
|
||||||
navigation={descriptor.navigation}
|
navigation={descriptor.navigation}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ type Props = {
|
|||||||
isVisible: boolean;
|
isVisible: boolean;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
style?: any;
|
style?: any;
|
||||||
|
enabled: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const FAR_FAR_AWAY = 30000; // this should be big enough to move the whole view out of its container
|
const FAR_FAR_AWAY = 30000; // this should be big enough to move the whole view out of its container
|
||||||
@@ -13,7 +14,7 @@ const FAR_FAR_AWAY = 30000; // this should be big enough to move the whole view
|
|||||||
export default class ResourceSavingScene extends React.Component<Props> {
|
export default class ResourceSavingScene extends React.Component<Props> {
|
||||||
render() {
|
render() {
|
||||||
// react-native-screens is buggy on web
|
// react-native-screens is buggy on web
|
||||||
if (screensEnabled?.() && Platform.OS !== 'web') {
|
if (screensEnabled?.() && this.props.enabled && Platform.OS !== 'web') {
|
||||||
const { isVisible, ...rest } = this.props;
|
const { isVisible, ...rest } = this.props;
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|||||||
@@ -3,6 +3,89 @@
|
|||||||
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.3.3](https://github.com/react-navigation/react-navigation-material-bottom-tabs/compare/react-navigation-material-bottom-tabs@2.3.2...react-navigation-material-bottom-tabs@2.3.3) (2020-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-material-bottom-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.3.2](https://github.com/react-navigation/react-navigation-material-bottom-tabs/compare/react-navigation-material-bottom-tabs@2.3.1...react-navigation-material-bottom-tabs@2.3.2) (2020-10-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-material-bottom-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.3.1](https://github.com/react-navigation/react-navigation-material-bottom-tabs/compare/react-navigation-material-bottom-tabs@2.3.0...react-navigation-material-bottom-tabs@2.3.1) (2020-09-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-material-bottom-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [2.3.0](https://github.com/react-navigation/react-navigation-material-bottom-tabs/compare/react-navigation-material-bottom-tabs@2.2.12...react-navigation-material-bottom-tabs@2.3.0) (2020-06-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* sync latest stack and upgrade typescript ([454e05b](https://github.com/react-navigation/react-navigation-material-bottom-tabs/commit/454e05b02ec97f053b381fdc801df899d8c93cb6))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.2.12](https://github.com/react-navigation/react-navigation-material-bottom-tabs/compare/react-navigation-material-bottom-tabs@2.2.11...react-navigation-material-bottom-tabs@2.2.12) (2020-04-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-material-bottom-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.2.11](https://github.com/react-navigation/react-navigation-material-bottom-tabs/compare/react-navigation-material-bottom-tabs@2.2.10...react-navigation-material-bottom-tabs@2.2.11) (2020-04-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-material-bottom-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.2.10](https://github.com/react-navigation/react-navigation-material-bottom-tabs/compare/react-navigation-material-bottom-tabs@2.2.9...react-navigation-material-bottom-tabs@2.2.10) (2020-04-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-material-bottom-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.2.9](https://github.com/react-navigation/react-navigation-material-bottom-tabs/compare/react-navigation-material-bottom-tabs@2.2.8...react-navigation-material-bottom-tabs@2.2.9) (2020-03-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-material-bottom-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.2.8](https://github.com/react-navigation/react-navigation-material-bottom-tabs/compare/react-navigation-material-bottom-tabs@2.2.6...react-navigation-material-bottom-tabs@2.2.8) (2020-03-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-material-bottom-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.2.7](https://github.com/react-navigation/react-navigation-material-bottom-tabs/compare/react-navigation-material-bottom-tabs@2.2.6...react-navigation-material-bottom-tabs@2.2.7) (2020-03-27)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-material-bottom-tabs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [2.2.6](https://github.com/react-navigation/react-navigation-material-bottom-tabs/compare/react-navigation-material-bottom-tabs@2.2.5...react-navigation-material-bottom-tabs@2.2.6) (2020-03-22)
|
## [2.2.6](https://github.com/react-navigation/react-navigation-material-bottom-tabs/compare/react-navigation-material-bottom-tabs@2.2.5...react-navigation-material-bottom-tabs@2.2.6) (2020-03-22)
|
||||||
|
|
||||||
**Note:** Version bump only for package react-navigation-material-bottom-tabs
|
**Note:** Version bump only for package react-navigation-material-bottom-tabs
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-navigation-material-bottom-tabs",
|
"name": "react-navigation-material-bottom-tabs",
|
||||||
"version": "2.2.6",
|
"version": "2.3.3",
|
||||||
"description": "Material Bottom Tab Navigation component for React Navigation",
|
"description": "Material Bottom Tab Navigation component for React Navigation",
|
||||||
"main": "lib/commonjs/index.js",
|
"main": "lib/commonjs/index.js",
|
||||||
"module": "lib/module/index.js",
|
"module": "lib/module/index.js",
|
||||||
@@ -38,18 +38,16 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/react-navigation/react-navigation-material-bottom-tabs#readme",
|
"homepage": "https://github.com/react-navigation/react-navigation-material-bottom-tabs#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.10.0",
|
"@react-native-community/bob": "^0.16.2",
|
||||||
"@types/hoist-non-react-statics": "^3.3.1",
|
"@types/hoist-non-react-statics": "^3.3.1",
|
||||||
"@types/react": "^16.9.23",
|
"@types/react": "^16.9.53",
|
||||||
"@types/react-native": "^0.61.22",
|
"@types/react-native": "^0.63.30",
|
||||||
"del-cli": "^3.0.0",
|
"del-cli": "^3.0.1",
|
||||||
"react": "~16.9.0",
|
"react": "~16.13.1",
|
||||||
"react-native": "~0.61.5",
|
"react-native": "~0.63.2",
|
||||||
"react-native-gesture-handler": "^1.6.0",
|
"react-native-paper": "^4.2.0",
|
||||||
"react-native-paper": "^3.1.1",
|
"react-navigation": "^4.4.3",
|
||||||
"react-native-reanimated": "^1.2.0",
|
"typescript": "^4.0.3"
|
||||||
"react-navigation": "^4.3.3",
|
|
||||||
"typescript": "~3.7.5"
|
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "*",
|
"react": "*",
|
||||||
|
|||||||
@@ -3,6 +3,103 @@
|
|||||||
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.
|
||||||
|
|
||||||
|
## [3.8.3](https://github.com/react-navigation/react-navigation-native/compare/@react-navigation/native@3.8.2...@react-navigation/native@3.8.3) (2020-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/native
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [3.8.2](https://github.com/react-navigation/react-navigation-native/compare/@react-navigation/native@3.8.1...@react-navigation/native@3.8.2) (2020-10-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/native
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [3.8.1](https://github.com/react-navigation/react-navigation-native/compare/@react-navigation/native@3.8.0...@react-navigation/native@3.8.1) (2020-09-24)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* don't use deprecated currentlyFocusedField ([#8684](https://github.com/react-navigation/react-navigation-native/issues/8684)) ([06a69f1](https://github.com/react-navigation/react-navigation-native/commit/06a69f1bfd81fe06b784ff4e6da290fee0c6467d)), closes [#8457](https://github.com/react-navigation/react-navigation-native/issues/8457)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [3.8.0](https://github.com/react-navigation/react-navigation-native/compare/@react-navigation/native@3.7.13...@react-navigation/native@3.8.0) (2020-06-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* improve error message when installing wrong version ([442ca3e](https://github.com/react-navigation/react-navigation-native/commit/442ca3e700c5805cdc5cd02c68f49042887a5054))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* sync latest stack and upgrade typescript ([454e05b](https://github.com/react-navigation/react-navigation-native/commit/454e05b02ec97f053b381fdc801df899d8c93cb6))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [3.7.13](https://github.com/react-navigation/react-navigation-native/compare/@react-navigation/native@3.7.12...@react-navigation/native@3.7.13) (2020-04-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/native
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [3.7.12](https://github.com/react-navigation/react-navigation-native/compare/@react-navigation/native@3.7.11...@react-navigation/native@3.7.12) (2020-04-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/native
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [3.7.11](https://github.com/react-navigation/react-navigation-native/compare/@react-navigation/native@3.7.10...@react-navigation/native@3.7.11) (2020-04-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/native
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [3.7.10](https://github.com/react-navigation/react-navigation-native/compare/@react-navigation/native@3.7.9...@react-navigation/native@3.7.10) (2020-03-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @react-navigation/native
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [3.7.9](https://github.com/react-navigation/react-navigation-native/compare/@react-navigation/native@3.7.7...@react-navigation/native@3.7.9) (2020-03-28)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* rework focus and blur events to make them more reliable ([cd08338](https://github.com/react-navigation/react-navigation-native/commit/cd083381866506a192f1ec842ac169f2b4277ca5)), closes [#4867](https://github.com/react-navigation/react-navigation-native/issues/4867) [#6187](https://github.com/react-navigation/react-navigation-native/issues/6187) [#6451](https://github.com/react-navigation/react-navigation-native/issues/6451) [#7628](https://github.com/react-navigation/react-navigation-native/issues/7628) [#7749](https://github.com/react-navigation/react-navigation-native/issues/7749)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [3.7.8](https://github.com/react-navigation/react-navigation-native/compare/@react-navigation/native@3.7.7...@react-navigation/native@3.7.8) (2020-03-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* rework focus and blur events to make them more reliable ([cd08338](https://github.com/react-navigation/react-navigation-native/commit/cd083381866506a192f1ec842ac169f2b4277ca5)), closes [#4867](https://github.com/react-navigation/react-navigation-native/issues/4867) [#6187](https://github.com/react-navigation/react-navigation-native/issues/6187) [#6451](https://github.com/react-navigation/react-navigation-native/issues/6451) [#7628](https://github.com/react-navigation/react-navigation-native/issues/7628) [#7749](https://github.com/react-navigation/react-navigation-native/issues/7749)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [3.7.7](https://github.com/react-navigation/react-navigation-native/compare/@react-navigation/native@3.7.6...@react-navigation/native@3.7.7) (2020-03-22)
|
## [3.7.7](https://github.com/react-navigation/react-navigation-native/compare/@react-navigation/native@3.7.6...@react-navigation/native@3.7.7) (2020-03-22)
|
||||||
|
|
||||||
**Note:** Version bump only for package @react-navigation/native
|
**Note:** Version bump only for package @react-navigation/native
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@react-navigation/native",
|
"name": "@react-navigation/native",
|
||||||
"version": "3.7.7",
|
"version": "3.8.3",
|
||||||
"description": "React Native support for React Navigation",
|
"description": "React Native support for React Navigation",
|
||||||
"main": "lib/commonjs/index.js",
|
"main": "lib/commonjs/index.js",
|
||||||
"react-native": "lib/module/index.js",
|
"react-native": "lib/module/index.js",
|
||||||
@@ -36,17 +36,17 @@
|
|||||||
"homepage": "https://github.com/react-navigation/react-navigation-native#readme",
|
"homepage": "https://github.com/react-navigation/react-navigation-native#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"hoist-non-react-statics": "^3.3.2",
|
"hoist-non-react-statics": "^3.3.2",
|
||||||
"react-native-safe-area-view": "^0.14.8"
|
"react-native-safe-area-view": "^0.14.9"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.10.0",
|
"@react-native-community/bob": "^0.16.2",
|
||||||
"@react-navigation/core": "^3.7.1",
|
"@react-navigation/core": "^3.7.9",
|
||||||
"@types/react-test-renderer": "^16.9.2",
|
"@types/react-test-renderer": "^16.9.3",
|
||||||
"del-cli": "^3.0.0",
|
"del-cli": "^3.0.1",
|
||||||
"react": "~16.9.0",
|
"react": "~16.13.1",
|
||||||
"react-native": "~0.61.5",
|
"react-native": "~0.63.2",
|
||||||
"react-native-gesture-handler": "^1.6.0",
|
"react-native-gesture-handler": "~1.7.0",
|
||||||
"react-test-renderer": "^16.9.2"
|
"react-test-renderer": "~16.13.1"
|
||||||
},
|
},
|
||||||
"@react-native-community/bob": {
|
"@react-native-community/bob": {
|
||||||
"source": "src",
|
"source": "src",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { Platform, StyleSheet, View } from 'react-native';
|
import { Platform, StyleSheet, View } from 'react-native';
|
||||||
import { SceneView } from '@react-navigation/core';
|
import { SceneView } from '@react-navigation/core';
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import {
|
import {
|
||||||
ScrollView,
|
ScrollView,
|
||||||
Platform,
|
Platform,
|
||||||
@@ -6,7 +6,6 @@ import {
|
|||||||
SectionList,
|
SectionList,
|
||||||
RefreshControl,
|
RefreshControl,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
// eslint-disable-next-line import/named
|
|
||||||
import { ScrollView as GHScrollView } from 'react-native-gesture-handler';
|
import { ScrollView as GHScrollView } from 'react-native-gesture-handler';
|
||||||
import createNavigationAwareScrollable from './createNavigationAwareScrollable';
|
import createNavigationAwareScrollable from './createNavigationAwareScrollable';
|
||||||
import invariant from './utils/invariant';
|
import invariant from './utils/invariant';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
|
|
||||||
import renderer from 'react-test-renderer';
|
import renderer from 'react-test-renderer';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
import renderer from 'react-test-renderer';
|
import renderer from 'react-test-renderer';
|
||||||
import withOrientation, { isOrientationLandscape } from '../withOrientation';
|
import withOrientation, { isOrientationLandscape } from '../withOrientation';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* eslint-disable react/sort-comp */
|
/* eslint-disable react/sort-comp */
|
||||||
|
|
||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { Linking, Platform, BackHandler } from 'react-native';
|
import { Linking, Platform, BackHandler } from 'react-native';
|
||||||
import {
|
import {
|
||||||
NavigationActions,
|
NavigationActions,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { TextInput } from 'react-native';
|
import { TextInput } from 'react-native';
|
||||||
|
|
||||||
export default (Navigator, navigatorConfig) =>
|
export default (Navigator, navigatorConfig) =>
|
||||||
@@ -8,7 +8,9 @@ export default (Navigator, navigatorConfig) =>
|
|||||||
_previouslyFocusedTextInput = null;
|
_previouslyFocusedTextInput = null;
|
||||||
|
|
||||||
_handleGestureBegin = () => {
|
_handleGestureBegin = () => {
|
||||||
this._previouslyFocusedTextInput = TextInput.State.currentlyFocusedField();
|
this._previouslyFocusedTextInput = TextInput.State.currentlyFocusedInput
|
||||||
|
? TextInput.State.currentlyFocusedInput()
|
||||||
|
: TextInput.State.currentlyFocusedField();
|
||||||
if (this._previouslyFocusedTextInput) {
|
if (this._previouslyFocusedTextInput) {
|
||||||
TextInput.State.blurTextInput(this._previouslyFocusedTextInput);
|
TextInput.State.blurTextInput(this._previouslyFocusedTextInput);
|
||||||
}
|
}
|
||||||
@@ -32,7 +34,9 @@ export default (Navigator, navigatorConfig) =>
|
|||||||
// in the case where the index did not change, I believe. We
|
// in the case where the index did not change, I believe. We
|
||||||
// should revisit this after 2.0 release.
|
// should revisit this after 2.0 release.
|
||||||
if (transitionProps.index !== prevTransitionProps.index) {
|
if (transitionProps.index !== prevTransitionProps.index) {
|
||||||
const currentField = TextInput.State.currentlyFocusedField();
|
const currentField = TextInput.State.currentlyFocusedInput
|
||||||
|
? TextInput.State.currentlyFocusedInput()
|
||||||
|
: TextInput.State.currentlyFocusedField();
|
||||||
if (currentField) {
|
if (currentField) {
|
||||||
TextInput.State.blurTextInput(currentField);
|
TextInput.State.blurTextInput(currentField);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import hoistStatics from 'hoist-non-react-statics';
|
import hoistStatics from 'hoist-non-react-statics';
|
||||||
import { withNavigation } from '@react-navigation/core';
|
import { withNavigation } from '@react-navigation/core';
|
||||||
|
|
||||||
export default function createNavigationAwareScrollable(Component) {
|
export default function createNavigationAwareScrollable(Component) {
|
||||||
const ComponentWithNavigationScrolling = withNavigation(
|
const ComponentWithNavigationScrolling = withNavigation(
|
||||||
class extends React.PureComponent<any> {
|
class extends React.PureComponent {
|
||||||
static displayName = `withNavigationScrolling(${
|
static displayName = `withNavigationScrolling(${
|
||||||
Component.displayName || Component.name
|
Component.displayName || Component.name
|
||||||
})`;
|
})`;
|
||||||
@@ -60,7 +60,7 @@ export default function createNavigationAwareScrollable(Component) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
class NavigationAwareScrollable extends React.PureComponent<any> {
|
class NavigationAwareScrollable extends React.PureComponent {
|
||||||
static displayName = `NavigationAwareScrollable(${
|
static displayName = `NavigationAwareScrollable(${
|
||||||
Component.displayName || Component.name
|
Component.displayName || Component.name
|
||||||
})`;
|
})`;
|
||||||
|
|||||||
@@ -43,6 +43,24 @@ module.exports = {
|
|||||||
get createNavigationFactory() {
|
get createNavigationFactory() {
|
||||||
return require('./throwIfWrongVersion').default;
|
return require('./throwIfWrongVersion').default;
|
||||||
},
|
},
|
||||||
|
get useNavigationBuilder() {
|
||||||
|
return require('./throwIfWrongVersion').default;
|
||||||
|
},
|
||||||
|
get useNavigation() {
|
||||||
|
return require('./throwIfWrongVersion').default;
|
||||||
|
},
|
||||||
|
get useRoute() {
|
||||||
|
return require('./throwIfWrongVersion').default;
|
||||||
|
},
|
||||||
|
get useFocusEffect() {
|
||||||
|
return require('./throwIfWrongVersion').default;
|
||||||
|
},
|
||||||
|
get useIsFocused() {
|
||||||
|
return require('./throwIfWrongVersion').default;
|
||||||
|
},
|
||||||
|
get useNavigationState() {
|
||||||
|
return require('./throwIfWrongVersion').default;
|
||||||
|
},
|
||||||
get NavigationContainer() {
|
get NavigationContainer() {
|
||||||
return require('./throwIfWrongVersion').default;
|
return require('./throwIfWrongVersion').default;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default function () {
|
export default function () {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"This version of '@react-navigation/native' is not compatible with React Navigation 5. Make sure you install 5.x version of '@react-navigation/native'."
|
'Looks like you are trying to use React Navigation 5 APIs, but have React Navigation 4 installed.\n\nMixing React Navigation 4 and 5 is not supported. See the documentation for installation instructions and usage guide for appropriate versions:\n\n- React Navigation 5: https://reactnavigation.org/docs/getting-started\n- React Navigation 4: https://reactnavigation.org/docs/4.x/getting-started'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { Dimensions } from 'react-native';
|
import { Dimensions } from 'react-native';
|
||||||
import hoistNonReactStatic from 'hoist-non-react-statics';
|
import hoistNonReactStatic from 'hoist-non-react-statics';
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,92 @@
|
|||||||
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.
|
||||||
|
|
||||||
|
## [4.4.3](https://github.com/react-navigation/react-navigation/compare/react-navigation@4.4.2...react-navigation@4.4.3) (2020-10-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.4.2](https://github.com/react-navigation/react-navigation/compare/react-navigation@4.4.1...react-navigation@4.4.2) (2020-10-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.4.1](https://github.com/react-navigation/react-navigation/compare/react-navigation@4.4.0...react-navigation@4.4.1) (2020-09-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [4.4.0](https://github.com/react-navigation/react-navigation/compare/react-navigation@4.3.9...react-navigation@4.4.0) (2020-06-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* sync latest stack and upgrade typescript ([454e05b](https://github.com/react-navigation/react-navigation/commit/454e05b02ec97f053b381fdc801df899d8c93cb6))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.3.9](https://github.com/react-navigation/react-navigation/compare/react-navigation@4.3.8...react-navigation@4.3.9) (2020-04-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* change old docUrl to new docUrl due v5 ([e09906a](https://github.com/react-navigation/react-navigation/commit/e09906a4235a0fca09140923ebe7af34b50b491a))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.3.8](https://github.com/react-navigation/react-navigation/compare/react-navigation@4.3.7...react-navigation@4.3.8) (2020-04-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.3.7](https://github.com/react-navigation/react-navigation/compare/react-navigation@4.3.6...react-navigation@4.3.7) (2020-04-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.3.6](https://github.com/react-navigation/react-navigation/compare/react-navigation@4.3.5...react-navigation@4.3.6) (2020-03-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.3.5](https://github.com/react-navigation/react-navigation/compare/react-navigation@4.3.3...react-navigation@4.3.5) (2020-03-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.3.4](https://github.com/react-navigation/react-navigation/compare/react-navigation@4.3.3...react-navigation@4.3.4) (2020-03-27)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [4.3.3](https://github.com/react-navigation/react-navigation/compare/react-navigation@4.3.2...react-navigation@4.3.3) (2020-03-22)
|
## [4.3.3](https://github.com/react-navigation/react-navigation/compare/react-navigation@4.3.2...react-navigation@4.3.3) (2020-03-22)
|
||||||
|
|
||||||
**Note:** Version bump only for package react-navigation
|
**Note:** Version bump only for package react-navigation
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-navigation",
|
"name": "react-navigation",
|
||||||
"version": "4.3.3",
|
"version": "4.4.3",
|
||||||
"description": "Routing and navigation for your React Native apps",
|
"description": "Routing and navigation for your React Native apps",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"types": "typescript/react-navigation.d.ts",
|
"types": "typescript/react-navigation.d.ts",
|
||||||
@@ -24,16 +24,16 @@
|
|||||||
"react-native": "*"
|
"react-native": "*"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-navigation/core": "^3.7.1",
|
"@react-navigation/core": "^3.7.9",
|
||||||
"@react-navigation/native": "^3.7.7"
|
"@react-navigation/native": "^3.8.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^16.9.23",
|
"@types/react": "^16.9.53",
|
||||||
"@types/react-native": "^0.61.22",
|
"@types/react-native": "^0.63.30",
|
||||||
"@types/react-test-renderer": "^16.9.2",
|
"@types/react-test-renderer": "^16.9.3",
|
||||||
"react": "~16.9.0",
|
"react": "~16.13.1",
|
||||||
"react-native": "~0.61.5",
|
"react-native": "~0.63.2",
|
||||||
"react-test-renderer": "^16.9.2",
|
"react-test-renderer": "~16.13.1",
|
||||||
"typescript": "~3.7.5"
|
"typescript": "^4.0.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
import renderer from 'react-test-renderer';
|
import renderer from 'react-test-renderer';
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
export default function docsUrl(path) {
|
export default function docsUrl(path) {
|
||||||
return `https://reactnavigation.org/docs/${path}`;
|
return `https://reactnavigation.org/docs/4.x/${path}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -734,7 +734,9 @@ export namespace StackActions {
|
|||||||
export const REPLACE: 'Navigation/REPLACE';
|
export const REPLACE: 'Navigation/REPLACE';
|
||||||
export const COMPLETE_TRANSITION: 'Navigation/COMPLETE_TRANSITION';
|
export const COMPLETE_TRANSITION: 'Navigation/COMPLETE_TRANSITION';
|
||||||
|
|
||||||
export function pop(options: NavigationPopActionPayload): NavigationPopAction;
|
export function pop(
|
||||||
|
options?: NavigationPopActionPayload
|
||||||
|
): NavigationPopAction;
|
||||||
export function popToTop(
|
export function popToTop(
|
||||||
options?: NavigationPopToTopActionPayload
|
options?: NavigationPopToTopActionPayload
|
||||||
): NavigationPopToTopAction;
|
): NavigationPopToTopAction;
|
||||||
@@ -810,17 +812,16 @@ export interface NavigationDescriptor<
|
|||||||
getComponent: () => React.ComponentType;
|
getComponent: () => React.ComponentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type NavigationView<
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
Options,
|
export type NavigationView<Options, State, ScreenProps = unknown> =
|
||||||
State,
|
| React.ComponentType<
|
||||||
ScreenProps = unknown
|
{
|
||||||
> = React.ComponentType<
|
descriptors: { [key: string]: NavigationDescriptor };
|
||||||
{
|
navigationConfig: Options;
|
||||||
descriptors: { [key: string]: NavigationDescriptor };
|
screenProps?: ScreenProps;
|
||||||
navigationConfig: Options;
|
} & NavigationInjectedProps
|
||||||
screenProps?: ScreenProps;
|
>
|
||||||
} & NavigationInjectedProps
|
| React.ComponentType<any>;
|
||||||
>;
|
|
||||||
|
|
||||||
export type CreateNavigatorConfig<
|
export type CreateNavigatorConfig<
|
||||||
NavigatorConfig,
|
NavigatorConfig,
|
||||||
@@ -897,11 +898,13 @@ export function withNavigation<
|
|||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-redeclare
|
||||||
export function withNavigation<P extends NavigationInjectedProps>(
|
export function withNavigation<P extends NavigationInjectedProps>(
|
||||||
Component: React.ComponentType<P>
|
Component: React.ComponentType<P>
|
||||||
): React.ComponentType<Omit<P, keyof NavigationInjectedProps>>;
|
): React.ComponentType<Omit<P, keyof NavigationInjectedProps>>;
|
||||||
|
|
||||||
// For backwards compatibility
|
// For backwards compatibility
|
||||||
|
// eslint-disable-next-line no-redeclare
|
||||||
export function withNavigation<T = {}, P = NavigationParams>(
|
export function withNavigation<T = {}, P = NavigationParams>(
|
||||||
Component: React.ComponentType<T & NavigationInjectedProps<P>>
|
Component: React.ComponentType<T & NavigationInjectedProps<P>>
|
||||||
): React.ComponentType<
|
): React.ComponentType<
|
||||||
@@ -929,11 +932,13 @@ export function withNavigationFocus<
|
|||||||
}
|
}
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-redeclare
|
||||||
export function withNavigationFocus<P extends NavigationFocusInjectedProps>(
|
export function withNavigationFocus<P extends NavigationFocusInjectedProps>(
|
||||||
Component: React.ComponentType<P>
|
Component: React.ComponentType<P>
|
||||||
): React.ComponentType<Omit<P, keyof NavigationFocusInjectedProps>>;
|
): React.ComponentType<Omit<P, keyof NavigationFocusInjectedProps>>;
|
||||||
|
|
||||||
// For backwards compatibility
|
// For backwards compatibility
|
||||||
|
// eslint-disable-next-line no-redeclare
|
||||||
export function withNavigationFocus<T = {}, P = NavigationParams>(
|
export function withNavigationFocus<T = {}, P = NavigationParams>(
|
||||||
Component: React.ComponentType<T & NavigationFocusInjectedProps<P>>
|
Component: React.ComponentType<T & NavigationFocusInjectedProps<P>>
|
||||||
): React.ComponentType<
|
): React.ComponentType<
|
||||||
|
|||||||
@@ -3,6 +3,206 @@
|
|||||||
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.10.2](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.10.1...react-navigation-stack@2.10.2) (2020-11-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-stack
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.10.1](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.10.0...react-navigation-stack@2.10.1) (2020-11-04)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-stack
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [2.10.0](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.9.0...react-navigation-stack@2.10.0) (2020-10-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* enable react-native-screens in Stack by default on iOS ([8411e6f](https://github.com/react-navigation/react-navigation-stack/commit/8411e6f764b86341e747cb7ca1ff4a775b4a827a))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [2.9.0](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.8.4...react-navigation-stack@2.9.0) (2020-10-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* sync latest stack ([6bdc1e9](https://github.com/react-navigation/react-navigation-stack/commit/6bdc1e9e5f6ca05e0494f6b9a1f7b9b60764628a))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.8.4](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.8.3...react-navigation-stack@2.8.4) (2020-10-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-stack
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.8.3](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.8.2...react-navigation-stack@2.8.3) (2020-09-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-stack
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.8.2](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.8.1...react-navigation-stack@2.8.2) (2020-06-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* sync latest stack ([46b797d](https://github.com/react-navigation/react-navigation-stack/commit/46b797dd297f789e3c92ff6f5c4432fedc891767))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.8.1](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.8.0...react-navigation-stack@2.8.1) (2020-06-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* pop with correct key from nested stack ([2e7f4a6](https://github.com/react-navigation/react-navigation-stack/commit/2e7f4a6d10a00930bd5c53ef6f4bf964c9638db5))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [2.8.0](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.7.0...react-navigation-stack@2.8.0) (2020-06-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* sync latest stack and upgrade typescript ([454e05b](https://github.com/react-navigation/react-navigation-stack/commit/454e05b02ec97f053b381fdc801df899d8c93cb6))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [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)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* sync latest stack ([bb82d50](https://github.com/react-navigation/react-navigation-stack/commit/bb82d5000f6577f421cc7f72df8064eb4c2a0650))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [2.4.0](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.3.13...react-navigation-stack@2.4.0) (2020-04-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* sync latest stack ([8b79e9b](https://github.com/react-navigation/react-navigation-stack/commit/8b79e9bee65c3ba6a788ca76771379319168f117))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.3.13](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.3.12...react-navigation-stack@2.3.13) (2020-04-22)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-stack
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.3.12](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.3.11...react-navigation-stack@2.3.12) (2020-04-17)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* stack peer warnings ([4c4e66f](https://github.com/react-navigation/react-navigation-stack/commit/4c4e66f05cd4d694f512f4cc38827f3fbf0f70de))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.3.11](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.3.10...react-navigation-stack@2.3.11) (2020-04-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-stack
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.3.10](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.3.9...react-navigation-stack@2.3.10) (2020-03-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package react-navigation-stack
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.3.9](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.3.7...react-navigation-stack@2.3.9) (2020-03-28)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* emit didFocus and didBlur events based on parent's transition ([14a6538](https://github.com/react-navigation/react-navigation-stack/commit/14a6538cc8e12c50d5d10722d75c9395a0a281ec))
|
||||||
|
* rework focus and blur events to make them more reliable ([cd08338](https://github.com/react-navigation/react-navigation-stack/commit/cd083381866506a192f1ec842ac169f2b4277ca5)), closes [#4867](https://github.com/react-navigation/react-navigation-stack/issues/4867) [#6187](https://github.com/react-navigation/react-navigation-stack/issues/6187) [#6451](https://github.com/react-navigation/react-navigation-stack/issues/6451) [#7628](https://github.com/react-navigation/react-navigation-stack/issues/7628) [#7749](https://github.com/react-navigation/react-navigation-stack/issues/7749)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.3.8](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.3.7...react-navigation-stack@2.3.8) (2020-03-27)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* rework focus and blur events to make them more reliable ([cd08338](https://github.com/react-navigation/react-navigation-stack/commit/cd083381866506a192f1ec842ac169f2b4277ca5)), closes [#4867](https://github.com/react-navigation/react-navigation-stack/issues/4867) [#6187](https://github.com/react-navigation/react-navigation-stack/issues/6187) [#6451](https://github.com/react-navigation/react-navigation-stack/issues/6451) [#7628](https://github.com/react-navigation/react-navigation-stack/issues/7628) [#7749](https://github.com/react-navigation/react-navigation-stack/issues/7749)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [2.3.7](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.3.6...react-navigation-stack@2.3.7) (2020-03-27)
|
## [2.3.7](https://github.com/react-navigation/react-navigation-stack/compare/react-navigation-stack@2.3.6...react-navigation-stack@2.3.7) (2020-03-27)
|
||||||
|
|
||||||
**Note:** Version bump only for package react-navigation-stack
|
**Note:** Version bump only for package react-navigation-stack
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ yarn example start
|
|||||||
|
|
||||||
The code in this repo uses the source from [`@react-navigation/stack`](https://github.com/react-navigation/navigation-ex/tree/master/packages/stack) and patches it to make it usable in React Navigation 4. If you need to make changes, please send a pull request there.
|
The code in this repo uses the source from [`@react-navigation/stack`](https://github.com/react-navigation/navigation-ex/tree/master/packages/stack) and patches it to make it usable in React Navigation 4. If you need to make changes, please send a pull request there.
|
||||||
|
|
||||||
If the change is specifically related to React Navigation 4 integration, first run `yarn sync`, then change the files in `src/vendor` and then run `yarn patch` to update the patch file with the latest changes.
|
If the change is specifically related to React Navigation 4 integration, first run `yarn patch:apply`, then change the files in `src/vendor` to resolve any conflicts and then run `yarn patch:create` to update the patch file with the latest changes.
|
||||||
|
|
||||||
Make sure your code passes TypeScript and ESLint. Run the following to verify:
|
Make sure your code passes TypeScript and ESLint. Run the following to verify:
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-navigation-stack",
|
"name": "react-navigation-stack",
|
||||||
"version": "2.3.7",
|
"version": "2.10.2",
|
||||||
"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",
|
||||||
@@ -13,8 +13,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"prepare": "bob build",
|
"prepare": "bob build",
|
||||||
"clean": "del lib",
|
"clean": "del lib",
|
||||||
"sync": "bash scripts/sync-stack.sh",
|
"patch:apply": "bash scripts/sync-stack.sh",
|
||||||
"patch": "diff -Naur ../../node_modules/@react-navigation/stack/src src/vendor > scripts/stack.patch; printf ''"
|
"patch:create": "diff -Naur ../../node_modules/@react-navigation/stack/src src/vendor > scripts/stack.patch; printf ''"
|
||||||
},
|
},
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
@@ -39,33 +39,33 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/react-navigation/react-navigation-stack#readme",
|
"homepage": "https://github.com/react-navigation/react-navigation-stack#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"color": "^3.1.2",
|
"color": "^3.1.3",
|
||||||
"react-native-iphone-x-helper": "^1.2.1"
|
"react-native-iphone-x-helper": "^1.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@react-native-community/bob": "^0.10.0",
|
"@react-native-community/bob": "^0.16.2",
|
||||||
"@react-native-community/masked-view": "^0.1.7",
|
"@react-native-community/masked-view": "0.1.10",
|
||||||
"@react-navigation/stack": "^5.2.7",
|
"@react-navigation/stack": "^5.12.8",
|
||||||
"@types/color": "^3.0.1",
|
"@types/color": "^3.0.1",
|
||||||
"@types/react": "^16.9.23",
|
"@types/react": "^16.9.53",
|
||||||
"@types/react-native": "^0.61.22",
|
"@types/react-native": "^0.63.30",
|
||||||
"@types/react-test-renderer": "^16.9.2",
|
"@types/react-test-renderer": "^16.9.3",
|
||||||
"del-cli": "^3.0.0",
|
"del-cli": "^3.0.1",
|
||||||
"react": "~16.9.0",
|
"react": "~16.13.1",
|
||||||
"react-native": "~0.61.4",
|
"react-native": "~0.63.2",
|
||||||
"react-native-gesture-handler": "^1.6.0",
|
"react-native-gesture-handler": "~1.7.0",
|
||||||
"react-native-safe-area-context": "^0.7.3",
|
"react-native-safe-area-context": "3.1.4",
|
||||||
"react-native-screens": "^2.3.0",
|
"react-native-screens": "~2.10.1",
|
||||||
"react-navigation": "^4.3.3",
|
"react-navigation": "^4.4.3",
|
||||||
"react-test-renderer": "~16.9.0",
|
"react-test-renderer": "~16.13.1",
|
||||||
"typescript": "~3.7.5"
|
"typescript": "^4.0.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@react-native-community/masked-view": "^0.1.1",
|
"@react-native-community/masked-view": ">=0.1.0",
|
||||||
"react": "*",
|
"react": "*",
|
||||||
"react-native": "*",
|
"react-native": "*",
|
||||||
"react-native-gesture-handler": "^1.5.0",
|
"react-native-gesture-handler": ">= 1.5.0",
|
||||||
"react-native-safe-area-context": "^0.6.0",
|
"react-native-safe-area-context": ">= 0.6.0",
|
||||||
"react-native-screens": ">=1.0.0 || >= 2.0.0-alpha.0 || >= 2.0.0-beta.0 || >= 2.0.0",
|
"react-native-screens": ">=1.0.0 || >= 2.0.0-alpha.0 || >= 2.0.0-beta.0 || >= 2.0.0",
|
||||||
"react-navigation": "^4.1.1"
|
"react-navigation": "^4.1.1"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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-03-23 00:04:17.000000000 +0100
|
--- ../../node_modules/@react-navigation/stack/src/index.tsx 2020-11-10 21:02:55.000000000 +0100
|
||||||
+++ src/vendor/index.tsx 2020-03-23 00:04:37.000000000 +0100
|
+++ src/vendor/index.tsx 2020-11-10 21:04:07.000000000 +0100
|
||||||
@@ -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';
|
||||||
@@ -16,22 +16,23 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/index.tsx src/vendor/i
|
|||||||
@@ -49,9 +44,10 @@
|
@@ -49,9 +44,10 @@
|
||||||
* Types
|
* Types
|
||||||
*/
|
*/
|
||||||
export {
|
export type {
|
||||||
- StackNavigationOptions,
|
- StackNavigationOptions,
|
||||||
- StackNavigationProp,
|
- StackNavigationProp,
|
||||||
- StackHeaderProps,
|
- StackScreenProps,
|
||||||
+ NavigationStackState,
|
+ NavigationStackState,
|
||||||
+ StackNavigationProp as NavigationStackProp,
|
+ StackNavigationProp as NavigationStackProp,
|
||||||
+ StackNavigationOptions as NavigationStackOptions,
|
+ StackNavigationOptions as NavigationStackOptions,
|
||||||
+ StackNavigationConfig as NavigationStackConfig,
|
+ StackNavigationConfig as NavigationStackConfig,
|
||||||
|
StackHeaderProps,
|
||||||
StackHeaderLeftButtonProps,
|
StackHeaderLeftButtonProps,
|
||||||
StackHeaderTitleProps,
|
StackHeaderTitleProps,
|
||||||
StackCardInterpolatedStyle,
|
|
||||||
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-03-23 00:04:17.000000000 +0100
|
--- ../../node_modules/@react-navigation/stack/src/navigators/createStackNavigator.tsx 2020-11-10 21:02:55.000000000 +0100
|
||||||
+++ 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,81 +0,0 @@
|
@@ -1,101 +0,0 @@
|
||||||
-import * as React from 'react';
|
-import * as React from 'react';
|
||||||
|
-import { Platform } from 'react-native';
|
||||||
-import {
|
-import {
|
||||||
- useNavigationBuilder,
|
- useNavigationBuilder,
|
||||||
- createNavigatorFactory,
|
- createNavigatorFactory,
|
||||||
@@ -41,9 +42,11 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/navigators/createStack
|
|||||||
- StackRouterOptions,
|
- StackRouterOptions,
|
||||||
- StackNavigationState,
|
- StackNavigationState,
|
||||||
- StackActions,
|
- StackActions,
|
||||||
|
- ParamListBase,
|
||||||
|
- StackActionHelpers,
|
||||||
-} from '@react-navigation/native';
|
-} from '@react-navigation/native';
|
||||||
-import StackView from '../views/Stack/StackView';
|
-import StackView from '../views/Stack/StackView';
|
||||||
-import {
|
-import type {
|
||||||
- StackNavigationConfig,
|
- StackNavigationConfig,
|
||||||
- StackNavigationOptions,
|
- StackNavigationOptions,
|
||||||
- StackNavigationEventMap,
|
- StackNavigationEventMap,
|
||||||
@@ -59,21 +62,38 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/navigators/createStack
|
|||||||
- screenOptions,
|
- screenOptions,
|
||||||
- ...rest
|
- ...rest
|
||||||
-}: Props) {
|
-}: Props) {
|
||||||
|
- const defaultOptions = {
|
||||||
|
- gestureEnabled: Platform.OS === 'ios',
|
||||||
|
- animationEnabled:
|
||||||
|
- Platform.OS !== 'web' &&
|
||||||
|
- Platform.OS !== 'windows' &&
|
||||||
|
- Platform.OS !== 'macos',
|
||||||
|
- };
|
||||||
|
-
|
||||||
- const { state, descriptors, navigation } = useNavigationBuilder<
|
- const { state, descriptors, navigation } = useNavigationBuilder<
|
||||||
- StackNavigationState,
|
- StackNavigationState<ParamListBase>,
|
||||||
- StackRouterOptions,
|
- StackRouterOptions,
|
||||||
|
- StackActionHelpers<ParamListBase>,
|
||||||
- StackNavigationOptions,
|
- StackNavigationOptions,
|
||||||
- StackNavigationEventMap
|
- StackNavigationEventMap
|
||||||
- >(StackRouter, {
|
- >(StackRouter, {
|
||||||
- initialRouteName,
|
- initialRouteName,
|
||||||
- children,
|
- children,
|
||||||
- screenOptions,
|
- screenOptions:
|
||||||
|
- typeof screenOptions === 'function'
|
||||||
|
- ? (...args) => ({
|
||||||
|
- ...defaultOptions,
|
||||||
|
- ...screenOptions(...args),
|
||||||
|
- })
|
||||||
|
- : {
|
||||||
|
- ...defaultOptions,
|
||||||
|
- ...screenOptions,
|
||||||
|
- },
|
||||||
- });
|
- });
|
||||||
-
|
-
|
||||||
- React.useEffect(
|
- React.useEffect(
|
||||||
- () =>
|
- () =>
|
||||||
- navigation.addListener &&
|
- navigation.addListener?.('tabPress', (e) => {
|
||||||
- navigation.addListener('tabPress', (e) => {
|
|
||||||
- const isFocused = navigation.isFocused();
|
- const isFocused = navigation.isFocused();
|
||||||
-
|
-
|
||||||
- // Run the operation in the next frame so we're sure all listeners have been run
|
- // Run the operation in the next frame so we're sure all listeners have been run
|
||||||
@@ -107,18 +127,18 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/navigators/createStack
|
|||||||
-}
|
-}
|
||||||
-
|
-
|
||||||
-export default createNavigatorFactory<
|
-export default createNavigatorFactory<
|
||||||
- StackNavigationState,
|
- StackNavigationState<ParamListBase>,
|
||||||
- StackNavigationOptions,
|
- StackNavigationOptions,
|
||||||
- StackNavigationEventMap,
|
- StackNavigationEventMap,
|
||||||
- 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-03-23 00:04:17.000000000 +0100
|
--- ../../node_modules/@react-navigation/stack/src/types.tsx 2020-11-10 21:02:55.000000000 +0100
|
||||||
+++ src/vendor/types.tsx 2020-03-23 00:04:40.000000000 +0100
|
+++ src/vendor/types.tsx 2020-11-10 21:04:07.000000000 +0100
|
||||||
@@ -8,14 +8,28 @@
|
@@ -8,15 +8,29 @@
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { EdgeInsets } from 'react-native-safe-area-context';
|
import type { EdgeInsets } from 'react-native-safe-area-context';
|
||||||
import {
|
import type {
|
||||||
+ NavigationRoute,
|
+ NavigationRoute,
|
||||||
+ NavigationState,
|
+ NavigationState,
|
||||||
+ NavigationScreenProp,
|
+ NavigationScreenProp,
|
||||||
@@ -129,6 +149,7 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/types.tsx src/vendor/t
|
|||||||
- NavigationHelpers,
|
- NavigationHelpers,
|
||||||
- StackNavigationState,
|
- StackNavigationState,
|
||||||
- StackActionHelpers,
|
- StackActionHelpers,
|
||||||
|
- RouteProp,
|
||||||
-} from '@react-navigation/native';
|
-} from '@react-navigation/native';
|
||||||
+ NavigationParams,
|
+ NavigationParams,
|
||||||
+ NavigationNavigateAction,
|
+ NavigationNavigateAction,
|
||||||
@@ -139,6 +160,7 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/types.tsx src/vendor/t
|
|||||||
+} from 'react-navigation';
|
+} from 'react-navigation';
|
||||||
+
|
+
|
||||||
+// @ts-ignore
|
+// @ts-ignore
|
||||||
|
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
+export type Route<T extends string> = NavigationRoute;
|
+export type Route<T extends string> = NavigationRoute;
|
||||||
+
|
+
|
||||||
+export type NavigationStackState = NavigationState;
|
+export type NavigationStackState = NavigationState;
|
||||||
@@ -151,27 +173,35 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/types.tsx src/vendor/t
|
|||||||
|
|
||||||
export type StackNavigationEventMap = {
|
export type StackNavigationEventMap = {
|
||||||
/**
|
/**
|
||||||
@@ -28,22 +42,29 @@
|
@@ -41,30 +55,29 @@
|
||||||
transitionEnd: { data: { closing: boolean } };
|
gestureCancel: { data: undefined };
|
||||||
};
|
};
|
||||||
|
|
||||||
-export type StackNavigationHelpers = NavigationHelpers<
|
-export type StackNavigationHelpers = NavigationHelpers<
|
||||||
- ParamListBase,
|
- ParamListBase,
|
||||||
- StackNavigationEventMap
|
- StackNavigationEventMap
|
||||||
->;
|
-> &
|
||||||
-
|
- StackActionHelpers<ParamListBase>;
|
||||||
+export type StackNavigationHelpers = NavigationProp<NavigationStackState>;
|
+export type StackNavigationHelpers = NavigationProp<NavigationStackState>;
|
||||||
|
|
||||||
export type StackNavigationProp<
|
export type StackNavigationProp<
|
||||||
- ParamList extends ParamListBase,
|
- ParamList extends ParamListBase,
|
||||||
- RouteName extends keyof ParamList = string
|
- RouteName extends keyof ParamList = string
|
||||||
-> = NavigationProp<
|
-> = NavigationProp<
|
||||||
- ParamList,
|
- ParamList,
|
||||||
- RouteName,
|
- RouteName,
|
||||||
- StackNavigationState,
|
- StackNavigationState<ParamList>,
|
||||||
- StackNavigationOptions,
|
- StackNavigationOptions,
|
||||||
- StackNavigationEventMap
|
- StackNavigationEventMap
|
||||||
-> &
|
-> &
|
||||||
- StackActionHelpers<ParamList>;
|
- StackActionHelpers<ParamList>;
|
||||||
|
-
|
||||||
|
-export type StackScreenProps<
|
||||||
|
- ParamList extends ParamListBase,
|
||||||
|
- RouteName extends keyof ParamList = string
|
||||||
|
-> = {
|
||||||
|
- navigation: StackNavigationProp<ParamList, RouteName>;
|
||||||
|
- route: RouteProp<ParamList, RouteName>;
|
||||||
+ State = NavigationRoute,
|
+ State = NavigationRoute,
|
||||||
+ Params = NavigationParams
|
+ Params = NavigationParams
|
||||||
+> = NavigationScreenProp<State, Params> & {
|
+> = NavigationScreenProp<State, Params> & {
|
||||||
@@ -192,11 +222,10 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/types.tsx src/vendor/t
|
|||||||
+ event: NavigationStackEventName,
|
+ event: NavigationStackEventName,
|
||||||
+ callback: NavigationEventCallback
|
+ callback: NavigationEventCallback
|
||||||
+ ) => NavigationEventSubscription;
|
+ ) => NavigationEventSubscription;
|
||||||
+};
|
};
|
||||||
|
|
||||||
export type Layout = { width: number; height: number };
|
export type Layout = { width: number; height: number };
|
||||||
|
@@ -245,24 +258,27 @@
|
||||||
@@ -218,24 +239,27 @@
|
|
||||||
/**
|
/**
|
||||||
* Navigation prop for the header.
|
* Navigation prop for the header.
|
||||||
*/
|
*/
|
||||||
@@ -211,7 +240,7 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/types.tsx src/vendor/t
|
|||||||
-export type StackDescriptor = Descriptor<
|
-export type StackDescriptor = Descriptor<
|
||||||
- ParamListBase,
|
- ParamListBase,
|
||||||
- string,
|
- string,
|
||||||
- StackNavigationState,
|
- StackNavigationState<ParamListBase>,
|
||||||
- StackNavigationOptions
|
- StackNavigationOptions
|
||||||
+export type StackDescriptor = NavigationDescriptor<
|
+export type StackDescriptor = NavigationDescriptor<
|
||||||
+ NavigationParams,
|
+ NavigationParams,
|
||||||
@@ -230,37 +259,49 @@ 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> & {
|
||||||
/**
|
/**
|
||||||
@@ -317,6 +341,8 @@
|
@@ -356,6 +372,8 @@
|
||||||
bottom?: number;
|
* Defaults to `false` for the last screen when mode='modal', otherwise `true`.
|
||||||
left?: number;
|
*/
|
||||||
};
|
detachPreviousScreen?: boolean;
|
||||||
+ onTransitionStart?: (props: TransitionCallbackProps) => void;
|
+ onTransitionStart?: (props: TransitionCallbackProps) => void;
|
||||||
+ onTransitionEnd?: (props: TransitionCallbackProps) => void;
|
+ onTransitionEnd?: (props: TransitionCallbackProps) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type StackNavigationConfig = {
|
export type StackNavigationConfig = {
|
||||||
|
diff -Naur ../../node_modules/@react-navigation/stack/src/utils/PreviousSceneContext.tsx src/vendor/utils/PreviousSceneContext.tsx
|
||||||
|
--- ../../node_modules/@react-navigation/stack/src/utils/PreviousSceneContext.tsx 2020-11-10 21:02:55.000000000 +0100
|
||||||
|
+++ src/vendor/utils/PreviousSceneContext.tsx 2020-11-10 21:04:07.000000000 +0100
|
||||||
|
@@ -1,6 +1,5 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
-import type { Route } from '@react-navigation/native';
|
||||||
|
-import type { Scene } from '../types';
|
||||||
|
+import type { Route, Scene } from '../types';
|
||||||
|
|
||||||
|
const PreviousSceneContext = React.createContext<
|
||||||
|
Scene<Route<string>> | undefined
|
||||||
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-03-23 00:04:17.000000000 +0100
|
--- ../../node_modules/@react-navigation/stack/src/views/Header/Header.tsx 2020-11-10 21:02:55.000000000 +0100
|
||||||
+++ src/vendor/views/Header/Header.tsx 2020-03-23 00:04:40.000000000 +0100
|
+++ src/vendor/views/Header/Header.tsx 2020-11-10 21:04:07.000000000 +0100
|
||||||
@@ -1,12 +1,14 @@
|
@@ -1,12 +1,15 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
-import { StackActions } from '@react-navigation/native';
|
-import { StackActions } from '@react-navigation/native';
|
||||||
+import { Dimensions } from 'react-native';
|
+import { Dimensions } from 'react-native';
|
||||||
+import { StackActions } from 'react-navigation';
|
+import { StackActions } from 'react-navigation';
|
||||||
+import { getStatusBarHeight } from 'react-native-iphone-x-helper';
|
+import { getStatusBarHeight } from 'react-native-iphone-x-helper';
|
||||||
|
+
|
||||||
|
+import HeaderSegment, { getDefaultHeaderHeight } from './HeaderSegment';
|
||||||
|
|
||||||
-import HeaderSegment from './HeaderSegment';
|
-import HeaderSegment from './HeaderSegment';
|
||||||
+import HeaderSegment, { getDefaultHeaderHeight } from './HeaderSegment';
|
|
||||||
import HeaderTitle from './HeaderTitle';
|
import HeaderTitle from './HeaderTitle';
|
||||||
import debounce from '../../utils/debounce';
|
import debounce from '../../utils/debounce';
|
||||||
import { StackHeaderProps, StackHeaderTitleProps } from '../../types';
|
import type { StackHeaderProps, StackHeaderTitleProps } from '../../types';
|
||||||
|
|
||||||
-export default React.memo(function Header(props: StackHeaderProps) {
|
-export default React.memo(function Header(props: StackHeaderProps) {
|
||||||
+const Header = React.memo(function Header(props: StackHeaderProps) {
|
+const Header = React.memo(function Header(props: StackHeaderProps) {
|
||||||
const {
|
const {
|
||||||
scene,
|
scene,
|
||||||
previous,
|
previous,
|
||||||
@@ -22,7 +24,7 @@
|
@@ -22,7 +25,7 @@
|
||||||
? options.headerTitle
|
? options.headerTitle
|
||||||
: options.title !== undefined
|
: options.title !== undefined
|
||||||
? options.title
|
? options.title
|
||||||
@@ -269,7 +310,7 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/Header.ts
|
|||||||
|
|
||||||
let leftLabel;
|
let leftLabel;
|
||||||
|
|
||||||
@@ -38,17 +40,12 @@
|
@@ -38,17 +41,20 @@
|
||||||
? o.headerTitle
|
? o.headerTitle
|
||||||
: o.title !== undefined
|
: o.title !== undefined
|
||||||
? o.title
|
? o.title
|
||||||
@@ -277,6 +318,7 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/Header.ts
|
|||||||
+ : previous.route.routeName;
|
+ : previous.route.routeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
const goBack = React.useCallback(
|
const goBack = React.useCallback(
|
||||||
debounce(() => {
|
debounce(() => {
|
||||||
- if (navigation.isFocused() && navigation.canGoBack()) {
|
- if (navigation.isFocused() && navigation.canGoBack()) {
|
||||||
@@ -284,12 +326,18 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/Header.ts
|
|||||||
- ...StackActions.pop(),
|
- ...StackActions.pop(),
|
||||||
- source: scene.route.key,
|
- source: scene.route.key,
|
||||||
- });
|
- });
|
||||||
- }
|
+ const key = navigation.isFirstRouteInParent()
|
||||||
+ navigation.dispatch(StackActions.pop({ key: scene.route.key }));
|
+ ? // If we're the first route, we're going back to a parent navigator
|
||||||
|
+ // So we need to get the key of the route we're nested in
|
||||||
|
+ navigation.dangerouslyGetParent()?.state.key
|
||||||
|
+ : scene.route.key;
|
||||||
|
+
|
||||||
|
+ if (key !== undefined) {
|
||||||
|
+ navigation.dispatch(StackActions.pop({ key }));
|
||||||
|
}
|
||||||
}, 50),
|
}, 50),
|
||||||
[navigation, scene.route.key]
|
[navigation, scene.route.key]
|
||||||
);
|
@@ -64,7 +70,10 @@
|
||||||
@@ -63,7 +60,10 @@
|
|
||||||
leftLabel={leftLabel}
|
leftLabel={leftLabel}
|
||||||
headerTitle={
|
headerTitle={
|
||||||
typeof options.headerTitle !== 'function'
|
typeof options.headerTitle !== 'function'
|
||||||
@@ -301,7 +349,7 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/Header.ts
|
|||||||
: options.headerTitle
|
: options.headerTitle
|
||||||
}
|
}
|
||||||
onGoBack={previous ? goBack : undefined}
|
onGoBack={previous ? goBack : undefined}
|
||||||
@@ -71,3 +71,18 @@
|
@@ -72,3 +81,18 @@
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -321,8 +369,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-03-23 00:04:17.000000000 +0100
|
--- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderBackButton.tsx 2020-11-10 21:02:55.000000000 +0100
|
||||||
+++ src/vendor/views/Header/HeaderBackButton.tsx 2020-03-23 00:04:40.000000000 +0100
|
+++ src/vendor/views/Header/HeaderBackButton.tsx 2020-11-10 21:04:07.000000000 +0100
|
||||||
@@ -8,9 +8,9 @@
|
@@ -8,9 +8,9 @@
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
LayoutChangeEvent,
|
LayoutChangeEvent,
|
||||||
@@ -331,26 +379,27 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderBac
|
|||||||
import MaskedView from '../MaskedView';
|
import MaskedView from '../MaskedView';
|
||||||
import TouchableItem from '../TouchableItem';
|
import TouchableItem from '../TouchableItem';
|
||||||
+import useTheme from '../../../utils/useTheme';
|
+import useTheme from '../../../utils/useTheme';
|
||||||
import { StackHeaderLeftButtonProps } from '../../types';
|
import type { StackHeaderLeftButtonProps } from '../../types';
|
||||||
|
|
||||||
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-03-23 00:04:17.000000000 +0100
|
--- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderBackground.tsx 2020-11-10 21:02:55.000000000 +0100
|
||||||
+++ src/vendor/views/Header/HeaderBackground.tsx 2020-03-23 00:04:40.000000000 +0100
|
+++ src/vendor/views/Header/HeaderBackground.tsx 2020-11-10 21:04:07.000000000 +0100
|
||||||
@@ -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-03-23 00:04:17.000000000 +0100
|
--- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderContainer.tsx 2020-11-10 21:02:55.000000000 +0100
|
||||||
+++ src/vendor/views/Header/HeaderContainer.tsx 2020-03-23 00:04:40.000000000 +0100
|
+++ src/vendor/views/Header/HeaderContainer.tsx 2020-11-10 21:04:07.000000000 +0100
|
||||||
@@ -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 { Animated, View, StyleSheet, StyleProp, ViewStyle } from 'react-native';
|
||||||
-import {
|
-import {
|
||||||
- NavigationContext,
|
- NavigationContext,
|
||||||
- NavigationRouteContext,
|
- NavigationRouteContext,
|
||||||
@@ -358,17 +407,17 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderCon
|
|||||||
- ParamListBase,
|
- ParamListBase,
|
||||||
-} from '@react-navigation/native';
|
-} from '@react-navigation/native';
|
||||||
+import { NavigationContext } from 'react-navigation';
|
+import { NavigationContext } from 'react-navigation';
|
||||||
import { EdgeInsets } from 'react-native-safe-area-context';
|
import type { EdgeInsets } from 'react-native-safe-area-context';
|
||||||
|
|
||||||
import Header from './Header';
|
import Header from './Header';
|
||||||
@@ -16,6 +11,7 @@
|
@@ -18,6 +13,7 @@
|
||||||
forSlideRight,
|
import PreviousSceneContext from '../../utils/PreviousSceneContext';
|
||||||
} from '../../TransitionConfigs/HeaderStyleInterpolators';
|
import type {
|
||||||
import {
|
|
||||||
+ Route,
|
|
||||||
Layout,
|
Layout,
|
||||||
|
+ Route,
|
||||||
Scene,
|
Scene,
|
||||||
StackHeaderStyleInterpolator,
|
StackHeaderStyleInterpolator,
|
||||||
|
StackNavigationProp,
|
||||||
@@ -99,9 +95,7 @@
|
@@ -99,9 +95,7 @@
|
||||||
insets,
|
insets,
|
||||||
scene,
|
scene,
|
||||||
@@ -389,9 +438,9 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Header/HeaderCon
|
|||||||
<View
|
<View
|
||||||
onLayout={
|
onLayout={
|
||||||
onContentHeightChange
|
onContentHeightChange
|
||||||
@@ -152,7 +146,7 @@
|
@@ -149,7 +143,7 @@
|
||||||
)
|
>
|
||||||
) : null}
|
{header !== undefined ? header(props) : <Header {...props} />}
|
||||||
</View>
|
</View>
|
||||||
- </NavigationRouteContext.Provider>
|
- </NavigationRouteContext.Provider>
|
||||||
+ </>
|
+ </>
|
||||||
@@ -399,18 +448,18 @@ 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-03-23 00:04:17.000000000 +0100
|
--- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderSegment.tsx 2020-11-10 21:02:55.000000000 +0100
|
||||||
+++ src/vendor/views/Header/HeaderSegment.tsx 2020-03-23 00:04:40.000000000 +0100
|
+++ src/vendor/views/Header/HeaderSegment.tsx 2020-11-10 21:04:07.000000000 +0100
|
||||||
@@ -8,7 +8,7 @@
|
@@ -8,7 +8,7 @@
|
||||||
ViewStyle,
|
ViewStyle,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { EdgeInsets } from 'react-native-safe-area-context';
|
import type { EdgeInsets } from 'react-native-safe-area-context';
|
||||||
-import { Route } from '@react-navigation/native';
|
-import type { Route } from '@react-navigation/native';
|
||||||
+import { NavigationRoute } from 'react-navigation';
|
+import type { NavigationRoute } from 'react-navigation';
|
||||||
import HeaderBackButton from './HeaderBackButton';
|
import HeaderBackButton from './HeaderBackButton';
|
||||||
import HeaderBackground from './HeaderBackground';
|
import HeaderBackground from './HeaderBackground';
|
||||||
import memoize from '../../utils/memoize';
|
import HeaderShownContext from '../../utils/HeaderShownContext';
|
||||||
@@ -28,7 +28,7 @@
|
@@ -29,7 +29,7 @@
|
||||||
onGoBack?: () => void;
|
onGoBack?: () => void;
|
||||||
title?: string;
|
title?: string;
|
||||||
leftLabel?: string;
|
leftLabel?: string;
|
||||||
@@ -420,164 +469,132 @@ 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-03-23 00:04:17.000000000 +0100
|
--- ../../node_modules/@react-navigation/stack/src/views/Header/HeaderTitle.tsx 2020-11-10 21:02:55.000000000 +0100
|
||||||
+++ src/vendor/views/Header/HeaderTitle.tsx 2020-03-23 00:04:40.000000000 +0100
|
+++ src/vendor/views/Header/HeaderTitle.tsx 2020-11-10 21:04:07.000000000 +0100
|
||||||
@@ -1,6 +1,6 @@
|
@@ -7,7 +7,7 @@
|
||||||
import * as React from 'react';
|
StyleProp,
|
||||||
import { Animated, StyleSheet, Platform } from 'react-native';
|
TextStyle,
|
||||||
|
} 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 = React.ComponentProps<typeof Animated.Text> & {
|
type Props = Omit<TextProps, 'style'> & {
|
||||||
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-03-23 00:04:17.000000000 +0100
|
--- ../../node_modules/@react-navigation/stack/src/views/Stack/Card.tsx 2020-11-10 21:02:55.000000000 +0100
|
||||||
+++ src/vendor/views/Stack/Card.tsx 2020-03-23 00:04:40.000000000 +0100
|
+++ src/vendor/views/Stack/Card.tsx 2020-11-10 21:04:07.000000000 +0100
|
||||||
@@ -138,7 +138,7 @@
|
@@ -162,7 +162,7 @@
|
||||||
|
|
||||||
private interactionHandle: number | undefined;
|
private interactionHandle: number | undefined;
|
||||||
|
|
||||||
- private pendingGestureCallback: number | undefined;
|
- private pendingGestureCallback: number | undefined;
|
||||||
+ private pendingGestureCallback: any;
|
+ private pendingGestureCallback: any;
|
||||||
|
|
||||||
private animate = ({
|
private lastToValue: number | undefined;
|
||||||
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-03-23 00:04:17.000000000 +0100
|
--- ../../node_modules/@react-navigation/stack/src/views/Stack/CardContainer.tsx 2020-11-10 21:02:55.000000000 +0100
|
||||||
+++ src/vendor/views/Stack/CardContainer.tsx 2020-03-23 00:04:40.000000000 +0100
|
+++ src/vendor/views/Stack/CardContainer.tsx 2020-11-10 21:04:07.000000000 +0100
|
||||||
@@ -1,10 +1,16 @@
|
@@ -1,12 +1,13 @@
|
||||||
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 type { 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 { Scene, Layout, StackHeaderMode, TransitionPreset } from '../../types';
|
import HeaderShownContext from '../../utils/HeaderShownContext';
|
||||||
|
import PreviousSceneContext from '../../utils/PreviousSceneContext';
|
||||||
+import useTheme from '../../../utils/useTheme';
|
+import useTheme from '../../../utils/useTheme';
|
||||||
+import {
|
import type {
|
||||||
+ Route,
|
+ Route,
|
||||||
+ Scene,
|
Scene,
|
||||||
+ Layout,
|
Layout,
|
||||||
+ StackHeaderMode,
|
StackHeaderMode,
|
||||||
+ TransitionPreset,
|
|
||||||
+} from '../../types';
|
|
||||||
|
|
||||||
type Props = TransitionPreset & {
|
|
||||||
index: number;
|
|
||||||
@@ -36,6 +42,7 @@
|
|
||||||
closing: boolean
|
|
||||||
) => void;
|
|
||||||
onTransitionEnd?: (props: { route: Route<string> }, closing: boolean) => void;
|
|
||||||
+ onTransitionComplete: (props: { route: Route<string> }) => void;
|
|
||||||
onPageChangeStart?: () => void;
|
|
||||||
onPageChangeConfirm?: () => void;
|
|
||||||
onPageChangeCancel?: () => void;
|
|
||||||
@@ -83,6 +90,7 @@
|
|
||||||
layout,
|
|
||||||
onCloseRoute,
|
|
||||||
onOpenRoute,
|
|
||||||
+ onTransitionComplete,
|
|
||||||
onPageChangeCancel,
|
|
||||||
onPageChangeConfirm,
|
|
||||||
onPageChangeStart,
|
|
||||||
@@ -152,6 +160,9 @@
|
|
||||||
};
|
|
||||||
}, [pointerEvents, scene.progress.next]);
|
|
||||||
|
|
||||||
+ // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
+ React.useEffect(() => onTransitionComplete({ route: scene.route }), []);
|
|
||||||
+
|
|
||||||
return (
|
|
||||||
<Card
|
|
||||||
index={index}
|
|
||||||
@@ -183,7 +194,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-03-23 00:04:17.000000000 +0100
|
--- ../../node_modules/@react-navigation/stack/src/views/Stack/CardStack.tsx 2020-11-10 21:02:55.000000000 +0100
|
||||||
+++ src/vendor/views/Stack/CardStack.tsx 2020-03-23 00:04:40.000000000 +0100
|
+++ src/vendor/views/Stack/CardStack.tsx 2020-11-10 21:04:07.000000000 +0100
|
||||||
@@ -9,9 +9,8 @@
|
@@ -6,11 +6,7 @@
|
||||||
ViewProps,
|
Dimensions,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { EdgeInsets } from 'react-native-safe-area-context';
|
import type { EdgeInsets } from 'react-native-safe-area-context';
|
||||||
-// eslint-disable-next-line import/no-unresolved
|
-import type {
|
||||||
import { ScreenContainer, Screen, screensEnabled } from 'react-native-screens'; // Import with * as to prevent getters being called
|
- ParamListBase,
|
||||||
-import { Route, StackNavigationState } from '@react-navigation/native';
|
- Route,
|
||||||
+import { NavigationState as StackNavigationState } from 'react-navigation';
|
- StackNavigationState,
|
||||||
|
-} from '@react-navigation/native';
|
||||||
|
+import type { NavigationState as StackNavigationState } from 'react-navigation';
|
||||||
|
|
||||||
import { getDefaultHeaderHeight } from '../Header/HeaderSegment';
|
|
||||||
import { Props as HeaderContainerProps } from '../Header/HeaderContainer';
|
|
||||||
@@ -24,6 +23,7 @@
|
|
||||||
import { forNoAnimation as forNoAnimationCard } from '../../TransitionConfigs/CardStyleInterpolators';
|
|
||||||
import getDistanceForDirection from '../../utils/getDistanceForDirection';
|
|
||||||
import {
|
import {
|
||||||
+ Route,
|
MaybeScreenContainer,
|
||||||
|
@@ -31,6 +27,7 @@
|
||||||
Layout,
|
Layout,
|
||||||
StackHeaderMode,
|
StackHeaderMode,
|
||||||
StackCardMode,
|
StackCardMode,
|
||||||
@@ -54,6 +54,7 @@
|
+ Route,
|
||||||
renderHeader: (props: HeaderContainerProps) => React.ReactNode;
|
Scene,
|
||||||
renderScene: (props: { route: Route<string> }) => React.ReactNode;
|
StackDescriptorMap,
|
||||||
headerMode: StackHeaderMode;
|
StackNavigationOptions,
|
||||||
+ onTransitionComplete: (props: { route: Route<string> }) => void;
|
@@ -44,7 +41,7 @@
|
||||||
onTransitionStart: (
|
type Props = {
|
||||||
props: { route: Route<string> },
|
mode: StackCardMode;
|
||||||
closing: boolean
|
insets: EdgeInsets;
|
||||||
@@ -383,6 +384,7 @@
|
- state: StackNavigationState<ParamListBase>;
|
||||||
renderHeader,
|
+ state: StackNavigationState;
|
||||||
renderScene,
|
descriptors: StackDescriptorMap;
|
||||||
headerMode,
|
routes: Route<string>[];
|
||||||
+ onTransitionComplete,
|
openingRouteKeys: string[];
|
||||||
onTransitionStart,
|
|
||||||
onTransitionEnd,
|
|
||||||
onPageChangeStart,
|
|
||||||
@@ -560,6 +562,7 @@
|
|
||||||
renderScene={renderScene}
|
|
||||||
onOpenRoute={onOpenRoute}
|
|
||||||
onCloseRoute={onCloseRoute}
|
|
||||||
+ onTransitionComplete={onTransitionComplete}
|
|
||||||
onTransitionStart={onTransitionStart}
|
|
||||||
onTransitionEnd={onTransitionEnd}
|
|
||||||
gestureEnabled={index !== 0 && getGesturesEnabled({ route })}
|
|
||||||
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-03-23 00:04:17.000000000 +0100
|
--- ../../node_modules/@react-navigation/stack/src/views/Stack/StackView.tsx 2020-11-10 21:02:55.000000000 +0100
|
||||||
+++ src/vendor/views/Stack/StackView.tsx 2020-03-23 00:07:11.000000000 +0100
|
+++ src/vendor/views/Stack/StackView.tsx 2020-11-10 21:04:07.000000000 +0100
|
||||||
@@ -4,9 +4,9 @@
|
@@ -2,12 +2,11 @@
|
||||||
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
import { View, Platform, StyleSheet } from 'react-native';
|
||||||
|
import { SafeAreaConsumer, EdgeInsets } from 'react-native-safe-area-context';
|
||||||
import {
|
import {
|
||||||
|
- NavigationHelpersContext,
|
||||||
StackActions,
|
StackActions,
|
||||||
- StackNavigationState,
|
- StackNavigationState,
|
||||||
- Route,
|
- Route,
|
||||||
|
- ParamListBase,
|
||||||
-} from '@react-navigation/native';
|
-} from '@react-navigation/native';
|
||||||
+ NavigationState as StackNavigationState,
|
+ NavigationState as StackNavigationState,
|
||||||
|
+ NavigationActions,
|
||||||
+ SceneView,
|
+ SceneView,
|
||||||
+} from 'react-navigation';
|
+} from 'react-navigation';
|
||||||
|
|
||||||
|
import { GestureHandlerRootView } from '../GestureHandler';
|
||||||
import CardStack from './CardStack';
|
import CardStack from './CardStack';
|
||||||
import KeyboardManager from '../KeyboardManager';
|
@@ -17,6 +16,7 @@
|
||||||
@@ -15,6 +15,7 @@
|
|
||||||
} from '../Header/HeaderContainer';
|
} from '../Header/HeaderContainer';
|
||||||
import SafeAreaProviderCompat from '../SafeAreaProviderCompat';
|
import SafeAreaProviderCompat from '../SafeAreaProviderCompat';
|
||||||
import {
|
import type {
|
||||||
+ Route,
|
+ Route,
|
||||||
StackNavigationHelpers,
|
StackNavigationHelpers,
|
||||||
StackNavigationConfig,
|
StackNavigationConfig,
|
||||||
StackDescriptorMap,
|
StackDescriptorMap,
|
||||||
@@ -24,6 +25,7 @@
|
@@ -24,9 +24,10 @@
|
||||||
state: StackNavigationState;
|
import HeaderShownContext from '../../utils/HeaderShownContext';
|
||||||
|
|
||||||
|
type Props = StackNavigationConfig & {
|
||||||
|
- state: StackNavigationState<ParamListBase>;
|
||||||
|
+ state: StackNavigationState;
|
||||||
navigation: StackNavigationHelpers;
|
navigation: StackNavigationHelpers;
|
||||||
descriptors: StackDescriptorMap;
|
descriptors: StackDescriptorMap;
|
||||||
+ screenProps: unknown;
|
+ screenProps: unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
@@ -290,14 +292,37 @@
|
@@ -295,7 +296,9 @@
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return gestureEnabled !== false;
|
||||||
|
+ return gestureEnabled !== undefined
|
||||||
|
+ ? gestureEnabled
|
||||||
|
+ : Platform.OS !== 'android';
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
@@ -323,26 +326,49 @@
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,25 +615,39 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/StackView.
|
|||||||
return <HeaderContainer {...props} />;
|
return <HeaderContainer {...props} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
+ private handleTransitionComplete = ({ route }: { route: Route<string> }) => {
|
+ private handleTransitionComplete = () => {
|
||||||
+ const { state, navigation } = this.props;
|
+ const { state, navigation } = this.props;
|
||||||
+
|
+
|
||||||
+ if (state.isTransitioning) {
|
+ if (state.isTransitioning) {
|
||||||
+ navigation.dispatch(
|
+ navigation.dispatch(
|
||||||
+ StackActions.completeTransition({
|
+ StackActions.completeTransition({
|
||||||
+ key: navigation.state.key,
|
+ key: navigation.state.key,
|
||||||
+ toChildKey: route.key,
|
+ toChildKey: state.routes[state.index].key,
|
||||||
+ })
|
+ })
|
||||||
+ );
|
+ );
|
||||||
+ }
|
+ }
|
||||||
+ };
|
+ };
|
||||||
+
|
+
|
||||||
private handleOpenRoute = ({ route }: { route: Route<string> }) => {
|
private handleOpenRoute = ({ route }: { route: Route<string> }) => {
|
||||||
+ this.handleTransitionComplete({ route });
|
const { state, navigation } = this.props;
|
||||||
this.setState((state) => ({
|
const { closingRouteKeys, replacingRouteKeys } = this.state;
|
||||||
routes: state.replacingRouteKeys.length
|
|
||||||
? state.routes.filter((r) => !state.replacingRouteKeys.includes(r.key))
|
+ this.handleTransitionComplete();
|
||||||
@@ -319,12 +344,17 @@
|
+
|
||||||
|
if (
|
||||||
|
closingRouteKeys.some((key) => key === route.key) &&
|
||||||
|
replacingRouteKeys.every((key) => key !== route.key) &&
|
||||||
|
- state.routeNames.includes(route.name) &&
|
||||||
|
!state.routes.some((r) => r.key === route.key)
|
||||||
|
) {
|
||||||
|
// 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
|
||||||
|
- navigation.navigate(route);
|
||||||
|
+ navigation.dispatch(NavigationActions.navigate(route));
|
||||||
|
} else {
|
||||||
|
this.setState((state) => ({
|
||||||
|
routes: state.replacingRouteKeys.length
|
||||||
|
@@ -368,12 +394,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
|
||||||
@@ -628,18 +659,12 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/StackView.
|
|||||||
+ // @ts-ignore
|
+ // @ts-ignore
|
||||||
+ navigation.dispatch(StackActions.pop({ key: route.key, prune: false }));
|
+ navigation.dispatch(StackActions.pop({ key: route.key, prune: false }));
|
||||||
} else {
|
} else {
|
||||||
+ // While closing route we need to point to the previous one assuming that
|
+ this.handleTransitionComplete();
|
||||||
+ // this previous one in routes array
|
|
||||||
+ const index = this.state.routes.findIndex((r) => r.key === route.key);
|
|
||||||
+
|
|
||||||
+ this.handleTransitionComplete({
|
|
||||||
+ route: this.state.routes[Math.max(index - 1, 0)],
|
|
||||||
+ });
|
|
||||||
+
|
+
|
||||||
// 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),
|
||||||
@@ -341,22 +371,24 @@
|
@@ -390,47 +415,41 @@
|
||||||
private handleTransitionStart = (
|
private handleTransitionStart = (
|
||||||
{ route }: { route: Route<string> },
|
{ route }: { route: Route<string> },
|
||||||
closing: boolean
|
closing: boolean
|
||||||
@@ -666,21 +691,68 @@ diff -Naur ../../node_modules/@react-navigation/stack/src/views/Stack/StackView.
|
|||||||
- data: { closing },
|
- data: { closing },
|
||||||
- target: route.key,
|
- target: route.key,
|
||||||
- });
|
- });
|
||||||
|
-
|
||||||
|
- private handleGestureStart = ({ route }: { route: Route<string> }) => {
|
||||||
|
- this.props.navigation.emit({
|
||||||
|
- type: 'gestureStart',
|
||||||
|
- target: route.key,
|
||||||
|
- });
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- private handleGestureEnd = ({ route }: { route: Route<string> }) => {
|
||||||
|
- this.props.navigation.emit({
|
||||||
|
- type: 'gestureEnd',
|
||||||
|
- target: route.key,
|
||||||
|
- });
|
||||||
|
- };
|
||||||
|
-
|
||||||
|
- private handleGestureCancel = ({ route }: { route: Route<string> }) => {
|
||||||
|
- this.props.navigation.emit({
|
||||||
|
- type: 'gestureCancel',
|
||||||
|
- target: route.key,
|
||||||
|
- });
|
||||||
+ ) => {
|
+ ) => {
|
||||||
+ const { descriptors } = this.props;
|
+ const { descriptors } = this.props;
|
||||||
+ const descriptor =
|
+ const descriptor =
|
||||||
+ descriptors[route.key] || this.state.descriptors[route.key];
|
+ descriptors[route.key] || this.state.descriptors[route.key];
|
||||||
+
|
+
|
||||||
+ descriptor?.options.onTransitionEnd?.({ closing });
|
+ descriptor?.options.onTransitionStart?.({ closing });
|
||||||
+ };
|
+ };
|
||||||
|
+
|
||||||
|
+ private handleGestureStart = () => {
|
||||||
|
+ // Do nothing
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ private handleGestureEnd = () => {
|
||||||
|
+ // Do nothing
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ private handleGestureCancel = () => {
|
||||||
|
+ // Do nothing
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
@@ -395,6 +427,7 @@
|
state,
|
||||||
closingRouteKeys={closingRouteKeys}
|
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
onOpenRoute={this.handleOpenRoute}
|
navigation,
|
||||||
onCloseRoute={this.handleCloseRoute}
|
keyboardHandlingEnabled,
|
||||||
+ onTransitionComplete={this.handleTransitionComplete}
|
mode = 'card',
|
||||||
onTransitionStart={this.handleTransitionStart}
|
@@ -450,7 +469,7 @@
|
||||||
onTransitionEnd={this.handleTransitionEnd}
|
} = this.state;
|
||||||
renderHeader={this.renderHeader}
|
|
||||||
|
return (
|
||||||
|
- <NavigationHelpersContext.Provider value={navigation}>
|
||||||
|
+ <>
|
||||||
|
<GestureHandlerWrapper style={styles.container}>
|
||||||
|
<SafeAreaProviderCompat>
|
||||||
|
<SafeAreaConsumer>
|
||||||
|
@@ -491,7 +510,7 @@
|
||||||
|
</SafeAreaConsumer>
|
||||||
|
</SafeAreaProviderCompat>
|
||||||
|
</GestureHandlerWrapper>
|
||||||
|
- </NavigationHelpersContext.Provider>
|
||||||
|
+ </>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export { default as createStackNavigator } from './navigators/createStackNavigat
|
|||||||
/**
|
/**
|
||||||
* Types
|
* Types
|
||||||
*/
|
*/
|
||||||
export {
|
export type {
|
||||||
NavigationStackScreenComponent,
|
NavigationStackScreenComponent,
|
||||||
NavigationStackScreenProps,
|
NavigationStackScreenProps,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import createAppContainer, {
|
|||||||
_TESTING_ONLY_reset_container_count,
|
_TESTING_ONLY_reset_container_count,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
} from '../../../../native/src/createAppContainer';
|
} from '../../../../native/src/createAppContainer';
|
||||||
import { StackNavigationProp } from '../../vendor/types';
|
import type { StackNavigationProp } from '../../vendor/types';
|
||||||
|
|
||||||
const NavigationTestUtils = {
|
const NavigationTestUtils = {
|
||||||
resetInternalState: _TESTING_ONLY_reset_container_count,
|
resetInternalState: _TESTING_ONLY_reset_container_count,
|
||||||
|
|||||||
@@ -8,454 +8,11 @@ exports[`Nested navigators renders succesfully as direct child 1`] = `
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<View
|
|
||||||
onLayout={[Function]}
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"flex": 1,
|
|
||||||
"overflow": "hidden",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<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": 0.01,
|
|
||||||
"restSpeedThreshold": 0.01,
|
|
||||||
"stiffness": 1000,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"open": Object {
|
|
||||||
"animation": "spring",
|
|
||||||
"config": Object {
|
|
||||||
"damping": 500,
|
|
||||||
"mass": 3,
|
|
||||||
"overshootClamping": true,
|
|
||||||
"restDisplacementThreshold": 0.01,
|
|
||||||
"restSpeedThreshold": 0.01,
|
|
||||||
"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": "#fff",
|
|
||||||
"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
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"flex": 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
onLayout={[Function]}
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"flex": 1,
|
|
||||||
"overflow": "hidden",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<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": 0.01,
|
|
||||||
"restSpeedThreshold": 0.01,
|
|
||||||
"stiffness": 1000,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"open": Object {
|
|
||||||
"animation": "spring",
|
|
||||||
"config": Object {
|
|
||||||
"damping": 500,
|
|
||||||
"mass": 3,
|
|
||||||
"overshootClamping": true,
|
|
||||||
"restDisplacementThreshold": 0.01,
|
|
||||||
"restSpeedThreshold": 0.01,
|
|
||||||
"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": "#fff",
|
|
||||||
"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
|
|
||||||
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": 18,
|
|
||||||
"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>
|
|
||||||
</PanGestureHandler>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<View
|
<View
|
||||||
pointerEvents="box-none"
|
pointerEvents="box-none"
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"left": 0,
|
"zIndex": 1,
|
||||||
"position": "absolute",
|
|
||||||
"right": 0,
|
|
||||||
"top": 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -467,7 +24,7 @@ exports[`Nested navigators renders succesfully as direct child 1`] = `
|
|||||||
style={null}
|
style={null}
|
||||||
>
|
>
|
||||||
<View
|
<View
|
||||||
pointerEvents="none"
|
pointerEvents="box-none"
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"bottom": 0,
|
"bottom": 0,
|
||||||
@@ -476,6 +33,7 @@ exports[`Nested navigators renders succesfully as direct child 1`] = `
|
|||||||
"position": "absolute",
|
"position": "absolute",
|
||||||
"right": 0,
|
"right": 0,
|
||||||
"top": 0,
|
"top": 0,
|
||||||
|
"zIndex": 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -531,13 +89,14 @@ exports[`Nested navigators renders succesfully as direct child 1`] = `
|
|||||||
pointerEvents="box-none"
|
pointerEvents="box-none"
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"marginHorizontal": 18,
|
"marginHorizontal": 16,
|
||||||
"opacity": 1,
|
"opacity": 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
accessibilityRole="header"
|
accessibilityRole="header"
|
||||||
|
aria-level="1"
|
||||||
numberOfLines={1}
|
numberOfLines={1}
|
||||||
onLayout={[Function]}
|
onLayout={[Function]}
|
||||||
style={
|
style={
|
||||||
@@ -555,6 +114,471 @@ exports[`Nested navigators renders succesfully as direct child 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
|
||||||
|
collapsable={false}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"opacity": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<View
|
||||||
|
accessibilityElementsHidden={false}
|
||||||
|
closing={false}
|
||||||
|
gestureVelocityImpact={0.3}
|
||||||
|
importantForAccessibility="auto"
|
||||||
|
onClose={[Function]}
|
||||||
|
onGestureBegin={[Function]}
|
||||||
|
onGestureCanceled={[Function]}
|
||||||
|
onGestureEnd={[Function]}
|
||||||
|
onOpen={[Function]}
|
||||||
|
onTransition={[Function]}
|
||||||
|
pointerEvents="box-none"
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"overflow": undefined,
|
||||||
|
},
|
||||||
|
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
|
||||||
|
needsOffscreenAlphaCompositing={false}
|
||||||
|
pointerEvents="box-none"
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 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
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
pointerEvents="box-none"
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"zIndex": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<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"
|
||||||
|
aria-level="1"
|
||||||
|
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
|
||||||
|
onLayout={[Function]}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
pointerEvents="box-none"
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"bottom": 0,
|
||||||
|
"left": 0,
|
||||||
|
"position": "absolute",
|
||||||
|
"right": 0,
|
||||||
|
"top": 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
collapsable={false}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"opacity": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<View
|
||||||
|
accessibilityElementsHidden={false}
|
||||||
|
closing={false}
|
||||||
|
gestureVelocityImpact={0.3}
|
||||||
|
importantForAccessibility="auto"
|
||||||
|
onClose={[Function]}
|
||||||
|
onGestureBegin={[Function]}
|
||||||
|
onGestureCanceled={[Function]}
|
||||||
|
onGestureEnd={[Function]}
|
||||||
|
onOpen={[Function]}
|
||||||
|
onTransition={[Function]}
|
||||||
|
pointerEvents="box-none"
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"overflow": undefined,
|
||||||
|
},
|
||||||
|
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
|
||||||
|
needsOffscreenAlphaCompositing={false}
|
||||||
|
pointerEvents="box-none"
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 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>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</PanGestureHandler>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@@ -8,176 +8,11 @@ exports[`StackNavigator applies correct values when headerRight is present 1`] =
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<View
|
|
||||||
onLayout={[Function]}
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"flex": 1,
|
|
||||||
"overflow": "hidden",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<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": 0.01,
|
|
||||||
"restSpeedThreshold": 0.01,
|
|
||||||
"stiffness": 1000,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"open": Object {
|
|
||||||
"animation": "spring",
|
|
||||||
"config": Object {
|
|
||||||
"damping": 500,
|
|
||||||
"mass": 3,
|
|
||||||
"overshootClamping": true,
|
|
||||||
"restDisplacementThreshold": 0.01,
|
|
||||||
"restSpeedThreshold": 0.01,
|
|
||||||
"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": "#fff",
|
|
||||||
"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 {
|
Object {
|
||||||
"left": 0,
|
"zIndex": 1,
|
||||||
"position": "absolute",
|
|
||||||
"right": 0,
|
|
||||||
"top": 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -189,7 +24,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,
|
||||||
@@ -198,6 +33,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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -254,13 +90,14 @@ exports[`StackNavigator applies correct values when headerRight is present 1`] =
|
|||||||
pointerEvents="box-none"
|
pointerEvents="box-none"
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"marginHorizontal": 18,
|
"marginHorizontal": 16,
|
||||||
"opacity": 1,
|
"opacity": 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
accessibilityRole="header"
|
accessibilityRole="header"
|
||||||
|
aria-level="1"
|
||||||
numberOfLines={1}
|
numberOfLines={1}
|
||||||
onLayout={[Function]}
|
onLayout={[Function]}
|
||||||
style={
|
style={
|
||||||
@@ -294,23 +131,11 @@ 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={
|
||||||
Object {
|
Object {
|
||||||
"flex": 1,
|
"flex": 1,
|
||||||
"overflow": "hidden",
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -326,6 +151,14 @@ exports[`StackNavigator renders successfully 1`] = `
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
<View
|
||||||
|
collapsable={false}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"opacity": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
<View
|
<View
|
||||||
accessibilityElementsHidden={false}
|
accessibilityElementsHidden={false}
|
||||||
closing={false}
|
closing={false}
|
||||||
@@ -334,17 +167,23 @@ exports[`StackNavigator renders successfully 1`] = `
|
|||||||
onClose={[Function]}
|
onClose={[Function]}
|
||||||
onGestureBegin={[Function]}
|
onGestureBegin={[Function]}
|
||||||
onGestureCanceled={[Function]}
|
onGestureCanceled={[Function]}
|
||||||
|
onGestureEnd={[Function]}
|
||||||
onOpen={[Function]}
|
onOpen={[Function]}
|
||||||
onTransitionStart={[Function]}
|
onTransition={[Function]}
|
||||||
pointerEvents="box-none"
|
pointerEvents="box-none"
|
||||||
style={
|
style={
|
||||||
Object {
|
Array [
|
||||||
"bottom": 0,
|
Object {
|
||||||
"left": 0,
|
"overflow": undefined,
|
||||||
"position": "absolute",
|
},
|
||||||
"right": 0,
|
Object {
|
||||||
"top": 0,
|
"bottom": 0,
|
||||||
}
|
"left": 0,
|
||||||
|
"position": "absolute",
|
||||||
|
"right": 0,
|
||||||
|
"top": 0,
|
||||||
|
},
|
||||||
|
]
|
||||||
}
|
}
|
||||||
transitionSpec={
|
transitionSpec={
|
||||||
Object {
|
Object {
|
||||||
@@ -354,8 +193,8 @@ exports[`StackNavigator renders successfully 1`] = `
|
|||||||
"damping": 500,
|
"damping": 500,
|
||||||
"mass": 3,
|
"mass": 3,
|
||||||
"overshootClamping": true,
|
"overshootClamping": true,
|
||||||
"restDisplacementThreshold": 0.01,
|
"restDisplacementThreshold": 10,
|
||||||
"restSpeedThreshold": 0.01,
|
"restSpeedThreshold": 10,
|
||||||
"stiffness": 1000,
|
"stiffness": 1000,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -365,8 +204,8 @@ exports[`StackNavigator renders successfully 1`] = `
|
|||||||
"damping": 500,
|
"damping": 500,
|
||||||
"mass": 3,
|
"mass": 3,
|
||||||
"overshootClamping": true,
|
"overshootClamping": true,
|
||||||
"restDisplacementThreshold": 0.01,
|
"restDisplacementThreshold": 10,
|
||||||
"restSpeedThreshold": 0.01,
|
"restSpeedThreshold": 10,
|
||||||
"stiffness": 1000,
|
"stiffness": 1000,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -374,11 +213,11 @@ exports[`StackNavigator renders successfully 1`] = `
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<View
|
<View
|
||||||
|
needsOffscreenAlphaCompositing={false}
|
||||||
pointerEvents="box-none"
|
pointerEvents="box-none"
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"flex": 1,
|
"flex": 1,
|
||||||
"marginTop": 44,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -412,7 +251,7 @@ exports[`StackNavigator renders successfully 1`] = `
|
|||||||
pointerEvents="none"
|
pointerEvents="none"
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"backgroundColor": "#fff",
|
"backgroundColor": "rgb(242, 242, 242)",
|
||||||
"bottom": 0,
|
"bottom": 0,
|
||||||
"left": 0,
|
"left": 0,
|
||||||
"position": "absolute",
|
"position": "absolute",
|
||||||
@@ -467,14 +306,22 @@ 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 {
|
Object {
|
||||||
"left": 0,
|
"zIndex": 1,
|
||||||
"position": "absolute",
|
|
||||||
"right": 0,
|
|
||||||
"top": 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -486,7 +333,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,
|
||||||
@@ -495,6 +342,7 @@ exports[`StackNavigator renders successfully 1`] = `
|
|||||||
"position": "absolute",
|
"position": "absolute",
|
||||||
"right": 0,
|
"right": 0,
|
||||||
"top": 0,
|
"top": 0,
|
||||||
|
"zIndex": 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -551,13 +399,14 @@ exports[`StackNavigator renders successfully 1`] = `
|
|||||||
pointerEvents="box-none"
|
pointerEvents="box-none"
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"marginHorizontal": 18,
|
"marginHorizontal": 16,
|
||||||
"opacity": 1,
|
"opacity": 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
accessibilityRole="header"
|
accessibilityRole="header"
|
||||||
|
aria-level="1"
|
||||||
numberOfLines={1}
|
numberOfLines={1}
|
||||||
onLayout={[Function]}
|
onLayout={[Function]}
|
||||||
style={
|
style={
|
||||||
@@ -575,5 +424,180 @@ 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
|
||||||
|
collapsable={false}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"opacity": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<View
|
||||||
|
accessibilityElementsHidden={false}
|
||||||
|
closing={false}
|
||||||
|
gestureVelocityImpact={0.3}
|
||||||
|
importantForAccessibility="auto"
|
||||||
|
onClose={[Function]}
|
||||||
|
onGestureBegin={[Function]}
|
||||||
|
onGestureCanceled={[Function]}
|
||||||
|
onGestureEnd={[Function]}
|
||||||
|
onOpen={[Function]}
|
||||||
|
onTransition={[Function]}
|
||||||
|
pointerEvents="box-none"
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"overflow": undefined,
|
||||||
|
},
|
||||||
|
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
|
||||||
|
needsOffscreenAlphaCompositing={false}
|
||||||
|
pointerEvents="box-none"
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flex": 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>
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
CreateNavigatorConfig,
|
CreateNavigatorConfig,
|
||||||
} from 'react-navigation';
|
} from 'react-navigation';
|
||||||
import StackView from '../views/StackView';
|
import StackView from '../views/StackView';
|
||||||
import {
|
import type {
|
||||||
StackNavigationConfig,
|
StackNavigationConfig,
|
||||||
StackNavigationOptions,
|
StackNavigationOptions,
|
||||||
StackNavigationProp,
|
StackNavigationProp,
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
import {
|
import type {
|
||||||
NavigationRoute,
|
NavigationRoute,
|
||||||
NavigationParams,
|
NavigationParams,
|
||||||
NavigationScreenConfig,
|
NavigationScreenConfig,
|
||||||
SupportedThemes,
|
SupportedThemes,
|
||||||
} from 'react-navigation';
|
} from 'react-navigation';
|
||||||
import { StackNavigationProp, StackNavigationOptions } from './vendor/types';
|
import type {
|
||||||
|
StackNavigationProp,
|
||||||
|
StackNavigationOptions,
|
||||||
|
} from './vendor/types';
|
||||||
|
|
||||||
export type NavigationStackScreenProps<
|
export type NavigationStackScreenProps<
|
||||||
Params = NavigationParams,
|
Params = NavigationParams,
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import { StyleProp, ViewStyle } from 'react-native';
|
import type { StyleProp, ViewStyle } from 'react-native';
|
||||||
import { StackNavigationOptions, StackNavigationConfig } from '../vendor/types';
|
import type {
|
||||||
|
StackNavigationOptions,
|
||||||
|
StackNavigationConfig,
|
||||||
|
} from '../vendor/types';
|
||||||
|
|
||||||
type Validation = {
|
type Validation = {
|
||||||
message: string;
|
message: string;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { EdgeInsets } from 'react-native-safe-area-context';
|
import type { EdgeInsets } from 'react-native-safe-area-context';
|
||||||
import { StackNavigationOptions } from '../vendor/types';
|
import type { StackNavigationOptions } from '../vendor/types';
|
||||||
|
|
||||||
type Validation = {
|
type Validation = {
|
||||||
check: (o: Record<string, any>) => boolean;
|
check: (o: Record<string, any>) => boolean;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Animated } from 'react-native';
|
import { Animated } from 'react-native';
|
||||||
import { isIphoneX } from 'react-native-iphone-x-helper';
|
import { isIphoneX } from 'react-native-iphone-x-helper';
|
||||||
import conditional from '../utils/conditional';
|
import conditional from '../utils/conditional';
|
||||||
import {
|
import type {
|
||||||
StackCardInterpolationProps,
|
StackCardInterpolationProps,
|
||||||
StackCardInterpolatedStyle,
|
StackCardInterpolatedStyle,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
@@ -164,6 +164,7 @@ export function forModalPresentationIOS({
|
|||||||
borderTopLeftRadius: borderRadius,
|
borderTopLeftRadius: borderRadius,
|
||||||
borderTopRightRadius: borderRadius,
|
borderTopRightRadius: borderRadius,
|
||||||
marginTop: index === 0 ? 0 : statusBarHeight,
|
marginTop: index === 0 ? 0 : statusBarHeight,
|
||||||
|
marginBottom: index === 0 ? 0 : topOffset,
|
||||||
transform: [{ translateY }, { scale }],
|
transform: [{ translateY }, { scale }],
|
||||||
},
|
},
|
||||||
overlayStyle: { opacity: overlayOpacity },
|
overlayStyle: { opacity: overlayOpacity },
|
||||||
@@ -288,8 +289,8 @@ export function forScaleFromCenterAndroid({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const opacity = progress.interpolate({
|
const opacity = progress.interpolate({
|
||||||
inputRange: [0, 0.8, 1, 1.2, 2],
|
inputRange: [0, 0.75, 0.875, 1, 1.0825, 1.2075, 2],
|
||||||
outputRange: [0, 0.5, 1, 0.33, 0],
|
outputRange: [0, 0, 1, 1, 1, 1, 0],
|
||||||
});
|
});
|
||||||
|
|
||||||
const scale = conditional(
|
const scale = conditional(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Animated, I18nManager } from 'react-native';
|
import { Animated, I18nManager } from 'react-native';
|
||||||
import {
|
import type {
|
||||||
StackHeaderInterpolationProps,
|
StackHeaderInterpolationProps,
|
||||||
StackHeaderInterpolatedStyle,
|
StackHeaderInterpolatedStyle,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { Platform } from 'react-native';
|
||||||
import {
|
import {
|
||||||
forHorizontalIOS,
|
forHorizontalIOS,
|
||||||
forVerticalIOS,
|
forVerticalIOS,
|
||||||
@@ -14,10 +15,10 @@ import {
|
|||||||
FadeOutToBottomAndroidSpec,
|
FadeOutToBottomAndroidSpec,
|
||||||
FadeInFromBottomAndroidSpec,
|
FadeInFromBottomAndroidSpec,
|
||||||
} from './TransitionSpecs';
|
} from './TransitionSpecs';
|
||||||
import { TransitionPreset } from '../types';
|
import type { TransitionPreset } from '../types';
|
||||||
import { Platform } from 'react-native';
|
|
||||||
|
|
||||||
const ANDROID_VERSION_PIE = 28;
|
const ANDROID_VERSION_PIE = 28;
|
||||||
|
const ANDROID_VERSION_10 = 29;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard iOS navigation transition.
|
* Standard iOS navigation transition.
|
||||||
@@ -102,10 +103,13 @@ export const ScaleFromCenterAndroid: TransitionPreset = {
|
|||||||
*/
|
*/
|
||||||
export const DefaultTransition = Platform.select({
|
export const DefaultTransition = Platform.select({
|
||||||
ios: SlideFromRightIOS,
|
ios: SlideFromRightIOS,
|
||||||
default:
|
android:
|
||||||
Platform.OS === 'android' && Platform.Version >= ANDROID_VERSION_PIE
|
Platform.Version >= ANDROID_VERSION_10
|
||||||
|
? ScaleFromCenterAndroid
|
||||||
|
: Platform.Version >= ANDROID_VERSION_PIE
|
||||||
? RevealFromBottomAndroid
|
? RevealFromBottomAndroid
|
||||||
: FadeFromBottomAndroid,
|
: FadeFromBottomAndroid,
|
||||||
|
default: ScaleFromCenterAndroid,
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Easing } from 'react-native';
|
import { Easing } from 'react-native';
|
||||||
import { TransitionSpec } from '../types';
|
import type { TransitionSpec } from '../types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exact values from UINavigationController's animation configuration.
|
* Exact values from UINavigationController's animation configuration.
|
||||||
@@ -11,8 +11,8 @@ export const TransitionIOSSpec: TransitionSpec = {
|
|||||||
damping: 500,
|
damping: 500,
|
||||||
mass: 3,
|
mass: 3,
|
||||||
overshootClamping: true,
|
overshootClamping: true,
|
||||||
restDisplacementThreshold: 0.01,
|
restDisplacementThreshold: 10,
|
||||||
restSpeedThreshold: 0.01,
|
restSpeedThreshold: 10,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user