virtual-scroller 1.11.0 → 1.11.2
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/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/ItemsContainer.js +22 -9
- package/commonjs/DOM/ItemsContainer.js.map +1 -1
- package/commonjs/ItemHeights.js +1 -1
- package/commonjs/ItemHeights.js.map +1 -1
- package/commonjs/VirtualScroller.layout.js +2 -2
- package/commonjs/VirtualScroller.layout.js.map +1 -1
- package/commonjs/VirtualScroller.state.js +1 -1
- package/commonjs/VirtualScroller.state.js.map +1 -1
- package/commonjs/react/VirtualScroller.js +48 -16
- package/commonjs/react/VirtualScroller.js.map +1 -1
- package/commonjs/react/useHandleItemIndexesChange.js +53 -0
- package/commonjs/react/useHandleItemIndexesChange.js.map +1 -0
- package/commonjs/react/{useHandleItemsChange.js → useHandleItemsPropertyChange.js} +21 -40
- package/commonjs/react/useHandleItemsPropertyChange.js.map +1 -0
- package/commonjs/react/useOnItemHeightChange.js +2 -2
- package/commonjs/react/useOnItemHeightChange.js.map +1 -1
- package/commonjs/react/useSetItemState.js +2 -2
- package/commonjs/react/useSetItemState.js.map +1 -1
- package/commonjs/react/useState.js +47 -69
- package/commonjs/react/useState.js.map +1 -1
- package/commonjs/react/useStyle.js +4 -4
- package/commonjs/react/useStyle.js.map +1 -1
- package/index.d.ts +1 -1
- package/modules/DOM/ItemsContainer.js +22 -9
- package/modules/DOM/ItemsContainer.js.map +1 -1
- package/modules/ItemHeights.js +1 -1
- package/modules/ItemHeights.js.map +1 -1
- package/modules/VirtualScroller.layout.js +2 -2
- package/modules/VirtualScroller.layout.js.map +1 -1
- package/modules/VirtualScroller.state.js +1 -1
- package/modules/VirtualScroller.state.js.map +1 -1
- package/modules/react/VirtualScroller.js +47 -17
- package/modules/react/VirtualScroller.js.map +1 -1
- package/modules/react/useHandleItemIndexesChange.js +45 -0
- package/modules/react/useHandleItemIndexesChange.js.map +1 -0
- package/modules/react/{useHandleItemsChange.js → useHandleItemsPropertyChange.js} +20 -39
- package/modules/react/useHandleItemsPropertyChange.js.map +1 -0
- package/modules/react/useOnItemHeightChange.js +2 -2
- package/modules/react/useOnItemHeightChange.js.map +1 -1
- package/modules/react/useSetItemState.js +2 -2
- package/modules/react/useSetItemState.js.map +1 -1
- package/modules/react/useState.js +48 -70
- package/modules/react/useState.js.map +1 -1
- package/modules/react/useStyle.js +4 -4
- package/modules/react/useStyle.js.map +1 -1
- package/package.json +1 -1
- package/source/DOM/ItemsContainer.js +13 -3
- package/source/ItemHeights.js +1 -1
- package/source/VirtualScroller.layout.js +2 -2
- package/source/VirtualScroller.state.js +1 -1
- package/source/react/VirtualScroller.js +45 -13
- package/source/react/useHandleItemIndexesChange.js +49 -0
- package/source/react/{useHandleItemsChange.js → useHandleItemsPropertyChange.js} +20 -38
- package/source/react/useOnItemHeightChange.js +2 -2
- package/source/react/useSetItemState.js +2 -2
- package/source/react/useState.js +57 -72
- package/source/react/useStyle.js +2 -2
- package/commonjs/react/useHandleItemsChange.js.map +0 -1
- package/modules/react/useHandleItemsChange.js.map +0 -1
|
@@ -25,7 +25,9 @@ var _useSetItemState = _interopRequireDefault(require("./useSetItemState.js"));
|
|
|
25
25
|
|
|
26
26
|
var _useOnItemHeightChange = _interopRequireDefault(require("./useOnItemHeightChange.js"));
|
|
27
27
|
|
|
28
|
-
var
|
|
28
|
+
var _useHandleItemsPropertyChange = _interopRequireDefault(require("./useHandleItemsPropertyChange.js"));
|
|
29
|
+
|
|
30
|
+
var _useHandleItemIndexesChange = _interopRequireDefault(require("./useHandleItemIndexesChange.js"));
|
|
29
31
|
|
|
30
32
|
var _useClassName = _interopRequireDefault(require("./useClassName.js"));
|
|
31
33
|
|
|
@@ -45,9 +47,31 @@ function _objectWithoutProperties(source, excluded) { if (source == null) return
|
|
|
45
47
|
|
|
46
48
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
47
49
|
|
|
50
|
+
// When `items` property changes, `useHandleItemsPropertyChange()` hook detects that
|
|
51
|
+
// and calls `VirtualScroller.setItems()` which in turn calls the `updateState()` function.
|
|
52
|
+
// At this point, an insignificant optimization could be applied:
|
|
53
|
+
// the component could avoid re-rendering the second time.
|
|
54
|
+
// Instead, the state update could be applied "immediately" if it originated
|
|
55
|
+
// from `.setItems()` function call, eliminating the unneeded second re-render.
|
|
56
|
+
//
|
|
57
|
+
// I could see how this minor optimization could get brittle when modifiying the code,
|
|
58
|
+
// so I put it under a feature flag so that it could potentially be turned off
|
|
59
|
+
// in case of any potential weird issues in some future.
|
|
60
|
+
//
|
|
61
|
+
// Another reason for using this feature is:
|
|
62
|
+
//
|
|
63
|
+
// Since `useHandleItemsPropertyChange()` runs at render time
|
|
64
|
+
// and not after the render has finished (not in an "effect"),
|
|
65
|
+
// if the state update was done "conventionally" (by calling `_setNewState()`),
|
|
66
|
+
// React would throw an error about updating state during render.
|
|
67
|
+
// No one knows what the original error message was.
|
|
68
|
+
// Perhaps it's no longer relevant in newer versions of React.
|
|
69
|
+
//
|
|
70
|
+
var USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION = true;
|
|
71
|
+
|
|
48
72
|
function VirtualScroller(_ref, ref) {
|
|
49
73
|
var AsComponent = _ref.as,
|
|
50
|
-
|
|
74
|
+
itemsProperty = _ref.items,
|
|
51
75
|
Component = _ref.itemComponent,
|
|
52
76
|
itemComponentProps = _ref.itemComponentProps,
|
|
53
77
|
estimatedItemHeight = _ref.estimatedItemHeight,
|
|
@@ -77,7 +101,7 @@ function VirtualScroller(_ref, ref) {
|
|
|
77
101
|
var container = (0, _react.useRef)(); // Create a `VirtualScroller` instance.
|
|
78
102
|
|
|
79
103
|
var virtualScroller = (0, _useVirtualScroller["default"])({
|
|
80
|
-
items:
|
|
104
|
+
items: itemsProperty,
|
|
81
105
|
// `estimatedItemHeight` property name is deprecated,
|
|
82
106
|
// use `getEstimatedItemHeight` property instead.
|
|
83
107
|
estimatedItemHeight: estimatedItemHeight,
|
|
@@ -115,10 +139,12 @@ function VirtualScroller(_ref, ref) {
|
|
|
115
139
|
var _useState = (0, _useState2["default"])({
|
|
116
140
|
initialState: _initialState,
|
|
117
141
|
onRender: virtualScroller.onRender,
|
|
118
|
-
|
|
142
|
+
itemsProperty: itemsProperty,
|
|
143
|
+
USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION: USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION
|
|
119
144
|
}),
|
|
120
145
|
getState = _useState.getState,
|
|
121
|
-
updateState = _useState.updateState
|
|
146
|
+
updateState = _useState.updateState,
|
|
147
|
+
getNextState = _useState.getNextState; // Use custom (external) state storage in the `VirtualScroller`.
|
|
122
148
|
|
|
123
149
|
|
|
124
150
|
(0, _react.useMemo)(function () {
|
|
@@ -141,22 +167,28 @@ function VirtualScroller(_ref, ref) {
|
|
|
141
167
|
|
|
142
168
|
|
|
143
169
|
var getSetItemState = (0, _useSetItemState["default"])({
|
|
144
|
-
|
|
170
|
+
initialItemsCount: itemsProperty.length,
|
|
145
171
|
virtualScroller: virtualScroller
|
|
146
172
|
}); // Cache per-item `onItemHeightChange` functions' "references"
|
|
147
173
|
// so that item components don't get re-rendered needlessly.
|
|
148
174
|
|
|
149
175
|
var getOnItemHeightChange = (0, _useOnItemHeightChange["default"])({
|
|
150
|
-
|
|
176
|
+
initialItemsCount: itemsProperty.length,
|
|
151
177
|
virtualScroller: virtualScroller
|
|
152
|
-
}); //
|
|
178
|
+
}); // Calls `.setItems()` if `items` property has changed.
|
|
153
179
|
|
|
154
|
-
(0,
|
|
180
|
+
(0, _useHandleItemsPropertyChange["default"])(itemsProperty, {
|
|
155
181
|
virtualScroller: virtualScroller,
|
|
156
182
|
// `preserveScrollPosition` property name is deprecated,
|
|
157
183
|
// use `preserveScrollPositionOnPrependItems` property instead.
|
|
158
184
|
preserveScrollPosition: preserveScrollPosition,
|
|
159
185
|
preserveScrollPositionOnPrependItems: preserveScrollPositionOnPrependItems,
|
|
186
|
+
nextItems: getNextState().items
|
|
187
|
+
}); // Updates `key`s if item indexes have changed.
|
|
188
|
+
|
|
189
|
+
(0, _useHandleItemIndexesChange["default"])({
|
|
190
|
+
virtualScroller: virtualScroller,
|
|
191
|
+
itemsBeingRendered: getNextState().items,
|
|
160
192
|
updateItemKeysForNewItems: updateItemKeysForNewItems
|
|
161
193
|
}); // Add instance methods to the React component.
|
|
162
194
|
|
|
@@ -190,20 +222,20 @@ function VirtualScroller(_ref, ref) {
|
|
|
190
222
|
});
|
|
191
223
|
var style = (0, _useStyle["default"])({
|
|
192
224
|
tbody: tbody,
|
|
193
|
-
|
|
225
|
+
getNextState: getNextState
|
|
194
226
|
});
|
|
195
227
|
|
|
196
|
-
var
|
|
197
|
-
|
|
198
|
-
itemStates =
|
|
199
|
-
firstShownItemIndex =
|
|
200
|
-
lastShownItemIndex =
|
|
228
|
+
var _getNextState = getNextState(),
|
|
229
|
+
currentItems = _getNextState.items,
|
|
230
|
+
itemStates = _getNextState.itemStates,
|
|
231
|
+
firstShownItemIndex = _getNextState.firstShownItemIndex,
|
|
232
|
+
lastShownItemIndex = _getNextState.lastShownItemIndex;
|
|
201
233
|
|
|
202
234
|
return /*#__PURE__*/_react["default"].createElement(AsComponent, _extends({}, rest, {
|
|
203
235
|
ref: container,
|
|
204
236
|
className: className,
|
|
205
237
|
style: style
|
|
206
|
-
}),
|
|
238
|
+
}), currentItems.map(function (item, i) {
|
|
207
239
|
if (i >= firstShownItemIndex && i <= lastShownItemIndex) {
|
|
208
240
|
// * Passing `item` as `children` property is legacy and is deprecated.
|
|
209
241
|
// If version `2.x` is published in some hypothetical future,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualScroller.js","names":["VirtualScroller","ref","AsComponent","as","items","Component","itemComponent","itemComponentProps","estimatedItemHeight","getEstimatedItemHeight","getEstimatedVisibleItemRowsCount","bypass","tbody","preserveScrollPosition","preserveScrollPositionOnPrependItems","measureItemsBatchSize","scrollableContainer","getScrollableContainer","getColumnsCount","getItemId","className","onMount","onItemFirstRender","onItemInitialRender","initialScrollPosition","onScrollPositionChange","onStateChange","initialState","getInitialItemState","rest","container","useRef","virtualScroller","useVirtualScroller","_initialState","useMemo","getInitialState","useState","onRender","getState","updateState","useVirtualScrollerStartStop","useItemKeys","getItemKey","updateItemKeysForNewItems","getSetItemState","useSetItemState","getOnItemHeightChange","useOnItemHeightChange","useHandleItemsChange","useInstanceMethods","useLayoutEffect","useClassName","style","useStyle","renderedItems","itemStates","firstShownItemIndex","lastShownItemIndex","map","item","i","React","forwardRef","elementType","PropTypes","oneOfType","string","func","object","propTypes","arrayOf","any","isRequired","number","bool","shape","beforeItemsHeight","afterItemsHeight","itemHeights","columnsCount","verticalSpacing","defaultProps"],"sources":["../../source/react/VirtualScroller.js"],"sourcesContent":["import React, { useRef, useMemo, useLayoutEffect } from 'react'\r\nimport PropTypes from 'prop-types'\r\n\r\nimport useState from './useState.js'\r\nimport useVirtualScroller from './useVirtualScroller.js'\r\nimport useVirtualScrollerStartStop from './useVirtualScrollerStartStop.js'\r\nimport useInstanceMethods from './useInstanceMethods.js'\r\nimport useItemKeys from './useItemKeys.js'\r\nimport useSetItemState from './useSetItemState.js'\r\nimport useOnItemHeightChange from './useOnItemHeightChange.js'\r\nimport useHandleItemsChange from './useHandleItemsChange.js'\r\nimport useClassName from './useClassName.js'\r\nimport useStyle from './useStyle.js'\r\n\r\nfunction VirtualScroller({\r\n\tas: AsComponent,\r\n\titems,\r\n\titemComponent: Component,\r\n\titemComponentProps,\r\n\t// `estimatedItemHeight` property name is deprecated,\r\n\t// use `getEstimatedItemHeight` property instead.\r\n\testimatedItemHeight,\r\n\tgetEstimatedItemHeight,\r\n\tgetEstimatedVisibleItemRowsCount,\r\n\tbypass,\r\n\ttbody,\r\n\t// `preserveScrollPosition` property name is deprecated,\r\n\t// use `preserveScrollPositionOnPrependItems` property instead.\r\n\tpreserveScrollPosition,\r\n\tpreserveScrollPositionOnPrependItems,\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\tclassName,\r\n\tonMount,\r\n\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\tonItemFirstRender,\r\n\tonItemInitialRender,\r\n\tinitialScrollPosition,\r\n\tonScrollPositionChange,\r\n\tonStateChange,\r\n\tinitialState,\r\n\tgetInitialItemState,\r\n\t...rest\r\n}, ref) {\r\n\t// List items \"container\" DOM Element reference.\r\n\tconst container = useRef()\r\n\r\n\t// Create a `VirtualScroller` instance.\r\n\tconst virtualScroller = useVirtualScroller({\r\n\t\titems,\r\n\t\t// `estimatedItemHeight` property name is deprecated,\r\n\t\t// use `getEstimatedItemHeight` property instead.\r\n\t\testimatedItemHeight,\r\n\t\tgetEstimatedItemHeight,\r\n\t\tgetEstimatedVisibleItemRowsCount,\r\n\t\tbypass,\r\n\t\t// bypassBatchSize,\r\n\t\ttbody,\r\n\t\tonItemInitialRender,\r\n\t\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\t\tonItemFirstRender,\r\n\t\tinitialScrollPosition,\r\n\t\tonScrollPositionChange,\r\n\t\tmeasureItemsBatchSize,\r\n\t\t// `scrollableContainer` property is deprecated.\r\n\t\t// Use `getScrollableContainer()` property instead.\r\n\t\tscrollableContainer,\r\n\t\tgetScrollableContainer,\r\n\t\tgetColumnsCount,\r\n\t\tgetItemId,\r\n\t\tAsComponent,\r\n\t\tinitialState,\r\n\t\tgetInitialItemState,\r\n\t\tonStateChange\r\n\t}, {\r\n\t\tcontainer\r\n\t})\r\n\r\n\t// Only compute the initial state once.\r\n\tconst _initialState = useMemo(() => {\r\n\t\treturn virtualScroller.getInitialState()\r\n\t}, [])\r\n\r\n\t// Use React's `useState()` hook for managing `VirtualScroller`'s state lifecycle.\r\n\t// This way, React will re-render the component on every state update.\r\n\tconst {\r\n\t\tgetState,\r\n\t\tupdateState\r\n\t} = useState({\r\n\t\tinitialState: _initialState,\r\n\t\tonRender: virtualScroller.onRender,\r\n\t\titems\r\n\t})\r\n\r\n\t// Use custom (external) state storage in the `VirtualScroller`.\r\n\tuseMemo(() => {\r\n\t\tvirtualScroller.useState({\r\n\t\t\tgetState,\r\n\t\t\tupdateState\r\n\t\t})\r\n\t}, [])\r\n\r\n\t// Start `VirtualScroller` on mount.\r\n\t// Stop `VirtualScroller` on unmount.\r\n\tuseVirtualScrollerStartStop(virtualScroller)\r\n\r\n\t// List items are rendered with `key`s so that React doesn't\r\n\t// \"reuse\" `itemComponent`s in cases when `items` are changed.\r\n\tconst {\r\n\t\tgetItemKey,\r\n\t\tupdateItemKeysForNewItems\r\n\t} = useItemKeys({\r\n\t\tgetItemId\r\n\t})\r\n\r\n\t// Cache per-item `setItemState` functions' \"references\"\r\n\t// so that item components don't get re-rendered needlessly.\r\n\tconst getSetItemState = useSetItemState({\r\n\t\titems,\r\n\t\tvirtualScroller\r\n\t})\r\n\r\n\t// Cache per-item `onItemHeightChange` functions' \"references\"\r\n\t// so that item components don't get re-rendered needlessly.\r\n\tconst getOnItemHeightChange = useOnItemHeightChange({\r\n\t\titems,\r\n\t\tvirtualScroller\r\n\t})\r\n\r\n\t// Detect if `items` have changed.\r\n\tuseHandleItemsChange(items, {\r\n\t\tvirtualScroller,\r\n\t\t// `preserveScrollPosition` property name is deprecated,\r\n\t\t// use `preserveScrollPositionOnPrependItems` property instead.\r\n\t\tpreserveScrollPosition,\r\n\t\tpreserveScrollPositionOnPrependItems,\r\n\t\tupdateItemKeysForNewItems\r\n\t})\r\n\r\n\t// Add instance methods to the React component.\r\n\tuseInstanceMethods(ref, {\r\n\t\tvirtualScroller\r\n\t})\r\n\r\n\tuseLayoutEffect(() => {\r\n\t\t// (deprecated)\r\n\t\t// `onMount()` option is deprecated due to no longer being used.\r\n\t\t// If someone thinks there's a valid use case for it, create an issue.\r\n\t\tif (onMount) {\r\n\t\t\tonMount()\r\n\t\t}\r\n\t}, [])\r\n\r\n\t// `willRender()` function is no longer used.\r\n\t//\r\n\t// // `getSnapshotBeforeUpdate()` is called right before `componentDidUpdate()`.\r\n\t// // A hook equivalent/workaround for `getSnapshotBeforeUpdate()`:\r\n\t// // https://github.com/facebook/react/issues/15221#issuecomment-583448887\r\n\t// //\r\n\t// getSnapshotBeforeUpdate(prevProps, prevState) {\r\n\t// \tif (this.state !== prevState) {\r\n\t// \t\tthis.willRender(this.state, prevState)\r\n\t// \t}\r\n\t// \t// Returns `null` to avoid React warning:\r\n\t// \t// \"A snapshot value (or null) must be returned. You have returned undefined\".\r\n\t// \treturn null\r\n\t// }\r\n\r\n\tclassName = useClassName(className, {\r\n\t\ttbody\r\n\t})\r\n\r\n\tconst style = useStyle({\r\n\t\ttbody,\r\n\t\tvirtualScroller\r\n\t})\r\n\r\n\tconst {\r\n\t\titems: renderedItems,\r\n\t\titemStates,\r\n\t\tfirstShownItemIndex,\r\n\t\tlastShownItemIndex\r\n\t} = virtualScroller.getState()\r\n\r\n\treturn (\r\n\t\t<AsComponent\r\n\t\t\t{...rest}\r\n\t\t\tref={container}\r\n\t\t\tclassName={className}\r\n\t\t\tstyle={style}>\r\n\t\t\t{renderedItems.map((item, i) => {\r\n\t\t\t\tif (i >= firstShownItemIndex && i <= lastShownItemIndex) {\r\n\t\t\t\t\t// * Passing `item` as `children` property is legacy and is deprecated.\r\n\t\t\t\t\t// If version `2.x` is published in some hypothetical future,\r\n\t\t\t\t\t// the `item` and `itemIndex` properties should be moved below\r\n\t\t\t\t\t// `{...itemComponentProps}`.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// * Passing `itemIndex` property is legacy and is deprecated.\r\n\t\t\t\t\t// The rationale is that setting new `items` on a React component\r\n\t\t\t\t\t// is an asynchronous operation, so when a user obtains `itemIndex`,\r\n\t\t\t\t\t// they don't know which `items` list does that index correspond to,\r\n\t\t\t\t\t// therefore making it useless, or even buggy if used incorreclty.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// * Passing `onStateChange` property for legacy reasons.\r\n\t\t\t\t\t// The new property name is `setState`.\r\n\t\t\t\t\t// The old property name `onStateChange` is deprecated.\r\n\t\t\t\t\t//\r\n\t\t\t\t\treturn (\r\n\t\t\t\t\t\t<Component\r\n\t\t\t\t\t\t\titem={item}\r\n\t\t\t\t\t\t\titemIndex={i}\r\n\t\t\t\t\t\t\t{...itemComponentProps}\r\n\t\t\t\t\t\t\tkey={getItemKey(item, i)}\r\n\t\t\t\t\t\t\tstate={itemStates && itemStates[i]}\r\n\t\t\t\t\t\t\tsetState={getSetItemState(i)}\r\n\t\t\t\t\t\t\tonStateChange={getSetItemState(i)}\r\n\t\t\t\t\t\t\tonHeightChange={getOnItemHeightChange(i)}>\r\n\t\t\t\t\t\t\t{item}\r\n\t\t\t\t\t\t</Component>\r\n\t\t\t\t\t)\r\n\t\t\t\t}\r\n\t\t\t\treturn null\r\n\t\t\t})}\r\n\t\t</AsComponent>\r\n\t)\r\n}\r\n\r\nVirtualScroller = React.forwardRef(VirtualScroller)\r\n\r\nexport default VirtualScroller\r\n\r\n// `PropTypes.elementType` is available in some version of `prop-types`.\r\n// https://github.com/facebook/prop-types/issues/200\r\nconst elementType = PropTypes.elementType || PropTypes.oneOfType([\r\n\tPropTypes.string,\r\n\tPropTypes.func,\r\n\tPropTypes.object\r\n])\r\n\r\nVirtualScroller.propTypes = {\r\n\tas: elementType,\r\n\titems: PropTypes.arrayOf(PropTypes.any).isRequired,\r\n\titemComponent: elementType.isRequired,\r\n\titemComponentProps: PropTypes.object,\r\n\t// `estimatedItemHeight` property name is deprecated,\r\n\t// use `getEstimatedItemHeight` property instead.\r\n\testimatedItemHeight: PropTypes.number,\r\n\tgetEstimatedItemHeight: PropTypes.func,\r\n\tgetEstimatedVisibleItemRowsCount: PropTypes.func,\r\n\tbypass: PropTypes.bool,\r\n\t// bypassBatchSize: PropTypes.number,\r\n\ttbody: PropTypes.bool,\r\n\tpreserveScrollPositionOnPrependItems: PropTypes.bool,\r\n\t// `preserveScrollPosition` property name is deprecated,\r\n\t// use `preserveScrollPositionOnPrependItems` instead.\r\n\tpreserveScrollPosition: PropTypes.bool,\r\n\tmeasureItemsBatchSize: PropTypes.number,\r\n\t// `scrollableContainer` property is deprecated.\r\n\t// Use `getScrollableContainer()` property instead.\r\n\tscrollableContainer: PropTypes.any,\r\n\tgetScrollableContainer: PropTypes.func,\r\n\tgetColumnsCount: PropTypes.func,\r\n\tgetItemId: PropTypes.func,\r\n\tclassName: PropTypes.string,\r\n\tonMount: PropTypes.func,\r\n\tonItemInitialRender: PropTypes.func,\r\n\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\tonItemFirstRender: PropTypes.func,\r\n\tinitialScrollPosition: PropTypes.number,\r\n\tonScrollPositionChange: PropTypes.func,\r\n\tonStateChange: PropTypes.func,\r\n\tinitialState: PropTypes.shape({\r\n\t\titems: PropTypes.arrayOf(PropTypes.object).isRequired,\r\n\t\titemStates: PropTypes.arrayOf(PropTypes.any).isRequired,\r\n\t\tfirstShownItemIndex: PropTypes.number.isRequired,\r\n\t\tlastShownItemIndex: PropTypes.number.isRequired,\r\n\t\tbeforeItemsHeight: PropTypes.number.isRequired,\r\n\t\tafterItemsHeight: PropTypes.number.isRequired,\r\n\t\titemHeights: PropTypes.arrayOf(PropTypes.number).isRequired,\r\n\t\tcolumnsCount: PropTypes.number,\r\n\t\tverticalSpacing: PropTypes.number\r\n\t}),\r\n\tgetInitialItemState: PropTypes.func\r\n}\r\n\r\nVirtualScroller.defaultProps = {\r\n\tas: 'div'\r\n}\r\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"VirtualScroller.js","names":["USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION","VirtualScroller","ref","AsComponent","as","itemsProperty","items","Component","itemComponent","itemComponentProps","estimatedItemHeight","getEstimatedItemHeight","getEstimatedVisibleItemRowsCount","bypass","tbody","preserveScrollPosition","preserveScrollPositionOnPrependItems","measureItemsBatchSize","scrollableContainer","getScrollableContainer","getColumnsCount","getItemId","className","onMount","onItemFirstRender","onItemInitialRender","initialScrollPosition","onScrollPositionChange","onStateChange","initialState","getInitialItemState","rest","container","useRef","virtualScroller","useVirtualScroller","_initialState","useMemo","getInitialState","useState","onRender","getState","updateState","getNextState","useVirtualScrollerStartStop","useItemKeys","getItemKey","updateItemKeysForNewItems","getSetItemState","useSetItemState","initialItemsCount","length","getOnItemHeightChange","useOnItemHeightChange","useHandleItemsPropertyChange","nextItems","useHandleItemIndexesChange","itemsBeingRendered","useInstanceMethods","useLayoutEffect","useClassName","style","useStyle","currentItems","itemStates","firstShownItemIndex","lastShownItemIndex","map","item","i","React","forwardRef","elementType","PropTypes","oneOfType","string","func","object","propTypes","arrayOf","any","isRequired","number","bool","shape","beforeItemsHeight","afterItemsHeight","itemHeights","columnsCount","verticalSpacing","defaultProps"],"sources":["../../source/react/VirtualScroller.js"],"sourcesContent":["import React, { useRef, useMemo, useLayoutEffect } from 'react'\r\nimport PropTypes from 'prop-types'\r\n\r\nimport useState from './useState.js'\r\nimport useVirtualScroller from './useVirtualScroller.js'\r\nimport useVirtualScrollerStartStop from './useVirtualScrollerStartStop.js'\r\nimport useInstanceMethods from './useInstanceMethods.js'\r\nimport useItemKeys from './useItemKeys.js'\r\nimport useSetItemState from './useSetItemState.js'\r\nimport useOnItemHeightChange from './useOnItemHeightChange.js'\r\nimport useHandleItemsPropertyChange from './useHandleItemsPropertyChange.js'\r\nimport useHandleItemIndexesChange from './useHandleItemIndexesChange.js'\r\nimport useClassName from './useClassName.js'\r\nimport useStyle from './useStyle.js'\r\n\r\n// When `items` property changes, `useHandleItemsPropertyChange()` hook detects that\r\n// and calls `VirtualScroller.setItems()` which in turn calls the `updateState()` function.\r\n// At this point, an insignificant optimization could be applied:\r\n// the component could avoid re-rendering the second time.\r\n// Instead, the state update could be applied \"immediately\" if it originated\r\n// from `.setItems()` function call, eliminating the unneeded second re-render.\r\n//\r\n// I could see how this minor optimization could get brittle when modifiying the code,\r\n// so I put it under a feature flag so that it could potentially be turned off\r\n// in case of any potential weird issues in some future.\r\n//\r\n// Another reason for using this feature is:\r\n//\r\n// Since `useHandleItemsPropertyChange()` runs at render time\r\n// and not after the render has finished (not in an \"effect\"),\r\n// if the state update was done \"conventionally\" (by calling `_setNewState()`),\r\n// React would throw an error about updating state during render.\r\n// No one knows what the original error message was.\r\n// Perhaps it's no longer relevant in newer versions of React.\r\n//\r\nconst USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION = true\r\n\r\nfunction VirtualScroller({\r\n\tas: AsComponent,\r\n\titems: itemsProperty,\r\n\titemComponent: Component,\r\n\titemComponentProps,\r\n\t// `estimatedItemHeight` property name is deprecated,\r\n\t// use `getEstimatedItemHeight` property instead.\r\n\testimatedItemHeight,\r\n\tgetEstimatedItemHeight,\r\n\tgetEstimatedVisibleItemRowsCount,\r\n\tbypass,\r\n\ttbody,\r\n\t// `preserveScrollPosition` property name is deprecated,\r\n\t// use `preserveScrollPositionOnPrependItems` property instead.\r\n\tpreserveScrollPosition,\r\n\tpreserveScrollPositionOnPrependItems,\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\tclassName,\r\n\tonMount,\r\n\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\tonItemFirstRender,\r\n\tonItemInitialRender,\r\n\tinitialScrollPosition,\r\n\tonScrollPositionChange,\r\n\tonStateChange,\r\n\tinitialState,\r\n\tgetInitialItemState,\r\n\t...rest\r\n}, ref) {\r\n\t// List items \"container\" DOM Element reference.\r\n\tconst container = useRef()\r\n\r\n\t// Create a `VirtualScroller` instance.\r\n\tconst virtualScroller = useVirtualScroller({\r\n\t\titems: itemsProperty,\r\n\t\t// `estimatedItemHeight` property name is deprecated,\r\n\t\t// use `getEstimatedItemHeight` property instead.\r\n\t\testimatedItemHeight,\r\n\t\tgetEstimatedItemHeight,\r\n\t\tgetEstimatedVisibleItemRowsCount,\r\n\t\tbypass,\r\n\t\t// bypassBatchSize,\r\n\t\ttbody,\r\n\t\tonItemInitialRender,\r\n\t\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\t\tonItemFirstRender,\r\n\t\tinitialScrollPosition,\r\n\t\tonScrollPositionChange,\r\n\t\tmeasureItemsBatchSize,\r\n\t\t// `scrollableContainer` property is deprecated.\r\n\t\t// Use `getScrollableContainer()` property instead.\r\n\t\tscrollableContainer,\r\n\t\tgetScrollableContainer,\r\n\t\tgetColumnsCount,\r\n\t\tgetItemId,\r\n\t\tAsComponent,\r\n\t\tinitialState,\r\n\t\tgetInitialItemState,\r\n\t\tonStateChange\r\n\t}, {\r\n\t\tcontainer\r\n\t})\r\n\r\n\t// Only compute the initial state once.\r\n\tconst _initialState = useMemo(() => {\r\n\t\treturn virtualScroller.getInitialState()\r\n\t}, [])\r\n\r\n\t// Use React's `useState()` hook for managing `VirtualScroller`'s state lifecycle.\r\n\t// This way, React will re-render the component on every state update.\r\n\tconst {\r\n\t\tgetState,\r\n\t\tupdateState,\r\n\t\tgetNextState\r\n\t} = useState({\r\n\t\tinitialState: _initialState,\r\n\t\tonRender: virtualScroller.onRender,\r\n\t\titemsProperty,\r\n\t\tUSE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION\r\n\t})\r\n\r\n\t// Use custom (external) state storage in the `VirtualScroller`.\r\n\tuseMemo(() => {\r\n\t\tvirtualScroller.useState({\r\n\t\t\tgetState,\r\n\t\t\tupdateState\r\n\t\t})\r\n\t}, [])\r\n\r\n\t// Start `VirtualScroller` on mount.\r\n\t// Stop `VirtualScroller` on unmount.\r\n\tuseVirtualScrollerStartStop(virtualScroller)\r\n\r\n\t// List items are rendered with `key`s so that React doesn't\r\n\t// \"reuse\" `itemComponent`s in cases when `items` are changed.\r\n\tconst {\r\n\t\tgetItemKey,\r\n\t\tupdateItemKeysForNewItems\r\n\t} = useItemKeys({\r\n\t\tgetItemId\r\n\t})\r\n\r\n\t// Cache per-item `setItemState` functions' \"references\"\r\n\t// so that item components don't get re-rendered needlessly.\r\n\tconst getSetItemState = useSetItemState({\r\n\t\tinitialItemsCount: itemsProperty.length,\r\n\t\tvirtualScroller\r\n\t})\r\n\r\n\t// Cache per-item `onItemHeightChange` functions' \"references\"\r\n\t// so that item components don't get re-rendered needlessly.\r\n\tconst getOnItemHeightChange = useOnItemHeightChange({\r\n\t\tinitialItemsCount: itemsProperty.length,\r\n\t\tvirtualScroller\r\n\t})\r\n\r\n\t// Calls `.setItems()` if `items` property has changed.\r\n\tuseHandleItemsPropertyChange(itemsProperty, {\r\n\t\tvirtualScroller,\r\n\t\t// `preserveScrollPosition` property name is deprecated,\r\n\t\t// use `preserveScrollPositionOnPrependItems` property instead.\r\n\t\tpreserveScrollPosition,\r\n\t\tpreserveScrollPositionOnPrependItems,\r\n\t\tnextItems: getNextState().items\r\n\t})\r\n\r\n\t// Updates `key`s if item indexes have changed.\r\n\tuseHandleItemIndexesChange({\r\n\t\tvirtualScroller,\r\n\t\titemsBeingRendered: getNextState().items,\r\n\t\tupdateItemKeysForNewItems\r\n\t})\r\n\r\n\t// Add instance methods to the React component.\r\n\tuseInstanceMethods(ref, {\r\n\t\tvirtualScroller\r\n\t})\r\n\r\n\tuseLayoutEffect(() => {\r\n\t\t// (deprecated)\r\n\t\t// `onMount()` option is deprecated due to no longer being used.\r\n\t\t// If someone thinks there's a valid use case for it, create an issue.\r\n\t\tif (onMount) {\r\n\t\t\tonMount()\r\n\t\t}\r\n\t}, [])\r\n\r\n\t// `willRender()` function is no longer used.\r\n\t//\r\n\t// // `getSnapshotBeforeUpdate()` is called right before `componentDidUpdate()`.\r\n\t// // A hook equivalent/workaround for `getSnapshotBeforeUpdate()`:\r\n\t// // https://github.com/facebook/react/issues/15221#issuecomment-583448887\r\n\t// //\r\n\t// getSnapshotBeforeUpdate(prevProps, prevState) {\r\n\t// \tif (this.state !== prevState) {\r\n\t// \t\tthis.willRender(this.state, prevState)\r\n\t// \t}\r\n\t// \t// Returns `null` to avoid React warning:\r\n\t// \t// \"A snapshot value (or null) must be returned. You have returned undefined\".\r\n\t// \treturn null\r\n\t// }\r\n\r\n\tclassName = useClassName(className, {\r\n\t\ttbody\r\n\t})\r\n\r\n\tconst style = useStyle({\r\n\t\ttbody,\r\n\t\tgetNextState\r\n\t})\r\n\r\n\tconst {\r\n\t\titems: currentItems,\r\n\t\titemStates,\r\n\t\tfirstShownItemIndex,\r\n\t\tlastShownItemIndex\r\n\t} = getNextState()\r\n\r\n\treturn (\r\n\t\t<AsComponent\r\n\t\t\t{...rest}\r\n\t\t\tref={container}\r\n\t\t\tclassName={className}\r\n\t\t\tstyle={style}>\r\n\t\t\t{currentItems.map((item, i) => {\r\n\t\t\t\tif (i >= firstShownItemIndex && i <= lastShownItemIndex) {\r\n\t\t\t\t\t// * Passing `item` as `children` property is legacy and is deprecated.\r\n\t\t\t\t\t// If version `2.x` is published in some hypothetical future,\r\n\t\t\t\t\t// the `item` and `itemIndex` properties should be moved below\r\n\t\t\t\t\t// `{...itemComponentProps}`.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// * Passing `itemIndex` property is legacy and is deprecated.\r\n\t\t\t\t\t// The rationale is that setting new `items` on a React component\r\n\t\t\t\t\t// is an asynchronous operation, so when a user obtains `itemIndex`,\r\n\t\t\t\t\t// they don't know which `items` list does that index correspond to,\r\n\t\t\t\t\t// therefore making it useless, or even buggy if used incorreclty.\r\n\t\t\t\t\t//\r\n\t\t\t\t\t// * Passing `onStateChange` property for legacy reasons.\r\n\t\t\t\t\t// The new property name is `setState`.\r\n\t\t\t\t\t// The old property name `onStateChange` is deprecated.\r\n\t\t\t\t\t//\r\n\t\t\t\t\treturn (\r\n\t\t\t\t\t\t<Component\r\n\t\t\t\t\t\t\titem={item}\r\n\t\t\t\t\t\t\titemIndex={i}\r\n\t\t\t\t\t\t\t{...itemComponentProps}\r\n\t\t\t\t\t\t\tkey={getItemKey(item, i)}\r\n\t\t\t\t\t\t\tstate={itemStates && itemStates[i]}\r\n\t\t\t\t\t\t\tsetState={getSetItemState(i)}\r\n\t\t\t\t\t\t\tonStateChange={getSetItemState(i)}\r\n\t\t\t\t\t\t\tonHeightChange={getOnItemHeightChange(i)}>\r\n\t\t\t\t\t\t\t{item}\r\n\t\t\t\t\t\t</Component>\r\n\t\t\t\t\t)\r\n\t\t\t\t}\r\n\t\t\t\treturn null\r\n\t\t\t})}\r\n\t\t</AsComponent>\r\n\t)\r\n}\r\n\r\nVirtualScroller = React.forwardRef(VirtualScroller)\r\n\r\nexport default VirtualScroller\r\n\r\n// `PropTypes.elementType` is available in some version of `prop-types`.\r\n// https://github.com/facebook/prop-types/issues/200\r\nconst elementType = PropTypes.elementType || PropTypes.oneOfType([\r\n\tPropTypes.string,\r\n\tPropTypes.func,\r\n\tPropTypes.object\r\n])\r\n\r\nVirtualScroller.propTypes = {\r\n\tas: elementType,\r\n\titems: PropTypes.arrayOf(PropTypes.any).isRequired,\r\n\titemComponent: elementType.isRequired,\r\n\titemComponentProps: PropTypes.object,\r\n\t// `estimatedItemHeight` property name is deprecated,\r\n\t// use `getEstimatedItemHeight` property instead.\r\n\testimatedItemHeight: PropTypes.number,\r\n\tgetEstimatedItemHeight: PropTypes.func,\r\n\tgetEstimatedVisibleItemRowsCount: PropTypes.func,\r\n\tbypass: PropTypes.bool,\r\n\t// bypassBatchSize: PropTypes.number,\r\n\ttbody: PropTypes.bool,\r\n\tpreserveScrollPositionOnPrependItems: PropTypes.bool,\r\n\t// `preserveScrollPosition` property name is deprecated,\r\n\t// use `preserveScrollPositionOnPrependItems` instead.\r\n\tpreserveScrollPosition: PropTypes.bool,\r\n\tmeasureItemsBatchSize: PropTypes.number,\r\n\t// `scrollableContainer` property is deprecated.\r\n\t// Use `getScrollableContainer()` property instead.\r\n\tscrollableContainer: PropTypes.any,\r\n\tgetScrollableContainer: PropTypes.func,\r\n\tgetColumnsCount: PropTypes.func,\r\n\tgetItemId: PropTypes.func,\r\n\tclassName: PropTypes.string,\r\n\tonMount: PropTypes.func,\r\n\tonItemInitialRender: PropTypes.func,\r\n\t// `onItemFirstRender(i)` is deprecated, use `onItemInitialRender(item)` instead.\r\n\tonItemFirstRender: PropTypes.func,\r\n\tinitialScrollPosition: PropTypes.number,\r\n\tonScrollPositionChange: PropTypes.func,\r\n\tonStateChange: PropTypes.func,\r\n\tinitialState: PropTypes.shape({\r\n\t\titems: PropTypes.arrayOf(PropTypes.object).isRequired,\r\n\t\titemStates: PropTypes.arrayOf(PropTypes.any).isRequired,\r\n\t\tfirstShownItemIndex: PropTypes.number.isRequired,\r\n\t\tlastShownItemIndex: PropTypes.number.isRequired,\r\n\t\tbeforeItemsHeight: PropTypes.number.isRequired,\r\n\t\tafterItemsHeight: PropTypes.number.isRequired,\r\n\t\titemHeights: PropTypes.arrayOf(PropTypes.number).isRequired,\r\n\t\tcolumnsCount: PropTypes.number,\r\n\t\tverticalSpacing: PropTypes.number\r\n\t}),\r\n\tgetInitialItemState: PropTypes.func\r\n}\r\n\r\nVirtualScroller.defaultProps = {\r\n\tas: 'div'\r\n}\r\n"],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = useHandleItemIndexesChange;
|
|
7
|
+
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
|
|
10
|
+
// If the order of the `items` changes, or new `items` get prepended resulting in a "shift":
|
|
11
|
+
//
|
|
12
|
+
// * Re-generate the React `key` prefix for item elements
|
|
13
|
+
// so that all item components are re-rendered for the new `items` list.
|
|
14
|
+
// That's because item components may have their own internal state,
|
|
15
|
+
// and simply passing another `item` property for an item component
|
|
16
|
+
// might result in bugs, which React would do with its "re-using" policy
|
|
17
|
+
// if the unique `key` workaround hasn't been used.
|
|
18
|
+
//
|
|
19
|
+
function useHandleItemIndexesChange(_ref) {
|
|
20
|
+
var virtualScroller = _ref.virtualScroller,
|
|
21
|
+
itemsBeingRendered = _ref.itemsBeingRendered,
|
|
22
|
+
updateItemKeysForNewItems = _ref.updateItemKeysForNewItems;
|
|
23
|
+
var previousItemsBeingRenderedRef = (0, _react.useRef)(itemsBeingRendered);
|
|
24
|
+
var previousItemsBeingRendered = previousItemsBeingRenderedRef.current;
|
|
25
|
+
var haveItemsChanged = itemsBeingRendered !== previousItemsBeingRendered;
|
|
26
|
+
previousItemsBeingRenderedRef.current = itemsBeingRendered;
|
|
27
|
+
|
|
28
|
+
if (haveItemsChanged) {
|
|
29
|
+
var shouldUpdateItemKeys = true;
|
|
30
|
+
var itemsDiff = virtualScroller.getItemsDiff(previousItemsBeingRendered, itemsBeingRendered); // `itemsDiff` will be `undefined` in case of a non-incremental items list change.
|
|
31
|
+
|
|
32
|
+
if (itemsDiff) {
|
|
33
|
+
var prependedItemsCount = itemsDiff.prependedItemsCount,
|
|
34
|
+
appendedItemsCount = itemsDiff.appendedItemsCount;
|
|
35
|
+
|
|
36
|
+
if (prependedItemsCount === 0 && appendedItemsCount === 0) {
|
|
37
|
+
// The items order hasn't changed.
|
|
38
|
+
// No need to re-generate the `key` prefix.
|
|
39
|
+
shouldUpdateItemKeys = false;
|
|
40
|
+
} else if (prependedItemsCount === 0 && appendedItemsCount > 0) {
|
|
41
|
+
// The item order hasn't changed.
|
|
42
|
+
// No need to re-generate the `key` prefix.
|
|
43
|
+
shouldUpdateItemKeys = false;
|
|
44
|
+
}
|
|
45
|
+
} // Update React element `key`s for the new set of `items`.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
if (shouldUpdateItemKeys) {
|
|
49
|
+
updateItemKeysForNewItems();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=useHandleItemIndexesChange.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useHandleItemIndexesChange.js","names":["useHandleItemIndexesChange","virtualScroller","itemsBeingRendered","updateItemKeysForNewItems","previousItemsBeingRenderedRef","useRef","previousItemsBeingRendered","current","haveItemsChanged","shouldUpdateItemKeys","itemsDiff","getItemsDiff","prependedItemsCount","appendedItemsCount"],"sources":["../../source/react/useHandleItemIndexesChange.js"],"sourcesContent":["import { useRef } from 'react'\r\n\r\n// If the order of the `items` changes, or new `items` get prepended resulting in a \"shift\":\r\n//\r\n// * Re-generate the React `key` prefix for item elements\r\n// so that all item components are re-rendered for the new `items` list.\r\n// That's because item components may have their own internal state,\r\n// and simply passing another `item` property for an item component\r\n// might result in bugs, which React would do with its \"re-using\" policy\r\n// if the unique `key` workaround hasn't been used.\r\n//\r\nexport default function useHandleItemIndexesChange({\r\n\tvirtualScroller,\r\n\titemsBeingRendered,\r\n\tupdateItemKeysForNewItems\r\n}) {\r\n\tconst previousItemsBeingRenderedRef = useRef(itemsBeingRendered)\r\n\tconst previousItemsBeingRendered = previousItemsBeingRenderedRef.current\r\n\tconst haveItemsChanged = itemsBeingRendered !== previousItemsBeingRendered\r\n\tpreviousItemsBeingRenderedRef.current = itemsBeingRendered\r\n\r\n\tif (haveItemsChanged) {\r\n\t\tlet shouldUpdateItemKeys = true\r\n\r\n\t\tconst itemsDiff = virtualScroller.getItemsDiff(previousItemsBeingRendered, itemsBeingRendered)\r\n\t\t// `itemsDiff` will be `undefined` in case of a non-incremental items list change.\r\n\t\tif (itemsDiff) {\r\n\t\t\tconst {\r\n\t\t\t\tprependedItemsCount,\r\n\t\t\t\tappendedItemsCount\r\n\t\t\t} = itemsDiff\r\n\t\t\tif (prependedItemsCount === 0 && appendedItemsCount === 0) {\r\n\t\t\t\t// The items order hasn't changed.\r\n\t\t\t\t// No need to re-generate the `key` prefix.\r\n\t\t\t\tshouldUpdateItemKeys = false\r\n\t\t\t}\r\n\t\t\telse if (prependedItemsCount === 0 && appendedItemsCount > 0) {\r\n\t\t\t\t// The item order hasn't changed.\r\n\t\t\t\t// No need to re-generate the `key` prefix.\r\n\t\t\t\tshouldUpdateItemKeys = false\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Update React element `key`s for the new set of `items`.\r\n\t\tif (shouldUpdateItemKeys) {\r\n\t\t\tupdateItemKeysForNewItems()\r\n\t\t}\r\n\t}\r\n}"],"mappings":";;;;;;;AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,SAASA,0BAAT,OAIZ;EAAA,IAHFC,eAGE,QAHFA,eAGE;EAAA,IAFFC,kBAEE,QAFFA,kBAEE;EAAA,IADFC,yBACE,QADFA,yBACE;EACF,IAAMC,6BAA6B,GAAG,IAAAC,aAAA,EAAOH,kBAAP,CAAtC;EACA,IAAMI,0BAA0B,GAAGF,6BAA6B,CAACG,OAAjE;EACA,IAAMC,gBAAgB,GAAGN,kBAAkB,KAAKI,0BAAhD;EACAF,6BAA6B,CAACG,OAA9B,GAAwCL,kBAAxC;;EAEA,IAAIM,gBAAJ,EAAsB;IACrB,IAAIC,oBAAoB,GAAG,IAA3B;IAEA,IAAMC,SAAS,GAAGT,eAAe,CAACU,YAAhB,CAA6BL,0BAA7B,EAAyDJ,kBAAzD,CAAlB,CAHqB,CAIrB;;IACA,IAAIQ,SAAJ,EAAe;MACd,IACCE,mBADD,GAGIF,SAHJ,CACCE,mBADD;MAAA,IAECC,kBAFD,GAGIH,SAHJ,CAECG,kBAFD;;MAIA,IAAID,mBAAmB,KAAK,CAAxB,IAA6BC,kBAAkB,KAAK,CAAxD,EAA2D;QAC1D;QACA;QACAJ,oBAAoB,GAAG,KAAvB;MACA,CAJD,MAKK,IAAIG,mBAAmB,KAAK,CAAxB,IAA6BC,kBAAkB,GAAG,CAAtD,EAAyD;QAC7D;QACA;QACAJ,oBAAoB,GAAG,KAAvB;MACA;IACD,CApBoB,CAsBrB;;;IACA,IAAIA,oBAAJ,EAA0B;MACzBN,yBAAyB;IACzB;EACD;AACD"}
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports["default"] =
|
|
6
|
+
exports["default"] = useHandleItemsPropertyChange;
|
|
7
7
|
|
|
8
8
|
var _react = require("react");
|
|
9
9
|
|
|
10
|
-
// If new `items`
|
|
10
|
+
// If new `items` property is passed:
|
|
11
11
|
//
|
|
12
12
|
// * Store the scroll Y position for the first one of the current items
|
|
13
13
|
// so that it could potentially (in some cases) be restored after the
|
|
@@ -15,22 +15,12 @@ var _react = require("react");
|
|
|
15
15
|
//
|
|
16
16
|
// * Call `VirtualScroller.setItems()` function.
|
|
17
17
|
//
|
|
18
|
-
|
|
19
|
-
// so that all item components are re-rendered for the new `items` list.
|
|
20
|
-
// That's because item components may have their own internal state,
|
|
21
|
-
// and simply passing another `item` property for an item component
|
|
22
|
-
// might result in bugs, which React would do with its "re-using" policy
|
|
23
|
-
// if the unique `key` workaround hasn't been used.
|
|
24
|
-
//
|
|
25
|
-
function useHandleItemsChange(items, _ref) {
|
|
18
|
+
function useHandleItemsPropertyChange(itemsProperty, _ref) {
|
|
26
19
|
var virtualScroller = _ref.virtualScroller,
|
|
27
20
|
preserveScrollPosition = _ref.preserveScrollPosition,
|
|
28
21
|
preserveScrollPositionOnPrependItems = _ref.preserveScrollPositionOnPrependItems,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
var _virtualScroller$getS = virtualScroller.getState(),
|
|
32
|
-
renderedItems = _virtualScroller$getS.items,
|
|
33
|
-
firstShownItemIndex = _virtualScroller$getS.firstShownItemIndex; // During render, check if the `items` list has changed.
|
|
22
|
+
nextItems = _ref.nextItems;
|
|
23
|
+
// During render, check if the `items` list has changed.
|
|
34
24
|
// If it has, capture the Y scroll position and updated item element `key`s.
|
|
35
25
|
// A long "advanced" sidenote on why capturing scroll Y position
|
|
36
26
|
// is done during render instead of in an "effect":
|
|
@@ -72,45 +62,36 @@ function useHandleItemsChange(items, _ref) {
|
|
|
72
62
|
// time rather than later in `componentDidUpdate()`: this way,
|
|
73
63
|
// scroll Y position is captured while the "Show previous" button
|
|
74
64
|
// is still being shown.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
var hasItemsPropertyChanged = items !== previousItems.current;
|
|
79
|
-
previousItems.current = items;
|
|
65
|
+
var previousItemsProperty = (0, _react.useRef)(itemsProperty);
|
|
66
|
+
var hasItemsPropertyChanged = itemsProperty !== previousItemsProperty.current;
|
|
67
|
+
previousItemsProperty.current = itemsProperty;
|
|
80
68
|
|
|
81
69
|
if (hasItemsPropertyChanged) {
|
|
82
|
-
var
|
|
83
|
-
|
|
84
|
-
var itemsDiff = virtualScroller.getItemsDiff(
|
|
70
|
+
var shouldUpdateItems = true; // Analyze the upcoming `items` change.
|
|
71
|
+
|
|
72
|
+
var itemsDiff = virtualScroller.getItemsDiff(nextItems, itemsProperty); // `itemsDiff` will be `undefined` in case of a non-incremental items list change.
|
|
85
73
|
|
|
86
74
|
if (itemsDiff) {
|
|
87
75
|
var prependedItemsCount = itemsDiff.prependedItemsCount,
|
|
88
76
|
appendedItemsCount = itemsDiff.appendedItemsCount;
|
|
89
77
|
|
|
90
78
|
if (prependedItemsCount === 0 && appendedItemsCount === 0) {
|
|
91
|
-
// The items
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
shouldUpdateItemKeys = false;
|
|
95
|
-
} else if (prependedItemsCount === 0 && appendedItemsCount > 0) {
|
|
96
|
-
// Just some items got appended. No need to re-generate
|
|
97
|
-
// the `key` prefix or to snapshot the Y scroll position.
|
|
98
|
-
shouldUpdateItemKeys = false;
|
|
79
|
+
// The items order hasn't changed.
|
|
80
|
+
// No need to update them in `VirtualScroller` or to snapshot the Y scroll position.
|
|
81
|
+
shouldUpdateItems = false;
|
|
99
82
|
}
|
|
100
83
|
}
|
|
101
84
|
|
|
102
|
-
if (
|
|
103
|
-
//
|
|
104
|
-
|
|
85
|
+
if (shouldUpdateItems) {
|
|
86
|
+
// Request to update the `items` in `VirtualScroller`.
|
|
87
|
+
// This will result in a `setState()` call.
|
|
88
|
+
// The new items won't be rendered until that state update is applied.
|
|
89
|
+
virtualScroller.setItems(itemsProperty, {
|
|
105
90
|
// `preserveScrollPosition` property name is deprecated,
|
|
106
91
|
// use `preserveScrollPositionOnPrependItems` property instead.
|
|
107
92
|
preserveScrollPositionOnPrependItems: preserveScrollPositionOnPrependItems || preserveScrollPosition
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
if (shouldUpdateItemKeys) {
|
|
111
|
-
updateItemKeysForNewItems();
|
|
112
|
-
}
|
|
93
|
+
});
|
|
113
94
|
}
|
|
114
95
|
}
|
|
115
96
|
}
|
|
116
|
-
//# sourceMappingURL=
|
|
97
|
+
//# sourceMappingURL=useHandleItemsPropertyChange.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useHandleItemsPropertyChange.js","names":["useHandleItemsPropertyChange","itemsProperty","virtualScroller","preserveScrollPosition","preserveScrollPositionOnPrependItems","nextItems","previousItemsProperty","useRef","hasItemsPropertyChanged","current","shouldUpdateItems","itemsDiff","getItemsDiff","prependedItemsCount","appendedItemsCount","setItems"],"sources":["../../source/react/useHandleItemsPropertyChange.js"],"sourcesContent":["import { useRef } from 'react'\r\n\r\n// If new `items` property is passed:\r\n//\r\n// * Store the scroll Y position for the first one of the current items\r\n// so that it could potentially (in some cases) be restored after the\r\n// new `items` are rendered.\r\n//\r\n// * Call `VirtualScroller.setItems()` function.\r\n//\r\nexport default function useHandleItemsPropertyChange(itemsProperty, {\r\n\tvirtualScroller,\r\n\t// `preserveScrollPosition` property name is deprecated,\r\n\t// use `preserveScrollPositionOnPrependItems` property instead.\r\n\tpreserveScrollPosition,\r\n\tpreserveScrollPositionOnPrependItems,\r\n\tnextItems\r\n}) {\r\n\t// During render, check if the `items` list has changed.\r\n\t// If it has, capture the Y scroll position and updated item element `key`s.\r\n\r\n\t// A long \"advanced\" sidenote on why capturing scroll Y position\r\n\t// is done during render instead of in an \"effect\":\r\n\t//\r\n\t// Previously, capturing scroll Y position was being done in `useLayoutEffect()`\r\n\t// but it was later found out that it wouldn't work for a \"Show previous\" button\r\n\t// scenario because that button would get hidden by the time `useLayoutEffect()`\r\n\t// gets called when there're no more \"previous\" items to show.\r\n\t//\r\n\t// Consider this code example:\r\n\t//\r\n\t// const { fromIndex, items } = this.state\r\n\t// const items = allItems.slice(fromIndex)\r\n\t// return (\r\n\t// \t{fromIndex > 0 &&\r\n\t// \t\t<button onClick={this.onShowPrevious}>\r\n\t// \t\t\tShow previous\r\n\t// \t\t</button>\r\n\t// \t}\r\n\t// \t<VirtualScroller\r\n\t// \t\titems={items}\r\n\t// \t\titemComponent={ItemComponent}/>\r\n\t// )\r\n\t//\r\n\t// Consider a user clicks \"Show previous\" to show the items from the start.\r\n\t// By the time `componentDidUpdate()` is called on `<VirtualScroller/>`,\r\n\t// the \"Show previous\" button has already been hidden\r\n\t// (because there're no more \"previous\" items)\r\n\t// which results in the scroll Y position jumping forward\r\n\t// by the height of that \"Show previous\" button.\r\n\t// This is because `<VirtualScroller/>` captures scroll Y\r\n\t// position when items are prepended via `.setItems()`\r\n\t// when the \"Show previous\" button is still being shown,\r\n\t// and then restores scroll Y position in `.onRender()`\r\n\t// when the \"Show previous\" button has already been hidden:\r\n\t// that's the reason for the scroll Y \"jump\".\r\n\t//\r\n\t// To prevent that, scroll Y position is captured at `render()`\r\n\t// time rather than later in `componentDidUpdate()`: this way,\r\n\t// scroll Y position is captured while the \"Show previous\" button\r\n\t// is still being shown.\r\n\r\n\tconst previousItemsProperty = useRef(itemsProperty)\r\n\tconst hasItemsPropertyChanged = itemsProperty !== previousItemsProperty.current\r\n\tpreviousItemsProperty.current = itemsProperty\r\n\r\n\tif (hasItemsPropertyChanged) {\r\n\t\tlet shouldUpdateItems = true\r\n\r\n\t\t// Analyze the upcoming `items` change.\r\n\t\tconst itemsDiff = virtualScroller.getItemsDiff(nextItems, itemsProperty)\r\n\r\n\t\t// `itemsDiff` will be `undefined` in case of a non-incremental items list change.\r\n\t\tif (itemsDiff) {\r\n\t\t\tconst {\r\n\t\t\t\tprependedItemsCount,\r\n\t\t\t\tappendedItemsCount\r\n\t\t\t} = itemsDiff\r\n\t\t\tif (prependedItemsCount === 0 && appendedItemsCount === 0) {\r\n\t\t\t\t// The items order hasn't changed.\r\n\t\t\t\t// No need to update them in `VirtualScroller` or to snapshot the Y scroll position.\r\n\t\t\t\tshouldUpdateItems = false\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (shouldUpdateItems) {\r\n\t\t\t// Request to update the `items` in `VirtualScroller`.\r\n\t\t\t// This will result in a `setState()` call.\r\n\t\t\t// The new items won't be rendered until that state update is applied.\r\n\t\t\tvirtualScroller.setItems(itemsProperty, {\r\n\t\t\t\t// `preserveScrollPosition` property name is deprecated,\r\n\t\t\t\t// use `preserveScrollPositionOnPrependItems` property instead.\r\n\t\t\t\tpreserveScrollPositionOnPrependItems: preserveScrollPositionOnPrependItems || preserveScrollPosition\r\n\t\t\t})\r\n\t\t}\r\n\t}\r\n}"],"mappings":";;;;;;;AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,SAASA,4BAAT,CAAsCC,aAAtC,QAOZ;EAAA,IANFC,eAME,QANFA,eAME;EAAA,IAHFC,sBAGE,QAHFA,sBAGE;EAAA,IAFFC,oCAEE,QAFFA,oCAEE;EAAA,IADFC,SACE,QADFA,SACE;EACF;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA,IAAMC,qBAAqB,GAAG,IAAAC,aAAA,EAAON,aAAP,CAA9B;EACA,IAAMO,uBAAuB,GAAGP,aAAa,KAAKK,qBAAqB,CAACG,OAAxE;EACAH,qBAAqB,CAACG,OAAtB,GAAgCR,aAAhC;;EAEA,IAAIO,uBAAJ,EAA6B;IAC5B,IAAIE,iBAAiB,GAAG,IAAxB,CAD4B,CAG5B;;IACA,IAAMC,SAAS,GAAGT,eAAe,CAACU,YAAhB,CAA6BP,SAA7B,EAAwCJ,aAAxC,CAAlB,CAJ4B,CAM5B;;IACA,IAAIU,SAAJ,EAAe;MACd,IACCE,mBADD,GAGIF,SAHJ,CACCE,mBADD;MAAA,IAECC,kBAFD,GAGIH,SAHJ,CAECG,kBAFD;;MAIA,IAAID,mBAAmB,KAAK,CAAxB,IAA6BC,kBAAkB,KAAK,CAAxD,EAA2D;QAC1D;QACA;QACAJ,iBAAiB,GAAG,KAApB;MACA;IACD;;IAED,IAAIA,iBAAJ,EAAuB;MACtB;MACA;MACA;MACAR,eAAe,CAACa,QAAhB,CAAyBd,aAAzB,EAAwC;QACvC;QACA;QACAG,oCAAoC,EAAEA,oCAAoC,IAAID;MAHvC,CAAxC;IAKA;EACD;AACD"}
|
|
@@ -8,11 +8,11 @@ exports["default"] = useOnItemHeightChange;
|
|
|
8
8
|
var _react = require("react");
|
|
9
9
|
|
|
10
10
|
function useOnItemHeightChange(_ref) {
|
|
11
|
-
var
|
|
11
|
+
var initialItemsCount = _ref.initialItemsCount,
|
|
12
12
|
virtualScroller = _ref.virtualScroller;
|
|
13
13
|
// Only compute the initial cache value once.
|
|
14
14
|
var initialCacheValue = (0, _react.useMemo)(function () {
|
|
15
|
-
return new Array(
|
|
15
|
+
return new Array(initialItemsCount);
|
|
16
16
|
}, []); // Handler functions cache.
|
|
17
17
|
|
|
18
18
|
var cache = (0, _react.useRef)(initialCacheValue); // Caches per-item `onItemHeightChange` functions' "references"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useOnItemHeightChange.js","names":["useOnItemHeightChange","
|
|
1
|
+
{"version":3,"file":"useOnItemHeightChange.js","names":["useOnItemHeightChange","initialItemsCount","virtualScroller","initialCacheValue","useMemo","Array","cache","useRef","getOnItemHeightChange","useCallback","i","current","onItemHeightChange"],"sources":["../../source/react/useOnItemHeightChange.js"],"sourcesContent":["import { useMemo, useRef, useCallback } from 'react'\r\n\r\nexport default function useOnItemHeightChange({\r\n\tinitialItemsCount,\r\n\tvirtualScroller\r\n}) {\r\n\t// Only compute the initial cache value once.\r\n\tconst initialCacheValue = useMemo(() => {\r\n\t\treturn new Array(initialItemsCount)\r\n\t}, [])\r\n\r\n\t// Handler functions cache.\r\n\tconst cache = useRef(initialCacheValue)\r\n\r\n\t// Caches per-item `onItemHeightChange` functions' \"references\"\r\n\t// so that item components don't get re-rendered needlessly.\r\n\tconst getOnItemHeightChange = useCallback((i) => {\r\n\t\tif (!cache.current[i]) {\r\n\t\t\tcache.current[i] = () => virtualScroller.onItemHeightChange(i)\r\n\t\t}\r\n\t\treturn cache.current[i]\r\n\t}, [\r\n\t\tvirtualScroller,\r\n\t\tcache\r\n\t])\r\n\r\n\treturn getOnItemHeightChange\r\n}"],"mappings":";;;;;;;AAAA;;AAEe,SAASA,qBAAT,OAGZ;EAAA,IAFFC,iBAEE,QAFFA,iBAEE;EAAA,IADFC,eACE,QADFA,eACE;EACF;EACA,IAAMC,iBAAiB,GAAG,IAAAC,cAAA,EAAQ,YAAM;IACvC,OAAO,IAAIC,KAAJ,CAAUJ,iBAAV,CAAP;EACA,CAFyB,EAEvB,EAFuB,CAA1B,CAFE,CAMF;;EACA,IAAMK,KAAK,GAAG,IAAAC,aAAA,EAAOJ,iBAAP,CAAd,CAPE,CASF;EACA;;EACA,IAAMK,qBAAqB,GAAG,IAAAC,kBAAA,EAAY,UAACC,CAAD,EAAO;IAChD,IAAI,CAACJ,KAAK,CAACK,OAAN,CAAcD,CAAd,CAAL,EAAuB;MACtBJ,KAAK,CAACK,OAAN,CAAcD,CAAd,IAAmB;QAAA,OAAMR,eAAe,CAACU,kBAAhB,CAAmCF,CAAnC,CAAN;MAAA,CAAnB;IACA;;IACD,OAAOJ,KAAK,CAACK,OAAN,CAAcD,CAAd,CAAP;EACA,CAL6B,EAK3B,CACFR,eADE,EAEFI,KAFE,CAL2B,CAA9B;EAUA,OAAOE,qBAAP;AACA"}
|
|
@@ -8,11 +8,11 @@ exports["default"] = useSetItemState;
|
|
|
8
8
|
var _react = require("react");
|
|
9
9
|
|
|
10
10
|
function useSetItemState(_ref) {
|
|
11
|
-
var
|
|
11
|
+
var initialItemsCount = _ref.initialItemsCount,
|
|
12
12
|
virtualScroller = _ref.virtualScroller;
|
|
13
13
|
// Only compute the initial cache value once.
|
|
14
14
|
var initialCacheValue = (0, _react.useMemo)(function () {
|
|
15
|
-
return new Array(
|
|
15
|
+
return new Array(initialItemsCount);
|
|
16
16
|
}, []); // Handler functions cache.
|
|
17
17
|
|
|
18
18
|
var cache = (0, _react.useRef)(initialCacheValue); // Caches per-item `setItemState` functions' "references"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSetItemState.js","names":["useSetItemState","
|
|
1
|
+
{"version":3,"file":"useSetItemState.js","names":["useSetItemState","initialItemsCount","virtualScroller","initialCacheValue","useMemo","Array","cache","useRef","getSetItemState","useCallback","i","current","itemState","setItemState"],"sources":["../../source/react/useSetItemState.js"],"sourcesContent":["import { useMemo, useRef, useCallback } from 'react'\r\n\r\nexport default function useSetItemState({\r\n\tinitialItemsCount,\r\n\tvirtualScroller\r\n}) {\r\n\t// Only compute the initial cache value once.\r\n\tconst initialCacheValue = useMemo(() => {\r\n\t\treturn new Array(initialItemsCount)\r\n\t}, [])\r\n\r\n\t// Handler functions cache.\r\n\tconst cache = useRef(initialCacheValue)\r\n\r\n\t// Caches per-item `setItemState` functions' \"references\"\r\n\t// so that item components don't get re-rendered needlessly.\r\n\tconst getSetItemState = useCallback((i) => {\r\n\t\tif (!cache.current[i]) {\r\n\t\t\tcache.current[i] = (itemState) => virtualScroller.setItemState(i, itemState)\r\n\t\t}\r\n\t\treturn cache.current[i]\r\n\t}, [\r\n\t\tvirtualScroller,\r\n\t\tcache\r\n\t])\r\n\r\n\treturn getSetItemState\r\n}"],"mappings":";;;;;;;AAAA;;AAEe,SAASA,eAAT,OAGZ;EAAA,IAFFC,iBAEE,QAFFA,iBAEE;EAAA,IADFC,eACE,QADFA,eACE;EACF;EACA,IAAMC,iBAAiB,GAAG,IAAAC,cAAA,EAAQ,YAAM;IACvC,OAAO,IAAIC,KAAJ,CAAUJ,iBAAV,CAAP;EACA,CAFyB,EAEvB,EAFuB,CAA1B,CAFE,CAMF;;EACA,IAAMK,KAAK,GAAG,IAAAC,aAAA,EAAOJ,iBAAP,CAAd,CAPE,CASF;EACA;;EACA,IAAMK,eAAe,GAAG,IAAAC,kBAAA,EAAY,UAACC,CAAD,EAAO;IAC1C,IAAI,CAACJ,KAAK,CAACK,OAAN,CAAcD,CAAd,CAAL,EAAuB;MACtBJ,KAAK,CAACK,OAAN,CAAcD,CAAd,IAAmB,UAACE,SAAD;QAAA,OAAeV,eAAe,CAACW,YAAhB,CAA6BH,CAA7B,EAAgCE,SAAhC,CAAf;MAAA,CAAnB;IACA;;IACD,OAAON,KAAK,CAACK,OAAN,CAAcD,CAAd,CAAP;EACA,CALuB,EAKrB,CACFR,eADE,EAEFI,KAFE,CALqB,CAAxB;EAUA,OAAOE,eAAP;AACA"}
|
|
@@ -29,110 +29,88 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
|
29
29
|
function _useState(_ref) {
|
|
30
30
|
var initialState = _ref.initialState,
|
|
31
31
|
onRender = _ref.onRender,
|
|
32
|
-
|
|
32
|
+
itemsProperty = _ref.itemsProperty,
|
|
33
|
+
USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION = _ref.USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION;
|
|
33
34
|
|
|
34
|
-
//
|
|
35
|
+
// This is a utility state variable that is used to re-render the component.
|
|
36
|
+
// It should not be used to access the current `VirtualScroller` state.
|
|
37
|
+
// It's more of a "requested" `VirtualScroller` state.
|
|
35
38
|
//
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
// the actual `state` of the `VirtualScroller`.
|
|
39
|
+
// It will also be stale in cases when `USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION`
|
|
40
|
+
// feature is used for setting new `items` in state.
|
|
39
41
|
//
|
|
40
|
-
|
|
41
|
-
// because it doesn't get initialized to `initialState`.
|
|
42
|
-
//
|
|
43
|
-
// * If `items` property gets changed, `state` reference variable gets updated immediately
|
|
44
|
-
// but the `_stateUpdate` variable here doesn't (until the component re-renders some other time).
|
|
45
|
-
//
|
|
46
|
-
// Instead, use the `state` reference below.
|
|
47
|
-
//
|
|
48
|
-
var _useState2 = (0, _react.useState)(),
|
|
42
|
+
var _useState2 = (0, _react.useState)(initialState),
|
|
49
43
|
_useState3 = _slicedToArray(_useState2, 2),
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
// It's also the "source of truth" on the actual `VirtualScroller` state.
|
|
55
|
-
//
|
|
44
|
+
_newState = _useState3[0],
|
|
45
|
+
_setNewState = _useState3[1]; // This `state` reference is what `VirtualScroller` uses internally.
|
|
46
|
+
// It's the "source of truth" on the actual `VirtualScroller` state.
|
|
56
47
|
|
|
57
48
|
|
|
58
|
-
var state = (0, _react.useRef)(initialState);
|
|
49
|
+
var state = (0, _react.useRef)(initialState);
|
|
50
|
+
var setState = (0, _react.useCallback)(function (newState) {
|
|
51
|
+
state.current = newState;
|
|
52
|
+
}, []); // Accumulates all "pending" state updates until they have been applied.
|
|
59
53
|
|
|
60
|
-
var
|
|
61
|
-
//
|
|
62
|
-
// Ignores the cases when `state` reference has already been updated
|
|
63
|
-
// "immediately" bypassing a `_setStateUpdate()` call, because
|
|
64
|
-
// in that case, `_stateUpdate` holds a stale value.
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
-
if (state.current !== targetState.current) {
|
|
68
|
-
state.current = _stateUpdate;
|
|
69
|
-
} // Call `onRender()` right after every state update.
|
|
70
|
-
//
|
|
71
|
-
// When `items` property changes, `useHandleItemsChange()` hook doesn't call
|
|
72
|
-
// `_setStateUpdate()` because there's no need for a re-render.
|
|
73
|
-
// But chaning `items` still does trigger a `VirtualScroller` state update,
|
|
74
|
-
// so added `items` property in the list of this "effect"'s dependencies.
|
|
75
|
-
//
|
|
54
|
+
var nextState = (0, _react.useRef)(initialState); // Updates the actual `VirtualScroller` state right after a requested state update
|
|
55
|
+
// has been applied. Doesn't do anything at initial render.
|
|
76
56
|
|
|
57
|
+
(0, _react.useLayoutEffect)(function () {
|
|
58
|
+
setState(_newState);
|
|
59
|
+
}, [_newState]); // Calls `onRender()` right after every state update (which is a re-render),
|
|
60
|
+
// and also right after the initial render.
|
|
77
61
|
|
|
78
62
|
(0, _react.useLayoutEffect)(function () {
|
|
79
63
|
onRender();
|
|
80
|
-
}, [
|
|
64
|
+
}, [_newState, // When using `USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION` feature,
|
|
65
|
+
// there won't be a `_setNewState()` function call when `items` property changes,
|
|
66
|
+
// hence the additional `itemsProperty` dependency.
|
|
67
|
+
USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION ? itemsProperty : undefined]);
|
|
81
68
|
return {
|
|
82
69
|
getState: function getState() {
|
|
83
70
|
return state.current;
|
|
84
71
|
},
|
|
85
|
-
|
|
72
|
+
getNextState: function getNextState() {
|
|
73
|
+
return nextState.current;
|
|
74
|
+
},
|
|
75
|
+
// Requests a state update.
|
|
86
76
|
//
|
|
87
|
-
// State updates are incremental meaning that this
|
|
77
|
+
// State updates are incremental meaning that this function mimicks
|
|
88
78
|
// the classic `React.Component`'s `this.setState()` behavior
|
|
89
|
-
// when calling `this.setState()`
|
|
90
|
-
//
|
|
79
|
+
// when calling `this.setState()` didn't replace `state` but rather merged
|
|
80
|
+
// the updated state properties over the "old" state properties.
|
|
91
81
|
//
|
|
92
|
-
// The reason
|
|
82
|
+
// The reason for using pending state updates accumulation is that
|
|
83
|
+
// `useState()` updates are "asynchronous" (not immediate),
|
|
93
84
|
// and simply merging over `...state` would merge over potentially stale
|
|
94
85
|
// property values in cases when more than a single `updateState()` call is made
|
|
95
|
-
// before the state actually updates, resulting in losing some of
|
|
86
|
+
// before the state actually updates, resulting in losing some of those state updates.
|
|
96
87
|
//
|
|
97
|
-
//
|
|
88
|
+
// Example: the first `updateState()` call updates shown item indexes,
|
|
98
89
|
// and the second `updateState()` call updates `verticalSpacing`.
|
|
99
90
|
// If it was simply `updateState({ ...state, ...stateUpdate })`
|
|
100
91
|
// then the second state update could overwrite the first state update,
|
|
101
92
|
// resulting in incorrect items being shown/hidden.
|
|
102
93
|
//
|
|
103
|
-
// Using `...state.current` instead of `...pendingState.current` here
|
|
104
|
-
// would produce "stale" results.
|
|
105
|
-
//
|
|
106
94
|
updateState: function updateState(stateUpdate) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
// if the state update was done as usual by calling `_setStateUpdate()`,
|
|
113
|
-
// React would throw an error about updating state during render.
|
|
114
|
-
// Hence, state update in that particular case should happen "directly",
|
|
115
|
-
// without waiting for an "asynchronous" effect to trigger and call
|
|
116
|
-
// an "asyncronous" `_setStateUpdate()` function.
|
|
117
|
-
//
|
|
118
|
-
// Updating state directly in that particular case works because there
|
|
119
|
-
// already is a render ongoing, so there's no need to re-render the component
|
|
120
|
-
// again after such render-time state update.
|
|
95
|
+
nextState.current = _objectSpread(_objectSpread({}, nextState.current), stateUpdate); // If `items` property did change, the component detects it at render time
|
|
96
|
+
// and updates `VirtualScroller` items immediately by calling `.setItems()`,
|
|
97
|
+
// which, in turn, immediately calls this `updateState()` function
|
|
98
|
+
// with a `stateUpdate` argument that contains the new `items`,
|
|
99
|
+
// so checking for `stateUpdate.items` could detect situations like that.
|
|
121
100
|
//
|
|
122
|
-
// When the initial `VirtualScroller` state is being set, it contains
|
|
101
|
+
// When the initial `VirtualScroller` state is being set, it contains the `.items`
|
|
123
102
|
// property too, but that initial setting is done using another function called
|
|
124
103
|
// `setInitialState()`, so using `if (stateUpdate.items)` condition here for describing
|
|
125
104
|
// just the case when `state` has been updated as a result of a `setItems()` call
|
|
126
105
|
// seems to be fine.
|
|
127
106
|
//
|
|
128
107
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
state.current = newState;
|
|
108
|
+
var _newState = nextState.current;
|
|
109
|
+
|
|
110
|
+
if (stateUpdate.items && USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION) {
|
|
111
|
+
setState(_newState);
|
|
134
112
|
} else {
|
|
135
|
-
|
|
113
|
+
_setNewState(_newState);
|
|
136
114
|
}
|
|
137
115
|
}
|
|
138
116
|
};
|