diff --git a/packages/gatsby-theme-carbon/gatsby-browser.js b/packages/gatsby-theme-carbon/gatsby-browser.js index d88dec901..8cf47f070 100644 --- a/packages/gatsby-theme-carbon/gatsby-browser.js +++ b/packages/gatsby-theme-carbon/gatsby-browser.js @@ -1,9 +1,42 @@ import React from 'react'; import ThemeProvider from './src/components/ThemeProvider'; import { NavContextProvider } from './src/util/context/NavContext'; +import { useSmoothScroll } from './src/util/hooks'; + +const SmoothLoader = ({ children }) => { + useSmoothScroll(); + return children; +}; export const wrapRootElement = ({ element }) => ( - {element} + + {element} + ); + +const getTargetOffset = hash => { + const id = window.decodeURI(hash.replace(`#`, ``)); + if (id !== ``) { + const element = document.getElementById(id); + if (element) { + return element.offsetTop - 48; + } + } + return null; +}; + +export const onInitialClientRender = () => { + requestAnimationFrame(() => { + const offset = getTargetOffset(window.location.hash); + if (offset !== null) { + window.scrollTo(0, offset); + } + }); +}; + +export const shouldUpdateScroll = ({ routerProps: { location } }) => { + const offset = getTargetOffset(location.hash); + return offset !== null ? [0, offset] : true; +}; diff --git a/packages/gatsby-theme-carbon/gatsby-ssr.js b/packages/gatsby-theme-carbon/gatsby-ssr.js index d88dec901..d1da7c6b3 100644 --- a/packages/gatsby-theme-carbon/gatsby-ssr.js +++ b/packages/gatsby-theme-carbon/gatsby-ssr.js @@ -1,3 +1,4 @@ +/* eslint-disable react/no-danger */ import React from 'react'; import ThemeProvider from './src/components/ThemeProvider'; import { NavContextProvider } from './src/util/context/NavContext'; @@ -7,3 +8,28 @@ export const wrapRootElement = ({ element }) => ( {element} ); + +export const onRenderBody = ({ setHeadComponents }) => { + const script = ` + document.addEventListener("DOMContentLoaded", function(event) { + var hash = window.decodeURI(location.hash.replace('#', '')) + if (hash !== '') { + var element = document.getElementById(hash) + if (element) { + var offset = element.offsetTop + // Wait for the browser to finish rendering before scrolling. + setTimeout((function() { + window.scrollTo(0, offset - 48) + }), 0) + } + } + }) + `; + + return setHeadComponents([ +