@tanstack/react-router 0.0.1-beta.83 → 1.0.0

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 (225) hide show
  1. package/LICENSE +1 -1
  2. package/build/cjs/CatchBoundary.js +128 -0
  3. package/build/cjs/CatchBoundary.js.map +1 -0
  4. package/build/cjs/Matches.js +233 -0
  5. package/build/cjs/Matches.js.map +1 -0
  6. package/build/cjs/RouterProvider.js +170 -0
  7. package/build/cjs/RouterProvider.js.map +1 -0
  8. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +2 -4
  9. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +1 -1
  10. package/build/cjs/_virtual/with-selector.development.js +16 -0
  11. package/build/cjs/_virtual/with-selector.development.js.map +1 -0
  12. package/build/cjs/_virtual/with-selector.js +16 -0
  13. package/build/cjs/_virtual/with-selector.js.map +1 -0
  14. package/build/cjs/_virtual/with-selector.production.min.js +16 -0
  15. package/build/cjs/_virtual/with-selector.production.min.js.map +1 -0
  16. package/build/cjs/awaited.js +43 -0
  17. package/build/cjs/awaited.js.map +1 -0
  18. package/build/cjs/build/esm/index.js +79 -0
  19. package/build/cjs/build/esm/index.js.map +1 -0
  20. package/build/cjs/defer.js +37 -0
  21. package/build/cjs/defer.js.map +1 -0
  22. package/build/cjs/fileRoute.js +27 -0
  23. package/build/cjs/fileRoute.js.map +1 -0
  24. package/build/cjs/index.js +113 -451
  25. package/build/cjs/index.js.map +1 -1
  26. package/build/cjs/lazyRouteComponent.js +54 -0
  27. package/build/cjs/lazyRouteComponent.js.map +1 -0
  28. package/build/cjs/link.js +223 -0
  29. package/build/cjs/link.js.map +1 -0
  30. package/build/cjs/node_modules/.pnpm/@tanstack_react-store@0.2.1_react-dom@18.2.0_react@18.2.0/node_modules/@tanstack/react-store/build/modern/index.js +47 -0
  31. package/build/cjs/node_modules/.pnpm/@tanstack_react-store@0.2.1_react-dom@18.2.0_react@18.2.0/node_modules/@tanstack/react-store/build/modern/index.js.map +1 -0
  32. package/build/cjs/node_modules/.pnpm/@tanstack_store@0.1.3/node_modules/@tanstack/store/build/modern/index.js +70 -0
  33. package/build/cjs/node_modules/.pnpm/@tanstack_store@0.1.3/node_modules/@tanstack/store/build/modern/index.js.map +1 -0
  34. package/build/cjs/node_modules/.pnpm/use-sync-external-store@1.2.0_react@18.2.0/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.js +188 -0
  35. package/build/cjs/node_modules/.pnpm/use-sync-external-store@1.2.0_react@18.2.0/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.js.map +1 -0
  36. package/build/cjs/node_modules/.pnpm/use-sync-external-store@1.2.0_react@18.2.0/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.js +39 -0
  37. package/build/cjs/node_modules/.pnpm/use-sync-external-store@1.2.0_react@18.2.0/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.js.map +1 -0
  38. package/build/cjs/node_modules/.pnpm/use-sync-external-store@1.2.0_react@18.2.0/node_modules/use-sync-external-store/shim/with-selector.js +26 -0
  39. package/build/cjs/node_modules/.pnpm/use-sync-external-store@1.2.0_react@18.2.0/node_modules/use-sync-external-store/shim/with-selector.js.map +1 -0
  40. package/build/cjs/packages/react-router/src/CatchBoundary.js +123 -0
  41. package/build/cjs/packages/react-router/src/CatchBoundary.js.map +1 -0
  42. package/build/cjs/packages/react-router/src/Matches.js +235 -0
  43. package/build/cjs/packages/react-router/src/Matches.js.map +1 -0
  44. package/build/cjs/packages/react-router/src/RouterProvider.js +144 -0
  45. package/build/cjs/packages/react-router/src/RouterProvider.js.map +1 -0
  46. package/build/cjs/packages/react-router/src/awaited.js +43 -0
  47. package/build/cjs/packages/react-router/src/awaited.js.map +1 -0
  48. package/build/cjs/packages/react-router/src/defer.js +37 -0
  49. package/build/cjs/packages/react-router/src/defer.js.map +1 -0
  50. package/build/cjs/packages/react-router/src/fileRoute.js +27 -0
  51. package/build/cjs/packages/react-router/src/fileRoute.js.map +1 -0
  52. package/build/cjs/packages/react-router/src/index.js +61 -0
  53. package/build/cjs/packages/react-router/src/index.js.map +1 -0
  54. package/build/cjs/packages/react-router/src/lazyRouteComponent.js +54 -0
  55. package/build/cjs/packages/react-router/src/lazyRouteComponent.js.map +1 -0
  56. package/build/cjs/packages/react-router/src/link.js +148 -0
  57. package/build/cjs/packages/react-router/src/link.js.map +1 -0
  58. package/build/cjs/packages/react-router/src/path.js +209 -0
  59. package/build/cjs/packages/react-router/src/path.js.map +1 -0
  60. package/build/cjs/packages/react-router/src/qss.js +63 -0
  61. package/build/cjs/packages/react-router/src/qss.js.map +1 -0
  62. package/build/cjs/packages/react-router/src/react.js +634 -0
  63. package/build/cjs/packages/react-router/src/react.js.map +1 -0
  64. package/build/cjs/packages/react-router/src/redirects.js +25 -0
  65. package/build/cjs/packages/react-router/src/redirects.js.map +1 -0
  66. package/build/cjs/packages/react-router/src/route.js +134 -0
  67. package/build/cjs/packages/react-router/src/route.js.map +1 -0
  68. package/build/cjs/packages/react-router/src/router.js +1111 -0
  69. package/build/cjs/packages/react-router/src/router.js.map +1 -0
  70. package/build/cjs/packages/react-router/src/scroll-restoration.js +53 -0
  71. package/build/cjs/packages/react-router/src/scroll-restoration.js.map +1 -0
  72. package/build/cjs/packages/react-router/src/searchParams.js +81 -0
  73. package/build/cjs/packages/react-router/src/searchParams.js.map +1 -0
  74. package/build/cjs/packages/react-router/src/useBlocker.js +61 -0
  75. package/build/cjs/packages/react-router/src/useBlocker.js.map +1 -0
  76. package/build/cjs/packages/react-router/src/useNavigate.js +75 -0
  77. package/build/cjs/packages/react-router/src/useNavigate.js.map +1 -0
  78. package/build/cjs/packages/react-router/src/useParams.js +26 -0
  79. package/build/cjs/packages/react-router/src/useParams.js.map +1 -0
  80. package/build/cjs/packages/react-router/src/useSearch.js +25 -0
  81. package/build/cjs/packages/react-router/src/useSearch.js.map +1 -0
  82. package/build/cjs/packages/react-router/src/utils.js +239 -0
  83. package/build/cjs/packages/react-router/src/utils.js.map +1 -0
  84. package/build/cjs/path.js +214 -0
  85. package/build/cjs/path.js.map +1 -0
  86. package/build/cjs/qss.js +63 -0
  87. package/build/cjs/qss.js.map +1 -0
  88. package/build/cjs/react/CatchBoundary.js +123 -0
  89. package/build/cjs/react/CatchBoundary.js.map +1 -0
  90. package/build/cjs/react/awaited.js +43 -0
  91. package/build/cjs/react/awaited.js.map +1 -0
  92. package/build/cjs/react/defer.js +37 -0
  93. package/build/cjs/react/defer.js.map +1 -0
  94. package/build/cjs/react.js +650 -0
  95. package/build/cjs/react.js.map +1 -0
  96. package/build/cjs/redirects.js +28 -0
  97. package/build/cjs/redirects.js.map +1 -0
  98. package/build/cjs/route.js +191 -0
  99. package/build/cjs/route.js.map +1 -0
  100. package/build/cjs/router.js +1085 -0
  101. package/build/cjs/router.js.map +1 -0
  102. package/build/cjs/routerConfig.js +209 -0
  103. package/build/cjs/routerConfig.js.map +1 -0
  104. package/build/cjs/scroll-restoration.js +202 -0
  105. package/build/cjs/scroll-restoration.js.map +1 -0
  106. package/build/cjs/searchParams.js +81 -0
  107. package/build/cjs/searchParams.js.map +1 -0
  108. package/build/cjs/src/CatchBoundary.js +126 -0
  109. package/build/cjs/src/CatchBoundary.js.map +1 -0
  110. package/build/cjs/src/Matches.js +235 -0
  111. package/build/cjs/src/Matches.js.map +1 -0
  112. package/build/cjs/src/RouterProvider.js +1051 -0
  113. package/build/cjs/src/RouterProvider.js.map +1 -0
  114. package/build/cjs/src/awaited.js +45 -0
  115. package/build/cjs/src/awaited.js.map +1 -0
  116. package/build/cjs/src/defer.js +39 -0
  117. package/build/cjs/src/defer.js.map +1 -0
  118. package/build/cjs/src/fileRoute.js +29 -0
  119. package/build/cjs/src/fileRoute.js.map +1 -0
  120. package/build/cjs/src/index.js +134 -0
  121. package/build/cjs/src/index.js.map +1 -0
  122. package/build/cjs/src/lazyRouteComponent.js +57 -0
  123. package/build/cjs/src/lazyRouteComponent.js.map +1 -0
  124. package/build/cjs/src/link.js +151 -0
  125. package/build/cjs/src/link.js.map +1 -0
  126. package/build/cjs/src/path.js +211 -0
  127. package/build/cjs/src/path.js.map +1 -0
  128. package/build/cjs/src/qss.js +65 -0
  129. package/build/cjs/src/qss.js.map +1 -0
  130. package/build/cjs/src/redirects.js +27 -0
  131. package/build/cjs/src/redirects.js.map +1 -0
  132. package/build/cjs/src/route.js +139 -0
  133. package/build/cjs/src/route.js.map +1 -0
  134. package/build/cjs/src/router.js +203 -0
  135. package/build/cjs/src/router.js.map +1 -0
  136. package/build/cjs/src/scroll-restoration.js +186 -0
  137. package/build/cjs/src/scroll-restoration.js.map +1 -0
  138. package/build/cjs/src/searchParams.js +83 -0
  139. package/build/cjs/src/searchParams.js.map +1 -0
  140. package/build/cjs/src/useBlocker.js +64 -0
  141. package/build/cjs/src/useBlocker.js.map +1 -0
  142. package/build/cjs/src/useNavigate.js +78 -0
  143. package/build/cjs/src/useNavigate.js.map +1 -0
  144. package/build/cjs/src/useParams.js +28 -0
  145. package/build/cjs/src/useParams.js.map +1 -0
  146. package/build/cjs/src/useSearch.js +27 -0
  147. package/build/cjs/src/useSearch.js.map +1 -0
  148. package/build/cjs/src/utils.js +230 -0
  149. package/build/cjs/src/utils.js.map +1 -0
  150. package/build/cjs/useBlocker.js +55 -0
  151. package/build/cjs/useBlocker.js.map +1 -0
  152. package/build/cjs/useNavigate.js +86 -0
  153. package/build/cjs/useNavigate.js.map +1 -0
  154. package/build/cjs/useParams.js +26 -0
  155. package/build/cjs/useParams.js.map +1 -0
  156. package/build/cjs/useSearch.js +25 -0
  157. package/build/cjs/useSearch.js.map +1 -0
  158. package/build/cjs/useStore.js +99 -0
  159. package/build/cjs/useStore.js.map +1 -0
  160. package/build/cjs/utils.js +241 -0
  161. package/build/cjs/utils.js.map +1 -0
  162. package/build/esm/index.js +2581 -337
  163. package/build/esm/index.js.map +1 -1
  164. package/build/stats-html.html +3494 -2700
  165. package/build/stats-react.json +1134 -87
  166. package/build/types/CatchBoundary.d.ts +36 -0
  167. package/build/types/Matches.d.ts +64 -0
  168. package/build/types/RouteMatch.d.ts +23 -0
  169. package/build/types/RouterProvider.d.ts +35 -0
  170. package/build/types/awaited.d.ts +9 -0
  171. package/build/types/defer.d.ts +19 -0
  172. package/build/types/fileRoute.d.ts +38 -0
  173. package/build/types/history.d.ts +7 -0
  174. package/build/types/index.d.ts +911 -88
  175. package/build/types/injectHtml.d.ts +0 -0
  176. package/build/types/lazyRouteComponent.d.ts +2 -0
  177. package/build/types/link.d.ts +93 -0
  178. package/build/types/location.d.ts +12 -0
  179. package/build/types/path.d.ts +17 -0
  180. package/build/types/qss.d.ts +2 -0
  181. package/build/types/react/CatchBoundary.d.ts +33 -0
  182. package/build/types/react/awaited.d.ts +9 -0
  183. package/build/types/react/defer.d.ts +19 -0
  184. package/build/types/react.d.ts +141 -0
  185. package/build/types/redirects.d.ts +11 -0
  186. package/build/types/route.d.ts +283 -0
  187. package/build/types/routeInfo.d.ts +31 -0
  188. package/build/types/router.d.ts +186 -0
  189. package/build/types/scroll-restoration.d.ts +18 -0
  190. package/build/types/searchParams.d.ts +7 -0
  191. package/build/types/useBlocker.d.ts +9 -0
  192. package/build/types/useNavigate.d.ts +19 -0
  193. package/build/types/useParams.d.ts +7 -0
  194. package/build/types/useSearch.d.ts +7 -0
  195. package/build/types/useStore.d.ts +12 -0
  196. package/build/types/utils.d.ts +69 -0
  197. package/build/umd/index.development.js +2829 -1796
  198. package/build/umd/index.development.js.map +1 -1
  199. package/build/umd/index.production.js +4 -24
  200. package/build/umd/index.production.js.map +1 -1
  201. package/package.json +9 -7
  202. package/src/CatchBoundary.tsx +101 -0
  203. package/src/Matches.tsx +423 -0
  204. package/src/RouterProvider.tsx +252 -0
  205. package/src/awaited.tsx +40 -0
  206. package/src/defer.ts +55 -0
  207. package/src/fileRoute.ts +152 -0
  208. package/src/history.ts +8 -0
  209. package/src/index.tsx +28 -747
  210. package/src/lazyRouteComponent.tsx +33 -0
  211. package/src/link.tsx +603 -0
  212. package/src/location.ts +13 -0
  213. package/src/path.ts +261 -0
  214. package/src/qss.ts +53 -0
  215. package/src/redirects.ts +39 -0
  216. package/src/route.ts +882 -0
  217. package/src/routeInfo.ts +84 -0
  218. package/src/router.ts +1671 -0
  219. package/src/scroll-restoration.tsx +230 -0
  220. package/src/searchParams.ts +79 -0
  221. package/src/useBlocker.tsx +27 -0
  222. package/src/useNavigate.tsx +111 -0
  223. package/src/useParams.tsx +25 -0
  224. package/src/useSearch.tsx +25 -0
  225. package/src/utils.ts +360 -0
package/src/index.tsx CHANGED
@@ -1,748 +1,29 @@
1
- import * as React from 'react'
2
-
3
- import {
4
- RegisteredRoutesInfo,
5
- RegisteredRouter,
6
- RouterStore,
7
- last,
8
- warning,
9
- RouterOptions,
10
- RouteMatch,
11
- MatchRouteOptions,
12
- AnyRoutesInfo,
13
- DefaultRoutesInfo,
14
- functionalUpdate,
15
- RoutesInfo,
16
- ValidFromPath,
17
- LinkOptions,
18
- RouteByPath,
19
- ResolveRelativePath,
20
- NoInfer,
21
- ToOptions,
22
- invariant,
23
- Router,
24
- AnyRootRoute,
25
- RootRoute,
26
- AnyRouteMatch,
27
- NavigateOptions,
28
- RouterConstructorOptions,
29
- } from '@tanstack/router'
30
- import { useStore } from '@tanstack/react-store'
31
-
32
1
  //
33
-
34
- export * from '@tanstack/router'
35
-
36
- export { useStore }
37
-
38
- //
39
-
40
- type ReactNode = any
41
-
42
- export type SyncRouteComponent<TProps = {}> = (props: TProps) => ReactNode
43
-
44
- export type RouteComponent<TProps = {}> = SyncRouteComponent<TProps> & {
45
- preload?: () => Promise<void>
46
- }
47
-
48
- export function lazy(
49
- importer: () => Promise<{ default: SyncRouteComponent }>,
50
- ): RouteComponent {
51
- const lazyComp = React.lazy(importer as any)
52
- let preloaded: Promise<SyncRouteComponent>
53
-
54
- const finalComp = lazyComp as unknown as RouteComponent
55
-
56
- finalComp.preload = async () => {
57
- if (!preloaded) {
58
- await importer()
59
- }
60
- }
61
-
62
- return finalComp
63
- }
64
-
65
- export type LinkPropsOptions<
66
- TFrom extends RegisteredRoutesInfo['routePaths'] = '/',
67
- TTo extends string = '',
68
- > = LinkOptions<RegisteredRoutesInfo, TFrom, TTo> & {
69
- // 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)
70
- activeProps?:
71
- | React.AnchorHTMLAttributes<HTMLAnchorElement>
72
- | (() => React.AnchorHTMLAttributes<HTMLAnchorElement>)
73
- // 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)
74
- inactiveProps?:
75
- | React.AnchorHTMLAttributes<HTMLAnchorElement>
76
- | (() => React.AnchorHTMLAttributes<HTMLAnchorElement>)
77
- }
78
-
79
- export type MakeUseMatchRouteOptions<
80
- TFrom extends RegisteredRoutesInfo['routePaths'] = '/',
81
- TTo extends string = '',
82
- > = ToOptions<RegisteredRoutesInfo, TFrom, TTo> & MatchRouteOptions
83
-
84
- export type MakeMatchRouteOptions<
85
- TFrom extends RegisteredRoutesInfo['routePaths'] = '/',
86
- TTo extends string = '',
87
- > = ToOptions<RegisteredRoutesInfo, TFrom, TTo> &
88
- MatchRouteOptions & {
89
- // 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
90
- children?:
91
- | ReactNode
92
- | ((
93
- params: RouteByPath<
94
- RegisteredRoutesInfo,
95
- ResolveRelativePath<TFrom, NoInfer<TTo>>
96
- >['__types']['allParams'],
97
- ) => ReactNode)
98
- }
99
-
100
- export type MakeLinkPropsOptions<
101
- TFrom extends ValidFromPath<RegisteredRoutesInfo> = '/',
102
- TTo extends string = '',
103
- > = LinkPropsOptions<TFrom, TTo> & React.AnchorHTMLAttributes<HTMLAnchorElement>
104
-
105
- export type MakeLinkOptions<
106
- TFrom extends RegisteredRoutesInfo['routePaths'] = '/',
107
- TTo extends string = '',
108
- > = LinkPropsOptions<TFrom, TTo> &
109
- React.AnchorHTMLAttributes<HTMLAnchorElement> &
110
- Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'children'> & {
111
- // 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
112
- children?: ReactNode | ((state: { isActive: boolean }) => ReactNode)
113
- }
114
-
115
- declare module '@tanstack/router' {
116
- interface FrameworkGenerics {
117
- Component: RouteComponent
118
- ErrorComponent: RouteComponent<{
119
- error: Error
120
- info: { componentStack: string }
121
- }>
122
- }
123
-
124
- interface RouterOptions<TRouteTree> {
125
- // ssrFooter?: () => JSX.Element | Node
126
- }
127
-
128
- interface FrameworkRouteOptions {
129
- wrapInSuspense?: boolean
130
- }
131
- }
132
-
133
- export type PromptProps = {
134
- message: string
135
- condition?: boolean | any
136
- children?: ReactNode
137
- }
138
-
139
- //
140
-
141
- export function useLinkProps<
142
- TFrom extends ValidFromPath<RegisteredRoutesInfo> = '/',
143
- TTo extends string = '',
144
- >(
145
- options: MakeLinkPropsOptions<TFrom, TTo>,
146
- ): React.AnchorHTMLAttributes<HTMLAnchorElement> {
147
- const router = useRouterContext()
148
-
149
- const {
150
- // custom props
151
- type,
152
- children,
153
- target,
154
- activeProps = () => ({ className: 'active' }),
155
- inactiveProps = () => ({}),
156
- activeOptions,
157
- disabled,
158
- // fromCurrent,
159
- hash,
160
- search,
161
- params,
162
- to = '.',
163
- preload,
164
- preloadDelay,
165
- replace,
166
- // element props
167
- style,
168
- className,
169
- onClick,
170
- onFocus,
171
- onMouseEnter,
172
- onMouseLeave,
173
- onTouchStart,
174
- ...rest
175
- } = options
176
-
177
- const linkInfo = router.buildLink(options as any)
178
-
179
- if (linkInfo.type === 'external') {
180
- const { href } = linkInfo
181
- return { href }
182
- }
183
-
184
- const {
185
- handleClick,
186
- handleFocus,
187
- handleEnter,
188
- handleLeave,
189
- handleTouchStart,
190
- isActive,
191
- next,
192
- } = linkInfo
193
-
194
- const reactHandleClick = (e: Event) => {
195
- if (React.startTransition) {
196
- // This is a hack for react < 18
197
- React.startTransition(() => {
198
- handleClick(e)
199
- })
200
- } else {
201
- handleClick(e)
202
- }
203
- }
204
-
205
- const composeHandlers =
206
- (handlers: (undefined | ((e: any) => void))[]) =>
207
- (e: React.SyntheticEvent) => {
208
- if (e.persist) e.persist()
209
- handlers.filter(Boolean).forEach((handler) => {
210
- if (e.defaultPrevented) return
211
- handler!(e)
212
- })
213
- }
214
-
215
- // Get the active props
216
- const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> = isActive
217
- ? functionalUpdate(activeProps as any, {}) ?? {}
218
- : {}
219
-
220
- // Get the inactive props
221
- const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =
222
- isActive ? {} : functionalUpdate(inactiveProps, {}) ?? {}
223
-
224
- return {
225
- ...resolvedActiveProps,
226
- ...resolvedInactiveProps,
227
- ...rest,
228
- href: disabled ? undefined : next.href,
229
- onClick: composeHandlers([onClick, reactHandleClick]),
230
- onFocus: composeHandlers([onFocus, handleFocus]),
231
- onMouseEnter: composeHandlers([onMouseEnter, handleEnter]),
232
- onMouseLeave: composeHandlers([onMouseLeave, handleLeave]),
233
- onTouchStart: composeHandlers([onTouchStart, handleTouchStart]),
234
- target,
235
- style: {
236
- ...style,
237
- ...resolvedActiveProps.style,
238
- ...resolvedInactiveProps.style,
239
- },
240
- className:
241
- [
242
- className,
243
- resolvedActiveProps.className,
244
- resolvedInactiveProps.className,
245
- ]
246
- .filter(Boolean)
247
- .join(' ') || undefined,
248
- ...(disabled
249
- ? {
250
- role: 'link',
251
- 'aria-disabled': true,
252
- }
253
- : undefined),
254
- ['data-status']: isActive ? 'active' : undefined,
255
- }
256
- }
257
-
258
- export interface LinkFn<
259
- TDefaultFrom extends RegisteredRoutesInfo['routePaths'] = '/',
260
- TDefaultTo extends string = '',
261
- > {
262
- <
263
- TFrom extends RegisteredRoutesInfo['routePaths'] = TDefaultFrom,
264
- TTo extends string = TDefaultTo,
265
- >(
266
- props: MakeLinkOptions<TFrom, TTo> & React.RefAttributes<HTMLAnchorElement>,
267
- ): ReactNode
268
- }
269
-
270
- export const Link: LinkFn = React.forwardRef((props: any, ref) => {
271
- const linkProps = useLinkProps(props)
272
-
273
- return (
274
- <a
275
- {...{
276
- ref: ref as any,
277
- ...linkProps,
278
- children:
279
- typeof props.children === 'function'
280
- ? props.children({
281
- isActive: (linkProps as any)['data-status'] === 'active',
282
- })
283
- : props.children,
284
- }}
285
- />
286
- )
287
- }) as any
288
-
289
- export function Navigate<
290
- TFrom extends RegisteredRoutesInfo['routePaths'] = '/',
291
- TTo extends string = '',
292
- >(props: NavigateOptions<RegisteredRoutesInfo, TFrom, TTo>): null {
293
- const router = useRouterContext()
294
-
295
- React.useLayoutEffect(() => {
296
- router.navigate(props as any)
297
- }, [])
298
-
299
- return null
300
- }
301
-
302
- type MatchesContextValue = AnyRouteMatch[]
303
-
304
- export const matchesContext = React.createContext<MatchesContextValue>(null!)
305
- export const routerContext = React.createContext<{ router: RegisteredRouter }>(
306
- null!,
307
- )
308
-
309
- export type MatchesProviderProps = {
310
- value: MatchesContextValue
311
- children: ReactNode
312
- }
313
-
314
- export class ReactRouter<
315
- TRouteConfig extends AnyRootRoute = RootRoute,
316
- TRoutesInfo extends AnyRoutesInfo = RoutesInfo<TRouteConfig>,
317
- > extends Router<TRouteConfig, TRoutesInfo> {
318
- constructor(opts: RouterConstructorOptions<TRouteConfig>) {
319
- super({
320
- ...opts,
321
- loadComponent: async (component) => {
322
- if (component.preload) {
323
- await component.preload()
324
- }
325
-
326
- return component as any
327
- },
328
- })
329
- }
330
- }
331
-
332
- export type RouterProps<
333
- TRouteConfig extends AnyRootRoute = RootRoute,
334
- TRoutesInfo extends AnyRoutesInfo = DefaultRoutesInfo,
335
- > = RouterOptions<TRouteConfig> & {
336
- router: Router<TRouteConfig, TRoutesInfo>
337
- }
338
-
339
- export function RouterProvider<
340
- TRouteConfig extends AnyRootRoute = RootRoute,
341
- TRoutesInfo extends AnyRoutesInfo = DefaultRoutesInfo,
342
- >({ router, ...rest }: RouterProps<TRouteConfig, TRoutesInfo>) {
343
- router.update(rest)
344
-
345
- const currentMatches = useStore(router.__store, (s) => s.currentMatches)
346
-
347
- React.useEffect(router.mount, [router])
348
-
349
- return (
350
- <routerContext.Provider value={{ router: router as any }}>
351
- <matchesContext.Provider value={[undefined!, ...currentMatches]}>
352
- <CatchBoundary
353
- errorComponent={ErrorComponent}
354
- onCatch={() => {
355
- warning(
356
- false,
357
- `Error in router! Consider setting an 'errorComponent' in your RootRoute! 👍`,
358
- )
359
- }}
360
- >
361
- <Outlet />
362
- </CatchBoundary>
363
- </matchesContext.Provider>
364
- </routerContext.Provider>
365
- )
366
- }
367
-
368
- export function useRouterContext(): RegisteredRouter {
369
- const value = React.useContext(routerContext)
370
- warning(value, 'useRouter must be used inside a <Router> component!')
371
-
372
- useStore(value.router.__store)
373
-
374
- return value.router
375
- }
376
-
377
- export function useRouter<T = RouterStore>(
378
- track?: (state: Router['__store']) => T,
379
- shallow?: boolean,
380
- ): RegisteredRouter {
381
- const router = useRouterContext()
382
- useStore(router.__store, track as any, shallow)
383
- return router
384
- }
385
-
386
- export function useMatches(): RouteMatch[] {
387
- return React.useContext(matchesContext)
388
- }
389
-
390
- export function useMatch<
391
- TFrom extends keyof RegisteredRoutesInfo['routesById'],
392
- TStrict extends boolean = true,
393
- TRouteMatch = RouteMatch<
394
- RegisteredRoutesInfo,
395
- RegisteredRoutesInfo['routesById'][TFrom]
396
- >,
397
- >(opts?: {
398
- from: TFrom
399
- strict?: TStrict
400
- track?: (match: TRouteMatch) => any
401
- shallow?: boolean
402
- }): TStrict extends true ? TRouteMatch : TRouteMatch | undefined {
403
- const router = useRouterContext()
404
- const nearestMatch = useMatches()[0]!
405
- const match = opts?.from
406
- ? router.state.currentMatches.find((d) => d.route.id === opts?.from)
407
- : nearestMatch
408
-
409
- invariant(
410
- match,
411
- `Could not find ${
412
- opts?.from ? `an active match from "${opts.from}"` : 'a nearest match!'
413
- }`,
414
- )
415
-
416
- if (opts?.strict ?? true) {
417
- invariant(
418
- nearestMatch.route.id == match?.route.id,
419
- `useMatch("${
420
- match?.route.id as string
421
- }") is being called in a component that is meant to render the '${
422
- nearestMatch.route.id
423
- }' route. Did you mean to 'useMatch("${
424
- match?.route.id as string
425
- }", { strict: false })' or 'useRoute("${
426
- match?.route.id as string
427
- }")' instead?`,
428
- )
429
- }
430
-
431
- useStore(
432
- match!.__store as any,
433
- (d) => opts?.track?.(match as any) ?? match,
434
- opts?.shallow,
435
- )
436
-
437
- return match as any
438
- }
439
-
440
- export function useRoute<
441
- TId extends keyof RegisteredRoutesInfo['routesById'] = '/',
442
- >(routeId: TId): RegisteredRoutesInfo['routesById'][TId] {
443
- const router = useRouterContext()
444
- const resolvedRoute = router.getRoute(routeId as any)
445
-
446
- invariant(
447
- resolvedRoute,
448
- `Could not find a route for route "${
449
- routeId as string
450
- }"! Did you forget to add it to your route?`,
451
- )
452
-
453
- return resolvedRoute as any
454
- }
455
-
456
- export function useSearch<
457
- TFrom extends keyof RegisteredRoutesInfo['routesById'],
458
- TStrict extends boolean = true,
459
- TSearch = RegisteredRoutesInfo['routesById'][TFrom]['__types']['fullSearchSchema'],
460
- TSelected = TSearch,
461
- >(opts?: {
462
- from: TFrom
463
- strict?: TStrict
464
- track?: (search: TSearch) => TSelected
465
- }): TStrict extends true ? TSelected : TSelected | undefined {
466
- const { track, ...matchOpts } = opts as any
467
- const match = useMatch(matchOpts)
468
- useStore(match.__store, (d: any) => opts?.track?.(d.search) ?? d.search, true)
469
-
470
- return (match as unknown as RouteMatch).state.search as any
471
- }
472
-
473
- export function useParams<
474
- TFrom extends keyof RegisteredRoutesInfo['routesById'] = '/',
475
- TDefaultSelected = RegisteredRoutesInfo['allParams'] &
476
- RegisteredRoutesInfo['routesById'][TFrom]['__types']['allParams'],
477
- TSelected = TDefaultSelected,
478
- >(opts?: {
479
- from: TFrom
480
- track?: (search: TDefaultSelected) => TSelected
481
- }): TSelected {
482
- const router = useRouterContext()
483
- useStore(
484
- router.__store,
485
- (d) => {
486
- const params = last(d.currentMatches)?.params as any
487
- return opts?.track?.(params) ?? params
488
- },
489
- true,
490
- )
491
-
492
- return last(router.state.currentMatches)?.params as any
493
- }
494
-
495
- export function useNavigate<
496
- TDefaultFrom extends keyof RegisteredRoutesInfo['routesById'] = '/',
497
- >(defaultOpts?: { from?: TDefaultFrom }) {
498
- const router = useRouterContext()
499
- return React.useCallback(
500
- <
501
- TFrom extends keyof RegisteredRoutesInfo['routesById'] = TDefaultFrom,
502
- TTo extends string = '',
503
- >(
504
- opts?: MakeLinkOptions<TFrom, TTo>,
505
- ) => {
506
- return router.navigate({ ...defaultOpts, ...(opts as any) })
507
- },
508
- [],
509
- )
510
- }
511
-
512
- export function useMatchRoute() {
513
- const router = useRouterContext()
514
-
515
- return React.useCallback(
516
- <
517
- TFrom extends ValidFromPath<RegisteredRoutesInfo> = '/',
518
- TTo extends string = '',
519
- >(
520
- opts: MakeUseMatchRouteOptions<TFrom, TTo>,
521
- ) => {
522
- const { pending, caseSensitive, ...rest } = opts
523
-
524
- return router.matchRoute(rest as any, {
525
- pending,
526
- caseSensitive,
527
- })
528
- },
529
- [],
530
- )
531
- }
532
-
533
- export function MatchRoute<
534
- TFrom extends ValidFromPath<RegisteredRoutesInfo> = '/',
535
- TTo extends string = '',
536
- >(props: MakeMatchRouteOptions<TFrom, TTo>): any {
537
- const matchRoute = useMatchRoute()
538
- const params = matchRoute(props)
539
-
540
- if (!params) {
541
- return null
542
- }
543
-
544
- if (typeof props.children === 'function') {
545
- return (props.children as any)(params)
546
- }
547
-
548
- return params ? props.children : null
549
- }
550
-
551
- export function Outlet() {
552
- const matches = useMatches().slice(1)
553
- const match = matches[0]
554
-
555
- if (!match) {
556
- return null
557
- }
558
-
559
- return <SubOutlet matches={matches} match={match} />
560
- }
561
-
562
- function SubOutlet({
563
- matches,
564
- match,
565
- }: {
566
- matches: RouteMatch[]
567
- match: RouteMatch
568
- }) {
569
- const router = useRouterContext()
570
- useStore(match!.__store, (store) => [store.status, store.error], true)
571
-
572
- const defaultPending = React.useCallback(() => null, [])
573
-
574
- const PendingComponent = (match.pendingComponent ??
575
- router.options.defaultPendingComponent ??
576
- defaultPending) as any
577
-
578
- const errorComponent =
579
- match.errorComponent ?? router.options.defaultErrorComponent
580
-
581
- const ResolvedSuspenseBoundary =
582
- match.route.options.wrapInSuspense ?? true ? React.Suspense : SafeFragment
583
- const ResolvedCatchBoundary = errorComponent ? CatchBoundary : SafeFragment
584
-
585
- return (
586
- <matchesContext.Provider value={matches}>
587
- <ResolvedSuspenseBoundary fallback={<PendingComponent />}>
588
- <ResolvedCatchBoundary
589
- key={match.route.id}
590
- errorComponent={errorComponent}
591
- onCatch={() => {
592
- warning(false, `Error in route match: ${match.id}`)
593
- }}
594
- >
595
- <Inner match={match} />
596
- </ResolvedCatchBoundary>
597
- </ResolvedSuspenseBoundary>
598
- </matchesContext.Provider>
599
- )
600
- }
601
-
602
- function Inner(props: { match: RouteMatch }): any {
603
- const router = useRouterContext()
604
-
605
- if (props.match.state.status === 'error') {
606
- throw props.match.state.error
607
- }
608
-
609
- if (props.match.state.status === 'success') {
610
- return React.createElement(
611
- (props.match.component as any) ??
612
- router.options.defaultComponent ??
613
- Outlet,
614
- )
615
- }
616
-
617
- if (props.match.state.status === 'pending') {
618
- throw props.match.__loadPromise
619
- }
620
-
621
- invariant(
622
- false,
623
- 'Idle routeMatch status encountered during rendering! You should never see this. File an issue!',
624
- )
625
- }
626
-
627
- function SafeFragment(props: any) {
628
- return <>{props.children}</>
629
- }
630
-
631
- // This is the messiest thing ever... I'm either seriously tired (likely) or
632
- // there has to be a better way to reset error boundaries when the
633
- // router's location key changes.
634
-
635
- class CatchBoundary extends React.Component<{
636
- children: any
637
- errorComponent: any
638
- onCatch: (error: any, info: any) => void
639
- }> {
640
- state = {
641
- error: false,
642
- info: undefined,
643
- }
644
- componentDidCatch(error: any, info: any) {
645
- this.props.onCatch(error, info)
646
- console.error(error)
647
- this.setState({
648
- error,
649
- info,
650
- })
651
- }
652
- render() {
653
- return (
654
- <CatchBoundaryInner
655
- {...this.props}
656
- errorState={this.state}
657
- reset={() => this.setState({})}
658
- />
659
- )
660
- }
661
- }
662
-
663
- function CatchBoundaryInner(props: {
664
- children: any
665
- errorComponent: any
666
- errorState: { error: unknown; info: any }
667
- reset: () => void
668
- }) {
669
- const [activeErrorState, setActiveErrorState] = React.useState(
670
- props.errorState,
671
- )
672
- const router = useRouterContext()
673
- const errorComponent = props.errorComponent ?? ErrorComponent
674
- const prevKeyRef = React.useRef('' as any)
675
-
676
- React.useEffect(() => {
677
- if (activeErrorState) {
678
- if (router.state.currentLocation.key !== prevKeyRef.current) {
679
- setActiveErrorState({} as any)
680
- }
681
- }
682
-
683
- prevKeyRef.current = router.state.currentLocation.key
684
- }, [activeErrorState, router.state.currentLocation.key])
685
-
686
- React.useEffect(() => {
687
- if (props.errorState.error) {
688
- setActiveErrorState(props.errorState)
689
- }
690
- // props.reset()
691
- }, [props.errorState.error])
692
-
693
- if (props.errorState.error && activeErrorState.error) {
694
- return React.createElement(errorComponent, activeErrorState)
695
- }
696
-
697
- return props.children
698
- }
699
-
700
- export function ErrorComponent({ error }: { error: any }) {
701
- return (
702
- <div style={{ padding: '.5rem', maxWidth: '100%' }}>
703
- <strong style={{ fontSize: '1.2rem' }}>Something went wrong!</strong>
704
- <div style={{ height: '.5rem' }} />
705
- <div>
706
- <pre
707
- style={{
708
- fontSize: '.7em',
709
- border: '1px solid red',
710
- borderRadius: '.25rem',
711
- padding: '.5rem',
712
- color: 'red',
713
- overflow: 'auto',
714
- }}
715
- >
716
- {error.message ? <code>{error.message}</code> : null}
717
- </pre>
718
- </div>
719
- </div>
720
- )
721
- }
722
-
723
- export function useBlocker(
724
- message: string,
725
- condition: boolean | any = true,
726
- ): void {
727
- const router = useRouter()
728
-
729
- React.useEffect(() => {
730
- if (!condition) return
731
-
732
- let unblock = router.history.block((retry, cancel) => {
733
- if (window.confirm(message)) {
734
- unblock()
735
- retry()
736
- } else {
737
- cancel()
738
- }
739
- })
740
-
741
- return unblock
742
- })
743
- }
744
-
745
- export function Block({ message, condition, children }: PromptProps) {
746
- useBlocker(message, condition)
747
- return (children ?? null) as ReactNode
748
- }
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'