Skip to content

Commit b809d3d

Browse files
authored
Merge pull request #29 from taion/update
Clean up support for non-window elements
2 parents 062aeb0 + 29b3e0b commit b809d3d

13 files changed

+386
-148
lines changed

.babelrc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
{
2-
"presets": ["es2015-loose", "stage-1", "react"],
2+
"presets": [
3+
["es2015", { "loose": true }],
4+
"stage-1",
5+
"react"
6+
],
37
"plugins": ["add-module-exports"]
48
}

.eslintrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
{
22
"extends": "airbnb",
33
"parser": "babel-eslint",
4+
"globals": {
5+
"__DEV__": false
6+
},
47
"rules": {
58
"max-len": [2, 79]
69
}

README.md

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ react-router-scroll is a React Router middleware that adds scroll management usi
66

77
## Usage
88

9-
```js
9+
```jsx
1010
import { applyRouterMiddleware, browserHistory, Router } from 'react-router';
11-
import useScroll from 'react-router-scroll';
11+
import { useScroll } from 'react-router-scroll';
1212

1313
/* ... */
1414

@@ -45,7 +45,7 @@ You can return:
4545
- a position array such as `[0, 100]` to scroll to that position
4646
- a truthy value to get normal scroll behavior
4747

48-
```js
48+
```jsx
4949
useScroll((prevRouterProps, { location }) => (
5050
prevRouterProps && location.pathname !== prevRouterProps.location.pathname
5151
));
@@ -63,6 +63,43 @@ useScroll((prevRouterProps, { routes }) => {
6363
});
6464
```
6565

66+
### Scrolling elements other than `window`
67+
68+
Use `<ScrollContainer>` to manage the scroll behavior of elements other than `window`. Each `<ScrollContainer>` must be given a unique `scrollKey`, and can be given an optional `shouldUpdateScroll` callback that behaves as above.
69+
70+
```jsx
71+
import { ScrollContainer } from 'react-router-scroll';
72+
73+
function Page() {
74+
/* ... */
75+
76+
return (
77+
<ScrollContainer
78+
scrollKey={scrollKey}
79+
shouldUpdateScroll={shouldUpdateScroll}
80+
>
81+
<MyScrollableComponent />
82+
</ScrollContainer>
83+
);
84+
}
85+
```
86+
87+
`<ScrollContainer>` does not support on-the-fly changes to `scrollKey` or to the DOM node for its child.
88+
89+
### Notes
90+
91+
#### Minimizing bundle size
92+
93+
If you are not using `<ScrollContainer>`, you can reduce your bundle size by importing the `useScroll` module directly.
94+
95+
```jsx
96+
import useScroll from 'react-router-scroll/lib/useScroll';
97+
```
98+
99+
#### Server rendering
100+
101+
Do not apply the `useScroll` middleware when rendering on a server. You may use `<ScrollContainer>` in server-rendered components, however, as it will do nothing when rendering on a server.
102+
66103
[build-badge]: https://img.shields.io/travis/taion/react-router-scroll/master.svg
67104
[build]: https://travis-ci.org/taion/react-router-scroll
68105

karma.conf.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ const webpack = require('webpack');
33
module.exports = config => {
44
const { env } = process;
55

6-
const isCi = env.CONTINUOUS_INTEGRATION === 'true';
7-
86
config.set({
97
frameworks: ['mocha'],
108

@@ -23,6 +21,7 @@ module.exports = config => {
2321
plugins: [
2422
new webpack.DefinePlugin({
2523
'process.env.NODE_ENV': JSON.stringify('test'),
24+
__DEV__: true,
2625
}),
2726
],
2827
devtool: 'cheap-module-inline-source-map',
@@ -46,7 +45,5 @@ module.exports = config => {
4645
},
4746

4847
browsers: env.BROWSER ? env.BROWSER.split(',') : ['Chrome', 'Firefox'],
49-
50-
singleRun: isCi,
5148
});
5249
};

package.json

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
"build": "rimraf lib && babel src -d lib",
1111
"lint": "eslint src test *.js",
1212
"prepublish": "npm run build",
13-
"test": "npm run lint && karma start"
13+
"tdd": "cross-env NODE_ENV=test karma start",
14+
"test": "npm run lint && npm run testonly",
15+
"testonly": "npm run tdd -- --single-run"
1416
},
1517
"repository": {
1618
"type": "git",
@@ -28,44 +30,44 @@
2830
},
2931
"homepage": "https://github.com/taion/react-router-scroll#readme",
3032
"dependencies": {
31-
"history": "^2.1.1",
32-
"scroll-behavior": "^0.7.0"
33+
"history": "^2.1.2",
34+
"scroll-behavior": "^0.8.0"
3335
},
3436
"peerDependencies": {
3537
"react": "^0.14.0 || ^15.0.0",
3638
"react-router": "^2.3.0"
3739
},
3840
"devDependencies": {
39-
"babel-cli": "^6.10.1",
40-
"babel-core": "^6.10.4",
41+
"babel-cli": "^6.11.4",
42+
"babel-core": "^6.13.2",
4143
"babel-eslint": "^6.1.2",
4244
"babel-loader": "^6.2.4",
4345
"babel-plugin-add-module-exports": "^0.2.1",
44-
"babel-polyfill": "^6.9.1",
45-
"babel-preset-es2015": "^6.9.0",
46-
"babel-preset-es2015-loose": "^7.0.0",
46+
"babel-polyfill": "^6.13.0",
47+
"babel-preset-es2015": "^6.13.2",
4748
"babel-preset-react": "^6.11.1",
48-
"babel-preset-stage-1": "^6.5.0",
49+
"babel-preset-stage-1": "^6.13.0",
4950
"chai": "^3.5.0",
51+
"cross-env": "^2.0.0",
5052
"dom-helpers": "^2.4.0",
5153
"eslint": "^2.13.1",
5254
"eslint-config-airbnb": "^9.0.1",
53-
"eslint-plugin-import": "^1.10.2",
55+
"eslint-plugin-import": "^1.12.0",
5456
"eslint-plugin-jsx-a11y": "^1.5.5",
5557
"eslint-plugin-react": "^5.2.2",
56-
"history": "^2.1.2",
57-
"karma": "^1.1.1",
58+
"karma": "^1.1.2",
5859
"karma-chrome-launcher": "^1.0.1",
5960
"karma-firefox-launcher": "^1.0.0",
6061
"karma-mocha": "^1.1.1",
61-
"karma-mocha-reporter": "^2.0.4",
62+
"karma-mocha-reporter": "^2.1.0",
6263
"karma-sourcemap-loader": "^0.3.7",
6364
"karma-webpack": "^1.7.0",
64-
"mocha": "^2.5.3",
65-
"react": "^15.2.1",
66-
"react-dom": "^15.2.1",
67-
"react-router": "^2.5.2",
68-
"rimraf": "^2.5.3",
65+
"mocha": "^3.0.1",
66+
"react": "^15.3.0",
67+
"react-dom": "^15.3.0",
68+
"react-router": "^2.6.1",
69+
"rimraf": "^2.5.4",
70+
"warning": "^3.0.0",
6971
"webpack": "^1.13.1"
7072
}
7173
}

src/ScrollBehaviorContainer.js

Lines changed: 0 additions & 78 deletions
This file was deleted.

src/ScrollBehaviorContext.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import React from 'react';
2+
import ScrollBehavior from 'scroll-behavior/lib/ScrollBehavior';
3+
4+
const propTypes = {
5+
shouldUpdateScroll: React.PropTypes.func,
6+
routerProps: React.PropTypes.object.isRequired,
7+
children: React.PropTypes.element.isRequired,
8+
};
9+
10+
const childContextTypes = {
11+
scrollBehavior: React.PropTypes.object.isRequired,
12+
};
13+
14+
class ScrollBehaviorContext extends React.Component {
15+
constructor(props, context) {
16+
super(props, context);
17+
18+
const { routerProps } = props;
19+
20+
this.scrollBehavior = new ScrollBehavior(
21+
routerProps.router,
22+
() => this.props.routerProps.location,
23+
this.shouldUpdateScroll,
24+
);
25+
26+
this.scrollBehavior.updateScroll(null, routerProps);
27+
}
28+
29+
getChildContext() {
30+
return {
31+
scrollBehavior: this,
32+
};
33+
}
34+
35+
componentDidUpdate(prevProps) {
36+
const { routerProps } = this.props;
37+
const prevRouterProps = prevProps.routerProps;
38+
39+
if (routerProps.location === prevRouterProps.location) {
40+
return;
41+
}
42+
43+
this.scrollBehavior.updateScroll(prevRouterProps, routerProps);
44+
}
45+
46+
componentWillUnmount() {
47+
this.scrollBehavior.stop();
48+
}
49+
50+
shouldUpdateScroll = (prevRouterProps, routerProps) => {
51+
const { shouldUpdateScroll } = this.props;
52+
if (!shouldUpdateScroll) {
53+
return true;
54+
}
55+
56+
// Hack to allow accessing scrollBehavior.readPosition().
57+
return shouldUpdateScroll.call(
58+
this.scrollBehavior, prevRouterProps, routerProps
59+
);
60+
};
61+
62+
registerElement = (key, element, shouldUpdateScroll) => {
63+
this.scrollBehavior.registerElement(
64+
key, element, shouldUpdateScroll, this.props.routerProps
65+
);
66+
};
67+
68+
unregisterElement = (key) => {
69+
this.scrollBehavior.unregisterElement(key);
70+
};
71+
72+
render() {
73+
return this.props.children;
74+
}
75+
}
76+
77+
ScrollBehaviorContext.propTypes = propTypes;
78+
ScrollBehaviorContext.childContextTypes = childContextTypes;
79+
80+
export default ScrollBehaviorContext;

0 commit comments

Comments
 (0)