59 lines
1.5 KiB
TypeScript
59 lines
1.5 KiB
TypeScript
import { useState, useCallback, useRef } from "react";
|
|
|
|
/**
|
|
* 설정 패널 접기/펼치기 상태를 sessionStorage로 기억하는 훅
|
|
*
|
|
* - 초기 상태: 모든 섹션 접힘
|
|
* - 사용자가 펼친 섹션은 같은 탭 세션 내에서 기억
|
|
* - 탭 닫으면 초기화
|
|
*
|
|
* @param storageKey sessionStorage 키 (예: "pop-card-list")
|
|
*/
|
|
export function useCollapsibleSections(storageKey: string) {
|
|
const fullKey = `pop-config-sections-${storageKey}`;
|
|
|
|
const [openSections, setOpenSections] = useState<Set<string>>(() => {
|
|
if (typeof window === "undefined") return new Set<string>();
|
|
try {
|
|
const saved = sessionStorage.getItem(fullKey);
|
|
if (saved) return new Set<string>(JSON.parse(saved));
|
|
} catch {}
|
|
return new Set<string>();
|
|
});
|
|
|
|
const openSectionsRef = useRef(openSections);
|
|
openSectionsRef.current = openSections;
|
|
|
|
const persist = useCallback(
|
|
(next: Set<string>) => {
|
|
try {
|
|
sessionStorage.setItem(fullKey, JSON.stringify([...next]));
|
|
} catch {}
|
|
},
|
|
[fullKey],
|
|
);
|
|
|
|
const isOpen = useCallback(
|
|
(key: string) => openSectionsRef.current.has(key),
|
|
[],
|
|
);
|
|
|
|
const toggle = useCallback(
|
|
(key: string) => {
|
|
setOpenSections((prev) => {
|
|
const next = new Set(prev);
|
|
if (next.has(key)) {
|
|
next.delete(key);
|
|
} else {
|
|
next.add(key);
|
|
}
|
|
persist(next);
|
|
return next;
|
|
});
|
|
},
|
|
[persist],
|
|
);
|
|
|
|
return { isOpen, toggle };
|
|
}
|