Skip to content

Instantly share code, notes, and snippets.

@50kudos
Last active October 9, 2022 14:09
Show Gist options
  • Save 50kudos/be77d465fc3df875400b587d1cc24f05 to your computer and use it in GitHub Desktop.
Save 50kudos/be77d465fc3df875400b587d1cc24f05 to your computer and use it in GitHub Desktop.
Custom elements compose nested props (https://jsfiddle.net/2L5ypn9a/2/)
button { margin: .5rem; }
input { display: inline-block; margin: 0 .5rem; }
stack-btns+span {display: block}
<body>Dots: <stack-show></stack-show> </body>
const define = (name, ctx, events, opts = {}) => {
const l = { handleEvent: e => {
ctx.e = e; const act = events[e.type]; if (!act) return
typeof act == "function" ? act(ctx) : act.find(c => e.target.matches(c[0]))?.[1](ctx)
} }
const off = self => self.off.forEach(d => d())
const on = (self, events) => {
self.off = Object.entries(events).map(([k, _]) => {
self.addEventListener(k, l)
return () => self.removeEventListener(k, l)
})}
if (customElements.get(name))
for (let el of document.querySelectorAll(name)) { off(el); on(el, events) }
else
customElements.define(name, class extends HTMLElement {
connectedCallback() { on(this, events) }
disconnectedCallback() { off(this) }
})
}
const mount = (s,html) => document.querySelector(s).innerHTML = html
const show = (stack,ch) => mount("stack-show", `<stack-btns></stack-btns><span>${stack.map(a => `<span>${ch || a.text}</span>`).join("")}</span>`)
const btns = (stack,ch) => mount("stack-btns", `<button data-cmd="add">+</button>${stack.length}<button data-cmd="rm">-</button>*<input value="${ch}">`)
define("stack-show", {ch: ".", stack: [], views: {show, btns}}, {"click": [
["[data-cmd=add]", ctx => { ctx.stack.push({text: "."}); ctx.render(ctx.stack, ctx.ch) }],
["[data-cmd=rm]", ctx => { ctx.stack.pop(); ctx.render(ctx.stack, ctx.ch) }]
],
"init": ctx => { let {stack, views} = ctx;
ctx.render = (stack,ch=".") => {views.show(stack,ch); views.btns(stack, ch)}
define("stack-btns", ctx, {"input": ({stack,e}) => Object.assign(ctx, {ch:e.target.value}) && ctx.render(stack, ctx.ch)})
ctx.render(stack)
}})
document.querySelector("stack-show").dispatchEvent(new CustomEvent("init"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment