Skip to content

Commit e6a3226

Browse files
committed
fix(mobile): scroll selected section tabs into view
1 parent 860f3d2 commit e6a3226

1 file changed

Lines changed: 7 additions & 1 deletion

File tree

‎apps/mobile/src/components/ui/Tabs.tsx‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { GlassView } from "expo-glass-effect";
2-
import { useState } from "react";
2+
import { useEffect, useRef, useState, type ComponentRef } from "react";
33
import { Pressable, ScrollView, View } from "react-native";
44
import Animated, { useAnimatedStyle, useReducedMotion, withTiming } from "react-native-reanimated";
55
import { withUniwind } from "uniwind";
@@ -25,8 +25,13 @@ export interface TabsProps<Value extends string> {
2525
export function Tabs<Value extends string>(props: TabsProps<Value>) {
2626
const { themeAppearance } = useAppearancePreferences();
2727
const reduceMotion = useReducedMotion();
28+
const scrollView = useRef<ComponentRef<typeof ScrollView>>(null);
2829
const [frames, setFrames] = useState<Partial<Record<Value, { x: number; width: number }>>>({});
2930
const frame = frames[props.selected];
31+
// oxlint-disable-next-line t3code/no-unreasoned-state-sync -- keeps the selected tab visible in the native scroll viewport
32+
useEffect(() => {
33+
if (frame) scrollView.current?.scrollTo({ x: frame.x, animated: false });
34+
}, [frame]);
3035
const duration = reduceMotion ? 0 : 220;
3136
const indicatorStyle = useAnimatedStyle(() => ({
3237
width: withTiming(frame?.width ?? 0, { duration }),
@@ -35,6 +40,7 @@ export function Tabs<Value extends string>(props: TabsProps<Value>) {
3540

3641
return (
3742
<ScrollView
43+
ref={scrollView}
3844
horizontal
3945
showsHorizontalScrollIndicator={false}
4046
className={cn("grow-0", props.className)}

0 commit comments

Comments
 (0)