From 1405f6f29e922b5c7cd3ea516ff71b081f8f569b Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Sat, 17 Sep 2022 21:43:18 +0200 Subject: [PATCH] Add handling of smooth scroll in existing router --- packages/next/client/index.tsx | 4 ++++ packages/next/shared/lib/router/router.ts | 14 +++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/next/client/index.tsx b/packages/next/client/index.tsx index 7324cccd7d90849..c0f5d8be0337347 100644 --- a/packages/next/client/index.tsx +++ b/packages/next/client/index.tsx @@ -688,7 +688,11 @@ function doRender(input: RenderRouteInfo): Promise { } if (input.scroll) { + const htmlElement = document.documentElement + const existing = htmlElement.style.scrollBehavior + htmlElement.style.scrollBehavior = 'auto' window.scrollTo(input.scroll.x, input.scroll.y) + htmlElement.style.scrollBehavior = existing } } diff --git a/packages/next/shared/lib/router/router.ts b/packages/next/shared/lib/router/router.ts index cda9125962a0719..c0e6bd190168d03 100644 --- a/packages/next/shared/lib/router/router.ts +++ b/packages/next/shared/lib/router/router.ts @@ -655,6 +655,14 @@ interface FetchNextDataParams { unstable_skipClientCache?: boolean } +function handleSmoothScroll(fn: () => void) { + const htmlElement = document.documentElement + const existing = htmlElement.style.scrollBehavior + htmlElement.style.scrollBehavior = 'auto' + fn() + htmlElement.style.scrollBehavior = existing +} + function tryToParseAsJSON(text: string) { try { return JSON.parse(text) @@ -2141,7 +2149,7 @@ export default class Router implements BaseRouter { // Scroll to top if the hash is just `#` with no value or `#top` // To mirror browsers if (hash === '' || hash === 'top') { - window.scrollTo(0, 0) + handleSmoothScroll(() => window.scrollTo(0, 0)) return } @@ -2150,14 +2158,14 @@ export default class Router implements BaseRouter { // First we check if the element by id is found const idEl = document.getElementById(rawHash) if (idEl) { - idEl.scrollIntoView() + handleSmoothScroll(() => idEl.scrollIntoView()) return } // If there's no element with the id, we check the `name` property // To mirror browsers const nameEl = document.getElementsByName(rawHash)[0] if (nameEl) { - nameEl.scrollIntoView() + handleSmoothScroll(() => nameEl.scrollIntoView()) } }