@@ -14,30 +14,38 @@ interface ThemeProviderProps {
1414 children : ReactNode ;
1515}
1616
17- export const ThemeProvider : React . FC < ThemeProviderProps > = ( { children } ) => {
18- const [ theme , setThemeState ] = useState < Theme > ( 'system' ) ;
19- const [ effectiveTheme , setEffectiveTheme ] = useState < 'light' | 'dark' > ( 'light' ) ;
20-
21- // Initialize theme from localStorage or default to system
22- useEffect ( ( ) => {
17+ // Initialize theme from localStorage before component render
18+ const getInitialTheme = ( ) : Theme => {
19+ if ( typeof window !== 'undefined' ) {
2320 const savedTheme = localStorage . getItem ( 'theme' ) as Theme | null ;
2421 if ( savedTheme && [ 'light' , 'dark' , 'system' ] . includes ( savedTheme ) ) {
25- setThemeState ( savedTheme ) ;
22+ return savedTheme ;
2623 }
27- } , [ ] ) ;
24+ }
25+ return 'system' ;
26+ } ;
2827
29- // Update effective theme based on theme setting and system preference
30- useEffect ( ( ) => {
31- const updateEffectiveTheme = ( ) => {
32- if ( theme === 'system ') {
33- const systemPrefersDark = window . matchMedia ( '(prefers-color-scheme: dark)' ) . matches ;
34- setEffectiveTheme ( systemPrefersDark ? 'dark' : 'light' ) ;
35- } else {
36- setEffectiveTheme ( theme ) ;
37- }
38- } ;
28+ // Get effective theme based on theme setting
29+ const getEffectiveTheme = ( theme : Theme ) : 'light' | 'dark' => {
30+ if ( theme === 'system' ) {
31+ if ( typeof window !== 'undefined ') {
32+ return window . matchMedia ( '(prefers-color-scheme: dark)' ) . matches ? 'dark' : 'light' ;
33+ }
34+ return 'light' ;
35+ }
36+ return theme ;
37+ } ;
3938
40- updateEffectiveTheme ( ) ;
39+ export const ThemeProvider : React . FC < ThemeProviderProps > = ( { children } ) => {
40+ const [ theme , setThemeState ] = useState < Theme > ( getInitialTheme ) ;
41+ const [ effectiveTheme , setEffectiveTheme ] = useState < 'light' | 'dark' > (
42+ getEffectiveTheme ( getInitialTheme ( ) )
43+ ) ;
44+
45+ // Update effective theme when theme changes
46+ useEffect ( ( ) => {
47+ const newEffectiveTheme = getEffectiveTheme ( theme ) ;
48+ setEffectiveTheme ( newEffectiveTheme ) ;
4149
4250 // Listen for system preference changes when in system mode
4351 if ( theme === 'system' ) {
@@ -54,11 +62,17 @@ export const ThemeProvider: React.FC<ThemeProviderProps> = ({ children }) => {
5462 // Apply theme to document
5563 useEffect ( ( ) => {
5664 const root = document . documentElement ;
65+
5766 if ( effectiveTheme === 'dark' ) {
5867 root . classList . add ( 'dark' ) ;
5968 } else {
6069 root . classList . remove ( 'dark' ) ;
6170 }
71+
72+ // Also apply to body for background
73+ document . body . className = effectiveTheme === 'dark'
74+ ? 'bg-gray-900 text-gray-50'
75+ : 'bg-gray-50 text-gray-900' ;
6276 } , [ effectiveTheme ] ) ;
6377
6478 const setTheme = ( newTheme : Theme ) => {
0 commit comments