@blossom-carousel/web
Version:
A native-scroll-first carousel component for the web.
2 lines (1 loc) • 7 kB
JavaScript
(function(f,u){typeof exports=="object"&&typeof module<"u"?u(exports):typeof define=="function"&&define.amd?define(["exports"],u):(f=typeof globalThis<"u"?globalThis:f||self,u(f.BlossomCarousel={}))})(this,function(f){"use strict";var Lt=Object.defineProperty;var Et=(f,u,L)=>u in f?Lt(f,u,{enumerable:!0,configurable:!0,writable:!0,value:L}):f[u]=L;var ct=(f,u,L)=>(Et(f,typeof u!="symbol"?u+"":u,L),L);const u=(e,h)=>{let k=!0;const m={x:0,y:0},i={x:0,y:0},d={x:0,y:0},S=new Proxy({x:0,y:0},{set(t,n,o){return t[n]===o||(t[n]=o,(t.x>=10||t.y>=10)&&A(!0)),!0}}),s=new Proxy({x:!1,y:!1},{set(t,n,o){return t[n]===o||(t[n]=o,t.x||t.y?(e.setAttribute("has-overflow","true"),e.addEventListener("pointerdown",_),e.addEventListener("wheel",nt,{passive:!1})):(e.removeAttribute("has-overflow"),e.removeEventListener("pointerdown",_),e.removeEventListener("wheel",nt))),!0}});let E=300,b=null,x=!1,w=300,p=300,G=300,J=300;const V={left:0,right:0},W={left:0,right:0};let D=[],B=null,X=null,Y=null,K=!1,F;function ut(){e==null||e.setAttribute("blossom-carousel","true"),B=(e==null?void 0:e.querySelectorAll("a[href]"))||null,B==null||B.forEach(o=>{o.addEventListener("click",N)}),window.addEventListener("keydown",ot),e.addEventListener("scroll",Z),X=new ResizeObserver(Q),X.observe(e),Y=new MutationObserver(ft),Y.observe(e,{attributes:!1,childList:!0,subtree:!1});const t=window.matchMedia("(hover: hover) and (pointer: fine)").matches,{scrollSnapType:n}=window.getComputedStyle(e);K=n!=="none",e.style.setProperty("--snap-type",n),t&&(e.style["scroll-snap-type"]="none"),e.setAttribute("has-repeat",h!=null&&h.repeat?"true":"false"),F=wt(o=>{(o===e||e.contains(o))&&A(!1)})}function at(){e.removeAttribute("blossom-carousel"),X==null||X.disconnect(),Y==null||Y.disconnect(),b&&cancelAnimationFrame(b),window.removeEventListener("keydown",ot),e.removeEventListener("scroll",Z),B==null||B.forEach(t=>{t.removeEventListener("click",N)}),F==null||F()}function N(t){S.x>10&&t.preventDefault()}function Q(){if(!e)return;const t="ontouchmove"in window;w=e.scrollWidth,p=e.clientWidth,G=e.scrollHeight,J=e.clientHeight;const n=window.getComputedStyle(e);s.x=!t&&w>p&&["auto","scroll"].includes(n.getPropertyValue("overflow-x")),s.y=!t&&G>J&&["auto","scroll"].includes(n.getPropertyValue("overflow-y")),V.right=parseInt(n.paddingRight)||0,V.left=parseInt(n.paddingLeft)||0,W.left=parseInt(n.scrollPaddingLeft)||0,W.right=parseInt(n.scrollPaddingRight)||0,E=w-p-4,D=K?dt(e):[],h!=null&&h.repeat&&O(null,null)}function ft(){Q()}function dt(t){let n=[],o=0;const c=r=>{if(o++,o>100)return;const v=window.getComputedStyle(r).scrollSnapAlign;if(v!=="none"){n.push({align:v,el:r});return}const T=r.children;if(T.length!==0)for(let a of T)c(a)};c(t);const j=t.getBoundingClientRect();let y=n.map(({el:r,align:v},T)=>{const a=r.getBoundingClientRect(),P=r.clientWidth,z=a.left-j.left+t.scrollLeft;switch(v){case"start":return z-W.left;case"end":return z+P-p+W.right;case"center":return z+P*.5-p/2;default:return null}});return y=y.filter(r=>r!==null).reduce((r,v)=>(r[r.length-1]!==v&&r.push(v),r),[]),y}function Z(){if(h!=null&&h.repeat){O(null,null);return}if(!(x||!e)){if(e.scrollLeft<0){const t=e.scrollLeft*-1;$(t)}else if(e.scrollLeft>w-p){const t=e.scrollLeft*-1+w-p;$(t)}}}const l={x:0,y:0};function _(t){e&&(s.x&&(l.x=e.scrollLeft,m.x=t.clientX,d.x=0),s.y&&(l.y=e.scrollTop,m.y=t.clientY,d.y=0),S.x=0,x=!0,window.addEventListener("pointermove",tt),window.addEventListener("pointerup",et))}function tt(t){if(t.preventDefault(),s.x){const n=m.x-t.clientX;i.x+=n,d.x+=n,m.x=t.clientX,S.x+=Math.abs(n)}if(s.y){const n=m.y-t.clientY;i.y+=n,d.y+=n,m.y=t.clientY,S.y+=Math.abs(n)}}function et(){window.removeEventListener("pointermove",tt),window.removeEventListener("pointerup",et),x=!1,!(S.x<=10)&&(s.x&&(d.x*=2),s.y&&(d.y*=2),pt(),bt())}function nt(t){if(Math.abs(t.deltaX)>Math.abs(t.deltaY)){if(A(!1),x||!e)return;s.x&&(l.x=e.scrollLeft),s.y&&(l.y=e.scrollTop)}}function ot(t){["ArrowLeft","ArrowRight","ArrowUp","ArrowDown"].includes(t.key)&&A(!1)}function pt(){const t=(st(mt({axis:"x"}),0,w-p)-i.x)*(1-g)*(1/g);d.x=t}function O(t,n){if(!e)return;const o=n??e.scrollLeft,c=V.left-o,j=o-(w-p-V.right),y=Array.from(e.children);let r=0;for(let a=y.length-1;a>=y.length/2;a--){const P=r>c?0:-(w-p);r+=y[a].clientWidth,y[a].style.translate=`${P}px 0`}let v=0;for(let a=0;a<y.length/2;a++){const P=v>j?0:w-p;v+=y[a].clientWidth,y[a].style.translate=`${P}px 0`}if(x)return;const T=o>E?4:o<4?E:null;T&&(I=!0,e.scrollTo({left:T,behavior:"instant"}))}const g=.72,q=.12;let lt=!1;function A(t){e&&(t&&!lt?(H=performance.now(),s.x&&(i.x=e.scrollLeft),s.y&&(i.y=e.scrollTop),b||(b=requestAnimationFrame(rt))):t||(b&&cancelAnimationFrame(b),b=null),lt=t,k=!t,e.setAttribute("has-snap",k?"true":"false"))}let M=0,H=0;function rt(t){b=requestAnimationFrame(rt),M=t-H,e&&(s.x&&(d.x*=g,x?l.x=R(l.x,i.x,g,M):(i.x+=d.x,l.x=R(l.x,i.x,q,M))),s.y&&(d.y*=g,x?l.y=R(l.y,i.y,g,M):(i.y+=d.y,l.y=R(l.y,i.y,q,M))),h!=null&&h.repeat&&(l.x>E&&(l.x=i.x=4),l.x<4&&(l.x=i.x=E)),I=!0,e.scrollTo({left:l.x,top:l.y,behavior:"instant"}),h!=null&&h.repeat?O(null,l.x):ht(it(l.x,2)),H=t)}let C=0;function ht(t){if(!e)return;const n=w-p;let o=0;if(t<0?o=x?t*-.2:0:t>n&&(o=x?(t-n)*-.2:0),C=R(C,o,x?.8:q,M),Math.abs(C)>.01){if($(C).defaultPrevented)return;e.style.transform=`translateX(${it(C,3)}px)`;return}e.style.transform="",C=0}function $(t){const n=new CustomEvent("overscroll",{bubbles:!0,cancelable:!0,detail:{left:t}});return e==null||e.dispatchEvent(n),n}let I=!1;const yt=e.scrollTo.bind(e);e.scrollTo=function(t){I===!0||A(!1),I=!1,yt(t)};const xt=e.scrollBy.bind(e);e.scrollBy=function(t){I===!0||A(!1),I=!1,xt(t)};function wt(t){const n=[],o=Element.prototype.scrollIntoView;return o&&(Element.prototype.scrollIntoView=function(c){return t(this,"scrollIntoView",[c]),o.call(this,c)},n.push(()=>{Element.prototype.scrollIntoView=o})),()=>n.forEach(c=>c())}function vt({axis:t="x"}){return i[t]+d[t]/(1-g)}function mt({axis:t="x"}){const n=vt({axis:t});return D.length?D.reduce((o,c)=>Math.abs(c-n)<Math.abs(o-n)?c:o):st(n,0,E)}function bt(){const t=n=>{n.preventDefault(),n.stopPropagation(),window.removeEventListener("click",t,!0)};window.addEventListener("click",t,!0)}function gt(t,n,o){return(1-o)*t+o*n}function R(t,n,o,c){return gt(t,n,1-Math.exp(Math.log(1-o)*(c/16.666666666666668)))}function st(t,n,o){return t<n?n:t>o?o:t}function it(t,n=0){const o=Math.pow(10,n);return Math.round(t*o)/o}return{snap:k,hasOverflow:s,init:ut,destroy:at}},L="";class U extends HTMLElement{constructor(){super();ct(this,"carouselInstance");const k=this.attachShadow({mode:"open"});this.setAttribute("blossom-carousel","true");const m=document.createElement("slot");k.appendChild(m)}connectedCallback(){this.carouselInstance=u(this,{repeat:!1}),this.carouselInstance.init()}disconnectedCallback(){this.carouselInstance.destroy()}}customElements.define("blossom-carousel",U),f.BlossomCarousel=U,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});