From ceac270f9719138f3089552626c6b3b4ff60d7f5 Mon Sep 17 00:00:00 2001 From: Tom Underhill Date: Thu, 12 Jan 2023 05:12:49 +0100 Subject: [PATCH] Return and Space keys do not trigger onPress events (#1623) * Update scripts to publish react-native-macos-init * Clean up merge markers * Restored ios:macos RNTester parity except for InputAccessoryView. * Revert "Restored ios:macos RNTester parity except for InputAccessoryView." This reverts commit 5a67ae06b01301ac43533e7e20dd7fed24a0937f. * Remove unnecessary android builds and tar file upload. * Fix pressability enter/return and spacebar key events * Don't change validKeysDown/Up for components that explicitly set them * Added event.defaultPrevented check to key events * Fixed spacing in RCTView.m * Ignore key event props not matching press events Co-authored-by: React-Native Bot <53619745+rnbot@users.noreply.github.com> --- Libraries/Pressability/Pressability.js | 23 +++++++++++++++++++++++ React/Views/RCTView.m | 6 ++++++ 2 files changed, 29 insertions(+) diff --git a/Libraries/Pressability/Pressability.js b/Libraries/Pressability/Pressability.js index 7f1626239ed8b8..4e8928ec3e9c58 100644 --- a/Libraries/Pressability/Pressability.js +++ b/Libraries/Pressability/Pressability.js @@ -628,12 +628,35 @@ export default class Pressability { if (onKeyDown != null) { onKeyDown(event); } + // Pressables on macOS should respond to the enter/return and spacebar keys. + // The keyDown event triggers a press event as well as the pressIn effect mimicking a native control behavior. + if ( + (event.nativeEvent.key === 'Enter' || + event.nativeEvent.key === ' ') && + event.defaultPrevented !== true + ) { + const {onPress, onPressIn} = this._config; + // $FlowFixMe: PressEvents don't mesh with keyboarding APIs. Keep legacy behavior of passing KeyEvents instead + onPressIn && onPressIn(event); + // $FlowFixMe: PressEvents don't mesh with keyboarding APIs. Keep legacy behavior of passing KeyEvents instead + onPress && onPress(event); + } }, onKeyUp: (event: KeyEvent): void => { const {onKeyUp} = this._config; if (onKeyUp != null) { onKeyUp(event); } + // The keyUp event triggers the pressOut effect. + if ( + (event.nativeEvent.key === 'Enter' || + event.nativeEvent.key === ' ') && + event.defaultPrevented !== true + ) { + const {onPressOut} = this._config; + // $FlowFixMe: PressEvents don't mesh with keyboarding APIs. Keep legacy behavior of passing KeyEvents instead + onPressOut && onPressOut(event); + } }, }; // ]TODO(macOS GH#774) diff --git a/React/Views/RCTView.m b/React/Views/RCTView.m index 7571f349d97435..02ce4f3a1b0459 100644 --- a/React/Views/RCTView.m +++ b/React/Views/RCTView.m @@ -1632,6 +1632,12 @@ - (RCTViewKeyboardEvent*)keyboardEvent:(NSEvent*)event { NSArray *validKeys = keyDown ? self.validKeysDown : self.validKeysUp; NSString *key = [RCTViewKeyboardEvent keyFromEvent:event]; + // If the view is focusable and the component didn't explicity set the validKeysDown or Up, + // allow enter/return and spacebar key events to mimic the behavior of native controls. + if (self.focusable && validKeys == nil) { + validKeys = @[@"Enter", @" "]; + } + // Only post events for keys we care about if (![validKeys containsObject:key]) { return nil;