import React, { ForwardedRef, MutableRefObject, RefAttributes, forwardRef, useImperativeHandle, } from 'react'; import { FlatList } from 'react-native'; import Animated, { useAnimatedRef } from 'react-native-reanimated'; import { AnimatedContext } from '../context/AnimatedContext'; import { useLazyContextValues } from './useLazyContextValues'; export interface LazyFlatListMethods { scrollToStart: typeof FlatList.prototype.scrollToEnd; scrollToEnd: typeof FlatList.prototype.scrollToEnd; scrollToIndex: typeof FlatList.prototype.scrollToIndex; scrollToOffset: typeof FlatList.prototype.scrollToOffset; scrollToItem: typeof FlatList.prototype.scrollToItem; } export interface LazyFlatListProps { /** * How far above or below the bottom of the FlatList the threshold trigger is. Negative is above, postive it below. Accepts [FlatList props](https://reactnative.dev/docs/FlatList). * @defaultValue 0 (bottom of Fl) */ offset?: number; /** * Ref to the LazyFlatList. Exposes scrollTo, scrollToStart, and scrollToEnd methods. */ ref?: MutableRefObject; /** * When true, console.logs FlatList measurements. Even if true, will not call console.log in production. */ debug?: boolean; } type Props = LazyFlatListProps & Omit< React.ComponentProps>, 'onLayout' | 'onScroll' | 'ref' | 'CellRendererComponent' >; /** * LazyFlatList to wrap Lazy Children in. */ const UnwrappedLazyFlatList = ( { offset: injectedOffset, debug = false, ...rest }: Props, ref: ForwardedRef ) => { const _flatListRef = useAnimatedRef>(); useImperativeHandle(ref, () => ({ scrollToStart: (options) => { _flatListRef.current?.scrollToOffset({ offset: 0, animated: options?.animated, }); }, scrollToEnd: (options) => { _flatListRef.current?.scrollToEnd(options); }, scrollToIndex: (options) => { _flatListRef.current?.scrollToIndex(options); }, scrollToOffset: (options) => { _flatListRef.current?.scrollToOffset(options); }, scrollToItem: (options) => { _flatListRef.current?.scrollToItem(options); }, })); const { value, measureScroller } = useLazyContextValues({ offset: injectedOffset, debug, horizontal: rest.horizontal, // @ts-ignore ref: _flatListRef, }); return ( ); }; const LazyFlatList = forwardRef(UnwrappedLazyFlatList) as ( props: Props & RefAttributes ) => React.ReactElement; export { LazyFlatList };