【React TypeScript】Material UIのTextFeildやAvater、ChipでFormのレイアウトを作成する!

【React TypeScript】Material UIのTextFeildやAvater、ChipでFormのレイアウトを作成する!
  • URLをコピーしました!

今回は、Material UIのTextFeildやAvater、ChipでFormのレイアウトを作成していきます!
Material UIは過去記事でも紹介しているので、今回は総集編みたいな感じになると思います。

まだ、React TypeScriptの開発環境を未構築の方は、「ReactとTypeScriptとRedux Toolkitの開発環境構築をしよう!」を参考にしてみてください!

本記事はReact・TypeScript・Redux Toolkitの利用を前提に実装をしていきます。
構築からデプロイまでやっていきますので、必要に応じて他の記事も参考にしてみてください。

学習に使った本はこちら!

¥24 (2024/04/15 17:44時点 | Amazon調べ)
\最大8%ポイントアップ!/
Amazon
¥3,839 (2024/04/18 18:13時点 | Amazon調べ)
\最大8%ポイントアップ!/
Amazon
¥700 (2024/04/17 16:11時点 | Amazon調べ)
\最大8%ポイントアップ!/
Amazon
クマじい

Amazon Kindle Unlimited でもReactの本はいっぱいあるぞ!

  • 技術書をたくさん読みたい!
  • 色々な技術を学びたい!
初回30日間無料体験があるので、どのような参考書があるか確認してみよう!

Kindle Unlimitedで技術書を読むならタブレットがあるとさらに便利ですよ!
10インチあるとより見やすいと思いますが、7インチでも十分見やすくなります!

目次

ページを作成しよう!

まずは、フォームを表示するページを作成しましょう。

もし過去の記事から見てくれている方であれば、Sample2Page.tsxは作られていると思いますので、必要な箇所だけ参考にしてもらえればと思います。

必要なファイルを用意する。

まずは、フォームを表示するページを作成するために、Sample2Page.tsxとSample2Page.module.scssを作成します。

  • components>pages>sample2Page>Sample2Page.tsxを作成
  • components>pages>sample2Page>Sample2Page.module.scssを作成

必要なファイルを用意する。

まずは、フォームを表示するページを作成するために、Sample2Page.tsxとSample2Page.module.scssを作成します。

  • components>pages>sample2Page>Sample2Page.tsxを作成
  • components>pages>sample2Page>Sample2Page.module.scssを作成

Sample2Page.tsxを修正する。

先ほど作成したSample2Page.tsxに雛形コードを追加していきます。

  • 詳細は基本的にソースコードを参照してください!
  • 前回までと唯一違う点は、<form></form>です。
    入力・送信フォームには、ほぼ必須のタグになります。
import React from "react";
import { RouteComponentProps } from "react-router-dom";
import { Link } from "react-router-dom";
import Button from "@material-ui/core/Button";
import { Path } from "../../../Routes";

type PropsTypes = RouteComponentProps;

const Sample2Page = ({ history }: PropsTypes): JSX.Element => {
  return <div>
    <form>
      //ここにFormを実装していく
    </form>
  </div>;
};

export default Sample2Page;

SUBMITボタンとCANCELボタンを追加する。

雛形を追加したSample2Page.tsxに、SUBMITボタンとCANCELボタンを作成しましょう。

  • SUMBITボタンは、type=”submit”にすることでフォームの内容を送信できるようになります。
  • CANCELは、type=”button”として、onClickにキャンセルの実装をしていきます。
import React from "react";
// react-router-dom
import { RouteComponentProps } from "react-router-dom";
import { Link } from "react-router-dom";
import { Path } from "../../../Routes";
// material-ui
import Button from "@material-ui/core/Button";
// styels
import styles from "./Sample2Page.module.scss";

type PropsTypes = RouteComponentProps;

const Sample2Page = ({ history }: PropsTypes): JSX.Element => {
  return (
    <div>
      <form className={styles.form}>
        <div className={styles.button_wrapper}>
          <Button
            type="submit"
            variant="contained"
            color="primary"
            className={styles.submit_button}
          >
            SUBMIT
          </Button>
          <Button
            type="button"
            variant="contained"
            color="secondary"
            onClick={() => null}
            className={styles.cancel_button}
          >
            CANCEL
          </Button>
        </div>
      </form>
    </div>
  );
};

export default Sample2Page;

ボタンのスタイルを修正する。

今のままでも良いのですが、marginを入れたり、右寄せにしておきたいのでStyleを追加していきます。
Sample2Page.module.scssを修正していきましょう!

  • ここは特殊なことはしていないので詳細は省きます。
  • 各ボタンの間隔を空けて、右寄せにしています。
.root {
  .form {
    .button_wrapper {
      display: flex;
      justify-content: flex-end;
      align-items: flex-end;
      margin: 20px;
      .submit_button,
      .cancel_button {
        margin: 5px;
      }
    }
  }
}

GridとBoxでレイアウトを整える。

GridとBoxを使って、今回作成するFormのレイアウトを作成していきましょう!
本来なら適切な粒度でコンポーネント分けするのですが、説明の関係上全てSample2Page.tsxに実装していきます。
Grid単位でコンポーネント分けしていれば、コードリーディングもしやすくなると思いますよ!

  • 詳細は、画面を見た方がわかりやすいと思うので、動作確認してみましょう!
import React from "react";
// react-router-dom
import { RouteComponentProps } from "react-router-dom";
import { Link } from "react-router-dom";
import { Path } from "../../../Routes";
// material-ui
import { Button, Grid, Box, Card } from "@material-ui/core";
// styels
import styles from "./Sample2Page.module.scss";

type PropsTypes = RouteComponentProps;

const Sample2Page = ({ history }: PropsTypes): JSX.Element => {
  return (
    <div className={styles.root}>
      <form className={styles.form}>
        <Grid container justifyContent="center" alignItems="center" spacing={3}>
          <Grid container spacing={3} item xs={3}>
            <Grid item xs={12}>
              <Card className={styles.card}>画像アップロード</Card>
            </Grid>
          </Grid>
          <Grid container spacing={3} item xs={9}>
            <Grid item xs={12}>
              <Card className={styles.card}>名前</Card>
              <Card className={styles.card}>ふりがな</Card>
              <Card className={styles.card}>生年月日</Card>
              <Card className={styles.card}>出身地</Card>
              <Card className={styles.card}>入社年月日</Card>
            </Grid>
          </Grid>
          <Grid container spacing={3} item xs={12}>
            <Grid item xs={12}>
              <Card className={styles.card}>Github</Card>
              <Card className={styles.card}>Twitter</Card>
              <Card className={styles.card}>Facebook</Card>
              <Card className={styles.card}>Instagram</Card>
              <Card className={styles.card}>Website</Card>
            </Grid>
          </Grid>
          <Grid container spacing={3} item xs={12}>
            <Grid item xs={12}>
              <Card className={styles.card}>PieChart1</Card>
              <Card className={styles.card}>PieChart2</Card>
              <Card className={styles.card}>PieChart3</Card>
              <Card className={styles.card}>PieChart4</Card>
            </Grid>
          </Grid>
          <Grid container spacing={3} item xs={12}>
            <Grid item xs={12}>
              <Card className={styles.card}>chipCard</Card>
            </Grid>
          </Grid>
          <Grid container spacing={3} item xs={12}>
            <Grid item xs={12}>
              <Card className={styles.card}>Text1</Card>
              <Card className={styles.card}>Text2</Card>
              <Card className={styles.card}>Text3</Card>
            </Grid>
          </Grid>
        </Grid>
        <Box component="span" m={2} className={styles.button_wrapper}>
          <Button
            type="submit"
            variant="contained"
            color="primary"
            className={styles.submit_button}
          >
            SUBMIT
          </Button>
          <Button
            type="button"
            variant="contained"
            color="secondary"
            onClick={() => null}
            className={styles.cancel_button}
          >
            CANCEL
          </Button>
        </Box>
      </form>
    </div>
  );
};

export default Sample2Page;

動作確認をする。

ここまでできたら動作確認をしていきましょう!

画像アップロードと名前等の部分は、Gridで3:9にしています。
それ以外は基本的に12になっているので問題ないかなと思います。

クマじい

次は、Cardそれぞれに入力フォームを入れていくということじゃな?

入力ボタン・入力欄を作成しよう!

作成したページに入力ボタンや入力欄を実装していきましょう!

Avatarボタンを作成する。

画像アップロードのCardの場所に、Avaterを使ったボタンを作成していきます。
AvaterをIconButtonでラップしてあげることで、AvaterをIconButtonとして利用することができます。

今後は、Avaterにはアイコンなどが入ってくる想定であり、設定されているものを表示してあげるのにも便利です。

<Grid item xs={12}>
  <div className={styles.upload_button}>
    <Tooltip title="add">
      <IconButton className={styles.icon_button}>
        <Avatar className={styles.avatar}>
          <AddAPhotoIcon />
        </Avatar>
      </IconButton>
    </Tooltip>
  </div>
</Grid>

Sample2Page.module.scssも修正しておきましょう。

.root {
  .form {
    .upload_button {
      display: flex;
      justify-content: center;
      align-items: center;
      .icon_button {
        .avatar {
          width: 150px;
          height: 150px;
        }
      }
    }
    .button_wrapper {
      display: flex;
      justify-content: flex-end;
      align-items: flex-end;
      margin: 20px;
      .submit_button,
      .cancel_button {
        margin: 5px;
      }
    }
  }
}

動作確認するとこんな感じになっていると思います。
Tooltipもつけているので、マウスオーバーでツールチップが表示されますね!

TextFieldを作成する。

Material UIのText Fieldを使ってテキスト入力欄を作成していきます。
Text Fieldもサンプルがたくさんありますが、今回はシンプルなものを参考にしています。

生年月日などはカレンダーで入力できるように「material-ui pickersとdata-fns」を利用しています。
ここに関しては、今回説明すると長くなりすぎるので別途「Material UI pickersを利用して、カレンダー入力を実装しよう!」を参照してください。
カレンダーが必要なければ、Textなどで対応してもらえれば良いと思います。

<Grid item xs={12}>
  <TextField
    margin="normal"
    id="name"
    label="名前"
    fullWidth
    className={styles.text_field}
  />
  <TextField
    margin="normal"
    id="kana"
    label="ふりがな"
    fullWidth
    className={styles.text_field}
  />
  <MuiPickersUtilsProvider utils={DateFnsUtils}>
    <KeyboardDatePicker
      margin="normal"
      id="birthday"
      label="生年月日"
      format="MM/dd/yyyy"
      value={new Date("2014-08-18T21:11:54")}
      onChange={() => null}
      fullWidth
    />
  </MuiPickersUtilsProvider>
  <TextField
    margin="normal"
    id="birthplace"
    label="出身地"
    fullWidth
    className={styles.text_field}
  />
  <MuiPickersUtilsProvider utils={DateFnsUtils}>
    <KeyboardDatePicker
      margin="normal"
      id="birthday"
      label="生年月日"
      format="MM/dd/yyyy"
      value={new Date("2014-08-18T21:11:54")}
      onChange={() => null}
      fullWidth
    />
  </MuiPickersUtilsProvider>
</Grid>

画面を確認すると入力欄が表示されたと思います。
入力欄が大きいような気もしますが、一旦これで進めていきます。

アイコン付きTextFieldを作成する。

上記で作成したTextFieldでも良いのですが、せっかくなのでアイコン付きのTextFieldも作成しておきます!
アイコンはお好きなものをインポートしてもらえれば良いと思います。

<Grid item xs={12}>
  <TextField
    margin="normal"
    id="github"
    label="GitHub"
    fullWidth
    className={styles.text_field}
    InputProps={{
      startAdornment: (
        <InputAdornment position="start">
          <GitHubIcon />
        </InputAdornment>
      ),
    }}
  />
  <TextField
    margin="normal"
    id="twitter"
    label="Twitter"
    fullWidth
    className={styles.text_field}
    InputProps={{
      startAdornment: (
        <InputAdornment position="start">
          <TwitterIcon />
        </InputAdornment>
      ),
    }}
  />
  <TextField
    margin="normal"
    id="facebook"
    label="Facebook"
    fullWidth
    className={styles.text_field}
    InputProps={{
      startAdornment: (
        <InputAdornment position="start">
          <FacebootIcon />
        </InputAdornment>
      ),
    }}
  />
  <TextField
    margin="normal"
    id="instagram"
    label="Instagram"
    fullWidth
    className={styles.text_field}
    InputProps={{
      startAdornment: (
        <InputAdornment position="start">
          <InstagramIcon />
        </InputAdornment>
      ),
    }}
  />
  <TextField
    margin="normal"
    id="web"
    label="Web"
    fullWidth
    className={styles.text_field}
    InputProps={{
      startAdornment: (
        <InputAdornment position="start">
          <WebIcon />
        </InputAdornment>
      ),
    }}
  />
</Grid>

こんな感じのアイコン付きTextFieldが作れたかなと思います。

Chipをボタンとして利用できるようにする。

前回までを見てくれている方であれば、Chipの使い方は理解できていると思いますが、次はChipをボタンとして利用していこうと思います。

interface ChipData {
  key: number;
  label: string;
  level: number;
}

...省略...

const [chipData, setChipData] = React.useState<ChipData[]>([
    { key: 0, label: "Angular", level: 1 },
    { key: 1, label: "jQuery", level: 2 },
    { key: 2, label: "Polymer", level: 3 },
    { key: 3, label: "React", level: 2 },
    { key: 4, label: "Vue.js", level: 1 },
  ]);

...省略...

<Grid item xs={12}>
  <Card className={styles.chip_card}>
    <CardHeader title="chipselect" className={styles.card_header} />
    <CardContent>
      {chipData.map((data) => {
         let icon = (
           <SentimentVeryDissatisfiedIcon
             className={styles.verydissatisfied_icon}
           />
        );
        if (data.level === 1) {
          icon = (
            <SentimentVerySatisfiedIcon
              className={styles.verysatisfied_icon}
            />
          );
        } else if (data.level === 2) {
          icon = (
            <SentimentSatisfiedIcon
              className={styles.satisfied_icon}
            />
          );
        }
        return (
          <Chip
            icon={icon}
            label={data.label}
            onClick={() => null}
            className={styles.chip}
          />
        );
      })}
    </CardContent>
  </Card>
</Grid>

Sample2Page.module.scssも修正しておきましょう。

.root {
  .form {
    .upload_button {
      display: flex;
      justify-content: center;
      align-items: center;
      .icon_button {
        .avatar {
          width: 150px;
          height: 150px;
        }
      }
    }
    .chip_card {
      background-color: transparent;
      border: 1px solid;
      .chip {
        margin: 5px;
      }
      .verydissatisfied_icon {
        color: gray;
      }
      .verysatisfied_icon {
        color: blue;
      }
      .satisfied_icon {
        color: salmon;
      }
    }
    .button_wrapper {
      display: flex;
      justify-content: flex-end;
      align-items: flex-end;
      margin: 20px;
      .submit_button,
      .cancel_button {
        margin: 5px;
      }
    }
  }
}

画面を確認するとChipが表示されており、ボタンとして利用できる状態になっていると思います。
(onClickを入れていないので、押下しても何も起きません。)

他の入力欄も実装する。

PieChartとTextと書かれている部分は、基本的にTextFeildを使ったものと何も変わらないのでソースコードのみ貼っておきます。

PieChartCard用

<Grid container spacing={3} item xs={12}>
  <Grid item xs={3}>
    <TextField
      margin="normal"
      id="title1"
      label="PieChartタイトル"
      fullWidth
      className={styles.text_field}
    />
  </Grid>
  <Grid item xs={7}>
    <TextField
      margin="normal"
      id="contents1"
      label="内容"
      fullWidth
      className={styles.text_field}
    />
  </Grid>
  <Grid item xs={2}>
    <TextField
      margin="normal"
      id="percentages1"
      label="%"
      variant="filled"
      fullWidth
      className={styles.text_field}
    />
  </Grid>
  <Grid item xs={3}>
    <TextField
      margin="normal"
      id="title2"
      label="PieChartタイトル"
      fullWidth
      className={styles.text_field}
    />
  </Grid>
   <Grid item xs={7}>
    <TextField
      margin="normal"
      id="contents2"
      label="内容"
      fullWidth
      className={styles.text_field}
    />
  </Grid>
  <Grid item xs={2}>
    <TextField
      margin="normal"
      id="percentages2"
      label="%"
      variant="filled"
      fullWidth
      className={styles.text_field}
    />
  </Grid>
  <Grid item xs={3}>
    <TextField
      margin="normal"
      id="title3"
      label="PieChartタイトル"
      fullWidth
      className={styles.text_field}
    />
  </Grid>
  <Grid item xs={7}>
    <TextField
      margin="normal"
      id="contents3"
      label="内容"
      fullWidth
      className={styles.text_field}
    />
  </Grid>
  <Grid item xs={2}>
    <TextField
      margin="normal"
      id="percentages3"
      label="%"
      variant="filled"
      fullWidth
      className={styles.text_field}
    />
  </Grid>
  <Grid item xs={3}>
    <TextField
      margin="normal"
      id="title4"
      label="PieChartタイトル"
      fullWidth
      className={styles.text_field}
    />
  </Grid>
  <Grid item xs={7}>
    <TextField
      margin="normal"
      id="contents4"
      label="内容"
      fullWidth
      className={styles.text_field}
    />
  </Grid>
  <Grid item xs={2}>
    <TextField
      margin="normal"
      id="percentages4"
      label="%"
      variant="filled"
      fullWidth
      className={styles.text_field}
    />
  </Grid>
</Grid>

TextCard用

<Grid container spacing={3} item xs={12}>
  <Grid item xs={3}>
    <TextField
      margin="normal"
      id="textcard_title1"
      label="テキストタイトル"
      fullWidth
      className={styles.text_field}
    />
  </Grid>
  <Grid item xs={9}>
    <TextField
      margin="normal"
      id="textcard_contents1"
      label="内容"
      multiline
      fullWidth
      variant="outlined"
      className={styles.text_field}
    />
  </Grid>
  <Grid item xs={3}>
    <TextField
      margin="normal"
      id="textcard_title2"
      label="テキストタイトル"
      fullWidth
      className={styles.text_field}
    />
  </Grid>
  <Grid item xs={9}>
    <TextField
      margin="normal"
      id="textcard_contents2"
      label="内容"
      multiline
      fullWidth
      variant="outlined"
      className={styles.text_field}
    />
  </Grid>
  <Grid item xs={3}>
    <TextField
      margin="normal"
      id="textcard_title3"
      label="テキストタイトル"
      fullWidth
      className={styles.text_field}
    />
  </Grid>
  <Grid item xs={9}>
    <TextField
      margin="normal"
      id="textcard_contents3"
      label="内容"
      multiline
      fullWidth
      variant="outlined"
      className={styles.text_field}
    />
  </Grid>
</Grid>

【おまけ】全体コードを確認する。

最終的なコードをあげておきます。
最後に全体をCardでラップして、スタイルで背景色を変更していますので、気になる方はこちらを参考にしてみてください。

import React from "react";
// react-router-dom
import { RouteComponentProps } from "react-router-dom";
import { Link } from "react-router-dom";
import { Path } from "../../../Routes";
// material-ui
import {
  Button,
  Grid,
  Box,
  Card,
  CardHeader,
  CardContent,
  Tooltip,
  IconButton,
  Avatar,
  TextField,
  InputAdornment,
  Chip,
  Divider,
} from "@material-ui/core";
import {
  DateRange as DateRangeIcon,
  Room as RoomIcon,
  Business as BusinessIcon,
  GitHub as GitHubIcon,
  Twitter as TwitterIcon,
  Facebook as FacebootIcon,
  Instagram as InstagramIcon,
  Web as WebIcon,
  AddAPhoto as AddAPhotoIcon,
  SentimentVerySatisfied as SentimentVerySatisfiedIcon,
  SentimentSatisfied as SentimentSatisfiedIcon,
  SentimentVeryDissatisfied as SentimentVeryDissatisfiedIcon,
} from "@material-ui/icons";
// styels
import styles from "./Sample2Page.module.scss";
// date-io
import DateFnsUtils from "@date-io/date-fns";
import {
  MuiPickersUtilsProvider,
  KeyboardTimePicker,
  KeyboardDatePicker,
} from "@material-ui/pickers";

type PropsTypes = RouteComponentProps;
interface ChipData {
  key: number;
  label: string;
  level: number;
}

const Sample2Page = ({ history }: PropsTypes): JSX.Element => {
  const [chipData, setChipData] = React.useState<ChipData[]>([
    { key: 0, label: "Angular", level: 1 },
    { key: 1, label: "jQuery", level: 2 },
    { key: 2, label: "Polymer", level: 3 },
    { key: 3, label: "React", level: 2 },
    { key: 4, label: "Vue.js", level: 1 },
  ]);
  return (
    <div className={styles.root}>
      <form className={styles.form}>
        <Grid container justifyContent="center" alignItems="center" spacing={3}>
          <Grid item xs={11}>
            <Card className={styles.form_card}>
              <CardHeader title="登録フォーム" className={styles.card_header} />
              <Divider />
              <CardContent>
                <Grid
                  container
                  justifyContent="center"
                  alignItems="center"
                  spacing={3}
                >
                  <Grid container spacing={3} item xs={3}>
                    <Grid item xs={12}>
                      <div className={styles.upload_button}>
                        <Tooltip title="add">
                          <IconButton className={styles.icon_button}>
                            <Avatar className={styles.avatar}>
                              <AddAPhotoIcon />
                            </Avatar>
                          </IconButton>
                        </Tooltip>
                      </div>
                    </Grid>
                  </Grid>
                  <Grid container spacing={3} item xs={9}>
                    <Grid item xs={12}>
                      <TextField
                        margin="normal"
                        id="name"
                        label="名前"
                        fullWidth
                        className={styles.text_field}
                      />
                      <TextField
                        margin="normal"
                        id="kana"
                        label="ふりがな"
                        fullWidth
                        className={styles.text_field}
                      />
                      <MuiPickersUtilsProvider utils={DateFnsUtils}>
                        <KeyboardDatePicker
                          margin="normal"
                          id="birthday"
                          label="生年月日"
                          format="MM/dd/yyyy"
                          value={new Date("2014-08-18T21:11:54")}
                          onChange={() => null}
                          fullWidth
                        />
                      </MuiPickersUtilsProvider>
                      <TextField
                        margin="normal"
                        id="birthplace"
                        label="出身地"
                        fullWidth
                        className={styles.text_field}
                      />
                      <MuiPickersUtilsProvider utils={DateFnsUtils}>
                        <KeyboardDatePicker
                          margin="normal"
                          id="birthday"
                          label="生年月日"
                          format="MM/dd/yyyy"
                          value={new Date("2014-08-18T21:11:54")}
                          onChange={() => null}
                          fullWidth
                        />
                      </MuiPickersUtilsProvider>
                    </Grid>
                  </Grid>
                  <Grid container spacing={3} item xs={12}>
                    <Grid item xs={12}>
                      <TextField
                        margin="normal"
                        id="github"
                        label="GitHub"
                        fullWidth
                        className={styles.text_field}
                        InputProps={{
                          startAdornment: (
                            <InputAdornment position="start">
                              <GitHubIcon />
                            </InputAdornment>
                          ),
                        }}
                      />
                      <TextField
                        margin="normal"
                        id="twitter"
                        label="Twitter"
                        fullWidth
                        className={styles.text_field}
                        InputProps={{
                          startAdornment: (
                            <InputAdornment position="start">
                              <TwitterIcon />
                            </InputAdornment>
                          ),
                        }}
                      />
                      <TextField
                        margin="normal"
                        id="facebook"
                        label="Facebook"
                        fullWidth
                        className={styles.text_field}
                        InputProps={{
                          startAdornment: (
                            <InputAdornment position="start">
                              <FacebootIcon />
                            </InputAdornment>
                          ),
                        }}
                      />
                      <TextField
                        margin="normal"
                        id="instagram"
                        label="Instagram"
                        fullWidth
                        className={styles.text_field}
                        InputProps={{
                          startAdornment: (
                            <InputAdornment position="start">
                              <InstagramIcon />
                            </InputAdornment>
                          ),
                        }}
                      />
                      <TextField
                        margin="normal"
                        id="web"
                        label="Web"
                        fullWidth
                        className={styles.text_field}
                        InputProps={{
                          startAdornment: (
                            <InputAdornment position="start">
                              <WebIcon />
                            </InputAdornment>
                          ),
                        }}
                      />
                    </Grid>
                  </Grid>
                  <Grid container spacing={3} item xs={12}>
                    <Grid item xs={3}>
                      <TextField
                        margin="normal"
                        id="title1"
                        label="PieChartタイトル"
                        fullWidth
                        className={styles.text_field}
                      />
                    </Grid>
                    <Grid item xs={7}>
                      <TextField
                        margin="normal"
                        id="contents1"
                        label="内容"
                        fullWidth
                        className={styles.text_field}
                      />
                    </Grid>
                    <Grid item xs={2}>
                      <TextField
                        margin="normal"
                        id="percentages1"
                        label="%"
                        variant="filled"
                        fullWidth
                        className={styles.text_field}
                      />
                    </Grid>
                    <Grid item xs={3}>
                      <TextField
                        margin="normal"
                        id="title2"
                        label="PieChartタイトル"
                        fullWidth
                        className={styles.text_field}
                      />
                    </Grid>
                    <Grid item xs={7}>
                      <TextField
                        margin="normal"
                        id="contents2"
                        label="内容"
                        fullWidth
                        className={styles.text_field}
                      />
                    </Grid>
                    <Grid item xs={2}>
                      <TextField
                        margin="normal"
                        id="percentages2"
                        label="%"
                        variant="filled"
                        fullWidth
                        className={styles.text_field}
                      />
                    </Grid>
                    <Grid item xs={3}>
                      <TextField
                        margin="normal"
                        id="title3"
                        label="PieChartタイトル"
                        fullWidth
                        className={styles.text_field}
                      />
                    </Grid>
                    <Grid item xs={7}>
                      <TextField
                        margin="normal"
                        id="contents3"
                        label="内容"
                        fullWidth
                        className={styles.text_field}
                      />
                    </Grid>
                    <Grid item xs={2}>
                      <TextField
                        margin="normal"
                        id="percentages3"
                        label="%"
                        variant="filled"
                        fullWidth
                        className={styles.text_field}
                      />
                    </Grid>
                    <Grid item xs={3}>
                      <TextField
                        margin="normal"
                        id="title4"
                        label="PieChartタイトル"
                        fullWidth
                        className={styles.text_field}
                      />
                    </Grid>
                    <Grid item xs={7}>
                      <TextField
                        margin="normal"
                        id="contents4"
                        label="内容"
                        fullWidth
                        className={styles.text_field}
                      />
                    </Grid>
                    <Grid item xs={2}>
                      <TextField
                        margin="normal"
                        id="percentages4"
                        label="%"
                        variant="filled"
                        fullWidth
                        className={styles.text_field}
                      />
                    </Grid>
                  </Grid>
                  <Grid container spacing={3} item xs={12}>
                    <Grid item xs={12}>
                      <Card className={styles.chip_card}>
                        <CardHeader
                          title="chipselect"
                          className={styles.card_header}
                        />
                        <CardContent>
                          {chipData.map((data) => {
                            let icon = (
                              <SentimentVeryDissatisfiedIcon
                                className={styles.verydissatisfied_icon}
                              />
                            );
                            if (data.level === 1) {
                              icon = (
                                <SentimentVerySatisfiedIcon
                                  className={styles.verysatisfied_icon}
                                />
                              );
                            } else if (data.level === 2) {
                              icon = (
                                <SentimentSatisfiedIcon
                                  className={styles.satisfied_icon}
                                />
                              );
                            }
                            return (
                              <Chip
                                icon={icon}
                                label={data.label}
                                onClick={() => null}
                                className={styles.chip}
                              />
                            );
                          })}
                        </CardContent>
                      </Card>
                    </Grid>
                  </Grid>
                  <Grid container spacing={3} item xs={12}>
                    <Grid item xs={3}>
                      <TextField
                        margin="normal"
                        id="textcard_title1"
                        label="テキストタイトル"
                        fullWidth
                        className={styles.text_field}
                      />
                    </Grid>
                    <Grid item xs={9}>
                      <TextField
                        margin="normal"
                        id="textcard_contents1"
                        label="内容"
                        multiline
                        fullWidth
                        variant="outlined"
                        className={styles.text_field}
                      />
                    </Grid>
                    <Grid item xs={3}>
                      <TextField
                        margin="normal"
                        id="textcard_title2"
                        label="テキストタイトル"
                        fullWidth
                        className={styles.text_field}
                      />
                    </Grid>
                    <Grid item xs={9}>
                      <TextField
                        margin="normal"
                        id="textcard_contents2"
                        label="内容"
                        multiline
                        fullWidth
                        variant="outlined"
                        className={styles.text_field}
                      />
                    </Grid>
                    <Grid item xs={3}>
                      <TextField
                        margin="normal"
                        id="textcard_title3"
                        label="テキストタイトル"
                        fullWidth
                        className={styles.text_field}
                      />
                    </Grid>
                    <Grid item xs={9}>
                      <TextField
                        margin="normal"
                        id="textcard_contents3"
                        label="内容"
                        multiline
                        fullWidth
                        variant="outlined"
                        className={styles.text_field}
                      />
                    </Grid>
                  </Grid>
                </Grid>
              </CardContent>
              <Box component="span" m={2} className={styles.button_wrapper}>
                <Button
                  type="submit"
                  variant="contained"
                  color="primary"
                  className={styles.submit_button}
                >
                  SUBMIT
                </Button>
                <Button
                  type="button"
                  variant="contained"
                  color="secondary"
                  onClick={() => null}
                  className={styles.cancel_button}
                >
                  CANCEL
                </Button>
              </Box>
            </Card>
          </Grid>
        </Grid>
      </form>
    </div>
  );
};
export default Sample2Page;
.root {
  .form {
    .form_card {
      .upload_button {
        display: flex;
        justify-content: center;
        align-items: center;
        .icon_button {
          .avatar {
            width: 150px;
            height: 150px;
          }
        }
      }
      .chip_card {
        background-color: transparent;
        border: 1px solid;
        .chip {
          margin: 5px;
        }
        .verydissatisfied_icon {
          color: gray;
        }
        .verysatisfied_icon {
          color: blue;
        }
        .satisfied_icon {
          color: salmon;
        }
      }
      .button_wrapper {
        display: flex;
        justify-content: flex-end;
        align-items: flex-end;
        margin: 20px;
        .submit_button,
        .cancel_button {
          margin: 5px;
        }
      }
    }
  }
}

最終的な画面はこちら!

まとめ

今回は、TextFeildやAvaterボタン、Chipボタンを実装してFormのレイアウトを作成していきました。
一部、省略した部分もありますが、全体のコードを載せておいたので、そちらから最終コードは確認してください。

今回は、全て同一ファイルに記述していきましたが、実際は適度な粒度でコンポーネント分けした方がいいですね。

本記事はReact・TypeScript・Redux Toolkitの利用を前提に実装をしていきます。
構築からデプロイまでやっていきますので、必要に応じて他の記事も参考にしてみてください。

また、今回のReactを勉強するにあたり利用した教材をあげています。
主に本(Amazon Unlimitedを含む)とUdemyの動画教材を利用しています。ここには私なりに理解した内容をもとに独自に内容を考えて共有しているので興味ある方は、本やUdemyを購入して勉強してみることをおすすめします。

学習に使った本はこちら!

¥24 (2024/04/15 17:44時点 | Amazon調べ)
\最大8%ポイントアップ!/
Amazon
¥3,839 (2024/04/18 18:13時点 | Amazon調べ)
\最大8%ポイントアップ!/
Amazon
¥700 (2024/04/17 16:11時点 | Amazon調べ)
\最大8%ポイントアップ!/
Amazon
クマじい

Amazon Kindle Unlimited でもReactの本はいっぱいあるぞ!

  • 技術書をたくさん読みたい!
  • 色々な技術を学びたい!
初回30日間無料体験があるので、どのような参考書があるか確認してみよう!

Kindle Unlimitedで技術書を読むならタブレットがあるとさらに便利ですよ!
10インチあるとより見やすいと思いますが、7インチでも十分見やすくなります!

【React TypeScript】Material UIのTextFeildやAvater、ChipでFormのレイアウトを作成する!

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

東京在住で20代のエンジニアです。
特に特技があるわけではありませんが、誰もが楽しくプログラミングができたらいいと思い、「teech lab.」を開設いたしました。

Enjoy Diaryという、ガジェットや雑貨を紹介しているブログもあります!
ぜひ、みてください!!

目次