atproto explorer pdsls.dev
atproto tool

refactor theme component

Changed files
+31 -50
src
+1 -2
src/components/create.tsx
···
import { agent } from "../components/login.jsx";
import { editor, Editor } from "../components/editor.jsx";
import * as monaco from "monaco-editor";
-
import { theme } from "./theme.jsx";
import Tooltip from "./tooltip.jsx";
import { useNavigate, useParams } from "@solidjs/router";
import { remove } from "@mary/exif-rm";
···
</div>
</div>
</div>
-
<Editor theme={theme().color} model={model!} />
<div class="flex flex-col gap-2">
<Show when={notice()}>
<div class="text-red-500 dark:text-red-400">{notice()}</div>
···
import { agent } from "../components/login.jsx";
import { editor, Editor } from "../components/editor.jsx";
import * as monaco from "monaco-editor";
import Tooltip from "./tooltip.jsx";
import { useNavigate, useParams } from "@solidjs/router";
import { remove } from "@mary/exif-rm";
···
</div>
</div>
</div>
+
<Editor model={model!} />
<div class="flex flex-col gap-2">
<Show when={notice()}>
<div class="text-red-500 dark:text-red-400">{notice()}</div>
+2 -2
src/components/editor.tsx
···
let editor: monaco.editor.IStandaloneCodeEditor;
-
const Editor = (props: { theme: string; model: monaco.editor.IModel }) => {
let editorDiv!: HTMLDivElement;
onMount(() => {
editor = monaco.editor.create(editorDiv, {
minimap: { enabled: false },
-
theme: props.theme === "dark" ? "vs-dark" : "vs",
model: props.model,
wordWrap: "on",
automaticLayout: true,
···
let editor: monaco.editor.IStandaloneCodeEditor;
+
const Editor = (props: { model: monaco.editor.IModel }) => {
let editorDiv!: HTMLDivElement;
onMount(() => {
editor = monaco.editor.create(editorDiv, {
minimap: { enabled: false },
+
theme: document.documentElement.classList.contains("dark") ? "vs-dark" : "vs",
model: props.model,
wordWrap: "on",
automaticLayout: true,
+28 -46
src/components/theme.tsx
···
import { createSignal } from "solid-js";
-
const getInitialTheme = () => {
-
const isDarkMode =
-
localStorage.theme === "dark" ||
-
(!("theme" in localStorage) && window.matchMedia("(prefers-color-scheme: dark)").matches);
-
return { color: isDarkMode ? "dark" : "light", system: !("theme" in localStorage) };
-
};
-
export const themeEvent = () => {
-
if (!theme().system) return;
const isDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
-
setTheme({ color: isDark ? "dark" : "light", system: theme().system });
document.documentElement.classList.toggle("dark", isDark);
};
-
export const [theme, setTheme] = createSignal(getInitialTheme());
-
export const ThemeSelection = () => {
-
const updateTheme = (newTheme: { color: string; system: boolean }) => {
setTheme(newTheme);
-
document.documentElement.classList.toggle("dark", newTheme.color === "dark");
-
if (newTheme.system) localStorage.removeItem("theme");
-
else localStorage.theme = newTheme.color;
};
-
return (
-
<div class="mt-2 flex items-center justify-between gap-1 text-base">
-
<button
-
name="System Theme"
-
classList={{
-
"p-1.5 flex items-center rounded-full": true,
-
"bg-neutral-200 dark:bg-neutral-600": theme().system,
-
}}
-
onclick={() =>
-
updateTheme({
-
color: window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light",
-
system: true,
-
})
-
}
-
>
-
<span class="iconify lucide--monitor"></span>
-
</button>
<button
-
name="Light Theme"
classList={{
"p-1.5 flex items-center rounded-full": true,
-
"bg-neutral-200": theme().color === "light" && !theme().system,
}}
-
onclick={() => updateTheme({ color: "light", system: false })}
>
-
<span class="iconify lucide--sun"></span>
</button>
-
<button
-
name="Dark Theme"
-
classList={{
-
"p-1.5 flex items-center rounded-full": true,
-
"bg-neutral-600": theme().color === "dark" && !theme().system,
-
}}
-
onclick={() => updateTheme({ color: "dark", system: false })}
-
>
-
<span class="iconify lucide--moon"></span>
-
</button>
</div>
);
};
···
import { createSignal } from "solid-js";
export const themeEvent = () => {
+
if (localStorage.getItem("theme") !== null) return;
const isDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
document.documentElement.classList.toggle("dark", isDark);
};
+
export const ThemeSelection = () => {
+
const [theme, setTheme] = createSignal(
+
localStorage.getItem("theme") === null ? "system"
+
: localStorage.theme === "dark" ? "dark"
+
: "light",
+
);
+
const updateTheme = (newTheme: string) => {
setTheme(newTheme);
+
document.documentElement.classList.toggle(
+
"dark",
+
newTheme === "dark" ||
+
(newTheme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches),
+
);
+
if (newTheme === "system") localStorage.removeItem("theme");
+
else localStorage.theme = newTheme;
};
+
const ThemeButton = (props: { theme: string; icon: string }) => {
+
return (
<button
classList={{
"p-1.5 flex items-center rounded-full": true,
+
"bg-neutral-200 dark:bg-neutral-600": theme() === props.theme,
}}
+
onclick={() => updateTheme(props.theme)}
>
+
<span class={"iconify " + props.icon}></span>
</button>
+
);
+
};
+
+
return (
+
<div class="mt-2 flex items-center justify-between gap-1 text-base">
+
<ThemeButton theme="system" icon="lucide--monitor" />
+
<ThemeButton theme="light" icon="lucide--sun" />
+
<ThemeButton theme="dark" icon="lucide--moon" />
</div>
);
};