Skip to content

Commit 529cb7f

Browse files
authored
Introduce props keyDownEvents and keyUpEvents (#2172)
1 parent 1f82ed9 commit 529cb7f

File tree

16 files changed

+328
-249
lines changed

16 files changed

+328
-249
lines changed

packages/react-native/Libraries/Components/Button.js

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@
1212

1313
import type {TextStyleProp, ViewStyleProp} from '../StyleSheet/StyleSheet';
1414
import type {PressEvent} from '../Types/CoreEventTypes';
15-
import type {BlurEvent, FocusEvent, KeyEvent} from '../Types/CoreEventTypes'; // [macOS]
15+
import type {
16+
BlurEvent,
17+
FocusEvent,
18+
HandledKeyEvent,
19+
KeyEvent,
20+
} from '../Types/CoreEventTypes'; // [macOS]
1621
import type {
1722
AccessibilityActionEvent,
1823
AccessibilityActionInfo,
@@ -177,17 +182,45 @@ type ButtonProps = $ReadOnly<{|
177182
onKeyUp?: ?(e: KeyEvent) => void,
178183

179184
/*
185+
* @deprecated use `keyDownEvents` or `keyUpEvents` instead
180186
* Array of keys to receive key down events for
181187
* For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown",
182188
*/
183189
validKeysDown?: ?Array<string>,
184190

185191
/*
192+
* @deprecated use `keyDownEvents` or `keyUpEvents` instead
186193
* Array of keys to receive key up events for
187194
* For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown",
188195
*/
189196
validKeysUp?: ?Array<string>,
190197

198+
/**
199+
* @deprecated use `keyDownEvents` or `keyUpEvents` instead
200+
* When `true`, allows `onKeyDown` and `onKeyUp` to receive events not specified in
201+
* `validKeysDown` and `validKeysUp`, respectively. Events matching `validKeysDown` and `validKeysUp`
202+
* are still removed from the event queue, but the others are not.
203+
*
204+
* @platform macos
205+
*/
206+
passthroughAllKeyEvents?: ?boolean,
207+
208+
/**
209+
* Array of keys to receive key down events for. These events have their default native behavior prevented.
210+
* Overrides the props `validKeysDown`, `validKeysUp` and `passthroughAllKeyEvents`
211+
*
212+
* @platform macos
213+
*/
214+
keyDownEvents?: ?Array<HandledKeyEvent>,
215+
216+
/**
217+
* Array of keys to receive key up events for. These events have their default native behavior prevented.
218+
* Overrides the props `validKeysDown`, `validKeysUp` and `passthroughAllKeyEvents`
219+
*
220+
* @platform macos
221+
*/
222+
keyUpEvents?: ?Array<HandledKeyEvent>,
223+
191224
/*
192225
* Specifies the Tooltip for the view
193226
*/
@@ -365,8 +398,6 @@ const Button: React.AbstractComponent<ButtonProps> = (props: ButtonProps) => {
365398
onBlur,
366399
onKeyDown,
367400
onKeyUp,
368-
validKeysDown,
369-
validKeysUp,
370401
tooltip,
371402
// macOS]
372403
} = props;
@@ -441,10 +472,6 @@ const Button: React.AbstractComponent<ButtonProps> = (props: ButtonProps) => {
441472
// [macOS
442473
onFocus={onFocus}
443474
onBlur={onBlur}
444-
onKeyDown={onKeyDown}
445-
onKeyUp={onKeyUp}
446-
validKeysDown={validKeysDown}
447-
validKeysUp={validKeysUp}
448475
tooltip={tooltip}
449476
// macOS]
450477
touchSoundDisabled={touchSoundDisabled}>

packages/react-native/Libraries/Components/Pressable/Pressable.js

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type {
1212
BlurEvent,
1313
// [macOS
1414
FocusEvent,
15+
HandledKeyEvent,
1516
KeyEvent,
1617
LayoutEvent,
1718
MouseEvent,
@@ -26,7 +27,6 @@ import type {
2627
AccessibilityState,
2728
AccessibilityValue,
2829
} from '../View/ViewAccessibility';
29-
import type {HandledKeyboardEvent} from '../View/ViewPropTypes'; // [macOS]
3030

3131
import {PressabilityDebugView} from '../../Pressability/PressabilityDebug';
3232
import usePressability from '../../Pressability/usePressability';
@@ -187,27 +187,44 @@ type Props = $ReadOnly<{|
187187
onKeyUp?: ?(event: KeyEvent) => void,
188188

189189
/**
190+
* Array of keys to receive key down events for. These events have their default native behavior prevented.
191+
*
192+
* @platform macos
193+
*/
194+
validKeysDown?: ?Array<string | HandledKeyEvent>,
195+
196+
/**
197+
* Array of keys to receive key up events for. These events have their default native behavior prevented.
198+
*
199+
* @platform macos
200+
*/
201+
validKeysUp?: ?Array<string | HandledKeyEvent>,
202+
203+
/**
204+
* @deprecated use `keyDownEvents` or `keyUpEvents` instead
190205
* When `true`, allows `onKeyDown` and `onKeyUp` to receive events not specified in
191206
* `validKeysDown` and `validKeysUp`, respectively. Events matching `validKeysDown` and `validKeysUp`
192-
* still have their native default behavior prevented, but the others do not.
207+
* are still removed from the event queue, but the others are not.
193208
*
194209
* @platform macos
195210
*/
196211
passthroughAllKeyEvents?: ?boolean,
197212

198213
/**
199214
* Array of keys to receive key down events for. These events have their default native behavior prevented.
215+
* Overrides the props `validKeysDown`, `validKeysUp` and `passthroughAllKeyEvents`
200216
*
201217
* @platform macos
202218
*/
203-
validKeysDown?: ?Array<string | HandledKeyboardEvent>,
219+
keyDownEvents?: ?Array<HandledKeyEvent>,
204220

205221
/**
206222
* Array of keys to receive key up events for. These events have their default native behavior prevented.
223+
* Overrides the props `validKeysDown`, `validKeysUp` and `passthroughAllKeyEvents`
207224
*
208225
* @platform macos
209226
*/
210-
validKeysUp?: ?Array<string | HandledKeyboardEvent>,
227+
keyUpEvents?: ?Array<HandledKeyEvent>,
211228

212229
/**
213230
* Specifies whether the view should receive the mouse down event when the
@@ -357,6 +374,9 @@ function Pressable(props: Props, forwardedRef): React.Node {
357374
onBlur,
358375
onKeyDown,
359376
onKeyUp,
377+
passthroughAllKeyEvents,
378+
keyDownEvents,
379+
keyUpEvents,
360380
acceptsFirstMouse,
361381
mouseDownCanMoveWindow,
362382
enableFocusRing,
@@ -397,6 +417,7 @@ function Pressable(props: Props, forwardedRef): React.Node {
397417
ariaLive === 'off' ? 'none' : ariaLive ?? props.accessibilityLiveRegion;
398418

399419
const accessibilityLabel = ariaLabel ?? props.accessibilityLabel;
420+
400421
const restPropsWithDefaults: React.ElementConfig<typeof View> = {
401422
...restProps,
402423
...android_rippleConfig?.viewProps,

packages/react-native/Libraries/Components/Touchable/TouchableNativeFeedback.js

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -78,18 +78,6 @@ type Props = $ReadOnly<{|
7878
*/
7979
nextFocusUp?: ?number,
8080

81-
/*
82-
* Array of keys to receive key down events for
83-
* For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown",
84-
*/
85-
validKeysDown?: ?Array<string>,
86-
87-
/*
88-
* Array of keys to receive key up events for
89-
* For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown",
90-
*/
91-
validKeysUp?: ?Array<string>,
92-
9381
/**
9482
* Set to true to add the ripple effect to the foreground of the view, instead
9583
* of the background. This is useful if one of your child views has a
@@ -343,8 +331,6 @@ class TouchableNativeFeedback extends React.Component<Props, State> {
343331
nextFocusUp: this.props.nextFocusUp,
344332
onLayout: this.props.onLayout,
345333
testID: this.props.testID,
346-
validKeysDown: this.props.validKeysDown,
347-
validKeysUp: this.props.validKeysUp,
348334
},
349335
...children,
350336
);

packages/react-native/Libraries/Components/Touchable/TouchableOpacity.js

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,6 @@ type Props = $ReadOnly<{|
3838
style?: ?ViewStyleProp,
3939

4040
hostRef?: ?React.Ref<typeof Animated.View>,
41-
42-
// [macOS
43-
/*
44-
* Array of keys to receive key down events for
45-
* For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown",
46-
*/
47-
validKeysDown?: ?Array<string>,
48-
49-
/*
50-
* Array of keys to receive key up events for
51-
* For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown",
52-
*/
53-
validKeysUp?: ?Array<string>,
54-
// macOS]
5541
|}>;
5642

5743
type State = $ReadOnly<{|
@@ -178,18 +164,6 @@ class TouchableOpacity extends React.Component<Props, State> {
178164
this.props.onFocus(event);
179165
}
180166
},
181-
onKeyDown: event => {
182-
if (this.props.onKeyDown != null) {
183-
this.props.onKeyDown(event);
184-
}
185-
},
186-
onKeyUp: event => {
187-
if (this.props.onKeyUp != null) {
188-
this.props.onKeyUp(event);
189-
}
190-
},
191-
validKeysDown: this.props.validKeysDown,
192-
validKeysUp: this.props.validKeysUp,
193167
onLongPress: this.props.onLongPress,
194168
onPress: this.props.onPress,
195169
onPressIn: event => {

packages/react-native/Libraries/Components/Touchable/TouchableWithoutFeedback.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,6 @@ type Props = $ReadOnly<{|
9595
onDragLeave?: (event: MouseEvent) => void,
9696
onDrop?: (event: MouseEvent) => void,
9797
draggedTypes?: ?DraggedTypesType,
98-
onKeyDown?: ?(event: KeyEvent) => void,
99-
onKeyUp?: ?(event: KeyEvent) => void,
100-
validKeysDown?: ?Array<string>,
101-
validKeysUp?: ?Array<string>,
10298
// macOS]
10399
pressRetentionOffset?: ?EdgeInsetsOrSizeProp,
104100
rejectResponderTermination?: ?boolean,
@@ -132,8 +128,6 @@ const PASSTHROUGH_PROPS = [
132128
'onAccessibilityAction',
133129
'onBlur',
134130
'onFocus',
135-
'validKeysDown',
136-
'validKeysUp',
137131
'onLayout',
138132
'onMouseEnter', // [macOS
139133
'onMouseLeave',
@@ -257,10 +251,6 @@ function createPressabilityConfig({
257251
android_disableSound: props.touchSoundDisabled,
258252
onBlur: props.onBlur,
259253
onFocus: props.onFocus,
260-
onKeyDown: props.onKeyDown,
261-
onKeyUp: props.onKeyUp,
262-
validKeysDown: props.validKeysDown,
263-
validKeysUp: props.validKeysUp,
264254
onLongPress: props.onLongPress,
265255
onPress: props.onPress,
266256
onPressIn: props.onPressIn,

packages/react-native/Libraries/Components/View/ReactNativeViewAttributes.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,11 @@ const UIView = {
4848
onDrop: true,
4949
onKeyDown: true,
5050
onKeyUp: true,
51-
passthroughAllKeyEvents: true,
5251
validKeysDown: true,
5352
validKeysUp: true,
53+
passthroughAllKeyEvents: true,
54+
keyDownEvents: true,
55+
keyUpEvents: true,
5456
draggedTypes: true,
5557
// macOS]
5658
};

packages/react-native/Libraries/Components/View/View.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ const View: React.AbstractComponent<
5555
nativeID,
5656
pointerEvents,
5757
tabIndex,
58+
// [macOS
59+
passthroughAllKeyEvents,
60+
validKeysDown,
61+
validKeysUp,
62+
keyDownEvents,
63+
keyUpEvents,
64+
// macOS]
5865
...otherProps
5966
}: ViewProps,
6067
forwardedRef,
@@ -102,6 +109,19 @@ const View: React.AbstractComponent<
102109
// $FlowFixMe[sketchy-null-mixed]
103110
const newPointerEvents = style?.pointerEvents || pointerEvents;
104111

112+
// [macOS
113+
let _passthroughAllKeyEvents = passthroughAllKeyEvents;
114+
let _validKeysDown = validKeysDown;
115+
let _validKeysUp = validKeysUp;
116+
if (keyDownEvents || keyUpEvents) {
117+
_passthroughAllKeyEvents = true;
118+
// $FlowFixMe[incompatible-type]
119+
_validKeysDown = keyDownEvents;
120+
// $FlowFixMe[incompatible-type]
121+
_validKeysUp = keyUpEvents;
122+
}
123+
// macOS]
124+
105125
const actualView = (
106126
<ViewNativeComponent
107127
{...otherProps}
@@ -123,6 +143,11 @@ const View: React.AbstractComponent<
123143
style={style}
124144
// $FlowFixMe[incompatible-type]
125145
pointerEvents={newPointerEvents}
146+
// [macOS
147+
passthroughAllKeyEvents={_passthroughAllKeyEvents}
148+
validKeysDown={_validKeysDown}
149+
validKeysUp={_validKeysUp}
150+
// macOS]
126151
ref={forwardedRef}
127152
/>
128153
);

packages/react-native/Libraries/Components/View/ViewPropTypes.d.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {GestureResponderHandlers} from '../../../types/public/ReactNativeRendere
1313
import {StyleProp} from '../../StyleSheet/StyleSheet';
1414
import {ViewStyle} from '../../StyleSheet/StyleSheetTypes';
1515
import {
16+
HandledKeyEvent,
1617
KeyEvent,
1718
LayoutChangeEvent,
1819
MouseEvent,
@@ -178,8 +179,11 @@ export interface ViewPropsMacOS {
178179
onDrop?: ((event: MouseEvent) => void) | undefined;
179180
onKeyDown?: ((event: KeyEvent) => void) | undefined;
180181
onKeyUp?: ((event: KeyEvent) => void) | undefined;
181-
validKeysDown?: string[] | undefined;
182-
validKeysUp?: string[] | undefined;
182+
validKeysDown?: Array<HandledKeyEvent | string> | undefined;
183+
validKeysUp?: Array<HandledKeyEvent | string> | undefined;
184+
passthroughAllKeyEvents?: boolean | undefined;
185+
keyDownEvents?: Array<HandledKeyEvent> | undefined;
186+
keyUpEvents?: Array<HandledKeyEvent> | undefined;
183187
draggedTypes?: DraggedTypesType | undefined;
184188
}
185189

0 commit comments

Comments
 (0)