From 5553afcae03ec20551ca29a4c717f6cb9929da1d Mon Sep 17 00:00:00 2001 From: Saad Najmi Date: Thu, 22 Aug 2024 00:18:20 -0700 Subject: [PATCH] Introduce props `keyDownEvents` and `keyUpEvents` --- .../Libraries/Components/Button.js | 41 ++- .../Components/Pressable/Pressable.js | 29 +- .../Touchable/TouchableNativeFeedback.js | 14 - .../Components/Touchable/TouchableOpacity.js | 26 -- .../Touchable/TouchableWithoutFeedback.js | 10 - .../View/ReactNativeViewAttributes.js | 4 +- .../Libraries/Components/View/View.js | 25 ++ .../Components/View/ViewPropTypes.d.ts | 8 +- .../Components/View/ViewPropTypes.js | 42 ++- .../NativeComponent/BaseViewConfig.macos.js | 4 +- .../Libraries/Pressability/Pressability.js | 14 +- .../Libraries/Types/CoreEventTypes.d.ts | 19 ++ .../Libraries/Types/CoreEventTypes.js | 20 ++ .../__snapshots__/public-api-test.js.snap | 19 +- .../KeyboardEventsExample.js | 261 ++++++++++-------- .../Lists/VirtualizedList.js | 23 +- 16 files changed, 319 insertions(+), 240 deletions(-) diff --git a/packages/react-native/Libraries/Components/Button.js b/packages/react-native/Libraries/Components/Button.js index 3e416270c58600..3d96a055e1711f 100644 --- a/packages/react-native/Libraries/Components/Button.js +++ b/packages/react-native/Libraries/Components/Button.js @@ -12,7 +12,12 @@ import type {TextStyleProp, ViewStyleProp} from '../StyleSheet/StyleSheet'; import type {PressEvent} from '../Types/CoreEventTypes'; -import type {BlurEvent, FocusEvent, KeyEvent} from '../Types/CoreEventTypes'; // [macOS] +import type { + BlurEvent, + FocusEvent, + HandledKeyEvent, + KeyEvent, +} from '../Types/CoreEventTypes'; // [macOS] import type { AccessibilityActionEvent, AccessibilityActionInfo, @@ -177,17 +182,45 @@ 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 */ @@ -365,8 +398,6 @@ const Button: React.AbstractComponent = (props: ButtonProps) => { onBlur, onKeyDown, onKeyUp, - validKeysDown, - validKeysUp, tooltip, // macOS] } = props; @@ -441,10 +472,6 @@ const Button: React.AbstractComponent = (props: ButtonProps) => { // [macOS onFocus={onFocus} 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..6583373b9e8027 100644 --- a/packages/react-native/Libraries/Components/Pressable/Pressable.js +++ b/packages/react-native/Libraries/Components/Pressable/Pressable.js @@ -12,6 +12,7 @@ import type { BlurEvent, // [macOS FocusEvent, + HandledKeyEvent, KeyEvent, LayoutEvent, MouseEvent, @@ -26,7 +27,6 @@ import type { AccessibilityState, AccessibilityValue, } from '../View/ViewAccessibility'; -import type {HandledKeyboardEvent} from '../View/ViewPropTypes'; // [macOS] import {PressabilityDebugView} from '../../Pressability/PressabilityDebug'; import usePressability from '../../Pressability/usePressability'; @@ -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..312ebf8843a085 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,19 @@ 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; + // $FlowFixMe[incompatible-type] + _validKeysDown = keyDownEvents; + // $FlowFixMe[incompatible-type] + _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..aa426748a8be4f 100644 --- a/packages/react-native/Libraries/Components/View/ViewPropTypes.d.ts +++ b/packages/react-native/Libraries/Components/View/ViewPropTypes.d.ts @@ -13,6 +13,7 @@ import {GestureResponderHandlers} from '../../../types/public/ReactNativeRendere import {StyleProp} from '../../StyleSheet/StyleSheet'; import {ViewStyle} from '../../StyleSheet/StyleSheetTypes'; import { + HandledKeyEvent, KeyEvent, LayoutChangeEvent, MouseEvent, @@ -178,8 +179,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..226e130271cedc 100644 --- a/packages/react-native/Libraries/Components/View/ViewPropTypes.js +++ b/packages/react-native/Libraries/Components/View/ViewPropTypes.js @@ -16,6 +16,7 @@ import type { BlurEvent, FocusEvent, // [macOS] + HandledKeyEvent, KeyEvent, Layout, LayoutEvent, @@ -99,26 +100,6 @@ type DirectEventProps = $ReadOnly<{| onAccessibilityEscape?: ?() => mixed, |}>; -// [macOS -/** - * Represents a key that could be passed to `validKeysDown` and `validKeysUp`. - * - * `key` is the actual key, such as "a", or one of the special values: - * "Tab", "Escape", "Enter", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", - * "Backspace", "Delete", "Home", "End", "PageUp", "PageDown". - * - * The rest are modifiers that when absent mean false. - * - * @platform macos - */ -export type HandledKeyboardEvent = $ReadOnly<{| - altKey?: ?boolean, - ctrlKey?: ?boolean, - metaKey?: ?boolean, - shiftKey?: ?boolean, - key: string, -|}>; - export type KeyboardEventProps = $ReadOnly<{| /** * Called after a key down event is detected. @@ -131,6 +112,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 +137,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/Types/CoreEventTypes.d.ts b/packages/react-native/Libraries/Types/CoreEventTypes.d.ts index 299982189f3dc5..88d32463272586 100644 --- a/packages/react-native/Libraries/Types/CoreEventTypes.d.ts +++ b/packages/react-native/Libraries/Types/CoreEventTypes.d.ts @@ -284,6 +284,25 @@ export interface NativeKeyEvent { key: string; } +/** + * Represents a key that could be passed to `validKeysDown` and `validKeysUp`. + * + * `key` is the actual key, such as "a", or one of the special values: + * "Tab", "Escape", "Enter", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", + * "Backspace", "Delete", "Home", "End", "PageUp", "PageDown". + * + * The rest are modifiers that when absent mean false. + * + * @platform macos + */ +export type HandledKeyEvent = { + altKey?: boolean | undefined; + ctrlKey?: boolean | undefined; + metaKey?: boolean | undefined; + shiftKey?: boolean | undefined; + key: string; +}; + export interface KeyEvent extends NativeSyntheticEvent {} export interface NativeFocusEvent extends TargetedEvent {} diff --git a/packages/react-native/Libraries/Types/CoreEventTypes.js b/packages/react-native/Libraries/Types/CoreEventTypes.js index b4e098662a0361..c8f1b917baf105 100644 --- a/packages/react-native/Libraries/Types/CoreEventTypes.js +++ b/packages/react-native/Libraries/Types/CoreEventTypes.js @@ -308,6 +308,26 @@ export type KeyEvent = SyntheticEvent< key: string, |}>, >; + +/** + * Represents a key that could be passed to `validKeysDown` and `validKeysUp`. + * + * `key` is the actual key, such as "a", or one of the special values: + * "Tab", "Escape", "Enter", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown", + * "Backspace", "Delete", "Home", "End", "PageUp", "PageDown". + * + * The rest are modifiers that when absent mean false. + * + * @platform macos + */ +export type HandledKeyEvent = $ReadOnly<{| + altKey?: ?boolean, + ctrlKey?: ?boolean, + metaKey?: ?boolean, + shiftKey?: ?boolean, + key: string, +|}>; + // macOS] export type MouseEvent = SyntheticEvent< 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/js/examples/KeyboardEventsExample/KeyboardEventsExample.js b/packages/rn-tester/js/examples/KeyboardEventsExample/KeyboardEventsExample.js index 2268d1dcf0e591..558f7e7677ca8c 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,56 @@ 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 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 +142,108 @@ function KeyEventExample(): React.Node { Shortcuts > Use keyboard navigation to move focus between controls. - {Platform.OS === 'macos' ? ( + + View + + + {showView && ( + <> + {ViewText} + + + )} + + TextInput + + + {showTextInput && ( <> - - 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} + {TextInputText} + + - ) : null} + )} + + TextInput with no handled keys + + + {showTextInput2 && ( + <> + + validKeysDown: []{'\n'} + validKeysUp: [] + + + + + )} {'Pass through all key events'} + + + {'Use keyDownEvents / keyUpEvents'} +