@teamvortexsoftware/vortex-react-native 1.0.0 → 1.0.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 (217) hide show
  1. package/dist/InviteFormCore-D4HkMMo0.d.mts +721 -0
  2. package/dist/InviteFormCore-D9oUCbu7.d.ts +721 -0
  3. package/dist/VortexClient.js +192 -0
  4. package/dist/VortexClient.js.map +1 -0
  5. package/dist/VortexDeferredLinks.js +127 -0
  6. package/dist/VortexDeferredLinks.js.map +1 -0
  7. package/dist/clientInfo.js +45 -0
  8. package/dist/clientInfo.js.map +1 -0
  9. package/dist/components/ContactsPickerModal.js +182 -0
  10. package/dist/components/ContactsPickerModal.js.map +1 -0
  11. package/dist/components/InviteFormCore.js +2141 -0
  12. package/dist/components/InviteFormCore.js.map +1 -0
  13. package/dist/components/InviteFormMobile.js +463 -0
  14. package/dist/components/InviteFormMobile.js.map +1 -0
  15. package/dist/components/InviteFormWeb.js +295 -0
  16. package/dist/components/InviteFormWeb.js.map +1 -0
  17. package/dist/components/PlacedItemToolbar.js +147 -0
  18. package/dist/components/PlacedItemToolbar.js.map +1 -0
  19. package/dist/components/ShareButtons.js +181 -0
  20. package/dist/components/ShareButtons.js.map +1 -0
  21. package/dist/components/VrtxContactsImport.js +234 -0
  22. package/dist/components/VrtxContactsImport.js.map +1 -0
  23. package/dist/components/VrtxEmailInvitations.js +341 -0
  24. package/dist/components/VrtxEmailInvitations.js.map +1 -0
  25. package/dist/components/VrtxFindFriends.js +400 -0
  26. package/dist/components/VrtxFindFriends.js.map +1 -0
  27. package/dist/components/VrtxHeading.js +58 -0
  28. package/dist/components/VrtxHeading.js.map +1 -0
  29. package/dist/components/VrtxIncomingInvitations.js +657 -0
  30. package/dist/components/VrtxIncomingInvitations.js.map +1 -0
  31. package/dist/components/VrtxInvitationSuggestions.js +506 -0
  32. package/dist/components/VrtxInvitationSuggestions.js.map +1 -0
  33. package/dist/components/VrtxInviteContacts.js +512 -0
  34. package/dist/components/VrtxInviteContacts.js.map +1 -0
  35. package/dist/components/VrtxOutgoingInvitations.js +572 -0
  36. package/dist/components/VrtxOutgoingInvitations.js.map +1 -0
  37. package/dist/components/VrtxSearchBox.js +487 -0
  38. package/dist/components/VrtxSearchBox.js.map +1 -0
  39. package/dist/components/VrtxSelect.js +27 -0
  40. package/dist/components/VrtxSelect.js.map +1 -0
  41. package/dist/components/VrtxShareOptions.js +435 -0
  42. package/dist/components/VrtxShareOptions.js.map +1 -0
  43. package/dist/components/VrtxSubmit.js +132 -0
  44. package/dist/components/VrtxSubmit.js.map +1 -0
  45. package/dist/components/VrtxText.js +146 -0
  46. package/dist/components/VrtxText.js.map +1 -0
  47. package/dist/constants/mockData.d.mts +7 -0
  48. package/dist/constants/mockData.d.ts +7 -0
  49. package/dist/constants/mockData.js +48 -0
  50. package/dist/constants/mockData.js.map +1 -0
  51. package/dist/constants/mockData.mjs +22 -0
  52. package/dist/constants/mockData.mjs.map +1 -0
  53. package/dist/context/VortexModulesContext.js +135 -0
  54. package/dist/context/VortexModulesContext.js.map +1 -0
  55. package/dist/hooks/useInvitationFormLogic.d.mts +2 -0
  56. package/dist/hooks/useInvitationFormLogic.d.ts +2 -0
  57. package/dist/hooks/useInvitationFormLogic.js +300 -0
  58. package/dist/hooks/useInvitationFormLogic.js.map +1 -0
  59. package/dist/hooks/useInvitationFormLogic.mjs +276 -0
  60. package/dist/hooks/useInvitationFormLogic.mjs.map +1 -0
  61. package/dist/hooks/usePrefetchWidgetConfiguration.js +117 -0
  62. package/dist/hooks/usePrefetchWidgetConfiguration.js.map +1 -0
  63. package/dist/hooks/useThemeStyles.js +41 -0
  64. package/dist/hooks/useThemeStyles.js.map +1 -0
  65. package/dist/hooks/useVortexInvite.js +732 -0
  66. package/dist/hooks/useVortexInvite.js.map +1 -0
  67. package/dist/index-web.d.mts +93 -0
  68. package/dist/index-web.d.ts +93 -0
  69. package/dist/index-web.js +7397 -0
  70. package/dist/index-web.js.map +1 -0
  71. package/dist/index-web.mjs +7445 -0
  72. package/dist/index-web.mjs.map +1 -0
  73. package/dist/index.d.mts +656 -0
  74. package/dist/index.d.ts +656 -0
  75. package/dist/index.js +10206 -0
  76. package/dist/index.js.map +1 -0
  77. package/dist/index.mjs +10244 -0
  78. package/dist/index.mjs.map +1 -0
  79. package/dist/types/VortexClient.d.ts +106 -0
  80. package/dist/types/VortexClient.d.ts.map +1 -0
  81. package/dist/types/VortexDeferredLinks.d.ts +73 -0
  82. package/dist/types/VortexDeferredLinks.d.ts.map +1 -0
  83. package/dist/types/clientInfo.d.ts +5 -0
  84. package/dist/types/clientInfo.d.ts.map +1 -0
  85. package/dist/types/components/ContactsPickerModal.d.ts +18 -0
  86. package/dist/types/components/ContactsPickerModal.d.ts.map +1 -0
  87. package/dist/types/components/InviteFormCore.d.ts +166 -0
  88. package/dist/types/components/InviteFormCore.d.ts.map +1 -0
  89. package/dist/types/components/InviteFormMobile.d.ts +42 -0
  90. package/dist/types/components/InviteFormMobile.d.ts.map +1 -0
  91. package/dist/types/components/InviteFormWeb.d.ts +87 -0
  92. package/dist/types/components/InviteFormWeb.d.ts.map +1 -0
  93. package/dist/types/components/PlacedItemToolbar.d.ts +16 -0
  94. package/dist/types/components/PlacedItemToolbar.d.ts.map +1 -0
  95. package/dist/types/components/ShareButtons.d.ts +29 -0
  96. package/dist/types/components/ShareButtons.d.ts.map +1 -0
  97. package/dist/types/components/VrtxContactsImport.d.ts +14 -0
  98. package/dist/types/components/VrtxContactsImport.d.ts.map +1 -0
  99. package/dist/types/components/VrtxEmailInvitations.d.ts +31 -0
  100. package/dist/types/components/VrtxEmailInvitations.d.ts.map +1 -0
  101. package/dist/types/components/VrtxFindFriends.d.ts +25 -0
  102. package/dist/types/components/VrtxFindFriends.d.ts.map +1 -0
  103. package/dist/types/components/VrtxHeading.d.ts +6 -0
  104. package/dist/types/components/VrtxHeading.d.ts.map +1 -0
  105. package/dist/types/components/VrtxIncomingInvitations.d.ts +27 -0
  106. package/dist/types/components/VrtxIncomingInvitations.d.ts.map +1 -0
  107. package/dist/types/components/VrtxInvitationSuggestions.d.ts +25 -0
  108. package/dist/types/components/VrtxInvitationSuggestions.d.ts.map +1 -0
  109. package/dist/types/components/VrtxInviteContacts.d.ts +24 -0
  110. package/dist/types/components/VrtxInviteContacts.d.ts.map +1 -0
  111. package/dist/types/components/VrtxOutgoingInvitations.d.ts +27 -0
  112. package/dist/types/components/VrtxOutgoingInvitations.d.ts.map +1 -0
  113. package/dist/types/components/VrtxSearchBox.d.ts +28 -0
  114. package/dist/types/components/VrtxSearchBox.d.ts.map +1 -0
  115. package/dist/types/components/VrtxSelect.d.ts +6 -0
  116. package/dist/types/components/VrtxSelect.d.ts.map +1 -0
  117. package/dist/types/components/VrtxShareOptions.d.ts +41 -0
  118. package/dist/types/components/VrtxShareOptions.d.ts.map +1 -0
  119. package/dist/types/components/VrtxSubmit.d.ts +18 -0
  120. package/dist/types/components/VrtxSubmit.d.ts.map +1 -0
  121. package/dist/types/components/VrtxText.d.ts +8 -0
  122. package/dist/types/components/VrtxText.d.ts.map +1 -0
  123. package/dist/types/constants/mockData.d.ts +4 -0
  124. package/dist/types/constants/mockData.d.ts.map +1 -0
  125. package/dist/types/context/VortexModulesContext.d.ts +238 -0
  126. package/dist/types/context/VortexModulesContext.d.ts.map +1 -0
  127. package/dist/types/findFriends.js +10 -0
  128. package/dist/types/findFriends.js.map +1 -0
  129. package/dist/types/hooks/useInvitationFormLogic.d.ts +55 -0
  130. package/dist/types/hooks/useInvitationFormLogic.d.ts.map +1 -0
  131. package/dist/types/hooks/usePrefetchWidgetConfiguration.d.ts +39 -0
  132. package/dist/types/hooks/usePrefetchWidgetConfiguration.d.ts.map +1 -0
  133. package/dist/types/hooks/useThemeStyles.d.ts +35 -0
  134. package/dist/types/hooks/useThemeStyles.d.ts.map +1 -0
  135. package/dist/types/hooks/useVortexInvite.d.ts +86 -0
  136. package/dist/types/hooks/useVortexInvite.d.ts.map +1 -0
  137. package/dist/types/index-web.d.ts +23 -0
  138. package/dist/types/index-web.d.ts.map +1 -0
  139. package/dist/types/index.d.ts +23 -0
  140. package/dist/types/index.d.ts.map +1 -0
  141. package/dist/types/invitations.js +13 -0
  142. package/dist/types/invitations.js.map +1 -0
  143. package/dist/types/inviteContacts.js +14 -0
  144. package/dist/types/inviteContacts.js.map +1 -0
  145. package/dist/types/platformOperations.js +3 -0
  146. package/dist/types/platformOperations.js.map +1 -0
  147. package/dist/types/searchBox.js +11 -0
  148. package/dist/types/searchBox.js.map +1 -0
  149. package/dist/types/types/findFriends.d.ts +101 -0
  150. package/dist/types/types/findFriends.d.ts.map +1 -0
  151. package/dist/types/types/invitations.d.ts +301 -0
  152. package/dist/types/types/invitations.d.ts.map +1 -0
  153. package/dist/types/types/inviteContacts.d.ts +86 -0
  154. package/dist/types/types/inviteContacts.d.ts.map +1 -0
  155. package/dist/types/types/platformOperations.d.ts +185 -0
  156. package/dist/types/types/platformOperations.d.ts.map +1 -0
  157. package/dist/types/types/searchBox.d.ts +69 -0
  158. package/dist/types/types/searchBox.d.ts.map +1 -0
  159. package/dist/types/types/unfurlConfig.d.ts +34 -0
  160. package/dist/types/types/unfurlConfig.d.ts.map +1 -0
  161. package/dist/types/unfurlConfig.js +21 -0
  162. package/dist/types/unfurlConfig.js.map +1 -0
  163. package/dist/types/utils/analytics.d.ts +54 -0
  164. package/dist/types/utils/analytics.d.ts.map +1 -0
  165. package/dist/types/utils/configCache.d.ts +34 -0
  166. package/dist/types/utils/configCache.d.ts.map +1 -0
  167. package/dist/types/utils/contactUtils.d.ts +9 -0
  168. package/dist/types/utils/contactUtils.d.ts.map +1 -0
  169. package/dist/types/utils/featureWarnings.d.ts +56 -0
  170. package/dist/types/utils/featureWarnings.d.ts.map +1 -0
  171. package/dist/types/utils/formUtils.d.ts +93 -0
  172. package/dist/types/utils/formUtils.d.ts.map +1 -0
  173. package/dist/types/utils/gradientUtils.d.ts +67 -0
  174. package/dist/types/utils/gradientUtils.d.ts.map +1 -0
  175. package/dist/types/utils/invitationEvents.d.ts +21 -0
  176. package/dist/types/utils/invitationEvents.d.ts.map +1 -0
  177. package/dist/types/utils/moduleLoaders.d.ts +115 -0
  178. package/dist/types/utils/moduleLoaders.d.ts.map +1 -0
  179. package/dist/types/utils/moduleLoaders.web.d.ts +73 -0
  180. package/dist/types/utils/moduleLoaders.web.d.ts.map +1 -0
  181. package/dist/types/utils/nameUtils.d.ts +15 -0
  182. package/dist/types/utils/nameUtils.d.ts.map +1 -0
  183. package/dist/types/utils/themeUtils.d.ts +38 -0
  184. package/dist/types/utils/themeUtils.d.ts.map +1 -0
  185. package/dist/types/vortexInvite.d.ts +165 -0
  186. package/dist/types/vortexInvite.d.ts.map +1 -0
  187. package/dist/useInvitationFormLogic-Ct73M19B.d.mts +242 -0
  188. package/dist/useInvitationFormLogic-Ct73M19B.d.ts +242 -0
  189. package/dist/utils/analytics.js +92 -0
  190. package/dist/utils/analytics.js.map +1 -0
  191. package/dist/utils/configCache.js +68 -0
  192. package/dist/utils/configCache.js.map +1 -0
  193. package/dist/utils/contactUtils.d.mts +12 -0
  194. package/dist/utils/contactUtils.d.ts +12 -0
  195. package/dist/utils/contactUtils.js +37 -0
  196. package/dist/utils/contactUtils.js.map +1 -0
  197. package/dist/utils/contactUtils.mjs +12 -0
  198. package/dist/utils/contactUtils.mjs.map +1 -0
  199. package/dist/utils/featureWarnings.js +214 -0
  200. package/dist/utils/featureWarnings.js.map +1 -0
  201. package/dist/utils/formUtils.js +284 -0
  202. package/dist/utils/formUtils.js.map +1 -0
  203. package/dist/utils/gradientUtils.js +120 -0
  204. package/dist/utils/gradientUtils.js.map +1 -0
  205. package/dist/utils/invitationEvents.js +45 -0
  206. package/dist/utils/invitationEvents.js.map +1 -0
  207. package/dist/utils/moduleLoaders.js +275 -0
  208. package/dist/utils/moduleLoaders.js.map +1 -0
  209. package/dist/utils/moduleLoaders.web.js +72 -0
  210. package/dist/utils/moduleLoaders.web.js.map +1 -0
  211. package/dist/utils/nameUtils.js +51 -0
  212. package/dist/utils/nameUtils.js.map +1 -0
  213. package/dist/utils/themeUtils.js +141 -0
  214. package/dist/utils/themeUtils.js.map +1 -0
  215. package/dist/vortexInvite.js +83 -0
  216. package/dist/vortexInvite.js.map +1 -0
  217. package/package.json +21 -56
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ /**
3
+ * Feature Warnings
4
+ *
5
+ * This module provides feature detection and helpful warnings for missing module configurations.
6
+ * It scans widget configuration to detect which features are required and prints actionable
7
+ * warnings when the corresponding module props are not specified.
8
+ *
9
+ * Warnings are only printed in development mode (__DEV__) and on native platforms.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.detectRequiredFeatures = detectRequiredFeatures;
13
+ exports.printFeatureWarnings = printFeatureWarnings;
14
+ exports.printWarningOnce = printWarningOnce;
15
+ exports.printInfoOnce = printInfoOnce;
16
+ exports.clearWarningsCache = clearWarningsCache;
17
+ const react_native_1 = require("react-native");
18
+ /**
19
+ * Recursively scans a node tree for gradient backgrounds.
20
+ */
21
+ function scanForGradients(node) {
22
+ var _a, _b, _c, _d, _e, _f;
23
+ if (!node)
24
+ return false;
25
+ // Check style.background for linear-gradient
26
+ if ((_c = (_b = (_a = node.style) === null || _a === void 0 ? void 0 : _a.background) === null || _b === void 0 ? void 0 : _b.includes) === null || _c === void 0 ? void 0 : _c.call(_b, 'linear-gradient')) {
27
+ return true;
28
+ }
29
+ // Check theme options for gradients
30
+ if (((_d = node.theme) === null || _d === void 0 ? void 0 : _d.options) && Array.isArray(node.theme.options)) {
31
+ for (const option of node.theme.options) {
32
+ if ((_f = (_e = option.value) === null || _e === void 0 ? void 0 : _e.includes) === null || _f === void 0 ? void 0 : _f.call(_e, 'linear-gradient')) {
33
+ return true;
34
+ }
35
+ }
36
+ }
37
+ // Recursively check children
38
+ if (node.children && Array.isArray(node.children)) {
39
+ for (const child of node.children) {
40
+ if (scanForGradients(child))
41
+ return true;
42
+ }
43
+ }
44
+ return false;
45
+ }
46
+ /**
47
+ * Recursively scans a node tree for QR code elements.
48
+ */
49
+ function scanForQRCode(node) {
50
+ if (!node)
51
+ return false;
52
+ if (node.type === 'vrtx-qr-code' || node.tagName === 'vrtx-qr-code') {
53
+ return true;
54
+ }
55
+ if (node.children && Array.isArray(node.children)) {
56
+ for (const child of node.children) {
57
+ if (scanForQRCode(child))
58
+ return true;
59
+ }
60
+ }
61
+ return false;
62
+ }
63
+ /**
64
+ * Recursively scans a node tree for share options (which need clipboard).
65
+ */
66
+ function scanForShareOptions(node) {
67
+ if (!node)
68
+ return false;
69
+ if (node.type === 'vrtx-share-options' || node.tagName === 'vrtx-share-options') {
70
+ return true;
71
+ }
72
+ if (node.children && Array.isArray(node.children)) {
73
+ for (const child of node.children) {
74
+ if (scanForShareOptions(child))
75
+ return true;
76
+ }
77
+ }
78
+ return false;
79
+ }
80
+ /**
81
+ * Detects which features are required based on widget configuration.
82
+ *
83
+ * @param widgetConfiguration - The widget configuration from the API
84
+ * @returns Object indicating which features are needed
85
+ */
86
+ function detectRequiredFeatures(widgetConfiguration) {
87
+ var _a;
88
+ const requirements = {
89
+ needsGradient: false,
90
+ needsQRCode: false,
91
+ needsHaptics: true, // Always nice to have for buttons
92
+ needsClipboard: false,
93
+ };
94
+ if (!widgetConfiguration)
95
+ return requirements;
96
+ const rootElement = ((_a = widgetConfiguration.data) === null || _a === void 0 ? void 0 : _a.rootElement) || widgetConfiguration.rootElement;
97
+ requirements.needsGradient = scanForGradients(rootElement);
98
+ requirements.needsQRCode = scanForQRCode(rootElement);
99
+ requirements.needsClipboard = scanForShareOptions(rootElement);
100
+ return requirements;
101
+ }
102
+ /**
103
+ * Prints helpful warnings for missing module configurations.
104
+ * Only prints in development mode and on native platforms.
105
+ * Uses deduplication helpers to prevent warnings from printing on every render.
106
+ *
107
+ * @param requirements - The detected feature requirements
108
+ * @param moduleConfig - The current module configuration from props
109
+ */
110
+ function printFeatureWarnings(requirements, moduleConfig) {
111
+ var _a, _b, _c, _d;
112
+ // Only warn in development and on native platforms
113
+ if (!__DEV__ || react_native_1.Platform.OS === 'web')
114
+ return;
115
+ // Check for module configuration
116
+ const hasGradientModule = (_a = moduleConfig.modules) === null || _a === void 0 ? void 0 : _a.gradient;
117
+ const hasQRCodeModule = (_b = moduleConfig.modules) === null || _b === void 0 ? void 0 : _b.qrCode;
118
+ const hasHapticsModule = (_c = moduleConfig.modules) === null || _c === void 0 ? void 0 : _c.haptics;
119
+ const hasClipboardModule = (_d = moduleConfig.modules) === null || _d === void 0 ? void 0 : _d.clipboard;
120
+ // Gradient warning
121
+ if (requirements.needsGradient && !hasGradientModule) {
122
+ printWarningOnce('vortex-gradient-module', `[Vortex] ⚠️ Gradient backgrounds detected in widget configuration, but no gradient module specified.
123
+
124
+ To enable gradients on native platforms, add the modules prop to <VortexInvite>:
125
+
126
+ For Expo projects:
127
+ <VortexInvite modules={{ gradient: 'expo-linear-gradient' }} ... />
128
+ Then run: npx expo install expo-linear-gradient
129
+
130
+ For bare React Native:
131
+ <VortexInvite modules={{ gradient: 'react-native-linear-gradient' }} ... />
132
+ Then run: npm install react-native-linear-gradient
133
+
134
+ Without a gradient module, gradient backgrounds will fall back to solid colors.
135
+ `);
136
+ }
137
+ // QR Code warning
138
+ if (requirements.needsQRCode && !hasQRCodeModule) {
139
+ printWarningOnce('vortex-qrcode-module', `[Vortex] ⚠️ QR Code feature detected in widget configuration, but no QR code module specified.
140
+
141
+ To enable QR codes, add the modules prop to <VortexInvite>:
142
+
143
+ For native apps:
144
+ <VortexInvite modules={{ qrCode: 'react-native-qrcode-svg' }} ... />
145
+ Then run: npm install react-native-qrcode-svg react-native-svg
146
+
147
+ For web preview:
148
+ <VortexInvite modules={{ qrCode: 'react-qr-code' }} ... />
149
+ Then run: npm install react-qr-code
150
+
151
+ Without a QR code module, QR codes will show a placeholder message.
152
+ `);
153
+ }
154
+ // Haptics info (less critical)
155
+ if (requirements.needsHaptics && !hasHapticsModule) {
156
+ printInfoOnce('vortex-haptics-module', `[Vortex] 💡 Tip: Add haptic feedback for better UX:
157
+
158
+ <VortexInvite modules={{ haptics: 'expo-haptics' }} ... />
159
+ Then run: npx expo install expo-haptics
160
+ `);
161
+ }
162
+ // Clipboard info (only if share options are present)
163
+ if (requirements.needsClipboard && !hasClipboardModule) {
164
+ printInfoOnce('vortex-clipboard-module', `[Vortex] 💡 Tip: For clipboard support (Copy Link), add:
165
+
166
+ For Expo projects:
167
+ <VortexInvite modules={{ clipboard: 'expo-clipboard' }} ... />
168
+ Then run: npx expo install expo-clipboard
169
+
170
+ For bare React Native:
171
+ <VortexInvite modules={{ clipboard: '@react-native-clipboard/clipboard' }} ... />
172
+ Then run: npm install @react-native-clipboard/clipboard
173
+
174
+ Without a clipboard module, the SDK will use React Native's built-in Clipboard API.
175
+ `);
176
+ }
177
+ }
178
+ /**
179
+ * Tracks which warnings have been printed to avoid duplicate warnings.
180
+ */
181
+ const printedWarnings = new Set();
182
+ /**
183
+ * Prints a warning only once per session.
184
+ * Useful for warnings that shouldn't spam the console on every render.
185
+ *
186
+ * @param key - Unique key for this warning
187
+ * @param message - The warning message to print
188
+ */
189
+ function printWarningOnce(key, message) {
190
+ if (!__DEV__ || printedWarnings.has(key))
191
+ return;
192
+ printedWarnings.add(key);
193
+ console.warn(message);
194
+ }
195
+ /**
196
+ * Prints an info message only once per session.
197
+ *
198
+ * @param key - Unique key for this message
199
+ * @param message - The info message to print
200
+ */
201
+ function printInfoOnce(key, message) {
202
+ if (!__DEV__ || printedWarnings.has(key))
203
+ return;
204
+ printedWarnings.add(key);
205
+ console.info(message);
206
+ }
207
+ /**
208
+ * Clears the printed warnings cache.
209
+ * Useful for testing or when you want warnings to be printed again.
210
+ */
211
+ function clearWarningsCache() {
212
+ printedWarnings.clear();
213
+ }
214
+ //# sourceMappingURL=featureWarnings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"featureWarnings.js","sourceRoot":"","sources":["../../src/utils/featureWarnings.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Feature Warnings\n *\n * This module provides feature detection and helpful warnings for missing module configurations.\n * It scans widget configuration to detect which features are required and prints actionable\n * warnings when the corresponding module props are not specified.\n *\n * Warnings are only printed in development mode (__DEV__) and on native platforms.\n */\n\nimport { Platform } from 'react-native';\nimport type { VortexModulesConfig } from '../context/VortexModulesContext';\n\n/**\n * Features that may be required based on widget configuration\n */\nexport interface FeatureRequirements {\n needsGradient: boolean;\n needsQRCode: boolean;\n needsHaptics: boolean;\n needsClipboard: boolean;\n}\n\n/**\n * Recursively scans a node tree for gradient backgrounds.\n */\nfunction scanForGradients(node: any): boolean {\n if (!node) return false;\n\n // Check style.background for linear-gradient\n if (node.style?.background?.includes?.('linear-gradient')) {\n return true;\n }\n\n // Check theme options for gradients\n if (node.theme?.options && Array.isArray(node.theme.options)) {\n for (const option of node.theme.options) {\n if (option.value?.includes?.('linear-gradient')) {\n return true;\n }\n }\n }\n\n // Recursively check children\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n if (scanForGradients(child)) return true;\n }\n }\n\n return false;\n}\n\n/**\n * Recursively scans a node tree for QR code elements.\n */\nfunction scanForQRCode(node: any): boolean {\n if (!node) return false;\n\n if (node.type === 'vrtx-qr-code' || node.tagName === 'vrtx-qr-code') {\n return true;\n }\n\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n if (scanForQRCode(child)) return true;\n }\n }\n\n return false;\n}\n\n/**\n * Recursively scans a node tree for share options (which need clipboard).\n */\nfunction scanForShareOptions(node: any): boolean {\n if (!node) return false;\n\n if (node.type === 'vrtx-share-options' || node.tagName === 'vrtx-share-options') {\n return true;\n }\n\n if (node.children && Array.isArray(node.children)) {\n for (const child of node.children) {\n if (scanForShareOptions(child)) return true;\n }\n }\n\n return false;\n}\n\n/**\n * Detects which features are required based on widget configuration.\n *\n * @param widgetConfiguration - The widget configuration from the API\n * @returns Object indicating which features are needed\n */\nexport function detectRequiredFeatures(widgetConfiguration: any): FeatureRequirements {\n const requirements: FeatureRequirements = {\n needsGradient: false,\n needsQRCode: false,\n needsHaptics: true, // Always nice to have for buttons\n needsClipboard: false,\n };\n\n if (!widgetConfiguration) return requirements;\n\n const rootElement =\n widgetConfiguration.data?.rootElement || widgetConfiguration.rootElement;\n\n requirements.needsGradient = scanForGradients(rootElement);\n requirements.needsQRCode = scanForQRCode(rootElement);\n requirements.needsClipboard = scanForShareOptions(rootElement);\n\n return requirements;\n}\n\n/**\n * Prints helpful warnings for missing module configurations.\n * Only prints in development mode and on native platforms.\n * Uses deduplication helpers to prevent warnings from printing on every render.\n *\n * @param requirements - The detected feature requirements\n * @param moduleConfig - The current module configuration from props\n */\nexport function printFeatureWarnings(\n requirements: FeatureRequirements,\n moduleConfig: VortexModulesConfig\n): void {\n // Only warn in development and on native platforms\n if (!__DEV__ || Platform.OS === 'web') return;\n\n // Check for module configuration\n const hasGradientModule = moduleConfig.modules?.gradient;\n const hasQRCodeModule = moduleConfig.modules?.qrCode;\n const hasHapticsModule = moduleConfig.modules?.haptics;\n const hasClipboardModule = moduleConfig.modules?.clipboard;\n\n // Gradient warning\n if (requirements.needsGradient && !hasGradientModule) {\n printWarningOnce(\n 'vortex-gradient-module',\n `[Vortex] ⚠️ Gradient backgrounds detected in widget configuration, but no gradient module specified.\n\nTo enable gradients on native platforms, add the modules prop to <VortexInvite>:\n\n For Expo projects:\n <VortexInvite modules={{ gradient: 'expo-linear-gradient' }} ... />\n Then run: npx expo install expo-linear-gradient\n\n For bare React Native:\n <VortexInvite modules={{ gradient: 'react-native-linear-gradient' }} ... />\n Then run: npm install react-native-linear-gradient\n\nWithout a gradient module, gradient backgrounds will fall back to solid colors.\n`\n );\n }\n\n // QR Code warning\n if (requirements.needsQRCode && !hasQRCodeModule) {\n printWarningOnce(\n 'vortex-qrcode-module',\n `[Vortex] ⚠️ QR Code feature detected in widget configuration, but no QR code module specified.\n\nTo enable QR codes, add the modules prop to <VortexInvite>:\n\n For native apps:\n <VortexInvite modules={{ qrCode: 'react-native-qrcode-svg' }} ... />\n Then run: npm install react-native-qrcode-svg react-native-svg\n\n For web preview:\n <VortexInvite modules={{ qrCode: 'react-qr-code' }} ... />\n Then run: npm install react-qr-code\n\nWithout a QR code module, QR codes will show a placeholder message.\n`\n );\n }\n\n // Haptics info (less critical)\n if (requirements.needsHaptics && !hasHapticsModule) {\n printInfoOnce(\n 'vortex-haptics-module',\n `[Vortex] 💡 Tip: Add haptic feedback for better UX:\n\n <VortexInvite modules={{ haptics: 'expo-haptics' }} ... />\n Then run: npx expo install expo-haptics\n`\n );\n }\n\n // Clipboard info (only if share options are present)\n if (requirements.needsClipboard && !hasClipboardModule) {\n printInfoOnce(\n 'vortex-clipboard-module',\n `[Vortex] 💡 Tip: For clipboard support (Copy Link), add:\n\n For Expo projects:\n <VortexInvite modules={{ clipboard: 'expo-clipboard' }} ... />\n Then run: npx expo install expo-clipboard\n\n For bare React Native:\n <VortexInvite modules={{ clipboard: '@react-native-clipboard/clipboard' }} ... />\n Then run: npm install @react-native-clipboard/clipboard\n\nWithout a clipboard module, the SDK will use React Native's built-in Clipboard API.\n`\n );\n }\n}\n\n/**\n * Tracks which warnings have been printed to avoid duplicate warnings.\n */\nconst printedWarnings = new Set<string>();\n\n/**\n * Prints a warning only once per session.\n * Useful for warnings that shouldn't spam the console on every render.\n *\n * @param key - Unique key for this warning\n * @param message - The warning message to print\n */\nexport function printWarningOnce(key: string, message: string): void {\n if (!__DEV__ || printedWarnings.has(key)) return;\n\n printedWarnings.add(key);\n console.warn(message);\n}\n\n/**\n * Prints an info message only once per session.\n *\n * @param key - Unique key for this message\n * @param message - The info message to print\n */\nexport function printInfoOnce(key: string, message: string): void {\n if (!__DEV__ || printedWarnings.has(key)) return;\n\n printedWarnings.add(key);\n console.info(message);\n}\n\n/**\n * Clears the printed warnings cache.\n * Useful for testing or when you want warnings to be printed again.\n */\nexport function clearWarningsCache(): void {\n printedWarnings.clear();\n}\n"]}
@@ -0,0 +1,284 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.extractFormConfiguration = extractFormConfiguration;
15
+ exports.convertFormStyleToRNStyle = convertFormStyleToRNStyle;
16
+ exports.findComponentByRole = findComponentByRole;
17
+ exports.mergeThemeAndComponentStyles = mergeThemeAndComponentStyles;
18
+ exports.getEmailPlaceholder = getEmailPlaceholder;
19
+ exports.getSubmitButtonLabel = getSubmitButtonLabel;
20
+ exports.hasGridLayout = hasGridLayout;
21
+ exports.hasEmailAndShareInSeparateColumns = hasEmailAndShareInSeparateColumns;
22
+ exports.getRoleOptions = getRoleOptions;
23
+ /**
24
+ * Extracts the form configuration from the widget configuration
25
+ */
26
+ function extractFormConfiguration(widgetConfiguration) {
27
+ var _a, _b, _c;
28
+ const formValue = (_c = (_b = (_a = widgetConfiguration === null || widgetConfiguration === void 0 ? void 0 : widgetConfiguration.configuration) === null || _a === void 0 ? void 0 : _a.props) === null || _b === void 0 ? void 0 : _b['vortex.components.form']) === null || _c === void 0 ? void 0 : _c.value;
29
+ if (!formValue) {
30
+ return null;
31
+ }
32
+ // Normalize: if the value contains a root node, start traversal from it
33
+ if (formValue.root) {
34
+ return [formValue.root];
35
+ }
36
+ // If it's already an array, return as-is
37
+ if (Array.isArray(formValue)) {
38
+ return formValue;
39
+ }
40
+ return null;
41
+ }
42
+ /**
43
+ * Converts form component style object to React Native styles
44
+ */
45
+ function convertFormStyleToRNStyle(style) {
46
+ if (!style)
47
+ return {};
48
+ const rnStyle = {};
49
+ const toCamel = (s) => s.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
50
+ const parseValue = (val) => {
51
+ if (typeof val === 'number')
52
+ return val;
53
+ if (typeof val !== 'string')
54
+ return String(val);
55
+ const pxMatch = val.match(/^(-?\d+(?:\.\d+)?)px$/i);
56
+ if (pxMatch)
57
+ return Number(pxMatch[1]);
58
+ const num = Number(val);
59
+ if (!isNaN(num))
60
+ return num;
61
+ return val;
62
+ };
63
+ Object.keys(style).forEach((key) => {
64
+ const raw = style[key];
65
+ const normalizedKey = toCamel(key);
66
+ if (raw && typeof raw === 'object' && ('value' in raw || 'computedValue' in raw)) {
67
+ const styleObj = raw;
68
+ if (styleObj.computedValue !== undefined) {
69
+ rnStyle[normalizedKey] = parseValue(styleObj.computedValue);
70
+ }
71
+ else if (styleObj.value !== undefined) {
72
+ rnStyle[normalizedKey] = parseValue(styleObj.value);
73
+ }
74
+ }
75
+ else {
76
+ rnStyle[normalizedKey] = parseValue(raw);
77
+ }
78
+ });
79
+ return rnStyle;
80
+ }
81
+ /**
82
+ * Find a specific component by role in the form configuration
83
+ */
84
+ function findComponentByRole(formConfig, role) {
85
+ if (!formConfig)
86
+ return null;
87
+ const findComponent = (components) => {
88
+ var _a;
89
+ for (const component of components) {
90
+ if (((_a = component.vortex) === null || _a === void 0 ? void 0 : _a.role) === role) {
91
+ return component;
92
+ }
93
+ if (component.children) {
94
+ const found = findComponent(component.children);
95
+ if (found)
96
+ return found;
97
+ }
98
+ }
99
+ return null;
100
+ };
101
+ return findComponent(formConfig);
102
+ }
103
+ /**
104
+ * Merges theme styles with component-specific styles from form configuration
105
+ */
106
+ function mergeThemeAndComponentStyles(themeStyles, themeColors, formConfig) {
107
+ var _a;
108
+ // Start with the base theme styles
109
+ const mergedStyles = Object.assign({}, themeStyles);
110
+ // Helper: find first node by predicate
111
+ const findNode = (nodes, predicate) => {
112
+ var _a;
113
+ if (!nodes)
114
+ return null;
115
+ for (const node of nodes) {
116
+ if (predicate(node))
117
+ return node;
118
+ if ((_a = node.children) === null || _a === void 0 ? void 0 : _a.length) {
119
+ const found = findNode(node.children, predicate);
120
+ if (found)
121
+ return found;
122
+ }
123
+ }
124
+ return null;
125
+ };
126
+ // 1) Merge root container style into containerStyles
127
+ const rootNode = formConfig === null || formConfig === void 0 ? void 0 : formConfig[0];
128
+ if (rootNode === null || rootNode === void 0 ? void 0 : rootNode.style) {
129
+ const rootStyle = convertFormStyleToRNStyle(rootNode.style);
130
+ // Avoid applying absolute dimensions that can break responsiveness on mobile
131
+ const _b = rootStyle, { width, height, maxWidth, minWidth, maxHeight, minHeight } = _b, responsiveRoot = __rest(_b, ["width", "height", "maxWidth", "minWidth", "maxHeight", "minHeight"]);
132
+ mergedStyles.containerStyles = Object.assign(Object.assign({}, mergedStyles.containerStyles), responsiveRoot);
133
+ }
134
+ // Find submit button and email input components
135
+ const submitButton = findComponentByRole(formConfig, 'submit');
136
+ const emailInput = findComponentByRole(formConfig, 'email');
137
+ // 2) Merge submit button styles
138
+ if (submitButton === null || submitButton === void 0 ? void 0 : submitButton.style) {
139
+ const submitButtonStyle = convertFormStyleToRNStyle(submitButton.style);
140
+ mergedStyles.primaryButton = Object.assign(Object.assign(Object.assign({}, mergedStyles.primaryButton), (submitButtonStyle['backgroundColor'] && {
141
+ backgroundColor: submitButtonStyle['backgroundColor'],
142
+ })), (submitButtonStyle['borderColor'] && { borderColor: submitButtonStyle['borderColor'] }));
143
+ // Update button text if there's a color specified
144
+ if (submitButtonStyle['color']) {
145
+ mergedStyles.primaryButtonText = Object.assign(Object.assign({}, mergedStyles.primaryButtonText), { color: submitButtonStyle['color'] });
146
+ }
147
+ }
148
+ // 3) Merge email input styles
149
+ if (emailInput === null || emailInput === void 0 ? void 0 : emailInput.style) {
150
+ const emailInputStyle = convertFormStyleToRNStyle(emailInput.style);
151
+ mergedStyles.inputStyles = Object.assign(Object.assign({}, mergedStyles.inputStyles), emailInputStyle);
152
+ }
153
+ // 4) Merge vrtx-share-options block theme into secondary buttons
154
+ const shareOptionsBlock = findNode(formConfig, (n) => n.type === 'block' &&
155
+ (n.subtype === 'vrtx-share-options' || n.tagName === 'vrtx-share-options'));
156
+ const optionEntries = (_a = shareOptionsBlock === null || shareOptionsBlock === void 0 ? void 0 : shareOptionsBlock.theme) === null || _a === void 0 ? void 0 : _a.options;
157
+ if (Array.isArray(optionEntries)) {
158
+ const map = {};
159
+ optionEntries.forEach((it) => {
160
+ if ((it === null || it === void 0 ? void 0 : it.key) && typeof it.value === 'string')
161
+ map[it.key] = it.value;
162
+ });
163
+ const bg = map['--vrtx-icon-button-background'];
164
+ const color = map['--vrtx-icon-button-color'];
165
+ if (bg) {
166
+ mergedStyles.secondaryButton = Object.assign(Object.assign({}, mergedStyles.secondaryButton), { backgroundColor: bg });
167
+ }
168
+ if (color) {
169
+ mergedStyles.secondaryButtonText = Object.assign(Object.assign({}, mergedStyles.secondaryButtonText), { color });
170
+ }
171
+ }
172
+ return mergedStyles;
173
+ }
174
+ /**
175
+ * Get email input placeholder from form configuration
176
+ */
177
+ function getEmailPlaceholder(formConfig) {
178
+ var _a;
179
+ const emailInput = findComponentByRole(formConfig, 'email');
180
+ // Prefer attributes.placeholder as per current JSON shape
181
+ const attrPlaceholder = (_a = emailInput === null || emailInput === void 0 ? void 0 : emailInput.attributes) === null || _a === void 0 ? void 0 : _a.placeholder;
182
+ return attrPlaceholder || (emailInput === null || emailInput === void 0 ? void 0 : emailInput.placeholder) || 'Enter email';
183
+ }
184
+ /**
185
+ * Get submit button label from form configuration
186
+ */
187
+ function getSubmitButtonLabel(formConfig) {
188
+ const submitButton = findComponentByRole(formConfig, 'submit');
189
+ // Prefer textContent per current JSON; fallback to label
190
+ return (submitButton === null || submitButton === void 0 ? void 0 : submitButton.textContent) || (submitButton === null || submitButton === void 0 ? void 0 : submitButton.label) || 'Invite';
191
+ }
192
+ /**
193
+ * Determines if the form layout uses a grid structure
194
+ */
195
+ function hasGridLayout(formConfig) {
196
+ if (!formConfig)
197
+ return false;
198
+ const findGrid = (components) => {
199
+ for (const component of components) {
200
+ if (component.type === 'grid') {
201
+ return true;
202
+ }
203
+ if (component.children) {
204
+ const found = findGrid(component.children);
205
+ if (found)
206
+ return true;
207
+ }
208
+ }
209
+ return false;
210
+ };
211
+ return findGrid(formConfig);
212
+ }
213
+ /**
214
+ * Determines if email and share components are in separate grid items
215
+ */
216
+ function hasEmailAndShareInSeparateColumns(formConfig) {
217
+ if (!formConfig)
218
+ return false;
219
+ // Adjusted to the current JSON tree (row/column/block)
220
+ const checkTree = (components) => {
221
+ for (const node of components) {
222
+ if (node.type === 'row' && Array.isArray(node.children)) {
223
+ // Look for two columns where one column has an email block and another has a submit block
224
+ const columns = node.children.filter((c) => c.type === 'column');
225
+ if (columns.length >= 2) {
226
+ let hasEmailCol = false;
227
+ let hasSubmitCol = false;
228
+ for (const col of columns) {
229
+ const blocks = (col.children || []).filter((c) => c.type === 'block');
230
+ const hasEmail = blocks.some((b) => { var _a; return ((_a = b.vortex) === null || _a === void 0 ? void 0 : _a.role) === 'email' || b.subtype === 'vrtx-email-invitations'; });
231
+ const hasSubmit = blocks.some((b) => { var _a; return ((_a = b.vortex) === null || _a === void 0 ? void 0 : _a.role) === 'submit' || b.subtype === 'vrtx-submit'; });
232
+ if (hasEmail)
233
+ hasEmailCol = true;
234
+ if (hasSubmit)
235
+ hasSubmitCol = true;
236
+ }
237
+ if (hasEmailCol && hasSubmitCol)
238
+ return true;
239
+ }
240
+ }
241
+ if (node.children && checkTree(node.children))
242
+ return true;
243
+ }
244
+ return false;
245
+ };
246
+ return checkTree(formConfig);
247
+ }
248
+ /**
249
+ * Extract role options from form configuration (e.g., vrtx-select with attributes.name === 'role')
250
+ */
251
+ function getRoleOptions(formConfig) {
252
+ if (!formConfig)
253
+ return [];
254
+ const findRoleSelect = (components) => {
255
+ var _a, _b, _c, _d;
256
+ for (const component of components) {
257
+ const isSelect = component.subtype === 'vrtx-select' || component.tagName === 'vrtx-select';
258
+ const isRole = ((_a = component === null || component === void 0 ? void 0 : component.attributes) === null || _a === void 0 ? void 0 : _a.name) === 'role' || ((_b = component.vortex) === null || _b === void 0 ? void 0 : _b.role) === 'role';
259
+ if (isSelect && isRole) {
260
+ return ((_c = component === null || component === void 0 ? void 0 : component.settings) === null || _c === void 0 ? void 0 : _c.options) || null;
261
+ }
262
+ if ((_d = component.children) === null || _d === void 0 ? void 0 : _d.length) {
263
+ const found = findRoleSelect(component.children);
264
+ if (found)
265
+ return found;
266
+ }
267
+ }
268
+ return null;
269
+ };
270
+ const options = findRoleSelect(formConfig);
271
+ if (Array.isArray(options)) {
272
+ // Normalize to label/value objects
273
+ return options.map((opt) => {
274
+ var _a;
275
+ return ({
276
+ id: opt.id,
277
+ label: (_a = opt.label) !== null && _a !== void 0 ? _a : String(opt.value),
278
+ value: String(opt.value),
279
+ });
280
+ });
281
+ }
282
+ return [];
283
+ }
284
+ //# sourceMappingURL=formUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formUtils.js","sourceRoot":"","sources":["../../src/utils/formUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { WidgetConfiguration } from '@teamvortexsoftware/vortex-types';\nimport { ThemeColors } from './themeUtils';\n\nexport interface FormComponentStyle {\n [key: string]: {\n label?: string;\n value?: string | number;\n computedValue?: string;\n unit?: string;\n };\n}\n\nexport interface FormComponentSettings {\n action?: {\n type: string;\n value: string;\n target?: string;\n };\n size?: number;\n}\n\nexport interface FormComponent {\n id: string;\n type: string;\n subtype?: string;\n label?: string;\n hint?: string;\n name?: string;\n required?: boolean;\n placeholder?: string;\n style?: FormComponentStyle;\n settings?: FormComponentSettings;\n vortex?: {\n role?: string;\n canRemove?: boolean;\n };\n children?: FormComponent[];\n multiValue?: boolean;\n validation?: Array<{\n type: string;\n value: string;\n operator: string;\n canRemove: boolean;\n errorMessage: string;\n }>;\n tagName?: string;\n textContent?: string;\n attributes?: {\n [key: string]: string;\n };\n}\n\nexport interface FormConfiguration {\n value: FormComponent[];\n valueType: string;\n}\n\n/**\n * Extracts the form configuration from the widget configuration\n */\nexport function extractFormConfiguration(\n widgetConfiguration?: WidgetConfiguration\n): FormComponent[] | null {\n const formValue = widgetConfiguration?.configuration?.props?.['vortex.components.form']\n ?.value as any;\n if (!formValue) {\n return null;\n }\n // Normalize: if the value contains a root node, start traversal from it\n if (formValue.root) {\n return [formValue.root] as unknown as FormComponent[];\n }\n // If it's already an array, return as-is\n if (Array.isArray(formValue)) {\n return formValue as FormComponent[];\n }\n return null;\n}\n\n/**\n * Converts form component style object to React Native styles\n */\nexport function convertFormStyleToRNStyle(\n style?: FormComponentStyle | Record<string, any>\n): Record<string, string | number> {\n if (!style) return {};\n\n const rnStyle: Record<string, string | number> = {};\n\n const toCamel = (s: string) => s.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\n const parseValue = (val: any): string | number => {\n if (typeof val === 'number') return val;\n if (typeof val !== 'string') return String(val);\n const pxMatch = val.match(/^(-?\\d+(?:\\.\\d+)?)px$/i);\n if (pxMatch) return Number(pxMatch[1]);\n const num = Number(val);\n if (!isNaN(num)) return num;\n return val;\n };\n\n Object.keys(style).forEach((key) => {\n const raw = (style as any)[key];\n const normalizedKey = toCamel(key);\n\n if (raw && typeof raw === 'object' && ('value' in raw || 'computedValue' in raw)) {\n const styleObj = raw as { value?: any; computedValue?: any };\n if (styleObj.computedValue !== undefined) {\n rnStyle[normalizedKey] = parseValue(styleObj.computedValue);\n } else if (styleObj.value !== undefined) {\n rnStyle[normalizedKey] = parseValue(styleObj.value);\n }\n } else {\n rnStyle[normalizedKey] = parseValue(raw);\n }\n });\n\n return rnStyle;\n}\n\n/**\n * Find a specific component by role in the form configuration\n */\nexport function findComponentByRole(\n formConfig: FormComponent[] | null,\n role: string\n): FormComponent | null {\n if (!formConfig) return null;\n\n const findComponent = (components: FormComponent[]): FormComponent | null => {\n for (const component of components) {\n if (component.vortex?.role === role) {\n return component;\n }\n\n if (component.children) {\n const found = findComponent(component.children);\n if (found) return found;\n }\n }\n\n return null;\n };\n\n return findComponent(formConfig);\n}\n\n/**\n * Merges theme styles with component-specific styles from form configuration\n */\nexport function mergeThemeAndComponentStyles(\n themeStyles: Record<string, Record<string, string | number>>,\n themeColors: ThemeColors,\n formConfig: FormComponent[] | null\n): Record<string, Record<string, string | number>> {\n // Start with the base theme styles\n const mergedStyles = { ...themeStyles };\n\n // Helper: find first node by predicate\n const findNode = (\n nodes: FormComponent[] | null | undefined,\n predicate: (n: any) => boolean\n ): any => {\n if (!nodes) return null;\n for (const node of nodes) {\n if (predicate(node)) return node;\n if (node.children?.length) {\n const found = findNode(node.children, predicate);\n if (found) return found;\n }\n }\n return null;\n };\n\n // 1) Merge root container style into containerStyles\n const rootNode = formConfig?.[0];\n if (rootNode?.style) {\n const rootStyle = convertFormStyleToRNStyle(rootNode.style as any);\n // Avoid applying absolute dimensions that can break responsiveness on mobile\n const { width, height, maxWidth, minWidth, maxHeight, minHeight, ...responsiveRoot } =\n rootStyle as any;\n mergedStyles.containerStyles = {\n ...mergedStyles.containerStyles,\n ...responsiveRoot,\n };\n }\n\n // Find submit button and email input components\n const submitButton = findComponentByRole(formConfig, 'submit');\n const emailInput = findComponentByRole(formConfig, 'email');\n\n // 2) Merge submit button styles\n if (submitButton?.style) {\n const submitButtonStyle = convertFormStyleToRNStyle(submitButton.style);\n mergedStyles.primaryButton = {\n ...mergedStyles.primaryButton,\n ...(submitButtonStyle['backgroundColor'] && {\n backgroundColor: submitButtonStyle['backgroundColor'],\n }),\n ...(submitButtonStyle['borderColor'] && { borderColor: submitButtonStyle['borderColor'] }),\n };\n\n // Update button text if there's a color specified\n if (submitButtonStyle['color']) {\n mergedStyles.primaryButtonText = {\n ...mergedStyles.primaryButtonText,\n color: submitButtonStyle['color'],\n };\n }\n }\n\n // 3) Merge email input styles\n if (emailInput?.style) {\n const emailInputStyle = convertFormStyleToRNStyle(emailInput.style);\n mergedStyles.inputStyles = {\n ...mergedStyles.inputStyles,\n ...emailInputStyle,\n };\n }\n\n // 4) Merge vrtx-share-options block theme into secondary buttons\n const shareOptionsBlock = findNode(\n formConfig,\n (n) =>\n n.type === 'block' &&\n (n.subtype === 'vrtx-share-options' || n.tagName === 'vrtx-share-options')\n ) as any;\n const optionEntries: Array<{ key?: string; value?: string }> | undefined =\n shareOptionsBlock?.theme?.options;\n if (Array.isArray(optionEntries)) {\n const map: Record<string, string> = {};\n optionEntries.forEach((it) => {\n if (it?.key && typeof it.value === 'string') map[it.key] = it.value;\n });\n const bg = map['--vrtx-icon-button-background'];\n const color = map['--vrtx-icon-button-color'];\n if (bg) {\n mergedStyles.secondaryButton = {\n ...mergedStyles.secondaryButton,\n backgroundColor: bg,\n };\n }\n if (color) {\n mergedStyles.secondaryButtonText = {\n ...mergedStyles.secondaryButtonText,\n color,\n };\n }\n }\n\n return mergedStyles;\n}\n\n/**\n * Get email input placeholder from form configuration\n */\nexport function getEmailPlaceholder(formConfig: FormComponent[] | null): string {\n const emailInput = findComponentByRole(formConfig, 'email');\n // Prefer attributes.placeholder as per current JSON shape\n const attrPlaceholder = (emailInput as any)?.attributes?.placeholder;\n return attrPlaceholder || emailInput?.placeholder || 'Enter email';\n}\n\n/**\n * Get submit button label from form configuration\n */\nexport function getSubmitButtonLabel(formConfig: FormComponent[] | null): string {\n const submitButton = findComponentByRole(formConfig, 'submit') as any;\n // Prefer textContent per current JSON; fallback to label\n return submitButton?.textContent || submitButton?.label || 'Invite';\n}\n\n/**\n * Determines if the form layout uses a grid structure\n */\nexport function hasGridLayout(formConfig: FormComponent[] | null): boolean {\n if (!formConfig) return false;\n\n const findGrid = (components: FormComponent[]): boolean => {\n for (const component of components) {\n if (component.type === 'grid') {\n return true;\n }\n\n if (component.children) {\n const found = findGrid(component.children);\n if (found) return true;\n }\n }\n\n return false;\n };\n\n return findGrid(formConfig);\n}\n\n/**\n * Determines if email and share components are in separate grid items\n */\nexport function hasEmailAndShareInSeparateColumns(formConfig: FormComponent[] | null): boolean {\n if (!formConfig) return false;\n\n // Adjusted to the current JSON tree (row/column/block)\n const checkTree = (components: FormComponent[]): boolean => {\n for (const node of components) {\n if (node.type === 'row' && Array.isArray(node.children)) {\n // Look for two columns where one column has an email block and another has a submit block\n const columns = node.children.filter((c) => c.type === 'column');\n if (columns.length >= 2) {\n let hasEmailCol = false;\n let hasSubmitCol = false;\n\n for (const col of columns) {\n const blocks = (col.children || []).filter((c) => c.type === 'block');\n const hasEmail = blocks.some(\n (b) => b.vortex?.role === 'email' || b.subtype === 'vrtx-email-invitations'\n );\n const hasSubmit = blocks.some(\n (b) => b.vortex?.role === 'submit' || b.subtype === 'vrtx-submit'\n );\n if (hasEmail) hasEmailCol = true;\n if (hasSubmit) hasSubmitCol = true;\n }\n\n if (hasEmailCol && hasSubmitCol) return true;\n }\n }\n\n if (node.children && checkTree(node.children)) return true;\n }\n return false;\n };\n\n return checkTree(formConfig);\n}\n\n/**\n * Extract role options from form configuration (e.g., vrtx-select with attributes.name === 'role')\n */\nexport function getRoleOptions(\n formConfig: FormComponent[] | null\n): Array<{ id?: string; label: string; value: string }> {\n if (!formConfig) return [];\n\n const findRoleSelect = (components: FormComponent[]): any | null => {\n for (const component of components) {\n const isSelect = component.subtype === 'vrtx-select' || component.tagName === 'vrtx-select';\n const isRole =\n (component as any)?.attributes?.name === 'role' || component.vortex?.role === 'role';\n if (isSelect && isRole) {\n return (component as any)?.settings?.options || null;\n }\n if (component.children?.length) {\n const found = findRoleSelect(component.children);\n if (found) return found;\n }\n }\n return null;\n };\n\n const options = findRoleSelect(formConfig);\n if (Array.isArray(options)) {\n // Normalize to label/value objects\n return options.map((opt: any) => ({\n id: opt.id,\n label: opt.label ?? String(opt.value),\n value: String(opt.value),\n }));\n }\n return [];\n}\n"]}