Files
gogs/web/src/lib/theme.ts
T

42 lines
1.2 KiB
TypeScript

import { useEffect, useState } from "react";
export type Theme = "light" | "dark" | "system";
const STORAGE_KEY = "gogs-theme";
function systemPrefersDark(): boolean {
return typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches;
}
function readStoredTheme(): Theme {
if (typeof localStorage === "undefined") return "system";
const v = localStorage.getItem(STORAGE_KEY);
return v === "light" || v === "dark" || v === "system" ? v : "system";
}
function applyTheme(theme: Theme) {
const dark = theme === "dark" || (theme === "system" && systemPrefersDark());
document.documentElement.classList.toggle("dark", dark);
}
export function useTheme() {
const [theme, setThemeState] = useState<Theme>(readStoredTheme);
useEffect(() => {
applyTheme(theme);
if (theme !== "system") return;
const mq = window.matchMedia("(prefers-color-scheme: dark)");
const onChange = () => applyTheme("system");
mq.addEventListener("change", onChange);
return () => mq.removeEventListener("change", onChange);
}, [theme]);
const setTheme = (next: Theme) => {
localStorage.setItem(STORAGE_KEY, next);
setThemeState(next);
applyTheme(next);
};
return { theme, setTheme };
}