From 5889cbebe392dd19c6ce0cfd5fa1f725ece1060a Mon Sep 17 00:00:00 2001 From: Huzaifa Khan Date: Thu, 11 Mar 2021 12:00:16 -0800 Subject: [PATCH] Added talkback support for button accessibility: disabled prop (#31001) Summary: Issue # https://github.com/facebook/react-native/issues/30934 .When using a screen reader disabled buttons do not announce that they are disabled. ## Changelog [Android] [Changed] - Passing accessibility state in button so it can announce disabled in talkback Pull Request resolved: https://github.com/facebook/react-native/pull/31001 Test Plan: I have added Button in Button Example with accessibiltyState prop that will announce button is disabled when testing with talkback. ## Ios test I am unable to run ios project on my machine. RNTesterPods.xcworkspace gives workspace integrity error :/ Reviewed By: kacieb Differential Revision: D26492483 Pulled By: lunaleaps fbshipit-source-id: c4bbe8ca896b0d303976591c300ccac67a96ac73 --- Libraries/Components/Button.js | 23 +++++++++++++++---- .../js/examples/Button/ButtonExample.js | 23 +++++++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/Libraries/Components/Button.js b/Libraries/Components/Button.js index 9659a7135b..a235b375d0 100644 --- a/Libraries/Components/Button.js +++ b/Libraries/Components/Button.js @@ -18,9 +18,9 @@ const Text = require('../Text/Text'); const TouchableNativeFeedback = require('./Touchable/TouchableNativeFeedback'); const TouchableOpacity = require('./Touchable/TouchableOpacity'); const View = require('./View/View'); - const invariant = require('invariant'); +import type {AccessibilityState} from './View/ViewAccessibility'; import type {PressEvent} from '../Types/CoreEventTypes'; import type {ColorValue} from '../StyleSheet/StyleSheet'; @@ -134,6 +134,11 @@ type ButtonProps = $ReadOnly<{| Used to locate this view in end-to-end tests. */ testID?: ?string, + + /** + * Accessibility props. + */ + accessibilityState?: ?AccessibilityState, |}>; /** @@ -261,7 +266,6 @@ class Button extends React.Component { nextFocusLeft, nextFocusRight, nextFocusUp, - disabled, testID, } = this.props; const buttonStyles = [styles.button]; @@ -273,12 +277,22 @@ class Button extends React.Component { buttonStyles.push({backgroundColor: color}); } } - const accessibilityState = {}; + + const disabled = + this.props.disabled != null + ? this.props.disabled + : this.props.accessibilityState?.disabled; + + const accessibilityState = + disabled !== this.props.accessibilityState?.disabled + ? {...this.props.accessibilityState, disabled} + : this.props.accessibilityState; + if (disabled) { buttonStyles.push(styles.buttonDisabled); textStyles.push(styles.textDisabled); - accessibilityState.disabled = true; } + invariant( typeof title === 'string', 'The title prop of a Button must be a string', @@ -287,6 +301,7 @@ class Button extends React.Component { Platform.OS === 'android' ? title.toUpperCase() : title; const Touchable = Platform.OS === 'android' ? TouchableNativeFeedback : TouchableOpacity; + return ( + {theme => { + return ( +