@@ -10,6 +10,7 @@ import tableStyles from '~/components/table/table.module.css';
1010import { Badge } from '../../badge' ;
1111import { EmptyState } from '../../empty-state' ;
1212import { Flex } from '../../flex' ;
13+ import { Skeleton } from '../../skeleton' ;
1314import styles from '../data-table.module.css' ;
1415import {
1516 DataTableColumnDef ,
@@ -154,6 +155,47 @@ function VirtualRows<TData>({
154155 } ) ;
155156}
156157
158+ function VirtualLoaderRows < TData > ( {
159+ rowCount,
160+ columns,
161+ rowHeight,
162+ startTop
163+ } : {
164+ rowCount : number ;
165+ columns : DataTableColumnDef < TData , unknown > [ ] ;
166+ rowHeight : number ;
167+ startTop : number ;
168+ } ) {
169+ const rows = Array . from ( { length : rowCount } ) ;
170+
171+ return rows . map ( ( _ , rowIndex ) => (
172+ < div
173+ role = 'row'
174+ key = { 'loading-row-' + rowIndex }
175+ className = { cx ( styles . virtualRow , styles [ 'row' ] ) }
176+ style = { {
177+ height : rowHeight ,
178+ top : startTop + rowIndex * rowHeight
179+ } }
180+ >
181+ { columns . map ( ( col , colIndex ) => (
182+ < div
183+ role = 'cell'
184+ key = { 'loading-column-' + colIndex }
185+ className = { cx (
186+ tableStyles . cell ,
187+ styles . virtualCell ,
188+ col . classNames ?. cell
189+ ) }
190+ style = { col . styles ?. cell }
191+ >
192+ < Skeleton containerClassName = { styles [ 'flex-1' ] } />
193+ </ div >
194+ ) ) }
195+ </ div >
196+ ) ) ;
197+ }
198+
157199const DefaultEmptyComponent = ( ) => (
158200 < EmptyState icon = { < TableIcon /> } heading = 'No Data' />
159201) ;
@@ -167,8 +209,14 @@ export function VirtualizedContent({
167209 zeroState,
168210 classNames = { }
169211} : VirtualizedContentProps ) {
170- const { onRowClick, table, isLoading, loadMoreData, tableQuery } =
171- useDataTable ( ) ;
212+ const {
213+ onRowClick,
214+ table,
215+ isLoading,
216+ loadMoreData,
217+ tableQuery,
218+ loadingRowCount = 3
219+ } = useDataTable ( ) ;
172220
173221 const headerGroups = table ?. getHeaderGroups ( ) ;
174222 const rowModel = table ?. getRowModel ( ) ;
@@ -215,6 +263,12 @@ export function VirtualizedContent({
215263 return < div className = { classNames . root } > { stateToShow } </ div > ;
216264 }
217265
266+ const showLoaderRows = isLoading && rows . length > 0 ;
267+ const loaderRowsHeight = showLoaderRows ? loadingRowCount * rowHeight : 0 ;
268+ const virtualTotalSize = virtualizer . getTotalSize ( ) ;
269+ const totalHeight = virtualTotalSize + loaderRowsHeight ;
270+ const visibleColumns = table . getVisibleLeafColumns ( ) ;
271+
218272 return (
219273 < div
220274 ref = { scrollContainerRef }
@@ -229,7 +283,7 @@ export function VirtualizedContent({
229283 < div
230284 role = 'rowgroup'
231285 className = { cx ( styles . virtualBodyGroup , classNames . body ) }
232- style = { { height : virtualizer . getTotalSize ( ) } }
286+ style = { { height : totalHeight } }
233287 >
234288 < VirtualRows
235289 rows = { rows }
@@ -239,6 +293,16 @@ export function VirtualizedContent({
239293 row : classNames . row
240294 } }
241295 />
296+ { showLoaderRows && (
297+ < VirtualLoaderRows
298+ rowCount = { loadingRowCount }
299+ columns = { visibleColumns . map (
300+ col => col . columnDef as DataTableColumnDef < unknown , unknown >
301+ ) }
302+ rowHeight = { rowHeight }
303+ startTop = { virtualTotalSize }
304+ />
305+ ) }
242306 </ div >
243307 </ div >
244308 </ div >
0 commit comments