@flexilla/alpine-offcanvas
Version:
AlpineJS plugin for adding offcanvas functionality to your AlpineJS components
2 lines (1 loc) • 9.82 kB
JavaScript
(()=>{var A=Object.defineProperty,$=(t,e,n)=>e in t?A(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,o=(t,e,n)=>$(t,typeof e!="symbol"?e+"":e,n),b=(t,e=document.body)=>e.querySelector(t),u=(t,e=document.body)=>Array.from(e.querySelectorAll(t)),S=({newElement:t,existingElement:e})=>{if(!(t instanceof HTMLElement)||!(e instanceof HTMLElement))throw new Error("Both parameters must be valid HTML elements.");let n=e.parentElement;if(n)n.insertBefore(t,e);else throw new Error("Existing element must have a parent element.")},H=({element:t,callback:e,type:n,keysCheck:s})=>{let a=getComputedStyle(t),i=a.transition;if(i!=="none"&&i!==""&&!s.includes(i)){let r="transitionend",h=()=>{t.removeEventListener(r,h),e()};t.addEventListener(r,h,{once:!0})}else e()},N=({element:t,callback:e})=>{H({element:t,callback:e,type:"transition",keysCheck:["all 0s ease 0s","all"]})},E=(t,e,n)=>{let s=new CustomEvent(e,{detail:n});t.dispatchEvent(s)};function M(t){let e=()=>{document.querySelector("[data-fx-component]:not([data-component-initialized])")?requestAnimationFrame(e):t()};e()}var L="data-fx-teleport-root",C="data-fx-teleported",D={append:()=>{},remove:()=>{},restore:()=>{}};function W(t,e,n="move"){var s;if(!(t instanceof HTMLElement))throw new Error("Source element must be an HTMLElement");if(!(e instanceof HTMLElement))throw new Error("Target element must be an HTMLElement");if(!["move","detachable"].includes(n))throw new Error(`Invalid teleport mode: ${n}. Must be "move" or "detachable".`);if((s=t.parentElement)!=null&&s.closest(`[${L}]`))return D;t.setAttribute(L,"");let a=document.createComment("teleporter-placeholder"),i=t.parentNode;return i&&i.insertBefore(a,t),n==="move"?(t.parentNode&&(e.appendChild(t),t.setAttribute(C,"")),{append(){t.parentNode!==e&&(e.appendChild(t),t.setAttribute(C,""))},remove(){a!=null&&a.parentNode&&t.parentNode&&a.parentNode.insertBefore(t,a)},restore(){a!=null&&a.parentNode&&t.parentNode!==i&&a.parentNode.insertBefore(t,a)}}):(t.parentNode&&(e.appendChild(t),t.setAttribute(C,"")),{append(){e.contains(t)||e.appendChild(t)},remove(){t.parentNode&&t.remove()},restore(){a!=null&&a.parentNode&&!t.parentNode&&a.parentNode.insertBefore(t,a)}})}var q=t=>{var e;return(e=t.parentElement)==null?void 0:e.removeChild(t)},B=t=>{t.setAttribute("data-state","invisible"),N({element:t,callback(){q(t)}})},z=(t,e)=>{let n=t;if(n===""||!n)return;let s=document.createElement("div");if(s.setAttribute("aria-hidden","true"),s.setAttribute("data-state","visible"),s.setAttribute("data-fx-offcanvas-overlay",""),s.setAttribute("data-offcanvas-el",e),n==="")return;let a=n.split(" ");return n!==""&&s.classList.add(...a),s},k=(t,e,n)=>{t.setAttribute("aria-hidden",n==="open"?"false":"true"),t.setAttribute("data-state",n),e||F(n)},F=t=>{document.body.style.overflow=t==="open"?"hidden":"",document.body.style.overflowY=t==="open"?"hidden":"auto"},G=(t,e)=>{if(t===e)return;t.setAttribute("aria-hidden","true"),t.setAttribute("data-state","close");let n=b(`[data-fx-offcanvas-overlay][data-offcanvas-el=${t.getAttribute("id")}]`,t.parentElement);n instanceof HTMLElement&&B(n)},R=t=>{let e=u("[data-fx-offcanvas][data-state=open]");if(!(e.length<=0))for(let n of e)G(n,t)},f=class{static initGlobalRegistry(){window.$flexillaInstances||(window.$flexillaInstances={})}static register(e,n,s){return this.initGlobalRegistry(),window.$flexillaInstances[e]||(window.$flexillaInstances[e]=[]),this.getInstance(e,n)||(window.$flexillaInstances[e].push({element:n,instance:s}),s)}static getInstance(e,n){var s,a;return this.initGlobalRegistry(),(a=(s=window.$flexillaInstances[e])==null?void 0:s.find(i=>i.element===n))==null?void 0:a.instance}static removeInstance(e,n){this.initGlobalRegistry(),window.$flexillaInstances[e]&&(window.$flexillaInstances[e]=window.$flexillaInstances[e].filter(s=>s.element!==n))}static setup(e){e.setAttribute("data-fx-component","fx")}static initialized(e){e.setAttribute("data-component-initialized","initialized")}},d=class{constructor(e,n={}){o(this,"offCanvasElement"),o(this,"offCanvasTriggers"),o(this,"offCanvasCloseBtns"),o(this,"offCanvasId",""),o(this,"dispatchEventToDocument"),o(this,"allowBodyScroll"),o(this,"staticBackdrop"),o(this,"backdrop"),o(this,"options"),o(this,"teleporter"),o(this,"moveElOnInit",()=>{M(()=>this.teleporter.append())}),o(this,"closeWhenClickOutSide",l=>{let v=this.offCanvasElement.getAttribute("data-state")==="open",m=!this.offCanvasElement.contains(l.target)&&![...this.offCanvasTriggers].includes(l.target);v&&m&&this.closeOffCanvas()}),o(this,"closeOffCanvas",()=>{var l,v,m,w,g;let y=!1;if(E(this.offCanvasElement,"offcanvas-before-hide",{offcanvasId:this.offCanvasElement.id,setExitAction:T=>{y=T}}),((m=(v=(l=this.options).beforeHide)==null?void 0:v.call(l))==null?void 0:m.cancelAction)||y)return;let x=this.offCanvasElement.getAttribute("id"),p=b(`[data-fx-offcanvas-overlay][data-offcanvas-el=${x}]`);p instanceof HTMLElement&&B(p),this.offCanvasElement.blur(),k(this.offCanvasElement,this.allowBodyScroll,"close"),document.removeEventListener("keydown",this.closeWithEsc),!this.allowBodyScroll&&!p&&document.removeEventListener("click",this.closeWhenClickOutSide),(g=(w=this.options).onHide)==null||g.call(w),E(this.offCanvasElement,"offcanvas-close",{offcanvasId:this.offCanvasElement.id})}),o(this,"closeWithEsc",l=>{l.key==="Escape"&&(l.preventDefault(),this.closeOffCanvas())}),o(this,"closeFromCloseBtn",l=>{l.target.blur(),this.closeOffCanvas()}),o(this,"changeState",()=>{this.offCanvasElement.getAttribute("data-state")==="open"?this.closeOffCanvas():this.openOffCanvas()}),o(this,"open",()=>{this.openOffCanvas()}),o(this,"close",()=>{this.closeOffCanvas()}),o(this,"setOptions",({allowBodyscroll:l})=>{l!==void 0&&(this.allowBodyScroll=l)});let s=typeof e=="string"?b(e):e;if(!(s instanceof HTMLElement))throw new Error("Invalid Offcanvas, the provided Element is not a valid HTMLElement");this.offCanvasElement=s;let a=f.getInstance("offcanvas",s);if(a)return a;f.setup(this.offCanvasElement),this.options=n;let{staticBackdrop:i,allowBodyScroll:r,backdrop:h}=this.options;this.setupAttributes(),this.staticBackdrop=i||s.hasAttribute("data-static-backdrop")&&s.dataset.staticBackdrop!=="false"||!1,this.allowBodyScroll=r||s.hasAttribute("data-allow-body-scroll")&&s.dataset.allowBodyScroll!=="false"||!1;let c=this.offCanvasElement.getAttribute("id");if(!c||c==="")throw new Error("\u274C id is required but missing on element:");this.offCanvasId=c,this.offCanvasTriggers=this.findOffCanvasElements("[data-offcanvas-trigger]",!1,c),this.offCanvasCloseBtns=this.findOffCanvasElements("[data-offcanvas-close]",!0,c,this.offCanvasElement),this.backdrop=h||this.offCanvasElement.dataset.offcanvasBackdrop||"",this.dispatchEventToDocument=this.dispatchEventToDocument=this.options.dispatchEventToDocument||!0,this.teleporter=W(this.offCanvasElement,document.body,"move"),this.setupOffcanvas(),this.moveElOnInit(),f.register("offcanvas",this.offCanvasElement,this),f.initialized(this.offCanvasElement)}findOffCanvasElements(e,n,s,a){return n?u(`${e}`,a):u(`${e}[data-target=${s}]`)}setupAttributes(){this.offCanvasElement.hasAttribute("data-fx-offcanvas")||this.offCanvasElement.setAttribute("data-fx-offcanvas","")}openOffCanvas(){var e,n,s,a;(n=(e=this.options).beforeShow)==null||n.call(e),R(this.offCanvasElement),k(this.offCanvasElement,this.allowBodyScroll,"open");let i=this.offCanvasElement.getAttribute("id"),r=z(this.backdrop,i);r instanceof HTMLElement&&(S({newElement:r,existingElement:this.offCanvasElement}),this.staticBackdrop||r.addEventListener("click",this.closeOffCanvas)),document.addEventListener("keydown",this.closeWithEsc),(a=(s=this.options).onShow)==null||a.call(s),E(this.offCanvasElement,"offcanvas-open",{offcanvasId:this.offCanvasElement.id})}initCloseBtns(){for(let e of this.offCanvasCloseBtns)e.addEventListener("click",this.closeFromCloseBtn)}initTriggers(){for(let e of this.offCanvasTriggers)e.addEventListener("click",this.changeState)}setupOffcanvas(){this.initTriggers(),this.initCloseBtns(),this.dispatchEventToDocument&&document.addEventListener(`sheet:${this.offCanvasId}:open`,this.open),this.dispatchEventToDocument&&document.addEventListener(`sheet:${this.offCanvasId}:close`,this.close)}cleanup(){for(let e of this.offCanvasTriggers)e.removeEventListener("click",this.changeState);for(let e of this.offCanvasCloseBtns)e.removeEventListener("click",this.closeOffCanvas);document.removeEventListener("keydown",this.closeWithEsc),this.allowBodyScroll||document.removeEventListener("click",this.closeWhenClickOutSide),this.dispatchEventToDocument&&document.removeEventListener(`sheet:${this.offCanvasId}:open`,this.open),this.dispatchEventToDocument&&document.removeEventListener(`sheet:${this.offCanvasId}:close`,this.close),f.removeInstance("offcanvas",this.offCanvasElement)}};o(d,"autoInit",(t="[data-fx-offcanvas]")=>{let e=u(t);for(let n of e)new d(n)}),o(d,"init",(t,e={})=>new d(t,e));var I=d;function j(t){t.directive("offcanvas",(e,{},{cleanup:n})=>{let s=e.getAttribute("id");if(!s){console.error("\u274C id is required but missing on element:",e);return}let a=new I(e);t.store("sheets")||t.store("sheets",{}),t.store("sheets")[s]=a;let i=()=>a.open(),r=()=>a.close();document.addEventListener(`sheet:${s}:open`,i),document.addEventListener(`sheet:${s}:close`,r),n(()=>{document.removeEventListener(`sheet:${s}:open`,i),document.removeEventListener(`sheet:${s}:close`,r),a.cleanup(),delete t.store("sheets")[s]})}),t.magic("offcanvas",e=>n=>t.store("sheets")?t.store("sheets")[n]?t.store("sheets")[n]:(console.warn(`\u26A0\uFE0F No offcanvas instance found for ID: ${n}`),null):(console.warn("\u26A0\uFE0F Alpine store for Offcanvas is not initialized."),null))}var O=j;document.addEventListener("alpine:init",()=>{O(window.Alpine)});})();