├── .gitignore
├── History.md
├── Makefile
├── Readme.md
├── example
└── index.js
├── index.js
├── lib
├── bus.js
├── fill.js
├── go.js
├── location.js
├── match.js
└── route.js
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | npm-debug.log
2 | node_modules
3 | .DS_Store
4 | components
5 | build
6 |
--------------------------------------------------------------------------------
/History.md:
--------------------------------------------------------------------------------
1 |
2 | 1.0.3 / 2015-09-24
3 | ==================
4 |
5 | * add react as a peer dependency
6 |
7 | 1.0.2 / 2015-09-18
8 | ==================
9 |
10 | * add: Route.match(path). fix: make example
11 | * add example
12 |
13 | 1.0.1 / 2015-06-08
14 | ==================
15 |
16 | * remove logging
17 |
18 | 1.0.0 / 2015-06-08
19 | ==================
20 |
21 | * Initial commit
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | example:
2 | @PORT=5000 ./node_modules/.bin/roo react example/index.js --live
3 |
4 | .PHONY: example
5 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # react-route
2 |
3 | Simple, tiny router for React.
4 |
5 | ```jsx
6 |
7 |
8 | Index /
9 |
10 |
11 | About me
12 |
13 |
14 |
15 |
16 | Hi amy!
17 |
18 |
19 |
20 | ```
21 |
22 | ## Features
23 |
24 | - Parameter support via `props.params`
25 | - Simple API for navigating pages
26 | - HTML5 History Support
27 | - No wrapping handlers
28 | - Nesting
29 |
30 | ## Installation
31 |
32 | ```js
33 | npm install react-route
34 | ```
35 |
36 | ## API
37 |
38 | ### ``
39 |
40 | Specify an express-style path. For a list of possibilities check out: https://github.com/pillarjs/path-to-regexp
41 |
42 | Any child components will receive a `params` property based on the pathname and keys provided.
43 |
44 | ```js
45 |
46 | Welcome user {this.props.params.user}
47 |
48 | ```
49 |
50 | ### Route.go(path)
51 |
52 | Navigate to `path` and re-render the routes.
53 |
54 | ```js
55 | onclick () {
56 | Route.go('/user/amy');
57 | }
58 | ```
59 |
60 | ## License
61 |
62 | MIT
63 |
--------------------------------------------------------------------------------
/example/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module Dependencies
3 | */
4 |
5 | var React = require('react')
6 | var Route = require('..')
7 |
8 | /**
9 | * Example Component
10 | */
11 |
12 | export default class Example extends React.Component {
13 | constructor (props) {
14 | super(props)
15 | }
16 |
17 | render () {
18 | return (
19 |
20 |
21 | index
22 |
23 |
24 | dashboard
25 |
26 |
27 | )
28 | }
29 | }
30 |
31 | if (typeof window !== 'undefined') {
32 | var component = React.createElement(Example, {})
33 | React.render(component, document.body)
34 | }
35 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Export `react-route`
3 | */
4 |
5 | exports = module.exports = require('./lib/route');
6 | exports.go = require('./lib/go');
7 | exports.match = require('./lib/match');
8 |
--------------------------------------------------------------------------------
/lib/bus.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Export `bus`
3 | */
4 |
5 | module.exports = require('component-emitter')({});
6 |
--------------------------------------------------------------------------------
/lib/fill.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module Dependencies
3 | */
4 |
5 | var Regexp = require('path-to-regexp')
6 | var location = require('./location');
7 |
8 | /**
9 | * Export `match`
10 | */
11 |
12 | module.exports = match;
13 |
14 | /**
15 | * Check if this route matches `path`, if so
16 | * populate `params`.
17 | *
18 | * @param {String} path
19 | * @param {Object} params
20 | * @return {Boolean}
21 | * @api private
22 | */
23 |
24 | function match(path, params, pathname) {
25 | var keys = [];
26 | var regexp = Regexp(path, keys);
27 | var m = regexp.exec(pathname || location.pathname);
28 |
29 | if (!m) return false;
30 | else if (!params) return true;
31 |
32 | for (var i = 1, len = m.length; i < len; ++i) {
33 | var key = keys[i - 1];
34 | var val = 'string' == typeof m[i] ? decodeURIComponent(m[i]) : m[i];
35 | if (key) params[key.name] = val;
36 | }
37 |
38 | return true;
39 | }
40 |
--------------------------------------------------------------------------------
/lib/go.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module Dependencies
3 | */
4 |
5 | var location = require('./location');
6 | var bus = require('./bus');
7 |
8 | /**
9 | * Export `Go`
10 | */
11 |
12 | module.exports = Go;
13 |
14 | /**
15 | * Go
16 | */
17 |
18 | function Go(path, state) {
19 | if (arguments.length) {
20 | window.history.pushState(state, null, path);
21 | bus.emit('pushstate', path);
22 | } else {
23 | var params = {};
24 | var m = match(location.pathname, params);
25 | return m && params;
26 | }
27 | }
28 |
29 | /**
30 | * Setup the "popstate" events
31 | */
32 |
33 | function onpopstate() {
34 | var loaded = false;
35 | if ('undefined' === typeof window) return;
36 | if (document.readyState === 'complete') {
37 | loaded = true;
38 | } else {
39 | window.addEventListener('load', function() {
40 | setTimeout(function() {
41 | loaded = true;
42 | }, 0);
43 | });
44 | }
45 |
46 | return function _onpopstate(e) {
47 | if (!loaded) return;
48 | bus.emit('popstate', location.pathname);
49 | }
50 | }
51 |
52 | /**
53 | * Start listening for the "popstate" event
54 | */
55 |
56 | window.addEventListener('popstate', onpopstate());
57 |
--------------------------------------------------------------------------------
/lib/location.js:
--------------------------------------------------------------------------------
1 | /**
2 | * To work properly with the URL
3 | * history.location generated polyfill in https://github.com/devote/HTML5-History-API
4 | */
5 |
6 | module.exports = ('undefined' !== typeof window) && (window.history.location || window.location);
7 |
--------------------------------------------------------------------------------
/lib/match.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module Dependencies
3 | */
4 |
5 | var fill = require('./fill')
6 |
7 | /**
8 | *
9 | */
10 |
11 | module.exports = match
12 |
13 | /**
14 | * Match against a path
15 | */
16 |
17 | function match (path, location) {
18 | location = location || window.location.pathname
19 | var params = {}
20 | return fill(path, params, location) && params
21 | }
22 |
--------------------------------------------------------------------------------
/lib/route.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Module Dependencies
3 | */
4 |
5 | var assign = require('object-assign');
6 | var fill = require('./fill');
7 | var React = require('react');
8 | var bus = require('./bus');
9 |
10 | /**
11 | * Export `Route`
12 | */
13 |
14 | module.exports = React.createClass({
15 |
16 | displayName: 'Route',
17 |
18 | setInitialState: function () {
19 | return {
20 | pathname: location.pathname
21 | }
22 | },
23 |
24 | componentDidMount: function () {
25 | var self = this;
26 |
27 | bus.on('pushstate', function(pathname) {
28 | self.setState({ pathname: pathname });
29 | })
30 |
31 | bus.on('popstate', function(pathname) {
32 | self.setState({ pathname: pathname });
33 | })
34 | },
35 |
36 | render: function(props) {
37 | var props = this.props;
38 | var path = props.path;
39 | var params = {};
40 |
41 | var m = fill(path, params);
42 | if (!m) return null;
43 |
44 | var children = React.Children.map(this.props.children, function(child) {
45 | return child.type
46 | ? React.cloneElement(child, assign({ params: params }, child.props))
47 | : React.createElement('span', {}, child);
48 | })
49 |
50 | return React.createElement('div', { className: 'Route'}, children);
51 | }
52 | });
53 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-route",
3 | "version": "1.0.3",
4 | "description": "tiny react router thats less opinionated than react-router",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "make test"
8 | },
9 | "keywords": [
10 | "react",
11 | "router",
12 | "tiny",
13 | "mini",
14 | "small"
15 | ],
16 | "author": "Matthew Mueller",
17 | "license": "MIT",
18 | "dependencies": {
19 | "component-emitter": "^1.2.0",
20 | "object-assign": "^3.0.0",
21 | "path-to-regexp": "^1.2.0"
22 | },
23 | "devDependencies": {
24 | "roo": "^0.4.5"
25 | },
26 | "peerDependencies": {
27 | "react": "^0.13.3 || ^0.14.0-rc1"
28 | }
29 | }
--------------------------------------------------------------------------------