Skip to content

Commit

Permalink
support React
Browse files Browse the repository at this point in the history
  • Loading branch information
k1r0s committed Mar 14, 2018
1 parent 5415b6d commit dcb055e
Show file tree
Hide file tree
Showing 9 changed files with 511 additions and 44 deletions.
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
### Preact Routlet

This package contains routing functionalities for [preact](https://github.com/developit/preact) applications. Instead of using HTML5 history API it uses the oldie `/#/what-ever` hash routing (this will change in the future).
This package contains routing functionalities for [preact](https://github.com/developit/preact) and, now from 0.3.0 `React` applications as well. Instead of using HTML5 history API it uses the oldie `/#/what-ever` hash routing (this will change in the future).

This project was created by exploring contextual ways to define routes rather than placing all the routes in a single file.

##### Usage:

Available imports:

```javascript
// if you're using React
import { renderOnRoute, navigate, RouterOutlet, PathLookup, routePool, Link } from "preact-routlet/react"
// if you're using Preact
import { renderOnRoute, navigate, RouterOutlet, PathLookup, routePool, Link } from "preact-routlet/preact"
```

Either `from "preact-routlet/preact"` or `from "preact-routlet/react"`

Place your RouterOutlet element somewhere in your JSX:
```html
<div>
Expand Down Expand Up @@ -85,7 +96,6 @@ So basically you're registering all the components that listen to route changes

- Navigation (code)
```javascript
import { navigate } from "preact-routlet";
...
navigate("/somewhere");
```
Expand Down
12 changes: 9 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"version": "0.2.1",
"description": "simple preact hash routing",
"scripts": {
"build": "rollup -c rollup.config.js"
"build": "npm run build:react ; npm run build:preact",
"build:react": "rollup -c rollup.config.react.js",
"build:preact": "rollup -c rollup.config.preact.js"
},
"main": "routlet.js",
"keywords": [],
Expand All @@ -12,13 +14,17 @@
"devDependencies": {
"babel-core": "^6.26.0",
"babel-plugin-external-helpers": "^6.22.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.6.1",
"rollup": "^0.50.0",
"rollup-plugin-babel": "^3.0.2"
},
"dependencies": {
"path-parser": "^2.0.2",
"preact": "^8.2.6"
"path-parser": "^2.0.2"
},
"peerDependencies": {
"preact": "^8.2.6",
"react": "^16.0.0"
}
}
11 changes: 6 additions & 5 deletions index.js → preact.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@ export const navigate = newUrl => location.hash = "#" + newUrl;

export class PathLookup extends Component {

state = {
params: null,
path: location.hash ? transformHash(location.hash): "/",
current: null
}

componentWillMount() {
gotoDefault();
this.setState({
params: null,
path: location.hash ? transformHash(location.hash): "/",
current: null
});
this.hashChange(this.state.path);
}

Expand Down
60 changes: 34 additions & 26 deletions routlet.js → preact.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('preact'), require('path-parser')) :
typeof define === 'function' && define.amd ? define(['exports', 'preact', 'path-parser'], factory) :
(factory((global.routlet = {}),global.preact,global.Path));
(factory((global.routletPreact = {}),global.preact,global.Path));
}(this, (function (exports,preact,Path) { 'use strict';

Path = Path && Path.hasOwnProperty('default') ? Path['default'] : Path;
Expand Down Expand Up @@ -246,28 +246,36 @@ var PathLookup = function (_Component) {
inherits(PathLookup, _Component);

function PathLookup() {
var _ref;

var _temp, _this, _ret;

classCallCheck(this, PathLookup);
return possibleConstructorReturn(this, (PathLookup.__proto__ || Object.getPrototypeOf(PathLookup)).apply(this, arguments));

for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}

return _ret = (_temp = (_this = babelHelpers.possibleConstructorReturn(this, (_ref = PathLookup.__proto__ || Object.getPrototypeOf(PathLookup)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
params: null,
path: location.hash ? transformHash(location.hash) : "/",
current: null
}, _temp), babelHelpers.possibleConstructorReturn(_this, _ret);
}

createClass(PathLookup, [{
key: "componentWillMount",
value: function componentWillMount() {
gotoDefault();
this.setState({
params: null,
path: location.hash ? transformHash(location.hash) : "/",
current: null
});
this.hashChange(this.state.path);
}
}, {
key: "componentDidMount",
value: function componentDidMount() {
var _this2 = this;

window.addEventListener("hashchange", function (_ref) {
var newURL = _ref.newURL;
window.addEventListener("hashchange", function (_ref2) {
var newURL = _ref2.newURL;
return _this2.hashChange(transformHash(newURL || location.hash));
});
}
Expand All @@ -278,10 +286,10 @@ var PathLookup = function (_Component) {
}
}, {
key: "render",
value: function render(_ref2, _ref3) {
var shouldRender = _ref2.shouldRender,
children = _ref2.children;
var path = _ref3.path;
value: function render(_ref3, _ref4) {
var shouldRender = _ref3.shouldRender,
children = _ref3.children;
var path = _ref4.path;

return shouldRender(path) ? children[0] : null;
}
Expand Down Expand Up @@ -311,16 +319,16 @@ var RouterOutlet = function (_PathLookup) {
}
}, {
key: "render",
value: function render(_ref4, _ref5) {
var children = _ref4.children,
_ref4$shouldRedirect = _ref4.shouldRedirect,
shouldRedirect = _ref4$shouldRedirect === undefined ? function (_) {
value: function render(_ref5, _ref6) {
var children = _ref5.children,
_ref5$shouldRedirect = _ref5.shouldRedirect,
shouldRedirect = _ref5$shouldRedirect === undefined ? function (_) {
return false;
} : _ref4$shouldRedirect,
redirect = _ref4.redirect;
var current = _ref5.current,
params = _ref5.params,
path = _ref5.path;
} : _ref5$shouldRedirect,
redirect = _ref5.redirect;
var current = _ref6.current,
params = _ref6.params,
path = _ref6.path;

var result = current ? preact.h(current, { params: params, path: path }) : children[0];

Expand All @@ -335,10 +343,10 @@ var RouterOutlet = function (_PathLookup) {
return RouterOutlet;
}(PathLookup);

var Link = function Link(_ref6) {
var href = _ref6.href,
children = _ref6.children,
props = objectWithoutProperties(_ref6, ["href", "children"]);
var Link = function Link(_ref7) {
var href = _ref7.href,
children = _ref7.children,
props = objectWithoutProperties(_ref7, ["href", "children"]);
return preact.h("a", _extends({ href: "#" + href }, props), children);
};

Expand Down
80 changes: 80 additions & 0 deletions react.dev.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React from "react";
import Path from 'path-parser';

export const routePool = [];

let FIRST_COMPONENT_HAS_MOUNTED = false;
const gotoDefault = _ => {
if(!FIRST_COMPONENT_HAS_MOUNTED) {
if(!location.hash) setTimeout(navigate, 1, "/");
FIRST_COMPONENT_HAS_MOUNTED = true;
}
}

const transformHash = rawHash => rawHash.split("#").pop();

export function renderOnRoute(path) {
return function(comp) {
routePool.push({
path,
parser: new Path(path),
comp,
});
return comp;
}
}

export const navigate = newUrl => location.hash = "#" + newUrl;

export class PathLookup extends React.Component {

state = {
params: null,
path: location.hash ? transformHash(location.hash): "/",
current: null
}

componentWillMount() {
gotoDefault();
this.hashChange(this.state.path);
}

componentDidMount() {
window.addEventListener("hashchange", ({ newURL }) =>
this.hashChange(transformHash(newURL || location.hash)));
}

hashChange(selectedRoute) {
this.setState({ path: selectedRoute });
}

render() {
return this.props.shouldRender(this.state.path) ? this.props.children: null;
}
}

export class RouterOutlet extends PathLookup {

hashChange(selectedRoute) {
const selectedMatcher = routePool.find(matcher => !!matcher.parser.test(selectedRoute));
this.setState({
"params": selectedMatcher ? selectedMatcher.parser.test(selectedRoute): null,
"path": selectedRoute,
"current": selectedMatcher ? selectedMatcher.comp: null
});
}

render() {
const result = this.state.current ? React.createElement(this.state.current, { params: this.state.params, path: this.state.path }): this.props.children;

if(this.props.shouldRedirect && this.props.shouldRedirect(this.state.path) && this.state.current) {
navigate(this.props.redirect);
return null;
}

return result;
}
}

export const Link = ({ href, children, ...props }) =>
React.createElement("a", { href: `#${href}`, ...props }, children);
Loading

0 comments on commit dcb055e

Please sign in to comment.