@tanstack/react-router 0.0.1-beta.204 → 0.0.1-beta.206
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/RouterProvider.js +963 -0
- package/build/cjs/RouterProvider.js.map +1 -0
- package/build/cjs/fileRoute.js +29 -0
- package/build/cjs/fileRoute.js.map +1 -0
- package/build/cjs/index.js +69 -21
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/path.js +211 -0
- package/build/cjs/path.js.map +1 -0
- package/build/cjs/qss.js +65 -0
- package/build/cjs/qss.js.map +1 -0
- package/build/cjs/react.js +148 -190
- package/build/cjs/react.js.map +1 -1
- package/build/cjs/redirects.js +27 -0
- package/build/cjs/redirects.js.map +1 -0
- package/build/cjs/route.js +136 -0
- package/build/cjs/route.js.map +1 -0
- package/build/cjs/router.js +203 -0
- package/build/cjs/router.js.map +1 -0
- package/build/cjs/searchParams.js +83 -0
- package/build/cjs/searchParams.js.map +1 -0
- package/build/cjs/utils.js +196 -0
- package/build/cjs/utils.js.map +1 -0
- package/build/esm/index.js +1801 -211
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +385 -164
- package/build/types/RouteMatch.d.ts +23 -0
- package/build/types/RouterProvider.d.ts +54 -0
- package/build/types/awaited.d.ts +0 -8
- package/build/types/defer.d.ts +0 -0
- package/build/types/fileRoute.d.ts +17 -0
- package/build/types/history.d.ts +7 -0
- package/build/types/index.d.ts +17 -4
- package/build/types/link.d.ts +98 -0
- package/build/types/location.d.ts +14 -0
- package/build/types/path.d.ts +16 -0
- package/build/types/qss.d.ts +2 -0
- package/build/types/react.d.ts +23 -83
- package/build/types/redirects.d.ts +10 -0
- package/build/types/route.d.ts +222 -0
- package/build/types/routeInfo.d.ts +22 -0
- package/build/types/router.d.ts +115 -0
- package/build/types/scroll-restoration.d.ts +0 -3
- package/build/types/searchParams.d.ts +7 -0
- package/build/types/utils.d.ts +48 -0
- package/build/umd/index.development.js +1118 -1540
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +2 -33
- package/build/umd/index.production.js.map +1 -1
- package/package.json +2 -4
- package/src/RouteMatch.ts +28 -0
- package/src/RouterProvider.tsx +1390 -0
- package/src/awaited.tsx +40 -40
- package/src/defer.ts +55 -0
- package/src/fileRoute.ts +143 -0
- package/src/history.ts +8 -0
- package/src/index.tsx +18 -5
- package/src/link.ts +347 -0
- package/src/location.ts +14 -0
- package/src/path.ts +256 -0
- package/src/qss.ts +53 -0
- package/src/react.tsx +174 -422
- package/src/redirects.ts +31 -0
- package/src/route.ts +710 -0
- package/src/routeInfo.ts +68 -0
- package/src/router.ts +373 -0
- package/src/scroll-restoration.tsx +205 -27
- package/src/searchParams.ts +78 -0
- package/src/utils.ts +257 -0
- package/build/cjs/awaited.js +0 -45
- package/build/cjs/awaited.js.map +0 -1
- package/build/cjs/scroll-restoration.js +0 -56
- package/build/cjs/scroll-restoration.js.map +0 -1
package/src/react.tsx
CHANGED
|
@@ -1,193 +1,46 @@
|
|
|
1
1
|
import * as React from 'react'
|
|
2
|
-
import { NoInfer, useStore } from '@tanstack/react-store'
|
|
3
2
|
import invariant from 'tiny-invariant'
|
|
4
3
|
import warning from 'tiny-warning'
|
|
5
4
|
import {
|
|
6
|
-
functionalUpdate,
|
|
7
|
-
last,
|
|
8
|
-
pick,
|
|
9
|
-
MatchRouteOptions,
|
|
10
|
-
RegisteredRouter,
|
|
11
|
-
RouterOptions,
|
|
12
|
-
Router,
|
|
13
|
-
RouteMatch,
|
|
14
|
-
RouteByPath,
|
|
15
|
-
AnyRoute,
|
|
16
|
-
AnyRouteProps,
|
|
17
5
|
LinkOptions,
|
|
18
6
|
ToOptions,
|
|
19
7
|
ResolveRelativePath,
|
|
20
8
|
NavigateOptions,
|
|
21
|
-
|
|
22
|
-
|
|
9
|
+
} from './link'
|
|
10
|
+
import {
|
|
23
11
|
AnySearchSchema,
|
|
24
|
-
|
|
25
|
-
RouteContext,
|
|
12
|
+
AnyPathParams,
|
|
26
13
|
AnyContext,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
14
|
+
AnyRoute,
|
|
15
|
+
rootRouteId,
|
|
16
|
+
} from './route'
|
|
17
|
+
import {
|
|
31
18
|
RoutePaths,
|
|
32
|
-
|
|
19
|
+
RouteByPath,
|
|
33
20
|
RouteIds,
|
|
34
|
-
RouteById,
|
|
35
21
|
ParseRoute,
|
|
22
|
+
RoutesById,
|
|
23
|
+
RouteById,
|
|
36
24
|
AllParams,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
} from '@tanstack/router-core'
|
|
25
|
+
} from './routeInfo'
|
|
26
|
+
import { RegisteredRouter, RouterOptions, Router, RouterState } from './router'
|
|
27
|
+
import { RouteMatch } from './RouteMatch'
|
|
28
|
+
import { NoInfer, functionalUpdate, last } from './utils'
|
|
29
|
+
import { MatchRouteOptions, RouterContext } from './RouterProvider'
|
|
30
|
+
import { routerContext } from './RouterProvider'
|
|
44
31
|
|
|
45
32
|
const useLayoutEffect =
|
|
46
33
|
typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect
|
|
47
34
|
|
|
48
|
-
declare module '@tanstack/router-core' {
|
|
49
|
-
interface RouterOptions<
|
|
50
|
-
TRouteTree extends AnyRoute,
|
|
51
|
-
TDehydrated extends Record<string, any>,
|
|
52
|
-
> {
|
|
53
|
-
Wrap?: React.ComponentType<{
|
|
54
|
-
children: React.ReactNode
|
|
55
|
-
dehydratedState?: TDehydrated
|
|
56
|
-
}>
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
interface RegisterRouteComponent<
|
|
60
|
-
TLoader = unknown,
|
|
61
|
-
TFullSearchSchema extends Record<string, any> = AnySearchSchema,
|
|
62
|
-
TAllParams extends AnyPathParams = AnyPathParams,
|
|
63
|
-
TAllContext extends Record<string, any> = AnyContext,
|
|
64
|
-
> {
|
|
65
|
-
RouteComponent: RouteComponent<
|
|
66
|
-
RouteProps<TLoader, TFullSearchSchema, TAllParams, TAllContext>
|
|
67
|
-
>
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
interface RegisterErrorRouteComponent<
|
|
71
|
-
TFullSearchSchema extends Record<string, any> = AnySearchSchema,
|
|
72
|
-
TAllParams extends AnyPathParams = AnyPathParams,
|
|
73
|
-
TAllContext extends Record<string, any> = AnyContext,
|
|
74
|
-
> {
|
|
75
|
-
ErrorRouteComponent: RouteComponent<
|
|
76
|
-
ErrorRouteProps<TFullSearchSchema, TAllParams, TAllContext>
|
|
77
|
-
>
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
interface RegisterPendingRouteComponent<
|
|
81
|
-
TFullSearchSchema extends Record<string, any> = AnySearchSchema,
|
|
82
|
-
TAllParams extends AnyPathParams = AnyPathParams,
|
|
83
|
-
TAllContext extends Record<string, any> = AnyContext,
|
|
84
|
-
> {
|
|
85
|
-
PendingRouteComponent: RouteComponent<
|
|
86
|
-
PendingRouteProps<TFullSearchSchema, TAllParams, TAllContext>
|
|
87
|
-
>
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
interface Route<
|
|
91
|
-
TParentRoute extends RouteConstraints['TParentRoute'] = AnyRoute,
|
|
92
|
-
TPath extends RouteConstraints['TPath'] = '/',
|
|
93
|
-
TFullPath extends RouteConstraints['TFullPath'] = ResolveFullPath<
|
|
94
|
-
TParentRoute,
|
|
95
|
-
TPath
|
|
96
|
-
>,
|
|
97
|
-
TCustomId extends RouteConstraints['TCustomId'] = string,
|
|
98
|
-
TId extends RouteConstraints['TId'] = ResolveId<
|
|
99
|
-
TParentRoute,
|
|
100
|
-
TCustomId,
|
|
101
|
-
TPath
|
|
102
|
-
>,
|
|
103
|
-
TLoaderContext extends RouteConstraints['TLoaderContext'] = AnyContext,
|
|
104
|
-
TLoader = unknown,
|
|
105
|
-
TSearchSchema extends RouteConstraints['TSearchSchema'] = {},
|
|
106
|
-
TFullSearchSchema extends RouteConstraints['TFullSearchSchema'] = ResolveFullSearchSchema<
|
|
107
|
-
TParentRoute,
|
|
108
|
-
TSearchSchema
|
|
109
|
-
>,
|
|
110
|
-
TParams extends RouteConstraints['TParams'] = Expand<
|
|
111
|
-
Record<ParsePathParams<TPath>, string>
|
|
112
|
-
>,
|
|
113
|
-
TAllParams extends RouteConstraints['TAllParams'] = ResolveAllParams<
|
|
114
|
-
TParentRoute,
|
|
115
|
-
TParams
|
|
116
|
-
>,
|
|
117
|
-
TRouteContext extends RouteConstraints['TRouteContext'] = RouteContext,
|
|
118
|
-
TAllContext extends RouteConstraints['TAllContext'] = Expand<
|
|
119
|
-
DeepMergeAll<
|
|
120
|
-
[
|
|
121
|
-
IsAny<TParentRoute['types']['context'], {}>,
|
|
122
|
-
TLoaderContext,
|
|
123
|
-
TRouteContext,
|
|
124
|
-
]
|
|
125
|
-
>
|
|
126
|
-
>,
|
|
127
|
-
TRouterContext extends RouteConstraints['TRouterContext'] = AnyContext,
|
|
128
|
-
TChildren extends RouteConstraints['TChildren'] = unknown,
|
|
129
|
-
TRouteTree extends RouteConstraints['TRouteTree'] = AnyRoute,
|
|
130
|
-
> {
|
|
131
|
-
useMatch: <TSelected = TAllContext>(opts?: {
|
|
132
|
-
select?: (search: TAllContext) => TSelected
|
|
133
|
-
}) => TSelected
|
|
134
|
-
useLoader: <TSelected = TLoader>(opts?: {
|
|
135
|
-
select?: (search: TLoader) => TSelected
|
|
136
|
-
}) => UseLoaderResult<TSelected>
|
|
137
|
-
useRouteContext: <TSelected = TAllContext>(opts?: {
|
|
138
|
-
select?: (search: TAllContext) => TSelected
|
|
139
|
-
}) => TSelected
|
|
140
|
-
useSearch: <TSelected = TFullSearchSchema>(opts?: {
|
|
141
|
-
select?: (search: TFullSearchSchema) => TSelected
|
|
142
|
-
}) => TSelected
|
|
143
|
-
useParams: <TSelected = TAllParams>(opts?: {
|
|
144
|
-
select?: (search: TAllParams) => TSelected
|
|
145
|
-
}) => TSelected
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
interface RegisterRouteProps<
|
|
149
|
-
TLoader = unknown,
|
|
150
|
-
TFullSearchSchema extends Record<string, any> = AnySearchSchema,
|
|
151
|
-
TAllParams extends AnyPathParams = AnyPathParams,
|
|
152
|
-
TAllContext extends Record<string, any> = AnyContext,
|
|
153
|
-
> {
|
|
154
|
-
RouteProps: RouteProps<TLoader, TFullSearchSchema, TAllParams, TAllContext>
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
interface RegisterPendingRouteProps<
|
|
158
|
-
TFullSearchSchema extends Record<string, any> = AnySearchSchema,
|
|
159
|
-
TAllParams extends AnyPathParams = AnyPathParams,
|
|
160
|
-
TAllContext extends Record<string, any> = AnyContext,
|
|
161
|
-
> {
|
|
162
|
-
PendingRouteProps: PendingRouteProps<
|
|
163
|
-
TFullSearchSchema,
|
|
164
|
-
TAllParams,
|
|
165
|
-
TAllContext
|
|
166
|
-
>
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
interface RegisterErrorRouteProps<
|
|
170
|
-
TFullSearchSchema extends Record<string, any> = AnySearchSchema,
|
|
171
|
-
TAllParams extends AnyPathParams = AnyPathParams,
|
|
172
|
-
TAllContext extends Record<string, any> = AnyContext,
|
|
173
|
-
> {
|
|
174
|
-
ErrorRouteProps: ErrorRouteProps
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
35
|
export type RouteProps<
|
|
179
|
-
TLoader = unknown,
|
|
180
36
|
TFullSearchSchema extends Record<string, any> = AnySearchSchema,
|
|
181
37
|
TAllParams extends AnyPathParams = AnyPathParams,
|
|
182
38
|
TAllContext extends Record<string, any> = AnyContext,
|
|
183
39
|
> = {
|
|
184
|
-
useLoader: <TSelected = TLoader>(opts?: {
|
|
185
|
-
select?: (search: TLoader) => TSelected
|
|
186
|
-
}) => UseLoaderResult<TSelected>
|
|
187
40
|
useMatch: <TSelected = TAllContext>(opts?: {
|
|
188
41
|
select?: (search: TAllContext) => TSelected
|
|
189
42
|
}) => TSelected
|
|
190
|
-
|
|
43
|
+
useRouteMeta: <TSelected = TAllContext>(opts?: {
|
|
191
44
|
select?: (search: TAllContext) => TSelected
|
|
192
45
|
}) => TSelected
|
|
193
46
|
useSearch: <TSelected = TFullSearchSchema>(opts?: {
|
|
@@ -205,43 +58,13 @@ export type ErrorRouteProps<
|
|
|
205
58
|
> = {
|
|
206
59
|
error: unknown
|
|
207
60
|
info: { componentStack: string }
|
|
208
|
-
} &
|
|
209
|
-
RouteProps<unknown, TFullSearchSchema, TAllParams, TAllContext>,
|
|
210
|
-
'useLoader'
|
|
211
|
-
>
|
|
61
|
+
} & RouteProps<TFullSearchSchema, TAllParams, TAllContext>
|
|
212
62
|
|
|
213
63
|
export type PendingRouteProps<
|
|
214
64
|
TFullSearchSchema extends Record<string, any> = AnySearchSchema,
|
|
215
65
|
TAllParams extends AnyPathParams = AnyPathParams,
|
|
216
66
|
TAllContext extends Record<string, any> = AnyContext,
|
|
217
|
-
> =
|
|
218
|
-
RouteProps<unknown, TFullSearchSchema, TAllParams, TAllContext>,
|
|
219
|
-
'useLoader'
|
|
220
|
-
>
|
|
221
|
-
|
|
222
|
-
Route.__onInit = (route) => {
|
|
223
|
-
Object.assign(route, {
|
|
224
|
-
useMatch: (opts = {}) => {
|
|
225
|
-
return useMatch({ ...opts, from: route.id }) as any
|
|
226
|
-
},
|
|
227
|
-
useLoader: (opts = {}) => {
|
|
228
|
-
return useLoader({ ...opts, from: route.id }) as any
|
|
229
|
-
},
|
|
230
|
-
useRouteContext: (opts: any = {}) => {
|
|
231
|
-
return useMatch({
|
|
232
|
-
...opts,
|
|
233
|
-
from: route.id,
|
|
234
|
-
select: (d: any) => (opts?.select ? opts.select(d.context) : d.context),
|
|
235
|
-
} as any)
|
|
236
|
-
},
|
|
237
|
-
useSearch: (opts = {}) => {
|
|
238
|
-
return useSearch({ ...opts, from: route.id } as any)
|
|
239
|
-
},
|
|
240
|
-
useParams: (opts = {}) => {
|
|
241
|
-
return useParams({ ...opts, from: route.id } as any)
|
|
242
|
-
},
|
|
243
|
-
})
|
|
244
|
-
}
|
|
67
|
+
> = RouteProps<TFullSearchSchema, TAllParams, TAllContext>
|
|
245
68
|
|
|
246
69
|
//
|
|
247
70
|
|
|
@@ -255,16 +78,29 @@ export type AsyncRouteComponent<TProps> = SyncRouteComponent<TProps> & {
|
|
|
255
78
|
preload?: () => Promise<void>
|
|
256
79
|
}
|
|
257
80
|
|
|
258
|
-
export type
|
|
81
|
+
export type RouteComponent<
|
|
82
|
+
TFullSearchSchema extends Record<string, any>,
|
|
83
|
+
TAllParams extends AnyPathParams,
|
|
84
|
+
TAllContext extends Record<string, any>,
|
|
85
|
+
> = AsyncRouteComponent<RouteProps<TFullSearchSchema, TAllParams, TAllContext>>
|
|
259
86
|
|
|
260
|
-
export type
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
87
|
+
export type ErrorRouteComponent<
|
|
88
|
+
TFullSearchSchema extends Record<string, any>,
|
|
89
|
+
TAllParams extends AnyPathParams,
|
|
90
|
+
TAllContext extends Record<string, any>,
|
|
91
|
+
> = AsyncRouteComponent<
|
|
92
|
+
ErrorRouteProps<TFullSearchSchema, TAllParams, TAllContext>
|
|
93
|
+
>
|
|
264
94
|
|
|
265
|
-
export type
|
|
95
|
+
export type PendingRouteComponent<
|
|
96
|
+
TFullSearchSchema extends Record<string, any>,
|
|
97
|
+
TAllParams extends AnyPathParams,
|
|
98
|
+
TAllContext extends Record<string, any>,
|
|
99
|
+
> = AsyncRouteComponent<
|
|
100
|
+
PendingRouteProps<TFullSearchSchema, TAllParams, TAllContext>
|
|
101
|
+
>
|
|
266
102
|
|
|
267
|
-
export type RouteComponent<
|
|
103
|
+
export type AnyRouteComponent = RouteComponent<any, any, any>
|
|
268
104
|
|
|
269
105
|
export function lazyRouteComponent<
|
|
270
106
|
T extends Record<string, any>,
|
|
@@ -384,7 +220,7 @@ export function useLinkProps<
|
|
|
384
220
|
>(
|
|
385
221
|
options: MakeLinkPropsOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>,
|
|
386
222
|
): React.AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
387
|
-
const
|
|
223
|
+
const { buildLink, state: routerState } = useRouter()
|
|
388
224
|
const match = useMatch({
|
|
389
225
|
strict: false,
|
|
390
226
|
})
|
|
@@ -418,7 +254,7 @@ export function useLinkProps<
|
|
|
418
254
|
...rest
|
|
419
255
|
} = options
|
|
420
256
|
|
|
421
|
-
const linkInfo =
|
|
257
|
+
const linkInfo = buildLink(routerState, {
|
|
422
258
|
from: options.to ? match.pathname : undefined,
|
|
423
259
|
...options,
|
|
424
260
|
} as any)
|
|
@@ -543,11 +379,11 @@ export function Navigate<
|
|
|
543
379
|
TMaskFrom extends RoutePaths<TRouteTree> = '/',
|
|
544
380
|
TMaskTo extends string = '',
|
|
545
381
|
>(props: NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>): null {
|
|
546
|
-
const
|
|
382
|
+
const { navigate } = useRouter()
|
|
547
383
|
const match = useMatch({ strict: false })
|
|
548
384
|
|
|
549
385
|
useLayoutEffect(() => {
|
|
550
|
-
|
|
386
|
+
navigate({
|
|
551
387
|
from: props.to ? match.pathname : undefined,
|
|
552
388
|
...props,
|
|
553
389
|
} as any)
|
|
@@ -556,112 +392,42 @@ export function Navigate<
|
|
|
556
392
|
return null
|
|
557
393
|
}
|
|
558
394
|
|
|
559
|
-
export const
|
|
560
|
-
export const routerContext = React.createContext<RegisteredRouter>(null!)
|
|
561
|
-
|
|
395
|
+
export const matchesContext = React.createContext<RouteMatch[]>(null!)
|
|
562
396
|
export type RouterProps<
|
|
563
397
|
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
|
|
564
398
|
TDehydrated extends Record<string, any> = Record<string, any>,
|
|
565
399
|
> = Omit<RouterOptions<TRouteTree, TDehydrated>, 'context'> & {
|
|
566
400
|
router: Router<TRouteTree>
|
|
567
|
-
context?: Partial<RouterOptions<TRouteTree, TDehydrated>['
|
|
401
|
+
context?: Partial<RouterOptions<TRouteTree, TDehydrated>['meta']>
|
|
568
402
|
}
|
|
569
403
|
|
|
570
|
-
export function
|
|
571
|
-
select: (state: RegisteredRouter['state']) => TSelected
|
|
572
|
-
}): TSelected {
|
|
573
|
-
const router = useRouter()
|
|
574
|
-
return useStore(router.__store, opts?.select as any)
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
export function RouterProvider<
|
|
404
|
+
export function useRouter<
|
|
578
405
|
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
React.useEffect(() => {
|
|
584
|
-
let unsub
|
|
585
|
-
|
|
586
|
-
React.startTransition(() => {
|
|
587
|
-
unsub = router.mount()
|
|
588
|
-
})
|
|
589
|
-
|
|
590
|
-
return unsub
|
|
591
|
-
}, [router])
|
|
592
|
-
|
|
593
|
-
const Wrap = router.options.Wrap || React.Fragment
|
|
594
|
-
|
|
595
|
-
return (
|
|
596
|
-
<Wrap>
|
|
597
|
-
<routerContext.Provider value={router as any}>
|
|
598
|
-
<Matches />
|
|
599
|
-
</routerContext.Provider>
|
|
600
|
-
</Wrap>
|
|
601
|
-
)
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
function Matches() {
|
|
605
|
-
const router = useRouter()
|
|
606
|
-
|
|
607
|
-
const matchIds = useRouterState({
|
|
608
|
-
select: (state) => {
|
|
609
|
-
return state.renderedMatchIds
|
|
610
|
-
},
|
|
611
|
-
})
|
|
612
|
-
|
|
613
|
-
const locationKey = useRouterState({
|
|
614
|
-
select: (d) => d.resolvedLocation.state?.key,
|
|
615
|
-
})
|
|
616
|
-
|
|
617
|
-
const route = router.getRoute(rootRouteId)
|
|
618
|
-
|
|
619
|
-
const errorComponent = React.useCallback(
|
|
620
|
-
(props: any) => {
|
|
621
|
-
return React.createElement(ErrorComponent, {
|
|
622
|
-
...props,
|
|
623
|
-
useMatch: route.useMatch,
|
|
624
|
-
useRouteContext: route.useRouteContext,
|
|
625
|
-
useSearch: route.useSearch,
|
|
626
|
-
useParams: route.useParams,
|
|
627
|
-
})
|
|
628
|
-
},
|
|
629
|
-
[route],
|
|
630
|
-
)
|
|
631
|
-
|
|
632
|
-
return (
|
|
633
|
-
<matchIdsContext.Provider value={[undefined!, ...matchIds]}>
|
|
634
|
-
<CatchBoundary
|
|
635
|
-
resetKey={locationKey}
|
|
636
|
-
errorComponent={errorComponent}
|
|
637
|
-
onCatch={() => {
|
|
638
|
-
warning(
|
|
639
|
-
false,
|
|
640
|
-
`Error in router! Consider setting an 'errorComponent' in your RootRoute! 👍`,
|
|
641
|
-
)
|
|
642
|
-
}}
|
|
643
|
-
>
|
|
644
|
-
<Outlet />
|
|
645
|
-
</CatchBoundary>
|
|
646
|
-
</matchIdsContext.Provider>
|
|
647
|
-
)
|
|
406
|
+
>(): RouterContext<TRouteTree> {
|
|
407
|
+
const value = React.useContext(routerContext)
|
|
408
|
+
warning(value, 'useRouter must be used inside a <RouterProvider> component!')
|
|
409
|
+
return value as any
|
|
648
410
|
}
|
|
649
411
|
|
|
650
|
-
export function
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
412
|
+
export function useRouterState<
|
|
413
|
+
TSelected = RouterState<RegisteredRouter['routeTree']>,
|
|
414
|
+
>(opts?: {
|
|
415
|
+
select: (state: RouterState<RegisteredRouter['routeTree']>) => TSelected
|
|
416
|
+
}): TSelected {
|
|
417
|
+
const { state } = useRouter()
|
|
418
|
+
// return useStore(router.__store, opts?.select as any)
|
|
419
|
+
return opts?.select ? opts.select(state) : (state as any)
|
|
654
420
|
}
|
|
655
421
|
|
|
656
422
|
export function useMatches<T = RouteMatch[]>(opts?: {
|
|
657
423
|
select?: (matches: RouteMatch[]) => T
|
|
658
424
|
}): T {
|
|
659
|
-
const
|
|
425
|
+
const contextMatches = React.useContext(matchesContext)
|
|
660
426
|
|
|
661
427
|
return useRouterState({
|
|
662
428
|
select: (state) => {
|
|
663
|
-
const matches = state.
|
|
664
|
-
state.
|
|
429
|
+
const matches = state.matches.slice(
|
|
430
|
+
state.matches.findIndex((d) => d.id === contextMatches[0]?.id),
|
|
665
431
|
)
|
|
666
432
|
return opts?.select ? opts.select(matches) : (matches as T)
|
|
667
433
|
},
|
|
@@ -689,15 +455,14 @@ export function useMatch<
|
|
|
689
455
|
select?: (match: TRouteMatchState) => TSelected
|
|
690
456
|
},
|
|
691
457
|
): TStrict extends true ? TRouteMatchState : TRouteMatchState | undefined {
|
|
692
|
-
const
|
|
693
|
-
const
|
|
694
|
-
const nearestMatchRouteId = router.getRouteMatch(nearestMatchId)?.routeId
|
|
458
|
+
const nearestMatch = React.useContext(matchesContext)[0]!
|
|
459
|
+
const nearestMatchRouteId = nearestMatch?.routeId
|
|
695
460
|
|
|
696
461
|
const matchRouteId = useRouterState({
|
|
697
462
|
select: (state) => {
|
|
698
463
|
const match = opts?.from
|
|
699
|
-
? state.
|
|
700
|
-
: state.
|
|
464
|
+
? state.matches.find((d) => d.routeId === opts?.from)
|
|
465
|
+
: state.matches.find((d) => d.id === nearestMatch.id)
|
|
701
466
|
|
|
702
467
|
return match!.routeId
|
|
703
468
|
},
|
|
@@ -719,8 +484,8 @@ export function useMatch<
|
|
|
719
484
|
const matchSelection = useRouterState({
|
|
720
485
|
select: (state) => {
|
|
721
486
|
const match = opts?.from
|
|
722
|
-
? state.
|
|
723
|
-
: state.
|
|
487
|
+
? state.matches.find((d) => d.routeId === opts?.from)
|
|
488
|
+
: state.matches.find((d) => d.id === nearestMatch.id)
|
|
724
489
|
|
|
725
490
|
invariant(
|
|
726
491
|
match,
|
|
@@ -749,61 +514,21 @@ export type RouteFromIdOrRoute<
|
|
|
749
514
|
? RouteIds<TRouteTree>
|
|
750
515
|
: never
|
|
751
516
|
|
|
752
|
-
export function
|
|
753
|
-
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
|
|
754
|
-
TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>,
|
|
755
|
-
TStrict extends boolean = true,
|
|
756
|
-
TLoader = RouteById<TRouteTree, TFrom>['types']['loader'],
|
|
757
|
-
TSelected = TLoader,
|
|
758
|
-
>(
|
|
759
|
-
opts: StrictOrFrom<TFrom> & {
|
|
760
|
-
select?: (search: TLoader) => TSelected
|
|
761
|
-
},
|
|
762
|
-
): TStrict extends true ? TSelected : TSelected | undefined {
|
|
763
|
-
return useMatch({
|
|
764
|
-
...(opts as any),
|
|
765
|
-
select: (match: RouteMatch) =>
|
|
766
|
-
opts?.select
|
|
767
|
-
? opts?.select(match.loaderData as TLoader)
|
|
768
|
-
: match.loaderData,
|
|
769
|
-
})
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
export function useRouterContext<
|
|
773
|
-
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
|
|
774
|
-
TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>,
|
|
775
|
-
TStrict extends boolean = true,
|
|
776
|
-
TContext = RouteById<TRouteTree, TFrom>['types']['context'],
|
|
777
|
-
TSelected = TContext,
|
|
778
|
-
>(
|
|
779
|
-
opts: StrictOrFrom<TFrom> & {
|
|
780
|
-
select?: (search: TContext) => TSelected
|
|
781
|
-
},
|
|
782
|
-
): TStrict extends true ? TSelected : TSelected | undefined {
|
|
783
|
-
return useMatch({
|
|
784
|
-
...(opts as any),
|
|
785
|
-
select: (match: RouteMatch) =>
|
|
786
|
-
opts?.select ? opts.select(match.context as TContext) : match.context,
|
|
787
|
-
})
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
export function useRouteContext<
|
|
517
|
+
export function useRouteMeta<
|
|
791
518
|
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
|
|
792
519
|
TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>,
|
|
793
520
|
TStrict extends boolean = true,
|
|
794
|
-
|
|
795
|
-
TSelected =
|
|
521
|
+
TRouteMeta = RouteById<TRouteTree, TFrom>['types']['allMeta'],
|
|
522
|
+
TSelected = TRouteMeta,
|
|
796
523
|
>(
|
|
797
524
|
opts: StrictOrFrom<TFrom> & {
|
|
798
|
-
select?: (search:
|
|
525
|
+
select?: (search: TRouteMeta) => TSelected
|
|
799
526
|
},
|
|
800
527
|
): TStrict extends true ? TSelected : TSelected | undefined {
|
|
801
528
|
return useMatch({
|
|
802
529
|
...(opts as any),
|
|
803
530
|
select: (match: RouteMatch) =>
|
|
804
|
-
opts?.select
|
|
805
|
-
? opts.select(match.context as TRouteContext)
|
|
806
|
-
: match.context,
|
|
531
|
+
opts?.select ? opts.select(match.meta as TRouteMeta) : match.meta,
|
|
807
532
|
})
|
|
808
533
|
}
|
|
809
534
|
|
|
@@ -839,7 +564,7 @@ export function useParams<
|
|
|
839
564
|
): TSelected {
|
|
840
565
|
return useRouterState({
|
|
841
566
|
select: (state: any) => {
|
|
842
|
-
const params = (last(state.
|
|
567
|
+
const params = (last(state.matches) as any)?.params
|
|
843
568
|
return opts?.select ? opts.select(params) : params
|
|
844
569
|
},
|
|
845
570
|
})
|
|
@@ -849,7 +574,7 @@ export function useNavigate<
|
|
|
849
574
|
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
|
|
850
575
|
TDefaultFrom extends RoutePaths<TRouteTree> = '/',
|
|
851
576
|
>(defaultOpts?: { from?: TDefaultFrom }) {
|
|
852
|
-
const
|
|
577
|
+
const { navigate } = useRouter()
|
|
853
578
|
const match = useMatch({
|
|
854
579
|
strict: false,
|
|
855
580
|
})
|
|
@@ -862,7 +587,7 @@ export function useNavigate<
|
|
|
862
587
|
>(
|
|
863
588
|
opts?: NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>,
|
|
864
589
|
) => {
|
|
865
|
-
return
|
|
590
|
+
return navigate({
|
|
866
591
|
from: opts?.to ? match.pathname : undefined,
|
|
867
592
|
...defaultOpts,
|
|
868
593
|
...(opts as any),
|
|
@@ -875,7 +600,7 @@ export function useNavigate<
|
|
|
875
600
|
export function useMatchRoute<
|
|
876
601
|
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
|
|
877
602
|
>() {
|
|
878
|
-
const
|
|
603
|
+
const { state, matchRoute } = useRouter()
|
|
879
604
|
|
|
880
605
|
return React.useCallback(
|
|
881
606
|
<
|
|
@@ -895,7 +620,7 @@ export function useMatchRoute<
|
|
|
895
620
|
): false | RouteById<TRouteTree, TResolved>['types']['allParams'] => {
|
|
896
621
|
const { pending, caseSensitive, ...rest } = opts
|
|
897
622
|
|
|
898
|
-
return
|
|
623
|
+
return matchRoute(state, rest as any, {
|
|
899
624
|
pending,
|
|
900
625
|
caseSensitive,
|
|
901
626
|
})
|
|
@@ -904,6 +629,54 @@ export function useMatchRoute<
|
|
|
904
629
|
)
|
|
905
630
|
}
|
|
906
631
|
|
|
632
|
+
export function Matches() {
|
|
633
|
+
const { routesById, state } = useRouter()
|
|
634
|
+
|
|
635
|
+
// const matches = useRouterState({
|
|
636
|
+
// select: (state) => {
|
|
637
|
+
// return state.matches
|
|
638
|
+
// },
|
|
639
|
+
// })
|
|
640
|
+
|
|
641
|
+
const { matches } = state
|
|
642
|
+
|
|
643
|
+
const locationKey = useRouterState({
|
|
644
|
+
select: (d) => d.resolvedLocation.state?.key,
|
|
645
|
+
})
|
|
646
|
+
|
|
647
|
+
const route = routesById[rootRouteId]
|
|
648
|
+
|
|
649
|
+
const errorComponent = React.useCallback(
|
|
650
|
+
(props: any) => {
|
|
651
|
+
return React.createElement(ErrorComponent, {
|
|
652
|
+
...props,
|
|
653
|
+
useMatch: route.useMatch,
|
|
654
|
+
useRouteMeta: route.useRouteMeta,
|
|
655
|
+
useSearch: route.useSearch,
|
|
656
|
+
useParams: route.useParams,
|
|
657
|
+
})
|
|
658
|
+
},
|
|
659
|
+
[route],
|
|
660
|
+
)
|
|
661
|
+
|
|
662
|
+
return (
|
|
663
|
+
<matchesContext.Provider value={matches}>
|
|
664
|
+
<CatchBoundary
|
|
665
|
+
resetKey={locationKey}
|
|
666
|
+
errorComponent={errorComponent}
|
|
667
|
+
onCatch={() => {
|
|
668
|
+
warning(
|
|
669
|
+
false,
|
|
670
|
+
`Error in router! Consider setting an 'errorComponent' in your RootRoute! 👍`,
|
|
671
|
+
)
|
|
672
|
+
}}
|
|
673
|
+
>
|
|
674
|
+
{matches.length ? <Match matches={matches} /> : null}
|
|
675
|
+
</CatchBoundary>
|
|
676
|
+
</matchesContext.Provider>
|
|
677
|
+
)
|
|
678
|
+
}
|
|
679
|
+
|
|
907
680
|
export function MatchRoute<
|
|
908
681
|
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
|
|
909
682
|
TFrom extends RoutePaths<TRouteTree> = '/',
|
|
@@ -924,33 +697,33 @@ export function MatchRoute<
|
|
|
924
697
|
}
|
|
925
698
|
|
|
926
699
|
export function Outlet() {
|
|
927
|
-
const
|
|
700
|
+
const matches = React.useContext(matchesContext).slice(1)
|
|
928
701
|
|
|
929
|
-
if (!
|
|
702
|
+
if (!matches[0]) {
|
|
930
703
|
return null
|
|
931
704
|
}
|
|
932
705
|
|
|
933
|
-
return <Match
|
|
706
|
+
return <Match matches={matches} />
|
|
934
707
|
}
|
|
935
708
|
|
|
936
709
|
const defaultPending = () => null
|
|
937
710
|
|
|
938
|
-
function Match({
|
|
939
|
-
const
|
|
940
|
-
const
|
|
941
|
-
const routeId =
|
|
942
|
-
const route =
|
|
711
|
+
function Match({ matches }: { matches: RouteMatch[] }) {
|
|
712
|
+
const { options, routesById } = useRouter()
|
|
713
|
+
const match = matches[0]!
|
|
714
|
+
const routeId = match?.routeId
|
|
715
|
+
const route = routesById[routeId]
|
|
943
716
|
const locationKey = useRouterState({
|
|
944
717
|
select: (s) => s.resolvedLocation.state?.key,
|
|
945
718
|
})
|
|
946
719
|
|
|
947
720
|
const PendingComponent = (route.options.pendingComponent ??
|
|
948
|
-
|
|
721
|
+
options.defaultPendingComponent ??
|
|
949
722
|
defaultPending) as any
|
|
950
723
|
|
|
951
724
|
const routeErrorComponent =
|
|
952
725
|
route.options.errorComponent ??
|
|
953
|
-
|
|
726
|
+
options.defaultErrorComponent ??
|
|
954
727
|
ErrorComponent
|
|
955
728
|
|
|
956
729
|
const ResolvedSuspenseBoundary =
|
|
@@ -967,7 +740,7 @@ function Match({ matchIds }: { matchIds: string[] }) {
|
|
|
967
740
|
return React.createElement(routeErrorComponent, {
|
|
968
741
|
...props,
|
|
969
742
|
useMatch: route.useMatch,
|
|
970
|
-
|
|
743
|
+
useRouteMeta: route.useRouteMeta,
|
|
971
744
|
useSearch: route.useSearch,
|
|
972
745
|
useParams: route.useParams,
|
|
973
746
|
})
|
|
@@ -976,11 +749,11 @@ function Match({ matchIds }: { matchIds: string[] }) {
|
|
|
976
749
|
)
|
|
977
750
|
|
|
978
751
|
return (
|
|
979
|
-
<
|
|
752
|
+
<matchesContext.Provider value={matches}>
|
|
980
753
|
<ResolvedSuspenseBoundary
|
|
981
754
|
fallback={React.createElement(PendingComponent, {
|
|
982
755
|
useMatch: route.useMatch,
|
|
983
|
-
|
|
756
|
+
useRouteMeta: route.useRouteMeta,
|
|
984
757
|
useSearch: route.useSearch,
|
|
985
758
|
useParams: route.useParams,
|
|
986
759
|
})}
|
|
@@ -989,56 +762,35 @@ function Match({ matchIds }: { matchIds: string[] }) {
|
|
|
989
762
|
resetKey={locationKey}
|
|
990
763
|
errorComponent={errorComponent}
|
|
991
764
|
onCatch={() => {
|
|
992
|
-
warning(false, `Error in route match: ${
|
|
765
|
+
warning(false, `Error in route match: ${match.id}`)
|
|
993
766
|
}}
|
|
994
767
|
>
|
|
995
|
-
<MatchInner
|
|
768
|
+
<MatchInner match={match} />
|
|
996
769
|
</ResolvedCatchBoundary>
|
|
997
770
|
</ResolvedSuspenseBoundary>
|
|
998
|
-
</
|
|
771
|
+
</matchesContext.Provider>
|
|
999
772
|
)
|
|
1000
773
|
}
|
|
1001
774
|
|
|
1002
|
-
function MatchInner({
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
}: {
|
|
1006
|
-
matchId: string
|
|
1007
|
-
PendingComponent: any
|
|
1008
|
-
}): any {
|
|
1009
|
-
const router = useRouter()
|
|
1010
|
-
|
|
1011
|
-
const match = useRouterState({
|
|
1012
|
-
select: (d) => {
|
|
1013
|
-
const match = d.matchesById[matchId]
|
|
1014
|
-
return pick(match!, ['status', 'loadPromise', 'routeId', 'error'])
|
|
1015
|
-
},
|
|
1016
|
-
})
|
|
1017
|
-
|
|
1018
|
-
const route = router.getRoute(match.routeId)
|
|
775
|
+
function MatchInner({ match }: { match: RouteMatch }): any {
|
|
776
|
+
const { options, routesById } = useRouter()
|
|
777
|
+
const route = routesById[match.routeId]
|
|
1019
778
|
|
|
1020
779
|
if (match.status === 'error') {
|
|
1021
780
|
throw match.error
|
|
1022
781
|
}
|
|
1023
782
|
|
|
1024
783
|
if (match.status === 'pending') {
|
|
1025
|
-
|
|
1026
|
-
useLoader: route.useLoader,
|
|
1027
|
-
useMatch: route.useMatch,
|
|
1028
|
-
useRouteContext: route.useRouteContext,
|
|
1029
|
-
useSearch: route.useSearch,
|
|
1030
|
-
useParams: route.useParams,
|
|
1031
|
-
})
|
|
784
|
+
throw match.loadPromise
|
|
1032
785
|
}
|
|
1033
786
|
|
|
1034
787
|
if (match.status === 'success') {
|
|
1035
|
-
let comp = route.options.component ??
|
|
788
|
+
let comp = route.options.component ?? options.defaultComponent
|
|
1036
789
|
|
|
1037
790
|
if (comp) {
|
|
1038
791
|
return React.createElement(comp, {
|
|
1039
|
-
useLoader: route.useLoader,
|
|
1040
792
|
useMatch: route.useMatch,
|
|
1041
|
-
|
|
793
|
+
useRouteMeta: route.useRouteMeta as any,
|
|
1042
794
|
useSearch: route.useSearch,
|
|
1043
795
|
useParams: route.useParams as any,
|
|
1044
796
|
} as any)
|
|
@@ -1057,36 +809,36 @@ function SafeFragment(props: any) {
|
|
|
1057
809
|
return <>{props.children}</>
|
|
1058
810
|
}
|
|
1059
811
|
|
|
1060
|
-
export function useInjectHtml() {
|
|
1061
|
-
|
|
812
|
+
// export function useInjectHtml() {
|
|
813
|
+
// const { } = useRouter()
|
|
1062
814
|
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
}
|
|
815
|
+
// return React.useCallback(
|
|
816
|
+
// (html: string | (() => Promise<string> | string)) => {
|
|
817
|
+
// router.injectHtml(html)
|
|
818
|
+
// },
|
|
819
|
+
// [],
|
|
820
|
+
// )
|
|
821
|
+
// }
|
|
1070
822
|
|
|
1071
|
-
export function useDehydrate() {
|
|
1072
|
-
|
|
823
|
+
// export function useDehydrate() {
|
|
824
|
+
// const { } = useRouter()
|
|
1073
825
|
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
}
|
|
826
|
+
// return React.useCallback(function dehydrate<T>(
|
|
827
|
+
// key: any,
|
|
828
|
+
// data: T | (() => Promise<T> | T),
|
|
829
|
+
// ) {
|
|
830
|
+
// return router.dehydrateData(key, data)
|
|
831
|
+
// },
|
|
832
|
+
// [])
|
|
833
|
+
// }
|
|
1082
834
|
|
|
1083
|
-
export function useHydrate() {
|
|
1084
|
-
|
|
835
|
+
// export function useHydrate() {
|
|
836
|
+
// const { } = useRouter()
|
|
1085
837
|
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
}
|
|
838
|
+
// return function hydrate<T = unknown>(key: any) {
|
|
839
|
+
// return router.hydrateData(key) as T
|
|
840
|
+
// }
|
|
841
|
+
// }
|
|
1090
842
|
|
|
1091
843
|
// This is the messiest thing ever... I'm either seriously tired (likely) or
|
|
1092
844
|
// there has to be a better way to reset error boundaries when the
|
|
@@ -1192,12 +944,12 @@ export function useBlocker(
|
|
|
1192
944
|
message: string,
|
|
1193
945
|
condition: boolean | any = true,
|
|
1194
946
|
): void {
|
|
1195
|
-
const
|
|
947
|
+
const { history } = useRouter()
|
|
1196
948
|
|
|
1197
949
|
React.useEffect(() => {
|
|
1198
950
|
if (!condition) return
|
|
1199
951
|
|
|
1200
|
-
let unblock =
|
|
952
|
+
let unblock = history.block((retry, cancel) => {
|
|
1201
953
|
if (window.confirm(message)) {
|
|
1202
954
|
unblock()
|
|
1203
955
|
retry()
|