Skip to content

Commit

Permalink
Adding new styling props to FlatList/VirtualizedList for ListHeaderCo…
Browse files Browse the repository at this point in the history
…mponent and ListFooterComponent

Summary:
We ran into a problem trying to style the optional prop `ListHeaderComponent` in the `FlatList` library component. Essentially we wanted to make `ListHeaderComponent` a flex item that filled all of the empty space in the list if there was any. Unfortunately the `ListHeaderComponent` is later wrapped in a `View` that blocked our styling. The `View` component was necessary as it added styling to handle inverting the `FlatList`. Similarly `ListFooterComponent` was handled the same way.

We came up the simple solution of adding two new optional props, `ListHeaderComponentStyle` and `ListFooterComponentStyle`, that are of type `ViewStyleProp` that allow users to pass in styling for `ListHeaderComponent` and `ListFooterComponent`.

With this change we were able to do something like the following to get the header component to fill all empty space in the `FlatList`.

```
<FlatList
    ...
    contentContainerStyle={{flexGrow: 1}}
    ListHeaderComponent={<View style={{flex: 1}} />}
    ListHeaderComponentStyle={{flexGrow: 1}}
    ...
/>
```
This solution will give users a lot more freedom when working with headers and footers.

Reviewed By: sahrens

Differential Revision: D8777038

fbshipit-source-id: f34116ce68548ea70223e639d0f84a099327f6b3
  • Loading branch information
Michael Ficaro authored and facebook-github-bot committed Jul 12, 2018
1 parent 8ee60e9 commit a2675ce
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 10 deletions.
10 changes: 9 additions & 1 deletion Libraries/Lists/FlatList.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const StyleSheet = require('StyleSheet');

const invariant = require('fbjs/lib/invariant');

import type {DangerouslyImpreciseStyleProp} from 'StyleSheet';
import type {DangerouslyImpreciseStyleProp, ViewStyleProp} from 'StyleSheet';
import type {
ViewabilityConfig,
ViewToken,
Expand Down Expand Up @@ -88,11 +88,19 @@ type OptionalProps<ItemT> = {
* a rendered element.
*/
ListFooterComponent?: ?(React.ComponentType<any> | React.Element<any>),
/**
* Styling for internal View for ListFooterComponent
*/
ListFooterComponentStyle?: ViewStyleProp,
/**
* Rendered at the top of all the items. Can be a React Component Class, a render function, or
* a rendered element.
*/
ListHeaderComponent?: ?(React.ComponentType<any> | React.Element<any>),
/**
* Styling for internal View for ListHeaderComponent
*/
ListHeaderComponentStyle?: ViewStyleProp,
/**
* Optional custom style for multi-item rows generated when numColumns > 1.
*/
Expand Down
24 changes: 21 additions & 3 deletions Libraries/Lists/VirtualizedList.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const warning = require('fbjs/lib/warning');

const {computeWindowedRenderLimits} = require('VirtualizeUtils');

import type {DangerouslyImpreciseStyleProp} from 'StyleSheet';
import type {DangerouslyImpreciseStyleProp, ViewStyleProp} from 'StyleSheet';
import type {
ViewabilityConfig,
ViewToken,
Expand Down Expand Up @@ -124,11 +124,19 @@ type OptionalProps = {
* a rendered element.
*/
ListFooterComponent?: ?(React.ComponentType<any> | React.Element<any>),
/**
* Styling for internal View for ListFooterComponent
*/
ListFooterComponentStyle?: ViewStyleProp,
/**
* Rendered at the top of all the items. Can be a React Component Class, a render function, or
* a rendered element.
*/
ListHeaderComponent?: ?(React.ComponentType<any> | React.Element<any>),
/**
* Styling for internal View for ListHeaderComponent
*/
ListHeaderComponentStyle?: ViewStyleProp,
/**
* A unique identifier for this list. If there are multiple VirtualizedLists at the same level of
* nesting within another VirtualizedList, this key is necessary for virtualization to
Expand Down Expand Up @@ -756,7 +764,12 @@ class VirtualizedList extends React.PureComponent<Props, State> {
<VirtualizedCellWrapper
cellKey={this._getCellKey() + '-header'}
key="$header">
<View onLayout={this._onLayoutHeader} style={inversionStyle}>
<View
onLayout={this._onLayoutHeader}
style={StyleSheet.compose(
inversionStyle,
this.props.ListHeaderComponentStyle,
)}>
{
// $FlowFixMe - Typing ReactNativeComponent revealed errors
element
Expand Down Expand Up @@ -892,7 +905,12 @@ class VirtualizedList extends React.PureComponent<Props, State> {
<VirtualizedCellWrapper
cellKey={this._getCellKey() + '-footer'}
key="$footer">
<View onLayout={this._onLayoutFooter} style={inversionStyle}>
<View
onLayout={this._onLayoutFooter}
style={StyleSheet.compose(
inversionStyle,
this.props.ListFooterComponentStyle,
)}>
{
// $FlowFixMe - Typing ReactNativeComponent revealed errors
element
Expand Down
2 changes: 0 additions & 2 deletions Libraries/Lists/__tests__/__snapshots__/FlatList-test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ exports[`FlatList renders all the bells and whistles 1`] = `
<View>
<View
onLayout={[Function]}
style={null}
>
<header />
</View>
Expand Down Expand Up @@ -119,7 +118,6 @@ exports[`FlatList renders all the bells and whistles 1`] = `
</View>
<View
onLayout={[Function]}
style={null}
>
<footer />
</View>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,6 @@ exports[`SectionList renders all the bells and whistles 1`] = `
<View>
<View
onLayout={[Function]}
style={null}
>
<header
v=""
Expand Down Expand Up @@ -484,7 +483,6 @@ exports[`SectionList renders all the bells and whistles 1`] = `
</View>
<View
onLayout={[Function]}
style={null}
>
<footer
v=""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -665,14 +665,12 @@ exports[`VirtualizedList renders empty list with empty component 1`] = `
<View>
<View
onLayout={[Function]}
style={null}
>
<header />
</View>
<empty />
<View
onLayout={[Function]}
style={null}
>
<footer />
</View>
Expand Down

2 comments on commit a2675ce

@Noitidart
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think better names for this prop would be ListHeaderComponentContainerStyle and ListFooterComponentContainerStyle (notice the added Container). Because we're stylling the contaienr view, and not the actual component. We should probably also document this in the docs, as we document the ScrollView container, as that has major repercussions on styling/layout.

@gitfdy
Copy link

@gitfdy gitfdy commented on a2675ce Sep 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my react native version is 0.54.0,but i want use this api,how can i do it?
i add these code in my project, but is not work in ios,android is fine,plz help

Please sign in to comment.