"use client"; /** * 자동 슬라이드 표시 모드 * * 전광판처럼 자동 전환, 터치 시 멈춤, 일정 시간 후 재개 * 컴포넌트 unmount 시 타이머 정리 필수 */ import React, { useState, useEffect, useRef, useCallback } from "react"; // ===== Props ===== export interface AutoSlideModeProps { /** 총 아이템 수 */ itemCount: number; /** 자동 전환 간격 (초, 기본 5) */ interval?: number; /** 터치 후 자동 재개까지 대기 시간 (초, 기본 3) */ resumeDelay?: number; /** 페이지 인디케이터 표시 여부 */ showIndicator?: boolean; /** 현재 인덱스에 해당하는 아이템 렌더링 */ renderItem: (index: number) => React.ReactNode; } // ===== 메인 컴포넌트 ===== export function AutoSlideModeComponent({ itemCount, interval = 5, resumeDelay = 3, showIndicator = true, renderItem, }: AutoSlideModeProps) { const [currentIndex, setCurrentIndex] = useState(0); const [isPaused, setIsPaused] = useState(false); const intervalRef = useRef | null>(null); const resumeTimerRef = useRef | null>(null); // 타이머 정리 함수 const clearTimers = useCallback(() => { if (intervalRef.current) { clearInterval(intervalRef.current); intervalRef.current = null; } if (resumeTimerRef.current) { clearTimeout(resumeTimerRef.current); resumeTimerRef.current = null; } }, []); // 자동 슬라이드 시작 const startAutoSlide = useCallback(() => { clearTimers(); if (itemCount <= 1) return; intervalRef.current = setInterval(() => { setCurrentIndex((prev) => (prev + 1) % itemCount); }, interval * 1000); }, [itemCount, interval, clearTimers]); // 터치/클릭으로 일시 정지 const handlePause = useCallback(() => { setIsPaused(true); clearTimers(); // resumeDelay 후 자동 재개 resumeTimerRef.current = setTimeout(() => { setIsPaused(false); startAutoSlide(); }, resumeDelay * 1000); }, [resumeDelay, clearTimers, startAutoSlide]); // 마운트 시 자동 슬라이드 시작, unmount 시 정리 useEffect(() => { if (!isPaused) { startAutoSlide(); } return clearTimers; }, [isPaused, startAutoSlide, clearTimers]); if (itemCount === 0) { return (
아이템 없음
); } return (
{/* 콘텐츠 (슬라이드 애니메이션) */}
{Array.from({ length: itemCount }).map((_, i) => (
{renderItem(i)}
))}
{/* 인디케이터 + 일시정지 표시 */} {showIndicator && itemCount > 1 && (
{isPaused && ( 일시정지 )} {Array.from({ length: itemCount }).map((_, i) => ( ))}
)}
); }