From 6763b42330cba992a5d5efcb7a557c1ec0471972 Mon Sep 17 00:00:00 2001 From: Jules Date: Tue, 24 Feb 2026 12:12:26 -0800 Subject: [PATCH] Revert "Fix screen reader focus not moving to opened menu on mWeb" --- .../TopLevelNavigationTabBar/index.tsx | 2 - .../ScreenWrapper/ScreenWrapperContainer.tsx | 9 +--- src/components/ScreenWrapper/index.tsx | 50 ++----------------- .../ModalStackNavigators/index.tsx | 7 +-- tests/ui/SearchPageTest.tsx | 10 ++-- 5 files changed, 10 insertions(+), 68 deletions(-) diff --git a/src/components/Navigation/TopLevelNavigationTabBar/index.tsx b/src/components/Navigation/TopLevelNavigationTabBar/index.tsx index da32b9ec2575..18bcaa2ee26d 100644 --- a/src/components/Navigation/TopLevelNavigationTabBar/index.tsx +++ b/src/components/Navigation/TopLevelNavigationTabBar/index.tsx @@ -67,8 +67,6 @@ function TopLevelNavigationTabBar({state}: TopLevelNavigationTabBarProps) { !shouldUseNarrowLayout ? styles.borderRight : {}, shouldDisplayLHB ? StyleUtils.positioning.l0 : StyleUtils.positioning.b0, ]} - accessibilityElementsHidden={!isReadyToDisplayBottomBar} - aria-hidden={!isReadyToDisplayBottomBar} > {/* We are not rendering NavigationTabBar conditionally for two reasons 1. It's faster to hide/show it than mount a new when needed. diff --git a/src/components/ScreenWrapper/ScreenWrapperContainer.tsx b/src/components/ScreenWrapper/ScreenWrapperContainer.tsx index 63b626c9612a..9118f8260c53 100644 --- a/src/components/ScreenWrapper/ScreenWrapperContainer.tsx +++ b/src/components/ScreenWrapper/ScreenWrapperContainer.tsx @@ -8,14 +8,12 @@ import KeyboardAvoidingView from '@components/KeyboardAvoidingView'; import ModalContext from '@components/Modal/ModalContext'; import useBottomSafeSafeAreaPaddingStyle from '@hooks/useBottomSafeSafeAreaPaddingStyle'; import useInitialDimensions from '@hooks/useInitialWindowDimensions'; -import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useSafeAreaPaddings from '@hooks/useSafeAreaPaddings'; import useTackInputFocus from '@hooks/useTackInputFocus'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import {isMobile, isMobileWebKit, isSafari} from '@libs/Browser'; import type {ForwardedFSClassProps} from '@libs/Fullstory/types'; -import getPlatform from '@libs/getPlatform'; import addViewportResizeListener from '@libs/VisualViewport'; import toggleTestToolsModal from '@userActions/TestTool'; import CONST from '@src/CONST'; @@ -110,8 +108,8 @@ function ScreenWrapperContainer({ includePaddingTop = true, includeSafeAreaPaddingBottom = false, isFocused = true, - forwardedFSClass, ref, + forwardedFSClass, }: ScreenWrapperContainerProps) { const {windowHeight} = useWindowDimensions(shouldUseCachedViewportHeight); const {initialHeight} = useInitialDimensions(); @@ -121,8 +119,6 @@ function ScreenWrapperContainer({ const {isBlurred} = useInputBlurState(); const {setIsBlurred} = useInputBlurActions(); const isAvoidingViewportScroll = useTackInputFocus(isFocused && shouldEnableMaxHeight && shouldAvoidScrollOnVirtualViewport && isMobileWebKit()); - const {shouldUseNarrowLayout} = useResponsiveLayout(); - const shouldHideFromAccessibility = shouldUseNarrowLayout && getPlatform() === CONST.PLATFORM.WEB && isMobile() && !isFocused; const isUsingEdgeToEdgeMode = enableEdgeToEdgeBottomSafeAreaPadding !== undefined; const shouldKeyboardOffsetBottomSafeAreaPadding = shouldKeyboardOffsetBottomSafeAreaPaddingProp ?? isUsingEdgeToEdgeMode; @@ -214,9 +210,6 @@ function ScreenWrapperContainer({ {...panResponder.panHandlers} testID={testID} fsClass={forwardedFSClass} - tabIndex={-1} - accessibilityElementsHidden={shouldHideFromAccessibility} - aria-hidden={shouldHideFromAccessibility} > >(); const navigation = navigationProp ?? navigationFallback; const isFocused = useIsFocused(); - const screenWrapperRef = useRef(null); - const mergedScreenWrapperRef = mergeRefs(screenWrapperRef, ref); // We need to use isSmallScreenWidth instead of shouldUseNarrowLayout for a case where we want to show the offline indicator only on small screens // eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth const {isSmallScreenWidth} = useResponsiveLayout(); - const shouldMoveAccessibilityFocus = getPlatform() === CONST.PLATFORM.WEB && isMobile(); const styles = useThemeStyles(); const {isDevelopment} = useEnvironment(); @@ -226,44 +220,6 @@ function ScreenWrapper({ // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - useEffect(() => { - if (!shouldMoveAccessibilityFocus || !didScreenTransitionEnd || !isFocused) { - return; - } - - if (typeof document === 'undefined') { - return; - } - - const element = screenWrapperRef.current; - if (!element || !('contains' in element) || !('querySelectorAll' in element)) { - return; - } - - const activeElement = document.activeElement; - if (activeElement && element.contains(activeElement)) { - return; - } - - const focusTargets = element.querySelectorAll('button, [href], [role="button"], [role="link"], [tabindex]:not([tabindex="-1"])'); - for (const focusTarget of focusTargets) { - const isDisabledTarget = focusTarget.matches(':disabled') || focusTarget.getAttribute('aria-disabled')?.toLowerCase() === 'true'; - if (isDisabledTarget || focusTarget.getAttribute('aria-hidden') === 'true') { - continue; - } - - if (focusTarget === activeElement) { - return; - } - - focusTarget.focus(); - const focusedElement = document.activeElement; - if (focusedElement === focusTarget || (focusedElement && focusTarget.contains(focusedElement))) { - return; - } - } - }, [didScreenTransitionEnd, isFocused, shouldMoveAccessibilityFocus]); - useFocusEffect( useCallback(() => { // On iOS, the transitionEnd event doesn't trigger some times. As such, we need to set a timeout @@ -299,7 +255,7 @@ function ScreenWrapper({ return ( (screens: Scr return ( // This container is necessary to hide card translation during transition. Without it the user would see un-clipped cards. - + {Object.keys(screens as Required).map((name) => ( { expect(screen.getByTestId('SearchPageNarrow')).toBeTruthy(); // Initially, there are two NavigationTabBars on screen: one from TopLevelNavigationTabBar and one from SearchPageNarrow. - let navigationTabBars = screen.getAllByTestId('NavigationTabBar', {includeHiddenElements: true}); + let navigationTabBars = screen.getAllByTestId('NavigationTabBar'); expect(navigationTabBars).toHaveLength(2); const searchAutocompleteInput = await screen.findByTestId('search-autocomplete-text-input'); @@ -126,12 +126,12 @@ describe('SearchPageNarrow', () => { }); await waitFor(() => { - navigationTabBars = screen.getAllByTestId('NavigationTabBar', {includeHiddenElements: true}); + navigationTabBars = screen.getAllByTestId('NavigationTabBar'); expect(navigationTabBars).toHaveLength(1); }); await waitFor(() => { - const topLevelNavigationTabBar = screen.getByTestId('TopLevelNavigationTabBar', {includeHiddenElements: true}); + const topLevelNavigationTabBar = screen.getByTestId('TopLevelNavigationTabBar'); expect(topLevelNavigationTabBar).toHaveStyle({pointerEvents: 'none', opacity: 0}); }); @@ -142,12 +142,12 @@ describe('SearchPageNarrow', () => { }); await waitFor(() => { - navigationTabBars = screen.getAllByTestId('NavigationTabBar', {includeHiddenElements: true}); + navigationTabBars = screen.getAllByTestId('NavigationTabBar'); expect(navigationTabBars).toHaveLength(2); }); await waitFor(() => { - const topLevelNavigationTabBar = screen.getByTestId('TopLevelNavigationTabBar', {includeHiddenElements: true}); + const topLevelNavigationTabBar = screen.getByTestId('TopLevelNavigationTabBar'); expect(topLevelNavigationTabBar).toHaveStyle({pointerEvents: 'auto', opacity: 1}); }); });