@@ -3,28 +3,63 @@ import { onMounted, ref } from 'vue';
3
3
type Appearance = 'light' | 'dark' | 'system' ;
4
4
5
5
export function updateTheme ( value : Appearance ) {
6
+ if ( typeof window === 'undefined' ) {
7
+ return ;
8
+ }
9
+
6
10
if ( value === 'system' ) {
7
- const systemTheme = window . matchMedia ( '(prefers-color-scheme: dark)' ) . matches ? 'dark' : 'light' ;
11
+ const mediaQueryList = window . matchMedia ( '(prefers-color-scheme: dark)' ) ;
12
+ const systemTheme = mediaQueryList . matches ? 'dark' : 'light' ;
13
+
8
14
document . documentElement . classList . toggle ( 'dark' , systemTheme === 'dark' ) ;
9
15
} else {
10
16
document . documentElement . classList . toggle ( 'dark' , value === 'dark' ) ;
11
17
}
12
18
}
13
19
14
- const mediaQuery = window . matchMedia ( '(prefers-color-scheme: dark)' ) ;
20
+ const setCookie = ( name : string , value : string , days = 365 ) => {
21
+ if ( typeof document === 'undefined' ) {
22
+ return ;
23
+ }
24
+
25
+ const maxAge = days * 24 * 60 * 60 ;
26
+
27
+ document . cookie = `${ name } =${ value } ;path=/;max-age=${ maxAge } ;SameSite=Lax` ;
28
+ } ;
29
+
30
+ const mediaQuery = ( ) => {
31
+ if ( typeof window === 'undefined' ) {
32
+ return null ;
33
+ }
34
+
35
+ return window . matchMedia ( '(prefers-color-scheme: dark)' ) ;
36
+ } ;
37
+
38
+ const getStoredAppearance = ( ) => {
39
+ if ( typeof window === 'undefined' ) {
40
+ return null ;
41
+ }
42
+
43
+ return localStorage . getItem ( 'appearance' ) as Appearance | null ;
44
+ } ;
15
45
16
46
const handleSystemThemeChange = ( ) => {
17
- const currentAppearance = localStorage . getItem ( 'appearance' ) as Appearance | null ;
47
+ const currentAppearance = getStoredAppearance ( ) ;
48
+
18
49
updateTheme ( currentAppearance || 'system' ) ;
19
50
} ;
20
51
21
52
export function initializeTheme ( ) {
53
+ if ( typeof window === 'undefined' ) {
54
+ return ;
55
+ }
56
+
22
57
// Initialize theme from saved preference or default to system...
23
- const savedAppearance = localStorage . getItem ( 'appearance' ) as Appearance | null ;
58
+ const savedAppearance = getStoredAppearance ( ) ;
24
59
updateTheme ( savedAppearance || 'system' ) ;
25
60
26
61
// Set up system theme change listener...
27
- mediaQuery . addEventListener ( 'change' , handleSystemThemeChange ) ;
62
+ mediaQuery ( ) ? .addEventListener ( 'change' , handleSystemThemeChange ) ;
28
63
}
29
64
30
65
export function useAppearance ( ) {
@@ -42,7 +77,13 @@ export function useAppearance() {
42
77
43
78
function updateAppearance ( value : Appearance ) {
44
79
appearance . value = value ;
80
+
81
+ // Store in localStorage for client-side persistence...
45
82
localStorage . setItem ( 'appearance' , value ) ;
83
+
84
+ // Store in cookie for SSR...
85
+ setCookie ( 'appearance' , value ) ;
86
+
46
87
updateTheme ( value ) ;
47
88
}
48
89
0 commit comments