Skip to content

Commit ea609de

Browse files
chakrihackerfacebook-github-bot
authored andcommitted
Disable TouchableOpacity when accessibility disabled is set (#31108)
Summary: When using a screen reader the TouchableOpacity component disables click functionality. Fixes Issue #30951 ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> [Android] [Changed] - Message Pull Request resolved: #31108 Test Plan: Added Exmple to Accessibility Reviewed By: yungsters Differential Revision: D28334356 Pulled By: kacieb fbshipit-source-id: 3a3e8efaf57272d2091392f6d7d3e0ba0f2a9adc
1 parent cdd0256 commit ea609de

File tree

4 files changed

+105
-6
lines changed

4 files changed

+105
-6
lines changed

Libraries/Components/Touchable/TouchableOpacity.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ class TouchableOpacity extends React.Component<Props, State> {
137137
_createPressabilityConfig(): PressabilityConfig {
138138
return {
139139
cancelable: !this.props.rejectResponderTermination,
140-
disabled: this.props.disabled,
140+
disabled: this.props.disabled ?? this.props.accessibilityState?.disabled,
141141
hitSlop: this.props.hitSlop,
142142
delayLongPress: this.props.delayLongPress,
143143
delayPressIn: this.props.delayPressIn,
@@ -215,13 +215,21 @@ class TouchableOpacity extends React.Component<Props, State> {
215215
...eventHandlersWithoutBlurAndFocus
216216
} = this.state.pressability.getEventHandlers();
217217

218+
const accessibilityState =
219+
this.props.disabled != null
220+
? {
221+
...this.props.accessibilityState,
222+
disabled: this.props.disabled,
223+
}
224+
: this.props.accessibilityState;
225+
218226
return (
219227
<Animated.View
220228
accessible={this.props.accessible !== false}
221229
accessibilityLabel={this.props.accessibilityLabel}
222230
accessibilityHint={this.props.accessibilityHint}
223231
accessibilityRole={this.props.accessibilityRole}
224-
accessibilityState={this.props.accessibilityState}
232+
accessibilityState={accessibilityState}
225233
accessibilityActions={this.props.accessibilityActions}
226234
onAccessibilityAction={this.props.onAccessibilityAction}
227235
accessibilityValue={this.props.accessibilityValue}

Libraries/Components/Touchable/__tests__/TouchableOpacity-test.js

+23-4
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,34 @@
1111
'use strict';
1212

1313
const React = require('react');
14+
const ReactTestRenderer = require('react-test-renderer');
1415
const Text = require('../../../Text/Text');
1516
const TouchableOpacity = require('../TouchableOpacity');
1617

17-
const render = require('../../../../jest/renderer');
18-
1918
describe('TouchableOpacity', () => {
2019
it('renders correctly', () => {
21-
const instance = render.create(
22-
<TouchableOpacity style={{}}>
20+
const instance = ReactTestRenderer.create(
21+
<TouchableOpacity>
22+
<Text>Touchable</Text>
23+
</TouchableOpacity>,
24+
);
25+
26+
expect(instance.toJSON()).toMatchSnapshot();
27+
});
28+
29+
it('renders in disabled state when a disabled prop is passed', () => {
30+
const instance = ReactTestRenderer.create(
31+
<TouchableOpacity disabled={true}>
32+
<Text>Touchable</Text>
33+
</TouchableOpacity>,
34+
);
35+
36+
expect(instance.toJSON()).toMatchSnapshot();
37+
});
38+
39+
it('renders in disabled state when a key disabled in accessibilityState is passed', () => {
40+
const instance = ReactTestRenderer.create(
41+
<TouchableOpacity accessibilityState={{disabled: true}}>
2342
<Text>Touchable</Text>
2443
</TouchableOpacity>,
2544
);

Libraries/Components/Touchable/__tests__/__snapshots__/TouchableOpacity-test.js.snap

+60
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,63 @@ exports[`TouchableOpacity renders correctly 1`] = `
2424
</Text>
2525
</View>
2626
`;
27+
28+
exports[`TouchableOpacity renders in disabled state when a disabled prop is passed 1`] = `
29+
<View
30+
accessibilityState={
31+
Object {
32+
"disabled": true,
33+
}
34+
}
35+
accessible={true}
36+
collapsable={false}
37+
focusable={false}
38+
nativeID="animatedComponent"
39+
onClick={[Function]}
40+
onResponderGrant={[Function]}
41+
onResponderMove={[Function]}
42+
onResponderRelease={[Function]}
43+
onResponderTerminate={[Function]}
44+
onResponderTerminationRequest={[Function]}
45+
onStartShouldSetResponder={[Function]}
46+
style={
47+
Object {
48+
"opacity": 1,
49+
}
50+
}
51+
>
52+
<Text>
53+
Touchable
54+
</Text>
55+
</View>
56+
`;
57+
58+
exports[`TouchableOpacity renders in disabled state when a key disabled in accessibilityState is passed 1`] = `
59+
<View
60+
accessibilityState={
61+
Object {
62+
"disabled": true,
63+
}
64+
}
65+
accessible={true}
66+
collapsable={false}
67+
focusable={false}
68+
nativeID="animatedComponent"
69+
onClick={[Function]}
70+
onResponderGrant={[Function]}
71+
onResponderMove={[Function]}
72+
onResponderRelease={[Function]}
73+
onResponderTerminate={[Function]}
74+
onResponderTerminationRequest={[Function]}
75+
onStartShouldSetResponder={[Function]}
76+
style={
77+
Object {
78+
"opacity": 1,
79+
}
80+
}
81+
>
82+
<Text>
83+
Touchable
84+
</Text>
85+
</View>
86+
`;

packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js

+12
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,18 @@ class AccessibilityExample extends React.Component<{}> {
161161
</TouchableOpacity>
162162
</RNTesterBlock>
163163

164+
<RNTesterBlock title="Disabled TouchableOpacity">
165+
<TouchableOpacity
166+
onPress={() => Alert.alert('Disabled Button has been pressed!')}
167+
accessibilityLabel={'You are pressing Disabled TouchableOpacity'}
168+
accessibilityState={{disabled: true}}>
169+
<View>
170+
<Text>
171+
I am disabled. Clicking me will not trigger any action.
172+
</Text>
173+
</View>
174+
</TouchableOpacity>
175+
</RNTesterBlock>
164176
<RNTesterBlock title="View with multiple states">
165177
<View
166178
accessible={true}

0 commit comments

Comments
 (0)