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 { getHostComponentNames , isHostText , isHostTextInput } from './host-component-names' ;
5
11
import { getTextContent } from './text-content' ;
12
+ import { isTextInputEditable } from './text-input' ;
6
13
7
14
type IsInaccessibleOptions = {
8
15
cache ?: WeakMap < ReactTestInstance , boolean > ;
@@ -45,7 +52,7 @@ export function isHiddenFromAccessibility(
45
52
return false ;
46
53
}
47
54
48
- /** RTL-compatitibility alias for `isHiddenFromAccessibility` */
55
+ /** RTL-compatibility alias for `isHiddenFromAccessibility` */
49
56
export const isInaccessible = isHiddenFromAccessibility ;
50
57
51
58
function isSubtreeInaccessible ( element : ReactTestInstance ) : boolean {
@@ -78,7 +85,7 @@ function isSubtreeInaccessible(element: ReactTestInstance): boolean {
78
85
// iOS: accessibilityViewIsModal or aria-modal
79
86
// See: https://reactnative.dev/docs/accessibility#accessibilityviewismodal-ios
80
87
const hostSiblings = getHostSiblings ( element ) ;
81
- if ( hostSiblings . some ( ( sibling ) => getAccessibilityViewIsModal ( sibling ) ) ) {
88
+ if ( hostSiblings . some ( ( sibling ) => computeAriaModal ( sibling ) ) ) {
82
89
return true ;
83
90
}
84
91
@@ -115,7 +122,7 @@ export function isAccessibilityElement(element: ReactTestInstance | null): boole
115
122
* @param element
116
123
* @returns
117
124
*/
118
- export function getAccessibilityRole ( element : ReactTestInstance ) {
125
+ export function getRole ( element : ReactTestInstance ) : Role | AccessibilityRole {
119
126
const explicitRole = element . props . role ?? element . props . accessibilityRole ;
120
127
if ( explicitRole ) {
121
128
return explicitRole ;
@@ -128,57 +135,55 @@ export function getAccessibilityRole(element: ReactTestInstance) {
128
135
return 'none' ;
129
136
}
130
137
131
- export function getAccessibilityViewIsModal ( element : ReactTestInstance ) {
138
+ export function computeAriaModal ( element : ReactTestInstance ) : boolean | undefined {
132
139
return element . props [ 'aria-modal' ] ?? element . props . accessibilityViewIsModal ;
133
140
}
134
141
135
- export function getAccessibilityLabel ( element : ReactTestInstance ) : string | undefined {
142
+ export function computeAriaLabel ( element : ReactTestInstance ) : string | undefined {
136
143
return element . props [ 'aria-label' ] ?? element . props . accessibilityLabel ;
137
144
}
138
145
139
- export function getAccessibilityLabelledBy ( element : ReactTestInstance ) : string | undefined {
146
+ export function computeAriaLabelledBy ( element : ReactTestInstance ) : string | undefined {
140
147
return element . props [ 'aria-labelledby' ] ?? element . props . accessibilityLabelledBy ;
141
148
}
142
149
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 ;
152
-
153
- const hasAnyAccessibilityStateProps =
154
- accessibilityState != null ||
155
- ariaBusy != null ||
156
- ariaChecked != null ||
157
- ariaDisabled != null ||
158
- ariaExpanded != null ||
159
- ariaSelected != null ;
150
+ // See: https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State#busy-state
151
+ export function computeAriaBusy ( { props } : ReactTestInstance ) : boolean {
152
+ return props [ 'aria-busy' ] ?? props . accessibilityState ?. busy ?? false ;
153
+ }
160
154
161
- if ( ! hasAnyAccessibilityStateProps ) {
155
+ // See: https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State#checked-state
156
+ export function computeAriaChecked ( element : ReactTestInstance ) : AccessibilityState [ 'checked' ] {
157
+ const role = getRole ( element ) ;
158
+ if ( role !== 'checkbox' && role !== 'radio' ) {
162
159
return undefined ;
163
160
}
164
161
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
- } ;
162
+ const props = element . props ;
163
+ return props [ 'aria-checked' ] ?? props . accessibilityState ?. checked ;
164
+ }
165
+
166
+ // See: https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State#disabled-state
167
+ export function computeAriaDisabled ( element : ReactTestInstance ) : boolean {
168
+ if ( isHostTextInput ( element ) && ! isTextInputEditable ( element ) ) {
169
+ return true ;
170
+ }
171
+
172
+ const { props } = element ;
173
+ return props [ 'aria-disabled' ] ?? props . accessibilityState ?. disabled ?? false ;
174
+ }
175
+
176
+ // See: https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State#expanded-state
177
+ export function computeAriaExpanded ( { props } : ReactTestInstance ) : boolean | undefined {
178
+ return props [ 'aria-expanded' ] ?? props . accessibilityState ?. expanded ;
172
179
}
173
180
174
- export function getAccessibilityCheckedState (
175
- element : ReactTestInstance ,
176
- ) : AccessibilityState [ 'checked' ] {
177
- const { accessibilityState, 'aria-checked' : ariaChecked } = element . props ;
178
- return ariaChecked ?? accessibilityState ?. checked ;
181
+ // See: https://github.com/callstack/react-native-testing-library/wiki/Accessibility:-State#selected-state
182
+ export function computeAriaSelected ( { props } : ReactTestInstance ) : boolean {
183
+ return props [ 'aria-selected' ] ?? props . accessibilityState ?. selected ?? false ;
179
184
}
180
185
181
- export function getAccessibilityValue ( element : ReactTestInstance ) : AccessibilityValue | undefined {
186
+ export function computeAriaValue ( element : ReactTestInstance ) : AccessibilityValue {
182
187
const {
183
188
accessibilityValue,
184
189
'aria-valuemax' : ariaValueMax ,
@@ -187,17 +192,6 @@ export function getAccessibilityValue(element: ReactTestInstance): Accessibility
187
192
'aria-valuetext' : ariaValueText ,
188
193
} = element . props ;
189
194
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
195
return {
202
196
max : ariaValueMax ?? accessibilityValue ?. max ,
203
197
min : ariaValueMin ?? accessibilityValue ?. min ,
@@ -206,39 +200,13 @@ export function getAccessibilityValue(element: ReactTestInstance): Accessibility
206
200
} ;
207
201
}
208
202
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 ) ;
203
+ export function computeAccessibleName ( element : ReactTestInstance ) : string | undefined {
204
+ const label = computeAriaLabel ( element ) ;
237
205
if ( label ) {
238
206
return label ;
239
207
}
240
208
241
- const labelElementId = getAccessibilityLabelledBy ( element ) ;
209
+ const labelElementId = computeAriaLabelledBy ( element ) ;
242
210
if ( labelElementId ) {
243
211
const rootElement = getUnsafeRootElement ( element ) ;
244
212
const labelElement = rootElement ?. findByProps ( { nativeID : labelElementId } ) ;
0 commit comments