/
color-scheme-toggle-demo.svelte
96 lines (78 loc) · 2.42 KB
/
color-scheme-toggle-demo.svelte
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
<script>
import { onMount } from 'svelte'
import { colors, themes } from 'styles.js'
import { getCustomProperty, setCustomProperty, setColors, setTheme } from 'helpers'
const LS_KEY = 'user-color-scheme'
const DOM_ATTR = `data-${LS_KEY}`
const CSS_PROP = LS_KEY
const getOpposite = (mode) => mode === 'dark' ? 'light' : 'dark'
const setPreference = (newPreference, getCustomProperty, setCustomProperty, LS_KEY, DOM_ATTR, CSS_PROP) => {
if (window) {
if (newPreference) {
document.documentElement.setAttribute(DOM_ATTR, newPreference)
setCustomProperty(CSS_PROP, newPreference)
window.localStorage.setItem(LS_KEY, newPreference)
} else {
const OS = getCustomProperty(CSS_PROP)
document.documentElement.setAttribute(DOM_ATTR, OS)
setCustomProperty(CSS_PROP, OS)
}
}
}
let toggleColorScheme
onMount(() => {
currentColorScheme = getCustomProperty(CSS_PROP)
toggleColorScheme = event => {
event.preventDefault()
const currentPreference = window.localStorage.getItem(LS_KEY) || currentColorScheme
const newPrefernece = getOpposite(currentPreference)
setPreference(newPrefernece)
}
})
</script>
<svelte:head>
{@html `
<style>
:root {
--${CSS_PROP}: 'light';
${setTheme(themes.light)}
}
@media (prefers-color-scheme: dark) {
:root {
--${CSS_PROP}: 'dark';
}
:root:not([data-user-color-scheme]) {
${setTheme(themes.dark)}
}
}
[data-user-color-scheme='dark'] {
${setTheme(themes.dark)}
}
</style>
`}
{@html `
<script>
document.body.removeAttribute('data-no-js')
var setPreference = ${setPreference.toString()}
var getCustomProperty = ${getCustomProperty.toString()}
var setCustomProperty = ${setCustomProperty.toString()}
var existingUserPrefernece = window.localStorage.getItem('${LS_KEY}')
setCustomProperty('${CSS_PROP}', getCustomProperty('${CSS_PROP}'))
setPreference(existingUserPrefernece, setCustomProperty, '${LS_KEY}', '${DOM_ATTR}', '${CSS_PROP}')
</script>
`}
</svelte:head>
<style>
:global([data-no-js] button) {
display: none;
}
:global([style*='--user-color-scheme:light'] button) {
...
}
:global([style*='--user-color-scheme:dark'] button) {
...
}
</style>
<button on:click={toggleColorScheme}>
...
</button>