@ -39,8 +39,6 @@ export default class ScrollableList extends PureComponent {
state = {
state = {
fullscreen : null ,
fullscreen : null ,
mouseMovedRecently : false ,
scrollToTopOnMouseIdle : false ,
} ;
} ;
intersectionObserverWrapper = new IntersectionObserverWrapper ( ) ;
intersectionObserverWrapper = new IntersectionObserverWrapper ( ) ;
@ -65,6 +63,8 @@ export default class ScrollableList extends PureComponent {
} ) ;
} ) ;
mouseIdleTimer = null ;
mouseIdleTimer = null ;
mouseMovedRecently = false ;
scrollToTopOnMouseIdle = false ;
clearMouseIdleTimer = ( ) => {
clearMouseIdleTimer = ( ) => {
if ( this . mouseIdleTimer === null ) {
if ( this . mouseIdleTimer === null ) {
@ -80,29 +80,26 @@ export default class ScrollableList extends PureComponent {
this . mouseIdleTimer =
this . mouseIdleTimer =
setTimeout ( this . handleMouseIdle , MOUSE _IDLE _DELAY ) ;
setTimeout ( this . handleMouseIdle , MOUSE _IDLE _DELAY ) ;
this . setState ( ( {
if ( ! this . mouseMovedRecently && this . node . scrollTop === 0 ) {
mouseMovedRecently ,
// Only set if we just started moving and are scrolled to the top.
scrollToTopOnMouseIdle ,
this . scrollToTopOnMouseIdle = true ;
} ) => ( {
}
mouseMovedRecently : true ,
// Save setting this flag for last, so we can do the comparison above.
// Only set scrollToTopOnMouseIdle if we just started moving and were
this . mouseMovedRecently = true ;
// scrolled to the top. Otherwise, just retain the previous state.
scrollToTopOnMouseIdle :
mouseMovedRecently
? scrollToTopOnMouseIdle
: ( this . node . scrollTop === 0 ) ,
} ) ) ;
} , MOUSE _IDLE _DELAY / 2 ) ;
} , MOUSE _IDLE _DELAY / 2 ) ;
handleWheel = throttle ( ( ) => {
this . scrollToTopOnMouseIdle = false ;
} , 150 , {
trailing : true ,
} ) ;
handleMouseIdle = ( ) => {
handleMouseIdle = ( ) => {
if ( this . state . scrollToTopOnMouseIdle ) {
if ( this . scrollToTopOnMouseIdle ) {
this . node . scrollTop = 0 ;
this . node . scrollTop = 0 ;
this . props . onScrollToTop ( ) ;
}
}
this . setState ( {
this . mouseMovedRecently = false ;
mouseMovedRecently : false ,
this . scrollToTopOnMouseIdle = false ;
scrollToTopOnMouseIdle : false ,
} ) ;
}
}
componentDidMount ( ) {
componentDidMount ( ) {
@ -118,7 +115,7 @@ export default class ScrollableList extends PureComponent {
const someItemInserted = React . Children . count ( prevProps . children ) > 0 &&
const someItemInserted = React . Children . count ( prevProps . children ) > 0 &&
React . Children . count ( prevProps . children ) < React . Children . count ( this . props . children ) &&
React . Children . count ( prevProps . children ) < React . Children . count ( this . props . children ) &&
this . getFirstChildKey ( prevProps ) !== this . getFirstChildKey ( this . props ) ;
this . getFirstChildKey ( prevProps ) !== this . getFirstChildKey ( this . props ) ;
if ( ( someItemInserted && this . node . scrollTop > 0 ) || this . state . mouseMovedRecently ) {
if ( ( someItemInserted && this . node . scrollTop > 0 ) || this . mouseMovedRecently ) {
return this . node . scrollHeight - this . node . scrollTop ;
return this . node . scrollHeight - this . node . scrollTop ;
} else {
} else {
return null ;
return null ;
@ -161,10 +158,12 @@ export default class ScrollableList extends PureComponent {
attachScrollListener ( ) {
attachScrollListener ( ) {
this . node . addEventListener ( 'scroll' , this . handleScroll ) ;
this . node . addEventListener ( 'scroll' , this . handleScroll ) ;
this . node . addEventListener ( 'wheel' , this . handleWheel ) ;
}
}
detachScrollListener ( ) {
detachScrollListener ( ) {
this . node . removeEventListener ( 'scroll' , this . handleScroll ) ;
this . node . removeEventListener ( 'scroll' , this . handleScroll ) ;
this . node . removeEventListener ( 'wheel' , this . handleWheel ) ;
}
}
getFirstChildKey ( props ) {
getFirstChildKey ( props ) {