Files
famapp/src/components/theme-picker.tsx
T
ginnoirandClaude Sonnet 4.6 8cc2ef0732 Add theming infrastructure (task 08)
CSS-variable multi-theme system (default + warm) × {light, dark, system}; per-user theme/theme_mode columns; no-flash pre-paint script; useTheme hook + ThemePicker component on /settings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 02:50:05 -05:00

71 lines
1.7 KiB
TypeScript

"use client";
import { THEMES, THEME_MODES } from "@/modules/_core/themes";
import type { ThemeId, ThemeMode } from "@/modules/_core/themes";
import { useTheme } from "@/hooks/use-theme";
import { Label } from "@/components/ui/label";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
interface Props {
initialTheme?: ThemeId;
initialMode?: ThemeMode;
signedIn?: boolean;
}
export function ThemePicker({
initialTheme = "default",
initialMode = "system",
signedIn = false,
}: Props) {
const { theme, mode, setTheme, setMode } = useTheme(
initialTheme,
initialMode,
signedIn,
);
return (
<div className="space-y-4">
<div className="space-y-1.5">
<Label>Theme</Label>
<Select value={theme} onValueChange={(v) => setTheme(v as ThemeId)}>
<SelectTrigger className="w-48">
<SelectValue />
</SelectTrigger>
<SelectContent>
{THEMES.map((t) => (
<SelectItem key={t.id} value={t.id}>
{t.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="space-y-1.5">
<Label>Mode</Label>
<div className="flex gap-1">
{THEME_MODES.map((m) => (
<Button
key={m.id}
variant="outline"
size="sm"
className={cn(mode === m.id && "bg-primary text-primary-foreground")}
onClick={() => setMode(m.id)}
>
{m.label}
</Button>
))}
</div>
</div>
</div>
);
}