From 438a31b34aa6b0a1cfb6b0478db4fb2905da2020 Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Wed, 4 Nov 2026 14:35:35 +0100 Subject: [PATCH] fix: close the dialog on top with Escape, not the file preview behind it --- .../preview-escape-dialog-ux-p2-pim.test.tsx | 37 +++++++++++++++++++ components/files/preview-shell.tsx | 5 +++ 2 files changed, 42 insertions(+) create mode 100644 components/files/__tests__/preview-escape-dialog-ux-p2-pim.test.tsx diff --git a/components/files/__tests__/preview-escape-dialog-ux-p2-pim.test.tsx b/components/files/__tests__/preview-escape-dialog-ux-p2-pim.test.tsx new file mode 100644 index 000000000..fa03adf36 --- /dev/null +++ b/components/files/__tests__/preview-escape-dialog-ux-p2-pim.test.tsx @@ -0,0 +1,37 @@ +import { render, fireEvent } from '@testing-library/react'; +import { describe, it, expect, vi } from 'vitest'; +import { PreviewShell } from '../preview-shell'; +import { Dialog } from '@/components/ui/dialog'; + +// pim-p2-7: Escape in "Import to a mail folder…", opened from a saved mail's +// preview, closed the preview behind the dialog and left the dialog open. +describe('Escape with a dialog over the file preview', () => { + it('closes the dialog, not the preview', () => { + const closePreview = vi.fn(); + const closeDialog = vi.fn(); + const { getByLabelText } = render( + <> + +

mail

+
+ + + + , + ); + fireEvent.keyDown(getByLabelText('Filter'), { key: 'Escape' }); + expect(closePreview).not.toHaveBeenCalled(); + expect(closeDialog).toHaveBeenCalledTimes(1); + }); + + it('still closes the preview when nothing is above it', () => { + const closePreview = vi.fn(); + render( + + + , + ); + fireEvent.keyDown(document.body, { key: 'Escape' }); + expect(closePreview).toHaveBeenCalledTimes(1); + }); +}); diff --git a/components/files/preview-shell.tsx b/components/files/preview-shell.tsx index d604d63de..aca9f089c 100644 --- a/components/files/preview-shell.tsx +++ b/components/files/preview-shell.tsx @@ -69,6 +69,11 @@ export function PreviewShell({ name, onClose, onDownload, actions, neighbours, c useEffect(() => { const onKey = (e: KeyboardEvent) => { if (e.key === "Escape") { + // A dialog opened from the preview (Import to a mail folder…) sits on top + // and closes first; the preview stays. + const target = e.target instanceof Element ? e.target : null; + const above = target?.closest('[role="dialog"], [role="alertdialog"]'); + if (above && shellRef.current && !shellRef.current.contains(above)) return; e.stopPropagation(); onClose(); return;