formstand 0.22.1 → 0.23.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/CHANGELOG.md +56 -0
- package/dist/{chunk-BMXIZEI4.js → chunk-EQIS5IVH.js} +23 -12
- package/dist/chunk-EQIS5IVH.js.map +1 -0
- package/dist/{createForm-BJum0RBu.d.cts → createForm-BexUOCjZ.d.cts} +7 -3
- package/dist/{createForm-BJum0RBu.d.ts → createForm-BexUOCjZ.d.ts} +7 -3
- package/dist/devtools/index.cjs.map +1 -1
- package/dist/devtools/index.d.cts +3 -2
- package/dist/devtools/index.d.ts +3 -2
- package/dist/devtools/index.js +1 -1
- package/dist/index.cjs +128 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -4
- package/dist/index.d.ts +19 -4
- package/dist/index.js +109 -8
- package/dist/index.js.map +1 -1
- package/dist/testing/index.d.cts +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/package.json +2 -2
- package/dist/chunk-BMXIZEI4.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -210,11 +210,11 @@ var hasOwnSlot = (obj, path) => parsePath(path).reduce(
|
|
|
210
210
|
},
|
|
211
211
|
{ ok: true, current: obj }
|
|
212
212
|
).ok;
|
|
213
|
-
var writeIntoArray = (arr, index, rest, value) => {
|
|
213
|
+
var writeIntoArray = (arr, index, rest, value, kindAt, prefix) => {
|
|
214
214
|
const length = Math.max(arr.length, index + 1);
|
|
215
215
|
return Array.from(
|
|
216
216
|
{ length },
|
|
217
|
-
(_, i) => i === index ? writeSegments(arr[i], rest, value) : arr[i]
|
|
217
|
+
(_, i) => i === index ? writeSegments(arr[i], rest, value, kindAt, [...prefix, index]) : arr[i]
|
|
218
218
|
);
|
|
219
219
|
};
|
|
220
220
|
var refusesHugeIndex = (index) => {
|
|
@@ -226,7 +226,7 @@ var refusesHugeIndex = (index) => {
|
|
|
226
226
|
}
|
|
227
227
|
return false;
|
|
228
228
|
};
|
|
229
|
-
var writeSegments = (obj, segments, value) => {
|
|
229
|
+
var writeSegments = (obj, segments, value, kindAt, prefix) => {
|
|
230
230
|
const [head, ...rest] = segments;
|
|
231
231
|
if (head === void 0) return value;
|
|
232
232
|
if (Array.isArray(obj)) {
|
|
@@ -237,7 +237,7 @@ var writeSegments = (obj, segments, value) => {
|
|
|
237
237
|
return obj;
|
|
238
238
|
}
|
|
239
239
|
if (refusesHugeIndex(head)) return obj;
|
|
240
|
-
return writeIntoArray(obj, head, rest, value);
|
|
240
|
+
return writeIntoArray(obj, head, rest, value, kindAt, prefix);
|
|
241
241
|
}
|
|
242
242
|
if (isPlainRecord(obj)) {
|
|
243
243
|
if (!isPlainObject(obj)) {
|
|
@@ -246,16 +246,27 @@ var writeSegments = (obj, segments, value) => {
|
|
|
246
246
|
);
|
|
247
247
|
return obj;
|
|
248
248
|
}
|
|
249
|
-
const
|
|
250
|
-
return {
|
|
249
|
+
const key2 = String(head);
|
|
250
|
+
return {
|
|
251
|
+
...obj,
|
|
252
|
+
[key2]: writeSegments(obj[key2], rest, value, kindAt, [...prefix, key2])
|
|
253
|
+
};
|
|
251
254
|
}
|
|
252
|
-
|
|
255
|
+
const kind = kindAt?.(prefix.map(String).join(".")) ?? (typeof head === "number" ? "array" : "record");
|
|
256
|
+
if (kind === "array") {
|
|
257
|
+
if (typeof head !== "number") {
|
|
258
|
+
console.warn(
|
|
259
|
+
`[formstand] cannot write string key "${head}" into an array; value left unchanged.`
|
|
260
|
+
);
|
|
261
|
+
return obj;
|
|
262
|
+
}
|
|
253
263
|
if (refusesHugeIndex(head)) return obj;
|
|
254
|
-
return writeIntoArray([], head, rest, value);
|
|
264
|
+
return writeIntoArray([], head, rest, value, kindAt, prefix);
|
|
255
265
|
}
|
|
256
|
-
|
|
266
|
+
const key = String(head);
|
|
267
|
+
return { [key]: writeSegments(void 0, rest, value, kindAt, [...prefix, key]) };
|
|
257
268
|
};
|
|
258
|
-
var setAtPath = (obj, path, value) => writeSegments(obj, parsePath(path), value);
|
|
269
|
+
var setAtPath = (obj, path, value, containerKindAt2) => writeSegments(obj, parsePath(path), value, containerKindAt2, []);
|
|
259
270
|
var issuePathToFormPath = (path) => path.filter((segment) => typeof segment !== "symbol").join(".");
|
|
260
271
|
var expandIssue = (issue, prefix) => {
|
|
261
272
|
const at = [...prefix, ...issue.path];
|
|
@@ -356,6 +367,9 @@ var fieldSchemaForIntrospection = (schema, path) => {
|
|
|
356
367
|
if (s instanceof zod.z.ZodTuple && typeof segment === "number") {
|
|
357
368
|
return s.def.items[segment] ?? null;
|
|
358
369
|
}
|
|
370
|
+
if (s instanceof zod.z.ZodRecord) {
|
|
371
|
+
return s.valueType;
|
|
372
|
+
}
|
|
359
373
|
if (s instanceof zod.z.ZodDiscriminatedUnion || s instanceof zod.z.ZodUnion) {
|
|
360
374
|
const options = s.def.options;
|
|
361
375
|
return options.reduce(
|
|
@@ -370,6 +384,22 @@ var fieldSchemaForIntrospection = (schema, path) => {
|
|
|
370
384
|
schema
|
|
371
385
|
);
|
|
372
386
|
};
|
|
387
|
+
var containerKindAt = (schema) => (prefix) => {
|
|
388
|
+
const sub = fieldSchemaForIntrospection(schema, prefix);
|
|
389
|
+
if (sub === null) return null;
|
|
390
|
+
const unwrapAll = (s) => {
|
|
391
|
+
const inner2 = unwrapForWalk(s);
|
|
392
|
+
return inner2 === null ? s : unwrapAll(inner2);
|
|
393
|
+
};
|
|
394
|
+
const inner = unwrapAll(sub);
|
|
395
|
+
if (inner instanceof zod.z.ZodArray || inner instanceof zod.z.ZodTuple) {
|
|
396
|
+
return "array";
|
|
397
|
+
}
|
|
398
|
+
if (inner instanceof zod.z.ZodObject || inner instanceof zod.z.ZodRecord) {
|
|
399
|
+
return "record";
|
|
400
|
+
}
|
|
401
|
+
return null;
|
|
402
|
+
};
|
|
373
403
|
var fieldSchemaAtPath = (schema, path) => parsePath(path).reduce((current, segment) => {
|
|
374
404
|
if (current === null || hasChecks(current)) return null;
|
|
375
405
|
if (current instanceof zod.z.ZodObject && typeof segment === "string") {
|
|
@@ -473,6 +503,7 @@ var releaseChangedSlices = (server, prevValues, nextValues) => {
|
|
|
473
503
|
};
|
|
474
504
|
var createForm = (schema, options) => {
|
|
475
505
|
const initialMode = options.mode ?? "onBlur";
|
|
506
|
+
const kindAt = containerKindAt(schema);
|
|
476
507
|
const initialReValidateMode = options.reValidateMode ?? "onChange";
|
|
477
508
|
const initial = {
|
|
478
509
|
values: options.initialValues,
|
|
@@ -830,7 +861,7 @@ var createForm = (schema, options) => {
|
|
|
830
861
|
}
|
|
831
862
|
const arr = Array.isArray(current) ? current : [];
|
|
832
863
|
const next = nextArray(arr);
|
|
833
|
-
const written = setAtPath(store.getState().values, path, next);
|
|
864
|
+
const written = setAtPath(store.getState().values, path, next, kindAt);
|
|
834
865
|
clearArrayOpsUnder(store, path, true);
|
|
835
866
|
if (Array.isArray(current) && getAtPath(written, path) === next) {
|
|
836
867
|
recordArrayOp(store, path, {
|
|
@@ -992,7 +1023,7 @@ var createForm = (schema, options) => {
|
|
|
992
1023
|
clearArrayOpsUnder(store, path);
|
|
993
1024
|
store.setState((state) => ({
|
|
994
1025
|
...state,
|
|
995
|
-
values: setAtPath(state.values, path, value),
|
|
1026
|
+
values: setAtPath(state.values, path, value, kindAt),
|
|
996
1027
|
...errorChannels(state, {
|
|
997
1028
|
serverErrors: releaseSpine(state.serverErrors, path)
|
|
998
1029
|
})
|
|
@@ -1139,7 +1170,7 @@ var createForm = (schema, options) => {
|
|
|
1139
1170
|
}
|
|
1140
1171
|
store.setState((state) => ({
|
|
1141
1172
|
...state,
|
|
1142
|
-
values: initialSlot.exists ? setAtPath(state.values, path, initialSlot.value) : state.values,
|
|
1173
|
+
values: initialSlot.exists ? setAtPath(state.values, path, initialSlot.value, kindAt) : state.values,
|
|
1143
1174
|
// A runtime "" path scopes the whole form (the imperative surface is
|
|
1144
1175
|
// string-typed even though FieldPath excludes ""). Server entries
|
|
1145
1176
|
// follow the setValue release contract (releaseSpine).
|
|
@@ -2023,7 +2054,10 @@ function useFieldArray(form, pathArg) {
|
|
|
2023
2054
|
items: Array.isArray(value) ? value : EMPTY_ITEMS,
|
|
2024
2055
|
// Own-key read, like useField: an array named "constructor" must
|
|
2025
2056
|
// not read Object as its error list.
|
|
2026
|
-
error: entryAt(state.errors, path)
|
|
2057
|
+
error: entryAt(state.errors, path),
|
|
2058
|
+
touched: flagAt(state.touched, path),
|
|
2059
|
+
dirty: isFieldDirty(value, getAtPath(state.initialValues, path)),
|
|
2060
|
+
isValidating: flagAt(state.isValidating, path)
|
|
2027
2061
|
};
|
|
2028
2062
|
})
|
|
2029
2063
|
);
|
|
@@ -2092,6 +2126,52 @@ function useFieldArray(form, pathArg) {
|
|
|
2092
2126
|
[form, path]
|
|
2093
2127
|
);
|
|
2094
2128
|
const clearError = react.useCallback(() => form.clearErrors?.(path), [form, path]);
|
|
2129
|
+
const setTouched = react.useCallback(
|
|
2130
|
+
(touched) => form.setTouched?.(path, touched),
|
|
2131
|
+
[form, path]
|
|
2132
|
+
);
|
|
2133
|
+
const onBlur = react.useCallback(() => {
|
|
2134
|
+
form.setTouched?.(path, true);
|
|
2135
|
+
const state = form.store.getState();
|
|
2136
|
+
if (shouldValidateOn(
|
|
2137
|
+
"blur",
|
|
2138
|
+
state.mode,
|
|
2139
|
+
state.reValidateMode,
|
|
2140
|
+
state.submitCount > 0,
|
|
2141
|
+
true
|
|
2142
|
+
)) {
|
|
2143
|
+
form.validateField?.(path);
|
|
2144
|
+
}
|
|
2145
|
+
}, [form, path]);
|
|
2146
|
+
const validate = react.useCallback(
|
|
2147
|
+
() => form.validateField?.(path) ?? { kind: "valid" },
|
|
2148
|
+
[form, path]
|
|
2149
|
+
);
|
|
2150
|
+
const replace = react.useCallback(
|
|
2151
|
+
(next) => {
|
|
2152
|
+
form.setValue?.(path, next);
|
|
2153
|
+
revalidate();
|
|
2154
|
+
},
|
|
2155
|
+
[form, path, revalidate]
|
|
2156
|
+
);
|
|
2157
|
+
const update = react.useCallback(
|
|
2158
|
+
(index, item) => {
|
|
2159
|
+
form.setValue?.(`${path}.${index}`, item);
|
|
2160
|
+
revalidate();
|
|
2161
|
+
},
|
|
2162
|
+
[form, path, revalidate]
|
|
2163
|
+
);
|
|
2164
|
+
const prepend = react.useCallback(
|
|
2165
|
+
(item) => {
|
|
2166
|
+
form.arrayInsert(path, 0, item);
|
|
2167
|
+
revalidate();
|
|
2168
|
+
},
|
|
2169
|
+
[form, path, revalidate]
|
|
2170
|
+
);
|
|
2171
|
+
const clear = react.useCallback(() => {
|
|
2172
|
+
form.setValue?.(path, []);
|
|
2173
|
+
revalidate();
|
|
2174
|
+
}, [form, path, revalidate]);
|
|
2095
2175
|
return react.useMemo(
|
|
2096
2176
|
() => ({
|
|
2097
2177
|
path,
|
|
@@ -2102,13 +2182,45 @@ function useFieldArray(form, pathArg) {
|
|
|
2102
2182
|
firstError: error?.[0],
|
|
2103
2183
|
setError,
|
|
2104
2184
|
clearError,
|
|
2185
|
+
touched: slice.touched,
|
|
2186
|
+
dirty: slice.dirty,
|
|
2187
|
+
isValidating: slice.isValidating,
|
|
2188
|
+
setTouched,
|
|
2189
|
+
onBlur,
|
|
2190
|
+
validate,
|
|
2105
2191
|
push,
|
|
2106
2192
|
remove,
|
|
2107
2193
|
insert,
|
|
2108
2194
|
move,
|
|
2109
|
-
swap
|
|
2195
|
+
swap,
|
|
2196
|
+
replace,
|
|
2197
|
+
update,
|
|
2198
|
+
prepend,
|
|
2199
|
+
clear
|
|
2110
2200
|
}),
|
|
2111
|
-
[
|
|
2201
|
+
[
|
|
2202
|
+
path,
|
|
2203
|
+
fields,
|
|
2204
|
+
items,
|
|
2205
|
+
error,
|
|
2206
|
+
setError,
|
|
2207
|
+
clearError,
|
|
2208
|
+
slice.touched,
|
|
2209
|
+
slice.dirty,
|
|
2210
|
+
slice.isValidating,
|
|
2211
|
+
setTouched,
|
|
2212
|
+
onBlur,
|
|
2213
|
+
validate,
|
|
2214
|
+
push,
|
|
2215
|
+
remove,
|
|
2216
|
+
insert,
|
|
2217
|
+
move,
|
|
2218
|
+
swap,
|
|
2219
|
+
replace,
|
|
2220
|
+
update,
|
|
2221
|
+
prepend,
|
|
2222
|
+
clear
|
|
2223
|
+
]
|
|
2112
2224
|
);
|
|
2113
2225
|
}
|
|
2114
2226
|
var useFormError = (form) => react$1.useStore(
|