mirror of
https://github.com/jaandrle/deka-dom-el
synced 2024-11-24 09:29:37 +01:00
S.attribute
is the best option
This commit is contained in:
parent
10ed0802f2
commit
efc5c34fc4
29
dist/dde-with-signals.js
vendored
29
dist/dde-with-signals.js
vendored
File diff suppressed because one or more lines are too long
13
dist/dde.js
vendored
13
dist/dde.js
vendored
File diff suppressed because one or more lines are too long
2
dist/esm-with-signals.d.ts
vendored
2
dist/esm-with-signals.d.ts
vendored
@ -521,7 +521,7 @@ interface S {
|
|||||||
* */
|
* */
|
||||||
el<S extends any>(signal: Signal<S, any>, el: (v: S)=> Element | Element[]): DocumentFragment;
|
el<S extends any>(signal: Signal<S, any>, el: (v: S)=> Element | Element[]): DocumentFragment;
|
||||||
|
|
||||||
fromAttribute<T>(element: HTMLElement, name: string, value?: T): Signal<T, {}>;
|
attribute(name: string, initial?: string): Signal<string, {}>;
|
||||||
}
|
}
|
||||||
export const S: S;
|
export const S: S;
|
||||||
declare global {
|
declare global {
|
||||||
|
8
dist/esm-with-signals.js
vendored
8
dist/esm-with-signals.js
vendored
File diff suppressed because one or more lines are too long
2
dist/esm.js
vendored
2
dist/esm.js
vendored
File diff suppressed because one or more lines are too long
@ -13,19 +13,19 @@ 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");
|
||||||
this.attachShadow({ mode: "open" }).append(
|
this.attachShadow({ mode: "open" }).append(
|
||||||
customElementRender(this, this.render, observedAttributes(S))
|
customElementRender(this, this.render)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render({ name, preName }){
|
render({ test }){
|
||||||
const { host }= scope;
|
|
||||||
const { test }= host();
|
|
||||||
console.log(scope.state);
|
console.log(scope.state);
|
||||||
host(
|
scope.host(
|
||||||
on.connected(()=> console.log(CustomHTMLTestElement)),
|
on.connected(()=> console.log(CustomHTMLTestElement)),
|
||||||
on.attributeChanged(e=> console.log(e)),
|
on.attributeChanged(e=> console.log(e)),
|
||||||
on.disconnected(()=> console.log(CustomHTMLTestElement))
|
on.disconnected(()=> console.log(CustomHTMLTestElement))
|
||||||
);
|
);
|
||||||
|
const name= S.attribute("name");
|
||||||
|
const preName= S.attribute("pre-name");
|
||||||
|
|
||||||
console.log({ name, test, preName});
|
console.log({ name, test, preName});
|
||||||
return el("p").append(
|
return el("p").append(
|
||||||
@ -46,7 +46,7 @@ export class CustomHTMLTestElement extends HTMLElement{
|
|||||||
lifecycleToEvents(CustomHTMLTestElement)
|
lifecycleToEvents(CustomHTMLTestElement)
|
||||||
customElements.define(CustomHTMLTestElement.tagName, CustomHTMLTestElement);
|
customElements.define(CustomHTMLTestElement.tagName, CustomHTMLTestElement);
|
||||||
|
|
||||||
function customElementRender(_this, render, props){
|
function customElementRender(_this, render, props= _this){
|
||||||
console.log(_this.shadowRoot, _this.childList);
|
console.log(_this.shadowRoot, _this.childList);
|
||||||
scope.push({ scope: _this, host: (...c)=> c.length ? c.forEach(c=> c(_this)) : _this, custom_element: _this });
|
scope.push({ scope: _this, host: (...c)=> c.length ? c.forEach(c=> c(_this)) : _this, custom_element: _this });
|
||||||
if(typeof props==="function") props= props(_this);
|
if(typeof props==="function") props= props(_this);
|
||||||
@ -54,17 +54,6 @@ function customElementRender(_this, render, props){
|
|||||||
scope.pop();
|
scope.pop();
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
function observedAttributes(options, element){
|
|
||||||
const fromAttribute= typeof options==="undefined" ? (_1, _2, v)=> v : ( options.fromAttribute || options );
|
|
||||||
if(!element) return observedAttributes.bind(null, fromAttribute)
|
|
||||||
return Object.fromEntries(
|
|
||||||
element.constructor.observedAttributes
|
|
||||||
.map(name=> [
|
|
||||||
name.replace(/-./g, m=> m.slice(1).toUpperCase()),
|
|
||||||
fromAttribute(element, name, element.getAttribute(name))
|
|
||||||
])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
function lifecycleToEvents(class_declaration){
|
function lifecycleToEvents(class_declaration){
|
||||||
for (const name of [ "connected", "disconnected" ])
|
for (const name of [ "connected", "disconnected" ])
|
||||||
wrapMethod(class_declaration.prototype, name+"Callback", function(target, thisArg, detail){
|
wrapMethod(class_declaration.prototype, name+"Callback", function(target, thisArg, detail){
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
"size-limit": [
|
"size-limit": [
|
||||||
{
|
{
|
||||||
"path": "./index.js",
|
"path": "./index.js",
|
||||||
"limit": "8 kB",
|
"limit": "8.5 kB",
|
||||||
"gzip": false
|
"gzip": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
2
signals.d.ts
vendored
2
signals.d.ts
vendored
@ -54,7 +54,7 @@ interface S {
|
|||||||
* */
|
* */
|
||||||
el<S extends any>(signal: Signal<S, any>, el: (v: S)=> Element | Element[]): DocumentFragment;
|
el<S extends any>(signal: Signal<S, any>, el: (v: S)=> Element | Element[]): DocumentFragment;
|
||||||
|
|
||||||
fromAttribute<T>(element: HTMLElement, name: string, value?: T): Signal<T, {}>;
|
attribute(name: string, initial?: string): Signal<string, {}>;
|
||||||
}
|
}
|
||||||
export const S: S;
|
export const S: S;
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -151,6 +151,11 @@ export function empty(el){
|
|||||||
Array.from(el.children).forEach(el=> el.remove());
|
Array.from(el.children).forEach(el=> el.remove());
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
|
export function elementAttribute(element, op, key, value){
|
||||||
|
if(element instanceof HTMLElement)
|
||||||
|
return element[op+"Attribute"](key, value);
|
||||||
|
return element[op+"AttributeNS"](null, key, value);
|
||||||
|
}
|
||||||
import { isUndef } from "./helpers.js";
|
import { isUndef } from "./helpers.js";
|
||||||
//TODO add cache? `(Map/Set)<el.tagName+key,isUndef>`
|
//TODO add cache? `(Map/Set)<el.tagName+key,isUndef>`
|
||||||
function isPropSetter(el, key){
|
function isPropSetter(el, key){
|
||||||
|
@ -85,7 +85,7 @@ S.clear= function(...signals){
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const key_reactive= "__dde_reactive";
|
const key_reactive= "__dde_reactive";
|
||||||
import { el } from "./dom.js";
|
import { el, elementAttribute } from "./dom.js";
|
||||||
import { scope } from "./dom.js";
|
import { scope } from "./dom.js";
|
||||||
S.el= function(signal, map){
|
S.el= function(signal, map){
|
||||||
const mark_start= el.mark({ type: "reactive" }, false);
|
const mark_start= el.mark({ type: "reactive" }, false);
|
||||||
@ -113,9 +113,20 @@ S.el= function(signal, map){
|
|||||||
};
|
};
|
||||||
import { on } from "./events.js";
|
import { on } from "./events.js";
|
||||||
const key_attributes= "__dde_attributes";
|
const key_attributes= "__dde_attributes";
|
||||||
S.fromAttribute= function(element, name, value){
|
S.attribute= function(name, initial= null){
|
||||||
if(!element[key_attributes]){ // needs registration
|
//TODO host=element & reuse existing
|
||||||
element[key_attributes]= {};
|
const out= S(initial);
|
||||||
|
let element;
|
||||||
|
scope.host(el=> {
|
||||||
|
element= el;
|
||||||
|
if(elementAttribute(element, "has", name)) out(elementAttribute(element, "get", name));
|
||||||
|
else if(initial!==null) elementAttribute(element, "set", name, initial);
|
||||||
|
|
||||||
|
if(el[key_attributes]){
|
||||||
|
el[key_attributes][name]= out;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
element[key_attributes]= { [name]: out };
|
||||||
on.attributeChanged(function attributeChangeToSignal({ detail }){
|
on.attributeChanged(function attributeChangeToSignal({ detail }){
|
||||||
/*! This maps attributes to signals (`S.attribute`).
|
/*! This maps attributes to signals (`S.attribute`).
|
||||||
* Investigate `__dde_attributes` key of the element.*/
|
* Investigate `__dde_attributes` key of the element.*/
|
||||||
@ -128,14 +139,12 @@ S.fromAttribute= function(element, name, value){
|
|||||||
* Investigate `__dde_attributes` key of the element.*/
|
* Investigate `__dde_attributes` key of the element.*/
|
||||||
S.clear(...Object.values(element[key_attributes]));
|
S.clear(...Object.values(element[key_attributes]));
|
||||||
})(element);
|
})(element);
|
||||||
}
|
});
|
||||||
const store= element[key_attributes];
|
|
||||||
const out= Reflect.has(store, name) ? Reflect.get(store, name) : (store[name]= S(value));
|
|
||||||
return new Proxy(out, {
|
return new Proxy(out, {
|
||||||
apply(target, _, args){
|
apply(target, _, args){
|
||||||
if(!args.length) return target();
|
if(!args.length) return target();
|
||||||
const value= args[0];
|
const value= args[0];
|
||||||
return element.setAttribute(name, value);
|
return elementAttribute(element, "set", name, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user