UNPKG

50.9 kBJavaScriptView Raw
1/**
2 * React Router v6.12.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 */
11import * as React from 'react';
12import { UNSAFE_invariant, joinPaths, matchPath, UNSAFE_getPathContributingMatches, UNSAFE_warning, resolveTo, parsePath, matchRoutes, Action, isRouteErrorResponse, createMemoryHistory, stripBasename, AbortedDeferredError, createRouter } from '@remix-run/router';
13export { AbortedDeferredError, Action as NavigationType, createPath, defer, generatePath, isRouteErrorResponse, json, matchPath, matchRoutes, parsePath, redirect, resolvePath } from '@remix-run/router';
14
15function _extends() {
16 _extends = Object.assign ? Object.assign.bind() : function (target) {
17 for (var i = 1; i < arguments.length; i++) {
18 var source = arguments[i];
19 for (var key in source) {
20 if (Object.prototype.hasOwnProperty.call(source, key)) {
21 target[key] = source[key];
22 }
23 }
24 }
25 return target;
26 };
27 return _extends.apply(this, arguments);
28}
29
30// Create react-specific types from the agnostic types in @remix-run/router to
31// export from react-router
32const DataRouterContext = /*#__PURE__*/React.createContext(null);
33if (process.env.NODE_ENV !== "production") {
34 DataRouterContext.displayName = "DataRouter";
35}
36const DataRouterStateContext = /*#__PURE__*/React.createContext(null);
37if (process.env.NODE_ENV !== "production") {
38 DataRouterStateContext.displayName = "DataRouterState";
39}
40const AwaitContext = /*#__PURE__*/React.createContext(null);
41if (process.env.NODE_ENV !== "production") {
42 AwaitContext.displayName = "Await";
43}
44
45/**
46 * A Navigator is a "location changer"; it's how you get to different locations.
47 *
48 * Every history instance conforms to the Navigator interface, but the
49 * distinction is useful primarily when it comes to the low-level <Router> API
50 * where both the location and a navigator must be provided separately in order
51 * to avoid "tearing" that may occur in a suspense-enabled app if the action
52 * and/or location were to be read directly from the history instance.
53 */
54
55const NavigationContext = /*#__PURE__*/React.createContext(null);
56if (process.env.NODE_ENV !== "production") {
57 NavigationContext.displayName = "Navigation";
58}
59const LocationContext = /*#__PURE__*/React.createContext(null);
60if (process.env.NODE_ENV !== "production") {
61 LocationContext.displayName = "Location";
62}
63const RouteContext = /*#__PURE__*/React.createContext({
64 outlet: null,
65 matches: [],
66 isDataRoute: false
67});
68if (process.env.NODE_ENV !== "production") {
69 RouteContext.displayName = "Route";
70}
71const RouteErrorContext = /*#__PURE__*/React.createContext(null);
72if (process.env.NODE_ENV !== "production") {
73 RouteErrorContext.displayName = "RouteError";
74}
75
76/**
77 * Returns the full href for the given "to" value. This is useful for building
78 * custom links that are also accessible and preserve right-click behavior.
79 *
80 * @see https://reactrouter.com/hooks/use-href
81 */
82function useHref(to, _temp) {
83 let {
84 relative
85 } = _temp === void 0 ? {} : _temp;
86 !useInRouterContext() ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
87 // router loaded. We can help them understand how to avoid that.
88 "useHref() may be used only in the context of a <Router> component.") : UNSAFE_invariant(false) : void 0;
89 let {
90 basename,
91 navigator
92 } = React.useContext(NavigationContext);
93 let {
94 hash,
95 pathname,
96 search
97 } = useResolvedPath(to, {
98 relative
99 });
100 let joinedPathname = pathname;
101
102 // If we're operating within a basename, prepend it to the pathname prior
103 // to creating the href. If this is a root navigation, then just use the raw
104 // basename which allows the basename to have full control over the presence
105 // of a trailing slash on root links
106 if (basename !== "/") {
107 joinedPathname = pathname === "/" ? basename : joinPaths([basename, pathname]);
108 }
109 return navigator.createHref({
110 pathname: joinedPathname,
111 search,
112 hash
113 });
114}
115
116/**
117 * Returns true if this component is a descendant of a <Router>.
118 *
119 * @see https://reactrouter.com/hooks/use-in-router-context
120 */
121function useInRouterContext() {
122 return React.useContext(LocationContext) != null;
123}
124
125/**
126 * Returns the current location object, which represents the current URL in web
127 * browsers.
128 *
129 * Note: If you're using this it may mean you're doing some of your own
130 * "routing" in your app, and we'd like to know what your use case is. We may
131 * be able to provide something higher-level to better suit your needs.
132 *
133 * @see https://reactrouter.com/hooks/use-location
134 */
135function useLocation() {
136 !useInRouterContext() ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
137 // router loaded. We can help them understand how to avoid that.
138 "useLocation() may be used only in the context of a <Router> component.") : UNSAFE_invariant(false) : void 0;
139 return React.useContext(LocationContext).location;
140}
141
142/**
143 * Returns the current navigation action which describes how the router came to
144 * the current location, either by a pop, push, or replace on the history stack.
145 *
146 * @see https://reactrouter.com/hooks/use-navigation-type
147 */
148function useNavigationType() {
149 return React.useContext(LocationContext).navigationType;
150}
151
152/**
153 * Returns a PathMatch object if the given pattern matches the current URL.
154 * This is useful for components that need to know "active" state, e.g.
155 * <NavLink>.
156 *
157 * @see https://reactrouter.com/hooks/use-match
158 */
159function useMatch(pattern) {
160 !useInRouterContext() ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
161 // router loaded. We can help them understand how to avoid that.
162 "useMatch() may be used only in the context of a <Router> component.") : UNSAFE_invariant(false) : void 0;
163 let {
164 pathname
165 } = useLocation();
166 return React.useMemo(() => matchPath(pattern, pathname), [pathname, pattern]);
167}
168
169/**
170 * The interface for the navigate() function returned from useNavigate().
171 */
172
173const navigateEffectWarning = "You should call navigate() in a React.useEffect(), not when " + "your component is first rendered.";
174
175// Mute warnings for calls to useNavigate in SSR environments
176function useIsomorphicLayoutEffect(cb) {
177 let isStatic = React.useContext(NavigationContext).static;
178 if (!isStatic) {
179 // We should be able to get rid of this once react 18.3 is released
180 // See: https://github.com/facebook/react/pull/26395
181 // eslint-disable-next-line react-hooks/rules-of-hooks
182 React.useLayoutEffect(cb);
183 }
184}
185
186/**
187 * Returns an imperative method for changing the location. Used by <Link>s, but
188 * may also be used by other elements to change the location.
189 *
190 * @see https://reactrouter.com/hooks/use-navigate
191 */
192function useNavigate() {
193 let {
194 isDataRoute
195 } = React.useContext(RouteContext);
196 // Conditional usage is OK here because the usage of a data router is static
197 // eslint-disable-next-line react-hooks/rules-of-hooks
198 return isDataRoute ? useNavigateStable() : useNavigateUnstable();
199}
200function useNavigateUnstable() {
201 !useInRouterContext() ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
202 // router loaded. We can help them understand how to avoid that.
203 "useNavigate() may be used only in the context of a <Router> component.") : UNSAFE_invariant(false) : void 0;
204 let dataRouterContext = React.useContext(DataRouterContext);
205 let {
206 basename,
207 navigator
208 } = React.useContext(NavigationContext);
209 let {
210 matches
211 } = React.useContext(RouteContext);
212 let {
213 pathname: locationPathname
214 } = useLocation();
215 let routePathnamesJson = JSON.stringify(UNSAFE_getPathContributingMatches(matches).map(match => match.pathnameBase));
216 let activeRef = React.useRef(false);
217 useIsomorphicLayoutEffect(() => {
218 activeRef.current = true;
219 });
220 let navigate = React.useCallback(function (to, options) {
221 if (options === void 0) {
222 options = {};
223 }
224 process.env.NODE_ENV !== "production" ? UNSAFE_warning(activeRef.current, navigateEffectWarning) : void 0;
225
226 // Short circuit here since if this happens on first render the navigate
227 // is useless because we haven't wired up our history listener yet
228 if (!activeRef.current) return;
229 if (typeof to === "number") {
230 navigator.go(to);
231 return;
232 }
233 let path = resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, options.relative === "path");
234
235 // If we're operating within a basename, prepend it to the pathname prior
236 // to handing off to history (but only if we're not in a data router,
237 // otherwise it'll prepend the basename inside of the router).
238 // If this is a root navigation, then we navigate to the raw basename
239 // which allows the basename to have full control over the presence of a
240 // trailing slash on root links
241 if (dataRouterContext == null && basename !== "/") {
242 path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]);
243 }
244 (!!options.replace ? navigator.replace : navigator.push)(path, options.state, options);
245 }, [basename, navigator, routePathnamesJson, locationPathname, dataRouterContext]);
246 return navigate;
247}
248const OutletContext = /*#__PURE__*/React.createContext(null);
249
250/**
251 * Returns the context (if provided) for the child route at this level of the route
252 * hierarchy.
253 * @see https://reactrouter.com/hooks/use-outlet-context
254 */
255function useOutletContext() {
256 return React.useContext(OutletContext);
257}
258
259/**
260 * Returns the element for the child route at this level of the route
261 * hierarchy. Used internally by <Outlet> to render child routes.
262 *
263 * @see https://reactrouter.com/hooks/use-outlet
264 */
265function useOutlet(context) {
266 let outlet = React.useContext(RouteContext).outlet;
267 if (outlet) {
268 return /*#__PURE__*/React.createElement(OutletContext.Provider, {
269 value: context
270 }, outlet);
271 }
272 return outlet;
273}
274
275/**
276 * Returns an object of key/value pairs of the dynamic params from the current
277 * URL that were matched by the route path.
278 *
279 * @see https://reactrouter.com/hooks/use-params
280 */
281function useParams() {
282 let {
283 matches
284 } = React.useContext(RouteContext);
285 let routeMatch = matches[matches.length - 1];
286 return routeMatch ? routeMatch.params : {};
287}
288
289/**
290 * Resolves the pathname of the given `to` value against the current location.
291 *
292 * @see https://reactrouter.com/hooks/use-resolved-path
293 */
294function useResolvedPath(to, _temp2) {
295 let {
296 relative
297 } = _temp2 === void 0 ? {} : _temp2;
298 let {
299 matches
300 } = React.useContext(RouteContext);
301 let {
302 pathname: locationPathname
303 } = useLocation();
304 let routePathnamesJson = JSON.stringify(UNSAFE_getPathContributingMatches(matches).map(match => match.pathnameBase));
305 return React.useMemo(() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, relative === "path"), [to, routePathnamesJson, locationPathname, relative]);
306}
307
308/**
309 * Returns the element of the route that matched the current location, prepared
310 * with the correct context to render the remainder of the route tree. Route
311 * elements in the tree must render an <Outlet> to render their child route's
312 * element.
313 *
314 * @see https://reactrouter.com/hooks/use-routes
315 */
316function useRoutes(routes, locationArg) {
317 return useRoutesImpl(routes, locationArg);
318}
319
320// Internal implementation with accept optional param for RouterProvider usage
321function useRoutesImpl(routes, locationArg, dataRouterState) {
322 !useInRouterContext() ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
323 // router loaded. We can help them understand how to avoid that.
324 "useRoutes() may be used only in the context of a <Router> component.") : UNSAFE_invariant(false) : void 0;
325 let {
326 navigator
327 } = React.useContext(NavigationContext);
328 let {
329 matches: parentMatches
330 } = React.useContext(RouteContext);
331 let routeMatch = parentMatches[parentMatches.length - 1];
332 let parentParams = routeMatch ? routeMatch.params : {};
333 let parentPathname = routeMatch ? routeMatch.pathname : "/";
334 let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : "/";
335 let parentRoute = routeMatch && routeMatch.route;
336 if (process.env.NODE_ENV !== "production") {
337 // You won't get a warning about 2 different <Routes> under a <Route>
338 // without a trailing *, but this is a best-effort warning anyway since we
339 // cannot even give the warning unless they land at the parent route.
340 //
341 // Example:
342 //
343 // <Routes>
344 // {/* This route path MUST end with /* because otherwise
345 // it will never match /blog/post/123 */}
346 // <Route path="blog" element={<Blog />} />
347 // <Route path="blog/feed" element={<BlogFeed />} />
348 // </Routes>
349 //
350 // function Blog() {
351 // return (
352 // <Routes>
353 // <Route path="post/:id" element={<Post />} />
354 // </Routes>
355 // );
356 // }
357 let parentPath = parentRoute && parentRoute.path || "";
358 warningOnce(parentPathname, !parentRoute || parentPath.endsWith("*"), "You rendered descendant <Routes> (or called `useRoutes()`) at " + ("\"" + parentPathname + "\" (under <Route path=\"" + parentPath + "\">) but the ") + "parent route path has no trailing \"*\". This means if you navigate " + "deeper, the parent won't match anymore and therefore the child " + "routes will never render.\n\n" + ("Please change the parent <Route path=\"" + parentPath + "\"> to <Route ") + ("path=\"" + (parentPath === "/" ? "*" : parentPath + "/*") + "\">."));
359 }
360 let locationFromContext = useLocation();
361 let location;
362 if (locationArg) {
363 var _parsedLocationArg$pa;
364 let parsedLocationArg = typeof locationArg === "string" ? parsePath(locationArg) : locationArg;
365 !(parentPathnameBase === "/" || ((_parsedLocationArg$pa = parsedLocationArg.pathname) == null ? void 0 : _parsedLocationArg$pa.startsWith(parentPathnameBase))) ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "When overriding the location using `<Routes location>` or `useRoutes(routes, location)`, " + "the location pathname must begin with the portion of the URL pathname that was " + ("matched by all parent routes. The current pathname base is \"" + parentPathnameBase + "\" ") + ("but pathname \"" + parsedLocationArg.pathname + "\" was given in the `location` prop.")) : UNSAFE_invariant(false) : void 0;
366 location = parsedLocationArg;
367 } else {
368 location = locationFromContext;
369 }
370 let pathname = location.pathname || "/";
371 let remainingPathname = parentPathnameBase === "/" ? pathname : pathname.slice(parentPathnameBase.length) || "/";
372 let matches = matchRoutes(routes, {
373 pathname: remainingPathname
374 });
375 if (process.env.NODE_ENV !== "production") {
376 process.env.NODE_ENV !== "production" ? UNSAFE_warning(parentRoute || matches != null, "No routes matched location \"" + location.pathname + location.search + location.hash + "\" ") : void 0;
377 process.env.NODE_ENV !== "production" ? UNSAFE_warning(matches == null || matches[matches.length - 1].route.element !== undefined || matches[matches.length - 1].route.Component !== undefined, "Matched leaf route at location \"" + location.pathname + location.search + location.hash + "\" " + "does not have an element or Component. This means it will render an <Outlet /> with a " + "null value by default resulting in an \"empty\" page.") : void 0;
378 }
379 let renderedMatches = _renderMatches(matches && matches.map(match => Object.assign({}, match, {
380 params: Object.assign({}, parentParams, match.params),
381 pathname: joinPaths([parentPathnameBase,
382 // Re-encode pathnames that were decoded inside matchRoutes
383 navigator.encodeLocation ? navigator.encodeLocation(match.pathname).pathname : match.pathname]),
384 pathnameBase: match.pathnameBase === "/" ? parentPathnameBase : joinPaths([parentPathnameBase,
385 // Re-encode pathnames that were decoded inside matchRoutes
386 navigator.encodeLocation ? navigator.encodeLocation(match.pathnameBase).pathname : match.pathnameBase])
387 })), parentMatches, dataRouterState);
388
389 // When a user passes in a `locationArg`, the associated routes need to
390 // be wrapped in a new `LocationContext.Provider` in order for `useLocation`
391 // to use the scoped location instead of the global location.
392 if (locationArg && renderedMatches) {
393 return /*#__PURE__*/React.createElement(LocationContext.Provider, {
394 value: {
395 location: _extends({
396 pathname: "/",
397 search: "",
398 hash: "",
399 state: null,
400 key: "default"
401 }, location),
402 navigationType: Action.Pop
403 }
404 }, renderedMatches);
405 }
406 return renderedMatches;
407}
408function DefaultErrorComponent() {
409 let error = useRouteError();
410 let message = isRouteErrorResponse(error) ? error.status + " " + error.statusText : error instanceof Error ? error.message : JSON.stringify(error);
411 let stack = error instanceof Error ? error.stack : null;
412 let lightgrey = "rgba(200,200,200, 0.5)";
413 let preStyles = {
414 padding: "0.5rem",
415 backgroundColor: lightgrey
416 };
417 let codeStyles = {
418 padding: "2px 4px",
419 backgroundColor: lightgrey
420 };
421 let devInfo = null;
422 if (process.env.NODE_ENV !== "production") {
423 console.error("Error handled by React Router default ErrorBoundary:", error);
424 devInfo = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("p", null, "\uD83D\uDCBF Hey developer \uD83D\uDC4B"), /*#__PURE__*/React.createElement("p", null, "You can provide a way better UX than this when your app throws errors by providing your own ", /*#__PURE__*/React.createElement("code", {
425 style: codeStyles
426 }, "ErrorBoundary"), " or", " ", /*#__PURE__*/React.createElement("code", {
427 style: codeStyles
428 }, "errorElement"), " prop on your route."));
429 }
430 return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("h2", null, "Unexpected Application Error!"), /*#__PURE__*/React.createElement("h3", {
431 style: {
432 fontStyle: "italic"
433 }
434 }, message), stack ? /*#__PURE__*/React.createElement("pre", {
435 style: preStyles
436 }, stack) : null, devInfo);
437}
438const defaultErrorElement = /*#__PURE__*/React.createElement(DefaultErrorComponent, null);
439class RenderErrorBoundary extends React.Component {
440 constructor(props) {
441 super(props);
442 this.state = {
443 location: props.location,
444 revalidation: props.revalidation,
445 error: props.error
446 };
447 }
448 static getDerivedStateFromError(error) {
449 return {
450 error: error
451 };
452 }
453 static getDerivedStateFromProps(props, state) {
454 // When we get into an error state, the user will likely click "back" to the
455 // previous page that didn't have an error. Because this wraps the entire
456 // application, that will have no effect--the error page continues to display.
457 // This gives us a mechanism to recover from the error when the location changes.
458 //
459 // Whether we're in an error state or not, we update the location in state
460 // so that when we are in an error state, it gets reset when a new location
461 // comes in and the user recovers from the error.
462 if (state.location !== props.location || state.revalidation !== "idle" && props.revalidation === "idle") {
463 return {
464 error: props.error,
465 location: props.location,
466 revalidation: props.revalidation
467 };
468 }
469
470 // If we're not changing locations, preserve the location but still surface
471 // any new errors that may come through. We retain the existing error, we do
472 // this because the error provided from the app state may be cleared without
473 // the location changing.
474 return {
475 error: props.error || state.error,
476 location: state.location,
477 revalidation: props.revalidation || state.revalidation
478 };
479 }
480 componentDidCatch(error, errorInfo) {
481 console.error("React Router caught the following error during render", error, errorInfo);
482 }
483 render() {
484 return this.state.error ? /*#__PURE__*/React.createElement(RouteContext.Provider, {
485 value: this.props.routeContext
486 }, /*#__PURE__*/React.createElement(RouteErrorContext.Provider, {
487 value: this.state.error,
488 children: this.props.component
489 })) : this.props.children;
490 }
491}
492function RenderedRoute(_ref) {
493 let {
494 routeContext,
495 match,
496 children
497 } = _ref;
498 let dataRouterContext = React.useContext(DataRouterContext);
499
500 // Track how deep we got in our render pass to emulate SSR componentDidCatch
501 // in a DataStaticRouter
502 if (dataRouterContext && dataRouterContext.static && dataRouterContext.staticContext && (match.route.errorElement || match.route.ErrorBoundary)) {
503 dataRouterContext.staticContext._deepestRenderedBoundaryId = match.route.id;
504 }
505 return /*#__PURE__*/React.createElement(RouteContext.Provider, {
506 value: routeContext
507 }, children);
508}
509function _renderMatches(matches, parentMatches, dataRouterState) {
510 var _dataRouterState2;
511 if (parentMatches === void 0) {
512 parentMatches = [];
513 }
514 if (dataRouterState === void 0) {
515 dataRouterState = null;
516 }
517 if (matches == null) {
518 var _dataRouterState;
519 if ((_dataRouterState = dataRouterState) != null && _dataRouterState.errors) {
520 // Don't bail if we have data router errors so we can render them in the
521 // boundary. Use the pre-matched (or shimmed) matches
522 matches = dataRouterState.matches;
523 } else {
524 return null;
525 }
526 }
527 let renderedMatches = matches;
528
529 // If we have data errors, trim matches to the highest error boundary
530 let errors = (_dataRouterState2 = dataRouterState) == null ? void 0 : _dataRouterState2.errors;
531 if (errors != null) {
532 let errorIndex = renderedMatches.findIndex(m => m.route.id && (errors == null ? void 0 : errors[m.route.id]));
533 !(errorIndex >= 0) ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "Could not find a matching route for errors on route IDs: " + Object.keys(errors).join(",")) : UNSAFE_invariant(false) : void 0;
534 renderedMatches = renderedMatches.slice(0, Math.min(renderedMatches.length, errorIndex + 1));
535 }
536 return renderedMatches.reduceRight((outlet, match, index) => {
537 let error = match.route.id ? errors == null ? void 0 : errors[match.route.id] : null;
538 // Only data routers handle errors
539 let errorElement = null;
540 if (dataRouterState) {
541 errorElement = match.route.errorElement || defaultErrorElement;
542 }
543 let matches = parentMatches.concat(renderedMatches.slice(0, index + 1));
544 let getChildren = () => {
545 let children;
546 if (error) {
547 children = errorElement;
548 } else if (match.route.Component) {
549 // Note: This is a de-optimized path since React won't re-use the
550 // ReactElement since it's identity changes with each new
551 // React.createElement call. We keep this so folks can use
552 // `<Route Component={...}>` in `<Routes>` but generally `Component`
553 // usage is only advised in `RouterProvider` when we can convert it to
554 // `element` ahead of time.
555 children = /*#__PURE__*/React.createElement(match.route.Component, null);
556 } else if (match.route.element) {
557 children = match.route.element;
558 } else {
559 children = outlet;
560 }
561 return /*#__PURE__*/React.createElement(RenderedRoute, {
562 match: match,
563 routeContext: {
564 outlet,
565 matches,
566 isDataRoute: dataRouterState != null
567 },
568 children: children
569 });
570 };
571 // Only wrap in an error boundary within data router usages when we have an
572 // ErrorBoundary/errorElement on this route. Otherwise let it bubble up to
573 // an ancestor ErrorBoundary/errorElement
574 return dataRouterState && (match.route.ErrorBoundary || match.route.errorElement || index === 0) ? /*#__PURE__*/React.createElement(RenderErrorBoundary, {
575 location: dataRouterState.location,
576 revalidation: dataRouterState.revalidation,
577 component: errorElement,
578 error: error,
579 children: getChildren(),
580 routeContext: {
581 outlet: null,
582 matches,
583 isDataRoute: true
584 }
585 }) : getChildren();
586 }, null);
587}
588var DataRouterHook;
589(function (DataRouterHook) {
590 DataRouterHook["UseBlocker"] = "useBlocker";
591 DataRouterHook["UseRevalidator"] = "useRevalidator";
592 DataRouterHook["UseNavigateStable"] = "useNavigate";
593})(DataRouterHook || (DataRouterHook = {}));
594var DataRouterStateHook;
595(function (DataRouterStateHook) {
596 DataRouterStateHook["UseBlocker"] = "useBlocker";
597 DataRouterStateHook["UseLoaderData"] = "useLoaderData";
598 DataRouterStateHook["UseActionData"] = "useActionData";
599 DataRouterStateHook["UseRouteError"] = "useRouteError";
600 DataRouterStateHook["UseNavigation"] = "useNavigation";
601 DataRouterStateHook["UseRouteLoaderData"] = "useRouteLoaderData";
602 DataRouterStateHook["UseMatches"] = "useMatches";
603 DataRouterStateHook["UseRevalidator"] = "useRevalidator";
604 DataRouterStateHook["UseNavigateStable"] = "useNavigate";
605 DataRouterStateHook["UseRouteId"] = "useRouteId";
606})(DataRouterStateHook || (DataRouterStateHook = {}));
607function getDataRouterConsoleError(hookName) {
608 return hookName + " must be used within a data router. See https://reactrouter.com/routers/picking-a-router.";
609}
610function useDataRouterContext(hookName) {
611 let ctx = React.useContext(DataRouterContext);
612 !ctx ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, getDataRouterConsoleError(hookName)) : UNSAFE_invariant(false) : void 0;
613 return ctx;
614}
615function useDataRouterState(hookName) {
616 let state = React.useContext(DataRouterStateContext);
617 !state ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, getDataRouterConsoleError(hookName)) : UNSAFE_invariant(false) : void 0;
618 return state;
619}
620function useRouteContext(hookName) {
621 let route = React.useContext(RouteContext);
622 !route ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, getDataRouterConsoleError(hookName)) : UNSAFE_invariant(false) : void 0;
623 return route;
624}
625
626// Internal version with hookName-aware debugging
627function useCurrentRouteId(hookName) {
628 let route = useRouteContext(hookName);
629 let thisRoute = route.matches[route.matches.length - 1];
630 !thisRoute.route.id ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, hookName + " can only be used on routes that contain a unique \"id\"") : UNSAFE_invariant(false) : void 0;
631 return thisRoute.route.id;
632}
633
634/**
635 * Returns the ID for the nearest contextual route
636 */
637function useRouteId() {
638 return useCurrentRouteId(DataRouterStateHook.UseRouteId);
639}
640
641/**
642 * Returns the current navigation, defaulting to an "idle" navigation when
643 * no navigation is in progress
644 */
645function useNavigation() {
646 let state = useDataRouterState(DataRouterStateHook.UseNavigation);
647 return state.navigation;
648}
649
650/**
651 * Returns a revalidate function for manually triggering revalidation, as well
652 * as the current state of any manual revalidations
653 */
654function useRevalidator() {
655 let dataRouterContext = useDataRouterContext(DataRouterHook.UseRevalidator);
656 let state = useDataRouterState(DataRouterStateHook.UseRevalidator);
657 return {
658 revalidate: dataRouterContext.router.revalidate,
659 state: state.revalidation
660 };
661}
662
663/**
664 * Returns the active route matches, useful for accessing loaderData for
665 * parent/child routes or the route "handle" property
666 */
667function useMatches() {
668 let {
669 matches,
670 loaderData
671 } = useDataRouterState(DataRouterStateHook.UseMatches);
672 return React.useMemo(() => matches.map(match => {
673 let {
674 pathname,
675 params
676 } = match;
677 // Note: This structure matches that created by createUseMatchesMatch
678 // in the @remix-run/router , so if you change this please also change
679 // that :) Eventually we'll DRY this up
680 return {
681 id: match.route.id,
682 pathname,
683 params,
684 data: loaderData[match.route.id],
685 handle: match.route.handle
686 };
687 }), [matches, loaderData]);
688}
689
690/**
691 * Returns the loader data for the nearest ancestor Route loader
692 */
693function useLoaderData() {
694 let state = useDataRouterState(DataRouterStateHook.UseLoaderData);
695 let routeId = useCurrentRouteId(DataRouterStateHook.UseLoaderData);
696 if (state.errors && state.errors[routeId] != null) {
697 console.error("You cannot `useLoaderData` in an errorElement (routeId: " + routeId + ")");
698 return undefined;
699 }
700 return state.loaderData[routeId];
701}
702
703/**
704 * Returns the loaderData for the given routeId
705 */
706function useRouteLoaderData(routeId) {
707 let state = useDataRouterState(DataRouterStateHook.UseRouteLoaderData);
708 return state.loaderData[routeId];
709}
710
711/**
712 * Returns the action data for the nearest ancestor Route action
713 */
714function useActionData() {
715 let state = useDataRouterState(DataRouterStateHook.UseActionData);
716 let route = React.useContext(RouteContext);
717 !route ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "useActionData must be used inside a RouteContext") : UNSAFE_invariant(false) : void 0;
718 return Object.values((state == null ? void 0 : state.actionData) || {})[0];
719}
720
721/**
722 * Returns the nearest ancestor Route error, which could be a loader/action
723 * error or a render error. This is intended to be called from your
724 * ErrorBoundary/errorElement to display a proper error message.
725 */
726function useRouteError() {
727 var _state$errors;
728 let error = React.useContext(RouteErrorContext);
729 let state = useDataRouterState(DataRouterStateHook.UseRouteError);
730 let routeId = useCurrentRouteId(DataRouterStateHook.UseRouteError);
731
732 // If this was a render error, we put it in a RouteError context inside
733 // of RenderErrorBoundary
734 if (error) {
735 return error;
736 }
737
738 // Otherwise look for errors from our data router state
739 return (_state$errors = state.errors) == null ? void 0 : _state$errors[routeId];
740}
741
742/**
743 * Returns the happy-path data from the nearest ancestor <Await /> value
744 */
745function useAsyncValue() {
746 let value = React.useContext(AwaitContext);
747 return value == null ? void 0 : value._data;
748}
749
750/**
751 * Returns the error from the nearest ancestor <Await /> value
752 */
753function useAsyncError() {
754 let value = React.useContext(AwaitContext);
755 return value == null ? void 0 : value._error;
756}
757let blockerId = 0;
758
759/**
760 * Allow the application to block navigations within the SPA and present the
761 * user a confirmation dialog to confirm the navigation. Mostly used to avoid
762 * using half-filled form data. This does not handle hard-reloads or
763 * cross-origin navigations.
764 */
765function useBlocker(shouldBlock) {
766 let {
767 router
768 } = useDataRouterContext(DataRouterHook.UseBlocker);
769 let state = useDataRouterState(DataRouterStateHook.UseBlocker);
770 let [blockerKey] = React.useState(() => String(++blockerId));
771 let blockerFunction = React.useCallback(args => {
772 return typeof shouldBlock === "function" ? !!shouldBlock(args) : !!shouldBlock;
773 }, [shouldBlock]);
774 let blocker = router.getBlocker(blockerKey, blockerFunction);
775
776 // Cleanup on unmount
777 React.useEffect(() => () => router.deleteBlocker(blockerKey), [router, blockerKey]);
778
779 // Prefer the blocker from state since DataRouterContext is memoized so this
780 // ensures we update on blocker state updates
781 return state.blockers.get(blockerKey) || blocker;
782}
783
784/**
785 * Stable version of useNavigate that is used when we are in the context of
786 * a RouterProvider.
787 */
788function useNavigateStable() {
789 let {
790 router
791 } = useDataRouterContext(DataRouterHook.UseNavigateStable);
792 let id = useCurrentRouteId(DataRouterStateHook.UseNavigateStable);
793 let activeRef = React.useRef(false);
794 useIsomorphicLayoutEffect(() => {
795 activeRef.current = true;
796 });
797 let navigate = React.useCallback(function (to, options) {
798 if (options === void 0) {
799 options = {};
800 }
801 process.env.NODE_ENV !== "production" ? UNSAFE_warning(activeRef.current, navigateEffectWarning) : void 0;
802
803 // Short circuit here since if this happens on first render the navigate
804 // is useless because we haven't wired up our router subscriber yet
805 if (!activeRef.current) return;
806 if (typeof to === "number") {
807 router.navigate(to);
808 } else {
809 router.navigate(to, _extends({
810 fromRouteId: id
811 }, options));
812 }
813 }, [router, id]);
814 return navigate;
815}
816const alreadyWarned = {};
817function warningOnce(key, cond, message) {
818 if (!cond && !alreadyWarned[key]) {
819 alreadyWarned[key] = true;
820 process.env.NODE_ENV !== "production" ? UNSAFE_warning(false, message) : void 0;
821 }
822}
823
824// Webpack + React 17 fails to compile on the usage of `React.startTransition` or
825// `React["startTransition"]` even if it's behind a feature detection of
826// `"startTransition" in React`. Moving this to a constant avoids the issue :/
827const START_TRANSITION = "startTransition";
828
829/**
830 * Given a Remix Router instance, render the appropriate UI
831 */
832function RouterProvider(_ref) {
833 let {
834 fallbackElement,
835 router
836 } = _ref;
837 // Need to use a layout effect here so we are subscribed early enough to
838 // pick up on any render-driven redirects/navigations (useEffect/<Navigate>)
839 let [state, setStateImpl] = React.useState(router.state);
840 let setState = React.useCallback(newState => {
841 START_TRANSITION in React ? React[START_TRANSITION](() => setStateImpl(newState)) : setStateImpl(newState);
842 }, [setStateImpl]);
843 React.useLayoutEffect(() => router.subscribe(setState), [router, setState]);
844 let navigator = React.useMemo(() => {
845 return {
846 createHref: router.createHref,
847 encodeLocation: router.encodeLocation,
848 go: n => router.navigate(n),
849 push: (to, state, opts) => router.navigate(to, {
850 state,
851 preventScrollReset: opts == null ? void 0 : opts.preventScrollReset
852 }),
853 replace: (to, state, opts) => router.navigate(to, {
854 replace: true,
855 state,
856 preventScrollReset: opts == null ? void 0 : opts.preventScrollReset
857 })
858 };
859 }, [router]);
860 let basename = router.basename || "/";
861 let dataRouterContext = React.useMemo(() => ({
862 router,
863 navigator,
864 static: false,
865 basename
866 }), [router, navigator, basename]);
867
868 // The fragment and {null} here are important! We need them to keep React 18's
869 // useId happy when we are server-rendering since we may have a <script> here
870 // containing the hydrated server-side staticContext (from StaticRouterProvider).
871 // useId relies on the component tree structure to generate deterministic id's
872 // so we need to ensure it remains the same on the client even though
873 // we don't need the <script> tag
874 return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(DataRouterContext.Provider, {
875 value: dataRouterContext
876 }, /*#__PURE__*/React.createElement(DataRouterStateContext.Provider, {
877 value: state
878 }, /*#__PURE__*/React.createElement(Router, {
879 basename: basename,
880 location: state.location,
881 navigationType: state.historyAction,
882 navigator: navigator
883 }, state.initialized ? /*#__PURE__*/React.createElement(DataRoutes, {
884 routes: router.routes,
885 state: state
886 }) : fallbackElement))), null);
887}
888function DataRoutes(_ref2) {
889 let {
890 routes,
891 state
892 } = _ref2;
893 return useRoutesImpl(routes, undefined, state);
894}
895/**
896 * A <Router> that stores all entries in memory.
897 *
898 * @see https://reactrouter.com/router-components/memory-router
899 */
900function MemoryRouter(_ref3) {
901 let {
902 basename,
903 children,
904 initialEntries,
905 initialIndex
906 } = _ref3;
907 let historyRef = React.useRef();
908 if (historyRef.current == null) {
909 historyRef.current = createMemoryHistory({
910 initialEntries,
911 initialIndex,
912 v5Compat: true
913 });
914 }
915 let history = historyRef.current;
916 let [state, setStateImpl] = React.useState({
917 action: history.action,
918 location: history.location
919 });
920 let setState = React.useCallback(newState => {
921 START_TRANSITION in React ? React[START_TRANSITION](() => setStateImpl(newState)) : setStateImpl(newState);
922 }, [setStateImpl]);
923 React.useLayoutEffect(() => history.listen(setState), [history, setState]);
924 return /*#__PURE__*/React.createElement(Router, {
925 basename: basename,
926 children: children,
927 location: state.location,
928 navigationType: state.action,
929 navigator: history
930 });
931}
932/**
933 * Changes the current location.
934 *
935 * Note: This API is mostly useful in React.Component subclasses that are not
936 * able to use hooks. In functional components, we recommend you use the
937 * `useNavigate` hook instead.
938 *
939 * @see https://reactrouter.com/components/navigate
940 */
941function Navigate(_ref4) {
942 let {
943 to,
944 replace,
945 state,
946 relative
947 } = _ref4;
948 !useInRouterContext() ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of
949 // the router loaded. We can help them understand how to avoid that.
950 "<Navigate> may be used only in the context of a <Router> component.") : UNSAFE_invariant(false) : void 0;
951 process.env.NODE_ENV !== "production" ? UNSAFE_warning(!React.useContext(NavigationContext).static, "<Navigate> must not be used on the initial render in a <StaticRouter>. " + "This is a no-op, but you should modify your code so the <Navigate> is " + "only ever rendered in response to some user interaction or state change.") : void 0;
952 let {
953 matches
954 } = React.useContext(RouteContext);
955 let {
956 pathname: locationPathname
957 } = useLocation();
958 let navigate = useNavigate();
959
960 // Resolve the path outside of the effect so that when effects run twice in
961 // StrictMode they navigate to the same place
962 let path = resolveTo(to, UNSAFE_getPathContributingMatches(matches).map(match => match.pathnameBase), locationPathname, relative === "path");
963 let jsonPath = JSON.stringify(path);
964 React.useEffect(() => navigate(JSON.parse(jsonPath), {
965 replace,
966 state,
967 relative
968 }), [navigate, jsonPath, relative, replace, state]);
969 return null;
970}
971/**
972 * Renders the child route's element, if there is one.
973 *
974 * @see https://reactrouter.com/components/outlet
975 */
976function Outlet(props) {
977 return useOutlet(props.context);
978}
979/**
980 * Declares an element that should be rendered at a certain URL path.
981 *
982 * @see https://reactrouter.com/components/route
983 */
984function Route(_props) {
985 process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "A <Route> is only ever to be used as the child of <Routes> element, " + "never rendered directly. Please wrap your <Route> in a <Routes>.") : UNSAFE_invariant(false) ;
986}
987/**
988 * Provides location context for the rest of the app.
989 *
990 * Note: You usually won't render a <Router> directly. Instead, you'll render a
991 * router that is more specific to your environment such as a <BrowserRouter>
992 * in web browsers or a <StaticRouter> for server rendering.
993 *
994 * @see https://reactrouter.com/router-components/router
995 */
996function Router(_ref5) {
997 let {
998 basename: basenameProp = "/",
999 children = null,
1000 location: locationProp,
1001 navigationType = Action.Pop,
1002 navigator,
1003 static: staticProp = false
1004 } = _ref5;
1005 !!useInRouterContext() ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "You cannot render a <Router> inside another <Router>." + " You should never have more than one in your app.") : UNSAFE_invariant(false) : void 0;
1006
1007 // Preserve trailing slashes on basename, so we can let the user control
1008 // the enforcement of trailing slashes throughout the app
1009 let basename = basenameProp.replace(/^\/*/, "/");
1010 let navigationContext = React.useMemo(() => ({
1011 basename,
1012 navigator,
1013 static: staticProp
1014 }), [basename, navigator, staticProp]);
1015 if (typeof locationProp === "string") {
1016 locationProp = parsePath(locationProp);
1017 }
1018 let {
1019 pathname = "/",
1020 search = "",
1021 hash = "",
1022 state = null,
1023 key = "default"
1024 } = locationProp;
1025 let locationContext = React.useMemo(() => {
1026 let trailingPathname = stripBasename(pathname, basename);
1027 if (trailingPathname == null) {
1028 return null;
1029 }
1030 return {
1031 location: {
1032 pathname: trailingPathname,
1033 search,
1034 hash,
1035 state,
1036 key
1037 },
1038 navigationType
1039 };
1040 }, [basename, pathname, search, hash, state, key, navigationType]);
1041 process.env.NODE_ENV !== "production" ? UNSAFE_warning(locationContext != null, "<Router basename=\"" + basename + "\"> is not able to match the URL " + ("\"" + pathname + search + hash + "\" because it does not start with the ") + "basename, so the <Router> won't render anything.") : void 0;
1042 if (locationContext == null) {
1043 return null;
1044 }
1045 return /*#__PURE__*/React.createElement(NavigationContext.Provider, {
1046 value: navigationContext
1047 }, /*#__PURE__*/React.createElement(LocationContext.Provider, {
1048 children: children,
1049 value: locationContext
1050 }));
1051}
1052/**
1053 * A container for a nested tree of <Route> elements that renders the branch
1054 * that best matches the current location.
1055 *
1056 * @see https://reactrouter.com/components/routes
1057 */
1058function Routes(_ref6) {
1059 let {
1060 children,
1061 location
1062 } = _ref6;
1063 return useRoutes(createRoutesFromChildren(children), location);
1064}
1065/**
1066 * Component to use for rendering lazily loaded data from returning defer()
1067 * in a loader function
1068 */
1069function Await(_ref7) {
1070 let {
1071 children,
1072 errorElement,
1073 resolve
1074 } = _ref7;
1075 return /*#__PURE__*/React.createElement(AwaitErrorBoundary, {
1076 resolve: resolve,
1077 errorElement: errorElement
1078 }, /*#__PURE__*/React.createElement(ResolveAwait, null, children));
1079}
1080var AwaitRenderStatus;
1081(function (AwaitRenderStatus) {
1082 AwaitRenderStatus[AwaitRenderStatus["pending"] = 0] = "pending";
1083 AwaitRenderStatus[AwaitRenderStatus["success"] = 1] = "success";
1084 AwaitRenderStatus[AwaitRenderStatus["error"] = 2] = "error";
1085})(AwaitRenderStatus || (AwaitRenderStatus = {}));
1086const neverSettledPromise = new Promise(() => {});
1087class AwaitErrorBoundary extends React.Component {
1088 constructor(props) {
1089 super(props);
1090 this.state = {
1091 error: null
1092 };
1093 }
1094 static getDerivedStateFromError(error) {
1095 return {
1096 error
1097 };
1098 }
1099 componentDidCatch(error, errorInfo) {
1100 console.error("<Await> caught the following error during render", error, errorInfo);
1101 }
1102 render() {
1103 let {
1104 children,
1105 errorElement,
1106 resolve
1107 } = this.props;
1108 let promise = null;
1109 let status = AwaitRenderStatus.pending;
1110 if (!(resolve instanceof Promise)) {
1111 // Didn't get a promise - provide as a resolved promise
1112 status = AwaitRenderStatus.success;
1113 promise = Promise.resolve();
1114 Object.defineProperty(promise, "_tracked", {
1115 get: () => true
1116 });
1117 Object.defineProperty(promise, "_data", {
1118 get: () => resolve
1119 });
1120 } else if (this.state.error) {
1121 // Caught a render error, provide it as a rejected promise
1122 status = AwaitRenderStatus.error;
1123 let renderError = this.state.error;
1124 promise = Promise.reject().catch(() => {}); // Avoid unhandled rejection warnings
1125 Object.defineProperty(promise, "_tracked", {
1126 get: () => true
1127 });
1128 Object.defineProperty(promise, "_error", {
1129 get: () => renderError
1130 });
1131 } else if (resolve._tracked) {
1132 // Already tracked promise - check contents
1133 promise = resolve;
1134 status = promise._error !== undefined ? AwaitRenderStatus.error : promise._data !== undefined ? AwaitRenderStatus.success : AwaitRenderStatus.pending;
1135 } else {
1136 // Raw (untracked) promise - track it
1137 status = AwaitRenderStatus.pending;
1138 Object.defineProperty(resolve, "_tracked", {
1139 get: () => true
1140 });
1141 promise = resolve.then(data => Object.defineProperty(resolve, "_data", {
1142 get: () => data
1143 }), error => Object.defineProperty(resolve, "_error", {
1144 get: () => error
1145 }));
1146 }
1147 if (status === AwaitRenderStatus.error && promise._error instanceof AbortedDeferredError) {
1148 // Freeze the UI by throwing a never resolved promise
1149 throw neverSettledPromise;
1150 }
1151 if (status === AwaitRenderStatus.error && !errorElement) {
1152 // No errorElement, throw to the nearest route-level error boundary
1153 throw promise._error;
1154 }
1155 if (status === AwaitRenderStatus.error) {
1156 // Render via our errorElement
1157 return /*#__PURE__*/React.createElement(AwaitContext.Provider, {
1158 value: promise,
1159 children: errorElement
1160 });
1161 }
1162 if (status === AwaitRenderStatus.success) {
1163 // Render children with resolved value
1164 return /*#__PURE__*/React.createElement(AwaitContext.Provider, {
1165 value: promise,
1166 children: children
1167 });
1168 }
1169
1170 // Throw to the suspense boundary
1171 throw promise;
1172 }
1173}
1174
1175/**
1176 * @private
1177 * Indirection to leverage useAsyncValue for a render-prop API on <Await>
1178 */
1179function ResolveAwait(_ref8) {
1180 let {
1181 children
1182 } = _ref8;
1183 let data = useAsyncValue();
1184 let toRender = typeof children === "function" ? children(data) : children;
1185 return /*#__PURE__*/React.createElement(React.Fragment, null, toRender);
1186}
1187
1188///////////////////////////////////////////////////////////////////////////////
1189// UTILS
1190///////////////////////////////////////////////////////////////////////////////
1191
1192/**
1193 * Creates a route config from a React "children" object, which is usually
1194 * either a `<Route>` element or an array of them. Used internally by
1195 * `<Routes>` to create a route config from its children.
1196 *
1197 * @see https://reactrouter.com/utils/create-routes-from-children
1198 */
1199function createRoutesFromChildren(children, parentPath) {
1200 if (parentPath === void 0) {
1201 parentPath = [];
1202 }
1203 let routes = [];
1204 React.Children.forEach(children, (element, index) => {
1205 if (! /*#__PURE__*/React.isValidElement(element)) {
1206 // Ignore non-elements. This allows people to more easily inline
1207 // conditionals in their route config.
1208 return;
1209 }
1210 let treePath = [...parentPath, index];
1211 if (element.type === React.Fragment) {
1212 // Transparently support React.Fragment and its children.
1213 routes.push.apply(routes, createRoutesFromChildren(element.props.children, treePath));
1214 return;
1215 }
1216 !(element.type === Route) ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "[" + (typeof element.type === "string" ? element.type : element.type.name) + "] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>") : UNSAFE_invariant(false) : void 0;
1217 !(!element.props.index || !element.props.children) ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, "An index route cannot have child routes.") : UNSAFE_invariant(false) : void 0;
1218 let route = {
1219 id: element.props.id || treePath.join("-"),
1220 caseSensitive: element.props.caseSensitive,
1221 element: element.props.element,
1222 Component: element.props.Component,
1223 index: element.props.index,
1224 path: element.props.path,
1225 loader: element.props.loader,
1226 action: element.props.action,
1227 errorElement: element.props.errorElement,
1228 ErrorBoundary: element.props.ErrorBoundary,
1229 hasErrorBoundary: element.props.ErrorBoundary != null || element.props.errorElement != null,
1230 shouldRevalidate: element.props.shouldRevalidate,
1231 handle: element.props.handle,
1232 lazy: element.props.lazy
1233 };
1234 if (element.props.children) {
1235 route.children = createRoutesFromChildren(element.props.children, treePath);
1236 }
1237 routes.push(route);
1238 });
1239 return routes;
1240}
1241
1242/**
1243 * Renders the result of `matchRoutes()` into a React element.
1244 */
1245function renderMatches(matches) {
1246 return _renderMatches(matches);
1247}
1248
1249function mapRouteProperties(route) {
1250 let updates = {
1251 // Note: this check also occurs in createRoutesFromChildren so update
1252 // there if you change this -- please and thank you!
1253 hasErrorBoundary: route.ErrorBoundary != null || route.errorElement != null
1254 };
1255 if (route.Component) {
1256 if (process.env.NODE_ENV !== "production") {
1257 if (route.element) {
1258 process.env.NODE_ENV !== "production" ? UNSAFE_warning(false, "You should not include both `Component` and `element` on your route - " + "`Component` will be used.") : void 0;
1259 }
1260 }
1261 Object.assign(updates, {
1262 element: /*#__PURE__*/React.createElement(route.Component),
1263 Component: undefined
1264 });
1265 }
1266 if (route.ErrorBoundary) {
1267 if (process.env.NODE_ENV !== "production") {
1268 if (route.errorElement) {
1269 process.env.NODE_ENV !== "production" ? UNSAFE_warning(false, "You should not include both `ErrorBoundary` and `errorElement` on your route - " + "`ErrorBoundary` will be used.") : void 0;
1270 }
1271 }
1272 Object.assign(updates, {
1273 errorElement: /*#__PURE__*/React.createElement(route.ErrorBoundary),
1274 ErrorBoundary: undefined
1275 });
1276 }
1277 return updates;
1278}
1279function createMemoryRouter(routes, opts) {
1280 return createRouter({
1281 basename: opts == null ? void 0 : opts.basename,
1282 future: _extends({}, opts == null ? void 0 : opts.future, {
1283 v7_prependBasename: true
1284 }),
1285 history: createMemoryHistory({
1286 initialEntries: opts == null ? void 0 : opts.initialEntries,
1287 initialIndex: opts == null ? void 0 : opts.initialIndex
1288 }),
1289 hydrationData: opts == null ? void 0 : opts.hydrationData,
1290 routes,
1291 mapRouteProperties
1292 }).initialize();
1293}
1294
1295export { Await, MemoryRouter, Navigate, Outlet, Route, Router, RouterProvider, Routes, DataRouterContext as UNSAFE_DataRouterContext, DataRouterStateContext as UNSAFE_DataRouterStateContext, LocationContext as UNSAFE_LocationContext, NavigationContext as UNSAFE_NavigationContext, RouteContext as UNSAFE_RouteContext, mapRouteProperties as UNSAFE_mapRouteProperties, useRouteId as UNSAFE_useRouteId, useRoutesImpl as UNSAFE_useRoutesImpl, createMemoryRouter, createRoutesFromChildren, createRoutesFromChildren as createRoutesFromElements, renderMatches, useBlocker as unstable_useBlocker, useActionData, useAsyncError, useAsyncValue, useHref, useInRouterContext, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes };
1296//# sourceMappingURL=index.js.map