From 114a12d7eb327f663064c3bbd1ef52e7b6ec1803 Mon Sep 17 00:00:00 2001 From: Doug Russell Date: Tue, 30 Oct 2018 21:24:40 -0400 Subject: [PATCH] Accessibility Escape --- Libraries/Components/View/ReactNativeViewAttributes.js | 1 + Libraries/Components/View/ViewPropTypes.js | 8 ++++++++ RNTester/js/AccessibilityIOSExample.js | 5 +++++ .../ComponentViews/View/RCTViewComponentView.mm | 6 ++++++ React/Views/RCTView.h | 1 + React/Views/RCTView.m | 10 ++++++++++ React/Views/RCTViewManager.m | 1 + .../fabric/components/view/ViewEventEmitter.cpp | 4 ++++ ReactCommon/fabric/components/view/ViewEventEmitter.h | 1 + 9 files changed, 37 insertions(+) diff --git a/Libraries/Components/View/ReactNativeViewAttributes.js b/Libraries/Components/View/ReactNativeViewAttributes.js index 5b4ab1c6c2c5..3ab651c37778 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 d2907278c34d..de993d1343ef 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?: ?Function, + + /** + * 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 fcae42844500..abfb02a94bc7 100644 --- a/RNTester/js/AccessibilityIOSExample.js +++ b/RNTester/js/AccessibilityIOSExample.js @@ -26,6 +26,11 @@ class AccessibilityIOSExample extends React.Component<{}> { alert('onMagicTap success')} 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 ce7e4a2c140b..5b4d4986bfbe 100644 --- a/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm @@ -536,6 +536,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 65ba3bfd643f..a4ef2b3e0433 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 f8091b906ec5..1493bbed07ab 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 154e9b0a2445..2eee1a65c293 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 16c1d6e16308..ed23c2d6570a 100644 --- a/ReactCommon/fabric/components/view/ViewEventEmitter.cpp +++ b/ReactCommon/fabric/components/view/ViewEventEmitter.cpp @@ -24,6 +24,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 431ede00089f..e16b4f98cbbe 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