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.
Files changed (69) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +48 -24
  3. package/bundle/virtual-scroller-dom.js +1 -1
  4. package/bundle/virtual-scroller-dom.js.map +1 -1
  5. package/bundle/virtual-scroller-react.js +1 -1
  6. package/bundle/virtual-scroller-react.js.map +1 -1
  7. package/bundle/virtual-scroller.js +1 -1
  8. package/bundle/virtual-scroller.js.map +1 -1
  9. package/commonjs/DOM/VirtualScroller.js +5 -0
  10. package/commonjs/DOM/VirtualScroller.js.map +1 -1
  11. package/commonjs/ItemHeights.js +1 -1
  12. package/commonjs/ItemHeights.js.map +1 -1
  13. package/commonjs/VirtualScroller.constructor.js +3 -0
  14. package/commonjs/VirtualScroller.constructor.js.map +1 -1
  15. package/commonjs/VirtualScroller.items.js +11 -10
  16. package/commonjs/VirtualScroller.items.js.map +1 -1
  17. package/commonjs/VirtualScroller.js +10 -3
  18. package/commonjs/VirtualScroller.js.map +1 -1
  19. package/commonjs/VirtualScroller.layout.js +2 -2
  20. package/commonjs/VirtualScroller.layout.js.map +1 -1
  21. package/commonjs/VirtualScroller.state.js +23 -13
  22. package/commonjs/VirtualScroller.state.js.map +1 -1
  23. package/commonjs/react/VirtualScroller.js +26 -11
  24. package/commonjs/react/VirtualScroller.js.map +1 -1
  25. package/commonjs/react/{useOnItemStateChange.js → useSetItemState.js} +7 -7
  26. package/commonjs/react/useSetItemState.js.map +1 -0
  27. package/commonjs/react/useVirtualScroller.js +2 -1
  28. package/commonjs/react/useVirtualScroller.js.map +1 -1
  29. package/commonjs/utility/fillArray.js +18 -0
  30. package/commonjs/utility/fillArray.js.map +1 -0
  31. package/dom/index.d.ts +7 -6
  32. package/index.d.ts +16 -15
  33. package/modules/DOM/VirtualScroller.js +5 -0
  34. package/modules/DOM/VirtualScroller.js.map +1 -1
  35. package/modules/ItemHeights.js +1 -1
  36. package/modules/ItemHeights.js.map +1 -1
  37. package/modules/VirtualScroller.constructor.js +3 -0
  38. package/modules/VirtualScroller.constructor.js.map +1 -1
  39. package/modules/VirtualScroller.items.js +10 -10
  40. package/modules/VirtualScroller.items.js.map +1 -1
  41. package/modules/VirtualScroller.js +10 -3
  42. package/modules/VirtualScroller.js.map +1 -1
  43. package/modules/VirtualScroller.layout.js +2 -2
  44. package/modules/VirtualScroller.layout.js.map +1 -1
  45. package/modules/VirtualScroller.state.js +20 -11
  46. package/modules/VirtualScroller.state.js.map +1 -1
  47. package/modules/react/VirtualScroller.js +26 -11
  48. package/modules/react/VirtualScroller.js.map +1 -1
  49. package/modules/react/{useOnItemStateChange.js → useSetItemState.js} +6 -6
  50. package/modules/react/useSetItemState.js.map +1 -0
  51. package/modules/react/useVirtualScroller.js +2 -1
  52. package/modules/react/useVirtualScroller.js.map +1 -1
  53. package/modules/utility/fillArray.js +11 -0
  54. package/modules/utility/fillArray.js.map +1 -0
  55. package/package.json +1 -1
  56. package/react/index.d.ts +14 -8
  57. package/source/DOM/VirtualScroller.js +4 -0
  58. package/source/ItemHeights.js +1 -1
  59. package/source/VirtualScroller.constructor.js +2 -1
  60. package/source/VirtualScroller.items.js +16 -8
  61. package/source/VirtualScroller.js +8 -2
  62. package/source/VirtualScroller.layout.js +2 -2
  63. package/source/VirtualScroller.state.js +15 -7
  64. package/source/react/VirtualScroller.js +25 -10
  65. package/source/react/{useOnItemStateChange.js → useSetItemState.js} +5 -5
  66. package/source/react/useVirtualScroller.js +2 -0
  67. package/source/utility/fillArray.js +8 -0
  68. package/commonjs/react/useOnItemStateChange.js.map +0 -1
  69. 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._onItemStateChange = (i, newItemState) => {
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 (state) {
84
- return getRestoredState.call(this, state)
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 useOnItemStateChange from './useOnItemStateChange.js'
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 `onItemStateChange` functions' "references"
121
+ // Cache per-item `setItemState` functions' "references"
120
122
  // so that item components don't get re-rendered needlessly.
121
- const getOnItemStateChange = useOnItemStateChange({
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
- // If version `2.x` is published in some hypothetical future,
198
- // the `item` and `itemIndex` properties should be moved below
199
- // `{...itemComponentProps}`.
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
- onStateChange={getOnItemStateChange(i)}
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 useOnItemStateChange({
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 `onItemStateChange` functions' "references"
15
+ // Caches per-item `setItemState` functions' "references"
16
16
  // so that item components don't get re-rendered needlessly.
17
- const getOnItemStateChange = useCallback((i) => {
17
+ const getSetItemState = useCallback((i) => {
18
18
  if (!cache.current[i]) {
19
- cache.current[i] = (itemState) => virtualScroller.onItemStateChange(i, itemState)
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 getOnItemStateChange
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
  )
@@ -0,0 +1,8 @@
1
+ export default function fillArray(array, getItem) {
2
+ let i = 0
3
+ while (i < array.length) {
4
+ array[i] = getItem(i)
5
+ i++
6
+ }
7
+ return array
8
+ }
@@ -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"}