@deneb-ui/ui 2.0.50 → 2.0.51
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/EditableContactForm.d.ts +4 -1
- package/dist/EditableContactForm.js +41 -12
- package/dist/hooks/useWhatsAppForm.d.ts +52 -0
- package/dist/hooks/useWhatsAppForm.js +228 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +2 -2
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
export interface EditableContactFormProps extends React.FormHTMLAttributes<HTMLFormElement> {
|
|
3
3
|
endpoint?: string;
|
|
4
|
+
whatsappUrl?: string;
|
|
5
|
+
whatsappUrlPath?: string;
|
|
6
|
+
submitMode?: 'whatsapp' | 'api' | 'both';
|
|
4
7
|
formTitle?: string;
|
|
5
8
|
formTitlePath?: string;
|
|
6
9
|
submitButtonText?: string;
|
|
@@ -16,4 +19,4 @@ export interface EditableContactFormProps extends React.FormHTMLAttributes<HTMLF
|
|
|
16
19
|
successMessage?: string;
|
|
17
20
|
showPhone?: boolean;
|
|
18
21
|
}
|
|
19
|
-
export declare function EditableContactForm({ endpoint, formTitle, formTitlePath, submitButtonText, submitLabelPath, nameLabelPath, namePlaceholderPath, emailLabelPath, emailPlaceholderPath, phoneLabelPath, phonePlaceholderPath, messageLabelPath, messagePlaceholderPath, successMessage, showPhone, className, style, ...props }: EditableContactFormProps): React.JSX.Element;
|
|
22
|
+
export declare function EditableContactForm({ endpoint, whatsappUrl, whatsappUrlPath, submitMode, formTitle, formTitlePath, submitButtonText, submitLabelPath, nameLabelPath, namePlaceholderPath, emailLabelPath, emailPlaceholderPath, phoneLabelPath, phonePlaceholderPath, messageLabelPath, messagePlaceholderPath, successMessage, showPhone, className, style, ...props }: EditableContactFormProps): React.JSX.Element;
|
|
@@ -4,7 +4,8 @@ exports.EditableContactForm = EditableContactForm;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const SiteDataProvider_1 = require("./SiteDataProvider");
|
|
7
|
-
|
|
7
|
+
const useWhatsAppForm_1 = require("./hooks/useWhatsAppForm");
|
|
8
|
+
function EditableContactForm({ endpoint = 'https://api.fivora.com/site-contact', whatsappUrl, whatsappUrlPath = 'contact.formWhatsappUrl', submitMode = 'whatsapp', formTitle, formTitlePath, submitButtonText = 'Send Message', submitLabelPath = 'contact.submitLabel', nameLabelPath = 'contact.nameLabel', namePlaceholderPath = 'contact.namePlaceholder', emailLabelPath = 'contact.emailLabel', emailPlaceholderPath = 'contact.emailPlaceholder', phoneLabelPath = 'contact.phoneLabel', phonePlaceholderPath = 'contact.phonePlaceholder', messageLabelPath = 'contact.messageLabel', messagePlaceholderPath = 'contact.messagePlaceholder', successMessage = 'Thank you! Your message has been sent successfully.', showPhone = false, className = '', style, ...props }) {
|
|
8
9
|
const siteData = (0, SiteDataProvider_1.useSiteData)();
|
|
9
10
|
const [status, setStatus] = (0, react_1.useState)('idle');
|
|
10
11
|
const [errorMessage, setErrorMessage] = (0, react_1.useState)('');
|
|
@@ -19,6 +20,18 @@ function EditableContactForm({ endpoint = 'https://api.fivora.com/site-contact',
|
|
|
19
20
|
const resolvedPhonePlaceholder = String(contactContent?.phonePlaceholder || '+1 (555) 000-0000');
|
|
20
21
|
const resolvedMessageLabel = String(contactContent?.messageLabel || 'Message');
|
|
21
22
|
const resolvedMessagePlaceholder = String(contactContent?.messagePlaceholder || 'Tell us how we can help...');
|
|
23
|
+
const { submitViaWhatsApp, resolvedWhatsappUrl } = (0, useWhatsAppForm_1.useWhatsAppForm)({
|
|
24
|
+
whatsappUrl,
|
|
25
|
+
whatsappUrlPath,
|
|
26
|
+
formName: resolvedFormTitle || 'Contact Form',
|
|
27
|
+
onSuccess: () => {
|
|
28
|
+
setStatus('success');
|
|
29
|
+
},
|
|
30
|
+
onError: (err) => {
|
|
31
|
+
setStatus('error');
|
|
32
|
+
setErrorMessage(err.message || 'Something went wrong. Please try again.');
|
|
33
|
+
},
|
|
34
|
+
});
|
|
22
35
|
const handleSubmit = async (e) => {
|
|
23
36
|
e.preventDefault();
|
|
24
37
|
setStatus('submitting');
|
|
@@ -32,22 +45,38 @@ function EditableContactForm({ endpoint = 'https://api.fivora.com/site-contact',
|
|
|
32
45
|
phone: showPhone ? formData.get('phone') : undefined,
|
|
33
46
|
message: formData.get('message'),
|
|
34
47
|
};
|
|
35
|
-
|
|
36
|
-
|
|
48
|
+
if (submitMode === 'api') {
|
|
49
|
+
try {
|
|
50
|
+
const res = await fetch(endpoint, {
|
|
51
|
+
method: 'POST',
|
|
52
|
+
headers: { 'Content-Type': 'application/json' },
|
|
53
|
+
body: JSON.stringify(payload),
|
|
54
|
+
});
|
|
55
|
+
if (!res.ok) {
|
|
56
|
+
throw new Error(`Submission error: ${res.statusText || 'Unable to send message'}`);
|
|
57
|
+
}
|
|
58
|
+
setStatus('success');
|
|
59
|
+
form.reset();
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
setStatus('error');
|
|
63
|
+
setErrorMessage(err.message || 'Something went wrong. Please try again.');
|
|
64
|
+
}
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// Default to WhatsApp dispatch (or both if requested)
|
|
68
|
+
if (submitMode === 'both') {
|
|
69
|
+
fetch(endpoint, {
|
|
37
70
|
method: 'POST',
|
|
38
71
|
headers: { 'Content-Type': 'application/json' },
|
|
39
72
|
body: JSON.stringify(payload),
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
73
|
+
}).catch(() => { });
|
|
74
|
+
}
|
|
75
|
+
const success = submitViaWhatsApp(form);
|
|
76
|
+
if (success) {
|
|
44
77
|
setStatus('success');
|
|
45
78
|
form.reset();
|
|
46
79
|
}
|
|
47
|
-
catch (err) {
|
|
48
|
-
setStatus('error');
|
|
49
|
-
setErrorMessage(err.message || 'Something went wrong. Please try again.');
|
|
50
|
-
}
|
|
51
80
|
};
|
|
52
81
|
return ((0, jsx_runtime_1.jsxs)("form", { onSubmit: handleSubmit, "data-fivora-contact-disabled": true, style: {
|
|
53
82
|
display: 'flex',
|
|
@@ -132,7 +161,7 @@ function EditableContactForm({ endpoint = 'https://api.fivora.com/site-contact',
|
|
|
132
161
|
opacity: status === 'submitting' ? 0.7 : 1,
|
|
133
162
|
boxShadow: '0 4px 14px 0 rgba(37, 99, 235, 0.35)',
|
|
134
163
|
transition: 'all 0.2s ease',
|
|
135
|
-
}, children: (0, jsx_runtime_1.jsx)("span", { "data-preview-field-path": submitLabelPath, children: status === 'submitting' ? 'Sending Message...' : resolvedSubmitText }) }), status === 'success' && ((0, jsx_runtime_1.jsx)("div", { style: {
|
|
164
|
+
}, children: (0, jsx_runtime_1.jsx)("span", { "data-preview-field-path": submitLabelPath, children: status === 'submitting' ? 'Sending Message...' : resolvedSubmitText }) }), (0, jsx_runtime_1.jsx)("span", { hidden: true, "aria-hidden": "true", "data-preview-field-path": whatsappUrlPath, children: resolvedWhatsappUrl }), status === 'success' && ((0, jsx_runtime_1.jsx)("div", { style: {
|
|
136
165
|
padding: '1rem',
|
|
137
166
|
borderRadius: '10px',
|
|
138
167
|
backgroundColor: 'rgba(34, 197, 94, 0.1)',
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface UseWhatsAppFormOptions {
|
|
3
|
+
/** The WhatsApp URL or phone number (e.g. "https://wa.me/1234567890", "+1234567890") */
|
|
4
|
+
whatsappUrl?: string | null;
|
|
5
|
+
/** Field path to query in siteData (e.g. "contact.formWhatsappUrl") */
|
|
6
|
+
whatsappUrlPath?: string;
|
|
7
|
+
/** Form name for message header (e.g. "Contact Inquiry", "Book Repair") */
|
|
8
|
+
formName?: string;
|
|
9
|
+
/** Business name for message header */
|
|
10
|
+
businessName?: string;
|
|
11
|
+
/** Custom message formatter callback */
|
|
12
|
+
formatMessage?: (data: Record<string, any>) => string;
|
|
13
|
+
/** Callback fired after opening WhatsApp */
|
|
14
|
+
onSuccess?: (details: {
|
|
15
|
+
data: Record<string, any>;
|
|
16
|
+
url: string;
|
|
17
|
+
}) => void;
|
|
18
|
+
/** Callback fired if submission encounters an error */
|
|
19
|
+
onError?: (error: Error) => void;
|
|
20
|
+
}
|
|
21
|
+
export interface UseWhatsAppFormReturn {
|
|
22
|
+
/** Submit directly from an HTML form element or submit FormEvent */
|
|
23
|
+
submitViaWhatsApp: (eOrForm: React.FormEvent<HTMLFormElement> | HTMLFormElement, extraData?: Record<string, any>) => boolean;
|
|
24
|
+
/** Submit explicit key-value data */
|
|
25
|
+
submitDataViaWhatsApp: (data: Record<string, any>) => boolean;
|
|
26
|
+
/** Construct full WhatsApp URL without triggering window navigation */
|
|
27
|
+
buildWhatsAppUrl: (data: Record<string, any>) => string;
|
|
28
|
+
/** Resolved target phone or URL */
|
|
29
|
+
resolvedWhatsappUrl: string;
|
|
30
|
+
/** The most recently generated WhatsApp link */
|
|
31
|
+
whatsAppLink: string | null;
|
|
32
|
+
/** Submission state */
|
|
33
|
+
isSubmitting: boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Extracts digits from a raw phone number, full wa.me link, or WhatsApp API link.
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveWhatsAppNumber(target?: string | null): string;
|
|
39
|
+
/**
|
|
40
|
+
* Extracts form field labels and values from an HTMLFormElement.
|
|
41
|
+
*/
|
|
42
|
+
export declare function extractFormData(form: HTMLFormElement): Record<string, any>;
|
|
43
|
+
export declare function defaultFormatMessage(data: Record<string, any>, options?: {
|
|
44
|
+
formName?: string;
|
|
45
|
+
businessName?: string;
|
|
46
|
+
}): string;
|
|
47
|
+
/**
|
|
48
|
+
* Universal Form-to-WhatsApp Hook.
|
|
49
|
+
* Supports HTMLFormElement submission, controlled component state data,
|
|
50
|
+
* automatic siteData URL lookup, and popup-blocker safe redirection.
|
|
51
|
+
*/
|
|
52
|
+
export declare function useWhatsAppForm(options?: UseWhatsAppFormOptions): UseWhatsAppFormReturn;
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.resolveWhatsAppNumber = resolveWhatsAppNumber;
|
|
5
|
+
exports.extractFormData = extractFormData;
|
|
6
|
+
exports.defaultFormatMessage = defaultFormatMessage;
|
|
7
|
+
exports.useWhatsAppForm = useWhatsAppForm;
|
|
8
|
+
const react_1 = require("react");
|
|
9
|
+
const SiteDataProvider_1 = require("../SiteDataProvider");
|
|
10
|
+
/**
|
|
11
|
+
* Extracts digits from a raw phone number, full wa.me link, or WhatsApp API link.
|
|
12
|
+
*/
|
|
13
|
+
function resolveWhatsAppNumber(target) {
|
|
14
|
+
if (!target)
|
|
15
|
+
return '';
|
|
16
|
+
const trimmed = String(target).trim();
|
|
17
|
+
const waMatch = trimmed.match(/wa\.me\/([0-9+]+)/i);
|
|
18
|
+
if (waMatch && waMatch[1]) {
|
|
19
|
+
return waMatch[1].replace(/[^0-9]/g, '');
|
|
20
|
+
}
|
|
21
|
+
const queryMatch = trimmed.match(/[?&]phone=([0-9+]+)/i);
|
|
22
|
+
if (queryMatch && queryMatch[1]) {
|
|
23
|
+
return queryMatch[1].replace(/[^0-9]/g, '');
|
|
24
|
+
}
|
|
25
|
+
return trimmed.replace(/[^0-9]/g, '');
|
|
26
|
+
}
|
|
27
|
+
function getValueByPath(obj, path) {
|
|
28
|
+
if (!obj || !path)
|
|
29
|
+
return undefined;
|
|
30
|
+
const parts = path.replace(/\[(\d+)\]/g, '.$1').split('.').filter(Boolean);
|
|
31
|
+
let curr = obj;
|
|
32
|
+
for (const part of parts) {
|
|
33
|
+
if (curr == null)
|
|
34
|
+
return undefined;
|
|
35
|
+
curr = curr[part];
|
|
36
|
+
}
|
|
37
|
+
return curr;
|
|
38
|
+
}
|
|
39
|
+
function humanizeFieldName(name) {
|
|
40
|
+
return name
|
|
41
|
+
.replace(/([A-Z])/g, ' $1')
|
|
42
|
+
.replace(/[-_]+/g, ' ')
|
|
43
|
+
.trim()
|
|
44
|
+
.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Extracts form field labels and values from an HTMLFormElement.
|
|
48
|
+
*/
|
|
49
|
+
function extractFormData(form) {
|
|
50
|
+
const result = {};
|
|
51
|
+
const elements = Array.from(form.elements);
|
|
52
|
+
for (const el of elements) {
|
|
53
|
+
if (!(el instanceof HTMLInputElement ||
|
|
54
|
+
el instanceof HTMLTextAreaElement ||
|
|
55
|
+
el instanceof HTMLSelectElement)) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (!el.name || el.disabled || el.type === 'submit' || el.type === 'reset' || el.type === 'button') {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if ((el.type === 'checkbox' || el.type === 'radio') && !el.checked) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
let fieldLabel = '';
|
|
65
|
+
if (el.id) {
|
|
66
|
+
const labelEl = form.querySelector(`label[for="${el.id}"]`);
|
|
67
|
+
if (labelEl && labelEl.textContent) {
|
|
68
|
+
fieldLabel = labelEl.textContent.trim();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (!fieldLabel) {
|
|
72
|
+
const parentLabel = el.closest('label');
|
|
73
|
+
if (parentLabel) {
|
|
74
|
+
const clone = parentLabel.cloneNode(true);
|
|
75
|
+
clone.querySelectorAll('input, select, textarea').forEach((n) => n.remove());
|
|
76
|
+
fieldLabel = clone.textContent?.trim() || '';
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (!fieldLabel && el.getAttribute('aria-label')) {
|
|
80
|
+
fieldLabel = el.getAttribute('aria-label') || '';
|
|
81
|
+
}
|
|
82
|
+
if (!fieldLabel && 'placeholder' in el && el.placeholder) {
|
|
83
|
+
fieldLabel = el.placeholder.trim();
|
|
84
|
+
}
|
|
85
|
+
if (!fieldLabel) {
|
|
86
|
+
fieldLabel = humanizeFieldName(el.name);
|
|
87
|
+
}
|
|
88
|
+
result[fieldLabel] = el.value;
|
|
89
|
+
}
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
function defaultFormatMessage(data, options = {}) {
|
|
93
|
+
const lines = [];
|
|
94
|
+
if (options.formName && options.businessName) {
|
|
95
|
+
lines.push(`*${options.formName} - ${options.businessName}*`);
|
|
96
|
+
}
|
|
97
|
+
else if (options.formName) {
|
|
98
|
+
lines.push(`*${options.formName}*`);
|
|
99
|
+
}
|
|
100
|
+
else if (options.businessName) {
|
|
101
|
+
lines.push(`*New Message for ${options.businessName}*`);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
lines.push(`*New Form Submission*`);
|
|
105
|
+
}
|
|
106
|
+
lines.push('────────────────────────');
|
|
107
|
+
for (const [key, val] of Object.entries(data)) {
|
|
108
|
+
if (val === undefined || val === null || val === '')
|
|
109
|
+
continue;
|
|
110
|
+
if (Array.isArray(val)) {
|
|
111
|
+
lines.push(`*${key}*:`);
|
|
112
|
+
val.forEach((item, idx) => {
|
|
113
|
+
if (typeof item === 'object' && item !== null) {
|
|
114
|
+
lines.push(` ${idx + 1}. ${JSON.stringify(item)}`);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
lines.push(` • ${item}`);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
else if (typeof val === 'object' && val !== null) {
|
|
122
|
+
lines.push(`*${key}*: ${JSON.stringify(val)}`);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
lines.push(`*${key}*: ${val}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
lines.push('────────────────────────');
|
|
129
|
+
lines.push('_Sent via website form_');
|
|
130
|
+
return lines.join('\n');
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Universal Form-to-WhatsApp Hook.
|
|
134
|
+
* Supports HTMLFormElement submission, controlled component state data,
|
|
135
|
+
* automatic siteData URL lookup, and popup-blocker safe redirection.
|
|
136
|
+
*/
|
|
137
|
+
function useWhatsAppForm(options = {}) {
|
|
138
|
+
const siteData = (0, SiteDataProvider_1.useSiteData)();
|
|
139
|
+
const [isSubmitting, setIsSubmitting] = (0, react_1.useState)(false);
|
|
140
|
+
const [whatsAppLink, setWhatsAppLink] = (0, react_1.useState)(null);
|
|
141
|
+
// 1. Resolve WhatsApp URL from options, siteData path, or fallback siteData fields
|
|
142
|
+
const content = siteData?.content;
|
|
143
|
+
const business = siteData?.business;
|
|
144
|
+
let resolvedUrl = options.whatsappUrl;
|
|
145
|
+
if (!resolvedUrl && options.whatsappUrlPath) {
|
|
146
|
+
resolvedUrl =
|
|
147
|
+
getValueByPath(content, options.whatsappUrlPath) ||
|
|
148
|
+
getValueByPath(siteData, options.whatsappUrlPath);
|
|
149
|
+
}
|
|
150
|
+
if (!resolvedUrl) {
|
|
151
|
+
resolvedUrl =
|
|
152
|
+
content?.contact?.formWhatsappUrl ||
|
|
153
|
+
content?.contact?.whatsappUrl ||
|
|
154
|
+
content?.home?.contact?.formWhatsappUrl ||
|
|
155
|
+
business?.whatsapp ||
|
|
156
|
+
siteData?.contact?.whatsapp ||
|
|
157
|
+
'https://wa.me/1234567890';
|
|
158
|
+
}
|
|
159
|
+
const resolvedBusinessName = options.businessName ||
|
|
160
|
+
business?.name ||
|
|
161
|
+
content?.common?.business?.name ||
|
|
162
|
+
siteData?.project?.name ||
|
|
163
|
+
'';
|
|
164
|
+
const buildUrl = (0, react_1.useCallback)((data) => {
|
|
165
|
+
const number = resolveWhatsAppNumber(resolvedUrl);
|
|
166
|
+
const message = options.formatMessage
|
|
167
|
+
? options.formatMessage(data)
|
|
168
|
+
: defaultFormatMessage(data, {
|
|
169
|
+
formName: options.formName,
|
|
170
|
+
businessName: resolvedBusinessName,
|
|
171
|
+
});
|
|
172
|
+
if (number) {
|
|
173
|
+
return `https://wa.me/${number}?text=${encodeURIComponent(message)}`;
|
|
174
|
+
}
|
|
175
|
+
if (resolvedUrl && /^https?:\/\//i.test(resolvedUrl)) {
|
|
176
|
+
const separator = resolvedUrl.includes('?') ? '&' : '?';
|
|
177
|
+
return `${resolvedUrl}${separator}text=${encodeURIComponent(message)}`;
|
|
178
|
+
}
|
|
179
|
+
return `https://wa.me/?text=${encodeURIComponent(message)}`;
|
|
180
|
+
}, [resolvedUrl, options.formatMessage, options.formName, resolvedBusinessName]);
|
|
181
|
+
const dispatchUrl = (0, react_1.useCallback)((url, data) => {
|
|
182
|
+
setIsSubmitting(true);
|
|
183
|
+
setWhatsAppLink(url);
|
|
184
|
+
try {
|
|
185
|
+
if (typeof window !== 'undefined') {
|
|
186
|
+
const opened = window.open(url, '_blank', 'noopener,noreferrer');
|
|
187
|
+
if (!opened || opened.closed || typeof opened.closed === 'undefined') {
|
|
188
|
+
window.location.href = url;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
options.onSuccess?.({ data, url });
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
options.onError?.(err);
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
finally {
|
|
199
|
+
setIsSubmitting(false);
|
|
200
|
+
}
|
|
201
|
+
}, [options]);
|
|
202
|
+
const submitDataViaWhatsApp = (0, react_1.useCallback)((data) => {
|
|
203
|
+
const url = buildUrl(data);
|
|
204
|
+
return dispatchUrl(url, data);
|
|
205
|
+
}, [buildUrl, dispatchUrl]);
|
|
206
|
+
const submitViaWhatsApp = (0, react_1.useCallback)((eOrForm, extraData) => {
|
|
207
|
+
let form = null;
|
|
208
|
+
if ('preventDefault' in eOrForm && typeof eOrForm.preventDefault === 'function') {
|
|
209
|
+
eOrForm.preventDefault();
|
|
210
|
+
form = (eOrForm.currentTarget || eOrForm.target);
|
|
211
|
+
}
|
|
212
|
+
else if (eOrForm instanceof HTMLElement) {
|
|
213
|
+
form = eOrForm;
|
|
214
|
+
}
|
|
215
|
+
const extracted = form ? extractFormData(form) : {};
|
|
216
|
+
const merged = extraData ? { ...extracted, ...extraData } : extracted;
|
|
217
|
+
const url = buildUrl(merged);
|
|
218
|
+
return dispatchUrl(url, merged);
|
|
219
|
+
}, [buildUrl, dispatchUrl]);
|
|
220
|
+
return {
|
|
221
|
+
submitViaWhatsApp,
|
|
222
|
+
submitDataViaWhatsApp,
|
|
223
|
+
buildWhatsAppUrl: buildUrl,
|
|
224
|
+
resolvedWhatsappUrl: String(resolvedUrl),
|
|
225
|
+
whatsAppLink,
|
|
226
|
+
isSubmitting,
|
|
227
|
+
};
|
|
228
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -42,6 +42,7 @@ export { DenebComponentStyles } from './DenebComponentStyles';
|
|
|
42
42
|
export { FontLoader, DENEB_FONTS_LINK_ID } from './fonts/FontLoader';
|
|
43
43
|
export { useDenebFonts } from './fonts/useDenebFonts';
|
|
44
44
|
export * from './hooks/useComponentStyle';
|
|
45
|
+
export * from './hooks/useWhatsAppForm';
|
|
45
46
|
export { DENEB_FONT_REGISTRY, DENEB_GOOGLE_FONT_COUNT, buildGoogleFontsStylesheetUrl, collectFontIdsFromSiteData, listFontsByCategory, lookupFontDefinition, normalizeFontId, resolveInstallableFont, formatResponsiveFontSize, } from '@deneb-ui/core';
|
|
46
47
|
export { STYLE_PATCH_MESSAGE, DENEB_STYLE_PATCH_MESSAGE, STYLE_TARGET_ATTRIBUTE, STYLE_TYPE_ATTRIBUTE, patchElementStyle, patchStyleByPath, styleToCssVariables, validateStyleTree, collectStyleTargetsFromHtml, } from '@deneb-ui/core';
|
|
47
48
|
export * from './utils';
|
package/dist/index.js
CHANGED
|
@@ -65,6 +65,7 @@ Object.defineProperty(exports, "DENEB_FONTS_LINK_ID", { enumerable: true, get: f
|
|
|
65
65
|
var useDenebFonts_1 = require("./fonts/useDenebFonts");
|
|
66
66
|
Object.defineProperty(exports, "useDenebFonts", { enumerable: true, get: function () { return useDenebFonts_1.useDenebFonts; } });
|
|
67
67
|
__exportStar(require("./hooks/useComponentStyle"), exports);
|
|
68
|
+
__exportStar(require("./hooks/useWhatsAppForm"), exports);
|
|
68
69
|
var core_1 = require("@deneb-ui/core");
|
|
69
70
|
Object.defineProperty(exports, "DENEB_FONT_REGISTRY", { enumerable: true, get: function () { return core_1.DENEB_FONT_REGISTRY; } });
|
|
70
71
|
Object.defineProperty(exports, "DENEB_GOOGLE_FONT_COUNT", { enumerable: true, get: function () { return core_1.DENEB_GOOGLE_FONT_COUNT; } });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deneb-ui/ui",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.51",
|
|
4
4
|
"description": "Visual-first React component library for editable commerce storefronts. Built for Next.js and Fivora.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
],
|
|
50
50
|
"license": "MIT",
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@deneb-ui/core": "^2.0.
|
|
52
|
+
"@deneb-ui/core": "^2.0.51"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
55
|
"react": "^18.0.0 || ^19.0.0",
|