UNPKG

epic-slidy

Version:
2 lines (1 loc) 14.1 kB
function t(t,i,s){return!1===s?String(t):function(t,i){const s=t-i.toString().length;return s>0?new Array(s+1).join("0")+i:String(i)}(!0===s?i.toString(10).length:s,t)}function i(t,i,s){return t.replace(/\$\{.+?}/g,t=>function(t,i,s=`\${${t}}`){return t.split(".").reduce((t,i)=>t[i]||s,i)}(t.substr(2,t.length-3).trim(),i,s))}class s{constructor(t,i){this.t=t,this.i=i,this.s(),this.h()}static disable(t){t.setAttribute("disabled",""),t.classList.add("is-disabled")}static enable(t){t.removeAttribute("disabled"),t.classList.remove("is-disabled")}destroy(){this.o.parentNode.removeChild(this.o),this.t.hooks.remove("beforeSlide",this.l)}s(){const{namespace:t,outer:s}=this.t,{controls:h}=this.i;let e="<",n=">";!0!==h&&(e=i(h,{label:"previous slide"}),n=i(h,{label:"next slide"}));const o=document.createElement("div");o.classList.add(t+"-controls"),o.innerHTML=`<button type="button" class="${t}-controls__item--prev">${e}</button>\n <button type="button" class="${t}-controls__item--next">${n}</button>`,this.o=o,this.u=this.o.querySelector("button:first-child"),this.p=this.o.querySelector("button:last-child"),s.appendChild(this.o),this.l()}h(){this.m=this.m.bind(this),this.v=this.v.bind(this),this.l=this.l.bind(this),this.t.hooks.add("beforeSlide",this.l),this.g(),this.i.keyboard&&addEventListener("keydown",t=>{37===t.keyCode?this.t.slidePrev("controls"):39===t.keyCode&&this.t.slideNext("controls")})}g(){this.u.addEventListener("click",this.m),this.p.addEventListener("click",this.v)}m(){this.t.slidePrev("controls")}v(){this.t.slideNext("controls")}l(){if(!this.i.loop){const{newIndex:t}=this.t,{length:i}=this.t.items;s.enable(this.u),s.enable(this.p),0===t&&s.disable(this.u),t+this.t.group>=i&&s.disable(this.p)}}}class h{constructor(t){this.o=t,this._=new Map,this.$=new Map,this.S=1e3,this.k=50,this.M=100,this.P=this.P.bind(this),this.A=this.A.bind(this),this.C=this.C.bind(this)}on(t,i){let s,e,n;switch(this._.set(t,i),t){case"click":case"drag":this.N||(s=h.T("mousedown")||h.G("PointerDown"),e=h.T("mouseup")||h.G("PointerUp"),n=h.T("mousemove")||h.G("PointerMove"),this.N=!0);break;case"tap":case"swipe":this.I||(s=h.T("touchstart")||h.G("PointerDown"),e=h.T("touchend")||h.G("PointerUp"),n=h.T("touchmove")||h.G("PointerMove"),this.I=!0,"swipe"===t&&(this.o.style.touchAction="pan-y"))}s&&this.h(s,this.P),e&&this.h(e,this.A),n&&this.h(n,this.C)}destroy(){this._.forEach((t,i)=>{this._.delete(i)}),this.$.forEach((t,i)=>{this.D(i)})}static L(t){return t.changedTouches?t.changedTouches[0]:t}static G(t){const i=t.toLowerCase();return navigator.msPointerEnabled?"MS"+t:!!window.PointerEvent&&i}static T(t){return"on"+t in window&&t}h(t,i,s=!1){this.$.has(t)||(this.o.addEventListener(t,i,s),this.$.set(t,i))}D(t){if(this.$.has(t)){const i=this.$.get(t);this.o.removeEventListener(t,i),this.$.delete(t)}}P(t){this.R=h.L(t).clientX,this.U=Date.now()}A(t){const i=h.L(t).clientX-this.R,s=Date.now()-this.U;if(Math.abs(i)<=this.k&&s<=this.S)return this._.has("click")&&this._.get("click")(),void(this._.has("tap")&&this._.get("tap")());if(Math.abs(i)>this.k&&s>this.M){const t=i>=0?"right":"left";this._.has("drag")&&this._.get("drag")(t,"drag"),this._.has("swipe")&&this._.get("swipe")(t,"swipe")}}C(t){}}class e{constructor(){this.q=new Map}add(t,i){const s=this.q.has(t)?this.q.get(t):new Set;s.add(i),this.q.set(t,s)}remove(t,i){if(!this.q.has(t))return;const s=this.q.get(t);s.delete(i),0===s.size?this.q.delete(t):this.q.set(t,s)}call(t,i,...s){this.q.has(t)&&this.q.get(t).forEach(t=>{t.call(i,...s)})}}class n{constructor(t,i){if(this.t=t,this.i=i,!this.i.nav)return;const s=!0===this.i.nav?"number":this.i.nav;if(/\${(number|thumb)}/.test(s))this.j="template",this.B=s;else if("thumb"===s)this.j="thumb";else{if("number"!==s)return void console.error('Slidy: wrong value for "nav" option');this.j="number"}this.s(),this.h()}static F(t){let i;return i="slidyThumb"in t.dataset?t.dataset.slidyThumb:t.querySelector("img").getAttribute("src").replace(/(.*)(\.\w{3,4}$)/,"$1_thumb$2"),`<img src="${i}">`}static H(t){return`<button type="button">\n <span>\n ${t}\n </span>\n </button>`}destroy(){this.o.parentNode.removeChild(this.o),this.t.hooks.remove("beforeSlide",this.J),this.t.hooks.remove("beforeSlide",this.K)}s(){const{items:s,groupsMax:h,namespace:e,outer:o}=this.t,{zerofill:r}=this.i,a=document.createElement("ol");a.classList.add(e+"-nav");const l=s.filter((t,i)=>i%this.t.group==0).map((s,e)=>{if("slidyNav"in s.dataset){const{slidyNav:t}=s.dataset;return"template"===this.j?i(this.B,{number:t,thumb:t}):n.H(t)}let o,a;const l={};switch(this.j){case"template":return/\${number}/.test(this.B)&&(l.number=t(e+1,h,r)),/\${thumb}/.test(this.B)&&(l.thumb=n.F(s)),i(this.B,l);case"thumb":return a=n.F(s),n.H(a);case"number":default:return o=t(e+1,h,r),n.H(o)}}).map(t=>`<li class="${e}-nav__item">${t}</li>`).join("");a.innerHTML=l,this.o=a,o.appendChild(this.o),this.O=Array.from(this.o.querySelectorAll("li")),this.K()}h(){this.V=this.V.bind(this),this.J=this.J.bind(this),this.K=this.K.bind(this),this.t.hooks.add("beforeSlide",this.J),this.t.hooks.add("beforeSlide",this.K),this.W()}W(){this.o.addEventListener("click",this.V)}J(){const t=this.o.querySelector(".is-active");if(t){t.classList.remove("is-active");const i=t.querySelector("button");i&&(i.disabled=!1)}}K(){const t=this.O[this.t.newGroup];t.classList.add("is-active");const i=t.querySelector("button");i&&(i.disabled=!0)}V(t){const i=function(t,i){for(let s=t;s&&s!==document;s=s.parentNode)if(s.classList.contains(i))return s;return null}(t.target,this.t.namespace+"-nav__item");if(null!==i){const t=Array.from(this.o.children).indexOf(i);this.t.slideTo(t,"nav")}}}class o{constructor(t,i){this.t=t,this.i=i,this.s(),this.h()}destroy(){this.o.parentNode.removeChild(this.o)}s(){const{currentGroup:i,groupsMax:s,items:h,namespace:e,outer:n}=this.t,{length:o}=h,{pagination:r,zerofill:a}=this.i,l=t(i+1,o,a),c=!0===r?"/":r,u=t(s,s,a),d=document.createElement("div");d.classList.add(e+"-pagination"),d.innerHTML=`<span class="${e}-pagination__current">${l}</span>\n <span class="${e}-pagination__separator">${c}</span>\n <span class="${e}-pagination__total">${u}</span>`,this.o=d,this.X=this.o.querySelector("span:nth-child(1)"),n.appendChild(this.o),this.l()}h(){this.t.hooks.add("beforeSlide",this.l.bind(this))}l(){this.X.textContent=t(this.t.newGroup+1,this.Y,this.i.zerofill)}}class r{constructor(t,i){this.t=t,this.Z=!1,this.shouldPrevent=!1,this.tt=i,this.Z=!1,this.it=this.t.options.queue,this.st=[]}add(t){this.t.hooks.call("preventSlide",this.t,t,this),this.shouldPrevent?this.shouldPrevent=!1:(this.shouldPrevent=!1,this.st.length>this.it&&(this.st.length=this.it),this.st.push(t),this.Z||this.ht())}empty(){this.st=[]}getCurrentItems(t){const{group:i,items:s}=this.t,{loop:h,preserveGroup:e}=this.t.options;let n=s.slice(t,t+i);return t+i>=s.length&&h&&e&&(n=n.concat(s.slice(0,i-(s.length-t)))),n}getNewItems(t){const{group:i,items:s}=this.t,{loop:h,preserveGroup:e}=this.t.options;let n=s.slice(t,t+i);return t+i>=s.length&&h&&e&&(n=n.concat(s.slice(0,i-(s.length-t)))),n}ht(){if(0===this.st.length)return;const[{move:t,trigger:i,index:s,animate:h}]=this.st,e={trigger:i,animate:h},{items:n}=this.t,{length:o}=n,{currentIndex:r,currentGroup:a,groupsMax:l,group:c,options:u}=this.t,{loop:d,preserveGroup:p}=u;let m,v,w;if("to"===t?(v=s,m=v*c):("prev"===t&&(v=a-1,m=r-c),"next"===t&&(v=a+1,m=r+c)),v<0&&(v=d?l-1:a),v>=l&&(v=d?0:a),m<0&&(m=d?p?o-Math.abs(m):o-o%c:r),m>=o&&(m=d?p?m-o:0:r),w="to"===t?v>a?"next":"prev":t,e.direction=w,e.currentIndex=r,e.newIndex=m,e.currentGroup=a,e.newGroup=v,v===a)return this.st.shift(),void this.ht();const b=this.getCurrentItems(r),f=this.getNewItems(m);this.t.newIndex=m,this.t.newGroup=v,this.t.hooks.call("beforeSlide",this.t,e,this.t.context,this.t.data),this.Z=!0,b.forEach(t=>{t.classList.remove("is-active")}),(h?this.tt:()=>Promise.resolve()).call(this.t,c>1?b:b[0],c>1?f:f[0],e,this.t.context,this.t.data).then(()=>{this.t.currentIndex=m,this.t.currentGroup=v,this.st.shift(),this.Z=!1,f.forEach(t=>{t.classList.add("is-active")}),this.t.hooks.call("afterSlide",this.t,e,this.t.context,this.t.data),this.ht()})}}export default class{constructor(t,i,s=null,h=null){let n;return this.data=h,this.hooks=new e,"string"==typeof t&&(n=document.querySelectorAll(t)),!t||n&&0===n.length?(this.et=!0,void console.error("Slidy: no element matching!")):(n&&n.length>1&&console.warn("Slidy: multiple elements matching!"),this.el=n?n[0]:t,this.i={auto:!1,click:!0,controls:!1,debounce:100,drag:!1,group:()=>1,height:"auto",index:0,interval:2e3,keyboard:!0,loop:!0,namespace:"slidy",nav:!1,pagination:!1,pause:!0,preserveGroup:!0,queue:1,resize:!0,reverse:!1,swipe:!1,tap:!1,transition:null,zerofill:!1,...i},null===this.i.transition?(this.et=!0,void console.error("Slidy: you should define a transition!")):(this.context=s||this,this.nt=this.i.debounce,this.currentIndex=this.i.index,this.newIndex=this.currentIndex,this.group=Number(this.i.group)||this.i.group(),this.currentGroup=Math.ceil(this.currentIndex/this.group),this.newGroup=this.currentGroup,void(this.newIndex%this.group==0||this.options.preserveGroup||console.warn("Slidy: index does not match with group!"))))}get options(){return this.i}get namespace(){return this.i.namespace}init(){this.et?console.error("Slidy: fix errors!"):(this.items=Array.from(this.el.children),this.itemsMax=this.items.length,this.groupsMax=Math.ceil(this.itemsMax/this.group),this.ot=!1,this.start=this.start.bind(this),this.slideNext=this.slideNext.bind(this),this.hooks.add("afterSlide",()=>{this.el.setAttribute("aria-valuenow",""+(this.currentIndex+1))}),this.hooks.call("beforeInit",this,this.el),this.rt=new r(this,this.i.transition),"auto"===this.i.height?this.reset():this.el.style.height=this.i.height+"px",this.outer=document.createElement("div"),this.el.parentNode.insertBefore(this.outer,this.el),this.outer.appendChild(this.el),this.at=this.rt.getCurrentItems(this.currentIndex),this.outer.classList.add(this.namespace+"-outer"),this.el.classList.add(this.namespace),this.items.forEach(t=>{t.classList.add(this.namespace+"__item")}),this.at.forEach(t=>{t.classList.add("is-active")}),this.el.setAttribute("role","slider"),this.el.setAttribute("aria-valuemin","1"),this.el.setAttribute("aria-valuemax",""+this.items.length),this.el.setAttribute("aria-valuenow",""+(this.currentIndex+1)),this.el.setAttribute("aria-valuenow",""+(this.currentGroup+1)),this.i.click&&(this.el.style.cursor="pointer"),this.i.controls&&(this.lt=new s(this,this.i)),this.i.nav&&(this.ct=new n(this,this.i)),this.i.pagination&&(this.ut=new o(this,this.i)),this.bind(),this.i.auto&&this.start(),this.hooks.call("afterInit",this,this.el))}on(t,i){this.hooks.add(t,i)}off(t,i){this.hooks.remove(t,i)}slidePrev(t,i=!1){!this.i.reverse||i?this.slide({move:"prev",trigger:t}):this.slideNext(t,!0)}slideNext(t,i=!1){!this.i.reverse||i?this.slide({move:"next",trigger:t}):this.slidePrev(t,!0)}slideTo(t,i,s=!0){this.slide({move:"to",trigger:i,index:t,animate:s})}slide(t){this.i.auto&&(window.clearInterval(this.dt),this.dt=window.setInterval(this.slideNext,this.i.interval)),this.rt?this.rt.add({index:null,animate:!0,...t}):this.stop()}start(t=this.i.interval,i=this.i.auto){this.pt=window.setTimeout(()=>{this.slideNext("auto"),!this.ot&&this.i.pause&&this.outer.addEventListener("mouseenter",this.vt),i&&(window.clearInterval(this.dt),this.dt=window.setInterval(this.slideNext,this.i.interval))},t)}stop(){this.ot&&this.outer.removeEventListener("mouseenter",this.vt),window.clearTimeout(this.pt),window.clearInterval(this.dt)}destroy(){this.wt=!0,this.stop(),this.rt&&(this.rt.empty(),delete this.rt),this.i.resize&&window.removeEventListener("resize",this.onResize),this.el.removeEventListener("mouseenter",this.vt),this.el.removeEventListener("mouseleave",this.bt),this.el.removeEventListener("click",this.V),this.items.forEach(t=>{t.classList.remove("is-active")}),this.ft&&(this.ft.destroy(),delete this.ft),this.lt&&(this.lt.destroy(),delete this.lt),this.ct&&(this.ct.destroy(),delete this.ct),this.ut&&(this.ut.destroy(),delete this.ut),this.outer.before(this.el),this.outer.parentNode&&this.outer.parentNode.removeChild(this.outer),this.el.classList.remove(this.namespace),this.items.forEach(t=>{t.classList.remove(this.namespace+"__item"),t.removeAttribute("style"),Array.from(t.children).forEach(t=>{t.removeAttribute("style")})}),this.el.removeAttribute("style"),this.el.removeAttribute("role"),this.el.removeAttribute("aria-valuemin"),this.el.removeAttribute("aria-valuemax"),this.el.removeAttribute("aria-valuenow"),this.el.removeAttribute("aria-valuenow")}bind(){this.vt=this.vt.bind(this),this.bt=this.bt.bind(this),this.V=this.V.bind(this),this.gt=this.gt.bind(this),this._t=this._t.bind(this),this.i.resize&&(this.onResize=function(t,i){let s;return function(...h){clearTimeout(s),s=window.setTimeout(()=>{s=null,t.apply(this,h)},i)}}(this.onResize,this.nt).bind(this),window.addEventListener("resize",this.onResize)),this.i.pause&&this.i.auto&&(this.outer.addEventListener("mouseenter",this.vt),this.ot=!0),this.ft=new h(this.el),"ontouchstart"in window?(this.i.tap&&this.ft.on("tap",this.gt),this.i.swipe&&this.ft.on("swipe",this._t)):(this.i.click&&this.ft.on("click",this.V),this.i.drag&&this.ft.on("drag",this._t))}reset(){if("auto"===this.i.height){this.el.style.height="";const t=t=>t.filter(t=>t>0).sort((t,i)=>i-t).slice(0,1),i=[],s=0===this.items[0].offsetHeight;this.items.forEach(t=>{i.push(s&&t.firstElementChild?t.firstElementChild.offsetHeight:t.offsetHeight)}),this.el.style.height=t(i)+"px"}}onResize(){this.wt||(this.reset(),Number(this.i.group)||(this.group=this.i.group()),this.hooks.call("afterResize",this,this.el))}V(){this.slideNext("click")}gt(){this.slideNext("tap")}_t(t,i){"right"===t&&this.slidePrev(i),"left"===t&&this.slideNext(i)}vt(){this.outer.removeEventListener("mouseenter",this.vt),this.stop(),this.outer.addEventListener("mouseleave",this.bt)}bt(){this.outer.removeEventListener("mouseleave",this.bt),this.start(),this.outer.addEventListener("mouseenter",this.vt)}}