virtual-scroller 1.11.1 → 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/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
|
@@ -15,13 +15,35 @@ import useInstanceMethods from './useInstanceMethods.js';
|
|
|
15
15
|
import useItemKeys from './useItemKeys.js';
|
|
16
16
|
import useSetItemState from './useSetItemState.js';
|
|
17
17
|
import useOnItemHeightChange from './useOnItemHeightChange.js';
|
|
18
|
-
import
|
|
18
|
+
import useHandleItemsPropertyChange from './useHandleItemsPropertyChange.js';
|
|
19
|
+
import useHandleItemIndexesChange from './useHandleItemIndexesChange.js';
|
|
19
20
|
import useClassName from './useClassName.js';
|
|
20
|
-
import useStyle from './useStyle.js';
|
|
21
|
+
import useStyle from './useStyle.js'; // When `items` property changes, `useHandleItemsPropertyChange()` hook detects that
|
|
22
|
+
// and calls `VirtualScroller.setItems()` which in turn calls the `updateState()` function.
|
|
23
|
+
// At this point, an insignificant optimization could be applied:
|
|
24
|
+
// the component could avoid re-rendering the second time.
|
|
25
|
+
// Instead, the state update could be applied "immediately" if it originated
|
|
26
|
+
// from `.setItems()` function call, eliminating the unneeded second re-render.
|
|
27
|
+
//
|
|
28
|
+
// I could see how this minor optimization could get brittle when modifiying the code,
|
|
29
|
+
// so I put it under a feature flag so that it could potentially be turned off
|
|
30
|
+
// in case of any potential weird issues in some future.
|
|
31
|
+
//
|
|
32
|
+
// Another reason for using this feature is:
|
|
33
|
+
//
|
|
34
|
+
// Since `useHandleItemsPropertyChange()` runs at render time
|
|
35
|
+
// and not after the render has finished (not in an "effect"),
|
|
36
|
+
// if the state update was done "conventionally" (by calling `_setNewState()`),
|
|
37
|
+
// React would throw an error about updating state during render.
|
|
38
|
+
// No one knows what the original error message was.
|
|
39
|
+
// Perhaps it's no longer relevant in newer versions of React.
|
|
40
|
+
//
|
|
41
|
+
|
|
42
|
+
var USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION = true;
|
|
21
43
|
|
|
22
44
|
function VirtualScroller(_ref, ref) {
|
|
23
45
|
var AsComponent = _ref.as,
|
|
24
|
-
|
|
46
|
+
itemsProperty = _ref.items,
|
|
25
47
|
Component = _ref.itemComponent,
|
|
26
48
|
itemComponentProps = _ref.itemComponentProps,
|
|
27
49
|
estimatedItemHeight = _ref.estimatedItemHeight,
|
|
@@ -51,7 +73,7 @@ function VirtualScroller(_ref, ref) {
|
|
|
51
73
|
var container = useRef(); // Create a `VirtualScroller` instance.
|
|
52
74
|
|
|
53
75
|
var virtualScroller = useVirtualScroller({
|
|
54
|
-
items:
|
|
76
|
+
items: itemsProperty,
|
|
55
77
|
// `estimatedItemHeight` property name is deprecated,
|
|
56
78
|
// use `getEstimatedItemHeight` property instead.
|
|
57
79
|
estimatedItemHeight: estimatedItemHeight,
|
|
@@ -89,10 +111,12 @@ function VirtualScroller(_ref, ref) {
|
|
|
89
111
|
var _useState = useState({
|
|
90
112
|
initialState: _initialState,
|
|
91
113
|
onRender: virtualScroller.onRender,
|
|
92
|
-
|
|
114
|
+
itemsProperty: itemsProperty,
|
|
115
|
+
USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION: USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION
|
|
93
116
|
}),
|
|
94
117
|
getState = _useState.getState,
|
|
95
|
-
updateState = _useState.updateState
|
|
118
|
+
updateState = _useState.updateState,
|
|
119
|
+
getNextState = _useState.getNextState; // Use custom (external) state storage in the `VirtualScroller`.
|
|
96
120
|
|
|
97
121
|
|
|
98
122
|
useMemo(function () {
|
|
@@ -115,22 +139,28 @@ function VirtualScroller(_ref, ref) {
|
|
|
115
139
|
|
|
116
140
|
|
|
117
141
|
var getSetItemState = useSetItemState({
|
|
118
|
-
|
|
142
|
+
initialItemsCount: itemsProperty.length,
|
|
119
143
|
virtualScroller: virtualScroller
|
|
120
144
|
}); // Cache per-item `onItemHeightChange` functions' "references"
|
|
121
145
|
// so that item components don't get re-rendered needlessly.
|
|
122
146
|
|
|
123
147
|
var getOnItemHeightChange = useOnItemHeightChange({
|
|
124
|
-
|
|
148
|
+
initialItemsCount: itemsProperty.length,
|
|
125
149
|
virtualScroller: virtualScroller
|
|
126
|
-
}); //
|
|
150
|
+
}); // Calls `.setItems()` if `items` property has changed.
|
|
127
151
|
|
|
128
|
-
|
|
152
|
+
useHandleItemsPropertyChange(itemsProperty, {
|
|
129
153
|
virtualScroller: virtualScroller,
|
|
130
154
|
// `preserveScrollPosition` property name is deprecated,
|
|
131
155
|
// use `preserveScrollPositionOnPrependItems` property instead.
|
|
132
156
|
preserveScrollPosition: preserveScrollPosition,
|
|
133
157
|
preserveScrollPositionOnPrependItems: preserveScrollPositionOnPrependItems,
|
|
158
|
+
nextItems: getNextState().items
|
|
159
|
+
}); // Updates `key`s if item indexes have changed.
|
|
160
|
+
|
|
161
|
+
useHandleItemIndexesChange({
|
|
162
|
+
virtualScroller: virtualScroller,
|
|
163
|
+
itemsBeingRendered: getNextState().items,
|
|
134
164
|
updateItemKeysForNewItems: updateItemKeysForNewItems
|
|
135
165
|
}); // Add instance methods to the React component.
|
|
136
166
|
|
|
@@ -164,20 +194,20 @@ function VirtualScroller(_ref, ref) {
|
|
|
164
194
|
});
|
|
165
195
|
var style = useStyle({
|
|
166
196
|
tbody: tbody,
|
|
167
|
-
|
|
197
|
+
getNextState: getNextState
|
|
168
198
|
});
|
|
169
199
|
|
|
170
|
-
var
|
|
171
|
-
|
|
172
|
-
itemStates =
|
|
173
|
-
firstShownItemIndex =
|
|
174
|
-
lastShownItemIndex =
|
|
200
|
+
var _getNextState = getNextState(),
|
|
201
|
+
currentItems = _getNextState.items,
|
|
202
|
+
itemStates = _getNextState.itemStates,
|
|
203
|
+
firstShownItemIndex = _getNextState.firstShownItemIndex,
|
|
204
|
+
lastShownItemIndex = _getNextState.lastShownItemIndex;
|
|
175
205
|
|
|
176
206
|
return /*#__PURE__*/React.createElement(AsComponent, _extends({}, rest, {
|
|
177
207
|
ref: container,
|
|
178
208
|
className: className,
|
|
179
209
|
style: style
|
|
180
|
-
}),
|
|
210
|
+
}), currentItems.map(function (item, i) {
|
|
181
211
|
if (i >= firstShownItemIndex && i <= lastShownItemIndex) {
|
|
182
212
|
// * Passing `item` as `children` property is legacy and is deprecated.
|
|
183
213
|
// If version `2.x` is published in some hypothetical future,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualScroller.js","names":["React","useRef","useMemo","useLayoutEffect","PropTypes","useState","useVirtualScroller","useVirtualScrollerStartStop","useInstanceMethods","useItemKeys","useSetItemState","useOnItemHeightChange","useHandleItemsChange","useClassName","useStyle","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","virtualScroller","_initialState","getInitialState","onRender","getState","updateState","getItemKey","updateItemKeysForNewItems","getSetItemState","getOnItemHeightChange","style","renderedItems","itemStates","firstShownItemIndex","lastShownItemIndex","map","item","i","forwardRef","elementType","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":";;;;;;;;AAAA,OAAOA,KAAP,IAAgBC,MAAhB,EAAwBC,OAAxB,EAAiCC,eAAjC,QAAwD,OAAxD;AACA,OAAOC,SAAP,MAAsB,YAAtB;AAEA,OAAOC,QAAP,MAAqB,eAArB;AACA,OAAOC,kBAAP,MAA+B,yBAA/B;AACA,OAAOC,2BAAP,MAAwC,kCAAxC;AACA,OAAOC,kBAAP,MAA+B,yBAA/B;AACA,OAAOC,WAAP,MAAwB,kBAAxB;AACA,OAAOC,eAAP,MAA4B,sBAA5B;AACA,OAAOC,qBAAP,MAAkC,4BAAlC;AACA,OAAOC,oBAAP,MAAiC,2BAAjC;AACA,OAAOC,YAAP,MAAyB,mBAAzB;AACA,OAAOC,QAAP,MAAqB,eAArB;;AAEA,SAASC,eAAT,OAkCGC,GAlCH,EAkCQ;EAAA,IAjCHC,WAiCG,QAjCPC,EAiCO;EAAA,IAhCPC,KAgCO,QAhCPA,KAgCO;EAAA,IA/BQC,SA+BR,QA/BPC,aA+BO;EAAA,IA9BPC,kBA8BO,QA9BPA,kBA8BO;EAAA,IA3BPC,mBA2BO,QA3BPA,mBA2BO;EAAA,IA1BPC,sBA0BO,QA1BPA,sBA0BO;EAAA,IAzBPC,gCAyBO,QAzBPA,gCAyBO;EAAA,IAxBPC,MAwBO,QAxBPA,MAwBO;EAAA,IAvBPC,KAuBO,QAvBPA,KAuBO;EAAA,IApBPC,sBAoBO,QApBPA,sBAoBO;EAAA,IAnBPC,oCAmBO,QAnBPA,oCAmBO;EAAA,IAlBPC,qBAkBO,QAlBPA,qBAkBO;EAAA,IAfPC,mBAeO,QAfPA,mBAeO;EAAA,IAdPC,sBAcO,QAdPA,sBAcO;EAAA,IAbPC,eAaO,QAbPA,eAaO;EAAA,IAZPC,SAYO,QAZPA,SAYO;EAAA,IAXPC,SAWO,QAXPA,SAWO;EAAA,IAVPC,OAUO,QAVPA,OAUO;EAAA,IARPC,iBAQO,QARPA,iBAQO;EAAA,IAPPC,mBAOO,QAPPA,mBAOO;EAAA,IANPC,qBAMO,QANPA,qBAMO;EAAA,IALPC,sBAKO,QALPA,sBAKO;EAAA,IAJPC,aAIO,QAJPA,aAIO;EAAA,IAHPC,YAGO,QAHPA,YAGO;EAAA,IAFPC,mBAEO,QAFPA,mBAEO;EAAA,IADJC,IACI;;EACP;EACA,IAAMC,SAAS,GAAG5C,MAAM,EAAxB,CAFO,CAIP;;EACA,IAAM6C,eAAe,GAAGxC,kBAAkB,CAAC;IAC1Ca,KAAK,EAALA,KAD0C;IAE1C;IACA;IACAI,mBAAmB,EAAnBA,mBAJ0C;IAK1CC,sBAAsB,EAAtBA,sBAL0C;IAM1CC,gCAAgC,EAAhCA,gCAN0C;IAO1CC,MAAM,EAANA,MAP0C;IAQ1C;IACAC,KAAK,EAALA,KAT0C;IAU1CW,mBAAmB,EAAnBA,mBAV0C;IAW1C;IACAD,iBAAiB,EAAjBA,iBAZ0C;IAa1CE,qBAAqB,EAArBA,qBAb0C;IAc1CC,sBAAsB,EAAtBA,sBAd0C;IAe1CV,qBAAqB,EAArBA,qBAf0C;IAgB1C;IACA;IACAC,mBAAmB,EAAnBA,mBAlB0C;IAmB1CC,sBAAsB,EAAtBA,sBAnB0C;IAoB1CC,eAAe,EAAfA,eApB0C;IAqB1CC,SAAS,EAATA,SArB0C;IAsB1CjB,WAAW,EAAXA,WAtB0C;IAuB1CyB,YAAY,EAAZA,YAvB0C;IAwB1CC,mBAAmB,EAAnBA,mBAxB0C;IAyB1CF,aAAa,EAAbA;EAzB0C,CAAD,EA0BvC;IACFI,SAAS,EAATA;EADE,CA1BuC,CAA1C,CALO,CAmCP;;EACA,IAAME,aAAa,GAAG7C,OAAO,CAAC,YAAM;IACnC,OAAO4C,eAAe,CAACE,eAAhB,EAAP;EACA,CAF4B,EAE1B,EAF0B,CAA7B,CApCO,CAwCP;EACA;;;EACA,gBAGI3C,QAAQ,CAAC;IACZqC,YAAY,EAAEK,aADF;IAEZE,QAAQ,EAAEH,eAAe,CAACG,QAFd;IAGZ9B,KAAK,EAALA;EAHY,CAAD,CAHZ;EAAA,IACC+B,QADD,aACCA,QADD;EAAA,IAECC,WAFD,aAECA,WAFD,CA1CO,CAmDP;;;EACAjD,OAAO,CAAC,YAAM;IACb4C,eAAe,CAACzC,QAAhB,CAAyB;MACxB6C,QAAQ,EAARA,QADwB;MAExBC,WAAW,EAAXA;IAFwB,CAAzB;EAIA,CALM,EAKJ,EALI,CAAP,CApDO,CA2DP;EACA;;EACA5C,2BAA2B,CAACuC,eAAD,CAA3B,CA7DO,CA+DP;EACA;;EACA,mBAGIrC,WAAW,CAAC;IACfyB,SAAS,EAATA;EADe,CAAD,CAHf;EAAA,IACCkB,UADD,gBACCA,UADD;EAAA,IAECC,yBAFD,gBAECA,yBAFD,CAjEO,CAwEP;EACA;;;EACA,IAAMC,eAAe,GAAG5C,eAAe,CAAC;IACvCS,KAAK,EAALA,KADuC;IAEvC2B,eAAe,EAAfA;EAFuC,CAAD,CAAvC,CA1EO,CA+EP;EACA;;EACA,IAAMS,qBAAqB,GAAG5C,qBAAqB,CAAC;IACnDQ,KAAK,EAALA,KADmD;IAEnD2B,eAAe,EAAfA;EAFmD,CAAD,CAAnD,CAjFO,CAsFP;;EACAlC,oBAAoB,CAACO,KAAD,EAAQ;IAC3B2B,eAAe,EAAfA,eAD2B;IAE3B;IACA;IACAlB,sBAAsB,EAAtBA,sBAJ2B;IAK3BC,oCAAoC,EAApCA,oCAL2B;IAM3BwB,yBAAyB,EAAzBA;EAN2B,CAAR,CAApB,CAvFO,CAgGP;;EACA7C,kBAAkB,CAACQ,GAAD,EAAM;IACvB8B,eAAe,EAAfA;EADuB,CAAN,CAAlB;EAIA3C,eAAe,CAAC,YAAM;IACrB;IACA;IACA;IACA,IAAIiC,OAAJ,EAAa;MACZA,OAAO;IACP;EACD,CAPc,EAOZ,EAPY,CAAf,CArGO,CA8GP;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEAD,SAAS,GAAGtB,YAAY,CAACsB,SAAD,EAAY;IACnCR,KAAK,EAALA;EADmC,CAAZ,CAAxB;EAIA,IAAM6B,KAAK,GAAG1C,QAAQ,CAAC;IACtBa,KAAK,EAALA,KADsB;IAEtBmB,eAAe,EAAfA;EAFsB,CAAD,CAAtB;;EAKA,4BAKIA,eAAe,CAACI,QAAhB,EALJ;EAAA,IACQO,aADR,yBACCtC,KADD;EAAA,IAECuC,UAFD,yBAECA,UAFD;EAAA,IAGCC,mBAHD,yBAGCA,mBAHD;EAAA,IAICC,kBAJD,yBAICA,kBAJD;;EAOA,oBACC,oBAAC,WAAD,eACKhB,IADL;IAEC,GAAG,EAAEC,SAFN;IAGC,SAAS,EAAEV,SAHZ;IAIC,KAAK,EAAEqB;EAJR,IAKEC,aAAa,CAACI,GAAd,CAAkB,UAACC,IAAD,EAAOC,CAAP,EAAa;IAC/B,IAAIA,CAAC,IAAIJ,mBAAL,IAA4BI,CAAC,IAAIH,kBAArC,EAAyD;MACxD;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA,oBACC,oBAAC,SAAD;QACC,IAAI,EAAEE,IADP;QAEC,SAAS,EAAEC;MAFZ,GAGKzC,kBAHL;QAIC,GAAG,EAAE8B,UAAU,CAACU,IAAD,EAAOC,CAAP,CAJhB;QAKC,KAAK,EAAEL,UAAU,IAAIA,UAAU,CAACK,CAAD,CALhC;QAMC,QAAQ,EAAET,eAAe,CAACS,CAAD,CAN1B;QAOC,aAAa,EAAET,eAAe,CAACS,CAAD,CAP/B;QAQC,cAAc,EAAER,qBAAqB,CAACQ,CAAD;MARtC,IASED,IATF,CADD;IAaA;;IACD,OAAO,IAAP;EACA,CAhCA,CALF,CADD;AAyCA;;AAED/C,eAAe,gBAAGf,KAAK,CAACgE,UAAN,CAAiBjD,eAAjB,CAAlB;AAEA,eAAeA,eAAf,C,CAEA;AACA;;AACA,IAAMkD,WAAW,GAAG7D,SAAS,CAAC6D,WAAV,IAAyB7D,SAAS,CAAC8D,SAAV,CAAoB,CAChE9D,SAAS,CAAC+D,MADsD,EAEhE/D,SAAS,CAACgE,IAFsD,EAGhEhE,SAAS,CAACiE,MAHsD,CAApB,CAA7C;AAMAtD,eAAe,CAACuD,SAAhB,GAA4B;EAC3BpD,EAAE,EAAE+C,WADuB;EAE3B9C,KAAK,EAAEf,SAAS,CAACmE,OAAV,CAAkBnE,SAAS,CAACoE,GAA5B,EAAiCC,UAFb;EAG3BpD,aAAa,EAAE4C,WAAW,CAACQ,UAHA;EAI3BnD,kBAAkB,EAAElB,SAAS,CAACiE,MAJH;EAK3B;EACA;EACA9C,mBAAmB,EAAEnB,SAAS,CAACsE,MAPJ;EAQ3BlD,sBAAsB,EAAEpB,SAAS,CAACgE,IARP;EAS3B3C,gCAAgC,EAAErB,SAAS,CAACgE,IATjB;EAU3B1C,MAAM,EAAEtB,SAAS,CAACuE,IAVS;EAW3B;EACAhD,KAAK,EAAEvB,SAAS,CAACuE,IAZU;EAa3B9C,oCAAoC,EAAEzB,SAAS,CAACuE,IAbrB;EAc3B;EACA;EACA/C,sBAAsB,EAAExB,SAAS,CAACuE,IAhBP;EAiB3B7C,qBAAqB,EAAE1B,SAAS,CAACsE,MAjBN;EAkB3B;EACA;EACA3C,mBAAmB,EAAE3B,SAAS,CAACoE,GApBJ;EAqB3BxC,sBAAsB,EAAE5B,SAAS,CAACgE,IArBP;EAsB3BnC,eAAe,EAAE7B,SAAS,CAACgE,IAtBA;EAuB3BlC,SAAS,EAAE9B,SAAS,CAACgE,IAvBM;EAwB3BjC,SAAS,EAAE/B,SAAS,CAAC+D,MAxBM;EAyB3B/B,OAAO,EAAEhC,SAAS,CAACgE,IAzBQ;EA0B3B9B,mBAAmB,EAAElC,SAAS,CAACgE,IA1BJ;EA2B3B;EACA/B,iBAAiB,EAAEjC,SAAS,CAACgE,IA5BF;EA6B3B7B,qBAAqB,EAAEnC,SAAS,CAACsE,MA7BN;EA8B3BlC,sBAAsB,EAAEpC,SAAS,CAACgE,IA9BP;EA+B3B3B,aAAa,EAAErC,SAAS,CAACgE,IA/BE;EAgC3B1B,YAAY,EAAEtC,SAAS,CAACwE,KAAV,CAAgB;IAC7BzD,KAAK,EAAEf,SAAS,CAACmE,OAAV,CAAkBnE,SAAS,CAACiE,MAA5B,EAAoCI,UADd;IAE7Bf,UAAU,EAAEtD,SAAS,CAACmE,OAAV,CAAkBnE,SAAS,CAACoE,GAA5B,EAAiCC,UAFhB;IAG7Bd,mBAAmB,EAAEvD,SAAS,CAACsE,MAAV,CAAiBD,UAHT;IAI7Bb,kBAAkB,EAAExD,SAAS,CAACsE,MAAV,CAAiBD,UAJR;IAK7BI,iBAAiB,EAAEzE,SAAS,CAACsE,MAAV,CAAiBD,UALP;IAM7BK,gBAAgB,EAAE1E,SAAS,CAACsE,MAAV,CAAiBD,UANN;IAO7BM,WAAW,EAAE3E,SAAS,CAACmE,OAAV,CAAkBnE,SAAS,CAACsE,MAA5B,EAAoCD,UAPpB;IAQ7BO,YAAY,EAAE5E,SAAS,CAACsE,MARK;IAS7BO,eAAe,EAAE7E,SAAS,CAACsE;EATE,CAAhB,CAhCa;EA2C3B/B,mBAAmB,EAAEvC,SAAS,CAACgE;AA3CJ,CAA5B;AA8CArD,eAAe,CAACmE,YAAhB,GAA+B;EAC9BhE,EAAE,EAAE;AAD0B,CAA/B"}
|
|
1
|
+
{"version":3,"file":"VirtualScroller.js","names":["React","useRef","useMemo","useLayoutEffect","PropTypes","useState","useVirtualScroller","useVirtualScrollerStartStop","useInstanceMethods","useItemKeys","useSetItemState","useOnItemHeightChange","useHandleItemsPropertyChange","useHandleItemIndexesChange","useClassName","useStyle","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","virtualScroller","_initialState","getInitialState","onRender","getState","updateState","getNextState","getItemKey","updateItemKeysForNewItems","getSetItemState","initialItemsCount","length","getOnItemHeightChange","nextItems","itemsBeingRendered","style","currentItems","itemStates","firstShownItemIndex","lastShownItemIndex","map","item","i","forwardRef","elementType","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,45 @@
|
|
|
1
|
+
import { useRef } from 'react'; // If the order of the `items` changes, or new `items` get prepended resulting in a "shift":
|
|
2
|
+
//
|
|
3
|
+
// * Re-generate the React `key` prefix for item elements
|
|
4
|
+
// so that all item components are re-rendered for the new `items` list.
|
|
5
|
+
// That's because item components may have their own internal state,
|
|
6
|
+
// and simply passing another `item` property for an item component
|
|
7
|
+
// might result in bugs, which React would do with its "re-using" policy
|
|
8
|
+
// if the unique `key` workaround hasn't been used.
|
|
9
|
+
//
|
|
10
|
+
|
|
11
|
+
export default function useHandleItemIndexesChange(_ref) {
|
|
12
|
+
var virtualScroller = _ref.virtualScroller,
|
|
13
|
+
itemsBeingRendered = _ref.itemsBeingRendered,
|
|
14
|
+
updateItemKeysForNewItems = _ref.updateItemKeysForNewItems;
|
|
15
|
+
var previousItemsBeingRenderedRef = useRef(itemsBeingRendered);
|
|
16
|
+
var previousItemsBeingRendered = previousItemsBeingRenderedRef.current;
|
|
17
|
+
var haveItemsChanged = itemsBeingRendered !== previousItemsBeingRendered;
|
|
18
|
+
previousItemsBeingRenderedRef.current = itemsBeingRendered;
|
|
19
|
+
|
|
20
|
+
if (haveItemsChanged) {
|
|
21
|
+
var shouldUpdateItemKeys = true;
|
|
22
|
+
var itemsDiff = virtualScroller.getItemsDiff(previousItemsBeingRendered, itemsBeingRendered); // `itemsDiff` will be `undefined` in case of a non-incremental items list change.
|
|
23
|
+
|
|
24
|
+
if (itemsDiff) {
|
|
25
|
+
var prependedItemsCount = itemsDiff.prependedItemsCount,
|
|
26
|
+
appendedItemsCount = itemsDiff.appendedItemsCount;
|
|
27
|
+
|
|
28
|
+
if (prependedItemsCount === 0 && appendedItemsCount === 0) {
|
|
29
|
+
// The items order hasn't changed.
|
|
30
|
+
// No need to re-generate the `key` prefix.
|
|
31
|
+
shouldUpdateItemKeys = false;
|
|
32
|
+
} else if (prependedItemsCount === 0 && appendedItemsCount > 0) {
|
|
33
|
+
// The item order hasn't changed.
|
|
34
|
+
// No need to re-generate the `key` prefix.
|
|
35
|
+
shouldUpdateItemKeys = false;
|
|
36
|
+
}
|
|
37
|
+
} // Update React element `key`s for the new set of `items`.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
if (shouldUpdateItemKeys) {
|
|
41
|
+
updateItemKeysForNewItems();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=useHandleItemIndexesChange.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useHandleItemIndexesChange.js","names":["useRef","useHandleItemIndexesChange","virtualScroller","itemsBeingRendered","updateItemKeysForNewItems","previousItemsBeingRenderedRef","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,SAASA,MAAT,QAAuB,OAAvB,C,CAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,eAAe,SAASC,0BAAT,OAIZ;EAAA,IAHFC,eAGE,QAHFA,eAGE;EAAA,IAFFC,kBAEE,QAFFA,kBAEE;EAAA,IADFC,yBACE,QADFA,yBACE;EACF,IAAMC,6BAA6B,GAAGL,MAAM,CAACG,kBAAD,CAA5C;EACA,IAAMG,0BAA0B,GAAGD,6BAA6B,CAACE,OAAjE;EACA,IAAMC,gBAAgB,GAAGL,kBAAkB,KAAKG,0BAAhD;EACAD,6BAA6B,CAACE,OAA9B,GAAwCJ,kBAAxC;;EAEA,IAAIK,gBAAJ,EAAsB;IACrB,IAAIC,oBAAoB,GAAG,IAA3B;IAEA,IAAMC,SAAS,GAAGR,eAAe,CAACS,YAAhB,CAA6BL,0BAA7B,EAAyDH,kBAAzD,CAAlB,CAHqB,CAIrB;;IACA,IAAIO,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;MACzBL,yBAAyB;IACzB;EACD;AACD"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useRef } from 'react'; // If new `items`
|
|
1
|
+
import { useRef } from 'react'; // If new `items` property is passed:
|
|
2
2
|
//
|
|
3
3
|
// * Store the scroll Y position for the first one of the current items
|
|
4
4
|
// so that it could potentially (in some cases) be restored after the
|
|
@@ -6,23 +6,13 @@ import { useRef } from 'react'; // If new `items` are passed:
|
|
|
6
6
|
//
|
|
7
7
|
// * Call `VirtualScroller.setItems()` function.
|
|
8
8
|
//
|
|
9
|
-
// * Re-generate the React `key` prefix for item elements
|
|
10
|
-
// so that all item components are re-rendered for the new `items` list.
|
|
11
|
-
// That's because item components may have their own internal state,
|
|
12
|
-
// and simply passing another `item` property for an item component
|
|
13
|
-
// might result in bugs, which React would do with its "re-using" policy
|
|
14
|
-
// if the unique `key` workaround hasn't been used.
|
|
15
|
-
//
|
|
16
9
|
|
|
17
|
-
export default function
|
|
10
|
+
export default function useHandleItemsPropertyChange(itemsProperty, _ref) {
|
|
18
11
|
var virtualScroller = _ref.virtualScroller,
|
|
19
12
|
preserveScrollPosition = _ref.preserveScrollPosition,
|
|
20
13
|
preserveScrollPositionOnPrependItems = _ref.preserveScrollPositionOnPrependItems,
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
var _virtualScroller$getS = virtualScroller.getState(),
|
|
24
|
-
renderedItems = _virtualScroller$getS.items,
|
|
25
|
-
firstShownItemIndex = _virtualScroller$getS.firstShownItemIndex; // During render, check if the `items` list has changed.
|
|
14
|
+
nextItems = _ref.nextItems;
|
|
15
|
+
// During render, check if the `items` list has changed.
|
|
26
16
|
// If it has, capture the Y scroll position and updated item element `key`s.
|
|
27
17
|
// A long "advanced" sidenote on why capturing scroll Y position
|
|
28
18
|
// is done during render instead of in an "effect":
|
|
@@ -64,45 +54,36 @@ export default function useHandleItemsChange(items, _ref) {
|
|
|
64
54
|
// time rather than later in `componentDidUpdate()`: this way,
|
|
65
55
|
// scroll Y position is captured while the "Show previous" button
|
|
66
56
|
// is still being shown.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
var hasItemsPropertyChanged = items !== previousItems.current;
|
|
71
|
-
previousItems.current = items;
|
|
57
|
+
var previousItemsProperty = useRef(itemsProperty);
|
|
58
|
+
var hasItemsPropertyChanged = itemsProperty !== previousItemsProperty.current;
|
|
59
|
+
previousItemsProperty.current = itemsProperty;
|
|
72
60
|
|
|
73
61
|
if (hasItemsPropertyChanged) {
|
|
74
|
-
var
|
|
75
|
-
|
|
76
|
-
var itemsDiff = virtualScroller.getItemsDiff(
|
|
62
|
+
var shouldUpdateItems = true; // Analyze the upcoming `items` change.
|
|
63
|
+
|
|
64
|
+
var itemsDiff = virtualScroller.getItemsDiff(nextItems, itemsProperty); // `itemsDiff` will be `undefined` in case of a non-incremental items list change.
|
|
77
65
|
|
|
78
66
|
if (itemsDiff) {
|
|
79
67
|
var prependedItemsCount = itemsDiff.prependedItemsCount,
|
|
80
68
|
appendedItemsCount = itemsDiff.appendedItemsCount;
|
|
81
69
|
|
|
82
70
|
if (prependedItemsCount === 0 && appendedItemsCount === 0) {
|
|
83
|
-
// The items
|
|
84
|
-
//
|
|
85
|
-
|
|
86
|
-
shouldUpdateItemKeys = false;
|
|
87
|
-
} else if (prependedItemsCount === 0 && appendedItemsCount > 0) {
|
|
88
|
-
// Just some items got appended. No need to re-generate
|
|
89
|
-
// the `key` prefix or to snapshot the Y scroll position.
|
|
90
|
-
shouldUpdateItemKeys = false;
|
|
71
|
+
// The items order hasn't changed.
|
|
72
|
+
// No need to update them in `VirtualScroller` or to snapshot the Y scroll position.
|
|
73
|
+
shouldUpdateItems = false;
|
|
91
74
|
}
|
|
92
75
|
}
|
|
93
76
|
|
|
94
|
-
if (
|
|
95
|
-
//
|
|
96
|
-
|
|
77
|
+
if (shouldUpdateItems) {
|
|
78
|
+
// Request to update the `items` in `VirtualScroller`.
|
|
79
|
+
// This will result in a `setState()` call.
|
|
80
|
+
// The new items won't be rendered until that state update is applied.
|
|
81
|
+
virtualScroller.setItems(itemsProperty, {
|
|
97
82
|
// `preserveScrollPosition` property name is deprecated,
|
|
98
83
|
// use `preserveScrollPositionOnPrependItems` property instead.
|
|
99
84
|
preserveScrollPositionOnPrependItems: preserveScrollPositionOnPrependItems || preserveScrollPosition
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
if (shouldUpdateItemKeys) {
|
|
103
|
-
updateItemKeysForNewItems();
|
|
104
|
-
}
|
|
85
|
+
});
|
|
105
86
|
}
|
|
106
87
|
}
|
|
107
88
|
}
|
|
108
|
-
//# sourceMappingURL=
|
|
89
|
+
//# sourceMappingURL=useHandleItemsPropertyChange.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useHandleItemsPropertyChange.js","names":["useRef","useHandleItemsPropertyChange","itemsProperty","virtualScroller","preserveScrollPosition","preserveScrollPositionOnPrependItems","nextItems","previousItemsProperty","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,SAASA,MAAT,QAAuB,OAAvB,C,CAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,eAAe,SAASC,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,GAAGP,MAAM,CAACE,aAAD,CAApC;EACA,IAAMM,uBAAuB,GAAGN,aAAa,KAAKK,qBAAqB,CAACE,OAAxE;EACAF,qBAAqB,CAACE,OAAtB,GAAgCP,aAAhC;;EAEA,IAAIM,uBAAJ,EAA6B;IAC5B,IAAIE,iBAAiB,GAAG,IAAxB,CAD4B,CAG5B;;IACA,IAAMC,SAAS,GAAGR,eAAe,CAACS,YAAhB,CAA6BN,SAA7B,EAAwCJ,aAAxC,CAAlB,CAJ4B,CAM5B;;IACA,IAAIS,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;MACAP,eAAe,CAACY,QAAhB,CAAyBb,aAAzB,EAAwC;QACvC;QACA;QACAG,oCAAoC,EAAEA,oCAAoC,IAAID;MAHvC,CAAxC;IAKA;EACD;AACD"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useMemo, useRef, useCallback } from 'react';
|
|
2
2
|
export default function useOnItemHeightChange(_ref) {
|
|
3
|
-
var
|
|
3
|
+
var initialItemsCount = _ref.initialItemsCount,
|
|
4
4
|
virtualScroller = _ref.virtualScroller;
|
|
5
5
|
// Only compute the initial cache value once.
|
|
6
6
|
var initialCacheValue = useMemo(function () {
|
|
7
|
-
return new Array(
|
|
7
|
+
return new Array(initialItemsCount);
|
|
8
8
|
}, []); // Handler functions cache.
|
|
9
9
|
|
|
10
10
|
var cache = useRef(initialCacheValue); // Caches per-item `onItemHeightChange` functions' "references"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useOnItemHeightChange.js","names":["useMemo","useRef","useCallback","useOnItemHeightChange","
|
|
1
|
+
{"version":3,"file":"useOnItemHeightChange.js","names":["useMemo","useRef","useCallback","useOnItemHeightChange","initialItemsCount","virtualScroller","initialCacheValue","Array","cache","getOnItemHeightChange","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,SAASA,OAAT,EAAkBC,MAAlB,EAA0BC,WAA1B,QAA6C,OAA7C;AAEA,eAAe,SAASC,qBAAT,OAGZ;EAAA,IAFFC,iBAEE,QAFFA,iBAEE;EAAA,IADFC,eACE,QADFA,eACE;EACF;EACA,IAAMC,iBAAiB,GAAGN,OAAO,CAAC,YAAM;IACvC,OAAO,IAAIO,KAAJ,CAAUH,iBAAV,CAAP;EACA,CAFgC,EAE9B,EAF8B,CAAjC,CAFE,CAMF;;EACA,IAAMI,KAAK,GAAGP,MAAM,CAACK,iBAAD,CAApB,CAPE,CASF;EACA;;EACA,IAAMG,qBAAqB,GAAGP,WAAW,CAAC,UAACQ,CAAD,EAAO;IAChD,IAAI,CAACF,KAAK,CAACG,OAAN,CAAcD,CAAd,CAAL,EAAuB;MACtBF,KAAK,CAACG,OAAN,CAAcD,CAAd,IAAmB;QAAA,OAAML,eAAe,CAACO,kBAAhB,CAAmCF,CAAnC,CAAN;MAAA,CAAnB;IACA;;IACD,OAAOF,KAAK,CAACG,OAAN,CAAcD,CAAd,CAAP;EACA,CALwC,EAKtC,CACFL,eADE,EAEFG,KAFE,CALsC,CAAzC;EAUA,OAAOC,qBAAP;AACA"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useMemo, useRef, useCallback } from 'react';
|
|
2
2
|
export default function useSetItemState(_ref) {
|
|
3
|
-
var
|
|
3
|
+
var initialItemsCount = _ref.initialItemsCount,
|
|
4
4
|
virtualScroller = _ref.virtualScroller;
|
|
5
5
|
// Only compute the initial cache value once.
|
|
6
6
|
var initialCacheValue = useMemo(function () {
|
|
7
|
-
return new Array(
|
|
7
|
+
return new Array(initialItemsCount);
|
|
8
8
|
}, []); // Handler functions cache.
|
|
9
9
|
|
|
10
10
|
var cache = useRef(initialCacheValue); // Caches per-item `setItemState` functions' "references"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSetItemState.js","names":["useMemo","useRef","useCallback","useSetItemState","
|
|
1
|
+
{"version":3,"file":"useSetItemState.js","names":["useMemo","useRef","useCallback","useSetItemState","initialItemsCount","virtualScroller","initialCacheValue","Array","cache","getSetItemState","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,SAASA,OAAT,EAAkBC,MAAlB,EAA0BC,WAA1B,QAA6C,OAA7C;AAEA,eAAe,SAASC,eAAT,OAGZ;EAAA,IAFFC,iBAEE,QAFFA,iBAEE;EAAA,IADFC,eACE,QADFA,eACE;EACF;EACA,IAAMC,iBAAiB,GAAGN,OAAO,CAAC,YAAM;IACvC,OAAO,IAAIO,KAAJ,CAAUH,iBAAV,CAAP;EACA,CAFgC,EAE9B,EAF8B,CAAjC,CAFE,CAMF;;EACA,IAAMI,KAAK,GAAGP,MAAM,CAACK,iBAAD,CAApB,CAPE,CASF;EACA;;EACA,IAAMG,eAAe,GAAGP,WAAW,CAAC,UAACQ,CAAD,EAAO;IAC1C,IAAI,CAACF,KAAK,CAACG,OAAN,CAAcD,CAAd,CAAL,EAAuB;MACtBF,KAAK,CAACG,OAAN,CAAcD,CAAd,IAAmB,UAACE,SAAD;QAAA,OAAeP,eAAe,CAACQ,YAAhB,CAA6BH,CAA7B,EAAgCE,SAAhC,CAAf;MAAA,CAAnB;IACA;;IACD,OAAOJ,KAAK,CAACG,OAAN,CAAcD,CAAd,CAAP;EACA,CALkC,EAKhC,CACFL,eADE,EAEFG,KAFE,CALgC,CAAnC;EAUA,OAAOC,eAAP;AACA"}
|
|
@@ -16,115 +16,93 @@ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Sy
|
|
|
16
16
|
|
|
17
17
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
18
18
|
|
|
19
|
-
import { useState, useRef, useLayoutEffect } from 'react'; // Creates state management functions.
|
|
19
|
+
import { useState, useRef, useCallback, useLayoutEffect } from 'react'; // Creates state management functions.
|
|
20
20
|
|
|
21
21
|
export default function _useState(_ref) {
|
|
22
22
|
var initialState = _ref.initialState,
|
|
23
23
|
onRender = _ref.onRender,
|
|
24
|
-
|
|
24
|
+
itemsProperty = _ref.itemsProperty,
|
|
25
|
+
USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION = _ref.USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION;
|
|
25
26
|
|
|
26
|
-
//
|
|
27
|
+
// This is a utility state variable that is used to re-render the component.
|
|
28
|
+
// It should not be used to access the current `VirtualScroller` state.
|
|
29
|
+
// It's more of a "requested" `VirtualScroller` state.
|
|
27
30
|
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
// the actual `state` of the `VirtualScroller`.
|
|
31
|
+
// It will also be stale in cases when `USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION`
|
|
32
|
+
// feature is used for setting new `items` in state.
|
|
31
33
|
//
|
|
32
|
-
|
|
33
|
-
// because it doesn't get initialized to `initialState`.
|
|
34
|
-
//
|
|
35
|
-
// * If `items` property gets changed, `state` reference variable gets updated immediately
|
|
36
|
-
// but the `_stateUpdate` variable here doesn't (until the component re-renders some other time).
|
|
37
|
-
//
|
|
38
|
-
// Instead, use the `state` reference below.
|
|
39
|
-
//
|
|
40
|
-
var _useState2 = useState(),
|
|
34
|
+
var _useState2 = useState(initialState),
|
|
41
35
|
_useState3 = _slicedToArray(_useState2, 2),
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
// It's also the "source of truth" on the actual `VirtualScroller` state.
|
|
47
|
-
//
|
|
36
|
+
_newState = _useState3[0],
|
|
37
|
+
_setNewState = _useState3[1]; // This `state` reference is what `VirtualScroller` uses internally.
|
|
38
|
+
// It's the "source of truth" on the actual `VirtualScroller` state.
|
|
48
39
|
|
|
49
40
|
|
|
50
|
-
var state = useRef(initialState);
|
|
41
|
+
var state = useRef(initialState);
|
|
42
|
+
var setState = useCallback(function (newState) {
|
|
43
|
+
state.current = newState;
|
|
44
|
+
}, []); // Accumulates all "pending" state updates until they have been applied.
|
|
51
45
|
|
|
52
|
-
var
|
|
53
|
-
//
|
|
54
|
-
// Ignores the cases when `state` reference has already been updated
|
|
55
|
-
// "immediately" bypassing a `_setStateUpdate()` call, because
|
|
56
|
-
// in that case, `_stateUpdate` holds a stale value.
|
|
57
|
-
//
|
|
58
|
-
|
|
59
|
-
if (state.current !== targetState.current) {
|
|
60
|
-
state.current = _stateUpdate;
|
|
61
|
-
} // Call `onRender()` right after every state update.
|
|
62
|
-
//
|
|
63
|
-
// When `items` property changes, `useHandleItemsChange()` hook doesn't call
|
|
64
|
-
// `_setStateUpdate()` because there's no need for a re-render.
|
|
65
|
-
// But chaning `items` still does trigger a `VirtualScroller` state update,
|
|
66
|
-
// so added `items` property in the list of this "effect"'s dependencies.
|
|
67
|
-
//
|
|
46
|
+
var nextState = useRef(initialState); // Updates the actual `VirtualScroller` state right after a requested state update
|
|
47
|
+
// has been applied. Doesn't do anything at initial render.
|
|
68
48
|
|
|
49
|
+
useLayoutEffect(function () {
|
|
50
|
+
setState(_newState);
|
|
51
|
+
}, [_newState]); // Calls `onRender()` right after every state update (which is a re-render),
|
|
52
|
+
// and also right after the initial render.
|
|
69
53
|
|
|
70
54
|
useLayoutEffect(function () {
|
|
71
55
|
onRender();
|
|
72
|
-
}, [
|
|
56
|
+
}, [_newState, // When using `USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION` feature,
|
|
57
|
+
// there won't be a `_setNewState()` function call when `items` property changes,
|
|
58
|
+
// hence the additional `itemsProperty` dependency.
|
|
59
|
+
USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION ? itemsProperty : undefined]);
|
|
73
60
|
return {
|
|
74
61
|
getState: function getState() {
|
|
75
62
|
return state.current;
|
|
76
63
|
},
|
|
77
|
-
|
|
64
|
+
getNextState: function getNextState() {
|
|
65
|
+
return nextState.current;
|
|
66
|
+
},
|
|
67
|
+
// Requests a state update.
|
|
78
68
|
//
|
|
79
|
-
// State updates are incremental meaning that this
|
|
69
|
+
// State updates are incremental meaning that this function mimicks
|
|
80
70
|
// the classic `React.Component`'s `this.setState()` behavior
|
|
81
|
-
// when calling `this.setState()`
|
|
82
|
-
//
|
|
71
|
+
// when calling `this.setState()` didn't replace `state` but rather merged
|
|
72
|
+
// the updated state properties over the "old" state properties.
|
|
83
73
|
//
|
|
84
|
-
// The reason
|
|
74
|
+
// The reason for using pending state updates accumulation is that
|
|
75
|
+
// `useState()` updates are "asynchronous" (not immediate),
|
|
85
76
|
// and simply merging over `...state` would merge over potentially stale
|
|
86
77
|
// property values in cases when more than a single `updateState()` call is made
|
|
87
|
-
// before the state actually updates, resulting in losing some of
|
|
78
|
+
// before the state actually updates, resulting in losing some of those state updates.
|
|
88
79
|
//
|
|
89
|
-
//
|
|
80
|
+
// Example: the first `updateState()` call updates shown item indexes,
|
|
90
81
|
// and the second `updateState()` call updates `verticalSpacing`.
|
|
91
82
|
// If it was simply `updateState({ ...state, ...stateUpdate })`
|
|
92
83
|
// then the second state update could overwrite the first state update,
|
|
93
84
|
// resulting in incorrect items being shown/hidden.
|
|
94
85
|
//
|
|
95
|
-
// Using `...state.current` instead of `...pendingState.current` here
|
|
96
|
-
// would produce "stale" results.
|
|
97
|
-
//
|
|
98
86
|
updateState: function updateState(stateUpdate) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
-
// if the state update was done as usual by calling `_setStateUpdate()`,
|
|
105
|
-
// React would throw an error about updating state during render.
|
|
106
|
-
// Hence, state update in that particular case should happen "directly",
|
|
107
|
-
// without waiting for an "asynchronous" effect to trigger and call
|
|
108
|
-
// an "asyncronous" `_setStateUpdate()` function.
|
|
109
|
-
//
|
|
110
|
-
// Updating state directly in that particular case works because there
|
|
111
|
-
// already is a render ongoing, so there's no need to re-render the component
|
|
112
|
-
// again after such render-time state update.
|
|
87
|
+
nextState.current = _objectSpread(_objectSpread({}, nextState.current), stateUpdate); // If `items` property did change, the component detects it at render time
|
|
88
|
+
// and updates `VirtualScroller` items immediately by calling `.setItems()`,
|
|
89
|
+
// which, in turn, immediately calls this `updateState()` function
|
|
90
|
+
// with a `stateUpdate` argument that contains the new `items`,
|
|
91
|
+
// so checking for `stateUpdate.items` could detect situations like that.
|
|
113
92
|
//
|
|
114
|
-
// When the initial `VirtualScroller` state is being set, it contains
|
|
93
|
+
// When the initial `VirtualScroller` state is being set, it contains the `.items`
|
|
115
94
|
// property too, but that initial setting is done using another function called
|
|
116
95
|
// `setInitialState()`, so using `if (stateUpdate.items)` condition here for describing
|
|
117
96
|
// just the case when `state` has been updated as a result of a `setItems()` call
|
|
118
97
|
// seems to be fine.
|
|
119
98
|
//
|
|
120
99
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
state.current = newState;
|
|
100
|
+
var _newState = nextState.current;
|
|
101
|
+
|
|
102
|
+
if (stateUpdate.items && USE_ITEMS_UPDATE_NO_SECOND_RENDER_OPTIMIZATION) {
|
|
103
|
+
setState(_newState);
|
|
126
104
|
} else {
|
|
127
|
-
|
|
105
|
+
_setNewState(_newState);
|
|
128
106
|
}
|
|
129
107
|
}
|
|
130
108
|
};
|