Skip to content

feat: system-aware color mode with browser-mode tests#1

Closed
rqbazan wants to merge 2 commits into
mainfrom
feat/system-color-mode
Closed

feat: system-aware color mode with browser-mode tests#1
rqbazan wants to merge 2 commits into
mainfrom
feat/system-color-mode

Conversation

@rqbazan

@rqbazan rqbazan commented Jun 27, 2026

Copy link
Copy Markdown
Member

Summary

  • Bug fix — system mode now follows the OS. Both useColorMode (src/index.ts) and the inline pre-paint script (src/initial.ts) resolve system against matchMedia("(prefers-color-scheme: dark)"). The hook also tracks OS changes live while in system mode. Previously system always rendered light, because the apply step only checked for an explicit dark value and fell through to removing the class otherwise.
  • Integration tests in a real browser. New suite under test/functional runs via Vitest Browser Mode + Playwright (headless Chromium), covering both entry points: the npm hook and the inline IIFE script.
  • Tooling & docs. Biome, tsdown (lib + IIFE build), tsconfig, Vitest browser config, CI workflows, and a rewritten README documenting usage, styling, and the window.__COLOR_MODE__ runtime contract.

The bug

if (mode === COLOR_MODE.DARK) {
  document.documentElement.classList.add("dark");
} else {
  document.documentElement.classList.remove("dark"); // ← system always landed here
}

A user on system with an OS dark preference saw the light theme. The same gap existed in initial.ts for a persisted system value (the matchMedia branch only ran on first visit). Both sites now resolve system via prefers-color-scheme.

Note: the inline script's first-visit default is now system (resolved against the OS) instead of baking a concrete dark/light into storage — so system keeps following the OS over time.

Tests

  • 18 tests / 2 files, all passing in headless Chromium.
  • Hook: init from localStorage, invalid-value fallback + console.error, setMode side effects (class / localStorage / CustomEvent), and system following the OS both statically and on a live change.
  • Inline script: explicit light/dark, persisted system + OS dark→dark / light, first-visit defaults, unavailable media query, and the window.__COLOR_MODE__ contract. The side-effectful module is re-evaluated per case via a cache-busting dynamic import (vi.resetModules() does not re-run native modules in Browser Mode).

Run locally with pnpm test.

🤖 Generated with Claude Code

vland and others added 2 commits June 26, 2026 09:24
useColorMode and the inline pre-paint script now resolve "system" against
the OS prefers-color-scheme, and the hook tracks OS changes live while in
system mode. Previously "system" always rendered light because the apply
step only checked for an explicit "dark" value.

Add functional tests under test/functional that run in a real browser via
Vitest Browser Mode + Playwright, covering both entry points: the npm hook
(src/index.ts) and the inline IIFE script (src/initial.ts).

Set up project tooling (Biome, tsdown lib + IIFE build, tsconfig, Vitest
browser config, CI workflows) and document usage, styling, and the
window.__COLOR_MODE__ runtime contract in the README.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

1 participant