Skip to content

Commit

Permalink
[added] IndexRoute
Browse files Browse the repository at this point in the history
  • Loading branch information
mjackson committed Aug 28, 2015
1 parent 2f0b8bf commit adc0a2f
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 8 deletions.
46 changes: 46 additions & 0 deletions modules/IndexRoute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from 'react';
import invariant from 'invariant';
import { createRouteFromReactElement } from './RouteUtils';
import { component, components, falsy } from './PropTypes';

var { bool, func } = React.PropTypes;

/**
* An <IndexRoute> is used to specify its parent's <Route indexRoute> in
* a JSX route config.
*/
var IndexRoute = React.createClass({

statics: {

createRouteFromReactElement(element, parentRoute) {
if (parentRoute) {
parentRoute.indexRoute = createRouteFromReactElement(element);
} else {
warning(
false,
'An <IndexRoute> does not make sense at the root of your route config'
);
}
}

},

propTypes: {
path: falsy,
ignoreScrollBehavior: bool,
component,
components,
getComponents: func
},

render() {
invariant(
false,
'<IndexRoute> elements are for router configuration only and should not be rendered'
);
}

});

export default IndexRoute;
19 changes: 15 additions & 4 deletions modules/RouteUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,23 @@ function checkPropTypes(componentName, propTypes, props) {
}
}

function createRoute(defaultProps, props) {
return { ...defaultProps, ...props };
}

export function createRouteFromReactElement(element) {
var type = element.type;
var route = Object.assign({}, type.defaultProps, element.props);
var route = createRoute(type.defaultProps, element.props);

if (type.propTypes)
checkPropTypes(type.displayName || type.name, type.propTypes, route);

if (route.children) {
route.childRoutes = createRoutesFromReactChildren(route.children);
var childRoutes = createRoutesFromReactChildren(route.children, route);

if (childRoutes.length)
route.childRoutes = childRoutes;

delete route.children;
}

Expand All @@ -54,14 +62,17 @@ export function createRouteFromReactElement(element) {
* Note: This method is automatically used when you provide <Route> children
* to a <Router> component.
*/
export function createRoutesFromReactChildren(children) {
export function createRoutesFromReactChildren(children, parentRoute) {
var routes = [];

React.Children.forEach(children, function (element) {
if (React.isValidElement(element)) {
// Component classes may have a static create* method.
if (element.type.createRouteFromReactElement) {
routes.push(element.type.createRouteFromReactElement(element));
var route = element.type.createRouteFromReactElement(element, parentRoute);

if (route)
routes.push(route);
} else {
routes.push(createRouteFromReactElement(element));
}
Expand Down
27 changes: 23 additions & 4 deletions modules/__tests__/createRoutesFromReactChildren-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import expect from 'expect';
import React from 'react';
import { createRoutesFromReactChildren } from '../RouteUtils';
import IndexRoute from '../IndexRoute';
import Route from '../Route';

describe('createRoutesFromReactChildren', function () {
Expand Down Expand Up @@ -28,10 +29,28 @@ describe('createRoutesFromReactChildren', function () {
}
});

it('works with index routes', function () {
var routes = createRoutesFromReactChildren(
<Route path="/" component={Parent}>
<IndexRoute component={Hello} />
</Route>
);

expect(routes).toEqual([
{
path: '/',
component: Parent,
indexRoute: {
component: Hello
}
}
]);
});

it('works with nested routes', function () {
var routes = createRoutesFromReactChildren(
<Route component={Parent}>
<Route path="home" components={{ hello: Hello, goodbye: Goodbye }}/>
<Route path="home" components={{ hello: Hello, goodbye: Goodbye }} />
</Route>
);

Expand All @@ -50,9 +69,9 @@ describe('createRoutesFromReactChildren', function () {

it('works with falsy children', function () {
var routes = createRoutesFromReactChildren([
<Route path="/one" component={Parent}/>,
<Route path="/one" component={Parent} />,
null,
<Route path="/two" component={Parent}/>,
<Route path="/two" component={Parent} />,
undefined
]);

Expand All @@ -71,7 +90,7 @@ describe('createRoutesFromReactChildren', function () {
var routes = createRoutesFromReactChildren(
<Route path="/one" component={Parent}>
// This is a comment.
<Route path="/two" component={Hello}/>
<Route path="/two" component={Hello} />
</Route>
);

Expand Down
1 change: 1 addition & 0 deletions modules/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export Router from './Router';
export Link from './Link';

/* components (configuration) */
export IndexRoute from './IndexRoute';
export Redirect from './Redirect';
export Route from './Route';

Expand Down

0 comments on commit adc0a2f

Please sign in to comment.