File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
import { useEffect, useState } from 'react'
/**
* 접을 수 있는 패널의 상태.
* - 사용자가 접거나 편 선택은 localStorage에 남아 새로고침 후에도 유지된다
* - 화면이 좁아져 미디어쿼리가 일치하면 자동으로 접힌다 (반응형)
* - 다시 넓어지면 사용자가 저장해 둔 선호로 복귀한다
*/
export function useCollapsiblePanel(storageKey: string, autoCollapseQuery: string) {
const [collapsed, setCollapsed] = useState<boolean>(() => {
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
}