Skip to content

Commit 91e8712

Browse files
committed
feature: add hook implementation
chore: add eslint
1 parent fe9158f commit 91e8712

File tree

18 files changed

+1155
-292
lines changed

18 files changed

+1155
-292
lines changed

.eslintrc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"parser": "@typescript-eslint/parser",
3+
"extends": [
4+
"plugin:@typescript-eslint/recommended",
5+
"prettier/@typescript-eslint",
6+
"plugin:prettier/recommended",
7+
"plugin:react/recommended",
8+
"plugin:jsx-a11y/recommended"
9+
],
10+
"plugins": ["@typescript-eslint", "react", "react-hooks", "jsx-a11y"],
11+
"rules": {
12+
"@typescript-eslint/explicit-function-return-type": "off",
13+
"react-hooks/rules-of-hooks": "error",
14+
"react-hooks/exhaustive-deps": "warn"
15+
},
16+
"parserOptions": {
17+
"ecmaVersion": 2018,
18+
"sourceType": "module",
19+
"ecmaFeatures": {
20+
"jsx": true
21+
}
22+
},
23+
"settings": {
24+
"react": {
25+
"version": "detect"
26+
}
27+
}
28+
}

.prettierrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"semi": false,
3+
"tabWidth": 2,
34
"trailingComma": "all",
45
"singleQuote": true,
56
"printWidth": 120

example/.eslintrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

example/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
"private": true,
77
"dependencies": {
88
"prop-types": "^15.7.2",
9-
"react": "^16.8.6",
9+
"react": "link:../node_modules/react",
10+
"react-dom": "link:../node_modules/react-dom",
1011
"react-bottom-scroll-listener": "link:..",
11-
"react-dom": "^16.8.6",
1212
"react-scripts": "^3.0.1",
1313
"react-toggle": "^4.0.2"
1414
},

example/src/App.js

Lines changed: 23 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,31 @@
1-
import React, { Component } from 'react'
1+
import React, { useState } from 'react'
22
import Toggle from 'react-toggle'
33

4-
import 'react-toggle/style.css'
4+
import ComponentExample from './ComponentExample'
5+
import HookExample from './HookExample'
56

6-
import BottomScrollListener from 'react-bottom-scroll-listener'
7+
const App = () => {
8+
const [hookExample, setHookExample] = useState(true)
9+
const [alertOnBottom, setAlertOnBottom] = useState(true)
710

8-
export default class App extends Component {
9-
state = {
10-
alertOnBottom: true,
11-
}
12-
13-
handleAlertBottomChange = () => {
14-
this.setState(prevState => ({ alertOnBottom: !prevState.alertOnBottom }))
15-
}
16-
17-
handleOnDocumentBottom = () => {
18-
console.log('I am at bottom! ' + Math.round(performance.now()))
19-
20-
if (this.state.alertOnBottom) {
21-
alert('Bottom hit! Too slow? Reduce "debounce" value in props')
22-
}
23-
}
24-
25-
handleContainerOnBottom = () => {
26-
console.log('I am at bottom in optional container! ' + Math.round(performance.now()))
27-
28-
if (this.state.alertOnBottom) {
29-
alert('Bottom of this container hit! Too slow? Reduce "debounce" value in props')
30-
}
31-
}
32-
33-
render() {
34-
return (
35-
<div className="root">
36-
<header>
37-
<h1>react-bottom-scroll-listener</h1>
11+
return (
12+
<div>
13+
<header>
14+
<h1>react-bottom-scroll-listener</h1>
15+
<div className="right-toggle-box">
3816
<label htmlFor="alert-state">
39-
<span>Use {this.state.alertOnBottom ? 'alert dialog' : 'console.log'}</span>
40-
<Toggle id="alert-state" checked={this.state.alertOnBottom} onChange={this.handleAlertBottomChange} />
17+
<span>Use {alertOnBottom ? 'alert dialog' : 'console.log'}</span>
18+
<Toggle id="alert-state" checked={alertOnBottom} onChange={() => setAlertOnBottom(b => !b)} />
19+
</label>
20+
<label htmlFor="use-hook-state">
21+
<span>Use {hookExample ? 'hook' : 'component'}</span>
22+
<Toggle id="use-hook-state" checked={hookExample} onChange={() => setHookExample(b => !b)} />
4123
</label>
42-
</header>
43-
44-
<div className="scrollbox">
45-
<h2>Callback when document hits bottom</h2>
46-
<div>Scroll down! ▼▼▼</div>
47-
<div>A bit more... ▼▼</div>
48-
<div>Almost there... ▼</div>
49-
<div>You've reached the bottom!</div>
5024
</div>
51-
52-
{/* When you only want to listen to the bottom of "document", you can put it anywhere */}
53-
<BottomScrollListener onBottom={this.handleOnDocumentBottom} />
54-
55-
{/* If you want to listen for the bottom of a specific container you need to forward
56-
a scrollRef as a ref to your container */}
57-
<BottomScrollListener onBottom={this.handleContainerOnBottom}>
58-
{scrollRef => (
59-
<div ref={scrollRef} className="innerScrollExample">
60-
<h4>Callback when this container hits bottom</h4>
61-
<div>Scroll down! ▼▼▼</div>
62-
<div>A bit more... ▼▼</div>
63-
<div>Almost there... ▼</div>
64-
<div>You've reached the bottom!</div>
65-
</div>
66-
)}
67-
</BottomScrollListener>
68-
</div>
69-
)
70-
}
25+
</header>
26+
{hookExample ? <HookExample alertOnBottom={alertOnBottom} /> : <ComponentExample alertOnBottom={alertOnBottom} />}
27+
</div>
28+
)
7129
}
30+
31+
export default App

example/src/ComponentExample.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React, { Component } from 'react'
2+
3+
import 'react-toggle/style.css'
4+
5+
import BottomScrollListener from 'react-bottom-scroll-listener'
6+
7+
class ComponentExample extends Component {
8+
handleOnDocumentBottom = () => {
9+
console.log('I am at bottom! ' + Math.round(performance.now()))
10+
11+
if (this.props.alertOnBottom) {
12+
alert('Bottom hit! Too slow? Reduce "debounce" value in props')
13+
}
14+
}
15+
16+
handleContainerOnBottom = () => {
17+
console.log('I am at bottom in optional container! ' + Math.round(performance.now()))
18+
19+
if (this.props.alertOnBottom) {
20+
alert('Bottom of this container hit! Too slow? Reduce "debounce" value in props')
21+
}
22+
}
23+
24+
render() {
25+
return (
26+
<div className="root">
27+
<div className="scroll-box">
28+
<h1>Component example</h1>
29+
<h2>Callback when document hits bottom</h2>
30+
<div>Scroll down! ▼▼▼</div>
31+
<div>A bit more... ▼▼</div>
32+
<div>Almost there... ▼</div>
33+
<div>You've reached the bottom!</div>
34+
</div>
35+
36+
{/* When you only want to listen to the bottom of "document", you can put it anywhere */}
37+
<BottomScrollListener onBottom={this.handleOnDocumentBottom} />
38+
39+
{/* If you want to listen for the bottom of a specific container you need to forward
40+
a scrollRef as a ref to your container */}
41+
<BottomScrollListener onBottom={this.handleContainerOnBottom}>
42+
{scrollRef => (
43+
<div ref={scrollRef} className="inner-scroll-example">
44+
<h4>Callback when this container hits bottom</h4>
45+
<div>Scroll down! ▼▼▼</div>
46+
<div>A bit more... ▼▼</div>
47+
<div>Almost there... ▼</div>
48+
<div>You've reached the bottom!</div>
49+
</div>
50+
)}
51+
</BottomScrollListener>
52+
</div>
53+
)
54+
}
55+
}
56+
57+
export default ComponentExample

example/src/HookExample.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import React, { useCallback } from 'react'
2+
3+
import { useBottomScrollListener } from 'react-bottom-scroll-listener'
4+
5+
const HookExample = ({ alertOnBottom }) => {
6+
const handleOnDocumentBottom = useCallback(() => {
7+
console.log('I am at bottom! ' + Math.round(performance.now()))
8+
9+
if (alertOnBottom) {
10+
alert('Bottom hit! Too slow? Reduce "debounce" value in props')
11+
}
12+
}, [alertOnBottom])
13+
14+
const handleContainerOnBottom = useCallback(() => {
15+
console.log('I am at bottom in optional container! ' + Math.round(performance.now()))
16+
17+
if (alertOnBottom) {
18+
alert('Bottom of this container hit! Too slow? Reduce "debounce" value in props')
19+
}
20+
}, [alertOnBottom])
21+
22+
/* This will trigger handleOnDocumentBottom when the body of the page hits the bottom */
23+
useBottomScrollListener(handleOnDocumentBottom)
24+
25+
/* This will trigger handleOnContainerBottom when the container that is passed the ref hits the bottom */
26+
const containerRef = useBottomScrollListener(handleContainerOnBottom)
27+
28+
return (
29+
<div className="root">
30+
<div className="scroll-box">
31+
<h1>Hook example</h1>
32+
<h2>Callback when document hits bottom</h2>
33+
<div>Scroll down! ▼▼▼</div>
34+
<div>A bit more... ▼▼</div>
35+
<div>Almost there... ▼</div>
36+
<div>You've reached the bottom!</div>
37+
</div>
38+
<div>
39+
<div ref={containerRef} className="inner-scroll-example">
40+
<h4>Callback when this container hits bottom</h4>
41+
<div>Scroll down! ▼▼▼</div>
42+
<div>A bit more... ▼▼</div>
43+
<div>Almost there... ▼</div>
44+
<div>You've reached the bottom!</div>
45+
</div>
46+
</div>
47+
</div>
48+
)
49+
}
50+
51+
export default HookExample

example/src/index.css

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,20 @@ header h1 {
3838

3939
header label {
4040
display: flex;
41+
justify-content: space-between;
4142
align-items: center;
4243
margin: 0 16px;
44+
width: 190px;
4345
}
4446

4547
header label span {
4648
margin: 0 8px;
49+
text-align: right;
50+
width: 100%;
51+
}
52+
53+
header > .right-toggle-box {
54+
display: flex;
4755
}
4856

4957
.root > label > input {
@@ -58,22 +66,22 @@ header label span {
5866
align-items: center;
5967
}
6068

61-
.scrollbox {
69+
.scroll-box {
6270
margin: 16px;
6371
margin-top: 68px;
6472
padding: 8px;
6573
color: #666;
6674
}
6775

68-
.scrollbox > div {
76+
.scroll-box > div {
6977
margin-bottom: 500px;
7078
}
7179

72-
.scrollbox > div:last-of-type {
80+
.scroll-box > div:last-of-type {
7381
margin-bottom: 0;
7482
}
7583

76-
.innerScrollExample {
84+
.inner-scroll-example {
7785
padding: 8px;
7886
position: absolute;
7987
right: 42px;
@@ -87,11 +95,11 @@ header label span {
8795
0px 1px 10px 0px rgba(0, 0, 0, 0.12);
8896
}
8997

90-
.innerScrollExample > div {
98+
.inner-scroll-example > div {
9199
margin-bottom: 150px;
92100
}
93101

94-
.innerScrollExample > div:last-of-type {
102+
.inner-scroll-example > div:last-of-type {
95103
margin-bottom: 0;
96104
}
97105

@@ -104,7 +112,7 @@ header label span {
104112
display: none;
105113
}
106114

107-
.innerScrollExample {
115+
.inner-scroll-example {
108116
top: 200px;
109117
left: 0;
110118
width: 80%;

example/yarn.lock

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8038,15 +8038,9 @@ react-dev-utils@^9.0.1:
80388038
strip-ansi "5.2.0"
80398039
text-table "0.2.0"
80408040

8041-
react-dom@^16.8.6:
8042-
version "16.8.6"
8043-
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.6.tgz#71d6303f631e8b0097f56165ef608f051ff6e10f"
8044-
integrity sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==
8045-
dependencies:
8046-
loose-envify "^1.1.0"
8047-
object-assign "^4.1.1"
8048-
prop-types "^15.6.2"
8049-
scheduler "^0.13.6"
8041+
"react-dom@link:../node_modules/react-dom":
8042+
version "0.0.0"
8043+
uid ""
80508044

80518045
react-error-overlay@^5.1.6:
80528046
version "5.1.6"
@@ -8125,15 +8119,9 @@ react-toggle@^4.0.2:
81258119
dependencies:
81268120
classnames "^2.2.5"
81278121

8128-
react@^16.8.6:
8129-
version "16.8.6"
8130-
resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe"
8131-
integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==
8132-
dependencies:
8133-
loose-envify "^1.1.0"
8134-
object-assign "^4.1.1"
8135-
prop-types "^15.6.2"
8136-
scheduler "^0.13.6"
8122+
"react@link:../node_modules/react":
8123+
version "0.0.0"
8124+
uid ""
81378125

81388126
read-pkg-up@^2.0.0:
81398127
version "2.0.0"

0 commit comments

Comments
 (0)