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("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("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("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(
|
||||
"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`
|
||||
:host {
|
||||
color: green;
|
||||
@ -22,12 +22,13 @@ export function thirdParty(){
|
||||
// Array.from((new URL(location)).searchParams.entries())
|
||||
// .forEach(([ key, value ])=> O.action(store, "set", key, value));
|
||||
// O.on(store, data=> history.replaceState("", "", "?"+(new URLSearchParams(JSON.parse(JSON.stringify(data)))).toString()));
|
||||
useAdapter(store, store_adapter, {
|
||||
useStore(store_adapter, {
|
||||
onread(data){
|
||||
Array.from(data.entries())
|
||||
.forEach(([ key, value ])=> O.action(store, "set", key, value));
|
||||
return store;
|
||||
}
|
||||
});
|
||||
})();
|
||||
return el("input", {
|
||||
className,
|
||||
value: store().value(),
|
||||
@ -36,9 +37,14 @@ export function thirdParty(){
|
||||
});
|
||||
}
|
||||
|
||||
function useAdapter(observable, adapter, { onread, onbeforewrite }= {}){
|
||||
if(!onread) onread= observable;
|
||||
function useStore(adapter_in, { onread, onbeforewrite }= {}){
|
||||
const adapter= typeof adapter_in === "function" ? { read: adapter_in } : adapter_in;
|
||||
if(!onread) onread= O;
|
||||
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)));
|
||||
return observable;
|
||||
};
|
||||
}
|
||||
|
@ -12,12 +12,13 @@ export class CustomHTMLTestElement extends HTMLElement{
|
||||
}
|
||||
connectedCallback(){
|
||||
if(!this.hasAttribute("pre-name")) this.setAttribute("pre-name", "default");
|
||||
console.log(observedAttributes(this));
|
||||
this.attachShadow({ mode: "open" }).append(
|
||||
customElementRender(this, this.render)
|
||||
);
|
||||
}
|
||||
|
||||
render({ test }){
|
||||
render(test){
|
||||
console.log(scope.state);
|
||||
scope.host(
|
||||
on.connected(()=> console.log(CustomHTMLTestElement)),
|
||||
|
@ -1,10 +1,11 @@
|
||||
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: custom_element,
|
||||
host: (...c)=> c.length ? c.forEach(c=> c(custom_element)) : custom_element,
|
||||
custom_element
|
||||
});
|
||||
if(typeof props==="function") props= props(custom_element);
|
||||
const out= render.call(custom_element, props);
|
||||
scope.pop();
|
||||
return out;
|
||||
@ -31,3 +32,17 @@ export { lifecycleToEvents as customElementWithDDE };
|
||||
function wrapMethod(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();
|
||||
export function observable(value, actions){
|
||||
if(typeof value!=="function")
|
||||
return create(value, actions);
|
||||
return create(false, value, actions);
|
||||
if(isObservable(value)) return value;
|
||||
|
||||
const out= create();
|
||||
const out= create(true);
|
||||
const contextReWatch= function(){
|
||||
const [ origin, ...deps_old ]= deps.get(contextReWatch);
|
||||
deps.set(contextReWatch, new Set([ origin ]));
|
||||
|
||||
stack_watch.push(contextReWatch);
|
||||
out(value());
|
||||
write(out, value());
|
||||
stack_watch.pop();
|
||||
|
||||
if(!deps_old.length) return;
|
||||
@ -180,9 +180,10 @@ function removeObservablesFromElements(o, listener, ...notes){
|
||||
});
|
||||
}
|
||||
|
||||
function create(value, actions){
|
||||
const o= (...value)=>
|
||||
value.length ? write(o, ...value) : read(o);
|
||||
function create(is_readonly, value, actions){
|
||||
const o= is_readonly
|
||||
? ()=> read(o)
|
||||
: (...value)=> value.length ? write(o, ...value) : read(o);
|
||||
return toObservable(o, value, actions);
|
||||
}
|
||||
const protoSigal= Object.assign(Object.create(null), {
|
||||
|
Loading…
Reference in New Issue
Block a user