@slidy/element
Version:
Simple, configurable & reusable carousel CustomElement
2 lines (1 loc) • 7.12 kB
JavaScript
var{assign:G,entries:lt}=Object,{abs:C,exp:pt,floor:dt,min:xt,max:B,round:j,sign:W}=Math;function P(e,n,t){return xt(t,B(e,n))}function Q(e,n=50,t=!0){let o=0;return t?a=>{let m=performance.now();m-o>=n&&(e(a),o=m)}:a=>e(a)}function A(e,n){for(let t=0;t<e.length;t++)n(e[t],t,e);return e}var Z=(e,n)=>C(e.deltaX)>=C(e.deltaY)&&n.axis!=="y";function mt(e,n=0){return new Promise((t,o)=>{let a=setInterval(()=>{n++,n>=69?(clearInterval(a),o("few slides")):e.childElementCount&&(clearInterval(a),t(wt(e)))},16)})}function wt(e){return A(e.children,(n,t)=>n.index=t)}function J(e,n,t){let o=e.children.length;return n.loop?(t+o)%o:P(0,t,o-1)}function V(e,n){if(e.type==="wheel")return Z(e,n)?e.deltaX:e.shiftKey||n.axis==="y"?e.deltaY:0;{let t=e.touches&&e.touches[0]||e;return n.axis==="y"?t.pageY:t.pageX}}function L(e,n,t){e.dispatchEvent(new CustomEvent(n,{detail:t}))}function D(e,n,t=!0){let o=t?"addEventListener":"removeEventListener";A(n,a=>e[o](...a))}function ft(e,n){let t=[...e.children],o=t.length,a=o-1,m=dt(o/2),M=o>1?t[1].offsetTop-t[0].offsetTop>=t[0].offsetHeight:!1,k=M?"offsetTop":"offsetLeft",v=M?"offsetHeight":"offsetWidth",d=W(t[a][k]),w=o>1?t[a][k]*d-t[a-1][k]*d-t[a-B(d,0)][v]:0,g=t.reduce((i,c)=>i+=c[v]+w,0)>e.offsetWidth,q=n.snap==="deck";G(n,{reverse:d,scrollable:g,vertical:M,edged:I()});function I(i){let c=b(d<0?a:0,"start"),l=b(d<0?0:a,"end"),y=b(i),O=n.direction,N=j(n.position),S=T=>O<=0&&T<=c||O>=0&&T>=l;return n.loop?!1:S(i>=0?y:N)}function b(i,c=n.snap){let l=E=>t.find(h=>h.index===E)||t[0],y=E=>e[v]-l(E)[v],O=T(d<0?a:0,"start"),N=T(d<0?0:a,"end"),S=T(i,c);return n.loop||c==="deck"?S:P(O,S,N);function T(E,h){h=q?"deck":h;let U=l(E)[v]+w*2<e[v]?n.indent??1:y(E)/2/w,K=h==="start"?0:h==="end"?1:.5,x=h==="start"?-U:h==="end"?U:0;return l(E)[k]-y(E)*K+w*x}}return{edges:I,distance:b,index(i){let c=({index:l})=>C(b(l)-i);return t.reduce((l,y)=>c(y)<c(l)?y:l).index},position(i){let c=n.index;if(i){let l=t.slice(c-m).concat(t.slice(0,c-m));e.replaceChildren(...l)}return b(c)},swap(i){let c=o%i?W(-i):i,l=c>0?0:a;return g&&(l?e.prepend(t[l]):e.append(t[l])),(t[l][v]+w)*(c*d)},sense(i,c,l){return i.shiftKey||n.axis==="y"&&i.type!=="touchmove"||C(c)>=l},animate(){A(t,(i,c)=>{i.i=c,i.active=n.loop?m:n.index,i.size=i[v]+w,i.dist=b(i.index),i.track=n.position-i.dist,i.turn=P(-1,i.track/i.size,1),i.exp=P(0,(i.size-C(i.track))/i.size,1);let l=q?i.dist:n.position,y=M?`translateY(${-l}px)`:`translateX(${-l}px)`,O={node:e,child:i,options:n,translate:y},N=n.animation?.(O)||{transform:y};G(i.style,g?N:{transform:""})})}}}function tt(e,n){let t={...n},o,a=0,m=0,M=0,k=0,v=0,d,w,p=a=t.index??=0,g=t.position??=0,q=t.direction??=0,I=(t.duration??=450)/2,b=t.sensity??=2.5,i=t.gravity??=1.2,c=t.clamp??=0,l=[["touchmove",st,{passive:!1}],["mousemove",st],["touchend",it],["mouseup",it],["scroll",()=>{x(p),i=2}]],y=[["wheel",bt,{passive:!1,capture:!0}]],O=[["touchstart",nt,{passive:!1}],["mousedown",nt],["keydown",vt],["contextmenu",()=>x(p)],["dragstart",s=>s.preventDefault()]],N=new ResizeObserver(s=>{g=t.position=o().position(),x(p),L(e,"resize",{ROE:s,options:t})}),S=new MutationObserver(s=>{A(s,r=>{[...r.addedNodes,...r.removedNodes].every(f=>"index"in f)||rt().then(X)}),L(e,"mutate",{ML:s,options:t})}),T=requestAnimationFrame,E="outline:0;overflow:hidden;user-select:none;-webkit-user-select:none;",h={init:X,update:gt,destroy:rt,to:x};X(),A(t.plugins||[],(s,r,u)=>{u[r]=s({node:e,options:t,instance:h})});function X(){mt(e).then(()=>{o=()=>ft(e,t),e.style.cssText+=E,e.onwheel=Q(ot,I,c),g=t.position=o().position(t.loop),N.observe(e),S.observe(e,{childList:!0}),D(e,O),D(window,y),L(e,"mount",{options:t})})}function U(s,r){q=t.direction=W(s),g=t.position+=u(s),p=t.index=o().index(g),i=o().edges()?1.8:t.gravity,b=0,o().animate(),L(e,"move",{index:p,position:g});function u(f){return p-a&&(f-=t.loop?o().swap(p-a):0,a=p,L(e,"index",{index:r})),f}}function K(s,r){let f=t.snap||o().edges(s)?o().distance(s):g+r,_=I*P(1,s-a,2),Y=f-g;M=T(at);let $=0,F=0,R=0;function at(ct){$||=ct,F=R;let yt=$-ct,ut=pt(yt/_),ht=t.easing?.(ut)||ut;R=Y*ht;let Et=F%R?(F-R)%Y:0;U(Et,s),j(R)?M=T(at):(b=t.sensity,H())}}function x(s=0,r=0){s=J(e,t,s),H(),K(s,r||o().distance(s)-g)}function nt(s){H(),b=t.sensity,m=V(s,t),k=s.timeStamp,v=0,D(window,l),!o().edges()&&s.stopPropagation()}function st(s){let r=(m-V(s,t))*(2-i),u=s.timeStamp-k,f=1e3*r/(i+u);k=s.timeStamp,m=V(s,t),v=(2-i)*f+(i-1)*v,o().sense(s,r,b)&&(U(r,p),s.preventDefault())}function it(){H();let s=v*(2-i),r=o().index(g+s);K(u(r,t),s);function u(f,_){return f=c&&f-a?p+c*q:f,J(e,_,f)}}function ot(s){H();let r=V(s,t)*(2-i),u=p+W(r)*(c||1),f=t.snap||d||o().edges(),_=o().sense(s,r,b),Y=o().edges()?r/5:r,$=d?u:p,F=d?0:I/2;!d&&_&&U(Y,p),w=f&&_?setTimeout(x,F,$):void 0,!o().edges()&&s.stopPropagation()}function bt(s){if(s.composedPath().includes(e)){let r=t.axis==="y"&&!o().edges();(Z(s,t)||r||s.shiftKey)&&s.preventDefault();let u=c||t.axis==="y"&&!t.vertical||s.shiftKey;d!==u&&(e.onwheel=Q(ot,I,u),d=u)}}function vt(s){let r=["ArrowLeft","ArrowRight","ArrowUp","ArrowDown"],u=(r.indexOf(s.key)%2-1||1)*(c||1);r.indexOf(s.key)>=0&&(x(p+u),s.preventDefault()),L(e,"keys",s.key)}function H(){clearTimeout(w),cancelAnimationFrame(M),D(window,l,!1)}function gt(s){A(lt(s),([r,u])=>{if(u!==t[r]){switch(r){case"index":x(p=t[r]=J(e,t,u));break;case"position":x(p,u);break;case"gravity":i=t[r]=P(0,u,2);break;case"duration":t[r]=u,I=u/2;break;case"sensity":b=t[r]=u;break;case"clamp":c=t[r]=u;break;default:t[r]=u;break}L(e,"update",s)}})}async function rt(){H(),N.disconnect(),S.disconnect(),D(e,O,!1),D(window,y,!1),L(e,"destroy",e)}return h}function et(e,n){return["animation","easing"].includes(e)?Tt(n):Ot(n)}function Ot(e){return!isNaN(e)||["true","false"].includes(e)?JSON.parse(e):e}function Tt(e){return Function(`const fn = ${e}; return fn`)()}var z=class e extends HTMLElement{_slidy;_options;static observedAttributes=["index","clamp","indent","sensity","gravity","duration","animation","plugins","easing","snap","axis","loop"];constructor(){super();let n=document.createElement("style"),t=":host{display:flex;flex-flow:var(--flow);gap:var(--gap,1rem);width:100%;height:var(--height,20rem)}::slotted(*){flex:0 0 var(--width,auto);width:var(--width,auto);height:100%}",o=document.createElement("slot");n.append(t),this.attachShadow({mode:"closed"}).append(n,o),this.setUpAccessors(e.observedAttributes),this._options=this.setUpOptions(e.observedAttributes)}set options(n){this._options=n}get options(){return this._options}setUpAccessors(n){n.forEach(t=>{Object.defineProperty(this,t,{set:o=>this.setAttribute(t,o),get:()=>this.getAttribute(t)})})}setUpOptions(n){return{...n.reduce((o,a)=>{let m=this[a];return m&&(o[a]=et(a,m)),o},{}),...this.options}}connectedCallback(){this.isConnected&&this.init(this._options)}attributeChangedCallback(n,t,o){let a=et(n,o),m={[n]:a};this.update(m)}init(n={}){this._slidy=tt(this,n)}to(n){this._slidy?.to(n)}update(n){this._slidy?.update(n)}destroy(){this._slidy?.destroy()}};typeof window=="object"&&"customElements"in window&&customElements.define("slidy-element",z);export{z as slidy};