@tanstack/react-router 0.0.1-beta.240 → 0.0.1-beta.242
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/CatchBoundary.js +7 -2
- package/build/cjs/CatchBoundary.js.map +1 -1
- package/build/cjs/Matches.js +66 -54
- package/build/cjs/Matches.js.map +1 -1
- package/build/cjs/index.js +1 -1
- package/build/cjs/link.js.map +1 -1
- package/build/cjs/path.js +1 -1
- package/build/cjs/path.js.map +1 -1
- package/build/cjs/router.js +1 -1
- package/build/cjs/router.js.map +1 -1
- package/build/esm/index.js +74 -58
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +365 -359
- package/build/types/CatchBoundary.d.ts +6 -3
- package/build/types/Matches.d.ts +3 -3
- package/build/umd/index.development.js +74 -58
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +2 -2
- package/src/CatchBoundary.tsx +8 -5
- package/src/Matches.tsx +94 -67
- package/src/link.tsx +56 -56
- package/src/path.ts +1 -1
- package/src/router.ts +1 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/react-router",
|
|
3
3
|
"author": "Tanner Linsley",
|
|
4
|
-
"version": "0.0.1-beta.
|
|
4
|
+
"version": "0.0.1-beta.242",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "tanstack/router",
|
|
7
7
|
"homepage": "https://tanstack.com/router",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@tanstack/store": "^0.1.3",
|
|
45
45
|
"tiny-invariant": "^1.3.1",
|
|
46
46
|
"tiny-warning": "^1.0.3",
|
|
47
|
-
"@tanstack/history": "0.0.1-beta.
|
|
47
|
+
"@tanstack/history": "0.0.1-beta.242"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "rollup --config rollup.config.js"
|
package/src/CatchBoundary.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react'
|
|
2
2
|
|
|
3
3
|
export function CatchBoundary(props: {
|
|
4
|
-
|
|
4
|
+
getResetKey: () => string
|
|
5
5
|
children: any
|
|
6
6
|
errorComponent?: any
|
|
7
7
|
onCatch: (error: any) => void
|
|
@@ -10,7 +10,7 @@ export function CatchBoundary(props: {
|
|
|
10
10
|
|
|
11
11
|
return (
|
|
12
12
|
<CatchBoundaryImpl
|
|
13
|
-
|
|
13
|
+
getResetKey={props.getResetKey}
|
|
14
14
|
onCatch={props.onCatch}
|
|
15
15
|
children={({ error }) => {
|
|
16
16
|
if (error) {
|
|
@@ -26,23 +26,26 @@ export function CatchBoundary(props: {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export class CatchBoundaryImpl extends React.Component<{
|
|
29
|
-
|
|
29
|
+
getResetKey: () => string
|
|
30
30
|
children: (props: { error: any; reset: () => void }) => any
|
|
31
31
|
onCatch?: (error: any) => void
|
|
32
32
|
}> {
|
|
33
33
|
state = { error: null } as any
|
|
34
|
+
static getDerivedStateFromProps(props: any) {
|
|
35
|
+
return { resetKey: props.getResetKey() }
|
|
36
|
+
}
|
|
34
37
|
static getDerivedStateFromError(error: any) {
|
|
35
38
|
return { error }
|
|
36
39
|
}
|
|
37
40
|
componentDidUpdate(
|
|
38
41
|
prevProps: Readonly<{
|
|
39
|
-
|
|
42
|
+
getResetKey: () => string
|
|
40
43
|
children: (props: { error: any; reset: () => void }) => any
|
|
41
44
|
onCatch?: ((error: any, info: any) => void) | undefined
|
|
42
45
|
}>,
|
|
43
46
|
prevState: any,
|
|
44
47
|
): void {
|
|
45
|
-
if (prevState.error &&
|
|
48
|
+
if (prevState.error && prevState.resetKey !== this.state.resetKey) {
|
|
46
49
|
this.setState({ error: null })
|
|
47
50
|
}
|
|
48
51
|
}
|
package/src/Matches.tsx
CHANGED
|
@@ -13,9 +13,11 @@ import {
|
|
|
13
13
|
RouteIds,
|
|
14
14
|
RoutePaths,
|
|
15
15
|
} from './routeInfo'
|
|
16
|
-
import { RegisteredRouter } from './router'
|
|
16
|
+
import { RegisteredRouter, RouterState } from './router'
|
|
17
17
|
import { NoInfer, StrictOrFrom, pick } from './utils'
|
|
18
18
|
|
|
19
|
+
export const matchContext = React.createContext<string | undefined>(undefined)
|
|
20
|
+
|
|
19
21
|
export interface RouteMatch<
|
|
20
22
|
TRouteTree extends AnyRoute = AnyRoute,
|
|
21
23
|
TRouteId extends RouteIds<TRouteTree> = ParseRoute<TRouteTree>['id'],
|
|
@@ -48,11 +50,11 @@ export type AnyRouteMatch = RouteMatch<any>
|
|
|
48
50
|
|
|
49
51
|
export function Matches() {
|
|
50
52
|
const router = useRouter()
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
const matchId = useRouterState({
|
|
54
|
+
select: (s) => {
|
|
55
|
+
return getRenderedMatches(s)[0]?.id
|
|
56
|
+
},
|
|
57
|
+
})
|
|
56
58
|
const route = router.routesById[rootRouteId]!
|
|
57
59
|
|
|
58
60
|
const errorComponent = React.useCallback(
|
|
@@ -69,9 +71,9 @@ export function Matches() {
|
|
|
69
71
|
)
|
|
70
72
|
|
|
71
73
|
return (
|
|
72
|
-
<
|
|
74
|
+
<matchContext.Provider value={matchId}>
|
|
73
75
|
<CatchBoundary
|
|
74
|
-
|
|
76
|
+
getResetKey={() => router.state.resolvedLocation.state?.key}
|
|
75
77
|
errorComponent={errorComponent}
|
|
76
78
|
onCatch={() => {
|
|
77
79
|
warning(
|
|
@@ -80,9 +82,9 @@ export function Matches() {
|
|
|
80
82
|
)
|
|
81
83
|
}}
|
|
82
84
|
>
|
|
83
|
-
{
|
|
85
|
+
{matchId ? <Match matchId={matchId} /> : null}
|
|
84
86
|
</CatchBoundary>
|
|
85
|
-
</
|
|
87
|
+
</matchContext.Provider>
|
|
86
88
|
)
|
|
87
89
|
}
|
|
88
90
|
|
|
@@ -90,16 +92,22 @@ function SafeFragment(props: any) {
|
|
|
90
92
|
return <>{props.children}</>
|
|
91
93
|
}
|
|
92
94
|
|
|
93
|
-
export function Match({
|
|
94
|
-
const { options, routesById } = useRouter()
|
|
95
|
-
const match = matches[0]!
|
|
96
|
-
const routeId = match?.routeId
|
|
97
|
-
const route = routesById[routeId]!
|
|
95
|
+
export function Match({ matchId }: { matchId: string }) {
|
|
98
96
|
const router = useRouter()
|
|
99
|
-
const
|
|
97
|
+
const routeId = useRouterState({
|
|
98
|
+
select: (s) =>
|
|
99
|
+
getRenderedMatches(s).find((d) => d.id === matchId)?.routeId as string,
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
invariant(
|
|
103
|
+
routeId,
|
|
104
|
+
`Could not find routeId for matchId "${matchId}". Please file an issue!`,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
const route = router.routesById[routeId]!
|
|
100
108
|
|
|
101
109
|
const PendingComponent = (route.options.pendingComponent ??
|
|
102
|
-
options.defaultPendingComponent) as any
|
|
110
|
+
router.options.defaultPendingComponent) as any
|
|
103
111
|
|
|
104
112
|
const pendingElement = PendingComponent
|
|
105
113
|
? React.createElement(PendingComponent, {
|
|
@@ -112,7 +120,7 @@ export function Match({ matches }: { matches: RouteMatch[] }) {
|
|
|
112
120
|
|
|
113
121
|
const routeErrorComponent =
|
|
114
122
|
route.options.errorComponent ??
|
|
115
|
-
options.defaultErrorComponent ??
|
|
123
|
+
router.options.defaultErrorComponent ??
|
|
116
124
|
ErrorComponent
|
|
117
125
|
|
|
118
126
|
const ResolvedSuspenseBoundary =
|
|
@@ -138,30 +146,45 @@ export function Match({ matches }: { matches: RouteMatch[] }) {
|
|
|
138
146
|
const ResolvedCatchBoundary = errorComponent ? CatchBoundary : SafeFragment
|
|
139
147
|
|
|
140
148
|
return (
|
|
141
|
-
<
|
|
149
|
+
<matchContext.Provider value={matchId}>
|
|
142
150
|
<ResolvedSuspenseBoundary fallback={pendingElement}>
|
|
143
151
|
<ResolvedCatchBoundary
|
|
144
|
-
|
|
152
|
+
getResetKey={() => router.state.resolvedLocation.state?.key}
|
|
145
153
|
errorComponent={errorComponent}
|
|
146
154
|
onCatch={() => {
|
|
147
|
-
warning(false, `Error in route match: ${
|
|
155
|
+
warning(false, `Error in route match: ${matchId}`)
|
|
148
156
|
}}
|
|
149
157
|
>
|
|
150
|
-
<MatchInner
|
|
158
|
+
<MatchInner matchId={matchId!} pendingElement={pendingElement} />
|
|
151
159
|
</ResolvedCatchBoundary>
|
|
152
160
|
</ResolvedSuspenseBoundary>
|
|
153
|
-
</
|
|
161
|
+
</matchContext.Provider>
|
|
154
162
|
)
|
|
155
163
|
}
|
|
156
164
|
function MatchInner({
|
|
157
|
-
|
|
165
|
+
matchId,
|
|
158
166
|
pendingElement,
|
|
159
167
|
}: {
|
|
160
|
-
|
|
168
|
+
matchId: string
|
|
161
169
|
pendingElement: any
|
|
162
170
|
}): any {
|
|
163
|
-
const
|
|
164
|
-
const
|
|
171
|
+
const router = useRouter()
|
|
172
|
+
const routeId = useRouterState({
|
|
173
|
+
select: (s) =>
|
|
174
|
+
getRenderedMatches(s).find((d) => d.id === matchId)?.routeId as string,
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
const route = router.routesById[routeId]!
|
|
178
|
+
|
|
179
|
+
const match = useRouterState({
|
|
180
|
+
select: (s) =>
|
|
181
|
+
pick(getRenderedMatches(s).find((d) => d.id === matchId)!, [
|
|
182
|
+
'status',
|
|
183
|
+
'error',
|
|
184
|
+
'showPending',
|
|
185
|
+
'loadPromise',
|
|
186
|
+
]),
|
|
187
|
+
})
|
|
165
188
|
|
|
166
189
|
if (match.status === 'error') {
|
|
167
190
|
throw match.error
|
|
@@ -175,7 +198,7 @@ function MatchInner({
|
|
|
175
198
|
}
|
|
176
199
|
|
|
177
200
|
if (match.status === 'success') {
|
|
178
|
-
let comp = route.options.component ?? options.defaultComponent
|
|
201
|
+
let comp = route.options.component ?? router.options.defaultComponent
|
|
179
202
|
|
|
180
203
|
if (comp) {
|
|
181
204
|
return React.createElement(comp, {
|
|
@@ -197,13 +220,21 @@ function MatchInner({
|
|
|
197
220
|
}
|
|
198
221
|
|
|
199
222
|
export function Outlet() {
|
|
200
|
-
const
|
|
223
|
+
const matchId = React.useContext(matchContext)
|
|
224
|
+
|
|
225
|
+
const childMatchId = useRouterState({
|
|
226
|
+
select: (s) => {
|
|
227
|
+
const matches = getRenderedMatches(s)
|
|
228
|
+
const index = matches.findIndex((d) => d.id === matchId)
|
|
229
|
+
return matches[index + 1]?.id
|
|
230
|
+
},
|
|
231
|
+
})
|
|
201
232
|
|
|
202
|
-
if (!
|
|
233
|
+
if (!childMatchId) {
|
|
203
234
|
return null
|
|
204
235
|
}
|
|
205
236
|
|
|
206
|
-
return <Match
|
|
237
|
+
return <Match matchId={childMatchId} />
|
|
207
238
|
}
|
|
208
239
|
|
|
209
240
|
export interface MatchRouteOptions {
|
|
@@ -291,6 +322,12 @@ export function MatchRoute<
|
|
|
291
322
|
return !!params ? props.children : null
|
|
292
323
|
}
|
|
293
324
|
|
|
325
|
+
function getRenderedMatches(state: RouterState) {
|
|
326
|
+
return state.pendingMatches?.some((d) => d.showPending)
|
|
327
|
+
? state.pendingMatches
|
|
328
|
+
: state.matches
|
|
329
|
+
}
|
|
330
|
+
|
|
294
331
|
export function useMatch<
|
|
295
332
|
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
|
|
296
333
|
TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>,
|
|
@@ -302,22 +339,20 @@ export function useMatch<
|
|
|
302
339
|
select?: (match: TRouteMatchState) => TSelected
|
|
303
340
|
},
|
|
304
341
|
): TStrict extends true ? TSelected : TSelected | undefined {
|
|
305
|
-
const
|
|
306
|
-
const
|
|
307
|
-
|
|
308
|
-
const matchRouteId = useRouterState({
|
|
309
|
-
select: (state) => {
|
|
310
|
-
const matches = state.pendingMatches?.some((d) => d.showPending)
|
|
311
|
-
? state.pendingMatches
|
|
312
|
-
: state.matches
|
|
342
|
+
const router = useRouter()
|
|
343
|
+
const nearestMatchId = React.useContext(matchContext)
|
|
313
344
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
345
|
+
const nearestMatchRouteId = getRenderedMatches(router.state).find(
|
|
346
|
+
(d) => d.id === nearestMatchId,
|
|
347
|
+
)?.routeId
|
|
317
348
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
349
|
+
const matchRouteId = (() => {
|
|
350
|
+
const matches = getRenderedMatches(router.state)
|
|
351
|
+
const match = opts?.from
|
|
352
|
+
? matches.find((d) => d.routeId === opts?.from)
|
|
353
|
+
: matches.find((d) => d.id === nearestMatchId)
|
|
354
|
+
return match!.routeId
|
|
355
|
+
})()
|
|
321
356
|
|
|
322
357
|
if (opts?.strict ?? true) {
|
|
323
358
|
invariant(
|
|
@@ -334,13 +369,9 @@ export function useMatch<
|
|
|
334
369
|
|
|
335
370
|
const matchSelection = useRouterState({
|
|
336
371
|
select: (state) => {
|
|
337
|
-
const
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
const match = opts?.from
|
|
342
|
-
? matches.find((d) => d.routeId === opts?.from)
|
|
343
|
-
: matches.find((d) => d.id === nearestMatch.id)
|
|
372
|
+
const match = getRenderedMatches(state).find(
|
|
373
|
+
(d) => d.id === nearestMatchId,
|
|
374
|
+
)
|
|
344
375
|
|
|
345
376
|
invariant(
|
|
346
377
|
match,
|
|
@@ -358,22 +389,15 @@ export function useMatch<
|
|
|
358
389
|
return matchSelection as any
|
|
359
390
|
}
|
|
360
391
|
|
|
361
|
-
export const matchesContext = React.createContext<RouteMatch[]>(null!)
|
|
362
|
-
|
|
363
392
|
export function useMatches<T = RouteMatch[]>(opts?: {
|
|
364
393
|
select?: (matches: RouteMatch[]) => T
|
|
365
394
|
}): T {
|
|
366
|
-
const
|
|
395
|
+
const contextMatchId = React.useContext(matchContext)
|
|
367
396
|
|
|
368
397
|
return useRouterState({
|
|
369
398
|
select: (state) => {
|
|
370
|
-
let matches = state
|
|
371
|
-
|
|
372
|
-
: state.matches
|
|
373
|
-
|
|
374
|
-
matches = matches.slice(
|
|
375
|
-
matches.findIndex((d) => d.id === contextMatches[0]?.id),
|
|
376
|
-
)
|
|
399
|
+
let matches = getRenderedMatches(state)
|
|
400
|
+
matches = matches.slice(matches.findIndex((d) => d.id === contextMatchId))
|
|
377
401
|
return opts?.select ? opts.select(matches) : (matches as T)
|
|
378
402
|
},
|
|
379
403
|
})
|
|
@@ -393,9 +417,12 @@ export function useLoaderData<
|
|
|
393
417
|
select?: (match: TRouteMatch) => TSelected
|
|
394
418
|
},
|
|
395
419
|
): TStrict extends true ? TSelected : TSelected | undefined {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
420
|
+
return useMatch({
|
|
421
|
+
...opts,
|
|
422
|
+
select: (s) => {
|
|
423
|
+
return typeof opts.select === 'function'
|
|
424
|
+
? opts.select(s?.loaderData)
|
|
425
|
+
: s?.loaderData
|
|
426
|
+
},
|
|
427
|
+
})!
|
|
401
428
|
}
|
package/src/link.tsx
CHANGED
|
@@ -43,31 +43,31 @@ export type LinkInfo =
|
|
|
43
43
|
export type CleanPath<T extends string> = T extends `${infer L}//${infer R}`
|
|
44
44
|
? CleanPath<`${CleanPath<L>}/${CleanPath<R>}`>
|
|
45
45
|
: T extends `${infer L}//`
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
? `${CleanPath<L>}/`
|
|
47
|
+
: T extends `//${infer L}`
|
|
48
|
+
? `/${CleanPath<L>}`
|
|
49
|
+
: T
|
|
50
50
|
|
|
51
51
|
export type Split<S, TIncludeTrailingSlash = true> = S extends unknown
|
|
52
52
|
? string extends S
|
|
53
53
|
? string[]
|
|
54
54
|
: S extends string
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
55
|
+
? CleanPath<S> extends ''
|
|
56
|
+
? []
|
|
57
|
+
: TIncludeTrailingSlash extends true
|
|
58
|
+
? CleanPath<S> extends `${infer T}/`
|
|
59
|
+
? [...Split<T>, '/']
|
|
60
|
+
: CleanPath<S> extends `/${infer U}`
|
|
61
|
+
? Split<U>
|
|
62
|
+
: CleanPath<S> extends `${infer T}/${infer U}`
|
|
63
|
+
? [...Split<T>, ...Split<U>]
|
|
64
|
+
: [S]
|
|
65
|
+
: CleanPath<S> extends `${infer T}/${infer U}`
|
|
66
|
+
? [...Split<T>, ...Split<U>]
|
|
67
|
+
: S extends string
|
|
68
|
+
? [S]
|
|
69
|
+
: never
|
|
69
70
|
: never
|
|
70
|
-
: never
|
|
71
71
|
: never
|
|
72
72
|
|
|
73
73
|
export type ParsePathParams<T extends string> = keyof {
|
|
@@ -77,10 +77,10 @@ export type ParsePathParams<T extends string> = keyof {
|
|
|
77
77
|
export type Join<T, Delimiter extends string = '/'> = T extends []
|
|
78
78
|
? ''
|
|
79
79
|
: T extends [infer L extends string]
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
? L
|
|
81
|
+
: T extends [infer L extends string, ...infer Tail extends [...string[]]]
|
|
82
|
+
? CleanPath<`${L}${Delimiter}${Join<Tail>}`>
|
|
83
|
+
: never
|
|
84
84
|
|
|
85
85
|
export type Last<T extends any[]> = T extends [...infer _, infer L] ? L : never
|
|
86
86
|
|
|
@@ -112,23 +112,23 @@ export type RelativeToPathAutoComplete<
|
|
|
112
112
|
>}`
|
|
113
113
|
: never
|
|
114
114
|
: TTo extends `./${infer RestTTo}`
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
? never
|
|
125
|
-
: SplitPaths extends [...Split<TFrom, false>, ...infer RestPath]
|
|
126
|
-
? Join<RestPath> extends { length: 0 }
|
|
115
|
+
? SplitPaths extends [
|
|
116
|
+
...Split<TFrom, false>,
|
|
117
|
+
...Split<RestTTo, false>,
|
|
118
|
+
...infer RestPath,
|
|
119
|
+
]
|
|
120
|
+
? `${TTo}${Join<RestPath>}`
|
|
121
|
+
: never
|
|
122
|
+
:
|
|
123
|
+
| (TFrom extends `/`
|
|
127
124
|
? never
|
|
128
|
-
:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
125
|
+
: SplitPaths extends [...Split<TFrom, false>, ...infer RestPath]
|
|
126
|
+
? Join<RestPath> extends { length: 0 }
|
|
127
|
+
? never
|
|
128
|
+
: './'
|
|
129
|
+
: never)
|
|
130
|
+
| (TFrom extends `/` ? never : '../')
|
|
131
|
+
| AllPaths
|
|
132
132
|
|
|
133
133
|
export type NavigateOptions<
|
|
134
134
|
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
|
|
@@ -333,22 +333,22 @@ export type ResolveRelativePath<TFrom, TTo = '.'> = TFrom extends string
|
|
|
333
333
|
? TTo extends '.'
|
|
334
334
|
? TFrom
|
|
335
335
|
: TTo extends `./`
|
|
336
|
-
? Join<[TFrom, '/']>
|
|
337
|
-
: TTo extends `./${infer TRest}`
|
|
338
|
-
? ResolveRelativePath<TFrom, TRest>
|
|
339
|
-
: TTo extends `/${infer TRest}`
|
|
340
|
-
? TTo
|
|
341
|
-
: Split<TTo> extends ['..', ...infer ToRest]
|
|
342
|
-
? Split<TFrom> extends [...infer FromRest, infer FromTail]
|
|
343
|
-
? ToRest extends ['/']
|
|
344
|
-
? Join<[...FromRest, '/']>
|
|
345
|
-
: ResolveRelativePath<Join<FromRest>, Join<ToRest>>
|
|
346
|
-
: never
|
|
347
|
-
: Split<TTo> extends ['.', ...infer ToRest]
|
|
348
|
-
? ToRest extends ['/']
|
|
349
336
|
? Join<[TFrom, '/']>
|
|
350
|
-
:
|
|
351
|
-
|
|
337
|
+
: TTo extends `./${infer TRest}`
|
|
338
|
+
? ResolveRelativePath<TFrom, TRest>
|
|
339
|
+
: TTo extends `/${infer TRest}`
|
|
340
|
+
? TTo
|
|
341
|
+
: Split<TTo> extends ['..', ...infer ToRest]
|
|
342
|
+
? Split<TFrom> extends [...infer FromRest, infer FromTail]
|
|
343
|
+
? ToRest extends ['/']
|
|
344
|
+
? Join<[...FromRest, '/']>
|
|
345
|
+
: ResolveRelativePath<Join<FromRest>, Join<ToRest>>
|
|
346
|
+
: never
|
|
347
|
+
: Split<TTo> extends ['.', ...infer ToRest]
|
|
348
|
+
? ToRest extends ['/']
|
|
349
|
+
? Join<[TFrom, '/']>
|
|
350
|
+
: ResolveRelativePath<TFrom, Join<ToRest>>
|
|
351
|
+
: CleanPath<Join<['/', ...Split<TFrom>, ...Split<TTo>]>>
|
|
352
352
|
: never
|
|
353
353
|
: never
|
|
354
354
|
|
|
@@ -443,8 +443,8 @@ export function useLinkProps<
|
|
|
443
443
|
href: disabled
|
|
444
444
|
? undefined
|
|
445
445
|
: next.maskedLocation
|
|
446
|
-
|
|
447
|
-
|
|
446
|
+
? next.maskedLocation.href
|
|
447
|
+
: next.href,
|
|
448
448
|
onClick: composeHandlers([onClick, handleClick]),
|
|
449
449
|
onFocus: composeHandlers([onFocus, handleFocus]),
|
|
450
450
|
onMouseEnter: composeHandlers([onMouseEnter, handleEnter]),
|
package/src/path.ts
CHANGED
package/src/router.ts
CHANGED
|
@@ -601,7 +601,7 @@ export class Router<
|
|
|
601
601
|
}
|
|
602
602
|
})()
|
|
603
603
|
|
|
604
|
-
const interpolatedPath = interpolatePath(route.
|
|
604
|
+
const interpolatedPath = interpolatePath(route.fullPath, routeParams)
|
|
605
605
|
const matchId =
|
|
606
606
|
interpolatePath(route.id, routeParams, true) +
|
|
607
607
|
(route.options.key?.({
|