mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-01-20 19:08:15 +08:00
Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed9ee4d5e5 | ||
|
|
36f9788e85 | ||
|
|
712ec9bab1 | ||
|
|
786456b645 | ||
|
|
3d7a62490c | ||
|
|
445e4d95b8 | ||
|
|
9c12052199 | ||
|
|
994c2c0828 | ||
|
|
c27a197ddb | ||
|
|
07afa55265 | ||
|
|
3ac5f412b7 | ||
|
|
70a2c3b97c | ||
|
|
4bd6f17b46 | ||
|
|
9824e90b9f | ||
|
|
eae992467b | ||
|
|
6b4d92ca4d | ||
|
|
41d3c97cea | ||
|
|
ab3e053338 | ||
|
|
b14262c2ef | ||
|
|
03d9133a7d | ||
|
|
d0835351bd | ||
|
|
f892526e7b | ||
|
|
1afdb799fc | ||
|
|
83d36dcf7c | ||
|
|
aa94038190 | ||
|
|
0b698ae5d6 | ||
|
|
dd3ce66120 | ||
|
|
82754d41d9 | ||
|
|
9d54ec68dd | ||
|
|
460754fde1 | ||
|
|
ffd1865485 | ||
|
|
50320bf0d9 | ||
|
|
74a04c3ce5 | ||
|
|
54d0d5180d | ||
|
|
14eb5a1e75 | ||
|
|
222c77a360 | ||
|
|
39316fc339 |
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@@ -25,7 +25,7 @@ Bugs with react-navigation must be reproducible *without any external libraries
|
||||
|
||||
### How to reproduce
|
||||
|
||||
- You must provide a way to reproduce the problem. If you are having an issue with your machine or build tools, the issue belongs on another repoistory as that is outside of the scope of React Navigation.
|
||||
- You must provide a way to reproduce the problem. If you are having an issue with your machine or build tools, the issue belongs on another repository as that is outside of the scope of React Navigation.
|
||||
- Either re-create the bug on [Snack](https://snack.expo.io) or link to a GitHub repository with code that reproduces the bug.
|
||||
- Explain how to run the example app and any steps that we need to take to reproduce the issue from the example app.
|
||||
|
||||
|
||||
116
CHANGELOG.md
116
CHANGELOG.md
@@ -7,6 +7,106 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
|
||||
## [2.18.3] - [2018-11-26](https://github.com/react-navigation/react-navigation/releases/tag/2.18.3)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Support React.forwardRef on createStackNavigator
|
||||
|
||||
## [2.18.2] - [2018-10-26](https://github.com/react-navigation/react-navigation/releases/tag/2.18.2)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Revert "Backport fix for child navigation object caching" due to edge case with transitioner
|
||||
|
||||
## [2.18.1] - [2018-10-23](https://github.com/react-navigation/react-navigation/releases/tag/2.18.1)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Backport fix for child navigation object caching
|
||||
|
||||
## [2.18.0] - [2018-10-11](https://github.com/react-navigation/react-navigation/releases/tag/2.18.0)
|
||||
|
||||
### Added
|
||||
|
||||
- Introduce getActiveChildNavigationOptions (#5080)
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated react-navigation-tabs to 0.8.4 to fix issue with Snack
|
||||
- Flow changes:
|
||||
- Update StackViewConfig to match recent changes (#5067)
|
||||
- Mark key in StackActions.replace as optional (#5073)
|
||||
- Remove drawer actions from react-navigation-web
|
||||
- Add disableRouteNamePaths option to router configs (#4824)
|
||||
|
||||
## [2.17.0] - [2018-09-25](https://github.com/react-navigation/react-navigation/releases/tag/2.17.0)
|
||||
|
||||
### Changed
|
||||
|
||||
- Add `dangerouslyGetParent()` to flow typings
|
||||
- Update react-navigation-stack to 0.7.0
|
||||
- Add transparentCard option to fix cards with a transparent bg when using rn-screens
|
||||
- Add window dimensions for iPhone XS Max and iPhone XR
|
||||
- Vendor clamp
|
||||
- Add overflow hidden to stack container
|
||||
- Completion on mount: StackView is responsible for calling the navigation completion action when `state.isTransitioning` is set. This fix handles that case when the stack is first mounting.
|
||||
|
||||
## [2.16.0] - [2018-09-19](https://github.com/react-navigation/react-navigation/releases/tag/2.16.0)
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated react-navigation-stack to 0.6.0 to make react-native-screens a peerDependency.
|
||||
- Updated react-navigation-tabs to 0.8.2 to make react-native-screens a peerDependency and add support for it in bottom tab navigator.
|
||||
- Make react-native-screens a direct dependency of react-navigation.
|
||||
|
||||
## [2.15.0] - [2018-09-19](https://github.com/react-navigation/react-navigation/releases/tag/2.15.0)
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated react-navigation-safe-area-view to 0.11.0 to support iPhoneXS Max and iPhoneXR.
|
||||
|
||||
## [2.14.2] - [2018-09-14](https://github.com/react-navigation/react-navigation/releases/tag/2.14.2)
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated react-navigation-stack to 0.5.1 to clamp interpolated values in animations.
|
||||
|
||||
## [2.14.1] - [2018-09-14](https://github.com/react-navigation/react-navigation/releases/tag/2.14.1)
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated react-navigation-stack to 0.5.0 to solve black screen on back and unpressable header area with hidden header when using react-native-screens.
|
||||
|
||||
## [2.14.0] - [2018-09-12](https://github.com/react-navigation/react-navigation/releases/tag/2.14.0)
|
||||
|
||||
### Added
|
||||
|
||||
- Updated react-navigation-stack to add experimental support for react-native-screens. See https://github.com/kmagiera/react-native-screens for information about how to enable it.
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated react-native-safe-area-view to 0.10.0 to solve circular dependency issue (fixes https://github.com/react-navigation/react-navigation/issues/4973)
|
||||
|
||||
## [2.13.0] - [2018-09-06](https://github.com/react-navigation/react-navigation/releases/tag/2.13.0)
|
||||
|
||||
### Added
|
||||
|
||||
- When `tabBarIcon` is a function it is now provided with a `horizontal` option that indicates whether horizontal tabs are being rendered (label to the right of the icon) or not.
|
||||
- Add some missing flow types ([1](https://github.com/react-navigation/react-navigation/pull/4836), [2](https://github.com/react-navigation/react-navigation/pull/4917)).
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated react-navigation-stack to 0.3.0.
|
||||
- Updated react-navigation-tabs to 0.7.0.
|
||||
- Pinned `create-react-context` dependency to `0.2.2` (https://github.com/react-navigation/react-navigation/issues/4934)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixes tab label font sizes in landscape and portrait.
|
||||
- Default tab bar background color and header background color are white on iOS.
|
||||
|
||||
## [2.12.1] - [2018-08-23](https://github.com/react-navigation/react-navigation/releases/tag/2.12.1)
|
||||
|
||||
### Fixed
|
||||
@@ -19,7 +119,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
- Add accessibility props for inactive screens in stack (https://github.com/react-navigation/react-navigation-stack/commit/4e04428e26df9076413b57b3346a7ce357de1a77)
|
||||
- Updated header title to match iOS 11/12 style correctly (https://github.com/react-navigation/react-navigation-stack/pull/1)
|
||||
- Add support for animating the header background on screen transitions and add interpolator to animate it along with the rest of the screen, but this is still opt-in behavior (https://github.com/react-navigation/react-navigation-stack/pull/3)
|
||||
- Updated react-native-safe-area-view to 0.2.0
|
||||
- Updated react-native-safe-area-view to 0.9.0
|
||||
|
||||
## [2.11.2] - [2018-08-03](https://github.com/react-navigation/react-navigation/releases/tag/2.11.2)
|
||||
### Changed
|
||||
@@ -50,7 +150,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
- Export `StackViewTransitionConfigs` to allow you to extend default config in custom transition configs. [#4761](https://github.com/react-navigation/react-navigation/pull/4761)
|
||||
|
||||
### Fixed
|
||||
- Error when building with haul: ref to pathToRegexp.compile(#4658).
|
||||
- Error when building with haul: ref to pathToRegexp.compile. [#4658](https://github.com/react-navigation/react-navigation/pull/4658).
|
||||
|
||||
## [2.9.1] - [2018-07-24](https://github.com/react-navigation/react-navigation/releases/tag/2.9.1)
|
||||
@@ -153,7 +252,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
### Changed
|
||||
- Improved examples
|
||||
|
||||
[Unreleased]: https://github.com/react-navigation/react-navigation/compare/2.12.1...HEAD
|
||||
[Unreleased]: https://github.com/react-navigation/react-navigation/compare/2.18.3...HEAD
|
||||
[2.18.3]: https://github.com/react-navigation/react-navigation/compare/2.18.2...2.18.3
|
||||
[2.18.2]: https://github.com/react-navigation/react-navigation/compare/2.18.1...2.18.2
|
||||
[2.18.1]: https://github.com/react-navigation/react-navigation/compare/2.18.0...2.18.1
|
||||
[2.18.0]: https://github.com/react-navigation/react-navigation/compare/2.17.0...2.18.0
|
||||
[2.17.0]: https://github.com/react-navigation/react-navigation/compare/2.16.0...2.17.0
|
||||
[2.16.0]: https://github.com/react-navigation/react-navigation/compare/2.15.0...2.16.0
|
||||
[2.15.0]: https://github.com/react-navigation/react-navigation/compare/2.14.2...2.15.0
|
||||
[2.14.2]: https://github.com/react-navigation/react-navigation/compare/2.14.1...2.14.2
|
||||
[2.14.1]: https://github.com/react-navigation/react-navigation/compare/2.14.0...2.14.1
|
||||
[2.14.0]: https://github.com/react-navigation/react-navigation/compare/2.13.1...2.14.0
|
||||
[2.13.0]: https://github.com/react-navigation/react-navigation/compare/2.12.1...2.13.0
|
||||
[2.12.1]: https://github.com/react-navigation/react-navigation/compare/2.12.0...2.12.1
|
||||
[2.12.0]: https://github.com/react-navigation/react-navigation/compare/2.11.2...2.12.0
|
||||
[2.11.2]: https://github.com/react-navigation/react-navigation/compare/2.11.1...2.11.2
|
||||
|
||||
@@ -1,2 +1,7 @@
|
||||
import { useScreens } from 'react-native-screens';
|
||||
|
||||
// Uncomment this to use react-native-screens
|
||||
// useScreens();
|
||||
|
||||
import App from './js/App';
|
||||
export default App;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"splash": {
|
||||
"image": "./assets/icons/splash.png"
|
||||
},
|
||||
"sdkVersion": "28.0.0",
|
||||
"sdkVersion": "30.0.0",
|
||||
"assetBundlePatterns": [
|
||||
"**/*"
|
||||
],
|
||||
|
||||
@@ -34,6 +34,7 @@ import SimpleStack from './SimpleStack';
|
||||
import StackWithHeaderPreset from './StackWithHeaderPreset';
|
||||
import StackWithTranslucentHeader from './StackWithTranslucentHeader';
|
||||
import SimpleTabs from './SimpleTabs';
|
||||
import CustomTabUI from './CustomTabUI';
|
||||
import SwitchWithStacks from './SwitchWithStacks';
|
||||
import TabsWithNavigationFocus from './TabsWithNavigationFocus';
|
||||
import TabsWithNavigationEvents from './TabsWithNavigationEvents';
|
||||
@@ -137,6 +138,10 @@ const ExampleInfo = {
|
||||
description:
|
||||
'Demo automatic handling of keyboard showing/hiding inside StackNavigator',
|
||||
},
|
||||
CustomTabUI: {
|
||||
name: 'Custom Tabs UI',
|
||||
description: 'Render additional views around a Tab navigator',
|
||||
},
|
||||
};
|
||||
|
||||
const ExampleRoutes = {
|
||||
@@ -161,6 +166,7 @@ const ExampleRoutes = {
|
||||
ModalStack: ModalStack,
|
||||
StacksWithKeys: StacksWithKeys,
|
||||
StacksInTabs: StacksInTabs,
|
||||
CustomTabUI: CustomTabUI,
|
||||
StacksOverTabs: StacksOverTabs,
|
||||
StacksOverTopTabs: StacksOverTopTabs,
|
||||
LinkStack: {
|
||||
|
||||
133
examples/NavigationPlayground/js/CustomTabUI.js
Normal file
133
examples/NavigationPlayground/js/CustomTabUI.js
Normal file
@@ -0,0 +1,133 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
LayoutAnimation,
|
||||
View,
|
||||
StyleSheet,
|
||||
StatusBar,
|
||||
Text,
|
||||
} from 'react-native';
|
||||
import {
|
||||
SafeAreaView,
|
||||
createMaterialTopTabNavigator,
|
||||
createNavigationContainer,
|
||||
} from 'react-navigation';
|
||||
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||
import { Button } from './commonComponents/ButtonWithMargin';
|
||||
|
||||
class MyHomeScreen extends React.Component {
|
||||
static navigationOptions = {
|
||||
tabBarLabel: 'Home',
|
||||
tabBarIcon: ({ tintColor, focused, horizontal }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'ios-home' : 'ios-home-outline'}
|
||||
size={horizontal ? 20 : 26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
};
|
||||
render() {
|
||||
const { navigation } = this.props;
|
||||
return (
|
||||
<SafeAreaView forceInset={{ horizontal: 'always', top: 'always' }}>
|
||||
<Text>Home Screen</Text>
|
||||
<Button
|
||||
onPress={() => navigation.navigate('Home')}
|
||||
title="Go to home tab"
|
||||
/>
|
||||
<Button onPress={() => navigation.goBack(null)} title="Go back" />
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ReccomendedScreen extends React.Component {
|
||||
static navigationOptions = {
|
||||
tabBarLabel: 'Reccomended',
|
||||
tabBarIcon: ({ tintColor, focused, horizontal }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'ios-people' : 'ios-people-outline'}
|
||||
size={horizontal ? 20 : 26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
};
|
||||
render() {
|
||||
const { navigation } = this.props;
|
||||
return (
|
||||
<SafeAreaView forceInset={{ horizontal: 'always', top: 'always' }}>
|
||||
<Text>Reccomended Screen</Text>
|
||||
<Button
|
||||
onPress={() => navigation.navigate('Home')}
|
||||
title="Go to home tab"
|
||||
/>
|
||||
<Button onPress={() => navigation.goBack(null)} title="Go back" />
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class FeaturedScreen extends React.Component {
|
||||
static navigationOptions = ({ navigation }) => ({
|
||||
tabBarLabel: 'Featured',
|
||||
tabBarIcon: ({ tintColor, focused, horizontal }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'ios-star' : 'ios-star-outline'}
|
||||
size={horizontal ? 20 : 26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
});
|
||||
render() {
|
||||
const { navigation } = this.props;
|
||||
return (
|
||||
<SafeAreaView forceInset={{ horizontal: 'always', top: 'always' }}>
|
||||
<Text>Featured Screen</Text>
|
||||
<Button
|
||||
onPress={() => navigation.navigate('Home')}
|
||||
title="Go to home tab"
|
||||
/>
|
||||
<Button onPress={() => navigation.goBack(null)} title="Go back" />
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const SimpleTabs = createMaterialTopTabNavigator({
|
||||
Home: MyHomeScreen,
|
||||
Reccomended: ReccomendedScreen,
|
||||
Featured: FeaturedScreen,
|
||||
});
|
||||
|
||||
class TabNavigator extends React.Component {
|
||||
static router = SimpleTabs.router;
|
||||
componentWillUpdate() {
|
||||
LayoutAnimation.easeInEaseOut();
|
||||
}
|
||||
render() {
|
||||
const { navigation } = this.props;
|
||||
const { routes, index } = navigation.state;
|
||||
const activeRoute = routes[index];
|
||||
let bottom = null;
|
||||
if (activeRoute.routeName !== 'Home') {
|
||||
bottom = (
|
||||
<View style={{ height: 50, borderTopWidth: StyleSheet.hairlineWidth }}>
|
||||
<Button title="Check out" onPress={() => {}} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
<StatusBar barStyle="default" />
|
||||
<SafeAreaView
|
||||
style={{ flex: 1 }}
|
||||
forceInset={{ horizontal: 'always', top: 'always' }}
|
||||
>
|
||||
<SimpleTabs navigation={navigation} />
|
||||
</SafeAreaView>
|
||||
{bottom}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default TabNavigator;
|
||||
@@ -40,10 +40,10 @@ MyHomeScreen.navigationOptions = {
|
||||
accessibilityLabel: 'TEST_ID_HOME_ACLBL',
|
||||
},
|
||||
tabBarLabel: 'Home',
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
tabBarIcon: ({ tintColor, focused, horizontal }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'ios-home' : 'ios-home-outline'}
|
||||
size={26}
|
||||
size={horizontal ? 20 : 26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
@@ -60,10 +60,10 @@ class MyPeopleScreen extends React.Component<MyPeopleScreenProps> {
|
||||
|
||||
static navigationOptions = {
|
||||
tabBarLabel: 'People',
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
tabBarIcon: ({ tintColor, focused, horizontal }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'ios-people' : 'ios-people-outline'}
|
||||
size={26}
|
||||
size={horizontal ? 20 : 26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
@@ -100,10 +100,10 @@ class MyChatScreen extends React.Component<MyChatScreenProps> {
|
||||
|
||||
static navigationOptions = {
|
||||
tabBarLabel: 'Chat',
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
tabBarIcon: ({ tintColor, focused, horizontal }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'ios-chatboxes' : 'ios-chatboxes-outline'}
|
||||
size={26}
|
||||
size={horizontal ? 20 : 26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
@@ -135,10 +135,10 @@ const MySettingsScreen = ({ navigation }) => (
|
||||
|
||||
MySettingsScreen.navigationOptions = {
|
||||
tabBarLabel: 'Settings',
|
||||
tabBarIcon: ({ tintColor, focused }) => (
|
||||
tabBarIcon: ({ tintColor, focused, horizontal }) => (
|
||||
<Ionicons
|
||||
name={focused ? 'ios-settings' : 'ios-settings-outline'}
|
||||
size={26}
|
||||
size={horizontal ? 20 : 26}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
SafeAreaView,
|
||||
createStackNavigator,
|
||||
createBottomTabNavigator,
|
||||
getActiveChildNavigationOptions,
|
||||
} from 'react-navigation';
|
||||
|
||||
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||
@@ -94,16 +95,10 @@ const TabNav = createBottomTabNavigator(
|
||||
}
|
||||
);
|
||||
|
||||
TabNav.navigationOptions = ({ navigation }) => {
|
||||
let { routeName } = navigation.state.routes[navigation.state.index];
|
||||
let title;
|
||||
if (routeName === 'SettingsTab') {
|
||||
title = 'Settings';
|
||||
} else if (routeName === 'MainTab') {
|
||||
title = 'Home';
|
||||
}
|
||||
TabNav.navigationOptions = ({ navigation, screenProps }) => {
|
||||
const childOptions = getActiveChildNavigationOptions(navigation, screenProps);
|
||||
return {
|
||||
title,
|
||||
title: childOptions.title,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -7,10 +7,11 @@
|
||||
"start": "expo start",
|
||||
"android": "expo start --android",
|
||||
"ios": "expo start --ios",
|
||||
"test": "flow"
|
||||
"test": "flow",
|
||||
"postinstall": "rm -rf node_modules/react-native-screens"
|
||||
},
|
||||
"dependencies": {
|
||||
"expo": "^28.0.0",
|
||||
"expo": "^30.0.0",
|
||||
"invariant": "^2.2.4",
|
||||
"react": "16.3.1",
|
||||
"react-native": "^0.55.0",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
27
flow/react-navigation.js
vendored
27
flow/react-navigation.js
vendored
@@ -143,6 +143,14 @@ declare module 'react-navigation' {
|
||||
+type: 'Navigation/TOGGLE_DRAWER',
|
||||
+key?: string,
|
||||
|};
|
||||
declare export type NavigationDrawerOpenedAction = {|
|
||||
+type: 'Navigation/DRAWER_OPENED',
|
||||
+key?: string,
|
||||
|};
|
||||
declare export type NavigationDrawerClosedAction = {|
|
||||
+type: 'Navigation/DRAWER_CLOSED',
|
||||
+key?: string,
|
||||
|};
|
||||
|
||||
declare export type NavigationAction =
|
||||
| NavigationBackAction
|
||||
@@ -157,7 +165,9 @@ declare module 'react-navigation' {
|
||||
| NavigationCompleteTransitionAction
|
||||
| NavigationOpenDrawerAction
|
||||
| NavigationCloseDrawerAction
|
||||
| NavigationToggleDrawerAction;
|
||||
| NavigationToggleDrawerAction
|
||||
| NavigationDrawerOpenedAction
|
||||
| NavigationDrawerClosedAction;
|
||||
|
||||
/**
|
||||
* NavigationState is a tree of routes for a single navigator, where each
|
||||
@@ -394,10 +404,18 @@ declare module 'react-navigation' {
|
||||
mode?: 'card' | 'modal',
|
||||
headerMode?: HeaderMode,
|
||||
headerTransitionPreset?: 'fade-in-place' | 'uikit',
|
||||
headerLayoutPreset?: 'left' | 'center',
|
||||
headerBackTitleVisible?: boolean,
|
||||
cardStyle?: ViewStyleProp,
|
||||
transitionConfig?: () => TransitionConfig,
|
||||
transitionConfig?: (
|
||||
transitionProps: NavigationTransitionProps,
|
||||
prevTransitionProps: ?NavigationTransitionProps,
|
||||
isModal: boolean
|
||||
) => TransitionConfig,
|
||||
onTransitionStart?: () => void,
|
||||
onTransitionEnd?: () => void,
|
||||
transparentCard?: boolean,
|
||||
disableKeyboardHandling?: boolean,
|
||||
|};
|
||||
|
||||
declare export type StackNavigatorConfig = {|
|
||||
@@ -516,6 +534,7 @@ declare module 'react-navigation' {
|
||||
callback: NavigationEventCallback
|
||||
) => NavigationEventSubscription,
|
||||
getParam: (paramName: string, fallback?: any) => any,
|
||||
dangerouslyGetParent: () => NavigationScreenProp<*>,
|
||||
isFocused: () => boolean,
|
||||
// Shared action creators that exist for all routers
|
||||
goBack: (routeKey?: ?string) => boolean,
|
||||
@@ -799,7 +818,7 @@ declare module 'react-navigation' {
|
||||
actions: Array<NavigationNavigateAction>,
|
||||
}) => NavigationResetAction,
|
||||
replace: (payload: {
|
||||
key: string,
|
||||
key?: string,
|
||||
routeName: string,
|
||||
params?: NavigationParams,
|
||||
action?: NavigationNavigateAction,
|
||||
@@ -813,6 +832,8 @@ declare module 'react-navigation' {
|
||||
OPEN_DRAWER: 'Navigation/OPEN_DRAWER',
|
||||
CLOSE_DRAWER: 'Navigation/CLOSE_DRAWER',
|
||||
TOGGLE_DRAWER: 'Navigation/TOGGLE_DRAWER',
|
||||
DRAWER_OPENED: 'Navigation/DRAWER_OPENED',
|
||||
DRAWER_CLOSED: 'Navigation/DRAWER_CLOSED',
|
||||
|
||||
openDrawer: (payload: {
|
||||
key?: string,
|
||||
|
||||
14
package.json
14
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-navigation",
|
||||
"version": "2.12.1",
|
||||
"version": "2.18.3",
|
||||
"description": "Routing and navigation for your React Native apps",
|
||||
"main": "src/react-navigation.js",
|
||||
"repository": {
|
||||
@@ -31,16 +31,18 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"clamp": "^1.0.1",
|
||||
"create-react-context": "^0.2.1",
|
||||
"create-react-context": "0.2.2",
|
||||
"hoist-non-react-statics": "^2.2.0",
|
||||
"path-to-regexp": "^1.7.0",
|
||||
"query-string": "^6.1.0",
|
||||
"react-is": "^16.5.2",
|
||||
"react-lifecycles-compat": "^3",
|
||||
"react-native-safe-area-view": "^0.9.0",
|
||||
"react-native-safe-area-view": "0.11.0",
|
||||
"react-native-screens": "^1.0.0-alpha.11",
|
||||
"react-navigation-deprecated-tab-navigator": "1.3.0",
|
||||
"react-navigation-drawer": "0.5.0",
|
||||
"react-navigation-stack": "0.2.3",
|
||||
"react-navigation-tabs": "0.6.0"
|
||||
"react-navigation-stack": "0.7.0",
|
||||
"react-navigation-tabs": "0.8.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.24.1",
|
||||
@@ -61,7 +63,7 @@
|
||||
"lint-staged": "^4.2.1",
|
||||
"prettier": "^1.12.1",
|
||||
"prettier-eslint": "^8.8.1",
|
||||
"react": "16.2.0",
|
||||
"react": "16.5.2",
|
||||
"react-native": "^0.52.0",
|
||||
"react-native-vector-icons": "^4.2.0",
|
||||
"react-test-renderer": "^16.0.0"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
|
||||
import renderer from 'react-test-renderer';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import renderer from 'react-test-renderer';
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React, { Component } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import renderer from 'react-test-renderer';
|
||||
|
||||
const {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import React from 'react';
|
||||
import { polyfill } from 'react-lifecycles-compat';
|
||||
|
||||
import getChildEventSubscriber from '../getChildEventSubscriber';
|
||||
|
||||
function createNavigator(NavigatorView, router, navigationConfig) {
|
||||
class Navigator extends React.Component {
|
||||
static router = router;
|
||||
@@ -16,7 +14,7 @@ function createNavigator(NavigatorView, router, navigationConfig) {
|
||||
static getDerivedStateFromProps(nextProps, prevState) {
|
||||
const prevDescriptors = prevState.descriptors;
|
||||
const { navigation, screenProps } = nextProps;
|
||||
const { dispatch, state, addListener } = navigation;
|
||||
const { state } = navigation;
|
||||
const { routes } = state;
|
||||
if (typeof routes === 'undefined') {
|
||||
throw new TypeError(
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import createNavigator from '../navigators/createNavigator';
|
||||
import SwitchRouter from '../routers/SwitchRouter';
|
||||
import SwitchView from '../views/SwitchView/SwitchView';
|
||||
|
||||
5
src/react-navigation.js
vendored
5
src/react-navigation.js
vendored
@@ -106,6 +106,11 @@ module.exports = {
|
||||
get validateRouteConfigMap() {
|
||||
return require('./routers/validateRouteConfigMap').default;
|
||||
},
|
||||
|
||||
// Utils
|
||||
get getActiveChildNavigationOptions() {
|
||||
return require('./utils/getActiveChildNavigationOptions').default;
|
||||
},
|
||||
get pathUtils() {
|
||||
return require('./routers/pathUtils').default;
|
||||
},
|
||||
|
||||
@@ -27,9 +27,6 @@ module.exports = {
|
||||
get StackActions() {
|
||||
return require('./routers/StackActions').default;
|
||||
},
|
||||
get DrawerActions() {
|
||||
return require('./routers/DrawerActions').default;
|
||||
},
|
||||
|
||||
// Routers
|
||||
get StackRouter() {
|
||||
|
||||
@@ -107,7 +107,7 @@ export default (routeConfigs, stackConfig = {}) => {
|
||||
const {
|
||||
getPathAndParamsForRoute,
|
||||
getActionForPathAndParams,
|
||||
} = createPathParser(childRouters, routeConfigs, stackConfig.paths);
|
||||
} = createPathParser(childRouters, routeConfigs, stackConfig);
|
||||
|
||||
return {
|
||||
childRouters,
|
||||
@@ -543,8 +543,10 @@ export default (routeConfigs, stackConfig = {}) => {
|
||||
state,
|
||||
childRoute.key,
|
||||
route,
|
||||
// the following tells replaceAt to NOT change the index to this route for the setParam action, because people don't expect param-setting actions to switch the active route
|
||||
action.type === NavigationActions.SET_PARAMS
|
||||
// the following tells replaceAt to NOT change the index to this route for the setParam action or complete transition action,
|
||||
// because people don't expect these actions to switch the active route
|
||||
action.type === NavigationActions.SET_PARAMS ||
|
||||
action.type === StackActions.COMPLETE_TRANSITION
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ export default (routeConfigs, config = {}) => {
|
||||
const {
|
||||
getPathAndParamsForRoute,
|
||||
getActionForPathAndParams,
|
||||
} = createPathParser(childRouters, routeConfigs, config.paths);
|
||||
} = createPathParser(childRouters, routeConfigs, config);
|
||||
|
||||
if (initialRouteIndex === -1) {
|
||||
throw new Error(
|
||||
|
||||
@@ -4,9 +4,9 @@ import React from 'react';
|
||||
|
||||
import SwitchRouter from '../SwitchRouter';
|
||||
import StackRouter from '../StackRouter';
|
||||
import TabRouter from '../TabRouter';
|
||||
import StackActions from '../StackActions';
|
||||
import NavigationActions from '../../NavigationActions';
|
||||
import { urlToPathAndParams } from '../pathUtils';
|
||||
import { _TESTING_ONLY_normalize_keys } from '../KeyGenerator';
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -442,16 +442,6 @@ const performRouterTest = createTestRouter => {
|
||||
});
|
||||
|
||||
test('URI encoded path param gets parsed and correctly printed', () => {
|
||||
const router = createTestRouter({
|
||||
main: {
|
||||
screen: () => <div />,
|
||||
},
|
||||
person: {
|
||||
path: 'people/:name',
|
||||
screen: () => <div />,
|
||||
},
|
||||
});
|
||||
|
||||
const action = testRouter.getActionForPathAndParams('people/Henry%20L');
|
||||
expect(action).toEqual({
|
||||
routeName: 'person',
|
||||
@@ -594,3 +584,39 @@ test('Handles nested switch routers', () => {
|
||||
expect(action.action.type).toEqual(NavigationActions.NAVIGATE);
|
||||
expect(action.action.routeName).toEqual('B');
|
||||
});
|
||||
|
||||
const performRouteNameAsPathDisabledTest = createTestRouter => {
|
||||
const BScreen = () => <div />;
|
||||
const NestedNavigator = () => <div />;
|
||||
NestedNavigator.router = createTestRouter({
|
||||
B: {
|
||||
screen: BScreen,
|
||||
path: 'baz',
|
||||
},
|
||||
});
|
||||
const router = createTestRouter(
|
||||
{
|
||||
A: NestedNavigator,
|
||||
},
|
||||
{ disableRouteNamePaths: true }
|
||||
);
|
||||
|
||||
test('disableRouteNamePaths option on router prevent the default path to be the routeName', () => {
|
||||
const action = router.getActionForPathAndParams('baz', {});
|
||||
|
||||
expect(action.routeName).toBe('A');
|
||||
expect(action.action.routeName).toBe('B');
|
||||
});
|
||||
};
|
||||
|
||||
describe('Stack router handles disableRouteNamePaths', () => {
|
||||
performRouteNameAsPathDisabledTest(StackRouter);
|
||||
});
|
||||
|
||||
describe('Switch router handles disableRouteNamePaths', () => {
|
||||
performRouteNameAsPathDisabledTest(SwitchRouter);
|
||||
});
|
||||
|
||||
describe('Tab router handles disableRouteNamePaths', () => {
|
||||
performRouteNameAsPathDisabledTest(TabRouter);
|
||||
});
|
||||
|
||||
@@ -492,7 +492,7 @@ describe('StackRouter', () => {
|
||||
},
|
||||
state
|
||||
);
|
||||
const barKey = state2.routes[1].routes[0].key;
|
||||
|
||||
const state3 = router.getStateForAction(
|
||||
{
|
||||
type: StackActions.POP_TO_TOP,
|
||||
@@ -520,7 +520,7 @@ describe('StackRouter', () => {
|
||||
},
|
||||
state
|
||||
);
|
||||
const barKey = state2.routes[1].routes[0].key;
|
||||
|
||||
const state3 = router.getStateForAction(
|
||||
{
|
||||
type: StackActions.POP_TO_TOP,
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import React from 'react';
|
||||
import TabRouter from '../TabRouter';
|
||||
|
||||
import StackActions from '../../routers/StackActions';
|
||||
import NavigationActions from '../../NavigationActions';
|
||||
|
||||
const INIT_ACTION = { type: NavigationActions.INIT };
|
||||
|
||||
@@ -12,6 +12,10 @@ ProfileNavigator.router = StackRouter({
|
||||
},
|
||||
});
|
||||
|
||||
const ScreenWithForwardRef = React.forwardRef((props, ref) => (
|
||||
<div ref={ref} />
|
||||
));
|
||||
|
||||
describe('validateRouteConfigMap', () => {
|
||||
test('Fails on empty bare screen', () => {
|
||||
const invalidMap = {
|
||||
@@ -57,4 +61,10 @@ describe('validateRouteConfigMap', () => {
|
||||
};
|
||||
validateRouteConfigMap(validMap);
|
||||
});
|
||||
test('Succeeds on React.forwardRef', () => {
|
||||
const validMap = {
|
||||
Chat: ScreenWithForwardRef,
|
||||
};
|
||||
validateRouteConfigMap(validMap);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,7 +26,7 @@ export default (routeConfigs, navigatorScreenConfig) => (
|
||||
navigation,
|
||||
screenProps
|
||||
) => {
|
||||
const { state, dispatch } = navigation;
|
||||
const { state } = navigation;
|
||||
const route = state;
|
||||
|
||||
invariant(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { isValidElementType } from 'react-is';
|
||||
import invariant from '../utils/invariant';
|
||||
|
||||
/**
|
||||
@@ -23,7 +24,7 @@ export default function getScreenForRouteName(routeConfigs, routeName) {
|
||||
if (typeof routeConfig.getScreen === 'function') {
|
||||
const screen = routeConfig.getScreen();
|
||||
invariant(
|
||||
typeof screen === 'function',
|
||||
isValidElementType(screen),
|
||||
`The getScreen defined for route '${routeName} didn't return a valid ` +
|
||||
'screen or navigator.\n\n' +
|
||||
'Please pass it like this:\n' +
|
||||
|
||||
@@ -67,7 +67,7 @@ export const urlToPathAndParams = (url, uriPrefix) => {
|
||||
export const createPathParser = (
|
||||
childRouters,
|
||||
routeConfigs,
|
||||
pathConfigs = {}
|
||||
{ paths: pathConfigs = {}, disableRouteNamePaths }
|
||||
) => {
|
||||
const pathsByRouteNames = {};
|
||||
let paths = [];
|
||||
@@ -84,8 +84,8 @@ export const createPathParser = (
|
||||
}
|
||||
|
||||
if (pathPattern === undefined) {
|
||||
// If the user hasn't specified a path at all, then we assume the routeName is an appropriate path
|
||||
pathPattern = routeName;
|
||||
// If the user hasn't specified a path at all nor disableRouteNamePaths, then we assume the routeName is an appropriate path
|
||||
pathPattern = disableRouteNamePaths ? null : routeName;
|
||||
}
|
||||
|
||||
invariant(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { isValidElementType } from 'react-is';
|
||||
import invariant from '../utils/invariant';
|
||||
|
||||
/**
|
||||
@@ -17,9 +18,7 @@ function validateRouteConfigMap(routeConfigs) {
|
||||
|
||||
if (
|
||||
!screenComponent ||
|
||||
(typeof screenComponent !== 'function' &&
|
||||
typeof screenComponent !== 'string' &&
|
||||
!routeConfig.getScreen)
|
||||
(!isValidElementType(screenComponent) && !routeConfig.getScreen)
|
||||
) {
|
||||
throw new Error(`The component for route '${routeName}' must be a React component. For example:
|
||||
|
||||
|
||||
9
src/utils/getActiveChildNavigationOptions.js
Normal file
9
src/utils/getActiveChildNavigationOptions.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const getActiveChildNavigationOptions = (navigation, screenProps) => {
|
||||
const { state, router, getChildNavigation } = navigation;
|
||||
const activeRoute = state.routes[state.index];
|
||||
const activeNavigation = getChildNavigation(activeRoute.key);
|
||||
const options = router.getScreenOptions(activeNavigation, screenProps);
|
||||
return options;
|
||||
};
|
||||
|
||||
export default getActiveChildNavigationOptions;
|
||||
@@ -1,5 +1,3 @@
|
||||
import { Animated } from 'react-native';
|
||||
|
||||
export default class AnimatedValueSubscription {
|
||||
constructor(value, callback) {
|
||||
this._value = value;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React from 'react';
|
||||
import createReactContext from 'create-react-context';
|
||||
|
||||
const NavigationContext = createReactContext();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Platform, StyleSheet, View } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import { polyfill } from 'react-lifecycles-compat';
|
||||
|
||||
import SceneView from './SceneView';
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import renderer from 'react-test-renderer';
|
||||
import NavigationEvents from '../NavigationEvents';
|
||||
import { NavigationProvider } from '../NavigationContext';
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import propTypes from 'prop-types';
|
||||
import hoistStatics from 'hoist-non-react-statics';
|
||||
import invariant from '../utils/invariant';
|
||||
import { NavigationConsumer } from './NavigationContext';
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import propTypes from 'prop-types';
|
||||
import hoistStatics from 'hoist-non-react-statics';
|
||||
import invariant from '../utils/invariant';
|
||||
import withNavigation from './withNavigation';
|
||||
|
||||
Reference in New Issue
Block a user