react-router 0.0.0-experimental-35fa15e5 → 0.0.0-experimental-8bb3ffdf

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.
@@ -3,12 +3,13 @@ import { Action as NavigationType } from "@remix-run/router";
3
3
  import * as React from "react";
4
4
  import type { IndexRouteObject, Navigator, NonIndexRouteObject, RouteMatch, RouteObject } from "./context";
5
5
  export interface FutureConfig {
6
+ v7_relativeSplatPath: boolean;
6
7
  v7_startTransition: boolean;
7
8
  }
8
9
  export interface RouterProviderProps {
9
10
  fallbackElement?: React.ReactNode;
10
11
  router: RemixRouter;
11
- future?: Partial<FutureConfig>;
12
+ future?: Partial<Pick<FutureConfig, "v7_startTransition">>;
12
13
  }
13
14
  /**
14
15
  * Given a Remix Router instance, render the appropriate UI
@@ -106,6 +107,7 @@ export interface RouterProps {
106
107
  navigationType?: NavigationType;
107
108
  navigator: Navigator;
108
109
  static?: boolean;
110
+ future?: Partial<Pick<FutureConfig, "v7_relativeSplatPath">>;
109
111
  }
110
112
  /**
111
113
  * Provides location context for the rest of the app.
@@ -116,7 +118,7 @@ export interface RouterProps {
116
118
  *
117
119
  * @see https://reactrouter.com/router-components/router
118
120
  */
119
- export declare function Router({ basename: basenameProp, children, location: locationProp, navigationType, navigator, static: staticProp, }: RouterProps): React.ReactElement | null;
121
+ export declare function Router({ basename: basenameProp, children, location: locationProp, navigationType, navigator, static: staticProp, future, }: RouterProps): React.ReactElement | null;
120
122
  export interface RoutesProps {
121
123
  children?: React.ReactNode;
122
124
  location?: Partial<Location> | string;
@@ -47,7 +47,7 @@ export interface RouteMatch<ParamKey extends string = string, RouteObjectType ex
47
47
  }
48
48
  export interface DataRouteMatch extends RouteMatch<string, DataRouteObject> {
49
49
  }
50
- export interface DataRouterContextObject extends NavigationContextObject {
50
+ export interface DataRouterContextObject extends Omit<NavigationContextObject, "future"> {
51
51
  router: Router;
52
52
  staticContext?: StaticHandlerContext;
53
53
  }
@@ -82,6 +82,9 @@ interface NavigationContextObject {
82
82
  basename: string;
83
83
  navigator: Navigator;
84
84
  static: boolean;
85
+ future: {
86
+ v7_relativeSplatPath: boolean;
87
+ };
85
88
  }
86
89
  export declare const NavigationContext: React.Context<NavigationContextObject>;
87
90
  interface LocationContextObject {
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * React Router v0.0.0-experimental-35fa15e5
2
+ * React Router v0.0.0-experimental-8bb3ffdf
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * React Router v0.0.0-experimental-35fa15e5
2
+ * React Router v0.0.0-experimental-8bb3ffdf
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -167,6 +167,7 @@ function useNavigateUnstable() {
167
167
  let dataRouterContext = React.useContext(DataRouterContext);
168
168
  let {
169
169
  basename,
170
+ future,
170
171
  navigator
171
172
  } = React.useContext(NavigationContext);
172
173
  let {
@@ -175,7 +176,7 @@ function useNavigateUnstable() {
175
176
  let {
176
177
  pathname: locationPathname
177
178
  } = useLocation();
178
- let routePathnamesJson = JSON.stringify(UNSAFE_getResolveToMatches(matches));
179
+ let routePathnamesJson = JSON.stringify(UNSAFE_getResolveToMatches(matches, future.v7_relativeSplatPath));
179
180
  let activeRef = React.useRef(false);
180
181
  useIsomorphicLayoutEffect(() => {
181
182
  activeRef.current = true;
@@ -248,13 +249,16 @@ function useParams() {
248
249
  function useResolvedPath(to, {
249
250
  relative
250
251
  } = {}) {
252
+ let {
253
+ future
254
+ } = React.useContext(NavigationContext);
251
255
  let {
252
256
  matches
253
257
  } = React.useContext(RouteContext);
254
258
  let {
255
259
  pathname: locationPathname
256
260
  } = useLocation();
257
- let routePathnamesJson = JSON.stringify(UNSAFE_getResolveToMatches(matches));
261
+ let routePathnamesJson = JSON.stringify(UNSAFE_getResolveToMatches(matches, future.v7_relativeSplatPath));
258
262
  return React.useMemo(() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, relative === "path"), [to, routePathnamesJson, locationPathname, relative]);
259
263
  }
260
264
  /**
@@ -325,7 +329,7 @@ function useRoutesImpl(routes, locationArg, dataRouterState, future) {
325
329
  });
326
330
  {
327
331
  UNSAFE_warning(parentRoute || matches != null, `No routes matched location "${location.pathname}${location.search}${location.hash}" `) ;
328
- 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.`) ;
332
+ UNSAFE_warning(matches == null || matches[matches.length - 1].route.element !== undefined || matches[matches.length - 1].route.Component !== undefined || matches[matches.length - 1].route.lazy !== 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.`) ;
329
333
  }
330
334
  let renderedMatches = _renderMatches(matches && matches.map(match => Object.assign({}, match, {
331
335
  params: Object.assign({}, parentParams, match.params),
@@ -422,7 +426,7 @@ class RenderErrorBoundary extends React.Component {
422
426
  // this because the error provided from the app state may be cleared without
423
427
  // the location changing.
424
428
  return {
425
- error: props.error || state.error,
429
+ error: props.error !== undefined ? props.error : state.error,
426
430
  location: state.location,
427
431
  revalidation: props.revalidation || state.revalidation
428
432
  };
@@ -431,7 +435,7 @@ class RenderErrorBoundary extends React.Component {
431
435
  console.error("React Router caught the following error during render", error, errorInfo);
432
436
  }
433
437
  render() {
434
- return this.state.error ? /*#__PURE__*/React.createElement(RouteContext.Provider, {
438
+ return this.state.error !== undefined ? /*#__PURE__*/React.createElement(RouteContext.Provider, {
435
439
  value: this.props.routeContext
436
440
  }, /*#__PURE__*/React.createElement(RouteErrorContext.Provider, {
437
441
  value: this.state.error,
@@ -483,17 +487,24 @@ function _renderMatches(matches, parentMatches = [], dataRouterState = null, fut
483
487
  if (match.route.HydrateFallback || match.route.hydrateFallbackElement) {
484
488
  fallbackIndex = i;
485
489
  }
486
- if (match.route.loader && match.route.id && dataRouterState.loaderData[match.route.id] === undefined && (!dataRouterState.errors || dataRouterState.errors[match.route.id] === undefined)) {
487
- // We found the first route without data/errors which means it's loader
488
- // still needs to run. Flag that we need to render a fallback and
489
- // render up until the appropriate fallback
490
- renderFallback = true;
491
- if (fallbackIndex >= 0) {
492
- renderedMatches = renderedMatches.slice(0, fallbackIndex + 1);
493
- } else {
494
- renderedMatches = [renderedMatches[0]];
490
+ if (match.route.id) {
491
+ let {
492
+ loaderData,
493
+ errors: _errors
494
+ } = dataRouterState;
495
+ let needsToRunLoader = match.route.loader && loaderData[match.route.id] === undefined && (!_errors || _errors[match.route.id] === undefined);
496
+ if (match.route.lazy || needsToRunLoader) {
497
+ // We found the first route that's not ready to render (waiting on
498
+ // lazy, or has a loader that hasn't run yet). Flag that we need to
499
+ // render a fallback and render up until the appropriate fallback
500
+ renderFallback = true;
501
+ if (fallbackIndex >= 0) {
502
+ renderedMatches = renderedMatches.slice(0, fallbackIndex + 1);
503
+ } else {
504
+ renderedMatches = [renderedMatches[0]];
505
+ }
506
+ break;
495
507
  }
496
- break;
497
508
  }
498
509
  }
499
510
  }
@@ -504,7 +515,7 @@ function _renderMatches(matches, parentMatches = [], dataRouterState = null, fut
504
515
  let errorElement = null;
505
516
  let hydrateFallbackElement = null;
506
517
  if (dataRouterState) {
507
- error = errors && match.route.id ? errors[match.route.id] : null;
518
+ error = errors && match.route.id ? errors[match.route.id] : undefined;
508
519
  errorElement = match.route.errorElement || defaultErrorElement;
509
520
  if (renderFallback) {
510
521
  if (fallbackIndex < 0 && index === 0) {
@@ -683,7 +694,7 @@ function useRouteError() {
683
694
  let routeId = useCurrentRouteId(DataRouterStateHook.UseRouteError);
684
695
  // If this was a render error, we put it in a RouteError context inside
685
696
  // of RenderErrorBoundary
686
- if (error) {
697
+ if (error !== undefined) {
687
698
  return error;
688
699
  }
689
700
  // Otherwise look for errors from our data router state
@@ -847,7 +858,7 @@ function RouterProvider({
847
858
  // pick up on any render-driven redirects/navigations (useEffect/<Navigate>)
848
859
  React.useLayoutEffect(() => router.subscribe(setState), [router, setState]);
849
860
  React.useEffect(() => {
850
- UNSAFE_warning(fallbackElement == null || !router.future.v7_partialHydration, "`<RouterProvider fallbackElement>` is deprecated when using `v7_partialHydration`") ;
861
+ UNSAFE_warning(fallbackElement == null || !router.future.v7_partialHydration, "`<RouterProvider fallbackElement>` is deprecated when using " + "`v7_partialHydration`, use a `HydrateFallback` component instead") ;
851
862
  // Only log this once on initial mount
852
863
  // eslint-disable-next-line react-hooks/exhaustive-deps
853
864
  }, []);
@@ -888,8 +899,11 @@ function RouterProvider({
888
899
  basename: basename,
889
900
  location: state.location,
890
901
  navigationType: state.historyAction,
891
- navigator: navigator
892
- }, state.initialized ? /*#__PURE__*/React.createElement(DataRoutes, {
902
+ navigator: navigator,
903
+ future: {
904
+ v7_relativeSplatPath: router.future.v7_relativeSplatPath
905
+ }
906
+ }, state.initialized || router.future.v7_partialHydration ? /*#__PURE__*/React.createElement(DataRoutes, {
893
907
  routes: router.routes,
894
908
  future: router.future,
895
909
  state: state
@@ -939,7 +953,8 @@ function MemoryRouter({
939
953
  children: children,
940
954
  location: state.location,
941
955
  navigationType: state.action,
942
- navigator: history
956
+ navigator: history,
957
+ future: future
943
958
  });
944
959
  }
945
960
  /**
@@ -961,7 +976,11 @@ function Navigate({
961
976
  // TODO: This error is probably because they somehow have 2 versions of
962
977
  // the router loaded. We can help them understand how to avoid that.
963
978
  `<Navigate> may be used only in the context of a <Router> component.`) : void 0;
964
- 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.`) ;
979
+ let {
980
+ future,
981
+ static: isStatic
982
+ } = React.useContext(NavigationContext);
983
+ UNSAFE_warning(!isStatic, `<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.`) ;
965
984
  let {
966
985
  matches
967
986
  } = React.useContext(RouteContext);
@@ -971,7 +990,7 @@ function Navigate({
971
990
  let navigate = useNavigate();
972
991
  // Resolve the path outside of the effect so that when effects run twice in
973
992
  // StrictMode they navigate to the same place
974
- let path = resolveTo(to, UNSAFE_getResolveToMatches(matches), locationPathname, relative === "path");
993
+ let path = resolveTo(to, UNSAFE_getResolveToMatches(matches, future.v7_relativeSplatPath), locationPathname, relative === "path");
975
994
  let jsonPath = JSON.stringify(path);
976
995
  React.useEffect(() => navigate(JSON.parse(jsonPath), {
977
996
  replace,
@@ -1011,7 +1030,8 @@ function Router({
1011
1030
  location: locationProp,
1012
1031
  navigationType = Action.Pop,
1013
1032
  navigator,
1014
- static: staticProp = false
1033
+ static: staticProp = false,
1034
+ future
1015
1035
  }) {
1016
1036
  !!useInRouterContext() ? UNSAFE_invariant(false, `You cannot render a <Router> inside another <Router>.` + ` You should never have more than one in your app.`) : void 0;
1017
1037
  // Preserve trailing slashes on basename, so we can let the user control
@@ -1020,8 +1040,12 @@ function Router({
1020
1040
  let navigationContext = React.useMemo(() => ({
1021
1041
  basename,
1022
1042
  navigator,
1023
- static: staticProp
1024
- }), [basename, navigator, staticProp]);
1043
+ static: staticProp,
1044
+ future: {
1045
+ v7_relativeSplatPath: false,
1046
+ ...future
1047
+ }
1048
+ }), [basename, future, navigator, staticProp]);
1025
1049
  if (typeof locationProp === "string") {
1026
1050
  locationProp = parsePath(locationProp);
1027
1051
  }