Files
portabase/src/features/theme/mode-toggle.tsx
T

58 lines
2.1 KiB
TypeScript
Raw Normal View History

"use client"
2026-02-10 17:02:06 +01:00
import { Moon, Sun, Monitor } from "lucide-react"
import { authClient } from "@/lib/auth/auth-client"
import { motion } from "motion/react"
import { useTheme } from "next-themes"
import { cn } from "@/lib/utils"
const themes = [
{ id: "light", icon: Sun, label: "Light" },
{ id: "system", icon: Monitor, label: "System" },
{ id: "dark", icon: Moon, label: "Dark" },
] as const
export function ModeToggle() {
2026-02-10 17:02:06 +01:00
const { theme } = useTheme()
2025-12-22 20:32:18 +01:00
2026-02-10 17:02:06 +01:00
const currentIndex = themes.findIndex((t) => t.id === theme)
const activeIndex = currentIndex === -1 ? 1 : currentIndex
const handleThemeChange = async (newTheme: "light" | "system" | "dark") => {
await authClient.updateUser({ theme: newTheme })
}
return (
2026-02-11 14:42:07 +01:00
<div className="flex items-center justify-center rounded-full bg-muted/50 p-0.5 border border-border/50 relative w-fit">
2026-02-10 17:02:06 +01:00
<motion.div
2026-02-11 14:42:07 +01:00
className="absolute h-6 w-7 rounded-full bg-background shadow-sm z-0 border border-border/20"
2026-02-10 17:02:06 +01:00
initial={false}
2026-02-11 14:42:07 +01:00
animate={{ x: activeIndex * 28 }}
2026-02-10 17:02:06 +01:00
transition={{ type: "spring", stiffness: 400, damping: 30 }}
2026-02-11 14:42:07 +01:00
style={{ left: "2px" }}
2026-02-10 17:02:06 +01:00
/>
<div className="flex gap-0 relative z-10">
{themes.map((t) => {
const Icon = t.icon
const isActive = theme === t.id
return (
<button
key={t.id}
onClick={() => handleThemeChange(t.id)}
className={cn(
2026-02-11 14:42:07 +01:00
"flex h-6 w-7 items-center justify-center rounded-full transition-colors duration-200 hover:text-foreground outline-none",
2026-02-10 17:02:06 +01:00
isActive ? "text-primary" : "text-muted-foreground"
)}
aria-label={t.label}
>
2026-02-11 14:42:07 +01:00
<Icon className="h-3.5 w-3.5" />
2026-02-10 17:02:06 +01:00
</button>
)
})}
</div>
</div>
)
2026-02-10 17:02:06 +01:00
}