Skip to content

Commit c52b37f

Browse files
committed
Fix that selected index is out of bounds on scroll to start or end
1 parent f44249f commit c52b37f

1 file changed

Lines changed: 18 additions & 1 deletion

File tree

src/WheelPicker.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,14 @@ const WheelPicker: React.FC<Props> = ({
7575
const handleMomentumScrollEnd = (
7676
event: NativeSyntheticEvent<NativeScrollEvent>,
7777
) => {
78-
const offsetY = event.nativeEvent.contentOffset.y;
78+
// Due to list bounciness when scrolling to the start or the end of the list
79+
// the offset might be negative or over the last item.
80+
// We therefore clamp the offset to the supported range.
81+
const offsetY = Math.min(
82+
itemHeight * (options.length - 1),
83+
Math.max(event.nativeEvent.contentOffset.y, 0),
84+
);
85+
7986
let index = Math.floor(Math.floor(offsetY) / itemHeight);
8087
const last = Math.floor(offsetY % itemHeight);
8188
if (last > itemHeight / 2) index++;
@@ -85,6 +92,16 @@ const WheelPicker: React.FC<Props> = ({
8592
}
8693
};
8794

95+
useEffect(() => {
96+
if (selectedIndex < 0 || selectedIndex >= options.length) {
97+
throw new Error(
98+
`Selected index ${selectedIndex} is out of bounds [0, ${
99+
options.length - 1
100+
}]`,
101+
);
102+
}
103+
}, [selectedIndex, options]);
104+
88105
/**
89106
* If selectedIndex is changed from outside (not via onChange) we need to scroll to the specified index.
90107
* This ensures that what the user sees as selected in the picker always corresponds to the value state.

0 commit comments

Comments
 (0)