always-uptime / app /components /theme-toggle.tsx
sachnun's picture
Update UI text and improve tooltip design
4a10ba1
raw
history blame
2.28 kB
import { Moon, Sun, Monitor } from "lucide-react";
import { useTheme } from "./theme-provider";
import { Button } from "./ui/button";
import { useState, useRef, useEffect } from "react";
export function ThemeToggle() {
const { theme, setTheme } = useTheme();
const [isOpen, setIsOpen] = useState(false);
const dropdownRef = useRef<HTMLDivElement>(null);
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
setIsOpen(false);
}
}
document.addEventListener("mousedown", handleClickOutside);
return () => document.removeEventListener("mousedown", handleClickOutside);
}, []);
const getIcon = () => {
if (theme === "light") return <Sun className="h-5 w-5" />;
if (theme === "dark") return <Moon className="h-5 w-5" />;
return <Monitor className="h-5 w-5" />;
};
const themes = [
{ value: "light", label: "Light", icon: <Sun className="h-4 w-4" /> },
{ value: "dark", label: "Dark", icon: <Moon className="h-4 w-4" /> },
{ value: "system", label: "System", icon: <Monitor className="h-4 w-4" /> },
];
return (
<div className="relative" ref={dropdownRef}>
<Button
variant="ghost"
size="icon"
onClick={() => setIsOpen(!isOpen)}
aria-label="Toggle theme"
>
{getIcon()}
</Button>
{isOpen && (
<div className="absolute right-0 mt-2 w-40 rounded-md shadow-lg bg-popover border border-border z-50">
<div className="py-1">
{themes.map((themeOption) => (
<button
key={themeOption.value}
onClick={() => {
setTheme(themeOption.value as "light" | "dark" | "system");
setIsOpen(false);
}}
className={`w-full flex items-center gap-2 px-4 py-2 text-sm hover:bg-accent hover:text-accent-foreground transition-colors ${
theme === themeOption.value ? "bg-accent" : ""
}`}
>
{themeOption.icon}
<span>{themeOption.label}</span>
</button>
))}
</div>
</div>
)}
</div>
);
}