@@ -2,30 +2,27 @@ import _ from 'lodash';
2
2
import PropTypes from 'prop-types' ;
3
3
import memoize from 'memoize-one' ;
4
4
import React from 'react' ;
5
- import { StyleSheet , ScrollView , Animated , Easing , UIManager , findNodeHandle } from 'react-native' ;
5
+ import { StyleSheet , UIManager , findNodeHandle } from 'react-native' ;
6
6
import { Constants } from '../../helpers' ;
7
7
import { Colors } from '../../style' ;
8
8
import { PureBaseComponent } from '../../commons' ;
9
9
import View from '../view' ;
10
10
import Carousel from '../carousel' ;
11
11
import PageControl from '../pageControl' ;
12
- import Image from '../image' ;
13
12
import ColorSwatch , { SWATCH_SIZE } from './ColorSwatch' ;
13
+ import ScrollBar from '../scrollBar' ;
14
14
15
15
16
16
const VERTICAL_PADDING = 16 ;
17
17
const HORIZONTAL_PADDING = 20 ;
18
18
const MINIMUM_MARGIN = 16 ;
19
19
const SCROLLABLE_HEIGHT = 92 ;
20
- const GRADIENT_WIDTH = 27 ;
21
20
const DEFAULT_NUMBER_OF_ROWS = 3 ;
22
- const gradientImage = ( ) => require ( './assets/gradient.png' ) ;
23
21
24
22
/**
25
23
* @description : A color palette component
26
24
* @example : https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/ColorPickerScreen.js
27
25
* @notes : This is a screen width component
28
- * @extends : ScrollView
29
26
*/
30
27
export default class ColorPalette extends PureBaseComponent {
31
28
static displayName = 'ColorPalette' ;
@@ -39,6 +36,10 @@ export default class ColorPalette extends PureBaseComponent {
39
36
* Style to pass the palette container
40
37
*/
41
38
containerStyle : PropTypes . oneOfType ( [ PropTypes . object , PropTypes . number , PropTypes . array ] ) ,
39
+ /**
40
+ * The container margins
41
+ */
42
+ containerWidth : PropTypes . number ,
42
43
/**
43
44
* Whether to use pagination when number of colors exceeds the number of rows
44
45
*/
@@ -80,12 +81,11 @@ export default class ColorPalette extends PureBaseComponent {
80
81
81
82
this . state = {
82
83
currentPage : 0 ,
83
- scrollable : false ,
84
- gradientOpacity : new Animated . Value ( 0 )
84
+ scrollable : false
85
85
} ;
86
86
87
87
this . carousel = React . createRef ( ) ;
88
- this . scrollView = React . createRef ( ) ;
88
+ this . scrollBar = React . createRef ( ) ;
89
89
this . initLocalVariables ( ) ;
90
90
}
91
91
@@ -99,7 +99,7 @@ export default class ColorPalette extends PureBaseComponent {
99
99
100
100
onOrientationChanged = ( ) => {
101
101
this . initLocalVariables ( ) ;
102
- this . setState ( { gradientOpacity : new Animated . Value ( 0 ) } ) ; // only to trigger render
102
+ this . setState ( { orientation : Constants . orientation } ) ; // only to trigger render
103
103
}
104
104
105
105
initLocalVariables ( ) {
@@ -127,15 +127,21 @@ export default class ColorPalette extends PureBaseComponent {
127
127
return this . getUniqueColors ( this . props . colors ) ;
128
128
}
129
129
130
- getUniqueColors = memoize ( ( colors ) => {
131
- const c = _ . map ( colors , color => {
132
- if ( Colors . isTransparent ( color ) ) {
133
- return color ;
134
- }
135
- return _ . toUpper ( color ) ;
136
- } ) ;
137
- return _ . uniq ( c ) ;
138
- } ) ;
130
+ get containerWidth ( ) {
131
+ return this . props . containerWidth || Constants . screenWidth ;
132
+ }
133
+
134
+ getUniqueColors = memoize (
135
+ ( colors ) => {
136
+ const c = _ . map ( colors , color => {
137
+ if ( Colors . isTransparent ( color ) ) {
138
+ return color ;
139
+ }
140
+ return _ . toUpper ( color ) ;
141
+ } ) ;
142
+ return _ . uniq ( c ) ;
143
+ }
144
+ ) ;
139
145
140
146
getNumberOfRows ( ) {
141
147
const { numberOfRows} = this . props ;
@@ -154,7 +160,7 @@ export default class ColorPalette extends PureBaseComponent {
154
160
// additional items have the minimum width of the margin between them and the previous item's width
155
161
const additionalItemMinimumWidth = SWATCH_SIZE + MINIMUM_MARGIN ;
156
162
// floor(space left / size of additional items)
157
- itemsPerRow += Math . floor ( ( Constants . screenWidth - firstItemWidth ) / additionalItemMinimumWidth ) ;
163
+ itemsPerRow += Math . floor ( ( this . containerWidth - firstItemWidth ) / additionalItemMinimumWidth ) ;
158
164
159
165
return itemsPerRow ;
160
166
}
@@ -170,26 +176,14 @@ export default class ColorPalette extends PureBaseComponent {
170
176
}
171
177
172
178
// Now that we have the itemsPerRow set, we can calculate the actual innerMargin
173
- const remainingSpace = Constants . screenWidth - this . itemsPerRow * SWATCH_SIZE - 2 * HORIZONTAL_PADDING ;
179
+ const remainingSpace = this . containerWidth - this . itemsPerRow * SWATCH_SIZE - 2 * HORIZONTAL_PADDING ;
174
180
// With pagination - there's 1 less space than the number of items
175
181
const numberOfMargins = this . itemsPerRow - 1 ;
176
182
const margin = remainingSpace / numberOfMargins ;
177
183
// We have to subtract something since otherwise some Android devices will overflow into the next line
178
184
return ( margin - 0.001 ) / 2 ;
179
185
}
180
186
181
- animateGradientOpacity = ( offsetX , contentWidth ) => {
182
- const overflow = contentWidth - Constants . screenWidth ;
183
- const newValue = offsetX > 0 && offsetX >= overflow - 1 ? 0 : 1 ;
184
-
185
- Animated . timing ( this . state . gradientOpacity , {
186
- toValue : newValue ,
187
- easing : Easing . inOut ( Easing . linear ) ,
188
- duration : 300 ,
189
- useNativeDriver : true
190
- } ) . start ( ) ;
191
- } ;
192
-
193
187
scrollToSelected ( ) {
194
188
const { scrollable, currentPage} = this . state ;
195
189
@@ -199,18 +193,19 @@ export default class ColorPalette extends PureBaseComponent {
199
193
if ( childRef ) {
200
194
const handle = findNodeHandle ( childRef ) ;
201
195
if ( handle ) {
202
- UIManager . measureLayoutRelativeToParent ( handle , e => {
203
- console . warn ( e ) ;
204
- } ,
205
- ( x , y , w , h ) => {
206
- if ( x + w > Constants . screenWidth ) {
207
- this . scrollView . current . scrollTo ( {
208
- x : x + w + HORIZONTAL_PADDING - Constants . screenWidth ,
209
- y : 0 ,
210
- animated : false
211
- } ) ;
212
- }
213
- } ) ;
196
+ UIManager . measureLayoutRelativeToParent ( handle ,
197
+ e => {
198
+ console . warn ( e ) ;
199
+ } ,
200
+ ( x , y , w , h ) => {
201
+ if ( x + w > this . containerWidth ) {
202
+ this . scrollBar . current . scrollTo ( {
203
+ x : x + w + HORIZONTAL_PADDING - this . containerWidth ,
204
+ y : 0 ,
205
+ animated : false
206
+ } ) ;
207
+ }
208
+ } ) ;
214
209
}
215
210
}
216
211
} else if ( this . usePagination ) {
@@ -219,16 +214,7 @@ export default class ColorPalette extends PureBaseComponent {
219
214
}
220
215
221
216
onContentSizeChange = contentWidth => {
222
- if ( contentWidth > Constants . screenWidth ) {
223
- this . setState ( { scrollable : true , gradientOpacity : new Animated . Value ( 1 ) } ) ;
224
- }
225
- } ;
226
-
227
- onScroll = event => {
228
- const { contentOffset, contentSize} = event . nativeEvent ;
229
- const offsetX = contentOffset . x ;
230
- const contentWidth = contentSize . width ;
231
- this . animateGradientOpacity ( offsetX , contentWidth ) ;
217
+ this . setState ( { scrollable : contentWidth > this . containerWidth , contentWidth} ) ;
232
218
} ;
233
219
234
220
onChangePage = index => {
@@ -245,25 +231,6 @@ export default class ColorPalette extends PureBaseComponent {
245
231
} , 0 ) ;
246
232
} ;
247
233
248
- renderGradient ( ) {
249
- return (
250
- < Animated . View
251
- pointerEvents = "none"
252
- style = { {
253
- position : 'absolute' ,
254
- right : 0 ,
255
- opacity : this . state . gradientOpacity
256
- } }
257
- >
258
- < Image
259
- source = { gradientImage ( ) }
260
- resizeMode = { 'stretch' }
261
- style = { { width : GRADIENT_WIDTH , height : SCROLLABLE_HEIGHT - 12 , tintColor : Colors . white } }
262
- />
263
- </ Animated . View >
264
- ) ;
265
- }
266
-
267
234
getHorizontalMargins = ( index ) => {
268
235
const isFirst = index === 0 ;
269
236
const isOnLeft = isFirst || index % this . itemsPerRow === 0 ;
@@ -300,7 +267,7 @@ export default class ColorPalette extends PureBaseComponent {
300
267
} ;
301
268
302
269
renderColorSwatch ( color , index ) {
303
- const { animatedIndex} = this . props ;
270
+ const { animatedIndex, testID } = this . props ;
304
271
305
272
return (
306
273
< ColorSwatch
@@ -313,6 +280,7 @@ export default class ColorPalette extends PureBaseComponent {
313
280
animated = { index === animatedIndex }
314
281
onPress = { this . onValueChange }
315
282
ref = { r => ( this . itemsRefs [ index ] = r ) }
283
+ testID = { `${ testID } -${ color } ` }
316
284
/>
317
285
) ;
318
286
}
@@ -334,49 +302,35 @@ export default class ColorPalette extends PureBaseComponent {
334
302
) ;
335
303
}
336
304
337
- renderScroll ( ) {
305
+ renderScrollableContent ( ) {
338
306
const { containerStyle, ...others } = this . props ;
339
- const { scrollable} = this . state ;
307
+ const { scrollable, contentWidth } = this . state ;
340
308
341
309
return (
342
- < ScrollView
343
- ref = { this . scrollView }
344
- horizontal
345
- showsHorizontalScrollIndicator = { false }
310
+ < ScrollBar
311
+ ref = { this . scrollBar }
346
312
style = { [ containerStyle , styles . scrollContainer ] }
347
313
scrollEnabled = { scrollable }
348
314
onContentSizeChange = { this . onContentSizeChange }
349
- onScroll = { this . onScroll }
315
+ height = { SCROLLABLE_HEIGHT }
316
+ containerProps = { { width : ! scrollable ? contentWidth : undefined } }
317
+ gradientHeight = { SCROLLABLE_HEIGHT - 12 }
350
318
>
351
319
{ this . renderPalette ( others , styles . scrollContent , this . colors ) }
352
- </ ScrollView >
320
+ </ ScrollBar >
353
321
) ;
354
322
}
355
323
356
- renderScrollableContent ( ) {
357
- const { scrollable} = this . state ;
358
-
359
- if ( scrollable ) {
360
- return (
361
- < View row >
362
- { this . renderScroll ( ) }
363
- { this . renderGradient ( ) }
364
- </ View >
365
- ) ;
366
- }
367
- return this . renderScroll ( ) ;
368
- }
369
-
370
324
renderPaginationContent ( ) {
371
325
const { containerStyle, loop, ...others } = this . props ;
372
326
const { currentPage} = this . state ;
373
327
const colorGroups = _ . chunk ( this . colors , this . itemsPerPage ) ;
374
328
375
329
return (
376
330
< View center style = { [ containerStyle , styles . paginationContainer ] } >
377
- < Carousel loop = { loop } onChangePage = { this . onChangePage } ref = { this . carousel } >
331
+ < Carousel migrate loop = { loop } onChangePage = { this . onChangePage } ref = { this . carousel } >
378
332
{ _ . map ( colorGroups , ( colorsPerPage , index ) => {
379
- return this . renderPalette ( others , { ...styles . page , width : Constants . screenWidth } , colorsPerPage , index ) ;
333
+ return this . renderPalette ( others , { ...styles . page , width : this . containerWidth } , colorsPerPage , index ) ;
380
334
} ) }
381
335
</ Carousel >
382
336
< PageControl
@@ -399,7 +353,7 @@ export default class ColorPalette extends PureBaseComponent {
399
353
const styles = StyleSheet . create ( {
400
354
paletteContainer : {
401
355
flexDirection : 'row' ,
402
- alignItems : 'flex-start ' ,
356
+ alignItems : 'center ' ,
403
357
paddingLeft : HORIZONTAL_PADDING ,
404
358
paddingVertical : VERTICAL_PADDING
405
359
} ,
0 commit comments