1
0
mirror of https://github.com/jaandrle/deka-dom-el synced 2025-07-01 04:12:14 +02:00

💥 docs observables

This commit is contained in:
2023-11-29 18:25:21 +01:00
parent 420defe4a2
commit 01f102c149
28 changed files with 1009 additions and 618 deletions

View File

@ -1,7 +1,11 @@
// when NPM
import { assign, el, elNS } from "deka-dom-el";
// https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm.js
// use NPM or for example https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm.js
import {
assign,
el, createElement,
elNS, createElementNS
} from "deka-dom-el";
el===createElement
elNS===createElementNS
// “internal” utils
import {
assignAttribute,

View File

@ -1,7 +1,4 @@
// when NPM
// use NPM or for example https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm.js
import { on, dispatchEvent } from "deka-dom-el";
// https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm.js
/**
* @type {ddeElementAddon}
* */
/** @type {ddeElementAddon} */

View File

@ -0,0 +1,18 @@
import { O } from "deka-dom-el/observables";
const observable= O(0, {
increaseOnlyOdd(add){
console.info(add);
if(add%2 === 0) return this.stopPropagation();
this.value+= add;
}
});
O.on(observable, console.log);
const oninterval= ()=>
O.action(observable, "increaseOnlyOdd", Math.floor(Math.random()*100));
const interval= 5*1000;
setTimeout(
clearInterval,
10*interval,
setInterval(oninterval, interval)
);

View File

@ -0,0 +1,56 @@
import { O } from "deka-dom-el/observables";
const todos= O([], {
push(item){
this.value.push(O(item));
},
pop(){
const removed= this.value.pop();
if(removed) O.clear(removed);
},
[O.symbols.onclear](){ // this covers `O.clear(todos)`
O.clear(...this.value);
}
});
import { el, on } from "deka-dom-el";
/** @type {ddeElementAddon<HTMLFormElement>} */
const onsubmit= on("submit", function(event){
event.preventDefault();
const data= new FormData(this);
switch (data.get("op")){
case "A"/*dd*/:
O.action(todos, "push", data.get("todo"));
break;
case "E"/*dit*/: {
const last= todos().at(-1);
if(!last) break;
last(data.get("todo"));
break;
}
case "R"/*emove*/:
O.action(todos, "pop");
break;
}
});
document.body.append(
el("ul").append(
O.el(todos, todos=>
todos.map(textContent=> el("li", textContent)))
),
el("form", null, onsubmit).append(
el("input", { type: "text", name: "todo", placeholder: "Todos text" }),
el(radio, { textContent: "Add", checked: true }),
el(radio, { textContent: "Edit last" }),
el(radio, { textContent: "Remove" }),
el("button", "Submit")
)
);
document.head.append(
el("style", "form{ display: flex; flex-flow: column nowrap; }")
);
function radio({ textContent, checked= false }){
return el("label").append(
el("input", { type: "radio", name: "op", value: textContent[0], checked }),
" ",textContent
)
}

View File

@ -8,7 +8,7 @@ O.on(observable, v=> console.log("observable", v), { signal: ac.signal });
O.on(double, v=> console.log("double", v), { signal: ac.signal });
observable(observable()+1);
const interval= 5000;
const interval= 5 * 1000;
const id= setInterval(()=> observable(observable()+1), interval);
ac.signal.addEventListener("abort",
()=> setTimeout(()=> clearInterval(id), 2*interval));

View File

@ -0,0 +1,15 @@
import { O } from "deka-dom-el/observables";
const count= O(0);
import { el } from "deka-dom-el";
document.body.append(
el("p", O(()=> "Currently: "+count())),
el("p", { classList: { red: O(()=> count()%2) }, dataset: { count }, textContent: "Attributes example" })
);
document.head.append(
el("style", ".red { color: red; }")
);
const interval= 5 * 1000;
setTimeout(clearInterval, 10*interval,
setInterval(()=> count(count()+1), interval));

View File

@ -0,0 +1,26 @@
import { O } from "deka-dom-el/observables";
const count= O(0, {
add(){ this.value= this.value + Math.round(Math.random()*10); }
});
const numbers= O([ count() ], {
push(next){ this.value.push(next); }
});
import { el } from "deka-dom-el";
document.body.append(
O.el(count, count=> count%2
? el("p", "Last number is odd.")
: el()
),
el("p", "Lucky numbers:"),
el("ul").append(
O.el(numbers, numbers=> numbers.toReversed()
.map(n=> el("li", n)))
)
);
const interval= 5*1000;
setTimeout(clearInterval, 10*interval, setInterval(function(){
O.action(count, "add");
O.action(numbers, "push", count());
}, interval));

View File

@ -1,10 +1,6 @@
// when NPM
import { O } from "deka-dom-el/observables";
// https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-observables.js
/**
* @type {ddeObservable}
* */
/**
* @type {ddeActions}
* */
// use NPM or for example https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-observables.js
import { O, observable } from "deka-dom-el/observables";
O===observable
/** @type {ddeObservable} */
/** @type {ddeAction} */
/** @type {ddeActions} */

View File

@ -4,5 +4,9 @@ const observable= O(0);
// β — just reacts on observable changes
O.on(observable, console.log);
// γ — just updates the value
observable(observable()+1);
setInterval(()=> observable(observable()+1), 5000);
const update= ()=> observable(observable()+1);
update();
const interval= 5*1000;
setTimeout(clearInterval, 10*interval,
setInterval(update, interval));

View File

@ -0,0 +1,25 @@
import { el } from "deka-dom-el";
import { mnemonicUl } from "../mnemonicUl.html.js";
export function mnemonic(){
return mnemonicUl().append(
el("li").append(
el("code", "assign(<element>, ...<idl-objects>): <element>"), " — assign properties to the element",
),
el("li").append(
el("code", "el(<tag-name>, <primitive>)[.append(...)]: <element-from-tag-name>"), " — simple element containing only text",
),
el("li").append(
el("code", "el(<tag-name>, <idl-object>)[.append(...)]: <element-from-tag-name>"), " — element with more properties",
),
el("li").append(
el("code", "el(<function>, <function-argument(s)>)[.append(...)]: <element-returned-by-function>"), " — using component represented by function",
),
el("li").append(
el("code", "el(<...>, <...>, ...<addons>)"), " — see following page"
),
el("li").append(
el("code", "elNS(<namespace>)(<as-el-see-above>)[.append(...)]: <element-based-on-arguments>"), " — typically SVG elements",
)
);
}

View File

@ -0,0 +1,20 @@
import { el } from "deka-dom-el";
import { mnemonicUl } from "../mnemonicUl.html.js";
export function mnemonic(){
return mnemonicUl().append(
el("li").append(
el("code", "on(<event>, <listener>[, <options>])(<element>)"), " — just ", el("code", "<element>.addEventListener(<event>, <listener>[, <options>])")
),
el("li").append(
el("code", "on.<live-cycle>(<event>, <listener>[, <options>])(<element>)"), " — corresponds to custom elemnets callbacks ", el("code", "<live-cycle>Callback(...){...}"),
". To connect to custom element see following page, else it is simulated by MutationObserver."
),
el("li").append(
el("code", "dispatchEvent(<event>[, <options>])(element)"), " — just ", el("code", "<element>.dispatchEvent(new Event(<event>[, <options>]))")
),
el("li").append(
el("code", "dispatchEvent(<event>[, <options>])(element, detail)"), " — just ", el("code", "<element>.dispatchEvent(new CustomEvent(<event>, { detail, ...<options> }))")
),
);
}

View File

@ -0,0 +1,28 @@
import { el } from "deka-dom-el";
import { mnemonicUl } from "../mnemonicUl.html.js";
export function mnemonic(){
return mnemonicUl().append(
el("li").append(
el("code", "O(<value>)"), " — observable: reactive value",
),
el("li").append(
el("code", "O(()=> <computation>)"), " — observable: reactive value dependent on calculation using other observables",
),
el("li").append(
el("code", "O.on(<observable>, <listener>[, <options>])"), " — listen to the observable value changes",
),
el("li").append(
el("code", "O.clear(...<observables>)"), " — off and clear observables",
),
el("li").append(
el("code", "O(<value>, <actions>)"), " — observable: pattern to create complex reactive objects/arrays",
),
el("li").append(
el("code", "O.action(<observable>, <action-name>, ...<action-arguments>)"), " — invoke an action for given observable"
),
el("li").append(
el("code", "O.el(<observable>, <function-returning-dom>)"), " — render partial dom structure (template) based on the current observable value",
)
);
}

View File

@ -7,8 +7,8 @@ ${host} h3{
}
`;
import { el, simulateSlots } from "deka-dom-el";
/** @param {Object} props @param {string} props.textContent */
export function mnemonicUl({ textContent= "" }){
/** @param {Object} [props] @param {string} [props.textContent] */
export function mnemonicUl({ textContent= "" }= {}){
if(textContent) textContent= " "+textContent
return simulateSlots(el("div", { className: "notice" }).append(
el(h3, "Mnemonic"+textContent),