Skip to content

Commit 05f99a7

Browse files
jeltehommingameta-codesync[bot]
authored andcommitted
Map role="slider" to the adjustable accessibility trait on iOS (#59463)
Summary: Hi, I'm a React Native developer. Thanks for the recent iOS accessibility work. On iOS, `role="slider"` ends up with no accessibility traits, so VoiceOver doesn't treat the view as adjustable. `accessibilityRole="adjustable"` on the same view works. The traits come from `fromString(const std::string &, AccessibilityTraits &)` in `accessibilityPropsConversions.h`, which has an `"adjustable"` case but no `"slider"` case. Before the ARIA roles moved to native in #37309, the JS mapping turned `role: 'slider'` into `accessibilityRole: 'adjustable'`, so this used to work. The native table maps `slider` to no trait instead. This adds `slider` to the `adjustable` case, the same way `img`/`image` and `heading`/`header` share a case. Android doesn't read `accessibilityTraits`, so only iOS changes. It only touches `slider`. The other roles listed in #50123 stay as they are, since the comment above `RCTViewIsInteractiveAccessibilityElement` says some of them carry no trait on purpose. I also left the legacy `RCTViewManager.m` table alone, which maps `slider` to `UIAccessibilityTraitNone` as well. Happy to change that one too if it's still wanted. Part of #50123. ## Changelog: [IOS] [FIXED] - `role="slider"` now gets the adjustable accessibility trait, like `accessibilityRole="adjustable"` Pull Request resolved: #59463 Test Plan: RNTester on an iPhone 18 Pro simulator (iOS 27.0), with the Playground rendering: ```tsx <View accessible role="slider" accessibilityLabel="Role slider" accessibilityValue={{min: 0, max: 10, now: 5}} /> <View accessible accessibilityRole="adjustable" accessibilityLabel="AccessibilityRole adjustable" accessibilityValue={{min: 0, max: 10, now: 5}} /> ``` The simulator's accessibility tree for both views: ``` main Role slider AXGroup traits: none AccessibilityRole adjustable AXAdjustable traits: adjustable this PR Role slider AXAdjustable traits: adjustable AccessibilityRole adjustable AXAdjustable traits: adjustable ``` - Added `derives_adjustable_trait_from_slider_role` to `AccessibilityPropsTest.cpp`, next to `derives_traits_from_role`. I couldn't run it, because I didn't find a way to run the ReactCommon gtests from the open-source checkout. - `node scripts/clang-format.js --check` passes on both files. - Not checked: the legacy architecture. Reviewed By: christophpurrer Differential Revision: D127482367 Pulled By: Abbondanzo fbshipit-source-id: bd315b64e1492c92d7a2b20831bab2dd636d2360
1 parent 1d1fade commit 05f99a7

2 files changed

Lines changed: 8 additions & 1 deletion

File tree

‎packages/react-native/ReactCommon/react/renderer/components/view/accessibilityPropsConversions.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ inline void fromString(const std::string &string, AccessibilityTraits &result)
7171
result = AccessibilityTraits::StartsMediaSession;
7272
return;
7373
}
74-
if (string == "adjustable") {
74+
if (string == "adjustable" || string == "slider") {
7575
result = AccessibilityTraits::Adjustable;
7676
return;
7777
}

‎packages/react-native/ReactCommon/react/renderer/components/view/tests/AccessibilityPropsTest.cpp‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ TEST(AccessibilityPropsTest, derives_traits_from_role) {
4444
EXPECT_TRUE(hasTrait(props.accessibilityTraits, AccessibilityTraits::Button));
4545
}
4646

47+
TEST(AccessibilityPropsTest, derives_adjustable_trait_from_slider_role) {
48+
auto props = parse(folly::dynamic::object("role", "slider"));
49+
50+
EXPECT_TRUE(
51+
hasTrait(props.accessibilityTraits, AccessibilityTraits::Adjustable));
52+
}
53+
4754
TEST(AccessibilityPropsTest, derives_traits_from_accessibility_role) {
4855
auto props = parse(folly::dynamic::object("accessibilityRole", "image"));
4956

0 commit comments

Comments
 (0)