|
@@ -14,14 +14,21 @@ import {
|
14
|
14
|
} from 'react-native';
|
15
|
15
|
|
16
|
16
|
// Polyfill GestureResponderEvent type with additional `force` property (iOS)
|
17
|
|
-interface NativeTouchEventWithForce extends NativeTouchEvent { force: number; }
|
|
17
|
+interface NativeTouchEventWithForce extends NativeTouchEvent {
|
|
18
|
+ force: number;
|
|
19
|
+}
|
18
|
20
|
interface GestureResponderEventWithForce extends NativeSyntheticEvent<NativeTouchEventWithForce> {}
|
19
|
21
|
|
20
|
22
|
export interface Props {
|
21
|
23
|
children: React.ReactNode;
|
22
|
|
- touchableComponent?: TouchableHighlight | TouchableOpacity | TouchableNativeFeedback | TouchableWithoutFeedback | React.ReactNode;
|
|
24
|
+ touchableComponent?:
|
|
25
|
+ | TouchableHighlight
|
|
26
|
+ | TouchableOpacity
|
|
27
|
+ | TouchableNativeFeedback
|
|
28
|
+ | TouchableWithoutFeedback
|
|
29
|
+ | React.ReactNode;
|
23
|
30
|
onPress?: () => void;
|
24
|
|
- onPressIn?: (reactTag?) => void;
|
|
31
|
+ onPressIn?: (payload: { reactTag: number | null }) => void;
|
25
|
32
|
onPeekIn?: () => void;
|
26
|
33
|
onPeekOut?: () => void;
|
27
|
34
|
}
|
|
@@ -30,8 +37,7 @@ const PREVIEW_DELAY = 350;
|
30
|
37
|
const PREVIEW_MIN_FORCE = 0.1;
|
31
|
38
|
const PREVIEW_TIMEOUT = 1250;
|
32
|
39
|
|
33
|
|
-export class TouchablePreview extends React.PureComponent<Props, any> {
|
34
|
|
-
|
|
40
|
+export class TouchablePreview extends React.PureComponent<Props> {
|
35
|
41
|
static propTypes = {
|
36
|
42
|
children: PropTypes.node,
|
37
|
43
|
touchableComponent: PropTypes.func,
|
|
@@ -48,7 +54,7 @@ export class TouchablePreview extends React.PureComponent<Props, any> {
|
48
|
54
|
static peeking = false;
|
49
|
55
|
|
50
|
56
|
private timeout: number | undefined;
|
51
|
|
- private ts: number = 0;
|
|
57
|
+ private touchStartedAt: number = 0;
|
52
|
58
|
private onRef = React.createRef<any>();
|
53
|
59
|
onPress = () => {
|
54
|
60
|
const { onPress } = this.props;
|
|
@@ -79,13 +85,13 @@ export class TouchablePreview extends React.PureComponent<Props, any> {
|
79
|
85
|
|
80
|
86
|
onTouchStart = (event: GestureResponderEvent) => {
|
81
|
87
|
// Store a timstamp of the initial touch start
|
82
|
|
- this.ts = event.nativeEvent.timestamp;
|
|
88
|
+ this.touchStartedAt = event.nativeEvent.timestamp;
|
83
|
89
|
}
|
84
|
90
|
|
85
|
91
|
onTouchMove = (event: GestureResponderEventWithForce) => {
|
86
|
92
|
clearTimeout(this.timeout);
|
87
|
93
|
const { force, timestamp } = event.nativeEvent;
|
88
|
|
- const diff = (timestamp - this.ts);
|
|
94
|
+ const diff = timestamp - this.touchStartedAt;
|
89
|
95
|
|
90
|
96
|
if (force > PREVIEW_MIN_FORCE && diff > PREVIEW_DELAY) {
|
91
|
97
|
TouchablePreview.peeking = true;
|
|
@@ -111,21 +117,15 @@ export class TouchablePreview extends React.PureComponent<Props, any> {
|
111
|
117
|
const { children, touchableComponent, onPress, onPressIn, ...props } = this.props;
|
112
|
118
|
|
113
|
119
|
// Default to TouchableWithoutFeedback for iOS if set to TouchableNativeFeedback
|
114
|
|
- const Touchable = (
|
115
|
|
- Platform.OS === 'ios' && touchableComponent instanceof TouchableNativeFeedback
|
116
|
|
- ? TouchableWithoutFeedback
|
117
|
|
- : touchableComponent
|
118
|
|
- ) as typeof TouchableWithoutFeedback;
|
|
120
|
+ const Touchable = (Platform.OS === 'ios' &&
|
|
121
|
+ touchableComponent instanceof TouchableNativeFeedback
|
|
122
|
+ ? TouchableWithoutFeedback
|
|
123
|
+ : touchableComponent) as typeof TouchableWithoutFeedback;
|
119
|
124
|
|
120
|
125
|
// Wrap component with Touchable for handling platform touches
|
121
|
126
|
// and a single react View for detecting force and timing.
|
122
|
127
|
return (
|
123
|
|
- <Touchable
|
124
|
|
- ref={this.onRef}
|
125
|
|
- onPress={this.onPress}
|
126
|
|
- onPressIn={this.onPressIn}
|
127
|
|
- {...props}
|
128
|
|
- >
|
|
128
|
+ <Touchable ref={this.onRef} onPress={this.onPress} onPressIn={this.onPressIn} {...props}>
|
129
|
129
|
<View
|
130
|
130
|
onTouchStart={this.onTouchStart}
|
131
|
131
|
onTouchMove={this.onTouchMove as (event: GestureResponderEvent) => void}
|