atproto explorer pdsls.dev
atproto tool
at v1.1.1 1.8 kB view raw
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 ? "system" 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 === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches), 22 ); 23 if (newTheme === "system") localStorage.removeItem("theme"); 24 else localStorage.theme = newTheme; 25 }; 26 27 const ThemeButton = (props: { theme: string; icon: string }) => { 28 return ( 29 <button 30 classList={{ 31 "p-1.5 flex items-center rounded-full border-[0.5px]": true, 32 "bg-neutral-200/60 border-neutral-300/60 dark:border-neutral-500/60 dark:bg-neutral-600": 33 theme() === props.theme, 34 "border-transparent": theme() !== props.theme, 35 }} 36 onclick={() => updateTheme(props.theme)} 37 > 38 <span class={"iconify " + props.icon}></span> 39 </button> 40 ); 41 }; 42 43 return ( 44 <div class="dark:bg-dark-100 dark:inset-shadow-dark-200 mt-2 flex items-center justify-between gap-1 rounded-full border-[0.5px] border-neutral-200/60 bg-white p-1 text-base text-neutral-800 inset-shadow-sm dark:border-neutral-600 dark:text-neutral-300"> 45 <ThemeButton theme="system" icon="lucide--monitor" /> 46 <ThemeButton theme="light" icon="lucide--sun" /> 47 <ThemeButton theme="dark" icon="lucide--moon" /> 48 </div> 49 ); 50};