@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,181 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.ShareButton = ShareButton;
40
+ exports.ShareButtons = ShareButtons;
41
+ const react_1 = __importStar(require("react"));
42
+ const react_native_1 = require("react-native");
43
+ const FontAwesome6_1 = __importDefault(require("react-native-vector-icons/FontAwesome6"));
44
+ const react_native_qrcode_svg_1 = __importDefault(require("react-native-qrcode-svg"));
45
+ function ShareButton({ iconName, label, onPress, themeColors, themeStyles, }) {
46
+ return (<react_native_1.View style={styles.shareButtonWrapper}>
47
+ <react_native_1.Pressable style={[styles.shareButton, themeStyles.secondaryButton]} onPress={onPress}>
48
+ <react_native_1.View style={styles.buttonContentContainer}>
49
+ <FontAwesome6_1.default name={iconName} size={24} color={themeColors.secondaryButtonForeground}/>
50
+ <react_native_1.Text style={[styles.shareButtonText, themeStyles.secondaryButtonText]}>{label}</react_native_1.Text>
51
+ </react_native_1.View>
52
+ </react_native_1.Pressable>
53
+ </react_native_1.View>);
54
+ }
55
+ function ShareButtons({ has, themeColors, themeStyles, handleShareLink, handleCopyLink, handleSmsShare, handleEmailShare, shareableLink, }) {
56
+ const [showQRCode, setShowQRCode] = (0, react_1.useState)(false);
57
+ // Define button configurations
58
+ const buttonConfigs = [
59
+ {
60
+ key: 'shareOptionsCopyLink',
61
+ iconName: 'copy',
62
+ label: 'Copy',
63
+ onPress: handleCopyLink,
64
+ isAvailable: true, // Always available when share is enabled
65
+ isWithShowUrl: has.shareOptionsCopyLink, // Special handling only if specifically enabled
66
+ },
67
+ {
68
+ key: 'shareOptionsSms',
69
+ iconName: 'message',
70
+ label: 'SMS',
71
+ onPress: handleSmsShare,
72
+ isAvailable: has.shareOptionsSms,
73
+ },
74
+ {
75
+ key: 'shareOptionsEmail',
76
+ iconName: 'envelope',
77
+ label: 'Email',
78
+ onPress: handleEmailShare,
79
+ isAvailable: has.shareOptionsEmail,
80
+ },
81
+ {
82
+ key: 'shareOptionsNativeShareSheet',
83
+ iconName: 'share-nodes',
84
+ label: 'Share Link',
85
+ onPress: handleShareLink,
86
+ isAvailable: has.shareOptionsNativeShareSheet,
87
+ },
88
+ {
89
+ key: 'shareOptionsQRCode',
90
+ iconName: 'qrcode',
91
+ label: 'QR Code',
92
+ onPress: () => setShowQRCode(!showQRCode),
93
+ isAvailable: has.shareOptionsQrCode,
94
+ },
95
+ {
96
+ key: 'shareOptionsWhatsApp',
97
+ iconName: 'whatsapp',
98
+ label: 'WhatsApp',
99
+ onPress: () => { },
100
+ isAvailable: has.shareOptionsWhatsApp,
101
+ },
102
+ // Add more share options as needed
103
+ // Example:
104
+ // {
105
+ // key: 'shareOptionsFacebookMessenger',
106
+ // iconName: 'facebook-messenger',
107
+ // label: 'Messenger',
108
+ // onPress: () => {},
109
+ // isAvailable: has.shareOptionsFacebookMessenger,
110
+ // },
111
+ ];
112
+ return (<>
113
+ {showQRCode && shareableLink && (<react_native_1.View style={styles.qrCodeContainer}>
114
+ <react_native_qrcode_svg_1.default value={shareableLink} size={200} color={themeColors.containerForeground} backgroundColor={themeColors.containerBackground}/>
115
+ </react_native_1.View>)}
116
+ {buttonConfigs
117
+ .filter((config) => config.isAvailable)
118
+ .map((config) => config.isWithShowUrl && config.key === 'shareOptionsCopyLink' && shareableLink ? (<react_native_1.View key={config.key} style={styles.copyLinkContainer}>
119
+ <react_native_1.TextInput style={[
120
+ styles.linkInput,
121
+ {
122
+ color: themeColors.containerForeground,
123
+ borderColor: themeColors.containerBorder,
124
+ },
125
+ ]} value={shareableLink} editable={false}/>
126
+ <react_native_1.Pressable style={[styles.copyButton, themeStyles.secondaryButton]} onPress={handleCopyLink}>
127
+ <FontAwesome6_1.default name="copy" size={20} color={themeColors.secondaryButtonForeground}/>
128
+ </react_native_1.Pressable>
129
+ </react_native_1.View>) : (<ShareButton key={config.key} iconName={config.iconName} label={config.label} onPress={config.onPress} themeColors={themeColors} themeStyles={themeStyles}/>))}
130
+ </>);
131
+ }
132
+ const styles = react_native_1.StyleSheet.create({
133
+ shareButtonWrapper: {
134
+ width: '48%',
135
+ margin: 5,
136
+ },
137
+ shareButton: {
138
+ flexDirection: 'row',
139
+ alignItems: 'center',
140
+ padding: 10,
141
+ borderWidth: 1,
142
+ borderRadius: 5,
143
+ justifyContent: 'center',
144
+ },
145
+ buttonContentContainer: {
146
+ flexDirection: 'row',
147
+ alignItems: 'center',
148
+ },
149
+ shareButtonText: {
150
+ marginLeft: 10,
151
+ },
152
+ qrCodeContainer: {
153
+ width: '100%',
154
+ alignItems: 'center',
155
+ justifyContent: 'center',
156
+ marginBottom: 20,
157
+ padding: 10,
158
+ },
159
+ copyLinkContainer: {
160
+ width: '100%',
161
+ flexDirection: 'row',
162
+ marginVertical: 5,
163
+ alignItems: 'center',
164
+ },
165
+ linkInput: {
166
+ flex: 1,
167
+ borderWidth: 1,
168
+ borderRadius: 5,
169
+ padding: 10,
170
+ marginRight: 5,
171
+ },
172
+ copyButton: {
173
+ width: 44,
174
+ height: 44,
175
+ alignItems: 'center',
176
+ justifyContent: 'center',
177
+ borderWidth: 1,
178
+ borderRadius: 5,
179
+ },
180
+ });
181
+ //# sourceMappingURL=ShareButtons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShareButtons.js","sourceRoot":"","sources":["../../src/components/ShareButtons.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState } from 'react';\nimport { Pressable, StyleSheet, Text, TextInput, View, Linking } from 'react-native';\nimport Icon from 'react-native-vector-icons/FontAwesome6';\nimport { ThemeColors } from '../utils/themeUtils';\nimport QRCode from 'react-native-qrcode-svg';\n\n/**\n * ShareButton component for rendering a single share option button\n */\ninterface ShareButtonProps {\n iconName: string;\n label: string;\n onPress: () => void;\n themeColors: ThemeColors;\n themeStyles: any;\n}\n\nexport function ShareButton({\n iconName,\n label,\n onPress,\n themeColors,\n themeStyles,\n}: ShareButtonProps) {\n return (\n <View style={styles.shareButtonWrapper}>\n <Pressable style={[styles.shareButton, themeStyles.secondaryButton]} onPress={onPress}>\n <View style={styles.buttonContentContainer}>\n <Icon name={iconName} size={24} color={themeColors.secondaryButtonForeground} />\n <Text style={[styles.shareButtonText, themeStyles.secondaryButtonText]}>{label}</Text>\n </View>\n </Pressable>\n </View>\n );\n}\n\n/**\n * ShareButtons component for rendering all available share options\n */\nexport interface ShareButtonsProps {\n has: any;\n themeColors: ThemeColors;\n themeStyles: any;\n handleShareLink: () => void;\n handleCopyLink: () => void;\n handleSmsShare: () => void;\n handleEmailShare: () => void;\n shareableLink?: string;\n}\n\nexport function ShareButtons({\n has,\n themeColors,\n themeStyles,\n handleShareLink,\n handleCopyLink,\n handleSmsShare,\n handleEmailShare,\n shareableLink,\n}: ShareButtonsProps) {\n const [showQRCode, setShowQRCode] = useState(false);\n // Define button configurations\n const buttonConfigs = [\n {\n key: 'shareOptionsCopyLink',\n iconName: 'copy',\n label: 'Copy',\n onPress: handleCopyLink,\n isAvailable: true, // Always available when share is enabled\n isWithShowUrl: has.shareOptionsCopyLink, // Special handling only if specifically enabled\n },\n {\n key: 'shareOptionsSms',\n iconName: 'message',\n label: 'SMS',\n onPress: handleSmsShare,\n isAvailable: has.shareOptionsSms,\n },\n {\n key: 'shareOptionsEmail',\n iconName: 'envelope',\n label: 'Email',\n onPress: handleEmailShare,\n isAvailable: has.shareOptionsEmail,\n },\n {\n key: 'shareOptionsNativeShareSheet',\n iconName: 'share-nodes',\n label: 'Share Link',\n onPress: handleShareLink,\n isAvailable: has.shareOptionsNativeShareSheet,\n },\n {\n key: 'shareOptionsQRCode',\n iconName: 'qrcode',\n label: 'QR Code',\n onPress: () => setShowQRCode(!showQRCode),\n isAvailable: has.shareOptionsQrCode,\n },\n {\n key: 'shareOptionsWhatsApp',\n iconName: 'whatsapp',\n label: 'WhatsApp',\n onPress: () => {},\n isAvailable: has.shareOptionsWhatsApp,\n },\n\n // Add more share options as needed\n // Example:\n // {\n // key: 'shareOptionsFacebookMessenger',\n // iconName: 'facebook-messenger',\n // label: 'Messenger',\n // onPress: () => {},\n // isAvailable: has.shareOptionsFacebookMessenger,\n // },\n ];\n\n return (\n <>\n {showQRCode && shareableLink && (\n <View style={styles.qrCodeContainer}>\n <QRCode\n value={shareableLink}\n size={200}\n color={themeColors.containerForeground}\n backgroundColor={themeColors.containerBackground}\n />\n </View>\n )}\n {buttonConfigs\n .filter((config) => config.isAvailable)\n .map((config) =>\n config.isWithShowUrl && config.key === 'shareOptionsCopyLink' && shareableLink ? (\n <View key={config.key} style={styles.copyLinkContainer}>\n <TextInput\n style={[\n styles.linkInput,\n {\n color: themeColors.containerForeground,\n borderColor: themeColors.containerBorder,\n },\n ]}\n value={shareableLink}\n editable={false}\n />\n <Pressable\n style={[styles.copyButton, themeStyles.secondaryButton]}\n onPress={handleCopyLink}\n >\n <Icon name=\"copy\" size={20} color={themeColors.secondaryButtonForeground} />\n </Pressable>\n </View>\n ) : (\n <ShareButton\n key={config.key}\n iconName={config.iconName}\n label={config.label}\n onPress={config.onPress}\n themeColors={themeColors}\n themeStyles={themeStyles}\n />\n )\n )}\n </>\n );\n}\n\nconst styles = StyleSheet.create({\n shareButtonWrapper: {\n width: '48%',\n margin: 5,\n },\n shareButton: {\n flexDirection: 'row',\n alignItems: 'center',\n padding: 10,\n borderWidth: 1,\n borderRadius: 5,\n justifyContent: 'center',\n },\n buttonContentContainer: {\n flexDirection: 'row',\n alignItems: 'center',\n },\n shareButtonText: {\n marginLeft: 10,\n },\n qrCodeContainer: {\n width: '100%',\n alignItems: 'center',\n justifyContent: 'center',\n marginBottom: 20,\n padding: 10,\n },\n copyLinkContainer: {\n width: '100%',\n flexDirection: 'row',\n marginVertical: 5,\n alignItems: 'center',\n },\n linkInput: {\n flex: 1,\n borderWidth: 1,\n borderRadius: 5,\n padding: 10,\n marginRight: 5,\n },\n copyButton: {\n width: 44,\n height: 44,\n alignItems: 'center',\n justifyContent: 'center',\n borderWidth: 1,\n borderRadius: 5,\n },\n});\n"]}
@@ -0,0 +1,234 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.VrtxContactsImport = VrtxContactsImport;
16
+ const react_1 = __importDefault(require("react"));
17
+ const react_native_1 = require("react-native");
18
+ const VortexModulesContext_1 = require("../context/VortexModulesContext");
19
+ const isWeb = react_native_1.Platform.OS === 'web';
20
+ const ButtonWrapper = ({ children, style, gradientString, onPress, disabled, }) => {
21
+ // Get the gradient module and loaders from context
22
+ const { gradientModule, loaders } = (0, VortexModulesContext_1.useVortexModules)();
23
+ const styleArray = Array.isArray(style) ? style : [style];
24
+ // On web, use CSS gradients directly
25
+ if (gradientString && isWeb) {
26
+ return (<react_native_1.TouchableOpacity style={[...styleArray, { background: gradientString }]} onPress={onPress} disabled={disabled} activeOpacity={0.7}>
27
+ {children}
28
+ </react_native_1.TouchableOpacity>);
29
+ }
30
+ // On native, try to use gradient library if specified
31
+ if (gradientString && gradientModule && loaders) {
32
+ const GradientComponent = loaders.loadGradientComponent(gradientModule);
33
+ const parsed = loaders.parseCSSLinearGradient(gradientString);
34
+ if (GradientComponent && parsed) {
35
+ const points = loaders.angleToGradientPoints(parsed.angle);
36
+ return (<react_native_1.TouchableOpacity onPress={onPress} disabled={disabled} activeOpacity={0.7}>
37
+ <GradientComponent colors={parsed.colors} locations={parsed.locations} start={points.start} end={points.end} style={styleArray}>
38
+ {children}
39
+ </GradientComponent>
40
+ </react_native_1.TouchableOpacity>);
41
+ }
42
+ }
43
+ // Fallback: solid color from first gradient stop
44
+ const fallbackColor = gradientString && loaders ? loaders.parseGradientFirstColor(gradientString) : null;
45
+ const finalStyle = fallbackColor ? [...styleArray, { backgroundColor: fallbackColor }] : styleArray;
46
+ return (<react_native_1.TouchableOpacity style={finalStyle} onPress={onPress} disabled={disabled} activeOpacity={0.7}>
47
+ {children}
48
+ </react_native_1.TouchableOpacity>);
49
+ };
50
+ function VrtxContactsImport({ block, renderIcon, isNativeContactsEnabled, isGoogleContactsEnabled, handleSelectFromContacts, handleSelectFromGoogle, triggerHaptic, isEditMode = false, }) {
51
+ var _a;
52
+ // Get loaders from context
53
+ const { loaders } = (0, VortexModulesContext_1.useVortexModules)();
54
+ // Helper to get customization label - null/undefined uses default, empty string shows nothing
55
+ const getCustomLabel = (key, defaultLabel) => {
56
+ var _a, _b, _c;
57
+ const textContent = (_c = (_b = (_a = block === null || block === void 0 ? void 0 : block.settings) === null || _a === void 0 ? void 0 : _a.customizations) === null || _b === void 0 ? void 0 : _b[key]) === null || _c === void 0 ? void 0 : _c.textContent;
58
+ // If textContent is null or undefined, use default. Empty string is valid (shows no label).
59
+ if (textContent === null || textContent === undefined) {
60
+ return defaultLabel;
61
+ }
62
+ return textContent;
63
+ };
64
+ const handleSelectFromContactsWithHaptics = () => __awaiter(this, void 0, void 0, function* () {
65
+ yield (triggerHaptic === null || triggerHaptic === void 0 ? void 0 : triggerHaptic('light'));
66
+ handleSelectFromContacts();
67
+ });
68
+ const handleSelectFromGoogleWithHaptics = () => __awaiter(this, void 0, void 0, function* () {
69
+ yield (triggerHaptic === null || triggerHaptic === void 0 ? void 0 : triggerHaptic('light'));
70
+ handleSelectFromGoogle();
71
+ });
72
+ // Convert theme options to inline styles
73
+ const themeToStyle = (theme) => {
74
+ if (!(theme === null || theme === void 0 ? void 0 : theme.options) || !Array.isArray(theme.options))
75
+ return {};
76
+ const style = {};
77
+ theme.options.forEach((option) => {
78
+ if (!option.value)
79
+ return;
80
+ const { key, value } = option;
81
+ // Handle padding and margin with shorthand expansion
82
+ if (key === '--vrtx-icon-button-padding' && value) {
83
+ const parts = value.trim().split(/\s+/);
84
+ if (parts.length === 1) {
85
+ style.paddingTop = style.paddingRight = style.paddingBottom = style.paddingLeft = value;
86
+ }
87
+ else if (parts.length === 2) {
88
+ style.paddingTop = style.paddingBottom = parts[0];
89
+ style.paddingRight = style.paddingLeft = parts[1];
90
+ }
91
+ else if (parts.length === 3) {
92
+ style.paddingTop = parts[0];
93
+ style.paddingRight = style.paddingLeft = parts[1];
94
+ style.paddingBottom = parts[2];
95
+ }
96
+ else if (parts.length === 4) {
97
+ style.paddingTop = parts[0];
98
+ style.paddingRight = parts[1];
99
+ style.paddingBottom = parts[2];
100
+ style.paddingLeft = parts[3];
101
+ }
102
+ return;
103
+ }
104
+ if (key === '--vrtx-icon-button-margin' && value) {
105
+ const parts = value.trim().split(/\s+/);
106
+ if (parts.length === 1) {
107
+ style.marginTop = style.marginRight = style.marginBottom = style.marginLeft = value;
108
+ }
109
+ else if (parts.length === 2) {
110
+ style.marginTop = style.marginBottom = parts[0];
111
+ style.marginRight = style.marginLeft = parts[1];
112
+ }
113
+ else if (parts.length === 3) {
114
+ style.marginTop = parts[0];
115
+ style.marginRight = style.marginLeft = parts[1];
116
+ style.marginBottom = parts[2];
117
+ }
118
+ else if (parts.length === 4) {
119
+ style.marginTop = parts[0];
120
+ style.marginRight = parts[1];
121
+ style.marginBottom = parts[2];
122
+ style.marginLeft = parts[3];
123
+ }
124
+ return;
125
+ }
126
+ // Map CSS custom properties to React Native style properties
127
+ const propertyMap = {
128
+ '--vrtx-icon-button-color': 'color',
129
+ '--vrtx-icon-button-background': 'background',
130
+ '--vrtx-icon-button-background-color': 'backgroundColor',
131
+ '--vrtx-icon-button-border-radius': 'borderRadius',
132
+ '--vrtx-icon-button-font-size': 'fontSize',
133
+ '--vrtx-icon-button-font-weight': 'fontWeight',
134
+ };
135
+ const styleProperty = propertyMap[key];
136
+ if (styleProperty) {
137
+ style[styleProperty] = value;
138
+ }
139
+ });
140
+ return style;
141
+ };
142
+ // Extract styles from the vrtx-contacts-import block itself (this block has the theme)
143
+ const blockStyle = (block === null || block === void 0 ? void 0 : block.style) || {};
144
+ const blockThemeStyle = themeToStyle(block === null || block === void 0 ? void 0 : block.theme);
145
+ // Merge styles (theme styles take precedence over block.style)
146
+ const mergedBlockStyle = Object.assign(Object.assign({}, blockStyle), blockThemeStyle);
147
+ // Extract gradient string and fallback color
148
+ // On native, 'background' is a CSS property that doesn't work — convert solid colors to 'backgroundColor'
149
+ const rawBlockBackground = mergedBlockStyle.background || null;
150
+ const isBlockGradient = rawBlockBackground === null || rawBlockBackground === void 0 ? void 0 : rawBlockBackground.includes('gradient');
151
+ const blockGradientString = isBlockGradient ? rawBlockBackground : null;
152
+ const blockFallbackColor = isBlockGradient
153
+ ? loaders === null || loaders === void 0 ? void 0 : loaders.parseGradientFirstColor(rawBlockBackground)
154
+ : rawBlockBackground || mergedBlockStyle.backgroundColor;
155
+ const blockTextColor = mergedBlockStyle.color || '#333';
156
+ // Create a clean style object without background/backgroundColor (we'll handle those separately)
157
+ const cleanBlockStyle = Object.assign({}, mergedBlockStyle);
158
+ delete cleanBlockStyle.background;
159
+ delete cleanBlockStyle.backgroundColor;
160
+ // Extract label from block attributes
161
+ const label = (_a = block === null || block === void 0 ? void 0 : block.attributes) === null || _a === void 0 ? void 0 : _a.label;
162
+ return (<react_native_1.View key={block.id} style={styles.contactButtonsContainer}>
163
+ {/* Section label from block attributes */}
164
+ {label && (<react_native_1.Text style={styles.sectionLabel}>{label}</react_native_1.Text>)}
165
+ {isNativeContactsEnabled() && (<ButtonWrapper style={[
166
+ styles.button,
167
+ styles.fullButton,
168
+ styles.tertiaryButton,
169
+ cleanBlockStyle,
170
+ blockFallbackColor ? { backgroundColor: blockFallbackColor } : undefined,
171
+ ]} gradientString={blockGradientString} onPress={handleSelectFromContactsWithHaptics}>
172
+ <react_native_1.View style={styles.buttonIconContainer}>
173
+ {renderIcon({ name: 'import-contacts', size: 18, color: blockTextColor })}
174
+ </react_native_1.View>
175
+ <react_native_1.Text style={[styles.tertiaryButtonText, { color: blockTextColor }]}>
176
+ {getCustomLabel('importContacts', 'Add from Contacts')}
177
+ </react_native_1.Text>
178
+ </ButtonWrapper>)}
179
+
180
+ {isGoogleContactsEnabled() && (<ButtonWrapper style={[
181
+ styles.button,
182
+ styles.fullButton,
183
+ styles.tertiaryButton,
184
+ cleanBlockStyle,
185
+ blockFallbackColor ? { backgroundColor: blockFallbackColor } : undefined,
186
+ ]} gradientString={blockGradientString} onPress={handleSelectFromGoogleWithHaptics}>
187
+ <react_native_1.View style={styles.buttonIconContainer}>
188
+ {renderIcon({ name: 'google', size: 18, color: blockTextColor })}
189
+ </react_native_1.View>
190
+ <react_native_1.Text style={[styles.tertiaryButtonText, { color: blockTextColor }]}>
191
+ {getCustomLabel('google', 'Add from Google Contacts')}
192
+ </react_native_1.Text>
193
+ </ButtonWrapper>)}
194
+ </react_native_1.View>);
195
+ }
196
+ const styles = react_native_1.StyleSheet.create({
197
+ contactButtonsContainer: {
198
+ gap: 12,
199
+ },
200
+ sectionLabel: {
201
+ fontSize: 14,
202
+ fontWeight: '500',
203
+ color: '#666',
204
+ marginBottom: 4,
205
+ },
206
+ button: {
207
+ paddingVertical: 12,
208
+ paddingHorizontal: 16,
209
+ borderRadius: 8,
210
+ flexDirection: 'row',
211
+ alignItems: 'center',
212
+ justifyContent: 'center',
213
+ gap: 8,
214
+ },
215
+ tertiaryButton: {
216
+ backgroundColor: '#f5f5f5',
217
+ },
218
+ fullButton: {
219
+ width: '100%',
220
+ },
221
+ buttonIconContainer: {
222
+ width: 18,
223
+ height: 18,
224
+ alignItems: 'center',
225
+ justifyContent: 'center',
226
+ overflow: 'visible',
227
+ },
228
+ tertiaryButtonText: {
229
+ color: '#333',
230
+ fontSize: 16,
231
+ fontWeight: '500',
232
+ },
233
+ });
234
+ //# sourceMappingURL=VrtxContactsImport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VrtxContactsImport.js","sourceRoot":"","sources":["../../src/components/VrtxContactsImport.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { View, Text, TouchableOpacity, StyleSheet, ViewStyle, Platform } from 'react-native';\nimport { IconRendererProps } from './InviteFormCore';\nimport { useVortexModules } from '../context/VortexModulesContext';\n\nconst isWeb = Platform.OS === 'web';\n\n// Button wrapper component that handles gradients on web, native gradient libraries, or solid color fallback\ninterface ButtonWrapperProps {\n children: React.ReactNode;\n style: ViewStyle | ViewStyle[];\n gradientString: string | null;\n onPress?: () => void;\n disabled?: boolean;\n}\n\nconst ButtonWrapper: React.FC<ButtonWrapperProps> = ({\n children,\n style,\n gradientString,\n onPress,\n disabled,\n}) => {\n // Get the gradient module and loaders from context\n const { gradientModule, loaders } = useVortexModules();\n const styleArray = Array.isArray(style) ? style : [style];\n\n // On web, use CSS gradients directly\n if (gradientString && isWeb) {\n return (\n <TouchableOpacity\n style={[...styleArray, { background: gradientString } as any]}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n }\n\n // On native, try to use gradient library if specified\n if (gradientString && gradientModule && loaders) {\n const GradientComponent = loaders.loadGradientComponent(gradientModule);\n const parsed = loaders.parseCSSLinearGradient(gradientString);\n\n if (GradientComponent && parsed) {\n const points = loaders.angleToGradientPoints(parsed.angle);\n\n return (\n <TouchableOpacity\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n <GradientComponent\n colors={parsed.colors}\n locations={parsed.locations}\n start={points.start}\n end={points.end}\n style={styleArray}\n >\n {children}\n </GradientComponent>\n </TouchableOpacity>\n );\n }\n }\n\n // Fallback: solid color from first gradient stop\n const fallbackColor = gradientString && loaders ? loaders.parseGradientFirstColor(gradientString) : null;\n const finalStyle = fallbackColor ? [...styleArray, { backgroundColor: fallbackColor }] : styleArray;\n\n return (\n <TouchableOpacity\n style={finalStyle}\n onPress={onPress}\n disabled={disabled}\n activeOpacity={0.7}\n >\n {children}\n </TouchableOpacity>\n );\n};\n\nexport interface VrtxContactsImportProps {\n block: any;\n renderIcon: (props: IconRendererProps) => React.ReactNode;\n isNativeContactsEnabled: () => boolean;\n isGoogleContactsEnabled: () => boolean;\n handleSelectFromContacts: () => void;\n handleSelectFromGoogle: () => void;\n triggerHaptic?: (style: 'light' | 'medium' | 'heavy') => Promise<void>;\n isEditMode?: boolean;\n}\n\nexport function VrtxContactsImport({\n block,\n renderIcon,\n isNativeContactsEnabled,\n isGoogleContactsEnabled,\n handleSelectFromContacts,\n handleSelectFromGoogle,\n triggerHaptic,\n isEditMode = false,\n}: VrtxContactsImportProps) {\n // Get loaders from context\n const { loaders } = useVortexModules();\n\n // Helper to get customization label - null/undefined uses default, empty string shows nothing\n const getCustomLabel = (key: string, defaultLabel: string): string => {\n const textContent = block?.settings?.customizations?.[key]?.textContent;\n // If textContent is null or undefined, use default. Empty string is valid (shows no label).\n if (textContent === null || textContent === undefined) {\n return defaultLabel;\n }\n return textContent;\n };\n\n const handleSelectFromContactsWithHaptics = async () => {\n await triggerHaptic?.('light');\n handleSelectFromContacts();\n };\n\n const handleSelectFromGoogleWithHaptics = async () => {\n await triggerHaptic?.('light');\n handleSelectFromGoogle();\n };\n\n // Convert theme options to inline styles\n const themeToStyle = (theme: any): Record<string, any> => {\n if (!theme?.options || !Array.isArray(theme.options)) return {};\n\n const style: Record<string, any> = {};\n\n theme.options.forEach((option: any) => {\n if (!option.value) return;\n\n const { key, value } = option;\n\n // Handle padding and margin with shorthand expansion\n if (key === '--vrtx-icon-button-padding' && value) {\n const parts = value.trim().split(/\\s+/);\n if (parts.length === 1) {\n style.paddingTop = style.paddingRight = style.paddingBottom = style.paddingLeft = value;\n } else if (parts.length === 2) {\n style.paddingTop = style.paddingBottom = parts[0];\n style.paddingRight = style.paddingLeft = parts[1];\n } else if (parts.length === 3) {\n style.paddingTop = parts[0];\n style.paddingRight = style.paddingLeft = parts[1];\n style.paddingBottom = parts[2];\n } else if (parts.length === 4) {\n style.paddingTop = parts[0];\n style.paddingRight = parts[1];\n style.paddingBottom = parts[2];\n style.paddingLeft = parts[3];\n }\n return;\n }\n\n if (key === '--vrtx-icon-button-margin' && value) {\n const parts = value.trim().split(/\\s+/);\n if (parts.length === 1) {\n style.marginTop = style.marginRight = style.marginBottom = style.marginLeft = value;\n } else if (parts.length === 2) {\n style.marginTop = style.marginBottom = parts[0];\n style.marginRight = style.marginLeft = parts[1];\n } else if (parts.length === 3) {\n style.marginTop = parts[0];\n style.marginRight = style.marginLeft = parts[1];\n style.marginBottom = parts[2];\n } else if (parts.length === 4) {\n style.marginTop = parts[0];\n style.marginRight = parts[1];\n style.marginBottom = parts[2];\n style.marginLeft = parts[3];\n }\n return;\n }\n\n // Map CSS custom properties to React Native style properties\n const propertyMap: Record<string, string> = {\n '--vrtx-icon-button-color': 'color',\n '--vrtx-icon-button-background': 'background',\n '--vrtx-icon-button-background-color': 'backgroundColor',\n '--vrtx-icon-button-border-radius': 'borderRadius',\n '--vrtx-icon-button-font-size': 'fontSize',\n '--vrtx-icon-button-font-weight': 'fontWeight',\n };\n\n const styleProperty = propertyMap[key];\n if (styleProperty) {\n style[styleProperty] = value;\n }\n });\n\n return style;\n };\n\n // Extract styles from the vrtx-contacts-import block itself (this block has the theme)\n const blockStyle = block?.style || {};\n const blockThemeStyle = themeToStyle(block?.theme);\n\n // Merge styles (theme styles take precedence over block.style)\n const mergedBlockStyle = { ...blockStyle, ...blockThemeStyle };\n\n // Extract gradient string and fallback color\n // On native, 'background' is a CSS property that doesn't work — convert solid colors to 'backgroundColor'\n const rawBlockBackground = mergedBlockStyle.background || null;\n const isBlockGradient = rawBlockBackground?.includes('gradient');\n const blockGradientString = isBlockGradient ? rawBlockBackground : null;\n const blockFallbackColor = isBlockGradient\n ? loaders?.parseGradientFirstColor(rawBlockBackground)\n : rawBlockBackground || mergedBlockStyle.backgroundColor;\n\n const blockTextColor = mergedBlockStyle.color || '#333';\n\n // Create a clean style object without background/backgroundColor (we'll handle those separately)\n const cleanBlockStyle = { ...mergedBlockStyle };\n delete cleanBlockStyle.background;\n delete cleanBlockStyle.backgroundColor;\n\n // Extract label from block attributes\n const label = block?.attributes?.label;\n\n return (\n <View key={block.id} style={styles.contactButtonsContainer}>\n {/* Section label from block attributes */}\n {label && (\n <Text style={styles.sectionLabel}>{label}</Text>\n )}\n {isNativeContactsEnabled() && (\n <ButtonWrapper\n style={[\n styles.button,\n styles.fullButton,\n styles.tertiaryButton,\n cleanBlockStyle,\n blockFallbackColor ? { backgroundColor: blockFallbackColor } : undefined,\n ]}\n gradientString={blockGradientString}\n onPress={handleSelectFromContactsWithHaptics}\n >\n <View style={styles.buttonIconContainer}>\n {renderIcon({ name: 'import-contacts', size: 18, color: blockTextColor })}\n </View>\n <Text style={[styles.tertiaryButtonText, { color: blockTextColor }]}>\n {getCustomLabel('importContacts', 'Add from Contacts')}\n </Text>\n </ButtonWrapper>\n )}\n\n {isGoogleContactsEnabled() && (\n <ButtonWrapper\n style={[\n styles.button,\n styles.fullButton,\n styles.tertiaryButton,\n cleanBlockStyle,\n blockFallbackColor ? { backgroundColor: blockFallbackColor } : undefined,\n ]}\n gradientString={blockGradientString}\n onPress={handleSelectFromGoogleWithHaptics}\n >\n <View style={styles.buttonIconContainer}>\n {renderIcon({ name: 'google', size: 18, color: blockTextColor })}\n </View>\n <Text style={[styles.tertiaryButtonText, { color: blockTextColor }]}>\n {getCustomLabel('google', 'Add from Google Contacts')}\n </Text>\n </ButtonWrapper>\n )}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n contactButtonsContainer: {\n gap: 12,\n },\n sectionLabel: {\n fontSize: 14,\n fontWeight: '500',\n color: '#666',\n marginBottom: 4,\n },\n button: {\n paddingVertical: 12,\n paddingHorizontal: 16,\n borderRadius: 8,\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 8,\n },\n tertiaryButton: {\n backgroundColor: '#f5f5f5',\n },\n fullButton: {\n width: '100%',\n },\n buttonIconContainer: {\n width: 18,\n height: 18,\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'visible',\n },\n tertiaryButtonText: {\n color: '#333',\n fontSize: 16,\n fontWeight: '500',\n },\n});\n"]}