mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-01-22 20:08:15 +08:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb78128439 | ||
|
|
c39ec7a10c | ||
|
|
0ff3347e97 | ||
|
|
b9d55a6330 | ||
|
|
315e43701b | ||
|
|
1d573bc246 | ||
|
|
3bfb0b90d0 | ||
|
|
8a129afe13 | ||
|
|
ab2a63fe92 | ||
|
|
c411210ecc | ||
|
|
01e7296520 | ||
|
|
8f3e0997c5 | ||
|
|
3f3ef6485c | ||
|
|
b12abb553f | ||
|
|
e02841a979 | ||
|
|
e147f34555 | ||
|
|
81e0ce136e | ||
|
|
8ba727c2cf | ||
|
|
9a86ef8362 | ||
|
|
4fe7c92847 | ||
|
|
afecaaed7f |
@@ -26,7 +26,7 @@
|
||||
"react": "16.2.0",
|
||||
"react-native": "^0.52.0",
|
||||
"react-navigation": "link:../..",
|
||||
"react-navigation-redux-helpers": "^1.0.0",
|
||||
"react-navigation-redux-helpers": "^1.0.3",
|
||||
"react-redux": "^5.0.6",
|
||||
"redux": "^3.7.2"
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { addNavigationHelpers, StackNavigator } from 'react-navigation';
|
||||
import { initializeListeners } from 'react-navigation-redux-helpers';
|
||||
|
||||
import LoginScreen from '../components/LoginScreen';
|
||||
import MainScreen from '../components/MainScreen';
|
||||
@@ -20,6 +21,10 @@ class AppWithNavigationState extends React.Component {
|
||||
nav: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
initializeListeners('root', this.props.nav);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { dispatch, nav } = this.props;
|
||||
return (
|
||||
|
||||
18
flow/react-navigation.js
vendored
18
flow/react-navigation.js
vendored
@@ -295,7 +295,6 @@ declare module 'react-navigation' {
|
||||
} & NavigationScreenRouteConfig);
|
||||
|
||||
declare export type NavigationScreenRouteConfig =
|
||||
| NavigationComponent
|
||||
| {
|
||||
screen: NavigationComponent,
|
||||
}
|
||||
@@ -361,6 +360,7 @@ declare module 'react-navigation' {
|
||||
initialRouteParams?: NavigationParams,
|
||||
paths?: NavigationPathsConfig,
|
||||
navigationOptions?: NavigationScreenConfig<*>,
|
||||
initialRouteKey?: string,
|
||||
|};
|
||||
|
||||
declare export type NavigationStackViewConfig = {|
|
||||
@@ -470,7 +470,7 @@ declare module 'react-navigation' {
|
||||
type: EventType,
|
||||
action: NavigationAction,
|
||||
state: NavigationState,
|
||||
lastState: NavigationState,
|
||||
lastState: ?NavigationState,
|
||||
};
|
||||
|
||||
declare export type NavigationEventCallback = (
|
||||
@@ -553,7 +553,7 @@ declare module 'react-navigation' {
|
||||
|
||||
declare export type NavigationContainerProps<S: {}, O: {}> = $Shape<{
|
||||
uriPrefix?: string | RegExp,
|
||||
onNavigationStateChange?: (
|
||||
onNavigationStateChange?: ?(
|
||||
NavigationState,
|
||||
NavigationState,
|
||||
NavigationAction
|
||||
@@ -724,7 +724,7 @@ declare module 'react-navigation' {
|
||||
SET_PARAMS: 'Navigation/SET_PARAMS',
|
||||
URI: 'Navigation/URI',
|
||||
back: {
|
||||
(payload: { key?: ?string }): NavigationBackAction,
|
||||
(payload?: { key?: ?string }): NavigationBackAction,
|
||||
toString: () => string,
|
||||
},
|
||||
init: {
|
||||
@@ -925,12 +925,14 @@ declare module 'react-navigation' {
|
||||
vertical?: _SafeAreaViewForceInsetValue,
|
||||
horizontal?: _SafeAreaViewForceInsetValue,
|
||||
},
|
||||
children: React$Node,
|
||||
children?: React$Node,
|
||||
style?: AnimatedViewStyleProp,
|
||||
};
|
||||
declare export var SafeAreaView: React$ComponentType<_SafeAreaViewProps>;
|
||||
|
||||
declare export var Header: React$ComponentType<HeaderProps>;
|
||||
declare export var Header: React$ComponentType<HeaderProps> & {
|
||||
HEIGHT: number,
|
||||
};
|
||||
|
||||
declare type _HeaderTitleProps = {
|
||||
children: React$Node,
|
||||
@@ -995,6 +997,8 @@ declare module 'react-navigation' {
|
||||
itemsContainerStyle?: ViewStyleProp,
|
||||
itemStyle?: ViewStyleProp,
|
||||
labelStyle?: TextStyleProp,
|
||||
activeLabelStyle?: TextStyleProp,
|
||||
inactiveLabelStyle?: TextStyleProp,
|
||||
iconContainerStyle?: ViewStyleProp,
|
||||
drawerPosition: 'left' | 'right',
|
||||
};
|
||||
@@ -1075,7 +1079,7 @@ declare module 'react-navigation' {
|
||||
declare export var TabBarBottom: React$ComponentType<_TabBarBottomProps>;
|
||||
|
||||
declare type _NavigationInjectedProps = {
|
||||
navigation: NavigationScreenProp<NavigationState>,
|
||||
navigation: NavigationScreenProp<NavigationStateRoute>,
|
||||
};
|
||||
declare export function withNavigation<T: {}>(
|
||||
Component: React$ComponentType<T & _NavigationInjectedProps>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-navigation",
|
||||
"version": "1.4.0",
|
||||
"version": "1.5.3",
|
||||
"description": "Routing and navigation for your React Native apps",
|
||||
"main": "src/react-navigation.js",
|
||||
"repository": {
|
||||
|
||||
@@ -11,6 +11,7 @@ import NavigationActions from '../NavigationActions';
|
||||
|
||||
export default (routeConfigMap, stackConfig = {}) => {
|
||||
const {
|
||||
initialRouteKey,
|
||||
initialRouteName,
|
||||
initialRouteParams,
|
||||
paths,
|
||||
@@ -25,6 +26,7 @@ export default (routeConfigMap, stackConfig = {}) => {
|
||||
} = stackConfig;
|
||||
|
||||
const stackRouterConfig = {
|
||||
initialRouteKey,
|
||||
initialRouteName,
|
||||
initialRouteParams,
|
||||
paths,
|
||||
@@ -47,7 +49,7 @@ export default (routeConfigMap, stackConfig = {}) => {
|
||||
onTransitionEnd={(lastTransition, transition) => {
|
||||
const { state, dispatch } = props.navigation;
|
||||
dispatch(NavigationActions.completeTransition({ key: state.key }));
|
||||
onTransitionEnd && onTransitionEnd();
|
||||
onTransitionEnd && onTransitionEnd(lastTransition, transition);
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -224,6 +224,7 @@ exports[`DrawerNavigator renders successfully 1`] = `
|
||||
"color": "#2196f3",
|
||||
},
|
||||
undefined,
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
|
||||
@@ -147,13 +147,12 @@ exports[`TabNavigator renders successfully 1`] = `
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"bottom": 0,
|
||||
"alignSelf": "center",
|
||||
"height": "100%",
|
||||
"justifyContent": "center",
|
||||
"left": 0,
|
||||
"opacity": 1,
|
||||
"position": "absolute",
|
||||
"right": 0,
|
||||
"top": 0,
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
/>
|
||||
@@ -162,13 +161,12 @@ exports[`TabNavigator renders successfully 1`] = `
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"bottom": 0,
|
||||
"alignSelf": "center",
|
||||
"height": "100%",
|
||||
"justifyContent": "center",
|
||||
"left": 0,
|
||||
"opacity": 0,
|
||||
"position": "absolute",
|
||||
"right": 0,
|
||||
"top": 0,
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -92,11 +92,12 @@ export default (routeConfigs, stackConfig = {}) => {
|
||||
...(action.params || {}),
|
||||
...(initialRouteParams || {}),
|
||||
};
|
||||
const { initialRouteKey } = stackConfig;
|
||||
route = {
|
||||
...route,
|
||||
...(params ? { params } : {}),
|
||||
routeName: initialRouteName,
|
||||
key: action.key || generateKey(),
|
||||
key: action.key || (initialRouteKey || generateKey()),
|
||||
};
|
||||
return {
|
||||
key: 'StackRouterRoot',
|
||||
|
||||
@@ -576,6 +576,23 @@ describe('StackRouter', () => {
|
||||
expect(state2.routes[1].routes[1].routes[1].routeName).toEqual('Corge');
|
||||
});
|
||||
|
||||
test('Navigate to initial screen is possible', () => {
|
||||
const TestRouter = StackRouter(
|
||||
{
|
||||
foo: { screen: () => <div /> },
|
||||
bar: { screen: () => <div /> },
|
||||
},
|
||||
{ initialRouteKey: 'foo' }
|
||||
);
|
||||
const initState = TestRouter.getStateForAction(NavigationActions.init());
|
||||
const pushedState = TestRouter.getStateForAction(
|
||||
NavigationActions.navigate({ routeName: 'foo', key: 'foo' }),
|
||||
initState
|
||||
);
|
||||
expect(pushedState.index).toEqual(0);
|
||||
expect(pushedState.routes[0].routeName).toEqual('foo');
|
||||
});
|
||||
|
||||
test('Navigate with key is idempotent', () => {
|
||||
const TestRouter = StackRouter({
|
||||
foo: { screen: () => <div /> },
|
||||
|
||||
@@ -110,7 +110,7 @@ class CardStack extends React.Component {
|
||||
}
|
||||
|
||||
_isRouteFocused = route => {
|
||||
const { state } = this.props.navigation;
|
||||
const { transitionProps: { navigation: { state } } } = this.props;
|
||||
const focusedRoute = state.routes[state.index];
|
||||
return route === focusedRoute;
|
||||
};
|
||||
@@ -129,7 +129,7 @@ class CardStack extends React.Component {
|
||||
const screenNavigation = addNavigationHelpers({
|
||||
dispatch: navigation.dispatch,
|
||||
state: scene.route,
|
||||
isFocused: this._isRouteFocused.bind(this, scene.route),
|
||||
isFocused: () => this._isRouteFocused(scene.route),
|
||||
addListener: this._childEventSubscribers[scene.route.key],
|
||||
});
|
||||
screenDetails = {
|
||||
|
||||
@@ -21,6 +21,8 @@ const DrawerNavigatorItems = ({
|
||||
itemsContainerStyle,
|
||||
itemStyle,
|
||||
labelStyle,
|
||||
activeLabelStyle,
|
||||
inactiveLabelStyle,
|
||||
iconContainerStyle,
|
||||
drawerPosition,
|
||||
}) => (
|
||||
@@ -34,6 +36,7 @@ const DrawerNavigatorItems = ({
|
||||
const scene = { route, index, focused, tintColor: color };
|
||||
const icon = renderIcon(scene);
|
||||
const label = getLabel(scene);
|
||||
const extraLabelStyle = focused ? activeLabelStyle : inactiveLabelStyle;
|
||||
return (
|
||||
<TouchableItem
|
||||
key={route.key}
|
||||
@@ -63,7 +66,9 @@ const DrawerNavigatorItems = ({
|
||||
</View>
|
||||
) : null}
|
||||
{typeof label === 'string' ? (
|
||||
<Text style={[styles.label, { color }, labelStyle]}>
|
||||
<Text
|
||||
style={[styles.label, { color }, labelStyle, extraLabelStyle]}
|
||||
>
|
||||
{label}
|
||||
</Text>
|
||||
) : (
|
||||
|
||||
@@ -108,7 +108,7 @@ export default class DrawerView extends React.PureComponent {
|
||||
this._screenNavigationProp = addNavigationHelpers({
|
||||
dispatch: navigation.dispatch,
|
||||
state: navigationState,
|
||||
isFocused: this._isRouteFocused.bind(this, navigationState),
|
||||
isFocused: () => this._isRouteFocused(navigationState),
|
||||
addListener: this._childEventSubscribers[navigationState.key],
|
||||
});
|
||||
};
|
||||
|
||||
@@ -100,6 +100,7 @@ class TabBarBottom extends React.PureComponent {
|
||||
if (showIcon === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<TabBarIcon
|
||||
position={position}
|
||||
@@ -108,7 +109,11 @@ class TabBarBottom extends React.PureComponent {
|
||||
inactiveTintColor={inactiveTintColor}
|
||||
renderIcon={renderIcon}
|
||||
scene={scene}
|
||||
style={showLabel && this._shouldUseHorizontalTabs() ? {} : styles.icon}
|
||||
style={
|
||||
showLabel && this._shouldUseHorizontalTabs()
|
||||
? styles.horizontalIcon
|
||||
: styles.icon
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -286,6 +291,9 @@ class TabBarBottom extends React.PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
const DEFAULT_HEIGHT = 49;
|
||||
const COMPACT_HEIGHT = 29;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
tabBar: {
|
||||
backgroundColor: '#F7F7F7', // Default background color in iOS 10
|
||||
@@ -294,10 +302,10 @@ const styles = StyleSheet.create({
|
||||
flexDirection: 'row',
|
||||
},
|
||||
tabBarCompact: {
|
||||
height: 29,
|
||||
height: COMPACT_HEIGHT,
|
||||
},
|
||||
tabBarRegular: {
|
||||
height: 49,
|
||||
height: DEFAULT_HEIGHT,
|
||||
},
|
||||
tab: {
|
||||
flex: 1,
|
||||
@@ -314,6 +322,9 @@ const styles = StyleSheet.create({
|
||||
icon: {
|
||||
flexGrow: 1,
|
||||
},
|
||||
horizontalIcon: {
|
||||
height: Platform.isPad ? DEFAULT_HEIGHT : COMPACT_HEIGHT,
|
||||
},
|
||||
label: {
|
||||
textAlign: 'center',
|
||||
backgroundColor: 'transparent',
|
||||
|
||||
@@ -23,6 +23,7 @@ export default class TabBarIcon extends React.PureComponent {
|
||||
inputRange,
|
||||
outputRange: inputRange.map(i => (i === index ? 0 : 1)),
|
||||
});
|
||||
|
||||
// We render the icon twice at the same position on top of each other:
|
||||
// active and inactive one, so we can fade between them.
|
||||
return (
|
||||
@@ -53,12 +54,11 @@ const styles = StyleSheet.create({
|
||||
// We render the icon twice at the same position on top of each other:
|
||||
// active and inactive one, so we can fade between them:
|
||||
// Cover the whole iconContainer:
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
alignItems: 'center',
|
||||
alignSelf: 'center',
|
||||
height: '100%',
|
||||
justifyContent: 'center',
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -93,13 +93,12 @@ exports[`TabBarBottom renders successfully 1`] = `
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"bottom": 0,
|
||||
"alignSelf": "center",
|
||||
"height": "100%",
|
||||
"justifyContent": "center",
|
||||
"left": 0,
|
||||
"opacity": 1,
|
||||
"position": "absolute",
|
||||
"right": 0,
|
||||
"top": 0,
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
/>
|
||||
@@ -108,13 +107,12 @@ exports[`TabBarBottom renders successfully 1`] = `
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"bottom": 0,
|
||||
"alignSelf": "center",
|
||||
"height": "100%",
|
||||
"justifyContent": "center",
|
||||
"left": 0,
|
||||
"opacity": 0,
|
||||
"position": "absolute",
|
||||
"right": 0,
|
||||
"top": 0,
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -31,7 +31,7 @@ export default function withCachedChildNavigation(Comp) {
|
||||
});
|
||||
}
|
||||
|
||||
_isRouteFocused = route => () => {
|
||||
_isRouteFocused = route => {
|
||||
const { state } = this.props.navigation;
|
||||
const focusedRoute = state.routes[state.index];
|
||||
return route === focusedRoute;
|
||||
@@ -58,7 +58,7 @@ export default function withCachedChildNavigation(Comp) {
|
||||
this._childNavigationProps[route.key] = addNavigationHelpers({
|
||||
dispatch: navigation.dispatch,
|
||||
state: route,
|
||||
isFocused: this._isRouteFocused.bind(this, route),
|
||||
isFocused: () => this._isRouteFocused(route),
|
||||
addListener: this._childEventSubscribers[route.key],
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user