mirror of
https://github.com/jaandrle/deka-dom-el
synced 2024-11-23 00:59:38 +01:00
🎉
This commit is contained in:
parent
eb920f7bbd
commit
89f9880277
@ -7,7 +7,7 @@ export function mnemonic(){
|
|||||||
el("code", "O(<value>)"), " — observable: reactive value",
|
el("code", "O(<value>)"), " — observable: reactive value",
|
||||||
),
|
),
|
||||||
el("li").append(
|
el("li").append(
|
||||||
el("code", "O(()=> <computation>)"), " — observable: reactive value dependent on calculation using other observables",
|
el("code", "O(()=> <computation>)"), " — read-only observable: reactive value dependent on calculation using other observables",
|
||||||
),
|
),
|
||||||
el("li").append(
|
el("li").append(
|
||||||
el("code", "O.on(<observable>, <listener>[, <options>])"), " — listen to the observable value changes",
|
el("code", "O.on(<observable>, <listener>[, <options>])"), " — listen to the observable value changes",
|
||||||
|
@ -88,7 +88,9 @@ export function page({ pkg, info }){
|
|||||||
el("code", "ariaset"), " and ", el("code", "classList"), "."
|
el("code", "ariaset"), " and ", el("code", "classList"), "."
|
||||||
),
|
),
|
||||||
el("p").append(
|
el("p").append(
|
||||||
"For computation, you can use the derived observable (see above) like ", el("code", "assign(element, { textContent: O(()=> 'Hello '+WorldObservable()) })"), "."
|
"For computation, you can use the “derived observable” (see above) like ", el("code", "assign(element, { textContent: O(()=> 'Hello '+WorldObservable()) })"), ".",
|
||||||
|
" ",
|
||||||
|
"This is read-only observable its value is computed based on given function and updated when any observable used in the function changes."
|
||||||
),
|
),
|
||||||
el("p").append(
|
el("p").append(
|
||||||
"To represent part of the template filled dynamically based on the observable value use ", el("code", "O.el(observable, DOMgenerator)"), ".",
|
"To represent part of the template filled dynamically based on the observable value use ", el("code", "O.el(observable, DOMgenerator)"), ".",
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { style, el, O } from '../exports.js';
|
import { style, el, O, isObservable } from '../exports.js';
|
||||||
const className= style.host(thirdParty).css`
|
const className= style.host(thirdParty).css`
|
||||||
:host {
|
:host {
|
||||||
color: green;
|
color: green;
|
||||||
@ -22,12 +22,13 @@ export function thirdParty(){
|
|||||||
// Array.from((new URL(location)).searchParams.entries())
|
// Array.from((new URL(location)).searchParams.entries())
|
||||||
// .forEach(([ key, value ])=> O.action(store, "set", key, value));
|
// .forEach(([ key, value ])=> O.action(store, "set", key, value));
|
||||||
// O.on(store, data=> history.replaceState("", "", "?"+(new URLSearchParams(JSON.parse(JSON.stringify(data)))).toString()));
|
// O.on(store, data=> history.replaceState("", "", "?"+(new URLSearchParams(JSON.parse(JSON.stringify(data)))).toString()));
|
||||||
useAdapter(store, store_adapter, {
|
useStore(store_adapter, {
|
||||||
onread(data){
|
onread(data){
|
||||||
Array.from(data.entries())
|
Array.from(data.entries())
|
||||||
.forEach(([ key, value ])=> O.action(store, "set", key, value));
|
.forEach(([ key, value ])=> O.action(store, "set", key, value));
|
||||||
|
return store;
|
||||||
}
|
}
|
||||||
});
|
})();
|
||||||
return el("input", {
|
return el("input", {
|
||||||
className,
|
className,
|
||||||
value: store().value(),
|
value: store().value(),
|
||||||
@ -36,9 +37,14 @@ export function thirdParty(){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function useAdapter(observable, adapter, { onread, onbeforewrite }= {}){
|
function useStore(adapter_in, { onread, onbeforewrite }= {}){
|
||||||
if(!onread) onread= observable;
|
const adapter= typeof adapter_in === "function" ? { read: adapter_in } : adapter_in;
|
||||||
|
if(!onread) onread= O;
|
||||||
if(!onbeforewrite) onbeforewrite= data=> JSON.parse(JSON.stringify(data));
|
if(!onbeforewrite) onbeforewrite= data=> JSON.parse(JSON.stringify(data));
|
||||||
onread(adapter.read()); //TODO OK as synchronous
|
return function useStoreInner(data_read){
|
||||||
|
const observable= onread(adapter.read(data_read)); //TODO OK as synchronous
|
||||||
|
if(adapter.write && isObservable(observable))
|
||||||
O.on(observable, data=> adapter.write(onbeforewrite(data)));
|
O.on(observable, data=> adapter.write(onbeforewrite(data)));
|
||||||
|
return observable;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,13 @@ export class CustomHTMLTestElement extends HTMLElement{
|
|||||||
}
|
}
|
||||||
connectedCallback(){
|
connectedCallback(){
|
||||||
if(!this.hasAttribute("pre-name")) this.setAttribute("pre-name", "default");
|
if(!this.hasAttribute("pre-name")) this.setAttribute("pre-name", "default");
|
||||||
|
console.log(observedAttributes(this));
|
||||||
this.attachShadow({ mode: "open" }).append(
|
this.attachShadow({ mode: "open" }).append(
|
||||||
customElementRender(this, this.render)
|
customElementRender(this, this.render)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render({ test }){
|
render(test){
|
||||||
console.log(scope.state);
|
console.log(scope.state);
|
||||||
scope.host(
|
scope.host(
|
||||||
on.connected(()=> console.log(CustomHTMLTestElement)),
|
on.connected(()=> console.log(CustomHTMLTestElement)),
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { scope } from "./dom.js";
|
import { scope } from "./dom.js";
|
||||||
export function customElementRender(custom_element, render, props= custom_element){
|
export function customElementRender(custom_element, render, props= observedAttributes){
|
||||||
scope.push({
|
scope.push({
|
||||||
scope: custom_element,
|
scope: custom_element,
|
||||||
host: (...c)=> c.length ? c.forEach(c=> c(custom_element)) : custom_element,
|
host: (...c)=> c.length ? c.forEach(c=> c(custom_element)) : custom_element,
|
||||||
custom_element
|
custom_element
|
||||||
});
|
});
|
||||||
|
if(typeof props==="function") props= props(custom_element);
|
||||||
const out= render.call(custom_element, props);
|
const out= render.call(custom_element, props);
|
||||||
scope.pop();
|
scope.pop();
|
||||||
return out;
|
return out;
|
||||||
@ -31,3 +32,17 @@ export { lifecycleToEvents as customElementWithDDE };
|
|||||||
function wrapMethod(obj, method, apply){
|
function wrapMethod(obj, method, apply){
|
||||||
obj[method]= new Proxy(obj[method] || (()=> {}), { apply });
|
obj[method]= new Proxy(obj[method] || (()=> {}), { apply });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function observedAttribute(instance, name){
|
||||||
|
const out= (...args)=> !args.length
|
||||||
|
? instance.getAttribute(name)
|
||||||
|
: instance.setAttribute(name, ...args);
|
||||||
|
out.attribute= name;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
export function observedAttributes(instance){
|
||||||
|
const { observedAttributes= [] }= instance.constructor;
|
||||||
|
return observedAttributes
|
||||||
|
.map(name=> [ name.replace(/-./g, x=> x[1].toUpperCase()), name ])
|
||||||
|
.reduce((out, [ key, name ])=> ( Reflect.set(out, key, observedAttribute(instance, name)), out ), {});
|
||||||
|
}
|
||||||
|
@ -18,16 +18,16 @@ const stack_watch= [];
|
|||||||
const deps= new WeakMap();
|
const deps= new WeakMap();
|
||||||
export function observable(value, actions){
|
export function observable(value, actions){
|
||||||
if(typeof value!=="function")
|
if(typeof value!=="function")
|
||||||
return create(value, actions);
|
return create(false, value, actions);
|
||||||
if(isObservable(value)) return value;
|
if(isObservable(value)) return value;
|
||||||
|
|
||||||
const out= create();
|
const out= create(true);
|
||||||
const contextReWatch= function(){
|
const contextReWatch= function(){
|
||||||
const [ origin, ...deps_old ]= deps.get(contextReWatch);
|
const [ origin, ...deps_old ]= deps.get(contextReWatch);
|
||||||
deps.set(contextReWatch, new Set([ origin ]));
|
deps.set(contextReWatch, new Set([ origin ]));
|
||||||
|
|
||||||
stack_watch.push(contextReWatch);
|
stack_watch.push(contextReWatch);
|
||||||
out(value());
|
write(out, value());
|
||||||
stack_watch.pop();
|
stack_watch.pop();
|
||||||
|
|
||||||
if(!deps_old.length) return;
|
if(!deps_old.length) return;
|
||||||
@ -180,9 +180,10 @@ function removeObservablesFromElements(o, listener, ...notes){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function create(value, actions){
|
function create(is_readonly, value, actions){
|
||||||
const o= (...value)=>
|
const o= is_readonly
|
||||||
value.length ? write(o, ...value) : read(o);
|
? ()=> read(o)
|
||||||
|
: (...value)=> value.length ? write(o, ...value) : read(o);
|
||||||
return toObservable(o, value, actions);
|
return toObservable(o, value, actions);
|
||||||
}
|
}
|
||||||
const protoSigal= Object.assign(Object.create(null), {
|
const protoSigal= Object.assign(Object.create(null), {
|
||||||
|
Loading…
Reference in New Issue
Block a user