react-router 7.15.1 → 8.3.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 (364) hide show
  1. package/CHANGELOG.md +181 -2
  2. package/dist/development/dom-export.d.ts +6 -172
  3. package/dist/development/dom-export.js +12 -1007
  4. package/dist/development/index-react-server-client.d.ts +7 -4
  5. package/dist/development/index-react-server-client.js +8 -52
  6. package/dist/development/index-react-server.d.ts +1789 -1657
  7. package/dist/development/index-react-server.js +3074 -3674
  8. package/dist/development/index.d.ts +41 -1469
  9. package/dist/development/index.js +36 -2621
  10. package/dist/development/lib/actions.js +50 -0
  11. package/dist/development/lib/components.d.ts +1030 -0
  12. package/dist/development/lib/components.js +841 -0
  13. package/dist/development/lib/context.d.ts +83 -0
  14. package/dist/development/lib/context.js +41 -0
  15. package/dist/development/lib/dom/dom.d.ts +119 -0
  16. package/dist/development/lib/dom/dom.js +143 -0
  17. package/dist/development/lib/dom/lib.d.ts +2054 -0
  18. package/dist/development/lib/dom/lib.js +1272 -0
  19. package/dist/development/lib/dom/server.d.ts +138 -0
  20. package/dist/development/lib/dom/server.js +301 -0
  21. package/dist/development/lib/dom/ssr/components.d.ts +198 -0
  22. package/dist/development/lib/dom/ssr/components.js +589 -0
  23. package/dist/development/lib/dom/ssr/data.js +29 -0
  24. package/dist/development/lib/dom/ssr/entry.d.ts +60 -0
  25. package/dist/development/lib/dom/ssr/errorBoundaries.d.ts +27 -0
  26. package/dist/development/lib/dom/ssr/errorBoundaries.js +87 -0
  27. package/dist/development/lib/dom/ssr/fallback.js +33 -0
  28. package/dist/development/lib/dom/ssr/fog-of-war.d.ts +12 -0
  29. package/dist/development/lib/dom/ssr/fog-of-war.js +185 -0
  30. package/dist/development/lib/dom/ssr/hydration.d.ts +32 -0
  31. package/dist/development/lib/dom/ssr/hydration.js +29 -0
  32. package/dist/development/lib/dom/ssr/invariant.js +16 -0
  33. package/dist/development/lib/dom/ssr/links.js +170 -0
  34. package/dist/development/lib/dom/ssr/markup.js +24 -0
  35. package/dist/development/lib/dom/ssr/routeModules.d.ts +206 -0
  36. package/dist/development/lib/dom/ssr/routeModules.js +31 -0
  37. package/dist/development/lib/dom/ssr/routes-test-stub.d.ts +75 -0
  38. package/dist/development/lib/dom/ssr/routes-test-stub.js +121 -0
  39. package/dist/development/lib/dom/ssr/routes.d.ts +33 -0
  40. package/dist/development/lib/dom/ssr/routes.js +303 -0
  41. package/dist/development/lib/dom/ssr/server.d.ts +48 -0
  42. package/dist/development/lib/dom/ssr/server.js +69 -0
  43. package/dist/development/lib/dom/ssr/single-fetch.d.ts +14 -0
  44. package/dist/development/lib/dom/ssr/single-fetch.js +345 -0
  45. package/dist/development/lib/dom-export/dom-router-provider.d.ts +9 -0
  46. package/dist/development/lib/dom-export/dom-router-provider.js +22 -0
  47. package/dist/development/lib/dom-export/hydrated-router.d.ts +125 -0
  48. package/dist/development/lib/dom-export/hydrated-router.js +150 -0
  49. package/dist/development/lib/errors.js +29 -0
  50. package/dist/development/lib/hooks.d.ts +974 -0
  51. package/dist/development/lib/hooks.js +1415 -0
  52. package/dist/development/lib/href.d.ts +36 -0
  53. package/dist/development/lib/href.js +70 -0
  54. package/dist/development/lib/router/history.d.ts +264 -0
  55. package/dist/development/lib/router/history.js +378 -0
  56. package/dist/development/lib/router/instrumentation.d.ts +111 -0
  57. package/dist/development/lib/router/instrumentation.js +290 -0
  58. package/dist/development/lib/router/links.d.ts +114 -0
  59. package/dist/development/lib/router/router.d.ts +663 -0
  60. package/dist/development/lib/router/router.js +2988 -0
  61. package/dist/development/lib/router/url.js +18 -0
  62. package/dist/development/lib/router/utils.d.ts +960 -0
  63. package/dist/development/lib/router/utils.js +881 -0
  64. package/dist/development/lib/rsc/browser.d.ts +137 -0
  65. package/dist/development/lib/rsc/browser.js +612 -0
  66. package/dist/development/lib/rsc/errorBoundaries.d.ts +11 -0
  67. package/dist/development/lib/rsc/errorBoundaries.js +90 -0
  68. package/dist/development/lib/rsc/html-stream/browser.d.ts +48 -0
  69. package/dist/development/lib/rsc/html-stream/browser.js +74 -0
  70. package/dist/development/lib/rsc/html-stream/server.js +97 -0
  71. package/dist/development/lib/rsc/route-modules.js +27 -0
  72. package/dist/development/lib/rsc/server.rsc.d.ts +224 -0
  73. package/dist/development/lib/rsc/server.ssr.d.ts +152 -0
  74. package/dist/development/lib/rsc/server.ssr.js +419 -0
  75. package/dist/development/lib/server-runtime/build.d.ts +66 -0
  76. package/dist/development/lib/server-runtime/cookies.d.ts +92 -0
  77. package/dist/development/lib/server-runtime/cookies.js +153 -0
  78. package/dist/development/lib/server-runtime/crypto.js +43 -0
  79. package/dist/development/lib/server-runtime/data.js +25 -0
  80. package/dist/development/lib/server-runtime/dev.d.ts +9 -0
  81. package/dist/development/lib/server-runtime/dev.js +26 -0
  82. package/dist/development/lib/server-runtime/entry.js +20 -0
  83. package/dist/development/lib/server-runtime/errors.js +75 -0
  84. package/dist/development/lib/server-runtime/headers.js +73 -0
  85. package/dist/development/lib/server-runtime/invariant.js +19 -0
  86. package/dist/development/lib/server-runtime/mode.d.ts +12 -0
  87. package/dist/development/lib/server-runtime/mode.js +25 -0
  88. package/dist/development/lib/server-runtime/routeMatching.js +28 -0
  89. package/dist/development/lib/server-runtime/routes.d.ts +13 -0
  90. package/dist/development/lib/server-runtime/routes.js +74 -0
  91. package/dist/development/lib/server-runtime/server.d.ts +22 -0
  92. package/dist/development/lib/server-runtime/server.js +364 -0
  93. package/dist/development/lib/server-runtime/serverHandoff.js +17 -0
  94. package/dist/development/lib/server-runtime/sessions/cookieStorage.d.ts +33 -0
  95. package/dist/development/lib/server-runtime/sessions/cookieStorage.js +53 -0
  96. package/dist/development/lib/server-runtime/sessions/memoryStorage.d.ts +29 -0
  97. package/dist/development/lib/server-runtime/sessions/memoryStorage.js +58 -0
  98. package/dist/development/lib/server-runtime/sessions.d.ts +174 -0
  99. package/dist/development/lib/server-runtime/sessions.js +115 -0
  100. package/dist/development/lib/server-runtime/single-fetch.d.ts +7 -0
  101. package/dist/development/lib/server-runtime/single-fetch.js +215 -0
  102. package/dist/development/lib/server-runtime/urls.js +28 -0
  103. package/dist/development/lib/server-runtime/warnings.js +20 -0
  104. package/dist/development/lib/types/future.d.ts +9 -0
  105. package/dist/development/lib/types/internal.d.ts +26 -177
  106. package/dist/development/lib/types/internal.js +3 -2
  107. package/dist/{production/register-Bsscfj79.d.ts → development/lib/types/register.d.ts} +9 -15
  108. package/dist/development/lib/types/route-data.d.ts +113 -0
  109. package/dist/development/lib/types/route-module-annotations.d.ts +149 -0
  110. package/dist/development/lib/types/route-module.d.ts +19 -0
  111. package/dist/development/lib/types/serializes-to.d.ts +13 -0
  112. package/dist/development/lib/types/utils.d.ts +11 -0
  113. package/dist/development/vendor/turbo-stream-v2/flatten.js +159 -0
  114. package/dist/development/vendor/turbo-stream-v2/turbo-stream.js +179 -0
  115. package/dist/development/vendor/turbo-stream-v2/unflatten.js +199 -0
  116. package/dist/development/vendor/turbo-stream-v2/utils.js +39 -0
  117. package/dist/production/dom-export.d.ts +6 -172
  118. package/dist/production/dom-export.js +12 -1007
  119. package/dist/production/index-react-server-client.d.ts +7 -4
  120. package/dist/production/index-react-server-client.js +8 -52
  121. package/dist/production/index-react-server.d.ts +1789 -1657
  122. package/dist/production/index-react-server.js +3065 -3674
  123. package/dist/production/index.d.ts +41 -1469
  124. package/dist/production/index.js +36 -2621
  125. package/dist/production/lib/actions.js +50 -0
  126. package/dist/production/lib/components.d.ts +1030 -0
  127. package/dist/production/lib/components.js +841 -0
  128. package/dist/production/lib/context.d.ts +83 -0
  129. package/dist/production/lib/context.js +41 -0
  130. package/dist/production/lib/dom/dom.d.ts +119 -0
  131. package/dist/production/lib/dom/dom.js +143 -0
  132. package/dist/production/lib/dom/lib.d.ts +2054 -0
  133. package/dist/production/lib/dom/lib.js +1272 -0
  134. package/dist/production/lib/dom/server.d.ts +138 -0
  135. package/dist/production/lib/dom/server.js +301 -0
  136. package/dist/production/lib/dom/ssr/components.d.ts +198 -0
  137. package/dist/production/lib/dom/ssr/components.js +589 -0
  138. package/dist/production/lib/dom/ssr/data.js +29 -0
  139. package/dist/production/lib/dom/ssr/entry.d.ts +60 -0
  140. package/dist/production/lib/dom/ssr/errorBoundaries.d.ts +27 -0
  141. package/dist/production/lib/dom/ssr/errorBoundaries.js +87 -0
  142. package/dist/production/lib/dom/ssr/fallback.js +23 -0
  143. package/dist/production/lib/dom/ssr/fog-of-war.d.ts +12 -0
  144. package/dist/production/lib/dom/ssr/fog-of-war.js +185 -0
  145. package/dist/production/lib/dom/ssr/hydration.d.ts +32 -0
  146. package/dist/production/lib/dom/ssr/hydration.js +29 -0
  147. package/dist/production/lib/dom/ssr/invariant.js +16 -0
  148. package/dist/production/lib/dom/ssr/links.js +170 -0
  149. package/dist/production/lib/dom/ssr/markup.js +24 -0
  150. package/dist/production/lib/dom/ssr/routeModules.d.ts +206 -0
  151. package/dist/production/lib/dom/ssr/routeModules.js +31 -0
  152. package/dist/production/lib/dom/ssr/routes-test-stub.d.ts +75 -0
  153. package/dist/production/lib/dom/ssr/routes-test-stub.js +121 -0
  154. package/dist/production/lib/dom/ssr/routes.d.ts +33 -0
  155. package/dist/production/lib/dom/ssr/routes.js +303 -0
  156. package/dist/production/lib/dom/ssr/server.d.ts +48 -0
  157. package/dist/production/lib/dom/ssr/server.js +69 -0
  158. package/dist/production/lib/dom/ssr/single-fetch.d.ts +14 -0
  159. package/dist/production/lib/dom/ssr/single-fetch.js +345 -0
  160. package/dist/production/lib/dom-export/dom-router-provider.d.ts +9 -0
  161. package/dist/production/lib/dom-export/dom-router-provider.js +22 -0
  162. package/dist/production/lib/dom-export/hydrated-router.d.ts +125 -0
  163. package/dist/production/lib/dom-export/hydrated-router.js +150 -0
  164. package/dist/production/lib/errors.js +29 -0
  165. package/dist/production/lib/hooks.d.ts +974 -0
  166. package/dist/production/lib/hooks.js +1400 -0
  167. package/dist/production/lib/href.d.ts +36 -0
  168. package/dist/production/lib/href.js +70 -0
  169. package/dist/production/lib/router/history.d.ts +264 -0
  170. package/dist/production/lib/router/history.js +378 -0
  171. package/dist/production/lib/router/instrumentation.d.ts +111 -0
  172. package/dist/production/lib/router/instrumentation.js +290 -0
  173. package/dist/production/lib/router/links.d.ts +114 -0
  174. package/dist/production/lib/router/router.d.ts +663 -0
  175. package/dist/production/lib/router/router.js +2988 -0
  176. package/dist/production/lib/router/url.js +18 -0
  177. package/dist/production/lib/router/utils.d.ts +960 -0
  178. package/dist/production/lib/router/utils.js +872 -0
  179. package/dist/production/lib/rsc/browser.d.ts +137 -0
  180. package/dist/production/lib/rsc/browser.js +612 -0
  181. package/dist/production/lib/rsc/errorBoundaries.d.ts +11 -0
  182. package/dist/production/lib/rsc/errorBoundaries.js +90 -0
  183. package/dist/production/lib/rsc/html-stream/browser.d.ts +48 -0
  184. package/dist/production/lib/rsc/html-stream/browser.js +74 -0
  185. package/dist/production/lib/rsc/html-stream/server.js +97 -0
  186. package/dist/production/lib/rsc/route-modules.js +27 -0
  187. package/dist/production/lib/rsc/server.rsc.d.ts +224 -0
  188. package/dist/production/lib/rsc/server.ssr.d.ts +152 -0
  189. package/dist/production/lib/rsc/server.ssr.js +419 -0
  190. package/dist/production/lib/server-runtime/build.d.ts +66 -0
  191. package/dist/production/lib/server-runtime/cookies.d.ts +92 -0
  192. package/dist/production/lib/server-runtime/cookies.js +153 -0
  193. package/dist/production/lib/server-runtime/crypto.js +43 -0
  194. package/dist/production/lib/server-runtime/data.js +25 -0
  195. package/dist/production/lib/server-runtime/dev.d.ts +9 -0
  196. package/dist/production/lib/server-runtime/dev.js +26 -0
  197. package/dist/production/lib/server-runtime/entry.js +20 -0
  198. package/dist/production/lib/server-runtime/errors.js +75 -0
  199. package/dist/production/lib/server-runtime/headers.js +73 -0
  200. package/dist/production/lib/server-runtime/invariant.js +19 -0
  201. package/dist/production/lib/server-runtime/mode.d.ts +12 -0
  202. package/dist/production/lib/server-runtime/mode.js +25 -0
  203. package/dist/production/lib/server-runtime/routeMatching.js +28 -0
  204. package/dist/production/lib/server-runtime/routes.d.ts +13 -0
  205. package/dist/production/lib/server-runtime/routes.js +74 -0
  206. package/dist/production/lib/server-runtime/server.d.ts +22 -0
  207. package/dist/production/lib/server-runtime/server.js +364 -0
  208. package/dist/production/lib/server-runtime/serverHandoff.js +17 -0
  209. package/dist/production/lib/server-runtime/sessions/cookieStorage.d.ts +33 -0
  210. package/dist/production/lib/server-runtime/sessions/cookieStorage.js +53 -0
  211. package/dist/production/lib/server-runtime/sessions/memoryStorage.d.ts +29 -0
  212. package/dist/production/lib/server-runtime/sessions/memoryStorage.js +58 -0
  213. package/dist/production/lib/server-runtime/sessions.d.ts +174 -0
  214. package/dist/production/lib/server-runtime/sessions.js +115 -0
  215. package/dist/production/lib/server-runtime/single-fetch.d.ts +7 -0
  216. package/dist/production/lib/server-runtime/single-fetch.js +215 -0
  217. package/dist/production/lib/server-runtime/urls.js +28 -0
  218. package/dist/production/lib/server-runtime/warnings.js +20 -0
  219. package/dist/production/lib/types/future.d.ts +9 -0
  220. package/dist/production/lib/types/internal.d.ts +26 -177
  221. package/dist/production/lib/types/internal.js +3 -2
  222. package/dist/{development/register-Bsscfj79.d.ts → production/lib/types/register.d.ts} +9 -15
  223. package/dist/production/lib/types/route-data.d.ts +113 -0
  224. package/dist/production/lib/types/route-module-annotations.d.ts +149 -0
  225. package/dist/production/lib/types/route-module.d.ts +19 -0
  226. package/dist/production/lib/types/serializes-to.d.ts +13 -0
  227. package/dist/production/lib/types/utils.d.ts +11 -0
  228. package/dist/production/vendor/turbo-stream-v2/flatten.js +159 -0
  229. package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +179 -0
  230. package/dist/production/vendor/turbo-stream-v2/unflatten.js +199 -0
  231. package/dist/production/vendor/turbo-stream-v2/utils.js +39 -0
  232. package/docs/explanation/backend-for-frontend.md +50 -0
  233. package/docs/explanation/code-splitting.md +77 -0
  234. package/docs/explanation/concurrency.md +135 -0
  235. package/docs/explanation/form-vs-fetcher.md +292 -0
  236. package/docs/explanation/hot-module-replacement.md +137 -0
  237. package/docs/explanation/hydration.md +14 -0
  238. package/docs/explanation/index-query-param.md +86 -0
  239. package/docs/explanation/index.md +4 -0
  240. package/docs/explanation/lazy-route-discovery.md +78 -0
  241. package/docs/explanation/location.md +6 -0
  242. package/docs/explanation/progressive-enhancement.md +150 -0
  243. package/docs/explanation/race-conditions.md +88 -0
  244. package/docs/explanation/react-transitions.md +160 -0
  245. package/docs/explanation/route-matching.md +7 -0
  246. package/docs/explanation/server-client-execution.md +4 -0
  247. package/docs/explanation/sessions-and-cookies.md +465 -0
  248. package/docs/explanation/special-files.md +16 -0
  249. package/docs/explanation/state-management.md +524 -0
  250. package/docs/explanation/styling.md +87 -0
  251. package/docs/explanation/type-safety.md +82 -0
  252. package/docs/how-to/accessibility.md +44 -0
  253. package/docs/how-to/client-data.md +199 -0
  254. package/docs/how-to/data-strategy.md +317 -0
  255. package/docs/how-to/error-boundary.md +231 -0
  256. package/docs/how-to/error-reporting.md +142 -0
  257. package/docs/how-to/fetchers.md +307 -0
  258. package/docs/how-to/file-route-conventions.md +410 -0
  259. package/docs/how-to/file-uploads.md +217 -0
  260. package/docs/how-to/form-validation.md +120 -0
  261. package/docs/how-to/headers.md +165 -0
  262. package/docs/how-to/index.md +4 -0
  263. package/docs/how-to/instrumentation.md +661 -0
  264. package/docs/how-to/meta.md +40 -0
  265. package/docs/how-to/middleware.md +647 -0
  266. package/docs/how-to/navigation-blocking.md +233 -0
  267. package/docs/how-to/optimize-revalidation.md +12 -0
  268. package/docs/how-to/pre-rendering.md +225 -0
  269. package/docs/how-to/presets.md +103 -0
  270. package/docs/how-to/react-server-components.md +951 -0
  271. package/docs/how-to/resource-routes.md +126 -0
  272. package/docs/how-to/route-module-type-safety.md +85 -0
  273. package/docs/how-to/search-params.md +4 -0
  274. package/docs/how-to/security.md +39 -0
  275. package/docs/how-to/server-bundles.md +66 -0
  276. package/docs/how-to/spa.md +120 -0
  277. package/docs/how-to/status.md +63 -0
  278. package/docs/how-to/suspense.md +132 -0
  279. package/docs/how-to/using-handle.md +117 -0
  280. package/docs/how-to/view-transitions.md +237 -0
  281. package/docs/how-to/webhook.md +50 -0
  282. package/docs/index.md +36 -0
  283. package/docs/start/data/actions.md +138 -0
  284. package/docs/start/data/custom.md +198 -0
  285. package/docs/start/data/data-loading.md +44 -0
  286. package/docs/start/data/index.md +4 -0
  287. package/docs/start/data/installation.md +56 -0
  288. package/docs/start/data/navigating.md +12 -0
  289. package/docs/start/data/pending-ui.md +12 -0
  290. package/docs/start/data/route-object.md +268 -0
  291. package/docs/start/data/routing.md +281 -0
  292. package/docs/start/data/testing.md +8 -0
  293. package/docs/start/declarative/index.md +4 -0
  294. package/docs/start/declarative/installation.md +43 -0
  295. package/docs/start/declarative/navigating.md +133 -0
  296. package/docs/start/declarative/routing.md +237 -0
  297. package/docs/start/declarative/url-values.md +65 -0
  298. package/docs/start/framework/actions.md +174 -0
  299. package/docs/start/framework/data-loading.md +201 -0
  300. package/docs/start/framework/deploying.md +104 -0
  301. package/docs/start/framework/index.md +4 -0
  302. package/docs/start/framework/installation.md +41 -0
  303. package/docs/start/framework/navigating.md +182 -0
  304. package/docs/start/framework/pending-ui.md +142 -0
  305. package/docs/start/framework/rendering.md +59 -0
  306. package/docs/start/framework/route-module.md +527 -0
  307. package/docs/start/framework/routing.md +362 -0
  308. package/docs/start/framework/testing.md +133 -0
  309. package/docs/start/index.md +4 -0
  310. package/docs/start/modes.md +200 -0
  311. package/docs/upgrading/component-routes.md +363 -0
  312. package/docs/upgrading/future.md +111 -0
  313. package/docs/upgrading/index.md +4 -0
  314. package/docs/upgrading/router-provider.md +445 -0
  315. package/docs/upgrading/v7.md +460 -0
  316. package/package.json +44 -87
  317. package/dist/development/browser-3AnU12UI.d.mts +0 -318
  318. package/dist/development/browser-BOdXz9dK.d.ts +0 -318
  319. package/dist/development/chunk-4N6VE7H7.mjs +0 -11528
  320. package/dist/development/chunk-4YRVXM2U.js +0 -188
  321. package/dist/development/chunk-66UKHEGQ.js +0 -1362
  322. package/dist/development/chunk-D6LUOGOQ.js +0 -10229
  323. package/dist/development/chunk-RJYABSBD.mjs +0 -2585
  324. package/dist/development/context-ByvtofY2.d.mts +0 -1771
  325. package/dist/development/data-BVUf681J.d.mts +0 -1732
  326. package/dist/development/data-BqZ2x964.d.ts +0 -1732
  327. package/dist/development/dom-export.d.mts +0 -172
  328. package/dist/development/dom-export.mjs +0 -1008
  329. package/dist/development/index-react-server-client-BS5F89FR.d.ts +0 -3655
  330. package/dist/development/index-react-server-client-DY04-103.d.mts +0 -2600
  331. package/dist/development/index-react-server-client.d.mts +0 -4
  332. package/dist/development/index-react-server-client.mjs +0 -59
  333. package/dist/development/index-react-server.d.mts +0 -2703
  334. package/dist/development/index-react-server.mjs +0 -3780
  335. package/dist/development/index.d.mts +0 -1472
  336. package/dist/development/index.mjs +0 -277
  337. package/dist/development/instrumentation-cRWWLfsU.d.ts +0 -715
  338. package/dist/development/lib/types/internal.d.mts +0 -184
  339. package/dist/development/lib/types/internal.mjs +0 -10
  340. package/dist/development/register-Df8okEea.d.mts +0 -30
  341. package/dist/production/browser-3AnU12UI.d.mts +0 -318
  342. package/dist/production/browser-BOdXz9dK.d.ts +0 -318
  343. package/dist/production/chunk-6S4627ZB.mjs +0 -2585
  344. package/dist/production/chunk-HUBUW7R3.js +0 -10229
  345. package/dist/production/chunk-JAKZPQZC.mjs +0 -11528
  346. package/dist/production/chunk-PNZCCTKT.js +0 -1362
  347. package/dist/production/chunk-Y6IFXO7V.js +0 -188
  348. package/dist/production/context-ByvtofY2.d.mts +0 -1771
  349. package/dist/production/data-BVUf681J.d.mts +0 -1732
  350. package/dist/production/data-BqZ2x964.d.ts +0 -1732
  351. package/dist/production/dom-export.d.mts +0 -172
  352. package/dist/production/dom-export.mjs +0 -1008
  353. package/dist/production/index-react-server-client-BS5F89FR.d.ts +0 -3655
  354. package/dist/production/index-react-server-client-DY04-103.d.mts +0 -2600
  355. package/dist/production/index-react-server-client.d.mts +0 -4
  356. package/dist/production/index-react-server-client.mjs +0 -59
  357. package/dist/production/index-react-server.d.mts +0 -2703
  358. package/dist/production/index-react-server.mjs +0 -3780
  359. package/dist/production/index.d.mts +0 -1472
  360. package/dist/production/index.mjs +0 -277
  361. package/dist/production/instrumentation-cRWWLfsU.d.ts +0 -715
  362. package/dist/production/lib/types/internal.d.mts +0 -184
  363. package/dist/production/lib/types/internal.mjs +0 -10
  364. package/dist/production/register-Df8okEea.d.mts +0 -30
@@ -0,0 +1,1272 @@
1
+ /**
2
+ * react-router v8.3.0
3
+ *
4
+ * Copyright (c) Remix Software Inc.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE.md file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import { ABSOLUTE_URL_REGEX } from "../router/url.js";
12
+ import { createBrowserHistory, createHashHistory, createPath, invariant, warning } from "../router/history.js";
13
+ import { ErrorResponseImpl, SUPPORTED_ERROR_TYPES, defaultMapRouteProperties, joinPaths, matchPath, parseToInfo, resolveTo, stripBasename } from "../router/utils.js";
14
+ import { IDLE_FETCHER, createRouter } from "../router/router.js";
15
+ import { DataRouterContext, DataRouterStateContext, FetchersContext, NavigationContext, RouteContext, ViewTransitionContext } from "../context.js";
16
+ import { useBlocker, useHref, useLocation, useMatches, useNavigate, useNavigation, useResolvedPath, useRouteId } from "../hooks.js";
17
+ import { Router, hydrationRouteProperties } from "../components.js";
18
+ import { createSearchParams, getFormSubmissionInfo, getSearchParamsForLocation, shouldProcessLinkClick } from "./dom.js";
19
+ import { escapeHtml } from "./ssr/markup.js";
20
+ import { FrameworkContext, PrefetchPageLinks, mergeRefs, usePrefetchBehavior } from "./ssr/components.js";
21
+ import * as React$1 from "react";
22
+ //#region lib/dom/lib.tsx
23
+ const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
24
+ try {
25
+ if (isBrowser) window.__reactRouterVersion = "8.3.0";
26
+ } catch (e) {}
27
+ /**
28
+ * Create a new {@link DataRouter| data router} that manages the application
29
+ * path via [`history.pushState`](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState)
30
+ * and [`history.replaceState`](https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState).
31
+ *
32
+ * Data Routers should not be held in React state. You should create your router
33
+ * once outside of the React tree and pass it to {@link RouterProvider | `<RouterProvider>`}.
34
+ * You can use `patchRoutesOnNavigation` to add additional routes programmatically.
35
+ *
36
+ * @public
37
+ * @category Data Routers
38
+ * @mode data
39
+ * @param routes Application routes
40
+ * @param opts Options
41
+ * @param {DOMRouterOpts.basename} opts.basename n/a
42
+ * @param {DOMRouterOpts.dataStrategy} opts.dataStrategy n/a
43
+ * @param {DOMRouterOpts.future} opts.future n/a
44
+ * @param {DOMRouterOpts.getContext} opts.getContext n/a
45
+ * @param {DOMRouterOpts.hydrationData} opts.hydrationData n/a
46
+ * @param {DOMRouterOpts.instrumentations} opts.instrumentations n/a
47
+ * @param {DOMRouterOpts.patchRoutesOnNavigation} opts.patchRoutesOnNavigation n/a
48
+ * @param {DOMRouterOpts.window} opts.window n/a
49
+ * @returns An initialized {@link DataRouter| data router} to pass to {@link RouterProvider | `<RouterProvider>`}
50
+ */
51
+ function createBrowserRouter(routes, opts) {
52
+ return createRouter({
53
+ basename: opts?.basename,
54
+ getContext: opts?.getContext,
55
+ future: opts?.future,
56
+ history: createBrowserHistory({ window: opts?.window }),
57
+ hydrationData: opts?.hydrationData || parseHydrationData(),
58
+ routes,
59
+ mapRouteProperties: defaultMapRouteProperties,
60
+ hydrationRouteProperties,
61
+ dataStrategy: opts?.dataStrategy,
62
+ patchRoutesOnNavigation: opts?.patchRoutesOnNavigation,
63
+ window: opts?.window,
64
+ instrumentations: opts?.instrumentations
65
+ }).initialize();
66
+ }
67
+ /**
68
+ * Create a new {@link DataRouter| data router} that manages the application
69
+ * path via the URL [`hash`](https://developer.mozilla.org/en-US/docs/Web/API/URL/hash).
70
+ *
71
+ * Data Routers should not be held in React state. You should create your router
72
+ * once outside of the React tree and pass it to {@link RouterProvider | `<RouterProvider>`}.
73
+ * You can use `patchRoutesOnNavigation` to add additional routes programmatically.
74
+ *
75
+ * @public
76
+ * @category Data Routers
77
+ * @mode data
78
+ * @param routes Application routes
79
+ * @param opts Options
80
+ * @param {DOMRouterOpts.basename} opts.basename n/a
81
+ * @param {DOMRouterOpts.future} opts.future n/a
82
+ * @param {DOMRouterOpts.getContext} opts.getContext n/a
83
+ * @param {DOMRouterOpts.hydrationData} opts.hydrationData n/a
84
+ * @param {DOMRouterOpts.instrumentations} opts.instrumentations n/a
85
+ * @param {DOMRouterOpts.dataStrategy} opts.dataStrategy n/a
86
+ * @param {DOMRouterOpts.patchRoutesOnNavigation} opts.patchRoutesOnNavigation n/a
87
+ * @param {DOMRouterOpts.window} opts.window n/a
88
+ * @returns An initialized {@link DataRouter| data router} to pass to {@link RouterProvider | `<RouterProvider>`}
89
+ */
90
+ function createHashRouter(routes, opts) {
91
+ return createRouter({
92
+ basename: opts?.basename,
93
+ getContext: opts?.getContext,
94
+ future: opts?.future,
95
+ history: createHashHistory({ window: opts?.window }),
96
+ hydrationData: opts?.hydrationData || parseHydrationData(),
97
+ routes,
98
+ mapRouteProperties: defaultMapRouteProperties,
99
+ hydrationRouteProperties,
100
+ dataStrategy: opts?.dataStrategy,
101
+ patchRoutesOnNavigation: opts?.patchRoutesOnNavigation,
102
+ window: opts?.window,
103
+ instrumentations: opts?.instrumentations
104
+ }).initialize();
105
+ }
106
+ function parseHydrationData() {
107
+ let state = window?.__staticRouterHydrationData;
108
+ if (state && state.errors) state = {
109
+ ...state,
110
+ errors: deserializeErrors(state.errors)
111
+ };
112
+ return state;
113
+ }
114
+ function deserializeErrors(errors) {
115
+ if (!errors) return null;
116
+ let entries = Object.entries(errors);
117
+ let serialized = {};
118
+ for (let [key, val] of entries) if (val && val.__type === "RouteErrorResponse") serialized[key] = new ErrorResponseImpl(val.status, val.statusText, val.data, val.internal === true);
119
+ else if (val && val.__type === "Error") {
120
+ if (typeof val.__subType === "string" && SUPPORTED_ERROR_TYPES.includes(val.__subType)) {
121
+ let ErrorConstructor = window[val.__subType];
122
+ if (typeof ErrorConstructor === "function") try {
123
+ let error = new ErrorConstructor(val.message);
124
+ error.stack = "";
125
+ serialized[key] = error;
126
+ } catch (e) {}
127
+ }
128
+ if (serialized[key] == null) {
129
+ let error = new Error(val.message);
130
+ error.stack = "";
131
+ serialized[key] = error;
132
+ }
133
+ } else serialized[key] = val;
134
+ return serialized;
135
+ }
136
+ /**
137
+ * A declarative {@link Router | `<Router>`} using the browser [`History`](https://developer.mozilla.org/en-US/docs/Web/API/History)
138
+ * API for client-side routing.
139
+ *
140
+ * @public
141
+ * @category Declarative Routers
142
+ * @mode declarative
143
+ * @param props Props
144
+ * @param {BrowserRouterProps.basename} props.basename n/a
145
+ * @param {BrowserRouterProps.children} props.children n/a
146
+ * @param {BrowserRouterProps.useTransitions} props.useTransitions n/a
147
+ * @param {BrowserRouterProps.window} props.window n/a
148
+ * @returns A declarative {@link Router | `<Router>`} using the browser [`History`](https://developer.mozilla.org/en-US/docs/Web/API/History)
149
+ * API for client-side routing.
150
+ */
151
+ function BrowserRouter({ basename, children, useTransitions, window }) {
152
+ let historyRef = React$1.useRef(null);
153
+ if (historyRef.current == null) historyRef.current = createBrowserHistory({
154
+ window,
155
+ v5Compat: true
156
+ });
157
+ let history = historyRef.current;
158
+ let [state, setStateImpl] = React$1.useState({
159
+ action: history.action,
160
+ location: history.location
161
+ });
162
+ let setState = React$1.useCallback((newState) => {
163
+ if (useTransitions === false) setStateImpl(newState);
164
+ else React$1.startTransition(() => setStateImpl(newState));
165
+ }, [useTransitions]);
166
+ React$1.useLayoutEffect(() => history.listen(setState), [history, setState]);
167
+ return /* @__PURE__ */ React$1.createElement(Router, {
168
+ basename,
169
+ children,
170
+ location: state.location,
171
+ navigationType: state.action,
172
+ navigator: history,
173
+ useTransitions
174
+ });
175
+ }
176
+ /**
177
+ * A declarative {@link Router | `<Router>`} that stores the location in the
178
+ * [`hash`](https://developer.mozilla.org/en-US/docs/Web/API/URL/hash) portion
179
+ * of the URL so it is not sent to the server.
180
+ *
181
+ * @public
182
+ * @category Declarative Routers
183
+ * @mode declarative
184
+ * @param props Props
185
+ * @param {HashRouterProps.basename} props.basename n/a
186
+ * @param {HashRouterProps.children} props.children n/a
187
+ * @param {HashRouterProps.useTransitions} props.useTransitions n/a
188
+ * @param {HashRouterProps.window} props.window n/a
189
+ * @returns A declarative {@link Router | `<Router>`} using the URL [`hash`](https://developer.mozilla.org/en-US/docs/Web/API/URL/hash)
190
+ * for client-side routing.
191
+ */
192
+ function HashRouter({ basename, children, useTransitions, window }) {
193
+ let historyRef = React$1.useRef(null);
194
+ if (historyRef.current == null) historyRef.current = createHashHistory({
195
+ window,
196
+ v5Compat: true
197
+ });
198
+ let history = historyRef.current;
199
+ let [state, setStateImpl] = React$1.useState({
200
+ action: history.action,
201
+ location: history.location
202
+ });
203
+ let setState = React$1.useCallback((newState) => {
204
+ if (useTransitions === false) setStateImpl(newState);
205
+ else React$1.startTransition(() => setStateImpl(newState));
206
+ }, [useTransitions]);
207
+ React$1.useLayoutEffect(() => history.listen(setState), [history, setState]);
208
+ return /* @__PURE__ */ React$1.createElement(Router, {
209
+ basename,
210
+ children,
211
+ location: state.location,
212
+ navigationType: state.action,
213
+ navigator: history,
214
+ useTransitions
215
+ });
216
+ }
217
+ /**
218
+ * A declarative {@link Router | `<Router>`} that accepts a pre-instantiated
219
+ * `history` object.
220
+ * It's important to note that using your own `history` object is highly discouraged
221
+ * and may add two versions of the `history` library to your bundles unless you use
222
+ * the same version of the `history` library that React Router uses internally.
223
+ *
224
+ * @name unstable_HistoryRouter
225
+ * @public
226
+ * @category Declarative Routers
227
+ * @mode declarative
228
+ * @param props Props
229
+ * @param {HistoryRouterProps.basename} props.basename n/a
230
+ * @param {HistoryRouterProps.children} props.children n/a
231
+ * @param {HistoryRouterProps.history} props.history n/a
232
+ * @param {HistoryRouterProps.useTransitions} props.useTransitions n/a
233
+ * @returns A declarative {@link Router | `<Router>`} using the provided history
234
+ * implementation for client-side routing.
235
+ */
236
+ function HistoryRouter({ basename, children, history, useTransitions }) {
237
+ let [state, setStateImpl] = React$1.useState({
238
+ action: history.action,
239
+ location: history.location
240
+ });
241
+ let setState = React$1.useCallback((newState) => {
242
+ if (useTransitions === false) setStateImpl(newState);
243
+ else React$1.startTransition(() => setStateImpl(newState));
244
+ }, [useTransitions]);
245
+ React$1.useLayoutEffect(() => history.listen(setState), [history, setState]);
246
+ return /* @__PURE__ */ React$1.createElement(Router, {
247
+ basename,
248
+ children,
249
+ location: state.location,
250
+ navigationType: state.action,
251
+ navigator: history,
252
+ useTransitions
253
+ });
254
+ }
255
+ HistoryRouter.displayName = "unstable_HistoryRouter";
256
+ /**
257
+ * A progressively enhanced [`<a href>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a)
258
+ * wrapper to enable navigation with client-side routing.
259
+ *
260
+ * @example
261
+ * import { Link } from "react-router";
262
+ *
263
+ * <Link to="/dashboard">Dashboard</Link>;
264
+ *
265
+ * <Link
266
+ * to={{
267
+ * pathname: "/some/path",
268
+ * search: "?query=string",
269
+ * hash: "#hash",
270
+ * }}
271
+ * />;
272
+ *
273
+ * @public
274
+ * @category Components
275
+ * @param {LinkProps.discover} props.discover [modes: framework] n/a
276
+ * @param {LinkProps.prefetch} props.prefetch [modes: framework] n/a
277
+ * @param {LinkProps.preventScrollReset} props.preventScrollReset [modes: framework, data] n/a
278
+ * @param {LinkProps.relative} props.relative n/a
279
+ * @param {LinkProps.reloadDocument} props.reloadDocument n/a
280
+ * @param {LinkProps.replace} props.replace n/a
281
+ * @param {LinkProps.state} props.state n/a
282
+ * @param {LinkProps.to} props.to n/a
283
+ * @param {LinkProps.viewTransition} props.viewTransition [modes: framework, data] n/a
284
+ * @param {LinkProps.defaultShouldRevalidate} props.defaultShouldRevalidate n/a
285
+ * @param {LinkProps.mask} props.mask [modes: framework, data] n/a
286
+ */
287
+ const Link = React$1.forwardRef(function LinkWithRef({ onClick, discover = "render", prefetch = "none", relative, reloadDocument, replace, mask, state, target, to, preventScrollReset, viewTransition, defaultShouldRevalidate, ...rest }, forwardedRef) {
288
+ let { basename, navigator, useTransitions } = React$1.useContext(NavigationContext);
289
+ let isAbsolute = typeof to === "string" && ABSOLUTE_URL_REGEX.test(to);
290
+ let parsed = parseToInfo(to, basename);
291
+ to = parsed.to;
292
+ let href = useHref(to, { relative });
293
+ let location = useLocation();
294
+ let maskedHref = null;
295
+ if (mask) {
296
+ let resolved = resolveTo(mask, [], location.mask ? location.mask.pathname : "/", true);
297
+ if (basename !== "/") resolved.pathname = resolved.pathname === "/" ? basename : joinPaths([basename, resolved.pathname]);
298
+ maskedHref = navigator.createHref(resolved);
299
+ }
300
+ let [shouldPrefetch, prefetchRef, prefetchHandlers] = usePrefetchBehavior(prefetch, rest);
301
+ let internalOnClick = useLinkClickHandler(to, {
302
+ replace,
303
+ mask,
304
+ state,
305
+ target,
306
+ preventScrollReset,
307
+ relative,
308
+ viewTransition,
309
+ defaultShouldRevalidate,
310
+ useTransitions
311
+ });
312
+ function handleClick(event) {
313
+ if (onClick) onClick(event);
314
+ if (!event.defaultPrevented) internalOnClick(event);
315
+ }
316
+ let isSpaLink = !(parsed.isExternal || reloadDocument);
317
+ let link = /* @__PURE__ */ React$1.createElement("a", {
318
+ ...rest,
319
+ ...prefetchHandlers,
320
+ href: (isSpaLink ? maskedHref : void 0) || parsed.absoluteURL || href,
321
+ onClick: isSpaLink ? handleClick : onClick,
322
+ ref: mergeRefs(forwardedRef, prefetchRef),
323
+ target,
324
+ "data-discover": !isAbsolute && discover === "render" ? "true" : void 0
325
+ });
326
+ return shouldPrefetch && !isAbsolute ? /* @__PURE__ */ React$1.createElement(React$1.Fragment, null, link, /* @__PURE__ */ React$1.createElement(PrefetchPageLinks, { page: href })) : link;
327
+ });
328
+ Link.displayName = "Link";
329
+ /**
330
+ * Wraps {@link Link | `<Link>`} with additional props for styling active and
331
+ * pending states.
332
+ *
333
+ * - Automatically applies classes to the link based on its `active` and `pending`
334
+ * states, see {@link NavLinkProps.className}
335
+ * - Note that `pending` is only available with Framework and Data modes.
336
+ * - Automatically applies `aria-current="page"` to the link when the link is active.
337
+ * See [`aria-current`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current)
338
+ * on MDN.
339
+ * - States are additionally available through the className, style, and children
340
+ * render props. See {@link NavLinkRenderProps}.
341
+ *
342
+ * @example
343
+ * <NavLink to="/message">Messages</NavLink>
344
+ *
345
+ * // Using render props
346
+ * <NavLink
347
+ * to="/messages"
348
+ * className={({ isActive, isPending }) =>
349
+ * isPending ? "pending" : isActive ? "active" : ""
350
+ * }
351
+ * >
352
+ * Messages
353
+ * </NavLink>
354
+ *
355
+ * @public
356
+ * @category Components
357
+ * @param {NavLinkProps.caseSensitive} props.caseSensitive n/a
358
+ * @param {NavLinkProps.children} props.children n/a
359
+ * @param {NavLinkProps.className} props.className n/a
360
+ * @param {NavLinkProps.discover} props.discover [modes: framework] n/a
361
+ * @param {NavLinkProps.end} props.end n/a
362
+ * @param {NavLinkProps.prefetch} props.prefetch [modes: framework] n/a
363
+ * @param {NavLinkProps.preventScrollReset} props.preventScrollReset [modes: framework, data] n/a
364
+ * @param {NavLinkProps.relative} props.relative n/a
365
+ * @param {NavLinkProps.reloadDocument} props.reloadDocument n/a
366
+ * @param {NavLinkProps.replace} props.replace n/a
367
+ * @param {NavLinkProps.state} props.state n/a
368
+ * @param {NavLinkProps.style} props.style n/a
369
+ * @param {NavLinkProps.to} props.to n/a
370
+ * @param {NavLinkProps.viewTransition} props.viewTransition [modes: framework, data] n/a
371
+ */
372
+ const NavLink = React$1.forwardRef(function NavLinkWithRef({ "aria-current": ariaCurrentProp = "page", caseSensitive = false, className: classNameProp = "", end = false, style: styleProp, to, viewTransition, children, ...rest }, ref) {
373
+ let path = useResolvedPath(to, { relative: rest.relative });
374
+ let location = useLocation();
375
+ let routerState = React$1.useContext(DataRouterStateContext);
376
+ let { navigator, basename } = React$1.useContext(NavigationContext);
377
+ let isTransitioning = routerState != null && useViewTransitionState(path) && viewTransition === true;
378
+ let toPathname = navigator.encodeLocation ? navigator.encodeLocation(path).pathname : path.pathname;
379
+ let locationPathname = location.pathname;
380
+ let nextLocationPathname = routerState && routerState.navigation && routerState.navigation.location ? routerState.navigation.location.pathname : null;
381
+ if (!caseSensitive) {
382
+ locationPathname = locationPathname.toLowerCase();
383
+ nextLocationPathname = nextLocationPathname ? nextLocationPathname.toLowerCase() : null;
384
+ toPathname = toPathname.toLowerCase();
385
+ }
386
+ if (nextLocationPathname && basename) nextLocationPathname = stripBasename(nextLocationPathname, basename) || nextLocationPathname;
387
+ const endSlashPosition = toPathname !== "/" && toPathname.endsWith("/") ? toPathname.length - 1 : toPathname.length;
388
+ let isActive = locationPathname === toPathname || !end && locationPathname.startsWith(toPathname) && locationPathname.charAt(endSlashPosition) === "/";
389
+ let isPending = nextLocationPathname != null && (nextLocationPathname === toPathname || !end && nextLocationPathname.startsWith(toPathname) && nextLocationPathname.charAt(endSlashPosition) === "/");
390
+ let renderProps = {
391
+ isActive,
392
+ isPending,
393
+ isTransitioning
394
+ };
395
+ let ariaCurrent = isActive ? ariaCurrentProp : void 0;
396
+ let className;
397
+ if (typeof classNameProp === "function") className = classNameProp(renderProps);
398
+ else className = [
399
+ classNameProp,
400
+ isActive ? "active" : null,
401
+ isPending ? "pending" : null,
402
+ isTransitioning ? "transitioning" : null
403
+ ].filter(Boolean).join(" ");
404
+ let style = typeof styleProp === "function" ? styleProp(renderProps) : styleProp;
405
+ return /* @__PURE__ */ React$1.createElement(Link, {
406
+ ...rest,
407
+ "aria-current": ariaCurrent,
408
+ className,
409
+ ref,
410
+ style,
411
+ to,
412
+ viewTransition
413
+ }, typeof children === "function" ? children(renderProps) : children);
414
+ });
415
+ NavLink.displayName = "NavLink";
416
+ /**
417
+ * A progressively enhanced HTML [`<form>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form)
418
+ * that submits data to actions via [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/fetch),
419
+ * activating pending states in {@link useNavigation} which enables advanced
420
+ * user interfaces beyond a basic HTML [`<form>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form).
421
+ * After a form's `action` completes, all data on the page is automatically
422
+ * revalidated to keep the UI in sync with the data.
423
+ *
424
+ * Because it uses the HTML form API, server rendered pages are interactive at a
425
+ * basic level before JavaScript loads. Instead of React Router managing the
426
+ * submission, the browser manages the submission as well as the pending states
427
+ * (like the spinning favicon). After JavaScript loads, React Router takes over
428
+ * enabling web application user experiences.
429
+ *
430
+ * `Form` is most useful for submissions that should also change the URL or
431
+ * otherwise add an entry to the browser history stack. For forms that shouldn't
432
+ * manipulate the browser [`History`](https://developer.mozilla.org/en-US/docs/Web/API/History)
433
+ * stack, use {@link FetcherWithComponents.Form | `<fetcher.Form>`}.
434
+ *
435
+ * @example
436
+ * import { Form } from "react-router";
437
+ *
438
+ * function NewEvent() {
439
+ * return (
440
+ * <Form action="/events" method="post">
441
+ * <input name="title" type="text" />
442
+ * <input name="description" type="text" />
443
+ * </Form>
444
+ * );
445
+ * }
446
+ *
447
+ * @public
448
+ * @category Components
449
+ * @mode framework
450
+ * @mode data
451
+ * @param {FormProps.action} action n/a
452
+ * @param {FormProps.discover} discover n/a
453
+ * @param {FormProps.encType} encType n/a
454
+ * @param {FormProps.fetcherKey} fetcherKey n/a
455
+ * @param {FormProps.method} method n/a
456
+ * @param {FormProps.navigate} navigate n/a
457
+ * @param {FormProps.preventScrollReset} preventScrollReset n/a
458
+ * @param {FormProps.relative} relative n/a
459
+ * @param {FormProps.reloadDocument} reloadDocument n/a
460
+ * @param {FormProps.replace} replace n/a
461
+ * @param {FormProps.state} state n/a
462
+ * @param {FormProps.viewTransition} viewTransition n/a
463
+ * @param {FormProps.defaultShouldRevalidate} defaultShouldRevalidate n/a
464
+ * @returns A progressively enhanced [`<form>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) component
465
+ */
466
+ const Form = React$1.forwardRef(({ discover = "render", fetcherKey, navigate, reloadDocument, replace, state, method = "get", action, onSubmit, relative, preventScrollReset, viewTransition, defaultShouldRevalidate, ...props }, forwardedRef) => {
467
+ let { useTransitions } = React$1.useContext(NavigationContext);
468
+ let submit = useSubmit();
469
+ let formAction = useFormAction(action, { relative });
470
+ let formMethod = method.toLowerCase() === "get" ? "get" : "post";
471
+ let isAbsolute = typeof action === "string" && ABSOLUTE_URL_REGEX.test(action);
472
+ let submitHandler = (event) => {
473
+ onSubmit && onSubmit(event);
474
+ if (event.defaultPrevented) return;
475
+ event.preventDefault();
476
+ let submitter = event.nativeEvent.submitter;
477
+ let submitMethod = submitter?.getAttribute("formmethod") || method;
478
+ let doSubmit = () => submit(submitter || event.currentTarget, {
479
+ fetcherKey,
480
+ method: submitMethod,
481
+ navigate,
482
+ replace,
483
+ state,
484
+ relative,
485
+ preventScrollReset,
486
+ viewTransition,
487
+ defaultShouldRevalidate
488
+ });
489
+ if (useTransitions && navigate !== false) React$1.startTransition(() => doSubmit());
490
+ else doSubmit();
491
+ };
492
+ return /* @__PURE__ */ React$1.createElement("form", {
493
+ ref: forwardedRef,
494
+ method: formMethod,
495
+ action: formAction,
496
+ onSubmit: reloadDocument ? onSubmit : submitHandler,
497
+ ...props,
498
+ "data-discover": !isAbsolute && discover === "render" ? "true" : void 0
499
+ });
500
+ });
501
+ Form.displayName = "Form";
502
+ /**
503
+ * Emulates the browser's scroll restoration on location changes. Apps should only render one of these, right before the {@link Scripts} component.
504
+ *
505
+ * ```tsx
506
+ * import { ScrollRestoration } from "react-router";
507
+ *
508
+ * export default function Root() {
509
+ * return (
510
+ * <html>
511
+ * <body>
512
+ * <ScrollRestoration />
513
+ * <Scripts />
514
+ * </body>
515
+ * </html>
516
+ * );
517
+ * }
518
+ * ```
519
+ *
520
+ * This component renders an inline `<script>` to prevent scroll flashing. The
521
+ * `nonce` prop will be passed down to the script tag to allow CSP nonce usage.
522
+ * If not provided in Framework Mode, it will default to any
523
+ * {@link ServerRouter | `<ServerRouter nonce>`} prop.
524
+ *
525
+ * ```tsx
526
+ * <ScrollRestoration nonce={cspNonce} />
527
+ * ```
528
+ *
529
+ * @public
530
+ * @category Components
531
+ * @mode framework
532
+ * @mode data
533
+ * @param props Props
534
+ * @param {ScrollRestorationProps.getKey} props.getKey n/a
535
+ * @param {ScriptsProps.nonce} props.nonce n/a
536
+ * @param {ScrollRestorationProps.storageKey} props.storageKey n/a
537
+ * @returns A [`<script>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)
538
+ * tag that restores scroll positions on navigation.
539
+ */
540
+ function ScrollRestoration({ getKey, storageKey, ...props }) {
541
+ let remixContext = React$1.useContext(FrameworkContext);
542
+ let { basename } = React$1.useContext(NavigationContext);
543
+ let location = useLocation();
544
+ let matches = useMatches();
545
+ useScrollRestoration({
546
+ getKey,
547
+ storageKey
548
+ });
549
+ let ssrKey = React$1.useMemo(() => {
550
+ if (!remixContext || !getKey) return null;
551
+ let userKey = getScrollRestorationKey(location, matches, basename, getKey);
552
+ return userKey !== location.key ? userKey : null;
553
+ }, []);
554
+ if (!remixContext || remixContext.isSpaMode) return null;
555
+ let restoreScroll = ((storageKey, restoreKey) => {
556
+ if (!window.history.state || !window.history.state.key) {
557
+ let key = Math.random().toString(32).slice(2);
558
+ window.history.replaceState({ key }, "");
559
+ }
560
+ try {
561
+ let storedY = JSON.parse(sessionStorage.getItem(storageKey) || "{}")[restoreKey || window.history.state.key];
562
+ if (typeof storedY === "number") window.scrollTo(0, storedY);
563
+ } catch (error) {
564
+ console.error(error);
565
+ sessionStorage.removeItem(storageKey);
566
+ }
567
+ }).toString();
568
+ if (props.nonce == null && remixContext?.nonce) props.nonce = remixContext.nonce;
569
+ return /* @__PURE__ */ React$1.createElement("script", {
570
+ ...props,
571
+ suppressHydrationWarning: true,
572
+ dangerouslySetInnerHTML: { __html: `(${restoreScroll})(${escapeHtml(JSON.stringify(storageKey || SCROLL_RESTORATION_STORAGE_KEY))}, ${escapeHtml(JSON.stringify(ssrKey))})` }
573
+ });
574
+ }
575
+ ScrollRestoration.displayName = "ScrollRestoration";
576
+ function getDataRouterConsoleError(hookName) {
577
+ return `${hookName} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`;
578
+ }
579
+ function useDataRouterContext(hookName) {
580
+ let ctx = React$1.useContext(DataRouterContext);
581
+ invariant(ctx, getDataRouterConsoleError(hookName));
582
+ return ctx;
583
+ }
584
+ function useDataRouterState(hookName) {
585
+ let state = React$1.useContext(DataRouterStateContext);
586
+ invariant(state, getDataRouterConsoleError(hookName));
587
+ return state;
588
+ }
589
+ /**
590
+ * Handles the click behavior for router {@link Link | `<Link>`} components.This
591
+ * is useful if you need to create custom {@link Link | `<Link>`} components with
592
+ * the same click behavior we use in our exported {@link Link | `<Link>`}.
593
+ *
594
+ * @public
595
+ * @category Hooks
596
+ * @param to The URL to navigate to, can be a string or a partial {@link Path}.
597
+ * @param options Options
598
+ * @param options.preventScrollReset Whether to prevent the scroll position from
599
+ * being reset to the top of the viewport on completion of the navigation when
600
+ * using the {@link ScrollRestoration} component. Defaults to `false`.
601
+ * @param options.relative The {@link RelativeRoutingType | relative routing type}
602
+ * to use for the link. Defaults to `"route"`.
603
+ * @param options.replace Whether to replace the current [`History`](https://developer.mozilla.org/en-US/docs/Web/API/History)
604
+ * entry instead of pushing a new one. Defaults to `false`.
605
+ * @param options.state The state to add to the [`History`](https://developer.mozilla.org/en-US/docs/Web/API/History)
606
+ * entry for this navigation. Defaults to `undefined`.
607
+ * @param options.target The target attribute for the link. Defaults to `undefined`.
608
+ * @param options.viewTransition Enables a [View Transition](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API)
609
+ * for this navigation. To apply specific styles during the transition, see
610
+ * {@link useViewTransitionState}. Defaults to `false`.
611
+ * @param options.defaultShouldRevalidate Specify the default revalidation
612
+ * behavior for the navigation. When not specified, loaders revalidate
613
+ * according to the router's standard revalidation behavior.
614
+ * @param options.mask Masked location to display in the browser instead
615
+ * of the router location. Defaults to `undefined`.
616
+ * @param options.useTransitions Wraps the navigation in
617
+ * [`React.startTransition`](https://react.dev/reference/react/startTransition)
618
+ * for concurrent rendering. Defaults to `false`.
619
+ * @returns A click handler function that can be used in a custom {@link Link} component.
620
+ */
621
+ function useLinkClickHandler(to, { target, replace: replaceProp, mask, state, preventScrollReset, relative, viewTransition, defaultShouldRevalidate, useTransitions } = {}) {
622
+ let navigate = useNavigate();
623
+ let location = useLocation();
624
+ let path = useResolvedPath(to, { relative });
625
+ return React$1.useCallback((event) => {
626
+ if (shouldProcessLinkClick(event, target)) {
627
+ event.preventDefault();
628
+ let replace = replaceProp !== void 0 ? replaceProp : createPath(location) === createPath(path);
629
+ let doNavigate = () => navigate(to, {
630
+ replace,
631
+ mask,
632
+ state,
633
+ preventScrollReset,
634
+ relative,
635
+ viewTransition,
636
+ defaultShouldRevalidate
637
+ });
638
+ if (useTransitions) React$1.startTransition(() => doNavigate());
639
+ else doNavigate();
640
+ }
641
+ }, [
642
+ location,
643
+ navigate,
644
+ path,
645
+ replaceProp,
646
+ mask,
647
+ state,
648
+ target,
649
+ to,
650
+ preventScrollReset,
651
+ relative,
652
+ viewTransition,
653
+ defaultShouldRevalidate,
654
+ useTransitions
655
+ ]);
656
+ }
657
+ /**
658
+ * Returns a tuple of the current URL's [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)
659
+ * and a function to update them. Setting the search params causes a navigation.
660
+ *
661
+ * ```tsx
662
+ * import { useSearchParams } from "react-router";
663
+ *
664
+ * export function SomeComponent() {
665
+ * const [searchParams, setSearchParams] = useSearchParams();
666
+ * // ...
667
+ * }
668
+ * ```
669
+ *
670
+ * ### `setSearchParams` function
671
+ *
672
+ * The second element of the tuple is a function that can be used to update the
673
+ * search params. It accepts the same types as `defaultInit` and will cause a
674
+ * navigation to the new URL.
675
+ *
676
+ * ```tsx
677
+ * let [searchParams, setSearchParams] = useSearchParams();
678
+ *
679
+ * // a search param string
680
+ * setSearchParams("?tab=1");
681
+ *
682
+ * // a shorthand object
683
+ * setSearchParams({ tab: "1" });
684
+ *
685
+ * // object keys can be arrays for multiple values on the key
686
+ * setSearchParams({ brand: ["nike", "reebok"] });
687
+ *
688
+ * // an array of tuples
689
+ * setSearchParams([["tab", "1"]]);
690
+ *
691
+ * // a `URLSearchParams` object
692
+ * setSearchParams(new URLSearchParams("?tab=1"));
693
+ * ```
694
+ *
695
+ * It also supports a function callback like React's
696
+ * [`setState`](https://react.dev/reference/react/useState#setstate):
697
+ *
698
+ * ```tsx
699
+ * setSearchParams((searchParams) => {
700
+ * searchParams.set("tab", "2");
701
+ * return searchParams;
702
+ * });
703
+ * ```
704
+ *
705
+ * <docs-warning>The function callback version of `setSearchParams` does not support
706
+ * the [queueing](https://react.dev/reference/react/useState#setstate-parameters)
707
+ * logic that React's `setState` implements. Multiple calls to `setSearchParams`
708
+ * in the same tick will not build on the prior value. If you need this behavior,
709
+ * you can use `setState` manually.</docs-warning>
710
+ *
711
+ * ### Notes
712
+ *
713
+ * Note that `searchParams` is a stable reference, so you can reliably use it
714
+ * as a dependency in React's [`useEffect`](https://react.dev/reference/react/useEffect)
715
+ * hooks.
716
+ *
717
+ * ```tsx
718
+ * useEffect(() => {
719
+ * console.log(searchParams.get("tab"));
720
+ * }, [searchParams]);
721
+ * ```
722
+ *
723
+ * However, this also means it's mutable. If you change the object without
724
+ * calling `setSearchParams`, its values will change between renders if some
725
+ * other state causes the component to re-render and URL will not reflect the
726
+ * values.
727
+ *
728
+ * @public
729
+ * @category Hooks
730
+ * @param defaultInit
731
+ * You can initialize the search params with a default value, though it **will
732
+ * not** change the URL on the first render.
733
+ *
734
+ * ```tsx
735
+ * // a search param string
736
+ * useSearchParams("?tab=1");
737
+ *
738
+ * // a shorthand object
739
+ * useSearchParams({ tab: "1" });
740
+ *
741
+ * // object keys can be arrays for multiple values on the key
742
+ * useSearchParams({ brand: ["nike", "reebok"] });
743
+ *
744
+ * // an array of tuples
745
+ * useSearchParams([["tab", "1"]]);
746
+ *
747
+ * // a `URLSearchParams` object
748
+ * useSearchParams(new URLSearchParams("?tab=1"));
749
+ * ```
750
+ * @returns A tuple of the current [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)
751
+ * and a function to update them.
752
+ */
753
+ function useSearchParams(defaultInit) {
754
+ warning(typeof URLSearchParams !== "undefined", "You cannot use the `useSearchParams` hook in a browser that does not support the URLSearchParams API. If you need to support Internet Explorer 11, we recommend you load a polyfill such as https://github.com/ungap/url-search-params.");
755
+ let defaultSearchParamsRef = React$1.useRef(createSearchParams(defaultInit));
756
+ let hasSetSearchParamsRef = React$1.useRef(false);
757
+ let location = useLocation();
758
+ let searchParams = React$1.useMemo(() => getSearchParamsForLocation(location.search, hasSetSearchParamsRef.current ? null : defaultSearchParamsRef.current), [location.search]);
759
+ let navigate = useNavigate();
760
+ return [searchParams, React$1.useCallback((nextInit, navigateOptions) => {
761
+ const newSearchParams = createSearchParams(typeof nextInit === "function" ? nextInit(new URLSearchParams(searchParams)) : nextInit);
762
+ hasSetSearchParamsRef.current = true;
763
+ navigate("?" + newSearchParams, navigateOptions);
764
+ }, [navigate, searchParams])];
765
+ }
766
+ let fetcherId = 0;
767
+ let getUniqueFetcherId = () => `__${String(++fetcherId)}__`;
768
+ /**
769
+ * The imperative version of {@link Form | `<Form>`} that lets you submit a form
770
+ * from code instead of a user interaction.
771
+ *
772
+ * @example
773
+ * import { useSubmit } from "react-router";
774
+ *
775
+ * function SomeComponent() {
776
+ * const submit = useSubmit();
777
+ * return (
778
+ * <Form onChange={(event) => submit(event.currentTarget)} />
779
+ * );
780
+ * }
781
+ *
782
+ * @public
783
+ * @category Hooks
784
+ * @mode framework
785
+ * @mode data
786
+ * @returns A function that can be called to submit a {@link Form} imperatively.
787
+ */
788
+ function useSubmit() {
789
+ let { router } = useDataRouterContext("useSubmit");
790
+ let { basename } = React$1.useContext(NavigationContext);
791
+ let currentRouteId = useRouteId();
792
+ let routerFetch = router.fetch;
793
+ let routerNavigate = router.navigate;
794
+ return React$1.useCallback(async (target, options = {}) => {
795
+ let { action, method, encType, formData, body } = getFormSubmissionInfo(target, basename);
796
+ if (options.navigate === false) await routerFetch(options.fetcherKey || getUniqueFetcherId(), currentRouteId, options.action || action, {
797
+ defaultShouldRevalidate: options.defaultShouldRevalidate,
798
+ preventScrollReset: options.preventScrollReset,
799
+ formData,
800
+ body,
801
+ formMethod: options.method || method,
802
+ formEncType: options.encType || encType,
803
+ flushSync: options.flushSync
804
+ });
805
+ else await routerNavigate(options.action || action, {
806
+ defaultShouldRevalidate: options.defaultShouldRevalidate,
807
+ preventScrollReset: options.preventScrollReset,
808
+ formData,
809
+ body,
810
+ formMethod: options.method || method,
811
+ formEncType: options.encType || encType,
812
+ replace: options.replace,
813
+ state: options.state,
814
+ fromRouteId: currentRouteId,
815
+ flushSync: options.flushSync,
816
+ viewTransition: options.viewTransition
817
+ });
818
+ }, [
819
+ routerFetch,
820
+ routerNavigate,
821
+ basename,
822
+ currentRouteId
823
+ ]);
824
+ }
825
+ /**
826
+ * Resolves the URL to the closest route in the component hierarchy instead of
827
+ * the current URL of the app.
828
+ *
829
+ * This is used internally by {@link Form} to resolve the `action` to the closest
830
+ * route, but can be used generically as well.
831
+ *
832
+ * ```ts
833
+ * import { useFormAction } from "react-router";
834
+ *
835
+ * function SomeComponent() {
836
+ * // closest route URL
837
+ * let action = useFormAction();
838
+ *
839
+ * // closest route URL + "destroy"
840
+ * let destroyAction = useFormAction("destroy");
841
+ * }
842
+ * ```
843
+ *
844
+ * <docs-info>This hook adds a `basename` if your app specifies one, so that it
845
+ * can be used with raw `<form>` elements in a progressively enhanced way. If
846
+ * you are using this to provide an `action` to `<Form>` or `fetcher.submit`, you
847
+ * will need to remove the `basename` since both of those will prepend it
848
+ * internally.</docs-info>
849
+ *
850
+ *
851
+ * @public
852
+ * @category Hooks
853
+ * @mode framework
854
+ * @mode data
855
+ * @param action The action to append to the closest route URL. Defaults to the
856
+ * closest route URL.
857
+ * @param options Options
858
+ * @param options.relative The relative routing type to use when resolving the
859
+ * action. Defaults to `"route"`.
860
+ * @returns The resolved action URL.
861
+ */
862
+ function useFormAction(action, { relative } = {}) {
863
+ let { basename } = React$1.useContext(NavigationContext);
864
+ let routeContext = React$1.useContext(RouteContext);
865
+ invariant(routeContext, "useFormAction must be used inside a RouteContext");
866
+ let [match] = routeContext.matches.slice(-1);
867
+ let path = { ...useResolvedPath(action ? action : ".", { relative }) };
868
+ let location = useLocation();
869
+ if (action == null) {
870
+ path.search = location.search;
871
+ let params = new URLSearchParams(path.search);
872
+ let indexValues = params.getAll("index");
873
+ if (indexValues.some((v) => v === "")) {
874
+ params.delete("index");
875
+ indexValues.filter((v) => v).forEach((v) => params.append("index", v));
876
+ let qs = params.toString();
877
+ path.search = qs ? `?${qs}` : "";
878
+ }
879
+ }
880
+ if ((!action || action === ".") && match.route.index) path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index";
881
+ if (basename !== "/") path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]);
882
+ return createPath(path);
883
+ }
884
+ /**
885
+ * Useful for creating complex, dynamic user interfaces that require multiple,
886
+ * concurrent data interactions without causing a navigation.
887
+ *
888
+ * Fetchers track their own, independent state and can be used to load data, submit
889
+ * forms, and generally interact with [`action`](../../start/framework/route-module#action)
890
+ * and [`loader`](../../start/framework/route-module#loader) functions.
891
+ *
892
+ * @example
893
+ * import { useFetcher } from "react-router"
894
+ *
895
+ * function SomeComponent() {
896
+ * let fetcher = useFetcher()
897
+ *
898
+ * // states are available on the fetcher
899
+ * fetcher.state // "idle" | "loading" | "submitting"
900
+ * fetcher.data // the data returned from the action or loader
901
+ *
902
+ * // render a form
903
+ * <fetcher.Form method="post" />
904
+ *
905
+ * // load data
906
+ * fetcher.load("/some/route")
907
+ *
908
+ * // submit data
909
+ * fetcher.submit(someFormRef, { method: "post" })
910
+ * fetcher.submit(someData, {
911
+ * method: "post",
912
+ * encType: "application/json"
913
+ * })
914
+ *
915
+ * // reset fetcher
916
+ * fetcher.reset()
917
+ * }
918
+ *
919
+ * @public
920
+ * @category Hooks
921
+ * @mode framework
922
+ * @mode data
923
+ * @param options Options
924
+ * @param options.key A unique key to identify the fetcher.
925
+ *
926
+ *
927
+ * By default, `useFetcher` generates a unique fetcher scoped to that component.
928
+ * If you want to identify a fetcher with your own key such that you can access
929
+ * it from elsewhere in your app, you can do that with the `key` option:
930
+ *
931
+ * ```tsx
932
+ * function SomeComp() {
933
+ * let fetcher = useFetcher({ key: "my-key" })
934
+ * // ...
935
+ * }
936
+ *
937
+ * // Somewhere else
938
+ * function AnotherComp() {
939
+ * // this will be the same fetcher, sharing the state across the app
940
+ * let fetcher = useFetcher({ key: "my-key" });
941
+ * // ...
942
+ * }
943
+ * ```
944
+ * @returns A {@link FetcherWithComponents} object that contains the fetcher's state, data, and components for submitting forms and loading data.
945
+ */
946
+ function useFetcher({ key } = {}) {
947
+ let { router } = useDataRouterContext("useFetcher");
948
+ let state = useDataRouterState("useFetcher");
949
+ let fetcherData = React$1.useContext(FetchersContext);
950
+ let route = React$1.useContext(RouteContext);
951
+ let routeId = route.matches[route.matches.length - 1]?.route.id;
952
+ invariant(fetcherData, `useFetcher must be used inside a FetchersContext`);
953
+ invariant(route, `useFetcher must be used inside a RouteContext`);
954
+ invariant(routeId != null, `useFetcher can only be used on routes that contain a unique "id"`);
955
+ let defaultKey = React$1.useId();
956
+ let [fetcherKey, setFetcherKey] = React$1.useState(key || defaultKey);
957
+ if (key && key !== fetcherKey) setFetcherKey(key);
958
+ let { deleteFetcher, getFetcher, resetFetcher, fetch: routerFetch } = router;
959
+ React$1.useEffect(() => {
960
+ getFetcher(fetcherKey);
961
+ return () => deleteFetcher(fetcherKey);
962
+ }, [
963
+ deleteFetcher,
964
+ getFetcher,
965
+ fetcherKey
966
+ ]);
967
+ let load = React$1.useCallback(async (href, opts) => {
968
+ invariant(routeId, "No routeId available for fetcher.load()");
969
+ await routerFetch(fetcherKey, routeId, href, opts);
970
+ }, [
971
+ fetcherKey,
972
+ routeId,
973
+ routerFetch
974
+ ]);
975
+ let submitImpl = useSubmit();
976
+ let submit = React$1.useCallback(async (target, opts) => {
977
+ await submitImpl(target, {
978
+ ...opts,
979
+ navigate: false,
980
+ fetcherKey
981
+ });
982
+ }, [fetcherKey, submitImpl]);
983
+ let reset = React$1.useCallback((opts) => resetFetcher(fetcherKey, opts), [resetFetcher, fetcherKey]);
984
+ let FetcherForm = React$1.useMemo(() => {
985
+ let FetcherForm = React$1.forwardRef((props, ref) => {
986
+ return /* @__PURE__ */ React$1.createElement(Form, {
987
+ ...props,
988
+ navigate: false,
989
+ fetcherKey,
990
+ ref
991
+ });
992
+ });
993
+ FetcherForm.displayName = "fetcher.Form";
994
+ return FetcherForm;
995
+ }, [fetcherKey]);
996
+ let fetcher = state.fetchers.get(fetcherKey) || IDLE_FETCHER;
997
+ let data = fetcherData.get(fetcherKey);
998
+ return React$1.useMemo(() => ({
999
+ Form: FetcherForm,
1000
+ submit,
1001
+ load,
1002
+ reset,
1003
+ ...fetcher,
1004
+ data
1005
+ }), [
1006
+ FetcherForm,
1007
+ submit,
1008
+ load,
1009
+ reset,
1010
+ fetcher,
1011
+ data
1012
+ ]);
1013
+ }
1014
+ /**
1015
+ * Returns an array of all in-flight {@link Fetcher}s. This is useful for components
1016
+ * throughout the app that didn't create the fetchers but want to use their submissions
1017
+ * to participate in optimistic UI.
1018
+ *
1019
+ * @example
1020
+ * import { useFetchers } from "react-router";
1021
+ *
1022
+ * function SomeComponent() {
1023
+ * const fetchers = useFetchers();
1024
+ * fetchers[0].formData; // FormData
1025
+ * fetchers[0].state; // etc.
1026
+ * // ...
1027
+ * }
1028
+ *
1029
+ * @public
1030
+ * @category Hooks
1031
+ * @mode framework
1032
+ * @mode data
1033
+ * @returns An array of all in-flight {@link Fetcher}s, each with a unique `key`
1034
+ * property.
1035
+ */
1036
+ function useFetchers() {
1037
+ let state = useDataRouterState("useFetchers");
1038
+ return React$1.useMemo(() => Array.from(state.fetchers.entries()).map(([key, fetcher]) => ({
1039
+ ...fetcher,
1040
+ key
1041
+ })), [state.fetchers]);
1042
+ }
1043
+ const SCROLL_RESTORATION_STORAGE_KEY = "react-router-scroll-positions";
1044
+ let savedScrollPositions = {};
1045
+ function getScrollRestorationKey(location, matches, basename, getKey) {
1046
+ let key = null;
1047
+ if (getKey) if (basename !== "/") key = getKey({
1048
+ ...location,
1049
+ pathname: stripBasename(location.pathname, basename) || location.pathname
1050
+ }, matches);
1051
+ else key = getKey(location, matches);
1052
+ if (key == null) key = location.key;
1053
+ return key;
1054
+ }
1055
+ /**
1056
+ * When rendered inside a {@link RouterProvider}, will restore scroll positions
1057
+ * on navigations
1058
+ *
1059
+ * <!--
1060
+ * Not marked `@public` because we only export as UNSAFE_ and therefore we don't
1061
+ * maintain an .md file for this hook
1062
+ * -->
1063
+ *
1064
+ * @name UNSAFE_useScrollRestoration
1065
+ * @category Hooks
1066
+ * @mode framework
1067
+ * @mode data
1068
+ * @param options Options
1069
+ * @param options.getKey A function that returns a key to use for scroll restoration.
1070
+ * This is useful for custom scroll restoration logic, such as using only the pathname
1071
+ * so that subsequent navigations to prior paths will restore the scroll. Defaults
1072
+ * to `location.key`.
1073
+ * @param options.storageKey The key to use for storing scroll positions in
1074
+ * `sessionStorage`. Defaults to `"react-router-scroll-positions"`.
1075
+ * @returns {void}
1076
+ */
1077
+ function useScrollRestoration({ getKey, storageKey } = {}) {
1078
+ let { router } = useDataRouterContext("useScrollRestoration");
1079
+ let { restoreScrollPosition, preventScrollReset } = useDataRouterState("useScrollRestoration");
1080
+ let { basename } = React$1.useContext(NavigationContext);
1081
+ let location = useLocation();
1082
+ let matches = useMatches();
1083
+ let navigation = useNavigation();
1084
+ React$1.useEffect(() => {
1085
+ window.history.scrollRestoration = "manual";
1086
+ return () => {
1087
+ window.history.scrollRestoration = "auto";
1088
+ };
1089
+ }, []);
1090
+ usePageHide(React$1.useCallback(() => {
1091
+ if (navigation.state === "idle") {
1092
+ let key = getScrollRestorationKey(location, matches, basename, getKey);
1093
+ savedScrollPositions[key] = window.scrollY;
1094
+ }
1095
+ try {
1096
+ sessionStorage.setItem(storageKey || SCROLL_RESTORATION_STORAGE_KEY, JSON.stringify(savedScrollPositions));
1097
+ } catch (error) {
1098
+ warning(false, `Failed to save scroll positions in sessionStorage, <ScrollRestoration /> will not work properly (${error}).`);
1099
+ }
1100
+ window.history.scrollRestoration = "auto";
1101
+ }, [
1102
+ navigation.state,
1103
+ getKey,
1104
+ basename,
1105
+ location,
1106
+ matches,
1107
+ storageKey
1108
+ ]));
1109
+ if (typeof document !== "undefined") {
1110
+ React$1.useLayoutEffect(() => {
1111
+ try {
1112
+ let sessionPositions = sessionStorage.getItem(storageKey || SCROLL_RESTORATION_STORAGE_KEY);
1113
+ if (sessionPositions) savedScrollPositions = JSON.parse(sessionPositions);
1114
+ } catch (e) {}
1115
+ }, [storageKey]);
1116
+ React$1.useLayoutEffect(() => {
1117
+ let disableScrollRestoration = router?.enableScrollRestoration(savedScrollPositions, () => window.scrollY, getKey ? (location, matches) => getScrollRestorationKey(location, matches, basename, getKey) : void 0);
1118
+ return () => disableScrollRestoration && disableScrollRestoration();
1119
+ }, [
1120
+ router,
1121
+ basename,
1122
+ getKey
1123
+ ]);
1124
+ React$1.useLayoutEffect(() => {
1125
+ if (restoreScrollPosition === false) return;
1126
+ if (typeof restoreScrollPosition === "number") {
1127
+ window.scrollTo(0, restoreScrollPosition);
1128
+ return;
1129
+ }
1130
+ try {
1131
+ if (location.hash) {
1132
+ let el = document.getElementById(decodeURIComponent(location.hash.slice(1)));
1133
+ if (el) {
1134
+ el.scrollIntoView();
1135
+ return;
1136
+ }
1137
+ }
1138
+ } catch {
1139
+ warning(false, `"${location.hash.slice(1)}" is not a decodable element ID. The view will not scroll to it.`);
1140
+ }
1141
+ if (preventScrollReset === true) return;
1142
+ window.scrollTo(0, 0);
1143
+ }, [
1144
+ location,
1145
+ restoreScrollPosition,
1146
+ preventScrollReset
1147
+ ]);
1148
+ }
1149
+ }
1150
+ /**
1151
+ * Set up a callback to be fired on [Window's `beforeunload` event](https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event).
1152
+ *
1153
+ * @public
1154
+ * @category Hooks
1155
+ * @param callback The callback to be called when the [`beforeunload` event](https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event)
1156
+ * is fired.
1157
+ * @param options Options
1158
+ * @param options.capture If `true`, the event will be captured during the capture
1159
+ * phase. Defaults to `false`.
1160
+ * @returns {void}
1161
+ */
1162
+ function useBeforeUnload(callback, options) {
1163
+ let { capture } = options || {};
1164
+ React$1.useEffect(() => {
1165
+ let opts = capture != null ? { capture } : void 0;
1166
+ window.addEventListener("beforeunload", callback, opts);
1167
+ return () => {
1168
+ window.removeEventListener("beforeunload", callback, opts);
1169
+ };
1170
+ }, [callback, capture]);
1171
+ }
1172
+ function usePageHide(callback, options) {
1173
+ let { capture } = options || {};
1174
+ React$1.useEffect(() => {
1175
+ let opts = capture != null ? { capture } : void 0;
1176
+ window.addEventListener("pagehide", callback, opts);
1177
+ return () => {
1178
+ window.removeEventListener("pagehide", callback, opts);
1179
+ };
1180
+ }, [callback, capture]);
1181
+ }
1182
+ /**
1183
+ * Wrapper around {@link useBlocker} to show a [`window.confirm`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm)
1184
+ * prompt to users instead of building a custom UI with {@link useBlocker}.
1185
+ *
1186
+ * The `unstable_` flag will not be removed because this technique has a lot of
1187
+ * rough edges and behaves very differently (and incorrectly sometimes) across
1188
+ * browsers if users click addition back/forward navigations while the
1189
+ * confirmation is open. Use at your own risk.
1190
+ *
1191
+ * @example
1192
+ * function ImportantForm() {
1193
+ * let [value, setValue] = React.useState("");
1194
+ *
1195
+ * // Block navigating elsewhere when data has been entered into the input
1196
+ * unstable_usePrompt({
1197
+ * message: "Are you sure?",
1198
+ * when: ({ currentLocation, nextLocation }) =>
1199
+ * value !== "" &&
1200
+ * currentLocation.pathname !== nextLocation.pathname,
1201
+ * });
1202
+ *
1203
+ * return (
1204
+ * <Form method="post">
1205
+ * <label>
1206
+ * Enter some important data:
1207
+ * <input
1208
+ * name="data"
1209
+ * value={value}
1210
+ * onChange={(e) => setValue(e.target.value)}
1211
+ * />
1212
+ * </label>
1213
+ * <button type="submit">Save</button>
1214
+ * </Form>
1215
+ * );
1216
+ * }
1217
+ *
1218
+ * @name unstable_usePrompt
1219
+ * @public
1220
+ * @category Hooks
1221
+ * @mode framework
1222
+ * @mode data
1223
+ * @param options Options
1224
+ * @param options.message The message to show in the confirmation dialog.
1225
+ * @param options.when A boolean or a function that returns a boolean indicating
1226
+ * whether to block the navigation. If a function is provided, it will receive an
1227
+ * object with `currentLocation` and `nextLocation` properties.
1228
+ * @returns {void}
1229
+ */
1230
+ function usePrompt({ when, message }) {
1231
+ let blocker = useBlocker(when);
1232
+ React$1.useEffect(() => {
1233
+ if (blocker.state === "blocked") if (window.confirm(message)) setTimeout(blocker.proceed, 0);
1234
+ else blocker.reset();
1235
+ }, [blocker, message]);
1236
+ React$1.useEffect(() => {
1237
+ if (blocker.state === "blocked" && !when) blocker.reset();
1238
+ }, [blocker, when]);
1239
+ }
1240
+ /**
1241
+ * This hook returns `true` when there is an active [View Transition](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API)
1242
+ * and the specified location matches either side of the navigation (the URL you are
1243
+ * navigating **to** or the URL you are navigating **from**). This can be used to apply finer-grained styles to
1244
+ * elements to further customize the view transition. This requires that view
1245
+ * transitions have been enabled for the given navigation via {@link LinkProps.viewTransition}
1246
+ * (or the `Form`, `submit`, or `navigate` call)
1247
+ *
1248
+ * @public
1249
+ * @category Hooks
1250
+ * @mode framework
1251
+ * @mode data
1252
+ * @param to The {@link To} location to compare against the active transition's current
1253
+ * and next URLs.
1254
+ * @param options Options
1255
+ * @param options.relative The relative routing type to use when resolving the
1256
+ * `to` location, defaults to `"route"`. See {@link RelativeRoutingType} for
1257
+ * more details.
1258
+ * @returns `true` if there is an active [View Transition](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API)
1259
+ * and the resolved path matches the transition's destination or source pathname, otherwise `false`.
1260
+ */
1261
+ function useViewTransitionState(to, { relative } = {}) {
1262
+ let vtContext = React$1.useContext(ViewTransitionContext);
1263
+ invariant(vtContext != null, "`useViewTransitionState` must be used within `react-router/dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");
1264
+ let { basename } = useDataRouterContext("useViewTransitionState");
1265
+ let path = useResolvedPath(to, { relative });
1266
+ if (!vtContext.isTransitioning) return false;
1267
+ let currentPath = stripBasename(vtContext.currentLocation.pathname, basename) || vtContext.currentLocation.pathname;
1268
+ let nextPath = stripBasename(vtContext.nextLocation.pathname, basename) || vtContext.nextLocation.pathname;
1269
+ return matchPath(path.pathname, nextPath) != null || matchPath(path.pathname, currentPath) != null;
1270
+ }
1271
+ //#endregion
1272
+ export { BrowserRouter, Form, HashRouter, HistoryRouter, Link, NavLink, ScrollRestoration, createBrowserRouter, createHashRouter, useBeforeUnload, useFetcher, useFetchers, useFormAction, useLinkClickHandler, usePrompt, useScrollRestoration, useSearchParams, useSubmit, useViewTransitionState };