@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.
- package/dist/InviteFormCore-D4HkMMo0.d.mts +721 -0
- package/dist/InviteFormCore-D9oUCbu7.d.ts +721 -0
- package/dist/VortexClient.js +192 -0
- package/dist/VortexClient.js.map +1 -0
- package/dist/VortexDeferredLinks.js +127 -0
- package/dist/VortexDeferredLinks.js.map +1 -0
- package/dist/clientInfo.js +45 -0
- package/dist/clientInfo.js.map +1 -0
- package/dist/components/ContactsPickerModal.js +182 -0
- package/dist/components/ContactsPickerModal.js.map +1 -0
- package/dist/components/InviteFormCore.js +2141 -0
- package/dist/components/InviteFormCore.js.map +1 -0
- package/dist/components/InviteFormMobile.js +463 -0
- package/dist/components/InviteFormMobile.js.map +1 -0
- package/dist/components/InviteFormWeb.js +295 -0
- package/dist/components/InviteFormWeb.js.map +1 -0
- package/dist/components/PlacedItemToolbar.js +147 -0
- package/dist/components/PlacedItemToolbar.js.map +1 -0
- package/dist/components/ShareButtons.js +181 -0
- package/dist/components/ShareButtons.js.map +1 -0
- package/dist/components/VrtxContactsImport.js +234 -0
- package/dist/components/VrtxContactsImport.js.map +1 -0
- package/dist/components/VrtxEmailInvitations.js +341 -0
- package/dist/components/VrtxEmailInvitations.js.map +1 -0
- package/dist/components/VrtxFindFriends.js +400 -0
- package/dist/components/VrtxFindFriends.js.map +1 -0
- package/dist/components/VrtxHeading.js +58 -0
- package/dist/components/VrtxHeading.js.map +1 -0
- package/dist/components/VrtxIncomingInvitations.js +657 -0
- package/dist/components/VrtxIncomingInvitations.js.map +1 -0
- package/dist/components/VrtxInvitationSuggestions.js +506 -0
- package/dist/components/VrtxInvitationSuggestions.js.map +1 -0
- package/dist/components/VrtxInviteContacts.js +512 -0
- package/dist/components/VrtxInviteContacts.js.map +1 -0
- package/dist/components/VrtxOutgoingInvitations.js +572 -0
- package/dist/components/VrtxOutgoingInvitations.js.map +1 -0
- package/dist/components/VrtxSearchBox.js +487 -0
- package/dist/components/VrtxSearchBox.js.map +1 -0
- package/dist/components/VrtxSelect.js +27 -0
- package/dist/components/VrtxSelect.js.map +1 -0
- package/dist/components/VrtxShareOptions.js +435 -0
- package/dist/components/VrtxShareOptions.js.map +1 -0
- package/dist/components/VrtxSubmit.js +132 -0
- package/dist/components/VrtxSubmit.js.map +1 -0
- package/dist/components/VrtxText.js +146 -0
- package/dist/components/VrtxText.js.map +1 -0
- package/dist/constants/mockData.d.mts +7 -0
- package/dist/constants/mockData.d.ts +7 -0
- package/dist/constants/mockData.js +48 -0
- package/dist/constants/mockData.js.map +1 -0
- package/dist/constants/mockData.mjs +22 -0
- package/dist/constants/mockData.mjs.map +1 -0
- package/dist/context/VortexModulesContext.js +135 -0
- package/dist/context/VortexModulesContext.js.map +1 -0
- package/dist/hooks/useInvitationFormLogic.d.mts +2 -0
- package/dist/hooks/useInvitationFormLogic.d.ts +2 -0
- package/dist/hooks/useInvitationFormLogic.js +300 -0
- package/dist/hooks/useInvitationFormLogic.js.map +1 -0
- package/dist/hooks/useInvitationFormLogic.mjs +276 -0
- package/dist/hooks/useInvitationFormLogic.mjs.map +1 -0
- package/dist/hooks/usePrefetchWidgetConfiguration.js +117 -0
- package/dist/hooks/usePrefetchWidgetConfiguration.js.map +1 -0
- package/dist/hooks/useThemeStyles.js +41 -0
- package/dist/hooks/useThemeStyles.js.map +1 -0
- package/dist/hooks/useVortexInvite.js +732 -0
- package/dist/hooks/useVortexInvite.js.map +1 -0
- package/dist/index-web.d.mts +93 -0
- package/dist/index-web.d.ts +93 -0
- package/dist/index-web.js +7397 -0
- package/dist/index-web.js.map +1 -0
- package/dist/index-web.mjs +7445 -0
- package/dist/index-web.mjs.map +1 -0
- package/dist/index.d.mts +656 -0
- package/dist/index.d.ts +656 -0
- package/dist/index.js +10206 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +10244 -0
- package/dist/index.mjs.map +1 -0
- package/dist/types/VortexClient.d.ts +106 -0
- package/dist/types/VortexClient.d.ts.map +1 -0
- package/dist/types/VortexDeferredLinks.d.ts +73 -0
- package/dist/types/VortexDeferredLinks.d.ts.map +1 -0
- package/dist/types/clientInfo.d.ts +5 -0
- package/dist/types/clientInfo.d.ts.map +1 -0
- package/dist/types/components/ContactsPickerModal.d.ts +18 -0
- package/dist/types/components/ContactsPickerModal.d.ts.map +1 -0
- package/dist/types/components/InviteFormCore.d.ts +166 -0
- package/dist/types/components/InviteFormCore.d.ts.map +1 -0
- package/dist/types/components/InviteFormMobile.d.ts +42 -0
- package/dist/types/components/InviteFormMobile.d.ts.map +1 -0
- package/dist/types/components/InviteFormWeb.d.ts +87 -0
- package/dist/types/components/InviteFormWeb.d.ts.map +1 -0
- package/dist/types/components/PlacedItemToolbar.d.ts +16 -0
- package/dist/types/components/PlacedItemToolbar.d.ts.map +1 -0
- package/dist/types/components/ShareButtons.d.ts +29 -0
- package/dist/types/components/ShareButtons.d.ts.map +1 -0
- package/dist/types/components/VrtxContactsImport.d.ts +14 -0
- package/dist/types/components/VrtxContactsImport.d.ts.map +1 -0
- package/dist/types/components/VrtxEmailInvitations.d.ts +31 -0
- package/dist/types/components/VrtxEmailInvitations.d.ts.map +1 -0
- package/dist/types/components/VrtxFindFriends.d.ts +25 -0
- package/dist/types/components/VrtxFindFriends.d.ts.map +1 -0
- package/dist/types/components/VrtxHeading.d.ts +6 -0
- package/dist/types/components/VrtxHeading.d.ts.map +1 -0
- package/dist/types/components/VrtxIncomingInvitations.d.ts +27 -0
- package/dist/types/components/VrtxIncomingInvitations.d.ts.map +1 -0
- package/dist/types/components/VrtxInvitationSuggestions.d.ts +25 -0
- package/dist/types/components/VrtxInvitationSuggestions.d.ts.map +1 -0
- package/dist/types/components/VrtxInviteContacts.d.ts +24 -0
- package/dist/types/components/VrtxInviteContacts.d.ts.map +1 -0
- package/dist/types/components/VrtxOutgoingInvitations.d.ts +27 -0
- package/dist/types/components/VrtxOutgoingInvitations.d.ts.map +1 -0
- package/dist/types/components/VrtxSearchBox.d.ts +28 -0
- package/dist/types/components/VrtxSearchBox.d.ts.map +1 -0
- package/dist/types/components/VrtxSelect.d.ts +6 -0
- package/dist/types/components/VrtxSelect.d.ts.map +1 -0
- package/dist/types/components/VrtxShareOptions.d.ts +41 -0
- package/dist/types/components/VrtxShareOptions.d.ts.map +1 -0
- package/dist/types/components/VrtxSubmit.d.ts +18 -0
- package/dist/types/components/VrtxSubmit.d.ts.map +1 -0
- package/dist/types/components/VrtxText.d.ts +8 -0
- package/dist/types/components/VrtxText.d.ts.map +1 -0
- package/dist/types/constants/mockData.d.ts +4 -0
- package/dist/types/constants/mockData.d.ts.map +1 -0
- package/dist/types/context/VortexModulesContext.d.ts +238 -0
- package/dist/types/context/VortexModulesContext.d.ts.map +1 -0
- package/dist/types/findFriends.js +10 -0
- package/dist/types/findFriends.js.map +1 -0
- package/dist/types/hooks/useInvitationFormLogic.d.ts +55 -0
- package/dist/types/hooks/useInvitationFormLogic.d.ts.map +1 -0
- package/dist/types/hooks/usePrefetchWidgetConfiguration.d.ts +39 -0
- package/dist/types/hooks/usePrefetchWidgetConfiguration.d.ts.map +1 -0
- package/dist/types/hooks/useThemeStyles.d.ts +35 -0
- package/dist/types/hooks/useThemeStyles.d.ts.map +1 -0
- package/dist/types/hooks/useVortexInvite.d.ts +86 -0
- package/dist/types/hooks/useVortexInvite.d.ts.map +1 -0
- package/dist/types/index-web.d.ts +23 -0
- package/dist/types/index-web.d.ts.map +1 -0
- package/dist/types/index.d.ts +23 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/invitations.js +13 -0
- package/dist/types/invitations.js.map +1 -0
- package/dist/types/inviteContacts.js +14 -0
- package/dist/types/inviteContacts.js.map +1 -0
- package/dist/types/platformOperations.js +3 -0
- package/dist/types/platformOperations.js.map +1 -0
- package/dist/types/searchBox.js +11 -0
- package/dist/types/searchBox.js.map +1 -0
- package/dist/types/types/findFriends.d.ts +101 -0
- package/dist/types/types/findFriends.d.ts.map +1 -0
- package/dist/types/types/invitations.d.ts +301 -0
- package/dist/types/types/invitations.d.ts.map +1 -0
- package/dist/types/types/inviteContacts.d.ts +86 -0
- package/dist/types/types/inviteContacts.d.ts.map +1 -0
- package/dist/types/types/platformOperations.d.ts +185 -0
- package/dist/types/types/platformOperations.d.ts.map +1 -0
- package/dist/types/types/searchBox.d.ts +69 -0
- package/dist/types/types/searchBox.d.ts.map +1 -0
- package/dist/types/types/unfurlConfig.d.ts +34 -0
- package/dist/types/types/unfurlConfig.d.ts.map +1 -0
- package/dist/types/unfurlConfig.js +21 -0
- package/dist/types/unfurlConfig.js.map +1 -0
- package/dist/types/utils/analytics.d.ts +54 -0
- package/dist/types/utils/analytics.d.ts.map +1 -0
- package/dist/types/utils/configCache.d.ts +34 -0
- package/dist/types/utils/configCache.d.ts.map +1 -0
- package/dist/types/utils/contactUtils.d.ts +9 -0
- package/dist/types/utils/contactUtils.d.ts.map +1 -0
- package/dist/types/utils/featureWarnings.d.ts +56 -0
- package/dist/types/utils/featureWarnings.d.ts.map +1 -0
- package/dist/types/utils/formUtils.d.ts +93 -0
- package/dist/types/utils/formUtils.d.ts.map +1 -0
- package/dist/types/utils/gradientUtils.d.ts +67 -0
- package/dist/types/utils/gradientUtils.d.ts.map +1 -0
- package/dist/types/utils/invitationEvents.d.ts +21 -0
- package/dist/types/utils/invitationEvents.d.ts.map +1 -0
- package/dist/types/utils/moduleLoaders.d.ts +115 -0
- package/dist/types/utils/moduleLoaders.d.ts.map +1 -0
- package/dist/types/utils/moduleLoaders.web.d.ts +73 -0
- package/dist/types/utils/moduleLoaders.web.d.ts.map +1 -0
- package/dist/types/utils/nameUtils.d.ts +15 -0
- package/dist/types/utils/nameUtils.d.ts.map +1 -0
- package/dist/types/utils/themeUtils.d.ts +38 -0
- package/dist/types/utils/themeUtils.d.ts.map +1 -0
- package/dist/types/vortexInvite.d.ts +165 -0
- package/dist/types/vortexInvite.d.ts.map +1 -0
- package/dist/useInvitationFormLogic-Ct73M19B.d.mts +242 -0
- package/dist/useInvitationFormLogic-Ct73M19B.d.ts +242 -0
- package/dist/utils/analytics.js +92 -0
- package/dist/utils/analytics.js.map +1 -0
- package/dist/utils/configCache.js +68 -0
- package/dist/utils/configCache.js.map +1 -0
- package/dist/utils/contactUtils.d.mts +12 -0
- package/dist/utils/contactUtils.d.ts +12 -0
- package/dist/utils/contactUtils.js +37 -0
- package/dist/utils/contactUtils.js.map +1 -0
- package/dist/utils/contactUtils.mjs +12 -0
- package/dist/utils/contactUtils.mjs.map +1 -0
- package/dist/utils/featureWarnings.js +214 -0
- package/dist/utils/featureWarnings.js.map +1 -0
- package/dist/utils/formUtils.js +284 -0
- package/dist/utils/formUtils.js.map +1 -0
- package/dist/utils/gradientUtils.js +120 -0
- package/dist/utils/gradientUtils.js.map +1 -0
- package/dist/utils/invitationEvents.js +45 -0
- package/dist/utils/invitationEvents.js.map +1 -0
- package/dist/utils/moduleLoaders.js +275 -0
- package/dist/utils/moduleLoaders.js.map +1 -0
- package/dist/utils/moduleLoaders.web.js +72 -0
- package/dist/utils/moduleLoaders.web.js.map +1 -0
- package/dist/utils/nameUtils.js +51 -0
- package/dist/utils/nameUtils.js.map +1 -0
- package/dist/utils/themeUtils.js +141 -0
- package/dist/utils/themeUtils.js.map +1 -0
- package/dist/vortexInvite.js +83 -0
- package/dist/vortexInvite.js.map +1 -0
- package/package.json +21 -56
|
@@ -0,0 +1,132 @@
|
|
|
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.VrtxSubmit = VrtxSubmit;
|
|
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 VrtxSubmit({ block, view, handleSendInvitation, triggerHaptic, loadingEmailInvite, sendSuccess, emailCount = 0, emailBlockCustomizations, emailBlockStyle, }) {
|
|
51
|
+
var _a;
|
|
52
|
+
// Get loaders from context
|
|
53
|
+
const { loaders } = (0, VortexModulesContext_1.useVortexModules)();
|
|
54
|
+
if (view !== 'email')
|
|
55
|
+
return null;
|
|
56
|
+
const handleSendInvitationWithHaptics = () => __awaiter(this, void 0, void 0, function* () {
|
|
57
|
+
yield (triggerHaptic === null || triggerHaptic === void 0 ? void 0 : triggerHaptic('light'));
|
|
58
|
+
yield handleSendInvitation();
|
|
59
|
+
});
|
|
60
|
+
// Use email block style to match the "Add by Email" button appearance
|
|
61
|
+
// Fall back to submit block's own style if no email block style provided
|
|
62
|
+
const effectiveStyle = emailBlockStyle && Object.keys(emailBlockStyle).length > 0
|
|
63
|
+
? emailBlockStyle
|
|
64
|
+
: ((block === null || block === void 0 ? void 0 : block.style) || {});
|
|
65
|
+
// Extract gradient string and fallback color
|
|
66
|
+
// On native, 'background' is a CSS property that doesn't work — convert solid colors to 'backgroundColor'
|
|
67
|
+
const rawBackground = effectiveStyle.background || null;
|
|
68
|
+
const isGradient = rawBackground === null || rawBackground === void 0 ? void 0 : rawBackground.includes('gradient');
|
|
69
|
+
const gradientString = isGradient ? rawBackground : null;
|
|
70
|
+
const fallbackColor = isGradient
|
|
71
|
+
? loaders === null || loaders === void 0 ? void 0 : loaders.parseGradientFirstColor(rawBackground)
|
|
72
|
+
: rawBackground || effectiveStyle.backgroundColor;
|
|
73
|
+
// Extract text color — for email block style, default to dark text like "Add by Email" button
|
|
74
|
+
const textColor = effectiveStyle.color || (emailBlockStyle ? '#333' : '#fff');
|
|
75
|
+
return (<react_native_1.View key={block.id}>
|
|
76
|
+
{sendSuccess ? (<react_native_1.View style={styles.successMessageContainer}>
|
|
77
|
+
<react_native_1.Text style={styles.invitedText}>✓ {((_a = emailBlockCustomizations === null || emailBlockCustomizations === void 0 ? void 0 : emailBlockCustomizations['mobile.successMessage']) === null || _a === void 0 ? void 0 : _a.textContent) || 'Invitation sent successfully!'}</react_native_1.Text>
|
|
78
|
+
</react_native_1.View>) : (<ButtonWrapper style={[
|
|
79
|
+
styles.button,
|
|
80
|
+
styles.fullButton,
|
|
81
|
+
{
|
|
82
|
+
borderWidth: 1,
|
|
83
|
+
borderColor: '#e0e0e0',
|
|
84
|
+
},
|
|
85
|
+
effectiveStyle,
|
|
86
|
+
fallbackColor ? { backgroundColor: fallbackColor } : undefined,
|
|
87
|
+
]} gradientString={gradientString} onPress={handleSendInvitationWithHaptics} disabled={loadingEmailInvite}>
|
|
88
|
+
{loadingEmailInvite ? (<react_native_1.ActivityIndicator size="small" color={textColor}/>) : (<react_native_1.Text style={[styles.buttonText, { color: textColor }]}>
|
|
89
|
+
{(() => {
|
|
90
|
+
var _a, _b;
|
|
91
|
+
// Mobile-specific labels from vrtx-email-invitations block customizations
|
|
92
|
+
// Defaults match elementRegistry: 'Send Invitation' / 'Send Invitations'
|
|
93
|
+
const singularLabel = ((_a = emailBlockCustomizations === null || emailBlockCustomizations === void 0 ? void 0 : emailBlockCustomizations['mobile.sendButton']) === null || _a === void 0 ? void 0 : _a.textContent) || 'Send Invitation';
|
|
94
|
+
const pluralLabel = ((_b = emailBlockCustomizations === null || emailBlockCustomizations === void 0 ? void 0 : emailBlockCustomizations['mobile.sendButtonPlural']) === null || _b === void 0 ? void 0 : _b.textContent) || 'Send Invitations';
|
|
95
|
+
return emailCount > 1 ? pluralLabel : singularLabel;
|
|
96
|
+
})()}
|
|
97
|
+
</react_native_1.Text>)}
|
|
98
|
+
</ButtonWrapper>)}
|
|
99
|
+
</react_native_1.View>);
|
|
100
|
+
}
|
|
101
|
+
const styles = react_native_1.StyleSheet.create({
|
|
102
|
+
successMessageContainer: {
|
|
103
|
+
padding: 16,
|
|
104
|
+
backgroundColor: '#e8f5e9',
|
|
105
|
+
borderRadius: 8,
|
|
106
|
+
alignItems: 'center',
|
|
107
|
+
},
|
|
108
|
+
invitedText: {
|
|
109
|
+
color: '#2e7d32',
|
|
110
|
+
fontSize: 16,
|
|
111
|
+
fontWeight: '600',
|
|
112
|
+
},
|
|
113
|
+
button: {
|
|
114
|
+
paddingVertical: 12,
|
|
115
|
+
paddingHorizontal: 16,
|
|
116
|
+
borderRadius: 8,
|
|
117
|
+
flexDirection: 'row',
|
|
118
|
+
alignItems: 'center',
|
|
119
|
+
justifyContent: 'center',
|
|
120
|
+
gap: 8,
|
|
121
|
+
backgroundColor: '#f5f5f5',
|
|
122
|
+
},
|
|
123
|
+
fullButton: {
|
|
124
|
+
width: '100%',
|
|
125
|
+
},
|
|
126
|
+
buttonText: {
|
|
127
|
+
color: '#333',
|
|
128
|
+
fontSize: 16,
|
|
129
|
+
fontWeight: '500',
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
//# sourceMappingURL=VrtxSubmit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VrtxSubmit.js","sourceRoot":"","sources":["../../src/components/VrtxSubmit.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\nimport { View, Text, TouchableOpacity, ActivityIndicator, StyleSheet, ViewStyle, Platform } from 'react-native';\nimport type { ViewType } from '../hooks/useInvitationFormLogic';\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 VrtxSubmitProps {\n block: any;\n view: ViewType;\n handleSendInvitation: () => Promise<void>;\n triggerHaptic?: (style: 'light' | 'medium' | 'heavy') => Promise<void>;\n loadingEmailInvite: boolean;\n sendSuccess: boolean;\n /** Number of emails currently in the pill list (for singular/plural button label) */\n emailCount?: number;\n /** Mobile-specific customizations from the vrtx-email-invitations block */\n emailBlockCustomizations?: Record<string, any>;\n /** Style from the email invitations block (to match \"Add by Email\" button appearance) */\n emailBlockStyle?: Record<string, any>;\n}\n\nexport function VrtxSubmit({\n block,\n view,\n handleSendInvitation,\n triggerHaptic,\n loadingEmailInvite,\n sendSuccess,\n emailCount = 0,\n emailBlockCustomizations,\n emailBlockStyle,\n}: VrtxSubmitProps) {\n // Get loaders from context\n const { loaders } = useVortexModules();\n\n if (view !== 'email') return null;\n\n const handleSendInvitationWithHaptics = async () => {\n await triggerHaptic?.('light');\n await handleSendInvitation();\n };\n\n // Use email block style to match the \"Add by Email\" button appearance\n // Fall back to submit block's own style if no email block style provided\n const effectiveStyle = emailBlockStyle && Object.keys(emailBlockStyle).length > 0\n ? emailBlockStyle\n : (block?.style || {});\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 rawBackground = effectiveStyle.background || null;\n const isGradient = rawBackground?.includes('gradient');\n const gradientString = isGradient ? rawBackground : null;\n const fallbackColor = isGradient\n ? loaders?.parseGradientFirstColor(rawBackground)\n : rawBackground || effectiveStyle.backgroundColor;\n\n // Extract text color — for email block style, default to dark text like \"Add by Email\" button\n const textColor = effectiveStyle.color || (emailBlockStyle ? '#333' : '#fff');\n\n return (\n <View key={block.id}>\n {sendSuccess ? (\n <View style={styles.successMessageContainer}>\n <Text style={styles.invitedText}>✓ {emailBlockCustomizations?.['mobile.successMessage']?.textContent || 'Invitation sent successfully!'}</Text>\n </View>\n ) : (\n <ButtonWrapper\n style={[\n styles.button,\n styles.fullButton,\n {\n borderWidth: 1,\n borderColor: '#e0e0e0',\n },\n effectiveStyle,\n fallbackColor ? { backgroundColor: fallbackColor } : undefined,\n ]}\n gradientString={gradientString}\n onPress={handleSendInvitationWithHaptics}\n disabled={loadingEmailInvite}\n >\n {loadingEmailInvite ? (\n <ActivityIndicator size=\"small\" color={textColor} />\n ) : (\n <Text style={[styles.buttonText, { color: textColor }]}>\n {(() => {\n // Mobile-specific labels from vrtx-email-invitations block customizations\n // Defaults match elementRegistry: 'Send Invitation' / 'Send Invitations'\n const singularLabel =\n emailBlockCustomizations?.['mobile.sendButton']?.textContent || 'Send Invitation';\n const pluralLabel =\n emailBlockCustomizations?.['mobile.sendButtonPlural']?.textContent || 'Send Invitations';\n return emailCount > 1 ? pluralLabel : singularLabel;\n })()}\n </Text>\n )}\n </ButtonWrapper>\n )}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n successMessageContainer: {\n padding: 16,\n backgroundColor: '#e8f5e9',\n borderRadius: 8,\n alignItems: 'center',\n },\n invitedText: {\n color: '#2e7d32',\n fontSize: 16,\n fontWeight: '600',\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 backgroundColor: '#f5f5f5',\n },\n fullButton: {\n width: '100%',\n },\n buttonText: {\n color: '#333',\n fontSize: 16,\n fontWeight: '500',\n },\n});\n"]}
|
|
@@ -0,0 +1,146 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.VrtxText = void 0;
|
|
37
|
+
const react_1 = __importStar(require("react"));
|
|
38
|
+
const react_native_1 = require("react-native");
|
|
39
|
+
const isWeb = react_native_1.Platform.OS === 'web';
|
|
40
|
+
const VrtxTextComponent = ({ block, isEditMode = false, onUpdate }) => {
|
|
41
|
+
// Strip HTML tags to get plain text
|
|
42
|
+
const stripHtml = (html) => {
|
|
43
|
+
if (!html)
|
|
44
|
+
return '';
|
|
45
|
+
const tmp = document.createElement('div');
|
|
46
|
+
tmp.innerHTML = html;
|
|
47
|
+
return tmp.textContent || tmp.innerText || '';
|
|
48
|
+
};
|
|
49
|
+
// Process styles for text gradients
|
|
50
|
+
const processTextGradient = (style) => {
|
|
51
|
+
if (!style)
|
|
52
|
+
return style;
|
|
53
|
+
const processedStyle = Object.assign({}, style);
|
|
54
|
+
const colorValue = processedStyle.color;
|
|
55
|
+
// Handle text gradients on web
|
|
56
|
+
if (isWeb && colorValue && typeof colorValue === 'string' && colorValue.includes('linear-gradient')) {
|
|
57
|
+
// Use backgroundImage instead of background to avoid resetting backgroundClip
|
|
58
|
+
processedStyle.backgroundImage = colorValue;
|
|
59
|
+
processedStyle.backgroundColor = 'transparent'; // Ensure solid background doesn't interfere
|
|
60
|
+
processedStyle.WebkitBackgroundClip = 'text';
|
|
61
|
+
processedStyle.backgroundClip = 'text';
|
|
62
|
+
processedStyle.WebkitTextFillColor = 'transparent';
|
|
63
|
+
processedStyle.color = 'transparent'; // Fallback
|
|
64
|
+
// Always set display to inline-block for gradients to render properly
|
|
65
|
+
processedStyle.display = 'inline-block';
|
|
66
|
+
}
|
|
67
|
+
return processedStyle;
|
|
68
|
+
};
|
|
69
|
+
const textContent = isWeb ? stripHtml(block.textContent || '') : block.textContent || '';
|
|
70
|
+
const divRef = (0, react_1.useRef)(null);
|
|
71
|
+
const blockIdRef = (0, react_1.useRef)(block.id);
|
|
72
|
+
const updateTimeoutRef = (0, react_1.useRef)(null);
|
|
73
|
+
const onUpdateRef = (0, react_1.useRef)(onUpdate);
|
|
74
|
+
const initializedRef = (0, react_1.useRef)(false);
|
|
75
|
+
// Keep onUpdateRef in sync with latest onUpdate
|
|
76
|
+
(0, react_1.useEffect)(() => {
|
|
77
|
+
onUpdateRef.current = onUpdate;
|
|
78
|
+
}, [onUpdate]);
|
|
79
|
+
// Initialize content ONCE using ref callback instead of useEffect
|
|
80
|
+
const refCallback = (0, react_1.useCallback)((element) => {
|
|
81
|
+
if (!element || !isWeb || !isEditMode)
|
|
82
|
+
return;
|
|
83
|
+
// Store ref
|
|
84
|
+
divRef.current = element;
|
|
85
|
+
// Only initialize once or when block ID changes
|
|
86
|
+
if (!initializedRef.current || blockIdRef.current !== block.id) {
|
|
87
|
+
console.log('🆕 Initializing contentEditable with:', block.textContent);
|
|
88
|
+
element.innerHTML = block.textContent || '';
|
|
89
|
+
blockIdRef.current = block.id;
|
|
90
|
+
initializedRef.current = true;
|
|
91
|
+
}
|
|
92
|
+
}, [block.id, block.textContent, isWeb, isEditMode]);
|
|
93
|
+
// Cleanup timeout on unmount
|
|
94
|
+
(0, react_1.useEffect)(() => {
|
|
95
|
+
return () => {
|
|
96
|
+
if (updateTimeoutRef.current) {
|
|
97
|
+
clearTimeout(updateTimeoutRef.current);
|
|
98
|
+
updateTimeoutRef.current = null;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}, []);
|
|
102
|
+
// On web + edit mode, use contentEditable div
|
|
103
|
+
if (isWeb && isEditMode) {
|
|
104
|
+
return (<react_native_1.View>
|
|
105
|
+
<div key={`editable-${block.id}`} ref={refCallback} contentEditable suppressContentEditableWarning data-block-id={block.id} data-text-editable="true" onInput={(e) => {
|
|
106
|
+
// Debounced auto-save on input
|
|
107
|
+
if (updateTimeoutRef.current) {
|
|
108
|
+
clearTimeout(updateTimeoutRef.current);
|
|
109
|
+
}
|
|
110
|
+
const newHtml = e.currentTarget.innerHTML || '';
|
|
111
|
+
console.log('⌨️ Input changed:', newHtml);
|
|
112
|
+
// Save after 1 second of no typing
|
|
113
|
+
updateTimeoutRef.current = setTimeout(() => {
|
|
114
|
+
var _a;
|
|
115
|
+
console.log('💾 Auto-saving:', newHtml);
|
|
116
|
+
(_a = onUpdateRef.current) === null || _a === void 0 ? void 0 : _a.call(onUpdateRef, block.id, {
|
|
117
|
+
textContent: newHtml,
|
|
118
|
+
});
|
|
119
|
+
}, 1000);
|
|
120
|
+
}} style={Object.assign({ outline: 'none', cursor: 'text', minHeight: '1em', whiteSpace: 'pre-wrap' }, processTextGradient(block.style))}/>
|
|
121
|
+
</react_native_1.View>);
|
|
122
|
+
}
|
|
123
|
+
// Native rendering or web non-edit mode
|
|
124
|
+
return (<react_native_1.View>
|
|
125
|
+
<react_native_1.Text style={[styles.text, block.style ? processTextGradient(block.style) : {}]}>{textContent}</react_native_1.Text>
|
|
126
|
+
</react_native_1.View>);
|
|
127
|
+
};
|
|
128
|
+
// Memo with custom comparison to prevent re-renders when block reference changes but content is the same
|
|
129
|
+
exports.VrtxText = react_1.default.memo(VrtxTextComponent, (prevProps, nextProps) => {
|
|
130
|
+
const sameBlock = prevProps.block.id === nextProps.block.id;
|
|
131
|
+
const sameEditMode = prevProps.isEditMode === nextProps.isEditMode;
|
|
132
|
+
const sameOnUpdate = prevProps.onUpdate === nextProps.onUpdate;
|
|
133
|
+
// In edit mode, IGNORE textContent changes in block prop
|
|
134
|
+
// The DOM contentEditable is the source of truth, not the Redux state
|
|
135
|
+
// We only care if the block ID changes (switching to a different block)
|
|
136
|
+
const shouldNotRerender = sameBlock && sameEditMode && sameOnUpdate;
|
|
137
|
+
return shouldNotRerender;
|
|
138
|
+
});
|
|
139
|
+
const styles = react_native_1.StyleSheet.create({
|
|
140
|
+
text: {
|
|
141
|
+
fontSize: 14,
|
|
142
|
+
lineHeight: 20,
|
|
143
|
+
color: '#000',
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
//# sourceMappingURL=VrtxText.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VrtxText.js","sourceRoot":"","sources":["../../src/components/VrtxText.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useRef, useEffect, useCallback } from 'react';\nimport { View, Text, StyleSheet, Platform } from 'react-native';\n\nconst isWeb = Platform.OS === 'web';\n\nexport interface VrtxTextProps {\n block: any;\n isEditMode?: boolean;\n onUpdate?: (blockId: string, updates: any) => void;\n}\n\nconst VrtxTextComponent = ({ block, isEditMode = false, onUpdate }: VrtxTextProps) => {\n // Strip HTML tags to get plain text\n const stripHtml = (html: string) => {\n if (!html) return '';\n const tmp = document.createElement('div');\n tmp.innerHTML = html;\n return tmp.textContent || tmp.innerText || '';\n };\n\n // Process styles for text gradients\n const processTextGradient = (style: any) => {\n if (!style) return style;\n\n const processedStyle = { ...style };\n const colorValue = processedStyle.color as string | undefined;\n\n // Handle text gradients on web\n if (isWeb && colorValue && typeof colorValue === 'string' && colorValue.includes('linear-gradient')) {\n // Use backgroundImage instead of background to avoid resetting backgroundClip\n processedStyle.backgroundImage = colorValue;\n processedStyle.backgroundColor = 'transparent'; // Ensure solid background doesn't interfere\n processedStyle.WebkitBackgroundClip = 'text';\n processedStyle.backgroundClip = 'text';\n processedStyle.WebkitTextFillColor = 'transparent';\n processedStyle.color = 'transparent'; // Fallback\n // Always set display to inline-block for gradients to render properly\n processedStyle.display = 'inline-block';\n }\n\n return processedStyle;\n };\n\n const textContent = isWeb ? stripHtml(block.textContent || '') : block.textContent || '';\n const divRef = useRef<HTMLDivElement | null>(null);\n const blockIdRef = useRef<string>(block.id);\n const updateTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const onUpdateRef = useRef(onUpdate);\n const initializedRef = useRef(false);\n\n // Keep onUpdateRef in sync with latest onUpdate\n useEffect(() => {\n onUpdateRef.current = onUpdate;\n }, [onUpdate]);\n\n // Initialize content ONCE using ref callback instead of useEffect\n const refCallback = useCallback(\n (element: HTMLDivElement | null) => {\n if (!element || !isWeb || !isEditMode) return;\n\n // Store ref\n divRef.current = element;\n\n // Only initialize once or when block ID changes\n if (!initializedRef.current || blockIdRef.current !== block.id) {\n console.log('🆕 Initializing contentEditable with:', block.textContent);\n element.innerHTML = block.textContent || '';\n blockIdRef.current = block.id;\n initializedRef.current = true;\n }\n },\n [block.id, block.textContent, isWeb, isEditMode]\n );\n\n // Cleanup timeout on unmount\n useEffect(() => {\n return () => {\n if (updateTimeoutRef.current) {\n clearTimeout(updateTimeoutRef.current);\n updateTimeoutRef.current = null;\n }\n };\n }, []);\n\n // On web + edit mode, use contentEditable div\n if (isWeb && isEditMode) {\n return (\n <View>\n <div\n key={`editable-${block.id}`}\n ref={refCallback}\n contentEditable\n suppressContentEditableWarning\n data-block-id={block.id}\n data-text-editable=\"true\"\n onInput={(e: any) => {\n // Debounced auto-save on input\n if (updateTimeoutRef.current) {\n clearTimeout(updateTimeoutRef.current);\n }\n\n const newHtml = e.currentTarget.innerHTML || '';\n console.log('⌨️ Input changed:', newHtml);\n\n // Save after 1 second of no typing\n updateTimeoutRef.current = setTimeout(() => {\n console.log('💾 Auto-saving:', newHtml);\n onUpdateRef.current?.(block.id, {\n textContent: newHtml,\n });\n }, 1000);\n }}\n style={{\n outline: 'none',\n cursor: 'text',\n minHeight: '1em',\n whiteSpace: 'pre-wrap',\n ...processTextGradient(block.style),\n }}\n />\n </View>\n );\n }\n\n // Native rendering or web non-edit mode\n return (\n <View>\n <Text style={[styles.text, block.style ? processTextGradient(block.style) : {}]}>{textContent}</Text>\n </View>\n );\n};\n\n// Memo with custom comparison to prevent re-renders when block reference changes but content is the same\nexport const VrtxText = React.memo(VrtxTextComponent, (prevProps, nextProps) => {\n const sameBlock = prevProps.block.id === nextProps.block.id;\n const sameEditMode = prevProps.isEditMode === nextProps.isEditMode;\n const sameOnUpdate = prevProps.onUpdate === nextProps.onUpdate;\n\n // In edit mode, IGNORE textContent changes in block prop\n // The DOM contentEditable is the source of truth, not the Redux state\n // We only care if the block ID changes (switching to a different block)\n const shouldNotRerender = sameBlock && sameEditMode && sameOnUpdate;\n\n return shouldNotRerender;\n});\n\nconst styles = StyleSheet.create({\n text: {\n fontSize: 14,\n lineHeight: 20,\n color: '#000',\n },\n});\n"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/constants/mockData.ts
|
|
21
|
+
var mockData_exports = {};
|
|
22
|
+
__export(mockData_exports, {
|
|
23
|
+
MOCK_CONTACTS: () => MOCK_CONTACTS,
|
|
24
|
+
MOCK_GOOGLE_CONTACTS: () => MOCK_GOOGLE_CONTACTS
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(mockData_exports);
|
|
27
|
+
var MOCK_CONTACTS = [
|
|
28
|
+
{ id: "1", name: "Alice Johnson", email: "alice.johnson@example.com" },
|
|
29
|
+
{ id: "2", name: "Bob Smith", email: "bob.smith@example.com" },
|
|
30
|
+
{ id: "3", name: "Charlie Brown", email: "charlie.brown@example.com" },
|
|
31
|
+
{ id: "4", name: "Diana Prince", email: "diana.prince@example.com" },
|
|
32
|
+
{ id: "5", name: "Ethan Hunt", email: "ethan.hunt@example.com" },
|
|
33
|
+
{ id: "6", name: "Fiona Green", email: "fiona.green@example.com" }
|
|
34
|
+
];
|
|
35
|
+
var MOCK_GOOGLE_CONTACTS = [
|
|
36
|
+
{ id: "g1", name: "John Doe", email: "john.doe@gmail.com" },
|
|
37
|
+
{ id: "g2", name: "Jane Smith", email: "jane.smith@gmail.com" },
|
|
38
|
+
{ id: "g3", name: "Michael Johnson", email: "michael.j@gmail.com" },
|
|
39
|
+
{ id: "g4", name: "Sarah Williams", email: "sarah.w@gmail.com" },
|
|
40
|
+
{ id: "g5", name: "David Brown", email: "david.brown@gmail.com" },
|
|
41
|
+
{ id: "g6", name: "Emma Davis", email: "emma.davis@gmail.com" }
|
|
42
|
+
];
|
|
43
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
44
|
+
0 && (module.exports = {
|
|
45
|
+
MOCK_CONTACTS,
|
|
46
|
+
MOCK_GOOGLE_CONTACTS
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=mockData.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/constants/mockData.ts"],"sourcesContent":["import type { Contact } from '../hooks/useInvitationFormLogic';\n\n// Mock contact data for demonstration\nexport const MOCK_CONTACTS: Contact[] = [\n { id: '1', name: 'Alice Johnson', email: 'alice.johnson@example.com' },\n { id: '2', name: 'Bob Smith', email: 'bob.smith@example.com' },\n { id: '3', name: 'Charlie Brown', email: 'charlie.brown@example.com' },\n { id: '4', name: 'Diana Prince', email: 'diana.prince@example.com' },\n { id: '5', name: 'Ethan Hunt', email: 'ethan.hunt@example.com' },\n { id: '6', name: 'Fiona Green', email: 'fiona.green@example.com' },\n];\n\n// Mock Google contact data for demonstration\nexport const MOCK_GOOGLE_CONTACTS: Contact[] = [\n { id: 'g1', name: 'John Doe', email: 'john.doe@gmail.com' },\n { id: 'g2', name: 'Jane Smith', email: 'jane.smith@gmail.com' },\n { id: 'g3', name: 'Michael Johnson', email: 'michael.j@gmail.com' },\n { id: 'g4', name: 'Sarah Williams', email: 'sarah.w@gmail.com' },\n { id: 'g5', name: 'David Brown', email: 'david.brown@gmail.com' },\n { id: 'g6', name: 'Emma Davis', email: 'emma.davis@gmail.com' },\n];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGO,IAAM,gBAA2B;AAAA,EACtC,EAAE,IAAI,KAAK,MAAM,iBAAiB,OAAO,4BAA4B;AAAA,EACrE,EAAE,IAAI,KAAK,MAAM,aAAa,OAAO,wBAAwB;AAAA,EAC7D,EAAE,IAAI,KAAK,MAAM,iBAAiB,OAAO,4BAA4B;AAAA,EACrE,EAAE,IAAI,KAAK,MAAM,gBAAgB,OAAO,2BAA2B;AAAA,EACnE,EAAE,IAAI,KAAK,MAAM,cAAc,OAAO,yBAAyB;AAAA,EAC/D,EAAE,IAAI,KAAK,MAAM,eAAe,OAAO,0BAA0B;AACnE;AAGO,IAAM,uBAAkC;AAAA,EAC7C,EAAE,IAAI,MAAM,MAAM,YAAY,OAAO,qBAAqB;AAAA,EAC1D,EAAE,IAAI,MAAM,MAAM,cAAc,OAAO,uBAAuB;AAAA,EAC9D,EAAE,IAAI,MAAM,MAAM,mBAAmB,OAAO,sBAAsB;AAAA,EAClE,EAAE,IAAI,MAAM,MAAM,kBAAkB,OAAO,oBAAoB;AAAA,EAC/D,EAAE,IAAI,MAAM,MAAM,eAAe,OAAO,wBAAwB;AAAA,EAChE,EAAE,IAAI,MAAM,MAAM,cAAc,OAAO,uBAAuB;AAChE;","names":[]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// src/constants/mockData.ts
|
|
2
|
+
var MOCK_CONTACTS = [
|
|
3
|
+
{ id: "1", name: "Alice Johnson", email: "alice.johnson@example.com" },
|
|
4
|
+
{ id: "2", name: "Bob Smith", email: "bob.smith@example.com" },
|
|
5
|
+
{ id: "3", name: "Charlie Brown", email: "charlie.brown@example.com" },
|
|
6
|
+
{ id: "4", name: "Diana Prince", email: "diana.prince@example.com" },
|
|
7
|
+
{ id: "5", name: "Ethan Hunt", email: "ethan.hunt@example.com" },
|
|
8
|
+
{ id: "6", name: "Fiona Green", email: "fiona.green@example.com" }
|
|
9
|
+
];
|
|
10
|
+
var MOCK_GOOGLE_CONTACTS = [
|
|
11
|
+
{ id: "g1", name: "John Doe", email: "john.doe@gmail.com" },
|
|
12
|
+
{ id: "g2", name: "Jane Smith", email: "jane.smith@gmail.com" },
|
|
13
|
+
{ id: "g3", name: "Michael Johnson", email: "michael.j@gmail.com" },
|
|
14
|
+
{ id: "g4", name: "Sarah Williams", email: "sarah.w@gmail.com" },
|
|
15
|
+
{ id: "g5", name: "David Brown", email: "david.brown@gmail.com" },
|
|
16
|
+
{ id: "g6", name: "Emma Davis", email: "emma.davis@gmail.com" }
|
|
17
|
+
];
|
|
18
|
+
export {
|
|
19
|
+
MOCK_CONTACTS,
|
|
20
|
+
MOCK_GOOGLE_CONTACTS
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=mockData.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/constants/mockData.ts"],"sourcesContent":["import type { Contact } from '../hooks/useInvitationFormLogic';\n\n// Mock contact data for demonstration\nexport const MOCK_CONTACTS: Contact[] = [\n { id: '1', name: 'Alice Johnson', email: 'alice.johnson@example.com' },\n { id: '2', name: 'Bob Smith', email: 'bob.smith@example.com' },\n { id: '3', name: 'Charlie Brown', email: 'charlie.brown@example.com' },\n { id: '4', name: 'Diana Prince', email: 'diana.prince@example.com' },\n { id: '5', name: 'Ethan Hunt', email: 'ethan.hunt@example.com' },\n { id: '6', name: 'Fiona Green', email: 'fiona.green@example.com' },\n];\n\n// Mock Google contact data for demonstration\nexport const MOCK_GOOGLE_CONTACTS: Contact[] = [\n { id: 'g1', name: 'John Doe', email: 'john.doe@gmail.com' },\n { id: 'g2', name: 'Jane Smith', email: 'jane.smith@gmail.com' },\n { id: 'g3', name: 'Michael Johnson', email: 'michael.j@gmail.com' },\n { id: 'g4', name: 'Sarah Williams', email: 'sarah.w@gmail.com' },\n { id: 'g5', name: 'David Brown', email: 'david.brown@gmail.com' },\n { id: 'g6', name: 'Emma Davis', email: 'emma.davis@gmail.com' },\n];\n"],"mappings":";AAGO,IAAM,gBAA2B;AAAA,EACtC,EAAE,IAAI,KAAK,MAAM,iBAAiB,OAAO,4BAA4B;AAAA,EACrE,EAAE,IAAI,KAAK,MAAM,aAAa,OAAO,wBAAwB;AAAA,EAC7D,EAAE,IAAI,KAAK,MAAM,iBAAiB,OAAO,4BAA4B;AAAA,EACrE,EAAE,IAAI,KAAK,MAAM,gBAAgB,OAAO,2BAA2B;AAAA,EACnE,EAAE,IAAI,KAAK,MAAM,cAAc,OAAO,yBAAyB;AAAA,EAC/D,EAAE,IAAI,KAAK,MAAM,eAAe,OAAO,0BAA0B;AACnE;AAGO,IAAM,uBAAkC;AAAA,EAC7C,EAAE,IAAI,MAAM,MAAM,YAAY,OAAO,qBAAqB;AAAA,EAC1D,EAAE,IAAI,MAAM,MAAM,cAAc,OAAO,uBAAuB;AAAA,EAC9D,EAAE,IAAI,MAAM,MAAM,mBAAmB,OAAO,sBAAsB;AAAA,EAClE,EAAE,IAAI,MAAM,MAAM,kBAAkB,OAAO,oBAAoB;AAAA,EAC/D,EAAE,IAAI,MAAM,MAAM,eAAe,OAAO,wBAAwB;AAAA,EAChE,EAAE,IAAI,MAAM,MAAM,cAAc,OAAO,uBAAuB;AAChE;","names":[]}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* VortexModulesContext
|
|
4
|
+
*
|
|
5
|
+
* Internal context for passing optional module configuration AND loader functions
|
|
6
|
+
* from entry points (VortexInvite/InviteFormWeb) down to child components
|
|
7
|
+
* without prop drilling.
|
|
8
|
+
*
|
|
9
|
+
* This is completely internal to the SDK - end users only need to pass props
|
|
10
|
+
* to <VortexInvite> and everything works automatically.
|
|
11
|
+
*
|
|
12
|
+
* The key insight is that entry points inject the appropriate loader functions:
|
|
13
|
+
* - Native entry (index.tsx/InviteFormMobile) injects loaders from moduleLoaders.ts
|
|
14
|
+
* - Web entry (preview.tsx/InviteFormWeb) injects loaders from moduleLoaders.web.ts
|
|
15
|
+
*
|
|
16
|
+
* This way, components don't import loaders directly, avoiding Metro/webpack bundler issues.
|
|
17
|
+
*
|
|
18
|
+
* Example usage (internal):
|
|
19
|
+
* ```tsx
|
|
20
|
+
* // In a child component
|
|
21
|
+
* const { modules, loaders } = useVortexModules();
|
|
22
|
+
* const GradientComponent = loaders.loadGradientComponent(modules?.gradient);
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
26
|
+
if (k2 === undefined) k2 = k;
|
|
27
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
28
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
29
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
30
|
+
}
|
|
31
|
+
Object.defineProperty(o, k2, desc);
|
|
32
|
+
}) : (function(o, m, k, k2) {
|
|
33
|
+
if (k2 === undefined) k2 = k;
|
|
34
|
+
o[k2] = m[k];
|
|
35
|
+
}));
|
|
36
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
37
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
38
|
+
}) : function(o, v) {
|
|
39
|
+
o["default"] = v;
|
|
40
|
+
});
|
|
41
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
42
|
+
var ownKeys = function(o) {
|
|
43
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
44
|
+
var ar = [];
|
|
45
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
46
|
+
return ar;
|
|
47
|
+
};
|
|
48
|
+
return ownKeys(o);
|
|
49
|
+
};
|
|
50
|
+
return function (mod) {
|
|
51
|
+
if (mod && mod.__esModule) return mod;
|
|
52
|
+
var result = {};
|
|
53
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
54
|
+
__setModuleDefault(result, mod);
|
|
55
|
+
return result;
|
|
56
|
+
};
|
|
57
|
+
})();
|
|
58
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
59
|
+
exports.VortexModulesContext = void 0;
|
|
60
|
+
exports.useVortexModules = useVortexModules;
|
|
61
|
+
exports.VortexModulesProvider = VortexModulesProvider;
|
|
62
|
+
const react_1 = __importStar(require("react"));
|
|
63
|
+
// Default stub loaders that return null (used when no loaders are provided)
|
|
64
|
+
const defaultLoaders = {
|
|
65
|
+
loadGradientComponent: () => null,
|
|
66
|
+
parseCSSLinearGradient: () => null,
|
|
67
|
+
angleToGradientPoints: (angle) => ({
|
|
68
|
+
start: { x: 0, y: 0 },
|
|
69
|
+
end: { x: 1, y: 1 },
|
|
70
|
+
}),
|
|
71
|
+
parseGradientFirstColor: () => null,
|
|
72
|
+
};
|
|
73
|
+
// Default empty config
|
|
74
|
+
const defaultConfig = {
|
|
75
|
+
loaders: defaultLoaders,
|
|
76
|
+
};
|
|
77
|
+
// Create the context with default empty config
|
|
78
|
+
const VortexModulesContext = (0, react_1.createContext)(defaultConfig);
|
|
79
|
+
exports.VortexModulesContext = VortexModulesContext;
|
|
80
|
+
/**
|
|
81
|
+
* Hook to access the module configuration from any child component.
|
|
82
|
+
*
|
|
83
|
+
* @returns The current module configuration including loaders
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```tsx
|
|
87
|
+
* function MyButton() {
|
|
88
|
+
* const { modules, loaders } = useVortexModules();
|
|
89
|
+
* const GradientComponent = loaders?.loadGradientComponent(modules?.gradient);
|
|
90
|
+
* // Use GradientComponent if available
|
|
91
|
+
* }
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
function useVortexModules() {
|
|
95
|
+
var _a, _b, _c, _d, _e;
|
|
96
|
+
const config = (0, react_1.useContext)(VortexModulesContext);
|
|
97
|
+
return Object.assign(Object.assign({}, config), { loaders: config.loaders || defaultLoaders,
|
|
98
|
+
// Provide computed accessors for easy access to individual module names
|
|
99
|
+
gradientModule: (_a = config.modules) === null || _a === void 0 ? void 0 : _a.gradient, hapticsModule: (_b = config.modules) === null || _b === void 0 ? void 0 : _b.haptics, qrCodeModule: (_c = config.modules) === null || _c === void 0 ? void 0 : _c.qrCode, clipboardModule: (_d = config.modules) === null || _d === void 0 ? void 0 : _d.clipboard, sharingModule: (_e = config.modules) === null || _e === void 0 ? void 0 : _e.sharing });
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Provider component that makes module configuration available to all children.
|
|
103
|
+
*
|
|
104
|
+
* This is used internally by VortexInvite and InviteFormWeb.
|
|
105
|
+
* End users don't need to use this directly.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```tsx
|
|
109
|
+
* // Internal usage in VortexInvite (native)
|
|
110
|
+
* import * as nativeLoaders from '../utils/moduleLoaders';
|
|
111
|
+
*
|
|
112
|
+
* <VortexModulesProvider config={{
|
|
113
|
+
* modules: { gradient: 'expo-linear-gradient', haptics: 'expo-haptics' },
|
|
114
|
+
* loaders: nativeLoaders
|
|
115
|
+
* }}>
|
|
116
|
+
* <InviteFormCore {...props} />
|
|
117
|
+
* </VortexModulesProvider>
|
|
118
|
+
*
|
|
119
|
+
* // Internal usage in InviteFormWeb (web)
|
|
120
|
+
* import * as webLoaders from '../utils/moduleLoaders.web';
|
|
121
|
+
*
|
|
122
|
+
* <VortexModulesProvider config={{ loaders: webLoaders }}>
|
|
123
|
+
* <InviteFormCore {...props} />
|
|
124
|
+
* </VortexModulesProvider>
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
function VortexModulesProvider({ config, children }) {
|
|
128
|
+
// Memoize the config to prevent unnecessary re-renders
|
|
129
|
+
// Using the entire config object as dependency to ensure all properties are tracked
|
|
130
|
+
const memoizedConfig = (0, react_1.useMemo)(() => (Object.assign(Object.assign({}, config), { loaders: config.loaders || defaultLoaders })), [config]);
|
|
131
|
+
return (<VortexModulesContext.Provider value={memoizedConfig}>
|
|
132
|
+
{children}
|
|
133
|
+
</VortexModulesContext.Provider>);
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=VortexModulesContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VortexModulesContext.js","sourceRoot":"","sources":["../../src/context/VortexModulesContext.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmMH,4CAoBC;AA2CD,sDAgBC;AAhRD,+CAA4F;AAgK5F,4EAA4E;AAC5E,MAAM,cAAc,GAAkB;IACpC,qBAAqB,EAAE,GAAG,EAAE,CAAC,IAAI;IACjC,sBAAsB,EAAE,GAAG,EAAE,CAAC,IAAI;IAClC,qBAAqB,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,CAAC;QACzC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;QACrB,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;KACpB,CAAC;IACF,uBAAuB,EAAE,GAAG,EAAE,CAAC,IAAI;CACpC,CAAC;AAEF,uBAAuB;AACvB,MAAM,aAAa,GAAwB;IACzC,OAAO,EAAE,cAAc;CACxB,CAAC;AAEF,+CAA+C;AAC/C,MAAM,oBAAoB,GAAG,IAAA,qBAAa,EAAsB,aAAa,CAAC,CAAC;AAkGtE,oDAAoB;AAhG7B;;;;;;;;;;;;;GAaG;AACH,SAAgB,gBAAgB;;IAQ9B,MAAM,MAAM,GAAG,IAAA,kBAAU,EAAC,oBAAoB,CAAC,CAAC;IAEhD,uCACK,MAAM,KACT,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,cAAc;QACzC,wEAAwE;QACxE,cAAc,EAAE,MAAA,MAAM,CAAC,OAAO,0CAAE,QAAQ,EACxC,aAAa,EAAE,MAAA,MAAM,CAAC,OAAO,0CAAE,OAAO,EACtC,YAAY,EAAE,MAAA,MAAM,CAAC,OAAO,0CAAE,MAAM,EACpC,eAAe,EAAE,MAAA,MAAM,CAAC,OAAO,0CAAE,SAAS,EAC1C,aAAa,EAAE,MAAA,MAAM,CAAC,OAAO,0CAAE,OAAO,IACtC;AACJ,CAAC;AAiBD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,SAAgB,qBAAqB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAA8B;IACpF,uDAAuD;IACvD,oFAAoF;IACpF,MAAM,cAAc,GAAG,IAAA,eAAO,EAC5B,GAAG,EAAE,CAAC,iCACD,MAAM,KACT,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,cAAc,IACzC,EACF,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,OAAO,CACL,CAAC,oBAAoB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,CACnD;MAAA,CAAC,QAAQ,CACX;IAAA,EAAE,oBAAoB,CAAC,QAAQ,CAAC,CACjC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * VortexModulesContext\n *\n * Internal context for passing optional module configuration AND loader functions\n * from entry points (VortexInvite/InviteFormWeb) down to child components\n * without prop drilling.\n *\n * This is completely internal to the SDK - end users only need to pass props\n * to <VortexInvite> and everything works automatically.\n *\n * The key insight is that entry points inject the appropriate loader functions:\n * - Native entry (index.tsx/InviteFormMobile) injects loaders from moduleLoaders.ts\n * - Web entry (preview.tsx/InviteFormWeb) injects loaders from moduleLoaders.web.ts\n *\n * This way, components don't import loaders directly, avoiding Metro/webpack bundler issues.\n *\n * Example usage (internal):\n * ```tsx\n * // In a child component\n * const { modules, loaders } = useVortexModules();\n * const GradientComponent = loaders.loadGradientComponent(modules?.gradient);\n * ```\n */\n\nimport React, { createContext, useContext, useMemo, ReactNode, ComponentType } from 'react';\n\n/**\n * Supported gradient library module names.\n * Users specify which library they have installed.\n */\nexport type GradientModuleName = 'expo-linear-gradient' | 'react-native-linear-gradient';\n\n/**\n * Supported haptics library module names.\n */\nexport type HapticsModuleName = 'expo-haptics';\n\n/**\n * Supported QR code library module names.\n */\nexport type QRCodeModuleName = 'react-native-qrcode-svg' | 'react-qr-code';\n\n/**\n * Supported clipboard library module names.\n */\nexport type ClipboardModuleName = 'expo-clipboard' | '@react-native-clipboard/clipboard';\n\n/**\n * Supported sharing library module names.\n */\nexport type SharingModuleName = 'expo-sharing';\n\n/**\n * Unified modules configuration object.\n * Users specify which optional native libraries they have installed via a single prop.\n *\n * @example\n * ```tsx\n * <VortexInvite\n * componentId=\"abc123\"\n * modules={{\n * gradient: 'expo-linear-gradient',\n * haptics: 'expo-haptics',\n * qrCode: 'react-native-qrcode-svg',\n * }}\n * />\n * ```\n */\nexport interface VortexModules {\n /**\n * Gradient library for button backgrounds.\n * For Expo: 'expo-linear-gradient'\n * For bare RN: 'react-native-linear-gradient'\n */\n gradient?: GradientModuleName;\n\n /**\n * Haptics library for touch feedback.\n * Currently only 'expo-haptics' is supported.\n */\n haptics?: HapticsModuleName;\n\n /**\n * QR code library for QR code display.\n * For native: 'react-native-qrcode-svg'\n * For web: 'react-qr-code'\n */\n qrCode?: QRCodeModuleName;\n\n /**\n * Clipboard library for copy functionality.\n * For Expo: 'expo-clipboard'\n * For bare RN: '@react-native-clipboard/clipboard'\n */\n clipboard?: ClipboardModuleName;\n\n /**\n * Sharing library for native share sheet.\n * Currently only 'expo-sharing' is supported.\n */\n sharing?: SharingModuleName;\n}\n\n/**\n * Props for gradient components (compatible with both expo and react-native-linear-gradient)\n */\nexport interface GradientProps {\n colors: string[];\n locations?: number[];\n start?: { x: number; y: number };\n end?: { x: number; y: number };\n style?: any;\n children?: React.ReactNode;\n}\n\n/**\n * 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 * Haptic feedback style\n */\nexport type HapticStyle = 'light' | 'medium' | 'heavy';\n\n/**\n * Module loader functions interface.\n * These are injected by entry points (native vs web) to avoid direct imports\n * that would cause bundler issues.\n */\nexport interface ModuleLoaders {\n /**\n * Loads the gradient component based on the specified module name.\n */\n loadGradientComponent: (moduleName: GradientModuleName | undefined) => ComponentType<GradientProps> | null;\n\n /**\n * Parses a CSS linear-gradient string into a structured format.\n */\n parseCSSLinearGradient: (css: string) => ParsedGradient | null;\n\n /**\n * Converts a CSS gradient angle to start/end points for LinearGradient component.\n */\n angleToGradientPoints: (angle: number) => GradientPoints;\n\n /**\n * Extracts the first color from a CSS gradient string.\n */\n parseGradientFirstColor: (gradientString: string) => string | null;\n}\n\n/**\n * Internal configuration for the modules context.\n * This combines the user-facing modules config with internal loader functions.\n */\nexport interface VortexModulesConfig {\n /**\n * Unified modules configuration object.\n * Users specify which optional native libraries they have installed.\n */\n modules?: VortexModules;\n\n /**\n * Module loader functions injected by entry points.\n * This allows native and web entry points to provide different implementations.\n * @internal\n */\n loaders?: ModuleLoaders;\n}\n\n// Default stub loaders that return null (used when no loaders are provided)\nconst defaultLoaders: ModuleLoaders = {\n loadGradientComponent: () => null,\n parseCSSLinearGradient: () => null,\n angleToGradientPoints: (angle: number) => ({\n start: { x: 0, y: 0 },\n end: { x: 1, y: 1 },\n }),\n parseGradientFirstColor: () => null,\n};\n\n// Default empty config\nconst defaultConfig: VortexModulesConfig = {\n loaders: defaultLoaders,\n};\n\n// Create the context with default empty config\nconst VortexModulesContext = createContext<VortexModulesConfig>(defaultConfig);\n\n/**\n * Hook to access the module configuration from any child component.\n *\n * @returns The current module configuration including loaders\n *\n * @example\n * ```tsx\n * function MyButton() {\n * const { modules, loaders } = useVortexModules();\n * const GradientComponent = loaders?.loadGradientComponent(modules?.gradient);\n * // Use GradientComponent if available\n * }\n * ```\n */\nexport function useVortexModules(): VortexModulesConfig & { \n // Computed properties for easy access\n gradientModule?: GradientModuleName;\n hapticsModule?: HapticsModuleName;\n qrCodeModule?: QRCodeModuleName;\n clipboardModule?: ClipboardModuleName;\n sharingModule?: SharingModuleName;\n} {\n const config = useContext(VortexModulesContext);\n \n return {\n ...config,\n loaders: config.loaders || defaultLoaders,\n // Provide computed accessors for easy access to individual module names\n gradientModule: config.modules?.gradient,\n hapticsModule: config.modules?.haptics,\n qrCodeModule: config.modules?.qrCode,\n clipboardModule: config.modules?.clipboard,\n sharingModule: config.modules?.sharing,\n };\n}\n\n/**\n * Props for the VortexModulesProvider component.\n */\nexport interface VortexModulesProviderProps {\n /**\n * Module configuration to provide to children.\n */\n config: VortexModulesConfig;\n\n /**\n * Child components that will have access to the module configuration.\n */\n children: ReactNode;\n}\n\n/**\n * Provider component that makes module configuration available to all children.\n *\n * This is used internally by VortexInvite and InviteFormWeb.\n * End users don't need to use this directly.\n *\n * @example\n * ```tsx\n * // Internal usage in VortexInvite (native)\n * import * as nativeLoaders from '../utils/moduleLoaders';\n * \n * <VortexModulesProvider config={{ \n * modules: { gradient: 'expo-linear-gradient', haptics: 'expo-haptics' },\n * loaders: nativeLoaders \n * }}>\n * <InviteFormCore {...props} />\n * </VortexModulesProvider>\n * \n * // Internal usage in InviteFormWeb (web)\n * import * as webLoaders from '../utils/moduleLoaders.web';\n * \n * <VortexModulesProvider config={{ loaders: webLoaders }}>\n * <InviteFormCore {...props} />\n * </VortexModulesProvider>\n * ```\n */\nexport function VortexModulesProvider({ config, children }: VortexModulesProviderProps) {\n // Memoize the config to prevent unnecessary re-renders\n // Using the entire config object as dependency to ensure all properties are tracked\n const memoizedConfig = useMemo(\n () => ({\n ...config,\n loaders: config.loaders || defaultLoaders,\n }),\n [config]\n );\n\n return (\n <VortexModulesContext.Provider value={memoizedConfig}>\n {children}\n </VortexModulesContext.Provider>\n );\n}\n\n// Export the context for testing purposes\nexport { VortexModulesContext };\n"]}
|