diff --git a/.changeset/strong-spies-tell.md b/.changeset/strong-spies-tell.md new file mode 100644 index 000000000..a08cce458 --- /dev/null +++ b/.changeset/strong-spies-tell.md @@ -0,0 +1,5 @@ +--- +"@heroui/use-aria-overlay": patch +--- + +prevent modal/drawer from closing on press instead (#5616) diff --git a/packages/hooks/use-aria-overlay/src/index.ts b/packages/hooks/use-aria-overlay/src/index.ts index 09c53333f..1ee1f1e80 100644 --- a/packages/hooks/use-aria-overlay/src/index.ts +++ b/packages/hooks/use-aria-overlay/src/index.ts @@ -65,7 +65,9 @@ export function useAriaOverlay(props: UseAriaOverlayProps, ref: RefObject, + ): "pressEnd" | "pressStart" | "unknown" { + const el = ref.current; + + if (!el) return "unknown"; + + const role = (el.getAttribute("role") || "").toLowerCase(); + const ariaModalAttr = el.getAttribute("aria-modal"); + + // Dialogs (Modal/Drawer) should close on press release. + // Include alertdialog and treat missing aria-modal (unless explicitly "false") as modal. + if ( + (role === "dialog" || role === "alertdialog") && + (ariaModalAttr === null || ariaModalAttr.toLowerCase() === "true") + ) { + return "pressEnd"; + } + + // Select-like/menu-like overlays typically close on press start. + if (["listbox", "menu", "tree", "grid", "combobox"].includes(role)) { + return "pressStart"; + } + + return "unknown"; + } + return { overlayProps: { onKeyDown,