@@ -12,7 +12,7 @@ import {
1212
1313export { createHashHistory , createBrowserHistory , createMemoryHistory }
1414
15- //
15+ // Types
1616
1717declare global {
1818 const __DEV__ : boolean
@@ -43,7 +43,7 @@ export type UseGeneric<
4343 ? Partial < Maybe < TGenerics [ TGeneric ] , DefaultGenerics [ TGeneric ] > >
4444 : Maybe < TGenerics [ TGeneric ] , DefaultGenerics [ TGeneric ] >
4545
46- export type ReactLocationOptions < TGenerics > = {
46+ export type ReactLocationOptions = {
4747 // The history object to be used internally by react-location
4848 // A history will be created automatically if not provided.
4949 history ?: BrowserHistory | MemoryHistory | HashHistory
@@ -52,7 +52,6 @@ export type ReactLocationOptions<TGenerics> = {
5252 basepath ?: string
5353 stringifySearch ?: SearchSerializer
5454 parseSearch ?: SearchParser
55- options ?: RouterOptions < TGenerics >
5655}
5756
5857type SearchSerializer = ( searchObj : Record < string , any > ) => string
@@ -91,6 +90,7 @@ export type RouteBasic<TGenerics extends PartialGenerics = DefaultGenerics> = {
9190 pendingMs ?: number
9291 // _If the `pendingElement` is shown_, the minimum duration for which it will be visible.
9392 pendingMinMs ?: number
93+ searchFilters ?: SearchFilter < TGenerics > [ ]
9494 // An array of child routes
9595 children ?: Route < TGenerics > [ ]
9696 import ?: never
@@ -114,6 +114,11 @@ export type MatchLocation<TGenerics extends PartialGenerics = DefaultGenerics> =
114114
115115export type SearchPredicate < TSearch > = ( search : TSearch ) => any
116116
117+ export type SearchFilter < TGenerics > = (
118+ prev : UseGeneric < TGenerics , 'Search' > ,
119+ next : UseGeneric < TGenerics , 'Search' > ,
120+ ) => UseGeneric < TGenerics , 'Search' >
121+
117122export type SyncOrAsyncElement <
118123 TGenerics extends PartialGenerics = DefaultGenerics ,
119124> = React . ReactNode | AsyncElement < TGenerics >
@@ -195,6 +200,7 @@ export type BuildNextOptions<
195200 hash ?: Updater < string >
196201 from ?: Partial < Location < TGenerics > >
197202 key ?: string
203+ __searchFilters ?: SearchFilter < TGenerics > [ ]
198204}
199205
200206export type NavigateOptions < TGenerics > = BuildNextOptions < TGenerics > & {
@@ -208,7 +214,7 @@ export type PromptProps = {
208214}
209215
210216export type LinkProps < TGenerics extends PartialGenerics = DefaultGenerics > =
211- Omit < React . AnchorHTMLAttributes < HTMLAnchorElement > , 'href' > & {
217+ Omit < React . AnchorHTMLAttributes < HTMLAnchorElement > , 'href' | 'children' > & {
212218 // The absolute or relative destination pathname
213219 to ?: string | number | null
214220 // The new search object or a function to update it
@@ -223,6 +229,9 @@ export type LinkProps<TGenerics extends PartialGenerics = DefaultGenerics> =
223229 activeOptions ?: ActiveOptions
224230 // If set, will preload the linked route on hover and cache it for this many milliseconds in hopes that the user will eventually navigate there.
225231 preload ?: number
232+ children ?:
233+ | React . ReactNode
234+ | ( ( state : { isActive : boolean } ) => React . ReactNode )
226235 }
227236
228237type ActiveOptions = {
@@ -283,7 +292,15 @@ export type FilterRoutesFn = <
283292 routes : Route < TGenerics > [ ] ,
284293) => Route < TGenerics > [ ]
285294
286- //
295+ export type RouterPropsType <
296+ TGenerics extends PartialGenerics = DefaultGenerics ,
297+ > = RouterProps < TGenerics >
298+
299+ export type RouterType < TGenerics extends PartialGenerics = DefaultGenerics > = (
300+ props : RouterProps < TGenerics > ,
301+ ) => JSX . Element
302+
303+ // Source
287304
288305const LocationContext = React . createContext < ReactLocation < any > > ( null ! )
289306const MatchesContext = React . createContext < Match < any > [ ] > ( null ! )
@@ -307,17 +324,6 @@ export class ReactLocation<
307324 basepath : string
308325 stringifySearch : SearchSerializer
309326 parseSearch : SearchParser
310- options : {
311- filterRoutes : FilterRoutesFn
312- defaultLinkPreloadMaxAge : number
313- defaultLoaderMaxAge : number
314- useErrorBoundary : boolean
315- defaultElement ?: SyncOrAsyncElement < TLocationGenerics >
316- defaultErrorElement ?: SyncOrAsyncElement < TLocationGenerics >
317- defaultPendingElement ?: SyncOrAsyncElement < TLocationGenerics >
318- defaultPendingMs ?: number
319- defaultPendingMinMs ?: number
320- }
321327
322328 current : Location < TLocationGenerics >
323329 destroy : ( ) => void
@@ -329,18 +335,11 @@ export class ReactLocation<
329335 listeners : ListenerFn [ ] = [ ]
330336 isTransitioning : boolean = false
331337
332- constructor ( options ?: ReactLocationOptions < TLocationGenerics > ) {
338+ constructor ( options ?: ReactLocationOptions ) {
333339 this . history = options ?. history || createDefaultHistory ( )
334340 this . basepath = options ?. basepath || '/'
335341 this . stringifySearch = options ?. stringifySearch ?? defaultStringifySearch
336342 this . parseSearch = options ?. parseSearch ?? defaultParseSearch
337- this . options = {
338- ...options ?. options ,
339- filterRoutes : options ?. options ?. filterRoutes ?? ( ( d ) => d ) ,
340- defaultLinkPreloadMaxAge : options ?. options ?. defaultLinkPreloadMaxAge ?? 0 ,
341- defaultLoaderMaxAge : options ?. options ?. defaultLoaderMaxAge ?? 0 ,
342- useErrorBoundary : options ?. options ?. useErrorBoundary ?? false ,
343- }
344343
345344 this . current = this . parseLocation ( this . history . location )
346345
@@ -373,13 +372,21 @@ export class ReactLocation<
373372 }
374373
375374 const pathname = resolvePath ( from . pathname , `${ dest . to ?? '.' } ` )
375+
376376 const updatedSearch =
377- dest . search === true
377+ ( dest . search === true
378378 ? from . search
379- : functionalUpdate ( dest . search , from . search )
380- const search = updatedSearch
381- ? replaceEqualDeep ( from . search , updatedSearch )
382- : { }
379+ : functionalUpdate ( dest . search , from . search ) ) ?? { }
380+
381+ const filteredSearch = dest . __searchFilters ?. length
382+ ? dest . __searchFilters . reduce (
383+ ( prev , next ) => next ( prev , updatedSearch ) ,
384+ updatedSearch ,
385+ )
386+ : updatedSearch
387+
388+ const search = replaceEqualDeep ( from . search , filteredSearch )
389+
383390 const searchStr = this . stringifySearch ( search )
384391 let hash = functionalUpdate ( dest . hash , from . hash )
385392 hash = hash ? `#${ hash } ` : ''
@@ -445,6 +452,7 @@ export class ReactLocation<
445452 previousLocation ?: Location < TGenerics > ,
446453 ) : Location < TGenerics > {
447454 const parsedSearch = this . parseSearch ( location . search )
455+
448456 return {
449457 pathname : location . pathname ,
450458 searchStr : location . search ,
@@ -456,14 +464,6 @@ export class ReactLocation<
456464 }
457465}
458466
459- export type RouterPropsType <
460- TGenerics extends PartialGenerics = DefaultGenerics ,
461- > = RouterProps < TGenerics >
462-
463- export type RouterType < TGenerics extends PartialGenerics = DefaultGenerics > = (
464- props : RouterProps < TGenerics > ,
465- ) => JSX . Element
466-
467467export function Router < TGenerics extends PartialGenerics = DefaultGenerics > ( {
468468 children,
469469 location,
@@ -485,16 +485,11 @@ function RouterInner<TGenerics extends PartialGenerics = DefaultGenerics>({
485485 if ( ! matchCacheRef . current ) matchCacheRef . current = { }
486486 const matchCache = matchCacheRef . current
487487
488- const options = {
489- ...location . options ,
490- ...rest ,
491- }
492-
493488 const [ state , setState ] = React . useState < RouterState < TGenerics > > ( {
494489 transition : {
495490 status : 'ready' ,
496491 location : location . current ,
497- matches : options . initialMatches ?? [ ] ,
492+ matches : rest . initialMatches ?? [ ] ,
498493 } ,
499494 } )
500495
@@ -573,7 +568,7 @@ function RouterInner<TGenerics extends PartialGenerics = DefaultGenerics>({
573568 const router = React . useMemo (
574569 ( ) : Router < TGenerics > => ( {
575570 ...state ,
576- ...options ,
571+ ...rest ,
577572 __ : {
578573 matchCache,
579574 setState : setState ,
@@ -631,7 +626,7 @@ function RouterInner<TGenerics extends PartialGenerics = DefaultGenerics>({
631626 } )
632627 } )
633628
634- matchLoader . loadData ( { maxAge : options . defaultLoaderMaxAge } )
629+ matchLoader . loadData ( { maxAge : rest . defaultLoaderMaxAge } )
635630 matchLoader . startPending ( )
636631 } catch ( err ) {
637632 console . error ( err )
@@ -1132,6 +1127,23 @@ export type LinkType<TGenerics extends PartialGenerics = DefaultGenerics> = (
11321127 props : LinkProps < TGenerics > ,
11331128) => JSX . Element
11341129
1130+ // export function useParentMatches<TGenerics>()
1131+ // {
1132+ // const router = useRouter<TGenerics>()
1133+ // const match = useMatch<TGenerics>()
1134+ // const matchIndex = router.transition.matches.findIndex(d => d.id === match.id)
1135+ // return router.transition.matches.slice(0, matchIndex)
1136+ // }
1137+
1138+ // export function useSearchFilters<TGenerics>() {
1139+ // const router = useRouter<TGenerics>()
1140+ // const match = useMatch<TGenerics>()
1141+ // const matchIndex = router.transition.matches.findIndex(
1142+ // (d) => d.id === match.id,
1143+ // )
1144+ // return router.transition.matches.slice(0, matchIndex)
1145+ // }
1146+
11351147export const Link = React . forwardRef ( function Link <
11361148 TGenerics extends PartialGenerics = DefaultGenerics ,
11371149> (
@@ -1175,6 +1187,7 @@ export const Link = React.forwardRef(function Link<
11751187 search,
11761188 hash,
11771189 from : { pathname : match . pathname } ,
1190+ // __searchFilters:
11781191 } )
11791192
11801193 // The click handler
@@ -1229,14 +1242,14 @@ export const Link = React.forwardRef(function Link<
12291242 const hashTest = activeOptions ?. includeHash ? hashIsEqual : true
12301243
12311244 // The final "active" test
1232- const isCurrent = pathTest && hashTest
1245+ const isActive = pathTest && hashTest
12331246
12341247 // Get the active props
12351248 const {
12361249 style : activeStyle = { } ,
12371250 className : activeClassName = '' ,
12381251 ...activeRest
1239- } = isCurrent ? getActiveProps ( ) : { }
1252+ } = isActive ? getActiveProps ( ) : { }
12401253
12411254 return (
12421255 < a
@@ -1254,7 +1267,8 @@ export const Link = React.forwardRef(function Link<
12541267 [ className , activeClassName ] . filter ( Boolean ) . join ( ' ' ) || undefined ,
12551268 ...rest ,
12561269 ...activeRest ,
1257- children,
1270+ children :
1271+ typeof children === 'function' ? children ( { isActive } ) : children ,
12581272 } }
12591273 />
12601274 )
0 commit comments