mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-01-19 18:38:16 +08:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed9ee4d5e5 | ||
|
|
36f9788e85 | ||
|
|
712ec9bab1 | ||
|
|
786456b645 | ||
|
|
3d7a62490c | ||
|
|
445e4d95b8 | ||
|
|
9c12052199 | ||
|
|
994c2c0828 | ||
|
|
c27a197ddb | ||
|
|
07afa55265 | ||
|
|
3ac5f412b7 | ||
|
|
70a2c3b97c | ||
|
|
4bd6f17b46 | ||
|
|
9824e90b9f | ||
|
|
eae992467b | ||
|
|
6b4d92ca4d | ||
|
|
41d3c97cea | ||
|
|
ab3e053338 | ||
|
|
b14262c2ef | ||
|
|
03d9133a7d |
68
CHANGELOG.md
68
CHANGELOG.md
@@ -7,11 +7,65 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [2.15.0] - [2018-09-14](https://github.com/react-navigation/react-navigation/releases/tag/2.15.0)
|
||||
|
||||
## [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-safe-area-view to 0.11.0 to support iPhoneXS Max and iPhoneXR
|
||||
- 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)
|
||||
|
||||
@@ -29,7 +83,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
|
||||
### Added
|
||||
|
||||
- Updated react-navigation-stack to add experimental support for react-navigation-screens. See https://github.com/kmagiera/react-native-screens for information about how to enable it.
|
||||
- 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
|
||||
|
||||
@@ -198,7 +252,13 @@ 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.15.0...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
|
||||
|
||||
@@ -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;
|
||||
@@ -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,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
11
flow/react-navigation.js
vendored
11
flow/react-navigation.js
vendored
@@ -407,9 +407,15 @@ declare module 'react-navigation' {
|
||||
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 = {|
|
||||
@@ -528,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,
|
||||
@@ -811,7 +818,7 @@ declare module 'react-navigation' {
|
||||
actions: Array<NavigationNavigateAction>,
|
||||
}) => NavigationResetAction,
|
||||
replace: (payload: {
|
||||
key: string,
|
||||
key?: string,
|
||||
routeName: string,
|
||||
params?: NavigationParams,
|
||||
action?: NavigationNavigateAction,
|
||||
|
||||
10
package.json
10
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-navigation",
|
||||
"version": "2.15.0",
|
||||
"version": "2.18.3",
|
||||
"description": "Routing and navigation for your React Native apps",
|
||||
"main": "src/react-navigation.js",
|
||||
"repository": {
|
||||
@@ -35,12 +35,14 @@
|
||||
"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.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.5.1",
|
||||
"react-navigation-tabs": "0.7.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