Skip to content

Commit

Permalink
Add scrollToIndex support in WindowScroller
Browse files Browse the repository at this point in the history
  • Loading branch information
leoasis committed Apr 4, 2017
1 parent 5984b6f commit 9fdaef6
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 7 deletions.
35 changes: 30 additions & 5 deletions source/WindowScroller/WindowScroller.example.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import cn from 'classnames'
import Immutable from 'immutable'
import React, { PropTypes, PureComponent } from 'react'
import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox'
import { LabeledInput, InputRow } from '../demo/LabeledInput'
import WindowScroller from './WindowScroller'
import List from '../List'
import AutoSizer from '../AutoSizer'
Expand All @@ -20,18 +21,20 @@ export default class WindowScrollerExample extends PureComponent {
super(props)

this.state = {
showHeaderText: true
showHeaderText: true,
scrollToIndex: undefined
}

this._hideHeader = this._hideHeader.bind(this)
this._rowRenderer = this._rowRenderer.bind(this)
this._onCheckboxChange = this._onCheckboxChange.bind(this)
this._onScrollToRowChange = this._onScrollToRowChange.bind(this)
this._setRef = this._setRef.bind(this)
}

render () {
const { list, isScrollingCustomElement, customElement } = this.context
const { showHeaderText } = this.state
const { showHeaderText, scrollToIndex } = this.state

return (
<ContentBox>
Expand Down Expand Up @@ -68,16 +71,25 @@ export default class WindowScrollerExample extends PureComponent {
Use custom element for scrolling
</label>
</ContentBoxParagraph>

<InputRow>
<LabeledInput
label='Scroll to'
name='onScrollToRow'
placeholder='Index...'
onChange={this._onScrollToRowChange}
value={scrollToIndex || ''}
/>
</InputRow>
<div className={styles.WindowScrollerWrapper}>
<WindowScroller
ref={this._setRef}
scrollElement={isScrollingCustomElement ? customElement : null}
>
{({ height, isScrolling, scrollTop }) => (
{({ height, isScrolling, scrollTop, onChildScroll }) => (
<AutoSizer disableHeight>
{({ width }) => (
<List
ref={(el) => { window.listEl = el }}
autoHeight
className={styles.List}
height={height}
Expand All @@ -86,7 +98,9 @@ export default class WindowScrollerExample extends PureComponent {
rowHeight={30}
rowRenderer={({ index, isVisible, key, style }) => this._rowRenderer({ index, isScrolling, isVisible, key, style })}
scrollTop={scrollTop}
scrollToIndex={scrollToIndex}
width={width}
onScroll={onChildScroll}
/>
)}
</AutoSizer>
Expand Down Expand Up @@ -121,7 +135,7 @@ export default class WindowScrollerExample extends PureComponent {
className={className}
style={style}
>
{row.name}
<i style={{marginRight: 5}}>{index}</i>{row.name}
</div>
)
}
Expand All @@ -133,4 +147,15 @@ export default class WindowScrollerExample extends PureComponent {
_onCheckboxChange (event) {
this.context.setScrollingCustomElement(event.target.checked)
}

_onScrollToRowChange (event) {
const { list } = this.context
let scrollToIndex = Math.min(list.size - 1, parseInt(event.target.value, 10))

if (isNaN(scrollToIndex)) {
scrollToIndex = undefined
}

this.setState({ scrollToIndex })
}
}
24 changes: 22 additions & 2 deletions source/WindowScroller/WindowScroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default class WindowScroller extends PureComponent {
}

this._onResize = this._onResize.bind(this)
this._onChildScroll = this._onChildScroll.bind(this)
this.__handleWindowScrollEvent = this.__handleWindowScrollEvent.bind(this)
this.__resetIsScrolling = this.__resetIsScrolling.bind(this)
}
Expand Down Expand Up @@ -97,7 +98,6 @@ export default class WindowScroller extends PureComponent {

componentWillUnmount () {
unregisterScrollListener(this, this.props.scrollElement || window)

window.removeEventListener('resize', this._onResize, false)
}

Expand All @@ -108,14 +108,34 @@ export default class WindowScroller extends PureComponent {
return children({
height,
isScrolling,
scrollTop
scrollTop,
onChildScroll: this._onChildScroll
})
}

_onResize (event) {
this.updatePosition()
}

_onChildScroll ({ scrollTop }) {
if (this.state.scrollTop === scrollTop) return

// Need this setTimeout here because otherwise for some reason by the time the 'scroll'
// event that happens after the `scrollTo` call, the `window.scrollY` value is incorrect.
// Visually, if setTimeout is not here, the scroll position changes back to the top
// even after calling `scrollTo` below.
// What makes this even weirder, this happens only if you scroll to a row index
// via the `scrollToRow` prop. This does not happen with the imperative method.
setTimeout(() => {
const scrollElement = this.scrollElement
if (scrollElement.scrollTo) {
scrollElement.scrollTo(0, scrollTop + this._positionFromTop)
} else {
scrollElement.scrollTop = scrollTop + this._positionFromTop
}
}, 0)
}

// Referenced by utils/onScroll
__handleWindowScrollEvent (event) {
const { onScroll } = this.props
Expand Down
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1110,6 +1110,10 @@ binary-extensions@^1.0.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.7.0.tgz#6c1610db163abfb34edfe42fa423343a1e01185d"

binary-search-bounds@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/binary-search-bounds/-/binary-search-bounds-1.0.0.tgz#323ca317e3f2a40f4244c7255f5384a5b207bb69"

blessed@^0.1.81:
version "0.1.81"
resolved "https://registry.yarnpkg.com/blessed/-/blessed-0.1.81.tgz#f962d687ec2c369570ae71af843256e6d0ca1129"
Expand Down Expand Up @@ -2840,6 +2844,12 @@ interpret@^0.6.4:
version "0.6.6"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-0.6.6.tgz#fecd7a18e7ce5ca6abfb953e1f86213a49f1625b"

interval-tree-1d@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/interval-tree-1d/-/interval-tree-1d-1.0.3.tgz#8fdbde02b6b2c7dbdead636bcbed8e08710d85c1"
dependencies:
binary-search-bounds "^1.0.0"

invariant@^2.2.0, invariant@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.1.tgz#b097010547668c7e337028ebe816ebe36c8a8d54"
Expand Down

0 comments on commit 9fdaef6

Please sign in to comment.