@uiw/react-native
Version:
UIW for React Native
121 lines (119 loc) • 3.17 kB
JavaScript
import React from 'react';
import { FlatList, Text, View } from 'react-native';
import Item from './Item';
const noop = () => null;
/**
* @see https://facebook.github.io/react-native/docs/flatlist.html#props
*/
export default class List extends React.PureComponent {
static Item = Item;
static defaultProps = {
data: [],
paddingLeft: 16,
flat: true,
size: 'default'
};
constructor(props) {
super(props);
this.state = {
data: []
};
}
static getDerivedStateFromProps(props) {
const getData = () => {
const {
size,
extra,
paddingLeft,
children
} = props;
const dataSource = React.Children.toArray(children).map(child => {
if (!React.isValidElement(child)) {
return null;
}
const props = {
size,
...child.props
};
return React.cloneElement(<Item paddingLeft={paddingLeft} extra={extra} {...props} />);
}).filter(Boolean);
return dataSource;
};
if (!props.renderItem) {
const result = getData();
return {
data: result
};
}
return null;
}
renderItemChild(props) {
return props.item;
}
render() {
const {
renderItem,
data,
children,
titleStyle,
titleLabelStyle,
paddingLeft,
flat,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
size,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
extra,
title,
ListHeaderComponent,
...otherProps
} = this.props;
const props = {};
if (!renderItem) {
props.data = this.state.data;
props.renderItem = this.renderItemChild.bind(this);
} else if (typeof renderItem === 'function') {
props.data = data;
props.renderItem = itemProps => renderItem({
...itemProps
});
}
let header = ListHeaderComponent;
if (title) {
header =
// eslint-disable-next-line
<View style={[{
paddingLeft,
paddingVertical: 12
}, titleStyle]}>
{typeof title === 'string' ?
// eslint-disable-next-line
<Text style={[{
fontWeight: '500'
}, titleLabelStyle]}>{title}</Text> : <View>{title}</View>}
</View>;
}
if (!props.renderItem) {
props.renderItem = noop;
}
if (!flat) {
return <View {...otherProps}>
<>
{header}
{/* eslint-disable-next-line */}
{(renderItem && (!data || data.length === 0) ||
// eslint-disable-next-line
!renderItem && (!children || React.Children.toArray(children).length === 0)) && otherProps.ListEmptyComponent}
{(props.data || []).map((item, idx) =>
// eslint-disable-next-line
React.cloneElement(props.renderItem && props.renderItem({
item,
index: idx
}) || <View />, {
key: idx
}))}
</>
</View>;
}
return <FlatList ListHeaderComponent={header} keyExtractor={(__, index) => index.toString()} {...otherProps} {...props} />;
}
}