"use client"; import { Slider } from "@/components/ui/slider"; import type { AccentColorOption, AppearanceSettings, RadiusPreset, WallpaperOption, } from "@/lib/desktop/appearance"; import { APPEARANCE_RADIUS_MAX, APPEARANCE_RADIUS_MIN, RADIUS_PRESETS, } from "@/lib/desktop/appearance"; import { SectionDivider, Toggle } from "@/modules/settings/components/panel/controls"; import { SETTINGS_BADGE_SURFACE, SETTINGS_PANEL_INSET, } from "@/modules/settings/components/panel/surface"; import { Check } from "@/components/icons/platform-icons"; import { cn } from "@/lib/utils"; import { AUTO_ACCENT_VALUE } from "@/lib/desktop/appearance"; type AppearanceSectionProps = { appearance: AppearanceSettings; wallpaperOptions: WallpaperOption[]; accentOptions: AccentColorOption[]; onAppearanceChange: (patch: Partial) => void; wallpaperAccentColor: string | null; }; // ── Segmented control ──────────────────────────────────────────────────────── function SegmentedControl({ options, value, onChange, }: { options: { label: string; value: T }[]; value: T; onChange: (value: T) => void; }) { return (
{options.map((opt) => ( ))}
); } // ── Row wrapper for Display controls ──────────────────────────────────────── function ControlRow({ label, children, }: { label: string; children: React.ReactNode; }) { return (
{label} {children}
); } // ── Theme mini-preview ─────────────────────────────────────────────────────── function ThemePreview({ theme }: { theme: "dark" | "light" }) { const isDark = theme === "dark"; const bg = isDark ? "oklch(0.13 0.015 250)" : "oklch(0.96 0.005 250)"; const sidebar = isDark ? "oklch(0.10 0.012 250 / 0.8)" : "oklch(0.90 0.008 250 / 0.8)"; const card = isDark ? "oklch(0.17 0.015 250 / 0.7)" : "oklch(0.99 0.004 250 / 0.7)"; const line1 = isDark ? "bg-white/20" : "bg-black/15"; const line2 = isDark ? "bg-white/10" : "bg-black/8"; const dot = isDark ? "bg-white/30" : "bg-black/20"; return (
{/* Sidebar strip */}
{[...Array(3)].map((_, i) => (
))}
{/* Content */}
{[...Array(3)].map((_, i) => (
))}
); } // ── Main component ─────────────────────────────────────────────────────────── export function AppearanceSection({ appearance, wallpaperOptions, accentOptions, onAppearanceChange, wallpaperAccentColor, }: AppearanceSectionProps) { const radiusPresets: RadiusPreset[] = RADIUS_PRESETS; const themeOptions: { name: string; value: AppearanceSettings["theme"] }[] = [ { name: "Dark", value: "dark" }, { name: "Light", value: "light" }, ]; return (
{/* ── Theme ── */}
{themeOptions.map((theme) => { const active = appearance.theme === theme.value; return ( ); })}
{/* ── Accent Color ── */}
{/* Auto option — derives color from wallpaper */} {(() => { const active = appearance.accentColor === AUTO_ACCENT_VALUE; const previewColor = wallpaperAccentColor ?? "oklch(0.65 0.2 250)"; return ( ); })()} {accentOptions.map((color) => { const active = appearance.accentColor === color.value; return ( ); })}

{appearance.accentColor === AUTO_ACCENT_VALUE ? "Auto — from wallpaper" : (accentOptions.find((c) => c.value === appearance.accentColor)?.name ?? "Custom")}

{/* ── Wallpaper ── */}
{wallpaperOptions.map((wallpaper) => { const active = appearance.wallpaper === wallpaper.src; return ( ); })}
{/* ── Shape ── */}
{/* Live preview */}
{/* Slider + badge */}
{ const next = values[0]; if (next === undefined) return; onAppearanceChange({ radius: next }); }} />
{appearance.radius}px
{/* Preset swatches */}
{radiusPresets.map((preset) => { const active = appearance.radius === preset.value; return ( ); })}
{/* ── Liquid Glass ── */}

Choose the look of glass surfaces across the interface.

{(["clear", "tinted"] as const).map((style) => { const active = appearance.glassStyle === style; return ( ); })}
{/* ── Display ── */}
onAppearanceChange({ iconSize: v })} /> onAppearanceChange({ fontSize: v })} /> onAppearanceChange({ dockPosition: v })} />
onAppearanceChange({ animationsEnabled: !appearance.animationsEnabled })} />
); }