1- import { AccessibilityState , AccessibilityValue , StyleSheet } from 'react-native' ;
1+ import {
2+ AccessibilityRole ,
3+ AccessibilityState ,
4+ AccessibilityValue ,
5+ Role ,
6+ StyleSheet ,
7+ } from 'react-native' ;
28import { ReactTestInstance } from 'react-test-renderer' ;
39import { getHostSiblings , getUnsafeRootElement } from './component-tree' ;
4- import { getHostComponentNames , isHostText } from './host-component-names' ;
10+ import { getHostComponentNames , isHostText , isHostTextInput } from './host-component-names' ;
511import { getTextContent } from './text-content' ;
12+ import { isTextInputEditable } from './text-input' ;
613
714type IsInaccessibleOptions = {
815 cache ?: WeakMap < ReactTestInstance , boolean > ;
@@ -45,7 +52,7 @@ export function isHiddenFromAccessibility(
4552 return false ;
4653}
4754
48- /** RTL-compatitibility alias for `isHiddenFromAccessibility` */
55+ /** RTL-compatibility alias for `isHiddenFromAccessibility` */
4956export const isInaccessible = isHiddenFromAccessibility ;
5057
5158function isSubtreeInaccessible ( element : ReactTestInstance ) : boolean {
@@ -78,7 +85,7 @@ function isSubtreeInaccessible(element: ReactTestInstance): boolean {
7885 // iOS: accessibilityViewIsModal or aria-modal
7986 // See: https://reactnative.dev/docs/accessibility#accessibilityviewismodal-ios
8087 const hostSiblings = getHostSiblings ( element ) ;
81- if ( hostSiblings . some ( ( sibling ) => getAccessibilityViewIsModal ( sibling ) ) ) {
88+ if ( hostSiblings . some ( ( sibling ) => computeAriaModal ( sibling ) ) ) {
8289 return true ;
8390 }
8491
@@ -115,7 +122,7 @@ export function isAccessibilityElement(element: ReactTestInstance | null): boole
115122 * @param element
116123 * @returns
117124 */
118- export function getAccessibilityRole ( element : ReactTestInstance ) {
125+ export function getRole ( element : ReactTestInstance ) : Role | AccessibilityRole {
119126 const explicitRole = element . props . role ?? element . props . accessibilityRole ;
120127 if ( explicitRole ) {
121128 return explicitRole ;
@@ -128,57 +135,55 @@ export function getAccessibilityRole(element: ReactTestInstance) {
128135 return 'none' ;
129136}
130137
131- export function getAccessibilityViewIsModal ( element : ReactTestInstance ) {
138+ export function computeAriaModal ( element : ReactTestInstance ) : boolean | undefined {
132139 return element . props [ 'aria-modal' ] ?? element . props . accessibilityViewIsModal ;
133140}
134141
135- export function getAccessibilityLabel ( element : ReactTestInstance ) : string | undefined {
142+ export function computeAriaLabel ( element : ReactTestInstance ) : string | undefined {
136143 return element . props [ 'aria-label' ] ?? element . props . accessibilityLabel ;
137144}
138145
139- export function getAccessibilityLabelledBy ( element : ReactTestInstance ) : string | undefined {
146+ export function computeAriaLabelledBy ( element : ReactTestInstance ) : string | undefined {
140147 return element . props [ 'aria-labelledby' ] ?? element . props . accessibilityLabelledBy ;
141148}
142149
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+ }
160154
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' ) {
162159 return undefined ;
163160 }
164161
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 ;
172179}
173180
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 ;
179184}
180185
181- export function getAccessibilityValue ( element : ReactTestInstance ) : AccessibilityValue | undefined {
186+ export function computeAriaValue ( element : ReactTestInstance ) : AccessibilityValue {
182187 const {
183188 accessibilityValue,
184189 'aria-valuemax' : ariaValueMax ,
@@ -187,17 +192,6 @@ export function getAccessibilityValue(element: ReactTestInstance): Accessibility
187192 'aria-valuetext' : ariaValueText ,
188193 } = element . props ;
189194
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-
201195 return {
202196 max : ariaValueMax ?? accessibilityValue ?. max ,
203197 min : ariaValueMin ?? accessibilityValue ?. min ,
@@ -206,39 +200,13 @@ export function getAccessibilityValue(element: ReactTestInstance): Accessibility
206200 } ;
207201}
208202
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 ) ;
237205 if ( label ) {
238206 return label ;
239207 }
240208
241- const labelElementId = getAccessibilityLabelledBy ( element ) ;
209+ const labelElementId = computeAriaLabelledBy ( element ) ;
242210 if ( labelElementId ) {
243211 const rootElement = getUnsafeRootElement ( element ) ;
244212 const labelElement = rootElement ?. findByProps ( { nativeID : labelElementId } ) ;
0 commit comments