@blossom-carousel/web
Version:
A native-scroll-first carousel component for the web.
2 lines (1 loc) • 8.01 kB
JavaScript
(function(d,a){typeof exports=="object"&&typeof module<"u"?a(exports):typeof define=="function"&&define.amd?define(["exports"],a):(d=typeof globalThis<"u"?globalThis:d||self,a(d.BlossomCarousel={}))})(this,function(d){"use strict";var Ce=Object.defineProperty;var Pe=(d,a,I)=>a in d?Ce(d,a,{enumerable:!0,configurable:!0,writable:!0,value:I}):d[a]=I;var pe=(d,a,I)=>(Pe(d,typeof a!="symbol"?a+"":a,I),I);const a=(t,h)=>{let B=!0;const m={x:0,y:0},i={x:0,y:0},u={x:0,y:0},V=new Proxy({x:0,y:0},{set(e,n,l){return e[n]===l||(e[n]=l,(e.x>=10||e.y>=10)&&A(!0)),!0}}),s=new Proxy({x:!1,y:!1},{set(e,n,l){return e[n]===l||(e[n]=l,e.x||e.y?(t.setAttribute("has-overflow","true"),t.addEventListener("pointerdown",ne),t.addEventListener("wheel",re,{passive:!1})):(t.removeAttribute("has-overflow"),t.removeEventListener("pointerdown",ne),t.removeEventListener("wheel",re))),!0}});let w=300,b=null,f=!1,y=300,p=300,Q=300,Z=300;const D={start:0,end:0},F={start:0,end:0};let q=[],W=null,O=null,R=null,Y=!1,H,g=1,E={target:null,x:0};function xe(){t==null||t.setAttribute("blossom-carousel","true"),W=(t==null?void 0:t.querySelectorAll("a[href]"))||null,W==null||W.forEach(l=>{l.addEventListener("click",_)}),window.addEventListener("keydown",se),t.addEventListener("scroll",te),O=new ResizeObserver(ee),O.observe(t),R=new MutationObserver(ye),R.observe(t,{attributes:!1,childList:!0,subtree:!1});const e=window.matchMedia("(hover: hover) and (pointer: fine)").matches;g=t.closest('[dir="rtl"]')?-1:1;const{scrollSnapType:n}=window.getComputedStyle(t);Y=n!=="none",t.style.setProperty("--snap-type",n),e&&(t.style["scroll-snap-type"]="none"),t.setAttribute("has-repeat",h!=null&&h.repeat?"true":"false"),H=Ae(l=>{(l===t||t.contains(l))&&A(!1)})}function he(){t.removeAttribute("blossom-carousel"),O==null||O.disconnect(),R==null||R.disconnect(),b&&cancelAnimationFrame(b),window.removeEventListener("keydown",se),t.removeEventListener("scroll",te),W==null||W.forEach(e=>{e.removeEventListener("click",_)}),H==null||H()}function _(e){V.x>10&&e.preventDefault()}function ee(){if(!t)return;const e="ontouchmove"in window;y=t.scrollWidth,p=t.clientWidth,Q=t.scrollHeight,Z=t.clientHeight;const n=window.getComputedStyle(t);s.x=!e&&y>p&&["auto","scroll"].includes(n.getPropertyValue("overflow-x")),s.y=!e&&Q>Z&&["auto","scroll"].includes(n.getPropertyValue("overflow-y")),D.end=parseInt(n.paddingInlineEnd)||0,D.start=parseInt(n.paddingInlineStart)||0,F.start=parseInt(n.scrollPaddingInlineStart)||0,F.end=parseInt(n.scrollPaddingInlineEnd)||0,g=t.closest('[dir="rtl"]')?-1:1,w=(y-p-4)*g,q=Y?ve(t):[],h!=null&&h.repeat&&$(null,null)}function ye(){ee()}function ve(e){let n=[],l=0;const c=o=>{if(l++,l>100)return;const v=window.getComputedStyle(o).scrollSnapAlign;if(v!=="none"){n.push({align:v,el:o});return}const S=o.children;if(S.length!==0)for(let k of S)c(k)};c(e);const J=e.getBoundingClientRect();return n.map(({el:o,align:v},S)=>{const k=o.getBoundingClientRect(),x=o.clientWidth,M=k.left-J.left+e.scrollLeft;switch(v){case"start":return{target:o,x:M-F.start};case"end":return{target:o,x:M+x-p+F.end};case"center":return{target:o,x:M+x*.5-p/2};default:return null}}).filter(o=>o!==null).reduce((o,v)=>((o.length===0||o[o.length-1].x!==v.x)&&o.push(v),o),[])}function te(){if(h!=null&&h.repeat){$(null,null);return}if(f||!t)return;const e=t.scrollLeft;if(e<0){const n=e*-1;U(n)}else if(e>y-p){const n=e*-1+y-p;U(n)}}const r={x:0,y:0};function ne(e){t&&(s.x&&(r.x=t.scrollLeft,m.x=e.clientX,u.x=0),s.y&&(r.y=t.scrollTop,m.y=e.clientY,u.y=0),V.x=0,f=!0,window.addEventListener("pointermove",le),window.addEventListener("pointerup",oe))}function le(e){if(e.preventDefault(),s.x){const n=m.x-e.clientX;i.x+=n,u.x+=n,m.x=e.clientX,V.x+=Math.abs(n)}if(s.y){const n=m.y-e.clientY;i.y+=n,u.y+=n,m.y=e.clientY,V.y+=Math.abs(n)}}function oe(){window.removeEventListener("pointermove",le),window.removeEventListener("pointerup",oe),f=!1,!(V.x<=10)&&(s.x&&(u.x*=2),s.y&&(u.y*=2),me(),Ie())}function re(e){if(Math.abs(e.deltaX)>Math.abs(e.deltaY)){if(A(!1),f||!t)return;s.x&&(r.x=t.scrollLeft),s.y&&(r.y=t.scrollTop)}}function se(e){["ArrowLeft","ArrowRight","ArrowUp","ArrowDown"].includes(e.key)&&A(!1)}function me(){const e=de({axis:"x"});e.x!==E.x&&ue(e),E=e;const n=(fe(e.x,Math.min((y-p)*g,0),Math.max((y-p)*g,0))-i.x)*(1-L)*(1/L);u.x=n}function $(e,n){if(!t)return;const l=n??t.scrollLeft,c=D.start-l,J=l-(y-p-D.end),o=Array.from(t.children);let v=0;for(let x=o.length-1;x>=o.length/2;x--){const M=v>c?0:-(y-p);v+=o[x].clientWidth,o[x].style.translate=`${M}px 0`}let S=0;for(let x=0;x<o.length/2;x++){const M=S>J?0:y-p;S+=o[x].clientWidth,o[x].style.translate=`${M}px 0`}if(f)return;const k=l>w?4:l<4?w:null;k&&(P=!0,t.scrollTo({left:k,behavior:"instant"}))}function ie(e){z&&e.stopPropagation()}const L=.72,j=.12;let z=!1;function A(e){t&&(e&&!z?(N=performance.now(),s.x&&(i.x=t.scrollLeft),s.y&&(i.y=t.scrollTop),t.addEventListener("scrollend",ie,{capture:!0,passive:!1}),b||(b=requestAnimationFrame(ce))):e||(b&&cancelAnimationFrame(b),b=null,t.removeEventListener("scrollend",ie)),z=e,B=!e,t.setAttribute("has-snap",B?"true":"false"))}let T=0,N=0;function ce(e){if(b=requestAnimationFrame(ce),T=e-N,!!t){if(s.x&&(u.x*=L,f?r.x=X(r.x,i.x,L,T):(i.x+=u.x,r.x=X(r.x,i.x,j,T))),s.y&&(u.y*=L,f?r.y=X(r.y,i.y,L,T):(i.y+=u.y,r.y=X(r.y,i.y,j,T))),h!=null&&h.repeat&&(r.x>w&&(r.x=i.x=4),r.x<4&&(r.x=i.x=w)),P=!0,t.scrollTo({left:r.x,top:r.y,behavior:"instant"}),f&&Y){const n=de({axis:"x"});n.x!==E.x&&(E=n,ue(n))}!f&&G(u.x,8)===0&&(A(!1),be(),Y&&ge()),h!=null&&h.repeat?$(null,r.x):we(G(r.x,2)),N=e}}let C=0;function we(e){if(!t)return;const n=w;let l=0;if(e*g<=0?l=f?e*-.2:0:e*g>n*g&&(l=f?(e-n)*-.2:0),C=X(C,l,f?.8:j,T),Math.abs(C)>.01){if(U(C).defaultPrevented)return;t.style.transform=`translateX(${G(C,3)}px)`;return}t.style.transform="",C=0}function U(e){const n=new CustomEvent("overscroll",{bubbles:!0,cancelable:!0,detail:{left:e}});return t==null||t.dispatchEvent(n),n}const ae=new Event("scrollend",{bubbles:!0,cancelable:!0});function be(){return t==null||t.dispatchEvent(ae),ae}function ge(){const e=new CustomEvent("scrollsnapchange",{bubbles:!0,cancelable:!0,detail:{snapTargetInline:E.target,snapTargetBlock:E.target}});return t==null||t.dispatchEvent(e),e}function ue(e){const n=new CustomEvent("scrollsnapchanging",{bubbles:!0,cancelable:!0,detail:{snapTargetInline:(e||E).target,snapTargetBlock:(e||E).target}});return t==null||t.dispatchEvent(n),n}let P=!1;const Ee=t.scrollTo.bind(t);t.scrollTo=function(e){P===!0||A(!1),P=!1,Ee(e)};const Le=t.scrollBy.bind(t);t.scrollBy=function(e){P===!0||A(!1),P=!1,Le(e)};function Ae(e){const n=[],l=Element.prototype.scrollIntoView;return l&&(Element.prototype.scrollIntoView=function(c){return e(this,"scrollIntoView",[c]),l.call(this,c)},n.push(()=>{Element.prototype.scrollIntoView=l})),()=>n.forEach(c=>c())}function Me({axis:e="x"}){return i[e]+u[e]/(1-L)}function de({axis:e="x"}){const n=Me({axis:e});return q.length?q.reduce((l,c)=>Math.abs(c.x-n)<Math.abs(l.x-n)?c:l):{target:null,x:fe(n,Math.min(w,0),Math.max(w,0))}}function Ie(){const e=n=>{n.preventDefault(),n.stopPropagation(),window.removeEventListener("click",e,!0)};window.addEventListener("click",e,!0)}function Te(e,n,l){return(1-l)*e+l*n}function X(e,n,l,c){return Te(e,n,1-Math.exp(Math.log(1-l)*(c/16.666666666666668)))}function fe(e,n,l){return e<n?n:e>l?l:e}function G(e,n=0){const l=Math.pow(10,n);return Math.round(e*l)/l}return{snap:B,hasOverflow:s,init:xe,destroy:he}},I="";class K extends HTMLElement{constructor(){super();pe(this,"carouselInstance");const B=this.attachShadow({mode:"open"});this.setAttribute("blossom-carousel","true");const m=document.createElement("slot");B.appendChild(m)}connectedCallback(){this.carouselInstance=a(this,{repeat:this.hasAttribute("repeat")}),this.carouselInstance.init()}disconnectedCallback(){this.carouselInstance.destroy()}}customElements.define("blossom-carousel",K),d.BlossomCarousel=K,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});