Skip to content

Commit 9d30e15

Browse files
authored
fix: Fix Talkback focus cursor movement when inside Dialogs (#7478)
* Fix Android talkback focus cusor movement when inside contain FocusScopes (e.g. Dialogs) * remove tab index to fix story behavior * go back to wikipedia because it works both inside and outside the storybook iframe * Temporary patch for Chrome Android
1 parent 3f8b6b8 commit 9d30e15

File tree

2 files changed

+9
-3
lines changed

2 files changed

+9
-3
lines changed

packages/@react-aria/focus/src/FocusScope.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212

1313
import {FocusableElement, RefObject} from '@react-types/shared';
1414
import {focusSafely} from './focusSafely';
15-
import {getOwnerDocument, useLayoutEffect} from '@react-aria/utils';
15+
import {getInteractionModality} from '@react-aria/interactions';
16+
import {getOwnerDocument, isAndroid, isChrome, useLayoutEffect} from '@react-aria/utils';
1617
import {isElementVisible} from './isElementVisible';
1718
import React, {ReactNode, useContext, useEffect, useMemo, useRef} from 'react';
1819

@@ -381,8 +382,14 @@ function useFocusContainment(scopeRef: RefObject<Element[] | null>, contain?: bo
381382
cancelAnimationFrame(raf.current);
382383
}
383384
raf.current = requestAnimationFrame(() => {
385+
// Patches infinite focus coersion loop for Android Talkback where the user isn't able to move the virtual cursor
386+
// if within a containing focus scope. Bug filed against Chrome: https://issuetracker.google.com/issues/384844019.
387+
// Note that this means focus can leave focus containing modals due to this, but it is isolated to Chrome Talkback.
388+
let modality = getInteractionModality();
389+
let shouldSkipFocusRestore = (modality === 'virtual' || modality === null) && isAndroid() && isChrome();
390+
384391
// Use document.activeElement instead of e.relatedTarget so we can tell if user clicked into iframe
385-
if (ownerDocument.activeElement && shouldContainFocus(scopeRef) && !isElementInChildScope(ownerDocument.activeElement, scopeRef)) {
392+
if (!shouldSkipFocusRestore && ownerDocument.activeElement && shouldContainFocus(scopeRef) && !isElementInChildScope(ownerDocument.activeElement, scopeRef)) {
386393
activeScope = scopeRef;
387394
if (ownerDocument.body.contains(e.target)) {
388395
focusedNode.current = e.target;

packages/@react-spectrum/menu/test/MenuTrigger.test.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1123,4 +1123,3 @@ AriaMenuTests({
11231123
)
11241124
}
11251125
});
1126-

0 commit comments

Comments
 (0)