69 lines
1.7 KiB
TypeScript
69 lines
1.7 KiB
TypeScript
|
import {
|
||
|
Button,
|
||
|
Dialog,
|
||
|
DialogActions,
|
||
|
DialogContent,
|
||
|
DialogContentText,
|
||
|
DialogTitle,
|
||
|
} from "@mui/material";
|
||
|
import React, { PropsWithChildren } from "react";
|
||
|
|
||
|
type AlertContext = (message: string, title?: string) => Promise<void>;
|
||
|
|
||
|
const AlertContextK = React.createContext<AlertContext | null>(null);
|
||
|
|
||
|
export function AlertDialogProvider(p: PropsWithChildren): React.ReactElement {
|
||
|
const [open, setOpen] = React.useState(false);
|
||
|
|
||
|
const [title, setTitle] = React.useState<string | undefined>(undefined);
|
||
|
const [message, setMessage] = React.useState("");
|
||
|
|
||
|
const cb = React.useRef<null | (() => void)>(null);
|
||
|
|
||
|
const handleClose = () => {
|
||
|
setOpen(false);
|
||
|
|
||
|
if (cb.current !== null) cb.current();
|
||
|
cb.current = null;
|
||
|
};
|
||
|
|
||
|
const hook: AlertContext = (message, title) => {
|
||
|
setTitle(title);
|
||
|
setMessage(message);
|
||
|
setOpen(true);
|
||
|
|
||
|
return new Promise((res) => {
|
||
|
cb.current = res;
|
||
|
});
|
||
|
};
|
||
|
|
||
|
return (
|
||
|
<>
|
||
|
<AlertContextK.Provider value={hook}>{p.children}</AlertContextK.Provider>
|
||
|
|
||
|
<Dialog
|
||
|
open={open}
|
||
|
onClose={handleClose}
|
||
|
aria-labelledby="alert-dialog-title"
|
||
|
aria-describedby="alert-dialog-description"
|
||
|
>
|
||
|
{title && <DialogTitle id="alert-dialog-title">{title}</DialogTitle>}
|
||
|
<DialogContent>
|
||
|
<DialogContentText id="alert-dialog-description">
|
||
|
{message}
|
||
|
</DialogContentText>
|
||
|
</DialogContent>
|
||
|
<DialogActions>
|
||
|
<Button onClick={handleClose} autoFocus>
|
||
|
Ok
|
||
|
</Button>
|
||
|
</DialogActions>
|
||
|
</Dialog>
|
||
|
</>
|
||
|
);
|
||
|
}
|
||
|
|
||
|
export function useAlert(): AlertContext {
|
||
|
return React.useContext(AlertContextK)!;
|
||
|
}
|