react-native-country-codes-picker
Advanced tools
@@ -11,7 +11,7 @@ import React from 'react'; | ||
| Easing, | ||
| Keyboard, | ||
| Keyboard, TouchableOpacity, | ||
| } from 'react-native'; | ||
| import { countryCodes } from '../constants/countryCodes'; | ||
| import { CountryButton } from './CountryButton'; | ||
| import { useKeyboardStatus } from '../helpers/useKeyboardStatus'; | ||
| import {countryCodes} from '../constants/countryCodes'; | ||
| import {CountryButton} from './CountryButton'; | ||
| import {useKeyboardStatus} from '../helpers/useKeyboardStatus'; | ||
@@ -23,2 +23,3 @@ const height = Dimensions.get('window').height; | ||
| * @param {?boolean} show Hide or show component by using this props | ||
| * @param {?boolean} disableBackdrop Hide or show component by using this props | ||
| * @param {?boolean} enableModalAvoiding Is modal should avoid keyboard ? On android to work required to use with androidWindowSoftInputMode with value pan, by default android will avoid keyboard by itself | ||
@@ -30,2 +31,3 @@ * @param {?string} androidWindowSoftInputMode Hide or show component by using this props | ||
| * @param {Function} pickerButtonOnPress Function to receive selected country | ||
| * @param {Function} onBackdropPress Function to receive selected country | ||
| * @param {?Object} style Styles | ||
@@ -37,13 +39,15 @@ * @param {?React.ReactNode} itemTemplate Country list template | ||
| export default function CountryPicker({ | ||
| show, | ||
| pickerButtonOnPress, | ||
| inputPlaceholder, | ||
| searchMessage, | ||
| lang = 'en', | ||
| style, | ||
| enableModalAvoiding, | ||
| androidWindowSoftInputMode, | ||
| itemTemplate: ItemTemplate = CountryButton, | ||
| ...rest | ||
| }) { | ||
| show, | ||
| pickerButtonOnPress, | ||
| inputPlaceholder, | ||
| searchMessage, | ||
| lang = 'en', | ||
| style, | ||
| enableModalAvoiding, | ||
| androidWindowSoftInputMode, | ||
| onBackdropPress, | ||
| disableBackdrop, | ||
| itemTemplate: ItemTemplate = CountryButton, | ||
| ...rest | ||
| }) { | ||
| const keyboardStatus = useKeyboardStatus(); | ||
@@ -53,10 +57,7 @@ const animationDriver = React.useRef(new Animated.Value(0)).current; | ||
| const [searchValue, setSearchValue] = React.useState(''); | ||
| const [visible, setVisible] = React.useState(show); | ||
| React.useEffect(() => { | ||
| if (show) { | ||
| Animated.timing(animationDriver, { | ||
| toValue: 1, | ||
| duration: 400, | ||
| useNativeDriver: true, | ||
| }).start(); | ||
| openModal(); | ||
| } else { | ||
@@ -111,2 +112,17 @@ closeModal(); | ||
| const modalBackdropFade = animationDriver.interpolate({ | ||
| inputRange: [0, 0.5, 1], | ||
| outputRange: [0, 0.5, 1], | ||
| extrapolate: 'clamp' | ||
| }); | ||
| const openModal = () => { | ||
| setVisible(true); | ||
| Animated.timing(animationDriver, { | ||
| toValue: 1, | ||
| duration: 400, | ||
| useNativeDriver: false, | ||
| }).start(); | ||
| }; | ||
| const closeModal = () => { | ||
@@ -116,20 +132,41 @@ Animated.timing(animationDriver, { | ||
| duration: 400, | ||
| useNativeDriver: true, | ||
| }).start(); | ||
| useNativeDriver: false, | ||
| }).start(() => setVisible(false)); | ||
| }; | ||
| if (!visible) | ||
| return null; | ||
| return ( | ||
| <Animated.View | ||
| style={[ | ||
| styles.container, | ||
| { | ||
| transform: [ | ||
| <> | ||
| {!disableBackdrop && ( | ||
| <Animated.View | ||
| onStartShouldSetResponder={onBackdropPress} | ||
| style={[ | ||
| { | ||
| translateY: modalPosition, | ||
| flex: 1, | ||
| opacity: modalBackdropFade, | ||
| backgroundColor: 'rgba(116,116,116,0.45)', | ||
| position: 'absolute', | ||
| width: '100%', | ||
| height: '100%', | ||
| justifyContent: 'flex-end' | ||
| }, | ||
| ], | ||
| }, | ||
| ]} | ||
| > | ||
| <View style={[styles.modal, style?.modal]}> | ||
| style?.backdrop | ||
| ]} | ||
| /> | ||
| )} | ||
| <Animated.View | ||
| style={[ | ||
| styles.modal, | ||
| style?.modal, | ||
| { | ||
| transform: [ | ||
| { | ||
| translateY: modalPosition, | ||
| }, | ||
| ], | ||
| }, | ||
| ]} | ||
| > | ||
| <View | ||
@@ -149,5 +186,5 @@ style={{ | ||
| </View> | ||
| <View style={styles.line} /> | ||
| <View style={[styles.line, style?.line]}/> | ||
| {resultCountries.length === 0 ? ( | ||
| <View style={styles.countryMessage}> | ||
| <View style={[styles.countryMessage, style?.countryMessageContainer]}> | ||
| <Text | ||
@@ -172,4 +209,7 @@ style={[ | ||
| maxToRenderPerBatch={10} | ||
| style={[{ | ||
| height: 250 | ||
| }, style?.itemsList]} | ||
| keyboardShouldPersistTaps={'handled'} | ||
| renderItem={({ item, index }) => { | ||
| renderItem={({item, index}) => { | ||
| let itemName = item?.name[lang]; | ||
@@ -186,4 +226,3 @@ let checkName = itemName.length ? itemName : item?.name['en']; | ||
| Keyboard.dismiss(); | ||
| pickerButtonOnPress(item); | ||
| closeModal(); | ||
| typeof pickerButtonOnPress === 'function' && pickerButtonOnPress(item); | ||
| }} | ||
@@ -196,13 +235,13 @@ /> | ||
| )} | ||
| </View> | ||
| <Animated.View | ||
| style={[ | ||
| styles.modalInner, | ||
| style?.modalInner, | ||
| { | ||
| height: animatedMargin, | ||
| }, | ||
| ]} | ||
| /> | ||
| </Animated.View> | ||
| <Animated.View | ||
| style={[ | ||
| styles.modalInner, | ||
| style?.modalInner, | ||
| { | ||
| height: animatedMargin, | ||
| }, | ||
| ]} | ||
| /> | ||
| </Animated.View> | ||
| </> | ||
| ); | ||
@@ -223,3 +262,2 @@ } | ||
| backgroundColor: 'white', | ||
| height: '50%', | ||
| width: '100%', | ||
@@ -234,2 +272,5 @@ borderTopRightRadius: 15, | ||
| }, | ||
| position: 'absolute', | ||
| bottom: 0, | ||
| zIndex: 10, | ||
| shadowOpacity: 0.37, | ||
@@ -243,4 +284,2 @@ shadowRadius: 7.49, | ||
| width: '100%', | ||
| zIndex: 100, | ||
| elevation: 10, | ||
| }, | ||
@@ -267,2 +306,2 @@ searchBar: { | ||
| }, | ||
| }; | ||
| }; |
+1
-1
| { | ||
| "name": "react-native-country-codes-picker", | ||
| "version": "1.3.4", | ||
| "version": "1.3.5", | ||
| "description": "This lib. provide country iso picker with search functionality", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
+20
-2
@@ -30,3 +30,3 @@ # react-native-country-codes-picker | ||
| ```JS | ||
| import {CountryPicker} from "react-native-country-codes-picker/components/CountryPicker"; | ||
| import {CountryPicker} from "react-native-country-codes-picker"; | ||
@@ -83,4 +83,6 @@ export default function App() { | ||
| | androidWindowSoftInputMode | string | | androidWindowSoftInputMode={'pan'} | Basicaly android avoid keyboard by itself, if you want to use custom avoiding you may use this prop | | ||
| | itemTemplate | ReactNode | | style={<CustomListItem />} | This parameter gets a React Node element to render it as a template for each item of the list. These properties are sent to the item: key, item, style, name, and onPress | | ||
| | itemTemplate | ReactNode | CountryButton | itemTemplate={YourTemplateComponentsHere} | This parameter gets a React Node element to render it as a template for each item of the list. These properties are sent to the item: key, item, style, name, and onPress | | ||
| | style | Object | | style={{yoursStylesHere}} | If you want to change styles for component you probably need this props. You can check the styling part below. | | ||
| | disableBackdrop | boolean | false | disableBackdrop | if you don't wanna show modal backdrop pass this prop.| | ||
| | onBackdropPress | function | null | onBackdropPress={() => setShow(false)} | If you want to close modal when user taps on the modal background. | | ||
@@ -101,2 +103,14 @@ :grey_exclamation: Also you can use all other FlatList and TextInput props if you need. :grey_exclamation: | ||
| }, | ||
| // Styles for modal backdrop [View] | ||
| backdrop: { | ||
| }, | ||
| // Styles for bottom input line [View] | ||
| line: { | ||
| }, | ||
| // Styles for list of countries [FlatList] | ||
| itemsList: { | ||
| }, | ||
| // Styles for input [TextInput] | ||
@@ -115,2 +129,6 @@ textInput: { | ||
| }, | ||
| // Styles for search message container [View] | ||
| countryMessageContainer: { | ||
| }, | ||
| // Flag styles [Text] | ||
@@ -117,0 +135,0 @@ flag: { |
85578
2.26%3726
0.95%160
12.68%