JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 2
  • Score
    100M100P100Q41839F
  • License ISC

Convenient wrapper around history API designed for use with mercury pattern

Package Exports

  • wrouter

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (wrouter) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

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')
      ])
    ]);
  }
}