Skip to content

Commit dbeb228

Browse files
add onAccessibilityBlur/onAccessibilityFocus events
1 parent 4537131 commit dbeb228

File tree

19 files changed

+301
-24
lines changed

19 files changed

+301
-24
lines changed

Libraries/Components/Button.js

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,17 @@ const View = require('./View/View');
2121

2222
const invariant = require('invariant');
2323

24-
import type {PressEvent} from '../Types/CoreEventTypes';
2524
import type {ColorValue} from '../StyleSheet/StyleSheet';
25+
import type {PressEvent, SyntheticEvent} from '../Types/CoreEventTypes';
26+
27+
type TargetEvent = SyntheticEvent<
28+
$ReadOnly<{|
29+
target: number,
30+
|}>,
31+
>;
32+
33+
type AccessibilityBlurEvent = TargetEvent;
34+
type AccessibilityFocusEvent = TargetEvent;
2635

2736
type ButtonProps = $ReadOnly<{|
2837
/**
@@ -134,6 +143,24 @@ type ButtonProps = $ReadOnly<{|
134143
Used to locate this view in end-to-end tests.
135144
*/
136145
testID?: ?string,
146+
147+
/**
148+
* When `accessible` is true and VoiceOver (iOS) or TalkBack (Android) is
149+
* enabled, this event is fired immediately once the element loses the screen
150+
* reader focus.
151+
*
152+
* See http://facebook.github.io/react-native/docs/view.html#onaccessibilityblur
153+
*/
154+
onAccessibilityBlur: (event?: AccessibilityBlurEvent) => mixed,
155+
156+
/**
157+
* When `accessible` is true and VoiceOver (iOS) or TalkBack (Android) is
158+
* enabled, this event is fired immediately once the element gains the screen
159+
* reader focus.
160+
*
161+
* See http://facebook.github.io/react-native/docs/view.html#onaccessibilityfocus
162+
*/
163+
onAccessibilityFocus: (event?: AccessibilityFocusEvent) => mixed,
137164
|}>;
138165

139166
/**
@@ -251,6 +278,8 @@ class Button extends React.Component<ButtonProps> {
251278
render(): React.Node {
252279
const {
253280
accessibilityLabel,
281+
onAccessibilityBlur,
282+
onAccessibilityFocus,
254283
color,
255284
onPress,
256285
touchSoundDisabled,
@@ -292,6 +321,8 @@ class Button extends React.Component<ButtonProps> {
292321
accessibilityLabel={accessibilityLabel}
293322
accessibilityRole="button"
294323
accessibilityState={accessibilityState}
324+
onAccessibilityBlur={onAccessibilityBlur}
325+
onAccessibilityFocus={onAccessibilityFocus}
295326
hasTVPreferredFocus={hasTVPreferredFocus}
296327
nextFocusDown={nextFocusDown}
297328
nextFocusForward={nextFocusForward}

Libraries/Components/TextInput/TextInput.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ const invariant = require('invariant');
2323
const nullthrows = require('nullthrows');
2424
const setAndForwardRef = require('../../Utilities/setAndForwardRef');
2525

26+
import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
2627
import type {TextStyleProp, ViewStyleProp} from '../../StyleSheet/StyleSheet';
2728
import type {ColorValue} from '../../StyleSheet/StyleSheet';
28-
import type {ViewProps} from '../View/ViewPropTypes';
29-
import type {SyntheticEvent, ScrollEvent} from '../../Types/CoreEventTypes';
29+
import type {ScrollEvent, SyntheticEvent} from '../../Types/CoreEventTypes';
3030
import type {PressEvent} from '../../Types/CoreEventTypes';
31-
import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
31+
import type {ViewProps} from '../View/ViewPropTypes';
3232
import type {TextInputNativeCommands} from './TextInputNativeCommands';
3333

3434
const {useLayoutEffect, useRef, useState} = React;
@@ -96,6 +96,8 @@ type TargetEvent = SyntheticEvent<
9696

9797
export type BlurEvent = TargetEvent;
9898
export type FocusEvent = TargetEvent;
99+
export type AccessibilityBlurEvent = TargetEvent;
100+
export type AccessibilityFocusEvent = TargetEvent;
99101

100102
type Selection = $ReadOnly<{|
101103
start: number,
@@ -710,6 +712,25 @@ export type Props = $ReadOnly<{|
710712
forwardedRef?: ?ReactRefSetter<
711713
React.ElementRef<HostComponent<mixed>> & ImperativeMethods,
712714
>,
715+
716+
/**
717+
* When `accessible` is true and VoiceOver (iOS) or TalkBack (Android) is
718+
* enabled, this event is fired immediately once the element loses the screen
719+
* reader focus.
720+
*
721+
* See http://facebook.github.io/react-native/docs/view.html#onaccessibilityblur
722+
*/
723+
724+
onAccessibilityBlur?: ?(event: AccessibilityBlurEvent) => mixed,
725+
726+
/**
727+
* When `accessible` is true and VoiceOver (iOS) or TalkBack (Android) is
728+
* enabled, this event is fired immediately once the element gains the screen
729+
* reader focus.
730+
*
731+
* See http://facebook.github.io/react-native/docs/view.html#onaccessibilityfocus
732+
*/
733+
onAccessibilityFocus?: ?(event: AccessibilityFocusEvent) => mixed,
713734
|}>;
714735

715736
type ImperativeMethods = $ReadOnly<{|

Libraries/Components/Touchable/TouchableHighlight.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@
1010

1111
'use strict';
1212

13+
import * as React from 'react';
14+
import View from '../../Components/View/View';
1315
import Pressability, {
1416
type PressabilityConfig,
1517
} from '../../Pressability/Pressability';
1618
import {PressabilityDebugView} from '../../Pressability/PressabilityDebug';
1719
import StyleSheet, {type ViewStyleProp} from '../../StyleSheet/StyleSheet';
1820
import type {ColorValue} from '../../StyleSheet/StyleSheet';
19-
import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback';
2021
import Platform from '../../Utilities/Platform';
21-
import View from '../../Components/View/View';
22-
import * as React from 'react';
22+
import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback';
2323

2424
type AndroidProps = $ReadOnly<{|
2525
nextFocusDown?: ?number,
@@ -299,6 +299,8 @@ class TouchableHighlight extends React.Component<Props, State> {
299299
accessibilityLiveRegion={this.props.accessibilityLiveRegion}
300300
accessibilityViewIsModal={this.props.accessibilityViewIsModal}
301301
accessibilityElementsHidden={this.props.accessibilityElementsHidden}
302+
onAccessibilityBlur={this.props.onAccessibilityBlur}
303+
onAccessibilityFocus={this.props.onAccessibilityFocus}
302304
style={StyleSheet.compose(
303305
this.props.style,
304306
this.state.extraStyles?.underlay,

Libraries/Components/Touchable/TouchableNativeFeedback.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ class TouchableNativeFeedback extends React.Component<Props, State> {
279279
accessibilityLiveRegion: this.props.accessibilityLiveRegion,
280280
accessibilityViewIsModal: this.props.accessibilityViewIsModal,
281281
accessibilityElementsHidden: this.props.accessibilityElementsHidden,
282+
onAccessibilityBlur: this.props.onAccessibilityBlur,
283+
onAccessibilityFocus: this.props.onAccessibilityFocus,
282284
hasTVPreferredFocus: this.props.hasTVPreferredFocus,
283285
hitSlop: this.props.hitSlop,
284286
focusable:

Libraries/Components/Touchable/TouchableOpacity.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ class TouchableOpacity extends React.Component<Props, State> {
231231
accessibilityLiveRegion={this.props.accessibilityLiveRegion}
232232
accessibilityViewIsModal={this.props.accessibilityViewIsModal}
233233
accessibilityElementsHidden={this.props.accessibilityElementsHidden}
234+
onAccessibilityBlur={this.props.onAccessibilityBlur}
235+
onAccessibilityFocus={this.props.onAccessibilityFocus}
234236
style={[this.props.style, {opacity: this.state.anim}]}
235237
nativeID={this.props.nativeID}
236238
testID={this.props.testID}

Libraries/Components/Touchable/TouchableWithoutFeedback.js

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,29 @@
1010

1111
'use strict';
1212

13-
import Pressability, {
14-
type PressabilityConfig,
15-
} from '../../Pressability/Pressability';
16-
import {PressabilityDebugView} from '../../Pressability/PressabilityDebug';
13+
import * as React from 'react';
14+
import View from '../../Components/View/View';
1715
import type {
1816
AccessibilityActionEvent,
1917
AccessibilityActionInfo,
2018
AccessibilityRole,
2119
AccessibilityState,
2220
AccessibilityValue,
2321
} from '../../Components/View/ViewAccessibility';
22+
import Pressability, {
23+
type PressabilityConfig,
24+
} from '../../Pressability/Pressability';
25+
import {PressabilityDebugView} from '../../Pressability/PressabilityDebug';
2426
import type {EdgeInsetsProp} from '../../StyleSheet/EdgeInsetsPropType';
2527
import type {
2628
BlurEvent,
2729
FocusEvent,
2830
LayoutEvent,
2931
PressEvent,
3032
} from '../../Types/CoreEventTypes';
31-
import View from '../../Components/View/View';
32-
import * as React from 'react';
33+
34+
type AccessibilityBlurEvent = BlurEvent;
35+
type AccessibilityFocusEvent = BlurEvent;
3336

3437
type Props = $ReadOnly<{|
3538
accessibilityActions?: ?$ReadOnlyArray<AccessibilityActionInfo>,
@@ -43,16 +46,18 @@ type Props = $ReadOnly<{|
4346
accessibilityValue?: ?AccessibilityValue,
4447
accessibilityViewIsModal?: ?boolean,
4548
accessible?: ?boolean,
49+
onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed,
50+
importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'),
51+
onAccessibilityBlur?: ?(event: AccessibilityBlurEvent) => mixed,
52+
onAccessibilityFocus?: ?(event: AccessibilityFocusEvent) => mixed,
4653
children?: ?React.Node,
4754
delayLongPress?: ?number,
4855
delayPressIn?: ?number,
4956
delayPressOut?: ?number,
5057
disabled?: ?boolean,
5158
focusable?: ?boolean,
5259
hitSlop?: ?EdgeInsetsProp,
53-
importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'),
5460
nativeID?: ?string,
55-
onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed,
5661
onBlur?: ?(event: BlurEvent) => mixed,
5762
onFocus?: ?(event: FocusEvent) => mixed,
5863
onLayout?: ?(event: LayoutEvent) => mixed,
@@ -81,6 +86,8 @@ const PASSTHROUGH_PROPS = [
8186
'accessibilityState',
8287
'accessibilityValue',
8388
'accessibilityViewIsModal',
89+
'onAccessibilityBlur',
90+
'onAccessibilityFocus',
8491
'hitSlop',
8592
'importantForAccessibility',
8693
'nativeID',

Libraries/Components/View/ReactNativeViewAttributes.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ const UIView = {
2222
accessibilityState: true,
2323
accessibilityValue: true,
2424
accessibilityHint: true,
25+
onAccessibilityBlur: true,
26+
onAccessibilityFocus: true,
2527
importantForAccessibility: true,
2628
nativeID: true,
2729
testID: true,

Libraries/Components/View/ReactNativeViewViewConfig.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,15 @@ const ReactNativeViewConfig: ViewConfig = {
9494
topAccessibilityAction: {
9595
registrationName: 'onAccessibilityAction',
9696
},
97+
onAccessibilityBlur: {
98+
registrationName: 'onAccessibilityBlur',
99+
},
97100
topAccessibilityEscape: {
98101
registrationName: 'onAccessibilityEscape',
99102
},
103+
onAccessibilityFocus: {
104+
registrationName: 'onAccessibilityFocus',
105+
},
100106
topAccessibilityTap: {
101107
registrationName: 'onAccessibilityTap',
102108
},
@@ -193,7 +199,9 @@ const ReactNativeViewConfig: ViewConfig = {
193199
nativeID: true,
194200
needsOffscreenAlphaCompositing: true,
195201
onAccessibilityAction: true,
202+
onAccessibilityBlur: true,
196203
onAccessibilityEscape: true,
204+
onAccessibilityFocus: true,
197205
onAccessibilityTap: true,
198206
onLayout: true,
199207
onMagicTap: true,

Libraries/Components/View/ReactNativeViewViewConfigAndroid.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ const ReactNativeViewViewConfigAndroid = {
6666
onAssetDidLoad: {
6767
registrationName: 'onAssetDidLoad',
6868
},
69+
onAccessibilityBlur: {
70+
registrationName: 'onAccessibilityBlur',
71+
},
72+
onAccessibilityFocus: {
73+
registrationName: 'onAccessibilityFocus',
74+
},
6975
},
7076
validAttributes: {
7177
hasTVPreferredFocus: true,

Libraries/Components/View/ViewAccessibility.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,12 @@ export type AccessibilityValue = $ReadOnly<{|
8484
*/
8585
text?: string,
8686
|}>;
87+
88+
type TargetEvent = SyntheticEvent<
89+
$ReadOnly<{|
90+
target: number,
91+
|}>,
92+
>;
93+
94+
export type AccessibilityBlurEvent = TargetEvent;
95+
export type AccessibilityFocusEvent = TargetEvent;

0 commit comments

Comments
 (0)