UNPKG

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