mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Adds accessiblity actions on core components (#31532)
Summary: Android: Adding custom actions (https://github.com/facebook/react-native/issues/30854). Adds accessiblity actions on core components (Button, TextInput, Text, and Picker). ## Changelog [General] [Added] - Adds accessiblity actions on core components Pull Request resolved: https://github.com/facebook/react-native/pull/31532 Test Plan: - `npm test` - Rendering of components on `RNTesterApp` using talkback: - Check if accessibility actions were available;  - Trigger `activate` action for all components;  ## Notes - For `TextInput` an unexpected error is raised:  Reviewed By: kacieb Differential Revision: D28654294 Pulled By: lunaleaps fbshipit-source-id: 80dd3f3c7aa27bbaf16ef12997e8f55952a02eb2
This commit is contained in:
committed by
Facebook GitHub Bot
parent
52b51f0886
commit
44717152ca
@@ -20,7 +20,11 @@ import TouchableOpacity from './Touchable/TouchableOpacity';
|
||||
import View from './View/View';
|
||||
import invariant from 'invariant';
|
||||
|
||||
import type {AccessibilityState} from './View/ViewAccessibility';
|
||||
import type {
|
||||
AccessibilityState,
|
||||
AccessibilityActionEvent,
|
||||
AccessibilityActionInfo,
|
||||
} from './View/ViewAccessibility';
|
||||
import type {PressEvent} from '../Types/CoreEventTypes';
|
||||
|
||||
type ButtonProps = $ReadOnly<{|
|
||||
@@ -137,6 +141,9 @@ type ButtonProps = $ReadOnly<{|
|
||||
/**
|
||||
* Accessibility props.
|
||||
*/
|
||||
accessible?: ?boolean,
|
||||
accessibilityActions?: ?$ReadOnlyArray<AccessibilityActionInfo>,
|
||||
onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed,
|
||||
accessibilityState?: ?AccessibilityState,
|
||||
|}>;
|
||||
|
||||
@@ -266,6 +273,9 @@ class Button extends React.Component<ButtonProps> {
|
||||
nextFocusRight,
|
||||
nextFocusUp,
|
||||
testID,
|
||||
accessible,
|
||||
accessibilityActions,
|
||||
onAccessibilityAction,
|
||||
} = this.props;
|
||||
const buttonStyles = [styles.button];
|
||||
const textStyles = [styles.text];
|
||||
@@ -303,6 +313,9 @@ class Button extends React.Component<ButtonProps> {
|
||||
|
||||
return (
|
||||
<Touchable
|
||||
accessible={accessible}
|
||||
accessibilityActions={accessibilityActions}
|
||||
onAccessibilityAction={onAccessibilityAction}
|
||||
accessibilityLabel={accessibilityLabel}
|
||||
accessibilityRole="button"
|
||||
accessibilityState={accessibilityState}
|
||||
|
||||
@@ -18,6 +18,11 @@ import UnimplementedView from '../UnimplementedViews/UnimplementedView';
|
||||
|
||||
import type {TextStyleProp, ColorValue} from '../../StyleSheet/StyleSheet';
|
||||
|
||||
import type {
|
||||
AccessibilityActionEvent,
|
||||
AccessibilityActionInfo,
|
||||
} from '../View/ViewAccessibility';
|
||||
|
||||
const MODE_DIALOG = 'dialog';
|
||||
const MODE_DROPDOWN = 'dropdown';
|
||||
|
||||
@@ -115,6 +120,27 @@ type PickerProps = $ReadOnly<{|
|
||||
* The string used for the accessibility label. Will be read once focused on the picker but not on change.
|
||||
*/
|
||||
accessibilityLabel?: ?string,
|
||||
|
||||
/**
|
||||
* When `true`, indicates that the view is an accessibility element.
|
||||
* By default, all the touchable elements are accessible.
|
||||
*
|
||||
* See https://reactnative.dev/docs/view.html#accessible
|
||||
*/
|
||||
accessible?: ?boolean,
|
||||
|
||||
/**
|
||||
* Provides an array of custom actions available for accessibility.
|
||||
*
|
||||
*/
|
||||
accessibilityActions?: ?$ReadOnlyArray<AccessibilityActionInfo>,
|
||||
|
||||
/**
|
||||
* When `accessible` is true, the system will try to invoke this function
|
||||
* when the user performs an accessibility custom action.
|
||||
*
|
||||
*/
|
||||
onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed,
|
||||
|}>;
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,6 +19,11 @@ import StyleSheet from '../../StyleSheet/StyleSheet';
|
||||
import invariant from 'invariant';
|
||||
import processColor from '../../StyleSheet/processColor';
|
||||
|
||||
import type {
|
||||
AccessibilityActionEvent,
|
||||
AccessibilityActionInfo,
|
||||
} from '../View/ViewAccessibility';
|
||||
|
||||
import type {SyntheticEvent} from '../../Types/CoreEventTypes';
|
||||
import type {ColorValue, TextStyleProp} from '../../StyleSheet/StyleSheet';
|
||||
|
||||
@@ -31,6 +36,9 @@ type PickerItemSelectSyntheticEvent = SyntheticEvent<
|
||||
type PickerItemValue = number | string;
|
||||
|
||||
type Props = $ReadOnly<{|
|
||||
accessible?: ?boolean,
|
||||
accessibilityActions?: ?$ReadOnlyArray<AccessibilityActionInfo>,
|
||||
onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed,
|
||||
accessibilityLabel?: ?Stringish,
|
||||
children?: React.Node,
|
||||
style?: ?TextStyleProp,
|
||||
@@ -111,6 +119,9 @@ function PickerAndroid(props: Props): React.Node {
|
||||
);
|
||||
|
||||
const rootProps = {
|
||||
accessible: props.accessible,
|
||||
accessibilityActions: props.accessibilityActions,
|
||||
onAccessibilityAction: props.onAccessibilityAction,
|
||||
accessibilityLabel: props.accessibilityLabel,
|
||||
enabled: props.enabled,
|
||||
items,
|
||||
|
||||
@@ -20,6 +20,8 @@ import type {TextStyleProp} from '../StyleSheet/StyleSheet';
|
||||
import type {
|
||||
AccessibilityRole,
|
||||
AccessibilityState,
|
||||
AccessibilityActionInfo,
|
||||
AccessibilityActionEvent,
|
||||
} from '../Components/View/ViewAccessibility';
|
||||
|
||||
export type PressRetentionOffset = $ReadOnly<{|
|
||||
@@ -39,6 +41,8 @@ export type TextProps = $ReadOnly<{|
|
||||
* See https://reactnative.dev/docs/text.html#accessible
|
||||
*/
|
||||
accessible?: ?boolean,
|
||||
accessibilityActions?: ?$ReadOnlyArray<AccessibilityActionInfo>,
|
||||
onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed,
|
||||
accessibilityHint?: ?Stringish,
|
||||
accessibilityLabel?: ?Stringish,
|
||||
accessibilityRole?: ?AccessibilityRole,
|
||||
|
||||
@@ -23,6 +23,7 @@ const {
|
||||
Alert,
|
||||
StyleSheet,
|
||||
Slider,
|
||||
Picker,
|
||||
Platform,
|
||||
} = require('react-native');
|
||||
import type {EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter';
|
||||
@@ -664,7 +665,7 @@ class AccessibilityActionsExample extends React.Component<{}> {
|
||||
</View>
|
||||
</RNTesterBlock>
|
||||
|
||||
<RNTesterBlock title="Button with custom accessibility actions">
|
||||
<RNTesterBlock title="TouchableWithoutFeedback with custom accessibility actions">
|
||||
<TouchableWithoutFeedback
|
||||
accessible={true}
|
||||
accessibilityActions={[
|
||||
@@ -692,6 +693,70 @@ class AccessibilityActionsExample extends React.Component<{}> {
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
</RNTesterBlock>
|
||||
|
||||
<RNTesterBlock title="Button with accessibility actions">
|
||||
<Button
|
||||
accessible={true}
|
||||
accessibilityActions={[
|
||||
{name: 'activate', label: 'activate label'},
|
||||
{name: 'copy', label: 'copy label'},
|
||||
]}
|
||||
onAccessibilityAction={event => {
|
||||
switch (event.nativeEvent.actionName) {
|
||||
case 'activate':
|
||||
Alert.alert('Alert', 'Activate accessiblity action');
|
||||
break;
|
||||
case 'copy':
|
||||
Alert.alert('Alert', 'copy action success');
|
||||
break;
|
||||
}
|
||||
}}
|
||||
onPress={() => Alert.alert('Button has been pressed!')}
|
||||
title="Button with accessiblity action"
|
||||
/>
|
||||
</RNTesterBlock>
|
||||
|
||||
<RNTesterBlock title="Text with custom accessibility actions">
|
||||
<Text
|
||||
accessible={true}
|
||||
accessibilityActions={[
|
||||
{name: 'activate', label: 'activate label'},
|
||||
{name: 'copy', label: 'copy label'},
|
||||
]}
|
||||
onAccessibilityAction={event => {
|
||||
switch (event.nativeEvent.actionName) {
|
||||
case 'activate':
|
||||
Alert.alert('Alert', 'Activate accessiblity action');
|
||||
break;
|
||||
case 'copy':
|
||||
Alert.alert('Alert', 'copy action success');
|
||||
break;
|
||||
}
|
||||
}}>
|
||||
Text
|
||||
</Text>
|
||||
</RNTesterBlock>
|
||||
|
||||
<RNTesterBlock title="Picker with accessibility actions">
|
||||
<Picker
|
||||
accessible={true}
|
||||
accessibilityActions={[
|
||||
{name: 'activate', label: 'activate label'},
|
||||
{name: 'copy', label: 'copy label'},
|
||||
]}
|
||||
onAccessibilityAction={event => {
|
||||
switch (event.nativeEvent.actionName) {
|
||||
case 'activate':
|
||||
Alert.alert('Alert', 'Activate accessiblity action');
|
||||
break;
|
||||
case 'copy':
|
||||
Alert.alert('Alert', 'copy action success');
|
||||
break;
|
||||
}
|
||||
}}>
|
||||
<Picker.Item label="Item 1" value="item1" />
|
||||
</Picker>
|
||||
</RNTesterBlock>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user