🚗

Reactで要素(Dialog, Menu, Modalなど)の外側をクリックした場合に閉じる系のやつを実装する方法

2024/01/08に公開

こんにちは、AIQ株式会社のフロントエンドエンジニアのまさぴょんです!
今回は、Reactで要素(Dialog, Menu, Modalなど)の外側をクリックした場合に閉じる系のやつを実装する方法について、解説します。

要素の外側をクリックした場合に閉じる系のやつとは?

要素の外側をクリックした場合に閉じる系のやつは、Dialog, SideMenuなどを開いているときに、外側をクリックすると閉じるあの挙動です。

今回は、よくあるDialogの外側をクリックすると閉じるを実装してみました。

SampleCodeは、次のような内容になります。

Dialog.tsx
/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";
import { useState } from "react";

/** Dialog Component */
const DialogCustom = () => {
  /** Dialog の開閉・制御 Flag */
  const [isOpen, setIsOpen] = useState(false);

  return (
    <div css={EmotionStyle.dialogPositionStyle}>
      {/* Dialog Open Btn */}
      <div>
        <button onClick={() => setIsOpen(true)}>Open</button>
      </div>

      {/* Dialog 本体 */}
      {isOpen && (
        <div css={EmotionStyle.dialogWrapperStyle}>
          <div css={EmotionStyle.dialogInnerStyle}>
            <h3>Dialog</h3>
            <button
              onClick={() => setIsOpen(false)}
              style={{ width: "60px", height: "30px" }}
            >
              Close
            </button>
          </div>
        </div>
      )}
      {/* Dialogの外側(Outer)領域: 外側ClickでもDialogを閉じる */}
      {isOpen && (
        <div
          onClick={() => setIsOpen(false)}
          css={EmotionStyle.dialogOuterStyle}
        ></div>
      )}
    </div>
  );
};

/** EmotionStyle */
const EmotionStyle = {
  /** Dialogの配置・Position */
  dialogPositionStyle: css`
    position: relative;
  `,
  /**
   * Dialog の DefaultStyle
   * - Dialogの配置・Position: 画面中央に配置
   */
  dialogWrapperStyle: css`
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%); /* x軸, y軸 */
    z-index: 100;
  `,
  /** Dialogの Inner Div の Style */
  dialogInnerStyle: css`
    width: 300px;
    height: 300px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 30px;
    background-color: white;
    border-radius: 8px;
    box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2);
  `,
  /**
   * Dialogの Outer Style
   * - Dialogの外側(Outer)領域: 画面全体を覆うように設定
   * - Dialogの外側(Outer)領域: 背景色を設定
   * - Dialogの外側(Outer)領域: z-indexを設定(Dialogの背面に配置)
   */
  dialogOuterStyle: css`
    position: fixed;
    left: 0;
    top: 0;
    z-index: 99;
    height: 100vh;
    width: 100vw;
    background-color: rgba(64, 70, 84, 0.101961);
  `,
};

export default DialogCustom;

Codeにコメントも記述しているので、わかるとは思いますが、実装ポイントをまとめると次のような感じです。

まとめ

いろいろな方法で、要素の外側をクリックした場合に閉じる系のやつを実装している人がいましたが、私の場合は、このやり方が一番、しっくりきました。

個人で、Blogもやっています、よかったら見てみてください。

https://masanyon.com/

注意事項

この記事は、AIQ 株式会社の社員による個人の見解であり、所属する組織の公式見解ではありません。

求む、冒険者!

AIQ株式会社では、一緒に働いてくれるエンジニアを絶賛、募集しております🐱🐹✨

詳しくは、Wantedly (https://www.wantedly.com/companies/aiqlab)を見てみてください。

参考・引用

https://zenn.dev/manase/scraps/281c83a3d644d6

AIQ Tech Blog (有志)

Discussion