1
1
import _ from 'lodash' ;
2
- import PropTypes from 'prop-types' ;
3
2
import React , { PureComponent } from 'react' ;
4
- import { StyleSheet , LayoutAnimation } from 'react-native' ;
5
- import { asBaseComponent , forwardRef } from '../../commons' ;
3
+ import { StyleSheet , LayoutAnimation , StyleProp , ViewStyle } from 'react-native' ;
4
+ import { asBaseComponent , forwardRef } from '../../commons/new ' ;
6
5
import { Colors } from '../../style' ;
7
- import TouchableOpacity from '../touchableOpacity' ;
6
+ import TouchableOpacity , { TouchableOpacityProps } from '../touchableOpacity' ;
8
7
import View from '../view' ;
9
8
10
9
const MAX_SHOWN_PAGES = 7 ;
11
10
const NUM_LARGE_INDICATORS = 3 ;
12
11
const DEFAULT_INDICATOR_COLOR = Colors . blue30 ;
13
12
14
- function getColorStyle ( color , inactiveColor , isCurrentPage ) {
13
+ function getColorStyle ( isCurrentPage : boolean , color ?: string , inactiveColor ?: string ) {
15
14
const activeColor = color || DEFAULT_INDICATOR_COLOR ;
16
15
return {
17
16
borderColor : isCurrentPage ? activeColor : inactiveColor || activeColor ,
18
17
backgroundColor : isCurrentPage ? activeColor : inactiveColor || 'transparent'
19
18
} ;
20
19
}
21
20
22
- function getSizeStyle ( size , enlargeActive , index , currentPage ) {
21
+ function getSizeStyle ( size : number , index : number , currentPage : number , enlargeActive ?: boolean ) {
23
22
const temp = enlargeActive ? ( index === currentPage ? size + 2 : size ) : size ;
24
23
return { width : temp , height : temp , borderRadius : temp / 2 } ;
25
24
}
26
25
26
+ function getNumberOfPagesShown ( props : PageControlProps ) {
27
+ return Math . min ( MAX_SHOWN_PAGES , props . numOfPages ) ;
28
+ }
29
+
30
+ export interface PageControlProps {
27
31
/**
28
- * @description : Page indicator, typically used in paged scroll-views
29
- * @image : https://user-images.githubusercontent.com/33805983/34663655-76698110-f460-11e7-854b-243d27f66fec.png
30
- * @example : https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/PageControlScreen.js
31
- */
32
- class PageControl extends PureComponent {
33
- static displayName = 'PageControl' ;
34
- static propTypes = {
35
- /**
36
32
* Limit the number of page indicators shown.
37
33
* enlargeActive prop is disabled in this state,
38
34
* When set to true there will be maximum of 7 shown.
39
35
* Only relevant when numOfPages > 5.
40
36
*/
41
- limitShownPages : PropTypes . bool ,
37
+ limitShownPages ?: boolean ;
42
38
/**
43
39
* Additional styles for the top container
44
40
*/
45
- containerStyle : PropTypes . oneOfType ( [ PropTypes . object , PropTypes . number , PropTypes . array ] ) ,
41
+ containerStyle ?: StyleProp < ViewStyle > ;
46
42
/**
47
43
* Total number of pages
48
44
*/
49
- numOfPages : PropTypes . number ,
45
+ numOfPages : number ;
50
46
/**
51
47
* Zero-based index of the current page
52
48
*/
53
- currentPage : PropTypes . number ,
49
+ currentPage : number ;
54
50
/**
55
51
* Action handler for clicking on a page indicator
56
52
*/
57
- onPagePress : PropTypes . func ,
53
+ onPagePress ?: ( index : number ) => void ;
58
54
/**
59
55
* Color of the selected page dot and, if inactiveColor not passed, the border of the not selected pages
60
56
*/
61
- color : PropTypes . string ,
57
+ color ?: string ;
62
58
/**
63
59
* Color of the unselected page dots and the border of the not selected pages
64
60
*/
65
- inactiveColor : PropTypes . string ,
61
+ inactiveColor ?: string ;
66
62
/**
67
63
* The size of the page indicator.
68
64
* When setting limitShownPages the medium sized will be 2/3 of size and the small will be 1/3 of size.
69
65
* An alternative is to send an array [smallSize, mediumSize, largeSize].
70
66
*/
71
- size : PropTypes . oneOfType ( [ PropTypes . number , PropTypes . array ] ) ,
67
+ size ?: number | [ number , number , number ] ;
72
68
/**
73
69
* Whether to enlarge the active page indicator
74
70
* Irrelevant when limitShownPages is in effect.
75
71
*/
76
- enlargeActive : PropTypes . bool ,
72
+ enlargeActive ?: boolean ;
77
73
/**
78
74
* The space between the siblings page indicators
79
75
*/
80
- spacing : PropTypes . number
81
- } ;
76
+ spacing ?: number ;
77
+ }
78
+
79
+ interface State {
80
+ numOfPagesShown : number ;
81
+ largeIndicatorsOffset : number ;
82
+ pagesOffset : number ;
83
+ prevPage ?: number ;
84
+ }
85
+
86
+ /**
87
+ * @description : Page indicator, typically used in paged scroll-views
88
+ * @image : https://user-images.githubusercontent.com/33805983/34663655-76698110-f460-11e7-854b-243d27f66fec.png
89
+ * @example : https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/PageControlScreen.js
90
+ */
91
+ class PageControl extends PureComponent < PageControlProps , State > {
92
+ static displayName = 'PageControl' ;
82
93
83
94
static DEFAULT_SIZE = 10 ;
84
95
static DEFAULT_SPACING = 4 ;
@@ -87,11 +98,11 @@ class PageControl extends PureComponent {
87
98
enlargeActive : false
88
99
} ;
89
100
90
- constructor ( props ) {
101
+ constructor ( props : PageControlProps ) {
91
102
super ( props ) ;
92
103
93
104
this . state = {
94
- numOfPagesShown : Math . min ( MAX_SHOWN_PAGES , props . numOfPages ) ,
105
+ numOfPagesShown : getNumberOfPagesShown ( props ) ,
95
106
largeIndicatorsOffset : 0 ,
96
107
pagesOffset : 0 ,
97
108
prevPage : undefined
@@ -109,10 +120,10 @@ class PageControl extends PureComponent {
109
120
}
110
121
}
111
122
112
- static getDerivedStateFromProps ( nextProps , prevState ) {
123
+ static getDerivedStateFromProps ( nextProps : PageControlProps , prevState : State ) {
113
124
const { currentPage} = nextProps ;
114
125
const { largeIndicatorsOffset : prevLargeIndicatorsOffset , prevPage} = prevState ;
115
- const newState = { } ;
126
+ const newState : { prevPage ?: number , pagesOffset ?: number , largeIndicatorsOffset ?: number } = { } ;
116
127
117
128
if ( currentPage !== prevPage ) {
118
129
newState . prevPage = currentPage ;
@@ -130,17 +141,17 @@ class PageControl extends PureComponent {
130
141
return _ . isEmpty ( newState ) ? null : newState ;
131
142
}
132
143
133
- static animate ( props ) {
144
+ static animate ( props : PageControlProps ) {
134
145
if ( PageControl . showLimitedVersion ( props ) ) {
135
146
LayoutAnimation . configureNext ( { ...LayoutAnimation . Presets . linear , duration : 100 } ) ;
136
147
}
137
148
}
138
149
139
- static showLimitedVersion ( { limitShownPages, numOfPages} ) {
150
+ static showLimitedVersion ( { limitShownPages, numOfPages} : PageControlProps ) {
140
151
return limitShownPages && numOfPages > 5 ;
141
152
}
142
153
143
- getSize ( index ) {
154
+ getSize ( index : number ) : undefined | number {
144
155
const { largeIndicatorsOffset} = this . state ;
145
156
const { numOfPages} = this . props ;
146
157
let mediumSize ,
@@ -166,23 +177,23 @@ class PageControl extends PureComponent {
166
177
}
167
178
}
168
179
169
- onPagePress = ( { index} ) => {
180
+ onPagePress = ( { customValue : index } : TouchableOpacityProps ) => {
170
181
PageControl . animate ( this . props ) ;
171
182
_ . invoke ( this . props , 'onPagePress' , index ) ;
172
183
} ;
173
184
174
- renderIndicator ( index , size , enlargeActive ) {
185
+ renderIndicator ( index : number , size : number , enlargeActive ?: boolean ) {
175
186
const { currentPage, color, inactiveColor, onPagePress, spacing = PageControl . DEFAULT_SPACING } = this . props ;
176
187
return (
177
188
< TouchableOpacity
178
- index = { index }
189
+ customValue = { index }
179
190
onPress = { onPagePress && this . onPagePress }
180
191
key = { index }
181
192
style = { [
182
193
styles . pageIndicator ,
183
194
{ marginHorizontal : spacing / 2 } ,
184
- getColorStyle ( color , inactiveColor , index === currentPage ) ,
185
- getSizeStyle ( size , enlargeActive , index , currentPage )
195
+ getColorStyle ( index === currentPage , color , inactiveColor ) ,
196
+ getSizeStyle ( size , index , currentPage , enlargeActive )
186
197
] }
187
198
/>
188
199
) ;
@@ -220,7 +231,7 @@ class PageControl extends PureComponent {
220
231
}
221
232
}
222
233
223
- export default asBaseComponent ( forwardRef ( PageControl ) ) ;
234
+ export default asBaseComponent < PageControlProps > ( forwardRef ( PageControl ) ) ;
224
235
225
236
const styles = StyleSheet . create ( {
226
237
container : {
0 commit comments