import React, { Component } from 'react';
import {
View,
Modal,
TouchableOpacity,
FlatList,
Dimensions,
Text,
ActivityIndicator,
TextInput,
} from 'react-native';
import PropTypes from 'prop-types';
import { getStatusBarHeight } from 'react-native-status-bar-height';
import Icon from 'react-native-vector-icons/AntDesign';
import ButtonOutline from './button-outline';
import TextField from './text-field';
import LocalizedString from '../localization';
import {
COLOR_BLACK_INACTIVE,
COLOR_BODY_TEXT,
COLOR_PRIMARY,
} from '../constant';
import { Body, H4 } from './labels';
const getScreenDimension = () => {
const statusBarHeight = getStatusBarHeight();
const { height, width } = Dimensions.get('window');
return { height: height - statusBarHeight, width };
};
const { width, height } = getScreenDimension();
const styles = {
modalContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
},
modalInnerContainer: {
alignItems: 'center',
backgroundColor: '#fff',
width: width - 30,
borderRadius: 10,
paddingTop: 20,
paddingHorizontal: 10,
},
headerSectionIos: {
height: 50,
alignSelf: 'stretch',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingHorizontal: 20,
backgroundColor: '#fff',
},
iosModalButton: {
color: 'black',
},
bodySectionIos: {
alignSelf: 'stretch',
paddingVertical: 20,
paddingHorizontal: 10,
},
pickerItemAndroid: {
borderBottomWidth: 1,
paddingVertical: 15,
alignItems: 'center',
},
flatListAndroid: {
height: (height * 30) / 100,
alignSelf: 'stretch',
},
footerAndroid: {
marginVertical: 20,
alignItems: 'center',
alignSelf: 'stretch',
},
clearButton: {
paddingVertical: 10,
paddingHorizontal: 10,
marginTop: 10,
},
simplePickerButton: {
flexDirection: 'row',
alignItems: 'flex-end',
// width: '100%',
},
noItemContainer: {
height: 50,
width,
alignItems: 'center',
alignSelf: 'center',
},
};
export default class SimplePicker extends Component {
constructor(props) {
super(props);
this.state = {
showModal: false,
selectedValue: props.selectedValue,
searchQuery: '',
};
}
componentDidUpdate() {
if (this.props.selectedValue !== this.state.selectedValue) {
// eslint-disable-next-line react/no-did-update-set-state
this.setState({ selectedValue: this.props.selectedValue });
}
}
onSearchQueryChange = query => {
this.setState({ searchQuery: query });
};
onClearButtonPressed = () => {
this.setState({ showModal: false });
this.props.onClearPressed();
};
onTextFieldPressed = () => {
if (this.props.validationButtonPress) {
this.props.onPressButton();
} else {
if (!this.props.disabled) {
this.setState({ showModal: true });
}
}
};
onValueSelect = item => {
const selectedItem = item || this.props.data[0];
this.props.onValueSelected(selectedItem);
this.setState({
showModal: false,
searchQuery: '',
});
};
onPickerValueChanged = value => {
const { data } = this.props;
const realValue = data.find(x =>
x.label || x.value ? x.value === value : x === value,
);
this.props.onValueSelected(realValue);
this.setState({ selectedValue: realValue });
};
onCancelPicker = () => {
this.setState({ showModal: false, searchQuery: '' });
};
// renderPicker = () => {
// const { selectedValue } = this.props;
// const displayedSelectedValue = selectedValue && (selectedValue.label || selectedValue.value)
// ? selectedValue.value
// : selectedValue;
// return (
// <Fragment>
// {
// this.props.data.length > 0 ?
// <Picker
// mode="dropdown"
// selectedValue={displayedSelectedValue}
// onValueChange={this.onPickerValueChanged}
// style={{ paddingHorizontal: 10 }}
// >
// {
// this.props.data.map((item) => {
// const label = item.label || item;
// const value = item.value || item;
// return (
// <Picker.Item label={label} value={value} key={value} />
// );
// })
// }
// </Picker> :
// <View style={styles.noItemContainer}>
// <H4 >
// {LocalizedString.common.errMsgNoResultFound}
// </H4>
// </View>
// }
// </Fragment>
// );
// };
renderTextField = () => {
const { selectedValue, loading } = this.props;
const displayedSelectedValue =
typeof selectedValue === 'object'
? selectedValue.label
: selectedValue || '';
return (
<TouchableOpacity
style={styles.simplePickerButton}
disabled={this.props.disabled || loading}
onPress={this.onTextFieldPressed}>
<TextField
label={this.props.label}
required={this.props.required}
error={this.props.error}
value={displayedSelectedValue}
editable={false}
containerStyle={{ flex: 1 }}
dow
{...this.props}
/>
{loading ? (
<View style={{ alignSelf: 'center' }}>
<ActivityIndicator size="small" color={COLOR_PRIMARY} />
</View>
) : (
<Icon
name="caretdown"
size={10}
style={{ marginBottom: 23 }}
color={COLOR_BLACK_INACTIVE}
/>
)}
</TouchableOpacity>
);
};
onPickerItemAndroidPressed = item => {
this.setState({ selectedValue: item });
this.onValueSelect(item);
};
renderPickerItemAndroid = ({ item }) => (
<TouchableOpacity
style={[
styles.pickerItemAndroid,
{ borderColor: this.props.separatorColor },
]}
onPress={() => this.onPickerItemAndroidPressed(item)}>
<Text
style={this.props.itemTextStyle}
allowFontScaling={false}
adjustsFontSizeToFit>
{item.label || item.value ? item.label : item}
</Text>
</TouchableOpacity>
);
renderAndroidPicker = () => {
const { data, cancelCaption, isSearch } = this.props;
const { searchQuery } = this.state;
const flatListHeight = data && data.length > 3 ? {} : { height: undefined };
const filteredData = data.filter(item => {
if (isSearch === true) {
return item.label.toLowerCase().includes(searchQuery.toLowerCase());
}
});
return (
<View>
{this.renderTextField()}
<Modal
animationType={this.props.animationType}
transparent
visible={this.state.showModal}
onRequestClose={() => {}}>
<View style={[styles.modalContainer]}>
<View style={[styles.modalInnerContainer]}>
{isSearch && (
<TextInput
style={{
height: 45,
width: '100%',
color: COLOR_BODY_TEXT,
borderWidth: 1,
borderColor: COLOR_BLACK_INACTIVE,
borderRadius: 8,
paddingHorizontal: 10,
}}
placeholder="Search..."
onChangeText={this.onSearchQueryChange}
/>
)}
<FlatList
data={isSearch === true ? filteredData : data}
ListEmptyComponent={
<View style={styles.noItemContainer}>
<H4>{LocalizedString.common.errMsgNoResultFound}</H4>
</View>
}
renderItem={this.renderPickerItemAndroid}
keyExtractor={item => item.value || item}
style={[styles.flatListAndroid, flatListHeight]}
/>
{this.props.showClearButton ? (
<View style={styles.footerAndroid}>
<ButtonOutline
caption={cancelCaption}
onPress={this.onCancelPicker}
/>
<TouchableOpacity
onPress={this.onClearButtonPressed}
style={styles.clearButton}>
<Body bold style={{ color: COLOR_PRIMARY }}>
{'Clear'}
</Body>
</TouchableOpacity>
</View>
) : (
<View style={styles.footerAndroid}>
<TouchableOpacity onPress={this.onCancelPicker}>
<Body bold style={{ color: COLOR_PRIMARY }}>
{cancelCaption}
</Body>
</TouchableOpacity>
</View>
)}
</View>
</View>
</Modal>
</View>
);
};
render() {
// return ios
// ? this.renderIosPicker()
// : this.renderAndroidPicker();
return this.renderAndroidPicker();
}
}
const pickerItemShape = PropTypes.shape({
value: PropTypes.string,
label: PropTypes.string,
});
const arrayShape = PropTypes.arrayOf(pickerItemShape);
SimplePicker.propTypes = {
loading: PropTypes.bool,
showClearButton: PropTypes.bool,
onClearPressed: PropTypes.func,
animationType: PropTypes.string,
label: PropTypes.string,
error: PropTypes.string,
separatorColor: PropTypes.string,
cancelCaption: PropTypes.string,
okCaption: PropTypes.string,
disabled: PropTypes.bool,
required: PropTypes.bool,
itemTextStyle: PropTypes.objectOf(
PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
),
selectedValue: PropTypes.oneOfType([pickerItemShape, PropTypes.string]),
onValueSelected: PropTypes.func,
data: PropTypes.oneOfType([arrayShape, PropTypes.arrayOf(PropTypes.string)])
.isRequired,
};
SimplePicker.defaultProps = {
loading: false,
showClearButton: false,
animationType: 'fade',
cancelCaption: 'Cancel',
okCaption: 'OK',
label: '',
error: '',
separatorColor: '#EEEEEE',
disabled: false,
required: false,
selectedValue: undefined,
itemTextStyle: { fontSize: 14 },
onValueSelected: () => {},
onClearPressed: () => {},
};