Skip to content

Dashboard appearance follows the OS with a System choice - #628

Draft
TonsOfFun wants to merge 1 commit into
mainfrom
feat/theme-follow-system
Draft

TonsOfFun wants to merge 1 commit into
mainfrom
feat/theme-follow-system

Conversation

@TonsOfFun

Copy link
Copy Markdown
Contributor

Closes #627. actionagent only; no migration. Bundle rebuilt with npm run build (a few hundred bytes of JS and CSS).

Settings → Appearance now offers System / Light / Dark instead of one dark-mode switch. System follows the OS appearance and changes with it while the page is open, which is also the default when nothing was chosen. Light and Dark are fixed, as the old toggle's choices were, and a choice that toggle saved still holds. The header's sun/moon button stays as the one-click flip: it picks the opposite of what shows and saves it as a fixed choice; System on the settings page follows the OS again.

Why the old toggle never followed the OS

ThemeProvider read prefers-color-scheme only when nothing was saved, then an effect saved light or dark on its first render, so the "only if the user hasn't set a preference" listener never fired again after the first visit.

What is in it

  • actionagent/frontend/utils/theme.mjs: the choice (readThemeChoice / writeThemeChoice, under the old dashboard-theme key; anything unknown reads as system, storage that throws is survived), resolveDarkMode(choice, systemDark), toggledChoice, themeDescription, and systemDarkQuery (null where the window has no matchMedia: server renders, some test windows).
  • contexts/ThemeContext.jsx: theme, systemDark, setTheme next to the darkMode and toggleDarkMode every component already reads; the media-query listener is always on, so switching back to System shows the current appearance at once, and it comes off with the provider.
  • SettingsView.jsx: the Appearance card is a "Theme" row with the shared SegmentedControl from primitives.jsx and a line that says what System is showing right now.
  • Header.jsx: a comment on what the sun/moon button now means; its behaviour is unchanged from the viewer's side.
  • CHANGELOG under Unreleased.

Tests

  • test/theme.test.mjs (6): the saved choice and its fallbacks, saving, resolution, the toggle's pick, the description, the query guard.
  • test/themeProvider.test.mjs (5), in a jsdom window whose media query the suite controls: nothing saved follows the system and its change events without saving anything; a saved fixed choice ignores the system and setTheme persists; System again shows the current appearance at once; the one-click toggle flips and saves a fixed choice; the listener comes off on unmount.
  • test/settingsCards.test.mjs (+1): the Appearance card offers System, Light and Dark, marks the saved choice, and the old copy is gone.
  • Full npm test in actionagent/frontend: 723 pass, 0 fail.

Not checked in a browser: the Settings page itself was not screenshotted; the control is the dashboard's existing SegmentedControl primitive.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EjYedJiSYGbTMY1NbL8mdK

Settings → Appearance offers System, Light and Dark instead of one
dark-mode switch. System, the default when nothing was chosen, follows
prefers-color-scheme and changes with it while the page is open; Light
and Dark are fixed, as the old toggle's choices were, and a choice that
toggle saved under dashboard-theme still holds. The header's sun/moon
button flips to the opposite of what shows and saves it as a fixed
choice.

The old provider read the OS preference once and then saved light or
dark on its first render, so its "follow the system" branch never ran
again. The choice and its resolution now live in utils/theme.mjs, with
the provider tested in a jsdom window whose media query the test flips.

Closes #627

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EjYedJiSYGbTMY1NbL8mdK

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dashboard appearance: a System option that follows the OS light/dark setting

1 participant