chatgpt2api / web /src /components /theme-toggle.tsx
peijun1's picture
clean deploy
dc03b36
Raw
History Blame Contribute Delete
1.73 kB
"use client";
import { Moon, Sun } from "lucide-react";
import { useEffect, useState } from "react";
type Theme = "light" | "dark";
const STORAGE_KEY = "chatgpt2api-theme";
function resolveInitialTheme(): Theme {
if (typeof window === "undefined") {
return "light";
}
const stored = window.localStorage.getItem(STORAGE_KEY);
if (stored === "light" || stored === "dark") {
return stored;
}
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
}
function applyTheme(theme: Theme) {
document.documentElement.classList.toggle("dark", theme === "dark");
document.documentElement.style.colorScheme = theme;
}
export function ThemeToggle() {
const [theme, setTheme] = useState<Theme>("light");
const isDark = theme === "dark";
useEffect(() => {
const nextTheme = resolveInitialTheme();
setTheme(nextTheme);
applyTheme(nextTheme);
}, []);
const toggleTheme = () => {
const nextTheme: Theme = isDark ? "light" : "dark";
window.localStorage.setItem(STORAGE_KEY, nextTheme);
setTheme(nextTheme);
applyTheme(nextTheme);
};
return (
<button
type="button"
aria-label={isDark ? "切换到浅色模式" : "切换到深色模式"}
title={isDark ? "浅色模式" : "深色模式"}
className="inline-flex size-8 shrink-0 items-center justify-center rounded-full border border-stone-200/80 bg-white/80 text-stone-500 shadow-sm transition hover:border-stone-300 hover:text-stone-900 dark:border-white/10 dark:bg-white/8 dark:text-stone-300 dark:hover:border-white/20 dark:hover:text-white"
onClick={toggleTheme}
>
{isDark ? <Sun className="size-4" /> : <Moon className="size-4" />}
</button>
);
}