wrouter

0.0.6 • Public • Published

wrouter

demo

Router state machine for virtual doms. It's a wrapper around single-page and catch-links for easier client side routing. It also works in Node if you pass in a route event.

install

$ npm install wrouter

example

Node:

var Router = require('wrouter');
var struct = require('observ-struct');
var value = require('observ');
var assert = require('assert');
 
var routeEvent = value('');
 
var routerState = Router({
  routeHash: {
    '/animals/:id': {
      component: {
        state: struct({ example: 'my data' }),
        render: function renderMyComponent(state) {
          assert(state.example === 'my data');
        }
      },
      // do anything that needs to happen before component.render is called
      routeFn: function(params, done) {
        console.log(params);
        done();
      }
    }
  },
  // pass in an event implemented like `observ`. If this is omitted the
  // router will listen for click events on document.body
  // (via `catch-links`)
  event: routeEvent
});
 
routerState(function onChange(state) {
  var view = Router.route(state);
  // {
  //    state: { example: 'my data' },
  //    render: renderMyComponent
  // }
  view.render(view.state);
});
 
 
routeEvent.set('/animals/3');   // { id: '3' }
try {
  routeEvent.set('no-match');
}
catch(err) {
  console.log(err);
  // [Error: router: no match found]
}
 

Browser:

var Loop = require('main-loop');
var vdom = require('virtual-dom');
var h = vdom.h;
var struct = require('observ-struct');
var value = require('observ');
var noop = function(){};
 
var Router = require('../Router.js');
var components = require('./components');
 
var animalItemEvent = struct({});
 
function fetchAnimal(id, cb) {
  setTimeout(function () {
    cb({
      id: id,
      _name: 'iguana',
      type: 'reptile'
    });
  }, 500);
}
 
var app = App();
var loop = Loop( app(), renderApp, vdom);
document.getElementById('content').appendChild(loop.target);
app(loop.update);
 
// root component
function App() {
 
  var routeHash = {
    '/': {
      component: {
        state: components.Home({home: 'home state'}),
        render: components.Home.render
      }
    },
    '/animals': {
      component: {
        state: components.Animals(),
        render: components.Animals.render
      }
    },
    '/animals/:id': {
      component: {
        state: components.AnimalItem({
          event: animalItemEvent
        }),
        render: components.AnimalItem.render
      },
 
      // do anything that needs to be done before the view is rendered
      routeFn: function(params, done) {
        if ( !state.loading() ) state.loading.set(true);
        fetchAnimal(params.id, function(animal) {
          if (state.loading) state.loading.set(false);
          animalItemEvent.set(animal);
          done();
        });
      }
    }
  };
 
  var state = struct({
    loading: value(false),
    router: Router({
      routeHash: routeHash
    })
  });
 
  return state;
}
 
function renderApp(state) {
  var page = Router.route(state.router);
  return h('div', {
    style: { }
  }, [
    h('div', {style: {
      width: '50%',
      display: 'inline-block'
    }}, [
      menu(),
      page ? page.render(page.state) : '',
    ]),
    h('div.loading', {
      style: {
        width: '30%',
        display: state.loading ? 'inline-block' : 'none',
        textAlign: 'center',
        fontSize: '2em',
      }
    }, ['loading'])
  ]);
 
  function menu() {
    return h('ul', [
      h('li', [
        h('a', {
          href: '/'
        }, 'Home')
      ]),
      h('li', [
        h('a', {
          href: '/animals'
        }, 'Animals')
      ]),
      h('li', [
        h('a', {
          href: '/animals/1'
        }, 'Animal Item')
      ])
    ]);
  }
}

Package Sidebar

Install

npm i wrouter

Weekly Downloads

0

Version

0.0.6

License

ISC

Last publish

Collaborators

  • nichoth