Openstatus www.openstatus.dev
at 4c0f4c00a38753a5d0dfd7e7b7b7706dec6f1503 73 lines 1.7 kB view raw
1"use client"; 2 3import { cn } from "@/lib/utils"; 4import { Laptop, Moon, Sun } from "lucide-react"; 5import { useTheme } from "next-themes"; 6import type * as React from "react"; 7import { useEffect, useState } from "react"; 8 9export function ThemeToggle({ 10 className, 11 ...props 12}: React.ComponentProps<"div">) { 13 const { setTheme, theme } = useTheme(); 14 const [mounted, setMounted] = useState(false); 15 16 useEffect(() => { 17 setMounted(true); 18 }, []); 19 20 if (!mounted) { 21 return ( 22 <div 23 className={cn( 24 "flex items-center gap-px bg-border [&>*]:flex [&>*]:flex-1 [&>*]:items-center [&>*]:justify-center [&>*]:bg-background [&>*]:p-4", 25 className, 26 )} 27 {...props} 28 > 29 <div> 30 <Sun className="h-6 w-6" /> 31 </div> 32 <div> 33 <Moon className="h-6 w-6" /> 34 </div> 35 <div> 36 <Laptop className="h-6 w-6" /> 37 </div> 38 </div> 39 ); 40 } 41 42 return ( 43 <div 44 className={cn( 45 "flex items-center gap-px bg-border [&>*]:flex [&>*]:flex-1 [&>*]:items-center [&>*]:justify-center [&>*]:bg-background [&>*]:p-4 [&>*]:hover:bg-muted [&>*]:data-[active=true]:bg-muted", 46 className, 47 )} 48 {...props} 49 > 50 <button 51 type="button" 52 data-active={theme === "light"} 53 onClick={() => setTheme("light")} 54 > 55 [light] 56 </button> 57 <button 58 type="button" 59 data-active={theme === "dark"} 60 onClick={() => setTheme("dark")} 61 > 62 [dark] 63 </button> 64 <button 65 type="button" 66 data-active={theme === "system"} 67 onClick={() => setTheme("system")} 68 > 69 [system] 70 </button> 71 </div> 72 ); 73}