LoadMoreRow.tsx60 lines · main
1import { useIntersectionObserver } from '@uidotdev/usehooks'
2import { useEffect } from 'react'
3import { cn, Skeleton, TableCell, TableRow } from 'ui'
4
5import { ShimmeringCard } from './ShimmeringCard'
6
7interface LoadMoreRowProps {
8 type?: 'card' | 'table'
9 isFetchingNextPage: boolean
10 fetchNextPage: () => void
11}
12
13export const LoadMoreRows = ({ type, isFetchingNextPage, fetchNextPage }: LoadMoreRowProps) => {
14 const [sentinelRef, entry] = useIntersectionObserver({
15 threshold: 0,
16 rootMargin: '200px 0px 200px 0px',
17 })
18
19 useEffect(() => {
20 if (entry?.isIntersecting && !isFetchingNextPage) {
21 fetchNextPage?.()
22 }
23 }, [entry?.isIntersecting, isFetchingNextPage, fetchNextPage])
24
25 if (type === 'card') {
26 return (
27 <ul
28 ref={sentinelRef}
29 className={cn(
30 'grid grid-cols-1 gap-2 md:gap-4',
31 'sm:grid-cols-1 md:grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 pb-6'
32 )}
33 >
34 {[...Array(2)].map((_, i) => (
35 <ShimmeringCard key={i} />
36 ))}
37 </ul>
38 )
39 }
40
41 return (
42 <TableRow ref={sentinelRef}>
43 <TableCell>
44 <Skeleton className="bg-surface-400 h-4 w-32"></Skeleton>
45 </TableCell>
46 <TableCell>
47 <Skeleton className="bg-surface-400 h-4 w-16"></Skeleton>
48 </TableCell>
49 <TableCell>
50 <Skeleton className="bg-surface-400 h-4 w-20"></Skeleton>
51 </TableCell>
52 <TableCell>
53 <Skeleton className="bg-surface-400 h-4 w-20"></Skeleton>
54 </TableCell>
55 <TableCell>
56 <Skeleton className="bg-surface-400 h-4 w-24"></Skeleton>
57 </TableCell>
58 </TableRow>
59 )
60}