[Flare] Ignore keyboard interactions on text input children (#15810)

This commit is contained in:
Nicolas Gallagher
2019-06-03 14:34:08 -07:00
committed by GitHub
parent fa1e8df116
commit 4f6cab547b
2 changed files with 33 additions and 5 deletions
+12 -5
View File
@@ -414,10 +414,17 @@ function dispatchCancel(
}
}
function isValidKeyPress(key: string): boolean {
function isValidKeyboardEvent(nativeEvent: Object): boolean {
const {key, target} = nativeEvent;
const {tagName, isContentEditable} = target;
// Accessibility for keyboards. Space and Enter only.
// "Spacebar" is for IE 11
return key === 'Enter' || key === ' ' || key === 'Spacebar';
return (
(key === 'Enter' || key === ' ' || key === 'Spacebar') &&
(tagName !== 'INPUT' &&
tagName !== 'TEXTAREA' &&
isContentEditable !== true)
);
}
function calculateDelayMS(delay: ?number, min = 0, fallback = 0) {
@@ -671,7 +678,7 @@ const PressResponder = {
// Ignore unrelated key events
if (pointerType === 'keyboard') {
if (!isValidKeyPress(nativeEvent.key)) {
if (!isValidKeyboardEvent(nativeEvent)) {
return;
}
}
@@ -717,7 +724,7 @@ const PressResponder = {
addRootEventTypes(context, state);
} else {
// Prevent spacebar press from scrolling the window
if (isValidKeyPress(nativeEvent.key) && nativeEvent.key === ' ') {
if (isValidKeyboardEvent(nativeEvent) && nativeEvent.key === ' ') {
nativeEvent.preventDefault();
}
}
@@ -859,7 +866,7 @@ const PressResponder = {
// Ignore unrelated keyboard events and verify press is within
// responder region for non-keyboard events.
if (pointerType === 'keyboard') {
if (!isValidKeyPress(nativeEvent.key)) {
if (!isValidKeyboardEvent(nativeEvent)) {
return;
}
// If the event target isn't within the press target, check if we're still
@@ -561,6 +561,27 @@ describe('Event responder: Press', () => {
);
});
it('is not called after invalid "keyup" event', () => {
const inputRef = React.createRef();
const element = (
<Press onPress={onPress}>
<input ref={inputRef} />
</Press>
);
ReactDOM.render(element, container);
inputRef.current.dispatchEvent(
createKeyboardEvent('keydown', {key: 'Enter'}),
);
inputRef.current.dispatchEvent(
createKeyboardEvent('keyup', {key: 'Enter'}),
);
inputRef.current.dispatchEvent(
createKeyboardEvent('keydown', {key: ' '}),
);
inputRef.current.dispatchEvent(createKeyboardEvent('keyup', {key: ' '}));
expect(onPress).not.toBeCalled();
});
it('is always called immediately after press is released', () => {
const element = (
<Press delayPressEnd={500} onPress={onPress}>