diff options
Diffstat (limited to 'src/view/com/util/TabBar.tsx')
-rw-r--r-- | src/view/com/util/TabBar.tsx | 161 |
1 files changed, 0 insertions, 161 deletions
diff --git a/src/view/com/util/TabBar.tsx b/src/view/com/util/TabBar.tsx deleted file mode 100644 index 545a6b742..000000000 --- a/src/view/com/util/TabBar.tsx +++ /dev/null @@ -1,161 +0,0 @@ -import React, {createRef, useState, useMemo} from 'react' -import { - Animated, - StyleSheet, - TouchableWithoutFeedback, - View, -} from 'react-native' -import {Text} from './text/Text' -import {usePalette} from 'lib/hooks/usePalette' -import {isDesktopWeb} from 'platform/detection' - -interface Layout { - x: number - width: number -} - -export interface TabBarProps { - selectedPage: number - items: string[] - position: Animated.Value - offset: Animated.Value - indicatorPosition?: 'top' | 'bottom' - indicatorColor?: string - onSelect?: (index: number) => void - onPressSelected?: () => void -} - -export function TabBar({ - selectedPage, - items, - position, - offset, - indicatorPosition = 'bottom', - indicatorColor, - onSelect, - onPressSelected, -}: TabBarProps) { - const pal = usePalette('default') - 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 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 onLayout = () => { - const promises = [] - for (let i = 0; i < items.length; i++) { - promises.push( - new Promise<Layout>(resolve => { - itemRefs[i].current?.measure( - (x: number, _y: number, width: number) => { - resolve({x, width}) - }, - ) - }), - ) - } - Promise.all(promises).then((layouts: Layout[]) => { - setItemLayouts(layouts) - }) - } - - const onPressItem = (index: number) => { - onSelect?.(index) - if (index === selectedPage) { - onPressSelected?.() - } - } - - return ( - <View style={[pal.view, styles.outer]} onLayout={onLayout}> - <Animated.View style={[styles.indicator, indicatorStyle]} /> - {items.map((item, i) => { - const selected = i === selectedPage - return ( - <TouchableWithoutFeedback key={i} onPress={() => onPressItem(i)}> - <View - style={ - indicatorPosition === 'top' ? styles.itemTop : styles.itemBottom - } - ref={itemRefs[i]}> - <Text type="xl-bold" style={selected ? pal.text : pal.textLight}> - {item} - </Text> - </View> - </TouchableWithoutFeedback> - ) - })} - </View> - ) -} - -const styles = isDesktopWeb - ? StyleSheet.create({ - outer: { - flexDirection: 'row', - paddingHorizontal: 18, - }, - itemTop: { - paddingTop: 16, - paddingBottom: 14, - marginRight: 24, - }, - itemBottom: { - paddingTop: 14, - paddingBottom: 16, - marginRight: 24, - }, - indicator: { - position: 'absolute', - left: 0, - width: 1, - height: 3, - }, - }) - : StyleSheet.create({ - outer: { - flexDirection: 'row', - paddingHorizontal: 14, - }, - itemTop: { - paddingTop: 10, - paddingBottom: 10, - marginRight: 24, - }, - itemBottom: { - paddingTop: 8, - paddingBottom: 12, - marginRight: 24, - }, - indicator: { - position: 'absolute', - left: 0, - width: 1, - height: 3, - }, - }) |