forked from pdsls.dev/pdsls
atproto explorer

refactor theme component

Changed files
+31 -50
src
+1 -2
src/components/create.tsx
··· 3 3 import { agent } from "../components/login.jsx"; 4 4 import { editor, Editor } from "../components/editor.jsx"; 5 5 import * as monaco from "monaco-editor"; 6 - import { theme } from "./theme.jsx"; 7 6 import Tooltip from "./tooltip.jsx"; 8 7 import { useNavigate, useParams } from "@solidjs/router"; 9 8 import { remove } from "@mary/exif-rm"; ··· 252 251 </div> 253 252 </div> 254 253 </div> 255 - <Editor theme={theme().color} model={model!} /> 254 + <Editor model={model!} /> 256 255 <div class="flex flex-col gap-2"> 257 256 <Show when={notice()}> 258 257 <div class="text-red-500 dark:text-red-400">{notice()}</div>
+2 -2
src/components/editor.tsx
··· 14 14 15 15 let editor: monaco.editor.IStandaloneCodeEditor; 16 16 17 - const Editor = (props: { theme: string; model: monaco.editor.IModel }) => { 17 + const Editor = (props: { model: monaco.editor.IModel }) => { 18 18 let editorDiv!: HTMLDivElement; 19 19 20 20 onMount(() => { 21 21 editor = monaco.editor.create(editorDiv, { 22 22 minimap: { enabled: false }, 23 - theme: props.theme === "dark" ? "vs-dark" : "vs", 23 + theme: document.documentElement.classList.contains("dark") ? "vs-dark" : "vs", 24 24 model: props.model, 25 25 wordWrap: "on", 26 26 automaticLayout: true,
+28 -46
src/components/theme.tsx
··· 1 1 import { createSignal } from "solid-js"; 2 2 3 - const getInitialTheme = () => { 4 - const isDarkMode = 5 - localStorage.theme === "dark" || 6 - (!("theme" in localStorage) && window.matchMedia("(prefers-color-scheme: dark)").matches); 7 - return { color: isDarkMode ? "dark" : "light", system: !("theme" in localStorage) }; 8 - }; 9 - 10 3 export const themeEvent = () => { 11 - if (!theme().system) return; 4 + if (localStorage.getItem("theme") !== null) return; 12 5 const isDark = window.matchMedia("(prefers-color-scheme: dark)").matches; 13 - setTheme({ color: isDark ? "dark" : "light", system: theme().system }); 14 6 document.documentElement.classList.toggle("dark", isDark); 15 7 }; 16 8 17 - export const [theme, setTheme] = createSignal(getInitialTheme()); 9 + export const ThemeSelection = () => { 10 + const [theme, setTheme] = createSignal( 11 + localStorage.getItem("theme") === null ? "system" 12 + : localStorage.theme === "dark" ? "dark" 13 + : "light", 14 + ); 18 15 19 - export const ThemeSelection = () => { 20 - const updateTheme = (newTheme: { color: string; system: boolean }) => { 16 + const updateTheme = (newTheme: string) => { 21 17 setTheme(newTheme); 22 - document.documentElement.classList.toggle("dark", newTheme.color === "dark"); 23 - if (newTheme.system) localStorage.removeItem("theme"); 24 - else localStorage.theme = newTheme.color; 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 25 }; 26 26 27 - return ( 28 - <div class="mt-2 flex items-center justify-between gap-1 text-base"> 29 - <button 30 - name="System Theme" 31 - classList={{ 32 - "p-1.5 flex items-center rounded-full": true, 33 - "bg-neutral-200 dark:bg-neutral-600": theme().system, 34 - }} 35 - onclick={() => 36 - updateTheme({ 37 - color: window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light", 38 - system: true, 39 - }) 40 - } 41 - > 42 - <span class="iconify lucide--monitor"></span> 43 - </button> 27 + const ThemeButton = (props: { theme: string; icon: string }) => { 28 + return ( 44 29 <button 45 - name="Light Theme" 46 30 classList={{ 47 31 "p-1.5 flex items-center rounded-full": true, 48 - "bg-neutral-200": theme().color === "light" && !theme().system, 32 + "bg-neutral-200 dark:bg-neutral-600": theme() === props.theme, 49 33 }} 50 - onclick={() => updateTheme({ color: "light", system: false })} 34 + onclick={() => updateTheme(props.theme)} 51 35 > 52 - <span class="iconify lucide--sun"></span> 36 + <span class={"iconify " + props.icon}></span> 53 37 </button> 54 - <button 55 - name="Dark Theme" 56 - classList={{ 57 - "p-1.5 flex items-center rounded-full": true, 58 - "bg-neutral-600": theme().color === "dark" && !theme().system, 59 - }} 60 - onclick={() => updateTheme({ color: "dark", system: false })} 61 - > 62 - <span class="iconify lucide--moon"></span> 63 - </button> 38 + ); 39 + }; 40 + 41 + return ( 42 + <div class="mt-2 flex items-center justify-between gap-1 text-base"> 43 + <ThemeButton theme="system" icon="lucide--monitor" /> 44 + <ThemeButton theme="light" icon="lucide--sun" /> 45 + <ThemeButton theme="dark" icon="lucide--moon" /> 64 46 </div> 65 47 ); 66 48 };