react-router 6.0.0-beta.6 → 6.0.1

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * React Router v6.0.0-beta.6
2
+ * React Router v6.0.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -14,24 +14,6 @@
14
14
  (global = global || self, factory(global.ReactRouter = {}, global.React, global.HistoryLibrary));
15
15
  }(this, (function (exports, React, history) { 'use strict';
16
16
 
17
- function _extends() {
18
- _extends = Object.assign || function (target) {
19
- for (var i = 1; i < arguments.length; i++) {
20
- var source = arguments[i];
21
-
22
- for (var key in source) {
23
- if (Object.prototype.hasOwnProperty.call(source, key)) {
24
- target[key] = source[key];
25
- }
26
- }
27
- }
28
-
29
- return target;
30
- };
31
-
32
- return _extends.apply(this, arguments);
33
- }
34
-
35
17
  function invariant(cond, message) {
36
18
  if (!cond) throw new Error(message);
37
19
  }
@@ -88,10 +70,7 @@
88
70
 
89
71
  const RouteContext = /*#__PURE__*/React.createContext({
90
72
  outlet: null,
91
- params: {},
92
- pathname: "/",
93
- pathnameBase: "/",
94
- route: null
73
+ matches: []
95
74
  });
96
75
 
97
76
  {
@@ -104,7 +83,7 @@
104
83
  /**
105
84
  * A <Router> that stores all entries in memory.
106
85
  *
107
- * @see https://reactrouter.com/api/MemoryRouter
86
+ * @see https://reactrouter.com/docs/en/v6/api#memoryrouter
108
87
  */
109
88
  function MemoryRouter(_ref) {
110
89
  let {
@@ -131,8 +110,8 @@
131
110
  return /*#__PURE__*/React.createElement(Router, {
132
111
  basename: basename,
133
112
  children: children,
134
- action: state.action,
135
113
  location: state.location,
114
+ navigationType: state.action,
136
115
  navigator: history$1
137
116
  });
138
117
  }
@@ -144,7 +123,7 @@
144
123
  * able to use hooks. In functional components, we recommend you use the
145
124
  * `useNavigate` hook instead.
146
125
  *
147
- * @see https://reactrouter.com/api/Navigate
126
+ * @see https://reactrouter.com/docs/en/v6/api#navigate
148
127
  */
149
128
  function Navigate(_ref2) {
150
129
  let {
@@ -169,7 +148,7 @@
169
148
  /**
170
149
  * Renders the child route's element, if there is one.
171
150
  *
172
- * @see https://reactrouter.com/api/Outlet
151
+ * @see https://reactrouter.com/docs/en/v6/api#outlet
173
152
  */
174
153
  function Outlet(_props) {
175
154
  return useOutlet();
@@ -178,7 +157,7 @@
178
157
  /**
179
158
  * Declares an element that should be rendered at a certain URL path.
180
159
  *
181
- * @see https://reactrouter.com/api/Route
160
+ * @see https://reactrouter.com/docs/en/v6/api#route
182
161
  */
183
162
  function Route(_props) {
184
163
  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>.") ;
@@ -191,14 +170,14 @@
191
170
  * router that is more specific to your environment such as a <BrowserRouter>
192
171
  * in web browsers or a <StaticRouter> for server rendering.
193
172
  *
194
- * @see https://reactrouter.com/api/Router
173
+ * @see https://reactrouter.com/docs/en/v6/api#router
195
174
  */
196
175
  function Router(_ref3) {
197
176
  let {
198
- action = history.Action.Pop,
199
177
  basename: basenameProp = "/",
200
178
  children = null,
201
179
  location: locationProp,
180
+ navigationType = history.Action.Pop,
202
181
  navigator,
203
182
  static: staticProp = false
204
183
  } = _ref3;
@@ -247,8 +226,8 @@
247
226
  }, /*#__PURE__*/React.createElement(LocationContext.Provider, {
248
227
  children: children,
249
228
  value: {
250
- action,
251
- location
229
+ location,
230
+ navigationType
252
231
  }
253
232
  }));
254
233
  }
@@ -257,7 +236,7 @@
257
236
  * A container for a nested tree of <Route> elements that renders the branch
258
237
  * that best matches the current location.
259
238
  *
260
- * @see https://reactrouter.com/api/Routes
239
+ * @see https://reactrouter.com/docs/en/v6/api#routes
261
240
  */
262
241
  function Routes(_ref4) {
263
242
  let {
@@ -269,48 +248,11 @@
269
248
  // HOOKS
270
249
  ///////////////////////////////////////////////////////////////////////////////
271
250
 
272
- /**
273
- * Blocks all navigation attempts. This is useful for preventing the page from
274
- * changing until some condition is met, like saving form data.
275
- *
276
- * @see https://reactrouter.com/api/useBlocker
277
- */
278
-
279
- function useBlocker(blocker, when) {
280
- if (when === void 0) {
281
- when = true;
282
- }
283
-
284
- !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
285
- // router loaded. We can help them understand how to avoid that.
286
- "useBlocker() may be used only in the context of a <Router> component.") : void 0;
287
- let {
288
- navigator
289
- } = React.useContext(NavigationContext);
290
- React.useEffect(() => {
291
- if (!when) return;
292
- let unblock = navigator.block(tx => {
293
- let autoUnblockingTx = _extends({}, tx, {
294
- retry() {
295
- // Automatically unblock the transition so it can play all the way
296
- // through before retrying it. TODO: Figure out how to re-enable
297
- // this block if the transition is cancelled for some reason.
298
- unblock();
299
- tx.retry();
300
- }
301
-
302
- });
303
-
304
- blocker(autoUnblockingTx);
305
- });
306
- return unblock;
307
- }, [navigator, blocker, when]);
308
- }
309
251
  /**
310
252
  * Returns the full href for the given "to" value. This is useful for building
311
253
  * custom links that are also accessible and preserve right-click behavior.
312
254
  *
313
- * @see https://reactrouter.com/api/useHref
255
+ * @see https://reactrouter.com/docs/en/v6/api#usehref
314
256
  */
315
257
 
316
258
  function useHref(to) {
@@ -321,20 +263,29 @@
321
263
  basename,
322
264
  navigator
323
265
  } = React.useContext(NavigationContext);
324
- let path = useResolvedPath(to);
266
+ let {
267
+ hash,
268
+ pathname,
269
+ search
270
+ } = useResolvedPath(to);
271
+ let joinedPathname = pathname;
325
272
 
326
273
  if (basename !== "/") {
327
274
  let toPathname = getToPathname(to);
328
275
  let endsWithSlash = toPathname != null && toPathname.endsWith("/");
329
- path.pathname = path.pathname === "/" ? basename + (endsWithSlash ? "/" : "") : joinPaths([basename, path.pathname]);
276
+ joinedPathname = pathname === "/" ? basename + (endsWithSlash ? "/" : "") : joinPaths([basename, pathname]);
330
277
  }
331
278
 
332
- return navigator.createHref(path);
279
+ return navigator.createHref({
280
+ pathname: joinedPathname,
281
+ search,
282
+ hash
283
+ });
333
284
  }
334
285
  /**
335
286
  * Returns true if this component is a descendant of a <Router>.
336
287
  *
337
- * @see https://reactrouter.com/api/useInRouterContext
288
+ * @see https://reactrouter.com/docs/en/v6/api#useinroutercontext
338
289
  */
339
290
 
340
291
  function useInRouterContext() {
@@ -348,7 +299,7 @@
348
299
  * "routing" in your app, and we'd like to know what your use case is. We may
349
300
  * be able to provide something higher-level to better suit your needs.
350
301
  *
351
- * @see https://reactrouter.com/api/useLocation
302
+ * @see https://reactrouter.com/docs/en/v6/api#uselocation
352
303
  */
353
304
 
354
305
  function useLocation() {
@@ -357,12 +308,22 @@
357
308
  "useLocation() may be used only in the context of a <Router> component.") : void 0;
358
309
  return React.useContext(LocationContext).location;
359
310
  }
311
+ /**
312
+ * Returns the current navigation action which describes how the router came to
313
+ * the current location, either by a pop, push, or replace on the history stack.
314
+ *
315
+ * @see https://reactrouter.com/docs/en/v6/api#usenavigationtype
316
+ */
317
+
318
+ function useNavigationType() {
319
+ return React.useContext(LocationContext).navigationType;
320
+ }
360
321
  /**
361
322
  * Returns true if the URL for the given "to" value matches the current URL.
362
323
  * This is useful for components that need to know "active" state, e.g.
363
324
  * <NavLink>.
364
325
  *
365
- * @see https://reactrouter.com/api/useMatch
326
+ * @see https://reactrouter.com/docs/en/v6/api#usematch
366
327
  */
367
328
 
368
329
  function useMatch(pattern) {
@@ -379,7 +340,7 @@
379
340
  * Returns an imperative method for changing the location. Used by <Link>s, but
380
341
  * may also be used by other elements to change the location.
381
342
  *
382
- * @see https://reactrouter.com/api/useNavigate
343
+ * @see https://reactrouter.com/docs/en/v6/api#usenavigate
383
344
  */
384
345
  function useNavigate() {
385
346
  !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
@@ -390,11 +351,12 @@
390
351
  navigator
391
352
  } = React.useContext(NavigationContext);
392
353
  let {
393
- pathname: routePathname
354
+ matches
394
355
  } = React.useContext(RouteContext);
395
356
  let {
396
357
  pathname: locationPathname
397
358
  } = useLocation();
359
+ let routePathnamesJson = JSON.stringify(matches.map(match => match.pathnameBase));
398
360
  let activeRef = React.useRef(false);
399
361
  React.useEffect(() => {
400
362
  activeRef.current = true;
@@ -412,21 +374,21 @@
412
374
  return;
413
375
  }
414
376
 
415
- let path = resolveTo(to, routePathname, locationPathname);
377
+ let path = resolveTo(to, JSON.parse(routePathnamesJson), locationPathname);
416
378
 
417
379
  if (basename !== "/") {
418
380
  path.pathname = joinPaths([basename, path.pathname]);
419
381
  }
420
382
 
421
383
  (!!options.replace ? navigator.replace : navigator.push)(path, options.state);
422
- }, [basename, navigator, routePathname, locationPathname]);
384
+ }, [basename, navigator, routePathnamesJson, locationPathname]);
423
385
  return navigate;
424
386
  }
425
387
  /**
426
388
  * Returns the element for the child route at this level of the route
427
389
  * hierarchy. Used internally by <Outlet> to render child routes.
428
390
  *
429
- * @see https://reactrouter.com/api/useOutlet
391
+ * @see https://reactrouter.com/docs/en/v6/api#useoutlet
430
392
  */
431
393
 
432
394
  function useOutlet() {
@@ -436,26 +398,31 @@
436
398
  * Returns an object of key/value pairs of the dynamic params from the current
437
399
  * URL that were matched by the route path.
438
400
  *
439
- * @see https://reactrouter.com/api/useParams
401
+ * @see https://reactrouter.com/docs/en/v6/api#useparams
440
402
  */
441
403
 
442
404
  function useParams() {
443
- return React.useContext(RouteContext).params;
405
+ let {
406
+ matches
407
+ } = React.useContext(RouteContext);
408
+ let routeMatch = matches[matches.length - 1];
409
+ return routeMatch ? routeMatch.params : {};
444
410
  }
445
411
  /**
446
412
  * Resolves the pathname of the given `to` value against the current location.
447
413
  *
448
- * @see https://reactrouter.com/api/useResolvedPath
414
+ * @see https://reactrouter.com/docs/en/v6/api#useresolvedpath
449
415
  */
450
416
 
451
417
  function useResolvedPath(to) {
452
418
  let {
453
- pathname: routePathname
419
+ matches
454
420
  } = React.useContext(RouteContext);
455
421
  let {
456
422
  pathname: locationPathname
457
423
  } = useLocation();
458
- return React.useMemo(() => resolveTo(to, routePathname, locationPathname), [to, routePathname, locationPathname]);
424
+ let routePathnamesJson = JSON.stringify(matches.map(match => match.pathnameBase));
425
+ return React.useMemo(() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname), [to, routePathnamesJson, locationPathname]);
459
426
  }
460
427
  /**
461
428
  * Returns the element of the route that matched the current location, prepared
@@ -463,7 +430,7 @@
463
430
  * elements in the tree must render an <Outlet> to render their child route's
464
431
  * element.
465
432
  *
466
- * @see https://reactrouter.com/api/useRoutes
433
+ * @see https://reactrouter.com/docs/en/v6/api#useroutes
467
434
  */
468
435
 
469
436
  function useRoutes(routes, locationArg) {
@@ -471,11 +438,13 @@
471
438
  // router loaded. We can help them understand how to avoid that.
472
439
  "useRoutes() may be used only in the context of a <Router> component.") : void 0;
473
440
  let {
474
- params: parentParams,
475
- pathname: parentPathname,
476
- pathnameBase: parentPathnameBase,
477
- route: parentRoute
441
+ matches: parentMatches
478
442
  } = React.useContext(RouteContext);
443
+ let routeMatch = parentMatches[parentMatches.length - 1];
444
+ let parentParams = routeMatch ? routeMatch.params : {};
445
+ let parentPathname = routeMatch ? routeMatch.pathname : "/";
446
+ let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : "/";
447
+ let parentRoute = routeMatch && routeMatch.route;
479
448
 
480
449
  {
481
450
  // You won't get a warning about 2 different <Routes> under a <Route>
@@ -523,13 +492,14 @@
523
492
 
524
493
  {
525
494
  warning(parentRoute || matches != null, "No routes matched location \"" + location.pathname + location.search + location.hash + "\" ") ;
495
+ warning(matches == null || matches[matches.length - 1].route.element !== undefined, "Matched leaf route at location \"" + location.pathname + location.search + location.hash + "\" does not have an element. " + "This means it will render an <Outlet /> with a null value by default resulting in an \"empty\" page.") ;
526
496
  }
527
497
 
528
- return renderMatches(matches && matches.map(match => Object.assign({}, match, {
498
+ return _renderMatches(matches && matches.map(match => Object.assign({}, match, {
529
499
  params: Object.assign({}, parentParams, match.params),
530
500
  pathname: joinPaths([parentPathnameBase, match.pathname]),
531
- pathnameBase: joinPaths([parentPathnameBase, match.pathnameBase])
532
- })));
501
+ pathnameBase: match.pathnameBase === "/" ? parentPathnameBase : joinPaths([parentPathnameBase, match.pathnameBase])
502
+ })), parentMatches);
533
503
  } ///////////////////////////////////////////////////////////////////////////////
534
504
  // UTILS
535
505
  ///////////////////////////////////////////////////////////////////////////////
@@ -539,7 +509,7 @@
539
509
  * either a `<Route>` element or an array of them. Used internally by
540
510
  * `<Routes>` to create a route config from its children.
541
511
  *
542
- * @see https://reactrouter.com/api/createRoutesFromChildren
512
+ * @see https://reactrouter.com/docs/en/v6/api#createroutesfromchildren
543
513
  */
544
514
 
545
515
  function createRoutesFromChildren(children) {
@@ -557,6 +527,7 @@
557
527
  return;
558
528
  }
559
529
 
530
+ !(element.type === Route) ? 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>") : void 0;
560
531
  let route = {
561
532
  caseSensitive: element.props.caseSensitive,
562
533
  element: element.props.element,
@@ -579,7 +550,7 @@
579
550
  /**
580
551
  * Returns a path with params interpolated.
581
552
  *
582
- * @see https://reactrouter.com/api/generatePath
553
+ * @see https://reactrouter.com/docs/en/v6/api#generatepath
583
554
  */
584
555
  function generatePath(path, params) {
585
556
  if (params === void 0) {
@@ -598,7 +569,7 @@
598
569
  /**
599
570
  * Matches the given routes to a location and returns the match data.
600
571
  *
601
- * @see https://reactrouter.com/api/matchRoutes
572
+ * @see https://reactrouter.com/docs/en/v6/api#matchroutes
602
573
  */
603
574
  function matchRoutes(routes, locationArg, basename) {
604
575
  if (basename === void 0) {
@@ -666,7 +637,7 @@
666
637
 
667
638
  branches.push({
668
639
  path,
669
- score: computeScore(path),
640
+ score: computeScore(path, route.index),
670
641
  routesMeta
671
642
  });
672
643
  });
@@ -679,14 +650,15 @@
679
650
  }
680
651
 
681
652
  const paramRe = /^:\w+$/;
682
- const dynamicSegmentValue = 2;
653
+ const dynamicSegmentValue = 3;
654
+ const indexRouteValue = 2;
683
655
  const emptySegmentValue = 1;
684
656
  const staticSegmentValue = 10;
685
657
  const splatPenalty = -2;
686
658
 
687
659
  const isSplat = s => s === "*";
688
660
 
689
- function computeScore(path) {
661
+ function computeScore(path, index) {
690
662
  let segments = path.split("/");
691
663
  let initialScore = segments.length;
692
664
 
@@ -694,6 +666,10 @@
694
666
  initialScore += splatPenalty;
695
667
  }
696
668
 
669
+ if (index) {
670
+ initialScore += indexRouteValue;
671
+ }
672
+
697
673
  return segments.filter(s => !isSplat(s)).reduce((score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === "" ? emptySegmentValue : staticSegmentValue), initialScore);
698
674
  }
699
675
 
@@ -736,7 +712,11 @@
736
712
  pathnameBase: joinPaths([matchedPathname, match.pathnameBase]),
737
713
  route
738
714
  });
739
- matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);
715
+
716
+ if (match.pathnameBase !== "/") {
717
+ matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);
718
+ }
719
+
740
720
  routes = route.children;
741
721
  }
742
722
 
@@ -748,16 +728,21 @@
748
728
 
749
729
 
750
730
  function renderMatches(matches) {
731
+ return _renderMatches(matches);
732
+ }
733
+
734
+ function _renderMatches(matches, parentMatches) {
735
+ if (parentMatches === void 0) {
736
+ parentMatches = [];
737
+ }
738
+
751
739
  if (matches == null) return null;
752
- return matches.reduceRight((outlet, match) => {
740
+ return matches.reduceRight((outlet, match, index) => {
753
741
  return /*#__PURE__*/React.createElement(RouteContext.Provider, {
754
- children: match.route.element || /*#__PURE__*/React.createElement(Outlet, null),
742
+ children: match.route.element !== undefined ? match.route.element : /*#__PURE__*/React.createElement(Outlet, null),
755
743
  value: {
756
744
  outlet,
757
- params: match.params,
758
- pathname: match.pathname,
759
- pathnameBase: match.pathnameBase,
760
- route: match.route
745
+ matches: parentMatches.concat(matches.slice(0, index + 1))
761
746
  }
762
747
  });
763
748
  }, null);
@@ -766,11 +751,12 @@
766
751
  * A PathPattern is used to match on some portion of a URL pathname.
767
752
  */
768
753
 
754
+
769
755
  /**
770
756
  * Performs pattern matching on a URL pathname and returns information about
771
757
  * the match.
772
758
  *
773
- * @see https://reactrouter.com/api/matchPath
759
+ * @see https://reactrouter.com/docs/en/v6/api#matchpath
774
760
  */
775
761
  function matchPath(pattern, pathname) {
776
762
  if (typeof pattern === "string") {
@@ -852,7 +838,7 @@
852
838
  /**
853
839
  * Returns a resolved path object relative to the given pathname.
854
840
  *
855
- * @see https://reactrouter.com/api/resolvePath
841
+ * @see https://reactrouter.com/docs/en/v6/api#resolvepath
856
842
  */
857
843
 
858
844
 
@@ -888,17 +874,48 @@
888
874
  return segments.length > 1 ? segments.join("/") : "/";
889
875
  }
890
876
 
891
- function resolveTo(to, routePathname, locationPathname) {
892
- return resolvePath(to, // If a pathname is explicitly provided in `to`, it should be
893
- // relative to the route context. This is explained in `Note on
894
- // `<Link to>` values` in our migration guide from v5 as a means of
895
- // disambiguation between `to` values that begin with `/` and those
896
- // that do not. However, this is problematic for `to` values that do
897
- // not provide a pathname. `to` can simply be a search or hash
898
- // string, in which case we should assume that the navigation is
899
- // relative to the current location's pathname and *not* the
900
- // route pathname.
901
- getToPathname(to) == null ? locationPathname : routePathname);
877
+ function resolveTo(toArg, routePathnames, locationPathname) {
878
+ let to = typeof toArg === "string" ? history.parsePath(toArg) : toArg;
879
+ let toPathname = toArg === "" || to.pathname === "" ? "/" : to.pathname; // If a pathname is explicitly provided in `to`, it should be relative to the
880
+ // route context. This is explained in `Note on `<Link to>` values` in our
881
+ // migration guide from v5 as a means of disambiguation between `to` values
882
+ // that begin with `/` and those that do not. However, this is problematic for
883
+ // `to` values that do not provide a pathname. `to` can simply be a search or
884
+ // hash string, in which case we should assume that the navigation is relative
885
+ // to the current location's pathname and *not* the route pathname.
886
+
887
+ let from;
888
+
889
+ if (toPathname == null) {
890
+ from = locationPathname;
891
+ } else {
892
+ let routePathnameIndex = routePathnames.length - 1;
893
+
894
+ if (toPathname.startsWith("..")) {
895
+ let toSegments = toPathname.split("/"); // Each leading .. segment means "go up one route" instead of "go up one
896
+ // URL segment". This is a key difference from how <a href> works and a
897
+ // major reason we call this a "to" value instead of a "href".
898
+
899
+ while (toSegments[0] === "..") {
900
+ toSegments.shift();
901
+ routePathnameIndex -= 1;
902
+ }
903
+
904
+ to.pathname = toSegments.join("/");
905
+ } // If there are more ".." segments than parent routes, resolve relative to
906
+ // the root / URL.
907
+
908
+
909
+ from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/";
910
+ }
911
+
912
+ let path = resolvePath(to, from); // Ensure the pathname has a trailing slash if the original to value had one.
913
+
914
+ if (toPathname && toPathname !== "/" && toPathname.endsWith("/") && !path.pathname.endsWith("/")) {
915
+ path.pathname += "/";
916
+ }
917
+
918
+ return path;
902
919
  }
903
920
 
904
921
  function getToPathname(to) {
@@ -946,12 +963,12 @@
946
963
  exports.matchRoutes = matchRoutes;
947
964
  exports.renderMatches = renderMatches;
948
965
  exports.resolvePath = resolvePath;
949
- exports.useBlocker = useBlocker;
950
966
  exports.useHref = useHref;
951
967
  exports.useInRouterContext = useInRouterContext;
952
968
  exports.useLocation = useLocation;
953
969
  exports.useMatch = useMatch;
954
970
  exports.useNavigate = useNavigate;
971
+ exports.useNavigationType = useNavigationType;
955
972
  exports.useOutlet = useOutlet;
956
973
  exports.useParams = useParams;
957
974
  exports.useResolvedPath = useResolvedPath;