From 4136eb65af6898f6f8a283213df451a463ac429f Mon Sep 17 00:00:00 2001 From: DarkWiiPlayer Date: Sat, 3 Aug 2024 19:13:04 +0200 Subject: [PATCH] Improve documentation of render function --- doc/html-helpers.md | 0 doc/{html-proxy.md => render.md} | 58 +++++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 9 deletions(-) delete mode 100644 doc/html-helpers.md rename doc/{html-proxy.md => render.md} (65%) diff --git a/doc/html-helpers.md b/doc/html-helpers.md deleted file mode 100644 index e69de29..0000000 diff --git a/doc/html-proxy.md b/doc/render.md similarity index 65% rename from doc/html-proxy.md rename to doc/render.md index 716a815..0397174 100644 --- a/doc/html-proxy.md +++ b/doc/render.md @@ -1,7 +1,7 @@ -# Skooma.js +# Rendering DOM nodes using `render.js` ```js -import {html} from "skooma.js" +import {html} from "skooma/render.js" ``` A functional-friendly helper library for procedural DOM generation and templating, with support for reactive state objects. @@ -110,7 +110,8 @@ html.div({ }) ``` -The `dataset` property will add its key/value pairs to the new node's `dataset`, as a more convenient alternative to setting individual `data-` attributes. +The `dataset` property will add its key/value pairs to the new node's `dataset`, +as a more convenient alternative to setting individual `data-` attributes. ```js const dataset = { foo: "bar" } @@ -123,12 +124,51 @@ console.log(div.getAttribute("data-foo") === "bar") Skooma supports reactivity through a simple protocol: -Observable objects identify themselves with the `observable` attribute, which -must return a truthy value. +Observable objects identify themselves with the `observable` attribute, +which must return a truthy value. -Observables are expected to expose a `value` attribute that is both readable and -writeable, and to emit a "change" event whenever its vale has changed. +Observables are expected to expose a `value` attribute that is both readable and writeable, +and to emit a "change" event whenever its vale has changed. -Observables can be used both as attribute values as well as for child elements. +Observables can be passed to skooma's node functions as both +attribute values (values in an object) or +child elements (direct arguments or in an array). -TODO: Explain what actually happens +#### Reactive Children + +Passing an observable as a child element will attempt to insert its current +value into the new node as if it was passed in directly, but will also hook into +the observable to replace the value when the state changes. + +```js +const state = new Observable.value(0) + +const button = html.button(state, { + click(event) { state.value++ } +}) +``` + +Note that to keep the replacement logic simple, it is not currently possible to +insert use document fragments, as these could insert several top-level children +into a component that would then all have to be replaced. When an observable +contains or changes to a document fragment, skooma will raise an error. + +Before replacing an element, a `"replace"` event is emitted from the old +element. This event bubbles and is cancelable, and can thus be used both to +completely prevent the replacement according to custom logic, to alter or +initialise the new element before it is inserted, or even to modify the old +object instead of replacing it. + +#### Reactive Attributes + +Passing an observable as an object value will, likewise, treat its value as the +attribute value, and update it whenever the state's value changes. + +```js +const state = new Observable.value(0) + +const input_1 = html.input({ type: "number", value: state }) +const input_2 = html.input({ type: "number", value: state }) +``` + +TODO: events as for reactive children