-
Notifications
You must be signed in to change notification settings - Fork 0
/
theme-panel.tsx
110 lines (107 loc) · 4 KB
/
theme-panel.tsx
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import { Menu, Transition } from '@headlessui/react';
import {
ComputerDesktopIcon,
MoonIcon,
SunIcon,
} from '@heroicons/react/24/outline';
import classNames from 'classnames';
import { Fragment, useEffect, useState } from 'react';
import {
localStorageThemeKey,
Theme,
themeResolver,
} from '../../theme-resolver';
export function ThemePanel(): JSX.Element {
const [theme, setTheme] = useState(
(localStorage.getItem(localStorageThemeKey) as Theme) || 'system'
);
useEffect(() => {
themeResolver(theme);
}, [theme]);
return (
<Menu as="div" className="relative inline-block text-left">
<div>
<Menu.Button
className="inline-flex w-full justify-center rounded-md p-2 text-sm font-medium focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 dark:text-sky-500"
data-cy="theme-open-modal-button"
>
<span className="sr-only">Theme switcher</span>
{theme === 'system' && (
<ComputerDesktopIcon className="h-4 w-4" aria-hidden="true" />
)}
{theme === 'light' && (
<SunIcon className="h-4 w-4" aria-hidden="true" />
)}
{theme === 'dark' && (
<MoonIcon className="h-4 w-4" aria-hidden="true" />
)}
</Menu.Button>
</div>
<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="absolute right-0 z-50 mt-2 w-36 origin-top-right rounded-md bg-white text-slate-500 shadow-lg ring-1 ring-slate-900/10 ring-opacity-5 focus:outline-none dark:bg-slate-800 dark:text-slate-400 dark:ring-0">
<div className="px-1 py-1">
<Menu.Item>
{({ active }) => (
<button
data-cy="system-theme-button"
className={classNames(
theme === 'system' ? 'text-blue-500 dark:text-sky-500' : '',
active ? 'bg-slate-50 dark:bg-slate-600/30' : '',
'group flex w-full items-center rounded-md px-2 py-2 text-sm'
)}
onClick={() => setTheme('system')}
>
<ComputerDesktopIcon
className="mr-2 h-4 w-4"
aria-hidden="true"
/>
System
</button>
)}
</Menu.Item>
<Menu.Item>
{({ active }) => (
<button
data-cy="light-theme-button"
className={classNames(
theme === 'light' ? 'text-blue-500 dark:text-sky-500' : '',
active ? 'bg-slate-50 dark:bg-slate-600/30' : '',
'group flex w-full items-center rounded-md px-2 py-2 text-sm'
)}
onClick={() => setTheme('light')}
>
<SunIcon className="mr-2 h-4 w-4" aria-hidden="true" />
Light
</button>
)}
</Menu.Item>
<Menu.Item>
{({ active }) => (
<button
data-cy="dark-theme-button"
className={classNames(
theme === 'dark' ? 'text-blue-500 dark:text-sky-500' : '',
active ? 'bg-slate-50 dark:bg-slate-600/30' : '',
'group flex w-full items-center rounded-md px-2 py-2 text-sm'
)}
onClick={() => setTheme('dark')}
>
<MoonIcon className="mr-2 h-4 w-4" aria-hidden="true" />
Dark
</button>
)}
</Menu.Item>
</div>
</Menu.Items>
</Transition>
</Menu>
);
}