mirror of
https://github.com/stefanpejcic/openpanel
synced 2025-06-26 18:28:26 +00:00
82 lines
2.2 KiB
TypeScript
82 lines
2.2 KiB
TypeScript
/**
|
|
* `useBlocker` and `usePrompt` is no longer part of react-router-dom for the routers other than `DataRouter`.
|
|
*
|
|
* The previous workaround (<v6.4) was to use `block` function in `UNSAFE_NavigationContext` which is now removed.
|
|
*
|
|
* We're using a workaround from the gist https://gist.github.com/MarksCode/64e438c82b0b2a1161e01c88ca0d0355 with some modifications
|
|
* Thanks to @MarksCode(https://github.com/MarksCode) for the workaround.
|
|
*/
|
|
|
|
import React from "react";
|
|
import { UNSAFE_NavigationContext as NavigationContext } from "react-router-dom";
|
|
|
|
function useConfirmExit(confirmExit: () => boolean, when = true) {
|
|
const { navigator } = React.useContext(NavigationContext);
|
|
|
|
React.useEffect(() => {
|
|
if (!when) {
|
|
return;
|
|
}
|
|
|
|
const go = navigator.go;
|
|
const push = navigator.push;
|
|
|
|
navigator.push = (...args: Parameters<typeof push>) => {
|
|
const result = confirmExit();
|
|
if (result !== false) {
|
|
push(...args);
|
|
}
|
|
};
|
|
|
|
navigator.go = (...args: Parameters<typeof go>) => {
|
|
const result = confirmExit();
|
|
if (result !== false) {
|
|
go(...args);
|
|
}
|
|
};
|
|
|
|
return () => {
|
|
navigator.push = push;
|
|
navigator.go = go;
|
|
};
|
|
}, [navigator, confirmExit, when]);
|
|
}
|
|
|
|
export function usePrompt(
|
|
message: string,
|
|
when = true,
|
|
onConfirm?: () => void,
|
|
legacy = false,
|
|
) {
|
|
const warnWhenListener = React.useCallback(
|
|
(e: { preventDefault: () => void; returnValue: string }) => {
|
|
e.preventDefault();
|
|
|
|
e.returnValue = message;
|
|
|
|
return e.returnValue;
|
|
},
|
|
[message],
|
|
);
|
|
|
|
React.useEffect(() => {
|
|
if (when && !legacy) {
|
|
window.addEventListener("beforeunload", warnWhenListener);
|
|
}
|
|
|
|
return () => {
|
|
window.removeEventListener("beforeunload", warnWhenListener);
|
|
};
|
|
}, [warnWhenListener, when, legacy]);
|
|
|
|
const confirmExit = React.useCallback(() => {
|
|
const confirm = window.confirm(message);
|
|
if (confirm && onConfirm) {
|
|
onConfirm();
|
|
}
|
|
return confirm;
|
|
}, [message]);
|
|
|
|
useConfirmExit(confirmExit, when);
|
|
}
|