Themer.tsx

 1import React, { createContext, 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 { Theme } from '@material-ui/core/styles';
 7import { NightsStayRounded, WbSunnyRounded } from '@material-ui/icons';
 8
 9const ThemeContext = createContext({
10  toggleMode: () => {},
11  mode: '',
12});
13
14const LightSwitch = () => {
15  const { mode, toggleMode } = useContext(ThemeContext);
16  const nextMode = mode === 'light' ? 'dark' : 'light';
17  const description = `Switch to ${nextMode} theme`;
18
19  return (
20    <Tooltip title={description}>
21      <IconButton onClick={toggleMode} aria-label={description}>
22        {mode === 'light' ? (
23          <WbSunnyRounded color="secondary" />
24        ) : (
25          <NightsStayRounded color="secondary" />
26        )}
27      </IconButton>
28    </Tooltip>
29  );
30};
31
32type Props = {
33  children: React.ReactNode;
34  lightTheme: Theme;
35  darkTheme: Theme;
36};
37const Themer = ({ children, lightTheme, darkTheme }: Props) => {
38  const savedMode = localStorage.getItem('themeMode');
39  const preferedMode = savedMode != null ? savedMode : 'light';
40  const [mode, setMode] = useState(preferedMode);
41
42  const toggleMode = () => {
43    const preferedMode = mode === 'light' ? 'dark' : 'light';
44    localStorage.setItem('themeMode', preferedMode);
45    setMode(preferedMode);
46  };
47
48  const preferedTheme = mode === 'dark' ? darkTheme : lightTheme;
49
50  return (
51    <ThemeContext.Provider value={{ toggleMode: toggleMode, mode: mode }}>
52      <ThemeProvider theme={preferedTheme}>{children}</ThemeProvider>
53    </ThemeContext.Provider>
54  );
55};
56
57export { Themer as default, LightSwitch };