@@ -24,6 +24,7 @@ import type {
2424 RelativeRoutingType ,
2525 Router as DataRouter ,
2626 RouterInit ,
27+ ScrollToFunction ,
2728} from "../router/router" ;
2829import { IDLE_FETCHER , createRouter } from "../router/router" ;
2930import type {
@@ -1934,6 +1935,11 @@ export type ScrollRestorationProps = ScriptsProps & {
19341935 * Defaults to `"react-router-scroll-positions"`.
19351936 */
19361937 storageKey ?: string ;
1938+ /**
1939+ * A function that will be called to scroll to a specific position. Defaults to
1940+ * `window.scrollTo(0, y)`. This is useful for custom scroll restoration.
1941+ */
1942+ scrollTo ?: ScrollToFunction ;
19371943} ;
19381944
19391945/**
@@ -1968,19 +1974,21 @@ export type ScrollRestorationProps = ScriptsProps & {
19681974 * @param {ScrollRestorationProps.getKey } props.getKey n/a
19691975 * @param {ScriptsProps.nonce } props.nonce n/a
19701976 * @param {ScrollRestorationProps.storageKey } props.storageKey n/a
1977+ * @param {ScrollRestorationProps.scrollTo } props.scrollTo n/a
19711978 * @returns A [`<script>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)
19721979 * tag that restores scroll positions on navigation.
19731980 */
19741981export function ScrollRestoration ( {
19751982 getKey,
19761983 storageKey,
1984+ scrollTo,
19771985 ...props
19781986} : ScrollRestorationProps ) {
19791987 let remixContext = React . useContext ( FrameworkContext ) ;
19801988 let { basename } = React . useContext ( NavigationContext ) ;
19811989 let location = useLocation ( ) ;
19821990 let matches = useMatches ( ) ;
1983- useScrollRestoration ( { getKey, storageKey } ) ;
1991+ useScrollRestoration ( { getKey, storageKey, scrollTo } ) ;
19841992
19851993 // In order to support `getKey`, we need to compute a "key" here so we can
19861994 // hydrate that up so that SSR scroll restoration isn't waiting on React to
@@ -2019,7 +2027,7 @@ export function ScrollRestoration({
20192027 let positions = JSON . parse ( sessionStorage . getItem ( storageKey ) || "{}" ) ;
20202028 let storedY = positions [ restoreKey || window . history . state . key ] ;
20212029 if ( typeof storedY === "number" ) {
2022- window . scrollTo ( 0 , storedY ) ;
2030+ scrollTo ? scrollTo ( storedY ) : window . scrollTo ( 0 , storedY ) ;
20232031 }
20242032 } catch ( error : unknown ) {
20252033 console . error ( error ) ;
@@ -2911,14 +2919,19 @@ function getScrollRestorationKey(
29112919 * to `location.key`.
29122920 * @param options.storageKey The key to use for storing scroll positions in
29132921 * `sessionStorage`. Defaults to `"react-router-scroll-positions"`.
2922+ * @param options.scrollTo A function that will be called to scroll to a
2923+ * specific position. Defaults to `window.scrollTo(0, y)`. This is useful for custom
2924+ * scroll restoration.
29142925 * @returns {void }
29152926 */
29162927export function useScrollRestoration ( {
29172928 getKey,
29182929 storageKey,
2930+ scrollTo,
29192931} : {
29202932 getKey ?: GetScrollRestorationKeyFunction ;
29212933 storageKey ?: string ;
2934+ scrollTo ?: ScrollToFunction ;
29222935} = { } ) : void {
29232936 let { router } = useDataRouterContext ( DataRouterHook . UseScrollRestoration ) ;
29242937 let { restoreScrollPosition, preventScrollReset } = useDataRouterState (
@@ -2999,7 +3012,7 @@ export function useScrollRestoration({
29993012
30003013 // been here before, scroll to it
30013014 if ( typeof restoreScrollPosition === "number" ) {
3002- window . scrollTo ( 0 , restoreScrollPosition ) ;
3015+ scrollTo ? scrollTo ( restoreScrollPosition ) : window . scrollTo ( 0 , restoreScrollPosition ) ;
30033016 return ;
30043017 }
30053018
@@ -3029,7 +3042,7 @@ export function useScrollRestoration({
30293042 }
30303043
30313044 // otherwise go to the top on new locations
3032- window . scrollTo ( 0 , 0 ) ;
3045+ scrollTo ? scrollTo ( 0 ) : window . scrollTo ( 0 , 0 ) ;
30333046 } , [ location , restoreScrollPosition , preventScrollReset ] ) ;
30343047 }
30353048}
0 commit comments