react-native-country-select 0.3.4 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -69,6 +69,8 @@
69
69
  npm install react-native-country-select
70
70
  # or
71
71
  yarn add react-native-country-select
72
+ # and
73
+ cd ios && pod install
72
74
  ```
73
75
 
74
76
  <br>
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable react-native/no-inline-styles */
2
- import React, {useEffect, useMemo, useRef, useState} from 'react';
2
+ import React, { useEffect, useMemo, useRef, useState } from 'react';
3
3
  import {
4
4
  Animated,
5
5
  Modal,
@@ -10,9 +10,13 @@ import {
10
10
  Keyboard,
11
11
  NativeSyntheticEvent,
12
12
  } from 'react-native';
13
+ import {
14
+ SafeAreaProvider,
15
+ SafeAreaView,
16
+ } from 'react-native-safe-area-context';
13
17
 
14
18
  import parseHeight from '../../utils/parseHeight';
15
- import {ICountrySelectStyle} from '../../interface';
19
+ import { ICountrySelectStyle } from '../../interface';
16
20
 
17
21
  interface BottomSheetModalProps extends ModalProps {
18
22
  visible: boolean;
@@ -67,19 +71,26 @@ export const BottomSheetModal: React.FC<BottomSheetModalProps> = ({
67
71
  const dragStartYRef = useRef(0);
68
72
 
69
73
  useEffect(() => {
70
- const DRAG_HANDLE_HEIGHT = 20;
71
- const availableHeight = Math.max(0, modalHeight - DRAG_HANDLE_HEIGHT);
72
- const parsedMinHeight = parseHeight(minBottomsheetHeight, availableHeight);
73
- const parsedMaxHeight = parseHeight(maxBottomsheetHeight, availableHeight);
74
+ const parsedMinHeight = parseHeight(
75
+ minBottomsheetHeight,
76
+ modalHeight
77
+ );
78
+ const parsedMaxHeight = parseHeight(
79
+ maxBottomsheetHeight,
80
+ modalHeight
81
+ );
74
82
  const parsedInitialHeight = parseHeight(
75
83
  initialBottomsheetHeight,
76
- availableHeight,
84
+ modalHeight
77
85
  );
78
86
  setBottomSheetSize({
79
- minHeight: parsedMinHeight || MIN_HEIGHT_PERCENTAGE * availableHeight,
80
- maxHeight: parsedMaxHeight || MAX_HEIGHT_PERCENTAGE * availableHeight,
87
+ minHeight:
88
+ parsedMinHeight || MIN_HEIGHT_PERCENTAGE * modalHeight,
89
+ maxHeight:
90
+ parsedMaxHeight || MAX_HEIGHT_PERCENTAGE * modalHeight,
81
91
  initialHeight:
82
- parsedInitialHeight || INITIAL_HEIGHT_PERCENTAGE * availableHeight,
92
+ parsedInitialHeight ||
93
+ INITIAL_HEIGHT_PERCENTAGE * modalHeight,
83
94
  });
84
95
  }, [
85
96
  modalHeight,
@@ -115,17 +126,17 @@ export const BottomSheetModal: React.FC<BottomSheetModalProps> = ({
115
126
  onStartShouldSetPanResponder: () => true,
116
127
  onMoveShouldSetPanResponder: (_evt, gestureState) =>
117
128
  Math.abs(gestureState.dy) > 5,
118
- onPanResponderGrant: e => {
129
+ onPanResponderGrant: (e) => {
119
130
  dragStartYRef.current = e.nativeEvent.pageY;
120
131
  sheetHeight.stopAnimation();
121
132
  },
122
- onPanResponderMove: e => {
133
+ onPanResponderMove: (e) => {
123
134
  const currentY = e.nativeEvent.pageY;
124
135
  const dy = currentY - dragStartYRef.current;
125
136
  const proposedHeight = lastHeightRef.current - dy;
126
137
  sheetHeight.setValue(proposedHeight);
127
138
  },
128
- onPanResponderRelease: e => {
139
+ onPanResponderRelease: (e) => {
129
140
  const currentY = e.nativeEvent.pageY;
130
141
  const dy = currentY - dragStartYRef.current;
131
142
  const currentHeight = lastHeightRef.current - dy;
@@ -134,12 +145,14 @@ export const BottomSheetModal: React.FC<BottomSheetModalProps> = ({
134
145
  toValue: 0,
135
146
  duration: 200,
136
147
  useNativeDriver: false,
137
- }).start(() => onRequestClose({} as NativeSyntheticEvent<any>));
148
+ }).start(() =>
149
+ onRequestClose({} as NativeSyntheticEvent<any>)
150
+ );
138
151
  return;
139
152
  }
140
153
  const finalHeight = Math.min(
141
154
  Math.max(currentHeight, bottomSheetSize.minHeight),
142
- bottomSheetSize.maxHeight,
155
+ bottomSheetSize.maxHeight
143
156
  );
144
157
  Animated.spring(sheetHeight, {
145
158
  toValue: finalHeight,
@@ -159,7 +172,7 @@ export const BottomSheetModal: React.FC<BottomSheetModalProps> = ({
159
172
  }).start();
160
173
  },
161
174
  }),
162
- [bottomSheetSize, sheetHeight, onRequestClose],
175
+ [bottomSheetSize, sheetHeight, onRequestClose]
163
176
  );
164
177
  return (
165
178
  <Modal
@@ -168,56 +181,68 @@ export const BottomSheetModal: React.FC<BottomSheetModalProps> = ({
168
181
  animationType="slide"
169
182
  onRequestClose={onRequestClose}
170
183
  statusBarTranslucent={statusBarTranslucent}
171
- {...props}>
172
- <View
173
- testID="countrySelectContainer"
174
- style={[styles.container, countrySelectStyle?.container]}
175
- onLayout={e => setModalHeight(e.nativeEvent.layout.height)}>
176
- <Pressable
177
- testID="countrySelectBackdrop"
178
- accessibilityRole="button"
179
- accessibilityLabel={accessibilityLabelBackdrop}
180
- accessibilityHint={accessibilityHintBackdrop}
181
- disabled={disabledBackdropPress || removedBackdrop}
182
- style={[
183
- styles.backdrop,
184
- countrySelectStyle?.backdrop,
185
- removedBackdrop && {backgroundColor: 'transparent'},
186
- ]}
187
- onPress={onBackdropPress || onRequestClose}
188
- />
189
- <Animated.View
190
- testID="countrySelectContent"
191
- style={[
192
- styles.content,
193
- countrySelectStyle?.content,
194
- {
195
- height: sheetHeight,
196
- },
197
- ]}>
184
+ {...props}
185
+ >
186
+ <SafeAreaProvider>
187
+ <SafeAreaView style={{ flex: 1 }}>
198
188
  <View
199
- {...panHandlers.panHandlers}
200
- style={[
201
- styles.dragHandleContainer,
202
- countrySelectStyle?.dragHandleContainer,
203
- ]}>
204
- {dragHandleIndicatorComponent ? (
205
- dragHandleIndicatorComponent()
206
- ) : (
189
+ testID="countrySelectContainer"
190
+ style={[styles.container, countrySelectStyle?.container]}
191
+ onLayout={(e) =>
192
+ setModalHeight(e.nativeEvent.layout.height)
193
+ }
194
+ >
195
+ <Pressable
196
+ testID="countrySelectBackdrop"
197
+ accessibilityRole="button"
198
+ accessibilityLabel={accessibilityLabelBackdrop}
199
+ accessibilityHint={accessibilityHintBackdrop}
200
+ disabled={disabledBackdropPress || removedBackdrop}
201
+ style={[
202
+ styles.backdrop,
203
+ countrySelectStyle?.backdrop,
204
+ removedBackdrop && { backgroundColor: 'transparent' },
205
+ ]}
206
+ onPress={onBackdropPress || onRequestClose}
207
+ />
208
+ <Animated.View
209
+ testID="countrySelectContent"
210
+ style={[
211
+ styles.content,
212
+ countrySelectStyle?.content,
213
+ {
214
+ height: sheetHeight,
215
+ },
216
+ ]}
217
+ >
207
218
  <View
219
+ {...panHandlers.panHandlers}
208
220
  style={[
209
- styles.dragHandleIndicator,
210
- countrySelectStyle?.dragHandleIndicator,
221
+ styles.dragHandleContainer,
222
+ countrySelectStyle?.dragHandleContainer,
211
223
  ]}
212
- />
213
- )}
224
+ >
225
+ {dragHandleIndicatorComponent ? (
226
+ dragHandleIndicatorComponent()
227
+ ) : (
228
+ <View
229
+ style={[
230
+ styles.dragHandleIndicator,
231
+ countrySelectStyle?.dragHandleIndicator,
232
+ ]}
233
+ />
234
+ )}
235
+ </View>
236
+ {header}
237
+ <Animated.View
238
+ style={{ flex: 1, flexDirection: 'row' }}
239
+ >
240
+ {children}
241
+ </Animated.View>
242
+ </Animated.View>
214
243
  </View>
215
- {header}
216
- <Animated.View style={{flex: 1, flexDirection: 'row'}}>
217
- {children}
218
- </Animated.View>
219
- </Animated.View>
220
- </View>
244
+ </SafeAreaView>
245
+ </SafeAreaProvider>
221
246
  </Modal>
222
247
  );
223
248
  };
@@ -7,8 +7,12 @@ import {
7
7
  Pressable,
8
8
  View,
9
9
  } from 'react-native';
10
+ import {
11
+ SafeAreaProvider,
12
+ SafeAreaView,
13
+ } from 'react-native-safe-area-context';
10
14
 
11
- import {ICountrySelectStyle} from '../../interface';
15
+ import { ICountrySelectStyle } from '../../interface';
12
16
 
13
17
  interface FullscreenModalProps extends ModalProps {
14
18
  visible: boolean;
@@ -47,39 +51,48 @@ export const FullscreenModal: React.FC<FullscreenModalProps> = ({
47
51
  animationType="fade"
48
52
  onRequestClose={onRequestClose}
49
53
  statusBarTranslucent={statusBarTranslucent}
50
- {...props}>
51
- <View
52
- testID="countrySelectContainer"
53
- style={[
54
- styles.container,
55
- countrySelectStyle?.container,
56
- {flex: 1, width: '100%', height: '100%'},
57
- ]}>
58
- <Pressable
59
- testID="countrySelectBackdrop"
60
- accessibilityRole="button"
61
- accessibilityLabel={accessibilityLabelBackdrop}
62
- accessibilityHint={accessibilityHintBackdrop}
63
- disabled={disabledBackdropPress || removedBackdrop}
64
- style={[
65
- styles.backdrop,
66
- {alignItems: 'center', justifyContent: 'center'},
67
- countrySelectStyle?.backdrop,
68
- removedBackdrop && {backgroundColor: 'transparent'},
69
- ]}
70
- onPress={onBackdropPress || onRequestClose}
71
- />
72
- <View
73
- testID="countrySelectContent"
74
- style={[
75
- styles.content,
76
- countrySelectStyle?.content,
77
- {borderRadius: 0, width: '100%', height: '100%'},
78
- ]}>
79
- {header}
80
- <View style={{flex: 1, flexDirection: 'row'}}>{children}</View>
81
- </View>
82
- </View>
54
+ {...props}
55
+ >
56
+ <SafeAreaProvider>
57
+ <SafeAreaView style={{ flex: 1 }}>
58
+ <View
59
+ testID="countrySelectContainer"
60
+ style={[
61
+ styles.container,
62
+ countrySelectStyle?.container,
63
+ { flex: 1, width: '100%', height: '100%' },
64
+ ]}
65
+ >
66
+ <Pressable
67
+ testID="countrySelectBackdrop"
68
+ accessibilityRole="button"
69
+ accessibilityLabel={accessibilityLabelBackdrop}
70
+ accessibilityHint={accessibilityHintBackdrop}
71
+ disabled={disabledBackdropPress || removedBackdrop}
72
+ style={[
73
+ styles.backdrop,
74
+ { alignItems: 'center', justifyContent: 'center' },
75
+ countrySelectStyle?.backdrop,
76
+ removedBackdrop && { backgroundColor: 'transparent' },
77
+ ]}
78
+ onPress={onBackdropPress || onRequestClose}
79
+ />
80
+ <View
81
+ testID="countrySelectContent"
82
+ style={[
83
+ styles.content,
84
+ countrySelectStyle?.content,
85
+ { borderRadius: 0, width: '100%', height: '100%' },
86
+ ]}
87
+ >
88
+ {header}
89
+ <View style={{ flex: 1, flexDirection: 'row' }}>
90
+ {children}
91
+ </View>
92
+ </View>
93
+ </View>
94
+ </SafeAreaView>
95
+ </SafeAreaProvider>
83
96
  </Modal>
84
97
  );
85
98
  };
@@ -7,8 +7,12 @@ import {
7
7
  Pressable,
8
8
  View,
9
9
  } from 'react-native';
10
+ import {
11
+ SafeAreaProvider,
12
+ SafeAreaView,
13
+ } from 'react-native-safe-area-context';
10
14
 
11
- import {ICountrySelectStyle} from '../../interface';
15
+ import { ICountrySelectStyle } from '../../interface';
12
16
 
13
17
  interface PopupModalProps extends ModalProps {
14
18
  visible: boolean;
@@ -47,31 +51,40 @@ export const PopupModal: React.FC<PopupModalProps> = ({
47
51
  animationType="fade"
48
52
  onRequestClose={onRequestClose}
49
53
  statusBarTranslucent={statusBarTranslucent}
50
- {...props}>
51
- <View
52
- testID="countrySelectContainer"
53
- style={[styles.container, countrySelectStyle?.container]}>
54
- <Pressable
55
- testID="countrySelectBackdrop"
56
- accessibilityRole="button"
57
- accessibilityLabel={accessibilityLabelBackdrop}
58
- accessibilityHint={accessibilityHintBackdrop}
59
- disabled={disabledBackdropPress || removedBackdrop}
60
- style={[
61
- styles.backdrop,
62
- {alignItems: 'center', justifyContent: 'center'},
63
- countrySelectStyle?.backdrop,
64
- removedBackdrop && {backgroundColor: 'transparent'},
65
- ]}
66
- onPress={onBackdropPress || onRequestClose}
67
- />
68
- <View
69
- testID="countrySelectContent"
70
- style={[styles.content, countrySelectStyle?.content]}>
71
- {header}
72
- <View style={{flex: 1, flexDirection: 'row'}}>{children}</View>
73
- </View>
74
- </View>
54
+ {...props}
55
+ >
56
+ <SafeAreaProvider>
57
+ <SafeAreaView style={{ flex: 1 }}>
58
+ <View
59
+ testID="countrySelectContainer"
60
+ style={[styles.container, countrySelectStyle?.container]}
61
+ >
62
+ <Pressable
63
+ testID="countrySelectBackdrop"
64
+ accessibilityRole="button"
65
+ accessibilityLabel={accessibilityLabelBackdrop}
66
+ accessibilityHint={accessibilityHintBackdrop}
67
+ disabled={disabledBackdropPress || removedBackdrop}
68
+ style={[
69
+ styles.backdrop,
70
+ { alignItems: 'center', justifyContent: 'center' },
71
+ countrySelectStyle?.backdrop,
72
+ removedBackdrop && { backgroundColor: 'transparent' },
73
+ ]}
74
+ onPress={onBackdropPress || onRequestClose}
75
+ />
76
+ <View
77
+ testID="countrySelectContent"
78
+ style={[styles.content, countrySelectStyle?.content]}
79
+ >
80
+ {header}
81
+ <View style={{ flex: 1, flexDirection: 'row' }}>
82
+ {children}
83
+ </View>
84
+ </View>
85
+ </View>
86
+ </SafeAreaView>
87
+ </SafeAreaProvider>
75
88
  </Modal>
76
89
  );
77
90
  };
@@ -1,4 +1,4 @@
1
- import {Platform, StatusBar, StyleSheet} from 'react-native';
1
+ import { Platform, StyleSheet } from 'react-native';
2
2
 
3
3
  export const createStyles = (theme, modalType, isFullScreen) =>
4
4
  StyleSheet.create({
@@ -23,7 +23,6 @@ export const createStyles = (theme, modalType, isFullScreen) =>
23
23
  content:
24
24
  modalType === 'popup' || isFullScreen
25
25
  ? {
26
- marginTop: StatusBar.currentHeight,
27
26
  width: '90%',
28
27
  maxWidth: 600,
29
28
  height: '60%',
@@ -32,7 +31,6 @@ export const createStyles = (theme, modalType, isFullScreen) =>
32
31
  paddingVertical: 16,
33
32
  }
34
33
  : {
35
- marginTop: StatusBar.currentHeight,
36
34
  width: '100%',
37
35
  borderTopLeftRadius: 20,
38
36
  borderTopRightRadius: 20,
@@ -44941,6 +44941,10 @@
44941
44941
  "official": "Amerika Birle\u015fik Devletleri K\u00fc\u00e7\u00fck D\u0131\u015f Adalar\u0131",
44942
44942
  "common": "Amerika Birle\u015fik Devletleri K\u00fc\u00e7\u00fck D\u0131\u015f Adalar\u0131"
44943
44943
  },
44944
+ "ukr": {
44945
+ "official": "\u041c\u0430\u043b\u0456\u0020\u0432\u0456\u0434\u0434\u0430\u043b\u0435\u043d\u0456\u0020\u043e\u0441\u0442\u0440\u043e\u0432\u0438\u0020\u0421\u0428\u0410",
44946
+ "common": "\u041c\u0430\u043b\u0456\u0020\u0432\u0456\u0434\u0434\u0430\u043b\u0435\u043d\u0456\u0020\u043e\u0441\u0442\u0440\u043e\u0432\u0438\u0020\u0421\u0428\u0410"
44947
+ },
44944
44948
  "urd": {
44945
44949
  "official": "\u0627\u0645\u0631\u06cc\u06a9\u06cc \u0686\u06be\u0648\u0679\u06d2 \u0628\u06cc\u0631\u0648\u0646\u06cc \u062c\u0632\u0627\u0626\u0631",
44946
44950
  "common": "\u0627\u0645\u0631\u06cc\u06a9\u06cc \u0686\u06be\u0648\u0679\u06d2 \u0628\u06cc\u0631\u0648\u0646\u06cc \u062c\u0632\u0627\u0626\u0631"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-country-select",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "šŸŒ React Native country picker with flags, search, TypeScript, i18n, and offline support. Lightweight, customizable, and designed with a modern UI.",
5
5
  "main": "lib/index.tsx",
6
6
  "types": "lib/index.d.ts",
@@ -26,6 +26,9 @@
26
26
  "react native country picker",
27
27
  "react native country select"
28
28
  ],
29
+ "scripts": {
30
+ "postinstall": "node scripts/install-react-native-safe-area-context.js"
31
+ },
29
32
  "repository": {
30
33
  "type": "git",
31
34
  "url": "git+https://github.com/AstrOOnauta/react-native-country-select.git"
@@ -39,10 +42,14 @@
39
42
  "publishConfig": {
40
43
  "registry": "https://registry.npmjs.org/"
41
44
  },
42
- "dependencies": {},
43
- "devDependencies": {},
44
45
  "peerDependencies": {
45
46
  "react": "*",
46
- "react-native": "*"
47
+ "react-native": "*",
48
+ "react-native-safe-area-context": ">=4.0.0"
49
+ },
50
+ "peerDependenciesMeta": {
51
+ "react-native-safe-area-context": {
52
+ "optional": false
53
+ }
47
54
  }
48
55
  }
@@ -0,0 +1,84 @@
1
+ const { execSync } = require('child_process');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ // Navigate to the project root directory (outside node_modules)
6
+ function findProjectRoot() {
7
+ let current = process.cwd();
8
+
9
+ // If we're inside node_modules, go up until we're out
10
+ while (current.includes('node_modules')) {
11
+ current = path.dirname(current);
12
+ }
13
+
14
+ // Look for the project's package.json
15
+ while (!fs.existsSync(path.join(current, 'package.json'))) {
16
+ const next = path.dirname(current);
17
+ if (next === current) break;
18
+ current = next;
19
+ }
20
+
21
+ return current;
22
+ }
23
+
24
+ const root = findProjectRoot();
25
+ process.chdir(root);
26
+
27
+ // Check if react-native-safe-area-context is already installed
28
+ function isPackageInstalled() {
29
+ const packagePath = path.join(
30
+ root,
31
+ 'node_modules',
32
+ 'react-native-safe-area-context'
33
+ );
34
+
35
+ if (fs.existsSync(packagePath)) {
36
+ console.log(
37
+ 'āœ… react-native-safe-area-context is already installed!\n'
38
+ );
39
+ return true;
40
+ }
41
+
42
+ return false;
43
+ }
44
+
45
+ // If already installed, do nothing
46
+ if (isPackageInstalled()) {
47
+ process.exit(0);
48
+ }
49
+
50
+ function detectPackageManager() {
51
+ if (fs.existsSync(path.join(root, 'bun.lockb'))) return 'bun';
52
+ if (fs.existsSync(path.join(root, 'pnpm-lock.yaml'))) return 'pnpm';
53
+ if (fs.existsSync(path.join(root, 'yarn.lock'))) return 'yarn';
54
+ return 'npm';
55
+ }
56
+
57
+ const pm = detectPackageManager();
58
+
59
+ const commands = {
60
+ npm: 'npm install react-native-safe-area-context@latest --save',
61
+ yarn: 'yarn add react-native-safe-area-context@latest',
62
+ pnpm: 'pnpm add react-native-safe-area-context@latest',
63
+ bun: 'bun add react-native-safe-area-context@latest',
64
+ };
65
+
66
+ const command = commands[pm] || commands.npm;
67
+
68
+ try {
69
+ console.log(`\nšŸ”§ Detected package manager: ${pm}`);
70
+ console.log(`šŸ“¦ Installing react-native-safe-area-context using:`);
71
+ console.log(`āž”ļø ${command}\n`);
72
+
73
+ execSync(command, { stdio: 'inherit' });
74
+
75
+ console.log(
76
+ `\nāœ… react-native-safe-area-context installed successfully!\n`
77
+ );
78
+ } catch (err) {
79
+ console.error(
80
+ '\nāš ļø Could not automatically install react-native-safe-area-context'
81
+ );
82
+ console.error('Please install it manually by running:\n');
83
+ console.error(` ${command}\n`);
84
+ }