diff options
Diffstat (limited to 'src/view/com/pager/TabBar.tsx')
-rw-r--r-- | src/view/com/pager/TabBar.tsx | 99 |
1 files changed, 59 insertions, 40 deletions
diff --git a/src/view/com/pager/TabBar.tsx b/src/view/com/pager/TabBar.tsx index a0b72a93f..9294b6026 100644 --- a/src/view/com/pager/TabBar.tsx +++ b/src/view/com/pager/TabBar.tsx @@ -1,5 +1,5 @@ import React, {createRef, useState, useMemo, useRef} from 'react' -import {Animated, StyleSheet, View} from 'react-native' +import {Animated, StyleSheet, View, ScrollView} from 'react-native' import {Text} from '../util/text/Text' import {PressableWithHover} from '../util/PressableWithHover' import {usePalette} from 'lib/hooks/usePalette' @@ -43,27 +43,39 @@ export function TabBar({ ) const panX = Animated.add(position, offset) const containerRef = useRef<View>(null) + const [scrollX, setScrollX] = useState(0) - const indicatorStyle = { - backgroundColor: indicatorColor || pal.colors.link, - bottom: - indicatorPosition === 'bottom' ? (isDesktopWeb ? 0 : -1) : undefined, - top: indicatorPosition === 'top' ? (isDesktopWeb ? 0 : -1) : undefined, - transform: [ - { - translateX: panX.interpolate({ - inputRange: items.map((_item, i) => i), - outputRange: itemLayouts.map(l => l.x + l.width / 2), - }), - }, - { - scaleX: panX.interpolate({ - inputRange: items.map((_item, i) => i), - outputRange: itemLayouts.map(l => l.width), - }), - }, + const indicatorStyle = useMemo( + () => ({ + backgroundColor: indicatorColor || pal.colors.link, + bottom: + indicatorPosition === 'bottom' ? (isDesktopWeb ? 0 : -1) : undefined, + top: indicatorPosition === 'top' ? (isDesktopWeb ? 0 : -1) : undefined, + transform: [ + { + translateX: panX.interpolate({ + inputRange: items.map((_item, i) => i), + outputRange: itemLayouts.map(l => l.x + l.width / 2 - scrollX), + }), + }, + { + scaleX: panX.interpolate({ + inputRange: items.map((_item, i) => i), + outputRange: itemLayouts.map(l => l.width), + }), + }, + ], + }), + [ + indicatorColor, + indicatorPosition, + itemLayouts, + items, + panX, + pal.colors.link, + scrollX, ], - } + ) const onLayout = React.useCallback(() => { const promises = [] @@ -105,26 +117,33 @@ export function TabBar({ onLayout={onLayout} ref={containerRef}> <Animated.View style={[styles.indicator, indicatorStyle]} /> - {items.map((item, i) => { - const selected = i === selectedPage - return ( - <PressableWithHover - ref={itemRefs[i]} - key={item} - style={ - indicatorPosition === 'top' ? styles.itemTop : styles.itemBottom - } - hoverStyle={pal.viewLight} - onPress={() => onPressItem(i)}> - <Text - type="xl-bold" - testID={testID ? `${testID}-${item}` : undefined} - style={selected ? pal.text : pal.textLight}> - {item} - </Text> - </PressableWithHover> - ) - })} + <ScrollView + horizontal={true} + showsHorizontalScrollIndicator={false} + onScroll={({nativeEvent}) => { + setScrollX(nativeEvent.contentOffset.x) + }}> + {items.map((item, i) => { + const selected = i === selectedPage + return ( + <PressableWithHover + ref={itemRefs[i]} + key={item} + style={ + indicatorPosition === 'top' ? styles.itemTop : styles.itemBottom + } + hoverStyle={pal.viewLight} + onPress={() => onPressItem(i)}> + <Text + type="xl-bold" + testID={testID ? `${testID}-${item}` : undefined} + style={selected ? pal.text : pal.textLight}> + {item} + </Text> + </PressableWithHover> + ) + })} + </ScrollView> </View> ) } |