Exosphere is a set of small, modular, self-hostable community tools built on the AT Protocol. app.exosphere.site
at main 41 lines 1.2 kB view raw
1import type { ComponentType } from "preact"; 2import { theme, setTheme } from "../theme-state.ts"; 3import * as ui from "@exosphere/client/ui.css"; 4 5type IconComponent = ComponentType<{ size: string | number }>; 6 7interface ThemeToggleProps { 8 icons: Record<"light" | "dark" | "system", IconComponent>; 9} 10 11const themeOptions = ["light", "dark", "system"] as const; 12const labels: Record<(typeof themeOptions)[number], string> = { 13 light: "Light", 14 dark: "Dark", 15 system: "System", 16}; 17 18export function ThemeToggle({ icons }: ThemeToggleProps) { 19 const current = theme.value; 20 21 return ( 22 <div class={ui.themeToggle} role="radiogroup" aria-label="Theme"> 23 {themeOptions.map((value) => { 24 const Icon = icons[value]; 25 return ( 26 <button 27 key={value} 28 class={`${ui.themeToggleBtn} ${current === value ? ui.themeToggleBtnActive : ""}`} 29 onClick={() => setTheme(value)} 30 role="radio" 31 aria-checked={current === value} 32 aria-label={labels[value]} 33 title={labels[value]} 34 > 35 <Icon size={16} /> 36 </button> 37 ); 38 })} 39 </div> 40 ); 41}