85 lines
2.1 KiB
TypeScript
85 lines
2.1 KiB
TypeScript
"use client"
|
|
|
|
import * as React from "react"
|
|
import { useTheme } from "next-themes"
|
|
import { Button } from "@/components/ui/button"
|
|
|
|
export function ThemeToggle() {
|
|
const { setTheme, theme, resolvedTheme } = useTheme()
|
|
const [mounted, setMounted] = React.useState(false)
|
|
|
|
React.useEffect(() => {
|
|
setMounted(true)
|
|
}, [])
|
|
|
|
if (!mounted) {
|
|
return null
|
|
}
|
|
|
|
const toggleTheme = () => {
|
|
setTheme(resolvedTheme === "light" ? "dark" : "light")
|
|
}
|
|
|
|
return (
|
|
<Button
|
|
variant="outline"
|
|
size="icon"
|
|
onClick={toggleTheme}
|
|
className="rounded-full fixed bottom-4 right-4 z-[9999] bg-white dark:bg-gray-800 border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 shadow-lg transition-all duration-200 hover:scale-110"
|
|
>
|
|
{resolvedTheme === "light" ? (
|
|
<MoonIcon className="h-[1.2rem] w-[1.2rem] transition-all duration-200" />
|
|
) : (
|
|
<SunIcon className="h-[1.2rem] w-[1.2rem] transition-all duration-200" />
|
|
)}
|
|
<span className="sr-only">Toggle theme</span>
|
|
</Button>
|
|
)
|
|
}
|
|
|
|
function SunIcon(props: React.SVGProps<SVGSVGElement>) {
|
|
return (
|
|
<svg
|
|
{...props}
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width="24"
|
|
height="24"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="2"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
>
|
|
<circle cx="12" cy="12" r="4" />
|
|
<path d="M12 2v2" />
|
|
<path d="M12 20v2" />
|
|
<path d="m4.93 4.93 1.41 1.41" />
|
|
<path d="m17.66 17.66 1.41 1.41" />
|
|
<path d="M2 12h2" />
|
|
<path d="M20 12h2" />
|
|
<path d="m6.34 17.66-1.41 1.41" />
|
|
<path d="m19.07 4.93-1.41 1.41" />
|
|
</svg>
|
|
)
|
|
}
|
|
|
|
function MoonIcon(props: React.SVGProps<SVGSVGElement>) {
|
|
return (
|
|
<svg
|
|
{...props}
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
width="24"
|
|
height="24"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="2"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
>
|
|
<path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" />
|
|
</svg>
|
|
)
|
|
}
|