Skip to content

Commit d018b0e

Browse files
committed
feat(theme-switcher): Theme Switcher
Implemented mui theme switcher component
1 parent d6bcdb0 commit d018b0e

File tree

4 files changed

+73
-34
lines changed

4 files changed

+73
-34
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,5 @@ See the section about [deployment](https://facebook.github.io/create-react-app/d
5555
* [React Hook Form vs. Formik: A technical and performance comparison](https://blog.logrocket.com/react-hook-form-vs-formik-comparison/)
5656
* [React Hook Form - form builder](https://react-hook-form.com/form-builder)
5757
* [React Hook Form - typescript Support](https://react-hook-form.com/ts)
58-
* [Redux Style Guide](https://redux.js.org/style-guide/style-guide#write-action-types-as-domaineventname)
58+
* [Redux Style Guide](https://redux.js.org/style-guide/style-guide#write-action-types-as-domaineventname)
59+
* [MUI - theme switcher](https://mui.com/customization/dark-mode/)

src/App.tsx

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,15 @@ import {Provider} from "react-redux";
33

44
import './App.css';
55
import {history, store} from "./store/store";
6-
import {createTheme} from '@mui/material/styles';
76
import AppRoutes from "./routes";
8-
import {ThemeProvider} from "@emotion/react";
9-
import {CssBaseline} from "@mui/material";
107
import {HistoryRouter as Router} from "redux-first-history/rr6";
118

129

13-
const theme = createTheme();
14-
1510
const App = () => (
1611
<>
1712
<Provider store={store}>
1813
<Router history={history}>
19-
<ThemeProvider theme={theme}>
20-
<CssBaseline/>
21-
<AppRoutes/>
22-
</ThemeProvider>
14+
<AppRoutes/>
2315
</Router>
2416
</Provider>
2517
</>

src/components/Layout/Header.tsx renamed to src/components/Headers/Header.tsx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11
import React from "react";
22

3-
import {Button, ButtonGroup, Link} from "@mui/material";
3+
import {Button, ButtonGroup, IconButton, Link} from "@mui/material";
44
import AppBar from '@mui/material/AppBar';
55
import Toolbar from '@mui/material/Toolbar';
66
import Typography from '@mui/material/Typography';
77
import {NavLink as RouterLink} from 'react-router-dom';
88
import {useTranslation} from "react-i18next";
9+
import Brightness7Icon from "@mui/icons-material/Brightness7";
10+
import Brightness4Icon from "@mui/icons-material/Brightness4";
11+
import {Theme} from "@mui/material/styles/createTheme";
912

10-
const Header = () => {
11-
const {t, i18n} = useTranslation();
1213

13-
// TODO: move state to redux
14-
const onChangeLanguage = (lang: string) => {
15-
i18n.changeLanguage(lang);
16-
};
14+
type HeaderProps = {
15+
currentThemeMode: string
16+
onChangeThemeClick: () => void
17+
onChangeLanguage: (lang: string) => void
18+
}
19+
20+
const Header = (props: HeaderProps) => {
21+
const {t} = useTranslation();
22+
23+
const {currentThemeMode, onChangeThemeClick, onChangeLanguage} = props;
1724

1825
return (
1926
<>
@@ -50,6 +57,9 @@ const Header = () => {
5057
<Button onClick={() => onChangeLanguage('en')}>🇺🇸</Button>
5158
<Button onClick={() => onChangeLanguage('pl')}>🇵🇱</Button>
5259
</ButtonGroup>
60+
<IconButton sx={{ ml: 1 }} onClick={onChangeThemeClick} color="inherit">
61+
{currentThemeMode === 'dark' ? <Brightness7Icon /> : <Brightness4Icon />}
62+
</IconButton>
5363
</nav>
5464
</Toolbar>
5565
</AppBar>

src/components/Layout/index.tsx

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,59 @@
11
import React from "react";
22
import {Outlet} from 'react-router-dom';
3-
import Header from "./Header";
3+
import Header from "../Headers/Header";
44
import Box from "@mui/material/Box";
5+
import {CssBaseline, ThemeProvider} from "@mui/material";
6+
import {createTheme} from "@mui/material/styles";
7+
import {useTranslation} from "react-i18next";
58

6-
const Layout = () => (
7-
<>
8-
<Header/>
9-
<main>
10-
<Box
11-
sx={{
12-
bgcolor: 'background.paper',
13-
pt: 3,
14-
pb: 3,
15-
}}
16-
>
17-
<Outlet/>
18-
</Box>
19-
</main>
20-
</>
21-
);
9+
10+
const Layout = () => {
11+
const [mode, setMode] = React.useState<'light' | 'dark'>('light');
12+
13+
const {i18n} = useTranslation();
14+
15+
// TODO: move state to redux
16+
const onChangeLanguage = (lang: string) => {
17+
i18n.changeLanguage(lang);
18+
};
19+
20+
const colorMode = React.useMemo(
21+
() => ({
22+
toggleColorMode: () => {
23+
setMode((prevMode) => (prevMode === 'light' ? 'dark' : 'light'));
24+
},
25+
}),
26+
[],
27+
);
28+
29+
const theme = React.useMemo(
30+
() => {
31+
return createTheme({
32+
palette: {
33+
mode,
34+
},
35+
});
36+
},
37+
[mode],
38+
);
39+
40+
return (
41+
<>
42+
<ThemeProvider theme={theme}>
43+
<CssBaseline/>
44+
<Header currentThemeMode={theme.palette.mode} onChangeThemeClick={colorMode.toggleColorMode} onChangeLanguage={onChangeLanguage}/>
45+
<main>
46+
<Box sx={{
47+
bgcolor: 'background.paper',
48+
pt: 3,
49+
pb: 3,
50+
}}>
51+
<Outlet/>
52+
</Box>
53+
</main>
54+
</ThemeProvider>
55+
</>
56+
);
57+
};
2258

2359
export default Layout;

0 commit comments

Comments
 (0)