11'use client'
22
3- import { useEffect , useState } from 'react'
3+ import { Fragment , useEffect , useState } from 'react'
44import { useTheme } from 'next-themes'
5+ import { Menu , RadioGroup , Transition } from '@headlessui/react'
6+
7+ const Sun = ( ) => (
8+ < svg
9+ xmlns = "http://www.w3.org/2000/svg"
10+ viewBox = "0 0 20 20"
11+ fill = "currentColor"
12+ className = "h-6 w-6 text-gray-900 dark:text-gray-100"
13+ >
14+ < path
15+ fillRule = "evenodd"
16+ d = "M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"
17+ clipRule = "evenodd"
18+ />
19+ </ svg >
20+ )
21+ const Moon = ( ) => (
22+ < svg
23+ xmlns = "http://www.w3.org/2000/svg"
24+ viewBox = "0 0 20 20"
25+ fill = "currentColor"
26+ className = "h-6 w-6 text-gray-900 dark:text-gray-100"
27+ >
28+ < path d = "M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" />
29+ </ svg >
30+ )
31+ const Monitor = ( ) => (
32+ < svg
33+ xmlns = "http://www.w3.org/2000/svg"
34+ viewBox = "0 0 20 20"
35+ fill = "none"
36+ stroke = "currentColor"
37+ stroke-width = "2"
38+ stroke-linecap = "round"
39+ stroke-linejoin = "round"
40+ className = "h-6 w-6 text-gray-900 dark:text-gray-100"
41+ >
42+ < rect x = "3" y = "3" width = "14" height = "10" rx = "2" ry = "2" > </ rect >
43+ < line x1 = "7" y1 = "17" x2 = "13" y2 = "17" > </ line >
44+ < line x1 = "10" y1 = "13" x2 = "10" y2 = "17" > </ line >
45+ </ svg >
46+ )
547
648const ThemeSwitch = ( ) => {
749 const [ mounted , setMounted ] = useState ( false )
@@ -11,29 +53,59 @@ const ThemeSwitch = () => {
1153 useEffect ( ( ) => setMounted ( true ) , [ ] )
1254
1355 return (
14- < button
15- aria-label = "Toggle Dark Mode"
16- onClick = { ( ) => setTheme ( theme === 'dark' || resolvedTheme === 'dark' ? 'light' : 'dark' ) }
17- >
18- < svg
19- xmlns = "http://www.w3.org/2000/svg"
20- viewBox = "0 0 20 20"
21- fill = "currentColor"
22- className = "h-6 w-6 text-gray-900 dark:text-gray-100"
23- >
24- { mounted ? (
25- theme === 'dark' || resolvedTheme === 'dark' ? (
26- < path
27- fillRule = "evenodd"
28- d = "M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"
29- clipRule = "evenodd"
30- />
31- ) : (
32- < path d = "M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" />
33- )
34- ) : null }
35- </ svg >
36- </ button >
56+ < div className = "mr-5" >
57+ < Menu as = "div" className = "relative inline-block text-left" >
58+ < div >
59+ < Menu . Button > { resolvedTheme === 'dark' ? < Moon /> : < Sun /> } </ Menu . Button >
60+ </ div >
61+ < Transition
62+ as = { Fragment }
63+ enter = "transition ease-out duration-100"
64+ enterFrom = "transform opacity-0 scale-95"
65+ enterTo = "transform opacity-100 scale-100"
66+ leave = "transition ease-in duration-75"
67+ leaveFrom = "transform opacity-100 scale-100"
68+ leaveTo = "transform opacity-0 scale-95"
69+ >
70+ < Menu . Items className = "absolute right-0 mt-2 w-32 origin-top-right divide-y divide-gray-100 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none dark:bg-gray-800" >
71+ < RadioGroup value = { theme } onChange = { setTheme } >
72+ < div className = "p-1" >
73+ < RadioGroup . Option value = "light" >
74+ < Menu . Item >
75+ < button className = "group flex w-full items-center rounded-md px-2 py-2 text-sm" >
76+ < div className = "mr-2" >
77+ < Sun />
78+ </ div >
79+ Light
80+ </ button >
81+ </ Menu . Item >
82+ </ RadioGroup . Option >
83+ < RadioGroup . Option value = "dark" >
84+ < Menu . Item >
85+ < button className = "group flex w-full items-center rounded-md px-2 py-2 text-sm" >
86+ < div className = "mr-2" >
87+ < Moon />
88+ </ div >
89+ Dark
90+ </ button >
91+ </ Menu . Item >
92+ </ RadioGroup . Option >
93+ < RadioGroup . Option value = "system" >
94+ < Menu . Item >
95+ < button className = "group flex w-full items-center rounded-md px-2 py-2 text-sm" >
96+ < div className = "mr-2" >
97+ < Monitor />
98+ </ div >
99+ System
100+ </ button >
101+ </ Menu . Item >
102+ </ RadioGroup . Option >
103+ </ div >
104+ </ RadioGroup >
105+ </ Menu . Items >
106+ </ Transition >
107+ </ Menu >
108+ </ div >
37109 )
38110}
39111
0 commit comments