diff --git a/packages/host/directory-picker-browse/src/client/DirectoryBrowser.tsx b/packages/host/directory-picker-browse/src/client/DirectoryBrowser.tsx index 3df65e2ffb..c70c3a5ea3 100644 --- a/packages/host/directory-picker-browse/src/client/DirectoryBrowser.tsx +++ b/packages/host/directory-picker-browse/src/client/DirectoryBrowser.tsx @@ -307,7 +307,14 @@ export function DirectoryBrowser({ open, listDirectory, createDirectory, onOpen, // listing itself fails, typing an absolute path is the one // remaining way forward. disabled={parentInert} - onClick={() => { setPathDraft(selected?.path ?? parent?.path ?? '') }} + onClick={() => { + // Opening the editor supersedes any pending listing: a + // settlement landing before the first keystroke would + // otherwise close the editor via navigate's draft reset. + requestSeq.current += 1 + setLoading(false) + setPathDraft(selected?.path ?? parent?.path ?? '') + }} /> ) diff --git a/packages/host/directory-picker-browse/tests/directory-browser.spec.tsx b/packages/host/directory-picker-browse/tests/directory-browser.spec.tsx index 381dc849e2..810245a8ea 100644 --- a/packages/host/directory-picker-browse/tests/directory-browser.spec.tsx +++ b/packages/host/directory-picker-browse/tests/directory-browser.spec.tsx @@ -337,6 +337,21 @@ describe('DirectoryBrowser', () => { expect(columns()).toHaveLength(2) }) + it('keeps the editor open when a pending listing settles right after Edit Path was clicked', async () => { + const pending: ((listing: DirectoryListing) => void)[] = [] + const b = mount() + await waitFor(() => { expect(screen.getByRole('listitem')).toBeTruthy() }) + // A crumb navigation hangs; the user opens the editor before it settles. + b.listDirectory.mockImplementation(() => + new Promise((settle) => { pending.push(settle) })) + fireEvent.click(within(screen.getByRole('navigation')).getByRole('button', { name: 'browser.home' })) + fireEvent.click(screen.getByRole('button', { name: 'browser.editPath' })) + expect(screen.getByLabelText('browser.editPath')).toBeTruthy() + await act(async () => { pending.shift()!(listingFor(HOME)) }) + // The superseded settlement must not close the editor underneath the user. + expect(screen.getByLabelText('browser.editPath')).toBeTruthy() + }) + it('keeps a newer path edit when an older slow navigation settles', async () => { const pending: ((listing: DirectoryListing) => void)[] = [] const b = mount()