feat: add three-way theme toggle with system preference support

Enhanced ThemeToggle component to cycle through light, dark, and system
themes instead of just toggling between light and dark. Added DesktopIcon
for system theme state and improved accessibility with descriptive labels
showing current and next theme states.
This commit is contained in:
2025-10-23 11:01:02 -05:00
parent a2a83e9593
commit 9635098102

View File

@@ -2,7 +2,7 @@
import { useTheme } from "next-themes"; import { useTheme } from "next-themes";
import { IconButton } from "@radix-ui/themes"; import { IconButton } from "@radix-ui/themes";
import { MoonIcon, SunIcon } from "@radix-ui/react-icons"; import { MoonIcon, SunIcon, DesktopIcon } from "@radix-ui/react-icons";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
export const ThemeToggle = () => { export const ThemeToggle = () => {
@@ -19,22 +19,43 @@ export const ThemeToggle = () => {
} }
const toggleTheme = () => { const toggleTheme = () => {
setTheme(theme === "light" ? "dark" : "light"); if (theme === "light") {
setTheme("dark");
} else if (theme === "dark") {
setTheme("system");
} else {
setTheme("light");
}
}; };
const getNextTheme = () => {
if (theme === "light") return "dark";
if (theme === "dark") return "system";
return "light";
};
const getIcon = () => {
if (theme === "light") {
return <SunIcon width="22" height="22" />;
} else if (theme === "dark") {
return <MoonIcon width="22" height="22" />;
} else {
return <DesktopIcon width="22" height="22" />;
}
};
const nextTheme = getNextTheme();
const themeLabel = theme === "system" ? "system" : theme === "light" ? "light" : "dark";
return ( return (
<IconButton <IconButton
size="3" size="3"
variant="ghost" variant="ghost"
onClick={toggleTheme} onClick={toggleTheme}
aria-label="Toggle theme" aria-label="Toggle theme"
title={`Switch to ${theme === "light" ? "dark" : "light"} mode`} title={`Current: ${themeLabel} mode. Click to switch to ${nextTheme} mode`}
> >
{theme === "light" ? ( {getIcon()}
<MoonIcon width="22" height="22" />
) : (
<SunIcon width="22" height="22" />
)}
</IconButton> </IconButton>
); );
}; };