Native ARIA Roles: Shared code (#37305)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37305

### 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`](https://learn.microsoft.com/en-us/dotnet/api/system.windows.automation.peers.automationcontroltype?view=windowsdesktop-7.0&viewFallbackFrom=dotnet-uwp-10.0) 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 syncs the Fabric representations of Roles to the current state of the world in JS, and adds usage to the view configs.
1. `Role` enum for the View `role` prop (ARIA role)
2. Sync enums and conversions to JS `AccessibilityRole`
    1. This parsing is done for `TextAttributes` only. `View` uses the string directly
    2. Add ARIA roles, and parse those to their enum form.
    3. Move enums from attributedstring primitves to accessibility primitives
3. Add to viewconfig to allow it to be passed

Changelog: [Internal]

Reviewed By: sammy-SC

Differential Revision: D45431372

fbshipit-source-id: 0150538345bbb6cb4d9426c4eebd0f67c2a33f3d
This commit is contained in:
Nick Gerleman
2023-05-13 11:03:19 -07:00
committed by Facebook GitHub Bot
parent 1b0e8b1de4
commit 9db5fa215e
14 changed files with 682 additions and 189 deletions
@@ -35,6 +35,7 @@ const UIView = {
collapsable: true,
needsOffscreenAlphaCompositing: true,
style: ReactNativeStyleAttributes,
role: true,
};
const RCTView = {
@@ -179,6 +179,7 @@ const validAttributesForNonEventProps = {
accessibilityActions: true,
accessibilityValue: true,
importantForAccessibility: true,
role: true,
rotation: true,
scaleX: true,
scaleY: true,
@@ -198,6 +198,7 @@ const validAttributesForNonEventProps = {
nativeID: true,
pointerEvents: true,
removeClippedSubviews: true,
role: true,
borderRadius: true,
borderColor: {process: require('../StyleSheet/processColor').default},
borderCurve: true,
@@ -26,6 +26,7 @@ target_link_libraries(react_render_attributedstring
glog
glog_init
react_debug
rrc_view
react_render_core
react_render_debug
react_render_graphics
@@ -101,6 +101,7 @@ void TextAttributes::apply(TextAttributes textAttributes) {
accessibilityRole = textAttributes.accessibilityRole.has_value()
? textAttributes.accessibilityRole
: accessibilityRole;
role = textAttributes.role.has_value() ? textAttributes.role : role;
}
#pragma mark - Operators
@@ -126,6 +127,7 @@ bool TextAttributes::operator==(const TextAttributes &rhs) const {
isHighlighted,
layoutDirection,
accessibilityRole,
role,
textTransform) ==
std::tie(
rhs.foregroundColor,
@@ -147,6 +149,7 @@ bool TextAttributes::operator==(const TextAttributes &rhs) const {
rhs.isHighlighted,
rhs.layoutDirection,
rhs.accessibilityRole,
rhs.role,
rhs.textTransform) &&
floatEquality(opacity, rhs.opacity) &&
floatEquality(fontSize, rhs.fontSize) &&
@@ -215,6 +218,7 @@ SharedDebugStringConvertibleList TextAttributes::getDebugProps() const {
debugStringConvertibleItem("isHighlighted", isHighlighted),
debugStringConvertibleItem("layoutDirection", layoutDirection),
debugStringConvertibleItem("accessibilityRole", accessibilityRole),
debugStringConvertibleItem("role", role),
};
}
#endif
@@ -13,6 +13,7 @@
#include <folly/Hash.h>
#include <react/renderer/attributedstring/primitives.h>
#include <react/renderer/components/view/AccessibilityPrimitives.h>
#include <react/renderer/core/LayoutPrimitives.h>
#include <react/renderer/core/ReactPrimitives.h>
#include <react/renderer/debug/DebugStringConvertible.h>
@@ -80,6 +81,7 @@ class TextAttributes : public DebugStringConvertible {
// construction.
std::optional<LayoutDirection> layoutDirection{};
std::optional<AccessibilityRole> accessibilityRole{};
std::optional<Role> role{};
#pragma mark - Operations
@@ -131,7 +133,8 @@ struct hash<facebook::react::TextAttributes> {
textAttributes.textShadowColor,
textAttributes.isHighlighted,
textAttributes.layoutDirection,
textAttributes.accessibilityRole);
textAttributes.accessibilityRole,
textAttributes.role);
}
};
} // namespace std
@@ -15,6 +15,7 @@
#include <react/renderer/attributedstring/TextAttributes.h>
#include <react/renderer/attributedstring/conversions.h>
#include <react/renderer/attributedstring/primitives.h>
#include <react/renderer/components/view/accessibilityPropsConversions.h>
#include <react/renderer/core/LayoutableShadowNode.h>
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/core/ShadowNode.h>
@@ -641,150 +642,6 @@ inline std::string toString(const TextDecorationStyle &textDecorationStyle) {
return "solid";
}
inline std::string toString(const AccessibilityRole &accessibilityRole) {
switch (accessibilityRole) {
case AccessibilityRole::None:
return "none";
case AccessibilityRole::Button:
return "button";
case AccessibilityRole::Link:
return "link";
case AccessibilityRole::Search:
return "search";
case AccessibilityRole::Image:
return "image";
case AccessibilityRole::Imagebutton:
return "imagebutton";
case AccessibilityRole::Keyboardkey:
return "keyboardkey";
case AccessibilityRole::Text:
return "text";
case AccessibilityRole::Adjustable:
return "adjustable";
case AccessibilityRole::Summary:
return "summary";
case AccessibilityRole::Header:
return "header";
case AccessibilityRole::Alert:
return "alert";
case AccessibilityRole::Checkbox:
return "checkbox";
case AccessibilityRole::Combobox:
return "combobox";
case AccessibilityRole::Menu:
return "menu";
case AccessibilityRole::Menubar:
return "menubar";
case AccessibilityRole::Menuitem:
return "menuitem";
case AccessibilityRole::Progressbar:
return "progressbar";
case AccessibilityRole::Radio:
return "radio";
case AccessibilityRole::Radiogroup:
return "radiogroup";
case AccessibilityRole::Scrollbar:
return "scrollbar";
case AccessibilityRole::Spinbutton:
return "spinbutton";
case AccessibilityRole::Switch:
return "switch";
case AccessibilityRole::Tab:
return "tab";
case AccessibilityRole::TabBar:
return "tabbar";
case AccessibilityRole::Tablist:
return "tablist";
case AccessibilityRole::Timer:
return "timer";
case AccessibilityRole::Toolbar:
return "toolbar";
}
LOG(ERROR) << "Unsupported AccessibilityRole value";
react_native_expect(false);
// sane default for prod
return "none";
}
inline void fromRawValue(
const PropsParserContext &context,
const RawValue &value,
AccessibilityRole &result) {
react_native_expect(value.hasType<std::string>());
if (value.hasType<std::string>()) {
auto string = (std::string)value;
if (string == "none") {
result = AccessibilityRole::None;
} else if (string == "button" || string == "togglebutton") {
result = AccessibilityRole::Button;
} else if (string == "link") {
result = AccessibilityRole::Link;
} else if (string == "search") {
result = AccessibilityRole::Search;
} else if (string == "image") {
result = AccessibilityRole::Image;
} else if (string == "imagebutton") {
result = AccessibilityRole::Imagebutton;
} else if (string == "keyboardkey") {
result = AccessibilityRole::Keyboardkey;
} else if (string == "text") {
result = AccessibilityRole::Text;
} else if (string == "adjustable") {
result = AccessibilityRole::Adjustable;
} else if (string == "summary") {
result = AccessibilityRole::Summary;
} else if (string == "header") {
result = AccessibilityRole::Header;
} else if (string == "alert") {
result = AccessibilityRole::Alert;
} else if (string == "checkbox") {
result = AccessibilityRole::Checkbox;
} else if (string == "combobox") {
result = AccessibilityRole::Combobox;
} else if (string == "menu") {
result = AccessibilityRole::Menu;
} else if (string == "menubar") {
result = AccessibilityRole::Menubar;
} else if (string == "menuitem") {
result = AccessibilityRole::Menuitem;
} else if (string == "progressbar") {
result = AccessibilityRole::Progressbar;
} else if (string == "radio") {
result = AccessibilityRole::Radio;
} else if (string == "radiogroup") {
result = AccessibilityRole::Radiogroup;
} else if (string == "scrollbar") {
result = AccessibilityRole::Scrollbar;
} else if (string == "spinbutton") {
result = AccessibilityRole::Spinbutton;
} else if (string == "switch") {
result = AccessibilityRole::Switch;
} else if (string == "tab") {
result = AccessibilityRole::Tab;
} else if (string == "tabbar") {
result = AccessibilityRole::TabBar;
} else if (string == "tablist") {
result = AccessibilityRole::Tablist;
} else if (string == "timer") {
result = AccessibilityRole::Timer;
} else if (string == "toolbar") {
result = AccessibilityRole::Toolbar;
} else {
LOG(ERROR) << "Unsupported AccessibilityRole value: " << string;
react_native_expect(false);
// sane default for prod
result = AccessibilityRole::None;
}
return;
}
LOG(ERROR) << "Unsupported AccessibilityRole type";
react_native_expect(false);
// sane default for prod
result = AccessibilityRole::None;
}
inline std::string toString(const HyphenationFrequency &hyphenationFrequency) {
switch (hyphenationFrequency) {
case HyphenationFrequency::None:
@@ -105,37 +105,6 @@ enum class TextDecorationLineType {
enum class TextDecorationStyle { Solid, Double, Dotted, Dashed };
enum class AccessibilityRole {
None,
Button,
Link,
Search,
Image,
Imagebutton,
Keyboardkey,
Text,
Adjustable,
Summary,
Header,
Alert,
Checkbox,
Combobox,
Menu,
Menubar,
Menuitem,
Progressbar,
Radio,
Radiogroup,
Scrollbar,
Spinbutton,
Switch,
Tab,
TabBar,
Tablist,
Timer,
Toolbar,
};
enum class TextTransform {
None,
Uppercase,
@@ -223,13 +192,6 @@ struct hash<facebook::react::TextBreakStrategy> {
}
};
template <>
struct hash<facebook::react::AccessibilityRole> {
size_t operator()(const facebook::react::AccessibilityRole &v) const {
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::TextTransform> {
size_t operator()(const facebook::react::TextTransform &v) const {
@@ -183,6 +183,13 @@ static TextAttributes convertRawProp(
sourceTextAttributes.accessibilityRole,
defaultTextAttributes.accessibilityRole);
textAttributes.role = convertRawProp(
context,
rawProps,
"role",
sourceTextAttributes.role,
defaultTextAttributes.role);
// Color (accessed in this order by ViewProps)
textAttributes.opacity = convertRawProp(
context,
@@ -293,6 +300,7 @@ void BaseTextProps::setProp(
textAttributes,
accessibilityRole,
"accessibilityRole");
REBUILD_FIELD_SWITCH_CASE(defaults, value, textAttributes, role, "role");
REBUILD_FIELD_SWITCH_CASE(
defaults, value, textAttributes, opacity, "opacity");
REBUILD_FIELD_SWITCH_CASE(
@@ -136,4 +136,131 @@ enum class AccessibilityLiveRegion : uint8_t {
Assertive,
};
enum class AccessibilityRole {
None,
Button,
Dropdownlist,
Togglebutton,
Link,
Search,
Image,
Keyboardkey,
Text,
Adjustable,
Imagebutton,
Header,
Summary,
Alert,
Checkbox,
Combobox,
Menu,
Menubar,
Menuitem,
Progressbar,
Radio,
Radiogroup,
Scrollbar,
Spinbutton,
Switch,
Tab,
Tabbar,
Tablist,
Timer,
List,
Toolbar,
Grid,
Pager,
Scrollview,
Horizontalscrollview,
Viewgroup,
Webview,
Drawerlayout,
Slidingdrawer,
Iconmenu,
};
enum class Role {
Alert,
Alertdialog,
Application,
Article,
Banner,
Button,
Cell,
Checkbox,
Columnheader,
Combobox,
Complementary,
Contentinfo,
Definition,
Dialog,
Directory,
Document,
Feed,
Figure,
Form,
Grid,
Group,
Heading,
Img,
Link,
List,
Listitem,
Log,
Main,
Marquee,
Math,
Menu,
Menubar,
Menuitem,
Meter,
Navigation,
None,
Note,
Option,
Presentation,
Progressbar,
Radio,
Radiogroup,
Region,
Row,
Rowgroup,
Rowheader,
Scrollbar,
Searchbox,
Separator,
Slider,
Spinbutton,
Status,
Summary,
Switch,
Tab,
Table,
Tablist,
Tabpanel,
Term,
Timer,
Toolbar,
Tooltip,
Tree,
Treegrid,
Treeitem,
};
} // namespace facebook::react
namespace std {
template <>
struct hash<facebook::react::AccessibilityRole> {
size_t operator()(const facebook::react::AccessibilityRole &v) const {
return hash<int>()(static_cast<int>(v));
}
};
template <>
struct hash<facebook::react::Role> {
size_t operator()(const facebook::react::Role &v) const {
return hash<int>()(static_cast<int>(v));
}
};
} // namespace std
@@ -171,6 +171,14 @@ AccessibilityProps::AccessibilityProps(
"importantForAccessibility",
sourceProps.importantForAccessibility,
ImportantForAccessibility::Auto)),
role(
CoreFeatures::enablePropIteratorSetter ? sourceProps.role
: convertRawProp(
context,
rawProps,
"role",
sourceProps.role,
{})),
testId(
CoreFeatures::enablePropIteratorSetter ? sourceProps.testId
: convertRawProp(
@@ -227,6 +235,7 @@ void AccessibilityProps::setProp(
RAW_SET_PROP_SWITCH_CASE_BASIC(onAccessibilityEscape);
RAW_SET_PROP_SWITCH_CASE_BASIC(onAccessibilityAction);
RAW_SET_PROP_SWITCH_CASE_BASIC(importantForAccessibility);
RAW_SET_PROP_SWITCH_CASE_BASIC(role);
RAW_SET_PROP_SWITCH_CASE(testId, "testID");
case CONSTEXPR_RAW_PROPS_KEY_HASH("accessibilityRole"): {
AccessibilityTraits traits = AccessibilityTraits::None;
@@ -57,6 +57,7 @@ class AccessibilityProps {
bool onAccessibilityAction{};
ImportantForAccessibility importantForAccessibility{
ImportantForAccessibility::Auto};
Role role{Role::None};
std::string testId{""};
#pragma mark - DebugStringConvertible
@@ -298,4 +298,486 @@ inline void fromRawValue(
}
}
inline std::string toString(const AccessibilityRole &accessibilityRole) {
switch (accessibilityRole) {
case AccessibilityRole::None:
return "none";
case AccessibilityRole::Button:
return "button";
case AccessibilityRole::Dropdownlist:
return "dropdownlist";
case AccessibilityRole::Togglebutton:
return "togglebutton";
case AccessibilityRole::Link:
return "link";
case AccessibilityRole::Search:
return "search";
case AccessibilityRole::Image:
return "image";
case AccessibilityRole::Keyboardkey:
return "keyboardkey";
case AccessibilityRole::Text:
return "text";
case AccessibilityRole::Adjustable:
return "adjustable";
case AccessibilityRole::Imagebutton:
return "imagebutton";
case AccessibilityRole::Header:
return "header";
case AccessibilityRole::Summary:
return "summary";
case AccessibilityRole::Alert:
return "alert";
case AccessibilityRole::Checkbox:
return "checkbox";
case AccessibilityRole::Combobox:
return "combobox";
case AccessibilityRole::Menu:
return "menu";
case AccessibilityRole::Menubar:
return "menubar";
case AccessibilityRole::Menuitem:
return "menuitem";
case AccessibilityRole::Progressbar:
return "progressbar";
case AccessibilityRole::Radio:
return "radio";
case AccessibilityRole::Radiogroup:
return "radiogroup";
case AccessibilityRole::Scrollbar:
return "scrollbar";
case AccessibilityRole::Spinbutton:
return "spinbutton";
case AccessibilityRole::Switch:
return "switch";
case AccessibilityRole::Tab:
return "tab";
case AccessibilityRole::Tabbar:
return "tabbar";
case AccessibilityRole::Tablist:
return "tablist";
case AccessibilityRole::Timer:
return "timer";
case AccessibilityRole::List:
return "timer";
case AccessibilityRole::Toolbar:
return "toolbar";
case AccessibilityRole::Grid:
return "grid";
case AccessibilityRole::Pager:
return "pager";
case AccessibilityRole::Scrollview:
return "scrollview";
case AccessibilityRole::Horizontalscrollview:
return "horizontalscrollview";
case AccessibilityRole::Viewgroup:
return "viewgroup";
case AccessibilityRole::Webview:
return "webview";
case AccessibilityRole::Drawerlayout:
return "drawerlayout";
case AccessibilityRole::Slidingdrawer:
return "slidingdrawer";
case AccessibilityRole::Iconmenu:
return "iconmenu";
}
LOG(ERROR) << "Unsupported AccessibilityRole value";
react_native_expect(false);
// sane default for prod
return "none";
}
inline void fromRawValue(
const PropsParserContext &context,
const RawValue &value,
AccessibilityRole &result) {
react_native_expect(value.hasType<std::string>());
if (value.hasType<std::string>()) {
auto string = (std::string)value;
if (string == "none") {
result = AccessibilityRole::None;
} else if (string == "button") {
result = AccessibilityRole::Button;
} else if (string == "dropdownlist") {
result = AccessibilityRole::Dropdownlist;
} else if (string == "togglebutton") {
result = AccessibilityRole::Togglebutton;
} else if (string == "link") {
result = AccessibilityRole::Link;
} else if (string == "search") {
result = AccessibilityRole::Search;
} else if (string == "image") {
result = AccessibilityRole::Image;
} else if (string == "keyboardkey") {
result = AccessibilityRole::Keyboardkey;
} else if (string == "text") {
result = AccessibilityRole::Text;
} else if (string == "adjustable") {
result = AccessibilityRole::Adjustable;
} else if (string == "imagebutton") {
result = AccessibilityRole::Imagebutton;
} else if (string == "header") {
result = AccessibilityRole::Header;
} else if (string == "summary") {
result = AccessibilityRole::Summary;
} else if (string == "alert") {
result = AccessibilityRole::Alert;
} else if (string == "checkbox") {
result = AccessibilityRole::Checkbox;
} else if (string == "combobox") {
result = AccessibilityRole::Combobox;
} else if (string == "menu") {
result = AccessibilityRole::Menu;
} else if (string == "menubar") {
result = AccessibilityRole::Menubar;
} else if (string == "menuitem") {
result = AccessibilityRole::Menuitem;
} else if (string == "progressbar") {
result = AccessibilityRole::Progressbar;
} else if (string == "radio") {
result = AccessibilityRole::Radio;
} else if (string == "radiogroup") {
result = AccessibilityRole::Radiogroup;
} else if (string == "scrollbar") {
result = AccessibilityRole::Scrollbar;
} else if (string == "spinbutton") {
result = AccessibilityRole::Spinbutton;
} else if (string == "switch") {
result = AccessibilityRole::Switch;
} else if (string == "tab") {
result = AccessibilityRole::Tab;
} else if (string == "tabbar") {
result = AccessibilityRole::Tabbar;
} else if (string == "tablist") {
result = AccessibilityRole::Tablist;
} else if (string == "timer") {
result = AccessibilityRole::Timer;
} else if (string == "toolbar") {
result = AccessibilityRole::Toolbar;
} else if (string == "grid") {
result = AccessibilityRole::Grid;
} else if (string == "pager") {
result = AccessibilityRole::Pager;
} else if (string == "scrollview") {
result = AccessibilityRole::Scrollview;
} else if (string == "horizontalscrollview") {
result = AccessibilityRole::Horizontalscrollview;
} else if (string == "viewgroup") {
result = AccessibilityRole::Viewgroup;
} else if (string == "webview") {
result = AccessibilityRole::Webview;
} else if (string == "drawerlayout") {
result = AccessibilityRole::Drawerlayout;
} else if (string == "slidingdrawer") {
result = AccessibilityRole::Slidingdrawer;
} else if (string == "iconmenu") {
result = AccessibilityRole::Iconmenu;
} else {
LOG(ERROR) << "Unsupported AccessibilityRole value: " << string;
react_native_expect(false);
// sane default for prod
result = AccessibilityRole::None;
}
return;
}
LOG(ERROR) << "Unsupported AccessibilityRole type";
react_native_expect(false);
// sane default for prod
result = AccessibilityRole::None;
}
inline std::string toString(const Role &role) {
switch (role) {
case Role::Alert:
return "alert";
case Role::Alertdialog:
return "alertdialog";
case Role::Application:
return "application";
case Role::Article:
return "article";
case Role::Banner:
return "banner";
case Role::Button:
return "button";
case Role::Cell:
return "cell";
case Role::Checkbox:
return "checkbox";
case Role::Columnheader:
return "columnheader";
case Role::Combobox:
return "combobox";
case Role::Complementary:
return "complementary";
case Role::Contentinfo:
return "contentinfo";
case Role::Definition:
return "definition";
case Role::Dialog:
return "dialog";
case Role::Directory:
return "directory";
case Role::Document:
return "document";
case Role::Feed:
return "feed";
case Role::Figure:
return "figure";
case Role::Form:
return "form";
case Role::Grid:
return "grid";
case Role::Group:
return "group";
case Role::Heading:
return "heading";
case Role::Img:
return "img";
case Role::Link:
return "link";
case Role::List:
return "list";
case Role::Listitem:
return "listitem";
case Role::Log:
return "log";
case Role::Main:
return "main";
case Role::Marquee:
return "marquee";
case Role::Math:
return "math";
case Role::Menu:
return "menu";
case Role::Menubar:
return "menubar";
case Role::Menuitem:
return "menuitem";
case Role::Meter:
return "meter";
case Role::Navigation:
return "navigation";
case Role::None:
return "none";
case Role::Note:
return "note";
case Role::Option:
return "option";
case Role::Presentation:
return "presentation";
case Role::Progressbar:
return "progressbar";
case Role::Radio:
return "radio";
case Role::Radiogroup:
return "radiogroup";
case Role::Region:
return "region";
case Role::Row:
return "row";
case Role::Rowgroup:
return "rowgroup";
case Role::Rowheader:
return "rowheader";
case Role::Scrollbar:
return "scrollbar";
case Role::Searchbox:
return "searchbox";
case Role::Separator:
return "separator";
case Role::Slider:
return "slider";
case Role::Spinbutton:
return "spinbutton";
case Role::Status:
return "status";
case Role::Summary:
return "summary";
case Role::Switch:
return "switch";
case Role::Tab:
return "tab";
case Role::Table:
return "table";
case Role::Tablist:
return "tablist";
case Role::Tabpanel:
return "tabpanel";
case Role::Term:
return "term";
case Role::Timer:
return "timer";
case Role::Toolbar:
return "toolbar";
case Role::Tooltip:
return "tooltip";
case Role::Tree:
return "tree";
case Role::Treegrid:
return "treegrid";
case Role::Treeitem:
return "treeitem";
}
LOG(ERROR) << "Unsupported Role value";
react_native_expect(false);
// sane default for prod
return "none";
}
inline void fromRawValue(
const PropsParserContext &context,
const RawValue &value,
Role &result) {
react_native_expect(value.hasType<std::string>());
if (value.hasType<std::string>()) {
auto string = (std::string)value;
if (string == "alert") {
result = Role::Alert;
} else if (string == "alertdialog") {
result = Role::Alertdialog;
} else if (string == "application") {
result = Role::Application;
} else if (string == "article") {
result = Role::Article;
} else if (string == "banner") {
result = Role::Banner;
} else if (string == "button") {
result = Role::Button;
} else if (string == "cell") {
result = Role::Cell;
} else if (string == "checkbox") {
result = Role::Checkbox;
} else if (string == "columnheader") {
result = Role::Columnheader;
} else if (string == "combobox") {
result = Role::Combobox;
} else if (string == "complementary") {
result = Role::Complementary;
} else if (string == "contentinfo") {
result = Role::Contentinfo;
} else if (string == "definition") {
result = Role::Definition;
} else if (string == "dialog") {
result = Role::Dialog;
} else if (string == "directory") {
result = Role::Directory;
} else if (string == "document") {
result = Role::Document;
} else if (string == "feed") {
result = Role::Feed;
} else if (string == "figure") {
result = Role::Figure;
} else if (string == "form") {
result = Role::Form;
} else if (string == "grid") {
result = Role::Grid;
} else if (string == "group") {
result = Role::Group;
} else if (string == "heading") {
result = Role::Heading;
} else if (string == "img") {
result = Role::Img;
} else if (string == "link") {
result = Role::Link;
} else if (string == "list") {
result = Role::List;
} else if (string == "listitem") {
result = Role::Listitem;
} else if (string == "log") {
result = Role::Log;
} else if (string == "main") {
result = Role::Main;
} else if (string == "marquee") {
result = Role::Marquee;
} else if (string == "math") {
result = Role::Math;
} else if (string == "menu") {
result = Role::Menu;
} else if (string == "menubar") {
result = Role::Menubar;
} else if (string == "menuitem") {
result = Role::Menuitem;
} else if (string == "meter") {
result = Role::Meter;
} else if (string == "navigation") {
result = Role::Navigation;
} else if (string == "none") {
result = Role::None;
} else if (string == "note") {
result = Role::Note;
} else if (string == "option") {
result = Role::Option;
} else if (string == "presentation") {
result = Role::Presentation;
} else if (string == "progressbar") {
result = Role::Progressbar;
} else if (string == "radio") {
result = Role::Radio;
} else if (string == "radiogroup") {
result = Role::Radiogroup;
} else if (string == "region") {
result = Role::Region;
} else if (string == "row") {
result = Role::Row;
} else if (string == "rowgroup") {
result = Role::Rowgroup;
} else if (string == "rowheader") {
result = Role::Rowheader;
} else if (string == "scrollbar") {
result = Role::Scrollbar;
} else if (string == "searchbox") {
result = Role::Searchbox;
} else if (string == "separator") {
result = Role::Separator;
} else if (string == "slider") {
result = Role::Slider;
} else if (string == "spinbutton") {
result = Role::Spinbutton;
} else if (string == "status") {
result = Role::Status;
} else if (string == "summary") {
result = Role::Summary;
} else if (string == "switch") {
result = Role::Switch;
} else if (string == "tab") {
result = Role::Tab;
} else if (string == "table") {
result = Role::Table;
} else if (string == "tablist") {
result = Role::Tablist;
} else if (string == "tabpanel") {
result = Role::Tabpanel;
} else if (string == "term") {
result = Role::Term;
} else if (string == "timer") {
result = Role::Timer;
} else if (string == "toolbar") {
result = Role::Toolbar;
} else if (string == "tooltip") {
result = Role::Tooltip;
} else if (string == "tree") {
result = Role::Tree;
} else if (string == "treegrid") {
result = Role::Treegrid;
} else if (string == "treeitem") {
result = Role::Treeitem;
} else {
LOG(ERROR) << "Unsupported Role value: " << string;
react_native_expect(false);
// sane default for prod
result = Role::None;
}
return;
}
LOG(ERROR) << "Unsupported Role type";
react_native_expect(false);
// sane default for prod
result = Role::None;
}
} // namespace facebook::react
@@ -297,6 +297,12 @@ NSDictionary<NSAttributedStringKey, id> *RCTNSTextAttributesFromTextAttributes(T
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;
@@ -306,9 +312,6 @@ NSDictionary<NSAttributedStringKey, id> *RCTNSTextAttributesFromTextAttributes(T
case AccessibilityRole::Image:
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("image");
break;
case AccessibilityRole::Imagebutton:
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("imagebutton");
break;
case AccessibilityRole::Keyboardkey:
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("keyboardkey");
break;
@@ -318,12 +321,15 @@ NSDictionary<NSAttributedStringKey, id> *RCTNSTextAttributesFromTextAttributes(T
case AccessibilityRole::Adjustable:
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("adjustable");
break;
case AccessibilityRole::Summary:
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("summary");
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;
@@ -363,7 +369,7 @@ NSDictionary<NSAttributedStringKey, id> *RCTNSTextAttributesFromTextAttributes(T
case AccessibilityRole::Tab:
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("tab");
break;
case AccessibilityRole::TabBar:
case AccessibilityRole::Tabbar:
attributes[RCTTextAttributesAccessibilityRoleAttributeName] = @("tabbar");
break;
case AccessibilityRole::Tablist:
@@ -372,9 +378,39 @@ NSDictionary<NSAttributedStringKey, id> *RCTNSTextAttributesFromTextAttributes(T
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;
};
}