react-router 7.18.0 → 8.0.0-pre.1

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 (285) hide show
  1. package/dist/development/dom-export.d.ts +6 -172
  2. package/dist/development/dom-export.js +12 -1009
  3. package/dist/development/index-react-server-client.d.ts +7 -4
  4. package/dist/development/index-react-server-client.js +8 -52
  5. package/dist/development/index-react-server.d.ts +1650 -1641
  6. package/dist/development/index-react-server.js +2882 -3664
  7. package/dist/development/index.d.ts +42 -1476
  8. package/dist/development/index.js +36 -2553
  9. package/dist/development/lib/actions.js +50 -0
  10. package/dist/development/lib/components.d.ts +1030 -0
  11. package/dist/development/lib/components.js +841 -0
  12. package/dist/development/lib/context.d.ts +83 -0
  13. package/dist/development/lib/context.js +41 -0
  14. package/dist/development/lib/dom/dom.d.ts +119 -0
  15. package/dist/development/lib/dom/dom.js +143 -0
  16. package/dist/development/lib/dom/lib.d.ts +2053 -0
  17. package/dist/development/lib/dom/lib.js +1271 -0
  18. package/dist/development/lib/dom/server.d.ts +138 -0
  19. package/dist/development/lib/dom/server.js +301 -0
  20. package/dist/development/lib/dom/ssr/components.d.ts +198 -0
  21. package/dist/development/lib/dom/ssr/components.js +589 -0
  22. package/dist/development/lib/dom/ssr/data.js +29 -0
  23. package/dist/development/lib/dom/ssr/entry.d.ts +60 -0
  24. package/dist/development/lib/dom/ssr/errorBoundaries.d.ts +27 -0
  25. package/dist/development/lib/dom/ssr/errorBoundaries.js +87 -0
  26. package/dist/development/lib/dom/ssr/fallback.js +33 -0
  27. package/dist/development/lib/dom/ssr/fog-of-war.d.ts +12 -0
  28. package/dist/development/lib/dom/ssr/fog-of-war.js +180 -0
  29. package/dist/development/lib/dom/ssr/hydration.d.ts +32 -0
  30. package/dist/development/lib/dom/ssr/hydration.js +29 -0
  31. package/dist/development/lib/dom/ssr/invariant.js +16 -0
  32. package/dist/development/lib/dom/ssr/links.js +170 -0
  33. package/dist/development/lib/dom/ssr/markup.js +24 -0
  34. package/dist/development/lib/dom/ssr/routeModules.d.ts +206 -0
  35. package/dist/development/lib/dom/ssr/routeModules.js +31 -0
  36. package/dist/development/lib/dom/ssr/routes-test-stub.d.ts +62 -0
  37. package/dist/development/lib/dom/ssr/routes-test-stub.js +108 -0
  38. package/dist/development/lib/dom/ssr/routes.d.ts +33 -0
  39. package/dist/development/lib/dom/ssr/routes.js +303 -0
  40. package/dist/development/lib/dom/ssr/server.d.ts +48 -0
  41. package/dist/development/lib/dom/ssr/server.js +69 -0
  42. package/dist/development/lib/dom/ssr/single-fetch.d.ts +14 -0
  43. package/dist/development/lib/dom/ssr/single-fetch.js +345 -0
  44. package/dist/development/lib/dom-export/dom-router-provider.d.ts +9 -0
  45. package/dist/development/lib/dom-export/dom-router-provider.js +22 -0
  46. package/dist/development/lib/dom-export/hydrated-router.d.ts +125 -0
  47. package/dist/development/lib/dom-export/hydrated-router.js +150 -0
  48. package/dist/development/lib/errors.js +29 -0
  49. package/dist/development/lib/hooks.d.ts +947 -0
  50. package/dist/development/lib/hooks.js +1388 -0
  51. package/dist/development/lib/href.d.ts +20 -0
  52. package/dist/development/lib/href.js +50 -0
  53. package/dist/development/lib/router/history.d.ts +258 -0
  54. package/dist/development/lib/router/history.js +372 -0
  55. package/dist/development/lib/router/instrumentation.d.ts +86 -0
  56. package/dist/development/lib/router/instrumentation.js +213 -0
  57. package/dist/development/lib/router/links.d.ts +114 -0
  58. package/dist/development/lib/router/router.d.ts +663 -0
  59. package/dist/development/lib/router/router.js +2988 -0
  60. package/dist/development/lib/router/url.js +18 -0
  61. package/dist/development/lib/router/utils.d.ts +948 -0
  62. package/dist/development/lib/router/utils.js +810 -0
  63. package/dist/development/lib/rsc/browser.d.ts +137 -0
  64. package/dist/development/lib/rsc/browser.js +603 -0
  65. package/dist/development/lib/rsc/errorBoundaries.d.ts +11 -0
  66. package/dist/development/lib/rsc/errorBoundaries.js +90 -0
  67. package/dist/development/lib/rsc/html-stream/browser.d.ts +48 -0
  68. package/dist/development/lib/rsc/html-stream/browser.js +74 -0
  69. package/dist/development/lib/rsc/html-stream/server.js +78 -0
  70. package/dist/development/lib/rsc/route-modules.js +27 -0
  71. package/dist/development/lib/rsc/server.rsc.d.ts +219 -0
  72. package/dist/development/lib/rsc/server.ssr.d.ts +129 -0
  73. package/dist/development/lib/rsc/server.ssr.js +404 -0
  74. package/dist/development/lib/server-runtime/build.d.ts +66 -0
  75. package/dist/development/lib/server-runtime/cookies.d.ts +66 -0
  76. package/dist/development/lib/server-runtime/cookies.js +139 -0
  77. package/dist/development/lib/server-runtime/crypto.js +43 -0
  78. package/dist/development/lib/server-runtime/data.d.ts +13 -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 +10 -0
  92. package/dist/development/lib/server-runtime/server.js +345 -0
  93. package/dist/development/lib/server-runtime/serverHandoff.js +17 -0
  94. package/dist/development/lib/server-runtime/sessions/cookieStorage.d.ts +25 -0
  95. package/dist/development/lib/server-runtime/sessions/cookieStorage.js +45 -0
  96. package/dist/development/lib/server-runtime/sessions/memoryStorage.d.ts +23 -0
  97. package/dist/development/lib/server-runtime/sessions/memoryStorage.js +52 -0
  98. package/dist/development/lib/server-runtime/sessions.d.ts +145 -0
  99. package/dist/development/lib/server-runtime/sessions.js +98 -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/development/{register-roq_0qYo.d.ts → 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 -1009
  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 +1650 -1641
  122. package/dist/production/index-react-server.js +2873 -3664
  123. package/dist/production/index.d.ts +42 -1476
  124. package/dist/production/index.js +36 -2553
  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 +2053 -0
  133. package/dist/production/lib/dom/lib.js +1271 -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 +180 -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 +62 -0
  153. package/dist/production/lib/dom/ssr/routes-test-stub.js +108 -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 +947 -0
  166. package/dist/production/lib/hooks.js +1373 -0
  167. package/dist/production/lib/href.d.ts +20 -0
  168. package/dist/production/lib/href.js +50 -0
  169. package/dist/production/lib/router/history.d.ts +258 -0
  170. package/dist/production/lib/router/history.js +372 -0
  171. package/dist/production/lib/router/instrumentation.d.ts +86 -0
  172. package/dist/production/lib/router/instrumentation.js +213 -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 +948 -0
  178. package/dist/production/lib/router/utils.js +801 -0
  179. package/dist/production/lib/rsc/browser.d.ts +137 -0
  180. package/dist/production/lib/rsc/browser.js +603 -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 +78 -0
  186. package/dist/production/lib/rsc/route-modules.js +27 -0
  187. package/dist/production/lib/rsc/server.rsc.d.ts +219 -0
  188. package/dist/production/lib/rsc/server.ssr.d.ts +129 -0
  189. package/dist/production/lib/rsc/server.ssr.js +404 -0
  190. package/dist/production/lib/server-runtime/build.d.ts +66 -0
  191. package/dist/production/lib/server-runtime/cookies.d.ts +66 -0
  192. package/dist/production/lib/server-runtime/cookies.js +139 -0
  193. package/dist/production/lib/server-runtime/crypto.js +43 -0
  194. package/dist/production/lib/server-runtime/data.d.ts +13 -0
  195. package/dist/production/lib/server-runtime/data.js +25 -0
  196. package/dist/production/lib/server-runtime/dev.d.ts +9 -0
  197. package/dist/production/lib/server-runtime/dev.js +26 -0
  198. package/dist/production/lib/server-runtime/entry.js +20 -0
  199. package/dist/production/lib/server-runtime/errors.js +75 -0
  200. package/dist/production/lib/server-runtime/headers.js +73 -0
  201. package/dist/production/lib/server-runtime/invariant.js +19 -0
  202. package/dist/production/lib/server-runtime/mode.d.ts +12 -0
  203. package/dist/production/lib/server-runtime/mode.js +25 -0
  204. package/dist/production/lib/server-runtime/routeMatching.js +28 -0
  205. package/dist/production/lib/server-runtime/routes.d.ts +13 -0
  206. package/dist/production/lib/server-runtime/routes.js +74 -0
  207. package/dist/production/lib/server-runtime/server.d.ts +10 -0
  208. package/dist/production/lib/server-runtime/server.js +345 -0
  209. package/dist/production/lib/server-runtime/serverHandoff.js +17 -0
  210. package/dist/production/lib/server-runtime/sessions/cookieStorage.d.ts +25 -0
  211. package/dist/production/lib/server-runtime/sessions/cookieStorage.js +45 -0
  212. package/dist/production/lib/server-runtime/sessions/memoryStorage.d.ts +23 -0
  213. package/dist/production/lib/server-runtime/sessions/memoryStorage.js +52 -0
  214. package/dist/production/lib/server-runtime/sessions.d.ts +145 -0
  215. package/dist/production/lib/server-runtime/sessions.js +98 -0
  216. package/dist/production/lib/server-runtime/single-fetch.d.ts +7 -0
  217. package/dist/production/lib/server-runtime/single-fetch.js +215 -0
  218. package/dist/production/lib/server-runtime/urls.js +28 -0
  219. package/dist/production/lib/server-runtime/warnings.js +20 -0
  220. package/dist/production/lib/types/future.d.ts +9 -0
  221. package/dist/production/lib/types/internal.d.ts +26 -177
  222. package/dist/production/lib/types/internal.js +3 -2
  223. package/dist/production/{register-roq_0qYo.d.ts → lib/types/register.d.ts} +9 -15
  224. package/dist/production/lib/types/route-data.d.ts +113 -0
  225. package/dist/production/lib/types/route-module-annotations.d.ts +149 -0
  226. package/dist/production/lib/types/route-module.d.ts +19 -0
  227. package/dist/production/lib/types/serializes-to.d.ts +13 -0
  228. package/dist/production/lib/types/utils.d.ts +11 -0
  229. package/dist/production/vendor/turbo-stream-v2/flatten.js +159 -0
  230. package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +179 -0
  231. package/dist/production/vendor/turbo-stream-v2/unflatten.js +199 -0
  232. package/dist/production/vendor/turbo-stream-v2/utils.js +39 -0
  233. package/docs/explanation/code-splitting.md +16 -0
  234. package/docs/how-to/middleware.md +6 -41
  235. package/docs/how-to/react-server-components.md +1 -1
  236. package/docs/upgrading/future.md +0 -249
  237. package/package.json +43 -87
  238. package/dist/development/browser-B2PdsXXH.d.ts +0 -318
  239. package/dist/development/browser-DBmQ1yAR.d.mts +0 -318
  240. package/dist/development/chunk-4ZMWKKQ3.mjs +0 -11606
  241. package/dist/development/chunk-E4MTK73K.mjs +0 -2517
  242. package/dist/development/chunk-U7ORXROY.js +0 -10307
  243. package/dist/development/chunk-WW7PN6QI.js +0 -188
  244. package/dist/development/chunk-YL5M26XI.js +0 -1366
  245. package/dist/development/context-CeD5LmaF.d.mts +0 -1779
  246. package/dist/development/data-CjO11-hU.d.ts +0 -1740
  247. package/dist/development/data-DEjBmEfD.d.mts +0 -1740
  248. package/dist/development/dom-export.d.mts +0 -172
  249. package/dist/development/dom-export.mjs +0 -1010
  250. package/dist/development/index-react-server-client-3ykjivgQ.d.ts +0 -3677
  251. package/dist/development/index-react-server-client-CACgcj2J.d.mts +0 -2614
  252. package/dist/development/index-react-server-client.d.mts +0 -4
  253. package/dist/development/index-react-server-client.mjs +0 -59
  254. package/dist/development/index-react-server.d.mts +0 -2711
  255. package/dist/development/index-react-server.mjs +0 -3803
  256. package/dist/development/index.d.mts +0 -1479
  257. package/dist/development/index.mjs +0 -275
  258. package/dist/development/instrumentation-Dkmpzd13.d.ts +0 -715
  259. package/dist/development/lib/types/internal.d.mts +0 -184
  260. package/dist/development/lib/types/internal.mjs +0 -10
  261. package/dist/development/register-CmkRspdl.d.mts +0 -30
  262. package/dist/production/browser-B2PdsXXH.d.ts +0 -318
  263. package/dist/production/browser-DBmQ1yAR.d.mts +0 -318
  264. package/dist/production/chunk-3Z6WS2WZ.js +0 -188
  265. package/dist/production/chunk-BIP66BKV.js +0 -1366
  266. package/dist/production/chunk-EGOTSXNH.mjs +0 -2517
  267. package/dist/production/chunk-IUPBOWYO.js +0 -10307
  268. package/dist/production/chunk-M7NGGUU6.mjs +0 -11606
  269. package/dist/production/context-CeD5LmaF.d.mts +0 -1779
  270. package/dist/production/data-CjO11-hU.d.ts +0 -1740
  271. package/dist/production/data-DEjBmEfD.d.mts +0 -1740
  272. package/dist/production/dom-export.d.mts +0 -172
  273. package/dist/production/dom-export.mjs +0 -1010
  274. package/dist/production/index-react-server-client-3ykjivgQ.d.ts +0 -3677
  275. package/dist/production/index-react-server-client-CACgcj2J.d.mts +0 -2614
  276. package/dist/production/index-react-server-client.d.mts +0 -4
  277. package/dist/production/index-react-server-client.mjs +0 -59
  278. package/dist/production/index-react-server.d.mts +0 -2711
  279. package/dist/production/index-react-server.mjs +0 -3803
  280. package/dist/production/index.d.mts +0 -1479
  281. package/dist/production/index.mjs +0 -275
  282. package/dist/production/instrumentation-Dkmpzd13.d.ts +0 -715
  283. package/dist/production/lib/types/internal.d.mts +0 -184
  284. package/dist/production/lib/types/internal.mjs +0 -10
  285. package/dist/production/register-CmkRspdl.d.mts +0 -30
@@ -0,0 +1,1271 @@
1
+ /**
2
+ * react-router v8.0.0-pre.1
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.0.0-pre.1";
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(toPathname.length) === "/");
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. Defaults to `true`.
613
+ * @param options.mask Masked location to display in the browser instead
614
+ * of the router location. Defaults to `undefined`.
615
+ * @param options.useTransitions Wraps the navigation in
616
+ * [`React.startTransition`](https://react.dev/reference/react/startTransition)
617
+ * for concurrent rendering. Defaults to `false`.
618
+ * @returns A click handler function that can be used in a custom {@link Link} component.
619
+ */
620
+ function useLinkClickHandler(to, { target, replace: replaceProp, mask, state, preventScrollReset, relative, viewTransition, defaultShouldRevalidate, useTransitions } = {}) {
621
+ let navigate = useNavigate();
622
+ let location = useLocation();
623
+ let path = useResolvedPath(to, { relative });
624
+ return React$1.useCallback((event) => {
625
+ if (shouldProcessLinkClick(event, target)) {
626
+ event.preventDefault();
627
+ let replace = replaceProp !== void 0 ? replaceProp : createPath(location) === createPath(path);
628
+ let doNavigate = () => navigate(to, {
629
+ replace,
630
+ mask,
631
+ state,
632
+ preventScrollReset,
633
+ relative,
634
+ viewTransition,
635
+ defaultShouldRevalidate
636
+ });
637
+ if (useTransitions) React$1.startTransition(() => doNavigate());
638
+ else doNavigate();
639
+ }
640
+ }, [
641
+ location,
642
+ navigate,
643
+ path,
644
+ replaceProp,
645
+ mask,
646
+ state,
647
+ target,
648
+ to,
649
+ preventScrollReset,
650
+ relative,
651
+ viewTransition,
652
+ defaultShouldRevalidate,
653
+ useTransitions
654
+ ]);
655
+ }
656
+ /**
657
+ * Returns a tuple of the current URL's [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)
658
+ * and a function to update them. Setting the search params causes a navigation.
659
+ *
660
+ * ```tsx
661
+ * import { useSearchParams } from "react-router";
662
+ *
663
+ * export function SomeComponent() {
664
+ * const [searchParams, setSearchParams] = useSearchParams();
665
+ * // ...
666
+ * }
667
+ * ```
668
+ *
669
+ * ### `setSearchParams` function
670
+ *
671
+ * The second element of the tuple is a function that can be used to update the
672
+ * search params. It accepts the same types as `defaultInit` and will cause a
673
+ * navigation to the new URL.
674
+ *
675
+ * ```tsx
676
+ * let [searchParams, setSearchParams] = useSearchParams();
677
+ *
678
+ * // a search param string
679
+ * setSearchParams("?tab=1");
680
+ *
681
+ * // a shorthand object
682
+ * setSearchParams({ tab: "1" });
683
+ *
684
+ * // object keys can be arrays for multiple values on the key
685
+ * setSearchParams({ brand: ["nike", "reebok"] });
686
+ *
687
+ * // an array of tuples
688
+ * setSearchParams([["tab", "1"]]);
689
+ *
690
+ * // a `URLSearchParams` object
691
+ * setSearchParams(new URLSearchParams("?tab=1"));
692
+ * ```
693
+ *
694
+ * It also supports a function callback like React's
695
+ * [`setState`](https://react.dev/reference/react/useState#setstate):
696
+ *
697
+ * ```tsx
698
+ * setSearchParams((searchParams) => {
699
+ * searchParams.set("tab", "2");
700
+ * return searchParams;
701
+ * });
702
+ * ```
703
+ *
704
+ * <docs-warning>The function callback version of `setSearchParams` does not support
705
+ * the [queueing](https://react.dev/reference/react/useState#setstate-parameters)
706
+ * logic that React's `setState` implements. Multiple calls to `setSearchParams`
707
+ * in the same tick will not build on the prior value. If you need this behavior,
708
+ * you can use `setState` manually.</docs-warning>
709
+ *
710
+ * ### Notes
711
+ *
712
+ * Note that `searchParams` is a stable reference, so you can reliably use it
713
+ * as a dependency in React's [`useEffect`](https://react.dev/reference/react/useEffect)
714
+ * hooks.
715
+ *
716
+ * ```tsx
717
+ * useEffect(() => {
718
+ * console.log(searchParams.get("tab"));
719
+ * }, [searchParams]);
720
+ * ```
721
+ *
722
+ * However, this also means it's mutable. If you change the object without
723
+ * calling `setSearchParams`, its values will change between renders if some
724
+ * other state causes the component to re-render and URL will not reflect the
725
+ * values.
726
+ *
727
+ * @public
728
+ * @category Hooks
729
+ * @param defaultInit
730
+ * You can initialize the search params with a default value, though it **will
731
+ * not** change the URL on the first render.
732
+ *
733
+ * ```tsx
734
+ * // a search param string
735
+ * useSearchParams("?tab=1");
736
+ *
737
+ * // a shorthand object
738
+ * useSearchParams({ tab: "1" });
739
+ *
740
+ * // object keys can be arrays for multiple values on the key
741
+ * useSearchParams({ brand: ["nike", "reebok"] });
742
+ *
743
+ * // an array of tuples
744
+ * useSearchParams([["tab", "1"]]);
745
+ *
746
+ * // a `URLSearchParams` object
747
+ * useSearchParams(new URLSearchParams("?tab=1"));
748
+ * ```
749
+ * @returns A tuple of the current [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)
750
+ * and a function to update them.
751
+ */
752
+ function useSearchParams(defaultInit) {
753
+ 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.");
754
+ let defaultSearchParamsRef = React$1.useRef(createSearchParams(defaultInit));
755
+ let hasSetSearchParamsRef = React$1.useRef(false);
756
+ let location = useLocation();
757
+ let searchParams = React$1.useMemo(() => getSearchParamsForLocation(location.search, hasSetSearchParamsRef.current ? null : defaultSearchParamsRef.current), [location.search]);
758
+ let navigate = useNavigate();
759
+ return [searchParams, React$1.useCallback((nextInit, navigateOptions) => {
760
+ const newSearchParams = createSearchParams(typeof nextInit === "function" ? nextInit(new URLSearchParams(searchParams)) : nextInit);
761
+ hasSetSearchParamsRef.current = true;
762
+ navigate("?" + newSearchParams, navigateOptions);
763
+ }, [navigate, searchParams])];
764
+ }
765
+ let fetcherId = 0;
766
+ let getUniqueFetcherId = () => `__${String(++fetcherId)}__`;
767
+ /**
768
+ * The imperative version of {@link Form | `<Form>`} that lets you submit a form
769
+ * from code instead of a user interaction.
770
+ *
771
+ * @example
772
+ * import { useSubmit } from "react-router";
773
+ *
774
+ * function SomeComponent() {
775
+ * const submit = useSubmit();
776
+ * return (
777
+ * <Form onChange={(event) => submit(event.currentTarget)} />
778
+ * );
779
+ * }
780
+ *
781
+ * @public
782
+ * @category Hooks
783
+ * @mode framework
784
+ * @mode data
785
+ * @returns A function that can be called to submit a {@link Form} imperatively.
786
+ */
787
+ function useSubmit() {
788
+ let { router } = useDataRouterContext("useSubmit");
789
+ let { basename } = React$1.useContext(NavigationContext);
790
+ let currentRouteId = useRouteId();
791
+ let routerFetch = router.fetch;
792
+ let routerNavigate = router.navigate;
793
+ return React$1.useCallback(async (target, options = {}) => {
794
+ let { action, method, encType, formData, body } = getFormSubmissionInfo(target, basename);
795
+ if (options.navigate === false) await routerFetch(options.fetcherKey || getUniqueFetcherId(), currentRouteId, options.action || action, {
796
+ defaultShouldRevalidate: options.defaultShouldRevalidate,
797
+ preventScrollReset: options.preventScrollReset,
798
+ formData,
799
+ body,
800
+ formMethod: options.method || method,
801
+ formEncType: options.encType || encType,
802
+ flushSync: options.flushSync
803
+ });
804
+ else await routerNavigate(options.action || action, {
805
+ defaultShouldRevalidate: options.defaultShouldRevalidate,
806
+ preventScrollReset: options.preventScrollReset,
807
+ formData,
808
+ body,
809
+ formMethod: options.method || method,
810
+ formEncType: options.encType || encType,
811
+ replace: options.replace,
812
+ state: options.state,
813
+ fromRouteId: currentRouteId,
814
+ flushSync: options.flushSync,
815
+ viewTransition: options.viewTransition
816
+ });
817
+ }, [
818
+ routerFetch,
819
+ routerNavigate,
820
+ basename,
821
+ currentRouteId
822
+ ]);
823
+ }
824
+ /**
825
+ * Resolves the URL to the closest route in the component hierarchy instead of
826
+ * the current URL of the app.
827
+ *
828
+ * This is used internally by {@link Form} to resolve the `action` to the closest
829
+ * route, but can be used generically as well.
830
+ *
831
+ * ```ts
832
+ * import { useFormAction } from "react-router";
833
+ *
834
+ * function SomeComponent() {
835
+ * // closest route URL
836
+ * let action = useFormAction();
837
+ *
838
+ * // closest route URL + "destroy"
839
+ * let destroyAction = useFormAction("destroy");
840
+ * }
841
+ * ```
842
+ *
843
+ * <docs-info>This hook adds a `basename` if your app specifies one, so that it
844
+ * can be used with raw `<form>` elements in a progressively enhanced way. If
845
+ * you are using this to provide an `action` to `<Form>` or `fetcher.submit`, you
846
+ * will need to remove the `basename` since both of those will prepend it
847
+ * internally.</docs-info>
848
+ *
849
+ *
850
+ * @public
851
+ * @category Hooks
852
+ * @mode framework
853
+ * @mode data
854
+ * @param action The action to append to the closest route URL. Defaults to the
855
+ * closest route URL.
856
+ * @param options Options
857
+ * @param options.relative The relative routing type to use when resolving the
858
+ * action. Defaults to `"route"`.
859
+ * @returns The resolved action URL.
860
+ */
861
+ function useFormAction(action, { relative } = {}) {
862
+ let { basename } = React$1.useContext(NavigationContext);
863
+ let routeContext = React$1.useContext(RouteContext);
864
+ invariant(routeContext, "useFormAction must be used inside a RouteContext");
865
+ let [match] = routeContext.matches.slice(-1);
866
+ let path = { ...useResolvedPath(action ? action : ".", { relative }) };
867
+ let location = useLocation();
868
+ if (action == null) {
869
+ path.search = location.search;
870
+ let params = new URLSearchParams(path.search);
871
+ let indexValues = params.getAll("index");
872
+ if (indexValues.some((v) => v === "")) {
873
+ params.delete("index");
874
+ indexValues.filter((v) => v).forEach((v) => params.append("index", v));
875
+ let qs = params.toString();
876
+ path.search = qs ? `?${qs}` : "";
877
+ }
878
+ }
879
+ if ((!action || action === ".") && match.route.index) path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index";
880
+ if (basename !== "/") path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]);
881
+ return createPath(path);
882
+ }
883
+ /**
884
+ * Useful for creating complex, dynamic user interfaces that require multiple,
885
+ * concurrent data interactions without causing a navigation.
886
+ *
887
+ * Fetchers track their own, independent state and can be used to load data, submit
888
+ * forms, and generally interact with [`action`](../../start/framework/route-module#action)
889
+ * and [`loader`](../../start/framework/route-module#loader) functions.
890
+ *
891
+ * @example
892
+ * import { useFetcher } from "react-router"
893
+ *
894
+ * function SomeComponent() {
895
+ * let fetcher = useFetcher()
896
+ *
897
+ * // states are available on the fetcher
898
+ * fetcher.state // "idle" | "loading" | "submitting"
899
+ * fetcher.data // the data returned from the action or loader
900
+ *
901
+ * // render a form
902
+ * <fetcher.Form method="post" />
903
+ *
904
+ * // load data
905
+ * fetcher.load("/some/route")
906
+ *
907
+ * // submit data
908
+ * fetcher.submit(someFormRef, { method: "post" })
909
+ * fetcher.submit(someData, {
910
+ * method: "post",
911
+ * encType: "application/json"
912
+ * })
913
+ *
914
+ * // reset fetcher
915
+ * fetcher.reset()
916
+ * }
917
+ *
918
+ * @public
919
+ * @category Hooks
920
+ * @mode framework
921
+ * @mode data
922
+ * @param options Options
923
+ * @param options.key A unique key to identify the fetcher.
924
+ *
925
+ *
926
+ * By default, `useFetcher` generates a unique fetcher scoped to that component.
927
+ * If you want to identify a fetcher with your own key such that you can access
928
+ * it from elsewhere in your app, you can do that with the `key` option:
929
+ *
930
+ * ```tsx
931
+ * function SomeComp() {
932
+ * let fetcher = useFetcher({ key: "my-key" })
933
+ * // ...
934
+ * }
935
+ *
936
+ * // Somewhere else
937
+ * function AnotherComp() {
938
+ * // this will be the same fetcher, sharing the state across the app
939
+ * let fetcher = useFetcher({ key: "my-key" });
940
+ * // ...
941
+ * }
942
+ * ```
943
+ * @returns A {@link FetcherWithComponents} object that contains the fetcher's state, data, and components for submitting forms and loading data.
944
+ */
945
+ function useFetcher({ key } = {}) {
946
+ let { router } = useDataRouterContext("useFetcher");
947
+ let state = useDataRouterState("useFetcher");
948
+ let fetcherData = React$1.useContext(FetchersContext);
949
+ let route = React$1.useContext(RouteContext);
950
+ let routeId = route.matches[route.matches.length - 1]?.route.id;
951
+ invariant(fetcherData, `useFetcher must be used inside a FetchersContext`);
952
+ invariant(route, `useFetcher must be used inside a RouteContext`);
953
+ invariant(routeId != null, `useFetcher can only be used on routes that contain a unique "id"`);
954
+ let defaultKey = React$1.useId();
955
+ let [fetcherKey, setFetcherKey] = React$1.useState(key || defaultKey);
956
+ if (key && key !== fetcherKey) setFetcherKey(key);
957
+ let { deleteFetcher, getFetcher, resetFetcher, fetch: routerFetch } = router;
958
+ React$1.useEffect(() => {
959
+ getFetcher(fetcherKey);
960
+ return () => deleteFetcher(fetcherKey);
961
+ }, [
962
+ deleteFetcher,
963
+ getFetcher,
964
+ fetcherKey
965
+ ]);
966
+ let load = React$1.useCallback(async (href, opts) => {
967
+ invariant(routeId, "No routeId available for fetcher.load()");
968
+ await routerFetch(fetcherKey, routeId, href, opts);
969
+ }, [
970
+ fetcherKey,
971
+ routeId,
972
+ routerFetch
973
+ ]);
974
+ let submitImpl = useSubmit();
975
+ let submit = React$1.useCallback(async (target, opts) => {
976
+ await submitImpl(target, {
977
+ ...opts,
978
+ navigate: false,
979
+ fetcherKey
980
+ });
981
+ }, [fetcherKey, submitImpl]);
982
+ let reset = React$1.useCallback((opts) => resetFetcher(fetcherKey, opts), [resetFetcher, fetcherKey]);
983
+ let FetcherForm = React$1.useMemo(() => {
984
+ let FetcherForm = React$1.forwardRef((props, ref) => {
985
+ return /* @__PURE__ */ React$1.createElement(Form, {
986
+ ...props,
987
+ navigate: false,
988
+ fetcherKey,
989
+ ref
990
+ });
991
+ });
992
+ FetcherForm.displayName = "fetcher.Form";
993
+ return FetcherForm;
994
+ }, [fetcherKey]);
995
+ let fetcher = state.fetchers.get(fetcherKey) || IDLE_FETCHER;
996
+ let data = fetcherData.get(fetcherKey);
997
+ return React$1.useMemo(() => ({
998
+ Form: FetcherForm,
999
+ submit,
1000
+ load,
1001
+ reset,
1002
+ ...fetcher,
1003
+ data
1004
+ }), [
1005
+ FetcherForm,
1006
+ submit,
1007
+ load,
1008
+ reset,
1009
+ fetcher,
1010
+ data
1011
+ ]);
1012
+ }
1013
+ /**
1014
+ * Returns an array of all in-flight {@link Fetcher}s. This is useful for components
1015
+ * throughout the app that didn't create the fetchers but want to use their submissions
1016
+ * to participate in optimistic UI.
1017
+ *
1018
+ * @example
1019
+ * import { useFetchers } from "react-router";
1020
+ *
1021
+ * function SomeComponent() {
1022
+ * const fetchers = useFetchers();
1023
+ * fetchers[0].formData; // FormData
1024
+ * fetchers[0].state; // etc.
1025
+ * // ...
1026
+ * }
1027
+ *
1028
+ * @public
1029
+ * @category Hooks
1030
+ * @mode framework
1031
+ * @mode data
1032
+ * @returns An array of all in-flight {@link Fetcher}s, each with a unique `key`
1033
+ * property.
1034
+ */
1035
+ function useFetchers() {
1036
+ let state = useDataRouterState("useFetchers");
1037
+ return React$1.useMemo(() => Array.from(state.fetchers.entries()).map(([key, fetcher]) => ({
1038
+ ...fetcher,
1039
+ key
1040
+ })), [state.fetchers]);
1041
+ }
1042
+ const SCROLL_RESTORATION_STORAGE_KEY = "react-router-scroll-positions";
1043
+ let savedScrollPositions = {};
1044
+ function getScrollRestorationKey(location, matches, basename, getKey) {
1045
+ let key = null;
1046
+ if (getKey) if (basename !== "/") key = getKey({
1047
+ ...location,
1048
+ pathname: stripBasename(location.pathname, basename) || location.pathname
1049
+ }, matches);
1050
+ else key = getKey(location, matches);
1051
+ if (key == null) key = location.key;
1052
+ return key;
1053
+ }
1054
+ /**
1055
+ * When rendered inside a {@link RouterProvider}, will restore scroll positions
1056
+ * on navigations
1057
+ *
1058
+ * <!--
1059
+ * Not marked `@public` because we only export as UNSAFE_ and therefore we don't
1060
+ * maintain an .md file for this hook
1061
+ * -->
1062
+ *
1063
+ * @name UNSAFE_useScrollRestoration
1064
+ * @category Hooks
1065
+ * @mode framework
1066
+ * @mode data
1067
+ * @param options Options
1068
+ * @param options.getKey A function that returns a key to use for scroll restoration.
1069
+ * This is useful for custom scroll restoration logic, such as using only the pathname
1070
+ * so that subsequent navigations to prior paths will restore the scroll. Defaults
1071
+ * to `location.key`.
1072
+ * @param options.storageKey The key to use for storing scroll positions in
1073
+ * `sessionStorage`. Defaults to `"react-router-scroll-positions"`.
1074
+ * @returns {void}
1075
+ */
1076
+ function useScrollRestoration({ getKey, storageKey } = {}) {
1077
+ let { router } = useDataRouterContext("useScrollRestoration");
1078
+ let { restoreScrollPosition, preventScrollReset } = useDataRouterState("useScrollRestoration");
1079
+ let { basename } = React$1.useContext(NavigationContext);
1080
+ let location = useLocation();
1081
+ let matches = useMatches();
1082
+ let navigation = useNavigation();
1083
+ React$1.useEffect(() => {
1084
+ window.history.scrollRestoration = "manual";
1085
+ return () => {
1086
+ window.history.scrollRestoration = "auto";
1087
+ };
1088
+ }, []);
1089
+ usePageHide(React$1.useCallback(() => {
1090
+ if (navigation.state === "idle") {
1091
+ let key = getScrollRestorationKey(location, matches, basename, getKey);
1092
+ savedScrollPositions[key] = window.scrollY;
1093
+ }
1094
+ try {
1095
+ sessionStorage.setItem(storageKey || SCROLL_RESTORATION_STORAGE_KEY, JSON.stringify(savedScrollPositions));
1096
+ } catch (error) {
1097
+ warning(false, `Failed to save scroll positions in sessionStorage, <ScrollRestoration /> will not work properly (${error}).`);
1098
+ }
1099
+ window.history.scrollRestoration = "auto";
1100
+ }, [
1101
+ navigation.state,
1102
+ getKey,
1103
+ basename,
1104
+ location,
1105
+ matches,
1106
+ storageKey
1107
+ ]));
1108
+ if (typeof document !== "undefined") {
1109
+ React$1.useLayoutEffect(() => {
1110
+ try {
1111
+ let sessionPositions = sessionStorage.getItem(storageKey || SCROLL_RESTORATION_STORAGE_KEY);
1112
+ if (sessionPositions) savedScrollPositions = JSON.parse(sessionPositions);
1113
+ } catch (e) {}
1114
+ }, [storageKey]);
1115
+ React$1.useLayoutEffect(() => {
1116
+ let disableScrollRestoration = router?.enableScrollRestoration(savedScrollPositions, () => window.scrollY, getKey ? (location, matches) => getScrollRestorationKey(location, matches, basename, getKey) : void 0);
1117
+ return () => disableScrollRestoration && disableScrollRestoration();
1118
+ }, [
1119
+ router,
1120
+ basename,
1121
+ getKey
1122
+ ]);
1123
+ React$1.useLayoutEffect(() => {
1124
+ if (restoreScrollPosition === false) return;
1125
+ if (typeof restoreScrollPosition === "number") {
1126
+ window.scrollTo(0, restoreScrollPosition);
1127
+ return;
1128
+ }
1129
+ try {
1130
+ if (location.hash) {
1131
+ let el = document.getElementById(decodeURIComponent(location.hash.slice(1)));
1132
+ if (el) {
1133
+ el.scrollIntoView();
1134
+ return;
1135
+ }
1136
+ }
1137
+ } catch {
1138
+ warning(false, `"${location.hash.slice(1)}" is not a decodable element ID. The view will not scroll to it.`);
1139
+ }
1140
+ if (preventScrollReset === true) return;
1141
+ window.scrollTo(0, 0);
1142
+ }, [
1143
+ location,
1144
+ restoreScrollPosition,
1145
+ preventScrollReset
1146
+ ]);
1147
+ }
1148
+ }
1149
+ /**
1150
+ * Set up a callback to be fired on [Window's `beforeunload` event](https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event).
1151
+ *
1152
+ * @public
1153
+ * @category Hooks
1154
+ * @param callback The callback to be called when the [`beforeunload` event](https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event)
1155
+ * is fired.
1156
+ * @param options Options
1157
+ * @param options.capture If `true`, the event will be captured during the capture
1158
+ * phase. Defaults to `false`.
1159
+ * @returns {void}
1160
+ */
1161
+ function useBeforeUnload(callback, options) {
1162
+ let { capture } = options || {};
1163
+ React$1.useEffect(() => {
1164
+ let opts = capture != null ? { capture } : void 0;
1165
+ window.addEventListener("beforeunload", callback, opts);
1166
+ return () => {
1167
+ window.removeEventListener("beforeunload", callback, opts);
1168
+ };
1169
+ }, [callback, capture]);
1170
+ }
1171
+ function usePageHide(callback, options) {
1172
+ let { capture } = options || {};
1173
+ React$1.useEffect(() => {
1174
+ let opts = capture != null ? { capture } : void 0;
1175
+ window.addEventListener("pagehide", callback, opts);
1176
+ return () => {
1177
+ window.removeEventListener("pagehide", callback, opts);
1178
+ };
1179
+ }, [callback, capture]);
1180
+ }
1181
+ /**
1182
+ * Wrapper around {@link useBlocker} to show a [`window.confirm`](https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm)
1183
+ * prompt to users instead of building a custom UI with {@link useBlocker}.
1184
+ *
1185
+ * The `unstable_` flag will not be removed because this technique has a lot of
1186
+ * rough edges and behaves very differently (and incorrectly sometimes) across
1187
+ * browsers if users click addition back/forward navigations while the
1188
+ * confirmation is open. Use at your own risk.
1189
+ *
1190
+ * @example
1191
+ * function ImportantForm() {
1192
+ * let [value, setValue] = React.useState("");
1193
+ *
1194
+ * // Block navigating elsewhere when data has been entered into the input
1195
+ * unstable_usePrompt({
1196
+ * message: "Are you sure?",
1197
+ * when: ({ currentLocation, nextLocation }) =>
1198
+ * value !== "" &&
1199
+ * currentLocation.pathname !== nextLocation.pathname,
1200
+ * });
1201
+ *
1202
+ * return (
1203
+ * <Form method="post">
1204
+ * <label>
1205
+ * Enter some important data:
1206
+ * <input
1207
+ * name="data"
1208
+ * value={value}
1209
+ * onChange={(e) => setValue(e.target.value)}
1210
+ * />
1211
+ * </label>
1212
+ * <button type="submit">Save</button>
1213
+ * </Form>
1214
+ * );
1215
+ * }
1216
+ *
1217
+ * @name unstable_usePrompt
1218
+ * @public
1219
+ * @category Hooks
1220
+ * @mode framework
1221
+ * @mode data
1222
+ * @param options Options
1223
+ * @param options.message The message to show in the confirmation dialog.
1224
+ * @param options.when A boolean or a function that returns a boolean indicating
1225
+ * whether to block the navigation. If a function is provided, it will receive an
1226
+ * object with `currentLocation` and `nextLocation` properties.
1227
+ * @returns {void}
1228
+ */
1229
+ function usePrompt({ when, message }) {
1230
+ let blocker = useBlocker(when);
1231
+ React$1.useEffect(() => {
1232
+ if (blocker.state === "blocked") if (window.confirm(message)) setTimeout(blocker.proceed, 0);
1233
+ else blocker.reset();
1234
+ }, [blocker, message]);
1235
+ React$1.useEffect(() => {
1236
+ if (blocker.state === "blocked" && !when) blocker.reset();
1237
+ }, [blocker, when]);
1238
+ }
1239
+ /**
1240
+ * This hook returns `true` when there is an active [View Transition](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API)
1241
+ * and the specified location matches either side of the navigation (the URL you are
1242
+ * navigating **to** or the URL you are navigating **from**). This can be used to apply finer-grained styles to
1243
+ * elements to further customize the view transition. This requires that view
1244
+ * transitions have been enabled for the given navigation via {@link LinkProps.viewTransition}
1245
+ * (or the `Form`, `submit`, or `navigate` call)
1246
+ *
1247
+ * @public
1248
+ * @category Hooks
1249
+ * @mode framework
1250
+ * @mode data
1251
+ * @param to The {@link To} location to compare against the active transition's current
1252
+ * and next URLs.
1253
+ * @param options Options
1254
+ * @param options.relative The relative routing type to use when resolving the
1255
+ * `to` location, defaults to `"route"`. See {@link RelativeRoutingType} for
1256
+ * more details.
1257
+ * @returns `true` if there is an active [View Transition](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API)
1258
+ * and the resolved path matches the transition's destination or source pathname, otherwise `false`.
1259
+ */
1260
+ function useViewTransitionState(to, { relative } = {}) {
1261
+ let vtContext = React$1.useContext(ViewTransitionContext);
1262
+ invariant(vtContext != null, "`useViewTransitionState` must be used within `react-router/dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");
1263
+ let { basename } = useDataRouterContext("useViewTransitionState");
1264
+ let path = useResolvedPath(to, { relative });
1265
+ if (!vtContext.isTransitioning) return false;
1266
+ let currentPath = stripBasename(vtContext.currentLocation.pathname, basename) || vtContext.currentLocation.pathname;
1267
+ let nextPath = stripBasename(vtContext.nextLocation.pathname, basename) || vtContext.nextLocation.pathname;
1268
+ return matchPath(path.pathname, nextPath) != null || matchPath(path.pathname, currentPath) != null;
1269
+ }
1270
+ //#endregion
1271
+ export { BrowserRouter, Form, HashRouter, HistoryRouter, Link, NavLink, ScrollRestoration, createBrowserRouter, createHashRouter, useBeforeUnload, useFetcher, useFetchers, useFormAction, useLinkClickHandler, usePrompt, useScrollRestoration, useSearchParams, useSubmit, useViewTransitionState };