UNPKG

react-native-modal-select

Version:
265 lines (249 loc) 8.86 kB
import React, {Fragment, useState, useEffect} from 'react'; import { StyleSheet, View, Text, Platform, TouchableOpacity, Modal, Dimensions, FlatList } from 'react-native'; import Icon from './Icon' const ReactNativeModalSelect = ({ backgroundColor = "white", textColor = "black", iconColor = "black", iconType = "ionicons", iconName = "md-person", iconPadding = 5, iconSize = 25, inputHeight = 40, inputWidth = '100%', inputBackgroundColor = "white", labelSize = 16, labelColor = "black", marginBottom = 25, selectedValue = { id: 1, label: 'Spiderman', value: 'Peter Parker', }, labelText = "Superheros", clearable = true, onRequestClose = () => console.log("Closing"), onSelect = (val) => console.log("selected hero: " + val), items = [ { id: 0, label: 'Batman', value: 'Bruce Wayne', }, { id: 1, label: 'Spiderman', value: 'Peter Parker', }, { id: 2, label: 'The Punisher', value: 'Frank Castle', }, { id: 3, label: 'Superman', value: 'Clark Kent', }, { id: 4, label: 'The Hulk', value: 'Bruce Banner', }, { id: 5, label: 'Iron Man', value: 'Tony Stark', } ], ...props }) => { const [optionsModalVisible, setOptionsModalVisible] = useState(false) const [optionSelected, setOptionSelected] = useState({id: 0, label: '', value: ''}) const DEVICE_HEIGHT = Dimensions.get("screen").height var options = props.items || items var bgColor = props.backgroundColor || backgroundColor var textColor = props.textColor || textColor var icon_color = props.iconColor || iconColor var icon_type = props.iconType || iconType var icon_padding = props.iconPadding || iconPadding var icon_name = props.iconName || iconName var icon_size = props.iconSize || iconSize var input_height = props.inputHeight || inputHeight var input_width = props.inputWidth || inputWidth var input_bg_color = props.inputBackgroundColor || inputBackgroundColor var label_size = props.labelSize || labelSize var label_color = props.labelcolor || labelColor var label_text = props.labelText || labelText var is_clearable = props.clearable || clearable var selected_value = props.selectedValue || optionSelected === null ? '' : optionSelected.value var margin_bottom = props.marginBottom || marginBottom var onRequestModalClose = props.onRequestClose || onRequestClose var onItemSelect = props.onSelect || onSelect const clear = () => { setOptionSelected(null) } const Item = ({ title }) => ( <View style={[styles.item, { backgroundColor: bgColor }]}> <Text style={[styles.title, { color: textColor }]} > {title} </Text> </View> ); const renderItem = ({ item }) => ( <TouchableOpacity onPress={() => { setOptionSelected(item) setOptionsModalVisible(false) }} > <Item title={item.label} /> </TouchableOpacity> ); useEffect(() => { if(optionSelected != null) { onItemSelect(optionSelected) } }, [optionSelected]) return ( <Fragment> <Modal animationType="fade" transparent={ true } visible={ optionsModalVisible } onRequestClose={ onRequestModalClose } style={ styles.modalContainer } > <View style={{ backgroundColor: 'rgba(0,0,0,0.5)', position: 'absolute', left: 0, right: 0, top: 0, height: DEVICE_HEIGHT }}> <TouchableOpacity activeOpacity={ 1 } style={{ width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center' }} onPress={ () => setOptionsModalVisible(false) } > <View style={ [styles.optionsModal, {backgroundColor: bgColor} ]}> {/* necessary to overload the higher level backdrop-click dismissal */} <TouchableOpacity activeOpacity={ 1 }> <FlatList data={ options } renderItem={ renderItem } keyExtractor={ item => item.value } /> </TouchableOpacity> </View> </TouchableOpacity> </View> </Modal> <View style={{ maxWidth: input_width }}> <Text style={{ fontSize: label_size, color: label_color }}>{ label_text }</Text> <TouchableOpacity style={[ styles.selectContainer, { backgroundColor: input_bg_color, width: '100%', borderRadius: Platform.OS == 'ios' ? 10 : 0, borderWidth: Platform.OS == 'ios' ? 0 : 1, marginBottom: margin_bottom, zIndex: 5 }]} onPress={() => { setOptionsModalVisible(true) }} > <Icon iconColor={icon_color} iconType={icon_type} iconPadding={icon_padding} iconName={icon_name} iconSize={icon_size} inputHeight={input_height} /> <View style={{ width: icon_name != null ? '70%' : '80%', minHeight: input_height, backgroundColor: input_bg_color, borderRadius: Platform.OS == 'ios' ? 10 : 0, alignItems: 'flex-end', flexDirection: 'row' }}> <View style={{ width: '100%', minHeight: input_height, backgroundColor: input_bg_color, borderRadius: Platform.OS == 'ios' ? 10 : 0, paddingLeft: '6%', justifyContent: 'center', }}> <Text style={{ color: textColor, }} > { selected_value } </Text> </View> </View> { is_clearable ? <TouchableOpacity style={{ position: 'absolute', right: 10 }} onPress={ clear }> <Icon iconType="antdesign" iconName="closecircle" iconSize={24} iconColor={iconColor} /> </TouchableOpacity> : <View></View> } </TouchableOpacity> </View> </Fragment> ) } const styles = StyleSheet.create({ selectContainer: { flexDirection: 'row', alignItems: 'center', }, optionsModal: { width: '85%', alignSelf: 'center', height: '60%', }, modalContainer: { height: '60%', width: '90%' }, modalBodyContainer: { backgroundColor: '#f0eff1', width: '100%', height: '98%' }, container: { flex: 1, marginTop: 0, }, item: { padding: 10, marginVertical: 8, marginHorizontal: 16, }, title: { fontSize: 18, }, }) export default ReactNativeModalSelect