Skip to content

Instantly share code, notes, and snippets.

@pwFoo
Forked from drodsou/custom-element-minimal.js
Created October 21, 2022 18:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pwFoo/4261e217e44706964d5de35dd2c014a0 to your computer and use it in GitHub Desktop.
Save pwFoo/4261e217e44706964d5de35dd2c014a0 to your computer and use it in GitHub Desktop.
minimal custom element - web component, webcomponent
/* non-shadow dom minimal custom element */
customElements.define("counter-ce", class extends HTMLElement {
connectedCallback() {
this.innerHTML = `
<button>
${this.innerHTML} <span></span>
</button>
`;
this.update = ()=>{
this.querySelector('span').innerHTML = eval(this.getAttribute('value'))
}
this.update();
eval(this.getAttribute('onload'));
}
// -- optional, if you need to listen on attribute changes
static get observedAttributes() { return ['value'] };
attributeChangedCallback (attr, oldValue, newValue) {
// first time, it triggers before element is initialized
if (this.update) this.update();
}
});
/* example using a global redux-like store
<counter-ce
value="window.store.state.counter"
onclick="window.store.dispatch('inc')"
onload="window.store.subscribe(this.update)"
>My button text</counter-ce>
*/
/* to syntax-sugar above */
function defineCE({tag,attr,html,update,onload, ...rest}) {
customElements.define(tag, class extends HTMLElement {
static get observedAttributes() { return attr };
attributeChangedCallback (attrName, oldValue, newValue) {
// first time, it triggers before element is initialized...
if (this.update) this.update();
}
connectedCallback() {
this.innerHTML = html.replace('<slot></slot>',this.innerHTML);
this.update = ()=>Object.entries(update||{}).forEach( ([selector,updater])=>{
updater(
this.querySelector(selector),
(attrName)=>eval(this.getAttribute(attrName))
)
});
Object.entries(rest).forEach( ([k,v])=>this[k] = v);
if (onload) { onload.call(this) }
eval(this.getAttribute('onload'))
this.update();
}
});
}
/* example */
defineCE({
tag: "counter-ce",
html:/*html*/`
<button>
<slot></slot> <span></span>
</button>
`,
update: {
'span' : (el,attr)=>el.innerHTML = attr('value'),
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment