Skip to content

Commit e79630f

Browse files
authored
Add ESlint and prettier (#137)
Add ESlint and prettier
2 parents aa40f2a + 9e09872 commit e79630f

File tree

9 files changed

+1123
-88
lines changed

9 files changed

+1123
-88
lines changed

.eslintrc.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const path = require('path');
2+
module.exports = {
3+
parser: '@typescript-eslint/parser',
4+
parserOptions: {
5+
project: path.resolve(__dirname, './tsconfig.json'),
6+
tsconfigRootDir: __dirname,
7+
},
8+
plugins: ['@typescript-eslint'],
9+
extends: [
10+
'eslint:recommended',
11+
'plugin:@typescript-eslint/eslint-recommended',
12+
'plugin:react/recommended',
13+
'plugin:@typescript-eslint/recommended',
14+
'plugin:@typescript-eslint/recommended-requiring-type-checking',
15+
'prettier',
16+
'prettier/@typescript-eslint',
17+
'prettier/react',
18+
],
19+
rules: {
20+
'@typescript-eslint/prefer-regexp-exec': 1,
21+
},
22+
};

.prettierrc.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
trailingComma = "es5"
2+
tabWidth = 2
3+
semi = true
4+
singleQuote = true

package.json

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@
99
"scripts": {
1010
"build": "microbundle",
1111
"storybook": "start-storybook -p 6006",
12-
"build-storybook": "build-storybook"
12+
"build-storybook": "build-storybook",
13+
"lint": "eslint 'src/**/*.{ts,tsx,js,jsx}'",
14+
"lint:fix": "yarn lint --fix",
15+
"prettier:check": "prettier --check 'src/**/*'",
16+
"prettify": "prettier --write 'src/**/*'",
17+
"ts-check": "tsc -p tsconfig.json --noEmit"
1318
},
1419
"repository": {
1520
"type": "git",
@@ -43,15 +48,42 @@
4348
"@types/react-dom": "^16.9.1",
4449
"@types/storybook__react": "^4.0.2",
4550
"@types/throttle-debounce": "^2.1.0",
51+
"@typescript-eslint/eslint-plugin": "^2.3.2",
52+
"@typescript-eslint/parser": "^2.3.2",
4653
"awesome-typescript-loader": "^5.2.1",
4754
"babel-loader": "^8.0.6",
55+
"eslint": "^6.5.1",
56+
"eslint-config-prettier": "^6.3.0",
57+
"eslint-plugin-react": "^7.15.0",
58+
"husky": ">=1",
59+
"lint-staged": ">=8",
4860
"microbundle": "^0.11.0",
61+
"prettier": "1.18.2",
4962
"react": "^16.10.1",
5063
"react-docgen-typescript-loader": "^3.2.1",
5164
"react-dom": "^16.10.1",
5265
"typescript": "^3.6.3"
5366
},
5467
"dependencies": {
5568
"throttle-debounce": "^2.1.0"
69+
},
70+
"husky": {
71+
"hooks": {
72+
"pre-commit": "yarn run ts-check && lint-staged"
73+
}
74+
},
75+
"lint-staged": {
76+
"*.{js,css,json,md}": [
77+
"prettier --write",
78+
"git add"
79+
],
80+
"*.js": [
81+
"eslint --fix",
82+
"git add"
83+
],
84+
"*.{ts,tsx}": [
85+
"eslint --fix",
86+
"git add"
87+
]
5688
}
5789
}

src/index.tsx

Lines changed: 49 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import React, { Component, ReactNode, CSSProperties } from "react";
2-
import { throttle } from "throttle-debounce";
3-
import { ThresholdUnits, parseThreshold } from "./utils/threshold";
1+
import React, { Component, ReactNode, CSSProperties } from 'react';
2+
import { throttle } from 'throttle-debounce';
3+
import { ThresholdUnits, parseThreshold } from './utils/threshold';
44

55
type Fn = () => any;
66
interface Props {
@@ -37,17 +37,15 @@ export default class InfiniteScroll extends Component<Props, State> {
3737

3838
this.state = {
3939
showLoader: false,
40-
pullToRefreshThresholdBreached: false
40+
pullToRefreshThresholdBreached: false,
4141
};
4242

43-
this.onScrollListener = this.onScrollListener.bind(this);
4443
this.throttledOnScrollListener = throttle(150, this.onScrollListener).bind(
4544
this
4645
);
4746
this.onStart = this.onStart.bind(this);
4847
this.onMove = this.onMove.bind(this);
4948
this.onEnd = this.onEnd.bind(this);
50-
this.getScrollableTarget = this.getScrollableTarget.bind(this);
5149
}
5250

5351
private throttledOnScrollListener: (e: MouseEvent) => void;
@@ -59,13 +57,13 @@ export default class InfiniteScroll extends Component<Props, State> {
5957
private _pullDown: HTMLDivElement | undefined;
6058

6159
// variables to keep track of pull down behaviour
62-
private startY: number = 0;
63-
private currentY: number = 0;
64-
private dragging: boolean = false;
60+
private startY = 0;
61+
private currentY = 0;
62+
private dragging = false;
6563

6664
// will be populated in componentDidMount
6765
// based on the height of the pull down element
68-
private maxPullDownDistance: number = 0;
66+
private maxPullDownDistance = 0;
6967

7068
componentDidMount() {
7169
this._scrollableNode = this.getScrollableTarget();
@@ -74,13 +72,13 @@ export default class InfiniteScroll extends Component<Props, State> {
7472
: this._scrollableNode || window;
7573

7674
if (this.el) {
77-
this.el.addEventListener("scroll", e =>
75+
this.el.addEventListener('scroll', e =>
7876
this.throttledOnScrollListener(e as MouseEvent)
7977
);
8078
}
8179

8280
if (
83-
typeof this.props.initialScrollY === "number" &&
81+
typeof this.props.initialScrollY === 'number' &&
8482
this.el &&
8583
this.el instanceof HTMLElement &&
8684
this.el.scrollHeight > this.props.initialScrollY
@@ -89,13 +87,13 @@ export default class InfiniteScroll extends Component<Props, State> {
8987
}
9088

9189
if (this.props.pullDownToRefresh && this.el) {
92-
this.el.addEventListener("touchstart", this.onStart);
93-
this.el.addEventListener("touchmove", this.onMove);
94-
this.el.addEventListener("touchend", this.onEnd);
90+
this.el.addEventListener('touchstart', this.onStart);
91+
this.el.addEventListener('touchmove', this.onMove);
92+
this.el.addEventListener('touchend', this.onEnd);
9593

96-
this.el.addEventListener("mousedown", this.onStart);
97-
this.el.addEventListener("mousemove", this.onMove);
98-
this.el.addEventListener("mouseup", this.onEnd);
94+
this.el.addEventListener('mousedown', this.onStart);
95+
this.el.addEventListener('mousemove', this.onMove);
96+
this.el.addEventListener('mouseup', this.onEnd);
9997

10098
// get BCR of pullDown element to position it above
10199
this.maxPullDownDistance =
@@ -106,7 +104,7 @@ export default class InfiniteScroll extends Component<Props, State> {
106104
0;
107105
this.forceUpdate();
108106

109-
if (typeof this.props.refreshFunction !== "function") {
107+
if (typeof this.props.refreshFunction !== 'function') {
110108
throw new Error(
111109
`Mandatory prop "refreshFunction" missing.
112110
Pull Down To Refresh functionality will not work
@@ -118,23 +116,23 @@ export default class InfiniteScroll extends Component<Props, State> {
118116

119117
componentWillUnmount() {
120118
if (this.el) {
121-
this.el.removeEventListener("scroll", e =>
119+
this.el.removeEventListener('scroll', e =>
122120
this.throttledOnScrollListener(e as MouseEvent)
123121
);
124122

125123
if (this.props.pullDownToRefresh) {
126-
this.el.removeEventListener("touchstart", this.onStart);
127-
this.el.removeEventListener("touchmove", this.onMove);
128-
this.el.removeEventListener("touchend", this.onEnd);
124+
this.el.removeEventListener('touchstart', this.onStart);
125+
this.el.removeEventListener('touchmove', this.onMove);
126+
this.el.removeEventListener('touchend', this.onEnd);
129127

130-
this.el.removeEventListener("mousedown", this.onStart);
131-
this.el.removeEventListener("mousemove", this.onMove);
132-
this.el.removeEventListener("mouseup", this.onEnd);
128+
this.el.removeEventListener('mousedown', this.onStart);
129+
this.el.removeEventListener('mousemove', this.onMove);
130+
this.el.removeEventListener('mouseup', this.onEnd);
133131
}
134132
}
135133
}
136134

137-
componentWillReceiveProps(props: Props) {
135+
UNSAFE_componentWillReceiveProps(props: Props) {
138136
// do nothing when dataLength and key are unchanged
139137
if (
140138
this.props.key === props.key &&
@@ -146,14 +144,14 @@ export default class InfiniteScroll extends Component<Props, State> {
146144
// update state when new data was sent in
147145
this.setState({
148146
showLoader: false,
149-
pullToRefreshThresholdBreached: false
147+
pullToRefreshThresholdBreached: false,
150148
});
151149
}
152150

153-
getScrollableTarget() {
151+
getScrollableTarget = () => {
154152
if (this.props.scrollableTarget instanceof HTMLElement)
155153
return this.props.scrollableTarget;
156-
if (typeof this.props.scrollableTarget === "string") {
154+
if (typeof this.props.scrollableTarget === 'string') {
157155
return document.getElementById(this.props.scrollableTarget);
158156
}
159157
if (this.props.scrollableTarget === null) {
@@ -163,7 +161,7 @@ export default class InfiniteScroll extends Component<Props, State> {
163161
`);
164162
}
165163
return null;
166-
}
164+
};
167165

168166
onStart: EventListener = (evt: Event) => {
169167
if (this.lastScrollTop) return;
@@ -178,7 +176,7 @@ export default class InfiniteScroll extends Component<Props, State> {
178176
this.currentY = this.startY;
179177

180178
if (this._infScroll) {
181-
this._infScroll.style.willChange = "transform";
179+
this._infScroll.style.willChange = 'transform';
182180
this._infScroll.style.transition = `transform 0.2s cubic-bezier(0,0,0.31,1)`;
183181
}
184182
};
@@ -200,15 +198,15 @@ export default class InfiniteScroll extends Component<Props, State> {
200198
Number(this.props.pullDownToRefreshThreshold)
201199
) {
202200
this.setState({
203-
pullToRefreshThresholdBreached: true
201+
pullToRefreshThresholdBreached: true,
204202
});
205203
}
206204

207205
// so you can drag upto 1.5 times of the maxPullDownDistance
208206
if (this.currentY - this.startY > this.maxPullDownDistance * 1.5) return;
209207

210208
if (this._infScroll) {
211-
this._infScroll.style.overflow = "visible";
209+
this._infScroll.style.overflow = 'visible';
212210
this._infScroll.style.transform = `translate3d(0px, ${this.currentY -
213211
this.startY}px, 0px)`;
214212
}
@@ -227,9 +225,9 @@ export default class InfiniteScroll extends Component<Props, State> {
227225
requestAnimationFrame(() => {
228226
// this._infScroll
229227
if (this._infScroll) {
230-
this._infScroll.style.overflow = "auto";
231-
this._infScroll.style.transform = "none";
232-
this._infScroll.style.willChange = "none";
228+
this._infScroll.style.overflow = 'auto';
229+
this._infScroll.style.transform = 'none';
230+
this._infScroll.style.willChange = 'none';
233231
}
234232
});
235233
};
@@ -257,14 +255,14 @@ export default class InfiniteScroll extends Component<Props, State> {
257255
);
258256
}
259257

260-
onScrollListener(event: MouseEvent) {
261-
if (typeof this.props.onScroll === "function") {
258+
onScrollListener = (event: MouseEvent) => {
259+
if (typeof this.props.onScroll === 'function') {
262260
// Execute this callback in next tick so that it does not affect the
263261
// functionality of the library.
264262
setTimeout(() => this.props.onScroll && this.props.onScroll(event), 0);
265263
}
266264

267-
let target =
265+
const target =
268266
this.props.height || this._scrollableNode
269267
? (event.target as HTMLElement)
270268
: document.documentElement.scrollTop
@@ -275,7 +273,7 @@ export default class InfiniteScroll extends Component<Props, State> {
275273
// prevents multiple triggers.
276274
if (this.actionTriggered) return;
277275

278-
let atBottom = this.isElementAtBottom(target, this.props.scrollThreshold);
276+
const atBottom = this.isElementAtBottom(target, this.props.scrollThreshold);
279277

280278
// call the `next` function in the props to trigger the next data fetch
281279
if (atBottom && this.props.hasMore) {
@@ -285,14 +283,14 @@ export default class InfiniteScroll extends Component<Props, State> {
285283
}
286284

287285
this.lastScrollTop = target.scrollTop;
288-
}
286+
};
289287

290288
render() {
291289
const style = {
292-
height: this.props.height || "auto",
293-
overflow: "auto",
294-
WebkitOverflowScrolling: "touch",
295-
...this.props.style
290+
height: this.props.height || 'auto',
291+
overflow: 'auto',
292+
WebkitOverflowScrolling: 'touch',
293+
...this.props.style,
296294
} as CSSProperties;
297295
const hasChildren =
298296
this.props.hasChildren ||
@@ -306,26 +304,26 @@ export default class InfiniteScroll extends Component<Props, State> {
306304
// on drag down as overflow becomes visible
307305
const outerDivStyle =
308306
this.props.pullDownToRefresh && this.props.height
309-
? { overflow: "auto" }
307+
? { overflow: 'auto' }
310308
: {};
311309
return (
312310
<div style={outerDivStyle}>
313311
<div
314-
className={`infinite-scroll-component ${this.props.className || ""}`}
312+
className={`infinite-scroll-component ${this.props.className || ''}`}
315313
ref={(infScroll: HTMLDivElement) => (this._infScroll = infScroll)}
316314
style={style}
317315
>
318316
{this.props.pullDownToRefresh && (
319317
<div
320-
style={{ position: "relative" }}
318+
style={{ position: 'relative' }}
321319
ref={(pullDown: HTMLDivElement) => (this._pullDown = pullDown)}
322320
>
323321
<div
324322
style={{
325-
position: "absolute",
323+
position: 'absolute',
326324
left: 0,
327325
right: 0,
328-
top: -1 * this.maxPullDownDistance
326+
top: -1 * this.maxPullDownDistance,
329327
}}
330328
>
331329
{this.state.pullToRefreshThresholdBreached

src/stories/WindowInfiniteScrollComponent.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import React from "react";
2-
import InfiniteScroll from "../index";
1+
import React from 'react';
2+
import InfiniteScroll from '../index';
33
type State = {
44
data: number[];
55
};
@@ -8,7 +8,7 @@ export default class WindowInfiniteScrollComponent extends React.Component<
88
State
99
> {
1010
state = {
11-
data: new Array(100).fill(1)
11+
data: new Array(100).fill(1),
1212
};
1313

1414
next = () => {
@@ -27,7 +27,10 @@ export default class WindowInfiniteScrollComponent extends React.Component<
2727
dataLength={this.state.data.length}
2828
>
2929
{this.state.data.map((_, i) => (
30-
<div style={{ height: 30, margin: 4, border: "1px solid hotpink" }}>
30+
<div
31+
key={i}
32+
style={{ height: 30, margin: 4, border: '1px solid hotpink' }}
33+
>
3134
#{i + 1} row
3235
</div>
3336
))}

0 commit comments

Comments
 (0)