BucketsTable.LoadMoreRow.tsx47 lines · main
1import { useIntersectionObserver } from '@uidotdev/usehooks'
2import { useEffect, type ReactNode } from 'react'
3import { TableCell, TableRow } from 'ui'
4import { ShimmeringLoader } from 'ui-patterns'
5
6import type { BucketsTablePaginationProps } from './BucketsTable.types'
7import { VirtualizedTableCell, VirtualizedTableRow } from '@/components/ui/VirtualizedTable'
8
9type LoadMoreRowProps = {
10 mode: 'standard' | 'virtualized'
11 colSpan: number
12} & BucketsTablePaginationProps
13
14export const LoadMoreRow = ({
15 mode,
16 colSpan,
17
18 hasMore = false,
19 isLoadingMore = false,
20 onLoadMore,
21}: LoadMoreRowProps): ReactNode => {
22 const [sentinelRef, entry] = useIntersectionObserver({
23 threshold: 0,
24 rootMargin: '200px 0px 200px 0px',
25 })
26
27 useEffect(() => {
28 if (entry?.isIntersecting && hasMore && !isLoadingMore) {
29 onLoadMore?.()
30 }
31 }, [entry?.isIntersecting, hasMore, isLoadingMore, onLoadMore])
32
33 if (!hasMore && !isLoadingMore) return null
34
35 const RowComponent = mode === 'standard' ? TableRow : VirtualizedTableRow
36 const CellComponent = mode === 'standard' ? TableCell : VirtualizedTableCell
37
38 return (
39 <RowComponent ref={sentinelRef}>
40 {Array.from({ length: colSpan }, (_, idx) => (
41 <CellComponent key={idx}>
42 {idx !== 0 && idx !== colSpan - 1 && <ShimmeringLoader className="w-3/4" />}
43 </CellComponent>
44 ))}
45 </RowComponent>
46 )
47}