fix: keep Possible duplicates inside the contact list's scroll area, so the list doesn't jump when contacts load

This commit is contained in:
Linus Rath
2026-11-04 16:09:40 +01:00
parent 0c34edb64e
commit ba633376d8
2 changed files with 13 additions and 4 deletions
@@ -90,6 +90,15 @@ describe('ContactList', () => {
expect(avatars().some((el) => el.classList.contains('hidden'))).toBe(false);
});
it('puts a banner at the top of the scrolling list, so its arrival moves nothing on screen', () => {
const { rerender } = render(<ContactList {...defaultProps} contacts={[]} isLoading />);
const scroller = screen.getByRole('listbox').parentElement!;
rerender(<ContactList {...defaultProps} banner={<button type="button">Possible duplicates (1)</button>} />);
// The same scroll area as with the loading rows, and the banner inside it.
expect(screen.getByRole('listbox').parentElement).toBe(scroller);
expect(scroller.firstElementChild).toBe(screen.getByRole('button', { name: 'Possible duplicates (1)' }));
});
it('shows the contacts as soon as they are there, even while loading', () => {
render(<ContactList {...defaultProps} isLoading />);
expect(screen.queryByTestId('contact-list-skeleton')).toBeNull();
+4 -4
View File
@@ -663,16 +663,15 @@ export function ContactList({
</div>
)}
{/* Contact list. The banner scrolls with it: it comes with the loaded
contacts, and above the scroll area it pushed the whole list down. */}
<div ref={listRef} className="flex-1 overflow-y-auto max-md:pb-20">
{!hasSelection && banner}
{/* Contact list */}
<div
ref={listRef}
role="listbox"
aria-label={t("title")}
aria-multiselectable
onKeyDown={handleListKeyDown}
className="flex-1 overflow-y-auto max-md:pb-20"
>
{sorted.length === 0 && isLoading && !searchQuery && activeFilters === 0 ? (
// The rows the page skeleton drew, at the same density.
@@ -781,6 +780,7 @@ export function ContactList({
})()
)}
</div>
</div>
{printTitle != null && (
<ContactListPrint