
Reactサンプルアプリ開発 プラニングポーカー (2) モーダルダイアログ
プレイヤーのカードをクリックするとモーダルダイアログでデッキを表示するようにする。

モーダルダイアログにはreact-modal
を使う。
$yarn add react-modal
$yarn add @types/react-modal
Modal
をインポート。
import Modal from 'react-modal';
オーバーレイを被せる要素をModal.setAppElement
で指定する。
Modal.setAppElement('#app');
オーバーレイとダイアログ領域に当てるカスタムスタイルを定義しておく。
const customStyles = {
overlay: {
backgroundColor: "rgba(0, 0, 0, 0.7)"
},
content: {
top: '50%',
left: '50%',
right: 'auto',
bottom: 'auto',
marginRight: '-50%',
padding: 0,
transform: 'translate(-50%, -50%)'
}
};
モーダルの開閉状態を表すステートをuseState
を使って宣言する。
export const Player: FunctionComponent<PlayerProps> = (props) => {
const [modalIsOpen, setModalIsOpen] = useState(false);
モーダル開閉用のハンドラを定義。
const handleModalOpen = () => {
setModalIsOpen(true);
}
const handleModalClose = () => {
setModalIsOpen(false);
}
カード領域のdiv
のonClick
でhandleModalOpen
を呼び出すように指定。
<div className="player-card" onClick={handleModalOpen}>
<span className="point">{props.bid}</span>
</div
Modal
コンポーネントを配置する。
<Modal isOpen={modalIsOpen} onRequestClose={handleModalClose}
contentLabel="test" style={customStyles} >
<Deck points={points} />
</Modal>
isOpen
属性には、ステート変数modalIsOpen
をバインドonRequestClose
属性にモーダルクローズのハンドラhandleModalClose
をバインドstyle
属性にはカスタムスタイルをバインドModal
タグの子要素にダイアログのコンテンツを配置する
これでモーダルダイアログの表示が実装できた。Player
コンポーネントの現在の実装は以下のとおり。
import React, { FunctionComponent, useState } from "react";
import Modal from 'react-modal';
import { Deck } from "./Deck";
Modal.setAppElement('#app');
const customStyles = {
overlay: {
backgroundColor: "rgba(0, 0, 0, 0.7)"
},
content: {
top: '50%',
left: '50%',
right: 'auto',
bottom: 'auto',
marginRight: '-50%',
padding: 0,
transform: 'translate(-50%, -50%)'
}
};
export type PlayerProps = {
name: string;
icon: number;
bid: string;
open: boolean;
}
export const Player: FunctionComponent<PlayerProps> = (props) => {
const [modalIsOpen, setModalIsOpen] = useState(false);
const points = ["0", "1", "2", "3", "5", "8"];
const handleModalOpen = () => {
setModalIsOpen(true);
}
const handleModalClose = () => {
setModalIsOpen(false);
}
return (
<div className="player">
<div className="player-info">
<div className={"player-icon-" + props.icon}>
</div>
<div className="player-name">{props.name}</div>
</div>
<div className="player-card" onClick={handleModalOpen}>
<span className="point">{props.bid}</span>
</div>
<Modal isOpen={modalIsOpen} onRequestClose={handleModalClose}
contentLabel="test" style={customStyles} >
<Deck points={points} />
</Modal>
</div>
)
}