react-native-picker-module-delete
Version:
React Native Picker Module for Android & IOS
220 lines (210 loc) • 6.19 kB
JavaScript
import React, { useEffect, useState, forwardRef, useCallback } from "react"
import { PlatformColor, StyleSheet, Text, TouchableOpacity, View } from "react-native"
import { Picker } from "@react-native-picker/picker"
import Modal from "react-native-modal"
const ReactNativePickerModule = forwardRef((props, ref) => {
const {
value,
items,
title,
onValueChange,
cancelButton,
confirmButton,
deleteButton,
onCancel,
onDelete,
contentContainerStyle,
titleStyle,
itemStyle,
useNativeDriver,
confirmButtonAlwaysEnabled,
confirmButtonDisabledTextStyle,
confirmButtonEnabledTextStyle,
cancelButtonTextStyle,
backdropColor,
backdropOpacity,
tintColor,
selectedColor,
confirmButtonStyle,
cancelButtonStyle,
} = props;
const dismissPress = () => {
setIsVisible(false)
if (onCancel) {
onCancel()
}
}
const [isVisible, setIsVisible] = useState(false)
const [selectedValue, setSelectedValue] = useState()
const setDefaultSelectedValue = useCallback(() =>
setSelectedValue(!value ? (typeof items[0] === "object" ? items[0].value : items[0]) : value),
[items, value]
);
useEffect(() => {
ref.current = {
show: () => setIsVisible(true),
hide: dismissPress,
}
});
// reset selected value state when items change
useEffect(() => {
if (isVisible) {
setDefaultSelectedValue();
}
}, [setDefaultSelectedValue, isVisible]);
return (
<Modal
backdropColor={backdropColor}
backdropOpacity={backdropOpacity}
onBackdropPress={dismissPress}
onBackButtonPress={dismissPress}
onShow={setDefaultSelectedValue}
useNativeDriver={useNativeDriver}
isVisible={isVisible}
style={{ justifyContent: "flex-end" }}
hideModalContentWhileAnimating={true}>
<View style={[styles.content, contentContainerStyle]}>
<View style={styles.titleView}>
<Text style={[styles.titleText, titleStyle]}>{title}</Text>
</View>
<Picker
itemStyle={itemStyle}
selectedValue={selectedValue}
style={{
maxHeight: 200,
overflow: "hidden",
}}
onValueChange={(itemValue, itemIndex) => setSelectedValue(itemValue)}>
{items.map((item, index) => {
if (item.hasOwnProperty("value") && item.hasOwnProperty("label")) {
return (
<Picker.Item
color={value === item.value ? selectedColor : tintColor}
key={"item-" + index}
label={item.label.toString()}
value={item.value.toString()}
/>
)
} else {
return (
<Picker.Item
color={value === item ? selectedColor : tintColor}
key={"item-" + index}
label={item.toString()}
value={item.toString()}
/>
)
}
})}
</Picker>
{onDelete && (
<TouchableOpacity
activeOpacity={0.9}
disabled={value === selectedValue}
onPress={() => {
onDelete(selectedValue)
}}
style={[styles.deleteButtonView]}>
<Text style={[styles.deleteButtonText]}>{deleteButton}</Text>
</TouchableOpacity>
)}
<TouchableOpacity
activeOpacity={0.9}
disabled={(value === selectedValue) && !confirmButtonAlwaysEnabled}
onPress={() => {
onValueChange(selectedValue)
setIsVisible(false)
}}
style={[styles.confirmButtonView, confirmButtonStyle]}>
<Text
style={[
styles.confirmButtonText,
(selectedValue === value && !confirmButtonAlwaysEnabled) ? confirmButtonDisabledTextStyle : confirmButtonEnabledTextStyle,
]}>
{confirmButton}
</Text>
</TouchableOpacity>
</View>
<View style={styles.cancelButton}>
<TouchableOpacity
activeOpacity={0.9}
style={[styles.cancelButtonView, cancelButtonStyle]}
onPress={dismissPress}>
<Text style={[styles.cancelButtonText, cancelButtonTextStyle]}>{cancelButton}</Text>
</TouchableOpacity>
</View>
</Modal>
)
})
const styles = StyleSheet.create({
content: {
backgroundColor: PlatformColor('systemBackground'),
borderRadius: 10,
borderColor: PlatformColor('separator'),
},
confirmButtonView: {
borderBottomEndRadius: 10,
borderBottomStartRadius: 10,
backgroundColor: PlatformColor('systemBackground'),
borderTopWidth: 1,
borderTopColor: PlatformColor('separator'),
paddingVertical: 15,
},
deleteButtonView: {
borderBottomEndRadius: 10,
borderBottomStartRadius: 10,
backgroundColor: PlatformColor('systemBackground'),
borderTopWidth: 1,
borderTopColor: PlatformColor('separator'),
paddingVertical: 15,
},
confirmButtonText: {
fontWeight: "500",
fontSize: 18,
textAlign: "center",
},
deleteButtonText: {
fontWeight: "500",
fontSize: 18,
textAlign: "center",
color: PlatformColor('systemRed'),
},
cancelButton: {
marginVertical: 10,
},
cancelButtonView: {
backgroundColor: PlatformColor('systemBackground'),
padding: 15,
borderRadius: 10,
},
cancelButtonText: {
fontWeight: "bold",
fontSize: 18,
textAlign: "center",
color: PlatformColor('link'),
},
titleView: {
padding: 12,
borderBottomWidth: 1,
borderBottomColor: PlatformColor('separator'),
},
titleText: {
fontWeight: "500",
fontSize: 14,
textAlign: "center",
color: "#bdbdbd",
},
})
ReactNativePickerModule.defaultProps = {
confirmButtonEnabledTextStyle: {
color: PlatformColor('link'),
},
confirmButtonDisabledTextStyle: {
color: PlatformColor('placeholderText'),
},
cancelButton: "Cancel",
confirmButton: "Confirm",
deleteButton: "Delete",
useNativeDriver: true,
}
export default ReactNativePickerModule