1
- import useRGS from "r18gs" ;
2
1
import type { SetStateAction } from "r18gs" ;
3
2
import type { ColorSchemePreference , ThemeState } from "../../constants" ;
4
- import { DEFAULT_ID , DEFAULT_THEME_STATE } from "../../constants" ;
3
+ import { DEFAULT_ID , useRGSMinify } from "../../constants" ;
5
4
import { useEffect } from "react" ;
6
-
5
+ const useEffectMinify = useEffect ;
7
6
export interface ThemeSwitcherProps {
8
7
/** id of target element to apply classes to. This is useful when you want to apply theme only to specific container. */
9
8
targetId ?: string ;
@@ -17,11 +16,11 @@ export interface ThemeSwitcherProps {
17
16
18
17
/** Add media query listener */
19
18
const useMediaQuery = ( setThemeState : SetStateAction < ThemeState > ) => {
20
- useEffect ( ( ) => {
19
+ useEffectMinify ( ( ) => {
21
20
// set event listener for media
22
21
const media = matchMedia ( "(prefers-color-scheme: dark)" ) ;
23
22
const updateSystemColorScheme = ( ) => {
24
- setThemeState ( state => ( { ...state , systemColorScheme : media . matches ? "dark" : "light" } ) ) ;
23
+ setThemeState ( state => ( { ...state , s : media . matches ? "dark" : "light" } ) ) ;
25
24
} ;
26
25
updateSystemColorScheme ( ) ;
27
26
media . addEventListener ( "change" , updateSystemColorScheme ) ;
@@ -31,65 +30,57 @@ const useMediaQuery = (setThemeState: SetStateAction<ThemeState>) => {
31
30
} , [ setThemeState ] ) ;
32
31
} ;
33
32
34
- export interface LoadSyncedStateProps extends ThemeSwitcherProps {
35
- setThemeState : SetStateAction < ThemeState > ;
36
- }
37
-
38
- const parseState = ( str ?: string | null ) => {
33
+ const parseState = ( str ?: string | null ) : Partial < ThemeState > => {
39
34
const parts = ( str ?? ",system" ) . split ( "," ) as [ string , ColorSchemePreference ] ;
40
- return { theme : parts [ 0 ] , colorSchemePreference : parts [ 1 ] } ;
35
+ return { t : parts [ 0 ] , c : parts [ 1 ] } ;
41
36
} ;
42
37
43
38
let tInit = 0 ;
44
39
45
- const useLoadSyncedState = ( { dontSync , targetId , setThemeState } : LoadSyncedStateProps ) => {
46
- useEffect ( ( ) => {
40
+ const useLoadSyncedState = ( setThemeState : SetStateAction < ThemeState > , dontSync ?: boolean , targetId ?: string ) => {
41
+ useEffectMinify ( ( ) => {
47
42
if ( dontSync ) return ;
48
43
tInit = Date . now ( ) ;
49
44
const key = targetId ?? DEFAULT_ID ;
50
45
setThemeState ( state => ( { ...state , ...parseState ( localStorage . getItem ( key ) ) } ) ) ;
51
- const storageListener = ( e : StorageEvent ) => {
46
+ const storageListener = ( e : StorageEvent ) : void => {
52
47
if ( e . key === key ) setThemeState ( state => ( { ...state , ...parseState ( e . newValue ) } ) ) ;
53
48
} ;
54
- window . addEventListener ( "storage" , storageListener ) ;
49
+ addEventListener ( "storage" , storageListener ) ;
50
+ // skipcq: JS-0045
55
51
return ( ) => {
56
- window . removeEventListener ( "storage" , storageListener ) ;
52
+ removeEventListener ( "storage" , storageListener ) ;
57
53
} ;
58
54
} , [ dontSync , setThemeState , targetId ] ) ;
59
55
} ;
60
56
61
57
const modifyTransition = ( themeTransition = "none" , targetId ?: string ) => {
62
- const css = document . createElement ( "style" ) ;
58
+ const documentMinify = document ;
59
+ const css = documentMinify . createElement ( "style" ) ;
63
60
/** split by ';' to prevent CSS injection */
64
61
const transition = `transition: ${ themeTransition . split ( ";" ) [ 0 ] } !important;` ;
65
62
const targetSelector = targetId
66
63
? `#${ targetId } ,#${ targetId } *,#${ targetId } ~ *,#${ targetId } ~ * *`
67
64
: "*" ;
68
65
css . appendChild (
69
- document . createTextNode (
66
+ documentMinify . createTextNode (
70
67
`${ targetSelector } {-webkit-${ transition } -moz-${ transition } -o-${ transition } -ms-${ transition } ${ transition } }` ,
71
68
) ,
72
69
) ;
73
- document . head . appendChild ( css ) ;
70
+ documentMinify . head . appendChild ( css ) ;
74
71
75
72
return ( ) => {
76
73
// Force restyle
77
- ( ( ) => window . getComputedStyle ( document . body ) ) ( ) ;
74
+ ( ( ) => getComputedStyle ( documentMinify . body ) ) ( ) ;
78
75
// Wait for next tick before removing
79
76
setTimeout ( ( ) => {
80
- document . head . removeChild ( css ) ;
77
+ documentMinify . head . removeChild ( css ) ;
81
78
} , 1 ) ;
82
79
} ;
83
80
} ;
84
81
85
- export interface ApplyClassesProps {
86
- targets : ( HTMLElement | null ) [ ] ;
87
- theme : string ;
88
- resolvedColorScheme : "light" | "dark" ;
89
- styles ?: Record < string , string > ;
90
- }
91
-
92
- const applyClasses = ( { targets, theme, resolvedColorScheme, styles } : ApplyClassesProps ) => {
82
+ /** Apply classes to the targets */
83
+ const applyClasses = ( targets : ( HTMLElement | null ) [ ] , theme : string , resolvedColorScheme : "light" | "dark" , styles ?: Record < string , string > ) => {
93
84
let cls = [ "dark" , "light" , `th-${ theme } ` , resolvedColorScheme ] ;
94
85
if ( styles ) cls = cls . map ( c => styles [ c ] ?? c ) ;
95
86
@@ -104,29 +95,24 @@ const applyClasses = ({ targets, theme, resolvedColorScheme, styles }: ApplyClas
104
95
} ) ;
105
96
} ;
106
97
107
- export interface UpdateDOMProps {
108
- targetId ?: string ;
109
- themeState : ThemeState ;
110
- dontSync ?: boolean ;
111
- styles ?: Record < string , string > ;
112
- }
113
-
114
- const updateDOM = ( { targetId, themeState, dontSync, styles } : UpdateDOMProps ) => {
115
- const { theme, colorSchemePreference : csp , systemColorScheme : scs } = themeState ;
98
+ /** Update DOM */
99
+ const updateDOM = ( themeState : ThemeState , targetId ?: string , dontSync ?: boolean , styles ?:Record < string , string > ) => {
100
+ const { t : theme , c : csp , s : scs } = themeState ;
116
101
const resolvedColorScheme = csp === "system" ? scs : csp ;
117
102
const key = targetId ?? DEFAULT_ID ;
118
103
// update DOM
119
104
let shoulCreateCookie = false ;
120
- const target = document . getElementById ( key ) ;
105
+ const documentMinify = document ;
106
+ const target = documentMinify . getElementById ( key ) ;
121
107
shoulCreateCookie = ! dontSync && target ?. getAttribute ( "data-nth" ) === "next" ;
122
108
123
109
/** do not update documentElement for local targets */
124
- const targets = targetId ? [ target ] : [ target , document . documentElement ] ;
110
+ const targets = targetId ? [ target ] : [ target , documentMinify . documentElement ] ;
125
111
126
- applyClasses ( { targets, styles , resolvedColorScheme, theme } ) ;
112
+ applyClasses ( targets , theme , resolvedColorScheme , styles ) ;
127
113
128
114
if ( shoulCreateCookie )
129
- document . cookie = `${ key } =${ theme } ,${ resolvedColorScheme } ; max-age=31536000; SameSite=Strict;` ;
115
+ documentMinify . cookie = `${ key } =${ theme } ,${ resolvedColorScheme } ; max-age=31536000; SameSite=Strict;` ;
130
116
} ;
131
117
132
118
/**
@@ -140,22 +126,19 @@ export const ThemeSwitcher = ({
140
126
styles,
141
127
} : ThemeSwitcherProps ) => {
142
128
if ( targetId === "" ) throw new Error ( "id can not be an empty string" ) ;
143
- const [ themeState , setThemeState ] = useRGS < ThemeState > (
144
- targetId ?? DEFAULT_ID ,
145
- DEFAULT_THEME_STATE ,
146
- ) ;
129
+ const [ themeState , setThemeState ] = useRGSMinify ( targetId ) ;
147
130
148
131
useMediaQuery ( setThemeState ) ;
149
132
150
- useLoadSyncedState ( { dontSync , targetId , setThemeState } ) ;
133
+ useLoadSyncedState ( setThemeState , dontSync , targetId ) ;
151
134
152
135
/** update DOM and storage */
153
- useEffect ( ( ) => {
136
+ useEffectMinify ( ( ) => {
154
137
const restoreTransitions = modifyTransition ( themeTransition , targetId ) ;
155
- updateDOM ( { targetId, themeState , dontSync, styles } ) ;
138
+ updateDOM ( themeState , targetId , dontSync , styles ) ;
156
139
if ( ! dontSync && tInit < Date . now ( ) - 300 ) {
157
140
// save to localStorage
158
- const { theme, colorSchemePreference } = themeState ;
141
+ const { t : theme , c : colorSchemePreference } = themeState ;
159
142
const stateToSave = [ theme , colorSchemePreference ] . join ( "," ) ;
160
143
const key = targetId ?? DEFAULT_ID ;
161
144
localStorage . setItem ( key , stateToSave ) ;
0 commit comments