Skip to content

GMartigny/Whiskers.js

Repository files navigation

Whiskers.js 😸

NPM version Minifies bundle size Code coverage

Minimalist HTML-in-JS reactive framework

Installation

Registry

npm install @gmartigny/whiskers.js

CDN

https://unpkg.com/@gmartigny/whiskers.js

Usage

Basic rendering

Prepare elements in order to append them to the DOM.

import { render } from "@gmartigny/whiskers.js";

const app = render("main", {
    class: "app",
}, [
    render("h1", "Whisker.js"),
    render("p", "Minimalist HTML-in-JS reactive framework."),
]);

document.body.appendChild(app);

CSS

Turn an object into a style element.

import { renderStyle } from "@gmartigny/whiskers.js";

const style = renderStyle({
    body: {
        "background-color": "#654321",
        
        ".nested": {
            padding: "2em",
        },
    },
});

document.head.appendChild(style);

Reactivity

Rerender on each change of the data.

import { render, reactive } from "@gmartigny/whiskers.js";

const data = {
    count: 0,
};

const counter = render(undefined, [
    render("button", {
        "@click": () => data.count++,
    }, "Increase"),
    reactive(data, "count", (value, el) => render(el || "span", value)),
]);

document.body.appendChild(counter);

List rendering

Render a list of items.

import { render, reactive } from "@gmartigny/whiskers.js";

const data = {
    list: ["Minimalist", "Ergonomic", "Fun"],
}

const parentRender = (node) => render(node ?? "ul");
const childRender = (value) => render("li", value);
const element = reactive(data, "list", parentRender, childRender)

document.body.appendChild(element);

Headless

React to changes without rendering.

import { reactive } from "@gmartigny/whiskers.js";

const data = {
    value: 42,
};

reactive(data, "value", (value) => {
    console.log(value); // => 42 the first time, 1234 the second time
});
data.value = 1234;

Complete example

Todo app

API

render

Property Type Default Description
element string | HTMLElement "div" Element to create or reuse
props? Object Set of attributes, prefix with "@" for event listeners, "--" for CSS variables and "." for properties
children? string|HTMLElement|Array<string|HTMLElement> List of children to append
render("input", {
    // DOM property
    type: "checkbox",
    // Property set in RAM
    ".private": "",
    // CSS variable
    "--color": "goldenrod",
    // Event listener
    "@input": value => console.assert(typeof value === "boolean"),
})

reactive

Property Type Default Description
data Object Store holding data
key string Field to observe
render Function Render callback called on change
childrenRender? Function Render callback for each child when observing an array

const data = {

const data = {
    value: 42,
    array: [1, 2, 3],
};
// For a single value
reactive(
    data,
    "value",
    // Called on each changes
    (value) => {},
);
// For an array
reactive(
    data,
    "array",
    // Called once on initialization
    (values) => {},
    // Called on each values and then for each update
    (value) => {},
);

License

MIT

About

Minimalist HTML in JS reactive framework

Resources

License

Security policy

Stars

Watchers

Forks

Sponsor this project