Skip to content

iOS: SafeAreaView ignores aria-hidden, aria-label and the other aria-* props #59747

Open

Description

@YevheniiKotyrlo

Description

On iOS, SafeAreaView is the native RCTSafeAreaView component itself (Libraries/Components/SafeAreaView/SafeAreaView.js), so its props never go through View, which turns aria-hidden into accessibilityElementsHidden, aria-label into accessibilityLabel and the other aria-* props into their accessibility* counterparts (Libraries/Components/View/View.js). The iOS view config sends the aria-* props to native under their own names (Libraries/NativeComponent/BaseViewConfig.ios.js), and no native code reads them. So on iOS, aria-hidden on a SafeAreaView leaves its content in the accessibility tree, and aria-label does not label it. On Android, SafeAreaView is View.

SafeAreaView is deprecated in favour of react-native-safe-area-context, but 0.88 and main still ship it.

Steps to reproduce

  1. Clone the reproducer. ReproducerApp/App.tsx renders four SafeAreaViews, each around a child text: one with aria-hidden, one with accessibilityElementsHidden, and two accessible ones, labelled with aria-label="Label from aria-label" and with accessibilityLabel="Label from accessibilityLabel".
  2. Run it on iOS in Release and read its accessibility tree. I read the tree XCUITest reads, with App.tsx as RNTester's root component, built from main at 9c3e743a6f, on an iPad Pro (12.9-inch, 4th generation) on iPadOS 27.2.
  3. Expected: "Child of SafeAreaView with aria-hidden" is not in the tree, as "Child of SafeAreaView with accessibilityElementsHidden" is not, and the SafeAreaView with aria-label is labelled "Label from aria-label", as the one with accessibilityLabel is labelled "Label from accessibilityLabel".
  4. Seen: "Child of SafeAreaView with aria-hidden" is an accessible element, and the SafeAreaView with aria-label is labelled "Child of SafeAreaView with aria-label", its child's text.

React Native Version

0.89.0-nightly-20261102-47a9917ac

Affected Platforms

Runtime - iOS, Build - MacOS

Output of npx @react-native-community/cli info

info ran without a pod install, which its iOS lines reflect.

System:
  OS: macOS 27.2
  CPU: (8) arm64 Apple M1
  Memory: 544.23 MB / 8.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 26.12.1
    path: /Users/yevhenii/.nvm/versions/node/v26.12.1/bin/node
  Yarn:
    version: 1.22.22
    path: /Users/yevhenii/contributions/.bin/yarn
  npm:
    version: 12.2.1
    path: /Users/yevhenii/.nvm/versions/node/v26.12.1/bin/npm
  Watchman:
    version: 2026.10.19.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.17.0
    path: /opt/homebrew/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 27.2
      - iOS 27.2
      - macOS 27.2
      - tvOS 27.2
      - visionOS 27.2
      - watchOS 27.2
  Android SDK: Not Found
IDEs:
  Android Studio: Not Found
  Xcode:
    version: 27.2/27B52
    path: /usr/bin/xcodebuild
Languages:
  Java: Not Found
  Ruby:
    version: 4.0.9
    path: /opt/homebrew/bin/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 21.0.0-alpha.1
    wanted: 21.0.0-alpha.1
  react:
    installed: 19.3.0
    wanted: 19.3.0
  react-native:
    installed: 0.89.0-nightly-20261102-47a9917ac
    wanted: 0.89.0-nightly-20261102-47a9917ac
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: Not found
  newArchEnabled: false

Stacktrace or Logs

No crash. The reproducer's accessible elements in the tree XCUITest reads:
StaticText: aria-* props on SafeAreaView
StaticText: Child of SafeAreaView with aria-hidden
Other: Child of SafeAreaView with aria-label
Other: Label from accessibilityLabel

MANDATORY Reproducer

https://github.com/YevheniiKotyrlo/rn-ios-safe-area-view-aria-props

Screenshots and Videos

Nothing on screen is wrong: the accessibility tree above is what VoiceOver reads.

Activity

  1. dave-otf commented on Nov 2, 2026

    @dave-otf

    The contrast with Android makes the missing iOS prop mapping clear: SafeAreaView renders RCTSafeAreaView directly, so it bypasses View's aria-* translation. A focused iOS test could assert both aria-hidden removal and aria-label exposure in the accessibility tree, alongside the existing accessibility* controls. That would pin the platform-specific regression.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions