From 0d1856d165c2801e64a5bb8ae8ebe244db2fa879 Mon Sep 17 00:00:00 2001 From: StarHeartHunt Date: Sun, 3 Dec 2023 11:42:05 +0800 Subject: [PATCH] style: extract logic --- src/components/ThemeSwitcher.tsx | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/components/ThemeSwitcher.tsx b/src/components/ThemeSwitcher.tsx index fa6893d..03a7f7d 100644 --- a/src/components/ThemeSwitcher.tsx +++ b/src/components/ThemeSwitcher.tsx @@ -11,11 +11,20 @@ type Props = { export default function ThemeSwitcher({ dayIcon, nightIcon }: Props) { const [theme, setTheme] = useState("light"); - function updateClass(mode: string) { - if (mode === "light") document.documentElement.classList.remove("dark"); + function updateClass(toTheme: string) { + if (toTheme === "light") document.documentElement.classList.remove("dark"); else document.documentElement.classList.add("dark"); } + const reverseTheme = () => (theme === "dark" ? "light" : "dark"); + + function syncTheme() { + const toTheme = reverseTheme(); + setTheme(toTheme); + localStorage.setItem("starheart-color-scheme", toTheme); + updateClass(toTheme); + } + useEffect(() => { const toTheme = localStorage.getItem("starheart-color-scheme") || "light"; setTheme(toTheme); @@ -28,9 +37,7 @@ export default function ThemeSwitcher({ dayIcon, nightIcon }: Props) { !window.matchMedia("(prefers-reduced-motion: reduce)").matches; if (!isAppearanceTransition) { - const toTheme = theme === "dark" ? "light" : "dark"; - setTheme(toTheme); - updateClass(toTheme); + syncTheme(); return; } @@ -41,12 +48,7 @@ export default function ThemeSwitcher({ dayIcon, nightIcon }: Props) { Math.max(y, innerHeight - y), ); // @ts-expect-error: Transition API - const transition = document.startViewTransition(() => { - const toTheme = theme === "dark" ? "light" : "dark"; - setTheme(toTheme); - localStorage.setItem("starheart-color-scheme", toTheme); - updateClass(toTheme); - }); + const transition = document.startViewTransition(() => syncTheme()); transition.ready.then(() => { const clipPath = [ `circle(0px at ${x}px ${y}px)`,