import { useCallback } from "react"; import { Sun, Moon, Monitor } from "lucide-react"; import type { ThemeMode, ColorTheme } from "@fusion/core"; interface ThemeSelectorProps { themeMode: ThemeMode; colorTheme: ColorTheme; dashboardFontScalePct?: number; onThemeModeChange: (mode: ThemeMode) => void; onColorThemeChange: (theme: ColorTheme) => void; onDashboardFontScaleChange?: (scalePct: number) => void; } const THEME_MODES: { value: ThemeMode; label: string; icon: typeof Sun }[] = [ { value: "light", label: "Light", icon: Sun }, { value: "dark", label: "Dark", icon: Moon }, { value: "system", label: "System", icon: Monitor }, ]; const FONT_SCALE_OPTIONS = [ { value: 90, label: "Small" }, { value: 100, label: "Default" }, { value: 110, label: "Large" }, { value: 120, label: "Largest" }, ] as const; const COLOR_THEMES: { value: ColorTheme; label: string; className: string }[] = [ { value: "default", label: "Default", className: "theme-swatch-default" }, { value: "ocean", label: "Ocean", className: "theme-swatch-ocean" }, { value: "forest", label: "Forest", className: "theme-swatch-forest" }, { value: "sunset", label: "Sunset", className: "theme-swatch-sunset" }, { value: "zen", label: "Zen", className: "theme-swatch-zen" }, { value: "berry", label: "Berry", className: "theme-swatch-berry" }, { value: "high-contrast", label: "High Contrast", className: "theme-swatch-high-contrast" }, { value: "industrial", label: "Industrial", className: "theme-swatch-industrial" }, { value: "monochrome", label: "Mono", className: "theme-swatch-monochrome" }, { value: "slate", label: "Slate", className: "theme-swatch-slate" }, { value: "ash", label: "Ash", className: "theme-swatch-ash" }, { value: "graphite", label: "Graphite", className: "theme-swatch-graphite" }, { value: "silver", label: "Silver", className: "theme-swatch-silver" }, { value: "solarized", label: "Solarized", className: "theme-swatch-solarized" }, { value: "factory", label: "Factory", className: "theme-swatch-factory" }, { value: "ayu", label: "Ayu", className: "theme-swatch-ayu" }, { value: "one-dark", label: "One Dark", className: "theme-swatch-one-dark" }, { value: "nord", label: "Nord", className: "theme-swatch-nord" }, { value: "dracula", label: "Dracula", className: "theme-swatch-dracula" }, { value: "gruvbox", label: "Gruvbox", className: "theme-swatch-gruvbox" }, { value: "tokyo-night", label: "Tokyo Night", className: "theme-swatch-tokyo-night" }, { value: "catppuccin-mocha", label: "Catppuccin Mocha", className: "theme-swatch-catppuccin-mocha" }, { value: "github-dark", label: "GitHub Dark", className: "theme-swatch-github-dark" }, { value: "everforest", label: "Everforest", className: "theme-swatch-everforest" }, { value: "rose-pine", label: "Rosé Pine", className: "theme-swatch-rose-pine" }, { value: "kanagawa", label: "Kanagawa", className: "theme-swatch-kanagawa" }, { value: "night-owl", label: "Night Owl", className: "theme-swatch-night-owl" }, { value: "palenight", label: "Palenight", className: "theme-swatch-palenight" }, { value: "monokai-pro", label: "Monokai Pro", className: "theme-swatch-monokai-pro" }, { value: "slime", label: "Slime", className: "theme-swatch-slime" }, { value: "brutalist", label: "Brutalist", className: "theme-swatch-brutalist" }, { value: "neon-city", label: "Neon City", className: "theme-swatch-neon-city" }, { value: "parchment", label: "Parchment", className: "theme-swatch-parchment" }, { value: "terminal", label: "Terminal", className: "theme-swatch-terminal" }, { value: "glass", label: "Glass", className: "theme-swatch-glass" }, { value: "horizon", label: "Horizon", className: "theme-swatch-horizon" }, { value: "vitesse", label: "Vitesse", className: "theme-swatch-vitesse" }, { value: "outrun", label: "Outrun", className: "theme-swatch-outrun" }, { value: "snazzy", label: "Snazzy", className: "theme-swatch-snazzy" }, { value: "porple", label: "Porple", className: "theme-swatch-porple" }, { value: "espresso", label: "Espresso", className: "theme-swatch-espresso" }, { value: "mars", label: "Mars", className: "theme-swatch-mars" }, { value: "poimandres", label: "Poimandres", className: "theme-swatch-poimandres" }, { value: "ember", label: "Ember", className: "theme-swatch-ember" }, { value: "rust", label: "Rust", className: "theme-swatch-rust" }, { value: "copper", label: "Copper", className: "theme-swatch-copper" }, { value: "foundry", label: "Foundry", className: "theme-swatch-foundry" }, { value: "carbon", label: "Carbon", className: "theme-swatch-carbon" }, { value: "sandstone", label: "Sandstone", className: "theme-swatch-sandstone" }, { value: "lagoon", label: "Lagoon", className: "theme-swatch-lagoon" }, { value: "frost", label: "Frost", className: "theme-swatch-frost" }, { value: "lavender", label: "Lavender", className: "theme-swatch-lavender" }, { value: "neon-bloom", label: "Neon Bloom", className: "theme-swatch-neon-bloom" }, { value: "sepia", label: "Sepia", className: "theme-swatch-sepia" }, ]; /** * ThemeSelector component for choosing light/dark/system mode and color theme */ export function ThemeSelector({ themeMode, colorTheme, dashboardFontScalePct = 100, onThemeModeChange, onColorThemeChange, onDashboardFontScaleChange = () => {}, }: ThemeSelectorProps) { const handleReset = useCallback(() => { onThemeModeChange("dark"); onColorThemeChange("default"); onDashboardFontScaleChange(100); }, [onThemeModeChange, onColorThemeChange, onDashboardFontScaleChange]); return (
{/* Theme Mode Toggle */}
{THEME_MODES.map(({ value, label, icon: Icon }) => ( ))}
{/* Current Theme Preview */}
{themeMode === "light" ? ( ) : themeMode === "dark" ? ( ) : ( )}
Current theme
{themeMode === "system" ? "System" : `${themeMode.charAt(0).toUpperCase() + themeMode.slice(1)}`} {" / "} {COLOR_THEMES.find((t) => t.value === colorTheme)?.label}
Font Size
{FONT_SCALE_OPTIONS.map(({ value, label }) => ( ))}
{/* Color Theme Grid */}
Color Theme
{COLOR_THEMES.map(({ value, label, className }) => ( ))}
{/* Reset Button */}
); }