From 4b0dc392b2ee1f5e9cd752fd3ee6186f88dc9b95 Mon Sep 17 00:00:00 2001 From: Saad Najmi Date: Wed, 21 Aug 2024 22:40:53 -0700 Subject: [PATCH] Introduce props `keyDownEvents` and `keyUpEvents` --- .../Libraries/Components/Button.js | 34 ++- .../Components/Pressable/Pressable.js | 27 +- .../Touchable/TouchableNativeFeedback.js | 14 - .../Components/Touchable/TouchableOpacity.js | 26 -- .../Touchable/TouchableWithoutFeedback.js | 10 - .../View/ReactNativeViewAttributes.js | 4 +- .../Libraries/Components/View/View.js | 23 ++ .../Components/View/ViewPropTypes.d.ts | 7 +- .../Components/View/ViewPropTypes.js | 21 +- .../NativeComponent/BaseViewConfig.macos.js | 4 +- .../Libraries/Pressability/Pressability.js | 14 +- .../__snapshots__/public-api-test.js.snap | 19 +- packages/rn-tester/Podfile.lock | 96 +++---- .../KeyboardEventsExample.js | 268 ++++++++++-------- .../Lists/VirtualizedList.js | 23 +- 15 files changed, 328 insertions(+), 262 deletions(-) diff --git a/packages/react-native/Libraries/Components/Button.js b/packages/react-native/Libraries/Components/Button.js index 3e416270c58600..e3b729f2a47194 100644 --- a/packages/react-native/Libraries/Components/Button.js +++ b/packages/react-native/Libraries/Components/Button.js @@ -177,17 +177,46 @@ type ButtonProps = $ReadOnly<{| onKeyUp?: ?(e: KeyEvent) => void, /* + * @deprecated use `keyDownEvents` or `keyUpEvents` instead * Array of keys to receive key down events for * For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", */ validKeysDown?: ?Array, /* + * @deprecated use `keyDownEvents` or `keyUpEvents` instead * Array of keys to receive key up events for * For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", */ validKeysUp?: ?Array, + + /** + * @deprecated use `keyDownEvents` or `keyUpEvents` instead + * When `true`, allows `onKeyDown` and `onKeyUp` to receive events not specified in + * `validKeysDown` and `validKeysUp`, respectively. Events matching `validKeysDown` and `validKeysUp` + * are still removed from the event queue, but the others are not. + * + * @platform macos + */ + passthroughAllKeyEvents?: ?boolean, + + /** + * Array of keys to receive key down events for. These events have their default native behavior prevented. + * Overrides the props `validKeysDown`, `validKeysUp` and `passthroughAllKeyEvents` + * + * @platform macos + */ + keyDownEvents?: ?Array, + + /** + * Array of keys to receive key up events for. These events have their default native behavior prevented. + * Overrides the props `validKeysDown`, `validKeysUp` and `passthroughAllKeyEvents` + * + * @platform macos + */ + keyUpEvents?: ?Array, + /* * Specifies the Tooltip for the view */ @@ -367,6 +396,9 @@ const Button: React.AbstractComponent = (props: ButtonProps) => { onKeyUp, validKeysDown, validKeysUp, + passthroughAllKeyEvents, + keyDownEvents, + keyUpEvents, tooltip, // macOS] } = props; @@ -443,8 +475,6 @@ const Button: React.AbstractComponent = (props: ButtonProps) => { onBlur={onBlur} onKeyDown={onKeyDown} onKeyUp={onKeyUp} - validKeysDown={validKeysDown} - validKeysUp={validKeysUp} tooltip={tooltip} // macOS] touchSoundDisabled={touchSoundDisabled}> diff --git a/packages/react-native/Libraries/Components/Pressable/Pressable.js b/packages/react-native/Libraries/Components/Pressable/Pressable.js index bcc03def85a744..f1347568bd4541 100644 --- a/packages/react-native/Libraries/Components/Pressable/Pressable.js +++ b/packages/react-native/Libraries/Components/Pressable/Pressable.js @@ -187,9 +187,24 @@ type Props = $ReadOnly<{| onKeyUp?: ?(event: KeyEvent) => void, /** + * Array of keys to receive key down events for. These events have their default native behavior prevented. + * + * @platform macos + */ + validKeysDown?: ?Array, + + /** + * Array of keys to receive key up events for. These events have their default native behavior prevented. + * + * @platform macos + */ + validKeysUp?: ?Array, + + /** + * @deprecated use `keyDownEvents` or `keyUpEvents` instead * When `true`, allows `onKeyDown` and `onKeyUp` to receive events not specified in * `validKeysDown` and `validKeysUp`, respectively. Events matching `validKeysDown` and `validKeysUp` - * still have their native default behavior prevented, but the others do not. + * are still removed from the event queue, but the others are not. * * @platform macos */ @@ -197,17 +212,19 @@ type Props = $ReadOnly<{| /** * Array of keys to receive key down events for. These events have their default native behavior prevented. + * Overrides the props `validKeysDown`, `validKeysUp` and `passthroughAllKeyEvents` * * @platform macos */ - validKeysDown?: ?Array, + keyDownEvents?: ?Array, /** * Array of keys to receive key up events for. These events have their default native behavior prevented. + * Overrides the props `validKeysDown`, `validKeysUp` and `passthroughAllKeyEvents` * * @platform macos */ - validKeysUp?: ?Array, + keyUpEvents?: ?Array, /** * Specifies whether the view should receive the mouse down event when the @@ -357,6 +374,9 @@ function Pressable(props: Props, forwardedRef): React.Node { onBlur, onKeyDown, onKeyUp, + passthroughAllKeyEvents, + keyDownEvents, + keyUpEvents, acceptsFirstMouse, mouseDownCanMoveWindow, enableFocusRing, @@ -397,6 +417,7 @@ function Pressable(props: Props, forwardedRef): React.Node { ariaLive === 'off' ? 'none' : ariaLive ?? props.accessibilityLiveRegion; const accessibilityLabel = ariaLabel ?? props.accessibilityLabel; + const restPropsWithDefaults: React.ElementConfig = { ...restProps, ...android_rippleConfig?.viewProps, diff --git a/packages/react-native/Libraries/Components/Touchable/TouchableNativeFeedback.js b/packages/react-native/Libraries/Components/Touchable/TouchableNativeFeedback.js index dd2005cecc5c40..0fb5f86702e417 100644 --- a/packages/react-native/Libraries/Components/Touchable/TouchableNativeFeedback.js +++ b/packages/react-native/Libraries/Components/Touchable/TouchableNativeFeedback.js @@ -78,18 +78,6 @@ type Props = $ReadOnly<{| */ nextFocusUp?: ?number, - /* - * Array of keys to receive key down events for - * For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", - */ - validKeysDown?: ?Array, - - /* - * Array of keys to receive key up events for - * For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", - */ - validKeysUp?: ?Array, - /** * Set to true to add the ripple effect to the foreground of the view, instead * of the background. This is useful if one of your child views has a @@ -343,8 +331,6 @@ class TouchableNativeFeedback extends React.Component { nextFocusUp: this.props.nextFocusUp, onLayout: this.props.onLayout, testID: this.props.testID, - validKeysDown: this.props.validKeysDown, - validKeysUp: this.props.validKeysUp, }, ...children, ); diff --git a/packages/react-native/Libraries/Components/Touchable/TouchableOpacity.js b/packages/react-native/Libraries/Components/Touchable/TouchableOpacity.js index 3dff76153742ef..de6d108b9eabd4 100644 --- a/packages/react-native/Libraries/Components/Touchable/TouchableOpacity.js +++ b/packages/react-native/Libraries/Components/Touchable/TouchableOpacity.js @@ -38,20 +38,6 @@ type Props = $ReadOnly<{| style?: ?ViewStyleProp, hostRef?: ?React.Ref, - - // [macOS - /* - * Array of keys to receive key down events for - * For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", - */ - validKeysDown?: ?Array, - - /* - * Array of keys to receive key up events for - * For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", - */ - validKeysUp?: ?Array, - // macOS] |}>; type State = $ReadOnly<{| @@ -178,18 +164,6 @@ class TouchableOpacity extends React.Component { this.props.onFocus(event); } }, - onKeyDown: event => { - if (this.props.onKeyDown != null) { - this.props.onKeyDown(event); - } - }, - onKeyUp: event => { - if (this.props.onKeyUp != null) { - this.props.onKeyUp(event); - } - }, - validKeysDown: this.props.validKeysDown, - validKeysUp: this.props.validKeysUp, onLongPress: this.props.onLongPress, onPress: this.props.onPress, onPressIn: event => { diff --git a/packages/react-native/Libraries/Components/Touchable/TouchableWithoutFeedback.js b/packages/react-native/Libraries/Components/Touchable/TouchableWithoutFeedback.js index 991d6518fbb00d..8f3f6f81f06f73 100755 --- a/packages/react-native/Libraries/Components/Touchable/TouchableWithoutFeedback.js +++ b/packages/react-native/Libraries/Components/Touchable/TouchableWithoutFeedback.js @@ -95,10 +95,6 @@ type Props = $ReadOnly<{| onDragLeave?: (event: MouseEvent) => void, onDrop?: (event: MouseEvent) => void, draggedTypes?: ?DraggedTypesType, - onKeyDown?: ?(event: KeyEvent) => void, - onKeyUp?: ?(event: KeyEvent) => void, - validKeysDown?: ?Array, - validKeysUp?: ?Array, // macOS] pressRetentionOffset?: ?EdgeInsetsOrSizeProp, rejectResponderTermination?: ?boolean, @@ -132,8 +128,6 @@ const PASSTHROUGH_PROPS = [ 'onAccessibilityAction', 'onBlur', 'onFocus', - 'validKeysDown', - 'validKeysUp', 'onLayout', 'onMouseEnter', // [macOS 'onMouseLeave', @@ -257,10 +251,6 @@ function createPressabilityConfig({ android_disableSound: props.touchSoundDisabled, onBlur: props.onBlur, onFocus: props.onFocus, - onKeyDown: props.onKeyDown, - onKeyUp: props.onKeyUp, - validKeysDown: props.validKeysDown, - validKeysUp: props.validKeysUp, onLongPress: props.onLongPress, onPress: props.onPress, onPressIn: props.onPressIn, diff --git a/packages/react-native/Libraries/Components/View/ReactNativeViewAttributes.js b/packages/react-native/Libraries/Components/View/ReactNativeViewAttributes.js index 963accabe90216..f15683f0b432f0 100644 --- a/packages/react-native/Libraries/Components/View/ReactNativeViewAttributes.js +++ b/packages/react-native/Libraries/Components/View/ReactNativeViewAttributes.js @@ -48,9 +48,11 @@ const UIView = { onDrop: true, onKeyDown: true, onKeyUp: true, - passthroughAllKeyEvents: true, validKeysDown: true, validKeysUp: true, + passthroughAllKeyEvents: true, + keyDownEvents: true, + keyUpEvents: true, draggedTypes: true, // macOS] }; diff --git a/packages/react-native/Libraries/Components/View/View.js b/packages/react-native/Libraries/Components/View/View.js index c4d2fc63ada85f..a4f4a6487ae1ff 100644 --- a/packages/react-native/Libraries/Components/View/View.js +++ b/packages/react-native/Libraries/Components/View/View.js @@ -55,6 +55,13 @@ const View: React.AbstractComponent< nativeID, pointerEvents, tabIndex, + // [macOS + passthroughAllKeyEvents, + validKeysDown, + validKeysUp, + keyDownEvents, + keyUpEvents, + // macOS] ...otherProps }: ViewProps, forwardedRef, @@ -102,6 +109,17 @@ const View: React.AbstractComponent< // $FlowFixMe[sketchy-null-mixed] const newPointerEvents = style?.pointerEvents || pointerEvents; + // [macOS + let _passthroughAllKeyEvents = passthroughAllKeyEvents; + let _validKeysDown = validKeysDown; + let _validKeysUp = validKeysUp; + if (keyDownEvents || keyUpEvents) { + _passthroughAllKeyEvents = true; + _validKeysDown = keyDownEvents; + _validKeysUp = keyUpEvents; + } + // macOS] + const actualView = ( ); diff --git a/packages/react-native/Libraries/Components/View/ViewPropTypes.d.ts b/packages/react-native/Libraries/Components/View/ViewPropTypes.d.ts index 5a8138df8a7e50..301b8af849c6c7 100644 --- a/packages/react-native/Libraries/Components/View/ViewPropTypes.d.ts +++ b/packages/react-native/Libraries/Components/View/ViewPropTypes.d.ts @@ -178,8 +178,11 @@ export interface ViewPropsMacOS { onDrop?: ((event: MouseEvent) => void) | undefined; onKeyDown?: ((event: KeyEvent) => void) | undefined; onKeyUp?: ((event: KeyEvent) => void) | undefined; - validKeysDown?: string[] | undefined; - validKeysUp?: string[] | undefined; + validKeysDown?: Array | undefined; + validKeysUp?: Array | undefined; + passthroughAllKeyEvents?: boolean | undefined; + keyDownEvents?: Array | undefined; + keyUpEvents?: Array | undefined; draggedTypes?: DraggedTypesType | undefined; } diff --git a/packages/react-native/Libraries/Components/View/ViewPropTypes.js b/packages/react-native/Libraries/Components/View/ViewPropTypes.js index 3706760f7ac221..55d83a0c3355aa 100644 --- a/packages/react-native/Libraries/Components/View/ViewPropTypes.js +++ b/packages/react-native/Libraries/Components/View/ViewPropTypes.js @@ -131,6 +131,21 @@ export type KeyboardEventProps = $ReadOnly<{| onKeyUp?: ?(event: KeyEvent) => void, /** + * Array of keys to receive key down events for. These events have their default native behavior prevented. + * + * @platform macos + */ + validKeysDown?: ?Array, + + /** + * Array of keys to receive key up events for. These events have their default native behavior prevented. + * + * @platform macos + */ + validKeysUp?: ?Array, + + /** + * @deprecated use `keyDownEvents` or `keyUpEvents` instead * When `true`, allows `onKeyDown` and `onKeyUp` to receive events not specified in * `validKeysDown` and `validKeysUp`, respectively. Events matching `validKeysDown` and `validKeysUp` * are still removed from the event queue, but the others are not. @@ -141,17 +156,19 @@ export type KeyboardEventProps = $ReadOnly<{| /** * Array of keys to receive key down events for. These events have their default native behavior prevented. + * Overrides the props `validKeysDown`, `validKeysUp` and `passthroughAllKeyEvents` * * @platform macos */ - validKeysDown?: ?Array, + keyDownEvents?: ?Array, /** * Array of keys to receive key up events for. These events have their default native behavior prevented. + * Overrides the props `validKeysDown`, `validKeysUp` and `passthroughAllKeyEvents` * * @platform macos */ - validKeysUp?: ?Array, + keyUpEvents?: ?Array, |}>; // macOS] diff --git a/packages/react-native/Libraries/NativeComponent/BaseViewConfig.macos.js b/packages/react-native/Libraries/NativeComponent/BaseViewConfig.macos.js index 3d2b949e0c8607..2cd32a5532fc46 100644 --- a/packages/react-native/Libraries/NativeComponent/BaseViewConfig.macos.js +++ b/packages/react-native/Libraries/NativeComponent/BaseViewConfig.macos.js @@ -53,9 +53,11 @@ const validAttributesForNonEventProps = { draggedTypes: true, enableFocusRing: true, tooltip: true, - passthroughAllKeyEvents: true, validKeysDown: true, validKeysUp: true, + passthroughAllKeyEvents: true, + keyDownEvents: true, + keyUpEvents: true, mouseDownCanMoveWindow: true, }; diff --git a/packages/react-native/Libraries/Pressability/Pressability.js b/packages/react-native/Libraries/Pressability/Pressability.js index 893c9b858c421d..6abbb1aeee4155 100644 --- a/packages/react-native/Libraries/Pressability/Pressability.js +++ b/packages/react-native/Libraries/Pressability/Pressability.js @@ -98,6 +98,7 @@ export type PressabilityConfig = $ReadOnly<{| */ onFocus?: ?(event: FocusEvent) => void, + // [macOS /* * Called after a key down event is detected. */ @@ -107,18 +108,7 @@ export type PressabilityConfig = $ReadOnly<{| * Called after a key up event is detected. */ onKeyUp?: ?(event: KeyEvent) => void, - - /* - * Array of keys to receive key down events for - * For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", - */ - validKeysDown?: ?Array, - - /* - * Array of keys to receive key up events for - * For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", - */ - validKeysUp?: ?Array, + // macOS] /** * Called when the hover is activated to provide visual feedback. diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 9312bf6060fa30..cad824273311d5 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -1710,6 +1710,9 @@ exports[`public API should not change unintentionally Libraries/Components/Butto onKeyUp?: ?(e: KeyEvent) => void, validKeysDown?: ?Array, validKeysUp?: ?Array, + passthroughAllKeyEvents?: ?boolean, + keyDownEvents?: ?Array, + keyUpEvents?: ?Array, tooltip?: string, accessible?: ?boolean, accessibilityActions?: ?$ReadOnlyArray, @@ -1901,9 +1904,11 @@ type Props = $ReadOnly<{| onBlur?: ?(event: BlurEvent) => void, onKeyDown?: ?(event: KeyEvent) => void, onKeyUp?: ?(event: KeyEvent) => void, - passthroughAllKeyEvents?: ?boolean, validKeysDown?: ?Array, validKeysUp?: ?Array, + passthroughAllKeyEvents?: ?boolean, + keyDownEvents?: ?Array, + keyUpEvents?: ?Array, acceptsFirstMouse?: ?boolean, mouseDownCanMoveWindow?: ?boolean, enableFocusRing?: ?boolean, @@ -3569,8 +3574,6 @@ type Props = $ReadOnly<{| activeOpacity?: ?number, style?: ?ViewStyleProp, hostRef?: ?React.Ref, - validKeysDown?: ?Array, - validKeysUp?: ?Array, |}>; declare const Touchable: React.AbstractComponent< Props, @@ -3636,9 +3639,11 @@ exports[`public API should not change unintentionally Libraries/Components/View/ onDrop: true, onKeyDown: true, onKeyUp: true, - passthroughAllKeyEvents: true, validKeysDown: true, validKeysUp: true, + passthroughAllKeyEvents: true, + keyDownEvents: true, + keyUpEvents: true, draggedTypes: true, }; declare const RCTView: { ...UIView, removeClippedSubviews: true }; @@ -3833,9 +3838,11 @@ export type HandledKeyboardEvent = $ReadOnly<{| export type KeyboardEventProps = $ReadOnly<{| onKeyDown?: ?(event: KeyEvent) => void, onKeyUp?: ?(event: KeyEvent) => void, - passthroughAllKeyEvents?: ?boolean, validKeysDown?: ?Array, validKeysUp?: ?Array, + passthroughAllKeyEvents?: ?boolean, + keyDownEvents?: ?Array, + keyUpEvents?: ?Array, |}>; type MouseEventProps = $ReadOnly<{| onMouseEnter?: ?(event: MouseEvent) => void, @@ -6443,8 +6450,6 @@ exports[`public API should not change unintentionally Libraries/Pressability/Pre onFocus?: ?(event: FocusEvent) => void, onKeyDown?: ?(event: KeyEvent) => void, onKeyUp?: ?(event: KeyEvent) => void, - validKeysDown?: ?Array, - validKeysUp?: ?Array, onHoverIn?: ?(event: MouseEvent) => mixed, onHoverOut?: ?(event: MouseEvent) => mixed, onLongPress?: ?(event: PressEvent) => mixed, diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index eefbc022fa70f6..e80ca91b969d62 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -1416,7 +1416,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost: 0686b6af8cbd638c784fea5afb789be66699823c DoubleConversion: 5b92c4507c560bb62e7aa1acdf2785ea3ff08b3b - FBLazyVector: 62aaa61b7b69d531a3ffd60fdbad3bb0384008b1 + FBLazyVector: f6ac6d0a05af3581dc906d63e44c7b6908d7eb5f fmt: 03574da4b7ba40de39da59677ca66610ce8c4a02 glog: 3a72874c0322c7caf24931d3a2777cb7a3090529 MyNativeView: e5442ab418e407beec1e41ac9d6fbf676e29165d @@ -1424,56 +1424,56 @@ SPEC CHECKSUMS: OCMock: 589f2c84dacb1f5aaf6e4cec1f292551fe748e74 RCT-Folly: b84ed447eb92e8adbb6101ae195ce6506481b22c RCTDeprecation: 3808e36294137f9ee5668f4df2e73dc079cd1dcf - RCTRequired: e849327aae4cd21bead62676b4589612c8c1958e - RCTTypeSafety: 7fbef1bc878c2aa2af95867c3aabacb5fd36a9ad - React: 1ccf276435a49f064a816ba5debcf496ad3a2143 - React-callinvoker: cb7f02cd7cbf7f787d25f56cdebbb6292388ebff + RCTRequired: af2967279a7971f8716754e02e42c80a37516c94 + RCTTypeSafety: cc703e89670a534e89208ec64a0b89de34179ead + React: 8cf732d083faedb02d0a086c4b6f4ead2550301e + React-callinvoker: a22c3c3dcf34eb67cf394dffbc1733485f6ae785 React-Codegen: 956c1b0bb3de8d8663a16b4b484684ca7eaea0f1 - React-Core: c03507ab2dfd9b7c3ce757b55e2f0050414af284 - React-CoreModules: b76b4fb3dd522d3a98f3b248c33213075e3162c5 - React-cxxreact: c2c393635f4bcc6d6c3bd87b532bee9dac1d50ad - React-debug: 39b29f0fad45920e54a96caecd330c36b899f2ed - React-Fabric: b132b508e092647bdbcb8ff330893f184a932abd - React-FabricImage: 3b1ec6f6be8b23b66398a20240e8dfa575d685d8 - React-featureflags: ca35757ebcfdb8916c5273da6faa05a2648ab53f - React-graphics: d286502f8f8faaebcb50dcc26b6a1f547c97b511 - React-ImageManager: a01b0edb8644ab8379af2e252e458064b7482012 - React-jsc: 49683dc2f8d13a63c7ae3ceca0a5c7f5e8b4158e - React-jserrorhandler: 1f2571a6ab3e7d89fdd0e45437b83eb49ccc86f4 - React-jsi: f9d8c14d006fe511af7d8e77692dfd1e156d49bc - React-jsiexecutor: 963edf21d57714773a0626123913c571efa049a8 - React-jsinspector: 41f653e7ab5f4cdd89ab7bbf4221304a7f02bc89 - React-jsitracing: 7ceb073994282bf1869677aefdf2aeaa1292f96d - React-logger: 1f014355650dd821879e6c8c9605670e42bb0d82 - React-Mapbuffer: 870df4678792a8897f39f1f05f16e7705a280ec9 - React-nativeconfig: 45737e7d0acd7b524c7c204b54c0b0cfd9a641a2 - React-NativeModulesApple: 1b291ae265c574457d5e81a4933960ceb0711301 - React-perflogger: b30e5b9f834231caf928254d5fb3e2ac5a23a110 - React-RCTActionSheet: cd6934d167f4e0c6f7263386d6970f8d27ea6127 - React-RCTAnimation: 6206907baf7092210bb99b1224549312ff85165f - React-RCTAppDelegate: f315dde99ccdb4bc1ad33afb11be404c49dd6870 - React-RCTBlob: 14e49f3ae9029d8d08ed524d32b3e1093cacdfad - React-RCTFabric: e966c9b8206113cde98f1b7e76f2dce3b2ab4b89 - React-RCTImage: acab25a65c58305ac07ab4126c18cb4408623f8c - React-RCTLinking: 5c4b48cd3f58b7fe7400fdeaccb21a446ba55671 - React-RCTNetwork: 0a23f947331d688f260c2d4e668503e07d7f2a81 - React-RCTPushNotification: e2aba6102b33b77d87eb4153e66d6dd880092cf3 - React-RCTSettings: 5a489bf650385a6664ad79438a8d01ea8407fbe6 - React-RCTTest: 4a551521303472b84e8c1039adfc117fe7c3208b - React-RCTText: f3fc4a0d3b46aac22e0812cf28a3f8b296b4745b - React-RCTVibration: 84d825d147b6d32503cb1f2b5fff2ff44c1b535b - React-rendererdebug: 5e44408adb547b3d64aa897b8485531f926a68d6 - React-rncore: 5dbd45235dbca06325f1fb341667b274239037e6 - React-RuntimeApple: a9257b6ba8a66a8ca179babf1e2525ba3a3d8052 - React-RuntimeCore: bfe5858bfee9486caf8e99b8f641bad8af0ccdbe - React-runtimeexecutor: 180b804c53ae1b8d6d91438ebc3e4d744ce24c76 - React-runtimescheduler: 24a20945ad382574e03438ffae1c54b40952d4c9 - React-utils: 2c5bc038d20c7b8c7dd188a57cf938aa49b420e8 - ReactCommon: 9e369ddf2218e3d7bd288273f52ee4041a999822 - ReactCommon-Samples: 1e9b9317898692cb043c326efd5b82c911f461f6 + React-Core: bac1d59a62043d507c71b98e768d552733847cab + React-CoreModules: 2e904cb6609e51302a106196238ad60508192f4e + React-cxxreact: f87e6f00cf6e165675404d900ec308ad70fd9e4d + React-debug: 9d38da653be820379f1004589eacc571b50497bb + React-Fabric: 3a5ebcd863bb1f3b0cb1fc4b1c54bfd28a4a93ac + React-FabricImage: e98b5ee23fdcc3b7ebeebfd214e1228d358a6560 + React-featureflags: cd4ba326c8eaabb69a16faca1b45c74793940c88 + React-graphics: e9e67f337165d1b06e3feca22e4a6c020bfe83af + React-ImageManager: f2f21dc9352852f5f62d332e529aac3ebab71c01 + React-jsc: b171bb9f35f0c56f5b99794261dfb72735a39bf9 + React-jserrorhandler: 098640e8fd7d567a7768d1d01e8c3b26bd6e9da4 + React-jsi: 41bc072a3e2efca069d40b7280e63ff730bd87c7 + React-jsiexecutor: d7ea58ea756dcbcfc71bac105cae0c1d57772ed7 + React-jsinspector: dc3eb10eb9db4285efbab0285e2b65e24f038304 + React-jsitracing: 1faf1b6dab82bd05b3611faa2123e865c219ef54 + React-logger: b33e121a8527a1397d25391cf1e739ccf2451d8b + React-Mapbuffer: 98d856d843665393e8ab660e892b1cc7c697c997 + React-nativeconfig: b87a11fb407343ce38925028fd7c9ef6cd2782a0 + React-NativeModulesApple: 397c511278240427b671e5758cc2b0acd54631ec + React-perflogger: c257a1e734924b6b2098b5bf0c4a9205a1ad40c0 + React-RCTActionSheet: 03e41bd2f7265c2ea993e73ca08c009b011debcd + React-RCTAnimation: 30f80245d0e2702619955bcbcc41ef5fbfc75024 + React-RCTAppDelegate: 96dba5ef931666839e9437bf6ec41be5c378182d + React-RCTBlob: 6669be2595900c3dc652fc40ab51fe4ab102bc7f + React-RCTFabric: 82f6ddd30328dafe14bf0e05a55b54d29371f078 + React-RCTImage: 964c6a5cb95c3b8b12df56fe8231bc035370a6cd + React-RCTLinking: 18b5f298270f459af0f5736e43cc5781a5f05778 + React-RCTNetwork: 217d2afc76d4e6da0a1f37145c581b7f6d42eefd + React-RCTPushNotification: 7f4fcd1c8b8599945795b534f0cdcffe8714409e + React-RCTSettings: dc55231c500783e65d03a4ab5432f9982d216de4 + React-RCTTest: 03a19a189f19850c467b6987e64cd7eda9b8a1f9 + React-RCTText: 104150737785b09ff1a206a098f853790d9fe747 + React-RCTVibration: 146a93d033ed682f4d1e267b3942916a24743a3c + React-rendererdebug: 5b06a52dea6848716377a5ce72a0c12cca3ece22 + React-rncore: 77adb0711ed3c1beda5da1fac6c86918bc142740 + React-RuntimeApple: e6a955f47cc46ab20cdb0249553613c5a31eaf38 + React-RuntimeCore: 54145dfdd2c89bfc04c84b368a06cbf2d48018be + React-runtimeexecutor: e16df4bef67b3f97abb7b2b1c456fa7c4d38eb77 + React-runtimescheduler: 63efc34b264f094e6cc3257d5882e1333b237178 + React-utils: bc9c116864ce79d71377a706880d43d98ba4ea5b + ReactCommon: 57ac52a0dcafde0c7686f2e7d1d35b18de067cb0 + ReactCommon-Samples: 08a60cbc9ff0ed3d37f015e6f12c69890ee7da7e ScreenshotManager: e2b9810347f641b9164aa485cb5fa7f3ab04184f SocketRocket: f6c6249082c011e6de2de60ed641ef8bbe0cfac9 - Yoga: 4b2d9dab52760b8b084fc882c7c9c3d5612ad82b + Yoga: be40bb6777d8bc9d58adbada1a1756174caf9fb0 PODFILE CHECKSUM: 8d41baa96deb5f6497f9f0824d3df78cb740d7a8 diff --git a/packages/rn-tester/js/examples/KeyboardEventsExample/KeyboardEventsExample.js b/packages/rn-tester/js/examples/KeyboardEventsExample/KeyboardEventsExample.js index 2268d1dcf0e591..8720d93f17387d 100644 --- a/packages/rn-tester/js/examples/KeyboardEventsExample/KeyboardEventsExample.js +++ b/packages/rn-tester/js/examples/KeyboardEventsExample/KeyboardEventsExample.js @@ -15,16 +15,8 @@ import type {KeyEvent} from 'react-native/Libraries/Types/CoreEventTypes'; const React = require('react'); const ReactNative = require('react-native'); -const { - Button, - Platform, - ScrollView, - StyleSheet, - Switch, - Text, - TextInput, - View, -} = ReactNative; +const {Button, ScrollView, StyleSheet, Switch, Text, TextInput, View} = + ReactNative; const switchStyle = { alignItems: 'center', @@ -91,13 +83,58 @@ function KeyEventExample(): React.Node { const [passthroughAllKeyEvents, setPassthroughAllKeyEvents] = React.useState(false); - const toggleSwitch = React.useCallback( + const togglePassthroughAllKeyEvents = React.useCallback( (value: boolean) => { setPassthroughAllKeyEvents(value); }, [setPassthroughAllKeyEvents], ); + const [useKeyDownOrUpEvents, setUseKeyDownOrUpEvents] = React.useState(false); + const toggleKeyDownOrUpEvents = React.useCallback( + (value: boolean) => { + setUseKeyDownOrUpEvents(value); + }, + [setUseKeyDownOrUpEvents], + ); + + const viewRef = React.useRef(null); + + const ViewText = useKeyDownOrUpEvents + ? "keyDownEvents: [{key: 'g'}, {key: 'Escape'}, {key: 'Enter'}, {key: 'ArrowLeft'}] \nkeyUpEvents: [{key: 'c'}, {key: 'd'}]" + : "validKeysDown: [g, Escape, Enter, ArrowLeft] \nvalidKeysUp: [c, d]"; + const viewKeyboardProps = useKeyDownOrUpEvents + ? { + keyDownEvents: [ + {key: 'g'}, + {key: 'Escape'}, + {key: 'Enter'}, + {key: 'ArrowLeft'}, + ], + keyUpEvents: [{key: 'c'}, {key: 'd'}], + } + : { + validKeysDown: ['g', 'Escape', 'Enter', 'ArrowLeft'], + validKeysUp: ['c ', 'd'], + }; + + const TextInputText = useKeyDownOrUpEvents + ? "keyDownEvents: [{key: 'ArrowRight'}, {key: 'ArrowDown'}, {key: 'Enter', ctrlKey: true}, \nkeyUpEvents: [{key: 'Escape'}, {key: 'Enter'}]" + : "validKeysDown: ['ArrowRight', 'ArrowDown', 'Enter'] \nvalidKeysUp: ['Escape ', {key: 'Enter', ctrlKey: true}]"; + const textInputKeyboardProps = useKeyDownOrUpEvents + ? { + keyDownEvents: [ + {key: 'ArrowRight'}, + {key: 'ArrowDown'}, + {key: 'Enter', ctrlKey: true}, + ], + keyUpEvents: [{key: 'Escape'}, {key: 'Enter'}], + } + : { + validKeysDown: ['ArrowRight', 'ArrowDown', 'Enter'], + validKeysUp: ['Escape ', {key: 'Enter', ctrlKey: true}], + }; + return ( @@ -107,120 +144,113 @@ function KeyEventExample(): React.Node { Shortcuts > Use keyboard navigation to move focus between controls. - {Platform.OS === 'macos' ? ( + + View + + + {showView && ( <> - - View - - - {showView ? ( - <> - - validKeysDown: [g, Escape, Enter, ArrowLeft]{'\n'} - validKeysUp: [c, d] - - - - ) : null} - - TextInput - - - {showTextInput ? ( - <> - - validKeysDown: [ArrowRight, ArrowDown, Ctrl+Enter]{'\n'} - validKeysUp: [Escape, Enter] - - - - - ) : null} - - TextInput with no handled keys - - - {showTextInput2 ? ( - <> - - validKeysDown: []{'\n'} - validKeysUp: [] - - - - - ) : null} + {ViewText} + { + console.log('View onPress'); + viewRef.current.focus(); + }} + onKeyDown={handleKeyDown} + onKeyUp={handleKeyUp} + passthroughAllKeyEvents={passthroughAllKeyEvents} + {...viewKeyboardProps} + /> - ) : null} + )} + + TextInput + + + {showTextInput && ( + <> + {TextInputText} + + + + )} + + TextInput with no handled keys + + + {showTextInput2 && ( + <> + + validKeysDown: []{'\n'} + validKeysUp: [] + + + + + )} {'Pass through all key events'} + + + {'Use keyDownEvents / keyUpEvents'} +