Skip to content

Commit cff022c

Browse files
committed
Only set stateDescription for the unchecked state of non-switch roles
TalkBack already announces the checked state of a checkable node in the device language. React Native's state strings are translated by Meta's internal pipeline after import, so a new string would be English-only for a while. Keep the switch on/off strings, which are already translated in every locale, and only fill the case TalkBack is silent on: unchecked checkboxes and radios. Drop the unused state_checked_description.
1 parent 6c5b5b4 commit cff022c

3 files changed

Lines changed: 13 additions & 14 deletions

File tree

‎packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.kt‎

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -643,8 +643,11 @@ public open class ReactAccessibilityDelegate( // The View this delegate is attac
643643
info.isChecked = boolValue
644644
// TalkBack only speaks the unchecked state of a checkable node, and only avoids
645645
// announcing "checked" and "on" together for a switch, when the node carries a
646-
// stateDescription (API 30+). Native CompoundButton always sets it, so do the same.
647-
info.stateDescription = getCheckedStateDescription(boolValue, role, context)
646+
// stateDescription (API 30+), as native CompoundButton sets.
647+
val stateDescription = getCheckedStateDescription(boolValue, role, context)
648+
if (stateDescription != null) {
649+
info.stateDescription = stateDescription
650+
}
648651
}
649652
}
650653
}
@@ -653,16 +656,17 @@ public open class ReactAccessibilityDelegate( // The View this delegate is attac
653656
checked: Boolean,
654657
role: AccessibilityRole?,
655658
context: Context,
656-
): String =
659+
): String? =
657660
if (role == AccessibilityRole.SWITCH) {
658661
context.getString(
659662
if (checked) R.string.state_on_description else R.string.state_off_description
660663
)
664+
} else if (!checked) {
665+
context.getString(R.string.state_unchecked_description)
661666
} else {
662-
context.getString(
663-
if (checked) R.string.state_checked_description
664-
else R.string.state_unchecked_description
665-
)
667+
// Leave the checked state to TalkBack, which already announces it in the device
668+
// language.
669+
null
666670
}
667671

668672
// TODO: Eventually support for other languages on talkback

‎packages/react-native/ReactAndroid/src/main/res/views/uimanager/values/strings.xml‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,6 @@
9696
name="state_off_description"
9797
description="a switch in its disabled state"
9898
>off</string>
99-
<string
100-
name="state_checked_description"
101-
description="a checkbox, radio button, or other checkable widget which is checked"
102-
>checked</string>
10399
<string
104100
name="state_unchecked_description"
105101
description="a checkbox, radio button, or other checkable widget which is not checked"

‎packages/react-native/ReactAndroid/src/test/java/com/facebook/react/uimanager/ReactAccessibilityDelegateTest.kt‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -395,13 +395,12 @@ class ReactAccessibilityDelegateTest {
395395
}
396396

397397
@Test
398-
fun testOnInitializeAccessibilityNodeInfo_checkedCheckbox_setsStateDescription() {
398+
fun testOnInitializeAccessibilityNodeInfo_checkedCheckbox_leavesStateDescriptionUnset() {
399399
val info = initializeNodeInfoWithCheckedState(AccessibilityRole.CHECKBOX, checked = true)
400400

401401
assertThat(info.isCheckable).isTrue()
402402
assertThat(info.isChecked).isTrue()
403-
assertThat(info.stateDescription)
404-
.isEqualTo(view.context.getString(R.string.state_checked_description))
403+
assertThat(info.stateDescription).isNull()
405404
}
406405

407406
@Test

0 commit comments

Comments
 (0)