A very simple bookmarking webapp
bookmarker.finxol.deno.net/
1import { createEffect, createSignal, onCleanup, onMount } from "solid-js"
2import { MoonIcon, SunIcon } from "lucide-solid"
3import { getInitialTheme, STORAGE_KEY, Theme } from "../utils/theme.ts"
4
5export function ThemeSwitcher() {
6 const [theme, setTheme] = createSignal<Theme>(getInitialTheme())
7
8 // Reactively apply the theme to <html> and persist to localStorage
9 createEffect(() => {
10 const current = theme()
11 document.documentElement.dataset.theme = current
12 localStorage.setItem(STORAGE_KEY, current)
13 })
14
15 // Listen for system preference changes when no explicit choice is stored
16 onMount(() => {
17 const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)")
18
19 const handleChange = (e: MediaQueryListEvent) => {
20 if (!localStorage.getItem(STORAGE_KEY)) {
21 setTheme(e.matches ? "dark" : "light")
22 }
23 }
24
25 mediaQuery.addEventListener("change", handleChange)
26 onCleanup(() => mediaQuery.removeEventListener("change", handleChange))
27 })
28
29 const toggleTheme = () => {
30 setTheme((prev) => (prev === "light" ? "dark" : "light"))
31 }
32
33 return (
34 <button
35 type="button"
36 onClick={toggleTheme}
37 title={`Switch to ${theme() === "light" ? "dark" : "light"} mode`}
38 class="button-icon button-ghost"
39 >
40 {theme() === "light"
41 ? <MoonIcon size={24} />
42 : <SunIcon size={24} />}
43 </button>
44 )
45}