UNPKG

@uiw/react-native

Version:
109 lines (108 loc) 4.08 kB
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;