virtual-scroller 1.16.3 → 1.16.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +72 -36
- package/bundle/virtual-scroller-dom.js +1 -1
- package/bundle/virtual-scroller-dom.js.map +1 -1
- package/bundle/virtual-scroller-react.js +1 -1
- package/bundle/virtual-scroller-react.js.map +1 -1
- package/bundle/virtual-scroller.js +1 -1
- package/bundle/virtual-scroller.js.map +1 -1
- package/commonjs/DOM/ListTopOffsetWatcher.js +2 -4
- package/commonjs/DOM/ListTopOffsetWatcher.js.map +1 -1
- package/commonjs/Scroll.js +8 -11
- package/commonjs/Scroll.js.map +1 -1
- package/commonjs/VirtualScroller.constructor.js +7 -8
- package/commonjs/VirtualScroller.constructor.js.map +1 -1
- package/commonjs/VirtualScroller.js +10 -1
- package/commonjs/VirtualScroller.js.map +1 -1
- package/commonjs/VirtualScroller.layout.js +62 -20
- package/commonjs/VirtualScroller.layout.js.map +1 -1
- package/commonjs/VirtualScroller.onRender.js +25 -2
- package/commonjs/VirtualScroller.onRender.js.map +1 -1
- package/commonjs/VirtualScroller.state.js +39 -0
- package/commonjs/VirtualScroller.state.js.map +1 -1
- package/commonjs/react/useCreateVirtualScroller.js +1 -1
- package/commonjs/react/useCreateVirtualScroller.js.map +1 -1
- package/commonjs/test/VirtualScroller.js +2 -1
- package/commonjs/test/VirtualScroller.js.map +1 -1
- package/commonjs/utility/scheduleOnNextTick.js +25 -0
- package/commonjs/utility/scheduleOnNextTick.js.map +1 -0
- package/index.d.ts +4 -0
- package/modules/DOM/ListTopOffsetWatcher.js +1 -6
- package/modules/DOM/ListTopOffsetWatcher.js.map +1 -1
- package/modules/Scroll.js +8 -11
- package/modules/Scroll.js.map +1 -1
- package/modules/VirtualScroller.constructor.js +7 -8
- package/modules/VirtualScroller.constructor.js.map +1 -1
- package/modules/VirtualScroller.js +9 -1
- package/modules/VirtualScroller.js.map +1 -1
- package/modules/VirtualScroller.layout.js +61 -23
- package/modules/VirtualScroller.layout.js.map +1 -1
- package/modules/VirtualScroller.onRender.js +24 -2
- package/modules/VirtualScroller.onRender.js.map +1 -1
- package/modules/VirtualScroller.state.js +39 -1
- package/modules/VirtualScroller.state.js.map +1 -1
- package/modules/react/useCreateVirtualScroller.js +1 -1
- package/modules/react/useCreateVirtualScroller.js.map +1 -1
- package/modules/test/VirtualScroller.js +2 -1
- package/modules/test/VirtualScroller.js.map +1 -1
- package/modules/utility/scheduleOnNextTick.js +15 -0
- package/modules/utility/scheduleOnNextTick.js.map +1 -0
- package/package.json +1 -1
- package/source/DOM/ListTopOffsetWatcher.js +0 -6
- package/source/Scroll.js +7 -9
- package/source/VirtualScroller.constructor.js +7 -7
- package/source/VirtualScroller.js +8 -0
- package/source/VirtualScroller.layout.js +61 -25
- package/source/VirtualScroller.onRender.js +29 -3
- package/source/VirtualScroller.state.js +38 -0
- package/source/react/useCreateVirtualScroller.js +1 -1
- package/source/test/VirtualScroller.js +2 -1
- package/source/utility/scheduleOnNextTick.js +16 -0
|
@@ -15,6 +15,8 @@ var _BeforeResize = require("./BeforeResize.js");
|
|
|
15
15
|
|
|
16
16
|
var _getStateSnapshot = _interopRequireDefault(require("./utility/getStateSnapshot.js"));
|
|
17
17
|
|
|
18
|
+
var _scheduleOnNextTick = require("./utility/scheduleOnNextTick.js");
|
|
19
|
+
|
|
18
20
|
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); }
|
|
19
21
|
|
|
20
22
|
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; }
|
|
@@ -107,6 +109,43 @@ function createStateHelpers(_ref) {
|
|
|
107
109
|
if ((0, _debug.isDebug)()) {
|
|
108
110
|
(0, _debug["default"])('~ Set state ~');
|
|
109
111
|
(0, _debug["default"])((0, _getStateSnapshot["default"])(stateUpdate));
|
|
112
|
+
} // Start tracking the time that elapsed since the start of a state update,
|
|
113
|
+
// because by default a state update causes a "syncrhonous" re-render
|
|
114
|
+
// which could, in turn, require an immediate follow-up re-render,
|
|
115
|
+
// which could again require an immediate follow-up re-render, etc,
|
|
116
|
+
// causing a "synchronous" re-render recursion, potentially freezing the UI.
|
|
117
|
+
//
|
|
118
|
+
// An avalanche of immediate follow-up re-renders usually happens
|
|
119
|
+
// when there're a lot of items in the list — hundreds of thousands —
|
|
120
|
+
// and the user suddenly scrolls down at the very bottom of the list
|
|
121
|
+
// causing a long chain of re-renders when the list starts gradually rendering
|
|
122
|
+
// all the items from top to bottom until it gets to the bottom of the list.
|
|
123
|
+
//
|
|
124
|
+
// In order to prevent freezing the UI in such cases, and to provide the user
|
|
125
|
+
// with the ability to break away from this kind of recursion, `VirtualScroller`
|
|
126
|
+
// has to introduce a momentary delay between successive "synchronous" re-renders.
|
|
127
|
+
//
|
|
128
|
+
// At the same time, it should only introduce such artificial momentary delay
|
|
129
|
+
// when it's really required in order to not hinder the list's performance unnecessarily.
|
|
130
|
+
//
|
|
131
|
+
// A kind of "golen mean" then is to measure the time that a succession of
|
|
132
|
+
// "synchronous" re-renders has already been going for, and interrupt it
|
|
133
|
+
// with a momentary delay if it has been going on for too long.
|
|
134
|
+
// How much's too long? Well, it could be a duration of a single frame.
|
|
135
|
+
//
|
|
136
|
+
// P.S. If this `.updateState()` call was initiated from another `.updateState()` call,
|
|
137
|
+
// i.e. if it was done recursively, then the time tracking will have already been started.
|
|
138
|
+
//
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
if (_this._stateUpdateSequenceStartedAt === undefined) {
|
|
142
|
+
_this._stateUpdateSequenceStartedAt = Date.now(); // Automatically reset `this._stateUpdateSequenceStartedAt` variable on "next tick",
|
|
143
|
+
// i.e. outside of a "synchronous" recursion.
|
|
144
|
+
|
|
145
|
+
_this._stateUpdateSequenceStartedAtResetTimer = (0, _scheduleOnNextTick.scheduleOnNextTick)(function () {
|
|
146
|
+
_this._stateUpdateSequenceStartedAtResetTimer = undefined;
|
|
147
|
+
_this._stateUpdateSequenceStartedAt = undefined;
|
|
148
|
+
});
|
|
110
149
|
} // Ensure that a non-initial `stateUpdate` can only contain an `items`
|
|
111
150
|
// property when it comes from a `setItems()` call.
|
|
112
151
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualScroller.state.js","names":["createStateHelpers","initialState","state","getInitialItemState","onStateChange","render","initialItems","items","_render","_setItemState","itemOrIndex","newItemState","i","_getItemIndexByItemOrIndex","undefined","isDebug","log","JSON","stringify","getState","itemStates","newItemsWillBeRendered","itemStatesThatChangedWhileNewItemsWereBeingRendered","String","_getState","updateState","stateUpdate","getStateSnapshot","_isSettingNewItems","reportError","waitingForRender","previousState","mostRecentSetStateValue","_setState","getInitialState","getRestoredState","call","getInitialStateFromScratch","useState","setState","_isActive","Error","_usesCustomStateStorage","newState","useDefaultStateStorage","defaultGetState","bind","defaultSetState","setInitialState","defaultSetInitialState","setUpState","onRender","getInitialLayoutState","beforeStart","fillArray","Array","length","firstShownItemIndex","lastShownItemIndex","cleanUpBeforeResizeState","verticalSpacing","isStateColumnsCountMismatch","columnsCount","getActualColumnsCount","warn","itemsCount","layout","getInitialLayoutValues","beforeItemsHeight","afterItemsHeight","itemHeights","onBeforeShowItems","getActualColumnsCountForState","stateColumnsCount","Math","floor"],"sources":["../source/VirtualScroller.state.js"],"sourcesContent":["import fillArray from './utility/fillArray.js'\r\nimport log, { warn, isDebug, reportError } from './utility/debug.js'\r\nimport { cleanUpBeforeResizeState } from './BeforeResize.js'\r\nimport getStateSnapshot from './utility/getStateSnapshot.js'\r\n\r\n// There're three main places where state is updated:\r\n//\r\n// * On scroll.\r\n// * On window resize.\r\n// * On set new items.\r\n//\r\n// State updates may be \"asynchronous\" (like in React), in which case the\r\n// corresponding operation is \"pending\" until the state update is applied.\r\n//\r\n// If there's a \"pending\" window resize or a \"pending\" update of the set of items,\r\n// then \"on scroll\" updates aren't dispatched.\r\n//\r\n// If there's a \"pending\" on scroll update and the window is resize or a new set\r\n// of items is set, then that \"pending\" on scroll update gets overwritten.\r\n//\r\n// If there's a \"pending\" update of the set of items, then window resize handler\r\n// sees that \"pending\" update and dispatches its own state update so that the\r\n// \"pending\" state update originating from `setItems()` is not lost.\r\n//\r\n// If there's a \"pending\" window resize, and a new set of items is set,\r\n// then the state update of the window resize handler gets overwritten.\r\n\r\nexport default function createStateHelpers({\r\n\tstate: initialState,\r\n\tgetInitialItemState,\r\n\tonStateChange,\r\n\trender,\r\n\titems: initialItems\r\n}) {\r\n\tthis.onStateChange = onStateChange\r\n\tthis._render = render\r\n\r\n\tthis.getInitialItemState = getInitialItemState\r\n\r\n\tthis._setItemState = (itemOrIndex, newItemState) => {\r\n\t\t// Item index.\r\n\t\tconst i = this._getItemIndexByItemOrIndex(itemOrIndex)\r\n\r\n\t\t// If the item wasn't found, the error was already reported,\r\n\t\t// so just return some \"sensible\" default value.\r\n\t\tif (i === undefined) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('~ Item state changed ~')\r\n\t\t\tlog('Item index', i)\r\n\t\t\t// Uses `JSON.stringify()` here instead of just outputting the JSON objects as is\r\n\t\t\t// because outputting JSON objects as is would show different results later when\r\n\t\t\t// the developer inspects those in the web browser console if those state objects\r\n\t\t\t// get modified in between they've been output to the console and the developer\r\n\t\t\t// decided to inspect them.\r\n\t\t\tlog('Previous state' + '\\n' + JSON.stringify(this.getState().itemStates[i], null, 2))\r\n\t\t\tlog('New state' + '\\n' + JSON.stringify(newItemState, null, 2))\r\n\t\t}\r\n\r\n\t\tthis.getState().itemStates[i] = newItemState\r\n\r\n\t\t// If there was a request for `setState()` with new `items`, then the changes\r\n\t\t// to `currentState.itemStates[]` made above would be overwritten when that\r\n\t\t// pending `setState()` call gets applied.\r\n\t\t// To fix that, the updates to current `itemStates[]` are noted in\r\n\t\t// `this.itemStatesThatChangedWhileNewItemsWereBeingRendered` variable.\r\n\t\t// That variable is then checked when the `setState()` call with the new `items`\r\n\t\t// has been updated.\r\n\t\tif (this.newItemsWillBeRendered) {\r\n\t\t\tif (!this.itemStatesThatChangedWhileNewItemsWereBeingRendered) {\r\n\t\t\t\tthis.itemStatesThatChangedWhileNewItemsWereBeingRendered = {}\r\n\t\t\t}\r\n\t\t\tthis.itemStatesThatChangedWhileNewItemsWereBeingRendered[String(i)] = newItemState\r\n\t\t}\r\n\t}\r\n\r\n\tthis.getState = () => this._getState()\r\n\r\n\tthis.updateState = (stateUpdate) => {\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('~ Set state ~')\r\n\t\t\tlog(getStateSnapshot(stateUpdate))\r\n\t\t}\r\n\r\n\t\t// Ensure that a non-initial `stateUpdate` can only contain an `items`\r\n\t\t// property when it comes from a `setItems()` call.\r\n\t\tif (stateUpdate.items) {\r\n\t\t\tif (!this._isSettingNewItems) {\r\n\t\t\t\treportError('A `stateUpdate` can only contain `items` property as a result of calling `.setItems()`')\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis._isSettingNewItems = undefined\r\n\r\n\t\tthis.waitingForRender = true\r\n\r\n\t\t// Store previous `state`.\r\n\t\tthis.previousState = this.getState()\r\n\r\n\t\t// If it's the first call to `this.updateState()` then initialize\r\n\t\t// the most recent `setState()` value to be the current state.\r\n\t\tif (!this.mostRecentSetStateValue) {\r\n\t\t\tthis.mostRecentSetStateValue = this.getState()\r\n\t\t}\r\n\r\n\t\t// Accumulates all \"pending\" state updates until they have been applied.\r\n\t\tthis.mostRecentSetStateValue = {\r\n\t\t\t...this.mostRecentSetStateValue,\r\n\t\t\t...stateUpdate\r\n\t\t}\r\n\r\n\t\t// Update `state`.\r\n\t\tthis._setState(this.mostRecentSetStateValue, stateUpdate)\r\n\t}\r\n\r\n\tthis.getInitialState = () => {\r\n\t\tif (initialState) {\r\n\t\t\treturn getRestoredState.call(this, initialState)\r\n\t\t}\r\n\t\treturn getInitialStateFromScratch.call(this, { getInitialItemState })\r\n\t}\r\n\r\n\tthis.useState = ({\r\n\t\tgetState,\r\n\t\tsetState,\r\n\t\tupdateState\r\n\t}) => {\r\n\t\tif (this._isActive) {\r\n\t\t\tthrow new Error('[virtual-scroller] `VirtualScroller` has already been started')\r\n\t\t}\r\n\r\n\t\tif (this._getState) {\r\n\t\t\tthrow new Error('[virtual-scroller] Custom state storage has already been configured')\r\n\t\t}\r\n\r\n\t\tif (render) {\r\n\t\t\tthrow new Error('[virtual-scroller] Creating a `VirtualScroller` class instance with a `render()` parameter implies using the default (internal) state storage')\r\n\t\t}\r\n\r\n\t\tif (setState && updateState) {\r\n\t\t\tthrow new Error('[virtual-scroller] When using a custom state storage, one must supply either `setState()` or `updateState()` function but not both')\r\n\t\t}\r\n\r\n\t\tif (!getState || !(setState || updateState)) {\r\n\t\t\tthrow new Error('[virtual-scroller] When using a custom state storage, one must supply both `getState()` and `setState()`/`updateState()` functions')\r\n\t\t}\r\n\r\n\t\tthis._usesCustomStateStorage = true\r\n\r\n\t\tthis._getState = getState\r\n\r\n\t\tthis._setState = (newState, stateUpdate) => {\r\n\t\t\tif (setState) {\r\n\t\t\t\tsetState(newState)\r\n\t\t\t} else {\r\n\t\t\t\tupdateState(stateUpdate)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tthis.useDefaultStateStorage = () => {\r\n\t\tif (!render) {\r\n\t\t\tthrow new Error('[virtual-scroller] When using the default (internal) state management, one must supply a `render(state, prevState)` function parameter')\r\n\t\t}\r\n\r\n\t\t// Create default `getState()`/`setState()` functions.\r\n\t\tthis._getState = defaultGetState.bind(this)\r\n\t\tthis._setState = defaultSetState.bind(this)\r\n\r\n\t\t// When `state` is stored externally, a developer is responsible for\r\n\t\t// initializing it with the initial value.\r\n\t\t// Otherwise, if default state management is used, set the initial state now.\r\n\t\tconst setInitialState = defaultSetInitialState.bind(this)\r\n\t\tsetInitialState(this.getInitialState())\r\n\t}\r\n\r\n\tthis.setUpState = () => {\r\n\t\t// If no custom state storage has been configured, use the default one.\r\n\t\t// Also sets the initial state.\r\n\t\tif (!this._usesCustomStateStorage) {\r\n\t\t\tthis.useDefaultStateStorage()\r\n\t\t}\r\n\t}\r\n\r\n\tfunction defaultGetState() {\r\n\t\treturn this.state\r\n\t}\r\n\r\n\tfunction defaultSetInitialState(newState) {\r\n\t\tthis.state = newState\r\n\t}\r\n\r\n\tfunction defaultSetState(newState, stateUpdate) {\r\n\t\t// // Because the default state updates are \"synchronous\" (immediate),\r\n\t\t// // the `...stateUpdate` could be applied over `...this.state`,\r\n\t\t// // and no state updates would be lost.\r\n\t\t// // But if it was \"asynchronous\" (not immediate), then `...this.state`\r\n\t\t// // wouldn't work in all cases, because it could be stale in cases\r\n\t\t// // when more than a single `setState()` call is made before\r\n\t\t// // the state actually updates, making some properties of `this.state` stale.\r\n\t\t// this.state = {\r\n\t\t// \t...this.state,\r\n\t\t// \t...stateUpdate\r\n\t\t// }\r\n\r\n\t\tthis.state = newState\r\n\r\n\t\trender(this.state, this.previousState)\r\n\r\n\t\tthis.onRender()\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the initial state of the `VirtualScroller` \"from scratch\".\r\n\t * (i.e. not from a previously saved one).\r\n\t * @param {function} [options.getInitialItemState] — Gets initial item state.\r\n\t * @return {object}\r\n\t */\r\n\tfunction getInitialStateFromScratch({ getInitialItemState }) {\r\n\t\tconst items = initialItems\r\n\r\n\t\tconst state = {\r\n\t\t\t...getInitialLayoutState.call(this, items, { beforeStart: true }),\r\n\t\t\titems,\r\n\t\t\titemStates: fillArray(new Array(items.length), (i) => getInitialItemState(items[i]))\r\n\t\t}\r\n\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('Initial state (autogenerated)', getStateSnapshot(state))\r\n\t\t}\r\n\t\tlog('First shown item index', state.firstShownItemIndex)\r\n\t\tlog('Last shown item index', state.lastShownItemIndex)\r\n\r\n\t\treturn state\r\n\t}\r\n\r\n\tfunction getRestoredState(state) {\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('Restore state', getStateSnapshot(state))\r\n\t\t}\r\n\r\n\t\t// Possibly clean up \"before resize\" property in state.\r\n\t\t// \"Before resize\" state property is cleaned up when all \"before resize\" item heights\r\n\t\t// have been re-measured in an asynchronous `this.updateState({ beforeResize: undefined })` call.\r\n\t\t// If `VirtualScroller` state was snapshotted externally before that `this.updateState()` call\r\n\t\t// has been applied, then \"before resize\" property might have not been cleaned up properly.\r\n\t\tstate = cleanUpBeforeResizeState(state)\r\n\r\n\t\t// Reset `verticalSpacing` so that it re-measures it after the list\r\n\t\t// has been rendered initially. The rationale is that a previously captured\r\n\t\t// inter-item vertical spacing can't be \"trusted\" in a sense that the user\r\n\t\t// might have resized the window after the previous `state` has been snapshotted.\r\n\t\t// If the user has resized the window, then changing window width might have\r\n\t\t// activated different CSS `@media()` \"queries\" resulting in a potentially different\r\n\t\t// vertical spacing when the `VirtualScroller` is re-created with such previously\r\n\t\t// snapshotted state.\r\n\t\tstate = {\r\n\t\t\t...state,\r\n\t\t\tverticalSpacing: undefined\r\n\t\t}\r\n\r\n\t\t// `this.verticalSpacing` acts as a \"true\" source for vertical spacing value.\r\n\t\t// Vertical spacing is also stored in `state` but `state` updates could be\r\n\t\t// \"asynchronous\" (not applied immediately) and `this.onUpdateShownItemIndexes()`\r\n\t\t// requires vertical spacing to be correct at any time, without any delays.\r\n\t\t// So, vertical spacing is also duplicated in `state`, but the \"true\" source\r\n\t\t// is still `this.verticalSpacing`.\r\n\t\t//\r\n\t\t// `this.verticalSpacing` must be initialized before calling `this.getInitialStateFromScratch()`\r\n\t\t// because `this.getInitialStateFromScratch()` uses `this.verticalSpacing` in its calculations.\r\n\t\t//\r\n\t\t// With the code above, `state.verticalSpacing` is always gonna be `undefined`,\r\n\t\t// so commented out this code. It's safer to just re-measure vertical spacing\r\n\t\t// from scratch when `VirtualScroller` is mounted.\r\n\t\t//\r\n\t\t// this.verticalSpacing = state ? state.verticalSpacing : undefined\r\n\r\n\t\t// Check if the actual `columnsCount` on the screen matches the one from state.\r\n\t\tif (isStateColumnsCountMismatch(state, {\r\n\t\t\tcolumnsCount: this.getActualColumnsCount()\r\n\t\t})) {\r\n\t\t\twarn('Reset Layout')\r\n\t\t\tstate = {\r\n\t\t\t\t...state,\r\n\t\t\t\t...getInitialLayoutState.call(this, state.items, { beforeStart: false })\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn state\r\n\t}\r\n\r\n\tfunction getInitialLayoutState(items, { beforeStart }) {\r\n\t\tconst itemsCount = items.length\r\n\r\n\t\tconst {\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex,\r\n\t\t\tbeforeItemsHeight,\r\n\t\t\tafterItemsHeight\r\n\t\t} = this.layout.getInitialLayoutValues({\r\n\t\t\titemsCount,\r\n\t\t\tcolumnsCount: this.getActualColumnsCount(),\r\n\t\t\tbeforeStart\r\n\t\t})\r\n\r\n\t\tconst itemHeights = new Array(itemsCount)\r\n\r\n\t\t// Optionally preload items to be rendered.\r\n\t\tthis.onBeforeShowItems(\r\n\t\t\titems,\r\n\t\t\titemHeights,\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex\r\n\t\t)\r\n\r\n\t\treturn {\r\n\t\t\titemHeights,\r\n\t\t\tcolumnsCount: this.getActualColumnsCountForState(),\r\n\t\t\tverticalSpacing: this.verticalSpacing,\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex,\r\n\t\t\tbeforeItemsHeight,\r\n\t\t\tafterItemsHeight\r\n\t\t}\r\n\t}\r\n\r\n\t// Checks if the actual `columnsCount` on the screen matches the one from state.\r\n\t//\r\n\t// For example, a developer might snapshot `VirtualScroller` state\r\n\t// when the user navigates from the page containing the list\r\n\t// in order to later restore the list's state when the user goes \"Back\".\r\n\t// But, the user might have also resized the window while being on that\r\n\t// \"other\" page, and when they come \"Back\", their snapshotted state\r\n\t// no longer qualifies. Well, it does qualify, but only partially.\r\n\t// For example, `itemStates` are still valid, but first and last shown\r\n\t// item indexes aren't.\r\n\t//\r\n\tfunction isStateColumnsCountMismatch(state, { columnsCount }) {\r\n\t\tconst stateColumnsCount = state.columnsCount || 1\r\n\t\tif (stateColumnsCount !== columnsCount) {\r\n\t\t\twarn('~ Columns Count changed from', stateColumnsCount, 'to', columnsCount, '~')\r\n\t\t\treturn true\r\n\t\t}\r\n\t\tconst firstShownItemIndex = Math.floor(state.firstShownItemIndex / columnsCount) * columnsCount\r\n\t\tif (firstShownItemIndex !== state.firstShownItemIndex) {\r\n\t\t\twarn('~ First Shown Item Index', state.firstShownItemIndex, 'is not divisible by Columns Count', columnsCount, '~')\r\n\t\t\treturn true\r\n\t\t}\r\n\t}\r\n}"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VirtualScroller.state.js","names":["createStateHelpers","initialState","state","getInitialItemState","onStateChange","render","initialItems","items","_render","_setItemState","itemOrIndex","newItemState","i","_getItemIndexByItemOrIndex","undefined","isDebug","log","JSON","stringify","getState","itemStates","newItemsWillBeRendered","itemStatesThatChangedWhileNewItemsWereBeingRendered","String","_getState","updateState","stateUpdate","getStateSnapshot","_stateUpdateSequenceStartedAt","Date","now","_stateUpdateSequenceStartedAtResetTimer","scheduleOnNextTick","_isSettingNewItems","reportError","waitingForRender","previousState","mostRecentSetStateValue","_setState","getInitialState","getRestoredState","call","getInitialStateFromScratch","useState","setState","_isActive","Error","_usesCustomStateStorage","newState","useDefaultStateStorage","defaultGetState","bind","defaultSetState","setInitialState","defaultSetInitialState","setUpState","onRender","getInitialLayoutState","beforeStart","fillArray","Array","length","firstShownItemIndex","lastShownItemIndex","cleanUpBeforeResizeState","verticalSpacing","isStateColumnsCountMismatch","columnsCount","getActualColumnsCount","warn","itemsCount","layout","getInitialLayoutValues","beforeItemsHeight","afterItemsHeight","itemHeights","onBeforeShowItems","getActualColumnsCountForState","stateColumnsCount","Math","floor"],"sources":["../source/VirtualScroller.state.js"],"sourcesContent":["import fillArray from './utility/fillArray.js'\r\nimport log, { warn, isDebug, reportError } from './utility/debug.js'\r\nimport { cleanUpBeforeResizeState } from './BeforeResize.js'\r\nimport getStateSnapshot from './utility/getStateSnapshot.js'\r\nimport { scheduleOnNextTick } from './utility/scheduleOnNextTick.js'\r\n\r\n// There're three main places where state is updated:\r\n//\r\n// * On scroll.\r\n// * On window resize.\r\n// * On set new items.\r\n//\r\n// State updates may be \"asynchronous\" (like in React), in which case the\r\n// corresponding operation is \"pending\" until the state update is applied.\r\n//\r\n// If there's a \"pending\" window resize or a \"pending\" update of the set of items,\r\n// then \"on scroll\" updates aren't dispatched.\r\n//\r\n// If there's a \"pending\" on scroll update and the window is resize or a new set\r\n// of items is set, then that \"pending\" on scroll update gets overwritten.\r\n//\r\n// If there's a \"pending\" update of the set of items, then window resize handler\r\n// sees that \"pending\" update and dispatches its own state update so that the\r\n// \"pending\" state update originating from `setItems()` is not lost.\r\n//\r\n// If there's a \"pending\" window resize, and a new set of items is set,\r\n// then the state update of the window resize handler gets overwritten.\r\n\r\nexport default function createStateHelpers({\r\n\tstate: initialState,\r\n\tgetInitialItemState,\r\n\tonStateChange,\r\n\trender,\r\n\titems: initialItems\r\n}) {\r\n\tthis.onStateChange = onStateChange\r\n\tthis._render = render\r\n\r\n\tthis.getInitialItemState = getInitialItemState\r\n\r\n\tthis._setItemState = (itemOrIndex, newItemState) => {\r\n\t\t// Item index.\r\n\t\tconst i = this._getItemIndexByItemOrIndex(itemOrIndex)\r\n\r\n\t\t// If the item wasn't found, the error was already reported,\r\n\t\t// so just return some \"sensible\" default value.\r\n\t\tif (i === undefined) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('~ Item state changed ~')\r\n\t\t\tlog('Item index', i)\r\n\t\t\t// Uses `JSON.stringify()` here instead of just outputting the JSON objects as is\r\n\t\t\t// because outputting JSON objects as is would show different results later when\r\n\t\t\t// the developer inspects those in the web browser console if those state objects\r\n\t\t\t// get modified in between they've been output to the console and the developer\r\n\t\t\t// decided to inspect them.\r\n\t\t\tlog('Previous state' + '\\n' + JSON.stringify(this.getState().itemStates[i], null, 2))\r\n\t\t\tlog('New state' + '\\n' + JSON.stringify(newItemState, null, 2))\r\n\t\t}\r\n\r\n\t\tthis.getState().itemStates[i] = newItemState\r\n\r\n\t\t// If there was a request for `setState()` with new `items`, then the changes\r\n\t\t// to `currentState.itemStates[]` made above would be overwritten when that\r\n\t\t// pending `setState()` call gets applied.\r\n\t\t// To fix that, the updates to current `itemStates[]` are noted in\r\n\t\t// `this.itemStatesThatChangedWhileNewItemsWereBeingRendered` variable.\r\n\t\t// That variable is then checked when the `setState()` call with the new `items`\r\n\t\t// has been updated.\r\n\t\tif (this.newItemsWillBeRendered) {\r\n\t\t\tif (!this.itemStatesThatChangedWhileNewItemsWereBeingRendered) {\r\n\t\t\t\tthis.itemStatesThatChangedWhileNewItemsWereBeingRendered = {}\r\n\t\t\t}\r\n\t\t\tthis.itemStatesThatChangedWhileNewItemsWereBeingRendered[String(i)] = newItemState\r\n\t\t}\r\n\t}\r\n\r\n\tthis.getState = () => this._getState()\r\n\r\n\tthis.updateState = (stateUpdate) => {\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('~ Set state ~')\r\n\t\t\tlog(getStateSnapshot(stateUpdate))\r\n\t\t}\r\n\r\n\t\t// Start tracking the time that elapsed since the start of a state update,\r\n\t\t// because by default a state update causes a \"syncrhonous\" re-render\r\n\t\t// which could, in turn, require an immediate follow-up re-render,\r\n\t\t// which could again require an immediate follow-up re-render, etc,\r\n\t\t// causing a \"synchronous\" re-render recursion, potentially freezing the UI.\r\n\t\t//\r\n\t\t// An avalanche of immediate follow-up re-renders usually happens\r\n\t\t// when there're a lot of items in the list — hundreds of thousands —\r\n\t\t// and the user suddenly scrolls down at the very bottom of the list\r\n\t\t// causing a long chain of re-renders when the list starts gradually rendering\r\n\t\t// all the items from top to bottom until it gets to the bottom of the list.\r\n\t\t//\r\n\t\t// In order to prevent freezing the UI in such cases, and to provide the user\r\n\t\t// with the ability to break away from this kind of recursion, `VirtualScroller`\r\n\t\t// has to introduce a momentary delay between successive \"synchronous\" re-renders.\r\n\t\t//\r\n\t\t// At the same time, it should only introduce such artificial momentary delay\r\n\t\t// when it's really required in order to not hinder the list's performance unnecessarily.\r\n\t\t//\r\n\t\t// A kind of \"golen mean\" then is to measure the time that a succession of\r\n\t\t// \"synchronous\" re-renders has already been going for, and interrupt it\r\n\t\t// with a momentary delay if it has been going on for too long.\r\n\t\t// How much's too long? Well, it could be a duration of a single frame.\r\n\t\t//\r\n\t\t// P.S. If this `.updateState()` call was initiated from another `.updateState()` call,\r\n\t\t// i.e. if it was done recursively, then the time tracking will have already been started.\r\n\t\t//\r\n\t\tif (this._stateUpdateSequenceStartedAt === undefined) {\r\n\t\t\tthis._stateUpdateSequenceStartedAt = Date.now()\r\n\t\t\t// Automatically reset `this._stateUpdateSequenceStartedAt` variable on \"next tick\",\r\n\t\t\t// i.e. outside of a \"synchronous\" recursion.\r\n\t\t\tthis._stateUpdateSequenceStartedAtResetTimer = scheduleOnNextTick(() => {\r\n\t\t\t\tthis._stateUpdateSequenceStartedAtResetTimer = undefined\r\n\t\t\t\tthis._stateUpdateSequenceStartedAt = undefined\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\t// Ensure that a non-initial `stateUpdate` can only contain an `items`\r\n\t\t// property when it comes from a `setItems()` call.\r\n\t\tif (stateUpdate.items) {\r\n\t\t\tif (!this._isSettingNewItems) {\r\n\t\t\t\treportError('A `stateUpdate` can only contain `items` property as a result of calling `.setItems()`')\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis._isSettingNewItems = undefined\r\n\r\n\t\tthis.waitingForRender = true\r\n\r\n\t\t// Store previous `state`.\r\n\t\tthis.previousState = this.getState()\r\n\r\n\t\t// If it's the first call to `this.updateState()` then initialize\r\n\t\t// the most recent `setState()` value to be the current state.\r\n\t\tif (!this.mostRecentSetStateValue) {\r\n\t\t\tthis.mostRecentSetStateValue = this.getState()\r\n\t\t}\r\n\r\n\t\t// Accumulates all \"pending\" state updates until they have been applied.\r\n\t\tthis.mostRecentSetStateValue = {\r\n\t\t\t...this.mostRecentSetStateValue,\r\n\t\t\t...stateUpdate\r\n\t\t}\r\n\r\n\t\t// Update `state`.\r\n\t\tthis._setState(this.mostRecentSetStateValue, stateUpdate)\r\n\t}\r\n\r\n\tthis.getInitialState = () => {\r\n\t\tif (initialState) {\r\n\t\t\treturn getRestoredState.call(this, initialState)\r\n\t\t}\r\n\t\treturn getInitialStateFromScratch.call(this, { getInitialItemState })\r\n\t}\r\n\r\n\tthis.useState = ({\r\n\t\tgetState,\r\n\t\tsetState,\r\n\t\tupdateState\r\n\t}) => {\r\n\t\tif (this._isActive) {\r\n\t\t\tthrow new Error('[virtual-scroller] `VirtualScroller` has already been started')\r\n\t\t}\r\n\r\n\t\tif (this._getState) {\r\n\t\t\tthrow new Error('[virtual-scroller] Custom state storage has already been configured')\r\n\t\t}\r\n\r\n\t\tif (render) {\r\n\t\t\tthrow new Error('[virtual-scroller] Creating a `VirtualScroller` class instance with a `render()` parameter implies using the default (internal) state storage')\r\n\t\t}\r\n\r\n\t\tif (setState && updateState) {\r\n\t\t\tthrow new Error('[virtual-scroller] When using a custom state storage, one must supply either `setState()` or `updateState()` function but not both')\r\n\t\t}\r\n\r\n\t\tif (!getState || !(setState || updateState)) {\r\n\t\t\tthrow new Error('[virtual-scroller] When using a custom state storage, one must supply both `getState()` and `setState()`/`updateState()` functions')\r\n\t\t}\r\n\r\n\t\tthis._usesCustomStateStorage = true\r\n\r\n\t\tthis._getState = getState\r\n\r\n\t\tthis._setState = (newState, stateUpdate) => {\r\n\t\t\tif (setState) {\r\n\t\t\t\tsetState(newState)\r\n\t\t\t} else {\r\n\t\t\t\tupdateState(stateUpdate)\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tthis.useDefaultStateStorage = () => {\r\n\t\tif (!render) {\r\n\t\t\tthrow new Error('[virtual-scroller] When using the default (internal) state management, one must supply a `render(state, prevState)` function parameter')\r\n\t\t}\r\n\r\n\t\t// Create default `getState()`/`setState()` functions.\r\n\t\tthis._getState = defaultGetState.bind(this)\r\n\t\tthis._setState = defaultSetState.bind(this)\r\n\r\n\t\t// When `state` is stored externally, a developer is responsible for\r\n\t\t// initializing it with the initial value.\r\n\t\t// Otherwise, if default state management is used, set the initial state now.\r\n\t\tconst setInitialState = defaultSetInitialState.bind(this)\r\n\t\tsetInitialState(this.getInitialState())\r\n\t}\r\n\r\n\tthis.setUpState = () => {\r\n\t\t// If no custom state storage has been configured, use the default one.\r\n\t\t// Also sets the initial state.\r\n\t\tif (!this._usesCustomStateStorage) {\r\n\t\t\tthis.useDefaultStateStorage()\r\n\t\t}\r\n\t}\r\n\r\n\tfunction defaultGetState() {\r\n\t\treturn this.state\r\n\t}\r\n\r\n\tfunction defaultSetInitialState(newState) {\r\n\t\tthis.state = newState\r\n\t}\r\n\r\n\tfunction defaultSetState(newState, stateUpdate) {\r\n\t\t// // Because the default state updates are \"synchronous\" (immediate),\r\n\t\t// // the `...stateUpdate` could be applied over `...this.state`,\r\n\t\t// // and no state updates would be lost.\r\n\t\t// // But if it was \"asynchronous\" (not immediate), then `...this.state`\r\n\t\t// // wouldn't work in all cases, because it could be stale in cases\r\n\t\t// // when more than a single `setState()` call is made before\r\n\t\t// // the state actually updates, making some properties of `this.state` stale.\r\n\t\t// this.state = {\r\n\t\t// \t...this.state,\r\n\t\t// \t...stateUpdate\r\n\t\t// }\r\n\r\n\t\tthis.state = newState\r\n\r\n\t\trender(this.state, this.previousState)\r\n\r\n\t\tthis.onRender()\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the initial state of the `VirtualScroller` \"from scratch\".\r\n\t * (i.e. not from a previously saved one).\r\n\t * @param {function} [options.getInitialItemState] — Gets initial item state.\r\n\t * @return {object}\r\n\t */\r\n\tfunction getInitialStateFromScratch({ getInitialItemState }) {\r\n\t\tconst items = initialItems\r\n\r\n\t\tconst state = {\r\n\t\t\t...getInitialLayoutState.call(this, items, { beforeStart: true }),\r\n\t\t\titems,\r\n\t\t\titemStates: fillArray(new Array(items.length), (i) => getInitialItemState(items[i]))\r\n\t\t}\r\n\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('Initial state (autogenerated)', getStateSnapshot(state))\r\n\t\t}\r\n\t\tlog('First shown item index', state.firstShownItemIndex)\r\n\t\tlog('Last shown item index', state.lastShownItemIndex)\r\n\r\n\t\treturn state\r\n\t}\r\n\r\n\tfunction getRestoredState(state) {\r\n\t\tif (isDebug()) {\r\n\t\t\tlog('Restore state', getStateSnapshot(state))\r\n\t\t}\r\n\r\n\t\t// Possibly clean up \"before resize\" property in state.\r\n\t\t// \"Before resize\" state property is cleaned up when all \"before resize\" item heights\r\n\t\t// have been re-measured in an asynchronous `this.updateState({ beforeResize: undefined })` call.\r\n\t\t// If `VirtualScroller` state was snapshotted externally before that `this.updateState()` call\r\n\t\t// has been applied, then \"before resize\" property might have not been cleaned up properly.\r\n\t\tstate = cleanUpBeforeResizeState(state)\r\n\r\n\t\t// Reset `verticalSpacing` so that it re-measures it after the list\r\n\t\t// has been rendered initially. The rationale is that a previously captured\r\n\t\t// inter-item vertical spacing can't be \"trusted\" in a sense that the user\r\n\t\t// might have resized the window after the previous `state` has been snapshotted.\r\n\t\t// If the user has resized the window, then changing window width might have\r\n\t\t// activated different CSS `@media()` \"queries\" resulting in a potentially different\r\n\t\t// vertical spacing when the `VirtualScroller` is re-created with such previously\r\n\t\t// snapshotted state.\r\n\t\tstate = {\r\n\t\t\t...state,\r\n\t\t\tverticalSpacing: undefined\r\n\t\t}\r\n\r\n\t\t// `this.verticalSpacing` acts as a \"true\" source for vertical spacing value.\r\n\t\t// Vertical spacing is also stored in `state` but `state` updates could be\r\n\t\t// \"asynchronous\" (not applied immediately) and `this.onUpdateShownItemIndexes()`\r\n\t\t// requires vertical spacing to be correct at any time, without any delays.\r\n\t\t// So, vertical spacing is also duplicated in `state`, but the \"true\" source\r\n\t\t// is still `this.verticalSpacing`.\r\n\t\t//\r\n\t\t// `this.verticalSpacing` must be initialized before calling `this.getInitialStateFromScratch()`\r\n\t\t// because `this.getInitialStateFromScratch()` uses `this.verticalSpacing` in its calculations.\r\n\t\t//\r\n\t\t// With the code above, `state.verticalSpacing` is always gonna be `undefined`,\r\n\t\t// so commented out this code. It's safer to just re-measure vertical spacing\r\n\t\t// from scratch when `VirtualScroller` is mounted.\r\n\t\t//\r\n\t\t// this.verticalSpacing = state ? state.verticalSpacing : undefined\r\n\r\n\t\t// Check if the actual `columnsCount` on the screen matches the one from state.\r\n\t\tif (isStateColumnsCountMismatch(state, {\r\n\t\t\tcolumnsCount: this.getActualColumnsCount()\r\n\t\t})) {\r\n\t\t\twarn('Reset Layout')\r\n\t\t\tstate = {\r\n\t\t\t\t...state,\r\n\t\t\t\t...getInitialLayoutState.call(this, state.items, { beforeStart: false })\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn state\r\n\t}\r\n\r\n\tfunction getInitialLayoutState(items, { beforeStart }) {\r\n\t\tconst itemsCount = items.length\r\n\r\n\t\tconst {\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex,\r\n\t\t\tbeforeItemsHeight,\r\n\t\t\tafterItemsHeight\r\n\t\t} = this.layout.getInitialLayoutValues({\r\n\t\t\titemsCount,\r\n\t\t\tcolumnsCount: this.getActualColumnsCount(),\r\n\t\t\tbeforeStart\r\n\t\t})\r\n\r\n\t\tconst itemHeights = new Array(itemsCount)\r\n\r\n\t\t// Optionally preload items to be rendered.\r\n\t\tthis.onBeforeShowItems(\r\n\t\t\titems,\r\n\t\t\titemHeights,\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex\r\n\t\t)\r\n\r\n\t\treturn {\r\n\t\t\titemHeights,\r\n\t\t\tcolumnsCount: this.getActualColumnsCountForState(),\r\n\t\t\tverticalSpacing: this.verticalSpacing,\r\n\t\t\tfirstShownItemIndex,\r\n\t\t\tlastShownItemIndex,\r\n\t\t\tbeforeItemsHeight,\r\n\t\t\tafterItemsHeight\r\n\t\t}\r\n\t}\r\n\r\n\t// Checks if the actual `columnsCount` on the screen matches the one from state.\r\n\t//\r\n\t// For example, a developer might snapshot `VirtualScroller` state\r\n\t// when the user navigates from the page containing the list\r\n\t// in order to later restore the list's state when the user goes \"Back\".\r\n\t// But, the user might have also resized the window while being on that\r\n\t// \"other\" page, and when they come \"Back\", their snapshotted state\r\n\t// no longer qualifies. Well, it does qualify, but only partially.\r\n\t// For example, `itemStates` are still valid, but first and last shown\r\n\t// item indexes aren't.\r\n\t//\r\n\tfunction isStateColumnsCountMismatch(state, { columnsCount }) {\r\n\t\tconst stateColumnsCount = state.columnsCount || 1\r\n\t\tif (stateColumnsCount !== columnsCount) {\r\n\t\t\twarn('~ Columns Count changed from', stateColumnsCount, 'to', columnsCount, '~')\r\n\t\t\treturn true\r\n\t\t}\r\n\t\tconst firstShownItemIndex = Math.floor(state.firstShownItemIndex / columnsCount) * columnsCount\r\n\t\tif (firstShownItemIndex !== state.firstShownItemIndex) {\r\n\t\t\twarn('~ First Shown Item Index', state.firstShownItemIndex, 'is not divisible by Columns Count', columnsCount, '~')\r\n\t\t\treturn true\r\n\t\t}\r\n\t}\r\n}"],"mappings":"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"}
|
|
@@ -35,7 +35,7 @@ function useVirtualScroller(_ref, _ref2) {
|
|
|
35
35
|
return (0, _react.useMemo)(function () {
|
|
36
36
|
// Create `virtual-scroller` instance.
|
|
37
37
|
return new _VirtualScroller["default"](getItemsContainerElement, items, {
|
|
38
|
-
|
|
38
|
+
delayRecursiveRenderUntilNextTick: true,
|
|
39
39
|
// `estimatedItemHeight` is deprecated, use `getEstimatedItemHeight()` instead.
|
|
40
40
|
estimatedItemHeight: estimatedItemHeight,
|
|
41
41
|
getEstimatedItemHeight: getEstimatedItemHeight,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCreateVirtualScroller.js","names":["useVirtualScroller","items","estimatedItemHeight","getEstimatedItemHeight","getEstimatedVisibleItemRowsCount","getEstimatedInterItemVerticalSpacing","bypass","onItemInitialRender","onItemFirstRender","initialScrollPosition","onScrollPositionChange","measureItemsBatchSize","scrollableContainer","getScrollableContainer","getColumnsCount","getItemId","initialState","getInitialItemState","onStateChange","getItemsContainerElement","useMemo","VirtualScroller","
|
|
1
|
+
{"version":3,"file":"useCreateVirtualScroller.js","names":["useVirtualScroller","items","estimatedItemHeight","getEstimatedItemHeight","getEstimatedVisibleItemRowsCount","getEstimatedInterItemVerticalSpacing","bypass","onItemInitialRender","onItemFirstRender","initialScrollPosition","onScrollPositionChange","measureItemsBatchSize","scrollableContainer","getScrollableContainer","getColumnsCount","getItemId","initialState","getInitialItemState","onStateChange","getItemsContainerElement","useMemo","VirtualScroller","delayRecursiveRenderUntilNextTick","state"],"sources":["../../source/react/useCreateVirtualScroller.js"],"sourcesContent":["import { useMemo } from 'react'\r\n\r\nimport VirtualScroller from '../VirtualScroller.js'\r\n\r\n// Creates a `VirtualScroller` instance.\r\nexport default function useVirtualScroller({\r\n\titems,\r\n\t// `estimatedItemHeight` is deprecated, use `getEstimatedItemHeight()` instead.\r\n\testimatedItemHeight,\r\n\tgetEstimatedItemHeight,\r\n\tgetEstimatedVisibleItemRowsCount,\r\n\tgetEstimatedInterItemVerticalSpacing,\r\n\tbypass,\r\n\t// bypassBatchSize,\r\n\tonItemInitialRender,\r\n\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\tonItemFirstRender,\r\n\tinitialScrollPosition,\r\n\tonScrollPositionChange,\r\n\tmeasureItemsBatchSize,\r\n\t// `scrollableContainer` property is deprecated.\r\n\t// Use `getScrollableContainer()` property instead.\r\n\tscrollableContainer,\r\n\tgetScrollableContainer,\r\n\tgetColumnsCount,\r\n\tgetItemId,\r\n\tinitialState,\r\n\tgetInitialItemState,\r\n\tonStateChange\r\n}, {\r\n\tgetItemsContainerElement\r\n}) {\r\n\treturn useMemo(() => {\r\n\t\t// Create `virtual-scroller` instance.\r\n\t\treturn new VirtualScroller(\r\n\t\t\tgetItemsContainerElement,\r\n\t\t\titems,\r\n\t\t\t{\r\n\t\t\t\tdelayRecursiveRenderUntilNextTick: true,\r\n\t\t\t\t// `estimatedItemHeight` is deprecated, use `getEstimatedItemHeight()` instead.\r\n\t\t\t\testimatedItemHeight,\r\n\t\t\t\tgetEstimatedItemHeight,\r\n\t\t\t\tgetEstimatedVisibleItemRowsCount,\r\n\t\t\t\tgetEstimatedInterItemVerticalSpacing,\r\n\t\t\t\tbypass,\r\n\t\t\t\t// bypassBatchSize,\r\n\t\t\t\tonItemInitialRender,\r\n\t\t\t\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\t\t\t\tonItemFirstRender,\r\n\t\t\t\tinitialScrollPosition,\r\n\t\t\t\tonScrollPositionChange,\r\n\t\t\t\tmeasureItemsBatchSize,\r\n\t\t\t\t// `scrollableContainer` property is deprecated.\r\n\t\t\t\t// Use `getScrollableContainer()` property instead.\r\n\t\t\t\tscrollableContainer,\r\n\t\t\t\tgetScrollableContainer,\r\n\t\t\t\tgetColumnsCount,\r\n\t\t\t\tgetItemId,\r\n\t\t\t\tstate: initialState,\r\n\t\t\t\tgetInitialItemState,\r\n\t\t\t\tonStateChange\r\n\t\t\t}\r\n\t\t)\r\n\t}, [])\r\n}"],"mappings":";;;;;;;AAAA;;AAEA;;;;AAEA;AACe,SAASA,kBAAT,cA0BZ;EAAA,IAzBFC,KAyBE,QAzBFA,KAyBE;EAAA,IAvBFC,mBAuBE,QAvBFA,mBAuBE;EAAA,IAtBFC,sBAsBE,QAtBFA,sBAsBE;EAAA,IArBFC,gCAqBE,QArBFA,gCAqBE;EAAA,IApBFC,oCAoBE,QApBFA,oCAoBE;EAAA,IAnBFC,MAmBE,QAnBFA,MAmBE;EAAA,IAjBFC,mBAiBE,QAjBFA,mBAiBE;EAAA,IAfFC,iBAeE,QAfFA,iBAeE;EAAA,IAdFC,qBAcE,QAdFA,qBAcE;EAAA,IAbFC,sBAaE,QAbFA,sBAaE;EAAA,IAZFC,qBAYE,QAZFA,qBAYE;EAAA,IATFC,mBASE,QATFA,mBASE;EAAA,IARFC,sBAQE,QARFA,sBAQE;EAAA,IAPFC,eAOE,QAPFA,eAOE;EAAA,IANFC,SAME,QANFA,SAME;EAAA,IALFC,YAKE,QALFA,YAKE;EAAA,IAJFC,mBAIE,QAJFA,mBAIE;EAAA,IAHFC,aAGE,QAHFA,aAGE;EAAA,IADFC,wBACE,SADFA,wBACE;EACF,OAAO,IAAAC,cAAA,EAAQ,YAAM;IACpB;IACA,OAAO,IAAIC,2BAAJ,CACNF,wBADM,EAENlB,KAFM,EAGN;MACCqB,iCAAiC,EAAE,IADpC;MAEC;MACApB,mBAAmB,EAAnBA,mBAHD;MAICC,sBAAsB,EAAtBA,sBAJD;MAKCC,gCAAgC,EAAhCA,gCALD;MAMCC,oCAAoC,EAApCA,oCAND;MAOCC,MAAM,EAANA,MAPD;MAQC;MACAC,mBAAmB,EAAnBA,mBATD;MAUC;MACAC,iBAAiB,EAAjBA,iBAXD;MAYCC,qBAAqB,EAArBA,qBAZD;MAaCC,sBAAsB,EAAtBA,sBAbD;MAcCC,qBAAqB,EAArBA,qBAdD;MAeC;MACA;MACAC,mBAAmB,EAAnBA,mBAjBD;MAkBCC,sBAAsB,EAAtBA,sBAlBD;MAmBCC,eAAe,EAAfA,eAnBD;MAoBCC,SAAS,EAATA,SApBD;MAqBCQ,KAAK,EAAEP,YArBR;MAsBCC,mBAAmB,EAAnBA,mBAtBD;MAuBCC,aAAa,EAAbA;IAvBD,CAHM,CAAP;EA6BA,CA/BM,EA+BJ,EA/BI,CAAP;AAgCA"}
|
|
@@ -136,7 +136,8 @@ var TestVirtualScroller = /*#__PURE__*/function () {
|
|
|
136
136
|
this.virtualScroller = new _VirtualScroller["default"](getItemsContainerElement, items, {
|
|
137
137
|
scrollableContainer: scrollableContainerElement,
|
|
138
138
|
engine: _Engine["default"],
|
|
139
|
-
|
|
139
|
+
_delayUnnecessaryRerenderUntilStopsScrolling: false,
|
|
140
|
+
delayRecursiveRenderUntilNextTick: false,
|
|
140
141
|
getItemId: getItemId,
|
|
141
142
|
getColumnsCount: getColumnsCount,
|
|
142
143
|
state: initialState,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualScroller.js","names":["DEBUG","TestVirtualScroller","scrollableContainerWidth","screenWidth","scrollableContainerHeight","screenHeight","columnsCount","verticalSpacing","items","getItemId","initialState","state","rest","Object","keys","length","Error","join","expectedStateUpdates","scrollableContainerElement","width","height","containerElement","paddingTop","paddingBottom","children","setScrollableContainerWidth","setScrollableContainerHeight","getItemsContainerElement","__columnsCount","getColumnsCount","getItemWidth","hasPausedStateUpdates","undefined","pausedStateUpdate","pausedStateUpdateAction","onBeforeUpdateState","stateUpdate","expectedStateUpdate","shift","expect","to","deep","equal","callback","render","virtualScroller","getState","beforeItemsHeight","afterItemsHeight","firstShownItemIndex","lastShownItemIndex","slice","map","item","getWidth","getHeight","getArea","area","getMarginTop","VirtualScroller","scrollableContainer","engine","Engine","_waitForScrollingToStop","onStateChange","console","log","getInitialState","useState","updateState","stateUpdateAction","onRender","expectedState","include","push","firstNonMeasuredItemIndex","getScrollY","scrollPosition","scrollToY","updateScreenDimensions","_triggerResizeListener","JSON","stringify","stop","start","updateLayout","itemOrIndex","getItemScrollPosition","onItemHeightDidChange","newState","setItemState","getAverageItemHeight","newItems","options","setItems"],"sources":["../../source/test/VirtualScroller.js"],"sourcesContent":["import { describe, it } from 'mocha'\r\nimport { expect } from 'chai'\r\n\r\nimport VirtualScroller from '../VirtualScroller.js'\r\nimport Engine from './Engine.js'\r\n\r\nconst DEBUG = false\r\n\r\nexport default class TestVirtualScroller {\r\n\tconstructor({\r\n\t\tscreenWidth: scrollableContainerWidth,\r\n\t\tscreenHeight: scrollableContainerHeight,\r\n\t\tcolumnsCount,\r\n\t\tverticalSpacing,\r\n\t\titems,\r\n\t\tgetItemId,\r\n\t\tstate: initialState,\r\n\t\t...rest\r\n\t}) {\r\n\t\t// Validate that no unknown properties are passed.\r\n\t\t// This prevents the cases when a developer confuses\r\n\t\t// `TestVirtualScroller` options for `VirtualScroller` options.\r\n\t\tif (Object.keys(rest).length > 0) {\r\n\t\t\tthrow new Error(`Unknown options: ${Object.keys(rest).join(', ')}`)\r\n\t\t}\r\n\r\n\t\tthis.expectedStateUpdates = []\r\n\r\n\t\tconst scrollableContainerElement = {\r\n\t\t\twidth: scrollableContainerWidth,\r\n\t\t\theight: scrollableContainerHeight\r\n\t\t}\r\n\r\n\t\tconst containerElement = {\r\n\t\t\tpaddingTop: 0,\r\n\t\t\tpaddingBottom: 0,\r\n\t\t\twidth: scrollableContainerElement.width,\r\n\t\t\tchildren: []\r\n\t\t}\r\n\r\n\t\tthis.setScrollableContainerWidth = (width) => {\r\n\t\t\tscrollableContainerElement.width = width\r\n\t\t\tcontainerElement.width = width\r\n\t\t}\r\n\r\n\t\tthis.setScrollableContainerHeight = (height) => {\r\n\t\t\tscrollableContainerElement.height = height\r\n\t\t}\r\n\r\n\t\tconst getItemsContainerElement = () => containerElement\r\n\r\n\t\tthis.__columnsCount = columnsCount\r\n\r\n\t\tconst getColumnsCount = () => this.__columnsCount\r\n\t\tconst getItemWidth = () => scrollableContainerElement.width / getColumnsCount()\r\n\r\n\t\tthis.hasPausedStateUpdates = undefined\r\n\t\tthis.pausedStateUpdate = undefined\r\n\t\tthis.pausedStateUpdateAction = undefined\r\n\r\n\t\tconst onBeforeUpdateState = (stateUpdate) => {\r\n\t\t\tif (this.expectedStateUpdates.length > 0) {\r\n\t\t\t\tconst expectedStateUpdate = this.expectedStateUpdates.shift()\r\n\t\t\t\texpect(stateUpdate).to.deep.equal(expectedStateUpdate.stateUpdate)\r\n\t\t\t\tif (expectedStateUpdate.callback) {\r\n\t\t\t\t\texpectedStateUpdate.callback()\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst render = () => {\r\n\t\t\tconst {\r\n\t\t\t\titems,\r\n\t\t\t\tbeforeItemsHeight,\r\n\t\t\t\tafterItemsHeight,\r\n\t\t\t\tfirstShownItemIndex,\r\n\t\t\t\tlastShownItemIndex\r\n\t\t\t} = this.virtualScroller.getState()\r\n\r\n\t\t\tcontainerElement.paddingTop = beforeItemsHeight\r\n\t\t\tcontainerElement.paddingBottom = afterItemsHeight\r\n\r\n\t\t\tcontainerElement.children = items\r\n\t\t\t\t.slice(firstShownItemIndex, lastShownItemIndex + 1)\r\n\t\t\t\t.map((item) => ({\r\n\t\t\t\t\tgetWidth: () => getItemWidth(),\r\n\t\t\t\t\tgetHeight: () => (item.getArea ? item.getArea() : item.area) / getItemWidth(),\r\n\t\t\t\t\tgetMarginTop: () => verticalSpacing\r\n\t\t\t\t}))\r\n\t\t}\r\n\r\n\t\tthis.virtualScroller = new VirtualScroller(getItemsContainerElement, items, {\r\n\t\t\tscrollableContainer: scrollableContainerElement,\r\n\t\t\tengine: Engine,\r\n\t\t\t_waitForScrollingToStop: false,\r\n\t\t\tgetItemId,\r\n\t\t\tgetColumnsCount,\r\n\t\t\tstate: initialState,\r\n\t\t\tonStateChange(state) {\r\n\t\t\t\tif (DEBUG) {\r\n\t\t\t\t\tconsole.log('~ Updated State ~')\r\n\t\t\t\t\tconsole.log(state)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\tlet state = this.virtualScroller.getInitialState()\r\n\r\n\t\tthis.virtualScroller.useState({\r\n\t\t\tgetState: () => state,\r\n\t\t\tupdateState: (stateUpdate) => {\r\n\t\t\t\tconst stateUpdateAction = (stateUpdate) => {\r\n\t\t\t\t\t// Is only used in tests.\r\n\t\t\t\t\tif (onBeforeUpdateState) {\r\n\t\t\t\t\t\tonBeforeUpdateState(stateUpdate)\r\n\t\t\t\t\t}\r\n\t\t\t\t\tstate = {\r\n\t\t\t\t\t\t...state,\r\n\t\t\t\t\t\t...stateUpdate\r\n\t\t\t\t\t}\r\n\t\t\t\t\trender()\r\n\t\t\t\t\tthis.virtualScroller.onRender()\r\n\t\t\t\t}\r\n\t\t\t\tif (this.hasPausedStateUpdates) {\r\n\t\t\t\t\tthis.pausedStateUpdate = {\r\n\t\t\t\t\t\t...this.pausedStateUpdate,\r\n\t\t\t\t\t\t...stateUpdate\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.pausedStateUpdateAction = stateUpdateAction\r\n\t\t\t\t} else {\r\n\t\t\t\t\tstateUpdateAction(stateUpdate)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\trender()\r\n\t}\r\n\r\n\tpauseStateUpdates() {\r\n\t\tif (this.hasPausedStateUpdates) {\r\n\t\t\tthrow new Error('[virtual-scroller] State updates have already been paused')\r\n\t\t}\r\n\t\tthis.hasPausedStateUpdates = true\r\n\t}\r\n\r\n\tresumeStateUpdates() {\r\n\t\tif (this.pausedStateUpdate) {\r\n\t\t\tthis.pausedStateUpdateAction(this.pausedStateUpdate)\r\n\t\t\tthis.pausedStateUpdate = undefined\r\n\t\t\tthis.pausedStateUpdateAction = undefined\r\n\t\t}\r\n\t\tthis.hasPausedStateUpdates = false\r\n\t}\r\n\r\n\tverifyState(expectedState) {\r\n\t\t// `mocha`/`chai`.\r\n\t\texpect(this.virtualScroller.getState()).to.deep.include(expectedState)\r\n\t}\r\n\r\n\texpectStateUpdate(stateUpdate, callback) {\r\n\t\tthis.expectedStateUpdates.push({\r\n\t\t\tstateUpdate,\r\n\t\t\tcallback\r\n\t\t})\r\n\t}\r\n\r\n\tgetFirstNonMeasuredItemIndex() {\r\n\t\treturn this.virtualScroller.firstNonMeasuredItemIndex\r\n\t}\r\n\r\n\tgetScrollY() {\r\n\t\treturn this.virtualScroller.scrollableContainer.getScrollY()\r\n\t}\r\n\r\n\tscrollTo(scrollPosition) {\r\n\t\tthis.virtualScroller.scrollableContainer.scrollToY(scrollPosition)\r\n\t}\r\n\r\n\tupdateScreenDimensions({\r\n\t\tscreenWidth: scrollableContainerWidth,\r\n\t\tscreenHeight: scrollableContainerHeight,\r\n\t\tcolumnsCount\r\n\t}) {\r\n\t\t// Resize scrollable container.\r\n\t\tthis.setScrollableContainerWidth(scrollableContainerWidth)\r\n\t\tthis.setScrollableContainerHeight(scrollableContainerHeight)\r\n\r\n\t\t// Update columns count.\r\n\t\tthis.__columnsCount = columnsCount\r\n\t}\r\n\r\n\t// Returns a `Promise`.\r\n\ttriggerResize({\r\n\t\tscreenWidth,\r\n\t\tscreenHeight,\r\n\t\tcolumnsCount,\r\n\t\tverticalSpacing\r\n\t}) {\r\n\t\tthis.updateScreenDimensions({\r\n\t\t\tscreenWidth,\r\n\t\t\tscreenHeight,\r\n\t\t\tcolumnsCount,\r\n\t\t\tverticalSpacing\r\n\t\t})\r\n\r\n\t\t// Call \"on resize\" listener.\r\n\t\treturn this.virtualScroller.scrollableContainer._triggerResizeListener()\r\n\t}\r\n\r\n\tstop() {\r\n\t\tif (this.expectedStateUpdates.length > 0) {\r\n\t\t\tthrow new Error(`[virtual-scroller] Expected ${this.expectedStateUpdates.length} state updates which didn't happen:\\n${JSON.stringify(this.expectedStateUpdates, null, 2)}`)\r\n\t\t}\r\n\t\tif (this.pausedStateUpdate) {\r\n\t\t\tthrow new Error('[virtual-scroller] State updates were paused and haven\\'t been resumed afterwards')\r\n\t\t}\r\n\t\tthis.virtualScroller.stop()\r\n\t}\r\n\r\n\tstart() {\r\n\t\tthis.virtualScroller.start()\r\n\t}\r\n\r\n\tgetState() {\r\n\t\treturn this.virtualScroller.getState()\r\n\t}\r\n\r\n\tupdateLayout() {\r\n\t\tthis.virtualScroller.updateLayout()\r\n\t}\r\n\r\n\tgetItemScrollPosition(itemOrIndex) {\r\n\t\treturn this.virtualScroller.getItemScrollPosition(itemOrIndex)\r\n\t}\r\n\r\n\tonItemHeightDidChange(itemOrIndex) {\r\n\t\tthis.virtualScroller.onItemHeightDidChange(itemOrIndex)\r\n\t}\r\n\r\n\tsetItemState(itemOrIndex, newState) {\r\n\t\tthis.virtualScroller.setItemState(itemOrIndex, newState)\r\n\t}\r\n\r\n\tgetAverageItemHeight() {\r\n\t\treturn this.virtualScroller.getAverageItemHeight()\r\n\t}\r\n\r\n\tsetItems(newItems, options) {\r\n\t\tthis.virtualScroller.setItems(newItems, options)\r\n\t}\r\n}\r\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VirtualScroller.js","names":["DEBUG","TestVirtualScroller","scrollableContainerWidth","screenWidth","scrollableContainerHeight","screenHeight","columnsCount","verticalSpacing","items","getItemId","initialState","state","rest","Object","keys","length","Error","join","expectedStateUpdates","scrollableContainerElement","width","height","containerElement","paddingTop","paddingBottom","children","setScrollableContainerWidth","setScrollableContainerHeight","getItemsContainerElement","__columnsCount","getColumnsCount","getItemWidth","hasPausedStateUpdates","undefined","pausedStateUpdate","pausedStateUpdateAction","onBeforeUpdateState","stateUpdate","expectedStateUpdate","shift","expect","to","deep","equal","callback","render","virtualScroller","getState","beforeItemsHeight","afterItemsHeight","firstShownItemIndex","lastShownItemIndex","slice","map","item","getWidth","getHeight","getArea","area","getMarginTop","VirtualScroller","scrollableContainer","engine","Engine","_delayUnnecessaryRerenderUntilStopsScrolling","delayRecursiveRenderUntilNextTick","onStateChange","console","log","getInitialState","useState","updateState","stateUpdateAction","onRender","expectedState","include","push","firstNonMeasuredItemIndex","getScrollY","scrollPosition","scrollToY","updateScreenDimensions","_triggerResizeListener","JSON","stringify","stop","start","updateLayout","itemOrIndex","getItemScrollPosition","onItemHeightDidChange","newState","setItemState","getAverageItemHeight","newItems","options","setItems"],"sources":["../../source/test/VirtualScroller.js"],"sourcesContent":["import { describe, it } from 'mocha'\r\nimport { expect } from 'chai'\r\n\r\nimport VirtualScroller from '../VirtualScroller.js'\r\nimport Engine from './Engine.js'\r\n\r\nconst DEBUG = false\r\n\r\nexport default class TestVirtualScroller {\r\n\tconstructor({\r\n\t\tscreenWidth: scrollableContainerWidth,\r\n\t\tscreenHeight: scrollableContainerHeight,\r\n\t\tcolumnsCount,\r\n\t\tverticalSpacing,\r\n\t\titems,\r\n\t\tgetItemId,\r\n\t\tstate: initialState,\r\n\t\t...rest\r\n\t}) {\r\n\t\t// Validate that no unknown properties are passed.\r\n\t\t// This prevents the cases when a developer confuses\r\n\t\t// `TestVirtualScroller` options for `VirtualScroller` options.\r\n\t\tif (Object.keys(rest).length > 0) {\r\n\t\t\tthrow new Error(`Unknown options: ${Object.keys(rest).join(', ')}`)\r\n\t\t}\r\n\r\n\t\tthis.expectedStateUpdates = []\r\n\r\n\t\tconst scrollableContainerElement = {\r\n\t\t\twidth: scrollableContainerWidth,\r\n\t\t\theight: scrollableContainerHeight\r\n\t\t}\r\n\r\n\t\tconst containerElement = {\r\n\t\t\tpaddingTop: 0,\r\n\t\t\tpaddingBottom: 0,\r\n\t\t\twidth: scrollableContainerElement.width,\r\n\t\t\tchildren: []\r\n\t\t}\r\n\r\n\t\tthis.setScrollableContainerWidth = (width) => {\r\n\t\t\tscrollableContainerElement.width = width\r\n\t\t\tcontainerElement.width = width\r\n\t\t}\r\n\r\n\t\tthis.setScrollableContainerHeight = (height) => {\r\n\t\t\tscrollableContainerElement.height = height\r\n\t\t}\r\n\r\n\t\tconst getItemsContainerElement = () => containerElement\r\n\r\n\t\tthis.__columnsCount = columnsCount\r\n\r\n\t\tconst getColumnsCount = () => this.__columnsCount\r\n\t\tconst getItemWidth = () => scrollableContainerElement.width / getColumnsCount()\r\n\r\n\t\tthis.hasPausedStateUpdates = undefined\r\n\t\tthis.pausedStateUpdate = undefined\r\n\t\tthis.pausedStateUpdateAction = undefined\r\n\r\n\t\tconst onBeforeUpdateState = (stateUpdate) => {\r\n\t\t\tif (this.expectedStateUpdates.length > 0) {\r\n\t\t\t\tconst expectedStateUpdate = this.expectedStateUpdates.shift()\r\n\t\t\t\texpect(stateUpdate).to.deep.equal(expectedStateUpdate.stateUpdate)\r\n\t\t\t\tif (expectedStateUpdate.callback) {\r\n\t\t\t\t\texpectedStateUpdate.callback()\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tconst render = () => {\r\n\t\t\tconst {\r\n\t\t\t\titems,\r\n\t\t\t\tbeforeItemsHeight,\r\n\t\t\t\tafterItemsHeight,\r\n\t\t\t\tfirstShownItemIndex,\r\n\t\t\t\tlastShownItemIndex\r\n\t\t\t} = this.virtualScroller.getState()\r\n\r\n\t\t\tcontainerElement.paddingTop = beforeItemsHeight\r\n\t\t\tcontainerElement.paddingBottom = afterItemsHeight\r\n\r\n\t\t\tcontainerElement.children = items\r\n\t\t\t\t.slice(firstShownItemIndex, lastShownItemIndex + 1)\r\n\t\t\t\t.map((item) => ({\r\n\t\t\t\t\tgetWidth: () => getItemWidth(),\r\n\t\t\t\t\tgetHeight: () => (item.getArea ? item.getArea() : item.area) / getItemWidth(),\r\n\t\t\t\t\tgetMarginTop: () => verticalSpacing\r\n\t\t\t\t}))\r\n\t\t}\r\n\r\n\t\tthis.virtualScroller = new VirtualScroller(getItemsContainerElement, items, {\r\n\t\t\tscrollableContainer: scrollableContainerElement,\r\n\t\t\tengine: Engine,\r\n\t\t\t_delayUnnecessaryRerenderUntilStopsScrolling: false,\r\n\t\t\tdelayRecursiveRenderUntilNextTick: false,\r\n\t\t\tgetItemId,\r\n\t\t\tgetColumnsCount,\r\n\t\t\tstate: initialState,\r\n\t\t\tonStateChange(state) {\r\n\t\t\t\tif (DEBUG) {\r\n\t\t\t\t\tconsole.log('~ Updated State ~')\r\n\t\t\t\t\tconsole.log(state)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\tlet state = this.virtualScroller.getInitialState()\r\n\r\n\t\tthis.virtualScroller.useState({\r\n\t\t\tgetState: () => state,\r\n\t\t\tupdateState: (stateUpdate) => {\r\n\t\t\t\tconst stateUpdateAction = (stateUpdate) => {\r\n\t\t\t\t\t// Is only used in tests.\r\n\t\t\t\t\tif (onBeforeUpdateState) {\r\n\t\t\t\t\t\tonBeforeUpdateState(stateUpdate)\r\n\t\t\t\t\t}\r\n\t\t\t\t\tstate = {\r\n\t\t\t\t\t\t...state,\r\n\t\t\t\t\t\t...stateUpdate\r\n\t\t\t\t\t}\r\n\t\t\t\t\trender()\r\n\t\t\t\t\tthis.virtualScroller.onRender()\r\n\t\t\t\t}\r\n\t\t\t\tif (this.hasPausedStateUpdates) {\r\n\t\t\t\t\tthis.pausedStateUpdate = {\r\n\t\t\t\t\t\t...this.pausedStateUpdate,\r\n\t\t\t\t\t\t...stateUpdate\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthis.pausedStateUpdateAction = stateUpdateAction\r\n\t\t\t\t} else {\r\n\t\t\t\t\tstateUpdateAction(stateUpdate)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t})\r\n\r\n\t\trender()\r\n\t}\r\n\r\n\tpauseStateUpdates() {\r\n\t\tif (this.hasPausedStateUpdates) {\r\n\t\t\tthrow new Error('[virtual-scroller] State updates have already been paused')\r\n\t\t}\r\n\t\tthis.hasPausedStateUpdates = true\r\n\t}\r\n\r\n\tresumeStateUpdates() {\r\n\t\tif (this.pausedStateUpdate) {\r\n\t\t\tthis.pausedStateUpdateAction(this.pausedStateUpdate)\r\n\t\t\tthis.pausedStateUpdate = undefined\r\n\t\t\tthis.pausedStateUpdateAction = undefined\r\n\t\t}\r\n\t\tthis.hasPausedStateUpdates = false\r\n\t}\r\n\r\n\tverifyState(expectedState) {\r\n\t\t// `mocha`/`chai`.\r\n\t\texpect(this.virtualScroller.getState()).to.deep.include(expectedState)\r\n\t}\r\n\r\n\texpectStateUpdate(stateUpdate, callback) {\r\n\t\tthis.expectedStateUpdates.push({\r\n\t\t\tstateUpdate,\r\n\t\t\tcallback\r\n\t\t})\r\n\t}\r\n\r\n\tgetFirstNonMeasuredItemIndex() {\r\n\t\treturn this.virtualScroller.firstNonMeasuredItemIndex\r\n\t}\r\n\r\n\tgetScrollY() {\r\n\t\treturn this.virtualScroller.scrollableContainer.getScrollY()\r\n\t}\r\n\r\n\tscrollTo(scrollPosition) {\r\n\t\tthis.virtualScroller.scrollableContainer.scrollToY(scrollPosition)\r\n\t}\r\n\r\n\tupdateScreenDimensions({\r\n\t\tscreenWidth: scrollableContainerWidth,\r\n\t\tscreenHeight: scrollableContainerHeight,\r\n\t\tcolumnsCount\r\n\t}) {\r\n\t\t// Resize scrollable container.\r\n\t\tthis.setScrollableContainerWidth(scrollableContainerWidth)\r\n\t\tthis.setScrollableContainerHeight(scrollableContainerHeight)\r\n\r\n\t\t// Update columns count.\r\n\t\tthis.__columnsCount = columnsCount\r\n\t}\r\n\r\n\t// Returns a `Promise`.\r\n\ttriggerResize({\r\n\t\tscreenWidth,\r\n\t\tscreenHeight,\r\n\t\tcolumnsCount,\r\n\t\tverticalSpacing\r\n\t}) {\r\n\t\tthis.updateScreenDimensions({\r\n\t\t\tscreenWidth,\r\n\t\t\tscreenHeight,\r\n\t\t\tcolumnsCount,\r\n\t\t\tverticalSpacing\r\n\t\t})\r\n\r\n\t\t// Call \"on resize\" listener.\r\n\t\treturn this.virtualScroller.scrollableContainer._triggerResizeListener()\r\n\t}\r\n\r\n\tstop() {\r\n\t\tif (this.expectedStateUpdates.length > 0) {\r\n\t\t\tthrow new Error(`[virtual-scroller] Expected ${this.expectedStateUpdates.length} state updates which didn't happen:\\n${JSON.stringify(this.expectedStateUpdates, null, 2)}`)\r\n\t\t}\r\n\t\tif (this.pausedStateUpdate) {\r\n\t\t\tthrow new Error('[virtual-scroller] State updates were paused and haven\\'t been resumed afterwards')\r\n\t\t}\r\n\t\tthis.virtualScroller.stop()\r\n\t}\r\n\r\n\tstart() {\r\n\t\tthis.virtualScroller.start()\r\n\t}\r\n\r\n\tgetState() {\r\n\t\treturn this.virtualScroller.getState()\r\n\t}\r\n\r\n\tupdateLayout() {\r\n\t\tthis.virtualScroller.updateLayout()\r\n\t}\r\n\r\n\tgetItemScrollPosition(itemOrIndex) {\r\n\t\treturn this.virtualScroller.getItemScrollPosition(itemOrIndex)\r\n\t}\r\n\r\n\tonItemHeightDidChange(itemOrIndex) {\r\n\t\tthis.virtualScroller.onItemHeightDidChange(itemOrIndex)\r\n\t}\r\n\r\n\tsetItemState(itemOrIndex, newState) {\r\n\t\tthis.virtualScroller.setItemState(itemOrIndex, newState)\r\n\t}\r\n\r\n\tgetAverageItemHeight() {\r\n\t\treturn this.virtualScroller.getAverageItemHeight()\r\n\t}\r\n\r\n\tsetItems(newItems, options) {\r\n\t\tthis.virtualScroller.setItems(newItems, options)\r\n\t}\r\n}\r\n"],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.scheduleOnNextTick = scheduleOnNextTick;
|
|
7
|
+
exports.unscheduleOnNextTick = unscheduleOnNextTick;
|
|
8
|
+
|
|
9
|
+
var _requestAnimationFrameTimeout = require("request-animation-frame-timeout");
|
|
10
|
+
|
|
11
|
+
// For some weird reason, in Chrome, `setTimeout()` would lag up to a second (or more) behind.
|
|
12
|
+
// Turns out, Chrome developers have deprecated `setTimeout()` API entirely without asking anyone.
|
|
13
|
+
// Replacing `setTimeout()` with `requestAnimationFrame()` can work around that Chrome bug.
|
|
14
|
+
// https://github.com/bvaughn/react-virtualized/issues/722
|
|
15
|
+
// This function could also use `requestAnimationFrame()` function
|
|
16
|
+
// but `setTimeout()` with `0` delay has practically the same effect
|
|
17
|
+
// and at the same time it's more universally supported, e.g. in Node.js.
|
|
18
|
+
function scheduleOnNextTick(func) {
|
|
19
|
+
return (0, _requestAnimationFrameTimeout.setTimeout)(func, 0);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function unscheduleOnNextTick(timerId) {
|
|
23
|
+
(0, _requestAnimationFrameTimeout.clearTimeout)(timerId);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=scheduleOnNextTick.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduleOnNextTick.js","names":["scheduleOnNextTick","func","setTimeout","unscheduleOnNextTick","timerId","clearTimeout"],"sources":["../../source/utility/scheduleOnNextTick.js"],"sourcesContent":["// For some weird reason, in Chrome, `setTimeout()` would lag up to a second (or more) behind.\r\n// Turns out, Chrome developers have deprecated `setTimeout()` API entirely without asking anyone.\r\n// Replacing `setTimeout()` with `requestAnimationFrame()` can work around that Chrome bug.\r\n// https://github.com/bvaughn/react-virtualized/issues/722\r\nimport { setTimeout, clearTimeout } from 'request-animation-frame-timeout'\r\n\r\n// This function could also use `requestAnimationFrame()` function\r\n// but `setTimeout()` with `0` delay has practically the same effect\r\n// and at the same time it's more universally supported, e.g. in Node.js.\r\nexport function scheduleOnNextTick(func) {\r\n\treturn setTimeout(func, 0)\r\n}\r\n\r\nexport function unscheduleOnNextTick(timerId) {\r\n\tclearTimeout(timerId)\r\n}"],"mappings":";;;;;;;;AAIA;;AAJA;AACA;AACA;AACA;AAGA;AACA;AACA;AACO,SAASA,kBAAT,CAA4BC,IAA5B,EAAkC;EACxC,OAAO,IAAAC,wCAAA,EAAWD,IAAX,EAAiB,CAAjB,CAAP;AACA;;AAEM,SAASE,oBAAT,CAA8BC,OAA9B,EAAuC;EAC7C,IAAAC,0CAAA,EAAaD,OAAb;AACA"}
|
package/index.d.ts
CHANGED
|
@@ -48,6 +48,8 @@ interface ScrollableContainerArgument {
|
|
|
48
48
|
getWidth(): number;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
// "Common" options shared by the "core" component and its implementations
|
|
52
|
+
// like React Virtual Scroller or DOM Virtual Scroller.
|
|
51
53
|
export interface VirtualScrollerCommonOptions<Item, ItemState> {
|
|
52
54
|
bypass?: boolean;
|
|
53
55
|
onStateChange?(newState: State<Item, ItemState>): void;
|
|
@@ -63,10 +65,12 @@ export interface VirtualScrollerCommonOptions<Item, ItemState> {
|
|
|
63
65
|
getColumnsCount?(scrollableContainer: ScrollableContainerArgument): number;
|
|
64
66
|
}
|
|
65
67
|
|
|
68
|
+
// "Core" component options.
|
|
66
69
|
interface Options<Element, Item, ItemState> extends VirtualScrollerCommonOptions<Item, ItemState> {
|
|
67
70
|
state?: State<Item, ItemState>;
|
|
68
71
|
render?(state: State<Item, ItemState>, previousState?: State<Item, ItemState>): void;
|
|
69
72
|
engine?: Engine<Element>;
|
|
73
|
+
delayRecursiveRenderUntilNextTick?: boolean;
|
|
70
74
|
// `scrollableContainer` is deprecated, use `getScrollableContainer()` instead.
|
|
71
75
|
scrollableContainer?: Element;
|
|
72
76
|
getScrollableContainer?(): Element;
|
|
@@ -4,12 +4,7 @@ function _defineProperties(target, props) { for (var i = 0; i < props.length; i+
|
|
|
4
4
|
|
|
5
5
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
6
6
|
|
|
7
|
-
//
|
|
8
|
-
// Turns out, Chrome developers have deprecated `setTimeout()` API entirely without asking anyone.
|
|
9
|
-
// Replacing `setTimeout()` with `requestAnimationFrame()` can work around that Chrome bug.
|
|
10
|
-
// https://github.com/bvaughn/react-virtualized/issues/722
|
|
11
|
-
import { setTimeout, clearTimeout } from 'request-animation-frame-timeout'; // Refreshing two times every seconds seems reasonable.
|
|
12
|
-
|
|
7
|
+
// Refreshing two times every seconds seems reasonable.
|
|
13
8
|
var WATCH_LIST_TOP_OFFSET_INTERVAL = 500; // Refreshing for 3 seconds after the initial page load seems reasonable.
|
|
14
9
|
|
|
15
10
|
var WATCH_LIST_TOP_OFFSET_MAX_DURATION = 3000; // `VirtualScroller` calls `this.layout.layOut()` on mount,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListTopOffsetWatcher.js","names":["
|
|
1
|
+
{"version":3,"file":"ListTopOffsetWatcher.js","names":["WATCH_LIST_TOP_OFFSET_INTERVAL","WATCH_LIST_TOP_OFFSET_MAX_DURATION","ListTopOffsetWatcher","getListTopOffset","onListTopOffsetChange","listTopOffset","listTopOffsetInsideScrollableContainer","undefined","start","_isActive","watchListTopOffset","watchListTopOffsetTimer","clearTimeout","startedAt","Date","now","check","setTimeout"],"sources":["../../source/DOM/ListTopOffsetWatcher.js"],"sourcesContent":["// Refreshing two times every seconds seems reasonable.\r\nconst WATCH_LIST_TOP_OFFSET_INTERVAL = 500\r\n\r\n// Refreshing for 3 seconds after the initial page load seems reasonable.\r\nconst WATCH_LIST_TOP_OFFSET_MAX_DURATION = 3000\r\n\r\n// `VirtualScroller` calls `this.layout.layOut()` on mount,\r\n// but if the page styles are applied after `VirtualScroller` mounts\r\n// (for example, if styles are applied via javascript, like Webpack does)\r\n// then the list might not render correctly and it will only show the first item.\r\n// The reason is that in that case calling `.getListTopOffset()` on mount\r\n// returns \"incorrect\" `top` position because the styles haven't been applied yet.\r\n//\r\n// For example, consider a page:\r\n//\r\n// <div class=\"page\">\r\n// <nav class=\"sidebar\">...</nav>\r\n// <main>...</main>\r\n// </div>\r\n//\r\n// The sidebar is styled as `position: fixed`, but, until\r\n// the page styles have been applied, it's gonna be a regular `<div/>`\r\n// meaning that `<main/>` will be rendered below the sidebar\r\n// and will appear offscreen, and so it will only render the first item.\r\n//\r\n// Then, the page styles are loaded and applied, and the sidebar\r\n// is now `position: fixed`, so `<main/>` is now rendered at the top of the page,\r\n// but `VirtualScroller`'s `.render()` has already been called\r\n// and it won't re-render until the user scrolls or the window is resized.\r\n//\r\n// This type of a bug doesn't seem to occur in production, but it can appear\r\n// in development mode when using Webpack. The workaround `VirtualScroller`\r\n// implements for such cases is calling `.getListTopOffset()`\r\n// on the list container DOM element periodically (every second) to check\r\n// if the `top` coordinate has changed as a result of CSS being applied:\r\n// if it has then it recalculates the shown item indexes.\r\n//\r\n// Maybe this bug could occur in production when using Webpack chunks.\r\n// That depends on how a style of a chunk is added to the page:\r\n// if it's added via `javascript` after the page has been rendered\r\n// then this workaround will also work for that case.\r\n//\r\n// Another example would be a page having a really tall expanded \"accordion\"\r\n// section, below which a `VirtualScroller` list resides. If the user un-expands\r\n// such expanded \"accordion\" section, the list would become visible but\r\n// it wouldn't get re-rendered because no `scroll` event has occured,\r\n// and the list only re-renders automatically on `scroll` events.\r\n// To work around such cases, call `virtualScroller.updateLayout()` method manually.\r\n// The workaround below could be extended to refresh the list's top coordinate\r\n// indefinitely and at higher intervals, but why waste CPU time on that.\r\n// There doesn't seem to be any DOM API for tracking an element's top position.\r\n// There is `IntersectionObserver` API but it doesn't exactly do that.\r\n//\r\nexport default class ListTopOffsetWatcher {\r\n\tconstructor({\r\n\t\tgetListTopOffset,\r\n\t\tonListTopOffsetChange\r\n\t}) {\r\n\t\tthis.getListTopOffset = getListTopOffset\r\n\t\tthis.onListTopOffsetChange = onListTopOffsetChange\r\n\t}\r\n\r\n\tonListTopOffset(listTopOffset) {\r\n\t\tif (this.listTopOffsetInsideScrollableContainer === undefined) {\r\n\t\t\t// Start periodical checks of the list's top offset\r\n\t\t\t// in order to perform a re-layout in case it changes.\r\n\t\t\t// See the comments in `ListTopOffsetWatcher.js` file\r\n\t\t\t// on why can the list's top offset change, and in which circumstances.\r\n\t\t\tthis.start()\r\n\t\t}\r\n\t\tthis.listTopOffsetInsideScrollableContainer = listTopOffset\r\n\t}\r\n\r\n\tstart() {\r\n\t\tthis._isActive = true\r\n\t\tthis.watchListTopOffset()\r\n\t}\r\n\r\n\tisStarted() {\r\n\t\treturn this._isActive\r\n\t}\r\n\r\n\tstop() {\r\n\t\tthis._isActive = false\r\n\r\n\t\tif (this.watchListTopOffsetTimer) {\r\n\t\t\tclearTimeout(this.watchListTopOffsetTimer)\r\n\t\t\tthis.watchListTopOffsetTimer = undefined\r\n\t\t}\r\n\t}\r\n\r\n\twatchListTopOffset() {\r\n\t\tconst startedAt = Date.now()\r\n\t\tconst check = () => {\r\n\t\t\t// If `VirtualScroller` has been unmounted\r\n\t\t\t// while `setTimeout()` was waiting, then exit.\r\n\t\t\tif (!this._isActive) {\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t\t// Skip comparing `top` coordinate of the list\r\n\t\t\t// when this function is called for the first time.\r\n\t\t\tif (this.listTopOffsetInsideScrollableContainer !== undefined) {\r\n\t\t\t\t// Calling `this.getListTopOffset()` on an element\r\n\t\t\t\t// runs about 0.003 milliseconds on a modern desktop CPU,\r\n\t\t\t\t// so I guess it's fine calling it twice a second.\r\n\t\t\t\tif (this.getListTopOffset() !== this.listTopOffsetInsideScrollableContainer) {\r\n\t\t\t\t\tthis.onListTopOffsetChange()\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// Compare `top` coordinate of the list twice a second\r\n\t\t\t// to find out if it has changed as a result of loading CSS styles.\r\n\t\t\t// The total duration of 3 seconds would be enough for any styles to load, I guess.\r\n\t\t\t// There could be other cases changing the `top` coordinate\r\n\t\t\t// of the list (like collapsing an \"accordeon\" panel above the list\r\n\t\t\t// without scrolling the page), but those cases should be handled\r\n\t\t\t// by manually calling `.updateLayout()` instance method on `VirtualScroller` instance.\r\n\t\t\tif (Date.now() - startedAt < WATCH_LIST_TOP_OFFSET_MAX_DURATION) {\r\n\t\t\t\tthis.watchListTopOffsetTimer = setTimeout(check, WATCH_LIST_TOP_OFFSET_INTERVAL)\r\n\t\t\t}\r\n\t\t}\r\n\t\t// Run the cycle.\r\n\t\tcheck()\r\n\t}\r\n}"],"mappings":";;;;;;AAAA;AACA,IAAMA,8BAA8B,GAAG,GAAvC,C,CAEA;;AACA,IAAMC,kCAAkC,GAAG,IAA3C,C,CAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;IACqBC,oB;EACpB,oCAGG;IAAA,IAFFC,gBAEE,QAFFA,gBAEE;IAAA,IADFC,qBACE,QADFA,qBACE;;IAAA;;IACF,KAAKD,gBAAL,GAAwBA,gBAAxB;IACA,KAAKC,qBAAL,GAA6BA,qBAA7B;EACA;;;;WAED,yBAAgBC,aAAhB,EAA+B;MAC9B,IAAI,KAAKC,sCAAL,KAAgDC,SAApD,EAA+D;QAC9D;QACA;QACA;QACA;QACA,KAAKC,KAAL;MACA;;MACD,KAAKF,sCAAL,GAA8CD,aAA9C;IACA;;;WAED,iBAAQ;MACP,KAAKI,SAAL,GAAiB,IAAjB;MACA,KAAKC,kBAAL;IACA;;;WAED,qBAAY;MACX,OAAO,KAAKD,SAAZ;IACA;;;WAED,gBAAO;MACN,KAAKA,SAAL,GAAiB,KAAjB;;MAEA,IAAI,KAAKE,uBAAT,EAAkC;QACjCC,YAAY,CAAC,KAAKD,uBAAN,CAAZ;QACA,KAAKA,uBAAL,GAA+BJ,SAA/B;MACA;IACD;;;WAED,8BAAqB;MAAA;;MACpB,IAAMM,SAAS,GAAGC,IAAI,CAACC,GAAL,EAAlB;;MACA,IAAMC,KAAK,GAAG,SAARA,KAAQ,GAAM;QACnB;QACA;QACA,IAAI,CAAC,KAAI,CAACP,SAAV,EAAqB;UACpB;QACA,CALkB,CAMnB;QACA;;;QACA,IAAI,KAAI,CAACH,sCAAL,KAAgDC,SAApD,EAA+D;UAC9D;UACA;UACA;UACA,IAAI,KAAI,CAACJ,gBAAL,OAA4B,KAAI,CAACG,sCAArC,EAA6E;YAC5E,KAAI,CAACF,qBAAL;UACA;QACD,CAfkB,CAgBnB;QACA;QACA;QACA;QACA;QACA;QACA;;;QACA,IAAIU,IAAI,CAACC,GAAL,KAAaF,SAAb,GAAyBZ,kCAA7B,EAAiE;UAChE,KAAI,CAACU,uBAAL,GAA+BM,UAAU,CAACD,KAAD,EAAQhB,8BAAR,CAAzC;QACA;MACD,CA1BD,CAFoB,CA6BpB;;;MACAgB,KAAK;IACL;;;;;;SArEmBd,oB"}
|
package/modules/Scroll.js
CHANGED
|
@@ -30,7 +30,7 @@ var Scroll = /*#__PURE__*/function () {
|
|
|
30
30
|
getListTopOffset = _ref.getListTopOffset,
|
|
31
31
|
getPrerenderMargin = _ref.getPrerenderMargin,
|
|
32
32
|
onScrolledToTop = _ref.onScrolledToTop,
|
|
33
|
-
|
|
33
|
+
delayUnnecessaryRerenderUntilStopsScrolling = _ref.delayUnnecessaryRerenderUntilStopsScrolling;
|
|
34
34
|
|
|
35
35
|
_classCallCheck(this, Scroll);
|
|
36
36
|
|
|
@@ -92,21 +92,18 @@ var Scroll = /*#__PURE__*/function () {
|
|
|
92
92
|
//
|
|
93
93
|
_this.getScrollY() + _this.scrollableContainer.getHeight() > _this.getLatestLayoutVisibleArea().bottom + _this.getPrerenderMargin() && _this.hasNonRenderedItemsAtTheBottom());
|
|
94
94
|
|
|
95
|
-
if (forceUpdate) {
|
|
95
|
+
if (forceUpdate || _this.delayUnnecessaryRerenderUntilStopsScrolling === false) {
|
|
96
96
|
log('The user has scrolled far enough: perform a re-layout');
|
|
97
|
-
} else {
|
|
98
|
-
log('The user is scrolling: perform a re-layout when they stop scrolling');
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (forceUpdate || _this.waitForScrollingToStop === false) {
|
|
102
97
|
return _this.onScroll();
|
|
103
|
-
}
|
|
104
|
-
// don't schedule a "re-layout when user stops scrolling" timer.
|
|
98
|
+
}
|
|
105
99
|
|
|
100
|
+
log('The user is scrolling: perform a re-layout when they stop scrolling'); // If a re-layout is already scheduled at the next "frame",
|
|
101
|
+
// don't schedule a timer to wait for the user to stop scrolling.
|
|
106
102
|
|
|
107
103
|
if (_this.isImmediateLayoutScheduled()) {
|
|
108
104
|
return;
|
|
109
|
-
}
|
|
105
|
+
} // Schedule a timer to wait for the user to stop scrolling.
|
|
106
|
+
|
|
110
107
|
|
|
111
108
|
_this.shouldCallOnScrollListenerWhenStopsScrolling = true;
|
|
112
109
|
|
|
@@ -126,7 +123,7 @@ var Scroll = /*#__PURE__*/function () {
|
|
|
126
123
|
this.getListTopOffset = getListTopOffset;
|
|
127
124
|
this.getPrerenderMargin = getPrerenderMargin;
|
|
128
125
|
this.onScrolledToTop = onScrolledToTop;
|
|
129
|
-
this.
|
|
126
|
+
this.delayUnnecessaryRerenderUntilStopsScrolling = delayUnnecessaryRerenderUntilStopsScrolling;
|
|
130
127
|
}
|
|
131
128
|
|
|
132
129
|
_createClass(Scroll, [{
|
package/modules/Scroll.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Scroll.js","names":["setTimeout","clearTimeout","log","Scroll","isInBypassMode","scrollableContainer","itemsContainer","onScroll","initialScrollPosition","onScrollPositionChange","isImmediateLayoutScheduled","hasNonRenderedItemsAtTheTop","hasNonRenderedItemsAtTheBottom","getLatestLayoutVisibleArea","getListTopOffset","getPrerenderMargin","onScrolledToTop","waitForScrollingToStop","scrollByY","scrollToY","getScrollY","ignoreScrollEvents","cancelOnStopScrollingTimer","forceUpdate","top","getHeight","bottom","shouldCallOnScrollListenerWhenStopsScrolling","watchOnStopScrolling","undefined","stopListeningToScroll","onScrollListener","scrollY","onStopScrollingTimer","delayed","ON_STOP_SCROLLING_INACTIVE_PERIOD"],"sources":["../source/Scroll.js"],"sourcesContent":["// For some weird reason, in Chrome, `setTimeout()` would lag up to a second (or more) behind.\r\n// Turns out, Chrome developers have deprecated `setTimeout()` API entirely without asking anyone.\r\n// Replacing `setTimeout()` with `requestAnimationFrame()` can work around that Chrome bug.\r\n// https://github.com/bvaughn/react-virtualized/issues/722\r\nimport { setTimeout, clearTimeout } from 'request-animation-frame-timeout'\r\n\r\nimport log from './utility/debug.js'\r\n\r\nexport default class Scroll {\r\n\tconstructor({\r\n\t\tisInBypassMode,\r\n\t\tscrollableContainer,\r\n\t\titemsContainer,\r\n\t\tonScroll,\r\n\t\tinitialScrollPosition,\r\n\t\tonScrollPositionChange,\r\n\t\tisImmediateLayoutScheduled,\r\n\t\thasNonRenderedItemsAtTheTop,\r\n\t\thasNonRenderedItemsAtTheBottom,\r\n\t\tgetLatestLayoutVisibleArea,\r\n\t\tgetListTopOffset,\r\n\t\tgetPrerenderMargin,\r\n\t\tonScrolledToTop,\r\n\t\twaitForScrollingToStop\r\n\t}) {\r\n\t\tthis.isInBypassMode = isInBypassMode\r\n\t\tthis.scrollableContainer = scrollableContainer\r\n\t\tthis.itemsContainer = itemsContainer\r\n\t\tthis.onScroll = onScroll\r\n\t\tthis.initialScrollPosition = initialScrollPosition\r\n\t\tthis.onScrollPositionChange = onScrollPositionChange\r\n\t\tthis.isImmediateLayoutScheduled = isImmediateLayoutScheduled\r\n\t\tthis.hasNonRenderedItemsAtTheTop = hasNonRenderedItemsAtTheTop\r\n\t\tthis.hasNonRenderedItemsAtTheBottom = hasNonRenderedItemsAtTheBottom\r\n\t\tthis.getLatestLayoutVisibleArea = getLatestLayoutVisibleArea\r\n\t\tthis.getListTopOffset = getListTopOffset\r\n\t\tthis.getPrerenderMargin = getPrerenderMargin\r\n\t\tthis.onScrolledToTop = onScrolledToTop\r\n\t\tthis.waitForScrollingToStop = waitForScrollingToStop\r\n\t}\r\n\r\n\tstart() {\r\n\t\tif (this.initialScrollPosition !== undefined) {\r\n\t\t\tthis.scrollToY(this.initialScrollPosition)\r\n\t\t\t// Don't restore this scroll position on restart.\r\n\t\t\tthis.initialScrollPosition = undefined\r\n\t\t}\r\n\t\tif (this.onScrollPositionChange) {\r\n\t\t\tthis.onScrollPositionChange(this.getScrollY())\r\n\t\t}\r\n\t\tthis.stopListeningToScroll = this.scrollableContainer.onScroll(this.onScrollListener)\r\n\t}\r\n\r\n\tstop() {\r\n\t\tthis.stopListeningToScroll()\r\n\t\tthis.stopListeningToScroll = undefined\r\n\t\t// this.onStopScrollingListener = undefined\r\n\t\tthis.shouldCallOnScrollListenerWhenStopsScrolling = undefined\r\n\t\tthis.cancelOnStopScrollingTimer()\r\n\t}\r\n\r\n\tscrollToY(scrollY) {\r\n\t\tthis.ignoreScrollEvents = true\r\n\t\tthis.scrollableContainer.scrollToY(scrollY)\r\n\t\tthis.ignoreScrollEvents = undefined\r\n\t}\r\n\r\n\tscrollByY = (scrollByY) => {\r\n\t\tthis.scrollToY(this.getScrollY() + scrollByY)\r\n\t}\r\n\r\n\tgetScrollY() {\r\n\t\treturn this.scrollableContainer.getScrollY()\r\n\t}\r\n\r\n\tcancelOnStopScrollingTimer() {\r\n\t\tif (this.onStopScrollingTimer) {\r\n\t\t\tclearTimeout(this.onStopScrollingTimer)\r\n\t\t\tthis.onStopScrollingTimer = undefined\r\n\t\t}\r\n\t}\r\n\r\n\tcancelScheduledLayout() {\r\n\t\t// Cancel a \"re-layout when user stops scrolling\" timer.\r\n\t\tthis.cancelOnStopScrollingTimer()\r\n\t}\r\n\r\n\tonScrollListener = () => {\r\n\t\tif (this.onScrollPositionChange) {\r\n\t\t\tthis.onScrollPositionChange(this.getScrollY())\r\n\t\t}\r\n\r\n\t\t// If the user has scrolled up to the top of the items container.\r\n\t\t// (this option isn't currently used)\r\n\t\tif (this.onScrolledToTop) {\r\n\t\t\tif (this.getScrollY() < this.getListTopOffset()) {\r\n\t\t\t\tthis.onScrolledToTop()\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (this.isInBypassMode()) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tif (this.ignoreScrollEvents) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t// Prefer not performing a re-layout while the user is scrolling (if possible).\r\n\t\t// If the user doesn't scroll too far and then stops for a moment,\r\n\t\t// then a mid-scroll re-layout could be delayed until such a brief stop:\r\n\t\t// presumably, this results in better (smoother) scrolling performance,\r\n\t\t// delaying the work to when it doesn't introduce any stutter or \"jank\".\r\n\r\n\t\t// Reset `this.onStopScrollingTimer` (will be re-created below).\r\n\t\tthis.cancelOnStopScrollingTimer()\r\n\r\n\t\t// See if the latest \"layout\" (the currently rendered set of items)\r\n\t\t// is still sufficient in order to show all the items that're\r\n\t\t// currently inside the viewport. If there're some non-rendered items\r\n\t\t// that're visible in the current viewport, then those items\r\n\t\t// should be rendered \"immediately\" rather than waiting until\r\n\t\t// the user stops scrolling.\r\n\t\tconst forceUpdate =\r\n\t\t\t// If the items have been rendered at least once\r\n\t\t\tthis.getLatestLayoutVisibleArea() && (\r\n\t\t\t\t(\r\n\t\t\t\t\t// If the user has scrolled up past the \"prerender margin\"\r\n\t\t\t\t\t// and there're some non-rendered items at the top,\r\n\t\t\t\t\t// then force a re-layout.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// (during these calculations we assume that the list's top coordinate\r\n\t\t\t\t\t// hasn't changed since previous layout; even if that's not exactly true,\r\n\t\t\t\t\t// the items will be re-layout when the user stops scrolling anyway)\r\n\t\t\t\t\t//\r\n\t\t\t\t\t(this.getScrollY() < this.getLatestLayoutVisibleArea().top - this.getPrerenderMargin()) &&\r\n\t\t\t\t\tthis.hasNonRenderedItemsAtTheTop()\r\n\t\t\t\t)\r\n\t\t\t\t||\r\n\t\t\t\t(\r\n\t\t\t\t\t// If the user has scrolled down past the \"prerender margin\"\r\n\t\t\t\t\t// and there're any non-rendered items left at the end,\r\n\t\t\t\t\t// then force a re-layout.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// (during these calculations we assume that the list's top coordinate\r\n\t\t\t\t\t// hasn't changed since previous layout; even if that's not exactly true,\r\n\t\t\t\t\t// the items will be re-layout when the user stops scrolling anyway)\r\n\t\t\t\t\t//\r\n\t\t\t\t\t(this.getScrollY() + this.scrollableContainer.getHeight() > this.getLatestLayoutVisibleArea().bottom + this.getPrerenderMargin()) &&\r\n\t\t\t\t\tthis.hasNonRenderedItemsAtTheBottom()\r\n\t\t\t\t)\r\n\t\t\t)\r\n\r\n\t\tif (forceUpdate) {\r\n\t\t\tlog('The user has scrolled far enough: perform a re-layout')\r\n\t\t} else {\r\n\t\t\tlog('The user is scrolling: perform a re-layout when they stop scrolling')\r\n\t\t}\r\n\r\n\t\tif (forceUpdate || this.waitForScrollingToStop === false) {\r\n\t\t\treturn this.onScroll()\r\n\t\t}\r\n\r\n\t\t// If a re-layout is already scheduled at the next \"frame\",\r\n\t\t// don't schedule a \"re-layout when user stops scrolling\" timer.\r\n\t\tif (this.isImmediateLayoutScheduled()) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tthis.shouldCallOnScrollListenerWhenStopsScrolling = true\r\n\t\tthis.watchOnStopScrolling()\r\n\t}\r\n\r\n\twatchOnStopScrolling() {\r\n\t\tthis.onStopScrollingTimer = setTimeout(\r\n\t\t\t() => {\r\n\t\t\t\tthis.onStopScrollingTimer = undefined\r\n\r\n\t\t\t\tif (this.shouldCallOnScrollListenerWhenStopsScrolling) {\r\n\t\t\t\t\tthis.shouldCallOnScrollListenerWhenStopsScrolling = undefined\r\n\t\t\t\t\tthis.onScroll({ delayed: true })\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// `onStopScrolling()` feature is not currently used.\r\n\t\t\t\t// if (this.onStopScrollingListener) {\r\n\t\t\t\t// \tconst onStopScrollingListener = this.onStopScrollingListener\r\n\t\t\t\t// \tthis.onStopScrollingListener = undefined\r\n\t\t\t\t// \t// `onStopScrollingListener()` may hypothetically schedule\r\n\t\t\t\t// \t// another `onStopScrolling()` listener, so set\r\n\t\t\t\t// \t// `this.onStopScrollingListener` to `undefined` before\r\n\t\t\t\t// \t// calling it rather than after.\r\n\t\t\t\t// \tlog('~ The user has stopped scrolling ~')\r\n\t\t\t\t// \tonStopScrollingListener()\r\n\t\t\t\t// }\r\n\t\t\t},\r\n\t\t\t// \"scroll\" events are usually dispatched every 16 milliseconds\r\n\t\t\t// for 60fps refresh rate, so waiting for 100 milliseconds feels\r\n\t\t\t// reasonable: that would be about 6 frames of inactivity period,\r\n\t\t\t// which could mean that either the user has stopped scrolling\r\n\t\t\t// (for a moment) or the browser is lagging and stuttering\r\n\t\t\t// (skipping frames due to high load).\r\n\t\t\t// If the user continues scrolling then this timeout is constantly\r\n\t\t\t// refreshed (cancelled and then re-created).\r\n\t\t\tON_STOP_SCROLLING_INACTIVE_PERIOD\r\n\t\t)\r\n\t}\r\n\r\n\t// (this function isn't currently used)\r\n\t// onStopScrolling(onStopScrollingListener) {\r\n\t// \tthis.onStopScrollingListener = onStopScrollingListener\r\n\t// \tif (!this.onStopScrollingTimer) {\r\n\t// \t\tthis.watchOnStopScrolling()\r\n\t// \t}\r\n\t// }\r\n\r\n\t/**\r\n\t * Returns visible area coordinates relative to the scrollable container.\r\n\t * @return {object} `{ top: number, bottom: number }`\r\n\t */\r\n\tgetVisibleAreaBounds() {\r\n\t\tconst scrollY = this.getScrollY()\r\n\t\treturn {\r\n\t\t\t// The first pixel of the screen.\r\n\t\t\ttop: scrollY,\r\n\t\t\t// The pixel after the last pixel of the screen.\r\n\t\t\tbottom: scrollY + this.scrollableContainer.getHeight()\r\n\t\t}\r\n\t}\r\n}\r\n\r\nconst ON_STOP_SCROLLING_INACTIVE_PERIOD = 100"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Scroll.js","names":["setTimeout","clearTimeout","log","Scroll","isInBypassMode","scrollableContainer","itemsContainer","onScroll","initialScrollPosition","onScrollPositionChange","isImmediateLayoutScheduled","hasNonRenderedItemsAtTheTop","hasNonRenderedItemsAtTheBottom","getLatestLayoutVisibleArea","getListTopOffset","getPrerenderMargin","onScrolledToTop","delayUnnecessaryRerenderUntilStopsScrolling","scrollByY","scrollToY","getScrollY","ignoreScrollEvents","cancelOnStopScrollingTimer","forceUpdate","top","getHeight","bottom","shouldCallOnScrollListenerWhenStopsScrolling","watchOnStopScrolling","undefined","stopListeningToScroll","onScrollListener","scrollY","onStopScrollingTimer","delayed","ON_STOP_SCROLLING_INACTIVE_PERIOD"],"sources":["../source/Scroll.js"],"sourcesContent":["// For some weird reason, in Chrome, `setTimeout()` would lag up to a second (or more) behind.\r\n// Turns out, Chrome developers have deprecated `setTimeout()` API entirely without asking anyone.\r\n// Replacing `setTimeout()` with `requestAnimationFrame()` can work around that Chrome bug.\r\n// https://github.com/bvaughn/react-virtualized/issues/722\r\nimport { setTimeout, clearTimeout } from 'request-animation-frame-timeout'\r\n\r\nimport log from './utility/debug.js'\r\n\r\nexport default class Scroll {\r\n\tconstructor({\r\n\t\tisInBypassMode,\r\n\t\tscrollableContainer,\r\n\t\titemsContainer,\r\n\t\tonScroll,\r\n\t\tinitialScrollPosition,\r\n\t\tonScrollPositionChange,\r\n\t\tisImmediateLayoutScheduled,\r\n\t\thasNonRenderedItemsAtTheTop,\r\n\t\thasNonRenderedItemsAtTheBottom,\r\n\t\tgetLatestLayoutVisibleArea,\r\n\t\tgetListTopOffset,\r\n\t\tgetPrerenderMargin,\r\n\t\tonScrolledToTop,\r\n\t\tdelayUnnecessaryRerenderUntilStopsScrolling\r\n\t}) {\r\n\t\tthis.isInBypassMode = isInBypassMode\r\n\t\tthis.scrollableContainer = scrollableContainer\r\n\t\tthis.itemsContainer = itemsContainer\r\n\t\tthis.onScroll = onScroll\r\n\t\tthis.initialScrollPosition = initialScrollPosition\r\n\t\tthis.onScrollPositionChange = onScrollPositionChange\r\n\t\tthis.isImmediateLayoutScheduled = isImmediateLayoutScheduled\r\n\t\tthis.hasNonRenderedItemsAtTheTop = hasNonRenderedItemsAtTheTop\r\n\t\tthis.hasNonRenderedItemsAtTheBottom = hasNonRenderedItemsAtTheBottom\r\n\t\tthis.getLatestLayoutVisibleArea = getLatestLayoutVisibleArea\r\n\t\tthis.getListTopOffset = getListTopOffset\r\n\t\tthis.getPrerenderMargin = getPrerenderMargin\r\n\t\tthis.onScrolledToTop = onScrolledToTop\r\n\t\tthis.delayUnnecessaryRerenderUntilStopsScrolling = delayUnnecessaryRerenderUntilStopsScrolling\r\n\t}\r\n\r\n\tstart() {\r\n\t\tif (this.initialScrollPosition !== undefined) {\r\n\t\t\tthis.scrollToY(this.initialScrollPosition)\r\n\t\t\t// Don't restore this scroll position on restart.\r\n\t\t\tthis.initialScrollPosition = undefined\r\n\t\t}\r\n\t\tif (this.onScrollPositionChange) {\r\n\t\t\tthis.onScrollPositionChange(this.getScrollY())\r\n\t\t}\r\n\t\tthis.stopListeningToScroll = this.scrollableContainer.onScroll(this.onScrollListener)\r\n\t}\r\n\r\n\tstop() {\r\n\t\tthis.stopListeningToScroll()\r\n\t\tthis.stopListeningToScroll = undefined\r\n\t\t// this.onStopScrollingListener = undefined\r\n\t\tthis.shouldCallOnScrollListenerWhenStopsScrolling = undefined\r\n\t\tthis.cancelOnStopScrollingTimer()\r\n\t}\r\n\r\n\tscrollToY(scrollY) {\r\n\t\tthis.ignoreScrollEvents = true\r\n\t\tthis.scrollableContainer.scrollToY(scrollY)\r\n\t\tthis.ignoreScrollEvents = undefined\r\n\t}\r\n\r\n\tscrollByY = (scrollByY) => {\r\n\t\tthis.scrollToY(this.getScrollY() + scrollByY)\r\n\t}\r\n\r\n\tgetScrollY() {\r\n\t\treturn this.scrollableContainer.getScrollY()\r\n\t}\r\n\r\n\tcancelOnStopScrollingTimer() {\r\n\t\tif (this.onStopScrollingTimer) {\r\n\t\t\tclearTimeout(this.onStopScrollingTimer)\r\n\t\t\tthis.onStopScrollingTimer = undefined\r\n\t\t}\r\n\t}\r\n\r\n\tcancelScheduledLayout() {\r\n\t\t// Cancel a \"re-layout when user stops scrolling\" timer.\r\n\t\tthis.cancelOnStopScrollingTimer()\r\n\t}\r\n\r\n\tonScrollListener = () => {\r\n\t\tif (this.onScrollPositionChange) {\r\n\t\t\tthis.onScrollPositionChange(this.getScrollY())\r\n\t\t}\r\n\r\n\t\t// If the user has scrolled up to the top of the items container.\r\n\t\t// (this option isn't currently used)\r\n\t\tif (this.onScrolledToTop) {\r\n\t\t\tif (this.getScrollY() < this.getListTopOffset()) {\r\n\t\t\t\tthis.onScrolledToTop()\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (this.isInBypassMode()) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tif (this.ignoreScrollEvents) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t// Prefer not performing a re-layout while the user is scrolling (if possible).\r\n\t\t// If the user doesn't scroll too far and then stops for a moment,\r\n\t\t// then a mid-scroll re-layout could be delayed until such a brief stop:\r\n\t\t// presumably, this results in better (smoother) scrolling performance,\r\n\t\t// delaying the work to when it doesn't introduce any stutter or \"jank\".\r\n\r\n\t\t// Reset `this.onStopScrollingTimer` (will be re-created below).\r\n\t\tthis.cancelOnStopScrollingTimer()\r\n\r\n\t\t// See if the latest \"layout\" (the currently rendered set of items)\r\n\t\t// is still sufficient in order to show all the items that're\r\n\t\t// currently inside the viewport. If there're some non-rendered items\r\n\t\t// that're visible in the current viewport, then those items\r\n\t\t// should be rendered \"immediately\" rather than waiting until\r\n\t\t// the user stops scrolling.\r\n\t\tconst forceUpdate =\r\n\t\t\t// If the items have been rendered at least once\r\n\t\t\tthis.getLatestLayoutVisibleArea() && (\r\n\t\t\t\t(\r\n\t\t\t\t\t// If the user has scrolled up past the \"prerender margin\"\r\n\t\t\t\t\t// and there're some non-rendered items at the top,\r\n\t\t\t\t\t// then force a re-layout.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// (during these calculations we assume that the list's top coordinate\r\n\t\t\t\t\t// hasn't changed since previous layout; even if that's not exactly true,\r\n\t\t\t\t\t// the items will be re-layout when the user stops scrolling anyway)\r\n\t\t\t\t\t//\r\n\t\t\t\t\t(this.getScrollY() < this.getLatestLayoutVisibleArea().top - this.getPrerenderMargin()) &&\r\n\t\t\t\t\tthis.hasNonRenderedItemsAtTheTop()\r\n\t\t\t\t)\r\n\t\t\t\t||\r\n\t\t\t\t(\r\n\t\t\t\t\t// If the user has scrolled down past the \"prerender margin\"\r\n\t\t\t\t\t// and there're any non-rendered items left at the end,\r\n\t\t\t\t\t// then force a re-layout.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// (during these calculations we assume that the list's top coordinate\r\n\t\t\t\t\t// hasn't changed since previous layout; even if that's not exactly true,\r\n\t\t\t\t\t// the items will be re-layout when the user stops scrolling anyway)\r\n\t\t\t\t\t//\r\n\t\t\t\t\t(this.getScrollY() + this.scrollableContainer.getHeight() > this.getLatestLayoutVisibleArea().bottom + this.getPrerenderMargin()) &&\r\n\t\t\t\t\tthis.hasNonRenderedItemsAtTheBottom()\r\n\t\t\t\t)\r\n\t\t\t)\r\n\r\n\t\tif (forceUpdate || this.delayUnnecessaryRerenderUntilStopsScrolling === false) {\r\n\t\t\tlog('The user has scrolled far enough: perform a re-layout')\r\n\t\t\treturn this.onScroll()\r\n\t\t}\r\n\r\n\t\tlog('The user is scrolling: perform a re-layout when they stop scrolling')\r\n\r\n\t\t// If a re-layout is already scheduled at the next \"frame\",\r\n\t\t// don't schedule a timer to wait for the user to stop scrolling.\r\n\t\tif (this.isImmediateLayoutScheduled()) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t// Schedule a timer to wait for the user to stop scrolling.\r\n\t\tthis.shouldCallOnScrollListenerWhenStopsScrolling = true\r\n\t\tthis.watchOnStopScrolling()\r\n\t}\r\n\r\n\twatchOnStopScrolling() {\r\n\t\tthis.onStopScrollingTimer = setTimeout(\r\n\t\t\t() => {\r\n\t\t\t\tthis.onStopScrollingTimer = undefined\r\n\r\n\t\t\t\tif (this.shouldCallOnScrollListenerWhenStopsScrolling) {\r\n\t\t\t\t\tthis.shouldCallOnScrollListenerWhenStopsScrolling = undefined\r\n\t\t\t\t\tthis.onScroll({ delayed: true })\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// `onStopScrolling()` feature is not currently used.\r\n\t\t\t\t// if (this.onStopScrollingListener) {\r\n\t\t\t\t// \tconst onStopScrollingListener = this.onStopScrollingListener\r\n\t\t\t\t// \tthis.onStopScrollingListener = undefined\r\n\t\t\t\t// \t// `onStopScrollingListener()` may hypothetically schedule\r\n\t\t\t\t// \t// another `onStopScrolling()` listener, so set\r\n\t\t\t\t// \t// `this.onStopScrollingListener` to `undefined` before\r\n\t\t\t\t// \t// calling it rather than after.\r\n\t\t\t\t// \tlog('~ The user has stopped scrolling ~')\r\n\t\t\t\t// \tonStopScrollingListener()\r\n\t\t\t\t// }\r\n\t\t\t},\r\n\t\t\t// \"scroll\" events are usually dispatched every 16 milliseconds\r\n\t\t\t// for 60fps refresh rate, so waiting for 100 milliseconds feels\r\n\t\t\t// reasonable: that would be about 6 frames of inactivity period,\r\n\t\t\t// which could mean that either the user has stopped scrolling\r\n\t\t\t// (for a moment) or the browser is lagging and stuttering\r\n\t\t\t// (skipping frames due to high load).\r\n\t\t\t// If the user continues scrolling then this timeout is constantly\r\n\t\t\t// refreshed (cancelled and then re-created).\r\n\t\t\tON_STOP_SCROLLING_INACTIVE_PERIOD\r\n\t\t)\r\n\t}\r\n\r\n\t// (this function isn't currently used)\r\n\t// onStopScrolling(onStopScrollingListener) {\r\n\t// \tthis.onStopScrollingListener = onStopScrollingListener\r\n\t// \tif (!this.onStopScrollingTimer) {\r\n\t// \t\tthis.watchOnStopScrolling()\r\n\t// \t}\r\n\t// }\r\n\r\n\t/**\r\n\t * Returns visible area coordinates relative to the scrollable container.\r\n\t * @return {object} `{ top: number, bottom: number }`\r\n\t */\r\n\tgetVisibleAreaBounds() {\r\n\t\tconst scrollY = this.getScrollY()\r\n\t\treturn {\r\n\t\t\t// The first pixel of the screen.\r\n\t\t\ttop: scrollY,\r\n\t\t\t// The pixel after the last pixel of the screen.\r\n\t\t\tbottom: scrollY + this.scrollableContainer.getHeight()\r\n\t\t}\r\n\t}\r\n}\r\n\r\nconst ON_STOP_SCROLLING_INACTIVE_PERIOD = 100"],"mappings":"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"}
|
|
@@ -43,8 +43,8 @@ export default function VirtualScrollerConstructor(getItemsContainerElement, ite
|
|
|
43
43
|
getEstimatedInterItemVerticalSpacing = options.getEstimatedInterItemVerticalSpacing,
|
|
44
44
|
onItemInitialRender = options.onItemInitialRender,
|
|
45
45
|
onItemFirstRender = options.onItemFirstRender,
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
delayRecursiveRenderUntilNextTick = options.delayRecursiveRenderUntilNextTick,
|
|
47
|
+
_delayUnnecessaryRerenderUntilStopsScrolling = options._delayUnnecessaryRerenderUntilStopsScrolling,
|
|
48
48
|
engine = options.engine;
|
|
49
49
|
var getEstimatedItemHeight = options.getEstimatedItemHeight,
|
|
50
50
|
getScrollableContainer = options.getScrollableContainer;
|
|
@@ -127,7 +127,7 @@ export default function VirtualScrollerConstructor(getItemsContainerElement, ite
|
|
|
127
127
|
// `.setState()` inside `componentWillUpdate()` or `componentDidUpdate()`.
|
|
128
128
|
// React limits the number of nested updates to prevent infinite loops."
|
|
129
129
|
|
|
130
|
-
this.
|
|
130
|
+
this._delayRecursiveRenderUntilNextTick = delayRecursiveRenderUntilNextTick; // `_getItemId()` function is used in `_getItemIndexByItemOrIndex()` function.
|
|
131
131
|
|
|
132
132
|
this._getItemId = getItemId;
|
|
133
133
|
|
|
@@ -204,7 +204,7 @@ export default function VirtualScrollerConstructor(getItemsContainerElement, ite
|
|
|
204
204
|
measureItemsBatchSize: measureItemsBatchSize,
|
|
205
205
|
initialScrollPosition: initialScrollPosition,
|
|
206
206
|
onScrollPositionChange: onScrollPositionChange,
|
|
207
|
-
|
|
207
|
+
delayUnnecessaryRerenderUntilStopsScrolling: _delayUnnecessaryRerenderUntilStopsScrolling
|
|
208
208
|
});
|
|
209
209
|
|
|
210
210
|
if (state) {
|
|
@@ -224,7 +224,7 @@ function createHelpers(_ref) {
|
|
|
224
224
|
measureItemsBatchSize = _ref.measureItemsBatchSize,
|
|
225
225
|
initialScrollPosition = _ref.initialScrollPosition,
|
|
226
226
|
onScrollPositionChange = _ref.onScrollPositionChange,
|
|
227
|
-
|
|
227
|
+
delayUnnecessaryRerenderUntilStopsScrolling = _ref.delayUnnecessaryRerenderUntilStopsScrolling;
|
|
228
228
|
this.itemsContainer = this.engine.createItemsContainer(this.getItemsContainerElement);
|
|
229
229
|
|
|
230
230
|
this.isItemsContainerElementTableBody = function () {
|
|
@@ -365,7 +365,7 @@ function createHelpers(_ref) {
|
|
|
365
365
|
isInBypassMode: this.isInBypassMode,
|
|
366
366
|
scrollableContainer: this.scrollableContainer,
|
|
367
367
|
itemsContainer: this.itemsContainer,
|
|
368
|
-
|
|
368
|
+
delayUnnecessaryRerenderUntilStopsScrolling: delayUnnecessaryRerenderUntilStopsScrolling,
|
|
369
369
|
onScroll: function onScroll() {
|
|
370
370
|
var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
|
371
371
|
delayed = _ref2.delayed;
|
|
@@ -401,8 +401,7 @@ function createHelpers(_ref) {
|
|
|
401
401
|
if (this.engine.watchListTopOffset) {
|
|
402
402
|
this.listTopOffsetWatcher = this.engine.watchListTopOffset({
|
|
403
403
|
getListTopOffset: this.getListTopOffsetInsideScrollableContainer,
|
|
404
|
-
onListTopOffsetChange: function onListTopOffsetChange(
|
|
405
|
-
var reason = _ref3.reason;
|
|
404
|
+
onListTopOffsetChange: function onListTopOffsetChange() {
|
|
406
405
|
return _this2.onUpdateShownItemIndexes({
|
|
407
406
|
reason: LAYOUT_REASON.TOP_OFFSET_CHANGED
|
|
408
407
|
});
|