react-f0rm 0.2.2 → 0.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 +527 -33
- package/dist/devtools/index.cjs.js +737 -0
- package/dist/devtools/index.cjs.js.map +1 -0
- package/dist/devtools/index.d.ts +33 -0
- package/dist/devtools/index.mjs +717 -0
- package/dist/devtools/index.mjs.map +1 -0
- package/dist/form-61297bc0.d.ts +578 -0
- package/dist/form-94c70b4b.mjs +378 -0
- package/dist/form-94c70b4b.mjs.map +1 -0
- package/dist/form-b9441d8c.cjs.js +387 -0
- package/dist/form-b9441d8c.cjs.js.map +1 -0
- package/dist/index.cjs.js +1257 -157
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +357 -53
- package/dist/index.mjs +1676 -0
- package/dist/index.mjs.map +1 -0
- package/dist/index.umd.js +1257 -157
- 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/resolvers/standard-schema.cjs.js +90 -0
- package/dist/resolvers/standard-schema.cjs.js.map +1 -0
- package/dist/resolvers/standard-schema.d.ts +66 -0
- package/dist/resolvers/standard-schema.mjs +86 -0
- package/dist/resolvers/standard-schema.mjs.map +1 -0
- package/dist/resolvers/yup.cjs.js +12 -2
- package/dist/resolvers/yup.cjs.js.map +1 -1
- package/dist/resolvers/yup.d.ts +2 -2
- package/dist/resolvers/yup.mjs +23 -0
- package/dist/resolvers/yup.mjs.map +1 -0
- package/dist/resolvers/zod.cjs.js +14 -1
- package/dist/resolvers/zod.cjs.js.map +1 -1
- package/dist/resolvers/zod.d.ts +2 -2
- package/dist/resolvers/zod.mjs +23 -0
- package/dist/resolvers/zod.mjs.map +1 -0
- package/dist/validate-148fe167.d.ts +22 -0
- package/package.json +34 -8
- package/dist/form-d06e6444.d.ts +0 -201
- package/dist/index.esm.js +0 -593
- package/dist/index.esm.js.map +0 -1
- package/dist/resolvers/yup.esm.js +0 -13
- package/dist/resolvers/yup.esm.js.map +0 -1
- package/dist/resolvers/zod.esm.js +0 -10
- package/dist/resolvers/zod.esm.js.map +0 -1
- package/dist/validate-0f17f86a.d.ts +0 -8
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1676 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import React__default, { useState, useRef, useEffect, useCallback, useMemo, useContext, useReducer, createContext, createElement } from 'react';
|
|
3
|
+
|
|
4
|
+
function getSet(ee, key) {
|
|
5
|
+
var set = ee.get(key);
|
|
6
|
+
if (set) return set;
|
|
7
|
+
var newSet = new Set();
|
|
8
|
+
ee.set(key, newSet);
|
|
9
|
+
return newSet;
|
|
10
|
+
}
|
|
11
|
+
function create$2() {
|
|
12
|
+
return new Map();
|
|
13
|
+
}
|
|
14
|
+
function emit$1(ee, key) {
|
|
15
|
+
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
|
16
|
+
args[_key - 2] = arguments[_key];
|
|
17
|
+
}
|
|
18
|
+
(ee.get(key) || []).forEach(function (h) {
|
|
19
|
+
return h.apply(void 0, args);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function on(ee, key, handler) {
|
|
23
|
+
var set = getSet(ee, key);
|
|
24
|
+
set.add(handler);
|
|
25
|
+
return function () {
|
|
26
|
+
return set.delete(handler);
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const pathCache = /* @__PURE__ */ new Map();
|
|
31
|
+
function normalizePath(path) {
|
|
32
|
+
if (Array.isArray(path)) return path;
|
|
33
|
+
const cached = pathCache.get(path);
|
|
34
|
+
if (cached) return cached;
|
|
35
|
+
const value = parsePath(path);
|
|
36
|
+
pathCache.set(path, value);
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
function parsePath(path) {
|
|
40
|
+
const result = [];
|
|
41
|
+
let identifier = "";
|
|
42
|
+
const flushIdentifier = () => {
|
|
43
|
+
result.push(identifier);
|
|
44
|
+
identifier = "";
|
|
45
|
+
};
|
|
46
|
+
for (let i = 0; i < path.length; i++) {
|
|
47
|
+
const char = path[i];
|
|
48
|
+
if (char === ".") {
|
|
49
|
+
if (identifier !== "") flushIdentifier();
|
|
50
|
+
} else if (char === "[") {
|
|
51
|
+
if (identifier !== "") flushIdentifier();
|
|
52
|
+
const quote = path[i + 1];
|
|
53
|
+
if (quote === '"' || quote === "'") {
|
|
54
|
+
const close = path.indexOf(quote, i + 2);
|
|
55
|
+
if (close === -1) {
|
|
56
|
+
throw new TypeError(`Unterminated quote in path: ${path}`);
|
|
57
|
+
}
|
|
58
|
+
if (path[close + 1] !== "]") {
|
|
59
|
+
throw new TypeError(
|
|
60
|
+
`Expected "]" after quoted segment in path: ${path}`
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
result.push(path.slice(i + 2, close));
|
|
64
|
+
i = close + 1;
|
|
65
|
+
} else {
|
|
66
|
+
const close = path.indexOf("]", i + 1);
|
|
67
|
+
if (close === -1) {
|
|
68
|
+
throw new TypeError(`Unterminated bracket in path: ${path}`);
|
|
69
|
+
}
|
|
70
|
+
const content = path.slice(i + 1, close);
|
|
71
|
+
result.push(/^-?\d+$/.test(content) ? Number(content) : content);
|
|
72
|
+
i = close;
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
identifier += char;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (identifier !== "" || result.length === 0) flushIdentifier();
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
function get(values, path) {
|
|
82
|
+
return path.reduce((current, p) => {
|
|
83
|
+
if (current == null) return void 0;
|
|
84
|
+
return current[p];
|
|
85
|
+
}, values);
|
|
86
|
+
}
|
|
87
|
+
function unset(values, path) {
|
|
88
|
+
if (!path.length || values == null) return values;
|
|
89
|
+
const [prop, ...props] = path;
|
|
90
|
+
if (props.length) {
|
|
91
|
+
const next = unset(values[prop], props);
|
|
92
|
+
return next === values[prop] ? values : set(values, path, next);
|
|
93
|
+
}
|
|
94
|
+
if (Array.isArray(values)) {
|
|
95
|
+
if (!(prop in values)) return values;
|
|
96
|
+
const arr = values.slice();
|
|
97
|
+
delete arr[prop];
|
|
98
|
+
return arr;
|
|
99
|
+
}
|
|
100
|
+
if (typeof values !== "object" || !(prop in values)) return values;
|
|
101
|
+
const copy = { ...values };
|
|
102
|
+
delete copy[prop];
|
|
103
|
+
return copy;
|
|
104
|
+
}
|
|
105
|
+
function set(values, path, value) {
|
|
106
|
+
if (!path.length) return value;
|
|
107
|
+
const [prop, ...props] = path;
|
|
108
|
+
if (typeof prop === "number") {
|
|
109
|
+
const arr = Array.isArray(values) ? values.slice() : [];
|
|
110
|
+
arr[prop] = set(arr[prop], props, value);
|
|
111
|
+
return arr;
|
|
112
|
+
}
|
|
113
|
+
return { ...values, [prop]: set(values && values[prop], props, value) };
|
|
114
|
+
}
|
|
115
|
+
function setOwned(root, path, value, owned) {
|
|
116
|
+
if (!path.length) return value;
|
|
117
|
+
let container = root;
|
|
118
|
+
let parent = null;
|
|
119
|
+
let parentProp = "";
|
|
120
|
+
for (let i = 0; i < path.length; i++) {
|
|
121
|
+
const prop = path[i];
|
|
122
|
+
if (!owned.has(container)) {
|
|
123
|
+
let copy;
|
|
124
|
+
if (typeof prop === "number") {
|
|
125
|
+
copy = Array.isArray(container) ? container.slice() : [];
|
|
126
|
+
} else {
|
|
127
|
+
copy = { ...container };
|
|
128
|
+
}
|
|
129
|
+
owned.add(copy);
|
|
130
|
+
if (i === 0) root = copy;
|
|
131
|
+
else parent[parentProp] = copy;
|
|
132
|
+
container = copy;
|
|
133
|
+
}
|
|
134
|
+
if (i === path.length - 1) {
|
|
135
|
+
container[prop] = value;
|
|
136
|
+
} else {
|
|
137
|
+
parent = container;
|
|
138
|
+
parentProp = prop;
|
|
139
|
+
container = container[prop];
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return root;
|
|
143
|
+
}
|
|
144
|
+
function isPromise(value) {
|
|
145
|
+
return value && typeof value.then === "function";
|
|
146
|
+
}
|
|
147
|
+
function waitUntil(emitter, event, isResolve, isReject) {
|
|
148
|
+
return new Promise((resolve, reject) => {
|
|
149
|
+
if (isReject()) return void reject();
|
|
150
|
+
if (isResolve()) return void resolve();
|
|
151
|
+
const off = on(emitter, event, () => {
|
|
152
|
+
if (isReject()) {
|
|
153
|
+
off();
|
|
154
|
+
reject();
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (!isResolve()) return;
|
|
158
|
+
off();
|
|
159
|
+
resolve();
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function create$1(name) {
|
|
165
|
+
const value = normalizePath(name);
|
|
166
|
+
return { value, key: JSON.stringify(value) };
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const emit = emit$1;
|
|
170
|
+
const VALIDATION_OUTCOME = /* @__PURE__ */ Symbol("validation-outcome");
|
|
171
|
+
function create(options) {
|
|
172
|
+
const emitter = create$2();
|
|
173
|
+
return {
|
|
174
|
+
emitter,
|
|
175
|
+
...options,
|
|
176
|
+
mode: options?.mode ?? "onSubmit",
|
|
177
|
+
reValidateMode: options?.reValidateMode ?? "onChange",
|
|
178
|
+
disabled: options?.disabled ?? false,
|
|
179
|
+
initialValues: options?.initialValues ?? {},
|
|
180
|
+
values: /* @__PURE__ */ new Map(),
|
|
181
|
+
deleted: /* @__PURE__ */ new Set(),
|
|
182
|
+
errors: /* @__PURE__ */ new Map(),
|
|
183
|
+
touched: /* @__PURE__ */ new Set(),
|
|
184
|
+
validators: /* @__PURE__ */ new Map(),
|
|
185
|
+
validating: /* @__PURE__ */ new Set(),
|
|
186
|
+
parsedValues: void 0,
|
|
187
|
+
isSubmitting: false,
|
|
188
|
+
submitCount: 0,
|
|
189
|
+
isSubmitSuccessful: void 0
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function getValues(form) {
|
|
193
|
+
const { initialValues, parsedValues, values, deleted } = form;
|
|
194
|
+
const owned = /* @__PURE__ */ new Set();
|
|
195
|
+
let merged = parsedValues ?? initialValues;
|
|
196
|
+
for (const [key, value] of values) {
|
|
197
|
+
merged = setOwned(merged, JSON.parse(key), value, owned);
|
|
198
|
+
}
|
|
199
|
+
for (const key of deleted) {
|
|
200
|
+
merged = unset(merged, JSON.parse(key));
|
|
201
|
+
}
|
|
202
|
+
return merged;
|
|
203
|
+
}
|
|
204
|
+
function getValue(form, name) {
|
|
205
|
+
return getValueByPath(form, create$1(name));
|
|
206
|
+
}
|
|
207
|
+
function getValueByPath({ initialValues, parsedValues, values, deleted }, path) {
|
|
208
|
+
if (values.has(path.key)) return values.get(path.key);
|
|
209
|
+
if (deleted.has(path.key)) return void 0;
|
|
210
|
+
return get(parsedValues ?? initialValues, path.value);
|
|
211
|
+
}
|
|
212
|
+
function setValue(form, name, value, options) {
|
|
213
|
+
setValueByPath(form, create$1(name), value, options);
|
|
214
|
+
}
|
|
215
|
+
function setValueByPath(form, path, value, options) {
|
|
216
|
+
const { emitter, values, deleted } = form;
|
|
217
|
+
values.set(path.key, value);
|
|
218
|
+
reviveBranch(deleted, path);
|
|
219
|
+
bumpDirtyVersion(form);
|
|
220
|
+
if (options?.shouldTouch) setTouchedByPath(form, path);
|
|
221
|
+
if (options?.shouldValidate) form.validators.get(path.key)?.();
|
|
222
|
+
emit(emitter, "change", path);
|
|
223
|
+
}
|
|
224
|
+
function getError(form, name) {
|
|
225
|
+
return getErrorByPath(form, create$1(name));
|
|
226
|
+
}
|
|
227
|
+
function getErrorByPath({ errors }, path) {
|
|
228
|
+
return errors.get(path.key)?.[0];
|
|
229
|
+
}
|
|
230
|
+
const NO_ERRORS = [];
|
|
231
|
+
function getFieldErrors(form, name) {
|
|
232
|
+
return getFieldErrorsByPath(form, create$1(name));
|
|
233
|
+
}
|
|
234
|
+
function getFieldErrorsByPath({ errors }, path) {
|
|
235
|
+
return errors.get(path.key) ?? NO_ERRORS;
|
|
236
|
+
}
|
|
237
|
+
function getErrors({ errors }) {
|
|
238
|
+
const entries = [];
|
|
239
|
+
for (const [key, list] of errors) {
|
|
240
|
+
const path = JSON.parse(key).join(".");
|
|
241
|
+
for (const { type, message } of list) entries.push({ path, type, message });
|
|
242
|
+
}
|
|
243
|
+
return entries;
|
|
244
|
+
}
|
|
245
|
+
function getFirstError({ errors }) {
|
|
246
|
+
return errors.values().next().value?.[0]?.message;
|
|
247
|
+
}
|
|
248
|
+
function getFieldState(form, name) {
|
|
249
|
+
const path = create$1(name);
|
|
250
|
+
const { initialValues, values, touched, validating } = form;
|
|
251
|
+
const live = values.get(path.key);
|
|
252
|
+
return {
|
|
253
|
+
value: getValueByPath(form, path),
|
|
254
|
+
error: getErrorByPath(form, path),
|
|
255
|
+
errors: getFieldErrorsByPath(form, path),
|
|
256
|
+
isDirty: values.has(path.key) && get(initialValues, path.value) !== live,
|
|
257
|
+
isTouched: touched.has(path.key),
|
|
258
|
+
isValidating: validating.has(path.key)
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
function unsetValidatingByPath({ emitter, validating }, path) {
|
|
262
|
+
validating.delete(path.key);
|
|
263
|
+
emit(emitter, "validating", path);
|
|
264
|
+
}
|
|
265
|
+
function setValidatingByPath({ emitter, validating }, path) {
|
|
266
|
+
validating.add(path.key);
|
|
267
|
+
emit(emitter, "validating", path);
|
|
268
|
+
}
|
|
269
|
+
function setError(form, name, error) {
|
|
270
|
+
setErrorByPath(form, create$1(name), error);
|
|
271
|
+
}
|
|
272
|
+
function setErrorByPath({ emitter, errors }, path, error) {
|
|
273
|
+
const list = normalizeErrors(error);
|
|
274
|
+
if (list) errors.set(path.key, list);
|
|
275
|
+
else errors.delete(path.key);
|
|
276
|
+
emit(emitter, "errors", path);
|
|
277
|
+
}
|
|
278
|
+
function normalizeErrors(error) {
|
|
279
|
+
if (typeof error === "string") {
|
|
280
|
+
return error ? [{ type: "custom", message: error }] : void 0;
|
|
281
|
+
}
|
|
282
|
+
if (isFieldError(error)) return [error];
|
|
283
|
+
if (!error) return void 0;
|
|
284
|
+
const list = [];
|
|
285
|
+
error.forEach((item) => {
|
|
286
|
+
if (typeof item === "string" && item) {
|
|
287
|
+
list.push({ type: "custom", message: item });
|
|
288
|
+
} else if (isFieldError(item)) {
|
|
289
|
+
list.push(item);
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
return list.length ? list : void 0;
|
|
293
|
+
}
|
|
294
|
+
function clearErrors(form, name) {
|
|
295
|
+
const { emitter, errors } = form;
|
|
296
|
+
if (name === void 0) {
|
|
297
|
+
errors.clear();
|
|
298
|
+
emit(emitter, "errors");
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
const paths = typeof name === "string" || isSegmentsPath(name) ? [create$1(name)] : name.map((one) => create$1(one));
|
|
302
|
+
for (const { key } of paths) errors.delete(key);
|
|
303
|
+
for (const path of paths) emit(emitter, "errors", path);
|
|
304
|
+
}
|
|
305
|
+
function setTouched(form, name) {
|
|
306
|
+
setTouchedByPath(form, create$1(name));
|
|
307
|
+
}
|
|
308
|
+
function setTouchedByPath({ emitter, touched }, path) {
|
|
309
|
+
if (touched.has(path.key)) return;
|
|
310
|
+
touched.add(path.key);
|
|
311
|
+
emit(emitter, "touched", path);
|
|
312
|
+
}
|
|
313
|
+
function hasTouched(form, name) {
|
|
314
|
+
return hasTouchedByPath(form, create$1(name));
|
|
315
|
+
}
|
|
316
|
+
function hasTouchedByPath({ touched }, path) {
|
|
317
|
+
return touched.has(path.key);
|
|
318
|
+
}
|
|
319
|
+
function isDirty(form) {
|
|
320
|
+
let dirty = false;
|
|
321
|
+
forEachDirtyField(form, () => {
|
|
322
|
+
dirty = true;
|
|
323
|
+
});
|
|
324
|
+
return dirty;
|
|
325
|
+
}
|
|
326
|
+
function forEachDirtyField({ initialValues, values }, fn) {
|
|
327
|
+
for (const [key, value] of values) {
|
|
328
|
+
const path = JSON.parse(key);
|
|
329
|
+
if (get(initialValues, path) !== value) fn(path.join("."));
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
const dirtyFieldsCaches = /* @__PURE__ */ new WeakMap();
|
|
333
|
+
function bumpDirtyVersion(form) {
|
|
334
|
+
const cache = dirtyFieldsCaches.get(form);
|
|
335
|
+
if (cache) cache.version++;
|
|
336
|
+
}
|
|
337
|
+
function computeDirtyFields(form) {
|
|
338
|
+
const dirtyFields = {};
|
|
339
|
+
forEachDirtyField(form, (key) => {
|
|
340
|
+
dirtyFields[key] = true;
|
|
341
|
+
});
|
|
342
|
+
return dirtyFields;
|
|
343
|
+
}
|
|
344
|
+
function sameDirtyKeys(a, b) {
|
|
345
|
+
const aKeys = Object.keys(a);
|
|
346
|
+
if (aKeys.length !== Object.keys(b).length) return false;
|
|
347
|
+
return aKeys.every((key) => b[key] === true);
|
|
348
|
+
}
|
|
349
|
+
function getDirtyFields(form) {
|
|
350
|
+
let cache = dirtyFieldsCaches.get(form);
|
|
351
|
+
if (!cache) {
|
|
352
|
+
cache = { version: 0, result: computeDirtyFields(form) };
|
|
353
|
+
dirtyFieldsCaches.set(form, cache);
|
|
354
|
+
} else if (cache.version > 0) {
|
|
355
|
+
const result = computeDirtyFields(form);
|
|
356
|
+
if (!sameDirtyKeys(cache.result, result)) cache.result = result;
|
|
357
|
+
cache.version = 0;
|
|
358
|
+
}
|
|
359
|
+
return cache.result;
|
|
360
|
+
}
|
|
361
|
+
function getTouchedFields({ touched }) {
|
|
362
|
+
return Array.from(
|
|
363
|
+
touched,
|
|
364
|
+
(key) => JSON.parse(key).join(".")
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
function isTouched({ touched }) {
|
|
368
|
+
return touched.size > 0;
|
|
369
|
+
}
|
|
370
|
+
function removeField(form, name) {
|
|
371
|
+
removeFieldByPath(form, create$1(name));
|
|
372
|
+
}
|
|
373
|
+
function removeFieldByPath(form, { key, value: segments }) {
|
|
374
|
+
const { emitter, values, touched, errors, validating, deleted } = form;
|
|
375
|
+
values.delete(key);
|
|
376
|
+
touched.delete(key);
|
|
377
|
+
errors.delete(key);
|
|
378
|
+
validating.delete(key);
|
|
379
|
+
if (!hasLiveBranch(values, segments)) deleted.add(key);
|
|
380
|
+
bumpDirtyVersion(form);
|
|
381
|
+
emit(emitter, "change");
|
|
382
|
+
emit(emitter, "touched");
|
|
383
|
+
emit(emitter, "errors");
|
|
384
|
+
emit(emitter, "validating");
|
|
385
|
+
}
|
|
386
|
+
function hasLiveBranch(values, segments) {
|
|
387
|
+
for (let i = 1; i < segments.length; i++) {
|
|
388
|
+
if (values.has(JSON.stringify(segments.slice(0, i)))) return true;
|
|
389
|
+
}
|
|
390
|
+
const stem = `${JSON.stringify(segments).slice(0, -1)},`;
|
|
391
|
+
for (const key of values.keys()) {
|
|
392
|
+
if (key.startsWith(stem)) return true;
|
|
393
|
+
}
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
396
|
+
function reviveBranch(deleted, { key }) {
|
|
397
|
+
if (!deleted.size) return;
|
|
398
|
+
for (const tombstone of deleted) {
|
|
399
|
+
if (tombstone === key || tombstone.startsWith(`${key.slice(0, -1)},`) || key.startsWith(`${tombstone.slice(0, -1)},`)) {
|
|
400
|
+
deleted.delete(tombstone);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
function setInitialValues(form, initialValues) {
|
|
405
|
+
if (form.initialValues === initialValues) return;
|
|
406
|
+
form.initialValues = initialValues;
|
|
407
|
+
form.parsedValues = void 0;
|
|
408
|
+
form.values.clear();
|
|
409
|
+
form.deleted.clear();
|
|
410
|
+
bumpDirtyVersion(form);
|
|
411
|
+
emit(form.emitter, "change");
|
|
412
|
+
}
|
|
413
|
+
function reset(form, initialValues, options) {
|
|
414
|
+
const dirtyValues = options?.keepDirtyValues ? Object.keys(getDirtyFields(form)).map((key) => ({
|
|
415
|
+
key,
|
|
416
|
+
value: getValue(form, key)
|
|
417
|
+
})) : [];
|
|
418
|
+
form.initialValues = initialValues;
|
|
419
|
+
form.parsedValues = void 0;
|
|
420
|
+
if (!options?.keepErrors) clearErrors(form);
|
|
421
|
+
const { emitter, touched, values, deleted, validating } = form;
|
|
422
|
+
values.clear();
|
|
423
|
+
deleted.clear();
|
|
424
|
+
if (!options?.keepTouched) touched.clear();
|
|
425
|
+
validating.clear();
|
|
426
|
+
if (!options?.keepIsSubmitting) form.isSubmitting = false;
|
|
427
|
+
if (!options?.keepSubmitCount) form.submitCount = 0;
|
|
428
|
+
if (!options?.keepIsSubmitted) form.isSubmitSuccessful = void 0;
|
|
429
|
+
bumpDirtyVersion(form);
|
|
430
|
+
for (const { key, value } of dirtyValues) {
|
|
431
|
+
setValueByPath(form, create$1(key), value);
|
|
432
|
+
}
|
|
433
|
+
emit(emitter, "change");
|
|
434
|
+
emit(emitter, "touched");
|
|
435
|
+
emit(emitter, "validating");
|
|
436
|
+
emit(emitter, "submitting");
|
|
437
|
+
emit(emitter, "submitCount");
|
|
438
|
+
emit(emitter, "submitSuccessful");
|
|
439
|
+
emit(emitter, "reset");
|
|
440
|
+
}
|
|
441
|
+
function resetField(form, name, options) {
|
|
442
|
+
const path = create$1(name);
|
|
443
|
+
const { emitter, values, touched, errors, deleted } = form;
|
|
444
|
+
values.delete(path.key);
|
|
445
|
+
if (form.parsedValues !== void 0) {
|
|
446
|
+
form.parsedValues = unset(form.parsedValues, path.value);
|
|
447
|
+
const initial = get(form.initialValues, path.value);
|
|
448
|
+
if (initial !== void 0) values.set(path.key, initial);
|
|
449
|
+
}
|
|
450
|
+
if (options && "value" in options) {
|
|
451
|
+
values.set(path.key, options.value);
|
|
452
|
+
}
|
|
453
|
+
reviveBranch(deleted, path);
|
|
454
|
+
emit(emitter, "change");
|
|
455
|
+
if (!options?.keepTouched && touched.delete(path.key)) {
|
|
456
|
+
emit(emitter, "touched", path);
|
|
457
|
+
}
|
|
458
|
+
if (!options?.keepErrors && errors.delete(path.key)) {
|
|
459
|
+
emit(emitter, "errors", path);
|
|
460
|
+
}
|
|
461
|
+
bumpDirtyVersion(form);
|
|
462
|
+
}
|
|
463
|
+
function hasErrors({ errors }) {
|
|
464
|
+
return errors.size > 0;
|
|
465
|
+
}
|
|
466
|
+
async function trigger(form, name) {
|
|
467
|
+
const settle = () => waitUntil(
|
|
468
|
+
form.emitter,
|
|
469
|
+
"validating",
|
|
470
|
+
() => !form.validating.size,
|
|
471
|
+
() => false
|
|
472
|
+
);
|
|
473
|
+
if (name === void 0) {
|
|
474
|
+
form.validators.forEach((validator) => validator());
|
|
475
|
+
await settle();
|
|
476
|
+
if (form.validate) {
|
|
477
|
+
const result = await form.validate(getValues(form));
|
|
478
|
+
applyValidateResult(form, result);
|
|
479
|
+
}
|
|
480
|
+
return !hasErrors(form);
|
|
481
|
+
}
|
|
482
|
+
const keys = typeof name === "string" || isSegmentsPath(name) ? [create$1(name).key] : name.map((one) => create$1(one).key);
|
|
483
|
+
keys.forEach((key) => form.validators.get(key)?.());
|
|
484
|
+
await settle();
|
|
485
|
+
return keys.every((key) => !form.errors.has(key));
|
|
486
|
+
}
|
|
487
|
+
function isSegmentsPath(name) {
|
|
488
|
+
return name.some((part) => typeof part === "number");
|
|
489
|
+
}
|
|
490
|
+
function isFieldError(value) {
|
|
491
|
+
return !!value && typeof value === "object" && typeof value.type === "string" && typeof value.message === "string";
|
|
492
|
+
}
|
|
493
|
+
function setFormErrors(form, result, segments = []) {
|
|
494
|
+
Object.entries(result).forEach(([key, value]) => {
|
|
495
|
+
const path = [...segments, ...normalizePath(key)];
|
|
496
|
+
if (typeof value === "string") {
|
|
497
|
+
if (value) setError(form, path, value);
|
|
498
|
+
} else if (Array.isArray(value)) {
|
|
499
|
+
setError(form, path, value);
|
|
500
|
+
} else if (isFieldError(value)) {
|
|
501
|
+
setError(form, path, value);
|
|
502
|
+
} else if (value && typeof value === "object") {
|
|
503
|
+
setFormErrors(form, value, path);
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
function setParsedValues(form, values) {
|
|
508
|
+
if (values === void 0 || values === form.parsedValues) return;
|
|
509
|
+
form.parsedValues = values;
|
|
510
|
+
emit(form.emitter, "change");
|
|
511
|
+
}
|
|
512
|
+
function applyValidateResult(form, result) {
|
|
513
|
+
if (!result) return;
|
|
514
|
+
if (typeof result === "object" && VALIDATION_OUTCOME in result) {
|
|
515
|
+
const outcome = result;
|
|
516
|
+
if (outcome.errors) setFormErrors(form, outcome.errors);
|
|
517
|
+
setParsedValues(form, outcome.values);
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
setFormErrors(form, result);
|
|
521
|
+
}
|
|
522
|
+
async function ensureValidate(form) {
|
|
523
|
+
form.validators.forEach((validator) => validator());
|
|
524
|
+
await waitUntil(
|
|
525
|
+
form.emitter,
|
|
526
|
+
"validating",
|
|
527
|
+
() => !form.validating.size,
|
|
528
|
+
() => hasErrors(form)
|
|
529
|
+
).catch(() => {
|
|
530
|
+
throw new Error(getFirstError(form));
|
|
531
|
+
});
|
|
532
|
+
if (form.validate) {
|
|
533
|
+
const result = await form.validate(getValues(form));
|
|
534
|
+
applyValidateResult(form, result);
|
|
535
|
+
if (hasErrors(form)) throw new Error(getFirstError(form));
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
async function validate(form) {
|
|
539
|
+
return ensureValidate(form).catch((e) => e.message);
|
|
540
|
+
}
|
|
541
|
+
function setIsSubmitting(form, value) {
|
|
542
|
+
form.isSubmitting = value;
|
|
543
|
+
emit(form.emitter, "submitting");
|
|
544
|
+
}
|
|
545
|
+
function incrementSubmitCount(form) {
|
|
546
|
+
form.submitCount++;
|
|
547
|
+
emit(form.emitter, "submitCount");
|
|
548
|
+
}
|
|
549
|
+
function setSubmitSuccessful(form, value) {
|
|
550
|
+
form.isSubmitSuccessful = value;
|
|
551
|
+
emit(form.emitter, "submitSuccessful");
|
|
552
|
+
}
|
|
553
|
+
function setDisabled(form, value) {
|
|
554
|
+
form.disabled = value;
|
|
555
|
+
emit(form.emitter, "disabled");
|
|
556
|
+
}
|
|
557
|
+
function nameToPath(name) {
|
|
558
|
+
if (name.startsWith("[")) {
|
|
559
|
+
try {
|
|
560
|
+
const segments = JSON.parse(name);
|
|
561
|
+
if (Array.isArray(segments)) return segments.join(".");
|
|
562
|
+
} catch {
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
return name;
|
|
566
|
+
}
|
|
567
|
+
function getNativeErrors(formEl) {
|
|
568
|
+
const errors = [];
|
|
569
|
+
const { elements } = formEl;
|
|
570
|
+
for (let i = 0; i < elements.length; i++) {
|
|
571
|
+
const el = elements[i];
|
|
572
|
+
if (el.name && typeof el.checkValidity === "function" && !el.checkValidity()) {
|
|
573
|
+
errors.push({
|
|
574
|
+
path: nameToPath(el.name),
|
|
575
|
+
type: "native",
|
|
576
|
+
message: el.validationMessage
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return errors;
|
|
581
|
+
}
|
|
582
|
+
function handleSubmit(form, options) {
|
|
583
|
+
const {
|
|
584
|
+
onSubmit,
|
|
585
|
+
onValidSubmit,
|
|
586
|
+
onInvalidSubmit,
|
|
587
|
+
shouldFocusError = true
|
|
588
|
+
} = options ?? {};
|
|
589
|
+
return async (e) => {
|
|
590
|
+
if (e && typeof e.preventDefault === "function") {
|
|
591
|
+
e.preventDefault();
|
|
592
|
+
}
|
|
593
|
+
const formEl = e?.currentTarget;
|
|
594
|
+
setIsSubmitting(form, true);
|
|
595
|
+
incrementSubmitCount(form);
|
|
596
|
+
const values = getValues(form);
|
|
597
|
+
if (formEl && typeof formEl.checkValidity === "function" && formEl.checkValidity() === false) {
|
|
598
|
+
formEl.reportValidity();
|
|
599
|
+
if (shouldFocusError && typeof formEl.querySelector === "function") {
|
|
600
|
+
const invalid = formEl.querySelector(":invalid");
|
|
601
|
+
if (invalid && typeof invalid.focus === "function") invalid.focus();
|
|
602
|
+
}
|
|
603
|
+
setIsSubmitting(form, false);
|
|
604
|
+
setSubmitSuccessful(form, false);
|
|
605
|
+
if (onInvalidSubmit) onInvalidSubmit(getNativeErrors(formEl), values);
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
const error = await validate(form);
|
|
609
|
+
if (error) {
|
|
610
|
+
setIsSubmitting(form, false);
|
|
611
|
+
setSubmitSuccessful(form, false);
|
|
612
|
+
if (shouldFocusError) {
|
|
613
|
+
const firstKey = form.errors.keys().next().value;
|
|
614
|
+
if (firstKey !== void 0) emit(form.emitter, "focusError", firstKey);
|
|
615
|
+
}
|
|
616
|
+
if (onInvalidSubmit) onInvalidSubmit(getErrors(form), values);
|
|
617
|
+
return;
|
|
618
|
+
}
|
|
619
|
+
try {
|
|
620
|
+
const submitted = getValues(form);
|
|
621
|
+
if (onSubmit) await onSubmit(submitted, e);
|
|
622
|
+
if (onValidSubmit) await onValidSubmit(submitted, e);
|
|
623
|
+
setSubmitSuccessful(form, true);
|
|
624
|
+
} catch {
|
|
625
|
+
setSubmitSuccessful(form, false);
|
|
626
|
+
} finally {
|
|
627
|
+
setIsSubmitting(form, false);
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
function setFocus(form, name, options) {
|
|
632
|
+
const { key } = create$1(name);
|
|
633
|
+
if (options) emit(form.emitter, "focusError", key, options);
|
|
634
|
+
else emit(form.emitter, "focusError", key);
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
function defaultMessage(type, bound) {
|
|
638
|
+
switch (type) {
|
|
639
|
+
case "required":
|
|
640
|
+
return "This field is required";
|
|
641
|
+
case "min":
|
|
642
|
+
return `Must be at least ${bound}`;
|
|
643
|
+
case "max":
|
|
644
|
+
return `Must be at most ${bound}`;
|
|
645
|
+
case "minLength":
|
|
646
|
+
return `Must be at least ${bound} characters`;
|
|
647
|
+
case "maxLength":
|
|
648
|
+
return `Must be at most ${bound} characters`;
|
|
649
|
+
case "pattern":
|
|
650
|
+
return "Invalid format";
|
|
651
|
+
default:
|
|
652
|
+
return "Invalid value";
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
function rulesToValidator(rules) {
|
|
656
|
+
return (value) => {
|
|
657
|
+
if (rules.required) {
|
|
658
|
+
if (value === "" || value === void 0 || value === null) {
|
|
659
|
+
return [
|
|
660
|
+
{
|
|
661
|
+
type: "required",
|
|
662
|
+
message: typeof rules.required === "string" ? rules.required : defaultMessage("required")
|
|
663
|
+
}
|
|
664
|
+
];
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
const errors = [];
|
|
668
|
+
const message = (type, bound) => rules.messages?.[type] ?? defaultMessage(type, bound);
|
|
669
|
+
if (rules.min !== void 0) {
|
|
670
|
+
const n = Number(value);
|
|
671
|
+
if (!Number.isNaN(n) && n < rules.min) {
|
|
672
|
+
errors.push({ type: "min", message: message("min", rules.min) });
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
if (rules.max !== void 0) {
|
|
676
|
+
const n = Number(value);
|
|
677
|
+
if (!Number.isNaN(n) && n > rules.max) {
|
|
678
|
+
errors.push({ type: "max", message: message("max", rules.max) });
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
if (rules.minLength !== void 0 && typeof value === "string" && value.length < rules.minLength) {
|
|
682
|
+
errors.push({
|
|
683
|
+
type: "minLength",
|
|
684
|
+
message: message("minLength", rules.minLength)
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
if (rules.maxLength !== void 0 && typeof value === "string" && value.length > rules.maxLength) {
|
|
688
|
+
errors.push({
|
|
689
|
+
type: "maxLength",
|
|
690
|
+
message: message("maxLength", rules.maxLength)
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
if (rules.pattern && !rules.pattern.value.test(value)) {
|
|
694
|
+
errors.push({
|
|
695
|
+
type: "pattern",
|
|
696
|
+
// pattern.message is type-required but JS consumers may omit it.
|
|
697
|
+
message: rules.messages?.pattern ?? rules.pattern.message ?? defaultMessage("pattern")
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
return errors.length ? errors : void 0;
|
|
701
|
+
};
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
var shim = {exports: {}};
|
|
705
|
+
|
|
706
|
+
var useSyncExternalStoreShim_production = {};
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* @license React
|
|
710
|
+
* use-sync-external-store-shim.production.js
|
|
711
|
+
*
|
|
712
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
713
|
+
*
|
|
714
|
+
* This source code is licensed under the MIT license found in the
|
|
715
|
+
* LICENSE file in the root directory of this source tree.
|
|
716
|
+
*/
|
|
717
|
+
|
|
718
|
+
var hasRequiredUseSyncExternalStoreShim_production;
|
|
719
|
+
|
|
720
|
+
function requireUseSyncExternalStoreShim_production () {
|
|
721
|
+
if (hasRequiredUseSyncExternalStoreShim_production) return useSyncExternalStoreShim_production;
|
|
722
|
+
hasRequiredUseSyncExternalStoreShim_production = 1;
|
|
723
|
+
var React = React__default;
|
|
724
|
+
function is(x, y) {
|
|
725
|
+
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
|
|
726
|
+
}
|
|
727
|
+
var objectIs = "function" === typeof Object.is ? Object.is : is,
|
|
728
|
+
useState = React.useState,
|
|
729
|
+
useEffect = React.useEffect,
|
|
730
|
+
useLayoutEffect = React.useLayoutEffect,
|
|
731
|
+
useDebugValue = React.useDebugValue;
|
|
732
|
+
function useSyncExternalStore$2(subscribe, getSnapshot) {
|
|
733
|
+
var value = getSnapshot(),
|
|
734
|
+
_useState = useState({ inst: { value: value, getSnapshot: getSnapshot } }),
|
|
735
|
+
inst = _useState[0].inst,
|
|
736
|
+
forceUpdate = _useState[1];
|
|
737
|
+
useLayoutEffect(
|
|
738
|
+
function () {
|
|
739
|
+
inst.value = value;
|
|
740
|
+
inst.getSnapshot = getSnapshot;
|
|
741
|
+
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
742
|
+
},
|
|
743
|
+
[subscribe, value, getSnapshot]
|
|
744
|
+
);
|
|
745
|
+
useEffect(
|
|
746
|
+
function () {
|
|
747
|
+
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
748
|
+
return subscribe(function () {
|
|
749
|
+
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
750
|
+
});
|
|
751
|
+
},
|
|
752
|
+
[subscribe]
|
|
753
|
+
);
|
|
754
|
+
useDebugValue(value);
|
|
755
|
+
return value;
|
|
756
|
+
}
|
|
757
|
+
function checkIfSnapshotChanged(inst) {
|
|
758
|
+
var latestGetSnapshot = inst.getSnapshot;
|
|
759
|
+
inst = inst.value;
|
|
760
|
+
try {
|
|
761
|
+
var nextValue = latestGetSnapshot();
|
|
762
|
+
return !objectIs(inst, nextValue);
|
|
763
|
+
} catch (error) {
|
|
764
|
+
return !0;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
function useSyncExternalStore$1(subscribe, getSnapshot) {
|
|
768
|
+
return getSnapshot();
|
|
769
|
+
}
|
|
770
|
+
var shim =
|
|
771
|
+
"undefined" === typeof window ||
|
|
772
|
+
"undefined" === typeof window.document ||
|
|
773
|
+
"undefined" === typeof window.document.createElement
|
|
774
|
+
? useSyncExternalStore$1
|
|
775
|
+
: useSyncExternalStore$2;
|
|
776
|
+
useSyncExternalStoreShim_production.useSyncExternalStore =
|
|
777
|
+
void 0 !== React.useSyncExternalStore ? React.useSyncExternalStore : shim;
|
|
778
|
+
return useSyncExternalStoreShim_production;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
var useSyncExternalStoreShim_development = {};
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* @license React
|
|
785
|
+
* use-sync-external-store-shim.development.js
|
|
786
|
+
*
|
|
787
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
788
|
+
*
|
|
789
|
+
* This source code is licensed under the MIT license found in the
|
|
790
|
+
* LICENSE file in the root directory of this source tree.
|
|
791
|
+
*/
|
|
792
|
+
|
|
793
|
+
var hasRequiredUseSyncExternalStoreShim_development;
|
|
794
|
+
|
|
795
|
+
function requireUseSyncExternalStoreShim_development () {
|
|
796
|
+
if (hasRequiredUseSyncExternalStoreShim_development) return useSyncExternalStoreShim_development;
|
|
797
|
+
hasRequiredUseSyncExternalStoreShim_development = 1;
|
|
798
|
+
"production" !== process.env.NODE_ENV &&
|
|
799
|
+
(function () {
|
|
800
|
+
function is(x, y) {
|
|
801
|
+
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
|
|
802
|
+
}
|
|
803
|
+
function useSyncExternalStore$2(subscribe, getSnapshot) {
|
|
804
|
+
didWarnOld18Alpha ||
|
|
805
|
+
void 0 === React.startTransition ||
|
|
806
|
+
((didWarnOld18Alpha = !0),
|
|
807
|
+
console.error(
|
|
808
|
+
"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."
|
|
809
|
+
));
|
|
810
|
+
var value = getSnapshot();
|
|
811
|
+
if (!didWarnUncachedGetSnapshot) {
|
|
812
|
+
var cachedValue = getSnapshot();
|
|
813
|
+
objectIs(value, cachedValue) ||
|
|
814
|
+
(console.error(
|
|
815
|
+
"The result of getSnapshot should be cached to avoid an infinite loop"
|
|
816
|
+
),
|
|
817
|
+
(didWarnUncachedGetSnapshot = !0));
|
|
818
|
+
}
|
|
819
|
+
cachedValue = useState({
|
|
820
|
+
inst: { value: value, getSnapshot: getSnapshot }
|
|
821
|
+
});
|
|
822
|
+
var inst = cachedValue[0].inst,
|
|
823
|
+
forceUpdate = cachedValue[1];
|
|
824
|
+
useLayoutEffect(
|
|
825
|
+
function () {
|
|
826
|
+
inst.value = value;
|
|
827
|
+
inst.getSnapshot = getSnapshot;
|
|
828
|
+
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
829
|
+
},
|
|
830
|
+
[subscribe, value, getSnapshot]
|
|
831
|
+
);
|
|
832
|
+
useEffect(
|
|
833
|
+
function () {
|
|
834
|
+
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
835
|
+
return subscribe(function () {
|
|
836
|
+
checkIfSnapshotChanged(inst) && forceUpdate({ inst: inst });
|
|
837
|
+
});
|
|
838
|
+
},
|
|
839
|
+
[subscribe]
|
|
840
|
+
);
|
|
841
|
+
useDebugValue(value);
|
|
842
|
+
return value;
|
|
843
|
+
}
|
|
844
|
+
function checkIfSnapshotChanged(inst) {
|
|
845
|
+
var latestGetSnapshot = inst.getSnapshot;
|
|
846
|
+
inst = inst.value;
|
|
847
|
+
try {
|
|
848
|
+
var nextValue = latestGetSnapshot();
|
|
849
|
+
return !objectIs(inst, nextValue);
|
|
850
|
+
} catch (error) {
|
|
851
|
+
return !0;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
function useSyncExternalStore$1(subscribe, getSnapshot) {
|
|
855
|
+
return getSnapshot();
|
|
856
|
+
}
|
|
857
|
+
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
|
|
858
|
+
"function" ===
|
|
859
|
+
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart &&
|
|
860
|
+
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
861
|
+
var React = React__default,
|
|
862
|
+
objectIs = "function" === typeof Object.is ? Object.is : is,
|
|
863
|
+
useState = React.useState,
|
|
864
|
+
useEffect = React.useEffect,
|
|
865
|
+
useLayoutEffect = React.useLayoutEffect,
|
|
866
|
+
useDebugValue = React.useDebugValue,
|
|
867
|
+
didWarnOld18Alpha = !1,
|
|
868
|
+
didWarnUncachedGetSnapshot = !1,
|
|
869
|
+
shim =
|
|
870
|
+
"undefined" === typeof window ||
|
|
871
|
+
"undefined" === typeof window.document ||
|
|
872
|
+
"undefined" === typeof window.document.createElement
|
|
873
|
+
? useSyncExternalStore$1
|
|
874
|
+
: useSyncExternalStore$2;
|
|
875
|
+
useSyncExternalStoreShim_development.useSyncExternalStore =
|
|
876
|
+
void 0 !== React.useSyncExternalStore ? React.useSyncExternalStore : shim;
|
|
877
|
+
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
|
|
878
|
+
"function" ===
|
|
879
|
+
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&
|
|
880
|
+
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
|
|
881
|
+
})();
|
|
882
|
+
return useSyncExternalStoreShim_development;
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
if (process.env.NODE_ENV === 'production') {
|
|
886
|
+
shim.exports = requireUseSyncExternalStoreShim_production();
|
|
887
|
+
} else {
|
|
888
|
+
shim.exports = requireUseSyncExternalStoreShim_development();
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
var shimExports = shim.exports;
|
|
892
|
+
|
|
893
|
+
function isDescendant(key, ancestorKey) {
|
|
894
|
+
return key.startsWith(`${ancestorKey.slice(0, -1)},`);
|
|
895
|
+
}
|
|
896
|
+
function onPathEvent(emitter, event, path, scope, cb) {
|
|
897
|
+
const { key } = path;
|
|
898
|
+
return on(emitter, event, (changed) => {
|
|
899
|
+
if (changed === void 0 || changed.key === key || isDescendant(key, changed.key) || scope === "branch" && isDescendant(changed.key, key)) {
|
|
900
|
+
cb();
|
|
901
|
+
}
|
|
902
|
+
});
|
|
903
|
+
}
|
|
904
|
+
function onKeyEvent(emitter, event, key, cb) {
|
|
905
|
+
return on(emitter, event, (changed) => {
|
|
906
|
+
if (changed === void 0 || changed.key === key) cb();
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
function isNameList(name) {
|
|
910
|
+
return Array.isArray(name) && name.every((part) => typeof part !== "number");
|
|
911
|
+
}
|
|
912
|
+
function subscribe(form, options) {
|
|
913
|
+
const { name, event = "change", scope = "branch", callback } = options;
|
|
914
|
+
if (name === void 0) return on(form.emitter, event, callback);
|
|
915
|
+
const names = isNameList(name) ? name : [name];
|
|
916
|
+
const unsubscribes = names.map((one) => {
|
|
917
|
+
const path = create$1(one);
|
|
918
|
+
return event === "errors" || event === "touched" ? onKeyEvent(form.emitter, event, path.key, callback) : onPathEvent(form.emitter, event, path, scope, callback);
|
|
919
|
+
});
|
|
920
|
+
return unsubscribes.length === 1 ? unsubscribes[0] : () => unsubscribes.forEach((unsubscribe) => unsubscribe());
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
function useForm(options) {
|
|
924
|
+
const [form] = useState(() => {
|
|
925
|
+
const created = create(options);
|
|
926
|
+
if (options && options.values !== void 0) {
|
|
927
|
+
setInitialValues(created, options.values);
|
|
928
|
+
}
|
|
929
|
+
return created;
|
|
930
|
+
});
|
|
931
|
+
const initialValues = options && options.initialValues;
|
|
932
|
+
const values = options && options.values;
|
|
933
|
+
const seededRef = useRef(null);
|
|
934
|
+
if (seededRef.current === null)
|
|
935
|
+
seededRef.current = { done: false, source: void 0 };
|
|
936
|
+
useEffect(() => {
|
|
937
|
+
const seeded = seededRef.current;
|
|
938
|
+
if (seeded.done && (seeded.source === initialValues || isEqual(seeded.source, initialValues))) {
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
seeded.done = true;
|
|
942
|
+
seeded.source = initialValues;
|
|
943
|
+
setInitialValues(form, initialValues);
|
|
944
|
+
}, [form, initialValues]);
|
|
945
|
+
const controlledRef = useRef(null);
|
|
946
|
+
if (controlledRef.current === null) {
|
|
947
|
+
controlledRef.current = { done: false, source: void 0 };
|
|
948
|
+
}
|
|
949
|
+
useEffect(() => {
|
|
950
|
+
if (values === void 0) return;
|
|
951
|
+
const seeded = controlledRef.current;
|
|
952
|
+
if (seeded.done && (seeded.source === values || isEqual(seeded.source, values))) {
|
|
953
|
+
return;
|
|
954
|
+
}
|
|
955
|
+
seeded.done = true;
|
|
956
|
+
seeded.source = values;
|
|
957
|
+
setInitialValues(form, values);
|
|
958
|
+
}, [form, values]);
|
|
959
|
+
return form;
|
|
960
|
+
}
|
|
961
|
+
function useWatchCore(subscribeFactory, getter) {
|
|
962
|
+
const cacheRef = useRef(null);
|
|
963
|
+
if (cacheRef.current === null) cacheRef.current = { hasValue: false };
|
|
964
|
+
const cache = cacheRef.current;
|
|
965
|
+
const getterRef = useRef(getter);
|
|
966
|
+
getterRef.current = getter;
|
|
967
|
+
const getSnapshot = useCallback(() => {
|
|
968
|
+
if (!cache.hasValue) {
|
|
969
|
+
cache.value = getterRef.current();
|
|
970
|
+
cache.hasValue = true;
|
|
971
|
+
}
|
|
972
|
+
return cache.value;
|
|
973
|
+
}, [cache]);
|
|
974
|
+
const subscribe = useCallback(
|
|
975
|
+
(notify) => {
|
|
976
|
+
cache.hasValue = false;
|
|
977
|
+
const invalidate = () => {
|
|
978
|
+
cache.hasValue = false;
|
|
979
|
+
notify();
|
|
980
|
+
};
|
|
981
|
+
return subscribeFactory(invalidate);
|
|
982
|
+
},
|
|
983
|
+
[subscribeFactory, cache]
|
|
984
|
+
);
|
|
985
|
+
return shimExports.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
986
|
+
}
|
|
987
|
+
function useWatch(emitter, event, getter) {
|
|
988
|
+
const subscribeFactory = useCallback(
|
|
989
|
+
(invalidate) => on(emitter, event, invalidate),
|
|
990
|
+
[emitter, event]
|
|
991
|
+
);
|
|
992
|
+
return useWatchCore(subscribeFactory, getter);
|
|
993
|
+
}
|
|
994
|
+
function useValue(form, name) {
|
|
995
|
+
return useValueByPath(form, create$1(name));
|
|
996
|
+
}
|
|
997
|
+
function useValueByPath(form, path) {
|
|
998
|
+
const { emitter } = form;
|
|
999
|
+
const { key } = path;
|
|
1000
|
+
const subscribeFactory = useCallback(
|
|
1001
|
+
(invalidate) => onPathEvent(emitter, "change", path, "leaf", invalidate),
|
|
1002
|
+
// 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
|
|
1003
|
+
[emitter, key]
|
|
1004
|
+
);
|
|
1005
|
+
return useWatchCore(subscribeFactory, getValueByPath.bind(null, form, path));
|
|
1006
|
+
}
|
|
1007
|
+
function useTouched(form, name) {
|
|
1008
|
+
return useTouchedByPath(form, create$1(name));
|
|
1009
|
+
}
|
|
1010
|
+
function useTouchedByPath(form, path) {
|
|
1011
|
+
const { emitter } = form;
|
|
1012
|
+
const { key } = path;
|
|
1013
|
+
const subscribeFactory = useCallback(
|
|
1014
|
+
(invalidate) => onKeyEvent(emitter, "touched", key, invalidate),
|
|
1015
|
+
[emitter, key]
|
|
1016
|
+
);
|
|
1017
|
+
return useWatchCore(
|
|
1018
|
+
subscribeFactory,
|
|
1019
|
+
hasTouchedByPath.bind(null, form, path)
|
|
1020
|
+
);
|
|
1021
|
+
}
|
|
1022
|
+
function useError(form, name) {
|
|
1023
|
+
return useErrorByPath(form, create$1(name))?.message;
|
|
1024
|
+
}
|
|
1025
|
+
function useErrorByPath(form, path) {
|
|
1026
|
+
const { emitter } = form;
|
|
1027
|
+
const { key } = path;
|
|
1028
|
+
const subscribeFactory = useCallback(
|
|
1029
|
+
(invalidate) => onKeyEvent(emitter, "errors", key, invalidate),
|
|
1030
|
+
[emitter, key]
|
|
1031
|
+
);
|
|
1032
|
+
return useWatchCore(subscribeFactory, getErrorByPath.bind(null, form, path));
|
|
1033
|
+
}
|
|
1034
|
+
function useFieldErrors(form, name) {
|
|
1035
|
+
return useFieldErrorsByPath(form, create$1(name));
|
|
1036
|
+
}
|
|
1037
|
+
function useFieldErrorsByPath(form, path) {
|
|
1038
|
+
const { emitter } = form;
|
|
1039
|
+
const { key } = path;
|
|
1040
|
+
const subscribeFactory = useCallback(
|
|
1041
|
+
(invalidate) => onKeyEvent(emitter, "errors", key, invalidate),
|
|
1042
|
+
[emitter, key]
|
|
1043
|
+
);
|
|
1044
|
+
return useWatchCore(
|
|
1045
|
+
subscribeFactory,
|
|
1046
|
+
getFieldErrorsByPath.bind(null, form, path)
|
|
1047
|
+
);
|
|
1048
|
+
}
|
|
1049
|
+
function useIsDirty(form) {
|
|
1050
|
+
return useWatch(form.emitter, "change", isDirty.bind(null, form));
|
|
1051
|
+
}
|
|
1052
|
+
function useDirtyFields(form) {
|
|
1053
|
+
return useWatch(form.emitter, "change", getDirtyFields.bind(null, form));
|
|
1054
|
+
}
|
|
1055
|
+
function useTouchedFields(form) {
|
|
1056
|
+
return useWatch(form.emitter, "touched", getTouchedFields.bind(null, form));
|
|
1057
|
+
}
|
|
1058
|
+
function useHasErrors(form) {
|
|
1059
|
+
return useWatch(form.emitter, "errors", hasErrors.bind(null, form));
|
|
1060
|
+
}
|
|
1061
|
+
function useIsSubmitting(form) {
|
|
1062
|
+
return useWatch(form.emitter, "submitting", () => form.isSubmitting);
|
|
1063
|
+
}
|
|
1064
|
+
function useSubmitCount(form) {
|
|
1065
|
+
return useWatch(form.emitter, "submitCount", () => form.submitCount);
|
|
1066
|
+
}
|
|
1067
|
+
function isEqual(a, b) {
|
|
1068
|
+
if (Object.is(a, b)) return true;
|
|
1069
|
+
if (a instanceof Date && b instanceof Date)
|
|
1070
|
+
return a.getTime() === b.getTime();
|
|
1071
|
+
if (!a || !b || typeof a !== "object" || typeof b !== "object") return false;
|
|
1072
|
+
const isArray = Array.isArray(a);
|
|
1073
|
+
if (isArray !== Array.isArray(b)) return false;
|
|
1074
|
+
if (isArray) {
|
|
1075
|
+
if (a.length !== b.length) return false;
|
|
1076
|
+
for (let i = 0; i < a.length; i++) {
|
|
1077
|
+
if (!isEqual(a[i], b[i])) return false;
|
|
1078
|
+
}
|
|
1079
|
+
return true;
|
|
1080
|
+
}
|
|
1081
|
+
const proto = Object.getPrototypeOf(a);
|
|
1082
|
+
if (proto !== Object.prototype && proto !== null) return false;
|
|
1083
|
+
if (Object.getPrototypeOf(b) !== proto) return false;
|
|
1084
|
+
const keysA = Object.keys(a);
|
|
1085
|
+
const keysB = Object.keys(b);
|
|
1086
|
+
if (keysA.length !== keysB.length) return false;
|
|
1087
|
+
for (const key of keysA) {
|
|
1088
|
+
if (!isEqual(a[key], b[key])) return false;
|
|
1089
|
+
}
|
|
1090
|
+
return true;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
function usePath(name) {
|
|
1094
|
+
const path = useMemo(() => create$1(normalizePath(name)), [name]);
|
|
1095
|
+
return useMemo(() => path, [path.key]);
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
function useStage(value) {
|
|
1099
|
+
const ref = useRef(value);
|
|
1100
|
+
ref.current = value;
|
|
1101
|
+
return ref;
|
|
1102
|
+
}
|
|
1103
|
+
function useStageFn(fn) {
|
|
1104
|
+
const ref = useStage(fn);
|
|
1105
|
+
return useCallback(
|
|
1106
|
+
(...params) => ref.current(...params),
|
|
1107
|
+
[ref]
|
|
1108
|
+
);
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
function useValidate(validate, path, formProp, options) {
|
|
1112
|
+
const contextForm = useContext(FormContext);
|
|
1113
|
+
const form = formProp || contextForm;
|
|
1114
|
+
if (!form) throw new Error("no form provided");
|
|
1115
|
+
const lockRef = useRef(null);
|
|
1116
|
+
const validateRef = useRef(validate);
|
|
1117
|
+
validateRef.current = validate;
|
|
1118
|
+
const debounceRef = useRef(options?.debounce ?? 0);
|
|
1119
|
+
debounceRef.current = options?.debounce ?? 0;
|
|
1120
|
+
useEffect(() => {
|
|
1121
|
+
let timer = null;
|
|
1122
|
+
let controller = null;
|
|
1123
|
+
let marked = false;
|
|
1124
|
+
const mark = () => {
|
|
1125
|
+
if (marked) return;
|
|
1126
|
+
marked = true;
|
|
1127
|
+
setValidatingByPath(form, path);
|
|
1128
|
+
};
|
|
1129
|
+
const unmark = () => {
|
|
1130
|
+
if (!marked) return;
|
|
1131
|
+
marked = false;
|
|
1132
|
+
unsetValidatingByPath(form, path);
|
|
1133
|
+
};
|
|
1134
|
+
const run = () => {
|
|
1135
|
+
timer = null;
|
|
1136
|
+
const fn = validateRef.current;
|
|
1137
|
+
if (!fn) {
|
|
1138
|
+
unmark();
|
|
1139
|
+
return;
|
|
1140
|
+
}
|
|
1141
|
+
controller?.abort();
|
|
1142
|
+
controller = new AbortController();
|
|
1143
|
+
const lock = lockRef.current = {};
|
|
1144
|
+
let result;
|
|
1145
|
+
try {
|
|
1146
|
+
result = fn(getValueByPath(form, path), {
|
|
1147
|
+
form,
|
|
1148
|
+
path,
|
|
1149
|
+
signal: controller.signal
|
|
1150
|
+
});
|
|
1151
|
+
} catch (e) {
|
|
1152
|
+
unmark();
|
|
1153
|
+
throw e;
|
|
1154
|
+
}
|
|
1155
|
+
if (!isPromise(result)) {
|
|
1156
|
+
setErrorByPath(form, path, result);
|
|
1157
|
+
unmark();
|
|
1158
|
+
return;
|
|
1159
|
+
}
|
|
1160
|
+
mark();
|
|
1161
|
+
result.then(
|
|
1162
|
+
(error) => {
|
|
1163
|
+
if (lock === lockRef.current) {
|
|
1164
|
+
setErrorByPath(form, path, error);
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
).catch(() => {
|
|
1168
|
+
}).finally(() => {
|
|
1169
|
+
if (lock === lockRef.current) {
|
|
1170
|
+
unmark();
|
|
1171
|
+
lockRef.current = null;
|
|
1172
|
+
}
|
|
1173
|
+
});
|
|
1174
|
+
};
|
|
1175
|
+
const validator = () => {
|
|
1176
|
+
const debounce = debounceRef.current;
|
|
1177
|
+
if (debounce > 0) {
|
|
1178
|
+
if (timer !== null) clearTimeout(timer);
|
|
1179
|
+
else mark();
|
|
1180
|
+
timer = setTimeout(run, debounce);
|
|
1181
|
+
return;
|
|
1182
|
+
}
|
|
1183
|
+
run();
|
|
1184
|
+
};
|
|
1185
|
+
form.validators.set(path.key, validator);
|
|
1186
|
+
return () => {
|
|
1187
|
+
form.validators.delete(path.key);
|
|
1188
|
+
if (timer !== null) {
|
|
1189
|
+
clearTimeout(timer);
|
|
1190
|
+
timer = null;
|
|
1191
|
+
}
|
|
1192
|
+
unmark();
|
|
1193
|
+
controller?.abort();
|
|
1194
|
+
};
|
|
1195
|
+
}, [form, path.key]);
|
|
1196
|
+
return useStageFn(() => form.validators.get(path.key)?.());
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
function combineRulesAndValidate(rules, validate) {
|
|
1200
|
+
if (!rules) return validate;
|
|
1201
|
+
const ruleValidator = rulesToValidator(rules);
|
|
1202
|
+
if (!validate) return ruleValidator;
|
|
1203
|
+
return (value, meta) => {
|
|
1204
|
+
const ruleErrors = ruleValidator(value, meta);
|
|
1205
|
+
const merge = (other) => {
|
|
1206
|
+
const list = [...ruleErrors ?? []];
|
|
1207
|
+
if (Array.isArray(other)) list.push(...other);
|
|
1208
|
+
else if (other) list.push(other);
|
|
1209
|
+
return list.length ? list : void 0;
|
|
1210
|
+
};
|
|
1211
|
+
const result = validate(value, meta);
|
|
1212
|
+
return isPromise(result) ? result.then(merge) : merge(result);
|
|
1213
|
+
};
|
|
1214
|
+
}
|
|
1215
|
+
function useDelayedErrors(errors, delay) {
|
|
1216
|
+
const [shown, setShown] = useState(errors);
|
|
1217
|
+
useEffect(() => {
|
|
1218
|
+
if (delay === void 0) return;
|
|
1219
|
+
if (errors.length === 0) {
|
|
1220
|
+
setShown(errors);
|
|
1221
|
+
return;
|
|
1222
|
+
}
|
|
1223
|
+
if (shown.length > 0) {
|
|
1224
|
+
setShown(errors);
|
|
1225
|
+
return;
|
|
1226
|
+
}
|
|
1227
|
+
const timer = setTimeout(() => setShown(errors), delay);
|
|
1228
|
+
return () => clearTimeout(timer);
|
|
1229
|
+
}, [errors, delay, shown]);
|
|
1230
|
+
return delay === void 0 ? errors : shown;
|
|
1231
|
+
}
|
|
1232
|
+
function useFieldCore({
|
|
1233
|
+
form: f1,
|
|
1234
|
+
name,
|
|
1235
|
+
initialValue,
|
|
1236
|
+
shouldUnregister,
|
|
1237
|
+
validate,
|
|
1238
|
+
rules,
|
|
1239
|
+
validateDebounce,
|
|
1240
|
+
delayError,
|
|
1241
|
+
disabled
|
|
1242
|
+
}, Context) {
|
|
1243
|
+
const contextForm = useContext(Context);
|
|
1244
|
+
const form = f1 || contextForm;
|
|
1245
|
+
if (!form) throw new Error("no form provided");
|
|
1246
|
+
const path = usePath(name);
|
|
1247
|
+
const validator = useValidate(
|
|
1248
|
+
combineRulesAndValidate(rules, validate),
|
|
1249
|
+
path,
|
|
1250
|
+
form,
|
|
1251
|
+
{
|
|
1252
|
+
debounce: validateDebounce
|
|
1253
|
+
}
|
|
1254
|
+
);
|
|
1255
|
+
const liveErrors = useFieldErrorsByPath(form, path);
|
|
1256
|
+
const errors = useDelayedErrors(liveErrors, delayError);
|
|
1257
|
+
const errorObject = errors[0];
|
|
1258
|
+
const error = errorObject?.message;
|
|
1259
|
+
const value = useValueByPath(form, path);
|
|
1260
|
+
const formDisabled = useWatch(form.emitter, "disabled", () => form.disabled);
|
|
1261
|
+
useEffect(() => {
|
|
1262
|
+
if (initialValue === void 0) return;
|
|
1263
|
+
if (getValueByPath(form, path) === void 0) {
|
|
1264
|
+
setValueByPath(form, path, initialValue);
|
|
1265
|
+
}
|
|
1266
|
+
}, [form, path, initialValue]);
|
|
1267
|
+
const onChange = useStageFn((v) => {
|
|
1268
|
+
setValueByPath(form, path, v);
|
|
1269
|
+
if (form.mode === "onChange" || form.mode === "all" || form.mode === "onTouched" && hasTouchedByPath(form, path) || liveErrors.length > 0 && form.reValidateMode === "onChange")
|
|
1270
|
+
validator();
|
|
1271
|
+
});
|
|
1272
|
+
const onBlur = useStageFn(() => {
|
|
1273
|
+
setTouchedByPath(form, path);
|
|
1274
|
+
if (form.mode === "onBlur" || form.mode === "onTouched" || form.mode === "all" || liveErrors.length > 0 && form.reValidateMode === "onBlur")
|
|
1275
|
+
validator();
|
|
1276
|
+
});
|
|
1277
|
+
useEffect(
|
|
1278
|
+
() => () => {
|
|
1279
|
+
if (shouldUnregister !== false) {
|
|
1280
|
+
removeFieldByPath(form, path);
|
|
1281
|
+
}
|
|
1282
|
+
},
|
|
1283
|
+
[path, form, shouldUnregister]
|
|
1284
|
+
);
|
|
1285
|
+
return {
|
|
1286
|
+
form,
|
|
1287
|
+
value,
|
|
1288
|
+
error,
|
|
1289
|
+
errorObject,
|
|
1290
|
+
errors,
|
|
1291
|
+
onChange,
|
|
1292
|
+
onBlur,
|
|
1293
|
+
name: path.key,
|
|
1294
|
+
disabled: formDisabled || !!disabled
|
|
1295
|
+
};
|
|
1296
|
+
}
|
|
1297
|
+
function useField(options) {
|
|
1298
|
+
return useFieldCore(options, FormContext);
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
let idCounter = 0;
|
|
1302
|
+
function generateId() {
|
|
1303
|
+
return `_${++idCounter}`;
|
|
1304
|
+
}
|
|
1305
|
+
function useFieldArrayCore(options, Context) {
|
|
1306
|
+
const contextForm = useContext(Context);
|
|
1307
|
+
const form = options.form || contextForm;
|
|
1308
|
+
if (!form) throw new Error("no form provided");
|
|
1309
|
+
const path = usePath(options.name);
|
|
1310
|
+
const idsRef = useRef([]);
|
|
1311
|
+
const getArray = useCallback(
|
|
1312
|
+
() => getValueByPath(form, path) || [],
|
|
1313
|
+
[form, path]
|
|
1314
|
+
);
|
|
1315
|
+
const setArray = useCallback(
|
|
1316
|
+
(arr) => {
|
|
1317
|
+
setValueByPath(form, path, arr);
|
|
1318
|
+
},
|
|
1319
|
+
[form, path]
|
|
1320
|
+
);
|
|
1321
|
+
const computeFields = useCallback(() => {
|
|
1322
|
+
const arr = getArray();
|
|
1323
|
+
while (idsRef.current.length < arr.length) {
|
|
1324
|
+
idsRef.current.push(generateId());
|
|
1325
|
+
}
|
|
1326
|
+
while (idsRef.current.length > arr.length) {
|
|
1327
|
+
idsRef.current.pop();
|
|
1328
|
+
}
|
|
1329
|
+
return idsRef.current.map((id, index) => ({ id, index }));
|
|
1330
|
+
}, [getArray]);
|
|
1331
|
+
const [fields, syncFields] = useReducer(
|
|
1332
|
+
computeFields,
|
|
1333
|
+
void 0,
|
|
1334
|
+
computeFields
|
|
1335
|
+
);
|
|
1336
|
+
useEffect(
|
|
1337
|
+
() => onPathEvent(form.emitter, "change", path, "branch", syncFields),
|
|
1338
|
+
[form.emitter, path]
|
|
1339
|
+
);
|
|
1340
|
+
const append = useStageFn((value) => {
|
|
1341
|
+
const arr = getArray();
|
|
1342
|
+
idsRef.current.push(generateId());
|
|
1343
|
+
setArray([...arr, value]);
|
|
1344
|
+
});
|
|
1345
|
+
const prepend = useStageFn((value) => {
|
|
1346
|
+
const arr = getArray();
|
|
1347
|
+
idsRef.current.unshift(generateId());
|
|
1348
|
+
setArray([value, ...arr]);
|
|
1349
|
+
});
|
|
1350
|
+
const insert = useStageFn((index, value) => {
|
|
1351
|
+
const arr = getArray();
|
|
1352
|
+
idsRef.current.splice(index, 0, generateId());
|
|
1353
|
+
const newArr = [...arr.slice(0, index), value, ...arr.slice(index)];
|
|
1354
|
+
setArray(newArr);
|
|
1355
|
+
});
|
|
1356
|
+
const remove = useStageFn((index) => {
|
|
1357
|
+
const arr = getArray();
|
|
1358
|
+
idsRef.current.splice(index, 1);
|
|
1359
|
+
const newArr = arr.filter((_, i) => i !== index);
|
|
1360
|
+
setArray(newArr);
|
|
1361
|
+
});
|
|
1362
|
+
const swap = useStageFn((from, to) => {
|
|
1363
|
+
const arr = getArray();
|
|
1364
|
+
[idsRef.current[from], idsRef.current[to]] = [
|
|
1365
|
+
idsRef.current[to],
|
|
1366
|
+
idsRef.current[from]
|
|
1367
|
+
];
|
|
1368
|
+
const newArr = [...arr];
|
|
1369
|
+
[newArr[from], newArr[to]] = [newArr[to], newArr[from]];
|
|
1370
|
+
setArray(newArr);
|
|
1371
|
+
});
|
|
1372
|
+
const move = useStageFn((from, to) => {
|
|
1373
|
+
const arr = getArray();
|
|
1374
|
+
const [id] = idsRef.current.splice(from, 1);
|
|
1375
|
+
idsRef.current.splice(to, 0, id);
|
|
1376
|
+
const newArr = [...arr];
|
|
1377
|
+
const [item] = newArr.splice(from, 1);
|
|
1378
|
+
newArr.splice(to, 0, item);
|
|
1379
|
+
setArray(newArr);
|
|
1380
|
+
});
|
|
1381
|
+
const replace = useStageFn((values) => {
|
|
1382
|
+
idsRef.current = values.map(() => generateId());
|
|
1383
|
+
setArray([...values]);
|
|
1384
|
+
});
|
|
1385
|
+
const update = useStageFn((index, value) => {
|
|
1386
|
+
const arr = getArray();
|
|
1387
|
+
if (index < 0 || index >= arr.length) return;
|
|
1388
|
+
const newArr = [...arr];
|
|
1389
|
+
newArr[index] = value;
|
|
1390
|
+
setArray(newArr);
|
|
1391
|
+
});
|
|
1392
|
+
return { fields, append, prepend, insert, remove, swap, move, replace, update };
|
|
1393
|
+
}
|
|
1394
|
+
function useFieldArray(options) {
|
|
1395
|
+
return useFieldArrayCore(options, FormContext);
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
const FormContext = createContext(null);
|
|
1399
|
+
const FormProvider = FormContext.Provider;
|
|
1400
|
+
function useFormContext() {
|
|
1401
|
+
const form = useContext(FormContext);
|
|
1402
|
+
if (!form) throw new Error("no form provided");
|
|
1403
|
+
return form;
|
|
1404
|
+
}
|
|
1405
|
+
function createFormContext() {
|
|
1406
|
+
const Context = createContext(null);
|
|
1407
|
+
function FormProvider2({
|
|
1408
|
+
form,
|
|
1409
|
+
children
|
|
1410
|
+
}) {
|
|
1411
|
+
return createElement(Context.Provider, { value: form }, children);
|
|
1412
|
+
}
|
|
1413
|
+
function useFormContext2() {
|
|
1414
|
+
const form = useContext(Context);
|
|
1415
|
+
if (!form) throw new Error("no form provided");
|
|
1416
|
+
return form;
|
|
1417
|
+
}
|
|
1418
|
+
function useField(options) {
|
|
1419
|
+
return useFieldCore(options, Context);
|
|
1420
|
+
}
|
|
1421
|
+
function useFieldArray(options) {
|
|
1422
|
+
return useFieldArrayCore(options, Context);
|
|
1423
|
+
}
|
|
1424
|
+
return { FormProvider: FormProvider2, useFormContext: useFormContext2, useField, useFieldArray };
|
|
1425
|
+
}
|
|
1426
|
+
const CheckboxGroupContext = createContext(null);
|
|
1427
|
+
const CheckboxGroupProvider = CheckboxGroupContext.Provider;
|
|
1428
|
+
function useCheckboxGroupContext() {
|
|
1429
|
+
const group = useContext(CheckboxGroupContext);
|
|
1430
|
+
if (!group) throw new Error("no group provided");
|
|
1431
|
+
return group;
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
function Form({
|
|
1435
|
+
form: f1,
|
|
1436
|
+
initialValues,
|
|
1437
|
+
values,
|
|
1438
|
+
onSubmit,
|
|
1439
|
+
onValidSubmit,
|
|
1440
|
+
onInvalidSubmit,
|
|
1441
|
+
shouldFocusError,
|
|
1442
|
+
...props
|
|
1443
|
+
}) {
|
|
1444
|
+
const f2 = useForm({ initialValues, values });
|
|
1445
|
+
const form = f1 || f2;
|
|
1446
|
+
const submit = handleSubmit(form, {
|
|
1447
|
+
onSubmit,
|
|
1448
|
+
onValidSubmit,
|
|
1449
|
+
onInvalidSubmit,
|
|
1450
|
+
shouldFocusError
|
|
1451
|
+
});
|
|
1452
|
+
return /* @__PURE__ */ React.createElement(FormProvider, { value: form }, /* @__PURE__ */ React.createElement("form", { ...props, noValidate: true, onSubmit: submit }));
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
function setRef(ref, value) {
|
|
1456
|
+
if (typeof ref === "function") {
|
|
1457
|
+
ref(value);
|
|
1458
|
+
} else if (ref) {
|
|
1459
|
+
ref.current = value;
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
function errorIdFromKey(key) {
|
|
1463
|
+
const id = key.replace(/["'[\],\s]+/g, "-").replace(/^-+|-+$/g, "");
|
|
1464
|
+
return id || "field";
|
|
1465
|
+
}
|
|
1466
|
+
const Field = React.forwardRef(
|
|
1467
|
+
({
|
|
1468
|
+
validate,
|
|
1469
|
+
eventToValue,
|
|
1470
|
+
initialValue,
|
|
1471
|
+
name,
|
|
1472
|
+
asProps,
|
|
1473
|
+
renderError,
|
|
1474
|
+
as,
|
|
1475
|
+
valueToProps,
|
|
1476
|
+
form: formProp,
|
|
1477
|
+
shouldUnregister,
|
|
1478
|
+
rules,
|
|
1479
|
+
validateDebounce,
|
|
1480
|
+
disabled,
|
|
1481
|
+
delayError,
|
|
1482
|
+
...props
|
|
1483
|
+
}, ref) => {
|
|
1484
|
+
const innerRef = React.useRef(null);
|
|
1485
|
+
const [nativeInvalidCount, setNativeInvalidCount] = React.useState(0);
|
|
1486
|
+
const mergedRef = React.useCallback(
|
|
1487
|
+
(node) => {
|
|
1488
|
+
innerRef.current = node;
|
|
1489
|
+
setRef(ref, node);
|
|
1490
|
+
},
|
|
1491
|
+
[ref]
|
|
1492
|
+
);
|
|
1493
|
+
const {
|
|
1494
|
+
value,
|
|
1495
|
+
onChange,
|
|
1496
|
+
onBlur,
|
|
1497
|
+
error,
|
|
1498
|
+
form,
|
|
1499
|
+
name: fieldKey,
|
|
1500
|
+
disabled: isDisabled
|
|
1501
|
+
} = useField({
|
|
1502
|
+
name,
|
|
1503
|
+
form: formProp,
|
|
1504
|
+
initialValue,
|
|
1505
|
+
shouldUnregister,
|
|
1506
|
+
rules,
|
|
1507
|
+
validateDebounce,
|
|
1508
|
+
delayError,
|
|
1509
|
+
disabled,
|
|
1510
|
+
validate: (...params) => {
|
|
1511
|
+
const el = innerRef.current;
|
|
1512
|
+
if (el && typeof el.checkValidity === "function") {
|
|
1513
|
+
el.setCustomValidity("");
|
|
1514
|
+
if (el.checkValidity() === false) {
|
|
1515
|
+
setNativeInvalidCount((count) => count + 1);
|
|
1516
|
+
return void 0;
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
if (validate) return validate(...params);
|
|
1520
|
+
}
|
|
1521
|
+
});
|
|
1522
|
+
const Component = as || "input";
|
|
1523
|
+
React.useEffect(() => {
|
|
1524
|
+
const el = innerRef.current;
|
|
1525
|
+
if (!el || typeof el.setCustomValidity !== "function") return;
|
|
1526
|
+
if (typeof error === "string") {
|
|
1527
|
+
el.setCustomValidity(error);
|
|
1528
|
+
el.reportValidity();
|
|
1529
|
+
} else {
|
|
1530
|
+
el.setCustomValidity("");
|
|
1531
|
+
}
|
|
1532
|
+
}, [error]);
|
|
1533
|
+
React.useEffect(() => {
|
|
1534
|
+
if (nativeInvalidCount > 0) innerRef.current?.reportValidity();
|
|
1535
|
+
}, [nativeInvalidCount]);
|
|
1536
|
+
React.useEffect(
|
|
1537
|
+
() => on(
|
|
1538
|
+
form.emitter,
|
|
1539
|
+
"focusError",
|
|
1540
|
+
(key, options) => {
|
|
1541
|
+
if (key !== fieldKey) return;
|
|
1542
|
+
const el = innerRef.current;
|
|
1543
|
+
if (!el || typeof el.focus !== "function") return;
|
|
1544
|
+
el.focus();
|
|
1545
|
+
if (options?.shouldSelect && typeof el.select === "function") {
|
|
1546
|
+
el.select();
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
),
|
|
1550
|
+
[form, fieldKey]
|
|
1551
|
+
);
|
|
1552
|
+
const toValue = eventToValue ?? ((e) => e.target.value);
|
|
1553
|
+
const errorId = errorIdFromKey(fieldKey);
|
|
1554
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
|
|
1555
|
+
Component,
|
|
1556
|
+
{
|
|
1557
|
+
"aria-invalid": error ? true : void 0,
|
|
1558
|
+
"aria-describedby": error && renderError ? errorId : void 0,
|
|
1559
|
+
...props,
|
|
1560
|
+
name: fieldKey,
|
|
1561
|
+
onBlur,
|
|
1562
|
+
...asProps,
|
|
1563
|
+
...valueToProps ? valueToProps(value) : { value },
|
|
1564
|
+
disabled: isDisabled,
|
|
1565
|
+
onChange: (e) => onChange(toValue(e)),
|
|
1566
|
+
ref: mergedRef
|
|
1567
|
+
}
|
|
1568
|
+
), error && renderError ? /* @__PURE__ */ React.createElement("span", { id: errorId, role: "alert" }, renderError(error, errorId)) : null);
|
|
1569
|
+
}
|
|
1570
|
+
);
|
|
1571
|
+
const Checkbox = React.forwardRef(
|
|
1572
|
+
({
|
|
1573
|
+
name,
|
|
1574
|
+
form,
|
|
1575
|
+
initialValue,
|
|
1576
|
+
shouldUnregister,
|
|
1577
|
+
validate,
|
|
1578
|
+
rules,
|
|
1579
|
+
validateDebounce,
|
|
1580
|
+
disabled,
|
|
1581
|
+
delayError,
|
|
1582
|
+
...props
|
|
1583
|
+
}, ref) => {
|
|
1584
|
+
const {
|
|
1585
|
+
value,
|
|
1586
|
+
onChange,
|
|
1587
|
+
onBlur,
|
|
1588
|
+
error,
|
|
1589
|
+
name: fieldKey,
|
|
1590
|
+
disabled: isDisabled
|
|
1591
|
+
} = useField({
|
|
1592
|
+
name,
|
|
1593
|
+
form,
|
|
1594
|
+
initialValue,
|
|
1595
|
+
shouldUnregister,
|
|
1596
|
+
validate,
|
|
1597
|
+
rules,
|
|
1598
|
+
validateDebounce,
|
|
1599
|
+
delayError,
|
|
1600
|
+
disabled
|
|
1601
|
+
});
|
|
1602
|
+
return /* @__PURE__ */ React.createElement(
|
|
1603
|
+
"input",
|
|
1604
|
+
{
|
|
1605
|
+
"aria-invalid": error ? true : void 0,
|
|
1606
|
+
...props,
|
|
1607
|
+
name: fieldKey,
|
|
1608
|
+
onBlur,
|
|
1609
|
+
type: "checkbox",
|
|
1610
|
+
checked: !!value,
|
|
1611
|
+
disabled: isDisabled,
|
|
1612
|
+
onChange: (e) => onChange(e.target.checked),
|
|
1613
|
+
ref
|
|
1614
|
+
}
|
|
1615
|
+
);
|
|
1616
|
+
}
|
|
1617
|
+
);
|
|
1618
|
+
function toSelectValue(multiple, value) {
|
|
1619
|
+
if (multiple) return Array.isArray(value) ? value : [];
|
|
1620
|
+
return value ?? "";
|
|
1621
|
+
}
|
|
1622
|
+
const Select = React.forwardRef(
|
|
1623
|
+
({
|
|
1624
|
+
name,
|
|
1625
|
+
multiple,
|
|
1626
|
+
children,
|
|
1627
|
+
form,
|
|
1628
|
+
initialValue,
|
|
1629
|
+
shouldUnregister,
|
|
1630
|
+
validate,
|
|
1631
|
+
rules,
|
|
1632
|
+
validateDebounce,
|
|
1633
|
+
disabled,
|
|
1634
|
+
delayError,
|
|
1635
|
+
...props
|
|
1636
|
+
}, ref) => {
|
|
1637
|
+
const {
|
|
1638
|
+
value,
|
|
1639
|
+
onChange,
|
|
1640
|
+
onBlur,
|
|
1641
|
+
error,
|
|
1642
|
+
name: fieldKey,
|
|
1643
|
+
disabled: isDisabled
|
|
1644
|
+
} = useField({
|
|
1645
|
+
name,
|
|
1646
|
+
form,
|
|
1647
|
+
initialValue,
|
|
1648
|
+
shouldUnregister,
|
|
1649
|
+
validate,
|
|
1650
|
+
rules,
|
|
1651
|
+
validateDebounce,
|
|
1652
|
+
delayError,
|
|
1653
|
+
disabled
|
|
1654
|
+
});
|
|
1655
|
+
return /* @__PURE__ */ React.createElement(
|
|
1656
|
+
"select",
|
|
1657
|
+
{
|
|
1658
|
+
"aria-invalid": error ? true : void 0,
|
|
1659
|
+
...props,
|
|
1660
|
+
name: fieldKey,
|
|
1661
|
+
onBlur,
|
|
1662
|
+
multiple,
|
|
1663
|
+
value: toSelectValue(multiple, value),
|
|
1664
|
+
disabled: isDisabled,
|
|
1665
|
+
onChange: (e) => onChange(
|
|
1666
|
+
multiple ? Array.from(e.target.selectedOptions, (option) => option.value) : e.target.value
|
|
1667
|
+
),
|
|
1668
|
+
ref
|
|
1669
|
+
},
|
|
1670
|
+
children
|
|
1671
|
+
);
|
|
1672
|
+
}
|
|
1673
|
+
);
|
|
1674
|
+
|
|
1675
|
+
export { Checkbox, CheckboxGroupContext, CheckboxGroupProvider, Field, Form, FormContext, FormProvider, Select, VALIDATION_OUTCOME, clearErrors, create as createForm, createFormContext, ensureValidate, getDirtyFields, getError, getErrorByPath, getErrors, getFieldErrors, getFieldErrorsByPath, getFieldState, getFirstError, getTouchedFields, getValue, getValueByPath, getValues, handleSubmit, hasErrors, hasTouched, hasTouchedByPath, incrementSubmitCount, isDirty, isTouched, removeField, removeFieldByPath, reset, resetField, setDisabled, setError, setErrorByPath, setFocus, setInitialValues, setIsSubmitting, setSubmitSuccessful, setTouched, setTouchedByPath, setValidatingByPath, setValue, setValueByPath, subscribe, trigger, unsetValidatingByPath, useCheckboxGroupContext, useDirtyFields, useError, useErrorByPath, useField, useFieldArray, useFieldErrors, useFieldErrorsByPath, useForm, useFormContext, useHasErrors, useIsDirty, useIsSubmitting, useSubmitCount, useTouched, useTouchedByPath, useTouchedFields, useValue, useValueByPath, useWatch, validate };
|
|
1676
|
+
//# sourceMappingURL=index.mjs.map
|