@wix/headless-forms 0.0.22 → 0.0.23
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/cjs/dist/react/Form.d.ts +24 -2
- package/cjs/dist/react/Form.js +27 -4
- package/cjs/dist/react/core/Form.d.ts +38 -8
- package/cjs/dist/react/core/Form.js +41 -3
- package/cjs/dist/react/types.d.ts +2 -2
- package/cjs/dist/services/form-service.js +9 -32
- package/dist/react/Form.d.ts +24 -2
- package/dist/react/Form.js +28 -5
- package/dist/react/core/Form.d.ts +38 -8
- package/dist/react/core/Form.js +37 -3
- package/dist/react/types.d.ts +2 -2
- package/dist/services/form-service.js +10 -33
- package/package.json +3 -3
package/cjs/dist/react/Form.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
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';
|
|
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, type LoginBarProps } from './types.js';
|
|
4
4
|
import { type FormServiceConfig } from '../services/form-service.js';
|
|
5
5
|
/**
|
|
6
6
|
* Props for the Form root component following the documented API
|
|
@@ -22,7 +22,9 @@ export interface RootProps {
|
|
|
22
22
|
* @component
|
|
23
23
|
* @param {RootProps} props - The component props
|
|
24
24
|
* @param {React.ReactNode} props.children - Child components that will have access to form context
|
|
25
|
-
* @param {FormServiceConfig} props.formServiceConfig - Form service configuration object
|
|
25
|
+
* @param {FormServiceConfig} props.formServiceConfig - Form service configuration object. Supports two patterns:
|
|
26
|
+
* - Pre-loaded form data: `{ form: Form, onSubmit?: Function, addressTemplates?: any[] }`
|
|
27
|
+
* - Lazy loading: `{ formId: string, namespace?: string, additionalMetadata?: Record<string, string | string[]>, onSubmit?: Function }`
|
|
26
28
|
* @param {boolean} [props.asChild] - Whether to render as a child component
|
|
27
29
|
* @param {string} [props.className] - CSS classes to apply to the root element
|
|
28
30
|
* @example
|
|
@@ -62,6 +64,25 @@ export interface RootProps {
|
|
|
62
64
|
* </Form.Root>
|
|
63
65
|
* );
|
|
64
66
|
* }
|
|
67
|
+
*
|
|
68
|
+
* // Pattern 3: With namespace and additional metadata (for bookings, etc.)
|
|
69
|
+
* function BookingFormPage({ formId }) {
|
|
70
|
+
* return (
|
|
71
|
+
* <Form.Root
|
|
72
|
+
* formServiceConfig={{
|
|
73
|
+
* formId,
|
|
74
|
+
* namespace: 'wix.bookings.form',
|
|
75
|
+
* additionalMetadata: { serviceId: ['service-123'] },
|
|
76
|
+
* }}
|
|
77
|
+
* >
|
|
78
|
+
* <Form.Loading className="flex justify-center p-4" />
|
|
79
|
+
* <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
|
|
80
|
+
* <Form.Fields fieldMap={FIELD_MAP} />
|
|
81
|
+
* <Form.Error className="text-destructive p-4 rounded-lg mb-4" />
|
|
82
|
+
* <Form.Submitted className="text-green-500 p-4 rounded-lg mb-4" />
|
|
83
|
+
* </Form.Root>
|
|
84
|
+
* );
|
|
85
|
+
* }
|
|
65
86
|
* ```
|
|
66
87
|
*/
|
|
67
88
|
export declare const Root: React.ForwardRefExoticComponent<RootProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -399,6 +420,7 @@ export interface FieldMap {
|
|
|
399
420
|
DONATION: React.ComponentType<DonationProps>;
|
|
400
421
|
APPOINTMENT: React.ComponentType<AppointmentProps>;
|
|
401
422
|
IMAGE_CHOICE: React.ComponentType<ImageChoiceProps>;
|
|
423
|
+
LOGIN_BAR: React.ComponentType<LoginBarProps>;
|
|
402
424
|
}
|
|
403
425
|
/**
|
|
404
426
|
* Props for the Form Fields component.
|
package/cjs/dist/react/Form.js
CHANGED
|
@@ -65,7 +65,9 @@ var TestIds;
|
|
|
65
65
|
* @component
|
|
66
66
|
* @param {RootProps} props - The component props
|
|
67
67
|
* @param {React.ReactNode} props.children - Child components that will have access to form context
|
|
68
|
-
* @param {FormServiceConfig} props.formServiceConfig - Form service configuration object
|
|
68
|
+
* @param {FormServiceConfig} props.formServiceConfig - Form service configuration object. Supports two patterns:
|
|
69
|
+
* - Pre-loaded form data: `{ form: Form, onSubmit?: Function, addressTemplates?: any[] }`
|
|
70
|
+
* - Lazy loading: `{ formId: string, namespace?: string, additionalMetadata?: Record<string, string | string[]>, onSubmit?: Function }`
|
|
69
71
|
* @param {boolean} [props.asChild] - Whether to render as a child component
|
|
70
72
|
* @param {string} [props.className] - CSS classes to apply to the root element
|
|
71
73
|
* @example
|
|
@@ -105,11 +107,30 @@ var TestIds;
|
|
|
105
107
|
* </Form.Root>
|
|
106
108
|
* );
|
|
107
109
|
* }
|
|
110
|
+
*
|
|
111
|
+
* // Pattern 3: With namespace and additional metadata (for bookings, etc.)
|
|
112
|
+
* function BookingFormPage({ formId }) {
|
|
113
|
+
* return (
|
|
114
|
+
* <Form.Root
|
|
115
|
+
* formServiceConfig={{
|
|
116
|
+
* formId,
|
|
117
|
+
* namespace: 'wix.bookings.form',
|
|
118
|
+
* additionalMetadata: { serviceId: ['service-123'] },
|
|
119
|
+
* }}
|
|
120
|
+
* >
|
|
121
|
+
* <Form.Loading className="flex justify-center p-4" />
|
|
122
|
+
* <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
|
|
123
|
+
* <Form.Fields fieldMap={FIELD_MAP} />
|
|
124
|
+
* <Form.Error className="text-destructive p-4 rounded-lg mb-4" />
|
|
125
|
+
* <Form.Submitted className="text-green-500 p-4 rounded-lg mb-4" />
|
|
126
|
+
* </Form.Root>
|
|
127
|
+
* );
|
|
128
|
+
* }
|
|
108
129
|
* ```
|
|
109
130
|
*/
|
|
110
131
|
exports.Root = react_1.default.forwardRef((props, ref) => {
|
|
111
132
|
const { children, formServiceConfig, asChild, ...otherProps } = props;
|
|
112
|
-
return ((0, jsx_runtime_1.jsx)(Form_js_1.Root, { formServiceConfig: formServiceConfig, children: (0, jsx_runtime_1.jsx)(RootContent, { asChild: asChild, ref: ref, ...otherProps, children: children }) }));
|
|
133
|
+
return ((0, jsx_runtime_1.jsx)(Form_js_1.Root, { formServiceConfig: formServiceConfig, formRef: ref, children: (0, jsx_runtime_1.jsx)(RootContent, { asChild: asChild, ref: ref, ...otherProps, children: children }) }));
|
|
113
134
|
});
|
|
114
135
|
/**
|
|
115
136
|
* Internal component to handle the Root content with service access.
|
|
@@ -528,16 +549,17 @@ exports.Fields = react_1.default.forwardRef((props, ref) => {
|
|
|
528
549
|
const [formErrors, setFormErrors] = (0, react_1.useState)([]);
|
|
529
550
|
const currentLocale = essentials_1.i18n.getLocale();
|
|
530
551
|
const currentLanguage = essentials_1.i18n.getLanguage();
|
|
552
|
+
const formRef = (0, Form_js_1.useFormRef)();
|
|
531
553
|
const handleFormValidate = (0, react_1.useCallback)((errors) => {
|
|
532
554
|
setFormErrors(errors);
|
|
533
555
|
}, []);
|
|
534
556
|
return ((0, jsx_runtime_1.jsx)(Form_js_1.Fields, { children: ({ form, formValues, submitForm, handleForm, addressTemplates }) => {
|
|
535
557
|
if (!form)
|
|
536
558
|
return null;
|
|
537
|
-
return ((0, jsx_runtime_1.jsx)("div", { ref: ref, children: (0, jsx_runtime_1.jsx)(form_public_1.FormProvider, { currency: 'USD', locale: currentLanguage, regionalFormat: currentLocale, addressTemplates: addressTemplates, children: (0, jsx_runtime_1.jsx)(form_public_1.UniqueFieldSuffixContextProvider, { parentId: form._id ?? '', children: (0, jsx_runtime_1.jsx)(FieldsWithForm, { form: form, values: formValues, onChange: handleForm, errors: formErrors, onValidate: handleFormValidate, fields: props.fieldMap, submitForm: submitForm, rowGapClassname: props.rowGapClassname, columnGapClassname: props.columnGapClassname }) }) }) }));
|
|
559
|
+
return ((0, jsx_runtime_1.jsx)("div", { ref: ref, children: (0, jsx_runtime_1.jsx)(form_public_1.FormProvider, { currency: 'USD', locale: currentLanguage, regionalFormat: currentLocale, addressTemplates: addressTemplates, children: (0, jsx_runtime_1.jsx)(form_public_1.UniqueFieldSuffixContextProvider, { parentId: form._id ?? '', children: (0, jsx_runtime_1.jsx)(FieldsWithForm, { form: form, values: formValues, onChange: handleForm, errors: formErrors, onValidate: handleFormValidate, fields: props.fieldMap, submitForm: submitForm, rowGapClassname: props.rowGapClassname, columnGapClassname: props.columnGapClassname, formRef: formRef }) }) }) }));
|
|
538
560
|
} }));
|
|
539
561
|
});
|
|
540
|
-
const FieldsWithForm = ({ form, submitForm, values, onChange, errors, onValidate, fields: fieldMap, rowGapClassname, columnGapClassname, }) => {
|
|
562
|
+
const FieldsWithForm = ({ form, submitForm, values, onChange, errors, onValidate, fields: fieldMap, rowGapClassname, columnGapClassname, formRef, }) => {
|
|
541
563
|
const coreUploadFile = async ({ file, formId, }) => {
|
|
542
564
|
const uploadUrl = await (0, utils_1.getUploadUrl)(formId, file);
|
|
543
565
|
if (uploadUrl === undefined) {
|
|
@@ -560,6 +582,7 @@ const FieldsWithForm = ({ form, submitForm, values, onChange, errors, onValidate
|
|
|
560
582
|
submitForm,
|
|
561
583
|
uploadFile: coreUploadFile,
|
|
562
584
|
fieldMap,
|
|
585
|
+
forwardedRef: formRef,
|
|
563
586
|
});
|
|
564
587
|
if (!formData)
|
|
565
588
|
return null;
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
import { forms } from '@wix/forms';
|
|
2
3
|
import { FormServiceConfig } from '../../services/form-service.js';
|
|
3
4
|
import { FormValues } from '../types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Hook to access the form ref from context
|
|
7
|
+
*/
|
|
8
|
+
export declare function useFormRef(): React.Ref<any> | undefined;
|
|
4
9
|
/**
|
|
5
10
|
* Props for Root headless component
|
|
6
11
|
*/
|
|
7
12
|
export interface RootProps {
|
|
8
13
|
children: React.ReactNode;
|
|
9
14
|
formServiceConfig: FormServiceConfig;
|
|
15
|
+
/** Optional ref to access form methods imperatively */
|
|
16
|
+
formRef?: React.Ref<any>;
|
|
10
17
|
}
|
|
11
18
|
/**
|
|
12
19
|
* Root component that provides the Form service context to its children.
|
|
@@ -16,7 +23,9 @@ export interface RootProps {
|
|
|
16
23
|
* @component
|
|
17
24
|
* @param {RootProps} props - Component props
|
|
18
25
|
* @param {React.ReactNode} props.children - Child components that will have access to form context
|
|
19
|
-
* @param {FormServiceConfig} props.formServiceConfig - Configuration object containing form data
|
|
26
|
+
* @param {FormServiceConfig} props.formServiceConfig - Configuration object containing form data. Supports two patterns:
|
|
27
|
+
* - Pre-loaded form data: `{ form: Form, onSubmit?: Function, addressTemplates?: any[] }`
|
|
28
|
+
* - Lazy loading: `{ formId: string, namespace?: string, additionalMetadata?: Record<string, string | string[]>, onSubmit?: Function }`
|
|
20
29
|
* @example
|
|
21
30
|
* ```tsx
|
|
22
31
|
* import { Form } from '@wix/headless-forms/react';
|
|
@@ -51,9 +60,30 @@ export interface RootProps {
|
|
|
51
60
|
* </Form.Root>
|
|
52
61
|
* );
|
|
53
62
|
* }
|
|
63
|
+
*
|
|
64
|
+
* // Pattern 3: With namespace and additional metadata (for bookings, etc.)
|
|
65
|
+
* function BookingFormPage({ formId }) {
|
|
66
|
+
* return (
|
|
67
|
+
* <Form.Root
|
|
68
|
+
* formServiceConfig={{
|
|
69
|
+
* formId,
|
|
70
|
+
* namespace: 'wix.bookings.form',
|
|
71
|
+
* additionalMetadata: { serviceId: ['service-123'] },
|
|
72
|
+
* }}
|
|
73
|
+
* >
|
|
74
|
+
* <Form.Loading>
|
|
75
|
+
* {({ isLoading }) => isLoading ? <div>Loading form...</div> : null}
|
|
76
|
+
* </Form.Loading>
|
|
77
|
+
* <Form.LoadingError>
|
|
78
|
+
* {({ error, hasError }) => hasError ? <div>{error}</div> : null}
|
|
79
|
+
* </Form.LoadingError>
|
|
80
|
+
* <Form.Fields fieldMap={FIELD_MAP} />
|
|
81
|
+
* </Form.Root>
|
|
82
|
+
* );
|
|
83
|
+
* }
|
|
54
84
|
* ```
|
|
55
85
|
*/
|
|
56
|
-
export declare function Root({ formServiceConfig, children, }: RootProps): React.ReactNode;
|
|
86
|
+
export declare function Root({ formServiceConfig, formRef, children, }: RootProps): React.ReactNode;
|
|
57
87
|
/**
|
|
58
88
|
* Props for FormLoading headless component
|
|
59
89
|
*/
|
|
@@ -91,7 +121,7 @@ export interface FormLoadingRenderProps {
|
|
|
91
121
|
* }
|
|
92
122
|
* ```
|
|
93
123
|
*/
|
|
94
|
-
export declare function Loading(props: FormLoadingProps):
|
|
124
|
+
export declare function Loading(props: FormLoadingProps): React.ReactNode;
|
|
95
125
|
/**
|
|
96
126
|
* Props for FormError headless component
|
|
97
127
|
*/
|
|
@@ -133,7 +163,7 @@ export interface FormErrorRenderProps {
|
|
|
133
163
|
* }
|
|
134
164
|
* ```
|
|
135
165
|
*/
|
|
136
|
-
export declare function LoadingError(props: FormErrorProps):
|
|
166
|
+
export declare function LoadingError(props: FormErrorProps): React.ReactNode;
|
|
137
167
|
/**
|
|
138
168
|
* Props for Form Submit Error headless component
|
|
139
169
|
*/
|
|
@@ -175,7 +205,7 @@ export interface FormSubmitErrorRenderProps {
|
|
|
175
205
|
* }
|
|
176
206
|
* ```
|
|
177
207
|
*/
|
|
178
|
-
export declare function Error(props: FormSubmitErrorProps):
|
|
208
|
+
export declare function Error(props: FormSubmitErrorProps): React.ReactNode;
|
|
179
209
|
/**
|
|
180
210
|
* Props for Form Submitted headless component
|
|
181
211
|
*/
|
|
@@ -218,7 +248,7 @@ export interface FormSubmittedRenderProps {
|
|
|
218
248
|
* }
|
|
219
249
|
* ```
|
|
220
250
|
*/
|
|
221
|
-
export declare function Submitted(props: FormSubmittedProps):
|
|
251
|
+
export declare function Submitted(props: FormSubmittedProps): React.ReactNode;
|
|
222
252
|
/**
|
|
223
253
|
* Render props for Fields component
|
|
224
254
|
*/
|
|
@@ -269,7 +299,7 @@ export interface FieldsProps {
|
|
|
269
299
|
* }
|
|
270
300
|
* ```
|
|
271
301
|
*/
|
|
272
|
-
export declare function Fields(props: FieldsProps):
|
|
302
|
+
export declare function Fields(props: FieldsProps): React.ReactNode;
|
|
273
303
|
/**
|
|
274
304
|
* Form view interface containing field definitions
|
|
275
305
|
*/
|
|
@@ -342,4 +372,4 @@ export interface FieldProps {
|
|
|
342
372
|
* }
|
|
343
373
|
* ```
|
|
344
374
|
*/
|
|
345
|
-
export declare function Field(props: FieldProps):
|
|
375
|
+
export declare function Field(props: FieldProps): React.ReactNode;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.useFormRef = useFormRef;
|
|
3
7
|
exports.Root = Root;
|
|
4
8
|
exports.Loading = Loading;
|
|
5
9
|
exports.LoadingError = LoadingError;
|
|
@@ -8,11 +12,22 @@ exports.Submitted = Submitted;
|
|
|
8
12
|
exports.Fields = Fields;
|
|
9
13
|
exports.Field = Field;
|
|
10
14
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
15
|
+
const react_1 = __importDefault(require("react"));
|
|
11
16
|
const services_manager_react_1 = require("@wix/services-manager-react");
|
|
12
17
|
const services_manager_1 = require("@wix/services-manager");
|
|
13
18
|
const form_service_js_1 = require("../../services/form-service.js");
|
|
14
19
|
const utils_js_1 = require("../utils.js");
|
|
15
20
|
const DEFAULT_SUCCESS_MESSAGE = 'Your form has been submitted successfully.';
|
|
21
|
+
/**
|
|
22
|
+
* Context for passing form ref from Root to Fields
|
|
23
|
+
*/
|
|
24
|
+
const FormRefContext = react_1.default.createContext(undefined);
|
|
25
|
+
/**
|
|
26
|
+
* Hook to access the form ref from context
|
|
27
|
+
*/
|
|
28
|
+
function useFormRef() {
|
|
29
|
+
return react_1.default.useContext(FormRefContext);
|
|
30
|
+
}
|
|
16
31
|
/**
|
|
17
32
|
* Root component that provides the Form service context to its children.
|
|
18
33
|
* This component sets up the necessary services for rendering and managing form data.
|
|
@@ -21,7 +36,9 @@ const DEFAULT_SUCCESS_MESSAGE = 'Your form has been submitted successfully.';
|
|
|
21
36
|
* @component
|
|
22
37
|
* @param {RootProps} props - Component props
|
|
23
38
|
* @param {React.ReactNode} props.children - Child components that will have access to form context
|
|
24
|
-
* @param {FormServiceConfig} props.formServiceConfig - Configuration object containing form data
|
|
39
|
+
* @param {FormServiceConfig} props.formServiceConfig - Configuration object containing form data. Supports two patterns:
|
|
40
|
+
* - Pre-loaded form data: `{ form: Form, onSubmit?: Function, addressTemplates?: any[] }`
|
|
41
|
+
* - Lazy loading: `{ formId: string, namespace?: string, additionalMetadata?: Record<string, string | string[]>, onSubmit?: Function }`
|
|
25
42
|
* @example
|
|
26
43
|
* ```tsx
|
|
27
44
|
* import { Form } from '@wix/headless-forms/react';
|
|
@@ -56,10 +73,31 @@ const DEFAULT_SUCCESS_MESSAGE = 'Your form has been submitted successfully.';
|
|
|
56
73
|
* </Form.Root>
|
|
57
74
|
* );
|
|
58
75
|
* }
|
|
76
|
+
*
|
|
77
|
+
* // Pattern 3: With namespace and additional metadata (for bookings, etc.)
|
|
78
|
+
* function BookingFormPage({ formId }) {
|
|
79
|
+
* return (
|
|
80
|
+
* <Form.Root
|
|
81
|
+
* formServiceConfig={{
|
|
82
|
+
* formId,
|
|
83
|
+
* namespace: 'wix.bookings.form',
|
|
84
|
+
* additionalMetadata: { serviceId: ['service-123'] },
|
|
85
|
+
* }}
|
|
86
|
+
* >
|
|
87
|
+
* <Form.Loading>
|
|
88
|
+
* {({ isLoading }) => isLoading ? <div>Loading form...</div> : null}
|
|
89
|
+
* </Form.Loading>
|
|
90
|
+
* <Form.LoadingError>
|
|
91
|
+
* {({ error, hasError }) => hasError ? <div>{error}</div> : null}
|
|
92
|
+
* </Form.LoadingError>
|
|
93
|
+
* <Form.Fields fieldMap={FIELD_MAP} />
|
|
94
|
+
* </Form.Root>
|
|
95
|
+
* );
|
|
96
|
+
* }
|
|
59
97
|
* ```
|
|
60
98
|
*/
|
|
61
|
-
function Root({ formServiceConfig, children, }) {
|
|
62
|
-
return ((0, jsx_runtime_1.jsx)(services_manager_react_1.WixServices, { servicesMap: (0, services_manager_1.createServicesMap)().addService(form_service_js_1.FormServiceDefinition, form_service_js_1.FormService, formServiceConfig), children: children }));
|
|
99
|
+
function Root({ formServiceConfig, formRef, children, }) {
|
|
100
|
+
return ((0, jsx_runtime_1.jsx)(services_manager_react_1.WixServices, { servicesMap: (0, services_manager_1.createServicesMap)().addService(form_service_js_1.FormServiceDefinition, form_service_js_1.FormService, formServiceConfig), children: (0, jsx_runtime_1.jsx)(FormRefContext.Provider, { value: formRef, children: children }) }));
|
|
63
101
|
}
|
|
64
102
|
/**
|
|
65
103
|
* Headless component for form loading state access
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
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 '@wix/form-public';
|
|
2
|
-
export type { CheckboxGroupProps, CheckboxProps, PhoneInputProps, DateInputProps, DatePickerProps, DateTimeInputProps, DropdownProps, FileUploadProps, MultilineAddressProps, NumberInputProps, RadioGroupProps, RatingInputProps, RichTextProps, SignatureProps, SubmitButtonProps, TagsProps, TextAreaProps, TextInputProps, TimeInputProps, ProductListProps, FixedPaymentProps, PaymentInputProps, DonationProps, AppointmentProps, ImageChoiceProps, };
|
|
1
|
+
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, type UseFormProps, type LoginBarProps } from '@wix/form-public';
|
|
2
|
+
export type { CheckboxGroupProps, CheckboxProps, PhoneInputProps, DateInputProps, DatePickerProps, DateTimeInputProps, DropdownProps, FileUploadProps, MultilineAddressProps, NumberInputProps, RadioGroupProps, RatingInputProps, RichTextProps, SignatureProps, SubmitButtonProps, TagsProps, TextAreaProps, TextInputProps, TimeInputProps, ProductListProps, FixedPaymentProps, PaymentInputProps, DonationProps, AppointmentProps, ImageChoiceProps, UseFormProps, LoginBarProps, };
|
|
3
3
|
export type FormValues = Record<string, any>;
|
|
4
4
|
export interface UploadFileParams {
|
|
5
5
|
file: File;
|
|
@@ -5,8 +5,8 @@ exports.loadFormServiceConfig = loadFormServiceConfig;
|
|
|
5
5
|
const forms_1 = require("@wix/forms");
|
|
6
6
|
const services_definitions_1 = require("@wix/services-definitions");
|
|
7
7
|
const signals_1 = require("@wix/services-definitions/core-services/signals");
|
|
8
|
-
const essentials_1 = require("@wix/essentials");
|
|
9
8
|
const address_forms_js_1 = require("./utils/address-forms.js");
|
|
9
|
+
const auto_sdk_forms_forms_1 = require("@wix/auto_sdk_forms_forms");
|
|
10
10
|
/**
|
|
11
11
|
* Service definition for the Form service.
|
|
12
12
|
* This defines the contract that the FormService must implement.
|
|
@@ -151,41 +151,18 @@ exports.FormService = services_definitions_1.implementService.withConfig()(expor
|
|
|
151
151
|
handleForm,
|
|
152
152
|
};
|
|
153
153
|
});
|
|
154
|
-
function
|
|
155
|
-
const params = new URLSearchParams();
|
|
156
|
-
params.append('formId', id);
|
|
157
|
-
if (namespace) {
|
|
158
|
-
params.append('namespace', namespace);
|
|
159
|
-
}
|
|
160
|
-
if (additionalMetadata) {
|
|
161
|
-
Object.entries(additionalMetadata).forEach(([key, value]) => {
|
|
162
|
-
if (Array.isArray(value)) {
|
|
163
|
-
value.forEach((v) => params.append(key, v));
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
params.append(key, value);
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
return params;
|
|
171
|
-
}
|
|
172
|
-
async function fetchForm({ id, namespace, additionalMetadata, }) {
|
|
154
|
+
async function fetchForm({ id, namespace = 'wix.form_app.form', additionalMetadata, }) {
|
|
173
155
|
try {
|
|
174
|
-
const
|
|
175
|
-
id,
|
|
176
|
-
namespace,
|
|
156
|
+
const response = await forms_1.forms.listForms(namespace, {
|
|
177
157
|
additionalMetadata,
|
|
158
|
+
formIds: [id],
|
|
159
|
+
fieldsets: [auto_sdk_forms_forms_1.Fieldset.NESTED_FORMS],
|
|
178
160
|
});
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
throw new Error(`Failed to fetch form: ${response.status} ${response.statusText}`);
|
|
183
|
-
}
|
|
184
|
-
const data = await response.json();
|
|
185
|
-
if (data && data.form) {
|
|
186
|
-
return data.form;
|
|
161
|
+
const form = response.forms?.[0];
|
|
162
|
+
if (!form) {
|
|
163
|
+
throw new Error('Form not found');
|
|
187
164
|
}
|
|
188
|
-
|
|
165
|
+
return form;
|
|
189
166
|
}
|
|
190
167
|
catch (err) {
|
|
191
168
|
console.error('Failed to load form:', id, err);
|
package/dist/react/Form.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
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';
|
|
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, type LoginBarProps } from './types.js';
|
|
4
4
|
import { type FormServiceConfig } from '../services/form-service.js';
|
|
5
5
|
/**
|
|
6
6
|
* Props for the Form root component following the documented API
|
|
@@ -22,7 +22,9 @@ export interface RootProps {
|
|
|
22
22
|
* @component
|
|
23
23
|
* @param {RootProps} props - The component props
|
|
24
24
|
* @param {React.ReactNode} props.children - Child components that will have access to form context
|
|
25
|
-
* @param {FormServiceConfig} props.formServiceConfig - Form service configuration object
|
|
25
|
+
* @param {FormServiceConfig} props.formServiceConfig - Form service configuration object. Supports two patterns:
|
|
26
|
+
* - Pre-loaded form data: `{ form: Form, onSubmit?: Function, addressTemplates?: any[] }`
|
|
27
|
+
* - Lazy loading: `{ formId: string, namespace?: string, additionalMetadata?: Record<string, string | string[]>, onSubmit?: Function }`
|
|
26
28
|
* @param {boolean} [props.asChild] - Whether to render as a child component
|
|
27
29
|
* @param {string} [props.className] - CSS classes to apply to the root element
|
|
28
30
|
* @example
|
|
@@ -62,6 +64,25 @@ export interface RootProps {
|
|
|
62
64
|
* </Form.Root>
|
|
63
65
|
* );
|
|
64
66
|
* }
|
|
67
|
+
*
|
|
68
|
+
* // Pattern 3: With namespace and additional metadata (for bookings, etc.)
|
|
69
|
+
* function BookingFormPage({ formId }) {
|
|
70
|
+
* return (
|
|
71
|
+
* <Form.Root
|
|
72
|
+
* formServiceConfig={{
|
|
73
|
+
* formId,
|
|
74
|
+
* namespace: 'wix.bookings.form',
|
|
75
|
+
* additionalMetadata: { serviceId: ['service-123'] },
|
|
76
|
+
* }}
|
|
77
|
+
* >
|
|
78
|
+
* <Form.Loading className="flex justify-center p-4" />
|
|
79
|
+
* <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
|
|
80
|
+
* <Form.Fields fieldMap={FIELD_MAP} />
|
|
81
|
+
* <Form.Error className="text-destructive p-4 rounded-lg mb-4" />
|
|
82
|
+
* <Form.Submitted className="text-green-500 p-4 rounded-lg mb-4" />
|
|
83
|
+
* </Form.Root>
|
|
84
|
+
* );
|
|
85
|
+
* }
|
|
65
86
|
* ```
|
|
66
87
|
*/
|
|
67
88
|
export declare const Root: React.ForwardRefExoticComponent<RootProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -399,6 +420,7 @@ export interface FieldMap {
|
|
|
399
420
|
DONATION: React.ComponentType<DonationProps>;
|
|
400
421
|
APPOINTMENT: React.ComponentType<AppointmentProps>;
|
|
401
422
|
IMAGE_CHOICE: React.ComponentType<ImageChoiceProps>;
|
|
423
|
+
LOGIN_BAR: React.ComponentType<LoginBarProps>;
|
|
402
424
|
}
|
|
403
425
|
/**
|
|
404
426
|
* Props for the Form Fields component.
|
package/dist/react/Form.js
CHANGED
|
@@ -3,7 +3,7 @@ import React, { useState, useCallback } from 'react';
|
|
|
3
3
|
import { AsChildSlot } from '@wix/headless-utils/react';
|
|
4
4
|
import { useForm, FormProvider, UniqueFieldSuffixContextProvider, } from '@wix/form-public';
|
|
5
5
|
import { i18n } from '@wix/essentials';
|
|
6
|
-
import { Root as CoreRoot, Loading as CoreLoading, LoadingError as CoreLoadingError, Error as CoreError, Submitted as CoreSubmitted, Fields as CoreFields, Field as CoreField, } from './core/Form.js';
|
|
6
|
+
import { Root as CoreRoot, Loading as CoreLoading, LoadingError as CoreLoadingError, Error as CoreError, Submitted as CoreSubmitted, Fields as CoreFields, Field as CoreField, useFormRef, } from './core/Form.js';
|
|
7
7
|
import { FieldContext, useFieldContext, } from './context/FieldContext.js';
|
|
8
8
|
import { FieldLayoutProvider, useFieldLayout, } from './context/FieldLayoutContext.js';
|
|
9
9
|
import { getUploadUrl, uploadFile } from '../services/utils';
|
|
@@ -29,7 +29,9 @@ var TestIds;
|
|
|
29
29
|
* @component
|
|
30
30
|
* @param {RootProps} props - The component props
|
|
31
31
|
* @param {React.ReactNode} props.children - Child components that will have access to form context
|
|
32
|
-
* @param {FormServiceConfig} props.formServiceConfig - Form service configuration object
|
|
32
|
+
* @param {FormServiceConfig} props.formServiceConfig - Form service configuration object. Supports two patterns:
|
|
33
|
+
* - Pre-loaded form data: `{ form: Form, onSubmit?: Function, addressTemplates?: any[] }`
|
|
34
|
+
* - Lazy loading: `{ formId: string, namespace?: string, additionalMetadata?: Record<string, string | string[]>, onSubmit?: Function }`
|
|
33
35
|
* @param {boolean} [props.asChild] - Whether to render as a child component
|
|
34
36
|
* @param {string} [props.className] - CSS classes to apply to the root element
|
|
35
37
|
* @example
|
|
@@ -69,11 +71,30 @@ var TestIds;
|
|
|
69
71
|
* </Form.Root>
|
|
70
72
|
* );
|
|
71
73
|
* }
|
|
74
|
+
*
|
|
75
|
+
* // Pattern 3: With namespace and additional metadata (for bookings, etc.)
|
|
76
|
+
* function BookingFormPage({ formId }) {
|
|
77
|
+
* return (
|
|
78
|
+
* <Form.Root
|
|
79
|
+
* formServiceConfig={{
|
|
80
|
+
* formId,
|
|
81
|
+
* namespace: 'wix.bookings.form',
|
|
82
|
+
* additionalMetadata: { serviceId: ['service-123'] },
|
|
83
|
+
* }}
|
|
84
|
+
* >
|
|
85
|
+
* <Form.Loading className="flex justify-center p-4" />
|
|
86
|
+
* <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
|
|
87
|
+
* <Form.Fields fieldMap={FIELD_MAP} />
|
|
88
|
+
* <Form.Error className="text-destructive p-4 rounded-lg mb-4" />
|
|
89
|
+
* <Form.Submitted className="text-green-500 p-4 rounded-lg mb-4" />
|
|
90
|
+
* </Form.Root>
|
|
91
|
+
* );
|
|
92
|
+
* }
|
|
72
93
|
* ```
|
|
73
94
|
*/
|
|
74
95
|
export const Root = React.forwardRef((props, ref) => {
|
|
75
96
|
const { children, formServiceConfig, asChild, ...otherProps } = props;
|
|
76
|
-
return (_jsx(CoreRoot, { formServiceConfig: formServiceConfig, children: _jsx(RootContent, { asChild: asChild, ref: ref, ...otherProps, children: children }) }));
|
|
97
|
+
return (_jsx(CoreRoot, { formServiceConfig: formServiceConfig, formRef: ref, children: _jsx(RootContent, { asChild: asChild, ref: ref, ...otherProps, children: children }) }));
|
|
77
98
|
});
|
|
78
99
|
/**
|
|
79
100
|
* Internal component to handle the Root content with service access.
|
|
@@ -492,16 +513,17 @@ export const Fields = React.forwardRef((props, ref) => {
|
|
|
492
513
|
const [formErrors, setFormErrors] = useState([]);
|
|
493
514
|
const currentLocale = i18n.getLocale();
|
|
494
515
|
const currentLanguage = i18n.getLanguage();
|
|
516
|
+
const formRef = useFormRef();
|
|
495
517
|
const handleFormValidate = useCallback((errors) => {
|
|
496
518
|
setFormErrors(errors);
|
|
497
519
|
}, []);
|
|
498
520
|
return (_jsx(CoreFields, { children: ({ form, formValues, submitForm, handleForm, addressTemplates }) => {
|
|
499
521
|
if (!form)
|
|
500
522
|
return null;
|
|
501
|
-
return (_jsx("div", { ref: ref, children: _jsx(FormProvider, { currency: 'USD', locale: currentLanguage, regionalFormat: currentLocale, addressTemplates: addressTemplates, children: _jsx(UniqueFieldSuffixContextProvider, { parentId: form._id ?? '', children: _jsx(FieldsWithForm, { form: form, values: formValues, onChange: handleForm, errors: formErrors, onValidate: handleFormValidate, fields: props.fieldMap, submitForm: submitForm, rowGapClassname: props.rowGapClassname, columnGapClassname: props.columnGapClassname }) }) }) }));
|
|
523
|
+
return (_jsx("div", { ref: ref, children: _jsx(FormProvider, { currency: 'USD', locale: currentLanguage, regionalFormat: currentLocale, addressTemplates: addressTemplates, children: _jsx(UniqueFieldSuffixContextProvider, { parentId: form._id ?? '', children: _jsx(FieldsWithForm, { form: form, values: formValues, onChange: handleForm, errors: formErrors, onValidate: handleFormValidate, fields: props.fieldMap, submitForm: submitForm, rowGapClassname: props.rowGapClassname, columnGapClassname: props.columnGapClassname, formRef: formRef }) }) }) }));
|
|
502
524
|
} }));
|
|
503
525
|
});
|
|
504
|
-
const FieldsWithForm = ({ form, submitForm, values, onChange, errors, onValidate, fields: fieldMap, rowGapClassname, columnGapClassname, }) => {
|
|
526
|
+
const FieldsWithForm = ({ form, submitForm, values, onChange, errors, onValidate, fields: fieldMap, rowGapClassname, columnGapClassname, formRef, }) => {
|
|
505
527
|
const coreUploadFile = async ({ file, formId, }) => {
|
|
506
528
|
const uploadUrl = await getUploadUrl(formId, file);
|
|
507
529
|
if (uploadUrl === undefined) {
|
|
@@ -524,6 +546,7 @@ const FieldsWithForm = ({ form, submitForm, values, onChange, errors, onValidate
|
|
|
524
546
|
submitForm,
|
|
525
547
|
uploadFile: coreUploadFile,
|
|
526
548
|
fieldMap,
|
|
549
|
+
forwardedRef: formRef,
|
|
527
550
|
});
|
|
528
551
|
if (!formData)
|
|
529
552
|
return null;
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
import { forms } from '@wix/forms';
|
|
2
3
|
import { FormServiceConfig } from '../../services/form-service.js';
|
|
3
4
|
import { FormValues } from '../types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Hook to access the form ref from context
|
|
7
|
+
*/
|
|
8
|
+
export declare function useFormRef(): React.Ref<any> | undefined;
|
|
4
9
|
/**
|
|
5
10
|
* Props for Root headless component
|
|
6
11
|
*/
|
|
7
12
|
export interface RootProps {
|
|
8
13
|
children: React.ReactNode;
|
|
9
14
|
formServiceConfig: FormServiceConfig;
|
|
15
|
+
/** Optional ref to access form methods imperatively */
|
|
16
|
+
formRef?: React.Ref<any>;
|
|
10
17
|
}
|
|
11
18
|
/**
|
|
12
19
|
* Root component that provides the Form service context to its children.
|
|
@@ -16,7 +23,9 @@ export interface RootProps {
|
|
|
16
23
|
* @component
|
|
17
24
|
* @param {RootProps} props - Component props
|
|
18
25
|
* @param {React.ReactNode} props.children - Child components that will have access to form context
|
|
19
|
-
* @param {FormServiceConfig} props.formServiceConfig - Configuration object containing form data
|
|
26
|
+
* @param {FormServiceConfig} props.formServiceConfig - Configuration object containing form data. Supports two patterns:
|
|
27
|
+
* - Pre-loaded form data: `{ form: Form, onSubmit?: Function, addressTemplates?: any[] }`
|
|
28
|
+
* - Lazy loading: `{ formId: string, namespace?: string, additionalMetadata?: Record<string, string | string[]>, onSubmit?: Function }`
|
|
20
29
|
* @example
|
|
21
30
|
* ```tsx
|
|
22
31
|
* import { Form } from '@wix/headless-forms/react';
|
|
@@ -51,9 +60,30 @@ export interface RootProps {
|
|
|
51
60
|
* </Form.Root>
|
|
52
61
|
* );
|
|
53
62
|
* }
|
|
63
|
+
*
|
|
64
|
+
* // Pattern 3: With namespace and additional metadata (for bookings, etc.)
|
|
65
|
+
* function BookingFormPage({ formId }) {
|
|
66
|
+
* return (
|
|
67
|
+
* <Form.Root
|
|
68
|
+
* formServiceConfig={{
|
|
69
|
+
* formId,
|
|
70
|
+
* namespace: 'wix.bookings.form',
|
|
71
|
+
* additionalMetadata: { serviceId: ['service-123'] },
|
|
72
|
+
* }}
|
|
73
|
+
* >
|
|
74
|
+
* <Form.Loading>
|
|
75
|
+
* {({ isLoading }) => isLoading ? <div>Loading form...</div> : null}
|
|
76
|
+
* </Form.Loading>
|
|
77
|
+
* <Form.LoadingError>
|
|
78
|
+
* {({ error, hasError }) => hasError ? <div>{error}</div> : null}
|
|
79
|
+
* </Form.LoadingError>
|
|
80
|
+
* <Form.Fields fieldMap={FIELD_MAP} />
|
|
81
|
+
* </Form.Root>
|
|
82
|
+
* );
|
|
83
|
+
* }
|
|
54
84
|
* ```
|
|
55
85
|
*/
|
|
56
|
-
export declare function Root({ formServiceConfig, children, }: RootProps): React.ReactNode;
|
|
86
|
+
export declare function Root({ formServiceConfig, formRef, children, }: RootProps): React.ReactNode;
|
|
57
87
|
/**
|
|
58
88
|
* Props for FormLoading headless component
|
|
59
89
|
*/
|
|
@@ -91,7 +121,7 @@ export interface FormLoadingRenderProps {
|
|
|
91
121
|
* }
|
|
92
122
|
* ```
|
|
93
123
|
*/
|
|
94
|
-
export declare function Loading(props: FormLoadingProps):
|
|
124
|
+
export declare function Loading(props: FormLoadingProps): React.ReactNode;
|
|
95
125
|
/**
|
|
96
126
|
* Props for FormError headless component
|
|
97
127
|
*/
|
|
@@ -133,7 +163,7 @@ export interface FormErrorRenderProps {
|
|
|
133
163
|
* }
|
|
134
164
|
* ```
|
|
135
165
|
*/
|
|
136
|
-
export declare function LoadingError(props: FormErrorProps):
|
|
166
|
+
export declare function LoadingError(props: FormErrorProps): React.ReactNode;
|
|
137
167
|
/**
|
|
138
168
|
* Props for Form Submit Error headless component
|
|
139
169
|
*/
|
|
@@ -175,7 +205,7 @@ export interface FormSubmitErrorRenderProps {
|
|
|
175
205
|
* }
|
|
176
206
|
* ```
|
|
177
207
|
*/
|
|
178
|
-
export declare function Error(props: FormSubmitErrorProps):
|
|
208
|
+
export declare function Error(props: FormSubmitErrorProps): React.ReactNode;
|
|
179
209
|
/**
|
|
180
210
|
* Props for Form Submitted headless component
|
|
181
211
|
*/
|
|
@@ -218,7 +248,7 @@ export interface FormSubmittedRenderProps {
|
|
|
218
248
|
* }
|
|
219
249
|
* ```
|
|
220
250
|
*/
|
|
221
|
-
export declare function Submitted(props: FormSubmittedProps):
|
|
251
|
+
export declare function Submitted(props: FormSubmittedProps): React.ReactNode;
|
|
222
252
|
/**
|
|
223
253
|
* Render props for Fields component
|
|
224
254
|
*/
|
|
@@ -269,7 +299,7 @@ export interface FieldsProps {
|
|
|
269
299
|
* }
|
|
270
300
|
* ```
|
|
271
301
|
*/
|
|
272
|
-
export declare function Fields(props: FieldsProps):
|
|
302
|
+
export declare function Fields(props: FieldsProps): React.ReactNode;
|
|
273
303
|
/**
|
|
274
304
|
* Form view interface containing field definitions
|
|
275
305
|
*/
|
|
@@ -342,4 +372,4 @@ export interface FieldProps {
|
|
|
342
372
|
* }
|
|
343
373
|
* ```
|
|
344
374
|
*/
|
|
345
|
-
export declare function Field(props: FieldProps):
|
|
375
|
+
export declare function Field(props: FieldProps): React.ReactNode;
|
package/dist/react/core/Form.js
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
2
3
|
import { useService, WixServices } from '@wix/services-manager-react';
|
|
3
4
|
import { createServicesMap } from '@wix/services-manager';
|
|
4
5
|
import { FormServiceDefinition, FormService, } from '../../services/form-service.js';
|
|
5
6
|
import { calculateGridStyles } from '../utils.js';
|
|
6
7
|
const DEFAULT_SUCCESS_MESSAGE = 'Your form has been submitted successfully.';
|
|
8
|
+
/**
|
|
9
|
+
* Context for passing form ref from Root to Fields
|
|
10
|
+
*/
|
|
11
|
+
const FormRefContext = React.createContext(undefined);
|
|
12
|
+
/**
|
|
13
|
+
* Hook to access the form ref from context
|
|
14
|
+
*/
|
|
15
|
+
export function useFormRef() {
|
|
16
|
+
return React.useContext(FormRefContext);
|
|
17
|
+
}
|
|
7
18
|
/**
|
|
8
19
|
* Root component that provides the Form service context to its children.
|
|
9
20
|
* This component sets up the necessary services for rendering and managing form data.
|
|
@@ -12,7 +23,9 @@ const DEFAULT_SUCCESS_MESSAGE = 'Your form has been submitted successfully.';
|
|
|
12
23
|
* @component
|
|
13
24
|
* @param {RootProps} props - Component props
|
|
14
25
|
* @param {React.ReactNode} props.children - Child components that will have access to form context
|
|
15
|
-
* @param {FormServiceConfig} props.formServiceConfig - Configuration object containing form data
|
|
26
|
+
* @param {FormServiceConfig} props.formServiceConfig - Configuration object containing form data. Supports two patterns:
|
|
27
|
+
* - Pre-loaded form data: `{ form: Form, onSubmit?: Function, addressTemplates?: any[] }`
|
|
28
|
+
* - Lazy loading: `{ formId: string, namespace?: string, additionalMetadata?: Record<string, string | string[]>, onSubmit?: Function }`
|
|
16
29
|
* @example
|
|
17
30
|
* ```tsx
|
|
18
31
|
* import { Form } from '@wix/headless-forms/react';
|
|
@@ -47,10 +60,31 @@ const DEFAULT_SUCCESS_MESSAGE = 'Your form has been submitted successfully.';
|
|
|
47
60
|
* </Form.Root>
|
|
48
61
|
* );
|
|
49
62
|
* }
|
|
63
|
+
*
|
|
64
|
+
* // Pattern 3: With namespace and additional metadata (for bookings, etc.)
|
|
65
|
+
* function BookingFormPage({ formId }) {
|
|
66
|
+
* return (
|
|
67
|
+
* <Form.Root
|
|
68
|
+
* formServiceConfig={{
|
|
69
|
+
* formId,
|
|
70
|
+
* namespace: 'wix.bookings.form',
|
|
71
|
+
* additionalMetadata: { serviceId: ['service-123'] },
|
|
72
|
+
* }}
|
|
73
|
+
* >
|
|
74
|
+
* <Form.Loading>
|
|
75
|
+
* {({ isLoading }) => isLoading ? <div>Loading form...</div> : null}
|
|
76
|
+
* </Form.Loading>
|
|
77
|
+
* <Form.LoadingError>
|
|
78
|
+
* {({ error, hasError }) => hasError ? <div>{error}</div> : null}
|
|
79
|
+
* </Form.LoadingError>
|
|
80
|
+
* <Form.Fields fieldMap={FIELD_MAP} />
|
|
81
|
+
* </Form.Root>
|
|
82
|
+
* );
|
|
83
|
+
* }
|
|
50
84
|
* ```
|
|
51
85
|
*/
|
|
52
|
-
export function Root({ formServiceConfig, children, }) {
|
|
53
|
-
return (_jsx(WixServices, { servicesMap: createServicesMap().addService(FormServiceDefinition, FormService, formServiceConfig), children: children }));
|
|
86
|
+
export function Root({ formServiceConfig, formRef, children, }) {
|
|
87
|
+
return (_jsx(WixServices, { servicesMap: createServicesMap().addService(FormServiceDefinition, FormService, formServiceConfig), children: _jsx(FormRefContext.Provider, { value: formRef, children: children }) }));
|
|
54
88
|
}
|
|
55
89
|
/**
|
|
56
90
|
* Headless component for form loading state access
|
package/dist/react/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
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 '@wix/form-public';
|
|
2
|
-
export type { CheckboxGroupProps, CheckboxProps, PhoneInputProps, DateInputProps, DatePickerProps, DateTimeInputProps, DropdownProps, FileUploadProps, MultilineAddressProps, NumberInputProps, RadioGroupProps, RatingInputProps, RichTextProps, SignatureProps, SubmitButtonProps, TagsProps, TextAreaProps, TextInputProps, TimeInputProps, ProductListProps, FixedPaymentProps, PaymentInputProps, DonationProps, AppointmentProps, ImageChoiceProps, };
|
|
1
|
+
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, type UseFormProps, type LoginBarProps } from '@wix/form-public';
|
|
2
|
+
export type { CheckboxGroupProps, CheckboxProps, PhoneInputProps, DateInputProps, DatePickerProps, DateTimeInputProps, DropdownProps, FileUploadProps, MultilineAddressProps, NumberInputProps, RadioGroupProps, RatingInputProps, RichTextProps, SignatureProps, SubmitButtonProps, TagsProps, TextAreaProps, TextInputProps, TimeInputProps, ProductListProps, FixedPaymentProps, PaymentInputProps, DonationProps, AppointmentProps, ImageChoiceProps, UseFormProps, LoginBarProps, };
|
|
3
3
|
export type FormValues = Record<string, any>;
|
|
4
4
|
export interface UploadFileParams {
|
|
5
5
|
file: File;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { submissions } from '@wix/forms';
|
|
1
|
+
import { forms, submissions } from '@wix/forms';
|
|
2
2
|
import { defineService, implementService } from '@wix/services-definitions';
|
|
3
3
|
import { SignalsServiceDefinition, } from '@wix/services-definitions/core-services/signals';
|
|
4
|
-
import { httpClient } from '@wix/essentials';
|
|
5
4
|
import { fetchAddressForms, hasMultilineAddressField, } from './utils/address-forms.js';
|
|
5
|
+
import { Fieldset } from '@wix/auto_sdk_forms_forms';
|
|
6
6
|
/**
|
|
7
7
|
* Service definition for the Form service.
|
|
8
8
|
* This defines the contract that the FormService must implement.
|
|
@@ -147,41 +147,18 @@ export const FormService = implementService.withConfig()(FormServiceDefinition,
|
|
|
147
147
|
handleForm,
|
|
148
148
|
};
|
|
149
149
|
});
|
|
150
|
-
function
|
|
151
|
-
const params = new URLSearchParams();
|
|
152
|
-
params.append('formId', id);
|
|
153
|
-
if (namespace) {
|
|
154
|
-
params.append('namespace', namespace);
|
|
155
|
-
}
|
|
156
|
-
if (additionalMetadata) {
|
|
157
|
-
Object.entries(additionalMetadata).forEach(([key, value]) => {
|
|
158
|
-
if (Array.isArray(value)) {
|
|
159
|
-
value.forEach((v) => params.append(key, v));
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
params.append(key, value);
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
return params;
|
|
167
|
-
}
|
|
168
|
-
async function fetchForm({ id, namespace, additionalMetadata, }) {
|
|
150
|
+
async function fetchForm({ id, namespace = 'wix.form_app.form', additionalMetadata, }) {
|
|
169
151
|
try {
|
|
170
|
-
const
|
|
171
|
-
id,
|
|
172
|
-
namespace,
|
|
152
|
+
const response = await forms.listForms(namespace, {
|
|
173
153
|
additionalMetadata,
|
|
154
|
+
formIds: [id],
|
|
155
|
+
fieldsets: [Fieldset.NESTED_FORMS],
|
|
174
156
|
});
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
throw new Error(`Failed to fetch form: ${response.status} ${response.statusText}`);
|
|
179
|
-
}
|
|
180
|
-
const data = await response.json();
|
|
181
|
-
if (data && data.form) {
|
|
182
|
-
return data.form;
|
|
157
|
+
const form = response.forms?.[0];
|
|
158
|
+
if (!form) {
|
|
159
|
+
throw new Error('Form not found');
|
|
183
160
|
}
|
|
184
|
-
|
|
161
|
+
return form;
|
|
185
162
|
}
|
|
186
163
|
catch (err) {
|
|
187
164
|
console.error('Failed to load form:', id, err);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/headless-forms",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.23",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"vitest": "^3.1.4"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@wix/form-public": "^0.
|
|
45
|
+
"@wix/form-public": "^0.104.0",
|
|
46
46
|
"@wix/forms": "^1.0.373",
|
|
47
47
|
"@wix/headless-utils": "0.0.8",
|
|
48
48
|
"@wix/services-definitions": "^0.1.4",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"groupId": "com.wixpress.headless-components"
|
|
60
60
|
}
|
|
61
61
|
},
|
|
62
|
-
"falconPackageHash": "
|
|
62
|
+
"falconPackageHash": "6d90b5a274c89f69fb6007bfac926468be779780b40000231b716ec3"
|
|
63
63
|
}
|