@tanstack/react-router 0.0.1-beta.230 → 0.0.1-beta.231
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/build/cjs/Matches.js +4 -1
- package/build/cjs/Matches.js.map +1 -1
- package/build/cjs/RouterProvider.js +2 -1
- package/build/cjs/RouterProvider.js.map +1 -1
- package/build/cjs/awaited.js +1 -1
- package/build/cjs/awaited.js.map +1 -1
- package/build/cjs/index.js +1 -0
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/router.js +3 -1
- package/build/cjs/router.js.map +1 -1
- package/build/cjs/scroll-restoration.js +52 -29
- package/build/cjs/scroll-restoration.js.map +1 -1
- package/build/esm/index.js +62 -34
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +289 -289
- package/build/types/scroll-restoration.d.ts +12 -0
- package/build/umd/index.development.js +62 -33
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +2 -2
- package/src/Matches.tsx +3 -1
- package/src/RouterProvider.tsx +3 -1
- package/src/awaited.tsx +1 -1
- package/src/router.ts +5 -1
- package/src/scroll-restoration.tsx +81 -43
|
@@ -4,3 +4,15 @@ export type ScrollRestorationOptions = {
|
|
|
4
4
|
};
|
|
5
5
|
export declare function useScrollRestoration(options?: ScrollRestorationOptions): void;
|
|
6
6
|
export declare function ScrollRestoration(props: ScrollRestorationOptions): null;
|
|
7
|
+
export declare function useElementScrollRestoration(options: ({
|
|
8
|
+
id: string;
|
|
9
|
+
getElement?: () => Element | undefined | null;
|
|
10
|
+
} | {
|
|
11
|
+
id?: string;
|
|
12
|
+
getElement: () => Element | undefined | null;
|
|
13
|
+
}) & {
|
|
14
|
+
getKey?: (location: ParsedLocation) => string;
|
|
15
|
+
}): {
|
|
16
|
+
scrollX: number;
|
|
17
|
+
scrollY: number;
|
|
18
|
+
} | undefined;
|
|
@@ -976,7 +976,10 @@
|
|
|
976
976
|
const match = matches[0];
|
|
977
977
|
const routeId = match?.routeId;
|
|
978
978
|
const route = routesById[routeId];
|
|
979
|
-
const
|
|
979
|
+
const router = useRouter();
|
|
980
|
+
const locationKey = router.latestLocation.state?.key;
|
|
981
|
+
// const locationKey = useRouterState().location.state?.key
|
|
982
|
+
|
|
980
983
|
const PendingComponent = route.options.pendingComponent ?? options.defaultPendingComponent;
|
|
981
984
|
const pendingElement = PendingComponent ? /*#__PURE__*/React__namespace.createElement(PendingComponent, {
|
|
982
985
|
useMatch: route.useMatch,
|
|
@@ -1147,9 +1150,10 @@
|
|
|
1147
1150
|
});
|
|
1148
1151
|
const [preState, setState] = React__namespace.useState(() => router.state);
|
|
1149
1152
|
const [isTransitioning, startReactTransition] = React__namespace.useTransition();
|
|
1153
|
+
const isAnyTransitioning = isTransitioning || preState.matches.some(d => d.status === 'pending');
|
|
1150
1154
|
const state = React__namespace.useMemo(() => ({
|
|
1151
1155
|
...preState,
|
|
1152
|
-
status:
|
|
1156
|
+
status: isAnyTransitioning ? 'pending' : 'idle',
|
|
1153
1157
|
location: isTransitioning ? router.latestLocation : preState.location,
|
|
1154
1158
|
pendingMatches: router.pendingMatches
|
|
1155
1159
|
}), [preState, isTransitioning]);
|
|
@@ -1264,7 +1268,7 @@
|
|
|
1264
1268
|
promise.__deferredState = state;
|
|
1265
1269
|
}
|
|
1266
1270
|
if (state.status === 'pending') {
|
|
1267
|
-
throw promise;
|
|
1271
|
+
throw new Promise(r => setTimeout(r, 1)).then(() => promise);
|
|
1268
1272
|
}
|
|
1269
1273
|
if (state.status === 'error') {
|
|
1270
1274
|
throw state.error;
|
|
@@ -2230,6 +2234,7 @@
|
|
|
2230
2234
|
// forcefully show the pending component
|
|
2231
2235
|
if (pendingPromise) {
|
|
2232
2236
|
pendingPromise.then(() => {
|
|
2237
|
+
if (latestPromise = checkLatest()) return;
|
|
2233
2238
|
didShowPending = true;
|
|
2234
2239
|
matches[index] = match = {
|
|
2235
2240
|
...match,
|
|
@@ -2249,6 +2254,7 @@
|
|
|
2249
2254
|
if (didShowPending && pendingMinMs) {
|
|
2250
2255
|
await new Promise(r => setTimeout(r, pendingMinMs));
|
|
2251
2256
|
}
|
|
2257
|
+
if (latestPromise = checkLatest()) return await latestPromise;
|
|
2252
2258
|
matches[index] = match = {
|
|
2253
2259
|
...match,
|
|
2254
2260
|
error: undefined,
|
|
@@ -2317,7 +2323,7 @@
|
|
|
2317
2323
|
// Ingest the new matches
|
|
2318
2324
|
this.setState(s => ({
|
|
2319
2325
|
...s,
|
|
2320
|
-
status: 'pending',
|
|
2326
|
+
// status: 'pending',
|
|
2321
2327
|
location: next,
|
|
2322
2328
|
matches
|
|
2323
2329
|
}));
|
|
@@ -2628,31 +2634,26 @@
|
|
|
2628
2634
|
const windowKey = 'window';
|
|
2629
2635
|
const delimiter = '___';
|
|
2630
2636
|
let weakScrolledElements = new WeakSet();
|
|
2631
|
-
let cache;
|
|
2632
2637
|
const sessionsStorage = typeof window !== 'undefined' && window.sessionStorage;
|
|
2638
|
+
let cache = sessionsStorage ? (() => {
|
|
2639
|
+
const storageKey = 'tsr-scroll-restoration-v2';
|
|
2640
|
+
const state = JSON.parse(window.sessionStorage.getItem(storageKey) || 'null') || {
|
|
2641
|
+
cached: {},
|
|
2642
|
+
next: {}
|
|
2643
|
+
};
|
|
2644
|
+
return {
|
|
2645
|
+
state,
|
|
2646
|
+
set: updater => {
|
|
2647
|
+
cache.state = functionalUpdate(updater, cache.state);
|
|
2648
|
+
window.sessionStorage.setItem(storageKey, JSON.stringify(cache.state));
|
|
2649
|
+
}
|
|
2650
|
+
};
|
|
2651
|
+
})() : undefined;
|
|
2633
2652
|
const defaultGetKey = location => location.state.key;
|
|
2634
2653
|
function useScrollRestoration(options) {
|
|
2635
2654
|
const router = useRouter();
|
|
2636
2655
|
useLayoutEffect(() => {
|
|
2637
2656
|
const getKey = options?.getKey || defaultGetKey;
|
|
2638
|
-
if (sessionsStorage) {
|
|
2639
|
-
if (!cache) {
|
|
2640
|
-
cache = (() => {
|
|
2641
|
-
const storageKey = 'tsr-scroll-restoration-v2';
|
|
2642
|
-
const state = JSON.parse(window.sessionStorage.getItem(storageKey) || 'null') || {
|
|
2643
|
-
cached: {},
|
|
2644
|
-
next: {}
|
|
2645
|
-
};
|
|
2646
|
-
return {
|
|
2647
|
-
state,
|
|
2648
|
-
set: updater => {
|
|
2649
|
-
cache.state = functionalUpdate(updater, cache.state);
|
|
2650
|
-
window.sessionStorage.setItem(storageKey, JSON.stringify(cache.state));
|
|
2651
|
-
}
|
|
2652
|
-
};
|
|
2653
|
-
})();
|
|
2654
|
-
}
|
|
2655
|
-
}
|
|
2656
2657
|
const {
|
|
2657
2658
|
history
|
|
2658
2659
|
} = window;
|
|
@@ -2662,7 +2663,17 @@
|
|
|
2662
2663
|
const onScroll = event => {
|
|
2663
2664
|
if (weakScrolledElements.has(event.target)) return;
|
|
2664
2665
|
weakScrolledElements.add(event.target);
|
|
2665
|
-
|
|
2666
|
+
let elementSelector = '';
|
|
2667
|
+
if (event.target === document || event.target === window) {
|
|
2668
|
+
elementSelector = windowKey;
|
|
2669
|
+
} else {
|
|
2670
|
+
const attrId = event.target.getAttribute('data-scroll-restoration-id');
|
|
2671
|
+
if (attrId) {
|
|
2672
|
+
elementSelector = `[data-scroll-restoration-id="${attrId}"]`;
|
|
2673
|
+
} else {
|
|
2674
|
+
elementSelector = getCssSelector(event.target);
|
|
2675
|
+
}
|
|
2676
|
+
}
|
|
2666
2677
|
if (!cache.state.next[elementSelector]) {
|
|
2667
2678
|
cache.set(c => ({
|
|
2668
2679
|
...c,
|
|
@@ -2676,15 +2687,6 @@
|
|
|
2676
2687
|
}));
|
|
2677
2688
|
}
|
|
2678
2689
|
};
|
|
2679
|
-
const getCssSelector = el => {
|
|
2680
|
-
let path = [],
|
|
2681
|
-
parent;
|
|
2682
|
-
while (parent = el.parentNode) {
|
|
2683
|
-
path.unshift(`${el.tagName}:nth-child(${[].indexOf.call(parent.children, el) + 1})`);
|
|
2684
|
-
el = parent;
|
|
2685
|
-
}
|
|
2686
|
-
return `${path.join(' > ')}`.toLowerCase();
|
|
2687
|
-
};
|
|
2688
2690
|
if (typeof document !== 'undefined') {
|
|
2689
2691
|
document.addEventListener('scroll', onScroll, true);
|
|
2690
2692
|
}
|
|
@@ -2764,6 +2766,32 @@
|
|
|
2764
2766
|
useScrollRestoration(props);
|
|
2765
2767
|
return null;
|
|
2766
2768
|
}
|
|
2769
|
+
function useElementScrollRestoration(options) {
|
|
2770
|
+
const router = useRouter();
|
|
2771
|
+
const getKey = options?.getKey || defaultGetKey;
|
|
2772
|
+
let elementSelector = '';
|
|
2773
|
+
if (options.id) {
|
|
2774
|
+
elementSelector = `[data-scroll-restoration-id="${options.id}"]`;
|
|
2775
|
+
} else {
|
|
2776
|
+
const element = options.getElement?.();
|
|
2777
|
+
if (!element) {
|
|
2778
|
+
return;
|
|
2779
|
+
}
|
|
2780
|
+
elementSelector = getCssSelector(element);
|
|
2781
|
+
}
|
|
2782
|
+
const restoreKey = getKey(router.latestLocation);
|
|
2783
|
+
const cacheKey = [restoreKey, elementSelector].join(delimiter);
|
|
2784
|
+
return cache.state.cached[cacheKey];
|
|
2785
|
+
}
|
|
2786
|
+
function getCssSelector(el) {
|
|
2787
|
+
let path = [],
|
|
2788
|
+
parent;
|
|
2789
|
+
while (parent = el.parentNode) {
|
|
2790
|
+
path.unshift(`${el.tagName}:nth-child(${[].indexOf.call(parent.children, el) + 1})`);
|
|
2791
|
+
el = parent;
|
|
2792
|
+
}
|
|
2793
|
+
return `${path.join(' > ')}`.toLowerCase();
|
|
2794
|
+
}
|
|
2767
2795
|
|
|
2768
2796
|
function useBlocker(message, condition = true) {
|
|
2769
2797
|
const {
|
|
@@ -2889,6 +2917,7 @@
|
|
|
2889
2917
|
exports.typedNavigate = typedNavigate;
|
|
2890
2918
|
exports.useAwaited = useAwaited;
|
|
2891
2919
|
exports.useBlocker = useBlocker;
|
|
2920
|
+
exports.useElementScrollRestoration = useElementScrollRestoration;
|
|
2892
2921
|
exports.useLayoutEffect = useLayoutEffect$1;
|
|
2893
2922
|
exports.useLinkProps = useLinkProps;
|
|
2894
2923
|
exports.useLoaderData = useLoaderData;
|