UNPKG

53 kBJavaScriptView Raw
1/**
2 * React Router v6.20.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, 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 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 = /*#__PURE__*/function (DataRouterHook) {
589 DataRouterHook["UseBlocker"] = "useBlocker";
590 DataRouterHook["UseRevalidator"] = "useRevalidator";
591 DataRouterHook["UseNavigateStable"] = "useNavigate";
592 return DataRouterHook;
593}(DataRouterHook || {});
594var DataRouterStateHook = /*#__PURE__*/function (DataRouterStateHook) {
595 DataRouterStateHook["UseBlocker"] = "useBlocker";
596 DataRouterStateHook["UseLoaderData"] = "useLoaderData";
597 DataRouterStateHook["UseActionData"] = "useActionData";
598 DataRouterStateHook["UseRouteError"] = "useRouteError";
599 DataRouterStateHook["UseNavigation"] = "useNavigation";
600 DataRouterStateHook["UseRouteLoaderData"] = "useRouteLoaderData";
601 DataRouterStateHook["UseMatches"] = "useMatches";
602 DataRouterStateHook["UseRevalidator"] = "useRevalidator";
603 DataRouterStateHook["UseNavigateStable"] = "useNavigate";
604 DataRouterStateHook["UseRouteId"] = "useRouteId";
605 return DataRouterStateHook;
606}(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 React.useMemo(() => ({
658 revalidate: dataRouterContext.router.revalidate,
659 state: state.revalidation
660 }), [dataRouterContext.router.revalidate, state.revalidation]);
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(m => UNSAFE_convertRouteMatchToUiMatch(m, loaderData)), [matches, loaderData]);
673}
674
675/**
676 * Returns the loader data for the nearest ancestor Route loader
677 */
678function useLoaderData() {
679 let state = useDataRouterState(DataRouterStateHook.UseLoaderData);
680 let routeId = useCurrentRouteId(DataRouterStateHook.UseLoaderData);
681 if (state.errors && state.errors[routeId] != null) {
682 console.error("You cannot `useLoaderData` in an errorElement (routeId: " + routeId + ")");
683 return undefined;
684 }
685 return state.loaderData[routeId];
686}
687
688/**
689 * Returns the loaderData for the given routeId
690 */
691function useRouteLoaderData(routeId) {
692 let state = useDataRouterState(DataRouterStateHook.UseRouteLoaderData);
693 return state.loaderData[routeId];
694}
695
696/**
697 * Returns the action data for the nearest ancestor Route action
698 */
699function useActionData() {
700 let state = useDataRouterState(DataRouterStateHook.UseActionData);
701 let routeId = useCurrentRouteId(DataRouterStateHook.UseLoaderData);
702 return state.actionData ? state.actionData[routeId] : undefined;
703}
704
705/**
706 * Returns the nearest ancestor Route error, which could be a loader/action
707 * error or a render error. This is intended to be called from your
708 * ErrorBoundary/errorElement to display a proper error message.
709 */
710function useRouteError() {
711 var _state$errors;
712 let error = React.useContext(RouteErrorContext);
713 let state = useDataRouterState(DataRouterStateHook.UseRouteError);
714 let routeId = useCurrentRouteId(DataRouterStateHook.UseRouteError);
715
716 // If this was a render error, we put it in a RouteError context inside
717 // of RenderErrorBoundary
718 if (error) {
719 return error;
720 }
721
722 // Otherwise look for errors from our data router state
723 return (_state$errors = state.errors) == null ? void 0 : _state$errors[routeId];
724}
725
726/**
727 * Returns the happy-path data from the nearest ancestor `<Await />` value
728 */
729function useAsyncValue() {
730 let value = React.useContext(AwaitContext);
731 return value == null ? void 0 : value._data;
732}
733
734/**
735 * Returns the error from the nearest ancestor `<Await />` value
736 */
737function useAsyncError() {
738 let value = React.useContext(AwaitContext);
739 return value == null ? void 0 : value._error;
740}
741let blockerId = 0;
742
743/**
744 * Allow the application to block navigations within the SPA and present the
745 * user a confirmation dialog to confirm the navigation. Mostly used to avoid
746 * using half-filled form data. This does not handle hard-reloads or
747 * cross-origin navigations.
748 */
749function useBlocker(shouldBlock) {
750 let {
751 router,
752 basename
753 } = useDataRouterContext(DataRouterHook.UseBlocker);
754 let state = useDataRouterState(DataRouterStateHook.UseBlocker);
755 let [blockerKey, setBlockerKey] = React.useState("");
756 let blockerFunction = React.useCallback(arg => {
757 if (typeof shouldBlock !== "function") {
758 return !!shouldBlock;
759 }
760 if (basename === "/") {
761 return shouldBlock(arg);
762 }
763
764 // If they provided us a function and we've got an active basename, strip
765 // it from the locations we expose to the user to match the behavior of
766 // useLocation
767 let {
768 currentLocation,
769 nextLocation,
770 historyAction
771 } = arg;
772 return shouldBlock({
773 currentLocation: _extends({}, currentLocation, {
774 pathname: stripBasename(currentLocation.pathname, basename) || currentLocation.pathname
775 }),
776 nextLocation: _extends({}, nextLocation, {
777 pathname: stripBasename(nextLocation.pathname, basename) || nextLocation.pathname
778 }),
779 historyAction
780 });
781 }, [basename, shouldBlock]);
782
783 // This effect is in charge of blocker key assignment and deletion (which is
784 // tightly coupled to the key)
785 React.useEffect(() => {
786 let key = String(++blockerId);
787 setBlockerKey(key);
788 return () => router.deleteBlocker(key);
789 }, [router]);
790
791 // This effect handles assigning the blockerFunction. This is to handle
792 // unstable blocker function identities, and happens only after the prior
793 // effect so we don't get an orphaned blockerFunction in the router with a
794 // key of "". Until then we just have the IDLE_BLOCKER.
795 React.useEffect(() => {
796 if (blockerKey !== "") {
797 router.getBlocker(blockerKey, blockerFunction);
798 }
799 }, [router, blockerKey, blockerFunction]);
800
801 // Prefer the blocker from `state` not `router.state` since DataRouterContext
802 // is memoized so this ensures we update on blocker state updates
803 return blockerKey && state.blockers.has(blockerKey) ? state.blockers.get(blockerKey) : IDLE_BLOCKER;
804}
805
806/**
807 * Stable version of useNavigate that is used when we are in the context of
808 * a RouterProvider.
809 */
810function useNavigateStable() {
811 let {
812 router
813 } = useDataRouterContext(DataRouterHook.UseNavigateStable);
814 let id = useCurrentRouteId(DataRouterStateHook.UseNavigateStable);
815 let activeRef = React.useRef(false);
816 useIsomorphicLayoutEffect(() => {
817 activeRef.current = true;
818 });
819 let navigate = React.useCallback(function (to, options) {
820 if (options === void 0) {
821 options = {};
822 }
823 process.env.NODE_ENV !== "production" ? UNSAFE_warning(activeRef.current, navigateEffectWarning) : void 0;
824
825 // Short circuit here since if this happens on first render the navigate
826 // is useless because we haven't wired up our router subscriber yet
827 if (!activeRef.current) return;
828 if (typeof to === "number") {
829 router.navigate(to);
830 } else {
831 router.navigate(to, _extends({
832 fromRouteId: id
833 }, options));
834 }
835 }, [router, id]);
836 return navigate;
837}
838const alreadyWarned = {};
839function warningOnce(key, cond, message) {
840 if (!cond && !alreadyWarned[key]) {
841 alreadyWarned[key] = true;
842 process.env.NODE_ENV !== "production" ? UNSAFE_warning(false, message) : void 0;
843 }
844}
845
846/**
847 Webpack + React 17 fails to compile on any of the following because webpack
848 complains that `startTransition` doesn't exist in `React`:
849 * import { startTransition } from "react"
850 * import * as React from from "react";
851 "startTransition" in React ? React.startTransition(() => setState()) : setState()
852 * import * as React from from "react";
853 "startTransition" in React ? React["startTransition"](() => setState()) : setState()
854
855 Moving it to a constant such as the following solves the Webpack/React 17 issue:
856 * import * as React from from "react";
857 const START_TRANSITION = "startTransition";
858 START_TRANSITION in React ? React[START_TRANSITION](() => setState()) : setState()
859
860 However, that introduces webpack/terser minification issues in production builds
861 in React 18 where minification/obfuscation ends up removing the call of
862 React.startTransition entirely from the first half of the ternary. Grabbing
863 this exported reference once up front resolves that issue.
864
865 See https://github.com/remix-run/react-router/issues/10579
866*/
867const START_TRANSITION = "startTransition";
868const startTransitionImpl = React[START_TRANSITION];
869
870/**
871 * Given a Remix Router instance, render the appropriate UI
872 */
873function RouterProvider(_ref) {
874 let {
875 fallbackElement,
876 router,
877 future
878 } = _ref;
879 let [state, setStateImpl] = React.useState(router.state);
880 let {
881 v7_startTransition
882 } = future || {};
883 let setState = React.useCallback(newState => {
884 if (v7_startTransition && startTransitionImpl) {
885 startTransitionImpl(() => setStateImpl(newState));
886 } else {
887 setStateImpl(newState);
888 }
889 }, [setStateImpl, v7_startTransition]);
890
891 // Need to use a layout effect here so we are subscribed early enough to
892 // pick up on any render-driven redirects/navigations (useEffect/<Navigate>)
893 React.useLayoutEffect(() => router.subscribe(setState), [router, setState]);
894 let navigator = React.useMemo(() => {
895 return {
896 createHref: router.createHref,
897 encodeLocation: router.encodeLocation,
898 go: n => router.navigate(n),
899 push: (to, state, opts) => router.navigate(to, {
900 state,
901 preventScrollReset: opts == null ? void 0 : opts.preventScrollReset
902 }),
903 replace: (to, state, opts) => router.navigate(to, {
904 replace: true,
905 state,
906 preventScrollReset: opts == null ? void 0 : opts.preventScrollReset
907 })
908 };
909 }, [router]);
910 let basename = router.basename || "/";
911 let dataRouterContext = React.useMemo(() => ({
912 router,
913 navigator,
914 static: false,
915 basename
916 }), [router, navigator, basename]);
917
918 // The fragment and {null} here are important! We need them to keep React 18's
919 // useId happy when we are server-rendering since we may have a <script> here
920 // containing the hydrated server-side staticContext (from StaticRouterProvider).
921 // useId relies on the component tree structure to generate deterministic id's
922 // so we need to ensure it remains the same on the client even though
923 // we don't need the <script> tag
924 return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(DataRouterContext.Provider, {
925 value: dataRouterContext
926 }, /*#__PURE__*/React.createElement(DataRouterStateContext.Provider, {
927 value: state
928 }, /*#__PURE__*/React.createElement(Router, {
929 basename: basename,
930 location: state.location,
931 navigationType: state.historyAction,
932 navigator: navigator
933 }, state.initialized ? /*#__PURE__*/React.createElement(DataRoutes, {
934 routes: router.routes,
935 state: state
936 }) : fallbackElement))), null);
937}
938function DataRoutes(_ref2) {
939 let {
940 routes,
941 state
942 } = _ref2;
943 return useRoutesImpl(routes, undefined, state);
944}
945/**
946 * A `<Router>` that stores all entries in memory.
947 *
948 * @see https://reactrouter.com/router-components/memory-router
949 */
950function MemoryRouter(_ref3) {
951 let {
952 basename,
953 children,
954 initialEntries,
955 initialIndex,
956 future
957 } = _ref3;
958 let historyRef = React.useRef();
959 if (historyRef.current == null) {
960 historyRef.current = createMemoryHistory({
961 initialEntries,
962 initialIndex,
963 v5Compat: true
964 });
965 }
966 let history = historyRef.current;
967 let [state, setStateImpl] = React.useState({
968 action: history.action,
969 location: history.location
970 });
971 let {
972 v7_startTransition
973 } = future || {};
974 let setState = React.useCallback(newState => {
975 v7_startTransition && startTransitionImpl ? startTransitionImpl(() => setStateImpl(newState)) : setStateImpl(newState);
976 }, [setStateImpl, v7_startTransition]);
977 React.useLayoutEffect(() => history.listen(setState), [history, setState]);
978 return /*#__PURE__*/React.createElement(Router, {
979 basename: basename,
980 children: children,
981 location: state.location,
982 navigationType: state.action,
983 navigator: history
984 });
985}
986/**
987 * Changes the current location.
988 *
989 * Note: This API is mostly useful in React.Component subclasses that are not
990 * able to use hooks. In functional components, we recommend you use the
991 * `useNavigate` hook instead.
992 *
993 * @see https://reactrouter.com/components/navigate
994 */
995function Navigate(_ref4) {
996 let {
997 to,
998 replace,
999 state,
1000 relative
1001 } = _ref4;
1002 !useInRouterContext() ? process.env.NODE_ENV !== "production" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of
1003 // the router loaded. We can help them understand how to avoid that.
1004 "<Navigate> may be used only in the context of a <Router> component.") : UNSAFE_invariant(false) : void 0;
1005 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;
1006 let {
1007 matches
1008 } = React.useContext(RouteContext);
1009 let {
1010 pathname: locationPathname
1011 } = useLocation();
1012 let navigate = useNavigate();
1013
1014 // Resolve the path outside of the effect so that when effects run twice in
1015 // StrictMode they navigate to the same place
1016 let path = resolveTo(to, UNSAFE_getPathContributingMatches(matches).map(match => match.pathnameBase), locationPathname, relative === "path");
1017 let jsonPath = JSON.stringify(path);
1018 React.useEffect(() => navigate(JSON.parse(jsonPath), {
1019 replace,
1020 state,
1021 relative
1022 }), [navigate, jsonPath, relative, replace, state]);
1023 return null;
1024}
1025/**
1026 * Renders the child route's element, if there is one.
1027 *
1028 * @see https://reactrouter.com/components/outlet
1029 */
1030function Outlet(props) {
1031 return useOutlet(props.context);
1032}
1033/**
1034 * Declares an element that should be rendered at a certain URL path.
1035 *
1036 * @see https://reactrouter.com/components/route
1037 */
1038function Route(_props) {
1039 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) ;
1040}
1041/**
1042 * Provides location context for the rest of the app.
1043 *
1044 * Note: You usually won't render a `<Router>` directly. Instead, you'll render a
1045 * router that is more specific to your environment such as a `<BrowserRouter>`
1046 * in web browsers or a `<StaticRouter>` for server rendering.
1047 *
1048 * @see https://reactrouter.com/router-components/router
1049 */
1050function Router(_ref5) {
1051 let {
1052 basename: basenameProp = "/",
1053 children = null,
1054 location: locationProp,
1055 navigationType = Action.Pop,
1056 navigator,
1057 static: staticProp = false
1058 } = _ref5;
1059 !!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;
1060
1061 // Preserve trailing slashes on basename, so we can let the user control
1062 // the enforcement of trailing slashes throughout the app
1063 let basename = basenameProp.replace(/^\/*/, "/");
1064 let navigationContext = React.useMemo(() => ({
1065 basename,
1066 navigator,
1067 static: staticProp
1068 }), [basename, navigator, staticProp]);
1069 if (typeof locationProp === "string") {
1070 locationProp = parsePath(locationProp);
1071 }
1072 let {
1073 pathname = "/",
1074 search = "",
1075 hash = "",
1076 state = null,
1077 key = "default"
1078 } = locationProp;
1079 let locationContext = React.useMemo(() => {
1080 let trailingPathname = stripBasename(pathname, basename);
1081 if (trailingPathname == null) {
1082 return null;
1083 }
1084 return {
1085 location: {
1086 pathname: trailingPathname,
1087 search,
1088 hash,
1089 state,
1090 key
1091 },
1092 navigationType
1093 };
1094 }, [basename, pathname, search, hash, state, key, navigationType]);
1095 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;
1096 if (locationContext == null) {
1097 return null;
1098 }
1099 return /*#__PURE__*/React.createElement(NavigationContext.Provider, {
1100 value: navigationContext
1101 }, /*#__PURE__*/React.createElement(LocationContext.Provider, {
1102 children: children,
1103 value: locationContext
1104 }));
1105}
1106/**
1107 * A container for a nested tree of `<Route>` elements that renders the branch
1108 * that best matches the current location.
1109 *
1110 * @see https://reactrouter.com/components/routes
1111 */
1112function Routes(_ref6) {
1113 let {
1114 children,
1115 location
1116 } = _ref6;
1117 return useRoutes(createRoutesFromChildren(children), location);
1118}
1119/**
1120 * Component to use for rendering lazily loaded data from returning defer()
1121 * in a loader function
1122 */
1123function Await(_ref7) {
1124 let {
1125 children,
1126 errorElement,
1127 resolve
1128 } = _ref7;
1129 return /*#__PURE__*/React.createElement(AwaitErrorBoundary, {
1130 resolve: resolve,
1131 errorElement: errorElement
1132 }, /*#__PURE__*/React.createElement(ResolveAwait, null, children));
1133}
1134var AwaitRenderStatus = /*#__PURE__*/function (AwaitRenderStatus) {
1135 AwaitRenderStatus[AwaitRenderStatus["pending"] = 0] = "pending";
1136 AwaitRenderStatus[AwaitRenderStatus["success"] = 1] = "success";
1137 AwaitRenderStatus[AwaitRenderStatus["error"] = 2] = "error";
1138 return AwaitRenderStatus;
1139}(AwaitRenderStatus || {});
1140const neverSettledPromise = new Promise(() => {});
1141class AwaitErrorBoundary extends React.Component {
1142 constructor(props) {
1143 super(props);
1144 this.state = {
1145 error: null
1146 };
1147 }
1148 static getDerivedStateFromError(error) {
1149 return {
1150 error
1151 };
1152 }
1153 componentDidCatch(error, errorInfo) {
1154 console.error("<Await> caught the following error during render", error, errorInfo);
1155 }
1156 render() {
1157 let {
1158 children,
1159 errorElement,
1160 resolve
1161 } = this.props;
1162 let promise = null;
1163 let status = AwaitRenderStatus.pending;
1164 if (!(resolve instanceof Promise)) {
1165 // Didn't get a promise - provide as a resolved promise
1166 status = AwaitRenderStatus.success;
1167 promise = Promise.resolve();
1168 Object.defineProperty(promise, "_tracked", {
1169 get: () => true
1170 });
1171 Object.defineProperty(promise, "_data", {
1172 get: () => resolve
1173 });
1174 } else if (this.state.error) {
1175 // Caught a render error, provide it as a rejected promise
1176 status = AwaitRenderStatus.error;
1177 let renderError = this.state.error;
1178 promise = Promise.reject().catch(() => {}); // Avoid unhandled rejection warnings
1179 Object.defineProperty(promise, "_tracked", {
1180 get: () => true
1181 });
1182 Object.defineProperty(promise, "_error", {
1183 get: () => renderError
1184 });
1185 } else if (resolve._tracked) {
1186 // Already tracked promise - check contents
1187 promise = resolve;
1188 status = promise._error !== undefined ? AwaitRenderStatus.error : promise._data !== undefined ? AwaitRenderStatus.success : AwaitRenderStatus.pending;
1189 } else {
1190 // Raw (untracked) promise - track it
1191 status = AwaitRenderStatus.pending;
1192 Object.defineProperty(resolve, "_tracked", {
1193 get: () => true
1194 });
1195 promise = resolve.then(data => Object.defineProperty(resolve, "_data", {
1196 get: () => data
1197 }), error => Object.defineProperty(resolve, "_error", {
1198 get: () => error
1199 }));
1200 }
1201 if (status === AwaitRenderStatus.error && promise._error instanceof AbortedDeferredError) {
1202 // Freeze the UI by throwing a never resolved promise
1203 throw neverSettledPromise;
1204 }
1205 if (status === AwaitRenderStatus.error && !errorElement) {
1206 // No errorElement, throw to the nearest route-level error boundary
1207 throw promise._error;
1208 }
1209 if (status === AwaitRenderStatus.error) {
1210 // Render via our errorElement
1211 return /*#__PURE__*/React.createElement(AwaitContext.Provider, {
1212 value: promise,
1213 children: errorElement
1214 });
1215 }
1216 if (status === AwaitRenderStatus.success) {
1217 // Render children with resolved value
1218 return /*#__PURE__*/React.createElement(AwaitContext.Provider, {
1219 value: promise,
1220 children: children
1221 });
1222 }
1223
1224 // Throw to the suspense boundary
1225 throw promise;
1226 }
1227}
1228
1229/**
1230 * @private
1231 * Indirection to leverage useAsyncValue for a render-prop API on `<Await>`
1232 */
1233function ResolveAwait(_ref8) {
1234 let {
1235 children
1236 } = _ref8;
1237 let data = useAsyncValue();
1238 let toRender = typeof children === "function" ? children(data) : children;
1239 return /*#__PURE__*/React.createElement(React.Fragment, null, toRender);
1240}
1241
1242///////////////////////////////////////////////////////////////////////////////
1243// UTILS
1244///////////////////////////////////////////////////////////////////////////////
1245
1246/**
1247 * Creates a route config from a React "children" object, which is usually
1248 * either a `<Route>` element or an array of them. Used internally by
1249 * `<Routes>` to create a route config from its children.
1250 *
1251 * @see https://reactrouter.com/utils/create-routes-from-children
1252 */
1253function createRoutesFromChildren(children, parentPath) {
1254 if (parentPath === void 0) {
1255 parentPath = [];
1256 }
1257 let routes = [];
1258 React.Children.forEach(children, (element, index) => {
1259 if (! /*#__PURE__*/React.isValidElement(element)) {
1260 // Ignore non-elements. This allows people to more easily inline
1261 // conditionals in their route config.
1262 return;
1263 }
1264 let treePath = [...parentPath, index];
1265 if (element.type === React.Fragment) {
1266 // Transparently support React.Fragment and its children.
1267 routes.push.apply(routes, createRoutesFromChildren(element.props.children, treePath));
1268 return;
1269 }
1270 !(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;
1271 !(!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;
1272 let route = {
1273 id: element.props.id || treePath.join("-"),
1274 caseSensitive: element.props.caseSensitive,
1275 element: element.props.element,
1276 Component: element.props.Component,
1277 index: element.props.index,
1278 path: element.props.path,
1279 loader: element.props.loader,
1280 action: element.props.action,
1281 errorElement: element.props.errorElement,
1282 ErrorBoundary: element.props.ErrorBoundary,
1283 hasErrorBoundary: element.props.ErrorBoundary != null || element.props.errorElement != null,
1284 shouldRevalidate: element.props.shouldRevalidate,
1285 handle: element.props.handle,
1286 lazy: element.props.lazy
1287 };
1288 if (element.props.children) {
1289 route.children = createRoutesFromChildren(element.props.children, treePath);
1290 }
1291 routes.push(route);
1292 });
1293 return routes;
1294}
1295
1296/**
1297 * Renders the result of `matchRoutes()` into a React element.
1298 */
1299function renderMatches(matches) {
1300 return _renderMatches(matches);
1301}
1302
1303function mapRouteProperties(route) {
1304 let updates = {
1305 // Note: this check also occurs in createRoutesFromChildren so update
1306 // there if you change this -- please and thank you!
1307 hasErrorBoundary: route.ErrorBoundary != null || route.errorElement != null
1308 };
1309 if (route.Component) {
1310 if (process.env.NODE_ENV !== "production") {
1311 if (route.element) {
1312 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;
1313 }
1314 }
1315 Object.assign(updates, {
1316 element: /*#__PURE__*/React.createElement(route.Component),
1317 Component: undefined
1318 });
1319 }
1320 if (route.ErrorBoundary) {
1321 if (process.env.NODE_ENV !== "production") {
1322 if (route.errorElement) {
1323 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;
1324 }
1325 }
1326 Object.assign(updates, {
1327 errorElement: /*#__PURE__*/React.createElement(route.ErrorBoundary),
1328 ErrorBoundary: undefined
1329 });
1330 }
1331 return updates;
1332}
1333function createMemoryRouter(routes, opts) {
1334 return createRouter({
1335 basename: opts == null ? void 0 : opts.basename,
1336 future: _extends({}, opts == null ? void 0 : opts.future, {
1337 v7_prependBasename: true
1338 }),
1339 history: createMemoryHistory({
1340 initialEntries: opts == null ? void 0 : opts.initialEntries,
1341 initialIndex: opts == null ? void 0 : opts.initialIndex
1342 }),
1343 hydrationData: opts == null ? void 0 : opts.hydrationData,
1344 routes,
1345 mapRouteProperties
1346 }).initialize();
1347}
1348
1349export { 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 };
1350//# sourceMappingURL=index.js.map