import React, { useState, useRef, useEffect } from 'react'; const SwipeToComplete = ({ onComplete, disabled, label = "Slide to Complete" }) => { const [startX, setStartX] = useState(0); const [currentX, setCurrentX] = useState(0); const [isDragging, setIsDragging] = useState(false); const [isCompleted, setIsCompleted] = useState(false); const containerRef = useRef(null); const thumbRef = useRef(null); const handleStart = (e) => { if (disabled || isCompleted) return; const clientX = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX; setStartX(clientX - currentX); setIsDragging(true); }; const handleMove = (e) => { if (!isDragging || disabled || isCompleted) return; const clientX = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX; const containerWidth = containerRef.current.offsetWidth; const thumbWidth = thumbRef.current.offsetWidth; const maxDrag = containerWidth - thumbWidth - 10; // 5px padding on each side let newX = clientX - startX; if (newX < 0) newX = 0; if (newX > maxDrag) { newX = maxDrag; setIsCompleted(true); setIsDragging(false); if (onComplete) onComplete(); } setCurrentX(newX); }; const handleEnd = () => { if (!isCompleted) { setIsDragging(false); setCurrentX(0); // snap back } }; useEffect(() => { if (isDragging) { window.addEventListener('mousemove', handleMove); window.addEventListener('mouseup', handleEnd); window.addEventListener('touchmove', handleMove); window.addEventListener('touchend', handleEnd); } else { window.removeEventListener('mousemove', handleMove); window.removeEventListener('mouseup', handleEnd); window.removeEventListener('touchmove', handleMove); window.removeEventListener('touchend', handleEnd); } return () => { window.removeEventListener('mousemove', handleMove); window.removeEventListener('mouseup', handleEnd); window.removeEventListener('touchmove', handleMove); window.removeEventListener('touchend', handleEnd); }; }, [isDragging, isCompleted, handleMove, handleEnd]); return (
50 && !isCompleted ? 'opacity-0' : 'opacity-100'}`}> {isCompleted ? 'Completed' : label}
{isCompleted ? 'check' : 'chevron_right'}
); }; export default SwipeToComplete;