11import { useState , useEffect } from 'react' ;
2+ import { Moon , Sun } from 'lucide-react' ;
23
34const DarkModeToggle = ( ) => {
45 const [ isDarkMode , setIsDarkMode ] = useState ( false ) ;
6+ const [ isHovered , setIsHovered ] = useState ( false ) ;
57
68 useEffect ( ( ) => {
79 const theme = localStorage . getItem ( 'theme' ) ;
@@ -25,12 +27,121 @@ const DarkModeToggle = () => {
2527 setIsDarkMode ( ! isDarkMode ) ;
2628 } ;
2729
30+ const trackWidth = 72 ;
31+ const thumbWidth = 28 ;
32+ const padding = 3 ;
33+
34+ const translateX = isDarkMode ? trackWidth - thumbWidth - padding : padding ;
35+
2836 return (
2937 < button
3038 onClick = { toggleDarkMode }
31- className = "p-2 rounded-full bg-gray-200 dark:bg-gray-800 text-gray-800 dark:text-gray-200"
39+ onMouseEnter = { ( ) => setIsHovered ( true ) }
40+ onMouseLeave = { ( ) => setIsHovered ( false ) }
41+ className = "group relative inline-flex h-9 w-18 items-center rounded-full transition-all duration-500 focus:outline-none focus:ring-2 focus:ring-offset-1"
42+ style = { {
43+ backgroundColor : isDarkMode ? '#1e293b' : '#bae6fd' ,
44+ boxShadow : isDarkMode
45+ ? '0 6px 16px rgba(30, 41, 59, 0.4), inset 0 1px 2px rgba(255, 255, 255, 0.05)'
46+ : '0 6px 16px rgba(186, 230, 253, 0.3), inset 0 1px 2px rgba(255, 255, 255, 0.1)' ,
47+
48+ transform : isHovered ? 'scale(1.05)' : 'scale(1)' ,
49+ transition : 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)' ,
50+ } }
51+ aria-label = { isDarkMode ? 'Switch to light mode' : 'Switch to dark mode' }
52+ role = "switch"
53+ aria-checked = { isDarkMode }
3254 >
33- { isDarkMode ? '☀️' : '🌙' }
55+ < div
56+ className = "absolute inset-0 rounded-full overflow-hidden"
57+ style = { {
58+ background : isDarkMode
59+ ? 'linear-gradient(135deg, rgba(148, 163, 184, 0.1) 0%, transparent 50%, rgba(71, 85, 105, 0.1) 100%)'
60+ : 'linear-gradient(135deg, rgba(255, 255, 255, 0.3) 0%, transparent 50%, rgba(56, 189, 248, 0.2) 100%)' ,
61+ opacity : isHovered ? 1 : 0.6 ,
62+ transition : 'opacity 0.3s ease' ,
63+ } }
64+ />
65+
66+ < span
67+ className = "absolute rounded-full blur-md transition-all duration-500"
68+ style = { {
69+ width : `${ thumbWidth } px` ,
70+ height : `${ thumbWidth } px` ,
71+ backgroundColor : isDarkMode ? '#818cf8' : '#fbbf24' ,
72+ opacity : isHovered ? 0.5 : 0.3 ,
73+ transform : `translateX(${ translateX } px)` ,
74+ } }
75+ />
76+
77+ < span
78+ className = "relative z-10 inline-flex h-7 w-7 items-center justify-center rounded-full bg-white overflow-hidden"
79+ style = { {
80+ transform : `translateX(${ translateX } px) ${ isHovered ? 'scale(1.1)' : 'scale(1)' } ` ,
81+ boxShadow : isDarkMode
82+ ? '0 3px 12px rgba(129, 140, 248, 0.5), 0 1px 4px rgba(0, 0, 0, 0.2), inset 0 1px 1px rgba(255, 255, 255, 0.7)'
83+ : '0 3px 12px rgba(251, 191, 36, 0.5), 0 1px 4px rgba(0, 0, 0, 0.1), inset 0 1px 1px rgba(255, 255, 255, 0.8)' ,
84+ transition : 'all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1)' ,
85+ } }
86+ >
87+ < div
88+ className = "absolute inset-0"
89+ style = { {
90+ background : isDarkMode
91+ ? 'radial-gradient(circle, rgba(129, 140, 248, 0.3) 0%, transparent 70%)'
92+ : 'radial-gradient(circle, rgba(251, 191, 36, 0.3) 0%, transparent 70%)' ,
93+ } }
94+ />
95+
96+ < Sun
97+ className = "absolute transition-all duration-500"
98+ size = { 16 }
99+ style = { {
100+ color : '#f59e0b' ,
101+ opacity : isDarkMode ? 0 : 1 ,
102+ transform : isDarkMode
103+ ? 'rotate(360deg) scale(0.3)'
104+ : `rotate(0deg) scale(1) ${ isHovered ? 'rotate(30deg)' : '' } ` ,
105+ filter : isDarkMode
106+ ? 'blur(2px)'
107+ : 'blur(0px) drop-shadow(0 0 6px rgba(245, 158, 11, 0.5))' ,
108+ transition : 'all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1)' ,
109+ } }
110+ />
111+
112+ < Moon
113+ className = "absolute transition-all duration-500"
114+ size = { 16 }
115+ style = { {
116+ color : '#818cf8' ,
117+ opacity : isDarkMode ? 1 : 0 ,
118+ transform : isDarkMode
119+ ? 'rotate(0deg) scale(1)'
120+ : 'rotate(-360deg) scale(0.3)' ,
121+ filter : isDarkMode
122+ ? 'drop-shadow(0 0 6px rgba(129, 140, 248, 0.5))'
123+ : 'blur(2px)' ,
124+ transition : 'all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1)' ,
125+ } }
126+ />
127+ </ span >
128+
129+ < Sun
130+ className = "absolute left-2 top-1/2 -translate-y-1/2 transition-all duration-500"
131+ size = { 12 }
132+ style = { {
133+ color : 'rgba(255, 255, 255, 0.9)' ,
134+ opacity : isDarkMode ? 0.2 : 0.7 ,
135+ } }
136+ />
137+ < Moon
138+ className = "absolute right-2 top-1/2 -translate-y-1/2 transition-all duration-500"
139+ size = { 12 }
140+ style = { {
141+ color : 'rgba(255, 255, 255, 0.9)' ,
142+ opacity : isDarkMode ? 0.7 : 0.2 ,
143+ } }
144+ />
34145 </ button >
35146 ) ;
36147} ;
0 commit comments