diff --git a/components/contacts/__tests__/contact-list.test.tsx b/components/contacts/__tests__/contact-list.test.tsx index a0864a598..81c8967bd 100644 --- a/components/contacts/__tests__/contact-list.test.tsx +++ b/components/contacts/__tests__/contact-list.test.tsx @@ -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(); + const scroller = screen.getByRole('listbox').parentElement!; + rerender(Possible duplicates (1)} />); + // 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(); expect(screen.queryByTestId('contact-list-skeleton')).toBeNull(); diff --git a/components/contacts/contact-list.tsx b/components/contacts/contact-list.tsx index 1f563aeba..f10f4a0f8 100644 --- a/components/contacts/contact-list.tsx +++ b/components/contacts/contact-list.tsx @@ -663,16 +663,15 @@ export function ContactList({ )} + {/* Contact list. The banner scrolls with it: it comes with the loaded + contacts, and above the scroll area it pushed the whole list down. */} +
{!hasSelection && banner} - - {/* Contact list */}
{sorted.length === 0 && isLoading && !searchQuery && activeFilters === 0 ? ( // The rows the page skeleton drew, at the same density. @@ -781,6 +780,7 @@ export function ContactList({ })() )}
+
{printTitle != null && (