From dfd720d425f6e30dc4af84dea8c65d0f2a6efe59 Mon Sep 17 00:00:00 2001 From: DarkWiiPlayer Date: Wed, 17 Jan 2024 09:10:01 +0100 Subject: [PATCH] [WIP] documentation --- doc/html-proxy.md | 66 +++++++++++++++++++++ doc/overview.md | 93 +++++++++++++++++++++++++++++ readme.md | 147 ---------------------------------------------- 3 files changed, 159 insertions(+), 147 deletions(-) create mode 100644 doc/html-proxy.md create mode 100644 doc/overview.md diff --git a/doc/html-proxy.md b/doc/html-proxy.md new file mode 100644 index 0000000..95b4b24 --- /dev/null +++ b/doc/html-proxy.md @@ -0,0 +1,66 @@ +# Skooma.js + +```js +import {html} from "skooma.js" +``` + +A functional-friendly helper library for procedural DOM generation and +templating, with support for reactive state objects. + +## Overview + +```js +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: + +```js +html.div("Hello, World!") +``` + +Attributes can be set by passing objects to the generator: + +```js +html.div("Big Text", {style: "font-size: 1.4em"}) +``` + +Complex structures can easily achieved by nesting generator functions: + +```js +html.div( + html.p( + html.b("Bold Text") + ) +) +``` + +For convenience, arrays assigned as attributes will be joined with spaces: + +```js +html.a({class: ["button", "important"]}) +``` + +Assigning a function as an attribute will instead attach it as an event listener: + +```js +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. + diff --git a/doc/overview.md b/doc/overview.md new file mode 100644 index 0000000..a8b9545 --- /dev/null +++ b/doc/overview.md @@ -0,0 +1,93 @@ +## Skooma.js + +### HTML Proxy + +The proxy object that does the actual HTML generation. + +```js +document.body.append(html.div( + html.span("Hello, World!") +)) +``` + +### Handle helper + +Wraps a funcion of the signature `event, ... -> value` so that +`event.preventDefault` gets called before running the function. + +```js +button.addEventListener("click", + handle(() => console.log("click")) +) +``` + +### Fragment helper + +Wraps a list of elements in a new document fragment. + +```js +const spans = fragment( + html.span("First span"), + html.span("Second span") +) +document.body.append(spans.cloneNode()) +``` + +### Text helper + +When called as a normal function, returns a new text node with the given +content. Unlike `document.createTextNode`, it does not fail for non-string +values. + +```js +const node = text("Hello, World!") +``` + +When used as a tagged template, returns a document fragment containing text +nodes and interpolated values. DOM nodes can be interpolated into the document +fragment. + +```js +const description = text`Interpolate ${html.b("bold")} text` +``` + +For consistency, even tagged templates with no interpolated variables will +always return a document fragment. + +## State.js + +### AbortRegistry + +`FinalizationRegistry` that takes an `AbortController` and aborts it whenever +the registered value gets collected. + +### ChangeEvent + +The event class emitted when a change is detected on a skooma state. +Provides the `final` getter. + +### MapStorage + +A utility class that simulates the `Storage` API but is backed by a map. Can be +used as fallback in environments where persistent storages aren't available. + +### SimpleState + +Base state class that all other states inherit from, used primarily for class +checking, as the `State` class introduces behaviours that may be undesireable +when inheriting. + +### State + +The main state class that does all the magic. + +### ForwardState + +Proxy to a named property on another State to be used with APIs that only accept +single-value states. + +### StoredState + +State class that is backed by a Storage instead of an internal proxy. + +## domLense.js diff --git a/readme.md b/readme.md index 8bdea5d..dc9f29f 100644 --- a/readme.md +++ b/readme.md @@ -1,148 +1 @@ # Skooma - -A functional-friendly helper library for procedural DOM generation and -templating. - -```js -import {html} from "skooma.js" -``` - -## Overview - -```js -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: - -```js -html.div("Hello, World!") -``` - -Attributes can be set by passing objects to the generator: - -```js -html.div("Big Text", {style: "font-size: 1.4em"}) -``` - -Complex structures can easily achieved by nesting generator functions: - -```js -html.div( - html.p( - html.b("Bold Text") - ) -) -``` - -For convenience, arrays assigned as attributes will be joined with spaces: - -```js -html.a({class: ["button", "important"]}) -``` - -Assigning a function as an attribute will instead attach it as an event -listener: - -```js -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 - -```js -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 tag with the user's name, and a text node for ! -``` - -## handle - -```js -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: - -```js -fn => event => { event.preventDefault(); return fn(event) } -``` - -## A few more examples: - -Create a Button that deletes itself: - -```js -document.body.append( - html.button("Delete Me", {click: event => event.target.remove()}) -) -``` - -Turn a two-dimensional array into an HTML table: -```js -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 -```js -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 -```js -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"), -])) -```