diff options
author | Ansh Nanda <anshnanda10@gmail.com> | 2023-05-16 17:27:46 -0700 |
---|---|---|
committer | Ansh Nanda <anshnanda10@gmail.com> | 2023-05-16 17:27:46 -0700 |
commit | 139027ac5f843c65aae5ad824d049aae6dae9f79 (patch) | |
tree | 08ab64e42152c61a8e79fa8f50df8b1a8cb7066d /src/view/com/pager/TabBar.tsx | |
parent | 532bc88ecc233e0bd59d7b06927262fa1ed1ce1d (diff) | |
download | voidsky-139027ac5f843c65aae5ad824d049aae6dae9f79.tar.zst |
bad fix to the tab bar animation
Diffstat (limited to 'src/view/com/pager/TabBar.tsx')
-rw-r--r-- | src/view/com/pager/TabBar.tsx | 154 |
1 files changed, 81 insertions, 73 deletions
diff --git a/src/view/com/pager/TabBar.tsx b/src/view/com/pager/TabBar.tsx index 3a7a5583e..6ef9d74e3 100644 --- a/src/view/com/pager/TabBar.tsx +++ b/src/view/com/pager/TabBar.tsx @@ -1,10 +1,9 @@ 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' import {isDesktopWeb} from 'platform/detection' -import {ScrollView} from 'react-native-gesture-handler' interface Layout { x: number @@ -35,59 +34,71 @@ export function TabBar({ onPressSelected, }: TabBarProps) { const pal = usePalette('default') - // const [itemLayouts, setItemLayouts] = useState<Layout[]>( - // items.map(() => ({x: 0, width: 0})), - // ) + const [itemLayouts, setItemLayouts] = useState<Layout[]>( + items.map(() => ({x: 0, width: 0})), + ) const itemRefs = useMemo( () => Array.from({length: items.length}).map(() => createRef<View>()), [items.length], ) - // const panX = Animated.add(position, offset) + 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 = () => { - // const promises = [] - // for (let i = 0; i < items.length; i++) { - // promises.push( - // new Promise<Layout>(resolve => { - // if (!containerRef.current || !itemRefs[i].current) { - // return resolve({x: 0, width: 0}) - // } + const onLayout = () => { + const promises = [] + for (let i = 0; i < items.length; i++) { + promises.push( + new Promise<Layout>(resolve => { + if (!containerRef.current || !itemRefs[i].current) { + return resolve({x: 0, width: 0}) + } - // itemRefs[i].current?.measureLayout( - // containerRef.current, - // (x: number, _y: number, width: number) => { - // resolve({x, width}) - // }, - // ) - // }), - // ) - // } - // Promise.all(promises).then((layouts: Layout[]) => { - // setItemLayouts(layouts) - // }) - // } + itemRefs[i].current?.measureLayout( + containerRef.current, + (x: number, _y: number, width: number) => { + resolve({x, width}) + }, + ) + }), + ) + } + Promise.all(promises).then((layouts: Layout[]) => { + setItemLayouts(layouts) + }) + } const onPressItem = (index: number) => { onSelect?.(index) @@ -100,31 +111,33 @@ export function TabBar({ <View testID={testID} style={[pal.view, styles.outer]} - // onLayout={onLayout} + onLayout={onLayout} ref={containerRef}> - <Animated.View style={[styles.indicator]} /> - <ScrollView horizontal={true} showsHorizontalScrollIndicator={false}> + <Animated.View style={[styles.indicator, indicatorStyle]} /> + <ScrollView + horizontal={true} + showsHorizontalScrollIndicator={false} + onScroll={({nativeEvent}) => { + setScrollX(nativeEvent.contentOffset.x) + }}> {items.map((item, i) => { const selected = i === selectedPage return ( - <Animated.View key={item} style={selected ? styles.active : []}> - <PressableWithHover - ref={itemRefs[i]} - 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> - </Animated.View> + <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> @@ -155,7 +168,6 @@ const styles = isDesktopWeb height: 3, zIndex: 1, }, - active: {}, }) : StyleSheet.create({ outer: { @@ -178,8 +190,4 @@ const styles = isDesktopWeb width: 1, height: 3, }, - active: { - borderBottomColor: 'blue', - borderBottomWidth: 3, - }, }) |