Infinite Scroll: wait for users to reach the top before triggering new requests (#84318)

* Infinite Scroll: wait for users to reach the top before triggering new requests

* Prettier

* Infinite Scroll: control top scrolling via prop

* Prettier
This commit is contained in:
Matias Chomicki 2024-03-15 13:52:55 +01:00 committed by GitHub
parent eae9bfe4bc
commit 15a641a509
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 4 deletions

View File

@ -43,7 +43,7 @@ function ScrollWithWrapper({ children, ...props }: Props) {
return (
<div style={{ height: 40, overflowY: 'scroll' }} ref={scrollRef} data-testid="scroll-element">
{initialized && (
<InfiniteScroll {...props} scrollElement={scrollRef.current!}>
<InfiniteScroll {...props} scrollElement={scrollRef.current!} topScrollEnabled>
{children}
</InfiniteScroll>
)}
@ -60,8 +60,16 @@ function setup(loadMoreMock: () => void, startPosition: number, rows: LogRowMode
act(() => {
events['scroll'](new Event('scroll'));
});
// When scrolling top, we wait for the user to reach the top, and then for a new scrolling event
// in the same direction before triggering a new query.
if (position === 0) {
wheel(-1);
}
}
function wheel(deltaY: number) {
element.scrollTop += deltaY;
act(() => {
const event = new WheelEvent('wheel', { deltaY });
events['wheel'](event);
@ -75,6 +83,7 @@ function setup(loadMoreMock: () => void, startPosition: number, rows: LogRowMode
rows={rows}
scrollElement={element as unknown as HTMLDivElement}
loadMoreLogs={loadMoreMock}
topScrollEnabled
>
<div data-testid="contents" style={{ height: 100 }} />
</InfiniteScroll>

View File

@ -17,6 +17,7 @@ export type Props = {
scrollElement?: HTMLDivElement;
sortOrder: LogsSortOrder;
timeZone: TimeZone;
topScrollEnabled?: boolean;
};
export const InfiniteScroll = ({
@ -28,6 +29,7 @@ export const InfiniteScroll = ({
scrollElement,
sortOrder,
timeZone,
topScrollEnabled = false,
}: Props) => {
const [upperOutOfRange, setUpperOutOfRange] = useState(false);
const [lowerOutOfRange, setLowerOutOfRange] = useState(false);
@ -83,9 +85,9 @@ export const InfiniteScroll = ({
lastScroll.current = scrollElement.scrollTop;
if (scrollDirection === ScrollDirection.NoScroll) {
return;
} else if (scrollDirection === ScrollDirection.Top) {
} else if (scrollDirection === ScrollDirection.Top && topScrollEnabled) {
scrollTop();
} else {
} else if (scrollDirection === ScrollDirection.Bottom) {
scrollBottom();
}
}
@ -127,7 +129,7 @@ export const InfiniteScroll = ({
scrollElement.removeEventListener('scroll', handleScroll);
scrollElement.removeEventListener('wheel', handleScroll);
};
}, [loadMoreLogs, loading, range, rows, scrollElement, sortOrder, timeZone]);
}, [loadMoreLogs, loading, range, rows, scrollElement, sortOrder, timeZone, topScrollEnabled]);
// We allow "now" to move when using relative time, so we hide the message so it doesn't flash.
const hideTopMessage = sortOrder === LogsSortOrder.Descending && isRelativeTime(range.raw.to);