-
Notifications
You must be signed in to change notification settings - Fork 290
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow touch scroll to be default prevented by making the handlers passive #423
Changes from 5 commits
0d3a5f6
a86b63f
fb83c2b
803faaf
6db0796
4127040
07a376f
44a1411
3499535
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -312,6 +312,14 @@ class FixedDataTable extends React.Component { | |
*/ | ||
stopReactWheelPropagation: PropTypes.bool, | ||
|
||
/** | ||
* If enabled scroll events will never be default handled. | ||
* If disabled/unspecified, scroll events will be default handled if the scroll | ||
* doesn't lead to a change in scroll offsets, which is preferable if you like | ||
* the page/container to scroll up when the table is already scrolled up max. | ||
*/ | ||
stopScrollDefaultHandling: PropTypes.bool, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the prop name and description fine? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you change the term "default handled" to "bubbled to the browser default handler"? Otherwise looks good. |
||
|
||
/** | ||
* If enabled scroll events will not be propagated outside of the table. | ||
*/ | ||
|
@@ -444,23 +452,32 @@ class FixedDataTable extends React.Component { | |
this._onScroll, | ||
this._shouldHandleWheelX, | ||
this._shouldHandleWheelY, | ||
this.props.stopScrollDefaultHandling, | ||
this.props.stopScrollPropagation | ||
); | ||
|
||
this._touchHandler = new ReactTouchHandler( | ||
this._onScroll, | ||
this._shouldHandleTouchX, | ||
this._shouldHandleTouchY, | ||
this.props.stopScrollDefaultHandling, | ||
this.props.stopScrollPropagation | ||
); | ||
} | ||
|
||
componentWillUnmount() { | ||
// TODO (pradeep): Remove these and pass to our table component directly after | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here's the related issue if you want to reference it: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks, will put. |
||
// React provides an API where event handlers can be specified to be non-passive (facebook/react#6436) | ||
this._divRef && this._divRef.removeEventListener( | ||
'wheel', | ||
this._wheelHandler.onWheel, | ||
{ passive: false } | ||
); | ||
this._divRef && this._divRef.removeEventListener( | ||
'touchmove', | ||
this._touchHandler.onTouchMove, | ||
{ passive: false } | ||
); | ||
this._wheelHandler = null; | ||
this._touchHandler = null; | ||
|
||
|
@@ -576,6 +593,11 @@ class FixedDataTable extends React.Component { | |
this._wheelHandler.onWheel, | ||
{ passive: false } | ||
); | ||
this._divRef && this._divRef.addEventListener( | ||
'touchmove', | ||
this._touchHandler.onTouchMove, | ||
{ passive: false } | ||
); | ||
this._reportContentHeight(); | ||
} | ||
|
||
|
@@ -798,7 +820,6 @@ class FixedDataTable extends React.Component { | |
onKeyDown={this._onKeyDown} | ||
onTouchStart={this._touchHandler.onTouchStart} | ||
onTouchEnd={this._touchHandler.onTouchEnd} | ||
onTouchMove={this._touchHandler.onTouchMove} | ||
onTouchCancel={this._touchHandler.onTouchCancel} | ||
ref={this._onRef} | ||
style={{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,6 +35,7 @@ class ReactTouchHandler { | |
/*function*/ onTouchScroll, | ||
/*boolean|function*/ handleScrollX, | ||
/*boolean|function*/ handleScrollY, | ||
/*?boolean|?function*/ preventDefault, | ||
/*?boolean|?function*/ stopPropagation | ||
) { | ||
|
||
|
@@ -78,7 +79,15 @@ class ReactTouchHandler { | |
emptyFunction.thatReturnsFalse; | ||
} | ||
|
||
// Can we just make this a boolean flag instead? | ||
if (typeof preventDefault !== 'function') { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep, let's not support passing a function. It doesn't take args, so I can't imagine what they would be using to decide... |
||
preventDefault = preventDefault ? | ||
emptyFunction.thatReturnsTrue : | ||
emptyFunction.thatReturnsFalse; | ||
} | ||
|
||
// TODO (jordan) Is configuring this necessary | ||
// I don't think so. We are only just passing a boolean anyway. | ||
if (typeof stopPropagation !== 'function') { | ||
stopPropagation = stopPropagation ? | ||
emptyFunction.thatReturnsTrue : | ||
|
@@ -87,6 +96,7 @@ class ReactTouchHandler { | |
|
||
this._handleScrollX = handleScrollX; | ||
this._handleScrollY = handleScrollY; | ||
this._preventDefault = preventDefault; | ||
this._stopPropagation = stopPropagation; | ||
this._onTouchScrollCallback = onTouchScroll; | ||
|
||
|
@@ -148,6 +158,9 @@ class ReactTouchHandler { | |
} | ||
|
||
onTouchMove(/*object*/ event) { | ||
if (this._preventDefault()) { | ||
event.preventDefault(); | ||
} | ||
|
||
var moveX = event.touches[0].pageX; | ||
var moveY = event.touches[0].pageY; | ||
|
@@ -175,7 +188,10 @@ class ReactTouchHandler { | |
this._deltaY = 0; | ||
} | ||
|
||
event.preventDefault(); | ||
// The event will result in a scroll to the table, so there's no need to also let the parent containers scroll | ||
if (!event.defaultPrevented) { | ||
event.preventDefault(); | ||
} | ||
|
||
// Ensure minimum delta magnitude is met to avoid jitter | ||
var changed = false; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just removed the wrapper div since the parent element and style is no longer needed