@uiw/react-native
Version:
UIW for React Native
103 lines • 3.2 kB
JavaScript
import React, { Fragment } from 'react';
import { View, Text, Image, TouchableOpacity, StyleSheet } from 'react-native';
import Flex from '../Flex';
function MaybeTextOrView({
children,
...otherProps
}) {
if (typeof children === 'string' || children && children.type.displayName === 'Text') {
return <Text {...otherProps}>{children}</Text>;
}
return <View {...otherProps}>{children}</View>;
}
const styles = StyleSheet.create({
defalut: {
backgroundColor: '#fff'
},
touchWarpper: {
flex: 1,
width: '100%',
alignItems: 'center',
justifyContent: 'center'
}
});
export default function Grid(props) {
const {
style,
data = [],
iconStyle,
textStyle,
itemStyle,
renderItem,
hasLine = true,
columns = 4,
onPress,
...otherProps
} = props;
if (!Array.isArray(data)) {
return null;
}
const childs = [];
let childItem = [];
data.forEach((item, idx) => {
if (idx !== 0 && idx % columns === 0) {
childs.push(childItem);
childItem = [];
}
let icon = null;
if (React.isValidElement(item.icon)) {
icon = item.icon;
} else if (item.icon) {
icon = <Image style={[{
width: 36,
height: 36
}, StyleSheet.flatten(iconStyle)]} source={typeof item.icon === 'number' ? item.icon : {
uri: item.icon
}} />;
}
if (renderItem && typeof renderItem === 'function') {
childItem.push(renderItem(item, idx, parseInt((idx / columns).toString(), 10) + 1));
} else {
const itemContent = <Fragment>
{icon && <MaybeTextOrView style={iconStyle}>{icon}</MaybeTextOrView>}
<MaybeTextOrView style={[{
marginTop: 9,
fontSize: 12
}, textStyle]}>{item.text}</MaybeTextOrView>
</Fragment>;
childItem.push(<Flex direction="column" align="center" justify="center" style={[{
height: 120
}, StyleSheet.flatten(itemStyle), {
width: `${100 / columns}%`
}]}>
{onPress ? <TouchableOpacity style={styles.touchWarpper} onPress={e => onPress(item, idx, parseInt((idx / columns).toString(), 10) + 1, e)}>
{itemContent}
</TouchableOpacity> : itemContent}
</Flex>);
}
if (idx === data.length - 1) {
childs.push(childItem);
}
});
return <View style={[styles.defalut, style]} {...otherProps}>
{childs.map((rowitem, rowidx) => <Flex justify="start" key={rowidx}>
{rowitem.map((item, idx) => {
if (!React.isValidElement(item)) {
return null;
}
const itemBorderStyle = {};
if (hasLine) {
const hairLineWidth = StyleSheet.hairlineWidth;
itemBorderStyle.borderBottomWidth = childs.length - 1 === rowidx ? 0 : hairLineWidth;
itemBorderStyle.borderRightWidth = rowitem.length - 1 === idx && rowitem.length === columns ? 0 : hairLineWidth;
itemBorderStyle.borderBottomColor = '#ddd';
itemBorderStyle.borderRightColor = '#ddd';
}
return React.cloneElement(item, {
key: idx,
style: [itemBorderStyle, item.props.style]
});
})}
</Flex>)}
</View>;
}