clear-react-router 1.4.3 → 1.4.5

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.
@@ -2,6 +2,7 @@ type RouterProps = {
2
2
  isAnimated?: boolean;
3
3
  animationDuration?: number;
4
4
  spinner?: boolean;
5
+ preserveScroll?: boolean;
5
6
  };
6
- export declare const Router: ({ isAnimated, animationDuration, spinner }: RouterProps) => import("react/jsx-runtime").JSX.Element | null;
7
+ export declare const Router: ({ isAnimated, animationDuration, spinner, preserveScroll }: RouterProps) => import("react/jsx-runtime").JSX.Element | null;
7
8
  export {};
@@ -4,7 +4,6 @@ type RouteProviderProps = {
4
4
  children: ReactNode;
5
5
  routeList: RouteItem[];
6
6
  context?: Record<string, unknown>;
7
- preserveScroll?: boolean;
8
7
  };
9
- export declare const RouterProvider: ({ children, routeList, context: initialContext, preserveScroll, }: RouteProviderProps) => import("react/jsx-runtime").JSX.Element;
8
+ export declare const RouterProvider: ({ children, routeList, context: initialContext }: RouteProviderProps) => import("react/jsx-runtime").JSX.Element;
10
9
  export {};
@@ -7,7 +7,7 @@ export type NavigationContextValue = {
7
7
  location: Location;
8
8
  blockerState: BlockerState;
9
9
  isLoading: boolean;
10
- nextRouteItem: RouteItem | undefined;
10
+ nextItem: RouteItem | undefined;
11
11
  };
12
12
  export type ActionsContextValue = {
13
13
  setLocation: Dispatch<SetStateAction<Location>>;
@@ -6,13 +6,12 @@ type UseHandleNavigation = {
6
6
  context: Record<string, unknown>;
7
7
  revalidateCache(arg: RevalidateCacheArgs): Promise<void>;
8
8
  setContext: Dispatch<SetStateAction<Record<string, unknown>>>;
9
- setScrollMap: Dispatch<SetStateAction<Record<string, number>>>;
10
9
  setLoaderState: Dispatch<SetStateAction<LoaderState>>;
11
10
  };
12
- export declare const useHandleNavigation: ({ setLocation, routeList, context, revalidateCache, setContext, setScrollMap, setLoaderState, }: UseHandleNavigation) => {
11
+ export declare const useHandleNavigation: ({ setLocation, routeList, context, revalidateCache, setContext, setLoaderState, }: UseHandleNavigation) => {
13
12
  blockerState: BlockerState;
14
13
  updateLocation: (nextLocation: Location) => Promise<void>;
15
14
  updateBlockedRoute: ({ type, payload }: UpdateBlockedRouteProps) => void;
16
- nextRouteItem: RouteItem | undefined;
15
+ nextItem: RouteItem | undefined;
17
16
  };
18
17
  export {};
@@ -1,6 +1,7 @@
1
1
  type UsePreserveScrollParams = {
2
2
  pathname: string;
3
3
  preserveScroll: boolean;
4
+ nextPathname?: string;
4
5
  };
5
- export declare const usePreserveScroll: ({ pathname, preserveScroll }: UsePreserveScrollParams) => import("react").Dispatch<import("react").SetStateAction<Record<string, number>>>;
6
+ export declare const usePreserveScroll: ({ pathname, preserveScroll, nextPathname }: UsePreserveScrollParams) => void;
6
7
  export {};
package/dist/index.js CHANGED
@@ -45,7 +45,7 @@ var require_react_jsx_runtime_production = /* @__PURE__ */ __commonJSMin(((expor
45
45
  var import_jsx_runtime = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
46
46
  module.exports = require_react_jsx_runtime_production();
47
47
  })))();
48
- var Provider = ({ children, setContext, context, updateBlockedRoute, updateLocation, location, setLocation, prefetchLoader, loaderState, blockerState, routeList, isLoading, nextRouteItem }) => {
48
+ var Provider = ({ children, setContext, context, updateBlockedRoute, updateLocation, location, setLocation, prefetchLoader, loaderState, blockerState, routeList, isLoading, nextItem }) => {
49
49
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PropsContext.Provider, {
50
50
  value: { routeList },
51
51
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ActionsContext.Provider, {
@@ -66,7 +66,7 @@ var Provider = ({ children, setContext, context, updateBlockedRoute, updateLocat
66
66
  blockerState,
67
67
  location,
68
68
  isLoading,
69
- nextRouteItem
69
+ nextItem
70
70
  },
71
71
  children
72
72
  })
@@ -136,22 +136,14 @@ var comparePaths = (el, pathname) => {
136
136
  };
137
137
  //#endregion
138
138
  //#region hooks/useHandleNavigation.ts
139
- var useHandleNavigation = ({ setLocation, routeList, context, revalidateCache, setContext, setScrollMap, setLoaderState }) => {
139
+ var useHandleNavigation = ({ setLocation, routeList, context, revalidateCache, setContext, setLoaderState }) => {
140
140
  const [blockedRoute, setBlockedRoute] = useState({
141
141
  from: "",
142
142
  to: ""
143
143
  });
144
- const [nextRouteItem, setNextRouteItem] = useState();
144
+ const [nextItem, setNextItem] = useState();
145
145
  const prevPathname = useRef("");
146
146
  const navigationSeq = useRef(0);
147
- const updateScrollMap = useCallback(() => setScrollMap((prevState) => {
148
- const scrollPosition = document.scrollingElement?.scrollTop ?? 0;
149
- if (!scrollPosition || prevState[prevPathname.current] === scrollPosition) return prevState;
150
- return {
151
- ...prevState,
152
- [prevPathname.current]: scrollPosition
153
- };
154
- }), [setScrollMap]);
155
147
  const navigation = useCallback((nextLocation) => {
156
148
  setLocation(nextLocation);
157
149
  prevPathname.current = nextLocation.pathname;
@@ -169,9 +161,8 @@ var useHandleNavigation = ({ setLocation, routeList, context, revalidateCache, s
169
161
  const navigationHandler = useCallback(async (nextLocation) => {
170
162
  navigationSeq.current = navigationSeq.current + 1;
171
163
  const seq = navigationSeq.current;
172
- updateScrollMap();
173
164
  const nextItem = routeList.find((el) => comparePaths(el, nextLocation.pathname));
174
- setNextRouteItem(nextItem);
165
+ setNextItem(nextItem);
175
166
  const params = getParamsObject({
176
167
  routeItem: nextItem,
177
168
  pathname: nextLocation.pathname
@@ -221,8 +212,7 @@ var useHandleNavigation = ({ setLocation, routeList, context, revalidateCache, s
221
212
  routeList,
222
213
  transitionedNavigation,
223
214
  setContext,
224
- setLoaderState,
225
- updateScrollMap
215
+ setLoaderState
226
216
  ]);
227
217
  const setNextLocationRef = useLatest(navigationHandler);
228
218
  const updateBlockedRoute = useCallback(({ type, payload = "" }) => setBlockedRoute((prevState) => {
@@ -276,7 +266,7 @@ var useHandleNavigation = ({ setLocation, routeList, context, revalidateCache, s
276
266
  }, [blockedRoute]),
277
267
  updateLocation,
278
268
  updateBlockedRoute,
279
- nextRouteItem
269
+ nextItem
280
270
  };
281
271
  };
282
272
  //#endregion
@@ -351,45 +341,23 @@ var useLoader = ({ routeList, context, setContext, setLoaderState }) => {
351
341
  };
352
342
  };
353
343
  //#endregion
354
- //#region hooks/usePreserveScroll.ts
355
- var usePreserveScroll = ({ pathname, preserveScroll }) => {
356
- const [scrollMap, setScrollMap] = useState({});
357
- useEffect(() => {
358
- if (!preserveScroll || !pathname || !scrollMap[pathname]) return;
359
- document.scrollingElement?.scrollTo({
360
- top: scrollMap[pathname],
361
- behavior: "smooth"
362
- });
363
- }, [
364
- pathname,
365
- scrollMap,
366
- preserveScroll
367
- ]);
368
- return setScrollMap;
369
- };
370
- //#endregion
371
344
  //#region components/RouterProvider.tsx
372
- var RouterProvider = ({ children, routeList, context: initialContext = {}, preserveScroll = true }) => {
345
+ var RouterProvider = ({ children, routeList, context: initialContext = {} }) => {
373
346
  const [location, setLocation] = useState({});
374
347
  const [context, setContext] = useState(initialContext);
375
348
  const [loaderState, setLoaderState] = useState({});
376
- const setScrollMap = usePreserveScroll({
377
- pathname: location.pathname,
378
- preserveScroll
379
- });
380
349
  const { prefetchLoader, revalidateCache, isLoading } = useLoader({
381
350
  routeList,
382
351
  context,
383
352
  setContext,
384
353
  setLoaderState
385
354
  });
386
- const { blockerState, updateLocation, updateBlockedRoute, nextRouteItem } = useHandleNavigation({
355
+ const { blockerState, updateLocation, updateBlockedRoute, nextItem } = useHandleNavigation({
387
356
  setLocation,
388
357
  routeList,
389
358
  context,
390
359
  setContext,
391
360
  revalidateCache,
392
- setScrollMap,
393
361
  setLoaderState
394
362
  });
395
363
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Provider, {
@@ -404,7 +372,7 @@ var RouterProvider = ({ children, routeList, context: initialContext = {}, prese
404
372
  context,
405
373
  setContext,
406
374
  routeList,
407
- nextRouteItem,
375
+ nextItem,
408
376
  isLoading
409
377
  }), [
410
378
  blockerState,
@@ -416,7 +384,7 @@ var RouterProvider = ({ children, routeList, context: initialContext = {}, prese
416
384
  routeList,
417
385
  updateBlockedRoute,
418
386
  updateLocation,
419
- nextRouteItem
387
+ nextItem
420
388
  ]),
421
389
  children
422
390
  });
@@ -470,6 +438,34 @@ var useApplyCustomAnimation = (animationDuration) => {
470
438
  }, [animationDuration]);
471
439
  };
472
440
  //#endregion
441
+ //#region hooks/usePreserveScroll.ts
442
+ var usePreserveScroll = ({ pathname, preserveScroll, nextPathname }) => {
443
+ const [scrollMap, setScrollMap] = useState({});
444
+ const prevPathname = useRef("");
445
+ useEffect(() => {
446
+ setScrollMap((prevState) => {
447
+ const scrollPosition = document.scrollingElement?.scrollTop ?? 0;
448
+ if (!scrollPosition || prevState[prevPathname.current] === scrollPosition) return prevState;
449
+ return {
450
+ ...prevState,
451
+ [prevPathname.current]: scrollPosition
452
+ };
453
+ });
454
+ prevPathname.current = pathname;
455
+ }, [pathname, nextPathname]);
456
+ useEffect(() => {
457
+ if (!preserveScroll || !pathname || !scrollMap[pathname]) return;
458
+ document.scrollingElement?.scrollTo({
459
+ top: scrollMap[pathname],
460
+ behavior: "smooth"
461
+ });
462
+ }, [
463
+ pathname,
464
+ scrollMap,
465
+ preserveScroll
466
+ ]);
467
+ };
468
+ //#endregion
473
469
  //#region context/RouterViewContext.ts
474
470
  var RouterViewContext = createContext({});
475
471
  //#endregion
@@ -492,38 +488,39 @@ var renderElement = (Component) => {
492
488
  //#endregion
493
489
  //#region components/Router.tsx
494
490
  var ALL_LOCATIONS = "*";
495
- var Router = ({ isAnimated, animationDuration, spinner = true }) => {
496
- const { location, isLoading, nextRouteItem } = useNavigationState();
491
+ var Router = ({ isAnimated, animationDuration, spinner = true, preserveScroll = true }) => {
492
+ const { location, isLoading, nextItem } = useNavigationState();
497
493
  const { routeList } = usePropsData();
498
494
  const { loaderState } = useRouterData();
495
+ usePreserveScroll({
496
+ nextPathname: nextItem?.path,
497
+ pathname: location.pathname,
498
+ preserveScroll
499
+ });
499
500
  useApplyCustomAnimation(animationDuration);
500
501
  const routeItem = useMemo(() => {
501
502
  if (!location.pathname) return void 0;
502
503
  return routeList.find((el) => el.path === ALL_LOCATIONS || comparePaths(el, location.pathname));
503
504
  }, [location.pathname, routeList]);
504
- const pendingRoute = useMemo(() => {
505
- if (location.pathname) return void 0;
506
- return routeList.find((el) => comparePaths(el, window.location.pathname));
507
- }, [location.pathname, routeList]);
508
505
  const params = useMemo(() => {
509
506
  return getParamsObject({
510
- routeItem: routeItem || pendingRoute,
507
+ routeItem: routeItem || nextItem,
511
508
  pathname: location.pathname || window.location.pathname
512
509
  });
513
510
  }, [
514
511
  location.pathname,
515
512
  routeItem,
516
- pendingRoute
513
+ nextItem
517
514
  ]);
518
515
  const shouldErrorElementShown = useMemo(() => Boolean(loaderState[location.pathname]?.loaderError || loaderState[location.pathname]?.beforeLoadError), [loaderState, location.pathname]);
519
- if (!routeItem && !pendingRoute) return null;
520
- if (!routeItem && pendingRoute) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ViewProvider, {
516
+ if (!routeItem && !nextItem) return null;
517
+ if (!routeItem && nextItem) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ViewProvider, {
521
518
  params,
522
- children: renderElement(pendingRoute?.loaderFallback)
519
+ children: renderElement(nextItem?.loaderFallback)
523
520
  });
524
521
  if (!isAnimated && !shouldErrorElementShown && isLoading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ViewProvider, {
525
522
  params,
526
- children: renderElement(nextRouteItem?.loaderFallback)
523
+ children: renderElement(nextItem?.loaderFallback)
527
524
  });
528
525
  if (shouldErrorElementShown) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ViewProvider, {
529
526
  params,
@@ -3,5 +3,5 @@ import { type ActionsContextValue, type DataContextValue, type NavigationContext
3
3
  type ProviderProps = PropsContextValue & NavigationContextValue & ActionsContextValue & DataContextValue & {
4
4
  children: ReactNode;
5
5
  };
6
- export declare const Provider: ({ children, setContext, context, updateBlockedRoute, updateLocation, location, setLocation, prefetchLoader, loaderState, blockerState, routeList, isLoading, nextRouteItem, }: ProviderProps) => import("react/jsx-runtime").JSX.Element;
6
+ export declare const Provider: ({ children, setContext, context, updateBlockedRoute, updateLocation, location, setLocation, prefetchLoader, loaderState, blockerState, routeList, isLoading, nextItem, }: ProviderProps) => import("react/jsx-runtime").JSX.Element;
7
7
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clear-react-router",
3
- "version": "1.4.3",
3
+ "version": "1.4.5",
4
4
  "description": "A lightweight, type-safe routing library for React applications",
5
5
  "author": "Andrew Bubnov",
6
6
  "scripts": {