base-element
An element authoring library for creating standalone and performant elements.
View this example List element in use with:
Or other examples:
example usage
Create a generic JavaScript "class" that inherits BaseElement:
var BaseElement = require('base-element')
function Bear () {
BaseElement.call(this)
}
Bear.prototype = Object.create(BaseElement.prototype)
Then build your elements:
Bear.prototype.render = function (typeOfBear) {
var vtree = this.html('div.bear', ['Im a ' + typeOfBear + '!'])
return this.afterRender(vtree)
}
Prefer just functions?
If you don't like "classes" the API supports an alternative interface with just
functions:
var createElement = require('base-element')
var el = createElement(document.body)
el.render(function () {
return this.html('button', {
onclick: function (e) {
window.alert(e.target.innerText + ' button was clicked')
}
}, 'click me')
})
data down, events up
DOMs work best (in the opinion of myself and many) when data goes down
and event (or actions) go up.
A simple example is a button element that changes when clicked. How it
changes is up to the element but what it changes to is up to the user.
This is our Button element:
var BaseElement = require('base-element')
function Button () {
BaseElement.call(this)
}
Button.prototype = Object.create(BaseElement.prototype)
Button.prototype.render = function (label) {
var self = this
var vtree = this.html('button', {
onclick: function (event) {
self.send('clicked', event.target)
}
}, label)
return this.afterRender(vtree)
}
and this is the user's implementation, creates a button and on every click it
changes to a random number:
var button = require('your-button')()
button.on('clicked', function (node) {
button.render('button label ' + Math.random())
})
nested architecture
Elements created using base-element
are intended on being shared and extended
by others. Each element should not require an additional library/framework to
run it or be injected into it in order to be ran. Elements should be standalone.
For example if I create an input-box
element and published on npm:
var BaseElement = require('base-element')
function InputBox (el) {
BaseElement.call(this, el)
}
InputBox.prototype = Object.create(BaseElement.prototype)
module.exports = InputBox
InputBox.prototype.render = function (value) {
return this.afterRender(this.html('input', {
onkeyup: function(e) {
this.send('changed', e.target.value)
}.bind(this),
value: value || ''
}))
}
Now yourself or another user can either consume your input-box
or extend it
to add their own functionality on top of yours, such as email-input
:
var InputBox = require('input-box')
function EmailInput (el) {
InputBox.call(this, el)
this.on('changed', function (text) {
})
}
EmailInput.prototype = Object.create(InputBox.prototype)
module.exports = EmailInput
EmailInput.prototype.render = function (data) {
data = data || {}
var vtree = this.html('div', [
this.html('label', data.label || 'Enter your email'),
InputBox.prototype.render(data.value)
])
return this.afterRender(vtree)
}
Both input-box
and email-input
can be ran on their own. When input-box
updates over time, email-input
can stay on a previous version until an upgrade
can be made.
install
npm with browserify, webpack, etc
npm install base-element
var BaseElement = require('base-element')
standalone
- copy/download/etc dist/base-element.js
<script src="base-element.js"></script>
<script>var element = new BaseElement()</script>
api
var element = new BaseElement([attachTo])
attachTo
is a DOM element you want to append to. Defaults to document.body
.
If you pass in false
then the element will not automatically append itself to
a parent node. This is useful if you plan on handling the rendering of the
virtual tree on your own.
element.send(name[, params...])
Sends an event up with a given name
and params
.
element.on(name, function)
Register an event listener for a given name:
element.on('clicked', function (params) {})
element.afterRender([params...])
This method needs to be called when returning a constructed virtual tree. It
will detect if we are at the top of the render tree and perform the DOM diff
and patching.
Button.prototype.render = function (data) {
var vtree = this.html('button')
return this.afterRender(vtree)
}
element.html(tag[, options], value)
A convenience wrapper for creating virtual-hyperscript nodes, i.e.:
var h = require('virtual-dom/h')
var vtree = h('div', 'Testing')
var vtree = this.html('div', 'Testing')
element.element
The root DOM node the virtual tree resides on.
element.vtree
The current virtual DOM tree of the base element.
license
(c) 2015 Kyle Robinson Young. MIT License