Skip to content

Instantly share code, notes, and snippets.

@jayrbolton
Last active October 15, 2019 22:17
Show Gist options
  • Save jayrbolton/03cd6173edf32c61c628 to your computer and use it in GitHub Desktop.
Save jayrbolton/03cd6173edf32c61c628 to your computer and use it in GitHub Desktop.
state-based dom manipulation where dom elements get bound to special ui state objects
The goals of this view library are:
- bridge the gap between js-land and html-land without mucking up the syntax and semantics of either
- little to no overhead to setup and use
- no precompilation, no transpiling, lightweight, fast
- declarative
- unit-testable UI behavior
The ideas:
- a lot like virtual-dom except more abstracted
- use plain JS objects and their regular JS semantics to define *view states* that affect the dom
- create a binding between an object and a dom element using "data-bind" attributes
- define the properties of the object that affect the DOM in different ways (eg. ".text", ".class", ".click", etc)
- this decouples javascript from the dom so that your javascript logic only needs to be thought of as manipulations of objects
property examples:
- an object with a '.text' property will set the textContent of its element to the value of that property
- an object with a '.click' property set to a function will fire that function whenever the node is clicked
- an object with a '.attr' property can set the various style rules of any element the object is bound to
Example todo list:
-- index.js
var state = require('stateful-dom')
state.set('newTodo', {
onSubmit: function(ev) {
todoList.push('collection', formToObject(ev.currentTarget))
ev.currentTarget.reset()
}
})
state.set('todoList', {
collection: [ { text: 'Get groceries', done: false } ],
// define properties that each item in 'collection' will have access to
each: {
finishItem: function(i, collection) {
state.set('todoList.collection', i, {done: true})
},
class: function() {
if(this.done) return 'is-done'
}
},
// Return the total undone remaining items out of all items
remainingCount: {
text: function() {
var remaining = this.collection.filter(function(item) { return !item.done }).length
return remaining + ' of ' + this.collection.length ' remaining'
}
}
})
-- index.html
<h1>Todo</h1>
<form data-bind='newTodo'>
<input type='text' name='text' placeholder='What needs to be done?'>
<button type='submit'>Add item</button>
</form>
<p data-bind='todoList.remainingCount'> </p>
<ul>
<li data-bind='todoList'>
<input type='checkbox' data-bind='todoList.each.finishItem'>
</li>
</ul>
@askirmas
Copy link

Hi. Did you find some real state-ful DOM library?

@jayrbolton
Copy link
Author

Things like Vue.js, Svelte, Knockout probably all have similar or the same features, plus a lot more

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment