1
- import { AccessibilityState , AccessibilityValue , StyleSheet } from 'react-native' ;
1
+ import {
2
+ AccessibilityRole ,
3
+ AccessibilityState ,
4
+ AccessibilityValue ,
5
+ Role ,
6
+ StyleSheet ,
7
+ } from 'react-native' ;
2
8
import { ReactTestInstance } from 'react-test-renderer' ;
3
9
import { getHostSiblings , getUnsafeRootElement } from './component-tree' ;
4
- import { getHostComponentNames , isHostText } from './host-component-names' ;
10
+ import {
11
+ getHostComponentNames ,
12
+ isHostSwitch ,
13
+ isHostText ,
14
+ isHostTextInput ,
15
+ } from './host-component-names' ;
5
16
import { getTextContent } from './text-content' ;
17
+ import { isTextInputEditable } from './text-input' ;
6
18
7
19
type IsInaccessibleOptions = {
8
20
cache ?: WeakMap < ReactTestInstance , boolean > ;
@@ -45,7 +57,7 @@ export function isHiddenFromAccessibility(
45
57
return false ;
46
58
}
47
59
48
- /** RTL-compatitibility alias for `isHiddenFromAccessibility` */
60
+ /** RTL-compatibility alias for `isHiddenFromAccessibility` */
49
61
export const isInaccessible = isHiddenFromAccessibility ;
50
62
51
63
function isSubtreeInaccessible ( element : ReactTestInstance ) : boolean {
@@ -78,7 +90,7 @@ function isSubtreeInaccessible(element: ReactTestInstance): boolean {
78
90
// iOS: accessibilityViewIsModal or aria-modal
79
91
// See: https://reactnative.dev/docs/accessibility#accessibilityviewismodal-ios
80
92
const hostSiblings = getHostSiblings ( element ) ;
81
- if ( hostSiblings . some ( ( sibling ) => getAccessibilityViewIsModal ( sibling ) ) ) {
93
+ if ( hostSiblings . some ( ( sibling ) => computeAriaModal ( sibling ) ) ) {
82
94
return true ;
83
95
}
84
96
@@ -115,7 +127,7 @@ export function isAccessibilityElement(element: ReactTestInstance | null): boole
115
127
* @param element
116
128
* @returns
117
129
*/
118
- export function getAccessibilityRole ( element : ReactTestInstance ) {
130
+ export function getRole ( element : ReactTestInstance ) : Role | AccessibilityRole {
119
131
const explicitRole = element . props . role ?? element . props . accessibilityRole ;
120
132
if ( explicitRole ) {
121
133
return explicitRole ;
@@ -128,57 +140,59 @@ export function getAccessibilityRole(element: ReactTestInstance) {
128
140
return 'none' ;
129
141
}
130
142
131
- export function getAccessibilityViewIsModal ( element : ReactTestInstance ) {
143
+ export function computeAriaModal ( element : ReactTestInstance ) : boolean | undefined {
132
144
return element . props [ 'aria-modal' ] ?? element . props . accessibilityViewIsModal ;
133
145
}
134
146
135
- export function getAccessibilityLabel ( element : ReactTestInstance ) : string | undefined {
147
+ export function computeAriaLabel ( element : ReactTestInstance ) : string | undefined {
136
148
return element . props [ 'aria-label' ] ?? element . props . accessibilityLabel ;
137
149
}
138
150
139
- export function getAccessibilityLabelledBy ( element : ReactTestInstance ) : string | undefined {
151
+ export function computeAriaLabelledBy ( element : ReactTestInstance ) : string | undefined {
140
152
return element . props [ 'aria-labelledby' ] ?? element . props . accessibilityLabelledBy ;
141
153
}
142
154
143
- export function getAccessibilityState ( element : ReactTestInstance ) : AccessibilityState | undefined {
144
- const {
145
- accessibilityState,
146
- 'aria-busy' : ariaBusy ,
147
- 'aria-checked' : ariaChecked ,
148
- 'aria-disabled' : ariaDisabled ,
149
- 'aria-expanded' : ariaExpanded ,
150
- 'aria-selected' : ariaSelected ,
151
- } = element . props ;
155
+ // See: https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State#busy-state
156
+ export function computeAriaBusy ( { props } : ReactTestInstance ) : boolean {
157
+ return props [ 'aria-busy' ] ?? props . accessibilityState ?. busy ?? false ;
158
+ }
152
159
153
- const hasAnyAccessibilityStateProps =
154
- accessibilityState != null ||
155
- ariaBusy != null ||
156
- ariaChecked != null ||
157
- ariaDisabled != null ||
158
- ariaExpanded != null ||
159
- ariaSelected != null ;
160
+ // See: https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State#checked-state
161
+ export function computeAriaChecked ( element : ReactTestInstance ) : AccessibilityState [ 'checked' ] {
162
+ if ( isHostSwitch ( element ) ) {
163
+ return element . props . value ;
164
+ }
160
165
161
- if ( ! hasAnyAccessibilityStateProps ) {
166
+ const role = getRole ( element ) ;
167
+ if ( role !== 'checkbox' && role !== 'radio' ) {
162
168
return undefined ;
163
169
}
164
170
165
- return {
166
- busy : ariaBusy ?? accessibilityState ?. busy ,
167
- checked : ariaChecked ?? accessibilityState ?. checked ,
168
- disabled : ariaDisabled ?? accessibilityState ?. disabled ,
169
- expanded : ariaExpanded ?? accessibilityState ?. expanded ,
170
- selected : ariaSelected ?? accessibilityState ?. selected ,
171
- } ;
171
+ const props = element . props ;
172
+ return props [ 'aria-checked' ] ?? props . accessibilityState ?. checked ;
173
+ }
174
+
175
+ // See: https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State#disabled-state
176
+ export function computeAriaDisabled ( element : ReactTestInstance ) : boolean {
177
+ if ( isHostTextInput ( element ) && ! isTextInputEditable ( element ) ) {
178
+ return true ;
179
+ }
180
+
181
+ const { props } = element ;
182
+ return props [ 'aria-disabled' ] ?? props . accessibilityState ?. disabled ?? false ;
183
+ }
184
+
185
+ // See: https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State#expanded-state
186
+ export function computeAriaExpanded ( { props } : ReactTestInstance ) : boolean | undefined {
187
+ return props [ 'aria-expanded' ] ?? props . accessibilityState ?. expanded ;
172
188
}
173
189
174
- export function getAccessibilityCheckedState (
175
- element : ReactTestInstance ,
176
- ) : AccessibilityState [ 'checked' ] {
177
- const { accessibilityState, 'aria-checked' : ariaChecked } = element . props ;
178
- return ariaChecked ?? accessibilityState ?. checked ;
190
+ // See: https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State#selected-state
191
+ export function computeAriaSelected ( { props } : ReactTestInstance ) : boolean {
192
+ return props [ 'aria-selected' ] ?? props . accessibilityState ?. selected ?? false ;
179
193
}
180
194
181
- export function getAccessibilityValue ( element : ReactTestInstance ) : AccessibilityValue | undefined {
195
+ export function computeAriaValue ( element : ReactTestInstance ) : AccessibilityValue {
182
196
const {
183
197
accessibilityValue,
184
198
'aria-valuemax' : ariaValueMax ,
@@ -187,17 +201,6 @@ export function getAccessibilityValue(element: ReactTestInstance): Accessibility
187
201
'aria-valuetext' : ariaValueText ,
188
202
} = element . props ;
189
203
190
- const hasAnyAccessibilityValueProps =
191
- accessibilityValue != null ||
192
- ariaValueMax != null ||
193
- ariaValueMin != null ||
194
- ariaValueNow != null ||
195
- ariaValueText != null ;
196
-
197
- if ( ! hasAnyAccessibilityValueProps ) {
198
- return undefined ;
199
- }
200
-
201
204
return {
202
205
max : ariaValueMax ?? accessibilityValue ?. max ,
203
206
min : ariaValueMin ?? accessibilityValue ?. min ,
@@ -206,39 +209,13 @@ export function getAccessibilityValue(element: ReactTestInstance): Accessibility
206
209
} ;
207
210
}
208
211
209
- export function isElementBusy ( element : ReactTestInstance ) : NonNullable < AccessibilityState [ 'busy' ] > {
210
- const { accessibilityState, 'aria-busy' : ariaBusy } = element . props ;
211
- return ariaBusy ?? accessibilityState ?. busy ?? false ;
212
- }
213
-
214
- export function isElementCollapsed (
215
- element : ReactTestInstance ,
216
- ) : NonNullable < AccessibilityState [ 'expanded' ] > {
217
- const { accessibilityState, 'aria-expanded' : ariaExpanded } = element . props ;
218
- return ( ariaExpanded ?? accessibilityState ?. expanded ) === false ;
219
- }
220
-
221
- export function isElementExpanded (
222
- element : ReactTestInstance ,
223
- ) : NonNullable < AccessibilityState [ 'expanded' ] > {
224
- const { accessibilityState, 'aria-expanded' : ariaExpanded } = element . props ;
225
- return ariaExpanded ?? accessibilityState ?. expanded ?? false ;
226
- }
227
-
228
- export function isElementSelected (
229
- element : ReactTestInstance ,
230
- ) : NonNullable < AccessibilityState [ 'selected' ] > {
231
- const { accessibilityState, 'aria-selected' : ariaSelected } = element . props ;
232
- return ariaSelected ?? accessibilityState ?. selected ?? false ;
233
- }
234
-
235
- export function getAccessibleName ( element : ReactTestInstance ) : string | undefined {
236
- const label = getAccessibilityLabel ( element ) ;
212
+ export function computeAccessibleName ( element : ReactTestInstance ) : string | undefined {
213
+ const label = computeAriaLabel ( element ) ;
237
214
if ( label ) {
238
215
return label ;
239
216
}
240
217
241
- const labelElementId = getAccessibilityLabelledBy ( element ) ;
218
+ const labelElementId = computeAriaLabelledBy ( element ) ;
242
219
if ( labelElementId ) {
243
220
const rootElement = getUnsafeRootElement ( element ) ;
244
221
const labelElement = rootElement ?. findByProps ( { nativeID : labelElementId } ) ;
0 commit comments