UNPKG

reactnativecomponents

Version:
156 lines (155 loc) 5.06 kB
import * as React from 'react'; import { Picker as RNPicker, PickerIOS, Platform, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import { View as AnimatableView } from 'react-native-animatable'; import AbstractFormComponent from '../Form/AbstractFormComponent'; import Dialog from '../Dialog/index'; import Input from '../Input'; import { Colors, separatorHeight } from '../styles'; const styles = StyleSheet.create({ dialogContainer: { backgroundColor: 'rgba(0,0,0,.4)', justifyContent: 'flex-end' }, picker: { backgroundColor: '#fff' }, header: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', height: 40, paddingHorizontal: 15, borderBottomWidth: separatorHeight, borderColor: Colors.separator, backgroundColor: Colors.underlay }, title: { color: '#0977FF', fontSize: 16, maxHeight: 40, minWidth: 10 } }); const showAnimation = { animation: 'fadeIn', duration: 200 }; const hideAnimation = { animation: 'fadeOut', duration: 500 }; /** * @author 田尘殇Sean(sean.snow@live.com) * @date 16/5/8 */ class Picker extends AbstractFormComponent { constructor(props) { super(props); this.state = { visible: false, selectedValue: null }; this.contentShowAnimation = { animation: 'fadeInUpBig', duration: 500 }; this.contentHideAnimation = { animation: 'fadeOutDownBig', duration: 500 }; this.state.selectedValue = props.defaultSelected || props.selectedValue; } componentWillReceiveProps({ selectedValue }) { if (this.props.selectedValue !== selectedValue) { this.setState({ selectedValue }); } } handleValueChange(selectedValue) { this.setState({ selectedValue }); if (Platform.OS === 'android') { const { onValueChange } = this.props; onValueChange && onValueChange(selectedValue); } } handleDialogOpen() { this.currentSelectedValue = this.state.selectedValue; this.handleDialogSwitch(); } handleConfirm() { const { onValueChange } = this.props; onValueChange && onValueChange(this.state.selectedValue); this.handleDialogSwitch(); } handleCancel() { this.setState({ selectedValue: this.currentSelectedValue }); this.handleDialogSwitch(); } handleDialogSwitch() { this.setState({ visible: !this.state.visible }); } getValue() { return this.state.selectedValue; } isValid() { return true; } renderHeader() { const { renderHeader, confirmText, cancelText, title } = this.props; if (renderHeader) { return renderHeader(); } return (<View style={styles.header}> <TouchableOpacity onPress={this.handleCancel}> <Text style={styles.title}>{cancelText}</Text> </TouchableOpacity> <Text style={[styles.title, { fontSize: 18 }]}>{title}</Text> <TouchableOpacity onPress={this.handleConfirm}> <Text style={styles.title}> {confirmText} </Text> </TouchableOpacity> </View>); } render() { const { editable, children, mode, style, ...other } = this.props; if (Platform.OS === 'android') { return (<RNPicker mode={mode} onValueChange={this.handleValueChange} selectedValue={this.state.selectedValue} style={style}> {children} </RNPicker>); } const props = this.state.visible ? this.contentShowAnimation : this.contentHideAnimation; let label = ' '; const childrenArr = React.Children.toArray(children); for (let i = 0; i < childrenArr.length; i++) { const child = childrenArr[i]; if (child.props.value === this.state.selectedValue) { label = child.props.label; break; } } return (<TouchableOpacity disabled={editable} onPress={this.handleDialogOpen}> <Input {...other} style={style}> {label} </Input> <Dialog hideAnimation={hideAnimation} onPress={this.handleCancel} showAnimation={showAnimation} statusBarAutoHidden={false} style={styles.dialogContainer} visible={this.state.visible}> <AnimatableView {...props} style={styles.picker}> {this.renderHeader()} <PickerIOS onValueChange={this.handleValueChange} selectedValue={this.state.selectedValue}> {children} </PickerIOS> </AnimatableView> </Dialog> </TouchableOpacity>); } } Picker.defaultProps = { cancelText: '取消', confirmText: '确认', mode: 'dialog', title: '' }; export const Item = Platform.select({ ios: PickerIOS.Item, android: RNPicker.Item }); export default Picker;