diff --git a/modules/RouteUtils.js b/modules/RouteUtils.js index bf5f599..c11f939 100644 --- a/modules/RouteUtils.js +++ b/modules/RouteUtils.js @@ -49,39 +49,71 @@ export function createRouteFromReactElement( return _createRouteFromReactElement(element); } +function getPropsFromRoute(route: RouteDef): Object { + const { + childRoutes, + component, + overlayComponent, + path, + routeType, + transition, + reducer, + indexRoute, + ...rest, + } = route; + return rest; +} + function createNavigationTreeAtIndex( createElement: ElementProvider, routes: Array, route: RouteDef, positionInParent: number ): ?PseudoElement { - const props = {}; + const { + childRoutes, + component, + overlayComponent, + path, + routeType, + indexRoute, + } = route; + + const props = { + ...getPropsFromRoute(route), + route, + routes, + }; props.createElement = createElement; - props.path = route.path || `[visual]${positionInParent}`; - props.type = route.routeType; - props.component = route.component; + props.path = path || `[visual]${positionInParent}`; + props.type = routeType; + props.component = component; - if (route.overlayComponent) { - props.overlayComponent = route.overlayComponent; + if (overlayComponent) { + props.overlayComponent = overlayComponent; } - if (route.childRoutes) { - props.navigationSubtree = route.childRoutes.map( + if (childRoutes) { + props.navigationSubtree = childRoutes.map( (r, index) => createNavigationTreeAtIndex(createElement, routes, r, index) ); // index route is given in `routes` but not in `childRoutes` - if (route.indexRoute) { - const indexRouteProps = {}; + if (indexRoute) { + const indexRouteProps = { + ...getPropsFromRoute(indexRoute), + route: indexRoute, + routes, + }; indexRouteProps.path = '[index]'; indexRouteProps.type = 'index'; - indexRouteProps.component = route.indexRoute.component; + indexRouteProps.component = indexRoute.component; indexRouteProps.createElement = createElement; - if (route.indexRoute.overlayComponent) { - indexRouteProps.overlayComponent = route.indexRoute.overlayComponent; + if (indexRoute.overlayComponent) { + indexRouteProps.overlayComponent = indexRoute.overlayComponent; } const indexRoutePseudoElement = { @@ -94,13 +126,14 @@ function createNavigationTreeAtIndex( } let pseudoElement; - if (route.routeType === STACK_ROUTE) { + if (routeType === STACK_ROUTE) { pseudoElement = { routeViewComponent: StackRouteView, props }; - } else if (route.routeType === TABS_ROUTE) { + } else if (routeType === TABS_ROUTE) { pseudoElement = { routeViewComponent: TabsRouteView, props }; } else { pseudoElement = { routeViewComponent: RouteView, props }; } + return pseudoElement; } @@ -109,7 +142,6 @@ export function createNavigationTree( routes: Array ): ?PseudoElement { const rootRoute = routes && routes.length && routes[0]; - if (!rootRoute) { return null; } diff --git a/modules/RouteView.js b/modules/RouteView.js index 4216502..c3eb825 100644 --- a/modules/RouteView.js +++ b/modules/RouteView.js @@ -72,6 +72,21 @@ class RouteView extends Component { ); } + getComponentProps(props: Object): Object { + const { + path, + type, + component, + overlayComponent, + navigationSubtree, + navigationState, + createElement, + onNavigate, + ...rest, + } = props; + return rest; + } + renderTransition(props: NavigationTransitionProps): ReactElement { const scenes = props.scenes.map( scene => this.renderScene({ @@ -119,6 +134,7 @@ class RouteView extends Component { } const componentProps = { + ...this.getComponentProps(this.props), params, routeParams, location, diff --git a/modules/RouterContext.js b/modules/RouterContext.js index 7c4210c..041861a 100644 --- a/modules/RouterContext.js +++ b/modules/RouterContext.js @@ -88,6 +88,8 @@ class RouterContext extends Component { navigationTree, navigationState, location, + route: {}, // TODO + routes: this.props.routes, }; element = React.createElement(RootContainer, passProps); diff --git a/modules/StackRouteView.js b/modules/StackRouteView.js index a30c5b2..e50ab43 100644 --- a/modules/StackRouteView.js +++ b/modules/StackRouteView.js @@ -68,6 +68,7 @@ class StackRouteView extends Component { const { location, params, routeParams } = scene.route; const overlayComponentProps = { + ...this.getComponentProps(navigationalElement.props), ...props, location, params, @@ -140,6 +141,21 @@ class StackRouteView extends Component { ); } + getComponentProps(props: Object): Object { + const { + path, + type, + component, + overlayComponent, + navigationSubtree, + navigationState, + createElement, + onNavigate, + ...rest, + } = props; + return rest; + } + renderTransition(props: NavigationTransitionProps): ReactElement { const overlay = this.renderOverlay({ ...props, @@ -203,6 +219,7 @@ class StackRouteView extends Component { } const componentProps = { + ...this.getComponentProps(this.props), params, routeParams, location, diff --git a/modules/TabsRouteView.js b/modules/TabsRouteView.js index ae24051..9f18df6 100644 --- a/modules/TabsRouteView.js +++ b/modules/TabsRouteView.js @@ -66,8 +66,8 @@ class TabsRouteView extends Component { const overlayComponent = navigationalElement.props.overlayComponent; if (overlayComponent) { const { location, params, routeParams } = scene.route; - const overlayComponentProps = { + ...this.getComponentProps(navigationalElement.props), ...props, location, params, @@ -140,6 +140,21 @@ class TabsRouteView extends Component { ); } + getComponentProps(props: Object): Object { + const { + path, + type, + component, + overlayComponent, + navigationSubtree, + navigationState, + createElement, + onNavigate, + ...rest, + } = props; + return rest; + } + renderTransition(props: NavigationTransitionProps): ReactElement { const overlay = this.renderOverlay({ ...props, @@ -203,6 +218,7 @@ class TabsRouteView extends Component { } const componentProps = { + ...this.getComponentProps(this.props), params, routeParams, location, diff --git a/modules/TypeDefinition.js b/modules/TypeDefinition.js index 7d59a7c..0586fb4 100644 --- a/modules/TypeDefinition.js +++ b/modules/TypeDefinition.js @@ -41,6 +41,7 @@ export type RouteDef = { routeType: ?RouteType, transition: ?string, reducer: Function, + indexRoute: ?Object, }; export type IndexRouteDef = { diff --git a/modules/applyRouterMiddleware.js b/modules/applyRouterMiddleware.js new file mode 100644 index 0000000..bd21650 --- /dev/null +++ b/modules/applyRouterMiddleware.js @@ -0,0 +1,37 @@ +/** + * This file is subject to the terms and conditions defined in the LICENSE file + * which is found in the in the root directory of React Router source tree. + * + * https://github.com/reactjs/react-router/blob/master/LICENSE.md + */ + +import React, { createElement } from 'react'; +import RouterContext from './RouterContext'; + +export default (...middlewares) => { + const withContext = middlewares.map(m => m.renderRouterContext).filter(f => f); + const withComponent = middlewares.map(m => m.renderRouteComponent).filter(f => f); + const makeCreateElement = (baseCreateElement = createElement) => ( + (Component, props) => ( + withComponent.reduceRight( + (previous, renderRouteComponent) => ( + renderRouteComponent(previous, props) + ), baseCreateElement(Component, props) + ) + ) + ); + + return (renderProps) => ( + withContext.reduceRight( + (previous, renderRouterContext) => ( + renderRouterContext(previous, renderProps) + ), ( + + ) + ) + ); +}; + diff --git a/modules/index.js b/modules/index.js index c23bc2e..d19ddf2 100644 --- a/modules/index.js +++ b/modules/index.js @@ -21,8 +21,9 @@ export { IndexRoute, Route, StackRoute, TabsRoute }; import RouterContext from './RouterContext'; import Reducer from './Reducer'; import { render } from './render'; +import applyRouterMiddleware from './applyRouterMiddleware'; -export { RouterContext, Reducer, render }; +export { RouterContext, Reducer, render, applyRouterMiddleware }; /* histories */ import nativeHistory from './nativeHistory';