Last active
August 15, 2024 05:32
-
-
Save sheepla/a36e15bdc39b09a73c54a89b8f3d1b16 to your computer and use it in GitHub Desktop.
React + MUIによるダークモードに切り換え可能なUIの実装
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import "./App.css"; | |
import LoginBox from "./components/LoginBox"; | |
import { | |
createTheme, | |
CssBaseline, | |
ThemeProvider, | |
useMediaQuery, | |
} from "@mui/material"; | |
import { deepPurple, indigo } from "@mui/material/colors"; | |
import MainAppBar from "./components/MainAppBar"; | |
function App() { | |
const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)"); | |
const [darkMode, setDarkMode] = React.useState<boolean>(prefersDarkMode); | |
const muiTheme = React.useMemo( | |
() => | |
createTheme({ | |
palette: { | |
mode: darkMode ? "dark" : "light", | |
primary: indigo, | |
secondary: deepPurple, | |
}, | |
}), | |
[darkMode] | |
); | |
const handleToggle = () => { | |
setDarkMode((mode) => { | |
console.debug("Next dark mode status: ", !mode); | |
return !mode; | |
}); | |
}; | |
return ( | |
<> | |
<ThemeProvider theme={muiTheme}> | |
<CssBaseline> | |
<MainAppBar darkMode={darkMode} handleToggle={handleToggle} /> | |
<LoginBox /> | |
</CssBaseline> | |
</ThemeProvider> | |
</> | |
); | |
} | |
export default App; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import { | |
AppBar, | |
Toolbar, | |
Typography, | |
Container, | |
Paper, | |
TextField, | |
Button, | |
Grid, | |
Box, | |
Link, | |
} from "@mui/material"; | |
import LoginIcon from "@mui/icons-material/Login"; | |
interface Credential { | |
userName: string; | |
password: string; | |
} | |
function LoginBox() { | |
return ( | |
<div | |
style={{ minHeight: "100vh", display: "flex", flexDirection: "column" }} | |
> | |
<Container | |
component="main" | |
maxWidth="xs" | |
sx={{ | |
flexGrow: 1, | |
display: "flex", | |
justifyContent: "center", | |
alignItems: "center", | |
}} | |
> | |
<Paper | |
elevation={10} | |
sx={{ | |
padding: 3, | |
display: "flex", | |
flexDirection: "column", | |
alignItems: "center", | |
}} | |
> | |
<Box sx={{ display: "flex", alignItems: "center", b: 2 }}> | |
<LoginIcon sx={{ mr: 1 }} /> | |
<Typography variant="h5">Login</Typography> | |
</Box> | |
<Box component="form" noValidate sx={{ mt: 1 }}> | |
<TextField | |
margin="normal" | |
required | |
fullWidth | |
id="user-name" | |
label="User Name" | |
name="text" | |
autoFocus | |
/> | |
<TextField | |
margin="normal" | |
required | |
fullWidth | |
name="password" | |
label="Password" | |
type="password" | |
id="password" | |
autoComplete="current-password" | |
/> | |
<Button | |
type="submit" | |
fullWidth | |
variant="contained" | |
sx={{ mt: 3, mb: 2 }} | |
> | |
Login | |
</Button> | |
</Box> | |
</Paper> | |
</Container> | |
</div> | |
); | |
} | |
export default LoginBox; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from "react"; | |
import { | |
AppBar, | |
Toolbar, | |
Typography, | |
Switch, | |
IconButton, | |
Box, | |
} from "@mui/material"; | |
import MenuIcon from "@mui/icons-material/Menu"; | |
import DarkModeIcon from "@mui/icons-material/DarkMode"; | |
import LightModeIcon from "@mui/icons-material/LightMode"; | |
function MainAppBar({ | |
darkMode, | |
handleToggle, | |
}: { | |
darkMode: boolean; | |
handleToggle: () => void; | |
}) { | |
return ( | |
<AppBar position="absolute"> | |
<Toolbar> | |
<IconButton | |
size="large" | |
edge="start" | |
color="inherit" | |
aria-label="menu" | |
sx={{ mr: 2 }} | |
> | |
<MenuIcon /> | |
</IconButton> | |
<Typography variant="h6" sx={{ flexGrow: 1 }}> | |
MyApp | |
</Typography> | |
<Box sx={{ display: "flex", alignItems: "center" }}> | |
{darkMode ? ( | |
<DarkModeIcon sx={{ m: 1 }} /> | |
) : ( | |
<LightModeIcon sx={{ m: 1 }} /> | |
)} | |
<Switch | |
checked={darkMode} | |
onChange={handleToggle} | |
inputProps={{ "aria-label": "toggle dark mode" }} | |
/> | |
</Box> | |
</Toolbar> | |
</AppBar> | |
); | |
} | |
export default MainAppBar; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "mui-app", | |
"version": "0.1.0", | |
"private": true, | |
"dependencies": { | |
"@emotion/react": "^11.11.4", | |
"@emotion/styled": "^11.11.5", | |
"@mui/icons-material": "^5.15.19", | |
"@mui/material": "^5.15.19", | |
"@testing-library/jest-dom": "^5.17.0", | |
"@testing-library/react": "^13.4.0", | |
"@testing-library/user-event": "^13.5.0", | |
"@types/jest": "^27.5.2", | |
"@types/node": "^16.18.97", | |
"@types/react": "^18.3.3", | |
"@types/react-dom": "^18.3.0", | |
"react": "^18.3.1", | |
"react-dom": "^18.3.1", | |
"react-hook-form": "^7.51.5", | |
"react-scripts": "5.0.1", | |
"typescript": "^4.9.5", | |
"web-vitals": "^2.1.4" | |
}, | |
"scripts": { | |
"start": "react-scripts start", | |
"build": "react-scripts build", | |
"test": "react-scripts test", | |
"eject": "react-scripts eject" | |
}, | |
"eslintConfig": { | |
"extends": [ | |
"react-app", | |
"react-app/jest" | |
] | |
}, | |
"browserslist": { | |
"production": [ | |
">0.2%", | |
"not dead", | |
"not op_mini all" | |
], | |
"development": [ | |
"last 1 chrome version", | |
"last 1 firefox version", | |
"last 1 safari version" | |
] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
結果
AppBarに付いているトグルスイッチを押すとダークモードのON/OFFを切り替えられる。
ついでにアイコンも変化するようにした。