Skip to content

Commit df6b5ff

Browse files
committed
Adds support for react-native-web.
Snaps to item automatically on react-native-web with usage of cooldown.
1 parent 85c4fb2 commit df6b5ff

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

src/WheelPicker.tsx

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
ViewProps,
1111
FlatListProps,
1212
FlatList,
13+
Platform
1314
} from 'react-native';
1415
import styles from './WheelPicker.styles';
1516
import WheelPickerItem from './WheelPickerItem';
@@ -50,7 +51,10 @@ const WheelPicker: React.FC<Props> = ({
5051
const flatListRef = useRef<FlatList>(null);
5152
const [scrollY] = useState(new Animated.Value(0));
5253

54+
const lastScrollTimestamp = useRef(new Date().getTime());
55+
5356
const containerHeight = (1 + visibleRest * 2) * itemHeight;
57+
const [scrollIndex, setScrollIndex] = useState(selectedIndex);
5458
const paddedOptions = useMemo(() => {
5559
const array: (string | null)[] = [...options];
5660
for (let i = 0; i < visibleRest; i++) {
@@ -94,6 +98,42 @@ const WheelPicker: React.FC<Props> = ({
9498
});
9599
}, [selectedIndex]);
96100

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+
97137
return (
98138
<View
99139
style={[styles.container, { height: containerHeight }, containerStyle]}
@@ -116,7 +156,11 @@ const WheelPicker: React.FC<Props> = ({
116156
showsVerticalScrollIndicator={false}
117157
onScroll={Animated.event(
118158
[{ nativeEvent: { contentOffset: { y: scrollY } } }],
119-
{ useNativeDriver: true },
159+
{
160+
useNativeDriver: true,
161+
listener: (event: NativeSyntheticEvent<any>
162+
) => handleScroll(event),
163+
},
120164
)}
121165
onMomentumScrollEnd={handleMomentumScrollEnd}
122166
snapToOffsets={offsets}
@@ -148,4 +192,4 @@ const WheelPicker: React.FC<Props> = ({
148192
);
149193
};
150194

151-
export default WheelPicker;
195+
export default WheelPicker;

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
import WheelPicker from './WheelPicker';
22

3-
export default WheelPicker;
3+
export default WheelPicker;

0 commit comments

Comments
 (0)