@wix/headless-forms 0.0.1 → 0.0.3
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/README.md +46 -0
- package/cjs/dist/react/Form.d.ts +4 -68
- package/cjs/dist/react/Form.js +36 -179
- package/cjs/dist/react/core/Form.d.ts +49 -3
- package/cjs/dist/react/core/Form.js +51 -19
- package/cjs/dist/react/types.d.ts +1 -1
- package/cjs/dist/services/form-service.d.ts +51 -150
- package/cjs/dist/services/form-service.js +65 -110
- package/dist/react/Form.d.ts +4 -68
- package/dist/react/Form.js +36 -176
- package/dist/react/core/Form.d.ts +49 -3
- package/dist/react/core/Form.js +50 -19
- package/dist/react/types.d.ts +1 -1
- package/dist/services/form-service.d.ts +51 -150
- package/dist/services/form-service.js +65 -110
- package/package.json +2 -1
package/dist/react/Form.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
2
|
-
import React from 'react';
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React, { useState, useCallback } from 'react';
|
|
3
3
|
import { AsChildSlot } from '@wix/headless-utils/react';
|
|
4
|
-
import
|
|
4
|
+
import { Form as FormViewer, } from '@wix/form-public';
|
|
5
|
+
import { Root as CoreRoot, Loading as CoreLoading, LoadingError as CoreLoadingError, Error as CoreError, Submitted as CoreSubmitted, Fields as CoreFields, } from './core/Form';
|
|
5
6
|
var TestIds;
|
|
6
7
|
(function (TestIds) {
|
|
7
8
|
TestIds["formRoot"] = "form-root";
|
|
9
|
+
TestIds["form"] = "form";
|
|
10
|
+
TestIds["formLoading"] = "form-loading";
|
|
8
11
|
TestIds["formLoadingError"] = "form-loading-error";
|
|
9
12
|
TestIds["formError"] = "form-error";
|
|
10
13
|
TestIds["formSubmitted"] = "form-submitted";
|
|
@@ -18,6 +21,7 @@ var TestIds;
|
|
|
18
21
|
* @param {RootProps} props - The component props
|
|
19
22
|
* @param {React.ReactNode} props.children - Child components that will have access to form context
|
|
20
23
|
* @param {FormServiceConfig} props.formServiceConfig - Form service configuration object
|
|
24
|
+
* @param {boolean} [props.asChild] - Whether to render as a child component
|
|
21
25
|
* @param {string} [props.className] - CSS classes to apply to the root element
|
|
22
26
|
* @example
|
|
23
27
|
* ```tsx
|
|
@@ -60,7 +64,7 @@ var TestIds;
|
|
|
60
64
|
*/
|
|
61
65
|
export const Root = React.forwardRef((props, ref) => {
|
|
62
66
|
const { children, formServiceConfig, asChild, ...otherProps } = props;
|
|
63
|
-
return (_jsx(
|
|
67
|
+
return (_jsx(CoreRoot, { formServiceConfig: formServiceConfig, children: _jsx(RootContent, { asChild: asChild, ref: ref, ...otherProps, children: children }) }));
|
|
64
68
|
});
|
|
65
69
|
/**
|
|
66
70
|
* Internal component to handle the Root content with service access.
|
|
@@ -75,7 +79,7 @@ export const Root = React.forwardRef((props, ref) => {
|
|
|
75
79
|
*/
|
|
76
80
|
const RootContent = React.forwardRef((props, ref) => {
|
|
77
81
|
const { asChild, children, className, ...otherProps } = props;
|
|
78
|
-
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.formRoot, customElement: children, customElementProps: {}, ...otherProps, children: _jsx("div", { children:
|
|
82
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.formRoot, customElement: children, customElementProps: {}, ...otherProps, children: _jsx("div", { children: children }) }));
|
|
79
83
|
});
|
|
80
84
|
/**
|
|
81
85
|
* Component that renders content during loading state.
|
|
@@ -124,10 +128,10 @@ const RootContent = React.forwardRef((props, ref) => {
|
|
|
124
128
|
*/
|
|
125
129
|
export const Loading = React.forwardRef((props, ref) => {
|
|
126
130
|
const { asChild, children, className, ...otherProps } = props;
|
|
127
|
-
return (_jsx(
|
|
131
|
+
return (_jsx(CoreLoading, { children: ({ isLoading }) => {
|
|
128
132
|
if (!isLoading)
|
|
129
133
|
return null;
|
|
130
|
-
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className,
|
|
134
|
+
return (_jsx(AsChildSlot, { "data-testid": TestIds.formLoading, ref: ref, asChild: asChild, className: className, customElement: children, content: "Loading form...", ...otherProps, children: _jsx("div", { children: "Loading form..." }) }));
|
|
131
135
|
} }));
|
|
132
136
|
});
|
|
133
137
|
/**
|
|
@@ -181,7 +185,7 @@ export const Loading = React.forwardRef((props, ref) => {
|
|
|
181
185
|
*/
|
|
182
186
|
export const LoadingError = React.forwardRef((props, ref) => {
|
|
183
187
|
const { asChild, children, className, ...otherProps } = props;
|
|
184
|
-
return (_jsx(
|
|
188
|
+
return (_jsx(CoreLoadingError, { children: ({ error, hasError }) => {
|
|
185
189
|
if (!hasError)
|
|
186
190
|
return null;
|
|
187
191
|
const errorData = { error, hasError };
|
|
@@ -237,7 +241,7 @@ export const LoadingError = React.forwardRef((props, ref) => {
|
|
|
237
241
|
*/
|
|
238
242
|
export const Error = React.forwardRef((props, ref) => {
|
|
239
243
|
const { asChild, children, className, ...otherProps } = props;
|
|
240
|
-
return (_jsx(
|
|
244
|
+
return (_jsx(CoreError, { children: ({ error, hasError }) => {
|
|
241
245
|
if (!hasError)
|
|
242
246
|
return null;
|
|
243
247
|
const errorData = { error, hasError };
|
|
@@ -293,7 +297,7 @@ export const Error = React.forwardRef((props, ref) => {
|
|
|
293
297
|
*/
|
|
294
298
|
export const Submitted = React.forwardRef((props, ref) => {
|
|
295
299
|
const { asChild, children, className, ...otherProps } = props;
|
|
296
|
-
return (_jsx(
|
|
300
|
+
return (_jsx(CoreSubmitted, { children: ({ isSubmitted, message }) => {
|
|
297
301
|
if (!isSubmitted)
|
|
298
302
|
return null;
|
|
299
303
|
const submittedData = { isSubmitted, message };
|
|
@@ -444,170 +448,26 @@ export const Submitted = React.forwardRef((props, ref) => {
|
|
|
444
448
|
* };
|
|
445
449
|
* ```
|
|
446
450
|
*/
|
|
447
|
-
export const Fields = React.forwardRef((
|
|
448
|
-
|
|
449
|
-
|
|
451
|
+
export const Fields = React.forwardRef((props, ref) => {
|
|
452
|
+
const [formValues, setFormValues] = useState({});
|
|
453
|
+
const [formErrors, setFormErrors] = useState([]);
|
|
454
|
+
const handleFormChange = useCallback((values) => {
|
|
455
|
+
setFormValues(values);
|
|
456
|
+
}, []);
|
|
457
|
+
const handleFormValidate = useCallback((errors) => {
|
|
458
|
+
setFormErrors(errors);
|
|
459
|
+
}, []);
|
|
460
|
+
return (_jsx(CoreFields, { children: ({ form }) => {
|
|
461
|
+
console.log('Fields form', form);
|
|
462
|
+
if (!form)
|
|
463
|
+
return null;
|
|
464
|
+
return (_jsx("div", { ref: ref, children: _jsx(FormViewer, { form: {
|
|
465
|
+
...form,
|
|
466
|
+
id: form?._id,
|
|
467
|
+
fields: form?.formFields?.map((field) => ({
|
|
468
|
+
...field,
|
|
469
|
+
id: field._id,
|
|
470
|
+
})),
|
|
471
|
+
}, values: formValues, onChange: handleFormChange, errors: formErrors, onValidate: handleFormValidate, fields: props.fieldMap }) }));
|
|
472
|
+
} }));
|
|
450
473
|
});
|
|
451
|
-
const MockViewer = ({ fieldMap }) => {
|
|
452
|
-
// This is how fieldMap is expected to be used in the viewer
|
|
453
|
-
const schemaFields = {
|
|
454
|
-
// CONTACTS_FIELD_TYPES
|
|
455
|
-
CONTACTS_COMPANY: fieldMap.TEXT_INPUT,
|
|
456
|
-
CONTACTS_POSITION: fieldMap.TEXT_INPUT,
|
|
457
|
-
CONTACTS_TAX_ID: fieldMap.TEXT_INPUT,
|
|
458
|
-
CONTACTS_FIRST_NAME: fieldMap.TEXT_INPUT,
|
|
459
|
-
CONTACTS_LAST_NAME: fieldMap.TEXT_INPUT,
|
|
460
|
-
CONTACTS_EMAIL: fieldMap.TEXT_INPUT,
|
|
461
|
-
CONTACTS_BIRTHDATE: fieldMap.DATE_INPUT,
|
|
462
|
-
CONTACTS_PHONE: fieldMap.PHONE_INPUT,
|
|
463
|
-
CONTACTS_ADDRESS: fieldMap.TEXT_INPUT,
|
|
464
|
-
CONTACTS_SUBSCRIBE: fieldMap.CHECKBOX,
|
|
465
|
-
// QUIZ_FIELD_TYPES
|
|
466
|
-
QUIZ_MULTI_CHOICE: fieldMap.CHECKBOX_GROUP,
|
|
467
|
-
QUIZ_SINGLE_CHOICE: fieldMap.RADIO_GROUP,
|
|
468
|
-
QUIZ_SHORT_TEXT: fieldMap.TEXT_INPUT,
|
|
469
|
-
QUIZ_LONG_TEXT: fieldMap.TEXT_AREA,
|
|
470
|
-
QUIZ_NUMBER: fieldMap.NUMBER_INPUT,
|
|
471
|
-
QUIZ_FILE_UPLOAD: fieldMap.FILE_UPLOAD,
|
|
472
|
-
QUIZ_IMAGE_CHOICE: fieldMap.IMAGE_CHOICE, // TODO: add
|
|
473
|
-
// DEXT_FIELD_TYPES
|
|
474
|
-
DEXT_TEXT_INPUT: fieldMap.TEXT_INPUT,
|
|
475
|
-
DEXT_TEXT_AREA: fieldMap.TEXT_AREA,
|
|
476
|
-
DEXT_DROPDOWN: fieldMap.DROPDOWN,
|
|
477
|
-
DEXT_URL_INPUT: fieldMap.TEXT_INPUT,
|
|
478
|
-
DEXT_RADIO_GROUP: fieldMap.RADIO_GROUP,
|
|
479
|
-
DEXT_NUMBER_INPUT: fieldMap.NUMBER_INPUT,
|
|
480
|
-
DEXT_CHECKBOX: fieldMap.CHECKBOX,
|
|
481
|
-
DEXT_CHECKBOX_GROUP: fieldMap.CHECKBOX_GROUP,
|
|
482
|
-
DEXT_EMAIL: fieldMap.TEXT_INPUT,
|
|
483
|
-
DEXT_PHONE: fieldMap.PHONE_INPUT,
|
|
484
|
-
DEXT_RATING_INPUT: fieldMap.RATING_INPUT,
|
|
485
|
-
DEXT_DATE_PICKER: fieldMap.DATE_PICKER,
|
|
486
|
-
DEXT_TAGS: fieldMap.TAGS,
|
|
487
|
-
// SCHEDULING_FIELD_TYPES
|
|
488
|
-
APPOINTMENT: fieldMap.APPOINTMENT,
|
|
489
|
-
SERVICES_DROPDOWN: fieldMap.DROPDOWN,
|
|
490
|
-
// ECOM_FIELD_TYPES
|
|
491
|
-
ECOM_ADDITIONAL_INFO: fieldMap.TEXT_AREA,
|
|
492
|
-
ECOM_ADDRESS: fieldMap.TEXT_INPUT,
|
|
493
|
-
ECOM_FULL_NAME: fieldMap.TEXT_INPUT,
|
|
494
|
-
ECOM_PHONE: fieldMap.PHONE_INPUT,
|
|
495
|
-
ECOM_COMPANY_NAME: fieldMap.TEXT_INPUT,
|
|
496
|
-
ECOM_EMAIL: fieldMap.TEXT_INPUT,
|
|
497
|
-
ECOM_SUBSCRIPTION: fieldMap.CHECKBOX,
|
|
498
|
-
// BOOKINGS_FIELD_TYPES
|
|
499
|
-
BOOKINGS_FIRST_NAME: fieldMap.TEXT_INPUT,
|
|
500
|
-
BOOKINGS_LAST_NAME: fieldMap.TEXT_INPUT,
|
|
501
|
-
BOOKINGS_EMAIL: fieldMap.TEXT_INPUT,
|
|
502
|
-
BOOKINGS_PHONE: fieldMap.PHONE_INPUT,
|
|
503
|
-
BOOKINGS_ADDRESS: fieldMap.TEXT_INPUT,
|
|
504
|
-
// PAYMENTS_FIELD_TYPES
|
|
505
|
-
PRODUCT_LIST: fieldMap.PRODUCT_LIST,
|
|
506
|
-
DONATION: fieldMap.DONATION,
|
|
507
|
-
PAYMENT_INPUT: fieldMap.PAYMENT_INPUT, // could be TEXT_INPUT?
|
|
508
|
-
FIXED_PAYMENT: fieldMap.FIXED_PAYMENT, // could be TAGS?
|
|
509
|
-
// COMMON_FIELD_TYPES
|
|
510
|
-
TEXT_INPUT: fieldMap.TEXT_INPUT,
|
|
511
|
-
NUMBER_INPUT: fieldMap.NUMBER_INPUT,
|
|
512
|
-
URL_INPUT: fieldMap.TEXT_INPUT,
|
|
513
|
-
TEXT_AREA: fieldMap.TEXT_AREA,
|
|
514
|
-
DATE_INPUT: fieldMap.DATE_INPUT,
|
|
515
|
-
DATE_TIME_INPUT: fieldMap.DATE_TIME_INPUT,
|
|
516
|
-
TIME_INPUT: fieldMap.TIME_INPUT,
|
|
517
|
-
RADIO_GROUP: fieldMap.RADIO_GROUP,
|
|
518
|
-
CHECKBOX_GROUP: fieldMap.CHECKBOX_GROUP,
|
|
519
|
-
FILE_UPLOAD: fieldMap.FILE_UPLOAD,
|
|
520
|
-
CHECKBOX: fieldMap.CHECKBOX,
|
|
521
|
-
DROPDOWN: fieldMap.DROPDOWN,
|
|
522
|
-
// NESTED_FORM: 'NESTED_FORM',
|
|
523
|
-
MULTILINE_ADDRESS: fieldMap.MULTILINE_ADDRESS,
|
|
524
|
-
// are these relevant for headless?
|
|
525
|
-
MLA_COUNTRY: fieldMap.DROPDOWN,
|
|
526
|
-
MLA_CITY: fieldMap.TEXT_INPUT,
|
|
527
|
-
MLA_ADDRESS_LINE: fieldMap.TEXT_INPUT, // dropdown if autocomplete disabled?
|
|
528
|
-
MLA_ADDRESS_LINE_2: fieldMap.TEXT_INPUT,
|
|
529
|
-
MLA_POSTAL_CODE: fieldMap.TEXT_INPUT,
|
|
530
|
-
MLA_SUBDIVISION: fieldMap.DROPDOWN,
|
|
531
|
-
MLA_STREET_NAME: fieldMap.TEXT_INPUT,
|
|
532
|
-
MLA_STREET_NUMBER: fieldMap.TEXT_INPUT,
|
|
533
|
-
MLA_APARTMENT: fieldMap.TEXT_INPUT,
|
|
534
|
-
FULL_NAME_FIRST_NAME: fieldMap.TEXT_INPUT,
|
|
535
|
-
FULL_NAME_LAST_NAME: fieldMap.TEXT_INPUT,
|
|
536
|
-
FULL_NAME: fieldMap.TEXT_INPUT,
|
|
537
|
-
VAT_ID: fieldMap.TEXT_INPUT,
|
|
538
|
-
SIGNATURE: fieldMap.SIGNATURE,
|
|
539
|
-
RATING_INPUT: fieldMap.RATING_INPUT,
|
|
540
|
-
TAGS: fieldMap.TAGS,
|
|
541
|
-
DATE_PICKER: fieldMap.DATE_PICKER,
|
|
542
|
-
// READONLY_FIELD_TYPES
|
|
543
|
-
HEADER: fieldMap.TEXT,
|
|
544
|
-
RICH_TEXT: fieldMap.TEXT,
|
|
545
|
-
SUBMIT_BUTTON: fieldMap.SUBMIT_BUTTON,
|
|
546
|
-
};
|
|
547
|
-
return (_jsxs(_Fragment, { children: [_jsx("div", { children: "Form Fields" }), _jsx("div", { children: JSON.stringify(schemaFields) })] }));
|
|
548
|
-
};
|
|
549
|
-
/**
|
|
550
|
-
* Main Form namespace containing all form components following the compound component pattern.
|
|
551
|
-
* Provides a headless, flexible way to render and manage forms with custom field components.
|
|
552
|
-
*
|
|
553
|
-
* @namespace Form
|
|
554
|
-
* @property {typeof Root} Root - Form root component that provides service context to all child components
|
|
555
|
-
* @property {typeof Loading} Loading - Form loading state component that displays content during form loading
|
|
556
|
-
* @property {typeof LoadingError} LoadingError - Form loading error state component for handling form loading errors
|
|
557
|
-
* @property {typeof Error} Error - Form submit error state component for handling form submission errors
|
|
558
|
-
* @property {typeof Submitted} Submitted - Form submitted state component for displaying success messages
|
|
559
|
-
* @property {typeof Fields} Fields - Form fields component for rendering form fields with custom field renderers
|
|
560
|
-
* @example
|
|
561
|
-
* ```tsx
|
|
562
|
-
* import { Form } from '@wix/headless-forms/react';
|
|
563
|
-
* import { loadFormServiceConfig } from '@wix/headless-forms/services';
|
|
564
|
-
* import { TextInput, TextArea, Checkbox } from './field-components';
|
|
565
|
-
*
|
|
566
|
-
* const FIELD_MAP = {
|
|
567
|
-
* TEXT_INPUT: TextInput,
|
|
568
|
-
* TEXT_AREA: TextArea,
|
|
569
|
-
* CHECKBOX: Checkbox,
|
|
570
|
-
* // ... other field components
|
|
571
|
-
* };
|
|
572
|
-
*
|
|
573
|
-
* // Pattern 1: Pre-loaded form data (SSR/SSG)
|
|
574
|
-
* function MyForm({ formServiceConfig }) {
|
|
575
|
-
* return (
|
|
576
|
-
* <Form.Root formServiceConfig={formServiceConfig}>
|
|
577
|
-
* <Form.Loading className="flex justify-center p-4" />
|
|
578
|
-
* <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
|
|
579
|
-
* <Form.Fields fieldMap={FIELD_MAP} />
|
|
580
|
-
* <Form.Error className="text-destructive p-4 rounded-lg mb-4" />
|
|
581
|
-
* <Form.Submitted className="text-green-500 p-4 rounded-lg mb-4" />
|
|
582
|
-
* </Form.Root>
|
|
583
|
-
* );
|
|
584
|
-
* }
|
|
585
|
-
*
|
|
586
|
-
* // Pattern 2: Lazy loading with formId (Client-side)
|
|
587
|
-
* function DynamicForm({ formId }) {
|
|
588
|
-
* return (
|
|
589
|
-
* <Form.Root formServiceConfig={{ formId }}>
|
|
590
|
-
* <Form.Loading className="flex justify-center p-4" />
|
|
591
|
-
* <Form.LoadingError className="text-destructive px-4 py-3 rounded mb-4" />
|
|
592
|
-
* <Form.Fields fieldMap={FIELD_MAP} />
|
|
593
|
-
* <Form.Error className="text-destructive p-4 rounded-lg mb-4" />
|
|
594
|
-
* <Form.Submitted className="text-green-500 p-4 rounded-lg mb-4" />
|
|
595
|
-
* </Form.Root>
|
|
596
|
-
* );
|
|
597
|
-
* }
|
|
598
|
-
* ```
|
|
599
|
-
*/
|
|
600
|
-
export const Form = {
|
|
601
|
-
/** Form root component that provides service context */
|
|
602
|
-
Root,
|
|
603
|
-
/** Form loading state component */
|
|
604
|
-
Loading,
|
|
605
|
-
/** Form loading error state component */
|
|
606
|
-
LoadingError,
|
|
607
|
-
/** Form error state component */
|
|
608
|
-
Error,
|
|
609
|
-
/** Form submitted state component */
|
|
610
|
-
Submitted,
|
|
611
|
-
/** Form fields component for rendering form fields */
|
|
612
|
-
Fields,
|
|
613
|
-
};
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import { forms } from '@wix/forms';
|
|
1
2
|
import { FormServiceConfig } from '../../services/form-service.js';
|
|
3
|
+
/**
|
|
4
|
+
* Props for Root headless component
|
|
5
|
+
*/
|
|
2
6
|
export interface RootProps {
|
|
3
7
|
children: React.ReactNode;
|
|
4
8
|
formServiceConfig: FormServiceConfig;
|
|
@@ -9,8 +13,9 @@ export interface RootProps {
|
|
|
9
13
|
*
|
|
10
14
|
* @order 1
|
|
11
15
|
* @component
|
|
12
|
-
* @param {
|
|
13
|
-
* @param {
|
|
16
|
+
* @param {RootProps} props - Component props
|
|
17
|
+
* @param {React.ReactNode} props.children - Child components that will have access to form context
|
|
18
|
+
* @param {FormServiceConfig} props.formServiceConfig - Configuration object containing form data
|
|
14
19
|
* @example
|
|
15
20
|
* ```tsx
|
|
16
21
|
* import { Form } from '@wix/headless-forms/react';
|
|
@@ -47,7 +52,7 @@ export interface RootProps {
|
|
|
47
52
|
* }
|
|
48
53
|
* ```
|
|
49
54
|
*/
|
|
50
|
-
export declare function Root(
|
|
55
|
+
export declare function Root({ formServiceConfig, children, }: RootProps): React.ReactNode;
|
|
51
56
|
/**
|
|
52
57
|
* Props for FormLoading headless component
|
|
53
58
|
*/
|
|
@@ -213,3 +218,44 @@ export interface FormSubmittedRenderProps {
|
|
|
213
218
|
* ```
|
|
214
219
|
*/
|
|
215
220
|
export declare function Submitted(props: FormSubmittedProps): import("react").ReactNode;
|
|
221
|
+
/**
|
|
222
|
+
* Render props for Fields component
|
|
223
|
+
*/
|
|
224
|
+
interface FieldsRenderProps {
|
|
225
|
+
form: forms.Form | null;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Props for Fields headless component
|
|
229
|
+
*/
|
|
230
|
+
interface FieldsProps {
|
|
231
|
+
children: (props: FieldsRenderProps) => React.ReactNode;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Fields component that provides form data to its children.
|
|
235
|
+
* This component accesses the form data from the service and passes it to children via render props.
|
|
236
|
+
*
|
|
237
|
+
* @component
|
|
238
|
+
* @param {FieldsProps} props - Component props
|
|
239
|
+
* @param {FieldsProps['children']} props.children - Render prop function that receives form data
|
|
240
|
+
* @example
|
|
241
|
+
* ```tsx
|
|
242
|
+
* import { Form } from '@wix/headless-forms/react';
|
|
243
|
+
*
|
|
244
|
+
* function FormFields() {
|
|
245
|
+
* return (
|
|
246
|
+
* <Form.Fields>
|
|
247
|
+
* {({ form }) => (
|
|
248
|
+
* form ? (
|
|
249
|
+
* <div>
|
|
250
|
+
* <h2>{form.name}</h2>
|
|
251
|
+
* <p>{form.description}</p>
|
|
252
|
+
* </div>
|
|
253
|
+
* ) : null
|
|
254
|
+
* )}
|
|
255
|
+
* </Form.Fields>
|
|
256
|
+
* );
|
|
257
|
+
* }
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
export declare function Fields(props: FieldsProps): import("react").ReactNode;
|
|
261
|
+
export {};
|
package/dist/react/core/Form.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useService, WixServices } from '@wix/services-manager-react';
|
|
3
|
-
import { FormServiceDefinition, FormService, } from '../../services/form-service.js';
|
|
4
3
|
import { createServicesMap } from '@wix/services-manager';
|
|
4
|
+
import { FormServiceDefinition, FormService, } from '../../services/form-service.js';
|
|
5
5
|
const DEFAULT_SUCCESS_MESSAGE = 'Your form has been submitted successfully.';
|
|
6
6
|
/**
|
|
7
7
|
* Root component that provides the Form service context to its children.
|
|
@@ -9,8 +9,9 @@ const DEFAULT_SUCCESS_MESSAGE = 'Your form has been submitted successfully.';
|
|
|
9
9
|
*
|
|
10
10
|
* @order 1
|
|
11
11
|
* @component
|
|
12
|
-
* @param {
|
|
13
|
-
* @param {
|
|
12
|
+
* @param {RootProps} props - Component props
|
|
13
|
+
* @param {React.ReactNode} props.children - Child components that will have access to form context
|
|
14
|
+
* @param {FormServiceConfig} props.formServiceConfig - Configuration object containing form data
|
|
14
15
|
* @example
|
|
15
16
|
* ```tsx
|
|
16
17
|
* import { Form } from '@wix/headless-forms/react';
|
|
@@ -47,8 +48,8 @@ const DEFAULT_SUCCESS_MESSAGE = 'Your form has been submitted successfully.';
|
|
|
47
48
|
* }
|
|
48
49
|
* ```
|
|
49
50
|
*/
|
|
50
|
-
export function Root(
|
|
51
|
-
return (_jsx(WixServices, { servicesMap: createServicesMap().addService(FormServiceDefinition, FormService,
|
|
51
|
+
export function Root({ formServiceConfig, children, }) {
|
|
52
|
+
return (_jsx(WixServices, { servicesMap: createServicesMap().addService(FormServiceDefinition, FormService, formServiceConfig), children: children }));
|
|
52
53
|
}
|
|
53
54
|
/**
|
|
54
55
|
* Headless component for form loading state access
|
|
@@ -74,8 +75,8 @@ export function Root(props) {
|
|
|
74
75
|
* ```
|
|
75
76
|
*/
|
|
76
77
|
export function Loading(props) {
|
|
77
|
-
const
|
|
78
|
-
const isLoading =
|
|
78
|
+
const { isLoadingSignal } = useService(FormServiceDefinition);
|
|
79
|
+
const isLoading = isLoadingSignal.get();
|
|
79
80
|
return props.children({
|
|
80
81
|
isLoading,
|
|
81
82
|
});
|
|
@@ -106,8 +107,8 @@ export function Loading(props) {
|
|
|
106
107
|
* ```
|
|
107
108
|
*/
|
|
108
109
|
export function LoadingError(props) {
|
|
109
|
-
const
|
|
110
|
-
const error =
|
|
110
|
+
const { errorSignal } = useService(FormServiceDefinition);
|
|
111
|
+
const error = errorSignal.get();
|
|
111
112
|
const hasError = !!error;
|
|
112
113
|
return props.children({
|
|
113
114
|
error,
|
|
@@ -140,10 +141,9 @@ export function LoadingError(props) {
|
|
|
140
141
|
* ```
|
|
141
142
|
*/
|
|
142
143
|
export function Error(props) {
|
|
143
|
-
|
|
144
|
-
const
|
|
145
|
-
const
|
|
146
|
-
const hasError = submitResponse.type === 'error';
|
|
144
|
+
// TODO: Implement submit response handling when submitResponseSignal is added to service
|
|
145
|
+
const error = null;
|
|
146
|
+
const hasError = false;
|
|
147
147
|
return props.children({
|
|
148
148
|
error,
|
|
149
149
|
hasError,
|
|
@@ -176,14 +176,45 @@ export function Error(props) {
|
|
|
176
176
|
* ```
|
|
177
177
|
*/
|
|
178
178
|
export function Submitted(props) {
|
|
179
|
-
|
|
180
|
-
const
|
|
181
|
-
const
|
|
182
|
-
const message = submitResponse.type === 'success'
|
|
183
|
-
? submitResponse.message || DEFAULT_SUCCESS_MESSAGE
|
|
184
|
-
: DEFAULT_SUCCESS_MESSAGE;
|
|
179
|
+
// TODO: Implement submit response handling when submitResponseSignal is added to service
|
|
180
|
+
const isSubmitted = false;
|
|
181
|
+
const message = DEFAULT_SUCCESS_MESSAGE;
|
|
185
182
|
return props.children({
|
|
186
183
|
isSubmitted,
|
|
187
184
|
message,
|
|
188
185
|
});
|
|
189
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* Fields component that provides form data to its children.
|
|
189
|
+
* This component accesses the form data from the service and passes it to children via render props.
|
|
190
|
+
*
|
|
191
|
+
* @component
|
|
192
|
+
* @param {FieldsProps} props - Component props
|
|
193
|
+
* @param {FieldsProps['children']} props.children - Render prop function that receives form data
|
|
194
|
+
* @example
|
|
195
|
+
* ```tsx
|
|
196
|
+
* import { Form } from '@wix/headless-forms/react';
|
|
197
|
+
*
|
|
198
|
+
* function FormFields() {
|
|
199
|
+
* return (
|
|
200
|
+
* <Form.Fields>
|
|
201
|
+
* {({ form }) => (
|
|
202
|
+
* form ? (
|
|
203
|
+
* <div>
|
|
204
|
+
* <h2>{form.name}</h2>
|
|
205
|
+
* <p>{form.description}</p>
|
|
206
|
+
* </div>
|
|
207
|
+
* ) : null
|
|
208
|
+
* )}
|
|
209
|
+
* </Form.Fields>
|
|
210
|
+
* );
|
|
211
|
+
* }
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
export function Fields(props) {
|
|
215
|
+
const { formSignal } = useService(FormServiceDefinition);
|
|
216
|
+
const form = formSignal.get();
|
|
217
|
+
return props.children({
|
|
218
|
+
form,
|
|
219
|
+
});
|
|
220
|
+
}
|
package/dist/react/types.d.ts
CHANGED
|
@@ -786,7 +786,7 @@ export interface DateInputProps extends BaseFieldProps {
|
|
|
786
786
|
label: string;
|
|
787
787
|
showLabel: boolean;
|
|
788
788
|
showPlaceholder: boolean;
|
|
789
|
-
|
|
789
|
+
showDateLabels: boolean;
|
|
790
790
|
acceptedDates: 'all' | 'past' | 'future';
|
|
791
791
|
description?: forms.RichContent;
|
|
792
792
|
}
|