Files
rowy/src/components/ConfirmDialog.tsx
2022-09-22 13:38:29 +10:00

127 lines
2.9 KiB
TypeScript

import { useState } from "react";
import { useAtom } from "jotai";
import {
Dialog,
DialogActions,
DialogContent,
DialogContentText,
DialogTitle,
TextField,
Button,
} from "@mui/material";
import { FadeTransitionMui } from "@src/components/Modal/FadeTransition";
import { projectScope, confirmDialogAtom } from "@src/atoms/projectScope";
export interface IConfirmDialogProps {
scope?: Parameters<typeof useAtom>[1];
}
/**
* Display a confirm dialog using `confirmDialogAtom` in `globalState`
* @see {@link confirmDialogAtom | Usage example}
*/
export default function ConfirmDialog({
scope = projectScope,
}: IConfirmDialogProps) {
const [
{
open,
title = "Are you sure?",
body,
handleConfirm,
confirm = "Confirm",
confirmationCommand,
confirmColor,
handleCancel,
cancel = "Cancel",
hideCancel,
maxWidth = "xs",
buttonLayout = "horizontal",
},
setState,
] = useAtom(confirmDialogAtom, scope);
const handleClose = () => {
setState({ open: false });
setDryText("");
};
const [dryText, setDryText] = useState("");
return (
<Dialog
open={open}
onClose={(_, reason) => {
if (reason === "backdropClick" || reason === "escapeKeyDown") return;
else handleClose();
}}
maxWidth={maxWidth}
TransitionComponent={FadeTransitionMui}
sx={{ cursor: "default", zIndex: (theme) => theme.zIndex.modal + 50 }}
>
<DialogTitle>{title}</DialogTitle>
<DialogContent>
{typeof body === "string" ? (
<DialogContentText>{body}</DialogContentText>
) : (
body
)}
{confirmationCommand && (
<TextField
value={dryText}
onChange={(e) => setDryText(e.target.value)}
autoFocus
label={`Type “${confirmationCommand}” below to continue:`}
placeholder={confirmationCommand}
fullWidth
id="dryText"
sx={{ mt: 3 }}
/>
)}
</DialogContent>
<DialogActions
sx={[
buttonLayout === "vertical" && {
flexDirection: "column",
alignItems: "stretch",
"& > :not(:first-of-type)": { ml: 0, mt: 1 },
},
]}
>
{!hideCancel && (
<Button
onClick={() => {
if (handleCancel) handleCancel();
handleClose();
}}
>
{cancel}
</Button>
)}
<Button
onClick={() => {
if (handleConfirm) handleConfirm();
handleClose();
}}
color={confirmColor || "primary"}
variant="contained"
autoFocus
disabled={
confirmationCommand ? dryText !== confirmationCommand : false
}
>
{confirm}
</Button>
</DialogActions>
</Dialog>
);
}