Skip to content

Commit efef448

Browse files
author
janriemer
committed
1.0.0
1 parent f4e474c commit efef448

File tree

8 files changed

+199
-42
lines changed

8 files changed

+199
-42
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
/shrinkwrap.yaml
44
/package-lock.json
55
.DS_Store
6-
/*.js
6+
./**/*.js
77
/*.map
88
/index.d.ts
99
/.rpt2_cache

README.md

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,61 @@
11
# scrolldir-observable
22
[![Build Status](https://travis-ci.org/janriemer/scrolldir-observable.svg?branch=master)](https://travis-ci.org/janriemer/scrolldir-observable)
33

4-
WIP - stay tuned!
4+
Get the direction of scrolling - as an [observable](https://github.com/ReactiveX/RxJS)
5+
6+
## Install
7+
```bash
8+
$ npm install scrolldir-observable
9+
```
10+
11+
## Usage
12+
### via `import`
13+
```typescript
14+
import scrollDirObservable from 'scrolldir-observable';
15+
16+
// will react on scroll events that happen on the document
17+
const scrollDir$ = scrollDirObservable(window.document);
18+
19+
scrollDir$.subscribe(dir => {
20+
console.log(dir); // 'up' or 'down', depending on the scroll direction
21+
});
22+
```
23+
24+
⚠ The observable only emits values on the **first scroll** or **when the scroll direction changes**. So if the user e.g. scrolls down for 2 seconds, the observable will emit the value `down` only **once**.
25+
26+
### via `script` tags
27+
In case you want to use this library via script tags, you can do it like this
28+
```html
29+
<!DOCTYPE html>
30+
<html>
31+
<head>
32+
<script type="module" src="scrolldir-observable/dist/bundles/scrolldir-observable.es.min.js"></script>
33+
<script nomodule src="scrolldir-observable/dist/bundles/scrolldir-observable.umd.min.js"></script>
34+
</head>
35+
...
36+
</html>
37+
```
38+
It tries to load the library as an ES module and if that is not supported, it will fall back to an UMD module. Further details can be found in Jake Archibald's great article [ECMAScript modules in browsers](https://jakearchibald.com/2017/es-modules-in-browsers/).
39+
40+
## API
41+
### scrollDirObservable(element: `HTMLElement | Document`, windowElem: `Window` = window): `Observable<Directions>`
42+
element: Some html element or the document on which scroll directions should be observed.
43+
44+
windowElem: The global window object - defaults to `window` - *if you use this library directly in the browser, you need not to care about this parameter*.
45+
46+
### Directions: `'up' | 'down'`
47+
`String`, which describes the direction of the scroll.
48+
49+
## Development
50+
- `npm run build`: compiles library into the dist folder:
51+
- standalone (used, if consumers want to bundle it themselves):
52+
- `dist/index.js`
53+
- `dist/index.es.js`
54+
- bundles (direct usage via script tags (see [Usage](#via-script-tags))):
55+
- `dist/bundles/scrolldir-observable.es.min.js`
56+
- `dist/bundles/scrolldir-observable.umd.min.js`
57+
- types: `dist/types/index.d.ts`
58+
- `npm test`: executes all tests
59+
60+
## License
61+
MIT

package.json

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@
22
"name": "scrolldir-observable",
33
"version": "1.0.0",
44
"description": "An observable for getting the scroll direction.",
5-
"main": "dist/scrolldir-observable.umd.js",
6-
"module": "dist/scrolldir-observable.esm.js",
5+
"main": "dist/index.js",
6+
"module": "dist/index.es.js",
77
"typings": "dist/types/index.d.ts",
88
"files": [
99
"dist"
1010
],
1111
"scripts": {
12-
"build": "rimraf dist && tsc && rollup -c rollup.config.ts",
13-
"test": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' mocha --timeout 20000 --reporter nyan --require ts-node/register test/index.spec.ts",
12+
"clean": "rimraf dist",
13+
"build": "npm run clean && tsc && npm run build:standalone && npm run build:bundle",
14+
"build:bundle": "rollup -c rollup.bundle.config.js",
15+
"build:standalone": "rollup -c rollup.config.ts",
16+
"test": "npm run build:bundle && TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' mocha --timeout 10000 --reporter nyan --require ts-node/register test/*.spec.ts",
1417
"prepare": "npm run build",
1518
"prepublish": "check-node-version --npm \">=4\" || npm run prepare"
1619
},
@@ -24,24 +27,25 @@
2427
"author": "Jan Riemer <janriemer@tutanota.de>",
2528
"license": "MIT",
2629
"dependencies": {
27-
"rxjs": "^6.2.1"
30+
"rxjs": "^6.3.3"
2831
},
2932
"devDependencies": {
3033
"@types/chai": "^4.1.4",
31-
"@types/jsdom": "^11.0.6",
34+
"@types/jsdom": "11.12.0",
3235
"@types/mocha": "^5.2.4",
3336
"@types/sinon": "^5.0.1",
3437
"chai": "^4.1.2",
3538
"check-node-version": "^3.2.0",
3639
"coffeescript": "^2.3.1",
37-
"jsdom": "11.0.0",
40+
"jsdom": "11.5.1",
3841
"mocha": "^5.2.0",
3942
"rimraf": "^2.6.2",
40-
"rollup": "^0.64.1",
43+
"rollup": "^0.66.6",
4144
"rollup-plugin-commonjs": "^9.1.5",
4245
"rollup-plugin-json": "^3.0.0",
4346
"rollup-plugin-node-resolve": "^3.3.0",
4447
"rollup-plugin-sourcemaps": "^0.4.2",
48+
"rollup-plugin-terser": "^3.0.0",
4549
"rollup-plugin-typescript2": "^0.16.1",
4650
"rxjs-marbles": "^4.3.1",
4751
"sinon": "^6.1.5",

rollup.bundle.config.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import {pkgName, libraryName, config} from './rollup.common.config';
2+
import {terser} from 'rollup-plugin-terser';
3+
import resolve from 'rollup-plugin-node-resolve';
4+
import commonjs from 'rollup-plugin-commonjs';
5+
6+
let localConfig = config;
7+
8+
// Allow bundling cjs modules (unlike webpack, rollup doesn't understand cjs).
9+
// Allow node_modules resolution, so you can use 'external' to control
10+
// which external modules to include in the bundle
11+
// https://github.com/rollup/rollup-plugin-node-resolve#usage
12+
localConfig.plugins.push(terser(), commonjs(), resolve());
13+
14+
// we have multiple configs instead of multiple outputs to prevent a bug in rollup-plugin-terser:
15+
// https://github.com/TrySound/rollup-plugin-terser/issues/5
16+
export default [
17+
{
18+
...localConfig,
19+
output: [
20+
{ file: `dist/bundles/${pkgName}.umd.min.js`, name: libraryName, format: 'umd', sourcemap: false },
21+
],
22+
},
23+
{
24+
...localConfig,
25+
output: [
26+
{ file: `dist/bundles/${pkgName}.es.min.js`, format: 'es', sourcemap: false },
27+
]
28+
}
29+
]

rollup.common.config.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import typescript from 'rollup-plugin-typescript2'
2+
import json from 'rollup-plugin-json'
3+
4+
const pkg = require('./package.json')
5+
export const pkgName = pkg.name;
6+
7+
export const libraryName = 'scrollDirObservable'
8+
9+
export const config =
10+
{
11+
input: `src/index.ts`,
12+
watch: {
13+
include: 'src/**',
14+
},
15+
plugins: [
16+
// Allow json resolution
17+
json(),
18+
// Compile TypeScript files
19+
typescript({ useTsconfigDeclarationDir: true }),
20+
],
21+
};

rollup.config.ts

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,15 @@
1-
import resolve from 'rollup-plugin-node-resolve'
2-
import commonjs from 'rollup-plugin-commonjs'
3-
import sourceMaps from 'rollup-plugin-sourcemaps'
4-
import typescript from 'rollup-plugin-typescript2'
5-
import json from 'rollup-plugin-json'
1+
import {config, libraryName} from './rollup.common.config';
62

7-
const pkg = require('./package.json')
8-
9-
const libraryName = 'scrollDirObservable'
3+
const pkg = require('./package.json');
104

115
export default [
126
{
13-
input: `src/index.ts`,
7+
...config,
148
output: [
15-
{ file: pkg.main, name: libraryName, format: 'umd', sourcemap: true },
16-
{ file: pkg.module, format: 'es', sourcemap: true },
17-
],
18-
// Indicate here external modules you don't wanna include in your bundle (i.e.: 'lodash')
19-
external: [],
20-
watch: {
21-
include: 'src/**',
22-
},
23-
plugins: [
24-
// Allow json resolution
25-
json(),
26-
// Compile TypeScript files
27-
typescript({ useTsconfigDeclarationDir: true }),
28-
// Allow bundling cjs modules (unlike webpack, rollup doesn't understand cjs)
29-
commonjs(),
30-
// Allow node_modules resolution, so you can use 'external' to control
31-
// which external modules to include in the bundle
32-
// https://github.com/rollup/rollup-plugin-node-resolve#usage
33-
resolve(),
34-
35-
// Resolve source maps to the original source
36-
sourceMaps(),
9+
{ file: pkg.main, name: libraryName, format: 'cjs', sourcemap: false },
10+
{ file: pkg.module, format: 'es', sourcemap: false },
3711
],
12+
// leave it up to the consumer to bundle deps
13+
external: ['rxjs', 'rxjs/operators']
3814
}
3915
]

test/bundle.spec.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import 'mocha';
2+
import {expect} from 'chai';
3+
import {JSDOM} from 'jsdom';
4+
import {join} from 'path';
5+
import {readFileSync} from 'fs';
6+
import { rollup } from 'rollup';
7+
//import {pkgName, libraryName} from '../rollup.common.config';
8+
9+
describe('Smoke-testing the generated bundle...', () => {
10+
11+
const bundlePath = join(__dirname, '..', 'dist', 'bundles');
12+
13+
it ('should expose a function within the umd module', () => {
14+
const script = loadScript(`scrolldir-observable.umd.min.js`);
15+
const html = `<html lang="en">
16+
<head>
17+
<meta charset="UTF-8">
18+
<title>Document</title>
19+
</head>
20+
<body>
21+
<script>
22+
${script}
23+
</script>
24+
<script>
25+
document.body.innerText = typeof window.scrollDirObservable;
26+
</script>
27+
</body>
28+
</html>`;
29+
const jsdom = new JSDOM(html, {runScripts: 'dangerously', resources: 'usable'});
30+
31+
expect(jsdom.window.document.body.innerText).to.eql('function');
32+
});
33+
34+
it ('should transform the es module into a functioning umd module', async () => {
35+
const scriptPath = join(bundlePath, `scrolldir-observable.es.min.js`);
36+
37+
const bundle = await rollup({
38+
input: scriptPath
39+
});
40+
41+
const {code} = await bundle.generate({
42+
format: 'umd',
43+
name: 'scrollDirObservable'
44+
});
45+
46+
const html = `<html lang="en">
47+
<head>
48+
<meta charset="UTF-8">
49+
<title>Document</title>
50+
</head>
51+
<body>
52+
<script>
53+
${code}
54+
</script>
55+
<script>
56+
document.body.innerText = typeof window.scrollDirObservable;
57+
</script>
58+
</body>
59+
</html>`;
60+
const jsdom = new JSDOM(html, {runScripts: 'dangerously', resources: 'usable'});
61+
62+
expect(jsdom.window.document.body.innerText).to.eql('function');
63+
});
64+
65+
66+
function loadScript(jsFile: string): string {
67+
return readFileSync(
68+
join(bundlePath, jsFile), {encoding: 'utf8'});
69+
}
70+
});

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"compilerOptions": {
3-
"sourceMap": true,
3+
"sourceMap": false,
44
"declaration": true,
55
"module": "es2015",
66
"moduleResolution": "node",

0 commit comments

Comments
 (0)