UNPKG

@lifarl/react-scroll-snap-slider

Version:

A performant React Slider / Carousel Component with CSS Scroll Snapping, Intersection Observer and Accessibility.

17 lines (14 loc) 10.3 kB
import*as e from"react";import r,{forwardRef as t,useState as n,useRef as a,useId as l,useCallback as i,useImperativeHandle as o,useEffect as c,useMemo as s,Children as u}from"react"; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */var d=function(){return d=Object.assign||function(e){for(var r,t=1,n=arguments.length;t<n;t++)for(var a in r=arguments[t])Object.prototype.hasOwnProperty.call(r,a)&&(e[a]=r[a]);return e},d.apply(this,arguments)};function f(e,r){var t={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&r.indexOf(n)<0&&(t[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var a=0;for(n=Object.getOwnPropertySymbols(e);a<n.length;a++)r.indexOf(n[a])<0&&Object.prototype.propertyIsEnumerable.call(e,n[a])&&(t[n[a]]=e[n[a]])}return t}var v=function(){for(var e=[],r=0;r<arguments.length;r++)e[r]=arguments[r];return e.filter(Boolean).join(" ")},m=r.forwardRef(function(e,t){var n=e.className,a=f(e,["className"]);return r.createElement("li",d({ref:t,className:v("scs-slide",n)},a))});m.displayName="StyledSlide";var b=r.forwardRef(function(e,t){var n=e.slideIndex,a=e.slidesPerPageSettings,l=e.slideWidth,i=e.className,o=e.slideCount,c=e.children;return a?"".concat(100/a.mobileSmall,"%"):!l||"".concat(l,"px"),r.createElement(m,{"data-index-number":n,key:n,className:i,role:"group","aria-roledescription":"slide","aria-label":"Slide ".concat(n+1).concat(o?" of ".concat(o):""),ref:t},c)});b.displayName="Slide";var p=r.memo(b),h=function(){for(var e=[],r=0;r<arguments.length;r++)e[r]=arguments[r];return e.filter(Boolean).join(" ")},N=r.forwardRef(function(e,t){var n=e.direction,a=e.className,l=e.type,i=void 0===l?"button":l,o=f(e,["direction","className","type"]),c="prev"===n?"scs-nav--prev":"scs-nav--next";return r.createElement("button",d({ref:t,type:i,className:h("scs-nav",c,a)},o))}),y=r.memo(N),g=r.forwardRef(function(e,t){var n=e.className,a=f(e,["className"]);return r.createElement("svg",d({ref:t,className:h("scs-arrow",n)},a))}),x=r.memo(g);N.displayName="StyledNavWrapper",g.displayName="StyledArrow";var w=e.forwardRef(function(r,t){var n=r.direction,a=r.onClick,l=r.className,i=r.iconClassName,o=r.ariaControls,c=r.ariaLabel,s=r.disabled,u=e.useMemo(function(){return"prev"===n?"M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z":"M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z"},[n]),d=e.useMemo(function(){return e.createElement("path",{d:u})},[u]);return e.createElement(y,{direction:n,onClick:a,ref:t,className:l,"aria-controls":o,"aria-label":c||("prev"===n?"Previous slide":"Next slide"),disabled:s},e.createElement(x,{viewBox:"0 0 8 8",className:i},d))});w.displayName="NavArrow";var C=e.memo(w),S=function(){for(var e=[],r=0;r<arguments.length;r++)e[r]=arguments[r];return e.filter(Boolean).join(" ")},E=r.forwardRef(function(e,t){var n=e.className,a=f(e,["className"]);return r.createElement("div",d({ref:t,className:S("scs-carousel",n)},a))}),A=r.forwardRef(function(e,t){var n=e.className,a=f(e,["className"]);return r.createElement("div",d({ref:t,className:S("scs-slider",n)},a))});A.displayName="StyledSlider";var k=r.memo(A),O=r.forwardRef(function(e,t){var n=e.className,a=f(e,["className"]);return r.createElement("ul",d({ref:t,className:S("scs-list",n)},a))});E.displayName="StyledCarousel",O.displayName="StyledUl";var P=t(function(e,t){var d,f=e.renderCustomArrow,v=e.slidesPerPageSettings,m=e.slideWidth,b=e.onScrollStart,h=e.onScrollEnd,N=e.onSlidesVisibilityChange,y=e.onSlideVisible,g=e.className,x=e.classes,w=e.ariaLabel,S=e.children,A=n(!1),P=A[0],R=A[1],j=a(null),L=a(null),W=a([]),M=a(null),B=a(null),D=a(null),I=a(0),T=a(0),q=a([]),z=l(),F=n(""),V=F[0],H=F[1],K=i(function(e,r){W.current[r]=e},[]),U=i(function(){var e,r,t;return(null===(t=null===(r=null===(e=L.current)||void 0===e?void 0:e.firstChild)||void 0===r?void 0:r.firstChild)||void 0===t?void 0:t.clientWidth)||0},[]),G=i(function(e){e.forEach(function(e){var r,t,n,a,l,i=e.target,o=Number(i.dataset.indexNumber);if(e.intersectionRatio>=.5)return I.current=o,q.current.push(o),q.current.sort(),null===(r=W.current[o])||void 0===r||r.setAttribute("aria-hidden","false"),W.current[o]&&((l=W.current[o]).removeAttribute("inert"),l.querySelectorAll("[data-scs-managed]").forEach(function(e){var r=e.getAttribute("data-scs-prev-tabindex");"none"===r?e.removeAttribute("tabindex"):null!==r&&e.setAttribute("tabindex",r),e.removeAttribute("data-scs-prev-tabindex"),e.removeAttribute("data-scs-managed")})),null===(t=W.current[o])||void 0===t||t.classList.remove("scs-slide--hidden"),void(y&&y(o));q.current=q.current.filter(function(e){return e!==o}),null===(n=W.current[o])||void 0===n||n.setAttribute("aria-hidden","true"),W.current[o]&&function(e){e.setAttribute("inert",""),e.querySelectorAll('a[href],area[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),iframe,object,embed,[contenteditable="true"],[tabindex]').forEach(function(e){e.hasAttribute("data-scs-managed")||(e.hasAttribute("tabindex")?e.setAttribute("data-scs-prev-tabindex",String(e.getAttribute("tabindex"))):e.setAttribute("data-scs-prev-tabindex","none"),e.setAttribute("tabindex","-1"),e.setAttribute("data-scs-managed","1"))})}(W.current[o]),null===(a=W.current[o])||void 0===a||a.classList.add("scs-slide--hidden")}),T.current=q.current[Math.floor(q.current.length/2)],N&&N(T.current);var t=r.Children.count(S);"number"==typeof T.current&&t>0&&(console.log("Slide ".concat(T.current+1," of ").concat(t)),H("Slide ".concat(T.current+1," of ").concat(t)))},[]),J=i(function(){if(!L.current)return!1;var e=L.current.clientWidth,r=U()-1;return W.current.length*r>e},[]),Q=i(function(e){var r="prev"===e?-1:1;if(L.current){var t=U(),n=Math.floor(L.current.clientWidth/t);L.current.scrollBy({top:0,behavior:"smooth",left:n*t*r})}},[U]),X=i(function(){null!==j.current&&clearTimeout(j.current),j.current=setTimeout(function(){j.current=null,R(!1),h&&h(T.current)},250),P||R(!0)},[h,P]),Y=i(function(e){L.current&&L.current.scrollTo({top:0,behavior:"smooth",left:e})},[]),Z=i(function(e){if(L.current){var r=L.current.scrollLeft,t=L.current.clientWidth,n=U(),a=n*e;a<r?Y(a):a+n>r+t&&Y(a+n-t)}},[]);o(t,function(){return{scrollToSlide:Z,sliderRef:L}}),c(function(){D.current&&D.current.disconnect();for(var e=function(e,r,t,n){void 0===e&&(e=null);var a=r.current;if(null!==a)return a;var l=new IntersectionObserver(t,{root:e,rootMargin:"0px",threshold:n});return r.current=l,l}(L.current,D,G,.5),r=0,t=W.current;r<t.length;r++){var n=t[r];n&&e.observe(n)}return function(){return e.disconnect()}},[r.Children.count(S)]),c(function(){P&&b&&b(T.current)},[P,b]),c(function(){if(L.current&&B.current&&M.current){!function(){if(!J())return B.current.disabled=!0,void(M.current.disabled=!0);if(P)return B.current.disabled=!0,void(M.current.disabled=!0);var e=L.current.scrollLeft<=30,r=L.current.clientWidth+L.current.scrollLeft>=L.current.scrollWidth-30;M.current.disabled=e,B.current.disabled=r}()}},[r.Children.count(S),P]),c(function(){var e=L.current;if(e)return e.addEventListener("scroll",X,{passive:!0}),function(){return e.removeEventListener("scroll",X)}},[X]);var $=a(r.Children.count(S));c(function(){$.current=r.Children.count(S)},[S]);var _=i(function(e){if(L.current){var r=$.current,t=T.current||0;switch(e.key){case"ArrowLeft":e.preventDefault(),Z(Math.max(0,t-1));break;case"ArrowRight":e.preventDefault(),Z(Math.min(r-1,t+1));break;case"Home":e.preventDefault(),Z(0);break;case"End":e.preventDefault(),Z(r-1)}}},[]),ee=s(function(){var e,r=v?"".concat(100/v.mobileSmall,"%"):m?"".concat(m,"px"):"100%";return(e={})["--scs-min-w"]=r,e["--scs-min-w-512"]=v?"".concat(100/v.mobileBig,"%"):void 0,e["--scs-min-w-753"]=v?"".concat(100/v.tablet,"%"):void 0,e["--scs-min-w-1232"]=v?"".concat(100/v.desktop,"%"):void 0,e},[v,m]);return r.createElement(E,{className:null!==(d=null==x?void 0:x.root)&&void 0!==d?d:g,role:"region","aria-roledescription":"carousel","aria-label":w},s(function(){var e,t;if(f)return r.createElement(r.Fragment,null,f({direction:"prev",ref:M,onClick:Q,ariaControls:z}),f({direction:"next",ref:B,onClick:Q,ariaControls:z}));return r.createElement(r.Fragment,null,r.createElement(C,{ref:M,direction:"prev",onClick:function(){return Q("prev")},className:null!==(e=null==x?void 0:x.navPrev)&&void 0!==e?e:null==x?void 0:x.nav,iconClassName:null==x?void 0:x.arrow,ariaControls:z}),r.createElement(C,{ref:B,direction:"next",onClick:function(){return Q("next")},className:null!==(t=null==x?void 0:x.navNext)&&void 0!==t?t:null==x?void 0:x.nav,iconClassName:null==x?void 0:x.arrow,ariaControls:z}))},[f,null==x?void 0:x.navPrev,null==x?void 0:x.navNext,null==x?void 0:x.nav,null==x?void 0:x.arrow,z,Q]),r.createElement(k,{ref:L,tabIndex:0,className:null==x?void 0:x.slider,id:z,role:"group","aria-roledescription":"slides","aria-label":"Carousel slides",onKeyDown:_,style:ee},s(function(){var e=r.Children.count(S);return r.createElement(O,{className:null==x?void 0:x.list,role:"list"},u.map(S,function(t,n){return r.createElement(p,{key:n,slideIndex:n,slidesPerPageSettings:v,slideWidth:m,ref:function(e){return K(e,n)},className:null==x?void 0:x.slide,slideCount:e},t)}))},[S,v,m,null==x?void 0:x.list,null==x?void 0:x.slide]),r.createElement("div",{"aria-live":"polite",className:"scs-visually-hidden"},V)))});P.displayName="Carousel";var R=P;export{R as Slider,x as StyledArrow,E as StyledCarousel,y as StyledNavWrapper,m as StyledSlide,k as StyledSlider,O as StyledUl}; //# sourceMappingURL=index.mjs.map