Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix scroll related issues #8061

Merged
merged 16 commits into from
Sep 24, 2018
Merged

Conversation

stefanprobst
Copy link
Contributor

Attempt to solve some scroll related issues:

const results = apiRunner(`shouldUpdateScroll`, {
prevRouterProps,
pathname,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that if we leave pathname here for backward compatibility, this change would potentially could go in

@stefanprobst
Copy link
Contributor Author

Not sure why location is still needed in <Link />, but tests fail without it, Will have a look tomorrow.

@stefanprobst
Copy link
Contributor Author

This should be good to go, let me know if there's anything else missing from my side.

@tomsseisums
Copy link
Contributor

pathname,
routerProps,
savedScrollPositions: this._stateStorage,
Copy link
Contributor

@tomsseisums tomsseisums Sep 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The naming here doesn't match the actual behavior. You don't get positions, you only get the storage.

But getting the storage here, implies you have to know how it works.

AFAIK, it isn't documented as it wasn't really a public API up until now. And when exposed to public, it should get documented, at least an example for how one might use it in shouldUpdateScroll...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, will update the docs with an example. Maybe it's enough to expose getSavedScrollPosition: this._stateStorage.read?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That'd seem to be better, yeah.

pathname,
routerProps,
Copy link
Contributor

@tomsseisums tomsseisums Sep 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm scared about history being passed here, same as I'm not a fan of location.replace/location.reload.

I wouldn't expose functionality that could be abused outside the normal loop of things potentially causing unexpected results.

@stefanprobst
Copy link
Contributor Author

Updated the docs, plucked off location from routerProps, and read() from the scroll position session store.
Still to do: docs should say what the return value of shouldUpdateScroll means, and maybe also that the positions are internally stored in SessionStorage, so survive a reload.
Question: Passing on read() works because of this, which is marked as a "hack". Is it okay to rely on that?

@tomsseisums
Copy link
Contributor

Updated the docs, plucked off location from routerProps, and read() from the scroll position session store.

history, not location. 🙂

@stefanprobst
Copy link
Contributor Author

Help! Could anybody give me some hints how to turn this into proper jsdoc, thanks!

/**
 * Allow a plugin to decide if the scroll position should update or
 * not on a route change.
 * 
 * @callback getSavedScrollPosition
 * @param {object} location A location object.
 * @param {string} location.pathname The path of the route.
 * @returns {Array|null} An [x, y] array of coordinates, or `null` if nothing was found.
 *
 * @function shouldUpdateScroll
 * @param {object} $0
 * @param {object} $0.prevRouterProps The previous state of the router before the route change.
 * @param {object} $0.routerProps The current state of the router.
 * @param {string} $0.pathname The new pathname (for backwards compatibility with v1).
 * @param {getSavedScrollPosition} $0.getSavedScrollPosition Takes a location and returns the coordinates of
 * the last scroll position for that location, or `null`. Gatsby saves scroll positions for each route
 * in `SessionStorage`, so they are available after page reload.
 * @returns {boolean|string|Array} Should return either an [x, y] Array of coordinates to scroll to,
 * a string of the `id` or `name` of an element to scroll to, `false` to not update the scroll position,
 * or `true` for the default behavior.
 * @example
 * exports.shouldUpdateScroll = ({
 *   routerProps: { location },
 *   getSavedScrollPosition
 * }) => {
 *   const currentPosition = getSavedScrollPosition(location)
 *   const queriedPosition = getSavedScrollPosition({ pathname: '/random' })
 *
 *   window.scrollTo(...(currentPosition || [0, 0]))
 *
 *   return false
 * }
 */
exports.shouldUpdateScroll = true

@tomsseisums
Copy link
Contributor

@stefanprobst what exactly is the problem over there?

@stefanprobst
Copy link
Contributor Author

@joltmode Neither @callback nor the @returns show up (nothing in React DevTools). This is all very probably because I'm doing this wrong, but could also be something to do with documentationjs or the transformer gatsby uses.

Unfortunately I could not find an example in the gatsby docs to emulate - the closest seems onCreateWebpackConfig.getConfig, which incidentally is also broken.

So my question is how to document getSavedScrollPosition and the return values correctly?

@stefanprobst
Copy link
Contributor Author

stefanprobst commented Sep 15, 2018

Updated the docs. Should be good now, apart from the fact that the return values don't show on the website, but that's a bug in gatsby-transformer-documentationjs (does not work for other documented APIs either) which should be fixed by #8208.

@KyleAMathews KyleAMathews force-pushed the master branch 4 times, most recently from b70dd5a to fc4ca3e Compare September 17, 2018 20:16
@pieh pieh self-assigned this Sep 24, 2018
Copy link
Contributor

@pieh pieh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @stefanprobst! Finally got chance to get back to this PR

@pieh pieh merged commit ef44cff into gatsbyjs:master Sep 24, 2018
@stefanprobst
Copy link
Contributor Author

Great, thanks!

oorestisime pushed a commit to oorestisime/gatsby that referenced this pull request Sep 28, 2018
…gatsbyjs#8061)

* Move scroll handling from Link to shouldUpdateScroll

* Pass all router props to shouldUpdateScroll

* Pass saved scroll positions to shouldUpdateScroll

* Let scroll-behavior handle everything

* Let scroll-behavior also handle element checking

* Keep pathname for backwards compatibility

* Make tests pass

* Don't expose history

* Only expose read method

* Update docs

* Update docs

* Lint

* Trigger travis rebuild (empty commit)

* remove TODO, scrollbehaviour in fact does that
@stefanprobst stefanprobst deleted the topics/scroll-behavior branch July 8, 2019 15:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[using-page-transitions] Scrolls to top before animating Fix handling of hash links & scrolling
3 participants