"use client"; import { useState, useCallback, useEffect } from "react"; interface UseImageModalReturn { selectedIndex: number | null; isOpen: boolean; open: (index: number) => void; close: () => void; next: () => void; prev: () => void; goTo: (index: number) => void; } /** * 이미지 갤러리 모달을 관리하는 훅 * * @param totalImages 전체 이미지 개수 * @param options 추가 옵션 * * @example * const { selectedIndex, isOpen, open, close, next, prev } = useImageModal(images.length); * * // 이미지 클릭 시 *
open(index)}>...
* * // 모달에서 * {isOpen && ( * * * * * * )} */ export function useImageModal( totalImages: number, options: { loop?: boolean; enableKeyboard?: boolean; } = {} ): UseImageModalReturn { const { loop = true, enableKeyboard = true } = options; const [selectedIndex, setSelectedIndex] = useState(null); const isOpen = selectedIndex !== null; const open = useCallback((index: number) => { setSelectedIndex(index); }, []); const close = useCallback(() => { setSelectedIndex(null); }, []); const next = useCallback(() => { if (selectedIndex === null || totalImages === 0) return; if (loop) { setSelectedIndex((prev) => prev !== null && prev < totalImages - 1 ? prev + 1 : 0 ); } else { setSelectedIndex((prev) => prev !== null && prev < totalImages - 1 ? prev + 1 : prev ); } }, [selectedIndex, totalImages, loop]); const prev = useCallback(() => { if (selectedIndex === null || totalImages === 0) return; if (loop) { setSelectedIndex((prev) => prev !== null && prev > 0 ? prev - 1 : totalImages - 1 ); } else { setSelectedIndex((prev) => prev !== null && prev > 0 ? prev - 1 : prev ); } }, [selectedIndex, totalImages, loop]); const goTo = useCallback((index: number) => { if (index >= 0 && index < totalImages) { setSelectedIndex(index); } }, [totalImages]); // 키보드 네비게이션 useEffect(() => { if (!enableKeyboard || !isOpen) return; const handleKeyDown = (e: KeyboardEvent) => { switch (e.key) { case "ArrowLeft": prev(); break; case "ArrowRight": next(); break; case "Escape": close(); break; } }; window.addEventListener("keydown", handleKeyDown); return () => window.removeEventListener("keydown", handleKeyDown); }, [enableKeyboard, isOpen, next, prev, close]); return { selectedIndex, isOpen, open, close, next, prev, goTo, }; } export default useImageModal;