BucketsTable.LoadMoreRow.tsx 1.4 KB

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