Skip to content

Commit

Permalink
Disable TouchableOpacity when accessibility disabled is set (#31108)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
chakrihacker authored and facebook-github-bot committed May 18, 2021
1 parent cdd0256 commit ea609de
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 6 deletions.
12 changes: 10 additions & 2 deletions Libraries/Components/Touchable/TouchableOpacity.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ class TouchableOpacity extends React.Component<Props, State> {
_createPressabilityConfig(): PressabilityConfig {
return {
cancelable: !this.props.rejectResponderTermination,
disabled: this.props.disabled,
disabled: this.props.disabled ?? this.props.accessibilityState?.disabled,
hitSlop: this.props.hitSlop,
delayLongPress: this.props.delayLongPress,
delayPressIn: this.props.delayPressIn,
Expand Down Expand Up @@ -215,13 +215,21 @@ class TouchableOpacity extends React.Component<Props, State> {
...eventHandlersWithoutBlurAndFocus
} = this.state.pressability.getEventHandlers();

const accessibilityState =
this.props.disabled != null
? {
...this.props.accessibilityState,
disabled: this.props.disabled,
}
: this.props.accessibilityState;

return (
<Animated.View
accessible={this.props.accessible !== false}
accessibilityLabel={this.props.accessibilityLabel}
accessibilityHint={this.props.accessibilityHint}
accessibilityRole={this.props.accessibilityRole}
accessibilityState={this.props.accessibilityState}
accessibilityState={accessibilityState}
accessibilityActions={this.props.accessibilityActions}
onAccessibilityAction={this.props.onAccessibilityAction}
accessibilityValue={this.props.accessibilityValue}
Expand Down
27 changes: 23 additions & 4 deletions Libraries/Components/Touchable/__tests__/TouchableOpacity-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,34 @@
'use strict';

const React = require('react');
const ReactTestRenderer = require('react-test-renderer');
const Text = require('../../../Text/Text');
const TouchableOpacity = require('../TouchableOpacity');

const render = require('../../../../jest/renderer');

describe('TouchableOpacity', () => {
it('renders correctly', () => {
const instance = render.create(
<TouchableOpacity style={{}}>
const instance = ReactTestRenderer.create(
<TouchableOpacity>
<Text>Touchable</Text>
</TouchableOpacity>,
);

expect(instance.toJSON()).toMatchSnapshot();
});

it('renders in disabled state when a disabled prop is passed', () => {
const instance = ReactTestRenderer.create(
<TouchableOpacity disabled={true}>
<Text>Touchable</Text>
</TouchableOpacity>,
);

expect(instance.toJSON()).toMatchSnapshot();
});

it('renders in disabled state when a key disabled in accessibilityState is passed', () => {
const instance = ReactTestRenderer.create(
<TouchableOpacity accessibilityState={{disabled: true}}>
<Text>Touchable</Text>
</TouchableOpacity>,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,63 @@ exports[`TouchableOpacity renders correctly 1`] = `
</Text>
</View>
`;

exports[`TouchableOpacity renders in disabled state when a disabled prop is passed 1`] = `
<View
accessibilityState={
Object {
"disabled": true,
}
}
accessible={true}
collapsable={false}
focusable={false}
nativeID="animatedComponent"
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
}
}
>
<Text>
Touchable
</Text>
</View>
`;

exports[`TouchableOpacity renders in disabled state when a key disabled in accessibilityState is passed 1`] = `
<View
accessibilityState={
Object {
"disabled": true,
}
}
accessible={true}
collapsable={false}
focusable={false}
nativeID="animatedComponent"
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
Object {
"opacity": 1,
}
}
>
<Text>
Touchable
</Text>
</View>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,18 @@ class AccessibilityExample extends React.Component<{}> {
</TouchableOpacity>
</RNTesterBlock>

<RNTesterBlock title="Disabled TouchableOpacity">
<TouchableOpacity
onPress={() => Alert.alert('Disabled Button has been pressed!')}
accessibilityLabel={'You are pressing Disabled TouchableOpacity'}
accessibilityState={{disabled: true}}>
<View>
<Text>
I am disabled. Clicking me will not trigger any action.
</Text>
</View>
</TouchableOpacity>
</RNTesterBlock>
<RNTesterBlock title="View with multiple states">
<View
accessible={true}
Expand Down

0 comments on commit ea609de

Please sign in to comment.