WFDASHDRIVER-APP/lib/theme.ts
SJCoetz 3c8fc91b3e feat: add complete dark mode support with settings toggle
- Set up class-based dark mode in Tailwind config
- Add pre-hydration dark mode application to avoid theme flash on initial load
- Implement accessible dark mode toggle in settings page
- Update all UI surfaces (headers, bottom nav, maps) with dark mode color schemes
- Add comprehensive global CSS overrides for arbitrary Tailwind classes
- Add brand accent strips to header and bottom nav for consistent visual framing
- Refine map waypoint styling: reduce dot size, update label positioning and styling
2026-07-07 18:28:19 +02:00

54 lines
No EOL
1.9 KiB
TypeScript

/**
* Theme utilities — read / write the dark-mode preference and
* apply it to <html>.
*
* Dark mode is a class-based Tailwind strategy (see
* tailwind.config.js). The class is toggled on `<html>` and the
* CSS in `app/globals.css` does the heavy lifting via the
* `.dark { --surface-XXX }` overrides.
*
* The settings live in the same `1driver_settings` localStorage
* key as the rest of AppSettings — see `lib/pocketbase.ts:231`
* for the writer. We don't import the pocketbase module here so
* that `applyDarkMode` can run during the pre-hydration
* `import` phase in `app/layout.tsx` without dragging PB into
* a server-only context.
*/
const SETTINGS_KEY = '1driver_settings';
function readSettings(): { darkMode?: boolean } {
if (typeof window === 'undefined') return {};
try {
const raw = window.localStorage.getItem(SETTINGS_KEY);
if (!raw) return {};
return JSON.parse(raw) as { darkMode?: boolean };
} catch {
return {};
}
}
/** Apply the persisted dark-mode preference to <html>. */
export function applyDarkMode(): void {
if (typeof document === 'undefined') return;
const { darkMode } = readSettings();
document.documentElement.classList.toggle('dark', Boolean(darkMode));
}
/** Toggle the preference, persist it, and apply it. */
export function setDarkMode(enabled: boolean): void {
if (typeof document === 'undefined') return;
document.documentElement.classList.toggle('dark', enabled);
// Persist alongside the rest of AppSettings — merge with whatever
// is already there so we don't blow away locationInterval etc.
let current: Record<string, unknown> = {};
try {
const raw = window.localStorage.getItem(SETTINGS_KEY);
if (raw) current = JSON.parse(raw);
} catch {
/* corrupted JSON — start fresh */
}
current.darkMode = enabled;
window.localStorage.setItem(SETTINGS_KEY, JSON.stringify(current));
}