-
Notifications
You must be signed in to change notification settings - Fork 24.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create a ClickableSpan for nested Text components
Summary: Right now nested Text components are not accessible on Android. This is because we only create a native ReactTextView for the parent component; the styling and touch handling for the child component are handled using spans. In order for TalkBack to announce the link, we need to linkify the text using a ClickableSpan. This diff adds ReactClickableSpan, which TextLayoutManager uses to linkify a span of text when its corresponding React component has `accessibilityRole="link"`. For example: <Text> A paragraph with some <Text accessible={true} accessibilityRole="link" onPress={onPress} onClick={onClick}>links</Text> surrounded by other text. </Text> With this diff, the child Text component will be announced by TalkBack ('links available') and exposed as an option in the context menu. Clicking on the link in the context menu fires the Text component's onClick, which we're explicitly forwarding to onPress in Text.js (for now - ideally this would probably use a separate event, but that would involve wiring it up in the renderer as well). ReactClickableSpan also applies text color from React if it exists; this is to override the default Android link styling (teal + underline). Changelog: [Android][Fixed] Make nested Text components accessible as links Reviewed By: yungsters, mdvacca Differential Revision: D23553222 fbshipit-source-id: a962b2833d73ec81047e86cfb41846513c486d87
- Loading branch information
1 parent
b705eaf
commit b352e2d
Showing
5 changed files
with
100 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
ReactAndroid/src/main/java/com/facebook/react/views/text/ReactClickableSpan.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* | ||
* Copyright (c) Facebook, Inc. and its affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
package com.facebook.react.views.text; | ||
|
||
import android.text.TextPaint; | ||
import android.text.style.ClickableSpan; | ||
import android.view.View; | ||
import androidx.annotation.NonNull; | ||
import com.facebook.react.bridge.ReactContext; | ||
import com.facebook.react.uimanager.UIManagerHelper; | ||
import com.facebook.react.uimanager.events.EventDispatcher; | ||
import com.facebook.react.views.view.ViewGroupClickEvent; | ||
|
||
/** | ||
* This class is used in {@link TextLayoutManager} to linkify and style a span of text with | ||
* accessibilityRole="link". This is needed to make nested Text components accessible. | ||
* | ||
* <p>For example, if your React component looks like this: | ||
* | ||
* <pre>{@code | ||
* <Text> | ||
* Some text with | ||
* <Text onPress={onPress} accessible={true} accessibilityRole="link">a link</Text> | ||
* in the middle. | ||
* </Text> | ||
* }</pre> | ||
* | ||
* then only one {@link ReactTextView} will be created, for the parent. The child Text component | ||
* does not exist as a native view, and therefore has no accessibility properties. Instead, we have | ||
* to use spans on the parent's {@link ReactTextView} to properly style the child, and to make it | ||
* accessible (TalkBack announces that the text has links available, and the links are exposed in | ||
* the context menu). | ||
*/ | ||
class ReactClickableSpan extends ClickableSpan implements ReactSpan { | ||
|
||
private final int mReactTag; | ||
private final int mForegroundColor; | ||
|
||
ReactClickableSpan(int reactTag, int foregroundColor) { | ||
mReactTag = reactTag; | ||
mForegroundColor = foregroundColor; | ||
} | ||
|
||
@Override | ||
public void onClick(@NonNull View view) { | ||
ReactContext context = (ReactContext) view.getContext(); | ||
EventDispatcher eventDispatcher = | ||
UIManagerHelper.getEventDispatcherForReactTag(context, mReactTag); | ||
if (eventDispatcher != null) { | ||
eventDispatcher.dispatchEvent(new ViewGroupClickEvent(mReactTag)); | ||
} | ||
} | ||
|
||
@Override | ||
public void updateDrawState(@NonNull TextPaint ds) { | ||
super.updateDrawState(ds); | ||
ds.setColor(mForegroundColor); | ||
ds.setUnderlineText(false); | ||
} | ||
|
||
public int getReactTag() { | ||
return mReactTag; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters