@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
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
2
13
  Object.defineProperty(exports, "__esModule", { value: true });
3
14
  exports.extractFormConfiguration = extractFormConfiguration;
4
15
  exports.convertFormStyleToRNStyle = convertFormStyleToRNStyle;
@@ -8,15 +19,25 @@ exports.getEmailPlaceholder = getEmailPlaceholder;
8
19
  exports.getSubmitButtonLabel = getSubmitButtonLabel;
9
20
  exports.hasGridLayout = hasGridLayout;
10
21
  exports.hasEmailAndShareInSeparateColumns = hasEmailAndShareInSeparateColumns;
22
+ exports.getRoleOptions = getRoleOptions;
11
23
  /**
12
24
  * Extracts the form configuration from the widget configuration
13
25
  */
14
26
  function extractFormConfiguration(widgetConfiguration) {
15
27
  var _a, _b, _c;
16
- if (!((_c = (_b = (_a = widgetConfiguration === null || widgetConfiguration === void 0 ? void 0 : widgetConfiguration.configuration) === null || _a === void 0 ? void 0 : _a.props) === null || _b === void 0 ? void 0 : _b["vortex.components.form"]) === null || _c === void 0 ? void 0 : _c.value)) {
28
+ const formValue = (_c = (_b = (_a = widgetConfiguration === null || widgetConfiguration === void 0 ? void 0 : widgetConfiguration.configuration) === null || _a === void 0 ? void 0 : _a.props) === null || _b === void 0 ? void 0 : _b['vortex.components.form']) === null || _c === void 0 ? void 0 : _c.value;
29
+ if (!formValue) {
17
30
  return null;
18
31
  }
19
- return widgetConfiguration.configuration.props["vortex.components.form"].value;
32
+ // Normalize: if the value contains a root node, start traversal from it
33
+ if (formValue.root) {
34
+ return [formValue.root];
35
+ }
36
+ // If it's already an array, return as-is
37
+ if (Array.isArray(formValue)) {
38
+ return formValue;
39
+ }
40
+ return null;
20
41
  }
21
42
  /**
22
43
  * Converts form component style object to React Native styles
@@ -25,23 +46,35 @@ function convertFormStyleToRNStyle(style) {
25
46
  if (!style)
26
47
  return {};
27
48
  const rnStyle = {};
49
+ const toCamel = (s) => s.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
50
+ const parseValue = (val) => {
51
+ if (typeof val === 'number')
52
+ return val;
53
+ if (typeof val !== 'string')
54
+ return String(val);
55
+ const pxMatch = val.match(/^(-?\d+(?:\.\d+)?)px$/i);
56
+ if (pxMatch)
57
+ return Number(pxMatch[1]);
58
+ const num = Number(val);
59
+ if (!isNaN(num))
60
+ return num;
61
+ return val;
62
+ };
28
63
  Object.keys(style).forEach((key) => {
29
- const styleObj = style[key];
30
- // Handle special cases like background-color to backgroundColor
31
- const normalizedKey = key.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
32
- // Use computedValue if available, otherwise use value
33
- if (styleObj.computedValue) {
34
- rnStyle[normalizedKey] = styleObj.computedValue;
35
- }
36
- else if (styleObj.value !== undefined) {
37
- // Handle numeric values
38
- if (typeof styleObj.value === 'string' && !isNaN(Number(styleObj.value))) {
39
- rnStyle[normalizedKey] = Number(styleObj.value);
64
+ const raw = style[key];
65
+ const normalizedKey = toCamel(key);
66
+ if (raw && typeof raw === 'object' && ('value' in raw || 'computedValue' in raw)) {
67
+ const styleObj = raw;
68
+ if (styleObj.computedValue !== undefined) {
69
+ rnStyle[normalizedKey] = parseValue(styleObj.computedValue);
40
70
  }
41
- else {
42
- rnStyle[normalizedKey] = styleObj.value;
71
+ else if (styleObj.value !== undefined) {
72
+ rnStyle[normalizedKey] = parseValue(styleObj.value);
43
73
  }
44
74
  }
75
+ else {
76
+ rnStyle[normalizedKey] = parseValue(raw);
77
+ }
45
78
  });
46
79
  return rnStyle;
47
80
  }
@@ -71,40 +104,90 @@ function findComponentByRole(formConfig, role) {
71
104
  * Merges theme styles with component-specific styles from form configuration
72
105
  */
73
106
  function mergeThemeAndComponentStyles(themeStyles, themeColors, formConfig) {
107
+ var _a;
74
108
  // Start with the base theme styles
75
109
  const mergedStyles = Object.assign({}, themeStyles);
110
+ // Helper: find first node by predicate
111
+ const findNode = (nodes, predicate) => {
112
+ var _a;
113
+ if (!nodes)
114
+ return null;
115
+ for (const node of nodes) {
116
+ if (predicate(node))
117
+ return node;
118
+ if ((_a = node.children) === null || _a === void 0 ? void 0 : _a.length) {
119
+ const found = findNode(node.children, predicate);
120
+ if (found)
121
+ return found;
122
+ }
123
+ }
124
+ return null;
125
+ };
126
+ // 1) Merge root container style into containerStyles
127
+ const rootNode = formConfig === null || formConfig === void 0 ? void 0 : formConfig[0];
128
+ if (rootNode === null || rootNode === void 0 ? void 0 : rootNode.style) {
129
+ const rootStyle = convertFormStyleToRNStyle(rootNode.style);
130
+ // Avoid applying absolute dimensions that can break responsiveness on mobile
131
+ const _b = rootStyle, { width, height, maxWidth, minWidth, maxHeight, minHeight } = _b, responsiveRoot = __rest(_b, ["width", "height", "maxWidth", "minWidth", "maxHeight", "minHeight"]);
132
+ mergedStyles.containerStyles = Object.assign(Object.assign({}, mergedStyles.containerStyles), responsiveRoot);
133
+ }
76
134
  // Find submit button and email input components
77
135
  const submitButton = findComponentByRole(formConfig, 'submit');
78
136
  const emailInput = findComponentByRole(formConfig, 'email');
79
- // Merge submit button styles
137
+ // 2) Merge submit button styles
80
138
  if (submitButton === null || submitButton === void 0 ? void 0 : submitButton.style) {
81
139
  const submitButtonStyle = convertFormStyleToRNStyle(submitButton.style);
82
- mergedStyles.primaryButton = Object.assign(Object.assign(Object.assign({}, mergedStyles.primaryButton), (submitButtonStyle['backgroundColor'] && { backgroundColor: submitButtonStyle['backgroundColor'] })), (submitButtonStyle['borderColor'] && { borderColor: submitButtonStyle['borderColor'] }));
140
+ mergedStyles.primaryButton = Object.assign(Object.assign(Object.assign({}, mergedStyles.primaryButton), (submitButtonStyle['backgroundColor'] && {
141
+ backgroundColor: submitButtonStyle['backgroundColor'],
142
+ })), (submitButtonStyle['borderColor'] && { borderColor: submitButtonStyle['borderColor'] }));
83
143
  // Update button text if there's a color specified
84
144
  if (submitButtonStyle['color']) {
85
145
  mergedStyles.primaryButtonText = Object.assign(Object.assign({}, mergedStyles.primaryButtonText), { color: submitButtonStyle['color'] });
86
146
  }
87
147
  }
88
- // Merge email input styles
148
+ // 3) Merge email input styles
89
149
  if (emailInput === null || emailInput === void 0 ? void 0 : emailInput.style) {
90
150
  const emailInputStyle = convertFormStyleToRNStyle(emailInput.style);
91
151
  mergedStyles.inputStyles = Object.assign(Object.assign({}, mergedStyles.inputStyles), emailInputStyle);
92
152
  }
153
+ // 4) Merge vrtx-share-options block theme into secondary buttons
154
+ const shareOptionsBlock = findNode(formConfig, (n) => n.type === 'block' &&
155
+ (n.subtype === 'vrtx-share-options' || n.tagName === 'vrtx-share-options'));
156
+ const optionEntries = (_a = shareOptionsBlock === null || shareOptionsBlock === void 0 ? void 0 : shareOptionsBlock.theme) === null || _a === void 0 ? void 0 : _a.options;
157
+ if (Array.isArray(optionEntries)) {
158
+ const map = {};
159
+ optionEntries.forEach((it) => {
160
+ if ((it === null || it === void 0 ? void 0 : it.key) && typeof it.value === 'string')
161
+ map[it.key] = it.value;
162
+ });
163
+ const bg = map['--vrtx-icon-button-background'];
164
+ const color = map['--vrtx-icon-button-color'];
165
+ if (bg) {
166
+ mergedStyles.secondaryButton = Object.assign(Object.assign({}, mergedStyles.secondaryButton), { backgroundColor: bg });
167
+ }
168
+ if (color) {
169
+ mergedStyles.secondaryButtonText = Object.assign(Object.assign({}, mergedStyles.secondaryButtonText), { color });
170
+ }
171
+ }
93
172
  return mergedStyles;
94
173
  }
95
174
  /**
96
175
  * Get email input placeholder from form configuration
97
176
  */
98
177
  function getEmailPlaceholder(formConfig) {
178
+ var _a;
99
179
  const emailInput = findComponentByRole(formConfig, 'email');
100
- return (emailInput === null || emailInput === void 0 ? void 0 : emailInput.placeholder) || 'Enter email';
180
+ // Prefer attributes.placeholder as per current JSON shape
181
+ const attrPlaceholder = (_a = emailInput === null || emailInput === void 0 ? void 0 : emailInput.attributes) === null || _a === void 0 ? void 0 : _a.placeholder;
182
+ return attrPlaceholder || (emailInput === null || emailInput === void 0 ? void 0 : emailInput.placeholder) || 'Enter email';
101
183
  }
102
184
  /**
103
185
  * Get submit button label from form configuration
104
186
  */
105
187
  function getSubmitButtonLabel(formConfig) {
106
188
  const submitButton = findComponentByRole(formConfig, 'submit');
107
- return (submitButton === null || submitButton === void 0 ? void 0 : submitButton.label) || 'Invite';
189
+ // Prefer textContent per current JSON; fallback to label
190
+ return (submitButton === null || submitButton === void 0 ? void 0 : submitButton.textContent) || (submitButton === null || submitButton === void 0 ? void 0 : submitButton.label) || 'Invite';
108
191
  }
109
192
  /**
110
193
  * Determines if the form layout uses a grid structure
@@ -133,42 +216,69 @@ function hasGridLayout(formConfig) {
133
216
  function hasEmailAndShareInSeparateColumns(formConfig) {
134
217
  if (!formConfig)
135
218
  return false;
136
- // Look for a grid with multiple grid-items
137
- const findSeparateColumns = (components) => {
138
- for (const component of components) {
139
- if (component.type === 'grid' && component.children) {
140
- // Check if there are at least 2 grid-items
141
- const gridItems = component.children.filter(child => child.type === 'grid-item');
142
- if (gridItems.length >= 2) {
143
- // Check if one has email and one has share
144
- let hasEmailItem = false;
145
- let hasShareItem = false;
146
- for (const item of gridItems) {
147
- if (!item.children)
148
- continue;
149
- // Check for email component
150
- if (!hasEmailItem) {
151
- hasEmailItem = item.children.some(child => {
152
- var _a;
153
- return child.type === 'form' &&
154
- ((_a = child.children) === null || _a === void 0 ? void 0 : _a.some(formChild => { var _a; return ((_a = formChild.vortex) === null || _a === void 0 ? void 0 : _a.role) === 'email'; }));
155
- });
156
- }
157
- // Check for share component
158
- if (!hasShareItem) {
159
- hasShareItem = item.children.some(child => child.type === 'vortex.components.share');
160
- }
219
+ // Adjusted to the current JSON tree (row/column/block)
220
+ const checkTree = (components) => {
221
+ for (const node of components) {
222
+ if (node.type === 'row' && Array.isArray(node.children)) {
223
+ // Look for two columns where one column has an email block and another has a submit block
224
+ const columns = node.children.filter((c) => c.type === 'column');
225
+ if (columns.length >= 2) {
226
+ let hasEmailCol = false;
227
+ let hasSubmitCol = false;
228
+ for (const col of columns) {
229
+ const blocks = (col.children || []).filter((c) => c.type === 'block');
230
+ const hasEmail = blocks.some((b) => { var _a; return ((_a = b.vortex) === null || _a === void 0 ? void 0 : _a.role) === 'email' || b.subtype === 'vrtx-email-invitations'; });
231
+ const hasSubmit = blocks.some((b) => { var _a; return ((_a = b.vortex) === null || _a === void 0 ? void 0 : _a.role) === 'submit' || b.subtype === 'vrtx-submit'; });
232
+ if (hasEmail)
233
+ hasEmailCol = true;
234
+ if (hasSubmit)
235
+ hasSubmitCol = true;
161
236
  }
162
- return hasEmailItem && hasShareItem;
237
+ if (hasEmailCol && hasSubmitCol)
238
+ return true;
163
239
  }
164
240
  }
165
- if (component.children) {
166
- const found = findSeparateColumns(component.children);
241
+ if (node.children && checkTree(node.children))
242
+ return true;
243
+ }
244
+ return false;
245
+ };
246
+ return checkTree(formConfig);
247
+ }
248
+ /**
249
+ * Extract role options from form configuration (e.g., vrtx-select with attributes.name === 'role')
250
+ */
251
+ function getRoleOptions(formConfig) {
252
+ if (!formConfig)
253
+ return [];
254
+ const findRoleSelect = (components) => {
255
+ var _a, _b, _c, _d;
256
+ for (const component of components) {
257
+ const isSelect = component.subtype === 'vrtx-select' || component.tagName === 'vrtx-select';
258
+ const isRole = ((_a = component === null || component === void 0 ? void 0 : component.attributes) === null || _a === void 0 ? void 0 : _a.name) === 'role' || ((_b = component.vortex) === null || _b === void 0 ? void 0 : _b.role) === 'role';
259
+ if (isSelect && isRole) {
260
+ return ((_c = component === null || component === void 0 ? void 0 : component.settings) === null || _c === void 0 ? void 0 : _c.options) || null;
261
+ }
262
+ if ((_d = component.children) === null || _d === void 0 ? void 0 : _d.length) {
263
+ const found = findRoleSelect(component.children);
167
264
  if (found)
168
- return true;
265
+ return found;
169
266
  }
170
267
  }
171
- return false;
268
+ return null;
172
269
  };
173
- return findSeparateColumns(formConfig);
270
+ const options = findRoleSelect(formConfig);
271
+ if (Array.isArray(options)) {
272
+ // Normalize to label/value objects
273
+ return options.map((opt) => {
274
+ var _a;
275
+ return ({
276
+ id: opt.id,
277
+ label: (_a = opt.label) !== null && _a !== void 0 ? _a : String(opt.value),
278
+ value: String(opt.value),
279
+ });
280
+ });
281
+ }
282
+ return [];
174
283
  }
284
+ //# sourceMappingURL=formUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formUtils.js","sourceRoot":"","sources":["../../src/utils/formUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { WidgetConfiguration } from '@teamvortexsoftware/vortex-types';\nimport { ThemeColors } from './themeUtils';\n\nexport interface FormComponentStyle {\n [key: string]: {\n label?: string;\n value?: string | number;\n computedValue?: string;\n unit?: string;\n };\n}\n\nexport interface FormComponentSettings {\n action?: {\n type: string;\n value: string;\n target?: string;\n };\n size?: number;\n}\n\nexport interface FormComponent {\n id: string;\n type: string;\n subtype?: string;\n label?: string;\n hint?: string;\n name?: string;\n required?: boolean;\n placeholder?: string;\n style?: FormComponentStyle;\n settings?: FormComponentSettings;\n vortex?: {\n role?: string;\n canRemove?: boolean;\n };\n children?: FormComponent[];\n multiValue?: boolean;\n validation?: Array<{\n type: string;\n value: string;\n operator: string;\n canRemove: boolean;\n errorMessage: string;\n }>;\n tagName?: string;\n textContent?: string;\n attributes?: {\n [key: string]: string;\n };\n}\n\nexport interface FormConfiguration {\n value: FormComponent[];\n valueType: string;\n}\n\n/**\n * Extracts the form configuration from the widget configuration\n */\nexport function extractFormConfiguration(\n widgetConfiguration?: WidgetConfiguration\n): FormComponent[] | null {\n const formValue = widgetConfiguration?.configuration?.props?.['vortex.components.form']\n ?.value as any;\n if (!formValue) {\n return null;\n }\n // Normalize: if the value contains a root node, start traversal from it\n if (formValue.root) {\n return [formValue.root] as unknown as FormComponent[];\n }\n // If it's already an array, return as-is\n if (Array.isArray(formValue)) {\n return formValue as FormComponent[];\n }\n return null;\n}\n\n/**\n * Converts form component style object to React Native styles\n */\nexport function convertFormStyleToRNStyle(\n style?: FormComponentStyle | Record<string, any>\n): Record<string, string | number> {\n if (!style) return {};\n\n const rnStyle: Record<string, string | number> = {};\n\n const toCamel = (s: string) => s.replace(/-([a-z])/g, (g) => g[1].toUpperCase());\n const parseValue = (val: any): string | number => {\n if (typeof val === 'number') return val;\n if (typeof val !== 'string') return String(val);\n const pxMatch = val.match(/^(-?\\d+(?:\\.\\d+)?)px$/i);\n if (pxMatch) return Number(pxMatch[1]);\n const num = Number(val);\n if (!isNaN(num)) return num;\n return val;\n };\n\n Object.keys(style).forEach((key) => {\n const raw = (style as any)[key];\n const normalizedKey = toCamel(key);\n\n if (raw && typeof raw === 'object' && ('value' in raw || 'computedValue' in raw)) {\n const styleObj = raw as { value?: any; computedValue?: any };\n if (styleObj.computedValue !== undefined) {\n rnStyle[normalizedKey] = parseValue(styleObj.computedValue);\n } else if (styleObj.value !== undefined) {\n rnStyle[normalizedKey] = parseValue(styleObj.value);\n }\n } else {\n rnStyle[normalizedKey] = parseValue(raw);\n }\n });\n\n return rnStyle;\n}\n\n/**\n * Find a specific component by role in the form configuration\n */\nexport function findComponentByRole(\n formConfig: FormComponent[] | null,\n role: string\n): FormComponent | null {\n if (!formConfig) return null;\n\n const findComponent = (components: FormComponent[]): FormComponent | null => {\n for (const component of components) {\n if (component.vortex?.role === role) {\n return component;\n }\n\n if (component.children) {\n const found = findComponent(component.children);\n if (found) return found;\n }\n }\n\n return null;\n };\n\n return findComponent(formConfig);\n}\n\n/**\n * Merges theme styles with component-specific styles from form configuration\n */\nexport function mergeThemeAndComponentStyles(\n themeStyles: Record<string, Record<string, string | number>>,\n themeColors: ThemeColors,\n formConfig: FormComponent[] | null\n): Record<string, Record<string, string | number>> {\n // Start with the base theme styles\n const mergedStyles = { ...themeStyles };\n\n // Helper: find first node by predicate\n const findNode = (\n nodes: FormComponent[] | null | undefined,\n predicate: (n: any) => boolean\n ): any => {\n if (!nodes) return null;\n for (const node of nodes) {\n if (predicate(node)) return node;\n if (node.children?.length) {\n const found = findNode(node.children, predicate);\n if (found) return found;\n }\n }\n return null;\n };\n\n // 1) Merge root container style into containerStyles\n const rootNode = formConfig?.[0];\n if (rootNode?.style) {\n const rootStyle = convertFormStyleToRNStyle(rootNode.style as any);\n // Avoid applying absolute dimensions that can break responsiveness on mobile\n const { width, height, maxWidth, minWidth, maxHeight, minHeight, ...responsiveRoot } =\n rootStyle as any;\n mergedStyles.containerStyles = {\n ...mergedStyles.containerStyles,\n ...responsiveRoot,\n };\n }\n\n // Find submit button and email input components\n const submitButton = findComponentByRole(formConfig, 'submit');\n const emailInput = findComponentByRole(formConfig, 'email');\n\n // 2) Merge submit button styles\n if (submitButton?.style) {\n const submitButtonStyle = convertFormStyleToRNStyle(submitButton.style);\n mergedStyles.primaryButton = {\n ...mergedStyles.primaryButton,\n ...(submitButtonStyle['backgroundColor'] && {\n backgroundColor: submitButtonStyle['backgroundColor'],\n }),\n ...(submitButtonStyle['borderColor'] && { borderColor: submitButtonStyle['borderColor'] }),\n };\n\n // Update button text if there's a color specified\n if (submitButtonStyle['color']) {\n mergedStyles.primaryButtonText = {\n ...mergedStyles.primaryButtonText,\n color: submitButtonStyle['color'],\n };\n }\n }\n\n // 3) Merge email input styles\n if (emailInput?.style) {\n const emailInputStyle = convertFormStyleToRNStyle(emailInput.style);\n mergedStyles.inputStyles = {\n ...mergedStyles.inputStyles,\n ...emailInputStyle,\n };\n }\n\n // 4) Merge vrtx-share-options block theme into secondary buttons\n const shareOptionsBlock = findNode(\n formConfig,\n (n) =>\n n.type === 'block' &&\n (n.subtype === 'vrtx-share-options' || n.tagName === 'vrtx-share-options')\n ) as any;\n const optionEntries: Array<{ key?: string; value?: string }> | undefined =\n shareOptionsBlock?.theme?.options;\n if (Array.isArray(optionEntries)) {\n const map: Record<string, string> = {};\n optionEntries.forEach((it) => {\n if (it?.key && typeof it.value === 'string') map[it.key] = it.value;\n });\n const bg = map['--vrtx-icon-button-background'];\n const color = map['--vrtx-icon-button-color'];\n if (bg) {\n mergedStyles.secondaryButton = {\n ...mergedStyles.secondaryButton,\n backgroundColor: bg,\n };\n }\n if (color) {\n mergedStyles.secondaryButtonText = {\n ...mergedStyles.secondaryButtonText,\n color,\n };\n }\n }\n\n return mergedStyles;\n}\n\n/**\n * Get email input placeholder from form configuration\n */\nexport function getEmailPlaceholder(formConfig: FormComponent[] | null): string {\n const emailInput = findComponentByRole(formConfig, 'email');\n // Prefer attributes.placeholder as per current JSON shape\n const attrPlaceholder = (emailInput as any)?.attributes?.placeholder;\n return attrPlaceholder || emailInput?.placeholder || 'Enter email';\n}\n\n/**\n * Get submit button label from form configuration\n */\nexport function getSubmitButtonLabel(formConfig: FormComponent[] | null): string {\n const submitButton = findComponentByRole(formConfig, 'submit') as any;\n // Prefer textContent per current JSON; fallback to label\n return submitButton?.textContent || submitButton?.label || 'Invite';\n}\n\n/**\n * Determines if the form layout uses a grid structure\n */\nexport function hasGridLayout(formConfig: FormComponent[] | null): boolean {\n if (!formConfig) return false;\n\n const findGrid = (components: FormComponent[]): boolean => {\n for (const component of components) {\n if (component.type === 'grid') {\n return true;\n }\n\n if (component.children) {\n const found = findGrid(component.children);\n if (found) return true;\n }\n }\n\n return false;\n };\n\n return findGrid(formConfig);\n}\n\n/**\n * Determines if email and share components are in separate grid items\n */\nexport function hasEmailAndShareInSeparateColumns(formConfig: FormComponent[] | null): boolean {\n if (!formConfig) return false;\n\n // Adjusted to the current JSON tree (row/column/block)\n const checkTree = (components: FormComponent[]): boolean => {\n for (const node of components) {\n if (node.type === 'row' && Array.isArray(node.children)) {\n // Look for two columns where one column has an email block and another has a submit block\n const columns = node.children.filter((c) => c.type === 'column');\n if (columns.length >= 2) {\n let hasEmailCol = false;\n let hasSubmitCol = false;\n\n for (const col of columns) {\n const blocks = (col.children || []).filter((c) => c.type === 'block');\n const hasEmail = blocks.some(\n (b) => b.vortex?.role === 'email' || b.subtype === 'vrtx-email-invitations'\n );\n const hasSubmit = blocks.some(\n (b) => b.vortex?.role === 'submit' || b.subtype === 'vrtx-submit'\n );\n if (hasEmail) hasEmailCol = true;\n if (hasSubmit) hasSubmitCol = true;\n }\n\n if (hasEmailCol && hasSubmitCol) return true;\n }\n }\n\n if (node.children && checkTree(node.children)) return true;\n }\n return false;\n };\n\n return checkTree(formConfig);\n}\n\n/**\n * Extract role options from form configuration (e.g., vrtx-select with attributes.name === 'role')\n */\nexport function getRoleOptions(\n formConfig: FormComponent[] | null\n): Array<{ id?: string; label: string; value: string }> {\n if (!formConfig) return [];\n\n const findRoleSelect = (components: FormComponent[]): any | null => {\n for (const component of components) {\n const isSelect = component.subtype === 'vrtx-select' || component.tagName === 'vrtx-select';\n const isRole =\n (component as any)?.attributes?.name === 'role' || component.vortex?.role === 'role';\n if (isSelect && isRole) {\n return (component as any)?.settings?.options || null;\n }\n if (component.children?.length) {\n const found = findRoleSelect(component.children);\n if (found) return found;\n }\n }\n return null;\n };\n\n const options = findRoleSelect(formConfig);\n if (Array.isArray(options)) {\n // Normalize to label/value objects\n return options.map((opt: any) => ({\n id: opt.id,\n label: opt.label ?? String(opt.value),\n value: String(opt.value),\n }));\n }\n return [];\n}\n"]}
@@ -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"]}