Skip to content

Commit

Permalink
add support for iOS "Darker System Colors" (Increase Contrast) settin…
Browse files Browse the repository at this point in the history
…g into AccessibilityInfo (#46826)

Summary:
Pull Request resolved: #46826

This change adds `isDarkerSystemColorsEnabled()` to `AccessibilityInfo` to enable access to iOS's "Increase Contrast" setting option. It also adds a new event, `darkerSystemColorsChanged`, to enable listeners to subscribe to changes on this setting.

## Changelog

[iOS][Added] - Added `isDarkerSystemColorsEnabled()` to `AccessibilityInfo` to read "Increase Contrast" setting value

Reviewed By: cipolleschi

Differential Revision: D63880393

fbshipit-source-id: a476f8fc4d7354826bc344876b359eb1a3485f0d
  • Loading branch information
Ariel Lin authored and facebook-github-bot committed Oct 4, 2024
1 parent 7bb12eb commit af3bee6
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type AccessibilityChangeEventName =
| 'invertColorsChanged' // iOS-only Event
| 'reduceMotionChanged'
| 'highTextContrastChanged' // Android-only Event
| 'darkerSystemColorsChanged' // iOS-only Event
| 'screenReaderChanged'
| 'reduceTransparencyChanged'; // iOS-only Event

Expand Down Expand Up @@ -77,6 +78,13 @@ export interface AccessibilityInfoStatic {
*/
isHighTextContrastEnabled: () => Promise<boolean>;

/**
* Query whether darker system colors is currently enabled.
*
* @platform ios
*/
isDarkerSystemColorsEnabled: () => Promise<boolean>;

/**
* Query whether reduce motion and prefer cross-fade transitions settings are currently enabled.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type AccessibilityEventDefinitionsIOS = {
grayscaleChanged: [boolean],
invertColorsChanged: [boolean],
reduceTransparencyChanged: [boolean],
darkerSystemColorsChanged: [boolean],
};

type AccessibilityEventDefinitions = {
Expand Down Expand Up @@ -64,6 +65,7 @@ const EventNames: Map<
['reduceMotionChanged', 'reduceMotionChanged'],
['reduceTransparencyChanged', 'reduceTransparencyChanged'],
['screenReaderChanged', 'screenReaderChanged'],
['darkerSystemColorsChanged', 'darkerSystemColorsChanged'],
]);

/**
Expand Down Expand Up @@ -200,6 +202,32 @@ const AccessibilityInfo = {
});
},

/**
* Query whether dark system colors is currently enabled. iOS only.
*
* Returns a promise which resolves to a boolean.
* The result is `true` when dark system colors is enabled and `false` otherwise.
*/
isDarkerSystemColorsEnabled(): Promise<boolean> {
return new Promise((resolve, reject) => {
if (Platform.OS === 'android') {
return Promise.resolve(false);
} else {
if (
NativeAccessibilityManagerIOS?.getCurrentDarkerSystemColorsState !=
null
) {
NativeAccessibilityManagerIOS.getCurrentDarkerSystemColorsState(
resolve,
reject,
);
} else {
reject(null);
}
}
});
},

/**
* Query whether reduce motion and prefer cross-fade transitions settings are currently enabled.
*
Expand Down Expand Up @@ -340,6 +368,9 @@ const AccessibilityInfo = {
* - `announcement`: The string announced by the screen reader.
* - `success`: A boolean indicating whether the announcement was
* successfully made.
* - `darkerSystemColorsChanged`: iOS-only event. Fires when the state of the dark system colors
* toggle changes. The argument to the event handler is a boolean. The boolean is `true` when
* dark system colors is enabled and `false` otherwise.
*
* These events are only supported on Android:
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,7 @@ type AccessibilityEventDefinitionsIOS = {
grayscaleChanged: [boolean],
invertColorsChanged: [boolean],
reduceTransparencyChanged: [boolean],
darkerSystemColorsChanged: [boolean],
};
type AccessibilityEventDefinitions = {
...AccessibilityEventDefinitionsAndroid,
Expand All @@ -1598,6 +1599,7 @@ declare const AccessibilityInfo: {
isInvertColorsEnabled(): Promise<boolean>,
isReduceMotionEnabled(): Promise<boolean>,
isHighTextContrastEnabled(): Promise<boolean>,
isDarkerSystemColorsEnabled(): Promise<boolean>,
prefersCrossFadeTransitions(): Promise<boolean>,
isReduceTransparencyEnabled(): Promise<boolean>,
isScreenReaderEnabled(): Promise<boolean>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ extern NSString *const RCTAccessibilityManagerDidUpdateMultiplierNotification; /
@property (nonatomic, assign) BOOL isGrayscaleEnabled;
@property (nonatomic, assign) BOOL isInvertColorsEnabled;
@property (nonatomic, assign) BOOL isReduceMotionEnabled;
@property (nonatomic, assign) BOOL isDarkerSystemColorsEnabled;
@property (nonatomic, assign) BOOL prefersCrossFadeTransitions;
@property (nonatomic, assign) BOOL isReduceTransparencyEnabled;
@property (nonatomic, assign) BOOL isVoiceOverEnabled;
Expand Down
27 changes: 27 additions & 0 deletions packages/react-native/React/CoreModules/RCTAccessibilityManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ - (instancetype)init
name:UIAccessibilityReduceMotionStatusDidChangeNotification
object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(darkerSystemColorsDidChange:)
name:UIAccessibilityDarkerSystemColorsStatusDidChangeNotification
object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reduceTransparencyStatusDidChange:)
name:UIAccessibilityReduceTransparencyStatusDidChangeNotification
Expand All @@ -91,6 +96,7 @@ - (instancetype)init
_isGrayscaleEnabled = UIAccessibilityIsGrayscaleEnabled();
_isInvertColorsEnabled = UIAccessibilityIsInvertColorsEnabled();
_isReduceMotionEnabled = UIAccessibilityIsReduceMotionEnabled();
_isDarkerSystemColorsEnabled = UIAccessibilityDarkerSystemColorsEnabled();
_isReduceTransparencyEnabled = UIAccessibilityIsReduceTransparencyEnabled();
_isVoiceOverEnabled = UIAccessibilityIsVoiceOverRunning();
}
Expand Down Expand Up @@ -169,6 +175,20 @@ - (void)reduceMotionStatusDidChange:(__unused NSNotification *)notification
}
}

- (void)darkerSystemColorsDidChange:(__unused NSNotification *)notification
{
BOOL newDarkerSystemColorsEnabled = UIAccessibilityDarkerSystemColorsEnabled();
if (_isDarkerSystemColorsEnabled != newDarkerSystemColorsEnabled) {
_isDarkerSystemColorsEnabled = newDarkerSystemColorsEnabled;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[[_moduleRegistry moduleForName:"EventDispatcher"] sendDeviceEventWithName:@"darkerSystemColorsChanged"
body:@(_isDarkerSystemColorsEnabled)];

#pragma clang diagnostic pop
}
}

- (void)reduceTransparencyStatusDidChange:(__unused NSNotification *)notification
{
BOOL newReduceTransparencyEnabled = UIAccessibilityIsReduceTransparencyEnabled();
Expand Down Expand Up @@ -354,6 +374,13 @@ static void setMultipliers(
onSuccess(@[ @(_isReduceMotionEnabled) ]);
}

RCT_EXPORT_METHOD(getCurrentDarkerSystemColorsState
: (RCTResponseSenderBlock)onSuccess onError
: (__unused RCTResponseSenderBlock)onError)
{
onSuccess(@[ @(_isDarkerSystemColorsEnabled) ]);
}

RCT_EXPORT_METHOD(getCurrentPrefersCrossFadeTransitionsState
: (RCTResponseSenderBlock)onSuccess onError
: (__unused RCTResponseSenderBlock)onError)
Expand Down
1 change: 1 addition & 0 deletions packages/react-native/jest/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ jest
isInvertColorsEnabled: jest.fn(() => Promise.resolve(false)),
isReduceMotionEnabled: jest.fn(() => Promise.resolve(false)),
isHighTextContrastEnabled: jest.fn(() => Promise.resolve(false)),
isDarkerSystemColorsEnabled: jest.fn(() => Promise.resolve(false)),
prefersCrossFadeTransitions: jest.fn(() => Promise.resolve(false)),
isReduceTransparencyEnabled: jest.fn(() => Promise.resolve(false)),
isScreenReaderEnabled: jest.fn(() => Promise.resolve(false)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export interface Spec extends TurboModule {
onSuccess: (isReduceMotionEnabled: boolean) => void,
onError: (error: Object) => void,
) => void;
+getCurrentDarkerSystemColorsState?: (
onSuccess: (isDarkerSystemColorsEnabled: boolean) => void,
onError: (error: Object) => void,
) => void;
+getCurrentPrefersCrossFadeTransitionsState?: (
onSuccess: (prefersCrossFadeTransitions: boolean) => void,
onError: (error: Object) => void,
Expand Down

0 comments on commit af3bee6

Please sign in to comment.