11'use client'
22
3- import React , { createContext , useContext , ReactNode , useState , useEffect , useCallback } from 'react'
3+ import React , { createContext , useContext , ReactNode , useState , useEffect , useCallback , useMemo } from 'react'
44import { NETWORK_COLORS , SEMANTIC_COLORS , ELEVATION_LEVELS } from './themeConstants'
55
66interface ThemeContextType {
@@ -33,12 +33,14 @@ interface ThemeProviderProps {
3333}
3434
3535export function ThemeProvider ( { children, initialNetworkId = 'polkadot' } : ThemeProviderProps ) {
36- const [ isDarkTheme , setIsDarkTheme ] = useState < boolean > ( true ) ;
36+ const [ isDarkTheme , setIsDarkTheme ] = useState < boolean > ( false ) ;
3737 const [ isLoaded , setIsLoaded ] = useState < boolean > ( false ) ;
3838 const [ currentNetworkId , setCurrentNetworkId ] = useState < string > ( initialNetworkId ) ;
39+ const [ mounted , setMounted ] = useState ( false ) ;
3940
40-
4141 const applyTheme = useCallback ( ( isDark : boolean , networkId : string ) => {
42+ if ( typeof window === 'undefined' ) return ;
43+
4244 document . documentElement . setAttribute ( 'data-theme' , isDark ? 'dark' : 'light' ) ;
4345 document . documentElement . setAttribute ( 'data-network' , networkId ) ;
4446
@@ -59,9 +61,8 @@ export function ThemeProvider({ children, initialNetworkId = 'polkadot' }: Theme
5961 } ) ;
6062 } , [ ] ) ;
6163
62-
6364 useEffect ( ( ) => {
64- if ( typeof window === 'undefined' ) return ;
65+ setMounted ( true ) ;
6566
6667 const storedTheme = localStorage . getItem ( 'theme' ) ;
6768 const storedNetwork = localStorage . getItem ( 'currentNetwork' ) ;
@@ -71,19 +72,17 @@ export function ThemeProvider({ children, initialNetworkId = 'polkadot' }: Theme
7172 setCurrentNetworkId ( storedNetwork ) ;
7273 }
7374
75+ let isDark : boolean ;
7476 if ( storedTheme ) {
75- const isDark = storedTheme === 'dark' ;
76- setIsDarkTheme ( isDark ) ;
77- applyTheme ( isDark , networkToUse ) ;
77+ isDark = storedTheme === 'dark' ;
7878 } else {
79- const prefersDark = window . matchMedia ( '(prefers-color-scheme: dark)' ) . matches ;
80- setIsDarkTheme ( prefersDark ) ;
81- applyTheme ( prefersDark , networkToUse ) ;
79+ isDark = window . matchMedia ( '(prefers-color-scheme: dark)' ) . matches ;
8280 }
8381
82+ setIsDarkTheme ( isDark ) ;
83+ applyTheme ( isDark , networkToUse ) ;
8484 setIsLoaded ( true ) ;
8585
86-
8786 const mediaQuery = window . matchMedia ( '(prefers-color-scheme: dark)' ) ;
8887 const handleChange = ( e : MediaQueryListEvent ) => {
8988 if ( ! localStorage . getItem ( 'theme' ) ) {
@@ -94,25 +93,22 @@ export function ThemeProvider({ children, initialNetworkId = 'polkadot' }: Theme
9493
9594 mediaQuery . addEventListener ( 'change' , handleChange ) ;
9695 return ( ) => mediaQuery . removeEventListener ( 'change' , handleChange ) ;
97- } , [ currentNetworkId , applyTheme ] ) ;
96+ } , [ applyTheme , currentNetworkId ] ) ;
9897
99-
10098 useEffect ( ( ) => {
101- if ( isLoaded ) {
99+ if ( isLoaded && mounted ) {
102100 applyTheme ( isDarkTheme , currentNetworkId ) ;
103101 localStorage . setItem ( 'currentNetwork' , currentNetworkId ) ;
104102 }
105- } , [ currentNetworkId , isLoaded , isDarkTheme , applyTheme ] ) ;
103+ } , [ currentNetworkId , isLoaded , isDarkTheme , applyTheme , mounted ] ) ;
106104
107-
108105 const toggleTheme = useCallback ( ( ) => {
109106 const newIsDark = ! isDarkTheme ;
110107 setIsDarkTheme ( newIsDark ) ;
111108 applyTheme ( newIsDark , currentNetworkId ) ;
112109 localStorage . setItem ( 'theme' , newIsDark ? 'dark' : 'light' ) ;
113110 } , [ isDarkTheme , currentNetworkId , applyTheme ] ) ;
114111
115-
116112 const getNetworkColor = useCallback ( ( colorType : 'primary' | 'secondary' | 'light' | 'dark' ) : string => {
117113 const networkColors = NETWORK_COLORS [ currentNetworkId ] || NETWORK_COLORS [ 'polkadot' ] ;
118114 return networkColors [ colorType ] ;
@@ -130,17 +126,33 @@ export function ThemeProvider({ children, initialNetworkId = 'polkadot' }: Theme
130126 return isDarkTheme ? elevationValue . dark : elevationValue . light ;
131127 } , [ isDarkTheme ] ) ;
132128
129+ const contextValue = useMemo ( ( ) => ( {
130+ isDarkTheme,
131+ toggleTheme,
132+ isLoaded,
133+ currentNetworkId,
134+ setCurrentNetworkId,
135+ getNetworkColor,
136+ getColor,
137+ getElevation
138+ } ) , [
139+ isDarkTheme ,
140+ toggleTheme ,
141+ isLoaded ,
142+ currentNetworkId ,
143+ setCurrentNetworkId ,
144+ getNetworkColor ,
145+ getColor ,
146+ getElevation
147+ ] ) ;
148+
149+
150+ if ( ! mounted ) {
151+ return null ;
152+ }
153+
133154 return (
134- < ThemeContext . Provider value = { {
135- isDarkTheme,
136- toggleTheme,
137- isLoaded,
138- currentNetworkId,
139- setCurrentNetworkId,
140- getNetworkColor,
141- getColor,
142- getElevation
143- } } >
155+ < ThemeContext . Provider value = { contextValue } >
144156 { children }
145157 </ ThemeContext . Provider >
146158 ) ;
0 commit comments