react-window 1.8.2 → 1.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -66,7 +66,7 @@ var cachedRTLResult = null; // TRICKY According to the spec, scrollLeft should b
66
66
  // and then verify that the subsequent "scroll" event matches the negative offset.
67
67
  // If it does not match, then we can assume a non-standard RTL scroll implementation.
68
68
 
69
- function isRTLOffsetNegative(recalculate) {
69
+ function getRTLOffsetType(recalculate) {
70
70
  if (recalculate === void 0) {
71
71
  recalculate = false;
72
72
  }
@@ -84,8 +84,19 @@ function isRTLOffsetNegative(recalculate) {
84
84
  innerStyle.height = '100px';
85
85
  outerDiv.appendChild(innerDiv);
86
86
  document.body.appendChild(outerDiv);
87
- outerDiv.scrollLeft = -10;
88
- cachedRTLResult = outerDiv.scrollLeft === -10;
87
+
88
+ if (outerDiv.scrollLeft > 0) {
89
+ cachedRTLResult = 'positive-descending';
90
+ } else {
91
+ outerDiv.scrollLeft = 1;
92
+
93
+ if (outerDiv.scrollLeft === 0) {
94
+ cachedRTLResult = 'negative';
95
+ } else {
96
+ cachedRTLResult = 'positive-ascending';
97
+ }
98
+ }
99
+
89
100
  document.body.removeChild(outerDiv);
90
101
  return cachedRTLResult;
91
102
  }
@@ -203,11 +214,17 @@ function createGridComponent(_ref2) {
203
214
  if (itemStyleCache.hasOwnProperty(key)) {
204
215
  style = itemStyleCache[key];
205
216
  } else {
206
- var _style;
207
-
208
- itemStyleCache[key] = style = (_style = {
209
- position: 'absolute'
210
- }, _style[direction === 'rtl' ? 'right' : 'left'] = getColumnOffset(_this.props, columnIndex, _this._instanceProps), _style.top = getRowOffset(_this.props, rowIndex, _this._instanceProps), _style.height = getRowHeight(_this.props, rowIndex, _this._instanceProps), _style.width = getColumnWidth(_this.props, columnIndex, _this._instanceProps), _style);
217
+ var _offset = getColumnOffset(_this.props, columnIndex, _this._instanceProps);
218
+
219
+ var isRtl = direction === 'rtl';
220
+ itemStyleCache[key] = style = {
221
+ position: 'absolute',
222
+ left: isRtl ? undefined : _offset,
223
+ right: isRtl ? _offset : undefined,
224
+ top: getRowOffset(_this.props, rowIndex, _this._instanceProps),
225
+ height: getRowHeight(_this.props, rowIndex, _this._instanceProps),
226
+ width: getColumnWidth(_this.props, columnIndex, _this._instanceProps)
227
+ };
211
228
  }
212
229
 
213
230
  return style;
@@ -235,19 +252,22 @@ function createGridComponent(_ref2) {
235
252
  return null;
236
253
  }
237
254
 
238
- var direction = _this.props.direction;
255
+ var direction = _this.props.direction; // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
256
+ // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
257
+ // It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
258
+ // So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
259
+
239
260
  var calculatedScrollLeft = scrollLeft;
240
261
 
241
262
  if (direction === 'rtl') {
242
- var isNegative = isRTLOffsetNegative(); // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
243
- // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
244
- // It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
245
- // So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
246
-
247
- if (isNegative) {
248
- calculatedScrollLeft = -scrollLeft;
249
- } else {
250
- calculatedScrollLeft = scrollWidth - clientWidth - scrollLeft;
263
+ switch (getRTLOffsetType()) {
264
+ case 'negative':
265
+ calculatedScrollLeft = -scrollLeft;
266
+ break;
267
+
268
+ case 'positive-descending':
269
+ calculatedScrollLeft = scrollWidth - clientWidth - scrollLeft;
270
+ break;
251
271
  }
252
272
  } // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
253
273
 
@@ -412,14 +432,20 @@ function createGridComponent(_ref2) {
412
432
  var outerRef = this._outerRef;
413
433
 
414
434
  if (direction === 'rtl') {
415
- var isNegative = isRTLOffsetNegative();
435
+ switch (getRTLOffsetType()) {
436
+ case 'negative':
437
+ outerRef.scrollLeft = -scrollLeft;
438
+ break;
416
439
 
417
- if (isNegative) {
418
- outerRef.scrollLeft = -scrollLeft;
419
- } else {
420
- var clientWidth = outerRef.clientWidth,
421
- scrollWidth = outerRef.scrollWidth;
422
- outerRef.scrollLeft = scrollWidth - clientWidth - scrollLeft;
440
+ case 'positive-ascending':
441
+ outerRef.scrollLeft = scrollLeft;
442
+ break;
443
+
444
+ default:
445
+ var clientWidth = outerRef.clientWidth,
446
+ scrollWidth = outerRef.scrollWidth;
447
+ outerRef.scrollLeft = scrollWidth - clientWidth - scrollLeft;
448
+ break;
423
449
  }
424
450
  } else {
425
451
  outerRef.scrollLeft = Math.max(0, scrollLeft);
@@ -848,7 +874,11 @@ var getOffsetForIndexAndAlignment = function getOffsetForIndexAndAlignment(itemT
848
874
  default:
849
875
  if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
850
876
  return scrollOffset;
851
- } else if (scrollOffset - minOffset < maxOffset - scrollOffset) {
877
+ } else if (minOffset > maxOffset) {
878
+ // Because we only take into account the scrollbar size when calculating minOffset
879
+ // this value can be larger than maxOffset when at the end of the list
880
+ return minOffset;
881
+ } else if (scrollOffset < minOffset) {
852
882
  return minOffset;
853
883
  } else {
854
884
  return maxOffset;
@@ -1081,16 +1111,21 @@ function createListComponent(_ref) {
1081
1111
  if (itemStyleCache.hasOwnProperty(index)) {
1082
1112
  style = itemStyleCache[index];
1083
1113
  } else {
1084
- var _style;
1085
-
1086
1114
  var _offset = getItemOffset(_this.props, index, _this._instanceProps);
1087
1115
 
1088
1116
  var size = getItemSize(_this.props, index, _this._instanceProps); // TODO Deprecate direction "horizontal"
1089
1117
 
1090
1118
  var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
1091
- itemStyleCache[index] = style = (_style = {
1092
- position: 'absolute'
1093
- }, _style[direction === 'rtl' ? 'right' : 'left'] = isHorizontal ? _offset : 0, _style.top = !isHorizontal ? _offset : 0, _style.height = !isHorizontal ? size : '100%', _style.width = isHorizontal ? size : '100%', _style);
1119
+ var isRtl = direction === 'rtl';
1120
+ var offsetHorizontal = isHorizontal ? _offset : 0;
1121
+ itemStyleCache[index] = style = {
1122
+ position: 'absolute',
1123
+ left: isRtl ? undefined : offsetHorizontal,
1124
+ right: isRtl ? offsetHorizontal : undefined,
1125
+ top: !isHorizontal ? _offset : 0,
1126
+ height: !isHorizontal ? size : '100%',
1127
+ width: isHorizontal ? size : '100%'
1128
+ };
1094
1129
  }
1095
1130
 
1096
1131
  return style;
@@ -1119,15 +1154,18 @@ function createListComponent(_ref) {
1119
1154
  var scrollOffset = scrollLeft;
1120
1155
 
1121
1156
  if (direction === 'rtl') {
1122
- var isNegative = isRTLOffsetNegative(); // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
1157
+ // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
1123
1158
  // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
1124
1159
  // It's also easier for this component if we convert offsets to the same format as they would be in for ltr.
1125
1160
  // So the simplest solution is to determine which browser behavior we're dealing with, and convert based on it.
1126
-
1127
- if (isNegative) {
1128
- scrollOffset = -scrollLeft;
1129
- } else {
1130
- scrollOffset = scrollWidth - clientWidth - scrollLeft;
1161
+ switch (getRTLOffsetType()) {
1162
+ case 'negative':
1163
+ scrollOffset = -scrollLeft;
1164
+ break;
1165
+
1166
+ case 'positive-descending':
1167
+ scrollOffset = scrollWidth - clientWidth - scrollLeft;
1168
+ break;
1131
1169
  }
1132
1170
  } // Prevent Safari's elastic scrolling from causing visual shaking when scrolling past bounds.
1133
1171
 
@@ -1270,14 +1308,20 @@ function createListComponent(_ref) {
1270
1308
  // TRICKY According to the spec, scrollLeft should be negative for RTL aligned elements.
1271
1309
  // This is not the case for all browsers though (e.g. Chrome reports values as positive, measured relative to the left).
1272
1310
  // So we need to determine which browser behavior we're dealing with, and mimic it.
1273
- var isNegative = isRTLOffsetNegative();
1274
-
1275
- if (isNegative) {
1276
- outerRef.scrollLeft = -scrollOffset;
1277
- } else {
1278
- var clientWidth = outerRef.clientWidth,
1279
- scrollWidth = outerRef.scrollWidth;
1280
- outerRef.scrollLeft = scrollWidth - clientWidth - scrollOffset;
1311
+ switch (getRTLOffsetType()) {
1312
+ case 'negative':
1313
+ outerRef.scrollLeft = -scrollOffset;
1314
+ break;
1315
+
1316
+ case 'positive-ascending':
1317
+ outerRef.scrollLeft = scrollOffset;
1318
+ break;
1319
+
1320
+ default:
1321
+ var clientWidth = outerRef.clientWidth,
1322
+ scrollWidth = outerRef.scrollWidth;
1323
+ outerRef.scrollLeft = scrollWidth - clientWidth - scrollOffset;
1324
+ break;
1281
1325
  }
1282
1326
  } else {
1283
1327
  outerRef.scrollLeft = scrollOffset;
@@ -1641,7 +1685,7 @@ createListComponent({
1641
1685
  default:
1642
1686
  if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
1643
1687
  return scrollOffset;
1644
- } else if (scrollOffset - minOffset < maxOffset - scrollOffset) {
1688
+ } else if (scrollOffset < minOffset) {
1645
1689
  return minOffset;
1646
1690
  } else {
1647
1691
  return maxOffset;
@@ -1746,7 +1790,8 @@ createGridComponent({
1746
1790
  var columnCount = _ref7.columnCount,
1747
1791
  columnWidth = _ref7.columnWidth,
1748
1792
  width = _ref7.width;
1749
- var maxOffset = Math.max(0, Math.min(columnCount * columnWidth - width, columnIndex * columnWidth));
1793
+ var lastColumnOffset = Math.max(0, columnCount * columnWidth - width);
1794
+ var maxOffset = Math.min(lastColumnOffset, columnIndex * columnWidth);
1750
1795
  var minOffset = Math.max(0, columnIndex * columnWidth - width + scrollbarSize + columnWidth);
1751
1796
 
1752
1797
  if (align === 'smart') {
@@ -1765,13 +1810,27 @@ createGridComponent({
1765
1810
  return minOffset;
1766
1811
 
1767
1812
  case 'center':
1768
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
1813
+ // "Centered" offset is usually the average of the min and max.
1814
+ // But near the edges of the list, this doesn't hold true.
1815
+ var middleOffset = Math.round(minOffset + (maxOffset - minOffset) / 2);
1816
+
1817
+ if (middleOffset < Math.ceil(width / 2)) {
1818
+ return 0; // near the beginning
1819
+ } else if (middleOffset > lastColumnOffset + Math.floor(width / 2)) {
1820
+ return lastColumnOffset; // near the end
1821
+ } else {
1822
+ return middleOffset;
1823
+ }
1769
1824
 
1770
1825
  case 'auto':
1771
1826
  default:
1772
1827
  if (scrollLeft >= minOffset && scrollLeft <= maxOffset) {
1773
1828
  return scrollLeft;
1774
- } else if (scrollLeft - minOffset < maxOffset - scrollLeft) {
1829
+ } else if (minOffset > maxOffset) {
1830
+ // Because we only take into account the scrollbar size when calculating minOffset
1831
+ // this value can be larger than maxOffset when at the end of the list
1832
+ return minOffset;
1833
+ } else if (scrollLeft < minOffset) {
1775
1834
  return minOffset;
1776
1835
  } else {
1777
1836
  return maxOffset;
@@ -1783,7 +1842,8 @@ createGridComponent({
1783
1842
  var rowHeight = _ref8.rowHeight,
1784
1843
  height = _ref8.height,
1785
1844
  rowCount = _ref8.rowCount;
1786
- var maxOffset = Math.max(0, Math.min(rowCount * rowHeight - height, rowIndex * rowHeight));
1845
+ var lastRowOffset = Math.max(0, rowCount * rowHeight - height);
1846
+ var maxOffset = Math.min(lastRowOffset, rowIndex * rowHeight);
1787
1847
  var minOffset = Math.max(0, rowIndex * rowHeight - height + scrollbarSize + rowHeight);
1788
1848
 
1789
1849
  if (align === 'smart') {
@@ -1802,13 +1862,27 @@ createGridComponent({
1802
1862
  return minOffset;
1803
1863
 
1804
1864
  case 'center':
1805
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
1865
+ // "Centered" offset is usually the average of the min and max.
1866
+ // But near the edges of the list, this doesn't hold true.
1867
+ var middleOffset = Math.round(minOffset + (maxOffset - minOffset) / 2);
1868
+
1869
+ if (middleOffset < Math.ceil(height / 2)) {
1870
+ return 0; // near the beginning
1871
+ } else if (middleOffset > lastRowOffset + Math.floor(height / 2)) {
1872
+ return lastRowOffset; // near the end
1873
+ } else {
1874
+ return middleOffset;
1875
+ }
1806
1876
 
1807
1877
  case 'auto':
1808
1878
  default:
1809
1879
  if (scrollTop >= minOffset && scrollTop <= maxOffset) {
1810
1880
  return scrollTop;
1811
- } else if (scrollTop - minOffset < maxOffset - scrollTop) {
1881
+ } else if (minOffset > maxOffset) {
1882
+ // Because we only take into account the scrollbar size when calculating minOffset
1883
+ // this value can be larger than maxOffset when at the end of the list
1884
+ return minOffset;
1885
+ } else if (scrollTop < minOffset) {
1812
1886
  return minOffset;
1813
1887
  } else {
1814
1888
  return maxOffset;
@@ -1826,7 +1900,9 @@ createGridComponent({
1826
1900
  columnCount = _ref10.columnCount,
1827
1901
  width = _ref10.width;
1828
1902
  var left = startIndex * columnWidth;
1829
- return Math.max(0, Math.min(columnCount - 1, startIndex + Math.floor((width + (scrollLeft - left)) / columnWidth)));
1903
+ var numVisibleColumns = Math.ceil((width + scrollLeft - left) / columnWidth);
1904
+ return Math.max(0, Math.min(columnCount - 1, startIndex + numVisibleColumns - 1 // -1 is because stop index is inclusive
1905
+ ));
1830
1906
  },
1831
1907
  getRowStartIndexForOffset: function getRowStartIndexForOffset(_ref11, scrollTop) {
1832
1908
  var rowHeight = _ref11.rowHeight,
@@ -1837,8 +1913,10 @@ createGridComponent({
1837
1913
  var rowHeight = _ref12.rowHeight,
1838
1914
  rowCount = _ref12.rowCount,
1839
1915
  height = _ref12.height;
1840
- var left = startIndex * rowHeight;
1841
- return Math.max(0, Math.min(rowCount - 1, startIndex + Math.floor((height + (scrollTop - left)) / rowHeight)));
1916
+ var top = startIndex * rowHeight;
1917
+ var numVisibleRows = Math.ceil((height + scrollTop - top) / rowHeight);
1918
+ return Math.max(0, Math.min(rowCount - 1, startIndex + numVisibleRows - 1 // -1 is because stop index is inclusive
1919
+ ));
1842
1920
  },
1843
1921
  initInstanceProps: function initInstanceProps(props) {// Noop
1844
1922
  },
@@ -1863,13 +1941,11 @@ var FixedSizeList =
1863
1941
  /*#__PURE__*/
1864
1942
  createListComponent({
1865
1943
  getItemOffset: function getItemOffset(_ref, index) {
1866
- var itemSize = _ref.itemSize,
1867
- size = _ref.size;
1944
+ var itemSize = _ref.itemSize;
1868
1945
  return index * itemSize;
1869
1946
  },
1870
1947
  getItemSize: function getItemSize(_ref2, index) {
1871
- var itemSize = _ref2.itemSize,
1872
- size = _ref2.size;
1948
+ var itemSize = _ref2.itemSize;
1873
1949
  return itemSize;
1874
1950
  },
1875
1951
  getEstimatedTotalSize: function getEstimatedTotalSize(_ref3) {
@@ -1887,7 +1963,8 @@ createListComponent({
1887
1963
  // TODO Deprecate direction "horizontal"
1888
1964
  var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
1889
1965
  var size = isHorizontal ? width : height;
1890
- var maxOffset = Math.max(0, Math.min(itemCount * itemSize - size, index * itemSize));
1966
+ var lastItemOffset = Math.max(0, itemCount * itemSize - size);
1967
+ var maxOffset = Math.min(lastItemOffset, index * itemSize);
1891
1968
  var minOffset = Math.max(0, index * itemSize - size + itemSize);
1892
1969
 
1893
1970
  if (align === 'smart') {
@@ -1906,13 +1983,25 @@ createListComponent({
1906
1983
  return minOffset;
1907
1984
 
1908
1985
  case 'center':
1909
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
1986
+ {
1987
+ // "Centered" offset is usually the average of the min and max.
1988
+ // But near the edges of the list, this doesn't hold true.
1989
+ var middleOffset = Math.round(minOffset + (maxOffset - minOffset) / 2);
1990
+
1991
+ if (middleOffset < Math.ceil(size / 2)) {
1992
+ return 0; // near the beginning
1993
+ } else if (middleOffset > lastItemOffset + Math.floor(size / 2)) {
1994
+ return lastItemOffset; // near the end
1995
+ } else {
1996
+ return middleOffset;
1997
+ }
1998
+ }
1910
1999
 
1911
2000
  case 'auto':
1912
2001
  default:
1913
2002
  if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
1914
2003
  return scrollOffset;
1915
- } else if (scrollOffset - minOffset < maxOffset - scrollOffset) {
2004
+ } else if (scrollOffset < minOffset) {
1916
2005
  return minOffset;
1917
2006
  } else {
1918
2007
  return maxOffset;
@@ -1936,7 +2025,9 @@ createListComponent({
1936
2025
  var isHorizontal = direction === 'horizontal' || layout === 'horizontal';
1937
2026
  var offset = startIndex * itemSize;
1938
2027
  var size = isHorizontal ? width : height;
1939
- return Math.max(0, Math.min(itemCount - 1, startIndex + Math.floor((size + (scrollOffset - offset)) / itemSize)));
2028
+ var numVisibleItems = Math.ceil((size + scrollOffset - offset) / itemSize);
2029
+ return Math.max(0, Math.min(itemCount - 1, startIndex + numVisibleItems - 1 // -1 is because stop index is inclusive
2030
+ ));
1940
2031
  },
1941
2032
  initInstanceProps: function initInstanceProps(props) {// Noop
1942
2033
  },
@@ -1996,3 +2087,4 @@ exports.FixedSizeGrid = FixedSizeGrid;
1996
2087
  exports.FixedSizeList = FixedSizeList;
1997
2088
  exports.areEqual = areEqual;
1998
2089
  exports.shouldComponentUpdate = shouldComponentUpdate;
2090
+ //# sourceMappingURL=index.cjs.js.map