Add accessibilityValueDescription support. (#26169)

Summary:
React Native components need a mechanism to specify their value to assistive technologies. This PR adds the notion of accessibilityValueDescription-- a property which either contains a textual description of a component's value, or for range-based components, such as sliders and progress bars, it contains range information (minimum, current, and maximum).

On iOS, the range-based info if present is converted into a percentage and added to the accessibilityValue property of the UIView. If text is present as part of the accessibilityValueDescription, it is used instead of the range-based information.

On Android, any range-based information in accessibilityValueDescription is exposed in the AccessibilityNodeInfo's RangeInfo. Text which is part of accessibilityValueDescription is appended to the content description.

## Changelog

[GENERAL] [Change] - add accessibilityValuedescription property.
Pull Request resolved: https://github.com/facebook/react-native/pull/26169

Test Plan: Added two new accessibility examples to RNTester, one which uses text and another which uses range-based info in accessibilityValueDescription. Verified that they both behave correctly on both Android and iOS.

Differential Revision: D17444730

Pulled By: cpojer

fbshipit-source-id: 1fb3252a90f88f7cafe1cbf7db08c03f14cc2321
This commit is contained in:
Marc Mulcahy authored and Facebook Github Bot committed 2019-09-18 03:16:42 -07:00
1 parent 7c8e266e39
commit 7df3eea1a7
14 files changed
+268 -3

No files matched your search

@@ -179,6 +179,7 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
final ReadableMap accessibilityState = (ReadableMap) view.getTag(R.id.accessibility_state);
final String accessibilityHint = (String) view.getTag(R.id.accessibility_hint);
final List<String> contentDescription = new ArrayList<>();
final ReadableMap accessibilityValue = (ReadableMap) view.getTag(R.id.accessibility_value);
if (accessibilityLabel != null) {
contentDescription.add(accessibilityLabel);
}
@@ -205,6 +206,12 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
}
}
}
if (accessibilityValue != null && accessibilityValue.hasKey("text")) {
final Dynamic text = accessibilityValue.getDynamic("text");
if (text != null && text.getType() == ReadableType.String) {
contentDescription.add(text.asString());
}
}
if (accessibilityHint != null) {
contentDescription.add(accessibilityHint);
}
@@ -223,6 +230,18 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
view.setTag(R.id.accessibility_actions, accessibilityActions);
}
@ReactProp(name = ViewProps.ACCESSIBILITY_VALUE)
public void setAccessibilityValue(T view, ReadableMap accessibilityValue) {
if (accessibilityValue == null) {
return;
}
view.setTag(R.id.accessibility_value, accessibilityValue);
if (accessibilityValue.hasKey("text")) {
updateViewContentDescription(view);
}
}
@Override
@ReactProp(name = ViewProps.IMPORTANT_FOR_ACCESSIBILITY)
public void setImportantForAccessibility(