1- "use client" ;
2-
1+ import type { Nullish } from "@pythnetwork/shared-lib/types" ;
32import { useTheme } from "next-themes" ;
4- import { useEffect , useRef , useState } from "react" ;
3+ import { useEffect , useState } from "react" ;
54
65function getThemePreferenceMediaQuery ( ) {
76 return globalThis . window . matchMedia ( "(prefers-color-scheme: dark)" ) ;
@@ -14,31 +13,39 @@ function getThemePreferenceMediaQuery() {
1413 * (which comes directly from their OS or from their browser's settings)
1514 */
1615export function useAppTheme ( ) {
17- /** refs */
18- const darkQueryRef = useRef ( getThemePreferenceMediaQuery ( ) ) ;
19-
2016 /** state */
17+ const [ darkQuery , setDarkQuery ] =
18+ useState < Nullish < ReturnType < typeof getThemePreferenceMediaQuery > > > (
19+ undefined ,
20+ ) ;
2121 const [ browserThemePreference , setBrowserThemePreference ] = useState <
22- "dark" | "light"
23- > ( darkQueryRef . current . matches ? "dark" : "light ") ;
22+ "dark" | "light" | "system"
23+ > ( "system ") ;
2424
2525 /** hooks */
2626 const { theme, ...rest } = useTheme ( ) ;
2727
2828 /** effects */
2929 useEffect ( ( ) => {
30- const { current : mediaQuery } = darkQueryRef ;
30+ setDarkQuery ( getThemePreferenceMediaQuery ( ) ) ;
31+ } , [ ] ) ;
32+
33+ useEffect ( ( ) => {
34+ if ( ! darkQuery ) return ;
35+
36+ // sync initial query
37+ setBrowserThemePreference ( darkQuery . matches ? "dark" : "light" ) ;
3138
3239 const handleChange = ( e : MediaQueryListEvent ) => {
3340 setBrowserThemePreference ( e . matches ? "dark" : "light" ) ;
3441 } ;
3542
36- mediaQuery . addEventListener ( "change" , handleChange ) ;
43+ darkQuery . addEventListener ( "change" , handleChange ) ;
3744
3845 return ( ) => {
39- mediaQuery . removeEventListener ( "change" , handleChange ) ;
46+ darkQuery . removeEventListener ( "change" , handleChange ) ;
4047 } ;
41- } , [ ] ) ;
48+ } , [ darkQuery ] ) ;
4249
4350 return {
4451 ...rest ,
0 commit comments