UNPKG

3.04 kBJavaScriptView Raw
1import React, {
2 Component, PropTypes,
3} from 'react';
4
5import {
6 ScrollView, Text, View,
7} from 'react-native';
8
9import Header from './header';
10import Item from './item';
11import Sheet from '../Sheet';
12
13class Picker extends Component {
14 // 初始化外界参数
15 constructor(props) {
16 super(props);
17 this.componentWillReceiveProps(props);
18 }
19
20 // 将变更同步到 state
21 componentWillReceiveProps = (props) => {
22 this.state = { ...props };
23 }
24
25 // 缩短 state 链路
26 set state(state) {
27 state && Object.keys(state).forEach(key => this[key] = state[key]);
28 }
29
30 // 私有化,避免数据流不清晰
31 _onDone = () => {
32 const { _value, onDone } = this;
33 onDone && onDone(_value());
34 }
35 _onPick = (key) => {
36 const { _items, _set, _value, multiple, onChange } = this;
37 let { _picked } = this;
38 if (multiple) {
39 _picked[key] = key in _picked ? !_picked[key] : !_items[key].props.picked;
40 } else {
41 _picked = _items.map((item, index) => index === key);
42 }
43
44 _set({
45 _picked,
46 }, () => onChange && onChange(_value()));
47 }
48 _picked = []
49 _set = this.setState.bind(this)
50
51 get _header() {
52 return this.children.find(({ type }) => type === Header);
53 }
54
55 get _items() {
56 return this.children.filter(({ type }) => type === Item);
57 }
58
59 _value = () => {
60 const { _items, _picked, multiple } = this;
61 if (multiple) {
62 return _items
63 .map((item, index) => _items[index].props.value || _items[index].props.children)
64 .filter((item, index) => index in _picked && _picked[index]);
65 }
66 const key = _picked.length ?
67 _picked.findIndex(item => item === true) :
68 _items.findIndex(item => item.props.picked);
69 if (key === -1) return undefined;
70 return _items[key].props.value || _items[key].props.children;
71 }
72
73 // 渲染
74 render() {
75 const {
76 _getStyle, _header, _items, _onDone, _onPick, _picked,
77 onCancel, style,
78 } = this;
79 return (
80 <Sheet visible onPressOverlay={onCancel}>
81 <View style={[{ backgroundColor: '#fff' }, style]}>
82 {_header && (
83 <Header
84 {..._header.props}
85 onPressLeft={onCancel}
86 onPressRight={_onDone}
87 />
88 )}
89 <ScrollView style={{ flex: 1 }}>
90 {_items.map(({ props }, index) => (
91 <Item
92 {...props}
93 key={index}
94 index={index}
95 isLast={index === _items.length}
96 onChange={() => _onPick(index)}
97 picked={index in _picked ? _picked[index] : props.picked}
98 />
99 ))}
100 </ScrollView>
101 </View>
102 </Sheet>
103 );
104 }
105}
106
107Picker.propTypes = {
108 onCancel: PropTypes.func,
109 onChange: PropTypes.func,
110 multiple: PropTypes.bool,
111 style: View.propTypes.style,
112};
113
114Picker.defaultProps = {
115 onCancel: () => {},
116 onChange: () => {},
117 multiple: false,
118 style: null,
119};
120
121Picker.Header = Header;
122Picker.Item = Item;
123
124export default Picker;