blob: 64fc385417fbe2a1867ce132e22f1a6edfed9321 [file] [log] [blame]
idillon3470d072022-11-22 15:22:34 -05001/*
2 * Copyright (C) 2022 Savoir-faire Linux Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License as
6 * published by the Free Software Foundation; either version 3 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Affero General Public License for more details.
13 *
14 * You should have received a copy of the GNU Affero General Public
15 * License along with this program. If not, see
16 * <https://www.gnu.org/licenses/>.
17 */
18import { PaletteMode } from '@mui/material';
19import { ThemeProvider } from '@mui/material/styles';
Ziwei Wangea4c1392023-01-05 14:50:45 -050020import useMediaQuery from '@mui/material/useMediaQuery';
idillon3470d072022-11-22 15:22:34 -050021import { createContext, useCallback, useEffect, useMemo, useState } from 'react';
22
23import { buildDefaultTheme } from '../themes/Default';
24import { WithChildren } from '../utils/utils';
25
26interface ICustomThemeContext {
27 mode: PaletteMode;
28 toggleMode: () => void;
29}
30
31export const CustomThemeContext = createContext<ICustomThemeContext>(undefined!);
32
33export default ({ children }: WithChildren) => {
34 const [mode, setMode] = useState<PaletteMode>('light');
Ziwei Wangea4c1392023-01-05 14:50:45 -050035 const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
idillon3470d072022-11-22 15:22:34 -050036
37 useEffect(() => {
Ziwei Wangcd687a42023-01-04 16:40:53 -050038 const themeModeInStorage = localStorage.getItem('themeMode');
39 let themeModeValue = 'light';
40 // localStorage returns null if no value is found for the given key
41 if (typeof themeModeInStorage === 'string') {
42 themeModeValue = JSON.parse(themeModeInStorage);
Ziwei Wangea4c1392023-01-05 14:50:45 -050043 setMode(themeModeValue === 'dark' ? 'dark' : 'light');
44 } else {
45 //when there is no theme mode stored in the localStorage, use the mode in OS preference
46 setMode(prefersDarkMode ? 'dark' : 'light');
Ziwei Wangcd687a42023-01-04 16:40:53 -050047 }
Ziwei Wangea4c1392023-01-05 14:50:45 -050048 }, [prefersDarkMode]);
idillon3470d072022-11-22 15:22:34 -050049
Ziwei Wangcd687a42023-01-04 16:40:53 -050050 const toggleMode = useCallback(() => {
51 setMode((mode) => {
52 const newMode = mode === 'light' ? 'dark' : 'light';
53 localStorage.setItem('themeMode', JSON.stringify(newMode));
54 return newMode;
55 });
56 }, [setMode]);
idillon3470d072022-11-22 15:22:34 -050057
58 const theme = useMemo(() => buildDefaultTheme(mode), [mode]);
59
simon5c677962022-12-02 16:51:54 -050060 const value = useMemo(
61 () => ({
62 mode,
63 toggleMode,
64 }),
65 [mode, toggleMode]
66 );
67
idillon3470d072022-11-22 15:22:34 -050068 return (
simon5c677962022-12-02 16:51:54 -050069 <CustomThemeContext.Provider value={value}>
idillon3470d072022-11-22 15:22:34 -050070 <ThemeProvider theme={theme}>{children}</ThemeProvider>
71 </CustomThemeContext.Provider>
72 );
73};