feat: support auto theme change according to system

This commit is contained in:
Alexey Kunitsky 2023-11-11 20:44:44 +01:00
parent ba761098be
commit 8130de23ff
2 changed files with 26 additions and 4 deletions

View File

@ -13,7 +13,7 @@ const Theme = () => {
theme: storedTheme
},
validationSchema: Yup.object({
theme: Yup.string().oneOf(['light', 'dark']).required('theme is required')
theme: Yup.string().oneOf(['light', 'dark', 'system']).required('theme is required')
}),
onSubmit: (values) => {
setStoredTheme(values.theme);
@ -55,6 +55,22 @@ const Theme = () => {
<label htmlFor="dark-theme" className="ml-1 cursor-pointer select-none">
Dark
</label>
<input
id="system-theme"
className="ml-4 cursor-pointer"
type="radio"
name="theme"
onChange={(e) => {
formik.handleChange(e);
formik.handleSubmit();
}}
value="system"
checked={formik.values.theme === 'system'}
/>
<label htmlFor="system-theme" className="ml-1 cursor-pointer select-none">
System
</label>
</div>
</div>
</StyledWrapper>

View File

@ -1,15 +1,21 @@
import themes from 'themes/index';
import useLocalStorage from 'hooks/useLocalStorage/index';
import { createContext, useContext } from 'react';
import { createContext, useContext, useState } from 'react';
import { ThemeProvider as SCThemeProvider } from 'styled-components';
export const ThemeContext = createContext();
export const ThemeProvider = (props) => {
const isBrowserThemeLight = window.matchMedia('(prefers-color-scheme: light)').matches;
const [storedTheme, setStoredTheme] = useLocalStorage('bruno.theme', isBrowserThemeLight ? 'light' : 'dark');
const [displayedTheme, setDisplayedTheme] = useState(isBrowserThemeLight ? 'light' : 'dark');
const [storedTheme, setStoredTheme] = useLocalStorage('bruno.theme', 'system');
const theme = themes[storedTheme];
window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', (e) => {
if (storedTheme !== 'system') return;
setDisplayedTheme(e.matches ? 'light' : 'dark');
});
const theme = storedTheme === 'system' ? themes[displayedTheme] : themes[storedTheme];
const themeOptions = Object.keys(themes);
const value = {
theme,