An element authoring library for creating standalone and performant elements.
View this example List element in use with:
Or other examples:
Create a generic JavaScript "class" that inherits BaseElement:
var BaseElement = require('base-element')
function Bear () {
BaseElement.call(this)
}
Bear.prototype = Object.create(BaseElement.prototype)
// Or inherits(Bear, BaseElement)
// Or class Bear extends BaseElement
Then build your elements:
Bear.prototype.render = function (typeOfBear) {
// Create a virtual DOM tree
var vtree = this.html('div.bear', ['Im a ' + typeOfBear + '!'])
// Call afterRender with your vtree when returning your vtree
return this.afterRender(vtree)
}
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)
// Or inherits(Button, BaseElement)
// Or class Button extends BaseElement
Button.prototype.render = function (label) {
var self = this
// The "label" data is coming down
var vtree = this.html('button', {
onclick: function (event) {
// We send the "clicked" event up
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())
})
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) {
// Builds an <input value="{value}: />
return this.afterRender(this.html('input', {
onkeyup: function(e) {
// When keys are typed in it we send the value up
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)
// When we receive a "changed" event from InputBox, handle it here
this.on('changed', function (text) {
/* Perform some email validation on text here,
then render() if we need an update */
})
}
EmailInput.prototype = Object.create(InputBox.prototype)
module.exports = EmailInput
EmailInput.prototype.render = function (data) {
data = data || {}
var vtree = this.html('div', [
// Put a <label>Enter your email</label> inside this <div>
this.html('label', data.label || 'Enter your email'),
// Call the InputBox's render
InputBox.prototype.render(data.value)
])
// Return the virtual DOM tree
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.
npm install base-element
var BaseElement = require('base-element')
- copy/download/etc dist/base-element.js
<script src="base-element.js"></script>
<script>var element = new BaseElement()</script>
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.
Sends an event up with a given name
and params
.
Register an event listener for a given name:
element.on('clicked', function (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 tree = this.html('button')
return this.afterRender(vtree)
}
A convenience wrapper for creating virtual-hyperscript nodes, i.e.:
var h = require('virtual-dom/h')
var vtree = h('div', 'Testing')
// is the same as
var vtree = this.html('div', 'Testing')
The root DOM node the virtual tree resides on.
The current virtual DOM tree of the base element.
(c) 2015 Kyle Robinson Young. MIT License