mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Native ARIA Roles: iOS Paper + Fabric (#37309)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/37309 ### Stack ARIA roles in React Native are implemented on top of accessibilityRole. This is lossy because there are many more ARIA roles than accessibilityRole. This is especially true for RN on desktop where accessibilityRole was designed around accessibility APIs only available on mobile. This series of changes aims to change this implementation to instead pass the ARIA role to native, alongside any existing accessibilityRole. This gives the platform more control in exactly how to map an ARIA role to native behavior. As an example, this would allow mapping any ARIA role to AutomationControlType on Windows without needing to fork to add new options to accessibilityRole. It also allows greater implementation flexibility for other platforms down the line, but for now, iOS and Android behave the same as before (though with their implementation living in native). ### Diff This enables the `role` prop in iOS. ARIA role strings become convertible to `UIAccessibilityTrait`, which is the sink of most of the roles. We keep a list of traits derived from `role` vs `accessibilityRole` on the view, then inval and apply the result any time the prop for either is set. Changelog: [Internal] Reviewed By: sammy-SC Differential Revision: D45432530 fbshipit-source-id: ced5be06e319c0b967d7511293e14e05147e5759
This commit is contained in:
committed by
Facebook GitHub Bot
parent
d54f486fe6
commit
2d07d5f160
+3
-1
@@ -17,6 +17,7 @@
|
||||
#import <react/renderer/components/view/ViewComponentDescriptor.h>
|
||||
#import <react/renderer/components/view/ViewEventEmitter.h>
|
||||
#import <react/renderer/components/view/ViewProps.h>
|
||||
#import <react/renderer/components/view/accessibilityPropsConversions.h>
|
||||
|
||||
#ifdef RCT_DYNAMIC_FRAMEWORKS
|
||||
#import <React/RCTComponentViewFactory.h>
|
||||
@@ -722,7 +723,8 @@ static NSString *RCTRecursiveAccessibilityLabel(UIView *view)
|
||||
}
|
||||
|
||||
NSMutableArray *valueComponents = [NSMutableArray new];
|
||||
NSString *roleString = [NSString stringWithUTF8String:props.accessibilityRole.c_str()];
|
||||
NSString *roleString = (props.role != Role::None) ? [NSString stringWithUTF8String:toString(props.role).c_str()]
|
||||
: [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
|
||||
|
||||
@@ -332,7 +332,11 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : unused)
|
||||
}
|
||||
}
|
||||
NSMutableArray *valueComponents = [NSMutableArray new];
|
||||
NSString *roleDescription = self.accessibilityRole ? rolesAndStatesDescription[self.accessibilityRole] : nil;
|
||||
|
||||
// TODO: This logic makes VoiceOver describe some AccessibilityRole which do not have a backing UIAccessibilityTrait.
|
||||
// It does not run on Fabric.
|
||||
NSString *role = self.role ?: self.accessibilityRole;
|
||||
NSString *roleDescription = role ? rolesAndStatesDescription[role] : nil;
|
||||
if (roleDescription) {
|
||||
[valueComponents addObject:roleDescription];
|
||||
}
|
||||
|
||||
@@ -26,54 +26,97 @@
|
||||
RCT_MULTI_ENUM_CONVERTER(
|
||||
UIAccessibilityTraits,
|
||||
(@{
|
||||
@"none" : @(UIAccessibilityTraitNone),
|
||||
@"adjustable" : @(UIAccessibilityTraitAdjustable),
|
||||
@"alert" : @(UIAccessibilityTraitNone),
|
||||
@"alertdialog" : @(UIAccessibilityTraitNone),
|
||||
@"allowsDirectInteraction" : @(UIAccessibilityTraitAllowsDirectInteraction),
|
||||
@"application" : @(UIAccessibilityTraitNone),
|
||||
@"article" : @(UIAccessibilityTraitNone),
|
||||
@"banner" : @(UIAccessibilityTraitNone),
|
||||
@"button" : @(UIAccessibilityTraitButton),
|
||||
@"cell" : @(UIAccessibilityTraitNone),
|
||||
@"checkbox" : @(UIAccessibilityTraitNone),
|
||||
@"columnheader" : @(UIAccessibilityTraitNone),
|
||||
@"combobox" : @(UIAccessibilityTraitNone),
|
||||
@"complementary" : @(UIAccessibilityTraitNone),
|
||||
@"contentinfo" : @(UIAccessibilityTraitNone),
|
||||
@"definition" : @(UIAccessibilityTraitNone),
|
||||
@"dialog" : @(UIAccessibilityTraitNone),
|
||||
@"directory" : @(UIAccessibilityTraitNone),
|
||||
@"disabled" : @(UIAccessibilityTraitNotEnabled),
|
||||
@"document" : @(UIAccessibilityTraitNone),
|
||||
@"drawerlayout" : @(UIAccessibilityTraitNone),
|
||||
@"dropdownlist" : @(UIAccessibilityTraitNone),
|
||||
@"togglebutton" : @(UIAccessibilityTraitButton),
|
||||
@"link" : @(UIAccessibilityTraitLink),
|
||||
@"feed" : @(UIAccessibilityTraitNone),
|
||||
@"figure" : @(UIAccessibilityTraitNone),
|
||||
@"form" : @(UIAccessibilityTraitNone),
|
||||
@"frequentUpdates" : @(UIAccessibilityTraitUpdatesFrequently),
|
||||
@"grid" : @(UIAccessibilityTraitNone),
|
||||
@"group" : @(UIAccessibilityTraitNone),
|
||||
@"header" : @(UIAccessibilityTraitHeader),
|
||||
@"search" : @(UIAccessibilityTraitSearchField),
|
||||
@"heading" : @(UIAccessibilityTraitHeader),
|
||||
@"horizontalscrollview" : @(UIAccessibilityTraitNone),
|
||||
@"iconmenu" : @(UIAccessibilityTraitNone),
|
||||
@"image" : @(UIAccessibilityTraitImage),
|
||||
@"imagebutton" : @(UIAccessibilityTraitImage | UIAccessibilityTraitButton),
|
||||
@"selected" : @(UIAccessibilityTraitSelected),
|
||||
@"plays" : @(UIAccessibilityTraitPlaysSound),
|
||||
@"img" : @(UIAccessibilityTraitImage),
|
||||
@"key" : @(UIAccessibilityTraitKeyboardKey),
|
||||
@"keyboardkey" : @(UIAccessibilityTraitKeyboardKey),
|
||||
@"text" : @(UIAccessibilityTraitStaticText),
|
||||
@"summary" : @(UIAccessibilityTraitSummaryElement),
|
||||
@"disabled" : @(UIAccessibilityTraitNotEnabled),
|
||||
@"frequentUpdates" : @(UIAccessibilityTraitUpdatesFrequently),
|
||||
@"startsMedia" : @(UIAccessibilityTraitStartsMediaSession),
|
||||
@"adjustable" : @(UIAccessibilityTraitAdjustable),
|
||||
@"allowsDirectInteraction" : @(UIAccessibilityTraitAllowsDirectInteraction),
|
||||
@"pageTurn" : @(UIAccessibilityTraitCausesPageTurn),
|
||||
@"alert" : @(UIAccessibilityTraitNone),
|
||||
@"checkbox" : @(UIAccessibilityTraitNone),
|
||||
@"combobox" : @(UIAccessibilityTraitNone),
|
||||
@"link" : @(UIAccessibilityTraitLink),
|
||||
@"list" : @(UIAccessibilityTraitNone),
|
||||
@"listitem" : @(UIAccessibilityTraitNone),
|
||||
@"log" : @(UIAccessibilityTraitNone),
|
||||
@"main" : @(UIAccessibilityTraitNone),
|
||||
@"marquee" : @(UIAccessibilityTraitNone),
|
||||
@"math" : @(UIAccessibilityTraitNone),
|
||||
@"menu" : @(UIAccessibilityTraitNone),
|
||||
@"menubar" : @(UIAccessibilityTraitNone),
|
||||
@"menuitem" : @(UIAccessibilityTraitNone),
|
||||
@"meter" : @(UIAccessibilityTraitNone),
|
||||
@"navigation" : @(UIAccessibilityTraitNone),
|
||||
@"none" : @(UIAccessibilityTraitNone),
|
||||
@"note" : @(UIAccessibilityTraitNone),
|
||||
@"option" : @(UIAccessibilityTraitNone),
|
||||
@"pager" : @(UIAccessibilityTraitNone),
|
||||
@"pageTurn" : @(UIAccessibilityTraitCausesPageTurn),
|
||||
@"plays" : @(UIAccessibilityTraitPlaysSound),
|
||||
@"presentation" : @(UIAccessibilityTraitNone),
|
||||
@"progressbar" : @(UIAccessibilityTraitUpdatesFrequently),
|
||||
@"radio" : @(UIAccessibilityTraitNone),
|
||||
@"radiogroup" : @(UIAccessibilityTraitNone),
|
||||
@"region" : @(UIAccessibilityTraitNone),
|
||||
@"row" : @(UIAccessibilityTraitNone),
|
||||
@"rowgroup" : @(UIAccessibilityTraitNone),
|
||||
@"rowheader" : @(UIAccessibilityTraitNone),
|
||||
@"scrollbar" : @(UIAccessibilityTraitNone),
|
||||
@"scrollview" : @(UIAccessibilityTraitNone),
|
||||
@"search" : @(UIAccessibilityTraitSearchField),
|
||||
@"searchbox" : @(UIAccessibilityTraitNone),
|
||||
@"selected" : @(UIAccessibilityTraitSelected),
|
||||
@"separator" : @(UIAccessibilityTraitNone),
|
||||
@"slider" : @(UIAccessibilityTraitNone),
|
||||
@"slidingdrawer" : @(UIAccessibilityTraitNone),
|
||||
@"spinbutton" : @(UIAccessibilityTraitNone),
|
||||
@"startsMedia" : @(UIAccessibilityTraitStartsMediaSession),
|
||||
@"status" : @(UIAccessibilityTraitNone),
|
||||
@"summary" : @(UIAccessibilityTraitSummaryElement),
|
||||
@"switch" : @(SwitchAccessibilityTrait),
|
||||
@"tab" : @(UIAccessibilityTraitNone),
|
||||
@"tabbar" : @(UIAccessibilityTraitTabBar),
|
||||
@"table" : @(UIAccessibilityTraitNone),
|
||||
@"tablist" : @(UIAccessibilityTraitNone),
|
||||
@"tabpanel" : @(UIAccessibilityTraitNone),
|
||||
@"term" : @(UIAccessibilityTraitNone),
|
||||
@"text" : @(UIAccessibilityTraitStaticText),
|
||||
@"timer" : @(UIAccessibilityTraitNone),
|
||||
@"togglebutton" : @(UIAccessibilityTraitButton),
|
||||
@"toolbar" : @(UIAccessibilityTraitNone),
|
||||
@"pager" : @(UIAccessibilityTraitNone),
|
||||
@"scrollview" : @(UIAccessibilityTraitNone),
|
||||
@"horizontalscrollview" : @(UIAccessibilityTraitNone),
|
||||
@"tooltip" : @(UIAccessibilityTraitNone),
|
||||
@"tree" : @(UIAccessibilityTraitNone),
|
||||
@"treegrid" : @(UIAccessibilityTraitNone),
|
||||
@"treeitem" : @(UIAccessibilityTraitNone),
|
||||
@"viewgroup" : @(UIAccessibilityTraitNone),
|
||||
@"webview" : @(UIAccessibilityTraitNone),
|
||||
@"drawerlayout" : @(UIAccessibilityTraitNone),
|
||||
@"slidingdrawer" : @(UIAccessibilityTraitNone),
|
||||
@"iconmenu" : @(UIAccessibilityTraitNone),
|
||||
@"list" : @(UIAccessibilityTraitNone),
|
||||
@"grid" : @(UIAccessibilityTraitNone),
|
||||
}),
|
||||
UIAccessibilityTraitNone,
|
||||
unsignedLongLongValue)
|
||||
@@ -182,22 +225,41 @@ RCT_CUSTOM_VIEW_PROPERTY(transform, CATransform3D, RCTView)
|
||||
}
|
||||
|
||||
RCT_CUSTOM_VIEW_PROPERTY(accessibilityRole, UIAccessibilityTraits, RCTView)
|
||||
{
|
||||
UIAccessibilityTraits accessibilityRoleTraits =
|
||||
json ? [RCTConvert UIAccessibilityTraits:json] : UIAccessibilityTraitNone;
|
||||
if (view.reactAccessibilityElement.accessibilityRoleTraits != accessibilityRoleTraits) {
|
||||
view.accessibilityRoleTraits = accessibilityRoleTraits;
|
||||
view.reactAccessibilityElement.accessibilityRole = json ? [RCTConvert NSString:json] : nil;
|
||||
[self updateAccessibilityTraitsForRole:view withDefaultView:defaultView];
|
||||
}
|
||||
}
|
||||
|
||||
RCT_CUSTOM_VIEW_PROPERTY(role, UIAccessibilityTraits, RCTView)
|
||||
{
|
||||
UIAccessibilityTraits roleTraits = json ? [RCTConvert UIAccessibilityTraits:json] : UIAccessibilityTraitNone;
|
||||
if (view.reactAccessibilityElement.roleTraits != roleTraits) {
|
||||
view.roleTraits = roleTraits;
|
||||
view.reactAccessibilityElement.role = json ? [RCTConvert NSString:json] : nil;
|
||||
[self updateAccessibilityTraitsForRole:view withDefaultView:defaultView];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateAccessibilityTraitsForRole:(RCTView *)view withDefaultView:(RCTView *)defaultView
|
||||
{
|
||||
const UIAccessibilityTraits AccessibilityRolesMask = UIAccessibilityTraitNone | UIAccessibilityTraitButton |
|
||||
UIAccessibilityTraitLink | UIAccessibilityTraitSearchField | UIAccessibilityTraitImage |
|
||||
UIAccessibilityTraitKeyboardKey | UIAccessibilityTraitStaticText | UIAccessibilityTraitAdjustable |
|
||||
UIAccessibilityTraitHeader | UIAccessibilityTraitSummaryElement | UIAccessibilityTraitTabBar |
|
||||
UIAccessibilityTraitUpdatesFrequently | SwitchAccessibilityTrait;
|
||||
view.reactAccessibilityElement.accessibilityTraits =
|
||||
view.reactAccessibilityElement.accessibilityTraits & ~AccessibilityRolesMask;
|
||||
UIAccessibilityTraits newTraits = json ? [RCTConvert UIAccessibilityTraits:json] : defaultView.accessibilityTraits;
|
||||
if (newTraits != UIAccessibilityTraitNone) {
|
||||
UIAccessibilityTraits maskedTraits = newTraits & AccessibilityRolesMask;
|
||||
view.reactAccessibilityElement.accessibilityTraits |= maskedTraits;
|
||||
} else {
|
||||
NSString *role = json ? [RCTConvert NSString:json] : @"";
|
||||
view.reactAccessibilityElement.accessibilityRole = role;
|
||||
}
|
||||
|
||||
// Clear any existing traits set for AccessibilityRole
|
||||
view.reactAccessibilityElement.accessibilityTraits &= ~(AccessibilityRolesMask);
|
||||
|
||||
view.reactAccessibilityElement.accessibilityTraits |= view.reactAccessibilityElement.role
|
||||
? view.reactAccessibilityElement.roleTraits
|
||||
: view.reactAccessibilityElement.accessibilityRole ? view.reactAccessibilityElement.accessibilityRoleTraits
|
||||
: (defaultView.accessibilityTraits & AccessibilityRolesMask);
|
||||
}
|
||||
|
||||
RCT_CUSTOM_VIEW_PROPERTY(accessibilityState, NSDictionary, RCTView)
|
||||
|
||||
@@ -117,10 +117,13 @@
|
||||
* Accessibility properties
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *accessibilityRole;
|
||||
@property (nonatomic, copy) NSString *role;
|
||||
@property (nonatomic, copy) NSDictionary<NSString *, id> *accessibilityState;
|
||||
@property (nonatomic, copy) NSArray<NSDictionary *> *accessibilityActions;
|
||||
@property (nonatomic, copy) NSDictionary *accessibilityValueInternal;
|
||||
@property (nonatomic, copy) NSString *accessibilityLanguage;
|
||||
@property (nonatomic) UIAccessibilityTraits accessibilityRoleTraits;
|
||||
@property (nonatomic) UIAccessibilityTraits roleTraits;
|
||||
|
||||
/**
|
||||
* Used in debugging to get a description of the view hierarchy rooted at
|
||||
|
||||
@@ -336,6 +336,16 @@
|
||||
objc_setAssociatedObject(self, @selector(accessibilityRole), accessibilityRole, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (NSString *)role
|
||||
{
|
||||
return objc_getAssociatedObject(self, _cmd);
|
||||
}
|
||||
|
||||
- (void)setRole:(NSString *)role
|
||||
{
|
||||
objc_setAssociatedObject(self, @selector(role), role, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (NSDictionary<NSString *, id> *)accessibilityState
|
||||
{
|
||||
return objc_getAssociatedObject(self, _cmd);
|
||||
@@ -356,6 +366,33 @@
|
||||
self, @selector(accessibilityValueInternal), accessibilityValue, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (UIAccessibilityTraits)accessibilityRoleTraits
|
||||
{
|
||||
NSNumber *traitsAsNumber = objc_getAssociatedObject(self, _cmd);
|
||||
return traitsAsNumber ? [traitsAsNumber unsignedLongLongValue] : UIAccessibilityTraitNone;
|
||||
}
|
||||
|
||||
- (void)setAccessibilityRoleTraits:(UIAccessibilityTraits)accessibilityRoleTraits
|
||||
{
|
||||
objc_setAssociatedObject(
|
||||
self,
|
||||
@selector(accessibilityRoleTraits),
|
||||
[NSNumber numberWithUnsignedLongLong:accessibilityRoleTraits],
|
||||
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
- (UIAccessibilityTraits)roleTraits
|
||||
{
|
||||
NSNumber *traitsAsNumber = objc_getAssociatedObject(self, _cmd);
|
||||
return traitsAsNumber ? [traitsAsNumber unsignedLongLongValue] : UIAccessibilityTraitNone;
|
||||
}
|
||||
|
||||
- (void)setRoleTraits:(UIAccessibilityTraits)roleTraits
|
||||
{
|
||||
objc_setAssociatedObject(
|
||||
self, @selector(roleTraits), [NSNumber numberWithUnsignedLongLong:roleTraits], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
}
|
||||
|
||||
#pragma mark - Debug
|
||||
- (void)react_addRecursiveDescriptionToString:(NSMutableString *)string atLevel:(NSUInteger)level
|
||||
{
|
||||
|
||||
+22
-18
@@ -171,14 +171,6 @@ AccessibilityProps::AccessibilityProps(
|
||||
"importantForAccessibility",
|
||||
sourceProps.importantForAccessibility,
|
||||
ImportantForAccessibility::Auto)),
|
||||
role(
|
||||
CoreFeatures::enablePropIteratorSetter ? sourceProps.role
|
||||
: convertRawProp(
|
||||
context,
|
||||
rawProps,
|
||||
"role",
|
||||
sourceProps.role,
|
||||
{})),
|
||||
testId(
|
||||
CoreFeatures::enablePropIteratorSetter ? sourceProps.testId
|
||||
: convertRawProp(
|
||||
@@ -195,19 +187,31 @@ AccessibilityProps::AccessibilityProps(
|
||||
// to work around here, and (2) would require very careful work to address
|
||||
// this case and not regress the more common cases.
|
||||
if (!CoreFeatures::enablePropIteratorSetter) {
|
||||
const auto *rawPropValue =
|
||||
auto *accessibilityRoleValue =
|
||||
rawProps.at("accessibilityRole", nullptr, nullptr);
|
||||
AccessibilityTraits traits;
|
||||
std::string roleString;
|
||||
if (rawPropValue == nullptr || !rawPropValue->hasValue()) {
|
||||
traits = sourceProps.accessibilityTraits;
|
||||
roleString = sourceProps.accessibilityRole;
|
||||
auto *roleValue = rawProps.at("role", nullptr, nullptr);
|
||||
|
||||
auto *precedentRoleValue =
|
||||
roleValue != nullptr ? roleValue : accessibilityRoleValue;
|
||||
|
||||
if (accessibilityRoleValue == nullptr ||
|
||||
!accessibilityRoleValue->hasValue()) {
|
||||
accessibilityRole = sourceProps.accessibilityRole;
|
||||
} else {
|
||||
fromRawValue(context, *rawPropValue, traits);
|
||||
fromRawValue(context, *rawPropValue, roleString);
|
||||
fromRawValue(context, *accessibilityRoleValue, accessibilityRole);
|
||||
}
|
||||
|
||||
if (roleValue == nullptr || !roleValue->hasValue()) {
|
||||
role = sourceProps.role;
|
||||
} else {
|
||||
fromRawValue(context, *roleValue, role);
|
||||
}
|
||||
|
||||
if (precedentRoleValue == nullptr || !precedentRoleValue->hasValue()) {
|
||||
accessibilityTraits = sourceProps.accessibilityTraits;
|
||||
} else {
|
||||
fromRawValue(context, *precedentRoleValue, accessibilityTraits);
|
||||
}
|
||||
accessibilityTraits = traits;
|
||||
accessibilityRole = roleString;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -30,7 +30,7 @@ inline void fromString(const std::string &string, AccessibilityTraits &result) {
|
||||
result = AccessibilityTraits::Link;
|
||||
return;
|
||||
}
|
||||
if (string == "image") {
|
||||
if (string == "image" || string == "img") {
|
||||
result = AccessibilityTraits::Image;
|
||||
return;
|
||||
}
|
||||
@@ -78,7 +78,7 @@ inline void fromString(const std::string &string, AccessibilityTraits &result) {
|
||||
result = AccessibilityTraits::CausesPageTurn;
|
||||
return;
|
||||
}
|
||||
if (string == "header") {
|
||||
if (string == "header" || string == "heading") {
|
||||
result = AccessibilityTraits::Header;
|
||||
return;
|
||||
}
|
||||
|
||||
+2
@@ -15,6 +15,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
NSString *const RCTAttributedStringIsHighlightedAttributeName = @"IsHighlighted";
|
||||
NSString *const RCTAttributedStringEventEmitterKey = @"EventEmitter";
|
||||
|
||||
// String representation of either `role` or `accessibilityRole`
|
||||
NSString *const RCTTextAttributesAccessibilityRoleAttributeName = @"AccessibilityRole";
|
||||
|
||||
/*
|
||||
|
||||
+7
-124
@@ -7,6 +7,7 @@
|
||||
|
||||
#import "RCTAttributedTextUtils.h"
|
||||
|
||||
#include <react/renderer/components/view/accessibilityPropsConversions.h>
|
||||
#include <react/renderer/core/LayoutableShadowNode.h>
|
||||
#include <react/renderer/textlayoutmanager/RCTFontProperties.h>
|
||||
#include <react/renderer/textlayoutmanager/RCTFontUtils.h>
|
||||
@@ -288,130 +289,12 @@ NSDictionary<NSAttributedStringKey, id> *RCTNSTextAttributesFromTextAttributes(T
|
||||
attributes[RCTAttributedStringIsHighlightedAttributeName] = @YES;
|
||||
}
|
||||
|
||||
if (textAttributes.accessibilityRole.has_value()) {
|
||||
auto accessibilityRole = textAttributes.accessibilityRole.value();
|
||||
switch (accessibilityRole) {
|
||||
case AccessibilityRole::None:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("none");
|
||||
break;
|
||||
case AccessibilityRole::Button:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("button");
|
||||
break;
|
||||
case AccessibilityRole::Dropdownlist:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("dropdownlist");
|
||||
break;
|
||||
case AccessibilityRole::Togglebutton:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("togglebutton");
|
||||
break;
|
||||
case AccessibilityRole::Link:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("link");
|
||||
break;
|
||||
case AccessibilityRole::Search:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("search");
|
||||
break;
|
||||
case AccessibilityRole::Image:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("image");
|
||||
break;
|
||||
case AccessibilityRole::Keyboardkey:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("keyboardkey");
|
||||
break;
|
||||
case AccessibilityRole::Text:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("text");
|
||||
break;
|
||||
case AccessibilityRole::Adjustable:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("adjustable");
|
||||
break;
|
||||
case AccessibilityRole::Imagebutton:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("imagebutton");
|
||||
break;
|
||||
case AccessibilityRole::Header:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("header");
|
||||
break;
|
||||
case AccessibilityRole::Summary:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("summary");
|
||||
break;
|
||||
case AccessibilityRole::Alert:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("alert");
|
||||
break;
|
||||
case AccessibilityRole::Checkbox:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("checkbox");
|
||||
break;
|
||||
case AccessibilityRole::Combobox:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("combobox");
|
||||
break;
|
||||
case AccessibilityRole::Menu:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("menu");
|
||||
break;
|
||||
case AccessibilityRole::Menubar:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("menubar");
|
||||
break;
|
||||
case AccessibilityRole::Menuitem:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("menuitem");
|
||||
break;
|
||||
case AccessibilityRole::Progressbar:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("progressbar");
|
||||
break;
|
||||
case AccessibilityRole::Radio:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("radio");
|
||||
break;
|
||||
case AccessibilityRole::Radiogroup:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("radiogroup");
|
||||
break;
|
||||
case AccessibilityRole::Scrollbar:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("scrollbar");
|
||||
break;
|
||||
case AccessibilityRole::Spinbutton:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("spinbutton");
|
||||
break;
|
||||
case AccessibilityRole::Switch:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("switch");
|
||||
break;
|
||||
case AccessibilityRole::Tab:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("tab");
|
||||
break;
|
||||
case AccessibilityRole::Tabbar:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("tabbar");
|
||||
break;
|
||||
case AccessibilityRole::Tablist:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("tablist");
|
||||
break;
|
||||
case AccessibilityRole::Timer:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("timer");
|
||||
break;
|
||||
case AccessibilityRole::List:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("list");
|
||||
break;
|
||||
case AccessibilityRole::Toolbar:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("toolbar");
|
||||
break;
|
||||
case AccessibilityRole::Grid:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("grid");
|
||||
break;
|
||||
case AccessibilityRole::Pager:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("pager");
|
||||
break;
|
||||
case AccessibilityRole::Scrollview:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("scrollview");
|
||||
break;
|
||||
case AccessibilityRole::Horizontalscrollview:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("horizontalscrollview");
|
||||
break;
|
||||
case AccessibilityRole::Viewgroup:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("viewgroup");
|
||||
break;
|
||||
case AccessibilityRole::Webview:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("webview");
|
||||
break;
|
||||
case AccessibilityRole::Drawerlayout:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("drawerlayout");
|
||||
break;
|
||||
case AccessibilityRole::Slidingdrawer:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("slidingdrawer");
|
||||
break;
|
||||
case AccessibilityRole::Iconmenu:
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("iconmenu");
|
||||
break;
|
||||
};
|
||||
if (textAttributes.role.has_value()) {
|
||||
std::string roleStr = toString(textAttributes.role.value());
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = [NSString stringWithCString:roleStr.c_str()];
|
||||
} else if (textAttributes.accessibilityRole.has_value()) {
|
||||
std::string roleStr = toString(textAttributes.accessibilityRole.value());
|
||||
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = [NSString stringWithCString:roleStr.c_str()];
|
||||
}
|
||||
|
||||
return [attributes copy];
|
||||
|
||||
Reference in New Issue
Block a user