@sanctum-key/react-native-sdk 1.0.23 → 1.0.25

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.
Files changed (76) hide show
  1. package/build/package.json +3 -1
  2. package/build/src/components/EnhancedCameraView.d.ts +7 -1
  3. package/build/src/components/EnhancedCameraView.d.ts.map +1 -1
  4. package/build/src/components/EnhancedCameraView.js +88 -30
  5. package/build/src/components/EnhancedCameraView.js.map +1 -1
  6. package/build/src/components/EnhancedCameraView.web.d.ts +5 -1
  7. package/build/src/components/EnhancedCameraView.web.d.ts.map +1 -1
  8. package/build/src/components/EnhancedCameraView.web.js +80 -295
  9. package/build/src/components/EnhancedCameraView.web.js.map +1 -1
  10. package/build/src/components/KYCElements/CameraCapture.js +1 -1
  11. package/build/src/components/KYCElements/CameraCapture.js.map +1 -1
  12. package/build/src/components/KYCElements/CountrySelection.d.ts.map +1 -1
  13. package/build/src/components/KYCElements/CountrySelection.js +38 -218
  14. package/build/src/components/KYCElements/CountrySelection.js.map +1 -1
  15. package/build/src/components/KYCElements/CountrySelectionTemplate.d.ts.map +1 -1
  16. package/build/src/components/KYCElements/CountrySelectionTemplate.js +119 -26
  17. package/build/src/components/KYCElements/CountrySelectionTemplate.js.map +1 -1
  18. package/build/src/components/KYCElements/IDCardCapture.d.ts.map +1 -1
  19. package/build/src/components/KYCElements/IDCardCapture.js +512 -87
  20. package/build/src/components/KYCElements/IDCardCapture.js.map +1 -1
  21. package/build/src/components/KYCElements/VerificationProgressTemplate.d.ts.map +1 -1
  22. package/build/src/components/KYCElements/VerificationProgressTemplate.js +93 -51
  23. package/build/src/components/KYCElements/VerificationProgressTemplate.js.map +1 -1
  24. package/build/src/components/OverLay/type.d.ts +1 -0
  25. package/build/src/components/OverLay/type.d.ts.map +1 -1
  26. package/build/src/components/OverLay/type.js.map +1 -1
  27. package/build/src/components/WebBarcodeScanner.d.ts +9 -0
  28. package/build/src/components/WebBarcodeScanner.d.ts.map +1 -0
  29. package/build/src/components/WebBarcodeScanner.js +152 -0
  30. package/build/src/components/WebBarcodeScanner.js.map +1 -0
  31. package/build/src/config/KYCConfigs.js +2 -2
  32. package/build/src/config/KYCConfigs.js.map +1 -1
  33. package/build/src/config/region_mapping.js +14 -14
  34. package/build/src/config/region_mapping.js.map +1 -1
  35. package/build/src/config/region_mapping.json +0 -14
  36. package/build/src/modules/api/CardAuthentification.d.ts +2 -0
  37. package/build/src/modules/api/CardAuthentification.d.ts.map +1 -1
  38. package/build/src/modules/api/CardAuthentification.js +23 -40
  39. package/build/src/modules/api/CardAuthentification.js.map +1 -1
  40. package/build/src/modules/api/KYCService.d.ts +7 -2
  41. package/build/src/modules/api/KYCService.d.ts.map +1 -1
  42. package/build/src/modules/api/KYCService.js +163 -57
  43. package/build/src/modules/api/KYCService.js.map +1 -1
  44. package/build/src/types/KYC.types.d.ts +1 -0
  45. package/build/src/types/KYC.types.d.ts.map +1 -1
  46. package/build/src/types/KYC.types.js.map +1 -1
  47. package/build/src/utils/aamvaParser.d.ts +62 -0
  48. package/build/src/utils/aamvaParser.d.ts.map +1 -0
  49. package/build/src/utils/aamvaParser.js +91 -0
  50. package/build/src/utils/aamvaParser.js.map +1 -0
  51. package/build/src/utils/cropByObb.d.ts.map +1 -1
  52. package/build/src/utils/cropByObb.js +4 -3
  53. package/build/src/utils/cropByObb.js.map +1 -1
  54. package/build/src/web/WebKYCEntry.d.ts +1 -1
  55. package/build/src/web/WebKYCEntry.d.ts.map +1 -1
  56. package/build/src/web/WebKYCEntry.js +105 -239
  57. package/build/src/web/WebKYCEntry.js.map +1 -1
  58. package/package.json +3 -1
  59. package/src/components/EnhancedCameraView.tsx +116 -42
  60. package/src/components/EnhancedCameraView.web.tsx +98 -338
  61. package/src/components/KYCElements/CameraCapture.tsx +1 -1
  62. package/src/components/KYCElements/CountrySelection.tsx +60 -240
  63. package/src/components/KYCElements/CountrySelectionTemplate.tsx +148 -29
  64. package/src/components/KYCElements/IDCardCapture.tsx +675 -142
  65. package/src/components/KYCElements/VerificationProgressTemplate.tsx +112 -65
  66. package/src/components/OverLay/type.ts +1 -1
  67. package/src/components/WebBarcodeScanner.tsx +273 -0
  68. package/src/config/KYCConfigs.ts +2 -2
  69. package/src/config/region_mapping.json +0 -14
  70. package/src/config/region_mapping.ts +14 -14
  71. package/src/modules/api/CardAuthentification.ts +44 -58
  72. package/src/modules/api/KYCService.ts +236 -82
  73. package/src/types/KYC.types.ts +1 -0
  74. package/src/utils/aamvaParser.ts +102 -0
  75. package/src/utils/cropByObb.ts +5 -3
  76. package/src/web/WebKYCEntry.tsx +125 -301
@@ -1,12 +1,5 @@
1
1
  import React, { useState, useMemo } from 'react';
2
- import {
3
- View,
4
- Text,
5
- TouchableOpacity,
6
- StyleSheet,
7
- FlatList,
8
- TextInput
9
- } from 'react-native';
2
+ import { View, Text, TouchableOpacity, StyleSheet, FlatList, TextInput } from 'react-native';
10
3
  import { KYCElement, KYCElementOption } from '../../types/KYC.types';
11
4
 
12
5
  interface CountrySelectionProps {
@@ -16,255 +9,74 @@ interface CountrySelectionProps {
16
9
  error?: string;
17
10
  }
18
11
 
19
- // 🌍 Comprehensive Global Country List
20
- const ALL_COUNTRIES: KYCElementOption[] = [
21
- { value: 'AF', label: 'Afghanistan', icon: '🇦🇫' },
22
- { value: 'AL', label: 'Albania', icon: '🇦🇱' },
23
- { value: 'DZ', label: 'Algeria', icon: '🇩🇿' },
24
- { value: 'AD', label: 'Andorra', icon: '🇦🇩' },
25
- { value: 'AO', label: 'Angola', icon: '🇦🇴' },
26
- { value: 'AR', label: 'Argentina', icon: '🇦🇷' },
27
- { value: 'AM', label: 'Armenia', icon: '🇦🇲' },
28
- { value: 'AU', label: 'Australia', icon: '🇦🇺' },
29
- { value: 'AT', label: 'Austria', icon: '🇦🇹' },
30
- { value: 'AZ', label: 'Azerbaijan', icon: '🇦🇿' },
31
- { value: 'BS', label: 'Bahamas', icon: '🇧🇸' },
32
- { value: 'BH', label: 'Bahrain', icon: '🇧🇭' },
33
- { value: 'BD', label: 'Bangladesh', icon: '🇧🇩' },
34
- { value: 'BB', label: 'Barbados', icon: '🇧🇧' },
35
- { value: 'BY', label: 'Belarus', icon: '🇧🇾' },
36
- { value: 'BE', label: 'Belgium', icon: '🇧🇪' },
37
- { value: 'BZ', label: 'Belize', icon: '🇧🇿' },
38
- { value: 'BJ', label: 'Benin', icon: '🇧🇯' },
39
- { value: 'BT', label: 'Bhutan', icon: '🇧🇹' },
40
- { value: 'BO', label: 'Bolivia', icon: '🇧🇴' },
41
- { value: 'BA', label: 'Bosnia and Herzegovina', icon: '🇧🇦' },
42
- { value: 'BW', label: 'Botswana', icon: '🇧🇼' },
43
- { value: 'BR', label: 'Brazil', icon: '🇧🇷' },
44
- { value: 'BN', label: 'Brunei', icon: '🇧🇳' },
45
- { value: 'BG', label: 'Bulgaria', icon: '🇧🇬' },
46
- { value: 'BF', label: 'Burkina Faso', icon: '🇧🇫' },
47
- { value: 'BI', label: 'Burundi', icon: '🇧🇮' },
48
- { value: 'CV', label: 'Cabo Verde', icon: '🇨🇻' },
49
- { value: 'KH', label: 'Cambodia', icon: '🇰🇭' },
50
- { value: 'CM', label: 'Cameroon', icon: '🇨🇲' },
51
- { value: 'CA', label: 'Canada', icon: '🇨🇦' },
52
- { value: 'CF', label: 'Central African Republic', icon: '🇨🇫' },
53
- { value: 'TD', label: 'Chad', icon: '🇹🇩' },
54
- { value: 'CL', label: 'Chile', icon: '🇨🇱' },
55
- { value: 'CN', label: 'China', icon: '🇨🇳' },
56
- { value: 'CO', label: 'Colombia', icon: '🇨🇴' },
57
- { value: 'KM', label: 'Comoros', icon: '🇰🇲' },
58
- { value: 'CG', label: 'Congo', icon: '🇨🇬' },
59
- { value: 'CD', label: 'Congo (DRC)', icon: '🇨🇩' },
60
- { value: 'CR', label: 'Costa Rica', icon: '🇨🇷' },
61
- { value: 'HR', label: 'Croatia', icon: '🇭🇷' },
62
- { value: 'CU', label: 'Cuba', icon: '🇨🇺' },
63
- { value: 'CY', label: 'Croatia', icon: '🇨🇾' },
64
- { value: 'CZ', label: 'Czechia', icon: '🇨🇿' },
65
- { value: 'DK', label: 'Denmark', icon: '🇩🇰' },
66
- { value: 'DJ', label: 'Djibouti', icon: '🇩🇯' },
67
- { value: 'DM', label: 'Dominica', icon: '🇩🇲' },
68
- { value: 'DO', label: 'Dominican Republic', icon: '🇩🇴' },
69
- { value: 'EC', label: 'Ecuador', icon: '🇪🇨' },
70
- { value: 'EG', label: 'Egypt', icon: '🇪🇬' },
71
- { value: 'SV', label: 'El Salvador', icon: '🇸🇻' },
72
- { value: 'GQ', label: 'Equatorial Guinea', icon: '🇬🇶' },
73
- { value: 'ER', label: 'Eritrea', icon: '🇪🇷' },
74
- { value: 'EE', label: 'Estonia', icon: '🇪🇪' },
75
- { value: 'SZ', label: 'Eswatini', icon: '🇸🇿' },
76
- { value: 'ET', label: 'Ethiopia', icon: '🇪🇹' },
77
- { value: 'FJ', label: 'Fiji', icon: '🇫🇯' },
78
- { value: 'FI', label: 'Finland', icon: '🇫🇮' },
79
- { value: 'FR', label: 'France', icon: '🇫🇷' },
80
- { value: 'GA', label: 'Gabon', icon: '🇬🇦' },
81
- { value: 'GM', label: 'Gambia', icon: '🇬🇲' },
82
- { value: 'GE', label: 'Georgia', icon: '🇬🇪' },
83
- { value: 'DE', label: 'Germany', icon: '🇩🇪' },
84
- { value: 'GH', label: 'Ghana', icon: '🇬🇭' },
85
- { value: 'GR', label: 'Greece', icon: '🇬🇷' },
86
- { value: 'GD', label: 'Grenada', icon: '🇬🇩' },
87
- { value: 'GT', label: 'Guatemala', icon: '🇬🇹' },
88
- { value: 'GN', label: 'Guinea', icon: '🇬🇳' },
89
- { value: 'GW', label: 'Guinea-Bissau', icon: '🇬🇼' },
90
- { value: 'GY', label: 'Guyana', icon: '🇬🇾' },
91
- { value: 'HT', label: 'Haiti', icon: '🇭🇹' },
92
- { value: 'HN', label: 'Honduras', icon: '🇭🇳' },
93
- { value: 'HU', label: 'Hungary', icon: '🇭🇺' },
94
- { value: 'IS', label: 'Iceland', icon: '🇮🇸' },
95
- { value: 'IN', label: 'India', icon: '🇮🇳' },
96
- { value: 'ID', label: 'Indonesia', icon: '🇮🇩' },
97
- { value: 'IR', label: 'Iran', icon: '🇮🇷' },
98
- { value: 'IQ', label: 'Iraq', icon: '🇮🇶' },
99
- { value: 'IE', label: 'Ireland', icon: '🇮🇪' },
100
- { value: 'IL', label: 'Ireland', icon: '🇮🇪' },
101
- { value: 'IT', label: 'Italy', icon: '🇮🇹' },
102
- { value: 'JM', label: 'Jamaica', icon: '🇯🇲' },
103
- { value: 'JP', label: 'Japan', icon: '🇯🇵' },
104
- { value: 'JO', label: 'Jordan', icon: '🇯🇴' },
105
- { value: 'KZ', label: 'Kazakhstan', icon: '🇰🇿' },
106
- { value: 'KE', label: 'Kenya', icon: '🇰🇪' },
107
- { value: 'KI', label: 'Kiribati', icon: '🇰🇮' },
108
- { value: 'KP', label: 'Korea (North)', icon: '🇰🇵' },
109
- { value: 'KR', label: 'Korea (South)', icon: '🇰🇷' },
110
- { value: 'KW', label: 'Kuwait', icon: '🇰🇼' },
111
- { value: 'KG', label: 'Kyrgyzstan', icon: '🇰🇬' },
112
- { value: 'LA', label: 'Laos', icon: '🇱🇦' },
113
- { value: 'LV', label: 'Latvia', icon: '🇱🇻' },
114
- { value: 'LB', label: 'Lebanon', icon: '🇱🇧' },
115
- { value: 'LS', label: 'Lesotho', icon: '🇱🇸' },
116
- { value: 'LR', label: 'Liberia', icon: '🇱🇷' },
117
- { value: 'LY', label: 'Libya', icon: '🇱🇾' },
118
- { value: 'LI', label: 'Liechtenstein', icon: '🇱🇮' },
119
- { value: 'LT', label: 'Lithuania', icon: '🇱🇹' },
120
- { value: 'LU', label: 'Luxembourg', icon: '🇱🇺' },
121
- { value: 'MG', label: 'Madagascar', icon: '🇲🇬' },
122
- { value: 'MW', label: 'Malawi', icon: '🇲🇼' },
123
- { value: 'MY', label: 'Malaysia', icon: '🇲🇾' },
124
- { value: 'MV', label: 'Maldives', icon: '🇲🇻' },
125
- { value: 'ML', label: 'Mali', icon: '🇲🇱' },
126
- { value: 'MT', label: 'Malta', icon: '🇲🇹' },
127
- { value: 'MH', label: 'Marshall Islands', icon: '🇲🇭' },
128
- { value: 'MR', label: 'Mauritania', icon: '🇲🇷' },
129
- { value: 'MU', label: 'Mauritius', icon: '🇲🇺' },
130
- { value: 'MX', label: 'Mexico', icon: '🇲🇽' },
131
- { value: 'FM', label: 'Micronesia', icon: '🇫🇲' },
132
- { value: 'MD', label: 'Moldova', icon: '🇲🇩' },
133
- { value: 'MC', label: 'Monaco', icon: '🇲🇨' },
134
- { value: 'MN', label: 'Mongolia', icon: '🇲🇳' },
135
- { value: 'ME', label: 'Montenegro', icon: '🇲🇪' },
136
- { value: 'MA', label: 'Morocco', icon: '🇲🇦' },
137
- { value: 'MZ', label: 'Mozambique', icon: '🇲🇿' },
138
- { value: 'MM', label: 'Myanmar', icon: '🇲🇲' },
139
- { value: 'NA', label: 'Namibia', icon: '🇳🇦' },
140
- { value: 'NR', label: 'Nauru', icon: '🇳🇷' },
141
- { value: 'NP', label: 'Nepal', icon: '🇳🇵' },
142
- { value: 'NL', label: 'Netherlands', icon: '🇳🇱' },
143
- { value: 'NZ', label: 'New Zealand', icon: '🇳🇿' },
144
- { value: 'NI', label: 'Nicaragua', icon: '🇳🇮' },
145
- { value: 'NE', label: 'Niger', icon: '🇳🇪' },
146
- { value: 'NG', label: 'Nigeria', icon: '🇳🇬' },
147
- { value: 'MK', label: 'North Macedonia', icon: '🇲🇰' },
148
- { value: 'NO', label: 'Norway', icon: '🇳🇴' },
149
- { value: 'OM', label: 'Oman', icon: '🇴🇲' },
150
- { value: 'PK', label: 'Pakistan', icon: '🇵🇰' },
151
- { value: 'PW', label: 'Palau', icon: '🇵🇼' },
152
- { value: 'PA', label: 'Panama', icon: '🇵🇦' },
153
- { value: 'PG', label: 'Papua New Guinea', icon: '🇵🇬' },
154
- { value: 'PY', label: 'Paraguay', icon: '🇵🇾' },
155
- { value: 'PE', label: 'Peru', icon: '🇵🇪' },
156
- { value: 'PH', label: 'Philippines', icon: '🇵🇭' },
157
- { value: 'PL', label: 'Poland', icon: '🇵🇱' },
158
- { value: 'PT', label: 'Portugal', icon: '🇵🇹' },
159
- { value: 'QA', label: 'Qatar', icon: '🇶🇦' },
160
- { value: 'RO', label: 'Romania', icon: '🇷🇴' },
161
- { value: 'RU', label: 'Russia', icon: '🇷🇺' },
162
- { value: 'RW', label: 'Rwanda', icon: '🇷🇼' },
163
- { value: 'WS', label: 'Samoa', icon: '🇼🇸' },
164
- { value: 'SM', label: 'San Marino', icon: '🇸🇲' },
165
- { value: 'ST', label: 'Sao Tome and Principe', icon: '🇸🇹' },
166
- { value: 'SA', label: 'Saudi Arabia', icon: '🇸🇦' },
167
- { value: 'SN', label: 'Senegal', icon: '🇸🇳' },
168
- { value: 'RS', label: 'Serbia', icon: '🇷🇸' },
169
- { value: 'SC', label: 'Seychelles', icon: '🇸🇨' },
170
- { value: 'SL', label: 'Sierra Leone', icon: '🇸🇱' },
171
- { value: 'SG', label: 'Singapore', icon: '🇸🇬' },
172
- { value: 'SK', label: 'Slovakia', icon: '🇸🇰' },
173
- { value: 'SI', label: 'Slovenia', icon: '🇸🇮' },
174
- { value: 'SB', label: 'Solomon Islands', icon: '🇸🇧' },
175
- { value: 'SO', label: 'Somalia', icon: '🇸🇴' },
176
- { value: 'ZA', label: 'South Africa', icon: '🇿🇦' },
177
- { value: 'ES', label: 'Spain', icon: '🇪🇸' },
178
- { value: 'LK', label: 'Sri Lanka', icon: '🇱🇰' },
179
- { value: 'SD', label: 'Sudan', icon: '🇸🇩' },
180
- { value: 'SR', label: 'Suriname', icon: '🇸🇷' },
181
- { value: 'SE', label: 'Sweden', icon: '🇸🇪' },
182
- { value: 'CH', label: 'Switzerland', icon: '🇨🇭' },
183
- { value: 'SY', label: 'Syria', icon: '🇸🇾' },
184
- { value: 'TW', label: 'Taiwan', icon: '🇹🇼' },
185
- { value: 'TJ', label: 'Tajikistan', icon: '🇹🇯' },
186
- { value: 'TZ', label: 'Tanzania', icon: '🇹🇿' },
187
- { value: 'TH', label: 'Thailand', icon: '🇹🇭' },
188
- { value: 'TL', label: 'Timor-Leste', icon: '🇹🇱' },
189
- { value: 'TG', label: 'Togo', icon: '🇹🇬' },
190
- { value: 'TO', label: 'Tonga', icon: '🇹🇴' },
191
- { value: 'TT', label: 'Trinidad and Tobago', icon: '🇹🇹' },
192
- { value: 'TN', label: 'Tunisia', icon: '🇹🇳' },
193
- { value: 'TR', label: 'Turkey', icon: '🇹🇷' },
194
- { value: 'TM', label: 'Turkmenistan', icon: '🇹🇲' },
195
- { value: 'TV', label: 'Tuvalu', icon: '🇹🇻' },
196
- { value: 'UG', label: 'Uganda', icon: '🇺🇬' },
197
- { value: 'UA', label: 'Ukraine', icon: '🇺🇦' },
198
- { value: 'AE', label: 'United Arab Emirates', icon: '🇦🇪' },
199
- { value: 'GB', label: 'United Kingdom', icon: '🇬🇧' },
200
- { value: 'US', label: 'United States', icon: '🇺🇸' },
201
- { value: 'UY', label: 'Uruguay', icon: '🇺🇾' },
202
- { value: 'UZ', label: 'Uzbekistan', icon: '🇺🇿' },
203
- { value: 'VU', label: 'Vanuatu', icon: '🇻🇺' },
204
- { value: 'VA', label: 'Vatican City', icon: '🇻🇦' },
205
- { value: 'VE', label: 'Venezuela', icon: '🇻🇪' },
206
- { value: 'VN', label: 'Vietnam', icon: '🇻🇳' },
207
- { value: 'YE', label: 'Yemen', icon: '🇾🇪' },
208
- { value: 'ZM', label: 'Zambia', icon: '🇿🇲' },
209
- { value: 'ZW', label: 'Zimbabwe', icon: '🇿🇼' },
210
- { value: 'OTHER', label: 'Other', icon: '🌍' },
211
- ];
212
-
213
12
  export const CountrySelection: React.FC<CountrySelectionProps> = ({
214
13
  element,
215
14
  value,
216
15
  onValueChange,
217
16
  error,
218
17
  }) => {
219
- // Use the massive list if the backend didn't supply specific options
220
- const countries = element.options && element.options.length > 0 ? element.options : ALL_COUNTRIES;
18
+ const countries = element.options || [];
19
+ console.log(`Countries options: ${countries}`)
20
+
221
21
  const [searchQuery, setSearchQuery] = useState('');
222
22
 
223
23
  // Filter countries based on user input
224
24
  const filteredCountries = useMemo(() => {
225
25
  if (!searchQuery.trim()) return countries;
226
26
  return countries.filter(country =>
227
- country.label.toLowerCase().includes(searchQuery.toLowerCase())
27
+ country.label.toLowerCase().includes(searchQuery.toLowerCase())
228
28
  );
229
29
  }, [countries, searchQuery]);
230
30
 
231
31
  // Extract the render logic into a separate function for FlatList performance
232
- const renderCountry = ({ item: country }: { item: KYCElementOption }) => (
233
- <TouchableOpacity
234
- style={[
235
- styles.option,
236
- value === country.value && styles.selectedOption
237
- ]}
238
- onPress={() => onValueChange(country.value)}
239
- activeOpacity={0.7}
240
- >
241
- <Text style={styles.optionIcon}>{country.icon}</Text>
242
- <View style={styles.optionContent}>
243
- <Text style={[
244
- styles.optionLabel,
245
- value === country.value && styles.selectedOptionLabel
246
- ]}>
247
- {country.label}
248
- </Text>
249
- {country.description && (
250
- <Text style={styles.optionDescription}>{country.description}</Text>
251
- )}
252
- </View>
253
- {value === country.value && (
254
- <View style={styles.checkmark}>
255
- <Text style={styles.checkmarkText}>✓</Text>
32
+ const renderCountry = ({ item: country }: { item: KYCElementOption }) => {
33
+ const isSelected = value === country.value;
34
+
35
+ return (
36
+ <TouchableOpacity
37
+ style={[
38
+ styles.option,
39
+ isSelected && styles.selectedOption
40
+ ]}
41
+ onPress={() => onValueChange(country.value)}
42
+ activeOpacity={0.7}
43
+ // Accessibility Enhancements
44
+ accessible={true}
45
+ accessibilityRole="button"
46
+ accessibilityState={{ selected: isSelected }}
47
+ accessibilityLabel={`${country.label}. ${isSelected ? 'Selected' : 'Unselected'}.`}
48
+ accessibilityHint={`Tap to select ${country.label} as your country`}
49
+ >
50
+ <Text style={styles.optionIcon}>{country.icon}</Text>
51
+
52
+ <View style={styles.optionContent}>
53
+ <Text style={[
54
+ styles.optionLabel,
55
+ isSelected && styles.selectedOptionLabel
56
+ ]}>
57
+ {country.label}
58
+ </Text>
59
+ {country.description && (
60
+ <Text style={styles.optionDescription}>{country.description}</Text>
61
+ )}
256
62
  </View>
257
- )}
258
- </TouchableOpacity>
259
- );
63
+
64
+ {isSelected && (
65
+ <View style={styles.checkmark}>
66
+ <Text style={styles.checkmarkText}>✓</Text>
67
+ </View>
68
+ )}
69
+ </TouchableOpacity>
70
+ );
71
+ };
260
72
 
261
73
  return (
262
74
  <View style={styles.container}>
263
75
  <View style={styles.headerContainer}>
264
- <Text style={styles.title}>{element.title}</Text>
76
+ <Text style={styles.title} accessibilityRole="header">{element.title}</Text>
265
77
  <Text style={styles.description}>{element.description}</Text>
266
78
 
267
- {/* Search Bar for better UX */}
79
+ {/* Search Bar */}
268
80
  <TextInput
269
81
  style={styles.searchInput}
270
82
  placeholder="Rechercher un pays..."
@@ -272,6 +84,10 @@ export const CountrySelection: React.FC<CountrySelectionProps> = ({
272
84
  value={searchQuery}
273
85
  onChangeText={setSearchQuery}
274
86
  clearButtonMode="while-editing" // Adds a clear 'x' on iOS
87
+ // Accessibility for Search
88
+ accessibilityRole="search"
89
+ accessibilityLabel="Search countries"
90
+ accessibilityHint="Type to filter the list of configured countries below"
275
91
  />
276
92
  </View>
277
93
 
@@ -279,20 +95,24 @@ export const CountrySelection: React.FC<CountrySelectionProps> = ({
279
95
  data={filteredCountries}
280
96
  keyExtractor={(item) => item.value}
281
97
  renderItem={renderCountry}
282
- showsVerticalScrollIndicator={false}
98
+ showsVerticalScrollIndicator={true} // Enable scroll indicator for better UX visibility
283
99
  contentContainerStyle={styles.listContent}
284
100
  keyboardShouldPersistTaps="handled"
101
+ keyboardDismissMode="on-drag" // 🚨 UX FIX: Hides keyboard naturally when user starts scrolling
285
102
  initialNumToRender={15}
286
103
  maxToRenderPerBatch={20}
287
104
  windowSize={5}
288
105
  removeClippedSubviews={true}
106
+ accessibilityRole="list"
289
107
  ListEmptyComponent={
290
- <Text style={styles.emptyText}>Aucun pays trouvé</Text>
108
+ <Text style={styles.emptyText} accessibilityRole="text">
109
+ Aucun pays configuré ou trouvé.
110
+ </Text>
291
111
  }
292
112
  />
293
113
 
294
114
  {error && (
295
- <Text style={styles.errorText}>{error}</Text>
115
+ <Text style={styles.errorText} accessibilityRole="alert">{error}</Text>
296
116
  )}
297
117
  </View>
298
118
  );
@@ -301,7 +121,7 @@ export const CountrySelection: React.FC<CountrySelectionProps> = ({
301
121
  const styles = StyleSheet.create({
302
122
  container: {
303
123
  flex: 1,
304
- backgroundColor: '#fff',
124
+ backgroundColor: '#fff',
305
125
  },
306
126
  headerContainer: {
307
127
  paddingHorizontal: 16,
@@ -334,7 +154,7 @@ const styles = StyleSheet.create({
334
154
  },
335
155
  listContent: {
336
156
  paddingHorizontal: 16,
337
- paddingBottom: 24,
157
+ paddingBottom: 24,
338
158
  },
339
159
  emptyText: {
340
160
  textAlign: 'center',
@@ -353,7 +173,7 @@ const styles = StyleSheet.create({
353
173
  borderColor: '#e5e5e5',
354
174
  shadowColor: '#000',
355
175
  shadowOffset: { width: 0, height: 2 },
356
- shadowOpacity: 0.05,
176
+ shadowOpacity: 0.05,
357
177
  shadowRadius: 3.84,
358
178
  elevation: 3,
359
179
  },