mirror of
https://github.com/jaandrle/deka-dom-el
synced 2024-11-22 07:49:38 +01:00
♻️ Simplify signals logic (use functions to read/set)
This commit is contained in:
parent
404971f484
commit
acdfb4ef57
@ -102,8 +102,8 @@ document.body.append(
|
|||||||
```js
|
```js
|
||||||
const value= S("");
|
const value= S("");
|
||||||
document.body.append(
|
document.body.append(
|
||||||
el("span", { style: { fontWeight: "bold" }, textContent: ()=> S(value) }),
|
el("span", { style: { fontWeight: "bold" }, textContent: value }),
|
||||||
el("input", { type: "text" },
|
el("input", { type: "text" },
|
||||||
listen("change", event=> S(value, event.target, value)))
|
listen("change", event=> value(event.target.value)))
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
@ -20,12 +20,7 @@ export function createElementNS(tag, attributes, attributes_todo){
|
|||||||
}
|
}
|
||||||
export { createElementNS as elNS };
|
export { createElementNS as elNS };
|
||||||
|
|
||||||
import { watch } from './signals.js';
|
import { watch, isSignal } from './signals.js';
|
||||||
function isReactive(key, attr){
|
|
||||||
if(typeof attr !== "function") return false;
|
|
||||||
if(key.startsWith("on")) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
export function assign(element, ...attributes){
|
export function assign(element, ...attributes){
|
||||||
if(!attributes.length) return element;
|
if(!attributes.length) return element;
|
||||||
const is_svg= element instanceof SVGElement;
|
const is_svg= element instanceof SVGElement;
|
||||||
@ -34,7 +29,7 @@ export function assign(element, ...attributes){
|
|||||||
Object.entries(Object.assign({}, ...attributes)).forEach(function assignNth([ key, attr ]){
|
Object.entries(Object.assign({}, ...attributes)).forEach(function assignNth([ key, attr ]){
|
||||||
if(key[0]==="=") return setRemoveAttr(key.slice(1), attr);
|
if(key[0]==="=") return setRemoveAttr(key.slice(1), attr);
|
||||||
if(key[0]===".") return setDelete(element, key.slice(1), attr);
|
if(key[0]===".") return setDelete(element, key.slice(1), attr);
|
||||||
if(isReactive(key, attr))
|
if(isSignal(attr)) //TODO: unmounted
|
||||||
return watch(()=> assignNth([ key, attr() ]));
|
return watch(()=> assignNth([ key, attr() ]));
|
||||||
if(typeof attr === "object"){
|
if(typeof attr === "object"){
|
||||||
switch(key){
|
switch(key){
|
||||||
|
@ -1,23 +1,16 @@
|
|||||||
const mark= Symbol.for("signal");
|
const mark= Symbol.for("signal");
|
||||||
export function isSignal(candidate){
|
export function isSignal(candidate){
|
||||||
try{
|
try{ return Reflect.has(candidate, mark); }
|
||||||
return Reflect.has(candidate, mark);
|
catch(e){ return false; }
|
||||||
} catch(e){
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
export function S(signal){
|
||||||
export function S(signal, ...value){
|
if(typeof signal!=="function")
|
||||||
if(typeof signal==="function"){
|
|
||||||
const out= create();
|
|
||||||
watch(()=> S(out, signal()));
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
if(!isSignal(signal))
|
|
||||||
return create(signal);
|
return create(signal);
|
||||||
|
if(isSignal(signal)) return signal;
|
||||||
|
|
||||||
if(value.length===0)
|
const out= create();
|
||||||
return read(signal);
|
watch(()=> out(signal()));
|
||||||
return write(signal, value[0]);
|
return out;
|
||||||
}
|
}
|
||||||
const stack= [];
|
const stack= [];
|
||||||
export function watch(context){
|
export function watch(context){
|
||||||
@ -30,16 +23,22 @@ function currentContext(){
|
|||||||
return stack[stack.length - 1];
|
return stack[stack.length - 1];
|
||||||
}
|
}
|
||||||
function create(value){
|
function create(value){
|
||||||
|
if(isSignal(value)) return value;
|
||||||
|
|
||||||
if(typeof value==="object" && value!==null)
|
if(typeof value==="object" && value!==null)
|
||||||
|
//TODO Array?
|
||||||
return Object.fromEntries(
|
return Object.fromEntries(
|
||||||
Object.entries(value)
|
Object.entries(value)
|
||||||
.map(([ key, value ])=> [ key, create(value) ])
|
.map(([ key, value ])=> [ key, create(value) ])
|
||||||
);
|
);
|
||||||
return {
|
const signal= (...value)=>
|
||||||
|
value.length ? write(signal, value[0]) : read(signal);
|
||||||
|
Object.assign(signal, {
|
||||||
[mark]: true,
|
[mark]: true,
|
||||||
value,
|
value,
|
||||||
listeners: new Set()
|
listeners: new Set()
|
||||||
};
|
});
|
||||||
|
return signal;
|
||||||
}
|
}
|
||||||
function read({ value, listeners }){
|
function read({ value, listeners }){
|
||||||
const context= currentContext();
|
const context= currentContext();
|
||||||
|
@ -22,24 +22,24 @@ function component({ name= "World", surname= "" }= {}){
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const store= S({ name, surname });
|
const store= S({ name, surname });
|
||||||
const full_name= S(()=> S(store.name)+" "+S(store.surname));
|
const full_name= S(()=> store.name()+" "+store.surname());
|
||||||
listen(full_name, console.log);
|
listen(full_name, console.log);
|
||||||
|
|
||||||
return el("div", { className }).append(
|
return el("div", { className }).append(
|
||||||
el("p").append(
|
el("p").append(
|
||||||
el("#text", { textContent: "Hello " }),
|
el("#text", { textContent: "Hello " }),
|
||||||
el("strong", { textContent: ()=> S(full_name) }),
|
el("strong", { textContent: full_name }),
|
||||||
el("#text", { textContent: "!" }),
|
el("#text", { textContent: "!" }),
|
||||||
),
|
),
|
||||||
el("label").append(
|
el("label").append(
|
||||||
el("#text", { textContent: "Set name:" }),
|
el("#text", { textContent: "Set name:" }),
|
||||||
el("input", { type: "text", value: ()=> S(store.name) },
|
el("input", { type: "text", value: store.name },
|
||||||
listen("change", ev=> S(store.name, ev.target.value))),
|
listen("change", ev=> store.name(ev.target.value))),
|
||||||
),
|
),
|
||||||
el("label").append(
|
el("label").append(
|
||||||
el("#text", { textContent: "Set surname:" }),
|
el("#text", { textContent: "Set surname:" }),
|
||||||
el("input", { type: "text", value: ()=> S(store.surname) },
|
el("input", { type: "text", value: store.surname },
|
||||||
listen("change", ev=> S(store.surname, ev.target.value))),
|
listen("change", ev=> store.surname(ev.target.value))),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user