Created
November 15, 2022 07:40
-
-
Save rndme/487634e3fd861dd67144be8cdc770694 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function wc(name, def) { // webcomponent wrapper by dandavis. MIT. | |
const PROPS = Object.keys(def.props || {}); | |
class wcMaker extends HTMLElement { | |
constructor() { | |
super(); | |
console.info("constrtr", this.constructor); | |
const shadow = this.attachShadow({ | |
mode: "open" | |
}); | |
shadow.appendChild(document.createElement("style")); | |
this.root = shadow.appendChild(document.createElement("root")); | |
PROPS.forEach(key => { | |
if (!this.hasAttribute(key)) { | |
this.setAttribute(key, def.props[key] === false ? "" : def.props[key]); | |
} | |
Object.defineProperty(this, key, { | |
get() { | |
return this.getAttribute(key); | |
}, | |
set(v) { | |
this.setAttribute(key, v === false ? "" : v); | |
} | |
}); | |
}, this); | |
Object.keys(def.events || {}).forEach(type => { | |
this.addEventListener(type, def.events[type]); | |
}, this); | |
def.create?.call(this, { | |
target: this, | |
type: "create", | |
detail: def | |
}); | |
} | |
connectedCallback(e) { | |
this.initialContent = this.innerHTML; | |
if (def.content) this.shadowRoot.children[1].innerHTML = def.content; | |
if (def.css) this.shadowRoot.children[0].textContent = def.css; | |
def.insert?.apply(this, arguments); | |
} | |
attributeChangedCallback(name, was, is) { | |
if (this[name] != is) this[name] = is; | |
def.change?.apply(this, arguments); | |
this.raise("change", {name, was, is}); | |
} | |
disconnectedCallback(e) { | |
def.remove?.apply(this, arguments); | |
} | |
adoptedCallback(e) { | |
def.adopt?.apply(this, arguments); | |
} | |
static get observedAttributes() { | |
return PROPS; | |
} | |
raise(name, details) { | |
this.dispatchEvent(new CustomEvent(name, { | |
detail: details || {} | |
})); | |
return this; | |
} | |
} //end class wcMaker | |
customElements.define("wc-" + name, wcMaker); | |
} | |
/* | |
// simple demo using most of the supported features: | |
// <wc-test id=test1 dan=Testing>Nobody</wc-test> | |
wc("test", { | |
create: console.info.bind(console, "Custom Element created"), | |
remove: console.info.bind(console, "Custom Element removed from page"), | |
change: function() { | |
this.root.innerHTML = "Hello " + this.dan | |
}, | |
css: `root { color: red; }`, | |
content: "Hello World", | |
props: { | |
dan: 101 | |
}, | |
events: { | |
klick: function(e) { | |
this.setAttribute("dan", e.detail + Math.random()); | |
//this.dan = Math.random(); // works too | |
}, | |
click: function() { | |
this.raise("klick", "WooHoo"); | |
}, | |
change: function(e){ // optional catch-all attr change userland event | |
console.log("elmement changed", e); | |
} | |
} | |
}); | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment