11import React from 'react' ;
22
3- import { throttle } from 'lodash' ;
4-
5- import { getArray } from '../../utils' ;
3+ import { isEqual , throttle } from 'lodash' ;
64
75interface UseScrollBasedChunksProps {
8- containerRef : React . RefObject < HTMLElement > ;
6+ parentRef ?: React . RefObject < HTMLElement > ;
7+ tableRef : React . RefObject < HTMLElement > ;
98 totalItems : number ;
10- itemHeight : number ;
9+ rowHeight : number ;
1110 chunkSize : number ;
1211}
1312
1413const THROTTLE_DELAY = 100 ;
1514const CHUNKS_AHEAD_COUNT = 1 ;
1615
1716export const useScrollBasedChunks = ( {
18- containerRef,
17+ parentRef,
18+ tableRef,
1919 totalItems,
20- itemHeight ,
20+ rowHeight ,
2121 chunkSize,
22- } : UseScrollBasedChunksProps ) : number [ ] => {
23- const [ activeChunks , setActiveChunks ] = React . useState < number [ ] > (
24- getArray ( 1 + CHUNKS_AHEAD_COUNT ) . map ( ( index ) => index ) ,
25- ) ;
22+ } : UseScrollBasedChunksProps ) : boolean [ ] => {
23+ const [ activeChunks , setActiveChunks ] = React . useState < boolean [ ] > ( [ true , true ] ) ;
2624
2725 const calculateActiveChunks = React . useCallback ( ( ) => {
28- const container = containerRef . current ;
29- if ( ! container ) {
26+ const container = parentRef ?. current ;
27+ const table = tableRef . current ;
28+ if ( ! container || ! table ) {
3029 return ;
3130 }
3231
33- const { scrollTop , clientHeight } = container ;
34- const visibleStartIndex = Math . floor ( scrollTop / itemHeight ) ;
32+ const tableScrollTop = Math . max ( container . scrollTop - table . offsetTop , 0 ) ;
33+ const visibleStartIndex = Math . floor ( Math . max ( tableScrollTop , 0 ) / rowHeight ) ;
3534 const visibleEndIndex = Math . min (
36- Math . ceil ( ( scrollTop + clientHeight ) / itemHeight ) ,
35+ Math . ceil ( ( tableScrollTop + container . clientHeight ) / rowHeight ) ,
3736 totalItems - 1 ,
3837 ) ;
3938
40- const startChunk = Math . floor ( visibleStartIndex / chunkSize ) ;
41- const endChunk = Math . floor ( visibleEndIndex / chunkSize ) ;
42-
43- const newActiveChunks = getArray ( endChunk - startChunk + 1 + CHUNKS_AHEAD_COUNT ) . map (
44- ( index ) => startChunk + index ,
39+ const startChunk = Math . max (
40+ Math . floor ( visibleStartIndex / chunkSize ) - CHUNKS_AHEAD_COUNT ,
41+ 0 ,
4542 ) ;
43+ const endChunk = Math . floor ( visibleEndIndex / chunkSize ) + CHUNKS_AHEAD_COUNT ;
4644
47- setActiveChunks ( newActiveChunks ) ;
48- } , [ chunkSize , containerRef , itemHeight , totalItems ] ) ;
45+ const newActiveChunks = [ ] ;
46+ for ( let i = startChunk ; i <= endChunk ; i ++ ) {
47+ newActiveChunks [ i ] = true ;
48+ }
49+
50+ if ( ! isEqual ( activeChunks , newActiveChunks ) ) {
51+ setActiveChunks ( newActiveChunks ) ;
52+ }
53+ } , [ parentRef , tableRef , rowHeight , totalItems , chunkSize , activeChunks ] ) ;
4954
5055 const throttledCalculateActiveChunks = React . useMemo (
5156 ( ) => throttle ( calculateActiveChunks , THROTTLE_DELAY ) ,
5257 [ calculateActiveChunks ] ,
5358 ) ;
5459
5560 React . useEffect ( ( ) => {
56- const container = containerRef . current ;
61+ const container = parentRef ? .current ;
5762 if ( ! container ) {
5863 return undefined ;
5964 }
@@ -63,7 +68,7 @@ export const useScrollBasedChunks = ({
6368 container . removeEventListener ( 'scroll' , throttledCalculateActiveChunks ) ;
6469 throttledCalculateActiveChunks . cancel ( ) ;
6570 } ;
66- } , [ containerRef , throttledCalculateActiveChunks ] ) ;
71+ } , [ parentRef , throttledCalculateActiveChunks ] ) ;
6772
6873 return activeChunks ;
6974} ;
0 commit comments