1import { createSignal } from "solid-js";
2
3export const themeEvent = () => {
4 if (localStorage.getItem("theme") !== null) return;
5 const isDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
6 document.documentElement.classList.toggle("dark", isDark);
7};
8
9export const ThemeSelection = () => {
10 const [theme, setTheme] = createSignal(
11 localStorage.getItem("theme") === null ? "auto"
12 : localStorage.theme === "dark" ? "dark"
13 : "light",
14 );
15
16 const updateTheme = (newTheme: string) => {
17 setTheme(newTheme);
18 document.documentElement.classList.toggle(
19 "dark",
20 newTheme === "dark" ||
21 (newTheme === "auto" && window.matchMedia("(prefers-color-scheme: dark)").matches),
22 );
23 if (newTheme === "auto") localStorage.removeItem("theme");
24 else localStorage.theme = newTheme;
25 };
26
27 const ThemeOption = (props: { theme: string; label: string }) => {
28 return (
29 <button
30 classList={{
31 "flex items-center min-w-21 justify-center rounded-xl border px-3 py-2": true,
32 "bg-neutral-200/60 border-neutral-300 dark:border-neutral-500 dark:bg-neutral-700":
33 theme() === props.theme,
34 "border-neutral-200 dark:border-neutral-600 hover:bg-neutral-200/30 dark:hover:bg-neutral-800":
35 theme() !== props.theme,
36 }}
37 onclick={() => updateTheme(props.theme)}
38 >
39 {props.label}
40 </button>
41 );
42 };
43
44 return (
45 <div class="flex flex-col gap-1">
46 <label class="font-medium select-none">Theme</label>
47 <div class="flex gap-2">
48 <ThemeOption theme="auto" label="Auto" />
49 <ThemeOption theme="light" label="Light" />
50 <ThemeOption theme="dark" label="Dark" />
51 </div>
52 </div>
53 );
54};