117 lines
2.7 KiB
TypeScript
117 lines
2.7 KiB
TypeScript
import { useMemo } from 'react';
|
|
import type { FC } from 'react';
|
|
import { View, StyleSheet } from 'react-native';
|
|
import type { ViewStyle } from 'react-native';
|
|
|
|
import { Cell } from './cell';
|
|
import type { RowProps, RowsProps } from '../types';
|
|
import { sum } from '../util';
|
|
|
|
/** Row component - Renders a single row of cells*/
|
|
export const Row: FC<RowProps> = ({
|
|
data,
|
|
style,
|
|
widthArr,
|
|
height,
|
|
flexArr,
|
|
textStyle,
|
|
borderStyle,
|
|
onPress,
|
|
cellTextStyle,
|
|
...props
|
|
}) => {
|
|
// calc total width based on width array
|
|
const totalWidth = widthArr ? sum(widthArr) : 0;
|
|
|
|
// calc row styles based on props
|
|
const rowStyle = useMemo((): ViewStyle => {
|
|
const styles: ViewStyle = {};
|
|
if (totalWidth) styles.width = totalWidth;
|
|
if (height) styles.height = height;
|
|
return styles;
|
|
}, [totalWidth, height]);
|
|
|
|
if (!data || !data.length) return null;
|
|
|
|
return (
|
|
<View style={[styles.row, rowStyle, style]}>
|
|
{data.map((item, index) => {
|
|
const cellFlex = flexArr?.[index];
|
|
const cellWidth = widthArr?.[index];
|
|
const customTextStyle = cellTextStyle
|
|
? cellTextStyle(item, index)
|
|
: undefined;
|
|
|
|
return (
|
|
<Cell
|
|
key={index}
|
|
data={item}
|
|
width={cellWidth}
|
|
height={height}
|
|
flex={cellFlex}
|
|
borderStyle={borderStyle}
|
|
textStyle={[customTextStyle, textStyle]}
|
|
onPress={onPress}
|
|
{...props}
|
|
/>
|
|
);
|
|
})}
|
|
</View>
|
|
);
|
|
};
|
|
|
|
/** Rows component - Renders multiple rows*/
|
|
export const Rows: FC<RowsProps> = ({
|
|
data,
|
|
style,
|
|
widthArr,
|
|
heightArr,
|
|
flexArr,
|
|
textStyle,
|
|
borderStyle,
|
|
...props
|
|
}) => {
|
|
// calc total flex and width
|
|
const totalFlex = flexArr ? sum(flexArr) : 0;
|
|
const totalWidth = widthArr ? sum(widthArr) : 0;
|
|
|
|
// calc container styles
|
|
const containerStyle = useMemo((): ViewStyle => {
|
|
const styles: ViewStyle = {};
|
|
if (totalFlex) styles.flex = totalFlex;
|
|
if (totalWidth) styles.width = totalWidth;
|
|
return styles;
|
|
}, [totalFlex, totalWidth]);
|
|
|
|
if (!data || !data.length) return null;
|
|
|
|
return (
|
|
<View style={containerStyle}>
|
|
{data.map((rowData, index) => {
|
|
const rowHeight = heightArr?.[index];
|
|
|
|
return (
|
|
<Row
|
|
key={index}
|
|
data={rowData}
|
|
widthArr={widthArr}
|
|
height={rowHeight}
|
|
flexArr={flexArr}
|
|
style={style}
|
|
textStyle={textStyle}
|
|
borderStyle={borderStyle}
|
|
{...props}
|
|
/>
|
|
);
|
|
})}
|
|
</View>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
row: {
|
|
flexDirection: 'row',
|
|
overflow: 'hidden',
|
|
},
|
|
});
|