mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-03-06 22:39:41 +08:00
Fix flow (#305)
* Fix Flow and Android build * Enable flow on CI * Fix and suppress flow errors
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"presets": ["react-native"],
|
||||
"env": {
|
||||
// For RN example development
|
||||
"development": {
|
||||
|
||||
@@ -52,4 +52,4 @@ suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
unsafe.enable_getters_and_setters=true
|
||||
|
||||
[version]
|
||||
^0.35.0
|
||||
^0.37.0
|
||||
|
||||
@@ -17,3 +17,6 @@ deployment:
|
||||
commands:
|
||||
- yarn run build-docs
|
||||
- ./scripts/deploy-website.sh
|
||||
test:
|
||||
pre:
|
||||
- yarn run flow
|
||||
|
||||
@@ -22,7 +22,7 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean getUseDeveloperSupport() {
|
||||
public boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
|
||||
|
||||
20
packages/react-navigation/jest-setup.js
vendored
20
packages/react-navigation/jest-setup.js
vendored
@@ -1,15 +1,13 @@
|
||||
/* @flow */
|
||||
/* eslint-env jest */
|
||||
|
||||
// See https://github.com/facebook/jest/issues/2208
|
||||
jest.mock('Linking', () => {
|
||||
return {
|
||||
addEventListener: jest.fn(),
|
||||
removeEventListener: jest.fn(),
|
||||
openURL: jest.fn(),
|
||||
canOpenURL: jest.fn(),
|
||||
getInitialURL: jest.fn().mockImplementation((value: string) => Promise.resolve(value)),
|
||||
}
|
||||
});
|
||||
jest.mock('Linking', () => ({
|
||||
addEventListener: jest.fn(),
|
||||
removeEventListener: jest.fn(),
|
||||
openURL: jest.fn(),
|
||||
canOpenURL: jest.fn(),
|
||||
getInitialURL: jest.fn().mockImplementation((value: string) => Promise.resolve(value)),
|
||||
}));
|
||||
|
||||
// See https://github.com/facebook/react-native/issues/11659
|
||||
jest.mock('ScrollView', () => {
|
||||
@@ -17,5 +15,5 @@ jest.mock('ScrollView', () => {
|
||||
class ScrollView extends RealComponent {
|
||||
scrollTo = () => {}
|
||||
}
|
||||
return ScrollView
|
||||
return ScrollView;
|
||||
});
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"babel-eslint": "^7.0.0",
|
||||
"babel-jest": "^17.0.2",
|
||||
"babel-preset-es2015": "^6.18.0",
|
||||
"babel-preset-react": "^6.16.0",
|
||||
"babel-preset-react": "^6.22.0",
|
||||
"babel-preset-react-native": "^1.9.0",
|
||||
"babel-preset-react-native-syntax": "^1.0.0",
|
||||
"babel-preset-stage-1": "^6.16.0",
|
||||
@@ -52,10 +52,10 @@
|
||||
"eslint-plugin-import": "^1.16.0",
|
||||
"eslint-plugin-jsx-a11y": "^2.2.2",
|
||||
"eslint-plugin-react": "^6.3.0",
|
||||
"flow-bin": "^0.35.0",
|
||||
"flow-bin": "^0.37.4",
|
||||
"jest": "^18.1.0",
|
||||
"react": "~15.4.0",
|
||||
"react-native": "^0.40.0",
|
||||
"react": "~15.4.2",
|
||||
"react-native": "^0.41.2",
|
||||
"react-native-vector-icons": "^3.0.0",
|
||||
"react-test-renderer": "^15.4.2"
|
||||
},
|
||||
|
||||
55
packages/react-navigation/src/TypeDefinition.js
vendored
55
packages/react-navigation/src/TypeDefinition.js
vendored
@@ -29,10 +29,10 @@ export type NavigationState = {
|
||||
* Index refers to the active child route in the routes array.
|
||||
*/
|
||||
index: number,
|
||||
routes: Array<NavigationRoute>,
|
||||
routes: Array<NavigationRoute | (NavigationRoute & NavigationState)>,
|
||||
};
|
||||
|
||||
export interface NavigationRoute {
|
||||
export type NavigationRoute = {
|
||||
/**
|
||||
* React's key used by some navigators. No need to specify these manually,
|
||||
* they will be defined by the router.
|
||||
@@ -52,7 +52,8 @@ export interface NavigationRoute {
|
||||
* e.g. `{ car_id: 123 }` in a route that displays a car.
|
||||
*/
|
||||
params?: NavigationParams,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export type NavigationRouter = {
|
||||
/**
|
||||
@@ -92,12 +93,11 @@ export type NavigationRouter = {
|
||||
};
|
||||
|
||||
export type NavigationScreenOption<T> =
|
||||
| T
|
||||
| (navigation: NavigationScreenProp<NavigationRoute, NavigationAction>,
|
||||
config: NavigationScreenOptionConfig,
|
||||
router?: NavigationRouter) => T
|
||||
| T;
|
||||
config: T) => T;
|
||||
|
||||
export type Style = Object | number | false | void;
|
||||
export type Style = { [key: string]: any } | number | false | null | void | Array<Style>;
|
||||
|
||||
export type HeaderConfig = {
|
||||
/**
|
||||
@@ -260,7 +260,7 @@ export type NavigationContainerConfig = {
|
||||
export type NavigationStackViewConfig = {
|
||||
mode?: 'card' | 'modal',
|
||||
headerMode?: HeaderMode,
|
||||
headerComponent?: ReactClass<HeaderProps>,
|
||||
headerComponent?: ReactClass<HeaderProps<*>>,
|
||||
cardStyle?: Style,
|
||||
onTransitionStart?: () => void,
|
||||
onTransitionEnd?: () => void
|
||||
@@ -290,23 +290,18 @@ export type NavigationAction =
|
||||
| NavigationStackAction
|
||||
| NavigationTabAction;
|
||||
|
||||
export type NavigationScreenRouteConfig = {
|
||||
/** React component or navigator to render for this route */
|
||||
screen: NavigationScreenComponent<*> | NavigationNavigator<*>,
|
||||
export type NavigationRouteConfig<T> = T & {
|
||||
navigationOptions?: NavigationScreenOptions,
|
||||
path?: string,
|
||||
};
|
||||
|
||||
export type NavigationLazyScreenRouteConfig = {
|
||||
/** React component or navigator to lazily require and render for this route */
|
||||
getScreen: () => (NavigationScreenComponent<*> | NavigationNavigator<*>),
|
||||
navigationOptions?: NavigationScreenOptions,
|
||||
path?: string,
|
||||
};
|
||||
|
||||
export type NavigationRouteConfig =
|
||||
| NavigationScreenRouteConfig
|
||||
| NavigationLazyScreenRouteConfig;
|
||||
export type NavigationScreenRouteConfig = NavigationScreenRouteConfig<{
|
||||
// React component or navigator for this route */
|
||||
screen: NavigationComponent,
|
||||
} | {
|
||||
// React component to lazily require and render for this route */
|
||||
getScreen: () => NavigationComponent,
|
||||
}>;
|
||||
|
||||
export type NavigationPathsConfig = {
|
||||
[routeName: string]: string,
|
||||
@@ -323,7 +318,7 @@ export type NavigationTabRouterConfig = {
|
||||
};
|
||||
|
||||
export type NavigationRouteConfigMap = {
|
||||
[routeName: string]: NavigationRouteConfig,
|
||||
[routeName: string]: NavigationRouteConfig<*>,
|
||||
};
|
||||
|
||||
export type NavigationDispatch<A> = (action: A) => boolean;
|
||||
@@ -333,16 +328,14 @@ export type NavigationProp<S, A> = {
|
||||
dispatch: NavigationDispatch<A>,
|
||||
};
|
||||
|
||||
export type NavigationScreenProp<S, A> = {
|
||||
state: S,
|
||||
dispatch: NavigationDispatch<A>,
|
||||
goBack: (routeKey?: string) => boolean,
|
||||
export type NavigationScreenProp<S, A> = NavigationProp<S, A> & {
|
||||
goBack: (routeKey?: ?string) => boolean,
|
||||
navigate: (routeName: string, params?: NavigationParams, action?: NavigationAction) => boolean,
|
||||
setParams: (newParams: NavigationParams) => boolean,
|
||||
};
|
||||
|
||||
export type NavigationNavigatorProps = {
|
||||
navigation: NavigationProp<NavigationState, NavigationAction>,
|
||||
navigation: NavigationProp<NavigationRoute, NavigationAction>,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -396,7 +389,7 @@ export type NavigationTransitionProps = {
|
||||
// is the index of the scene
|
||||
scene: NavigationScene,
|
||||
index: number,
|
||||
navigation: NavigationScreenProp<NavigationRoute, NavigationAction>,
|
||||
navigation: NavigationScreenProp<*, NavigationAction>,
|
||||
|
||||
// The gesture distance for `horizontal` and `vertical` transitions
|
||||
gestureResponseDistance?: ?number,
|
||||
@@ -442,8 +435,4 @@ export type NavigationSceneRenderer = (
|
||||
|
||||
export type NavigationStyleInterpolator = (
|
||||
props: NavigationSceneRendererProps,
|
||||
) => Object;
|
||||
|
||||
export type ContextWithNavigation = {
|
||||
navigation: NavigationScreenProp<NavigationState, NavigationAction>;
|
||||
};
|
||||
) => Style;
|
||||
|
||||
6
packages/react-navigation/src/__tests__/.eslintrc
Normal file
6
packages/react-navigation/src/__tests__/.eslintrc
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "../../.eslintrc",
|
||||
"env": {
|
||||
"jest": true
|
||||
},
|
||||
}
|
||||
@@ -17,7 +17,7 @@ describe('addNavigationHelpers', () => {
|
||||
it('handles Back action when the key is not defined', () => {
|
||||
const mockedDispatch = jest.fn(() => false).mockImplementationOnce(() => true);
|
||||
expect(addNavigationHelpers({
|
||||
state: {},
|
||||
state: { routeName: 'Home' },
|
||||
dispatch: mockedDispatch,
|
||||
}).goBack()).toEqual(true);
|
||||
expect(mockedDispatch).toBeCalledWith({ type: NavigationActions.BACK });
|
||||
@@ -27,7 +27,7 @@ describe('addNavigationHelpers', () => {
|
||||
it('handles Navigate action', () => {
|
||||
const mockedDispatch = jest.fn(() => false).mockImplementationOnce(() => true);
|
||||
expect(addNavigationHelpers({
|
||||
state: {},
|
||||
state: { routeName: 'Home' },
|
||||
dispatch: mockedDispatch,
|
||||
}).navigate('Profile', { name: 'Matt' })).toEqual(true);
|
||||
expect(mockedDispatch).toBeCalledWith({
|
||||
@@ -43,11 +43,11 @@ describe('addNavigationHelpers', () => {
|
||||
expect(addNavigationHelpers({
|
||||
state: { key: 'B', routeName: 'Settings' },
|
||||
dispatch: mockedDispatch,
|
||||
}).setParams({ notificationsEnabled: true })).toEqual(true);
|
||||
}).setParams({ notificationsEnabled: 'yes' })).toEqual(true);
|
||||
expect(mockedDispatch).toBeCalledWith({
|
||||
type: NavigationActions.SET_PARAMS,
|
||||
key: 'B',
|
||||
params: { notificationsEnabled: true },
|
||||
params: { notificationsEnabled: 'yes' },
|
||||
});
|
||||
expect(mockedDispatch.mock.calls.length).toBe(1);
|
||||
});
|
||||
|
||||
@@ -6,36 +6,36 @@
|
||||
|
||||
import type {
|
||||
NavigationAction,
|
||||
NavigationScreenProp,
|
||||
NavigationProp,
|
||||
NavigationRoute,
|
||||
NavigationParams,
|
||||
} from './TypeDefinition';
|
||||
|
||||
import NavigationActions from './NavigationActions'
|
||||
import NavigationActions from './NavigationActions';
|
||||
|
||||
export default (navigation: NavigationProp<NavigationRoute, NavigationAction>): NavigationScreenProp<NavigationRoute, NavigationAction> => ({
|
||||
...navigation,
|
||||
goBack: (key): boolean => {
|
||||
return navigation.dispatch(NavigationActions.back({
|
||||
export default function<S: *> (navigation: NavigationProp<S, NavigationAction>) {
|
||||
return {
|
||||
...navigation,
|
||||
goBack: (key?: ?string): boolean => navigation.dispatch(NavigationActions.back({
|
||||
key: key === undefined ? navigation.state.key : key,
|
||||
}));
|
||||
},
|
||||
navigate: (routeName, params, action): boolean => {
|
||||
return navigation.dispatch(NavigationActions.navigate({
|
||||
routeName,
|
||||
params,
|
||||
action,
|
||||
}));
|
||||
},
|
||||
/**
|
||||
* For updating current route params. For example the nav bar title and
|
||||
* buttons are based on the route params.
|
||||
* This means `setParams` can be used to update nav bar for example.
|
||||
*/
|
||||
setParams: (params): boolean => {
|
||||
return navigation.dispatch(NavigationActions.setParams({
|
||||
params,
|
||||
key: navigation.state.key
|
||||
}));
|
||||
}
|
||||
});
|
||||
})),
|
||||
navigate: (
|
||||
routeName: string,
|
||||
params?: NavigationParams,
|
||||
action?: NavigationAction): boolean =>
|
||||
navigation.dispatch(NavigationActions.navigate({
|
||||
routeName,
|
||||
params,
|
||||
action,
|
||||
})),
|
||||
/**
|
||||
* For updating current route params. For example the nav bar title and
|
||||
* buttons are based on the route params.
|
||||
* This means `setParams` can be used to update nav bar for example.
|
||||
*/
|
||||
setParams: (params: NavigationParams): boolean =>
|
||||
navigation.dispatch(NavigationActions.setParams({
|
||||
params,
|
||||
key: navigation.state.key,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,10 +10,12 @@ import NavigationActions from './NavigationActions';
|
||||
import addNavigationHelpers from './addNavigationHelpers';
|
||||
|
||||
import type {
|
||||
NavigationRoute,
|
||||
NavigationAction,
|
||||
NavigationContainerOptions,
|
||||
NavigationProp,
|
||||
NavigationState,
|
||||
NavigationScreenProp,
|
||||
} from './TypeDefinition';
|
||||
|
||||
/**
|
||||
@@ -22,16 +24,16 @@ import type {
|
||||
* This allows to use e.g. the StackNavigator and TabNavigator as root-level
|
||||
* components.
|
||||
*/
|
||||
const createNavigationContainer = (
|
||||
export default function createNavigationContainer<T: *>(
|
||||
Component: ReactClass<*>,
|
||||
containerConfig?: NavigationContainerOptions
|
||||
) => {
|
||||
) {
|
||||
type Props = {
|
||||
navigation: NavigationProp<NavigationState, NavigationAction>,
|
||||
navigation: NavigationProp<T, NavigationAction>,
|
||||
};
|
||||
|
||||
type State = {
|
||||
nav: NavigationState,
|
||||
nav: ?NavigationState,
|
||||
};
|
||||
|
||||
function urlToPathAndParams(url: string) {
|
||||
@@ -49,7 +51,7 @@ const createNavigationContainer = (
|
||||
}
|
||||
|
||||
class NavigationContainer extends React.Component {
|
||||
state: ?State;
|
||||
state: State;
|
||||
props: Props;
|
||||
|
||||
subs: ?{
|
||||
@@ -75,12 +77,11 @@ const createNavigationContainer = (
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.state = null;
|
||||
if (this._isStateful()) {
|
||||
this.state = {
|
||||
nav: Component.router.getStateForAction(NavigationActions.init()),
|
||||
};
|
||||
}
|
||||
this.state = {
|
||||
nav: this._isStateful()
|
||||
? Component.router.getStateForAction(NavigationActions.init())
|
||||
: null,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@@ -110,7 +111,7 @@ const createNavigationContainer = (
|
||||
this.subs && this.subs.remove();
|
||||
}
|
||||
|
||||
_handleOpenURL = ({ url }) => {
|
||||
_handleOpenURL = ({ url }: { url: string }) => {
|
||||
console.log('Handling URL:', url);
|
||||
const parsedUrl = urlToPathAndParams(url);
|
||||
if (parsedUrl) {
|
||||
@@ -145,6 +146,8 @@ const createNavigationContainer = (
|
||||
return false;
|
||||
};
|
||||
|
||||
_navigation: ?NavigationScreenProp<NavigationRoute, NavigationAction>;
|
||||
|
||||
render() {
|
||||
let navigation = this.props.navigation;
|
||||
if (this._isStateful()) {
|
||||
@@ -166,6 +169,5 @@ const createNavigationContainer = (
|
||||
}
|
||||
|
||||
return NavigationContainer;
|
||||
};
|
||||
}
|
||||
|
||||
export default createNavigationContainer;
|
||||
|
||||
@@ -4,6 +4,7 @@ import React from 'react';
|
||||
|
||||
import type {
|
||||
NavigationRouter,
|
||||
NavigationRoute,
|
||||
NavigationNavigator,
|
||||
NavigationNavigatorProps,
|
||||
} from '../TypeDefinition';
|
||||
|
||||
@@ -9,6 +9,7 @@ import StateUtils from '../StateUtils';
|
||||
import validateRouteConfigMap from './validateRouteConfigMap';
|
||||
|
||||
import type {
|
||||
NavigationRoute,
|
||||
NavigationAction,
|
||||
NavigationComponent,
|
||||
NavigationNavigateAction,
|
||||
@@ -69,10 +70,8 @@ export default (
|
||||
const wildcardRe = pathToRegexp(`${pathPattern}/*`, keys);
|
||||
re = new RegExp(`(?:${re.source})|(?:${wildcardRe.source})`);
|
||||
}
|
||||
paths[routeName] = {
|
||||
re,
|
||||
keys,
|
||||
};
|
||||
/* $FlowFixMe */
|
||||
paths[routeName] = { re, keys };
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -91,7 +90,7 @@ export default (
|
||||
},
|
||||
|
||||
getStateForAction(action: NavigationStackAction, state: ?NavigationState) {
|
||||
action = NavigationActions.mapDeprecatedActionAndWarn(action)
|
||||
action = NavigationActions.mapDeprecatedActionAndWarn(action);
|
||||
|
||||
// Set up the initial state if needed
|
||||
if (!state) {
|
||||
@@ -157,7 +156,8 @@ export default (
|
||||
}
|
||||
|
||||
if (action.type === NavigationActions.SET_PARAMS) {
|
||||
const lastRoute = state.routes.find(route => route.key === action.key);
|
||||
/* $FlowFixMe */
|
||||
const lastRoute = state.routes.find((route: *) => route.key === action.key);
|
||||
if (lastRoute) {
|
||||
const params = {
|
||||
...lastRoute.params,
|
||||
@@ -180,7 +180,7 @@ export default (
|
||||
|
||||
return {
|
||||
...state,
|
||||
routes: resetAction.actions.map((action: NavigationNavigateAction, index) => {
|
||||
routes: resetAction.actions.map((action: NavigationNavigateAction, index: number) => {
|
||||
const router = childRouters[action.routeName];
|
||||
if (router) {
|
||||
return {
|
||||
@@ -204,7 +204,9 @@ export default (
|
||||
if (action.type === NavigationActions.BACK) {
|
||||
let backRouteIndex = null;
|
||||
if (action.key) {
|
||||
const backRoute = state.routes.find(route => route.key === action.key);
|
||||
/* $FlowFixMe */
|
||||
const backRoute = state.routes.find((route: *) => route.key === action.key);
|
||||
/* $FlowFixMe */
|
||||
backRouteIndex = state.routes.indexOf(backRoute);
|
||||
}
|
||||
if (backRouteIndex == null) {
|
||||
@@ -242,7 +244,9 @@ export default (
|
||||
let matchedRouteName;
|
||||
let pathMatch;
|
||||
let pathMatchKeys;
|
||||
|
||||
for (const routeName in paths) {
|
||||
/* $FlowFixMe */
|
||||
const { re, keys } = paths[routeName];
|
||||
pathMatch = re.exec(pathToResolve);
|
||||
if (pathMatch && pathMatch.length) {
|
||||
@@ -264,21 +268,23 @@ export default (
|
||||
let nestedAction;
|
||||
if (childRouters[matchedRouteName]) {
|
||||
nestedAction = childRouters[matchedRouteName].getActionForPathAndParams(
|
||||
/* $FlowFixMe */
|
||||
pathMatch.slice(pathMatchKeys.length).join('/')
|
||||
);
|
||||
}
|
||||
|
||||
// reduce the matched pieces of the path into the params
|
||||
// of the route. `params` is null if there are no params.
|
||||
const params = pathMatch.slice(1).reduce((result, matchResult, i) => {
|
||||
/* $FlowFixMe */
|
||||
const params = pathMatch.slice(1).reduce((result: *, matchResult: *, i: number) => {
|
||||
const key = pathMatchKeys[i];
|
||||
if (key.asterisk || !key) {
|
||||
return result;
|
||||
}
|
||||
result = result || {};
|
||||
const nextResult = result || {};
|
||||
const paramName = key.name;
|
||||
result[paramName] = matchResult;
|
||||
return result;
|
||||
nextResult[paramName] = matchResult;
|
||||
return nextResult;
|
||||
}, null);
|
||||
|
||||
return NavigationActions.navigate({
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
/* @flow */
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
import getScreenForRouteName from './getScreenForRouteName';
|
||||
import createConfigGetter from './createConfigGetter';
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
import warning from 'fbjs/lib/warning';
|
||||
|
||||
import NavigationActions from '../NavigationActions';
|
||||
import StateUtils from '../StateUtils';
|
||||
|
||||
import validateRouteConfigMap from './validateRouteConfigMap';
|
||||
|
||||
import type {
|
||||
NavigationAction,
|
||||
NavigationComponent,
|
||||
NavigationScreenComponent,
|
||||
NavigationState,
|
||||
NavigationRouteConfigMap,
|
||||
NavigationParams,
|
||||
@@ -51,8 +47,12 @@ export default (
|
||||
`Should be one of ${order.map((n: *) => `"${n}"`).join(', ')}`
|
||||
);
|
||||
return {
|
||||
getStateForAction(action: NavigationAction, inputState: ?NavigationState): ?NavigationState {
|
||||
action = NavigationActions.mapDeprecatedActionAndWarn(action)
|
||||
getStateForAction(
|
||||
action: NavigationAction | { action: NavigationAction },
|
||||
inputState?: ?NavigationState
|
||||
): ?NavigationState {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
action = NavigationActions.mapDeprecatedActionAndWarn(action);
|
||||
|
||||
// Establish a default state
|
||||
let state = inputState;
|
||||
@@ -82,7 +82,10 @@ export default (
|
||||
const activeTabLastState = state.routes[state.index];
|
||||
const activeTabRouter = tabRouters[order[state.index]];
|
||||
if (activeTabRouter) {
|
||||
const activeTabState = activeTabRouter.getStateForAction(action.action || action, activeTabLastState);
|
||||
const activeTabState = activeTabRouter.getStateForAction(
|
||||
action.action || action,
|
||||
activeTabLastState
|
||||
);
|
||||
if (!activeTabState && inputState) {
|
||||
return null;
|
||||
}
|
||||
@@ -100,12 +103,15 @@ export default (
|
||||
// handle the action, to allow inner tabs to change first
|
||||
let activeTabIndex = state.index;
|
||||
const isBackEligible = action.key == null || action.key === activeTabLastState.key;
|
||||
if (action.type === NavigationActions.BACK && isBackEligible && shouldBackNavigateToInitialRoute) {
|
||||
if (
|
||||
action.type === NavigationActions.BACK &&
|
||||
isBackEligible && shouldBackNavigateToInitialRoute
|
||||
) {
|
||||
activeTabIndex = initialRouteIndex;
|
||||
}
|
||||
let didNavigate = false;
|
||||
if (action.type === NavigationActions.NAVIGATE) {
|
||||
const navigateAction = ((action: any): NavigationNavigateAction);
|
||||
const navigateAction = ((action: *): NavigationNavigateAction);
|
||||
didNavigate = !!order.find((tabId: string, i: number) => {
|
||||
if (tabId === navigateAction.routeName) {
|
||||
activeTabIndex = i;
|
||||
@@ -115,7 +121,9 @@ export default (
|
||||
});
|
||||
if (didNavigate && action.action) {
|
||||
const tabRouter = tabRouters[action.routeName];
|
||||
const newChildState = tabRouter && tabRouter.getStateForAction(action.action, state.routes[activeTabIndex]);
|
||||
const newChildState = tabRouter
|
||||
? tabRouter.getStateForAction(action.action, state.routes[activeTabIndex])
|
||||
: null;
|
||||
if (newChildState && newChildState !== state.routes[activeTabIndex]) {
|
||||
const routes = [...state.routes];
|
||||
routes[activeTabIndex] = newChildState;
|
||||
@@ -126,10 +134,12 @@ export default (
|
||||
};
|
||||
}
|
||||
}
|
||||
// console.log({navId: order.join('-'), action, order, lastIndex: state.index, index: activeTabIndex});
|
||||
}
|
||||
if (action.type === NavigationActions.SET_PARAMS) {
|
||||
const lastRoute = state.routes.find(route => route.key === action.key);
|
||||
const lastRoute = state.routes.find(
|
||||
/* $FlowFixMe */
|
||||
(route: *) => route.key === action.key
|
||||
);
|
||||
if (lastRoute) {
|
||||
const params = {
|
||||
...lastRoute.params,
|
||||
@@ -147,7 +157,6 @@ export default (
|
||||
}
|
||||
}
|
||||
if (activeTabIndex !== state.index) {
|
||||
// console.log(`${order.join('-')}: Normal navigation`, {lastIndex: state.index, newIndex: activeTabIndex});
|
||||
return {
|
||||
...state,
|
||||
index: activeTabIndex,
|
||||
@@ -160,7 +169,8 @@ export default (
|
||||
|
||||
// Let other tabs handle it and switch to the first tab that returns a new state
|
||||
let index = state.index;
|
||||
let routes = state.routes;
|
||||
/* $FlowFixMe */
|
||||
let routes: Array<NavigationState> = state.routes;
|
||||
order.find((tabId: string, i: number) => {
|
||||
const tabRouter = tabRouters[tabId];
|
||||
if (i === index) {
|
||||
@@ -195,7 +205,7 @@ export default (
|
||||
return state;
|
||||
},
|
||||
|
||||
getComponentForState(state: NavigationState) {
|
||||
getComponentForState(state: NavigationState): NavigationScreenComponent<*> {
|
||||
const routeName = order[state.index];
|
||||
invariant(
|
||||
routeName,
|
||||
@@ -239,7 +249,7 @@ export default (
|
||||
* This will return null if there is no action matched
|
||||
*/
|
||||
getActionForPathAndParams(path: string, params: ?NavigationParams) {
|
||||
return order.map((tabId: string, index: number) => {
|
||||
return order.map((tabId: string) => {
|
||||
const parts = path.split('/');
|
||||
const pathToTest = paths[tabId];
|
||||
if (parts[0] === pathToTest) {
|
||||
@@ -254,10 +264,11 @@ export default (
|
||||
}
|
||||
return action;
|
||||
}
|
||||
}).find(action => !!action) || order.map((tabId: string, index: number) => {
|
||||
return null;
|
||||
}).find((action: *) => !!action) || order.map((tabId: string) => {
|
||||
const tabRouter = tabRouters[tabId];
|
||||
return tabRouter && tabRouter.getActionForPathAndParams(path, params);
|
||||
}).find(action => !!action) || null;
|
||||
}).find((action: *) => !!action) || null;
|
||||
},
|
||||
|
||||
getScreenConfig: createConfigGetter(routeConfigs, config.navigationOptions),
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "../../../.eslintrc",
|
||||
"env": {
|
||||
"jest": true
|
||||
},
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
/* @flow */
|
||||
|
||||
import React from 'react';
|
||||
|
||||
@@ -15,11 +13,10 @@ const ROUTERS = {
|
||||
StackRouter,
|
||||
};
|
||||
|
||||
Object.keys(ROUTERS).forEach((routerName) => {
|
||||
Object.keys(ROUTERS).forEach((routerName: string) => {
|
||||
const Router = ROUTERS[routerName];
|
||||
|
||||
describe(`General router features - ${routerName}`, () => {
|
||||
|
||||
test('title is configurable using navigationOptions and getScreenConfig', () => {
|
||||
class FooView extends React.Component {
|
||||
render() { return <div />; }
|
||||
@@ -38,13 +35,13 @@ Object.keys(ROUTERS).forEach((routerName) => {
|
||||
Baz: { screen: BazView },
|
||||
});
|
||||
const routes = [
|
||||
{key: 'A', routeName: 'Foo'},
|
||||
{key: 'B', routeName: 'Bar'},
|
||||
{key: 'A', routeName: 'Baz', params: { id: '123' }},
|
||||
{ key: 'A', routeName: 'Foo' },
|
||||
{ key: 'B', routeName: 'Bar' },
|
||||
{ key: 'A', routeName: 'Baz', params: { id: '123' } },
|
||||
];
|
||||
expect(router.getScreenConfig(addNavigationHelpers({ state: routes[0], dispatch: () => false, }), 'title')).toEqual(null);
|
||||
expect(router.getScreenConfig(addNavigationHelpers({ state: routes[1], dispatch: () => false, }), 'title')).toEqual('BarTitle');
|
||||
expect(router.getScreenConfig(addNavigationHelpers({ state: routes[2], dispatch: () => false, }), 'title')).toEqual('Baz-123');
|
||||
expect(router.getScreenConfig(addNavigationHelpers({ state: routes[0], dispatch: () => false }), 'title')).toEqual(null);
|
||||
expect(router.getScreenConfig(addNavigationHelpers({ state: routes[1], dispatch: () => false }), 'title')).toEqual('BarTitle');
|
||||
expect(router.getScreenConfig(addNavigationHelpers({ state: routes[2], dispatch: () => false }), 'title')).toEqual('Baz-123');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -93,9 +90,10 @@ test('Handles deep action', () => {
|
||||
],
|
||||
};
|
||||
expect(state1).toEqual(expectedState);
|
||||
const state2 = TestRouter.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Foo', action: {type: NavigationActions.NAVIGATE, routeName: 'Zoo'} }, state1);
|
||||
expect(state2.index).toEqual(1);
|
||||
expect(state2.routes[1].index).toEqual(1);
|
||||
const state2 = TestRouter.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Foo', action: { type: NavigationActions.NAVIGATE, routeName: 'Zoo' } }, state1);
|
||||
expect(state2 && state2.index).toEqual(1);
|
||||
/* $FlowFixMe */
|
||||
expect(state2 && state2.routes[1].index).toEqual(1);
|
||||
});
|
||||
|
||||
test('Supports lazily-evaluated getScreen', () => {
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
/* @flow */
|
||||
|
||||
import React from 'react';
|
||||
|
||||
@@ -359,7 +357,7 @@ describe('StackRouter', () => {
|
||||
const state3 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Bar', params: { name: 'Foo' } }, state2);
|
||||
const state4 = router.getStateForAction({ type: NavigationActions.BACK, key: 'wrongKey' }, state3);
|
||||
expect(state3).toEqual(state4);
|
||||
const state5 = router.getStateForAction({ type: NavigationActions.BACK, key: state3.routes[1].key }, state4);
|
||||
const state5 = router.getStateForAction({ type: NavigationActions.BACK, key: state3 && state3.routes[1].key }, state4);
|
||||
expect(state5).toEqual(state);
|
||||
});
|
||||
|
||||
@@ -466,6 +464,7 @@ describe('StackRouter', () => {
|
||||
|
||||
expect(state2 && state2.index).toEqual(0);
|
||||
expect(state2 && state2.routes[0].routeName).toEqual('Foo');
|
||||
/* $FlowFixMe */
|
||||
expect(state2 && state2.routes[0].routes[0].routeName).toEqual('baz');
|
||||
});
|
||||
|
||||
@@ -497,7 +496,9 @@ describe('StackRouter', () => {
|
||||
screen: () => <div />,
|
||||
},
|
||||
});
|
||||
/* $FlowFixMe: these are for deprecated action names */
|
||||
const state = router.getStateForAction({ type: 'Init' });
|
||||
/* $FlowFixMe: these are for deprecated action names */
|
||||
const state2 = router.getStateForAction({ type: 'Reset', actions: [{ type: 'Navigate', routeName: 'Foo', params: { bar: '42' } }, { type: 'Navigate', routeName: 'Bar' }], index: 1 }, state);
|
||||
expect(state2 && state2.index).toEqual(1);
|
||||
expect(state2 && state2.routes[0].params).toEqual({ bar: '42' });
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
/*
|
||||
* @flow
|
||||
*/
|
||||
/* @flow */
|
||||
|
||||
import React from 'react';
|
||||
import TabRouter from '../TabRouter';
|
||||
@@ -377,7 +375,9 @@ describe('TabRouter', () => {
|
||||
|
||||
test('Maps old actions (uses "getStateForAction returns null when navigating to same tab" test)', () => {
|
||||
const router = TabRouter({ Foo: BareLeafRouteConfig, Bar: BareLeafRouteConfig }, { initialRouteName: 'Bar' });
|
||||
/* $FlowFixMe: these are for deprecated action names */
|
||||
const state = router.getStateForAction({ type: 'Init' });
|
||||
/* $FlowFixMe: these are for deprecated action names */
|
||||
const state2 = router.getStateForAction({ type: 'Navigate', routeName: 'Bar' }, state);
|
||||
expect(state2).toEqual(null);
|
||||
});
|
||||
|
||||
@@ -62,20 +62,23 @@ test('should get config for screen', () => {
|
||||
|
||||
const routes = [
|
||||
{ key: 'A', routeName: 'Home' },
|
||||
{ key: 'B', routeName: 'Home', params: { user: 'jane', } },
|
||||
{ key: 'B', routeName: 'Home', params: { user: 'jane' } },
|
||||
{ key: 'C', routeName: 'Settings' },
|
||||
{ key: 'D', routeName: 'Notifications' },
|
||||
{ key: 'E', routeName: 'Notifications', params: { fullscreen: true, } },
|
||||
{ key: 'E', routeName: 'Notifications', params: { fullscreen: true } },
|
||||
];
|
||||
|
||||
expect(getScreenConfig(addNavigationHelpers({ state: routes[0], dispatch: () => false }), 'title')).toEqual('Welcome anonymous');
|
||||
expect(getScreenConfig(addNavigationHelpers({ state: routes[1], dispatch: () => false }), 'title')).toEqual('Welcome jane');
|
||||
/* $FlowFixMe: we want tests to fail on undefined */
|
||||
expect(getScreenConfig(addNavigationHelpers({ state: routes[0], dispatch: () => false }), 'header').visible).toEqual(true);
|
||||
expect(getScreenConfig(addNavigationHelpers({ state: routes[2], dispatch: () => false }), 'title')).toEqual('Settings!!!');
|
||||
expect(getScreenConfig(addNavigationHelpers({ state: routes[2], dispatch: () => false }), 'permalink')).toEqual('');
|
||||
/* $FlowFixMe: we want tests to fail on undefined */
|
||||
expect(getScreenConfig(addNavigationHelpers({ state: routes[2], dispatch: () => false }), 'header').visible).toEqual(false);
|
||||
expect(getScreenConfig(addNavigationHelpers({ state: routes[3], dispatch: () => false }), 'title')).toEqual('10 new notifications');
|
||||
expect(getScreenConfig(addNavigationHelpers({ state: routes[3], dispatch: () => false }), 'count')).toEqual(0);
|
||||
/* $FlowFixMe: we want tests to fail on undefined */
|
||||
expect(getScreenConfig(addNavigationHelpers({ state: routes[4], dispatch: () => false }), 'header').visible).toEqual(false);
|
||||
});
|
||||
|
||||
@@ -120,13 +123,12 @@ test('should throw if the screen is not defined under the route config', () => {
|
||||
});
|
||||
|
||||
test('should get recursive config for screen', () => {
|
||||
|
||||
class NotificationScreen extends Component {
|
||||
static router = {
|
||||
getScreenConfig: (navigation, optionName) => 'Baz',
|
||||
getScreenConfig: () => 'Baz',
|
||||
};
|
||||
static navigationOptions = {
|
||||
title: (navigation, childTitle) => `Bar ${childTitle}`,
|
||||
title: (navigation: *, childTitle: *) => `Bar ${childTitle}`,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -134,7 +136,7 @@ test('should get recursive config for screen', () => {
|
||||
Notifications: {
|
||||
screen: NotificationScreen,
|
||||
navigationOptions: {
|
||||
title: (navigation, childTitle) => `Foo ${childTitle}`,
|
||||
title: (navigation: *, childTitle: *) => `Foo ${childTitle}`,
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -144,7 +146,7 @@ test('should get recursive config for screen', () => {
|
||||
key: 'A',
|
||||
routeName: 'Notifications',
|
||||
index: 0,
|
||||
routes: [ { key: 'A', routeName: 'Anything' } ],
|
||||
routes: [{ key: 'A', routeName: 'Anything' }],
|
||||
},
|
||||
dispatch: () => false,
|
||||
});
|
||||
@@ -153,10 +155,9 @@ test('should get recursive config for screen', () => {
|
||||
});
|
||||
|
||||
test('Allow passthrough configuration', () => {
|
||||
|
||||
class NotificationScreen extends Component {
|
||||
static navigationOptions = {
|
||||
tabBar: (navigation, tabBar) => ({ deepConfig: `also ${tabBar.color}` }),
|
||||
tabBar: (navigation: *, tabBar: *) => ({ deepConfig: `also ${tabBar.color}` }),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -174,5 +175,5 @@ test('Allow passthrough configuration', () => {
|
||||
dispatch: () => false,
|
||||
});
|
||||
|
||||
expect(getScreenConfig(childNavigation, 'tabBar', {color: 'red'})).toEqual({deepConfig: 'also red'});
|
||||
expect(getScreenConfig(childNavigation, 'tabBar', { color: 'red' })).toEqual({ deepConfig: 'also red' });
|
||||
});
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
/* @flow */
|
||||
|
||||
import React from 'react';
|
||||
|
||||
|
||||
@@ -8,10 +8,10 @@ import getScreenForRouteName from './getScreenForRouteName';
|
||||
import addNavigationHelpers from '../addNavigationHelpers';
|
||||
|
||||
import type {
|
||||
NavigationScreenProp,
|
||||
NavigationRoute,
|
||||
NavigationProp,
|
||||
NavigationAction,
|
||||
NavigationRouteConfigMap,
|
||||
NavigationScreenOption,
|
||||
NavigationScreenOptions,
|
||||
} from '../TypeDefinition';
|
||||
|
||||
@@ -20,9 +20,9 @@ export default (
|
||||
defaultOptions?: NavigationScreenOptions
|
||||
) =>
|
||||
(
|
||||
navigation: NavigationScreenProp<NavigationRoute, NavigationAction>,
|
||||
navigation: NavigationProp<*, NavigationAction>,
|
||||
optionName: string,
|
||||
config?: Object
|
||||
config?: NavigationScreenOption<*>
|
||||
) => {
|
||||
const route = navigation.state;
|
||||
invariant(
|
||||
@@ -55,7 +55,7 @@ export default (
|
||||
Component.navigationOptions,
|
||||
routeConfig.navigationOptions,
|
||||
].reduce(
|
||||
(acc: Object, options: NavigationScreenOptions) => {
|
||||
(acc: *, options: NavigationScreenOptions) => {
|
||||
if (options && options[optionName] !== undefined) {
|
||||
return typeof options[optionName] === 'function'
|
||||
? options[optionName](navigation, acc)
|
||||
|
||||
@@ -2,34 +2,37 @@
|
||||
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
|
||||
import type { NavigationRouteConfigMap } from '../TypeDefinition';
|
||||
import type {
|
||||
NavigationComponent,
|
||||
NavigationRouteConfigMap,
|
||||
} from '../TypeDefinition';
|
||||
|
||||
/**
|
||||
* Simple helper that gets a single screen (React component or navigator)
|
||||
* out of the navigator config.
|
||||
*/
|
||||
export default function getScreenForRouteName(
|
||||
export default function getScreenForRouteName( // eslint-disable-line consistent-return
|
||||
routeConfigs: NavigationRouteConfigMap,
|
||||
routeName: string,
|
||||
) {
|
||||
): NavigationComponent {
|
||||
const routeConfig = routeConfigs[routeName];
|
||||
|
||||
invariant(
|
||||
routeConfig,
|
||||
`There is no route defined for key ${routeName}.\n` +
|
||||
`Must be one of: ${Object.keys(routeConfigs).map(a => `'${a}'`).join(',')}`
|
||||
`Must be one of: ${Object.keys(routeConfigs).map((a: string) => `'${a}'`).join(',')}`
|
||||
);
|
||||
|
||||
if (routeConfig.screen) {
|
||||
return routeConfig.screen;
|
||||
}
|
||||
|
||||
if (routeConfig.getScreen) {
|
||||
if (typeof routeConfig.getScreen === 'function') {
|
||||
const screen = routeConfig.getScreen();
|
||||
invariant(
|
||||
typeof screen === 'function',
|
||||
`The getScreen defined for route '${routeName} didn't return a valid ` +
|
||||
`screen or navigator.\n\n` +
|
||||
'screen or navigator.\n\n' +
|
||||
'Please pass it like this:\n' +
|
||||
`${routeName}: {\n getScreen: () => require('./MyScreen').default\n}`
|
||||
);
|
||||
|
||||
@@ -34,10 +34,7 @@ function validateRouteConfigMap(routeConfigs: NavigationRouteConfigMap) {
|
||||
|
||||
if (routeConfig.screen) {
|
||||
invariant(
|
||||
// `screen: MyScreen`
|
||||
typeof (routeConfig.screen) === 'function',
|
||||
//(!routeConfig.screen.navigation) &&
|
||||
//(!routeConfig.component.router),
|
||||
`The component for route '${routeName}' must be a ` +
|
||||
'a React component. For example:\n\n' +
|
||||
'import MyScreen from \'./MyScreen\';\n' +
|
||||
|
||||
47
packages/react-navigation/src/views/CardStack.js
vendored
47
packages/react-navigation/src/views/CardStack.js
vendored
@@ -1,6 +1,6 @@
|
||||
/* @flow */
|
||||
|
||||
import React, { PropTypes } from 'react';
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
NativeModules,
|
||||
@@ -21,18 +21,16 @@ import SceneView from './SceneView';
|
||||
import type {
|
||||
NavigationAction,
|
||||
NavigationScreenProp,
|
||||
NavigationState,
|
||||
NavigationScene,
|
||||
NavigationRoute,
|
||||
NavigationSceneRenderer,
|
||||
NavigationSceneRendererProps,
|
||||
NavigationTransitionProps,
|
||||
NavigationRouter,
|
||||
Style,
|
||||
} from '../TypeDefinition';
|
||||
|
||||
import type {
|
||||
HeaderMode,
|
||||
HeaderProps,
|
||||
} from './Header';
|
||||
|
||||
import type { TransitionConfig } from './TransitionConfigs';
|
||||
@@ -44,14 +42,14 @@ const NativeAnimatedModule = NativeModules && NativeModules.NativeAnimatedModule
|
||||
type Props = {
|
||||
screenProps?: {};
|
||||
headerMode: HeaderMode,
|
||||
headerComponent?: ReactClass<HeaderProps>,
|
||||
headerComponent?: ReactClass<*>,
|
||||
mode: 'card' | 'modal',
|
||||
navigation: NavigationScreenProp<NavigationState, NavigationAction>,
|
||||
navigation: NavigationScreenProp<*, NavigationAction>,
|
||||
router: NavigationRouter,
|
||||
cardStyle?: any,
|
||||
cardStyle?: Style,
|
||||
onTransitionStart?: () => void,
|
||||
onTransitionEnd?: () => void,
|
||||
style: any,
|
||||
style: Style,
|
||||
gestureResponseDistance?: ?number,
|
||||
/**
|
||||
* If true, enable navigating back by swiping (see CardStackPanResponder).
|
||||
@@ -67,13 +65,15 @@ type Props = {
|
||||
type DefaultProps = {
|
||||
mode: 'card' | 'modal',
|
||||
gesturesEnabled: boolean,
|
||||
headerComponent: ReactClass<HeaderProps>,
|
||||
headerComponent: ReactClass<*>,
|
||||
};
|
||||
|
||||
class CardStack extends React.Component<DefaultProps, Props, void> {
|
||||
class CardStack extends Component<DefaultProps, Props, void> {
|
||||
_render: NavigationSceneRenderer;
|
||||
_renderScene: NavigationSceneRenderer;
|
||||
_childNavigationProps: { [key: string]: NavigationScreenProp<NavigationRoute, NavigationAction> } = {};
|
||||
_childNavigationProps: {
|
||||
[key: string]: NavigationScreenProp<*, NavigationAction>
|
||||
} = {};
|
||||
|
||||
static Card = Card;
|
||||
static Header = Header;
|
||||
@@ -248,7 +248,7 @@ class CardStack extends React.Component<DefaultProps, Props, void> {
|
||||
style={styles.scenes}
|
||||
>
|
||||
{props.scenes.map(
|
||||
scene => this._renderScene({
|
||||
(scene: *) => this._renderScene({
|
||||
...props,
|
||||
scene,
|
||||
navigation: this._getChildNavigation(scene),
|
||||
@@ -286,13 +286,13 @@ class CardStack extends React.Component<DefaultProps, Props, void> {
|
||||
...this.props.transitionConfig,
|
||||
...defaultConfig,
|
||||
};
|
||||
} else {
|
||||
return defaultConfig;
|
||||
}
|
||||
|
||||
return defaultConfig;
|
||||
}
|
||||
|
||||
_renderInnerCard(
|
||||
Component: ReactClass<*>,
|
||||
SceneComponent: ReactClass<*>,
|
||||
props: NavigationSceneRendererProps,
|
||||
): React.Element<*> {
|
||||
const header = this.props.router.getScreenConfig(props.navigation, 'header');
|
||||
@@ -307,7 +307,7 @@ class CardStack extends React.Component<DefaultProps, Props, void> {
|
||||
<SceneView
|
||||
screenProps={this.props.screenProps}
|
||||
navigation={props.navigation}
|
||||
component={Component}
|
||||
component={SceneComponent}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
@@ -316,12 +316,14 @@ class CardStack extends React.Component<DefaultProps, Props, void> {
|
||||
<SceneView
|
||||
screenProps={this.props.screenProps}
|
||||
navigation={props.navigation}
|
||||
component={Component}
|
||||
component={SceneComponent}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_getChildNavigation = (scene: NavigationScene): NavigationScreenProp<NavigationRoute, NavigationAction> => {
|
||||
_getChildNavigation = (
|
||||
scene: NavigationScene
|
||||
): NavigationScreenProp<*, NavigationAction> => {
|
||||
let navigation = this._childNavigationProps[scene.key];
|
||||
if (!navigation || navigation.state !== scene.route) {
|
||||
navigation = this._childNavigationProps[scene.key] = addNavigationHelpers({
|
||||
@@ -335,6 +337,7 @@ class CardStack extends React.Component<DefaultProps, Props, void> {
|
||||
_renderScene(props: NavigationSceneRendererProps): React.Element<*> {
|
||||
const isModal = this.props.mode === 'modal';
|
||||
|
||||
/* $FlowFixMe */
|
||||
const { screenInterpolator } = this._getTransitionConfig();
|
||||
const style = screenInterpolator && screenInterpolator(props);
|
||||
|
||||
@@ -343,7 +346,9 @@ class CardStack extends React.Component<DefaultProps, Props, void> {
|
||||
if (this.props.gesturesEnabled) {
|
||||
let onNavigateBack = null;
|
||||
if (this.props.navigation.state.index !== 0) {
|
||||
onNavigateBack = () => this.props.navigation.dispatch(NavigationActions.back({ key: props.scene.route.key }));
|
||||
onNavigateBack = () => this.props.navigation.dispatch(
|
||||
NavigationActions.back({ key: props.scene.route.key })
|
||||
);
|
||||
}
|
||||
const panHandlersProps = {
|
||||
...props,
|
||||
@@ -355,14 +360,14 @@ class CardStack extends React.Component<DefaultProps, Props, void> {
|
||||
CardStackPanResponder.forHorizontal(panHandlersProps);
|
||||
}
|
||||
|
||||
const Component = this.props.router.getComponentForRouteName(props.scene.route.routeName);
|
||||
const SceneComponent = this.props.router.getComponentForRouteName(props.scene.route.routeName);
|
||||
|
||||
return (
|
||||
<Card
|
||||
{...props}
|
||||
key={`card_${props.scene.key}`}
|
||||
panHandlers={panHandlers}
|
||||
renderScene={props => this._renderInnerCard(Component, props)}
|
||||
renderScene={(sceneProps: *) => this._renderInnerCard(SceneComponent, sceneProps)}
|
||||
style={[style, this.props.cardStyle]}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -12,7 +12,9 @@ import TouchableItem from '../TouchableItem';
|
||||
import type {
|
||||
NavigationScreenProp,
|
||||
NavigationState,
|
||||
NavigationRoute,
|
||||
NavigationAction,
|
||||
Style,
|
||||
} from '../../TypeDefinition';
|
||||
import type {
|
||||
DrawerScene,
|
||||
@@ -26,7 +28,7 @@ type Props = {
|
||||
inactiveBackgroundColor?: string;
|
||||
getLabelText: (scene: DrawerScene) => string;
|
||||
renderIcon: (scene: DrawerScene) => ?React.Element<*>;
|
||||
style?: any;
|
||||
style?: Style;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,9 @@ type Props = {
|
||||
screenProps?: {};
|
||||
router: NavigationRouter,
|
||||
navigation: NavigationScreenProp<NavigationState, NavigationAction>,
|
||||
childNavigationProps: { [key: string]: NavigationScreenProp<NavigationRoute, NavigationAction> },
|
||||
childNavigationProps: {
|
||||
[key: string]: NavigationScreenProp<NavigationRoute, NavigationAction>;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,15 +12,17 @@ import withCachedChildNavigation from '../../withCachedChildNavigation';
|
||||
import type {
|
||||
NavigationScreenProp,
|
||||
NavigationState,
|
||||
NavigationRoute,
|
||||
NavigationAction,
|
||||
NavigationRouter,
|
||||
Style,
|
||||
} from '../../TypeDefinition';
|
||||
|
||||
import type {
|
||||
DrawerScene,
|
||||
} from './DrawerView';
|
||||
|
||||
type Navigation = NavigationScreenProp<NavigationState, NavigationAction>;
|
||||
type Navigation = NavigationScreenProp<NavigationRoute, NavigationAction>;
|
||||
|
||||
type Props = {
|
||||
router: NavigationRouter,
|
||||
@@ -28,7 +30,7 @@ type Props = {
|
||||
childNavigationProps: { [key: string]: Navigation },
|
||||
contentComponent: ReactClass<*>,
|
||||
contentOptions?: {},
|
||||
style?: any;
|
||||
style?: Style;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,6 +13,7 @@ import type {
|
||||
NavigationRouter,
|
||||
NavigationState,
|
||||
NavigationAction,
|
||||
Style,
|
||||
} from '../../TypeDefinition';
|
||||
|
||||
export type DrawerScene = {
|
||||
@@ -27,21 +28,19 @@ export type DrawerViewConfig = {
|
||||
drawerPosition: 'left' | 'right',
|
||||
contentComponent: ReactClass<*>,
|
||||
contentOptions?: {},
|
||||
style?: any;
|
||||
style?: Style;
|
||||
};
|
||||
|
||||
type Navigation = NavigationScreenProp<NavigationState, NavigationAction>;
|
||||
|
||||
type Props = DrawerViewConfig & {
|
||||
screenProps?: {};
|
||||
router: NavigationRouter,
|
||||
navigation: Navigation,
|
||||
navigation: NavigationScreenProp<NavigationState, NavigationAction>,
|
||||
};
|
||||
|
||||
/**
|
||||
* Component that renders the drawer.
|
||||
*/
|
||||
export default class DrawerView extends PureComponent<void, Props, void> {
|
||||
export default class DrawerView<T: *> extends PureComponent<void, Props, void> {
|
||||
|
||||
static Items = DrawerNavigatorItems;
|
||||
|
||||
@@ -63,7 +62,7 @@ export default class DrawerView extends PureComponent<void, Props, void> {
|
||||
this._updateScreenNavigation(nextProps.navigation);
|
||||
}
|
||||
|
||||
_screenNavigationProp: Navigation;
|
||||
_screenNavigationProp: NavigationScreenProp<T, NavigationAction>;
|
||||
|
||||
_handleDrawerOpen = () => {
|
||||
const { navigation } = this.props;
|
||||
@@ -82,9 +81,9 @@ export default class DrawerView extends PureComponent<void, Props, void> {
|
||||
};
|
||||
|
||||
_updateScreenNavigation = (
|
||||
navigation: Navigation
|
||||
navigation: NavigationScreenProp<NavigationState, NavigationAction>
|
||||
) => {
|
||||
const navigationState: any = navigation.state.routes.find((route: *) => route.routeName === 'DrawerClose');
|
||||
const navigationState = navigation.state.routes.find((route: *) => route.routeName === 'DrawerClose');
|
||||
if (this._screenNavigationProp && this._screenNavigationProp.state === navigationState) {
|
||||
return;
|
||||
}
|
||||
@@ -94,8 +93,10 @@ export default class DrawerView extends PureComponent<void, Props, void> {
|
||||
});
|
||||
}
|
||||
|
||||
_getNavigationState = (navigation: Navigation) => {
|
||||
const navigationState: any = navigation.state.routes.find((route: *) => route.routeName === 'DrawerClose');
|
||||
_getNavigationState = (
|
||||
navigation: NavigationScreenProp<NavigationState, NavigationAction>
|
||||
) => {
|
||||
const navigationState = navigation.state.routes.find((route: *) => route.routeName === 'DrawerClose');
|
||||
return navigationState;
|
||||
};
|
||||
|
||||
|
||||
76
packages/react-navigation/src/views/Header.js
vendored
76
packages/react-navigation/src/views/Header.js
vendored
@@ -20,30 +20,31 @@ import addNavigationHelpers from '../addNavigationHelpers';
|
||||
import type {
|
||||
NavigationScene,
|
||||
NavigationRouter,
|
||||
NavigationRoute,
|
||||
NavigationState,
|
||||
NavigationAction,
|
||||
NavigationScreenProp,
|
||||
NavigationSceneRendererProps,
|
||||
NavigationStyleInterpolator,
|
||||
Style,
|
||||
} from '../TypeDefinition';
|
||||
|
||||
export type HeaderMode = 'float' | 'screen' | 'none';
|
||||
|
||||
type SubViewProps = NavigationSceneRendererProps & {
|
||||
onNavigateBack: ?() => void,
|
||||
onNavigateBack?: () => void,
|
||||
};
|
||||
|
||||
type Navigation = NavigationScreenProp<NavigationRoute, NavigationAction>;
|
||||
type Navigation = NavigationScreenProp<NavigationState, NavigationAction>;
|
||||
|
||||
type SubViewRenderer = (subViewProps: SubViewProps) => ?React.Element<*>;
|
||||
|
||||
export type HeaderProps = NavigationSceneRendererProps & {
|
||||
mode: HeaderMode,
|
||||
onNavigateBack: ?Function,
|
||||
onNavigateBack?: () => void,
|
||||
renderLeftComponent: SubViewRenderer,
|
||||
renderRightComponent: SubViewRenderer,
|
||||
renderTitleComponent: SubViewRenderer,
|
||||
tintColor: ?string,
|
||||
tintColor?: string,
|
||||
router: NavigationRouter,
|
||||
};
|
||||
|
||||
@@ -98,7 +99,7 @@ class Header extends React.Component<void, HeaderProps, void> {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
_getHeaderTitleStyle(navigation: Navigation): ?object {
|
||||
_getHeaderTitleStyle(navigation: Navigation): Style {
|
||||
const header = this.props.router.getScreenConfig(navigation, 'header');
|
||||
if (header && header.titleStyle) {
|
||||
return header.titleStyle;
|
||||
@@ -106,14 +107,14 @@ class Header extends React.Component<void, HeaderProps, void> {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
_renderTitleComponent = (props: SubViewProps) => {
|
||||
_renderTitleComponent = (props: SubViewProps): React.Element<HeaderTitle> => {
|
||||
const titleStyle = this._getHeaderTitleStyle(props.navigation);
|
||||
const color = this._getHeaderTintColor(props.navigation);
|
||||
const title = this._getHeaderTitle(props.navigation);
|
||||
return <HeaderTitle style={[color && { color }, titleStyle]}>{title}</HeaderTitle>;
|
||||
return <HeaderTitle style={[color ? { color } : null, titleStyle]}>{title}</HeaderTitle>;
|
||||
};
|
||||
|
||||
_renderLeftComponent = (props: SubViewProps) => {
|
||||
_renderLeftComponent = (props: SubViewProps): ?React.Element<HeaderBackButton> => {
|
||||
if (props.scene.index === 0 || !props.onNavigateBack) {
|
||||
return null;
|
||||
}
|
||||
@@ -137,21 +138,17 @@ class Header extends React.Component<void, HeaderProps, void> {
|
||||
);
|
||||
};
|
||||
|
||||
_renderRightComponent = () => {
|
||||
return null;
|
||||
};
|
||||
_renderRightComponent = () => null;
|
||||
|
||||
_renderLeft(props: NavigationSceneRendererProps): ?React.Element<*> {
|
||||
return this._renderSubView(
|
||||
_renderLeft = (props: NavigationSceneRendererProps): ?React.Element<*> => this._renderSubView(
|
||||
props,
|
||||
'left',
|
||||
this.props.renderLeftComponent,
|
||||
this._renderLeftComponent,
|
||||
HeaderStyleInterpolator.forLeft,
|
||||
);
|
||||
}
|
||||
|
||||
_renderTitle(props: NavigationSceneRendererProps, options: *): ?React.Element<*> {
|
||||
_renderTitle = (props: NavigationSceneRendererProps, options: *): ?React.Element<*> => {
|
||||
const style = {};
|
||||
|
||||
if (Platform.OS === 'android') {
|
||||
@@ -172,15 +169,13 @@ class Header extends React.Component<void, HeaderProps, void> {
|
||||
);
|
||||
}
|
||||
|
||||
_renderRight(props: NavigationSceneRendererProps): ?React.Element<*> {
|
||||
return this._renderSubView(
|
||||
_renderRight = (props: NavigationSceneRendererProps): ?React.Element<*> => this._renderSubView(
|
||||
props,
|
||||
'right',
|
||||
this.props.renderRightComponent,
|
||||
this._renderRightComponent,
|
||||
HeaderStyleInterpolator.forRight,
|
||||
);
|
||||
}
|
||||
|
||||
_renderSubView(
|
||||
props: NavigationSceneRendererProps,
|
||||
@@ -241,11 +236,10 @@ class Header extends React.Component<void, HeaderProps, void> {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { scenes, scene, style, position, progress, ...rest } = this.props;
|
||||
|
||||
let leftComponents = null;
|
||||
let titleComponents = null;
|
||||
let rightComponents = null;
|
||||
let appBar = null;
|
||||
|
||||
if (this.props.mode === 'float') {
|
||||
// eslint-disable-next-line no-shadow
|
||||
const scenesProps = (scenes.map((scene: NavigationScene, index: number) => {
|
||||
const props = NavigationPropTypes.extractSceneRendererProps(this.props);
|
||||
props.scene = scene;
|
||||
@@ -256,35 +250,47 @@ class Header extends React.Component<void, HeaderProps, void> {
|
||||
});
|
||||
return props;
|
||||
}): Array<NavigationSceneRendererProps>);
|
||||
leftComponents = scenesProps.map(this._renderLeft, this);
|
||||
rightComponents = scenesProps.map(this._renderRight, this);
|
||||
titleComponents = scenesProps.map((props: *, i: number) =>
|
||||
const leftComponents = scenesProps.map(this._renderLeft, this);
|
||||
const rightComponents = scenesProps.map(this._renderRight, this);
|
||||
const titleComponents = scenesProps.map((props: *, i: number) =>
|
||||
this._renderTitle(props, {
|
||||
hasLeftComponent: leftComponents && !!leftComponents[i],
|
||||
hasRightComponent: rightComponents && !!rightComponents[i],
|
||||
})
|
||||
);
|
||||
|
||||
appBar = (
|
||||
<View style={styles.appBar}>
|
||||
{titleComponents}
|
||||
{leftComponents}
|
||||
{rightComponents}
|
||||
</View>
|
||||
);
|
||||
} else {
|
||||
const staticRendererProps = {
|
||||
...this.props,
|
||||
position: new Animated.Value(scene.index),
|
||||
progress: new Animated.Value(0),
|
||||
};
|
||||
leftComponents = this._renderLeft(staticRendererProps);
|
||||
rightComponents = this._renderRight(staticRendererProps);
|
||||
titleComponents = this._renderTitle(staticRendererProps, {
|
||||
hasLeftComponent: !!leftComponents,
|
||||
hasRightComponent: !!rightComponents,
|
||||
const leftComponent = this._renderLeft(staticRendererProps);
|
||||
const rightComponent = this._renderRight(staticRendererProps);
|
||||
const titleComponent = this._renderTitle(staticRendererProps, {
|
||||
hasLeftComponent: !!leftComponent,
|
||||
hasRightComponent: !!rightComponent,
|
||||
});
|
||||
|
||||
appBar = (
|
||||
<View style={styles.appBar}>
|
||||
{titleComponent}
|
||||
{leftComponent}
|
||||
{rightComponent}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Animated.View {...rest} style={[styles.container, style]}>
|
||||
<View style={styles.appBar}>
|
||||
{titleComponents}
|
||||
{leftComponents}
|
||||
{rightComponents}
|
||||
</View>
|
||||
{appBar}
|
||||
</Animated.View>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@ import {
|
||||
import TouchableItem from './TouchableItem';
|
||||
|
||||
type Props = {
|
||||
onPress: Function,
|
||||
onPress?: () => void,
|
||||
title?: string,
|
||||
tintColor?: string;
|
||||
tintColor?: ?string;
|
||||
};
|
||||
|
||||
const HeaderBackButton = ({ onPress, title, tintColor }: Props) => (
|
||||
|
||||
@@ -8,8 +8,13 @@ import {
|
||||
Text,
|
||||
} from 'react-native';
|
||||
|
||||
import type {
|
||||
Style,
|
||||
} from '../TypeDefinition';
|
||||
|
||||
type Props = {
|
||||
style?: any,
|
||||
tintColor?: ?string;
|
||||
style?: Style,
|
||||
};
|
||||
|
||||
const HeaderTitle = ({ style, ...rest }: Props) => (
|
||||
|
||||
@@ -5,13 +5,13 @@ import React, { PureComponent } from 'react';
|
||||
import type {
|
||||
NavigationScreenProp,
|
||||
NavigationState,
|
||||
NavigationRoute,
|
||||
NavigationAction,
|
||||
ContextWithNavigation,
|
||||
} from '../TypeDefinition';
|
||||
|
||||
type Props = {
|
||||
screenProps?: {};
|
||||
navigation: NavigationScreenProp<NavigationState, NavigationAction>;
|
||||
navigation: NavigationScreenProp<NavigationRoute, NavigationAction>;
|
||||
component: ReactClass<*>;
|
||||
};
|
||||
|
||||
@@ -24,7 +24,7 @@ export default class SceneView extends PureComponent<void, Props, void> {
|
||||
|
||||
props: Props;
|
||||
|
||||
getChildContext(): ContextWithNavigation {
|
||||
getChildContext() {
|
||||
return {
|
||||
navigation: this.props.navigation,
|
||||
};
|
||||
|
||||
@@ -12,14 +12,12 @@ import TabBarIcon from './TabBarIcon';
|
||||
import type {
|
||||
NavigationRoute,
|
||||
NavigationState,
|
||||
Style,
|
||||
} from '../../TypeDefinition';
|
||||
|
||||
type TabScene = {
|
||||
route: NavigationRoute;
|
||||
focused: boolean;
|
||||
index: number;
|
||||
tintColor?: string;
|
||||
};
|
||||
import type {
|
||||
TabScene,
|
||||
} from './TabView';
|
||||
|
||||
type DefaultProps = {
|
||||
activeTintColor: string;
|
||||
@@ -40,8 +38,8 @@ type Props = {
|
||||
getLabelText: (scene: TabScene) => string;
|
||||
renderIcon: (scene: TabScene) => React.Element<*>;
|
||||
showLabel: boolean;
|
||||
style: any;
|
||||
labelStyle?: any;
|
||||
style?: Style;
|
||||
labelStyle?: Style;
|
||||
showIcon: boolean;
|
||||
};
|
||||
|
||||
|
||||
@@ -8,25 +8,23 @@ import {
|
||||
} from 'react-native';
|
||||
|
||||
import type {
|
||||
NavigationRoute,
|
||||
NavigationState,
|
||||
NavigationRoute,
|
||||
Style,
|
||||
} from '../../TypeDefinition';
|
||||
|
||||
type TabScene = {
|
||||
route: NavigationRoute;
|
||||
focused: boolean;
|
||||
index: number;
|
||||
tintColor?: string;
|
||||
};
|
||||
import type {
|
||||
TabScene,
|
||||
} from './TabView';
|
||||
|
||||
type Props = {
|
||||
activeTintColor: string;
|
||||
inactiveTintColor: string;
|
||||
scene: TabScene,
|
||||
scene: TabScene;
|
||||
position: Animated.Value;
|
||||
navigationState: NavigationState;
|
||||
renderIcon: (scene: TabScene) => React.Element<*>;
|
||||
style?: any;
|
||||
style?: Style;
|
||||
};
|
||||
|
||||
export default class TabBarIcon extends PureComponent<void, Props, void> {
|
||||
|
||||
@@ -9,16 +9,14 @@ import { TabBar } from 'react-native-tab-view';
|
||||
import TabBarIcon from './TabBarIcon';
|
||||
|
||||
import type {
|
||||
NavigationRoute,
|
||||
NavigationState,
|
||||
NavigationRoute,
|
||||
Style,
|
||||
} from '../../TypeDefinition';
|
||||
|
||||
type TabScene = {
|
||||
route: NavigationRoute;
|
||||
focused: boolean;
|
||||
index: number;
|
||||
tintColor?: string;
|
||||
};
|
||||
import type {
|
||||
TabScene,
|
||||
} from './TabView';
|
||||
|
||||
type DefaultProps = {
|
||||
activeTintColor: string;
|
||||
@@ -38,7 +36,7 @@ type Props = {
|
||||
navigationState: NavigationState;
|
||||
getLabelText: (scene: TabScene) => string;
|
||||
renderIcon: (scene: TabScene) => React.Element<*>;
|
||||
labelStyle?: any;
|
||||
labelStyle?: Style;
|
||||
};
|
||||
|
||||
export default class TabBarTop extends PureComponent<DefaultProps, Props, void> {
|
||||
@@ -81,7 +79,7 @@ export default class TabBarTop extends PureComponent<DefaultProps, Props, void>
|
||||
if (typeof label === 'string') {
|
||||
return (
|
||||
<Animated.Text style={[styles.label, { color }, labelStyle]}>
|
||||
{label}
|
||||
{upperCaseLabel ? label.toUpperCase() : label}
|
||||
</Animated.Text>
|
||||
);
|
||||
}
|
||||
@@ -115,10 +113,12 @@ export default class TabBarTop extends PureComponent<DefaultProps, Props, void>
|
||||
};
|
||||
|
||||
render() {
|
||||
// TODO: Define full proptypes
|
||||
const props: any = this.props;
|
||||
|
||||
return (
|
||||
<TabBar
|
||||
{/* $FlowFixMe */
|
||||
...this.props}
|
||||
{...props}
|
||||
renderIcon={this._renderIcon}
|
||||
renderLabel={this._renderLabel}
|
||||
/>
|
||||
|
||||
@@ -33,6 +33,13 @@ export type TabViewConfig = {
|
||||
lazyLoad?: boolean;
|
||||
};
|
||||
|
||||
export type TabScene = {
|
||||
route: NavigationRoute;
|
||||
focused: boolean;
|
||||
index: number;
|
||||
tintColor?: ?string;
|
||||
};
|
||||
|
||||
type Props = TabViewConfig & {
|
||||
screenProps?: {},
|
||||
navigation: NavigationScreenProp<NavigationState, NavigationAction>;
|
||||
@@ -40,13 +47,6 @@ type Props = TabViewConfig & {
|
||||
childNavigationProps: { [key: string]: NavigationScreenProp<NavigationRoute, NavigationAction> },
|
||||
};
|
||||
|
||||
type TabScene = {
|
||||
route: NavigationRoute;
|
||||
focused: boolean;
|
||||
index: number;
|
||||
tintColor?: string;
|
||||
};
|
||||
|
||||
let TabViewPager;
|
||||
|
||||
switch (Platform.OS) {
|
||||
@@ -176,6 +176,7 @@ class TabView extends PureComponent<void, Props, void> {
|
||||
}
|
||||
|
||||
return (
|
||||
/* $FlowFixMe */
|
||||
<TabViewAnimated
|
||||
style={styles.container}
|
||||
navigationState={navigation.state}
|
||||
@@ -193,7 +194,6 @@ class TabView extends PureComponent<void, Props, void> {
|
||||
|
||||
const TabViewEnhanced = withCachedChildNavigation(TabView);
|
||||
|
||||
/* $FlowFixMe */
|
||||
TabViewEnhanced.TabBarTop = TabBarTop;
|
||||
TabViewEnhanced.TabBarBottom = TabBarBottom;
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@ import {
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import type {
|
||||
Style,
|
||||
} from '../TypeDefinition';
|
||||
|
||||
const ANDROID_VERSION_LOLLIPOP = 21;
|
||||
|
||||
@@ -26,7 +29,7 @@ type Props = {
|
||||
pressColor?: string;
|
||||
activeOpacity?: number;
|
||||
children?: React.Element<*>;
|
||||
style?: any;
|
||||
style?: Style;
|
||||
};
|
||||
|
||||
type DefaultProps = {
|
||||
@@ -58,9 +61,11 @@ export default class TouchableItem extends Component<DefaultProps, Props, void>
|
||||
* We need to pass the background prop to specify a borderless ripple effect.
|
||||
*/
|
||||
if (Platform.OS === 'android' && Platform.Version >= ANDROID_VERSION_LOLLIPOP) {
|
||||
const { style, ...rest } = this.props; // eslint-disable-line no-unused-vars
|
||||
|
||||
return (
|
||||
<TouchableNativeFeedback
|
||||
{...this.props}
|
||||
{...rest}
|
||||
style={null}
|
||||
background={
|
||||
TouchableNativeFeedback.Ripple(
|
||||
@@ -74,12 +79,12 @@ export default class TouchableItem extends Component<DefaultProps, Props, void>
|
||||
</View>
|
||||
</TouchableNativeFeedback>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<TouchableOpacity {...this.props}>
|
||||
{this.props.children}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TouchableOpacity {...this.props}>
|
||||
{this.props.children}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import type {
|
||||
NavigationAnimatedValue,
|
||||
NavigationLayout,
|
||||
NavigationScene,
|
||||
NavigationState,
|
||||
NavigationRoute,
|
||||
NavigationAction,
|
||||
NavigationScreenProp,
|
||||
@@ -31,7 +32,7 @@ type Props = {
|
||||
transitionProps: NavigationTransitionProps,
|
||||
prevTransitionProps: ?NavigationTransitionProps,
|
||||
) => NavigationTransitionSpec,
|
||||
navigation: NavigationScreenProp<NavigationRoute, NavigationAction>,
|
||||
navigation: NavigationScreenProp<NavigationState, NavigationAction>,
|
||||
onTransitionEnd: () => void,
|
||||
onTransitionStart: () => void,
|
||||
render: (
|
||||
@@ -58,6 +59,12 @@ class Transitioner extends React.Component<*, Props, State> {
|
||||
_prevTransitionProps: ?NavigationTransitionProps;
|
||||
_transitionProps: NavigationTransitionProps;
|
||||
_isMounted: boolean;
|
||||
_isTransitionRunning: boolean;
|
||||
_queuedTransition: ?{
|
||||
nextProps: Props,
|
||||
nextScenes: Array<NavigationScene>,
|
||||
indexHasChanged: boolean,
|
||||
};
|
||||
|
||||
props: Props;
|
||||
state: State;
|
||||
|
||||
6
packages/react-navigation/src/views/__tests__/.eslintrc
Normal file
6
packages/react-navigation/src/views/__tests__/.eslintrc
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "../../../.eslintrc",
|
||||
"env": {
|
||||
"jest": true
|
||||
},
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
/* @flow */
|
||||
|
||||
import ScenesReducer from '../ScenesReducer';
|
||||
|
||||
@@ -7,7 +8,7 @@ import ScenesReducer from '../ScenesReducer';
|
||||
function testTransition(states) {
|
||||
const routes = states.map(keys => ({
|
||||
index: 0,
|
||||
routes: keys.map(key => ({ key })),
|
||||
routes: keys.map(key => ({ key, routeName: '' })),
|
||||
}));
|
||||
|
||||
let scenes = [];
|
||||
@@ -34,6 +35,7 @@ describe('ScenesReducer', () => {
|
||||
key: 'scene_1',
|
||||
route: {
|
||||
key: '1',
|
||||
routeName: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -43,6 +45,7 @@ describe('ScenesReducer', () => {
|
||||
key: 'scene_2',
|
||||
route: {
|
||||
key: '2',
|
||||
routeName: '',
|
||||
},
|
||||
},
|
||||
]);
|
||||
@@ -63,6 +66,7 @@ describe('ScenesReducer', () => {
|
||||
key: 'scene_1',
|
||||
route: {
|
||||
key: '1',
|
||||
routeName: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -72,6 +76,7 @@ describe('ScenesReducer', () => {
|
||||
key: 'scene_2',
|
||||
route: {
|
||||
key: '2',
|
||||
routeName: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -81,6 +86,7 @@ describe('ScenesReducer', () => {
|
||||
key: 'scene_3',
|
||||
route: {
|
||||
key: '3',
|
||||
routeName: '',
|
||||
},
|
||||
},
|
||||
]);
|
||||
@@ -89,29 +95,30 @@ describe('ScenesReducer', () => {
|
||||
it('gets active scene when index changes', () => {
|
||||
const state1 = {
|
||||
index: 0,
|
||||
routes: [{ key: '1' }, { key: '2' }],
|
||||
routes: [{ key: '1', routeName: '' }, { key: '2', routeName: '' }],
|
||||
};
|
||||
|
||||
const state2 = {
|
||||
index: 1,
|
||||
routes: [{ key: '1' }, { key: '2' }],
|
||||
routes: [{ key: '1', routeName: '' }, { key: '2', routeName: '' }],
|
||||
};
|
||||
|
||||
const scenes1 = ScenesReducer([], state1, null);
|
||||
const scenes2 = ScenesReducer(scenes1, state2, state1);
|
||||
const route = scenes2.find(scene => scene.isActive).route;
|
||||
expect(route).toEqual({ key: '2' });
|
||||
/* $FlowFixMe: We want tests to fail on undefined */
|
||||
const route = scenes2.find((scene: *) => scene.isActive).route;
|
||||
expect(route).toEqual({ key: '2', routeName: '' });
|
||||
});
|
||||
|
||||
it('gets same scenes', () => {
|
||||
const state1 = {
|
||||
index: 0,
|
||||
routes: [{ key: '1' }, { key: '2' }],
|
||||
routes: [{ key: '1', routeName: '' }, { key: '2', routeName: '' }],
|
||||
};
|
||||
|
||||
const state2 = {
|
||||
index: 0,
|
||||
routes: [{ key: '1' }, { key: '2' }],
|
||||
routes: [{ key: '1', routeName: '' }, { key: '2', routeName: '' }],
|
||||
};
|
||||
|
||||
const scenes1 = ScenesReducer([], state1, null);
|
||||
@@ -122,12 +129,12 @@ describe('ScenesReducer', () => {
|
||||
it('gets different scenes when keys are different', () => {
|
||||
const state1 = {
|
||||
index: 0,
|
||||
routes: [{ key: '1' }, { key: '2' }],
|
||||
routes: [{ key: '1', routeName: '' }, { key: '2', routeName: '' }],
|
||||
};
|
||||
|
||||
const state2 = {
|
||||
index: 0,
|
||||
routes: [{ key: '2' }, { key: '1' }],
|
||||
routes: [{ key: '2', routeName: '' }, { key: '1', routeName: '' }],
|
||||
};
|
||||
|
||||
const scenes1 = ScenesReducer([], state1, null);
|
||||
@@ -138,12 +145,12 @@ describe('ScenesReducer', () => {
|
||||
it('gets different scenes when routes are different', () => {
|
||||
const state1 = {
|
||||
index: 0,
|
||||
routes: [{ key: '1', x: 1 }, { key: '2', x: 2 }],
|
||||
routes: [{ key: '1', x: 1, routeName: '' }, { key: '2', x: 2, routeName: '' }],
|
||||
};
|
||||
|
||||
const state2 = {
|
||||
index: 0,
|
||||
routes: [{ key: '1', x: 3 }, { key: '2', x: 4 }],
|
||||
routes: [{ key: '1', x: 3, routeName: '' }, { key: '2', x: 4, routeName: '' }],
|
||||
};
|
||||
|
||||
const scenes1 = ScenesReducer([], state1, null);
|
||||
@@ -155,12 +162,12 @@ describe('ScenesReducer', () => {
|
||||
it('gets different scenes when state index changes', () => {
|
||||
const state1 = {
|
||||
index: 0,
|
||||
routes: [{ key: '1', x: 1 }, { key: '2', x: 2 }],
|
||||
routes: [{ key: '1', x: 1, routeName: '' }, { key: '2', x: 2, routeName: '' }],
|
||||
};
|
||||
|
||||
const state2 = {
|
||||
index: 1,
|
||||
routes: [{ key: '1', x: 1 }, { key: '2', x: 2 }],
|
||||
routes: [{ key: '1', x: 1, routeName: '' }, { key: '2', x: 2, routeName: '' }],
|
||||
};
|
||||
|
||||
const scenes1 = ScenesReducer([], state1, null);
|
||||
@@ -183,6 +190,7 @@ describe('ScenesReducer', () => {
|
||||
key: 'scene_1',
|
||||
route: {
|
||||
key: '1',
|
||||
routeName: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -192,6 +200,7 @@ describe('ScenesReducer', () => {
|
||||
key: 'scene_2',
|
||||
route: {
|
||||
key: '2',
|
||||
routeName: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -201,6 +210,7 @@ describe('ScenesReducer', () => {
|
||||
key: 'scene_3',
|
||||
route: {
|
||||
key: '3',
|
||||
routeName: '',
|
||||
},
|
||||
},
|
||||
]);
|
||||
@@ -220,6 +230,7 @@ describe('ScenesReducer', () => {
|
||||
key: 'scene_1',
|
||||
route: {
|
||||
key: '1',
|
||||
routeName: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -229,6 +240,7 @@ describe('ScenesReducer', () => {
|
||||
key: 'scene_3',
|
||||
route: {
|
||||
key: '3',
|
||||
routeName: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -238,6 +250,7 @@ describe('ScenesReducer', () => {
|
||||
key: 'scene_2',
|
||||
route: {
|
||||
key: '2',
|
||||
routeName: '',
|
||||
},
|
||||
},
|
||||
]);
|
||||
@@ -258,6 +271,7 @@ describe('ScenesReducer', () => {
|
||||
key: 'scene_1',
|
||||
route: {
|
||||
key: '1',
|
||||
routeName: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -267,6 +281,7 @@ describe('ScenesReducer', () => {
|
||||
key: 'scene_2',
|
||||
route: {
|
||||
key: '2',
|
||||
routeName: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -276,6 +291,7 @@ describe('ScenesReducer', () => {
|
||||
key: 'scene_3',
|
||||
route: {
|
||||
key: '3',
|
||||
routeName: '',
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -3,10 +3,23 @@
|
||||
import React from 'react';
|
||||
import hoistStatics from 'hoist-non-react-statics';
|
||||
|
||||
import type { ContextWithNavigation } from '../TypeDefinition';
|
||||
import type {
|
||||
NavigationState,
|
||||
NavigationRoute,
|
||||
NavigationAction,
|
||||
} from '../TypeDefinition';
|
||||
|
||||
export default function withNavigation(Component: ReactClass<T>) {
|
||||
const componentWithNavigation = (props: T, { navigation }: ContextWithNavigation) => (
|
||||
type Context = {
|
||||
navigation: InjectedProps<NavigationState, NavigationAction>,
|
||||
};
|
||||
|
||||
type InjectedProps = {
|
||||
navigation: InjectedProps<NavigationState, NavigationAction>,
|
||||
};
|
||||
|
||||
|
||||
export default function withNavigation<T: *>(Component: ReactClass<T & InjectedProps>) {
|
||||
const componentWithNavigation = (props: T, { navigation }: Context) => (
|
||||
<Component {...props} navigation={navigation} />
|
||||
);
|
||||
|
||||
|
||||
@@ -4,23 +4,24 @@ import React, { PureComponent } from 'react';
|
||||
|
||||
import addNavigationHelpers from './addNavigationHelpers';
|
||||
|
||||
|
||||
import type {
|
||||
NavigationScreenProp,
|
||||
NavigationState,
|
||||
NavigationRoute,
|
||||
NavigationAction,
|
||||
} from './TypeDefinition';
|
||||
|
||||
type Props = {
|
||||
navigation: NavigationScreenProp<NavigationState, NavigationAction>,
|
||||
type InjectedProps<N> = {
|
||||
childNavigationProps: {
|
||||
[key: string]: N,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* HOC which caches the child navigation items.
|
||||
*/
|
||||
export default function withCachedChildNavigation<T: Props>(Comp: ReactClass<T>): ReactClass<T> {
|
||||
return class extends PureComponent<void, T, void> {
|
||||
export default function withCachedChildNavigation<T: *, N: *>(
|
||||
Comp: ReactClass<T & InjectedProps<N>>
|
||||
): ReactClass<T> {
|
||||
return class extends PureComponent {
|
||||
|
||||
static displayName = `withCachedChildNavigation(${Comp.displayName || Comp.name})`;
|
||||
|
||||
@@ -35,11 +36,11 @@ export default function withCachedChildNavigation<T: Props>(Comp: ReactClass<T>)
|
||||
}
|
||||
|
||||
_childNavigationProps: {
|
||||
[key: string]: NavigationScreenProp<NavigationRoute, NavigationAction>,
|
||||
[key: string]: NavigationScreenProp<N, NavigationAction>,
|
||||
};
|
||||
|
||||
_updateNavigationProps = (
|
||||
navigation: NavigationScreenProp<NavigationState, NavigationAction>
|
||||
navigation: NavigationScreenProp<N, NavigationAction>
|
||||
) => {
|
||||
// Update props for each child route
|
||||
if (!this._childNavigationProps) {
|
||||
|
||||
@@ -259,7 +259,7 @@ babel-code-frame@^6.16.0, babel-code-frame@^6.22.0:
|
||||
esutils "^2.0.2"
|
||||
js-tokens "^3.0.0"
|
||||
|
||||
babel-core@^6.0.0, babel-core@^6.18.2, babel-core@^6.22.0, babel-core@^6.22.1, babel-core@^6.7.2:
|
||||
babel-core@^6.0.0, babel-core@^6.18.2, babel-core@^6.21.0, babel-core@^6.22.0, babel-core@^6.22.1, babel-core@^6.7.2:
|
||||
version "6.22.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.22.1.tgz#9c5fd658ba1772d28d721f6d25d968fc7ae21648"
|
||||
dependencies:
|
||||
@@ -293,7 +293,7 @@ babel-eslint@^7.0.0:
|
||||
babylon "^6.13.0"
|
||||
lodash.pickby "^4.6.0"
|
||||
|
||||
babel-generator@^6.18.0, babel-generator@^6.19.0, babel-generator@^6.22.0:
|
||||
babel-generator@^6.18.0, babel-generator@^6.21.0, babel-generator@^6.22.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.22.0.tgz#d642bf4961911a8adc7c692b0c9297f325cda805"
|
||||
dependencies:
|
||||
@@ -542,7 +542,7 @@ babel-plugin-syntax-object-rest-spread@^6.13.0, babel-plugin-syntax-object-rest-
|
||||
version "6.13.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5"
|
||||
|
||||
babel-plugin-syntax-trailing-function-commas@^6.13.0, babel-plugin-syntax-trailing-function-commas@^6.22.0, babel-plugin-syntax-trailing-function-commas@^6.5.0, babel-plugin-syntax-trailing-function-commas@^6.8.0:
|
||||
babel-plugin-syntax-trailing-function-commas@^6.13.0, babel-plugin-syntax-trailing-function-commas@^6.20.0, babel-plugin-syntax-trailing-function-commas@^6.22.0, babel-plugin-syntax-trailing-function-commas@^6.5.0, babel-plugin-syntax-trailing-function-commas@^6.8.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3"
|
||||
|
||||
@@ -784,7 +784,7 @@ babel-plugin-transform-export-extensions@^6.22.0:
|
||||
babel-plugin-syntax-export-extensions "^6.8.0"
|
||||
babel-runtime "^6.22.0"
|
||||
|
||||
babel-plugin-transform-flow-strip-types@^6.18.0, babel-plugin-transform-flow-strip-types@^6.22.0, babel-plugin-transform-flow-strip-types@^6.5.0, babel-plugin-transform-flow-strip-types@^6.7.0, babel-plugin-transform-flow-strip-types@^6.8.0:
|
||||
babel-plugin-transform-flow-strip-types@^6.21.0, babel-plugin-transform-flow-strip-types@^6.22.0, babel-plugin-transform-flow-strip-types@^6.5.0, babel-plugin-transform-flow-strip-types@^6.7.0, babel-plugin-transform-flow-strip-types@^6.8.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf"
|
||||
dependencies:
|
||||
@@ -797,7 +797,7 @@ babel-plugin-transform-object-assign@^6.5.0:
|
||||
dependencies:
|
||||
babel-runtime "^6.22.0"
|
||||
|
||||
babel-plugin-transform-object-rest-spread@^6.19.0, babel-plugin-transform-object-rest-spread@^6.22.0, babel-plugin-transform-object-rest-spread@^6.5.0, babel-plugin-transform-object-rest-spread@^6.6.5, babel-plugin-transform-object-rest-spread@^6.8.0:
|
||||
babel-plugin-transform-object-rest-spread@^6.20.2, babel-plugin-transform-object-rest-spread@^6.22.0, babel-plugin-transform-object-rest-spread@^6.5.0, babel-plugin-transform-object-rest-spread@^6.6.5, babel-plugin-transform-object-rest-spread@^6.8.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.22.0.tgz#1d419b55e68d2e4f64a5ff3373bd67d73c8e83bc"
|
||||
dependencies:
|
||||
@@ -845,7 +845,7 @@ babel-plugin-transform-strict-mode@^6.22.0:
|
||||
babel-runtime "^6.22.0"
|
||||
babel-types "^6.22.0"
|
||||
|
||||
babel-polyfill@^6.16.0, babel-polyfill@^6.22.0:
|
||||
babel-polyfill@^6.20.0, babel-polyfill@^6.22.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.22.0.tgz#1ac99ebdcc6ba4db1e2618c387b2084a82154a3b"
|
||||
dependencies:
|
||||
@@ -981,7 +981,7 @@ babel-preset-react-native-syntax@^1.0.0:
|
||||
babel-plugin-syntax-object-rest-spread "^6.13.0"
|
||||
babel-plugin-syntax-trailing-function-commas "^6.13.0"
|
||||
|
||||
babel-preset-react-native@^1.9.0:
|
||||
babel-preset-react-native@^1.9.0, babel-preset-react-native@^1.9.1:
|
||||
version "1.9.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-preset-react-native/-/babel-preset-react-native-1.9.1.tgz#ec8e378274410d78f550fa9f8edd70353f3bb2fe"
|
||||
dependencies:
|
||||
@@ -1015,7 +1015,7 @@ babel-preset-react-native@^1.9.0:
|
||||
babel-plugin-transform-regenerator "^6.5.0"
|
||||
react-transform-hmr "^1.0.4"
|
||||
|
||||
babel-preset-react@^6.16.0:
|
||||
babel-preset-react@^6.22.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.22.0.tgz#7bc97e2d73eec4b980fb6b4e4e0884e81ccdc165"
|
||||
dependencies:
|
||||
@@ -1066,7 +1066,7 @@ babel-register@^6.18.0, babel-register@^6.22.0:
|
||||
mkdirp "^0.5.1"
|
||||
source-map-support "^0.4.2"
|
||||
|
||||
babel-runtime@^6.18.0, babel-runtime@^6.22.0:
|
||||
babel-runtime@^6.18.0, babel-runtime@^6.20.0, babel-runtime@^6.22.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.22.0.tgz#1cf8b4ac67c77a4ddb0db2ae1f74de52ac4ca611"
|
||||
dependencies:
|
||||
@@ -1083,7 +1083,7 @@ babel-template@^6.16.0, babel-template@^6.22.0:
|
||||
babylon "^6.11.0"
|
||||
lodash "^4.2.0"
|
||||
|
||||
babel-traverse@^6.15.0, babel-traverse@^6.18.0, babel-traverse@^6.19.0, babel-traverse@^6.22.0, babel-traverse@^6.22.1:
|
||||
babel-traverse@^6.15.0, babel-traverse@^6.18.0, babel-traverse@^6.21.0, babel-traverse@^6.22.0, babel-traverse@^6.22.1:
|
||||
version "6.22.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.22.1.tgz#3b95cd6b7427d6f1f757704908f2fc9748a5f59f"
|
||||
dependencies:
|
||||
@@ -1097,7 +1097,7 @@ babel-traverse@^6.15.0, babel-traverse@^6.18.0, babel-traverse@^6.19.0, babel-tr
|
||||
invariant "^2.2.0"
|
||||
lodash "^4.2.0"
|
||||
|
||||
babel-types@^6.15.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.22.0:
|
||||
babel-types@^6.15.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.21.0, babel-types@^6.22.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.22.0.tgz#2a447e8d0ea25d2512409e4175479fd78cc8b1db"
|
||||
dependencies:
|
||||
@@ -1214,18 +1214,12 @@ browser-resolve@^1.11.2:
|
||||
dependencies:
|
||||
resolve "1.1.7"
|
||||
|
||||
bser@1.0.2:
|
||||
bser@1.0.2, bser@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/bser/-/bser-1.0.2.tgz#381116970b2a6deea5646dd15dd7278444b56169"
|
||||
dependencies:
|
||||
node-int64 "^0.4.0"
|
||||
|
||||
bser@^1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/bser/-/bser-1.0.3.tgz#d63da19ee17330a0e260d2a34422b21a89520317"
|
||||
dependencies:
|
||||
node-int64 "^0.4.0"
|
||||
|
||||
buffer-shims@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51"
|
||||
@@ -2130,9 +2124,9 @@ flat-cache@^1.2.1:
|
||||
graceful-fs "^4.1.2"
|
||||
write "^0.2.1"
|
||||
|
||||
flow-bin@^0.35.0:
|
||||
version "0.35.0"
|
||||
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.35.0.tgz#63d4eb9582ce352541be98e6a424503217141b07"
|
||||
flow-bin@^0.37.4:
|
||||
version "0.37.4"
|
||||
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.37.4.tgz#3d8da2ef746e80e730d166e09040f4198969b76b"
|
||||
|
||||
for-in@^0.1.5:
|
||||
version "0.1.6"
|
||||
@@ -2844,9 +2838,9 @@ jest-file-exists@^17.0.0:
|
||||
version "17.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-file-exists/-/jest-file-exists-17.0.0.tgz#7f63eb73a1c43a13f461be261768b45af2cdd169"
|
||||
|
||||
jest-haste-map@17.0.3:
|
||||
version "17.0.3"
|
||||
resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-17.0.3.tgz#5232783e70577217b6b17d2a1c1766637a1d2fbd"
|
||||
jest-haste-map@18.0.0:
|
||||
version "18.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-18.0.0.tgz#707d3b5ae3bcbda971c39e8b911d20ad8502c748"
|
||||
dependencies:
|
||||
fb-watchman "^1.9.0"
|
||||
graceful-fs "^4.1.6"
|
||||
@@ -3881,27 +3875,27 @@ react-native-vector-icons@^3.0.0:
|
||||
lodash "^4.0.0"
|
||||
yargs "^6.3.0"
|
||||
|
||||
react-native@^0.40.0:
|
||||
version "0.40.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.40.0.tgz#ca7b86a8e8fbc7653634ad47ca2ffd69fdf18ad5"
|
||||
react-native@^0.41.2:
|
||||
version "0.41.2"
|
||||
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.41.2.tgz#c6f486b8450a9909e6fed2dfd2c2af946563bf4f"
|
||||
dependencies:
|
||||
absolute-path "^0.0.0"
|
||||
art "^0.10.0"
|
||||
async "^2.0.1"
|
||||
babel-core "^6.18.2"
|
||||
babel-generator "^6.19.0"
|
||||
babel-core "^6.21.0"
|
||||
babel-generator "^6.21.0"
|
||||
babel-plugin-external-helpers "^6.18.0"
|
||||
babel-plugin-syntax-trailing-function-commas "^6.13.0"
|
||||
babel-plugin-transform-flow-strip-types "^6.18.0"
|
||||
babel-plugin-transform-object-rest-spread "^6.19.0"
|
||||
babel-polyfill "^6.16.0"
|
||||
babel-plugin-syntax-trailing-function-commas "^6.20.0"
|
||||
babel-plugin-transform-flow-strip-types "^6.21.0"
|
||||
babel-plugin-transform-object-rest-spread "^6.20.2"
|
||||
babel-polyfill "^6.20.0"
|
||||
babel-preset-es2015-node "^6.1.1"
|
||||
babel-preset-fbjs "^2.1.0"
|
||||
babel-preset-react-native "^1.9.0"
|
||||
babel-preset-react-native "^1.9.1"
|
||||
babel-register "^6.18.0"
|
||||
babel-runtime "^6.18.0"
|
||||
babel-traverse "^6.19.0"
|
||||
babel-types "^6.19.0"
|
||||
babel-runtime "^6.20.0"
|
||||
babel-traverse "^6.21.0"
|
||||
babel-types "^6.21.0"
|
||||
babylon "^6.14.1"
|
||||
base64-js "^1.1.2"
|
||||
bser "^1.0.2"
|
||||
@@ -3921,7 +3915,7 @@ react-native@^0.40.0:
|
||||
immutable "~3.7.6"
|
||||
imurmurhash "^0.1.4"
|
||||
inquirer "^0.12.0"
|
||||
jest-haste-map "17.0.3"
|
||||
jest-haste-map "18.0.0"
|
||||
joi "^6.6.1"
|
||||
json-stable-stringify "^1.0.1"
|
||||
json5 "^0.4.0"
|
||||
@@ -3936,7 +3930,6 @@ react-native@^0.40.0:
|
||||
opn "^3.0.2"
|
||||
optimist "^0.6.1"
|
||||
plist "^1.2.0"
|
||||
progress "^1.1.8"
|
||||
promise "^7.1.1"
|
||||
react-clone-referenced-element "^1.0.1"
|
||||
react-timer-mixin "^0.13.2"
|
||||
|
||||
Reference in New Issue
Block a user