UNPKG

lightswind

Version:

A collection of beautifully crafted React Components, Blocks & Templates for Modern Developers. Create stunning web applications effortlessly by using our 160+ professional and animated react components.

63 lines (62 loc) 5.18 kB
// @ts-nocheck "use client"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useState, useEffect } from "react"; import { motion } from "framer-motion"; import { Sun, Moon, Cloud, Star } from "lucide-react"; import { cn } from "../../lib/utils"; export function CoolThemeToggle({ className, size = "md" }) { const [theme, setTheme] = useState("light"); const [mounted, setMounted] = useState(false); useEffect(() => { setMounted(true); const isDark = document.documentElement.classList.contains("dark"); setTheme(isDark ? "dark" : "light"); const observer = new MutationObserver(() => { setTheme(document.documentElement.classList.contains("dark") ? "dark" : "light"); }); observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"] }); return () => observer.disconnect(); }, []); const toggleTheme = () => { const newTheme = theme === "light" ? "dark" : "light"; setTheme(newTheme); if (newTheme === "dark") { document.documentElement.classList.add("dark"); localStorage.setItem("theme", "dark"); } else { document.documentElement.classList.remove("dark"); localStorage.setItem("theme", "light"); } }; if (!mounted) return _jsx("div", { className: cn("inline-flex rounded-full bg-muted", size === "sm" ? "h-6 w-12" : size === "md" ? "h-8 w-16" : "h-10 w-20") }); const sizes = { sm: { button: "w-12 h-6", thumb: "w-4 h-4", icon: "w-2.5 h-2.5", padding: "p-1", translateX: "translateX(24px)", cloudSize: "w-3 h-3" }, md: { button: "w-16 h-8", thumb: "w-6 h-6", icon: "w-4 h-4", padding: "p-1", translateX: "translateX(32px)", cloudSize: "w-5 h-5" }, lg: { button: "w-20 h-10", thumb: "w-8 h-8", icon: "w-5 h-5", padding: "p-1", translateX: "translateX(40px)", cloudSize: "w-6 h-6" } }; const currentSize = sizes[size]; return (_jsxs("button", { onClick: toggleTheme, className: cn("relative rounded-full transition-colors duration-500 ease-in-out focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 overflow-hidden", theme === "dark" ? "bg-slate-900" : "bg-sky-300", currentSize.button, currentSize.padding, className), "aria-label": "Toggle theme", children: [_jsxs("div", { className: "absolute inset-0 z-0 overflow-hidden rounded-full", children: [_jsx(motion.div, { initial: false, animate: { opacity: theme === "light" ? 1 : 0, y: theme === "light" ? 0 : 10, }, transition: { duration: 0.4 }, className: "absolute inset-0 flex items-center justify-end pr-2 text-white", children: _jsx(Cloud, { className: cn("text-white/80 fill-white/80", currentSize.cloudSize) }) }), _jsx(motion.div, { initial: false, animate: { opacity: theme === "dark" ? 1 : 0, y: theme === "dark" ? 0 : -10, }, transition: { duration: 0.4 }, className: "absolute inset-0 flex items-center justify-start pl-2", children: _jsxs("div", { className: "relative w-full h-full", children: [_jsx(Star, { className: cn("absolute top-1 left-2 text-yellow-100 fill-yellow-100 opacity-70", size === "lg" ? "w-2 h-2" : "w-1 h-1") }), _jsx(Star, { className: cn("absolute bottom-2 left-4 text-yellow-100 fill-yellow-100 opacity-50", size === "lg" ? "w-3 h-3" : "w-1.5 h-1.5") }), _jsx(Star, { className: cn("absolute top-3 left-6 text-yellow-100 fill-yellow-100 opacity-90", size === "lg" ? "w-1.5 h-1.5" : "w-1 h-1") })] }) })] }), _jsx(motion.div, { layout: true, transition: { type: "spring", stiffness: 500, damping: 30, }, className: cn("relative z-10 flex items-center justify-center rounded-full shadow-md", theme === "dark" ? "bg-slate-800" : "bg-yellow-400", currentSize.thumb), animate: { x: theme === "dark" ? parseInt(currentSize.translateX.replace("translateX(", "").replace("px)", "")) : 0 }, children: _jsxs("div", { className: "relative flex items-center justify-center w-full h-full", children: [_jsx(motion.div, { initial: false, animate: { rotate: theme === "dark" ? 180 : 0, scale: theme === "dark" ? 0 : 1, opacity: theme === "dark" ? 0 : 1, }, transition: { duration: 0.4 }, className: "absolute", children: _jsx(Sun, { className: cn("text-white fill-white/20", currentSize.icon) }) }), _jsx(motion.div, { initial: false, animate: { rotate: theme === "dark" ? 0 : -180, scale: theme === "dark" ? 1 : 0, opacity: theme === "dark" ? 1 : 0, }, transition: { duration: 0.4 }, className: "absolute flex items-center justify-center", children: _jsx(Moon, { className: cn("text-yellow-200 fill-yellow-200", currentSize.icon) }) })] }) })] })); }