Skip to content

Commit

Permalink
Add setLabeledBy
Browse files Browse the repository at this point in the history
Summary:
Adding setLabeledBy to style.

In android we would pass a view, but i think working with tags makes more sense (?)
Im happy to hear any other feedback about how better to implement this.

other improvement I see is just add the special labeledBy view tag id, so we wont override it with any other view ids if we would set somethign on it. (But if we are setting labeled by I would think they will know what they are doing (?))

there are two methods:
```
public void setLabeledBy (View label)
and
public void setLabeledBy (View root,
                int virtualDescendantId)
```

As there is a workaround to set this using:

```
Text(
    text = "I'm a text",
    style =
        Style.onInitializeAccessibilityNodeInfo { event ->
              event.superDelegate.onInitializeAccessibilityNodeInfo(
                  event.host, event.info)
              val parentView = event.host.parent as View
              if (placeholderText == null) {
                event.info.setLabeledBy(......)
              }
            }
       )

```
I focused only on the first simplier method

Reviewed By: zielinskimz

Differential Revision: D65419674

fbshipit-source-id: 71519ba442cb9d7327ba7c47c72e31ff557d7ae3
  • Loading branch information
Anna Powolny authored and facebook-github-bot committed Nov 5, 2024
1 parent e679f09 commit bc0cb49
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 0 deletions.
4 changes: 4 additions & 0 deletions litho-core/src/main/java/com/facebook/litho/CommonProps.kt
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,10 @@ class CommonProps : LayoutProps, Equivalence<CommonProps?> {
getOrCreateNodeInfo().minDurationBetweenContentChangesMillis = duration
}

fun setLabeledBy(viewTag: Any?) {
getOrCreateNodeInfo().labeledBy = viewTag
}

fun clickable(isClickable: Boolean) {
getOrCreateNodeInfo().setClickable(isClickable)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,14 @@ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCo
mNodeInfo.getMinDurationBetweenContentChangesMillis());
}

if (mNodeInfo != null && mNodeInfo.getLabeledBy() != null && mountItem != null) {
final ComponentContext scopedContext = getComponentContext(mountItem.getRenderTreeNode());
final View labeledByView = scopedContext.findViewWithTag(mNodeInfo.getLabeledBy());
if (labeledByView != null) {
node.setLabeledBy(labeledByView);
}
}

if (mNodeInfo != null && mNodeInfo.getFocusOrder() != null && mountItem != null) {
final ComponentContext scopedContext = getComponentContext(mountItem.getRenderTreeNode());
final FocusOrderModel focusOrder = mNodeInfo.getFocusOrder();
Expand Down
16 changes: 16 additions & 0 deletions litho-core/src/main/java/com/facebook/litho/NodeInfo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ class NodeInfo : Equivalence<NodeInfo> {
EventHandler<SendAccessibilityEventUncheckedEvent>? =
null
private var _minDurationBetweenContentChangesMillis: Long? = null
private var _labeledBy: Any? = null

var visibility: Visibility? = null
internal set(value) {
Expand Down Expand Up @@ -412,6 +413,13 @@ class NodeInfo : Equivalence<NodeInfo> {
_minDurationBetweenContentChangesMillis = duration
}

var labeledBy: Any?
get() = _labeledBy
set(viewTag) {
flags = flags or PFLAG_LABELED_BY_IS_SET
_labeledBy = viewTag
}

fun needsAccessibilityDelegate(): Boolean =
_onInitializeAccessibilityEventHandler != null ||
_onInitializeAccessibilityNodeInfoHandler != null ||
Expand All @@ -427,6 +435,7 @@ class NodeInfo : Equivalence<NodeInfo> {
_accessibilityRole != null ||
_accessibilityRoleDescription != null ||
_focusOrder != null ||
_labeledBy != null ||
screenReaderFocusState != SCREEN_READER_FOCUS_UNSET

fun setFocusable(isFocusable: Boolean) {
Expand Down Expand Up @@ -822,6 +831,9 @@ class NodeInfo : Equivalence<NodeInfo> {
if (flags and PFLAG_VISIBILITY_IS_SET != 0L) {
target.visibility = visibility
}
if (flags and PFLAG_LABELED_BY_IS_SET != 0L) {
target.labeledBy = labeledBy
}
}

fun copyInto(target: ViewAttributes) {
Expand Down Expand Up @@ -1030,5 +1042,9 @@ class NodeInfo : Equivalence<NodeInfo> {
// When this flag is set, setMinDurationBetweenContentChangesMillis was explicitly set on this
// node.
private const val PFLAG_MIN_DURATION_BETWEEN_CHANGES_IS_SET = 1L shl 36

// When this flag is set, setLabeledBy was explicitly set on this
// node.
private const val PFLAG_LABELED_BY_IS_SET = 1L shl 36
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ internal enum class AccessibilityField : StyleItemField {
ON_VIRTUAL_VIEW_KEYBOARD_FOCUS_CHANGED,
SCREEN_READER_FOCUSABLE,
MIN_DURATION_BETWEEN_CONTENT_CHANGES,
LABELED_BY,
}

@PublishedApi
Expand Down Expand Up @@ -114,6 +115,7 @@ internal data class AccessibilityStyleItem(
commonProps.screenReaderFocusable(value as Boolean)
AccessibilityField.MIN_DURATION_BETWEEN_CONTENT_CHANGES ->
commonProps.setMinDurationBetweenContentChangesMillis(value as Long)
AccessibilityField.LABELED_BY -> commonProps.setLabeledBy(value)
}
}
}
Expand Down Expand Up @@ -325,6 +327,17 @@ inline fun Style.screenReaderFocusable(isFocusable: Boolean): Style =
inline fun Style.minDurationBetweenContentChangesMillis(duration: Long): Style =
this + AccessibilityStyleItem(AccessibilityField.MIN_DURATION_BETWEEN_CONTENT_CHANGES, duration)

/**
* Sets the view which serves as the label of the view represented by this info for accessibility
* purposes.
*
* @param viewTag The view tag of the view which serves as the label of the view represented by this
*
* See [android.view.accessibility.AccessibilityNodeInfo.setLabeledBy].
*/
inline fun Style.labeledBy(viewTag: Any): Style =
this + AccessibilityStyleItem(AccessibilityField.LABELED_BY, viewTag)

/**
* Enum values for [importantForAccessibility].
*
Expand Down

0 comments on commit bc0cb49

Please sign in to comment.