mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
fix(use-aria-overlay): prevent modal/drawer from closing on press instead (#5624)
* fix(modal/drawer): prevent modal/drawer from closing on press instead * refactor(useAriaOverlay): improve getOverlayTypeFromRef with ARIA checks and hoist * refactor(useAriaOverlay): add alertdialog & fallback to modal when aria-modal is missing * Merge branch 'canary' into pr/5624 * chore(changeset): add issue number * refactor(use-aria-overlay): getOverlayInteractionType --------- Co-authored-by: WK Wong <wingkwong.code@gmail.com>
This commit is contained in:
parent
e0dc33f3b6
commit
b6fda4fe6f
5
.changeset/strong-spies-tell.md
Normal file
5
.changeset/strong-spies-tell.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"@heroui/use-aria-overlay": patch
|
||||
---
|
||||
|
||||
prevent modal/drawer from closing on press instead (#5616)
|
||||
@ -65,7 +65,9 @@ export function useAriaOverlay(props: UseAriaOverlayProps, ref: RefObject<Elemen
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
onHide();
|
||||
if (getOverlayInteractionType(ref) !== "pressEnd") {
|
||||
onHide();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -130,6 +132,38 @@ export function useAriaOverlay(props: UseAriaOverlayProps, ref: RefObject<Elemen
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines the interaction type for overlay dismissal based on the element's ARIA role.
|
||||
* @param ref - Reference to the overlay element
|
||||
* @returns "pressEnd" for dialogs (close on release), "pressStart" for menus (close on press), or "unknown"
|
||||
*/
|
||||
function getOverlayInteractionType(
|
||||
ref: RefObject<Element>,
|
||||
): "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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user