50 lines
1.4 KiB
TypeScript
50 lines
1.4 KiB
TypeScript
"use client";
|
|
|
|
import { useTheme } from "next-themes";
|
|
import { Moon, Sun, Monitor } from "lucide-react";
|
|
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuTrigger,
|
|
} from "@/components/ui/dropdown-menu";
|
|
|
|
const OPTIONS = [
|
|
{ value: "light", label: "Light", icon: Sun },
|
|
{ value: "dark", label: "Dark", icon: Moon },
|
|
{ value: "system", label: "System", icon: Monitor },
|
|
] as const;
|
|
|
|
export function ThemeToggle({ collapsed }: { collapsed?: boolean }) {
|
|
const { theme, setTheme } = useTheme();
|
|
const current = OPTIONS.find((o) => o.value === theme) ?? OPTIONS[2];
|
|
const Icon = current.icon;
|
|
|
|
return (
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger
|
|
render={
|
|
<Button
|
|
variant="ghost"
|
|
size={collapsed ? "icon" : "default"}
|
|
className={collapsed ? undefined : "w-full justify-start gap-2"}
|
|
>
|
|
<Icon className="size-4" />
|
|
{!collapsed && <span>Theme</span>}
|
|
</Button>
|
|
}
|
|
/>
|
|
<DropdownMenuContent align="start" side="right">
|
|
{OPTIONS.map((option) => (
|
|
<DropdownMenuItem key={option.value} onSelect={() => setTheme(option.value)}>
|
|
<option.icon className="size-4" />
|
|
{option.label}
|
|
</DropdownMenuItem>
|
|
))}
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
);
|
|
}
|