virtual-scroller 1.10.2 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.md +48 -24
- 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/VirtualScroller.js +5 -0
- package/commonjs/DOM/VirtualScroller.js.map +1 -1
- package/commonjs/ItemHeights.js +1 -1
- package/commonjs/ItemHeights.js.map +1 -1
- package/commonjs/VirtualScroller.constructor.js +3 -0
- package/commonjs/VirtualScroller.constructor.js.map +1 -1
- package/commonjs/VirtualScroller.items.js +11 -10
- package/commonjs/VirtualScroller.items.js.map +1 -1
- package/commonjs/VirtualScroller.js +10 -3
- package/commonjs/VirtualScroller.js.map +1 -1
- package/commonjs/VirtualScroller.layout.js +2 -2
- package/commonjs/VirtualScroller.layout.js.map +1 -1
- package/commonjs/VirtualScroller.state.js +23 -13
- package/commonjs/VirtualScroller.state.js.map +1 -1
- package/commonjs/react/VirtualScroller.js +26 -11
- package/commonjs/react/VirtualScroller.js.map +1 -1
- package/commonjs/react/{useOnItemStateChange.js → useSetItemState.js} +7 -7
- package/commonjs/react/useSetItemState.js.map +1 -0
- package/commonjs/react/useVirtualScroller.js +2 -1
- package/commonjs/react/useVirtualScroller.js.map +1 -1
- package/commonjs/utility/fillArray.js +18 -0
- package/commonjs/utility/fillArray.js.map +1 -0
- package/dom/index.d.ts +7 -6
- package/index.d.ts +16 -15
- package/modules/DOM/VirtualScroller.js +5 -0
- package/modules/DOM/VirtualScroller.js.map +1 -1
- package/modules/ItemHeights.js +1 -1
- package/modules/ItemHeights.js.map +1 -1
- package/modules/VirtualScroller.constructor.js +3 -0
- package/modules/VirtualScroller.constructor.js.map +1 -1
- package/modules/VirtualScroller.items.js +10 -10
- package/modules/VirtualScroller.items.js.map +1 -1
- package/modules/VirtualScroller.js +10 -3
- package/modules/VirtualScroller.js.map +1 -1
- package/modules/VirtualScroller.layout.js +2 -2
- package/modules/VirtualScroller.layout.js.map +1 -1
- package/modules/VirtualScroller.state.js +20 -11
- package/modules/VirtualScroller.state.js.map +1 -1
- package/modules/react/VirtualScroller.js +26 -11
- package/modules/react/VirtualScroller.js.map +1 -1
- package/modules/react/{useOnItemStateChange.js → useSetItemState.js} +6 -6
- package/modules/react/useSetItemState.js.map +1 -0
- package/modules/react/useVirtualScroller.js +2 -1
- package/modules/react/useVirtualScroller.js.map +1 -1
- package/modules/utility/fillArray.js +11 -0
- package/modules/utility/fillArray.js.map +1 -0
- package/package.json +1 -1
- package/react/index.d.ts +14 -8
- package/source/DOM/VirtualScroller.js +4 -0
- package/source/ItemHeights.js +1 -1
- package/source/VirtualScroller.constructor.js +2 -1
- package/source/VirtualScroller.items.js +16 -8
- package/source/VirtualScroller.js +8 -2
- package/source/VirtualScroller.layout.js +2 -2
- package/source/VirtualScroller.state.js +15 -7
- package/source/react/VirtualScroller.js +25 -10
- package/source/react/{useOnItemStateChange.js → useSetItemState.js} +5 -5
- package/source/react/useVirtualScroller.js +2 -0
- package/source/utility/fillArray.js +8 -0
- package/commonjs/react/useOnItemStateChange.js.map +0 -1
- package/modules/react/useOnItemStateChange.js.map +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import fillArray from './utility/fillArray.js'
|
|
1
2
|
import log, { warn, isDebug, reportError } from './utility/debug.js'
|
|
2
3
|
import { cleanUpBeforeResizeState } from './BeforeResize.js'
|
|
3
4
|
import getStateSnapshot from './utility/getStateSnapshot.js'
|
|
@@ -25,7 +26,8 @@ import getStateSnapshot from './utility/getStateSnapshot.js'
|
|
|
25
26
|
// then the state update of the window resize handler gets overwritten.
|
|
26
27
|
|
|
27
28
|
export default function createStateHelpers({
|
|
28
|
-
state,
|
|
29
|
+
state: initialState,
|
|
30
|
+
getInitialItemState,
|
|
29
31
|
onStateChange,
|
|
30
32
|
render,
|
|
31
33
|
items: initialItems
|
|
@@ -33,7 +35,9 @@ export default function createStateHelpers({
|
|
|
33
35
|
this.onStateChange = onStateChange
|
|
34
36
|
this._render = render
|
|
35
37
|
|
|
36
|
-
this.
|
|
38
|
+
this.getInitialItemState = getInitialItemState
|
|
39
|
+
|
|
40
|
+
this._setItemState = (i, newItemState) => {
|
|
37
41
|
if (isDebug()) {
|
|
38
42
|
log('~ Item state changed ~')
|
|
39
43
|
log('Item', i)
|
|
@@ -80,10 +84,10 @@ export default function createStateHelpers({
|
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
this.getInitialState = () => {
|
|
83
|
-
if (
|
|
84
|
-
return getRestoredState.call(this,
|
|
87
|
+
if (initialState) {
|
|
88
|
+
return getRestoredState.call(this, initialState)
|
|
85
89
|
}
|
|
86
|
-
return getInitialStateFromScratch.call(this)
|
|
90
|
+
return getInitialStateFromScratch.call(this, { getInitialItemState })
|
|
87
91
|
}
|
|
88
92
|
|
|
89
93
|
this.useState = ({
|
|
@@ -156,20 +160,24 @@ export default function createStateHelpers({
|
|
|
156
160
|
/**
|
|
157
161
|
* Returns the initial state of the `VirtualScroller` "from scratch".
|
|
158
162
|
* (i.e. not from a previously saved one).
|
|
163
|
+
* @param {function} [options.getInitialItemState] — Gets initial item state.
|
|
159
164
|
* @return {object}
|
|
160
165
|
*/
|
|
161
|
-
function getInitialStateFromScratch() {
|
|
166
|
+
function getInitialStateFromScratch({ getInitialItemState }) {
|
|
162
167
|
const items = initialItems
|
|
168
|
+
|
|
163
169
|
const state = {
|
|
164
170
|
...getInitialLayoutState.call(this, items, { beforeStart: true }),
|
|
165
171
|
items,
|
|
166
|
-
itemStates: new Array(items.length)
|
|
172
|
+
itemStates: fillArray(new Array(items.length), (i) => getInitialItemState(items[i]))
|
|
167
173
|
}
|
|
174
|
+
|
|
168
175
|
if (isDebug()) {
|
|
169
176
|
log('Initial state (autogenerated)', getStateSnapshot(state))
|
|
170
177
|
}
|
|
171
178
|
log('First shown item index', state.firstShownItemIndex)
|
|
172
179
|
log('Last shown item index', state.lastShownItemIndex)
|
|
180
|
+
|
|
173
181
|
return state
|
|
174
182
|
}
|
|
175
183
|
|
|
@@ -6,7 +6,7 @@ import useVirtualScroller from './useVirtualScroller.js'
|
|
|
6
6
|
import useVirtualScrollerStartStop from './useVirtualScrollerStartStop.js'
|
|
7
7
|
import useInstanceMethods from './useInstanceMethods.js'
|
|
8
8
|
import useItemKeys from './useItemKeys.js'
|
|
9
|
-
import
|
|
9
|
+
import useSetItemState from './useSetItemState.js'
|
|
10
10
|
import useOnItemHeightChange from './useOnItemHeightChange.js'
|
|
11
11
|
import useHandleItemsChange from './useHandleItemsChange.js'
|
|
12
12
|
import useClassName from './useClassName.js'
|
|
@@ -44,6 +44,7 @@ function VirtualScroller({
|
|
|
44
44
|
onScrollPositionChange,
|
|
45
45
|
onStateChange,
|
|
46
46
|
initialState,
|
|
47
|
+
getInitialItemState,
|
|
47
48
|
...rest
|
|
48
49
|
}, ref) {
|
|
49
50
|
// List items "container" DOM Element reference.
|
|
@@ -74,6 +75,7 @@ function VirtualScroller({
|
|
|
74
75
|
getItemId,
|
|
75
76
|
AsComponent,
|
|
76
77
|
initialState,
|
|
78
|
+
getInitialItemState,
|
|
77
79
|
onStateChange
|
|
78
80
|
}, {
|
|
79
81
|
container
|
|
@@ -116,9 +118,9 @@ function VirtualScroller({
|
|
|
116
118
|
getItemId
|
|
117
119
|
})
|
|
118
120
|
|
|
119
|
-
// Cache per-item `
|
|
121
|
+
// Cache per-item `setItemState` functions' "references"
|
|
120
122
|
// so that item components don't get re-rendered needlessly.
|
|
121
|
-
const
|
|
123
|
+
const getSetItemState = useSetItemState({
|
|
122
124
|
items,
|
|
123
125
|
virtualScroller
|
|
124
126
|
})
|
|
@@ -193,10 +195,21 @@ function VirtualScroller({
|
|
|
193
195
|
style={style}>
|
|
194
196
|
{renderedItems.map((item, i) => {
|
|
195
197
|
if (i >= firstShownItemIndex && i <= lastShownItemIndex) {
|
|
196
|
-
// Passing `item` as `children` property is legacy and is deprecated.
|
|
197
|
-
//
|
|
198
|
-
//
|
|
199
|
-
//
|
|
198
|
+
// * Passing `item` as `children` property is legacy and is deprecated.
|
|
199
|
+
// If version `2.x` is published in some hypothetical future,
|
|
200
|
+
// the `item` and `itemIndex` properties should be moved below
|
|
201
|
+
// `{...itemComponentProps}`.
|
|
202
|
+
//
|
|
203
|
+
// * Passing `itemIndex` property is legacy and is deprecated.
|
|
204
|
+
// The rationale is that setting new `items` on a React component
|
|
205
|
+
// is an asynchronous operation, so when a user obtains `itemIndex`,
|
|
206
|
+
// they don't know which `items` list does that index correspond to,
|
|
207
|
+
// therefore making it useless, or even buggy if used incorreclty.
|
|
208
|
+
//
|
|
209
|
+
// * Passing `onStateChange` property for legacy reasons.
|
|
210
|
+
// The new property name is `setState`.
|
|
211
|
+
// The old property name `onStateChange` is deprecated.
|
|
212
|
+
//
|
|
200
213
|
return (
|
|
201
214
|
<Component
|
|
202
215
|
item={item}
|
|
@@ -204,7 +217,8 @@ function VirtualScroller({
|
|
|
204
217
|
{...itemComponentProps}
|
|
205
218
|
key={getItemKey(item, i)}
|
|
206
219
|
state={itemStates && itemStates[i]}
|
|
207
|
-
|
|
220
|
+
setState={getSetItemState(i)}
|
|
221
|
+
onStateChange={getSetItemState(i)}
|
|
208
222
|
onHeightChange={getOnItemHeightChange(i)}>
|
|
209
223
|
{item}
|
|
210
224
|
</Component>
|
|
@@ -262,7 +276,7 @@ VirtualScroller.propTypes = {
|
|
|
262
276
|
onStateChange: PropTypes.func,
|
|
263
277
|
initialState: PropTypes.shape({
|
|
264
278
|
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
265
|
-
itemStates: PropTypes.arrayOf(PropTypes.any),
|
|
279
|
+
itemStates: PropTypes.arrayOf(PropTypes.any).isRequired,
|
|
266
280
|
firstShownItemIndex: PropTypes.number.isRequired,
|
|
267
281
|
lastShownItemIndex: PropTypes.number.isRequired,
|
|
268
282
|
beforeItemsHeight: PropTypes.number.isRequired,
|
|
@@ -270,7 +284,8 @@ VirtualScroller.propTypes = {
|
|
|
270
284
|
itemHeights: PropTypes.arrayOf(PropTypes.number).isRequired,
|
|
271
285
|
columnsCount: PropTypes.number,
|
|
272
286
|
verticalSpacing: PropTypes.number
|
|
273
|
-
})
|
|
287
|
+
}),
|
|
288
|
+
getInitialItemState: PropTypes.func
|
|
274
289
|
}
|
|
275
290
|
|
|
276
291
|
VirtualScroller.defaultProps = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useMemo, useRef, useCallback } from 'react'
|
|
2
2
|
|
|
3
|
-
export default function
|
|
3
|
+
export default function useSetItemState({
|
|
4
4
|
items,
|
|
5
5
|
virtualScroller
|
|
6
6
|
}) {
|
|
@@ -12,11 +12,11 @@ export default function useOnItemStateChange({
|
|
|
12
12
|
// Handler functions cache.
|
|
13
13
|
const cache = useRef(initialCacheValue)
|
|
14
14
|
|
|
15
|
-
// Caches per-item `
|
|
15
|
+
// Caches per-item `setItemState` functions' "references"
|
|
16
16
|
// so that item components don't get re-rendered needlessly.
|
|
17
|
-
const
|
|
17
|
+
const getSetItemState = useCallback((i) => {
|
|
18
18
|
if (!cache.current[i]) {
|
|
19
|
-
cache.current[i] = (itemState) => virtualScroller.
|
|
19
|
+
cache.current[i] = (itemState) => virtualScroller.setItemState(i, itemState)
|
|
20
20
|
}
|
|
21
21
|
return cache.current[i]
|
|
22
22
|
}, [
|
|
@@ -24,5 +24,5 @@ export default function useOnItemStateChange({
|
|
|
24
24
|
cache
|
|
25
25
|
])
|
|
26
26
|
|
|
27
|
-
return
|
|
27
|
+
return getSetItemState
|
|
28
28
|
}
|
|
@@ -26,6 +26,7 @@ export default function useVirtualScroller({
|
|
|
26
26
|
getItemId,
|
|
27
27
|
AsComponent,
|
|
28
28
|
initialState,
|
|
29
|
+
getInitialItemState,
|
|
29
30
|
onStateChange
|
|
30
31
|
}, {
|
|
31
32
|
container
|
|
@@ -58,6 +59,7 @@ export default function useVirtualScroller({
|
|
|
58
59
|
getItemId,
|
|
59
60
|
tbody: AsComponent === 'tbody',
|
|
60
61
|
state: initialState,
|
|
62
|
+
getInitialItemState,
|
|
61
63
|
onStateChange
|
|
62
64
|
}
|
|
63
65
|
)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useOnItemStateChange.js","names":["useOnItemStateChange","items","virtualScroller","initialCacheValue","useMemo","Array","length","cache","useRef","getOnItemStateChange","useCallback","i","current","itemState","onItemStateChange"],"sources":["../../source/react/useOnItemStateChange.js"],"sourcesContent":["import { useMemo, useRef, useCallback } from 'react'\r\n\r\nexport default function useOnItemStateChange({\r\n\titems,\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(items.length)\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 `onItemStateChange` functions' \"references\"\r\n\t// so that item components don't get re-rendered needlessly.\r\n\tconst getOnItemStateChange = useCallback((i) => {\r\n\t\tif (!cache.current[i]) {\r\n\t\t\tcache.current[i] = (itemState) => virtualScroller.onItemStateChange(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 getOnItemStateChange\r\n}"],"mappings":";;;;;;;AAAA;;AAEe,SAASA,oBAAT,OAGZ;EAAA,IAFFC,KAEE,QAFFA,KAEE;EAAA,IADFC,eACE,QADFA,eACE;EACF;EACA,IAAMC,iBAAiB,GAAG,IAAAC,cAAA,EAAQ,YAAM;IACvC,OAAO,IAAIC,KAAJ,CAAUJ,KAAK,CAACK,MAAhB,CAAP;EACA,CAFyB,EAEvB,EAFuB,CAA1B,CAFE,CAMF;;EACA,IAAMC,KAAK,GAAG,IAAAC,aAAA,EAAOL,iBAAP,CAAd,CAPE,CASF;EACA;;EACA,IAAMM,oBAAoB,GAAG,IAAAC,kBAAA,EAAY,UAACC,CAAD,EAAO;IAC/C,IAAI,CAACJ,KAAK,CAACK,OAAN,CAAcD,CAAd,CAAL,EAAuB;MACtBJ,KAAK,CAACK,OAAN,CAAcD,CAAd,IAAmB,UAACE,SAAD;QAAA,OAAeX,eAAe,CAACY,iBAAhB,CAAkCH,CAAlC,EAAqCE,SAArC,CAAf;MAAA,CAAnB;IACA;;IACD,OAAON,KAAK,CAACK,OAAN,CAAcD,CAAd,CAAP;EACA,CAL4B,EAK1B,CACFT,eADE,EAEFK,KAFE,CAL0B,CAA7B;EAUA,OAAOE,oBAAP;AACA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useOnItemStateChange.js","names":["useMemo","useRef","useCallback","useOnItemStateChange","items","virtualScroller","initialCacheValue","Array","length","cache","getOnItemStateChange","i","current","itemState","onItemStateChange"],"sources":["../../source/react/useOnItemStateChange.js"],"sourcesContent":["import { useMemo, useRef, useCallback } from 'react'\r\n\r\nexport default function useOnItemStateChange({\r\n\titems,\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(items.length)\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 `onItemStateChange` functions' \"references\"\r\n\t// so that item components don't get re-rendered needlessly.\r\n\tconst getOnItemStateChange = useCallback((i) => {\r\n\t\tif (!cache.current[i]) {\r\n\t\t\tcache.current[i] = (itemState) => virtualScroller.onItemStateChange(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 getOnItemStateChange\r\n}"],"mappings":"AAAA,SAASA,OAAT,EAAkBC,MAAlB,EAA0BC,WAA1B,QAA6C,OAA7C;AAEA,eAAe,SAASC,oBAAT,OAGZ;EAAA,IAFFC,KAEE,QAFFA,KAEE;EAAA,IADFC,eACE,QADFA,eACE;EACF;EACA,IAAMC,iBAAiB,GAAGN,OAAO,CAAC,YAAM;IACvC,OAAO,IAAIO,KAAJ,CAAUH,KAAK,CAACI,MAAhB,CAAP;EACA,CAFgC,EAE9B,EAF8B,CAAjC,CAFE,CAMF;;EACA,IAAMC,KAAK,GAAGR,MAAM,CAACK,iBAAD,CAApB,CAPE,CASF;EACA;;EACA,IAAMI,oBAAoB,GAAGR,WAAW,CAAC,UAACS,CAAD,EAAO;IAC/C,IAAI,CAACF,KAAK,CAACG,OAAN,CAAcD,CAAd,CAAL,EAAuB;MACtBF,KAAK,CAACG,OAAN,CAAcD,CAAd,IAAmB,UAACE,SAAD;QAAA,OAAeR,eAAe,CAACS,iBAAhB,CAAkCH,CAAlC,EAAqCE,SAArC,CAAf;MAAA,CAAnB;IACA;;IACD,OAAOJ,KAAK,CAACG,OAAN,CAAcD,CAAd,CAAP;EACA,CALuC,EAKrC,CACFN,eADE,EAEFI,KAFE,CALqC,CAAxC;EAUA,OAAOC,oBAAP;AACA"}
|