UNPKG

@diagramers/admin

Version:

Diagramers Admin Template - React starter for admin dashboards.

132 lines (116 loc) 4.11 kB
import React, { useEffect } from 'react'; import GlideJs from '@glidejs/glide'; import '@glidejs/glide/dist/css/glide.core.min.css'; import { useWindowSize } from 'hooks/useWindowSize'; import { useSelector } from 'react-redux'; import CsLineIcons from 'cs-line-icons/CsLineIcons'; const Glide = ({ className = '', options = { gap: 0, rewind: false, bound: true, perView: 6, breakpoints: { 400: { perView: 1 }, 1000: { perView: 2 }, 1400: { perView: 3 }, 1900: { perView: 5 }, 3840: { perView: 6 }, }, }, noDots = false, noControls = false, children, }) => { const carouselRef = React.useRef(); const glideRef = React.useRef(); const { width } = useWindowSize(); const { placementStatus, behaviourStatus, attrMobile } = useSelector((state) => state.menu); const init = () => { glideRef.current = new GlideJs(carouselRef.current, options); if (!noDots) { glideRef.current.on(['mount.before'], () => { const bulletCount = glideRef.current.selector.querySelectorAll('.glide__slide').length; const bulletWrapper = glideRef.current.selector.querySelectorAll('.glide__bullets')[0]; if (!bulletWrapper) { return; } while (bulletWrapper.firstChild) { bulletWrapper.removeChild(bulletWrapper.firstChild); } for (let index = 0; index < bulletCount; index += 1) { const button = document.createElement('button'); button.className = 'glide__bullet'; button.setAttribute('data-glide-dir', `=${index}`); bulletWrapper.appendChild(button); } }); } // Hiding them with d-none if it is needed glideRef.current.on(['resize', 'build.after'], () => { const { perView } = glideRef.current.settings; const total = glideRef.current.selector.querySelectorAll('.glide__slide').length; const sub = total - perView; // Adds or removes d-none class glideRef.current.selector.querySelectorAll('.glide__bullet').forEach((el, i) => { if (i > sub) { el.classList.add('d-none'); } else { el.classList.remove('d-none'); } }); // Prevents the empty last stop when resized for a larger breakpoint with more items if (glideRef.current.index > sub && sub >= 0) { glideRef.current.go(`=${sub}`); } }); glideRef.current.mount(); }; const update = () => { glideRef.current.update(); }; const destroy = () => { glideRef.current.destroy(); }; useEffect(() => { init(); return () => { destroy(); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(() => { if (width && carouselRef.current && glideRef.current) { setTimeout(() => { update(); }, 10); } }, [width, placementStatus, behaviourStatus, attrMobile]); return ( <div ref={carouselRef} className={`glide ${className}`}> <div className="glide__track" data-glide-el="track"> <div className="glide__slides">{children}</div> {!noControls && ( <div className="text-center"> <span className="glide__arrows slider-nav" data-glide-el="controls"> <button type="button" className="btn btn-icon btn-icon-only btn-outline-primary" data-glide-dir="<"> <CsLineIcons icon="chevron-left" /> </button> </span>{' '} {!noDots && <span className="glide__bullets" data-glide-el="controls[nav]" />}{' '} <span className="glide__arrows slider-nav" data-glide-el="controls"> <button type="button" className="btn btn-icon btn-icon-only btn-outline-primary" data-glide-dir=">"> <CsLineIcons icon="chevron-right" /> </button> </span> </div> )} </div> </div> ); }; const Item = ({ className = '', children }) => <div className={`glide__slide ${className}`}>{children}</div>; Glide.Item = Item; Glide.Item.displayName = 'Item'; export default Glide;