From 99e3f7727cac2b3efe953f2f47c75db43c010fec Mon Sep 17 00:00:00 2001 From: Jimmy Jia Date: Wed, 26 Oct 2016 14:32:52 -0400 Subject: [PATCH] Add JSX configuration support --- examples/basic-jsx/README.md | 1 + examples/basic-jsx/package.json | 16 +++++ examples/basic-jsx/public/index.html | 14 ++++ examples/basic-jsx/src/index.js | 101 +++++++++++++++++++++++++++ package.json | 1 + src/jsx/Redirect.js | 18 +++++ src/jsx/Route.js | 16 +++++ src/jsx/makeRouteConfig.js | 15 ++++ 8 files changed, 182 insertions(+) create mode 100644 examples/basic-jsx/README.md create mode 100644 examples/basic-jsx/package.json create mode 100644 examples/basic-jsx/public/index.html create mode 100644 examples/basic-jsx/src/index.js create mode 100644 src/jsx/Redirect.js create mode 100644 src/jsx/Route.js create mode 100644 src/jsx/makeRouteConfig.js diff --git a/examples/basic-jsx/README.md b/examples/basic-jsx/README.md new file mode 100644 index 00000000..aeb716ba --- /dev/null +++ b/examples/basic-jsx/README.md @@ -0,0 +1 @@ +# Found Basic JSX Example diff --git a/examples/basic-jsx/package.json b/examples/basic-jsx/package.json new file mode 100644 index 00000000..23849c36 --- /dev/null +++ b/examples/basic-jsx/package.json @@ -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" + } +} diff --git a/examples/basic-jsx/public/index.html b/examples/basic-jsx/public/index.html new file mode 100644 index 00000000..066a7935 --- /dev/null +++ b/examples/basic-jsx/public/index.html @@ -0,0 +1,14 @@ + + + + + + + Found Basic JSX Example + + + +
+ + + diff --git a/examples/basic-jsx/src/index.js b/examples/basic-jsx/src/index.js new file mode 100644 index 00000000..ba8efc8b --- /dev/null +++ b/examples/basic-jsx/src/index.js @@ -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 ( +
  • + +
  • + ); +} + +const propTypes = { + children: React.PropTypes.node, +}; + +function App({ children }) { + return ( +
    + + + {children} +
    + ); +} + +App.propTypes = propTypes; + +const BrowserRouter = createBrowserRouter({ + routeConfig: makeRouteConfig( + +
    Main
    } + /> +
    Foo
    } + /> + new Promise((resolve) => { + setTimeout(resolve, 1000, ({ data }) =>
    {data}
    ); + })} + getData={() => new Promise((resolve) => { + setTimeout(resolve, 1000, 'Bar'); + })} + render={({ Component, props }) => ( + Component && props ? ( + + ) : ( +
    Loading…
    + ) + )} + /> + +
    + ), +}); + +ReactDOM.render( + ( +
    + {error.status === 404 ? 'Not found' : 'Error'} +
    + )} + />, + document.getElementById('root'), +); diff --git a/package.json b/package.json index 5eb0011b..1fde617b 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/jsx/Redirect.js b/src/jsx/Redirect.js new file mode 100644 index 00000000..54bf80d6 --- /dev/null +++ b/src/jsx/Redirect.js @@ -0,0 +1,18 @@ +import invariant from 'invariant'; + +import RedirectObject from '../Redirect'; + +function createRoute(props) { + return new RedirectObject(props); +} + +function Redirect() { + invariant( + false, + ' is only for configuration and should not be rendered.', + ); +} + +Redirect.createRoute = createRoute; + +export default Redirect; diff --git a/src/jsx/Route.js b/src/jsx/Route.js new file mode 100644 index 00000000..06c345e2 --- /dev/null +++ b/src/jsx/Route.js @@ -0,0 +1,16 @@ +import invariant from 'invariant'; + +function createRoute(props) { + return props; +} + +function Route() { + invariant( + false, + ' is only for configuration and should not be rendered.', + ); +} + +Route.createRoute = createRoute; + +export default Route; diff --git a/src/jsx/makeRouteConfig.js b/src/jsx/makeRouteConfig.js new file mode 100644 index 00000000..f34b6683 --- /dev/null +++ b/src/jsx/makeRouteConfig.js @@ -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; + }); +}