import type { History, Blocker, Transition } from 'history'; import { useEffect } from 'react'; import { Navigator as BaseNavigator, unstable_usePrompt as usePrompt, } from 'react-router-dom'; interface Navigator extends BaseNavigator { block?: History['block']; location: Location; } interface FormBasedPreventNavigationProps { promptMessage?: string; preventNavigate: boolean; navigator: Navigator; } /** Temporary function to allow backwards compatibility with routers that do not use the new Data API */ export default function NewFormBasedPreventNavigation({ promptMessage = 'Changes you made may not be saved.', preventNavigate, navigator, }: FormBasedPreventNavigationProps) { usePrompt({ when: preventNavigate, message: promptMessage, }); // TODO: Once react-router fully supports usePrompt and when we do not want to support routers // that do not support the react-router Data API we can remove this. useEffect(() => { if (!preventNavigate) { return; } let unblock = () => {}; const push = navigator.push; navigator.push = (...args: Parameters) => { if (window.confirm(promptMessage)) { push(...args); } }; window.addEventListener('beforeunload', beforeUnload); return () => { unblock(); navigator.push = push; window.removeEventListener('beforeunload', beforeUnload); }; function beforeUnload(e: BeforeUnloadEvent) { e.preventDefault(); e.returnValue = promptMessage; } }, [preventNavigate, promptMessage, navigator]); return null; }