useChapterListCollapse 用 localStorage 记忆折叠态(SSR 首帧恒展开避免 hydration 不一致);收起降为带展开按钮的窄轨、让宽给正文,展开时标题旁加收起按钮;三栏栅格据折叠态切列宽,章节列表/高亮/切章导航全保留。
47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
"use client";
|
||
|
||
import { useCallback, useEffect, useState } from "react";
|
||
|
||
// 「目录」列折叠偏好的持久化键(对齐既有 `ww.` 前缀约定)。
|
||
export const CHAPTER_LIST_COLLAPSE_KEY = "ww.workbench_chapter_list_collapsed";
|
||
|
||
export interface ChapterListCollapse {
|
||
// true=目录列收起(让宽给正文);false=展开。
|
||
collapsed: boolean;
|
||
toggle: () => void;
|
||
}
|
||
|
||
function persist(collapsed: boolean): void {
|
||
if (typeof window === "undefined") return;
|
||
try {
|
||
window.localStorage.setItem(CHAPTER_LIST_COLLAPSE_KEY, collapsed ? "1" : "0");
|
||
} catch {
|
||
// 隐私模式/配额异常忽略:折叠是纯 UI 偏好,写盘失败不影响导航功能。
|
||
}
|
||
}
|
||
|
||
// 记住「目录」列收起/展开状态(P2-2):SSR 首帧恒展开(避免 hydration 不一致),
|
||
// 挂载后再从 localStorage 恢复;toggle 即时写回。仅桌面(≥xl)用得上,窄屏走抽屉不受影响。
|
||
export function useChapterListCollapse(): ChapterListCollapse {
|
||
const [collapsed, setCollapsed] = useState(false);
|
||
|
||
useEffect(() => {
|
||
if (typeof window === "undefined") return;
|
||
try {
|
||
setCollapsed(window.localStorage.getItem(CHAPTER_LIST_COLLAPSE_KEY) === "1");
|
||
} catch {
|
||
// 读盘失败则维持默认展开。
|
||
}
|
||
}, []);
|
||
|
||
const toggle = useCallback(() => {
|
||
setCollapsed((prev) => {
|
||
const next = !prev;
|
||
persist(next);
|
||
return next;
|
||
});
|
||
}, []);
|
||
|
||
return { collapsed, toggle };
|
||
}
|