Skip to content

Commit e81aa39

Browse files
authored
fix: add loader rows in virtualized datatable (#580)
* fix: add loader rows in virtualized datatable * chore: resolve pr comments
1 parent c48e9dc commit e81aa39

File tree

2 files changed

+68
-3
lines changed

2 files changed

+68
-3
lines changed

packages/raystack/components/data-table/components/virtualized-content.tsx

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import tableStyles from '~/components/table/table.module.css';
1010
import { Badge } from '../../badge';
1111
import { EmptyState } from '../../empty-state';
1212
import { Flex } from '../../flex';
13+
import { Skeleton } from '../../skeleton';
1314
import styles from '../data-table.module.css';
1415
import {
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+
157199
const 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>

packages/raystack/components/data-table/data-table.module.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
overflow-x: auto;
8383
position: relative;
8484
height: 100%;
85+
overscroll-behavior: auto;
8586
}
8687

8788
.stickyHeader {

0 commit comments

Comments
 (0)