Repository navigation
Add AccessibilityInfo.getPreferences() and a longer iOS timeout while Switch Control runs - #59318
Open
camilopires wants to merge 3 commits into
Open
camilopires wants to merge 3 commits into
camilopires wants to merge 3 commits into
Conversation
Add a preferences snapshot for accessibility settings that change how an app should draw its own controls, named by what the user needs rather than by each platform's setting: prefersSwitchLabels (iOS On/Off Labels) and prefersNonColorIndicators (iOS Differentiate Without Color). Android has neither setting, so it resolves both to false. preferencesChanged carries the whole new snapshot. getRecommendedTimeoutMillis now asks the iOS module too, so iOS can return a longer timeout while Switch Control is running. Adds Jest tests, type tests, the API snapshot and an RNTester row. The iOS native side follows in the next commit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RCTAccessibilityManager builds the getPreferences() snapshot from On/Off Labels (UIAccessibilityIsOnOffSwitchLabelsEnabled) and Differentiate Without Color (UIAccessibilityShouldDifferentiateWithoutColor), observes both settings' notifications, and sends preferencesChanged with the whole snapshot only when it changes. getRecommendedTimeoutMillis returns three times the original timeout while Switch Control is running, because moving between elements one switch press at a time is slow. Adds RCTAccessibilityManagerTests for the timeout and for sending the event only on a change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RCTAccessibilityManager now reads the On/Off Labels, Differentiate Without Color and Switch Control settings through readers that tests can replace (RCTAccessibilityManagerSetSystemReaders, in +Internal.h). The tests post the real UIKit notifications and call getCurrentPreferences and getRecommendedTimeoutMillis, so they cover the observers, the deduplication and the native callbacks, not just a helper. This replaces the two earlier test hooks. RNTester's preferences row also reads the snapshot and the recommended timeout again when the app becomes active, because Switch Control has no change event. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning JavaScript API change detected This PR commits an update to
This change was flagged as: |
This was referenced Oct 21, 2026
Contributor
|
there are several conflicts in this PR. Can you rebase on top of main please? |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
Following the discussion in react-native-community/discussions-and-proposals#1026, this adds one snapshot for accessibility settings that change how an app should draw its own controls. It replaces the one-flag-per-setting PRs #59178, #59179 and #59180.
React Native apps mostly draw their own switches and buttons with
PressableandView, so the system can't adapt them to these settings as it doesUISwitchand system buttons. The app has to read the setting itself.prefersCrossFadeTransitionsalready does this. A platform with no such setting reportsfalse, so apps don't need platform checks. A future setting becomes a new field, not a new method and event.preferencesChangedcarries the whole new snapshot, and fires only when a field changes.getPreferences()resolves both fields tofalsewithout a native call, andpreferencesChangeddoesn't subscribe, like the other iOS-only events.Switch Control uses the existing
getRecommendedTimeoutMillis(originalTimeout)rather than a new flag or method. Until now it read Android's "Time to take action" setting and returnedoriginalTimeoutunchanged on iOS. On iOS it now returns three timesoriginalTimeoutwhile Switch Control is running. Moving between elements one switch press at a time is slow, so a 4-second toast is often gone before you reach it. Apple publishes no recommended figure, so 3× is a judgement call, and I'm happy to change it. This also replaces the separategetRecommendedTimeoutI suggested on #1026, since the method already exists.Scope: Show Borders (#59177) has already landed as
isShowBordersEnabled(), and the Android contrast level (#59181) is in review, so neither is folded into the snapshot here. #59176 (Bold Text on Android) is separate. It also editsAccessibilityInfo.js, so whichever lands second needs a small rebase.Changelog:
[IOS] [ADDED] -
AccessibilityInfo.getPreferences()andpreferencesChanged(On/Off Labels and Differentiate Without Color)[IOS] [CHANGED] -
AccessibilityInfo.getRecommendedTimeoutMillis()returns a longer timeout while Switch Control is runningTest Plan:
yarn jest packages/react-native/Libraries/Components/AccessibilityInfo: 49 tests pass. They covergetPreferenceson both platforms (including an older iOS binary without the native method), the iOS timeout with and without the native method, and the event wiring.yarn flow-check: 0 errorsyarn lint: passesyarn build-types --validate: API snapshot up to dateyarn test-generated-typescriptandyarn test-typescript-legacy: passyarn format-check-cpp, and Prettier on the changed JS and TS: passRCTAccessibilityManagerTestsin RNTesterUnitTests: 5 tests pass. They replace the system setting readers, post the real UIKit notifications, and callgetCurrentPreferencesandgetRecommendedTimeoutMillis. They check the startup snapshot, that each setting's change sends the whole snapshot, that a notification without a change sends nothing, and the timeout with Switch Control on and off. Removing the On/Off Labels observer makes its test fail.On an iPhone 18 Pro simulator running iOS 27.0, I switched each setting in the Settings app with a throwaway XCUITest (not part of this PR). Then I read RNTester's Accessibility → "display options" rows. RNTester stayed running, so the "Last preferencesChanged" row could only update through the event.
preferencesChangedgetPreferences()afterwardsThe recommended-timeout row read "4000 ms" with Switch Control off. The row reads the value again whenever RNTester becomes active, because Switch Control has no change event.
Android: RNTester on an API 36 emulator shows "Preferences: switch labels off, non-color indicators off.", "Last preferencesChanged: none." and "Recommended timeout for 4000 ms: 4000 ms.", with no errors.
Not verified: the timeout with Switch Control running. The iOS simulator has no Switch Control, so it needs a physical device. The policy itself is unit-tested. I didn't run a SwiftPM build either, because this PR doesn't change linking or
Package.swift.