import { Platform, useWindowDimensions } from "react-native"; import { useSafeAreaFrame, useSafeAreaInsets } from "react-native-safe-area-context"; import { spacing } from "@/constants/theme"; /** Standard UITabBar content height (home indicator is separate). */ const IOS_TAB_BAR_HEIGHT = 49; /** Trim extra inset so scroll content sits closer to the tab bar. */ const TAB_BAR_PADDING_TRIM = spacing.lg; /** * Pixels between the bottom of the safe-area layout frame and the window bottom. */ function useBelowLayoutFrame(): number { const { height: windowHeight } = useWindowDimensions(); const frame = useSafeAreaFrame(); return Math.max(0, windowHeight - frame.y - frame.height); } /** Native tab bar height excluding the home-indicator inset. */ export function useNativeTabBarHeight(): number { const belowLayoutFrame = useBelowLayoutFrame(); const { bottom: homeIndicator } = useSafeAreaInsets(); const measured = Math.max(0, belowLayoutFrame - homeIndicator); if (measured > 0) return measured; return Platform.OS === "ios" ? IOS_TAB_BAR_HEIGHT : 0; } /** * Bottom padding so scroll content can clear the floating native tab bar. * Uses tab bar + home indicator as the target — layout-frame measurement can * over-report and leave a large empty scroll gap above the tab bar. */ export function useTabBarScrollPadding(): number { const { bottom: homeIndicator } = useSafeAreaInsets(); const tabBar = useNativeTabBarHeight(); const clearance = tabBar + homeIndicator; return Math.max(spacing.xs, clearance - TAB_BAR_PADDING_TRIM); } /** Bottom offset for floating action buttons above the tab bar. */ export function useFloatingActionBottom(): number { const { bottom: homeIndicator } = useSafeAreaInsets(); const tabBar = useNativeTabBarHeight(); return tabBar + homeIndicator + spacing.xs; } /** @deprecated Use useTabBarScrollPadding */ export function useTabBarInset() { return useTabBarScrollPadding(); }