@squaredr/fieldcraft-pro 1.4.0 → 1.6.0
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/{chunk-BK4SMEW4.mjs → chunk-5LKGCZAW.mjs} +1 -0
- package/dist/{chunk-BYT2P3I6.mjs → chunk-ANBMT5AW.mjs} +46 -58
- package/dist/{chunk-22T5PY6L.mjs → chunk-IKGS2ZXV.mjs} +382 -87
- package/dist/form-builder/index.d.mts +1 -1
- package/dist/form-builder/index.d.ts +1 -1
- package/dist/form-builder/index.js +45 -59
- package/dist/form-builder/index.mjs +1 -1
- package/dist/{index-nvIvXlmc.d.ts → index-D19524df.d.mts} +3 -14
- package/dist/{index-nvIvXlmc.d.mts → index-D19524df.d.ts} +3 -14
- package/dist/index.d.mts +30 -4
- package/dist/index.d.ts +30 -4
- package/dist/index.js +739 -105
- package/dist/index.mjs +276 -4
- package/dist/response-viewer/index.js +1 -0
- package/dist/response-viewer/index.mjs +1 -1
- package/dist/styles.css +1 -1
- package/dist/theme-editor/index.d.mts +78 -13
- package/dist/theme-editor/index.d.ts +78 -13
- package/dist/theme-editor/index.js +381 -86
- package/dist/theme-editor/index.mjs +1 -1
- package/package.json +15 -5
- package/theme-editor/styles.css +20 -5
- package/dist/preview-schema-DFvV4y6J.d.mts +0 -66
- package/dist/preview-schema-DFvV4y6J.d.ts +0 -66
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,283 @@
|
|
|
1
|
-
export { DEFAULT_PALETTE, DEFAULT_SCHEMA, FormBuilder, FormBuilderThemeProvider, QUESTION_TYPE_INFO, addOption, addQuestion, addSection,
|
|
2
|
-
export { ResponseViewer } from './chunk-
|
|
1
|
+
export { DEFAULT_PALETTE, DEFAULT_SCHEMA, FormBuilder, FormBuilderThemeProvider, QUESTION_TYPE_INFO, addOption, addQuestion, addSection, duplicateQuestion, duplicateSection, findQuestion, findSection, generateId, generateOptionId, generateQuestionId, generateSectionId, moveOption, moveQuestion, moveSection, removeOption, removeQuestion, removeSection, updateOption, updateQuestion, updateSection, useBuilderState, useBuilderTheme, useDragDrop, useUndoRedo } from './chunk-ANBMT5AW.mjs';
|
|
2
|
+
export { ResponseViewer } from './chunk-5LKGCZAW.mjs';
|
|
3
3
|
export { cn } from './chunk-QQ4JZGTD.mjs';
|
|
4
|
-
export { PREVIEW_SCHEMA, ThemeEditor, ThemeEditorInner } from './chunk-
|
|
4
|
+
export { PRESET_FAMILIES, PREVIEW_SCHEMA, ThemeEditor, ThemeEditorInner, ThemeEditorThemeProvider, resolveThemeFromDOM, themeEditorDarkPreset, themeEditorLightPreset, useEditorTheme } from './chunk-IKGS2ZXV.mjs';
|
|
5
5
|
export { FieldCraftProProvider, UnlicensedOverlay, isProductionEnvironment, requireLicense, useLicense, validateLicense } from './chunk-VECQKSWS.mjs';
|
|
6
|
+
import { useState, useEffect, Suspense } from 'react';
|
|
7
|
+
import { FieldWrapper } from '@squaredr/fieldcraft-react';
|
|
8
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
9
|
+
|
|
10
|
+
function formatCurrency(amount, currency) {
|
|
11
|
+
if (amount == null) return "";
|
|
12
|
+
try {
|
|
13
|
+
return new Intl.NumberFormat(void 0, {
|
|
14
|
+
style: "currency",
|
|
15
|
+
currency: currency ?? "USD"
|
|
16
|
+
}).format(amount);
|
|
17
|
+
} catch {
|
|
18
|
+
return `${currency ?? "USD"} ${amount.toFixed(2)}`;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function ProPaymentField(props) {
|
|
22
|
+
const { field, value, error, touched, disabled, readonly, onChange, onBlur, customProps } = props;
|
|
23
|
+
const config = field.config;
|
|
24
|
+
const current = value ?? { status: "pending" };
|
|
25
|
+
const provider = config?.provider ?? "stripe";
|
|
26
|
+
const publicKey = config?.publicKey;
|
|
27
|
+
const amount = customProps?.amount ?? config?.amount;
|
|
28
|
+
const currency = config?.currency ?? "USD";
|
|
29
|
+
const directSecret = customProps?.clientSecret;
|
|
30
|
+
const onCreateIntent = customProps?.onCreatePaymentIntent;
|
|
31
|
+
const onPaymentComplete = customProps?.onPaymentComplete;
|
|
32
|
+
const serverUrl = config?.serverUrl;
|
|
33
|
+
const [clientSecret, setClientSecret] = useState(directSecret);
|
|
34
|
+
const [intentLoading, setIntentLoading] = useState(false);
|
|
35
|
+
const [intentError, setIntentError] = useState(null);
|
|
36
|
+
const mode = directSecret ? "direct" : onCreateIntent ? "callback" : serverUrl ? "url" : "setup";
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (directSecret) {
|
|
39
|
+
setClientSecret(directSecret);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (mode === "setup" || !amount || !publicKey) return;
|
|
43
|
+
if (clientSecret) return;
|
|
44
|
+
const fetchIntent = async () => {
|
|
45
|
+
setIntentLoading(true);
|
|
46
|
+
setIntentError(null);
|
|
47
|
+
try {
|
|
48
|
+
if (mode === "callback" && onCreateIntent) {
|
|
49
|
+
const result = await onCreateIntent({ amount, currency, provider, metadata: { fieldId: field.id } });
|
|
50
|
+
setClientSecret(result.clientSecret);
|
|
51
|
+
} else if (mode === "url" && serverUrl) {
|
|
52
|
+
const res = await fetch(serverUrl, {
|
|
53
|
+
method: "POST",
|
|
54
|
+
headers: { "Content-Type": "application/json" },
|
|
55
|
+
body: JSON.stringify({ amount, currency, provider, metadata: { fieldId: field.id } })
|
|
56
|
+
});
|
|
57
|
+
if (!res.ok) throw new Error(`Server error (${res.status})`);
|
|
58
|
+
const data = await res.json();
|
|
59
|
+
setClientSecret(data.clientSecret);
|
|
60
|
+
}
|
|
61
|
+
} catch (err) {
|
|
62
|
+
setIntentError(err instanceof Error ? err.message : "Failed to create payment intent");
|
|
63
|
+
} finally {
|
|
64
|
+
setIntentLoading(false);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
fetchIntent();
|
|
68
|
+
}, [mode, amount, currency, provider, publicKey, directSecret, clientSecret, onCreateIntent, serverUrl, field.id]);
|
|
69
|
+
const handleSuccess = (chargeId) => {
|
|
70
|
+
const result = { status: "succeeded", chargeId };
|
|
71
|
+
onChange(result);
|
|
72
|
+
onPaymentComplete?.(result);
|
|
73
|
+
onBlur();
|
|
74
|
+
};
|
|
75
|
+
const handleError = (message) => {
|
|
76
|
+
const result = { status: "failed", error: message };
|
|
77
|
+
onChange(result);
|
|
78
|
+
onPaymentComplete?.(result);
|
|
79
|
+
onBlur();
|
|
80
|
+
};
|
|
81
|
+
if (!publicKey) {
|
|
82
|
+
return /* @__PURE__ */ jsx(FieldWrapper, { field, error, touched, children: /* @__PURE__ */ jsx("div", { className: "rounded-lg border-2 border-dashed border-input p-4 text-center", children: /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
83
|
+
"Payment field \u2014 configure a ",
|
|
84
|
+
/* @__PURE__ */ jsx("code", { className: "bg-muted px-1 rounded text-xs", children: "publicKey" }),
|
|
85
|
+
" in the field properties panel."
|
|
86
|
+
] }) }) });
|
|
87
|
+
}
|
|
88
|
+
if (provider !== "stripe") {
|
|
89
|
+
return /* @__PURE__ */ jsx(FieldWrapper, { field, error, touched, children: /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-input bg-muted/50 p-4", children: /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
90
|
+
'Provider "',
|
|
91
|
+
provider,
|
|
92
|
+
'" \u2014 coming soon.'
|
|
93
|
+
] }) }) });
|
|
94
|
+
}
|
|
95
|
+
if (current.status === "succeeded") {
|
|
96
|
+
return /* @__PURE__ */ jsx(FieldWrapper, { field, error, touched, children: /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-input p-4", children: [
|
|
97
|
+
amount != null && /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground mb-2", children: [
|
|
98
|
+
formatCurrency(amount, currency),
|
|
99
|
+
config?.description && /* @__PURE__ */ jsxs("span", { children: [
|
|
100
|
+
" \u2014 ",
|
|
101
|
+
config.description
|
|
102
|
+
] })
|
|
103
|
+
] }),
|
|
104
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm font-medium", style: { color: "var(--success, #22c55e)" }, children: [
|
|
105
|
+
/* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, width: 16, height: 16, children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" }) }),
|
|
106
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
107
|
+
"Payment successful",
|
|
108
|
+
current.chargeId ? ` (${current.chargeId})` : ""
|
|
109
|
+
] })
|
|
110
|
+
] })
|
|
111
|
+
] }) });
|
|
112
|
+
}
|
|
113
|
+
if (current.status === "failed") {
|
|
114
|
+
return /* @__PURE__ */ jsx(FieldWrapper, { field, error, touched, children: /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-destructive/50 p-4", children: [
|
|
115
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-destructive font-medium", children: [
|
|
116
|
+
/* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, width: 16, height: 16, children: [
|
|
117
|
+
/* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
118
|
+
/* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
119
|
+
] }),
|
|
120
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
121
|
+
"Payment failed",
|
|
122
|
+
current.error ? `: ${current.error}` : ""
|
|
123
|
+
] })
|
|
124
|
+
] }),
|
|
125
|
+
/* @__PURE__ */ jsx(
|
|
126
|
+
"button",
|
|
127
|
+
{
|
|
128
|
+
type: "button",
|
|
129
|
+
className: "mt-2 text-xs text-primary hover:underline",
|
|
130
|
+
onClick: () => {
|
|
131
|
+
onChange({ status: "pending" });
|
|
132
|
+
setClientSecret(void 0);
|
|
133
|
+
},
|
|
134
|
+
children: "Retry"
|
|
135
|
+
}
|
|
136
|
+
)
|
|
137
|
+
] }) });
|
|
138
|
+
}
|
|
139
|
+
if (intentLoading || mode !== "setup" && mode !== "direct" && !clientSecret) {
|
|
140
|
+
return /* @__PURE__ */ jsx(FieldWrapper, { field, error, touched, children: /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-input p-4", children: [
|
|
141
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
|
|
142
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: "Payment" }),
|
|
143
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs bg-muted px-2 py-0.5 rounded", children: provider })
|
|
144
|
+
] }),
|
|
145
|
+
amount != null && /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground mb-3", children: [
|
|
146
|
+
"Amount: ",
|
|
147
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: formatCurrency(amount, currency) }),
|
|
148
|
+
config?.description && /* @__PURE__ */ jsxs("span", { children: [
|
|
149
|
+
" \u2014 ",
|
|
150
|
+
config.description
|
|
151
|
+
] })
|
|
152
|
+
] }),
|
|
153
|
+
intentError ? /* @__PURE__ */ jsxs("div", { children: [
|
|
154
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: intentError }),
|
|
155
|
+
/* @__PURE__ */ jsx(
|
|
156
|
+
"button",
|
|
157
|
+
{
|
|
158
|
+
type: "button",
|
|
159
|
+
className: "mt-2 text-xs text-primary hover:underline",
|
|
160
|
+
onClick: () => {
|
|
161
|
+
setIntentError(null);
|
|
162
|
+
setClientSecret(void 0);
|
|
163
|
+
},
|
|
164
|
+
children: "Retry"
|
|
165
|
+
}
|
|
166
|
+
)
|
|
167
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
168
|
+
/* @__PURE__ */ jsx("svg", { className: "animate-spin size-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10", strokeDasharray: "60", strokeDashoffset: "20" }) }),
|
|
169
|
+
/* @__PURE__ */ jsx("span", { children: "Preparing payment..." })
|
|
170
|
+
] })
|
|
171
|
+
] }) });
|
|
172
|
+
}
|
|
173
|
+
if (!clientSecret) {
|
|
174
|
+
const waitingForAmount = config?.amountField && !amount;
|
|
175
|
+
return /* @__PURE__ */ jsx(FieldWrapper, { field, error, touched, children: /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-input p-4", children: [
|
|
176
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
|
|
177
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: "Payment" }),
|
|
178
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs bg-muted px-2 py-0.5 rounded", children: provider })
|
|
179
|
+
] }),
|
|
180
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: waitingForAmount ? "Select an option above to proceed with payment." : "Provide a clientSecret via customProps, an onCreatePaymentIntent callback, or a serverUrl." })
|
|
181
|
+
] }) });
|
|
182
|
+
}
|
|
183
|
+
return /* @__PURE__ */ jsx(FieldWrapper, { field, error, touched, children: /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-input p-4", children: [
|
|
184
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-3", children: [
|
|
185
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: "Payment" }),
|
|
186
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs bg-muted px-2 py-0.5 rounded", children: provider })
|
|
187
|
+
] }),
|
|
188
|
+
amount != null && /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground mb-3", children: [
|
|
189
|
+
"Amount: ",
|
|
190
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: formatCurrency(amount, currency) }),
|
|
191
|
+
config?.description && /* @__PURE__ */ jsxs("span", { children: [
|
|
192
|
+
" \u2014 ",
|
|
193
|
+
config.description
|
|
194
|
+
] })
|
|
195
|
+
] }),
|
|
196
|
+
/* @__PURE__ */ jsx(
|
|
197
|
+
Suspense,
|
|
198
|
+
{
|
|
199
|
+
fallback: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground py-4", children: [
|
|
200
|
+
/* @__PURE__ */ jsx("svg", { className: "animate-spin size-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10", strokeDasharray: "60", strokeDashoffset: "20" }) }),
|
|
201
|
+
"Loading payment form..."
|
|
202
|
+
] }),
|
|
203
|
+
children: /* @__PURE__ */ jsx(
|
|
204
|
+
PayKitCheckout,
|
|
205
|
+
{
|
|
206
|
+
publicKey,
|
|
207
|
+
clientSecret,
|
|
208
|
+
amount,
|
|
209
|
+
currency,
|
|
210
|
+
disabled: disabled || readonly,
|
|
211
|
+
onSuccess: handleSuccess,
|
|
212
|
+
onError: handleError
|
|
213
|
+
}
|
|
214
|
+
)
|
|
215
|
+
}
|
|
216
|
+
)
|
|
217
|
+
] }) });
|
|
218
|
+
}
|
|
219
|
+
function PayKitCheckout({
|
|
220
|
+
publicKey,
|
|
221
|
+
clientSecret,
|
|
222
|
+
amount,
|
|
223
|
+
currency,
|
|
224
|
+
disabled,
|
|
225
|
+
onSuccess,
|
|
226
|
+
onError
|
|
227
|
+
}) {
|
|
228
|
+
const [PayKit, setPayKit] = useState(null);
|
|
229
|
+
const [loadError, setLoadError] = useState(null);
|
|
230
|
+
useEffect(() => {
|
|
231
|
+
let cancelled = false;
|
|
232
|
+
Promise.all([
|
|
233
|
+
// @ts-expect-error — optional peer dep, resolved at runtime
|
|
234
|
+
import('@squaredr/paykit-react'),
|
|
235
|
+
// @ts-expect-error — optional peer dep, resolved at runtime
|
|
236
|
+
import('@squaredr/paykit-stripe/client')
|
|
237
|
+
]).then(([paykit, stripe]) => {
|
|
238
|
+
if (cancelled) return;
|
|
239
|
+
setPayKit({
|
|
240
|
+
Provider: paykit.PayKitProvider,
|
|
241
|
+
Form: paykit.CheckoutForm,
|
|
242
|
+
adapter: new stripe.StripeClientAdapter(publicKey)
|
|
243
|
+
});
|
|
244
|
+
}).catch((err) => {
|
|
245
|
+
if (cancelled) return;
|
|
246
|
+
setLoadError(
|
|
247
|
+
`Failed to load payment SDK. Ensure @squaredr/paykit-react and @squaredr/paykit-stripe are installed. (${err.message})`
|
|
248
|
+
);
|
|
249
|
+
});
|
|
250
|
+
return () => {
|
|
251
|
+
cancelled = true;
|
|
252
|
+
};
|
|
253
|
+
}, [publicKey]);
|
|
254
|
+
if (loadError) {
|
|
255
|
+
return /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: loadError });
|
|
256
|
+
}
|
|
257
|
+
if (!PayKit) {
|
|
258
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground py-2", children: [
|
|
259
|
+
/* @__PURE__ */ jsx("svg", { className: "animate-spin size-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10", strokeDasharray: "60", strokeDashoffset: "20" }) }),
|
|
260
|
+
"Loading Stripe..."
|
|
261
|
+
] });
|
|
262
|
+
}
|
|
263
|
+
return /* @__PURE__ */ jsx(PayKit.Provider, { clientAdapter: PayKit.adapter, children: /* @__PURE__ */ jsx(
|
|
264
|
+
PayKit.Form,
|
|
265
|
+
{
|
|
266
|
+
clientSecret,
|
|
267
|
+
submitLabel: disabled ? "Payment disabled" : `Pay ${formatCurrency(amount, currency)}`,
|
|
268
|
+
onSuccess: (result) => onSuccess(result.chargeId),
|
|
269
|
+
onError: (err) => onError(err.message)
|
|
270
|
+
}
|
|
271
|
+
) });
|
|
272
|
+
}
|
|
273
|
+
var PRO_FIELD_OVERRIDES = {
|
|
274
|
+
payment: ProPaymentField
|
|
275
|
+
};
|
|
6
276
|
|
|
7
277
|
// src/index.ts
|
|
8
278
|
if (typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" && globalThis.process.env?.NODE_ENV !== "production") {
|
|
9
279
|
const _fc_banner = `
|
|
10
|
-
%c FieldCraft Pro %c v1.
|
|
280
|
+
%c FieldCraft Pro %c v1.6.0
|
|
11
281
|
|
|
12
282
|
%cForm Builder \xB7 Response Viewer \xB7 Theme Editor
|
|
13
283
|
|
|
@@ -24,3 +294,5 @@ Need a license? \u2192 https://squaredr.tech/products/fieldcraft/admin-pro#prici
|
|
|
24
294
|
"color:#6b7280"
|
|
25
295
|
);
|
|
26
296
|
}
|
|
297
|
+
|
|
298
|
+
export { PRO_FIELD_OVERRIDES, ProPaymentField };
|
|
@@ -2073,6 +2073,7 @@ function ResponseViewerInner({
|
|
|
2073
2073
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2074
2074
|
"div",
|
|
2075
2075
|
{
|
|
2076
|
+
"data-fcrv-root": "",
|
|
2076
2077
|
className: "flex flex-col border border-border rounded-lg overflow-hidden bg-background text-foreground",
|
|
2077
2078
|
style: { height: heightValue, width: widthValue },
|
|
2078
2079
|
children: [
|