import { useState, useEffect } from 'react'; import { Label } from '@/components/ui/label'; import { Palette, Moon, Sun, Type } from 'lucide-react'; import { darkThemes, lightThemes } from '@/config/theme-options'; import { UI_SANS_FONT_OPTIONS, UI_MONO_FONT_OPTIONS, DEFAULT_FONT_VALUE, } from '@/config/ui-font-options'; import { cn } from '@/lib/utils'; import { useAppStore } from '@/store/app-store'; import { FontSelector } from '@/components/shared'; import type { Theme } from '../shared/types'; interface AppearanceSectionProps { effectiveTheme: Theme; onThemeChange: (theme: Theme) => void; } export function AppearanceSection({ effectiveTheme, onThemeChange }: AppearanceSectionProps) { const { fontFamilySans, fontFamilyMono, setFontSans, setFontMono } = useAppStore(); // Determine if current theme is light or dark const isLightTheme = lightThemes.some((t) => t.value === effectiveTheme); const [activeTab, setActiveTab] = useState<'dark' | 'light'>(isLightTheme ? 'light' : 'dark'); // Sync active tab when theme changes useEffect(() => { const currentIsLight = lightThemes.some((t) => t.value === effectiveTheme); setActiveTab(currentIsLight ? 'light' : 'dark'); }, [effectiveTheme]); const themesToShow = activeTab === 'dark' ? darkThemes : lightThemes; // Convert null to 'default' for Select component // Also fallback to default if the stored font is not in the available options const isValidSansFont = (font: string | null): boolean => { if (!font) return false; return UI_SANS_FONT_OPTIONS.some((opt) => opt.value === font); }; const isValidMonoFont = (font: string | null): boolean => { if (!font) return false; return UI_MONO_FONT_OPTIONS.some((opt) => opt.value === font); }; const fontSansValue = fontFamilySans && isValidSansFont(fontFamilySans) ? fontFamilySans : DEFAULT_FONT_VALUE; const fontMonoValue = fontFamilyMono && isValidMonoFont(fontFamilyMono) ? fontFamilyMono : DEFAULT_FONT_VALUE; const handleFontSansChange = (value: string) => { setFontSans(value === DEFAULT_FONT_VALUE ? null : value); }; const handleFontMonoChange = (value: string) => { setFontMono(value === DEFAULT_FONT_VALUE ? null : value); }; return (

Appearance

Customize the look and feel of your application.

{/* Theme Section */}
{/* Dark/Light Tabs */}
{themesToShow.map(({ value, label, Icon, testId, color }) => { const isActive = effectiveTheme === value; return ( ); })}
{/* Fonts Section */}

Set default fonts for all projects. Individual projects can override these settings.

{/* UI Font Selector */}

Used for headings, labels, and UI text

{/* Code Font Selector */}

Used for code blocks and monospaced text

); }