fix: let Escape close only the dialog, not also clear the selection behind it

This commit is contained in:
Linus Rath
2026-10-28 02:07:54 +01:00
parent b08bb61a96
commit 5a898dcfd7
2 changed files with 21 additions and 1 deletions
+16
View File
@@ -141,3 +141,19 @@ describe('useFocusTrap', () => {
expect(screen.getByTestId('panel')).not.toHaveAttribute('tabindex');
});
});
describe('useFocusTrap and the page behind', () => {
it('keeps an Escape that closed the dialog from the page', () => {
const page = vi.fn();
document.addEventListener('keydown', page);
try {
const onEscape = vi.fn();
render(<Page open onEscape={onEscape} />);
fireEvent.keyDown(screen.getByLabelText('name'), { key: 'Escape' });
expect(onEscape).toHaveBeenCalledTimes(1);
expect(page).not.toHaveBeenCalled();
} finally {
document.removeEventListener('keydown', page);
}
});
});
+5 -1
View File
@@ -70,7 +70,11 @@ export function useFocusTrap({
const handleKeyDown = (e: KeyboardEvent) => {
// Handle Escape
if (e.key === 'Escape' && onEscapeRef.current) {
if (isTopmost()) onEscapeRef.current();
if (!isTopmost()) return;
// Escape closes the innermost layer only (R8): the page's own
// handlers (Files clears its selection) must not see it too.
e.stopPropagation();
onEscapeRef.current();
return;
}