Skip to content

Commit

Permalink
cherry pick c0ec10d: macOS Keyboard Support (microsoft#657)
Browse files Browse the repository at this point in the history
  • Loading branch information
HeyImChris authored and amgleitman committed Dec 17, 2020
1 parent f69bfd7 commit 93dbde3
Show file tree
Hide file tree
Showing 22 changed files with 789 additions and 225 deletions.
32 changes: 31 additions & 1 deletion Libraries/Components/Button.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const View = require('./View/View');

const invariant = require('invariant');

import type {PressEvent} from '../Types/CoreEventTypes';
import type {PressEvent, KeyEvent} from '../Types/CoreEventTypes';
import type {FocusEvent, BlurEvent} from './TextInput/TextInput'; // TODO(OSS Candidate ISS#2710739)

type ButtonProps = $ReadOnly<{|
Expand Down Expand Up @@ -112,6 +112,28 @@ type ButtonProps = $ReadOnly<{|
* Handler to be called when the button loses key focus
*/
onFocus?: ?(e: FocusEvent) => void,

/**
* Handler to be called when a key down press is detected
*/
onKeyDown?: ?(e: KeyEvent) => void,

/**
* Handler to be called when a key up press is detected
*/
onKeyUp?: ?(e: KeyEvent) => void,

/*
* Array of keys to receive key down events for
* For arrow keys, add "leftArrow", "rightArrow", "upArrow", "downArrow",
*/
validKeysDown?: ?Array<string>,

/*
* Array of keys to receive key up events for
* For arrow keys, add "leftArrow", "rightArrow", "upArrow", "downArrow",
*/
validKeysUp?: ?Array<string>,
// ]TODO(OSS Candidate ISS#2710739)
|}>;

Expand Down Expand Up @@ -162,6 +184,10 @@ class Button extends React.Component<ButtonProps> {
testID,
onFocus, // TODO(OSS Candidate ISS#2710739)
onBlur, // TODO(OSS Candidate ISS#2710739)
onKeyDown,
validKeysDown,
validKeysUp,
onKeyUp,
} = this.props;
const buttonStyles = [styles.button];
const textStyles = [styles.text];
Expand Down Expand Up @@ -206,6 +232,10 @@ class Button extends React.Component<ButtonProps> {
onPress={onPress}
onFocus={onFocus} // TODO(OSS Candidate ISS#2710739)
onBlur={onBlur} // TODO(OSS Candidate ISS#2710739)
onKeyDown={onKeyDown}
onKeyUp={onKeyUp}
validKeysDown={validKeysDown}
validKeysUp={validKeysUp}
touchSoundDisabled={touchSoundDisabled}>
<View style={buttonStyles}>
<Text style={textStyles} disabled={disabled}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ exports[`TextInput tests should render as expected: should deep render when mock
onChange={[Function]}
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onKeyUp={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
Expand Down Expand Up @@ -40,6 +42,8 @@ exports[`TextInput tests should render as expected: should deep render when not
onChange={[Function]}
onClick={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onKeyUp={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
Expand Down
14 changes: 14 additions & 0 deletions Libraries/Components/Touchable/TouchableNativeFeedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,18 @@ type Props = $ReadOnly<{|
*/
nextFocusUp?: ?number,

/*
* Array of keys to receive key down events for
* For arrow keys, add "leftArrow", "rightArrow", "upArrow", "downArrow",
*/
validKeysDown?: ?Array<string>,

/*
* Array of keys to receive key up events for
* For arrow keys, add "leftArrow", "rightArrow", "upArrow", "downArrow",
*/
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 @@ -285,6 +297,8 @@ 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
31 changes: 25 additions & 6 deletions Libraries/Components/Touchable/TouchableOpacity.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ type Props = $ReadOnly<{|
style?: ?ViewStyleProp,

hostRef: React.Ref<typeof Animated.View>,
/*
* Array of keys to receive key down events for
* For arrow keys, add "leftArrow", "rightArrow", "upArrow", "downArrow",
*/
validKeysDown?: ?Array<string>,

/*
* Array of keys to receive key up events for
* For arrow keys, add "leftArrow", "rightArrow", "upArrow", "downArrow",
*/
validKeysUp?: ?Array<string>,
|}>;

type State = $ReadOnly<{|
Expand Down Expand Up @@ -164,16 +175,20 @@ class TouchableOpacity extends React.Component<Props, State> {
this.props.onFocus(event);
}
},
onLongPress: event => {
if (this.props.onLongPress != null) {
this.props.onLongPress(event);
onKeyDown: event => {
if (this.props.onKeyDown != null) {
this.props.onKeyDown(event);
}
},
onPress: event => {
if (this.props.onPress != null) {
this.props.onPress(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 => {
this._opacityActive(
event.dispatchConfig.registrationName === 'onResponderGrant'
Expand Down Expand Up @@ -278,6 +293,10 @@ class TouchableOpacity extends React.Component<Props, State> {
onDrop={this.props.onDrop}
onFocus={this.props.onFocus}
onBlur={this.props.onBlur}
onKeyDown={this.props.onKeyDown}
onKeyUp={this.props.onKeyUp}
validKeysDown={this.props.validKeysDown}
validKeysUp={this.props.validKeysUp}
draggedTypes={this.props.draggedTypes} // ]TODO(macOS ISS#2323203)
ref={this.props.hostRef}
{...eventHandlersWithoutBlurAndFocus}>
Expand Down
33 changes: 33 additions & 0 deletions Libraries/Components/Touchable/TouchableWithoutFeedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import type {EdgeInsetsProp} from '../../StyleSheet/EdgeInsetsPropType';
import type {
BlurEvent,
FocusEvent,
KeyEvent,
LayoutEvent,
PressEvent,
MouseEvent, // TODO(macOS ISS#2323203)
Expand Down Expand Up @@ -62,6 +63,10 @@ type Props = $ReadOnly<{|
onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed,
onBlur?: ?(event: BlurEvent) => mixed,
onFocus?: ?(event: FocusEvent) => mixed,
onKeyDown?: ?(event: KeyEvent) => mixed,
onKeyUp?: ?(event: KeyEvent) => mixed,
validKeysDown?: ?Array<string>,
validKeysUp?: ?Array<string>,
onLayout?: ?(event: LayoutEvent) => mixed,
onLongPress?: ?(event: PressEvent) => mixed,
onPress?: ?(event: PressEvent) => mixed,
Expand Down Expand Up @@ -103,6 +108,10 @@ const PASSTHROUGH_PROPS = [
'onAccessibilityAction',
'onBlur',
'onFocus',
'onKeyDown',
'onKeyUp',
'validKeysDown',
'validKeysUp',
'onLayout',
'onMouseEnter', // [TODO(macOS ISS#2323203)
'onMouseLeave',
Expand Down Expand Up @@ -242,4 +251,28 @@ class TouchableWithoutFeedback extends React.Component<Props, State> {
}
}

function createPressabilityConfig(props: Props): PressabilityConfig {
return {
cancelable: !props.rejectResponderTermination,
disabled: props.disabled,
hitSlop: props.hitSlop,
delayLongPress: props.delayLongPress,
delayPressIn: props.delayPressIn,
delayPressOut: props.delayPressOut,
minPressDuration: 0,
pressRectOffset: props.pressRetentionOffset,
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,
onPressOut: props.onPressOut,
};
}

module.exports = TouchableWithoutFeedback;
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ exports[`TouchableHighlight renders correctly 1`] = `
enableFocusRing={true}
focusable={false}
onClick={[Function]}
onKeyDown={[Function]}
onKeyUp={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
Expand Down
4 changes: 4 additions & 0 deletions Libraries/Components/View/ReactNativeViewAttributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ const UIView = {
onDragEnter: true,
onDragLeave: true,
onDrop: true,
onKeyDown: true,
onKeyUp: true,
validKeysDown: true,
validKeysUp: true,
draggedTypes: true, // ]TODO(macOS ISS#2323203)
style: ReactNativeStyleAttributes,
};
Expand Down
14 changes: 14 additions & 0 deletions Libraries/Components/View/ReactNativeViewViewConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ const ReactNativeViewConfig = {
captured: 'onFocusCapture',
},
},
topKeyUp: {
phasedRegistrationNames: {
bubbled: 'onKeyUp',
captured: 'onKeyUpCapture',
},
},
topKeyDown: {
phasedRegistrationNames: {
bubbled: 'onKeyDown',
captured: 'onKeyDownCapture',
},
},
topKeyPress: {
phasedRegistrationNames: {
bubbled: 'onKeyPress',
Expand Down Expand Up @@ -338,6 +350,8 @@ const ReactNativeViewConfig = {
transform: {diff: require('../../Utilities/differ/matricesDiffer')},
translateX: true,
translateY: true,
validKeysDown: true,
validKeysUp: true,
width: true,
zIndex: true,
},
Expand Down
4 changes: 4 additions & 0 deletions Libraries/Components/View/ReactNativeViewViewConfigMacOS.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ const ReactNativeViewViewConfigMacOS = {
onDragLeave: true,
onDrop: true,
onFocus: true,
onKeyDown: true,
onKeyUp: true,
validKeysDown: true,
validKeysUp: true,
onMouseEnter: true,
onMouseLeave: true,
tooltip: true,
Expand Down
17 changes: 17 additions & 0 deletions Libraries/Components/View/ViewPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type {
Layout,
LayoutEvent,
ScrollEvent, // TODO(macOS ISS#2323203)
KeyEvent,
} from '../../Types/CoreEventTypes';
import type {EdgeInsetsProp} from '../../StyleSheet/EdgeInsetsPropType';
import type {Node} from 'react';
Expand All @@ -33,6 +34,8 @@ import type {

// [TODO(macOS ISS#2323203)
import type {DraggedTypesType} from '../View/DraggedType';
//$FlowFixMe
import {array} from 'yargs';
// ]TODO(macOS ISS#2323203)

export type ViewLayout = Layout;
Expand All @@ -41,6 +44,8 @@ export type ViewLayoutEvent = LayoutEvent;
type BubblingEventProps = $ReadOnly<{|
onBlur?: ?(event: BlurEvent) => mixed,
onFocus?: ?(event: FocusEvent) => mixed,
onKeyDown?: ?(event: KeyEvent) => mixed,
onKeyUp?: ?(event: KeyEvent) => mixed,
|}>;

type DirectEventProps = $ReadOnly<{|
Expand Down Expand Up @@ -590,6 +595,18 @@ export type ViewProps = $ReadOnly<{|
*/
enableFocusRing?: ?boolean, // TODO(macOS ISS#2323203)

/*
* Array of keys to receive key down events for
* For arrow keys, add "leftArrow", "rightArrow", "upArrow", "downArrow",
*/
validKeysDown?: ?array<string>,

/*
* Array of keys to receive key up events for
* For arrow keys, add "leftArrow", "rightArrow", "upArrow", "downArrow",
*/
validKeysUp?: ?array<string>,

/**
* Enables Dran'n'Drop Support for certain types of dragged types
*
Expand Down
Loading

0 comments on commit 93dbde3

Please sign in to comment.