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,36 +336,38 @@ 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
const key = keyExtractor!(item, index) ? emptyComponent
return ( : (data as Array<ItemT>)?.map((item, index) => {
<Row<ItemT> const key = keyExtractor!(item, index)
key={key} return (
item={item} <Row<ItemT>
index={index} key={key}
renderItem={renderItem} item={item}
extraData={extraData} index={index}
onItemSeen={onItemSeen} renderItem={renderItem}
disableContentVisibility={disableContentVisibility} extraData={extraData}
/> onItemSeen={onItemSeen}
) disableContentVisibility={disableContentVisibility}
})} />
{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>
) )