Files
beenvoice-app/lib/tab-bar-insets.ts
T
soconnor 0b2d65a4e9 Add Authentik sign-in, fix tab scroll insets, and polish multi-account auth.
Mobile app detects SSO per server, supports OAuth sign-in, and preserves saved
sessions when adding accounts. Tab screens get proper chrome layout and tab-bar
clearance with scrollable page headers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-18 02:27:31 -04:00

68 lines
2.3 KiB
TypeScript

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;
}
/**
* Bottom padding for tab-root ScrollViews (Dashboard, Invoices, etc.).
* Uses full tab-bar clearance — do not trim; undershooting hides content under the bar.
*/
export function useTabScreenScrollPadding(): number {
const { bottom: homeIndicator } = useSafeAreaInsets();
const tabBar = useNativeTabBarHeight();
return tabBar + homeIndicator + spacing.sm;
}
/** @deprecated Use useTabBarScrollPadding */
export function useTabBarInset() {
return useTabBarScrollPadding();
}