@tanstack/react-router 0.0.1-beta.16 → 0.0.1-beta.19

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/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.16",
4
+ "version": "0.0.1-beta.19",
5
5
  "license": "MIT",
6
6
  "repository": "tanstack/router",
7
7
  "homepage": "https://tanstack.com/router/",
@@ -41,8 +41,7 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@babel/runtime": "^7.16.7",
44
- "@tanstack/router-core": "0.0.1-beta.16",
45
- "react-lazy-with-preload": "^2.2.1",
44
+ "@tanstack/router-core": "0.0.1-beta.19",
46
45
  "use-sync-external-store": "^1.2.0"
47
46
  },
48
47
  "devDependencies": {
package/src/index.tsx CHANGED
@@ -6,7 +6,6 @@ import {
6
6
  AnyRoute,
7
7
  CheckId,
8
8
  rootRouteId,
9
- Router,
10
9
  RouterState,
11
10
  ToIdOption,
12
11
  } from '@tanstack/router-core'
@@ -31,18 +30,62 @@ import {
31
30
  NoInfer,
32
31
  ToOptions,
33
32
  invariant,
33
+ Router,
34
34
  } from '@tanstack/router-core'
35
35
 
36
36
  export * from '@tanstack/router-core'
37
37
 
38
- export { lazyWithPreload as lazy } from 'react-lazy-with-preload/lib/index'
39
- export type { PreloadableComponent as LazyComponent } from 'react-lazy-with-preload'
38
+ export interface ResolveRouter {
39
+ // router: Router
40
+ }
41
+
42
+ export type ResolvedRouter = ResolveRouter extends {
43
+ router: Router<infer TRouteConfig, infer TAllRouteInfo>
44
+ }
45
+ ? Router<TRouteConfig, TAllRouteInfo>
46
+ : Router
47
+
48
+ export type ResolvedAllRouteInfo = ResolveRouter extends {
49
+ router: Router<infer TRouteConfig, infer TAllRouteInfo>
50
+ }
51
+ ? TAllRouteInfo
52
+ : AnyAllRouteInfo
53
+
54
+ export type SyncRouteComponent = (props?: {}) => JSX.Element | React.ReactNode
40
55
 
41
- type SyncRouteComponent = (props?: {}) => React.ReactNode
42
56
  export type RouteComponent = SyncRouteComponent & {
43
- preload?: () => Promise<{
44
- default: SyncRouteComponent
45
- }>
57
+ preload?: () => Promise<SyncRouteComponent>
58
+ }
59
+
60
+ export function lazy(
61
+ importer: () => Promise<{ default: SyncRouteComponent }>,
62
+ ): RouteComponent {
63
+ const lazyComp = React.lazy(importer as any)
64
+ let promise: Promise<SyncRouteComponent>
65
+ let resolvedComp: SyncRouteComponent
66
+
67
+ const forwardedComp = React.forwardRef((props, ref) => {
68
+ const resolvedCompRef = React.useRef(resolvedComp || lazyComp)
69
+ return React.createElement(
70
+ resolvedCompRef.current as any,
71
+ { ...(ref ? { ref } : {}), ...props } as any,
72
+ )
73
+ })
74
+
75
+ const finalComp = forwardedComp as unknown as RouteComponent
76
+
77
+ finalComp.preload = () => {
78
+ if (!promise) {
79
+ promise = importer().then((module) => {
80
+ resolvedComp = module.default
81
+ return resolvedComp
82
+ })
83
+ }
84
+
85
+ return promise
86
+ }
87
+
88
+ return finalComp
46
89
  }
47
90
 
48
91
  declare module '@tanstack/router-core' {
@@ -171,18 +214,24 @@ export type PromptProps = {
171
214
 
172
215
  //
173
216
 
174
- const matchesContext = React.createContext<RouteMatch[]>(null!)
175
- const routerContext = React.createContext<{ router: Router<any, any> }>(null!)
217
+ export function Link<TTo extends string = '.'>(
218
+ props: LinkPropsOptions<ResolvedAllRouteInfo, '/', TTo> &
219
+ React.AnchorHTMLAttributes<HTMLAnchorElement> &
220
+ Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'children'> & {
221
+ children?:
222
+ | React.ReactNode
223
+ | ((state: { isActive: boolean }) => React.ReactNode)
224
+ },
225
+ ): JSX.Element {
226
+ const router = useRouter()
227
+ return <router.Link {...(props as any)} />
228
+ }
176
229
 
177
- // Detect if we're in the DOM
178
- const isDOM = Boolean(
179
- typeof window !== 'undefined' &&
180
- window.document &&
181
- window.document.createElement,
230
+ export const matchesContext = React.createContext<RouteMatch[]>(null!)
231
+ export const routerContext = React.createContext<{ router: ResolvedRouter }>(
232
+ null!,
182
233
  )
183
234
 
184
- const useLayoutEffect = isDOM ? React.useLayoutEffect : React.useEffect
185
-
186
235
  export type MatchesProviderProps = {
187
236
  value: RouteMatch[]
188
237
  children: React.ReactNode
@@ -391,15 +440,15 @@ export function createReactRouter<
391
440
 
392
441
  invariant(
393
442
  runtimeMatch.routeId == match?.routeId,
394
- `useMatch('${
443
+ `useMatch("${
395
444
  match?.routeId as string
396
- }') is being called in a component that is meant to render the '${
445
+ }") is being called in a component that is meant to render the '${
397
446
  runtimeMatch.routeId
398
- }' route. Did you mean to 'useMatch(${
447
+ }' route. Did you mean to 'useMatch("${
399
448
  match?.routeId as string
400
- }, { strict: false })' or 'useRoute(${
449
+ }", { strict: false })' or 'useRoute("${
401
450
  match?.routeId as string
402
- })' instead?`,
451
+ }")' instead?`,
403
452
  )
404
453
  }
405
454
 
@@ -446,11 +495,12 @@ export function RouterProvider<
446
495
 
447
496
  useRouterSubscription(router)
448
497
  React.useEffect(() => {
498
+ console.log('hello')
449
499
  return router.mount()
450
500
  }, [router])
451
501
 
452
502
  return (
453
- <routerContext.Provider value={{ router }}>
503
+ <routerContext.Provider value={{ router: router as any }}>
454
504
  <MatchesProvider value={router.state.matches}>
455
505
  {children ?? <Outlet />}
456
506
  </MatchesProvider>
@@ -458,19 +508,37 @@ export function RouterProvider<
458
508
  )
459
509
  }
460
510
 
461
- export function useRouter(): Router {
511
+ export function useRouter(): ResolvedRouter {
462
512
  const value = React.useContext(routerContext)
463
513
  warning(!value, 'useRouter must be used inside a <Router> component!')
464
514
 
465
515
  useRouterSubscription(value.router)
466
516
 
467
- return value.router as Router
517
+ return value.router
468
518
  }
469
519
 
470
520
  export function useMatches(): RouteMatch[] {
471
521
  return React.useContext(matchesContext)
472
522
  }
473
523
 
524
+ export function useMatch<
525
+ TId extends keyof ResolvedAllRouteInfo['routeInfoById'],
526
+ TStrict extends true | false = true,
527
+ >(
528
+ routeId: TId,
529
+ opts?: { strict?: TStrict },
530
+ ): TStrict extends true
531
+ ? RouteMatch<ResolvedAllRouteInfo, ResolvedAllRouteInfo['routeInfoById'][TId]>
532
+ :
533
+ | RouteMatch<
534
+ ResolvedAllRouteInfo,
535
+ ResolvedAllRouteInfo['routeInfoById'][TId]
536
+ >
537
+ | undefined {
538
+ const router = useRouter()
539
+ return router.useMatch(routeId as any, opts) as any
540
+ }
541
+
474
542
  export function Outlet() {
475
543
  const router = useRouter()
476
544
  const matches = useMatches().slice(1)
@@ -507,12 +575,8 @@ export function Outlet() {
507
575
  )
508
576
  }
509
577
 
510
- if (match.__.loadPromise) {
511
- console.log(match.matchId, 'suspend')
512
- throw match.__.loadPromise
513
- }
514
-
515
- invariant(false, 'This should never happen!')
578
+ console.log(match.matchId, 'suspend')
579
+ throw match.__.loadPromise
516
580
  })() as JSX.Element
517
581
  }
518
582
  </CatchBoundary>