@teamvortexsoftware/vortex-react-native 0.0.13 → 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 (228) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +1227 -11
  3. package/dist/InviteFormCore-D4HkMMo0.d.mts +721 -0
  4. package/dist/InviteFormCore-D9oUCbu7.d.ts +721 -0
  5. package/dist/VortexClient.js +192 -0
  6. package/dist/VortexClient.js.map +1 -0
  7. package/dist/VortexDeferredLinks.js +127 -0
  8. package/dist/VortexDeferredLinks.js.map +1 -0
  9. package/dist/clientInfo.js +45 -0
  10. package/dist/clientInfo.js.map +1 -0
  11. package/dist/components/ContactsPickerModal.js +182 -0
  12. package/dist/components/ContactsPickerModal.js.map +1 -0
  13. package/dist/components/InviteFormCore.js +2141 -0
  14. package/dist/components/InviteFormCore.js.map +1 -0
  15. package/dist/components/InviteFormMobile.js +463 -0
  16. package/dist/components/InviteFormMobile.js.map +1 -0
  17. package/dist/components/InviteFormWeb.js +295 -0
  18. package/dist/components/InviteFormWeb.js.map +1 -0
  19. package/dist/components/PlacedItemToolbar.js +147 -0
  20. package/dist/components/PlacedItemToolbar.js.map +1 -0
  21. package/dist/components/ShareButtons.js +1 -0
  22. package/dist/components/ShareButtons.js.map +1 -0
  23. package/dist/components/VrtxContactsImport.js +234 -0
  24. package/dist/components/VrtxContactsImport.js.map +1 -0
  25. package/dist/components/VrtxEmailInvitations.js +341 -0
  26. package/dist/components/VrtxEmailInvitations.js.map +1 -0
  27. package/dist/components/VrtxFindFriends.js +400 -0
  28. package/dist/components/VrtxFindFriends.js.map +1 -0
  29. package/dist/components/VrtxHeading.js +58 -0
  30. package/dist/components/VrtxHeading.js.map +1 -0
  31. package/dist/components/VrtxIncomingInvitations.js +657 -0
  32. package/dist/components/VrtxIncomingInvitations.js.map +1 -0
  33. package/dist/components/VrtxInvitationSuggestions.js +506 -0
  34. package/dist/components/VrtxInvitationSuggestions.js.map +1 -0
  35. package/dist/components/VrtxInviteContacts.js +512 -0
  36. package/dist/components/VrtxInviteContacts.js.map +1 -0
  37. package/dist/components/VrtxOutgoingInvitations.js +572 -0
  38. package/dist/components/VrtxOutgoingInvitations.js.map +1 -0
  39. package/dist/components/VrtxSearchBox.js +487 -0
  40. package/dist/components/VrtxSearchBox.js.map +1 -0
  41. package/dist/components/VrtxSelect.js +27 -0
  42. package/dist/components/VrtxSelect.js.map +1 -0
  43. package/dist/components/VrtxShareOptions.js +435 -0
  44. package/dist/components/VrtxShareOptions.js.map +1 -0
  45. package/dist/components/VrtxSubmit.js +132 -0
  46. package/dist/components/VrtxSubmit.js.map +1 -0
  47. package/dist/components/VrtxText.js +146 -0
  48. package/dist/components/VrtxText.js.map +1 -0
  49. package/dist/constants/mockData.d.mts +7 -0
  50. package/dist/constants/mockData.d.ts +7 -0
  51. package/dist/constants/mockData.js +48 -0
  52. package/dist/constants/mockData.js.map +1 -0
  53. package/dist/constants/mockData.mjs +22 -0
  54. package/dist/constants/mockData.mjs.map +1 -0
  55. package/dist/context/VortexModulesContext.js +135 -0
  56. package/dist/context/VortexModulesContext.js.map +1 -0
  57. package/dist/hooks/useInvitationFormLogic.d.mts +2 -0
  58. package/dist/hooks/useInvitationFormLogic.d.ts +2 -0
  59. package/dist/hooks/useInvitationFormLogic.js +300 -0
  60. package/dist/hooks/useInvitationFormLogic.js.map +1 -0
  61. package/dist/hooks/useInvitationFormLogic.mjs +276 -0
  62. package/dist/hooks/useInvitationFormLogic.mjs.map +1 -0
  63. package/dist/hooks/usePrefetchWidgetConfiguration.js +117 -0
  64. package/dist/hooks/usePrefetchWidgetConfiguration.js.map +1 -0
  65. package/dist/hooks/useThemeStyles.js +2 -0
  66. package/dist/hooks/useThemeStyles.js.map +1 -0
  67. package/dist/hooks/useVortexInvite.js +467 -56
  68. package/dist/hooks/useVortexInvite.js.map +1 -0
  69. package/dist/index-web.d.mts +93 -0
  70. package/dist/index-web.d.ts +93 -0
  71. package/dist/index-web.js +7397 -0
  72. package/dist/index-web.js.map +1 -0
  73. package/dist/index-web.mjs +7445 -0
  74. package/dist/index-web.mjs.map +1 -0
  75. package/dist/index.d.mts +656 -0
  76. package/dist/index.d.ts +656 -0
  77. package/dist/index.js +10205 -4
  78. package/dist/index.js.map +1 -0
  79. package/dist/index.mjs +10244 -0
  80. package/dist/index.mjs.map +1 -0
  81. package/dist/types/VortexClient.d.ts +106 -0
  82. package/dist/types/VortexClient.d.ts.map +1 -0
  83. package/dist/types/VortexDeferredLinks.d.ts +73 -0
  84. package/dist/types/VortexDeferredLinks.d.ts.map +1 -0
  85. package/dist/types/clientInfo.d.ts +5 -0
  86. package/dist/types/clientInfo.d.ts.map +1 -0
  87. package/dist/types/components/ContactsPickerModal.d.ts +18 -0
  88. package/dist/types/components/ContactsPickerModal.d.ts.map +1 -0
  89. package/dist/types/components/InviteFormCore.d.ts +166 -0
  90. package/dist/types/components/InviteFormCore.d.ts.map +1 -0
  91. package/dist/types/components/InviteFormMobile.d.ts +42 -0
  92. package/dist/types/components/InviteFormMobile.d.ts.map +1 -0
  93. package/dist/types/components/InviteFormWeb.d.ts +87 -0
  94. package/dist/types/components/InviteFormWeb.d.ts.map +1 -0
  95. package/dist/types/components/PlacedItemToolbar.d.ts +16 -0
  96. package/dist/types/components/PlacedItemToolbar.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 +1 -0
  134. package/dist/types/hooks/useThemeStyles.d.ts.map +1 -1
  135. package/dist/types/hooks/useVortexInvite.d.ts +48 -6
  136. package/dist/types/hooks/useVortexInvite.d.ts.map +1 -1
  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 +21 -0
  140. package/dist/types/index.d.ts.map +1 -1
  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/{shared/InvitationResult.js → types/platformOperations.js} +1 -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 +11 -3
  172. package/dist/types/utils/formUtils.d.ts.map +1 -1
  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 +3 -1
  184. package/dist/types/utils/themeUtils.d.ts.map +1 -1
  185. package/dist/types/vortexInvite.d.ts +145 -5
  186. package/dist/types/vortexInvite.d.ts.map +1 -1
  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 +161 -51
  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 +117 -32
  214. package/dist/utils/themeUtils.js.map +1 -0
  215. package/dist/vortexInvite.js +78 -167
  216. package/dist/vortexInvite.js.map +1 -0
  217. package/package.json +69 -31
  218. package/dist/components/Clipboard.js +0 -64
  219. package/dist/shared/api.js +0 -90
  220. package/dist/tests/TestVortexInvite.js +0 -134
  221. package/dist/types/components/Clipboard.d.ts +0 -16
  222. package/dist/types/components/Clipboard.d.ts.map +0 -1
  223. package/dist/types/shared/InvitationResult.d.ts +0 -24
  224. package/dist/types/shared/InvitationResult.d.ts.map +0 -1
  225. package/dist/types/shared/api.d.ts +0 -14
  226. package/dist/types/shared/api.d.ts.map +0 -1
  227. package/dist/types/tests/TestVortexInvite.d.ts +0 -4
  228. package/dist/types/tests/TestVortexInvite.d.ts.map +0 -1
@@ -0,0 +1,275 @@
1
+ "use strict";
2
+ /**
3
+ * Module Loaders
4
+ *
5
+ * This module provides explicit module loading for optional dependencies.
6
+ * Instead of auto-detecting which libraries are installed (which causes Metro bundler issues),
7
+ * users explicitly specify which module they want to use via props.
8
+ *
9
+ * This approach:
10
+ * - Avoids Metro static analysis issues with optional dependencies
11
+ * - Gives users explicit control over which libraries to use
12
+ * - Provides clear error messages when a module is specified but not installed
13
+ * - Only requires the module that the user explicitly specifies
14
+ */
15
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
16
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
17
+ return new (P || (P = Promise))(function (resolve, reject) {
18
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
19
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
20
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
21
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
22
+ });
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.parseGradientFirstColor = exports.angleToGradientPoints = exports.parseCSSLinearGradient = void 0;
26
+ exports.loadGradientComponent = loadGradientComponent;
27
+ exports.loadHapticsTrigger = loadHapticsTrigger;
28
+ exports.loadQRCodeComponent = loadQRCodeComponent;
29
+ exports.loadClipboardOperations = loadClipboardOperations;
30
+ const react_native_1 = require("react-native");
31
+ // ============================================================================
32
+ // Module Loading Helpers
33
+ // ============================================================================
34
+ /**
35
+ * Cache for loaded modules to avoid repeated require calls
36
+ */
37
+ const moduleCache = new Map();
38
+ /**
39
+ * List of modules that are native-only and should not be loaded on web.
40
+ * These modules contain native code that doesn't exist in web builds.
41
+ */
42
+ const NATIVE_ONLY_MODULES = [
43
+ 'expo-linear-gradient',
44
+ 'react-native-linear-gradient',
45
+ 'expo-haptics',
46
+ 'react-native-qrcode-svg',
47
+ '@react-native-clipboard/clipboard',
48
+ ];
49
+ /**
50
+ * Loads a module by name, with caching and error handling.
51
+ * Uses explicit require statements to ensure Metro can resolve them.
52
+ *
53
+ * IMPORTANT: Native-only modules are skipped on web platform to prevent
54
+ * build errors. The web platform uses CSS equivalents (gradients) or
55
+ * browser APIs (clipboard) instead.
56
+ *
57
+ * @param moduleName - The name of the module to load
58
+ * @returns The loaded module or null if not available
59
+ */
60
+ function loadModule(moduleName) {
61
+ // Check cache first
62
+ if (moduleCache.has(moduleName)) {
63
+ return moduleCache.get(moduleName);
64
+ }
65
+ // Skip native-only modules on web platform
66
+ // These modules contain native code that doesn't exist in web builds
67
+ if (react_native_1.Platform.OS === 'web' && NATIVE_ONLY_MODULES.includes(moduleName)) {
68
+ moduleCache.set(moduleName, null);
69
+ return null;
70
+ }
71
+ try {
72
+ let mod = null;
73
+ // Use explicit require statements for each supported module
74
+ // This ensures Metro can properly resolve and bundle them when installed
75
+ switch (moduleName) {
76
+ case 'expo-linear-gradient':
77
+ mod = require('expo-linear-gradient');
78
+ break;
79
+ case 'react-native-linear-gradient':
80
+ mod = require('react-native-linear-gradient');
81
+ break;
82
+ case 'expo-haptics':
83
+ mod = require('expo-haptics');
84
+ break;
85
+ case 'react-native-qrcode-svg':
86
+ mod = require('react-native-qrcode-svg');
87
+ break;
88
+ case 'react-qr-code':
89
+ mod = require('react-qr-code');
90
+ break;
91
+ case 'expo-clipboard':
92
+ mod = require('expo-clipboard');
93
+ break;
94
+ case '@react-native-clipboard/clipboard':
95
+ mod = require('@react-native-clipboard/clipboard');
96
+ break;
97
+ default:
98
+ console.warn(`[Vortex] Unknown module: ${moduleName}`);
99
+ return null;
100
+ }
101
+ moduleCache.set(moduleName, mod);
102
+ return mod;
103
+ }
104
+ catch (error) {
105
+ // Module not installed - cache null to avoid repeated attempts
106
+ moduleCache.set(moduleName, null);
107
+ console.error(`[Vortex] Failed to load module "${moduleName}". ` +
108
+ `Make sure it's installed: npm install ${moduleName}`);
109
+ return null;
110
+ }
111
+ }
112
+ // ============================================================================
113
+ // Gradient Loading
114
+ // ============================================================================
115
+ /**
116
+ * Loads the gradient component based on the specified module name.
117
+ *
118
+ * @param moduleName - The gradient module to load ('expo-linear-gradient' or 'react-native-linear-gradient')
119
+ * @returns The gradient component or null if not available
120
+ *
121
+ * @example
122
+ * ```tsx
123
+ * const GradientComponent = loadGradientComponent('expo-linear-gradient');
124
+ * if (GradientComponent) {
125
+ * return <GradientComponent colors={['#ff0000', '#0000ff']} style={styles.button} />;
126
+ * }
127
+ * ```
128
+ */
129
+ function loadGradientComponent(moduleName) {
130
+ if (!moduleName) {
131
+ return null;
132
+ }
133
+ // On web, we use CSS gradients directly, no component needed
134
+ if (react_native_1.Platform.OS === 'web') {
135
+ return null;
136
+ }
137
+ const mod = loadModule(moduleName);
138
+ if (!mod) {
139
+ return null;
140
+ }
141
+ // expo-linear-gradient exports { LinearGradient }
142
+ // react-native-linear-gradient exports default
143
+ if (moduleName === 'expo-linear-gradient') {
144
+ return mod.LinearGradient || null;
145
+ }
146
+ else if (moduleName === 'react-native-linear-gradient') {
147
+ return mod.default || null;
148
+ }
149
+ return null;
150
+ }
151
+ // ============================================================================
152
+ // Haptics Loading
153
+ // ============================================================================
154
+ /**
155
+ * Creates a haptic feedback trigger function based on the specified module.
156
+ *
157
+ * @param moduleName - The haptics module to use ('expo-haptics')
158
+ * @returns A function to trigger haptic feedback, or null if not available
159
+ *
160
+ * @example
161
+ * ```tsx
162
+ * const triggerHaptic = loadHapticsTrigger('expo-haptics');
163
+ * if (triggerHaptic) {
164
+ * await triggerHaptic('light');
165
+ * }
166
+ * ```
167
+ */
168
+ function loadHapticsTrigger(moduleName) {
169
+ if (!moduleName) {
170
+ return null;
171
+ }
172
+ // Haptics don't make sense on web
173
+ if (react_native_1.Platform.OS === 'web') {
174
+ return null;
175
+ }
176
+ const mod = loadModule(moduleName);
177
+ if (!mod) {
178
+ return null;
179
+ }
180
+ if (moduleName === 'expo-haptics') {
181
+ return (style) => __awaiter(this, void 0, void 0, function* () {
182
+ const feedbackStyle = style === 'light'
183
+ ? mod.ImpactFeedbackStyle.Light
184
+ : style === 'medium'
185
+ ? mod.ImpactFeedbackStyle.Medium
186
+ : mod.ImpactFeedbackStyle.Heavy;
187
+ yield mod.impactAsync(feedbackStyle);
188
+ });
189
+ }
190
+ return null;
191
+ }
192
+ // ============================================================================
193
+ // QR Code Loading
194
+ // ============================================================================
195
+ /**
196
+ * Loads the QR code component based on the specified module name.
197
+ *
198
+ * @param moduleName - The QR code module to load ('react-native-qrcode-svg' or 'react-qr-code')
199
+ * @returns The QR code component or null if not available
200
+ *
201
+ * @example
202
+ * ```tsx
203
+ * const QRCodeComponent = loadQRCodeComponent('react-native-qrcode-svg');
204
+ * if (QRCodeComponent) {
205
+ * return <QRCodeComponent value="https://example.com" size={200} />;
206
+ * }
207
+ * ```
208
+ */
209
+ function loadQRCodeComponent(moduleName) {
210
+ if (!moduleName) {
211
+ return null;
212
+ }
213
+ const mod = loadModule(moduleName);
214
+ if (!mod) {
215
+ return null;
216
+ }
217
+ // react-native-qrcode-svg exports default
218
+ // react-qr-code exports default
219
+ return mod.default || null;
220
+ }
221
+ /**
222
+ * Loads clipboard operations based on the specified module.
223
+ *
224
+ * @param moduleName - The clipboard module to use ('expo-clipboard' or '@react-native-clipboard/clipboard')
225
+ * @returns Clipboard operations object or null if not available
226
+ *
227
+ * @example
228
+ * ```tsx
229
+ * const clipboard = loadClipboardOperations('expo-clipboard');
230
+ * if (clipboard) {
231
+ * await clipboard.setString('Hello, world!');
232
+ * }
233
+ * ```
234
+ */
235
+ function loadClipboardOperations(moduleName) {
236
+ if (!moduleName) {
237
+ return null;
238
+ }
239
+ const mod = loadModule(moduleName);
240
+ if (!mod) {
241
+ return null;
242
+ }
243
+ if (moduleName === 'expo-clipboard') {
244
+ return {
245
+ setString: (text) => __awaiter(this, void 0, void 0, function* () {
246
+ yield mod.setStringAsync(text);
247
+ }),
248
+ getString: () => __awaiter(this, void 0, void 0, function* () {
249
+ return yield mod.getStringAsync();
250
+ }),
251
+ };
252
+ }
253
+ else if (moduleName === '@react-native-clipboard/clipboard') {
254
+ const Clipboard = mod.default || mod;
255
+ return {
256
+ setString: (text) => __awaiter(this, void 0, void 0, function* () {
257
+ Clipboard.setString(text);
258
+ }),
259
+ getString: () => __awaiter(this, void 0, void 0, function* () {
260
+ return yield Clipboard.getString();
261
+ }),
262
+ };
263
+ }
264
+ return null;
265
+ }
266
+ // ============================================================================
267
+ // Gradient Parsing Utilities (re-exported from shared gradientUtils.ts)
268
+ // ============================================================================
269
+ // Re-export gradient utilities from the shared module to maintain backward compatibility
270
+ // and provide a single source of truth for gradient parsing logic
271
+ var gradientUtils_1 = require("./gradientUtils");
272
+ Object.defineProperty(exports, "parseCSSLinearGradient", { enumerable: true, get: function () { return gradientUtils_1.parseCSSLinearGradient; } });
273
+ Object.defineProperty(exports, "angleToGradientPoints", { enumerable: true, get: function () { return gradientUtils_1.angleToGradientPoints; } });
274
+ Object.defineProperty(exports, "parseGradientFirstColor", { enumerable: true, get: function () { return gradientUtils_1.parseGradientFirstColor; } });
275
+ //# sourceMappingURL=moduleLoaders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"moduleLoaders.js","sourceRoot":"","sources":["../../src/utils/moduleLoaders.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Module Loaders\n *\n * This module provides explicit module loading for optional dependencies.\n * Instead of auto-detecting which libraries are installed (which causes Metro bundler issues),\n * users explicitly specify which module they want to use via props.\n *\n * This approach:\n * - Avoids Metro static analysis issues with optional dependencies\n * - Gives users explicit control over which libraries to use\n * - Provides clear error messages when a module is specified but not installed\n * - Only requires the module that the user explicitly specifies\n */\n\nimport { Platform } from 'react-native';\nimport type { ComponentType } from 'react';\nimport type {\n GradientModuleName,\n HapticsModuleName,\n QRCodeModuleName,\n ClipboardModuleName,\n} from '../context/VortexModulesContext';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Props for gradient components (compatible with both expo and react-native-linear-gradient)\n */\nexport interface GradientProps {\n colors: string[];\n locations?: number[];\n start?: { x: number; y: number };\n end?: { x: number; y: number };\n style?: any;\n children?: React.ReactNode;\n}\n\n/**\n * Props for QR code components\n */\nexport interface QRCodeProps {\n value: string;\n size?: number;\n color?: string;\n backgroundColor?: string;\n style?: any;\n}\n\n/**\n * Haptic feedback style\n */\nexport type HapticStyle = 'light' | 'medium' | 'heavy';\n\n// ============================================================================\n// Module Loading Helpers\n// ============================================================================\n\n/**\n * Cache for loaded modules to avoid repeated require calls\n */\nconst moduleCache = new Map<string, any>();\n\n/**\n * List of modules that are native-only and should not be loaded on web.\n * These modules contain native code that doesn't exist in web builds.\n */\nconst NATIVE_ONLY_MODULES = [\n 'expo-linear-gradient',\n 'react-native-linear-gradient',\n 'expo-haptics',\n 'react-native-qrcode-svg',\n '@react-native-clipboard/clipboard',\n];\n\n/**\n * Loads a module by name, with caching and error handling.\n * Uses explicit require statements to ensure Metro can resolve them.\n *\n * IMPORTANT: Native-only modules are skipped on web platform to prevent\n * build errors. The web platform uses CSS equivalents (gradients) or\n * browser APIs (clipboard) instead.\n *\n * @param moduleName - The name of the module to load\n * @returns The loaded module or null if not available\n */\nfunction loadModule<T>(moduleName: string): T | null {\n // Check cache first\n if (moduleCache.has(moduleName)) {\n return moduleCache.get(moduleName);\n }\n\n // Skip native-only modules on web platform\n // These modules contain native code that doesn't exist in web builds\n if (Platform.OS === 'web' && NATIVE_ONLY_MODULES.includes(moduleName)) {\n moduleCache.set(moduleName, null);\n return null;\n }\n\n try {\n let mod: any = null;\n\n // Use explicit require statements for each supported module\n // This ensures Metro can properly resolve and bundle them when installed\n switch (moduleName) {\n case 'expo-linear-gradient':\n mod = require('expo-linear-gradient');\n break;\n case 'react-native-linear-gradient':\n mod = require('react-native-linear-gradient');\n break;\n case 'expo-haptics':\n mod = require('expo-haptics');\n break;\n case 'react-native-qrcode-svg':\n mod = require('react-native-qrcode-svg');\n break;\n case 'react-qr-code':\n mod = require('react-qr-code');\n break;\n case 'expo-clipboard':\n mod = require('expo-clipboard');\n break;\n case '@react-native-clipboard/clipboard':\n mod = require('@react-native-clipboard/clipboard');\n break;\n default:\n console.warn(`[Vortex] Unknown module: ${moduleName}`);\n return null;\n }\n\n moduleCache.set(moduleName, mod);\n return mod;\n } catch (error) {\n // Module not installed - cache null to avoid repeated attempts\n moduleCache.set(moduleName, null);\n console.error(\n `[Vortex] Failed to load module \"${moduleName}\". ` +\n `Make sure it's installed: npm install ${moduleName}`\n );\n return null;\n }\n}\n\n// ============================================================================\n// Gradient Loading\n// ============================================================================\n\n/**\n * Loads the gradient component based on the specified module name.\n *\n * @param moduleName - The gradient module to load ('expo-linear-gradient' or 'react-native-linear-gradient')\n * @returns The gradient component or null if not available\n *\n * @example\n * ```tsx\n * const GradientComponent = loadGradientComponent('expo-linear-gradient');\n * if (GradientComponent) {\n * return <GradientComponent colors={['#ff0000', '#0000ff']} style={styles.button} />;\n * }\n * ```\n */\nexport function loadGradientComponent(\n moduleName: GradientModuleName | undefined\n): ComponentType<GradientProps> | null {\n if (!moduleName) {\n return null;\n }\n\n // On web, we use CSS gradients directly, no component needed\n if (Platform.OS === 'web') {\n return null;\n }\n\n const mod = loadModule<any>(moduleName);\n if (!mod) {\n return null;\n }\n\n // expo-linear-gradient exports { LinearGradient }\n // react-native-linear-gradient exports default\n if (moduleName === 'expo-linear-gradient') {\n return mod.LinearGradient || null;\n } else if (moduleName === 'react-native-linear-gradient') {\n return mod.default || null;\n }\n\n return null;\n}\n\n// ============================================================================\n// Haptics Loading\n// ============================================================================\n\n/**\n * Creates a haptic feedback trigger function based on the specified module.\n *\n * @param moduleName - The haptics module to use ('expo-haptics')\n * @returns A function to trigger haptic feedback, or null if not available\n *\n * @example\n * ```tsx\n * const triggerHaptic = loadHapticsTrigger('expo-haptics');\n * if (triggerHaptic) {\n * await triggerHaptic('light');\n * }\n * ```\n */\nexport function loadHapticsTrigger(\n moduleName: HapticsModuleName | undefined\n): ((style: HapticStyle) => Promise<void>) | null {\n if (!moduleName) {\n return null;\n }\n\n // Haptics don't make sense on web\n if (Platform.OS === 'web') {\n return null;\n }\n\n const mod = loadModule<any>(moduleName);\n if (!mod) {\n return null;\n }\n\n if (moduleName === 'expo-haptics') {\n return async (style: HapticStyle) => {\n const feedbackStyle =\n style === 'light'\n ? mod.ImpactFeedbackStyle.Light\n : style === 'medium'\n ? mod.ImpactFeedbackStyle.Medium\n : mod.ImpactFeedbackStyle.Heavy;\n\n await mod.impactAsync(feedbackStyle);\n };\n }\n\n return null;\n}\n\n// ============================================================================\n// QR Code Loading\n// ============================================================================\n\n/**\n * Loads the QR code component based on the specified module name.\n *\n * @param moduleName - The QR code module to load ('react-native-qrcode-svg' or 'react-qr-code')\n * @returns The QR code component or null if not available\n *\n * @example\n * ```tsx\n * const QRCodeComponent = loadQRCodeComponent('react-native-qrcode-svg');\n * if (QRCodeComponent) {\n * return <QRCodeComponent value=\"https://example.com\" size={200} />;\n * }\n * ```\n */\nexport function loadQRCodeComponent(\n moduleName: QRCodeModuleName | undefined\n): ComponentType<QRCodeProps> | null {\n if (!moduleName) {\n return null;\n }\n\n const mod = loadModule<any>(moduleName);\n if (!mod) {\n return null;\n }\n\n // react-native-qrcode-svg exports default\n // react-qr-code exports default\n return mod.default || null;\n}\n\n// ============================================================================\n// Clipboard Loading\n// ============================================================================\n\n/**\n * Clipboard operations interface\n */\nexport interface ClipboardOperations {\n setString: (text: string) => Promise<void>;\n getString: () => Promise<string>;\n}\n\n/**\n * Loads clipboard operations based on the specified module.\n *\n * @param moduleName - The clipboard module to use ('expo-clipboard' or '@react-native-clipboard/clipboard')\n * @returns Clipboard operations object or null if not available\n *\n * @example\n * ```tsx\n * const clipboard = loadClipboardOperations('expo-clipboard');\n * if (clipboard) {\n * await clipboard.setString('Hello, world!');\n * }\n * ```\n */\nexport function loadClipboardOperations(\n moduleName: ClipboardModuleName | undefined\n): ClipboardOperations | null {\n if (!moduleName) {\n return null;\n }\n\n const mod = loadModule<any>(moduleName);\n if (!mod) {\n return null;\n }\n\n if (moduleName === 'expo-clipboard') {\n return {\n setString: async (text: string) => {\n await mod.setStringAsync(text);\n },\n getString: async () => {\n return await mod.getStringAsync();\n },\n };\n } else if (moduleName === '@react-native-clipboard/clipboard') {\n const Clipboard = mod.default || mod;\n return {\n setString: async (text: string) => {\n Clipboard.setString(text);\n },\n getString: async () => {\n return await Clipboard.getString();\n },\n };\n }\n\n return null;\n}\n\n// ============================================================================\n// Gradient Parsing Utilities (re-exported from shared gradientUtils.ts)\n// ============================================================================\n\n// Re-export gradient utilities from the shared module to maintain backward compatibility\n// and provide a single source of truth for gradient parsing logic\nexport {\n parseCSSLinearGradient,\n angleToGradientPoints,\n parseGradientFirstColor,\n type ParsedGradient,\n type GradientPoints,\n} from './gradientUtils';\n"]}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ /**
3
+ * Web-Safe Module Loaders
4
+ *
5
+ * This module provides stub implementations for web environments.
6
+ * On web, we use CSS gradients directly, browser clipboard APIs, etc.
7
+ * All loader functions return null, and components use CSS/browser fallbacks.
8
+ *
9
+ * This file is used by InviteFormWeb (web entry point) to avoid
10
+ * importing native modules that would cause Next.js/webpack build errors.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.parseGradientFirstColor = exports.angleToGradientPoints = exports.parseCSSLinearGradient = void 0;
14
+ exports.loadGradientComponent = loadGradientComponent;
15
+ exports.loadHapticsTrigger = loadHapticsTrigger;
16
+ exports.loadQRCodeComponent = loadQRCodeComponent;
17
+ exports.loadClipboardOperations = loadClipboardOperations;
18
+ // ============================================================================
19
+ // Web-Safe Loader Stubs
20
+ // ============================================================================
21
+ /**
22
+ * Web-safe gradient loader - always returns null.
23
+ * On web, CSS gradients are used directly via the `background` style property.
24
+ */
25
+ function loadGradientComponent(_moduleName) {
26
+ // Web uses CSS gradients directly, no component needed
27
+ return null;
28
+ }
29
+ /**
30
+ * Web-safe haptics loader - always returns null.
31
+ * Haptic feedback doesn't make sense on web.
32
+ */
33
+ function loadHapticsTrigger(_moduleName) {
34
+ // No haptics on web
35
+ return null;
36
+ }
37
+ /**
38
+ * Web-safe QR code loader - returns null for native modules.
39
+ * For web, react-qr-code can be loaded if needed.
40
+ */
41
+ function loadQRCodeComponent(moduleName) {
42
+ // Only react-qr-code works on web
43
+ if (moduleName === 'react-qr-code') {
44
+ try {
45
+ const mod = require('react-qr-code');
46
+ return mod.default || null;
47
+ }
48
+ catch (_a) {
49
+ return null;
50
+ }
51
+ }
52
+ // react-native-qrcode-svg is native-only
53
+ return null;
54
+ }
55
+ /**
56
+ * Web-safe clipboard loader - always returns null.
57
+ * Web uses navigator.clipboard API directly.
58
+ */
59
+ function loadClipboardOperations(_moduleName) {
60
+ // Web uses navigator.clipboard directly
61
+ return null;
62
+ }
63
+ // ============================================================================
64
+ // Gradient Parsing Utilities (re-exported from shared gradientUtils.ts)
65
+ // ============================================================================
66
+ // Re-export gradient utilities from the shared module
67
+ // These are pure JS functions with no native dependencies, safe for web
68
+ var gradientUtils_1 = require("./gradientUtils");
69
+ Object.defineProperty(exports, "parseCSSLinearGradient", { enumerable: true, get: function () { return gradientUtils_1.parseCSSLinearGradient; } });
70
+ Object.defineProperty(exports, "angleToGradientPoints", { enumerable: true, get: function () { return gradientUtils_1.angleToGradientPoints; } });
71
+ Object.defineProperty(exports, "parseGradientFirstColor", { enumerable: true, get: function () { return gradientUtils_1.parseGradientFirstColor; } });
72
+ //# sourceMappingURL=moduleLoaders.web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"moduleLoaders.web.js","sourceRoot":"","sources":["../../src/utils/moduleLoaders.web.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AA6DH,sDAKC;AAMD,gDAKC;AAMD,kDAcC;AAMD,0DAKC;AAvDD,+EAA+E;AAC/E,wBAAwB;AACxB,+EAA+E;AAE/E;;;GAGG;AACH,SAAgB,qBAAqB,CACnC,WAA2C;IAE3C,uDAAuD;IACvD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAgB,kBAAkB,CAChC,WAA0C;IAE1C,oBAAoB;IACpB,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAgB,mBAAmB,CACjC,UAAwC;IAExC,kCAAkC;IAClC,IAAI,UAAU,KAAK,eAAe,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;YACrC,OAAO,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC;QAC7B,CAAC;QAAC,WAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,yCAAyC;IACzC,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAgB,uBAAuB,CACrC,WAA4C;IAE5C,wCAAwC;IACxC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+EAA+E;AAC/E,wEAAwE;AACxE,+EAA+E;AAE/E,sDAAsD;AACtD,wEAAwE;AACxE,iDAIyB;AAHvB,uHAAA,sBAAsB,OAAA;AACtB,sHAAA,qBAAqB,OAAA;AACrB,wHAAA,uBAAuB,OAAA","sourcesContent":["/**\n * Web-Safe Module Loaders\n *\n * This module provides stub implementations for web environments.\n * On web, we use CSS gradients directly, browser clipboard APIs, etc.\n * All loader functions return null, and components use CSS/browser fallbacks.\n *\n * This file is used by InviteFormWeb (web entry point) to avoid\n * importing native modules that would cause Next.js/webpack build errors.\n */\n\nimport type { ComponentType } from 'react';\nimport type {\n GradientModuleName,\n HapticsModuleName,\n QRCodeModuleName,\n ClipboardModuleName,\n} from '../context/VortexModulesContext';\n\n// ============================================================================\n// Types (re-exported for consistency with moduleLoaders.ts)\n// ============================================================================\n\n/**\n * Props for gradient components\n */\nexport interface GradientProps {\n colors: string[];\n locations?: number[];\n start?: { x: number; y: number };\n end?: { x: number; y: number };\n style?: any;\n children?: React.ReactNode;\n}\n\n/**\n * Props for QR code components\n */\nexport interface QRCodeProps {\n value: string;\n size?: number;\n color?: string;\n backgroundColor?: string;\n style?: any;\n}\n\n/**\n * Haptic feedback style\n */\nexport type HapticStyle = 'light' | 'medium' | 'heavy';\n\n/**\n * Clipboard operations interface\n */\nexport interface ClipboardOperations {\n setString: (text: string) => Promise<void>;\n getString: () => Promise<string>;\n}\n\n// Re-export gradient types from shared module\nexport type { ParsedGradient, GradientPoints } from './gradientUtils';\n\n// ============================================================================\n// Web-Safe Loader Stubs\n// ============================================================================\n\n/**\n * Web-safe gradient loader - always returns null.\n * On web, CSS gradients are used directly via the `background` style property.\n */\nexport function loadGradientComponent(\n _moduleName: GradientModuleName | undefined\n): ComponentType<GradientProps> | null {\n // Web uses CSS gradients directly, no component needed\n return null;\n}\n\n/**\n * Web-safe haptics loader - always returns null.\n * Haptic feedback doesn't make sense on web.\n */\nexport function loadHapticsTrigger(\n _moduleName: HapticsModuleName | undefined\n): ((style: HapticStyle) => Promise<void>) | null {\n // No haptics on web\n return null;\n}\n\n/**\n * Web-safe QR code loader - returns null for native modules.\n * For web, react-qr-code can be loaded if needed.\n */\nexport function loadQRCodeComponent(\n moduleName: QRCodeModuleName | undefined\n): ComponentType<QRCodeProps> | null {\n // Only react-qr-code works on web\n if (moduleName === 'react-qr-code') {\n try {\n const mod = require('react-qr-code');\n return mod.default || null;\n } catch {\n return null;\n }\n }\n // react-native-qrcode-svg is native-only\n return null;\n}\n\n/**\n * Web-safe clipboard loader - always returns null.\n * Web uses navigator.clipboard API directly.\n */\nexport function loadClipboardOperations(\n _moduleName: ClipboardModuleName | undefined\n): ClipboardOperations | null {\n // Web uses navigator.clipboard directly\n return null;\n}\n\n// ============================================================================\n// Gradient Parsing Utilities (re-exported from shared gradientUtils.ts)\n// ============================================================================\n\n// Re-export gradient utilities from the shared module\n// These are pure JS functions with no native dependencies, safe for web\nexport {\n parseCSSLinearGradient,\n angleToGradientPoints,\n parseGradientFirstColor,\n} from './gradientUtils';\n"]}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.inferNameFromEmail = inferNameFromEmail;
4
+ /**
5
+ * Infers a human-readable name from an email address
6
+ * Handles common separators like dots, dashes, underscores
7
+ *
8
+ * @param email - The email address to extract a name from
9
+ * @returns A capitalized name or the email if extraction fails
10
+ *
11
+ * @example
12
+ * inferNameFromEmail('john@foo.com') // 'John'
13
+ * inferNameFromEmail('john.doe@example.com') // 'John Doe'
14
+ * inferNameFromEmail('mary-jane@test.com') // 'Mary Jane'
15
+ * inferNameFromEmail('bob_smith123@mail.com') // 'Bob Smith'
16
+ */
17
+ function inferNameFromEmail(email) {
18
+ if (!email || typeof email !== 'string') {
19
+ return 'Unknown';
20
+ }
21
+ // Extract the local part (before @)
22
+ const localPart = email.split('@')[0];
23
+ if (!localPart) {
24
+ return 'Unknown';
25
+ }
26
+ // Split by common separators: dot, dash, underscore
27
+ const parts = localPart.split(/[._-]+/);
28
+ // Filter out empty parts and numbers-only parts
29
+ const nameParts = parts
30
+ .filter(part => part.length > 0)
31
+ .filter(part => !/^\d+$/.test(part)); // Remove pure number parts
32
+ if (nameParts.length === 0) {
33
+ // If nothing left after filtering, just capitalize the whole local part
34
+ return capitalizeWord(localPart);
35
+ }
36
+ // Capitalize each part and join with spaces
37
+ return nameParts.map(capitalizeWord).join(' ');
38
+ }
39
+ /**
40
+ * Capitalizes the first letter of a word and lowercases the rest
41
+ *
42
+ * @param word - The word to capitalize
43
+ * @returns The capitalized word
44
+ */
45
+ function capitalizeWord(word) {
46
+ if (!word || word.length === 0) {
47
+ return word;
48
+ }
49
+ return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
50
+ }
51
+ //# sourceMappingURL=nameUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nameUtils.js","sourceRoot":"","sources":["../../src/utils/nameUtils.ts"],"names":[],"mappings":";;AAaA,gDA0BC;AAvCD;;;;;;;;;;;;GAYG;AACH,SAAgB,kBAAkB,CAAC,KAAa;IAC9C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,oCAAoC;IACpC,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,oDAAoD;IACpD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAExC,gDAAgD;IAChD,MAAM,SAAS,GAAG,KAAK;SACpB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SAC/B,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,2BAA2B;IAEnE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,wEAAwE;QACxE,OAAO,cAAc,CAAC,SAAS,CAAC,CAAC;IACnC,CAAC;IAED,4CAA4C;IAC5C,OAAO,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACjD,CAAC;AAED;;;;;GAKG;AACH,SAAS,cAAc,CAAC,IAAY;IAClC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;AACpE,CAAC","sourcesContent":["/**\n * Infers a human-readable name from an email address\n * Handles common separators like dots, dashes, underscores\n * \n * @param email - The email address to extract a name from\n * @returns A capitalized name or the email if extraction fails\n * \n * @example\n * inferNameFromEmail('john@foo.com') // 'John'\n * inferNameFromEmail('john.doe@example.com') // 'John Doe'\n * inferNameFromEmail('mary-jane@test.com') // 'Mary Jane'\n * inferNameFromEmail('bob_smith123@mail.com') // 'Bob Smith'\n */\nexport function inferNameFromEmail(email: string): string {\n if (!email || typeof email !== 'string') {\n return 'Unknown';\n }\n\n // Extract the local part (before @)\n const localPart = email.split('@')[0];\n if (!localPart) {\n return 'Unknown';\n }\n\n // Split by common separators: dot, dash, underscore\n const parts = localPart.split(/[._-]+/);\n\n // Filter out empty parts and numbers-only parts\n const nameParts = parts\n .filter(part => part.length > 0)\n .filter(part => !/^\\d+$/.test(part)); // Remove pure number parts\n\n if (nameParts.length === 0) {\n // If nothing left after filtering, just capitalize the whole local part\n return capitalizeWord(localPart);\n }\n\n // Capitalize each part and join with spaces\n return nameParts.map(capitalizeWord).join(' ');\n}\n\n/**\n * Capitalizes the first letter of a word and lowercases the rest\n * \n * @param word - The word to capitalize\n * @returns The capitalized word\n */\nfunction capitalizeWord(word: string): string {\n if (!word || word.length === 0) {\n return word;\n }\n return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();\n}\n"]}
@@ -2,55 +2,140 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.extractThemeColors = extractThemeColors;
4
4
  exports.extractFeatureFlags = extractFeatureFlags;
5
+ /**
6
+ * Extracts the color from a CSS border shorthand value (e.g., "1px solid #c4c4c4" → "#c4c4c4")
7
+ * Returns undefined if the value doesn't match the expected format
8
+ */
9
+ function extractBorderColor(borderValue) {
10
+ if (!borderValue)
11
+ return undefined;
12
+ const parts = borderValue.trim().split(/\s+/);
13
+ // Expect exactly 3 parts: width, style, color (e.g., "1px solid #c4c4c4")
14
+ if (parts.length === 3) {
15
+ return parts[2];
16
+ }
17
+ return undefined;
18
+ }
5
19
  /**
6
20
  * Extracts theme colors from widget configuration
7
21
  */
8
22
  function extractThemeColors(widgetConfiguration) {
9
23
  var _a, _b;
10
- const options = (_a = widgetConfiguration === null || widgetConfiguration === void 0 ? void 0 : widgetConfiguration.configuration) === null || _a === void 0 ? void 0 : _a.props;
11
- const colors = ((_b = options === null || options === void 0 ? void 0 : options['vortex.theme.colors']) === null || _b === void 0 ? void 0 : _b.value) || [];
24
+ const props = (_a = widgetConfiguration === null || widgetConfiguration === void 0 ? void 0 : widgetConfiguration.configuration) === null || _a === void 0 ? void 0 : _a.props;
25
+ const themeValue = (_b = props === null || props === void 0 ? void 0 : props['vortex.theme']) === null || _b === void 0 ? void 0 : _b.value;
26
+ // Normalize theme entries to an array of { key, value }
27
+ let entries = [];
28
+ if (Array.isArray(themeValue)) {
29
+ entries = themeValue;
30
+ }
31
+ else if (themeValue && Array.isArray(themeValue.options)) {
32
+ entries = themeValue.options;
33
+ }
34
+ else if (themeValue && typeof themeValue === 'object') {
35
+ // Fallback: treat object map as entries if present
36
+ entries = Object.keys(themeValue)
37
+ .filter((k) => k.startsWith('--'))
38
+ .map((k) => ({ key: k, value: String(themeValue[k]) }));
39
+ }
12
40
  const colorMap = {};
13
- colors.forEach((color) => {
14
- if (color.key && color.value) {
15
- colorMap[color.key] = color.value;
41
+ entries.forEach((item) => {
42
+ const k = item === null || item === void 0 ? void 0 : item.key;
43
+ const v = item === null || item === void 0 ? void 0 : item.value;
44
+ if (typeof k === 'string' && typeof v === 'string') {
45
+ colorMap[k] = v;
16
46
  }
17
47
  });
18
48
  return {
19
- containerBackground: colorMap['--container-background'] || '#ffffff',
20
- containerForeground: colorMap['--container-foreground-color'] || '#666666',
21
- containerBorder: colorMap['--container-border-color'] || '#c4c4c4',
22
- primaryButtonBackground: colorMap['--primary-button-background'] || '#197af3',
23
- primaryButtonForeground: colorMap['--primary-button-foreground-color'] || '#ffffff',
24
- primaryButtonBorder: colorMap['--primary-button-border-color'] || '#000000',
25
- secondaryButtonBackground: colorMap['--secondary-button-background'] || '#dfdfdf',
26
- secondaryButtonForeground: colorMap['--secondary-button-foreground-color'] || '#000000',
27
- secondaryButtonBorder: colorMap['--secondary-button-border-color'] || '#c4c4c4',
49
+ containerBackground: colorMap['--vrtx-root-background'] || colorMap['--color-background'] || '#ffffff',
50
+ containerForeground: colorMap['--vrtx-root-color'] || colorMap['--color-foreground'] || '#666666',
51
+ containerBorder: extractBorderColor(colorMap['--vrtx-root-border']) ||
52
+ extractBorderColor(colorMap['--vrtx-input-border']) ||
53
+ colorMap['--color-border'] ||
54
+ '#c4c4c4',
55
+ primaryButtonBackground: colorMap['--vrtx-submit-primary-background'] ||
56
+ colorMap['--vrtx-button-primary-background'] ||
57
+ colorMap['--color-primary-background'] ||
58
+ '#197af3',
59
+ primaryButtonForeground: colorMap['--vrtx-submit-primary-color'] ||
60
+ colorMap['--color-primary-foreground'] ||
61
+ '#ffffff',
62
+ primaryButtonBorder: extractBorderColor(colorMap['--vrtx-submit-primary-border']) ||
63
+ colorMap['--vrtx-submit-primary-border-color'] ||
64
+ colorMap['--vrtx-button-primary-border-color'] ||
65
+ colorMap['--color-primary-border'] ||
66
+ '#000000',
67
+ secondaryButtonBackground: colorMap['--vrtx-submit-secondary-background'] ||
68
+ colorMap['--vrtx-button-secondary-background'] ||
69
+ colorMap['--color-secondary-background'] ||
70
+ '#dfdfdf',
71
+ secondaryButtonForeground: colorMap['--vrtx-submit-secondary-color'] ||
72
+ colorMap['--vrtx-button-secondary-color'] ||
73
+ colorMap['--color-secondary-foreground'] ||
74
+ '#000000',
75
+ secondaryButtonBorder: extractBorderColor(colorMap['--vrtx-submit-secondary-border']) ||
76
+ colorMap['--vrtx-submit-secondary-border-color'] ||
77
+ colorMap['--vrtx-button-secondary-border-color'] ||
78
+ colorMap['--color-secondary-border'] ||
79
+ '#c4c4c4',
28
80
  };
29
81
  }
30
82
  /**
31
83
  * Extracts feature flags from widget configuration
32
84
  */
33
85
  function extractFeatureFlags(widgetConfiguration) {
34
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
35
- const features = Array.isArray((_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']) === null || _c === void 0 ? void 0 : _c.value)
36
- ? (_f = (_e = (_d = widgetConfiguration === null || widgetConfiguration === void 0 ? void 0 : widgetConfiguration.configuration) === null || _d === void 0 ? void 0 : _d.props) === null || _e === void 0 ? void 0 : _e['vortex.components']) === null || _f === void 0 ? void 0 : _f.value
86
+ var _a, _b, _c, _d;
87
+ const props = (_a = widgetConfiguration === null || widgetConfiguration === void 0 ? void 0 : widgetConfiguration.configuration) === null || _a === void 0 ? void 0 : _a.props;
88
+ const features = Array.isArray((_b = props === null || props === void 0 ? void 0 : props['vortex.components']) === null || _b === void 0 ? void 0 : _b.value)
89
+ ? props['vortex.components'].value
37
90
  : [];
38
- const shareOptions = Array.isArray((_j = (_h = (_g = widgetConfiguration === null || widgetConfiguration === void 0 ? void 0 : widgetConfiguration.configuration) === null || _g === void 0 ? void 0 : _g.props) === null || _h === void 0 ? void 0 : _h['vortex.components.share.options']) === null || _j === void 0 ? void 0 : _j.value)
39
- ? (_m = (_l = (_k = widgetConfiguration === null || widgetConfiguration === void 0 ? void 0 : widgetConfiguration.configuration) === null || _k === void 0 ? void 0 : _k.props) === null || _l === void 0 ? void 0 : _l['vortex.components.share.options']) === null || _m === void 0 ? void 0 : _m.value
91
+ const shareOptions = Array.isArray((_c = props === null || props === void 0 ? void 0 : props['vortex.components.share.options']) === null || _c === void 0 ? void 0 : _c.value)
92
+ ? props['vortex.components.share.options'].value
40
93
  : [];
94
+ // Detect presence of blocks in the form tree (row/column/block with subtype)
95
+ const formValue = (_d = props === null || props === void 0 ? void 0 : props['vortex.components.form']) === null || _d === void 0 ? void 0 : _d.value;
96
+ let hasEmailBlock = false;
97
+ let hasShareBlock = false;
98
+ const traverse = (node) => {
99
+ if (!node)
100
+ return;
101
+ if (Array.isArray(node)) {
102
+ node.forEach(traverse);
103
+ return;
104
+ }
105
+ if (node.type === 'block') {
106
+ if (node.subtype === 'vrtx-email-invitations')
107
+ hasEmailBlock = true;
108
+ if (node.subtype === 'vrtx-share-options')
109
+ hasShareBlock = true;
110
+ }
111
+ if (node.children && node.children.length) {
112
+ node.children.forEach(traverse);
113
+ }
114
+ };
115
+ if (formValue === null || formValue === void 0 ? void 0 : formValue.root) {
116
+ traverse(formValue.root);
117
+ }
118
+ else if (Array.isArray(formValue)) {
119
+ traverse(formValue);
120
+ }
41
121
  return {
42
- shareableLinks: features.includes("vortex.components.emailinvitations"),
43
- emailInvitations: features.includes("vortex.components.share"),
44
- shareEnabled: features.includes("vortex.components.share"),
45
- shareOptionsCopyLink: shareOptions.includes("copyLink"),
46
- shareOptionsFacebookMessenger: shareOptions.includes("facebookMessenger"),
47
- shareOptionsInstagramDms: shareOptions.includes("instagramDms"),
48
- shareOptionsLinkedInMessaging: shareOptions.includes("linkedInMessaging"),
49
- shareOptionsNativeShareSheet: shareOptions.includes("nativeShareSheet"),
50
- shareOptionsQrCode: shareOptions.includes("qrCode"), // Only true if specifically included
51
- shareOptionsEmail: shareOptions.includes("email"),
52
- shareOptionsSms: shareOptions.includes("sms"),
53
- shareOptionsTwitterDms: shareOptions.includes("twitterDms"),
54
- shareOptionsWhatsApp: shareOptions.includes("whatsApp"),
122
+ // Email invites if feature enabled or email block present
123
+ emailInvitations: features.includes('vortex.components.emailinvitations') || hasEmailBlock,
124
+ // Share section enabled if share block present or explicit feature (if ever provided)
125
+ shareEnabled: hasShareBlock || features.includes('vortex.components.share'),
126
+ shareableLinks: hasShareBlock || features.includes('vortex.components.share'),
127
+ shareOptionsCopyLink: shareOptions.includes('copyLink'),
128
+ shareOptionsFacebookMessenger: shareOptions.includes('facebookMessenger'),
129
+ shareOptionsInstagramDms: shareOptions.includes('instagramDms'),
130
+ shareOptionsLinkedInMessaging: shareOptions.includes('linkedInMessaging'),
131
+ shareOptionsNativeShareSheet: shareOptions.includes('nativeShareSheet'),
132
+ shareOptionsQrCode: shareOptions.includes('qrCode'),
133
+ shareOptionsSms: shareOptions.includes('sms'),
134
+ shareOptionsTwitterDms: shareOptions.includes('twitterDms'),
135
+ shareOptionsEmail: shareOptions.includes('email'),
136
+ shareOptionsWhatsApp: shareOptions.includes('whatsApp'),
137
+ shareOptionsLine: shareOptions.includes('line'),
138
+ shareOptionsOrder: shareOptions,
55
139
  };
56
140
  }
141
+ //# sourceMappingURL=themeUtils.js.map