1 | import React from 'react';
|
2 |
|
3 | import {
|
4 | ScrollView, Text, TouchableWithoutFeedback, View,
|
5 | } from 'react-native';
|
6 |
|
7 |
|
8 |
|
9 | import { isEqual } from './helper';
|
10 |
|
11 | function Select({
|
12 | children, multiple, onChange, options, style, value,
|
13 | }) {
|
14 |
|
15 |
|
16 | if (options === undefined) {
|
17 | options = children;
|
18 | }
|
19 |
|
20 |
|
21 | if (!Array.isArray(options)) {
|
22 | options = options ? [options] : [];
|
23 | }
|
24 |
|
25 | const values = [], selected = [];
|
26 | const onSelect = index => {
|
27 |
|
28 | if (onChange === undefined) return;
|
29 |
|
30 |
|
31 | if (!multiple) {
|
32 | return onChange(values[index], index);
|
33 | }
|
34 |
|
35 |
|
36 | if (index in selected) {
|
37 | delete selected[index];
|
38 | } else {
|
39 | selected[index] = values[index];
|
40 | }
|
41 |
|
42 |
|
43 | onChange(selected.filter(option => option === undefined), Object.keys(selected));
|
44 | };
|
45 | const isSelected = ({ props }, index) => {
|
46 |
|
47 | let isTrue = value === undefined && props.selected;
|
48 |
|
49 |
|
50 | if (multiple) {
|
51 | isTrue = isTrue || value.findIndex(_value => isEqual(_value, props.value)) !== -1;
|
52 | } else {
|
53 | if (selected.length > 1) return false;
|
54 | isTrue = isTrue || isEqual(value, props.value);
|
55 | }
|
56 |
|
57 |
|
58 | if (isTrue) {
|
59 | selected[index] = props.value;
|
60 | return true;
|
61 | }
|
62 |
|
63 | return false;
|
64 | };
|
65 |
|
66 |
|
67 | return (
|
68 | <ScrollView style={[{ flexGrow: 1, flexShrink: 0 }, style]}>
|
69 | {options.map((item, index) => {
|
70 |
|
71 | if (typeof item in { number: null, string: null }) {
|
72 | item = <Text value={item}>{item}</Text>;
|
73 | }
|
74 |
|
75 |
|
76 | if (item.label !== undefined) {
|
77 | item = <Text value={item.value || item.label}>{item.label}</Text>;
|
78 | }
|
79 |
|
80 |
|
81 | values[index] = item.props.value;
|
82 |
|
83 |
|
84 | const selected = isSelected(item, index);
|
85 |
|
86 |
|
87 | if (item.type === Text) {
|
88 | item = (
|
89 | <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
|
90 | <Text {...item.props} style={[{ backgroundColor: 'transparent' }, item.props.style]} />
|
91 | {selected ? <Text>-</Text> : null}
|
92 | </View>
|
93 | );
|
94 | }
|
95 |
|
96 |
|
97 | return (
|
98 | <TouchableWithoutFeedback key={index} onPress={() => onSelect(index)}>
|
99 | <View>
|
100 | <item.type {...item.props} selected={selected} />
|
101 | </View>
|
102 | </TouchableWithoutFeedback>
|
103 | );
|
104 | })}
|
105 | </ScrollView>
|
106 | );
|
107 | }
|
108 | Select.propTypes = {};
|
109 | Select.defaultProps = {};
|
110 |
|
111 | export default Select;
|