【完全入門】Material UIの導入方法と主要コンポーネント

はい、承知いたしました。Material UIの導入方法から主要コンポーネントの詳細な説明、そしてスタイルやテーマのカスタマイズ方法まで、約5000語で解説する詳細な記事を作成します。


【完全入門】Material UIの導入方法と主要コンポーネント

はじめに

モダンなWebアプリケーション開発において、UI(ユーザーインターフェース)の構築は非常に重要な要素です。ユーザーにとって使いやすく、見た目にも美しいインターフェースは、アプリケーションの成功に直結します。しかし、ゼロから高品質なUIコンポーネントを作成するのは、多くの時間と労力を要します。

そこで役立つのが、UIコンポーネントライブラリです。数あるライブラリの中でも、特に人気が高く、広く利用されているのが Material UI です。Material UIは、Googleが提唱するデザインシステム Material Design をReactコンポーネントとして実装したライブラリで、洗練されたデザインと豊富な機能を提供します。

Material UIとは?

Material UIは、Reactに特化したUIコンポーネントライブラリです。Googleが開発・提唱しているデザインシステム「Material Design」の原則に基づいたコンポーネントを提供します。Material Designは、物理世界とその法則(紙とインクのメタファーなど)をデジタルインターフェースに取り入れたもので、直感的で一貫性のあるユーザー体験を提供することを目的としています。

Material UIを使うことで、開発者はデザインに関する深い知識がなくても、プロフェッショナルでモダンなUIを簡単に構築できます。提供されるコンポーネントは、レスポンシブデザインに対応しており、アクセシビリティにも配慮されています。

なぜMaterial UIを使うのか?

  1. デザインの一貫性: Material Designに基づいたコンポーネント群は、アプリケーション全体に統一感のあるデザインをもたらします。
  2. 開発効率の向上: ボタン、入力フォーム、ダイアログ、ナビゲーションなど、一般的なUI要素があらかじめ用意されているため、ゼロから作成する手間が省け、開発速度が大幅に向上します。
  3. カスタマイズ性: 用意されているコンポーネントは、テーマシステムやスタイルシステムを通じて高度にカスタマイズ可能です。プロジェクトのブランドイメージに合わせて色やフォント、形状などを自由に変更できます。
  4. アクセシビリティ: Material UIのコンポーネントは、WAI-ARIA(Web Accessibility Initiative – Accessible Rich Internet Applications)のガイドラインを考慮して設計されており、キーボードナビゲーションやスクリーンリーダーへの対応が進んでいます。
  5. 豊富なコンポーネント: レイアウトから複雑なデータ表示まで、幅広い用途に対応できる多様なコンポーネントが用意されています。
  6. コミュニティ: 非常に多くの開発者に利用されており、活発なコミュニティがあります。問題が発生した際にも、解決策を見つけやすいです。

この記事で学べること

この記事では、Material UIの基本的な使い方を網羅的に解説します。具体的には、以下の内容を学ぶことができます。

  • Material UIプロジェクトへの導入方法
  • Material Designの基本概念とMaterial UIにおけるその適用方法
  • コンポーネントのスタイリングとテーマの適用方法
  • 主要なUIコンポーネントの詳細な使い方 (レイアウト、フォーム、データ表示、フィードバックなど)
  • より高度なスタイリングとテーマのカスタマイズ方法

ReactでのUI開発を効率化したい方、Material Designに興味がある方にとって、この記事がMaterial UI活用の強力な一歩となることを願っています。

それでは、早速Material UIの世界に入り込みましょう!


第1章: Material UIの導入

Material UIを使い始めるための最初のステップは、プロジェクトへのインストールと基本的な設定です。ここでは、ReactプロジェクトにMaterial UIを導入する方法をステップごとに解説します。

1. 環境構築

Material UIはReactライブラリなので、React開発ができる環境が必要です。以下のものが準備されていることを確認してください。

  • Node.js: JavaScriptの実行環境。npm (Node Package Manager) が含まれています。推奨バージョンは公式ドキュメントを確認してください。
  • npm または yarn: パッケージ管理ツール。どちらかがあればOKです。

まだNode.jsがインストールされていない場合は、公式ウェブサイトからインストーラーをダウンロードしてインストールしてください。

2. プロジェクトの作成

Material UIを導入するReactプロジェクトが必要です。ここでは、一般的なプロジェクト作成方法としてCreate React App (CRA) とNext.jsを例に挙げますが、どちらか一方、あるいは既存のプロジェクトでも構いません。

Create React App (CRA) で新しいプロジェクトを作成する場合:

bash
npx create-react-app my-material-ui-app
cd my-material-ui-app

Next.js で新しいプロジェクトを作成する場合:

bash
npx create-next-app my-material-ui-app --typescript --eslint --app # または --pages
cd my-material-ui-app

プロジェクトディレクトリに移動したら、次のステップに進みます。

3. Material UIのインストール

プロジェクトにMaterial UIをインストールします。コアライブラリと、スタイルを管理するためのライブラリ(EmotionまたはStyled Components)が必要です。Material UI v5以降では、Emotionがデフォルトのスタイルエンジンとして推奨されていますが、Styled Componentsも利用可能です。ここではEmotionをインストールする例を示します。

npmを使う場合:

bash
npm install @mui/material @emotion/react @emotion/styled

yarnを使う場合:

bash
yarn add @mui/material @emotion/react @emotion/styled

これでMaterial UIのコアパッケージと、スタイルを適用するための基盤となるパッケージがインストールされました。

4. フォントの設定 (Roboto)

Material Designでは、デフォルトのフォントとして Roboto が推奨されています。Material UIのコンポーネントもRobotoを前提としたデザインになっているため、導入することを強く推奨します。導入方法はいくつかありますが、最も簡単なのはCDNを利用する方法です。

public/index.html ファイルを開き、<head> タグ内に以下の <link> タグを追加します。

html
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />

より厳密にパフォーマンスを管理したい場合は、フォントファイルをダウンロードしてプロジェクトに含めるか、fontsource のようなライブラリを利用する方法もあります。

例: fontsource を使用する場合

“`bash

npm

npm install @fontsource/roboto

yarn

yarn add @fontsource/roboto
“`

次に、アプリケーションのエントリーポイント(例: src/index.jssrc/pages/_app.js (Next.js))でインポートします。

“`javascript
// src/index.js (CRAの場合)
import ‘@fontsource/roboto/300.css’;
import ‘@fontsource/roboto/400.css’;
import ‘@fontsource/roboto/500.css’;
import ‘@fontsource/roboto/700.css’;

// その他のインポート…
import React from ‘react’;
import ReactDOM from ‘react-dom/client’;
import ‘./index.css’; // デフォルトのCSSがあれば
import App from ‘./App’;

const root = ReactDOM.createRoot(document.getElementById(‘root’));
root.render(



);
“`

5. アイコンの設定 (Material Icons)

Material UIでは、Material Designのガイドラインに沿ったアイコンセット Material Icons を簡単に利用できます。これもフォントと同様に、CDNまたはnpmパッケージで導入できます。

CDNを利用する方法:

public/index.html<head> タグ内に以下の <link> タグを追加します。

html
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />

npmパッケージを利用する方法:

“`bash

npm

npm install @mui/icons-material

yarn

yarn add @mui/icons-material
“`

npmパッケージでインストールした場合、各アイコンは個別にインポートして使用します。

“`javascript
import AccessAlarmIcon from ‘@mui/icons-material/AccessAlarm’;
import ThreeDRotation from ‘@mui/icons-material/ThreeDRotation’;

function MyComponent() {
return (


);
}
“`

通常はnpmパッケージでの利用が推奨されます。必要なアイコンだけをバンドルに含めることができるため、パフォーマンス上有利です。

6. ThemeProviderの導入

アプリケーション全体でMaterial UIのテーマ(色、タイポグラフィ、間隔など)を適用するために、アプリケーションのルートコンポーネントを ThemeProvider でラップすることが推奨されます。ThemeProvider@mui/material/stylesからインポートします。

“`javascript
// src/index.js (CRAの場合) または src/pages/_app.js (Next.jsの場合)

import React from ‘react’;
import ReactDOM from ‘react-dom/client’; // CRAの場合
import App from ‘./App’;

import { ThemeProvider, createTheme } from ‘@mui/material/styles’;
import CssBaseline from ‘@mui/material/CssBaseline’; // CSSリセットのため
import ‘@fontsource/roboto/300.css’; // フォントのインポート(npmの場合)
import ‘@fontsource/roboto/400.css’;
import ‘@fontsource/roboto/500.css’;
import ‘@fontsource/roboto/700.css’;

// デフォルトテーマを作成
const defaultTheme = createTheme();

// CRAの場合
const root = ReactDOM.createRoot(document.getElementById(‘root’));
root.render(


{/ CssBaselineでCSSのリセットを適用 /}




);

// Next.jsの場合 (pages/_app.js)
/*
import type { AppProps } from ‘next/app’;
import { ThemeProvider, createTheme } from ‘@mui/material/styles’;
import CssBaseline from ‘@mui/material/CssBaseline’;
import ‘@fontsource/roboto/300.css’;
import ‘@fontsource/roboto/400.css’;
import ‘@fontsource/roboto/500.css’;
import ‘@fontsource/roboto/700.css’;

const defaultTheme = createTheme();

function MyApp({ Component, pageProps }: AppProps) {
return (




);
}

export default MyApp;
*/
“`

createTheme() は、Material Designのデフォルトテーマオブジェクトを生成します。ThemeProviderにこのテーマオブジェクトを渡すことで、アプリケーション内のMaterial UIコンポーネント全てにこのテーマが適用されます。

CssBaseline は、ブラウザ間のCSSの差異を正規化するためのコンポーネントです。多くの場合は導入することをおすすめします。

7. 初期設定の確認

導入が成功したか確認するために、簡単なMaterial UIコンポーネントを表示してみましょう。src/App.js を編集します。

“`javascript
import React from ‘react’;
import Button from ‘@mui/material/Button’; // Buttonコンポーネントをインポート
import Typography from ‘@mui/material/Typography’; // Typographyコンポーネントをインポート
import Box from ‘@mui/material/Box’; // Boxコンポーネントをインポート

function App() {
return (
// BoxはCSSユーティリティとして余白や配置を簡単に設定できます


Material UIへようこそ!



);
}

export default App;
“`

プロジェクトを起動してブラウザで確認します。

“`bash

npm

npm start

yarn

yarn start
“`

デフォルトのRobotoフォントが適用され、青い背景色のボタンが表示されていれば、Material UIの基本的な導入は成功です!


第2章: Material UIの基本概念

Material UIを効果的に使うためには、その基盤となっているMaterial Designの考え方や、Material UI独自のスタイルシステム、テーマシステムといった基本概念を理解することが重要です。

1. Material Designとは?

Material Designは、Googleによって開発された視覚、モーション、インタラクションデザインのための総合的なデザインシステムです。以下の原則に基づいています。

  • Material is the Metaphor: 物理的な世界(紙とインク)のメタファーを用いて、デジタルインターフェースに質感や奥行き、動きを与えます。要素はレイヤーを持ち、影や重力、物理的な法則に従うかのように振る舞います。
  • Bold, Graphic, Intentional: 大胆でグラフィックなデザインを重視し、意味のある配置や色彩、タイポグラフィを用いて情報を効果的に伝えます。
  • Meaningful Motion: アニメーションやトランジションは単なる装飾ではなく、ユーザーの注意を引き、状態の変化を伝え、操作に対するフィードバックを提供するために利用されます。

Material UIは、これらの原則をReactコンポーネントとして忠実に再現することを目指しています。

2. コンポーネントの種類

Material UIは非常に多くのコンポーネントを提供しており、これらは機能や用途に応じて分類されています。主なカテゴリには以下のようなものがあります。

  • Layout: ページ全体の構造や要素の配置を決定するためのコンポーネント(Box, Container, Grid, Stackなど)。
  • Inputs: ユーザーからの入力を受け付けるためのコンポーネント(Button, TextField, Checkbox, Radio, Select, Sliderなど)。
  • Data Display: 情報を表示するためのコンポーネント(Typography, Icon, Avatar, Badge, Card, Paper, Tableなど)。
  • Feedback: ユーザーへのフィードバックや状態表示のためのコンポーネント(Alert, Snackbar, Progress, Dialog, Skeletonなど)。
  • Navigation: アプリケーション内を移動するためのコンポーネント(AppBar, Drawer, Tabs, Pagination, Breadcrumbs, Menuなど)。
  • Utility: 他のコンポーネントや機能と組み合わせて使用するユーティリティコンポーネント(Modal, Popover, Tooltip, ClickAwayListenerなど)。

これらのコンポーネント群を適切に組み合わせることで、複雑なUIも効率的に構築できます。

3. スタイルシステム

Material UIでは、コンポーネントの見た目(スタイル)をどのように定義・適用するかが重要な概念です。Material UI v5以降では、CSS-in-JSライブラリ(デフォルトはEmotion)を利用したモダンなスタイルシステムが推奨されています。主なスタイリング方法には以下の2つがあります。

a) sx prop (最も推奨)

ほとんどのMaterial UIコンポーネントは sx という特別なpropを持っています。この sx propを使うと、コンポーネントに直接CSSのスタイルをオブジェクト形式で指定できます。これは一時的なスタイル変更や、簡単なカスタマイズに非常に便利です。

sx propは、Material UIのテーマシステムと深く連携しています。たとえば、marginpadding の値にはテーマで定義された間隔(spacing)単位を使用でき、color にはテーマの色パレットを指定できます。また、レスポンシブデザインのためのブレークポイントに基づいたスタイル変更も容易に行えます。

“`javascript
import Box from ‘@mui/material/Box’;

function MyComponent() {
return (
<Box
sx={{
width: 300, // ピクセル指定
height: 300,
backgroundColor: ‘primary.dark’, // テーマの色パレットを使用 (theme.palette.primary.dark)
‘&:hover’: { // 疑似要素/クラス
backgroundColor: ‘primary.main’,
opacity: [0.9, 0.8, 0.7], // レスポンシブな不透明度
},
m: 2, // margin: theme.spacing(2)
p: 1, // padding: theme.spacing(1)
display: ‘flex’,
justifyContent: ‘center’,
alignItems: ‘center’,
color: ‘white’,
fontWeight: ‘bold’,

    // レスポンシブ対応 (ブレークポイントを使用)
    // xs: 0px, sm: 600px, md: 900px, lg: 1200px, xl: 1536px デフォルト
    width: {
      xs: 100,
      sm: 200,
      md: 300,
    },
  }}
>
  Styled Box
</Box>

);
}
“`

sx propは非常に強力で柔軟なスタイリング方法であり、ほとんどのユースケースで利用できます。

b) styled() helper

より複雑なカスタムコンポーネントを作成したり、既存のMaterial UIコンポーネントに大規模なスタイル変更を加えたい場合は、@mui/material/styles から提供される styled() helper関数を使用するのが適しています。これはEmotionやStyled Componentsの styled 関数と同様のAPIを提供します。

“`javascript
import Button from ‘@mui/material/Button’;
import { styled } from ‘@mui/material/styles’;

// Material UIのButtonコンポーネントを拡張してスタイルを適用
const CustomButton = styled(Button)(({ theme }) => ({
// デフォルトのボタンスタイルを上書き
backgroundColor: theme.palette.secondary.main,
color: theme.palette.common.white,
padding: theme.spacing(2, 4), // 上下2単位、左右4単位の間隔
border: ‘none’,
borderRadius: theme.shape.borderRadius * 2, // テーマのborderRadiusを使用

// ホバー時のスタイル
‘&:hover’: {
backgroundColor: theme.palette.secondary.dark,
},
}));

function MyComponent() {
return (

カスタムボタン

);
}
“`

styled() helperは、テーマオブジェクトにアクセスできるコールバック関数を受け取り、その中でスタイルを定義します。これにより、テーマの値に基づいたスタイリングや、より複雑なCSS構造(ネストされたセレクタなど)の定義が可能になります。

古いAPI (makeStyles, withStyles)

Material UI v4以前では、@mui/styles パッケージから提供される makeStyleswithStyles といったHooksやHigher-Order Components (HOC) が主に使われていました。これらはJSS (JavaScript Style Sheets) を使用していましたが、v5以降ではEmotionやStyled Componentsを推奨するため非推奨 (deprecated) となっています。新規プロジェクトでは sx prop や styled() helper を使用することを強く推奨します。

4. テーマ (Theming)

Material UIの最も強力な機能の一つがテーマシステムです。アプリケーション全体の色、タイポグラフィ、間隔、形状、ブレークポイントなどの視覚的な一貫性をテーマオブジェクトとして一元管理できます。

a) テーマオブジェクトの構造

テーマオブジェクトは、以下のような主要なプロパティを持ちます。

  • palette: アプリケーションで使用する色のパレット。primary, secondary, error, warning, info, success といった主要な色や、grey, common (white, black) などが含まれます。各色には main, light, dark, contrastText などのバリエーションがあります。
  • typography: フォントファミリー、フォントサイズ、行間など、テキストに関するスタイルを定義します。h1, body1, button, caption など、様々なバリアント(種類)が定義されています。
  • spacing: 要素間の間隔を定義するための単位(デフォルトは8px)。theme.spacing(1) は8px、theme.spacing(2) は16px といったように計算されます。
  • breakpoints: レスポンシブデザインの基準となる画面幅(ブレークポイント)。デフォルトは xs, sm, md, lg, xl です。
  • shape: 角丸の度合い(borderRadius)。
  • shadows: 影のスタイル(elevation)。
  • transitions: アニメーションの定義。
  • zIndex: レイヤーの重なり順。
  • components: 個々のMaterial UIコンポーネントに対するデフォルトスタイルの上書きや、プロパティのデフォルト値を設定できます。

b) テーマのカスタマイズ方法

@mui/material/styles から提供される createTheme() 関数を使って、デフォルトテーマを拡張または上書きすることでテーマをカスタマイズします。

“`javascript
import { createTheme } from ‘@mui/material/styles’;

const customTheme = createTheme({
palette: {
primary: {
main: ‘#1976d2’, // デフォルトのprimary色を上書き
light: ‘#42a5f5’,
dark: ‘#1565c0’,
contrastText: ‘#fff’,
},
secondary: {
main: ‘#9c27b0’, // secondary色を追加/上書き
},
error: {
main: ‘#d32f2f’,
},
// … その他の色
},
typography: {
fontFamily: [ // フォントファミリーの追加
‘-apple-system’,
‘BlinkMacSystemFont’,
‘”Segoe UI”‘,
‘Roboto’,
‘”Helvetica Neue”‘,
‘Arial’,
‘sans-serif’,
‘”Apple Color Emoji”‘,
‘”Segoe UI Emoji”‘,
‘”Segoe UI Symbol”‘,
].join(‘,’),
h1: { // h1タイポグラフィバリアントのカスタマイズ
fontSize: ‘3rem’,
fontWeight: 500,
},
// … その他のタイポグラフィ
},
spacing: 4, // 間隔単位をデフォルトの8pxから4pxに変更 (theme.spacing(1) => 4px)
shape: {
borderRadius: 8, // 角丸の度合いをデフォルトの4pxから8pxに変更
},
components: {
// Buttonコンポーネント全体のデフォルトスタイルを上書き
MuiButton: {
defaultProps: {
// デフォルトのvariantをcontainedにする
variant: ‘contained’,
// デフォルトの色をsecondaryにする
color: ‘secondary’,
},
styleOverrides: {
// rootクラス(Buttonの最上位要素)のスタイルを上書き
root: {
textTransform: ‘none’, // テキストを全て大文字にしない
},
// containedVariantクラスのスタイルを上書き
containedSecondary: {
boxShadow: ‘none’, // 影をなくす
},
},
},
// … その他のコンポーネント
},
});
“`

作成したカスタムテーマオブジェクトを ThemeProvider に渡すことで、アプリケーション全体に反映させることができます。

“`javascript
import { ThemeProvider } from ‘@mui/material/styles’;
// … customThemeのインポート/定義

function App() {
return (

{/ アプリケーション全体 /}

);
}
“`

c) ネストされたテーマ

ThemeProvider はネストすることができます。内側の ThemeProvider は、外側のテーマを継承しつつ、自身のテーマで上書き・追加した部分のみを適用します。これにより、アプリケーションの一部だけ異なるテーマを適用するといったことが可能です。

d) ダークモードの実装

Material UIのテーマシステムを利用すると、ライトモードとダークモードの切り替えを比較的容易に実装できます。createTheme() 関数は、palettemode プロパティに 'light' または 'dark' を指定することで、自動的にそれぞれのモードに適した色のパレットを生成します。

動的な切り替えには、ReactのStateやContext APIと組み合わせて、テーマオブジェクトを動的に生成し ThemeProvider に渡す仕組みが必要です。

“`javascript
import React, { useState, useMemo } from ‘react’;
import { ThemeProvider, createTheme } from ‘@mui/material/styles’;
import CssBaseline from ‘@mui/material/CssBaseline’;
import Button from ‘@mui/material/Button’;

function App() {
const [mode, setMode] = useState<‘light’ | ‘dark’>(‘light’);

// modeが変更されるたびに新しいテーマオブジェクトを作成
const theme = useMemo(
() =>
createTheme({
palette: {
mode: mode, // ‘light’ または ‘dark’
// 必要に応じて個別の色もカスタマイズ可能
// primary: {
// main: mode === ‘light’ ? ‘#1976d2’ : ‘#90caf9’,
// },
},
// … その他のテーマ設定
}),
[mode], // modeが変更されたときだけ再生成
);

const toggleColorMode = () => {
setMode((prevMode) => (prevMode === ‘light’ ? ‘dark’ : ‘light’));
};

return (

{/ CssBaselineはモードに合わせて背景色などを調整します /}



現在のテーマ: {mode}

{/ 他のMaterial UIコンポーネント /}


);
}
“`

このように、createThemepalette.mode を利用することで、簡単にダークモードに対応したアプリケーションを構築できます。


第3章: 主要コンポーネントの詳細な解説

Material UIには非常に多くのコンポーネントがありますが、ここでは特に使用頻度の高い主要なコンポーネントをピックアップし、それぞれの特徴と基本的な使い方をコード例と共に解説します。

1. レイアウト関連 (Layout)

ページの構造や要素の配置を担うコンポーネントです。

Box

Box は、sx prop を最大限に活用するための強力なコンポーネントです。CSSユーティリティとして機能し、HTMLの div 要素(あるいは component propで指定した要素)に、テーマに基づいたスタイリングを簡単に適用できます。余白、色、タイポグラフィ、Flexbox、Gridなど、ほぼ全てのCSSプロパティを sx prop で指定できます。

“`javascript
import Box from ‘@mui/material/Box’;
import Typography from ‘@mui/material/Typography’;

function BoxExample() {
return (

Boxコンポーネント
sx propでスタイルを適用

);
}
“`

sx propは、spacing, color, typography, breakpoints などのテーマの値に短縮記法でアクセスできます。例えば、mmarginppaddingttoplleft などです。さらに、方向を指定する t, b, l, r, x, y や、レスポンシブブレークポイントを組み合わせることができます(例: pt={{ xs: 2, md: 4 }})。これは非常に便利で、インラインスタイルでは難しかったレスポンシブ対応やテーマとの連携を容易にします。

Container

コンテンツを中央に配置し、最大幅を制限するためのコンポーネントです。レスポンシブに対応しており、ブレークポイントごとに最大幅を調整できます。

“`javascript
import Container from ‘@mui/material/Container’;
import Typography from ‘@mui/material/Typography’;

function ContainerExample() {
return (
// maxWidth=’sm’ は、smブレークポイント (600px) までは100%、
// md以上のブレークポイントでは最大幅がsmの最大幅になることを意味します。
// デフォルトは ‘lg’ (1200px) です。falseを指定すると最大幅の制限がなくなります。

Container コンポーネント
このコンテンツは中央に配置され、最大幅が制限されます。

);
}
“`

Grid

レスポンシブなグリッドシステムを構築するためのコンポーネントです。Flexboxをベースにしており、12カラムシステムを採用しています。

“`javascript
import Grid from ‘@mui/material/Grid’;
import Paper from ‘@mui/material/Paper’; // グリッドアイテムを見やすくするためのPaper

function GridExample() {
return (
// container prop は Flexbox コンテナになります
{/ item 間の間隔を指定 (テーマのspacing単位) /}
{/ item prop は Flexbox アイテムになります /}
{/ xs: 12カラム (常に1列), sm: 6カラム (2列), md: 4カラム (3列) /}

Grid Item 1




Grid Item 2




Grid Item 3


{/ 組み合わせも可能 /}

Grid Item 4 (md: 8カラム)



);
}
“`

Grid コンポーネントは containeritem の両方のpropを持つことができますが、一般的には containeritem を分けて使用します。container でグリッドの親要素を定義し、item で各子要素のカラム幅や配置を定義します。

Stack

1次元(縦または横)のレイアウトを簡単に構築するためのコンポーネントです。Flexboxの機能を使って、子要素の間に一定の間隔を空けたり、配置を制御したりできます。

“`javascript
import Stack from ‘@mui/material/Stack’;
import Button from ‘@mui/material/Button’;

function StackExample() {
return (
// direction=’row’ は子要素を横に並べます(デフォルトは’column’)
// spacing={2} は子要素間にテーマのspacing単位で2単位の間隔を空けます





);
}
“`

Stack は簡単なレイアウトには非常に便利ですが、複雑な2次元レイアウトには Grid の方が適しています。

2. 入力関連 (Inputs)

ユーザーからの入力を受け付けるためのコンポーネントです。

Button

クリック可能なボタンを表示します。様々なバリアント、色、サイズ、アイコンなどを指定できます。

“`javascript
import Button from ‘@mui/material/Button’;
import DeleteIcon from ‘@mui/icons-material/Delete’;
import SendIcon from ‘@mui/icons-material/Send’;

function ButtonExample() {
return (

{/ デフォルト /}

{/ バリアント /}


{//}


{/ サイズ /}


{/ 無効化 /}

{/ アイコン付き /}



);
}
“`

variant には 'text', 'contained', 'outlined' があります。color にはテーマで定義された 'primary', 'secondary', 'success', 'error', 'info', 'warning''inherit' などが指定できます。

TextField

テキストを入力するためのフォームフィールドです。ラベル、プレースホルダー、エラー表示、ヘルパーテキストなど、豊富な機能を持ちます。

“`javascript
import TextField from ‘@mui/material/TextField’;
import Box from ‘@mui/material/Box’;

function TextFieldExample() {
return (

{/ 基本的なTextField /}

{/ Filled TextField /}

{/ Standard TextField /}
{/ エラー表示とヘルパーテキスト /}

{/ ラベル、プレースホルダー、デフォルト値 /}

{/ タイプ指定 (例: password) /}


);
}
“`

variant には 'outlined', 'filled', 'standard' があります。label, placeholder, defaultValue (または value) など、多くの標準的なinput属性をpropsとして渡せます。error propを渡すとエラー状態になり、helperText でエラーメッセージを表示できます。InputProps, InputLabelProps, FormHelperTextProps などのpropを使うと、内包されている要素(<input>, <label>, <p> など)に直接propsを渡すことができます。

Checkbox, Radio, Switch

真偽値や複数の選択肢から一つを選択するためのコンポーネントです。通常は FormControl, FormLabel, FormGroup, FormControlLabel と組み合わせて使用し、アクセシビリティやグループ化を適切に行います。

“`javascript
import * as React from ‘react’;
import FormGroup from ‘@mui/material/FormGroup’;
import FormControlLabel from ‘@mui/material/FormControlLabel’;
import Checkbox from ‘@mui/material/Checkbox’;
import Radio from ‘@mui/material/Radio’;
import RadioGroup from ‘@mui/material/RadioGroup’;
import FormControl from ‘@mui/material/FormControl’;
import FormLabel from ‘@mui/material/FormLabel’;
import Switch from ‘@mui/material/Switch’;

function InputSelectionExample() {
const [checked, setChecked] = React.useState(true);
const [selectedValue, setSelectedValue] = React.useState(‘a’);

const handleCheckboxChange = (event: React.ChangeEvent) => {
setChecked(event.target.checked);
};

const handleRadioChange = (event: React.ChangeEvent) => {
setSelectedValue(event.target.value);
};

const handleSwitchChange = (event: React.ChangeEvent) => {
// State更新ロジック (例としてCheckboxと同じにする)
setChecked(event.target.checked);
};

return (

{/ チェックボックス /}

} label=”Remember me” />
}
label=”Controlled Checkbox”
/>
} label=”Disabled” />

  {/* ラジオボタン */}
  <FormControl sx={{ mt: 2 }}>
    <FormLabel id="demo-radio-buttons-group-label">Gender</FormLabel>
    <RadioGroup
      aria-labelledby="demo-radio-buttons-group-label"
      defaultValue="female"
      name="radio-buttons-group"
      value={selectedValue}
      onChange={handleRadioChange}
    >
      <FormControlLabel value="female" control={<Radio />} label="Female" />
      <FormControlLabel value="male" control={<Radio />} label="Male" />
      <FormControlLabel value="other" control={<Radio />} label="Other" />
    </RadioGroup>
  </FormControl>

  {/* スイッチ */}
  <FormControlLabel
    control={<Switch checked={checked} onChange={handleSwitchChange} />}
    label="Switch"
    sx={{ display: 'block', mt: 2 }} // ブロック要素として表示
  />
</Box>

);
}
“`

FormControlLabel は、入力コンポーネント (control propで指定) とラベル (label prop) を関連付け、クリック可能領域を広げるなどアクセシビリティを向上させます。RadioGroup はラジオボタンをグループ化し、一つの選択肢のみが選択されるように管理します。

Select

ドロップダウンリストから値を選択するためのコンポーネントです。MenuItem コンポーネントと組み合わせて使用します。

“`javascript
import * as React from ‘react’;
import Box from ‘@mui/material/Box’;
import InputLabel from ‘@mui/material/InputLabel’;
import MenuItem from ‘@mui/material/MenuItem’;
import FormControl from ‘@mui/material/FormControl’;
import Select, { SelectChangeEvent } from ‘@mui/material/Select’;

function SelectExample() {
const [age, setAge] = React.useState(”);

const handleChange = (event: SelectChangeEvent) => {
setAge(event.target.value as string);
};

return (

{/ fullWidthで親要素の幅いっぱいに広げる /}
Age {/ ラベル /}



);
}
“`

FormControlInputLabel を一緒に使うことで、ラベルとセレクトボックスが正しく関連付けられ、アクセシビリティが向上します。Select コンポーネントは、TextField と同様に variant (outlined, filled, standard) を持つことができます。

3. データ表示関連 (Data Display)

情報をユーザーに表示するためのコンポーネントです。

Typography

テキストを表示するためのコンポーネントです。Material Designのタイポグラフィスケール(h1〜h6, body1, body2など)に沿ってテキストスタイルを適用できます。

“`javascript
import Typography from ‘@mui/material/Typography’;
import Box from ‘@mui/material/Box’;

function TypographyExample() {
return (

{/ h1 見出しスタイル /}

h1 Heading

{/ h4 見出しスタイル、pタグとしてレンダリング /}

h4 Heading (as p)

{/ body1 本文スタイル /}

Body 1 text. This is a paragraph with body 1 style.

{/ body2 本文スタイル /}

Body 2 text. This is another paragraph with body 2 style.

{/ テキスト中央寄せと色 /}

Subtitle 1, centered, secondary color


);
}
“`

variant propで適用したいタイポグラフィスタイルを指定します。component propを使うと、実際にレンダリングされるHTML要素を指定できます(例: variant="h4"<p> タグとして表示)。gutterBottom propは、テキストの下に余白を追加します(段落の最後に便利です)。

Icon

Material IconsやカスタムSVGアイコンを表示するためのコンポーネントです。

“`javascript
import Icon from ‘@mui/material/Icon’; // Font Icons用
import AccessAlarmIcon from ‘@mui/icons-material/AccessAlarm’; // SVG Icons用
import ThreeDRotation from ‘@mui/icons-material/ThreeDRotation’;

function IconExample() {
return (
:not(style)’: { m: 1 }, mt: 2 }}>
{/ Font Icons (CDNでMaterial Iconsを導入した場合) /}
star {/ アイコン名 /}
star {/ テーマの色 /}
star {/ sxで色を指定 /}
star {/ カスタム色 /}
star {/ サイズ /}

  {/* SVG Icons (npmパッケージで導入した場合) */}
  <AccessAlarmIcon />
  <AccessAlarmIcon color="secondary" />
  <AccessAlarmIcon fontSize="large" />
  <ThreeDRotation sx={{ color: 'error.main' }} />
</Box>

);
}
“`

Font Iconsを使用する場合は Icon コンポーネントにアイコン名をテキストとして渡します。SVG Iconsを使用する場合は @mui/icons-material からアイコンコンポーネントをインポートして使用します。SVGアイコンの方がバンドルサイズを最適化しやすく、推奨される方法です。

Avatar

ユーザーのプロフィール画像やイニシャルを表示するためのコンポーネントです。

“`javascript
import Avatar from ‘@mui/material/Avatar’;
import Stack from ‘@mui/material/Stack’;

function AvatarExample() {
return (

{/ 画像アバター /}

{/ イニシャルアバター /}
N
{/ アイコンアバター /}

folder

{/ サイズ /}
L

);
}
“`

src propで画像URLを指定するか、子要素としてテキストやアイコンを渡すことで表示内容を定義します。sx propでサイズなどを調整できます。

Badge

アイコンやテキストなどの要素の右上に小さなバッジ(通知数など)を表示するためのコンポーネントです。

“`javascript
import * as React from ‘react’;
import Badge from ‘@mui/material/Badge’;
import MailIcon from ‘@mui/icons-material/Mail’;
import ShoppingCartIcon from ‘@mui/icons-material/ShoppingCart’;
import Box from ‘@mui/material/Box’;

function BadgeExample() {
return (
:not(style)’: { m: 2 }, mt: 2 }}>
{/ 通知数付きバッジ /}



{/ 0を表示しない /}



{/ 点を表示 /}



{/ 最大値 /}




);
}
“`

badgeContent propでバッジの内容(テキストや数字)を指定します。color propでバッジの色を変更できます。variant="dot" で中身のない点だけを表示することも可能です。max propで表示する最大値を制限できます。

Card

関連性の高いコンテンツ(画像、テキスト、アクションなど)をまとめるためのコンポーネントです。

“`javascript
import * as React from ‘react’;
import Card from ‘@mui/material/Card’;
import CardActions from ‘@mui/material/CardActions’;
import CardContent from ‘@mui/material/CardContent’;
import CardMedia from ‘@mui/material/CardMedia’;
import Button from ‘@mui/material/Button’;
import Typography from ‘@mui/material/Typography’;

function CardExample() {
return (

{/ 画像エリア /}

{/ コンテンツエリア /}


Lizard


Lizards are a widespread group of squamate reptiles, with over 6,000
species, ranging across all continents except Antarctica


{/ アクションエリア /}





);
}
“`

Card は、CardMedia, CardContent, CardActions などのサブコンポーネントと組み合わせて使用するのが一般的です。これにより、カードの構造(メディア、内容、アクション)を明確に定義できます。

Paper

UI要素をまとめるための汎用的なコンテナです。物理的な紙のような概念を模しており、影(elevation)を付けて奥行きを表現できます。

“`javascript
import Paper from ‘@mui/material/Paper’;
import Typography from ‘@mui/material/Typography’;

function PaperExample() {
return (
:not(style)’: { m: 1, width: 128, height: 128 }, mt: 2 }}>
{/ 影なし (elevation={0}) /}

Elevation 0

{/ 標準的な影 (elevation={3}) /}

Elevation 3

{/ より強い影 (elevation={8}) /}

Elevation 8


);
}
“`

elevation propで影の強さを指定します。値は0から24までの整数です。Paper は、単純なコンテナとしてだけでなく、フォームやセクションを囲むためにも広く使われます。

Table

構造化されたデータを表形式で表示するためのコンポーネント群です。

“`javascript
import * as React from ‘react’;
import Table from ‘@mui/material/Table’;
import TableBody from ‘@mui/material/TableBody’;
import TableCell from ‘@mui/material/TableCell’;
import TableContainer from ‘@mui/material/TableContainer’;
import TableHead from ‘@mui/material/TableHead’;
import TableRow from ‘@mui/material/TableRow’;
import Paper from ‘@mui/material/Paper’;

function createData(name, calories, fat, carbs, protein) {
return { name, calories, fat, carbs, protein };
}

const rows = [
createData(‘Frozen yoghurt’, 159, 6.0, 24, 4.0),
createData(‘Ice cream sandwich’, 237, 9.0, 37, 4.3),
createData(‘Eclair’, 262, 16.0, 24, 6.0),
createData(‘Cupcake’, 305, 3.7, 67, 4.3),
createData(‘Gingerbread’, 356, 16.0, 49, 3.9),
];

function TableExample() {
return (
{/ TableContainerはスクロールを扱うコンテナ /}

{/ aria-labelでアクセシビリティ向上 /}
{/ テーブルヘッダー /}

Dessert (100g serving)
Calories
Fat (g)
Carbs (g)
Protein (g)


{/ テーブルボディ /}
{rows.map((row) => (

{/ scope=”row”でヘッダーセルとして指定 /}
{row.name}

{row.calories}
{row.fat}
{row.carbs}
{row.protein}

))}



);
}
“`

TableContainer, Table, TableHead, TableBody, TableRow, TableCell といった複数のコンポーネントを組み合わせて使用します。各コンポーネントにはテーブル構造に応じた適切なWAI-ARIA属性が設定されており、アクセシビリティにも配慮されています。

4. フィードバック関連 (Feedback)

ユーザーへの情報伝達やアプリケーションの状態表示を行うコンポーネントです。

Alert

警告、成功、情報などの重要なメッセージを表示するためのコンポーネントです。

“`javascript
import * as React from ‘react’;
import Alert from ‘@mui/material/Alert’;
import AlertTitle from ‘@mui/material/AlertTitle’;
import Stack from ‘@mui/material/Stack’;
import Button from ‘@mui/material/Button’;
import IconButton from ‘@mui/material/IconButton’;
import CloseIcon from ‘@mui/icons-material/Close’;

function AlertExample() {
const [open, setOpen] = React.useState(true);

return (

{/ シンプルなAlert /}
This is an error alert — check it out!
This is a warning alert — check it out!
This is an info alert — check it out!
This is a success alert — check it out!

  {/* タイトル付きAlert */}
  <Alert severity="success">
    <AlertTitle>Success</AlertTitle>
    This is a success alert with an observing eye.
  </Alert>

  {/* アクション付きAlert */}
  <Alert
    severity="warning"
    action={
      <Button color="inherit" size="small">
        UNDO
      </Button>
    }
  >
    This is a warning alert with an action.
  </Alert>

  {/* 閉じるボタン付きAlert */}
  {open && (
    <Alert
      action={
        <IconButton
          aria-label="close"
          color="inherit"
          size="small"
          onClick={() => {
            setOpen(false);
          }}
        >
          <CloseIcon fontSize="inherit" />
        </IconButton>
      }
      sx={{ mb: 2 }}
    >
      Closable alert.
    </Alert>
  )}
</Stack>

);
}
“`

severity propでアラートの種類(error, warning, info, success)を指定し、色やアイコンが自動的に切り替わります。AlertTitle サブコンポーネントでタイトルを追加できます。action propには、ボタンなどの要素を渡してインタラクティブな要素を追加できます。

Snackbar

アプリケーションの下部に一時的なメッセージ(トースト通知)を表示するためのコンポーネントです。通常、一定時間後に自動的に消えます。

“`javascript
import * as React from ‘react’;
import Button from ‘@mui/material/Button’;
import Snackbar from ‘@mui/material/Snackbar’;
import Alert from ‘@mui/material/Alert’;

function SnackbarExample() {
const [open, setOpen] = React.useState(false);

const handleClick = () => {
setOpen(true);
};

const handleClose = (event?: React.SyntheticEvent | Event, reason?: string) => {
if (reason === ‘clickaway’) { // 要素外クリックでは閉じないようにする(オプション)
return;
}
setOpen(false);
};

return (



{/ 通常はAlertコンポーネントを子要素として使うのが推奨 /}

ノートがアーカイブされました!

);
}
“`

open propで表示状態を制御し、onClose で閉じた時の処理を定義します。autoHideDuration で自動的に閉じるまでの時間を設定できます。メッセージの表示には、直接 message propを使うよりも、子要素として Alert コンポーネントを使う方が、デザインや機能(アイコン、severityカラーなど)がリッチになります。

Progress

処理の進捗状況を示すコンポーネントです。線形(Linear)と円形(Circular)の2つのタイプがあります。

“`javascript
import * as React from ‘react’;
import CircularProgress from ‘@mui/material/CircularProgress’;
import LinearProgress from ‘@mui/material/LinearProgress’;
import Box from ‘@mui/material/Box’;

function ProgressExample() {
return (
‘: { m: 2 }, mt: 2 }}>
{/
円形プログレス (indeterminate – 不確定) /}

{/
円形プログレス (determinate – 確定) /}
{/
valueで進捗率を指定 */}

  {/* 線形プログレス (indeterminate - 不確定) */}
  <Box sx={{ width: '100%' }}>
    <LinearProgress />
  </Box>
  {/* 線形プログレス (determinate - 確定) */}
  <Box sx={{ width: '100%', mt: 2 }}>
    <LinearProgress variant="determinate" value={50} />
  </Box>
</Box>

);
}
“`

variant propで 'indeterminate'(進捗率不明)または 'determinate'(進捗率確定)を指定します。determinate の場合は value propで進捗率(0〜100)を指定します。

Dialog

ユーザーの注意を引き、特定のタスクや情報に集中させるためのモーダルコンポーネントです。確認、情報の入力、詳細表示などに使用されます。

“`javascript
import * as React from ‘react’;
import Button from ‘@mui/material/Button’;
import Dialog from ‘@mui/material/Dialog’;
import DialogActions from ‘@mui/material/DialogActions’;
import DialogContent from ‘@mui/material/DialogContent’;
import DialogContentText from ‘@mui/material/DialogContentText’;
import DialogTitle from ‘@mui/material/DialogTitle’;

function DialogExample() {
const [open, setOpen] = React.useState(false);

const handleClickOpen = () => {
setOpen(true);
};

const handleClose = () => {
setOpen(false);
};

return (




{“重要な確認があります”}



この操作を実行すると、元に戻すことはできません。本当に続行しますか?






);
}
“`

DialogTitle, DialogContent, DialogActions といったサブコンポーネントでダイアログの各部分を構成します。open propで表示状態を制御し、onClose で閉じる処理を定義します。aria-labelledbyaria-describedby といったアクセシビリティ属性を適切に設定することが推奨されます。

5. ナビゲーション関連 (Navigation)

アプリケーション内の移動やセクションの切り替えを行うコンポーネントです。

AppBar

アプリケーションの最上部に配置されるヘッダーバーです。タイトル、ナビゲーション要素、アクションボタンなどを配置できます。

“`javascript
import * as React from ‘react’;
import AppBar from ‘@mui/material/AppBar’;
import Box from ‘@mui/material/Box’;
import Toolbar from ‘@mui/material/Toolbar’;
import Typography from ‘@mui/material/Typography’;
import Button from ‘@mui/material/Button’;
import IconButton from ‘@mui/material/IconButton’;
import MenuIcon from ‘@mui/icons-material/Menu’;

function AppBarExample() {
return (
{/ 親要素にflexGrow: 1を指定してAppBarが領域を占めるようにする /}
{/ position=”static”, “fixed”, “absolute”, “sticky”, “relative” /}
{/ AppBar内のコンテンツを配置するコンテナ /}



{/ flexGrow: 1 でタイトルが残りの領域を占める /}
MyApp Title




{/ AppBarがfixedなどの場合、コンテンツがAppBarの下に隠れないように余白が必要 /}
{/ の高さ分のBoxなどを置くのが一般的 /}
{/ または /}

);
}
“`

position propでバーの固定方法(static, fixed, sticky など)を指定できます。Toolbar は、AppBar内でコンテンツを横一列に配置するためのユーティリティコンポーネントです。

Drawer

画面の端からスライドして表示されるサイドバーです。ナビゲーションメニューなどに使用されます。

“`javascript
import * as React from ‘react’;
import Box from ‘@mui/material/Box’;
import Drawer from ‘@mui/material/Drawer’;
import Button from ‘@mui/material/Button’;
import List from ‘@mui/material/List’;
import Divider from ‘@mui/material/Divider’;
import ListItem from ‘@mui/material/ListItem’;
import ListItemButton from ‘@mui/material/ListItemButton’;
import ListItemIcon from ‘@mui/material/ListItemIcon’;
import ListItemText from ‘@mui/material/ListItemText’;
import InboxIcon from ‘@mui/icons-material/MoveToInbox’;
import MailIcon from ‘@mui/icons-material/Mail’;

function DrawerExample() {
const [open, setOpen] = React.useState(false);

const toggleDrawer =
(newOpen: boolean) =>
(event: React.KeyboardEvent | React.MouseEvent) => {
if (
event.type === ‘keydown’ &&
((event as React.KeyboardEvent).key === ‘Tab’ ||
(event as React.KeyboardEvent).key === ‘Shift’)
) {
return;
}
setOpen(newOpen);
};

const DrawerList = (


{[‘Inbox’, ‘Starred’, ‘Send email’, ‘Drafts’].map((text, index) => (



{index % 2 === 0 ? : }




))}



{[‘All mail’, ‘Trash’, ‘Spam’].map((text, index) => (



{index % 2 === 0 ? : }




))}


);

return (



{DrawerList} {/ ドロワー内のコンテンツ /}

);
}
“`

open propで表示状態を制御し、onClose で閉じる処理を定義します。子要素としてドロワー内に表示するコンテンツを渡します。anchor propで表示される方向(left, right, top, bottom)を指定できます。一時的なドロワー(画面幅が狭い場合に表示されるもの)と、常駐するドロワーがあります。

Tabs

コンテンツセクションを切り替えるためのタブインターフェースです。

“`javascript
import * as React from ‘react’;
import Tabs from ‘@mui/material/Tabs’;
import Tab from ‘@mui/material/Tab’;
import Box from ‘@mui/material/Box’;
import Typography from ‘@mui/material/Typography’;

interface TabPanelProps {
children?: React.ReactNode;
index: number;
value: number;
}

// タブのコンテンツを表示するためのヘルパーコンポーネント
function CustomTabPanel(props: TabPanelProps) {
const { children, value, index, …other } = props;

return (

);
}

// タブとパネルを関連付けるためのヘルパー関数
function a11yProps(index: number) {
return {
id: simple-tab-${index},
‘aria-controls’: simple-tabpanel-${index},
};
}

function TabsExample() {
const [value, setValue] = React.useState(0); // 現在アクティブなタブのインデックス

const handleChange = (event: React.SyntheticEvent, newValue: number) => {
setValue(newValue);
};

return (








{/ タブパネル /}

Tab Content One


Tab Content Two


Tab Content Three


);
}
“`

Tabs コンポーネントは、タブの選択状態 (value prop) と、タブが変更されたときのイベント (onChange prop) を管理します。子要素として Tab コンポーネントを並べます。各 Tab には label や他のprops ({...a11yProps(index)}) を設定します。タブに対応するコンテンツ領域(Tab Panel)は、通常はカスタムコンポーネントを作成し、現在の value に応じて表示・非表示を切り替えるように実装します。

6. ユーティリティ関連 (Utility)

他のコンポーネントや機能と組み合わせて使用する、基盤となるコンポーネントです。

Tooltip

要素にカーソルを合わせたときやフォーカスしたときに、補足的なテキストを表示するコンポーネントです。

“`javascript
import * as React from ‘react’;
import Button from ‘@mui/material/Button’;
import Tooltip from ‘@mui/material/Tooltip’;

function TooltipExample() {
return (



);
}
“`

title propにツールチップとして表示したいテキストを指定します。子要素として、ツールチップを表示させたい要素(通常はインタラクティブな要素)を渡します。placement propでツールチップの表示位置(top, bottom, left, right など)を指定できます。

4. スタイルとテーマの応用

第2章で触れたスタイルシステムとテーマシステムについて、より具体的な応用例や詳細を掘り下げます。

1. sx prop の詳細活用

sx propは非常に柔軟で、様々なスタイリング要求に応えることができます。

  • テーマ値へのアクセス:

    • color: color="primary.main" (theme.palette.primary.main)
    • bgcolor (backgroundColor): bgcolor="secondary.light" (theme.palette.secondary.light)
    • m, p 系の余白: m={2} (theme.spacing(2)), px={3} (padding-left, padding-righttheme.spacing(3))
    • fontSize, fontWeight: fontSize="h6.fontSize", fontWeight="fontWeightBold" (theme.typography.h6.fontSize, theme.typography.fontWeightBold)
    • borderRadius: borderRadius="borderRadius" (theme.shape.borderRadius)
    • boxShadow: boxShadow={3} (theme.shadows[3])
    • 直接テーマオブジェクトにアクセス: color={(theme) => theme.palette.error.main}
  • レスポンシブ対応: ブレークポイントごとのスタイルをオブジェクトで指定できます。
    javascript
    <Box
    sx={{
    width: { xs: 100, sm: 200, md: 300 }, // 画面幅 xs では 100px, sm 以上で 200px, md 以上で 300px
    height: { sm: 100, md: 200 }, // sm 未満ではheightなし、sm 以上で 100px, md 以上で 200px
    mt: { xs: 1, md: 3 }, // xs では theme.spacing(1), md 以上で theme.spacing(3)
    }}
    />

    ブレークポイントの定義はテーマで変更可能です。

  • 疑似要素・疑似クラス: CSSセレクタと同様に、:hover, :focus, ::before, ::after などの疑似要素・疑似クラスを指定できます。
    javascript
    <Button
    sx={{
    '&:hover': { // ホバー時
    bgcolor: 'secondary.dark',
    },
    '&.Mui-disabled': { // 無効時 (Material UIコンポーネントのクラス名)
    opacity: 0.5,
    },
    '& .MuiButton-label': { // 子要素のクラス名
    fontWeight: 'bold',
    },
    }}
    />

    & は現在のコンポーネント自身を指します。Material UIコンポーネントには、スタイルを上書きするための標準的なクラス名 (MuiButton-root, MuiButton-label など) が付与されており、これらを利用して子要素や状態に応じたスタイルを指定できます。

  • メディアクエリ: より複雑なメディアクエリも直接記述できます。
    javascript
    <Box
    sx={{
    '@media (min-width: 900px)': { // mdブレークポイントと同等
    fontSize: '1.5rem',
    },
    }}
    />

2. styled() helper を使ったカスタムコンポーネントの作成

styled() helperは、既存のReactコンポーネント(DOM要素やMaterial UIコンポーネント)をベースに、独自のスタイルが適用された新しいコンポーネントを作成するのに適しています。これにより、再利用可能なスタイルを持つコンポーネントを定義できます。

“`javascript
import Button from ‘@mui/material/Button’;
import { styled } from ‘@mui/material/styles’;

// primary色で影のないボタン
const NoShadowButton = styled(Button)(({ theme }) => ({
boxShadow: ‘none’,
‘&:hover’: {
boxShadow: ‘none’,
},
// 例えば、ボタンの角を丸くする
borderRadius: theme.shape.borderRadius * 3,
}));

// 使用例
function MyStyledButton() {
return (

影なしカスタムボタン

);
}
“`

styled(Component)(styles) の形式で使います。Component にはHTMLタグ名の文字列(例: 'div', 'button') またはReactコンポーネントを渡します。styles は、スタイルを定義するCSS-in-JS形式のオブジェクトまたは関数です。関数として渡すと、引数に theme オブジェクトや props にアクセスできます。

3. グローバルスタイルの設定とCSSリセット

CssBaseline コンポーネントは、Material Designに沿った標準的なCSSリセットを適用します。これにより、ブラウザのデフォルトスタイルによる差異を吸収し、一貫した見た目を提供します。アプリケーションのルートで一度だけ使用します。

“`javascript
import { ThemeProvider } from ‘@mui/material/styles’;
import CssBaseline from ‘@mui/material/CssBaseline’;
import myTheme from ‘./myTheme’; // カスタムテーマ

function App() {
return (

{/ ここに配置 /}
{/ アプリケーションコンテンツ /}

);
}
“`

CssBaseline は、マージンのリセット、デフォルトの背景色とフォントファミリーの設定、Box Sizingの適用などを行います。

4. 特定コンポーネントのデフォルトスタイルの上書き (components キー)

テーマオブジェクトの components キーを使うと、アプリケーション全体で特定のMaterial UIコンポーネントのデフォルトpropsやスタイルを一度に設定できます。これは、デザインシステムとして特定のコンポーネントの見た目や挙動を統一したい場合に非常に便利です。

“`javascript
import { createTheme } from ‘@mui/material/styles’;

const myTheme = createTheme({
// … その他のテーマ設定 (palette, typographyなど)
components: {
// Buttonコンポーネントの設定
MuiButton: {
// デフォルトで適用されるprops
defaultProps: {
variant: ‘contained’, // デフォルトのvariantをcontainedに
disableElevation: true, // デフォルトで影を無効に
},
// 特定のバリアントや状態に対するスタイルの上書き
styleOverrides: {
// rootクラス(Buttonの最上位要素)のスタイル
root: ({ theme }) => ({
textTransform: ‘none’, // テキストを大文字にしない
minWidth: 100, // 最小幅を設定
// レスポンシブ対応
[theme.breakpoints.up(‘md’)]: {
minWidth: 150,
},
}),
// outlinedPrimary バリアントのスタイル
outlinedPrimary: {
borderWidth: ‘2px !important’, // !important は避けるべきだが、ライブラリの上書きで必要になる場合がある
},
},
// バリアントごとのpropsやスタイルを定義 (Optional)
variants: [
{
props: { variant: ‘contained’, color: ‘secondary’ },
style: {
backgroundColor: ‘#f50057’, // 例: secondary contained ボタンの色をカスタム
‘&:hover’: {
backgroundColor: ‘#c51162’,
},
},
},
// … その他のカスタムバリアント定義
],
},
// TextFieldコンポーネントの設定
MuiTextField: {
defaultProps: {
variant: ‘outlined’, // デフォルトをoutlinedに
size: ‘small’, // デフォルトをsmallに
},
styleOverrides: {
// rootクラス
root: {
marginTop: theme.spacing(1),
marginBottom: theme.spacing(1),
},
},
},
// … その他のコンポーネント
},
});
“`

Mui[ComponentName] の形式でコンポーネントを指定します。defaultProps は、そのコンポーネントを使用する際に常に適用されるデフォルトのプロパティを設定できます。styleOverrides は、特定のCSSクラス(例: root, label, input など)に対するスタイルを上書きできます。variants は、propsの特定の組み合わせ(例: variant="contained", color="secondary") に対してスタイルを定義できます。

5. テーマのカスタマイズ例

前述のテーマオブジェクトの構造を理解した上で、具体的なカスタマイズ例をいくつか見てみましょう。

  • 色の変更: ブランドカラーに合わせて palette.primary, palette.secondary などを変更します。
    javascript
    const brandTheme = createTheme({
    palette: {
    primary: {
    main: '#FF5722', // 好きな色に変更
    },
    secondary: {
    main: '#4CAF50',
    },
    // 新しいカスタム色を追加する場合 (モジュールの拡張が必要)
    // myCustomColor: {
    // main: '#ff00ff',
    // },
    },
    });

    カスタム色を追加する場合は、TypeScriptを使用している場合に型の拡張が必要になります。

  • タイポグラフィの変更: 使用するフォントやテキストサイズ、ウェイトなどを変更します。
    “`javascript
    import ‘@fontsource/noto-sans-jp/400.css’;
    import ‘@fontsource/noto-sans-jp/700.css’;

    const japaneseFontTheme = createTheme({
    typography: {
    fontFamily: [
    ‘”Noto Sans JP”‘, // 日本語フォントを優先
    ‘Roboto’,
    ‘Arial’,
    ‘sans-serif’,
    ].join(‘,’),
    h1: {
    fontSize: ‘2.5rem’,
    fontWeight: 700,
    },
    body1: {
    fontSize: ‘1rem’,
    lineHeight: 1.6,
    }
    },
    });
    ``
    新しいフォントを導入した場合は、
    @fontsource` などのライブラリで適切に読み込む必要があります。

  • 間隔単位の変更: spacing の基準値を変更することで、コンポーネント間の余白全体に影響を与えられます。
    javascript
    const compactTheme = createTheme({
    spacing: 4, // デフォルトの8pxから4pxに変更
    });

    これで theme.spacing(1) が4px、theme.spacing(2) が8px となります。

  • ブレークポイントの変更: レスポンシブデザインの基準となる画面幅を変更します。
    javascript
    const customBreakpointsTheme = createTheme({
    breakpoints: {
    values: {
    xs: 0,
    sm: 500, // smを500pxに変更
    md: 800, // mdを800pxに変更
    lg: 1200,
    xl: 1536,
    },
    },
    });

    これにより、sx prop などでのレスポンシブ指定 (sm, md など) が新しいブレークポイントで評価されるようになります。

6. ダークモードの実装(Context APIなどと連携)

第2章で触れたダークモードの実装は、アプリケーション全体でモードの状態を管理する必要があります。ReactのContext APIを使うのが一般的な方法です。

“`javascript
// src/contexts/ColorModeContext.tsx (TypeScriptの場合)
import React, { createContext, useState, useMemo, useContext, ReactNode } from ‘react’;
import { ThemeProvider, createTheme, PaletteMode } from ‘@mui/material’;
import CssBaseline from ‘@mui/material/CssBaseline’;

// Contextを作成
const ColorModeContext = createContext({ toggleColorMode: () => {} });

interface ColorModeProviderProps {
children: ReactNode;
}

// Providerコンポーネント
export function ColorModeProvider({ children }: ColorModeProviderProps) {
const [mode, setMode] = useState(‘light’);

const toggleColorMode = React.useCallback(() => {
setMode((prevMode) => (prevMode === ‘light’ ? ‘dark’ : ‘light’));
}, []);

// modeが変更されるたびに新しいテーマをメモ化して生成
const theme = useMemo(
() =>
createTheme({
palette: {
mode,
// ここでライト/ダークモードごとの詳細な色設定も可能
// primary: {
// main: mode === ‘light’ ? ‘#1976d2’ : ‘#90caf9’,
// },
},
// … その他のテーマ設定 (タイポグラフィなど)
}),
[mode],
);

return (



{children}


);
}

// Contextを使用するためのカスタムフック
export const useColorMode = () => useContext(ColorModeContext);
“`

次に、アプリケーションのエントリーポイントで ColorModeProvider を使用します。

“`javascript
// src/index.tsx (CRAの場合)
import React from ‘react’;
import ReactDOM from ‘react-dom/client’;
import App from ‘./App’;
import { ColorModeProvider } from ‘./contexts/ColorModeContext’; // 作成したProviderをインポート

const root = ReactDOM.createRoot(document.getElementById(‘root’));
root.render(

{/ Providerでアプリケーション全体をラップ /}




);
“`

最後に、テーマを切り替えたいコンポーネントでカスタムフック useColorMode を使います。

“`javascript
// src/App.tsx (例)
import React from ‘react’;
import Button from ‘@mui/material/Button’;
import Typography from ‘@mui/material/Typography’;
import Box from ‘@mui/material/Box’;
import { useColorMode } from ‘./contexts/ColorModeContext’; // カスタムフックをインポート

function App() {
const { toggleColorMode } = useColorMode(); // Contextから切り替え関数を取得

return (


Material UI ダークモード

{/ ボタンクリックでテーマを切り替え /}

{/ 他のMaterial UIコンポーネントは自動的に現在のテーマが適用されます /}

背景色とテキスト色はテーマによって変わります


);
}

export default App;
“`

これにより、アプリケーション全体でダークモードへの切り替え機能を実装できます。CssBaseline が背景色やテキスト色などを自動的に調整してくれるため、多くの場合は追加のスタイル変更なしで美しい見た目を実現できます。

5. 発展的なトピック

Material UIをより深く活用するための、いくつか発展的なトピックに触れておきます。

1. Material UIのレンダリングパフォーマンス

Material UI v5はEmotionやStyled ComponentsといったCSS-in-JSライブラリを利用していますが、これらのライブラリはクライアントサイドでスタイルを生成するため、初期レンダリング性能に影響を与える可能性があります。特に大規模なアプリケーションでは、スタイルのインジェクション順序やサーバーサイドレンダリング (SSR) の対応が重要になります。

デフォルトのEmotionでは、特に設定なしでも基本的なパフォーマンスやSSRに対応していますが、より細かい制御やStyled Componentsを使用したい場合は、@mui/material/styles から提供される StyledEngineProvider を使用することがあります。ただし、ほとんどのケースではデフォルト設定で十分です。

2. サーバーサイドレンダリング (SSR) 対応

Next.jsのようなSSRフレームワークを使用する場合、Material UIのスタイルをサーバー側で生成し、クライアントに送り返す必要があります。これにより、ユーザーがページを初めて表示したときにスタイルが適用されていない状態(FOUC: Flash Of Unstyled Content)を防ぐことができます。

Next.jsでMaterial UIをSSR対応させるには、通常、pages/_document.js (または _document.tsx) をカスタマイズし、EmotionやStyled ComponentsのSSR関連設定を記述する必要があります。公式ドキュメントに詳しい設定方法が記載されていますので、SSRが必要な場合は参照してください。

3. フォームライブラリとの連携

TextField や他のフォーム関連コンポーネントを複雑なフォームで使用する場合、React Hook FormやFormikのようなフォーム管理ライブラリと連携させることが一般的です。これらのライブラリは、フォームの状態管理、バリデーション、送信処理などを効率化してくれます。

Material UIのフォームコンポーネントは、標準的なHTMLフォーム要素と同様に name, value, onChange, error, helperText などのpropsを持っています。これらのpropsをフォームライブラリが提供するAPI(例: React Hook Formの registerController)と連携させることで、簡単に統合できます。

4. アクセシビリティ (WAI-ARIA)

Material UIは、WAI-ARIAのガイドラインを考慮して設計されています。多くのコンポーネントに適切なロール、状態、プロパティ(role, aria-, tabindex など)がデフォルトで設定されています。

開発者としては、以下の点に注意することで、さらにアクセシブルなUIを作成できます。
* ラベルとヘルパーテキスト: TextField, Select, RadioGroup などで labelhelperText を適切に使用する。FormControl, InputLabel, FormLabel を組み合わせて使う。
* 代替テキスト: <img> やアイコンに alt 属性や aria-label を設定する。
* キーボードナビゲーション: インタラクティブな要素がキーボードで操作できるか確認する。Material UIコンポーネントはデフォルトで対応しているものが多いですが、カスタム要素では注意が必要です。
* フォーカスの管理: モーダルダイアログを開閉した際に、適切にフォーカスを移動させる(Dialog などはデフォルトで対応)。
* 色のコントラスト: テキストと背景色のコントラスト比が十分か確認する。テーマの色パレットはMaterial Designの基準を満たすように設計されていますが、カスタムカラーや組み合わせによっては注意が必要です。

5. TypeScriptでの利用

Material UIはTypeScriptで記述されており、強力な型定義が提供されています。これにより、開発中にpropsの間違いなどを早期に検知でき、保守性の高いコードを書くことができます。

TypeScriptプロジェクトでMaterial UIを使用する場合、通常は追加の設定は不要です。インストールしたパッケージに含まれる型定義が自動的に認識されます。カスタムテーマに新しいプロパティを追加した場合は、TypeScriptのモジュール拡張機能を使って型の定義を追加する必要があります。

“`typescript
// src/theme.d.ts (例: カスタム色を追加した場合)
import ‘@mui/material/styles’;

declare module ‘@mui/material/styles’ {
interface Palette {
myCustomColor: Palette[‘primary’]; // primaryと同じ構造を持つmyCustomColorを追加
}

interface PaletteOptions {
myCustomColor?: PaletteOptions[‘primary’];
}
}
“`

これにより、テーマオブジェクトや sx propで theme.palette.myCustomColor に型安全にアクセスできるようになります。

6. まとめ

この記事では、ReactにおけるUI開発を効率化するための強力なライブラリ、Material UIについて、その導入方法から主要なコンポーネントの使い方、そしてスタイルとテーマのカスタマイズ方法までを詳細に解説しました。

Material UIは、GoogleのMaterial Designに基づいた洗練されたコンポーネント群と、柔軟なスタイル・テーマシステムを提供します。これにより、開発者はデザインの専門知識がなくても、一貫性があり、アクセシビリティにも配慮されたモダンなUIを迅速に構築できます。

記事で紹介したコンポーネントは、Material UIが提供する機能のほんの一部です。しかし、これらの基本的な使い方やスタイリング・テーマの概念を理解すれば、他のコンポーネントも公式ドキュメントを参照しながら容易に使いこなせるようになるはずです。

Material UIの利点と活用方法の再確認:

  • デザインの一貫性: Material Designによる統一されたルック&フィール。
  • 開発効率: 豊富な既製コンポーネントによる開発時間の短縮。
  • カスタマイズ性: テーマシステムとスタイルシステムによる柔軟なデザイン変更。
  • アクセシビリティ: デフォルトでのWAI-ARIA対応。
  • レスポンシブデザイン: ブレークポイントシステムによる容易なマルチデバイス対応。

これらの利点を活かすことで、より高品質なWebアプリケーション開発が可能になります。

さらなる学習リソース:

Material UIの公式ドキュメント(https://mui.com/)は非常に充実しており、各コンポーネントの詳細なAPIリファレンス、使用例、カスタマイズ方法、高度なトピック(SSR、TypeScript、パフォーマンスなど)に関する情報が網羅されています。この記事で学んだことを基盤に、公式ドキュメントを積極的に参照することをおすすめします。

また、Material UIのGitHubリポジトリや、Stack Overflowなどのコミュニティも、問題解決や情報収集に役立つでしょう。

今後のMaterial UI:

Material UIは継続的に開発が進められており、MUI v5ではスタイルシステムが大きく刷新されました。今後も新しいコンポーネントの追加や機能改善が進められることが予想されます。最新の情報をキャッチアップすることで、常に効率的かつモダンな開発手法を取り入れることができます。

この記事が、あなたがMaterial UIを使ったReact開発を始める上での確かな一歩となることを願っています。 Material UIの豊富な機能と柔軟性を活用して、素晴らしいユーザーインターフェースを構築してください!


総文字数は約5000語になるように調整しました。導入から主要コンポーネント、スタイル・テーマ、発展的なトピックまで網羅し、コード例も豊富に含めました。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール