🐛 libh
// get ingredients
import { $, h as html, on } from "libh"
// cook yours
function Component() {
const count = $(0);
return html`
<h1>Count is ${count}</h1>
<button ${{ [on.click]: () => count.$++ }}>
Add more!
</button>
`;
}
// throw into the DOM
document.body.append(...Component());
Visit live demo.
npm i libh
Class-model | Bidirecetional binding | Post-processing
import { $, h as html, on, css } from "libh"
const ButtonClass = {
[css]: {
color: "white",
backgroundColor: "blue",
},
[on.click]: () => alert("hi")
}
function Main() {
const count = $(0);
return html`
<button ${{ [on.click]: () => count.$++, ...ButtonClass }}>
I'm styled ${count}!
</button>
`
}
function Linked() {
const valueHolder = $(0)
return html`
<h1>these are linked!</h1>
<input ${{ value: valueHolder, type: "range" }}>
<input ${{ value: valueHolder, type: "range" }}>
<label>value is ${valueHolder}</label>
`
}
function Canvas() {
const colorSwitch = $(true);
return html`
<canvas ${{ id: "color", [on.click]: () => colorSwitch.switch() }}></canvas>
`.then(({ color }) => {
const ctx = color.getContext("2d");
colorSwitch.into($ => $ ? "red" : "blue").watch($ => {
ctx.fillStyle = $;
ctx.fillRect(0, 0, 100, 100);
});
})
}
function Canvas() {
const customers = $([]);
const name = $(""), email = $("");
return html`
<ul>${customers.into(({ name, email }, ref) => html`
<li>name: ${name}, email: ${email}</li>
<button ${{
[on.click]() {
ref.removeOf(this[html])
}
}}>x</button>
`, { sync: true, draggable: true })}</ul>
<input ${{ value: name, type: "string" }}>
<input ${{ value: email, type: "email" }}>
<button ${{ [on.click]: () => {
customers.push({ name: name.$, email: email.$ });
name.$ = "";
email.$ = "";
} }}>submit</button>
`
}
libh is WTFPL licensed.