virtual-scroller 1.8.1 → 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 (247) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/README.md +337 -160
  3. package/bundle/virtual-scroller-dom.js +1 -1
  4. package/bundle/virtual-scroller-dom.js.map +1 -1
  5. package/bundle/virtual-scroller-react.js +1 -1
  6. package/bundle/virtual-scroller-react.js.map +1 -1
  7. package/bundle/virtual-scroller.js +1 -1
  8. package/bundle/virtual-scroller.js.map +1 -1
  9. package/commonjs/BeforeResize.js +23 -27
  10. package/commonjs/BeforeResize.js.map +1 -1
  11. package/commonjs/DOM/Engine.js +7 -7
  12. package/commonjs/DOM/Engine.js.map +1 -1
  13. package/commonjs/DOM/ItemsContainer.js +1 -1
  14. package/commonjs/DOM/ItemsContainer.js.map +1 -1
  15. package/commonjs/DOM/ListTopOffsetWatcher.js +15 -9
  16. package/commonjs/DOM/ListTopOffsetWatcher.js.map +1 -1
  17. package/commonjs/DOM/ScrollableContainer.js +28 -28
  18. package/commonjs/DOM/ScrollableContainer.js.map +1 -1
  19. package/commonjs/DOM/VirtualScroller.js +20 -17
  20. package/commonjs/DOM/VirtualScroller.js.map +1 -1
  21. package/commonjs/DOM/tbody.js +16 -10
  22. package/commonjs/DOM/tbody.js.map +1 -1
  23. package/commonjs/ItemHeights.js +13 -7
  24. package/commonjs/ItemHeights.js.map +1 -1
  25. package/commonjs/Layout.js +15 -13
  26. package/commonjs/Layout.js.map +1 -1
  27. package/commonjs/Layout.test.js +8 -3
  28. package/commonjs/Layout.test.js.map +1 -1
  29. package/commonjs/{ListHeightChangeWatcher.js → ListHeightMeasurement.js} +26 -28
  30. package/commonjs/ListHeightMeasurement.js.map +1 -0
  31. package/commonjs/Resize.js +38 -28
  32. package/commonjs/Resize.js.map +1 -1
  33. package/commonjs/Scroll.js +28 -44
  34. package/commonjs/Scroll.js.map +1 -1
  35. package/commonjs/VirtualScroller.columns.js +43 -0
  36. package/commonjs/VirtualScroller.columns.js.map +1 -0
  37. package/commonjs/VirtualScroller.constructor.js +408 -0
  38. package/commonjs/VirtualScroller.constructor.js.map +1 -0
  39. package/commonjs/VirtualScroller.items.js +305 -0
  40. package/commonjs/VirtualScroller.items.js.map +1 -0
  41. package/commonjs/VirtualScroller.js +132 -1872
  42. package/commonjs/VirtualScroller.js.map +1 -1
  43. package/commonjs/VirtualScroller.layout.js +562 -0
  44. package/commonjs/VirtualScroller.layout.js.map +1 -0
  45. package/commonjs/VirtualScroller.onRender.js +357 -0
  46. package/commonjs/VirtualScroller.onRender.js.map +1 -0
  47. package/commonjs/VirtualScroller.resize.js +186 -0
  48. package/commonjs/VirtualScroller.resize.js.map +1 -0
  49. package/commonjs/VirtualScroller.state.js +301 -0
  50. package/commonjs/VirtualScroller.state.js.map +1 -0
  51. package/commonjs/VirtualScroller.verticalSpacing.js +65 -0
  52. package/commonjs/VirtualScroller.verticalSpacing.js.map +1 -0
  53. package/commonjs/getItemCoordinates.js.map +1 -1
  54. package/commonjs/getItemsDiff.js.map +1 -1
  55. package/commonjs/getVerticalSpacing.js.map +1 -1
  56. package/commonjs/package.json +5 -0
  57. package/commonjs/react/VirtualScroller.js +180 -620
  58. package/commonjs/react/VirtualScroller.js.map +1 -1
  59. package/commonjs/react/useClassName.js +26 -0
  60. package/commonjs/react/useClassName.js.map +1 -0
  61. package/commonjs/react/useHandleItemsChange.js +116 -0
  62. package/commonjs/react/useHandleItemsChange.js.map +1 -0
  63. package/commonjs/react/useInstanceMethods.js +37 -0
  64. package/commonjs/react/useInstanceMethods.js.map +1 -0
  65. package/commonjs/react/useItemKeys.js +60 -0
  66. package/commonjs/react/useItemKeys.js.map +1 -0
  67. package/commonjs/react/useOnItemHeightChange.js +32 -0
  68. package/commonjs/react/useOnItemHeightChange.js.map +1 -0
  69. package/commonjs/react/useOnItemStateChange.js +32 -0
  70. package/commonjs/react/useOnItemStateChange.js.map +1 -0
  71. package/commonjs/react/useState.js +140 -0
  72. package/commonjs/react/useState.js.map +1 -0
  73. package/commonjs/react/useStyle.js +29 -0
  74. package/commonjs/react/useStyle.js.map +1 -0
  75. package/commonjs/react/useVirtualScroller.js +62 -0
  76. package/commonjs/react/useVirtualScroller.js.map +1 -0
  77. package/commonjs/react/useVirtualScrollerStartStop.js +20 -0
  78. package/commonjs/react/useVirtualScrollerStartStop.js.map +1 -0
  79. package/commonjs/test/Engine.js +23 -0
  80. package/commonjs/test/Engine.js.map +1 -0
  81. package/commonjs/test/ItemsContainer.js +127 -0
  82. package/commonjs/test/ItemsContainer.js.map +1 -0
  83. package/commonjs/test/ScrollableContainer.js +130 -0
  84. package/commonjs/test/ScrollableContainer.js.map +1 -0
  85. package/commonjs/test/VirtualScroller.js +281 -0
  86. package/commonjs/test/VirtualScroller.js.map +1 -0
  87. package/commonjs/utility/debounce.js +2 -2
  88. package/commonjs/utility/debounce.js.map +1 -1
  89. package/commonjs/utility/debug.js.map +1 -1
  90. package/commonjs/utility/getStateSnapshot.js +2 -2
  91. package/commonjs/utility/getStateSnapshot.js.map +1 -1
  92. package/commonjs/utility/px.js.map +1 -1
  93. package/commonjs/utility/px.test.js +1 -1
  94. package/commonjs/utility/px.test.js.map +1 -1
  95. package/commonjs/utility/shallowEqual.js +1 -1
  96. package/commonjs/utility/shallowEqual.js.map +1 -1
  97. package/commonjs/utility/throttle.js.map +1 -1
  98. package/dom/index.cjs +4 -0
  99. package/dom/index.cjs.js +9 -0
  100. package/dom/index.d.ts +6 -4
  101. package/dom/index.js +1 -1
  102. package/dom/package.json +10 -4
  103. package/index.cjs +4 -0
  104. package/index.cjs.js +9 -0
  105. package/index.d.ts +30 -15
  106. package/index.js +1 -1
  107. package/modules/BeforeResize.js +22 -27
  108. package/modules/BeforeResize.js.map +1 -1
  109. package/modules/DOM/Engine.js +6 -6
  110. package/modules/DOM/Engine.js.map +1 -1
  111. package/modules/DOM/ItemsContainer.js +1 -1
  112. package/modules/DOM/ItemsContainer.js.map +1 -1
  113. package/modules/DOM/ListTopOffsetWatcher.js +15 -9
  114. package/modules/DOM/ListTopOffsetWatcher.js.map +1 -1
  115. package/modules/DOM/ScrollableContainer.js +28 -28
  116. package/modules/DOM/ScrollableContainer.js.map +1 -1
  117. package/modules/DOM/VirtualScroller.js +19 -16
  118. package/modules/DOM/VirtualScroller.js.map +1 -1
  119. package/modules/DOM/tbody.js +11 -9
  120. package/modules/DOM/tbody.js.map +1 -1
  121. package/modules/ItemHeights.js +12 -6
  122. package/modules/ItemHeights.js.map +1 -1
  123. package/modules/Layout.js +14 -12
  124. package/modules/Layout.js.map +1 -1
  125. package/modules/Layout.test.js +8 -3
  126. package/modules/Layout.test.js.map +1 -1
  127. package/modules/{ListHeightChangeWatcher.js → ListHeightMeasurement.js} +25 -27
  128. package/modules/ListHeightMeasurement.js.map +1 -0
  129. package/modules/Resize.js +38 -28
  130. package/modules/Resize.js.map +1 -1
  131. package/modules/Scroll.js +28 -44
  132. package/modules/Scroll.js.map +1 -1
  133. package/modules/VirtualScroller.columns.js +36 -0
  134. package/modules/VirtualScroller.columns.js.map +1 -0
  135. package/modules/VirtualScroller.constructor.js +371 -0
  136. package/modules/VirtualScroller.constructor.js.map +1 -0
  137. package/modules/VirtualScroller.items.js +288 -0
  138. package/modules/VirtualScroller.items.js.map +1 -0
  139. package/modules/VirtualScroller.js +132 -1860
  140. package/modules/VirtualScroller.js.map +1 -1
  141. package/modules/VirtualScroller.layout.js +549 -0
  142. package/modules/VirtualScroller.layout.js.map +1 -0
  143. package/modules/VirtualScroller.onRender.js +337 -0
  144. package/modules/VirtualScroller.onRender.js.map +1 -0
  145. package/modules/VirtualScroller.resize.js +176 -0
  146. package/modules/VirtualScroller.resize.js.map +1 -0
  147. package/modules/VirtualScroller.state.js +283 -0
  148. package/modules/VirtualScroller.state.js.map +1 -0
  149. package/modules/VirtualScroller.verticalSpacing.js +54 -0
  150. package/modules/VirtualScroller.verticalSpacing.js.map +1 -0
  151. package/modules/getItemCoordinates.js.map +1 -1
  152. package/modules/getItemsDiff.js.map +1 -1
  153. package/modules/getVerticalSpacing.js.map +1 -1
  154. package/modules/react/VirtualScroller.js +176 -625
  155. package/modules/react/VirtualScroller.js.map +1 -1
  156. package/modules/react/useClassName.js +18 -0
  157. package/modules/react/useClassName.js.map +1 -0
  158. package/modules/react/useHandleItemsChange.js +108 -0
  159. package/modules/react/useHandleItemsChange.js.map +1 -0
  160. package/modules/react/useInstanceMethods.js +28 -0
  161. package/modules/react/useInstanceMethods.js.map +1 -0
  162. package/modules/react/useItemKeys.js +52 -0
  163. package/modules/react/useItemKeys.js.map +1 -0
  164. package/modules/react/useOnItemHeightChange.js +24 -0
  165. package/modules/react/useOnItemHeightChange.js.map +1 -0
  166. package/modules/react/useOnItemStateChange.js +24 -0
  167. package/modules/react/useOnItemStateChange.js.map +1 -0
  168. package/modules/react/useState.js +132 -0
  169. package/modules/react/useState.js.map +1 -0
  170. package/modules/react/useStyle.js +19 -0
  171. package/modules/react/useStyle.js.map +1 -0
  172. package/modules/react/useVirtualScroller.js +51 -0
  173. package/modules/react/useVirtualScroller.js.map +1 -0
  174. package/modules/react/useVirtualScrollerStartStop.js +12 -0
  175. package/modules/react/useVirtualScrollerStartStop.js.map +1 -0
  176. package/modules/test/Engine.js +11 -0
  177. package/modules/test/Engine.js.map +1 -0
  178. package/modules/test/ItemsContainer.js +120 -0
  179. package/modules/test/ItemsContainer.js.map +1 -0
  180. package/modules/test/ScrollableContainer.js +123 -0
  181. package/modules/test/ScrollableContainer.js.map +1 -0
  182. package/modules/test/VirtualScroller.js +270 -0
  183. package/modules/test/VirtualScroller.js.map +1 -0
  184. package/modules/utility/debounce.js +2 -2
  185. package/modules/utility/debounce.js.map +1 -1
  186. package/modules/utility/debug.js.map +1 -1
  187. package/modules/utility/getStateSnapshot.js +2 -2
  188. package/modules/utility/getStateSnapshot.js.map +1 -1
  189. package/modules/utility/px.js.map +1 -1
  190. package/modules/utility/px.test.js +1 -1
  191. package/modules/utility/px.test.js.map +1 -1
  192. package/modules/utility/shallowEqual.js +1 -1
  193. package/modules/utility/shallowEqual.js.map +1 -1
  194. package/modules/utility/throttle.js.map +1 -1
  195. package/package.json +46 -23
  196. package/react/index.cjs +4 -0
  197. package/react/index.cjs.js +9 -0
  198. package/react/index.d.ts +10 -9
  199. package/react/index.js +1 -1
  200. package/react/package.json +10 -4
  201. package/rollup.config.mjs +62 -0
  202. package/runnable/create-commonjs-package-json.js +11 -0
  203. package/source/BeforeResize.js +16 -21
  204. package/source/DOM/Engine.js +8 -10
  205. package/source/DOM/ListTopOffsetWatcher.js +13 -8
  206. package/source/DOM/ScrollableContainer.js +23 -21
  207. package/source/DOM/VirtualScroller.js +27 -11
  208. package/source/DOM/tbody.js +30 -21
  209. package/source/ItemHeights.js +9 -4
  210. package/source/Layout.js +12 -9
  211. package/source/Layout.test.js +8 -3
  212. package/source/{ListHeightChangeWatcher.js → ListHeightMeasurement.js} +21 -20
  213. package/source/Resize.js +41 -25
  214. package/source/Scroll.js +27 -35
  215. package/source/VirtualScroller.columns.js +26 -0
  216. package/source/VirtualScroller.constructor.js +336 -0
  217. package/source/VirtualScroller.items.js +302 -0
  218. package/source/VirtualScroller.js +144 -1875
  219. package/source/VirtualScroller.layout.js +539 -0
  220. package/source/VirtualScroller.onRender.js +345 -0
  221. package/source/VirtualScroller.resize.js +189 -0
  222. package/source/VirtualScroller.state.js +284 -0
  223. package/source/VirtualScroller.verticalSpacing.js +51 -0
  224. package/source/react/VirtualScroller.js +243 -587
  225. package/source/react/useClassName.js +14 -0
  226. package/source/react/useHandleItemsChange.js +115 -0
  227. package/source/react/useInstanceMethods.js +25 -0
  228. package/source/react/useItemKeys.js +59 -0
  229. package/source/react/useOnItemHeightChange.js +28 -0
  230. package/source/react/useOnItemStateChange.js +28 -0
  231. package/source/react/useState.js +114 -0
  232. package/source/react/useStyle.js +20 -0
  233. package/source/react/useVirtualScroller.js +59 -0
  234. package/source/react/useVirtualScrollerStartStop.js +12 -0
  235. package/source/test/Engine.js +11 -0
  236. package/source/test/ItemsContainer.js +87 -0
  237. package/source/test/ScrollableContainer.js +88 -0
  238. package/source/test/VirtualScroller.js +232 -0
  239. package/source/utility/debounce.js +2 -2
  240. package/source/utility/px.test.js +1 -1
  241. package/babel.config.js +0 -25
  242. package/babel.js +0 -5
  243. package/commonjs/ListHeightChangeWatcher.js.map +0 -1
  244. package/dom/index.commonjs.js +0 -4
  245. package/index.commonjs.js +0 -4
  246. package/modules/ListHeightChangeWatcher.js.map +0 -1
  247. package/react/index.commonjs.js +0 -4
@@ -0,0 +1,357 @@
1
+ "use strict";
2
+
3
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
4
+
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports["default"] = _default;
9
+
10
+ var _debug = _interopRequireWildcard(require("./utility/debug.js"));
11
+
12
+ var _getStateSnapshot = _interopRequireDefault(require("./utility/getStateSnapshot.js"));
13
+
14
+ var _shallowEqual = _interopRequireDefault(require("./utility/shallowEqual.js"));
15
+
16
+ var _Layout = require("./Layout.js");
17
+
18
+ var _tbody = require("./DOM/tbody.js");
19
+
20
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
21
+
22
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
23
+
24
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
25
+
26
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
27
+
28
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
29
+
30
+ 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; }
31
+
32
+ function _default() {
33
+ var _this = this;
34
+
35
+ /**
36
+ * Should be called right after updates to `state` have been rendered.
37
+ * @param {object} newState
38
+ * @param {object} [prevState]
39
+ */
40
+ this._onRender = function (newState, prevState) {
41
+ (0, _debug["default"])('~ Rendered ~');
42
+
43
+ if ((0, _debug.isDebug)()) {
44
+ (0, _debug["default"])('State', (0, _getStateSnapshot["default"])(newState));
45
+ }
46
+
47
+ if (_this.onStateChange) {
48
+ if (!(0, _shallowEqual["default"])(newState, prevState)) {
49
+ _this.onStateChange(newState);
50
+ }
51
+ } // Update `<tbody/>` `padding`.
52
+ // (`<tbody/>` is different in a way that it can't have `margin`, only `padding`).
53
+ // https://gitlab.com/catamphetamine/virtual-scroller/-/issues/1
54
+
55
+
56
+ if (_this.tbody) {
57
+ (0, _tbody.setTbodyPadding)(_this.getItemsContainerElement(), newState.beforeItemsHeight, newState.afterItemsHeight);
58
+ }
59
+
60
+ if (!prevState) {
61
+ return;
62
+ } // `this.resetStateUpdateFlags()` must be called before calling
63
+ // `this.measureItemHeightsAndSpacing()`.
64
+
65
+
66
+ var _resetStateUpdateFlag = resetStateUpdateFlags.call(_this),
67
+ nonMeasuredItemsHaveBeenRendered = _resetStateUpdateFlag.nonMeasuredItemsHaveBeenRendered,
68
+ widthHasChanged = _resetStateUpdateFlag.widthHasChanged;
69
+
70
+ var layoutUpdateReason; // If the `VirtualScroller`, while calculating layout parameters, encounters
71
+ // a not-shown item with a non-measured height, it calls `updateState()` just to
72
+ // render that item first, and then, after the list has been re-rendered, it measures
73
+ // the item's height and then proceeds with calculating the correct layout parameters.
74
+
75
+ if (nonMeasuredItemsHaveBeenRendered) {
76
+ layoutUpdateReason = _Layout.LAYOUT_REASON.NON_MEASURED_ITEMS_HAVE_BEEN_MEASURED;
77
+ } // If scrollable container width has changed, and it has been re-rendered,
78
+ // then it's time to measure the new item heights and then perform a re-layout
79
+ // with the correctly calculated layout parameters.
80
+ //
81
+ // A re-layout is required because the layout parameters calculated on resize
82
+ // are approximate ones, and the exact item heights aren't known at that point.
83
+ // So on resize, it calls `updateState()` just to re-render the `VirtualScroller`.
84
+ // After it has been re-rendered, it will measure item heights and then calculate
85
+ // correct layout parameters.
86
+ //
87
+
88
+
89
+ if (widthHasChanged) {
90
+ layoutUpdateReason = _Layout.LAYOUT_REASON.VIEWPORT_WIDTH_CHANGED; // Reset measured item heights on viewport width change.
91
+
92
+ _this.itemHeights.reset(); // Reset `verticalSpacing` (will be re-measured).
93
+
94
+
95
+ _this.verticalSpacing = undefined;
96
+ }
97
+
98
+ var previousItems = prevState.items;
99
+ var newItems = newState.items; // Even if `this.newItemsWillBeRendered` flag is `true`,
100
+ // `newItems` could still be equal to `previousItems`.
101
+ // For example, when `updateState()` calls don't update `state` immediately
102
+ // and a developer first calls `setItems(newItems)` and then calls `setItems(oldItems)`:
103
+ // in that case, `this.newItemsWillBeRendered` flag will be `true` but the actual `items`
104
+ // in state wouldn't have changed due to the first `updateState()` call being overwritten
105
+ // by the second `updateState()` call (that's called "batching state updates" in React).
106
+
107
+ if (newItems !== previousItems) {
108
+ var itemsDiff = _this.getItemsDiff(previousItems, newItems);
109
+
110
+ if (itemsDiff) {
111
+ // The call to `.onPrepend()` must precede the call to `.measureItemHeights()`
112
+ // which is called in `.onRender()`.
113
+ // `this.itemHeights.onPrepend()` updates `firstMeasuredItemIndex`
114
+ // and `lastMeasuredItemIndex` of `this.itemHeights`.
115
+ var prependedItemsCount = itemsDiff.prependedItemsCount;
116
+
117
+ _this.itemHeights.onPrepend(prependedItemsCount);
118
+ } else {
119
+ _this.itemHeights.reset();
120
+ }
121
+
122
+ if (!widthHasChanged) {
123
+ // The call to `this.onNewItemsRendered()` must precede the call to
124
+ // `.measureItemHeights()` which is called in `.onRender()` because
125
+ // `this.onNewItemsRendered()` updates `firstMeasuredItemIndex` and
126
+ // `lastMeasuredItemIndex` of `this.itemHeights` in case of a prepend.
127
+ //
128
+ // If after prepending items the scroll position
129
+ // should be "restored" so that there's no "jump" of content
130
+ // then it means that all previous items have just been rendered
131
+ // in a single pass, and there's no need to update layout again.
132
+ //
133
+ if (onNewItemsRendered.call(_this, itemsDiff, newState) !== 'SEAMLESS_PREPEND') {
134
+ layoutUpdateReason = _Layout.LAYOUT_REASON.ITEMS_CHANGED;
135
+ }
136
+ }
137
+ }
138
+
139
+ var stateUpdate; // Re-measure item heights.
140
+ // Also, measure vertical spacing (if not measured) and fix `<table/>` padding.
141
+ //
142
+ // This block should go after `if (newItems !== previousItems) {}`
143
+ // because `this.itemHeights` can get `.reset()` there, which would
144
+ // discard all the measurements done here, and having currently shown
145
+ // item height measurements is required.
146
+ //
147
+
148
+ if (newState.firstShownItemIndex !== prevState.firstShownItemIndex || newState.lastShownItemIndex !== prevState.lastShownItemIndex || newState.items !== prevState.items || widthHasChanged) {
149
+ var verticalSpacingStateUpdate = _this.measureItemHeightsAndSpacing();
150
+
151
+ if (verticalSpacingStateUpdate) {
152
+ stateUpdate = _objectSpread(_objectSpread({}, stateUpdate), verticalSpacingStateUpdate);
153
+ }
154
+ } // Clean up "before resize" item heights and adjust the scroll position accordingly.
155
+ // Calling `this.beforeResize.cleanUpBeforeResizeItemHeights()` might trigger
156
+ // a `this.updateState()` call but that wouldn't matter because `beforeResize`
157
+ // properties have already been modified directly in `state` (a hacky technique)
158
+
159
+
160
+ var cleanedUpBeforeResize = _this.beforeResize.cleanUpBeforeResizeItemHeights();
161
+
162
+ if (cleanedUpBeforeResize !== undefined) {
163
+ var scrollBy = cleanedUpBeforeResize.scrollBy,
164
+ beforeResize = cleanedUpBeforeResize.beforeResize;
165
+ (0, _debug["default"])('Correct scroll position by', scrollBy);
166
+
167
+ _this.scroll.scrollByY(scrollBy);
168
+
169
+ stateUpdate = _objectSpread(_objectSpread({}, stateUpdate), {}, {
170
+ beforeResize: beforeResize
171
+ });
172
+ }
173
+
174
+ if (!_this._isActive) {
175
+ _this._stoppedStateUpdate = stateUpdate;
176
+ return;
177
+ }
178
+
179
+ if (layoutUpdateReason) {
180
+ updateStateRightAfterRender.call(_this, {
181
+ stateUpdate: stateUpdate,
182
+ reason: layoutUpdateReason
183
+ });
184
+ } else if (stateUpdate) {
185
+ _this.updateState(stateUpdate);
186
+ } else {
187
+ (0, _debug["default"])('~ Finished Layout ~');
188
+ }
189
+ }; // After a new set of items has been rendered:
190
+ //
191
+ // * Restores scroll position when using `preserveScrollPositionOnPrependItems`
192
+ // and items have been prepended.
193
+ //
194
+ // * Applies any "pending" `itemHeights` updates — those ones that happened
195
+ // while an asynchronous `updateState()` call in `setItems()` was pending.
196
+ //
197
+ // * Either creates or resets the snapshot of the current layout.
198
+ //
199
+ // The current layout snapshot could be stored as a "previously calculated layout" variable
200
+ // so that it could theoretically be used when calculating new layout incrementally
201
+ // rather than from scratch, which would be an optimization.
202
+ //
203
+ // The "previously calculated layout" feature is not currently used.
204
+ //
205
+
206
+
207
+ function onNewItemsRendered(itemsDiff, newLayout) {
208
+ // If it's an "incremental" update.
209
+ if (itemsDiff) {
210
+ var prependedItemsCount = itemsDiff.prependedItemsCount,
211
+ appendedItemsCount = itemsDiff.appendedItemsCount;
212
+
213
+ var _this$getState = this.getState(),
214
+ itemHeights = _this$getState.itemHeights,
215
+ itemStates = _this$getState.itemStates; // See if any items' heights changed while new items were being rendered.
216
+
217
+
218
+ if (this.itemHeightsThatChangedWhileNewItemsWereBeingRendered) {
219
+ for (var _i = 0, _Object$keys = Object.keys(this.itemHeightsThatChangedWhileNewItemsWereBeingRendered); _i < _Object$keys.length; _i++) {
220
+ var i = _Object$keys[_i];
221
+ itemHeights[prependedItemsCount + parseInt(i)] = this.itemHeightsThatChangedWhileNewItemsWereBeingRendered[i];
222
+ }
223
+ } // See if any items' states changed while new items were being rendered.
224
+
225
+
226
+ if (this.itemStatesThatChangedWhileNewItemsWereBeingRendered) {
227
+ for (var _i2 = 0, _Object$keys2 = Object.keys(this.itemStatesThatChangedWhileNewItemsWereBeingRendered); _i2 < _Object$keys2.length; _i2++) {
228
+ var _i3 = _Object$keys2[_i2];
229
+ itemStates[prependedItemsCount + parseInt(_i3)] = this.itemStatesThatChangedWhileNewItemsWereBeingRendered[_i3];
230
+ }
231
+ }
232
+
233
+ if (prependedItemsCount === 0) {
234
+ // Adjust `this.previouslyCalculatedLayout`.
235
+ if (this.previouslyCalculatedLayout) {
236
+ if (this.previouslyCalculatedLayout.firstShownItemIndex === newLayout.firstShownItemIndex && this.previouslyCalculatedLayout.lastShownItemIndex === newLayout.lastShownItemIndex) {// `this.previouslyCalculatedLayout` stays the same.
237
+ // `firstShownItemIndex` / `lastShownItemIndex` didn't get changed in `setItems()`,
238
+ // so `beforeItemsHeight` and `shownItemsHeight` also stayed the same.
239
+ } else {
240
+ (0, _debug.warn)('Unexpected (non-matching) "firstShownItemIndex" or "lastShownItemIndex" encountered in "onRender()" after appending items');
241
+ (0, _debug.warn)('Previously calculated layout', this.previouslyCalculatedLayout);
242
+ (0, _debug.warn)('New layout', newLayout);
243
+ this.previouslyCalculatedLayout = undefined;
244
+ }
245
+ }
246
+
247
+ return 'SEAMLESS_APPEND';
248
+ } else {
249
+ if (this.listHeightMeasurement.hasSnapshot()) {
250
+ if (newLayout.firstShownItemIndex === 0) {
251
+ // Restore (adjust) scroll position.
252
+ (0, _debug["default"])('~ Restore Scroll Position ~');
253
+ var listBottomOffsetChange = this.listHeightMeasurement.getListBottomOffsetChange({
254
+ beforeItemsHeight: newLayout.beforeItemsHeight
255
+ });
256
+ this.listHeightMeasurement.reset();
257
+
258
+ if (listBottomOffsetChange) {
259
+ (0, _debug["default"])('Scroll down by', listBottomOffsetChange);
260
+ this.scroll.scrollByY(listBottomOffsetChange);
261
+ } else {
262
+ (0, _debug["default"])('Scroll position hasn\'t changed');
263
+ } // Create new `this.previouslyCalculatedLayout`.
264
+
265
+
266
+ if (this.previouslyCalculatedLayout) {
267
+ if (this.previouslyCalculatedLayout.firstShownItemIndex === 0 && this.previouslyCalculatedLayout.lastShownItemIndex === newLayout.lastShownItemIndex - prependedItemsCount) {
268
+ this.previouslyCalculatedLayout = {
269
+ beforeItemsHeight: 0,
270
+ shownItemsHeight: this.previouslyCalculatedLayout.shownItemsHeight + listBottomOffsetChange,
271
+ firstShownItemIndex: 0,
272
+ lastShownItemIndex: newLayout.lastShownItemIndex
273
+ };
274
+ } else {
275
+ (0, _debug.warn)('Unexpected (non-matching) "firstShownItemIndex" or "lastShownItemIndex" encountered in "onRender()" after prepending items');
276
+ (0, _debug.warn)('Previously calculated layout', this.previouslyCalculatedLayout);
277
+ (0, _debug.warn)('New layout', newLayout);
278
+ this.previouslyCalculatedLayout = undefined;
279
+ }
280
+ }
281
+
282
+ return 'SEAMLESS_PREPEND';
283
+ } else {
284
+ (0, _debug.warn)("Unexpected \"firstShownItemIndex\" ".concat(newLayout.firstShownItemIndex, " encountered in \"onRender()\" after prepending items. Expected 0."));
285
+ }
286
+ }
287
+ }
288
+ } // Reset `this.previouslyCalculatedLayout` in any case other than
289
+ // SEAMLESS_PREPEND or SEAMLESS_APPEND.
290
+
291
+
292
+ this.previouslyCalculatedLayout = undefined;
293
+ }
294
+
295
+ function updateStateRightAfterRender(_ref) {
296
+ var reason = _ref.reason,
297
+ stateUpdate = _ref.stateUpdate;
298
+
299
+ // In React, `setTimeout()` is used to prevent a React error:
300
+ // "Maximum update depth exceeded.
301
+ // This can happen when a component repeatedly calls
302
+ // `.updateState()` inside `componentWillUpdate()` or `componentDidUpdate()`.
303
+ // React limits the number of nested updates to prevent infinite loops."
304
+ if (this._useTimeoutInRenderLoop) {
305
+ // Cancel a previously scheduled re-layout.
306
+ stateUpdate = this.cancelLayoutTimer({
307
+ stateUpdate: stateUpdate
308
+ }); // Schedule a new re-layout.
309
+
310
+ this.scheduleLayoutTimer({
311
+ reason: reason,
312
+ stateUpdate: stateUpdate
313
+ });
314
+ } else {
315
+ this.onUpdateShownItemIndexes({
316
+ reason: reason,
317
+ stateUpdate: stateUpdate
318
+ });
319
+ }
320
+ }
321
+
322
+ function resetStateUpdateFlags() {
323
+ // Read and reset `this.widthHasChanged` flag.
324
+ //
325
+ // If `this.widthHasChanged` flag was reset after calling
326
+ // `this.measureWidthHeightsAndSpacingAndUpdateTablePadding()`
327
+ // then there would be a bug because
328
+ // `this.measureWidthHeightsAndSpacingAndUpdateTablePadding()`
329
+ // calls `this.updateState({ verticalSpacing })` which calls
330
+ // `this.onRender()` immediately, so `this.widthHasChanged`
331
+ // flag wouldn't be reset by that time and would trigger things
332
+ // like `this.itemHeights.reset()` a second time.
333
+ //
334
+ // So, instead read the value of `this.widthHasChanged` flag
335
+ // and reset it right away to prevent any such potential bugs.
336
+ //
337
+ var widthHasChanged = Boolean(this.widthHasChanged); //
338
+ // Reset `this.widthHasChanged` flag.
339
+
340
+ this.widthHasChanged = undefined; // Read `this.firstNonMeasuredItemIndex` flag.
341
+
342
+ var nonMeasuredItemsHaveBeenRendered = this.firstNonMeasuredItemIndex !== undefined; // Reset `this.firstNonMeasuredItemIndex` flag.
343
+
344
+ this.firstNonMeasuredItemIndex = undefined; // Reset `this.newItemsWillBeRendered` flag.
345
+
346
+ this.newItemsWillBeRendered = undefined; // Reset `this.itemHeightsThatChangedWhileNewItemsWereBeingRendered`.
347
+
348
+ this.itemHeightsThatChangedWhileNewItemsWereBeingRendered = undefined; // Reset `this.itemStatesThatChangedWhileNewItemsWereBeingRendered`.
349
+
350
+ this.itemStatesThatChangedWhileNewItemsWereBeingRendered = undefined;
351
+ return {
352
+ nonMeasuredItemsHaveBeenRendered: nonMeasuredItemsHaveBeenRendered,
353
+ widthHasChanged: widthHasChanged
354
+ };
355
+ }
356
+ }
357
+ //# sourceMappingURL=VirtualScroller.onRender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VirtualScroller.onRender.js","names":["_onRender","newState","prevState","log","isDebug","getStateSnapshot","onStateChange","shallowEqual","tbody","setTbodyPadding","getItemsContainerElement","beforeItemsHeight","afterItemsHeight","resetStateUpdateFlags","call","nonMeasuredItemsHaveBeenRendered","widthHasChanged","layoutUpdateReason","LAYOUT_REASON","NON_MEASURED_ITEMS_HAVE_BEEN_MEASURED","VIEWPORT_WIDTH_CHANGED","itemHeights","reset","verticalSpacing","undefined","previousItems","items","newItems","itemsDiff","getItemsDiff","prependedItemsCount","onPrepend","onNewItemsRendered","ITEMS_CHANGED","stateUpdate","firstShownItemIndex","lastShownItemIndex","verticalSpacingStateUpdate","measureItemHeightsAndSpacing","cleanedUpBeforeResize","beforeResize","cleanUpBeforeResizeItemHeights","scrollBy","scroll","scrollByY","_isActive","_stoppedStateUpdate","updateStateRightAfterRender","reason","updateState","newLayout","appendedItemsCount","getState","itemStates","itemHeightsThatChangedWhileNewItemsWereBeingRendered","Object","keys","i","parseInt","itemStatesThatChangedWhileNewItemsWereBeingRendered","previouslyCalculatedLayout","warn","listHeightMeasurement","hasSnapshot","listBottomOffsetChange","getListBottomOffsetChange","shownItemsHeight","_useTimeoutInRenderLoop","cancelLayoutTimer","scheduleLayoutTimer","onUpdateShownItemIndexes","Boolean","firstNonMeasuredItemIndex","newItemsWillBeRendered"],"sources":["../source/VirtualScroller.onRender.js"],"sourcesContent":["import log, { warn, isDebug } from './utility/debug.js'\r\nimport getStateSnapshot from './utility/getStateSnapshot.js'\r\nimport shallowEqual from './utility/shallowEqual.js'\r\nimport { LAYOUT_REASON } from './Layout.js'\r\nimport { setTbodyPadding } from './DOM/tbody.js'\r\n\r\nexport default function() {\r\n\t/**\r\n\t * Should be called right after updates to `state` have been rendered.\r\n\t * @param {object} newState\r\n\t * @param {object} [prevState]\r\n\t */\r\n\tthis._onRender = (newState, prevState) => {\r\n\t\tlog('~ Rendered ~')\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('State', getStateSnapshot(newState))\r\n\t\t}\r\n\r\n\t\tif (this.onStateChange) {\r\n\t\t\tif (!shallowEqual(newState, prevState)) {\r\n\t\t\t\tthis.onStateChange(newState)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Update `<tbody/>` `padding`.\r\n\t\t// (`<tbody/>` is different in a way that it can't have `margin`, only `padding`).\r\n\t\t// https://gitlab.com/catamphetamine/virtual-scroller/-/issues/1\r\n\t\tif (this.tbody) {\r\n\t\t\tsetTbodyPadding(\r\n\t\t\t\tthis.getItemsContainerElement(),\r\n\t\t\t\tnewState.beforeItemsHeight,\r\n\t\t\t\tnewState.afterItemsHeight\r\n\t\t\t)\r\n\t\t}\r\n\r\n\t\tif (!prevState) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t// `this.resetStateUpdateFlags()` must be called before calling\r\n\t\t// `this.measureItemHeightsAndSpacing()`.\r\n\t\tconst {\r\n\t\t\tnonMeasuredItemsHaveBeenRendered,\r\n\t\t\twidthHasChanged\r\n\t\t} = resetStateUpdateFlags.call(this)\r\n\r\n\t\tlet layoutUpdateReason\r\n\r\n\t\t// If the `VirtualScroller`, while calculating layout parameters, encounters\r\n\t\t// a not-shown item with a non-measured height, it calls `updateState()` just to\r\n\t\t// render that item first, and then, after the list has been re-rendered, it measures\r\n\t\t// the item's height and then proceeds with calculating the correct layout parameters.\r\n\t\tif (nonMeasuredItemsHaveBeenRendered) {\r\n\t\t\tlayoutUpdateReason = LAYOUT_REASON.NON_MEASURED_ITEMS_HAVE_BEEN_MEASURED\r\n\t\t}\r\n\r\n\t\t// If scrollable container width has changed, and it has been re-rendered,\r\n\t\t// then it's time to measure the new item heights and then perform a re-layout\r\n\t\t// with the correctly calculated layout parameters.\r\n\t\t//\r\n\t\t// A re-layout is required because the layout parameters calculated on resize\r\n\t\t// are approximate ones, and the exact item heights aren't known at that point.\r\n\t\t// So on resize, it calls `updateState()` just to re-render the `VirtualScroller`.\r\n\t\t// After it has been re-rendered, it will measure item heights and then calculate\r\n\t\t// correct layout parameters.\r\n\t\t//\r\n\t\tif (widthHasChanged) {\r\n\t\t\tlayoutUpdateReason = LAYOUT_REASON.VIEWPORT_WIDTH_CHANGED\r\n\r\n\t\t\t// Reset measured item heights on viewport width change.\r\n\t\t\tthis.itemHeights.reset()\r\n\r\n\t\t\t// Reset `verticalSpacing` (will be re-measured).\r\n\t\t\tthis.verticalSpacing = undefined\r\n\t\t}\r\n\r\n\t\tconst { items: previousItems } = prevState\r\n\t\tconst { items: newItems } = newState\r\n\t\t// Even if `this.newItemsWillBeRendered` flag is `true`,\r\n\t\t// `newItems` could still be equal to `previousItems`.\r\n\t\t// For example, when `updateState()` calls don't update `state` immediately\r\n\t\t// and a developer first calls `setItems(newItems)` and then calls `setItems(oldItems)`:\r\n\t\t// in that case, `this.newItemsWillBeRendered` flag will be `true` but the actual `items`\r\n\t\t// in state wouldn't have changed due to the first `updateState()` call being overwritten\r\n\t\t// by the second `updateState()` call (that's called \"batching state updates\" in React).\r\n\t\tif (newItems !== previousItems) {\r\n\t\t\tconst itemsDiff = this.getItemsDiff(previousItems, newItems)\r\n\t\t\tif (itemsDiff) {\r\n\t\t\t\t// The call to `.onPrepend()` must precede the call to `.measureItemHeights()`\r\n\t\t\t\t// which is called in `.onRender()`.\r\n\t\t\t\t// `this.itemHeights.onPrepend()` updates `firstMeasuredItemIndex`\r\n\t\t\t\t// and `lastMeasuredItemIndex` of `this.itemHeights`.\r\n\t\t\t\tconst { prependedItemsCount } = itemsDiff\r\n\t\t\t\tthis.itemHeights.onPrepend(prependedItemsCount)\r\n\t\t\t} else {\r\n\t\t\t\tthis.itemHeights.reset()\r\n\t\t\t}\r\n\r\n\t\t\tif (!widthHasChanged) {\r\n\t\t\t\t// The call to `this.onNewItemsRendered()` must precede the call to\r\n\t\t\t\t// `.measureItemHeights()` which is called in `.onRender()` because\r\n\t\t\t\t// `this.onNewItemsRendered()` updates `firstMeasuredItemIndex` and\r\n\t\t\t\t// `lastMeasuredItemIndex` of `this.itemHeights` in case of a prepend.\r\n\t\t\t\t//\r\n\t\t\t\t// If after prepending items the scroll position\r\n\t\t\t\t// should be \"restored\" so that there's no \"jump\" of content\r\n\t\t\t\t// then it means that all previous items have just been rendered\r\n\t\t\t\t// in a single pass, and there's no need to update layout again.\r\n\t\t\t\t//\r\n\t\t\t\tif (onNewItemsRendered.call(this, itemsDiff, newState) !== 'SEAMLESS_PREPEND') {\r\n\t\t\t\t\tlayoutUpdateReason = LAYOUT_REASON.ITEMS_CHANGED\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tlet stateUpdate\r\n\r\n\t\t// Re-measure item heights.\r\n\t\t// Also, measure vertical spacing (if not measured) and fix `<table/>` padding.\r\n\t\t//\r\n\t\t// This block should go after `if (newItems !== previousItems) {}`\r\n\t\t// because `this.itemHeights` can get `.reset()` there, which would\r\n\t\t// discard all the measurements done here, and having currently shown\r\n\t\t// item height measurements is required.\r\n\t\t//\r\n\t\tif (\r\n\t\t\tnewState.firstShownItemIndex !== prevState.firstShownItemIndex ||\r\n\t\t\tnewState.lastShownItemIndex !== prevState.lastShownItemIndex ||\r\n\t\t\tnewState.items !== prevState.items ||\r\n\t\t\twidthHasChanged\r\n\t\t) {\r\n\t\t\tconst verticalSpacingStateUpdate = this.measureItemHeightsAndSpacing()\r\n\t\t\tif (verticalSpacingStateUpdate) {\r\n\t\t\t\tstateUpdate = {\r\n\t\t\t\t\t...stateUpdate,\r\n\t\t\t\t\t...verticalSpacingStateUpdate\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Clean up \"before resize\" item heights and adjust the scroll position accordingly.\r\n\t\t// Calling `this.beforeResize.cleanUpBeforeResizeItemHeights()` might trigger\r\n\t\t// a `this.updateState()` call but that wouldn't matter because `beforeResize`\r\n\t\t// properties have already been modified directly in `state` (a hacky technique)\r\n\t\tconst cleanedUpBeforeResize = this.beforeResize.cleanUpBeforeResizeItemHeights()\r\n\t\tif (cleanedUpBeforeResize !== undefined) {\r\n\t\t\tconst { scrollBy, beforeResize } = cleanedUpBeforeResize\r\n\t\t\tlog('Correct scroll position by', scrollBy)\r\n\t\t\tthis.scroll.scrollByY(scrollBy)\r\n\t\t\tstateUpdate = {\r\n\t\t\t\t...stateUpdate,\r\n\t\t\t\tbeforeResize\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!this._isActive) {\r\n\t\t\tthis._stoppedStateUpdate = stateUpdate\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tif (layoutUpdateReason) {\r\n\t\t\tupdateStateRightAfterRender.call(this, {\r\n\t\t\t\tstateUpdate,\r\n\t\t\t\treason: layoutUpdateReason\r\n\t\t\t})\r\n\t\t} else if (stateUpdate) {\r\n\t\t\tthis.updateState(stateUpdate)\r\n\t\t} else {\r\n\t\t\tlog('~ Finished Layout ~')\r\n\t\t}\r\n\t}\r\n\r\n\t// After a new set of items has been rendered:\r\n\t//\r\n\t// * Restores scroll position when using `preserveScrollPositionOnPrependItems`\r\n\t// and items have been prepended.\r\n\t//\r\n\t// * Applies any \"pending\" `itemHeights` updates — those ones that happened\r\n\t// while an asynchronous `updateState()` call in `setItems()` was pending.\r\n\t//\r\n\t// * Either creates or resets the snapshot of the current layout.\r\n\t//\r\n\t// The current layout snapshot could be stored as a \"previously calculated layout\" variable\r\n\t// so that it could theoretically be used when calculating new layout incrementally\r\n\t// rather than from scratch, which would be an optimization.\r\n\t//\r\n\t// The \"previously calculated layout\" feature is not currently used.\r\n\t//\r\n\tfunction onNewItemsRendered(itemsDiff, newLayout) {\r\n\t\t// If it's an \"incremental\" update.\r\n\t\tif (itemsDiff) {\r\n\t\t\tconst {\r\n\t\t\t\tprependedItemsCount,\r\n\t\t\t\tappendedItemsCount\r\n\t\t\t} = itemsDiff\r\n\r\n\t\t\tconst {\r\n\t\t\t\titemHeights,\r\n\t\t\t\titemStates\r\n\t\t\t} = this.getState()\r\n\r\n\t\t\t// See if any items' heights changed while new items were being rendered.\r\n\t\t\tif (this.itemHeightsThatChangedWhileNewItemsWereBeingRendered) {\r\n\t\t\t\tfor (const i of Object.keys(this.itemHeightsThatChangedWhileNewItemsWereBeingRendered)) {\r\n\t\t\t\t\titemHeights[prependedItemsCount + parseInt(i)] = this.itemHeightsThatChangedWhileNewItemsWereBeingRendered[i]\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// See if any items' states changed while new items were being rendered.\r\n\t\t\tif (this.itemStatesThatChangedWhileNewItemsWereBeingRendered) {\r\n\t\t\t\tfor (const i of Object.keys(this.itemStatesThatChangedWhileNewItemsWereBeingRendered)) {\r\n\t\t\t\t\titemStates[prependedItemsCount + parseInt(i)] = this.itemStatesThatChangedWhileNewItemsWereBeingRendered[i]\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (prependedItemsCount === 0) {\r\n\t\t\t\t// Adjust `this.previouslyCalculatedLayout`.\r\n\t\t\t\tif (this.previouslyCalculatedLayout) {\r\n\t\t\t\t\tif (\r\n\t\t\t\t\t\tthis.previouslyCalculatedLayout.firstShownItemIndex === newLayout.firstShownItemIndex &&\r\n\t\t\t\t\t\tthis.previouslyCalculatedLayout.lastShownItemIndex === newLayout.lastShownItemIndex\r\n\t\t\t\t\t) {\r\n\t\t\t\t\t\t// `this.previouslyCalculatedLayout` stays the same.\r\n\t\t\t\t\t\t// `firstShownItemIndex` / `lastShownItemIndex` didn't get changed in `setItems()`,\r\n\t\t\t\t\t\t// so `beforeItemsHeight` and `shownItemsHeight` also stayed the same.\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\twarn('Unexpected (non-matching) \"firstShownItemIndex\" or \"lastShownItemIndex\" encountered in \"onRender()\" after appending items')\r\n\t\t\t\t\t\twarn('Previously calculated layout', this.previouslyCalculatedLayout)\r\n\t\t\t\t\t\twarn('New layout', newLayout)\r\n\t\t\t\t\t\tthis.previouslyCalculatedLayout = undefined\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\treturn 'SEAMLESS_APPEND'\r\n\t\t\t} else {\r\n\t\t\t\tif (this.listHeightMeasurement.hasSnapshot()) {\r\n\t\t\t\t\tif (newLayout.firstShownItemIndex === 0) {\r\n\t\t\t\t\t\t// Restore (adjust) scroll position.\r\n\t\t\t\t\t\tlog('~ Restore Scroll Position ~')\r\n\t\t\t\t\t\tconst listBottomOffsetChange = this.listHeightMeasurement.getListBottomOffsetChange({\r\n\t\t\t\t\t\t\tbeforeItemsHeight: newLayout.beforeItemsHeight\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t\tthis.listHeightMeasurement.reset()\r\n\t\t\t\t\t\tif (listBottomOffsetChange) {\r\n\t\t\t\t\t\t\tlog('Scroll down by', listBottomOffsetChange)\r\n\t\t\t\t\t\t\tthis.scroll.scrollByY(listBottomOffsetChange)\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tlog('Scroll position hasn\\'t changed')\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t// Create new `this.previouslyCalculatedLayout`.\r\n\t\t\t\t\t\tif (this.previouslyCalculatedLayout) {\r\n\t\t\t\t\t\t\tif (\r\n\t\t\t\t\t\t\t\tthis.previouslyCalculatedLayout.firstShownItemIndex === 0 &&\r\n\t\t\t\t\t\t\t\tthis.previouslyCalculatedLayout.lastShownItemIndex === newLayout.lastShownItemIndex - prependedItemsCount\r\n\t\t\t\t\t\t\t) {\r\n\t\t\t\t\t\t\t\tthis.previouslyCalculatedLayout = {\r\n\t\t\t\t\t\t\t\t\tbeforeItemsHeight: 0,\r\n\t\t\t\t\t\t\t\t\tshownItemsHeight: this.previouslyCalculatedLayout.shownItemsHeight + listBottomOffsetChange,\r\n\t\t\t\t\t\t\t\t\tfirstShownItemIndex: 0,\r\n\t\t\t\t\t\t\t\t\tlastShownItemIndex: newLayout.lastShownItemIndex\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\twarn('Unexpected (non-matching) \"firstShownItemIndex\" or \"lastShownItemIndex\" encountered in \"onRender()\" after prepending items')\r\n\t\t\t\t\t\t\t\twarn('Previously calculated layout', this.previouslyCalculatedLayout)\r\n\t\t\t\t\t\t\t\twarn('New layout', newLayout)\r\n\t\t\t\t\t\t\t\tthis.previouslyCalculatedLayout = undefined\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\treturn 'SEAMLESS_PREPEND'\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\twarn(`Unexpected \"firstShownItemIndex\" ${newLayout.firstShownItemIndex} encountered in \"onRender()\" after prepending items. Expected 0.`)\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Reset `this.previouslyCalculatedLayout` in any case other than\r\n\t\t// SEAMLESS_PREPEND or SEAMLESS_APPEND.\r\n\t\tthis.previouslyCalculatedLayout = undefined\r\n\t}\r\n\r\n\tfunction updateStateRightAfterRender({\r\n\t\treason,\r\n\t\tstateUpdate\r\n\t}) {\r\n\t\t// In React, `setTimeout()` is used to prevent a React error:\r\n\t\t// \"Maximum update depth exceeded.\r\n\t\t// This can happen when a component repeatedly calls\r\n\t\t// `.updateState()` inside `componentWillUpdate()` or `componentDidUpdate()`.\r\n\t\t// React limits the number of nested updates to prevent infinite loops.\"\r\n\t\tif (this._useTimeoutInRenderLoop) {\r\n\t\t\t// Cancel a previously scheduled re-layout.\r\n\t\t\tstateUpdate = this.cancelLayoutTimer({ stateUpdate })\r\n\t\t\t// Schedule a new re-layout.\r\n\t\t\tthis.scheduleLayoutTimer({\r\n\t\t\t\treason,\r\n\t\t\t\tstateUpdate\r\n\t\t\t})\r\n\t\t} else {\r\n\t\t\tthis.onUpdateShownItemIndexes({\r\n\t\t\t\treason,\r\n\t\t\t\tstateUpdate\r\n\t\t\t})\r\n\t\t}\r\n\t}\r\n\r\n\tfunction resetStateUpdateFlags() {\r\n\t\t// Read and reset `this.widthHasChanged` flag.\r\n\t\t//\r\n\t\t// If `this.widthHasChanged` flag was reset after calling\r\n\t\t// `this.measureWidthHeightsAndSpacingAndUpdateTablePadding()`\r\n\t\t// then there would be a bug because\r\n\t\t// `this.measureWidthHeightsAndSpacingAndUpdateTablePadding()`\r\n\t\t// calls `this.updateState({ verticalSpacing })` which calls\r\n\t\t// `this.onRender()` immediately, so `this.widthHasChanged`\r\n\t\t// flag wouldn't be reset by that time and would trigger things\r\n\t\t// like `this.itemHeights.reset()` a second time.\r\n\t\t//\r\n\t\t// So, instead read the value of `this.widthHasChanged` flag\r\n\t\t// and reset it right away to prevent any such potential bugs.\r\n\t\t//\r\n\t\tconst widthHasChanged = Boolean(this.widthHasChanged)\r\n\t\t//\r\n\t\t// Reset `this.widthHasChanged` flag.\r\n\t\tthis.widthHasChanged = undefined\r\n\r\n\t\t// Read `this.firstNonMeasuredItemIndex` flag.\r\n\t\tconst nonMeasuredItemsHaveBeenRendered = this.firstNonMeasuredItemIndex !== undefined\r\n\t\t// Reset `this.firstNonMeasuredItemIndex` flag.\r\n\t\tthis.firstNonMeasuredItemIndex = undefined\r\n\r\n\t\t// Reset `this.newItemsWillBeRendered` flag.\r\n\t\tthis.newItemsWillBeRendered = undefined\r\n\r\n\t\t// Reset `this.itemHeightsThatChangedWhileNewItemsWereBeingRendered`.\r\n\t\tthis.itemHeightsThatChangedWhileNewItemsWereBeingRendered = undefined\r\n\r\n\t\t// Reset `this.itemStatesThatChangedWhileNewItemsWereBeingRendered`.\r\n\t\tthis.itemStatesThatChangedWhileNewItemsWereBeingRendered = undefined\r\n\r\n\t\treturn {\r\n\t\t\tnonMeasuredItemsHaveBeenRendered,\r\n\t\t\twidthHasChanged\r\n\t\t}\r\n\t}\r\n}"],"mappings":"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"}
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports["default"] = _default;
7
+
8
+ var _debug = _interopRequireDefault(require("./utility/debug.js"));
9
+
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
11
+
12
+ function _default() {
13
+ var _this = this;
14
+
15
+ this.onResize = function () {
16
+ // Reset "previously calculated layout".
17
+ //
18
+ // The "previously calculated layout" feature is not currently used.
19
+ //
20
+ // The current layout snapshot could be stored as a "previously calculated layout" variable
21
+ // so that it could theoretically be used when calculating new layout incrementally
22
+ // rather than from scratch, which would be an optimization.
23
+ //
24
+ _this.previouslyCalculatedLayout = undefined; // Cancel any potential scheduled scroll position restoration.
25
+
26
+ _this.listHeightMeasurement.reset(); // Get the most recent items count.
27
+ // If there're a "pending" `setItems()` call then use the items count from that call
28
+ // instead of using the count of currently shown `items` from `state`.
29
+ // A `setItems()` call is "pending" when `updateState()` operation is "asynchronous", that is
30
+ // when `updateState()` calls aren't applied immediately, like in React.
31
+
32
+
33
+ var itemsCount = _this.newItemsWillBeRendered ? _this.newItemsWillBeRendered.count : _this.getState().itemHeights.length; // If layout values have been calculated as a result of a "pending" `setItems()` call,
34
+ // then don't discard those new layout values and use them instead of the ones from `state`.
35
+ //
36
+ // A `setItems()` call is "pending" when `updateState()` operation is "asynchronous", that is
37
+ // when `updateState()` calls aren't applied immediately, like in React.
38
+ //
39
+
40
+ var layout = _this.newItemsWillBeRendered ? _this.newItemsWillBeRendered.layout : _this.getState(); // Update `VirtualScroller` state.
41
+
42
+ var newState = {
43
+ scrollableContainerWidth: _this.scrollableContainer.getWidth(),
44
+ // This state update should also overwrite all the `state` properties
45
+ // that are also updated in the "on scroll" handler (`getShownItemIndexes()`):
46
+ //
47
+ // * `firstShownItemIndex`
48
+ // * `lastShownItemIndex`
49
+ // * `beforeItemsHeight`
50
+ // * `afterItemsHeight`
51
+ //
52
+ // That's because this `updateState()` update has a higher priority
53
+ // than that of the "on scroll" handler, so it should overwrite
54
+ // any potential state changes dispatched by the "on scroll" handler.
55
+ //
56
+ // All these properties might have changed, but they're not
57
+ // recalculated here becase they'll be recalculated after
58
+ // this new state is applied (rendered).
59
+ //
60
+ firstShownItemIndex: layout.firstShownItemIndex,
61
+ lastShownItemIndex: layout.lastShownItemIndex,
62
+ beforeItemsHeight: layout.beforeItemsHeight,
63
+ afterItemsHeight: layout.afterItemsHeight,
64
+ // Reset item heights, because if scrollable container's width (or height)
65
+ // has changed, then the list width (or height) most likely also has changed,
66
+ // and also some CSS `@media()` rules might have been added or removed.
67
+ // So re-render the list entirely.
68
+ itemHeights: new Array(itemsCount),
69
+ columnsCount: _this.getActualColumnsCountForState(),
70
+ // Re-measure vertical spacing after render because new CSS styles
71
+ // might be applied for the new window width.
72
+ verticalSpacing: undefined
73
+ };
74
+ var firstShownItemIndex = layout.firstShownItemIndex,
75
+ lastShownItemIndex = layout.lastShownItemIndex; // Get the `columnsCount` for the new window width.
76
+
77
+ var newColumnsCount = _this.getActualColumnsCount(); // Re-calculate `firstShownItemIndex` and `lastShownItemIndex`
78
+ // based on the new `columnsCount` so that the whole row is visible.
79
+
80
+
81
+ var newFirstShownItemIndex = Math.floor(firstShownItemIndex / newColumnsCount) * newColumnsCount;
82
+ var newLastShownItemIndex = Math.min(Math.ceil((lastShownItemIndex + 1) / newColumnsCount) * newColumnsCount, itemsCount) - 1; // Potentially update `firstShownItemIndex` if it needs to be adjusted in order to
83
+ // correspond to the new `columnsCount`.
84
+
85
+ if (newFirstShownItemIndex !== firstShownItemIndex) {
86
+ (0, _debug["default"])('Columns Count changed from', _this.getState().columnsCount || 1, 'to', newColumnsCount);
87
+ (0, _debug["default"])('First Shown Item Index needs to change from', firstShownItemIndex, 'to', newFirstShownItemIndex);
88
+ } // Always rewrite `firstShownItemIndex` and `lastShownItemIndex`
89
+ // as part of the `state` update, even if it hasn't been modified.
90
+ //
91
+ // The reason is that there could be two subsequent `onResize()` calls:
92
+ // the first one could be user resizing the window to half of its width,
93
+ // resulting in an "asynchronous" `updateState()` call, and then, before that
94
+ // `updateState()` call is applied, a second resize event happens when the user
95
+ // has resized the window back to its original width, meaning that the
96
+ // `columnsCount` is back to its original value.
97
+ // In that case, the final `newFirstShownItemIndex` will be equal to the
98
+ // original `firstShownItemIndex` that was in `state` before the user
99
+ // has started resizing the window, so, in the end, `state.firstShownItemIndex`
100
+ // property wouldn't have changed, but it still has to be part of the final
101
+ // state update in order to overwrite the previous update of `firstShownItemIndex`
102
+ // property that has been scheduled to be applied in state after the first resize
103
+ // happened.
104
+ //
105
+
106
+
107
+ newState.firstShownItemIndex = newFirstShownItemIndex;
108
+ newState.lastShownItemIndex = newLastShownItemIndex;
109
+
110
+ var verticalSpacing = _this.getVerticalSpacing();
111
+
112
+ var columnsCount = _this.getColumnsCount(); // `beforeResize` is always overwritten in `state` here.
113
+ // (once it has started being tracked in `state`)
114
+
115
+
116
+ if (_this.shouldDiscardBeforeResizeItemHeights() || newFirstShownItemIndex === 0) {
117
+ if (_this.beforeResize.shouldIncludeBeforeResizeValuesInState()) {
118
+ newState.beforeResize = undefined;
119
+ }
120
+ } // Snapshot "before resize" values in order to preserve the currently
121
+ // shown items' vertical position on screen so that there's no "content jumping".
122
+ else {
123
+ // Keep "before resize" values in order to preserve the currently
124
+ // shown items' vertical position on screen so that there's no
125
+ // "content jumping". These "before resize" values will be discarded
126
+ // when (if) the user scrolls back to the top of the list.
127
+ newState.beforeResize = {
128
+ verticalSpacing: verticalSpacing,
129
+ columnsCount: columnsCount,
130
+ itemHeights: _this.beforeResize.snapshotBeforeResizeItemHeights({
131
+ firstShownItemIndex: firstShownItemIndex,
132
+ newFirstShownItemIndex: newFirstShownItemIndex,
133
+ newColumnsCount: newColumnsCount
134
+ })
135
+ };
136
+ } // `this.widthHasChanged` tells `VirtualScroller` that it should
137
+ // temporarily stop other updates (like "on scroll" updates) and wait
138
+ // for the new `state` to be applied, after which the `onRender()`
139
+ // function will clear this flag and perform a re-layout.
140
+ //
141
+ // A re-layout is required because the layout parameters calculated above
142
+ // are approximate ones, and the exact item heights aren't known at this point.
143
+ // So the `updateState()` call below is just to re-render the `VirtualScroller`.
144
+ // After it has been re-rendered, it will measure item heights and then calculate
145
+ // correct layout parameters.
146
+ //
147
+
148
+
149
+ _this.widthHasChanged = {
150
+ stateUpdate: newState
151
+ }; // Rerender.
152
+
153
+ _this.updateState(newState);
154
+ }; // Returns whether "before resize" item heights should be discarded
155
+ // as a result of calling `setItems()` with a new set of items
156
+ // when an asynchronous `updateState()` call inside that function
157
+ // hasn't been applied yet.
158
+ //
159
+ // If `setItems()` update was an "incremental" one and no items
160
+ // have been prepended, then `firstShownItemIndex` is preserved,
161
+ // and all items' heights before it should be kept in order to
162
+ // preserve the top offset of the first shown item so that there's
163
+ // no "content jumping".
164
+ //
165
+ // If `setItems()` update was an "incremental" one but there're
166
+ // some prepended items, then it means that now there're new items
167
+ // with unknown heights at the top, so the top offset of the first
168
+ // shown item won't be preserved because there're no "before resize"
169
+ // heights of those items.
170
+ //
171
+ // If `setItems()` update was not an "incremental" one, then don't
172
+ // attempt to restore previous item heights after a potential window
173
+ // width change because all item heights have been reset.
174
+ //
175
+
176
+
177
+ this.shouldDiscardBeforeResizeItemHeights = function () {
178
+ if (_this.newItemsWillBeRendered) {
179
+ var _this$newItemsWillBeR = _this.newItemsWillBeRendered,
180
+ prepend = _this$newItemsWillBeR.prepend,
181
+ replace = _this$newItemsWillBeR.replace;
182
+ return prepend || replace;
183
+ }
184
+ };
185
+ }
186
+ //# sourceMappingURL=VirtualScroller.resize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VirtualScroller.resize.js","names":["onResize","previouslyCalculatedLayout","undefined","listHeightMeasurement","reset","itemsCount","newItemsWillBeRendered","count","getState","itemHeights","length","layout","newState","scrollableContainerWidth","scrollableContainer","getWidth","firstShownItemIndex","lastShownItemIndex","beforeItemsHeight","afterItemsHeight","Array","columnsCount","getActualColumnsCountForState","verticalSpacing","newColumnsCount","getActualColumnsCount","newFirstShownItemIndex","Math","floor","newLastShownItemIndex","min","ceil","log","getVerticalSpacing","getColumnsCount","shouldDiscardBeforeResizeItemHeights","beforeResize","shouldIncludeBeforeResizeValuesInState","snapshotBeforeResizeItemHeights","widthHasChanged","stateUpdate","updateState","prepend","replace"],"sources":["../source/VirtualScroller.resize.js"],"sourcesContent":["import log from './utility/debug.js'\r\n\r\nexport default function() {\r\n\tthis.onResize = () => {\r\n\t\t// Reset \"previously calculated layout\".\r\n\t\t//\r\n\t\t// The \"previously calculated layout\" feature is not currently used.\r\n\t\t//\r\n\t\t// The current layout snapshot could be stored as a \"previously calculated layout\" variable\r\n\t\t// so that it could theoretically be used when calculating new layout incrementally\r\n\t\t// rather than from scratch, which would be an optimization.\r\n\t\t//\r\n\t\tthis.previouslyCalculatedLayout = undefined\r\n\r\n\t\t// Cancel any potential scheduled scroll position restoration.\r\n\t\tthis.listHeightMeasurement.reset()\r\n\r\n\t\t// Get the most recent items count.\r\n\t\t// If there're a \"pending\" `setItems()` call then use the items count from that call\r\n\t\t// instead of using the count of currently shown `items` from `state`.\r\n\t\t// A `setItems()` call is \"pending\" when `updateState()` operation is \"asynchronous\", that is\r\n\t\t// when `updateState()` calls aren't applied immediately, like in React.\r\n\t\tconst itemsCount = this.newItemsWillBeRendered\r\n\t\t\t? this.newItemsWillBeRendered.count\r\n\t\t\t: this.getState().itemHeights.length\r\n\r\n\t\t// If layout values have been calculated as a result of a \"pending\" `setItems()` call,\r\n\t\t// then don't discard those new layout values and use them instead of the ones from `state`.\r\n\t\t//\r\n\t\t// A `setItems()` call is \"pending\" when `updateState()` operation is \"asynchronous\", that is\r\n\t\t// when `updateState()` calls aren't applied immediately, like in React.\r\n\t\t//\r\n\t\tconst layout = this.newItemsWillBeRendered\r\n\t\t\t? this.newItemsWillBeRendered.layout\r\n\t\t\t: this.getState()\r\n\r\n\t\t// Update `VirtualScroller` state.\r\n\t\tconst newState = {\r\n\t\t\tscrollableContainerWidth: this.scrollableContainer.getWidth(),\r\n\r\n\t\t\t// This state update should also overwrite all the `state` properties\r\n\t\t\t// that are also updated in the \"on scroll\" handler (`getShownItemIndexes()`):\r\n\t\t\t//\r\n\t\t\t// * `firstShownItemIndex`\r\n\t\t\t// * `lastShownItemIndex`\r\n\t\t\t// * `beforeItemsHeight`\r\n\t\t\t// * `afterItemsHeight`\r\n\t\t\t//\r\n\t\t\t// That's because this `updateState()` update has a higher priority\r\n\t\t\t// than that of the \"on scroll\" handler, so it should overwrite\r\n\t\t\t// any potential state changes dispatched by the \"on scroll\" handler.\r\n\t\t\t//\r\n\t\t\t// All these properties might have changed, but they're not\r\n\t\t\t// recalculated here becase they'll be recalculated after\r\n\t\t\t// this new state is applied (rendered).\r\n\t\t\t//\r\n\t\t\tfirstShownItemIndex: layout.firstShownItemIndex,\r\n\t\t\tlastShownItemIndex: layout.lastShownItemIndex,\r\n\t\t\tbeforeItemsHeight: layout.beforeItemsHeight,\r\n\t\t\tafterItemsHeight: layout.afterItemsHeight,\r\n\r\n\t\t\t// Reset item heights, because if scrollable container's width (or height)\r\n\t\t\t// has changed, then the list width (or height) most likely also has changed,\r\n\t\t\t// and also some CSS `@media()` rules might have been added or removed.\r\n\t\t\t// So re-render the list entirely.\r\n\t\t\titemHeights: new Array(itemsCount),\r\n\r\n\t\t\tcolumnsCount: this.getActualColumnsCountForState(),\r\n\r\n\t\t\t// Re-measure vertical spacing after render because new CSS styles\r\n\t\t\t// might be applied for the new window width.\r\n\t\t\tverticalSpacing: undefined\r\n\t\t}\r\n\r\n\t\tconst { firstShownItemIndex, lastShownItemIndex } = layout\r\n\r\n\t\t// Get the `columnsCount` for the new window width.\r\n\t\tconst newColumnsCount = this.getActualColumnsCount()\r\n\r\n\t\t// Re-calculate `firstShownItemIndex` and `lastShownItemIndex`\r\n\t\t// based on the new `columnsCount` so that the whole row is visible.\r\n\t\tconst newFirstShownItemIndex = Math.floor(firstShownItemIndex / newColumnsCount) * newColumnsCount\r\n\t\tconst newLastShownItemIndex = Math.min(\r\n\t\t\tMath.ceil((lastShownItemIndex + 1) / newColumnsCount) * newColumnsCount,\r\n\t\t\titemsCount\r\n\t\t) - 1\r\n\r\n\t\t// Potentially update `firstShownItemIndex` if it needs to be adjusted in order to\r\n\t\t// correspond to the new `columnsCount`.\r\n\t\tif (newFirstShownItemIndex !== firstShownItemIndex) {\r\n\t\t\tlog('Columns Count changed from', this.getState().columnsCount || 1, 'to', newColumnsCount)\r\n\t\t\tlog('First Shown Item Index needs to change from', firstShownItemIndex, 'to', newFirstShownItemIndex)\r\n\t\t}\r\n\r\n\t\t// Always rewrite `firstShownItemIndex` and `lastShownItemIndex`\r\n\t\t// as part of the `state` update, even if it hasn't been modified.\r\n\t\t//\r\n\t\t// The reason is that there could be two subsequent `onResize()` calls:\r\n\t\t// the first one could be user resizing the window to half of its width,\r\n\t\t// resulting in an \"asynchronous\" `updateState()` call, and then, before that\r\n\t\t// `updateState()` call is applied, a second resize event happens when the user\r\n\t\t// has resized the window back to its original width, meaning that the\r\n\t\t// `columnsCount` is back to its original value.\r\n\t\t// In that case, the final `newFirstShownItemIndex` will be equal to the\r\n\t\t// original `firstShownItemIndex` that was in `state` before the user\r\n\t\t// has started resizing the window, so, in the end, `state.firstShownItemIndex`\r\n\t\t// property wouldn't have changed, but it still has to be part of the final\r\n\t\t// state update in order to overwrite the previous update of `firstShownItemIndex`\r\n\t\t// property that has been scheduled to be applied in state after the first resize\r\n\t\t// happened.\r\n\t\t//\r\n\t\tnewState.firstShownItemIndex = newFirstShownItemIndex\r\n\t\tnewState.lastShownItemIndex = newLastShownItemIndex\r\n\r\n\t\tconst verticalSpacing = this.getVerticalSpacing()\r\n\t\tconst columnsCount = this.getColumnsCount()\r\n\r\n\t\t// `beforeResize` is always overwritten in `state` here.\r\n\t\t// (once it has started being tracked in `state`)\r\n\t\tif (this.shouldDiscardBeforeResizeItemHeights() || newFirstShownItemIndex === 0) {\r\n\t\t\tif (this.beforeResize.shouldIncludeBeforeResizeValuesInState()) {\r\n\t\t\t\tnewState.beforeResize = undefined\r\n\t\t\t}\r\n\t\t}\r\n\t\t// Snapshot \"before resize\" values in order to preserve the currently\r\n\t\t// shown items' vertical position on screen so that there's no \"content jumping\".\r\n\t\telse {\r\n\t\t\t// Keep \"before resize\" values in order to preserve the currently\r\n\t\t\t// shown items' vertical position on screen so that there's no\r\n\t\t\t// \"content jumping\". These \"before resize\" values will be discarded\r\n\t\t\t// when (if) the user scrolls back to the top of the list.\r\n\t\t\tnewState.beforeResize = {\r\n\t\t\t\tverticalSpacing,\r\n\t\t\t\tcolumnsCount,\r\n\t\t\t\titemHeights: this.beforeResize.snapshotBeforeResizeItemHeights({\r\n\t\t\t\t\tfirstShownItemIndex,\r\n\t\t\t\t\tnewFirstShownItemIndex,\r\n\t\t\t\t\tnewColumnsCount\r\n\t\t\t\t})\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// `this.widthHasChanged` tells `VirtualScroller` that it should\r\n\t\t// temporarily stop other updates (like \"on scroll\" updates) and wait\r\n\t\t// for the new `state` to be applied, after which the `onRender()`\r\n\t\t// function will clear this flag and perform a re-layout.\r\n\t\t//\r\n\t\t// A re-layout is required because the layout parameters calculated above\r\n\t\t// are approximate ones, and the exact item heights aren't known at this point.\r\n\t\t// So the `updateState()` call below is just to re-render the `VirtualScroller`.\r\n\t\t// After it has been re-rendered, it will measure item heights and then calculate\r\n\t\t// correct layout parameters.\r\n\t\t//\r\n\t\tthis.widthHasChanged = {\r\n\t\t\tstateUpdate: newState\r\n\t\t}\r\n\r\n\t\t// Rerender.\r\n\t\tthis.updateState(newState)\r\n\t}\r\n\r\n\t// Returns whether \"before resize\" item heights should be discarded\r\n\t// as a result of calling `setItems()` with a new set of items\r\n\t// when an asynchronous `updateState()` call inside that function\r\n\t// hasn't been applied yet.\r\n\t//\r\n\t// If `setItems()` update was an \"incremental\" one and no items\r\n\t// have been prepended, then `firstShownItemIndex` is preserved,\r\n\t// and all items' heights before it should be kept in order to\r\n\t// preserve the top offset of the first shown item so that there's\r\n\t// no \"content jumping\".\r\n\t//\r\n\t// If `setItems()` update was an \"incremental\" one but there're\r\n\t// some prepended items, then it means that now there're new items\r\n\t// with unknown heights at the top, so the top offset of the first\r\n\t// shown item won't be preserved because there're no \"before resize\"\r\n\t// heights of those items.\r\n\t//\r\n\t// If `setItems()` update was not an \"incremental\" one, then don't\r\n\t// attempt to restore previous item heights after a potential window\r\n\t// width change because all item heights have been reset.\r\n\t//\r\n\tthis.shouldDiscardBeforeResizeItemHeights = () => {\r\n\t\tif (this.newItemsWillBeRendered) {\r\n\t\t\tconst { prepend, replace } = this.newItemsWillBeRendered\r\n\t\t\treturn prepend || replace\r\n\t\t}\r\n\t}\r\n}"],"mappings":"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"}