From 88f2356eedf71183d02cde0826c8a0c6910f83dd Mon Sep 17 00:00:00 2001 From: Kazuki Yamashiro Date: Fri, 2 Apr 2021 17:10:45 -0700 Subject: [PATCH] Added talkback support for TouchableNativeFeedback accessibility: disabled prop (#31224) Summary: Issue https://github.com/facebook/react-native/issues/30952 Add talkback support for TouchableNativeFeedback component. ## Changelog [Android] [Changed] - TouchableNativeFeedback: sync disabled prop with accessibilityState Pull Request resolved: https://github.com/facebook/react-native/pull/31224 Test Plan: I have checked that talkback and disabled works properly on the actual device(Pixel4a Android11). ```jsx /** * Sample React Native App * https://github.com/facebook/react-native * * format * flow strict-local */ import * as React from 'react'; import { Text, View, StyleSheet, TouchableNativeFeedback, Alert, } from 'react-native'; export default function App() { const onPress = () => Alert.alert('test'); return ( {/*not disabled, voice:double tap to activate*/} talkback OK {/*disabled, voice:disabled*/} should be disabled when disabled is true {/*disabled, voice:disabled*/} should be disabled when accessibilityState disabled is true {/*disabled, voice:disabled*/} should be disabled when disabled is true and accessibilityState is empty {/*disabled, voice:disabled*/} should keep accessibilityState when disabled is true {/*disabled, voice:disabled*/} should overwrite accessibilityState with value of disabled prop {/*not disabled, voice:double tap to activate*/} should overwrite accessibilityState with value of disabled prop ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', padding: 16, }, touchable: {flex: 0.5, borderColor: 'black', borderWidth: 1, marginBottom: 8}, text: {alignSelf: 'center'}, }); ``` Reviewed By: yungsters Differential Revision: D27479271 Pulled By: kacieb fbshipit-source-id: 43187839b58dfe8f91afdba91453fb6b98e1a604 --- .../Touchable/TouchableNativeFeedback.js | 15 ++- .../__tests__/TouchableNativeFeedback-test.js | 86 +++++++++++++- .../TouchableNativeFeedback-test.js.snap | 110 ++++++++++++++++++ 3 files changed, 206 insertions(+), 5 deletions(-) diff --git a/Libraries/Components/Touchable/TouchableNativeFeedback.js b/Libraries/Components/Touchable/TouchableNativeFeedback.js index e18b625ab868c2..8c1ad218fb4809 100644 --- a/Libraries/Components/Touchable/TouchableNativeFeedback.js +++ b/Libraries/Components/Touchable/TouchableNativeFeedback.js @@ -168,7 +168,10 @@ class TouchableNativeFeedback extends React.Component { _createPressabilityConfig(): PressabilityConfig { return { cancelable: !this.props.rejectResponderTermination, - disabled: this.props.disabled, + disabled: + this.props.disabled != null + ? this.props.disabled + : this.props.accessibilityState?.disabled, hitSlop: this.props.hitSlop, delayLongPress: this.props.delayLongPress, delayPressIn: this.props.delayPressIn, @@ -255,6 +258,14 @@ class TouchableNativeFeedback extends React.Component { ...eventHandlersWithoutBlurAndFocus } = this.state.pressability.getEventHandlers(); + const accessibilityState = + this.props.disabled != null + ? { + ...this.props.accessibilityState, + disabled: this.props.disabled, + } + : this.props.accessibilityState; + return React.cloneElement( element, { @@ -269,7 +280,7 @@ class TouchableNativeFeedback extends React.Component { accessibilityHint: this.props.accessibilityHint, accessibilityLabel: this.props.accessibilityLabel, accessibilityRole: this.props.accessibilityRole, - accessibilityState: this.props.accessibilityState, + accessibilityState: accessibilityState, accessibilityActions: this.props.accessibilityActions, onAccessibilityAction: this.props.onAccessibilityAction, accessibilityValue: this.props.accessibilityValue, diff --git a/Libraries/Components/Touchable/__tests__/TouchableNativeFeedback-test.js b/Libraries/Components/Touchable/__tests__/TouchableNativeFeedback-test.js index 766912665d6d6b..237b1a22745cb9 100644 --- a/Libraries/Components/Touchable/__tests__/TouchableNativeFeedback-test.js +++ b/Libraries/Components/Touchable/__tests__/TouchableNativeFeedback-test.js @@ -10,9 +10,11 @@ 'use strict'; -const React = require('react'); -const Text = require('../../../Text/Text'); -const TouchableNativeFeedback = require('../TouchableNativeFeedback'); +import * as React from 'react'; +import ReactTestRenderer from 'react-test-renderer'; +import Text from '../../../Text/Text'; +import TouchableNativeFeedback from '../TouchableNativeFeedback'; +import View from '../../View/View'; const render = require('../../../../jest/renderer'); @@ -33,3 +35,81 @@ describe('TouchableWithoutFeedback', () => { ); }); }); + +describe('', () => { + it('should render as expected', () => { + const instance = ReactTestRenderer.create( + + + , + ); + + expect(instance.toJSON()).toMatchSnapshot(); + }); +}); + +describe('', () => { + it('should be disabled when disabled is true', () => { + expect( + ReactTestRenderer.create( + + + , + ), + ).toMatchSnapshot(); + }); +}); + +describe('', () => { + it('should be disabled when disabled is true and accessibilityState is empty', () => { + expect( + ReactTestRenderer.create( + + + , + ), + ).toMatchSnapshot(); + }); +}); + +describe('', () => { + it('should keep accessibilityState when disabled is true', () => { + expect( + ReactTestRenderer.create( + + + , + ), + ).toMatchSnapshot(); + }); +}); + +describe('', () => { + it('should overwrite accessibilityState with value of disabled prop', () => { + expect( + ReactTestRenderer.create( + + + , + ), + ).toMatchSnapshot(); + }); +}); + +describe('', () => { + it('should overwrite accessibilityState with value of disabled prop', () => { + expect( + ReactTestRenderer.create( + + + , + ), + ).toMatchSnapshot(); + }); +}); diff --git a/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableNativeFeedback-test.js.snap b/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableNativeFeedback-test.js.snap index 27c69f493086da..64b098803b11c3 100644 --- a/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableNativeFeedback-test.js.snap +++ b/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableNativeFeedback-test.js.snap @@ -15,3 +15,113 @@ exports[`TouchableWithoutFeedback renders correctly 1`] = ` Touchable `; + +exports[` should render as expected 1`] = ` + +`; + +exports[` should be disabled when disabled is true 1`] = ` + +`; + +exports[` should be disabled when disabled is true and accessibilityState is empty 1`] = ` + +`; + +exports[` should keep accessibilityState when disabled is true 1`] = ` + +`; + +exports[` should overwrite accessibilityState with value of disabled prop 1`] = ` + +`; + +exports[` should overwrite accessibilityState with value of disabled prop 1`] = ` + +`;