Socket
Socket
Sign inDemoInstall

virtual-scroller

Package Overview
Dependencies
3
Maintainers
1
Versions
78
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.11.1 to 1.11.2

commonjs/react/useHandleItemIndexesChange.js

31

commonjs/DOM/ItemsContainer.js

@@ -24,13 +24,26 @@ "use strict";

}
/**
* Returns an item element's "top offset", relative to the items `container`'s top edge.
* @param {number} renderedElementIndex — An index of an item relative to the "first shown item index". For example, if the list is showing items from index 8 to index 12 then `renderedElementIndex = 0` would mean the item at index `8`.
* @return {number}
*/
_createClass(ItemsContainer, [{
key: "_getNthRenderedItemElement",
value: function _getNthRenderedItemElement(renderedElementIndex) {
var childNodes = this.getElement().childNodes;
_createClass(ItemsContainer, [{
if (renderedElementIndex > childNodes.length - 1) {
console.log('~ Items Container Contents ~');
console.log(this.getElement().innerHTML);
throw new Error("Element with index ".concat(renderedElementIndex, " was not found in the list of Rendered Item Elements in the Items Container of Virtual Scroller. There're only ").concat(childNodes.length, " Elements there."));
}
return childNodes[renderedElementIndex];
}
/**
* Returns an item element's "top offset", relative to the items `container`'s top edge.
* @param {number} renderedElementIndex — An index of an item relative to the "first shown item index". For example, if the list is showing items from index 8 to index 12 then `renderedElementIndex = 0` would mean the item at index `8`.
* @return {number}
*/
}, {
key: "getNthRenderedItemTopOffset",
value: function getNthRenderedItemTopOffset(renderedElementIndex) {
return this.getElement().childNodes[renderedElementIndex].getBoundingClientRect().top - this.getElement().getBoundingClientRect().top;
return this._getNthRenderedItemElement(renderedElementIndex).getBoundingClientRect().top - this.getElement().getBoundingClientRect().top;
}

@@ -47,4 +60,4 @@ /**

// `offsetHeight` is not precise enough (doesn't return fractional pixels).
// return this.getElement().childNodes[renderedElementIndex].offsetHeight
return this.getElement().childNodes[renderedElementIndex].getBoundingClientRect().height;
// return this._getNthRenderedItemElement(renderedElementIndex).offsetHeight
return this._getNthRenderedItemElement(renderedElementIndex).getBoundingClientRect().height;
}

@@ -51,0 +64,0 @@ /**

@@ -211,3 +211,3 @@ "use strict";

if (previousHeight !== _height) {
(0, _debug.warn)('Item index', i, 'height changed unexpectedly: it was', previousHeight, 'before, but now it is', _height, '. An item\'s height is allowed to change only in two cases: when the item\'s "state" changes and the developer calls `setItemState(i, newState)`, or when the item\'s height changes for some other reason and the developer calls `onItemHeightChange(i)`. Perhaps you forgot to persist the item\'s "state" by calling `setItemState(i, newState)` when it changed, and that "state" got lost when the item element was unmounted, which resulted in a different height when the item was shown again having its "state" reset.'); // Update the item's height as an attempt to fix things.
(0, _debug.warn)('Item index', i, 'height changed unexpectedly: it was', previousHeight, 'before, but now it is', _height, '. An item\'s height is allowed to change only in two cases: when the item\'s "state" changes and the developer calls `setItemState(i, newState)`, or when the item\'s height changes for any reason and the developer calls `onItemHeightChange(i)`. Perhaps you forgot to persist the item\'s "state" by calling `setItemState(i, newState)` when it changed, and that "state" got lost when the item element was unmounted, which resulted in a different height when the item was shown again having its "state" reset.'); // Update the item's height as an attempt to fix things.

@@ -214,0 +214,0 @@ this._set(i, _height);

@@ -11,7 +11,7 @@ "use strict";

function useOnItemHeightChange(_ref) {
var items = _ref.items,
var initialItemsCount = _ref.initialItemsCount,
virtualScroller = _ref.virtualScroller;
// Only compute the initial cache value once.
var initialCacheValue = (0, _react.useMemo)(function () {
return new Array(items.length);
return new Array(initialItemsCount);
}, []); // Handler functions cache.

@@ -18,0 +18,0 @@

@@ -11,7 +11,7 @@ "use strict";

function useSetItemState(_ref) {
var items = _ref.items,
var initialItemsCount = _ref.initialItemsCount,
virtualScroller = _ref.virtualScroller;
// Only compute the initial cache value once.
var initialCacheValue = (0, _react.useMemo)(function () {
return new Array(items.length);
return new Array(initialItemsCount);
}, []); // Handler functions cache.

@@ -18,0 +18,0 @@

@@ -32,51 +32,38 @@ "use strict";

onRender = _ref.onRender,
items = _ref.items;
itemsProperty = _ref.itemsProperty,
USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION = _ref.USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION;
// `VirtualScroller` state.
// This is a utility state variable that is used to re-render the component.
// It should not be used to access the current `VirtualScroller` state.
// It's more of a "requested" `VirtualScroller` state.
//
// The `_stateUpdate` variable shouldn't be used directly
// because in some cases its value may not represent
// the actual `state` of the `VirtualScroller`.
// It will also be stale in cases when `USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION`
// feature is used for setting new `items` in state.
//
// * It will contain an incorrect initial value if `initialState` property is passed
// because it doesn't get initialized to `initialState`.
//
// * If `items` property gets changed, `state` reference variable gets updated immediately
// but the `_stateUpdate` variable here doesn't (until the component re-renders some other time).
//
// Instead, use the `state` reference below.
//
var _useState2 = (0, _react.useState)(),
var _useState2 = (0, _react.useState)(initialState),
_useState3 = _slicedToArray(_useState2, 2),
_stateUpdate = _useState3[0],
_setStateUpdate = _useState3[1]; // This `state` reference is used for accessing the externally stored
// virtual scroller state from inside a `VirtualScroller` instance.
//
// It's also the "source of truth" on the actual `VirtualScroller` state.
//
_newState = _useState3[0],
_setNewState = _useState3[1]; // This `state` reference is what `VirtualScroller` uses internally.
// It's the "source of truth" on the actual `VirtualScroller` state.
var state = (0, _react.useRef)(initialState); // Accumulates state updates until they have been applied.
var state = (0, _react.useRef)(initialState);
var setState = (0, _react.useCallback)(function (newState) {
state.current = newState;
}, []); // Accumulates all "pending" state updates until they have been applied.
var targetState = (0, _react.useRef)(initialState); // Update the current state reference.
//
// Ignores the cases when `state` reference has already been updated
// "immediately" bypassing a `_setStateUpdate()` call, because
// in that case, `_stateUpdate` holds a stale value.
//
var nextState = (0, _react.useRef)(initialState); // Updates the actual `VirtualScroller` state right after a requested state update
// has been applied. Doesn't do anything at initial render.
if (state.current !== targetState.current) {
state.current = _stateUpdate;
} // Call `onRender()` right after every state update.
//
// When `items` property changes, `useHandleItemsChange()` hook doesn't call
// `_setStateUpdate()` because there's no need for a re-render.
// But chaning `items` still does trigger a `VirtualScroller` state update,
// so added `items` property in the list of this "effect"'s dependencies.
//
(0, _react.useLayoutEffect)(function () {
setState(_newState);
}, [_newState]); // Calls `onRender()` right after every state update (which is a re-render),
// and also right after the initial render.
(0, _react.useLayoutEffect)(function () {
onRender();
}, [_stateUpdate, items]);
}, [_newState, // When using `USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION` feature,
// there won't be a `_setNewState()` function call when `items` property changes,
// hence the additional `itemsProperty` dependency.
USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION ? itemsProperty : undefined]);
return {

@@ -86,15 +73,19 @@ getState: function getState() {

},
// Updates existing state.
getNextState: function getNextState() {
return nextState.current;
},
// Requests a state update.
//
// State updates are incremental meaning that this code should mimick
// State updates are incremental meaning that this function mimicks
// the classic `React.Component`'s `this.setState()` behavior
// when calling `this.setState()` doesn't replace `state` but rather merges
// a set of the updated state properties with the rest of the old ones.
// when calling `this.setState()` didn't replace `state` but rather merged
// the updated state properties over the "old" state properties.
//
// The reason is that `useState()` updates are "asynchronous" (not immediate),
// The reason for using pending state updates accumulation is that
// `useState()` updates are "asynchronous" (not immediate),
// and simply merging over `...state` would merge over potentially stale
// property values in cases when more than a single `updateState()` call is made
// before the state actually updates, resulting in losing some of the state updates.
// before the state actually updates, resulting in losing some of those state updates.
//
// For example, the first `updateState()` call updates shown item indexes,
// Example: the first `updateState()` call updates shown item indexes,
// and the second `updateState()` call updates `verticalSpacing`.

@@ -105,22 +96,10 @@ // If it was simply `updateState({ ...state, ...stateUpdate })`

//
// Using `...state.current` instead of `...pendingState.current` here
// would produce "stale" results.
//
updateState: function updateState(stateUpdate) {
var newState = _objectSpread(_objectSpread({}, targetState.current), stateUpdate);
targetState.current = newState; // If `items` property did change the component detects it at render time
// and updates `VirtualScroller` items immediately by calling `.setItems()`.
// But, since all of that happens at render time and not in an "effect",
// if the state update was done as usual by calling `_setStateUpdate()`,
// React would throw an error about updating state during render.
// Hence, state update in that particular case should happen "directly",
// without waiting for an "asynchronous" effect to trigger and call
// an "asyncronous" `_setStateUpdate()` function.
nextState.current = _objectSpread(_objectSpread({}, nextState.current), stateUpdate); // If `items` property did change, the component detects it at render time
// and updates `VirtualScroller` items immediately by calling `.setItems()`,
// which, in turn, immediately calls this `updateState()` function
// with a `stateUpdate` argument that contains the new `items`,
// so checking for `stateUpdate.items` could detect situations like that.
//
// Updating state directly in that particular case works because there
// already is a render ongoing, so there's no need to re-render the component
// again after such render-time state update.
//
// When the initial `VirtualScroller` state is being set, it contains an `.items`
// When the initial `VirtualScroller` state is being set, it contains the `.items`
// property too, but that initial setting is done using another function called

@@ -132,9 +111,8 @@ // `setInitialState()`, so using `if (stateUpdate.items)` condition here for describing

if (stateUpdate.items) {
// If a `stateUpdate` contains `items` then it means that there was a `setItems()` call.
// No need to trigger a re-render — the component got re-rendered anyway.
// Just update the `state` "in place".
state.current = newState;
var _newState = nextState.current;
if (stateUpdate.items && USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION) {
setState(_newState);
} else {
_setStateUpdate(newState);
_setNewState(_newState);
}

@@ -141,0 +119,0 @@ }

@@ -14,3 +14,3 @@ "use strict";

var tbody = _ref.tbody,
virtualScroller = _ref.virtualScroller;
getNextState = _ref.getNextState;

@@ -21,5 +21,5 @@ if (tbody) {

var _virtualScroller$getS = virtualScroller.getState(),
beforeItemsHeight = _virtualScroller$getS.beforeItemsHeight,
afterItemsHeight = _virtualScroller$getS.afterItemsHeight;
var _getNextState = getNextState(),
beforeItemsHeight = _getNextState.beforeItemsHeight,
afterItemsHeight = _getNextState.afterItemsHeight;

@@ -26,0 +26,0 @@ return {

@@ -28,4 +28,6 @@ "use strict";

var _useHandleItemsChange = _interopRequireDefault(require("./useHandleItemsChange.js"));
var _useHandleItemsPropertyChange = _interopRequireDefault(require("./useHandleItemsPropertyChange.js"));
var _useHandleItemIndexesChange = _interopRequireDefault(require("./useHandleItemIndexesChange.js"));
var _useClassName = _interopRequireDefault(require("./useClassName.js"));

@@ -49,5 +51,27 @@

// When `items` property changes, `useHandleItemsPropertyChange()` hook detects that
// and calls `VirtualScroller.setItems()` which in turn calls the `updateState()` function.
// At this point, an insignificant optimization could be applied:
// the component could avoid re-rendering the second time.
// Instead, the state update could be applied "immediately" if it originated
// from `.setItems()` function call, eliminating the unneeded second re-render.
//
// I could see how this minor optimization could get brittle when modifiying the code,
// so I put it under a feature flag so that it could potentially be turned off
// in case of any potential weird issues in some future.
//
// Another reason for using this feature is:
//
// Since `useHandleItemsPropertyChange()` runs at render time
// and not after the render has finished (not in an "effect"),
// if the state update was done "conventionally" (by calling `_setNewState()`),
// React would throw an error about updating state during render.
// No one knows what the original error message was.
// Perhaps it's no longer relevant in newer versions of React.
//
var USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION = true;
function VirtualScroller(_ref, ref) {
var AsComponent = _ref.as,
items = _ref.items,
itemsProperty = _ref.items,
Component = _ref.itemComponent,

@@ -82,3 +106,3 @@ itemComponentProps = _ref.itemComponentProps,

var virtualScroller = (0, _useVirtualScroller["default"])({
items: items,
items: itemsProperty,
// `estimatedItemHeight` property name is deprecated,

@@ -121,6 +145,8 @@ // use `getEstimatedItemHeight` property instead.

onRender: virtualScroller.onRender,
items: items
itemsProperty: itemsProperty,
USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION: USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION
}),
getState = _useState.getState,
updateState = _useState.updateState; // Use custom (external) state storage in the `VirtualScroller`.
updateState = _useState.updateState,
getNextState = _useState.getNextState; // Use custom (external) state storage in the `VirtualScroller`.

@@ -148,3 +174,3 @@

var getSetItemState = (0, _useSetItemState["default"])({
items: items,
initialItemsCount: itemsProperty.length,
virtualScroller: virtualScroller

@@ -155,7 +181,7 @@ }); // Cache per-item `onItemHeightChange` functions' "references"

var getOnItemHeightChange = (0, _useOnItemHeightChange["default"])({
items: items,
initialItemsCount: itemsProperty.length,
virtualScroller: virtualScroller
}); // Detect if `items` have changed.
}); // Calls `.setItems()` if `items` property has changed.
(0, _useHandleItemsChange["default"])(items, {
(0, _useHandleItemsPropertyChange["default"])(itemsProperty, {
virtualScroller: virtualScroller,

@@ -166,2 +192,8 @@ // `preserveScrollPosition` property name is deprecated,

preserveScrollPositionOnPrependItems: preserveScrollPositionOnPrependItems,
nextItems: getNextState().items
}); // Updates `key`s if item indexes have changed.
(0, _useHandleItemIndexesChange["default"])({
virtualScroller: virtualScroller,
itemsBeingRendered: getNextState().items,
updateItemKeysForNewItems: updateItemKeysForNewItems

@@ -200,10 +232,10 @@ }); // Add instance methods to the React component.

tbody: tbody,
virtualScroller: virtualScroller
getNextState: getNextState
});
var _virtualScroller$getS = virtualScroller.getState(),
renderedItems = _virtualScroller$getS.items,
itemStates = _virtualScroller$getS.itemStates,
firstShownItemIndex = _virtualScroller$getS.firstShownItemIndex,
lastShownItemIndex = _virtualScroller$getS.lastShownItemIndex;
var _getNextState = getNextState(),
currentItems = _getNextState.items,
itemStates = _getNextState.itemStates,
firstShownItemIndex = _getNextState.firstShownItemIndex,
lastShownItemIndex = _getNextState.lastShownItemIndex;

@@ -214,3 +246,3 @@ return /*#__PURE__*/_react["default"].createElement(AsComponent, _extends({}, rest, {

style: style
}), renderedItems.map(function (item, i) {
}), currentItems.map(function (item, i) {
if (i >= firstShownItemIndex && i <= lastShownItemIndex) {

@@ -217,0 +249,0 @@ // * Passing `item` as `children` property is legacy and is deprecated.

@@ -399,3 +399,3 @@ "use strict";

(0, _debug["default"])('~ Re-measure item height ~');
(0, _debug["default"])('Item', i);
(0, _debug["default"])('Item index', i);

@@ -434,3 +434,3 @@ var _this$getState2 = _this.getState(),

// `.onItemHeightChange(i)` gets called.
return (0, _debug.warn)('The item is no longer rendered. This is not necessarily a bug, and could happen, for example, when there\'re several `onItemHeightChange(i)` calls issued at the same time.');
return (0, _debug.warn)('The item is no longer rendered. This is not necessarily a bug, and could happen, for example, when when a developer calls `onItemHeightChange(i)` while looping through a batch of items.');
}

@@ -437,0 +437,0 @@

@@ -66,3 +66,3 @@ "use strict";

(0, _debug["default"])('~ Item state changed ~');
(0, _debug["default"])('Item', i); // Uses `JSON.stringify()` here instead of just outputting the JSON objects as is
(0, _debug["default"])('Item index', i); // Uses `JSON.stringify()` here instead of just outputting the JSON objects as is
// because outputting JSON objects as is would show different results later when

@@ -69,0 +69,0 @@ // the developer inspects those in the web browser console if those state objects

@@ -17,13 +17,26 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

}
/**
* Returns an item element's "top offset", relative to the items `container`'s top edge.
* @param {number} renderedElementIndex — An index of an item relative to the "first shown item index". For example, if the list is showing items from index 8 to index 12 then `renderedElementIndex = 0` would mean the item at index `8`.
* @return {number}
*/
_createClass(ItemsContainer, [{
key: "_getNthRenderedItemElement",
value: function _getNthRenderedItemElement(renderedElementIndex) {
var childNodes = this.getElement().childNodes;
_createClass(ItemsContainer, [{
if (renderedElementIndex > childNodes.length - 1) {
console.log('~ Items Container Contents ~');
console.log(this.getElement().innerHTML);
throw new Error("Element with index ".concat(renderedElementIndex, " was not found in the list of Rendered Item Elements in the Items Container of Virtual Scroller. There're only ").concat(childNodes.length, " Elements there."));
}
return childNodes[renderedElementIndex];
}
/**
* Returns an item element's "top offset", relative to the items `container`'s top edge.
* @param {number} renderedElementIndex — An index of an item relative to the "first shown item index". For example, if the list is showing items from index 8 to index 12 then `renderedElementIndex = 0` would mean the item at index `8`.
* @return {number}
*/
}, {
key: "getNthRenderedItemTopOffset",
value: function getNthRenderedItemTopOffset(renderedElementIndex) {
return this.getElement().childNodes[renderedElementIndex].getBoundingClientRect().top - this.getElement().getBoundingClientRect().top;
return this._getNthRenderedItemElement(renderedElementIndex).getBoundingClientRect().top - this.getElement().getBoundingClientRect().top;
}

@@ -40,4 +53,4 @@ /**

// `offsetHeight` is not precise enough (doesn't return fractional pixels).
// return this.getElement().childNodes[renderedElementIndex].offsetHeight
return this.getElement().childNodes[renderedElementIndex].getBoundingClientRect().height;
// return this._getNthRenderedItemElement(renderedElementIndex).offsetHeight
return this._getNthRenderedItemElement(renderedElementIndex).getBoundingClientRect().height;
}

@@ -44,0 +57,0 @@ /**

@@ -198,3 +198,3 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

if (previousHeight !== _height) {
warn('Item index', i, 'height changed unexpectedly: it was', previousHeight, 'before, but now it is', _height, '. An item\'s height is allowed to change only in two cases: when the item\'s "state" changes and the developer calls `setItemState(i, newState)`, or when the item\'s height changes for some other reason and the developer calls `onItemHeightChange(i)`. Perhaps you forgot to persist the item\'s "state" by calling `setItemState(i, newState)` when it changed, and that "state" got lost when the item element was unmounted, which resulted in a different height when the item was shown again having its "state" reset.'); // Update the item's height as an attempt to fix things.
warn('Item index', i, 'height changed unexpectedly: it was', previousHeight, 'before, but now it is', _height, '. An item\'s height is allowed to change only in two cases: when the item\'s "state" changes and the developer calls `setItemState(i, newState)`, or when the item\'s height changes for any reason and the developer calls `onItemHeightChange(i)`. Perhaps you forgot to persist the item\'s "state" by calling `setItemState(i, newState)` when it changed, and that "state" got lost when the item element was unmounted, which resulted in a different height when the item was shown again having its "state" reset.'); // Update the item's height as an attempt to fix things.

@@ -201,0 +201,0 @@ this._set(i, _height);

import { useMemo, useRef, useCallback } from 'react';
export default function useOnItemHeightChange(_ref) {
var items = _ref.items,
var initialItemsCount = _ref.initialItemsCount,
virtualScroller = _ref.virtualScroller;
// Only compute the initial cache value once.
var initialCacheValue = useMemo(function () {
return new Array(items.length);
return new Array(initialItemsCount);
}, []); // Handler functions cache.

@@ -9,0 +9,0 @@

import { useMemo, useRef, useCallback } from 'react';
export default function useSetItemState(_ref) {
var items = _ref.items,
var initialItemsCount = _ref.initialItemsCount,
virtualScroller = _ref.virtualScroller;
// Only compute the initial cache value once.
var initialCacheValue = useMemo(function () {
return new Array(items.length);
return new Array(initialItemsCount);
}, []); // Handler functions cache.

@@ -9,0 +9,0 @@

@@ -19,3 +19,3 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

import { useState, useRef, useLayoutEffect } from 'react'; // Creates state management functions.
import { useState, useRef, useCallback, useLayoutEffect } from 'react'; // Creates state management functions.

@@ -25,51 +25,38 @@ export default function _useState(_ref) {

onRender = _ref.onRender,
items = _ref.items;
itemsProperty = _ref.itemsProperty,
USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION = _ref.USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION;
// `VirtualScroller` state.
// This is a utility state variable that is used to re-render the component.
// It should not be used to access the current `VirtualScroller` state.
// It's more of a "requested" `VirtualScroller` state.
//
// The `_stateUpdate` variable shouldn't be used directly
// because in some cases its value may not represent
// the actual `state` of the `VirtualScroller`.
// It will also be stale in cases when `USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION`
// feature is used for setting new `items` in state.
//
// * It will contain an incorrect initial value if `initialState` property is passed
// because it doesn't get initialized to `initialState`.
//
// * If `items` property gets changed, `state` reference variable gets updated immediately
// but the `_stateUpdate` variable here doesn't (until the component re-renders some other time).
//
// Instead, use the `state` reference below.
//
var _useState2 = useState(),
var _useState2 = useState(initialState),
_useState3 = _slicedToArray(_useState2, 2),
_stateUpdate = _useState3[0],
_setStateUpdate = _useState3[1]; // This `state` reference is used for accessing the externally stored
// virtual scroller state from inside a `VirtualScroller` instance.
//
// It's also the "source of truth" on the actual `VirtualScroller` state.
//
_newState = _useState3[0],
_setNewState = _useState3[1]; // This `state` reference is what `VirtualScroller` uses internally.
// It's the "source of truth" on the actual `VirtualScroller` state.
var state = useRef(initialState); // Accumulates state updates until they have been applied.
var state = useRef(initialState);
var setState = useCallback(function (newState) {
state.current = newState;
}, []); // Accumulates all "pending" state updates until they have been applied.
var targetState = useRef(initialState); // Update the current state reference.
//
// Ignores the cases when `state` reference has already been updated
// "immediately" bypassing a `_setStateUpdate()` call, because
// in that case, `_stateUpdate` holds a stale value.
//
var nextState = useRef(initialState); // Updates the actual `VirtualScroller` state right after a requested state update
// has been applied. Doesn't do anything at initial render.
if (state.current !== targetState.current) {
state.current = _stateUpdate;
} // Call `onRender()` right after every state update.
//
// When `items` property changes, `useHandleItemsChange()` hook doesn't call
// `_setStateUpdate()` because there's no need for a re-render.
// But chaning `items` still does trigger a `VirtualScroller` state update,
// so added `items` property in the list of this "effect"'s dependencies.
//
useLayoutEffect(function () {
setState(_newState);
}, [_newState]); // Calls `onRender()` right after every state update (which is a re-render),
// and also right after the initial render.
useLayoutEffect(function () {
onRender();
}, [_stateUpdate, items]);
}, [_newState, // When using `USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION` feature,
// there won't be a `_setNewState()` function call when `items` property changes,
// hence the additional `itemsProperty` dependency.
USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION ? itemsProperty : undefined]);
return {

@@ -79,15 +66,19 @@ getState: function getState() {

},
// Updates existing state.
getNextState: function getNextState() {
return nextState.current;
},
// Requests a state update.
//
// State updates are incremental meaning that this code should mimick
// State updates are incremental meaning that this function mimicks
// the classic `React.Component`'s `this.setState()` behavior
// when calling `this.setState()` doesn't replace `state` but rather merges
// a set of the updated state properties with the rest of the old ones.
// when calling `this.setState()` didn't replace `state` but rather merged
// the updated state properties over the "old" state properties.
//
// The reason is that `useState()` updates are "asynchronous" (not immediate),
// The reason for using pending state updates accumulation is that
// `useState()` updates are "asynchronous" (not immediate),
// and simply merging over `...state` would merge over potentially stale
// property values in cases when more than a single `updateState()` call is made
// before the state actually updates, resulting in losing some of the state updates.
// before the state actually updates, resulting in losing some of those state updates.
//
// For example, the first `updateState()` call updates shown item indexes,
// Example: the first `updateState()` call updates shown item indexes,
// and the second `updateState()` call updates `verticalSpacing`.

@@ -98,22 +89,10 @@ // If it was simply `updateState({ ...state, ...stateUpdate })`

//
// Using `...state.current` instead of `...pendingState.current` here
// would produce "stale" results.
//
updateState: function updateState(stateUpdate) {
var newState = _objectSpread(_objectSpread({}, targetState.current), stateUpdate);
targetState.current = newState; // If `items` property did change the component detects it at render time
// and updates `VirtualScroller` items immediately by calling `.setItems()`.
// But, since all of that happens at render time and not in an "effect",
// if the state update was done as usual by calling `_setStateUpdate()`,
// React would throw an error about updating state during render.
// Hence, state update in that particular case should happen "directly",
// without waiting for an "asynchronous" effect to trigger and call
// an "asyncronous" `_setStateUpdate()` function.
nextState.current = _objectSpread(_objectSpread({}, nextState.current), stateUpdate); // If `items` property did change, the component detects it at render time
// and updates `VirtualScroller` items immediately by calling `.setItems()`,
// which, in turn, immediately calls this `updateState()` function
// with a `stateUpdate` argument that contains the new `items`,
// so checking for `stateUpdate.items` could detect situations like that.
//
// Updating state directly in that particular case works because there
// already is a render ongoing, so there's no need to re-render the component
// again after such render-time state update.
//
// When the initial `VirtualScroller` state is being set, it contains an `.items`
// When the initial `VirtualScroller` state is being set, it contains the `.items`
// property too, but that initial setting is done using another function called

@@ -125,9 +104,8 @@ // `setInitialState()`, so using `if (stateUpdate.items)` condition here for describing

if (stateUpdate.items) {
// If a `stateUpdate` contains `items` then it means that there was a `setItems()` call.
// No need to trigger a re-render — the component got re-rendered anyway.
// Just update the `state` "in place".
state.current = newState;
var _newState = nextState.current;
if (stateUpdate.items && USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION) {
setState(_newState);
} else {
_setStateUpdate(newState);
_setNewState(_newState);
}

@@ -134,0 +112,0 @@ }

import px from '../utility/px.js';
export default function useStyle(_ref) {
var tbody = _ref.tbody,
virtualScroller = _ref.virtualScroller;
getNextState = _ref.getNextState;

@@ -10,5 +10,5 @@ if (tbody) {

var _virtualScroller$getS = virtualScroller.getState(),
beforeItemsHeight = _virtualScroller$getS.beforeItemsHeight,
afterItemsHeight = _virtualScroller$getS.afterItemsHeight;
var _getNextState = getNextState(),
beforeItemsHeight = _getNextState.beforeItemsHeight,
afterItemsHeight = _getNextState.afterItemsHeight;

@@ -15,0 +15,0 @@ return {

@@ -18,9 +18,31 @@ var _excluded = ["as", "items", "itemComponent", "itemComponentProps", "estimatedItemHeight", "getEstimatedItemHeight", "getEstimatedVisibleItemRowsCount", "bypass", "tbody", "preserveScrollPosition", "preserveScrollPositionOnPrependItems", "measureItemsBatchSize", "scrollableContainer", "getScrollableContainer", "getColumnsCount", "getItemId", "className", "onMount", "onItemFirstRender", "onItemInitialRender", "initialScrollPosition", "onScrollPositionChange", "onStateChange", "initialState", "getInitialItemState"];

import useOnItemHeightChange from './useOnItemHeightChange.js';
import useHandleItemsChange from './useHandleItemsChange.js';
import useHandleItemsPropertyChange from './useHandleItemsPropertyChange.js';
import useHandleItemIndexesChange from './useHandleItemIndexesChange.js';
import useClassName from './useClassName.js';
import useStyle from './useStyle.js';
import useStyle from './useStyle.js'; // When `items` property changes, `useHandleItemsPropertyChange()` hook detects that
// and calls `VirtualScroller.setItems()` which in turn calls the `updateState()` function.
// At this point, an insignificant optimization could be applied:
// the component could avoid re-rendering the second time.
// Instead, the state update could be applied "immediately" if it originated
// from `.setItems()` function call, eliminating the unneeded second re-render.
//
// I could see how this minor optimization could get brittle when modifiying the code,
// so I put it under a feature flag so that it could potentially be turned off
// in case of any potential weird issues in some future.
//
// Another reason for using this feature is:
//
// Since `useHandleItemsPropertyChange()` runs at render time
// and not after the render has finished (not in an "effect"),
// if the state update was done "conventionally" (by calling `_setNewState()`),
// React would throw an error about updating state during render.
// No one knows what the original error message was.
// Perhaps it's no longer relevant in newer versions of React.
//
var USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION = true;
function VirtualScroller(_ref, ref) {
var AsComponent = _ref.as,
items = _ref.items,
itemsProperty = _ref.items,
Component = _ref.itemComponent,

@@ -55,3 +77,3 @@ itemComponentProps = _ref.itemComponentProps,

var virtualScroller = useVirtualScroller({
items: items,
items: itemsProperty,
// `estimatedItemHeight` property name is deprecated,

@@ -94,6 +116,8 @@ // use `getEstimatedItemHeight` property instead.

onRender: virtualScroller.onRender,
items: items
itemsProperty: itemsProperty,
USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION: USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION
}),
getState = _useState.getState,
updateState = _useState.updateState; // Use custom (external) state storage in the `VirtualScroller`.
updateState = _useState.updateState,
getNextState = _useState.getNextState; // Use custom (external) state storage in the `VirtualScroller`.

@@ -121,3 +145,3 @@

var getSetItemState = useSetItemState({
items: items,
initialItemsCount: itemsProperty.length,
virtualScroller: virtualScroller

@@ -128,7 +152,7 @@ }); // Cache per-item `onItemHeightChange` functions' "references"

var getOnItemHeightChange = useOnItemHeightChange({
items: items,
initialItemsCount: itemsProperty.length,
virtualScroller: virtualScroller
}); // Detect if `items` have changed.
}); // Calls `.setItems()` if `items` property has changed.
useHandleItemsChange(items, {
useHandleItemsPropertyChange(itemsProperty, {
virtualScroller: virtualScroller,

@@ -139,2 +163,8 @@ // `preserveScrollPosition` property name is deprecated,

preserveScrollPositionOnPrependItems: preserveScrollPositionOnPrependItems,
nextItems: getNextState().items
}); // Updates `key`s if item indexes have changed.
useHandleItemIndexesChange({
virtualScroller: virtualScroller,
itemsBeingRendered: getNextState().items,
updateItemKeysForNewItems: updateItemKeysForNewItems

@@ -173,10 +203,10 @@ }); // Add instance methods to the React component.

tbody: tbody,
virtualScroller: virtualScroller
getNextState: getNextState
});
var _virtualScroller$getS = virtualScroller.getState(),
renderedItems = _virtualScroller$getS.items,
itemStates = _virtualScroller$getS.itemStates,
firstShownItemIndex = _virtualScroller$getS.firstShownItemIndex,
lastShownItemIndex = _virtualScroller$getS.lastShownItemIndex;
var _getNextState = getNextState(),
currentItems = _getNextState.items,
itemStates = _getNextState.itemStates,
firstShownItemIndex = _getNextState.firstShownItemIndex,
lastShownItemIndex = _getNextState.lastShownItemIndex;

@@ -187,3 +217,3 @@ return /*#__PURE__*/React.createElement(AsComponent, _extends({}, rest, {

style: style
}), renderedItems.map(function (item, i) {
}), currentItems.map(function (item, i) {
if (i >= firstShownItemIndex && i <= lastShownItemIndex) {

@@ -190,0 +220,0 @@ // * Passing `item` as `children` property is legacy and is deprecated.

@@ -387,3 +387,3 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

log('~ Re-measure item height ~');
log('Item', i);
log('Item index', i);

@@ -422,3 +422,3 @@ var _this$getState2 = _this.getState(),

// `.onItemHeightChange(i)` gets called.
return warn('The item is no longer rendered. This is not necessarily a bug, and could happen, for example, when there\'re several `onItemHeightChange(i)` calls issued at the same time.');
return warn('The item is no longer rendered. This is not necessarily a bug, and could happen, for example, when when a developer calls `onItemHeightChange(i)` while looping through a batch of items.');
}

@@ -425,0 +425,0 @@

@@ -47,3 +47,3 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

log('~ Item state changed ~');
log('Item', i); // Uses `JSON.stringify()` here instead of just outputting the JSON objects as is
log('Item index', i); // Uses `JSON.stringify()` here instead of just outputting the JSON objects as is
// because outputting JSON objects as is would show different results later when

@@ -50,0 +50,0 @@ // the developer inspects those in the web browser console if those state objects

{
"name": "virtual-scroller",
"version": "1.11.1",
"version": "1.11.2",
"description": "A component for efficiently rendering large lists of variable height items",

@@ -5,0 +5,0 @@ "main": "index.cjs",

@@ -10,2 +10,12 @@ export default class ItemsContainer {

_getNthRenderedItemElement(renderedElementIndex) {
const childNodes = this.getElement().childNodes
if (renderedElementIndex > childNodes.length - 1) {
console.log('~ Items Container Contents ~')
console.log(this.getElement().innerHTML)
throw new Error(`Element with index ${renderedElementIndex} was not found in the list of Rendered Item Elements in the Items Container of Virtual Scroller. There're only ${childNodes.length} Elements there.`)
}
return childNodes[renderedElementIndex]
}
/**

@@ -17,3 +27,3 @@ * Returns an item element's "top offset", relative to the items `container`'s top edge.

getNthRenderedItemTopOffset(renderedElementIndex) {
return this.getElement().childNodes[renderedElementIndex].getBoundingClientRect().top - this.getElement().getBoundingClientRect().top
return this._getNthRenderedItemElement(renderedElementIndex).getBoundingClientRect().top - this.getElement().getBoundingClientRect().top
}

@@ -28,4 +38,4 @@

// `offsetHeight` is not precise enough (doesn't return fractional pixels).
// return this.getElement().childNodes[renderedElementIndex].offsetHeight
return this.getElement().childNodes[renderedElementIndex].getBoundingClientRect().height
// return this._getNthRenderedItemElement(renderedElementIndex).offsetHeight
return this._getNthRenderedItemElement(renderedElementIndex).getBoundingClientRect().height
}

@@ -32,0 +42,0 @@

@@ -172,3 +172,3 @@ import log, { warn, isDebug, reportError } from './utility/debug.js'

if (previousHeight !== height) {
warn('Item index', i, 'height changed unexpectedly: it was', previousHeight, 'before, but now it is', height, '. An item\'s height is allowed to change only in two cases: when the item\'s "state" changes and the developer calls `setItemState(i, newState)`, or when the item\'s height changes for some other reason and the developer calls `onItemHeightChange(i)`. Perhaps you forgot to persist the item\'s "state" by calling `setItemState(i, newState)` when it changed, and that "state" got lost when the item element was unmounted, which resulted in a different height when the item was shown again having its "state" reset.')
warn('Item index', i, 'height changed unexpectedly: it was', previousHeight, 'before, but now it is', height, '. An item\'s height is allowed to change only in two cases: when the item\'s "state" changes and the developer calls `setItemState(i, newState)`, or when the item\'s height changes for any reason and the developer calls `onItemHeightChange(i)`. Perhaps you forgot to persist the item\'s "state" by calling `setItemState(i, newState)` when it changed, and that "state" got lost when the item element was unmounted, which resulted in a different height when the item was shown again having its "state" reset.')
// Update the item's height as an attempt to fix things.

@@ -175,0 +175,0 @@ this._set(i, height)

import { useMemo, useRef, useCallback } from 'react'
export default function useOnItemHeightChange({
items,
initialItemsCount,
virtualScroller

@@ -9,3 +9,3 @@ }) {

const initialCacheValue = useMemo(() => {
return new Array(items.length)
return new Array(initialItemsCount)
}, [])

@@ -12,0 +12,0 @@

import { useMemo, useRef, useCallback } from 'react'
export default function useSetItemState({
items,
initialItemsCount,
virtualScroller

@@ -9,3 +9,3 @@ }) {

const initialCacheValue = useMemo(() => {
return new Array(items.length)
return new Array(initialItemsCount)
}, [])

@@ -12,0 +12,0 @@

@@ -1,53 +0,48 @@

import { useState, useRef, useLayoutEffect } from 'react'
import { useState, useRef, useCallback, useLayoutEffect } from 'react'
// Creates state management functions.
export default function _useState({ initialState, onRender, items }) {
// `VirtualScroller` state.
export default function _useState({
initialState,
onRender,
itemsProperty,
USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION
}) {
// This is a utility state variable that is used to re-render the component.
// It should not be used to access the current `VirtualScroller` state.
// It's more of a "requested" `VirtualScroller` state.
//
// The `_stateUpdate` variable shouldn't be used directly
// because in some cases its value may not represent
// the actual `state` of the `VirtualScroller`.
// It will also be stale in cases when `USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION`
// feature is used for setting new `items` in state.
//
// * It will contain an incorrect initial value if `initialState` property is passed
// because it doesn't get initialized to `initialState`.
//
// * If `items` property gets changed, `state` reference variable gets updated immediately
// but the `_stateUpdate` variable here doesn't (until the component re-renders some other time).
//
// Instead, use the `state` reference below.
//
const [_stateUpdate, _setStateUpdate] = useState()
const [_newState, _setNewState] = useState(initialState)
// This `state` reference is used for accessing the externally stored
// virtual scroller state from inside a `VirtualScroller` instance.
//
// It's also the "source of truth" on the actual `VirtualScroller` state.
//
// This `state` reference is what `VirtualScroller` uses internally.
// It's the "source of truth" on the actual `VirtualScroller` state.
const state = useRef(initialState)
// Accumulates state updates until they have been applied.
const targetState = useRef(initialState)
const setState = useCallback((newState) => {
state.current = newState
}, [])
// Update the current state reference.
//
// Ignores the cases when `state` reference has already been updated
// "immediately" bypassing a `_setStateUpdate()` call, because
// in that case, `_stateUpdate` holds a stale value.
//
if (state.current !== targetState.current) {
state.current = _stateUpdate
}
// Accumulates all "pending" state updates until they have been applied.
const nextState = useRef(initialState)
// Call `onRender()` right after every state update.
//
// When `items` property changes, `useHandleItemsChange()` hook doesn't call
// `_setStateUpdate()` because there's no need for a re-render.
// But chaning `items` still does trigger a `VirtualScroller` state update,
// so added `items` property in the list of this "effect"'s dependencies.
//
// Updates the actual `VirtualScroller` state right after a requested state update
// has been applied. Doesn't do anything at initial render.
useLayoutEffect(() => {
setState(_newState)
}, [
_newState
])
// Calls `onRender()` right after every state update (which is a re-render),
// and also right after the initial render.
useLayoutEffect(() => {
onRender()
}, [
_stateUpdate,
items
_newState,
// When using `USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION` feature,
// there won't be a `_setNewState()` function call when `items` property changes,
// hence the additional `itemsProperty` dependency.
USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION ? itemsProperty : undefined
])

@@ -58,15 +53,18 @@

// Updates existing state.
getNextState: () => nextState.current,
// Requests a state update.
//
// State updates are incremental meaning that this code should mimick
// State updates are incremental meaning that this function mimicks
// the classic `React.Component`'s `this.setState()` behavior
// when calling `this.setState()` doesn't replace `state` but rather merges
// a set of the updated state properties with the rest of the old ones.
// when calling `this.setState()` didn't replace `state` but rather merged
// the updated state properties over the "old" state properties.
//
// The reason is that `useState()` updates are "asynchronous" (not immediate),
// The reason for using pending state updates accumulation is that
// `useState()` updates are "asynchronous" (not immediate),
// and simply merging over `...state` would merge over potentially stale
// property values in cases when more than a single `updateState()` call is made
// before the state actually updates, resulting in losing some of the state updates.
// before the state actually updates, resulting in losing some of those state updates.
//
// For example, the first `updateState()` call updates shown item indexes,
// Example: the first `updateState()` call updates shown item indexes,
// and the second `updateState()` call updates `verticalSpacing`.

@@ -77,25 +75,14 @@ // If it was simply `updateState({ ...state, ...stateUpdate })`

//
// Using `...state.current` instead of `...pendingState.current` here
// would produce "stale" results.
//
updateState: (stateUpdate) => {
const newState = {
...targetState.current,
nextState.current = {
...nextState.current,
...stateUpdate
}
targetState.current = newState
// If `items` property did change the component detects it at render time
// and updates `VirtualScroller` items immediately by calling `.setItems()`.
// But, since all of that happens at render time and not in an "effect",
// if the state update was done as usual by calling `_setStateUpdate()`,
// React would throw an error about updating state during render.
// Hence, state update in that particular case should happen "directly",
// without waiting for an "asynchronous" effect to trigger and call
// an "asyncronous" `_setStateUpdate()` function.
// If `items` property did change, the component detects it at render time
// and updates `VirtualScroller` items immediately by calling `.setItems()`,
// which, in turn, immediately calls this `updateState()` function
// with a `stateUpdate` argument that contains the new `items`,
// so checking for `stateUpdate.items` could detect situations like that.
//
// Updating state directly in that particular case works because there
// already is a render ongoing, so there's no need to re-render the component
// again after such render-time state update.
//
// When the initial `VirtualScroller` state is being set, it contains an `.items`
// When the initial `VirtualScroller` state is being set, it contains the `.items`
// property too, but that initial setting is done using another function called

@@ -106,9 +93,7 @@ // `setInitialState()`, so using `if (stateUpdate.items)` condition here for describing

//
if (stateUpdate.items) {
// If a `stateUpdate` contains `items` then it means that there was a `setItems()` call.
// No need to trigger a re-render — the component got re-rendered anyway.
// Just update the `state` "in place".
state.current = newState
const _newState = nextState.current
if (stateUpdate.items && USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION) {
setState(_newState)
} else {
_setStateUpdate(newState)
_setNewState(_newState)
}

@@ -115,0 +100,0 @@ }

@@ -5,3 +5,3 @@ import px from '../utility/px.js'

tbody,
virtualScroller
getNextState
}) {

@@ -15,3 +15,3 @@ if (tbody) {

afterItemsHeight
} = virtualScroller.getState()
} = getNextState()

@@ -18,0 +18,0 @@ return {

@@ -11,9 +11,32 @@ import React, { useRef, useMemo, useLayoutEffect } from 'react'

import useOnItemHeightChange from './useOnItemHeightChange.js'
import useHandleItemsChange from './useHandleItemsChange.js'
import useHandleItemsPropertyChange from './useHandleItemsPropertyChange.js'
import useHandleItemIndexesChange from './useHandleItemIndexesChange.js'
import useClassName from './useClassName.js'
import useStyle from './useStyle.js'
// When `items` property changes, `useHandleItemsPropertyChange()` hook detects that
// and calls `VirtualScroller.setItems()` which in turn calls the `updateState()` function.
// At this point, an insignificant optimization could be applied:
// the component could avoid re-rendering the second time.
// Instead, the state update could be applied "immediately" if it originated
// from `.setItems()` function call, eliminating the unneeded second re-render.
//
// I could see how this minor optimization could get brittle when modifiying the code,
// so I put it under a feature flag so that it could potentially be turned off
// in case of any potential weird issues in some future.
//
// Another reason for using this feature is:
//
// Since `useHandleItemsPropertyChange()` runs at render time
// and not after the render has finished (not in an "effect"),
// if the state update was done "conventionally" (by calling `_setNewState()`),
// React would throw an error about updating state during render.
// No one knows what the original error message was.
// Perhaps it's no longer relevant in newer versions of React.
//
const USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION = true
function VirtualScroller({
as: AsComponent,
items,
items: itemsProperty,
itemComponent: Component,

@@ -56,3 +79,3 @@ itemComponentProps,

const virtualScroller = useVirtualScroller({
items,
items: itemsProperty,
// `estimatedItemHeight` property name is deprecated,

@@ -95,7 +118,9 @@ // use `getEstimatedItemHeight` property instead.

getState,
updateState
updateState,
getNextState
} = useState({
initialState: _initialState,
onRender: virtualScroller.onRender,
items
itemsProperty,
USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION
})

@@ -127,3 +152,3 @@

const getSetItemState = useSetItemState({
items,
initialItemsCount: itemsProperty.length,
virtualScroller

@@ -135,8 +160,8 @@ })

const getOnItemHeightChange = useOnItemHeightChange({
items,
initialItemsCount: itemsProperty.length,
virtualScroller
})
// Detect if `items` have changed.
useHandleItemsChange(items, {
// Calls `.setItems()` if `items` property has changed.
useHandleItemsPropertyChange(itemsProperty, {
virtualScroller,

@@ -147,2 +172,9 @@ // `preserveScrollPosition` property name is deprecated,

preserveScrollPositionOnPrependItems,
nextItems: getNextState().items
})
// Updates `key`s if item indexes have changed.
useHandleItemIndexesChange({
virtualScroller,
itemsBeingRendered: getNextState().items,
updateItemKeysForNewItems

@@ -186,11 +218,11 @@ })

tbody,
virtualScroller
getNextState
})
const {
items: renderedItems,
items: currentItems,
itemStates,
firstShownItemIndex,
lastShownItemIndex
} = virtualScroller.getState()
} = getNextState()

@@ -203,3 +235,3 @@ return (

style={style}>
{renderedItems.map((item, i) => {
{currentItems.map((item, i) => {
if (i >= firstShownItemIndex && i <= lastShownItemIndex) {

@@ -206,0 +238,0 @@ // * Passing `item` as `children` property is legacy and is deprecated.

@@ -375,3 +375,3 @@ // For some weird reason, in Chrome, `setTimeout()` would lag up to a second (or more) behind.

log('~ Re-measure item height ~')
log('Item', i)
log('Item index', i)

@@ -411,3 +411,3 @@ const {

// `.onItemHeightChange(i)` gets called.
return warn('The item is no longer rendered. This is not necessarily a bug, and could happen, for example, when there\'re several `onItemHeightChange(i)` calls issued at the same time.')
return warn('The item is no longer rendered. This is not necessarily a bug, and could happen, for example, when when a developer calls `onItemHeightChange(i)` while looping through a batch of items.')
}

@@ -414,0 +414,0 @@

@@ -43,3 +43,3 @@ import fillArray from './utility/fillArray.js'

log('~ Item state changed ~')
log('Item', i)
log('Item index', i)
// Uses `JSON.stringify()` here instead of just outputting the JSON objects as is

@@ -46,0 +46,0 @@ // because outputting JSON objects as is would show different results later when

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc