import { useEffect, useState } from 'react' /** * 접을 수 있는 패널의 상태. * - 사용자가 접거나 편 선택은 localStorage에 남아 새로고침 후에도 유지된다 * - 화면이 좁아져 미디어쿼리가 일치하면 자동으로 접힌다 (반응형) * - 다시 넓어지면 사용자가 저장해 둔 선호로 복귀한다 */ export function useCollapsiblePanel(storageKey: string, autoCollapseQuery: string) { const [collapsed, setCollapsed] = useState(() => { if (typeof window === 'undefined') { return false } if (window.localStorage.getItem(storageKey) === '1') { return true } return ( typeof window.matchMedia === 'function' && window.matchMedia(autoCollapseQuery).matches ) }) useEffect(() => { // jsdom(테스트 환경)에는 matchMedia가 없다 if (typeof window.matchMedia !== 'function') { return } const mq = window.matchMedia(autoCollapseQuery) const onChange = (e: MediaQueryListEvent) => { setCollapsed(e.matches ? true : window.localStorage.getItem(storageKey) === '1') } mq.addEventListener('change', onChange) return () => mq.removeEventListener('change', onChange) }, [storageKey, autoCollapseQuery]) const toggle = () => { setCollapsed((prev) => { const next = !prev window.localStorage.setItem(storageKey, next ? '1' : '0') return next }) } return [collapsed, toggle] as const }