react-f0rm 1.1.1 → 1.3.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 +242 -39
- 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-BKrUdpfI.cjs.js +2 -0
- package/dist/errors-BKrUdpfI.cjs.js.map +1 -0
- package/dist/errors-CrQBddrJ.mjs +2 -0
- package/dist/errors-CrQBddrJ.mjs.map +1 -0
- package/dist/form-CeKSBs31.d.ts +486 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1097 -118
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +1082 -544
- 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-CNtuUhmk.mjs +2 -0
- package/dist/validate-CNtuUhmk.mjs.map +1 -0
- package/dist/validate-Cl4ksNFu.cjs.js +2 -0
- package/dist/validate-Cl4ksNFu.cjs.js.map +1 -0
- package/dist/validate-nksgv1pR.d.ts +272 -0
- package/dist/values-Cu6awQOJ.cjs.js +2 -0
- package/dist/values-Cu6awQOJ.cjs.js.map +1 -0
- package/dist/values-DRY-a32G.mjs +2 -0
- package/dist/values-DRY-a32G.mjs.map +1 -0
- package/package.json +87 -29
- 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
|
-
}
|
|
300
|
-
function setValue(form, name, value, options) {
|
|
301
|
-
setValueByPath(form, create$1(name), value, options);
|
|
302
385
|
}
|
|
303
|
-
function
|
|
304
|
-
const
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
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,37 +433,16 @@
|
|
|
358
433
|
function getFirstError({ errors }) {
|
|
359
434
|
return errors.values().next().value?.[0]?.message;
|
|
360
435
|
}
|
|
361
|
-
function
|
|
362
|
-
|
|
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);
|
|
436
|
+
function setError(form, name, error, options) {
|
|
437
|
+
setErrorByPath(form, create$1(name), error, options);
|
|
383
438
|
}
|
|
384
|
-
function
|
|
385
|
-
|
|
386
|
-
}
|
|
387
|
-
function setErrorByPath({ emitter, errors }, path, error) {
|
|
439
|
+
function setErrorByPath(form, path, error, options) {
|
|
440
|
+
const { emitter, errors } = form;
|
|
388
441
|
const list = normalizeErrors(error);
|
|
389
442
|
if (list) errors.set(path.key, list);
|
|
390
443
|
else errors.delete(path.key);
|
|
391
444
|
emit(emitter, "errors", path);
|
|
445
|
+
if (options?.shouldFocus) emit(emitter, "focusError", path.key);
|
|
392
446
|
}
|
|
393
447
|
function normalizeErrors(error) {
|
|
394
448
|
if (typeof error === "string") {
|
|
@@ -430,19 +484,13 @@
|
|
|
430
484
|
);
|
|
431
485
|
}
|
|
432
486
|
}
|
|
433
|
-
function
|
|
434
|
-
|
|
435
|
-
}
|
|
436
|
-
function setTouchedByPath({ emitter, touched }, path) {
|
|
437
|
-
if (touched.has(path.key)) return;
|
|
438
|
-
touched.add(path.key);
|
|
439
|
-
emit(emitter, "touched", path);
|
|
440
|
-
}
|
|
441
|
-
function hasTouched(form, name) {
|
|
442
|
-
return hasTouchedByPath(form, create$1(name));
|
|
487
|
+
function hasErrors({ errors }) {
|
|
488
|
+
return errors.size > 0;
|
|
443
489
|
}
|
|
444
|
-
|
|
445
|
-
|
|
490
|
+
|
|
491
|
+
function isFieldDirtyByPath(form, path) {
|
|
492
|
+
const live = form.values.get(path.key);
|
|
493
|
+
return form.values.has(path.key) && getDirtyBaseline(form, path.key, path.value) !== live;
|
|
446
494
|
}
|
|
447
495
|
function isDirty(form) {
|
|
448
496
|
let dirty = false;
|
|
@@ -457,39 +505,6 @@
|
|
|
457
505
|
if (getDirtyBaseline(form, key, path) !== value) fn(path.join("."));
|
|
458
506
|
}
|
|
459
507
|
}
|
|
460
|
-
const dirtyBaselines = /* @__PURE__ */ new WeakMap();
|
|
461
|
-
function getDirtyBaseline(form, key, segments) {
|
|
462
|
-
const baselines = dirtyBaselines.get(form);
|
|
463
|
-
if (baselines?.has(key)) return baselines.get(key);
|
|
464
|
-
return get(form.initialValues, segments);
|
|
465
|
-
}
|
|
466
|
-
function setDirtyBaseline(form, { key }, value) {
|
|
467
|
-
let baselines = dirtyBaselines.get(form);
|
|
468
|
-
if (!baselines) {
|
|
469
|
-
baselines = /* @__PURE__ */ new Map();
|
|
470
|
-
dirtyBaselines.set(form, baselines);
|
|
471
|
-
}
|
|
472
|
-
baselines.set(key, value);
|
|
473
|
-
}
|
|
474
|
-
function pruneDirtyBaselines(form, { key }) {
|
|
475
|
-
const baselines = dirtyBaselines.get(form);
|
|
476
|
-
if (!baselines?.size) return;
|
|
477
|
-
const stem = `${key.slice(0, -1)},`;
|
|
478
|
-
for (const baselineKey of baselines.keys()) {
|
|
479
|
-
if (baselineKey.startsWith(stem)) baselines.delete(baselineKey);
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
function clearDirtyBaselines(form, key) {
|
|
483
|
-
const baselines = dirtyBaselines.get(form);
|
|
484
|
-
if (!baselines) return;
|
|
485
|
-
if (key === void 0) baselines.clear();
|
|
486
|
-
else baselines.delete(key);
|
|
487
|
-
}
|
|
488
|
-
const dirtyFieldsCaches = /* @__PURE__ */ new WeakMap();
|
|
489
|
-
function bumpDirtyVersion(form) {
|
|
490
|
-
const cache = dirtyFieldsCaches.get(form);
|
|
491
|
-
if (cache) cache.version++;
|
|
492
|
-
}
|
|
493
508
|
function computeDirtyFields(form) {
|
|
494
509
|
const dirtyFields = {};
|
|
495
510
|
forEachDirtyField(form, (key) => {
|
|
@@ -514,6 +529,21 @@
|
|
|
514
529
|
}
|
|
515
530
|
return cache.result;
|
|
516
531
|
}
|
|
532
|
+
|
|
533
|
+
function setTouched(form, name) {
|
|
534
|
+
setTouchedByPath(form, create$1(name));
|
|
535
|
+
}
|
|
536
|
+
function setTouchedByPath({ emitter, touched }, path) {
|
|
537
|
+
if (touched.has(path.key)) return;
|
|
538
|
+
touched.add(path.key);
|
|
539
|
+
emit(emitter, "touched", path);
|
|
540
|
+
}
|
|
541
|
+
function hasTouched(form, name) {
|
|
542
|
+
return hasTouchedByPath(form, create$1(name));
|
|
543
|
+
}
|
|
544
|
+
function hasTouchedByPath({ touched }, path) {
|
|
545
|
+
return touched.has(path.key);
|
|
546
|
+
}
|
|
517
547
|
function getTouchedFields({ touched }) {
|
|
518
548
|
return Array.from(
|
|
519
549
|
touched,
|
|
@@ -523,18 +553,102 @@
|
|
|
523
553
|
function isTouched({ touched }) {
|
|
524
554
|
return touched.size > 0;
|
|
525
555
|
}
|
|
526
|
-
|
|
527
|
-
|
|
556
|
+
|
|
557
|
+
function getValues(form) {
|
|
558
|
+
let cache = valuesCaches.get(form);
|
|
559
|
+
if (!cache) {
|
|
560
|
+
cache = { version: 0, result: computeValues(form) };
|
|
561
|
+
valuesCaches.set(form, cache);
|
|
562
|
+
} else if (cache.version > 0) {
|
|
563
|
+
cache.result = computeValues(form);
|
|
564
|
+
cache.version = 0;
|
|
565
|
+
}
|
|
566
|
+
return cache.result;
|
|
567
|
+
}
|
|
568
|
+
function computeValues(form) {
|
|
569
|
+
const { initialValues, parsedValues, values, deleted } = form;
|
|
570
|
+
const owned = /* @__PURE__ */ new Set();
|
|
571
|
+
let merged = parsedValues ?? initialValues;
|
|
572
|
+
for (const [key, value] of values) {
|
|
573
|
+
merged = setOwned(merged, JSON.parse(key), value, owned);
|
|
574
|
+
}
|
|
575
|
+
for (const key of deleted) {
|
|
576
|
+
merged = unset(merged, JSON.parse(key));
|
|
577
|
+
}
|
|
578
|
+
return merged;
|
|
579
|
+
}
|
|
580
|
+
function getValue(form, name) {
|
|
581
|
+
return getValueByPath(form, create$1(name));
|
|
582
|
+
}
|
|
583
|
+
function getValueByPath({ initialValues, parsedValues, values, deleted }, path) {
|
|
584
|
+
const { key, value: segments } = path;
|
|
585
|
+
if (values.has(key)) return values.get(key);
|
|
586
|
+
if (deleted.has(key)) return void 0;
|
|
587
|
+
for (let i = segments.length - 1; i > 0; i--) {
|
|
588
|
+
const ancestorKey = JSON.stringify(segments.slice(0, i));
|
|
589
|
+
if (values.has(ancestorKey)) {
|
|
590
|
+
return get(values.get(ancestorKey), segments.slice(i));
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
return get(parsedValues ?? initialValues, segments);
|
|
594
|
+
}
|
|
595
|
+
function setValue(form, name, value, options) {
|
|
596
|
+
setValueByPath(form, create$1(name), value, options);
|
|
597
|
+
}
|
|
598
|
+
function setValueByPath(form, path, value, options) {
|
|
599
|
+
const { emitter, values, deleted } = form;
|
|
600
|
+
const next = typeof value === "function" ? value(getValueByPath(form, path)) : value;
|
|
601
|
+
values.set(path.key, next);
|
|
602
|
+
pruneDescendantKeys(values, path);
|
|
603
|
+
reviveBranch(deleted, path);
|
|
604
|
+
pruneDirtyBaselines(form, path);
|
|
605
|
+
if (options?.shouldDirty === false) setDirtyBaseline(form, path, next);
|
|
606
|
+
bumpDirtyVersion(form);
|
|
607
|
+
bumpValuesVersion(form);
|
|
608
|
+
if (options?.shouldTouch) setTouchedByPath(form, path);
|
|
609
|
+
if (options?.shouldValidate) form.validators.get(path.key)?.();
|
|
610
|
+
emit(emitter, "change", path);
|
|
611
|
+
}
|
|
612
|
+
function seedValueByPath(form, path, value) {
|
|
613
|
+
const { values, deleted } = form;
|
|
614
|
+
values.set(path.key, value);
|
|
615
|
+
pruneDescendantKeys(values, path);
|
|
616
|
+
reviveBranch(deleted, path);
|
|
617
|
+
pruneDirtyBaselines(form, path);
|
|
618
|
+
bumpDirtyVersion(form);
|
|
619
|
+
bumpValuesVersion(form);
|
|
620
|
+
}
|
|
621
|
+
function emitChangeByPath({ emitter }, path) {
|
|
622
|
+
emit(emitter, "change", path);
|
|
623
|
+
}
|
|
624
|
+
function getFieldState(form, name) {
|
|
625
|
+
const path = create$1(name);
|
|
626
|
+
const { touched, validating } = form;
|
|
627
|
+
return {
|
|
628
|
+
value: getValueByPath(form, path),
|
|
629
|
+
error: getErrorByPath(form, path),
|
|
630
|
+
errors: getFieldErrorsByPath(form, path),
|
|
631
|
+
// The shared per-field rule (committed baselines included): the field
|
|
632
|
+
// is dirty while its live value differs from its effective baseline.
|
|
633
|
+
isDirty: isFieldDirtyByPath(form, path),
|
|
634
|
+
isTouched: touched.has(path.key),
|
|
635
|
+
isValidating: validating.has(path.key)
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
function removeField(form, name, options) {
|
|
639
|
+
removeFieldByPath(form, create$1(name), options);
|
|
528
640
|
}
|
|
529
|
-
function removeFieldByPath(form, path) {
|
|
641
|
+
function removeFieldByPath(form, path, options) {
|
|
530
642
|
const { key, value: segments } = path;
|
|
531
643
|
const { emitter, values, touched, errors, validating, deleted } = form;
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
644
|
+
if (!options?.keepValue && !options?.keepDirty) {
|
|
645
|
+
values.delete(key);
|
|
646
|
+
clearDirtyBaselines(form, key);
|
|
647
|
+
if (!hasLiveBranch(values, segments)) deleted.add(key);
|
|
648
|
+
}
|
|
649
|
+
if (!options?.keepTouched) touched.delete(key);
|
|
650
|
+
if (!options?.keepError) errors.delete(key);
|
|
535
651
|
validating.delete(key);
|
|
536
|
-
clearDirtyBaselines(form, key);
|
|
537
|
-
if (!hasLiveBranch(values, segments)) deleted.add(key);
|
|
538
652
|
bumpDirtyVersion(form);
|
|
539
653
|
bumpValuesVersion(form);
|
|
540
654
|
emit(emitter, "change", path);
|
|
@@ -580,17 +694,37 @@
|
|
|
580
694
|
bumpValuesVersion(form);
|
|
581
695
|
emit(form.emitter, "change");
|
|
582
696
|
}
|
|
697
|
+
function collectValueLeaves(node, segments, out) {
|
|
698
|
+
if (node !== null && typeof node === "object") {
|
|
699
|
+
if (Array.isArray(node)) {
|
|
700
|
+
for (let i = 0; i < node.length; i++) {
|
|
701
|
+
collectValueLeaves(node[i], [...segments, i], out);
|
|
702
|
+
}
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
const keys = Object.keys(node);
|
|
706
|
+
if (keys.length > 0) {
|
|
707
|
+
for (const k of keys) {
|
|
708
|
+
collectValueLeaves(node[k], [...segments, k], out);
|
|
709
|
+
}
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
out.push({ segments, value: node });
|
|
714
|
+
}
|
|
583
715
|
function reset(form, initialValues, options) {
|
|
584
|
-
const
|
|
585
|
-
if (options?.
|
|
716
|
+
const keptValues = [];
|
|
717
|
+
if (options?.keepValues) {
|
|
718
|
+
collectValueLeaves(getValues(form), [], keptValues);
|
|
719
|
+
} else if (options?.keepDirtyValues) {
|
|
586
720
|
for (const [key, value] of form.values) {
|
|
587
721
|
const segments = JSON.parse(key);
|
|
588
722
|
if (getDirtyBaseline(form, key, segments) !== value) {
|
|
589
|
-
|
|
723
|
+
keptValues.push({ segments, value });
|
|
590
724
|
}
|
|
591
725
|
}
|
|
592
726
|
}
|
|
593
|
-
form.initialValues = initialValues;
|
|
727
|
+
form.initialValues = options?.keepDefaultValues ? form.initialValues : initialValues ?? form.initialValues;
|
|
594
728
|
form.parsedValues = void 0;
|
|
595
729
|
if (!options?.keepErrors) clearErrors(form);
|
|
596
730
|
const { emitter, touched, values, deleted, validating } = form;
|
|
@@ -601,10 +735,11 @@
|
|
|
601
735
|
validating.clear();
|
|
602
736
|
if (!options?.keepIsSubmitting) form.isSubmitting = false;
|
|
603
737
|
if (!options?.keepSubmitCount) form.submitCount = 0;
|
|
604
|
-
if (!options?.keepIsSubmitted) form.
|
|
738
|
+
if (!options?.keepIsSubmitted) form.isSubmitted = false;
|
|
739
|
+
if (!options?.keepIsSubmitSuccessful) form.isSubmitSuccessful = void 0;
|
|
605
740
|
bumpDirtyVersion(form);
|
|
606
741
|
bumpValuesVersion(form);
|
|
607
|
-
for (const { segments, value } of
|
|
742
|
+
for (const { segments, value } of keptValues) {
|
|
608
743
|
setValueByPath(form, create$1(segments), value);
|
|
609
744
|
}
|
|
610
745
|
emit(emitter, "change");
|
|
@@ -639,10 +774,151 @@
|
|
|
639
774
|
bumpDirtyVersion(form);
|
|
640
775
|
bumpValuesVersion(form);
|
|
641
776
|
}
|
|
642
|
-
|
|
643
|
-
|
|
777
|
+
|
|
778
|
+
function unsetValidatingByPath({ emitter, validating }, path) {
|
|
779
|
+
validating.delete(path.key);
|
|
780
|
+
emit(emitter, "validating", path);
|
|
781
|
+
}
|
|
782
|
+
function setValidatingByPath({ emitter, validating }, path) {
|
|
783
|
+
validating.add(path.key);
|
|
784
|
+
emit(emitter, "validating", path);
|
|
785
|
+
}
|
|
786
|
+
function registerValidatorByPath(form, path, registration) {
|
|
787
|
+
let timer = null;
|
|
788
|
+
let controller = null;
|
|
789
|
+
let marked = false;
|
|
790
|
+
let lock = null;
|
|
791
|
+
let errorSource = null;
|
|
792
|
+
const hasErrors2 = (errors) => errors !== void 0 && !(Array.isArray(errors) && errors.length === 0);
|
|
793
|
+
const mark = () => {
|
|
794
|
+
if (marked) return;
|
|
795
|
+
marked = true;
|
|
796
|
+
setValidatingByPath(form, path);
|
|
797
|
+
};
|
|
798
|
+
const unmark = () => {
|
|
799
|
+
if (!marked) return;
|
|
800
|
+
marked = false;
|
|
801
|
+
unsetValidatingByPath(form, path);
|
|
802
|
+
};
|
|
803
|
+
const runSync = () => {
|
|
804
|
+
const sync = registration.sync();
|
|
805
|
+
if (!sync) return false;
|
|
806
|
+
const errors = sync(getValueByPath(form, path), { form, path });
|
|
807
|
+
if (!hasErrors2(errors)) {
|
|
808
|
+
if (!registration.validate() || errorSource === "sync") {
|
|
809
|
+
setErrorByPath(form, path, void 0);
|
|
810
|
+
errorSource = null;
|
|
811
|
+
}
|
|
812
|
+
return false;
|
|
813
|
+
}
|
|
814
|
+
setErrorByPath(form, path, errors);
|
|
815
|
+
errorSource = "sync";
|
|
816
|
+
return true;
|
|
817
|
+
};
|
|
818
|
+
const collectSyncErrors = () => {
|
|
819
|
+
const sync = registration.sync();
|
|
820
|
+
if (!sync) return null;
|
|
821
|
+
const errors = sync(getValueByPath(form, path), { form, path });
|
|
822
|
+
if (errors === void 0) return null;
|
|
823
|
+
const list = Array.isArray(errors) ? errors : [errors];
|
|
824
|
+
return list.length ? list : null;
|
|
825
|
+
};
|
|
826
|
+
const land = (result) => {
|
|
827
|
+
if (registration.asyncAlways?.()) {
|
|
828
|
+
const gate = collectSyncErrors();
|
|
829
|
+
const own = result === void 0 ? [] : Array.isArray(result) ? result : [result];
|
|
830
|
+
setErrorByPath(form, path, [...gate ?? [], ...own]);
|
|
831
|
+
errorSource = hasErrors2(result) ? "validator" : gate ? "sync" : null;
|
|
832
|
+
} else {
|
|
833
|
+
setErrorByPath(form, path, result);
|
|
834
|
+
errorSource = hasErrors2(result) ? "validator" : null;
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
const supersede = () => {
|
|
838
|
+
if (timer !== null) {
|
|
839
|
+
clearTimeout(timer);
|
|
840
|
+
timer = null;
|
|
841
|
+
}
|
|
842
|
+
controller?.abort();
|
|
843
|
+
lock = {};
|
|
844
|
+
};
|
|
845
|
+
const runValidator = () => {
|
|
846
|
+
const fn = registration.validate();
|
|
847
|
+
if (!fn) {
|
|
848
|
+
unmark();
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
controller?.abort();
|
|
852
|
+
controller = new AbortController();
|
|
853
|
+
const round = lock = {};
|
|
854
|
+
let result;
|
|
855
|
+
try {
|
|
856
|
+
result = fn(getValueByPath(form, path), {
|
|
857
|
+
form,
|
|
858
|
+
path,
|
|
859
|
+
signal: controller.signal
|
|
860
|
+
});
|
|
861
|
+
} catch (e) {
|
|
862
|
+
unmark();
|
|
863
|
+
throw e;
|
|
864
|
+
}
|
|
865
|
+
if (!isPromise(result)) {
|
|
866
|
+
land(result);
|
|
867
|
+
unmark();
|
|
868
|
+
return;
|
|
869
|
+
}
|
|
870
|
+
mark();
|
|
871
|
+
result.then(
|
|
872
|
+
(error) => {
|
|
873
|
+
if (lock === round) {
|
|
874
|
+
land(error);
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
).catch(() => {
|
|
878
|
+
}).finally(() => {
|
|
879
|
+
if (lock === round) {
|
|
880
|
+
unmark();
|
|
881
|
+
lock = null;
|
|
882
|
+
}
|
|
883
|
+
});
|
|
884
|
+
};
|
|
885
|
+
const run = () => {
|
|
886
|
+
timer = null;
|
|
887
|
+
if (runSync() && !registration.asyncAlways?.()) {
|
|
888
|
+
supersede();
|
|
889
|
+
unmark();
|
|
890
|
+
return;
|
|
891
|
+
}
|
|
892
|
+
runValidator();
|
|
893
|
+
};
|
|
894
|
+
const kick = () => {
|
|
895
|
+
if (runSync() && !registration.asyncAlways?.()) {
|
|
896
|
+
supersede();
|
|
897
|
+
unmark();
|
|
898
|
+
return;
|
|
899
|
+
}
|
|
900
|
+
if (!registration.validate()) return;
|
|
901
|
+
const debounce = registration.debounce();
|
|
902
|
+
if (debounce > 0) {
|
|
903
|
+
if (timer !== null) clearTimeout(timer);
|
|
904
|
+
else mark();
|
|
905
|
+
timer = setTimeout(run, debounce);
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
908
|
+
runValidator();
|
|
909
|
+
};
|
|
910
|
+
form.validators.set(path.key, kick);
|
|
911
|
+
return () => {
|
|
912
|
+
form.validators.delete(path.key);
|
|
913
|
+
if (timer !== null) {
|
|
914
|
+
clearTimeout(timer);
|
|
915
|
+
timer = null;
|
|
916
|
+
}
|
|
917
|
+
unmark();
|
|
918
|
+
controller?.abort();
|
|
919
|
+
};
|
|
644
920
|
}
|
|
645
|
-
async function trigger(form, name) {
|
|
921
|
+
async function trigger(form, name, options) {
|
|
646
922
|
const settle = (keys2) => waitUntil(
|
|
647
923
|
form.emitter,
|
|
648
924
|
"validating",
|
|
@@ -653,18 +929,25 @@
|
|
|
653
929
|
form.validators.forEach((validator) => validator());
|
|
654
930
|
await settle();
|
|
655
931
|
if (form.validate) await runFormValidate(form);
|
|
932
|
+
if (options?.shouldTouch) touchKeys(form, [...form.validators.keys()]);
|
|
933
|
+
if (options?.shouldFocus) {
|
|
934
|
+
const firstKey = form.errors.keys().next().value;
|
|
935
|
+
if (firstKey !== void 0) emit(form.emitter, "focusError", firstKey);
|
|
936
|
+
}
|
|
656
937
|
return !hasErrors(form);
|
|
657
938
|
}
|
|
658
939
|
const keys = typeof name === "string" || isSegmentsPath(name) ? [create$1(name).key] : name.map((one) => create$1(one).key);
|
|
659
940
|
keys.forEach((key) => form.validators.get(key)?.());
|
|
660
941
|
await settle(keys);
|
|
942
|
+
if (options?.shouldTouch) touchKeys(form, keys);
|
|
943
|
+
if (options?.shouldFocus) {
|
|
944
|
+
const firstKey = keys.find((key) => form.errors.has(key));
|
|
945
|
+
if (firstKey !== void 0) emit(form.emitter, "focusError", firstKey);
|
|
946
|
+
}
|
|
661
947
|
return keys.every((key) => !form.errors.has(key));
|
|
662
948
|
}
|
|
663
|
-
function
|
|
664
|
-
|
|
665
|
-
}
|
|
666
|
-
function isFieldError(value) {
|
|
667
|
-
return !!value && typeof value === "object" && typeof value.type === "string" && typeof value.message === "string";
|
|
949
|
+
function touchKeys(form, keys) {
|
|
950
|
+
keys.forEach((key) => setTouchedByPath(form, create$1(JSON.parse(key))));
|
|
668
951
|
}
|
|
669
952
|
function setFormErrors(form, result, segments = [], footprint) {
|
|
670
953
|
Object.entries(result).forEach(([key, value]) => {
|
|
@@ -694,12 +977,6 @@
|
|
|
694
977
|
const stored = form.errors.get(path.key);
|
|
695
978
|
if (stored) footprint.set(path.key, stored);
|
|
696
979
|
}
|
|
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
980
|
function applyValidateResult(form, result) {
|
|
704
981
|
const footprint = form.validateDeps ? getFormErrorFootprint(form) : void 0;
|
|
705
982
|
if (footprint) {
|
|
@@ -897,6 +1174,55 @@
|
|
|
897
1174
|
async function validate(form) {
|
|
898
1175
|
return ensureValidate(form).catch((e) => e.message);
|
|
899
1176
|
}
|
|
1177
|
+
|
|
1178
|
+
const fieldModes = /* @__PURE__ */ new WeakMap();
|
|
1179
|
+
function changeValue(form, name, value, options) {
|
|
1180
|
+
changeValueByPath(form, create$1(name), value, options);
|
|
1181
|
+
}
|
|
1182
|
+
function changeValueByPath(form, path, value, options) {
|
|
1183
|
+
if (options?.shouldDirty === false) setDirtyBaseline(form, path, value);
|
|
1184
|
+
if (fieldModes.get(form)?.get(path.key)) {
|
|
1185
|
+
userChangeByPath(form, path, value);
|
|
1186
|
+
} else {
|
|
1187
|
+
setValueByPath(form, path, value, options);
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
function registerFieldMode(form, path, mode) {
|
|
1191
|
+
let modes = fieldModes.get(form);
|
|
1192
|
+
if (!modes) {
|
|
1193
|
+
modes = /* @__PURE__ */ new Map();
|
|
1194
|
+
fieldModes.set(form, modes);
|
|
1195
|
+
}
|
|
1196
|
+
const displaced = modes.has(path.key);
|
|
1197
|
+
const token = {};
|
|
1198
|
+
modes.set(path.key, { mode, token });
|
|
1199
|
+
return { token, displaced };
|
|
1200
|
+
}
|
|
1201
|
+
function unregisterFieldMode(form, path, token) {
|
|
1202
|
+
const modes = fieldModes.get(form);
|
|
1203
|
+
const entry = modes?.get(path.key);
|
|
1204
|
+
if (modes && entry && entry.token === token) modes.delete(path.key);
|
|
1205
|
+
}
|
|
1206
|
+
function runUserChangeGate(form, path, mode) {
|
|
1207
|
+
if (mode === "onChange" || mode === "all" || mode === "onTouched" && hasTouchedByPath(form, path) || getFieldErrorsByPath(form, path).length > 0 && form.reValidateMode === "onChange")
|
|
1208
|
+
form.validators.get(path.key)?.();
|
|
1209
|
+
revalidateFormOnChange(form, path, mode);
|
|
1210
|
+
revalidateDependentsOnChange(form, path, mode);
|
|
1211
|
+
}
|
|
1212
|
+
function userChangeByPath(form, path, value) {
|
|
1213
|
+
setValueByPath(form, path, value);
|
|
1214
|
+
const entry = fieldModes.get(form)?.get(path.key);
|
|
1215
|
+
if (entry) runUserChangeGate(form, path, entry.mode ?? form.mode);
|
|
1216
|
+
}
|
|
1217
|
+
function userBlur(form, path) {
|
|
1218
|
+
setTouchedByPath(form, path);
|
|
1219
|
+
const entry = fieldModes.get(form)?.get(path.key);
|
|
1220
|
+
if (!entry) return;
|
|
1221
|
+
const mode = entry.mode ?? form.mode;
|
|
1222
|
+
if (mode === "onBlur" || mode === "onTouched" || mode === "all" || getFieldErrorsByPath(form, path).length > 0 && form.reValidateMode === "onBlur")
|
|
1223
|
+
form.validators.get(path.key)?.();
|
|
1224
|
+
}
|
|
1225
|
+
|
|
900
1226
|
function setIsSubmitting(form, value) {
|
|
901
1227
|
form.isSubmitting = value;
|
|
902
1228
|
emit(form.emitter, "submitting");
|
|
@@ -913,6 +1239,10 @@
|
|
|
913
1239
|
form.disabled = value;
|
|
914
1240
|
emit(form.emitter, "disabled");
|
|
915
1241
|
}
|
|
1242
|
+
function setStatus(form, value) {
|
|
1243
|
+
form.status = value;
|
|
1244
|
+
emit(form.emitter, "status");
|
|
1245
|
+
}
|
|
916
1246
|
function nameToPath(name) {
|
|
917
1247
|
if (name.startsWith("[")) {
|
|
918
1248
|
try {
|
|
@@ -943,6 +1273,7 @@
|
|
|
943
1273
|
onSubmit,
|
|
944
1274
|
onValidSubmit,
|
|
945
1275
|
onInvalidSubmit,
|
|
1276
|
+
onAction,
|
|
946
1277
|
shouldFocusError = true
|
|
947
1278
|
} = options ?? {};
|
|
948
1279
|
return async (e) => {
|
|
@@ -950,6 +1281,7 @@
|
|
|
950
1281
|
e.preventDefault();
|
|
951
1282
|
}
|
|
952
1283
|
const formEl = e?.currentTarget;
|
|
1284
|
+
form.isSubmitted = true;
|
|
953
1285
|
setIsSubmitting(form, true);
|
|
954
1286
|
incrementSubmitCount(form);
|
|
955
1287
|
const values = getValues(form);
|
|
@@ -979,6 +1311,7 @@
|
|
|
979
1311
|
const submitted = getValues(form);
|
|
980
1312
|
if (onSubmit) await onSubmit(submitted, e);
|
|
981
1313
|
if (onValidSubmit) await onValidSubmit(submitted, e);
|
|
1314
|
+
if (onAction) await onAction(submitted, e);
|
|
982
1315
|
setSubmitSuccessful(form, true);
|
|
983
1316
|
} catch {
|
|
984
1317
|
setSubmitSuccessful(form, false);
|
|
@@ -987,12 +1320,62 @@
|
|
|
987
1320
|
}
|
|
988
1321
|
};
|
|
989
1322
|
}
|
|
1323
|
+
|
|
990
1324
|
function setFocus(form, name, options) {
|
|
991
1325
|
const { key } = create$1(name);
|
|
992
1326
|
if (options) emit(form.emitter, "focusError", key, options);
|
|
993
1327
|
else emit(form.emitter, "focusError", key);
|
|
994
1328
|
}
|
|
995
1329
|
|
|
1330
|
+
function create(options) {
|
|
1331
|
+
const emitter = create$2();
|
|
1332
|
+
_setMaxListeners(emitter, 0);
|
|
1333
|
+
let source = options?.initialValues ?? {};
|
|
1334
|
+
if (typeof source === "function") source = source();
|
|
1335
|
+
const form = {
|
|
1336
|
+
emitter,
|
|
1337
|
+
...options,
|
|
1338
|
+
mode: options?.mode ?? "onSubmit",
|
|
1339
|
+
reValidateMode: options?.reValidateMode ?? "onChange",
|
|
1340
|
+
disabled: options?.disabled ?? false,
|
|
1341
|
+
validateOnMount: options?.validateOnMount ?? false,
|
|
1342
|
+
asyncAlways: options?.asyncAlways ?? false,
|
|
1343
|
+
validateDeps: options?.validateDeps ? new Set(options.validateDeps.map((dep) => create$1(dep).key)) : void 0,
|
|
1344
|
+
initialValues: {},
|
|
1345
|
+
values: /* @__PURE__ */ new Map(),
|
|
1346
|
+
deleted: /* @__PURE__ */ new Set(),
|
|
1347
|
+
errors: /* @__PURE__ */ new Map(),
|
|
1348
|
+
touched: /* @__PURE__ */ new Set(),
|
|
1349
|
+
validators: /* @__PURE__ */ new Map(),
|
|
1350
|
+
validating: /* @__PURE__ */ new Set(),
|
|
1351
|
+
parsedValues: void 0,
|
|
1352
|
+
isSubmitting: false,
|
|
1353
|
+
isSubmitted: false,
|
|
1354
|
+
submitCount: 0,
|
|
1355
|
+
isSubmitSuccessful: void 0,
|
|
1356
|
+
isLoading: false,
|
|
1357
|
+
status: void 0
|
|
1358
|
+
};
|
|
1359
|
+
if (isPromise(source)) {
|
|
1360
|
+
form.isLoading = true;
|
|
1361
|
+
emit(emitter, "loading");
|
|
1362
|
+
Promise.resolve(source).then(
|
|
1363
|
+
(resolved) => {
|
|
1364
|
+
setInitialValues(form, resolved ?? {});
|
|
1365
|
+
form.isLoading = false;
|
|
1366
|
+
emit(emitter, "loading");
|
|
1367
|
+
},
|
|
1368
|
+
(error) => {
|
|
1369
|
+
form.isLoading = false;
|
|
1370
|
+
emit(emitter, "loading");
|
|
1371
|
+
}
|
|
1372
|
+
);
|
|
1373
|
+
} else {
|
|
1374
|
+
form.initialValues = source;
|
|
1375
|
+
}
|
|
1376
|
+
return form;
|
|
1377
|
+
}
|
|
1378
|
+
|
|
996
1379
|
function defaultMessage(type, bound) {
|
|
997
1380
|
switch (type) {
|
|
998
1381
|
case "required":
|
|
@@ -1012,9 +1395,9 @@
|
|
|
1012
1395
|
}
|
|
1013
1396
|
}
|
|
1014
1397
|
function rulesToValidator(rules) {
|
|
1015
|
-
return (value) => {
|
|
1398
|
+
return (value, meta) => {
|
|
1016
1399
|
if (rules.required) {
|
|
1017
|
-
if (value === "" || value === void 0 || value === null) {
|
|
1400
|
+
if (value === "" || value === void 0 || value === null || Array.isArray(value) && value.length === 0) {
|
|
1018
1401
|
return [
|
|
1019
1402
|
{
|
|
1020
1403
|
type: "required",
|
|
@@ -1037,13 +1420,14 @@
|
|
|
1037
1420
|
errors.push({ type: "max", message: message("max", rules.max) });
|
|
1038
1421
|
}
|
|
1039
1422
|
}
|
|
1040
|
-
|
|
1423
|
+
const isSized = typeof value === "string" || Array.isArray(value);
|
|
1424
|
+
if (rules.minLength !== void 0 && isSized && value.length < rules.minLength) {
|
|
1041
1425
|
errors.push({
|
|
1042
1426
|
type: "minLength",
|
|
1043
1427
|
message: message("minLength", rules.minLength)
|
|
1044
1428
|
});
|
|
1045
1429
|
}
|
|
1046
|
-
if (rules.maxLength !== void 0 &&
|
|
1430
|
+
if (rules.maxLength !== void 0 && isSized && value.length > rules.maxLength) {
|
|
1047
1431
|
errors.push({
|
|
1048
1432
|
type: "maxLength",
|
|
1049
1433
|
message: message("maxLength", rules.maxLength)
|
|
@@ -1056,207 +1440,32 @@
|
|
|
1056
1440
|
message: rules.messages?.pattern ?? rules.pattern.message ?? defaultMessage("pattern")
|
|
1057
1441
|
});
|
|
1058
1442
|
}
|
|
1443
|
+
if (rules.validate !== void 0) {
|
|
1444
|
+
const fns = typeof rules.validate === "function" ? { validate: rules.validate } : rules.validate;
|
|
1445
|
+
for (const [type, fn] of Object.entries(fns)) {
|
|
1446
|
+
const result = fn(value, meta);
|
|
1447
|
+
if (result === void 0) continue;
|
|
1448
|
+
for (const entry of Array.isArray(result) ? result : [result]) {
|
|
1449
|
+
errors.push(
|
|
1450
|
+
typeof entry === "string" ? { type, message: entry } : { ...entry, type }
|
|
1451
|
+
);
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1059
1455
|
return errors.length ? errors : void 0;
|
|
1060
1456
|
};
|
|
1061
1457
|
}
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
1072
|
-
*
|
|
1073
|
-
* This source code is licensed under the MIT license found in the
|
|
1074
|
-
* LICENSE file in the root directory of this source tree.
|
|
1075
|
-
*/
|
|
1076
|
-
|
|
1077
|
-
var hasRequiredUseSyncExternalStoreShim_production;
|
|
1078
|
-
|
|
1079
|
-
function requireUseSyncExternalStoreShim_production () {
|
|
1080
|
-
if (hasRequiredUseSyncExternalStoreShim_production) return useSyncExternalStoreShim_production;
|
|
1081
|
-
hasRequiredUseSyncExternalStoreShim_production = 1;
|
|
1082
|
-
var React$1 = React;
|
|
1083
|
-
function is(x, y) {
|
|
1084
|
-
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
|
|
1085
|
-
}
|
|
1086
|
-
var objectIs = "function" === typeof Object.is ? Object.is : is,
|
|
1087
|
-
useState = React$1.useState,
|
|
1088
|
-
useEffect = React$1.useEffect,
|
|
1089
|
-
useLayoutEffect = React$1.useLayoutEffect,
|
|
1090
|
-
useDebugValue = React$1.useDebugValue;
|
|
1091
|
-
function useSyncExternalStore$2(subscribe, getSnapshot) {
|
|
1092
|
-
var value = getSnapshot(),
|
|
1093
|
-
_useState = useState({ inst: { value: value, getSnapshot: getSnapshot } }),
|
|
1094
|
-
inst = _useState[0].inst,
|
|
1095
|
-
forceUpdate = _useState[1];
|
|
1096
|
-
useLayoutEffect(
|
|
1097
|
-
function () {
|
|
1098
|
-
inst.value = value;
|
|
1099
|
-
inst.getSnapshot = getSnapshot;
|
|
1100
|
-
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
1101
|
-
},
|
|
1102
|
-
[subscribe, value, getSnapshot]
|
|
1103
|
-
);
|
|
1104
|
-
useEffect(
|
|
1105
|
-
function () {
|
|
1106
|
-
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
1107
|
-
return subscribe(function () {
|
|
1108
|
-
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
1109
|
-
});
|
|
1110
|
-
},
|
|
1111
|
-
[subscribe]
|
|
1112
|
-
);
|
|
1113
|
-
useDebugValue(value);
|
|
1114
|
-
return value;
|
|
1115
|
-
}
|
|
1116
|
-
function checkIfSnapshotChanged(inst) {
|
|
1117
|
-
var latestGetSnapshot = inst.getSnapshot;
|
|
1118
|
-
inst = inst.value;
|
|
1119
|
-
try {
|
|
1120
|
-
var nextValue = latestGetSnapshot();
|
|
1121
|
-
return !objectIs(inst, nextValue);
|
|
1122
|
-
} catch (error) {
|
|
1123
|
-
return true;
|
|
1124
|
-
}
|
|
1125
|
-
}
|
|
1126
|
-
function useSyncExternalStore$1(subscribe, getSnapshot) {
|
|
1127
|
-
return getSnapshot();
|
|
1128
|
-
}
|
|
1129
|
-
var shim =
|
|
1130
|
-
"undefined" === typeof window ||
|
|
1131
|
-
"undefined" === typeof window.document ||
|
|
1132
|
-
"undefined" === typeof window.document.createElement
|
|
1133
|
-
? useSyncExternalStore$1
|
|
1134
|
-
: useSyncExternalStore$2;
|
|
1135
|
-
useSyncExternalStoreShim_production.useSyncExternalStore =
|
|
1136
|
-
void 0 !== React$1.useSyncExternalStore ? React$1.useSyncExternalStore : shim;
|
|
1137
|
-
return useSyncExternalStoreShim_production;
|
|
1138
|
-
}
|
|
1139
|
-
|
|
1140
|
-
var useSyncExternalStoreShim_development = {};
|
|
1141
|
-
|
|
1142
|
-
/**
|
|
1143
|
-
* @license React
|
|
1144
|
-
* use-sync-external-store-shim.development.js
|
|
1145
|
-
*
|
|
1146
|
-
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
1147
|
-
*
|
|
1148
|
-
* This source code is licensed under the MIT license found in the
|
|
1149
|
-
* LICENSE file in the root directory of this source tree.
|
|
1150
|
-
*/
|
|
1151
|
-
|
|
1152
|
-
var hasRequiredUseSyncExternalStoreShim_development;
|
|
1153
|
-
|
|
1154
|
-
function requireUseSyncExternalStoreShim_development () {
|
|
1155
|
-
if (hasRequiredUseSyncExternalStoreShim_development) return useSyncExternalStoreShim_development;
|
|
1156
|
-
hasRequiredUseSyncExternalStoreShim_development = 1;
|
|
1157
|
-
"production" !== process.env.NODE_ENV &&
|
|
1158
|
-
(function () {
|
|
1159
|
-
function is(x, y) {
|
|
1160
|
-
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
|
|
1161
|
-
}
|
|
1162
|
-
function useSyncExternalStore$2(subscribe, getSnapshot) {
|
|
1163
|
-
didWarnOld18Alpha ||
|
|
1164
|
-
void 0 === React$1.startTransition ||
|
|
1165
|
-
((didWarnOld18Alpha = true),
|
|
1166
|
-
console.error(
|
|
1167
|
-
"You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."
|
|
1168
|
-
));
|
|
1169
|
-
var value = getSnapshot();
|
|
1170
|
-
if (!didWarnUncachedGetSnapshot) {
|
|
1171
|
-
var cachedValue = getSnapshot();
|
|
1172
|
-
objectIs(value, cachedValue) ||
|
|
1173
|
-
(console.error(
|
|
1174
|
-
"The result of getSnapshot should be cached to avoid an infinite loop"
|
|
1175
|
-
),
|
|
1176
|
-
(didWarnUncachedGetSnapshot = true));
|
|
1177
|
-
}
|
|
1178
|
-
cachedValue = useState({
|
|
1179
|
-
inst: { value: value, getSnapshot: getSnapshot }
|
|
1180
|
-
});
|
|
1181
|
-
var inst = cachedValue[0].inst,
|
|
1182
|
-
forceUpdate = cachedValue[1];
|
|
1183
|
-
useLayoutEffect(
|
|
1184
|
-
function () {
|
|
1185
|
-
inst.value = value;
|
|
1186
|
-
inst.getSnapshot = getSnapshot;
|
|
1187
|
-
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
1188
|
-
},
|
|
1189
|
-
[subscribe, value, getSnapshot]
|
|
1190
|
-
);
|
|
1191
|
-
useEffect(
|
|
1192
|
-
function () {
|
|
1193
|
-
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
1194
|
-
return subscribe(function () {
|
|
1195
|
-
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
1196
|
-
});
|
|
1197
|
-
},
|
|
1198
|
-
[subscribe]
|
|
1199
|
-
);
|
|
1200
|
-
useDebugValue(value);
|
|
1201
|
-
return value;
|
|
1202
|
-
}
|
|
1203
|
-
function checkIfSnapshotChanged(inst) {
|
|
1204
|
-
var latestGetSnapshot = inst.getSnapshot;
|
|
1205
|
-
inst = inst.value;
|
|
1206
|
-
try {
|
|
1207
|
-
var nextValue = latestGetSnapshot();
|
|
1208
|
-
return !objectIs(inst, nextValue);
|
|
1209
|
-
} catch (error) {
|
|
1210
|
-
return true;
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
function useSyncExternalStore$1(subscribe, getSnapshot) {
|
|
1214
|
-
return getSnapshot();
|
|
1215
|
-
}
|
|
1216
|
-
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
|
|
1217
|
-
"function" ===
|
|
1218
|
-
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart &&
|
|
1219
|
-
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
1220
|
-
var React$1 = React,
|
|
1221
|
-
objectIs = "function" === typeof Object.is ? Object.is : is,
|
|
1222
|
-
useState = React$1.useState,
|
|
1223
|
-
useEffect = React$1.useEffect,
|
|
1224
|
-
useLayoutEffect = React$1.useLayoutEffect,
|
|
1225
|
-
useDebugValue = React$1.useDebugValue,
|
|
1226
|
-
didWarnOld18Alpha = false,
|
|
1227
|
-
didWarnUncachedGetSnapshot = false,
|
|
1228
|
-
shim =
|
|
1229
|
-
"undefined" === typeof window ||
|
|
1230
|
-
"undefined" === typeof window.document ||
|
|
1231
|
-
"undefined" === typeof window.document.createElement
|
|
1232
|
-
? useSyncExternalStore$1
|
|
1233
|
-
: useSyncExternalStore$2;
|
|
1234
|
-
useSyncExternalStoreShim_development.useSyncExternalStore =
|
|
1235
|
-
void 0 !== React$1.useSyncExternalStore ? React$1.useSyncExternalStore : shim;
|
|
1236
|
-
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
|
|
1237
|
-
"function" ===
|
|
1238
|
-
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
|
|
1239
|
-
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
|
|
1240
|
-
})();
|
|
1241
|
-
return useSyncExternalStoreShim_development;
|
|
1242
|
-
}
|
|
1243
|
-
|
|
1244
|
-
var hasRequiredShim;
|
|
1245
|
-
|
|
1246
|
-
function requireShim () {
|
|
1247
|
-
if (hasRequiredShim) return shim.exports;
|
|
1248
|
-
hasRequiredShim = 1;
|
|
1249
|
-
|
|
1250
|
-
if (process.env.NODE_ENV === 'production') {
|
|
1251
|
-
shim.exports = requireUseSyncExternalStoreShim_production();
|
|
1252
|
-
} else {
|
|
1253
|
-
shim.exports = requireUseSyncExternalStoreShim_development();
|
|
1254
|
-
}
|
|
1255
|
-
return shim.exports;
|
|
1458
|
+
function rulesToConstraintAttrs(rules) {
|
|
1459
|
+
const attrs = {};
|
|
1460
|
+
if (rules.required) attrs.required = true;
|
|
1461
|
+
if (rules.min !== void 0) attrs.min = rules.min;
|
|
1462
|
+
if (rules.max !== void 0) attrs.max = rules.max;
|
|
1463
|
+
if (rules.minLength !== void 0) attrs.minLength = rules.minLength;
|
|
1464
|
+
if (rules.maxLength !== void 0) attrs.maxLength = rules.maxLength;
|
|
1465
|
+
if (rules.pattern) attrs.pattern = rules.pattern.value.source;
|
|
1466
|
+
return attrs;
|
|
1256
1467
|
}
|
|
1257
1468
|
|
|
1258
|
-
var shimExports = requireShim();
|
|
1259
|
-
|
|
1260
1469
|
function isDescendant(key, ancestorKey) {
|
|
1261
1470
|
return key.startsWith(`${ancestorKey.slice(0, -1)},`);
|
|
1262
1471
|
}
|
|
@@ -1302,6 +1511,9 @@
|
|
|
1302
1511
|
seededRef.current = { done: false, source: void 0 };
|
|
1303
1512
|
React.useEffect(() => {
|
|
1304
1513
|
if (initialValues === void 0) return;
|
|
1514
|
+
if (typeof initialValues === "function" || isPromise(initialValues)) {
|
|
1515
|
+
return;
|
|
1516
|
+
}
|
|
1305
1517
|
const seeded = seededRef.current;
|
|
1306
1518
|
if (seeded.done && (seeded.source === initialValues || isEqual(seeded.source, initialValues))) {
|
|
1307
1519
|
return;
|
|
@@ -1324,14 +1536,29 @@
|
|
|
1324
1536
|
seeded.source = values;
|
|
1325
1537
|
setInitialValues(form, values);
|
|
1326
1538
|
}, [form, values]);
|
|
1539
|
+
React.useEffect(() => {
|
|
1540
|
+
if (!form.validateOnMount || !form.validate) return;
|
|
1541
|
+
const run = () => {
|
|
1542
|
+
void runFormValidate(form).catch(() => void 0);
|
|
1543
|
+
};
|
|
1544
|
+
if (!form.isLoading) {
|
|
1545
|
+
run();
|
|
1546
|
+
return;
|
|
1547
|
+
}
|
|
1548
|
+
return on(form.emitter, "loading", () => {
|
|
1549
|
+
run();
|
|
1550
|
+
});
|
|
1551
|
+
}, [form]);
|
|
1327
1552
|
return form;
|
|
1328
1553
|
}
|
|
1329
|
-
function useWatchCore(subscribeFactory, getter) {
|
|
1554
|
+
function useWatchCore(subscribeFactory, getter, isEqual2) {
|
|
1330
1555
|
const cacheRef = React.useRef(null);
|
|
1331
1556
|
if (cacheRef.current === null) cacheRef.current = { hasValue: false };
|
|
1332
1557
|
const cache = cacheRef.current;
|
|
1333
1558
|
const getterRef = React.useRef(getter);
|
|
1334
1559
|
getterRef.current = getter;
|
|
1560
|
+
const isEqualRef = React.useRef(isEqual2);
|
|
1561
|
+
isEqualRef.current = isEqual2;
|
|
1335
1562
|
const getSnapshot = React.useCallback(() => {
|
|
1336
1563
|
if (!cache.hasValue) {
|
|
1337
1564
|
cache.value = getterRef.current();
|
|
@@ -1343,6 +1570,14 @@
|
|
|
1343
1570
|
(notify) => {
|
|
1344
1571
|
cache.hasValue = false;
|
|
1345
1572
|
const invalidate = () => {
|
|
1573
|
+
const compare = isEqualRef.current;
|
|
1574
|
+
if (compare && cache.hasValue) {
|
|
1575
|
+
const next = getterRef.current();
|
|
1576
|
+
if (compare(cache.value, next)) return;
|
|
1577
|
+
cache.value = next;
|
|
1578
|
+
notify();
|
|
1579
|
+
return;
|
|
1580
|
+
}
|
|
1346
1581
|
cache.hasValue = false;
|
|
1347
1582
|
notify();
|
|
1348
1583
|
};
|
|
@@ -1350,27 +1585,35 @@
|
|
|
1350
1585
|
},
|
|
1351
1586
|
[subscribeFactory, cache]
|
|
1352
1587
|
);
|
|
1353
|
-
return
|
|
1588
|
+
return React.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
1354
1589
|
}
|
|
1355
|
-
function useWatch(
|
|
1590
|
+
function useWatch(formOrEmitter, event, getter, isEqual2) {
|
|
1591
|
+
const emitter = "emitter" in formOrEmitter ? formOrEmitter.emitter : formOrEmitter;
|
|
1356
1592
|
const subscribeFactory = React.useCallback(
|
|
1357
1593
|
(invalidate) => on(emitter, event, invalidate),
|
|
1358
1594
|
[emitter, event]
|
|
1359
1595
|
);
|
|
1360
|
-
return useWatchCore(subscribeFactory, getter);
|
|
1596
|
+
return useWatchCore(subscribeFactory, getter, isEqual2);
|
|
1361
1597
|
}
|
|
1362
|
-
function useValue(form, name) {
|
|
1363
|
-
return useValueByPath(form, create$1(name));
|
|
1598
|
+
function useValue(form, name, options) {
|
|
1599
|
+
return useValueByPath(form, create$1(name), options);
|
|
1364
1600
|
}
|
|
1365
|
-
function useValueByPath(form, path) {
|
|
1601
|
+
function useValueByPath(form, path, options) {
|
|
1366
1602
|
const { emitter } = form;
|
|
1367
1603
|
const { key } = path;
|
|
1604
|
+
const scope = options?.exact === false ? "branch" : "leaf";
|
|
1368
1605
|
const subscribeFactory = React.useCallback(
|
|
1369
|
-
(invalidate) => onPathEvent(emitter, "change", path,
|
|
1606
|
+
(invalidate) => onPathEvent(emitter, "change", path, scope, invalidate),
|
|
1370
1607
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- deps are `key` on purpose: useValue creates a fresh Path per render, so the object must stay out of the deps while the key string pins the subscription
|
|
1371
|
-
[emitter, key]
|
|
1608
|
+
[emitter, key, scope]
|
|
1372
1609
|
);
|
|
1373
|
-
return useWatchCore(subscribeFactory,
|
|
1610
|
+
return useWatchCore(subscribeFactory, () => {
|
|
1611
|
+
if (options?.exact === false) {
|
|
1612
|
+
return get(getValues(form), path.value);
|
|
1613
|
+
}
|
|
1614
|
+
const value = getValueByPath(form, path);
|
|
1615
|
+
return value === void 0 ? options?.defaultValue : value;
|
|
1616
|
+
});
|
|
1374
1617
|
}
|
|
1375
1618
|
function useTouched(form, name) {
|
|
1376
1619
|
return useTouchedByPath(form, create$1(name));
|
|
@@ -1415,19 +1658,88 @@
|
|
|
1415
1658
|
);
|
|
1416
1659
|
}
|
|
1417
1660
|
function useIsDirty(form) {
|
|
1418
|
-
return useWatch(form
|
|
1661
|
+
return useWatch(form, "change", isDirty.bind(null, form));
|
|
1662
|
+
}
|
|
1663
|
+
function useIsFieldDirty(form, name) {
|
|
1664
|
+
return useIsFieldDirtyByPath(form, create$1(name));
|
|
1665
|
+
}
|
|
1666
|
+
function useIsFieldDirtyByPath(form, path) {
|
|
1667
|
+
const { emitter } = form;
|
|
1668
|
+
const { key } = path;
|
|
1669
|
+
const subscribeFactory = React.useCallback(
|
|
1670
|
+
(invalidate) => onPathEvent(emitter, "change", path, "leaf", invalidate),
|
|
1671
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- same key-pinning convention as useValueByPath
|
|
1672
|
+
[emitter, key]
|
|
1673
|
+
);
|
|
1674
|
+
return useWatchCore(subscribeFactory, () => isFieldDirtyByPath(form, path));
|
|
1419
1675
|
}
|
|
1420
1676
|
function useDirtyFields(form) {
|
|
1421
|
-
return useWatch(form
|
|
1677
|
+
return useWatch(form, "change", getDirtyFields.bind(null, form));
|
|
1422
1678
|
}
|
|
1423
1679
|
function useTouchedFields(form) {
|
|
1424
|
-
return useWatch(form
|
|
1680
|
+
return useWatch(form, "touched", getTouchedFields.bind(null, form));
|
|
1681
|
+
}
|
|
1682
|
+
const FORM_STATE_EVENTS = [
|
|
1683
|
+
"change",
|
|
1684
|
+
"errors",
|
|
1685
|
+
"touched",
|
|
1686
|
+
"validating",
|
|
1687
|
+
"submitting",
|
|
1688
|
+
"submitCount",
|
|
1689
|
+
"submitSuccessful",
|
|
1690
|
+
"disabled",
|
|
1691
|
+
"loading"
|
|
1692
|
+
];
|
|
1693
|
+
function getFormState(form) {
|
|
1694
|
+
return {
|
|
1695
|
+
isDirty: isDirty(form),
|
|
1696
|
+
dirtyFields: getDirtyFields(form),
|
|
1697
|
+
isTouched: form.touched.size > 0,
|
|
1698
|
+
touchedFields: getTouchedFields(form),
|
|
1699
|
+
hasErrors: hasErrors(form),
|
|
1700
|
+
isValid: !hasErrors(form),
|
|
1701
|
+
isSubmitting: form.isSubmitting,
|
|
1702
|
+
isSubmitted: form.isSubmitted,
|
|
1703
|
+
isValidating: form.validating.size > 0,
|
|
1704
|
+
isSubmitSuccessful: form.isSubmitSuccessful,
|
|
1705
|
+
submitCount: form.submitCount,
|
|
1706
|
+
isLoading: form.isLoading,
|
|
1707
|
+
disabled: form.disabled
|
|
1708
|
+
};
|
|
1709
|
+
}
|
|
1710
|
+
function isSameFormState(a, b) {
|
|
1711
|
+
const sameTouched = a.touchedFields.length === b.touchedFields.length && a.touchedFields.every((path, i) => path === b.touchedFields[i]);
|
|
1712
|
+
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.isSubmitted === b.isSubmitted && a.isValidating === b.isValidating && a.isSubmitSuccessful === b.isSubmitSuccessful && a.submitCount === b.submitCount && a.isLoading === b.isLoading && a.disabled === b.disabled;
|
|
1713
|
+
}
|
|
1714
|
+
function useFormState(form) {
|
|
1715
|
+
const getter = React.useCallback(() => getFormState(form), [form]);
|
|
1716
|
+
const subscribeFactory = React.useCallback(
|
|
1717
|
+
(invalidate) => {
|
|
1718
|
+
const offs = FORM_STATE_EVENTS.map(
|
|
1719
|
+
(event) => on(form.emitter, event, invalidate)
|
|
1720
|
+
);
|
|
1721
|
+
return () => {
|
|
1722
|
+
for (const off of offs) off();
|
|
1723
|
+
};
|
|
1724
|
+
},
|
|
1725
|
+
[form.emitter]
|
|
1726
|
+
);
|
|
1727
|
+
return useWatchCore(subscribeFactory, getter, isSameFormState);
|
|
1425
1728
|
}
|
|
1426
1729
|
function useHasErrors(form) {
|
|
1427
|
-
return useWatch(form
|
|
1730
|
+
return useWatch(form, "errors", hasErrors.bind(null, form));
|
|
1731
|
+
}
|
|
1732
|
+
function useIsValid(form) {
|
|
1733
|
+
return useWatch(form, "errors", () => !hasErrors(form));
|
|
1428
1734
|
}
|
|
1429
1735
|
function useIsSubmitting(form) {
|
|
1430
|
-
return useWatch(form
|
|
1736
|
+
return useWatch(form, "submitting", () => form.isSubmitting);
|
|
1737
|
+
}
|
|
1738
|
+
function useIsLoading(form) {
|
|
1739
|
+
return useWatch(form, "loading", () => form.isLoading);
|
|
1740
|
+
}
|
|
1741
|
+
function useStatus(form) {
|
|
1742
|
+
return useWatch(form, "status", () => form.status);
|
|
1431
1743
|
}
|
|
1432
1744
|
function useCanSubmit(form) {
|
|
1433
1745
|
const { emitter } = form;
|
|
@@ -1448,7 +1760,23 @@
|
|
|
1448
1760
|
);
|
|
1449
1761
|
}
|
|
1450
1762
|
function useSubmitCount(form) {
|
|
1451
|
-
return useWatch(form
|
|
1763
|
+
return useWatch(form, "submitCount", () => form.submitCount);
|
|
1764
|
+
}
|
|
1765
|
+
function useIsValidating(form) {
|
|
1766
|
+
return useWatch(form, "validating", () => form.validating.size > 0);
|
|
1767
|
+
}
|
|
1768
|
+
function useIsSubmitSuccessful(form) {
|
|
1769
|
+
return useWatch(
|
|
1770
|
+
form.emitter,
|
|
1771
|
+
"submitSuccessful",
|
|
1772
|
+
() => !!form.isSubmitSuccessful
|
|
1773
|
+
);
|
|
1774
|
+
}
|
|
1775
|
+
function useFormError(form) {
|
|
1776
|
+
return useErrorByPath(form, create$1(FORM_ERROR))?.message;
|
|
1777
|
+
}
|
|
1778
|
+
function useFormErrors(form) {
|
|
1779
|
+
return useFieldErrorsByPath(form, create$1(FORM_ERROR));
|
|
1452
1780
|
}
|
|
1453
1781
|
|
|
1454
1782
|
function usePath(name) {
|
|
@@ -1468,97 +1796,94 @@
|
|
|
1468
1796
|
[ref]
|
|
1469
1797
|
);
|
|
1470
1798
|
}
|
|
1799
|
+
function useUnmountRestore(teardown, restore) {
|
|
1800
|
+
const removedRef = React.useRef(false);
|
|
1801
|
+
React.useEffect(() => {
|
|
1802
|
+
if (removedRef.current) {
|
|
1803
|
+
removedRef.current = false;
|
|
1804
|
+
restore();
|
|
1805
|
+
}
|
|
1806
|
+
return () => {
|
|
1807
|
+
removedRef.current = true;
|
|
1808
|
+
teardown();
|
|
1809
|
+
};
|
|
1810
|
+
}, []);
|
|
1811
|
+
}
|
|
1471
1812
|
|
|
1472
1813
|
function useValidate(validate, path, formProp, options) {
|
|
1473
1814
|
const contextForm = React.useContext(FormContext);
|
|
1474
1815
|
const form = formProp || contextForm;
|
|
1475
1816
|
if (!form) throw new Error("no form provided");
|
|
1476
|
-
const lockRef = React.useRef(null);
|
|
1477
1817
|
const validateRef = React.useRef(validate);
|
|
1478
1818
|
validateRef.current = validate;
|
|
1479
1819
|
const debounceRef = React.useRef(options?.debounce ?? 0);
|
|
1480
1820
|
debounceRef.current = options?.debounce ?? 0;
|
|
1821
|
+
const syncRef = React.useRef(options?.sync);
|
|
1822
|
+
syncRef.current = options?.sync;
|
|
1823
|
+
const asyncAlwaysRef = React.useRef(options?.asyncAlways ?? false);
|
|
1824
|
+
asyncAlwaysRef.current = options?.asyncAlways ?? false;
|
|
1481
1825
|
React.useEffect(() => {
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1826
|
+
const dispose = registerValidatorByPath(form, path, {
|
|
1827
|
+
validate: () => validateRef.current,
|
|
1828
|
+
debounce: () => debounceRef.current,
|
|
1829
|
+
sync: () => syncRef.current,
|
|
1830
|
+
asyncAlways: () => asyncAlwaysRef.current
|
|
1831
|
+
});
|
|
1832
|
+
const validateOnMount = options?.validateOnMount ?? form.validateOnMount;
|
|
1833
|
+
if (!validateOnMount || !validateRef.current && !syncRef.current) {
|
|
1834
|
+
return dispose;
|
|
1835
|
+
}
|
|
1836
|
+
let disposed = false;
|
|
1837
|
+
const kick = () => {
|
|
1838
|
+
if (disposed) return;
|
|
1839
|
+
form.validators.get(path.key)?.();
|
|
1494
1840
|
};
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
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
|
-
}
|
|
1841
|
+
if (!form.isLoading) {
|
|
1842
|
+
kick();
|
|
1843
|
+
} else {
|
|
1844
|
+
const off = on(form.emitter, "loading", () => {
|
|
1845
|
+
off();
|
|
1846
|
+
kick();
|
|
1534
1847
|
});
|
|
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);
|
|
1848
|
+
}
|
|
1547
1849
|
return () => {
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
clearTimeout(timer);
|
|
1551
|
-
timer = null;
|
|
1552
|
-
}
|
|
1553
|
-
unmark();
|
|
1554
|
-
controller?.abort();
|
|
1850
|
+
disposed = true;
|
|
1851
|
+
dispose();
|
|
1555
1852
|
};
|
|
1556
1853
|
}, [form, path.key]);
|
|
1557
1854
|
return useStageFn(() => form.validators.get(path.key)?.());
|
|
1558
1855
|
}
|
|
1559
1856
|
|
|
1857
|
+
function removeFieldForUnmount(form, path) {
|
|
1858
|
+
const { key } = path;
|
|
1859
|
+
const snapshot = {
|
|
1860
|
+
present: form.values.has(key),
|
|
1861
|
+
value: form.values.get(key),
|
|
1862
|
+
touched: form.touched.has(key),
|
|
1863
|
+
errors: form.errors.get(key)
|
|
1864
|
+
};
|
|
1865
|
+
removeFieldByPath(form, path);
|
|
1866
|
+
return snapshot;
|
|
1867
|
+
}
|
|
1868
|
+
function restoreRemovedField(form, path, snapshot) {
|
|
1869
|
+
const { key } = path;
|
|
1870
|
+
if (snapshot.present) {
|
|
1871
|
+
setValueByPath(form, path, snapshot.value, { shouldDirty: false });
|
|
1872
|
+
} else {
|
|
1873
|
+
form.deleted.delete(key);
|
|
1874
|
+
bumpValuesVersion(form);
|
|
1875
|
+
emit(form.emitter, "change", path);
|
|
1876
|
+
}
|
|
1877
|
+
if (snapshot.touched) setTouchedByPath(form, path);
|
|
1878
|
+
if (snapshot.errors) setErrorByPath(form, path, snapshot.errors);
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1881
|
+
const uncontrolledSyncRegistry = /* @__PURE__ */ new WeakMap();
|
|
1882
|
+
function hasRuleConstraints(rules) {
|
|
1883
|
+
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 || rules.validate !== void 0;
|
|
1884
|
+
}
|
|
1560
1885
|
function combineRulesAndValidate(rules, validate) {
|
|
1561
|
-
if (!rules) return validate;
|
|
1886
|
+
if (!rules || !hasRuleConstraints(rules)) return validate;
|
|
1562
1887
|
const ruleValidator = rulesToValidator(rules);
|
|
1563
1888
|
if (!validate) return ruleValidator;
|
|
1564
1889
|
return (value, meta) => {
|
|
@@ -1590,6 +1915,25 @@
|
|
|
1590
1915
|
}, [errors, delay, shown]);
|
|
1591
1916
|
return delay === void 0 ? errors : shown;
|
|
1592
1917
|
}
|
|
1918
|
+
function useFieldValue(form, path, uncontrolled) {
|
|
1919
|
+
const snapshotRef = React.useRef({
|
|
1920
|
+
has: false,
|
|
1921
|
+
value: void 0
|
|
1922
|
+
});
|
|
1923
|
+
const getter = React.useCallback(() => {
|
|
1924
|
+
if (!uncontrolled) return getValueByPath(form, path);
|
|
1925
|
+
if (!snapshotRef.current.has) {
|
|
1926
|
+
snapshotRef.current = { has: true, value: getValueByPath(form, path) };
|
|
1927
|
+
}
|
|
1928
|
+
return snapshotRef.current.value;
|
|
1929
|
+
}, [uncontrolled, form, path]);
|
|
1930
|
+
const subscribeFactory = React.useCallback(
|
|
1931
|
+
(invalidate) => uncontrolled ? () => {
|
|
1932
|
+
} : onPathEvent(form.emitter, "change", path, "leaf", invalidate),
|
|
1933
|
+
[uncontrolled, form.emitter, path]
|
|
1934
|
+
);
|
|
1935
|
+
return useWatchCore(subscribeFactory, getter);
|
|
1936
|
+
}
|
|
1593
1937
|
function useFieldCore({
|
|
1594
1938
|
form: f1,
|
|
1595
1939
|
name,
|
|
@@ -1599,8 +1943,11 @@
|
|
|
1599
1943
|
rules,
|
|
1600
1944
|
validateDebounce,
|
|
1601
1945
|
validateDeps,
|
|
1946
|
+
validateOnMount,
|
|
1602
1947
|
delayError,
|
|
1603
1948
|
disabled,
|
|
1949
|
+
uncontrolled,
|
|
1950
|
+
asyncAlways,
|
|
1604
1951
|
mode: modeOption
|
|
1605
1952
|
}, Context) {
|
|
1606
1953
|
const contextForm = React.useContext(Context);
|
|
@@ -1618,35 +1965,41 @@
|
|
|
1618
1965
|
seededRef.current = false;
|
|
1619
1966
|
emitChangeByPath(form, path);
|
|
1620
1967
|
});
|
|
1621
|
-
const
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
);
|
|
1968
|
+
const restRules = rules ? { ...rules, required: void 0 } : void 0;
|
|
1969
|
+
useValidate(combineRulesAndValidate(restRules, validate), path, form, {
|
|
1970
|
+
debounce: validateDebounce,
|
|
1971
|
+
validateOnMount,
|
|
1972
|
+
asyncAlways: asyncAlways ?? form.asyncAlways,
|
|
1973
|
+
sync: rules && rules.required !== void 0 ? rulesToValidator({ required: rules.required }) : void 0
|
|
1974
|
+
});
|
|
1629
1975
|
const liveErrors = useFieldErrorsByPath(form, path);
|
|
1630
1976
|
const errors = useDelayedErrors(liveErrors, delayError);
|
|
1631
1977
|
const errorObject = errors[0];
|
|
1632
1978
|
const error = errorObject?.message;
|
|
1633
|
-
const value =
|
|
1634
|
-
const
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1979
|
+
const value = useFieldValue(form, path, !!uncontrolled);
|
|
1980
|
+
const isDirty = useWatchCore(
|
|
1981
|
+
React.useCallback(
|
|
1982
|
+
(invalidate) => uncontrolled ? () => {
|
|
1983
|
+
} : onPathEvent(form.emitter, "change", path, "leaf", invalidate),
|
|
1984
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- usePath memoizes the Path per key, so key pins the subscription like every path-scoped hook
|
|
1985
|
+
[form.emitter, path.key, uncontrolled]
|
|
1986
|
+
),
|
|
1987
|
+
() => isFieldDirtyByPath(form, path)
|
|
1988
|
+
);
|
|
1989
|
+
const validating = useWatchCore(
|
|
1990
|
+
React.useCallback(
|
|
1991
|
+
(invalidate) => onKeyEvent(form.emitter, "validating", path.key, invalidate),
|
|
1992
|
+
[form.emitter, path.key]
|
|
1993
|
+
),
|
|
1994
|
+
() => form.validating.has(path.key)
|
|
1995
|
+
);
|
|
1996
|
+
const formDisabled = useWatch(form, "disabled", () => form.disabled);
|
|
1997
|
+
const onChange = useStageFn((v) => userChangeByPath(form, path, v));
|
|
1998
|
+
const onBlur = useStageFn(() => userBlur(form, path));
|
|
1643
1999
|
React.useEffect(() => {
|
|
1644
|
-
form
|
|
1645
|
-
return () =>
|
|
1646
|
-
|
|
1647
|
-
form.changeHandlers.delete(path.key);
|
|
1648
|
-
};
|
|
1649
|
-
}, [form, path.key, onChange]);
|
|
2000
|
+
const { token, displaced } = registerFieldMode(form, path, modeOption);
|
|
2001
|
+
return () => unregisterFieldMode(form, path, token);
|
|
2002
|
+
}, [form, path.key, modeOption]);
|
|
1650
2003
|
const depsKey = validateDeps?.length ? validateDeps.join("\n") : void 0;
|
|
1651
2004
|
React.useEffect(() => {
|
|
1652
2005
|
if (!depsKey) return;
|
|
@@ -1654,29 +2007,77 @@
|
|
|
1654
2007
|
registerFieldValidateDeps(form, path.key, depKeys);
|
|
1655
2008
|
return () => unregisterFieldValidateDeps(form, path.key, depKeys);
|
|
1656
2009
|
}, [form, path.key, depsKey]);
|
|
1657
|
-
const
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
});
|
|
2010
|
+
const elementRef = React.useRef(null);
|
|
2011
|
+
const focusRef = React.useCallback((el) => {
|
|
2012
|
+
elementRef.current = el;
|
|
2013
|
+
}, []);
|
|
1662
2014
|
React.useEffect(
|
|
1663
|
-
() => (
|
|
1664
|
-
|
|
1665
|
-
|
|
2015
|
+
() => on(
|
|
2016
|
+
form.emitter,
|
|
2017
|
+
"focusError",
|
|
2018
|
+
(key, options) => {
|
|
2019
|
+
if (key !== path.key) return;
|
|
2020
|
+
const el = elementRef.current;
|
|
2021
|
+
if (!el || typeof el.focus !== "function") return;
|
|
2022
|
+
el.focus();
|
|
2023
|
+
if (options?.shouldSelect && typeof el.select === "function") {
|
|
2024
|
+
el.select();
|
|
2025
|
+
}
|
|
1666
2026
|
}
|
|
1667
|
-
|
|
1668
|
-
[
|
|
2027
|
+
),
|
|
2028
|
+
[form, path.key]
|
|
1669
2029
|
);
|
|
2030
|
+
React.useEffect(() => {
|
|
2031
|
+
if (!uncontrolled) return;
|
|
2032
|
+
let entry = uncontrolledSyncRegistry.get(form);
|
|
2033
|
+
if (!entry) {
|
|
2034
|
+
const cells = /* @__PURE__ */ new Map();
|
|
2035
|
+
const off = on(form.emitter, "change", (changed) => {
|
|
2036
|
+
if (changed) return;
|
|
2037
|
+
for (const read of cells.values()) {
|
|
2038
|
+
const { el, path: path2 } = read();
|
|
2039
|
+
if (!el || el.type === "file") continue;
|
|
2040
|
+
const next = getValueByPath(form, path2);
|
|
2041
|
+
const asString = next == null ? "" : String(next);
|
|
2042
|
+
if (el.value !== asString) el.value = asString;
|
|
2043
|
+
}
|
|
2044
|
+
});
|
|
2045
|
+
entry = { cells, off };
|
|
2046
|
+
uncontrolledSyncRegistry.set(form, entry);
|
|
2047
|
+
}
|
|
2048
|
+
entry.cells.set(path.key, () => ({ el: elementRef.current, path }));
|
|
2049
|
+
return () => {
|
|
2050
|
+
entry.cells.delete(path.key);
|
|
2051
|
+
if (entry.cells.size === 0) {
|
|
2052
|
+
entry.off();
|
|
2053
|
+
uncontrolledSyncRegistry.delete(form);
|
|
2054
|
+
}
|
|
2055
|
+
};
|
|
2056
|
+
}, [form, path.key, uncontrolled]);
|
|
2057
|
+
const removalSnapshotRef = React.useRef(null);
|
|
2058
|
+
const teardownOnUnmount = useStageFn(() => {
|
|
2059
|
+
if ((shouldUnregister ?? form.shouldUnregister) === false) return;
|
|
2060
|
+
removalSnapshotRef.current = removeFieldForUnmount(form, path);
|
|
2061
|
+
});
|
|
2062
|
+
const restoreAfterStrictMode = useStageFn(() => {
|
|
2063
|
+
const snapshot = removalSnapshotRef.current;
|
|
2064
|
+
removalSnapshotRef.current = null;
|
|
2065
|
+
if (snapshot) restoreRemovedField(form, path, snapshot);
|
|
2066
|
+
});
|
|
2067
|
+
useUnmountRestore(teardownOnUnmount, restoreAfterStrictMode);
|
|
1670
2068
|
return {
|
|
1671
2069
|
form,
|
|
1672
2070
|
value,
|
|
1673
2071
|
error,
|
|
1674
2072
|
errorObject,
|
|
1675
2073
|
errors,
|
|
2074
|
+
isDirty,
|
|
2075
|
+
validating,
|
|
1676
2076
|
onChange,
|
|
1677
2077
|
onBlur,
|
|
1678
2078
|
name: path.key,
|
|
1679
|
-
disabled: formDisabled || !!disabled
|
|
2079
|
+
disabled: formDisabled || !!disabled,
|
|
2080
|
+
focusRef
|
|
1680
2081
|
};
|
|
1681
2082
|
}
|
|
1682
2083
|
function useField(options) {
|
|
@@ -1708,6 +2109,8 @@
|
|
|
1708
2109
|
const contextForm = React.useContext(Context);
|
|
1709
2110
|
const form = options.form || contextForm;
|
|
1710
2111
|
if (!form) throw new Error("no form provided");
|
|
2112
|
+
const keyName = options.keyName ?? "id";
|
|
2113
|
+
const { rules, shouldUnregister } = options;
|
|
1711
2114
|
const path = usePath(options.name);
|
|
1712
2115
|
const idsRef = React.useRef([]);
|
|
1713
2116
|
const getArray = React.useCallback(
|
|
@@ -1728,8 +2131,12 @@
|
|
|
1728
2131
|
while (idsRef.current.length > arr.length) {
|
|
1729
2132
|
idsRef.current.pop();
|
|
1730
2133
|
}
|
|
1731
|
-
return idsRef.current.map((id, index) => ({
|
|
1732
|
-
|
|
2134
|
+
return idsRef.current.map((id, index) => ({
|
|
2135
|
+
id,
|
|
2136
|
+
index,
|
|
2137
|
+
[keyName]: id
|
|
2138
|
+
}));
|
|
2139
|
+
}, [getArray, form, keyName]);
|
|
1733
2140
|
const [fields, syncFields] = React.useReducer(
|
|
1734
2141
|
computeFields,
|
|
1735
2142
|
void 0,
|
|
@@ -1747,6 +2154,25 @@
|
|
|
1747
2154
|
if (registry?.get(path.key) === idsRef.current) registry.delete(path.key);
|
|
1748
2155
|
};
|
|
1749
2156
|
}, [form, path.key]);
|
|
2157
|
+
const removalSnapshotRef = React.useRef(null);
|
|
2158
|
+
const teardownOnUnmount = useStageFn(() => {
|
|
2159
|
+
if ((shouldUnregister ?? form.shouldUnregister) === false) return;
|
|
2160
|
+
removalSnapshotRef.current = removeFieldForUnmount(form, path);
|
|
2161
|
+
});
|
|
2162
|
+
const restoreAfterStrictMode = useStageFn(() => {
|
|
2163
|
+
const snapshot = removalSnapshotRef.current;
|
|
2164
|
+
removalSnapshotRef.current = null;
|
|
2165
|
+
if (snapshot) restoreRemovedField(form, path, snapshot);
|
|
2166
|
+
});
|
|
2167
|
+
useUnmountRestore(teardownOnUnmount, restoreAfterStrictMode);
|
|
2168
|
+
useValidate(
|
|
2169
|
+
rules ? rulesToValidator({ ...rules, required: void 0 }) : void 0,
|
|
2170
|
+
path,
|
|
2171
|
+
form,
|
|
2172
|
+
{
|
|
2173
|
+
sync: rules && rules.required !== void 0 ? rulesToValidator({ required: rules.required }) : void 0
|
|
2174
|
+
}
|
|
2175
|
+
);
|
|
1750
2176
|
const append = useStageFn((value) => {
|
|
1751
2177
|
const arr = getArray();
|
|
1752
2178
|
idsRef.current.push(generateId(form));
|
|
@@ -1905,29 +2331,108 @@
|
|
|
1905
2331
|
return group;
|
|
1906
2332
|
}
|
|
1907
2333
|
|
|
2334
|
+
function useTransform(form, name, options = {}) {
|
|
2335
|
+
const path = usePath(name);
|
|
2336
|
+
const { toDisplay, fromDisplay } = options;
|
|
2337
|
+
const subscribeFactory = React.useCallback(
|
|
2338
|
+
(invalidate) => onPathEvent(form.emitter, "change", path, "leaf", invalidate),
|
|
2339
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- usePath memoizes the Path per key, so key pins the subscription like every path-scoped hook
|
|
2340
|
+
[form.emitter, path.key]
|
|
2341
|
+
);
|
|
2342
|
+
const raw = useWatchCore(subscribeFactory, () => getValueByPath(form, path));
|
|
2343
|
+
const value = toDisplay ? toDisplay(raw) : raw;
|
|
2344
|
+
const onChange = React.useCallback(
|
|
2345
|
+
(display) => {
|
|
2346
|
+
userChangeByPath(
|
|
2347
|
+
form,
|
|
2348
|
+
path,
|
|
2349
|
+
fromDisplay ? fromDisplay(display) : display
|
|
2350
|
+
);
|
|
2351
|
+
},
|
|
2352
|
+
[form, path, fromDisplay]
|
|
2353
|
+
);
|
|
2354
|
+
return { value, onChange };
|
|
2355
|
+
}
|
|
2356
|
+
|
|
2357
|
+
function appendFormDataValue(fd, key, value) {
|
|
2358
|
+
if (value == null) return;
|
|
2359
|
+
if (Array.isArray(value)) {
|
|
2360
|
+
for (const item of value) appendFormDataValue(fd, key, item);
|
|
2361
|
+
return;
|
|
2362
|
+
}
|
|
2363
|
+
if (typeof FileList !== "undefined" && value instanceof FileList) {
|
|
2364
|
+
for (let i = 0; i < value.length; i++) fd.append(key, value.item(i));
|
|
2365
|
+
return;
|
|
2366
|
+
}
|
|
2367
|
+
if (typeof File !== "undefined" && value instanceof File) {
|
|
2368
|
+
fd.append(key, value, value.name);
|
|
2369
|
+
return;
|
|
2370
|
+
}
|
|
2371
|
+
if (typeof Blob !== "undefined" && value instanceof Blob) {
|
|
2372
|
+
fd.append(key, value);
|
|
2373
|
+
return;
|
|
2374
|
+
}
|
|
2375
|
+
if (value instanceof Date) {
|
|
2376
|
+
fd.append(key, value.toISOString());
|
|
2377
|
+
return;
|
|
2378
|
+
}
|
|
2379
|
+
fd.append(
|
|
2380
|
+
key,
|
|
2381
|
+
typeof value === "object" ? JSON.stringify(value) : String(value)
|
|
2382
|
+
);
|
|
2383
|
+
}
|
|
2384
|
+
function formDataFromValues(values) {
|
|
2385
|
+
const fd = new FormData();
|
|
2386
|
+
for (const key of Object.keys(values)) {
|
|
2387
|
+
appendFormDataValue(fd, key, values[key]);
|
|
2388
|
+
}
|
|
2389
|
+
return fd;
|
|
2390
|
+
}
|
|
2391
|
+
|
|
1908
2392
|
function Form({
|
|
1909
2393
|
form: f1,
|
|
1910
2394
|
context,
|
|
1911
2395
|
initialValues,
|
|
1912
2396
|
values,
|
|
2397
|
+
shouldUnregister,
|
|
2398
|
+
validateOnMount,
|
|
2399
|
+
disabled,
|
|
2400
|
+
asyncAlways,
|
|
1913
2401
|
onSubmit,
|
|
1914
2402
|
onValidSubmit,
|
|
1915
2403
|
onInvalidSubmit,
|
|
2404
|
+
action,
|
|
1916
2405
|
shouldFocusError,
|
|
1917
2406
|
...props
|
|
1918
2407
|
}) {
|
|
1919
|
-
const f2 = useForm({
|
|
2408
|
+
const f2 = useForm({
|
|
2409
|
+
initialValues,
|
|
2410
|
+
values,
|
|
2411
|
+
shouldUnregister,
|
|
2412
|
+
validateOnMount,
|
|
2413
|
+
disabled,
|
|
2414
|
+
asyncAlways
|
|
2415
|
+
});
|
|
1920
2416
|
const form = f1 || f2;
|
|
2417
|
+
React__namespace.useEffect(() => {
|
|
2418
|
+
if (disabled !== void 0) setDisabled(form, disabled);
|
|
2419
|
+
}, [form, disabled]);
|
|
1921
2420
|
const submit = handleSubmit(form, {
|
|
1922
2421
|
onSubmit,
|
|
1923
2422
|
onValidSubmit,
|
|
1924
2423
|
onInvalidSubmit,
|
|
1925
|
-
shouldFocusError
|
|
2424
|
+
shouldFocusError,
|
|
2425
|
+
onAction: action ? (values2) => action(formDataFromValues(values2)) : void 0
|
|
1926
2426
|
});
|
|
1927
2427
|
const { Provider } = context ?? FormContext;
|
|
1928
2428
|
return /* @__PURE__ */ React__namespace.createElement(Provider, { value: form }, /* @__PURE__ */ React__namespace.createElement("form", { ...props, noValidate: true, onSubmit: submit }));
|
|
1929
2429
|
}
|
|
1930
2430
|
|
|
2431
|
+
function FormField({ children, ...options }) {
|
|
2432
|
+
const field = useField(options);
|
|
2433
|
+
return children(field);
|
|
2434
|
+
}
|
|
2435
|
+
|
|
1931
2436
|
function setRef(ref, value) {
|
|
1932
2437
|
if (typeof ref === "function") {
|
|
1933
2438
|
ref(value);
|
|
@@ -1962,28 +2467,26 @@
|
|
|
1962
2467
|
shouldUnregister,
|
|
1963
2468
|
rules,
|
|
1964
2469
|
validateDebounce,
|
|
2470
|
+
validateOnMount,
|
|
2471
|
+
valueAsNumber,
|
|
2472
|
+
valueAsDate,
|
|
2473
|
+
asyncAlways,
|
|
1965
2474
|
disabled,
|
|
1966
2475
|
delayError,
|
|
1967
2476
|
mode,
|
|
2477
|
+
uncontrolled,
|
|
1968
2478
|
...props
|
|
1969
2479
|
}, ref) => {
|
|
1970
2480
|
const innerRef = React__namespace.useRef(null);
|
|
1971
2481
|
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
2482
|
const {
|
|
1980
2483
|
value,
|
|
1981
2484
|
onChange,
|
|
1982
2485
|
onBlur,
|
|
1983
2486
|
error,
|
|
1984
|
-
form,
|
|
1985
2487
|
name: fieldKey,
|
|
1986
|
-
disabled: isDisabled
|
|
2488
|
+
disabled: isDisabled,
|
|
2489
|
+
focusRef
|
|
1987
2490
|
} = useField({
|
|
1988
2491
|
name,
|
|
1989
2492
|
form: formProp,
|
|
@@ -1991,9 +2494,14 @@
|
|
|
1991
2494
|
shouldUnregister,
|
|
1992
2495
|
rules,
|
|
1993
2496
|
validateDebounce,
|
|
2497
|
+
validateOnMount,
|
|
1994
2498
|
delayError,
|
|
1995
2499
|
disabled,
|
|
2500
|
+
asyncAlways,
|
|
1996
2501
|
mode,
|
|
2502
|
+
// File inputs cannot be value-controlled at all — force the
|
|
2503
|
+
// uncontrolled path so no `value` prop ever reaches the element.
|
|
2504
|
+
uncontrolled: uncontrolled || props.type === "file",
|
|
1997
2505
|
validate: (...params) => {
|
|
1998
2506
|
const el = innerRef.current;
|
|
1999
2507
|
if (el && typeof el.checkValidity === "function") {
|
|
@@ -2006,6 +2514,14 @@
|
|
|
2006
2514
|
if (validate) return validate(...params);
|
|
2007
2515
|
}
|
|
2008
2516
|
});
|
|
2517
|
+
const mergedRef = React__namespace.useCallback(
|
|
2518
|
+
(node) => {
|
|
2519
|
+
innerRef.current = node;
|
|
2520
|
+
focusRef(node);
|
|
2521
|
+
setRef(ref, node);
|
|
2522
|
+
},
|
|
2523
|
+
[ref, focusRef]
|
|
2524
|
+
);
|
|
2009
2525
|
const Component = as || "input";
|
|
2010
2526
|
React__namespace.useEffect(() => {
|
|
2011
2527
|
const el = innerRef.current;
|
|
@@ -2020,32 +2536,20 @@
|
|
|
2020
2536
|
React__namespace.useEffect(() => {
|
|
2021
2537
|
if (nativeInvalidCount > 0) innerRef.current?.reportValidity();
|
|
2022
2538
|
}, [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);
|
|
2539
|
+
const isFile = props.type === "file";
|
|
2540
|
+
const toValue = eventToValue ?? (isFile ? (e) => e.target.files : valueAsNumber ? (e) => e.target.valueAsNumber : valueAsDate ? (e) => e.target.valueAsDate : (e) => e.target.value);
|
|
2541
|
+
const valueProps = valueToProps ? valueToProps(value) : isFile ? {} : uncontrolled ? { defaultValue: value } : { value };
|
|
2040
2542
|
const errorId = errorIdFromKey(fieldKey);
|
|
2543
|
+
const constraintAttrs = rules ? rulesToConstraintAttrs(rules) : void 0;
|
|
2041
2544
|
return /* @__PURE__ */ React__namespace.createElement(React__namespace.Fragment, null, /* @__PURE__ */ React__namespace.createElement(
|
|
2042
2545
|
Component,
|
|
2043
2546
|
{
|
|
2547
|
+
...constraintAttrs,
|
|
2044
2548
|
...props,
|
|
2045
2549
|
name: fieldKey,
|
|
2046
2550
|
onBlur,
|
|
2047
2551
|
...asProps,
|
|
2048
|
-
...
|
|
2552
|
+
...valueProps,
|
|
2049
2553
|
...ariaProps(error, fieldKey, props),
|
|
2050
2554
|
disabled: isDisabled,
|
|
2051
2555
|
onChange: (e) => onChange(toValue(e)),
|
|
@@ -2063,6 +2567,8 @@
|
|
|
2063
2567
|
validate,
|
|
2064
2568
|
rules,
|
|
2065
2569
|
validateDebounce,
|
|
2570
|
+
validateOnMount,
|
|
2571
|
+
asyncAlways,
|
|
2066
2572
|
disabled,
|
|
2067
2573
|
delayError,
|
|
2068
2574
|
mode,
|
|
@@ -2083,13 +2589,17 @@
|
|
|
2083
2589
|
validate,
|
|
2084
2590
|
rules,
|
|
2085
2591
|
validateDebounce,
|
|
2592
|
+
validateOnMount,
|
|
2593
|
+
asyncAlways,
|
|
2086
2594
|
delayError,
|
|
2087
2595
|
disabled,
|
|
2088
2596
|
mode
|
|
2089
2597
|
});
|
|
2598
|
+
const constraintAttrs = rules ? rulesToConstraintAttrs(rules) : void 0;
|
|
2090
2599
|
return /* @__PURE__ */ React__namespace.createElement(
|
|
2091
2600
|
"input",
|
|
2092
2601
|
{
|
|
2602
|
+
...constraintAttrs,
|
|
2093
2603
|
...props,
|
|
2094
2604
|
name: fieldKey,
|
|
2095
2605
|
onBlur,
|
|
@@ -2118,6 +2628,8 @@
|
|
|
2118
2628
|
validate,
|
|
2119
2629
|
rules,
|
|
2120
2630
|
validateDebounce,
|
|
2631
|
+
validateOnMount,
|
|
2632
|
+
asyncAlways,
|
|
2121
2633
|
disabled,
|
|
2122
2634
|
delayError,
|
|
2123
2635
|
mode,
|
|
@@ -2138,13 +2650,17 @@
|
|
|
2138
2650
|
validate,
|
|
2139
2651
|
rules,
|
|
2140
2652
|
validateDebounce,
|
|
2653
|
+
validateOnMount,
|
|
2654
|
+
asyncAlways,
|
|
2141
2655
|
delayError,
|
|
2142
2656
|
disabled,
|
|
2143
2657
|
mode
|
|
2144
2658
|
});
|
|
2659
|
+
const constraintAttrs = rules ? rulesToConstraintAttrs(rules) : void 0;
|
|
2145
2660
|
return /* @__PURE__ */ React__namespace.createElement(
|
|
2146
2661
|
"select",
|
|
2147
2662
|
{
|
|
2663
|
+
...constraintAttrs,
|
|
2148
2664
|
...props,
|
|
2149
2665
|
name: fieldKey,
|
|
2150
2666
|
onBlur,
|
|
@@ -2165,9 +2681,11 @@
|
|
|
2165
2681
|
exports.Checkbox = Checkbox;
|
|
2166
2682
|
exports.CheckboxGroupContext = CheckboxGroupContext;
|
|
2167
2683
|
exports.CheckboxGroupProvider = CheckboxGroupProvider;
|
|
2684
|
+
exports.FORM_ERROR = FORM_ERROR;
|
|
2168
2685
|
exports.Field = Field;
|
|
2169
2686
|
exports.Form = Form;
|
|
2170
2687
|
exports.FormContext = FormContext;
|
|
2688
|
+
exports.FormField = FormField;
|
|
2171
2689
|
exports.FormProvider = FormProvider;
|
|
2172
2690
|
exports.Select = Select;
|
|
2173
2691
|
exports.VALIDATION_OUTCOME = VALIDATION_OUTCOME;
|
|
@@ -2197,14 +2715,18 @@
|
|
|
2197
2715
|
exports.hasTouchedByPath = hasTouchedByPath;
|
|
2198
2716
|
exports.incrementSubmitCount = incrementSubmitCount;
|
|
2199
2717
|
exports.isDirty = isDirty;
|
|
2718
|
+
exports.isFieldDirtyByPath = isFieldDirtyByPath;
|
|
2200
2719
|
exports.isTouched = isTouched;
|
|
2720
|
+
exports.registerFieldMode = registerFieldMode;
|
|
2201
2721
|
exports.registerFieldValidateDeps = registerFieldValidateDeps;
|
|
2722
|
+
exports.registerValidatorByPath = registerValidatorByPath;
|
|
2202
2723
|
exports.removeField = removeField;
|
|
2203
2724
|
exports.removeFieldByPath = removeFieldByPath;
|
|
2204
2725
|
exports.reset = reset;
|
|
2205
2726
|
exports.resetField = resetField;
|
|
2206
2727
|
exports.revalidateDependentsOnChange = revalidateDependentsOnChange;
|
|
2207
2728
|
exports.revalidateFormOnChange = revalidateFormOnChange;
|
|
2729
|
+
exports.runFormValidate = runFormValidate;
|
|
2208
2730
|
exports.seedValueByPath = seedValueByPath;
|
|
2209
2731
|
exports.setDisabled = setDisabled;
|
|
2210
2732
|
exports.setError = setError;
|
|
@@ -2213,6 +2735,7 @@
|
|
|
2213
2735
|
exports.setInitialValues = setInitialValues;
|
|
2214
2736
|
exports.setIsSubmitting = setIsSubmitting;
|
|
2215
2737
|
exports.setServerErrors = setServerErrors;
|
|
2738
|
+
exports.setStatus = setStatus;
|
|
2216
2739
|
exports.setSubmitSuccessful = setSubmitSuccessful;
|
|
2217
2740
|
exports.setTouched = setTouched;
|
|
2218
2741
|
exports.setTouchedByPath = setTouchedByPath;
|
|
@@ -2221,6 +2744,7 @@
|
|
|
2221
2744
|
exports.setValueByPath = setValueByPath;
|
|
2222
2745
|
exports.subscribe = subscribe;
|
|
2223
2746
|
exports.trigger = trigger;
|
|
2747
|
+
exports.unregisterFieldMode = unregisterFieldMode;
|
|
2224
2748
|
exports.unregisterFieldValidateDeps = unregisterFieldValidateDeps;
|
|
2225
2749
|
exports.unsetValidatingByPath = unsetValidatingByPath;
|
|
2226
2750
|
exports.useCanSubmit = useCanSubmit;
|
|
@@ -2235,16 +2759,30 @@
|
|
|
2235
2759
|
exports.useFieldErrorsByPath = useFieldErrorsByPath;
|
|
2236
2760
|
exports.useForm = useForm;
|
|
2237
2761
|
exports.useFormContext = useFormContext;
|
|
2762
|
+
exports.useFormError = useFormError;
|
|
2763
|
+
exports.useFormErrors = useFormErrors;
|
|
2764
|
+
exports.useFormState = useFormState;
|
|
2238
2765
|
exports.useHasErrors = useHasErrors;
|
|
2239
2766
|
exports.useIsDirty = useIsDirty;
|
|
2767
|
+
exports.useIsFieldDirty = useIsFieldDirty;
|
|
2768
|
+
exports.useIsFieldDirtyByPath = useIsFieldDirtyByPath;
|
|
2769
|
+
exports.useIsLoading = useIsLoading;
|
|
2770
|
+
exports.useIsSubmitSuccessful = useIsSubmitSuccessful;
|
|
2240
2771
|
exports.useIsSubmitting = useIsSubmitting;
|
|
2772
|
+
exports.useIsValid = useIsValid;
|
|
2773
|
+
exports.useIsValidating = useIsValidating;
|
|
2774
|
+
exports.useStatus = useStatus;
|
|
2241
2775
|
exports.useSubmitCount = useSubmitCount;
|
|
2242
2776
|
exports.useTouched = useTouched;
|
|
2243
2777
|
exports.useTouchedByPath = useTouchedByPath;
|
|
2244
2778
|
exports.useTouchedFields = useTouchedFields;
|
|
2779
|
+
exports.useTransform = useTransform;
|
|
2245
2780
|
exports.useValue = useValue;
|
|
2246
2781
|
exports.useValueByPath = useValueByPath;
|
|
2247
2782
|
exports.useWatch = useWatch;
|
|
2783
|
+
exports.useWatchCore = useWatchCore;
|
|
2784
|
+
exports.userBlur = userBlur;
|
|
2785
|
+
exports.userChangeByPath = userChangeByPath;
|
|
2248
2786
|
exports.validate = validate;
|
|
2249
2787
|
|
|
2250
2788
|
}));
|