From d8b788aecc10dc478544420f2f765ca177f47da7 Mon Sep 17 00:00:00 2001 From: Dustin Healy <54083382+dustinhealy@users.noreply.github.com> Date: Tue, 16 Dec 2025 06:15:43 -0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8F=83=20feat:=20Keep=20Modals=20Open=20o?= =?UTF-8?q?n=20Escape=20in=20Dropdown=20Menus=20(#10975)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: filter dropdown now closable with escape, doesn't close whole modal * refactor: simplify escapekeydown handler logic for tooltips and dropdown menus * refactor: more specific conditions for preventDefault --- .../client/src/components/OriginalDialog.tsx | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/packages/client/src/components/OriginalDialog.tsx b/packages/client/src/components/OriginalDialog.tsx index 74e67c60fd..706732f19a 100644 --- a/packages/client/src/components/OriginalDialog.tsx +++ b/packages/client/src/components/OriginalDialog.tsx @@ -78,29 +78,39 @@ const DialogContent = React.forwardRef< }, ref, ) => { - /* Handle Escape key to prevent closing dialog if a tooltip is open + const contentRef = React.useRef(null); + + React.useImperativeHandle(ref, () => contentRef.current as HTMLDivElement, []); + + /* Handle Escape key to prevent closing dialog if a tooltip or dropdown is open (this is a workaround in order to achieve WCAG compliance which requires that our tooltips be dismissable with Escape key) */ const handleEscapeKeyDown = React.useCallback( (event: KeyboardEvent) => { - const tooltips = document.querySelectorAll('.tooltip'); + if (!contentRef.current) { + propsOnEscapeKeyDown?.(event); + return; + } - for (const tooltip of Array.from(tooltips)) { - const computedStyle = window.getComputedStyle(tooltip); - const opacity = parseFloat(computedStyle.opacity); + const tooltips = contentRef.current.querySelectorAll('.tooltip'); + const dropdownMenus = contentRef.current.querySelectorAll('[role="menu"]'); - if ( - tooltip.parentElement && - computedStyle.display !== 'none' && - computedStyle.visibility !== 'hidden' && - opacity > 0 - ) { + for (const tooltip of tooltips) { + const style = window.getComputedStyle(tooltip); + if (style.display !== 'none') { + event.preventDefault(); + return; + } + } + + for (const dropdownMenu of dropdownMenus) { + const style = window.getComputedStyle(dropdownMenu); + if (style.display !== 'none') { event.preventDefault(); return; } } - // Call the original handler if it exists propsOnEscapeKeyDown?.(event); }, [propsOnEscapeKeyDown], @@ -110,7 +120,7 @@ const DialogContent = React.forwardRef<