virtual-scroller 1.7.9 → 1.9.0

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.
Files changed (283) hide show
  1. package/.gitlab-ci.yml +1 -1
  2. package/CHANGELOG.md +71 -1
  3. package/README.md +434 -151
  4. package/bundle/index-bypass.html +1 -1
  5. package/bundle/index-dom.html +1 -1
  6. package/bundle/index-grid.html +1 -2
  7. package/bundle/index-scrollableContainer.html +1 -1
  8. package/bundle/index-tbody-scrollableContainer.html +2 -0
  9. package/bundle/index-tbody.html +2 -0
  10. package/bundle/virtual-scroller-dom.js +1 -1
  11. package/bundle/virtual-scroller-dom.js.map +1 -1
  12. package/bundle/virtual-scroller-react.js +1 -1
  13. package/bundle/virtual-scroller-react.js.map +1 -1
  14. package/bundle/virtual-scroller.js +1 -1
  15. package/bundle/virtual-scroller.js.map +1 -1
  16. package/commonjs/BeforeResize.js +315 -0
  17. package/commonjs/BeforeResize.js.map +1 -0
  18. package/commonjs/DOM/Engine.js +46 -0
  19. package/commonjs/DOM/Engine.js.map +1 -0
  20. package/commonjs/DOM/ItemsContainer.js +78 -0
  21. package/commonjs/DOM/ItemsContainer.js.map +1 -0
  22. package/commonjs/DOM/{WaitForStylesToLoad.js → ListTopOffsetWatcher.js} +71 -44
  23. package/commonjs/DOM/ListTopOffsetWatcher.js.map +1 -0
  24. package/commonjs/DOM/ScrollableContainer.js +69 -101
  25. package/commonjs/DOM/ScrollableContainer.js.map +1 -1
  26. package/commonjs/DOM/VirtualScroller.js +37 -29
  27. package/commonjs/DOM/VirtualScroller.js.map +1 -1
  28. package/commonjs/DOM/tbody.js +17 -11
  29. package/commonjs/DOM/tbody.js.map +1 -1
  30. package/commonjs/ItemHeights.js +33 -34
  31. package/commonjs/ItemHeights.js.map +1 -1
  32. package/commonjs/Layout.js +591 -216
  33. package/commonjs/Layout.js.map +1 -1
  34. package/commonjs/Layout.test.js +196 -0
  35. package/commonjs/Layout.test.js.map +1 -0
  36. package/commonjs/ListHeightMeasurement.js +124 -0
  37. package/commonjs/ListHeightMeasurement.js.map +1 -0
  38. package/commonjs/Resize.js +50 -39
  39. package/commonjs/Resize.js.map +1 -1
  40. package/commonjs/Scroll.js +139 -95
  41. package/commonjs/Scroll.js.map +1 -1
  42. package/commonjs/VirtualScroller.columns.js +43 -0
  43. package/commonjs/VirtualScroller.columns.js.map +1 -0
  44. package/commonjs/VirtualScroller.constructor.js +408 -0
  45. package/commonjs/VirtualScroller.constructor.js.map +1 -0
  46. package/commonjs/VirtualScroller.items.js +305 -0
  47. package/commonjs/VirtualScroller.items.js.map +1 -0
  48. package/commonjs/VirtualScroller.js +160 -1021
  49. package/commonjs/VirtualScroller.js.map +1 -1
  50. package/commonjs/VirtualScroller.layout.js +562 -0
  51. package/commonjs/VirtualScroller.layout.js.map +1 -0
  52. package/commonjs/VirtualScroller.onRender.js +357 -0
  53. package/commonjs/VirtualScroller.onRender.js.map +1 -0
  54. package/commonjs/VirtualScroller.resize.js +186 -0
  55. package/commonjs/VirtualScroller.resize.js.map +1 -0
  56. package/commonjs/VirtualScroller.state.js +301 -0
  57. package/commonjs/VirtualScroller.state.js.map +1 -0
  58. package/commonjs/VirtualScroller.verticalSpacing.js +65 -0
  59. package/commonjs/VirtualScroller.verticalSpacing.js.map +1 -0
  60. package/commonjs/getItemCoordinates.js.map +1 -1
  61. package/commonjs/getItemsDiff.js.map +1 -1
  62. package/commonjs/getVerticalSpacing.js +8 -8
  63. package/commonjs/getVerticalSpacing.js.map +1 -1
  64. package/commonjs/package.json +5 -0
  65. package/commonjs/react/VirtualScroller.js +182 -628
  66. package/commonjs/react/VirtualScroller.js.map +1 -1
  67. package/commonjs/react/useClassName.js +26 -0
  68. package/commonjs/react/useClassName.js.map +1 -0
  69. package/commonjs/react/useHandleItemsChange.js +116 -0
  70. package/commonjs/react/useHandleItemsChange.js.map +1 -0
  71. package/commonjs/react/useInstanceMethods.js +37 -0
  72. package/commonjs/react/useInstanceMethods.js.map +1 -0
  73. package/commonjs/react/useItemKeys.js +60 -0
  74. package/commonjs/react/useItemKeys.js.map +1 -0
  75. package/commonjs/react/useOnItemHeightChange.js +32 -0
  76. package/commonjs/react/useOnItemHeightChange.js.map +1 -0
  77. package/commonjs/react/useOnItemStateChange.js +32 -0
  78. package/commonjs/react/useOnItemStateChange.js.map +1 -0
  79. package/commonjs/react/useState.js +140 -0
  80. package/commonjs/react/useState.js.map +1 -0
  81. package/commonjs/react/useStyle.js +29 -0
  82. package/commonjs/react/useStyle.js.map +1 -0
  83. package/commonjs/react/useVirtualScroller.js +62 -0
  84. package/commonjs/react/useVirtualScroller.js.map +1 -0
  85. package/commonjs/react/useVirtualScrollerStartStop.js +20 -0
  86. package/commonjs/react/useVirtualScrollerStartStop.js.map +1 -0
  87. package/commonjs/test/Engine.js +23 -0
  88. package/commonjs/test/Engine.js.map +1 -0
  89. package/commonjs/test/ItemsContainer.js +127 -0
  90. package/commonjs/test/ItemsContainer.js.map +1 -0
  91. package/commonjs/test/ScrollableContainer.js +130 -0
  92. package/commonjs/test/ScrollableContainer.js.map +1 -0
  93. package/commonjs/test/VirtualScroller.js +281 -0
  94. package/commonjs/test/VirtualScroller.js.map +1 -0
  95. package/commonjs/utility/debounce.js +28 -6
  96. package/commonjs/utility/debounce.js.map +1 -1
  97. package/commonjs/utility/debug.js +51 -12
  98. package/commonjs/utility/debug.js.map +1 -1
  99. package/commonjs/utility/getStateSnapshot.js +50 -0
  100. package/commonjs/utility/getStateSnapshot.js.map +1 -0
  101. package/commonjs/utility/px.js +1 -1
  102. package/commonjs/utility/px.js.map +1 -1
  103. package/commonjs/utility/px.test.js +14 -0
  104. package/commonjs/utility/px.test.js.map +1 -0
  105. package/commonjs/utility/shallowEqual.js +1 -1
  106. package/commonjs/utility/shallowEqual.js.map +1 -1
  107. package/commonjs/utility/throttle.js.map +1 -1
  108. package/dom/index.cjs +4 -0
  109. package/dom/index.cjs.js +9 -0
  110. package/dom/index.d.ts +25 -0
  111. package/dom/index.js +1 -1
  112. package/dom/package.json +10 -4
  113. package/index.cjs +4 -0
  114. package/index.cjs.js +9 -0
  115. package/index.d.ts +99 -0
  116. package/index.js +1 -1
  117. package/modules/BeforeResize.js +305 -0
  118. package/modules/BeforeResize.js.map +1 -0
  119. package/modules/DOM/Engine.js +27 -0
  120. package/modules/DOM/Engine.js.map +1 -0
  121. package/modules/DOM/ItemsContainer.js +71 -0
  122. package/modules/DOM/ItemsContainer.js.map +1 -0
  123. package/modules/DOM/{WaitForStylesToLoad.js → ListTopOffsetWatcher.js} +72 -44
  124. package/modules/DOM/ListTopOffsetWatcher.js.map +1 -0
  125. package/modules/DOM/ScrollableContainer.js +68 -100
  126. package/modules/DOM/ScrollableContainer.js.map +1 -1
  127. package/modules/DOM/VirtualScroller.js +32 -28
  128. package/modules/DOM/VirtualScroller.js.map +1 -1
  129. package/modules/DOM/tbody.js +11 -9
  130. package/modules/DOM/tbody.js.map +1 -1
  131. package/modules/ItemHeights.js +28 -33
  132. package/modules/ItemHeights.js.map +1 -1
  133. package/modules/Layout.js +585 -214
  134. package/modules/Layout.js.map +1 -1
  135. package/modules/Layout.test.js +190 -0
  136. package/modules/Layout.test.js.map +1 -0
  137. package/modules/ListHeightMeasurement.js +117 -0
  138. package/modules/ListHeightMeasurement.js.map +1 -0
  139. package/modules/Resize.js +50 -39
  140. package/modules/Resize.js.map +1 -1
  141. package/modules/Scroll.js +139 -94
  142. package/modules/Scroll.js.map +1 -1
  143. package/modules/VirtualScroller.columns.js +36 -0
  144. package/modules/VirtualScroller.columns.js.map +1 -0
  145. package/modules/VirtualScroller.constructor.js +371 -0
  146. package/modules/VirtualScroller.constructor.js.map +1 -0
  147. package/modules/VirtualScroller.items.js +288 -0
  148. package/modules/VirtualScroller.items.js.map +1 -0
  149. package/modules/VirtualScroller.js +159 -1014
  150. package/modules/VirtualScroller.js.map +1 -1
  151. package/modules/VirtualScroller.layout.js +549 -0
  152. package/modules/VirtualScroller.layout.js.map +1 -0
  153. package/modules/VirtualScroller.onRender.js +337 -0
  154. package/modules/VirtualScroller.onRender.js.map +1 -0
  155. package/modules/VirtualScroller.resize.js +176 -0
  156. package/modules/VirtualScroller.resize.js.map +1 -0
  157. package/modules/VirtualScroller.state.js +283 -0
  158. package/modules/VirtualScroller.state.js.map +1 -0
  159. package/modules/VirtualScroller.verticalSpacing.js +54 -0
  160. package/modules/VirtualScroller.verticalSpacing.js.map +1 -0
  161. package/modules/getItemCoordinates.js.map +1 -1
  162. package/modules/getItemsDiff.js.map +1 -1
  163. package/modules/getVerticalSpacing.js +8 -8
  164. package/modules/getVerticalSpacing.js.map +1 -1
  165. package/modules/react/VirtualScroller.js +179 -634
  166. package/modules/react/VirtualScroller.js.map +1 -1
  167. package/modules/react/useClassName.js +18 -0
  168. package/modules/react/useClassName.js.map +1 -0
  169. package/modules/react/useHandleItemsChange.js +108 -0
  170. package/modules/react/useHandleItemsChange.js.map +1 -0
  171. package/modules/react/useInstanceMethods.js +28 -0
  172. package/modules/react/useInstanceMethods.js.map +1 -0
  173. package/modules/react/useItemKeys.js +52 -0
  174. package/modules/react/useItemKeys.js.map +1 -0
  175. package/modules/react/useOnItemHeightChange.js +24 -0
  176. package/modules/react/useOnItemHeightChange.js.map +1 -0
  177. package/modules/react/useOnItemStateChange.js +24 -0
  178. package/modules/react/useOnItemStateChange.js.map +1 -0
  179. package/modules/react/useState.js +132 -0
  180. package/modules/react/useState.js.map +1 -0
  181. package/modules/react/useStyle.js +19 -0
  182. package/modules/react/useStyle.js.map +1 -0
  183. package/modules/react/useVirtualScroller.js +51 -0
  184. package/modules/react/useVirtualScroller.js.map +1 -0
  185. package/modules/react/useVirtualScrollerStartStop.js +12 -0
  186. package/modules/react/useVirtualScrollerStartStop.js.map +1 -0
  187. package/modules/test/Engine.js +11 -0
  188. package/modules/test/Engine.js.map +1 -0
  189. package/modules/test/ItemsContainer.js +120 -0
  190. package/modules/test/ItemsContainer.js.map +1 -0
  191. package/modules/test/ScrollableContainer.js +123 -0
  192. package/modules/test/ScrollableContainer.js.map +1 -0
  193. package/modules/test/VirtualScroller.js +270 -0
  194. package/modules/test/VirtualScroller.js.map +1 -0
  195. package/modules/utility/debounce.js +28 -6
  196. package/modules/utility/debounce.js.map +1 -1
  197. package/modules/utility/debug.js +47 -10
  198. package/modules/utility/debug.js.map +1 -1
  199. package/modules/utility/getStateSnapshot.js +43 -0
  200. package/modules/utility/getStateSnapshot.js.map +1 -0
  201. package/modules/utility/px.js +1 -1
  202. package/modules/utility/px.js.map +1 -1
  203. package/modules/utility/px.test.js +9 -0
  204. package/modules/utility/px.test.js.map +1 -0
  205. package/modules/utility/shallowEqual.js +1 -1
  206. package/modules/utility/shallowEqual.js.map +1 -1
  207. package/modules/utility/throttle.js.map +1 -1
  208. package/package.json +54 -29
  209. package/react/index.cjs +4 -0
  210. package/react/index.cjs.js +9 -0
  211. package/react/index.d.ts +28 -0
  212. package/react/index.js +1 -1
  213. package/react/package.json +10 -4
  214. package/rollup.config.mjs +62 -0
  215. package/runnable/create-commonjs-package-json.js +11 -0
  216. package/source/BeforeResize.js +312 -0
  217. package/source/DOM/Engine.js +30 -0
  218. package/source/DOM/ItemsContainer.js +48 -0
  219. package/source/DOM/{WaitForStylesToLoad.js → ListTopOffsetWatcher.js} +61 -30
  220. package/source/DOM/ScrollableContainer.js +51 -73
  221. package/source/DOM/VirtualScroller.js +33 -18
  222. package/source/DOM/tbody.js +30 -21
  223. package/source/ItemHeights.js +27 -27
  224. package/source/Layout.js +629 -252
  225. package/source/Layout.test.js +176 -0
  226. package/source/ListHeightMeasurement.js +95 -0
  227. package/source/Resize.js +56 -32
  228. package/source/Scroll.js +135 -82
  229. package/source/VirtualScroller.columns.js +26 -0
  230. package/source/VirtualScroller.constructor.js +336 -0
  231. package/source/VirtualScroller.items.js +302 -0
  232. package/source/VirtualScroller.js +162 -936
  233. package/source/VirtualScroller.layout.js +539 -0
  234. package/source/VirtualScroller.onRender.js +345 -0
  235. package/source/VirtualScroller.resize.js +189 -0
  236. package/source/VirtualScroller.state.js +284 -0
  237. package/source/VirtualScroller.verticalSpacing.js +51 -0
  238. package/source/getVerticalSpacing.js +7 -7
  239. package/source/react/VirtualScroller.js +243 -603
  240. package/source/react/useClassName.js +14 -0
  241. package/source/react/useHandleItemsChange.js +115 -0
  242. package/source/react/useInstanceMethods.js +25 -0
  243. package/source/react/useItemKeys.js +59 -0
  244. package/source/react/useOnItemHeightChange.js +28 -0
  245. package/source/react/useOnItemStateChange.js +28 -0
  246. package/source/react/useState.js +114 -0
  247. package/source/react/useStyle.js +20 -0
  248. package/source/react/useVirtualScroller.js +59 -0
  249. package/source/react/useVirtualScrollerStartStop.js +12 -0
  250. package/source/test/Engine.js +11 -0
  251. package/source/test/ItemsContainer.js +87 -0
  252. package/source/test/ScrollableContainer.js +88 -0
  253. package/source/test/VirtualScroller.js +232 -0
  254. package/source/utility/debounce.js +22 -5
  255. package/source/utility/debug.js +34 -3
  256. package/source/utility/getStateSnapshot.js +36 -0
  257. package/source/utility/px.js +1 -1
  258. package/source/utility/px.test.js +9 -0
  259. package/website/index-bypass.html +195 -0
  260. package/website/index-grid.html +0 -1
  261. package/website/index-scrollableContainer.html +208 -0
  262. package/website/index-tbody-scrollableContainer.html +68 -0
  263. package/website/index-tbody.html +55 -0
  264. package/commonjs/DOM/RenderingEngine.js +0 -33
  265. package/commonjs/DOM/RenderingEngine.js.map +0 -1
  266. package/commonjs/DOM/Screen.js +0 -87
  267. package/commonjs/DOM/Screen.js.map +0 -1
  268. package/commonjs/DOM/WaitForStylesToLoad.js.map +0 -1
  269. package/commonjs/RestoreScroll.js +0 -118
  270. package/commonjs/RestoreScroll.js.map +0 -1
  271. package/dom/index.commonjs.js +0 -4
  272. package/index.commonjs.js +0 -4
  273. package/modules/DOM/RenderingEngine.js +0 -19
  274. package/modules/DOM/RenderingEngine.js.map +0 -1
  275. package/modules/DOM/Screen.js +0 -80
  276. package/modules/DOM/Screen.js.map +0 -1
  277. package/modules/DOM/WaitForStylesToLoad.js.map +0 -1
  278. package/modules/RestoreScroll.js +0 -111
  279. package/modules/RestoreScroll.js.map +0 -1
  280. package/react/index.commonjs.js +0 -4
  281. package/source/DOM/RenderingEngine.js +0 -22
  282. package/source/DOM/Screen.js +0 -51
  283. package/source/RestoreScroll.js +0 -86
@@ -1,646 +1,209 @@
1
+ var _excluded = ["as", "items", "itemComponent", "itemComponentProps", "estimatedItemHeight", "bypass", "tbody", "preserveScrollPosition", "preserveScrollPositionOnPrependItems", "measureItemsBatchSize", "scrollableContainer", "getScrollableContainer", "getColumnsCount", "getItemId", "className", "onMount", "onItemFirstRender", "onItemInitialRender", "initialScrollPosition", "onScrollPositionChange", "onStateChange", "initialState"];
2
+
1
3
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
4
 
3
5
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
4
6
 
5
7
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
6
8
 
7
- function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
8
-
9
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
10
-
11
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
12
-
13
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
14
-
15
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
16
-
17
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
18
-
19
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
20
-
21
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
22
-
23
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
24
-
25
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
26
-
27
- import React from 'react';
9
+ import { useRef, useMemo, useLayoutEffect } from 'react';
28
10
  import PropTypes from 'prop-types';
29
- import VirtualScrollerCore from '../VirtualScroller';
30
- import { reportError } from '../utility/debug';
31
- import px from '../utility/px'; // `PropTypes.elementType` is available in some version of `prop-types`.
32
- // https://github.com/facebook/prop-types/issues/200
33
-
34
- var elementType = PropTypes.elementType || PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.object]);
35
-
36
- var VirtualScroller =
37
- /*#__PURE__*/
38
- function (_React$Component) {
39
- _inherits(VirtualScroller, _React$Component);
40
-
41
- // Handler function caches.
42
- // Just so that the props passed to `itemComponent`
43
- // are not changed on every `.render()` and so
44
- // `itemComponent` won't re-render if it's a `PureComponent`.
45
- // Item refs for `.renderItem(i)`.
46
- // List items are rendered with `key`s
47
- // so that React doesn't reuse `itemComponent`s
48
- // in cases when `items` are changed.
49
- function VirtualScroller(props) {
50
- var _this;
51
-
52
- _classCallCheck(this, VirtualScroller);
53
-
54
- _this = _possibleConstructorReturn(this, _getPrototypeOf(VirtualScroller).call(this, props)); // `this.previousItemsProperty` is only used for comparing
55
- // `previousItems` with `newItems` inside `render()`.
56
-
57
- _defineProperty(_assertThisInitialized(_this), "container", React.createRef());
58
-
59
- _defineProperty(_assertThisInitialized(_this), "onItemStateChange", new Array(_this.props.items.length));
60
-
61
- _defineProperty(_assertThisInitialized(_this), "onItemHeightChange", new Array(_this.props.items.length));
62
-
63
- _defineProperty(_assertThisInitialized(_this), "itemRefs", new Array(_this.props.items.length));
64
-
65
- _defineProperty(_assertThisInitialized(_this), "itemKeyPrefixes", []);
66
-
67
- _defineProperty(_assertThisInitialized(_this), "updateLayout", function () {
68
- return _this.virtualScroller.updateLayout();
69
- });
70
-
71
- _defineProperty(_assertThisInitialized(_this), "layout", function () {
72
- return _this.updateLayout();
73
- });
74
-
75
- _defineProperty(_assertThisInitialized(_this), "onItemInitialRender", function () {
76
- var onItemInitialRender = _this.props.onItemInitialRender;
77
-
78
- if (onItemInitialRender) {
79
- onItemInitialRender.apply(void 0, arguments);
80
- }
81
- });
82
-
83
- _defineProperty(_assertThisInitialized(_this), "onItemFirstRender", function () {
84
- var onItemFirstRender = _this.props.onItemFirstRender;
85
-
86
- if (onItemFirstRender) {
87
- onItemFirstRender.apply(void 0, arguments);
88
- }
89
- });
90
-
91
- _this.previousItemsProperty = props.items; // Generate unique `key` prefix for list item components.
92
-
93
- _this.generateItemKeyPrefix(); // Create `VirtualScroller` instance.
94
-
95
-
96
- _this.createVirtualScroller();
97
-
98
- return _this;
99
- }
100
-
101
- _createClass(VirtualScroller, [{
102
- key: "createVirtualScroller",
103
- value: function createVirtualScroller() {
104
- var _this2 = this;
105
-
106
- var _this$props = this.props,
107
- AsComponent = _this$props.as,
108
- items = _this$props.items,
109
- initialState = _this$props.initialState,
110
- initialCustomState = _this$props.initialCustomState,
111
- onStateChange = _this$props.onStateChange,
112
- estimatedItemHeight = _this$props.estimatedItemHeight,
113
- preserveScrollPositionOfTheBottomOfTheListOnMount = _this$props.preserveScrollPositionOfTheBottomOfTheListOnMount,
114
- preserveScrollPositionAtBottomOnMount = _this$props.preserveScrollPositionAtBottomOnMount,
115
- initialScrollPosition = _this$props.initialScrollPosition,
116
- onScrollPositionChange = _this$props.onScrollPositionChange,
117
- measureItemsBatchSize = _this$props.measureItemsBatchSize,
118
- scrollableContainer = _this$props.scrollableContainer,
119
- getScrollableContainer = _this$props.getScrollableContainer,
120
- getColumnsCount = _this$props.getColumnsCount,
121
- getItemId = _this$props.getItemId,
122
- bypass = _this$props.bypass; // Create `virtual-scroller` instance.
123
-
124
- this.virtualScroller = new VirtualScrollerCore(function () {
125
- return _this2.container.current;
126
- }, items, {
127
- _useTimeoutInRenderLoop: true,
128
- estimatedItemHeight: estimatedItemHeight,
129
- bypass: bypass,
130
- // bypassBatchSize,
131
- onItemInitialRender: this.onItemInitialRender,
132
- // `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.
133
- onItemFirstRender: this.onItemFirstRender,
134
- preserveScrollPositionOfTheBottomOfTheListOnMount: preserveScrollPositionOfTheBottomOfTheListOnMount,
135
- // `preserveScrollPositionAtBottomOnMount` property name is deprecated,
136
- // use `preserveScrollPositionOfTheBottomOfTheListOnMount` property instead.
137
- preserveScrollPositionAtBottomOnMount: preserveScrollPositionAtBottomOnMount,
138
- initialScrollPosition: initialScrollPosition,
139
- onScrollPositionChange: onScrollPositionChange,
140
- shouldUpdateLayoutOnScreenResize: this.shouldUpdateLayoutOnScreenResize,
141
- measureItemsBatchSize: measureItemsBatchSize,
142
- scrollableContainer: scrollableContainer,
143
- // `getScrollableContainer` property is deprecated.
144
- // Use `scrollableContainer` instead.
145
- getScrollableContainer: getScrollableContainer,
146
- getColumnsCount: getColumnsCount,
147
- getItemId: getItemId,
148
- tbody: AsComponent === 'tbody',
149
- state: initialState,
150
- customState: initialCustomState,
151
- onStateChange: onStateChange,
152
- getState: function getState() {
153
- return _this2.state;
154
- },
155
- setState: function setState(newState, _ref) {
156
- var willUpdateState = _ref.willUpdateState,
157
- didUpdateState = _ref.didUpdateState;
158
- _this2.willUpdateState = willUpdateState;
159
- _this2.didUpdateState = didUpdateState;
160
-
161
- if (_this2.state) {
162
- // Update existing state.
163
- //
164
- // In case of hypothetically rewriting this in React hooks,
165
- // it wouldn't simply be `setState({ ...prevState, ...newState })`.
166
- // The reason is that `setState()` would be "asynchronous" (not immediate),
167
- // and `...prevState` would be stale in cases when more than a single
168
- // `setState()` call is made before the state actually updates,
169
- // making `prevState` stale, and, as a consequence, losing some
170
- // of the state updates.
171
- // For example, the first `setState()` call updates shown item indexes,
172
- // and the second `setState()` call updates `verticalSpacing`:
173
- // if it was simply `setState({ ...prevState, ...newState })`,
174
- // then the second state update could overwrite the first state update,
175
- // resulting in incorrect items being shown/hidden.
176
- //
177
- // I guess, in hooks, it could be something like:
178
- //
179
- // const [firstShownItemIndex, setFirstShownItemIndex] = useState()
180
- // ...
181
- // const setState = useCallback((newState) => {
182
- // for (const key in newState) {
183
- // switch (key) {
184
- // case 'firstShownItemIndex':
185
- // setFirstShownItemIndex(newState[key])
186
- // break
187
- // ...
188
- // }
189
- // }
190
- // setFirstShownItemIndex
191
- // }, [])
192
- // const virtualScroller = new VirtualScrollerCore({
193
- // setState,
194
- // ...
195
- // })
196
- // // `getState()` function would be updated on every render.
197
- // virtualScroller.getState = () => ({
198
- // firstShownItemIndex,
199
- // ...
200
- // })
201
- //
202
- // But as long as it uses the classic `this.setState()`,
203
- // it's fine and simple.
204
- _this2.setState(newState);
205
- } else {
206
- // Set initial state.
207
- willUpdateState(newState);
208
- _this2.state = newState;
209
- didUpdateState();
210
- }
211
- }
212
- });
213
- } // This is a proxy for `VirtualScroller`'s `.updateLayout` instance method.
214
-
215
- }, {
216
- key: "shouldUseRefs",
217
- value: function shouldUseRefs() {
218
- // There's no way to detect if `ref` can be passed to `component`:
219
- // https://github.com/facebook/react/issues/16309
220
- // So it only uses `ref`s for `React.Component`s.
221
- var itemComponent = this.props.itemComponent;
222
- return isComponentClass(itemComponent);
223
- }
224
- /**
225
- * Returns a `key` for an `item`'s element.
226
- * @param {object} item — The item.
227
- * @param {number} i — Item's index in `items` list.
228
- * @return {any}
229
- */
230
-
11
+ import useState from './useState.js';
12
+ import useVirtualScroller from './useVirtualScroller.js';
13
+ import useVirtualScrollerStartStop from './useVirtualScrollerStartStop.js';
14
+ import useInstanceMethods from './useInstanceMethods.js';
15
+ import useItemKeys from './useItemKeys.js';
16
+ import useOnItemStateChange from './useOnItemStateChange.js';
17
+ import useOnItemHeightChange from './useOnItemHeightChange.js';
18
+ import useHandleItemsChange from './useHandleItemsChange.js';
19
+ import useClassName from './useClassName.js';
20
+ import useStyle from './useStyle.js';
21
+
22
+ function VirtualScroller(_ref, ref) {
23
+ var AsComponent = _ref.as,
24
+ items = _ref.items,
25
+ Component = _ref.itemComponent,
26
+ itemComponentProps = _ref.itemComponentProps,
27
+ estimatedItemHeight = _ref.estimatedItemHeight,
28
+ bypass = _ref.bypass,
29
+ tbody = _ref.tbody,
30
+ preserveScrollPosition = _ref.preserveScrollPosition,
31
+ preserveScrollPositionOnPrependItems = _ref.preserveScrollPositionOnPrependItems,
32
+ measureItemsBatchSize = _ref.measureItemsBatchSize,
33
+ scrollableContainer = _ref.scrollableContainer,
34
+ getScrollableContainer = _ref.getScrollableContainer,
35
+ getColumnsCount = _ref.getColumnsCount,
36
+ getItemId = _ref.getItemId,
37
+ className = _ref.className,
38
+ onMount = _ref.onMount,
39
+ onItemFirstRender = _ref.onItemFirstRender,
40
+ onItemInitialRender = _ref.onItemInitialRender,
41
+ initialScrollPosition = _ref.initialScrollPosition,
42
+ onScrollPositionChange = _ref.onScrollPositionChange,
43
+ onStateChange = _ref.onStateChange,
44
+ initialState = _ref.initialState,
45
+ rest = _objectWithoutProperties(_ref, _excluded);
46
+
47
+ // List items "container" DOM Element reference.
48
+ var container = useRef(); // Create a `VirtualScroller` instance.
49
+
50
+ var virtualScroller = useVirtualScroller({
51
+ items: items,
52
+ estimatedItemHeight: estimatedItemHeight,
53
+ bypass: bypass,
54
+ // bypassBatchSize,
55
+ tbody: tbody,
56
+ onItemInitialRender: onItemInitialRender,
57
+ // `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.
58
+ onItemFirstRender: onItemFirstRender,
59
+ initialScrollPosition: initialScrollPosition,
60
+ onScrollPositionChange: onScrollPositionChange,
61
+ measureItemsBatchSize: measureItemsBatchSize,
62
+ // `scrollableContainer` property is deprecated.
63
+ // Use `getScrollableContainer()` property instead.
64
+ scrollableContainer: scrollableContainer,
65
+ getScrollableContainer: getScrollableContainer,
66
+ getColumnsCount: getColumnsCount,
67
+ getItemId: getItemId,
68
+ AsComponent: AsComponent,
69
+ initialState: initialState,
70
+ onStateChange: onStateChange
231
71
  }, {
232
- key: "getItemKey",
233
- value: function getItemKey(item, i) {
234
- var getItemId = this.props.getItemId;
72
+ container: container
73
+ }); // Only compute the initial state once.
235
74
 
236
- if (getItemId) {
237
- return getItemId(item);
238
- }
75
+ var _initialState = useMemo(function () {
76
+ return virtualScroller.getInitialState();
77
+ }, []); // Create state management functions.
239
78
 
240
- return "".concat(this.itemKeyPrefix, ":").concat(i);
241
- }
242
- /**
243
- * A proxy to `VirtualScroller.getItemCoordinates(i)`.
244
- * @param {number} i
245
- * @return {object}
246
- */
247
-
248
- /*
249
- getItemCoordinates(i) {
250
- return this.virtualScroller.getItemCoordinates(i)
251
- }
252
- */
253
-
254
- /**
255
- * `updateItem(i)` has been renamed to `renderItem(i)`.
256
- * @param {number} i
257
- */
258
-
259
- }, {
260
- key: "updateItem",
261
- value: function updateItem(i) {
262
- return this.renderItem(i);
263
- }
264
- /**
265
- * Re-renders an item.
266
- * @param {number} i
267
- */
268
-
269
- }, {
270
- key: "renderItem",
271
- value: function renderItem(i) {
272
- var _this3 = this;
273
-
274
- i = this.getItemIndex(i);
275
-
276
- if (i === undefined) {
277
- return reportError("Item ".concat(JSON.stringify(i), " not found when calling \".renderItem()\""));
278
- }
279
-
280
- if (this.shouldUseRefs()) {
281
- // The item may be non-rendered when `.renderItem(i)` is called on it.
282
- // For example, when there's a "parent comment" having several "replies"
283
- // each of which has an autogenerated quote of the "parent comment"
284
- // and then the "parent comment" is updated (for example, a YouTube video
285
- // link gets parsed into an embedded video player) and all of its "replies"
286
- // should be updated too to show the parsed video title instead of the URL,
287
- // so `.renderItem(i)` is simply called on all of the "parent post"'s replies
288
- // regardless of some of those replies being rendered or not.
289
- if (this.itemRefs[i] && this.itemRefs[i].current) {
290
- var items = this.props.items; // Stores `item` here because the `i` index
291
- // might have changed when the callback is called,
292
- // or the item even may have been removed.
293
-
294
- var item = items[i];
295
- this.itemRefs[i].current.forceUpdate(function () {
296
- if (_this3._isMounted) {
297
- // Recalculates the `i` index here because it
298
- // might have changed when the callback is called,
299
- // or the item even may have been removed.
300
- var _i = items.indexOf(item);
301
-
302
- if (_i >= 0) {
303
- _this3.virtualScroller.onItemHeightChange(_i);
304
- }
305
- }
306
- });
307
- }
308
- }
309
- }
310
- }, {
311
- key: "getItemIndex",
312
- value: function getItemIndex(i) {
313
- if (typeof i === 'number') {
314
- return i;
315
- }
316
79
 
317
- if (_typeof(i) === 'object' && i !== null) {
318
- var _this$props2 = this.props,
319
- items = _this$props2.items,
320
- getItemId = _this$props2.getItemId;
321
- var item = i;
322
- i = 0;
80
+ var _useState = useState({
81
+ initialState: _initialState,
82
+ onRender: virtualScroller.onRender,
83
+ items: items
84
+ }),
85
+ getState = _useState.getState,
86
+ updateState = _useState.updateState; // Use custom (external) state storage in the `VirtualScroller`.
323
87
 
324
- while (i < items.length) {
325
- if (getItemId) {
326
- if (getItemId(item) === getItemId(items[i])) {
327
- return i;
328
- }
329
- } else {
330
- if (item === items[i]) {
331
- return i;
332
- }
333
- }
334
88
 
335
- i++;
336
- }
337
- }
338
- } // Functional components can't have a `ref` assigned to them.
339
- // Item `ref`s are only used for calling `.renderItem(i)` instance method,
340
- // because `.renderItem(i)` calls `.forceUpdate()` on item `i`.
341
- // If a developer is not using the `.renderItem(i)` instance method
342
- // then `ref`s aren't required and will be omitted.
343
-
344
- }, {
345
- key: "getItemRef",
346
- value: function getItemRef(i) {
347
- if (!this.itemRefs[i]) {
348
- this.itemRefs[i] = React.createRef();
349
- }
350
-
351
- return this.itemRefs[i];
352
- }
353
- }, {
354
- key: "getOnItemStateChange",
355
- value: function getOnItemStateChange(i) {
356
- var _this4 = this;
357
-
358
- if (!this.onItemStateChange[i]) {
359
- this.onItemStateChange[i] = function (itemState) {
360
- return _this4.virtualScroller.onItemStateChange(i, itemState);
361
- };
362
- }
363
-
364
- return this.onItemStateChange[i];
365
- }
366
- }, {
367
- key: "getOnItemHeightChange",
368
- value: function getOnItemHeightChange(i) {
369
- var _this5 = this;
370
-
371
- if (!this.onItemHeightChange[i]) {
372
- this.onItemHeightChange[i] = function () {
373
- return _this5.virtualScroller.onItemHeightChange(i);
374
- };
375
- }
376
-
377
- return this.onItemHeightChange[i];
378
- }
379
- }, {
380
- key: "generateItemKeyPrefix",
381
- value: function generateItemKeyPrefix() {
382
- var prefix = String(Math.random()).slice(2);
383
-
384
- if (this.itemKeyPrefixes.indexOf(prefix) >= 0) {
385
- return this.generateItemKeyPrefix();
386
- }
387
-
388
- this.itemKeyPrefixes.push(prefix);
389
- this.itemKeyPrefix = prefix;
390
- }
391
- }, {
392
- key: "componentDidMount",
393
- value: function componentDidMount() {
394
- var onMount = this.props.onMount; // `onMount()` option is deprecated due to no longer being used.
395
- // If someone thinks there's a valid use case for it, create an issue.
396
-
397
- if (onMount) {
398
- onMount();
399
- }
400
-
401
- this._isMounted = true; // Start listening to scroll events.
402
-
403
- this.virtualScroller.listen();
404
- } // `getSnapshotBeforeUpdate()` is called right before `componentDidUpdate()`.
405
-
406
- }, {
407
- key: "getSnapshotBeforeUpdate",
408
- value: function getSnapshotBeforeUpdate(prevProps, prevState) {
409
- if (this.state !== prevState) {
410
- this.willUpdateState(this.state, prevState);
411
- } // Returns `null` to avoid React warning:
412
- // "A snapshot value (or null) must be returned. You have returned undefined".
413
-
414
-
415
- return null;
416
- } // `componentDidUpdate()` is called immediately after React component has re-rendered.
417
- // That would correspond to `useLayoutEffect()` in React Hooks.
418
-
419
- }, {
420
- key: "componentDidUpdate",
421
- value: function componentDidUpdate(prevProps, prevState) {
422
- // If `state` did change.
423
- if (this.state !== prevState) {
424
- this.didUpdateState(prevState);
425
- } // If `items` property did change then update `virtual-scroller` items.
426
- // This could have been done in `.render()` but `.setItems()` calls
427
- // `.setState()` internally which would result in React throwing an error.
428
-
429
-
430
- var _this$props3 = this.props,
431
- items = _this$props3.items,
432
- preserveScrollPosition = _this$props3.preserveScrollPosition,
433
- preserveScrollPositionOnPrependItems = _this$props3.preserveScrollPositionOnPrependItems;
434
-
435
- if (items !== prevProps.items) {
436
- this.virtualScroller.setItems(items, {
437
- // `preserveScrollPosition` property name is deprecated,
438
- // use `preserveScrollPositionOnPrependItems` instead.
439
- preserveScrollPositionOnPrependItems: preserveScrollPositionOnPrependItems || preserveScrollPosition
440
- });
441
- }
442
- }
443
- }, {
444
- key: "componentWillUnmount",
445
- value: function componentWillUnmount() {
446
- this._isMounted = false; // Stop listening to scroll events.
447
-
448
- this.virtualScroller.stop();
89
+ useMemo(function () {
90
+ virtualScroller.useState({
91
+ getState: getState,
92
+ updateState: updateState
93
+ });
94
+ }, []); // Start `VirtualScroller` on mount.
95
+ // Stop `VirtualScroller` on unmount.
96
+
97
+ useVirtualScrollerStartStop(virtualScroller); // List items are rendered with `key`s so that React doesn't
98
+ // "reuse" `itemComponent`s in cases when `items` are changed.
99
+
100
+ var _useItemKeys = useItemKeys({
101
+ getItemId: getItemId
102
+ }),
103
+ getItemKey = _useItemKeys.getItemKey,
104
+ updateItemKeysForNewItems = _useItemKeys.updateItemKeysForNewItems; // Cache per-item `onItemStateChange` functions' "references"
105
+ // so that item components don't get re-rendered needlessly.
106
+
107
+
108
+ var getOnItemStateChange = useOnItemStateChange({
109
+ items: items,
110
+ virtualScroller: virtualScroller
111
+ }); // Cache per-item `onItemHeightChange` functions' "references"
112
+ // so that item components don't get re-rendered needlessly.
113
+
114
+ var getOnItemHeightChange = useOnItemHeightChange({
115
+ items: items,
116
+ virtualScroller: virtualScroller
117
+ }); // Detect if `items` have changed.
118
+
119
+ useHandleItemsChange(items, {
120
+ virtualScroller: virtualScroller,
121
+ // `preserveScrollPosition` property name is deprecated,
122
+ // use `preserveScrollPositionOnPrependItems` property instead.
123
+ preserveScrollPosition: preserveScrollPosition,
124
+ preserveScrollPositionOnPrependItems: preserveScrollPositionOnPrependItems,
125
+ updateItemKeysForNewItems: updateItemKeysForNewItems
126
+ }); // Add instance methods to the React component.
127
+
128
+ useInstanceMethods(ref, {
129
+ virtualScroller: virtualScroller
130
+ });
131
+ useLayoutEffect(function () {
132
+ // (deprecated)
133
+ // `onMount()` option is deprecated due to no longer being used.
134
+ // If someone thinks there's a valid use case for it, create an issue.
135
+ if (onMount) {
136
+ onMount();
449
137
  }
450
- }, {
451
- key: "render",
452
- value: function render() {
453
- var _this6 = this;
454
-
455
- var _this$props4 = this.props,
456
- AsComponent = _this$props4.as,
457
- Component = _this$props4.itemComponent,
458
- itemComponentProps = _this$props4.itemComponentProps,
459
- _items = _this$props4.items,
460
- estimatedItemHeight = _this$props4.estimatedItemHeight,
461
- bypass = _this$props4.bypass,
462
- preserveScrollPositionOnPrependItems = _this$props4.preserveScrollPositionOnPrependItems,
463
- preserveScrollPosition = _this$props4.preserveScrollPosition,
464
- preserveScrollPositionOfTheBottomOfTheListOnMount = _this$props4.preserveScrollPositionOfTheBottomOfTheListOnMount,
465
- preserveScrollPositionAtBottomOnMount = _this$props4.preserveScrollPositionAtBottomOnMount,
466
- initialScrollPosition = _this$props4.initialScrollPosition,
467
- onScrollPositionChange = _this$props4.onScrollPositionChange,
468
- measureItemsBatchSize = _this$props4.measureItemsBatchSize,
469
- scrollableContainer = _this$props4.scrollableContainer,
470
- getScrollableContainer = _this$props4.getScrollableContainer,
471
- getColumnsCount = _this$props4.getColumnsCount,
472
- initialState = _this$props4.initialState,
473
- initialCustomState = _this$props4.initialCustomState,
474
- onStateChange = _this$props4.onStateChange,
475
- onItemInitialRender = _this$props4.onItemInitialRender,
476
- onItemFirstRender = _this$props4.onItemFirstRender,
477
- getItemId = _this$props4.getItemId,
478
- onMount = _this$props4.onMount,
479
- className = _this$props4.className,
480
- rest = _objectWithoutProperties(_this$props4, ["as", "itemComponent", "itemComponentProps", "items", "estimatedItemHeight", "bypass", "preserveScrollPositionOnPrependItems", "preserveScrollPosition", "preserveScrollPositionOfTheBottomOfTheListOnMount", "preserveScrollPositionAtBottomOnMount", "initialScrollPosition", "onScrollPositionChange", "measureItemsBatchSize", "scrollableContainer", "getScrollableContainer", "getColumnsCount", "initialState", "initialCustomState", "onStateChange", "onItemInitialRender", "onItemFirstRender", "getItemId", "onMount", "className"]);
481
-
482
- var _this$virtualScroller = this.virtualScroller.getState(),
483
- items = _this$virtualScroller.items,
484
- itemStates = _this$virtualScroller.itemStates,
485
- firstShownItemIndex = _this$virtualScroller.firstShownItemIndex,
486
- lastShownItemIndex = _this$virtualScroller.lastShownItemIndex,
487
- beforeItemsHeight = _this$virtualScroller.beforeItemsHeight,
488
- afterItemsHeight = _this$virtualScroller.afterItemsHeight; // If `items` are about to be changed then
489
- // store the scroll Y position for the first one
490
- // of the current items.
491
- // Previously it was being done in `componentDidUpdate()`
492
- // but it was later found out that it wouldn't work
493
- // for "Show previous" button because it would
494
- // get hidden before `componentDidUpdate()` is called.
495
- //
496
- // Consider this code example:
497
- //
498
- // const { fromIndex, items } = this.state
499
- // const items = allItems.slice(fromIndex)
500
- // return (
501
- // {fromIndex > 0 &&
502
- // <button onClick={this.onShowPrevious}>
503
- // Show previous
504
- // </button>
505
- // }
506
- // <VirtualScroller
507
- // items={items}
508
- // itemComponent={ItemComponent}/>
509
- // )
510
- //
511
- // Consider a user clicks "Show previous" to show the items from the start.
512
- // By the time `componentDidUpdate()` is called on `<VirtualScroller/>`,
513
- // the "Show previous" button has already been hidden
514
- // (because there're no more "previous" items)
515
- // which results in the scroll Y position jumping forward
516
- // by the height of that "Show previous" button.
517
- // This is because `<VirtualScroller/>` captures scroll Y
518
- // position when items are prepended via `.setItems()`
519
- // when the "Show previous" button is still being shown,
520
- // and then restores scroll Y position in `.didUpdateState()`
521
- // when the "Show previous" button has already been hidden:
522
- // that's the reason for the scroll Y "jump".
523
- //
524
- // To prevent that, scroll Y position is captured at `render()`
525
- // time rather than later in `componentDidUpdate()`: this way,
526
- // scroll Y position is captured while the "Show previous" button
527
- // is still being shown.
528
- //
529
-
530
-
531
- var newItems = this.props.items;
532
- var previousItems = items; // this.virtualScroller.getState().items
533
- // There's one case when `newItems !== previousItems` is `true`
534
- // from the start: when `initialState.items` are passed.
535
- // To handle that single case `this.previousItemsProperty`
536
- // is tracked and `this.itemsPropertyHasChanged` flag is set.
537
-
538
- if (!this.itemsPropertyWasChanged) {
539
- this.itemsPropertyWasChanged = this.props.items !== this.previousItemsProperty;
540
- }
541
-
542
- this.previousItemsProperty = this.props.items;
543
-
544
- if (this.itemsPropertyWasChanged && newItems !== previousItems) {
545
- var itemsDiff = this.virtualScroller.getItemsDiff(previousItems, newItems);
546
-
547
- if (itemsDiff && itemsDiff.prependedItemsCount === 0 && itemsDiff.appendedItemsCount > 0) {// If it's just items that have been appended
548
- // then no need to re-generate the prefix
549
- // and to fix scroll position and to clear caches.
550
- } else {
551
- // If the items update was incremental, then it's possible
552
- // that some items were prepended, and so the scroll Y position
553
- // should be restored after rendering those new items
554
- // in order for the currently shown items to stay
555
- // on the same position on screen.
556
- // (only if explicitly opted into using this feature)
557
- //
558
- // If the items update wasn't incremental
559
- // then there's no point in restoring scroll position.
560
- //
561
- // `preserveScrollPosition` property name is deprecated,
562
- // use `preserveScrollPositionOnPrependItems` instead.
563
- //
564
- if (itemsDiff) {
565
- var prependedItemsCount = itemsDiff.prependedItemsCount;
566
-
567
- if (prependedItemsCount > 0) {
568
- if (preserveScrollPositionOnPrependItems || preserveScrollPosition) {
569
- if (firstShownItemIndex === 0) {
570
- this.virtualScroller.restoreScroll.captureScroll({
571
- previousItems: previousItems,
572
- newItems: newItems,
573
- prependedItemsCount: prependedItemsCount
574
- });
575
- }
576
- }
577
- }
578
- } // Reset the unique `key` prefix for item component keys.
579
-
580
-
581
- if (!getItemId) {
582
- this.generateItemKeyPrefix();
583
- } // Reset item refs.
584
-
585
-
586
- this.itemRefs = new Array(newItems.length);
587
- }
588
- }
589
-
590
- var tbody = this.virtualScroller.tbody;
591
- return React.createElement(AsComponent, _extends({}, rest, {
592
- ref: this.container,
593
- className: tbody ? className ? className + ' ' + 'VirtualScroller' : 'VirtualScroller' : className,
594
- style: {
595
- paddingTop: tbody ? undefined : px(beforeItemsHeight),
596
- paddingBottom: tbody ? undefined : px(afterItemsHeight)
597
- }
598
- }), items.map(function (item, i) {
599
- if (i >= firstShownItemIndex && i <= lastShownItemIndex) {
600
- return React.createElement(Component, _extends({}, itemComponentProps, {
601
- key: _this6.getItemKey(item, i),
602
- ref: _this6.shouldUseRefs() ? _this6.getItemRef(i) : undefined,
603
- state: itemStates && itemStates[i],
604
- onStateChange: _this6.getOnItemStateChange(i),
605
- onHeightChange: _this6.getOnItemHeightChange(i)
606
- }), item);
607
- }
138
+ }, []); // `willRender()` function is no longer used.
139
+ //
140
+ // // `getSnapshotBeforeUpdate()` is called right before `componentDidUpdate()`.
141
+ // // A hook equivalent/workaround for `getSnapshotBeforeUpdate()`:
142
+ // // https://github.com/facebook/react/issues/15221#issuecomment-583448887
143
+ // //
144
+ // getSnapshotBeforeUpdate(prevProps, prevState) {
145
+ // if (this.state !== prevState) {
146
+ // this.willRender(this.state, prevState)
147
+ // }
148
+ // // Returns `null` to avoid React warning:
149
+ // // "A snapshot value (or null) must be returned. You have returned undefined".
150
+ // return null
151
+ // }
608
152
 
609
- return null;
610
- }));
153
+ className = useClassName(className, {
154
+ tbody: tbody
155
+ });
156
+ var style = useStyle({
157
+ tbody: tbody,
158
+ virtualScroller: virtualScroller
159
+ });
160
+
161
+ var _virtualScroller$getS = virtualScroller.getState(),
162
+ renderedItems = _virtualScroller$getS.items,
163
+ itemStates = _virtualScroller$getS.itemStates,
164
+ firstShownItemIndex = _virtualScroller$getS.firstShownItemIndex,
165
+ lastShownItemIndex = _virtualScroller$getS.lastShownItemIndex;
166
+
167
+ return /*#__PURE__*/React.createElement(AsComponent, _extends({}, rest, {
168
+ ref: container,
169
+ className: className,
170
+ style: style
171
+ }), renderedItems.map(function (item, i) {
172
+ if (i >= firstShownItemIndex && i <= lastShownItemIndex) {
173
+ return /*#__PURE__*/React.createElement(Component, _extends({}, itemComponentProps, {
174
+ key: getItemKey(item, i),
175
+ state: itemStates && itemStates[i],
176
+ onStateChange: getOnItemStateChange(i),
177
+ onHeightChange: getOnItemHeightChange(i)
178
+ }), item);
611
179
  }
612
- }]);
613
180
 
614
- return VirtualScroller;
615
- }(React.Component);
616
- /**
617
- * Checks if the argument is a `React.Component` class.
618
- * https://overreacted.io/how-does-react-tell-a-class-from-a-function/
619
- * @param {any} Component
620
- * @return {object} [result] Returns `undefined` if it's not a `React.Component`. Returns an empty object if it's a `React.Component` (`.isReactComponent` is an empty object).
621
- */
181
+ return null;
182
+ }));
183
+ }
622
184
 
185
+ VirtualScroller = React.forwardRef(VirtualScroller);
186
+ export default VirtualScroller; // `PropTypes.elementType` is available in some version of `prop-types`.
187
+ // https://github.com/facebook/prop-types/issues/200
623
188
 
624
- _defineProperty(VirtualScroller, "propTypes", {
189
+ var elementType = PropTypes.elementType || PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.object]);
190
+ VirtualScroller.propTypes = {
625
191
  as: elementType,
626
- items: PropTypes.arrayOf(PropTypes.object).isRequired,
192
+ items: PropTypes.arrayOf(PropTypes.any).isRequired,
627
193
  itemComponent: elementType.isRequired,
628
194
  itemComponentProps: PropTypes.object,
629
195
  estimatedItemHeight: PropTypes.number,
630
196
  bypass: PropTypes.bool,
631
197
  // bypassBatchSize: PropTypes.number,
198
+ tbody: PropTypes.bool,
632
199
  preserveScrollPositionOnPrependItems: PropTypes.bool,
633
200
  // `preserveScrollPosition` property name is deprecated,
634
201
  // use `preserveScrollPositionOnPrependItems` instead.
635
202
  preserveScrollPosition: PropTypes.bool,
636
- preserveScrollPositionOfTheBottomOfTheListOnMount: PropTypes.bool,
637
- // `preserveScrollPositionAtBottomOnMount` property name is deprecated,
638
- // use `preserveScrollPositionOfTheBottomOfTheListOnMount` property instead.
639
- preserveScrollPositionAtBottomOnMount: PropTypes.bool,
640
203
  measureItemsBatchSize: PropTypes.number,
204
+ // `scrollableContainer` property is deprecated.
205
+ // Use `getScrollableContainer()` property instead.
641
206
  scrollableContainer: PropTypes.any,
642
- // `getScrollableContainer` property is deprecated.
643
- // Use `scrollableContainer` instead.
644
207
  getScrollableContainer: PropTypes.func,
645
208
  getColumnsCount: PropTypes.func,
646
209
  getItemId: PropTypes.func,
@@ -652,7 +215,6 @@ _defineProperty(VirtualScroller, "propTypes", {
652
215
  initialScrollPosition: PropTypes.number,
653
216
  onScrollPositionChange: PropTypes.func,
654
217
  onStateChange: PropTypes.func,
655
- initialCustomState: PropTypes.object,
656
218
  initialState: PropTypes.shape({
657
219
  items: PropTypes.arrayOf(PropTypes.object).isRequired,
658
220
  itemStates: PropTypes.arrayOf(PropTypes.any),
@@ -664,25 +226,8 @@ _defineProperty(VirtualScroller, "propTypes", {
664
226
  columnsCount: PropTypes.number,
665
227
  verticalSpacing: PropTypes.number
666
228
  })
667
- });
668
-
669
- _defineProperty(VirtualScroller, "defaultProps", {
670
- as: 'div' // `this.state` is already reserved for `virtual-scroller`.
671
- // static getDerivedStateFromProps(props, state) {
672
- // return {
673
- // prevProps: {
674
- // items: props.items
675
- // }
676
- // }
677
- // }
678
-
679
- });
680
-
681
- export { VirtualScroller as default };
682
-
683
- function isComponentClass(Component) {
684
- // return Component.prototype instanceof React.Component
685
- // `React.memo()` returns `.prototype === undefined` for some reason.
686
- return Component.prototype && Component.prototype.isReactComponent;
687
- }
229
+ };
230
+ VirtualScroller.defaultProps = {
231
+ as: 'div'
232
+ };
688
233
  //# sourceMappingURL=VirtualScroller.js.map