diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm index e2239c99531559..ecfe8bc408fd95 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm @@ -721,21 +721,40 @@ - (NSString *)accessibilityValue } } + NSMutableArray *valueComponents = [NSMutableArray new]; + NSString *roleString = [NSString stringWithUTF8String:props.accessibilityRole.c_str()]; + + // In iOS, checkbox and radio buttons aren't recognized as traits. However, + // because our apps use checkbox and radio buttons often, we should announce + // these to screenreader users. (They should already be familiar with them + // from using web). + if ([roleString isEqualToString:@"checkbox"]) { + [valueComponents addObject:@"checkbox"]; + } + + if ([roleString isEqualToString:@"radio"]) { + [valueComponents addObject:@"radio button"]; + } + // Handle states which haven't already been handled. if (props.accessibilityState.checked == AccessibilityState::Checked) { - return @"checked"; + [valueComponents addObject:@"checked"]; } if (props.accessibilityState.checked == AccessibilityState::Unchecked) { - return @"unchecked"; + [valueComponents addObject:@"unchecked"]; } if (props.accessibilityState.checked == AccessibilityState::Mixed) { - return @"mixed"; + [valueComponents addObject:@"mixed"]; } if (props.accessibilityState.expanded) { - return @"expanded"; + [valueComponents addObject:@"expanded"]; } if (props.accessibilityState.busy) { - return @"busy"; + [valueComponents addObject:@"busy"]; + } + + if (valueComponents.count > 0) { + return [valueComponents componentsJoinedByString:@", "]; } return nil;