Skip to content

Commit 10f266b

Browse files
authored
Merge pull request #58 from LayerXcom/feat/disable-for-testing
Add disableForTesting option to useNavigationGuard
2 parents 5e4d2c4 + 790c96f commit 10f266b

5 files changed

Lines changed: 26 additions & 8 deletions

File tree

.github/workflows/e2e-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ jobs:
2424
"15.4",
2525
"15.5",
2626
"16.0",
27+
"16.1",
2728
]
2829
node-version: [20]
2930
steps:

CHANGELOG

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.3.0] - 2026-02-26
11+
12+
### Added
13+
14+
- Add `disableForTesting` option to `useNavigationGuard` to make the hook a complete no-op without requiring `NavigationGuardProvider` context, intended for test and storybook environments.
15+
- Support Next.js 16 as peer dependency and add E2E CI targets for v16.0 and v16.1.
16+
1017
## [0.2.0] - 2025-06-28
1118

1219
### Added
@@ -38,7 +45,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3845

3946
- The initial release of next-navigation-guard.
4047

41-
[unreleased]: https://github.com/LayerXcom/next-navigation-guard/compare/v0.2.0...HEAD
48+
[unreleased]: https://github.com/LayerXcom/next-navigation-guard/compare/v0.3.0...HEAD
49+
[0.3.0]: https://github.com/LayerXcom/next-navigation-guard/compare/v0.2.0...v0.3.0
4250
[0.2.0]: https://github.com/LayerXcom/next-navigation-guard/releases/tag/v0.2.0
4351
[0.1.2]: https://github.com/LayerXcom/next-navigation-guard/releases/tag/v0.1.2
4452
[0.1.1]: https://github.com/LayerXcom/next-navigation-guard/releases/tag/v0.1.1

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "next-navigation-guard",
3-
"version": "0.2.0",
3+
"version": "0.3.0",
44
"description": "Navigation Guard for Next.js App Router and Pages Router.",
55
"main": "./dist/index.js",
66
"module": "./dist/index.js",
@@ -32,7 +32,7 @@
3232
},
3333
"packageManager": "pnpm@9.9.0+sha512.60c18acd138bff695d339be6ad13f7e936eea6745660d4cc4a776d5247c540d0edee1a563695c183a66eb917ef88f2b4feb1fc25f32a7adcadc7aaf3438e99c1",
3434
"peerDependencies": {
35-
"next": "^14 || ^15",
35+
"next": "^14 || ^15 || ^16",
3636
"react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc"
3737
},
3838
"devDependencies": {

src/hooks/useNavigationGuard.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { debug } from "../utils/debug";
88
export function useNavigationGuard(options: NavigationGuardOptions) {
99
const callbackId = useId();
1010
const guardMapRef = useContext(NavigationGuardProviderContext);
11-
if (!guardMapRef)
11+
if (!guardMapRef && !options.disableForTesting)
1212
throw new Error(
1313
"useNavigationGuard must be used within a NavigationGuardProvider"
1414
);
@@ -18,6 +18,8 @@ export function useNavigationGuard(options: NavigationGuardOptions) {
1818
} | null>(null);
1919

2020
useIsomorphicLayoutEffect(() => {
21+
if (options.disableForTesting) return;
22+
2123
const callback: NavigationGuardCallback = (params) => {
2224
debug(`Guard callback called with:`, params);
2325
if (options.confirm) {
@@ -36,17 +38,17 @@ export function useNavigationGuard(options: NavigationGuardOptions) {
3638

3739
const enabled = options.enabled;
3840

39-
guardMapRef.current.set(callbackId, {
41+
guardMapRef!.current.set(callbackId, {
4042
enabled: typeof enabled === "function" ? enabled : () => enabled ?? true,
4143
callback,
4244
});
4345

4446
return () => {
45-
guardMapRef.current.delete(callbackId);
47+
guardMapRef!.current.delete(callbackId);
4648
};
47-
}, [callbackId, guardMapRef, options.confirm, options.enabled]);
49+
}, [callbackId, guardMapRef, options.confirm, options.enabled, options.disableForTesting]);
4850

49-
const active = pendingState !== null;
51+
const active = options.disableForTesting ? false : pendingState !== null;
5052

5153
const accept = useCallback(() => {
5254
if (!pendingState) return;

src/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ export interface NavigationGuardOptions {
22
/** @default true */
33
enabled?: boolean | ((params: NavigationGuardParams) => boolean);
44
confirm?: NavigationGuardCallback;
5+
/**
6+
* When true, the hook becomes a complete no-op: no guard is registered,
7+
* NavigationGuardProvider context is not required, and `active` is always false.
8+
* Intended for test and storybook environments.
9+
* @default false
10+
*/
11+
disableForTesting?: boolean;
512
}
613

714
export interface NavigationGuardParams {

0 commit comments

Comments
 (0)