@wix/headless-forms 0.0.2 → 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 +3 -67
- package/cjs/dist/react/Form.js +25 -86
- package/cjs/dist/react/core/Form.d.ts +49 -3
- package/cjs/dist/react/core/Form.js +51 -19
- 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 +3 -67
- package/dist/react/Form.js +25 -86
- package/dist/react/core/Form.d.ts +49 -3
- package/dist/react/core/Form.js +50 -19
- package/dist/services/form-service.d.ts +51 -150
- package/dist/services/form-service.js +65 -110
- package/package.json +1 -1
|
@@ -1,137 +1,92 @@
|
|
|
1
1
|
import { forms } from '@wix/forms';
|
|
2
2
|
import { defineService, implementService } from '@wix/services-definitions';
|
|
3
3
|
import { SignalsServiceDefinition, } from '@wix/services-definitions/core-services/signals';
|
|
4
|
-
export const FormServiceDefinition = defineService('formService');
|
|
5
4
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* This service provides reactive state management for form data, loading states, errors, and submission responses.
|
|
9
|
-
* It automatically handles form loading when only a formId is provided, making it suitable for both SSR and client-side scenarios.
|
|
10
|
-
*
|
|
11
|
-
* ## Service Behavior
|
|
12
|
-
*
|
|
13
|
-
* **Configuration Resolution:**
|
|
14
|
-
* - If `form` is provided: Uses pre-loaded form data immediately (SSR/SSG pattern)
|
|
15
|
-
* - If only `formId` is provided: Loads form data asynchronously from Wix Forms API
|
|
16
|
-
* - If both are provided: Uses pre-loaded `form` data and ignores `formId`
|
|
17
|
-
* - If neither is provided: Throws an error during service initialization
|
|
5
|
+
* Service definition for the Form service.
|
|
6
|
+
* This defines the contract that the FormService must implement.
|
|
18
7
|
*
|
|
19
|
-
*
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* - Network errors during form loading are caught and stored in the `error` signal
|
|
27
|
-
* - "Form not found" errors are handled when the formId doesn't exist
|
|
28
|
-
* - All errors are logged to console for debugging
|
|
8
|
+
* @constant
|
|
9
|
+
*/
|
|
10
|
+
export const FormServiceDefinition = defineService('formService');
|
|
11
|
+
/**
|
|
12
|
+
* Implementation of the Form service that manages reactive form data.
|
|
13
|
+
* This service provides signals for form data, loading state, and error handling.
|
|
14
|
+
* It supports both pre-loaded form data and lazy loading with form IDs.
|
|
29
15
|
*
|
|
30
16
|
* @example
|
|
31
17
|
* ```tsx
|
|
32
|
-
* //
|
|
33
|
-
* const
|
|
18
|
+
* // Pre-loaded form data (SSR/SSG)
|
|
19
|
+
* const formService = FormService.withConfig({ form: formData });
|
|
34
20
|
*
|
|
35
|
-
* //
|
|
36
|
-
* const
|
|
37
|
-
*
|
|
38
|
-
* // Access form data (null during loading)
|
|
39
|
-
* const form = service.form.get();
|
|
40
|
-
*
|
|
41
|
-
* // Check for errors
|
|
42
|
-
* const error = service.error.get();
|
|
21
|
+
* // Lazy loading with form ID (client-side)
|
|
22
|
+
* const formService = FormService.withConfig({ formId: 'form-123' });
|
|
43
23
|
* ```
|
|
44
|
-
*
|
|
45
24
|
*/
|
|
46
25
|
export const FormService = implementService.withConfig()(FormServiceDefinition, ({ getService, config }) => {
|
|
47
26
|
const signalsService = getService(SignalsServiceDefinition);
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
27
|
+
const isLoadingSignal = signalsService.signal(false);
|
|
28
|
+
const errorSignal = signalsService.signal(null);
|
|
29
|
+
const hasSchema = 'form' in config;
|
|
30
|
+
const formSignal = signalsService.signal(hasSchema ? config.form : null);
|
|
31
|
+
if (!hasSchema) {
|
|
32
|
+
isLoadingSignal.set(true);
|
|
33
|
+
loadForm(config.formId);
|
|
52
34
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// Load form asynchronously
|
|
60
|
-
forms
|
|
61
|
-
.getForm(formId)
|
|
62
|
-
.then((loadedForm) => {
|
|
63
|
-
if (loadedForm) {
|
|
64
|
-
form.set(loadedForm);
|
|
65
|
-
isLoading.set(false);
|
|
35
|
+
async function loadForm(id) {
|
|
36
|
+
try {
|
|
37
|
+
const result = await fetchForm(id);
|
|
38
|
+
if (result) {
|
|
39
|
+
formSignal.set(result);
|
|
40
|
+
console.log('result', !!result);
|
|
66
41
|
}
|
|
67
42
|
else {
|
|
68
|
-
|
|
69
|
-
isLoading.set(false);
|
|
43
|
+
errorSignal.set('Form not found');
|
|
70
44
|
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
errorSignal.set('Failed to load form');
|
|
48
|
+
throw err;
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
isLoadingSignal.set(false);
|
|
52
|
+
}
|
|
77
53
|
}
|
|
78
|
-
return {
|
|
54
|
+
return {
|
|
55
|
+
formSignal: formSignal,
|
|
56
|
+
isLoadingSignal: isLoadingSignal,
|
|
57
|
+
errorSignal: errorSignal,
|
|
58
|
+
};
|
|
79
59
|
});
|
|
60
|
+
async function fetchForm(id) {
|
|
61
|
+
try {
|
|
62
|
+
const result = await forms.getForm(id);
|
|
63
|
+
if (!result) {
|
|
64
|
+
throw new Error(`Form ${id} not found`);
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
console.error('Failed to load form:', id, err);
|
|
70
|
+
throw err;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
80
73
|
/**
|
|
81
|
-
* Loads form service configuration
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
* object that can be used to initialize the Form service. This is the recommended approach
|
|
85
|
-
* for server-side rendering (SSR) and static site generation (SSG) scenarios.
|
|
86
|
-
*
|
|
87
|
-
* @param {string} id - The unique identifier of the form to load
|
|
88
|
-
* @returns {Promise<FormServiceConfigResult>} A promise that resolves to either:
|
|
89
|
-
* - `{ type: 'success', config: FormServiceConfig }` if the form is found and loaded successfully
|
|
90
|
-
* - `{ type: 'notFound' }` if the form doesn't exist or an error occurs during loading
|
|
91
|
-
*
|
|
92
|
-
* @example
|
|
93
|
-
* ```tsx
|
|
94
|
-
* import { loadFormServiceConfig } from '@wix/headless-forms/services';
|
|
74
|
+
* Loads form service configuration from the Wix Forms API for SSR initialization.
|
|
75
|
+
* This function is designed to be used during Server-Side Rendering (SSR) to preload
|
|
76
|
+
* a specific form by ID that will be used to configure the FormService.
|
|
95
77
|
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* if (formServiceConfigResult.type === 'notFound') {
|
|
100
|
-
* return Astro.redirect('/404');
|
|
101
|
-
* }
|
|
102
|
-
*
|
|
103
|
-
* // Use pre-loaded form data
|
|
104
|
-
* const formServiceConfig = formServiceConfigResult.config;
|
|
105
|
-
* <Form.Root formServiceConfig={formServiceConfig} />
|
|
106
|
-
* ```
|
|
78
|
+
* @param {string} formId - The unique identifier of the form to load
|
|
79
|
+
* @returns {Promise<FormServiceConfig>} Configuration object with pre-loaded form data
|
|
80
|
+
* @throws {Error} When the form cannot be loaded
|
|
107
81
|
*
|
|
108
82
|
* @example
|
|
109
83
|
* ```tsx
|
|
110
|
-
* //
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* <Form.Loading>
|
|
114
|
-
* {({ isLoading }) => isLoading ? <div>Loading...</div> : null}
|
|
115
|
-
* </Form.Loading>
|
|
116
|
-
* <Form.Fields fieldMap={FIELD_MAP} />
|
|
117
|
-
* </Form.Root>
|
|
84
|
+
* // In your SSR/SSG setup
|
|
85
|
+
* const formConfig = await loadFormServiceConfig('form-123');
|
|
86
|
+
* const formService = FormService.withConfig(formConfig);
|
|
118
87
|
* ```
|
|
119
|
-
*
|
|
120
|
-
* @throws {Error} Logs errors to console but returns 'notFound' result instead of throwing
|
|
121
88
|
*/
|
|
122
|
-
export async function loadFormServiceConfig(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (!form) {
|
|
126
|
-
return { type: 'notFound' };
|
|
127
|
-
}
|
|
128
|
-
return {
|
|
129
|
-
type: 'success',
|
|
130
|
-
config: { form },
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
catch (error) {
|
|
134
|
-
console.error('Failed to load form:', error);
|
|
135
|
-
}
|
|
136
|
-
return { type: 'notFound' };
|
|
89
|
+
export async function loadFormServiceConfig(formId) {
|
|
90
|
+
const form = await fetchForm(formId);
|
|
91
|
+
return { form };
|
|
137
92
|
}
|