UNPKG

@kadconsulting/dry

Version:
119 lines 5.82 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useEffect, forwardRef, useRef, useState, } from 'react'; import './CardCarousel.scss'; import useWindowSize from '../../hooks/useWindowSize'; import Icon from '../Icons/Icon/Icon'; import { ArrowLeft, ArrowRight } from '../Icons/paths'; import { IconSizes } from '../Icons/Icon/IconTypes'; import classNames from 'classnames'; const CardCarousel = forwardRef(({ cards, autoplay = false, interval = 5000, displayCount = 3, bubbleSelector = false, moveOneAtATime = false, buttonsBottom = false, displayButtons = false, 'data-testid': testId = 'card-carousel', ...restProps }, ref) => { const { width } = useWindowSize(); const [currentIndex, setCurrentIndex] = useState(0); const [paused, setPaused] = useState(!autoplay); const carouselRef = useRef(null); const touchStartRef = useRef(0); useEffect(() => { const timerId = setInterval(() => { if (!paused) { next(); } }, interval); return () => { clearInterval(timerId); }; }, [paused, interval]); const next = () => { if (carouselRef.current) { setCurrentIndex((prevIndex) => { const maxIndex = cards.length - displayCount; if (moveOneAtATime) { return Math.min(prevIndex + 1, maxIndex); } else { const nextIndex = prevIndex + displayCount; return nextIndex <= maxIndex ? nextIndex : prevIndex; } }); } }; const prev = () => { if (carouselRef.current) { setCurrentIndex((prevIndex) => { if (moveOneAtATime) { return Math.max(prevIndex - 1, 0); } else { const nextIndex = prevIndex - displayCount; return nextIndex >= 0 ? nextIndex : prevIndex; } }); } }; const pause = () => setPaused(true); const resume = () => setPaused(false); const handleKeyDown = (event) => { switch (event.key) { case 'ArrowRight': next(); break; case 'ArrowLeft': prev(); break; default: break; } }; const displayVisibleCards = () => { const visibleCards = cards.slice(currentIndex, currentIndex + displayCount); return (_jsx("div", { className: 'dry-card-carousel__content', ref: carouselRef, children: visibleCards.map((card, index) => (_jsx("div", { className: 'dry-card-carousel__card', style: { flex: `0 0 ${(width - (width / 100) * 25) / displayCount}px`, }, children: card }, index))) })); }; const displayBubbles = () => { const bubbleCount = moveOneAtATime ? cards.length - displayCount + 1 : Math.ceil(cards.length / displayCount); const bubbles = []; for (let index = 0; index < bubbleCount; index++) { bubbles.push(_jsx("button", { className: classNames('dry-card-carousel__bubble', { 'dry-card-carousel__bubble--active': index === (moveOneAtATime ? currentIndex : Math.floor(currentIndex / displayCount)), }), onClick: () => setCurrentIndex(moveOneAtATime ? index : index * displayCount) }, index)); } return bubbles; }; const handleTouchStart = (event) => { touchStartRef.current = event.touches[0].clientX; }; const handleTouchMove = (event) => { // Implement touch move logic if needed }; const handleTouchEnd = (event) => { const touchEnd = event.changedTouches[0].clientX; if (touchStartRef.current - touchEnd > 50) { next(); } else if (touchEnd - touchStartRef.current > 50) { prev(); } }; useEffect(() => { window.addEventListener('keydown', handleKeyDown); return () => { window.removeEventListener('keydown', handleKeyDown); }; }, []); const renderButtons = () => (_jsxs("div", { className: classNames('dry-card-carousel__buttons', { 'dry-card-carousel__buttons--bottom': buttonsBottom, 'dry-card-carousel__buttons--overlay': !buttonsBottom, }), children: [_jsx("div", { onClick: prev, className: classNames('dry-card-carousel__button', 'dry-card-carousel__button--back', { 'dry-card-carousel__button--disabled': currentIndex === 0, }), children: _jsx(Icon, { size: IconSizes.SMALL, Path: ArrowLeft }) }), _jsx("div", { onClick: next, className: classNames('dry-card-carousel__button', 'dry-card-carousel__button--forward', { 'dry-card-carousel__button--disabled': currentIndex + displayCount >= cards.length, }), children: _jsx(Icon, { size: IconSizes.SMALL, Path: ArrowRight }) })] })); return (_jsxs("div", { className: 'dry-card-carousel', onMouseEnter: pause, onMouseLeave: resume, onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, onTouchEnd: handleTouchEnd, ref: ref, "data-testid": testId, ...restProps, children: [_jsxs("div", { className: 'dry-card-carousel__content-wrapper', children: [displayVisibleCards(), !bubbleSelector && !buttonsBottom && renderButtons(), displayButtons && renderButtons()] }), !bubbleSelector && buttonsBottom && renderButtons(), bubbleSelector && (_jsx("div", { className: 'dry-card-carousel__bubbles', children: displayBubbles() }))] })); }); export default CardCarousel; //# sourceMappingURL=CardCarousel.js.map