この記事で分かること
- Next.jsとTailwind CSSでのダイアログボックス(モーダル)の実装方法
全ソースコードはこちら
実行結果
機能概要
- Open Modalをクリックするとダイアログが開く
- ダイアログはOKをクリックするかダイアログの外をクリックすると閉じる
- メッセージは固定
実装コード
ダイアログボックスコンポーネント
- src/app/components/Modal.tsx
import React from 'react';
export type ModalProps = {
open: boolean;
onCancel: () => void;
onOk: () => void;
};
const Modal = (props: ModalProps) => {
return props.open ? (
<>
<div className="bg-white top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-80 h-48 p-5 flex flex-col items-start absolute z-20">
<h1 className="text-xl font-bold mb-5">Title</h1>
<p className="text-lg mb-5">Dialog Message.</p>
<div className="flex mt-auto w-full">
<button
className="bg-slate-900 hover:bg-slate-700 text-white px-8 py-2 mx-auto"
onClick={() => props.onOk()}
>
OK
</button>
</div>
</div>
<div
className="fixed bg-black bg-opacity-50 w-full h-full z-10"
onClick={() => props.onCancel()}
></div>
</>
) : (
<></>
);
};
export default Modal;
呼び出し側
- src/app/page.tsx
'use client';
import MessageDialog from './components/Modal';
import { useState } from 'react';
export default function Home() {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<MessageDialog
open={isOpen}
onCancel={() => setIsOpen(false)}
onOk={() => setIsOpen(false)}
/>
<div className="flex flex-col min-h-screen items-center justify-center">
<button
className="bg-slate-900 hover:bg-slate-700 text-white text-lg w-60 h-14 py-2 px-4"
onClick={() => setIsOpen(true)}
>
Open Modal
</button>
</div>
</>
);
}
フォルダ構成(抜粋)
src
└─ app
├─ components
│ └─ Modal.tsx
└─ page.tsx
ポイント
- ダイアログは
absolute
を指定することで、元の画面の上に重なるように表示する -
absolute
の次にfixed
のdiv
を指定することで、背景を半透明を実現し、クリック判定を持たせる - ダイアログに
z-20
、ダイアログの周囲にz-10
のZインデックスを指定し、ダイアログが全面に来るようにする - 呼び出し元は
useState()
でisOpen
フラグを設定する - useStateを使用するためClient Side Rendering(
'use client';
)を指定する必要がある -
props
でメッセージ等を渡すようにすれば、ダイアログの表示を可変にできる - ダイアログの
<div>
にclassName="shadow-2xl"
や"rounded"
などを指定するともう少しカッコよくなる