Skip to content

Commit

Permalink
Avoid loading next page in PaginatedMultiSelect when scrolling up (#6855
Browse files Browse the repository at this point in the history
)
  • Loading branch information
acelaya authored Nov 19, 2024
1 parent 494d226 commit 2196571
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export default function PaginatedMultiSelect<TResult, TSelect>({
onChange,
}: PaginatedMultiSelectProps<TResult, TSelect>) {
const lastOptionRef = useRef<HTMLElement | null>(null);
const lastListboxScrollPosition = useRef(0);

return (
<MultiSelect
Expand All @@ -100,7 +101,14 @@ export default function PaginatedMultiSelect<TResult, TSelect>({
buttonContent={buttonContent}
data-testid={`${entity}-select`}
onListboxScroll={e => {
if (elementScrollIsAtBottom(e.target as HTMLUListElement)) {
const element = e.target as HTMLUListElement;
const newScrollPosition = element.scrollTop;
const isScrollingDown =
newScrollPosition > lastListboxScrollPosition.current;

lastListboxScrollPosition.current = newScrollPosition;

if (isScrollingDown && elementScrollIsAtBottom(element)) {
result.loadNextPage();
}
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,11 @@ describe('PaginatedMultiSelect', () => {
return { select, fakeLoadNextPage };
}

function scrollTo(select, scrollHeight) {
function scrollTo(select, { scrollHeight, scrollTop = 100 }) {
select.props().onListboxScroll({
target: {
scrollTop: 100,
clientHeight: 50,
scrollTop,
scrollHeight,
},
});
Expand All @@ -108,16 +108,27 @@ describe('PaginatedMultiSelect', () => {
it('loads next page when scroll is at the bottom', () => {
const { select, fakeLoadNextPage } = getScrollableSelect();

scrollTo(select, 160);
scrollTo(select, { scrollHeight: 160 });
assert.called(fakeLoadNextPage);
});

it('does nothing when scroll is not at the bottom', () => {
const { select, fakeLoadNextPage } = getScrollableSelect();

scrollTo(select, 250);
scrollTo(select, { scrollHeight: 250 });
assert.notCalled(fakeLoadNextPage);
});

it('does not scroll again if scrolling up', () => {
const { select, fakeLoadNextPage } = getScrollableSelect();

// We scroll down, then a little bit up, still inside the offset gap
scrollTo(select, { scrollHeight: 160, scrollTop: 155 });
scrollTo(select, { scrollHeight: 160, scrollTop: 150 });

// The page is attempted to load only once, and ignored when scrolling up
assert.calledOnce(fakeLoadNextPage);
});
});

it('displays only active item if provided', () => {
Expand Down

0 comments on commit 2196571

Please sign in to comment.