@wix/headless-forms 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +46 -0
  2. package/cjs/dist/react/Form.d.ts +802 -0
  3. package/cjs/dist/react/Form.js +776 -0
  4. package/cjs/dist/react/Phone.d.ts +47 -0
  5. package/cjs/dist/react/Phone.js +56 -0
  6. package/cjs/dist/react/constants/calling-country-codes.d.ts +242 -0
  7. package/cjs/dist/react/constants/calling-country-codes.js +242 -0
  8. package/cjs/dist/react/context/FieldContext.d.ts +12 -0
  9. package/cjs/dist/react/context/FieldContext.js +16 -0
  10. package/cjs/dist/react/context/FieldLayoutContext.d.ts +12 -0
  11. package/cjs/dist/react/context/FieldLayoutContext.js +21 -0
  12. package/cjs/dist/react/core/Form.d.ts +342 -0
  13. package/cjs/dist/react/core/Form.js +278 -0
  14. package/cjs/dist/react/index.d.ts +3 -0
  15. package/cjs/dist/react/index.js +42 -0
  16. package/cjs/dist/react/types.d.ts +3 -0
  17. package/cjs/dist/react/types.js +2 -0
  18. package/cjs/dist/react/utils.d.ts +13 -0
  19. package/cjs/dist/react/utils.js +20 -0
  20. package/cjs/dist/services/form-service.d.ts +114 -0
  21. package/cjs/dist/services/form-service.js +152 -0
  22. package/cjs/dist/services/index.d.ts +1 -0
  23. package/cjs/dist/services/index.js +17 -0
  24. package/cjs/package.json +3 -0
  25. package/dist/react/Form.d.ts +802 -0
  26. package/dist/react/Form.js +740 -0
  27. package/dist/react/Phone.d.ts +47 -0
  28. package/dist/react/Phone.js +50 -0
  29. package/dist/react/constants/calling-country-codes.d.ts +242 -0
  30. package/dist/react/constants/calling-country-codes.js +241 -0
  31. package/dist/react/context/FieldContext.d.ts +12 -0
  32. package/dist/react/context/FieldContext.js +9 -0
  33. package/dist/react/context/FieldLayoutContext.d.ts +12 -0
  34. package/dist/react/context/FieldLayoutContext.js +13 -0
  35. package/dist/react/core/Form.d.ts +342 -0
  36. package/dist/react/core/Form.js +269 -0
  37. package/dist/react/index.d.ts +3 -0
  38. package/dist/react/index.js +3 -0
  39. package/dist/react/types.d.ts +3 -0
  40. package/dist/react/types.js +1 -0
  41. package/dist/react/utils.d.ts +13 -0
  42. package/dist/react/utils.js +17 -0
  43. package/dist/services/form-service.d.ts +114 -0
  44. package/dist/services/form-service.js +148 -0
  45. package/dist/services/index.d.ts +1 -0
  46. package/dist/services/index.js +1 -0
  47. package/package.json +62 -0
  48. package/react/package.json +4 -0
  49. package/services/package.json +4 -0
@@ -0,0 +1,802 @@
1
+ import React from 'react';
2
+ import { type FormError } from '@wix/form-public';
3
+ import { type CheckboxGroupProps, type CheckboxProps, type PhoneInputProps, type DateInputProps, type DatePickerProps, type DateTimeInputProps, type DropdownProps, type FileUploadProps, type MultilineAddressProps, type NumberInputProps, type RadioGroupProps, type RatingInputProps, type RichTextProps, type SignatureProps, type SubmitButtonProps, type TagsProps, type TextAreaProps, type TextInputProps, type TimeInputProps, type ProductListProps, type FixedPaymentProps, type PaymentInputProps, type DonationProps, type AppointmentProps, type ImageChoiceProps } from './types.js';
4
+ import { type FormServiceConfig } from '../services/form-service.js';
5
+ /**
6
+ * Props for the Form root component following the documented API
7
+ */
8
+ export interface RootProps {
9
+ children: React.ReactNode;
10
+ /** Form service configuration */
11
+ formServiceConfig: FormServiceConfig;
12
+ /** Whether to render as a child component */
13
+ asChild?: boolean;
14
+ /** CSS classes to apply to the root element */
15
+ className?: string;
16
+ }
17
+ /**
18
+ * Root component that provides all necessary service contexts for a complete form experience.
19
+ * This component sets up the Form service and provides context to child components.
20
+ * Must be used as the top-level component for all form functionality.
21
+ *
22
+ * @component
23
+ * @param {RootProps} props - The component props
24
+ * @param {React.ReactNode} props.children - Child components that will have access to form context
25
+ * @param {FormServiceConfig} props.formServiceConfig - Form service configuration object
26
+ * @param {boolean} [props.asChild] - Whether to render as a child component
27
+ * @param {string} [props.className] - CSS classes to apply to the root element
28
+ * @example
29
+ * ```tsx
30
+ * import { Form } from '@wix/headless-forms/react';
31
+ * import { loadFormServiceConfig } from '@wix/headless-forms/services';
32
+ *
33
+ * const FIELD_MAP = {
34
+ * TEXT_INPUT: TextInput,
35
+ * TEXT_AREA: TextArea,
36
+ * CHECKBOX: Checkbox,
37
+ * // ... other field components
38
+ * };
39
+ *
40
+ * // Pattern 1: Pre-loaded form data (SSR/SSG)
41
+ * function FormPage({ formServiceConfig }) {
42
+ * return (
43
+ * <Form.Root formServiceConfig={formServiceConfig}>
44
+ * <Form.Loading className="flex justify-center p-4" />
45
+ * <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
46
+ * <Form.Fields fieldMap={FIELD_MAP} />
47
+ * <Form.Error className="text-destructive p-4 rounded-lg mb-4" />
48
+ * <Form.Submitted className="text-green-500 p-4 rounded-lg mb-4" />
49
+ * </Form.Root>
50
+ * );
51
+ * }
52
+ *
53
+ * // Pattern 2: Lazy loading with formId (Client-side)
54
+ * function DynamicFormPage({ formId }) {
55
+ * return (
56
+ * <Form.Root formServiceConfig={{ formId }}>
57
+ * <Form.Loading className="flex justify-center p-4" />
58
+ * <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
59
+ * <Form.Fields fieldMap={FIELD_MAP} />
60
+ * <Form.Error className="text-destructive p-4 rounded-lg mb-4" />
61
+ * <Form.Submitted className="text-green-500 p-4 rounded-lg mb-4" />
62
+ * </Form.Root>
63
+ * );
64
+ * }
65
+ * ```
66
+ */
67
+ export declare const Root: React.ForwardRefExoticComponent<RootProps & React.RefAttributes<HTMLDivElement>>;
68
+ /**
69
+ * Props for Form Loading component
70
+ */
71
+ export interface LoadingProps {
72
+ /** Whether to render as a child component */
73
+ asChild?: boolean;
74
+ /** Content to display during loading state (can be a ReactNode) */
75
+ children?: React.ReactNode;
76
+ /** CSS classes to apply to the default element */
77
+ className?: string;
78
+ }
79
+ /**
80
+ * Component that renders content during loading state.
81
+ * Only displays its children when the form is currently loading.
82
+ *
83
+ * @component
84
+ * @param {LoadingProps} props - The component props
85
+ * @param {boolean} [props.asChild] - Whether to render as a child component
86
+ * @param {React.ReactNode} [props.children] - Content to display during loading state
87
+ * @param {string} [props.className] - CSS classes to apply to the default element
88
+ * @example
89
+ * ```tsx
90
+ * import { Form } from '@wix/headless-forms/react';
91
+ *
92
+ * // Default usage with className
93
+ * function FormLoading() {
94
+ * return (
95
+ * <Form.Loading className="flex justify-center p-4" />
96
+ * );
97
+ * }
98
+ *
99
+ * // Custom content
100
+ * function CustomFormLoading() {
101
+ * return (
102
+ * <Form.Loading>
103
+ * <div className="flex justify-center items-center p-4">
104
+ * <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
105
+ * <span className="ml-2 text-foreground font-paragraph">Loading form...</span>
106
+ * </div>
107
+ * </Form.Loading>
108
+ * );
109
+ * }
110
+ *
111
+ * // With asChild for custom components
112
+ * function CustomFormLoadingAsChild() {
113
+ * return (
114
+ * <Form.Loading asChild>
115
+ * <div className="custom-loading-container">
116
+ * <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
117
+ * <span className="ml-2 text-foreground font-paragraph">Loading form...</span>
118
+ * </div>
119
+ * </Form.Loading>
120
+ * );
121
+ * }
122
+ * ```
123
+ */
124
+ export declare const Loading: React.ForwardRefExoticComponent<LoadingProps & React.RefAttributes<HTMLElement>>;
125
+ /**
126
+ * Props for Form LoadingError component
127
+ */
128
+ export interface LoadingErrorProps {
129
+ /** Whether to render as a child component */
130
+ asChild?: boolean;
131
+ /** Content to display during error state (can be a ReactNode) */
132
+ children?: React.ReactNode;
133
+ /** CSS classes to apply to the default element */
134
+ className?: string;
135
+ }
136
+ /**
137
+ * Component that renders content when there's an error loading the form.
138
+ * Only displays its children when an error has occurred.
139
+ *
140
+ * @component
141
+ * @param {LoadingErrorProps} props - The component props
142
+ * @param {boolean} [props.asChild] - Whether to render as a child component
143
+ * @param {React.ReactNode} [props.children] - Content to display during error state
144
+ * @param {string} [props.className] - CSS classes to apply to the default element
145
+ * @example
146
+ * ```tsx
147
+ * import { Form } from '@wix/headless-forms/react';
148
+ *
149
+ * // Default usage with className
150
+ * function FormLoadingError() {
151
+ * return (
152
+ * <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
153
+ * );
154
+ * }
155
+ *
156
+ * // Custom content
157
+ * function CustomLoadingError() {
158
+ * return (
159
+ * <Form.LoadingError>
160
+ * <div className="bg-destructive/10 border border-destructive text-destructive px-4 py-3 rounded mb-4">
161
+ * <h3 className="font-heading text-lg">Error loading form</h3>
162
+ * <p className="font-paragraph">Something went wrong. Please try again.</p>
163
+ * </div>
164
+ * </Form.LoadingError>
165
+ * );
166
+ * }
167
+ *
168
+ * // With asChild for custom components
169
+ * function CustomLoadingErrorAsChild() {
170
+ * return (
171
+ * <Form.LoadingError asChild>
172
+ * {React.forwardRef<HTMLDivElement, { error: string | null; hasError: boolean }>(
173
+ * ({ error }, ref) => (
174
+ * <div ref={ref} className="custom-error-container">
175
+ * <h3 className="font-heading">Error Loading Form</h3>
176
+ * <p className="font-paragraph">{error}</p>
177
+ * </div>
178
+ * )
179
+ * )}
180
+ * </Form.LoadingError>
181
+ * );
182
+ * }
183
+ * ```
184
+ */
185
+ export declare const LoadingError: React.ForwardRefExoticComponent<LoadingErrorProps & React.RefAttributes<HTMLElement>>;
186
+ /**
187
+ * Props for Form Error component
188
+ */
189
+ export interface ErrorProps {
190
+ /** Whether to render as a child component */
191
+ asChild?: boolean;
192
+ /** Content to display during submit error state (can be a ReactNode) */
193
+ children?: React.ReactNode;
194
+ /** CSS classes to apply to the default element */
195
+ className?: string;
196
+ }
197
+ /**
198
+ * Component that renders content when there's an error during form submission.
199
+ * Only displays its children when a submission error has occurred.
200
+ *
201
+ * @component
202
+ * @param {ErrorProps} props - The component props
203
+ * @param {boolean} [props.asChild] - Whether to render as a child component
204
+ * @param {React.ReactNode} [props.children] - Content to display during submit error state
205
+ * @param {string} [props.className] - CSS classes to apply to the default element
206
+ * @example
207
+ * ```tsx
208
+ * import { Form } from '@wix/headless-forms/react';
209
+ *
210
+ * // Default usage with className
211
+ * function FormError() {
212
+ * return <Form.Error className="text-destructive p-4 rounded-lg mb-4" />;
213
+ * }
214
+ *
215
+ * // Custom content
216
+ * function CustomFormError() {
217
+ * return (
218
+ * <Form.Error>
219
+ * <div className="bg-destructive/10 border border-destructive text-destructive p-4 rounded-lg mb-4">
220
+ * <h3 className="font-heading text-lg">Submission Failed</h3>
221
+ * <p className="font-paragraph">Please check your input and try again.</p>
222
+ * </div>
223
+ * </Form.Error>
224
+ * );
225
+ * }
226
+ *
227
+ * // With asChild for custom components
228
+ * function CustomFormErrorAsChild() {
229
+ * return (
230
+ * <Form.Error asChild>
231
+ * {React.forwardRef<HTMLDivElement, { error: string | null; hasError: boolean }>(
232
+ * ({ error }, ref) => (
233
+ * <div ref={ref} className="custom-error-container">
234
+ * <h3 className="font-heading">Submission Failed</h3>
235
+ * <p className="font-paragraph">{error}</p>
236
+ * </div>
237
+ * )
238
+ * )}
239
+ * </Form.Error>
240
+ * );
241
+ * }
242
+ * ```
243
+ */
244
+ export declare const Error: React.ForwardRefExoticComponent<ErrorProps & React.RefAttributes<HTMLElement>>;
245
+ /**
246
+ * Props for Form Submitted component
247
+ */
248
+ export interface SubmittedProps {
249
+ /** Whether to render as a child component */
250
+ asChild?: boolean;
251
+ /** Content to display after successful submission (can be a ReactNode) */
252
+ children?: React.ReactNode;
253
+ /** CSS classes to apply to the default element */
254
+ className?: string;
255
+ }
256
+ /**
257
+ * Component that renders content after successful form submission.
258
+ * Only displays its children when the form has been successfully submitted.
259
+ *
260
+ * @component
261
+ * @param {SubmittedProps} props - The component props
262
+ * @param {boolean} [props.asChild] - Whether to render as a child component
263
+ * @param {React.ReactNode} [props.children] - Content to display after successful submission
264
+ * @param {string} [props.className] - CSS classes to apply to the default element
265
+ * @example
266
+ * ```tsx
267
+ * import { Form } from '@wix/headless-forms/react';
268
+ *
269
+ * // Default usage with className
270
+ * function FormSubmitted() {
271
+ * return <Form.Submitted className="text-green-500 p-4 rounded-lg mb-4" />;
272
+ * }
273
+ *
274
+ * // Custom content
275
+ * function CustomFormSubmitted() {
276
+ * return (
277
+ * <Form.Submitted>
278
+ * <div className="bg-green-50 border border-green-200 text-green-800 p-6 rounded-lg mb-4">
279
+ * <h2 className="font-heading text-xl mb-2">Thank You!</h2>
280
+ * <p className="font-paragraph">Your form has been submitted successfully.</p>
281
+ * </div>
282
+ * </Form.Submitted>
283
+ * );
284
+ * }
285
+ *
286
+ * // With asChild for custom components
287
+ * function CustomFormSubmittedAsChild() {
288
+ * return (
289
+ * <Form.Submitted asChild>
290
+ * {React.forwardRef<HTMLDivElement, { isSubmitted: boolean; message: string }>(
291
+ * ({ message }, ref) => (
292
+ * <div ref={ref} className="custom-success-container">
293
+ * <h2 className="font-heading">Thank You!</h2>
294
+ * <p className="font-paragraph">{message}</p>
295
+ * </div>
296
+ * )
297
+ * )}
298
+ * </Form.Submitted>
299
+ * );
300
+ * }
301
+ * ```
302
+ */
303
+ export declare const Submitted: React.ForwardRefExoticComponent<SubmittedProps & React.RefAttributes<HTMLElement>>;
304
+ /**
305
+ * Mapping of form field types to their corresponding React components.
306
+ *
307
+ * ALL field components in this map MUST use Form.Field for proper
308
+ * grid layout positioning.
309
+ *
310
+ * Each key represents a field type identifier that matches the field types defined
311
+ * in the form configuration, and each value is a React component that will receive
312
+ * the field's props and render the appropriate UI element.
313
+ *
314
+ * The field components must accept the corresponding props interface for their field type.
315
+ * For example, TEXT_INPUT components should accept TextInputProps, CHECKBOX components
316
+ * should accept CheckboxProps, etc.
317
+ *
318
+ * @interface FieldMap
319
+ * @property {React.ComponentType<TextInputProps>} TEXT_INPUT - Component for single-line text input fields
320
+ * @property {React.ComponentType<TextAreaProps>} TEXT_AREA - Component for multi-line text input fields
321
+ * @property {React.ComponentType<PhoneInputProps>} PHONE_INPUT - Component for phone number input fields
322
+ * @property {React.ComponentType<MultilineAddressProps>} MULTILINE_ADDRESS - Component for complex address input fields
323
+ * @property {React.ComponentType<DateInputProps>} DATE_INPUT - Component for date input fields (day/month/year)
324
+ * @property {React.ComponentType<DatePickerProps>} DATE_PICKER - Component for calendar-based date selection
325
+ * @property {React.ComponentType<DateTimeInputProps>} DATE_TIME_INPUT - Component for combined date and time input
326
+ * @property {React.ComponentType<FileUploadProps>} FILE_UPLOAD - Component for file upload fields
327
+ * @property {React.ComponentType<NumberInputProps>} NUMBER_INPUT - Component for numerical input fields
328
+ * @property {React.ComponentType<CheckboxProps>} CHECKBOX - Component for boolean checkbox fields
329
+ * @property {React.ComponentType<SignatureProps>} SIGNATURE - Component for digital signature capture
330
+ * @property {React.ComponentType<RatingInputProps>} RATING_INPUT - Component for 1-5 star rating input
331
+ * @property {React.ComponentType<RadioGroupProps>} RADIO_GROUP - Component for single selection from multiple options
332
+ * @property {React.ComponentType<CheckboxGroupProps>} CHECKBOX_GROUP - Component for multiple selection from multiple options
333
+ * @property {React.ComponentType<DropdownProps>} DROPDOWN - Component for dropdown selection fields
334
+ * @property {React.ComponentType<TagsProps>} TAGS - Component for tag-based selection fields
335
+ * @property {React.ComponentType<TimeInputProps>} TIME_INPUT - Component for time-only input fields
336
+ * @property {React.ComponentType<RichTextProps>} TEXT - Component for rich text display fields
337
+ * @property {React.ComponentType<SubmitButtonProps>} SUBMIT_BUTTON - Component for form submission button
338
+ * @property {React.ComponentType<ProductListProps>} PRODUCT_LIST - Component for product selection fields
339
+ * @property {React.ComponentType<FixedPaymentProps>} FIXED_PAYMENT - Component for fixed payment amount display
340
+ * @property {React.ComponentType<PaymentInputProps>} PAYMENT_INPUT - Component for custom payment amount input
341
+ * @property {React.ComponentType<DonationProps>} DONATION - Component for donation amount selection
342
+ * @property {React.ComponentType<AppointmentProps>} APPOINTMENT - Component for appointment scheduling
343
+ * @property {React.ComponentType<ImageChoiceProps>} IMAGE_CHOICE - Component for image-based selection
344
+ *
345
+ * @example
346
+ * ```tsx
347
+ * const FIELD_MAP: FieldMap = {
348
+ * TEXT_INPUT: TextInput,
349
+ * TEXT_AREA: TextArea,
350
+ * PHONE_INPUT: PhoneInput,
351
+ * MULTILINE_ADDRESS: MultilineAddress,
352
+ * DATE_INPUT: DateInput,
353
+ * DATE_PICKER: DatePicker,
354
+ * DATE_TIME_INPUT: DateTimeInput,
355
+ * FILE_UPLOAD: FileUpload,
356
+ * NUMBER_INPUT: NumberInput,
357
+ * CHECKBOX: Checkbox,
358
+ * SIGNATURE: Signature,
359
+ * RATING_INPUT: RatingInput,
360
+ * RADIO_GROUP: RadioGroup,
361
+ * CHECKBOX_GROUP: CheckboxGroup,
362
+ * DROPDOWN: Dropdown,
363
+ * TAGS: Tags,
364
+ * TIME_INPUT: TimeInput,
365
+ * TEXT: RichText,
366
+ * SUBMIT_BUTTON: SubmitButton,
367
+ * PRODUCT_LIST: ProductList,
368
+ * FIXED_PAYMENT: FixedPayment,
369
+ * PAYMENT_INPUT: PaymentInput,
370
+ * DONATION: Donation,
371
+ * APPOINTMENT: Appointment,
372
+ * IMAGE_CHOICE: ImageChoice,
373
+ * };
374
+ * ```
375
+ */
376
+ export interface FieldMap {
377
+ TEXT_INPUT: React.ComponentType<TextInputProps>;
378
+ TEXT_AREA: React.ComponentType<TextAreaProps>;
379
+ PHONE_INPUT: React.ComponentType<PhoneInputProps>;
380
+ MULTILINE_ADDRESS: React.ComponentType<MultilineAddressProps>;
381
+ DATE_INPUT: React.ComponentType<DateInputProps>;
382
+ DATE_PICKER: React.ComponentType<DatePickerProps>;
383
+ DATE_TIME_INPUT: React.ComponentType<DateTimeInputProps>;
384
+ FILE_UPLOAD: React.ComponentType<FileUploadProps>;
385
+ NUMBER_INPUT: React.ComponentType<NumberInputProps>;
386
+ CHECKBOX: React.ComponentType<CheckboxProps>;
387
+ SIGNATURE: React.ComponentType<SignatureProps>;
388
+ RATING_INPUT: React.ComponentType<RatingInputProps>;
389
+ RADIO_GROUP: React.ComponentType<RadioGroupProps>;
390
+ CHECKBOX_GROUP: React.ComponentType<CheckboxGroupProps>;
391
+ DROPDOWN: React.ComponentType<DropdownProps>;
392
+ TAGS: React.ComponentType<TagsProps>;
393
+ TIME_INPUT: React.ComponentType<TimeInputProps>;
394
+ TEXT: React.ComponentType<RichTextProps>;
395
+ SUBMIT_BUTTON: React.ComponentType<SubmitButtonProps>;
396
+ PRODUCT_LIST: React.ComponentType<ProductListProps>;
397
+ FIXED_PAYMENT: React.ComponentType<FixedPaymentProps>;
398
+ PAYMENT_INPUT: React.ComponentType<PaymentInputProps>;
399
+ DONATION: React.ComponentType<DonationProps>;
400
+ APPOINTMENT: React.ComponentType<AppointmentProps>;
401
+ IMAGE_CHOICE: React.ComponentType<ImageChoiceProps>;
402
+ }
403
+ /**
404
+ * Props for the Form Fields component.
405
+ *
406
+ * @interface FieldsProps
407
+ * @property {FieldMap} fieldMap - A mapping of field types to their corresponding React components
408
+ * @property {string} rowGapClassname - CSS class name for gap between rows
409
+ * @property {string} columnGapClassname - CSS class name for gap between columns
410
+ * @example
411
+ * ```tsx
412
+ * const FIELD_MAP = {
413
+ * TEXT_INPUT: TextInput,
414
+ * TEXT_AREA: TextArea,
415
+ * NUMBER_INPUT: NumberInput,
416
+ * CHECKBOX: Checkbox,
417
+ * RADIO_GROUP: RadioGroup,
418
+ * CHECKBOX_GROUP: CheckboxGroup,
419
+ * DROPDOWN: Dropdown,
420
+ * // ... remaining field components
421
+ * };
422
+ *
423
+ * <Form.Fields fieldMap={FIELD_MAP} rowGapClassname="gap-y-4" columnGapClassname="gap-x-2" />
424
+ * ```
425
+ */
426
+ interface FieldsProps {
427
+ fieldMap: FieldMap;
428
+ rowGapClassname: string;
429
+ columnGapClassname: string;
430
+ }
431
+ /**
432
+ * Fields component for rendering a form with custom field renderers.
433
+ * This component handles the rendering of form fields based on the provided fieldMap.
434
+ * Must be used within Form.Root to access form context.
435
+ *
436
+ * @component
437
+ * @param {FieldsProps} props - Component props
438
+ * @param {FieldMap} props.fieldMap - A mapping of field types to their corresponding React components
439
+ * @param {string} props.rowGapClassname - CSS class name for gap between rows
440
+ * @param {string} props.columnGapClassname - CSS class name for gap between columns
441
+ * @example
442
+ * ```tsx
443
+ * import { Form } from '@wix/headless-forms/react';
444
+ * import { TextInput, TextArea, Checkbox } from './field-components';
445
+ *
446
+ * const FIELD_MAP = {
447
+ * TEXT_INPUT: TextInput,
448
+ * TEXT_AREA: TextArea,
449
+ * CHECKBOX: Checkbox,
450
+ * NUMBER_INPUT: NumberInput,
451
+ * // ... remaining field components
452
+ * };
453
+ *
454
+ * function ContactForm({ formServiceConfig }) {
455
+ * return (
456
+ * <Form.Root formServiceConfig={formServiceConfig}>
457
+ * <Form.Loading className="flex justify-center p-4" />
458
+ * <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
459
+ * <Form.Fields
460
+ * fieldMap={FIELD_MAP}
461
+ * rowGapClassname="gap-y-4"
462
+ * columnGapClassname="gap-x-2"
463
+ * />
464
+ * </Form.Root>
465
+ * );
466
+ * }
467
+ * ```
468
+ */
469
+ /**
470
+ * Fields component for rendering a form with custom field renderers.
471
+ * It maps each field type from the form configuration to its corresponding React component
472
+ * and renders them in the order and layout defined by the form structure.
473
+ *
474
+ * The component automatically handles:
475
+ * - Field validation and error display
476
+ * - Form state management
477
+ * - Field value updates
478
+ * - Grid layout with configurable row and column gaps
479
+ *
480
+ * Must be used within Form.Root to access form context.
481
+ *
482
+ * @component
483
+ * @param {FieldsProps} props - The component props
484
+ * @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.
485
+ * @param {string} props.rowGapClassname - CSS class name for gap between form rows
486
+ * @param {string} props.columnGapClassname - CSS class name for gap between form columns
487
+ *
488
+ * @example
489
+ * ```tsx
490
+ * import { Form } from '@wix/headless-forms/react';
491
+ * import { loadFormServiceConfig } from '@wix/headless-forms/services';
492
+ * import {
493
+ * TextInput,
494
+ * TextArea,
495
+ * PhoneInput,
496
+ * MultilineAddress,
497
+ * DateInput,
498
+ * DatePicker,
499
+ * DateTimeInput,
500
+ * FileUpload,
501
+ * NumberInput,
502
+ * Checkbox,
503
+ * Signature,
504
+ * RatingInput,
505
+ * RadioGroup,
506
+ * CheckboxGroup,
507
+ * Dropdown,
508
+ * Tags,
509
+ * TimeInput,
510
+ * RichText,
511
+ * SubmitButton,
512
+ * ProductList,
513
+ * FixedPayment,
514
+ * PaymentInput,
515
+ * Donation,
516
+ * Appointment,
517
+ * ImageChoice
518
+ * } from './components';
519
+ *
520
+ * // Define your field mapping - this tells the Fields component which React component to use for each field type
521
+ * const FIELD_MAP = {
522
+ * TEXT_INPUT: TextInput,
523
+ * TEXT_AREA: TextArea,
524
+ * PHONE_INPUT: PhoneInput,
525
+ * MULTILINE_ADDRESS: MultilineAddress,
526
+ * DATE_INPUT: DateInput,
527
+ * DATE_PICKER: DatePicker,
528
+ * DATE_TIME_INPUT: DateTimeInput,
529
+ * FILE_UPLOAD: FileUpload,
530
+ * NUMBER_INPUT: NumberInput,
531
+ * CHECKBOX: Checkbox,
532
+ * SIGNATURE: Signature,
533
+ * RATING_INPUT: RatingInput,
534
+ * RADIO_GROUP: RadioGroup,
535
+ * CHECKBOX_GROUP: CheckboxGroup,
536
+ * DROPDOWN: Dropdown,
537
+ * TAGS: Tags,
538
+ * TIME_INPUT: TimeInput,
539
+ * TEXT: RichText,
540
+ * SUBMIT_BUTTON: SubmitButton,
541
+ * PRODUCT_LIST: ProductList,
542
+ * FIXED_PAYMENT: FixedPayment,
543
+ * PAYMENT_INPUT: PaymentInput,
544
+ * DONATION: Donation,
545
+ * APPOINTMENT: Appointment,
546
+ * IMAGE_CHOICE: ImageChoice,
547
+ * };
548
+ *
549
+ * function ContactForm({ formServiceConfig }) {
550
+ * return (
551
+ * <Form.Root formServiceConfig={formServiceConfig}>
552
+ * <Form.Loading className="flex justify-center p-4" />
553
+ * <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
554
+ * <Form.Fields
555
+ * fieldMap={FIELD_MAP}
556
+ * rowGapClassname="gap-y-4"
557
+ * columnGapClassname="gap-x-2"
558
+ * />
559
+ * <Form.Error className="text-destructive p-4 rounded-lg mb-4" />
560
+ * <Form.Submitted className="text-green-500 p-4 rounded-lg mb-4" />
561
+ * </Form.Root>
562
+ * );
563
+ * }
564
+ * ```
565
+ *
566
+ * @example
567
+ * ```tsx
568
+ * // Creating custom field components - ALL field components MUST use Form.Field
569
+ * // This example shows the REQUIRED structure for a TEXT_INPUT component
570
+ * import { Form, type TextInputProps } from '@wix/headless-forms/react';
571
+ *
572
+ * const TextInput = (props: TextInputProps) => {
573
+ * const { id, value, onChange, label, error, required, ...inputProps } = props;
574
+ *
575
+ * // Form.Field provides automatic grid layout positioning
576
+ * return (
577
+ * <Form.Field id={id}>
578
+ * <Form.Field.Label>
579
+ * <label className="text-foreground font-paragraph">
580
+ * {label}
581
+ * {required && <span className="text-destructive ml-1">*</span>}
582
+ * </label>
583
+ * </Form.Field.Label>
584
+ * <Form.Field.Input
585
+ * description={error && <span className="text-destructive text-sm">{error}</span>}
586
+ * >
587
+ * <input
588
+ * type="text"
589
+ * value={value || ''}
590
+ * onChange={(e) => onChange(e.target.value)}
591
+ * className="bg-background border-foreground text-foreground"
592
+ * aria-invalid={!!error}
593
+ * {...inputProps}
594
+ * />
595
+ * </Form.Field.Input>
596
+ * </Form.Field>
597
+ * );
598
+ * };
599
+ *
600
+ * const FIELD_MAP = {
601
+ * TEXT_INPUT: TextInput,
602
+ * // ... all other field components must also use Form.Field
603
+ * };
604
+ * ```
605
+ */
606
+ export declare const Fields: React.ForwardRefExoticComponent<FieldsProps & React.RefAttributes<HTMLDivElement>>;
607
+ /**
608
+ * Props for Field container component
609
+ */
610
+ export interface FieldProps {
611
+ /** The unique identifier for this field */
612
+ id: string;
613
+ /** Child components (Field.Label, Field.Input, etc.) */
614
+ children: React.ReactNode;
615
+ /** Whether to render as a child component */
616
+ asChild?: boolean;
617
+ /** CSS classes to apply to the root element */
618
+ className?: string;
619
+ }
620
+ /**
621
+ * Field component with sub-components
622
+ */
623
+ interface FieldComponent extends React.ForwardRefExoticComponent<FieldProps & React.RefAttributes<HTMLDivElement>> {
624
+ Label: typeof FieldLabel;
625
+ InputWrapper: typeof FieldInputWrapper;
626
+ Input: typeof FieldInput;
627
+ Error: typeof FieldError;
628
+ }
629
+ /**
630
+ * Props for Field.Label component
631
+ */
632
+ export interface FieldLabelProps {
633
+ /** Label content to display */
634
+ children: React.ReactNode;
635
+ /** Whether to render as a child component */
636
+ asChild?: boolean;
637
+ /** CSS classes to apply to the label element */
638
+ className?: string;
639
+ }
640
+ export interface FieldInputWrapperProps {
641
+ /** Child components (typically Field.Input and Field.Error) */
642
+ children: React.ReactNode;
643
+ /** Whether to render as a child component */
644
+ asChild?: boolean;
645
+ /** CSS classes to apply to the wrapper element */
646
+ className?: string;
647
+ }
648
+ /**
649
+ * Props for Field.Input component
650
+ */
651
+ export interface FieldInputProps {
652
+ /** Input element to render */
653
+ children: React.ReactNode;
654
+ /** Whether to render as a child component */
655
+ asChild?: boolean;
656
+ /** CSS classes to apply to the input element */
657
+ className?: string;
658
+ /** Description text to display below the input */
659
+ description?: React.ReactNode;
660
+ }
661
+ /**
662
+ * Render props for Field.Error component
663
+ */
664
+ export interface FieldErrorRenderProps {
665
+ /** The error type */
666
+ type: FormError['errorType'];
667
+ /** The error message */
668
+ message: string;
669
+ }
670
+ /**
671
+ * Props for Field.Error component
672
+ */
673
+ export interface FieldErrorProps {
674
+ /** Whether to render as a child component */
675
+ asChild?: boolean;
676
+ /** CSS classes to apply to the error element */
677
+ className?: string;
678
+ /** The error message */
679
+ errorMessage?: string;
680
+ /** Child components to render */
681
+ children?: React.ReactNode;
682
+ }
683
+ /**
684
+ * Props for Field.Label.Required component
685
+ */
686
+ export interface FieldLabelRequiredProps {
687
+ /** Whether to show the required indicator */
688
+ required?: boolean;
689
+ /** Custom content to display (defaults to red asterisk) */
690
+ children?: React.ReactNode;
691
+ /** Whether to render as a child component */
692
+ asChild?: boolean;
693
+ /** CSS classes to apply to the required indicator */
694
+ className?: string;
695
+ }
696
+ /**
697
+ * Required indicator component for form field labels.
698
+ * Must be used within a Form.Field.Label component.
699
+ *
700
+ * @component
701
+ * @example
702
+ * ```tsx
703
+ * import { Form } from '@wix/headless-forms/react';
704
+ *
705
+ * // Basic usage with required prop
706
+ * <Form.Field.Label>
707
+ * <label className="text-foreground font-paragraph">
708
+ * Email Address
709
+ * <Form.Field.Label.Required />
710
+ * </label>
711
+ * </Form.Field.Label>
712
+ *
713
+ * // Custom styling
714
+ * <Form.Field.Label>
715
+ * <label className="text-foreground font-paragraph">
716
+ * Username
717
+ * <Form.Field.Label.Required required={true} className="text-destructive ml-2" />
718
+ * </label>
719
+ * </Form.Field.Label>
720
+ */
721
+ export declare const FieldLabelRequired: React.ForwardRefExoticComponent<FieldLabelRequiredProps & React.RefAttributes<HTMLSpanElement>>;
722
+ interface FieldLabelComponent extends React.ForwardRefExoticComponent<FieldLabelProps & React.RefAttributes<HTMLDivElement>> {
723
+ Required: typeof FieldLabelRequired;
724
+ }
725
+ export declare const FieldLabel: FieldLabelComponent;
726
+ /**
727
+ * InputWrapper component that wraps input and error elements with grid positioning.
728
+ * Must be used within a Form.Field component.
729
+ * This wrapper applies the grid positioning styles to contain both the input and error.
730
+ *
731
+ * @component
732
+ * @example
733
+ * ```tsx
734
+ * import { Form } from '@wix/headless-forms/react';
735
+ *
736
+ * <Form.Field id="email">
737
+ * <Form.Field.Label>
738
+ * <label className="text-foreground font-paragraph">Email Address</label>
739
+ * </Form.Field.Label>
740
+ * <Form.Field.InputWrapper>
741
+ * <Form.Field.Input>
742
+ * <input type="email" className="bg-background border-foreground text-foreground" />
743
+ * </Form.Field.Input>
744
+ * <Form.Field.Error>
745
+ * <span className="text-destructive text-sm font-paragraph">Please enter a valid email</span>
746
+ * </Form.Field.Error>
747
+ * </Form.Field.InputWrapper>
748
+ * </Form.Field>
749
+ * ```
750
+ */
751
+ export declare const FieldInputWrapper: React.ForwardRefExoticComponent<FieldInputWrapperProps & React.RefAttributes<HTMLDivElement>>;
752
+ /**
753
+ * Input component for a form field.
754
+ * Must be used within a Form.Field.InputWrapper component.
755
+ * Renders the actual input element without grid positioning.
756
+ *
757
+ * @component
758
+ * @example
759
+ * ```tsx
760
+ * import { Form } from '@wix/headless-forms/react';
761
+ *
762
+ * <Form.Field id="password">
763
+ * <Form.Field.Label>
764
+ * <label className="text-foreground font-paragraph">Password</label>
765
+ * </Form.Field.Label>
766
+ * <Form.Field.InputWrapper>
767
+ * <Form.Field.Input description={<span className="text-secondary-foreground">Min 8 characters</span>}>
768
+ * <input type="password" className="bg-background border-foreground text-foreground" />
769
+ * </Form.Field.Input>
770
+ * </Form.Field.InputWrapper>
771
+ * </Form.Field>
772
+ * ```
773
+ */
774
+ export declare const FieldInput: React.ForwardRefExoticComponent<FieldInputProps & React.RefAttributes<HTMLDivElement>>;
775
+ /**
776
+ * Error component for displaying field-level validation errors.
777
+ * Must be used within a Form.Field.InputWrapper component.
778
+ * Only renders when there is an error for the current field.
779
+ *
780
+ * @component
781
+ * @example
782
+ * ```tsx
783
+ * import { Form } from '@wix/headless-forms/react';
784
+ *
785
+ * <Form.Field id="email">
786
+ * <Form.Field.Label>
787
+ * <label className="text-foreground font-paragraph">Email Address</label>
788
+ * </Form.Field.Label>
789
+ * <Form.Field.InputWrapper>
790
+ * <Form.Field.Input>
791
+ * <input type="email" className="bg-background border-foreground text-foreground" />
792
+ * </Form.Field.Input>
793
+ * <Form.Field.Error path="email">
794
+ * <span className="text-destructive text-sm font-paragraph">Please enter a valid email address</span>
795
+ * </Form.Field.Error>
796
+ * </Form.Field.InputWrapper>
797
+ * </Form.Field>
798
+ * ```
799
+ */
800
+ export declare const FieldError: React.ForwardRefExoticComponent<FieldErrorProps & React.RefAttributes<HTMLDivElement>>;
801
+ export declare const Field: FieldComponent;
802
+ export {};