【Material UI】モーダルウィンドウの背景をクリックしても閉じないようにする方法

React UIライブラリMaterial UIのModal(モーダル)コンポーネントでは、デフォルトでモーダルウィンドウの背景バックドロップをクリックするとモーダルが閉じます。

See the Pen MUI Modal by hosakat (@hosakat) on CodePen.

ただ、要件として、閉じるボタンなどを明示的に押さないとモーダルを閉じないようにする必要があることも考えられます。

そのような場合、モーダル背景をクリックしても、どのようにしてモーダルが閉じないようにするのかを説明します。

propで制御できないの?

まずは、モーダルコンポーネントに「背景クリックで閉じないようにする」ことを渡せるpropがあれば一番楽でしょう。

あればいいなあと思い調べてみると、

そのようなpropは昔はあったが今はない

ことがわかりました。

というのは、Material UI Coreパッケージ(@material-ui/core)が4.12バージョンにアップデートされる際に、disableBackdropClick という素敵なpropがなくなってしまったのです。

disableBackdropClick は、名前からわかるように、trueを与えると背景バックドロップのクリックを禁止することができるpropでした。

めっちゃ使いたい、、なんでなくなった、、と思われますが、今はpropを使わない他の方法で制御するしかなさそうです。

onCloseに渡す関数内に処理を記述することで解決!

いきなり解決策ですが、

モーダルコンポーネントに閉じるリクエストが送られた際に発火するonClose関数に渡すハンドル関数handleClose()で、以下のように記述します。

const [open, setOpen] = useState(false);
const handleClose = (event: React.MouseEvent<HTMLInputElement>, reason: 'backdropClick') => {
    if ( reason === 'backdropClick') return;
    setOpen(false);
  };
...
return (
    <>
      ...
      <Modal
        open={open}
        onClose={handleClose}
        ...
      >
        モーダルの中身
      </Modal>
    <>
)
...

ここでは、モーダルというDialog要素の背景をクリックした際のイベントを取得して、クリックした際にモーダルが閉じる処理が実行されないようにしています。

以下から挙動を確認できます。

See the Pen Untitled by hosakat (@hosakat) on CodePen.

まとめ

これでモーダル背景をクリックしてもモーダルが消えないようにすることができました!

また、元々のdisableBackdropClick のような、背景クリックでモーダルを消すかどうかを選択するpropsを作成することで、モーダルごとに背景クリック時の挙動を制御できるでしょう。

const [open, setOpen] = useState(false);
const handleClose = (event: React.MouseEvent<HTMLInputElement>, reason: 'backdropClick') => {
    // disableBackdropClickがpropで渡される背景クリック時の挙動制御プロパティ
    if ( disableBackdropClick && reason === 'backdropClick') return;
    setOpen(false);
  };

ぜひ参考にしてみてください。

コメント

タイトルとURLをコピーしました