add support for `ListEmptyComponent`, allow `undefined` data (#4403)

* add support for `ListEmptyComponent`, allow `undefined` data

* change `header` and `footer` to be in line with `emptyComponent`

* don't render `onEndReached` or `onStartReached` `Visibility` if empty
zio/stable
Hailey 2024-06-18 17:33:43 -07:00 committed by GitHub
parent 3dc34be929
commit 8788708bd2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 39 additions and 24 deletions

View File

@ -38,6 +38,7 @@ function ListImpl<ItemT>(
{ {
ListHeaderComponent, ListHeaderComponent,
ListFooterComponent, ListFooterComponent,
ListEmptyComponent,
containWeb, containWeb,
contentContainerStyle, contentContainerStyle,
data, data,
@ -72,23 +73,35 @@ function ListImpl<ItemT>(
) )
} }
let header: JSX.Element | null = null const isEmpty = !data || data.length === 0
let headerComponent: JSX.Element | null = null
if (ListHeaderComponent != null) { if (ListHeaderComponent != null) {
if (isValidElement(ListHeaderComponent)) { if (isValidElement(ListHeaderComponent)) {
header = ListHeaderComponent headerComponent = ListHeaderComponent
} else { } else {
// @ts-ignore Nah it's fine. // @ts-ignore Nah it's fine.
header = <ListHeaderComponent /> headerComponent = <ListHeaderComponent />
} }
} }
let footer: JSX.Element | null = null let footerComponent: JSX.Element | null = null
if (ListFooterComponent != null) { if (ListFooterComponent != null) {
if (isValidElement(ListFooterComponent)) { if (isValidElement(ListFooterComponent)) {
footer = ListFooterComponent footerComponent = ListFooterComponent
} else { } else {
// @ts-ignore Nah it's fine. // @ts-ignore Nah it's fine.
footer = <ListFooterComponent /> footerComponent = <ListFooterComponent />
}
}
let emptyComponent: JSX.Element | null = null
if (ListEmptyComponent != null) {
if (isValidElement(ListEmptyComponent)) {
emptyComponent = ListEmptyComponent
} else {
// @ts-ignore Nah it's fine.
emptyComponent = <ListEmptyComponent />
} }
} }
@ -323,15 +336,17 @@ function ListImpl<ItemT>(
onVisibleChange={handleAboveTheFoldVisibleChange} onVisibleChange={handleAboveTheFoldVisibleChange}
style={[styles.aboveTheFoldDetector, {height: headerOffset}]} style={[styles.aboveTheFoldDetector, {height: headerOffset}]}
/> />
{onStartReached && ( {onStartReached && !isEmpty && (
<Visibility <Visibility
root={containWeb ? nativeRef : null} root={containWeb ? nativeRef : null}
onVisibleChange={onHeadVisibilityChange} onVisibleChange={onHeadVisibilityChange}
topMargin={(onStartReachedThreshold ?? 0) * 100 + '%'} topMargin={(onStartReachedThreshold ?? 0) * 100 + '%'}
/> />
)} )}
{header} {headerComponent}
{(data as Array<ItemT>).map((item, index) => { {isEmpty
? emptyComponent
: (data as Array<ItemT>)?.map((item, index) => {
const key = keyExtractor!(item, index) const key = keyExtractor!(item, index)
return ( return (
<Row<ItemT> <Row<ItemT>
@ -345,14 +360,14 @@ function ListImpl<ItemT>(
/> />
) )
})} })}
{onEndReached && ( {onEndReached && !isEmpty && (
<Visibility <Visibility
root={containWeb ? nativeRef : null} root={containWeb ? nativeRef : null}
onVisibleChange={onTailVisibilityChange} onVisibleChange={onTailVisibilityChange}
bottomMargin={(onEndReachedThreshold ?? 0) * 100 + '%'} bottomMargin={(onEndReachedThreshold ?? 0) * 100 + '%'}
/> />
)} )}
{footer} {footerComponent}
</View> </View>
</View> </View>
) )