1
1
import React from "react" ;
2
- import { useMemo , useLayoutEffect , useState , useCallback } from "react" ;
2
+ import { useMemo , useLayoutEffect , useState } from "react" ;
3
3
import { useLocation } from "react-router-dom" ;
4
4
import logoWide from "src/assets/svg/logo-wide.svg" ;
5
5
import logoSquare from "src/assets/svg/logo-square.svg" ;
@@ -18,6 +18,8 @@ export interface TopBarProps {
18
18
links : Array < { localeKey : DictionaryKeys < "navbar-section" > ; href : string } > ;
19
19
}
20
20
21
+ type Theme = "light" | "dark" ;
22
+
21
23
export function TopBar ( { version, links } : TopBarProps ) : JSX . Element {
22
24
const { pathname } = useLocation ( ) ;
23
25
const languageLessPathname = useMemo ( ( ) => stripLanguageCodeFromHRef ( pathname ) , [ pathname ] ) ;
@@ -41,25 +43,17 @@ export function TopBar({ version, links }: TopBarProps): JSX.Element {
41
43
42
44
const { localize } = useLocale ( ) ;
43
45
44
- const [ isDark , setIsDark ] = useState ( ( ) => {
45
- const savedTheme = localStorage . getItem ( "theme" ) ;
46
- const isDark = savedTheme === "dark" ;
47
- return savedTheme ? isDark : true ; // default should be dark
46
+ const [ theme , setTheme ] = useState ( ( ) : Theme => {
47
+ const savedTheme = localStorage . getItem ( "theme" ) || "" ;
48
+ if ( [ "light" , "dark" ] . includes ( savedTheme ) ) return savedTheme as Theme ;
49
+
50
+ return window . matchMedia ?.( "(prefers-color-scheme: light)" ) ?. matches ? "light" : "dark" ;
48
51
} ) ;
49
52
50
53
useLayoutEffect ( ( ) => {
51
- const theme = localStorage . getItem ( "theme" ) ;
52
- if ( theme ) {
53
- document . documentElement . setAttribute ( "data-theme" , theme ) ;
54
- }
55
- } , [ ] ) ;
56
-
57
- const toggleTheme = useCallback ( ( ) => {
58
- const newTheme = isDark ? "light" : "dark" ;
59
- setIsDark ( ! isDark ) ;
60
- localStorage . setItem ( "theme" , newTheme ) ;
61
- document . documentElement . setAttribute ( "data-theme" , newTheme ) ;
62
- } , [ isDark , setIsDark ] ) ;
54
+ localStorage . setItem ( "theme" , theme ) ;
55
+ document . documentElement . setAttribute ( "data-theme" , theme ) ;
56
+ } , [ theme ] ) ;
63
57
64
58
return (
65
59
< div className = "bg-neutral" >
@@ -133,12 +127,12 @@ export function TopBar({ version, links }: TopBarProps): JSX.Element {
133
127
< path d = "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" > </ path >
134
128
</ svg >
135
129
< input
136
- onClick = { toggleTheme }
130
+ onClick = { ( ) => setTheme ( theme === "dark" ? "light" : "dark" ) }
137
131
id = "theme-toggle"
138
132
type = "checkbox"
139
133
value = "dzcodeLight"
140
134
className = "theme-controller toggle"
141
- checked = { ! isDark }
135
+ checked = { theme === "light" }
142
136
/>
143
137
< svg
144
138
xmlns = "http://www.w3.org/2000/svg"
0 commit comments