-
Notifications
You must be signed in to change notification settings - Fork 481
Expand file tree
/
Copy pathdark-mode.ts
More file actions
126 lines (107 loc) · 2.86 KB
/
Copy pathdark-mode.ts
File metadata and controls
126 lines (107 loc) · 2.86 KB
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
export type ThemePreference = 'system' | 'light' | 'dark';
let _isDarkModeSetup = false;
let _isDarkMode = false;
export function getSystemTheme(): 'light' | 'dark' | null {
if (typeof window === 'undefined') {
return null;
}
return window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light';
}
export function getThemePreference(): ThemePreference {
try {
const stored = window.localStorage.getItem('theme');
if (stored === 'light') {
return 'light';
}
if (stored === 'dark') {
return 'dark';
}
return 'system';
} catch {
return 'system';
}
}
function _applyTheme(): void {
const preference = getThemePreference();
let shouldBeDark = false;
if (preference === 'dark') {
shouldBeDark = true;
} else if (preference === 'light') {
shouldBeDark = false;
} else {
// System preference
shouldBeDark = getSystemTheme() === 'dark';
}
const changed = _isDarkModeSetup && _isDarkMode !== shouldBeDark;
_isDarkMode = shouldBeDark;
if (shouldBeDark) {
document.documentElement.classList.add('dark-mode');
} else {
document.documentElement.classList.remove('dark-mode');
}
if (changed) {
window.dispatchEvent(new CustomEvent('profiler-theme-change'));
}
}
export function setThemePreference(pref: ThemePreference): void {
try {
if (pref === 'system') {
window.localStorage.removeItem('theme');
} else {
window.localStorage.setItem('theme', pref);
}
} catch (e) {
console.warn('localStorage access denied', e);
}
_applyTheme();
}
export function isDarkMode(): boolean {
if (!_isDarkModeSetup) {
try {
_applyTheme();
// Listen for localStorage changes from other tabs
window.addEventListener('storage', (event: StorageEvent) => {
if (event.key === 'theme' || event.key === null) {
_applyTheme();
}
});
// Listen for system preference changes
window
.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', () => {
// Only re-apply if user is using system preference
if (getThemePreference() === 'system') {
_applyTheme();
}
});
} catch (e) {
console.warn('localStorage access denied', e);
}
_isDarkModeSetup = true;
}
return _isDarkMode;
}
export function lightDark(light: string, dark: string): string {
return isDarkMode() ? dark : light;
}
export function maybeLightDark(value: string | [string, string]): string {
if (typeof value === 'string') {
return value;
}
return lightDark(value[0], value[1]);
}
export function initTheme() {
isDarkMode();
}
export function setDarkMode() {
setThemePreference('dark');
}
export function setLightMode() {
setThemePreference('light');
}
export function resetForTest() {
_isDarkModeSetup = false;
_isDarkMode = false;
}