@@ -10,6 +10,7 @@ import {
10
10
ViewProps ,
11
11
FlatListProps ,
12
12
FlatList ,
13
+ Platform
13
14
} from 'react-native' ;
14
15
import styles from './WheelPicker.styles' ;
15
16
import WheelPickerItem from './WheelPickerItem' ;
@@ -50,7 +51,10 @@ const WheelPicker: React.FC<Props> = ({
50
51
const flatListRef = useRef < FlatList > ( null ) ;
51
52
const [ scrollY ] = useState ( new Animated . Value ( 0 ) ) ;
52
53
54
+ const lastScrollTimestamp = useRef ( new Date ( ) . getTime ( ) ) ;
55
+
53
56
const containerHeight = ( 1 + visibleRest * 2 ) * itemHeight ;
57
+ const [ scrollIndex , setScrollIndex ] = useState ( selectedIndex ) ;
54
58
const paddedOptions = useMemo ( ( ) => {
55
59
const array : ( string | null ) [ ] = [ ...options ] ;
56
60
for ( let i = 0 ; i < visibleRest ; i ++ ) {
@@ -94,6 +98,42 @@ const WheelPicker: React.FC<Props> = ({
94
98
} ) ;
95
99
} , [ selectedIndex ] ) ;
96
100
101
+
102
+ useEffect ( ( ) => {
103
+ if ( Platform . OS === 'web' ) {
104
+ const SCROLL_COOLDOWN_MILLISECONDS = 100 ;
105
+ const SCROLL_DID_STOP_TIMEOUT = 500 ;
106
+ const intervalID = setInterval ( ( ) => {
107
+ const time = new Date ( ) . getTime ( ) ;
108
+ const difference = time - lastScrollTimestamp . current ;
109
+ if ( difference > SCROLL_DID_STOP_TIMEOUT ) {
110
+ flatListRef . current ?. scrollToIndex ( {
111
+ index : scrollIndex ,
112
+ animated : true ,
113
+ } ) ;
114
+ }
115
+ } , SCROLL_COOLDOWN_MILLISECONDS ) ;
116
+ return ( ) => {
117
+ clearInterval ( intervalID ) ;
118
+ } ;
119
+ }
120
+ } , [ scrollIndex ] ) ;
121
+
122
+ useEffect ( ( ) => {
123
+ if ( Platform . OS === 'web' ) {
124
+ onChange ( scrollIndex ) ;
125
+ }
126
+ } , [ scrollIndex , onChange ] ) ;
127
+
128
+ const handleScroll = ( event : NativeSyntheticEvent < any > ) => {
129
+ if ( Platform . OS === 'web' ) {
130
+ const positionY = event . nativeEvent . contentOffset . y ;
131
+ const index = Math . round ( positionY / itemHeight ) ;
132
+ setScrollIndex ( index ) ;
133
+ lastScrollTimestamp . current = new Date ( ) . getTime ( ) ;
134
+ }
135
+ } ;
136
+
97
137
return (
98
138
< View
99
139
style = { [ styles . container , { height : containerHeight } , containerStyle ] }
@@ -116,7 +156,11 @@ const WheelPicker: React.FC<Props> = ({
116
156
showsVerticalScrollIndicator = { false }
117
157
onScroll = { Animated . event (
118
158
[ { nativeEvent : { contentOffset : { y : scrollY } } } ] ,
119
- { useNativeDriver : true } ,
159
+ {
160
+ useNativeDriver : true ,
161
+ listener : ( event : NativeSyntheticEvent < any >
162
+ ) => handleScroll ( event ) ,
163
+ } ,
120
164
) }
121
165
onMomentumScrollEnd = { handleMomentumScrollEnd }
122
166
snapToOffsets = { offsets }
@@ -148,4 +192,4 @@ const WheelPicker: React.FC<Props> = ({
148
192
) ;
149
193
} ;
150
194
151
- export default WheelPicker ;
195
+ export default WheelPicker ;
0 commit comments