@uiw/react-native
Version:
UIW for React Native
109 lines (108 loc) • 4.08 kB
JavaScript
import React from 'react';
import { SafeAreaView, TouchableOpacity, View } from 'react-native';
import { arrayTreeFilter } from '../utils/utils';
import Flex from '../Flex';
import Text from '../Typography/Text';
import Modal from '../Modal';
import WheelPicker from './components/WheelPicker';
import { useTheme } from '@shopify/restyle';
const generateNextValue = (data, value, cols) => {
let d = data;
let level = 0;
const nextValue = [];
if (value && value.length) {
do {
const index = d.findIndex((item) => item.value + '' === value[level] + '');
if (index < 0) {
break;
}
nextValue[level] = value[level] + '';
level += 1;
d = d[index].children || [];
} while (d.length > 0);
}
for (let i = level; i < cols; i++) {
if (d && d.length) {
nextValue[i] = d[0].value + '';
d = d[0].children || [];
}
else {
break;
}
}
return nextValue;
};
function Picker(props) {
const { cols = 1, data = [], visible = false, displayType = 'view', cancelText = '取消', okText = '确定', title, onClosed, onChange, ...restProps } = props;
const theme = useTheme();
const [value, setValue] = React.useState(generateNextValue(data, props.value, cols));
React.useEffect(() => {
setValue(generateNextValue(data, props.value, cols));
}, [data, props.value]);
const onValueChange = (value, index) => {
// 修改当前的值,然后把后面的值都清掉
const newValue = [...value];
newValue[index] = value + '';
newValue.length = index + 1;
const nextValue = generateNextValue(data, newValue, cols);
setValue(nextValue);
if (displayType === 'view') {
onChange?.(value);
}
};
const getCols = () => {
const childrenTree = arrayTreeFilter(data, (c, level) => {
return c.value + '' === value[level] + '';
}).map((c) => c.children);
// in case the users data is async get when select change
const needPad = cols - childrenTree.length;
if (needPad > 0) {
for (let i = 0; i < needPad; i++) {
childrenTree.push([]);
}
}
childrenTree.length = cols - 1;
childrenTree.unshift(data);
return childrenTree.map((item = [], level) => (<WheelPicker containerStyle={{ marginRight: level !== childrenTree.length - 1 ? 5 : 0 }} key={level} {...restProps} {...{ data: item.map((el) => ({ ...el, value: `${el.value}` })), value: `${value[level]}` }} onChange={(val) => onValueChange(val, level)}/>));
};
const handleOk = () => {
onChange?.(value);
onClosed?.();
};
const handleClose = () => {
onClosed?.();
};
const PickerComp = <Flex>{getCols()}</Flex>;
if (displayType === 'modal') {
return (<Modal visible={visible} onClosed={handleClose}>
<SafeAreaView>
<View style={{ padding: 8 }}>
<Flex justify="between">
<Flex.Item>
<TouchableOpacity activeOpacity={0.5} onPress={handleClose}>
<Text color="primary_background" style={{ fontSize: 16 }}>
{cancelText}
</Text>
</TouchableOpacity>
</Flex.Item>
<Flex.Item>
<Text color="primary_background" style={{ fontSize: 16 }}>
{title}
</Text>
</Flex.Item>
<Flex.Item>
<TouchableOpacity activeOpacity={0.5} onPress={handleOk}>
<Text color="primary_background" style={{ fontSize: 16 }}>
{okText}
</Text>
</TouchableOpacity>
</Flex.Item>
</Flex>
<View style={{ height: '100%' }}>{PickerComp}</View>
</View>
</SafeAreaView>
</Modal>);
}
return PickerComp;
}
export default Picker;