@axenstudio/axen-form 0.1.17 → 0.1.19
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 +34 -3
- package/dist/adapters/yupAdapter.cjs +29 -10
- package/dist/adapters/yupAdapter.d.ts +1 -2
- package/dist/adapters/yupAdapter.js +29 -10
- package/dist/adapters/zodAdapter.cjs +29 -10
- package/dist/adapters/zodAdapter.d.ts +1 -2
- package/dist/adapters/zodAdapter.js +29 -10
- package/dist/core/dateUtils.d.ts +0 -1
- package/dist/core/formStore.cjs +214 -47
- package/dist/core/formStore.d.ts +5 -2
- package/dist/core/formStore.js +214 -47
- package/dist/core/numberUtils.d.ts +0 -1
- package/dist/core/pathUtils.d.ts +0 -1
- package/dist/core/payloadUtils.d.ts +0 -1
- package/dist/core/semanticValidation.cjs +82 -0
- package/dist/core/semanticValidation.d.ts +5 -0
- package/dist/core/semanticValidation.js +82 -0
- package/dist/core/validation.cjs +4 -3
- package/dist/core/validation.d.ts +0 -1
- package/dist/core/validation.js +4 -3
- package/dist/fields/AutocompleteField/AutocompleteField.d.ts +1 -2
- package/dist/fields/AutocompleteMultiField/AutocompleteMultiField.d.ts +1 -2
- package/dist/fields/AutocompletePredictField/AutocompletePredictField.d.ts +1 -2
- package/dist/fields/CheckboxField/CheckboxField.d.ts +1 -2
- package/dist/fields/ColorField/ColorField.d.ts +1 -2
- package/dist/fields/CurrencyField/CurrencyField.d.ts +1 -2
- package/dist/fields/DateField/DateField.d.ts +1 -2
- package/dist/fields/DateField/DatePicker.d.ts +1 -2
- package/dist/fields/DateTimeField/DateTimeField.d.ts +1 -2
- package/dist/fields/EmailField/EmailField.d.ts +1 -2
- package/dist/fields/NumberField/NumberField.d.ts +1 -2
- package/dist/fields/PasswordField/PasswordField.d.ts +1 -2
- package/dist/fields/PhoneField/PhoneField.d.ts +1 -2
- package/dist/fields/RadioField/RadioField.d.ts +1 -2
- package/dist/fields/SelectField/SelectField.d.ts +1 -2
- package/dist/fields/SliderField/SliderField.d.ts +1 -2
- package/dist/fields/SwitchField/SwitchField.d.ts +1 -2
- package/dist/fields/TextField/TextField.d.ts +1 -2
- package/dist/fields/TextareaField/TextareaField.d.ts +1 -2
- package/dist/fields/TimeField/TimeField.d.ts +1 -2
- package/dist/fields/TimeField/TimePicker.d.ts +1 -2
- package/dist/fields/defaultComponentMap.cjs +3 -0
- package/dist/fields/defaultComponentMap.d.ts +0 -1
- package/dist/fields/defaultComponentMap.js +3 -0
- package/dist/fields/defaultPlaceholders.d.ts +0 -1
- package/dist/fields/fieldBase.module.css.cjs +92 -70
- package/dist/fields/fieldBase.module.css.js +92 -70
- package/dist/fields/fieldUtils.d.ts +0 -1
- package/dist/fields/iconUtils.d.ts +0 -1
- package/dist/fields/icons.d.ts +3 -4
- package/dist/index.cjs +31 -22
- package/dist/index.d.ts +3 -2
- package/dist/index.js +32 -23
- package/dist/layout/Box/Box.d.ts +1 -2
- package/dist/layout/Divider/Divider.d.ts +1 -2
- package/dist/layout/Grid/Grid.d.ts +1 -2
- package/dist/layout/Spacer/Spacer.d.ts +1 -2
- package/dist/layout/Stack/Stack.d.ts +1 -2
- package/dist/layout/index.d.ts +0 -1
- package/dist/react/AxenArrayField.cjs +2 -0
- package/dist/react/AxenArrayField.d.ts +1 -2
- package/dist/react/AxenArrayField.js +2 -0
- package/dist/react/AxenField.cjs +2 -0
- package/dist/react/AxenField.d.ts +1 -2
- package/dist/react/AxenField.js +2 -0
- package/dist/react/AxenForm.cjs +29 -23
- package/dist/react/AxenForm.d.ts +0 -1
- package/dist/react/AxenForm.js +30 -24
- package/dist/react/FormContext.d.ts +0 -1
- package/dist/react/useAxenForm.cjs +17 -4
- package/dist/react/useAxenForm.d.ts +1 -2
- package/dist/react/useAxenForm.js +17 -4
- package/dist/react/useField.cjs +3 -0
- package/dist/react/useField.d.ts +0 -1
- package/dist/react/useField.js +3 -0
- package/dist/react/useFieldArray.cjs +19 -13
- package/dist/react/useFieldArray.d.ts +0 -1
- package/dist/react/useFieldArray.js +19 -13
- package/dist/react/useFormState.cjs +18 -0
- package/dist/react/useFormState.d.ts +5 -0
- package/dist/react/useFormState.js +18 -0
- package/dist/types.d.ts +28 -3
- package/package.json +5 -2
- package/dist/adapters/yupAdapter.d.ts.map +0 -1
- package/dist/adapters/zodAdapter.d.ts.map +0 -1
- package/dist/core/dateUtils.d.ts.map +0 -1
- package/dist/core/formStore.d.ts.map +0 -1
- package/dist/core/numberUtils.d.ts.map +0 -1
- package/dist/core/pathUtils.d.ts.map +0 -1
- package/dist/core/payloadUtils.d.ts.map +0 -1
- package/dist/core/validation.d.ts.map +0 -1
- package/dist/fields/AutocompleteField/AutocompleteField.d.ts.map +0 -1
- package/dist/fields/AutocompleteMultiField/AutocompleteMultiField.d.ts.map +0 -1
- package/dist/fields/AutocompletePredictField/AutocompletePredictField.d.ts.map +0 -1
- package/dist/fields/CheckboxField/CheckboxField.d.ts.map +0 -1
- package/dist/fields/ColorField/ColorField.d.ts.map +0 -1
- package/dist/fields/CurrencyField/CurrencyField.d.ts.map +0 -1
- package/dist/fields/DateField/DateField.d.ts.map +0 -1
- package/dist/fields/DateField/DatePicker.d.ts.map +0 -1
- package/dist/fields/DateTimeField/DateTimeField.d.ts.map +0 -1
- package/dist/fields/EmailField/EmailField.d.ts.map +0 -1
- package/dist/fields/NumberField/NumberField.d.ts.map +0 -1
- package/dist/fields/PasswordField/PasswordField.d.ts.map +0 -1
- package/dist/fields/PhoneField/PhoneField.d.ts.map +0 -1
- package/dist/fields/RadioField/RadioField.d.ts.map +0 -1
- package/dist/fields/SelectField/SelectField.d.ts.map +0 -1
- package/dist/fields/SliderField/SliderField.d.ts.map +0 -1
- package/dist/fields/SwitchField/SwitchField.d.ts.map +0 -1
- package/dist/fields/TextField/TextField.d.ts.map +0 -1
- package/dist/fields/TextareaField/TextareaField.d.ts.map +0 -1
- package/dist/fields/TimeField/TimeField.d.ts.map +0 -1
- package/dist/fields/TimeField/TimePicker.d.ts.map +0 -1
- package/dist/fields/defaultComponentMap.d.ts.map +0 -1
- package/dist/fields/defaultPlaceholders.d.ts.map +0 -1
- package/dist/fields/fieldUtils.d.ts.map +0 -1
- package/dist/fields/iconUtils.d.ts.map +0 -1
- package/dist/fields/icons.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/layout/Box/Box.d.ts.map +0 -1
- package/dist/layout/Divider/Divider.d.ts.map +0 -1
- package/dist/layout/Grid/Grid.d.ts.map +0 -1
- package/dist/layout/Spacer/Spacer.d.ts.map +0 -1
- package/dist/layout/Stack/Stack.d.ts.map +0 -1
- package/dist/layout/index.d.ts.map +0 -1
- package/dist/react/AxenArrayField.d.ts.map +0 -1
- package/dist/react/AxenField.d.ts.map +0 -1
- package/dist/react/AxenForm.d.ts.map +0 -1
- package/dist/react/FormContext.d.ts.map +0 -1
- package/dist/react/useAxenForm.d.ts.map +0 -1
- package/dist/react/useField.d.ts.map +0 -1
- package/dist/react/useFieldArray.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
package/dist/core/formStore.cjs
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const pathUtils = require("./pathUtils.cjs");
|
|
4
|
+
function valuesEqual(a, b) {
|
|
5
|
+
if (Object.is(a, b)) return true;
|
|
6
|
+
if (a instanceof Date || b instanceof Date) return a instanceof Date && b instanceof Date && a.getTime() === b.getTime();
|
|
7
|
+
if (a === null || b === null || typeof a !== "object" || typeof b !== "object") return false;
|
|
8
|
+
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
|
9
|
+
const left = a;
|
|
10
|
+
const right = b;
|
|
11
|
+
const keys = Object.keys(left);
|
|
12
|
+
if (keys.length !== Object.keys(right).length) return false;
|
|
13
|
+
return keys.every((key) => Object.prototype.hasOwnProperty.call(right, key) && valuesEqual(left[key], right[key]));
|
|
14
|
+
}
|
|
4
15
|
function createFormStore(options) {
|
|
5
16
|
const {
|
|
6
17
|
initialValues,
|
|
@@ -12,6 +23,9 @@ function createFormStore(options) {
|
|
|
12
23
|
values: structuredClone(initialValues),
|
|
13
24
|
errors: {},
|
|
14
25
|
touched: {},
|
|
26
|
+
validationStatus: "unvalidated",
|
|
27
|
+
fieldValidationStatus: {},
|
|
28
|
+
isValidating: false,
|
|
15
29
|
dirty: false,
|
|
16
30
|
isSubmitting: false,
|
|
17
31
|
submitCount: 0,
|
|
@@ -20,6 +34,9 @@ function createFormStore(options) {
|
|
|
20
34
|
const subscribers = /* @__PURE__ */ new Set();
|
|
21
35
|
const fieldSubscribers = /* @__PURE__ */ new Map();
|
|
22
36
|
let validationSchema = options.validationSchema;
|
|
37
|
+
let valuesRevision = 0;
|
|
38
|
+
let formRequest = 0;
|
|
39
|
+
const fieldRequests = /* @__PURE__ */ new Map();
|
|
23
40
|
if (validationAdapter && options.fields && !validationSchema) {
|
|
24
41
|
validationSchema = validationAdapter.buildSchema(options.fields);
|
|
25
42
|
}
|
|
@@ -48,16 +65,53 @@ function createFormStore(options) {
|
|
|
48
65
|
var _a;
|
|
49
66
|
(_a = fieldSubscribers.get(name)) == null ? void 0 : _a.forEach((fn) => fn());
|
|
50
67
|
}
|
|
68
|
+
function notifyAllFields() {
|
|
69
|
+
for (const name of fieldSubscribers.keys()) notifyField(name);
|
|
70
|
+
notify();
|
|
71
|
+
}
|
|
72
|
+
function notifyValuePath(path) {
|
|
73
|
+
const related = (key) => key === path || key.startsWith(`${path}.`) || key.startsWith(`${path}[`) || path.startsWith(`${key}.`) || path.startsWith(`${key}[`);
|
|
74
|
+
for (const key of fieldSubscribers.keys()) if (related(key)) notifyField(key);
|
|
75
|
+
notify();
|
|
76
|
+
}
|
|
51
77
|
function setFieldValue(name, value) {
|
|
78
|
+
const nextValues = pathUtils.set(state.values, name, value);
|
|
79
|
+
const statuses = { ...state.fieldValidationStatus, [name]: "unvalidated" };
|
|
80
|
+
const dependents = (options.fields ?? []).filter((field) => {
|
|
81
|
+
var _a;
|
|
82
|
+
return field.name !== name && ((_a = field.rules) == null ? void 0 : _a.countryField) === name;
|
|
83
|
+
});
|
|
84
|
+
const errors = { ...state.errors };
|
|
85
|
+
for (const field of dependents) {
|
|
86
|
+
statuses[field.name] = "unvalidated";
|
|
87
|
+
delete errors[field.name];
|
|
88
|
+
}
|
|
89
|
+
valuesRevision += 1;
|
|
52
90
|
state = {
|
|
53
91
|
...state,
|
|
54
|
-
values:
|
|
55
|
-
|
|
92
|
+
values: nextValues,
|
|
93
|
+
errors,
|
|
94
|
+
dirty: !valuesEqual(nextValues, state.initialValues),
|
|
95
|
+
validationStatus: "unvalidated",
|
|
96
|
+
isValidating: false,
|
|
97
|
+
fieldValidationStatus: statuses
|
|
56
98
|
};
|
|
57
|
-
|
|
58
|
-
|
|
99
|
+
for (const field of options.fields ?? []) {
|
|
100
|
+
if (field.hidden && state.errors[field.name] && (typeof field.hidden === "function" ? field.hidden(nextValues) : field.hidden)) {
|
|
101
|
+
setFieldError(field.name, void 0);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
notifyValuePath(name);
|
|
105
|
+
for (const field of dependents) notifyField(field.name);
|
|
59
106
|
if (validateOnChange && validationAdapter && validationSchema) {
|
|
60
|
-
|
|
107
|
+
const revision = valuesRevision;
|
|
108
|
+
for (const fieldName of [name, ...dependents.map((field) => field.name)]) {
|
|
109
|
+
void runFieldValidation(fieldName).catch((error) => {
|
|
110
|
+
if (revision === valuesRevision) {
|
|
111
|
+
setFieldError(fieldName, error instanceof Error ? error.message : "Validation failed");
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
61
115
|
}
|
|
62
116
|
}
|
|
63
117
|
function setFieldTouched(name, touched = true) {
|
|
@@ -68,28 +122,84 @@ function createFormStore(options) {
|
|
|
68
122
|
notifyField(name);
|
|
69
123
|
notify();
|
|
70
124
|
if (validateOnBlur && touched && validationAdapter && validationSchema) {
|
|
71
|
-
|
|
125
|
+
const revision = valuesRevision;
|
|
126
|
+
void runFieldValidation(name).catch((error) => {
|
|
127
|
+
if (revision === valuesRevision) setFieldError(name, error instanceof Error ? error.message : "Validation failed");
|
|
128
|
+
});
|
|
72
129
|
}
|
|
73
130
|
}
|
|
74
131
|
function setFieldError(name, error) {
|
|
75
|
-
const
|
|
76
|
-
if (error)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
132
|
+
const errors = { ...state.errors };
|
|
133
|
+
if (error) errors[name] = error;
|
|
134
|
+
else delete errors[name];
|
|
135
|
+
state = {
|
|
136
|
+
...state,
|
|
137
|
+
errors,
|
|
138
|
+
validationStatus: Object.keys(errors).length ? "invalid" : "unvalidated",
|
|
139
|
+
isValidating: false,
|
|
140
|
+
fieldValidationStatus: { ...state.fieldValidationStatus, [name]: error ? "invalid" : "unvalidated" }
|
|
141
|
+
};
|
|
82
142
|
notifyField(name);
|
|
83
143
|
notify();
|
|
84
144
|
}
|
|
85
145
|
function setValues(values) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
146
|
+
valuesRevision += 1;
|
|
147
|
+
state = {
|
|
148
|
+
...state,
|
|
149
|
+
values,
|
|
150
|
+
dirty: !valuesEqual(values, state.initialValues),
|
|
151
|
+
validationStatus: "unvalidated",
|
|
152
|
+
isValidating: false,
|
|
153
|
+
fieldValidationStatus: {}
|
|
154
|
+
};
|
|
155
|
+
notifyAllFields();
|
|
89
156
|
}
|
|
90
157
|
function setErrors(errors) {
|
|
91
|
-
state = {
|
|
92
|
-
|
|
158
|
+
state = {
|
|
159
|
+
...state,
|
|
160
|
+
errors,
|
|
161
|
+
validationStatus: Object.keys(errors).length ? "invalid" : "unvalidated",
|
|
162
|
+
isValidating: false,
|
|
163
|
+
fieldValidationStatus: {}
|
|
164
|
+
};
|
|
165
|
+
notifyAllFields();
|
|
166
|
+
}
|
|
167
|
+
function setFieldArrayValue(name, items, origins) {
|
|
168
|
+
const remap = (entries) => {
|
|
169
|
+
const result = {};
|
|
170
|
+
for (const [path, value] of Object.entries(entries)) {
|
|
171
|
+
if (!path.startsWith(name)) {
|
|
172
|
+
result[path] = value;
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
const suffix = path.slice(name.length);
|
|
176
|
+
const match = /^(?:\.(\d+)|\[(\d+)\])(?=\.|\[|$)/.exec(suffix);
|
|
177
|
+
if (!match) {
|
|
178
|
+
result[path] = value;
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
const oldIndex = Number(match[1] ?? match[2]);
|
|
182
|
+
const tail = suffix.slice(match[0].length);
|
|
183
|
+
for (let i = 0; i < origins.length; i++) {
|
|
184
|
+
if (origins[i] !== oldIndex) continue;
|
|
185
|
+
result[`${name}${match[1] !== void 0 ? `.${i}` : `[${i}]`}${tail}`] = value;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return result;
|
|
189
|
+
};
|
|
190
|
+
const values = pathUtils.set(state.values, name, items);
|
|
191
|
+
valuesRevision += 1;
|
|
192
|
+
state = {
|
|
193
|
+
...state,
|
|
194
|
+
values,
|
|
195
|
+
dirty: !valuesEqual(values, state.initialValues),
|
|
196
|
+
errors: remap(state.errors),
|
|
197
|
+
touched: remap(state.touched),
|
|
198
|
+
validationStatus: "unvalidated",
|
|
199
|
+
isValidating: false,
|
|
200
|
+
fieldValidationStatus: remap(state.fieldValidationStatus)
|
|
201
|
+
};
|
|
202
|
+
notifyValuePath(name);
|
|
93
203
|
}
|
|
94
204
|
function resetForm(nextValues) {
|
|
95
205
|
const newValues = nextValues ? { ...state.initialValues, ...nextValues } : structuredClone(state.initialValues);
|
|
@@ -97,29 +207,94 @@ function createFormStore(options) {
|
|
|
97
207
|
values: newValues,
|
|
98
208
|
errors: {},
|
|
99
209
|
touched: {},
|
|
210
|
+
validationStatus: "unvalidated",
|
|
211
|
+
fieldValidationStatus: {},
|
|
212
|
+
isValidating: false,
|
|
100
213
|
dirty: false,
|
|
101
214
|
isSubmitting: false,
|
|
102
215
|
submitCount: state.submitCount,
|
|
103
|
-
initialValues: state.initialValues
|
|
216
|
+
initialValues: nextValues ? structuredClone(newValues) : state.initialValues
|
|
104
217
|
};
|
|
105
|
-
|
|
218
|
+
valuesRevision += 1;
|
|
219
|
+
notifyAllFields();
|
|
106
220
|
}
|
|
107
221
|
async function validateForm() {
|
|
108
222
|
if (!validationAdapter || !validationSchema) return {};
|
|
109
|
-
const
|
|
110
|
-
|
|
223
|
+
const revision = valuesRevision;
|
|
224
|
+
const request = ++formRequest;
|
|
225
|
+
state = { ...state, validationStatus: "validating", isValidating: true };
|
|
111
226
|
notify();
|
|
112
|
-
|
|
113
|
-
|
|
227
|
+
try {
|
|
228
|
+
const errors = await validationAdapter.validate(validationSchema, state.values);
|
|
229
|
+
if (revision !== valuesRevision || request !== formRequest) return state.errors;
|
|
230
|
+
const statuses = { ...state.fieldValidationStatus };
|
|
231
|
+
for (const field of options.fields ?? []) statuses[field.name] = errors[field.name] ? "invalid" : "valid";
|
|
232
|
+
state = {
|
|
233
|
+
...state,
|
|
234
|
+
errors,
|
|
235
|
+
validationStatus: Object.keys(errors).length ? "invalid" : "valid",
|
|
236
|
+
isValidating: false,
|
|
237
|
+
fieldValidationStatus: statuses
|
|
238
|
+
};
|
|
239
|
+
notify();
|
|
240
|
+
for (const name of fieldSubscribers.keys()) notifyField(name);
|
|
241
|
+
return errors;
|
|
242
|
+
} catch (error) {
|
|
243
|
+
if (revision === valuesRevision && request === formRequest) {
|
|
244
|
+
state = { ...state, validationStatus: "unvalidated", isValidating: false };
|
|
245
|
+
notify();
|
|
246
|
+
}
|
|
247
|
+
throw error;
|
|
114
248
|
}
|
|
115
|
-
return errors;
|
|
116
249
|
}
|
|
117
250
|
async function validateField(name) {
|
|
251
|
+
var _a;
|
|
118
252
|
if (!(validationAdapter == null ? void 0 : validationAdapter.validateField) || !validationSchema) return void 0;
|
|
253
|
+
const revision = valuesRevision;
|
|
254
|
+
const request = (fieldRequests.get(name) ?? 0) + 1;
|
|
255
|
+
fieldRequests.set(name, request);
|
|
256
|
+
const config = (_a = options.fields) == null ? void 0 : _a.find((field) => field.name === name);
|
|
257
|
+
const hidden = (config == null ? void 0 : config.hidden) && (typeof config.hidden === "function" ? config.hidden(state.values) : config.hidden);
|
|
258
|
+
if (hidden) {
|
|
259
|
+
setFieldError(name, void 0);
|
|
260
|
+
state = { ...state, fieldValidationStatus: { ...state.fieldValidationStatus, [name]: "valid" } };
|
|
261
|
+
notifyField(name);
|
|
262
|
+
notify();
|
|
263
|
+
return void 0;
|
|
264
|
+
}
|
|
265
|
+
state = {
|
|
266
|
+
...state,
|
|
267
|
+
fieldValidationStatus: { ...state.fieldValidationStatus, [name]: "validating" },
|
|
268
|
+
validationStatus: state.validationStatus === "validating" ? "validating" : "unvalidated"
|
|
269
|
+
};
|
|
270
|
+
notifyField(name);
|
|
271
|
+
notify();
|
|
119
272
|
const fieldValue = pathUtils.get(state.values, name);
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
273
|
+
try {
|
|
274
|
+
const error = await validationAdapter.validateField(validationSchema, name, fieldValue, state.values);
|
|
275
|
+
if (revision === valuesRevision && request === fieldRequests.get(name)) {
|
|
276
|
+
const errors = { ...state.errors };
|
|
277
|
+
if (error) errors[name] = error;
|
|
278
|
+
else delete errors[name];
|
|
279
|
+
state = {
|
|
280
|
+
...state,
|
|
281
|
+
errors,
|
|
282
|
+
validationStatus: state.validationStatus === "validating" ? "validating" : Object.keys(errors).length ? "invalid" : "unvalidated",
|
|
283
|
+
fieldValidationStatus: { ...state.fieldValidationStatus, [name]: error ? "invalid" : "valid" }
|
|
284
|
+
};
|
|
285
|
+
notifyField(name);
|
|
286
|
+
notify();
|
|
287
|
+
return error;
|
|
288
|
+
}
|
|
289
|
+
return state.errors[name];
|
|
290
|
+
} catch (error) {
|
|
291
|
+
if (revision === valuesRevision && request === fieldRequests.get(name)) {
|
|
292
|
+
state = { ...state, fieldValidationStatus: { ...state.fieldValidationStatus, [name]: "unvalidated" } };
|
|
293
|
+
notifyField(name);
|
|
294
|
+
notify();
|
|
295
|
+
}
|
|
296
|
+
throw error;
|
|
297
|
+
}
|
|
123
298
|
}
|
|
124
299
|
async function runFieldValidation(name) {
|
|
125
300
|
if (validationAdapter == null ? void 0 : validationAdapter.validateField) {
|
|
@@ -129,27 +304,18 @@ function createFormStore(options) {
|
|
|
129
304
|
}
|
|
130
305
|
}
|
|
131
306
|
async function submitForm(onSubmit) {
|
|
307
|
+
if (state.isSubmitting) return;
|
|
132
308
|
state = { ...state, isSubmitting: true, submitCount: state.submitCount + 1 };
|
|
133
309
|
notify();
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
const handler = onSubmit ?? options.onSubmit;
|
|
145
|
-
if (handler) {
|
|
146
|
-
try {
|
|
147
|
-
await handler(state.values);
|
|
148
|
-
} finally {
|
|
149
|
-
state = { ...state, isSubmitting: false };
|
|
150
|
-
notify();
|
|
151
|
-
}
|
|
152
|
-
} else {
|
|
310
|
+
try {
|
|
311
|
+
touchAllFields();
|
|
312
|
+
const revision = valuesRevision;
|
|
313
|
+
const errors = await validateForm();
|
|
314
|
+
for (const name of Object.keys(state.touched)) notifyField(name);
|
|
315
|
+
if (revision !== valuesRevision || Object.keys(errors).length > 0) return;
|
|
316
|
+
const handler = onSubmit ?? options.onSubmit;
|
|
317
|
+
if (handler) await handler(state.values);
|
|
318
|
+
} finally {
|
|
153
319
|
state = { ...state, isSubmitting: false };
|
|
154
320
|
notify();
|
|
155
321
|
}
|
|
@@ -188,6 +354,7 @@ function createFormStore(options) {
|
|
|
188
354
|
setFieldError,
|
|
189
355
|
setValues,
|
|
190
356
|
setErrors,
|
|
357
|
+
setFieldArrayValue,
|
|
191
358
|
resetForm,
|
|
192
359
|
validateForm,
|
|
193
360
|
validateField,
|
package/dist/core/formStore.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import { FieldConfig, ValidationAdapter } from '../types';
|
|
1
|
+
import { FieldConfig, ValidationAdapter, ValidationStatus } from '../types';
|
|
2
2
|
export interface FormState<TValues extends Record<string, unknown> = Record<string, unknown>> {
|
|
3
3
|
values: TValues;
|
|
4
4
|
errors: Record<string, string>;
|
|
5
5
|
touched: Record<string, boolean>;
|
|
6
|
+
validationStatus: ValidationStatus;
|
|
7
|
+
fieldValidationStatus: Record<string, ValidationStatus>;
|
|
8
|
+
isValidating: boolean;
|
|
6
9
|
dirty: boolean;
|
|
7
10
|
isSubmitting: boolean;
|
|
8
11
|
submitCount: number;
|
|
@@ -27,6 +30,7 @@ export declare function createFormStore<TValues extends Record<string, unknown>>
|
|
|
27
30
|
setFieldError: (name: string, error: string | undefined) => void;
|
|
28
31
|
setValues: (values: TValues) => void;
|
|
29
32
|
setErrors: (errors: Record<string, string>) => void;
|
|
33
|
+
setFieldArrayValue: (name: string, items: unknown[], origins: Array<number | null>) => void;
|
|
30
34
|
resetForm: (nextValues?: Partial<TValues>) => void;
|
|
31
35
|
validateForm: () => Promise<Record<string, string>>;
|
|
32
36
|
validateField: (name: string) => Promise<string | undefined>;
|
|
@@ -37,4 +41,3 @@ export declare function createFormStore<TValues extends Record<string, unknown>>
|
|
|
37
41
|
getFieldTouched: (name: string) => boolean;
|
|
38
42
|
};
|
|
39
43
|
export type FormStore<TValues extends Record<string, unknown> = Record<string, unknown>> = ReturnType<typeof createFormStore<TValues>>;
|
|
40
|
-
//# sourceMappingURL=formStore.d.ts.map
|