UNPKG

x-widget

Version:

Adds the ability to define reusable Widgets (WebComponents) using Alpinejs.

6 lines (3 loc) 5.43 kB
var _=t=>t.replace(/[a-z][A-Z]/g,r=>r[0]+"-"+r[1].toLowerCase());function w(t){let r=this,n=Object.entries(Object.getOwnPropertyDescriptors(t));return(e,o)=>{let s=k(e);console.assert(s,"widget not found");let i=Array.from(s.attributes).filter(c=>c.name.startsWith("x-prop:")).map(({name:c})=>c.substr(7)),a=new MutationObserver(c=>{c.forEach(({attributeName:d,target:g})=>{p(d,g.getAttribute(d))})});a.observe(s,{attributes:!0,attributeFilter:Object.keys(t).map(_),attributeOldValue:!1});let u=Object.fromEntries(n.filter(([c])=>!i.includes(c))),l=r.reactive(Object.assign(Object.create(Object.getPrototypeOf(t),u),{destroy(){a.disconnect()}})),f=[...s.attributes];for(let c of Object.getOwnPropertyNames(t)){let d=f.find(g=>g.name.match(new RegExp(`^((x-(bind|prop))?:)?${_(c)}$`)));!d||(d.name.startsWith("x-prop:")?Object.defineProperty(l,c,{configurable:!0,enumerable:!0,get(){return o[c]},set(g){o[c]=g}}):p(c,s.getAttribute(_(c))))}function p(c,d){let g=t[c];if(typeof g=="boolean")d===""?l[c]=!0:d==="false"?l[c]=!1:l[c]=!!d;else if(typeof g=="number")l[c]=parseFloat(d);else if(typeof g=="string")l[c]=d;else throw new Error("unsupported static attribute: "+c)}return l}}function k(t){for(;t&&!t.tagName.includes("-");)t=t.parentElement;return t}function S(t,r,n){return t._x_dataStack=[r,...h(n||t)],()=>{t._x_dataStack=t._x_dataStack.filter(e=>e!==r)}}function h(t){return t._x_dataStack?t._x_dataStack:typeof ShadowRoot=="function"&&t instanceof ShadowRoot?h(t.host):t.parentNode?h(t.parentNode):[]}function y(t){let r=new Proxy({},{ownKeys:()=>Array.from(new Set(t.flatMap(n=>Object.keys(n)))),has:(n,e)=>t.some(o=>o.hasOwnProperty(e)),get:(n,e)=>(t.find(o=>{if(o.hasOwnProperty(e)){let s=Object.getOwnPropertyDescriptor(o,e);if(s.get&&s.get._x_alreadyBound||s.set&&s.set._x_alreadyBound)return!0;if((s.get||s.set)&&s.enumerable){let i=s.get,a=s.set,u=s;i=i&&i.bind(r),a=a&&a.bind(r),i&&(i._x_alreadyBound=!0),a&&(a._x_alreadyBound=!0),Object.defineProperty(o,e,{...u,get:i,set:a})}return!0}return!1})||{})[e],set:(n,e,o)=>{let s=t.find(i=>i.hasOwnProperty(e));return s?s[e]=o:t[t.length-1][e]=o,!0}});return r}function E(t,r,n,...e){try{return n(...e)}catch(o){m(o,t,r)}}function m(t,r,n=void 0){Object.assign(t,{el:r,expression:n}),console.warn(`Alpine Expression Error: ${t.message} ${n?'Expression: "'+n+`" `:""}`,r),setTimeout(()=>{throw t},0)}function x(t,r){let n=h(t),e=N(n,r,t);return E.bind(null,t,r,e)}function N(t,r,n){let e=C(r,n);return(o=()=>{},{scope:s={}}={})=>{e.result=void 0,e.finished=!1;let i=y([s,...t]);if(typeof e=="function"){let a=e(e,i).catch(u=>m(u,n,r));e.finished?(o(O(e.result,i)),e.result=void 0):a.then(u=>O(u,i)).catch(u=>m(u,n,r)).finally(()=>e.result=void 0)}}}function O(t,r){return typeof t=="function"?t.bind(r):t}var b={};function C(t,r){if(b[t])return b[t];let n=Object.getPrototypeOf(async function(){}).constructor,e=/^[\n\s]*if.*\(.*\)/.test(t)||/^(let|const)\s/.test(t)?`(() => { ${t} })()`:t,s=(()=>{try{return new n(["__self","scope"],`with (scope) { __self.result = ${e} }; __self.finished = true; return __self.result;`)}catch(i){return m(i,r,t),Promise.resolve()}})();return b[t]=s,s}var D=t=>t.replace(/-([a-zA-Z])/g,r=>r[1].toUpperCase()+r.substr(2));function v(t,{value:r,expression:n},{cleanup:e}){let o=D(r),s=x(n===o?t.parentElement:t,n),i,a=T(t,n)?x(t.parentElement,`${n} = __`):(f,{scope:{__:p}})=>i=p,u={};Object.defineProperty(u,o,{get(){let f;return typeof i!="undefined"?i:(s(p=>f=p),f)},set(f){o!=="value"&&(t[o]=f),a(()=>{},{scope:{__:f}})}}),o!=="value"&&(t[o]=u[o]);let l=S(t,u);e(()=>l())}function T(t,r){try{let n=y(h(t));return new Function("scope",`with(scope) {${r} = ${r}}`)(n),!0}catch{return!1}}function P(t){for(;t&&!t._x_slots;)t=t.parentElement;return t?._x_slots}function j(t,{expression:r,modifiers:n},{Alpine:e}){let o=r;if(window.customElements.get(o))return;if(n[0]){let i=document.createElement("style");i.innerHTML=`${o} { display: ${n[0]}}`,document.head.appendChild(i)}e._widgets?e._widgets.push(o):e._widgets=[o];let s=t.content.firstElementChild;window.customElements.define(o,class extends HTMLElement{constructor(){super();this._slotFills=null}connectedCallback(){let i;this._slotFills?i=this._slotFills:(i=A(this),this._slotFills=i);let a=s.cloneNode(!0);this._x_slots=Object.fromEntries([...i.entries()].map(([l,f])=>[l,f]));let u=F(a);for(let l of u){let f=l.name||"default",p=i.get(f);p?l.replaceWith(...p.map(c=>c.cloneNode(!0))):l.replaceWith(...l.childNodes)}requestAnimationFrame(()=>{for(;this.firstChild;)this.removeChild(this.firstChild);this.appendChild(a)}),this.dispatchEvent(new CustomEvent("x-widget:connected",{bubbles:!0}))}})}function F(t){let r=[...t.querySelectorAll("slot")];t.tagName==="SLOT"&&r.unshift(t);let n=t.querySelectorAll("template");for(let e of n)if(!e.getAttribute("x-widget"))for(let o of e.content.children)r.push(...F(o));return r}function A(t){let r=new Map;function n(e,o){r.has(e)?r.get(e).push(...o):r.set(e,o)}for(let e of t.childNodes)if(e.tagName==="TEMPLATE"){let o=e.getAttribute("slot"),s=!o&&(e.getAttribute("x-for")||e.getAttribute("x-if"));n(o||"default",s?[e]:[...e.content.childNodes])}else(e.nodeType!==Node.TEXT_NODE||e.textContent.trim())&&n("default",[e]);return r}function G(t){t.magic("slots",P),t.directive("widget",j),t.directive("prop",v),t.data("xWidget",w.bind(t))}export{G as default,P as slotsMagic,v as xPropDirective,w as xWidgetData,j as xWidgetDirective};