react-f0rm 1.1.1 → 1.2.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/README.md +152 -32
- package/dist/devtools/index.cjs.js +1 -1
- package/dist/devtools/index.cjs.js.map +1 -1
- package/dist/devtools/index.d.ts +2 -2
- package/dist/devtools/index.mjs +1 -1
- package/dist/devtools/index.mjs.map +1 -1
- package/dist/errors-CxSjrWJO.cjs.js +2 -0
- package/dist/errors-CxSjrWJO.cjs.js.map +1 -0
- package/dist/errors-CzWtwjO0.mjs +2 -0
- package/dist/errors-CzWtwjO0.mjs.map +1 -0
- package/dist/form-CvmWHUrd.d.ts +423 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +786 -102
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +796 -354
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +2 -2
- package/dist/index.umd.min.js.map +1 -1
- package/dist/persist.cjs.js +2 -0
- package/dist/persist.cjs.js.map +1 -0
- package/dist/persist.d.ts +49 -0
- package/dist/persist.mjs +2 -0
- package/dist/persist.mjs.map +1 -0
- package/dist/resolvers/standard-schema.cjs.js +1 -1
- package/dist/resolvers/standard-schema.cjs.js.map +1 -1
- package/dist/resolvers/standard-schema.d.ts +7 -5
- package/dist/resolvers/standard-schema.mjs +1 -1
- package/dist/resolvers/standard-schema.mjs.map +1 -1
- package/dist/resolvers/yup.cjs.js +1 -1
- package/dist/resolvers/yup.cjs.js.map +1 -1
- package/dist/resolvers/yup.d.ts +1 -1
- package/dist/resolvers/yup.mjs +1 -1
- package/dist/resolvers/yup.mjs.map +1 -1
- package/dist/resolvers/zod.cjs.js +1 -1
- package/dist/resolvers/zod.cjs.js.map +1 -1
- package/dist/resolvers/zod.d.ts +1 -1
- package/dist/resolvers/zod.mjs +1 -1
- package/dist/resolvers/zod.mjs.map +1 -1
- package/dist/server/index.cjs.js +2 -0
- package/dist/server/index.cjs.js.map +1 -0
- package/dist/server/index.d.ts +77 -0
- package/dist/server/index.mjs +2 -0
- package/dist/server/index.mjs.map +1 -0
- package/dist/validate-B1Gdjeaq.mjs +2 -0
- package/dist/validate-B1Gdjeaq.mjs.map +1 -0
- package/dist/validate-CUmNZqg6.d.ts +238 -0
- package/dist/validate-DAfz8Nbb.cjs.js +2 -0
- package/dist/validate-DAfz8Nbb.cjs.js.map +1 -0
- package/dist/values-B1IV-6V4.mjs +2 -0
- package/dist/values-B1IV-6V4.mjs.map +1 -0
- package/dist/values-CDNAYEOB.cjs.js +2 -0
- package/dist/values-CDNAYEOB.cjs.js.map +1 -0
- package/package.json +71 -24
- package/dist/form-2_tBkEXU.mjs +0 -2
- package/dist/form-2_tBkEXU.mjs.map +0 -1
- package/dist/form-BiDaJLjD.d.ts +0 -826
- package/dist/form-BwLNQ6WB.cjs.js +0 -2
- package/dist/form-BwLNQ6WB.cjs.js.map +0 -1
- package/dist/validate-2XUilILy.d.ts +0 -22
package/dist/index.umd.js
CHANGED
|
@@ -23,6 +23,67 @@
|
|
|
23
23
|
|
|
24
24
|
var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
|
|
25
25
|
|
|
26
|
+
function _arrayLikeToArray(r, a) {
|
|
27
|
+
(null == a || a > r.length) && (a = r.length);
|
|
28
|
+
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
29
|
+
return n;
|
|
30
|
+
}
|
|
31
|
+
function _createForOfIteratorHelper(r, e) {
|
|
32
|
+
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
33
|
+
if (!t) {
|
|
34
|
+
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e) {
|
|
35
|
+
t && (r = t);
|
|
36
|
+
var n = 0,
|
|
37
|
+
F = function () {};
|
|
38
|
+
return {
|
|
39
|
+
s: F,
|
|
40
|
+
n: function () {
|
|
41
|
+
return n >= r.length ? {
|
|
42
|
+
done: true
|
|
43
|
+
} : {
|
|
44
|
+
done: false,
|
|
45
|
+
value: r[n++]
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
e: function (r) {
|
|
49
|
+
throw r;
|
|
50
|
+
},
|
|
51
|
+
f: F
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
55
|
+
}
|
|
56
|
+
var o,
|
|
57
|
+
a = true,
|
|
58
|
+
u = false;
|
|
59
|
+
return {
|
|
60
|
+
s: function () {
|
|
61
|
+
t = t.call(r);
|
|
62
|
+
},
|
|
63
|
+
n: function () {
|
|
64
|
+
var r = t.next();
|
|
65
|
+
return a = r.done, r;
|
|
66
|
+
},
|
|
67
|
+
e: function (r) {
|
|
68
|
+
u = true, o = r;
|
|
69
|
+
},
|
|
70
|
+
f: function () {
|
|
71
|
+
try {
|
|
72
|
+
a || null == t.return || t.return();
|
|
73
|
+
} finally {
|
|
74
|
+
if (u) throw o;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
function _unsupportedIterableToArray(r, a) {
|
|
80
|
+
if (r) {
|
|
81
|
+
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
|
82
|
+
var t = {}.toString.call(r).slice(8, -1);
|
|
83
|
+
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
26
87
|
function getSet(ee, key) {
|
|
27
88
|
var set = ee.get(key);
|
|
28
89
|
if (set) return set;
|
|
@@ -30,20 +91,85 @@
|
|
|
30
91
|
ee.set(key, newSet);
|
|
31
92
|
return newSet;
|
|
32
93
|
}
|
|
94
|
+
|
|
95
|
+
// DEV-only listener-leak warning. Checked via process.env.NODE_ENV because the
|
|
96
|
+
// build pipeline has no compile-time constant injection; the typeof guard
|
|
97
|
+
// keeps direct browser usage of the UMD build safe. In production the whole
|
|
98
|
+
// machinery is skipped and `on` only pays one boolean test.
|
|
99
|
+
var DEV = typeof process !== 'undefined' && process.env && process.env.NODE_ENV !== 'production';
|
|
100
|
+
var DEFAULT_MAX_LISTENERS = 10;
|
|
101
|
+
var maxListenersMap = new WeakMap();
|
|
102
|
+
var warnedKeysMap = new WeakMap();
|
|
103
|
+
function _setMaxListeners(ee, n) {
|
|
104
|
+
maxListenersMap.set(ee, n);
|
|
105
|
+
}
|
|
106
|
+
function checkMaxListeners(ee, key, size) {
|
|
107
|
+
var max = maxListenersMap.get(ee);
|
|
108
|
+
if (max === undefined) max = DEFAULT_MAX_LISTENERS;
|
|
109
|
+
if (max <= 0 || size <= max) return;
|
|
110
|
+
var warnedKeys = warnedKeysMap.get(ee);
|
|
111
|
+
if (!warnedKeys) {
|
|
112
|
+
warnedKeys = new Set();
|
|
113
|
+
warnedKeysMap.set(ee, warnedKeys);
|
|
114
|
+
}
|
|
115
|
+
if (warnedKeys.has(key)) return;
|
|
116
|
+
warnedKeys.add(key);
|
|
117
|
+
// eslint-disable-next-line no-console
|
|
118
|
+
console.warn("Possible event-emitter memory leak: ".concat(size, " \"").concat(String(key), "\" listeners added. ") + "Use setMaxListeners(ee, n) to raise the limit, or 0 to disable this warning.");
|
|
119
|
+
}
|
|
120
|
+
var errorEvent = Symbol('error');
|
|
33
121
|
function create$2() {
|
|
34
122
|
return new Map();
|
|
35
123
|
}
|
|
124
|
+
|
|
125
|
+
// A throwing handler must not stop its peers: errors are collected while the
|
|
126
|
+
// remaining handlers still run, then reported through emitError (the
|
|
127
|
+
// errorEvent channel). If no error handler is subscribed either, the first
|
|
128
|
+
// collected error is rethrown to the emit caller instead of being swallowed.
|
|
129
|
+
// Iteration follows Set semantics: a listener added while this emit runs is
|
|
130
|
+
// still visited by that same emit, and a listener removed before it is
|
|
131
|
+
// visited is skipped. Removing a whole key (off/removeAllListeners) does not
|
|
132
|
+
// affect an emit already in flight.
|
|
36
133
|
function emit(ee, key) {
|
|
37
134
|
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
|
38
135
|
args[_key - 2] = arguments[_key];
|
|
39
136
|
}
|
|
40
|
-
|
|
41
|
-
|
|
137
|
+
var set = ee.get(key);
|
|
138
|
+
if (!set || !set.size) return;
|
|
139
|
+
var errors;
|
|
140
|
+
set.forEach(function (h) {
|
|
141
|
+
try {
|
|
142
|
+
h.apply(void 0, args);
|
|
143
|
+
} catch (err) {
|
|
144
|
+
if (errors) errors.push(err);else errors = [err];
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
if (errors) {
|
|
148
|
+
var _iterator = _createForOfIteratorHelper(errors),
|
|
149
|
+
_step;
|
|
150
|
+
try {
|
|
151
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
152
|
+
var err = _step.value;
|
|
153
|
+
emitError(ee, err);
|
|
154
|
+
}
|
|
155
|
+
} catch (err) {
|
|
156
|
+
_iterator.e(err);
|
|
157
|
+
} finally {
|
|
158
|
+
_iterator.f();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function emitError(ee, err) {
|
|
163
|
+
var handlerSet = ee.get(errorEvent);
|
|
164
|
+
if (!handlerSet || !handlerSet.size) throw err;
|
|
165
|
+
handlerSet.forEach(function (h) {
|
|
166
|
+
return h(err);
|
|
42
167
|
});
|
|
43
168
|
}
|
|
44
169
|
function on(ee, key, handler) {
|
|
45
170
|
var set = getSet(ee, key);
|
|
46
171
|
set.add(handler);
|
|
172
|
+
if (DEV) checkMaxListeners(ee, key, set.size);
|
|
47
173
|
return function () {
|
|
48
174
|
return set.delete(handler);
|
|
49
175
|
};
|
|
@@ -230,110 +356,59 @@
|
|
|
230
356
|
return { value, key: JSON.stringify(value) };
|
|
231
357
|
}
|
|
232
358
|
|
|
233
|
-
const VALIDATION_OUTCOME = /* @__PURE__ */ Symbol("validation-outcome");
|
|
234
|
-
function create(options) {
|
|
235
|
-
const emitter = create$2();
|
|
236
|
-
return {
|
|
237
|
-
emitter,
|
|
238
|
-
...options,
|
|
239
|
-
mode: options?.mode ?? "onSubmit",
|
|
240
|
-
reValidateMode: options?.reValidateMode ?? "onChange",
|
|
241
|
-
disabled: options?.disabled ?? false,
|
|
242
|
-
validateDeps: options?.validateDeps ? new Set(options.validateDeps.map((dep) => create$1(dep).key)) : void 0,
|
|
243
|
-
initialValues: options?.initialValues ?? {},
|
|
244
|
-
values: /* @__PURE__ */ new Map(),
|
|
245
|
-
deleted: /* @__PURE__ */ new Set(),
|
|
246
|
-
errors: /* @__PURE__ */ new Map(),
|
|
247
|
-
touched: /* @__PURE__ */ new Set(),
|
|
248
|
-
validators: /* @__PURE__ */ new Map(),
|
|
249
|
-
changeHandlers: /* @__PURE__ */ new Map(),
|
|
250
|
-
validating: /* @__PURE__ */ new Set(),
|
|
251
|
-
parsedValues: void 0,
|
|
252
|
-
isSubmitting: false,
|
|
253
|
-
submitCount: 0,
|
|
254
|
-
isSubmitSuccessful: void 0
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
359
|
const valuesCaches = /* @__PURE__ */ new WeakMap();
|
|
258
360
|
function bumpValuesVersion(form) {
|
|
259
361
|
const cache = valuesCaches.get(form);
|
|
260
362
|
if (cache) cache.version++;
|
|
261
363
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
} else if (cache.version > 0) {
|
|
268
|
-
cache.result = computeValues(form);
|
|
269
|
-
cache.version = 0;
|
|
270
|
-
}
|
|
271
|
-
return cache.result;
|
|
364
|
+
const dirtyBaselines = /* @__PURE__ */ new WeakMap();
|
|
365
|
+
function getDirtyBaseline(form, key, segments) {
|
|
366
|
+
const baselines = dirtyBaselines.get(form);
|
|
367
|
+
if (baselines?.has(key)) return baselines.get(key);
|
|
368
|
+
return get(form.initialValues, segments);
|
|
272
369
|
}
|
|
273
|
-
function
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
merged = setOwned(merged, JSON.parse(key), value, owned);
|
|
279
|
-
}
|
|
280
|
-
for (const key of deleted) {
|
|
281
|
-
merged = unset(merged, JSON.parse(key));
|
|
370
|
+
function setDirtyBaseline(form, { key }, value) {
|
|
371
|
+
let baselines = dirtyBaselines.get(form);
|
|
372
|
+
if (!baselines) {
|
|
373
|
+
baselines = /* @__PURE__ */ new Map();
|
|
374
|
+
dirtyBaselines.set(form, baselines);
|
|
282
375
|
}
|
|
283
|
-
|
|
284
|
-
}
|
|
285
|
-
function getValue(form, name) {
|
|
286
|
-
return getValueByPath(form, create$1(name));
|
|
376
|
+
baselines.set(key, value);
|
|
287
377
|
}
|
|
288
|
-
function
|
|
289
|
-
const
|
|
290
|
-
if (
|
|
291
|
-
|
|
292
|
-
for (
|
|
293
|
-
|
|
294
|
-
if (values.has(ancestorKey)) {
|
|
295
|
-
return get(values.get(ancestorKey), segments.slice(i));
|
|
296
|
-
}
|
|
378
|
+
function pruneDirtyBaselines(form, { key }) {
|
|
379
|
+
const baselines = dirtyBaselines.get(form);
|
|
380
|
+
if (!baselines?.size) return;
|
|
381
|
+
const stem = `${key.slice(0, -1)},`;
|
|
382
|
+
for (const baselineKey of baselines.keys()) {
|
|
383
|
+
if (baselineKey.startsWith(stem)) baselines.delete(baselineKey);
|
|
297
384
|
}
|
|
298
|
-
return get(parsedValues ?? initialValues, segments);
|
|
299
385
|
}
|
|
300
|
-
function
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
values.set(path.key, value);
|
|
306
|
-
pruneDescendantKeys(values, path);
|
|
307
|
-
reviveBranch(deleted, path);
|
|
308
|
-
pruneDirtyBaselines(form, path);
|
|
309
|
-
if (options?.shouldDirty === false) setDirtyBaseline(form, path, value);
|
|
310
|
-
bumpDirtyVersion(form);
|
|
311
|
-
bumpValuesVersion(form);
|
|
312
|
-
if (options?.shouldTouch) setTouchedByPath(form, path);
|
|
313
|
-
if (options?.shouldValidate) form.validators.get(path.key)?.();
|
|
314
|
-
emit(emitter, "change", path);
|
|
386
|
+
function clearDirtyBaselines(form, key) {
|
|
387
|
+
const baselines = dirtyBaselines.get(form);
|
|
388
|
+
if (!baselines) return;
|
|
389
|
+
if (key === void 0) baselines.clear();
|
|
390
|
+
else baselines.delete(key);
|
|
315
391
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
reviveBranch(deleted, path);
|
|
321
|
-
pruneDirtyBaselines(form, path);
|
|
322
|
-
bumpDirtyVersion(form);
|
|
323
|
-
bumpValuesVersion(form);
|
|
392
|
+
const dirtyFieldsCaches = /* @__PURE__ */ new WeakMap();
|
|
393
|
+
function bumpDirtyVersion(form) {
|
|
394
|
+
const cache = dirtyFieldsCaches.get(form);
|
|
395
|
+
if (cache) cache.version++;
|
|
324
396
|
}
|
|
325
|
-
function
|
|
326
|
-
|
|
397
|
+
function isSegmentsPath(name) {
|
|
398
|
+
return name.some((part) => typeof part === "number");
|
|
327
399
|
}
|
|
328
|
-
function
|
|
329
|
-
|
|
400
|
+
function isFieldError(value) {
|
|
401
|
+
return !!value && typeof value === "object" && typeof value.type === "string" && typeof value.message === "string";
|
|
330
402
|
}
|
|
331
|
-
function
|
|
332
|
-
if (
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
403
|
+
function setParsedValues(form, values) {
|
|
404
|
+
if (values === void 0 || values === form.parsedValues) return;
|
|
405
|
+
form.parsedValues = values;
|
|
406
|
+
bumpValuesVersion(form);
|
|
407
|
+
emit(form.emitter, "change");
|
|
336
408
|
}
|
|
409
|
+
|
|
410
|
+
const FORM_ERROR = "_form";
|
|
411
|
+
const VALIDATION_OUTCOME = /* @__PURE__ */ Symbol("validation-outcome");
|
|
337
412
|
function getError(form, name) {
|
|
338
413
|
return getErrorByPath(form, create$1(name));
|
|
339
414
|
}
|
|
@@ -358,29 +433,6 @@
|
|
|
358
433
|
function getFirstError({ errors }) {
|
|
359
434
|
return errors.values().next().value?.[0]?.message;
|
|
360
435
|
}
|
|
361
|
-
function getFieldState(form, name) {
|
|
362
|
-
const path = create$1(name);
|
|
363
|
-
const { values, touched, validating } = form;
|
|
364
|
-
const live = values.get(path.key);
|
|
365
|
-
return {
|
|
366
|
-
value: getValueByPath(form, path),
|
|
367
|
-
error: getErrorByPath(form, path),
|
|
368
|
-
errors: getFieldErrorsByPath(form, path),
|
|
369
|
-
// Same rule as getDirtyFields, committed baselines included: the field
|
|
370
|
-
// is dirty while its live value differs from its effective baseline.
|
|
371
|
-
isDirty: values.has(path.key) && getDirtyBaseline(form, path.key, path.value) !== live,
|
|
372
|
-
isTouched: touched.has(path.key),
|
|
373
|
-
isValidating: validating.has(path.key)
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
function unsetValidatingByPath({ emitter, validating }, path) {
|
|
377
|
-
validating.delete(path.key);
|
|
378
|
-
emit(emitter, "validating", path);
|
|
379
|
-
}
|
|
380
|
-
function setValidatingByPath({ emitter, validating }, path) {
|
|
381
|
-
validating.add(path.key);
|
|
382
|
-
emit(emitter, "validating", path);
|
|
383
|
-
}
|
|
384
436
|
function setError(form, name, error) {
|
|
385
437
|
setErrorByPath(form, create$1(name), error);
|
|
386
438
|
}
|
|
@@ -430,6 +482,10 @@
|
|
|
430
482
|
);
|
|
431
483
|
}
|
|
432
484
|
}
|
|
485
|
+
function hasErrors({ errors }) {
|
|
486
|
+
return errors.size > 0;
|
|
487
|
+
}
|
|
488
|
+
|
|
433
489
|
function setTouched(form, name) {
|
|
434
490
|
setTouchedByPath(form, create$1(name));
|
|
435
491
|
}
|
|
@@ -444,97 +500,111 @@
|
|
|
444
500
|
function hasTouchedByPath({ touched }, path) {
|
|
445
501
|
return touched.has(path.key);
|
|
446
502
|
}
|
|
447
|
-
function
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
return dirty;
|
|
453
|
-
}
|
|
454
|
-
function forEachDirtyField(form, fn) {
|
|
455
|
-
for (const [key, value] of form.values) {
|
|
456
|
-
const path = JSON.parse(key);
|
|
457
|
-
if (getDirtyBaseline(form, key, path) !== value) fn(path.join("."));
|
|
458
|
-
}
|
|
503
|
+
function getTouchedFields({ touched }) {
|
|
504
|
+
return Array.from(
|
|
505
|
+
touched,
|
|
506
|
+
(key) => JSON.parse(key).join(".")
|
|
507
|
+
);
|
|
459
508
|
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
const baselines = dirtyBaselines.get(form);
|
|
463
|
-
if (baselines?.has(key)) return baselines.get(key);
|
|
464
|
-
return get(form.initialValues, segments);
|
|
509
|
+
function isTouched({ touched }) {
|
|
510
|
+
return touched.size > 0;
|
|
465
511
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
512
|
+
|
|
513
|
+
function getValues(form) {
|
|
514
|
+
let cache = valuesCaches.get(form);
|
|
515
|
+
if (!cache) {
|
|
516
|
+
cache = { version: 0, result: computeValues(form) };
|
|
517
|
+
valuesCaches.set(form, cache);
|
|
518
|
+
} else if (cache.version > 0) {
|
|
519
|
+
cache.result = computeValues(form);
|
|
520
|
+
cache.version = 0;
|
|
471
521
|
}
|
|
472
|
-
|
|
522
|
+
return cache.result;
|
|
473
523
|
}
|
|
474
|
-
function
|
|
475
|
-
const
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
for (const
|
|
479
|
-
|
|
524
|
+
function computeValues(form) {
|
|
525
|
+
const { initialValues, parsedValues, values, deleted } = form;
|
|
526
|
+
const owned = /* @__PURE__ */ new Set();
|
|
527
|
+
let merged = parsedValues ?? initialValues;
|
|
528
|
+
for (const [key, value] of values) {
|
|
529
|
+
merged = setOwned(merged, JSON.parse(key), value, owned);
|
|
480
530
|
}
|
|
531
|
+
for (const key of deleted) {
|
|
532
|
+
merged = unset(merged, JSON.parse(key));
|
|
533
|
+
}
|
|
534
|
+
return merged;
|
|
481
535
|
}
|
|
482
|
-
function
|
|
483
|
-
|
|
484
|
-
if (!baselines) return;
|
|
485
|
-
if (key === void 0) baselines.clear();
|
|
486
|
-
else baselines.delete(key);
|
|
536
|
+
function getValue(form, name) {
|
|
537
|
+
return getValueByPath(form, create$1(name));
|
|
487
538
|
}
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
if (
|
|
539
|
+
function getValueByPath({ initialValues, parsedValues, values, deleted }, path) {
|
|
540
|
+
const { key, value: segments } = path;
|
|
541
|
+
if (values.has(key)) return values.get(key);
|
|
542
|
+
if (deleted.has(key)) return void 0;
|
|
543
|
+
for (let i = segments.length - 1; i > 0; i--) {
|
|
544
|
+
const ancestorKey = JSON.stringify(segments.slice(0, i));
|
|
545
|
+
if (values.has(ancestorKey)) {
|
|
546
|
+
return get(values.get(ancestorKey), segments.slice(i));
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
return get(parsedValues ?? initialValues, segments);
|
|
492
550
|
}
|
|
493
|
-
function
|
|
494
|
-
|
|
495
|
-
forEachDirtyField(form, (key) => {
|
|
496
|
-
dirtyFields[key] = true;
|
|
497
|
-
});
|
|
498
|
-
return dirtyFields;
|
|
551
|
+
function setValue(form, name, value, options) {
|
|
552
|
+
setValueByPath(form, create$1(name), value, options);
|
|
499
553
|
}
|
|
500
|
-
function
|
|
501
|
-
const
|
|
502
|
-
|
|
503
|
-
|
|
554
|
+
function setValueByPath(form, path, value, options) {
|
|
555
|
+
const { emitter, values, deleted } = form;
|
|
556
|
+
values.set(path.key, value);
|
|
557
|
+
pruneDescendantKeys(values, path);
|
|
558
|
+
reviveBranch(deleted, path);
|
|
559
|
+
pruneDirtyBaselines(form, path);
|
|
560
|
+
if (options?.shouldDirty === false) setDirtyBaseline(form, path, value);
|
|
561
|
+
bumpDirtyVersion(form);
|
|
562
|
+
bumpValuesVersion(form);
|
|
563
|
+
if (options?.shouldTouch) setTouchedByPath(form, path);
|
|
564
|
+
if (options?.shouldValidate) form.validators.get(path.key)?.();
|
|
565
|
+
emit(emitter, "change", path);
|
|
504
566
|
}
|
|
505
|
-
function
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
cache.version = 0;
|
|
514
|
-
}
|
|
515
|
-
return cache.result;
|
|
567
|
+
function seedValueByPath(form, path, value) {
|
|
568
|
+
const { values, deleted } = form;
|
|
569
|
+
values.set(path.key, value);
|
|
570
|
+
pruneDescendantKeys(values, path);
|
|
571
|
+
reviveBranch(deleted, path);
|
|
572
|
+
pruneDirtyBaselines(form, path);
|
|
573
|
+
bumpDirtyVersion(form);
|
|
574
|
+
bumpValuesVersion(form);
|
|
516
575
|
}
|
|
517
|
-
function
|
|
518
|
-
|
|
519
|
-
touched,
|
|
520
|
-
(key) => JSON.parse(key).join(".")
|
|
521
|
-
);
|
|
576
|
+
function emitChangeByPath({ emitter }, path) {
|
|
577
|
+
emit(emitter, "change", path);
|
|
522
578
|
}
|
|
523
|
-
function
|
|
524
|
-
|
|
579
|
+
function getFieldState(form, name) {
|
|
580
|
+
const path = create$1(name);
|
|
581
|
+
const { values, touched, validating } = form;
|
|
582
|
+
const live = values.get(path.key);
|
|
583
|
+
return {
|
|
584
|
+
value: getValueByPath(form, path),
|
|
585
|
+
error: getErrorByPath(form, path),
|
|
586
|
+
errors: getFieldErrorsByPath(form, path),
|
|
587
|
+
// Same rule as getDirtyFields, committed baselines included: the field
|
|
588
|
+
// is dirty while its live value differs from its effective baseline.
|
|
589
|
+
isDirty: values.has(path.key) && getDirtyBaseline(form, path.key, path.value) !== live,
|
|
590
|
+
isTouched: touched.has(path.key),
|
|
591
|
+
isValidating: validating.has(path.key)
|
|
592
|
+
};
|
|
525
593
|
}
|
|
526
|
-
function removeField(form, name) {
|
|
527
|
-
removeFieldByPath(form, create$1(name));
|
|
594
|
+
function removeField(form, name, options) {
|
|
595
|
+
removeFieldByPath(form, create$1(name), options);
|
|
528
596
|
}
|
|
529
|
-
function removeFieldByPath(form, path) {
|
|
597
|
+
function removeFieldByPath(form, path, options) {
|
|
530
598
|
const { key, value: segments } = path;
|
|
531
599
|
const { emitter, values, touched, errors, validating, deleted } = form;
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
600
|
+
if (!options?.keepValue && !options?.keepDirty) {
|
|
601
|
+
values.delete(key);
|
|
602
|
+
clearDirtyBaselines(form, key);
|
|
603
|
+
if (!hasLiveBranch(values, segments)) deleted.add(key);
|
|
604
|
+
}
|
|
605
|
+
if (!options?.keepTouched) touched.delete(key);
|
|
606
|
+
if (!options?.keepError) errors.delete(key);
|
|
535
607
|
validating.delete(key);
|
|
536
|
-
clearDirtyBaselines(form, key);
|
|
537
|
-
if (!hasLiveBranch(values, segments)) deleted.add(key);
|
|
538
608
|
bumpDirtyVersion(form);
|
|
539
609
|
bumpValuesVersion(form);
|
|
540
610
|
emit(emitter, "change", path);
|
|
@@ -580,17 +650,37 @@
|
|
|
580
650
|
bumpValuesVersion(form);
|
|
581
651
|
emit(form.emitter, "change");
|
|
582
652
|
}
|
|
653
|
+
function collectValueLeaves(node, segments, out) {
|
|
654
|
+
if (node !== null && typeof node === "object") {
|
|
655
|
+
if (Array.isArray(node)) {
|
|
656
|
+
for (let i = 0; i < node.length; i++) {
|
|
657
|
+
collectValueLeaves(node[i], [...segments, i], out);
|
|
658
|
+
}
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
const keys = Object.keys(node);
|
|
662
|
+
if (keys.length > 0) {
|
|
663
|
+
for (const k of keys) {
|
|
664
|
+
collectValueLeaves(node[k], [...segments, k], out);
|
|
665
|
+
}
|
|
666
|
+
return;
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
out.push({ segments, value: node });
|
|
670
|
+
}
|
|
583
671
|
function reset(form, initialValues, options) {
|
|
584
|
-
const
|
|
585
|
-
if (options?.
|
|
672
|
+
const keptValues = [];
|
|
673
|
+
if (options?.keepValues) {
|
|
674
|
+
collectValueLeaves(getValues(form), [], keptValues);
|
|
675
|
+
} else if (options?.keepDirtyValues) {
|
|
586
676
|
for (const [key, value] of form.values) {
|
|
587
677
|
const segments = JSON.parse(key);
|
|
588
678
|
if (getDirtyBaseline(form, key, segments) !== value) {
|
|
589
|
-
|
|
679
|
+
keptValues.push({ segments, value });
|
|
590
680
|
}
|
|
591
681
|
}
|
|
592
682
|
}
|
|
593
|
-
form.initialValues = initialValues;
|
|
683
|
+
form.initialValues = options?.keepDefaultValues ? form.initialValues : initialValues ?? form.initialValues;
|
|
594
684
|
form.parsedValues = void 0;
|
|
595
685
|
if (!options?.keepErrors) clearErrors(form);
|
|
596
686
|
const { emitter, touched, values, deleted, validating } = form;
|
|
@@ -604,7 +694,7 @@
|
|
|
604
694
|
if (!options?.keepIsSubmitted) form.isSubmitSuccessful = void 0;
|
|
605
695
|
bumpDirtyVersion(form);
|
|
606
696
|
bumpValuesVersion(form);
|
|
607
|
-
for (const { segments, value } of
|
|
697
|
+
for (const { segments, value } of keptValues) {
|
|
608
698
|
setValueByPath(form, create$1(segments), value);
|
|
609
699
|
}
|
|
610
700
|
emit(emitter, "change");
|
|
@@ -639,10 +729,172 @@
|
|
|
639
729
|
bumpDirtyVersion(form);
|
|
640
730
|
bumpValuesVersion(form);
|
|
641
731
|
}
|
|
642
|
-
|
|
643
|
-
|
|
732
|
+
|
|
733
|
+
function isDirty(form) {
|
|
734
|
+
let dirty = false;
|
|
735
|
+
forEachDirtyField(form, () => {
|
|
736
|
+
dirty = true;
|
|
737
|
+
});
|
|
738
|
+
return dirty;
|
|
739
|
+
}
|
|
740
|
+
function forEachDirtyField(form, fn) {
|
|
741
|
+
for (const [key, value] of form.values) {
|
|
742
|
+
const path = JSON.parse(key);
|
|
743
|
+
if (getDirtyBaseline(form, key, path) !== value) fn(path.join("."));
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
function computeDirtyFields(form) {
|
|
747
|
+
const dirtyFields = {};
|
|
748
|
+
forEachDirtyField(form, (key) => {
|
|
749
|
+
dirtyFields[key] = true;
|
|
750
|
+
});
|
|
751
|
+
return dirtyFields;
|
|
752
|
+
}
|
|
753
|
+
function sameDirtyKeys(a, b) {
|
|
754
|
+
const aKeys = Object.keys(a);
|
|
755
|
+
if (aKeys.length !== Object.keys(b).length) return false;
|
|
756
|
+
return aKeys.every((key) => b[key] === true);
|
|
757
|
+
}
|
|
758
|
+
function getDirtyFields(form) {
|
|
759
|
+
let cache = dirtyFieldsCaches.get(form);
|
|
760
|
+
if (!cache) {
|
|
761
|
+
cache = { version: 0, result: computeDirtyFields(form) };
|
|
762
|
+
dirtyFieldsCaches.set(form, cache);
|
|
763
|
+
} else if (cache.version > 0) {
|
|
764
|
+
const result = computeDirtyFields(form);
|
|
765
|
+
if (!sameDirtyKeys(cache.result, result)) cache.result = result;
|
|
766
|
+
cache.version = 0;
|
|
767
|
+
}
|
|
768
|
+
return cache.result;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
function unsetValidatingByPath({ emitter, validating }, path) {
|
|
772
|
+
validating.delete(path.key);
|
|
773
|
+
emit(emitter, "validating", path);
|
|
774
|
+
}
|
|
775
|
+
function setValidatingByPath({ emitter, validating }, path) {
|
|
776
|
+
validating.add(path.key);
|
|
777
|
+
emit(emitter, "validating", path);
|
|
778
|
+
}
|
|
779
|
+
function registerValidatorByPath(form, path, registration) {
|
|
780
|
+
let timer = null;
|
|
781
|
+
let controller = null;
|
|
782
|
+
let marked = false;
|
|
783
|
+
let lock = null;
|
|
784
|
+
let errorSource = null;
|
|
785
|
+
const hasErrors2 = (errors) => errors !== void 0 && !(Array.isArray(errors) && errors.length === 0);
|
|
786
|
+
const mark = () => {
|
|
787
|
+
if (marked) return;
|
|
788
|
+
marked = true;
|
|
789
|
+
setValidatingByPath(form, path);
|
|
790
|
+
};
|
|
791
|
+
const unmark = () => {
|
|
792
|
+
if (!marked) return;
|
|
793
|
+
marked = false;
|
|
794
|
+
unsetValidatingByPath(form, path);
|
|
795
|
+
};
|
|
796
|
+
const runSync = () => {
|
|
797
|
+
const sync = registration.sync();
|
|
798
|
+
if (!sync) return false;
|
|
799
|
+
const errors = sync(getValueByPath(form, path), { form, path });
|
|
800
|
+
if (!hasErrors2(errors)) {
|
|
801
|
+
if (!registration.validate() || errorSource === "sync") {
|
|
802
|
+
setErrorByPath(form, path, void 0);
|
|
803
|
+
errorSource = null;
|
|
804
|
+
}
|
|
805
|
+
return false;
|
|
806
|
+
}
|
|
807
|
+
setErrorByPath(form, path, errors);
|
|
808
|
+
errorSource = "sync";
|
|
809
|
+
return true;
|
|
810
|
+
};
|
|
811
|
+
const supersede = () => {
|
|
812
|
+
if (timer !== null) {
|
|
813
|
+
clearTimeout(timer);
|
|
814
|
+
timer = null;
|
|
815
|
+
}
|
|
816
|
+
controller?.abort();
|
|
817
|
+
lock = {};
|
|
818
|
+
};
|
|
819
|
+
const runValidator = () => {
|
|
820
|
+
const fn = registration.validate();
|
|
821
|
+
if (!fn) {
|
|
822
|
+
unmark();
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
controller?.abort();
|
|
826
|
+
controller = new AbortController();
|
|
827
|
+
const round = lock = {};
|
|
828
|
+
let result;
|
|
829
|
+
try {
|
|
830
|
+
result = fn(getValueByPath(form, path), {
|
|
831
|
+
form,
|
|
832
|
+
path,
|
|
833
|
+
signal: controller.signal
|
|
834
|
+
});
|
|
835
|
+
} catch (e) {
|
|
836
|
+
unmark();
|
|
837
|
+
throw e;
|
|
838
|
+
}
|
|
839
|
+
if (!isPromise(result)) {
|
|
840
|
+
setErrorByPath(form, path, result);
|
|
841
|
+
errorSource = hasErrors2(result) ? "validator" : null;
|
|
842
|
+
unmark();
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
mark();
|
|
846
|
+
result.then(
|
|
847
|
+
(error) => {
|
|
848
|
+
if (lock === round) {
|
|
849
|
+
setErrorByPath(form, path, error);
|
|
850
|
+
errorSource = hasErrors2(error) ? "validator" : null;
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
).catch(() => {
|
|
854
|
+
}).finally(() => {
|
|
855
|
+
if (lock === round) {
|
|
856
|
+
unmark();
|
|
857
|
+
lock = null;
|
|
858
|
+
}
|
|
859
|
+
});
|
|
860
|
+
};
|
|
861
|
+
const run = () => {
|
|
862
|
+
timer = null;
|
|
863
|
+
if (runSync()) {
|
|
864
|
+
supersede();
|
|
865
|
+
unmark();
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
runValidator();
|
|
869
|
+
};
|
|
870
|
+
const kick = () => {
|
|
871
|
+
if (runSync()) {
|
|
872
|
+
supersede();
|
|
873
|
+
unmark();
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
if (!registration.validate()) return;
|
|
877
|
+
const debounce = registration.debounce();
|
|
878
|
+
if (debounce > 0) {
|
|
879
|
+
if (timer !== null) clearTimeout(timer);
|
|
880
|
+
else mark();
|
|
881
|
+
timer = setTimeout(run, debounce);
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
884
|
+
runValidator();
|
|
885
|
+
};
|
|
886
|
+
form.validators.set(path.key, kick);
|
|
887
|
+
return () => {
|
|
888
|
+
form.validators.delete(path.key);
|
|
889
|
+
if (timer !== null) {
|
|
890
|
+
clearTimeout(timer);
|
|
891
|
+
timer = null;
|
|
892
|
+
}
|
|
893
|
+
unmark();
|
|
894
|
+
controller?.abort();
|
|
895
|
+
};
|
|
644
896
|
}
|
|
645
|
-
async function trigger(form, name) {
|
|
897
|
+
async function trigger(form, name, options) {
|
|
646
898
|
const settle = (keys2) => waitUntil(
|
|
647
899
|
form.emitter,
|
|
648
900
|
"validating",
|
|
@@ -653,18 +905,25 @@
|
|
|
653
905
|
form.validators.forEach((validator) => validator());
|
|
654
906
|
await settle();
|
|
655
907
|
if (form.validate) await runFormValidate(form);
|
|
908
|
+
if (options?.shouldTouch) touchKeys(form, [...form.validators.keys()]);
|
|
909
|
+
if (options?.shouldFocus) {
|
|
910
|
+
const firstKey = form.errors.keys().next().value;
|
|
911
|
+
if (firstKey !== void 0) emit(form.emitter, "focusError", firstKey);
|
|
912
|
+
}
|
|
656
913
|
return !hasErrors(form);
|
|
657
914
|
}
|
|
658
915
|
const keys = typeof name === "string" || isSegmentsPath(name) ? [create$1(name).key] : name.map((one) => create$1(one).key);
|
|
659
916
|
keys.forEach((key) => form.validators.get(key)?.());
|
|
660
917
|
await settle(keys);
|
|
918
|
+
if (options?.shouldTouch) touchKeys(form, keys);
|
|
919
|
+
if (options?.shouldFocus) {
|
|
920
|
+
const firstKey = keys.find((key) => form.errors.has(key));
|
|
921
|
+
if (firstKey !== void 0) emit(form.emitter, "focusError", firstKey);
|
|
922
|
+
}
|
|
661
923
|
return keys.every((key) => !form.errors.has(key));
|
|
662
924
|
}
|
|
663
|
-
function
|
|
664
|
-
|
|
665
|
-
}
|
|
666
|
-
function isFieldError(value) {
|
|
667
|
-
return !!value && typeof value === "object" && typeof value.type === "string" && typeof value.message === "string";
|
|
925
|
+
function touchKeys(form, keys) {
|
|
926
|
+
keys.forEach((key) => setTouchedByPath(form, create$1(JSON.parse(key))));
|
|
668
927
|
}
|
|
669
928
|
function setFormErrors(form, result, segments = [], footprint) {
|
|
670
929
|
Object.entries(result).forEach(([key, value]) => {
|
|
@@ -694,12 +953,6 @@
|
|
|
694
953
|
const stored = form.errors.get(path.key);
|
|
695
954
|
if (stored) footprint.set(path.key, stored);
|
|
696
955
|
}
|
|
697
|
-
function setParsedValues(form, values) {
|
|
698
|
-
if (values === void 0 || values === form.parsedValues) return;
|
|
699
|
-
form.parsedValues = values;
|
|
700
|
-
bumpValuesVersion(form);
|
|
701
|
-
emit(form.emitter, "change");
|
|
702
|
-
}
|
|
703
956
|
function applyValidateResult(form, result) {
|
|
704
957
|
const footprint = form.validateDeps ? getFormErrorFootprint(form) : void 0;
|
|
705
958
|
if (footprint) {
|
|
@@ -897,6 +1150,55 @@
|
|
|
897
1150
|
async function validate(form) {
|
|
898
1151
|
return ensureValidate(form).catch((e) => e.message);
|
|
899
1152
|
}
|
|
1153
|
+
|
|
1154
|
+
const fieldModes = /* @__PURE__ */ new WeakMap();
|
|
1155
|
+
function changeValue(form, name, value, options) {
|
|
1156
|
+
changeValueByPath(form, create$1(name), value, options);
|
|
1157
|
+
}
|
|
1158
|
+
function changeValueByPath(form, path, value, options) {
|
|
1159
|
+
if (options?.shouldDirty === false) setDirtyBaseline(form, path, value);
|
|
1160
|
+
if (fieldModes.get(form)?.get(path.key)) {
|
|
1161
|
+
userChangeByPath(form, path, value);
|
|
1162
|
+
} else {
|
|
1163
|
+
setValueByPath(form, path, value, options);
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
function registerFieldMode(form, path, mode) {
|
|
1167
|
+
let modes = fieldModes.get(form);
|
|
1168
|
+
if (!modes) {
|
|
1169
|
+
modes = /* @__PURE__ */ new Map();
|
|
1170
|
+
fieldModes.set(form, modes);
|
|
1171
|
+
}
|
|
1172
|
+
const displaced = modes.has(path.key);
|
|
1173
|
+
const token = {};
|
|
1174
|
+
modes.set(path.key, { mode, token });
|
|
1175
|
+
return { token, displaced };
|
|
1176
|
+
}
|
|
1177
|
+
function unregisterFieldMode(form, path, token) {
|
|
1178
|
+
const modes = fieldModes.get(form);
|
|
1179
|
+
const entry = modes?.get(path.key);
|
|
1180
|
+
if (modes && entry && entry.token === token) modes.delete(path.key);
|
|
1181
|
+
}
|
|
1182
|
+
function runUserChangeGate(form, path, mode) {
|
|
1183
|
+
if (mode === "onChange" || mode === "all" || mode === "onTouched" && hasTouchedByPath(form, path) || getFieldErrorsByPath(form, path).length > 0 && form.reValidateMode === "onChange")
|
|
1184
|
+
form.validators.get(path.key)?.();
|
|
1185
|
+
revalidateFormOnChange(form, path, mode);
|
|
1186
|
+
revalidateDependentsOnChange(form, path, mode);
|
|
1187
|
+
}
|
|
1188
|
+
function userChangeByPath(form, path, value) {
|
|
1189
|
+
setValueByPath(form, path, value);
|
|
1190
|
+
const entry = fieldModes.get(form)?.get(path.key);
|
|
1191
|
+
if (entry) runUserChangeGate(form, path, entry.mode ?? form.mode);
|
|
1192
|
+
}
|
|
1193
|
+
function userBlur(form, path) {
|
|
1194
|
+
setTouchedByPath(form, path);
|
|
1195
|
+
const entry = fieldModes.get(form)?.get(path.key);
|
|
1196
|
+
if (!entry) return;
|
|
1197
|
+
const mode = entry.mode ?? form.mode;
|
|
1198
|
+
if (mode === "onBlur" || mode === "onTouched" || mode === "all" || getFieldErrorsByPath(form, path).length > 0 && form.reValidateMode === "onBlur")
|
|
1199
|
+
form.validators.get(path.key)?.();
|
|
1200
|
+
}
|
|
1201
|
+
|
|
900
1202
|
function setIsSubmitting(form, value) {
|
|
901
1203
|
form.isSubmitting = value;
|
|
902
1204
|
emit(form.emitter, "submitting");
|
|
@@ -943,6 +1245,7 @@
|
|
|
943
1245
|
onSubmit,
|
|
944
1246
|
onValidSubmit,
|
|
945
1247
|
onInvalidSubmit,
|
|
1248
|
+
onAction,
|
|
946
1249
|
shouldFocusError = true
|
|
947
1250
|
} = options ?? {};
|
|
948
1251
|
return async (e) => {
|
|
@@ -979,6 +1282,7 @@
|
|
|
979
1282
|
const submitted = getValues(form);
|
|
980
1283
|
if (onSubmit) await onSubmit(submitted, e);
|
|
981
1284
|
if (onValidSubmit) await onValidSubmit(submitted, e);
|
|
1285
|
+
if (onAction) await onAction(submitted, e);
|
|
982
1286
|
setSubmitSuccessful(form, true);
|
|
983
1287
|
} catch {
|
|
984
1288
|
setSubmitSuccessful(form, false);
|
|
@@ -987,12 +1291,58 @@
|
|
|
987
1291
|
}
|
|
988
1292
|
};
|
|
989
1293
|
}
|
|
1294
|
+
|
|
990
1295
|
function setFocus(form, name, options) {
|
|
991
1296
|
const { key } = create$1(name);
|
|
992
1297
|
if (options) emit(form.emitter, "focusError", key, options);
|
|
993
1298
|
else emit(form.emitter, "focusError", key);
|
|
994
1299
|
}
|
|
995
1300
|
|
|
1301
|
+
function create(options) {
|
|
1302
|
+
const emitter = create$2();
|
|
1303
|
+
_setMaxListeners(emitter, 0);
|
|
1304
|
+
let source = options?.initialValues ?? {};
|
|
1305
|
+
if (typeof source === "function") source = source();
|
|
1306
|
+
const form = {
|
|
1307
|
+
emitter,
|
|
1308
|
+
...options,
|
|
1309
|
+
mode: options?.mode ?? "onSubmit",
|
|
1310
|
+
reValidateMode: options?.reValidateMode ?? "onChange",
|
|
1311
|
+
disabled: options?.disabled ?? false,
|
|
1312
|
+
validateDeps: options?.validateDeps ? new Set(options.validateDeps.map((dep) => create$1(dep).key)) : void 0,
|
|
1313
|
+
initialValues: {},
|
|
1314
|
+
values: /* @__PURE__ */ new Map(),
|
|
1315
|
+
deleted: /* @__PURE__ */ new Set(),
|
|
1316
|
+
errors: /* @__PURE__ */ new Map(),
|
|
1317
|
+
touched: /* @__PURE__ */ new Set(),
|
|
1318
|
+
validators: /* @__PURE__ */ new Map(),
|
|
1319
|
+
validating: /* @__PURE__ */ new Set(),
|
|
1320
|
+
parsedValues: void 0,
|
|
1321
|
+
isSubmitting: false,
|
|
1322
|
+
submitCount: 0,
|
|
1323
|
+
isSubmitSuccessful: void 0,
|
|
1324
|
+
isLoading: false
|
|
1325
|
+
};
|
|
1326
|
+
if (isPromise(source)) {
|
|
1327
|
+
form.isLoading = true;
|
|
1328
|
+
emit(emitter, "loading");
|
|
1329
|
+
Promise.resolve(source).then(
|
|
1330
|
+
(resolved) => {
|
|
1331
|
+
form.isLoading = false;
|
|
1332
|
+
emit(emitter, "loading");
|
|
1333
|
+
setInitialValues(form, resolved ?? {});
|
|
1334
|
+
},
|
|
1335
|
+
(error) => {
|
|
1336
|
+
form.isLoading = false;
|
|
1337
|
+
emit(emitter, "loading");
|
|
1338
|
+
}
|
|
1339
|
+
);
|
|
1340
|
+
} else {
|
|
1341
|
+
form.initialValues = source;
|
|
1342
|
+
}
|
|
1343
|
+
return form;
|
|
1344
|
+
}
|
|
1345
|
+
|
|
996
1346
|
function defaultMessage(type, bound) {
|
|
997
1347
|
switch (type) {
|
|
998
1348
|
case "required":
|
|
@@ -1302,6 +1652,9 @@
|
|
|
1302
1652
|
seededRef.current = { done: false, source: void 0 };
|
|
1303
1653
|
React.useEffect(() => {
|
|
1304
1654
|
if (initialValues === void 0) return;
|
|
1655
|
+
if (typeof initialValues === "function" || isPromise(initialValues)) {
|
|
1656
|
+
return;
|
|
1657
|
+
}
|
|
1305
1658
|
const seeded = seededRef.current;
|
|
1306
1659
|
if (seeded.done && (seeded.source === initialValues || isEqual(seeded.source, initialValues))) {
|
|
1307
1660
|
return;
|
|
@@ -1326,12 +1679,14 @@
|
|
|
1326
1679
|
}, [form, values]);
|
|
1327
1680
|
return form;
|
|
1328
1681
|
}
|
|
1329
|
-
function useWatchCore(subscribeFactory, getter) {
|
|
1682
|
+
function useWatchCore(subscribeFactory, getter, isEqual2) {
|
|
1330
1683
|
const cacheRef = React.useRef(null);
|
|
1331
1684
|
if (cacheRef.current === null) cacheRef.current = { hasValue: false };
|
|
1332
1685
|
const cache = cacheRef.current;
|
|
1333
1686
|
const getterRef = React.useRef(getter);
|
|
1334
1687
|
getterRef.current = getter;
|
|
1688
|
+
const isEqualRef = React.useRef(isEqual2);
|
|
1689
|
+
isEqualRef.current = isEqual2;
|
|
1335
1690
|
const getSnapshot = React.useCallback(() => {
|
|
1336
1691
|
if (!cache.hasValue) {
|
|
1337
1692
|
cache.value = getterRef.current();
|
|
@@ -1343,6 +1698,14 @@
|
|
|
1343
1698
|
(notify) => {
|
|
1344
1699
|
cache.hasValue = false;
|
|
1345
1700
|
const invalidate = () => {
|
|
1701
|
+
const compare = isEqualRef.current;
|
|
1702
|
+
if (compare && cache.hasValue) {
|
|
1703
|
+
const next = getterRef.current();
|
|
1704
|
+
if (compare(cache.value, next)) return;
|
|
1705
|
+
cache.value = next;
|
|
1706
|
+
notify();
|
|
1707
|
+
return;
|
|
1708
|
+
}
|
|
1346
1709
|
cache.hasValue = false;
|
|
1347
1710
|
notify();
|
|
1348
1711
|
};
|
|
@@ -1352,12 +1715,13 @@
|
|
|
1352
1715
|
);
|
|
1353
1716
|
return shimExports.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
1354
1717
|
}
|
|
1355
|
-
function useWatch(
|
|
1718
|
+
function useWatch(formOrEmitter, event, getter, isEqual2) {
|
|
1719
|
+
const emitter = "emitter" in formOrEmitter ? formOrEmitter.emitter : formOrEmitter;
|
|
1356
1720
|
const subscribeFactory = React.useCallback(
|
|
1357
1721
|
(invalidate) => on(emitter, event, invalidate),
|
|
1358
1722
|
[emitter, event]
|
|
1359
1723
|
);
|
|
1360
|
-
return useWatchCore(subscribeFactory, getter);
|
|
1724
|
+
return useWatchCore(subscribeFactory, getter, isEqual2);
|
|
1361
1725
|
}
|
|
1362
1726
|
function useValue(form, name) {
|
|
1363
1727
|
return useValueByPath(form, create$1(name));
|
|
@@ -1415,19 +1779,71 @@
|
|
|
1415
1779
|
);
|
|
1416
1780
|
}
|
|
1417
1781
|
function useIsDirty(form) {
|
|
1418
|
-
return useWatch(form
|
|
1782
|
+
return useWatch(form, "change", isDirty.bind(null, form));
|
|
1419
1783
|
}
|
|
1420
1784
|
function useDirtyFields(form) {
|
|
1421
|
-
return useWatch(form
|
|
1785
|
+
return useWatch(form, "change", getDirtyFields.bind(null, form));
|
|
1422
1786
|
}
|
|
1423
1787
|
function useTouchedFields(form) {
|
|
1424
|
-
return useWatch(form
|
|
1788
|
+
return useWatch(form, "touched", getTouchedFields.bind(null, form));
|
|
1789
|
+
}
|
|
1790
|
+
const FORM_STATE_EVENTS = [
|
|
1791
|
+
"change",
|
|
1792
|
+
"errors",
|
|
1793
|
+
"touched",
|
|
1794
|
+
"validating",
|
|
1795
|
+
"submitting",
|
|
1796
|
+
"submitCount",
|
|
1797
|
+
"submitSuccessful",
|
|
1798
|
+
"disabled",
|
|
1799
|
+
"loading"
|
|
1800
|
+
];
|
|
1801
|
+
function getFormState(form) {
|
|
1802
|
+
return {
|
|
1803
|
+
isDirty: isDirty(form),
|
|
1804
|
+
dirtyFields: getDirtyFields(form),
|
|
1805
|
+
isTouched: form.touched.size > 0,
|
|
1806
|
+
touchedFields: getTouchedFields(form),
|
|
1807
|
+
hasErrors: hasErrors(form),
|
|
1808
|
+
isValid: !hasErrors(form),
|
|
1809
|
+
isSubmitting: form.isSubmitting,
|
|
1810
|
+
isValidating: form.validating.size > 0,
|
|
1811
|
+
isSubmitSuccessful: form.isSubmitSuccessful,
|
|
1812
|
+
submitCount: form.submitCount,
|
|
1813
|
+
isLoading: form.isLoading,
|
|
1814
|
+
disabled: form.disabled
|
|
1815
|
+
};
|
|
1816
|
+
}
|
|
1817
|
+
function isSameFormState(a, b) {
|
|
1818
|
+
const sameTouched = a.touchedFields.length === b.touchedFields.length && a.touchedFields.every((path, i) => path === b.touchedFields[i]);
|
|
1819
|
+
return a.isDirty === b.isDirty && a.dirtyFields === b.dirtyFields && a.isTouched === b.isTouched && sameTouched && a.hasErrors === b.hasErrors && a.isValid === b.isValid && a.isSubmitting === b.isSubmitting && a.isValidating === b.isValidating && a.isSubmitSuccessful === b.isSubmitSuccessful && a.submitCount === b.submitCount && a.isLoading === b.isLoading && a.disabled === b.disabled;
|
|
1820
|
+
}
|
|
1821
|
+
function useFormState(form) {
|
|
1822
|
+
const getter = React.useCallback(() => getFormState(form), [form]);
|
|
1823
|
+
const subscribeFactory = React.useCallback(
|
|
1824
|
+
(invalidate) => {
|
|
1825
|
+
const offs = FORM_STATE_EVENTS.map(
|
|
1826
|
+
(event) => on(form.emitter, event, invalidate)
|
|
1827
|
+
);
|
|
1828
|
+
return () => {
|
|
1829
|
+
for (const off of offs) off();
|
|
1830
|
+
};
|
|
1831
|
+
},
|
|
1832
|
+
[form.emitter]
|
|
1833
|
+
);
|
|
1834
|
+
return useWatchCore(subscribeFactory, getter, isSameFormState);
|
|
1425
1835
|
}
|
|
1426
1836
|
function useHasErrors(form) {
|
|
1427
|
-
return useWatch(form
|
|
1837
|
+
return useWatch(form, "errors", hasErrors.bind(null, form));
|
|
1838
|
+
}
|
|
1839
|
+
function useIsValid(form) {
|
|
1840
|
+
return useWatch(form, "errors", () => !hasErrors(form));
|
|
1428
1841
|
}
|
|
1429
1842
|
function useIsSubmitting(form) {
|
|
1430
|
-
return useWatch(form
|
|
1843
|
+
return useWatch(form, "submitting", () => form.isSubmitting);
|
|
1844
|
+
}
|
|
1845
|
+
function useIsLoading(form) {
|
|
1846
|
+
return useWatch(form, "loading", () => form.isLoading);
|
|
1431
1847
|
}
|
|
1432
1848
|
function useCanSubmit(form) {
|
|
1433
1849
|
const { emitter } = form;
|
|
@@ -1448,7 +1864,23 @@
|
|
|
1448
1864
|
);
|
|
1449
1865
|
}
|
|
1450
1866
|
function useSubmitCount(form) {
|
|
1451
|
-
return useWatch(form
|
|
1867
|
+
return useWatch(form, "submitCount", () => form.submitCount);
|
|
1868
|
+
}
|
|
1869
|
+
function useIsValidating(form) {
|
|
1870
|
+
return useWatch(form, "validating", () => form.validating.size > 0);
|
|
1871
|
+
}
|
|
1872
|
+
function useIsSubmitSuccessful(form) {
|
|
1873
|
+
return useWatch(
|
|
1874
|
+
form.emitter,
|
|
1875
|
+
"submitSuccessful",
|
|
1876
|
+
() => !!form.isSubmitSuccessful
|
|
1877
|
+
);
|
|
1878
|
+
}
|
|
1879
|
+
function useFormError(form) {
|
|
1880
|
+
return useErrorByPath(form, create$1(FORM_ERROR))?.message;
|
|
1881
|
+
}
|
|
1882
|
+
function useFormErrors(form) {
|
|
1883
|
+
return useFieldErrorsByPath(form, create$1(FORM_ERROR));
|
|
1452
1884
|
}
|
|
1453
1885
|
|
|
1454
1886
|
function usePath(name) {
|
|
@@ -1473,92 +1905,29 @@
|
|
|
1473
1905
|
const contextForm = React.useContext(FormContext);
|
|
1474
1906
|
const form = formProp || contextForm;
|
|
1475
1907
|
if (!form) throw new Error("no form provided");
|
|
1476
|
-
const lockRef = React.useRef(null);
|
|
1477
1908
|
const validateRef = React.useRef(validate);
|
|
1478
1909
|
validateRef.current = validate;
|
|
1479
1910
|
const debounceRef = React.useRef(options?.debounce ?? 0);
|
|
1480
1911
|
debounceRef.current = options?.debounce ?? 0;
|
|
1481
|
-
React.
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
marked = false;
|
|
1493
|
-
unsetValidatingByPath(form, path);
|
|
1494
|
-
};
|
|
1495
|
-
const run = () => {
|
|
1496
|
-
timer = null;
|
|
1497
|
-
const fn = validateRef.current;
|
|
1498
|
-
if (!fn) {
|
|
1499
|
-
unmark();
|
|
1500
|
-
return;
|
|
1501
|
-
}
|
|
1502
|
-
controller?.abort();
|
|
1503
|
-
controller = new AbortController();
|
|
1504
|
-
const lock = lockRef.current = {};
|
|
1505
|
-
let result;
|
|
1506
|
-
try {
|
|
1507
|
-
result = fn(getValueByPath(form, path), {
|
|
1508
|
-
form,
|
|
1509
|
-
path,
|
|
1510
|
-
signal: controller.signal
|
|
1511
|
-
});
|
|
1512
|
-
} catch (e) {
|
|
1513
|
-
unmark();
|
|
1514
|
-
throw e;
|
|
1515
|
-
}
|
|
1516
|
-
if (!isPromise(result)) {
|
|
1517
|
-
setErrorByPath(form, path, result);
|
|
1518
|
-
unmark();
|
|
1519
|
-
return;
|
|
1520
|
-
}
|
|
1521
|
-
mark();
|
|
1522
|
-
result.then(
|
|
1523
|
-
(error) => {
|
|
1524
|
-
if (lock === lockRef.current) {
|
|
1525
|
-
setErrorByPath(form, path, error);
|
|
1526
|
-
}
|
|
1527
|
-
}
|
|
1528
|
-
).catch(() => {
|
|
1529
|
-
}).finally(() => {
|
|
1530
|
-
if (lock === lockRef.current) {
|
|
1531
|
-
unmark();
|
|
1532
|
-
lockRef.current = null;
|
|
1533
|
-
}
|
|
1534
|
-
});
|
|
1535
|
-
};
|
|
1536
|
-
const validator = () => {
|
|
1537
|
-
const debounce = debounceRef.current;
|
|
1538
|
-
if (debounce > 0) {
|
|
1539
|
-
if (timer !== null) clearTimeout(timer);
|
|
1540
|
-
else mark();
|
|
1541
|
-
timer = setTimeout(run, debounce);
|
|
1542
|
-
return;
|
|
1543
|
-
}
|
|
1544
|
-
run();
|
|
1545
|
-
};
|
|
1546
|
-
form.validators.set(path.key, validator);
|
|
1547
|
-
return () => {
|
|
1548
|
-
form.validators.delete(path.key);
|
|
1549
|
-
if (timer !== null) {
|
|
1550
|
-
clearTimeout(timer);
|
|
1551
|
-
timer = null;
|
|
1552
|
-
}
|
|
1553
|
-
unmark();
|
|
1554
|
-
controller?.abort();
|
|
1555
|
-
};
|
|
1556
|
-
}, [form, path.key]);
|
|
1912
|
+
const syncRef = React.useRef(options?.sync);
|
|
1913
|
+
syncRef.current = options?.sync;
|
|
1914
|
+
React.useEffect(
|
|
1915
|
+
() => registerValidatorByPath(form, path, {
|
|
1916
|
+
validate: () => validateRef.current,
|
|
1917
|
+
debounce: () => debounceRef.current,
|
|
1918
|
+
sync: () => syncRef.current
|
|
1919
|
+
}),
|
|
1920
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- deps are `path.key` on purpose: usePath returns a stable Path per key, so re-subscribing on key (not object identity) is enough
|
|
1921
|
+
[form, path.key]
|
|
1922
|
+
);
|
|
1557
1923
|
return useStageFn(() => form.validators.get(path.key)?.());
|
|
1558
1924
|
}
|
|
1559
1925
|
|
|
1926
|
+
function hasRuleConstraints(rules) {
|
|
1927
|
+
return rules.required !== void 0 || rules.min !== void 0 || rules.max !== void 0 || rules.minLength !== void 0 || rules.maxLength !== void 0 || rules.pattern !== void 0;
|
|
1928
|
+
}
|
|
1560
1929
|
function combineRulesAndValidate(rules, validate) {
|
|
1561
|
-
if (!rules) return validate;
|
|
1930
|
+
if (!rules || !hasRuleConstraints(rules)) return validate;
|
|
1562
1931
|
const ruleValidator = rulesToValidator(rules);
|
|
1563
1932
|
if (!validate) return ruleValidator;
|
|
1564
1933
|
return (value, meta) => {
|
|
@@ -1590,6 +1959,25 @@
|
|
|
1590
1959
|
}, [errors, delay, shown]);
|
|
1591
1960
|
return delay === void 0 ? errors : shown;
|
|
1592
1961
|
}
|
|
1962
|
+
function useFieldValue(form, path, uncontrolled) {
|
|
1963
|
+
const snapshotRef = React.useRef({
|
|
1964
|
+
has: false,
|
|
1965
|
+
value: void 0
|
|
1966
|
+
});
|
|
1967
|
+
const getter = React.useCallback(() => {
|
|
1968
|
+
if (!uncontrolled) return getValueByPath(form, path);
|
|
1969
|
+
if (!snapshotRef.current.has) {
|
|
1970
|
+
snapshotRef.current = { has: true, value: getValueByPath(form, path) };
|
|
1971
|
+
}
|
|
1972
|
+
return snapshotRef.current.value;
|
|
1973
|
+
}, [uncontrolled, form, path]);
|
|
1974
|
+
const subscribeFactory = React.useCallback(
|
|
1975
|
+
(invalidate) => uncontrolled ? () => {
|
|
1976
|
+
} : onPathEvent(form.emitter, "change", path, "leaf", invalidate),
|
|
1977
|
+
[uncontrolled, form.emitter, path]
|
|
1978
|
+
);
|
|
1979
|
+
return useWatchCore(subscribeFactory, getter);
|
|
1980
|
+
}
|
|
1593
1981
|
function useFieldCore({
|
|
1594
1982
|
form: f1,
|
|
1595
1983
|
name,
|
|
@@ -1601,6 +1989,7 @@
|
|
|
1601
1989
|
validateDeps,
|
|
1602
1990
|
delayError,
|
|
1603
1991
|
disabled,
|
|
1992
|
+
uncontrolled,
|
|
1604
1993
|
mode: modeOption
|
|
1605
1994
|
}, Context) {
|
|
1606
1995
|
const contextForm = React.useContext(Context);
|
|
@@ -1618,35 +2007,23 @@
|
|
|
1618
2007
|
seededRef.current = false;
|
|
1619
2008
|
emitChangeByPath(form, path);
|
|
1620
2009
|
});
|
|
1621
|
-
const
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
debounce: validateDebounce
|
|
1627
|
-
}
|
|
1628
|
-
);
|
|
2010
|
+
const restRules = rules ? { ...rules, required: void 0 } : void 0;
|
|
2011
|
+
useValidate(combineRulesAndValidate(restRules, validate), path, form, {
|
|
2012
|
+
debounce: validateDebounce,
|
|
2013
|
+
sync: rules && rules.required !== void 0 ? rulesToValidator({ required: rules.required }) : void 0
|
|
2014
|
+
});
|
|
1629
2015
|
const liveErrors = useFieldErrorsByPath(form, path);
|
|
1630
2016
|
const errors = useDelayedErrors(liveErrors, delayError);
|
|
1631
2017
|
const errorObject = errors[0];
|
|
1632
2018
|
const error = errorObject?.message;
|
|
1633
|
-
const value =
|
|
1634
|
-
const formDisabled = useWatch(form
|
|
1635
|
-
const
|
|
1636
|
-
const
|
|
1637
|
-
setValueByPath(form, path, v);
|
|
1638
|
-
if (mode === "onChange" || mode === "all" || mode === "onTouched" && hasTouchedByPath(form, path) || liveErrors.length > 0 && form.reValidateMode === "onChange")
|
|
1639
|
-
validator();
|
|
1640
|
-
revalidateFormOnChange(form, path, mode);
|
|
1641
|
-
revalidateDependentsOnChange(form, path, mode);
|
|
1642
|
-
});
|
|
2019
|
+
const value = useFieldValue(form, path, !!uncontrolled);
|
|
2020
|
+
const formDisabled = useWatch(form, "disabled", () => form.disabled);
|
|
2021
|
+
const onChange = useStageFn((v) => userChangeByPath(form, path, v));
|
|
2022
|
+
const onBlur = useStageFn(() => userBlur(form, path));
|
|
1643
2023
|
React.useEffect(() => {
|
|
1644
|
-
form
|
|
1645
|
-
return () =>
|
|
1646
|
-
|
|
1647
|
-
form.changeHandlers.delete(path.key);
|
|
1648
|
-
};
|
|
1649
|
-
}, [form, path.key, onChange]);
|
|
2024
|
+
const { token, displaced } = registerFieldMode(form, path, modeOption);
|
|
2025
|
+
return () => unregisterFieldMode(form, path, token);
|
|
2026
|
+
}, [form, path.key, modeOption]);
|
|
1650
2027
|
const depsKey = validateDeps?.length ? validateDeps.join("\n") : void 0;
|
|
1651
2028
|
React.useEffect(() => {
|
|
1652
2029
|
if (!depsKey) return;
|
|
@@ -1654,14 +2031,29 @@
|
|
|
1654
2031
|
registerFieldValidateDeps(form, path.key, depKeys);
|
|
1655
2032
|
return () => unregisterFieldValidateDeps(form, path.key, depKeys);
|
|
1656
2033
|
}, [form, path.key, depsKey]);
|
|
1657
|
-
const
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
2034
|
+
const elementRef = React.useRef(null);
|
|
2035
|
+
const focusRef = React.useCallback((el) => {
|
|
2036
|
+
elementRef.current = el;
|
|
2037
|
+
}, []);
|
|
2038
|
+
React.useEffect(
|
|
2039
|
+
() => on(
|
|
2040
|
+
form.emitter,
|
|
2041
|
+
"focusError",
|
|
2042
|
+
(key, options) => {
|
|
2043
|
+
if (key !== path.key) return;
|
|
2044
|
+
const el = elementRef.current;
|
|
2045
|
+
if (!el || typeof el.focus !== "function") return;
|
|
2046
|
+
el.focus();
|
|
2047
|
+
if (options?.shouldSelect && typeof el.select === "function") {
|
|
2048
|
+
el.select();
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
),
|
|
2052
|
+
[form, path.key]
|
|
2053
|
+
);
|
|
1662
2054
|
React.useEffect(
|
|
1663
2055
|
() => () => {
|
|
1664
|
-
if (shouldUnregister !== false) {
|
|
2056
|
+
if ((shouldUnregister ?? form.shouldUnregister) !== false) {
|
|
1665
2057
|
removeFieldByPath(form, path);
|
|
1666
2058
|
}
|
|
1667
2059
|
},
|
|
@@ -1676,7 +2068,8 @@
|
|
|
1676
2068
|
onChange,
|
|
1677
2069
|
onBlur,
|
|
1678
2070
|
name: path.key,
|
|
1679
|
-
disabled: formDisabled || !!disabled
|
|
2071
|
+
disabled: formDisabled || !!disabled,
|
|
2072
|
+
focusRef
|
|
1680
2073
|
};
|
|
1681
2074
|
}
|
|
1682
2075
|
function useField(options) {
|
|
@@ -1905,29 +2298,72 @@
|
|
|
1905
2298
|
return group;
|
|
1906
2299
|
}
|
|
1907
2300
|
|
|
2301
|
+
function appendFormDataValue(fd, key, value) {
|
|
2302
|
+
if (value == null) return;
|
|
2303
|
+
if (Array.isArray(value)) {
|
|
2304
|
+
for (const item of value) appendFormDataValue(fd, key, item);
|
|
2305
|
+
return;
|
|
2306
|
+
}
|
|
2307
|
+
if (typeof FileList !== "undefined" && value instanceof FileList) {
|
|
2308
|
+
for (let i = 0; i < value.length; i++) fd.append(key, value.item(i));
|
|
2309
|
+
return;
|
|
2310
|
+
}
|
|
2311
|
+
if (typeof File !== "undefined" && value instanceof File) {
|
|
2312
|
+
fd.append(key, value, value.name);
|
|
2313
|
+
return;
|
|
2314
|
+
}
|
|
2315
|
+
if (typeof Blob !== "undefined" && value instanceof Blob) {
|
|
2316
|
+
fd.append(key, value);
|
|
2317
|
+
return;
|
|
2318
|
+
}
|
|
2319
|
+
if (value instanceof Date) {
|
|
2320
|
+
fd.append(key, value.toISOString());
|
|
2321
|
+
return;
|
|
2322
|
+
}
|
|
2323
|
+
fd.append(
|
|
2324
|
+
key,
|
|
2325
|
+
typeof value === "object" ? JSON.stringify(value) : String(value)
|
|
2326
|
+
);
|
|
2327
|
+
}
|
|
2328
|
+
function formDataFromValues(values) {
|
|
2329
|
+
const fd = new FormData();
|
|
2330
|
+
for (const key of Object.keys(values)) {
|
|
2331
|
+
appendFormDataValue(fd, key, values[key]);
|
|
2332
|
+
}
|
|
2333
|
+
return fd;
|
|
2334
|
+
}
|
|
2335
|
+
|
|
1908
2336
|
function Form({
|
|
1909
2337
|
form: f1,
|
|
1910
2338
|
context,
|
|
1911
2339
|
initialValues,
|
|
1912
2340
|
values,
|
|
2341
|
+
shouldUnregister,
|
|
1913
2342
|
onSubmit,
|
|
1914
2343
|
onValidSubmit,
|
|
1915
2344
|
onInvalidSubmit,
|
|
2345
|
+
action,
|
|
1916
2346
|
shouldFocusError,
|
|
1917
2347
|
...props
|
|
1918
2348
|
}) {
|
|
1919
|
-
const f2 = useForm({ initialValues, values });
|
|
2349
|
+
const f2 = useForm({ initialValues, values, shouldUnregister });
|
|
1920
2350
|
const form = f1 || f2;
|
|
1921
2351
|
const submit = handleSubmit(form, {
|
|
1922
2352
|
onSubmit,
|
|
1923
2353
|
onValidSubmit,
|
|
1924
2354
|
onInvalidSubmit,
|
|
1925
|
-
shouldFocusError
|
|
2355
|
+
shouldFocusError,
|
|
2356
|
+
onAction: action ? (values2) => action(formDataFromValues(values2)) : void 0
|
|
1926
2357
|
});
|
|
1927
2358
|
const { Provider } = context ?? FormContext;
|
|
1928
2359
|
return /* @__PURE__ */ React__namespace.createElement(Provider, { value: form }, /* @__PURE__ */ React__namespace.createElement("form", { ...props, noValidate: true, onSubmit: submit }));
|
|
1929
2360
|
}
|
|
1930
2361
|
|
|
2362
|
+
function FormField({ children, ...options }) {
|
|
2363
|
+
const field = useField(options);
|
|
2364
|
+
return children(field);
|
|
2365
|
+
}
|
|
2366
|
+
|
|
1931
2367
|
function setRef(ref, value) {
|
|
1932
2368
|
if (typeof ref === "function") {
|
|
1933
2369
|
ref(value);
|
|
@@ -1965,25 +2401,19 @@
|
|
|
1965
2401
|
disabled,
|
|
1966
2402
|
delayError,
|
|
1967
2403
|
mode,
|
|
2404
|
+
uncontrolled,
|
|
1968
2405
|
...props
|
|
1969
2406
|
}, ref) => {
|
|
1970
2407
|
const innerRef = React__namespace.useRef(null);
|
|
1971
2408
|
const [nativeInvalidCount, setNativeInvalidCount] = React__namespace.useState(0);
|
|
1972
|
-
const mergedRef = React__namespace.useCallback(
|
|
1973
|
-
(node) => {
|
|
1974
|
-
innerRef.current = node;
|
|
1975
|
-
setRef(ref, node);
|
|
1976
|
-
},
|
|
1977
|
-
[ref]
|
|
1978
|
-
);
|
|
1979
2409
|
const {
|
|
1980
2410
|
value,
|
|
1981
2411
|
onChange,
|
|
1982
2412
|
onBlur,
|
|
1983
2413
|
error,
|
|
1984
|
-
form,
|
|
1985
2414
|
name: fieldKey,
|
|
1986
|
-
disabled: isDisabled
|
|
2415
|
+
disabled: isDisabled,
|
|
2416
|
+
focusRef
|
|
1987
2417
|
} = useField({
|
|
1988
2418
|
name,
|
|
1989
2419
|
form: formProp,
|
|
@@ -1994,6 +2424,9 @@
|
|
|
1994
2424
|
delayError,
|
|
1995
2425
|
disabled,
|
|
1996
2426
|
mode,
|
|
2427
|
+
// File inputs cannot be value-controlled at all — force the
|
|
2428
|
+
// uncontrolled path so no `value` prop ever reaches the element.
|
|
2429
|
+
uncontrolled: uncontrolled || props.type === "file",
|
|
1997
2430
|
validate: (...params) => {
|
|
1998
2431
|
const el = innerRef.current;
|
|
1999
2432
|
if (el && typeof el.checkValidity === "function") {
|
|
@@ -2006,6 +2439,14 @@
|
|
|
2006
2439
|
if (validate) return validate(...params);
|
|
2007
2440
|
}
|
|
2008
2441
|
});
|
|
2442
|
+
const mergedRef = React__namespace.useCallback(
|
|
2443
|
+
(node) => {
|
|
2444
|
+
innerRef.current = node;
|
|
2445
|
+
focusRef(node);
|
|
2446
|
+
setRef(ref, node);
|
|
2447
|
+
},
|
|
2448
|
+
[ref, focusRef]
|
|
2449
|
+
);
|
|
2009
2450
|
const Component = as || "input";
|
|
2010
2451
|
React__namespace.useEffect(() => {
|
|
2011
2452
|
const el = innerRef.current;
|
|
@@ -2020,23 +2461,9 @@
|
|
|
2020
2461
|
React__namespace.useEffect(() => {
|
|
2021
2462
|
if (nativeInvalidCount > 0) innerRef.current?.reportValidity();
|
|
2022
2463
|
}, [nativeInvalidCount]);
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
"focusError",
|
|
2027
|
-
(key, options) => {
|
|
2028
|
-
if (key !== fieldKey) return;
|
|
2029
|
-
const el = innerRef.current;
|
|
2030
|
-
if (!el || typeof el.focus !== "function") return;
|
|
2031
|
-
el.focus();
|
|
2032
|
-
if (options?.shouldSelect && typeof el.select === "function") {
|
|
2033
|
-
el.select();
|
|
2034
|
-
}
|
|
2035
|
-
}
|
|
2036
|
-
),
|
|
2037
|
-
[form, fieldKey]
|
|
2038
|
-
);
|
|
2039
|
-
const toValue = eventToValue ?? ((e) => e.target.value);
|
|
2464
|
+
const isFile = props.type === "file";
|
|
2465
|
+
const toValue = eventToValue ?? (isFile ? (e) => e.target.files : (e) => e.target.value);
|
|
2466
|
+
const valueProps = valueToProps ? valueToProps(value) : isFile ? {} : uncontrolled ? { defaultValue: value } : { value };
|
|
2040
2467
|
const errorId = errorIdFromKey(fieldKey);
|
|
2041
2468
|
return /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement(
|
|
2042
2469
|
Component,
|
|
@@ -2045,7 +2472,7 @@
|
|
|
2045
2472
|
name: fieldKey,
|
|
2046
2473
|
onBlur,
|
|
2047
2474
|
...asProps,
|
|
2048
|
-
...
|
|
2475
|
+
...valueProps,
|
|
2049
2476
|
...ariaProps(error, fieldKey, props),
|
|
2050
2477
|
disabled: isDisabled,
|
|
2051
2478
|
onChange: (e) => onChange(toValue(e)),
|
|
@@ -2165,9 +2592,11 @@
|
|
|
2165
2592
|
exports.Checkbox = Checkbox;
|
|
2166
2593
|
exports.CheckboxGroupContext = CheckboxGroupContext;
|
|
2167
2594
|
exports.CheckboxGroupProvider = CheckboxGroupProvider;
|
|
2595
|
+
exports.FORM_ERROR = FORM_ERROR;
|
|
2168
2596
|
exports.Field = Field;
|
|
2169
2597
|
exports.Form = Form;
|
|
2170
2598
|
exports.FormContext = FormContext;
|
|
2599
|
+
exports.FormField = FormField;
|
|
2171
2600
|
exports.FormProvider = FormProvider;
|
|
2172
2601
|
exports.Select = Select;
|
|
2173
2602
|
exports.VALIDATION_OUTCOME = VALIDATION_OUTCOME;
|
|
@@ -2198,7 +2627,9 @@
|
|
|
2198
2627
|
exports.incrementSubmitCount = incrementSubmitCount;
|
|
2199
2628
|
exports.isDirty = isDirty;
|
|
2200
2629
|
exports.isTouched = isTouched;
|
|
2630
|
+
exports.registerFieldMode = registerFieldMode;
|
|
2201
2631
|
exports.registerFieldValidateDeps = registerFieldValidateDeps;
|
|
2632
|
+
exports.registerValidatorByPath = registerValidatorByPath;
|
|
2202
2633
|
exports.removeField = removeField;
|
|
2203
2634
|
exports.removeFieldByPath = removeFieldByPath;
|
|
2204
2635
|
exports.reset = reset;
|
|
@@ -2221,6 +2652,7 @@
|
|
|
2221
2652
|
exports.setValueByPath = setValueByPath;
|
|
2222
2653
|
exports.subscribe = subscribe;
|
|
2223
2654
|
exports.trigger = trigger;
|
|
2655
|
+
exports.unregisterFieldMode = unregisterFieldMode;
|
|
2224
2656
|
exports.unregisterFieldValidateDeps = unregisterFieldValidateDeps;
|
|
2225
2657
|
exports.unsetValidatingByPath = unsetValidatingByPath;
|
|
2226
2658
|
exports.useCanSubmit = useCanSubmit;
|
|
@@ -2235,9 +2667,16 @@
|
|
|
2235
2667
|
exports.useFieldErrorsByPath = useFieldErrorsByPath;
|
|
2236
2668
|
exports.useForm = useForm;
|
|
2237
2669
|
exports.useFormContext = useFormContext;
|
|
2670
|
+
exports.useFormError = useFormError;
|
|
2671
|
+
exports.useFormErrors = useFormErrors;
|
|
2672
|
+
exports.useFormState = useFormState;
|
|
2238
2673
|
exports.useHasErrors = useHasErrors;
|
|
2239
2674
|
exports.useIsDirty = useIsDirty;
|
|
2675
|
+
exports.useIsLoading = useIsLoading;
|
|
2676
|
+
exports.useIsSubmitSuccessful = useIsSubmitSuccessful;
|
|
2240
2677
|
exports.useIsSubmitting = useIsSubmitting;
|
|
2678
|
+
exports.useIsValid = useIsValid;
|
|
2679
|
+
exports.useIsValidating = useIsValidating;
|
|
2241
2680
|
exports.useSubmitCount = useSubmitCount;
|
|
2242
2681
|
exports.useTouched = useTouched;
|
|
2243
2682
|
exports.useTouchedByPath = useTouchedByPath;
|
|
@@ -2245,6 +2684,9 @@
|
|
|
2245
2684
|
exports.useValue = useValue;
|
|
2246
2685
|
exports.useValueByPath = useValueByPath;
|
|
2247
2686
|
exports.useWatch = useWatch;
|
|
2687
|
+
exports.useWatchCore = useWatchCore;
|
|
2688
|
+
exports.userBlur = userBlur;
|
|
2689
|
+
exports.userChangeByPath = userChangeByPath;
|
|
2248
2690
|
exports.validate = validate;
|
|
2249
2691
|
|
|
2250
2692
|
}));
|