Themer.tsx

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