fix(ui): stabilize infinite-stream callbacks + suppress empty-state flash
- useInfiniteStream: wrap fetchNextPage and refresh in useCallback so InfiniteScrollArea's IntersectionObserver does not re-subscribe on every parent render. - InfiniteScrollArea: do not render 'End of stream' until at least one item has loaded and the initial query has settled (was flashing on mount before first fetch). - AgentHealth: pass isLoading + hasItems to both InfiniteScrollArea wrappers.
This commit is contained in:
@@ -6,6 +6,8 @@ export interface InfiniteScrollAreaProps {
|
||||
onTopVisibilityChange?: (atTop: boolean) => void;
|
||||
isFetchingNextPage: boolean;
|
||||
hasNextPage: boolean;
|
||||
isLoading?: boolean;
|
||||
hasItems?: boolean;
|
||||
maxHeight?: number | string;
|
||||
children: ReactNode;
|
||||
/** Optional caller-owned scroll container ref (e.g. for scroll-to-top on refresh). */
|
||||
@@ -18,6 +20,8 @@ export function InfiniteScrollArea({
|
||||
onTopVisibilityChange,
|
||||
isFetchingNextPage,
|
||||
hasNextPage,
|
||||
isLoading = false,
|
||||
hasItems = true,
|
||||
maxHeight = 360,
|
||||
children,
|
||||
scrollRef,
|
||||
@@ -68,7 +72,9 @@ export function InfiniteScrollArea({
|
||||
{children}
|
||||
<div ref={bottomSentinel} className={styles.sentinel} aria-hidden="true" />
|
||||
{isFetchingNextPage && <div className={styles.loadingMore}>Loading more…</div>}
|
||||
{!hasNextPage && <div className={styles.endOfStream}>End of stream</div>}
|
||||
{!hasNextPage && !isLoading && hasItems && (
|
||||
<div className={styles.endOfStream}>End of stream</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user