Files
suaveplan/apps/testbed/src/client/components/layout/theme-toggle.md
2026-05-27 23:29:53 +01:00

1.7 KiB

theme-toggle

Purpose

ThemeToggle is a button that toggles between light and dark visual themes. It applies the theme by setting a data-theme attribute on <html> (consumed by CSS custom properties and Tailwind dark mode variants) and persists the choice to localStorage["theme"]. On first render it reads the stored preference, falling back to the OS prefers-color-scheme media query.

Every E2E test for the testbed's theme feature interacts via data-testid="theme-toggle".

Features

  • Reads initial theme from localStorage["theme"] or prefers-color-scheme
  • Applies data-theme attribute to document.documentElement on every toggle
  • Persists selection to localStorage so choice survives page reloads
  • Accessible: aria-label updates to describe the next action
  • data-testid="theme-toggle" for deterministic Playwright targeting

Usage: Basic Example

import { ThemeToggle } from "./theme-toggle.js";
<ThemeToggle />

Usage: Advanced Example

// E2E -- toggle and verify data-theme attribute persists
await page.click('[data-testid="theme-toggle"]');
expect(await page.getAttribute("html", "data-theme")).toBe("dark");
await page.reload();
expect(await page.getAttribute("html", "data-theme")).toBe("dark");

API Reference

ThemeToggle(): JSX.Element

No props. Reads and writes localStorage["theme"]. Sets document.documentElement.dataset.theme.

Implementation Notes

The component does not accept a controlled theme prop -- the theme is global document state. getInitialTheme runs synchronously on the first render pass to avoid a flash of the default theme before the stored preference is applied.