Merge pull request #952 from amstiel/feature/system-theme

feat(#731): support theme sync with system
This commit is contained in:
Anoop M D 2023-12-18 22:34:27 +05:30 committed by GitHub
commit 9e44c4a95f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 4 deletions

View File

@ -13,7 +13,7 @@ const Theme = () => {
theme: storedTheme theme: storedTheme
}, },
validationSchema: Yup.object({ 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) => { onSubmit: (values) => {
setStoredTheme(values.theme); setStoredTheme(values.theme);
@ -55,6 +55,22 @@ const Theme = () => {
<label htmlFor="dark-theme" className="ml-1 cursor-pointer select-none"> <label htmlFor="dark-theme" className="ml-1 cursor-pointer select-none">
Dark Dark
</label> </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>
</div> </div>
</StyledWrapper> </StyledWrapper>

View File

@ -1,15 +1,23 @@
import themes from 'themes/index'; import themes from 'themes/index';
import useLocalStorage from 'hooks/useLocalStorage/index'; import useLocalStorage from 'hooks/useLocalStorage/index';
import { createContext, useContext } from 'react'; import { createContext, useContext, useEffect, useState } from 'react';
import { ThemeProvider as SCThemeProvider } from 'styled-components'; import { ThemeProvider as SCThemeProvider } from 'styled-components';
export const ThemeContext = createContext(); export const ThemeContext = createContext();
export const ThemeProvider = (props) => { export const ThemeProvider = (props) => {
const isBrowserThemeLight = window.matchMedia('(prefers-color-scheme: light)').matches; 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]; useEffect(() => {
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 themeOptions = Object.keys(themes);
const value = { const value = {
theme, theme,