@@ -8,18 +8,20 @@ const isScrolledDown = (el, threshold) => {
8
8
return bottom >= el . scrollHeight - threshold
9
9
}
10
10
11
- const isScrolledTop = el => el . scrollTop === 0
11
+ const isScrolledUp = el => el . scrollTop === 0
12
12
13
13
const scrollDown = el => el . scrollTop = el . scrollHeight - el . clientHeight
14
14
15
15
const scrollDownBy = ( amount , el ) => el . scrollTop += amount
16
+ const scrollUpBy = ( amount , el ) => el . scrollTop -= amount
16
17
17
18
export default ( Component , { isScrolledDownThreshold = 150 } = { } ) => class extends React . PureComponent {
18
19
constructor ( props ) {
19
20
super ( props )
20
21
this . _isScrolledDown = true /* whether the user has scrolled down */
21
22
this . _el = null
22
- this . scrollHeight = null
23
+ this . _scrollHeight = null
24
+ this . _isScrolledUp = null
23
25
}
24
26
scrollDownIfNeeded ( ) {
25
27
if ( this . _isScrolledDown && hasOverflow ( this . _el ) ) {
@@ -28,7 +30,7 @@ export default (Component, { isScrolledDownThreshold = 150 } = { }) => class ext
28
30
}
29
31
handleScroll ( e ) {
30
32
this . _isScrolledDown = isScrolledDown ( this . _el , isScrolledDownThreshold )
31
- if ( isScrolledTop ( this . _el ) ) {
33
+ if ( isScrolledUp ( this . _el ) ) {
32
34
this . props . onScrolledTop && this . props . onScrolledTop ( e )
33
35
}
34
36
this . props . onScrolled && this . props . onScrolled ( e )
@@ -37,17 +39,18 @@ export default (Component, { isScrolledDownThreshold = 150 } = { }) => class ext
37
39
this . scrollDownIfNeeded ( )
38
40
}
39
41
componentWillUpdate ( nextProps , nextState ) {
40
- this . scrollHeight = this . _el . scrollHeight
42
+ this . _scrollHeight = this . _el . scrollHeight
43
+ this . _isScrolledUp = isScrolledUp ( this . _el )
41
44
}
42
-
43
45
componentDidUpdate ( ) {
44
- if ( this . scrollHeight !== null ) {
46
+ /* if the list is scrolled all the way up and new items are added, preserve the current scroll position */
47
+ if ( this . _isScrolledUp && this . _scrollHeight !== null ) {
45
48
/* the scroll height increased by this much during the update */
46
- const difference = this . _el . scrollHeight - this . scrollHeight
47
- this . scrollHeight = null
49
+ const difference = this . _el . scrollHeight - this . _scrollHeight
50
+ this . _scrollHeight = null
48
51
scrollDownBy ( difference , this . _el )
49
52
}
50
- this . scrollDownIfNeeded ( )
53
+ else this . scrollDownIfNeeded ( )
51
54
}
52
55
render ( ) {
53
56
const { onScrolled, onScrolledTop, ...rest } = this . props
0 commit comments