From 65f6ffe5cd30546dbd8389ee31e972e577528198 Mon Sep 17 00:00:00 2001 From: yokuisiti Date: Wed, 27 May 2026 09:13:59 +0000 Subject: [PATCH] feat: add dark mode toggle (#31) - Add ThemeToggle component with sun/moon icon button - Persists preference to localStorage (sorosave-theme) - Falls back to system prefers-color-scheme on first visit - CSS class-based dark mode (.dark on ) for instant toggle - Smooth 200ms transition on background/color change - Integrated into Navbar next to ConnectWallet button Closes #31 --- src/app/globals.css | 10 ++++---- src/app/layout.tsx | 4 ++-- src/components/Navbar.tsx | 6 ++++- src/components/ThemeToggle.tsx | 43 ++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 src/components/ThemeToggle.tsx diff --git a/src/app/globals.css b/src/app/globals.css index fb4bd21..065152f 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -7,14 +7,14 @@ --background: #ffffff; } -@media (prefers-color-scheme: dark) { - :root { - --foreground: #ededed; - --background: #0a0a0a; - } +/* Dark mode via class (controlled by ThemeToggle) */ +.dark { + --foreground: #ededed; + --background: #0a0a0a; } body { color: var(--foreground); background: var(--background); + transition: background-color 0.2s ease, color 0.2s ease; } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 17200f3..cd77f19 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -14,8 +14,8 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( - - + + {children} diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 2d673aa..b7d117c 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -2,6 +2,7 @@ import Link from "next/link"; import { ConnectWallet } from "./ConnectWallet"; +import { ThemeToggle } from "./ThemeToggle"; export function Navbar() { return ( @@ -27,7 +28,10 @@ export function Navbar() { - +
+ + +
diff --git a/src/components/ThemeToggle.tsx b/src/components/ThemeToggle.tsx new file mode 100644 index 0000000..80b680d --- /dev/null +++ b/src/components/ThemeToggle.tsx @@ -0,0 +1,43 @@ +"use client"; + +import { useEffect, useState } from "react"; + +export function ThemeToggle() { + const [dark, setDark] = useState(false); + + // On mount, read saved preference or system preference + useEffect(() => { + const saved = localStorage.getItem("sorosave-theme"); + const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; + const isDark = saved ? saved === "dark" : prefersDark; + setDark(isDark); + document.documentElement.classList.toggle("dark", isDark); + }, []); + + const toggle = () => { + const next = !dark; + setDark(next); + document.documentElement.classList.toggle("dark", next); + localStorage.setItem("sorosave-theme", next ? "dark" : "light"); + }; + + return ( + + ); +}