UNPKG

vue-snap

Version:

Lightweight Carousel based on CSS Scroll Snap

2 lines (1 loc) 3.16 kB
var VueSnap=function(c,e){"use strict";const b=typeof window<"u",C=(l,t,n=5)=>Math.abs(l-t)<=n;function k(l,t){let n=null;const i=(...d)=>{n&&clearTimeout(n),n=setTimeout(()=>{l(...d)},t)};return i.cancel=()=>{n&&clearTimeout(n),n=null},i}const E=100;function T(l,t){const n=e.ref(!0),i=e.ref(!1),d=e.ref(0),a=()=>t.value?Array.from(t.value.children??[]).map(o=>({offsetLeft:o.offsetLeft,offsetWidth:o.offsetWidth})):[],S=o=>t.value?o.findIndex(({offsetLeft:s})=>C(s,t.value.scrollLeft,10)):-1,h=o=>{if(!t.value)return;const{scrollLeft:s,offsetWidth:f,scrollWidth:B}=t.value;o!==d.value&&l("slideChange",o),d.value=o;const _=o===0,O=C(s+f,B,10);_?(n.value=!0,l("leftBound",!0)):n.value=!1,O?(i.value=!0,l("rightBound",!0)):i.value=!1},m=o=>{const s=a(),f=S(s);if(f===-1)return;const B=f+o,_=s[B];!_||!t.value||t.value.scrollTo({left:_.offsetLeft,behavior:"smooth"})},r=o=>{const f=a()[o];!f||!t.value||t.value.scrollTo({left:f.offsetLeft,behavior:"smooth"})},u=()=>{const o=a(),s=S(o);s!==-1&&h(s)},g=k(u,E);return e.onMounted(()=>{!b||!t.value||(u(),t.value.addEventListener("scroll",g),l("mounted",!0))}),e.onBeforeUnmount(()=>{!b||!t.value||t.value.removeEventListener("scroll",g)}),{goToSlide:r,changeSlide:m,isBoundLeft:n,isBoundRight:i}}const I={class:"vs-carousel"},R=["aria-label","disabled"],p=["aria-label","disabled"],w=e.defineComponent({__name:"Carousel",props:{tag:{default:"ul"},hideArrowsOnBound:{type:Boolean,default:!1},i18n:{default:()=>({slideLeft:"Slide left",slideRight:"Slide right"})}},emits:["mounted","slideChange","leftBound","rightBound"],setup(l,{expose:t,emit:n}){const i=n,d=e.ref(null),{changeSlide:a,goToSlide:S,isBoundLeft:h,isBoundRight:m}=T(i,d);return t({changeSlide:a,goToSlide:S}),(r,u)=>(e.openBlock(),e.createElementBlock("div",I,[(e.openBlock(),e.createBlock(e.resolveDynamicComponent(r.tag),{ref_key:"vsWrapper",ref:d,class:"vs-carousel__wrapper"},{default:e.withCtx(()=>[e.renderSlot(r.$slots,"default")]),_:3},512)),e.renderSlot(r.$slots,"arrows",e.normalizeProps(e.guardReactiveProps({changeSlide:e.unref(a),isBoundLeft:e.unref(h),isBoundRight:e.unref(m)})),()=>[e.withDirectives(e.createElementVNode("button",{type:"button","aria-label":r.i18n.slideLeft,disabled:e.unref(h),class:"vs-carousel__arrows vs-carousel__arrows--left",onClick:u[0]||(u[0]=g=>e.unref(a)(-1))}," ← ",8,R),[[e.vShow,r.hideArrowsOnBound?!e.unref(h):!0]]),e.withDirectives(e.createElementVNode("button",{type:"button","aria-label":r.i18n.slideRight,disabled:e.unref(m),class:"vs-carousel__arrows vs-carousel__arrows--right",onClick:u[1]||(u[1]=g=>e.unref(a)(1))}," → ",8,p),[[e.vShow,r.hideArrowsOnBound?!e.unref(m):!0]])])]))}}),L=e.defineComponent({__name:"Slide",props:{tag:{type:String,default:"li"}},setup(l){return(t,n)=>(e.openBlock(),e.createBlock(e.resolveDynamicComponent(l.tag),{ref:"vsSlide",class:"vs-carousel__slide",tabindex:"0"},{default:e.withCtx(()=>[e.renderSlot(t.$slots,"default")]),_:3},512))}}),y={install:l=>{l.component("Carousel",w),l.component("Slide",L)}};return c.Carousel=w,c.Slide=L,c.VueSnap=y,c.default=y,Object.defineProperties(c,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}}),c}({},Vue);