From 2076042eac66aaab3a15608549138d9a91bd9b5e Mon Sep 17 00:00:00 2001 From: kronpatel Date: Fri, 24 Oct 2025 13:49:51 +0530 Subject: [PATCH] feat(theme): add smooth transitions and prevent flash in theme toggle --- components/shared/theme-toggle.tsx | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/components/shared/theme-toggle.tsx b/components/shared/theme-toggle.tsx index b52edfb..861d86d 100644 --- a/components/shared/theme-toggle.tsx +++ b/components/shared/theme-toggle.tsx @@ -8,14 +8,28 @@ import { useEffect, useState } from "react"; export default function ModeToggle() { const { theme, setTheme } = useTheme(); const [mounted, setMounted] = useState(false); + const [isChanging, setIsChanging] = useState(false); // Wait for component to mount before rendering icons useEffect(() => { setMounted(true); }, []); + // Add smooth transition when theme changes + useEffect(() => { + if (mounted) { + document.documentElement.style.transition = "background-color 0.3s ease-in-out, color 0.3s ease-in-out"; + return () => { + document.documentElement.style.transition = ""; + }; + } + }, [mounted]); + const toggleTheme = () => { + setIsChanging(true); setTheme(theme === "light" ? "dark" : "light"); + // Reset changing state after transition + setTimeout(() => setIsChanging(false), 300); }; // Prevent rendering on server to avoid hydration mismatch @@ -26,10 +40,19 @@ export default function ModeToggle() { onClick={toggleTheme} whileTap={{ rotate: 180 }} transition={{ duration: 0.3 }} - className="px-2 rounded-full transition flex items-center justify-center" + className={`px-2 rounded-full transition-all duration-300 flex items-center justify-center ${ + isChanging ? 'opacity-50' : 'opacity-100' + }`} aria-label="Toggle theme" + disabled={isChanging} > - {theme === "light" ? : } + + {theme === "light" ? : } + ); }