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',
|
||
|
},
|
||
|
});
|