MUI ( Nextjs / Material-ui ) で共通ダイアログの実装

OKとキャンセルが選択できる共通Daialogを実装する。
何度か使うものはComponent化して使うのが良い。

完成イメージはこちら。

OkCancelDialogComponentのコード。

import Grid from '@mui/material/Grid'
import { Box, BoxProps, Button, Dialog, DialogContent, Typography, TypographyProps } from '@mui/material'
import { Icon } from '@iconify/react'
import { styled } from '@mui/material/styles'
import IconButton from '@mui/material/IconButton'

const BoxWrapper = styled(Box)<BoxProps>(({ theme }) => ({
  width: '100%',
  margin: 'auto',
  [theme.breakpoints.down('md')]: {
    maxWidth: 400
  }
}))

const TypographyStyled = styled(Typography)<TypographyProps>(({ theme }) => ({
  fontWeight: 600,
  letterSpacing: '0.18px',
  marginBottom: theme.spacing(1.5),
  [theme.breakpoints.down('md')]: { marginTop: theme.spacing(8) }
}))

interface Props {
  open: boolean
  onCancel: () => void
  onOk: () => void
  title: string
  description: string
}

const OkCancelDialog = (props: Props) => {
  const { open, onCancel: onCancel, onOk: onOk } = props

  return (
    <Dialog maxWidth='md' scroll='body' open={open}>
      <DialogContent
        sx={{
          px: theme => [`${theme.spacing(6)} !important`, `${theme.spacing(6)} !important`],
          maxWidth: '450px',
          margin: 'auto',
          width: '100%'
        }}
      >
        <BoxWrapper>
          <Grid container direction='row' justifyContent='flex-end' alignItems='center' sx={{ mb: 6 }}>
            <IconButton edge='end' onClick={() => onCancel()}>
              <Icon icon='basil:cross-outline' fontSize={40} />
            </IconButton>
          </Grid>
          <Box sx={{ mb: 6, textAlign: 'center' }}>
            <TypographyStyled variant='h5'>{props.title}</TypographyStyled>
            <Typography variant='body2'>{props.description}</Typography>
          </Box>
          <Grid container direction='row' justifyContent='center' alignItems='center' gap={8}>
            <Button
              size='large'
              type='submit'
              variant='contained'
              onClick={() => onOk()}
              sx={{ mb: 2, width: '130px' }}
            >
              OK
            </Button>
            <Button
              size='large'
              color='secondary'
              variant='outlined'
              onClick={() => onCancel()}
              sx={{ mb: 2, width: '130px' }}
            >
              キャンセル
            </Button>
          </Grid>
        </BoxWrapper>
      </DialogContent>
    </Dialog>
  )
}

export default OkCancelDialog

Componentするため、Dialogを開くstate、キャンセル、OK時のEvent、Dialog毎に異なるDialogタイトル、説明文を渡すPropsを作成している。

interface Props {
  open: boolean
  onCancel: () => void
  onOk: () => void
  title: string
  description: string
}

OkCancelDialogComponentを使用するときは、

まず、Dialogの開閉stateを定義する。

const [openDialog, setOpenDialog] = useState<boolean>(false)

その後、Propsにそれぞれ渡す形になる。
開きたいタイミングで setOpenDialog(true) とすることで、Dialogが表示できる。

<OkCancelDialog
  open={openDialog}
  onCancel={() => {
    setOpenDialog(false)
  }}
  onOk={onUpdate}
  title='ダイアログ'
  description='更新します。よろしいですか?'
></OkCancelDialog>
よかったらシェアしてね!
目次