diff --git a/Libraries/Components/View/ReactNativeViewAttributes.js b/Libraries/Components/View/ReactNativeViewAttributes.js index 5b4ab1c6c2c5fa..3ab651c37778b3 100644 --- a/Libraries/Components/View/ReactNativeViewAttributes.js +++ b/Libraries/Components/View/ReactNativeViewAttributes.js @@ -34,6 +34,7 @@ ReactNativeViewAttributes.UIView = { onAccessibilityAction: true, onAccessibilityTap: true, onMagicTap: true, + onAccessibilityEscape: true, collapsable: true, needsOffscreenAlphaCompositing: true, style: ReactNativeStyleAttributes, diff --git a/Libraries/Components/View/ViewPropTypes.js b/Libraries/Components/View/ViewPropTypes.js index a5f54867c8674f..f1e5cbe79f0618 100644 --- a/Libraries/Components/View/ViewPropTypes.js +++ b/Libraries/Components/View/ViewPropTypes.js @@ -62,6 +62,14 @@ type DirectEventProps = $ReadOnly<{| * See http://facebook.github.io/react-native/docs/view.html#onmagictap */ onMagicTap?: ?() => void, + + /** + * When `accessible` is `true`, the system will invoke this function when the + * user performs the escape gesture. + * + * See http://facebook.github.io/react-native/docs/view.html#onaccessibilityescape + */ + onAccessibilityEscape?: ?Function, |}>; type TouchEventProps = $ReadOnly<{| diff --git a/RNTester/js/AccessibilityIOSExample.js b/RNTester/js/AccessibilityIOSExample.js index 96ed8fc39fc31c..d6e20efc8a452b 100644 --- a/RNTester/js/AccessibilityIOSExample.js +++ b/RNTester/js/AccessibilityIOSExample.js @@ -30,6 +30,11 @@ class AccessibilityIOSExample extends React.Component<{}> { accessible={true}> Accessibility magic tap example + alert('onAccessibilityEscape success')} + accessible={true}> + Accessibility escape example + Accessibility label example diff --git a/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm index d9e3884c1c5c3a..82ae59c11e5f79 100644 --- a/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm @@ -553,6 +553,12 @@ - (BOOL)accessibilityPerformMagicTap return YES; } +- (BOOL)accessibilityPerformEscape +{ + _eventEmitter->onAccessibilityEscape(); + return YES; +} + - (BOOL)didActivateAccessibilityCustomAction:(UIAccessibilityCustomAction *)action { _eventEmitter->onAccessibilityAction(RCTStringFromNSString(action.name)); diff --git a/React/Views/RCTView.h b/React/Views/RCTView.h index 65ba3bfd643fd4..a4ef2b3e0433c6 100644 --- a/React/Views/RCTView.h +++ b/React/Views/RCTView.h @@ -24,6 +24,7 @@ @property (nonatomic, copy) RCTDirectEventBlock onAccessibilityAction; @property (nonatomic, copy) RCTDirectEventBlock onAccessibilityTap; @property (nonatomic, copy) RCTDirectEventBlock onMagicTap; +@property (nonatomic, copy) RCTDirectEventBlock onAccessibilityEscape; /** * Accessibility properties diff --git a/React/Views/RCTView.m b/React/Views/RCTView.m index f8091b906ec579..1493bbed07ab16 100644 --- a/React/Views/RCTView.m +++ b/React/Views/RCTView.m @@ -284,6 +284,16 @@ - (BOOL)accessibilityPerformMagicTap } } +- (BOOL)accessibilityPerformEscape +{ + if (_onAccessibilityEscape) { + _onAccessibilityEscape(nil); + return YES; + } else { + return NO; + } +} + - (NSString *)description { NSString *superDescription = super.description; diff --git a/React/Views/RCTViewManager.m b/React/Views/RCTViewManager.m index 154e9b0a244501..2eee1a65c29325 100644 --- a/React/Views/RCTViewManager.m +++ b/React/Views/RCTViewManager.m @@ -119,6 +119,7 @@ - (RCTShadowView *)shadowView RCT_REMAP_VIEW_PROPERTY(onAccessibilityAction, reactAccessibilityElement.onAccessibilityAction, RCTDirectEventBlock) RCT_REMAP_VIEW_PROPERTY(onAccessibilityTap, reactAccessibilityElement.onAccessibilityTap, RCTDirectEventBlock) RCT_REMAP_VIEW_PROPERTY(onMagicTap, reactAccessibilityElement.onMagicTap, RCTDirectEventBlock) +RCT_REMAP_VIEW_PROPERTY(onAccessibilityEscape, reactAccessibilityElement.onAccessibilityEscape, RCTDirectEventBlock) RCT_REMAP_VIEW_PROPERTY(testID, reactAccessibilityElement.accessibilityIdentifier, NSString) RCT_EXPORT_VIEW_PROPERTY(backgroundColor, UIColor) diff --git a/ReactCommon/fabric/components/view/ViewEventEmitter.cpp b/ReactCommon/fabric/components/view/ViewEventEmitter.cpp index ccd8398745c7a1..4ab1f900201ae7 100644 --- a/ReactCommon/fabric/components/view/ViewEventEmitter.cpp +++ b/ReactCommon/fabric/components/view/ViewEventEmitter.cpp @@ -28,6 +28,10 @@ void ViewEventEmitter::onAccessibilityMagicTap() const { dispatchEvent("magicTap"); } +void ViewEventEmitter::onAccessibilityEscape() const { + dispatchEvent("accessibilityEscape"); +} + #pragma mark - Layout void ViewEventEmitter::onLayout(const LayoutMetrics &layoutMetrics) const { diff --git a/ReactCommon/fabric/components/view/ViewEventEmitter.h b/ReactCommon/fabric/components/view/ViewEventEmitter.h index 431ede00089f29..e16b4f98cbbe71 100644 --- a/ReactCommon/fabric/components/view/ViewEventEmitter.h +++ b/ReactCommon/fabric/components/view/ViewEventEmitter.h @@ -28,6 +28,7 @@ class ViewEventEmitter : public TouchEventEmitter { void onAccessibilityAction(const std::string &name) const; void onAccessibilityTap() const; void onAccessibilityMagicTap() const; + void onAccessibilityEscape() const; #pragma mark - Layout