import { beforeNavigate } from '$app/navigation'; import { onMount } from 'svelte'; /** * Warn before leaving a page with unsaved form state. Call once from a * component's script (during init). `isDirty` is read live on each navigation, * so pass a closure over the form's reactive state — and have it return `false` * once a save has succeeded (or is in flight) so the post-save redirect doesn't * prompt. * * Covers both in-app navigation (SvelteKit `beforeNavigate`, with a confirm) and * full-page unload / tab close / reload (the native `beforeunload` prompt). */ export function guardUnsavedChanges(isDirty: () => boolean): void { beforeNavigate((nav) => { // `leave` (tab close / reload) can't show a custom confirm here — the // beforeunload handler below covers it. Only guard in-app navigations. if (nav.type === 'leave') return; if (!isDirty()) return; if (!confirm('You have unsaved changes. Leave this page and discard them?')) { nav.cancel(); } }); onMount(() => { const handler = (e: BeforeUnloadEvent) => { if (isDirty()) { e.preventDefault(); // Legacy browsers require returnValue to be set. e.returnValue = ''; } }; window.addEventListener('beforeunload', handler); return () => window.removeEventListener('beforeunload', handler); }); }