@oxyhq/services 5.7.5 → 5.8.1

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 (239) hide show
  1. package/README.md +76 -76
  2. package/lib/commonjs/core/index.js +177 -102
  3. package/lib/commonjs/core/index.js.map +1 -1
  4. package/lib/commonjs/index.js +88 -29
  5. package/lib/commonjs/index.js.map +1 -1
  6. package/lib/commonjs/node/createAuth.js +585 -7
  7. package/lib/commonjs/node/createAuth.js.map +1 -1
  8. package/lib/commonjs/node/index.js +38 -1
  9. package/lib/commonjs/node/index.js.map +1 -1
  10. package/lib/commonjs/ui/components/Avatar.js +15 -6
  11. package/lib/commonjs/ui/components/Avatar.js.map +1 -1
  12. package/lib/commonjs/ui/components/GroupedItem.js +58 -13
  13. package/lib/commonjs/ui/components/GroupedItem.js.map +1 -1
  14. package/lib/commonjs/ui/components/GroupedSection.js +7 -1
  15. package/lib/commonjs/ui/components/GroupedSection.js.map +1 -1
  16. package/lib/commonjs/ui/components/Header.js +322 -0
  17. package/lib/commonjs/ui/components/Header.js.map +1 -0
  18. package/lib/commonjs/ui/components/OxyProvider.js +23 -7
  19. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  20. package/lib/commonjs/ui/components/index.js +7 -0
  21. package/lib/commonjs/ui/components/index.js.map +1 -1
  22. package/lib/commonjs/ui/components/internal/GroupedPillButtons.js +1 -1
  23. package/lib/commonjs/ui/components/internal/GroupedPillButtons.js.map +1 -1
  24. package/lib/commonjs/ui/components/internal/TextField.js +606 -546
  25. package/lib/commonjs/ui/components/internal/TextField.js.map +1 -1
  26. package/lib/commonjs/ui/components/internal/TextField.md +436 -0
  27. package/lib/commonjs/ui/context/OxyContext.js +122 -78
  28. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  29. package/lib/commonjs/ui/hooks/useSessionSocket.js +5 -2
  30. package/lib/commonjs/ui/hooks/useSessionSocket.js.map +1 -1
  31. package/lib/commonjs/ui/navigation/OxyRouter.js +1 -1
  32. package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -1
  33. package/lib/commonjs/ui/screens/AccountCenterScreen.js +6 -6
  34. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
  35. package/lib/commonjs/ui/screens/AccountManagementDemo.js +3 -3
  36. package/lib/commonjs/ui/screens/AccountManagementDemo.js.map +1 -1
  37. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +241 -598
  38. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
  39. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +1151 -406
  40. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  41. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +135 -237
  42. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  43. package/lib/commonjs/ui/screens/AppInfoScreen.js +246 -463
  44. package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
  45. package/lib/commonjs/ui/screens/FeedbackScreen.js +3 -3
  46. package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
  47. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +808 -650
  48. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -1
  49. package/lib/commonjs/ui/screens/RecoverAccountScreen.js +51 -72
  50. package/lib/commonjs/ui/screens/RecoverAccountScreen.js.map +1 -1
  51. package/lib/commonjs/ui/screens/SessionManagementScreen.js +11 -29
  52. package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
  53. package/lib/commonjs/ui/screens/SignInScreen.js +30 -303
  54. package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
  55. package/lib/commonjs/ui/screens/SignUpScreen.js +4 -4
  56. package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -1
  57. package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +19 -31
  58. package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +1 -1
  59. package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +7 -10
  60. package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +1 -1
  61. package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js +11 -5
  62. package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js.map +1 -1
  63. package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js +11 -4
  64. package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js.map +1 -1
  65. package/lib/commonjs/ui/stores/authStore.js +12 -0
  66. package/lib/commonjs/ui/stores/authStore.js.map +1 -1
  67. package/lib/commonjs/ui/styles/authStyles.js +337 -0
  68. package/lib/commonjs/ui/styles/authStyles.js.map +1 -0
  69. package/lib/commonjs/ui/styles/index.js +11 -0
  70. package/lib/commonjs/ui/styles/index.js.map +1 -1
  71. package/lib/module/core/index.js +177 -41
  72. package/lib/module/core/index.js.map +1 -1
  73. package/lib/module/index.js +26 -4
  74. package/lib/module/index.js.map +1 -1
  75. package/lib/module/node/createAuth.js +584 -7
  76. package/lib/module/node/createAuth.js.map +1 -1
  77. package/lib/module/node/index.js +7 -1
  78. package/lib/module/node/index.js.map +1 -1
  79. package/lib/module/ui/components/Avatar.js +15 -6
  80. package/lib/module/ui/components/Avatar.js.map +1 -1
  81. package/lib/module/ui/components/GroupedItem.js +59 -14
  82. package/lib/module/ui/components/GroupedItem.js.map +1 -1
  83. package/lib/module/ui/components/GroupedSection.js +7 -1
  84. package/lib/module/ui/components/GroupedSection.js.map +1 -1
  85. package/lib/module/ui/components/Header.js +317 -0
  86. package/lib/module/ui/components/Header.js.map +1 -0
  87. package/lib/module/ui/components/OxyProvider.js +25 -9
  88. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  89. package/lib/module/ui/components/index.js +1 -0
  90. package/lib/module/ui/components/index.js.map +1 -1
  91. package/lib/module/ui/components/internal/GroupedPillButtons.js +1 -1
  92. package/lib/module/ui/components/internal/GroupedPillButtons.js.map +1 -1
  93. package/lib/module/ui/components/internal/TextField.js +607 -547
  94. package/lib/module/ui/components/internal/TextField.js.map +1 -1
  95. package/lib/module/ui/components/internal/TextField.md +436 -0
  96. package/lib/module/ui/context/OxyContext.js +121 -77
  97. package/lib/module/ui/context/OxyContext.js.map +1 -1
  98. package/lib/module/ui/hooks/useSessionSocket.js +5 -2
  99. package/lib/module/ui/hooks/useSessionSocket.js.map +1 -1
  100. package/lib/module/ui/navigation/OxyRouter.js +1 -1
  101. package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
  102. package/lib/module/ui/screens/AccountCenterScreen.js +6 -6
  103. package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
  104. package/lib/module/ui/screens/AccountManagementDemo.js +3 -3
  105. package/lib/module/ui/screens/AccountManagementDemo.js.map +1 -1
  106. package/lib/module/ui/screens/AccountOverviewScreen.js +242 -597
  107. package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
  108. package/lib/module/ui/screens/AccountSettingsScreen.js +1152 -407
  109. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  110. package/lib/module/ui/screens/AccountSwitcherScreen.js +135 -237
  111. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  112. package/lib/module/ui/screens/AppInfoScreen.js +248 -465
  113. package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
  114. package/lib/module/ui/screens/FeedbackScreen.js +3 -3
  115. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
  116. package/lib/module/ui/screens/PaymentGatewayScreen.js +809 -651
  117. package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
  118. package/lib/module/ui/screens/RecoverAccountScreen.js +53 -74
  119. package/lib/module/ui/screens/RecoverAccountScreen.js.map +1 -1
  120. package/lib/module/ui/screens/SessionManagementScreen.js +11 -29
  121. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
  122. package/lib/module/ui/screens/SignInScreen.js +32 -305
  123. package/lib/module/ui/screens/SignInScreen.js.map +1 -1
  124. package/lib/module/ui/screens/SignUpScreen.js +5 -5
  125. package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
  126. package/lib/module/ui/screens/internal/SignInPasswordStep.js +19 -31
  127. package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +1 -1
  128. package/lib/module/ui/screens/internal/SignInUsernameStep.js +7 -10
  129. package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +1 -1
  130. package/lib/module/ui/screens/internal/SignUpIdentityStep.js +11 -5
  131. package/lib/module/ui/screens/internal/SignUpIdentityStep.js.map +1 -1
  132. package/lib/module/ui/screens/internal/SignUpSecurityStep.js +11 -4
  133. package/lib/module/ui/screens/internal/SignUpSecurityStep.js.map +1 -1
  134. package/lib/module/ui/stores/authStore.js +12 -0
  135. package/lib/module/ui/stores/authStore.js.map +1 -1
  136. package/lib/module/ui/styles/authStyles.js +332 -0
  137. package/lib/module/ui/styles/authStyles.js.map +1 -0
  138. package/lib/module/ui/styles/index.js +1 -0
  139. package/lib/module/ui/styles/index.js.map +1 -1
  140. package/lib/typescript/core/index.d.ts +68 -24
  141. package/lib/typescript/core/index.d.ts.map +1 -1
  142. package/lib/typescript/index.d.ts +13 -3
  143. package/lib/typescript/index.d.ts.map +1 -1
  144. package/lib/typescript/node/createAuth.d.ts +112 -0
  145. package/lib/typescript/node/createAuth.d.ts.map +1 -1
  146. package/lib/typescript/node/index.d.ts +2 -0
  147. package/lib/typescript/node/index.d.ts.map +1 -1
  148. package/lib/typescript/ui/components/Avatar.d.ts.map +1 -1
  149. package/lib/typescript/ui/components/GroupedItem.d.ts +6 -0
  150. package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -1
  151. package/lib/typescript/ui/components/GroupedSection.d.ts +6 -0
  152. package/lib/typescript/ui/components/GroupedSection.d.ts.map +1 -1
  153. package/lib/typescript/ui/components/Header.d.ts +22 -0
  154. package/lib/typescript/ui/components/Header.d.ts.map +1 -0
  155. package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
  156. package/lib/typescript/ui/components/index.d.ts +1 -0
  157. package/lib/typescript/ui/components/index.d.ts.map +1 -1
  158. package/lib/typescript/ui/components/internal/TextField.d.ts +31 -16
  159. package/lib/typescript/ui/components/internal/TextField.d.ts.map +1 -1
  160. package/lib/typescript/ui/context/OxyContext.d.ts +5 -2
  161. package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
  162. package/lib/typescript/ui/hooks/useSessionSocket.d.ts.map +1 -1
  163. package/lib/typescript/ui/navigation/types.d.ts +9 -2
  164. package/lib/typescript/ui/navigation/types.d.ts.map +1 -1
  165. package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
  166. package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
  167. package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
  168. package/lib/typescript/ui/screens/AppInfoScreen.d.ts.map +1 -1
  169. package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
  170. package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts +5 -1
  171. package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts.map +1 -1
  172. package/lib/typescript/ui/screens/SessionManagementScreen.d.ts.map +1 -1
  173. package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
  174. package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts +1 -1
  175. package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts.map +1 -1
  176. package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts +0 -1
  177. package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts.map +1 -1
  178. package/lib/typescript/ui/screens/internal/SignUpIdentityStep.d.ts.map +1 -1
  179. package/lib/typescript/ui/screens/internal/SignUpSecurityStep.d.ts.map +1 -1
  180. package/lib/typescript/ui/stores/authStore.d.ts.map +1 -1
  181. package/lib/typescript/ui/styles/authStyles.d.ts +326 -0
  182. package/lib/typescript/ui/styles/authStyles.d.ts.map +1 -0
  183. package/lib/typescript/ui/styles/index.d.ts +1 -0
  184. package/lib/typescript/ui/styles/index.d.ts.map +1 -1
  185. package/package.json +1 -4
  186. package/src/core/index.ts +195 -41
  187. package/src/index.ts +72 -4
  188. package/src/node/createAuth.ts +623 -7
  189. package/src/node/index.ts +19 -1
  190. package/src/ui/components/Avatar.tsx +11 -5
  191. package/src/ui/components/GroupedItem.tsx +57 -9
  192. package/src/ui/components/GroupedSection.tsx +12 -0
  193. package/src/ui/components/Header.tsx +364 -0
  194. package/src/ui/components/OxyProvider.tsx +31 -15
  195. package/src/ui/components/index.ts +1 -0
  196. package/src/ui/components/internal/GroupedPillButtons.tsx +1 -1
  197. package/src/ui/components/internal/TextField.md +436 -0
  198. package/src/ui/components/internal/TextField.tsx +720 -620
  199. package/src/ui/context/OxyContext.tsx +150 -63
  200. package/src/ui/hooks/useSessionSocket.ts +5 -2
  201. package/src/ui/navigation/OxyRouter.tsx +1 -1
  202. package/src/ui/navigation/types.ts +10 -2
  203. package/src/ui/screens/AccountCenterScreen.tsx +5 -5
  204. package/src/ui/screens/AccountManagementDemo.tsx +9 -9
  205. package/src/ui/screens/AccountOverviewScreen.tsx +265 -414
  206. package/src/ui/screens/AccountSettingsScreen.tsx +1165 -403
  207. package/src/ui/screens/AccountSwitcherScreen.tsx +158 -202
  208. package/src/ui/screens/AppInfoScreen.tsx +270 -497
  209. package/src/ui/screens/FeedbackScreen.tsx +3 -3
  210. package/src/ui/screens/PaymentGatewayScreen.tsx +668 -365
  211. package/src/ui/screens/ProfileScreen.tsx +5 -5
  212. package/src/ui/screens/RecoverAccountScreen.tsx +46 -74
  213. package/src/ui/screens/SessionManagementScreen.tsx +14 -22
  214. package/src/ui/screens/SignInScreen.tsx +27 -294
  215. package/src/ui/screens/SignUpScreen.tsx +5 -5
  216. package/src/ui/screens/internal/SignInPasswordStep.tsx +11 -22
  217. package/src/ui/screens/internal/SignInUsernameStep.tsx +3 -10
  218. package/src/ui/screens/internal/SignUpIdentityStep.tsx +2 -5
  219. package/src/ui/screens/internal/SignUpSecurityStep.tsx +3 -4
  220. package/src/ui/stores/authStore.ts +12 -0
  221. package/src/ui/styles/authStyles.ts +352 -0
  222. package/src/ui/styles/index.ts +1 -0
  223. package/lib/commonjs/core/auth-manager.js +0 -440
  224. package/lib/commonjs/core/auth-manager.js.map +0 -1
  225. package/lib/commonjs/core/use-auth.js +0 -244
  226. package/lib/commonjs/core/use-auth.js.map +0 -1
  227. package/lib/module/core/auth-manager.js +0 -432
  228. package/lib/module/core/auth-manager.js.map +0 -1
  229. package/lib/module/core/use-auth.js +0 -235
  230. package/lib/module/core/use-auth.js.map +0 -1
  231. package/lib/typescript/core/auth-manager.d.ts +0 -136
  232. package/lib/typescript/core/auth-manager.d.ts.map +0 -1
  233. package/lib/typescript/core/use-auth.d.ts +0 -79
  234. package/lib/typescript/core/use-auth.d.ts.map +0 -1
  235. package/src/__tests__/middleware.test.ts +0 -105
  236. package/src/__tests__/setup.ts +0 -10
  237. package/src/__tests__/zero-config-auth.test.ts +0 -607
  238. package/src/core/auth-manager.ts +0 -500
  239. package/src/core/use-auth.tsx +0 -245
@@ -30,6 +30,7 @@ const OxyProvider: React.FC<OxyProviderProps> = (props) => {
30
30
  onAuthStateChange,
31
31
  storageKeyPrefix,
32
32
  showInternalToaster = true,
33
+ baseURL, // Add support for baseURL
33
34
  ...bottomSheetProps
34
35
  } = props;
35
36
 
@@ -41,6 +42,7 @@ const OxyProvider: React.FC<OxyProviderProps> = (props) => {
41
42
  return (
42
43
  <OxyContextProvider
43
44
  oxyServices={oxyServices}
45
+ baseURL={baseURL}
44
46
  storageKeyPrefix={storageKeyPrefix}
45
47
  onAuthStateChange={onAuthStateChange}
46
48
  >
@@ -53,6 +55,7 @@ const OxyProvider: React.FC<OxyProviderProps> = (props) => {
53
55
  return (
54
56
  <OxyContextProvider
55
57
  oxyServices={oxyServices}
58
+ baseURL={baseURL}
56
59
  storageKeyPrefix={storageKeyPrefix}
57
60
  onAuthStateChange={onAuthStateChange}
58
61
  bottomSheetRef={internalBottomSheetRef}
@@ -85,7 +88,7 @@ const OxyProvider: React.FC<OxyProviderProps> = (props) => {
85
88
  * and reimplemented using BottomSheetModal for better Android compatibility
86
89
  */
87
90
  const OxyBottomSheet: React.FC<OxyProviderProps> = ({
88
- oxyServices,
91
+ oxyServices: providedOxyServices,
89
92
  initialScreen = 'SignIn',
90
93
  onClose,
91
94
  onAuthenticated,
@@ -95,6 +98,13 @@ const OxyBottomSheet: React.FC<OxyProviderProps> = ({
95
98
  autoPresent = false,
96
99
  showInternalToaster = true,
97
100
  }) => {
101
+ // Helper function to determine if native driver should be used
102
+ const shouldUseNativeDriver = () => {
103
+ return Platform.OS === 'ios';
104
+ };
105
+ // Get oxyServices from context if not provided as prop
106
+ const contextOxy = useOxy();
107
+ const oxyServices = providedOxyServices || contextOxy?.oxyServices;
98
108
  // Use the internal ref (which is passed as a prop from OxyProvider)
99
109
  const modalRef = useRef<BottomSheetModalRef>(null);
100
110
  const navigationRef = useRef<((screen: string, props?: Record<string, any>) => void) | null>(null);
@@ -168,13 +178,13 @@ const OxyBottomSheet: React.FC<OxyProviderProps> = ({
168
178
  Animated.timing(fadeAnim, {
169
179
  toValue: 1,
170
180
  duration: 300,
171
- useNativeDriver: Platform.OS === 'ios',
181
+ useNativeDriver: shouldUseNativeDriver(),
172
182
  }),
173
183
  Animated.spring(slideAnim, {
174
184
  toValue: 0,
175
185
  friction: 8,
176
186
  tension: 40,
177
- useNativeDriver: Platform.OS === 'ios',
187
+ useNativeDriver: shouldUseNativeDriver(),
178
188
  }),
179
189
  ]).start();
180
190
  };
@@ -186,13 +196,13 @@ const OxyBottomSheet: React.FC<OxyProviderProps> = ({
186
196
  Animated.timing(fadeAnim, {
187
197
  toValue: 1,
188
198
  duration: 300,
189
- useNativeDriver: Platform.OS === 'ios',
199
+ useNativeDriver: shouldUseNativeDriver(),
190
200
  }),
191
201
  Animated.spring(slideAnim, {
192
202
  toValue: 0,
193
203
  friction: 8,
194
204
  tension: 40,
195
- useNativeDriver: Platform.OS === 'ios',
205
+ useNativeDriver: shouldUseNativeDriver(),
196
206
  }),
197
207
  ]).start();
198
208
  }, 100);
@@ -204,7 +214,7 @@ const OxyBottomSheet: React.FC<OxyProviderProps> = ({
204
214
  Animated.timing(fadeAnim, {
205
215
  toValue: 0,
206
216
  duration: Platform.OS === 'android' ? 100 : 200,
207
- useNativeDriver: Platform.OS === 'ios',
217
+ useNativeDriver: shouldUseNativeDriver(),
208
218
  }).start(() => {
209
219
  modalRef.current?.dismiss();
210
220
  if (onClose) {
@@ -304,15 +314,21 @@ const OxyBottomSheet: React.FC<OxyProviderProps> = ({
304
314
  { opacity: fadeAnim, transform: [{ translateY: slideAnim }] }
305
315
  ]}
306
316
  >
307
- <OxyRouter
308
- oxyServices={oxyServices}
309
- initialScreen={initialScreen}
310
- onClose={handleClose}
311
- onAuthenticated={handleAuthenticated}
312
- theme={theme}
313
- navigationRef={navigationRef}
314
- containerWidth={800} // static, since dynamic sizing is used
315
- />
317
+ {oxyServices ? (
318
+ <OxyRouter
319
+ oxyServices={oxyServices}
320
+ initialScreen={initialScreen}
321
+ onClose={handleClose}
322
+ onAuthenticated={handleAuthenticated}
323
+ theme={theme}
324
+ navigationRef={navigationRef}
325
+ containerWidth={800} // static, since dynamic sizing is used
326
+ />
327
+ ) : (
328
+ <View style={styles.errorContainer}>
329
+ <Text>OxyServices not available</Text>
330
+ </View>
331
+ )}
316
332
  </Animated.View>
317
333
  </View>
318
334
  </BottomSheetScrollView>
@@ -5,6 +5,7 @@ export { default as SectionTitle } from './SectionTitle';
5
5
  export { default as GroupedItem } from './GroupedItem';
6
6
  export { default as GroupedSection } from './GroupedSection';
7
7
  export { default as QuickActions } from './QuickActions';
8
+ export { default as Header } from './Header';
8
9
 
9
10
  // Re-export existing components
10
11
  export { default as Avatar } from './Avatar';
@@ -247,7 +247,7 @@ const GroupedPillButtons: React.FC<GroupedPillButtonsProps> = ({
247
247
  const styles = StyleSheet.create({
248
248
  container: {
249
249
  flexDirection: 'row',
250
- justifyContent: 'center',
250
+ justifyContent: 'flex-end',
251
251
  marginTop: 16,
252
252
  marginBottom: 8,
253
253
  width: '100%',
@@ -0,0 +1,436 @@
1
+ # TextField Component
2
+
3
+ A comprehensive, production-ready text input component with advanced features, validation, and accessibility support.
4
+
5
+ ## Features
6
+
7
+ ### ✨ Core Features
8
+ - **Floating Labels**: Animated labels that float above the input when focused or filled
9
+ - **Material Design**: Follows Material Design principles with outlined and filled variants
10
+ - **Cross-Platform**: Optimized for both React Native and Web platforms
11
+ - **Accessibility**: Full accessibility support with proper labels, hints, and roles
12
+ - **Customizable**: Extensive theming and styling options
13
+
14
+ ### 🎯 Advanced Features
15
+ - **Input Masking**: Built-in masks for phone numbers, credit cards, and currency
16
+ - **Password Strength**: Real-time password strength indicator
17
+ - **Character Counting**: Optional character count display
18
+ - **Debounced Validation**: Configurable debounced validation with loading states
19
+ - **Clear Button**: Optional clear button for easy input clearing
20
+ - **Custom Components**: Support for custom left and right components
21
+ - **Disabled State**: Full disabled state support
22
+ - **Helper Text**: Optional helper text below inputs
23
+ - **Validation States**: Error, success, and loading states with visual indicators
24
+
25
+ ### 🔧 Technical Features
26
+ - **TypeScript**: Full TypeScript support with comprehensive type definitions
27
+ - **Performance**: Optimized with proper memoization and debouncing
28
+ - **Ref Forwarding**: Proper ref forwarding for focus management
29
+ - **Event Handling**: Comprehensive event handling with proper cleanup
30
+ - **State Management**: Robust internal state management
31
+
32
+ ## Props
33
+
34
+ ### Basic Props
35
+ | Prop | Type | Default | Description |
36
+ |------|------|---------|-------------|
37
+ | `label` | `string` | - | The label text for the input |
38
+ | `icon` | `string` | - | Ionicons icon name |
39
+ | `iconColor` | `string` | - | Custom icon color |
40
+ | `error` | `string` | - | Error message to display |
41
+ | `success` | `boolean` | `false` | Whether to show success state |
42
+ | `loading` | `boolean` | `false` | Whether to show loading state |
43
+ | `variant` | `'outlined' \| 'filled'` | `'outlined'` | Input variant style |
44
+ | `disabled` | `boolean` | `false` | Whether the input is disabled |
45
+
46
+ ### Enhanced Features
47
+ | Prop | Type | Default | Description |
48
+ |------|------|---------|-------------|
49
+ | `helperText` | `string` | - | Helper text displayed below input |
50
+ | `maxLength` | `number` | - | Maximum character limit |
51
+ | `showCharacterCount` | `boolean` | `false` | Show character count |
52
+ | `inputMask` | `'phone' \| 'creditCard' \| 'currency' \| 'custom'` | - | Input masking type |
53
+ | `customMask` | `(value: string) => string` | - | Custom masking function |
54
+ | `formatValue` | `(value: string) => string` | - | Custom value formatting |
55
+ | `validateOnChange` | `boolean` | `false` | Enable real-time validation |
56
+ | `debounceMs` | `number` | `300` | Debounce delay for validation |
57
+ | `passwordStrength` | `boolean` | `false` | Show password strength indicator |
58
+ | `clearable` | `boolean` | `false` | Show clear button |
59
+
60
+ ### Accessibility Props
61
+ | Prop | Type | Default | Description |
62
+ |------|------|---------|-------------|
63
+ | `accessibilityLabel` | `string` | - | Accessibility label |
64
+ | `accessibilityHint` | `string` | - | Accessibility hint |
65
+ | `accessibilityRole` | `string` | `'text'` | Accessibility role |
66
+
67
+ ### Advanced Props
68
+ | Prop | Type | Default | Description |
69
+ |------|------|---------|-------------|
70
+ | `onValidationChange` | `(isValid: boolean, value: string) => void` | - | Validation change callback |
71
+ | `onClear` | `() => void` | - | Clear button callback |
72
+ | `autoFocus` | `boolean` | `false` | Auto focus on mount |
73
+ | `returnKeyType` | `'done' \| 'go' \| 'next' \| 'search' \| 'send'` | - | Return key type |
74
+ | `blurOnSubmit` | `boolean` | - | Blur on submit |
75
+ | `keyboardType` | `KeyboardTypeOptions` | - | Keyboard type |
76
+
77
+ ### Styling Props
78
+ | Prop | Type | Default | Description |
79
+ |------|------|---------|-------------|
80
+ | `colors` | `object` | - | Color theme object |
81
+ | `containerStyle` | `StyleProp<ViewStyle>` | - | Container style |
82
+ | `inputStyle` | `StyleProp<TextStyle>` | - | Input style |
83
+ | `labelStyle` | `StyleProp<TextStyle>` | - | Label style |
84
+ | `errorStyle` | `StyleProp<ViewStyle>` | - | Error container style |
85
+
86
+ ### Component Props
87
+ | Prop | Type | Default | Description |
88
+ |------|------|---------|-------------|
89
+ | `leftComponent` | `ReactNode` | - | Custom left component |
90
+ | `rightComponent` | `ReactNode` | - | Custom right component |
91
+
92
+ ## Color Theme Object
93
+
94
+ ```typescript
95
+ interface ColorTheme {
96
+ primary: string; // Primary color for focus states
97
+ secondaryText: string; // Secondary text color
98
+ text: string; // Main text color
99
+ error: string; // Error color
100
+ success: string; // Success color
101
+ border: string; // Border color
102
+ inputBackground: string; // Input background color
103
+ disabled: string; // Disabled text color
104
+ disabledBackground: string; // Disabled background color
105
+ }
106
+ ```
107
+
108
+ ## Usage Examples
109
+
110
+ ### Basic Usage
111
+ ```tsx
112
+ import TextField from './TextField';
113
+
114
+ <TextField
115
+ label="Username"
116
+ value={username}
117
+ onChangeText={setUsername}
118
+ colors={colors}
119
+ />
120
+ ```
121
+
122
+ ### With Icon and Validation
123
+ ```tsx
124
+ <TextField
125
+ label="Email"
126
+ icon="mail-outline"
127
+ value={email}
128
+ onChangeText={setEmail}
129
+ error={emailError}
130
+ success={isEmailValid}
131
+ colors={colors}
132
+ variant="filled"
133
+ />
134
+ ```
135
+
136
+ ### Password with Strength Indicator
137
+ ```tsx
138
+ <TextField
139
+ label="Password"
140
+ icon="lock-closed-outline"
141
+ value={password}
142
+ onChangeText={setPassword}
143
+ secureTextEntry={true}
144
+ passwordStrength={true}
145
+ colors={colors}
146
+ helperText="Enter a strong password"
147
+ />
148
+ ```
149
+
150
+ ### Phone Number with Mask
151
+ ```tsx
152
+ <TextField
153
+ label="Phone Number"
154
+ icon="call-outline"
155
+ value={phone}
156
+ onChangeText={setPhone}
157
+ inputMask="phone"
158
+ keyboardType="phone-pad"
159
+ colors={colors}
160
+ />
161
+ ```
162
+
163
+ ### Credit Card with Character Count
164
+ ```tsx
165
+ <TextField
166
+ label="Credit Card"
167
+ icon="card-outline"
168
+ value={creditCard}
169
+ onChangeText={setCreditCard}
170
+ inputMask="creditCard"
171
+ keyboardType="numeric"
172
+ maxLength={19}
173
+ showCharacterCount={true}
174
+ colors={colors}
175
+ />
176
+ ```
177
+
178
+ ### Real-time Validation
179
+ ```tsx
180
+ <TextField
181
+ label="Username"
182
+ icon="person-outline"
183
+ value={username}
184
+ onChangeText={setUsername}
185
+ error={usernameError}
186
+ success={isUsernameValid}
187
+ loading={isValidating}
188
+ validateOnChange={true}
189
+ debounceMs={500}
190
+ onValidationChange={(isValid, value) => {
191
+ // Handle validation result
192
+ }}
193
+ colors={colors}
194
+ />
195
+ ```
196
+
197
+ ### Disabled State
198
+ ```tsx
199
+ <TextField
200
+ label="Disabled Field"
201
+ value="This field is disabled"
202
+ onChangeText={() => {}}
203
+ disabled={true}
204
+ colors={colors}
205
+ helperText="This field cannot be edited"
206
+ />
207
+ ```
208
+
209
+ ### Custom Right Component
210
+ ```tsx
211
+ <TextField
212
+ label="With Custom Button"
213
+ icon="add-circle-outline"
214
+ value={value}
215
+ onChangeText={setValue}
216
+ colors={colors}
217
+ rightComponent={
218
+ <TouchableOpacity
219
+ style={styles.customButton}
220
+ onPress={handleCustomAction}
221
+ >
222
+ <Text style={styles.customButtonText}>Add</Text>
223
+ </TouchableOpacity>
224
+ }
225
+ />
226
+ ```
227
+
228
+ ### Multiline Input
229
+ ```tsx
230
+ <TextField
231
+ label="Bio"
232
+ icon="document-text-outline"
233
+ value={bio}
234
+ onChangeText={setBio}
235
+ multiline={true}
236
+ numberOfLines={4}
237
+ maxLength={500}
238
+ showCharacterCount={true}
239
+ colors={colors}
240
+ helperText="Tell us about yourself"
241
+ />
242
+ ```
243
+
244
+ ## Input Masks
245
+
246
+ ### Built-in Masks
247
+
248
+ #### Phone Number
249
+ ```tsx
250
+ inputMask="phone"
251
+ // Input: 1234567890
252
+ // Output: (123) 456-7890
253
+ ```
254
+
255
+ #### Credit Card
256
+ ```tsx
257
+ inputMask="creditCard"
258
+ // Input: 1234567890123456
259
+ // Output: 1234 5678 9012 3456
260
+ ```
261
+
262
+ #### Currency
263
+ ```tsx
264
+ inputMask="currency"
265
+ // Input: 123.45
266
+ // Output: $123.45
267
+ ```
268
+
269
+ ### Custom Mask
270
+ ```tsx
271
+ const customMask = (value: string) => {
272
+ // Your custom formatting logic
273
+ return formattedValue;
274
+ };
275
+
276
+ <TextField
277
+ inputMask="custom"
278
+ customMask={customMask}
279
+ // ... other props
280
+ />
281
+ ```
282
+
283
+ ## Password Strength
284
+
285
+ The password strength indicator provides real-time feedback on password strength:
286
+
287
+ - **Weak (0-25%)**: Red
288
+ - **Fair (26-50%)**: Orange
289
+ - **Good (51-75%)**: Blue
290
+ - **Strong (76-100%)**: Green
291
+
292
+ ```tsx
293
+ <TextField
294
+ label="Password"
295
+ secureTextEntry={true}
296
+ passwordStrength={true}
297
+ // ... other props
298
+ />
299
+ ```
300
+
301
+ ## Validation
302
+
303
+ ### Real-time Validation
304
+ ```tsx
305
+ const [emailError, setEmailError] = useState('');
306
+ const [isEmailValid, setIsEmailValid] = useState(false);
307
+
308
+ <TextField
309
+ label="Email"
310
+ value={email}
311
+ onChangeText={setEmail}
312
+ error={emailError}
313
+ success={isEmailValid}
314
+ validateOnChange={true}
315
+ debounceMs={500}
316
+ onValidationChange={(isValid, value) => {
317
+ if (isValid) {
318
+ setIsEmailValid(true);
319
+ setEmailError('');
320
+ } else {
321
+ setIsEmailValid(false);
322
+ setEmailError('Please enter a valid email address');
323
+ }
324
+ }}
325
+ />
326
+ ```
327
+
328
+ ## Accessibility
329
+
330
+ The component includes comprehensive accessibility support:
331
+
332
+ - Proper accessibility labels and hints
333
+ - Keyboard navigation support
334
+ - Screen reader compatibility
335
+ - Focus management
336
+ - Disabled state handling
337
+
338
+ ```tsx
339
+ <TextField
340
+ label="Username"
341
+ accessibilityLabel="Enter your username"
342
+ accessibilityHint="Username must be at least 3 characters long"
343
+ accessibilityRole="text"
344
+ // ... other props
345
+ />
346
+ ```
347
+
348
+ ## Focus Management
349
+
350
+ ```tsx
351
+ const inputRef = useRef<TextInput>(null);
352
+
353
+ <TextField
354
+ ref={inputRef}
355
+ label="Username"
356
+ // ... other props
357
+ />
358
+
359
+ // Focus the input
360
+ inputRef.current?.focus();
361
+ ```
362
+
363
+ ## Styling
364
+
365
+ ### Custom Colors
366
+ ```tsx
367
+ const colors = {
368
+ primary: '#d169e5',
369
+ secondaryText: '#666666',
370
+ text: '#000000',
371
+ error: '#D32F2F',
372
+ success: '#2E7D32',
373
+ border: '#E0E0E0',
374
+ inputBackground: '#F5F5F5',
375
+ disabled: '#E0E0E0',
376
+ disabledBackground: '#F5F5F5',
377
+ };
378
+
379
+ <TextField
380
+ colors={colors}
381
+ // ... other props
382
+ />
383
+ ```
384
+
385
+ ### Custom Styles
386
+ ```tsx
387
+ <TextField
388
+ containerStyle={{ marginBottom: 20 }}
389
+ inputStyle={{ fontSize: 18 }}
390
+ labelStyle={{ fontWeight: 'bold' }}
391
+ errorStyle={{ backgroundColor: '#ffebee' }}
392
+ // ... other props
393
+ />
394
+ ```
395
+
396
+ ## Best Practices
397
+
398
+ 1. **Always provide labels** for accessibility
399
+ 2. **Use appropriate keyboard types** for different input types
400
+ 3. **Implement proper validation** with user-friendly error messages
401
+ 4. **Use debouncing** for real-time validation to avoid performance issues
402
+ 5. **Provide helper text** for complex inputs
403
+ 6. **Handle disabled states** appropriately
404
+ 7. **Use consistent color themes** across your app
405
+ 8. **Test accessibility** with screen readers
406
+
407
+ ## Performance Considerations
408
+
409
+ - The component uses `useCallback` and `useMemo` for performance optimization
410
+ - Debouncing is built-in for validation to prevent excessive re-renders
411
+ - Proper cleanup of timers and animations
412
+ - Efficient state management to minimize re-renders
413
+
414
+ ## Browser Support
415
+
416
+ - React Native: All supported platforms
417
+ - Web: Modern browsers with React Native Web support
418
+ - Mobile: iOS and Android with proper keyboard handling
419
+
420
+ ## Dependencies
421
+
422
+ - React Native
423
+ - @expo/vector-icons (for icons)
424
+ - react-native-svg (for border rendering)
425
+
426
+ ## Migration from Previous Version
427
+
428
+ The improved TextField component is mostly backward compatible. Key changes:
429
+
430
+ 1. **New props**: Added many new features while maintaining existing API
431
+ 2. **Better TypeScript**: Improved type definitions
432
+ 3. **Enhanced accessibility**: Better accessibility support
433
+ 4. **Performance improvements**: Optimized rendering and state management
434
+ 5. **Removed web-specific code**: Unified implementation for all platforms
435
+
436
+ Existing code should continue to work with minimal changes.