Skip to content

Instantly share code, notes, and snippets.

@matthiasak
Last active March 28, 2016 16:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthiasak/8ad279c77a6a05ad16bf to your computer and use it in GitHub Desktop.
Save matthiasak/8ad279c77a6a05ad16bf to your computer and use it in GitHub Desktop.
Copy the following code into https://matthiasak.github.io/arbiter-frame/#// to see it run
const router = (routes, fn=(a,b)=>a(b)) => {
let current = null
const listen = () => {
window.addEventListener('hashchange', () => {
trigger(window.location.hashname.slice(1))
})
}
const trigger = path => {
Object.keys(routes).reduce((a,x) => {
let v = match(x,path)
if(v){
fn(routes[x], v)
return true
}
if(a) return true
}, false)
}
const match = (pattern, path) => {
let parts = pattern.split('/').filter(x => x.length),
names = parts.reduce((a,x) => x[0] === ':' ? [...a, x.slice(1)] : a, []),
v = parts.map(x => x[0] === ':' ? '/([^/]+)' : '/'+x).join(''),
results = RegExp(v).exec(path),
parsed = (results || []).slice(1)
return !results ? false : names.reduce((a,v,i) => ({...a, [v]: parsed[i]}), {})
}
return {
add: (name, fn) => !!(routes[name] = fn),
remove: name => (delete routes[name]) && true,
listen,
match,
trigger
}
}
// use a router inside a custom <Router> Component in React ...
const app = () => {
let [React, DOM] = [react, reactDom],
{Component} = React
class Home extends Component {
constructor(...p){
super(...p)
}
render(){
return <div><h1 style={{color:'white'}}>Home Screen</h1></div>
}
}
class Router extends Component {
constructor(...a){
super(...a)
let p = this.props
this.state = {
routes: p.routes || {},
default: p.default || '/'
}
this.router = router(this.state.routes, (el, props) => {
this.current = el
})
this.router.trigger(this.state.default)
}
render(){
return this.current()
}
}
DOM.render(<Router routes={{
'/': () => <Home/>
}}/>, document.body)
}
require('react', 'react-dom').then(app)
// ... or use router outside of a React Component
let x = router({
'/:x/test/:y' : ({x,y}) => log({x,y}),
'/': () => log('home screen')
})
log(x.match('/:x/test/:y', '/anything/test/anything')) // test a route pattern with a route
x.trigger('/') // trigger the / route
x.trigger('/hi/test/bye') // any named URI segments will be passed to the route callback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment