react-router 6.0.0-beta.6 → 6.0.0-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import { Action } from "history";
3
- import type { Blocker, History, InitialEntry, Location, Path, State, To } from "history";
3
+ import type { History, InitialEntry, Location, Path, State, To } from "history";
4
4
  /**
5
5
  * A Navigator is a "location changer"; it's how you get to different locations.
6
6
  *
@@ -10,7 +10,7 @@ import type { Blocker, History, InitialEntry, Location, Path, State, To } from "
10
10
  * to avoid "tearing" that may occur in a suspense-enabled app if the action
11
11
  * and/or location were to be read directly from the history instance.
12
12
  */
13
- export declare type Navigator = Omit<History, "action" | "location" | "back" | "forward" | "listen">;
13
+ export declare type Navigator = Omit<History, "action" | "location" | "back" | "forward" | "listen" | "block">;
14
14
  interface NavigationContextObject {
15
15
  basename: string;
16
16
  navigator: Navigator;
@@ -22,14 +22,11 @@ interface LocationContextObject {
22
22
  location: Location;
23
23
  }
24
24
  declare const LocationContext: React.Context<LocationContextObject>;
25
- interface RouteContextObject<ParamKey extends string = string> {
25
+ interface RouteContextObject {
26
26
  outlet: React.ReactElement | null;
27
- params: Readonly<Params<ParamKey>>;
28
- pathname: string;
29
- pathnameBase: string;
30
- route: RouteObject | null;
27
+ matches: RouteMatch[];
31
28
  }
32
- declare const RouteContext: React.Context<RouteContextObject<string>>;
29
+ declare const RouteContext: React.Context<RouteContextObject>;
33
30
  export interface MemoryRouterProps {
34
31
  basename?: string;
35
32
  children?: React.ReactNode;
@@ -122,13 +119,6 @@ export interface RoutesProps {
122
119
  * @see https://reactrouter.com/api/Routes
123
120
  */
124
121
  export declare function Routes({ children, location }: RoutesProps): React.ReactElement | null;
125
- /**
126
- * Blocks all navigation attempts. This is useful for preventing the page from
127
- * changing until some condition is met, like saving form data.
128
- *
129
- * @see https://reactrouter.com/api/useBlocker
130
- */
131
- export declare function useBlocker(blocker: Blocker, when?: boolean): void;
132
122
  /**
133
123
  * Returns the full href for the given "to" value. This is useful for building
134
124
  * custom links that are also accessible and preserve right-click behavior.
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * React Router v6.0.0-beta.6
2
+ * React Router v6.0.0-beta.7
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -11,24 +11,6 @@
11
11
  import { createContext, useRef, useState, useLayoutEffect, createElement, useContext, useEffect, useMemo, useCallback, Children, isValidElement, Fragment } from 'react';
12
12
  import { createMemoryHistory, Action, parsePath } from 'history';
13
13
 
14
- function _extends() {
15
- _extends = Object.assign || function (target) {
16
- for (var i = 1; i < arguments.length; i++) {
17
- var source = arguments[i];
18
-
19
- for (var key in source) {
20
- if (Object.prototype.hasOwnProperty.call(source, key)) {
21
- target[key] = source[key];
22
- }
23
- }
24
- }
25
-
26
- return target;
27
- };
28
-
29
- return _extends.apply(this, arguments);
30
- }
31
-
32
14
  function invariant(cond, message) {
33
15
  if (!cond) throw new Error(message);
34
16
  }
@@ -85,10 +67,7 @@ if (process.env.NODE_ENV !== "production") {
85
67
 
86
68
  const RouteContext = /*#__PURE__*/createContext({
87
69
  outlet: null,
88
- params: {},
89
- pathname: "/",
90
- pathnameBase: "/",
91
- route: null
70
+ matches: []
92
71
  });
93
72
 
94
73
  if (process.env.NODE_ENV !== "production") {
@@ -266,43 +245,6 @@ function Routes(_ref4) {
266
245
  // HOOKS
267
246
  ///////////////////////////////////////////////////////////////////////////////
268
247
 
269
- /**
270
- * Blocks all navigation attempts. This is useful for preventing the page from
271
- * changing until some condition is met, like saving form data.
272
- *
273
- * @see https://reactrouter.com/api/useBlocker
274
- */
275
-
276
- function useBlocker(blocker, when) {
277
- if (when === void 0) {
278
- when = true;
279
- }
280
-
281
- !useInRouterContext() ? process.env.NODE_ENV !== "production" ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
282
- // router loaded. We can help them understand how to avoid that.
283
- "useBlocker() may be used only in the context of a <Router> component.") : invariant(false) : void 0;
284
- let {
285
- navigator
286
- } = useContext(NavigationContext);
287
- useEffect(() => {
288
- if (!when) return;
289
- let unblock = navigator.block(tx => {
290
- let autoUnblockingTx = _extends({}, tx, {
291
- retry() {
292
- // Automatically unblock the transition so it can play all the way
293
- // through before retrying it. TODO: Figure out how to re-enable
294
- // this block if the transition is cancelled for some reason.
295
- unblock();
296
- tx.retry();
297
- }
298
-
299
- });
300
-
301
- blocker(autoUnblockingTx);
302
- });
303
- return unblock;
304
- }, [navigator, blocker, when]);
305
- }
306
248
  /**
307
249
  * Returns the full href for the given "to" value. This is useful for building
308
250
  * custom links that are also accessible and preserve right-click behavior.
@@ -387,11 +329,12 @@ function useNavigate() {
387
329
  navigator
388
330
  } = useContext(NavigationContext);
389
331
  let {
390
- pathname: routePathname
332
+ matches
391
333
  } = useContext(RouteContext);
392
334
  let {
393
335
  pathname: locationPathname
394
336
  } = useLocation();
337
+ let routePathnamesJson = JSON.stringify(matches.map(match => match.pathnameBase));
395
338
  let activeRef = useRef(false);
396
339
  useEffect(() => {
397
340
  activeRef.current = true;
@@ -409,14 +352,14 @@ function useNavigate() {
409
352
  return;
410
353
  }
411
354
 
412
- let path = resolveTo(to, routePathname, locationPathname);
355
+ let path = resolveTo(to, JSON.parse(routePathnamesJson), locationPathname);
413
356
 
414
357
  if (basename !== "/") {
415
358
  path.pathname = joinPaths([basename, path.pathname]);
416
359
  }
417
360
 
418
361
  (!!options.replace ? navigator.replace : navigator.push)(path, options.state);
419
- }, [basename, navigator, routePathname, locationPathname]);
362
+ }, [basename, navigator, routePathnamesJson, locationPathname]);
420
363
  return navigate;
421
364
  }
422
365
  /**
@@ -437,7 +380,11 @@ function useOutlet() {
437
380
  */
438
381
 
439
382
  function useParams() {
440
- return useContext(RouteContext).params;
383
+ let {
384
+ matches
385
+ } = useContext(RouteContext);
386
+ let routeMatch = matches[matches.length - 1];
387
+ return routeMatch ? routeMatch.params : {};
441
388
  }
442
389
  /**
443
390
  * Resolves the pathname of the given `to` value against the current location.
@@ -447,12 +394,13 @@ function useParams() {
447
394
 
448
395
  function useResolvedPath(to) {
449
396
  let {
450
- pathname: routePathname
397
+ matches
451
398
  } = useContext(RouteContext);
452
399
  let {
453
400
  pathname: locationPathname
454
401
  } = useLocation();
455
- return useMemo(() => resolveTo(to, routePathname, locationPathname), [to, routePathname, locationPathname]);
402
+ let routePathnamesJson = JSON.stringify(matches.map(match => match.pathnameBase));
403
+ return useMemo(() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname), [to, routePathnamesJson, locationPathname]);
456
404
  }
457
405
  /**
458
406
  * Returns the element of the route that matched the current location, prepared
@@ -468,11 +416,13 @@ function useRoutes(routes, locationArg) {
468
416
  // router loaded. We can help them understand how to avoid that.
469
417
  "useRoutes() may be used only in the context of a <Router> component.") : invariant(false) : void 0;
470
418
  let {
471
- params: parentParams,
472
- pathname: parentPathname,
473
- pathnameBase: parentPathnameBase,
474
- route: parentRoute
419
+ matches: parentMatches
475
420
  } = useContext(RouteContext);
421
+ let routeMatch = parentMatches[parentMatches.length - 1];
422
+ let parentParams = routeMatch ? routeMatch.params : {};
423
+ let parentPathname = routeMatch ? routeMatch.pathname : "/";
424
+ let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : "/";
425
+ let parentRoute = routeMatch && routeMatch.route;
476
426
 
477
427
  if (process.env.NODE_ENV !== "production") {
478
428
  // You won't get a warning about 2 different <Routes> under a <Route>
@@ -522,11 +472,11 @@ function useRoutes(routes, locationArg) {
522
472
  process.env.NODE_ENV !== "production" ? warning(parentRoute || matches != null, "No routes matched location \"" + location.pathname + location.search + location.hash + "\" ") : void 0;
523
473
  }
524
474
 
525
- return renderMatches(matches && matches.map(match => Object.assign({}, match, {
475
+ return _renderMatches(matches && matches.map(match => Object.assign({}, match, {
526
476
  params: Object.assign({}, parentParams, match.params),
527
477
  pathname: joinPaths([parentPathnameBase, match.pathname]),
528
478
  pathnameBase: joinPaths([parentPathnameBase, match.pathnameBase])
529
- })));
479
+ })), parentMatches);
530
480
  } ///////////////////////////////////////////////////////////////////////////////
531
481
  // UTILS
532
482
  ///////////////////////////////////////////////////////////////////////////////
@@ -733,7 +683,11 @@ routesArg, pathname) {
733
683
  pathnameBase: joinPaths([matchedPathname, match.pathnameBase]),
734
684
  route
735
685
  });
736
- matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);
686
+
687
+ if (match.pathnameBase !== "/") {
688
+ matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);
689
+ }
690
+
737
691
  routes = route.children;
738
692
  }
739
693
 
@@ -745,16 +699,21 @@ routesArg, pathname) {
745
699
 
746
700
 
747
701
  function renderMatches(matches) {
702
+ return _renderMatches(matches);
703
+ }
704
+
705
+ function _renderMatches(matches, parentMatches) {
706
+ if (parentMatches === void 0) {
707
+ parentMatches = [];
708
+ }
709
+
748
710
  if (matches == null) return null;
749
- return matches.reduceRight((outlet, match) => {
711
+ return matches.reduceRight((outlet, match, index) => {
750
712
  return /*#__PURE__*/createElement(RouteContext.Provider, {
751
713
  children: match.route.element || /*#__PURE__*/createElement(Outlet, null),
752
714
  value: {
753
715
  outlet,
754
- params: match.params,
755
- pathname: match.pathname,
756
- pathnameBase: match.pathnameBase,
757
- route: match.route
716
+ matches: parentMatches.concat(matches.slice(0, index + 1))
758
717
  }
759
718
  });
760
719
  }, null);
@@ -763,6 +722,7 @@ function renderMatches(matches) {
763
722
  * A PathPattern is used to match on some portion of a URL pathname.
764
723
  */
765
724
 
725
+
766
726
  /**
767
727
  * Performs pattern matching on a URL pathname and returns information about
768
728
  * the match.
@@ -885,17 +845,48 @@ function resolvePathname(relativePath, fromPathname) {
885
845
  return segments.length > 1 ? segments.join("/") : "/";
886
846
  }
887
847
 
888
- function resolveTo(to, routePathname, locationPathname) {
889
- return resolvePath(to, // If a pathname is explicitly provided in `to`, it should be
890
- // relative to the route context. This is explained in `Note on
891
- // `<Link to>` values` in our migration guide from v5 as a means of
892
- // disambiguation between `to` values that begin with `/` and those
893
- // that do not. However, this is problematic for `to` values that do
894
- // not provide a pathname. `to` can simply be a search or hash
895
- // string, in which case we should assume that the navigation is
896
- // relative to the current location's pathname and *not* the
897
- // route pathname.
898
- getToPathname(to) == null ? locationPathname : routePathname);
848
+ function resolveTo(toArg, routePathnames, locationPathname) {
849
+ let to = typeof toArg === "string" ? parsePath(toArg) : toArg;
850
+ let toPathname = toArg === "" || to.pathname === "" ? "/" : to.pathname; // If a pathname is explicitly provided in `to`, it should be relative to the
851
+ // route context. This is explained in `Note on `<Link to>` values` in our
852
+ // migration guide from v5 as a means of disambiguation between `to` values
853
+ // that begin with `/` and those that do not. However, this is problematic for
854
+ // `to` values that do not provide a pathname. `to` can simply be a search or
855
+ // hash string, in which case we should assume that the navigation is relative
856
+ // to the current location's pathname and *not* the route pathname.
857
+
858
+ let from;
859
+
860
+ if (toPathname == null) {
861
+ from = locationPathname;
862
+ } else {
863
+ let routePathnameIndex = routePathnames.length - 1;
864
+
865
+ if (toPathname.startsWith("..")) {
866
+ let toSegments = toPathname.split("/"); // Each leading .. segment means "go up one route" instead of "go up one
867
+ // URL segment". This is a key difference from how <a href> works and a
868
+ // major reason we call this a "to" value instead of a "href".
869
+
870
+ while (toSegments[0] === "..") {
871
+ toSegments.shift();
872
+ routePathnameIndex -= 1;
873
+ }
874
+
875
+ to.pathname = toSegments.join("/");
876
+ } // If there are more ".." segments than parent routes, resolve relative to
877
+ // the root / URL.
878
+
879
+
880
+ from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/";
881
+ }
882
+
883
+ let path = resolvePath(to, from); // Ensure the pathname has a trailing slash if the original to value had one.
884
+
885
+ if (toPathname && toPathname !== "/" && toPathname.endsWith("/") && !path.pathname.endsWith("/")) {
886
+ path.pathname += "/";
887
+ }
888
+
889
+ return path;
899
890
  }
900
891
 
901
892
  function getToPathname(to) {
@@ -928,5 +919,5 @@ const normalizeSearch = search => !search || search === "?" ? "" : search.starts
928
919
 
929
920
  const normalizeHash = hash => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash; ///////////////////////////////////////////////////////////////////////////////
930
921
 
931
- export { MemoryRouter, Navigate, Outlet, Route, Router, Routes, LocationContext as UNSAFE_LocationContext, NavigationContext as UNSAFE_NavigationContext, RouteContext as UNSAFE_RouteContext, createRoutesFromChildren, generatePath, matchPath, matchRoutes, renderMatches, resolvePath, useBlocker, useHref, useInRouterContext, useLocation, useMatch, useNavigate, useOutlet, useParams, useResolvedPath, useRoutes };
922
+ export { MemoryRouter, Navigate, Outlet, Route, Router, Routes, LocationContext as UNSAFE_LocationContext, NavigationContext as UNSAFE_NavigationContext, RouteContext as UNSAFE_RouteContext, createRoutesFromChildren, generatePath, matchPath, matchRoutes, renderMatches, resolvePath, useHref, useInRouterContext, useLocation, useMatch, useNavigate, useOutlet, useParams, useResolvedPath, useRoutes };
932
923
  //# sourceMappingURL=index.js.map