-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathDarkModeToggle.tsx
More file actions
65 lines (61 loc) · 2.17 KB
/
DarkModeToggle.tsx
File metadata and controls
65 lines (61 loc) · 2.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import cn from 'clsx';
import { useState, useEffect } from 'react';
import { Switch } from '@headlessui/react';
import { SunIcon, MoonIcon } from '../icons/heroicons';
export function DarkModeToggle() {
const [enabled, setEnabled] = useState(false);
useEffect(() => {
const isDarkModeEnabled = document.documentElement.classList.contains('dark');
setEnabled(isDarkModeEnabled);
}, []);
const handleChange = () => {
if (enabled) {
document.documentElement.classList.remove('dark');
localStorage.setItem('theme', 'light');
} else {
document.documentElement.classList.add('dark');
localStorage.setItem('theme', 'dark');
}
setEnabled(!enabled);
};
return (
<Switch
checked={enabled}
onChange={handleChange}
className={cn(
'relative bg-gray-200 dark:bg-gray-500 inline-flex flex-shrink-0 h-8 w-12 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500'
)}
>
<span className="sr-only">Use setting</span>
<span
className={cn(
enabled ? 'translate-x-4' : 'translate-x-0',
'pointer-events-none relative inline-block h-7 w-7 rounded-full bg-white dark:bg-gray-900 shadow transform ring-0 transition ease-in-out duration-200'
)}
>
<span
className={cn(
enabled
? 'opacity-0 ease-out duration-100'
: 'opacity-100 ease-in duration-200',
'absolute inset-0 h-full w-full flex items-center justify-center transition-opacity'
)}
aria-hidden="true"
>
<SunIcon className="text-yellow-500 w-5 h-5" aria-hidden="true" />
</span>
<span
className={cn(
enabled
? 'opacity-100 ease-in duration-200'
: 'opacity-0 ease-out duration-100',
'absolute inset-0 h-full w-full flex items-center justify-center transition-opacity'
)}
aria-hidden="true"
>
<MoonIcon className="text-orange-500 w-5 h-5" />
</span>
</span>
</Switch>
);
}