From db7c77018832bee2381ec403591e1879f88cb8a6 Mon Sep 17 00:00:00 2001 From: Jack Stenglein Date: Mon, 10 Feb 2025 15:54:31 -0600 Subject: [PATCH 1/2] Export NavigationGuardProviderContext --- src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/index.ts b/src/index.ts index 75f6043..6b1d158 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ export { useNavigationGuard } from "./hooks/useNavigationGuard"; export { NavigationGuardProvider } from "./components/NavigationGuardProvider"; +export { NavigationGuardProviderContext } from "./components/NavigationGuardProviderContext"; export type { NavigationGuardCallback as NavigationGuard } from "./types"; From 77e5c25997a76635350363296afb31b722ca5896 Mon Sep 17 00:00:00 2001 From: Jack Stenglein Date: Tue, 11 Feb 2025 08:46:43 -0600 Subject: [PATCH 2/2] Update README.md Adds instructions on using exported NavigationGuardProviderContext and clarifies custom dialog example --- README.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/README.md b/README.md index aae0f15..f2b3476 100644 --- a/README.md +++ b/README.md @@ -73,4 +73,47 @@ pnpm install next-navigation-guard ) ``` + Note that `navGuard.active` is only set for client-side navigation. If the user attempts to close the tab or + manually navigates to a new URL, the navigation guard will fallback to the browser's default confirmation + dialog. This is an inherent limitation of modern browsers. + +- Hooking into the library's underlying state + + This is an advanced use-case if, for example, you have a special routing setup that prevents you from using + the built-in NextJS router or Link component. + + ```tsx + import { NavigationGuardProviderContext } from 'next-navigation-guard'; + + function SpecialLink({ href }: { href: string }) { + const guardMapRef = useContext(NavigationGuardProivderContext); + let guardNavigation: React.MouseEventHandler | undefined = undefined; + + for (const guard of guardMapRef.current.values()) { + const { enabled, callback } = guard; + if (!enabled({ to: href, type: 'push' })) continue; + + guardNavigation = (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + + let confirmed = callback({ to: href, type: 'push' }); + if (typeof confirmed === 'boolean') { + confirmed = Promise.resolve(confirmed); + } + + void confirmed.then((confirmed) => { + if (!confirmed) return; + + guard.enabled = () => false; + window.location.href = href; + }); + }; + break; + } + + return Click Here; + } + ``` + See working example in example/ directory and its `NavigationGuardToggle` component.