Initial Commit
This commit is contained in:
48
apps/testbed/src/client/components/layout/theme-toggle.md
Normal file
48
apps/testbed/src/client/components/layout/theme-toggle.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
|
||||
```tsx
|
||||
import { ThemeToggle } from "./theme-toggle.js";
|
||||
<ThemeToggle />
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```tsx
|
||||
// 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.
|
||||
Reference in New Issue
Block a user