From be7c50fefd7f13201fb538ded93d91b374341173 Mon Sep 17 00:00:00 2001 From: Gabriel Donadel Dall'Agnol Date: Thu, 25 Aug 2022 10:45:15 -0700 Subject: [PATCH] feat: Add support for "Prefer Cross-Fade Transitions" into AccessibilityInfo (#34406) Summary: This PR adds `prefersCrossFadeTransitions()` to AccessibilityInfo in order to add support for "Prefer Cross-Fade Transitions", exposing the iOS settings option as proposed here https://github.com/react-native-community/discussions-and-proposals/issues/452. I believe this would be especially helpful for solving https://github.com/facebook/react-native/issues/31484 #### TODO - [ ] Submit react-native-web PR updating AccessibilityInfo documentation. ## Changelog [iOS] [Added] - Add support for "Prefer Cross-Fade Transitions" into AccessibilityInfo Pull Request resolved: https://github.com/facebook/react-native/pull/34406 Test Plan: **On iOS 14+** 1. Access Settings > "General" > "Accessibility" > "Reduce Motion", enable "Reduce Motion" then enable "Prefer Cross-Fade Transitions". 2. Open the RNTester app and navigate to the Accessibility page https://user-images.githubusercontent.com/11707729/154588402-7d050858-3c2d-4d86-9585-928b8c66941b.mov Reviewed By: cipolleschi Differential Revision: D38711316 Pulled By: makovkastar fbshipit-source-id: b9965cd4285f1aa0f1fa927080370a22329c2f62 --- .../AccessibilityInfo.flow.js | 10 +++++++ .../AccessibilityInfo/AccessibilityInfo.js | 28 +++++++++++++++++++ .../NativeAccessibilityManager.js | 4 +++ React/CoreModules/RCTAccessibilityManager.h | 1 + React/CoreModules/RCTAccessibilityManager.mm | 11 ++++++++ jest/setup.js | 1 + .../Accessibility/AccessibilityExample.js | 5 ++++ 7 files changed, 60 insertions(+) diff --git a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.flow.js b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.flow.js index 8b38c926507b6c..60c3ec53cd3f44 100644 --- a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.flow.js +++ b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.flow.js @@ -85,6 +85,16 @@ export interface AccessibilityInfo { */ isReduceMotionEnabled: () => Promise; + /** + * Query whether reduce motion and prefer cross-fade transitions settings are currently enabled. + * + * Returns a promise which resolves to a boolean. + * The result is `true` when prefer cross-fade transitions is enabled and `false` otherwise. + * + * See https://reactnative.dev/docs/accessibilityinfo#prefersCrossFadeTransitions + */ + prefersCrossFadeTransitions: () => Promise; + /** * Query whether reduced transparency is currently enabled. * diff --git a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js index dc13f6dcdcd40e..1f116ddcf1795e 100644 --- a/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js +++ b/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js @@ -179,6 +179,34 @@ const AccessibilityInfo: AccessibilityInfoType = { }); }, + /** + * Query whether reduce motion and prefer cross-fade transitions settings are currently enabled. + * + * Returns a promise which resolves to a boolean. + * The result is `true` when prefer cross-fade transitions is enabled and `false` otherwise. + * + * See https://reactnative.dev/docs/accessibilityinfo#prefersCrossFadeTransitions + */ + prefersCrossFadeTransitions(): Promise { + return new Promise((resolve, reject) => { + if (Platform.OS === 'android') { + return Promise.resolve(false); + } else { + if ( + NativeAccessibilityManagerIOS?.getCurrentPrefersCrossFadeTransitionsState != + null + ) { + NativeAccessibilityManagerIOS.getCurrentPrefersCrossFadeTransitionsState( + resolve, + reject, + ); + } else { + reject(null); + } + } + }); + }, + /** * Query whether reduced transparency is currently enabled. * diff --git a/Libraries/Components/AccessibilityInfo/NativeAccessibilityManager.js b/Libraries/Components/AccessibilityInfo/NativeAccessibilityManager.js index d4c400ac3e99c3..a8dfc7147e1ffb 100644 --- a/Libraries/Components/AccessibilityInfo/NativeAccessibilityManager.js +++ b/Libraries/Components/AccessibilityInfo/NativeAccessibilityManager.js @@ -28,6 +28,10 @@ export interface Spec extends TurboModule { onSuccess: (isReduceMotionEnabled: boolean) => void, onError: (error: Object) => void, ) => void; + +getCurrentPrefersCrossFadeTransitionsState?: ( + onSuccess: (prefersCrossFadeTransitions: boolean) => void, + onError: (error: Object) => void, + ) => void; +getCurrentReduceTransparencyState: ( onSuccess: (isReduceTransparencyEnabled: boolean) => void, onError: (error: Object) => void, diff --git a/React/CoreModules/RCTAccessibilityManager.h b/React/CoreModules/RCTAccessibilityManager.h index 77f7388aacc551..707d5766dd4c53 100644 --- a/React/CoreModules/RCTAccessibilityManager.h +++ b/React/CoreModules/RCTAccessibilityManager.h @@ -23,6 +23,7 @@ extern NSString *const RCTAccessibilityManagerDidUpdateMultiplierNotification; / @property (nonatomic, assign) BOOL isGrayscaleEnabled; @property (nonatomic, assign) BOOL isInvertColorsEnabled; @property (nonatomic, assign) BOOL isReduceMotionEnabled; +@property (nonatomic, assign) BOOL prefersCrossFadeTransitions; @property (nonatomic, assign) BOOL isReduceTransparencyEnabled; @property (nonatomic, assign) BOOL isVoiceOverEnabled; diff --git a/React/CoreModules/RCTAccessibilityManager.mm b/React/CoreModules/RCTAccessibilityManager.mm index 33b0501f694396..99c3d2ffef1101 100644 --- a/React/CoreModules/RCTAccessibilityManager.mm +++ b/React/CoreModules/RCTAccessibilityManager.mm @@ -358,6 +358,17 @@ static void setMultipliers( onSuccess(@[ @(_isReduceMotionEnabled) ]); } +RCT_EXPORT_METHOD(getCurrentPrefersCrossFadeTransitionsState + : (RCTResponseSenderBlock)onSuccess onError + : (__unused RCTResponseSenderBlock)onError) +{ + if (@available(iOS 14.0, *)) { + onSuccess(@[ @(UIAccessibilityPrefersCrossFadeTransitions()) ]); + } else { + onSuccess(@[ @(false) ]); + } +} + RCT_EXPORT_METHOD(getCurrentReduceTransparencyState : (RCTResponseSenderBlock)onSuccess onError : (__unused RCTResponseSenderBlock)onError) diff --git a/jest/setup.js b/jest/setup.js index 258948e851e4ed..e422cb64460d95 100644 --- a/jest/setup.js +++ b/jest/setup.js @@ -128,6 +128,7 @@ jest isGrayscaleEnabled: jest.fn(), isInvertColorsEnabled: jest.fn(), isReduceMotionEnabled: jest.fn(), + prefersCrossFadeTransitions: jest.fn(), isReduceTransparencyEnabled: jest.fn(), isScreenReaderEnabled: jest.fn(() => Promise.resolve(false)), setAccessibilityFocus: jest.fn(), diff --git a/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js b/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js index 271a3db44bc7af..e3c6e333300ea5 100644 --- a/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js +++ b/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js @@ -1183,6 +1183,11 @@ class DisplayOptionsStatusExample extends React.Component<{}> { optionChecker={AccessibilityInfo.isReduceMotionEnabled} notification={'reduceMotionChanged'} /> +