1
1
import mitt from 'mitt'
2
- import { useEffect , useState } from 'react'
2
+ import {
3
+ createContext ,
4
+ createElement ,
5
+ useContext ,
6
+ useEffect ,
7
+ useMemo ,
8
+ useState ,
9
+ type ReactNode
10
+ } from 'react'
3
11
import { renderQueryString } from '../url-encoding'
4
12
import { createAdapterProvider } from './lib/context'
5
13
import type { AdapterOptions } from './lib/defs'
6
14
import { patchHistory , type SearchParamsSyncEmitter } from './lib/patch-history'
7
15
8
16
const emitter : SearchParamsSyncEmitter = mitt ( )
9
17
10
- function updateUrl ( search : URLSearchParams , options : AdapterOptions ) {
11
- const url = new URL ( location . href )
12
- url . search = renderQueryString ( search )
13
- const method =
14
- options . history === 'push' ? history . pushState : history . replaceState
15
- method . call ( history , history . state , '' , url )
16
- emitter . emit ( 'update' , search )
17
- if ( options . scroll === true ) {
18
- window . scrollTo ( { top : 0 } )
18
+ function generateUpdateUrlFn ( fullPageNavigationOnShallowFalseUpdates : boolean ) {
19
+ return function updateUrl ( search : URLSearchParams , options : AdapterOptions ) {
20
+ const url = new URL ( location . href )
21
+ url . search = renderQueryString ( search )
22
+ if ( fullPageNavigationOnShallowFalseUpdates && options . shallow === false ) {
23
+ const method =
24
+ options . history === 'push' ? location . assign : location . replace
25
+ method . call ( location , url )
26
+ } else {
27
+ const method =
28
+ options . history === 'push' ? history . pushState : history . replaceState
29
+ method . call ( history , history . state , '' , url )
30
+ }
31
+ emitter . emit ( 'update' , search )
32
+ if ( options . scroll === true ) {
33
+ window . scrollTo ( { top : 0 } )
34
+ }
19
35
}
20
36
}
21
37
38
+ const NuqsReactAdapterContext = createContext ( {
39
+ fullPageNavigationOnShallowFalseUpdates : false
40
+ } )
41
+
22
42
function useNuqsReactAdapter ( ) {
43
+ const { fullPageNavigationOnShallowFalseUpdates } = useContext (
44
+ NuqsReactAdapterContext
45
+ )
23
46
const [ searchParams , setSearchParams ] = useState ( ( ) => {
24
47
if ( typeof location === 'undefined' ) {
25
48
return new URLSearchParams ( )
@@ -39,13 +62,31 @@ function useNuqsReactAdapter() {
39
62
window . removeEventListener ( 'popstate' , onPopState )
40
63
}
41
64
} , [ ] )
65
+ const updateUrl = useMemo (
66
+ ( ) => generateUpdateUrlFn ( fullPageNavigationOnShallowFalseUpdates ) ,
67
+ [ fullPageNavigationOnShallowFalseUpdates ]
68
+ )
42
69
return {
43
70
searchParams,
44
71
updateUrl
45
72
}
46
73
}
47
74
48
- export const NuqsAdapter = createAdapterProvider ( useNuqsReactAdapter )
75
+ const NuqsReactAdapter = createAdapterProvider ( useNuqsReactAdapter )
76
+
77
+ export function NuqsAdapter ( {
78
+ children,
79
+ fullPageNavigationOnShallowFalseUpdates = false
80
+ } : {
81
+ children : ReactNode
82
+ fullPageNavigationOnShallowFalseUpdates ?: boolean
83
+ } ) {
84
+ return createElement (
85
+ NuqsReactAdapterContext . Provider ,
86
+ { value : { fullPageNavigationOnShallowFalseUpdates } } ,
87
+ createElement ( NuqsReactAdapter , null , children )
88
+ )
89
+ }
49
90
50
91
/**
51
92
* Opt-in to syncing shallow updates of the URL with the useOptimisticSearchParams hook.
0 commit comments