@tanstack/form-core 0.10.3 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/FieldApi.d.ts +95 -0
- package/dist/cjs/FormApi.d.ts +118 -0
- package/dist/cjs/index.cjs +926 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.cts +5 -0
- package/dist/cjs/index.d.ts +5 -0
- package/dist/cjs/index.js +926 -0
- package/dist/cjs/mergeForm.d.ts +4 -0
- package/dist/cjs/tests/FieldApi.spec.d.ts +1 -0
- package/dist/cjs/tests/FieldApi.test-d.d.ts +1 -0
- package/dist/cjs/tests/FormApi.spec.d.ts +1 -0
- package/dist/cjs/tests/mutateMergeDeep.spec.d.ts +1 -0
- package/dist/cjs/tests/utils.d.ts +1 -0
- package/dist/cjs/tests/utils.spec.d.ts +1 -0
- package/dist/cjs/types.d.ts +14 -0
- package/dist/cjs/utils.d.ts +57 -0
- package/dist/mjs/FieldApi.d.ts +95 -0
- package/dist/mjs/FormApi.d.ts +118 -0
- package/dist/mjs/index.d.mts +5 -0
- package/dist/mjs/index.d.ts +5 -0
- package/dist/mjs/index.js +926 -0
- package/dist/mjs/index.mjs +926 -0
- package/dist/mjs/index.mjs.map +1 -0
- package/dist/mjs/mergeForm.d.ts +4 -0
- package/dist/mjs/tests/FieldApi.spec.d.ts +1 -0
- package/dist/mjs/tests/FieldApi.test-d.d.ts +1 -0
- package/dist/mjs/tests/FormApi.spec.d.ts +1 -0
- package/dist/mjs/tests/mutateMergeDeep.spec.d.ts +1 -0
- package/dist/mjs/tests/utils.d.ts +1 -0
- package/dist/mjs/tests/utils.spec.d.ts +1 -0
- package/dist/mjs/types.d.ts +14 -0
- package/dist/mjs/utils.d.ts +57 -0
- package/package.json +16 -21
- package/src/FieldApi.ts +328 -236
- package/src/FormApi.ts +302 -216
- package/src/index.ts +1 -0
- package/src/mergeForm.ts +42 -0
- package/src/tests/FieldApi.spec.ts +135 -48
- package/src/tests/FieldApi.test-d.ts +10 -6
- package/src/tests/FormApi.spec.ts +171 -62
- package/src/tests/mutateMergeDeep.spec.ts +32 -0
- package/src/tests/utils.ts +1 -1
- package/src/types.ts +11 -2
- package/src/utils.ts +137 -14
- package/build/legacy/FieldApi.cjs +0 -340
- package/build/legacy/FieldApi.cjs.map +0 -1
- package/build/legacy/FieldApi.d.cts +0 -4
- package/build/legacy/FieldApi.d.ts +0 -4
- package/build/legacy/FieldApi.js +0 -315
- package/build/legacy/FieldApi.js.map +0 -1
- package/build/legacy/FormApi.cjs +0 -438
- package/build/legacy/FormApi.cjs.map +0 -1
- package/build/legacy/FormApi.d.cts +0 -4
- package/build/legacy/FormApi.d.ts +0 -4
- package/build/legacy/FormApi.js +0 -419
- package/build/legacy/FormApi.js.map +0 -1
- package/build/legacy/index.cjs +0 -31
- package/build/legacy/index.cjs.map +0 -1
- package/build/legacy/index.d.cts +0 -170
- package/build/legacy/index.d.ts +0 -170
- package/build/legacy/index.js +0 -6
- package/build/legacy/index.js.map +0 -1
- package/build/legacy/types.cjs +0 -19
- package/build/legacy/types.cjs.map +0 -1
- package/build/legacy/types.d.cts +0 -7
- package/build/legacy/types.d.ts +0 -7
- package/build/legacy/types.js +0 -1
- package/build/legacy/types.js.map +0 -1
- package/build/legacy/utils.cjs +0 -132
- package/build/legacy/utils.cjs.map +0 -1
- package/build/legacy/utils.d.cts +0 -37
- package/build/legacy/utils.d.ts +0 -37
- package/build/legacy/utils.js +0 -103
- package/build/legacy/utils.js.map +0 -1
- package/build/modern/FieldApi.cjs +0 -337
- package/build/modern/FieldApi.cjs.map +0 -1
- package/build/modern/FieldApi.d.cts +0 -4
- package/build/modern/FieldApi.d.ts +0 -4
- package/build/modern/FieldApi.js +0 -312
- package/build/modern/FieldApi.js.map +0 -1
- package/build/modern/FormApi.cjs +0 -431
- package/build/modern/FormApi.cjs.map +0 -1
- package/build/modern/FormApi.d.cts +0 -4
- package/build/modern/FormApi.d.ts +0 -4
- package/build/modern/FormApi.js +0 -412
- package/build/modern/FormApi.js.map +0 -1
- package/build/modern/index.cjs +0 -31
- package/build/modern/index.cjs.map +0 -1
- package/build/modern/index.d.cts +0 -170
- package/build/modern/index.d.ts +0 -170
- package/build/modern/index.js +0 -6
- package/build/modern/index.js.map +0 -1
- package/build/modern/types.cjs +0 -19
- package/build/modern/types.cjs.map +0 -1
- package/build/modern/types.d.cts +0 -7
- package/build/modern/types.d.ts +0 -7
- package/build/modern/types.js +0 -1
- package/build/modern/types.js.map +0 -1
- package/build/modern/utils.cjs +0 -132
- package/build/modern/utils.cjs.map +0 -1
- package/build/modern/utils.d.cts +0 -37
- package/build/modern/utils.d.ts +0 -37
- package/build/modern/utils.js +0 -103
- package/build/modern/utils.js.map +0 -1
package/build/modern/FormApi.cjs
DELETED
|
@@ -1,431 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/FormApi.ts
|
|
21
|
-
var FormApi_exports = {};
|
|
22
|
-
__export(FormApi_exports, {
|
|
23
|
-
FormApi: () => FormApi
|
|
24
|
-
});
|
|
25
|
-
module.exports = __toCommonJS(FormApi_exports);
|
|
26
|
-
var import_store = require("@tanstack/store");
|
|
27
|
-
var import_utils = require("./utils.cjs");
|
|
28
|
-
function getDefaultFormState(defaultState) {
|
|
29
|
-
return {
|
|
30
|
-
values: defaultState.values ?? {},
|
|
31
|
-
errors: defaultState.errors ?? [],
|
|
32
|
-
errorMap: defaultState.errorMap ?? {},
|
|
33
|
-
fieldMeta: defaultState.fieldMeta ?? {},
|
|
34
|
-
canSubmit: defaultState.canSubmit ?? true,
|
|
35
|
-
isFieldsValid: defaultState.isFieldsValid ?? false,
|
|
36
|
-
isFieldsValidating: defaultState.isFieldsValidating ?? false,
|
|
37
|
-
isFormValid: defaultState.isFormValid ?? false,
|
|
38
|
-
isFormValidating: defaultState.isFormValidating ?? false,
|
|
39
|
-
isSubmitted: defaultState.isSubmitted ?? false,
|
|
40
|
-
isSubmitting: defaultState.isSubmitting ?? false,
|
|
41
|
-
isTouched: defaultState.isTouched ?? false,
|
|
42
|
-
isValid: defaultState.isValid ?? false,
|
|
43
|
-
isValidating: defaultState.isValidating ?? false,
|
|
44
|
-
submissionAttempts: defaultState.submissionAttempts ?? 0,
|
|
45
|
-
formValidationCount: defaultState.formValidationCount ?? 0
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
var FormApi = class {
|
|
49
|
-
constructor(opts) {
|
|
50
|
-
// // This carries the context for nested fields
|
|
51
|
-
this.options = {};
|
|
52
|
-
this.fieldInfo = {};
|
|
53
|
-
this.validationMeta = {};
|
|
54
|
-
this.mount = () => {
|
|
55
|
-
const doValidate = () => {
|
|
56
|
-
if (this.options.validator && typeof this.options.onMount !== "function") {
|
|
57
|
-
return this.options.validator().validate(
|
|
58
|
-
this.state.values,
|
|
59
|
-
this.options.onMount
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
return this.options.onMount(
|
|
63
|
-
this.state.values,
|
|
64
|
-
this
|
|
65
|
-
);
|
|
66
|
-
};
|
|
67
|
-
if (!this.options.onMount)
|
|
68
|
-
return;
|
|
69
|
-
const error = doValidate();
|
|
70
|
-
if (error) {
|
|
71
|
-
this.store.setState((prev) => ({
|
|
72
|
-
...prev,
|
|
73
|
-
errorMap: { ...prev.errorMap, onMount: error }
|
|
74
|
-
}));
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
this.update = (options) => {
|
|
78
|
-
if (!options)
|
|
79
|
-
return;
|
|
80
|
-
this.store.batch(() => {
|
|
81
|
-
const shouldUpdateValues = options.defaultValues && options.defaultValues !== this.options.defaultValues && !this.state.isTouched;
|
|
82
|
-
const shouldUpdateState = options.defaultState !== this.options.defaultState && !this.state.isTouched;
|
|
83
|
-
this.store.setState(
|
|
84
|
-
() => getDefaultFormState(
|
|
85
|
-
Object.assign(
|
|
86
|
-
{},
|
|
87
|
-
this.state,
|
|
88
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
89
|
-
shouldUpdateState ? options.defaultState : {},
|
|
90
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
91
|
-
shouldUpdateValues ? {
|
|
92
|
-
values: options.defaultValues
|
|
93
|
-
} : {}
|
|
94
|
-
)
|
|
95
|
-
)
|
|
96
|
-
);
|
|
97
|
-
});
|
|
98
|
-
this.options = options;
|
|
99
|
-
};
|
|
100
|
-
this.reset = () => this.store.setState(
|
|
101
|
-
() => getDefaultFormState({
|
|
102
|
-
...this.options.defaultState,
|
|
103
|
-
values: this.options.defaultValues ?? this.options.defaultState?.values
|
|
104
|
-
})
|
|
105
|
-
);
|
|
106
|
-
this.validateAllFields = async (cause) => {
|
|
107
|
-
const fieldValidationPromises = [];
|
|
108
|
-
this.store.batch(() => {
|
|
109
|
-
void Object.values(this.fieldInfo).forEach((field) => {
|
|
110
|
-
Object.values(field.instances).forEach((instance) => {
|
|
111
|
-
fieldValidationPromises.push(
|
|
112
|
-
Promise.resolve().then(() => instance.validate(cause))
|
|
113
|
-
);
|
|
114
|
-
if (!instance.state.meta.isTouched) {
|
|
115
|
-
instance.setMeta((prev) => ({ ...prev, isTouched: true }));
|
|
116
|
-
}
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
return Promise.all(fieldValidationPromises);
|
|
121
|
-
};
|
|
122
|
-
this.validateSync = (cause) => {
|
|
123
|
-
const { onChange, onBlur } = this.options;
|
|
124
|
-
const validate = cause === "change" ? onChange : cause === "blur" ? onBlur : void 0;
|
|
125
|
-
if (!validate)
|
|
126
|
-
return;
|
|
127
|
-
const errorMapKey = getErrorMapKey(cause);
|
|
128
|
-
const doValidate = () => {
|
|
129
|
-
if (this.options.validator && typeof validate !== "function") {
|
|
130
|
-
return this.options.validator().validate(
|
|
131
|
-
this.state.values,
|
|
132
|
-
validate
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
return validate(
|
|
136
|
-
this.state.values,
|
|
137
|
-
this
|
|
138
|
-
);
|
|
139
|
-
};
|
|
140
|
-
const error = normalizeError(doValidate());
|
|
141
|
-
if (this.state.errorMap[errorMapKey] !== error) {
|
|
142
|
-
this.store.setState((prev) => ({
|
|
143
|
-
...prev,
|
|
144
|
-
errorMap: {
|
|
145
|
-
...prev.errorMap,
|
|
146
|
-
[errorMapKey]: error
|
|
147
|
-
}
|
|
148
|
-
}));
|
|
149
|
-
}
|
|
150
|
-
if (this.state.errorMap[errorMapKey]) {
|
|
151
|
-
this.cancelValidateAsync();
|
|
152
|
-
}
|
|
153
|
-
};
|
|
154
|
-
this.__leaseValidateAsync = () => {
|
|
155
|
-
const count = (this.validationMeta.validationAsyncCount || 0) + 1;
|
|
156
|
-
this.validationMeta.validationAsyncCount = count;
|
|
157
|
-
return count;
|
|
158
|
-
};
|
|
159
|
-
this.cancelValidateAsync = () => {
|
|
160
|
-
this.__leaseValidateAsync();
|
|
161
|
-
this.store.setState((prev) => ({
|
|
162
|
-
...prev,
|
|
163
|
-
isFormValidating: false
|
|
164
|
-
}));
|
|
165
|
-
};
|
|
166
|
-
this.validateAsync = async (cause) => {
|
|
167
|
-
const {
|
|
168
|
-
onChangeAsync,
|
|
169
|
-
onBlurAsync,
|
|
170
|
-
asyncDebounceMs,
|
|
171
|
-
onBlurAsyncDebounceMs,
|
|
172
|
-
onChangeAsyncDebounceMs
|
|
173
|
-
} = this.options;
|
|
174
|
-
const validate = cause === "change" ? onChangeAsync : cause === "blur" ? onBlurAsync : void 0;
|
|
175
|
-
if (!validate)
|
|
176
|
-
return [];
|
|
177
|
-
const debounceMs = (cause === "change" ? onChangeAsyncDebounceMs : onBlurAsyncDebounceMs) ?? asyncDebounceMs ?? 0;
|
|
178
|
-
if (!this.state.isFormValidating) {
|
|
179
|
-
this.store.setState((prev) => ({ ...prev, isFormValidating: true }));
|
|
180
|
-
}
|
|
181
|
-
const validationAsyncCount = this.__leaseValidateAsync();
|
|
182
|
-
const checkLatest = () => validationAsyncCount === this.validationMeta.validationAsyncCount;
|
|
183
|
-
if (!this.validationMeta.validationPromise) {
|
|
184
|
-
this.validationMeta.validationPromise = new Promise((resolve, reject) => {
|
|
185
|
-
this.validationMeta.validationResolve = resolve;
|
|
186
|
-
this.validationMeta.validationReject = reject;
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
if (debounceMs > 0) {
|
|
190
|
-
await new Promise((r) => setTimeout(r, debounceMs));
|
|
191
|
-
}
|
|
192
|
-
const doValidate = () => {
|
|
193
|
-
if (typeof validate === "function") {
|
|
194
|
-
return validate(this.state.values, this);
|
|
195
|
-
}
|
|
196
|
-
if (this.options.validator && typeof validate !== "function") {
|
|
197
|
-
return this.options.validator().validateAsync(
|
|
198
|
-
this.state.values,
|
|
199
|
-
validate
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
const errorMapKey = getErrorMapKey(cause);
|
|
203
|
-
throw new Error(
|
|
204
|
-
`Form validation for ${errorMapKey}Async failed. ${errorMapKey}Async should either be a function, or \`validator\` should be correct.`
|
|
205
|
-
);
|
|
206
|
-
};
|
|
207
|
-
if (checkLatest()) {
|
|
208
|
-
const prevErrors = this.state.errors;
|
|
209
|
-
try {
|
|
210
|
-
const rawError = await doValidate();
|
|
211
|
-
if (checkLatest()) {
|
|
212
|
-
const error = normalizeError(rawError);
|
|
213
|
-
this.store.setState((prev) => ({
|
|
214
|
-
...prev,
|
|
215
|
-
isFormValidating: false,
|
|
216
|
-
errorMap: {
|
|
217
|
-
...prev.errorMap,
|
|
218
|
-
[getErrorMapKey(cause)]: error
|
|
219
|
-
}
|
|
220
|
-
}));
|
|
221
|
-
this.validationMeta.validationResolve?.([...prevErrors, error]);
|
|
222
|
-
}
|
|
223
|
-
} catch (error) {
|
|
224
|
-
if (checkLatest()) {
|
|
225
|
-
this.validationMeta.validationReject?.([...prevErrors, error]);
|
|
226
|
-
throw error;
|
|
227
|
-
}
|
|
228
|
-
} finally {
|
|
229
|
-
if (checkLatest()) {
|
|
230
|
-
this.store.setState((prev) => ({ ...prev, isFormValidating: false }));
|
|
231
|
-
delete this.validationMeta.validationPromise;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
return await this.validationMeta.validationPromise ?? [];
|
|
236
|
-
};
|
|
237
|
-
this.validate = (cause) => {
|
|
238
|
-
const errorMapKey = getErrorMapKey(cause);
|
|
239
|
-
const prevError = this.state.errorMap[errorMapKey];
|
|
240
|
-
this.validateSync(cause);
|
|
241
|
-
const newError = this.state.errorMap[errorMapKey];
|
|
242
|
-
if (prevError !== newError && !this.options.asyncAlways && !(newError === void 0 && prevError !== void 0))
|
|
243
|
-
return this.state.errors;
|
|
244
|
-
return this.validateAsync(cause);
|
|
245
|
-
};
|
|
246
|
-
this.handleSubmit = async () => {
|
|
247
|
-
this.store.setState((old) => ({
|
|
248
|
-
...old,
|
|
249
|
-
// Submission attempts mark the form as not submitted
|
|
250
|
-
isSubmitted: false,
|
|
251
|
-
// Count submission attempts
|
|
252
|
-
submissionAttempts: old.submissionAttempts + 1
|
|
253
|
-
}));
|
|
254
|
-
if (!this.state.canSubmit)
|
|
255
|
-
return;
|
|
256
|
-
this.store.setState((d) => ({ ...d, isSubmitting: true }));
|
|
257
|
-
const done = () => {
|
|
258
|
-
this.store.setState((prev) => ({ ...prev, isSubmitting: false }));
|
|
259
|
-
};
|
|
260
|
-
await this.validateAllFields("submit");
|
|
261
|
-
if (!this.state.isFieldsValid) {
|
|
262
|
-
done();
|
|
263
|
-
this.options.onSubmitInvalid?.(this.state.values, this);
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
await this.validate("submit");
|
|
267
|
-
if (!this.state.isValid) {
|
|
268
|
-
done();
|
|
269
|
-
this.options.onSubmitInvalid?.(this.state.values, this);
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
try {
|
|
273
|
-
await this.options.onSubmit?.(this.state.values, this);
|
|
274
|
-
this.store.batch(() => {
|
|
275
|
-
this.store.setState((prev) => ({ ...prev, isSubmitted: true }));
|
|
276
|
-
done();
|
|
277
|
-
});
|
|
278
|
-
} catch (err) {
|
|
279
|
-
done();
|
|
280
|
-
throw err;
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
|
-
this.getFieldValue = (field) => (0, import_utils.getBy)(this.state.values, field);
|
|
284
|
-
this.getFieldMeta = (field) => {
|
|
285
|
-
return this.state.fieldMeta[field];
|
|
286
|
-
};
|
|
287
|
-
this.getFieldInfo = (field) => {
|
|
288
|
-
return this.fieldInfo[field] ||= {
|
|
289
|
-
instances: {}
|
|
290
|
-
};
|
|
291
|
-
};
|
|
292
|
-
this.setFieldMeta = (field, updater) => {
|
|
293
|
-
this.store.setState((prev) => {
|
|
294
|
-
return {
|
|
295
|
-
...prev,
|
|
296
|
-
fieldMeta: {
|
|
297
|
-
...prev.fieldMeta,
|
|
298
|
-
[field]: (0, import_utils.functionalUpdate)(updater, prev.fieldMeta[field])
|
|
299
|
-
}
|
|
300
|
-
};
|
|
301
|
-
});
|
|
302
|
-
};
|
|
303
|
-
this.setFieldValue = (field, updater, opts) => {
|
|
304
|
-
const touch = opts?.touch;
|
|
305
|
-
this.store.batch(() => {
|
|
306
|
-
if (touch) {
|
|
307
|
-
this.setFieldMeta(field, (prev) => ({
|
|
308
|
-
...prev,
|
|
309
|
-
isTouched: true
|
|
310
|
-
}));
|
|
311
|
-
}
|
|
312
|
-
this.store.setState((prev) => {
|
|
313
|
-
return {
|
|
314
|
-
...prev,
|
|
315
|
-
values: (0, import_utils.setBy)(prev.values, field, updater)
|
|
316
|
-
};
|
|
317
|
-
});
|
|
318
|
-
});
|
|
319
|
-
};
|
|
320
|
-
this.deleteField = (field) => {
|
|
321
|
-
this.store.setState((prev) => {
|
|
322
|
-
const newState = { ...prev };
|
|
323
|
-
newState.values = (0, import_utils.deleteBy)(newState.values, field);
|
|
324
|
-
delete newState.fieldMeta[field];
|
|
325
|
-
return newState;
|
|
326
|
-
});
|
|
327
|
-
};
|
|
328
|
-
this.pushFieldValue = (field, value, opts) => {
|
|
329
|
-
return this.setFieldValue(
|
|
330
|
-
field,
|
|
331
|
-
(prev) => [...Array.isArray(prev) ? prev : [], value],
|
|
332
|
-
opts
|
|
333
|
-
);
|
|
334
|
-
};
|
|
335
|
-
this.insertFieldValue = (field, index, value, opts) => {
|
|
336
|
-
this.setFieldValue(
|
|
337
|
-
field,
|
|
338
|
-
(prev) => {
|
|
339
|
-
return prev.map(
|
|
340
|
-
(d, i) => i === index ? value : d
|
|
341
|
-
);
|
|
342
|
-
},
|
|
343
|
-
opts
|
|
344
|
-
);
|
|
345
|
-
};
|
|
346
|
-
this.removeFieldValue = (field, index, opts) => {
|
|
347
|
-
this.setFieldValue(
|
|
348
|
-
field,
|
|
349
|
-
(prev) => {
|
|
350
|
-
return prev.filter(
|
|
351
|
-
(_d, i) => i !== index
|
|
352
|
-
);
|
|
353
|
-
},
|
|
354
|
-
opts
|
|
355
|
-
);
|
|
356
|
-
};
|
|
357
|
-
this.swapFieldValues = (field, index1, index2) => {
|
|
358
|
-
this.setFieldValue(field, (prev) => {
|
|
359
|
-
const prev1 = prev[index1];
|
|
360
|
-
const prev2 = prev[index2];
|
|
361
|
-
return (0, import_utils.setBy)((0, import_utils.setBy)(prev, `${index1}`, prev2), `${index2}`, prev1);
|
|
362
|
-
});
|
|
363
|
-
};
|
|
364
|
-
this.store = new import_store.Store(
|
|
365
|
-
getDefaultFormState({
|
|
366
|
-
...opts?.defaultState,
|
|
367
|
-
values: opts?.defaultValues ?? opts?.defaultState?.values,
|
|
368
|
-
isFormValid: true
|
|
369
|
-
}),
|
|
370
|
-
{
|
|
371
|
-
onUpdate: () => {
|
|
372
|
-
let { state } = this.store;
|
|
373
|
-
const fieldMetaValues = Object.values(state.fieldMeta);
|
|
374
|
-
const isFieldsValidating = fieldMetaValues.some(
|
|
375
|
-
(field) => field?.isValidating
|
|
376
|
-
);
|
|
377
|
-
const isFieldsValid = !fieldMetaValues.some(
|
|
378
|
-
(field) => field?.errorMap && (0, import_utils.isNonEmptyArray)(Object.values(field.errorMap).filter(Boolean))
|
|
379
|
-
);
|
|
380
|
-
const isTouched = fieldMetaValues.some((field) => field?.isTouched);
|
|
381
|
-
const isValidating = isFieldsValidating || state.isFormValidating;
|
|
382
|
-
state.errors = Object.values(state.errorMap).filter(
|
|
383
|
-
(val) => val !== void 0
|
|
384
|
-
);
|
|
385
|
-
const isFormValid = state.errors.length === 0;
|
|
386
|
-
const isValid = isFieldsValid && isFormValid;
|
|
387
|
-
const canSubmit = state.submissionAttempts === 0 && !isTouched || !isValidating && !state.isSubmitting && isValid;
|
|
388
|
-
state = {
|
|
389
|
-
...state,
|
|
390
|
-
isFieldsValidating,
|
|
391
|
-
isFieldsValid,
|
|
392
|
-
isFormValid,
|
|
393
|
-
isValid,
|
|
394
|
-
canSubmit,
|
|
395
|
-
isTouched
|
|
396
|
-
};
|
|
397
|
-
this.store.state = state;
|
|
398
|
-
this.state = state;
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
);
|
|
402
|
-
this.state = this.store.state;
|
|
403
|
-
this.update(opts || {});
|
|
404
|
-
}
|
|
405
|
-
};
|
|
406
|
-
function normalizeError(rawError) {
|
|
407
|
-
if (rawError) {
|
|
408
|
-
if (typeof rawError !== "string") {
|
|
409
|
-
return "Invalid Form Values";
|
|
410
|
-
}
|
|
411
|
-
return rawError;
|
|
412
|
-
}
|
|
413
|
-
return void 0;
|
|
414
|
-
}
|
|
415
|
-
function getErrorMapKey(cause) {
|
|
416
|
-
switch (cause) {
|
|
417
|
-
case "submit":
|
|
418
|
-
return "onSubmit";
|
|
419
|
-
case "change":
|
|
420
|
-
return "onChange";
|
|
421
|
-
case "blur":
|
|
422
|
-
return "onBlur";
|
|
423
|
-
case "mount":
|
|
424
|
-
return "onMount";
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
428
|
-
0 && (module.exports = {
|
|
429
|
-
FormApi
|
|
430
|
-
});
|
|
431
|
-
//# sourceMappingURL=FormApi.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/FormApi.ts"],"sourcesContent":["import { Store } from '@tanstack/store'\nimport type { DeepKeys, DeepValue, Updater } from './utils'\nimport {\n deleteBy,\n functionalUpdate,\n getBy,\n isNonEmptyArray,\n setBy,\n} from './utils'\nimport type { FieldApi, FieldMeta, ValidationCause } from './FieldApi'\nimport type { ValidationError, Validator } from './types'\n\ntype ValidateFn<TData, ValidatorType> = (\n values: TData,\n formApi: FormApi<TData, ValidatorType>,\n) => ValidationError\n\ntype ValidateOrFn<TData, ValidatorType> = ValidatorType extends Validator<TData>\n ? Parameters<ReturnType<ValidatorType>['validate']>[1]\n : ValidateFn<TData, ValidatorType>\n\ntype ValidateAsyncFn<TData, ValidatorType> = (\n value: TData,\n fieldApi: FormApi<TData, ValidatorType>,\n) => ValidationError | Promise<ValidationError>\n\nexport type FormOptions<TData, ValidatorType> = {\n defaultValues?: TData\n defaultState?: Partial<FormState<TData>>\n asyncAlways?: boolean\n asyncDebounceMs?: number\n validator?: ValidatorType\n onMount?: ValidateOrFn<TData, ValidatorType>\n onChange?: ValidateOrFn<TData, ValidatorType>\n onChangeAsync?: ValidateAsyncFn<TData, ValidatorType>\n onChangeAsyncDebounceMs?: number\n onBlur?: ValidateOrFn<TData, ValidatorType>\n onBlurAsync?: ValidateAsyncFn<TData, ValidatorType>\n onBlurAsyncDebounceMs?: number\n onSubmit?: (\n values: TData,\n formApi: FormApi<TData, ValidatorType>,\n ) => any | Promise<any>\n onSubmitInvalid?: (\n values: TData,\n formApi: FormApi<TData, ValidatorType>,\n ) => void\n}\n\nexport type FieldInfo<TFormData, ValidatorType> = {\n instances: Record<string, FieldApi<TFormData, any, unknown, ValidatorType>>\n} & ValidationMeta\n\nexport type ValidationMeta = {\n validationCount?: number\n validationAsyncCount?: number\n validationPromise?: Promise<ValidationError[] | undefined>\n validationResolve?: (errors: ValidationError[] | undefined) => void\n validationReject?: (errors: unknown) => void\n}\n\nexport type ValidationErrorMapKeys = `on${Capitalize<ValidationCause>}`\n\nexport type ValidationErrorMap = {\n [K in ValidationErrorMapKeys]?: ValidationError\n}\n\nexport type FormState<TData> = {\n values: TData\n // Form Validation\n isFormValidating: boolean\n formValidationCount: number\n isFormValid: boolean\n errors: ValidationError[]\n errorMap: ValidationErrorMap\n // Fields\n fieldMeta: Record<DeepKeys<TData>, FieldMeta>\n isFieldsValidating: boolean\n isFieldsValid: boolean\n isSubmitting: boolean\n // General\n isTouched: boolean\n isSubmitted: boolean\n isValidating: boolean\n isValid: boolean\n canSubmit: boolean\n submissionAttempts: number\n}\n\nfunction getDefaultFormState<TData>(\n defaultState: Partial<FormState<TData>>,\n): FormState<TData> {\n return {\n values: defaultState.values ?? ({} as never),\n errors: defaultState.errors ?? [],\n errorMap: defaultState.errorMap ?? {},\n fieldMeta: defaultState.fieldMeta ?? ({} as never),\n canSubmit: defaultState.canSubmit ?? true,\n isFieldsValid: defaultState.isFieldsValid ?? false,\n isFieldsValidating: defaultState.isFieldsValidating ?? false,\n isFormValid: defaultState.isFormValid ?? false,\n isFormValidating: defaultState.isFormValidating ?? false,\n isSubmitted: defaultState.isSubmitted ?? false,\n isSubmitting: defaultState.isSubmitting ?? false,\n isTouched: defaultState.isTouched ?? false,\n isValid: defaultState.isValid ?? false,\n isValidating: defaultState.isValidating ?? false,\n submissionAttempts: defaultState.submissionAttempts ?? 0,\n formValidationCount: defaultState.formValidationCount ?? 0,\n }\n}\n\nexport class FormApi<TFormData, ValidatorType> {\n // // This carries the context for nested fields\n options: FormOptions<TFormData, ValidatorType> = {}\n store!: Store<FormState<TFormData>>\n // Do not use __state directly, as it is not reactive.\n // Please use form.useStore() utility to subscribe to state\n state!: FormState<TFormData>\n fieldInfo: Record<DeepKeys<TFormData>, FieldInfo<TFormData, ValidatorType>> =\n {} as any\n fieldName?: string\n validationMeta: ValidationMeta = {}\n\n constructor(opts?: FormOptions<TFormData, ValidatorType>) {\n this.store = new Store<FormState<TFormData>>(\n getDefaultFormState({\n ...(opts?.defaultState as any),\n values: opts?.defaultValues ?? opts?.defaultState?.values,\n isFormValid: true,\n }),\n {\n onUpdate: () => {\n let { state } = this.store\n // Computed state\n const fieldMetaValues = Object.values(state.fieldMeta) as (\n | FieldMeta\n | undefined\n )[]\n\n const isFieldsValidating = fieldMetaValues.some(\n (field) => field?.isValidating,\n )\n\n const isFieldsValid = !fieldMetaValues.some(\n (field) =>\n field?.errorMap &&\n isNonEmptyArray(Object.values(field.errorMap).filter(Boolean)),\n )\n\n const isTouched = fieldMetaValues.some((field) => field?.isTouched)\n\n const isValidating = isFieldsValidating || state.isFormValidating\n state.errors = Object.values(state.errorMap).filter(\n (val: unknown) => val !== undefined,\n )\n const isFormValid = state.errors.length === 0\n const isValid = isFieldsValid && isFormValid\n const canSubmit =\n (state.submissionAttempts === 0 && !isTouched) ||\n (!isValidating && !state.isSubmitting && isValid)\n\n state = {\n ...state,\n isFieldsValidating,\n isFieldsValid,\n isFormValid,\n isValid,\n canSubmit,\n isTouched,\n }\n\n this.store.state = state\n this.state = state\n },\n },\n )\n\n this.state = this.store.state\n\n this.update(opts || {})\n }\n\n mount = () => {\n const doValidate = () => {\n if (\n this.options.validator &&\n typeof this.options.onMount !== 'function'\n ) {\n return (this.options.validator as Validator<TFormData>)().validate(\n this.state.values,\n this.options.onMount,\n )\n }\n return (this.options.onMount as ValidateFn<TFormData, ValidatorType>)(\n this.state.values,\n this,\n )\n }\n if (!this.options.onMount) return\n const error = doValidate()\n if (error) {\n this.store.setState((prev) => ({\n ...prev,\n errorMap: { ...prev.errorMap, onMount: error },\n }))\n }\n }\n\n update = (options?: FormOptions<TFormData, ValidatorType>) => {\n if (!options) return\n\n this.store.batch(() => {\n const shouldUpdateValues =\n options.defaultValues &&\n options.defaultValues !== this.options.defaultValues &&\n !this.state.isTouched\n\n const shouldUpdateState =\n options.defaultState !== this.options.defaultState &&\n !this.state.isTouched\n\n this.store.setState(() =>\n getDefaultFormState(\n Object.assign(\n {},\n this.state as any,\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n shouldUpdateState ? options.defaultState : {},\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n shouldUpdateValues\n ? {\n values: options.defaultValues,\n }\n : {},\n ),\n ),\n )\n })\n\n this.options = options\n }\n\n reset = () =>\n this.store.setState(() =>\n getDefaultFormState({\n ...(this.options.defaultState as any),\n values: this.options.defaultValues ?? this.options.defaultState?.values,\n }),\n )\n\n validateAllFields = async (cause: ValidationCause) => {\n const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any\n this.store.batch(() => {\n void (\n Object.values(this.fieldInfo) as FieldInfo<any, ValidatorType>[]\n ).forEach((field) => {\n Object.values(field.instances).forEach((instance) => {\n // Validate the field\n fieldValidationPromises.push(\n Promise.resolve().then(() => instance.validate(cause)),\n )\n // If any fields are not touched\n if (!instance.state.meta.isTouched) {\n // Mark them as touched\n instance.setMeta((prev) => ({ ...prev, isTouched: true }))\n }\n })\n })\n })\n\n return Promise.all(fieldValidationPromises)\n }\n\n validateSync = (cause: ValidationCause): void => {\n const { onChange, onBlur } = this.options\n const validate =\n cause === 'change' ? onChange : cause === 'blur' ? onBlur : undefined\n if (!validate) return\n\n const errorMapKey = getErrorMapKey(cause)\n const doValidate = () => {\n if (this.options.validator && typeof validate !== 'function') {\n return (this.options.validator as Validator<TFormData>)().validate(\n this.state.values,\n validate,\n )\n }\n\n return (validate as ValidateFn<TFormData, ValidatorType>)(\n this.state.values,\n this,\n )\n }\n\n const error = normalizeError(doValidate())\n if (this.state.errorMap[errorMapKey] !== error) {\n this.store.setState((prev) => ({\n ...prev,\n errorMap: {\n ...prev.errorMap,\n [errorMapKey]: error,\n },\n }))\n }\n\n if (this.state.errorMap[errorMapKey]) {\n this.cancelValidateAsync()\n }\n }\n\n __leaseValidateAsync = () => {\n const count = (this.validationMeta.validationAsyncCount || 0) + 1\n this.validationMeta.validationAsyncCount = count\n return count\n }\n\n cancelValidateAsync = () => {\n // Lease a new validation count to ignore any pending validations\n this.__leaseValidateAsync()\n // Cancel any pending validation state\n this.store.setState((prev) => ({\n ...prev,\n isFormValidating: false,\n }))\n }\n\n validateAsync = async (\n cause: ValidationCause,\n ): Promise<ValidationError[]> => {\n const {\n onChangeAsync,\n onBlurAsync,\n asyncDebounceMs,\n onBlurAsyncDebounceMs,\n onChangeAsyncDebounceMs,\n } = this.options\n\n const validate =\n cause === 'change'\n ? onChangeAsync\n : cause === 'blur'\n ? onBlurAsync\n : undefined\n\n if (!validate) return []\n const debounceMs =\n (cause === 'change' ? onChangeAsyncDebounceMs : onBlurAsyncDebounceMs) ??\n asyncDebounceMs ??\n 0\n\n if (!this.state.isFormValidating) {\n this.store.setState((prev) => ({ ...prev, isFormValidating: true }))\n }\n\n // Use the validationCount for all field instances to\n // track freshness of the validation\n const validationAsyncCount = this.__leaseValidateAsync()\n\n const checkLatest = () =>\n validationAsyncCount === this.validationMeta.validationAsyncCount\n\n if (!this.validationMeta.validationPromise) {\n this.validationMeta.validationPromise = new Promise((resolve, reject) => {\n this.validationMeta.validationResolve = resolve\n this.validationMeta.validationReject = reject\n })\n }\n\n if (debounceMs > 0) {\n await new Promise((r) => setTimeout(r, debounceMs))\n }\n\n const doValidate = () => {\n if (typeof validate === 'function') {\n return validate(this.state.values, this) as ValidationError\n }\n if (this.options.validator && typeof validate !== 'function') {\n return (this.options.validator as Validator<TFormData>)().validateAsync(\n this.state.values,\n validate,\n )\n }\n const errorMapKey = getErrorMapKey(cause)\n throw new Error(\n `Form validation for ${errorMapKey}Async failed. ${errorMapKey}Async should either be a function, or \\`validator\\` should be correct.`,\n )\n }\n\n // Only kick off validation if this validation is the latest attempt\n if (checkLatest()) {\n const prevErrors = this.state.errors\n try {\n const rawError = await doValidate()\n if (checkLatest()) {\n const error = normalizeError(rawError)\n this.store.setState((prev) => ({\n ...prev,\n isFormValidating: false,\n errorMap: {\n ...prev.errorMap,\n [getErrorMapKey(cause)]: error,\n },\n }))\n this.validationMeta.validationResolve?.([...prevErrors, error])\n }\n } catch (error) {\n if (checkLatest()) {\n this.validationMeta.validationReject?.([...prevErrors, error])\n throw error\n }\n } finally {\n if (checkLatest()) {\n this.store.setState((prev) => ({ ...prev, isFormValidating: false }))\n delete this.validationMeta.validationPromise\n }\n }\n }\n // Always return the latest validation promise to the caller\n return (await this.validationMeta.validationPromise) ?? []\n }\n\n validate = (\n cause: ValidationCause,\n ): ValidationError[] | Promise<ValidationError[]> => {\n // Store the previous error for the errorMapKey (eg. onChange, onBlur, onSubmit)\n const errorMapKey = getErrorMapKey(cause)\n const prevError = this.state.errorMap[errorMapKey]\n\n // Attempt to sync validate first\n this.validateSync(cause)\n\n const newError = this.state.errorMap[errorMapKey]\n if (\n prevError !== newError &&\n !this.options.asyncAlways &&\n !(newError === undefined && prevError !== undefined)\n )\n return this.state.errors\n\n // No error? Attempt async validation\n return this.validateAsync(cause)\n }\n\n handleSubmit = async () => {\n // Check to see that the form and all fields have been touched\n // If they have not, touch them all and run validation\n // Run form validation\n // Submit the form\n\n this.store.setState((old) => ({\n ...old,\n // Submission attempts mark the form as not submitted\n isSubmitted: false,\n // Count submission attempts\n submissionAttempts: old.submissionAttempts + 1,\n }))\n\n // Don't let invalid forms submit\n if (!this.state.canSubmit) return\n\n this.store.setState((d) => ({ ...d, isSubmitting: true }))\n\n const done = () => {\n this.store.setState((prev) => ({ ...prev, isSubmitting: false }))\n }\n\n // Validate all fields\n await this.validateAllFields('submit')\n\n // Fields are invalid, do not submit\n if (!this.state.isFieldsValid) {\n done()\n this.options.onSubmitInvalid?.(this.state.values, this)\n return\n }\n\n // Run validation for the form\n await this.validate('submit')\n\n if (!this.state.isValid) {\n done()\n this.options.onSubmitInvalid?.(this.state.values, this)\n return\n }\n\n try {\n // Run the submit code\n await this.options.onSubmit?.(this.state.values, this)\n\n this.store.batch(() => {\n this.store.setState((prev) => ({ ...prev, isSubmitted: true }))\n done()\n })\n } catch (err) {\n done()\n throw err\n }\n }\n\n getFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): DeepValue<TFormData, TField> => getBy(this.state.values, field)\n\n getFieldMeta = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): FieldMeta | undefined => {\n return this.state.fieldMeta[field]\n }\n\n getFieldInfo = <TField extends DeepKeys<TFormData>>(\n field: TField,\n ): FieldInfo<TFormData, ValidatorType> => {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return (this.fieldInfo[field] ||= {\n instances: {},\n })\n }\n\n setFieldMeta = <TField extends DeepKeys<TFormData>>(\n field: TField,\n updater: Updater<FieldMeta>,\n ) => {\n this.store.setState((prev) => {\n return {\n ...prev,\n fieldMeta: {\n ...prev.fieldMeta,\n [field]: functionalUpdate(updater, prev.fieldMeta[field]),\n },\n }\n })\n }\n\n setFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n updater: Updater<DeepValue<TFormData, TField>>,\n opts?: { touch?: boolean },\n ) => {\n const touch = opts?.touch\n\n this.store.batch(() => {\n if (touch) {\n this.setFieldMeta(field, (prev) => ({\n ...prev,\n isTouched: true,\n }))\n }\n\n this.store.setState((prev) => {\n return {\n ...prev,\n values: setBy(prev.values, field, updater),\n }\n })\n })\n }\n\n deleteField = <TField extends DeepKeys<TFormData>>(field: TField) => {\n this.store.setState((prev) => {\n const newState = { ...prev }\n newState.values = deleteBy(newState.values, field)\n delete newState.fieldMeta[field]\n\n return newState\n })\n }\n\n pushFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: { touch?: boolean },\n ) => {\n return this.setFieldValue(\n field,\n (prev) => [...(Array.isArray(prev) ? prev : []), value] as any,\n opts,\n )\n }\n\n insertFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n value: DeepValue<TFormData, TField> extends any[]\n ? DeepValue<TFormData, TField>[number]\n : never,\n opts?: { touch?: boolean },\n ) => {\n this.setFieldValue(\n field,\n (prev) => {\n return (prev as DeepValue<TFormData, TField>[]).map((d, i) =>\n i === index ? value : d,\n ) as any\n },\n opts,\n )\n }\n\n removeFieldValue = <TField extends DeepKeys<TFormData>>(\n field: TField,\n index: number,\n opts?: { touch?: boolean },\n ) => {\n this.setFieldValue(\n field,\n (prev) => {\n return (prev as DeepValue<TFormData, TField>[]).filter(\n (_d, i) => i !== index,\n ) as any\n },\n opts,\n )\n }\n\n swapFieldValues = <TField extends DeepKeys<TFormData>>(\n field: TField,\n index1: number,\n index2: number,\n ) => {\n this.setFieldValue(field, (prev: any) => {\n const prev1 = prev[index1]!\n const prev2 = prev[index2]!\n return setBy(setBy(prev, `${index1}`, prev2), `${index2}`, prev1)\n })\n }\n}\n\nfunction normalizeError(rawError?: ValidationError) {\n if (rawError) {\n if (typeof rawError !== 'string') {\n return 'Invalid Form Values'\n }\n\n return rawError\n }\n\n return undefined\n}\n\nfunction getErrorMapKey(cause: ValidationCause) {\n switch (cause) {\n case 'submit':\n return 'onSubmit'\n case 'change':\n return 'onChange'\n case 'blur':\n return 'onBlur'\n case 'mount':\n return 'onMount'\n }\n}\n"],"mappings":"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","names":[]}
|