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