Skip to content

Commit 3ec1253

Browse files
committed
Add high contrast API to AccessibilityInfo
1 parent d4530ee commit 3ec1253

File tree

7 files changed

+82
-4
lines changed

7 files changed

+82
-4
lines changed

Libraries/Components/AccessibilityInfo/AccessibilityInfo.android.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ const AccessibilityInfo = {
5252
return Promise.resolve(false);
5353
},
5454

55+
/**
56+
* macOS only
57+
*/
58+
isHighContrastEnabled: function(): Promise<boolean> {
59+
return Promise.resolve(false);
60+
},
61+
5562
/**
5663
* iOS only
5764
*/

Libraries/Components/AccessibilityInfo/AccessibilityInfo.ios.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@ const AccessibilityInfo = {
8585
});
8686
},
8787

88+
/**
89+
* macOS only
90+
*/
91+
isHighContrastEnabled: function(): Promise<boolean> {
92+
Promise.resolve(false);
93+
},
94+
8895
/**
8996
* Query whether inverted colors are currently enabled.
9097
*

Libraries/Components/AccessibilityInfo/AccessibilityInfo.macos.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const RCTDeviceEventEmitter = require('../../EventEmitter/RCTDeviceEventEmitter'
1818
import NativeAccessibilityManager from './NativeAccessibilityManager';
1919

2020
const CHANGE_EVENT_NAME = {
21+
highContrastChanged: 'highContrastChanged',
2122
invertColorsChanged: 'invertColorsChanged',
2223
reduceMotionChanged: 'reduceMotionChanged',
2324
reduceTransparencyChanged: 'reduceTransparencyChanged',
@@ -26,6 +27,7 @@ const CHANGE_EVENT_NAME = {
2627

2728
type ChangeEventName = $Keys<{
2829
change: string,
30+
highContrastChanged: string,
2931
invertColorsChanged: string,
3032
reduceMotionChanged: string,
3133
reduceTransparencyChanged: string,
@@ -58,6 +60,22 @@ const AccessibilityInfo = {
5860
return Promise.resolve(false);
5961
},
6062

63+
/**
64+
* Query whether high contrast is currently enabled.
65+
*
66+
* Returns a promise which resolves to a boolean.
67+
* The result is `true` when invert color is enabled and `false` otherwise.
68+
*/
69+
isHighContrastEnabled: function(): Promise<boolean> {
70+
return new Promise((resolve, reject) => {
71+
if (NativeAccessibilityManager) {
72+
NativeAccessibilityManager.getCurrentHighContrastState(resolve, reject);
73+
} else {
74+
reject(reject);
75+
}
76+
});
77+
},
78+
6179
/**
6280
* Query whether inverted colors are currently enabled.
6381
*

Libraries/Components/AccessibilityInfo/NativeAccessibilityManager.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ export interface Spec extends TurboModule {
2222
onSuccess: (isGrayscaleEnabled: boolean) => void,
2323
onError: (error: Object) => void,
2424
) => void;
25+
// [TODO(macOS ISS#2323203)
26+
+getCurrentHighContrastState: (
27+
onSuccess: (isHighContrastEnabled: boolean) => void,
28+
onError: (error: Object) => void,
29+
) => void;
30+
// ]TODO(macOS ISS#2323203)
2531
+getCurrentInvertColorsState: (
2632
onSuccess: (isInvertColorsEnabled: boolean) => void,
2733
onError: (error: Object) => void,

RNTester/js/examples/Accessibility/AccessibilityExample.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,16 @@ class DisplayOptionsStatusExample extends React.Component<{}> {
739739
state = {};
740740

741741
componentDidMount() {
742+
AccessibilityInfo.addEventListener(
743+
'highContrastChanged',
744+
this._handleHighContrastToggled,
745+
);
746+
AccessibilityInfo.isHighContrastEnabled().done(isEnabled => {
747+
this.setState({
748+
highContrastEnabled: isEnabled,
749+
});
750+
});
751+
742752
AccessibilityInfo.addEventListener(
743753
'invertColorsChanged',
744754
this._handleInvertColorsToggled,
@@ -771,6 +781,10 @@ class DisplayOptionsStatusExample extends React.Component<{}> {
771781
}
772782

773783
componentWillUnmount() {
784+
AccessibilityInfo.removeEventListener(
785+
'highContrastChanged',
786+
this._handleHighContrastToggled,
787+
);
774788
AccessibilityInfo.removeEventListener(
775789
'invertColorsChanged',
776790
this._handleInvertColorsToggled,
@@ -785,6 +799,12 @@ class DisplayOptionsStatusExample extends React.Component<{}> {
785799
);
786800
}
787801

802+
_handleHighContrastToggled = isEnabled => {
803+
this.setState({
804+
highContrastEnabled: isEnabled,
805+
});
806+
};
807+
788808
_handleInvertColorsToggled = isEnabled => {
789809
this.setState({
790810
invertColorsEnabled: isEnabled,
@@ -806,6 +826,12 @@ class DisplayOptionsStatusExample extends React.Component<{}> {
806826
render() {
807827
return (
808828
<View>
829+
<View>
830+
<Text>
831+
High contrast is{' '}
832+
{this.state.highContrastEnabled ? 'enabled' : 'disabled'}.
833+
</Text>
834+
</View>
809835
<View>
810836
<Text>
811837
Invert colors is{' '}

React/CoreModules/RCTAccessibilityManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ extern NSString *const RCTAccessibilityManagerDidUpdateMultiplierNotification; /
2121

2222
@property (nonatomic, assign) BOOL isBoldTextEnabled;
2323
@property (nonatomic, assign) BOOL isGrayscaleEnabled;
24+
@property (nonatomic, assign) BOOL isHighContrastEnabled; // TODO(macOS ISS#2323203)
2425
@property (nonatomic, assign) BOOL isInvertColorsEnabled;
2526
@property (nonatomic, assign) BOOL isReduceMotionEnabled;
2627
@property (nonatomic, assign) BOOL isReduceTransparencyEnabled;

React/Modules/MacOS/RCTAccessibilityManager.m

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ @implementation RCTAccessibilityManager
2323

2424
static void *AccessibilityVoiceOverChangeContext = &AccessibilityVoiceOverChangeContext;
2525

26-
+ (BOOL)requiresMainQueueSetup
26+
+ (BOOL)requiresMainQueueSetup
2727
{
2828
return NO;
2929
}
3030

31-
- (instancetype)init
31+
- (instancetype)init
3232
{
3333
if (self = [super init]) {
3434
[[NSWorkspace sharedWorkspace] addObserver:self
@@ -39,11 +39,11 @@ - (instancetype)init
3939
selector:@selector(accessibilityDisplayOptionsChange:)
4040
name:NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification
4141
object:nil];
42+
_isHighContrastEnabled = [[NSWorkspace sharedWorkspace] accessibilityDisplayShouldIncreaseContrast];
4243
_isInvertColorsEnabled = [[NSWorkspace sharedWorkspace] accessibilityDisplayShouldInvertColors];
4344
_isReduceMotionEnabled = [[NSWorkspace sharedWorkspace] accessibilityDisplayShouldReduceMotion];
4445
_isReduceTransparencyEnabled = [[NSWorkspace sharedWorkspace] accessibilityDisplayShouldReduceTransparency];
4546
_isVoiceOverEnabled = [[NSWorkspace sharedWorkspace] isVoiceOverEnabled];
46-
4747
}
4848
return self;
4949
}
@@ -53,7 +53,7 @@ - (void)dealloc
5353
[[NSWorkspace sharedWorkspace] removeObserver:self
5454
forKeyPath:@"voiceOverEnabled"
5555
context:AccessibilityVoiceOverChangeContext];
56-
[[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
56+
[[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
5757
}
5858

5959
RCT_EXPORT_METHOD(announceForAccessibility:(NSString *)announcement)
@@ -67,6 +67,12 @@ - (void)dealloc
6767
);
6868
}
6969

70+
RCT_EXPORT_METHOD(getCurrentHighContrastState:(RCTResponseSenderBlock)callback
71+
error:(__unused RCTResponseSenderBlock)error)
72+
{
73+
callback(@[@(_isHighContrastEnabled)]);
74+
}
75+
7076
RCT_EXPORT_METHOD(getCurrentInvertColorsState:(RCTResponseSenderBlock)callback
7177
error:(__unused RCTResponseSenderBlock)error)
7278
{
@@ -124,9 +130,16 @@ - (void)observeValueForKeyPath:(NSString *)keyPath
124130

125131
- (void)accessibilityDisplayOptionsChange:(NSNotification *)notification
126132
{
133+
BOOL newHighContrastEnabled = [[NSWorkspace sharedWorkspace] accessibilityDisplayShouldIncreaseContrast];
127134
BOOL newInvertColorsEnabled = [[NSWorkspace sharedWorkspace] accessibilityDisplayShouldInvertColors];
128135
BOOL newReduceMotionEnabled = [[NSWorkspace sharedWorkspace] accessibilityDisplayShouldReduceMotion];
129136
BOOL newReduceTransparencyEnabled = [[NSWorkspace sharedWorkspace] accessibilityDisplayShouldReduceTransparency];
137+
138+
if (_isHighContrastEnabled != newHighContrastEnabled) {
139+
_isHighContrastEnabled = newHighContrastEnabled;
140+
[_bridge.eventDispatcher sendDeviceEventWithName:@"highContrastChanged"
141+
body:@(_isHighContrastEnabled)];
142+
}
130143
if (_isInvertColorsEnabled != newInvertColorsEnabled) {
131144
_isInvertColorsEnabled = newInvertColorsEnabled;
132145
[_bridge.eventDispatcher sendDeviceEventWithName:@"invertColorsChanged"

0 commit comments

Comments
 (0)