@tanstack/react-router 0.0.1-beta.22 → 0.0.1-beta.221

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.
Files changed (108) hide show
  1. package/LICENSE +21 -0
  2. package/build/cjs/CatchBoundary.js +126 -0
  3. package/build/cjs/CatchBoundary.js.map +1 -0
  4. package/build/cjs/Matches.js +235 -0
  5. package/build/cjs/Matches.js.map +1 -0
  6. package/build/cjs/RouterProvider.js +1085 -0
  7. package/build/cjs/RouterProvider.js.map +1 -0
  8. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +1 -19
  9. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +1 -1
  10. package/build/cjs/awaited.js +45 -0
  11. package/build/cjs/awaited.js.map +1 -0
  12. package/build/cjs/defer.js +39 -0
  13. package/build/cjs/defer.js.map +1 -0
  14. package/build/cjs/fileRoute.js +29 -0
  15. package/build/cjs/fileRoute.js.map +1 -0
  16. package/build/cjs/index.js +135 -0
  17. package/build/cjs/index.js.map +1 -0
  18. package/build/cjs/lazyRouteComponent.js +57 -0
  19. package/build/cjs/lazyRouteComponent.js.map +1 -0
  20. package/build/cjs/link.js +151 -0
  21. package/build/cjs/link.js.map +1 -0
  22. package/build/cjs/path.js +211 -0
  23. package/build/cjs/path.js.map +1 -0
  24. package/build/cjs/qss.js +65 -0
  25. package/build/cjs/qss.js.map +1 -0
  26. package/build/cjs/redirects.js +27 -0
  27. package/build/cjs/redirects.js.map +1 -0
  28. package/build/cjs/route.js +139 -0
  29. package/build/cjs/route.js.map +1 -0
  30. package/build/cjs/router.js +160 -0
  31. package/build/cjs/router.js.map +1 -0
  32. package/build/cjs/scroll-restoration.js +186 -0
  33. package/build/cjs/scroll-restoration.js.map +1 -0
  34. package/build/cjs/searchParams.js +83 -0
  35. package/build/cjs/searchParams.js.map +1 -0
  36. package/build/cjs/useBlocker.js +64 -0
  37. package/build/cjs/useBlocker.js.map +1 -0
  38. package/build/cjs/useNavigate.js +78 -0
  39. package/build/cjs/useNavigate.js.map +1 -0
  40. package/build/cjs/useParams.js +28 -0
  41. package/build/cjs/useParams.js.map +1 -0
  42. package/build/cjs/useSearch.js +27 -0
  43. package/build/cjs/useSearch.js.map +1 -0
  44. package/build/cjs/utils.js +236 -0
  45. package/build/cjs/utils.js.map +1 -0
  46. package/build/esm/index.js +2136 -2564
  47. package/build/esm/index.js.map +1 -1
  48. package/build/stats-html.html +59 -49
  49. package/build/stats-react.json +922 -43
  50. package/build/types/CatchBoundary.d.ts +33 -0
  51. package/build/types/Matches.d.ts +34 -0
  52. package/build/types/RouterProvider.d.ts +87 -0
  53. package/build/types/awaited.d.ts +8 -0
  54. package/build/types/defer.d.ts +19 -0
  55. package/build/types/fileRoute.d.ts +32 -0
  56. package/build/types/history.d.ts +7 -0
  57. package/build/types/index.d.ts +27 -104
  58. package/build/types/injectHtml.d.ts +0 -0
  59. package/build/types/lazyRouteComponent.d.ts +2 -0
  60. package/build/types/link.d.ts +105 -0
  61. package/build/types/location.d.ts +14 -0
  62. package/build/types/path.d.ts +16 -0
  63. package/build/types/qss.d.ts +2 -0
  64. package/build/types/redirects.d.ts +10 -0
  65. package/build/types/route.d.ts +270 -0
  66. package/build/types/routeInfo.d.ts +22 -0
  67. package/build/types/router.d.ts +123 -0
  68. package/build/types/scroll-restoration.d.ts +6 -0
  69. package/build/types/searchParams.d.ts +7 -0
  70. package/build/types/useBlocker.d.ts +8 -0
  71. package/build/types/useNavigate.d.ts +20 -0
  72. package/build/types/useParams.d.ts +7 -0
  73. package/build/types/useSearch.d.ts +7 -0
  74. package/build/types/utils.d.ts +66 -0
  75. package/build/umd/index.development.js +2399 -2484
  76. package/build/umd/index.development.js.map +1 -1
  77. package/build/umd/index.production.js +4 -4
  78. package/build/umd/index.production.js.map +1 -1
  79. package/package.json +9 -10
  80. package/src/CatchBoundary.tsx +98 -0
  81. package/src/Matches.tsx +345 -0
  82. package/src/RouterProvider.tsx +1575 -0
  83. package/src/awaited.tsx +40 -0
  84. package/src/defer.ts +55 -0
  85. package/src/fileRoute.ts +153 -0
  86. package/src/history.ts +8 -0
  87. package/src/index.tsx +28 -693
  88. package/src/injectHtml.ts +28 -0
  89. package/src/lazyRouteComponent.tsx +33 -0
  90. package/src/link.tsx +508 -0
  91. package/src/location.ts +15 -0
  92. package/src/path.ts +256 -0
  93. package/src/qss.ts +53 -0
  94. package/src/redirects.ts +31 -0
  95. package/src/route.ts +837 -0
  96. package/src/routeInfo.ts +68 -0
  97. package/src/router.ts +330 -0
  98. package/src/scroll-restoration.tsx +192 -0
  99. package/src/searchParams.ts +79 -0
  100. package/src/useBlocker.tsx +34 -0
  101. package/src/useNavigate.tsx +109 -0
  102. package/src/useParams.tsx +25 -0
  103. package/src/useSearch.tsx +25 -0
  104. package/src/utils.ts +350 -0
  105. package/build/cjs/react-router/src/index.js +0 -466
  106. package/build/cjs/react-router/src/index.js.map +0 -1
  107. package/build/cjs/router-core/build/esm/index.js +0 -2523
  108. package/build/cjs/router-core/build/esm/index.js.map +0 -1
package/src/index.tsx CHANGED
@@ -1,694 +1,29 @@
1
- import * as React from 'react'
2
-
3
- import { useSyncExternalStore } from 'use-sync-external-store/shim'
4
-
5
- import {
6
- AnyRoute,
7
- CheckId,
8
- rootRouteId,
9
- Route,
10
- RouterState,
11
- ToIdOption,
12
- } from '@tanstack/router-core'
13
- import {
14
- warning,
15
- RouterOptions,
16
- RouteMatch,
17
- MatchRouteOptions,
18
- RouteConfig,
19
- AnyRouteConfig,
20
- AnyAllRouteInfo,
21
- DefaultAllRouteInfo,
22
- functionalUpdate,
23
- createRouter,
24
- AnyRouteInfo,
25
- AllRouteInfo,
26
- RouteInfo,
27
- ValidFromPath,
28
- LinkOptions,
29
- RouteInfoByPath,
30
- ResolveRelativePath,
31
- NoInfer,
32
- ToOptions,
33
- invariant,
34
- Router,
35
- } from '@tanstack/router-core'
36
-
37
- export * from '@tanstack/router-core'
38
-
39
- export interface RegisterRouter {
40
- // router: Router
41
- }
42
-
43
- export type RegisteredRouter = RegisterRouter extends {
44
- router: Router<infer TRouteConfig, infer TAllRouteInfo>
45
- }
46
- ? Router<TRouteConfig, TAllRouteInfo>
47
- : Router
48
-
49
- export type RegisteredAllRouteInfo = RegisterRouter extends {
50
- router: Router<infer TRouteConfig, infer TAllRouteInfo>
51
- }
52
- ? TAllRouteInfo
53
- : AnyAllRouteInfo
54
-
55
- export type SyncRouteComponent = (props?: {}) => JSX.Element | React.ReactNode
56
-
57
- export type RouteComponent = SyncRouteComponent & {
58
- preload?: () => Promise<SyncRouteComponent>
59
- }
60
-
61
- export function lazy(
62
- importer: () => Promise<{ default: SyncRouteComponent }>,
63
- ): RouteComponent {
64
- const lazyComp = React.lazy(importer as any)
65
- let promise: Promise<SyncRouteComponent>
66
- let resolvedComp: SyncRouteComponent
67
-
68
- const forwardedComp = React.forwardRef((props, ref) => {
69
- const resolvedCompRef = React.useRef(resolvedComp || lazyComp)
70
- return React.createElement(
71
- resolvedCompRef.current as any,
72
- { ...(ref ? { ref } : {}), ...props } as any,
73
- )
74
- })
75
-
76
- const finalComp = forwardedComp as unknown as RouteComponent
77
-
78
- finalComp.preload = () => {
79
- if (!promise) {
80
- promise = importer().then((module) => {
81
- resolvedComp = module.default
82
- return resolvedComp
83
- })
84
- }
85
-
86
- return promise
87
- }
88
-
89
- return finalComp
90
- }
91
-
92
- type LinkPropsOptions<
93
- TAllRouteInfo extends AnyAllRouteInfo,
94
- TFrom extends ValidFromPath<TAllRouteInfo>,
95
- TTo extends string,
96
- > = LinkOptions<TAllRouteInfo, TFrom, TTo> & {
97
- // A function that returns additional props for the `active` state of this link. These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)
98
- activeProps?:
99
- | React.AnchorHTMLAttributes<HTMLAnchorElement>
100
- | (() => React.AnchorHTMLAttributes<HTMLAnchorElement>)
101
- // A function that returns additional props for the `inactive` state of this link. These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)
102
- inactiveProps?:
103
- | React.AnchorHTMLAttributes<HTMLAnchorElement>
104
- | (() => React.AnchorHTMLAttributes<HTMLAnchorElement>)
105
- }
106
-
107
- type MakeMatchRouteOptions<
108
- TAllRouteInfo extends AnyAllRouteInfo,
109
- TFrom extends ValidFromPath<TAllRouteInfo>,
110
- TTo extends string,
111
- > = ToOptions<TAllRouteInfo, TFrom, TTo> &
112
- MatchRouteOptions & {
113
- // If a function is passed as a child, it will be given the `isActive` boolean to aid in further styling on the element it returns
114
- children?:
115
- | React.ReactNode
116
- | ((
117
- params: RouteInfoByPath<
118
- TAllRouteInfo,
119
- ResolveRelativePath<TFrom, NoInfer<TTo>>
120
- >['allParams'],
121
- ) => React.ReactNode)
122
- }
123
-
124
- type MakeLinkPropsOptions<
125
- TAllRouteInfo extends AnyAllRouteInfo,
126
- TFrom extends ValidFromPath<TAllRouteInfo>,
127
- TTo extends string,
128
- > = LinkPropsOptions<TAllRouteInfo, TFrom, TTo> &
129
- React.AnchorHTMLAttributes<HTMLAnchorElement>
130
-
131
- type MakeLinkOptions<
132
- TAllRouteInfo extends AnyAllRouteInfo,
133
- TFrom extends ValidFromPath<TAllRouteInfo>,
134
- TTo extends string,
135
- > = LinkPropsOptions<TAllRouteInfo, TFrom, TTo> &
136
- React.AnchorHTMLAttributes<HTMLAnchorElement> &
137
- Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'children'> & {
138
- // If a function is passed as a child, it will be given the `isActive` boolean to aid in further styling on the element it returns
139
- children?:
140
- | React.ReactNode
141
- | ((state: { isActive: boolean }) => React.ReactNode)
142
- }
143
-
144
- declare module '@tanstack/router-core' {
145
- interface FrameworkGenerics {
146
- Component: RouteComponent
147
- }
148
-
149
- interface Router<
150
- TRouteConfig extends AnyRouteConfig = RouteConfig,
151
- TAllRouteInfo extends AnyAllRouteInfo = AllRouteInfo<TRouteConfig>,
152
- > {
153
- useState: () => RouterState
154
- useRoute: <TId extends keyof TAllRouteInfo['routeInfoById']>(
155
- routeId: TId,
156
- ) => Route<TAllRouteInfo, TAllRouteInfo['routeInfoById'][TId]>
157
- useNearestMatch: () => RouteMatch<TAllRouteInfo, RouteInfo>
158
- useMatch: <
159
- TId extends keyof TAllRouteInfo['routeInfoById'],
160
- TStrict extends boolean = true,
161
- >(
162
- routeId: TId,
163
- opts?: { strict?: TStrict },
164
- ) => TStrict extends true
165
- ? RouteMatch<TAllRouteInfo, TAllRouteInfo['routeInfoById'][TId]>
166
- :
167
- | RouteMatch<TAllRouteInfo, TAllRouteInfo['routeInfoById'][TId]>
168
- | undefined
169
- linkProps: <TTo extends string = '.'>(
170
- props: MakeLinkPropsOptions<TAllRouteInfo, '/', TTo>,
171
- ) => React.AnchorHTMLAttributes<HTMLAnchorElement>
172
- Link: <TTo extends string = '.'>(
173
- props: MakeLinkOptions<TAllRouteInfo, '/', TTo>,
174
- ) => JSX.Element
175
- MatchRoute: <TTo extends string = '.'>(
176
- props: MakeMatchRouteOptions<TAllRouteInfo, '/', TTo>,
177
- ) => JSX.Element
178
- }
179
-
180
- interface Route<
181
- TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
182
- TRouteInfo extends AnyRouteInfo = RouteInfo,
183
- > {
184
- useRoute: <
185
- TTo extends string = '.',
186
- TResolved extends string = ResolveRelativePath<
187
- TRouteInfo['id'],
188
- NoInfer<TTo>
189
- >,
190
- >(
191
- routeId: CheckId<
192
- TAllRouteInfo,
193
- TResolved,
194
- ToIdOption<TAllRouteInfo, TRouteInfo['id'], TTo>
195
- >,
196
- opts?: { strict?: boolean },
197
- ) => Route<TAllRouteInfo, TAllRouteInfo['routeInfoById'][TResolved]>
198
- linkProps: <TTo extends string = '.'>(
199
- props: MakeLinkPropsOptions<TAllRouteInfo, TRouteInfo['fullPath'], TTo>,
200
- ) => React.AnchorHTMLAttributes<HTMLAnchorElement>
201
- Link: <TTo extends string = '.'>(
202
- props: MakeLinkOptions<TAllRouteInfo, TRouteInfo['fullPath'], TTo>,
203
- ) => JSX.Element
204
- MatchRoute: <TTo extends string = '.'>(
205
- props: MakeMatchRouteOptions<TAllRouteInfo, TRouteInfo['fullPath'], TTo>,
206
- ) => JSX.Element
207
- }
208
- }
209
-
210
- export type PromptProps = {
211
- message: string
212
- when?: boolean | any
213
- children?: React.ReactNode
214
- }
215
-
216
1
  //
217
-
218
- export function Link<TTo extends string = '.'>(
219
- props: MakeLinkOptions<RegisteredAllRouteInfo, '/', TTo>,
220
- ): JSX.Element {
221
- const router = useRouter()
222
- return <router.Link {...(props as any)} />
223
- }
224
-
225
- export const matchesContext = React.createContext<RouteMatch[]>(null!)
226
- export const routerContext = React.createContext<{ router: RegisteredRouter }>(
227
- null!,
228
- )
229
-
230
- export type MatchesProviderProps = {
231
- value: RouteMatch[]
232
- children: React.ReactNode
233
- }
234
-
235
- export function MatchesProvider(props: MatchesProviderProps) {
236
- return <matchesContext.Provider {...props} />
237
- }
238
-
239
- const useRouterSubscription = (router: Router<any, any>) => {
240
- useSyncExternalStore(
241
- (cb) => router.subscribe(() => cb()),
242
- () => router.state,
243
- () => router.state,
244
- )
245
- }
246
-
247
- export function createReactRouter<
248
- TRouteConfig extends AnyRouteConfig = RouteConfig,
249
- >(opts: RouterOptions<TRouteConfig>): Router<TRouteConfig> {
250
- const makeRouteExt = (
251
- route: AnyRoute,
252
- router: Router<any, any>,
253
- ): Pick<AnyRoute, 'useRoute' | 'linkProps' | 'Link' | 'MatchRoute'> => {
254
- return {
255
- useRoute: (subRouteId = '.' as any) => {
256
- const resolvedRouteId = router.resolvePath(
257
- route.routeId,
258
- subRouteId as string,
259
- )
260
- const resolvedRoute = router.getRoute(resolvedRouteId)
261
- useRouterSubscription(router)
262
- invariant(
263
- resolvedRoute,
264
- `Could not find a route for route "${
265
- resolvedRouteId as string
266
- }"! Did you forget to add it to your route config?`,
267
- )
268
- return resolvedRoute
269
- },
270
- linkProps: (options) => {
271
- const {
272
- // custom props
273
- type,
274
- children,
275
- target,
276
- activeProps = () => ({ className: 'active' }),
277
- inactiveProps = () => ({}),
278
- activeOptions,
279
- disabled,
280
- // fromCurrent,
281
- hash,
282
- search,
283
- params,
284
- to,
285
- preload,
286
- preloadDelay,
287
- preloadMaxAge,
288
- replace,
289
- // element props
290
- style,
291
- className,
292
- onClick,
293
- onFocus,
294
- onMouseEnter,
295
- onMouseLeave,
296
- onTouchStart,
297
- onTouchEnd,
298
- ...rest
299
- } = options
300
-
301
- const linkInfo = route.buildLink(options as any)
302
-
303
- if (linkInfo.type === 'external') {
304
- const { href } = linkInfo
305
- return { href }
306
- }
307
-
308
- const {
309
- handleClick,
310
- handleFocus,
311
- handleEnter,
312
- handleLeave,
313
- isActive,
314
- next,
315
- } = linkInfo
316
-
317
- const reactHandleClick = (e: Event) => {
318
- React.startTransition(() => {
319
- handleClick(e)
320
- })
321
- }
322
-
323
- const composeHandlers =
324
- (handlers: (undefined | ((e: any) => void))[]) =>
325
- (e: React.SyntheticEvent) => {
326
- e.persist()
327
- handlers.forEach((handler) => {
328
- if (handler) handler(e)
329
- })
330
- }
331
-
332
- // Get the active props
333
- const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> =
334
- isActive ? functionalUpdate(activeProps, {}) ?? {} : {}
335
-
336
- // Get the inactive props
337
- const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =
338
- isActive ? {} : functionalUpdate(inactiveProps, {}) ?? {}
339
-
340
- return {
341
- ...resolvedActiveProps,
342
- ...resolvedInactiveProps,
343
- ...rest,
344
- href: disabled ? undefined : next.href,
345
- onClick: composeHandlers([reactHandleClick, onClick]),
346
- onFocus: composeHandlers([handleFocus, onFocus]),
347
- onMouseEnter: composeHandlers([handleEnter, onMouseEnter]),
348
- onMouseLeave: composeHandlers([handleLeave, onMouseLeave]),
349
- target,
350
- style: {
351
- ...style,
352
- ...resolvedActiveProps.style,
353
- ...resolvedInactiveProps.style,
354
- },
355
- className:
356
- [
357
- className,
358
- resolvedActiveProps.className,
359
- resolvedInactiveProps.className,
360
- ]
361
- .filter(Boolean)
362
- .join(' ') || undefined,
363
- ...(disabled
364
- ? {
365
- role: 'link',
366
- 'aria-disabled': true,
367
- }
368
- : undefined),
369
- ['data-status']: isActive ? 'active' : undefined,
370
- }
371
- },
372
- Link: React.forwardRef((props: any, ref) => {
373
- const linkProps = route.linkProps(props)
374
-
375
- useRouterSubscription(router)
376
-
377
- return (
378
- <a
379
- {...{
380
- ref: ref as any,
381
- ...linkProps,
382
- children:
383
- typeof props.children === 'function'
384
- ? props.children({
385
- isActive: (linkProps as any)['data-status'] === 'active',
386
- })
387
- : props.children,
388
- }}
389
- />
390
- )
391
- }) as any,
392
- MatchRoute: (opts) => {
393
- const { pending, caseSensitive, children, ...rest } = opts
394
-
395
- const params = route.matchRoute(rest as any, {
396
- pending,
397
- caseSensitive,
398
- })
399
-
400
- if (!params) {
401
- return null
402
- }
403
-
404
- return typeof opts.children === 'function'
405
- ? opts.children(params as any)
406
- : (opts.children as any)
407
- },
408
- }
409
- }
410
-
411
- const coreRouter = createRouter<TRouteConfig>({
412
- ...opts,
413
- createRouter: (router) => {
414
- const routerExt: Pick<Router<any, any>, 'useMatch' | 'useState'> = {
415
- useState: () => {
416
- useRouterSubscription(router)
417
- return router.state
418
- },
419
- useMatch: (routeId, opts) => {
420
- useRouterSubscription(router)
421
-
422
- invariant(
423
- routeId !== rootRouteId,
424
- `"${rootRouteId}" cannot be used with useMatch! Did you mean to useRoute("${rootRouteId}")?`,
425
- )
426
-
427
- const runtimeMatch = useMatches()?.[0]!
428
- const match = router.state.matches.find((d) => d.routeId === routeId)
429
-
430
- if (opts?.strict ?? true) {
431
- invariant(
432
- match,
433
- `Could not find an active match for "${routeId as string}"!`,
434
- )
435
-
436
- invariant(
437
- runtimeMatch.routeId == match?.routeId,
438
- `useMatch("${
439
- match?.routeId as string
440
- }") is being called in a component that is meant to render the '${
441
- runtimeMatch.routeId
442
- }' route. Did you mean to 'useMatch("${
443
- match?.routeId as string
444
- }", { strict: false })' or 'useRoute("${
445
- match?.routeId as string
446
- }")' instead?`,
447
- )
448
- }
449
-
450
- return match as any
451
- },
452
- }
453
-
454
- const routeExt = makeRouteExt(router.getRoute(rootRouteId), router)
455
-
456
- Object.assign(router, routerExt, routeExt)
457
- },
458
- createRoute: ({ router, route }) => {
459
- const routeExt = makeRouteExt(route, router)
460
-
461
- Object.assign(route, routeExt)
462
- },
463
- loadComponent: async (component) => {
464
- if (component.preload && typeof document !== 'undefined') {
465
- component.preload()
466
- // return await component.preload()
467
- }
468
-
469
- return component as any
470
- },
471
- })
472
-
473
- return coreRouter as any
474
- }
475
-
476
- export type RouterProps<
477
- TRouteConfig extends AnyRouteConfig = RouteConfig,
478
- TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
479
- > = RouterOptions<TRouteConfig> & {
480
- router: Router<TRouteConfig, TAllRouteInfo>
481
- // Children will default to `<Outlet />` if not provided
482
- children?: React.ReactNode
483
- }
484
-
485
- export function RouterProvider<
486
- TRouteConfig extends AnyRouteConfig = RouteConfig,
487
- TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
488
- >({ children, router, ...rest }: RouterProps<TRouteConfig, TAllRouteInfo>) {
489
- router.update(rest)
490
-
491
- useRouterSubscription(router)
492
- React.useEffect(() => {
493
- console.log('hello')
494
- return router.mount()
495
- }, [router])
496
-
497
- return (
498
- <routerContext.Provider value={{ router: router as any }}>
499
- <MatchesProvider value={router.state.matches}>
500
- {children ?? <Outlet />}
501
- </MatchesProvider>
502
- </routerContext.Provider>
503
- )
504
- }
505
-
506
- export function useRouter(): RegisteredRouter {
507
- const value = React.useContext(routerContext)
508
- warning(!value, 'useRouter must be used inside a <Router> component!')
509
-
510
- useRouterSubscription(value.router)
511
-
512
- return value.router
513
- }
514
-
515
- export function useMatches(): RouteMatch[] {
516
- return React.useContext(matchesContext)
517
- }
518
-
519
- export function useMatch<
520
- TId extends keyof RegisteredAllRouteInfo['routeInfoById'],
521
- TStrict extends boolean = true,
522
- >(
523
- routeId: TId,
524
- opts?: { strict?: TStrict },
525
- ): TStrict extends true
526
- ? RouteMatch<
527
- RegisteredAllRouteInfo,
528
- RegisteredAllRouteInfo['routeInfoById'][TId]
529
- >
530
- :
531
- | RouteMatch<
532
- RegisteredAllRouteInfo,
533
- RegisteredAllRouteInfo['routeInfoById'][TId]
534
- >
535
- | undefined {
536
- const router = useRouter()
537
- return router.useMatch(routeId as any, opts) as any
538
- }
539
-
540
- export function useNearestMatch(): RouteMatch<
541
- RegisteredAllRouteInfo,
542
- RouteInfo
543
- > {
544
- const runtimeMatch = useMatches()?.[0]!
545
-
546
- invariant(runtimeMatch, `Could not find a nearest match!`)
547
-
548
- return runtimeMatch as any
549
- }
550
-
551
- export function useRoute<
552
- TId extends keyof RegisteredAllRouteInfo['routeInfoById'],
553
- >(
554
- routeId: TId,
555
- ): Route<RegisteredAllRouteInfo, RegisteredAllRouteInfo['routeInfoById'][TId]> {
556
- const router = useRouter()
557
- return router.useRoute(routeId as any) as any
558
- }
559
-
560
- export function linkProps<TTo extends string = '.'>(
561
- props: MakeLinkPropsOptions<RegisteredAllRouteInfo, '/', TTo>,
562
- ): React.AnchorHTMLAttributes<HTMLAnchorElement> {
563
- const router = useRouter()
564
- return router.linkProps(props as any)
565
- }
566
-
567
- export function MatchRoute<TTo extends string = '.'>(
568
- props: MakeMatchRouteOptions<RegisteredAllRouteInfo, '/', TTo>,
569
- ): JSX.Element {
570
- const router = useRouter()
571
- return React.createElement(router.MatchRoute, props as any)
572
- }
573
-
574
- export function Outlet() {
575
- const router = useRouter()
576
- const matches = useMatches().slice(1)
577
- const match = matches[0]
578
-
579
- const defaultPending = React.useCallback(() => null, [])
580
-
581
- if (!match) {
582
- return null
583
- }
584
-
585
- const PendingComponent = (match.__.pendingComponent ??
586
- router.options.defaultPendingComponent ??
587
- defaultPending) as any
588
-
589
- const errorComponent =
590
- match.__.errorComponent ?? router.options.defaultErrorComponent
591
-
592
- return (
593
- <MatchesProvider value={matches}>
594
- <React.Suspense fallback={<PendingComponent />}>
595
- <CatchBoundary errorComponent={errorComponent}>
596
- {
597
- ((): React.ReactNode => {
598
- if (match.status === 'error') {
599
- throw match.error
600
- }
601
-
602
- if (match.status === 'success') {
603
- return React.createElement(
604
- (match.__.component as any) ??
605
- router.options.defaultComponent ??
606
- Outlet,
607
- )
608
- }
609
-
610
- console.log(match.matchId, 'suspend')
611
- throw match.__.loadPromise
612
- })() as JSX.Element
613
- }
614
- </CatchBoundary>
615
- </React.Suspense>
616
- </MatchesProvider>
617
- )
618
- }
619
-
620
- class CatchBoundary extends React.Component<{
621
- children: any
622
- errorComponent: any
623
- }> {
624
- state = {
625
- error: false,
626
- }
627
- componentDidCatch(error: any, info: any) {
628
- console.error(error)
629
-
630
- this.setState({
631
- error,
632
- info,
633
- })
634
- }
635
- render() {
636
- const errorComponent = this.props.errorComponent ?? DefaultErrorBoundary
637
-
638
- if (this.state.error) {
639
- return React.createElement(errorComponent, this.state)
640
- }
641
-
642
- return this.props.children
643
- }
644
- }
645
-
646
- export function DefaultErrorBoundary({ error }: { error: any }) {
647
- return (
648
- <div style={{ padding: '.5rem', maxWidth: '100%' }}>
649
- <strong style={{ fontSize: '1.2rem' }}>Something went wrong!</strong>
650
- <div style={{ height: '.5rem' }} />
651
- <div>
652
- <pre>
653
- {error.message ? (
654
- <code
655
- style={{
656
- fontSize: '.7em',
657
- border: '1px solid red',
658
- borderRadius: '.25rem',
659
- padding: '.5rem',
660
- color: 'red',
661
- }}
662
- >
663
- {error.message}
664
- </code>
665
- ) : null}
666
- </pre>
667
- </div>
668
- </div>
669
- )
670
- }
671
-
672
- export function usePrompt(message: string, when: boolean | any): void {
673
- const router = useRouter()
674
-
675
- React.useEffect(() => {
676
- if (!when) return
677
-
678
- let unblock = router.history.block((transition) => {
679
- if (window.confirm(message)) {
680
- unblock()
681
- transition.retry()
682
- } else {
683
- router.location.pathname = window.location.pathname
684
- }
685
- })
686
-
687
- return unblock
688
- }, [when, location, message])
689
- }
690
-
691
- export function Prompt({ message, when, children }: PromptProps) {
692
- usePrompt(message, when ?? true)
693
- return (children ?? null) as React.ReactNode
694
- }
2
+ export * from '@tanstack/history'
3
+ export { default as invariant } from 'tiny-invariant'
4
+ export { default as warning } from 'tiny-warning'
5
+ export * from './awaited'
6
+ export * from './defer'
7
+ export * from './CatchBoundary'
8
+ export * from './fileRoute'
9
+ export * from './history'
10
+ export * from './index'
11
+ // export * from './injectHtml'
12
+ export * from './lazyRouteComponent'
13
+ export * from './link'
14
+ export * from './location'
15
+ export * from './Matches'
16
+ export * from './path'
17
+ export * from './qss'
18
+ export * from './redirects'
19
+ export * from './route'
20
+ export * from './routeInfo'
21
+ export * from './router'
22
+ export * from './RouterProvider'
23
+ export * from './scroll-restoration'
24
+ export * from './searchParams'
25
+ export * from './useBlocker'
26
+ export * from './useNavigate'
27
+ export * from './useParams'
28
+ export * from './useSearch'
29
+ export * from './utils'