Themer.tsx

 1import React, { createContext, useCallback, useContext, useState } from 'react';
 2
 3import { ThemeProvider } from '@material-ui/core';
 4import IconButton from '@material-ui/core/IconButton/IconButton';
 5import Tooltip from '@material-ui/core/Tooltip/Tooltip';
 6import { createMuiTheme, ThemeOptions } from '@material-ui/core/styles';
 7import { NightsStayRounded, WbSunnyRounded } from '@material-ui/icons';
 8
 9const defaultTheme: ThemeOptions = {
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
43  const toggleMode = useCallback(() => {
44    const newMode = theme.palette?.type === 'dark' ? 'light' : 'dark';
45    const adjustedTheme: ThemeOptions = {
46      ...theme,
47      palette: {
48        ...theme.palette,
49        type: newMode,
50      },
51    };
52    setTheme(adjustedTheme);
53  }, [theme, setTheme]);
54
55  const newMode = theme.palette?.type === 'dark' ? 'light' : 'dark';
56
57  return (
58    <ThemeContext.Provider value={{ toggleMode: toggleMode, mode: newMode }}>
59      <ThemeProvider theme={createMuiTheme(theme)}> {children} </ThemeProvider>
60    </ThemeContext.Provider>
61  );
62};
63
64export { Themer as default, LightSwitch };