UNPKG

@uiw/react-native

Version:
103 lines 3.2 kB
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>; }