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..f8878748eaefe3 100644 --- a/React/CoreModules/RCTAccessibilityManager.mm +++ b/React/CoreModules/RCTAccessibilityManager.mm @@ -358,6 +358,18 @@ 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'} /> +