From 4707ad9e1d2bade4a97cafc1706ca82fd449d73f Mon Sep 17 00:00:00 2001 From: Clara Youdale Date: Thu, 6 Jun 2024 12:16:29 -0300 Subject: [PATCH 1/3] Add smooth scroll behavior --- site/gatsby-site/src/global.css | 1 + 1 file changed, 1 insertion(+) diff --git a/site/gatsby-site/src/global.css b/site/gatsby-site/src/global.css index 4d4546fce9..6baf65438f 100644 --- a/site/gatsby-site/src/global.css +++ b/site/gatsby-site/src/global.css @@ -46,6 +46,7 @@ html { body { font-family: 'Karla', sans-serif !important; font-size: 16px; + scroll-behavior: smooth; } html, body, #___gatsby, #gatsby-focus-wrapper { From d0d81b8fcb8fb7abd3636efab0394a676a565721 Mon Sep 17 00:00:00 2001 From: Clara Youdale Date: Thu, 6 Jun 2024 15:29:45 -0300 Subject: [PATCH 2/3] Add function that scrolls when element exists --- site/gatsby-site/gatsby-browser.js | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/site/gatsby-site/gatsby-browser.js b/site/gatsby-site/gatsby-browser.js index c696ab0023..9d5c3d6c57 100644 --- a/site/gatsby-site/gatsby-browser.js +++ b/site/gatsby-site/gatsby-browser.js @@ -12,6 +12,32 @@ export const shouldUpdateScroll = ({ routerProps: { location } }) => { } }; +const onRouteUpdate = ({ location }) => scrollToAnchor(location); + +function scrollToAnchor(location, mainNavHeight = 0) { + if (location && location.hash) { + const checkAndScroll = () => { + if (document.readyState === 'complete') { + const item = document.querySelector(location.hash); + + if (item) { + const itemTop = item.offsetTop; + + window.scrollTo({ + top: itemTop - mainNavHeight, + behavior: 'smooth', + }); + } + } else { + requestAnimationFrame(checkAndScroll); + } + }; + + requestAnimationFrame(checkAndScroll); + } + return true; +} + import { wrapRootElement, wrapPageElement } from './gatsby-shared'; -export { wrapPageElement, wrapRootElement }; +export { wrapPageElement, wrapRootElement, onRouteUpdate }; From 6705be2d81a131ff673f515634f47b102c1391ff Mon Sep 17 00:00:00 2001 From: Clara Youdale Date: Fri, 7 Jun 2024 13:12:49 -0300 Subject: [PATCH 3/3] Add comment to function --- site/gatsby-site/gatsby-browser.js | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/site/gatsby-site/gatsby-browser.js b/site/gatsby-site/gatsby-browser.js index 9d5c3d6c57..c0d402c64b 100644 --- a/site/gatsby-site/gatsby-browser.js +++ b/site/gatsby-site/gatsby-browser.js @@ -14,6 +14,14 @@ export const shouldUpdateScroll = ({ routerProps: { location } }) => { const onRouteUpdate = ({ location }) => scrollToAnchor(location); +/** + * Scrolls smoothly to the anchor specified in the URL hash. + * If the page is still loading, it waits until the document is fully loaded. + * It uses requestAnimationFrame for efficient checking and scrolling. + * + * @param {object} location - The location object containing the URL. + * @param {number} mainNavHeight - The height of the main navigation to offset the scroll position (default is 0). + */ function scrollToAnchor(location, mainNavHeight = 0) { if (location && location.hash) { const checkAndScroll = () => { @@ -21,10 +29,21 @@ function scrollToAnchor(location, mainNavHeight = 0) { const item = document.querySelector(location.hash); if (item) { - const itemTop = item.offsetTop; + const itemTop = item.offsetTop - mainNavHeight; + + const itemBottom = itemTop + item.offsetHeight; + + const viewportTop = window.scrollY; + + const viewportBottom = viewportTop + window.innerHeight; + + // Check if the item is already in view + if (itemBottom > viewportTop && itemTop < viewportBottom) { + return; + } window.scrollTo({ - top: itemTop - mainNavHeight, + top: itemTop, behavior: 'smooth', }); }