"use client";
import type { LucideIcon } from "lucide-react";
import {
Monitor,
Check,
Sun,
Moon,
Sunset,
Waves,
Leaf,
Hexagon,
Rose,
Flower2,
Mountain,
TreePine,
Grape,
Star,
Flame,
Wine,
DraftingCompass,
CircuitBoard,
} from "lucide-react";
import { useTheme } from "@/components/theme/theme-provider";
import type { ThemeName } from "@/components/theme/theme-provider";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
type ThemeOption = {
value: ThemeName;
label: string;
icon: LucideIcon;
swatch: string;
};
// The looks, grouped by surface. Each value is one next-themes value (see
// app/layout.tsx for the class mapping); the little dot is the theme's own
// accent so the picker previews the vibe.
const LIGHT_OPTIONS: ThemeOption[] = [
{ value: "default", label: "Default", icon: Sun, swatch: "#4f56e0" },
{ value: "sunset", label: "Sunset", icon: Sunset, swatch: "#c2410c" },
{ value: "meadow", label: "Meadow", icon: Leaf, swatch: "#059669" },
{ value: "honey", label: "Honey", icon: Hexagon, swatch: "#d97706" },
{ value: "rose", label: "Rosé", icon: Rose, swatch: "#e11d48" },
{ value: "lavender", label: "Lavender", icon: Flower2, swatch: "#7c3aed" },
{ value: "slate", label: "Slate", icon: Mountain, swatch: "#4a6d9c" },
{ value: "blueprint", label: "Blueprint", icon: DraftingCompass, swatch: "#2b4bc4" },
];
const DARK_OPTIONS: ThemeOption[] = [
{ value: "dark", label: "Dark", icon: Moon, swatch: "#7c83f2" },
{ value: "ocean", label: "Ocean", icon: Waves, swatch: "#5eead4" },
{ value: "pine", label: "Pine", icon: TreePine, swatch: "#34d399" },
{ value: "plum", label: "Plum", icon: Grape, swatch: "#c084fc" },
{ value: "midnight", label: "Midnight", icon: Star, swatch: "#93c5fd" },
{ value: "ember", label: "Ember", icon: Flame, swatch: "#fbbf24" },
{ value: "rosewood", label: "Rosewood", icon: Wine, swatch: "#fb7185" },
{ value: "cyberpunk", label: "Cyberpunk", icon: CircuitBoard, swatch: "#ff2bd6" },
];
const ALL_OPTIONS = [...LIGHT_OPTIONS, ...DARK_OPTIONS];
function OptionRow({
option,
active,
onSelect,
}: {
option: ThemeOption;
active: boolean;
onSelect: () => void;
}) {
const Icon = option.icon;
return (
);
}
export function ThemeToggle({ collapsed }: { collapsed?: boolean }) {
const { theme, setTheme } = useTheme();
// The picker shows all the real themes in Light/Dark sections; "system" is
// handled by a dedicated row since it resolves to one of them per device
// preference.
const known = ALL_OPTIONS.find((o) => o.value === theme);
const isSystem = theme === "system" || theme === undefined;
const Icon = (isSystem ? Monitor : known?.icon) ?? Monitor;
const label = isSystem ? "System" : known?.label ?? "Default";
return (
{!collapsed && {label}}
}
/>
Light
{LIGHT_OPTIONS.map((option) => (
setTheme(option.value)}
/>
))}
Dark
{DARK_OPTIONS.map((option) => (
setTheme(option.value)}
/>
))}
);
}