Skip to content

Commit

Permalink
Introduce props keyDownEvents and keyUpEvents (#2172)
Browse files Browse the repository at this point in the history
  • Loading branch information
Saadnajmi committed Aug 23, 2024
1 parent 1f82ed9 commit 529cb7f
Show file tree
Hide file tree
Showing 16 changed files with 328 additions and 249 deletions.
41 changes: 34 additions & 7 deletions packages/react-native/Libraries/Components/Button.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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<string>,

/*
* @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<string>,

/**
* @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<HandledKeyEvent>,

/**
* 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<HandledKeyEvent>,

/*
* Specifies the Tooltip for the view
*/
Expand Down Expand Up @@ -365,8 +398,6 @@ const Button: React.AbstractComponent<ButtonProps> = (props: ButtonProps) => {
onBlur,
onKeyDown,
onKeyUp,
validKeysDown,
validKeysUp,
tooltip,
// macOS]
} = props;
Expand Down Expand Up @@ -441,10 +472,6 @@ const Button: React.AbstractComponent<ButtonProps> = (props: ButtonProps) => {
// [macOS
onFocus={onFocus}
onBlur={onBlur}
onKeyDown={onKeyDown}
onKeyUp={onKeyUp}
validKeysDown={validKeysDown}
validKeysUp={validKeysUp}
tooltip={tooltip}
// macOS]
touchSoundDisabled={touchSoundDisabled}>
Expand Down
29 changes: 25 additions & 4 deletions packages/react-native/Libraries/Components/Pressable/Pressable.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
BlurEvent,
// [macOS
FocusEvent,
HandledKeyEvent,
KeyEvent,
LayoutEvent,
MouseEvent,
Expand All @@ -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';
Expand Down Expand Up @@ -187,27 +187,44 @@ 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<string | HandledKeyEvent>,

/**
* Array of keys to receive key up events for. These events have their default native behavior prevented.
*
* @platform macos
*/
validKeysUp?: ?Array<string | HandledKeyEvent>,

/**
* @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
*/
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
*/
validKeysDown?: ?Array<string | HandledKeyboardEvent>,
keyDownEvents?: ?Array<HandledKeyEvent>,

/**
* 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<string | HandledKeyboardEvent>,
keyUpEvents?: ?Array<HandledKeyEvent>,

/**
* Specifies whether the view should receive the mouse down event when the
Expand Down Expand Up @@ -357,6 +374,9 @@ function Pressable(props: Props, forwardedRef): React.Node {
onBlur,
onKeyDown,
onKeyUp,
passthroughAllKeyEvents,
keyDownEvents,
keyUpEvents,
acceptsFirstMouse,
mouseDownCanMoveWindow,
enableFocusRing,
Expand Down Expand Up @@ -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<typeof View> = {
...restProps,
...android_rippleConfig?.viewProps,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>,

/*
* Array of keys to receive key up events for
* For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown",
*/
validKeysUp?: ?Array<string>,

/**
* 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
Expand Down Expand Up @@ -343,8 +331,6 @@ class TouchableNativeFeedback extends React.Component<Props, State> {
nextFocusUp: this.props.nextFocusUp,
onLayout: this.props.onLayout,
testID: this.props.testID,
validKeysDown: this.props.validKeysDown,
validKeysUp: this.props.validKeysUp,
},
...children,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,6 @@ type Props = $ReadOnly<{|
style?: ?ViewStyleProp,

hostRef?: ?React.Ref<typeof Animated.View>,

// [macOS
/*
* Array of keys to receive key down events for
* For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown",
*/
validKeysDown?: ?Array<string>,

/*
* Array of keys to receive key up events for
* For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown",
*/
validKeysUp?: ?Array<string>,
// macOS]
|}>;

type State = $ReadOnly<{|
Expand Down Expand Up @@ -178,18 +164,6 @@ class TouchableOpacity extends React.Component<Props, State> {
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 => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>,
validKeysUp?: ?Array<string>,
// macOS]
pressRetentionOffset?: ?EdgeInsetsOrSizeProp,
rejectResponderTermination?: ?boolean,
Expand Down Expand Up @@ -132,8 +128,6 @@ const PASSTHROUGH_PROPS = [
'onAccessibilityAction',
'onBlur',
'onFocus',
'validKeysDown',
'validKeysUp',
'onLayout',
'onMouseEnter', // [macOS
'onMouseLeave',
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]
};
Expand Down
25 changes: 25 additions & 0 deletions packages/react-native/Libraries/Components/View/View.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ const View: React.AbstractComponent<
nativeID,
pointerEvents,
tabIndex,
// [macOS
passthroughAllKeyEvents,
validKeysDown,
validKeysUp,
keyDownEvents,
keyUpEvents,
// macOS]
...otherProps
}: ViewProps,
forwardedRef,
Expand Down Expand Up @@ -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 = (
<ViewNativeComponent
{...otherProps}
Expand All @@ -123,6 +143,11 @@ const View: React.AbstractComponent<
style={style}
// $FlowFixMe[incompatible-type]
pointerEvents={newPointerEvents}
// [macOS
passthroughAllKeyEvents={_passthroughAllKeyEvents}
validKeysDown={_validKeysDown}
validKeysUp={_validKeysUp}
// macOS]
ref={forwardedRef}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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<HandledKeyEvent | string> | undefined;
validKeysUp?: Array<HandledKeyEvent | string> | undefined;
passthroughAllKeyEvents?: boolean | undefined;
keyDownEvents?: Array<HandledKeyEvent> | undefined;
keyUpEvents?: Array<HandledKeyEvent> | undefined;
draggedTypes?: DraggedTypesType | undefined;
}

Expand Down
Loading

0 comments on commit 529cb7f

Please sign in to comment.