Skip to content

Commit

Permalink
Refactor library
Browse files Browse the repository at this point in the history
- Remove secondary scroll behaviors
- Separate scroll logic from history logic
  • Loading branch information
taion committed May 3, 2016
1 parent 67546aa commit 675a9b6
Show file tree
Hide file tree
Showing 29 changed files with 506 additions and 861 deletions.
11 changes: 9 additions & 2 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"stage": 1,
"loose": "all"
"env": {
"cjs": {
"presets": ["es2015-loose", "stage-1"],
"plugins": ["add-module-exports"]
},
"es": {
"presets": ["es2015-loose-native-modules", "stage-1"]
}
}
}
6 changes: 5 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
{
"extends": "rackt"
"extends": "airbnb-base",
"parser": "babel-eslint",
"rules": {
"max-len": [2, 79]
}
}
67 changes: 17 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,99 +1,66 @@
# scroll-behavior [![Travis][build-badge]][build] [![npm][npm-badge]][npm]

Scroll behaviors for use with [`history`](https://github.com/reactjs/history).
Scroll management for [`history`](https://github.com/reactjs/history).

[![Coveralls][coveralls-badge]][coveralls]
[![Discord][discord-badge]][discord]

## Usage

Extend your history object with one of the scroll behaviors in this library to get the desired scroll behavior after transitions.

```js
import createHistory from 'history/lib/createBrowserHistory'
import withScroll from 'scroll-behavior/lib/withStandardScroll'
import createHistory from 'history/lib/createBrowserHistory';
import withScroll from 'scroll-behavior';

const history = withScroll(createHistory())
const history = withScroll(createHistory());
```

## Guide

### Installation

```
$ npm install history scroll-behavior
$ npm i -S history
$ npm i -S scroll-behavior
```

You may also want to install [React Router](https://github.com/reactjs/react-router) to obtain a complete routing solution for React that works with history.

### Scroll behaviors

#### `withScrollToTop`

`withScrollToTop` scrolls to the top of the page after any transition.

This is not fully reliable for `POP` transitions.

#### `withSimpleScroll`
### Basic usage

`withSimpleScroll` scrolls to the top of the page on `PUSH` and `REPLACE` transitions, while allowing the browser to manage scroll position for `POP` transitions.

This can give pretty good results with synchronous transitions on browsers like Chrome that don't update the scroll position until after they've notified `history` of the location change. It will not work as well when using asynchronous transitions or with browsers like Firefox that update the scroll position before emitting the location change.

#### `withStandardScroll`

`withStandardScroll` attempts to imitate native browser scroll behavior by recording updates to the window scroll position, then restoring the previous scroll position upon a `POP` transition.
Extend your history object using `withScroll`. The extended history object will manage the scroll position for transitions.

### Custom behavior

You can further customize scroll behavior by providing a `shouldUpdateScroll` callback when extending the history object. This callback is called with both the previous location and the current location.
You can customize the scroll behavior by providing a `shouldUpdateScroll` callback when extending the history object. This callback is called with both the previous location and the current location.

You can return:

- a falsy value to suppress the scroll update
- a position array such as `[ 0, 100 ]` to scroll to that position
- a position array such as `[0, 100]` to scroll to that position
- a truthy value to get normal scroll behavior

```js
const history = withScroll(createHistory(), (prevLocation, location) => (
// Don't scroll if the pathname is the same.
location.pathname !== prevLocation.pathname
))
));
```

```js
const history = withScroll(createHistory(), (prevLocation, location) => (
// Scroll to top when attempting to vist the current path.
location.pathname === prevLocation.pathname ? [ 0, 0 ] : true
))
```

### Async transitions

If you are using async routes or async data loading, you may need to defer the update of the scroll position until the async transition is complete. You can do this by passing in a callback as the third argument to `shouldUpdateScroll`:

```js
let updateScroll

const history = withScroll(createHistory(), (prevLocation, location, cb) => {
updateScroll = cb
})
```

After transition is finished, you can trigger the update of the scroll position by invoking the callback with the same value you would have returned from a synchronous `shouldUpdateScroll` function:

```js
updateScroll(true)
location.pathname === prevLocation.pathname ? [0, 0] : true
));
```

[build-badge]: https://img.shields.io/travis/taion/scroll-behavior/master.svg?style=flat-square
[build-badge]: https://img.shields.io/travis/taion/scroll-behavior/master.svg
[build]: https://travis-ci.org/taion/scroll-behavior

[npm-badge]: https://img.shields.io/npm/v/scroll-behavior.svg?style=flat-square
[npm-badge]: https://img.shields.io/npm/v/scroll-behavior.svg
[npm]: https://www.npmjs.org/package/scroll-behavior

[coveralls-badge]: https://img.shields.io/coveralls/taion/scroll-behavior/master.svg?style=flat-square
[coveralls-badge]: https://img.shields.io/coveralls/taion/scroll-behavior/master.svg
[coveralls]: https://coveralls.io/github/taion/scroll-behavior

[discord-badge]: https://img.shields.io/badge/Discord-join%20chat%20%E2%86%92-738bd7.svg?style=flat-square
[discord-badge]: https://img.shields.io/badge/Discord-join%20chat%20%E2%86%92-738bd7.svg
[discord]: https://discord.gg/0ZcbPKXt5bYaNQ46
59 changes: 31 additions & 28 deletions karma.conf.babel.js
Original file line number Diff line number Diff line change
@@ -1,74 +1,77 @@
import path from 'path'
import webpack from 'webpack'
import path from 'path';
import webpack from 'webpack';

export default config => {
const { env } = process
const { env } = process;

const isCi = env.CONTINUOUS_INTEGRATION === 'true'
const runCoverage = env.COVERAGE === 'true' || isCi
const isCi = env.CONTINUOUS_INTEGRATION === 'true';
const runCoverage = env.COVERAGE === 'true' || isCi;

const coverageLoaders = []
const coverageReporters = []
const coverageLoaders = [];
const coverageReporters = [];

if (runCoverage) {
coverageLoaders.push({
test: /\.js$/,
include: path.resolve('modules/'),
exclude: /__tests__/,
loader: 'isparta'
})
loader: 'isparta',
});

coverageReporters.push('coverage')
coverageReporters.push('coverage');

if (isCi) {
coverageReporters.push('coveralls')
coverageReporters.push('coveralls');
}
}

config.set({
frameworks: [ 'mocha' ],
frameworks: ['mocha'],

files: [ 'tests.webpack.js' ],
files: ['./test/index.js'],

preprocessors: {
'tests.webpack.js': [ 'webpack', 'sourcemap' ]
'./test/index.js': ['webpack', 'sourcemap'],
},

webpack: {
module: {
loaders: [
{ test: /\.js$/, exclude: /node_modules/, loader: 'babel' },
...coverageLoaders
]
...coverageLoaders,
],
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('test')
})
'process.env.NODE_ENV': JSON.stringify('test'),
}),
],
devtool: 'inline-source-map'
devtool: 'inline-source-map',
},

webpackMiddleware: {
noInfo: true
noInfo: true,
},

reporters: [ 'mocha', ...coverageReporters ],
reporters: [
'mocha',
...coverageReporters,
],

coverageReporter: {
type: 'lcov',
dir: 'coverage'
dir: 'coverage',
},

customLaunchers: {
ChromeCi: {
base: 'Chrome',
flags: [ '--no-sandbox' ]
}
flags: ['--no-sandbox'],
},
},

browsers: isCi ? [ env.BROWSER ] : [ 'Chrome', 'Firefox' ],
browsers: isCi ? [env.BROWSER] : ['Chrome', 'Firefox'],

singleRun: isCi
})
}
singleRun: isCi,
});
};
4 changes: 2 additions & 2 deletions karma.conf.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
require('babel-core/register')
module.exports = require('./karma.conf.babel.js')
require('babel-register');
module.exports = require('./karma.conf.babel.js');
5 changes: 0 additions & 5 deletions modules/__tests__/.eslintrc

This file was deleted.

10 changes: 0 additions & 10 deletions modules/__tests__/config.js

This file was deleted.

6 changes: 0 additions & 6 deletions modules/__tests__/delay.js

This file was deleted.

97 changes: 0 additions & 97 deletions modules/__tests__/describeShouldUpdateScroll.js

This file was deleted.

Loading

0 comments on commit 675a9b6

Please sign in to comment.