@billdog.io/react-native 1.0.0-beta.2

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 (309) hide show
  1. package/BillDogReactNative.podspec +30 -0
  2. package/LICENSE +21 -0
  3. package/README.md +330 -0
  4. package/android/build.gradle +99 -0
  5. package/android/src/main/AndroidManifest.xml +1 -0
  6. package/android/src/main/kotlin/io/billdog/reactnative/BillDogABTestModule.kt +317 -0
  7. package/android/src/main/kotlin/io/billdog/reactnative/BillDogAnalyticsModule.kt +389 -0
  8. package/android/src/main/kotlin/io/billdog/reactnative/BillDogModule.kt +817 -0
  9. package/android/src/main/kotlin/io/billdog/reactnative/BillDogPaywallViewManager.kt +383 -0
  10. package/android/src/main/kotlin/io/billdog/reactnative/BillDogSurveyModule.kt +427 -0
  11. package/android/src/main/kotlin/io/billdog/reactnative/BillDogVirtualCurrencyModule.kt +407 -0
  12. package/android/src/main/kotlin/io/billdog/virtualcurrency/BillDogVirtualCurrencyPackage.kt +44 -0
  13. package/dist/AdvancedPaywallCache.d.ts +70 -0
  14. package/dist/AdvancedPaywallCache.js +344 -0
  15. package/dist/BillDog.d.ts +255 -0
  16. package/dist/BillDog.js +918 -0
  17. package/dist/BillDogConfiguration.d.ts +145 -0
  18. package/dist/BillDogConfiguration.js +229 -0
  19. package/dist/ComponentRenderer.d.ts +17 -0
  20. package/dist/ComponentRenderer.js +886 -0
  21. package/dist/LayoutEngine.d.ts +101 -0
  22. package/dist/LayoutEngine.js +394 -0
  23. package/dist/LocalizationResolver.d.ts +99 -0
  24. package/dist/LocalizationResolver.js +266 -0
  25. package/dist/NativePaywallView.d.ts +36 -0
  26. package/dist/NativePaywallView.js +59 -0
  27. package/dist/PaywallCache.d.ts +74 -0
  28. package/dist/PaywallCache.js +293 -0
  29. package/dist/PaywallStateManager.d.ts +62 -0
  30. package/dist/PaywallStateManager.js +147 -0
  31. package/dist/PaywallView.d.ts +42 -0
  32. package/dist/PaywallView.js +275 -0
  33. package/dist/ProductVariableProvider.d.ts +60 -0
  34. package/dist/ProductVariableProvider.js +239 -0
  35. package/dist/VariableResolver.d.ts +120 -0
  36. package/dist/VariableResolver.js +379 -0
  37. package/dist/WebViewPaywall.d.ts +75 -0
  38. package/dist/WebViewPaywall.js +360 -0
  39. package/dist/animations/presets.d.ts +49 -0
  40. package/dist/animations/presets.js +367 -0
  41. package/dist/components/AccoladeCpsComponent.d.ts +13 -0
  42. package/dist/components/AccoladeCpsComponent.js +248 -0
  43. package/dist/components/AccordionComponent.d.ts +10 -0
  44. package/dist/components/AccordionComponent.js +187 -0
  45. package/dist/components/AnimatedWrapper.d.ts +35 -0
  46. package/dist/components/AnimatedWrapper.js +277 -0
  47. package/dist/components/CarouselComponent.d.ts +23 -0
  48. package/dist/components/CarouselComponent.js +484 -0
  49. package/dist/components/ChartCurveComponent.d.ts +13 -0
  50. package/dist/components/ChartCurveComponent.js +333 -0
  51. package/dist/components/CheckboxComponent.d.ts +9 -0
  52. package/dist/components/CheckboxComponent.js +172 -0
  53. package/dist/components/ConfettiComponent.d.ts +9 -0
  54. package/dist/components/ConfettiComponent.js +172 -0
  55. package/dist/components/CountdownComponent.d.ts +16 -0
  56. package/dist/components/CountdownComponent.js +414 -0
  57. package/dist/components/DelayedXComponent.d.ts +12 -0
  58. package/dist/components/DelayedXComponent.js +240 -0
  59. package/dist/components/DrawerModalComponent.d.ts +20 -0
  60. package/dist/components/DrawerModalComponent.js +286 -0
  61. package/dist/components/GradientView.d.ts +38 -0
  62. package/dist/components/GradientView.js +126 -0
  63. package/dist/components/HapticFeedbackComponent.d.ts +16 -0
  64. package/dist/components/HapticFeedbackComponent.js +64 -0
  65. package/dist/components/HorizontalProductsComponent.d.ts +17 -0
  66. package/dist/components/HorizontalProductsComponent.js +284 -0
  67. package/dist/components/MultiChoiceGridComponent.d.ts +13 -0
  68. package/dist/components/MultiChoiceGridComponent.js +234 -0
  69. package/dist/components/NPSScaleComponent.d.ts +16 -0
  70. package/dist/components/NPSScaleComponent.js +260 -0
  71. package/dist/components/NavigationComponent.d.ts +26 -0
  72. package/dist/components/NavigationComponent.js +302 -0
  73. package/dist/components/OAuthButtonComponent.d.ts +20 -0
  74. package/dist/components/OAuthButtonComponent.js +237 -0
  75. package/dist/components/ProgressLoaderComponent.d.ts +13 -0
  76. package/dist/components/ProgressLoaderComponent.js +308 -0
  77. package/dist/components/ProgressStepperComponent.d.ts +18 -0
  78. package/dist/components/ProgressStepperComponent.js +228 -0
  79. package/dist/components/SegmentedPickerComponent.d.ts +10 -0
  80. package/dist/components/SegmentedPickerComponent.js +221 -0
  81. package/dist/components/ShareButtonsComponent.d.ts +21 -0
  82. package/dist/components/ShareButtonsComponent.js +265 -0
  83. package/dist/components/ShareCodeComponent.d.ts +16 -0
  84. package/dist/components/ShareCodeComponent.js +274 -0
  85. package/dist/components/SingleChoiceGridComponent.d.ts +13 -0
  86. package/dist/components/SingleChoiceGridComponent.js +210 -0
  87. package/dist/components/SliderComponent.d.ts +9 -0
  88. package/dist/components/SliderComponent.js +263 -0
  89. package/dist/components/StarRatingInputComponent.d.ts +20 -0
  90. package/dist/components/StarRatingInputComponent.js +198 -0
  91. package/dist/components/StickerCompositeComponent.d.ts +13 -0
  92. package/dist/components/StickerCompositeComponent.js +136 -0
  93. package/dist/components/TabsComponent.d.ts +19 -0
  94. package/dist/components/TabsComponent.js +431 -0
  95. package/dist/components/TextInputComponent.d.ts +18 -0
  96. package/dist/components/TextInputComponent.js +227 -0
  97. package/dist/components/TimelineComponent.d.ts +19 -0
  98. package/dist/components/TimelineComponent.js +104 -0
  99. package/dist/components/ToggleComponent.d.ts +14 -0
  100. package/dist/components/ToggleComponent.js +132 -0
  101. package/dist/components/VerticalProductsComponent.d.ts +17 -0
  102. package/dist/components/VerticalProductsComponent.js +311 -0
  103. package/dist/dynamicValues.d.ts +36 -0
  104. package/dist/dynamicValues.js +142 -0
  105. package/dist/filters/dateFilters.d.ts +50 -0
  106. package/dist/filters/dateFilters.js +390 -0
  107. package/dist/filters/index.d.ts +18 -0
  108. package/dist/filters/index.js +253 -0
  109. package/dist/hooks/useOfferings.d.ts +76 -0
  110. package/dist/hooks/useOfferings.js +99 -0
  111. package/dist/hooks/usePaywall.d.ts +27 -0
  112. package/dist/hooks/usePaywall.js +114 -0
  113. package/dist/hooks/usePlacement.d.ts +34 -0
  114. package/dist/hooks/usePlacement.js +89 -0
  115. package/dist/hooks/useSubscription.d.ts +40 -0
  116. package/dist/hooks/useSubscription.js +97 -0
  117. package/dist/index.d.ts +98 -0
  118. package/dist/index.js +198 -0
  119. package/dist/models/BillDogError.d.ts +40 -0
  120. package/dist/models/BillDogError.js +11 -0
  121. package/dist/models/CacheFetchPolicy.d.ts +8 -0
  122. package/dist/models/CacheFetchPolicy.js +4 -0
  123. package/dist/models/CustomProduct.d.ts +32 -0
  124. package/dist/models/CustomProduct.js +15 -0
  125. package/dist/models/CustomerInfo.d.ts +17 -0
  126. package/dist/models/CustomerInfo.js +11 -0
  127. package/dist/models/Delegate.d.ts +20 -0
  128. package/dist/models/Delegate.js +11 -0
  129. package/dist/models/EntitlementInfo.d.ts +19 -0
  130. package/dist/models/EntitlementInfo.js +2 -0
  131. package/dist/models/Placement.d.ts +54 -0
  132. package/dist/models/Placement.js +15 -0
  133. package/dist/models/PurchaseParams.d.ts +39 -0
  134. package/dist/models/PurchaseParams.js +60 -0
  135. package/dist/models/PurchaseResult.d.ts +30 -0
  136. package/dist/models/PurchaseResult.js +15 -0
  137. package/dist/models/RestoreResult.d.ts +30 -0
  138. package/dist/models/RestoreResult.js +22 -0
  139. package/dist/models/RestoredItem.d.ts +26 -0
  140. package/dist/models/RestoredItem.js +13 -0
  141. package/dist/modules/ABTest.d.ts +65 -0
  142. package/dist/modules/ABTest.js +113 -0
  143. package/dist/modules/Analytics.d.ts +91 -0
  144. package/dist/modules/Analytics.js +182 -0
  145. package/dist/modules/Survey.d.ts +65 -0
  146. package/dist/modules/Survey.js +82 -0
  147. package/dist/modules/VirtualCurrency.d.ts +63 -0
  148. package/dist/modules/VirtualCurrency.js +147 -0
  149. package/dist/murmur.d.ts +23 -0
  150. package/dist/murmur.js +104 -0
  151. package/dist/notifications/LiveActivitiesManager.d.ts +47 -0
  152. package/dist/notifications/LiveActivitiesManager.js +106 -0
  153. package/dist/notifications/NotificationScheduler.d.ts +55 -0
  154. package/dist/notifications/NotificationScheduler.js +199 -0
  155. package/dist/notifications/PurchaseNotificationHandler.d.ts +24 -0
  156. package/dist/notifications/PurchaseNotificationHandler.js +55 -0
  157. package/dist/notifications/useDeviceToken.d.ts +36 -0
  158. package/dist/notifications/useDeviceToken.js +97 -0
  159. package/dist/notifications/useLiveActivity.d.ts +39 -0
  160. package/dist/notifications/useLiveActivity.js +104 -0
  161. package/dist/review/ReviewAnalytics.d.ts +34 -0
  162. package/dist/review/ReviewAnalytics.js +73 -0
  163. package/dist/review/ReviewManager.d.ts +83 -0
  164. package/dist/review/ReviewManager.js +339 -0
  165. package/dist/review/ReviewTimingManager.d.ts +82 -0
  166. package/dist/review/ReviewTimingManager.js +224 -0
  167. package/dist/survey-core/types.d.ts +215 -0
  168. package/dist/survey-core/types.js +8 -0
  169. package/dist/types.d.ts +438 -0
  170. package/dist/types.js +158 -0
  171. package/dist/utils/ApiClient.d.ts +65 -0
  172. package/dist/utils/ApiClient.js +132 -0
  173. package/dist/utils/CSSConverter.d.ts +49 -0
  174. package/dist/utils/CSSConverter.js +470 -0
  175. package/dist/utils/animations.d.ts +41 -0
  176. package/dist/utils/animations.js +194 -0
  177. package/dist/utils/calendarIntegration.d.ts +36 -0
  178. package/dist/utils/calendarIntegration.js +89 -0
  179. package/dist/utils/configurationResolver.d.ts +23 -0
  180. package/dist/utils/configurationResolver.js +78 -0
  181. package/dist/utils/deviceDetection.d.ts +38 -0
  182. package/dist/utils/deviceDetection.js +59 -0
  183. package/dist/utils/hapticFeedback.d.ts +17 -0
  184. package/dist/utils/hapticFeedback.js +53 -0
  185. package/dist/utils/iconMapper.d.ts +26 -0
  186. package/dist/utils/iconMapper.js +113 -0
  187. package/dist/utils/notificationPermissions.d.ts +13 -0
  188. package/dist/utils/notificationPermissions.js +51 -0
  189. package/dist/utils/priceFormatting.d.ts +19 -0
  190. package/dist/utils/priceFormatting.js +99 -0
  191. package/dist/utils/shareSheet.d.ts +17 -0
  192. package/dist/utils/shareSheet.js +42 -0
  193. package/dist/utils/subscriptionUpgrade.d.ts +84 -0
  194. package/dist/utils/subscriptionUpgrade.js +100 -0
  195. package/dist/valueUtils.d.ts +48 -0
  196. package/dist/valueUtils.js +129 -0
  197. package/dist/xFlowTags.d.ts +18 -0
  198. package/dist/xFlowTags.js +385 -0
  199. package/ios/BillDogABTest.m +50 -0
  200. package/ios/BillDogABTest.swift +188 -0
  201. package/ios/BillDogAnalytics.m +105 -0
  202. package/ios/BillDogAnalytics.swift +324 -0
  203. package/ios/BillDogBridge.m +222 -0
  204. package/ios/BillDogBridge.swift +715 -0
  205. package/ios/BillDogLiveActivities.m +41 -0
  206. package/ios/BillDogLiveActivities.swift +104 -0
  207. package/ios/BillDogPaywallViewManager.m +39 -0
  208. package/ios/BillDogPaywallViewManager.swift +361 -0
  209. package/ios/BillDogSurvey.m +34 -0
  210. package/ios/BillDogSurvey.swift +257 -0
  211. package/ios/BillDogVirtualCurrencyBridge.m +63 -0
  212. package/ios/BillDogVirtualCurrencyBridge.swift +511 -0
  213. package/junit.xml +25 -0
  214. package/package.json +61 -0
  215. package/react-native.config.js +13 -0
  216. package/src/AdvancedPaywallCache.ts +433 -0
  217. package/src/BillDog.ts +983 -0
  218. package/src/BillDogConfiguration.ts +318 -0
  219. package/src/ComponentRenderer.tsx +1325 -0
  220. package/src/LayoutEngine.ts +459 -0
  221. package/src/LocalizationResolver.ts +311 -0
  222. package/src/NativePaywallView.tsx +132 -0
  223. package/src/PaywallCache.ts +358 -0
  224. package/src/PaywallStateManager.ts +154 -0
  225. package/src/PaywallView.tsx +328 -0
  226. package/src/ProductVariableProvider.ts +282 -0
  227. package/src/VariableResolver.ts +516 -0
  228. package/src/WebViewPaywall.tsx +454 -0
  229. package/src/animations/presets.ts +421 -0
  230. package/src/components/AccoladeCpsComponent.tsx +259 -0
  231. package/src/components/AccordionComponent.tsx +213 -0
  232. package/src/components/AnimatedWrapper.tsx +316 -0
  233. package/src/components/CarouselComponent.tsx +615 -0
  234. package/src/components/ChartCurveComponent.tsx +452 -0
  235. package/src/components/CheckboxComponent.tsx +185 -0
  236. package/src/components/ConfettiComponent.tsx +178 -0
  237. package/src/components/CountdownComponent.tsx +454 -0
  238. package/src/components/DelayedXComponent.tsx +266 -0
  239. package/src/components/DrawerModalComponent.tsx +324 -0
  240. package/src/components/GradientView.tsx +129 -0
  241. package/src/components/HapticFeedbackComponent.tsx +39 -0
  242. package/src/components/HorizontalProductsComponent.tsx +329 -0
  243. package/src/components/MultiChoiceGridComponent.tsx +265 -0
  244. package/src/components/NPSScaleComponent.tsx +294 -0
  245. package/src/components/NavigationComponent.tsx +329 -0
  246. package/src/components/OAuthButtonComponent.tsx +266 -0
  247. package/src/components/ProgressLoaderComponent.tsx +366 -0
  248. package/src/components/ProgressStepperComponent.tsx +250 -0
  249. package/src/components/SegmentedPickerComponent.tsx +245 -0
  250. package/src/components/ShareButtonsComponent.tsx +299 -0
  251. package/src/components/ShareCodeComponent.tsx +303 -0
  252. package/src/components/SingleChoiceGridComponent.tsx +229 -0
  253. package/src/components/SliderComponent.tsx +280 -0
  254. package/src/components/StarRatingInputComponent.tsx +223 -0
  255. package/src/components/StickerCompositeComponent.tsx +168 -0
  256. package/src/components/TabsComponent.tsx +496 -0
  257. package/src/components/TextInputComponent.tsx +258 -0
  258. package/src/components/TimelineComponent.tsx +129 -0
  259. package/src/components/ToggleComponent.tsx +142 -0
  260. package/src/components/VerticalProductsComponent.tsx +357 -0
  261. package/src/dynamicValues.ts +180 -0
  262. package/src/filters/dateFilters.ts +411 -0
  263. package/src/filters/index.ts +281 -0
  264. package/src/hooks/useOfferings.ts +192 -0
  265. package/src/hooks/usePaywall.ts +154 -0
  266. package/src/hooks/usePlacement.ts +143 -0
  267. package/src/hooks/useSubscription.ts +154 -0
  268. package/src/index.ts +245 -0
  269. package/src/models/BillDogError.ts +24 -0
  270. package/src/models/CacheFetchPolicy.ts +13 -0
  271. package/src/models/CustomProduct.ts +33 -0
  272. package/src/models/CustomerInfo.ts +26 -0
  273. package/src/models/Delegate.ts +22 -0
  274. package/src/models/EntitlementInfo.ts +27 -0
  275. package/src/models/Placement.ts +50 -0
  276. package/src/models/PurchaseParams.ts +81 -0
  277. package/src/models/PurchaseResult.ts +32 -0
  278. package/src/models/RestoreResult.ts +27 -0
  279. package/src/models/RestoredItem.ts +25 -0
  280. package/src/modules/ABTest.ts +131 -0
  281. package/src/modules/Analytics.ts +227 -0
  282. package/src/modules/Survey.ts +126 -0
  283. package/src/modules/VirtualCurrency.ts +223 -0
  284. package/src/murmur.ts +102 -0
  285. package/src/notifications/LiveActivitiesManager.ts +140 -0
  286. package/src/notifications/NotificationScheduler.ts +292 -0
  287. package/src/notifications/PurchaseNotificationHandler.ts +67 -0
  288. package/src/notifications/useDeviceToken.ts +116 -0
  289. package/src/notifications/useLiveActivity.ts +125 -0
  290. package/src/review/ReviewAnalytics.ts +89 -0
  291. package/src/review/ReviewManager.ts +355 -0
  292. package/src/review/ReviewTimingManager.ts +265 -0
  293. package/src/survey-core/types.ts +244 -0
  294. package/src/types/ambient.d.ts +9 -0
  295. package/src/types.ts +680 -0
  296. package/src/utils/ApiClient.ts +163 -0
  297. package/src/utils/CSSConverter.ts +552 -0
  298. package/src/utils/animations.ts +232 -0
  299. package/src/utils/calendarIntegration.ts +113 -0
  300. package/src/utils/configurationResolver.ts +106 -0
  301. package/src/utils/deviceDetection.ts +83 -0
  302. package/src/utils/hapticFeedback.ts +55 -0
  303. package/src/utils/iconMapper.ts +102 -0
  304. package/src/utils/notificationPermissions.ts +48 -0
  305. package/src/utils/priceFormatting.ts +119 -0
  306. package/src/utils/shareSheet.ts +55 -0
  307. package/src/utils/subscriptionUpgrade.ts +183 -0
  308. package/src/valueUtils.ts +108 -0
  309. package/src/xFlowTags.ts +463 -0
@@ -0,0 +1,431 @@
1
+ "use strict";
2
+ /**
3
+ * TabsComponent - Interactive tabs for React Native
4
+ * Uses element:{id}.currentIndex for state tracking (Superwall pattern)
5
+ * Full property support matching web schema for cross-platform consistency
6
+ * Phase 2 Enhanced: icon support, alignment, sizing, disabled state, animation duration, overflow
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.TabsComponent = void 0;
43
+ const react_1 = __importStar(require("react"));
44
+ const react_native_1 = require("react-native");
45
+ // Enable LayoutAnimation on Android
46
+ if (react_native_1.Platform.OS === 'android' && react_native_1.UIManager.setLayoutAnimationEnabledExperimental) {
47
+ react_native_1.UIManager.setLayoutAnimationEnabledExperimental(true);
48
+ }
49
+ // Icon mapping for React Native (using basic Unicode symbols as fallback)
50
+ const ICON_MAP = {
51
+ home: '🏠',
52
+ star: '⭐',
53
+ settings: '⚙️',
54
+ person: '👤',
55
+ favorite: '❤️',
56
+ heart: '❤️',
57
+ search: '🔍',
58
+ check: '✓',
59
+ close: '✕',
60
+ add: '+',
61
+ remove: '-',
62
+ edit: '✏️',
63
+ delete: '🗑️',
64
+ share: '↗️',
65
+ download: '⬇️',
66
+ upload: '⬆️',
67
+ refresh: '🔄',
68
+ info: 'ℹ️',
69
+ help: '❓',
70
+ warning: '⚠️',
71
+ error: '❌',
72
+ lock: '🔒',
73
+ unlock: '🔓',
74
+ notification: '🔔',
75
+ email: '✉️',
76
+ phone: '📞',
77
+ location: '📍',
78
+ calendar: '📅',
79
+ time: '⏰',
80
+ camera: '📷',
81
+ photo: '🖼️',
82
+ video: '🎥',
83
+ music: '🎵',
84
+ play: '▶️',
85
+ pause: '⏸️',
86
+ stop: '⏹️',
87
+ crown: '👑',
88
+ premium: '👑',
89
+ diamond: '💎',
90
+ gift: '🎁',
91
+ cart: '🛒',
92
+ wallet: '💰',
93
+ rocket: '🚀',
94
+ trophy: '🏆',
95
+ medal: '🏅',
96
+ badge: '📛',
97
+ verified: '✅',
98
+ shield: '🛡️',
99
+ bolt: '⚡',
100
+ fire: '🔥',
101
+ sparkle: '✨',
102
+ magic: '🪄',
103
+ };
104
+ const TabsComponent = ({ component, renderChild, stateManager, isPreviewMode = false, onTabChange, }) => {
105
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1;
106
+ const props = component.properties || {};
107
+ // Core Properties
108
+ const tabCount = (_a = props.tabCount) !== null && _a !== void 0 ? _a : 3;
109
+ const defaultTab = (_b = props.defaultTab) !== null && _b !== void 0 ? _b : 0;
110
+ const animated = (_c = props.animated) !== null && _c !== void 0 ? _c : true;
111
+ const variant = (_d = props.variant) !== null && _d !== void 0 ? _d : 'pills';
112
+ // Phase 2: New Properties
113
+ const tabAlignment = (_e = props.tabAlignment) !== null && _e !== void 0 ? _e : 'stretch';
114
+ const tabSizing = (_f = props.tabSizing) !== null && _f !== void 0 ? _f : 'equal';
115
+ const fixedTabWidth = props.fixedTabWidth;
116
+ const animationDuration = (_g = props.animationDuration) !== null && _g !== void 0 ? _g : 200;
117
+ const overflowBehavior = (_h = props.overflowBehavior) !== null && _h !== void 0 ? _h : 'scroll';
118
+ const tabIconPosition = (_j = props.tabIconPosition) !== null && _j !== void 0 ? _j : 'left';
119
+ // Styling Properties (matching web schema)
120
+ const activeTabColor = (_k = props.activeTabColor) !== null && _k !== void 0 ? _k : '#FFFFFF';
121
+ const inactiveTabColor = (_l = props.inactiveTabColor) !== null && _l !== void 0 ? _l : 'transparent';
122
+ const activeTextColor = (_m = props.activeTextColor) !== null && _m !== void 0 ? _m : '#000000';
123
+ const inactiveTextColor = (_o = props.inactiveTextColor) !== null && _o !== void 0 ? _o : '#666666';
124
+ const tabListBackgroundColor = (_p = props.tabListBackgroundColor) !== null && _p !== void 0 ? _p : '#F5F5F5';
125
+ const tabFontSize = (_q = props.tabFontSize) !== null && _q !== void 0 ? _q : 14;
126
+ const tabFontWeight = (_r = props.tabFontWeight) !== null && _r !== void 0 ? _r : '600';
127
+ const tabBorderRadius = (_s = props.tabBorderRadius) !== null && _s !== void 0 ? _s : 8;
128
+ const tabListBorderRadius = (_t = props.tabListBorderRadius) !== null && _t !== void 0 ? _t : 10;
129
+ const tabGap = (_u = props.tabGap) !== null && _u !== void 0 ? _u : 4;
130
+ const tabPaddingX = (_v = props.tabPaddingX) !== null && _v !== void 0 ? _v : 16;
131
+ const tabPaddingY = (_w = props.tabPaddingY) !== null && _w !== void 0 ? _w : 10;
132
+ // Phase 2: Disabled state colors
133
+ const disabledTextColor = (_x = props.disabledTextColor) !== null && _x !== void 0 ? _x : '#AAAAAA';
134
+ const disabledTabFill = (_y = props.disabledTabFill) !== null && _y !== void 0 ? _y : '#F0F0F0';
135
+ const [currentIndex, setCurrentIndex] = (0, react_1.useState)(defaultTab);
136
+ // Resolve tab children by role (canonical pattern matching all other renderers)
137
+ const tabChildren = (0, react_1.useMemo)(() => {
138
+ return (component.children || [])
139
+ .filter(child => /^tab-\d+$/.test(child.role || ''))
140
+ .sort((a, b) => {
141
+ var _a, _b;
142
+ const aNum = parseInt(((_a = a.role) === null || _a === void 0 ? void 0 : _a.replace('tab-', '')) || '0');
143
+ const bNum = parseInt(((_b = b.role) === null || _b === void 0 ? void 0 : _b.replace('tab-', '')) || '0');
144
+ return aNum - bNum;
145
+ });
146
+ }, [component.children]);
147
+ // Get tab label from child properties (canonical: label → text → name)
148
+ const getTabLabel = (0, react_1.useCallback)((index) => {
149
+ var _a, _b, _c, _d, _e;
150
+ const child = tabChildren[index];
151
+ if (!child)
152
+ return `Tab ${index + 1}`;
153
+ return (_e = (_d = (_b = (_a = child.properties) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : (_c = child.properties) === null || _c === void 0 ? void 0 : _c.text) !== null && _d !== void 0 ? _d : child.name) !== null && _e !== void 0 ? _e : `Tab ${index + 1}`;
154
+ }, [tabChildren]);
155
+ // Get tab icon from child properties
156
+ const getTabIcon = (0, react_1.useCallback)((index) => {
157
+ var _a;
158
+ const child = tabChildren[index];
159
+ const iconName = (_a = child === null || child === void 0 ? void 0 : child.properties) === null || _a === void 0 ? void 0 : _a.icon;
160
+ if (iconName && ICON_MAP[iconName.toLowerCase()]) {
161
+ return ICON_MAP[iconName.toLowerCase()];
162
+ }
163
+ return undefined;
164
+ }, [tabChildren]);
165
+ // Check if tab is disabled from child properties
166
+ const isTabDisabled = (0, react_1.useCallback)((index) => {
167
+ var _a, _b;
168
+ const child = tabChildren[index];
169
+ return (_b = (_a = child === null || child === void 0 ? void 0 : child.properties) === null || _a === void 0 ? void 0 : _a.disabled) !== null && _b !== void 0 ? _b : false;
170
+ }, [tabChildren]);
171
+ // Parse children to find content panels - filter by content-panel-X role and sort
172
+ const contentPanels = (0, react_1.useMemo)(() => {
173
+ const children = component.children || [];
174
+ return children
175
+ .filter(child => /^content-panel-\d+$/.test(child.role || ''))
176
+ .sort((a, b) => {
177
+ var _a, _b;
178
+ const aNum = parseInt(((_a = a.role) === null || _a === void 0 ? void 0 : _a.replace('content-panel-', '')) || '0');
179
+ const bNum = parseInt(((_b = b.role) === null || _b === void 0 ? void 0 : _b.replace('content-panel-', '')) || '0');
180
+ return aNum - bNum;
181
+ });
182
+ }, [component.children]);
183
+ // Update state manager
184
+ (0, react_1.useEffect)(() => {
185
+ if (stateManager) {
186
+ stateManager.updateState(`element:${component.id}.currentIndex`, currentIndex);
187
+ }
188
+ }, [component.id, currentIndex, stateManager]);
189
+ // Listen for external state changes
190
+ (0, react_1.useEffect)(() => {
191
+ if (!stateManager)
192
+ return;
193
+ const unsubscribe = stateManager.subscribeToState(`element:${component.id}.currentIndex`, (value) => {
194
+ if (typeof value === 'number' && value !== currentIndex) {
195
+ selectTab(value);
196
+ }
197
+ });
198
+ return unsubscribe;
199
+ }, [component.id, currentIndex, stateManager]);
200
+ const selectTab = (0, react_1.useCallback)((index) => {
201
+ if (index < 0 || index >= tabCount)
202
+ return;
203
+ // Phase 2: Check if tab is disabled
204
+ if (isTabDisabled(index))
205
+ return;
206
+ const previousIndex = currentIndex;
207
+ const tabLabel = getTabLabel(index);
208
+ if (animated) {
209
+ react_native_1.LayoutAnimation.configureNext({
210
+ duration: animationDuration,
211
+ update: { type: react_native_1.LayoutAnimation.Types.easeInEaseOut },
212
+ });
213
+ }
214
+ setCurrentIndex(index);
215
+ // Phase 2: Fire tab change callback
216
+ onTabChange === null || onTabChange === void 0 ? void 0 : onTabChange(component.id, previousIndex, index, tabLabel);
217
+ }, [animated, animationDuration, tabCount, currentIndex, isTabDisabled, getTabLabel, onTabChange, component.id]);
218
+ // Content gap from containerLayout (matching web schema)
219
+ const contentGap = (_0 = (_z = component.containerLayout) === null || _z === void 0 ? void 0 : _z.gap) !== null && _0 !== void 0 ? _0 : 12;
220
+ // Phase 2: Get flex justification based on alignment
221
+ const getJustifyContent = () => {
222
+ switch (tabAlignment) {
223
+ case 'start': return 'flex-start';
224
+ case 'center': return 'center';
225
+ case 'end': return 'flex-end';
226
+ case 'stretch':
227
+ default: return 'flex-start';
228
+ }
229
+ };
230
+ // Variant-specific styles
231
+ const getTabListStyle = () => {
232
+ const baseStyle = {
233
+ backgroundColor: tabListBackgroundColor,
234
+ flexDirection: 'row',
235
+ padding: 4,
236
+ marginBottom: contentGap,
237
+ justifyContent: getJustifyContent(),
238
+ };
239
+ switch (variant) {
240
+ case 'underline':
241
+ return {
242
+ ...baseStyle,
243
+ backgroundColor: 'transparent',
244
+ borderBottomWidth: 1,
245
+ borderBottomColor: '#e5e5e5',
246
+ padding: 0,
247
+ };
248
+ case 'boxed':
249
+ return {
250
+ ...baseStyle,
251
+ borderRadius: tabBorderRadius,
252
+ borderWidth: 1,
253
+ borderColor: '#e5e5e5',
254
+ padding: 0,
255
+ };
256
+ default: // pills
257
+ return {
258
+ ...baseStyle,
259
+ borderRadius: tabListBorderRadius,
260
+ };
261
+ }
262
+ };
263
+ const getTabButtonStyle = (isActive, isDisabled) => {
264
+ // Phase 2: Determine width based on sizing mode
265
+ let widthStyle = {};
266
+ if (tabSizing === 'equal' && tabAlignment === 'stretch') {
267
+ widthStyle = { flex: 1 };
268
+ }
269
+ else if (tabSizing === 'fixed' && fixedTabWidth) {
270
+ widthStyle = { width: fixedTabWidth };
271
+ }
272
+ // Phase 2: Determine background color
273
+ const bgColor = isDisabled
274
+ ? disabledTabFill
275
+ : (isActive ? activeTabColor : inactiveTabColor);
276
+ const baseStyle = {
277
+ ...widthStyle,
278
+ paddingVertical: tabPaddingY,
279
+ paddingHorizontal: tabPaddingX,
280
+ alignItems: 'center',
281
+ justifyContent: 'center',
282
+ marginHorizontal: tabGap / 2,
283
+ opacity: isDisabled ? 0.5 : 1,
284
+ };
285
+ switch (variant) {
286
+ case 'underline':
287
+ return {
288
+ ...baseStyle,
289
+ marginHorizontal: 0,
290
+ borderBottomWidth: isActive ? 2 : 0,
291
+ borderBottomColor: isActive ? activeTextColor : 'transparent',
292
+ };
293
+ case 'boxed':
294
+ return {
295
+ ...baseStyle,
296
+ marginHorizontal: 0,
297
+ backgroundColor: bgColor,
298
+ };
299
+ default: // pills
300
+ return {
301
+ ...baseStyle,
302
+ backgroundColor: bgColor,
303
+ borderRadius: tabBorderRadius,
304
+ };
305
+ }
306
+ };
307
+ const getTabTextStyle = (isActive, isDisabled) => {
308
+ const textColor = isDisabled
309
+ ? disabledTextColor
310
+ : (isActive ? activeTextColor : inactiveTextColor);
311
+ return {
312
+ fontSize: tabFontSize,
313
+ fontWeight: isActive ? tabFontWeight : '500',
314
+ color: textColor,
315
+ };
316
+ };
317
+ // Phase 2: Render tab content with icon
318
+ const renderTabContent = (index, isActive, isDisabled) => {
319
+ const label = getTabLabel(index);
320
+ const icon = getTabIcon(index);
321
+ const textStyle = getTabTextStyle(isActive, isDisabled);
322
+ if (!icon || tabIconPosition === 'only') {
323
+ if (icon && tabIconPosition === 'only') {
324
+ return <react_native_1.Text style={[textStyle, { fontSize: tabFontSize + 4 }]}>{icon}</react_native_1.Text>;
325
+ }
326
+ return <react_native_1.Text style={textStyle}>{label}</react_native_1.Text>;
327
+ }
328
+ const iconElement = <react_native_1.Text style={[textStyle, { fontSize: tabFontSize + 2, marginHorizontal: 4 }]}>{icon}</react_native_1.Text>;
329
+ const labelElement = <react_native_1.Text style={textStyle}>{label}</react_native_1.Text>;
330
+ switch (tabIconPosition) {
331
+ case 'right':
332
+ return (<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center' }}>
333
+ {labelElement}
334
+ {iconElement}
335
+ </react_native_1.View>);
336
+ case 'top':
337
+ return (<react_native_1.View style={{ alignItems: 'center' }}>
338
+ {iconElement}
339
+ {labelElement}
340
+ </react_native_1.View>);
341
+ case 'left':
342
+ default:
343
+ return (<react_native_1.View style={{ flexDirection: 'row', alignItems: 'center' }}>
344
+ {iconElement}
345
+ {labelElement}
346
+ </react_native_1.View>);
347
+ }
348
+ };
349
+ // Render tab list
350
+ const renderTabList = () => {
351
+ const actualTabCount = tabChildren.length || tabCount;
352
+ const tabButtons = Array.from({ length: actualTabCount }, (_, index) => {
353
+ const isActive = index === currentIndex;
354
+ const disabled = isTabDisabled(index);
355
+ return (<react_1.default.Fragment key={index}>
356
+ <react_native_1.TouchableOpacity style={getTabButtonStyle(isActive, disabled)} onPress={() => selectTab(index)} activeOpacity={disabled ? 1 : 0.7} disabled={disabled}>
357
+ {renderTabContent(index, isActive, disabled)}
358
+ </react_native_1.TouchableOpacity>
359
+ {variant === 'boxed' && index < actualTabCount - 1 && (<react_native_1.View style={styles.boxedDivider}/>)}
360
+ </react_1.default.Fragment>);
361
+ });
362
+ const tabListStyle = getTabListStyle();
363
+ // Phase 2: Handle overflow behavior
364
+ if (overflowBehavior === 'scroll') {
365
+ return (<react_native_1.ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={tabListStyle}>
366
+ {tabButtons}
367
+ </react_native_1.ScrollView>);
368
+ }
369
+ return (<react_native_1.View style={tabListStyle}>
370
+ {tabButtons}
371
+ </react_native_1.View>);
372
+ };
373
+ // Render content panel - no fallback to first panel
374
+ const renderContentPanel = () => {
375
+ const panel = contentPanels[currentIndex];
376
+ if (!panel) {
377
+ // Empty placeholder matching web style
378
+ return (<react_native_1.View style={styles.emptyPlaceholder}>
379
+ <react_native_1.Text style={styles.emptyPlaceholderText}>
380
+ No content panel for Tab {currentIndex + 1}
381
+ </react_native_1.Text>
382
+ </react_native_1.View>);
383
+ }
384
+ return (<react_native_1.View style={styles.contentPanel}>
385
+ {renderChild(panel, currentIndex)}
386
+ </react_native_1.View>);
387
+ };
388
+ if (!((_1 = component.children) === null || _1 === void 0 ? void 0 : _1.length)) {
389
+ return (<react_native_1.View style={styles.emptyContainer}>
390
+ <react_native_1.Text style={styles.emptyText}>Add tabs to the component</react_native_1.Text>
391
+ </react_native_1.View>);
392
+ }
393
+ return (<react_native_1.View style={styles.container}>
394
+ {renderTabList()}
395
+ {renderContentPanel()}
396
+ </react_native_1.View>);
397
+ };
398
+ exports.TabsComponent = TabsComponent;
399
+ const styles = react_native_1.StyleSheet.create({
400
+ container: {
401
+ flex: 1,
402
+ },
403
+ contentPanel: {
404
+ flex: 1,
405
+ },
406
+ boxedDivider: {
407
+ width: 1,
408
+ backgroundColor: '#e5e5e5',
409
+ },
410
+ emptyContainer: {
411
+ padding: 32,
412
+ alignItems: 'center',
413
+ justifyContent: 'center',
414
+ },
415
+ emptyText: {
416
+ color: '#999',
417
+ fontSize: 14,
418
+ },
419
+ emptyPlaceholder: {
420
+ minHeight: 100,
421
+ backgroundColor: 'rgba(128, 128, 128, 0.1)',
422
+ borderRadius: 8,
423
+ padding: 16,
424
+ alignItems: 'center',
425
+ justifyContent: 'center',
426
+ },
427
+ emptyPlaceholderText: {
428
+ color: 'rgba(128, 128, 128, 0.6)',
429
+ fontSize: 14,
430
+ },
431
+ });
@@ -0,0 +1,18 @@
1
+ /**
2
+ * TextInputComponent - React Native
3
+ *
4
+ * Form field for text/email/password input with validation.
5
+ * Features:
6
+ * - Multiple field types (text, email, password, phone, number)
7
+ * - Real-time validation
8
+ * - State manager integration for form data collection
9
+ */
10
+ import React from 'react';
11
+ import { PaywallComponent } from '../types';
12
+ interface TextInputComponentProps {
13
+ component: PaywallComponent;
14
+ stateManager?: any;
15
+ isPreviewMode?: boolean;
16
+ }
17
+ export declare const TextInputComponent: React.FC<TextInputComponentProps>;
18
+ export {};
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ /**
3
+ * TextInputComponent - React Native
4
+ *
5
+ * Form field for text/email/password input with validation.
6
+ * Features:
7
+ * - Multiple field types (text, email, password, phone, number)
8
+ * - Real-time validation
9
+ * - State manager integration for form data collection
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || (function () {
28
+ var ownKeys = function(o) {
29
+ ownKeys = Object.getOwnPropertyNames || function (o) {
30
+ var ar = [];
31
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
32
+ return ar;
33
+ };
34
+ return ownKeys(o);
35
+ };
36
+ return function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ })();
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.TextInputComponent = void 0;
46
+ const react_1 = __importStar(require("react"));
47
+ const react_native_1 = require("react-native");
48
+ // Validation patterns
49
+ const VALIDATION_PATTERNS = {
50
+ email: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
51
+ phone: /^[\d\s\-+()]{7,20}$/,
52
+ url: /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/,
53
+ };
54
+ const TextInputComponent = ({ component, stateManager, isPreviewMode = false, }) => {
55
+ var _a;
56
+ const props = component.properties;
57
+ const componentId = component.id;
58
+ // Extract props
59
+ const fieldType = props.fieldType || 'text';
60
+ const placeholder = props.placeholder || 'Enter text...';
61
+ const label = props.label;
62
+ const helperText = props.helperText;
63
+ const defaultValue = props.defaultValue || '';
64
+ const required = props.required || false;
65
+ const minLength = props.minLength || 0;
66
+ const maxLength = props.maxLength || 255;
67
+ const fontSize = props.fontSize || 16;
68
+ const textColor = props.textColor || '#000000';
69
+ const placeholderColor = props.placeholderColor || '#9CA3AF';
70
+ const labelColor = props.labelColor || '#374151';
71
+ const errorColor = props.errorColor || '#EF4444';
72
+ const backgroundColor = ((_a = props.backgroundColor) === null || _a === void 0 ? void 0 : _a.color) || '#FFFFFF';
73
+ const borderColor = props.borderColor || '#D1D5DB';
74
+ const focusBorderColor = props.focusBorderColor || '#3B82F6';
75
+ const errorBorderColor = props.errorBorderColor || '#EF4444';
76
+ const borderRadius = props.borderRadius || 8;
77
+ const borderWidth = props.borderWidth || 1;
78
+ const inputHeight = props.inputHeight || 48;
79
+ const [value, setValue] = (0, react_1.useState)(defaultValue);
80
+ const [isFocused, setIsFocused] = (0, react_1.useState)(false);
81
+ const [showPassword, setShowPassword] = (0, react_1.useState)(false);
82
+ const [errors, setErrors] = (0, react_1.useState)([]);
83
+ const [touched, setTouched] = (0, react_1.useState)(false);
84
+ // Validate value
85
+ const validate = (0, react_1.useCallback)((val) => {
86
+ const validationErrors = [];
87
+ if (required && !val.trim()) {
88
+ validationErrors.push('This field is required');
89
+ }
90
+ if (val.length > 0 && minLength > 0 && val.length < minLength) {
91
+ validationErrors.push(`Must be at least ${minLength} characters`);
92
+ }
93
+ if (val.length > maxLength) {
94
+ validationErrors.push(`Must be less than ${maxLength} characters`);
95
+ }
96
+ if (fieldType === 'email' && val && !VALIDATION_PATTERNS.email.test(val)) {
97
+ validationErrors.push('Please enter a valid email address');
98
+ }
99
+ if (fieldType === 'phone' && val && !VALIDATION_PATTERNS.phone.test(val)) {
100
+ validationErrors.push('Please enter a valid phone number');
101
+ }
102
+ return validationErrors;
103
+ }, [required, minLength, maxLength, fieldType]);
104
+ // Update state manager when value changes
105
+ (0, react_1.useEffect)(() => {
106
+ if (stateManager) {
107
+ const validationErrors = validate(value);
108
+ const isValid = validationErrors.length === 0;
109
+ stateManager.updateState(`element:${componentId}.value`, value);
110
+ stateManager.updateState(`element:${componentId}.isValid`, isValid);
111
+ stateManager.updateState(`element:${componentId}.fieldData`, {
112
+ fieldId: componentId,
113
+ fieldType,
114
+ value,
115
+ isValid,
116
+ validationErrors,
117
+ });
118
+ }
119
+ }, [value, componentId, fieldType, stateManager, validate]);
120
+ // Subscribe to external state changes
121
+ (0, react_1.useEffect)(() => {
122
+ if (stateManager) {
123
+ return stateManager.subscribeToState(`element:${componentId}.value`, (newValue) => {
124
+ if (newValue !== value) {
125
+ setValue(newValue);
126
+ }
127
+ });
128
+ }
129
+ }, [componentId, stateManager, value]);
130
+ // Handle input change
131
+ const handleChange = (0, react_1.useCallback)((text) => {
132
+ setValue(text);
133
+ if (touched) {
134
+ setErrors(validate(text));
135
+ }
136
+ }, [touched, validate]);
137
+ // Handle blur
138
+ const handleBlur = (0, react_1.useCallback)(() => {
139
+ setIsFocused(false);
140
+ setTouched(true);
141
+ setErrors(validate(value));
142
+ }, [value, validate]);
143
+ // Determine keyboard type
144
+ const keyboardType = (0, react_1.useMemo)(() => {
145
+ switch (fieldType) {
146
+ case 'email': return 'email-address';
147
+ case 'phone': return 'phone-pad';
148
+ case 'number': return 'numeric';
149
+ default: return 'default';
150
+ }
151
+ }, [fieldType]);
152
+ // Current border color
153
+ const currentBorderColor = errors.length > 0 && touched
154
+ ? errorBorderColor
155
+ : isFocused
156
+ ? focusBorderColor
157
+ : borderColor;
158
+ const hasError = errors.length > 0 && touched;
159
+ return (<react_native_1.View style={styles.container}>
160
+ {/* Label */}
161
+ {label && (<react_native_1.Text style={[styles.label, { fontSize: fontSize - 2, color: labelColor }]}>
162
+ {label}
163
+ {required && <react_native_1.Text style={{ color: errorColor }}> *</react_native_1.Text>}
164
+ </react_native_1.Text>)}
165
+
166
+ {/* Input Container */}
167
+ <react_native_1.View style={styles.inputContainer}>
168
+ <react_native_1.TextInput value={value} onChangeText={handleChange} onFocus={() => setIsFocused(true)} onBlur={handleBlur} placeholder={placeholder} placeholderTextColor={placeholderColor} maxLength={maxLength} keyboardType={keyboardType} secureTextEntry={fieldType === 'password' && !showPassword} autoCapitalize={fieldType === 'email' ? 'none' : 'sentences'} autoCorrect={fieldType !== 'email' && fieldType !== 'password'} style={[
169
+ styles.input,
170
+ {
171
+ height: inputHeight,
172
+ fontSize,
173
+ color: textColor,
174
+ backgroundColor,
175
+ borderColor: currentBorderColor,
176
+ borderRadius,
177
+ borderWidth,
178
+ paddingRight: fieldType === 'password' ? 48 : 16,
179
+ },
180
+ ]}/>
181
+
182
+ {/* Password Toggle */}
183
+ {fieldType === 'password' && (<react_native_1.TouchableOpacity style={styles.passwordToggle} onPress={() => setShowPassword(!showPassword)}>
184
+ <react_native_1.Text style={{ color: placeholderColor, fontSize: 12 }}>
185
+ {showPassword ? 'HIDE' : 'SHOW'}
186
+ </react_native_1.Text>
187
+ </react_native_1.TouchableOpacity>)}
188
+ </react_native_1.View>
189
+
190
+ {/* Helper Text / Error */}
191
+ {(helperText || hasError) && (<react_native_1.Text style={[
192
+ styles.helperText,
193
+ {
194
+ fontSize: fontSize - 4,
195
+ color: hasError ? errorColor : placeholderColor,
196
+ },
197
+ ]}>
198
+ {hasError ? errors[0] : helperText}
199
+ </react_native_1.Text>)}
200
+ </react_native_1.View>);
201
+ };
202
+ exports.TextInputComponent = TextInputComponent;
203
+ const styles = react_native_1.StyleSheet.create({
204
+ container: {
205
+ width: '100%',
206
+ },
207
+ label: {
208
+ fontWeight: '500',
209
+ marginBottom: 6,
210
+ },
211
+ inputContainer: {
212
+ position: 'relative',
213
+ },
214
+ input: {
215
+ paddingHorizontal: 16,
216
+ },
217
+ passwordToggle: {
218
+ position: 'absolute',
219
+ right: 16,
220
+ top: 0,
221
+ bottom: 0,
222
+ justifyContent: 'center',
223
+ },
224
+ helperText: {
225
+ marginTop: 4,
226
+ },
227
+ });