Files
goose/extensions-site/app/components/themeToggle.tsx
Bradley Axen 1c9a7c0b05 feat: V1.0 (#734)
Co-authored-by: Michael Neale <michael.neale@gmail.com>
Co-authored-by: Wendy Tang <wendytang@squareup.com>
Co-authored-by: Jarrod Sibbison <72240382+jsibbison-square@users.noreply.github.com>
Co-authored-by: Alex Hancock <alex.hancock@example.com>
Co-authored-by: Alex Hancock <alexhancock@block.xyz>
Co-authored-by: Lifei Zhou <lifei@squareup.com>
Co-authored-by: Wes <141185334+wesrblock@users.noreply.github.com>
Co-authored-by: Max Novich <maksymstepanenko1990@gmail.com>
Co-authored-by: Zaki Ali <zaki@squareup.com>
Co-authored-by: Salman Mohammed <smohammed@squareup.com>
Co-authored-by: Kalvin C <kalvinnchau@users.noreply.github.com>
Co-authored-by: Alec Thomas <alec@swapoff.org>
Co-authored-by: lily-de <119957291+lily-de@users.noreply.github.com>
Co-authored-by: kalvinnchau <kalvin@block.xyz>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Rizel Scarlett <rizel@squareup.com>
Co-authored-by: bwrage <bwrage@squareup.com>
Co-authored-by: Kalvin Chau <kalvin@squareup.com>
Co-authored-by: Alice Hau <110418948+ahau-square@users.noreply.github.com>
Co-authored-by: Alistair Gray <ajgray@stripe.com>
Co-authored-by: Nahiyan Khan <nahiyan.khan@gmail.com>
Co-authored-by: Alex Hancock <alexhancock@squareup.com>
Co-authored-by: Nahiyan Khan <nahiyan@squareup.com>
Co-authored-by: marcelle <1852848+laanak08@users.noreply.github.com>
Co-authored-by: Yingjie He <yingjiehe@block.xyz>
Co-authored-by: Yingjie He <yingjiehe@squareup.com>
Co-authored-by: Lily Delalande <ldelalande@block.xyz>
Co-authored-by: Adewale Abati <acekyd01@gmail.com>
Co-authored-by: Ebony Louis <ebony774@gmail.com>
Co-authored-by: Angie Jones <jones.angie@gmail.com>
Co-authored-by: Ebony Louis <55366651+EbonyLouis@users.noreply.github.com>
2025-01-24 13:04:43 -08:00

103 lines
4.0 KiB
TypeScript

import { useEffect, useState } from "react";
export const ThemeToggle = ({ className = "" }) => {
const [activeTheme, setActiveTheme] = useState<string>("system");
useEffect(() => {
const savedTheme = localStorage.getItem("theme");
if (savedTheme === "system" || !savedTheme) {
applySystemTheme();
setActiveTheme("system");
} else {
applyTheme(savedTheme);
setActiveTheme(savedTheme);
}
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
const handleSystemThemeChange = () => {
if (!savedTheme || savedTheme === "system") {
applySystemTheme();
}
};
mediaQuery.addEventListener("change", handleSystemThemeChange);
return () => {
mediaQuery.removeEventListener("change", handleSystemThemeChange);
};
}, []);
const applyTheme = (theme: string) => {
if (theme === "dark") {
document.documentElement.classList.add("dark");
} else if (theme === "light") {
document.documentElement.classList.remove("dark");
}
};
const handleThemeChange = (newTheme: string) => {
setActiveTheme(newTheme);
localStorage.setItem("theme", newTheme);
if (newTheme === "system") {
applySystemTheme();
} else {
applyTheme(newTheme);
}
};
const applySystemTheme = () => {
const systemPrefersDark = window.matchMedia(
"(prefers-color-scheme: dark)"
).matches;
if (systemPrefersDark) {
document.documentElement.classList.add("dark");
} else {
document.documentElement.classList.remove("dark");
}
};
return (
<div
className={`h-12 w-12 overflow-hidden relative rounded-full border border-borderSubtle ${className}`}
>
<button
// onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
onClick={() => handleThemeChange("light")}
className="absolute left-[-1px] bg-bg flex h-12 w-12 flex-row items-center justify-center transition-all rotate-180 dark:rotate-0 translate-x-[100%] dark:translate-x-[0%]"
>
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
className="h-5 w-5 sm:h-7 sm:w-7 text-[#fac64d] transition-all duration-[400ms]"
>
<path d="M6.995 12C6.995 14.761 9.241 17.007 12.002 17.007C14.763 17.007 17.009 14.761 17.009 12C17.009 9.239 14.763 6.993 12.002 6.993C9.241 6.993 6.995 9.239 6.995 12ZM11 19H13V22H11V19ZM11 2H13V5H11V2ZM2 11H5V13H2V11ZM19 11H22V13H19V11Z"></path>
<path d="M5.63702 19.778L4.22302 18.364L6.34402 16.243L7.75802 17.657L5.63702 19.778Z"></path>
<path d="M16.242 6.34405L18.364 4.22205L19.778 5.63605L17.656 7.75805L16.242 6.34405Z"></path>
<path d="M6.34402 7.75902L4.22302 5.63702L5.63802 4.22302L7.75802 6.34502L6.34402 7.75902Z"></path>
<path d="M19.778 18.3639L18.364 19.7779L16.242 17.6559L17.656 16.2419L19.778 18.3639Z"></path>
</svg>
</button>
<button
// onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
onClick={() => handleThemeChange("dark")}
className="absolute left-[-1px] bg-bg flex h-12 w-12 flex-row items-center justify-center transition-all dark:translate-x-[-100%] dark:-rotate-90"
>
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
className="h-5 w-5 sm:h-7 sm:w-7 text-[#8b8bf8] transition-all duration-[400ms]"
>
<path d="M12 11.807C10.7418 10.5483 9.88488 8.94484 9.53762 7.1993C9.19037 5.45375 9.36832 3.64444 10.049 2C8.10826 2.38205 6.3256 3.33431 4.92899 4.735C1.02399 8.64 1.02399 14.972 4.92899 18.877C8.83499 22.783 15.166 22.782 19.072 18.877C20.4723 17.4805 21.4245 15.6983 21.807 13.758C20.1625 14.4385 18.3533 14.6164 16.6077 14.2692C14.8622 13.9219 13.2588 13.0651 12 11.807V11.807Z"></path>
</svg>
</button>
</div>
);
};