import React, { ForwardedRef, Ref, forwardRef } from 'react'; import { useHeaderHeight } from '@react-navigation/elements'; import { FlatList, FlatListProps, ScrollView, ScrollViewProps, SectionList, SectionListProps } from 'react-native'; import useCurrentTrack from '../utility/useCurrentTrack'; import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs'; declare module 'react' { function forwardRef( render: (props: P, ref: React.Ref) => React.ReactElement | null ): (props: P & React.RefAttributes) => React.ReactElement | null; } /** * A wrapper for ScrollView that takes any paddings, margins and insets into * account that result from the bottom tabs, potential NowPlaying overlay and header. */ export function SafeScrollView({ contentContainerStyle, ...props }: ScrollViewProps) { const { top, bottom } = useNavigationOffsets(); return ( ); } /** * A wrapper for ScrollView that takes any paddings, margins and insets into * account that result from the bottom tabs, potential NowPlaying overlay and header. */ function BareSafeSectionList({ contentContainerStyle, ...props }: SectionListProps, ref: ForwardedRef>) { const { top, bottom } = useNavigationOffsets(); return ( ); } export const SafeSectionList = forwardRef(BareSafeSectionList); /** * A wrapper for ScrollView that takes any paddings, margins and insets into * account that result from the bottom tabs, potential NowPlaying overlay and header. */ function BareSafeFlatList({ contentContainerStyle, ...props }: FlatListProps, ref: ForwardedRef>) { const { top, bottom } = useNavigationOffsets(); return ( ); } export const SafeFlatList = forwardRef(BareSafeFlatList); /** * A hook that returns the correct offset that should be applied to any Views * that are wrapped in a NavigationView, in order to account for overlays, * headers and bottom tabs. */ export function useNavigationOffsets({ includeOverlay = true } = {} as { includeOverlay?: boolean }) { const headerHeight = useHeaderHeight(); const bottomBarHeight = useBottomTabBarHeight(); const { track } = useCurrentTrack(); return { top: headerHeight, bottom: (track && includeOverlay ? 68 : 0) + bottomBarHeight || 0, }; }