Add withFlattenedRoutes HOC

This commit is contained in:
Kimmo Puputti 2017-02-16 11:36:33 +02:00
parent 4020c36215
commit f1772cc532
3 changed files with 61 additions and 0 deletions

View file

@ -0,0 +1,7 @@
exports[`withFlattenedRoutes should inject the provided routes 1`] = `<withFlattenedRoutes(CompComp) />`;
exports[`withFlattenedRoutes should inject the provided routes 2`] = `
<div>
SomePage
</div>
`;

View file

@ -1,7 +1,9 @@
import React, { PropTypes } from 'react';
import { find } from 'lodash';
import { matchPath } from 'react-router-dom';
import pathToRegexp from 'path-to-regexp';
import routesConfiguration from '../routesConfiguration';
import * as propTypes from './propTypes';
export const flattenRoutes = routesArray =>
routesArray.reduce((a, b) => a.concat(b.routes ? [b].concat(flattenRoutes(b.routes)) : b), []);
@ -69,3 +71,27 @@ const matchPathnameCreator = routes =>
* matchRoutesToLocation helps to figure out which routes are related to given location.
*/
export const matchPathname = matchPathnameCreator(routesConfiguration);
/**
* A higher order component (HOC) to take the flattened routes from
* the context that the RoutesProvider component has provided.
*
* Injects the routes as the `flattenedRoutes` prop in the given
* component. Works similarly as `withRouter` in React Router.
*/
export const withFlattenedRoutes = Component => {
const WithFlattenedRoutesComponent = (props, context) => (
<Component flattenedRoutes={context.flattenedRoutes} {...props} />
);
WithFlattenedRoutesComponent.displayName = `withFlattenedRoutes(${Component.displayName ||
Component.name})`;
const { arrayOf } = PropTypes;
WithFlattenedRoutesComponent.contextTypes = {
flattenedRoutes: arrayOf(propTypes.route).isRequired,
};
return WithFlattenedRoutesComponent;
};

28
src/util/routes.test.js Normal file
View file

@ -0,0 +1,28 @@
import React, { PropTypes } from 'react';
import { RoutesProvider } from '../components';
import { renderDeep, renderShallow } from './test-helpers';
import * as propTypes from './propTypes';
import { withFlattenedRoutes } from './routes';
const { arrayOf } = PropTypes;
describe('withFlattenedRoutes', () => {
it('should inject the provided routes', () => {
const CompComp = props => <div>{props.flattenedRoutes[0].name}</div>;
CompComp.propTypes = { flattenedRoutes: arrayOf(propTypes.route).isRequired };
const Comp = withFlattenedRoutes(CompComp);
const routes = [{ name: 'SomePage', path: 'some-page', component: () => null }];
const shallowTree = renderShallow(
<RoutesProvider flattenedRoutes={routes}>
<Comp />
</RoutesProvider>,
);
expect(shallowTree).toMatchSnapshot();
const deepTree = renderDeep(
<RoutesProvider flattenedRoutes={routes}>
<Comp />
</RoutesProvider>,
);
expect(deepTree).toMatchSnapshot();
});
});