diff --git a/packages/react-aria/src/interactions/utils.ts b/packages/react-aria/src/interactions/utils.ts index 54d10330d02..82d92ed3a9b 100644 --- a/packages/react-aria/src/interactions/utils.ts +++ b/packages/react-aria/src/interactions/utils.ts @@ -109,7 +109,7 @@ export let ignoreFocusEvent = false; */ export function preventFocus(target: FocusableElement | null): (() => void) | undefined { // The browser will focus the nearest focusable ancestor of our target. - while (target && !isFocusable(target)) { + while (target && !isFocusable(target, {skipVisibilityCheck: true})) { target = target.parentElement; } diff --git a/packages/react-aria/src/utils/isFocusable.ts b/packages/react-aria/src/utils/isFocusable.ts index 9f8f6114b99..f9fae7cafbb 100644 --- a/packages/react-aria/src/utils/isFocusable.ts +++ b/packages/react-aria/src/utils/isFocusable.ts @@ -34,8 +34,8 @@ const FOCUSABLE_ELEMENT_SELECTOR = focusableElements.join(':not([hidden]),') + ' focusableElements.push('[tabindex]:not([tabindex="-1"]):not([disabled])'); const TABBABLE_ELEMENT_SELECTOR = focusableElements.join(':not([hidden]):not([tabindex="-1"]),'); -export function isFocusable(element: Element): boolean { - return element.matches(FOCUSABLE_ELEMENT_SELECTOR) && isElementVisible(element) && !isInert(element); +export function isFocusable(element: Element, options?: {skipVisibilityCheck?: boolean}): boolean { + return element.matches(FOCUSABLE_ELEMENT_SELECTOR) && !isInert(element) && (options?.skipVisibilityCheck || isElementVisible(element)); } export function isTabbable(element: Element): boolean {