MUI v5 でページの骨格デザインを作成する (Layoutコンポーネント)
投稿日: 2024/03/13
更新日: 2024/06/26
はじめに
この記事ではエンジニアとしてMUIを使ってきた中で溜まってきた知見を共有することにあります。MUIのドキュメントに書いてあることは省略することが多いですので、そちらも目を通してください。
コンポーネントの便利な使い方や実装例を紹介していきます。
layoutのコンポーネント紹介
Layoutに関するコンポーネントを軽く紹介します。
Box
Boxコンポーネントはデフォルトで<div>
としてレンダリングされます。ではなぜ<div>
ではなく<Box>
を使うのかというと、他のMUIコンポーネントと同じようなpropsを使えるからです。
公式ドキュメントにあるサンプルコードを見てみるとよくわかると思います。
import * as React from 'react'; import Box from '@mui/material/Box'; export default function BoxSystemProps() { return ( <Box height={200} width={200} my={4} display="flex" alignItems="center" gap={4} p={2} sx={{ border: '2px solid grey' }} > This Box uses MUI System props for quick customization. </Box> ); }
component引数を使って<div>
以外がレンダリングされるように指定できます。
Container
Containerコンポーネントは子要素の横幅を制限して中央に配置します。基本的にページの外側に配置して、メインコンテンツやサイドバーを囲みます。1ページに複数回使うことはほぼないと思います。
GridとStack
Gridコンポーネントは横幅を12で分割し、各要素を指定の割合で表示できます。
Stackコンポーネントは単に横や縦に要素を並べるときに使います。
使い分けとして、例えばメインコンテンツとサイドバーの配置などはGridをよく使います。画面幅が小さくなったときにメインコンテンツも再度バーも同じ割合で小さくなります。
固定サイズのボタンやアイコンを横に並べたりするときはStackが便利です。
2カラムの例
要件
よくある2カラムのレイアウトを作ってみます。
header, main content, side bar, footerの要素があり、side barの下側の要素はスクロールに追従するとします。
動作例
スクロール前(PC)
スクロール後(PC)
また、画面横幅が小さいときはサイドバーをメインコンテンツの下に配置します。
スクロール前(Mobile)
スクロール後(Mobile)
ソースコード
src/pages/layout/TwoColumnPage/TwoColumnPage.tsx
import { Box, Button, Container, Grid, Stack } from "@mui/material" import { FC } from "react" export const TwoColumnPage: FC = () => { return ( <Container maxWidth="md"> <Grid container alignItems="flex-start" spacing={4} sx={{ display: "flex", alignItems: "stretch" }} > {/* header */} <Grid item xs={12}> <Box width="100%" height="100px" sx={{ backgroundColor: "darkblue", fontSize: "2.5rem" }} > header </Box> </Grid> {/* main content */} <Grid item xs={12} md={8}> <Box width="100%" height="800px" sx={{ backgroundColor: "darkblue" }}> <Box sx={{ fontSize: "2.5rem" }}>main content</Box> <Stack direction={"row"} spacing={1} useFlexGap flexWrap="wrap"> {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((i) => ( <Button variant="contained">Button{i}</Button> ))} </Stack> </Box> </Grid> {/* side bar */} <Grid item xs={12} md={4}> <Box width="100%" height="200px" sx={{ backgroundColor: "darkblue", fontSize: "2.5rem" }} > {"side bar(upper)"} </Box> <Box sx={{ position: "sticky", top: 40, mt: 4, backgroundColor: "darkblue", fontSize: "2.5rem", }} > {"side bar(bottom)"} </Box> </Grid> {/* footer */} <Grid item xs={12}> <Box width="100%" height="100px" sx={{ backgroundColor: "darkblue", fontSize: "2.5rem" }} > footer </Box> </Grid> </Grid> </Container> ) }
Noh を作ってるエンジニア。