@@ -13,6 +13,12 @@ import Text, {TextProps} from '../../components/text';
1313
1414const AnimatedFlatList = Animated . createAnimatedComponent ( FlatList ) ;
1515
16+ enum WheelPickerAlign {
17+ CENTER = 'center' ,
18+ RIGHT = 'right' ,
19+ LEFT = 'left'
20+ }
21+
1622export interface WheelPickerProps {
1723 /**
1824 * Initial value (doesn't work with selectedValue)
@@ -72,10 +78,14 @@ export interface WheelPickerProps {
7278 * Support passing items as children props
7379 */
7480 children ?: JSX . Element | JSX . Element [ ] ;
81+ /**
82+ * Align the content to center, right ot left (default: center)
83+ */
84+ align ?: WheelPickerAlign ;
7585 testID ?: string ;
7686}
7787
78- const WheelPicker = React . memo ( ( {
88+ const WheelPicker = ( {
7989 items : propItems ,
8090 itemHeight = 44 ,
8191 numberOfVisibleRows = 5 ,
@@ -86,6 +96,7 @@ const WheelPicker = React.memo(({
8696 labelStyle,
8797 labelProps,
8898 onChange,
99+ align,
89100 style,
90101 children,
91102 initialValue,
@@ -115,6 +126,7 @@ const WheelPicker = React.memo(({
115126
116127 const prevIndex = useRef ( currentIndex ) ;
117128 const [ scrollOffset , setScrollOffset ] = useState ( currentIndex * itemHeight ) ;
129+ const [ flatListWidth , setFlatListWidth ] = useState ( 0 ) ;
118130 const keyExtractor = useCallback ( ( item : ItemProps , index : number ) => `${ item } .${ index } ` , [ ] ) ;
119131
120132 /* This effect enforce the index to be controlled by selectedValue passed by the user */
@@ -168,6 +180,14 @@ const WheelPicker = React.memo(({
168180 } ,
169181 [ onChange ] ) ;
170182
183+ const alignmentStyle = useMemo ( ( ) =>
184+ align === WheelPickerAlign . RIGHT
185+ ? { alignSelf : 'flex-end' }
186+ : align === WheelPickerAlign . LEFT
187+ ? { alignSelf : 'flex-start' }
188+ : { alignSelf : 'center' } ,
189+ [ align ] ) ;
190+
171191 const renderItem = useCallback ( ( { item, index} ) => {
172192 return (
173193 < Item
@@ -178,6 +198,9 @@ const WheelPicker = React.memo(({
178198 inactiveColor = { inactiveTextColor }
179199 style = { textStyle }
180200 { ...item }
201+ fakeLabel = { label }
202+ fakeLabelStyle = { labelStyle }
203+ fakeLabelProps = { labelProps }
181204 centerH = { ! label }
182205 onSelect = { selectItem }
183206 testID = { `${ testID } .item_${ index } ` }
@@ -194,15 +217,22 @@ const WheelPicker = React.memo(({
194217 ) ;
195218 } , [ ] ) ;
196219
220+ const labelContainerStyle = useMemo ( ( ) => {
221+ return [ { position : 'absolute' , top : 0 , bottom : 0 } , alignmentStyle ] ;
222+ } , [ alignmentStyle ] ) ;
223+
197224 const labelContainer = useMemo ( ( ) => {
198225 return (
199- < View centerV >
200- < Text marginL-s2 text80M { ...labelProps } color = { activeTextColor } style = { labelStyle } >
201- { label }
202- </ Text >
226+ // @ts -expect-error
227+ < View style = { labelContainerStyle } width = { flatListWidth } pointerEvents = "none" >
228+ < View style = { styles . label } centerV pointerEvents = "none" >
229+ < Text marginL-s2 marginR-s5 text80M { ...labelProps } color = { activeTextColor } style = { labelStyle } >
230+ { label }
231+ </ Text >
232+ </ View >
203233 </ View >
204234 ) ;
205- } , [ ] ) ;
235+ } , [ flatListWidth , labelContainerStyle , label , labelProps , activeTextColor , labelStyle ] ) ;
206236
207237 const fader = useMemo ( ( ) => ( position : FaderPosition ) => {
208238 return < Fader visible position = { position } size = { 60 } /> ;
@@ -214,14 +244,23 @@ const WheelPicker = React.memo(({
214244 } ,
215245 [ itemHeight ] ) ;
216246
247+ const updateFlatListWidth = useCallback ( ( width : number ) => {
248+ setFlatListWidth ( width ) ;
249+ } , [ ] ) ;
250+
217251 const contentContainerStyle = useMemo ( ( ) => {
218- return { paddingVertical : height / 2 - itemHeight / 2 } ;
219- } , [ height , itemHeight ] ) ;
252+ return [
253+ {
254+ paddingVertical : height / 2 - itemHeight / 2
255+ } ,
256+ alignmentStyle
257+ ] ;
258+ } , [ height , itemHeight , alignmentStyle ] ) ;
220259
221260 return (
222261 < View testID = { testID } bg-white style = { style } >
223- < View row marginH-s5 centerH >
224- < View >
262+ < View row centerH >
263+ < View flexG >
225264 < AnimatedFlatList
226265 testID = { `${ testID } .list` }
227266 height = { height }
@@ -235,23 +274,26 @@ const WheelPicker = React.memo(({
235274 onLayout = { scrollToPassedIndex }
236275 // @ts -ignore
237276 ref = { scrollView }
277+ // @ts -expect-error
238278 contentContainerStyle = { contentContainerStyle }
239279 snapToInterval = { itemHeight }
240280 decelerationRate = { Constants . isAndroid ? 0.98 : 'normal' }
241281 renderItem = { renderItem }
242282 getItemLayout = { getItemLayout }
243283 initialScrollIndex = { currentIndex }
284+ onContentSizeChange = { updateFlatListWidth }
244285 />
245286 </ View >
246- { label && labelContainer }
247287 </ View >
288+ { label && labelContainer }
248289 { fader ( FaderPosition . BOTTOM ) }
249290 { fader ( FaderPosition . TOP ) }
250291 { separators }
251292 </ View >
252293 ) ;
253- } ) ;
294+ } ;
254295
296+ WheelPicker . alignments = WheelPickerAlign ;
255297export default WheelPicker ;
256298
257299const styles = StyleSheet . create ( {
@@ -260,5 +302,11 @@ const styles = StyleSheet.create({
260302 borderBottomWidth : 1 ,
261303 height : Spacings . s9 ,
262304 borderColor : Colors . grey60
305+ } ,
306+ label : {
307+ position : 'absolute' ,
308+ right : 0 ,
309+ top : 0 ,
310+ bottom : 0
263311 }
264312} ) ;
0 commit comments