Add dark mode toggle in the sidebar
Adds a persistent dark/light theme toggle (localStorage + data-bs-theme on <html>) so it applies globally, including the circuit editor route which has no visible sidebar. An inline beforeInteractive script sets the theme before hydration to avoid a flash of the wrong theme. Bootstrap components pick up data-bs-theme automatically; the custom circuit-grid CSS previously used ~150 hardcoded hex colors, all converted to semantic tokens in globals.css with light/dark values. Verified with a headless-browser pass across the project list, project detail page, circuit editor, project-device drawer and a settings modal in both themes; no console errors. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
a99980c47b
commit
64ccd1f829
4 changed files with 395 additions and 127 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import type { Metadata } from "next";
|
||||
import Script from "next/script";
|
||||
import "bootstrap/dist/css/bootstrap.min.css";
|
||||
import "./globals.css";
|
||||
import { AppShell } from "../frontend/components/AppShell";
|
||||
|
|
@ -8,10 +9,33 @@ export const metadata: Metadata = {
|
|||
description: "Leistungsbilanz für elektrische Verbraucher und Stromkreislisten",
|
||||
};
|
||||
|
||||
// Keep this key literal in sync with THEME_STORAGE_KEY in ThemeToggle.tsx.
|
||||
// It must stay inline (not imported) so it runs before hydration and never
|
||||
// flashes the wrong theme on load.
|
||||
const THEME_INIT_SCRIPT = `
|
||||
(function () {
|
||||
try {
|
||||
var stored = localStorage.getItem("leistungsbilanz:theme");
|
||||
var theme =
|
||||
stored === "dark" || stored === "light"
|
||||
? stored
|
||||
: window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
? "dark"
|
||||
: "light";
|
||||
document.documentElement.setAttribute("data-bs-theme", theme);
|
||||
} catch (error) {
|
||||
// Storage/matchMedia unavailable: fall back to the default light theme.
|
||||
}
|
||||
})();
|
||||
`;
|
||||
|
||||
export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
|
||||
return (
|
||||
<html lang="de">
|
||||
<html lang="de" suppressHydrationWarning>
|
||||
<body>
|
||||
<Script id="theme-init" strategy="beforeInteractive">
|
||||
{THEME_INIT_SCRIPT}
|
||||
</Script>
|
||||
<AppShell>{children}</AppShell>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue