Skip to content

Commit a3489b3

Browse files
authoredNov 27, 2023
RFC/feat: default accessibility roles (#1490)
* feat: default accessibility roles * chore: remove default text input role * chore: update tests * chore: update docs
1 parent ab679c9 commit a3489b3

File tree

2 files changed

+42
-6
lines changed

2 files changed

+42
-6
lines changed
 

‎src/helpers/accessiblity.ts

+26-6
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import {
44
StyleSheet,
55
} from 'react-native';
66
import { ReactTestInstance } from 'react-test-renderer';
7-
import { getTextContent } from './text-content';
87
import { getHostSiblings, getUnsafeRootElement } from './component-tree';
9-
import { getHostComponentNames } from './host-component-names';
8+
import { getHostComponentNames, isHostText } from './host-component-names';
9+
import { getTextContent } from './text-content';
1010

1111
type IsInaccessibleOptions = {
1212
cache?: WeakMap<ReactTestInstance, boolean>;
@@ -113,10 +113,30 @@ export function isAccessibilityElement(
113113
);
114114
}
115115

116-
export function getAccessibilityRole(
117-
element: ReactTestInstance
118-
): string | undefined {
119-
return element.props.role ?? element.props.accessibilityRole;
116+
/**
117+
* Returns the accessibility role for given element. It will return explicit
118+
* role from either `role` or `accessibilityRole` props if set.
119+
*
120+
* If explicit role is not available, it would try to return default element
121+
* role:
122+
* - `text` for `Text` elements
123+
*
124+
* In all other cases this functions returns `none`.
125+
*
126+
* @param element
127+
* @returns
128+
*/
129+
export function getAccessibilityRole(element: ReactTestInstance) {
130+
const explicitRole = element.props.role ?? element.props.accessibilityRole;
131+
if (explicitRole) {
132+
return explicitRole;
133+
}
134+
135+
if (isHostText(element)) {
136+
return 'text';
137+
}
138+
139+
return 'none';
120140
}
121141

122142
export function getAccessibilityViewIsModal(element: ReactTestInstance) {

‎src/queries/__tests__/role.test.tsx

+16
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
TouchableOpacity,
44
TouchableWithoutFeedback,
55
Text,
6+
TextInput,
67
View,
78
Pressable,
89
Button as RNButton,
@@ -110,6 +111,21 @@ test('supports role prop', () => {
110111
expect(screen.getByRole('button')).toBeTruthy();
111112
});
112113

114+
test('supports default View component "none" role', () => {
115+
const screen = render(<View testID="view" accessible />);
116+
expect(screen.getByRole('none').props.testID).toBe('view');
117+
});
118+
119+
test('supports default Text component "text" role', () => {
120+
const screen = render(<Text testID="text" />);
121+
expect(screen.getByRole('text').props.testID).toBe('text');
122+
});
123+
124+
test('supports default TextInput component "none" role', () => {
125+
const screen = render(<TextInput testID="text-input" />);
126+
expect(screen.getByRole('none').props.testID).toBe('text-input');
127+
});
128+
113129
describe('supports name option', () => {
114130
test('returns an element that has the corresponding role and a children with the name', () => {
115131
const { getByRole } = render(

0 commit comments

Comments
 (0)
Please sign in to comment.