@tanstack/react-router 0.0.1-beta.23 → 0.0.1-beta.231

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