diff --git a/packages/react-native-web/src/exports/Modal/ModalFocusTrap.js b/packages/react-native-web/src/exports/Modal/ModalFocusTrap.js index f596bf60d..c9b3dd91f 100644 --- a/packages/react-native-web/src/exports/Modal/ModalFocusTrap.js +++ b/packages/react-native-web/src/exports/Modal/ModalFocusTrap.js @@ -58,7 +58,7 @@ function focusFirstDescendant(element: any) { function focusLastDescendant(element: any) { for (let i = element.childNodes.length - 1; i >= 0; i--) { const child = element.childNodes[i]; - if (attemptFocus(child) || focusLastDescendant(child)) { + if (focusLastDescendant(child) || attemptFocus(child)) { return true; } } diff --git a/packages/react-native-web/src/exports/Modal/__tests__/index-test.js b/packages/react-native-web/src/exports/Modal/__tests__/index-test.js index f05307488..b250918b0 100644 --- a/packages/react-native-web/src/exports/Modal/__tests__/index-test.js +++ b/packages/react-native-web/src/exports/Modal/__tests__/index-test.js @@ -532,6 +532,33 @@ describe('components/Modal', () => { expect(document.activeElement).toBe(insideEndElement); }); + test('focus wraps backwards to the last element inside a focusable container', () => { + render( + <> + + + Inside A + +
+ + Inside B + +
+
+ + ); + + const insideStartElement = document.querySelector( + '[data-testid="inside-a"]' + ); + const insideEndElement = document.querySelector('[data-testid="inside-b"]'); + const focusBracket = + insideStartElement.parentNode.parentNode.parentNode.previousSibling; + insideStartElement.focus(); + focusBracket.focus(); + expect(document.activeElement).toBe(insideEndElement); + }); + test('focus is trapped without contents', () => { render( <>