[Flare] Ignore keyboard interactions on text input children (#15810)
Nicolas Gallagher committed
Jun 3, 2019 at 14:34 UTC
4f6cab547bab2001f74998bd3979134e18ae1257
2 files changed
+33
-5
packages/react-events/src/Press.js
+12
-5
@@ -414,10 +414,17 @@ function dispatchCancel(
414
}
415
}
416
417
-function isValidKeyPress(key: string): boolean {
417
+function isValidKeyboardEvent(nativeEvent: Object): boolean {
418
+ const {key, target} = nativeEvent;
419
+ const {tagName, isContentEditable} = target;
420
// Accessibility for keyboards. Space and Enter only.
421
// "Spacebar" is for IE 11
420
- return key === 'Enter' || key === ' ' || key === 'Spacebar';
422
+ return (
423
+ (key === 'Enter' || key === ' ' || key === 'Spacebar') &&
424
+ (tagName !== 'INPUT' &&
425
+ tagName !== 'TEXTAREA' &&
426
+ isContentEditable !== true)
427
+ );
428
}
429
430
function calculateDelayMS(delay: ?number, min = 0, fallback = 0) {
@@ -671,7 +678,7 @@ const PressResponder = {
678
679
// Ignore unrelated key events
680
if (pointerType === 'keyboard') {
674
- if (!isValidKeyPress(nativeEvent.key)) {
681
+ if (!isValidKeyboardEvent(nativeEvent)) {
682
return;
683
}
684
}
@@ -717,7 +724,7 @@ const PressResponder = {
724
addRootEventTypes(context, state);
725
} else {
726
// Prevent spacebar press from scrolling the window
720
- if (isValidKeyPress(nativeEvent.key) && nativeEvent.key === ' ') {
727
+ if (isValidKeyboardEvent(nativeEvent) && nativeEvent.key === ' ') {
728
nativeEvent.preventDefault();
729
}
730
}
@@ -859,7 +866,7 @@ const PressResponder = {
866
// Ignore unrelated keyboard events and verify press is within
867
// responder region for non-keyboard events.
868
if (pointerType === 'keyboard') {
862
- if (!isValidKeyPress(nativeEvent.key)) {
869
+ if (!isValidKeyboardEvent(nativeEvent)) {
870
return;
871
}
872
// If the event target isn't within the press target, check if we're still
packages/react-events/src/__tests__/Press-test.internal.js
+21
@@ -561,6 +561,27 @@ describe('Event responder: Press', () => {
561
);
562
});
563
564
+ it('is not called after invalid "keyup" event', () => {
565
+ const inputRef = React.createRef();
566
+ const element = (
567
+ <Press onPress={onPress}>
568
+ <input ref={inputRef} />
569
+ </Press>
570
+ );
571
+ ReactDOM.render(element, container);
572
+ inputRef.current.dispatchEvent(
573
+ createKeyboardEvent('keydown', {key: 'Enter'}),
574
+ );
575
+ inputRef.current.dispatchEvent(
576
+ createKeyboardEvent('keyup', {key: 'Enter'}),
577
+ );
578
+ inputRef.current.dispatchEvent(
579
+ createKeyboardEvent('keydown', {key: ' '}),
580
+ );
581
+ inputRef.current.dispatchEvent(createKeyboardEvent('keyup', {key: ' '}));
582
+ expect(onPress).not.toBeCalled();
583
+ });
584
+
585
it('is always called immediately after press is released', () => {
586
const element = (
587
<Press delayPressEnd={500} onPress={onPress}>