@samitouri / QOS-React-2 / commits / 9d90189ee3

react-window sync flushes scroll updates

Brian Vaughn committed Jun 5, 2019 at 14:30 UTC 9d90189ee3129f3a6169fb510ca33bcf69fd200c
1 file changed +74 -64
vendor/react-window/dist/index.esm.js
+74 -64
@@ -3,6 +3,7 @@ import _inheritsLoose from '@babel/runtime/helpers/esm/inheritsLoose';
3 import _assertThisInitialized from '@babel/runtime/helpers/esm/assertThisInitialized';
4 import memoizeOne from 'memoize-one';
5 import { createElement, PureComponent } from 'react';
6 +import { flushSync } from 'react-dom';
7 import _objectWithoutPropertiesLoose from '@babel/runtime/helpers/esm/objectWithoutPropertiesLoose';
8
9 // Animation frame based implementation of setTimeout.
@@ -182,37 +183,40 @@ function createGridComponent(_ref2) {
183 scrollTop = _event$currentTarget.scrollTop,
184 scrollWidth = _event$currentTarget.scrollWidth;
185
185 - _this.setState(function (prevState) {
186 - if (prevState.scrollLeft === scrollLeft && prevState.scrollTop === scrollTop) {
187 - // Scroll position may have been updated by cDM/cDU,
188 - // In which case we don't need to trigger another render,
189 - // And we don't want to update state.isScrolling.
190 - return null;
191 - }
186 + // Force flush sync for scroll updates to reduce visual checkerboarding.
187 + flushSync(() => {
188 + _this.setState(function (prevState) {
189 + if (prevState.scrollLeft === scrollLeft && prevState.scrollTop === scrollTop) {
190 + // Scroll position may have been updated by cDM/cDU,
191 + // In which case we don't need to trigger another render,
192 + // And we don't want to update state.isScrolling.
193 + return null;
194 + }
195
193 - var direction = _this.props.direction; // HACK According to the spec, scrollLeft should be negative for RTL aligned elements.
194 - // Chrome does not seem to adhere; its scrollLeft values are positive (measured relative to the left).
195 - // See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft
196 + var direction = _this.props.direction; // HACK According to the spec, scrollLeft should be negative for RTL aligned elements.
197 + // Chrome does not seem to adhere; its scrollLeft values are positive (measured relative to the left).
198 + // See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft
199
197 - var calculatedScrollLeft = scrollLeft;
200 + var calculatedScrollLeft = scrollLeft;
201
199 - if (direction === 'rtl') {
200 - if (scrollLeft <= 0) {
201 - calculatedScrollLeft = -scrollLeft;
202 - } else {
203 - calculatedScrollLeft = scrollWidth - clientWidth - scrollLeft;
202 + if (direction === 'rtl') {
203 + if (scrollLeft <= 0) {
204 + calculatedScrollLeft = -scrollLeft;
205 + } else {
206 + calculatedScrollLeft = scrollWidth - clientWidth - scrollLeft;
207 + }
208 }
205 - }
209
207 - return {
208 - isScrolling: true,
209 - horizontalScrollDirection: prevState.scrollLeft < scrollLeft ? 'forward' : 'backward',
210 - scrollLeft: calculatedScrollLeft,
211 - scrollTop: scrollTop,
212 - verticalScrollDirection: prevState.scrollTop < scrollTop ? 'forward' : 'backward',
213 - scrollUpdateWasRequested: false
214 - };
215 - }, _this._resetIsScrollingDebounced);
210 + return {
211 + isScrolling: true,
212 + horizontalScrollDirection: prevState.scrollLeft < scrollLeft ? 'forward' : 'backward',
213 + scrollLeft: calculatedScrollLeft,
214 + scrollTop: scrollTop,
215 + verticalScrollDirection: prevState.scrollTop < scrollTop ? 'forward' : 'backward',
216 + scrollUpdateWasRequested: false
217 + };
218 + }, _this._resetIsScrollingDebounced);
219 + });
220 };
221
222 _this._outerRefSetter = function (ref) {
@@ -1023,55 +1027,61 @@ function createListComponent(_ref) {
1027 scrollLeft = _event$currentTarget.scrollLeft,
1028 scrollWidth = _event$currentTarget.scrollWidth;
1029
1026 - _this.setState(function (prevState) {
1027 - if (prevState.scrollOffset === scrollLeft) {
1028 - // Scroll position may have been updated by cDM/cDU,
1029 - // In which case we don't need to trigger another render,
1030 - // And we don't want to update state.isScrolling.
1031 - return null;
1032 - }
1030 + // Force flush sync for scroll updates to reduce visual checkerboarding.
1031 + flushSync(() => {
1032 + _this.setState(function (prevState) {
1033 + if (prevState.scrollOffset === scrollLeft) {
1034 + // Scroll position may have been updated by cDM/cDU,
1035 + // In which case we don't need to trigger another render,
1036 + // And we don't want to update state.isScrolling.
1037 + return null;
1038 + }
1039
1034 - var direction = _this.props.direction; // HACK According to the spec, scrollLeft should be negative for RTL aligned elements.
1035 - // Chrome does not seem to adhere; its scrolLeft values are positive (measured relative to the left).
1036 - // See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft
1040 + var direction = _this.props.direction; // HACK According to the spec, scrollLeft should be negative for RTL aligned elements.
1041 + // Chrome does not seem to adhere; its scrolLeft values are positive (measured relative to the left).
1042 + // See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft
1043
1038 - var scrollOffset = scrollLeft;
1044 + var scrollOffset = scrollLeft;
1045
1040 - if (direction === 'rtl') {
1041 - if (scrollLeft <= 0) {
1042 - scrollOffset = -scrollOffset;
1043 - } else {
1044 - scrollOffset = scrollWidth - clientWidth - scrollLeft;
1046 + if (direction === 'rtl') {
1047 + if (scrollLeft <= 0) {
1048 + scrollOffset = -scrollOffset;
1049 + } else {
1050 + scrollOffset = scrollWidth - clientWidth - scrollLeft;
1051 + }
1052 }
1046 - }
1053
1048 - return {
1049 - isScrolling: true,
1050 - scrollDirection: prevState.scrollOffset < scrollLeft ? 'forward' : 'backward',
1051 - scrollOffset: scrollOffset,
1052 - scrollUpdateWasRequested: false
1053 - };
1054 - }, _this._resetIsScrollingDebounced);
1054 + return {
1055 + isScrolling: true,
1056 + scrollDirection: prevState.scrollOffset < scrollLeft ? 'forward' : 'backward',
1057 + scrollOffset: scrollOffset,
1058 + scrollUpdateWasRequested: false
1059 + };
1060 + }, _this._resetIsScrollingDebounced);
1061 + });
1062 };
1063
1064 _this._onScrollVertical = function (event) {
1065 var scrollTop = event.currentTarget.scrollTop;
1066
1060 - _this.setState(function (prevState) {
1061 - if (prevState.scrollOffset === scrollTop) {
1062 - // Scroll position may have been updated by cDM/cDU,
1063 - // In which case we don't need to trigger another render,
1064 - // And we don't want to update state.isScrolling.
1065 - return null;
1066 - }
1067 + // Force flush sync for scroll updates to reduce visual checkerboarding.
1068 + flushSync(() => {
1069 + _this.setState(function (prevState) {
1070 + if (prevState.scrollOffset === scrollTop) {
1071 + // Scroll position may have been updated by cDM/cDU,
1072 + // In which case we don't need to trigger another render,
1073 + // And we don't want to update state.isScrolling.
1074 + return null;
1075 + }
1076
1068 - return {
1069 - isScrolling: true,
1070 - scrollDirection: prevState.scrollOffset < scrollTop ? 'forward' : 'backward',
1071 - scrollOffset: scrollTop,
1072 - scrollUpdateWasRequested: false
1073 - };
1074 - }, _this._resetIsScrollingDebounced);
1077 + return {
1078 + isScrolling: true,
1079 + scrollDirection: prevState.scrollOffset < scrollTop ? 'forward' : 'backward',
1080 + scrollOffset: scrollTop,
1081 + scrollUpdateWasRequested: false
1082 + };
1083 + }, _this._resetIsScrollingDebounced);
1084 + });
1085 };
1086
1087 _this._outerRefSetter = function (ref) {