Skip to content

Commit

Permalink
fix(gatsby-react-router-scroll): Major improvements to scroll handling
Browse files Browse the repository at this point in the history
  • Loading branch information
blainekasten committed May 20, 2020
1 parent 85bb822 commit 8373529
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 170 deletions.
4 changes: 1 addition & 3 deletions packages/gatsby-react-router-scroll/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
"url": "https://github.com/gatsbyjs/gatsby/issues"
},
"dependencies": {
"@babel/runtime": "^7.9.6",
"scroll-behavior": "^0.9.12",
"warning": "^3.0.0"
"@babel/runtime": "^7.9.6"
},
"devDependencies": {
"@babel/cli": "^7.8.4",
Expand Down
110 changes: 52 additions & 58 deletions packages/gatsby-react-router-scroll/src/ScrollBehaviorContext.js
Original file line number Diff line number Diff line change
@@ -1,51 +1,64 @@
import React from "react"
import ScrollBehavior from "scroll-behavior"
import PropTypes from "prop-types"
import { globalHistory as history } from "@reach/router/lib/history"
import SessionStorage from "./StateStorage"

export const ScrollBehaviorContext = React.createContext()

const propTypes = {
shouldUpdateScroll: PropTypes.func,
children: PropTypes.element.isRequired,
location: PropTypes.object.isRequired,
}

class ScrollContext extends React.Component {
export default class ScrollContext extends React.Component {
constructor(props, context) {
super(props, context)

this.scrollBehavior = new ScrollBehavior({
addTransitionHook: history.listen,
stateStorage: new SessionStorage(),
getCurrentLocation: () => this.props.location,
shouldUpdateScroll: this.shouldUpdateScroll,
})
this._stateStorage = new SessionStorage()
}

componentDidUpdate(prevProps) {
const { location } = this.props
const prevLocation = prevProps.location
scrollListener = () => {
const { key } = this.props.location

if (location === prevLocation) {
return
}
this._stateStorage.save(this.props.location, key, window.scrollY)
}

const prevRouterProps = {
location: prevProps.location,
}
componentDidMount() {
window.addEventListener(`scroll`, this.scrollListener)

this.scrollBehavior.updateScroll(prevRouterProps, { history, location })
const scrollPosition = this._stateStorage.read(
this.props.location,
this.props.location.key
)
if (scrollPosition) {
this.windowScroll(scrollPosition)
} else if (this.props.location.hash) {
this.scrollToHash(decodeURI(this.props.location.hash))
}
}

componentWillUnmount() {
this.scrollBehavior.stop()
window.removeEventListener(`scroll`, this.scrollListener)
}

getRouterProps() {
const { location } = this.props
return { location, history }
componentDidUpdate(prevProps) {
const { hash } = this.props.location

const scrollPosition = this._stateStorage.read(
this.props.location,
this.props.location.key
)
if (scrollPosition) {
this.windowScroll(scrollPosition, prevProps)
} else if (hash) {
this.scrollToHash(decodeURI(hash), prevProps)
}
}

windowScroll = (position, prevProps) => {
if (this.shouldUpdateScroll(prevProps, this.props)) {
window.scroll(0, position)
}
}

scrollToHash = (hash, prevProps) => {
const node = document.querySelector(hash)

if (node && this.shouldUpdateScroll(prevProps, this.props)) {
node.scrollIntoView()
}
}

shouldUpdateScroll = (prevRouterProps, routerProps) => {
Expand All @@ -54,36 +67,17 @@ class ScrollContext extends React.Component {
return true
}

// Hack to allow accessing scrollBehavior._stateStorage.
return shouldUpdateScroll.call(
this.scrollBehavior,
prevRouterProps,
routerProps
)
}

registerElement = (key, element, shouldUpdateScroll) => {
this.scrollBehavior.registerElement(
key,
element,
shouldUpdateScroll,
this.getRouterProps()
)
}

unregisterElement = key => {
this.scrollBehavior.unregisterElement(key)
// Hack to allow accessing this._stateStorage.
return shouldUpdateScroll.call(this, prevRouterProps, routerProps)
}

render() {
return (
<ScrollBehaviorContext.Provider value={this}>
{React.Children.only(this.props.children)}
</ScrollBehaviorContext.Provider>
)
return this.props.children
}
}

ScrollContext.propTypes = propTypes

export default ScrollContext
ScrollContext.propTypes = {
shouldUpdateScroll: PropTypes.func,
children: PropTypes.element.isRequired,
location: PropTypes.object.isRequired,
}
83 changes: 0 additions & 83 deletions packages/gatsby-react-router-scroll/src/ScrollContainer.js

This file was deleted.

2 changes: 0 additions & 2 deletions packages/gatsby-react-router-scroll/src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
import ScrollBehaviorContext from "./ScrollBehaviorContext"
import ScrollContainer from "./ScrollContainer"
exports.ScrollContainer = ScrollContainer
exports.ScrollContext = ScrollBehaviorContext
55 changes: 31 additions & 24 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
semver "^5.4.1"
source-map "^0.5.0"

"@babel/core@^7.6.6", "@babel/core@^7.8.7", "@babel/core@^7.9.6":
"@babel/core@^7.8.7", "@babel/core@^7.9.6":
version "7.9.6"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.6.tgz#d9aa1f580abf3b2286ef40b6904d390904c63376"
integrity sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==
Expand Down Expand Up @@ -2015,13 +2015,6 @@
dependencies:
regenerator-runtime "^0.13.2"

"@babel/runtime@^7.1.2", "@babel/runtime@^7.7.4", "@babel/runtime@^7.8.4":
version "7.8.7"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.7.tgz#8fefce9802db54881ba59f90bb28719b4996324d"
integrity sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg==
dependencies:
regenerator-runtime "^0.13.4"

"@babel/runtime@^7.6.3":
version "7.7.4"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.4.tgz#b23a856751e4bf099262f867767889c0e3fe175b"
Expand All @@ -2036,20 +2029,27 @@
dependencies:
regenerator-runtime "^0.13.2"

"@babel/runtime@^7.9.2":
version "7.9.2"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06"
integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==
"@babel/runtime@^7.7.4", "@babel/runtime@^7.8.4":
version "7.8.7"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.7.tgz#8fefce9802db54881ba59f90bb28719b4996324d"
integrity sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg==
dependencies:
regenerator-runtime "^0.13.4"

"@babel/runtime@^7.9.6":
"@babel/runtime@^7.8.7", "@babel/runtime@^7.9.6":
version "7.9.6"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.6.tgz#a9102eb5cadedf3f31d08a9ecf294af7827ea29f"
integrity sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==
dependencies:
regenerator-runtime "^0.13.4"

"@babel/runtime@^7.9.2":
version "7.9.2"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.2.tgz#d90df0583a3a252f09aaa619665367bae518db06"
integrity sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==
dependencies:
regenerator-runtime "^0.13.4"

"@babel/standalone@^7.9.6":
version "7.9.6"
resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.9.6.tgz#7a5f82c6fa29959b12f708213be6de8ec0b79338"
Expand Down Expand Up @@ -8551,7 +8551,7 @@ cssstyle@^2.2.0:
dependencies:
cssom "~0.3.6"

csstype@^2.2.0:
csstype@^2.2.0, csstype@^2.6.7:
version "2.6.10"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.10.tgz#e63af50e66d7c266edb6b32909cfd0aabe03928b"
integrity sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w==
Expand Down Expand Up @@ -9331,12 +9331,13 @@ dom-converter@~0.1:
dependencies:
utila "~0.3"

dom-helpers@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8"
integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==
dom-helpers@^5.1.4:
version "5.1.4"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.1.4.tgz#4609680ab5c79a45f2531441f1949b79d6587f4b"
integrity sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==
dependencies:
"@babel/runtime" "^7.1.2"
"@babel/runtime" "^7.8.7"
csstype "^2.6.7"

dom-serializer@0, dom-serializer@~0.1.0, dom-serializer@~0.1.1:
version "0.1.1"
Expand Down Expand Up @@ -18369,6 +18370,11 @@ package-json@^6.3.0:
registry-url "^5.0.0"
semver "^6.2.0"

page-lifecycle@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/page-lifecycle/-/page-lifecycle-0.1.2.tgz#f17a083c082bd5ababddd77f1025a4b1c8808012"
integrity sha512-+3uccYgL0CXG0KSXRxZi4uc2E6mqFWV5HqiJJgcnaJCiS0LqiuJ4vB420N21NFuLvuvLB4Jr5drgQ2NXAXF9Iw==

pako@^0.2.5:
version "0.2.9"
resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
Expand Down Expand Up @@ -22270,13 +22276,14 @@ schemes@^1.0.1:
dependencies:
extend "^3.0.0"

scroll-behavior@^0.9.12:
version "0.9.12"
resolved "https://registry.yarnpkg.com/scroll-behavior/-/scroll-behavior-0.9.12.tgz#1c22d273ec4ce6cd4714a443fead50227da9424c"
integrity sha512-18sirtyq1P/VsBX6O/vgw20Np+ngduFXEMO4/NDFXabdOKBL2kjPVUpz1y0+jm99EWwFJafxf5/tCyMeXt9Xyg==
scroll-behavior@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/scroll-behavior/-/scroll-behavior-0.11.0.tgz#fff2765b6007341b80a04678fcd314e54d5b03ea"
integrity sha512-wQvNs3Q1TRvEkkwrFd/BkIL+dA4PYQl55/FUlmtjgz63/FtbnyR6MkLyRmjK0Rg3LCZCr0jORsFfMLkeNYdFuA==
dependencies:
dom-helpers "^3.4.0"
dom-helpers "^5.1.4"
invariant "^2.2.4"
page-lifecycle "^0.1.2"

section-matter@^1.0.0:
version "1.0.0"
Expand Down

0 comments on commit 8373529

Please sign in to comment.