@fixture-inc/forms-react 0.1.0-beta.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/index.cjs ADDED
@@ -0,0 +1,503 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ Field: () => Field,
34
+ FixtureFormsContext: () => FixtureFormsContext,
35
+ Form: () => Form,
36
+ FormClient: () => import_forms_browser2.FormClient,
37
+ useFixtureForm: () => useFixtureForm,
38
+ useFixtureFormsContext: () => useFixtureFormsContext,
39
+ useVisitorId: () => useVisitorId
40
+ });
41
+ module.exports = __toCommonJS(index_exports);
42
+
43
+ // src/hooks.ts
44
+ var import_react2 = require("react");
45
+ var import_forms_core = require("@fixture-inc/forms-core");
46
+ var import_forms_browser = require("@fixture-inc/forms-browser");
47
+
48
+ // src/context.ts
49
+ var import_react = require("react");
50
+ var FixtureFormsContext = (0, import_react.createContext)(null);
51
+ function useFixtureFormsContext() {
52
+ return (0, import_react.useContext)(FixtureFormsContext);
53
+ }
54
+
55
+ // src/hooks.ts
56
+ function useFixtureForm(formId, options = {}) {
57
+ const {
58
+ apiUrl,
59
+ enabled = true,
60
+ initialData,
61
+ fetcher,
62
+ debug,
63
+ onSuccess,
64
+ onError
65
+ } = options;
66
+ const context = useFixtureFormsContext();
67
+ const clientRef = (0, import_react2.useRef)(null);
68
+ if (!clientRef.current) {
69
+ clientRef.current = context?.client ?? new import_forms_browser.FormClient({
70
+ apiUrl: apiUrl ?? context?.apiUrl,
71
+ debug: debug ?? context?.debug
72
+ });
73
+ }
74
+ const client = clientRef.current;
75
+ const [status, setStatus] = (0, import_react2.useState)(
76
+ initialData ? "ready" : "idle"
77
+ );
78
+ const [form, setForm] = (0, import_react2.useState)(initialData?.form ?? null);
79
+ const [nonce, setNonce] = (0, import_react2.useState)(initialData?.nonce ?? null);
80
+ const [values, setValuesState] = (0, import_react2.useState)(() => {
81
+ if (initialData?.form) {
82
+ return initializeValues(initialData.form);
83
+ }
84
+ return {};
85
+ });
86
+ const [errors, setErrors] = (0, import_react2.useState)({});
87
+ const [error, setError] = (0, import_react2.useState)(null);
88
+ const [result, setResult] = (0, import_react2.useState)(null);
89
+ function initializeValues(formData) {
90
+ const vals = {};
91
+ for (const field of formData.fields) {
92
+ vals[field.id] = (0, import_forms_core.getDefaultValue)(field.type);
93
+ }
94
+ return vals;
95
+ }
96
+ const fetchForm = (0, import_react2.useCallback)(async () => {
97
+ if (!formId) return;
98
+ setStatus("loading");
99
+ setError(null);
100
+ try {
101
+ let response;
102
+ if (fetcher) {
103
+ response = await fetcher(formId);
104
+ } else {
105
+ response = await client.fetchForm(formId);
106
+ }
107
+ setForm(response.form);
108
+ setNonce(response.nonce);
109
+ setValuesState(initializeValues(response.form));
110
+ setErrors({});
111
+ setStatus("ready");
112
+ } catch (err) {
113
+ const normalized = (0, import_forms_browser.normalizeError)(err);
114
+ setError(normalized.message);
115
+ setStatus("error");
116
+ if (onError) {
117
+ onError(normalized);
118
+ }
119
+ }
120
+ }, [formId, client, fetcher, onError]);
121
+ (0, import_react2.useEffect)(() => {
122
+ if (enabled && !initialData) {
123
+ fetchForm();
124
+ }
125
+ }, [enabled, initialData, fetchForm]);
126
+ const setValue = (0, import_react2.useCallback)((fieldId, value) => {
127
+ setValuesState((prev) => ({ ...prev, [fieldId]: value }));
128
+ setErrors((prev) => {
129
+ const next = { ...prev };
130
+ delete next[fieldId];
131
+ return next;
132
+ });
133
+ }, []);
134
+ const setValuesFunc = (0, import_react2.useCallback)((newValues) => {
135
+ setValuesState((prev) => ({ ...prev, ...newValues }));
136
+ }, []);
137
+ const getFieldValue = (0, import_react2.useCallback)(
138
+ (fieldId) => {
139
+ return values[fieldId];
140
+ },
141
+ [values]
142
+ );
143
+ const submit = (0, import_react2.useCallback)(async () => {
144
+ if (!form || !nonce) {
145
+ setError("Form not loaded");
146
+ return;
147
+ }
148
+ const validationErrors = (0, import_forms_core.validateForm)(
149
+ form.fields,
150
+ values
151
+ );
152
+ if (validationErrors.length > 0) {
153
+ setErrors((0, import_forms_core.errorsToRecord)(validationErrors));
154
+ return;
155
+ }
156
+ setStatus("submitting");
157
+ setError(null);
158
+ try {
159
+ const { result: submitResult, newNonce } = await client.submitWithRetry(
160
+ formId,
161
+ form,
162
+ values,
163
+ { nonce }
164
+ );
165
+ if (newNonce) {
166
+ setNonce(newNonce);
167
+ }
168
+ if (submitResult.redirectUrl && typeof window !== "undefined") {
169
+ window.location.href = submitResult.redirectUrl;
170
+ return;
171
+ }
172
+ setResult(submitResult);
173
+ setStatus("success");
174
+ if (onSuccess) {
175
+ onSuccess(submitResult);
176
+ }
177
+ } catch (err) {
178
+ const normalized = (0, import_forms_browser.normalizeError)(err);
179
+ setError(normalized.message);
180
+ setStatus("ready");
181
+ if (onError) {
182
+ onError(normalized);
183
+ }
184
+ }
185
+ }, [form, nonce, values, formId, client, onSuccess, onError]);
186
+ const reset = (0, import_react2.useCallback)(() => {
187
+ if (form) {
188
+ setValuesState(initializeValues(form));
189
+ }
190
+ setErrors({});
191
+ setError(null);
192
+ setResult(null);
193
+ setStatus(form ? "ready" : "idle");
194
+ }, [form]);
195
+ const getFieldProps = (0, import_react2.useCallback)(
196
+ (fieldId) => {
197
+ const field = form?.fields.find((f) => f.id === fieldId);
198
+ const value = values[fieldId];
199
+ const isCheckbox = field?.type === "checkbox";
200
+ return {
201
+ id: `ff-${fieldId}`,
202
+ name: fieldId,
203
+ value: isCheckbox ? "true" : value ?? "",
204
+ checked: isCheckbox ? value : void 0,
205
+ required: field?.required,
206
+ type: field?.type === "email" ? "email" : field?.type === "phone" ? "tel" : void 0,
207
+ onChange: (e) => {
208
+ if (isCheckbox) {
209
+ setValue(fieldId, e.target.checked);
210
+ } else {
211
+ setValue(fieldId, e.target.value);
212
+ }
213
+ }
214
+ };
215
+ },
216
+ [form, values, setValue]
217
+ );
218
+ const fields = (0, import_react2.useMemo)(() => form?.fields ?? [], [form]);
219
+ return {
220
+ form,
221
+ fields,
222
+ status,
223
+ error,
224
+ result,
225
+ values,
226
+ errors,
227
+ getFieldValue,
228
+ setValue,
229
+ setValues: setValuesFunc,
230
+ submit,
231
+ reset,
232
+ refetch: fetchForm,
233
+ getFieldProps
234
+ };
235
+ }
236
+ function useVisitorId() {
237
+ const [visitorId, setVisitorId] = (0, import_react2.useState)(null);
238
+ (0, import_react2.useEffect)(() => {
239
+ import("@fixture-inc/forms-browser").then(({ getVisitorId }) => {
240
+ setVisitorId(getVisitorId());
241
+ });
242
+ }, []);
243
+ return visitorId;
244
+ }
245
+
246
+ // src/components/Field.tsx
247
+ var import_jsx_runtime = require("react/jsx-runtime");
248
+ function Field({
249
+ field,
250
+ value,
251
+ error,
252
+ onChange
253
+ }) {
254
+ const id = `ff-${field.id}`;
255
+ const required = field.required;
256
+ const baseInputProps = {
257
+ id,
258
+ name: field.id,
259
+ required,
260
+ "aria-invalid": error ? true : void 0,
261
+ "aria-describedby": error ? `${id}-error` : void 0
262
+ };
263
+ let input;
264
+ switch (field.type) {
265
+ case "textarea":
266
+ input = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
267
+ "textarea",
268
+ {
269
+ ...baseInputProps,
270
+ className: "ff-textarea",
271
+ placeholder: field.placeholder,
272
+ value: value ?? "",
273
+ onChange: (e) => onChange(e.target.value)
274
+ }
275
+ );
276
+ break;
277
+ case "dropdown":
278
+ input = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
279
+ "select",
280
+ {
281
+ ...baseInputProps,
282
+ className: "ff-select",
283
+ value: value ?? "",
284
+ onChange: (e) => onChange(e.target.value),
285
+ children: [
286
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "", children: "Select..." }),
287
+ field.options?.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: opt, children: opt }, opt))
288
+ ]
289
+ }
290
+ );
291
+ break;
292
+ case "checkbox":
293
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "ff-field", children: [
294
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "ff-checkbox-wrapper", children: [
295
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
296
+ "input",
297
+ {
298
+ ...baseInputProps,
299
+ type: "checkbox",
300
+ className: "ff-checkbox",
301
+ checked: value ?? false,
302
+ onChange: (e) => onChange(e.target.checked)
303
+ }
304
+ ),
305
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: id, className: "ff-checkbox-label", children: [
306
+ field.label,
307
+ required && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "ff-required", children: "*" })
308
+ ] })
309
+ ] }),
310
+ error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { id: `${id}-error`, className: "ff-field-error", role: "alert", children: error })
311
+ ] });
312
+ case "radio":
313
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "ff-field", children: [
314
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "ff-label", children: [
315
+ field.label,
316
+ required && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "ff-required", children: "*" })
317
+ ] }),
318
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "ff-radio-group", role: "radiogroup", "aria-labelledby": id, children: field.options?.map((opt, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "ff-radio-wrapper", children: [
319
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
320
+ "input",
321
+ {
322
+ type: "radio",
323
+ name: field.id,
324
+ value: opt,
325
+ className: "ff-radio",
326
+ checked: value === opt,
327
+ required: i === 0 && required,
328
+ onChange: () => onChange(opt)
329
+ }
330
+ ),
331
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "ff-radio-label", children: opt })
332
+ ] }, opt)) }),
333
+ error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { id: `${id}-error`, className: "ff-field-error", role: "alert", children: error })
334
+ ] });
335
+ case "email":
336
+ input = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
337
+ "input",
338
+ {
339
+ ...baseInputProps,
340
+ type: "email",
341
+ className: "ff-input",
342
+ placeholder: field.placeholder,
343
+ value: value ?? "",
344
+ onChange: (e) => onChange(e.target.value)
345
+ }
346
+ );
347
+ break;
348
+ case "phone":
349
+ input = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
350
+ "input",
351
+ {
352
+ ...baseInputProps,
353
+ type: "tel",
354
+ className: "ff-input",
355
+ placeholder: field.placeholder,
356
+ value: value ?? "",
357
+ onChange: (e) => onChange(e.target.value)
358
+ }
359
+ );
360
+ break;
361
+ default:
362
+ input = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
363
+ "input",
364
+ {
365
+ ...baseInputProps,
366
+ type: "text",
367
+ className: "ff-input",
368
+ placeholder: field.placeholder,
369
+ value: value ?? "",
370
+ onChange: (e) => onChange(e.target.value)
371
+ }
372
+ );
373
+ }
374
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "ff-field", children: [
375
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: id, className: "ff-label", children: [
376
+ field.label,
377
+ required && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "ff-required", children: "*" })
378
+ ] }),
379
+ input,
380
+ error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { id: `${id}-error`, className: "ff-field-error", role: "alert", children: error })
381
+ ] });
382
+ }
383
+
384
+ // src/components/Form.tsx
385
+ var import_jsx_runtime2 = require("react/jsx-runtime");
386
+ function Form({
387
+ formId,
388
+ className = "",
389
+ submitText = "Submit",
390
+ submittingText = "Submitting...",
391
+ successTitle = "Thank you!",
392
+ successMessage,
393
+ loadingMessage = "Loading form...",
394
+ hideBadge = false,
395
+ children,
396
+ ...options
397
+ }) {
398
+ const {
399
+ form,
400
+ fields,
401
+ values,
402
+ errors,
403
+ error,
404
+ status,
405
+ result,
406
+ setValue,
407
+ getFieldProps,
408
+ submit
409
+ } = useFixtureForm(formId, options);
410
+ if (status === "loading" || status === "idle") {
411
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: `ff-form ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "ff-loading", children: loadingMessage }) });
412
+ }
413
+ if (status === "error" && !form) {
414
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: `ff-form ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "ff-error", children: error }) });
415
+ }
416
+ if (status === "success") {
417
+ const message = successMessage || result?.successMessage || "Thank you for your submission!";
418
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: `ff-form ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "ff-success", children: [
419
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "ff-success-icon", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
420
+ "path",
421
+ {
422
+ strokeLinecap: "round",
423
+ strokeLinejoin: "round",
424
+ strokeWidth: 2,
425
+ d: "M5 13l4 4L19 7"
426
+ }
427
+ ) }) }),
428
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { className: "ff-success-title", children: successTitle }),
429
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "ff-success-message", children: message })
430
+ ] }) });
431
+ }
432
+ if (!form) {
433
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: `ff-form ${className}`, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "ff-error", children: "Form not found" }) });
434
+ }
435
+ if (children) {
436
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: `ff-form ${className}`, "data-form-id": form.id, children: children({
437
+ form,
438
+ fields,
439
+ values,
440
+ errors,
441
+ setValue,
442
+ getFieldProps,
443
+ submit,
444
+ status
445
+ }) });
446
+ }
447
+ const showBadge = !hideBadge && form.settings?.branding?.show_fixture_badge !== false;
448
+ const handleSubmit = (e) => {
449
+ e.preventDefault();
450
+ submit();
451
+ };
452
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `ff-form ${className}`, "data-form-id": form.id, children: [
453
+ (form.name || form.description) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "ff-form-header", children: [
454
+ form.name && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { className: "ff-form-title", children: form.name }),
455
+ form.description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "ff-form-description", children: form.description })
456
+ ] }),
457
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { className: "ff-form-element", onSubmit: handleSubmit, children: [
458
+ error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "ff-error", role: "alert", children: error }),
459
+ fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
460
+ Field,
461
+ {
462
+ field,
463
+ value: values[field.id],
464
+ error: errors[field.id],
465
+ onChange: (value) => setValue(field.id, value)
466
+ },
467
+ field.id
468
+ )),
469
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
470
+ "button",
471
+ {
472
+ type: "submit",
473
+ className: "ff-button",
474
+ disabled: status === "submitting",
475
+ children: status === "submitting" ? submittingText : submitText
476
+ }
477
+ )
478
+ ] }),
479
+ showBadge && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "ff-badge", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
480
+ "a",
481
+ {
482
+ href: "https://fixture.app",
483
+ target: "_blank",
484
+ rel: "noopener noreferrer",
485
+ children: "Powered by Fixture"
486
+ }
487
+ ) })
488
+ ] });
489
+ }
490
+
491
+ // src/index.ts
492
+ var import_forms_browser2 = require("@fixture-inc/forms-browser");
493
+ // Annotate the CommonJS export names for ESM import in node:
494
+ 0 && (module.exports = {
495
+ Field,
496
+ FixtureFormsContext,
497
+ Form,
498
+ FormClient,
499
+ useFixtureForm,
500
+ useFixtureFormsContext,
501
+ useVisitorId
502
+ });
503
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/hooks.ts","../src/context.ts","../src/components/Field.tsx","../src/components/Form.tsx"],"sourcesContent":["/**\n * @fixture-inc/forms-react\n *\n * React hooks and components for Fixture Forms.\n */\n\n// Hooks\nexport { useFixtureForm, useVisitorId } from './hooks'\nexport type { UseFixtureFormOptions, UseFixtureFormReturn, FieldInputProps } from './hooks'\n\n// Context\nexport { FixtureFormsContext, useFixtureFormsContext } from './context'\nexport type { FixtureFormsContextValue } from './context'\n\n// Components\nexport { Form, Field } from './components'\nexport type { FormProps, FieldProps } from './components'\n\n// Re-export commonly used types from core\nexport type {\n Form as FormType,\n FormField,\n FormResponse,\n SubmitResult,\n FieldType,\n FormStatus,\n NormalizedError,\n} from '@fixture-inc/forms-core'\n\n// Re-export client for advanced usage\nexport { FormClient } from '@fixture-inc/forms-browser'\nexport type { FormClientConfig } from '@fixture-inc/forms-browser'\n","/**\n * React hooks for Fixture Forms\n */\n\nimport { useState, useEffect, useCallback, useMemo, useRef } from 'react'\nimport {\n type Form,\n type FormField,\n type FormResponse,\n type SubmitResult,\n type FieldType,\n type FormStatus,\n type FieldValueMap,\n getDefaultValue,\n validateForm,\n errorsToRecord,\n} from '@fixture-inc/forms-core'\nimport { FormClient, normalizeError } from '@fixture-inc/forms-browser'\nimport { useFixtureFormsContext } from './context'\n\n/**\n * Options for useFixtureForm hook\n */\nexport interface UseFixtureFormOptions {\n /** API endpoint. Defaults to inferred from context or 'https://api.fixture.app' */\n apiUrl?: string\n\n /** Disable auto-fetching. Useful for SSR or conditional rendering. Default: true */\n enabled?: boolean\n\n /** Pre-populate with server-fetched data (for SSR hydration) */\n initialData?: { form: Form; nonce: string }\n\n /** Custom fetch function (for testing, SSR, or proxying) */\n fetcher?: (formId: string) => Promise<{ form: Form; nonce: string }>\n\n /** Enable debug logging */\n debug?: boolean\n\n /** Called on successful submission */\n onSuccess?: (result: SubmitResult) => void\n\n /** Called on any error */\n onError?: (error: { message: string }) => void\n}\n\n/**\n * Props for binding to form inputs\n */\nexport interface FieldInputProps {\n id: string\n name: string\n value: string | boolean\n onChange: (\n e: React.ChangeEvent<\n HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement\n >\n ) => void\n required?: boolean\n type?: string\n checked?: boolean\n}\n\n/**\n * Return type for useFixtureForm hook\n */\nexport interface UseFixtureFormReturn {\n // Form data\n /** Form definition (null while loading) */\n form: Form | null\n /** Form fields array (empty while loading) */\n fields: FormField[]\n\n // State\n /** Current form status */\n status: FormStatus\n /** Global error message */\n error: string | null\n /** Submission result (available after success) */\n result: SubmitResult | null\n\n // Field values\n /** Current field values. Use getFieldValue() for type-safe access. */\n values: Record<string, unknown>\n /** Field validation errors */\n errors: Record<string, string>\n\n // Type-safe value accessor\n /** Get field value with canonical type */\n getFieldValue: <T extends FieldType>(fieldId: string) => FieldValueMap[T] | undefined\n\n // Actions\n /** Set a single field value */\n setValue: (fieldId: string, value: unknown) => void\n /** Set multiple field values */\n setValues: (values: Record<string, unknown>) => void\n /** Submit the form */\n submit: () => Promise<void>\n /** Reset form to initial values */\n reset: () => void\n /** Refetch form from server */\n refetch: () => Promise<void>\n\n // Helpers\n /** Get props for binding to an input element */\n getFieldProps: (fieldId: string) => FieldInputProps\n}\n\n/**\n * Hook for using Fixture Forms in React\n *\n * @example\n * ```tsx\n * function ContactForm() {\n * const { form, fields, values, setValue, submit, status } = useFixtureForm('contact-form')\n *\n * if (status === 'loading') return <div>Loading...</div>\n * if (status === 'success') return <div>Thanks!</div>\n *\n * return (\n * <form onSubmit={(e) => { e.preventDefault(); submit(); }}>\n * {fields.map(field => (\n * <input\n * key={field.id}\n * {...getFieldProps(field.id)}\n * />\n * ))}\n * <button type=\"submit\" disabled={status === 'submitting'}>\n * Submit\n * </button>\n * </form>\n * )\n * }\n * ```\n */\nexport function useFixtureForm(\n formId: string,\n options: UseFixtureFormOptions = {}\n): UseFixtureFormReturn {\n const {\n apiUrl,\n enabled = true,\n initialData,\n fetcher,\n debug,\n onSuccess,\n onError,\n } = options\n\n // Get context if available\n const context = useFixtureFormsContext()\n\n // Create or reuse client\n const clientRef = useRef<FormClient | null>(null)\n if (!clientRef.current) {\n clientRef.current =\n context?.client ??\n new FormClient({\n apiUrl: apiUrl ?? context?.apiUrl,\n debug: debug ?? context?.debug,\n })\n }\n const client = clientRef.current\n\n // State\n const [status, setStatus] = useState<FormStatus>(\n initialData ? 'ready' : 'idle'\n )\n const [form, setForm] = useState<Form | null>(initialData?.form ?? null)\n const [nonce, setNonce] = useState<string | null>(initialData?.nonce ?? null)\n const [values, setValuesState] = useState<Record<string, unknown>>(() => {\n if (initialData?.form) {\n return initializeValues(initialData.form)\n }\n return {}\n })\n const [errors, setErrors] = useState<Record<string, string>>({})\n const [error, setError] = useState<string | null>(null)\n const [result, setResult] = useState<SubmitResult | null>(null)\n\n // Initialize values from form\n function initializeValues(formData: Form): Record<string, unknown> {\n const vals: Record<string, unknown> = {}\n for (const field of formData.fields) {\n vals[field.id] = getDefaultValue(field.type)\n }\n return vals\n }\n\n // Fetch form\n const fetchForm = useCallback(async () => {\n if (!formId) return\n\n setStatus('loading')\n setError(null)\n\n try {\n let response: FormResponse\n\n if (fetcher) {\n response = await fetcher(formId)\n } else {\n response = await client.fetchForm(formId)\n }\n\n setForm(response.form)\n setNonce(response.nonce)\n setValuesState(initializeValues(response.form))\n setErrors({})\n setStatus('ready')\n } catch (err) {\n const normalized = normalizeError(err)\n setError(normalized.message)\n setStatus('error')\n\n if (onError) {\n onError(normalized)\n }\n }\n }, [formId, client, fetcher, onError])\n\n // Auto-fetch on mount\n useEffect(() => {\n if (enabled && !initialData) {\n fetchForm()\n }\n }, [enabled, initialData, fetchForm])\n\n // Set single value\n const setValue = useCallback((fieldId: string, value: unknown) => {\n setValuesState((prev) => ({ ...prev, [fieldId]: value }))\n // Clear field error when value changes\n setErrors((prev) => {\n const next = { ...prev }\n delete next[fieldId]\n return next\n })\n }, [])\n\n // Set multiple values\n const setValuesFunc = useCallback((newValues: Record<string, unknown>) => {\n setValuesState((prev) => ({ ...prev, ...newValues }))\n }, [])\n\n // Get type-safe field value\n const getFieldValue = useCallback(\n <T extends FieldType>(fieldId: string): FieldValueMap[T] | undefined => {\n return values[fieldId] as FieldValueMap[T] | undefined\n },\n [values]\n )\n\n // Submit form\n const submit = useCallback(async () => {\n if (!form || !nonce) {\n setError('Form not loaded')\n return\n }\n\n // Validate\n const validationErrors = validateForm(\n form.fields,\n values as Record<string, string | boolean>\n )\n if (validationErrors.length > 0) {\n setErrors(errorsToRecord(validationErrors))\n return\n }\n\n setStatus('submitting')\n setError(null)\n\n try {\n const { result: submitResult, newNonce } = await client.submitWithRetry(\n formId,\n form,\n values,\n { nonce }\n )\n\n // Update nonce if refreshed\n if (newNonce) {\n setNonce(newNonce)\n }\n\n // Handle redirect\n if (submitResult.redirectUrl && typeof window !== 'undefined') {\n window.location.href = submitResult.redirectUrl\n return\n }\n\n setResult(submitResult)\n setStatus('success')\n\n if (onSuccess) {\n onSuccess(submitResult)\n }\n } catch (err) {\n const normalized = normalizeError(err)\n setError(normalized.message)\n setStatus('ready')\n\n if (onError) {\n onError(normalized)\n }\n }\n }, [form, nonce, values, formId, client, onSuccess, onError])\n\n // Reset form\n const reset = useCallback(() => {\n if (form) {\n setValuesState(initializeValues(form))\n }\n setErrors({})\n setError(null)\n setResult(null)\n setStatus(form ? 'ready' : 'idle')\n }, [form])\n\n // Get field props for easy binding\n const getFieldProps = useCallback(\n (fieldId: string): FieldInputProps => {\n const field = form?.fields.find((f) => f.id === fieldId)\n const value = values[fieldId]\n const isCheckbox = field?.type === 'checkbox'\n\n return {\n id: `ff-${fieldId}`,\n name: fieldId,\n value: isCheckbox ? 'true' : (value as string) ?? '',\n checked: isCheckbox ? (value as boolean) : undefined,\n required: field?.required,\n type: field?.type === 'email' ? 'email' : field?.type === 'phone' ? 'tel' : undefined,\n onChange: (e) => {\n if (isCheckbox) {\n setValue(fieldId, (e.target as HTMLInputElement).checked)\n } else {\n setValue(fieldId, e.target.value)\n }\n },\n }\n },\n [form, values, setValue]\n )\n\n // Memoize fields array\n const fields = useMemo(() => form?.fields ?? [], [form])\n\n return {\n form,\n fields,\n status,\n error,\n result,\n values,\n errors,\n getFieldValue,\n setValue,\n setValues: setValuesFunc,\n submit,\n reset,\n refetch: fetchForm,\n getFieldProps,\n }\n}\n\n/**\n * Hook to get the visitor ID from the forms tracker\n */\nexport function useVisitorId(): string | null {\n const [visitorId, setVisitorId] = useState<string | null>(null)\n\n useEffect(() => {\n // Import dynamically to avoid SSR issues\n import('@fixture-inc/forms-browser').then(({ getVisitorId }) => {\n setVisitorId(getVisitorId())\n })\n }, [])\n\n return visitorId\n}\n","/**\n * React context for Fixture Forms\n */\n\nimport { createContext, useContext } from 'react'\nimport type { FormClient } from '@fixture-inc/forms-browser'\n\n/**\n * Context value for the forms provider\n */\nexport interface FixtureFormsContextValue {\n /** Shared FormClient instance */\n client: FormClient\n /** Default API URL */\n apiUrl?: string\n /** Debug mode enabled */\n debug?: boolean\n}\n\n/**\n * Context for sharing FormClient across components\n */\nexport const FixtureFormsContext = createContext<FixtureFormsContextValue | null>(null)\n\n/**\n * Hook to access the forms context\n *\n * @returns Context value or null if not in provider\n */\nexport function useFixtureFormsContext(): FixtureFormsContextValue | null {\n return useContext(FixtureFormsContext)\n}\n","/**\n * Pre-built Field component\n *\n * Renders a single form field with appropriate input type and styling.\n */\n\nimport React from 'react'\nimport type { FormField } from '@fixture-inc/forms-core'\n\nexport interface FieldProps {\n /** Field definition */\n field: FormField\n /** Current value */\n value: unknown\n /** Validation error */\n error?: string\n /** Called when value changes */\n onChange: (value: unknown) => void\n}\n\n/**\n * Render a single form field\n */\nexport function Field({\n field,\n value,\n error,\n onChange,\n}: FieldProps): React.ReactElement {\n const id = `ff-${field.id}`\n const required = field.required\n\n // Common props for inputs\n const baseInputProps = {\n id,\n name: field.id,\n required,\n 'aria-invalid': error ? true : undefined,\n 'aria-describedby': error ? `${id}-error` : undefined,\n }\n\n // Render field based on type\n let input: React.ReactNode\n\n switch (field.type) {\n case 'textarea':\n input = (\n <textarea\n {...baseInputProps}\n className=\"ff-textarea\"\n placeholder={field.placeholder}\n value={(value as string) ?? ''}\n onChange={(e) => onChange(e.target.value)}\n />\n )\n break\n\n case 'dropdown':\n input = (\n <select\n {...baseInputProps}\n className=\"ff-select\"\n value={(value as string) ?? ''}\n onChange={(e) => onChange(e.target.value)}\n >\n <option value=\"\">Select...</option>\n {field.options?.map((opt) => (\n <option key={opt} value={opt}>\n {opt}\n </option>\n ))}\n </select>\n )\n break\n\n case 'checkbox':\n return (\n <div className=\"ff-field\">\n <div className=\"ff-checkbox-wrapper\">\n <input\n {...baseInputProps}\n type=\"checkbox\"\n className=\"ff-checkbox\"\n checked={(value as boolean) ?? false}\n onChange={(e) => onChange(e.target.checked)}\n />\n <label htmlFor={id} className=\"ff-checkbox-label\">\n {field.label}\n {required && <span className=\"ff-required\">*</span>}\n </label>\n </div>\n {error && (\n <div id={`${id}-error`} className=\"ff-field-error\" role=\"alert\">\n {error}\n </div>\n )}\n </div>\n )\n\n case 'radio':\n return (\n <div className=\"ff-field\">\n <div className=\"ff-label\">\n {field.label}\n {required && <span className=\"ff-required\">*</span>}\n </div>\n <div className=\"ff-radio-group\" role=\"radiogroup\" aria-labelledby={id}>\n {field.options?.map((opt, i) => (\n <label key={opt} className=\"ff-radio-wrapper\">\n <input\n type=\"radio\"\n name={field.id}\n value={opt}\n className=\"ff-radio\"\n checked={(value as string) === opt}\n required={i === 0 && required}\n onChange={() => onChange(opt)}\n />\n <span className=\"ff-radio-label\">{opt}</span>\n </label>\n ))}\n </div>\n {error && (\n <div id={`${id}-error`} className=\"ff-field-error\" role=\"alert\">\n {error}\n </div>\n )}\n </div>\n )\n\n case 'email':\n input = (\n <input\n {...baseInputProps}\n type=\"email\"\n className=\"ff-input\"\n placeholder={field.placeholder}\n value={(value as string) ?? ''}\n onChange={(e) => onChange(e.target.value)}\n />\n )\n break\n\n case 'phone':\n input = (\n <input\n {...baseInputProps}\n type=\"tel\"\n className=\"ff-input\"\n placeholder={field.placeholder}\n value={(value as string) ?? ''}\n onChange={(e) => onChange(e.target.value)}\n />\n )\n break\n\n default: // text\n input = (\n <input\n {...baseInputProps}\n type=\"text\"\n className=\"ff-input\"\n placeholder={field.placeholder}\n value={(value as string) ?? ''}\n onChange={(e) => onChange(e.target.value)}\n />\n )\n }\n\n return (\n <div className=\"ff-field\">\n <label htmlFor={id} className=\"ff-label\">\n {field.label}\n {required && <span className=\"ff-required\">*</span>}\n </label>\n {input}\n {error && (\n <div id={`${id}-error`} className=\"ff-field-error\" role=\"alert\">\n {error}\n </div>\n )}\n </div>\n )\n}\n","/**\n * Pre-built Form component\n *\n * A complete, styled form component that handles loading, submission, and success states.\n */\n\nimport React from 'react'\nimport type { SubmitResult, Form as FormType } from '@fixture-inc/forms-core'\nimport { useFixtureForm, type UseFixtureFormOptions, type FieldInputProps } from '../hooks'\nimport { Field } from './Field'\n\nexport interface FormProps extends UseFixtureFormOptions {\n /** Form ID to render */\n formId: string\n /** Custom className for the form container */\n className?: string\n /** Custom submit button text */\n submitText?: string\n /** Custom submitting button text */\n submittingText?: string\n /** Custom success title */\n successTitle?: string\n /** Custom success message (overrides server response) */\n successMessage?: string\n /** Custom loading message */\n loadingMessage?: string\n /** Hide the \"Powered by Fixture\" badge */\n hideBadge?: boolean\n /** Custom render function for the form */\n children?: (props: {\n form: FormType\n fields: FormType['fields']\n values: Record<string, unknown>\n errors: Record<string, string>\n setValue: (fieldId: string, value: unknown) => void\n getFieldProps: (fieldId: string) => FieldInputProps\n submit: () => Promise<void>\n status: string\n }) => React.ReactNode\n}\n\n/**\n * Pre-built form component with default styling\n */\nexport function Form({\n formId,\n className = '',\n submitText = 'Submit',\n submittingText = 'Submitting...',\n successTitle = 'Thank you!',\n successMessage,\n loadingMessage = 'Loading form...',\n hideBadge = false,\n children,\n ...options\n}: FormProps): React.ReactElement {\n const {\n form,\n fields,\n values,\n errors,\n error,\n status,\n result,\n setValue,\n getFieldProps,\n submit,\n } = useFixtureForm(formId, options)\n\n // Loading state\n if (status === 'loading' || status === 'idle') {\n return (\n <div className={`ff-form ${className}`}>\n <div className=\"ff-loading\">{loadingMessage}</div>\n </div>\n )\n }\n\n // Error state (form failed to load)\n if (status === 'error' && !form) {\n return (\n <div className={`ff-form ${className}`}>\n <div className=\"ff-error\">{error}</div>\n </div>\n )\n }\n\n // Success state\n if (status === 'success') {\n const message =\n successMessage || result?.successMessage || 'Thank you for your submission!'\n return (\n <div className={`ff-form ${className}`}>\n <div className=\"ff-success\">\n <div className=\"ff-success-icon\">\n <svg fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 13l4 4L19 7\"\n />\n </svg>\n </div>\n <h2 className=\"ff-success-title\">{successTitle}</h2>\n <p className=\"ff-success-message\">{message}</p>\n </div>\n </div>\n )\n }\n\n // Form state\n if (!form) {\n return (\n <div className={`ff-form ${className}`}>\n <div className=\"ff-error\">Form not found</div>\n </div>\n )\n }\n\n // Custom render function\n if (children) {\n return (\n <div className={`ff-form ${className}`} data-form-id={form.id}>\n {children({\n form,\n fields,\n values,\n errors,\n setValue,\n getFieldProps,\n submit,\n status,\n })}\n </div>\n )\n }\n\n // Default render\n const showBadge =\n !hideBadge && form.settings?.branding?.show_fixture_badge !== false\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault()\n submit()\n }\n\n return (\n <div className={`ff-form ${className}`} data-form-id={form.id}>\n {(form.name || form.description) && (\n <div className=\"ff-form-header\">\n {form.name && <h2 className=\"ff-form-title\">{form.name}</h2>}\n {form.description && (\n <p className=\"ff-form-description\">{form.description}</p>\n )}\n </div>\n )}\n\n <form className=\"ff-form-element\" onSubmit={handleSubmit}>\n {error && (\n <div className=\"ff-error\" role=\"alert\">\n {error}\n </div>\n )}\n\n {fields.map((field) => (\n <Field\n key={field.id}\n field={field}\n value={values[field.id]}\n error={errors[field.id]}\n onChange={(value) => setValue(field.id, value)}\n />\n ))}\n\n <button\n type=\"submit\"\n className=\"ff-button\"\n disabled={status === 'submitting'}\n >\n {status === 'submitting' ? submittingText : submitText}\n </button>\n </form>\n\n {showBadge && (\n <div className=\"ff-badge\">\n <a\n href=\"https://fixture.app\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Powered by Fixture\n </a>\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime","import_forms_browser"]}