1
1
import _ from 'lodash' ;
2
2
import memoize from 'memoize-one' ;
3
3
import React , { PureComponent } from 'react' ;
4
- import { StyleSheet , UIManager , findNodeHandle , StyleProp , ViewStyle } from 'react-native' ;
4
+ import { StyleSheet , StyleProp , ViewStyle } from 'react-native' ;
5
5
import { Colors } from '../../style' ;
6
6
import { Constants } from '../../commons/new' ;
7
7
import View from '../view' ;
8
8
import Carousel from '../carousel' ;
9
9
import ScrollBar from '../scrollBar' ;
10
10
import PageControl from '../pageControl' ;
11
- import ColorSwatch , { SWATCH_SIZE } from '../colorSwatch' ;
12
-
11
+ import ColorSwatch , { SWATCH_SIZE , SWATCH_MARGIN } from '../colorSwatch' ;
13
12
14
13
interface Props {
15
14
/**
@@ -58,10 +57,10 @@ interface Props {
58
57
export type ColorPaletteProps = Props ;
59
58
60
59
interface State {
61
- currentPage : number ,
62
- scrollable : boolean ,
63
- orientation ?: string ,
64
- contentWidth ?: number
60
+ currentPage : number ;
61
+ scrollable : boolean ;
62
+ orientation ?: string ;
63
+ contentWidth ?: number ;
65
64
}
66
65
67
66
const VERTICAL_PADDING = 16 ;
@@ -100,7 +99,7 @@ class ColorPalette extends PureComponent<Props, State> {
100
99
101
100
carousel : React . RefObject < typeof Carousel > = React . createRef ( ) ;
102
101
scrollBar : React . RefObject < any > = React . createRef ( ) ;
103
- itemsRefs ?: React . RefObject < typeof ColorSwatch > [ ] = undefined ;
102
+ itemsRefs ?: any = React . createRef ( ) ;
104
103
selectedColorIndex ?: number = undefined ;
105
104
selectedPage ?: number = undefined ;
106
105
currentColorsCount ?: number = undefined ;
@@ -113,6 +112,18 @@ class ColorPalette extends PureComponent<Props, State> {
113
112
114
113
componentDidMount ( ) {
115
114
this . dimensionsChangeListener = Constants . addDimensionsEventListener ( this . onOrientationChanged ) ;
115
+ _ . times ( this . props . colors . length , i => {
116
+ this . itemsRefs . current [ i ] = React . createRef ( ) ;
117
+ } ) ;
118
+ this . scrollToSelected ( ) ;
119
+ }
120
+
121
+ componentDidUpdate ( prevProps : Props ) {
122
+ if ( this . props . colors !== prevProps . colors ) {
123
+ const newIndex = this . itemsRefs . current . length ;
124
+ this . itemsRefs . current [ newIndex ] = React . createRef ( ) ;
125
+ this . scrollToSelected ( ) ;
126
+ }
116
127
}
117
128
118
129
componentWillUnmount ( ) {
@@ -127,7 +138,7 @@ class ColorPalette extends PureComponent<Props, State> {
127
138
} ;
128
139
129
140
initLocalVariables ( ) {
130
- this . itemsRefs = undefined ;
141
+ this . itemsRefs . current = [ ] ;
131
142
this . selectedColorIndex = undefined ;
132
143
this . selectedPage = undefined ;
133
144
this . currentColorsCount = this . colors . length ;
@@ -208,38 +219,36 @@ class ColorPalette extends PureComponent<Props, State> {
208
219
return ( margin - 0.001 ) / 2 ;
209
220
}
210
221
211
- scrollToSelected ( ) {
222
+ scrollToSelected = ( ) => setTimeout ( ( ) => {
212
223
const { scrollable, currentPage} = this . state ;
213
224
214
- if ( scrollable && this . selectedColorIndex !== undefined && this . itemsRefs ) {
215
- const childRef = this . itemsRefs [ this . selectedColorIndex ] ;
225
+ if ( scrollable && this . selectedColorIndex !== undefined && this . itemsRefs . current ) {
226
+ // The this.selectedColorIndex layout doesn't update on time
227
+ // so we use this.selectedColorIndex - 1 and add an offset of 1 Swatch
228
+ const childRef : any = this . itemsRefs . current [ this . selectedColorIndex - 1 ] ?. current ;
216
229
217
230
if ( childRef ) {
218
- const handle = findNodeHandle ( childRef . current ) ;
219
- if ( handle ) {
220
- //@ts -ignore
221
- UIManager . measureLayoutRelativeToParent ( handle , e => {
222
- console . warn ( e ) ;
223
- } ,
224
- ( x : number , _y : number , w : number , _h : number ) => {
225
- if ( x + w > this . containerWidth ) {
226
- this . scrollBar ?. current ?. scrollTo ( {
227
- x : x + w + HORIZONTAL_PADDING - this . containerWidth ,
228
- y : 0 ,
229
- animated : false
230
- } ) ;
231
- }
231
+ const childLayout = childRef . getLayout ( ) ;
232
+ const leftMargins = this . getHorizontalMargins ( this . selectedColorIndex ) . marginLeft ;
233
+ const childX = childLayout . x + childLayout . width + SWATCH_MARGIN + leftMargins + SWATCH_SIZE ;
234
+ if ( childX > this . containerWidth ) {
235
+ this . scrollBar ?. current ?. scrollTo ( {
236
+ x : childX + HORIZONTAL_PADDING - this . containerWidth ,
237
+ y : 0 ,
238
+ animated : false
232
239
} ) ;
233
240
}
241
+ } else if ( this . usePagination ) {
242
+ this . carousel ?. current ?. goToPage ( this . selectedPage || currentPage , false ) ;
234
243
}
235
- } else if ( this . usePagination ) {
236
- this . carousel ?. current ?. goToPage ( this . selectedPage || currentPage , false ) ;
237
244
}
238
- }
245
+ } , 100 )
239
246
240
247
onContentSizeChange = ( contentWidth : number ) => {
241
248
this . setState ( {
242
- scrollable : contentWidth > this . containerWidth , contentWidth} ) ;
249
+ scrollable : contentWidth > this . containerWidth ,
250
+ contentWidth
251
+ } ) ;
243
252
} ;
244
253
245
254
onChangePage = ( index : number ) => {
@@ -250,12 +259,6 @@ class ColorPalette extends PureComponent<Props, State> {
250
259
this . props . onValueChange ?.( value , options ) ;
251
260
} ;
252
261
253
- onLayout = ( ) => {
254
- setTimeout ( ( ) => {
255
- this . scrollToSelected ( ) ;
256
- } , 0 ) ;
257
- } ;
258
-
259
262
getHorizontalMargins = ( index : number ) => {
260
263
const isFirst = index === 0 ;
261
264
const isOnLeft = isFirst || index % this . itemsPerRow === 0 ;
@@ -292,12 +295,6 @@ class ColorPalette extends PureComponent<Props, State> {
292
295
}
293
296
} ;
294
297
295
- addRefByIndex = ( index : number , ref ?: any ) => {
296
- if ( this . itemsRefs && ref ) {
297
- this . itemsRefs [ index ] = ref ;
298
- }
299
- }
300
-
301
298
renderColorSwatch ( color : string , index : number ) {
302
299
const { animatedIndex, testID} = this . props ;
303
300
@@ -311,18 +308,17 @@ class ColorPalette extends PureComponent<Props, State> {
311
308
selected = { this . value === color }
312
309
animated = { index === animatedIndex }
313
310
onPress = { this . onValueChange }
314
- ref = { r => this . addRefByIndex ( index , r ) }
311
+ ref = { this . itemsRefs . current [ index ] }
315
312
testID = { `${ testID } -${ color } ` }
316
313
/>
317
314
) ;
318
315
}
319
316
320
317
renderPalette ( props : Props , contentStyle : StyleProp < ViewStyle > , colors : string [ ] , pageIndex : number ) {
321
318
const { style, ...others } = props ;
322
- this . itemsRefs = [ ] ;
323
319
324
320
return (
325
- < View key = { pageIndex } { ...others } style = { [ styles . paletteContainer , contentStyle , style ] } onLayout = { this . onLayout } >
321
+ < View key = { pageIndex } { ...others } style = { [ styles . paletteContainer , contentStyle , style ] } >
326
322
{ _ . map ( colors , ( color , i ) => {
327
323
if ( color === this . value ) {
328
324
this . selectedColorIndex = i ;
0 commit comments