import type { PendingVisit } from '@inertiajs/core'; import { router } from '@inertiajs/vue3'; import { onMounted, onUnmounted, toValue } from 'vue'; import type { MaybeRefOrGetter } from 'vue'; import { useLocalization } from '@/composables/useLocalization'; export function useUnsavedChanges( dirty: MaybeRefOrGetter, allowVisit: (visit: PendingVisit) => boolean = () => false, ) { const { t } = useLocalization(); let removeBeforeListener: (() => void) | undefined; const confirmLeave = (): boolean => !toValue(dirty) || window.confirm(t('forms.leaveConfirm')); const beforeUnload = (event: BeforeUnloadEvent): void => { if (toValue(dirty)) { event.preventDefault(); event.returnValue = ''; } }; onMounted(() => { removeBeforeListener = router.on('before', (event) => { if (event.defaultPrevented || allowVisit(event.detail.visit)) { return; } // Keep the original visit and its callbacks; never replay a mutation. return confirmLeave(); }); window.addEventListener('beforeunload', beforeUnload); }); onUnmounted(() => { removeBeforeListener?.(); window.removeEventListener('beforeunload', beforeUnload); }); return { confirmLeave }; }