@tanstack/react-router 0.0.1-beta.241 → 0.0.1-beta.243

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,12 +1,12 @@
1
1
  import * as React from 'react';
2
2
  export declare function CatchBoundary(props: {
3
- resetKey: string;
3
+ getResetKey: () => string;
4
4
  children: any;
5
5
  errorComponent?: any;
6
6
  onCatch: (error: any) => void;
7
7
  }): React.JSX.Element;
8
8
  export declare class CatchBoundaryImpl extends React.Component<{
9
- resetKey: string;
9
+ getResetKey: () => string;
10
10
  children: (props: {
11
11
  error: any;
12
12
  reset: () => void;
@@ -14,11 +14,14 @@ export declare class CatchBoundaryImpl extends React.Component<{
14
14
  onCatch?: (error: any) => void;
15
15
  }> {
16
16
  state: any;
17
+ static getDerivedStateFromProps(props: any): {
18
+ resetKey: any;
19
+ };
17
20
  static getDerivedStateFromError(error: any): {
18
21
  error: any;
19
22
  };
20
23
  componentDidUpdate(prevProps: Readonly<{
21
- resetKey: string;
24
+ getResetKey: () => string;
22
25
  children: (props: {
23
26
  error: any;
24
27
  reset: () => void;
@@ -4,6 +4,7 @@ import { AnyRoute, ReactNode } from './route';
4
4
  import { FullSearchSchema, ParseRoute, RouteById, RouteByPath, RouteIds, RoutePaths } from './routeInfo';
5
5
  import { RegisteredRouter } from './router';
6
6
  import { NoInfer, StrictOrFrom } from './utils';
7
+ export declare const matchContext: React.Context<string | undefined>;
7
8
  export interface RouteMatch<TRouteTree extends AnyRoute = AnyRoute, TRouteId extends RouteIds<TRouteTree> = ParseRoute<TRouteTree>['id']> {
8
9
  id: string;
9
10
  routeId: TRouteId;
@@ -29,8 +30,8 @@ export interface RouteMatch<TRouteTree extends AnyRoute = AnyRoute, TRouteId ext
29
30
  }
30
31
  export type AnyRouteMatch = RouteMatch<any>;
31
32
  export declare function Matches(): React.JSX.Element;
32
- export declare function Match({ matches }: {
33
- matches: RouteMatch[];
33
+ export declare function Match({ matchId }: {
34
+ matchId: string;
34
35
  }): React.JSX.Element;
35
36
  export declare function Outlet(): React.JSX.Element | null;
36
37
  export interface MatchRouteOptions {
@@ -48,7 +49,6 @@ export declare function MatchRoute<TRouteTree extends AnyRoute = RegisteredRoute
48
49
  export declare function useMatch<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>, TStrict extends boolean = true, TRouteMatchState = RouteMatch<TRouteTree, TFrom>, TSelected = TRouteMatchState>(opts: StrictOrFrom<TFrom> & {
49
50
  select?: (match: TRouteMatchState) => TSelected;
50
51
  }): TStrict extends true ? TSelected : TSelected | undefined;
51
- export declare const matchesContext: React.Context<RouteMatch<AnyRoute, any>[]>;
52
52
  export declare function useMatches<T = RouteMatch[]>(opts?: {
53
53
  select?: (matches: RouteMatch[]) => T;
54
54
  }): T;
@@ -611,7 +611,7 @@
611
611
  function CatchBoundary(props) {
612
612
  const errorComponent = props.errorComponent ?? ErrorComponent;
613
613
  return /*#__PURE__*/React__namespace.createElement(CatchBoundaryImpl, {
614
- resetKey: props.resetKey,
614
+ getResetKey: props.getResetKey,
615
615
  onCatch: props.onCatch,
616
616
  children: ({
617
617
  error
@@ -629,13 +629,18 @@
629
629
  state = {
630
630
  error: null
631
631
  };
632
+ static getDerivedStateFromProps(props) {
633
+ return {
634
+ resetKey: props.getResetKey()
635
+ };
636
+ }
632
637
  static getDerivedStateFromError(error) {
633
638
  return {
634
639
  error
635
640
  };
636
641
  }
637
642
  componentDidUpdate(prevProps, prevState) {
638
- if (prevState.error && prevProps.resetKey !== this.props.resetKey) {
643
+ if (prevState.error && prevState.resetKey !== this.state.resetKey) {
639
644
  this.setState({
640
645
  error: null
641
646
  });
@@ -1198,11 +1203,14 @@
1198
1203
 
1199
1204
  //
1200
1205
 
1206
+ const matchContext = /*#__PURE__*/React__namespace.createContext(undefined);
1201
1207
  function Matches() {
1202
1208
  const router = useRouter();
1203
- const routerState = useRouterState();
1204
- const matches = routerState.pendingMatches?.some(d => d.showPending) ? routerState.pendingMatches : routerState.matches;
1205
- const locationKey = routerState.resolvedLocation.state.key;
1209
+ const matchId = useRouterState({
1210
+ select: s => {
1211
+ return getRenderedMatches(s)[0]?.id;
1212
+ }
1213
+ });
1206
1214
  const route = router.routesById[rootRouteId];
1207
1215
  const errorComponent = React__namespace.useCallback(props => {
1208
1216
  return /*#__PURE__*/React__namespace.createElement(ErrorComponent, {
@@ -1213,41 +1221,38 @@
1213
1221
  useParams: route.useParams
1214
1222
  });
1215
1223
  }, [route]);
1216
- return /*#__PURE__*/React__namespace.createElement(matchesContext.Provider, {
1217
- value: matches
1224
+ return /*#__PURE__*/React__namespace.createElement(matchContext.Provider, {
1225
+ value: matchId
1218
1226
  }, /*#__PURE__*/React__namespace.createElement(CatchBoundary, {
1219
- resetKey: locationKey,
1227
+ getResetKey: () => router.state.resolvedLocation.state?.key,
1220
1228
  errorComponent: errorComponent,
1221
1229
  onCatch: () => {
1222
1230
  warning(false, `Error in router! Consider setting an 'errorComponent' in your RootRoute! 👍`);
1223
1231
  }
1224
- }, matches.length ? /*#__PURE__*/React__namespace.createElement(Match, {
1225
- matches: matches
1232
+ }, matchId ? /*#__PURE__*/React__namespace.createElement(Match, {
1233
+ matchId: matchId
1226
1234
  }) : null));
1227
1235
  }
1228
1236
  function SafeFragment(props) {
1229
1237
  return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, props.children);
1230
1238
  }
1231
1239
  function Match({
1232
- matches
1240
+ matchId
1233
1241
  }) {
1234
- const {
1235
- options,
1236
- routesById
1237
- } = useRouter();
1238
- const match = matches[0];
1239
- const routeId = match?.routeId;
1240
- const route = routesById[routeId];
1241
- useRouter();
1242
- const locationKey = useRouterState().resolvedLocation.state?.key;
1243
- const PendingComponent = route.options.pendingComponent ?? options.defaultPendingComponent;
1242
+ const router = useRouter();
1243
+ const routeId = useRouterState({
1244
+ select: s => getRenderedMatches(s).find(d => d.id === matchId)?.routeId
1245
+ });
1246
+ invariant(routeId, `Could not find routeId for matchId "${matchId}". Please file an issue!`);
1247
+ const route = router.routesById[routeId];
1248
+ const PendingComponent = route.options.pendingComponent ?? router.options.defaultPendingComponent;
1244
1249
  const pendingElement = PendingComponent ? /*#__PURE__*/React__namespace.createElement(PendingComponent, {
1245
1250
  useMatch: route.useMatch,
1246
1251
  useRouteContext: route.useRouteContext,
1247
1252
  useSearch: route.useSearch,
1248
1253
  useParams: route.useParams
1249
1254
  }) : undefined;
1250
- const routeErrorComponent = route.options.errorComponent ?? options.defaultErrorComponent ?? ErrorComponent;
1255
+ const routeErrorComponent = route.options.errorComponent ?? router.options.defaultErrorComponent ?? ErrorComponent;
1251
1256
  const ResolvedSuspenseBoundary = route.options.wrapInSuspense ?? pendingElement ? React__namespace.Suspense : SafeFragment;
1252
1257
  const errorComponent = routeErrorComponent ? React__namespace.useCallback(props => {
1253
1258
  return /*#__PURE__*/React__namespace.createElement(routeErrorComponent, {
@@ -1259,30 +1264,33 @@
1259
1264
  });
1260
1265
  }, [route]) : undefined;
1261
1266
  const ResolvedCatchBoundary = errorComponent ? CatchBoundary : SafeFragment;
1262
- return /*#__PURE__*/React__namespace.createElement(matchesContext.Provider, {
1263
- value: matches
1267
+ return /*#__PURE__*/React__namespace.createElement(matchContext.Provider, {
1268
+ value: matchId
1264
1269
  }, /*#__PURE__*/React__namespace.createElement(ResolvedSuspenseBoundary, {
1265
1270
  fallback: pendingElement
1266
1271
  }, /*#__PURE__*/React__namespace.createElement(ResolvedCatchBoundary, {
1267
- resetKey: locationKey,
1272
+ getResetKey: () => router.state.resolvedLocation.state?.key,
1268
1273
  errorComponent: errorComponent,
1269
1274
  onCatch: () => {
1270
- warning(false, `Error in route match: ${match.id}`);
1275
+ warning(false, `Error in route match: ${matchId}`);
1271
1276
  }
1272
1277
  }, /*#__PURE__*/React__namespace.createElement(MatchInner, {
1273
- match: match,
1278
+ matchId: matchId,
1274
1279
  pendingElement: pendingElement
1275
1280
  }))));
1276
1281
  }
1277
1282
  function MatchInner({
1278
- match,
1283
+ matchId,
1279
1284
  pendingElement
1280
1285
  }) {
1281
- const {
1282
- options,
1283
- routesById
1284
- } = useRouter();
1285
- const route = routesById[match.routeId];
1286
+ const router = useRouter();
1287
+ const routeId = useRouterState({
1288
+ select: s => getRenderedMatches(s).find(d => d.id === matchId)?.routeId
1289
+ });
1290
+ const route = router.routesById[routeId];
1291
+ const match = useRouterState({
1292
+ select: s => pick(getRenderedMatches(s).find(d => d.id === matchId), ['status', 'error', 'showPending', 'loadPromise'])
1293
+ });
1286
1294
  if (match.status === 'error') {
1287
1295
  throw match.error;
1288
1296
  }
@@ -1293,7 +1301,7 @@
1293
1301
  throw match.loadPromise;
1294
1302
  }
1295
1303
  if (match.status === 'success') {
1296
- let comp = route.options.component ?? options.defaultComponent;
1304
+ let comp = route.options.component ?? router.options.defaultComponent;
1297
1305
  if (comp) {
1298
1306
  return /*#__PURE__*/React__namespace.createElement(comp, {
1299
1307
  useMatch: route.useMatch,
@@ -1308,12 +1316,19 @@
1308
1316
  invariant(false, 'Idle routeMatch status encountered during rendering! You should never see this. File an issue!');
1309
1317
  }
1310
1318
  function Outlet() {
1311
- const matches = React__namespace.useContext(matchesContext).slice(1);
1312
- if (!matches[0]) {
1319
+ const matchId = React__namespace.useContext(matchContext);
1320
+ const childMatchId = useRouterState({
1321
+ select: s => {
1322
+ const matches = getRenderedMatches(s);
1323
+ const index = matches.findIndex(d => d.id === matchId);
1324
+ return matches[index + 1]?.id;
1325
+ }
1326
+ });
1327
+ if (!childMatchId) {
1313
1328
  return null;
1314
1329
  }
1315
1330
  return /*#__PURE__*/React__namespace.createElement(Match, {
1316
- matches: matches
1331
+ matchId: childMatchId
1317
1332
  });
1318
1333
  }
1319
1334
  function useMatchRoute() {
@@ -1340,46 +1355,47 @@
1340
1355
  }
1341
1356
  return !!params ? props.children : null;
1342
1357
  }
1358
+ function getRenderedMatches(state) {
1359
+ return state.pendingMatches?.some(d => d.showPending) ? state.pendingMatches : state.matches;
1360
+ }
1343
1361
  function useMatch(opts) {
1344
- const nearestMatch = React__namespace.useContext(matchesContext)[0];
1345
- const nearestMatchRouteId = nearestMatch?.routeId;
1346
- const matchRouteId = useRouterState({
1347
- select: state => {
1348
- const matches = state.pendingMatches?.some(d => d.showPending) ? state.pendingMatches : state.matches;
1349
- const match = opts?.from ? matches.find(d => d.routeId === opts?.from) : matches.find(d => d.id === nearestMatch.id);
1350
- return match.routeId;
1351
- }
1352
- });
1362
+ const router = useRouter();
1363
+ const nearestMatchId = React__namespace.useContext(matchContext);
1364
+ const nearestMatchRouteId = getRenderedMatches(router.state).find(d => d.id === nearestMatchId)?.routeId;
1365
+ const matchRouteId = (() => {
1366
+ const matches = getRenderedMatches(router.state);
1367
+ const match = opts?.from ? matches.find(d => d.routeId === opts?.from) : matches.find(d => d.id === nearestMatchId);
1368
+ return match.routeId;
1369
+ })();
1353
1370
  if (opts?.strict ?? true) {
1354
1371
  invariant(nearestMatchRouteId == matchRouteId, `useMatch("${matchRouteId}") is being called in a component that is meant to render the '${nearestMatchRouteId}' route. Did you mean to 'useMatch("${matchRouteId}", { strict: false })' or 'useRoute("${matchRouteId}")' instead?`);
1355
1372
  }
1356
1373
  const matchSelection = useRouterState({
1357
1374
  select: state => {
1358
- const matches = state.pendingMatches?.some(d => d.showPending) ? state.pendingMatches : state.matches;
1359
- const match = opts?.from ? matches.find(d => d.routeId === opts?.from) : matches.find(d => d.id === nearestMatch.id);
1375
+ const match = getRenderedMatches(state).find(d => d.id === nearestMatchId);
1360
1376
  invariant(match, `Could not find ${opts?.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`);
1361
1377
  return opts?.select ? opts.select(match) : match;
1362
1378
  }
1363
1379
  });
1364
1380
  return matchSelection;
1365
1381
  }
1366
- const matchesContext = /*#__PURE__*/React__namespace.createContext(null);
1367
1382
  function useMatches(opts) {
1368
- const contextMatches = React__namespace.useContext(matchesContext);
1383
+ const contextMatchId = React__namespace.useContext(matchContext);
1369
1384
  return useRouterState({
1370
1385
  select: state => {
1371
- let matches = state.pendingMatches?.some(d => d.showPending) ? state.pendingMatches : state.matches;
1372
- matches = matches.slice(matches.findIndex(d => d.id === contextMatches[0]?.id));
1386
+ let matches = getRenderedMatches(state);
1387
+ matches = matches.slice(matches.findIndex(d => d.id === contextMatchId));
1373
1388
  return opts?.select ? opts.select(matches) : matches;
1374
1389
  }
1375
1390
  });
1376
1391
  }
1377
1392
  function useLoaderData(opts) {
1378
- const match = useMatch({
1393
+ return useMatch({
1379
1394
  ...opts,
1380
- select: undefined
1395
+ select: s => {
1396
+ return typeof opts.select === 'function' ? opts.select(s?.loaderData) : s?.loaderData;
1397
+ }
1381
1398
  });
1382
- return typeof opts.select === 'function' ? opts.select(match?.loaderData) : match?.loaderData;
1383
1399
  }
1384
1400
 
1385
1401
  const routerContext = /*#__PURE__*/React__namespace.createContext(null);
@@ -2099,7 +2115,7 @@
2099
2115
  return [parentSearch, searchError];
2100
2116
  }
2101
2117
  })();
2102
- const interpolatedPath = interpolatePath(route.path, routeParams);
2118
+ const interpolatedPath = interpolatePath(route.fullPath, routeParams);
2103
2119
  const matchId = interpolatePath(route.id, routeParams, true) + (route.options.key?.({
2104
2120
  search: preMatchSearch,
2105
2121
  location: this.state.location
@@ -3094,12 +3110,13 @@
3094
3110
  const {
3095
3111
  navigate
3096
3112
  } = useRouter();
3097
- const match = useMatch({
3098
- strict: false
3113
+ const matchPathname = useMatch({
3114
+ strict: false,
3115
+ select: s => s.pathname
3099
3116
  });
3100
3117
  return React__namespace.useCallback(opts => {
3101
3118
  return navigate({
3102
- from: opts?.to ? match.pathname : undefined,
3119
+ from: opts?.to ? matchPathname : undefined,
3103
3120
  ...defaultOpts,
3104
3121
  ...opts
3105
3122
  });
@@ -3171,8 +3188,8 @@
3171
3188
  exports.lazyFn = lazyFn;
3172
3189
  exports.lazyRouteComponent = lazyRouteComponent;
3173
3190
  exports.matchByPath = matchByPath;
3191
+ exports.matchContext = matchContext;
3174
3192
  exports.matchPathname = matchPathname;
3175
- exports.matchesContext = matchesContext;
3176
3193
  exports.parsePathname = parsePathname;
3177
3194
  exports.parseSearchWith = parseSearchWith;
3178
3195
  exports.pick = pick;