@wix/headless-forms 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,652 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.Form = exports.Fields = exports.Submitted = exports.Error = exports.LoadingError = exports.Loading = exports.Root = void 0;
40
+ const jsx_runtime_1 = require("react/jsx-runtime");
41
+ const react_1 = __importDefault(require("react"));
42
+ const react_2 = require("@wix/headless-utils/react");
43
+ const CoreForm = __importStar(require("./core/Form.js"));
44
+ var TestIds;
45
+ (function (TestIds) {
46
+ TestIds["formRoot"] = "form-root";
47
+ TestIds["formLoadingError"] = "form-loading-error";
48
+ TestIds["formError"] = "form-error";
49
+ TestIds["formSubmitted"] = "form-submitted";
50
+ })(TestIds || (TestIds = {}));
51
+ /**
52
+ * Root component that provides all necessary service contexts for a complete form experience.
53
+ * This component sets up the Form service and provides context to child components.
54
+ * Must be used as the top-level component for all form functionality.
55
+ *
56
+ * @component
57
+ * @param {RootProps} props - The component props
58
+ * @param {React.ReactNode} props.children - Child components that will have access to form context
59
+ * @param {FormServiceConfig} props.formServiceConfig - Form service configuration object
60
+ * @param {string} [props.className] - CSS classes to apply to the root element
61
+ * @example
62
+ * ```tsx
63
+ * import { Form } from '@wix/headless-forms/react';
64
+ * import { loadFormServiceConfig } from '@wix/headless-forms/services';
65
+ *
66
+ * const FIELD_MAP = {
67
+ * TEXT_INPUT: TextInput,
68
+ * TEXT_AREA: TextArea,
69
+ * CHECKBOX: Checkbox,
70
+ * // ... other field components
71
+ * };
72
+ *
73
+ * // Pattern 1: Pre-loaded form data (SSR/SSG)
74
+ * function FormPage({ formServiceConfig }) {
75
+ * return (
76
+ * <Form.Root formServiceConfig={formServiceConfig}>
77
+ * <Form.Loading className="flex justify-center p-4" />
78
+ * <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
79
+ * <Form.Fields fieldMap={FIELD_MAP} />
80
+ * <Form.Error className="text-destructive p-4 rounded-lg mb-4" />
81
+ * <Form.Submitted className="text-green-500 p-4 rounded-lg mb-4" />
82
+ * </Form.Root>
83
+ * );
84
+ * }
85
+ *
86
+ * // Pattern 2: Lazy loading with formId (Client-side)
87
+ * function DynamicFormPage({ formId }) {
88
+ * return (
89
+ * <Form.Root formServiceConfig={{ formId }}>
90
+ * <Form.Loading className="flex justify-center p-4" />
91
+ * <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
92
+ * <Form.Fields fieldMap={FIELD_MAP} />
93
+ * <Form.Error className="text-destructive p-4 rounded-lg mb-4" />
94
+ * <Form.Submitted className="text-green-500 p-4 rounded-lg mb-4" />
95
+ * </Form.Root>
96
+ * );
97
+ * }
98
+ * ```
99
+ */
100
+ exports.Root = react_1.default.forwardRef((props, ref) => {
101
+ const { children, formServiceConfig, asChild, ...otherProps } = props;
102
+ return ((0, jsx_runtime_1.jsx)(CoreForm.Root, { formServiceConfig: formServiceConfig, children: (0, jsx_runtime_1.jsx)(RootContent, { asChild: asChild, ref: ref, ...otherProps, children: children }) }));
103
+ });
104
+ /**
105
+ * Internal component to handle the Root content with service access.
106
+ * This component wraps the children with the necessary div container and applies styling.
107
+ *
108
+ * @internal
109
+ * @param {RootContentProps} props - Component props
110
+ * @param {React.ReactNode} props.children - Child components to render
111
+ * @param {string} [props.className] - CSS classes to apply to the container
112
+ * @param {boolean} [props.asChild] - Whether to render as a child component
113
+ * @returns {JSX.Element} The wrapped content
114
+ */
115
+ const RootContent = react_1.default.forwardRef((props, ref) => {
116
+ const { asChild, children, className, ...otherProps } = props;
117
+ return ((0, jsx_runtime_1.jsx)(react_2.AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.formRoot, customElement: children, customElementProps: {}, ...otherProps, children: (0, jsx_runtime_1.jsx)("div", { children: react_1.default.isValidElement(children) ? children : null }) }));
118
+ });
119
+ /**
120
+ * Component that renders content during loading state.
121
+ * Only displays its children when the form is currently loading.
122
+ *
123
+ * @component
124
+ * @param {LoadingProps} props - The component props
125
+ * @param {boolean} [props.asChild] - Whether to render as a child component
126
+ * @param {React.ReactNode} [props.children] - Content to display during loading state
127
+ * @param {string} [props.className] - CSS classes to apply to the default element
128
+ * @example
129
+ * ```tsx
130
+ * import { Form } from '@wix/headless-forms/react';
131
+ *
132
+ * // Default usage with className
133
+ * function FormLoading() {
134
+ * return (
135
+ * <Form.Loading className="flex justify-center p-4" />
136
+ * );
137
+ * }
138
+ *
139
+ * // Custom content
140
+ * function CustomFormLoading() {
141
+ * return (
142
+ * <Form.Loading>
143
+ * <div className="flex justify-center items-center p-4">
144
+ * <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
145
+ * <span className="ml-2 text-foreground font-paragraph">Loading form...</span>
146
+ * </div>
147
+ * </Form.Loading>
148
+ * );
149
+ * }
150
+ *
151
+ * // With asChild for custom components
152
+ * function CustomFormLoadingAsChild() {
153
+ * return (
154
+ * <Form.Loading asChild>
155
+ * <div className="custom-loading-container">
156
+ * <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
157
+ * <span className="ml-2 text-foreground font-paragraph">Loading form...</span>
158
+ * </div>
159
+ * </Form.Loading>
160
+ * );
161
+ * }
162
+ * ```
163
+ */
164
+ exports.Loading = react_1.default.forwardRef((props, ref) => {
165
+ const { asChild, children, className, ...otherProps } = props;
166
+ return ((0, jsx_runtime_1.jsx)(CoreForm.Loading, { children: ({ isLoading }) => {
167
+ if (!isLoading)
168
+ return null;
169
+ return ((0, jsx_runtime_1.jsx)(react_2.AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": "form-loading", customElement: children, content: "Loading form...", ...otherProps, children: (0, jsx_runtime_1.jsx)("div", { children: "Loading form..." }) }));
170
+ } }));
171
+ });
172
+ /**
173
+ * Component that renders content when there's an error loading the form.
174
+ * Only displays its children when an error has occurred.
175
+ *
176
+ * @component
177
+ * @param {LoadingErrorProps} props - The component props
178
+ * @param {boolean} [props.asChild] - Whether to render as a child component
179
+ * @param {React.ReactNode} [props.children] - Content to display during error state
180
+ * @param {string} [props.className] - CSS classes to apply to the default element
181
+ * @example
182
+ * ```tsx
183
+ * import { Form } from '@wix/headless-forms/react';
184
+ *
185
+ * // Default usage with className
186
+ * function FormLoadingError() {
187
+ * return (
188
+ * <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
189
+ * );
190
+ * }
191
+ *
192
+ * // Custom content
193
+ * function CustomLoadingError() {
194
+ * return (
195
+ * <Form.LoadingError>
196
+ * <div className="bg-destructive/10 border border-destructive text-destructive px-4 py-3 rounded mb-4">
197
+ * <h3 className="font-heading text-lg">Error loading form</h3>
198
+ * <p className="font-paragraph">Something went wrong. Please try again.</p>
199
+ * </div>
200
+ * </Form.LoadingError>
201
+ * );
202
+ * }
203
+ *
204
+ * // With asChild for custom components
205
+ * function CustomLoadingErrorAsChild() {
206
+ * return (
207
+ * <Form.LoadingError asChild>
208
+ * {React.forwardRef<HTMLDivElement, { error: string | null; hasError: boolean }>(
209
+ * ({ error }, ref) => (
210
+ * <div ref={ref} className="custom-error-container">
211
+ * <h3 className="font-heading">Error Loading Form</h3>
212
+ * <p className="font-paragraph">{error}</p>
213
+ * </div>
214
+ * )
215
+ * )}
216
+ * </Form.LoadingError>
217
+ * );
218
+ * }
219
+ * ```
220
+ */
221
+ exports.LoadingError = react_1.default.forwardRef((props, ref) => {
222
+ const { asChild, children, className, ...otherProps } = props;
223
+ return ((0, jsx_runtime_1.jsx)(CoreForm.LoadingError, { children: ({ error, hasError }) => {
224
+ if (!hasError)
225
+ return null;
226
+ const errorData = { error, hasError };
227
+ return ((0, jsx_runtime_1.jsx)(react_2.AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.formLoadingError, customElement: children, customElementProps: errorData, content: error, ...otherProps, children: (0, jsx_runtime_1.jsx)("div", { children: error }) }));
228
+ } }));
229
+ });
230
+ /**
231
+ * Component that renders content when there's an error during form submission.
232
+ * Only displays its children when a submission error has occurred.
233
+ *
234
+ * @component
235
+ * @param {ErrorProps} props - The component props
236
+ * @param {boolean} [props.asChild] - Whether to render as a child component
237
+ * @param {React.ReactNode} [props.children] - Content to display during submit error state
238
+ * @param {string} [props.className] - CSS classes to apply to the default element
239
+ * @example
240
+ * ```tsx
241
+ * import { Form } from '@wix/headless-forms/react';
242
+ *
243
+ * // Default usage with className
244
+ * function FormError() {
245
+ * return <Form.Error className="text-destructive p-4 rounded-lg mb-4" />;
246
+ * }
247
+ *
248
+ * // Custom content
249
+ * function CustomFormError() {
250
+ * return (
251
+ * <Form.Error>
252
+ * <div className="bg-destructive/10 border border-destructive text-destructive p-4 rounded-lg mb-4">
253
+ * <h3 className="font-heading text-lg">Submission Failed</h3>
254
+ * <p className="font-paragraph">Please check your input and try again.</p>
255
+ * </div>
256
+ * </Form.Error>
257
+ * );
258
+ * }
259
+ *
260
+ * // With asChild for custom components
261
+ * function CustomFormErrorAsChild() {
262
+ * return (
263
+ * <Form.Error asChild>
264
+ * {React.forwardRef<HTMLDivElement, { error: string | null; hasError: boolean }>(
265
+ * ({ error }, ref) => (
266
+ * <div ref={ref} className="custom-error-container">
267
+ * <h3 className="font-heading">Submission Failed</h3>
268
+ * <p className="font-paragraph">{error}</p>
269
+ * </div>
270
+ * )
271
+ * )}
272
+ * </Form.Error>
273
+ * );
274
+ * }
275
+ * ```
276
+ */
277
+ exports.Error = react_1.default.forwardRef((props, ref) => {
278
+ const { asChild, children, className, ...otherProps } = props;
279
+ return ((0, jsx_runtime_1.jsx)(CoreForm.Error, { children: ({ error, hasError }) => {
280
+ if (!hasError)
281
+ return null;
282
+ const errorData = { error, hasError };
283
+ return ((0, jsx_runtime_1.jsx)(react_2.AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.formError, customElement: children, customElementProps: errorData, content: error, ...otherProps, children: (0, jsx_runtime_1.jsx)("div", { className: "text-destructive text-sm sm:text-base", children: error }) }));
284
+ } }));
285
+ });
286
+ /**
287
+ * Component that renders content after successful form submission.
288
+ * Only displays its children when the form has been successfully submitted.
289
+ *
290
+ * @component
291
+ * @param {SubmittedProps} props - The component props
292
+ * @param {boolean} [props.asChild] - Whether to render as a child component
293
+ * @param {React.ReactNode} [props.children] - Content to display after successful submission
294
+ * @param {string} [props.className] - CSS classes to apply to the default element
295
+ * @example
296
+ * ```tsx
297
+ * import { Form } from '@wix/headless-forms/react';
298
+ *
299
+ * // Default usage with className
300
+ * function FormSubmitted() {
301
+ * return <Form.Submitted className="text-green-500 p-4 rounded-lg mb-4" />;
302
+ * }
303
+ *
304
+ * // Custom content
305
+ * function CustomFormSubmitted() {
306
+ * return (
307
+ * <Form.Submitted>
308
+ * <div className="bg-green-50 border border-green-200 text-green-800 p-6 rounded-lg mb-4">
309
+ * <h2 className="font-heading text-xl mb-2">Thank You!</h2>
310
+ * <p className="font-paragraph">Your form has been submitted successfully.</p>
311
+ * </div>
312
+ * </Form.Submitted>
313
+ * );
314
+ * }
315
+ *
316
+ * // With asChild for custom components
317
+ * function CustomFormSubmittedAsChild() {
318
+ * return (
319
+ * <Form.Submitted asChild>
320
+ * {React.forwardRef<HTMLDivElement, { isSubmitted: boolean; message: string }>(
321
+ * ({ message }, ref) => (
322
+ * <div ref={ref} className="custom-success-container">
323
+ * <h2 className="font-heading">Thank You!</h2>
324
+ * <p className="font-paragraph">{message}</p>
325
+ * </div>
326
+ * )
327
+ * )}
328
+ * </Form.Submitted>
329
+ * );
330
+ * }
331
+ * ```
332
+ */
333
+ exports.Submitted = react_1.default.forwardRef((props, ref) => {
334
+ const { asChild, children, className, ...otherProps } = props;
335
+ return ((0, jsx_runtime_1.jsx)(CoreForm.Submitted, { children: ({ isSubmitted, message }) => {
336
+ if (!isSubmitted)
337
+ return null;
338
+ const submittedData = { isSubmitted, message };
339
+ return ((0, jsx_runtime_1.jsx)(react_2.AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.formSubmitted, customElement: children, customElementProps: submittedData, content: message, ...otherProps, children: (0, jsx_runtime_1.jsx)("div", { className: "text-green-500 text-sm sm:text-base", children: message }) }));
340
+ } }));
341
+ });
342
+ /**
343
+ * Fields component for rendering a form with custom field renderers.
344
+ * This component handles the rendering of form fields based on the provided fieldMap.
345
+ * Must be used within Form.Root to access form context.
346
+ *
347
+ * @component
348
+ * @param {FieldsProps} props - Component props
349
+ * @param {FieldMap} props.fieldMap - A mapping of field types to their corresponding React components
350
+ * @example
351
+ * ```tsx
352
+ * import { Form } from '@wix/headless-forms/react';
353
+ * import { TextInput, TextArea, Checkbox } from './field-components';
354
+ *
355
+ * const FIELD_MAP = {
356
+ * TEXT_INPUT: TextInput,
357
+ * TEXT_AREA: TextArea,
358
+ * CHECKBOX: Checkbox,
359
+ * NUMBER_INPUT: NumberInput,
360
+ * // ... remaining field components
361
+ * };
362
+ *
363
+ * function ContactForm({ formServiceConfig }) {
364
+ * return (
365
+ * <Form.Root formServiceConfig={formServiceConfig}>
366
+ * <Form.Loading className="flex justify-center p-4" />
367
+ * <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
368
+ * <Form.Fields fieldMap={FIELD_MAP} />
369
+ * </Form.Root>
370
+ * );
371
+ * }
372
+ * ```
373
+ */
374
+ /**
375
+ * Fields component for rendering a form with custom field renderers.
376
+ * It maps each field type from the form configuration to its corresponding React component
377
+ * and renders them in the order and layout defined by the form structure.
378
+ *
379
+ * The component automatically handles:
380
+ * - Field validation and error display
381
+ * - Form state management
382
+ * - Field value updates
383
+ *
384
+ * Must be used within Form.Root to access form context.
385
+ *
386
+ * @component
387
+ * @param {FieldsProps} props - The component props
388
+ * @param {FieldMap} props.fieldMap - A mapping of field types to their corresponding React components. Each key represents a field type (e.g., 'TEXT_INPUT', 'CHECKBOX') and the value is the React component that should render that field type.
389
+ *
390
+ * @example
391
+ * ```tsx
392
+ * import { Form } from '@wix/headless-forms/react';
393
+ * import { loadFormServiceConfig } from '@wix/headless-forms/services';
394
+ * import {
395
+ * TextInput,
396
+ * TextArea,
397
+ * PhoneInput,
398
+ * MultilineAddress,
399
+ * DateInput,
400
+ * DatePicker,
401
+ * DateTimeInput,
402
+ * FileUpload,
403
+ * NumberInput,
404
+ * Checkbox,
405
+ * Signature,
406
+ * RatingInput,
407
+ * RadioGroup,
408
+ * CheckboxGroup,
409
+ * Dropdown,
410
+ * Tags,
411
+ * TimeInput,
412
+ * RichText,
413
+ * SubmitButton,
414
+ * ProductList,
415
+ * FixedPayment,
416
+ * PaymentInput,
417
+ * Donation,
418
+ * Appointment,
419
+ * ImageChoice
420
+ * } from './components';
421
+ *
422
+ * // Define your field mapping - this tells the Fields component which React component to use for each field type
423
+ * const FIELD_MAP = {
424
+ * TEXT_INPUT: TextInput,
425
+ * TEXT_AREA: TextArea,
426
+ * PHONE_INPUT: PhoneInput,
427
+ * MULTILINE_ADDRESS: MultilineAddress,
428
+ * DATE_INPUT: DateInput,
429
+ * DATE_PICKER: DatePicker,
430
+ * DATE_TIME_INPUT: DateTimeInput,
431
+ * FILE_UPLOAD: FileUpload,
432
+ * NUMBER_INPUT: NumberInput,
433
+ * CHECKBOX: Checkbox,
434
+ * SIGNATURE: Signature,
435
+ * RATING_INPUT: RatingInput,
436
+ * RADIO_GROUP: RadioGroup,
437
+ * CHECKBOX_GROUP: CheckboxGroup,
438
+ * DROPDOWN: Dropdown,
439
+ * TAGS: Tags,
440
+ * TIME_INPUT: TimeInput,
441
+ * TEXT: RichText,
442
+ * SUBMIT_BUTTON: SubmitButton,
443
+ * PRODUCT_LIST: ProductList,
444
+ * FIXED_PAYMENT: FixedPayment,
445
+ * PAYMENT_INPUT: PaymentInput,
446
+ * DONATION: Donation,
447
+ * APPOINTMENT: Appointment,
448
+ * IMAGE_CHOICE: ImageChoice,
449
+ * };
450
+ *
451
+ * function ContactForm({ formServiceConfig }) {
452
+ * return (
453
+ * <Form.Root formServiceConfig={formServiceConfig}>
454
+ * <Form.Loading className="flex justify-center p-4" />
455
+ * <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
456
+ * <Form.Fields fieldMap={FIELD_MAP} />
457
+ * <Form.Error className="text-destructive p-4 rounded-lg mb-4" />
458
+ * <Form.Submitted className="text-green-500 p-4 rounded-lg mb-4" />
459
+ * </Form.Root>
460
+ * );
461
+ * }
462
+ * ```
463
+ *
464
+ * @example
465
+ * ```tsx
466
+ * // Advanced usage with custom field components
467
+ * const CustomTextField = ({ value, onChange, label, error, ...props }) => (
468
+ * <div className="form-field">
469
+ * <label className="text-foreground font-paragraph">{label}</label>
470
+ * <input
471
+ * value={value || ''}
472
+ * onChange={(e) => onChange(e.target.value)}
473
+ * className="bg-background border-foreground text-foreground"
474
+ * {...props}
475
+ * />
476
+ * {error && <span className="text-destructive">{error}</span>}
477
+ * </div>
478
+ * );
479
+ *
480
+ * const FIELD_MAP = {
481
+ * TEXT_INPUT: CustomTextField,
482
+ * // ... other field components
483
+ * };
484
+ * ```
485
+ */
486
+ exports.Fields = react_1.default.forwardRef(({ fieldMap }) => {
487
+ // TODO: render real viewer
488
+ return (0, jsx_runtime_1.jsx)(MockViewer, { fieldMap: fieldMap });
489
+ });
490
+ const MockViewer = ({ fieldMap }) => {
491
+ // This is how fieldMap is expected to be used in the viewer
492
+ const schemaFields = {
493
+ // CONTACTS_FIELD_TYPES
494
+ CONTACTS_COMPANY: fieldMap.TEXT_INPUT,
495
+ CONTACTS_POSITION: fieldMap.TEXT_INPUT,
496
+ CONTACTS_TAX_ID: fieldMap.TEXT_INPUT,
497
+ CONTACTS_FIRST_NAME: fieldMap.TEXT_INPUT,
498
+ CONTACTS_LAST_NAME: fieldMap.TEXT_INPUT,
499
+ CONTACTS_EMAIL: fieldMap.TEXT_INPUT,
500
+ CONTACTS_BIRTHDATE: fieldMap.DATE_INPUT,
501
+ CONTACTS_PHONE: fieldMap.PHONE_INPUT,
502
+ CONTACTS_ADDRESS: fieldMap.TEXT_INPUT,
503
+ CONTACTS_SUBSCRIBE: fieldMap.CHECKBOX,
504
+ // QUIZ_FIELD_TYPES
505
+ QUIZ_MULTI_CHOICE: fieldMap.CHECKBOX_GROUP,
506
+ QUIZ_SINGLE_CHOICE: fieldMap.RADIO_GROUP,
507
+ QUIZ_SHORT_TEXT: fieldMap.TEXT_INPUT,
508
+ QUIZ_LONG_TEXT: fieldMap.TEXT_AREA,
509
+ QUIZ_NUMBER: fieldMap.NUMBER_INPUT,
510
+ QUIZ_FILE_UPLOAD: fieldMap.FILE_UPLOAD,
511
+ QUIZ_IMAGE_CHOICE: fieldMap.IMAGE_CHOICE, // TODO: add
512
+ // DEXT_FIELD_TYPES
513
+ DEXT_TEXT_INPUT: fieldMap.TEXT_INPUT,
514
+ DEXT_TEXT_AREA: fieldMap.TEXT_AREA,
515
+ DEXT_DROPDOWN: fieldMap.DROPDOWN,
516
+ DEXT_URL_INPUT: fieldMap.TEXT_INPUT,
517
+ DEXT_RADIO_GROUP: fieldMap.RADIO_GROUP,
518
+ DEXT_NUMBER_INPUT: fieldMap.NUMBER_INPUT,
519
+ DEXT_CHECKBOX: fieldMap.CHECKBOX,
520
+ DEXT_CHECKBOX_GROUP: fieldMap.CHECKBOX_GROUP,
521
+ DEXT_EMAIL: fieldMap.TEXT_INPUT,
522
+ DEXT_PHONE: fieldMap.PHONE_INPUT,
523
+ DEXT_RATING_INPUT: fieldMap.RATING_INPUT,
524
+ DEXT_DATE_PICKER: fieldMap.DATE_PICKER,
525
+ DEXT_TAGS: fieldMap.TAGS,
526
+ // SCHEDULING_FIELD_TYPES
527
+ APPOINTMENT: fieldMap.APPOINTMENT,
528
+ SERVICES_DROPDOWN: fieldMap.DROPDOWN,
529
+ // ECOM_FIELD_TYPES
530
+ ECOM_ADDITIONAL_INFO: fieldMap.TEXT_AREA,
531
+ ECOM_ADDRESS: fieldMap.TEXT_INPUT,
532
+ ECOM_FULL_NAME: fieldMap.TEXT_INPUT,
533
+ ECOM_PHONE: fieldMap.PHONE_INPUT,
534
+ ECOM_COMPANY_NAME: fieldMap.TEXT_INPUT,
535
+ ECOM_EMAIL: fieldMap.TEXT_INPUT,
536
+ ECOM_SUBSCRIPTION: fieldMap.CHECKBOX,
537
+ // BOOKINGS_FIELD_TYPES
538
+ BOOKINGS_FIRST_NAME: fieldMap.TEXT_INPUT,
539
+ BOOKINGS_LAST_NAME: fieldMap.TEXT_INPUT,
540
+ BOOKINGS_EMAIL: fieldMap.TEXT_INPUT,
541
+ BOOKINGS_PHONE: fieldMap.PHONE_INPUT,
542
+ BOOKINGS_ADDRESS: fieldMap.TEXT_INPUT,
543
+ // PAYMENTS_FIELD_TYPES
544
+ PRODUCT_LIST: fieldMap.PRODUCT_LIST,
545
+ DONATION: fieldMap.DONATION,
546
+ PAYMENT_INPUT: fieldMap.PAYMENT_INPUT, // could be TEXT_INPUT?
547
+ FIXED_PAYMENT: fieldMap.FIXED_PAYMENT, // could be TAGS?
548
+ // COMMON_FIELD_TYPES
549
+ TEXT_INPUT: fieldMap.TEXT_INPUT,
550
+ NUMBER_INPUT: fieldMap.NUMBER_INPUT,
551
+ URL_INPUT: fieldMap.TEXT_INPUT,
552
+ TEXT_AREA: fieldMap.TEXT_AREA,
553
+ DATE_INPUT: fieldMap.DATE_INPUT,
554
+ DATE_TIME_INPUT: fieldMap.DATE_TIME_INPUT,
555
+ TIME_INPUT: fieldMap.TIME_INPUT,
556
+ RADIO_GROUP: fieldMap.RADIO_GROUP,
557
+ CHECKBOX_GROUP: fieldMap.CHECKBOX_GROUP,
558
+ FILE_UPLOAD: fieldMap.FILE_UPLOAD,
559
+ CHECKBOX: fieldMap.CHECKBOX,
560
+ DROPDOWN: fieldMap.DROPDOWN,
561
+ // NESTED_FORM: 'NESTED_FORM',
562
+ MULTILINE_ADDRESS: fieldMap.MULTILINE_ADDRESS,
563
+ // are these relevant for headless?
564
+ MLA_COUNTRY: fieldMap.DROPDOWN,
565
+ MLA_CITY: fieldMap.TEXT_INPUT,
566
+ MLA_ADDRESS_LINE: fieldMap.TEXT_INPUT, // dropdown if autocomplete disabled?
567
+ MLA_ADDRESS_LINE_2: fieldMap.TEXT_INPUT,
568
+ MLA_POSTAL_CODE: fieldMap.TEXT_INPUT,
569
+ MLA_SUBDIVISION: fieldMap.DROPDOWN,
570
+ MLA_STREET_NAME: fieldMap.TEXT_INPUT,
571
+ MLA_STREET_NUMBER: fieldMap.TEXT_INPUT,
572
+ MLA_APARTMENT: fieldMap.TEXT_INPUT,
573
+ FULL_NAME_FIRST_NAME: fieldMap.TEXT_INPUT,
574
+ FULL_NAME_LAST_NAME: fieldMap.TEXT_INPUT,
575
+ FULL_NAME: fieldMap.TEXT_INPUT,
576
+ VAT_ID: fieldMap.TEXT_INPUT,
577
+ SIGNATURE: fieldMap.SIGNATURE,
578
+ RATING_INPUT: fieldMap.RATING_INPUT,
579
+ TAGS: fieldMap.TAGS,
580
+ DATE_PICKER: fieldMap.DATE_PICKER,
581
+ // READONLY_FIELD_TYPES
582
+ HEADER: fieldMap.TEXT,
583
+ RICH_TEXT: fieldMap.TEXT,
584
+ SUBMIT_BUTTON: fieldMap.SUBMIT_BUTTON,
585
+ };
586
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { children: "Form Fields" }), (0, jsx_runtime_1.jsx)("div", { children: JSON.stringify(schemaFields) })] }));
587
+ };
588
+ /**
589
+ * Main Form namespace containing all form components following the compound component pattern.
590
+ * Provides a headless, flexible way to render and manage forms with custom field components.
591
+ *
592
+ * @namespace Form
593
+ * @property {typeof Root} Root - Form root component that provides service context to all child components
594
+ * @property {typeof Loading} Loading - Form loading state component that displays content during form loading
595
+ * @property {typeof LoadingError} LoadingError - Form loading error state component for handling form loading errors
596
+ * @property {typeof Error} Error - Form submit error state component for handling form submission errors
597
+ * @property {typeof Submitted} Submitted - Form submitted state component for displaying success messages
598
+ * @property {typeof Fields} Fields - Form fields component for rendering form fields with custom field renderers
599
+ * @example
600
+ * ```tsx
601
+ * import { Form } from '@wix/headless-forms/react';
602
+ * import { loadFormServiceConfig } from '@wix/headless-forms/services';
603
+ * import { TextInput, TextArea, Checkbox } from './field-components';
604
+ *
605
+ * const FIELD_MAP = {
606
+ * TEXT_INPUT: TextInput,
607
+ * TEXT_AREA: TextArea,
608
+ * CHECKBOX: Checkbox,
609
+ * // ... other field components
610
+ * };
611
+ *
612
+ * // Pattern 1: Pre-loaded form data (SSR/SSG)
613
+ * function MyForm({ formServiceConfig }) {
614
+ * return (
615
+ * <Form.Root formServiceConfig={formServiceConfig}>
616
+ * <Form.Loading className="flex justify-center p-4" />
617
+ * <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
618
+ * <Form.Fields fieldMap={FIELD_MAP} />
619
+ * <Form.Error className="text-destructive p-4 rounded-lg mb-4" />
620
+ * <Form.Submitted className="text-green-500 p-4 rounded-lg mb-4" />
621
+ * </Form.Root>
622
+ * );
623
+ * }
624
+ *
625
+ * // Pattern 2: Lazy loading with formId (Client-side)
626
+ * function DynamicForm({ formId }) {
627
+ * return (
628
+ * <Form.Root formServiceConfig={{ formId }}>
629
+ * <Form.Loading className="flex justify-center p-4" />
630
+ * <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
631
+ * <Form.Fields fieldMap={FIELD_MAP} />
632
+ * <Form.Error className="text-destructive p-4 rounded-lg mb-4" />
633
+ * <Form.Submitted className="text-green-500 p-4 rounded-lg mb-4" />
634
+ * </Form.Root>
635
+ * );
636
+ * }
637
+ * ```
638
+ */
639
+ exports.Form = {
640
+ /** Form root component that provides service context */
641
+ Root: exports.Root,
642
+ /** Form loading state component */
643
+ Loading: exports.Loading,
644
+ /** Form loading error state component */
645
+ LoadingError: exports.LoadingError,
646
+ /** Form error state component */
647
+ Error: exports.Error,
648
+ /** Form submitted state component */
649
+ Submitted: exports.Submitted,
650
+ /** Form fields component for rendering form fields */
651
+ Fields: exports.Fields,
652
+ };