Skip to content

Commit

Permalink
Add JSX configuration support
Browse files Browse the repository at this point in the history
  • Loading branch information
taion committed Oct 26, 2016
1 parent 82ce750 commit 99e3f77
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 0 deletions.
1 change: 1 addition & 0 deletions examples/basic-jsx/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Found Basic JSX Example
16 changes: 16 additions & 0 deletions examples/basic-jsx/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "basic-jsx",
"version": "0.1.0",
"private": true,
"devDependencies": {
"react-scripts": "0.7.0"
},
"dependencies": {
"found": "../..",
"react": "^15.3.2",
"react-dom": "^15.3.2"
},
"scripts": {
"start": "react-scripts start"
}
}
14 changes: 14 additions & 0 deletions examples/basic-jsx/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Found Basic JSX Example</title>
</head>

<body>
<div id="root"></div>
</body>

</html>
101 changes: 101 additions & 0 deletions examples/basic-jsx/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import createBrowserRouter from 'found/lib/createBrowserRouter';
import Link from 'found/lib/Link';
import makeRouteConfig from 'found/lib/jsx/makeRouteConfig';
import Redirect from 'found/lib/jsx/Redirect';
import Route from 'found/lib/jsx/Route';
import React from 'react';
import ReactDOM from 'react-dom';

function LinkItem(props) {
// TODO: Remove the pragma once evcohen/eslint-plugin-jsx-a11y#81 lands.
return (
<li>
<Link // eslint-disable-line jsx-a11y/anchor-has-content
{...props}
activeStyle={{ fontWeight: 'bold' }}
/>
</li>
);
}

const propTypes = {
children: React.PropTypes.node,
};

function App({ children }) {
return (
<div>
<ul>
<LinkItem to="/">
Main
</LinkItem>
<ul>
<LinkItem to="/foo">
Foo
</LinkItem>
<LinkItem to="/bar">
Bar (async)
</LinkItem>
<LinkItem to="/baz">
Baz (redirects to Foo)
</LinkItem>
<LinkItem to="/qux">
Qux (missing)
</LinkItem>
</ul>
</ul>

{children}
</div>
);
}

App.propTypes = propTypes;

const BrowserRouter = createBrowserRouter({
routeConfig: makeRouteConfig(
<Route
path="/"
Component={App}
>
<Route
Component={() => <div>Main</div>}
/>
<Route
path="foo"
Component={() => <div>Foo</div>}
/>
<Route
path="bar"
getComponent={() => new Promise((resolve) => {
setTimeout(resolve, 1000, ({ data }) => <div>{data}</div>);
})}
getData={() => new Promise((resolve) => {
setTimeout(resolve, 1000, 'Bar');
})}
render={({ Component, props }) => (
Component && props ? (
<Component {...props} />
) : (
<div><small>Loading&hellip;</small></div>
)
)}
/>
<Redirect
from="baz"
to="/foo"
/>
</Route>
),
});

ReactDOM.render(
<BrowserRouter
renderError={error => (
<div>
{error.status === 404 ? 'Not found' : 'Error'}
</div>
)}
/>,
document.getElementById('root'),
);
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"dependencies": {
"babel-runtime": "^6.18.0",
"farce": "^0.0.2",
"invariant": "^2.2.1",
"is-promise": "^2.1.0",
"lodash": "^4.16.4",
"path-to-regexp": "^1.6.0",
Expand Down
18 changes: 18 additions & 0 deletions src/jsx/Redirect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import invariant from 'invariant';

import RedirectObject from '../Redirect';

function createRoute(props) {
return new RedirectObject(props);
}

function Redirect() {
invariant(
false,
'<Redirect> is only for configuration and should not be rendered.',
);
}

Redirect.createRoute = createRoute;

export default Redirect;
16 changes: 16 additions & 0 deletions src/jsx/Route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import invariant from 'invariant';

function createRoute(props) {
return props;
}

function Route() {
invariant(
false,
'<Route> is only for configuration and should not be rendered.',
);
}

Route.createRoute = createRoute;

export default Route;
15 changes: 15 additions & 0 deletions src/jsx/makeRouteConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';

export default function makeRouteConfig(node) {
return React.Children.toArray(node)
.filter(React.isValidElement)
.map(({ type, props: { children, ...props } }) => {
const route = type.createRoute(props);

if (children) {
route.children = makeRouteConfig(children);
}

return route;
});
}

0 comments on commit 99e3f77

Please sign in to comment.