Material-ui で提供されている Dialog
コンポーネントは、それ自体が便利なダイアログコンポーネントであるが、閉じるボタンなどの実装は各自で実装する必要がある。
そこで、閉じるボタンや、スマホなどの画面サイズが小さいデバイスの時にフルスクリーンで表示する機能など、ある程度共通的な機能をまとた部品を今回は作ってみる。
完成イメージ
今回作る部品の完成イメージは次のとおり。モーダルダイアログのタイトルと閉じるボタン(×)は共通側で実装し、コンテンツ部分のみ個別に実装する方式とする。
また、スマホなどの横幅が狭いデバイスで表示された場合は、フルスクリーンでダイアログを表示するようにしている。
ダイアログ部品の実装
まず、共通部品となるダイアログ部品を作る。
import React, { useEffect, useState } from 'react';
import CloseIcon from '@mui/icons-material/Close';
import {
Dialog, DialogContent,
DialogTitle,
IconButton,
useMediaQuery
} from '@mui/material';
import { useTheme } from '@mui/material/styles';
import PropTypes from 'prop-types';
/**
* タイトルエリアのスタイル
*/
const titleStyle = {
display: "flex",
justifyContent: "space-between",
alignItems: "center",
backgroundColor: '#333',
'& *': {
fontWeight: 'bold',
color: '#fff'
}
}
function ModalDialog(props: any) {
// プロパティ
const {
title,
onClose,
open,
maxWidth,
} = props;
// ダイアログ表示状態
const [dialogOpen, setDialogOpen] = useState(false);
const theme = useTheme();
const fullScreen = useMediaQuery(theme.breakpoints.down('sm'));
// openの値が変化した時
useEffect(() => setDialogOpen(open), [open]);
// ダイアログクローズ
const handleClose = () => {
setDialogOpen(false);
onClose();
};
return (
<Dialog
open={dialogOpen}
fullWidth={true}
fullScreen={fullScreen}
maxWidth={maxWidth}>
<DialogTitle sx={{ ...titleStyle }}>
<span>{title}</span>
<IconButton aria-label="close" onClick={handleClose}>
<CloseIcon />
</IconButton>
</DialogTitle>
<DialogContent>
{props.children}
</DialogContent>
</Dialog>
);
}
// プロパティ
ModalDialog.propTypes = {
title: PropTypes.string.isRequired,
onClose: PropTypes.func.isRequired,
open: PropTypes.bool.isRequired,
children: PropTypes.element,
maxWidth: PropTypes.string
};
export default ModalDialog;
作ったダイアログ部品を使う
次に、上で作成したダイアログ部品を使って、モーダルダイアログを実装する。
ソースコードは次のとおり、ダイアログに表示するコンテンツは、ModalDialog
の子要素に書けばいい。
import { Box, Stack, TextField } from '@mui/material';
import Button from '@mui/material/Button';
import React, { useState } from 'react';
import ModalDialog from './dialog/ModalDialog';
function Sample() {
// ダイアログ用のstate
const [digOpen, setDigOpen] = useState(false);
return (
<div>
<ModalDialog
title="タイトル"
open={digOpen}
onClose={() => setDigOpen(false)}>
<Box sx={{ mt: 2 }}>
<Stack spacing={2}>
<TextField
label="ID"
variant="filled"
/>
<TextField
label="Password"
variant="filled"
/>
</Stack>
<Box sx={{ mt: 3 }}>
<Button variant="contained">ログイン</Button>
</Box>
</Box>
</ModalDialog>
<Button onClick={() => setDigOpen(true)}>
モーダル表示
</Button>
</div>
);
}
export default Sample;
まとめ
ここまでの内容で、共通的に使えるダイアログ部品は完成だ。
SPAアプリなどでは、ダイアログを使った画面をよく実装するため、今日つ部品としてまとめておくと便利である。
0 件のコメント:
コメントを投稿