feat: 深色模式手动开关(三态:跟随系统 / 浅色 / 深色) - #9
Merged
Conversation
The dark palette already existed but only ever came from prefers-color-scheme, so a user could not choose it. tokens.css now reaches the same palette through .theme-dark, and .theme-light opts out of the media query so forcing light survives a dark desktop. Three states rather than a toggle: "system" is a real choice, and it carries no class at all so the media query stays in charge. A two-state switch would have to guess what "off" means the moment the desktop flips. The palette is written twice because CSS cannot share a declaration list between a media query and a class. A test compares the two blocks so they cannot drift, and asserts the sizing tokens stay out of them: duplicating --sidebar-width there would drop it whenever light was forced. index.html applies the stored class before the first paint, and the provider writes one resolved theme-color meta tag, since the two media-driven tags cannot see a forced palette. ThemePicker sits first in the sidebar's bottom group so its margin-top: auto pushes appearance, language and the task centre down together. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #6
改动
深色配色本来就完整存在,但只由
prefers-color-scheme驱动,用户无法选择。现在tokens.css让同一份暗色变量也能通过.theme-dark命中,.theme-light则用:not()退出媒体查询,所以在深色桌面上强制浅色能生效。三态而不是开关。「跟随系统」是一个真实的选项,它不加任何 class,正是这样才把决定权留给 CSS 媒体查询。二态开关在桌面主题切换的瞬间必须猜"关"是什么意思,而想跟随系统的用户没有办法表达这个意愿。
控件做成
<select>,与紧邻的语言选择器同构;图标反映当前实际生效的配色,所以选「跟随系统」时显示的是太阳或月亮,而不是一个含义模糊的图标。两个容易出错的地方
暗色调色板写了两遍。 CSS 无法在媒体查询和 class 之间共享声明列表。我没有用变通手段掩盖这一点,而是加了一个测试对比两个块的变量集合,确保它们不会漂移——并做了变异测试验证守卫有效(只改其中一块的
--page-bg会立刻失败)。尺寸变量必须留在
:root。--radius-*、--sidebar-width、--footer-height只在浅色块定义一次。如果跟着复制进暗色块,强制浅色时就会丢失。另有一个测试断言暗色块里不含这些变量。浏览器实测确认三种状态下--sidebar-width都是 232px。防闪烁与窗口色
index.html用 inline script 在首次绘制前就设好 class。另外 index.html 里那两个theme-colormeta 是 media 驱动的,看不到手动选择,所以 provider 会写一个 resolved 的 meta 覆盖它们——否则窗口边框色会和内容不一致。一个实测中发现并修掉的布局 bug
我最初把
ThemePicker放在语言选择器之后,而margin-top: auto移到了它身上。结果语言选择器失去下推作用,停留在侧边栏上方(top=225),外观和任务中心却在底部。改成ThemePicker排在这组的第一位,三者才作为一组贴底。浏览器实测确认顺序为 外观 722 → 语言 760 → 任务中心 808。验证
tsc --noEmit与生产构建通过#151517、浅色#ececef、跟随系统无 classstorage key 用
oneagent.theme,与 app 内oneagent.locale的点号风格一致(site 用的是连字符oneagent-theme,但两者不共享 storage,不必迁就)。🤖 Generated with Claude Code