Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Libraries/Components/View/ViewPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,13 @@ export type ViewProps = $ReadOnly<{|
*/
accessibilityActions?: ?$ReadOnlyArray<AccessibilityActionInfo>,

/**
* Specifies the nativeID of the associated label text. When the assistive technology focuses on the component with this props, the text is read aloud.
*
* @platform android
*/
accessibilityLabelledBy?: ?string | ?Array<string>,

/**
* Views that are only used to layout their children or otherwise don't draw
* anything may be automatically removed from the native hierarchy as an
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,21 @@ public void setNativeId(@NonNull T view, @Nullable String nativeId) {
ReactFindViewUtil.notifyViewRendered(view);
}

@Override
@ReactProp(name = ViewProps.ACCESSIBILITY_LABELLED_BY)
public void setAccessibilityLabelledBy(@NonNull T view, @Nullable Dynamic nativeId) {
if (nativeId.isNull()) {
return;
}
if (nativeId.getType() == ReadableType.String) {
view.setTag(R.id.labelled_by, nativeId.asString());
} else if (nativeId.getType() == ReadableType.Array) {
// On Android, this takes a single View as labeledBy. If an array is specified, set the first
// element in the tag.
view.setTag(R.id.labelled_by, nativeId.asArray().getString(0));
}
}

@Override
@ReactProp(name = ViewProps.ACCESSIBILITY_LABEL)
public void setAccessibilityLabel(@NonNull T view, @Nullable String accessibilityLabel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;

Expand Down Expand Up @@ -64,6 +65,9 @@ public void setImportantForAccessibility(
@Override
public void setNativeId(@NonNull T view, String nativeId) {}

@Override
public void setAccessibilityLabelledBy(@NonNull T view, Dynamic nativeId) {}

@Override
public void setOpacity(@NonNull T view, float opacity) {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.events.Event;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.uimanager.util.ReactFindViewUtil;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

google-java-format suggested changes:

@@ -39,0 +39 @@
+import java.util.HashMap;

import java.util.HashMap;

/**
Expand Down Expand Up @@ -191,6 +192,8 @@ public void handleMessage(Message msg) {
};
}

@Nullable View mAccessibilityLabelledBy;

@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
Expand All @@ -200,6 +203,15 @@ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCo
setRole(info, accessibilityRole, host.getContext());
}

final Object accessibilityLabelledBy = host.getTag(R.id.labelled_by);
if (accessibilityLabelledBy != null) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

google-java-format suggested changes:

@@ -206,12 +206,11 @@
-        ReactFindViewUtil.findView(
-            host.getRootView(),
-            new ReactFindViewUtil.OnViewFoundListener() {
-                @Override
-                public String getNativeId() {
-                  return (String) accessibilityLabelledBy;
-                }
-
-                @Override
-                public void onViewFound(View view) {
-                  info.setLabeledBy(view);
-                }
+      ReactFindViewUtil.findView(
+          host.getRootView(),
+          new ReactFindViewUtil.OnViewFoundListener() {
+            @Override
+            public String getNativeId() {
+              return (String) accessibilityLabelledBy;
+            }
+
+            @Override
+            public void onViewFound(View view) {
+              info.setLabeledBy(view);

mAccessibilityLabelledBy =
ReactFindViewUtil.findView(host.getRootView(), (String) accessibilityLabelledBy);
if (mAccessibilityLabelledBy != null) {
info.setLabeledBy(mAccessibilityLabelledBy);
}
}

// state is changeable.
final ReadableMap accessibilityState = (ReadableMap) host.getTag(R.id.accessibility_state);
if (accessibilityState != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import android.view.View;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.ColorPropConverter;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.yoga.YogaConstants;
Expand Down Expand Up @@ -84,6 +85,9 @@ public void setProperty(T view, String propName, @Nullable Object value) {
case ViewProps.NATIVE_ID:
mViewManager.setNativeId(view, (String) value);
break;
case ViewProps.ACCESSIBILITY_LABELLED_BY:
mViewManager.setAccessibilityLabelledBy(view, (Dynamic) value);
break;
case ViewProps.OPACITY:
mViewManager.setOpacity(view, value == null ? 1.0f : ((Double) value).floatValue());
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import android.view.View;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;

Expand Down Expand Up @@ -49,6 +50,8 @@ public interface BaseViewManagerInterface<T extends View> {

void setNativeId(T view, @Nullable String nativeId);

void setAccessibilityLabelledBy(T view, @Nullable Dynamic nativeId);

void setOpacity(T view, float opacity);

void setRenderToHardwareTexture(T view, boolean useHWTexture);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ public class ViewProps {
public static final String ACCESSIBILITY_STATE = "accessibilityState";
public static final String ACCESSIBILITY_ACTIONS = "accessibilityActions";
public static final String ACCESSIBILITY_VALUE = "accessibilityValue";
public static final String ACCESSIBILITY_LABELLED_BY = "accessibilityLabelledBy";
public static final String IMPORTANT_FOR_ACCESSIBILITY = "importantForAccessibility";

// DEPRECATED
Expand Down
3 changes: 3 additions & 0 deletions ReactAndroid/src/main/res/views/uimanager/values/ids.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,7 @@
<!--tag is used to store accessibilityValue tag -->
<item type="id" name="accessibility_value"/>

<!--tag is used to store accessibilityLabelledBy tag -->
<item type="id" name="labelled_by"/>

</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,24 @@ class AccessibilityExample extends React.Component<{}> {
<Text>Accessible view with label, hint, role, and state</Text>
</View>
</RNTesterBlock>

<RNTesterBlock title="TextInput with accessibilityLabelledBy attribute">
<View>
<Text nativeID="formLabel1">Mail Address</Text>
<TextInput
accessibilityLabel="input test1"
accessibilityLabelledBy="formLabel1"
style={styles.default}
/>
<Text nativeID="formLabel2">First Name</Text>
<TextInput
accessibilityLabel="input test2"
accessibilityLabelledBy={['formLabel2', 'formLabel3']}
style={styles.default}
value="Foo"
/>
</View>
</RNTesterBlock>
</View>
);
}
Expand Down