Skip to content

Commit 6e18de8

Browse files
committed
Sets scroll index using handle scroll event
Update WheelPicker.tsx Update WheelPicker.tsx Adds type Update WheelPicker.tsx Update WheelPicker.tsx Update WheelPicker.tsx Update WheelPicker.tsx Adds ability to snap to index. Update package.json Update package.json Update WheelPicker.tsx Update WheelPicker.tsx Update package.json Update WheelPicker.tsx Ensures extra calculations only run for react-native for web. Lints code. Updates event type to use Animated event. Modifies event and flat list ref types. Allows Typsecript to compile without errors Adds support for react-native-web.
1 parent 85c4fb2 commit 6e18de8

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)