-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
theme-resolver.tsx
67 lines (56 loc) · 1.84 KB
/
theme-resolver.tsx
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
import { getGraphService } from './machines/graph.service';
const htmlEl = document.documentElement;
export const localStorageThemeKey = 'nx-dep-graph-theme';
export type Theme = 'light' | 'dark' | 'system';
export let currentTheme: Theme;
function mediaListener(ev: MediaQueryListEvent) {
const resolver = ev.matches ? 'dark' : 'light';
toggleHtmlClass(resolver);
currentTheme = resolver;
}
function toggleHtmlClass(theme: Theme) {
if (theme === 'dark') {
htmlEl.classList.add('dark');
htmlEl.classList.remove('light');
} else {
htmlEl.classList.add('light');
htmlEl.classList.remove('dark');
}
}
export function themeInit() {
const theme =
(localStorage.getItem(localStorageThemeKey) as Theme) ?? 'system';
themeResolver(theme);
}
export function themeResolver(theme: Theme) {
if (!('matchMedia' in window)) {
return;
}
const darkMedia = window.matchMedia('(prefers-color-scheme: dark)');
if (theme !== 'system') {
darkMedia.removeEventListener('change', mediaListener);
toggleHtmlClass(theme);
currentTheme = theme;
} else {
const resolver = darkMedia.matches ? 'dark' : 'light';
darkMedia.addEventListener('change', mediaListener);
toggleHtmlClass(resolver);
currentTheme = resolver;
}
localStorage.setItem(localStorageThemeKey, theme);
getGraphService().theme = currentTheme;
}
export function selectValueByThemeDynamic<T>(
darkModeSetting: T,
lightModeSetting: T
): () => T {
return () => selectValueByThemeStatic(darkModeSetting, lightModeSetting);
}
// The function exists because some places do not support selectDynamically
// It also prevents the dynamic change of theme for certain elements like tippy
export function selectValueByThemeStatic<T>(
darkModeSetting: T,
lightModeSetting: T
): T {
return currentTheme === 'dark' ? darkModeSetting : lightModeSetting;
}