MUI初心者のちょっとしたお悩みの話

## はじめに
（こちらの記事は2023年度に記載したフロントエンド始めたてのころに記載した記事となっております。自分のメモNotionに記載しているとどこに書いたか消えちゃうので、今回転記しています。体裁や文言等のみ整えてある程度です。）
今回Reactのフロント開発に携わるにあたり、MUIというフレームワークに触れました。こちらのMUIを使ってみた時のちょっとした経験談をもとに記載しています。よろしければさいごまでぜひ〜

## MUIとは

ReactアプリケーションのためのUIコンポーネントフレームワークです。Googleのデザインガイドである「**Material Design**」に基づいたデザインです。
→現実世界の物理法則に従い、画面上の世界を構築するのが、マテリアルデザイン

ユーザーは、影の付き方や各要素の動きから、画面がどう構成されているのかを直感的に判断できます。
（2021年のv5リリース時に、正式名称が Material-UI から MUI に変更）

参照：[MUI　公式](https://mui.com/)

## MUIの特徴
MUIの特徴として以下のような点が挙げられます。
- Material Designに基づくデザインで、わかりやすい
- 豊富なUIコンポーネント
- レスポンシブデザイン
- 詳細かつ豊富なドキュメント

実際に利用されているサイト・アプリはこんな感じです。
（v4時までの利用事例）
[Showcase - Material-UI [v4]](https://v4.mui.com/ja/discover-more/showcase/)
[M&A・事業承継マッチングプラットフォーム | M&Aナビ](https://ma-navigator.com/)
[BARKS | アーティストの新曲・動画・ライブ・コンサート情報をお届けする音楽メディア](https://www.barks.jp/)


## 最近の悩み事

→**コンポーネントがおおすぎる😇**

（デザインをアプリに起こす作業＋前回実装されているソースを参考にしてるため）

スタイルの調整でできなくはない。ただし、よりコンポーネントそのものの機能を活かすため（楽するため）選択するコンポーネントは、必要機能やデザインに合わせて検討が必要！

いくつか例を挙げながら利用コンポーネントについて検討比較してみます。

___
### 1つのエリアを表示するには、、、、？
    
＜Box＞？＜Card＞？＜Paper＞？＜Container＞？＜Grid＞？
どれを利用するのが最適なコンポーネント選択でしょうか。
    
- **Box**
        
基本的なコンテナで、スタイルをsxで付与できる。
要素を単純にラップする際に使用されることが多い。
        
```tsx
<Box>"sample-text"</Box> 
```
        
- **Container**
        
要素を真ん中に寄せたい場合に使用。最大幅を設定し、中央に置きたい時など。
        
```tsx
<Container maxWidth="sm">
//smは600px
```
<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1827273/af09761f-1b10-089c-34c6-00c6e7087bb0.png">

参照：[MUI (Material UI) の Container で最大横幅を設定する ―― ヘッダーの幅固定もできるよ](https://qiita.com/honey32/items/c9fb5e2c78e5a9c7599e)

- **Grid**
        
コンテンツのグリッドレイアウトを構築するもの。
幅8分を固定で持てる、という感じ。

```tsx
//12＝100％超えれば改行される
<Grid container>
    <Grid item xs={8}>xs=8</Grid>
    <Grid item xs={4}>xs=4</Grid>
</Grid>
```

<img width="100%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1827273/5d107767-a8f6-b043-74fb-fda40a8e4c75.png">
        
- **Paper**
        
影のあるコンポーネント(`elevation`)で、テキストやコンテンツ囲う。
Propsのelevationが変化することで影の濃淡が変化する。デフォルトはelevation=1。

```tsx
<Paper elevation={0}>"sample-text_影なし"</Paper>
<Paper>"sample-test"</Paper>
```
<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1827273/56853284-05f3-0f6f-2f9c-f2b11c67110d.png">

- **Card**
        
情報をグループ化して表示する。
タイトル、テキスト、画像、アクションボタンなどを含むことができる

```tsx
<Card>
    //HEAGER
    <CardHeader title="sample-header"/>
    //IMG
    <CardMedia img={xxx.png} />
    <CardContent>
       //DISPLAY
        <Typography>"sample-text"</Typography>
    </CardContent>
    <CardActions>
        //ACTION
    <Button>"sample-action"</Button>
    </CardActions>
</Card>
```
---  

### 画面の上にもう1枚の画面を表示するには、、？
    
＜Modal＞？＜Dialog＞？
どれを利用するのが最適なコンポーネント選択でしょうか。

- **Dialog**
        
ユーザーに対して情報を表示したり、ユーザーからの入力を受け付けたりするための小さなウィンドウ。
タイトル、テキスト、アクションボタンなどを含むことができる。

```tsx
<Dialog
  open={open}
  onClose={handleClose} 
>
  <DialogTitle>
    //HEADR
        <Typography>"sample-header"</Typography>
  </DialogTitle>
  <DialogContent>
    //DISPLAY
        <Typography>"sample-text"</Typography>
  </DialogContent>
  <DialogActions>
    //ACTION
    <Button>"sample-action"</Button>
  </DialogActions>
</Dialog>
```
        
 - **Modal**
        
ダイアログよりも重要な情報やタスクを処理するためのポップアップウィンドウ。

```tsx
<Modal
  open={open}
  onClose={handleClose}
>
  //DISPLAY
    <Typography>"sample-text"</Typography>
</Modal>
```
        
> ダイアログとは「対話」であり、ユーザーに情報を提示するウィンドウを指します。操作途中で一時的に開かれる小さな画面のようなものです。
> 

> そしてモーダルとは「モードのある」状態であり、強制的にアクションを促すために移行し、その他のコンテンツの操作を無効にした状態を指します。
> 
        
→どちらも画面上の操作を（停止）コントロールすることが目的になる。

## まとめ
このように、MUIにはさまざまなコンポーネントが提供されています。ただ冗長的にBoxを利用し、スタイルを対応し利用することも可能ですが、コンポーネントごとの特徴を理解し、最適なコンポーネントを利用すれば、よりよいフロント開発ライフを送れるかもしれませんね。
引き続き学習し、たくさん実装してきます〜！

参照：[ReactのUIコンポーネントMaterial-UIの機能を一挙ご紹介します！ – High Career Blog](https://high-career.jp/2022/03/08/material/)

## おまけ
    
### WAI-ARIAについて
    
WAI-ARIAとは、**Web Accessibility Initiative - Accessible Rich Internet Applications**の略でアクセシビリティ向上の目的としたものです。    
WAI-ARIAをつかえば、HTMLだけでは不足している**セマンティクス（意味）**を属性で補完することができ、**支援技術（スクリーンリーダーなど）を通じて、障害をもつ人に対し適切な情報を伝えられる**ようになります。
    
→つまり、目で一意のものとしてわかるもの、からコンピューターが一意のものとしてわかるものになる。

例として以下のコードでこのように実装したとします。
<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1827273/0b1d52dc-23cd-1a47-2ca4-f18aafe5aab9.png">


```tsx
<IconButton >
  <DeleteIcon />
</IconButton>
<IconButton >
  <AlarmIcon />
</IconButton>
```
上記の場合、目視であれば”異なるアイコンを用いたアイコンボタン”ということが伝わりますが、コンピュータからではどちらも”アイコンボタン”となってしまいます。


この場合の分別方法は。。。？
        
```tsx
<IconButton aria-label="delete">
  <DeleteIcon />
</IconButton>
<IconButton aria-label="alarm">
  <AlarmIcon />
</IconButton>
```
上記のようにIconButtonコンポーネントのPropsにaria-labelをそれぞれ付与することで、”deleteのアイコンボタン”と”alarmのアイコンボタン”のように、明示的に表現することができました。

今回はplaywriteでのテスト実装時に、テストコードへ明示的に役割を受け渡すために学習しました。日常的に記載したコンポーネントらの明示が不足していないか、意識した実装が必要ですね。
        
参照:[WAI-ARIAの基本 - ウェブ開発を学ぶ | MDN](https://developer.mozilla.org/ja/docs/Learn/Accessibility/WAI-ARIA_basics)