強力なUIコンポーネントライブラリ「MUI(Material-UI)」について《コンポーネント編》

基本的なコンポーネントの使用方法

MUIは、豊富なUIコンポーネントを提供しており、それを使うことでReactアプリケーションの開発を迅速に進められます。

ここでは、MUIでよく使用される基本的なコンポーネントであるボタン、テキストフィールド、アイコン、そしてレイアウトに使用するGridやBoxの使い方について解説します。

ボタン(Button)

MUIのボタンコンポーネントは、クリックイベントをトリガーするための基本的なUI要素です。MUIのボタンは、異なるスタイルやカスタマイズが可能です。主なボタンのタイプには、テキストボタン、輪郭ボタン(アウトラインボタン)、コンテインボタン(塗りつぶしボタン)があります。

import React from 'react';
import Button from '@mui/material/Button';

function MyButton() {
  return (
    <div>
      {/* テキストボタン */}
      <Button variant="text">Text</Button>

      {/* 輪郭ボタン */}
      <Button variant="outlined">Outlined</Button>

      {/* コンテインボタン */}
      <Button variant="contained">Contained</Button>

      {/* クリックイベントを持つボタン */}
      <Button variant="contained" color="primary" onClick={() => alert('Button Clicked!')}>
        Click Me
      </Button>
    </div>
  );
}

export default MyButton;

ボタンのプロパティ

  • variant: ボタンのスタイルを指定します。text,outlined,containedの3種類があります。
  • color: primary,secondary,error,warning,info,successなどの色を指定できます。
  • onClick: ボタンがクリックされたときに発生するイベントを設定します。

テキストフィールド(TextField)

TextFieldは、ユーザーがテキストを入力できるUIコンポーネントです。通常の入力フィールドに加えて、MUIではラベルやバリデーションなどの機能もサポートしています。

import React, { useState } from 'react';
import TextField from '@mui/material/TextField';

function MyTextField() {
  const [value, setValue] = useState('');

  return (
    <div>
      <TextField
        label="名前"
        variant="outlined"
        value={value}
        onChange={(e) => setValue(e.target.value)}
      />
      <p>入力された値: {value}</p>
    </div>
  );
}

export default MyTextField;

テキストフィールドのプロパティ

  • label: フィールドに表示されるラベル。
  • variant: テキストフィールドの外観。outlined,filled,standardの3種類があります。
  • value: テキストフィールドの現在の値を管理。
  • onChange: ユーザーがテキストを入力した際に発生するイベント。

アイコン(Icon)

MUIは多くのアイコンを提供しており、アプリケーション内で簡単に使用できます。アイコンは視覚的なヒントを提供したり、インタラクションを示すために使われます。@mui/icons-materialパッケージをインストールすることで、MUIの公式アイコンセットを利用できます。

npm install @mui/icons-material

以下のコードは、アイコンをボタンと一緒に使用する例です。

import React from 'react';
import Button from '@mui/material/Button';
import DeleteIcon from '@mui/icons-material/Delete';
import SendIcon from '@mui/icons-material/Send';

function MyIconButtons() {
  return (
    <div>
      {/* アイコン付きボタン */}
      <Button variant="contained" startIcon={<DeleteIcon />}>
        Delete
      </Button>

      <Button variant="contained" endIcon={<SendIcon />}>
        Send
      </Button>
    </div>
  );
}

export default MyIconButtons;

アイコンボタンのプロパティ

  • startIcon: ボタンの左側にアイコンを配置します。
  • endIcon: ボタンの右側にアイコンを配置します。

Box

Boxは、CSSのプロパティを直接渡してスタイル調整ができる便利なコンポーネントです。簡単にマージンやパディングなどのレイアウトを指定できます。

import React from 'react';
import Box from '@mui/material/Box';

function MyBox() {
  return (
    <Box
      sx={{
        width: 300,
        height: 300,
        backgroundColor: 'primary.main',
        '&:hover': {
          backgroundColor: 'primary.dark',
        },
      }}
    />
  );
}

export default MyBox;

Boxのプロパティ

  • sx: MUIのスタイルシステムを利用してCSSを直接設定します。MUIのテーマに基づくスタイリングが可能です。

高度なコンポーネントの使用方法

MUIは、ボタンやテキストフィールドなどの基本的なコンポーネントに加え、より複雑なUI要素を提供しています。これらの高度なコンポーネントを活用することで、よりインタラクティブで機能的なアプリケーションを構築することができます。

ここでは、モーダル、ダイアログ、スナックバー、アラート、タブ、ナビゲーションドロワー、テーブルの作成とカスタマイズについて詳しく解説します。

Modalは、より汎用的なオーバーレイウィンドウを提供します。カスタマイズ可能で、特定のコンテンツやフォームを表示する際に利用します。

import React, { useState } from 'react';
import { Modal, Box, Button } from '@mui/material';

function MyModal() {
  const [open, setOpen] = useState(false);

  const handleOpen = () => setOpen(true);
  const handleClose = () => setOpen(false);

  return (
    <div>
      <Button onClick={handleOpen}>モーダルを開く</Button>
      <Modal
        open={open}
        onClose={handleClose}
        aria-labelledby="modal-title"
        aria-describedby="modal-description"
      >
        <Box sx={{ width: 400, padding: 2, margin: 'auto', backgroundColor: 'white' }}>
          <h2 id="modal-title">モーダルタイトル</h2>
          <p id="modal-description">ここにコンテンツを表示します。</p>
          <Button onClick={handleClose}>閉じる</Button>
        </Box>
      </Modal>
    </div>
  );
}

export default MyModal;

ダイアログ(Dialog)

Dialogは、Modalのより具体的な実装で、標準的なダイアログボックスとして使われます。DialogTitleやDialogActionsなどの専用コンポーネントを使って、簡単に実装できます。

import React, { useState } from 'react';
import { Dialog, DialogTitle, DialogContent, DialogActions, Button } from '@mui/material';

function MyDialog() {
  const [open, setOpen] = useState(false);

  const handleOpen = () => setOpen(true);
  const handleClose = () => setOpen(false);

  return (
    <div>
      <Button onClick={handleOpen}>ダイアログを開く</Button>
      <Dialog open={open} onClose={handleClose}>
        <DialogTitle>確認</DialogTitle>
        <DialogContent>この操作を続行しますか?</DialogContent>
        <DialogActions>
          <Button onClick={handleClose}>キャンセル</Button>
          <Button onClick={handleClose}>続行</Button>
        </DialogActions>
      </Dialog>
    </div>
  );
}

export default MyDialog;

スナックバー(Snackbar)

Snackbarは、画面の下部や上部に表示される短いメッセージです。自動的に消えるか、ユーザーが閉じることができます。

import React, { useState } from 'react';
import { Snackbar, Button } from '@mui/material';

function MySnackbar() {
  const [open, setOpen] = useState(false);

  const handleOpen = () => setOpen(true);
  const handleClose = () => setOpen(false);

  return (
    <div>
      <Button onClick={handleOpen}>スナックバーを表示</Button>
      <Snackbar
        open={open}
        message="操作が成功しました"
        autoHideDuration={4000}
        onClose={handleClose}
      />
    </div>
  );
}

export default MySnackbar;

アラート(Alert)

Alertは、成功、エラー、警告、情報などのメッセージを色分けして表示するためのコンポーネントです。

import React from 'react';
import { Alert, AlertTitle } from '@mui/material';

function MyAlert() {
  return (
    <Alert severity="success">
      <AlertTitle>成功</AlertTitle>
      操作が正常に完了しました。
    </Alert>
  );
}

export default MyAlert;

タブ(Tabs)

Tabsは、複数のコンテンツを一度に表示するのではなく、タブを切り替えることで別のコンテンツを表示するために使います。

import React, { useState } from 'react';
import { Tabs, Tab, Box } from '@mui/material';

function MyTabs() {
  const [value, setValue] = useState(0);

  const handleChange = (event, newValue) => {
    setValue(newValue);
  };

  return (
    <Box>
      <Tabs value={value} onChange={handleChange}>
        <Tab label="タブ1" />
        <Tab label="タブ2" />
        <Tab label="タブ3" />
      </Tabs>
      {value === 0 && <Box>タブ1の内容</Box>}
      {value === 1 && <Box>タブ2の内容</Box>}
      {value === 2 && <Box>タブ3の内容</Box>}
    </Box>
  );
}

export default MyTabs;

ナビゲーションドロワー(Drawer)

Drawerは、サイドバーとして機能し、ナビゲーションメニューやアクションを表示するためのコンポーネントです。開閉可能で、通常はアプリケーションのレイアウトにおいて、サイドメニューとして使用されます。

import React, { useState } from 'react';
import { Drawer, Button, List, ListItem, ListItemText } from '@mui/material';

function MyDrawer() {
  const [open, setOpen] = useState(false);

  const toggleDrawer = () => setOpen(!open);

  return (
    <div>
      <Button onClick={toggleDrawer}>メニューを開く</Button>
      <Drawer anchor="left" open={open} onClose={toggleDrawer}>
        <List>
          <ListItem button>
            <ListItemText primary="ホーム" />
          </ListItem>
          <ListItem button>
            <ListItemText primary="設定" />
          </ListItem>
        </List>
      </Drawer>
    </div>
  );
}

export default MyDrawer;

テーブル(Table)の作成とカスタマイズ

Tableは、データを表形式で表示するために使用されます。MUIのテーブルコンポーネントは、ソート、フィルタリング、ページネーションなど、さまざまな機能をサポートしており、複雑なデータ表示に最適です。

import React from 'react';
import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper } from '@mui/material';

function MyTable() {
  const rows = [
    { name: 'John Doe', age: 30, job: 'Developer' },
    { name: 'Jane Smith', age: 25, job: 'Designer' },
    { name: 'Sam Brown', age: 28, job: 'Product Manager' },
  ];

  return (
    <TableContainer component={Paper}>
      <Table>
        <TableHead>
          <TableRow>
            <TableCell>名前</TableCell>
            <TableCell>年齢</TableCell>
            <TableCell>職業</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {rows.map((row, index) => (
            <TableRow key={index}>
              <TableCell>{row.name}</TableCell>
              <TableCell>{row.age}</TableCell>
              <TableCell>{row.job}</TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </TableContainer>
  );
}

export default MyTable;

テーブルのプロパティ

  • TableHead: テーブルのヘッダー行。
  • TableBody: テーブルのデータ行。
  • TableCell: 各セルの内容。

レスポンシブデザインとレイアウト

現代のWebアプリケーションでは、さまざまなデバイスや画面サイズに対応するレスポンシブデザインが重要です。MUIでは、効率的にレスポンシブデザインを実現するために、強力なグリッドシステム、メディアクエリ、Flexboxといった機能を提供しています。

この章では、これらの機能を使って、画面のサイズに応じた柔軟なレイアウトを作成する方法を詳しく解説します。

MUIのグリッドシステムの使用

MUIのグリッドシステムは、Gridコンポーネントを使って、画面の幅に基づいたレスポンシブレイアウトを簡単に構築するためのツールです。Gridは12列のシステムに基づいており、各要素の横幅をxs,sm,md,lg,xlといったブレークポイントで指定できます。

以下の例では、Gridコンポーネントを使用して、レスポンシブなレイアウトを作成します。画面幅に応じて、表示される列の数が変わるように設定されています。

import React from 'react';
import { Grid, Paper } from '@mui/material';

function ResponsiveGrid() {
  return (
    <Grid container spacing={2}>
      <Grid item xs={12} sm={6} md={4} lg={3}>
        <Paper>1列目</Paper>
      </Grid>
      <Grid item xs={12} sm={6} md={4} lg={3}>
        <Paper>2列目</Paper>
      </Grid>
      <Grid item xs={12} sm={6} md={4} lg={3}>
        <Paper>3列目</Paper>
      </Grid>
      <Grid item xs={12} sm={6} md={4} lg={3}>
        <Paper>4列目</Paper>
      </Grid>
    </Grid>
  );
}

export default ResponsiveGrid;

このコードでは、画面が小さい場合(xs=12)、各項目は1列ずつ表示されます。画面が広がると、sm=6で2列、md=4で3列、そしてlg=3で4列になるように指定されています。これにより、デバイスの画面サイズに応じてレイアウトが動的に変わります。

グリッドプロパティ

  • container: グリッドの親要素に指定し、内部でアイテムを配置できるようにします。
  • item: グリッド内に配置する子要素に指定します。
  • spacing: アイテム間のスペースを指定します(単位はpx)。

メディアクエリとレスポンシブユーティリティ

MUIでは、スタイルを画面サイズに合わせて変更できるメディアクエリが提供されています。これにより、コンポーネントのスタイルを画面幅に基づいて動的に変更することが可能です。

useMediaQueryフックを使用して、画面のサイズに応じてスタイルやレイアウトを変更することができます。たとえば、以下の例では、画面が小さい場合にテキストを小さく、大きい場合にはテキストを大きくしています。

import React from 'react';
import { useMediaQuery, Typography } from '@mui/material';

function ResponsiveText() {
  const isSmallScreen = useMediaQuery('(max-width:600px)');

  return (
    <Typography variant={isSmallScreen ? 'body2' : 'h6'}>
      このテキストは画面サイズに応じて変更されます
    </Typography>
  );
}

export default ResponsiveText;

レスポンシブユーティリティ

MUIには、特定のブレークポイントでプロパティを適用するレスポンシブユーティリティも含まれています。これにより、コンポーネントのスタイルや挙動を簡単に制御できます。

import React from 'react';
import { Box } from '@mui/material';

function ResponsiveBox() {
  return (
    <Box
      sx={{
        width: {
          xs: 100, // 小さい画面では幅100px
          sm: 200, // 中程度の画面では幅200px
          md: 300, // 大きい画面では幅300px
        },
        bgcolor: {
          xs: 'red',  // 小さい画面では赤色
          sm: 'blue', // 中程度の画面では青色
          md: 'green', // 大きい画面では緑色
        }
      }}
    >
      レスポンシブなBox
    </Box>
  );
}

export default ResponsiveBox;

この例では、画面の幅に応じてBoxの幅や背景色が動的に変わります。sxプロパティで、xs,sm,mdなどのブレークポイントを設定することで、レスポンシブなスタイルを簡単に実装できます。

Flexboxを使ったレイアウトの調整

Flexboxは、柔軟なレイアウトを作成するためのCSSレイアウトモデルです。MUIのBoxコンポーネントは、display: flexのプロパティを持ち、Flexboxベースのレイアウトを簡単に適用できます。

以下の例では、Boxコンポーネントを使って、Flexboxレイアウトを設定し、子要素を中央に配置しています。

import React from 'react';
import { Box, Paper } from '@mui/material';

function FlexboxLayout() {
  return (
    <Box
      sx={{
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center',
        height: '100vh',
      }}
    >
      <Paper sx={{ padding: 2 }}>中央に配置されたコンテンツ</Paper>
    </Box>
  );
}

export default FlexboxLayout;

Flexboxのプロパティ

  • display: flex: 子要素をフレックスコンテナとして扱います。
  • justifyContent: 横方向の配置(flex-start,center,space-betweenなど)。
  • alignItems: 縦方向の配置(flex-start,center,stretchなど)。
  • flexDirection: 子要素の配置方向(row,columnなど)。

複雑なレイアウト

Flexboxを使うことで、複雑なレスポンシブレイアウトも簡単に作成できます。以下の例では、2列レイアウトを画面サイズに応じて縦並びに変更しています。

import React from 'react';
import { Box, Paper } from '@mui/material';

function ComplexFlexboxLayout() {
  return (
    <Box
      sx={{
        display: 'flex',
        flexDirection: { xs: 'column', sm: 'row' },
        gap: 2,
      }}
    >
      <Paper sx={{ padding: 2 }}>コンテンツ1</Paper>
      <Paper sx={{ padding: 2 }}>コンテンツ2</Paper>
    </Box>
  );
}

export default ComplexFlexboxLayout;

このレイアウトでは、xs(小さな画面)では縦並び(column)に、sm(中程度の画面)では横並び(row)に配置が変わります。gapプロパティで、アイテム間のスペースを簡単に調整できます。

関連記事

強力なUIコンポーネントライブラリ「MUI(Material-UI)」について《トラブルシューティング編》
# よくある質問とトラブルシューティング MUI(Material-UI)を使用していると、初心者でも経験者でも共通して直面しやすいエラーや問題がいくつか存在します。この章では、よく発生するエラーとその解決方法、ドキュメントでは見つけにくい設定の [...]
2024年10月15日 13:41
強力なUIコンポーネントライブラリ「MUI(Material-UI)」について《テーマ・スタイリング編》
# MUIのテーマカスタマイズ MUI(Material-UI)はデフォルトのテーマをベースに、簡単にテーマをカスタマイズできる柔軟なシステムを提供しています。これにより、アプリケーションのデザインをブランドや要件に合わせて調整可能です。 [...]
2024年10月15日 11:56
強力なUIコンポーネントライブラリ「MUI(Material-UI)」について《概要編》
# はじめに ウェブアプリケーションの開発において、デザインと使いやすさを両立することは非常に重要です。MUI(Material-UI)は、Reactと組み合わせて簡単に洗練されたユーザーインターフェースを構築できる強力なUIコンポーネントライブ [...]
2024年10月15日 10:10
【React】React-ToastifyのカラーテーマとPCの外観モードを連動させる方法【TypeScript】
# はじめに Webアプリでユーザー情報の変更などを行った際、処理が正常に完了したことをユーザーに伝えるために、画面の端に一時的にメッセージを表示する機能のことを「トースト」といいます。 >トーストとは、主にデスクトップアプリケーションの機 [...]
2022年7月31日 21:24
RailsアプリにおけるReactの使い方や注意点など
# はじめに [こちらのページ](https://qiita.com/TsutomuNakamura/items/72d8cf9f07a5a30be048)でReactの基本について勉強しました。 Railsアプリの中でReactを利用するとい [...]
2019年12月13日 12:37
【Rails】Railsアプリにreact-railsを追加する手順
# はじめに JavaScriptフレームワークといえば長らくjQuery一強でした。しかし、ここ数年はAngularJSやReact、Vue.jsといった新しいフレームワークがどんどんと登場しています。過去5年間の検索回数の推移を見てみると、2 [...]
2019年12月11日 15:21