import React, { useRef, useCallback, useState } from 'react'; function Carousel({ children, activeIndex, setActiveIndex, labels = [], showLabels = true, className = '' }) { const touchStartX = useRef(null); const touchStartY = useRef(null); const trackRef = useRef(null); const [dragOffset, setDragOffset] = useState(0); const [isDragging, setIsDragging] = useState(false); const itemCount = React.Children.count(children); const SWIPE_THRESHOLD = 50; const handleTouchStart = useCallback((e) => { touchStartX.current = e.touches[0].clientX; touchStartY.current = e.touches[0].clientY; setIsDragging(true); }, []); const handleTouchMove = useCallback((e) => { if (!touchStartX.current || !isDragging) return; const currentX = e.touches[0].clientX; const currentY = e.touches[0].clientY; const diffX = currentX - touchStartX.current; const diffY = Math.abs(currentY - touchStartY.current); // Only drag horizontally if not scrolling vertically if (Math.abs(diffX) > diffY) { // Add resistance at edges let offset = diffX; if ((activeIndex === 0 && diffX > 0) || (activeIndex === itemCount - 1 && diffX < 0)) { offset = diffX * 0.25; } setDragOffset(offset); } }, [isDragging, activeIndex, itemCount]); const handleTouchEnd = useCallback((e) => { if (!touchStartX.current) return; const diff = touchStartX.current - e.changedTouches[0].clientX; if (Math.abs(diff) > SWIPE_THRESHOLD) { if (diff > 0 && activeIndex < itemCount - 1) { setActiveIndex(activeIndex + 1); } else if (diff < 0 && activeIndex > 0) { setActiveIndex(activeIndex - 1); } } touchStartX.current = null; touchStartY.current = null; setDragOffset(0); setIsDragging(false); }, [activeIndex, setActiveIndex, itemCount]); const handleKeyDown = useCallback((e) => { if (e.key === 'ArrowLeft' && activeIndex > 0) { setActiveIndex(activeIndex - 1); } else if (e.key === 'ArrowRight' && activeIndex < itemCount - 1) { setActiveIndex(activeIndex + 1); } }, [activeIndex, setActiveIndex, itemCount]); // Calculate transform with drag offset const baseTransform = -(activeIndex * 100); const dragPercent = trackRef.current ? (dragOffset / trackRef.current.offsetWidth) * 100 : 0; const transform = baseTransform + dragPercent; return (
{React.Children.map(children, (child, i) => (
{child}
))}
{Array.from({ length: itemCount }).map((_, i) => ( ))}
); } export default Carousel;