|
1 | | -import { useEffect } from 'react' |
2 | 1 | import { useTranslation } from 'react-i18next' |
3 | 2 | import styled, { css } from 'styled-components' |
4 | 3 |
|
5 | | -import { |
6 | | - CheckCircleSVG, |
7 | | - LanguageSVG, |
8 | | - LeftArrowSVG, |
9 | | - MoonSVG, |
10 | | - SunSVG, |
11 | | - Typography, |
12 | | - useTheme, |
13 | | -} from '@ensdomains/thorin' |
14 | | - |
15 | | -import { useLocalStorage } from '@app/hooks/useLocalStorage' |
| 4 | +import { LeftArrowSVG, ThemeSVG, ThemeToggle, Typography } from '@ensdomains/thorin' |
16 | 5 |
|
17 | 6 | import type { HamburgerView } from './Hamburger' |
18 | 7 |
|
@@ -92,142 +81,31 @@ const InnerHeading = styled.div( |
92 | 81 | `, |
93 | 82 | ) |
94 | 83 |
|
95 | | -const LanguagesContainer = styled.div( |
96 | | - ({ theme }) => css` |
97 | | - display: flex; |
98 | | - flex-direction: column-reverse; |
99 | | - align-items: stretch; |
100 | | - justify-content: flex-start; |
101 | | - gap: ${theme.space['2']}; |
102 | | - @media (min-width: ${theme.breakpoints.sm}px) { |
103 | | - flex-direction: column; |
104 | | - padding: ${theme.space['2']}; |
105 | | - gap: 0; |
106 | | - } |
107 | | - `, |
108 | | -) |
109 | | - |
110 | | -const LanguageItem = styled.div( |
111 | | - ({ theme }) => css` |
112 | | - display: flex; |
113 | | - flex-direction: row; |
114 | | - align-items: center; |
115 | | - justify-content: space-between; |
116 | | -
|
117 | | - padding: ${theme.space['4']}; |
118 | | - border-radius: ${theme.radii.large}; |
119 | | - border: 1px solid ${theme.colors.border}; |
120 | | -
|
121 | | - transition: all 0.1s ease-in-out; |
122 | | - cursor: pointer; |
123 | | -
|
124 | | - &:hover { |
125 | | - background-color: ${theme.colors.greySurface}; |
126 | | - } |
127 | | -
|
128 | | - & > div { |
129 | | - display: flex; |
130 | | - flex-direction: row; |
131 | | - align-items: center; |
132 | | - justify-content: flex-start; |
133 | | - gap: ${theme.space['2']}; |
134 | | - } |
135 | | - @media (min-width: ${theme.breakpoints.sm}px) { |
136 | | - border: none; |
137 | | - } |
138 | | - `, |
139 | | -) |
140 | | - |
141 | | -const CheckIcon = styled.svg( |
142 | | - ({ theme }) => css` |
143 | | - width: 1rem; |
144 | | - height: 1rem; |
145 | | -
|
146 | | - display: block; |
147 | | - color: ${theme.colors.green}; |
148 | | - `, |
149 | | -) |
150 | | - |
151 | 84 | export const ThemeMenu = ({ |
152 | 85 | setCurrentView, |
153 | 86 | }: { |
154 | 87 | setCurrentView: (view: HamburgerView) => void |
155 | 88 | }) => { |
156 | | - const { setMode, mode } = useTheme() |
157 | 89 | const { t } = useTranslation() |
158 | | - const [usingSystemTheme, setUsingSystemTheme] = useLocalStorage('usingSystemTheme', false) |
159 | | - |
160 | | - useEffect(() => { |
161 | | - if (usingSystemTheme) { |
162 | | - const darkQuery = window.matchMedia('(prefers-color-scheme: dark)') |
163 | | - document.documentElement.setAttribute('data-theme', darkQuery.matches ? 'dark' : 'light') |
164 | | - const listener = (event: MediaQueryListEvent) => { |
165 | | - document.documentElement.setAttribute('data-theme', event.matches ? 'dark' : 'light') |
166 | | - } |
167 | | - darkQuery.addEventListener('change', listener) |
168 | | - return () => darkQuery.removeEventListener('change', listener) |
169 | | - } |
170 | | - }, [usingSystemTheme]) |
171 | 90 |
|
172 | 91 | return ( |
173 | 92 | <Container> |
174 | 93 | <HeadingWrapper> |
175 | 94 | <Heading onClick={() => setCurrentView('main')}> |
176 | 95 | <LeftArrowSVG width={16} height={16} /> |
177 | 96 | <InnerHeading> |
178 | | - <LanguageSVG /> |
| 97 | + <ThemeSVG height={16} width={16} /> |
179 | 98 | <Typography weight="bold">{t('navigation.theme')}</Typography> |
180 | 99 | </InnerHeading> |
181 | 100 | </Heading> |
182 | 101 | </HeadingWrapper> |
183 | | - <LanguagesContainer> |
184 | | - <LanguageItem |
185 | | - onClick={() => { |
186 | | - setMode('light') |
187 | | - |
188 | | - setUsingSystemTheme(false) |
189 | | - }} |
190 | | - > |
191 | | - <div> |
192 | | - <CheckIcon |
193 | | - as={CheckCircleSVG} |
194 | | - style={{ display: mode === 'light' && !usingSystemTheme ? 'block' : 'none' }} |
195 | | - /> |
196 | | - <Typography>{t('navigation.mode.light')}</Typography> |
197 | | - </div> |
198 | | - <SunSVG height={16} width={16} /> |
199 | | - </LanguageItem> |
200 | | - <LanguageItem |
201 | | - onClick={() => { |
202 | | - setMode('dark') |
203 | | - |
204 | | - setUsingSystemTheme(false) |
205 | | - }} |
206 | | - > |
207 | | - <div> |
208 | | - <CheckIcon |
209 | | - as={CheckCircleSVG} |
210 | | - style={{ display: mode === 'dark' && !usingSystemTheme ? 'block' : 'none' }} |
211 | | - /> |
212 | | - <Typography>{t('navigation.mode.dark')}</Typography> |
213 | | - </div> |
214 | | - <MoonSVG height={16} width={16} /> |
215 | | - </LanguageItem> |
216 | | - <LanguageItem |
217 | | - onClick={() => { |
218 | | - setUsingSystemTheme(true) |
219 | | - }} |
220 | | - > |
221 | | - <div> |
222 | | - <CheckIcon |
223 | | - style={{ display: usingSystemTheme ? 'block' : 'none' }} |
224 | | - as={CheckCircleSVG} |
225 | | - /> |
226 | | - <Typography>{t('navigation.mode.system')}</Typography> |
227 | | - </div> |
228 | | - <MoonSVG height={16} width={16} /> |
229 | | - </LanguageItem> |
230 | | - </LanguagesContainer> |
| 102 | + <ThemeToggle |
| 103 | + labels={{ |
| 104 | + light: t('navigation.mode.light'), |
| 105 | + dark: t('navigation.mode.dark'), |
| 106 | + system: t('navigation.mode.system'), |
| 107 | + }} |
| 108 | + /> |
231 | 109 | </Container> |
232 | 110 | ) |
233 | 111 | } |
0 commit comments