about summary refs log tree commit diff
path: root/src/view/com/pager/TabBar.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/view/com/pager/TabBar.tsx')
-rw-r--r--src/view/com/pager/TabBar.tsx99
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>
   )
 }