42 lines
1016 B
TypeScript
42 lines
1016 B
TypeScript
import { useEffect, useMemo, useState } from "react";
|
|
import { ThemeProviderContext, type Theme, type ThemeProviderProps } from "../ThemeProvider";
|
|
|
|
|
|
export function ThemeProvider({
|
|
children,
|
|
defaultTheme = "system",
|
|
storageKey = "vite-ui-theme"
|
|
}: ThemeProviderProps){
|
|
const [ theme, setTheme ] = useState<Theme>(localStorage.getItem(storageKey) as Theme || defaultTheme);
|
|
|
|
|
|
useEffect(() => {
|
|
const root = window.document.documentElement;
|
|
root.classList.remove("light", "dark");
|
|
|
|
if(theme === "system"){
|
|
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
root.classList.add(systemTheme);
|
|
}
|
|
else{
|
|
root.classList.add(theme);
|
|
}
|
|
}, [ theme ]);
|
|
|
|
|
|
const currentTheme = useMemo(() => ({
|
|
theme,
|
|
setTheme: (theme: Theme) => {
|
|
localStorage.setItem(storageKey, theme);
|
|
setTheme(theme);
|
|
}
|
|
}), [ theme, storageKey ]);
|
|
|
|
|
|
return (
|
|
<ThemeProviderContext.Provider value={currentTheme}>
|
|
{children}
|
|
</ThemeProviderContext.Provider>
|
|
);
|
|
}
|