Skip to content

Commit 0710095

Browse files
authored
fix: infinite scroll not fetching more when initial fetch does not fill the screen (#19)
1 parent ced2f8e commit 0710095

File tree

1 file changed

+32
-4
lines changed

1 file changed

+32
-4
lines changed

src/components/databrowser/components/sidebar/infinite-scroll.tsx

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { PropsWithChildren } from "react"
22
import { IconLoader2 } from "@tabler/icons-react"
33
import type { UseInfiniteQueryResult } from "@tanstack/react-query"
4+
import { useEffect, useRef } from "react"
45

56
import { ScrollArea } from "@/components/ui/scroll-area"
67

@@ -10,6 +11,10 @@ export const InfiniteScroll = ({
1011
}: PropsWithChildren<{
1112
query: UseInfiniteQueryResult
1213
}>) => {
14+
const scrollRef = useRef<HTMLDivElement>(null)
15+
const contentRef = useRef<HTMLDivElement>(null)
16+
17+
// Fetch more on scroll
1318
const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {
1419
const { scrollTop, clientHeight, scrollHeight } = e.currentTarget
1520
if (scrollTop + clientHeight > scrollHeight - 100) {
@@ -20,17 +25,40 @@ export const InfiniteScroll = ({
2025
}
2126
}
2227

28+
// Check if viewport is filled and fetch more if needed
29+
const checkAndFetchMore = () => {
30+
if (!scrollRef.current || !contentRef.current) return
31+
32+
const viewportHeight = scrollRef.current.clientHeight
33+
const contentHeight = contentRef.current.clientHeight
34+
35+
// Fetch until it overflows a bit
36+
const overflowThreshold = viewportHeight + 100
37+
38+
if (contentHeight < overflowThreshold && query.hasNextPage && !query.isFetching) {
39+
query.fetchNextPage()
40+
}
41+
}
42+
43+
useEffect(() => {
44+
// Timeout for dom update
45+
const timer = setTimeout(checkAndFetchMore, 100)
46+
return () => clearTimeout(timer)
47+
}, [query.data])
48+
2349
return (
2450
<ScrollArea
2551
type="always"
2652
className="block h-full w-full transition-all"
2753
onScroll={handleScroll}
54+
ref={scrollRef}
2855
>
29-
{children}
56+
<div ref={contentRef}>
57+
{children}
3058

31-
{/* scroll trigger */}
32-
<div className="flex h-[100px] justify-center py-2 text-zinc-300">
33-
{query.isFetching && <IconLoader2 className="animate-spin" size={16} />}
59+
<div className="flex h-[100px] justify-center py-2 text-zinc-300">
60+
{query.isFetching && <IconLoader2 className="animate-spin" size={16} />}
61+
</div>
3462
</div>
3563
</ScrollArea>
3664
)

0 commit comments

Comments
 (0)