From 64184d23f838918b54a970d169ccf9feb2a349dd Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Tue, 3 Nov 2026 05:26:39 +0100 Subject: [PATCH] fix: keep Tab and the / shortcut out of a message list hidden by the open message --- .../mail-app-return-to-list.test.tsx | 18 +++++++++++++++++ components/mail/mail-app.tsx | 20 +++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/components/mail/__tests__/mail-app-return-to-list.test.tsx b/components/mail/__tests__/mail-app-return-to-list.test.tsx index e07345052..b9b3ec364 100644 --- a/components/mail/__tests__/mail-app-return-to-list.test.tsx +++ b/components/mail/__tests__/mail-app-return-to-list.test.tsx @@ -273,6 +273,24 @@ describe.each([ }); }); +describe('A list collapsed under an open message (focused layout)', () => { + const list = () => screen.getByText('message list').closest('section')!; + + it('is out of the Tab order while the message is open', async () => { + render(); + await screen.findByText('stub archive', {}, { timeout: 5000 }); + expect(list()).toHaveAttribute('inert'); + }); + + it('comes back for the / shortcut, whose search field lives in it', async () => { + render(); + await screen.findByText('stub archive', {}, { timeout: 5000 }); + act(() => { fireEvent.keyDown(window, { key: '/' }); }); + await waitFor(() => expect(selectedId()).toBeNull()); + await waitFor(() => expect(list()).not.toHaveAttribute('inert')); + }); +}); + describe('The e shortcut in Mountain View', () => { beforeEach(() => { useSettingsStore.setState({ interfaceLayout: 'mountain-view' } as never); diff --git a/components/mail/mail-app.tsx b/components/mail/mail-app.tsx index a4f6e764f..895f89626 100644 --- a/components/mail/mail-app.tsx +++ b/components/mail/mail-app.tsx @@ -1109,10 +1109,19 @@ export function MailApp({ linkSegments: routeSegments }: MailAppProps = {}) { }, onFocusSearch: () => { if (isScheduledView) return; - const searchInput = document.querySelector('[data-search-input]') as HTMLInputElement; - if (searchInput) { - searchInput.focus(); - searchInput.select(); + const focusSearch = () => { + const searchInput = document.querySelector('[data-search-input]') as HTMLInputElement; + if (searchInput) { + searchInput.focus(); + searchInput.select(); + } + }; + // The field is in the list, which an open message can have collapsed. + if (shouldCollapseListPane) { + handleMobileBack(); + requestAnimationFrame(() => requestAnimationFrame(focusSearch)); + } else { + focusSearch(); } }, onShowHelp: () => { @@ -5089,6 +5098,9 @@ export function MailApp({ linkSegments: routeSegments }: MailAppProps = {}) {