Themer.tsx

 1import React, { createContext, useContext, useState } from 'react';
 2
 3import { PaletteType, ThemeProvider, useMediaQuery } from '@material-ui/core';
 4import IconButton from '@material-ui/core/IconButton/IconButton';
 5import Tooltip from '@material-ui/core/Tooltip/Tooltip';
 6import { createMuiTheme } from '@material-ui/core/styles';
 7import { NightsStayRounded, WbSunnyRounded } from '@material-ui/icons';
 8
 9const defaultTheme = {
10  palette: {
11    type: 'light',
12    primary: {
13      main: '#263238',
14    },
15  },
16};
17
18const ThemeContext = createContext({
19  toggleMode: () => {},
20  mode: '',
21});
22
23const LightSwitch = () => {
24  const { mode, toggleMode } = useContext(ThemeContext);
25
26  return (
27    <Tooltip title="Toggle Dark-/Lightmode">
28      <IconButton onClick={toggleMode} aria-label="Toggle Dark-/Lightmode">
29        {mode === 'light' ? (
30          <WbSunnyRounded color="secondary" />
31        ) : (
32          <NightsStayRounded color="secondary" />
33        )}
34      </IconButton>
35    </Tooltip>
36  );
37};
38
39type Props = { children: React.ReactNode };
40const Themer = ({ children }: Props) => {
41  const [theme, setTheme] = useState(defaultTheme);
42  const preferseDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
43  const browserMode = preferseDarkMode ? 'dark' : 'light';
44  const preferedMode = localStorage.getItem('themeMode');
45  const curMode = preferedMode != null ? preferedMode : browserMode;
46
47  const adjustedTheme = {
48    ...theme,
49    palette: {
50      ...theme.palette,
51      type: (curMode === 'dark' ? 'dark' : 'light') as PaletteType,
52    },
53  };
54
55  const toggleMode = () => {
56    const preferedMode = curMode === 'dark' ? 'light' : 'dark';
57    localStorage.setItem('themeMode', preferedMode);
58    const adjustedTheme = {
59      ...theme,
60      palette: {
61        ...theme.palette,
62        type: preferedMode as PaletteType,
63      },
64    };
65    setTheme(adjustedTheme);
66  };
67
68  return (
69    <ThemeContext.Provider value={{ toggleMode: toggleMode, mode: curMode }}>
70      <ThemeProvider theme={createMuiTheme(adjustedTheme)}>
71        {children}
72      </ThemeProvider>
73    </ThemeContext.Provider>
74  );
75};
76
77export { Themer as default, LightSwitch };