1import { NightsStayRounded, WbSunnyRounded } from '@mui/icons-material';
2import { ThemeProvider, StyledEngineProvider } from '@mui/material';
3import IconButton from '@mui/material/IconButton';
4import Tooltip from '@mui/material/Tooltip';
5import { Theme } from '@mui/material/styles';
6import * as React from 'react';
7import { createContext, useContext, useState } from 'react';
8
9declare module '@mui/styles/defaultTheme' {
10 // eslint-disable-next-line @typescript-eslint/no-empty-interface
11 interface DefaultTheme extends Theme {}
12}
13
14const ThemeContext = createContext({
15 toggleMode: () => {},
16 mode: '',
17});
18
19type LightSwitchProps = {
20 className?: string;
21};
22const LightSwitch = ({ className }: LightSwitchProps) => {
23 const { mode, toggleMode } = useContext(ThemeContext);
24 const nextMode = mode === 'light' ? 'dark' : 'light';
25 const description = `Switch to ${nextMode} theme`;
26
27 return (
28 <Tooltip title={description}>
29 <IconButton
30 onClick={toggleMode}
31 aria-label={description}
32 className={className}
33 size="large"
34 >
35 {mode === 'light' ? <WbSunnyRounded /> : <NightsStayRounded />}
36 </IconButton>
37 </Tooltip>
38 );
39};
40
41type Props = {
42 children: React.ReactNode;
43 lightTheme: Theme;
44 darkTheme: Theme;
45};
46const Themer = ({ children, lightTheme, darkTheme }: Props) => {
47 const savedMode = localStorage.getItem('themeMode');
48 const preferedMode = savedMode != null ? savedMode : 'light';
49 const [mode, setMode] = useState(preferedMode);
50
51 const toggleMode = () => {
52 const preferedMode = mode === 'light' ? 'dark' : 'light';
53 localStorage.setItem('themeMode', preferedMode);
54 setMode(preferedMode);
55 };
56
57 const preferedTheme = mode === 'dark' ? darkTheme : lightTheme;
58
59 return (
60 <ThemeContext.Provider value={{ toggleMode: toggleMode, mode: mode }}>
61 <StyledEngineProvider injectFirst>
62 <ThemeProvider theme={preferedTheme}>{children}</ThemeProvider>
63 </StyledEngineProvider>
64 </ThemeContext.Provider>
65 );
66};
67
68export { Themer as default, LightSwitch };