1
1
import _ from 'lodash' ;
2
- import PropTypes from 'prop-types' ;
3
2
import React , { PureComponent } from 'react' ;
4
- import { Animated , Easing , StyleSheet } from 'react-native' ;
3
+ import { Animated , Easing , StyleSheet , StyleProp , ViewStyle , LayoutChangeEvent } from 'react-native' ;
5
4
import { Constants } from '../../helpers' ;
6
5
import View from '../view' ;
7
6
import asPanViewConsumer from '../panningViews/asPanViewConsumer' ;
8
- import PanningProvider from '../panningViews/panningProvider' ;
7
+ import PanningProvider , { PanningDirections , PanAmountsProps , PanDirectionsProps , PanLocationProps } from '../panningViews/panningProvider' ;
9
8
import PanResponderView from '../panningViews/panResponderView' ;
10
9
11
10
const MAXIMUM_DRAGS_AFTER_SWIPE = 2 ;
12
11
13
- class DialogDismissibleView extends PureComponent {
14
- static propTypes = {
15
- /**
16
- * The direction of the allowed pan (default is DOWN)
17
- * Types: UP, DOWN, LEFT and RIGHT (using PanningProvider.Directions.###)
18
- */
19
- direction : PropTypes . oneOf ( Object . values ( PanningProvider . Directions ) ) ,
20
- /**
21
- * onDismiss callback
22
- */
23
- onDismiss : PropTypes . func ,
24
- /**
25
- * The dialog`s container style
26
- */
27
- containerStyle : PropTypes . oneOfType ( [ PropTypes . object , PropTypes . number , PropTypes . array ] ) ,
28
- /**
29
- * Whether to show the dialog or not
30
- */
31
- visible : PropTypes . bool
32
- } ;
12
+ interface PanContextProps {
13
+ isPanning : boolean ;
14
+ dragDeltas : PanAmountsProps ;
15
+ swipeDirections : PanDirectionsProps ;
16
+ }
17
+
18
+ interface DialogDismissibleProps {
19
+ /**
20
+ * Additional styling
21
+ */
22
+ style ?: StyleProp < ViewStyle > ;
23
+ /**
24
+ * The direction of the allowed pan (default is DOWN)
25
+ * Types: UP, DOWN, LEFT and RIGHT (using PanningProvider.Directions.###)
26
+ */
27
+ direction ?: PanningDirections ;
28
+ /**
29
+ * onDismiss callback
30
+ */
31
+ onDismiss ?: ( ) => void ;
32
+ /**
33
+ * The dialog`s container style
34
+ */
35
+ containerStyle ?: StyleProp < ViewStyle > ;
36
+ /**
37
+ * Whether to show the dialog or not
38
+ */
39
+ visible ?: boolean ;
40
+ }
41
+
42
+ interface Props extends DialogDismissibleProps {
43
+ context : PanContextProps ;
44
+ }
45
+
46
+ interface State {
47
+ visible ?: boolean ;
48
+ hide : boolean ;
49
+ }
50
+
51
+ interface LocationProps {
52
+ left : number ;
53
+ top : number ;
54
+ }
33
55
34
- static defaultProps = {
35
- direction : PanningProvider . Directions . DOWN ,
36
- onDismiss : _ . noop
56
+ const DEFAULT_DIRECTION = PanningProvider . Directions . DOWN ;
57
+
58
+ class DialogDismissibleView extends PureComponent < Props , State > {
59
+
60
+ public static defaultProps : Partial < Props > = {
61
+ direction : DEFAULT_DIRECTION ,
62
+ onDismiss : ( ) => { }
37
63
} ;
38
64
39
- constructor ( props ) {
65
+ private hiddenLocation : LocationProps ;
66
+ private animatedValue = new Animated . Value ( 0 ) ;
67
+ private width = Constants . screenWidth ;
68
+ private height = Constants . screenHeight ;
69
+ private counter = 0 ;
70
+ private swipe : PanDirectionsProps = { } ;
71
+ private thresholdX = 0 ;
72
+ private thresholdY = 0 ;
73
+ private ref = React . createRef < any > ( ) ;
74
+
75
+ constructor ( props : Props ) {
40
76
super ( props ) ;
41
77
42
- this . setInitialValues ( ) ;
78
+ this . hiddenLocation = this . getHiddenLocation ( 0 , 0 ) ;
43
79
this . state = {
44
80
visible : props . visible ,
45
81
hide : false
46
82
} ;
47
83
}
48
84
49
- setInitialValues ( ) {
50
- this . hiddenLocation = { } ;
51
- this . resetSwipe ( ) ;
52
- this . animatedValue = new Animated . Value ( 0 ) ;
53
- this . width = Constants . screenWidth ;
54
- this . height = Constants . screenHeight ;
55
- this . hiddenLocation = this . getHiddenLocation ( 0 , 0 ) ;
56
- }
57
-
58
- componentDidUpdate ( prevProps ) {
59
- const { isPanning, dragDeltas, swipeDirections} = this . props . context ; // eslint-disable-line
60
- const { dragDeltas : prevDragDeltas , swipeDirections : prevSwipeDirections } = prevProps . context ; // eslint-disable-line
85
+ componentDidUpdate ( prevProps : Props ) {
86
+ const { isPanning, dragDeltas, swipeDirections} = this . props . context ;
87
+ const { dragDeltas : prevDragDeltas , swipeDirections : prevSwipeDirections } = prevProps . context ;
61
88
const { hide} = this . state ;
62
89
63
90
if (
@@ -81,7 +108,7 @@ class DialogDismissibleView extends PureComponent {
81
108
}
82
109
}
83
110
84
- static getDerivedStateFromProps ( nextProps , prevState ) {
111
+ static getDerivedStateFromProps ( nextProps : DialogDismissibleProps , prevState : State ) {
85
112
const { visible} = nextProps ;
86
113
const { visible : prevVisible } = prevState ;
87
114
@@ -97,8 +124,8 @@ class DialogDismissibleView extends PureComponent {
97
124
this . swipe = { } ;
98
125
} ;
99
126
100
- isSwiping = ( ) => {
101
- return this . swipe . x || this . swipe . y ;
127
+ isSwiping = ( ) : boolean => {
128
+ return ! _ . isUndefined ( this . swipe . x ) || ! _ . isUndefined ( this . swipe . y ) ;
102
129
} ;
103
130
104
131
onDrag = ( ) => {
@@ -111,11 +138,11 @@ class DialogDismissibleView extends PureComponent {
111
138
}
112
139
} ;
113
140
114
- onSwipe = swipeDirections => {
141
+ onSwipe = ( swipeDirections : PanDirectionsProps ) => {
115
142
this . swipe = swipeDirections ;
116
143
} ;
117
144
118
- getHiddenLocation = ( left , top ) => {
145
+ getHiddenLocation = ( left : number , top : number ) : LocationProps => {
119
146
const { direction} = this . props ;
120
147
const topInset = Constants . isIphoneX ? Constants . getSafeAreaInsets ( ) . top : Constants . isIOS ? 20 : 0 ;
121
148
const bottomInset = Constants . isIphoneX ? Constants . getSafeAreaInsets ( ) . bottom : Constants . isIOS ? 20 : 0 ;
@@ -140,7 +167,7 @@ class DialogDismissibleView extends PureComponent {
140
167
return result ;
141
168
} ;
142
169
143
- animateTo = ( toValue , animationEndCallback ) => {
170
+ animateTo = ( toValue : number , animationEndCallback ?: Animated . EndCallback ) => {
144
171
Animated . timing ( this . animatedValue , {
145
172
toValue,
146
173
duration : 300 ,
@@ -168,17 +195,19 @@ class DialogDismissibleView extends PureComponent {
168
195
} ;
169
196
} ;
170
197
171
- onLayout = event => {
198
+ onLayout = ( event : LayoutChangeEvent ) => {
172
199
// DO NOT move the width\height into the measureInWindow - it causes errors with orientation change
173
200
const layout = event . nativeEvent . layout ;
174
201
this . width = layout . width ;
175
202
this . height = layout . height ;
176
203
this . thresholdX = this . width / 2 ;
177
204
this . thresholdY = this . height / 2 ;
178
- this . ref . measureInWindow ( ( x , y ) => {
179
- this . hiddenLocation = this . getHiddenLocation ( x , y ) ;
180
- this . animateTo ( 1 ) ;
181
- } ) ;
205
+ if ( this . ref . current ) {
206
+ this . ref . current . measureInWindow ( ( x : number , y : number ) => {
207
+ this . hiddenLocation = this . getHiddenLocation ( x , y ) ;
208
+ this . animateTo ( 1 ) ;
209
+ } ) ;
210
+ }
182
211
} ;
183
212
184
213
hide = ( ) => {
@@ -187,16 +216,16 @@ class DialogDismissibleView extends PureComponent {
187
216
this . animateTo ( 0 , ( ) => this . setState ( { visible : false , hide : false } , onDismiss ) ) ;
188
217
} ;
189
218
190
- resetToShown = ( left , top , direction ) => {
219
+ resetToShown = ( left : number , top : number , direction : PanningDirections ) => {
191
220
const toValue = [ PanningProvider . Directions . LEFT , PanningProvider . Directions . RIGHT ] . includes ( direction )
192
221
? 1 + left / this . hiddenLocation . left
193
222
: 1 + top / this . hiddenLocation . top ;
194
223
195
224
this . animateTo ( toValue ) ;
196
225
} ;
197
226
198
- onPanLocationChanged = ( { left, top} ) => {
199
- const { direction} = this . props ;
227
+ onPanLocationChanged = ( { left = 0 , top = 0 } : PanLocationProps ) => {
228
+ const { direction = DEFAULT_DIRECTION } = this . props ;
200
229
const endValue = { x : Math . round ( left ) , y : Math . round ( top ) } ;
201
230
if ( this . isSwiping ( ) ) {
202
231
this . hide ( ) ;
@@ -220,7 +249,7 @@ class DialogDismissibleView extends PureComponent {
220
249
const { visible} = this . state ;
221
250
222
251
return (
223
- < View ref = { r => ( this . ref = r ) } style = { containerStyle } onLayout = { this . onLayout } >
252
+ < View ref = { this . ref } style = { containerStyle } onLayout = { this . onLayout } >
224
253
< PanResponderView
225
254
// !visible && styles.hidden is done to fix a bug is iOS
226
255
style = { [ style , this . getAnimationStyle ( ) , ! visible && styles . hidden ] }
@@ -234,7 +263,7 @@ class DialogDismissibleView extends PureComponent {
234
263
}
235
264
}
236
265
237
- export default asPanViewConsumer ( DialogDismissibleView ) ;
266
+ export default asPanViewConsumer < DialogDismissibleProps > ( DialogDismissibleView ) ;
238
267
239
268
const styles = StyleSheet . create ( {
240
269
hidden : {
0 commit comments