Skip to content

Commit fe101aa

Browse files
jorge-cabfacebook-github-bot
authored andcommitted
Add screenReaderFocusable prop (#50850)
Summary: Pull Request resolved: #50850 This prop will be used to enable screen reader focusability without allowing keyboard focus. Mostly a quality of life prop for product engineers and maps 1:1 to Android Changelog: [Android][Added] - Expose Android's screenReaderFocusable prop Differential Revision: D73382051
1 parent 43403be commit fe101aa

File tree

10 files changed

+46
-5
lines changed

10 files changed

+46
-5
lines changed

packages/react-native/Libraries/Components/View/ViewAccessibility.d.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ export interface AccessibilityProps
101101
}
102102

103103
export type AccessibilityActionInfo = Readonly<{
104-
name: AccessibilityActionName | string;
105-
label?: string | undefined;
104+
name: AccessibilityActionName | string,
105+
label?: string | undefined,
106106
}>;
107107

108108
export type AccessibilityActionName =
@@ -136,8 +136,8 @@ export type AccessibilityActionName =
136136

137137
export type AccessibilityActionEvent = NativeSyntheticEvent<
138138
Readonly<{
139-
actionName: string;
140-
}>
139+
actionName: string,
140+
}>,
141141
>;
142142

143143
export interface AccessibilityState {
@@ -273,6 +273,13 @@ export interface AccessibilityPropsAndroid {
273273
| 'no'
274274
| 'no-hide-descendants'
275275
| undefined;
276+
277+
/**
278+
* Enables the view to be screen reader focusable, not keyboard focusable.
279+
*
280+
* @platform android
281+
*/
282+
screenReaderFocusable?: boolean | undefined;
276283
}
277284

278285
export interface AccessibilityPropsIOS {

packages/react-native/Libraries/Components/View/ViewAccessibility.js

+8
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,14 @@ export type AccessibilityPropsAndroid = $ReadOnly<{
258258
* See https://reactnative.dev/docs/view#importantforaccessibility
259259
*/
260260
importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'),
261+
262+
/**
263+
* Enables the view to be screen reader focusable, not keyboard focusable. This has lower priority
264+
* than focusable or accessible props.
265+
*
266+
* @platform android
267+
*/
268+
screenReaderFocusable?: boolean,
261269
}>;
262270

263271
export type AccessibilityPropsIOS = $ReadOnly<{

packages/react-native/Libraries/NativeComponent/BaseViewConfig.android.js

+1
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ const validAttributesForNonEventProps = {
205205
accessibilityValue: true,
206206
experimental_accessibilityOrder: true,
207207
importantForAccessibility: true,
208+
screenReaderFocusable: true,
208209
role: true,
209210
rotation: true,
210211
scaleX: true,

packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap

+1
Original file line numberDiff line numberDiff line change
@@ -3642,6 +3642,7 @@ export type AccessibilityPropsAndroid = $ReadOnly<{
36423642
accessibilityLiveRegion?: ?(\\"none\\" | \\"polite\\" | \\"assertive\\"),
36433643
\\"aria-live\\"?: ?(\\"polite\\" | \\"assertive\\" | \\"off\\"),
36443644
importantForAccessibility?: ?(\\"auto\\" | \\"yes\\" | \\"no\\" | \\"no-hide-descendants\\"),
3645+
screenReaderFocusable?: ?boolean,
36453646
}>;
36463647
export type AccessibilityPropsIOS = $ReadOnly<{
36473648
accessibilityIgnoresInvertColors?: ?boolean,

packages/react-native/ReactAndroid/api/ReactAndroid.api

+2
Original file line numberDiff line numberDiff line change
@@ -3524,6 +3524,7 @@ public abstract class com/facebook/react/uimanager/BaseViewManager : com/faceboo
35243524
public fun setRotation (Landroid/view/View;F)V
35253525
public fun setScaleX (Landroid/view/View;F)V
35263526
public fun setScaleY (Landroid/view/View;F)V
3527+
public fun setScreenReaderFocusable (Landroid/view/View;Ljava/lang/Boolean;)V
35273528
public fun setShadowColor (Landroid/view/View;I)V
35283529
public fun setShouldBlockNativeResponder (Landroid/view/View;Z)V
35293530
public fun setStartShouldSetResponder (Landroid/view/View;Z)V
@@ -4896,6 +4897,7 @@ public final class com/facebook/react/uimanager/ViewProps {
48964897
public static final field ROW_GAP Ljava/lang/String;
48974898
public static final field SCALE_X Ljava/lang/String;
48984899
public static final field SCALE_Y Ljava/lang/String;
4900+
public static final field SCREEN_READER_FOCUSABLE Ljava/lang/String;
48994901
public static final field SCROLL Ljava/lang/String;
49004902
public static final field SHADOW_COLOR Ljava/lang/String;
49014903
public static final field START Ljava/lang/String;

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java

+11
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,17 @@ public void setImportantForAccessibility(
513513
}
514514
}
515515

516+
@ReactProp(name = ViewProps.SCREEN_READER_FOCUSABLE)
517+
public void setScreenReaderFocusable(@NonNull T view, @Nullable Boolean screenReaderFocusable) {
518+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
519+
if (screenReaderFocusable != null) {
520+
view.setScreenReaderFocusable(screenReaderFocusable);
521+
} else {
522+
view.setScreenReaderFocusable(false);
523+
}
524+
}
525+
}
526+
516527
@ReactProp(name = ViewProps.ROLE)
517528
public void setRole(@NonNull T view, @Nullable String role) {
518529
if (role == null) {

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

+1
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ public object ViewProps {
159159
public const val ACCESSIBILITY_LABELLED_BY: String = "accessibilityLabelledBy"
160160
public const val ACCESSIBILITY_ORDER: String = "experimental_accessibilityOrder"
161161
public const val IMPORTANT_FOR_ACCESSIBILITY: String = "importantForAccessibility"
162+
public const val SCREEN_READER_FOCUSABLE: String = "screenReaderFocusable"
162163
public const val ROLE: String = "role"
163164
// DEPRECATED
164165
public const val ROTATION: String = "rotation"

packages/react-native/ReactCommon/react/renderer/components/view/AccessibilityProps.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,15 @@ AccessibilityProps::AccessibilityProps(
199199
"importantForAccessibility",
200200
sourceProps.importantForAccessibility,
201201
ImportantForAccessibility::Auto)),
202+
screenReaderFocusable(
203+
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
204+
? sourceProps.screenReaderFocusable
205+
: convertRawProp(
206+
context,
207+
rawProps,
208+
"screenReaderFocusable",
209+
sourceProps.screenReaderFocusable,
210+
false)),
202211
testId(
203212
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
204213
? sourceProps.testId

packages/react-native/ReactCommon/react/renderer/components/view/AccessibilityProps.h

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class AccessibilityProps {
5555
bool onAccessibilityAction{};
5656
ImportantForAccessibility importantForAccessibility{
5757
ImportantForAccessibility::Auto};
58+
bool screenReaderFocusable{false};
5859
Role role{Role::None};
5960
std::string testId;
6061

packages/react-native/ReactCommon/react/renderer/components/view/ViewShadowNode.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ void ViewShadowNode::initialize() noexcept {
6363
viewProps.mixBlendMode != BlendMode::Normal ||
6464
viewProps.isolation == Isolation::Isolate ||
6565
HostPlatformViewTraitsInitializer::formsStackingContext(viewProps) ||
66-
!viewProps.accessibilityOrder.empty();
66+
!viewProps.accessibilityOrder.empty() || viewProps.screenReaderFocusable;
6767

6868
bool formsView = formsStackingContext ||
6969
isColorMeaningful(viewProps.backgroundColor) || hasBorder() ||

0 commit comments

Comments
 (0)