UNPKG

53.2 kBJavaScriptView Raw
1/**
2 * React Router v6.19.0
3 *
4 * Copyright (c) Remix Software Inc.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE.md file in the root directory of this source tree.
8 *
9 * @license MIT
10 */
11import * as React from 'react';
12import { UNSAFE_invariant, joinPaths, matchPath, UNSAFE_getPathContributingMatches, UNSAFE_warning, resolveTo, parsePath, matchRoutes, Action, UNSAFE_convertRouteMatchToUiMatch, stripBasename, IDLE_BLOCKER, isRouteErrorResponse, createMemoryHistory, AbortedDeferredError, createRouter } from '@remix-run/router';
13export { AbortedDeferredError, Action as NavigationType, createPath, defer, generatePath, isRouteErrorResponse, json, matchPath, matchRoutes, parsePath, redirect, redirectDocument, 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
305 // Use the full pathname for the leaf match so we include splat values
306 // for "." links
307 let routePathnamesJson = JSON.stringify(UNSAFE_getPathContributingMatches(matches).map((match, idx) => idx === matches.length - 1 ? match.pathname : match.pathnameBase));
308 return React.useMemo(() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, relative === "path"), [to, routePathnamesJson, locationPathname, relative]);
309}
310
311/**
312 * Returns the element of the route that matched the current location, prepared
313 * with the correct context to render the remainder of the route tree. Route
314 * elements in the tree must render an `<Outlet>` to render their child route's
315 * element.
316 *
317 * @see https://reactrouter.com/hooks/use-routes
318 */
319function useRoutes(routes, locationArg) {
320 return useRoutesImpl(routes, locationArg);
321}
322
323// Internal implementation with accept optional param for RouterProvider usage
324function useRoutesImpl(routes, locationArg, dataRouterState) {
325 !useInRouterContext() ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
326 // router loaded. We can help them understand how to avoid that.
327 "useRoutes() may be used only in the context of a <Router> component.") : UNSAFE_invariant(false) : void 0;
328 let {
329 navigator
330 } = React.useContext(NavigationContext);
331 let {
332 matches: parentMatches
333 } = React.useContext(RouteContext);
334 let routeMatch = parentMatches[parentMatches.length - 1];
335 let parentParams = routeMatch ? routeMatch.params : {};
336 let parentPathname = routeMatch ? routeMatch.pathname : "/";
337 let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : "/";
338 let parentRoute = routeMatch && routeMatch.route;
339 if (process.env.NODE_ENV !== "production") {
340 // You won't get a warning about 2 different <Routes> under a <Route>
341 // without a trailing *, but this is a best-effort warning anyway since we
342 // cannot even give the warning unless they land at the parent route.
343 //
344 // Example:
345 //
346 // <Routes>
347 // {/* This route path MUST end with /* because otherwise
348 // it will never match /blog/post/123 */}
349 // <Route path="blog" element={<Blog />} />
350 // <Route path="blog/feed" element={<BlogFeed />} />
351 // </Routes>
352 //
353 // function Blog() {
354 // return (
355 // <Routes>
356 // <Route path="post/:id" element={<Post />} />
357 // </Routes>
358 // );
359 // }
360 let parentPath = parentRoute && parentRoute.path || "";
361 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 + "/*") + "\">."));
362 }
363 let locationFromContext = useLocation();
364 let location;
365 if (locationArg) {
366 var _parsedLocationArg$pa;
367 let parsedLocationArg = typeof locationArg === "string" ? parsePath(locationArg) : locationArg;
368 !(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;
369 location = parsedLocationArg;
370 } else {
371 location = locationFromContext;
372 }
373 let pathname = location.pathname || "/";
374 let remainingPathname = parentPathnameBase === "/" ? pathname : pathname.slice(parentPathnameBase.length) || "/";
375 let matches = matchRoutes(routes, {
376 pathname: remainingPathname
377 });
378 if (process.env.NODE_ENV !== "production") {
379 process.env.NODE_ENV !== "production" ? UNSAFE_warning(parentRoute || matches != null, "No routes matched location \"" + location.pathname + location.search + location.hash + "\" ") : void 0;
380 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;
381 }
382 let renderedMatches = _renderMatches(matches && matches.map(match => Object.assign({}, match, {
383 params: Object.assign({}, parentParams, match.params),
384 pathname: joinPaths([parentPathnameBase,
385 // Re-encode pathnames that were decoded inside matchRoutes
386 navigator.encodeLocation ? navigator.encodeLocation(match.pathname).pathname : match.pathname]),
387 pathnameBase: match.pathnameBase === "/" ? parentPathnameBase : joinPaths([parentPathnameBase,
388 // Re-encode pathnames that were decoded inside matchRoutes
389 navigator.encodeLocation ? navigator.encodeLocation(match.pathnameBase).pathname : match.pathnameBase])
390 })), parentMatches, dataRouterState);
391
392 // When a user passes in a `locationArg`, the associated routes need to
393 // be wrapped in a new `LocationContext.Provider` in order for `useLocation`
394 // to use the scoped location instead of the global location.
395 if (locationArg && renderedMatches) {
396 return /*#__PURE__*/React.createElement(LocationContext.Provider, {
397 value: {
398 location: _extends({
399 pathname: "/",
400 search: "",
401 hash: "",
402 state: null,
403 key: "default"
404 }, location),
405 navigationType: Action.Pop
406 }
407 }, renderedMatches);
408 }
409 return renderedMatches;
410}
411function DefaultErrorComponent() {
412 let error = useRouteError();
413 let message = isRouteErrorResponse(error) ? error.status + " " + error.statusText : error instanceof Error ? error.message : JSON.stringify(error);
414 let stack = error instanceof Error ? error.stack : null;
415 let lightgrey = "rgba(200,200,200, 0.5)";
416 let preStyles = {
417 padding: "0.5rem",
418 backgroundColor: lightgrey
419 };
420 let codeStyles = {
421 padding: "2px 4px",
422 backgroundColor: lightgrey
423 };
424 let devInfo = null;
425 if (process.env.NODE_ENV !== "production") {
426 console.error("Error handled by React Router default ErrorBoundary:", error);
427 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", {
428 style: codeStyles
429 }, "ErrorBoundary"), " or", " ", /*#__PURE__*/React.createElement("code", {
430 style: codeStyles
431 }, "errorElement"), " prop on your route."));
432 }
433 return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("h2", null, "Unexpected Application Error!"), /*#__PURE__*/React.createElement("h3", {
434 style: {
435 fontStyle: "italic"
436 }
437 }, message), stack ? /*#__PURE__*/React.createElement("pre", {
438 style: preStyles
439 }, stack) : null, devInfo);
440}
441const defaultErrorElement = /*#__PURE__*/React.createElement(DefaultErrorComponent, null);
442class RenderErrorBoundary extends React.Component {
443 constructor(props) {
444 super(props);
445 this.state = {
446 location: props.location,
447 revalidation: props.revalidation,
448 error: props.error
449 };
450 }
451 static getDerivedStateFromError(error) {
452 return {
453 error: error
454 };
455 }
456 static getDerivedStateFromProps(props, state) {
457 // When we get into an error state, the user will likely click "back" to the
458 // previous page that didn't have an error. Because this wraps the entire
459 // application, that will have no effect--the error page continues to display.
460 // This gives us a mechanism to recover from the error when the location changes.
461 //
462 // Whether we're in an error state or not, we update the location in state
463 // so that when we are in an error state, it gets reset when a new location
464 // comes in and the user recovers from the error.
465 if (state.location !== props.location || state.revalidation !== "idle" && props.revalidation === "idle") {
466 return {
467 error: props.error,
468 location: props.location,
469 revalidation: props.revalidation
470 };
471 }
472
473 // If we're not changing locations, preserve the location but still surface
474 // any new errors that may come through. We retain the existing error, we do
475 // this because the error provided from the app state may be cleared without
476 // the location changing.
477 return {
478 error: props.error || state.error,
479 location: state.location,
480 revalidation: props.revalidation || state.revalidation
481 };
482 }
483 componentDidCatch(error, errorInfo) {
484 console.error("React Router caught the following error during render", error, errorInfo);
485 }
486 render() {
487 return this.state.error ? /*#__PURE__*/React.createElement(RouteContext.Provider, {
488 value: this.props.routeContext
489 }, /*#__PURE__*/React.createElement(RouteErrorContext.Provider, {
490 value: this.state.error,
491 children: this.props.component
492 })) : this.props.children;
493 }
494}
495function RenderedRoute(_ref) {
496 let {
497 routeContext,
498 match,
499 children
500 } = _ref;
501 let dataRouterContext = React.useContext(DataRouterContext);
502
503 // Track how deep we got in our render pass to emulate SSR componentDidCatch
504 // in a DataStaticRouter
505 if (dataRouterContext && dataRouterContext.static && dataRouterContext.staticContext && (match.route.errorElement || match.route.ErrorBoundary)) {
506 dataRouterContext.staticContext._deepestRenderedBoundaryId = match.route.id;
507 }
508 return /*#__PURE__*/React.createElement(RouteContext.Provider, {
509 value: routeContext
510 }, children);
511}
512function _renderMatches(matches, parentMatches, dataRouterState) {
513 var _dataRouterState2;
514 if (parentMatches === void 0) {
515 parentMatches = [];
516 }
517 if (dataRouterState === void 0) {
518 dataRouterState = null;
519 }
520 if (matches == null) {
521 var _dataRouterState;
522 if ((_dataRouterState = dataRouterState) != null && _dataRouterState.errors) {
523 // Don't bail if we have data router errors so we can render them in the
524 // boundary. Use the pre-matched (or shimmed) matches
525 matches = dataRouterState.matches;
526 } else {
527 return null;
528 }
529 }
530 let renderedMatches = matches;
531
532 // If we have data errors, trim matches to the highest error boundary
533 let errors = (_dataRouterState2 = dataRouterState) == null ? void 0 : _dataRouterState2.errors;
534 if (errors != null) {
535 let errorIndex = renderedMatches.findIndex(m => m.route.id && (errors == null ? void 0 : errors[m.route.id]));
536 !(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;
537 renderedMatches = renderedMatches.slice(0, Math.min(renderedMatches.length, errorIndex + 1));
538 }
539 return renderedMatches.reduceRight((outlet, match, index) => {
540 let error = match.route.id ? errors == null ? void 0 : errors[match.route.id] : null;
541 // Only data routers handle errors
542 let errorElement = null;
543 if (dataRouterState) {
544 errorElement = match.route.errorElement || defaultErrorElement;
545 }
546 let matches = parentMatches.concat(renderedMatches.slice(0, index + 1));
547 let getChildren = () => {
548 let children;
549 if (error) {
550 children = errorElement;
551 } else if (match.route.Component) {
552 // Note: This is a de-optimized path since React won't re-use the
553 // ReactElement since it's identity changes with each new
554 // React.createElement call. We keep this so folks can use
555 // `<Route Component={...}>` in `<Routes>` but generally `Component`
556 // usage is only advised in `RouterProvider` when we can convert it to
557 // `element` ahead of time.
558 children = /*#__PURE__*/React.createElement(match.route.Component, null);
559 } else if (match.route.element) {
560 children = match.route.element;
561 } else {
562 children = outlet;
563 }
564 return /*#__PURE__*/React.createElement(RenderedRoute, {
565 match: match,
566 routeContext: {
567 outlet,
568 matches,
569 isDataRoute: dataRouterState != null
570 },
571 children: children
572 });
573 };
574 // Only wrap in an error boundary within data router usages when we have an
575 // ErrorBoundary/errorElement on this route. Otherwise let it bubble up to
576 // an ancestor ErrorBoundary/errorElement
577 return dataRouterState && (match.route.ErrorBoundary || match.route.errorElement || index === 0) ? /*#__PURE__*/React.createElement(RenderErrorBoundary, {
578 location: dataRouterState.location,
579 revalidation: dataRouterState.revalidation,
580 component: errorElement,
581 error: error,
582 children: getChildren(),
583 routeContext: {
584 outlet: null,
585 matches,
586 isDataRoute: true
587 }
588 }) : getChildren();
589 }, null);
590}
591var DataRouterHook = /*#__PURE__*/function (DataRouterHook) {
592 DataRouterHook["UseBlocker"] = "useBlocker";
593 DataRouterHook["UseRevalidator"] = "useRevalidator";
594 DataRouterHook["UseNavigateStable"] = "useNavigate";
595 return DataRouterHook;
596}(DataRouterHook || {});
597var DataRouterStateHook = /*#__PURE__*/function (DataRouterStateHook) {
598 DataRouterStateHook["UseBlocker"] = "useBlocker";
599 DataRouterStateHook["UseLoaderData"] = "useLoaderData";
600 DataRouterStateHook["UseActionData"] = "useActionData";
601 DataRouterStateHook["UseRouteError"] = "useRouteError";
602 DataRouterStateHook["UseNavigation"] = "useNavigation";
603 DataRouterStateHook["UseRouteLoaderData"] = "useRouteLoaderData";
604 DataRouterStateHook["UseMatches"] = "useMatches";
605 DataRouterStateHook["UseRevalidator"] = "useRevalidator";
606 DataRouterStateHook["UseNavigateStable"] = "useNavigate";
607 DataRouterStateHook["UseRouteId"] = "useRouteId";
608 return DataRouterStateHook;
609}(DataRouterStateHook || {});
610function getDataRouterConsoleError(hookName) {
611 return hookName + " must be used within a data router. See https://reactrouter.com/routers/picking-a-router.";
612}
613function useDataRouterContext(hookName) {
614 let ctx = React.useContext(DataRouterContext);
615 !ctx ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, getDataRouterConsoleError(hookName)) : UNSAFE_invariant(false) : void 0;
616 return ctx;
617}
618function useDataRouterState(hookName) {
619 let state = React.useContext(DataRouterStateContext);
620 !state ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, getDataRouterConsoleError(hookName)) : UNSAFE_invariant(false) : void 0;
621 return state;
622}
623function useRouteContext(hookName) {
624 let route = React.useContext(RouteContext);
625 !route ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, getDataRouterConsoleError(hookName)) : UNSAFE_invariant(false) : void 0;
626 return route;
627}
628
629// Internal version with hookName-aware debugging
630function useCurrentRouteId(hookName) {
631 let route = useRouteContext(hookName);
632 let thisRoute = route.matches[route.matches.length - 1];
633 !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;
634 return thisRoute.route.id;
635}
636
637/**
638 * Returns the ID for the nearest contextual route
639 */
640function useRouteId() {
641 return useCurrentRouteId(DataRouterStateHook.UseRouteId);
642}
643
644/**
645 * Returns the current navigation, defaulting to an "idle" navigation when
646 * no navigation is in progress
647 */
648function useNavigation() {
649 let state = useDataRouterState(DataRouterStateHook.UseNavigation);
650 return state.navigation;
651}
652
653/**
654 * Returns a revalidate function for manually triggering revalidation, as well
655 * as the current state of any manual revalidations
656 */
657function useRevalidator() {
658 let dataRouterContext = useDataRouterContext(DataRouterHook.UseRevalidator);
659 let state = useDataRouterState(DataRouterStateHook.UseRevalidator);
660 return React.useMemo(() => ({
661 revalidate: dataRouterContext.router.revalidate,
662 state: state.revalidation
663 }), [dataRouterContext.router.revalidate, state.revalidation]);
664}
665
666/**
667 * Returns the active route matches, useful for accessing loaderData for
668 * parent/child routes or the route "handle" property
669 */
670function useMatches() {
671 let {
672 matches,
673 loaderData
674 } = useDataRouterState(DataRouterStateHook.UseMatches);
675 return React.useMemo(() => matches.map(m => UNSAFE_convertRouteMatchToUiMatch(m, loaderData)), [matches, loaderData]);
676}
677
678/**
679 * Returns the loader data for the nearest ancestor Route loader
680 */
681function useLoaderData() {
682 let state = useDataRouterState(DataRouterStateHook.UseLoaderData);
683 let routeId = useCurrentRouteId(DataRouterStateHook.UseLoaderData);
684 if (state.errors && state.errors[routeId] != null) {
685 console.error("You cannot `useLoaderData` in an errorElement (routeId: " + routeId + ")");
686 return undefined;
687 }
688 return state.loaderData[routeId];
689}
690
691/**
692 * Returns the loaderData for the given routeId
693 */
694function useRouteLoaderData(routeId) {
695 let state = useDataRouterState(DataRouterStateHook.UseRouteLoaderData);
696 return state.loaderData[routeId];
697}
698
699/**
700 * Returns the action data for the nearest ancestor Route action
701 */
702function useActionData() {
703 let state = useDataRouterState(DataRouterStateHook.UseActionData);
704 let routeId = useCurrentRouteId(DataRouterStateHook.UseLoaderData);
705 return state.actionData ? state.actionData[routeId] : undefined;
706}
707
708/**
709 * Returns the nearest ancestor Route error, which could be a loader/action
710 * error or a render error. This is intended to be called from your
711 * ErrorBoundary/errorElement to display a proper error message.
712 */
713function useRouteError() {
714 var _state$errors;
715 let error = React.useContext(RouteErrorContext);
716 let state = useDataRouterState(DataRouterStateHook.UseRouteError);
717 let routeId = useCurrentRouteId(DataRouterStateHook.UseRouteError);
718
719 // If this was a render error, we put it in a RouteError context inside
720 // of RenderErrorBoundary
721 if (error) {
722 return error;
723 }
724
725 // Otherwise look for errors from our data router state
726 return (_state$errors = state.errors) == null ? void 0 : _state$errors[routeId];
727}
728
729/**
730 * Returns the happy-path data from the nearest ancestor `<Await />` value
731 */
732function useAsyncValue() {
733 let value = React.useContext(AwaitContext);
734 return value == null ? void 0 : value._data;
735}
736
737/**
738 * Returns the error from the nearest ancestor `<Await />` value
739 */
740function useAsyncError() {
741 let value = React.useContext(AwaitContext);
742 return value == null ? void 0 : value._error;
743}
744let blockerId = 0;
745
746/**
747 * Allow the application to block navigations within the SPA and present the
748 * user a confirmation dialog to confirm the navigation. Mostly used to avoid
749 * using half-filled form data. This does not handle hard-reloads or
750 * cross-origin navigations.
751 */
752function useBlocker(shouldBlock) {
753 let {
754 router,
755 basename
756 } = useDataRouterContext(DataRouterHook.UseBlocker);
757 let state = useDataRouterState(DataRouterStateHook.UseBlocker);
758 let [blockerKey, setBlockerKey] = React.useState("");
759 let blockerFunction = React.useCallback(arg => {
760 if (typeof shouldBlock !== "function") {
761 return !!shouldBlock;
762 }
763 if (basename === "/") {
764 return shouldBlock(arg);
765 }
766
767 // If they provided us a function and we've got an active basename, strip
768 // it from the locations we expose to the user to match the behavior of
769 // useLocation
770 let {
771 currentLocation,
772 nextLocation,
773 historyAction
774 } = arg;
775 return shouldBlock({
776 currentLocation: _extends({}, currentLocation, {
777 pathname: stripBasename(currentLocation.pathname, basename) || currentLocation.pathname
778 }),
779 nextLocation: _extends({}, nextLocation, {
780 pathname: stripBasename(nextLocation.pathname, basename) || nextLocation.pathname
781 }),
782 historyAction
783 });
784 }, [basename, shouldBlock]);
785
786 // This effect is in charge of blocker key assignment and deletion (which is
787 // tightly coupled to the key)
788 React.useEffect(() => {
789 let key = String(++blockerId);
790 setBlockerKey(key);
791 return () => router.deleteBlocker(key);
792 }, [router]);
793
794 // This effect handles assigning the blockerFunction. This is to handle
795 // unstable blocker function identities, and happens only after the prior
796 // effect so we don't get an orphaned blockerFunction in the router with a
797 // key of "". Until then we just have the IDLE_BLOCKER.
798 React.useEffect(() => {
799 if (blockerKey !== "") {
800 router.getBlocker(blockerKey, blockerFunction);
801 }
802 }, [router, blockerKey, blockerFunction]);
803
804 // Prefer the blocker from `state` not `router.state` since DataRouterContext
805 // is memoized so this ensures we update on blocker state updates
806 return blockerKey && state.blockers.has(blockerKey) ? state.blockers.get(blockerKey) : IDLE_BLOCKER;
807}
808
809/**
810 * Stable version of useNavigate that is used when we are in the context of
811 * a RouterProvider.
812 */
813function useNavigateStable() {
814 let {
815 router
816 } = useDataRouterContext(DataRouterHook.UseNavigateStable);
817 let id = useCurrentRouteId(DataRouterStateHook.UseNavigateStable);
818 let activeRef = React.useRef(false);
819 useIsomorphicLayoutEffect(() => {
820 activeRef.current = true;
821 });
822 let navigate = React.useCallback(function (to, options) {
823 if (options === void 0) {
824 options = {};
825 }
826 process.env.NODE_ENV !== "production" ? UNSAFE_warning(activeRef.current, navigateEffectWarning) : void 0;
827
828 // Short circuit here since if this happens on first render the navigate
829 // is useless because we haven't wired up our router subscriber yet
830 if (!activeRef.current) return;
831 if (typeof to === "number") {
832 router.navigate(to);
833 } else {
834 router.navigate(to, _extends({
835 fromRouteId: id
836 }, options));
837 }
838 }, [router, id]);
839 return navigate;
840}
841const alreadyWarned = {};
842function warningOnce(key, cond, message) {
843 if (!cond && !alreadyWarned[key]) {
844 alreadyWarned[key] = true;
845 process.env.NODE_ENV !== "production" ? UNSAFE_warning(false, message) : void 0;
846 }
847}
848
849/**
850 Webpack + React 17 fails to compile on any of the following because webpack
851 complains that `startTransition` doesn't exist in `React`:
852 * import { startTransition } from "react"
853 * import * as React from from "react";
854 "startTransition" in React ? React.startTransition(() => setState()) : setState()
855 * import * as React from from "react";
856 "startTransition" in React ? React["startTransition"](() => setState()) : setState()
857
858 Moving it to a constant such as the following solves the Webpack/React 17 issue:
859 * import * as React from from "react";
860 const START_TRANSITION = "startTransition";
861 START_TRANSITION in React ? React[START_TRANSITION](() => setState()) : setState()
862
863 However, that introduces webpack/terser minification issues in production builds
864 in React 18 where minification/obfuscation ends up removing the call of
865 React.startTransition entirely from the first half of the ternary. Grabbing
866 this exported reference once up front resolves that issue.
867
868 See https://github.com/remix-run/react-router/issues/10579
869*/
870const START_TRANSITION = "startTransition";
871const startTransitionImpl = React[START_TRANSITION];
872
873/**
874 * Given a Remix Router instance, render the appropriate UI
875 */
876function RouterProvider(_ref) {
877 let {
878 fallbackElement,
879 router,
880 future
881 } = _ref;
882 let [state, setStateImpl] = React.useState(router.state);
883 let {
884 v7_startTransition
885 } = future || {};
886 let setState = React.useCallback(newState => {
887 if (v7_startTransition && startTransitionImpl) {
888 startTransitionImpl(() => setStateImpl(newState));
889 } else {
890 setStateImpl(newState);
891 }
892 }, [setStateImpl, v7_startTransition]);
893
894 // Need to use a layout effect here so we are subscribed early enough to
895 // pick up on any render-driven redirects/navigations (useEffect/<Navigate>)
896 React.useLayoutEffect(() => router.subscribe(setState), [router, setState]);
897 let navigator = React.useMemo(() => {
898 return {
899 createHref: router.createHref,
900 encodeLocation: router.encodeLocation,
901 go: n => router.navigate(n),
902 push: (to, state, opts) => router.navigate(to, {
903 state,
904 preventScrollReset: opts == null ? void 0 : opts.preventScrollReset
905 }),
906 replace: (to, state, opts) => router.navigate(to, {
907 replace: true,
908 state,
909 preventScrollReset: opts == null ? void 0 : opts.preventScrollReset
910 })
911 };
912 }, [router]);
913 let basename = router.basename || "/";
914 let dataRouterContext = React.useMemo(() => ({
915 router,
916 navigator,
917 static: false,
918 basename
919 }), [router, navigator, basename]);
920
921 // The fragment and {null} here are important! We need them to keep React 18's
922 // useId happy when we are server-rendering since we may have a <script> here
923 // containing the hydrated server-side staticContext (from StaticRouterProvider).
924 // useId relies on the component tree structure to generate deterministic id's
925 // so we need to ensure it remains the same on the client even though
926 // we don't need the <script> tag
927 return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(DataRouterContext.Provider, {
928 value: dataRouterContext
929 }, /*#__PURE__*/React.createElement(DataRouterStateContext.Provider, {
930 value: state
931 }, /*#__PURE__*/React.createElement(Router, {
932 basename: basename,
933 location: state.location,
934 navigationType: state.historyAction,
935 navigator: navigator
936 }, state.initialized ? /*#__PURE__*/React.createElement(DataRoutes, {
937 routes: router.routes,
938 state: state
939 }) : fallbackElement))), null);
940}
941function DataRoutes(_ref2) {
942 let {
943 routes,
944 state
945 } = _ref2;
946 return useRoutesImpl(routes, undefined, state);
947}
948/**
949 * A `<Router>` that stores all entries in memory.
950 *
951 * @see https://reactrouter.com/router-components/memory-router
952 */
953function MemoryRouter(_ref3) {
954 let {
955 basename,
956 children,
957 initialEntries,
958 initialIndex,
959 future
960 } = _ref3;
961 let historyRef = React.useRef();
962 if (historyRef.current == null) {
963 historyRef.current = createMemoryHistory({
964 initialEntries,
965 initialIndex,
966 v5Compat: true
967 });
968 }
969 let history = historyRef.current;
970 let [state, setStateImpl] = React.useState({
971 action: history.action,
972 location: history.location
973 });
974 let {
975 v7_startTransition
976 } = future || {};
977 let setState = React.useCallback(newState => {
978 v7_startTransition && startTransitionImpl ? startTransitionImpl(() => setStateImpl(newState)) : setStateImpl(newState);
979 }, [setStateImpl, v7_startTransition]);
980 React.useLayoutEffect(() => history.listen(setState), [history, setState]);
981 return /*#__PURE__*/React.createElement(Router, {
982 basename: basename,
983 children: children,
984 location: state.location,
985 navigationType: state.action,
986 navigator: history
987 });
988}
989/**
990 * Changes the current location.
991 *
992 * Note: This API is mostly useful in React.Component subclasses that are not
993 * able to use hooks. In functional components, we recommend you use the
994 * `useNavigate` hook instead.
995 *
996 * @see https://reactrouter.com/components/navigate
997 */
998function Navigate(_ref4) {
999 let {
1000 to,
1001 replace,
1002 state,
1003 relative
1004 } = _ref4;
1005 !useInRouterContext() ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of
1006 // the router loaded. We can help them understand how to avoid that.
1007 "<Navigate> may be used only in the context of a <Router> component.") : UNSAFE_invariant(false) : void 0;
1008 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;
1009 let {
1010 matches
1011 } = React.useContext(RouteContext);
1012 let {
1013 pathname: locationPathname
1014 } = useLocation();
1015 let navigate = useNavigate();
1016
1017 // Resolve the path outside of the effect so that when effects run twice in
1018 // StrictMode they navigate to the same place
1019 let path = resolveTo(to, UNSAFE_getPathContributingMatches(matches).map(match => match.pathnameBase), locationPathname, relative === "path");
1020 let jsonPath = JSON.stringify(path);
1021 React.useEffect(() => navigate(JSON.parse(jsonPath), {
1022 replace,
1023 state,
1024 relative
1025 }), [navigate, jsonPath, relative, replace, state]);
1026 return null;
1027}
1028/**
1029 * Renders the child route's element, if there is one.
1030 *
1031 * @see https://reactrouter.com/components/outlet
1032 */
1033function Outlet(props) {
1034 return useOutlet(props.context);
1035}
1036/**
1037 * Declares an element that should be rendered at a certain URL path.
1038 *
1039 * @see https://reactrouter.com/components/route
1040 */
1041function Route(_props) {
1042 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) ;
1043}
1044/**
1045 * Provides location context for the rest of the app.
1046 *
1047 * Note: You usually won't render a `<Router>` directly. Instead, you'll render a
1048 * router that is more specific to your environment such as a `<BrowserRouter>`
1049 * in web browsers or a `<StaticRouter>` for server rendering.
1050 *
1051 * @see https://reactrouter.com/router-components/router
1052 */
1053function Router(_ref5) {
1054 let {
1055 basename: basenameProp = "/",
1056 children = null,
1057 location: locationProp,
1058 navigationType = Action.Pop,
1059 navigator,
1060 static: staticProp = false
1061 } = _ref5;
1062 !!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;
1063
1064 // Preserve trailing slashes on basename, so we can let the user control
1065 // the enforcement of trailing slashes throughout the app
1066 let basename = basenameProp.replace(/^\/*/, "/");
1067 let navigationContext = React.useMemo(() => ({
1068 basename,
1069 navigator,
1070 static: staticProp
1071 }), [basename, navigator, staticProp]);
1072 if (typeof locationProp === "string") {
1073 locationProp = parsePath(locationProp);
1074 }
1075 let {
1076 pathname = "/",
1077 search = "",
1078 hash = "",
1079 state = null,
1080 key = "default"
1081 } = locationProp;
1082 let locationContext = React.useMemo(() => {
1083 let trailingPathname = stripBasename(pathname, basename);
1084 if (trailingPathname == null) {
1085 return null;
1086 }
1087 return {
1088 location: {
1089 pathname: trailingPathname,
1090 search,
1091 hash,
1092 state,
1093 key
1094 },
1095 navigationType
1096 };
1097 }, [basename, pathname, search, hash, state, key, navigationType]);
1098 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;
1099 if (locationContext == null) {
1100 return null;
1101 }
1102 return /*#__PURE__*/React.createElement(NavigationContext.Provider, {
1103 value: navigationContext
1104 }, /*#__PURE__*/React.createElement(LocationContext.Provider, {
1105 children: children,
1106 value: locationContext
1107 }));
1108}
1109/**
1110 * A container for a nested tree of `<Route>` elements that renders the branch
1111 * that best matches the current location.
1112 *
1113 * @see https://reactrouter.com/components/routes
1114 */
1115function Routes(_ref6) {
1116 let {
1117 children,
1118 location
1119 } = _ref6;
1120 return useRoutes(createRoutesFromChildren(children), location);
1121}
1122/**
1123 * Component to use for rendering lazily loaded data from returning defer()
1124 * in a loader function
1125 */
1126function Await(_ref7) {
1127 let {
1128 children,
1129 errorElement,
1130 resolve
1131 } = _ref7;
1132 return /*#__PURE__*/React.createElement(AwaitErrorBoundary, {
1133 resolve: resolve,
1134 errorElement: errorElement
1135 }, /*#__PURE__*/React.createElement(ResolveAwait, null, children));
1136}
1137var AwaitRenderStatus = /*#__PURE__*/function (AwaitRenderStatus) {
1138 AwaitRenderStatus[AwaitRenderStatus["pending"] = 0] = "pending";
1139 AwaitRenderStatus[AwaitRenderStatus["success"] = 1] = "success";
1140 AwaitRenderStatus[AwaitRenderStatus["error"] = 2] = "error";
1141 return AwaitRenderStatus;
1142}(AwaitRenderStatus || {});
1143const neverSettledPromise = new Promise(() => {});
1144class AwaitErrorBoundary extends React.Component {
1145 constructor(props) {
1146 super(props);
1147 this.state = {
1148 error: null
1149 };
1150 }
1151 static getDerivedStateFromError(error) {
1152 return {
1153 error
1154 };
1155 }
1156 componentDidCatch(error, errorInfo) {
1157 console.error("<Await> caught the following error during render", error, errorInfo);
1158 }
1159 render() {
1160 let {
1161 children,
1162 errorElement,
1163 resolve
1164 } = this.props;
1165 let promise = null;
1166 let status = AwaitRenderStatus.pending;
1167 if (!(resolve instanceof Promise)) {
1168 // Didn't get a promise - provide as a resolved promise
1169 status = AwaitRenderStatus.success;
1170 promise = Promise.resolve();
1171 Object.defineProperty(promise, "_tracked", {
1172 get: () => true
1173 });
1174 Object.defineProperty(promise, "_data", {
1175 get: () => resolve
1176 });
1177 } else if (this.state.error) {
1178 // Caught a render error, provide it as a rejected promise
1179 status = AwaitRenderStatus.error;
1180 let renderError = this.state.error;
1181 promise = Promise.reject().catch(() => {}); // Avoid unhandled rejection warnings
1182 Object.defineProperty(promise, "_tracked", {
1183 get: () => true
1184 });
1185 Object.defineProperty(promise, "_error", {
1186 get: () => renderError
1187 });
1188 } else if (resolve._tracked) {
1189 // Already tracked promise - check contents
1190 promise = resolve;
1191 status = promise._error !== undefined ? AwaitRenderStatus.error : promise._data !== undefined ? AwaitRenderStatus.success : AwaitRenderStatus.pending;
1192 } else {
1193 // Raw (untracked) promise - track it
1194 status = AwaitRenderStatus.pending;
1195 Object.defineProperty(resolve, "_tracked", {
1196 get: () => true
1197 });
1198 promise = resolve.then(data => Object.defineProperty(resolve, "_data", {
1199 get: () => data
1200 }), error => Object.defineProperty(resolve, "_error", {
1201 get: () => error
1202 }));
1203 }
1204 if (status === AwaitRenderStatus.error && promise._error instanceof AbortedDeferredError) {
1205 // Freeze the UI by throwing a never resolved promise
1206 throw neverSettledPromise;
1207 }
1208 if (status === AwaitRenderStatus.error && !errorElement) {
1209 // No errorElement, throw to the nearest route-level error boundary
1210 throw promise._error;
1211 }
1212 if (status === AwaitRenderStatus.error) {
1213 // Render via our errorElement
1214 return /*#__PURE__*/React.createElement(AwaitContext.Provider, {
1215 value: promise,
1216 children: errorElement
1217 });
1218 }
1219 if (status === AwaitRenderStatus.success) {
1220 // Render children with resolved value
1221 return /*#__PURE__*/React.createElement(AwaitContext.Provider, {
1222 value: promise,
1223 children: children
1224 });
1225 }
1226
1227 // Throw to the suspense boundary
1228 throw promise;
1229 }
1230}
1231
1232/**
1233 * @private
1234 * Indirection to leverage useAsyncValue for a render-prop API on `<Await>`
1235 */
1236function ResolveAwait(_ref8) {
1237 let {
1238 children
1239 } = _ref8;
1240 let data = useAsyncValue();
1241 let toRender = typeof children === "function" ? children(data) : children;
1242 return /*#__PURE__*/React.createElement(React.Fragment, null, toRender);
1243}
1244
1245///////////////////////////////////////////////////////////////////////////////
1246// UTILS
1247///////////////////////////////////////////////////////////////////////////////
1248
1249/**
1250 * Creates a route config from a React "children" object, which is usually
1251 * either a `<Route>` element or an array of them. Used internally by
1252 * `<Routes>` to create a route config from its children.
1253 *
1254 * @see https://reactrouter.com/utils/create-routes-from-children
1255 */
1256function createRoutesFromChildren(children, parentPath) {
1257 if (parentPath === void 0) {
1258 parentPath = [];
1259 }
1260 let routes = [];
1261 React.Children.forEach(children, (element, index) => {
1262 if (! /*#__PURE__*/React.isValidElement(element)) {
1263 // Ignore non-elements. This allows people to more easily inline
1264 // conditionals in their route config.
1265 return;
1266 }
1267 let treePath = [...parentPath, index];
1268 if (element.type === React.Fragment) {
1269 // Transparently support React.Fragment and its children.
1270 routes.push.apply(routes, createRoutesFromChildren(element.props.children, treePath));
1271 return;
1272 }
1273 !(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;
1274 !(!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;
1275 let route = {
1276 id: element.props.id || treePath.join("-"),
1277 caseSensitive: element.props.caseSensitive,
1278 element: element.props.element,
1279 Component: element.props.Component,
1280 index: element.props.index,
1281 path: element.props.path,
1282 loader: element.props.loader,
1283 action: element.props.action,
1284 errorElement: element.props.errorElement,
1285 ErrorBoundary: element.props.ErrorBoundary,
1286 hasErrorBoundary: element.props.ErrorBoundary != null || element.props.errorElement != null,
1287 shouldRevalidate: element.props.shouldRevalidate,
1288 handle: element.props.handle,
1289 lazy: element.props.lazy
1290 };
1291 if (element.props.children) {
1292 route.children = createRoutesFromChildren(element.props.children, treePath);
1293 }
1294 routes.push(route);
1295 });
1296 return routes;
1297}
1298
1299/**
1300 * Renders the result of `matchRoutes()` into a React element.
1301 */
1302function renderMatches(matches) {
1303 return _renderMatches(matches);
1304}
1305
1306function mapRouteProperties(route) {
1307 let updates = {
1308 // Note: this check also occurs in createRoutesFromChildren so update
1309 // there if you change this -- please and thank you!
1310 hasErrorBoundary: route.ErrorBoundary != null || route.errorElement != null
1311 };
1312 if (route.Component) {
1313 if (process.env.NODE_ENV !== "production") {
1314 if (route.element) {
1315 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;
1316 }
1317 }
1318 Object.assign(updates, {
1319 element: /*#__PURE__*/React.createElement(route.Component),
1320 Component: undefined
1321 });
1322 }
1323 if (route.ErrorBoundary) {
1324 if (process.env.NODE_ENV !== "production") {
1325 if (route.errorElement) {
1326 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;
1327 }
1328 }
1329 Object.assign(updates, {
1330 errorElement: /*#__PURE__*/React.createElement(route.ErrorBoundary),
1331 ErrorBoundary: undefined
1332 });
1333 }
1334 return updates;
1335}
1336function createMemoryRouter(routes, opts) {
1337 return createRouter({
1338 basename: opts == null ? void 0 : opts.basename,
1339 future: _extends({}, opts == null ? void 0 : opts.future, {
1340 v7_prependBasename: true
1341 }),
1342 history: createMemoryHistory({
1343 initialEntries: opts == null ? void 0 : opts.initialEntries,
1344 initialIndex: opts == null ? void 0 : opts.initialIndex
1345 }),
1346 hydrationData: opts == null ? void 0 : opts.hydrationData,
1347 routes,
1348 mapRouteProperties
1349 }).initialize();
1350}
1351
1352export { 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, useActionData, useAsyncError, useAsyncValue, useBlocker, useHref, useInRouterContext, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes };
1353//# sourceMappingURL=index.js.map