Skip to content

Commit f18e86d

Browse files
cleanup
1 parent 6b4208c commit f18e86d

File tree

2 files changed

+47
-47
lines changed

2 files changed

+47
-47
lines changed

src/lib/ThemeToggle.svelte

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,6 @@
3131
<div class="relative inline-block">
3232
<button class="w-6 h-6 leading-none" use:menu.button onchange={change}>
3333
<Icon />
34-
<!-- <span hidden={theme.override === 'system'}>
35-
<span class="dark:hidden inline">{@html theme.icons.light(true)}</span>
36-
<span class="hidden dark:inline">{@html theme.icons.dark(true)}</span>
37-
</span>
38-
<span hidden={theme.override !== 'system'}>
39-
<span class="dark:hidden inline">{@html theme.icons.light(false)}</span>
40-
<span class="hidden dark:inline">{@html theme.icons.dark(false)}</span>
41-
</span> -->
4234
</button>
4335

4436
<Transition

src/lib/state.svelte.ts

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,92 @@
11
import { defaultColors, type Colors } from "./colors"
22
import { defaultIcons, type Icons } from "./icons"
3-
import { createSubscriber, MediaQuery } from "svelte/reactivity"
3+
import { MediaQuery } from "svelte/reactivity"
44
import { on } from "svelte/events"
55

66
export type Theme = 'light' | 'dark' | 'system'
77

88
export const themes: Theme[] = ['light', 'dark', 'system']
99

1010
export interface Labels {
11-
light: string
12-
dark: string
13-
system: string
11+
light: string
12+
dark: string
13+
system: string
1414
}
1515

1616
export const defaultLabels = {
17-
light: 'Light',
18-
dark: 'Dark',
19-
system: 'System',
17+
light: 'Light',
18+
dark: 'Dark',
19+
system: 'System',
2020
}
2121

2222
export interface Config {
23-
key: string
24-
colors: Colors
25-
icons: Icons
26-
labels: Labels
23+
key: string
24+
colors: Colors
25+
icons: Icons
26+
labels: Labels
2727
}
2828

2929
class ThemeState {
30+
#mq = new MediaQuery('(prefers-color-scheme: dark)')
31+
#system = $derived<Theme>(this.#mq.current ? 'dark' : 'light')
3032
#override = $state<Theme>('system')
31-
#system: Theme
32-
#value: Theme
33-
#subscribe: VoidFunction
34-
#update?: VoidFunction
33+
#value = $derived(this.#override === 'system' ? this.#system : this.#override)
34+
35+
#subscribers = 0
36+
#off?: VoidFunction
3537

3638
colors = defaultColors
3739
icons = defaultIcons
3840
labels = defaultLabels
3941

40-
constructor() {
41-
const prefersDark = new MediaQuery('(prefers-color-scheme: dark)')
42-
this.#system = $derived(prefersDark.current ? 'dark' : 'light')
43-
this.#value = $derived(this.#override === 'system' ? this.#system : this.#override)
44-
45-
this.#subscribe = createSubscriber(update => {
46-
this.#update = update
47-
const saved: Theme = localStorage.theme ?? 'system'
48-
this.#override = saved
49-
update()
50-
51-
return on(window, 'storage', (event: StorageEvent) => {
52-
if (event.key === 'theme') {
53-
this.#override = event.newValue as Theme
54-
update()
42+
private subscribe() {
43+
if ($effect.tracking()) {
44+
$effect(() => {
45+
if (this.#subscribers === 0) {
46+
const saved: Theme = localStorage.theme ?? 'system'
47+
this.#override = saved
48+
49+
this.#off = on(window, 'storage', (event: StorageEvent) => {
50+
if (event.key === 'theme') {
51+
this.#override = event.newValue as Theme
52+
}
53+
})
54+
55+
$effect(() => {
56+
document.documentElement.classList.toggle('dark', this.#value === 'dark')
57+
})
5558
}
56-
})
57-
})
5859

59-
$effect.root(() => {
60-
$effect.pre(() => {
61-
document.documentElement.classList.toggle('dark', this.#value === 'dark')
60+
this.#subscribers++
61+
62+
return () => {
63+
this.#subscribers--
64+
if (this.#subscribers === 0) {
65+
this.#off?.()
66+
this.#off = undefined
67+
}
68+
}
6269
})
63-
})
70+
}
6471
}
6572

6673
get system() {
74+
this.subscribe()
6775
return this.#system
6876
}
6977

7078
get override() {
71-
this.#subscribe()
79+
this.subscribe()
7280
return this.#override
7381
}
7482

7583
get current() {
76-
this.#subscribe()
84+
this.subscribe()
7785
return this.#value
7886
}
7987

8088
set current(value: Theme) {
89+
this.subscribe()
8190
switch (value) {
8291
case 'dark':
8392
case 'light':
@@ -88,7 +97,6 @@ class ThemeState {
8897
break
8998
}
9099
this.#override = value
91-
this.#update?.()
92100
}
93101
}
94102

0 commit comments

Comments
 (0)