@uiw/react-native
Version:
UIW for React Native
192 lines (174 loc) • 4.83 kB
JavaScript
import { View, Text, StyleSheet, TouchableHighlight } from 'react-native';
import React, { Component } from 'react';
import { Picker } from '@react-native-picker/picker';
import arrayTreeFilter from '../utils/arrayTreeFilter';
import Modal from '../Modal';
import { colors } from '../utils';
export default class SelectCascader extends Component {
static defaultProps = {
dismissText: '取消',
okText: '确定',
title: '请选择',
disabled: false,
cols: 3
};
state = {
value: this.getValue(this.props.data, this.props.defaultValue || this.props.value),
modalVisible: this.props.visible
};
outerCtrl = () => {
this.setState({
modalVisible: !this.state.modalVisible
});
};
componentWillReceiveProps(nextProps) {
if ('value' in nextProps) {
this.setState({
value: this.getValue(nextProps.data, nextProps.value)
});
}
if ('visible' in nextProps) {
this.setState({
modalVisible: nextProps.visible
});
}
}
getSel(value) {
if (!value) {
return '';
}
const treeChildren = arrayTreeFilter(this.props.data, (c, level) => {
return c.value === value[level];
});
return treeChildren.map(v => {
return v.label;
}).join(',');
}
onValueChange = (itemValue, index) => {
const value = this.state.value.concat();
value[index] = itemValue;
const children = arrayTreeFilter(this.props.data, (c, level) => {
return level <= index && c.value === value[level];
});
let data = children[index];
let i;
for (i = index + 1; data && data.children && data.children.length && i < this.props.cols; i++) {
data = data.children[0];
value[i] = data.value;
}
value.length = i;
value[index] = itemValue;
this.setState({
value
});
if (this.props.onChange) {
this.props.onChange(value, this.getSel(value));
}
};
getValue(d, val) {
let data = d || this.props.data;
let value = val || this.props.value || this.props.defaultValue;
if (!value || !value.length || value.indexOf(undefined) > -1) {
value = [];
for (let i = 0; i < this.props.cols; i++) {
if (data && data.length) {
value[i] = data[0].value;
if (data[0].children) {
data = data[0].children;
}
}
}
}
return value;
}
getCols = () => {
const {
data,
cols,
pickerItemStyle
} = this.props;
const {
value
} = this.state;
const childrenTree = arrayTreeFilter(data, (c, level) => {
return c.value === value[level];
}).map(c => c.children);
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((children = [], level) => <Picker key={level} // eslint-disable-next-line react-native/no-inline-styles
style={{
flex: 1
}} selectedValue={value[level]} onValueChange={itemValue => this.onValueChange(itemValue, level)} itemStyle={pickerItemStyle}>
{children.map(item => <Picker.Item value={item.value} label={item.label} key={item.value} />)}
</Picker>);
};
onDismiss = () => {
if (this.props.onDismiss) {
this.props.onDismiss();
}
};
onOk = () => {
if (this.props.onOk) {
const {
value
} = this.state;
this.props.onOk(value, this.getSel(value));
}
};
render() {
const {
title,
dismissText,
okText,
onDismiss,
headerStyle
} = this.props;
const cols = this.getCols();
return <Modal visible={this.state.modalVisible} onClosed={() => {
this.setState({
modalVisible: false
});
}}>
<>
<View style={[styles.header, headerStyle]}>
<TouchableHighlight onPress={onDismiss} style={[styles.headerItem]}>
<Text>{dismissText}</Text>
</TouchableHighlight>
<View style={[styles.headerItem]}>
<Text>{title}</Text>
</View>
<TouchableHighlight onPress={this.onOk} style={[styles.headerItem]}>
<Text>{okText}</Text>
</TouchableHighlight>
</View>
<View style={styles.list}>{cols}</View>
</>
</Modal>;
}
}
const styles = StyleSheet.create({
header: {
height: 44,
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'center',
borderBottomWidth: 1,
borderBottomColor: colors.blue
},
headerItem: {
height: 44,
alignItems: 'center',
justifyContent: 'center',
flex: 1
},
list: {
flexDirection: 'row',
alignItems: 'center'
}
});