theme-watcher
v0.3.4
Published
Plug-and-play theme watcher for React SPAs
Downloads
22
Readme
theme-watcher
Zero-dependency theme watcher. Works with React, Tailwind, shadcn, or any CSS framework.
Install
npm i theme-watcherUsage
import { ThemeWatcher, useTheme } from "theme-watcher";
function App() {
return (
<>
<ThemeWatcher />
<ThemeToggle />
</>
);
}
function ThemeToggle() {
const { resolvedTheme, toggleMode } = useTheme();
return (
<button onClick={toggleMode}>
{resolvedTheme === "dark" ? "Light" : "Dark"}
</button>
);
}<ThemeWatcher /> handles:
- System preference detection (
prefers-color-scheme) - localStorage persistence
- Cross-tab synchronization
- DOM updates (sets
classordata-*attribute on<html>)
API
<ThemeWatcher />
Place once near your app root. Renders nothing.
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| theme | "light" \| "dark" | - | Force a specific theme (ignores storage/system) |
| defaultTheme | "light" \| "dark" \| "system" | "system" | Initial theme when no stored preference |
| storageKey | string | "theme" | localStorage key for persistence |
| attribute | "class" \| "data-*" | "class" | Attribute set on <html> (e.g., "data-theme") |
| enableColorScheme | boolean | true | Set color-scheme CSS property on <html> |
| disableTransitionOnChange | boolean | false | Disable CSS transitions during theme change |
useTheme()
Hook for reading and controlling theme state.
| Return | Type | Description |
|--------|------|-------------|
| theme | "light" \| "dark" \| "system" | Current stored preference |
| resolvedTheme | "light" \| "dark" | Actual applied theme (resolves "system" to OS preference) |
| systemTheme | "light" \| "dark" | Current OS preference |
| setTheme(t) | (t) => void | Set preference ("light", "dark", or "system") |
| set(t) | (t) => void | Alias for setTheme |
| get() | () => string | Read stored preference directly |
| toggleMode() | () => void | Toggle between "light" and "dark" |
Tailwind / shadcn Setup
Set darkMode: "class" in tailwind.config.js. No other configuration needed.
:root {
--background: #ffffff;
--foreground: #111111;
}
.dark {
--background: #111111;
--foreground: #ffffff;
}Data Attribute Mode
For CSS frameworks that use data-theme instead of class:
<ThemeWatcher attribute="data-theme" />:root[data-theme="light"] { /* ... */ }
:root[data-theme="dark"] { /* ... */ }Behavior
- On mount: reads localStorage (falls back to
defaultTheme) - If
"system": resolves viaprefers-color-schememedia query - Applies to
<html>: toggles class or sets data attribute - Listens for: OS preference changes, storage events (cross-tab sync)
- On change: updates DOM, localStorage, and all
useTheme()subscribers
