DarkWiiPlayer
3f838821e4
Function arguments to skooma generators are now only treated as initialisers if they take at least one named argument. Otherwise they are called and their return value is evaluated as their replacement. The process is recursive and can happen repeatedly for functions that themselves return functions. |
||
---|---|---|
domLense.js | ||
license.md | ||
package.json | ||
readme.md | ||
skooma.js | ||
state.js |
Skooma
A functional-friendly helper library for procedural DOM generation and templating.
import {html} from "skooma.js"
Overview
const text = new State({value: "Skooma is cool"})
setTimeout(() => {text.value = "Skooma is awesome!"}, 1e5)
document.body.append(html.div(
html.h1("Hello, World!"),
html.p(text, {class: "amazing"}),
html.button("Show Proof", {click: event => { alert("It's true!") }})
))
Interface / Examples
Basic DOM generation
Accessing the html
proxy with any string key returns a new node generator
function:
html.div("Hello, World!")
Attributes can be set by passing objects to the generator:
html.div("Big Text", {style: "font-size: 1.4em"})
Complex structures can easily achieved by nesting generator functions:
html.div(
html.p(
html.b("Bold Text")
)
)
For convenience, arrays assigned as attributes will be joined with spaces:
html.a({class: ["button", "important"]})
Assigning a function as an attribute will instead attach it as an event listener:
html.button("Click me!", {click: event => {
alert("You clicked the button.")
}})
Generators can be called with many arguments. Arrays get iterated recursively as if they were part of a flat argument list.
Generating Text Nodes
text("Hello, World")
// Wraps document.createTextNode
text()
// Defaults to empty string instead of erroring
text(null)
// Non-string arguments still error
text`Hello, World!`
// returns a new document fragment containing the text node "Hello, World!"
text`Hello, ${user}!`
// returns a document fragment containing 3 nodes:
// "Hello, ", the interpolated value of `user` and "!"
text`Hello, ${html.b(user)}!`
// Text node for Hello, the <b> tag with the user's name, and a text node for !
handle
import {handle} from 'skooma.js'
Since it is common for event handlers to call preventDefault()
, skooma
provides a helper function called handle
with the following definition:
fn => event => { event.preventDefault(); return fn(event) }
A few more examples:
Create a Button that deletes itself:
document.body.append(
html.button("Delete Me", {click: event => event.target.remove()})
)
Turn a two-dimensional array into an HTML table:
const table = rows =>
html.table(html.tbody(rows.map(
row => html.tr(row.map(
cell => html.rd(cell, {dataset: {
content: cell.toLowerCase(),
}})
))
)))
A list that you can add items to
let list, input = ""
document.body.append(html.div([
list=html.ul(),
html.input({type: 'text', input: e => input = e.target.value}),
html.button({click: event => list.append(html.li(input))}, "Add"),
]))
A list that you can also delete items from
const listItem = content => html.li(
html.span(content), " ", html.a("[remove]", {
click: event => event.target.closest("li").remove(),
style: { cursor: 'pointer', color: 'red' },
})
)
let list, input = ""
document.body.append(html.div([
list=html.ul(),
html.input({type: 'text', input: e => input = e.target.value}),
html.button({click: event => list.append(listItem(input))}, "Add"),
]))