import { Moon, Sun } from "lucide-react"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; import { useTheme } from "../context/ThemeContext"; type ThemeToggleVariant = "icon" | "menu-action" | "compact-menu-action"; interface ThemeToggleProps { className?: string; /** * `icon` (default): compact icon button — suitable for headers, * floating chrome (e.g. the unauthenticated `/auth` page), and any * other surface that just wants a toggle affordance. * * `menu-action`: full-width row with label + description + icon — * suitable for explanatory menus. * * `compact-menu-action`: compact label + icon row — matches the * surrounding actions in `SidebarAccountMenu`. */ variant?: ThemeToggleVariant; /** * Called after `toggleTheme` runs. Surfaces like a popover menu use * this to dismiss the menu once the user has acted. */ onAfterToggle?: () => void; } const MENU_ACTION_DESCRIPTION = "Toggle the app appearance."; /** * Canonical theme-toggle widget. Both the signed-out `/auth` chrome and * the in-app account menu render through this component so the label, * icon, and toggle behaviour stay in sync as the theme model evolves. */ export function ThemeToggle({ className, variant = "icon", onAfterToggle }: ThemeToggleProps) { const { theme, toggleTheme } = useTheme(); const isDark = theme === "dark"; const label = isDark ? "Switch to light mode" : "Switch to dark mode"; const Icon = isDark ? Sun : Moon; function handleClick() { toggleTheme(); onAfterToggle?.(); } if (variant === "compact-menu-action") { return ( ); } if (variant === "menu-action") { return ( ); } return ( ); }