Skip to content

Commit af3bee6

Browse files
Ariel Linfacebook-github-bot
authored andcommitted
add support for iOS "Darker System Colors" (Increase Contrast) setting 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
1 parent 7bb12eb commit af3bee6

7 files changed

Lines changed: 74 additions & 0 deletions

File tree

‎packages/react-native/Libraries/Components/AccessibilityInfo/AccessibilityInfo.d.ts‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type AccessibilityChangeEventName =
1717
| 'invertColorsChanged' // iOS-only Event
1818
| 'reduceMotionChanged'
1919
| 'highTextContrastChanged' // Android-only Event
20+
| 'darkerSystemColorsChanged' // iOS-only Event
2021
| 'screenReaderChanged'
2122
| 'reduceTransparencyChanged'; // iOS-only Event
2223

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

81+
/**
82+
* Query whether darker system colors is currently enabled.
83+
*
84+
* @platform ios
85+
*/
86+
isDarkerSystemColorsEnabled: () => Promise<boolean>;
87+
8088
/**
8189
* Query whether reduce motion and prefer cross-fade transitions settings are currently enabled.
8290
*

‎packages/react-native/Libraries/Components/AccessibilityInfo/AccessibilityInfo.js‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ type AccessibilityEventDefinitionsIOS = {
3131
grayscaleChanged: [boolean],
3232
invertColorsChanged: [boolean],
3333
reduceTransparencyChanged: [boolean],
34+
darkerSystemColorsChanged: [boolean],
3435
};
3536

3637
type AccessibilityEventDefinitions = {
@@ -64,6 +65,7 @@ const EventNames: Map<
6465
['reduceMotionChanged', 'reduceMotionChanged'],
6566
['reduceTransparencyChanged', 'reduceTransparencyChanged'],
6667
['screenReaderChanged', 'screenReaderChanged'],
68+
['darkerSystemColorsChanged', 'darkerSystemColorsChanged'],
6769
]);
6870

6971
/**
@@ -200,6 +202,32 @@ const AccessibilityInfo = {
200202
});
201203
},
202204

205+
/**
206+
* Query whether dark system colors is currently enabled. iOS only.
207+
*
208+
* Returns a promise which resolves to a boolean.
209+
* The result is `true` when dark system colors is enabled and `false` otherwise.
210+
*/
211+
isDarkerSystemColorsEnabled(): Promise<boolean> {
212+
return new Promise((resolve, reject) => {
213+
if (Platform.OS === 'android') {
214+
return Promise.resolve(false);
215+
} else {
216+
if (
217+
NativeAccessibilityManagerIOS?.getCurrentDarkerSystemColorsState !=
218+
null
219+
) {
220+
NativeAccessibilityManagerIOS.getCurrentDarkerSystemColorsState(
221+
resolve,
222+
reject,
223+
);
224+
} else {
225+
reject(null);
226+
}
227+
}
228+
});
229+
},
230+
203231
/**
204232
* Query whether reduce motion and prefer cross-fade transitions settings are currently enabled.
205233
*
@@ -340,6 +368,9 @@ const AccessibilityInfo = {
340368
* - `announcement`: The string announced by the screen reader.
341369
* - `success`: A boolean indicating whether the announcement was
342370
* successfully made.
371+
* - `darkerSystemColorsChanged`: iOS-only event. Fires when the state of the dark system colors
372+
* toggle changes. The argument to the event handler is a boolean. The boolean is `true` when
373+
* dark system colors is enabled and `false` otherwise.
343374
*
344375
* These events are only supported on Android:
345376
*

‎packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1583,6 +1583,7 @@ type AccessibilityEventDefinitionsIOS = {
15831583
grayscaleChanged: [boolean],
15841584
invertColorsChanged: [boolean],
15851585
reduceTransparencyChanged: [boolean],
1586+
darkerSystemColorsChanged: [boolean],
15861587
};
15871588
type AccessibilityEventDefinitions = {
15881589
...AccessibilityEventDefinitionsAndroid,
@@ -1598,6 +1599,7 @@ declare const AccessibilityInfo: {
15981599
isInvertColorsEnabled(): Promise<boolean>,
15991600
isReduceMotionEnabled(): Promise<boolean>,
16001601
isHighTextContrastEnabled(): Promise<boolean>,
1602+
isDarkerSystemColorsEnabled(): Promise<boolean>,
16011603
prefersCrossFadeTransitions(): Promise<boolean>,
16021604
isReduceTransparencyEnabled(): Promise<boolean>,
16031605
isScreenReaderEnabled(): Promise<boolean>,

‎packages/react-native/React/CoreModules/RCTAccessibilityManager.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ extern NSString *const RCTAccessibilityManagerDidUpdateMultiplierNotification; /
2424
@property (nonatomic, assign) BOOL isGrayscaleEnabled;
2525
@property (nonatomic, assign) BOOL isInvertColorsEnabled;
2626
@property (nonatomic, assign) BOOL isReduceMotionEnabled;
27+
@property (nonatomic, assign) BOOL isDarkerSystemColorsEnabled;
2728
@property (nonatomic, assign) BOOL prefersCrossFadeTransitions;
2829
@property (nonatomic, assign) BOOL isReduceTransparencyEnabled;
2930
@property (nonatomic, assign) BOOL isVoiceOverEnabled;

‎packages/react-native/React/CoreModules/RCTAccessibilityManager.mm‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ - (instancetype)init
7676
name:UIAccessibilityReduceMotionStatusDidChangeNotification
7777
object:nil];
7878

79+
[[NSNotificationCenter defaultCenter] addObserver:self
80+
selector:@selector(darkerSystemColorsDidChange:)
81+
name:UIAccessibilityDarkerSystemColorsStatusDidChangeNotification
82+
object:nil];
83+
7984
[[NSNotificationCenter defaultCenter] addObserver:self
8085
selector:@selector(reduceTransparencyStatusDidChange:)
8186
name:UIAccessibilityReduceTransparencyStatusDidChangeNotification
@@ -91,6 +96,7 @@ - (instancetype)init
9196
_isGrayscaleEnabled = UIAccessibilityIsGrayscaleEnabled();
9297
_isInvertColorsEnabled = UIAccessibilityIsInvertColorsEnabled();
9398
_isReduceMotionEnabled = UIAccessibilityIsReduceMotionEnabled();
99+
_isDarkerSystemColorsEnabled = UIAccessibilityDarkerSystemColorsEnabled();
94100
_isReduceTransparencyEnabled = UIAccessibilityIsReduceTransparencyEnabled();
95101
_isVoiceOverEnabled = UIAccessibilityIsVoiceOverRunning();
96102
}
@@ -169,6 +175,20 @@ - (void)reduceMotionStatusDidChange:(__unused NSNotification *)notification
169175
}
170176
}
171177

178+
- (void)darkerSystemColorsDidChange:(__unused NSNotification *)notification
179+
{
180+
BOOL newDarkerSystemColorsEnabled = UIAccessibilityDarkerSystemColorsEnabled();
181+
if (_isDarkerSystemColorsEnabled != newDarkerSystemColorsEnabled) {
182+
_isDarkerSystemColorsEnabled = newDarkerSystemColorsEnabled;
183+
#pragma clang diagnostic push
184+
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
185+
[[_moduleRegistry moduleForName:"EventDispatcher"] sendDeviceEventWithName:@"darkerSystemColorsChanged"
186+
body:@(_isDarkerSystemColorsEnabled)];
187+
188+
#pragma clang diagnostic pop
189+
}
190+
}
191+
172192
- (void)reduceTransparencyStatusDidChange:(__unused NSNotification *)notification
173193
{
174194
BOOL newReduceTransparencyEnabled = UIAccessibilityIsReduceTransparencyEnabled();
@@ -354,6 +374,13 @@ static void setMultipliers(
354374
onSuccess(@[ @(_isReduceMotionEnabled) ]);
355375
}
356376

377+
RCT_EXPORT_METHOD(getCurrentDarkerSystemColorsState
378+
: (RCTResponseSenderBlock)onSuccess onError
379+
: (__unused RCTResponseSenderBlock)onError)
380+
{
381+
onSuccess(@[ @(_isDarkerSystemColorsEnabled) ]);
382+
}
383+
357384
RCT_EXPORT_METHOD(getCurrentPrefersCrossFadeTransitionsState
358385
: (RCTResponseSenderBlock)onSuccess onError
359386
: (__unused RCTResponseSenderBlock)onError)

‎packages/react-native/jest/setup.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ jest
152152
isInvertColorsEnabled: jest.fn(() => Promise.resolve(false)),
153153
isReduceMotionEnabled: jest.fn(() => Promise.resolve(false)),
154154
isHighTextContrastEnabled: jest.fn(() => Promise.resolve(false)),
155+
isDarkerSystemColorsEnabled: jest.fn(() => Promise.resolve(false)),
155156
prefersCrossFadeTransitions: jest.fn(() => Promise.resolve(false)),
156157
isReduceTransparencyEnabled: jest.fn(() => Promise.resolve(false)),
157158
isScreenReaderEnabled: jest.fn(() => Promise.resolve(false)),

‎packages/react-native/src/private/specs/modules/NativeAccessibilityManager.js‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ export interface Spec extends TurboModule {
2929
onSuccess: (isReduceMotionEnabled: boolean) => void,
3030
onError: (error: Object) => void,
3131
) => void;
32+
+getCurrentDarkerSystemColorsState?: (
33+
onSuccess: (isDarkerSystemColorsEnabled: boolean) => void,
34+
onError: (error: Object) => void,
35+
) => void;
3236
+getCurrentPrefersCrossFadeTransitionsState?: (
3337
onSuccess: (prefersCrossFadeTransitions: boolean) => void,
3438
onError: (error: Object) => void,

0 commit comments

Comments
 (0)