Files
sofa/apps/native/src/components/navigation/native-tab-bar.android.tsx
T
jake ed3fd54896 refactor(native): replace hardcoded pixel font sizes with semantic Tailwind classes and add ScaledIcon
Replace all `text-[Npx]` arbitrary size utilities with their nearest semantic Tailwind equivalents (`text-sm`, `text-base`, `text-xs`, `text-3xl`, etc.) across every component so text participates properly in the system font-scale pipeline.

Introduce a `ScaledIcon` component backed by a `useScaledSize` hook that multiplies a base icon size by the current font-scale factor, then replace every bare Tabler icon with `ScaledIcon` so icons grow and shrink in proportion with the surrounding text.

- Add `maxFontSizeMultiplier={1.0}` to badge and label text that must not reflow at large accessibility sizes (the "Admin" pill, type/rating chips, provider name labels, and the TMDB attribution line).
2026-03-16 12:46:55 -04:00

67 lines
2.2 KiB
TypeScript

import {
NativeTabs,
type NativeTabsProps,
} from "expo-router/unstable-native-tabs";
import { useMemo } from "react";
import { useCSSVariable, useResolveClassNames } from "uniwind";
import * as Haptics from "@/utils/haptics";
export function NativeTabBar() {
const primaryColor = useCSSVariable("--color-primary") as string;
const mutedFgColor = useCSSVariable("--color-muted-foreground") as string;
const surfaceColor = useCSSVariable("--color-card") as string;
const rippleColor = useCSSVariable("--color-secondary") as string;
const screenListeners = useMemo<NativeTabsProps["screenListeners"]>(
() => ({
tabPress: () => {
void Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
},
}),
[],
);
const labelTextStyle = useResolveClassNames("font-medium font-sans text-xs");
return (
<NativeTabs
backgroundColor={surfaceColor}
disableIndicator
iconColor={{
default: mutedFgColor,
selected: primaryColor,
}}
indicatorColor="transparent"
labelStyle={{
default: [
labelTextStyle as Record<string, unknown>,
{ color: mutedFgColor },
],
selected: [
labelTextStyle as Record<string, unknown>,
{ color: primaryColor },
],
}}
labelVisibilityMode="labeled"
rippleColor={rippleColor}
screenListeners={screenListeners}
>
<NativeTabs.Trigger name="(home)">
<NativeTabs.Trigger.Label>Home</NativeTabs.Trigger.Label>
<NativeTabs.Trigger.Icon md="home" />
</NativeTabs.Trigger>
<NativeTabs.Trigger name="(explore)">
<NativeTabs.Trigger.Label>Explore</NativeTabs.Trigger.Label>
<NativeTabs.Trigger.Icon md="explore" />
</NativeTabs.Trigger>
<NativeTabs.Trigger name="(search)">
<NativeTabs.Trigger.Label>Search</NativeTabs.Trigger.Label>
<NativeTabs.Trigger.Icon md="search" />
</NativeTabs.Trigger>
<NativeTabs.Trigger name="(settings)">
<NativeTabs.Trigger.Label>Settings</NativeTabs.Trigger.Label>
<NativeTabs.Trigger.Icon md="settings" />
</NativeTabs.Trigger>
</NativeTabs>
);
}