From b923ac89474df0e96fd2f92352ff6caf93b92b49 Mon Sep 17 00:00:00 2001 From: vince Date: Sat, 20 Jun 2026 00:58:30 +0200 Subject: [PATCH] fix(ui): harden theme toggle accessibility --- src/App.test.tsx | 1 + src/App.tsx | 12 ++++++-- src/lib/ui/components/ThemeToggle.tsx | 1 - src/lib/ui/stories/ThemeToggle.stories.tsx | 5 ++++ src/lib/ui/theme.test.ts | 21 ++++++++++++++ src/lib/ui/theme.ts | 26 ++++++++++++++---- tests/e2e/dashboard.spec.ts | 18 ++++++++++++ ...d-light-desktop-chromium-desktop-linux.png | Bin 0 -> 280194 bytes 8 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 tests/e2e/dashboard.spec.ts-snapshots/dashboard-light-desktop-chromium-desktop-linux.png diff --git a/src/App.test.tsx b/src/App.test.tsx index b14edf1..b7abbc7 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -35,6 +35,7 @@ describe("React app dashboard state view", () => { expect(html).toContain('data-ui-theme-toggle="true"'); expect(html).toContain('aria-label="Switch to light theme"'); + expect(html).not.toContain("aria-pressed"); expect(html).toContain("Dark"); }); }); diff --git a/src/App.tsx b/src/App.tsx index 081d630..99cdc5e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -93,7 +93,7 @@ export default function App() { const [theme, setTheme] = useState(() => { if (typeof window === "undefined") return "dark"; - return resolveInitialUiTheme(window.localStorage); + return resolveInitialUiTheme(getThemeStorage()); }); useEffect(() => { @@ -113,7 +113,7 @@ export default function App() { useEffect(() => { document.documentElement.dataset.uiTheme = theme; - persistUiTheme(theme, window.localStorage); + persistUiTheme(theme, getThemeStorage()); }, [theme]); useEffect(() => { @@ -173,3 +173,11 @@ function stateIcon(state: DashboardRuntimeState["state"]): string { if (state === "loading") return "mdi:progress-clock"; return "mdi:tray"; } + +function getThemeStorage(): Storage | undefined { + try { + return window.localStorage; + } catch { + return undefined; + } +} diff --git a/src/lib/ui/components/ThemeToggle.tsx b/src/lib/ui/components/ThemeToggle.tsx index 46455fc..1c8fb1a 100644 --- a/src/lib/ui/components/ThemeToggle.tsx +++ b/src/lib/ui/components/ThemeToggle.tsx @@ -14,7 +14,6 @@ export function ThemeToggle({ theme, onThemeChange }: ThemeToggleProps) { return (