1.0.2 • Published 4 years ago

minichoo v1.0.2

Weekly downloads
1
License
MIT
Repository
github
Last release
4 years ago

minichoo

a smaller (10KB bundle), standalone version of choo without using any virtual DOM

assumptions

this library assumes there is a div with an id of "app" to mount the app too. this library assumes the browser is modern but should work ok with babel-polyfill

idea

  • when you want choo but smaller and without node api or babel polyfill
  • live off the land: use template strings directly and completely avoid the virtual DOM
  • make it attach to the window like jquery suitable for a small script tag dependency
  • no need to bundle or build

todo:

  • add examples for using forms
  • finish documentation
  • allow mount to attach to any DOM element
  • scrutinize use of innerHTML and template strings for security issues!
  • security review and audit
  • create version using commonjs modules suitable for browserify

include in a html page

<link rel="stylesheet" href="https://unpkg.com/tachyons/css/tachyons.min.css">
<script src="https://unpkg.com/minichoo@1.0.1/minichoo.min.js"></script>

<div id="app"></div>

example

var app = minichoo()

app.use(function (state, emitter) {
  state.demo = 1;
})

app.route('/', function (state, emitter) {
  state.ready(() => {
    console.log('dom is ready')
  })
  window.increment = function () {
    state.demo++; // this does not re-render the page automatically
    // this is a cheap trick to re-render the page
    window.location = '#/'
  }
  return `
  <article class="vh-100 dt w-100 bg-dark-pink">
    <div class="dtc v-mid tc white ph3 ph4-l">
      <h1 class="f6 f2-m f-subheadline-l fw6 tc">minichoo :: demo: ${state.demo}</h1>
      <a href="#!" class="f6 link dim br1 ba bw2 ph3 pv2 mb2 dib navy" onclick="window.increment()">increment</a>
      <a class="f6 link dim br1 ba bw2 ph3 pv2 mb2 dib navy" href="#/page2">go to page 2</a>
    </div>
  </article>
  `
})

app.route('/page2', function () {
  return `<article class="vh-100 dt w-100 bg-dark-pink">
    <div class="dtc v-mid tc white ph3 ph4-l">
      <h1 class="f6 f2-m f-subheadline-l fw6 tc">minichoo :: page 2</h1>
      <a class="f6 link dim br1 ba bw2 ph3 pv2 mb2 dib navy" href="#/">go home</a>
    </div>
  </article>`
})

app.mount()

minichoo

this is the minichoo source code without deps: (nanorouter and nanobus)...

// minichoo
//
function minichoo () {
  if (! (this instanceof minichoo)) return new minichoo ()
  this.middleware = []
  this.routes = {}
  this.state = {}
  this.params = {}
  var self = this
  this.emitter = Nanobus()
  this.router = Nanorouter()
  setTimeout(() => {
    this.app = document.getElementById("app")
  })
  window.onhashchange = function() {
    var current_route = location.hash.replace(/\#/g, '') || '/#';
    // <a href="#!" will be ignored...
    if (!current_route.includes('!')) self.router.emit(current_route)
  }
}

minichoo.prototype._finish_setup = function () {
  var self = this
  Object.keys(self.routes).forEach(function (route) {
    self.router.on(route, function (params) {
      self.state.params = params
      self.app.innerHTML = self.routes[route](self.state, self.emitter)
    })
  })
}

minichoo.prototype.use = function (middleware) {
  assert.ok(typeof middleware === 'function')
  this.middleware.push(middleware)
}

minichoo.prototype.route = function (route, handler) {
  assert.ok(typeof route === 'string')
  assert.ok(typeof handler === 'function')
  this.routes[route] = handler;
}

minichoo.prototype.mount = function (element) {
  var self = this;
  var default_middleware = function (state, emit) {
    state.ready = function (...args) { return setTimeout(...args); }
    state.form = function addForm (id, callback) {
      var form = document.getElementById(id)
      form.addEventListener('submit', function (e) {
        e.preventDefault()
        var data = new FormData(e.currentTarget)
        callback(data, e)
      })
    }
  }
  default_middleware(self.state, self.emitter)
  self.middleware.forEach(function (middleware) {
    middleware(self.state, self.emitter)
  })
  self._finish_setup()
  setTimeout(function () {
    self.app.innerHTML = self.routes[
    Object.keys(self.routes)[0]
    ](self.state, self.emitter)
  }, 1000)
}

window.minichoo = minichoo;

gotchas

  • uses hash based routing so you must do this: <a href="#/some-route" instead of <a href="/some-route"
1.0.2

4 years ago

1.0.1

4 years ago

0.0.1

4 years ago