feat(ui): 工作台精修 + 拆分(P3-3..7)
- Workbench.tsx 937→467 行,抽出 AiToolbar/WorkbenchToolbar/MobileContextBar - P3-3 AI 工具条分组留白 + 眉题 + 主 CTA 凸显 - P3-4 专注写作模式(useFocusMode hook+vitest,隐藏侧栏加宽正文)+ 左双栏面色区分 - P3-5 右栏本章参考小标题去衬线(font-sans) + 空态引导(无标题保 h2→h3 大纲) - P3-6 底栏信息/操作/状态三区 + TOC 当前章高亮;TOC 状态点因无每章状态数据跳过 - P3-7 展示层流式跟随滚动(不触碰 SSE 逻辑,尊重 reduced-motion) - AppShell 加可选 hideNav(加法式,默认 false)
This commit is contained in:
61
apps/web/lib/workbench/useFocusMode.test.ts
Normal file
61
apps/web/lib/workbench/useFocusMode.test.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
// @vitest-environment jsdom
|
||||
import { act, renderHook } from "@testing-library/react";
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { FOCUS_MODE_KEY, useFocusMode } from "./useFocusMode";
|
||||
|
||||
// 本仓库 jsdom 未提供可用的 Storage(setItem/clear 缺失),装一个内存版 localStorage。
|
||||
function installMemoryStorage(): Storage {
|
||||
const map = new Map<string, string>();
|
||||
const storage: Storage = {
|
||||
get length() {
|
||||
return map.size;
|
||||
},
|
||||
clear: () => map.clear(),
|
||||
getItem: (key) => (map.has(key) ? (map.get(key) ?? null) : null),
|
||||
key: (index) => Array.from(map.keys())[index] ?? null,
|
||||
removeItem: (key) => map.delete(key),
|
||||
setItem: (key, value) => map.set(key, String(value)),
|
||||
};
|
||||
Object.defineProperty(window, "localStorage", {
|
||||
value: storage,
|
||||
configurable: true,
|
||||
});
|
||||
return storage;
|
||||
}
|
||||
|
||||
describe("useFocusMode", () => {
|
||||
beforeEach(() => {
|
||||
installMemoryStorage();
|
||||
});
|
||||
afterEach(() => {
|
||||
window.localStorage.clear();
|
||||
});
|
||||
|
||||
it("默认关闭(无存档时 focus=false)", () => {
|
||||
const { result } = renderHook(() => useFocusMode());
|
||||
expect(result.current.focus).toBe(false);
|
||||
});
|
||||
|
||||
it("toggle 翻转并把状态写入 localStorage", () => {
|
||||
const { result } = renderHook(() => useFocusMode());
|
||||
|
||||
act(() => result.current.toggle());
|
||||
|
||||
expect(result.current.focus).toBe(true);
|
||||
expect(window.localStorage.getItem(FOCUS_MODE_KEY)).toBe("1");
|
||||
|
||||
act(() => result.current.toggle());
|
||||
|
||||
expect(result.current.focus).toBe(false);
|
||||
expect(window.localStorage.getItem(FOCUS_MODE_KEY)).toBe("0");
|
||||
});
|
||||
|
||||
it("挂载时从 localStorage 恢复已开启状态", () => {
|
||||
window.localStorage.setItem(FOCUS_MODE_KEY, "1");
|
||||
|
||||
const { result } = renderHook(() => useFocusMode());
|
||||
|
||||
expect(result.current.focus).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user