【React】MUIのモーダルに閉じるボタンを追加する

MUI(Material-UI)のBasic modalを使用したところ、デフォルトで閉じるボタンがありませんでしたので、MUIのBasic modalに「閉じるボタン」を追加する方法をまとめました。

閉じる機能を明示的に表現するためには「閉じるボタン」を表示したいですよね。

MUIのデフォルトのModalに「閉じるボタン」を追加し、以下のような画面作成をゴールとしていします。

目標物

使用したMUI

MUIのデフォルトのModalはこちら

React Modal component - Material UI
The modal component provides a solid foundation for creating dialogs, popovers, lightboxes, or whatever else.

変更前

create-react-appでできるデフォルトのこちらの画面の「Learn React」を「Open Modal」に変えて、Modal機能を追加していきます。

create-react-appのデフォルト

import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

Basic Modalの導入

MUIを使うために、MUIのinstallをします。

Installation - Material UI
Install Material UI, the world's most popular React UI framework.

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

BasicModal.jsファイルを作りMUIからコピペし、「Learn React」を「Open Modal」にまんま置き換えます。

import logo from "./logo.svg";
import "./App.css";
import BasicModal from "./BasicModal";

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <BasicModal />
      </header>
    </div>
  );
}

export default App;

import * as React from "react";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import Modal from "@mui/material/Modal";

const style = {
  position: "absolute",
  top: "50%",
  left: "50%",
  transform: "translate(-50%, -50%)",
  width: 400,
  bgcolor: "background.paper",
  border: "2px solid #000",
  boxShadow: 24,
  p: 4,
};

export default function BasicModal() {
  const [open, setOpen] = React.useState(false);
  const handleOpen = () => setOpen(true);
  const handleClose = () => setOpen(false);

  return (
    <div>
      <Button onClick={handleOpen}>Open modal</Button>
      <Modal
        open={open}
        onClose={handleClose}
        aria-labelledby="modal-modal-title"
        aria-describedby="modal-modal-description"
      >
        <Box sx={style}>
          <Typography id="modal-modal-title" variant="h6" component="h2">
            Text in a modal
          </Typography>
          <Typography id="modal-modal-description" sx={{ mt: 2 }}>
            Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
          </Typography>
        </Box>
      </Modal>
    </div>
  );
}

すると、modalができましたね!

これはデフォルトですので、この時点では閉じるボタンがありません。

閉じるボタンを追加していきましょう!

「閉じるボタン」追加

close iconを使用するため、まずは以下よりinstallします。

$ npm install @mui/icons-material

Material Icons - Material UI
2,100+ ready-to-use React Material Icons from the official website.

閉じるボタンを配置したいところに、コンポーネントを記述します。

IconButtonを使うといい感じにできるのでこれも使いましょう。

React Button component - Material UI
Buttons allow users to take actions, and make choices, with a single tap.

最終的なコードがこちら

import * as React from "react";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import Modal from "@mui/material/Modal";
import IconButton from "@mui/material/IconButton";
import CloseIcon from "@mui/icons-material/Close";

const style = {
  position: "absolute",
  top: "50%",
  left: "50%",
  transform: "translate(-50%, -50%)",
  width: 400,
  bgcolor: "background.paper",
  border: "2px solid #000",
  boxShadow: 24,
  p: 4,
};

const closeButtonStyle = {
  height: 0,
  textAlign: "right",
};

export default function BasicModal() {
  const [open, setOpen] = React.useState(false);
  const handleOpen = () => setOpen(true);
  const handleClose = () => setOpen(false);

  return (
    <div>
      <Button onClick={handleOpen}>Open modal</Button>
      <Modal
        open={open}
        onClose={handleClose}
        aria-labelledby="modal-modal-title"
        aria-describedby="modal-modal-description"
      >
        <Box sx={style}>
          <Box sx={closeButtonStyle}>
            <IconButton onClick={handleClose}>
              <CloseIcon />
            </IconButton>
          </Box>
          <Typography id="modal-modal-title" variant="h6" component="h2">
            Text in a modal
          </Typography>
          <Typography id="modal-modal-description" sx={{ mt: 2 }}>
            Duis mollis, est non commodo luctus, nisi erat porttitor ligula.
          </Typography>
        </Box>
      </Modal>
    </div>
  );
}

変更箇所

・IconButtonの追加

・CloseIconの追加

・閉じるボタンの位置を指定するため、closeButtonStyleを追加

以上、記事にするほどでもなく簡単でした。

お読みいただきありがとうございます。

コメント