x-widget
Version:
Adds the ability to define reusable Widgets (WebComponents) using Alpinejs.
2 lines (1 loc) • 1.59 kB
JavaScript
function p(e){for(;e&&!e._x_slots;)e=e.parentElement;return e?._x_slots}function g(e,{expression:l,modifiers:i},{Alpine:t}){let s=l;if(window.customElements.get(s))return;if(i[0]){let o=document.createElement("style");o.innerHTML=`${s} { display: ${i[0]}}`,document.head.appendChild(o)}t._widgets?t._widgets.push(s):t._widgets=[s];let c=e.content.firstElementChild;window.customElements.define(s,class extends HTMLElement{constructor(){super();this._slotFills=null}connectedCallback(){let o;this._slotFills?o=this._slotFills:(o=m(this),this._slotFills=o);let d=c.cloneNode(!0);this._x_slots=Object.fromEntries([...o.entries()].map(([n,r])=>[n,r]));let f=u(d);for(let n of f){let r=n.name||"default",a=o.get(r);a?n.replaceWith(...a.map(h=>h.cloneNode(!0))):n.replaceWith(...n.childNodes)}requestAnimationFrame(()=>{for(;this.firstChild;)this.removeChild(this.firstChild);this.appendChild(d)}),this.dispatchEvent(new CustomEvent("x-widget:connected",{bubbles:!0}))}})}function u(e){let l=[...e.querySelectorAll("slot")];e.tagName==="SLOT"&&l.unshift(e);let i=e.querySelectorAll("template");for(let t of i)if(!t.getAttribute("x-widget"))for(let s of t.content.children)l.push(...u(s));return l}function m(e){let l=new Map;function i(t,s){l.has(t)?l.get(t).push(...s):l.set(t,s)}for(let t of e.childNodes)if(t.tagName==="TEMPLATE"){let s=t.getAttribute("slot"),c=!s&&(t.getAttribute("x-for")||t.getAttribute("x-if"));i(s||"default",c?[t]:[...t.content.childNodes])}else(t.nodeType!==Node.TEXT_NODE||t.textContent.trim())&&i("default",[t]);return l}export{p as slotsMagic,g as xWidgetDirective};