Skip to content

Commit 70bcba0

Browse files
akwasniewskilatekvo
authored andcommitted
[Web] fixed texinput submition when inside pressable (#3623)
## Description Fixes issue #3622. On web, when we submitted `TextInput` using enter, which was inside `Pressable`, then Gesture Handler didn't recognize any subsqeuent taps or gestures. Tap gesture was kept in active state, and caused all other gestures to fail. ## Test plan ```ts import React from 'react'; import { useState } from 'react'; import { View } from 'react-native'; import { Pressable, TextInput } from 'react-native-gesture-handler'; export default function EmptyExample() { const [shown, setShown] = useState(true) return ( <View> <Pressable key="2" style={{ backgroundColor: 'red', width: 100, height: 60 }} testID="bad-pressable" onPress={() => { console.log("pressed") }}> {shown ? <TextInput style={{ backgroundColor: 'green', width: 100, height: 60 }} onSubmitEditing={() => { console.log("submit"); setShown(false); }} /> : <View ></View>} </Pressable > </View > ) }; ```
1 parent 83f1ee4 commit 70bcba0

File tree

1 file changed

+50
-8
lines changed

1 file changed

+50
-8
lines changed

packages/react-native-gesture-handler/src/web/tools/KeyboardEventManager.ts

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,47 @@ import EventManager from './EventManager';
33
import { PointerType } from '../../PointerType';
44

55
export default class KeyboardEventManager extends EventManager<HTMLElement> {
6-
private activationKeys = ['Enter', ' '];
7-
private cancelationKeys = ['Tab'];
6+
private static activationKeys = ['Enter', ' '];
7+
private static cancelationKeys = ['Tab'];
88
private isPressed = false;
9+
private static registeredStaticListeners = false;
10+
private static instances: Set<KeyboardEventManager> = new Set();
11+
12+
private static keyUpStaticCallback = (event: KeyboardEvent): void => {
13+
// We need a global listener, as in some cases, keyUp event gets stop-propagated.
14+
// Then, if we used only component-level listeners the gesture would never end,
15+
// causing other gestues to fail.
16+
17+
if (this.activationKeys.indexOf(event.key) === -1) {
18+
return;
19+
}
20+
21+
this.instances.forEach((item) => {
22+
item.onKeyUp(event);
23+
});
24+
};
925

1026
private keyDownCallback = (event: KeyboardEvent): void => {
11-
if (this.cancelationKeys.indexOf(event.key) !== -1 && this.isPressed) {
27+
if (
28+
KeyboardEventManager.cancelationKeys.indexOf(event.key) !== -1 &&
29+
this.isPressed
30+
) {
1231
this.dispatchEvent(event, EventTypes.CANCEL);
1332
return;
1433
}
1534

16-
if (this.activationKeys.indexOf(event.key) === -1) {
35+
if (KeyboardEventManager.activationKeys.indexOf(event.key) === -1) {
1736
return;
1837
}
1938

2039
this.dispatchEvent(event, EventTypes.DOWN);
2140
};
2241

23-
private keyUpCallback = (event: KeyboardEvent): void => {
24-
if (this.activationKeys.indexOf(event.key) === -1 || !this.isPressed) {
42+
private onKeyUp = (event: KeyboardEvent): void => {
43+
if (
44+
KeyboardEventManager.activationKeys.indexOf(event.key) === -1 ||
45+
!this.isPressed
46+
) {
2547
return;
2648
}
2749

@@ -53,12 +75,32 @@ export default class KeyboardEventManager extends EventManager<HTMLElement> {
5375

5476
public registerListeners(): void {
5577
this.view.addEventListener('keydown', this.keyDownCallback);
56-
this.view.addEventListener('keyup', this.keyUpCallback);
78+
79+
KeyboardEventManager.instances.add(this);
80+
81+
if (!KeyboardEventManager.registeredStaticListeners) {
82+
KeyboardEventManager.registeredStaticListeners = true;
83+
document.addEventListener(
84+
'keyup',
85+
KeyboardEventManager.keyUpStaticCallback,
86+
{ capture: true }
87+
);
88+
}
5789
}
5890

5991
public unregisterListeners(): void {
6092
this.view.removeEventListener('keydown', this.keyDownCallback);
61-
this.view.removeEventListener('keyup', this.keyUpCallback);
93+
94+
KeyboardEventManager.instances.delete(this);
95+
96+
if (KeyboardEventManager.instances.size === 0) {
97+
document.removeEventListener(
98+
'keyup',
99+
KeyboardEventManager.keyUpStaticCallback,
100+
{ capture: true }
101+
);
102+
KeyboardEventManager.registeredStaticListeners = false;
103+
}
62104
}
63105

64106
protected mapEvent(

0 commit comments

Comments
 (0)