@bacano/sdk 1.2.2 → 1.2.4
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/CONTENT_TYPE_MANAGEMENT.md +42 -2
- package/FLOWS.md +114 -0
- package/README.md +89 -18
- package/STOREFRONT_FORMS.md +50 -0
- package/STOREFRONT_PAYMENTS.md +231 -0
- package/client.d.ts +9 -1
- package/content-management-types.d.ts +44 -1
- package/content-management.cjs +26 -0
- package/content-management.js +26 -0
- package/flows.d.ts +109 -0
- package/form-conditions.d.ts +6 -0
- package/index.cjs +142 -3
- package/index.d.ts +3 -0
- package/index.js +142 -3
- package/modules/checkout.d.ts +1 -1
- package/modules/content.d.ts +1 -0
- package/package.json +1 -1
- package/react/flow-form.d.ts +9 -0
- package/react/form-scale-control.d.ts +9 -0
- package/react/forms.cjs +260 -65
- package/react/forms.d.ts +1 -0
- package/react/forms.js +254 -59
- package/react.cjs +106 -2
- package/react.js +106 -2
- package/skills/bacano-web/SKILL.md +2 -0
- package/skills/bacano-web/references/storefront.md +2 -0
- package/transport/documents.d.ts +2 -1
- package/types.d.ts +14 -1
package/react/forms.cjs
CHANGED
|
@@ -20,12 +20,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// libs/sdk/src/react/forms.tsx
|
|
21
21
|
var forms_exports = {};
|
|
22
22
|
__export(forms_exports, {
|
|
23
|
+
BacanoFlowForm: () => BacanoFlowForm,
|
|
23
24
|
BacanoForm: () => BacanoForm,
|
|
24
25
|
useBacanoForm: () => useBacanoForm,
|
|
25
26
|
useBacanoFormTracking: () => useBacanoFormTracking
|
|
26
27
|
});
|
|
27
28
|
module.exports = __toCommonJS(forms_exports);
|
|
28
|
-
var
|
|
29
|
+
var import_react5 = require("react");
|
|
29
30
|
|
|
30
31
|
// libs/sdk/src/errors.ts
|
|
31
32
|
var WebsiteError = class extends Error {
|
|
@@ -41,11 +42,124 @@ var WebsiteError = class extends Error {
|
|
|
41
42
|
}
|
|
42
43
|
};
|
|
43
44
|
|
|
44
|
-
// libs/sdk/src/
|
|
45
|
+
// libs/sdk/src/form-conditions.ts
|
|
46
|
+
function formRootFields(definition) {
|
|
47
|
+
return [
|
|
48
|
+
...definition.fields,
|
|
49
|
+
...definition.sections.flatMap((section) => section.fields),
|
|
50
|
+
...definition.steps.flatMap((step) => [
|
|
51
|
+
...step.fields,
|
|
52
|
+
...step.sections.flatMap((section) => section.fields)
|
|
53
|
+
])
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
function visibleFormFields(fields, values) {
|
|
57
|
+
return fields.flatMap((field) => [
|
|
58
|
+
field,
|
|
59
|
+
...visibleFormFields(
|
|
60
|
+
field.branches?.find((branch) => branch.value === values[field.key])?.fields ?? [],
|
|
61
|
+
values
|
|
62
|
+
)
|
|
63
|
+
]);
|
|
64
|
+
}
|
|
65
|
+
function allFormFields(fields) {
|
|
66
|
+
return fields.flatMap((field) => [
|
|
67
|
+
field,
|
|
68
|
+
...allFormFields((field.branches ?? []).flatMap((branch) => branch.fields))
|
|
69
|
+
]);
|
|
70
|
+
}
|
|
71
|
+
function activeFormValues(definition, values) {
|
|
72
|
+
const keys = new Set(
|
|
73
|
+
visibleFormFields(formRootFields(definition), values).map(
|
|
74
|
+
(field) => field.key
|
|
75
|
+
)
|
|
76
|
+
);
|
|
77
|
+
return Object.fromEntries(
|
|
78
|
+
Object.entries(values).filter(([key]) => keys.has(key))
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// libs/sdk/src/react/form-scale-control.tsx
|
|
45
83
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
84
|
+
function FormScaleControl({
|
|
85
|
+
field,
|
|
86
|
+
id,
|
|
87
|
+
value,
|
|
88
|
+
onChange,
|
|
89
|
+
className
|
|
90
|
+
}) {
|
|
91
|
+
const scale = field.scale;
|
|
92
|
+
if (!scale) return null;
|
|
93
|
+
const options = Array.from(
|
|
94
|
+
{ length: Math.max(0, Math.min(11, scale.max - scale.min + 1)) },
|
|
95
|
+
(_, index) => scale.min + index
|
|
96
|
+
);
|
|
97
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
98
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
99
|
+
"div",
|
|
100
|
+
{
|
|
101
|
+
role: "radiogroup",
|
|
102
|
+
"aria-labelledby": `${id}-label`,
|
|
103
|
+
style: { display: "flex", flexWrap: "wrap", gap: 12 },
|
|
104
|
+
children: options.map((number) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
105
|
+
"label",
|
|
106
|
+
{
|
|
107
|
+
style: { display: "inline-flex", alignItems: "center", gap: 4 },
|
|
108
|
+
children: [
|
|
109
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
110
|
+
"input",
|
|
111
|
+
{
|
|
112
|
+
className,
|
|
113
|
+
type: "radio",
|
|
114
|
+
name: id,
|
|
115
|
+
value: String(number),
|
|
116
|
+
checked: value === String(number),
|
|
117
|
+
required: field.required,
|
|
118
|
+
onChange: () => onChange(String(number)),
|
|
119
|
+
"aria-label": `${number} de ${scale.max}`
|
|
120
|
+
}
|
|
121
|
+
),
|
|
122
|
+
scale.display === "stars" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
123
|
+
"span",
|
|
124
|
+
{
|
|
125
|
+
"aria-hidden": "true",
|
|
126
|
+
style: {
|
|
127
|
+
fontSize: 24,
|
|
128
|
+
color: Number(value) >= number ? "var(--accent, #b45309)" : "var(--muted, #6b7280)"
|
|
129
|
+
},
|
|
130
|
+
children: "\u2605"
|
|
131
|
+
}
|
|
132
|
+
) : number
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
number
|
|
136
|
+
))
|
|
137
|
+
}
|
|
138
|
+
),
|
|
139
|
+
(scale.minLabel || scale.maxLabel) && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { children: [
|
|
140
|
+
scale.minLabel,
|
|
141
|
+
" \u2014 ",
|
|
142
|
+
scale.maxLabel
|
|
143
|
+
] })
|
|
144
|
+
] });
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// libs/sdk/src/react/form-field-control.tsx
|
|
148
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
46
149
|
function BacanoFormFieldControl(props) {
|
|
47
150
|
const { field, className, value, onChange } = props;
|
|
48
151
|
const controlId = props.id ?? field.key;
|
|
152
|
+
if (field.type === "scale")
|
|
153
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
154
|
+
FormScaleControl,
|
|
155
|
+
{
|
|
156
|
+
field,
|
|
157
|
+
id: controlId,
|
|
158
|
+
value,
|
|
159
|
+
onChange,
|
|
160
|
+
className
|
|
161
|
+
}
|
|
162
|
+
);
|
|
49
163
|
const common = {
|
|
50
164
|
id: controlId,
|
|
51
165
|
name: field.key,
|
|
@@ -53,7 +167,7 @@ function BacanoFormFieldControl(props) {
|
|
|
53
167
|
className
|
|
54
168
|
};
|
|
55
169
|
if (field.type === "textarea") {
|
|
56
|
-
return /* @__PURE__ */ (0,
|
|
170
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
57
171
|
"textarea",
|
|
58
172
|
{
|
|
59
173
|
...common,
|
|
@@ -67,7 +181,7 @@ function BacanoFormFieldControl(props) {
|
|
|
67
181
|
}
|
|
68
182
|
if (field.type === "select" || field.type === "multi_select") {
|
|
69
183
|
const isMultiple = field.type === "multi_select";
|
|
70
|
-
return /* @__PURE__ */ (0,
|
|
184
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
71
185
|
"select",
|
|
72
186
|
{
|
|
73
187
|
...common,
|
|
@@ -80,15 +194,15 @@ function BacanoFormFieldControl(props) {
|
|
|
80
194
|
) : event.target.value
|
|
81
195
|
),
|
|
82
196
|
children: [
|
|
83
|
-
!isMultiple ? /* @__PURE__ */ (0,
|
|
84
|
-
(field.options ?? []).map((option) => /* @__PURE__ */ (0,
|
|
197
|
+
!isMultiple ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: "", children: field.placeholder ?? "Selecciona una opci\xF3n" }) : null,
|
|
198
|
+
(field.options ?? []).map((option) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: option.value, children: option.label }, option.value))
|
|
85
199
|
]
|
|
86
200
|
}
|
|
87
201
|
);
|
|
88
202
|
}
|
|
89
203
|
if (field.type === "radio") {
|
|
90
|
-
return /* @__PURE__ */ (0,
|
|
91
|
-
/* @__PURE__ */ (0,
|
|
204
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { role: "radiogroup", "aria-labelledby": `${controlId}-label`, children: (field.options ?? []).map((option) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { children: [
|
|
205
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
92
206
|
"input",
|
|
93
207
|
{
|
|
94
208
|
type: "radio",
|
|
@@ -103,7 +217,7 @@ function BacanoFormFieldControl(props) {
|
|
|
103
217
|
] }, option.value)) });
|
|
104
218
|
}
|
|
105
219
|
if (field.type === "checkbox") {
|
|
106
|
-
return /* @__PURE__ */ (0,
|
|
220
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
107
221
|
"input",
|
|
108
222
|
{
|
|
109
223
|
...common,
|
|
@@ -113,7 +227,7 @@ function BacanoFormFieldControl(props) {
|
|
|
113
227
|
}
|
|
114
228
|
);
|
|
115
229
|
}
|
|
116
|
-
return /* @__PURE__ */ (0,
|
|
230
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
117
231
|
"input",
|
|
118
232
|
{
|
|
119
233
|
...common,
|
|
@@ -130,13 +244,13 @@ function BacanoFormFieldControl(props) {
|
|
|
130
244
|
}
|
|
131
245
|
|
|
132
246
|
// libs/sdk/src/react/form-sections.tsx
|
|
133
|
-
var
|
|
247
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
134
248
|
function FormFields(props) {
|
|
135
249
|
return props.fields.map((field) => {
|
|
136
250
|
const controlId = `${props.idPrefix}-${field.key}`;
|
|
137
251
|
const value = props.values[field.key] ?? (field.type === "checkbox" ? false : field.type === "multi_select" ? [] : "");
|
|
138
|
-
return /* @__PURE__ */ (0,
|
|
139
|
-
/* @__PURE__ */ (0,
|
|
252
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: props.classNames?.field, children: [
|
|
253
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
140
254
|
"label",
|
|
141
255
|
{
|
|
142
256
|
id: `${controlId}-label`,
|
|
@@ -145,7 +259,7 @@ function FormFields(props) {
|
|
|
145
259
|
children: field.label
|
|
146
260
|
}
|
|
147
261
|
),
|
|
148
|
-
/* @__PURE__ */ (0,
|
|
262
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
149
263
|
BacanoFormFieldControl,
|
|
150
264
|
{
|
|
151
265
|
field,
|
|
@@ -155,15 +269,18 @@ function FormFields(props) {
|
|
|
155
269
|
onChange: (nextValue) => props.onChange(field.key, nextValue)
|
|
156
270
|
}
|
|
157
271
|
),
|
|
158
|
-
field.helpText ? /* @__PURE__ */ (0,
|
|
272
|
+
field.helpText ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: props.classNames?.helpText, children: field.helpText }) : null,
|
|
273
|
+
field.branches?.map(
|
|
274
|
+
(branch) => branch.value === props.values[field.key] ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { "data-bacano-form-branch": branch.value, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FormFields, { ...props, fields: branch.fields }) }, branch.value) : null
|
|
275
|
+
)
|
|
159
276
|
] }, field.key);
|
|
160
277
|
});
|
|
161
278
|
}
|
|
162
279
|
function FormSections(props) {
|
|
163
|
-
return props.sections.map((section) => /* @__PURE__ */ (0,
|
|
164
|
-
/* @__PURE__ */ (0,
|
|
165
|
-
section.description ? /* @__PURE__ */ (0,
|
|
166
|
-
/* @__PURE__ */ (0,
|
|
280
|
+
return props.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: props.classNames?.section, children: [
|
|
281
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: props.classNames?.sectionTitle, children: section.title }),
|
|
282
|
+
section.description ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: props.classNames?.sectionDescription, children: section.description }) : null,
|
|
283
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
167
284
|
FormFields,
|
|
168
285
|
{
|
|
169
286
|
fields: section.fields,
|
|
@@ -303,8 +420,82 @@ function useBacanoState() {
|
|
|
303
420
|
return (0, import_react3.useContext)(BacanoReactContext);
|
|
304
421
|
}
|
|
305
422
|
|
|
423
|
+
// libs/sdk/src/react/flow-form.tsx
|
|
424
|
+
var import_react4 = require("react");
|
|
425
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
426
|
+
function BacanoFlowForm({
|
|
427
|
+
form,
|
|
428
|
+
onSubmit,
|
|
429
|
+
onRefresh,
|
|
430
|
+
classNames
|
|
431
|
+
}) {
|
|
432
|
+
const id = (0, import_react4.useId)();
|
|
433
|
+
const [values, setValues] = (0, import_react4.useState)(
|
|
434
|
+
() => activeFormValues(form.definition, form.initialValues ?? {})
|
|
435
|
+
);
|
|
436
|
+
const [error, setError] = (0, import_react4.useState)("");
|
|
437
|
+
const [busy, setBusy] = (0, import_react4.useState)(false);
|
|
438
|
+
const common = {
|
|
439
|
+
idPrefix: id,
|
|
440
|
+
values,
|
|
441
|
+
classNames,
|
|
442
|
+
onChange: (key, value) => setValues(
|
|
443
|
+
(current) => activeFormValues(form.definition, { ...current, [key]: value })
|
|
444
|
+
)
|
|
445
|
+
};
|
|
446
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
447
|
+
"form",
|
|
448
|
+
{
|
|
449
|
+
className: classNames?.root,
|
|
450
|
+
onSubmit: async (event) => {
|
|
451
|
+
event.preventDefault();
|
|
452
|
+
if (busy) return;
|
|
453
|
+
setBusy(true);
|
|
454
|
+
setError("");
|
|
455
|
+
try {
|
|
456
|
+
await onSubmit(activeFormValues(form.definition, values), form);
|
|
457
|
+
} catch (reason) {
|
|
458
|
+
setError(
|
|
459
|
+
reason instanceof Error ? reason.message : "No fue posible enviar la respuesta."
|
|
460
|
+
);
|
|
461
|
+
} finally {
|
|
462
|
+
setBusy(false);
|
|
463
|
+
}
|
|
464
|
+
},
|
|
465
|
+
children: [
|
|
466
|
+
form.correction && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { role: "status", children: [
|
|
467
|
+
"Cargamos tus respuestas anteriores para que puedas corregirlas.",
|
|
468
|
+
form.correction.formChanged && " Las preguntas cambiaron; revisa los campos antes de enviar."
|
|
469
|
+
] }),
|
|
470
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FormFields, { ...common, fields: form.definition.fields }),
|
|
471
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FormSections, { ...common, sections: form.definition.sections }),
|
|
472
|
+
form.definition.steps.map((step) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: classNames?.section, children: [
|
|
473
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: classNames?.sectionTitle, children: step.title }),
|
|
474
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { children: step.description }),
|
|
475
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FormFields, { ...common, fields: step.fields }),
|
|
476
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FormSections, { ...common, sections: step.sections })
|
|
477
|
+
] }, step.key)),
|
|
478
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { role: "alert", children: [
|
|
479
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { children: error === "FLOW_FORM_CHANGED" ? "El formulario cambi\xF3. Actualiza las preguntas y revisa tus respuestas antes de enviarlas." : error }),
|
|
480
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
481
|
+
"button",
|
|
482
|
+
{
|
|
483
|
+
type: "button",
|
|
484
|
+
onClick: () => void onRefresh().catch(
|
|
485
|
+
() => setError("No se pudo actualizar el formulario.")
|
|
486
|
+
),
|
|
487
|
+
children: "Actualizar preguntas sin borrar mis respuestas"
|
|
488
|
+
}
|
|
489
|
+
)
|
|
490
|
+
] }),
|
|
491
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "submit", disabled: busy, className: classNames?.button, children: busy ? "Guardando\u2026" : form.definition.submitLabel })
|
|
492
|
+
]
|
|
493
|
+
}
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
|
|
306
497
|
// libs/sdk/src/react/forms.tsx
|
|
307
|
-
var
|
|
498
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
308
499
|
var EMPTY_FORM_FIELDS = [];
|
|
309
500
|
var EMPTY_FORM_SECTIONS = [];
|
|
310
501
|
var EMPTY_FORM_STEPS = [];
|
|
@@ -316,12 +507,12 @@ function useBacanoForm(formKey, options) {
|
|
|
316
507
|
} = useBacanoState();
|
|
317
508
|
const enabled = options?.enabled ?? true;
|
|
318
509
|
const initialForm = options?.initialForm?.key === formKey ? options.initialForm : null;
|
|
319
|
-
const [form, setForm] = (0,
|
|
320
|
-
const formRef = (0,
|
|
321
|
-
const requestVersion = (0,
|
|
322
|
-
const [loading, setLoading] = (0,
|
|
323
|
-
const [error, setError] = (0,
|
|
324
|
-
const load = (0,
|
|
510
|
+
const [form, setForm] = (0, import_react5.useState)(initialForm);
|
|
511
|
+
const formRef = (0, import_react5.useRef)(initialForm);
|
|
512
|
+
const requestVersion = (0, import_react5.useRef)(0);
|
|
513
|
+
const [loading, setLoading] = (0, import_react5.useState)(enabled && !initialForm);
|
|
514
|
+
const [error, setError] = (0, import_react5.useState)(null);
|
|
515
|
+
const load = (0, import_react5.useCallback)(
|
|
325
516
|
async (force = false) => {
|
|
326
517
|
if (!enabled || !client) return;
|
|
327
518
|
const version = ++requestVersion.current;
|
|
@@ -344,7 +535,7 @@ function useBacanoForm(formKey, options) {
|
|
|
344
535
|
},
|
|
345
536
|
[client, enabled, formKey]
|
|
346
537
|
);
|
|
347
|
-
(0,
|
|
538
|
+
(0, import_react5.useEffect)(() => {
|
|
348
539
|
if (!enabled) {
|
|
349
540
|
formRef.current = null;
|
|
350
541
|
setForm(null);
|
|
@@ -365,44 +556,45 @@ function useBacanoForm(formKey, options) {
|
|
|
365
556
|
};
|
|
366
557
|
}
|
|
367
558
|
function BacanoFormInstance(props) {
|
|
368
|
-
const reactId = (0,
|
|
559
|
+
const reactId = (0, import_react5.useId)();
|
|
369
560
|
const idPrefix = `${props.formKey}-${reactId.replace(/:/g, "")}`;
|
|
370
561
|
const { client } = useBacanoState();
|
|
371
562
|
const { form, loading, error } = useBacanoForm(props.formKey, {
|
|
372
563
|
initialForm: props.initialForm
|
|
373
564
|
});
|
|
374
|
-
const [internalValues, setValues] = (0,
|
|
375
|
-
const [step, setStep] = (0,
|
|
376
|
-
const [submitting, setSubmitting] = (0,
|
|
377
|
-
const [submitted, setSubmitted] = (0,
|
|
378
|
-
const [submissionError, setSubmissionError] = (0,
|
|
379
|
-
const [honeypot, setHoneypot] = (0,
|
|
565
|
+
const [internalValues, setValues] = (0, import_react5.useState)({});
|
|
566
|
+
const [step, setStep] = (0, import_react5.useState)(0);
|
|
567
|
+
const [submitting, setSubmitting] = (0, import_react5.useState)(false);
|
|
568
|
+
const [submitted, setSubmitted] = (0, import_react5.useState)(false);
|
|
569
|
+
const [submissionError, setSubmissionError] = (0, import_react5.useState)(null);
|
|
570
|
+
const [honeypot, setHoneypot] = (0, import_react5.useState)("");
|
|
380
571
|
const tracking = useBacanoFormTracking(props.formKey, {
|
|
381
572
|
visible: (props.visible ?? true) && !loading && form?.status === "ACTIVE" && !submitted
|
|
382
573
|
});
|
|
383
|
-
const idempotencyKey = (0,
|
|
574
|
+
const idempotencyKey = (0, import_react5.useRef)(crypto.randomUUID());
|
|
384
575
|
const fields = form?.definition.fields ?? EMPTY_FORM_FIELDS;
|
|
385
576
|
const sections = form?.definition.sections ?? EMPTY_FORM_SECTIONS;
|
|
386
577
|
const steps = form?.definition.steps ?? EMPTY_FORM_STEPS;
|
|
387
|
-
const fieldKeys = (0,
|
|
578
|
+
const fieldKeys = (0, import_react5.useMemo)(
|
|
388
579
|
() => new Set(
|
|
389
|
-
[
|
|
580
|
+
allFormFields([
|
|
390
581
|
...fields,
|
|
391
582
|
...sections.flatMap((section) => section.fields),
|
|
392
583
|
...steps.flatMap((formStep) => [
|
|
393
584
|
...formStep.fields,
|
|
394
585
|
...formStep.sections.flatMap((section) => section.fields)
|
|
395
586
|
])
|
|
396
|
-
].map((field) => field.key)
|
|
587
|
+
]).map((field) => field.key)
|
|
397
588
|
),
|
|
398
589
|
[fields, sections, steps]
|
|
399
590
|
);
|
|
400
|
-
const
|
|
591
|
+
const rawValues = Object.fromEntries(
|
|
401
592
|
Object.entries(props.values ?? internalValues).filter(
|
|
402
593
|
([key]) => fieldKeys.has(key)
|
|
403
594
|
)
|
|
404
595
|
);
|
|
405
|
-
(
|
|
596
|
+
const values = form ? activeFormValues(form.definition, props.values ?? internalValues) : rawValues;
|
|
597
|
+
(0, import_react5.useEffect)(() => {
|
|
406
598
|
setStep(0);
|
|
407
599
|
setValues(
|
|
408
600
|
(current) => Object.fromEntries(
|
|
@@ -414,15 +606,15 @@ function BacanoFormInstance(props) {
|
|
|
414
606
|
setHoneypot("");
|
|
415
607
|
idempotencyKey.current = crypto.randomUUID();
|
|
416
608
|
}, [fieldKeys, form?.version]);
|
|
417
|
-
if (loading) return /* @__PURE__ */ (0,
|
|
609
|
+
if (loading) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: props.loadingFallback ?? null });
|
|
418
610
|
if (error && !form)
|
|
419
|
-
return /* @__PURE__ */ (0,
|
|
420
|
-
if (!form) return /* @__PURE__ */ (0,
|
|
611
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: props.errorFallback?.(error) ?? props.unavailableFallback ?? null });
|
|
612
|
+
if (!form) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: props.unavailableFallback ?? null });
|
|
421
613
|
if (form.status === "PAUSED") {
|
|
422
|
-
return /* @__PURE__ */ (0,
|
|
614
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: props.classNames?.message, "data-bacano-form-unavailable": true, children: props.unavailableFallback ?? form.definition.unavailableMessage });
|
|
423
615
|
}
|
|
424
616
|
if (submitted) {
|
|
425
|
-
return /* @__PURE__ */ (0,
|
|
617
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: props.classNames?.message, "data-bacano-form-success": true, children: form.definition.successMessage });
|
|
426
618
|
}
|
|
427
619
|
const isMultiStep = steps.length > 0;
|
|
428
620
|
const activeStep = isMultiStep ? steps[step] : null;
|
|
@@ -430,7 +622,10 @@ function BacanoFormInstance(props) {
|
|
|
430
622
|
const setFieldValue = (key, value) => {
|
|
431
623
|
if (value !== "" && value !== false && (!Array.isArray(value) || value.length > 0))
|
|
432
624
|
tracking.start();
|
|
433
|
-
const nextValues =
|
|
625
|
+
const nextValues = activeFormValues(form.definition, {
|
|
626
|
+
...values,
|
|
627
|
+
[key]: value
|
|
628
|
+
});
|
|
434
629
|
setValues(nextValues);
|
|
435
630
|
props.onValuesChange?.(nextValues);
|
|
436
631
|
};
|
|
@@ -486,7 +681,7 @@ function BacanoFormInstance(props) {
|
|
|
486
681
|
setSubmitting(false);
|
|
487
682
|
}
|
|
488
683
|
};
|
|
489
|
-
return /* @__PURE__ */ (0,
|
|
684
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
490
685
|
"form",
|
|
491
686
|
{
|
|
492
687
|
noValidate: true,
|
|
@@ -495,7 +690,7 @@ function BacanoFormInstance(props) {
|
|
|
495
690
|
"data-bacano-form-version": form.version,
|
|
496
691
|
onSubmit: (event) => void submit(event),
|
|
497
692
|
children: [
|
|
498
|
-
/* @__PURE__ */ (0,
|
|
693
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
499
694
|
"div",
|
|
500
695
|
{
|
|
501
696
|
"aria-hidden": "true",
|
|
@@ -507,8 +702,8 @@ function BacanoFormInstance(props) {
|
|
|
507
702
|
clip: "rect(0 0 0 0)"
|
|
508
703
|
},
|
|
509
704
|
children: [
|
|
510
|
-
/* @__PURE__ */ (0,
|
|
511
|
-
/* @__PURE__ */ (0,
|
|
705
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("label", { htmlFor: `${form.key}-company-website`, children: "Empresa" }),
|
|
706
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
512
707
|
"input",
|
|
513
708
|
{
|
|
514
709
|
id: `${form.key}-company-website`,
|
|
@@ -522,12 +717,12 @@ function BacanoFormInstance(props) {
|
|
|
522
717
|
]
|
|
523
718
|
}
|
|
524
719
|
),
|
|
525
|
-
/* @__PURE__ */ (0,
|
|
526
|
-
form.description ? /* @__PURE__ */ (0,
|
|
527
|
-
activeStep ? /* @__PURE__ */ (0,
|
|
528
|
-
/* @__PURE__ */ (0,
|
|
529
|
-
activeStep.description ? /* @__PURE__ */ (0,
|
|
530
|
-
/* @__PURE__ */ (0,
|
|
720
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { className: props.classNames?.title, children: form.name }),
|
|
721
|
+
form.description ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: props.classNames?.description, children: form.description }) : null,
|
|
722
|
+
activeStep ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: props.classNames?.step, "data-bacano-form-step": true, children: [
|
|
723
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { className: props.classNames?.stepTitle, children: activeStep.title }),
|
|
724
|
+
activeStep.description ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: props.classNames?.stepDescription, children: activeStep.description }) : null,
|
|
725
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
531
726
|
FormFields,
|
|
532
727
|
{
|
|
533
728
|
fields: activeStep.fields,
|
|
@@ -537,7 +732,7 @@ function BacanoFormInstance(props) {
|
|
|
537
732
|
onChange: setFieldValue
|
|
538
733
|
}
|
|
539
734
|
),
|
|
540
|
-
/* @__PURE__ */ (0,
|
|
735
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
541
736
|
FormSections,
|
|
542
737
|
{
|
|
543
738
|
sections: activeStep.sections,
|
|
@@ -547,8 +742,8 @@ function BacanoFormInstance(props) {
|
|
|
547
742
|
onChange: setFieldValue
|
|
548
743
|
}
|
|
549
744
|
)
|
|
550
|
-
] }) : /* @__PURE__ */ (0,
|
|
551
|
-
/* @__PURE__ */ (0,
|
|
745
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
746
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
552
747
|
FormFields,
|
|
553
748
|
{
|
|
554
749
|
fields,
|
|
@@ -558,7 +753,7 @@ function BacanoFormInstance(props) {
|
|
|
558
753
|
onChange: setFieldValue
|
|
559
754
|
}
|
|
560
755
|
),
|
|
561
|
-
/* @__PURE__ */ (0,
|
|
756
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
562
757
|
FormSections,
|
|
563
758
|
{
|
|
564
759
|
sections,
|
|
@@ -569,8 +764,8 @@ function BacanoFormInstance(props) {
|
|
|
569
764
|
}
|
|
570
765
|
)
|
|
571
766
|
] }),
|
|
572
|
-
/* @__PURE__ */ (0,
|
|
573
|
-
isMultiStep && step > 0 ? /* @__PURE__ */ (0,
|
|
767
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: props.classNames?.actions, children: [
|
|
768
|
+
isMultiStep && step > 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
574
769
|
"button",
|
|
575
770
|
{
|
|
576
771
|
type: "button",
|
|
@@ -578,7 +773,7 @@ function BacanoFormInstance(props) {
|
|
|
578
773
|
children: "Anterior"
|
|
579
774
|
}
|
|
580
775
|
) : null,
|
|
581
|
-
/* @__PURE__ */ (0,
|
|
776
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
582
777
|
"button",
|
|
583
778
|
{
|
|
584
779
|
type: "submit",
|
|
@@ -588,7 +783,7 @@ function BacanoFormInstance(props) {
|
|
|
588
783
|
}
|
|
589
784
|
)
|
|
590
785
|
] }),
|
|
591
|
-
submissionError ? /* @__PURE__ */ (0,
|
|
786
|
+
submissionError ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
592
787
|
"div",
|
|
593
788
|
{
|
|
594
789
|
role: "alert",
|
|
@@ -602,5 +797,5 @@ function BacanoFormInstance(props) {
|
|
|
602
797
|
);
|
|
603
798
|
}
|
|
604
799
|
function BacanoForm(props) {
|
|
605
|
-
return /* @__PURE__ */ (0,
|
|
800
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(BacanoFormInstance, { ...props }, props.formKey);
|
|
606
801
|
}
|
package/react/forms.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
import type { WebsiteFormResponseResult, WebsitePublishedForm } from "../types";
|
|
3
|
+
export { BacanoFlowForm } from "./flow-form";
|
|
3
4
|
export { useBacanoFormTracking } from "./form-tracking";
|
|
4
5
|
export type BacanoFormValues = Record<string, string | string[] | boolean>;
|
|
5
6
|
export interface UseBacanoFormOptions {
|