UNPKG

alpinejs-component

Version:

Directive-based Alpine.js components with Shadow DOM encapsulation, slots, and cached template rendering

4 lines (3 loc) 4.27 kB
function C(o=100){let n=new Map;return n.maxEntries=o,n}function y(o,n,t){for(o.set(n,t);o.size>o.maxEntries;){let c=o.keys().next().value;o.delete(c)}}var T=C(200),S=C(200),g=C(100);function I(o){if(!o)return!0;try{return new URL(o,window.location.href).origin===window.location.origin}catch{return!1}}function b(o,n=new Set){if(!o||n.has(o))return"";n.add(o);try{return[...o.cssRules].map(t=>typeof CSSImportRule<"u"&&t instanceof CSSImportRule?b(t.styleSheet,n):typeof CSSStyleRule<"u"&&t instanceof CSSStyleRule&&t.selectorText===":root"?"":t.cssText).filter(Boolean).join(` `)}catch{return""}}function v(o,n){let t=[...new Set(n.map(d=>d.trim()).filter(Boolean))];if(!t.length)return;let c=t.slice().sort().join(",");if(!g.has(c)){let e=(t.includes("global")?[...document.styleSheets]:[...document.styleSheets].filter(({title:r})=>t.includes(r))).filter(({href:r})=>I(r)).map(r=>b(r)).join(` `),l=new CSSStyleSheet;l.replaceSync(e),y(g,c,l)}o.adoptedStyleSheets=[g.get(c)]}function F(o){let n=document.createElement("template");return n.innerHTML=o,n.content}function $(o,{allowCrossOrigin:n=!1}={}){let t=(o||"").trim();if(!t.length)return"";let c;try{c=new URL(t,window.location.href)}catch{throw new Error(`Invalid URL for x-component.url: ${t}`)}if(!["http:","https:"].includes(c.protocol))throw new Error(`Unsupported URL protocol for x-component.url: ${c.protocol}`);if(!n&&c.origin!==window.location.origin)throw new Error(`Cross-origin URL blocked for x-component.url: ${c.href}`);return c.href}function L(o){let n=(o||"").trim();if(!n.length)return null;if(!T.has(n)){let t=document.getElementById(n);if(!t)return console.warn(`[alpinejs-component] Missing template: "${n}"`),null;y(T,n,F(t.innerHTML))}return T.get(n).cloneNode(!0)}async function j(o,n={}){let t=$(o,n);if(!t.length)return null;S.has(t)||y(S,t,fetch(t).then(c=>{if(!c.ok)throw new Error(`Request failed (${c.status}) for ${t}`);return c.text()}));try{let c=await S.get(t);return F(c).cloneNode(!0)}catch(c){throw S.delete(t),c}}function _(o){function n(e,l){if(!e)return"";try{let r=l(e);return typeof r=="string"?r.trim():r===null||typeof r>"u"?"":String(r)}catch(r){return console.error(`[alpinejs-component] Failed to evaluate expression: ${e}`,r),{value:"",error:r}}}function t(e){return(e.getAttribute("x-component-styles")||e.getAttribute("styles")||"").split(",").map(r=>r.trim()).filter(Boolean)}function c(e,l,r={}){e.dispatchEvent(new CustomEvent(l,{bubbles:!0,composed:!0,detail:r}))}function d(e){let l=e._x_componentSlots||[];for(let r of l)r.nodeType===Node.ELEMENT_NODE&&o.destroyTree(r),r.remove();e._x_componentSlots=[]}function x(e){d(e);let l=[...e.querySelectorAll(":scope > template[x-slot]")];if(!l.length)return;let r=[];for(let i of l){let h=(i.getAttribute("x-slot")||"").trim(),w=i.content.cloneNode(!0),u=[...w.childNodes];if(h.length)for(let a of u)a.nodeType===Node.ELEMENT_NODE&&a.setAttribute("slot",h);i.after(w),r.push(...u)}for(let i of r)i.nodeType===Node.ELEMENT_NODE&&o.initTree(i);e._x_componentSlots=r}o.directive("component",(e,{expression:l,modifiers:r},{effect:i,cleanup:h,evaluate:w})=>{let u=0,a=!1;i(()=>{let f=n(l,w),s=typeof f=="string"?f:f.value;if(typeof f=="object"&&f.error&&c(e,"x-component:error",{source:l,error:f.error}),!s.length){d(e),e.shadowRoot&&a&&(o.destroyTree(e.shadowRoot),e.shadowRoot.replaceChildren(),a=!1);return}let E=++u;(async()=>{let N=r.includes("url");try{N&&c(e,"x-component:loading",{source:s});let p=N?await j(s,{allowCrossOrigin:r.includes("external")}):L(s);if(E!==u)return;if(!p){let R=new Error(`Component source resolved but no fragment was returned: ${s}`);d(e),e.shadowRoot&&a&&(o.destroyTree(e.shadowRoot),e.shadowRoot.replaceChildren(),a=!1),console.error(`[alpinejs-component] Failed to render component: ${s}`,R),c(e,"x-component:error",{source:s,error:R});return}let m=e.shadowRoot||e.attachShadow({mode:"open"});a&&o.destroyTree(m),o.addScopeToNode(m,{},e),x(e),m.replaceChildren(p);let U=t(e);U.length&&v(m,U),o.initTree(m),a=!0,c(e,"x-component:loaded",{source:s})}catch(p){console.error(`[alpinejs-component] Failed to render component: ${s}`,p),c(e,"x-component:error",{source:s,error:p})}})()}),h(()=>{u+=1,d(e),e.shadowRoot&&a&&o.destroyTree(e.shadowRoot)})})}var A=_;export{A as default};