/** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format */ import type * as React from 'react'; import type { ListRenderItem, ViewToken, VirtualizedListProps, ViewabilityConfig, } from '@react-native/virtualized-lists'; import type {ScrollViewComponent} from '../Components/ScrollView/ScrollView'; import type {StyleProp} from '../StyleSheet/StyleSheet'; import type {ViewStyle} from '../StyleSheet/StyleSheetTypes'; import type {View} from '../Components/View/View'; export interface FlatListProps extends VirtualizedListProps { /** * Optional custom style for multi-item rows generated when numColumns > 1 */ columnWrapperStyle?: StyleProp | undefined; /** * Determines when the keyboard should stay visible after a tap. * - 'never' (the default), tapping outside of the focused text input when the keyboard is up dismisses the keyboard. When this happens, children won't receive the tap. * - 'always', the keyboard will not dismiss automatically, and the scroll view will not catch taps, but children of the scroll view can catch taps. * - 'handled', the keyboard will not dismiss automatically when the tap was handled by a children, (or captured by an ancestor). * - false, deprecated, use 'never' instead * - true, deprecated, use 'always' instead */ keyboardShouldPersistTaps?: | boolean | 'always' | 'never' | 'handled' | undefined; /** * An array (or array-like list) of items to render. Other data types can be * used by targeting VirtualizedList directly. */ data: ArrayLike | null | undefined; /** * A marker property for telling the list to re-render (since it implements PureComponent). * If any of your `renderItem`, Header, Footer, etc. functions depend on anything outside of the `data` prop, * stick it here and treat it immutably. */ extraData?: any | undefined; /** * `getItemLayout` is an optional optimization that lets us skip measurement of dynamic * content if you know the height of items a priori. getItemLayout is the most efficient, * and is easy to use if you have fixed height items, for example: * ``` * getItemLayout={(data, index) => ( * {length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index} * )} * ``` * Remember to include separator length (height or width) in your offset calculation if you specify * `ItemSeparatorComponent`. */ getItemLayout?: | (( data: ArrayLike | null | undefined, index: number, ) => {length: number; offset: number; index: number}) | undefined; /** * If true, renders items next to each other horizontally instead of stacked vertically. */ horizontal?: boolean | null | undefined; /** * How many items to render in the initial batch */ initialNumToRender?: number | undefined; /** * Instead of starting at the top with the first item, start at initialScrollIndex */ initialScrollIndex?: number | null | undefined; /** * Used to extract a unique key for a given item at the specified index. Key is used for caching * and as the react key to track item re-ordering. The default extractor checks `item.key`, then * falls back to using the index, like React does. */ keyExtractor?: ((item: ItemT, index: number) => string) | undefined; /** * Uses legacy MetroListView instead of default VirtualizedSectionList */ legacyImplementation?: boolean | undefined; /** * Multiple columns can only be rendered with `horizontal={false}` and will zig-zag like a `flexWrap` layout. * Items should all be the same height - masonry layouts are not supported. */ numColumns?: number | undefined; /** * If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. * Make sure to also set the refreshing prop correctly. */ onRefresh?: (() => void) | null | undefined; /** * Called when the viewability of rows changes, as defined by the `viewablePercentThreshold` prop. */ onViewableItemsChanged?: | ((info: { viewableItems: Array>; changed: Array>; }) => void) | null | undefined; /** * Set this true while waiting for new data from a refresh. */ refreshing?: boolean | null | undefined; /** * Takes an item from data and renders it into the list. Typical usage: * ``` * _renderItem = ({item}) => ( * this._onPress(item)}> * {item.title} * * ); * ... * * ``` * Provides additional metadata like `index` if you need it. */ renderItem: ListRenderItem | null | undefined; /** * See `ViewabilityHelper` for flow type and further documentation. */ viewabilityConfig?: ViewabilityConfig | undefined; /** * Note: may have bugs (missing content) in some circumstances - use at your own risk. * * This may improve scroll performance for large lists. */ removeClippedSubviews?: boolean | undefined; /** * Fades out the edges of the scroll content. * * If the value is greater than 0, the fading edges will be set accordingly * to the current scroll direction and position, * indicating if there is more content to show. * * The default value is 0. * @platform android */ fadingEdgeLength?: number | undefined; } export abstract class FlatListComponent< ItemT, Props, > extends React.Component { /** * Scrolls to the end of the content. May be janky without `getItemLayout` prop. */ scrollToEnd: (params?: {animated?: boolean | null | undefined}) => void; /** * Scrolls to the item at the specified index such that it is positioned in the viewable area * such that viewPosition 0 places it at the top, 1 at the bottom, and 0.5 centered in the middle. * Cannot scroll to locations outside the render window without specifying the getItemLayout prop. */ scrollToIndex: (params: { animated?: boolean | null | undefined; index: number; viewOffset?: number | undefined; viewPosition?: number | undefined; }) => void; /** * Requires linear scan through data - use `scrollToIndex` instead if possible. * May be janky without `getItemLayout` prop. */ scrollToItem: (params: { animated?: boolean | null | undefined; item: ItemT; viewOffset?: number | undefined; viewPosition?: number | undefined; }) => void; /** * Scroll to a specific content pixel offset, like a normal `ScrollView`. */ scrollToOffset: (params: { animated?: boolean | null | undefined; offset: number; }) => void; /** * Tells the list an interaction has occurred, which should trigger viewability calculations, * e.g. if waitForInteractions is true and the user has not scrolled. This is typically called * by taps on items or by navigation actions. */ recordInteraction: () => void; /** * Displays the scroll indicators momentarily. */ flashScrollIndicators: () => void; /** * Provides a handle to the underlying scroll responder. */ getScrollResponder: () => JSX.Element | null | undefined; /** * Provides a reference to the underlying host component */ getNativeScrollRef: () => | React.ElementRef | React.ElementRef | null | undefined; getScrollableNode: () => any; // TODO: use `unknown` instead of `any` for Typescript >= 3.0 setNativeProps: (props: {[key: string]: any}) => void; } export class FlatList extends FlatListComponent< ItemT, FlatListProps > {}