Skip to content

Commit

Permalink
Remove validKeysDown, validKeysUp, and passThroughAllKeyEvents
Browse files Browse the repository at this point in the history
  • Loading branch information
Saadnajmi committed Aug 22, 2024
1 parent acdd184 commit 3e3cd23
Show file tree
Hide file tree
Showing 21 changed files with 140 additions and 291 deletions.
25 changes: 12 additions & 13 deletions packages/react-native/Libraries/Components/Button.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,19 +176,19 @@ 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",
/**
* Array of keys to receive key down events for. These events have their default native behavior prevented.
*
* @platform macos
*/
validKeysDown?: ?Array<string>,
keyDownEvents?: ?Array<HandledKeyboardEvent>,

/*
* @deprecated use `keyDownEvents` or `keyUpEvents` instead
* Array of keys to receive key up events for
* For arrow keys, add "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown",
/**
* Array of keys to receive key up events for. These events have their default native behavior prevented.
*
* @platform macos
*/
validKeysUp?: ?Array<string>,
keyUpEvents?: ?Array<HandledKeyboardEvent>,


/**
Expand Down Expand Up @@ -394,9 +394,6 @@ const Button: React.AbstractComponent<ButtonProps> = (props: ButtonProps) => {
onBlur,
onKeyDown,
onKeyUp,
validKeysDown,
validKeysUp,
passthroughAllKeyEvents,
keyDownEvents,
keyUpEvents,
tooltip,
Expand Down Expand Up @@ -475,6 +472,8 @@ const Button: React.AbstractComponent<ButtonProps> = (props: ButtonProps) => {
onBlur={onBlur}
onKeyDown={onKeyDown}
onKeyUp={onKeyUp}
keyDownEvents={keyDownEvents}
keyUpEvents={keyUpEvents}
tooltip={tooltip}
// macOS]
touchSoundDisabled={touchSoundDisabled}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,14 @@ type Props = $ReadOnly<{|
*
* @platform macos
*/
validKeysDown?: ?Array<string | HandledKeyboardEvent>,
keyDownEvents?: ?Array<HandledKeyboardEvent>,

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

/**
* @deprecated use `keyDownEvents` or `keyUpEvents` instead
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ const PASSTHROUGH_PROPS = [
'onDragLeave',
'onDrop',
'draggedTypes',
'onKeyDown',
'onKeyUp',
'keyDownEvents',
'keyUpEvents',
'tooltip', // macOS]
'testID',
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ const UIView = {
onDrop: true,
onKeyDown: true,
onKeyUp: true,
validKeysDown: true,
validKeysUp: true,
passthroughAllKeyEvents: true,
keyDownEvents: true,
keyUpEvents: true,
draggedTypes: true,
Expand Down
15 changes: 10 additions & 5 deletions packages/react-native/Libraries/Components/View/ViewPropTypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,14 @@ export interface ViewPropsAndroid {
export type DraggedType = 'fileUrl';
export type DraggedTypesType = DraggedType | DraggedType[];

export type HandledKeyboardEvent = {
altKey?: boolean | undefined;
ctrlKey?: boolean | undefined;
metaKey?: boolean | undefined;
shiftKey?: boolean | undefined;
key: string;
};

export interface ViewPropsMacOS {
acceptsFirstMouse?: boolean | undefined;
allowsVibrancy?: boolean | undefined;
Expand All @@ -178,11 +186,8 @@ export interface ViewPropsMacOS {
onDrop?: ((event: MouseEvent) => void) | undefined;
onKeyDown?: ((event: KeyEvent) => void) | undefined;
onKeyUp?: ((event: KeyEvent) => void) | undefined;
validKeysDown?: Array<HandledKeyEvent | string> | undefined;
validKeysUp?: Array<HandledKeyEvent | string> | undefined;
passthroughAllKeyEvents?: boolean | undefined;
keyDownEvents?: Array<HandledKeyEvent> | undefined;
keyUpEvents?: Array<HandledKeyEvent> | undefined;
keyDownEvents?: HandledKeyboardEvent[] | undefined;
keyUpEvents?: HandledKeyboardEvent[] | undefined;
draggedTypes?: DraggedTypesType | undefined;
}

Expand Down
28 changes: 1 addition & 27 deletions packages/react-native/Libraries/Components/View/ViewPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ type DirectEventProps = $ReadOnly<{|

// [macOS
/**
* Represents a key that could be passed to `validKeysDown` and `validKeysUp`.
* Represents a key that could be passed to `keyDownEvents` and `keyUpEvents`.
*
* `key` is the actual key, such as "a", or one of the special values:
* "Tab", "Escape", "Enter", "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown",
Expand Down Expand Up @@ -135,36 +135,10 @@ export type KeyboardEventProps = $ReadOnly<{|
*
* @platform macos
*/
validKeysDown?: ?Array<string | HandledKeyboardEvent>,

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

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

/**
* 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
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ const validAttributesForNonEventProps = {
draggedTypes: true,
enableFocusRing: true,
tooltip: true,
validKeysDown: true,
validKeysUp: true,
passthroughAllKeyEvents: true,
keyDownEvents: true,
keyUpEvents: true,
mouseDownCanMoveWindow: true,
Expand Down
4 changes: 4 additions & 0 deletions packages/react-native/Libraries/Pressability/Pressability.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,15 @@ export type PressabilityConfig = $ReadOnly<{|
// [macOS
/*
* Called after a key down event is detected.
*
* @platform macos
*/
onKeyDown?: ?(event: KeyEvent) => void,

/*
* Called after a key up event is detected.
*
* @platform macos
*/
onKeyUp?: ?(event: KeyEvent) => void,
// macOS]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ NS_ASSUME_NONNULL_BEGIN
#if TARGET_OS_OSX // [macOS
- (BOOL)textInputShouldHandleDeleteForward:(id<RCTBackedTextInputViewProtocol>)sender; // Return `YES` to have the deleteForward event handled normally. Return `NO` to disallow it and handle it yourself.
- (BOOL)textInputShouldHandleKeyEvent:(NSEvent *)event; // Return `YES` to have the key event handled normally. Return `NO` to disallow it and handle it yourself.
- (BOOL)hasValidKeyDownOrValidKeyUp:(NSString *)key;
- (BOOL)hasKeyDownEventOrKeyUpEvent:(NSString *)key;
- (NSDragOperation)textInputDraggingEntered:(id<NSDraggingInfo>)draggingInfo;
- (void)textInputDraggingExited:(id<NSDraggingInfo>)draggingInfo;
- (BOOL)textInputShouldHandleDragOperation:(id<NSDraggingInfo>)draggingInfo;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ - (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor doComman
//escape
} else if (commandSelector == @selector(cancelOperation:)) {
[textInputDelegate textInputDidCancel];
if (![textInputDelegate hasValidKeyDownOrValidKeyUp:@"Escape"]) {
if (![textInputDelegate hasKeyDownEventOrKeyUpEvent:@"Escape"]) {
[[_backedTextInputView window] makeFirstResponder:nil];
}
commandHandled = YES;
Expand Down Expand Up @@ -450,7 +450,7 @@ - (BOOL)textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector
//escape
} else if (commandSelector == @selector(cancelOperation:)) {
[textInputDelegate textInputDidCancel];
if (![textInputDelegate hasValidKeyDownOrValidKeyUp:@"Escape"]) {
if (![textInputDelegate hasKeyDownEventOrKeyUpEvent:@"Escape"]) {
[[_backedTextInputView window] makeFirstResponder:nil];
}
commandHandled = YES;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -749,9 +749,9 @@ - (BOOL)textInputShouldHandleDeleteForward:(__unused id)sender {
return YES;
}

- (BOOL)hasValidKeyDownOrValidKeyUp:(NSString *)key {
return [RCTHandledKey key:key matchesFilter:self.validKeysDown]
|| [RCTHandledKey key:key matchesFilter:self.validKeysUp];
- (BOOL)hasKeyDownEventOrKeyUpEvent:(NSString *)key {
return [RCTHandledKey key:key matchesFilter:self.keyDownEvents]
|| [RCTHandledKey key:key matchesFilter:self.keyUpEvents];
}

- (NSDragOperation)textInputDraggingEntered:(id<NSDraggingInfo>)draggingInfo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1708,9 +1708,6 @@ exports[`public API should not change unintentionally Libraries/Components/Butto
onFocus?: ?(e: FocusEvent) => void,
onKeyDown?: ?(e: KeyEvent) => void,
onKeyUp?: ?(e: KeyEvent) => void,
validKeysDown?: ?Array<string>,
validKeysUp?: ?Array<string>,
passthroughAllKeyEvents?: ?boolean,
keyDownEvents?: ?Array<HandledKeyboardEvent>,
keyUpEvents?: ?Array<HandledKeyboardEvent>,
tooltip?: string,
Expand Down Expand Up @@ -1904,9 +1901,6 @@ type Props = $ReadOnly<{|
onBlur?: ?(event: BlurEvent) => void,
onKeyDown?: ?(event: KeyEvent) => void,
onKeyUp?: ?(event: KeyEvent) => void,
validKeysDown?: ?Array<string | HandledKeyboardEvent>,
validKeysUp?: ?Array<string | HandledKeyboardEvent>,
passthroughAllKeyEvents?: ?boolean,
keyDownEvents?: ?Array<HandledKeyboardEvent>,
keyUpEvents?: ?Array<HandledKeyboardEvent>,
acceptsFirstMouse?: ?boolean,
Expand Down Expand Up @@ -3574,6 +3568,8 @@ type Props = $ReadOnly<{|
activeOpacity?: ?number,
style?: ?ViewStyleProp,
hostRef?: ?React.Ref<typeof Animated.View>,
keyDownEvents?: ?Array<HandledKeyboardEvent>,
keyUpEvents?: ?Array<HandledKeyboardEvent>,
|}>;
declare const Touchable: React.AbstractComponent<
Props,
Expand Down Expand Up @@ -3639,9 +3635,6 @@ exports[`public API should not change unintentionally Libraries/Components/View/
onDrop: true,
onKeyDown: true,
onKeyUp: true,
validKeysDown: true,
validKeysUp: true,
passthroughAllKeyEvents: true,
keyDownEvents: true,
keyUpEvents: true,
draggedTypes: true,
Expand Down Expand Up @@ -3838,9 +3831,6 @@ export type HandledKeyboardEvent = $ReadOnly<{|
export type KeyboardEventProps = $ReadOnly<{|
onKeyDown?: ?(event: KeyEvent) => void,
onKeyUp?: ?(event: KeyEvent) => void,
validKeysDown?: ?Array<string | HandledKeyboardEvent>,
validKeysUp?: ?Array<string | HandledKeyboardEvent>,
passthroughAllKeyEvents?: ?boolean,
keyDownEvents?: ?Array<HandledKeyboardEvent>,
keyUpEvents?: ?Array<HandledKeyboardEvent>,
|}>;
Expand Down Expand Up @@ -6450,6 +6440,8 @@ exports[`public API should not change unintentionally Libraries/Pressability/Pre
onFocus?: ?(event: FocusEvent) => void,
onKeyDown?: ?(event: KeyEvent) => void,
onKeyUp?: ?(event: KeyEvent) => void,
keyDownEvents?: ?Array<HandledKeyboardEvent>,
keyUpEvents?: ?Array<HandledKeyboardEvent>,
onHoverIn?: ?(event: MouseEvent) => mixed,
onHoverOut?: ?(event: MouseEvent) => mixed,
onLongPress?: ?(event: PressEvent) => mixed,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ - (void)continuousSpellCheckingDidChange:(BOOL)enabled {}
- (void)grammarCheckingDidChange:(BOOL)enabled {}


- (BOOL)hasValidKeyDownOrValidKeyUp:(nonnull NSString *)key {
- (BOOL)hasKeyDownEventOrKeyUpEvent:(nonnull NSString *)key {
return YES;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/react-native/React/Views/RCTHandledKey.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#if TARGET_OS_OSX
#import <React/RCTConvert.h>

// This class is used for specifying key filtering e.g. for -[RCTView validKeysDown] and -[RCTView validKeysUp]
// This class is used for specifying key filtering e.g. for -[RCTView keyDownEvents] and -[RCTView keyUpEvents]
// Also see RCTViewKeyboardEvent, which is a React representation of an actual NSEvent that is dispatched to JS.
@interface RCTHandledKey : NSObject

Expand Down
8 changes: 1 addition & 7 deletions packages/react-native/React/Views/RCTHandledKey.m
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,6 @@ @implementation RCTConvert (RCTHandledKey)

+ (RCTHandledKey *)RCTHandledKey:(id)json
{
// legacy way of specifying validKeysDown and validKeysUp -- here we ignore the modifiers when comparing to the NSEvent
if ([json isKindOfClass:[NSString class]]) {
return [[RCTHandledKey alloc] initWithKey:(NSString *)json];
}

// modern way of specifying validKeys and validKeysUp -- here we assume missing modifiers to mean false\NO
if ([json isKindOfClass:[NSDictionary class]]) {
NSDictionary *dict = (NSDictionary *)json;
NSString *key = dict[@"key"];
Expand All @@ -122,7 +116,7 @@ + (RCTHandledKey *)RCTHandledKey:(id)json
for (NSString *key in modifiers) {
id value = dict[key];
if (value == nil) {
value = @NO; // assume NO -- instead of nil i.e. "don't care" unlike the string case above.
value = @(NO); // assume NO -- instead of nil i.e. "don't care" unlike the string case above.
}

if (![value isKindOfClass:[NSNumber class]]) {
Expand Down
6 changes: 3 additions & 3 deletions packages/react-native/React/Views/RCTView.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ extern const UIAccessibilityTraits SwitchAccessibilityTrait;
/**
* macOS Properties
*/

@property (nonatomic, assign) CATransform3D transform3D;

// `allowsVibrancy` is readonly on NSView, so let's create a new property to make it assignable
Expand All @@ -171,11 +172,10 @@ extern const UIAccessibilityTraits SwitchAccessibilityTrait;
// NOTE does not properly work with single line text inputs (most key downs). This is because those are
// presumably handled by the window's field editor. To make it work, we'd need to look into providing
// a custom field editor for NSTextField controls.
@property (nonatomic, assign) BOOL passthroughAllKeyEvents;
@property (nonatomic, copy) RCTDirectEventBlock onKeyDown;
@property (nonatomic, copy) RCTDirectEventBlock onKeyUp;
@property (nonatomic, copy) NSArray<RCTHandledKey*> *validKeysDown;
@property (nonatomic, copy) NSArray<RCTHandledKey*> *validKeysUp;
@property (nonatomic, copy) NSArray<RCTHandledKey*> *keyDownEvents;
@property (nonatomic, copy) NSArray<RCTHandledKey*> *keyUpEvents;

// Shadow Properties
@property (nonatomic, strong) NSColor *shadowColor;
Expand Down
15 changes: 5 additions & 10 deletions packages/react-native/React/Views/RCTView.m
Original file line number Diff line number Diff line change
Expand Up @@ -1611,9 +1611,9 @@ - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender

- (RCTViewKeyboardEvent*)keyboardEvent:(NSEvent*)event shouldBlock:(BOOL *)shouldBlock {
BOOL keyDown = event.type == NSEventTypeKeyDown;
NSArray<RCTHandledKey *> *validKeys = keyDown ? self.validKeysDown : self.validKeysUp;
NSArray<RCTHandledKey *> *validKeys = keyDown ? self.keyDownEvents : self.keyUpEvents;

// If the view is focusable and the component didn't explicity set the validKeysDown or validKeysUp,
// If the view is focusable and the component didn't explicity set the keyDownEvents or keyUpEvents,
// allow enter/return and spacebar key events to mimic the behavior of native controls.
if (self.focusable && validKeys == nil) {
validKeys = @[
Expand All @@ -1625,9 +1625,9 @@ - (RCTViewKeyboardEvent*)keyboardEvent:(NSEvent*)event shouldBlock:(BOOL *)shoul
// If a view specifies a key, it will always be removed from the responder chain (i.e. "handled")
*shouldBlock = [RCTHandledKey event:event matchesFilter:validKeys];

// If an event isn't being removed from the queue, but was requested to "passthrough" by a view,
// we want to be sure we dispatch it only once for that view. See note for GetEventDispatchStateDictionary.
if ([self passthroughAllKeyEvents] && !*shouldBlock) {
// If an event isn't being removed from the queue, we want to be sure we dispatch it
// only once for that view. See note for GetEventDispatchStateDictionary.
if (!*shouldBlock) {
NSNumber *tag = [self reactTag];
NSMutableDictionary<NSNumber *, NSNumber *> *dict = GetEventDispatchStateDictionary(event);

Expand All @@ -1638,11 +1638,6 @@ - (RCTViewKeyboardEvent*)keyboardEvent:(NSEvent*)event shouldBlock:(BOOL *)shoul
dict[tag] = @YES;
}

// Don't pass events we don't care about
if (![self passthroughAllKeyEvents] && !*shouldBlock) {
return nil;
}

return [RCTViewKeyboardEvent keyEventFromEvent:event reactTag:self.reactTag];
}

Expand Down
Loading

0 comments on commit 3e3cd23

Please sign in to comment.