@uiw/react-native
Version:
UIW for React Native
129 lines (111 loc) • 3.04 kB
JavaScript
import React, { Component } 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 Component {
static Item = Item;
static defaultProps = {
data: [],
paddingLeft: 16,
flat: true,
size: 'default'
};
constructor(props) {
super(props);
this.state = {
data: []
};
}
getData(nextProps) {
const {
size,
extra,
paddingLeft,
children
} = nextProps || this.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);
this.setState({
data: dataSource
});
}
componentDidMount() {
if (!this.props.renderItem) {
this.getData();
}
}
UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps !== this.props) {
this.getData(nextProps);
}
}
renderItemChild(props) {
return props.item;
}
render() {
const {
renderItem,
data,
children,
titleStyle,
paddingLeft,
flat,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
size,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
extra,
ListHeaderComponent,
title,
...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 react-native/no-inline-styles
<View style={[{
paddingLeft,
paddingVertical: 12
}, titleStyle]}>
{typeof title === 'string' ? // eslint-disable-next-line react-native/no-inline-styles
<Text style={{
color: '#808080'
}}>{title}</Text> : <View>{title}</View>}
</View>;
}
if (!props.renderItem) {
props.renderItem = noop;
}
if (!flat) {
return <View {...otherProps}>
{header}
{(renderItem && (!data || data.length === 0) || !renderItem && (!children || React.Children.toArray(children).length === 0)) && otherProps.ListEmptyComponent}
{(props.data || []).map((item, idx) => React.cloneElement(props.renderItem && props.renderItem({
item,
index: idx
}) || <View />, {
key: idx
}))}
</View>;
}
return <FlatList ListHeaderComponent={header} keyExtractor={(__, index) => index.toString()} {...otherProps} {...props} />;
}
}