Skip to content

Introduce props keyDownEvents and keyUpEvents #2171

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading