From d637f0a84984d4cbd9f3d2acbf033fdf8aa98e3a Mon Sep 17 00:00:00 2001 From: Muse Date: Sat, 14 Nov 2026 15:57:23 +0800 Subject: [PATCH] =?UTF-8?q?feat(theme):=20=E4=B8=BB=E9=A2=98=E6=95=B4?= =?UTF-8?q?=E5=A5=97=E8=81=94=E5=8A=A8=E2=80=94=E2=80=94=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E9=85=8D=E8=89=B2=E8=B7=9F=E9=9A=8F=E6=96=87=E6=A1=A3=E4=B8=BB?= =?UTF-8?q?=E9=A2=98=EF=BC=88docs/22=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 六套文档主题各加一组同气质的界面变量(data-doc-theme 驱动),选什么 主题,标题栏/菜单/侧边栏/状态栏就穿什么配色;界面跟随当前生效主题 (含单文档临时主题)。视图「深色主题」开关撤下,明暗并入主题; data-theme 退化为 paperTone 派生信号供 Mermaid/源码编辑器读取。 --- docs/22-theme-linkage.md | 30 ++++++++++++++++++++++ src/App.tsx | 9 +++---- src/components/Stage5Modals.tsx | 2 +- src/styles.css | 44 ++++++++++++++++++++++++--------- 4 files changed, 68 insertions(+), 17 deletions(-) create mode 100644 docs/22-theme-linkage.md diff --git a/docs/22-theme-linkage.md b/docs/22-theme-linkage.md new file mode 100644 index 0000000..5471ce9 --- /dev/null +++ b/docs/22-theme-linkage.md @@ -0,0 +1,30 @@ +# 主题整套联动(2026-11-14) + +## 需求 + +用户反馈「切换主题,只有文档变了」,拍板选「整套联动」:文档主题什么样, +界面配色也跟着成什么样。此前文档主题只作用于编辑区排版,界面另有独立的 +浅/深开关(视图菜单),两套互不相干。 + +## 实现 + +- styles.css 为六套文档主题各加一组界面变量(html[data-doc-theme='…']): + 背景/面板/边框/文字/次级文字/强调色/选中底/悬停/代码底,取自该主题文档 + 配色的气质(GitHub 蓝、Notion 暖灰、简约蓝、深色护眼墨绿深色、专注写作 + 暖纸、经典纸张米色)。默认主题沿用 :root 基础值。原 html[data-theme='dark'] + 界面变量块删除。 +- 界面跟随的是「当前生效主题」:全局主题,或当前文档的临时主题覆盖—— + 切到设了临时主题的文档,整个窗口跟着换装。 +- 视图菜单「深色主题」撤下:明暗已并入主题(选深色护眼即整套深色)。 + ui.theme 偏好字段保留在存量数据里但不再生效。 +- data-theme 属性保留为明暗派生信号(纸面为深色的主题 = dark),由文档 + 主题的 paperTone 派生,供 Mermaid 渲染主题等 JS 消费方读取;源码编辑器 + 的明暗同样改为按 paperTone 派生,不再回退 ui.theme。 + +## 验证 + +- 无头浏览器逐个切换 7 套主题,量 body/侧边栏/标题栏计算背景色:与各自 + 设计值逐一吻合(如深色护眼 body #1d221c、纸张 body #f3ecd7、GitHub + body #f6f8fa),文档纸面与框架同色系;深色护眼截图全窗墨绿深灰、文字 + 对比正常。 +- tsc 0 错误;vitest 全量通过;构建通过。 diff --git a/src/App.tsx b/src/App.tsx index 9552795..63aa597 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -196,7 +196,6 @@ export default function App() { const uiSaveTimerRef = useRef(undefined) useEffect(() => { - document.documentElement.dataset.theme = ui.theme if (!uiLoadedRef.current) return window.clearTimeout(uiSaveTimerRef.current) uiSaveTimerRef.current = window.setTimeout(() => { @@ -228,6 +227,9 @@ export default function App() { const effectiveDocTheme = (tab ? docOverrides[tab.id] : undefined) ?? ui.docTheme useEffect(() => { document.documentElement.dataset.docTheme = effectiveDocTheme + // 整套联动(docs/22):界面配色由 CSS 按 data-doc-theme 接管; + // data-theme 退化为明暗派生信号(深色纸面主题 = dark),供 Mermaid 等读取。 + document.documentElement.dataset.theme = docThemeById(effectiveDocTheme).paperTone === 'dark' ? 'dark' : 'light' }, [effectiveDocTheme]) useEffect(() => { @@ -1157,7 +1159,6 @@ export default function App() { { label: '文档大纲', checked: sidebarMode === 'outline', onClick: () => { setSidebarMode('outline'); setUi((u) => ({ ...u, sidebar: true })) } }, { divider: true }, { label: '源代码模式', checked: sourceMode, disabled: !tab, onClick: toggleSourceMode }, - { label: '深色主题', checked: ui.theme === 'dark', onClick: () => setUi((u) => ({ ...u, theme: u.theme === 'dark' ? 'light' : 'dark' })) }, { label: `自动保存(${ui.autosaveSeconds} 秒)`, checked: ui.autosave, onClick: () => setUi((u) => ({ ...u, autosave: !u.autosave })) }, { label: '专注模式', checked: ui.focusMode, disabled: sourceMode, onClick: () => setUi((u) => ({ ...u, focusMode: !u.focusMode })) }, { label: '打字机模式', checked: ui.typewriter, disabled: sourceMode, onClick: () => setUi((u) => ({ ...u, typewriter: !u.typewriter })) }, @@ -1260,9 +1261,7 @@ export default function App() { tabId={tab.id} initialText={tab.content} initialCursorOffset={sourceCursorOffset} - dark={docThemeById(effectiveDocTheme).paperTone - ? docThemeById(effectiveDocTheme).paperTone === 'dark' - : ui.theme === 'dark'} + dark={docThemeById(effectiveDocTheme).paperTone === 'dark'} onChange={(text) => dispatch({ type: 'updateContent', id: tab.id, content: text })} onReady={(api) => { sourceApiRef.current = api }} /> diff --git a/src/components/Stage5Modals.tsx b/src/components/Stage5Modals.tsx index cf5e96a..a967b28 100644 --- a/src/components/Stage5Modals.tsx +++ b/src/components/Stage5Modals.tsx @@ -26,7 +26,7 @@ export function AppearanceModal({ docTheme, override, customCss, autosave, autos
e.stopPropagation()}>

外观与设置

-
文档主题(作用于编辑区排版)
+
主题(文档排版与界面配色整套生效)
{DOC_THEMES.map((t) => (