Noh | エンジニア向け情報共有コミュニティ
Signup / Login

MUI v5 でページの骨格デザインを作成する (Layoutコンポーネント)

javascript
typescript
mui
react

投稿日: 2024/03/13

更新日: 2024/06/26

MUI (旧 material-ui )の実用小ネタ集

はじめに

この記事ではエンジニアとしてMUIを使ってきた中で溜まってきた知見を共有することにあります。MUIのドキュメントに書いてあることは省略することが多いですので、そちらも目を通してください。

コンポーネントの便利な使い方や実装例を紹介していきます。

https://mui.com/material-ui/getting-started/

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> ) }
yosi

Noh を作ってるエンジニア。

目次