Handle press after scroll

This commit is contained in:
Dan Abramov
2023-10-17 16:39:54 +01:00
parent 262125cd88
commit caa55cba7a
+18 -6
View File
@@ -35,6 +35,8 @@ export function TabBar({
const {isDesktop, isTablet} = useWebMediaQueries() const {isDesktop, isTablet} = useWebMediaQueries()
const [layouts, setLayouts] = useState([]) const [layouts, setLayouts] = useState([])
const shouldSync = useSharedValue(true) const shouldSync = useSharedValue(true)
const scrollX = useSharedValue(0)
const didScroll = useSharedValue(false)
const indicatorStyle = useAnimatedStyle(() => { const indicatorStyle = useAnimatedStyle(() => {
if (layouts.length < items.length - 1 || layouts.some(l => l === undefined)) { if (layouts.length < items.length - 1 || layouts.some(l => l === undefined)) {
@@ -46,15 +48,19 @@ export function TabBar({
} }
}) })
const onPressItem = useCallback( const onPressItem = (index: number) => {
(index: number) => { if (!didScroll.value) {
scrollElRef.current.scrollTo({
x: scrollX.value + ((index - selectedPage) / (items.length - 1)) * (contentSize.value - SCREEN.width),
animated: true
})
}
didScroll.value = false
onSelect?.(index) onSelect?.(index)
if (index === selectedPage) { if (index === selectedPage) {
onPressSelected?.() onPressSelected?.()
} }
}, };
[onSelect, selectedPage, onPressSelected],
)
useAnimatedReaction(() => { useAnimatedReaction(() => {
return (dragProgress.value / (items.length - 1)) * (contentSize.value - SCREEN.width) return (dragProgress.value / (items.length - 1)) * (contentSize.value - SCREEN.width)
@@ -71,6 +77,7 @@ export function TabBar({
const nextX = (dragProgress.value / (items.length - 1)) * (contentSize.value - SCREEN.width) const nextX = (dragProgress.value / (items.length - 1)) * (contentSize.value - SCREEN.width)
scrollTo(scrollElRef, nextX, 0, true); scrollTo(scrollElRef, nextX, 0, true);
shouldSync.value = true shouldSync.value = true
didScroll.value = false
} }
}) })
@@ -99,7 +106,12 @@ export function TabBar({
}} }}
onScrollBeginDrag={e => { onScrollBeginDrag={e => {
shouldSync.value = false shouldSync.value = false
}}> didScroll.value = true
}}
onScroll={e => {
scrollX.value = Math.round(e.nativeEvent.contentOffset.x)
}}
scrollEventThrottle={16}>
{items.map((item, i) => { {items.map((item, i) => {
return ( return (
<PressableWithHover <PressableWithHover