From 21f4f577774233e6ad3c78103fbdbad39ba69ff6 Mon Sep 17 00:00:00 2001 From: Ryan Florence Date: Wed, 6 Aug 2014 23:32:41 -0600 Subject: [PATCH] [added] preserveScrollPosition Route/Routes props closes #121 --- docs/api/components/Route.md | 6 ++++++ docs/api/components/Routes.md | 11 +++++++++-- modules/components/Route.js | 9 ++++++++- modules/components/Routes.js | 16 +++++++++++++++- 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/docs/api/components/Route.md b/docs/api/components/Route.md index f225ff12a0..acc1d35f91 100644 --- a/docs/api/components/Route.md +++ b/docs/api/components/Route.md @@ -23,6 +23,12 @@ inherit the path of their parent. The component to be rendered when the route is active. +### `preserveScrollPosition` + +If `true`, the router will not scroll the window up when the route is +transitioned to. Defaults to `false`. Ignored if the parent `` +has been set to `true`. + ### `children` Routes can be nested. When a child route matches, the parent route's diff --git a/docs/api/components/Routes.md b/docs/api/components/Routes.md index 70f95916ac..14e8b943da 100644 --- a/docs/api/components/Routes.md +++ b/docs/api/components/Routes.md @@ -17,8 +17,15 @@ works without a server, if you use `history` your server will need to support it. For browsers that don't support the HTML5 history API the router will -fall back to `window.location` if you choose `history`. This way all -users get the same urls and can share them. +fall back to `window.location` if you choose `history`, in other words, +the router will simply cause a full page reload. This way all users get +the same urls and can share them. + +### `preserveScrollPosition` + +If `true`, the router will not scroll the window up globally when any +route is transitioned to. Defaults to `false`. When `false`, the +`` gets to decide whether or not to scroll on transition. Example ------- diff --git a/modules/components/Route.js b/modules/components/Route.js index b42bccc29c..7085f1a82a 100644 --- a/modules/components/Route.js +++ b/modules/components/Route.js @@ -72,10 +72,17 @@ var Route = React.createClass({ }, + getDefaultProps: function() { + return { + preserveScrollPosition: false + }; + }, + propTypes: { handler: React.PropTypes.any.isRequired, path: React.PropTypes.string, - name: React.PropTypes.string + name: React.PropTypes.string, + preserveScrollPosition: React.PropTypes.bool }, render: function () { diff --git a/modules/components/Routes.js b/modules/components/Routes.js index 55edf01727..3b51346828 100644 --- a/modules/components/Routes.js +++ b/modules/components/Routes.js @@ -54,11 +54,13 @@ var Routes = React.createClass({ propTypes: { location: React.PropTypes.oneOf([ 'hash', 'history' ]).isRequired, + preserveScrollPosition: React.PropTypes.bool }, getDefaultProps: function () { return { - location: 'hash' + location: 'hash', + preserveScrollPosition: false }; }, @@ -339,6 +341,8 @@ function syncWithTransition(routes, transition) { }) }; + // TODO: add functional test + maybeScrollWindow(routes, toMatches[toMatches.length - 1]); routes.setState(state); return state; @@ -436,4 +440,14 @@ function reversedArray(array) { return array.slice(0).reverse(); } +function maybeScrollWindow(routes, match) { + if (routes.props.preserveScrollPosition) + return; + + if (!match || match.route.props.preserveScrollPosition) + return; + + window.scrollTo(0, 0); +} + module.exports = Routes;