1
1
import React from 'react' ;
2
2
3
3
import { usePaginatedTableState } from './PaginatedTableContext' ;
4
- import { TableChunk } from './TableChunk ' ;
4
+ import { TableChunksRenderer } from './TableChunksRenderer ' ;
5
5
import { TableHead } from './TableHead' ;
6
6
import { DEFAULT_TABLE_ROW_HEIGHT } from './constants' ;
7
7
import { b } from './shared' ;
@@ -14,7 +14,7 @@ import type {
14
14
RenderEmptyDataMessage ,
15
15
RenderErrorMessage ,
16
16
} from './types' ;
17
- import { useScrollBasedChunks } from './useScrollBasedChunks ' ;
17
+ import { calculateElementOffsetTop } from './utils ' ;
18
18
19
19
import './PaginatedTable.scss' ;
20
20
@@ -62,14 +62,7 @@ export const PaginatedTable = <T, F>({
62
62
const { sortParams, foundEntities} = tableState ;
63
63
64
64
const tableRef = React . useRef < HTMLDivElement > ( null ) ;
65
-
66
- const activeChunks = useScrollBasedChunks ( {
67
- scrollContainerRef,
68
- tableRef,
69
- totalItems : foundEntities ,
70
- rowHeight,
71
- chunkSize,
72
- } ) ;
65
+ const [ tableOffset , setTableOffset ] = React . useState ( 0 ) ;
73
66
74
67
// this prevent situation when filters are new, but active chunks is not yet recalculated (it will be done to the next rendrer, so we bring filters change on the next render too)
75
68
const [ filters , setFilters ] = React . useState ( rawFilters ) ;
@@ -78,15 +71,6 @@ export const PaginatedTable = <T, F>({
78
71
setFilters ( rawFilters ) ;
79
72
} , [ rawFilters ] ) ;
80
73
81
- const lastChunkSize = React . useMemo ( ( ) => {
82
- // If foundEntities = 0, there will only first chunk
83
- // Display it with 1 row, to display empty data message
84
- if ( ! foundEntities ) {
85
- return 1 ;
86
- }
87
- return foundEntities % chunkSize || chunkSize ;
88
- } , [ foundEntities , chunkSize ] ) ;
89
-
90
74
const handleDataFetched = React . useCallback (
91
75
( data ?: PaginatedTableData < T > ) => {
92
76
if ( data ) {
@@ -99,6 +83,25 @@ export const PaginatedTable = <T, F>({
99
83
[ onDataFetched , setFoundEntities , setIsInitialLoad , setTotalEntities ] ,
100
84
) ;
101
85
86
+ React . useLayoutEffect ( ( ) => {
87
+ const scrollContainer = scrollContainerRef . current ;
88
+ const table = tableRef . current ;
89
+ if ( table && scrollContainer ) {
90
+ setTableOffset ( calculateElementOffsetTop ( table , scrollContainer ) ) ;
91
+ }
92
+ } , [ scrollContainerRef . current , tableRef . current , foundEntities ] ) ;
93
+
94
+ // Set will-change: transform on scroll container if not already set
95
+ React . useLayoutEffect ( ( ) => {
96
+ const scrollContainer = scrollContainerRef . current ;
97
+ if ( scrollContainer ) {
98
+ const computedStyle = window . getComputedStyle ( scrollContainer ) ;
99
+ if ( computedStyle . willChange !== 'transform' ) {
100
+ scrollContainer . style . willChange = 'transform' ;
101
+ }
102
+ }
103
+ } , [ scrollContainerRef . current ] ) ;
104
+
102
105
// Reset table on initialization and filters change
103
106
React . useLayoutEffect ( ( ) => {
104
107
const defaultTotal = initialEntitiesCount || 0 ;
@@ -109,33 +112,29 @@ export const PaginatedTable = <T, F>({
109
112
setIsInitialLoad ( true ) ;
110
113
} , [ initialEntitiesCount , setTotalEntities , setFoundEntities , setIsInitialLoad ] ) ;
111
114
112
- const renderChunks = ( ) => {
113
- return activeChunks . map ( ( isActive , index ) => (
114
- < TableChunk < T , F >
115
- key = { index }
116
- id = { index }
117
- calculatedCount = { index === activeChunks . length - 1 ? lastChunkSize : chunkSize }
118
- chunkSize = { chunkSize }
119
- rowHeight = { rowHeight }
120
- columns = { columns }
121
- fetchData = { fetchData }
122
- filters = { filters }
123
- tableName = { tableName }
124
- sortParams = { sortParams }
125
- getRowClassName = { getRowClassName }
126
- renderErrorMessage = { renderErrorMessage }
127
- renderEmptyDataMessage = { renderEmptyDataMessage }
128
- onDataFetched = { handleDataFetched }
129
- isActive = { isActive }
130
- keepCache = { keepCache }
131
- />
132
- ) ) ;
133
- } ;
134
-
135
115
const renderTable = ( ) => (
136
116
< table className = { b ( 'table' ) } >
137
117
< TableHead columns = { columns } onSort = { setSortParams } onColumnsResize = { onColumnsResize } />
138
- { renderChunks ( ) }
118
+ < tbody >
119
+ < TableChunksRenderer
120
+ scrollContainerRef = { scrollContainerRef }
121
+ tableRef = { tableRef }
122
+ foundEntities = { foundEntities }
123
+ tableOffset = { tableOffset }
124
+ chunkSize = { chunkSize }
125
+ rowHeight = { rowHeight }
126
+ columns = { columns }
127
+ fetchData = { fetchData }
128
+ filters = { filters }
129
+ tableName = { tableName }
130
+ sortParams = { sortParams }
131
+ getRowClassName = { getRowClassName }
132
+ renderErrorMessage = { renderErrorMessage }
133
+ renderEmptyDataMessage = { renderEmptyDataMessage }
134
+ onDataFetched = { handleDataFetched }
135
+ keepCache = { keepCache }
136
+ />
137
+ </ tbody >
139
138
</ table >
140
139
) ;
141
140
0 commit comments