Skip to content

Commit b8ccb26

Browse files
KevinGVargasfacebook-github-bot
authored andcommitted
Added button with accessibility action example and support for Touchables (react#25582)
Summary: We added a test to make sure button and accessibility actions would not have unwanted behavior. Additionally we added support for accessibility actions for all touchables. However we discovered that RCTTextView and possibly anything else that does not derive from RCTView does not support accessibility actions and need to be children off a component that does support it for it to not crash in ios. This became noticeable when TouchableWithoutFeedback only worked if text is a child of view on ios. In a local branch we where able to modify RCTTextView to support accessibility actions and text no longer needed to be a child of view for it to work. ## Changelog [General] [Added] - Button test with accessibility actions [General] [Added] - Support for accessibility actions to all Touchables. With TouchableWithoutFeedback being a special case where text must be a child of view. (See AccessibilityExample.js for an example) Pull Request resolved: react#25582 Test Plan: Test plan is testing in RNTester making sure the examples work ## Open Question What would you say is the best practice for adding accessibility action support for all the components that do not extended from RCTView? Reviewed By: cpojer Differential Revision: D16192919 Pulled By: osdnk fbshipit-source-id: 7d4e186ba1f30393f2b4d08a0e227b960f83586c
1 parent fdd8deb commit b8ccb26

6 files changed

Lines changed: 46 additions & 0 deletions

File tree

Libraries/Components/Touchable/TouchableBounce.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ const TouchableBounce = ((createReactClass({
182182
accessibilityRole={this.props.accessibilityRole}
183183
accessibilityStates={this.props.accessibilityStates}
184184
accessibilityState={this.props.accessibilityState}
185+
accessibilityActions={this.props.accessibilityActions}
186+
onAccessibilityAction={this.props.onAccessibilityAction}
185187
nativeID={this.props.nativeID}
186188
testID={this.props.testID}
187189
hitSlop={this.props.hitSlop}

Libraries/Components/Touchable/TouchableHighlight.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,8 @@ const TouchableHighlight = ((createReactClass({
409409
accessibilityRole={this.props.accessibilityRole}
410410
accessibilityStates={this.props.accessibilityStates}
411411
accessibilityState={this.props.accessibilityState}
412+
accessibilityActions={this.props.accessibilityActions}
413+
onAccessibilityAction={this.props.onAccessibilityAction}
412414
style={StyleSheet.compose(
413415
this.props.style,
414416
this.state.extraUnderlayStyle,

Libraries/Components/Touchable/TouchableNativeFeedback.android.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,8 @@ const TouchableNativeFeedback = createReactClass({
315315
accessibilityRole: this.props.accessibilityRole,
316316
accessibilityStates: this.props.accessibilityStates,
317317
accessibilityState: this.props.accessibilityState,
318+
accessibilityActions: this.props.accessibilityActions,
319+
onAccessibilityAction: this.props.onAccessibilityAction,
318320
children,
319321
testID: this.props.testID,
320322
onLayout: this.props.onLayout,

Libraries/Components/Touchable/TouchableOpacity.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ const TouchableOpacity = ((createReactClass({
312312
accessibilityRole={this.props.accessibilityRole}
313313
accessibilityStates={this.props.accessibilityStates}
314314
accessibilityState={this.props.accessibilityState}
315+
accessibilityActions={this.props.accessibilityActions}
316+
onAccessibilityAction={this.props.onAccessibilityAction}
315317
style={[this.props.style, {opacity: this.state.anim}]}
316318
nativeID={this.props.nativeID}
317319
testID={this.props.testID}

Libraries/Components/Touchable/TouchableWithoutFeedback.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ import type {
3333
AccessibilityRole,
3434
AccessibilityStates,
3535
AccessibilityState,
36+
AccessibilityActionInfo,
37+
AccessibilityActionEvent,
3638
} from '../View/ViewAccessibility';
3739

3840
type TargetEvent = SyntheticEvent<
@@ -53,6 +55,8 @@ const OVERRIDE_PROPS = [
5355
'accessibilityRole',
5456
'accessibilityStates',
5557
'accessibilityState',
58+
'accessibilityActions',
59+
'onAccessibilityAction',
5660
'hitSlop',
5761
'nativeID',
5862
'onBlur',
@@ -69,6 +73,7 @@ export type Props = $ReadOnly<{|
6973
accessibilityRole?: ?AccessibilityRole,
7074
accessibilityStates?: ?AccessibilityStates,
7175
accessibilityState?: ?AccessibilityState,
76+
accessibilityActions?: ?$ReadOnlyArray<AccessibilityActionInfo>,
7277
children?: ?React.Node,
7378
delayLongPress?: ?number,
7479
delayPressIn?: ?number,
@@ -84,6 +89,7 @@ export type Props = $ReadOnly<{|
8489
onPress?: ?(event: PressEvent) => mixed,
8590
onPressIn?: ?(event: PressEvent) => mixed,
8691
onPressOut?: ?(event: PressEvent) => mixed,
92+
onAccessibilityAction?: ?(event: AccessibilityActionEvent) => void,
8793
pressRetentionOffset?: ?EdgeInsetsProp,
8894
rejectResponderTermination?: ?boolean,
8995
testID?: ?string,
@@ -108,6 +114,8 @@ const TouchableWithoutFeedback = ((createReactClass({
108114
accessibilityRole: PropTypes.oneOf(DeprecatedAccessibilityRoles),
109115
accessibilityStates: PropTypes.array,
110116
accessibilityState: PropTypes.object,
117+
accessibilityActions: PropTypes.array,
118+
onAccessibilityAction: PropTypes.func,
111119
/**
112120
* When `accessible` is true (which is the default) this may be called when
113121
* the OS-specific concept of "focus" occurs. Some platforms may not have

RNTester/js/examples/Accessibility/AccessibilityExample.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const {
1616
Text,
1717
View,
1818
TouchableOpacity,
19+
TouchableWithoutFeedback,
1920
Alert,
2021
UIManager,
2122
findNodeHandle,
@@ -478,6 +479,35 @@ class AccessibilityActionsExample extends React.Component {
478479
<Text>Slider</Text>
479480
</View>
480481
</RNTesterBlock>
482+
483+
<RNTesterBlock title="Button with custom accessibility actions">
484+
<TouchableWithoutFeedback
485+
accessible={true}
486+
accessibilityActions={[
487+
{name: 'cut', label: 'cut label'},
488+
{name: 'copy', label: 'copy label'},
489+
{name: 'paste', label: 'paste label'},
490+
]}
491+
onAccessibilityAction={event => {
492+
switch (event.nativeEvent.actionName) {
493+
case 'cut':
494+
Alert.alert('Alert', 'cut action success');
495+
break;
496+
case 'copy':
497+
Alert.alert('Alert', 'copy action success');
498+
break;
499+
case 'paste':
500+
Alert.alert('Alert', 'paste action success');
501+
break;
502+
}
503+
}}
504+
onPress={() => Alert.alert('Button has been pressed!')}
505+
accessibilityRole="button">
506+
<View>
507+
<Text>Click me</Text>
508+
</View>
509+
</TouchableWithoutFeedback>
510+
</RNTesterBlock>
481511
</View>
482512
);
483513
}

0 commit comments

Comments
 (0)