22import { createContext , ReactNode , useContext , useEffect , useState } from "react" ;
33
44type Theme = "dark" | "light" | "system" ;
5+ type ResolvedTheme = "dark" | "light" ;
56
67type ThemeProviderProps = {
78 children : ReactNode ;
@@ -11,36 +12,50 @@ type ThemeProviderProps = {
1112
1213type ThemeProviderState = {
1314 theme : Theme ;
15+ resolvedTheme : ResolvedTheme ;
1416 setTheme : ( theme : Theme ) => void ;
1517} ;
1618
1719const initialState : ThemeProviderState = {
1820 theme : "system" ,
21+ resolvedTheme : "light" ,
1922 setTheme : ( ) => null ,
2023} ;
2124
2225const ThemeProviderContext = createContext < ThemeProviderState > ( initialState ) ;
2326
2427export function ThemeProvider ( { children, defaultTheme = "system" , storageKey = "vite-ui-theme" , ...props } : ThemeProviderProps ) {
2528 const [ theme , setTheme ] = useState < Theme > ( ( ) => ( localStorage . getItem ( storageKey ) as Theme ) || defaultTheme ) ;
29+ const [ resolvedTheme , setResolvedTheme ] = useState < ResolvedTheme > ( "light" ) ;
2630
2731 useEffect ( ( ) => {
2832 const root = window . document . documentElement ;
2933
3034 root . classList . remove ( "light" , "dark" ) ;
3135
3236 if ( theme === "system" ) {
33- const systemTheme = window . matchMedia ( "(prefers-color-scheme: dark)" ) . matches ? "dark" : "light" ;
37+ const mediaQuery = window . matchMedia ( "(prefers-color-scheme: dark)" ) ;
38+ const applySystemTheme = ( ) => {
39+ const systemTheme = mediaQuery . matches ? "dark" : "light" ;
3440
35- root . classList . add ( systemTheme ) ;
36- return ;
41+ root . classList . remove ( "light" , "dark" ) ;
42+ root . classList . add ( systemTheme ) ;
43+ setResolvedTheme ( systemTheme ) ;
44+ } ;
45+
46+ applySystemTheme ( ) ;
47+ mediaQuery . addEventListener ( "change" , applySystemTheme ) ;
48+
49+ return ( ) => mediaQuery . removeEventListener ( "change" , applySystemTheme ) ;
3750 }
3851
3952 root . classList . add ( theme ) ;
53+ setResolvedTheme ( theme ) ;
4054 } , [ theme ] ) ;
4155
4256 const value = {
4357 theme,
58+ resolvedTheme,
4459 setTheme : ( theme : Theme ) => {
4560 localStorage . setItem ( storageKey , theme ) ;
4661 setTheme ( theme ) ;
0 commit comments