Skip to content

Commit

Permalink
Feat: FlatLists as @react-native/flat-lists package
Browse files Browse the repository at this point in the history
Summary: This diff moves `FlatList` and `SectionList` to a
new package `@react-native/flat-lists`.
This is a first step towards moving all the `FlatList`-related code
to a separate package.
This will allow us to make changes to the `FlatList` implementation
without affecting the rest of the React Native codebase.

Changelog: [General] [Changed] - Move `FlatList`s to `@react-native/flat-lists` package.
`FlatList` and `SectionList` are now available in `@react-native/flat-lists` package.
**Warning**: This though this is NOT a breaking change, and you will NOT need to
update your imports to use the new package. But, moving forward it will
be better to install `@react-native/flat-list` if you want to import explicitly.
  • Loading branch information
Pranav-yadav committed Mar 23, 2023
1 parent 308838c commit 7184780
Show file tree
Hide file tree
Showing 27 changed files with 1,860 additions and 1,671 deletions.
1 change: 1 addition & 0 deletions packages/flat-lists/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__tests__
246 changes: 246 additions & 0 deletions packages/flat-lists/Lists/FlatList.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
/**
* 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,
} from '@react-native/virtualized-lists';
import type {
ScrollViewComponent,
StyleProp,
ViewStyle,
View,
} from 'react-native';

export interface FlatListProps<ItemT> extends VirtualizedListProps<ItemT> {
/**
* Optional custom style for multi-item rows generated when numColumns > 1
*/
columnWrapperStyle?: StyleProp<ViewStyle> | 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<ItemT> | 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<ItemT> | 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<ViewToken>;
changed: Array<ViewToken>;
}) => 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}) => (
* <TouchableOpacity onPress={() => this._onPress(item)}>
* <Text>{item.title}</Text>
* </TouchableOpacity>
* );
* ...
* <FlatList data={[{title: 'Title Text', key: 'item1'}]} renderItem={this._renderItem} />
* ```
* Provides additional metadata like `index` if you need it.
*/
renderItem: ListRenderItem<ItemT> | null | undefined;

/**
* See `ViewabilityHelper` for flow type and further documentation.
*/
viewabilityConfig?: any | 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<Props> {
/**
* 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<typeof View>
| React.ElementRef<typeof ScrollViewComponent>
| null
| undefined;

getScrollableNode: () => any;

// TODO: use `unknown` instead of `any` for Typescript >= 3.0
setNativeProps: (props: {[key: string]: any}) => void;
}

export class FlatList<ItemT = any> extends FlatListComponent<
ItemT,
FlatListProps<ItemT>
> {}
Loading

0 comments on commit 7184780

Please sign in to comment.