/ src / layouts / AppGlobalStyles.tsx
AppGlobalStyles.tsx
 1  import { useMediaQuery } from '@mui/material';
 2  import CssBaseline from '@mui/material/CssBaseline';
 3  import { createTheme, ThemeProvider } from '@mui/material/styles';
 4  import { deepmerge } from '@mui/utils';
 5  import React, { ReactNode, useEffect, useMemo, useState } from 'react';
 6  
 7  import { getDesignTokens, getThemedComponents } from '../utils/theme';
 8  
 9  export const ColorModeContext = React.createContext({
10    // eslint-disable-next-line @typescript-eslint/no-empty-function
11    toggleColorMode: () => {},
12  });
13  
14  type Mode = 'light' | 'dark';
15  
16  /**
17   * Main Layout component which wrapps around the whole app
18   * @param param0
19   * @returns
20   */
21  export function AppGlobalStyles({ children }: { children: ReactNode }) {
22    const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
23    const [mode, setMode] = useState<Mode>(prefersDarkMode ? 'dark' : 'light');
24    const colorMode = useMemo(
25      () => ({
26        toggleColorMode: () => {
27          setMode((prevMode) => {
28            const newMode = prevMode === 'light' ? 'dark' : 'light';
29            localStorage.setItem('colorMode', newMode);
30            return newMode;
31          });
32        },
33      }),
34      []
35    );
36  
37    useEffect(() => {
38      const initialMode = localStorage?.getItem('colorMode') as Mode;
39      if (initialMode) {
40        setMode(initialMode);
41      } else if (prefersDarkMode) {
42        setMode('dark');
43      }
44    }, []);
45  
46    const theme = useMemo(() => {
47      const themeCreate = createTheme(getDesignTokens(mode));
48      return deepmerge(themeCreate, getThemedComponents(themeCreate));
49    }, [mode]);
50  
51    return (
52      <ColorModeContext.Provider value={colorMode}>
53        <ThemeProvider theme={theme}>
54          {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}
55          <CssBaseline />
56  
57          {children}
58        </ThemeProvider>
59      </ColorModeContext.Provider>
60    );
61  }