@tanstack/react-router 0.0.1-beta.26 → 0.0.1-beta.261

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