@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,120 @@
1
+ "use strict";
2
+ /**
3
+ * Gradient Parsing Utilities
4
+ *
5
+ * Pure JavaScript utilities for parsing CSS gradients.
6
+ * These are shared between native (moduleLoaders.ts) and web (moduleLoaders.web.ts)
7
+ * implementations to avoid code duplication.
8
+ *
9
+ * These utilities have NO native dependencies and are safe to import from anywhere.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.parseCSSLinearGradient = parseCSSLinearGradient;
13
+ exports.angleToGradientPoints = angleToGradientPoints;
14
+ exports.parseGradientFirstColor = parseGradientFirstColor;
15
+ /**
16
+ * Parses a CSS linear-gradient string into a structured format.
17
+ *
18
+ * Supports formats like:
19
+ * - "linear-gradient(90deg, #ff0000 0%, #0000ff 100%)"
20
+ * - "linear-gradient(to right, #ff0000 0%, #0000ff 100%)"
21
+ * - "linear-gradient(135deg, rgba(255,0,0,1) 0%, rgba(0,0,255,1) 100%)"
22
+ *
23
+ * @param css - CSS linear-gradient string
24
+ * @returns Parsed gradient data or null if parsing fails
25
+ */
26
+ function parseCSSLinearGradient(css) {
27
+ var _a, _b;
28
+ if (!css || !css.includes('linear-gradient')) {
29
+ return null;
30
+ }
31
+ // Parse angle
32
+ let angle = 180; // Default: top to bottom
33
+ const angleMatch = css.match(/linear-gradient\(\s*(\d+)deg/i);
34
+ if (angleMatch) {
35
+ angle = parseInt(angleMatch[1], 10);
36
+ }
37
+ else {
38
+ // Handle directional keywords
39
+ const directionMatch = css.match(/linear-gradient\(\s*to\s+(\w+)(?:\s+(\w+))?/i);
40
+ if (directionMatch) {
41
+ const direction = directionMatch[1].toLowerCase();
42
+ const secondDirection = (_a = directionMatch[2]) === null || _a === void 0 ? void 0 : _a.toLowerCase();
43
+ const directionAngles = {
44
+ 'right': 90,
45
+ 'left': 270,
46
+ 'bottom': 180,
47
+ 'top': 0,
48
+ 'right-bottom': 135,
49
+ 'left-bottom': 225,
50
+ 'right-top': 45,
51
+ 'left-top': 315,
52
+ };
53
+ const key = secondDirection ? `${direction}-${secondDirection}` : direction;
54
+ angle = (_b = directionAngles[key]) !== null && _b !== void 0 ? _b : 180;
55
+ }
56
+ }
57
+ // Parse color stops
58
+ const stopsRegex = /(#[0-9a-fA-F]{3,8}|rgba?\([^)]+\)|[a-z]+)\s+(\d+)%/gi;
59
+ const colors = [];
60
+ const locations = [];
61
+ let match;
62
+ while ((match = stopsRegex.exec(css)) !== null) {
63
+ const color = match[1].trim();
64
+ const location = parseInt(match[2], 10) / 100;
65
+ if (color !== 'to' && color !== 'from') {
66
+ colors.push(color);
67
+ locations.push(location);
68
+ }
69
+ }
70
+ if (colors.length < 2) {
71
+ return null;
72
+ }
73
+ return { type: 'linear', angle, colors, locations };
74
+ }
75
+ /**
76
+ * Converts a CSS gradient angle to start/end points for LinearGradient component.
77
+ *
78
+ * CSS gradient angles:
79
+ * - 0deg = bottom to top
80
+ * - 90deg = left to right
81
+ * - 180deg = top to bottom
82
+ * - 270deg = right to left
83
+ *
84
+ * LinearGradient uses normalized coordinates (0-1) for start/end points.
85
+ *
86
+ * @param angle - CSS gradient angle in degrees
87
+ * @returns Start and end points for LinearGradient
88
+ */
89
+ function angleToGradientPoints(angle) {
90
+ const normalizedAngle = ((angle % 360) + 360) % 360;
91
+ const rad = ((90 - normalizedAngle) * Math.PI) / 180;
92
+ const cos = Math.cos(rad);
93
+ const sin = Math.sin(rad);
94
+ return {
95
+ start: { x: 0.5 - cos / 2, y: 0.5 + sin / 2 },
96
+ end: { x: 0.5 + cos / 2, y: 0.5 - sin / 2 },
97
+ };
98
+ }
99
+ /**
100
+ * Extracts the first color from a CSS gradient string.
101
+ * Used as a fallback when gradient libraries are not available.
102
+ *
103
+ * @param gradientString - CSS linear-gradient string
104
+ * @returns First color from the gradient or null
105
+ */
106
+ function parseGradientFirstColor(gradientString) {
107
+ if (!gradientString || !gradientString.includes('linear-gradient')) {
108
+ return null;
109
+ }
110
+ const stopsRegex = /(#[0-9a-fA-F]{3,8}|rgba?\([^)]+\)|[a-z]+)\s+(\d+)%/i;
111
+ const match = stopsRegex.exec(gradientString);
112
+ if (match) {
113
+ const color = match[1].trim();
114
+ if (color !== 'to' && color !== 'from') {
115
+ return color;
116
+ }
117
+ }
118
+ return null;
119
+ }
120
+ //# sourceMappingURL=gradientUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gradientUtils.js","sourceRoot":"","sources":["../../src/utils/gradientUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Gradient Parsing Utilities\n *\n * Pure JavaScript utilities for parsing CSS gradients.\n * These are shared between native (moduleLoaders.ts) and web (moduleLoaders.web.ts)\n * implementations to avoid code duplication.\n *\n * These utilities have NO native dependencies and are safe to import from anywhere.\n */\n\n/**\n * Parsed gradient data structure\n */\nexport interface ParsedGradient {\n type: 'linear';\n angle: number;\n colors: string[];\n locations: number[];\n}\n\n/**\n * Gradient points for LinearGradient component\n */\nexport interface GradientPoints {\n start: { x: number; y: number };\n end: { x: number; y: number };\n}\n\n/**\n * Parses a CSS linear-gradient string into a structured format.\n *\n * Supports formats like:\n * - \"linear-gradient(90deg, #ff0000 0%, #0000ff 100%)\"\n * - \"linear-gradient(to right, #ff0000 0%, #0000ff 100%)\"\n * - \"linear-gradient(135deg, rgba(255,0,0,1) 0%, rgba(0,0,255,1) 100%)\"\n *\n * @param css - CSS linear-gradient string\n * @returns Parsed gradient data or null if parsing fails\n */\nexport function parseCSSLinearGradient(css: string): ParsedGradient | null {\n if (!css || !css.includes('linear-gradient')) {\n return null;\n }\n\n // Parse angle\n let angle = 180; // Default: top to bottom\n\n const angleMatch = css.match(/linear-gradient\\(\\s*(\\d+)deg/i);\n if (angleMatch) {\n angle = parseInt(angleMatch[1], 10);\n } else {\n // Handle directional keywords\n const directionMatch = css.match(/linear-gradient\\(\\s*to\\s+(\\w+)(?:\\s+(\\w+))?/i);\n if (directionMatch) {\n const direction = directionMatch[1].toLowerCase();\n const secondDirection = directionMatch[2]?.toLowerCase();\n\n const directionAngles: Record<string, number> = {\n 'right': 90,\n 'left': 270,\n 'bottom': 180,\n 'top': 0,\n 'right-bottom': 135,\n 'left-bottom': 225,\n 'right-top': 45,\n 'left-top': 315,\n };\n\n const key = secondDirection ? `${direction}-${secondDirection}` : direction;\n angle = directionAngles[key] ?? 180;\n }\n }\n\n // Parse color stops\n const stopsRegex = /(#[0-9a-fA-F]{3,8}|rgba?\\([^)]+\\)|[a-z]+)\\s+(\\d+)%/gi;\n const colors: string[] = [];\n const locations: number[] = [];\n\n let match;\n while ((match = stopsRegex.exec(css)) !== null) {\n const color = match[1].trim();\n const location = parseInt(match[2], 10) / 100;\n\n if (color !== 'to' && color !== 'from') {\n colors.push(color);\n locations.push(location);\n }\n }\n\n if (colors.length < 2) {\n return null;\n }\n\n return { type: 'linear', angle, colors, locations };\n}\n\n/**\n * Converts a CSS gradient angle to start/end points for LinearGradient component.\n *\n * CSS gradient angles:\n * - 0deg = bottom to top\n * - 90deg = left to right\n * - 180deg = top to bottom\n * - 270deg = right to left\n *\n * LinearGradient uses normalized coordinates (0-1) for start/end points.\n *\n * @param angle - CSS gradient angle in degrees\n * @returns Start and end points for LinearGradient\n */\nexport function angleToGradientPoints(angle: number): GradientPoints {\n const normalizedAngle = ((angle % 360) + 360) % 360;\n const rad = ((90 - normalizedAngle) * Math.PI) / 180;\n\n const cos = Math.cos(rad);\n const sin = Math.sin(rad);\n\n return {\n start: { x: 0.5 - cos / 2, y: 0.5 + sin / 2 },\n end: { x: 0.5 + cos / 2, y: 0.5 - sin / 2 },\n };\n}\n\n/**\n * Extracts the first color from a CSS gradient string.\n * Used as a fallback when gradient libraries are not available.\n *\n * @param gradientString - CSS linear-gradient string\n * @returns First color from the gradient or null\n */\nexport function parseGradientFirstColor(gradientString: string): string | null {\n if (!gradientString || !gradientString.includes('linear-gradient')) {\n return null;\n }\n\n const stopsRegex = /(#[0-9a-fA-F]{3,8}|rgba?\\([^)]+\\)|[a-z]+)\\s+(\\d+)%/i;\n const match = stopsRegex.exec(gradientString);\n\n if (match) {\n const color = match[1].trim();\n if (color !== 'to' && color !== 'from') {\n return color;\n }\n }\n\n return null;\n}\n"]}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ /**
3
+ * Simple event emitter for invitation-related events.
4
+ * Used to notify components (like VrtxOutgoingInvitations) when invitations are created
5
+ * so they can refresh their data.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.subscribeToInvitationEvent = subscribeToInvitationEvent;
9
+ exports.emitInvitationEvent = emitInvitationEvent;
10
+ const listeners = new Map();
11
+ /**
12
+ * Subscribe to an invitation event.
13
+ * @param event The event type to listen for
14
+ * @param listener The callback to invoke when the event is emitted
15
+ * @returns A function to unsubscribe
16
+ */
17
+ function subscribeToInvitationEvent(event, listener) {
18
+ if (!listeners.has(event)) {
19
+ listeners.set(event, new Set());
20
+ }
21
+ listeners.get(event).add(listener);
22
+ // Return unsubscribe function
23
+ return () => {
24
+ var _a;
25
+ (_a = listeners.get(event)) === null || _a === void 0 ? void 0 : _a.delete(listener);
26
+ };
27
+ }
28
+ /**
29
+ * Emit an invitation event to notify all subscribers.
30
+ * @param event The event type to emit
31
+ */
32
+ function emitInvitationEvent(event) {
33
+ const eventListeners = listeners.get(event);
34
+ if (eventListeners) {
35
+ eventListeners.forEach((listener) => {
36
+ try {
37
+ listener();
38
+ }
39
+ catch (err) {
40
+ console.warn(`[InvitationEvents] Error in listener for ${event}:`, err);
41
+ }
42
+ });
43
+ }
44
+ }
45
+ //# sourceMappingURL=invitationEvents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invitationEvents.js","sourceRoot":"","sources":["../../src/utils/invitationEvents.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAcH,gEAaC;AAMD,kDAWC;AAtCD,MAAM,SAAS,GAA2D,IAAI,GAAG,EAAE,CAAC;AAEpF;;;;;GAKG;AACH,SAAgB,0BAA0B,CACxC,KAA0B,EAC1B,QAAiC;IAEjC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;IAClC,CAAC;IACD,SAAS,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAEpC,8BAA8B;IAC9B,OAAO,GAAG,EAAE;;QACV,MAAA,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,0CAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,KAA0B;IAC5D,MAAM,cAAc,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC5C,IAAI,cAAc,EAAE,CAAC;QACnB,cAAc,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;YAClC,IAAI,CAAC;gBACH,QAAQ,EAAE,CAAC;YACb,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,IAAI,CAAC,4CAA4C,KAAK,GAAG,EAAE,GAAG,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC","sourcesContent":["/**\n * Simple event emitter for invitation-related events.\n * Used to notify components (like VrtxOutgoingInvitations) when invitations are created\n * so they can refresh their data.\n */\n\ntype InvitationEventType = 'invitationCreated' | 'invitationRevoked' | 'invitationAccepted' | 'invitationDeleted';\n\ntype InvitationEventListener = () => void;\n\nconst listeners: Map<InvitationEventType, Set<InvitationEventListener>> = new Map();\n\n/**\n * Subscribe to an invitation event.\n * @param event The event type to listen for\n * @param listener The callback to invoke when the event is emitted\n * @returns A function to unsubscribe\n */\nexport function subscribeToInvitationEvent(\n event: InvitationEventType,\n listener: InvitationEventListener\n): () => void {\n if (!listeners.has(event)) {\n listeners.set(event, new Set());\n }\n listeners.get(event)!.add(listener);\n\n // Return unsubscribe function\n return () => {\n listeners.get(event)?.delete(listener);\n };\n}\n\n/**\n * Emit an invitation event to notify all subscribers.\n * @param event The event type to emit\n */\nexport function emitInvitationEvent(event: InvitationEventType): void {\n const eventListeners = listeners.get(event);\n if (eventListeners) {\n eventListeners.forEach((listener) => {\n try {\n listener();\n } catch (err) {\n console.warn(`[InvitationEvents] Error in listener for ${event}:`, err);\n }\n });\n }\n}\n"]}
@@ -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"]}