@kadconsulting/dry
Version:
KAD Reusable Component Library
119 lines • 5.82 kB
JavaScript
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