Skip to content

Commit

Permalink
feat: pass matches into context() and beforeLoad() (#2258)
Browse files Browse the repository at this point in the history
this will allow typesafe access to the matches so something like this can be done:

```tsx
const leafMatch = c.matches[c.matches.length - 1];
if (leafMatch.fullPath === '/dashboard/invoices/$invoiceId') {
   if (leafMatch.params.invoiceId === '1') {
        throw notFound();
   }
}
```
  • Loading branch information
schiller-manuel authored Sep 3, 2024
1 parent 2e6a543 commit 7ffdf93
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 4 deletions.
6 changes: 3 additions & 3 deletions packages/react-router/src/Matches.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,8 @@ export function MatchRoute<
return params ? props.children : null
}
export type MakeRouteMatches<
TRouter extends AnyRouter = AnyRouter,
export type MakeRouteMatchUnion<
TRouter extends AnyRouter = RegisteredRouter,
TRoute extends AnyRoute = ParseRoute<TRouter['routeTree']>,
> = TRoute extends any
? RouteMatch<
Expand All @@ -369,7 +369,7 @@ export type MakeRouteMatches<
export function useMatches<
TRouter extends AnyRouter = RegisteredRouter,
TRouteMatch = MakeRouteMatches<TRouter>,
TRouteMatch = MakeRouteMatchUnion<TRouter>,
T = Array<TRouteMatch>,
>(opts?: { select?: (matches: Array<TRouteMatch>) => T }): T {
return useRouterState({
Expand Down
3 changes: 2 additions & 1 deletion packages/react-router/src/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { rootRouteId } from './root'
import type * as React from 'react'
import type { RootRouteId } from './root'
import type { UseNavigateResult } from './useNavigate'
import type { MakeRouteMatch, RouteMatch } from './Matches'
import type { MakeRouteMatch, MakeRouteMatchUnion, RouteMatch } from './Matches'
import type { NavigateOptions, ParsePathParams, ToMaskOptions } from './link'
import type { ParsedLocation } from './location'
import type { RouteById, RouteIds, RoutePaths } from './routeInfo'
Expand Down Expand Up @@ -285,6 +285,7 @@ export interface ContextOptions<
navigate: NavigateFn
buildLocation: BuildLocationFn
cause: 'preload' | 'enter' | 'stay'
matches: Array<MakeRouteMatchUnion>
}

export interface RouteContextOptions<
Expand Down
2 changes: 2 additions & 0 deletions packages/react-router/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,7 @@ export class Router<
cause: match.cause,
abortController: match.abortController,
preload: !!match.preload,
matches,
}

// Get the route context
Expand Down Expand Up @@ -2080,6 +2081,7 @@ export class Router<
this.navigate({ ...opts, _fromLocation: location }),
buildLocation: this.buildLocation,
cause: preload ? 'preload' : cause,
matches,
}

let beforeLoadContext =
Expand Down
21 changes: 21 additions & 0 deletions packages/react-router/tests/route.test-d.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
Route,
SearchSchemaInput,
} from '../src'
import type { MakeRouteMatchUnion } from '../src/Matches'

test('when creating the root', () => {
const rootRoute = createRootRoute()
Expand All @@ -38,6 +39,7 @@ test('when creating the root with routeContext', () => {
cause: 'preload' | 'enter' | 'stay'
context: {}
search: {}
matches: Array<MakeRouteMatchUnion>
}>()
},
})
Expand All @@ -60,6 +62,7 @@ test('when creating the root with beforeLoad', () => {
cause: 'preload' | 'enter' | 'stay'
context: {}
search: {}
matches: Array<MakeRouteMatchUnion>
}>()
},
})
Expand Down Expand Up @@ -107,6 +110,7 @@ test('when creating the root route with context and routeContext', () => {
cause: 'preload' | 'enter' | 'stay'
context: { userId: string }
search: {}
matches: Array<MakeRouteMatchUnion>
}>()
},
})
Expand Down Expand Up @@ -141,6 +145,7 @@ test('when creating the root route with context and beforeLoad', () => {
cause: 'preload' | 'enter' | 'stay'
context: { userId: string }
search: {}
matches: Array<MakeRouteMatchUnion>
}>()
},
})
Expand Down Expand Up @@ -210,6 +215,7 @@ test('when creating the root route with context, routeContext, beforeLoad and a
cause: 'preload' | 'enter' | 'stay'
context: { userId: string }
search: {}
matches: Array<MakeRouteMatchUnion>
}>()

return {
Expand All @@ -227,6 +233,7 @@ test('when creating the root route with context, routeContext, beforeLoad and a
cause: 'preload' | 'enter' | 'stay'
context: { userId: string; env: 'env1' }
search: {}
matches: Array<MakeRouteMatchUnion>
}>()
return { permission: 'view' as const }
},
Expand Down Expand Up @@ -319,6 +326,7 @@ test('when creating a child route with routeContext from the root route with con
cause: 'preload' | 'enter' | 'stay'
context: { userId: string }
search: {}
matches: Array<MakeRouteMatchUnion>
}>()

return {
Expand All @@ -345,6 +353,7 @@ test('when creating a child route with beforeLoad from the root route with conte
cause: 'preload' | 'enter' | 'stay'
context: { userId: string }
search: {}
matches: Array<MakeRouteMatchUnion>
}>()
},
})
Expand Down Expand Up @@ -614,6 +623,7 @@ test('when creating a child route with params, search with routeContext from the
cause: 'preload' | 'enter' | 'stay'
context: { userId: string }
search: { page: number }
matches: Array<MakeRouteMatchUnion>
}>()
},
})
Expand All @@ -637,6 +647,7 @@ test('when creating a child route with params, search with beforeLoad from the r
cause: 'preload' | 'enter' | 'stay'
context: { userId: string }
search: { page: number }
matches: Array<MakeRouteMatchUnion>
}>()
},
})
Expand All @@ -660,6 +671,7 @@ test('when creating a child route with params, search with routeContext, beforeL
cause: 'preload' | 'enter' | 'stay'
context: { userId: string }
search: { page: number }
matches: Array<MakeRouteMatchUnion>
}>()
return {
env: 'env1',
Expand All @@ -676,6 +688,7 @@ test('when creating a child route with params, search with routeContext, beforeL
cause: 'preload' | 'enter' | 'stay'
context: { userId: string; env: string }
search: { page: number }
matches: Array<MakeRouteMatchUnion>
}>()
return { permission: 'view' } as const
},
Expand Down Expand Up @@ -774,6 +787,7 @@ test('when creating a child route with routeContext from a parent with routeCont
cause: 'preload' | 'enter' | 'stay'
context: { userId: string }
search: {}
matches: Array<MakeRouteMatchUnion>
}>()

return { invoiceId: 'invoiceId1' }
Expand All @@ -794,6 +808,7 @@ test('when creating a child route with routeContext from a parent with routeCont
cause: 'preload' | 'enter' | 'stay'
context: { userId: string; invoiceId: string }
search: {}
matches: Array<MakeRouteMatchUnion>
}>()

return { detailId: 'detailId1' }
Expand Down Expand Up @@ -837,6 +852,7 @@ test('when creating a child route with beforeLoad from a parent with beforeLoad'
cause: 'preload' | 'enter' | 'stay'
context: { userId: string }
search: {}
matches: Array<MakeRouteMatchUnion>
}>()
return { invoiceId: 'invoiceId1' }
},
Expand All @@ -856,6 +872,7 @@ test('when creating a child route with beforeLoad from a parent with beforeLoad'
cause: 'preload' | 'enter' | 'stay'
context: { userId: string; invoiceId: string }
search: {}
matches: Array<MakeRouteMatchUnion>
}>()
return { detailId: 'detailId1' }
},
Expand Down Expand Up @@ -899,6 +916,7 @@ test('when creating a child route with routeContext, beforeLoad, search, params,
cause: 'preload' | 'enter' | 'stay'
context: { userId: string }
search: { page: number }
matches: Array<MakeRouteMatchUnion>
}>()
return { env: 'env1' }
},
Expand All @@ -913,6 +931,7 @@ test('when creating a child route with routeContext, beforeLoad, search, params,
cause: 'preload' | 'enter' | 'stay'
context: { userId: string; env: string }
search: { page: number }
matches: Array<MakeRouteMatchUnion>
}>()
return { invoicePermissions: ['view'] as const }
},
Expand Down Expand Up @@ -942,6 +961,7 @@ test('when creating a child route with routeContext, beforeLoad, search, params,
invoicePermissions: readonly ['view']
}
search: { page: number; detailPage: number }
matches: Array<MakeRouteMatchUnion>
}>()
return { detailEnv: 'detailEnv' }
},
Expand All @@ -961,6 +981,7 @@ test('when creating a child route with routeContext, beforeLoad, search, params,
invoicePermissions: readonly ['view']
}
search: { page: number; detailPage: number }
matches: Array<MakeRouteMatchUnion>
}>()
return { detailsPermissions: ['view'] as const }
},
Expand Down

0 comments on commit 7ffdf93

Please sign in to comment.