vee-validate 4.8.6 → 4.9.1
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 +1 -0
- package/dist/vee-validate.d.ts +266 -73
- package/dist/vee-validate.esm.js +672 -581
- package/dist/vee-validate.js +556 -495
- package/dist/vee-validate.min.js +2 -2
- package/package.json +3 -2
package/dist/vee-validate.esm.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* vee-validate v4.
|
|
2
|
+
* vee-validate v4.9.1
|
|
3
3
|
* (c) 2023 Abdelrahman Awad
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
6
|
-
import { getCurrentInstance, inject, warn as warn$1, computed, ref, watch,
|
|
6
|
+
import { getCurrentInstance, inject, warn as warn$1, unref, computed, ref, watch, isRef, reactive, onUnmounted, nextTick, onMounted, provide, onBeforeUnmount, defineComponent, toRef, resolveDynamicComponent, h, watchEffect, shallowRef } from 'vue';
|
|
7
7
|
import { setupDevtoolsPlugin } from '@vue/devtools-api';
|
|
8
8
|
|
|
9
9
|
function isCallable(fn) {
|
|
@@ -20,6 +20,19 @@ function toNumber(value) {
|
|
|
20
20
|
const n = parseFloat(value);
|
|
21
21
|
return isNaN(n) ? value : n;
|
|
22
22
|
}
|
|
23
|
+
function merge(target, source) {
|
|
24
|
+
Object.keys(source).forEach(key => {
|
|
25
|
+
if (isObject(source[key])) {
|
|
26
|
+
if (!target[key]) {
|
|
27
|
+
target[key] = {};
|
|
28
|
+
}
|
|
29
|
+
merge(target[key], source[key]);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
target[key] = source[key];
|
|
33
|
+
});
|
|
34
|
+
return target;
|
|
35
|
+
}
|
|
23
36
|
|
|
24
37
|
const RULES = {};
|
|
25
38
|
/**
|
|
@@ -390,15 +403,6 @@ function injectWithSelf(symbol, def = undefined) {
|
|
|
390
403
|
function warn(message) {
|
|
391
404
|
warn$1(`[vee-validate]: ${message}`);
|
|
392
405
|
}
|
|
393
|
-
/**
|
|
394
|
-
* Ensures we deal with a singular field value
|
|
395
|
-
*/
|
|
396
|
-
function normalizeField(field) {
|
|
397
|
-
if (Array.isArray(field)) {
|
|
398
|
-
return field[0];
|
|
399
|
-
}
|
|
400
|
-
return field;
|
|
401
|
-
}
|
|
402
406
|
function resolveNextCheckboxValue(currentValue, checkedValue, uncheckedValue) {
|
|
403
407
|
if (Array.isArray(currentValue)) {
|
|
404
408
|
const newVal = [...currentValue];
|
|
@@ -497,6 +501,27 @@ function unravel(value) {
|
|
|
497
501
|
function lazyToRef(value) {
|
|
498
502
|
return computed(() => unravel(value));
|
|
499
503
|
}
|
|
504
|
+
function normalizeErrorItem(message) {
|
|
505
|
+
return Array.isArray(message) ? message : message ? [message] : [];
|
|
506
|
+
}
|
|
507
|
+
function resolveFieldOrPathState(path) {
|
|
508
|
+
const form = injectWithSelf(FormContextKey);
|
|
509
|
+
const state = path ? computed(() => form === null || form === void 0 ? void 0 : form.getPathState(unref(path))) : undefined;
|
|
510
|
+
const field = path ? undefined : inject(FieldContextKey);
|
|
511
|
+
if (!field && !(state === null || state === void 0 ? void 0 : state.value)) {
|
|
512
|
+
warn(`field with name ${unref(path)} was not found`);
|
|
513
|
+
}
|
|
514
|
+
return state || field;
|
|
515
|
+
}
|
|
516
|
+
function omit(obj, keys) {
|
|
517
|
+
const target = {};
|
|
518
|
+
for (const key in obj) {
|
|
519
|
+
if (!keys.includes(key)) {
|
|
520
|
+
target[key] = obj[key];
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
return target;
|
|
524
|
+
}
|
|
500
525
|
|
|
501
526
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
502
527
|
const normalizeChildren = (tag, context, slotProps) => {
|
|
@@ -921,32 +946,64 @@ async function validateObjectSchema(schema, values, opts) {
|
|
|
921
946
|
let ID_COUNTER = 0;
|
|
922
947
|
function useFieldState(path, init) {
|
|
923
948
|
const { value, initialValue, setInitialValue } = _useFieldValue(path, init.modelValue, init.form);
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
949
|
+
if (!init.form) {
|
|
950
|
+
const { errors, setErrors } = createFieldErrors();
|
|
951
|
+
const id = ID_COUNTER >= Number.MAX_SAFE_INTEGER ? 0 : ++ID_COUNTER;
|
|
952
|
+
const meta = createFieldMeta(value, initialValue, errors);
|
|
953
|
+
function setState(state) {
|
|
954
|
+
var _a;
|
|
955
|
+
if ('value' in state) {
|
|
956
|
+
value.value = state.value;
|
|
957
|
+
}
|
|
958
|
+
if ('errors' in state) {
|
|
959
|
+
setErrors(state.errors);
|
|
960
|
+
}
|
|
961
|
+
if ('touched' in state) {
|
|
962
|
+
meta.touched = (_a = state.touched) !== null && _a !== void 0 ? _a : meta.touched;
|
|
963
|
+
}
|
|
964
|
+
if ('initialValue' in state) {
|
|
965
|
+
setInitialValue(state.initialValue);
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
return {
|
|
969
|
+
id,
|
|
970
|
+
path,
|
|
971
|
+
value,
|
|
972
|
+
initialValue,
|
|
973
|
+
meta,
|
|
974
|
+
errors,
|
|
975
|
+
setState,
|
|
976
|
+
};
|
|
977
|
+
}
|
|
978
|
+
const state = init.form.createPathState(path, {
|
|
979
|
+
bails: init.bails,
|
|
980
|
+
label: init.label,
|
|
981
|
+
type: init.type,
|
|
982
|
+
validate: init.validate,
|
|
983
|
+
});
|
|
984
|
+
const errors = computed(() => state.errors);
|
|
927
985
|
function setState(state) {
|
|
928
|
-
var _a;
|
|
986
|
+
var _a, _b, _c;
|
|
929
987
|
if ('value' in state) {
|
|
930
988
|
value.value = state.value;
|
|
931
989
|
}
|
|
932
990
|
if ('errors' in state) {
|
|
933
|
-
|
|
991
|
+
(_a = init.form) === null || _a === void 0 ? void 0 : _a.setFieldError(unref(path), state.errors);
|
|
934
992
|
}
|
|
935
993
|
if ('touched' in state) {
|
|
936
|
-
|
|
994
|
+
(_b = init.form) === null || _b === void 0 ? void 0 : _b.setFieldTouched(unref(path), (_c = state.touched) !== null && _c !== void 0 ? _c : false);
|
|
937
995
|
}
|
|
938
996
|
if ('initialValue' in state) {
|
|
939
997
|
setInitialValue(state.initialValue);
|
|
940
998
|
}
|
|
941
999
|
}
|
|
942
1000
|
return {
|
|
943
|
-
id,
|
|
1001
|
+
id: Array.isArray(state.id) ? state.id[state.id.length - 1] : state.id,
|
|
944
1002
|
path,
|
|
945
1003
|
value,
|
|
946
|
-
initialValue,
|
|
947
|
-
meta,
|
|
948
1004
|
errors,
|
|
949
|
-
|
|
1005
|
+
meta: state,
|
|
1006
|
+
initialValue,
|
|
950
1007
|
setState,
|
|
951
1008
|
};
|
|
952
1009
|
}
|
|
@@ -959,7 +1016,7 @@ function _useFieldValue(path, modelValue, form) {
|
|
|
959
1016
|
if (!form) {
|
|
960
1017
|
return unref(modelRef);
|
|
961
1018
|
}
|
|
962
|
-
return getFromPath(form.
|
|
1019
|
+
return getFromPath(form.initialValues.value, unref(path), unref(modelRef));
|
|
963
1020
|
}
|
|
964
1021
|
function setInitialValue(value) {
|
|
965
1022
|
if (!form) {
|
|
@@ -1017,7 +1074,7 @@ function resolveModelValue(modelValue, form, initialValue, path) {
|
|
|
1017
1074
|
/**
|
|
1018
1075
|
* Creates meta flags state and some associated effects with them
|
|
1019
1076
|
*/
|
|
1020
|
-
function
|
|
1077
|
+
function createFieldMeta(currentValue, initialValue, errors) {
|
|
1021
1078
|
const meta = reactive({
|
|
1022
1079
|
touched: false,
|
|
1023
1080
|
pending: false,
|
|
@@ -1039,29 +1096,12 @@ function _useFieldMeta(currentValue, initialValue, errors) {
|
|
|
1039
1096
|
/**
|
|
1040
1097
|
* Creates the error message state for the field state
|
|
1041
1098
|
*/
|
|
1042
|
-
function
|
|
1043
|
-
|
|
1044
|
-
if (!messages) {
|
|
1045
|
-
return [];
|
|
1046
|
-
}
|
|
1047
|
-
return Array.isArray(messages) ? messages : [messages];
|
|
1048
|
-
}
|
|
1049
|
-
if (!form) {
|
|
1050
|
-
const errors = ref([]);
|
|
1051
|
-
return {
|
|
1052
|
-
errors,
|
|
1053
|
-
errorMessage: computed(() => errors.value[0]),
|
|
1054
|
-
setErrors: (messages) => {
|
|
1055
|
-
errors.value = normalizeErrors(messages);
|
|
1056
|
-
},
|
|
1057
|
-
};
|
|
1058
|
-
}
|
|
1059
|
-
const errors = computed(() => form.errorBag.value[unref(path)] || []);
|
|
1099
|
+
function createFieldErrors() {
|
|
1100
|
+
const errors = ref([]);
|
|
1060
1101
|
return {
|
|
1061
1102
|
errors,
|
|
1062
|
-
errorMessage: computed(() => errors.value[0]),
|
|
1063
1103
|
setErrors: (messages) => {
|
|
1064
|
-
|
|
1104
|
+
errors.value = normalizeErrorItem(messages);
|
|
1065
1105
|
},
|
|
1066
1106
|
};
|
|
1067
1107
|
}
|
|
@@ -1151,7 +1191,17 @@ function setupApiHooks(api) {
|
|
|
1151
1191
|
console.error('There is not a valid selected vee-validate node or component');
|
|
1152
1192
|
return;
|
|
1153
1193
|
}
|
|
1154
|
-
|
|
1194
|
+
if (SELECTED_NODE.type === 'field') {
|
|
1195
|
+
await SELECTED_NODE.field.validate();
|
|
1196
|
+
return;
|
|
1197
|
+
}
|
|
1198
|
+
if (SELECTED_NODE.type === 'form') {
|
|
1199
|
+
await SELECTED_NODE.form.validate();
|
|
1200
|
+
return;
|
|
1201
|
+
}
|
|
1202
|
+
if (SELECTED_NODE.type === 'pathState') {
|
|
1203
|
+
await SELECTED_NODE.form.validateField(SELECTED_NODE.state.path);
|
|
1204
|
+
}
|
|
1155
1205
|
},
|
|
1156
1206
|
},
|
|
1157
1207
|
{
|
|
@@ -1162,11 +1212,16 @@ function setupApiHooks(api) {
|
|
|
1162
1212
|
console.error('There is not a valid selected vee-validate node or component');
|
|
1163
1213
|
return;
|
|
1164
1214
|
}
|
|
1165
|
-
if ('
|
|
1166
|
-
SELECTED_NODE.resetField();
|
|
1215
|
+
if (SELECTED_NODE.type === 'field') {
|
|
1216
|
+
SELECTED_NODE.field.resetField();
|
|
1167
1217
|
return;
|
|
1168
1218
|
}
|
|
1169
|
-
SELECTED_NODE.
|
|
1219
|
+
if (SELECTED_NODE.type === 'form') {
|
|
1220
|
+
SELECTED_NODE.form.resetForm();
|
|
1221
|
+
}
|
|
1222
|
+
if (SELECTED_NODE.type === 'pathState') {
|
|
1223
|
+
SELECTED_NODE.form.resetField(SELECTED_NODE.state.path);
|
|
1224
|
+
}
|
|
1170
1225
|
},
|
|
1171
1226
|
},
|
|
1172
1227
|
],
|
|
@@ -1186,29 +1241,37 @@ function setupApiHooks(api) {
|
|
|
1186
1241
|
if (payload.inspectorId !== INSPECTOR_ID || ctx.currentTab !== `custom-inspector:${INSPECTOR_ID}`) {
|
|
1187
1242
|
return;
|
|
1188
1243
|
}
|
|
1189
|
-
const { form, field, type } = decodeNodeId(payload.nodeId);
|
|
1244
|
+
const { form, field, state, type } = decodeNodeId(payload.nodeId);
|
|
1190
1245
|
if (form && type === 'form') {
|
|
1191
1246
|
payload.state = buildFormState(form);
|
|
1192
|
-
SELECTED_NODE = form;
|
|
1247
|
+
SELECTED_NODE = { type: 'form', form };
|
|
1248
|
+
return;
|
|
1249
|
+
}
|
|
1250
|
+
if (state && type === 'pathState' && form) {
|
|
1251
|
+
payload.state = buildFieldState(state);
|
|
1252
|
+
SELECTED_NODE = { type: 'pathState', state, form };
|
|
1193
1253
|
return;
|
|
1194
1254
|
}
|
|
1195
1255
|
if (field && type === 'field') {
|
|
1196
|
-
payload.state = buildFieldState(
|
|
1197
|
-
|
|
1256
|
+
payload.state = buildFieldState({
|
|
1257
|
+
errors: field.errors.value,
|
|
1258
|
+
dirty: field.meta.dirty,
|
|
1259
|
+
valid: field.meta.valid,
|
|
1260
|
+
touched: field.meta.touched,
|
|
1261
|
+
value: field.value.value,
|
|
1262
|
+
initialValue: field.meta.initialValue,
|
|
1263
|
+
});
|
|
1264
|
+
SELECTED_NODE = { field, type: 'field' };
|
|
1198
1265
|
return;
|
|
1199
1266
|
}
|
|
1200
1267
|
SELECTED_NODE = null;
|
|
1201
1268
|
});
|
|
1202
1269
|
}
|
|
1203
1270
|
function mapFormForDevtoolsInspector(form) {
|
|
1204
|
-
const { textColor, bgColor } =
|
|
1271
|
+
const { textColor, bgColor } = getValidityColors(form.meta.value.valid);
|
|
1205
1272
|
const formTreeNodes = {};
|
|
1206
|
-
Object.values(form.
|
|
1207
|
-
|
|
1208
|
-
if (!fieldInstance) {
|
|
1209
|
-
return;
|
|
1210
|
-
}
|
|
1211
|
-
setInPath(formTreeNodes, unref(fieldInstance.name), mapFieldForDevtoolsInspector(fieldInstance, form));
|
|
1273
|
+
Object.values(form.getAllPathStates()).forEach(state => {
|
|
1274
|
+
setInPath(formTreeNodes, unref(state.path), mapPathForDevtoolsInspector(state, form));
|
|
1212
1275
|
});
|
|
1213
1276
|
function buildFormTree(tree, path = []) {
|
|
1214
1277
|
const key = [...path].pop();
|
|
@@ -1243,68 +1306,71 @@ function mapFormForDevtoolsInspector(form) {
|
|
|
1243
1306
|
backgroundColor: bgColor,
|
|
1244
1307
|
},
|
|
1245
1308
|
{
|
|
1246
|
-
label: `${
|
|
1309
|
+
label: `${form.getAllPathStates().length} fields`,
|
|
1247
1310
|
textColor: COLORS.white,
|
|
1248
1311
|
backgroundColor: COLORS.unknown,
|
|
1249
1312
|
},
|
|
1250
1313
|
],
|
|
1251
1314
|
};
|
|
1252
1315
|
}
|
|
1316
|
+
function mapPathForDevtoolsInspector(state, form) {
|
|
1317
|
+
return {
|
|
1318
|
+
id: encodeNodeId(form, state),
|
|
1319
|
+
label: unref(state.path),
|
|
1320
|
+
tags: getFieldNodeTags(state.multiple, state.fieldsCount, state.type, state.valid, form),
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1253
1323
|
function mapFieldForDevtoolsInspector(field, form) {
|
|
1254
|
-
const fieldInstance = normalizeField(field);
|
|
1255
|
-
const { textColor, bgColor } = getTagTheme(fieldInstance);
|
|
1256
|
-
const isGroup = Array.isArray(field) && field.length > 1;
|
|
1257
1324
|
return {
|
|
1258
|
-
id: encodeNodeId(form,
|
|
1259
|
-
label: unref(
|
|
1260
|
-
|
|
1261
|
-
tags: [
|
|
1262
|
-
isGroup
|
|
1263
|
-
? undefined
|
|
1264
|
-
: {
|
|
1265
|
-
label: 'Field',
|
|
1266
|
-
textColor,
|
|
1267
|
-
backgroundColor: bgColor,
|
|
1268
|
-
},
|
|
1269
|
-
!form
|
|
1270
|
-
? {
|
|
1271
|
-
label: 'Standalone',
|
|
1272
|
-
textColor: COLORS.black,
|
|
1273
|
-
backgroundColor: COLORS.gray,
|
|
1274
|
-
}
|
|
1275
|
-
: undefined,
|
|
1276
|
-
!isGroup && fieldInstance.type === 'checkbox'
|
|
1277
|
-
? {
|
|
1278
|
-
label: 'Checkbox',
|
|
1279
|
-
textColor: COLORS.white,
|
|
1280
|
-
backgroundColor: COLORS.blue,
|
|
1281
|
-
}
|
|
1282
|
-
: undefined,
|
|
1283
|
-
!isGroup && fieldInstance.type === 'radio'
|
|
1284
|
-
? {
|
|
1285
|
-
label: 'Radio',
|
|
1286
|
-
textColor: COLORS.white,
|
|
1287
|
-
backgroundColor: COLORS.purple,
|
|
1288
|
-
}
|
|
1289
|
-
: undefined,
|
|
1290
|
-
isGroup
|
|
1291
|
-
? {
|
|
1292
|
-
label: 'Group',
|
|
1293
|
-
textColor: COLORS.black,
|
|
1294
|
-
backgroundColor: COLORS.orange,
|
|
1295
|
-
}
|
|
1296
|
-
: undefined,
|
|
1297
|
-
].filter(Boolean),
|
|
1325
|
+
id: encodeNodeId(form, field),
|
|
1326
|
+
label: unref(field.name),
|
|
1327
|
+
tags: getFieldNodeTags(false, 1, field.type, field.meta.valid, form),
|
|
1298
1328
|
};
|
|
1299
1329
|
}
|
|
1300
|
-
function
|
|
1301
|
-
const
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1330
|
+
function getFieldNodeTags(multiple, fieldsCount, type, valid, form) {
|
|
1331
|
+
const { textColor, bgColor } = getValidityColors(valid);
|
|
1332
|
+
return [
|
|
1333
|
+
multiple
|
|
1334
|
+
? undefined
|
|
1335
|
+
: {
|
|
1336
|
+
label: 'Field',
|
|
1337
|
+
textColor,
|
|
1338
|
+
backgroundColor: bgColor,
|
|
1339
|
+
},
|
|
1340
|
+
!form
|
|
1341
|
+
? {
|
|
1342
|
+
label: 'Standalone',
|
|
1343
|
+
textColor: COLORS.black,
|
|
1344
|
+
backgroundColor: COLORS.gray,
|
|
1345
|
+
}
|
|
1346
|
+
: undefined,
|
|
1347
|
+
type === 'checkbox'
|
|
1348
|
+
? {
|
|
1349
|
+
label: 'Checkbox',
|
|
1350
|
+
textColor: COLORS.white,
|
|
1351
|
+
backgroundColor: COLORS.blue,
|
|
1352
|
+
}
|
|
1353
|
+
: undefined,
|
|
1354
|
+
type === 'radio'
|
|
1355
|
+
? {
|
|
1356
|
+
label: 'Radio',
|
|
1357
|
+
textColor: COLORS.white,
|
|
1358
|
+
backgroundColor: COLORS.purple,
|
|
1359
|
+
}
|
|
1360
|
+
: undefined,
|
|
1361
|
+
multiple
|
|
1362
|
+
? {
|
|
1363
|
+
label: 'Multiple',
|
|
1364
|
+
textColor: COLORS.black,
|
|
1365
|
+
backgroundColor: COLORS.orange,
|
|
1366
|
+
}
|
|
1367
|
+
: undefined,
|
|
1368
|
+
].filter(Boolean);
|
|
1369
|
+
}
|
|
1370
|
+
function encodeNodeId(form, stateOrField) {
|
|
1371
|
+
const type = stateOrField ? ('path' in stateOrField ? 'pathState' : 'field') : 'form';
|
|
1372
|
+
const fieldPath = stateOrField ? ('path' in stateOrField ? stateOrField === null || stateOrField === void 0 ? void 0 : stateOrField.path : unref(stateOrField === null || stateOrField === void 0 ? void 0 : stateOrField.name)) : '';
|
|
1373
|
+
const idObject = { f: form === null || form === void 0 ? void 0 : form.formId, ff: fieldPath, type };
|
|
1308
1374
|
return btoa(JSON.stringify(idObject));
|
|
1309
1375
|
}
|
|
1310
1376
|
function decodeNodeId(nodeId) {
|
|
@@ -1324,11 +1390,11 @@ function decodeNodeId(nodeId) {
|
|
|
1324
1390
|
if (!form) {
|
|
1325
1391
|
return {};
|
|
1326
1392
|
}
|
|
1327
|
-
const
|
|
1393
|
+
const state = form.getPathState(idObject.ff);
|
|
1328
1394
|
return {
|
|
1329
1395
|
type: idObject.type,
|
|
1330
1396
|
form,
|
|
1331
|
-
|
|
1397
|
+
state,
|
|
1332
1398
|
};
|
|
1333
1399
|
}
|
|
1334
1400
|
catch (err) {
|
|
@@ -1336,30 +1402,29 @@ function decodeNodeId(nodeId) {
|
|
|
1336
1402
|
}
|
|
1337
1403
|
return {};
|
|
1338
1404
|
}
|
|
1339
|
-
function buildFieldState(
|
|
1340
|
-
const { errors, meta, value } = field;
|
|
1405
|
+
function buildFieldState(state) {
|
|
1341
1406
|
return {
|
|
1342
1407
|
'Field state': [
|
|
1343
|
-
{ key: 'errors', value: errors
|
|
1408
|
+
{ key: 'errors', value: state.errors },
|
|
1344
1409
|
{
|
|
1345
1410
|
key: 'initialValue',
|
|
1346
|
-
value:
|
|
1411
|
+
value: state.initialValue,
|
|
1347
1412
|
},
|
|
1348
1413
|
{
|
|
1349
1414
|
key: 'currentValue',
|
|
1350
|
-
value:
|
|
1415
|
+
value: state.value,
|
|
1351
1416
|
},
|
|
1352
1417
|
{
|
|
1353
1418
|
key: 'touched',
|
|
1354
|
-
value:
|
|
1419
|
+
value: state.touched,
|
|
1355
1420
|
},
|
|
1356
1421
|
{
|
|
1357
1422
|
key: 'dirty',
|
|
1358
|
-
value:
|
|
1423
|
+
value: state.dirty,
|
|
1359
1424
|
},
|
|
1360
1425
|
{
|
|
1361
1426
|
key: 'valid',
|
|
1362
|
-
value:
|
|
1427
|
+
value: state.valid,
|
|
1363
1428
|
},
|
|
1364
1429
|
],
|
|
1365
1430
|
};
|
|
@@ -1413,15 +1478,10 @@ function buildFormState(form) {
|
|
|
1413
1478
|
/**
|
|
1414
1479
|
* Resolves the tag color based on the form state
|
|
1415
1480
|
*/
|
|
1416
|
-
function
|
|
1417
|
-
// const fallbackColors = {
|
|
1418
|
-
// bgColor: COLORS.unknown,
|
|
1419
|
-
// textColor: COLORS.white,
|
|
1420
|
-
// };
|
|
1421
|
-
const isValid = 'id' in fieldOrForm ? fieldOrForm.meta.valid : fieldOrForm.meta.value.valid;
|
|
1481
|
+
function getValidityColors(valid) {
|
|
1422
1482
|
return {
|
|
1423
|
-
bgColor:
|
|
1424
|
-
textColor:
|
|
1483
|
+
bgColor: valid ? COLORS.success : COLORS.error,
|
|
1484
|
+
textColor: valid ? COLORS.black : COLORS.white,
|
|
1425
1485
|
};
|
|
1426
1486
|
}
|
|
1427
1487
|
|
|
@@ -1430,7 +1490,7 @@ function getTagTheme(fieldOrForm) {
|
|
|
1430
1490
|
*/
|
|
1431
1491
|
function useField(path, rules, opts) {
|
|
1432
1492
|
if (hasCheckedAttr(opts === null || opts === void 0 ? void 0 : opts.type)) {
|
|
1433
|
-
return
|
|
1493
|
+
return useFieldWithChecked(path, rules, opts);
|
|
1434
1494
|
}
|
|
1435
1495
|
return _useField(path, rules, opts);
|
|
1436
1496
|
}
|
|
@@ -1439,12 +1499,30 @@ function _useField(path, rules, opts) {
|
|
|
1439
1499
|
const injectedForm = controlled ? injectWithSelf(FormContextKey) : undefined;
|
|
1440
1500
|
const form = controlForm || injectedForm;
|
|
1441
1501
|
const name = lazyToRef(path);
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1502
|
+
let PENDING_UNMOUNT = false;
|
|
1503
|
+
const validator = computed(() => {
|
|
1504
|
+
const schema = unref(form === null || form === void 0 ? void 0 : form.schema);
|
|
1505
|
+
if (schema) {
|
|
1506
|
+
return undefined;
|
|
1507
|
+
}
|
|
1508
|
+
const rulesValue = unref(rules);
|
|
1509
|
+
if (isYupValidator(rulesValue) ||
|
|
1510
|
+
isTypedSchema(rulesValue) ||
|
|
1511
|
+
isCallable(rulesValue) ||
|
|
1512
|
+
Array.isArray(rulesValue)) {
|
|
1513
|
+
return rulesValue;
|
|
1514
|
+
}
|
|
1515
|
+
return normalizeRules(rulesValue);
|
|
1516
|
+
});
|
|
1517
|
+
const { id, value, initialValue, meta, setState, errors } = useFieldState(name, {
|
|
1445
1518
|
modelValue,
|
|
1446
1519
|
form,
|
|
1520
|
+
bails,
|
|
1521
|
+
label,
|
|
1522
|
+
type,
|
|
1523
|
+
validate: validator.value ? validate$1 : undefined,
|
|
1447
1524
|
});
|
|
1525
|
+
const errorMessage = computed(() => errors.value[0]);
|
|
1448
1526
|
if (syncVModel) {
|
|
1449
1527
|
useVModel({ value, prop: modelPropName, handleChange });
|
|
1450
1528
|
}
|
|
@@ -1454,51 +1532,37 @@ function _useField(path, rules, opts) {
|
|
|
1454
1532
|
const handleBlur = () => {
|
|
1455
1533
|
meta.touched = true;
|
|
1456
1534
|
};
|
|
1457
|
-
const normalizedRules = computed(() => {
|
|
1458
|
-
let rulesValue = unref(rules);
|
|
1459
|
-
const schema = unref(form === null || form === void 0 ? void 0 : form.schema);
|
|
1460
|
-
if (schema && !isYupValidator(schema) && !isTypedSchema(schema)) {
|
|
1461
|
-
rulesValue = extractRuleFromSchema(schema, unref(name)) || rulesValue;
|
|
1462
|
-
}
|
|
1463
|
-
if (isYupValidator(rulesValue) ||
|
|
1464
|
-
isTypedSchema(rulesValue) ||
|
|
1465
|
-
isCallable(rulesValue) ||
|
|
1466
|
-
Array.isArray(rulesValue)) {
|
|
1467
|
-
return rulesValue;
|
|
1468
|
-
}
|
|
1469
|
-
return normalizeRules(rulesValue);
|
|
1470
|
-
});
|
|
1471
1535
|
async function validateCurrentValue(mode) {
|
|
1472
1536
|
var _a, _b;
|
|
1473
1537
|
if (form === null || form === void 0 ? void 0 : form.validateSchema) {
|
|
1474
1538
|
return (_a = (await form.validateSchema(mode)).results[unref(name)]) !== null && _a !== void 0 ? _a : { valid: true, errors: [] };
|
|
1475
1539
|
}
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1540
|
+
if (validator.value) {
|
|
1541
|
+
return validate(value.value, validator.value, {
|
|
1542
|
+
name: unref(name),
|
|
1543
|
+
label: unref(label),
|
|
1544
|
+
values: (_b = form === null || form === void 0 ? void 0 : form.values) !== null && _b !== void 0 ? _b : {},
|
|
1545
|
+
bails,
|
|
1546
|
+
});
|
|
1547
|
+
}
|
|
1548
|
+
return { valid: true, errors: [] };
|
|
1482
1549
|
}
|
|
1483
1550
|
const validateWithStateMutation = withLatest(async () => {
|
|
1484
1551
|
meta.pending = true;
|
|
1485
1552
|
meta.validated = true;
|
|
1486
1553
|
return validateCurrentValue('validated-only');
|
|
1487
1554
|
}, result => {
|
|
1488
|
-
if (
|
|
1489
|
-
|
|
1490
|
-
result.errors = [];
|
|
1555
|
+
if (PENDING_UNMOUNT) {
|
|
1556
|
+
return;
|
|
1491
1557
|
}
|
|
1492
1558
|
setState({ errors: result.errors });
|
|
1493
1559
|
meta.pending = false;
|
|
1560
|
+
meta.valid = result.valid;
|
|
1494
1561
|
return result;
|
|
1495
1562
|
});
|
|
1496
1563
|
const validateValidStateOnly = withLatest(async () => {
|
|
1497
1564
|
return validateCurrentValue('silent');
|
|
1498
1565
|
}, result => {
|
|
1499
|
-
if (markedForRemoval) {
|
|
1500
|
-
result.valid = true;
|
|
1501
|
-
}
|
|
1502
1566
|
meta.valid = result.valid;
|
|
1503
1567
|
return result;
|
|
1504
1568
|
});
|
|
@@ -1511,7 +1575,7 @@ function _useField(path, rules, opts) {
|
|
|
1511
1575
|
// Common input/change event handler
|
|
1512
1576
|
function handleChange(e, shouldValidate = true) {
|
|
1513
1577
|
const newValue = normalizeEventValue(e);
|
|
1514
|
-
|
|
1578
|
+
setValue(newValue, false);
|
|
1515
1579
|
if (!validateOnValueUpdate && shouldValidate) {
|
|
1516
1580
|
validateWithStateMutation();
|
|
1517
1581
|
}
|
|
@@ -1530,24 +1594,8 @@ function _useField(path, rules, opts) {
|
|
|
1530
1594
|
function setTouched(isTouched) {
|
|
1531
1595
|
meta.touched = isTouched;
|
|
1532
1596
|
}
|
|
1533
|
-
let unwatchValue;
|
|
1534
|
-
let lastWatchedValue = klona(value.value);
|
|
1535
|
-
function watchValue() {
|
|
1536
|
-
unwatchValue = watch(value, (val, oldVal) => {
|
|
1537
|
-
if (isEqual(val, oldVal) && isEqual(val, lastWatchedValue)) {
|
|
1538
|
-
return;
|
|
1539
|
-
}
|
|
1540
|
-
const validateFn = validateOnValueUpdate ? validateWithStateMutation : validateValidStateOnly;
|
|
1541
|
-
validateFn();
|
|
1542
|
-
lastWatchedValue = klona(val);
|
|
1543
|
-
}, {
|
|
1544
|
-
deep: true,
|
|
1545
|
-
});
|
|
1546
|
-
}
|
|
1547
|
-
watchValue();
|
|
1548
1597
|
function resetField(state) {
|
|
1549
1598
|
var _a;
|
|
1550
|
-
unwatchValue === null || unwatchValue === void 0 ? void 0 : unwatchValue();
|
|
1551
1599
|
const newValue = state && 'value' in state ? state.value : initialValue.value;
|
|
1552
1600
|
setState({
|
|
1553
1601
|
value: klona(newValue),
|
|
@@ -1558,22 +1606,41 @@ function _useField(path, rules, opts) {
|
|
|
1558
1606
|
meta.pending = false;
|
|
1559
1607
|
meta.validated = false;
|
|
1560
1608
|
validateValidStateOnly();
|
|
1561
|
-
// need to watch at next tick to avoid triggering the value watcher
|
|
1562
|
-
nextTick(() => {
|
|
1563
|
-
watchValue();
|
|
1564
|
-
});
|
|
1565
1609
|
}
|
|
1566
|
-
function setValue(newValue) {
|
|
1610
|
+
function setValue(newValue, validate = true) {
|
|
1567
1611
|
value.value = newValue;
|
|
1612
|
+
if (!validate) {
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1615
|
+
const validateFn = validateOnValueUpdate ? validateWithStateMutation : validateValidStateOnly;
|
|
1616
|
+
validateFn();
|
|
1568
1617
|
}
|
|
1569
1618
|
function setErrors(errors) {
|
|
1570
1619
|
setState({ errors: Array.isArray(errors) ? errors : [errors] });
|
|
1571
1620
|
}
|
|
1621
|
+
const valueProxy = computed({
|
|
1622
|
+
get() {
|
|
1623
|
+
return value.value;
|
|
1624
|
+
},
|
|
1625
|
+
set(newValue) {
|
|
1626
|
+
setValue(newValue, validateOnValueUpdate);
|
|
1627
|
+
},
|
|
1628
|
+
});
|
|
1629
|
+
if ((process.env.NODE_ENV !== 'production')) {
|
|
1630
|
+
watch(valueProxy, (value, oldValue) => {
|
|
1631
|
+
if (!isObject(value)) {
|
|
1632
|
+
return;
|
|
1633
|
+
}
|
|
1634
|
+
if (value === oldValue && isEqual(value, oldValue)) {
|
|
1635
|
+
warn$1('Detected a possible deep change on field `value` ref, for nested changes please either set the entire ref value or use `setValue` or `handleChange`.');
|
|
1636
|
+
}
|
|
1637
|
+
}, { deep: true });
|
|
1638
|
+
}
|
|
1572
1639
|
const field = {
|
|
1573
1640
|
id,
|
|
1574
1641
|
name,
|
|
1575
1642
|
label,
|
|
1576
|
-
value,
|
|
1643
|
+
value: valueProxy,
|
|
1577
1644
|
meta,
|
|
1578
1645
|
errors,
|
|
1579
1646
|
errorMessage,
|
|
@@ -1617,14 +1684,9 @@ function _useField(path, rules, opts) {
|
|
|
1617
1684
|
return field;
|
|
1618
1685
|
}
|
|
1619
1686
|
// associate the field with the given form
|
|
1620
|
-
form.register(field);
|
|
1621
|
-
onBeforeUnmount(() => {
|
|
1622
|
-
markedForRemoval = true;
|
|
1623
|
-
form.unregister(field);
|
|
1624
|
-
});
|
|
1625
1687
|
// extract cross-field dependencies in a computed prop
|
|
1626
1688
|
const dependencies = computed(() => {
|
|
1627
|
-
const rulesVal =
|
|
1689
|
+
const rulesVal = validator.value;
|
|
1628
1690
|
// is falsy, a function schema or a yup schema
|
|
1629
1691
|
if (!rulesVal ||
|
|
1630
1692
|
isCallable(rulesVal) ||
|
|
@@ -1658,6 +1720,37 @@ function _useField(path, rules, opts) {
|
|
|
1658
1720
|
meta.validated ? validateWithStateMutation() : validateValidStateOnly();
|
|
1659
1721
|
}
|
|
1660
1722
|
});
|
|
1723
|
+
onBeforeUnmount(() => {
|
|
1724
|
+
var _a;
|
|
1725
|
+
PENDING_UNMOUNT = true;
|
|
1726
|
+
const shouldKeepValue = (_a = unref(field.keepValueOnUnmount)) !== null && _a !== void 0 ? _a : unref(form.keepValuesOnUnmount);
|
|
1727
|
+
if (shouldKeepValue || !form) {
|
|
1728
|
+
return;
|
|
1729
|
+
}
|
|
1730
|
+
const path = unravel(name);
|
|
1731
|
+
const pathState = form.getPathState(path);
|
|
1732
|
+
const matchesId = Array.isArray(pathState === null || pathState === void 0 ? void 0 : pathState.id) && (pathState === null || pathState === void 0 ? void 0 : pathState.multiple)
|
|
1733
|
+
? pathState === null || pathState === void 0 ? void 0 : pathState.id.includes(field.id)
|
|
1734
|
+
: (pathState === null || pathState === void 0 ? void 0 : pathState.id) === field.id;
|
|
1735
|
+
if (!matchesId) {
|
|
1736
|
+
return;
|
|
1737
|
+
}
|
|
1738
|
+
if ((pathState === null || pathState === void 0 ? void 0 : pathState.multiple) && Array.isArray(pathState.value)) {
|
|
1739
|
+
const valueIdx = pathState.value.findIndex(i => isEqual(i, unref(field.checkedValue)));
|
|
1740
|
+
if (valueIdx > -1) {
|
|
1741
|
+
const newVal = [...pathState.value];
|
|
1742
|
+
newVal.splice(valueIdx, 1);
|
|
1743
|
+
form.setFieldValue(path, newVal);
|
|
1744
|
+
}
|
|
1745
|
+
if (Array.isArray(pathState.id)) {
|
|
1746
|
+
pathState.id.splice(pathState.id.indexOf(field.id), 1);
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
else {
|
|
1750
|
+
form.unsetPathValue(path);
|
|
1751
|
+
}
|
|
1752
|
+
form.removePathState(path);
|
|
1753
|
+
});
|
|
1661
1754
|
return field;
|
|
1662
1755
|
}
|
|
1663
1756
|
/**
|
|
@@ -1688,22 +1781,11 @@ function normalizeOptions(opts) {
|
|
|
1688
1781
|
const controlled = 'standalone' in opts ? !opts.standalone : opts.controlled;
|
|
1689
1782
|
return Object.assign(Object.assign(Object.assign({}, defaults()), (opts || {})), { initialValue, controlled: controlled !== null && controlled !== void 0 ? controlled : true, checkedValue });
|
|
1690
1783
|
}
|
|
1691
|
-
|
|
1692
|
-
* Extracts the validation rules from a schema
|
|
1693
|
-
*/
|
|
1694
|
-
function extractRuleFromSchema(schema, fieldName) {
|
|
1695
|
-
// no schema at all
|
|
1696
|
-
if (!schema) {
|
|
1697
|
-
return undefined;
|
|
1698
|
-
}
|
|
1699
|
-
// there is a key on the schema object for this field
|
|
1700
|
-
return schema[fieldName];
|
|
1701
|
-
}
|
|
1702
|
-
function useCheckboxField(name, rules, opts) {
|
|
1784
|
+
function useFieldWithChecked(name, rules, opts) {
|
|
1703
1785
|
const form = !(opts === null || opts === void 0 ? void 0 : opts.standalone) ? injectWithSelf(FormContextKey) : undefined;
|
|
1704
1786
|
const checkedValue = opts === null || opts === void 0 ? void 0 : opts.checkedValue;
|
|
1705
1787
|
const uncheckedValue = opts === null || opts === void 0 ? void 0 : opts.uncheckedValue;
|
|
1706
|
-
function
|
|
1788
|
+
function patchCheckedApi(field) {
|
|
1707
1789
|
const handleChange = field.handleChange;
|
|
1708
1790
|
const checked = computed(() => {
|
|
1709
1791
|
const currentValue = unref(field.value);
|
|
@@ -1720,9 +1802,15 @@ function useCheckboxField(name, rules, opts) {
|
|
|
1720
1802
|
}
|
|
1721
1803
|
return;
|
|
1722
1804
|
}
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1805
|
+
const path = unravel(name);
|
|
1806
|
+
const pathState = form === null || form === void 0 ? void 0 : form.getPathState(path);
|
|
1807
|
+
const value = normalizeEventValue(e);
|
|
1808
|
+
let newValue;
|
|
1809
|
+
if (form && (pathState === null || pathState === void 0 ? void 0 : pathState.multiple) && pathState.type === 'checkbox') {
|
|
1810
|
+
newValue = resolveNextCheckboxValue(getFromPath(form.values, path) || [], value, undefined);
|
|
1811
|
+
}
|
|
1812
|
+
else {
|
|
1813
|
+
// Single checkbox field without a form to toggle it's value
|
|
1726
1814
|
newValue = resolveNextCheckboxValue(unref(field.value), unref(checkedValue), unref(uncheckedValue));
|
|
1727
1815
|
}
|
|
1728
1816
|
handleChange(newValue, shouldValidate);
|
|
@@ -1731,7 +1819,7 @@ function useCheckboxField(name, rules, opts) {
|
|
|
1731
1819
|
checkedValue,
|
|
1732
1820
|
uncheckedValue, handleChange: handleCheckboxChange });
|
|
1733
1821
|
}
|
|
1734
|
-
return
|
|
1822
|
+
return patchCheckedApi(_useField(name, rules, opts));
|
|
1735
1823
|
}
|
|
1736
1824
|
function useVModel({ prop, value, handleChange }) {
|
|
1737
1825
|
const vm = getCurrentInstance();
|
|
@@ -1876,9 +1964,27 @@ const FieldImpl = defineComponent({
|
|
|
1876
1964
|
};
|
|
1877
1965
|
const fieldProps = computed(() => {
|
|
1878
1966
|
const { validateOnInput, validateOnChange, validateOnBlur, validateOnModelUpdate } = resolveValidationTriggers(props);
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1967
|
+
function baseOnBlur(e) {
|
|
1968
|
+
handleBlur(e);
|
|
1969
|
+
if (isCallable(ctx.attrs.onBlur)) {
|
|
1970
|
+
ctx.attrs.onBlur(e);
|
|
1971
|
+
}
|
|
1972
|
+
if (validateOnBlur) {
|
|
1973
|
+
validateField();
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
function baseOnInput(e) {
|
|
1977
|
+
onChangeHandler(e, validateOnInput);
|
|
1978
|
+
if (isCallable(ctx.attrs.onInput)) {
|
|
1979
|
+
ctx.attrs.onInput(e);
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
function baseOnChange(e) {
|
|
1983
|
+
onChangeHandler(e, validateOnChange);
|
|
1984
|
+
if (isCallable(ctx.attrs.onChange)) {
|
|
1985
|
+
ctx.attrs.onChange(e);
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1882
1988
|
const attrs = {
|
|
1883
1989
|
name: props.name,
|
|
1884
1990
|
onBlur: baseOnBlur,
|
|
@@ -1957,6 +2063,7 @@ function resolveInitialValue(props, ctx) {
|
|
|
1957
2063
|
const Field = FieldImpl;
|
|
1958
2064
|
|
|
1959
2065
|
let FORM_COUNTER = 0;
|
|
2066
|
+
const PRIVATE_PATH_STATE_KEYS = ['bails', 'fieldsCount', 'id', 'multiple', 'type', 'validate'];
|
|
1960
2067
|
function resolveInitialValues(opts) {
|
|
1961
2068
|
const providedValues = unref(opts === null || opts === void 0 ? void 0 : opts.initialValues) || {};
|
|
1962
2069
|
const schema = unref(opts === null || opts === void 0 ? void 0 : opts.validationSchema);
|
|
@@ -1968,12 +2075,8 @@ function resolveInitialValues(opts) {
|
|
|
1968
2075
|
function useForm(opts) {
|
|
1969
2076
|
var _a;
|
|
1970
2077
|
const formId = FORM_COUNTER++;
|
|
1971
|
-
const controlledModelPaths = new Set();
|
|
1972
2078
|
// Prevents fields from double resetting their values, which causes checkboxes to toggle their initial value
|
|
1973
|
-
|
|
1974
|
-
let RESET_LOCK = false;
|
|
1975
|
-
// A lookup containing fields or field groups
|
|
1976
|
-
const fieldsByPath = ref({});
|
|
2079
|
+
let FIELD_ID_COUNTER = 0;
|
|
1977
2080
|
// If the form is currently submitting
|
|
1978
2081
|
const isSubmitting = ref(false);
|
|
1979
2082
|
// The number of times the user tried to submit the form
|
|
@@ -1982,44 +2085,62 @@ function useForm(opts) {
|
|
|
1982
2085
|
const fieldArrays = [];
|
|
1983
2086
|
// a private ref for all form values
|
|
1984
2087
|
const formValues = reactive(resolveInitialValues(opts));
|
|
1985
|
-
|
|
1986
|
-
const
|
|
2088
|
+
const pathStates = ref([]);
|
|
2089
|
+
const extraErrorsBag = ref({});
|
|
2090
|
+
/**
|
|
2091
|
+
* Manually sets an error message on a specific field
|
|
2092
|
+
*/
|
|
2093
|
+
function setFieldError(field, message) {
|
|
2094
|
+
const state = findPathState(field);
|
|
2095
|
+
if (!state) {
|
|
2096
|
+
extraErrorsBag.value[field] = normalizeErrorItem(message);
|
|
2097
|
+
return;
|
|
2098
|
+
}
|
|
2099
|
+
state.errors = normalizeErrorItem(message);
|
|
2100
|
+
}
|
|
2101
|
+
/**
|
|
2102
|
+
* Sets errors for the fields specified in the object
|
|
2103
|
+
*/
|
|
2104
|
+
function setErrors(paths) {
|
|
2105
|
+
keysOf(paths).forEach(path => {
|
|
2106
|
+
setFieldError(path, paths[path]);
|
|
2107
|
+
});
|
|
2108
|
+
}
|
|
2109
|
+
if (opts === null || opts === void 0 ? void 0 : opts.initialErrors) {
|
|
2110
|
+
setErrors(opts.initialErrors);
|
|
2111
|
+
}
|
|
2112
|
+
const errorBag = computed(() => {
|
|
2113
|
+
const pathErrors = pathStates.value.reduce((acc, state) => {
|
|
2114
|
+
if (state.errors.length) {
|
|
2115
|
+
acc[state.path] = state.errors;
|
|
2116
|
+
}
|
|
2117
|
+
return acc;
|
|
2118
|
+
}, {});
|
|
2119
|
+
return Object.assign(Object.assign({}, extraErrorsBag.value), pathErrors);
|
|
2120
|
+
});
|
|
1987
2121
|
// Gets the first error of each field
|
|
1988
2122
|
const errors = computed(() => {
|
|
1989
2123
|
return keysOf(errorBag.value).reduce((acc, key) => {
|
|
1990
|
-
const
|
|
1991
|
-
if (
|
|
1992
|
-
acc[key] =
|
|
2124
|
+
const errors = errorBag.value[key];
|
|
2125
|
+
if (errors === null || errors === void 0 ? void 0 : errors.length) {
|
|
2126
|
+
acc[key] = errors[0];
|
|
1993
2127
|
}
|
|
1994
2128
|
return acc;
|
|
1995
2129
|
}, {});
|
|
1996
2130
|
});
|
|
1997
|
-
function getFirstFieldAtPath(path) {
|
|
1998
|
-
const fieldOrGroup = fieldsByPath.value[path];
|
|
1999
|
-
return Array.isArray(fieldOrGroup) ? fieldOrGroup[0] : fieldOrGroup;
|
|
2000
|
-
}
|
|
2001
|
-
function fieldExists(path) {
|
|
2002
|
-
return !!fieldsByPath.value[path];
|
|
2003
|
-
}
|
|
2004
2131
|
/**
|
|
2005
2132
|
* Holds a computed reference to all fields names and labels
|
|
2006
2133
|
*/
|
|
2007
2134
|
const fieldNames = computed(() => {
|
|
2008
|
-
return
|
|
2009
|
-
|
|
2010
|
-
if (field) {
|
|
2011
|
-
names[path] = { name: unref(field.name) || '', label: unref(field.label) || '' };
|
|
2012
|
-
}
|
|
2135
|
+
return pathStates.value.reduce((names, state) => {
|
|
2136
|
+
names[state.path] = { name: state.path || '', label: state.label || '' };
|
|
2013
2137
|
return names;
|
|
2014
2138
|
}, {});
|
|
2015
2139
|
});
|
|
2016
2140
|
const fieldBailsMap = computed(() => {
|
|
2017
|
-
return
|
|
2141
|
+
return pathStates.value.reduce((map, state) => {
|
|
2018
2142
|
var _a;
|
|
2019
|
-
|
|
2020
|
-
if (field) {
|
|
2021
|
-
map[path] = (_a = field.bails) !== null && _a !== void 0 ? _a : true;
|
|
2022
|
-
}
|
|
2143
|
+
map[state.path] = (_a = state.bails) !== null && _a !== void 0 ? _a : true;
|
|
2023
2144
|
return map;
|
|
2024
2145
|
}, {});
|
|
2025
2146
|
});
|
|
@@ -2028,17 +2149,74 @@ function useForm(opts) {
|
|
|
2028
2149
|
const initialErrors = Object.assign({}, ((opts === null || opts === void 0 ? void 0 : opts.initialErrors) || {}));
|
|
2029
2150
|
const keepValuesOnUnmount = (_a = opts === null || opts === void 0 ? void 0 : opts.keepValuesOnUnmount) !== null && _a !== void 0 ? _a : false;
|
|
2030
2151
|
// initial form values
|
|
2031
|
-
const { initialValues, originalInitialValues, setInitialValues } = useFormInitialValues(
|
|
2152
|
+
const { initialValues, originalInitialValues, setInitialValues } = useFormInitialValues(pathStates, formValues, opts);
|
|
2032
2153
|
// form meta aggregations
|
|
2033
|
-
const meta = useFormMeta(
|
|
2154
|
+
const meta = useFormMeta(pathStates, formValues, originalInitialValues, errors);
|
|
2034
2155
|
const controlledValues = computed(() => {
|
|
2035
|
-
return
|
|
2036
|
-
const value = getFromPath(formValues, path);
|
|
2037
|
-
setInPath(acc, path, value);
|
|
2156
|
+
return pathStates.value.reduce((acc, state) => {
|
|
2157
|
+
const value = getFromPath(formValues, state.path);
|
|
2158
|
+
setInPath(acc, state.path, value);
|
|
2038
2159
|
return acc;
|
|
2039
2160
|
}, {});
|
|
2040
2161
|
});
|
|
2041
2162
|
const schema = opts === null || opts === void 0 ? void 0 : opts.validationSchema;
|
|
2163
|
+
function createPathState(path, config) {
|
|
2164
|
+
var _a, _b;
|
|
2165
|
+
const initialValue = computed(() => getFromPath(initialValues.value, unravel(path)));
|
|
2166
|
+
const pathStateExists = pathStates.value.find(state => state.path === unref(path));
|
|
2167
|
+
if (pathStateExists) {
|
|
2168
|
+
if ((config === null || config === void 0 ? void 0 : config.type) === 'checkbox' || (config === null || config === void 0 ? void 0 : config.type) === 'radio') {
|
|
2169
|
+
pathStateExists.multiple = true;
|
|
2170
|
+
}
|
|
2171
|
+
if (Array.isArray(pathStateExists.id)) {
|
|
2172
|
+
pathStateExists.id.push(FIELD_ID_COUNTER++);
|
|
2173
|
+
}
|
|
2174
|
+
else {
|
|
2175
|
+
pathStateExists.id = [pathStateExists.id, FIELD_ID_COUNTER++];
|
|
2176
|
+
}
|
|
2177
|
+
pathStateExists.fieldsCount++;
|
|
2178
|
+
return pathStateExists;
|
|
2179
|
+
}
|
|
2180
|
+
const currentValue = computed(() => getFromPath(formValues, unravel(path)));
|
|
2181
|
+
const pathValue = unravel(path);
|
|
2182
|
+
const state = reactive({
|
|
2183
|
+
id: FIELD_ID_COUNTER++,
|
|
2184
|
+
path,
|
|
2185
|
+
touched: false,
|
|
2186
|
+
pending: false,
|
|
2187
|
+
valid: true,
|
|
2188
|
+
validated: !!((_a = initialErrors[pathValue]) === null || _a === void 0 ? void 0 : _a.length),
|
|
2189
|
+
initialValue,
|
|
2190
|
+
errors: shallowRef([]),
|
|
2191
|
+
bails: (_b = config === null || config === void 0 ? void 0 : config.bails) !== null && _b !== void 0 ? _b : false,
|
|
2192
|
+
label: config === null || config === void 0 ? void 0 : config.label,
|
|
2193
|
+
type: (config === null || config === void 0 ? void 0 : config.type) || 'default',
|
|
2194
|
+
value: currentValue,
|
|
2195
|
+
multiple: false,
|
|
2196
|
+
fieldsCount: 1,
|
|
2197
|
+
validate: config === null || config === void 0 ? void 0 : config.validate,
|
|
2198
|
+
dirty: computed(() => {
|
|
2199
|
+
return !isEqual(unref(currentValue), unref(initialValue));
|
|
2200
|
+
}),
|
|
2201
|
+
});
|
|
2202
|
+
pathStates.value.push(state);
|
|
2203
|
+
// if it has errors before, validate it.
|
|
2204
|
+
if (errors.value[pathValue] && !initialErrors[pathValue]) {
|
|
2205
|
+
nextTick(() => {
|
|
2206
|
+
validateField(pathValue);
|
|
2207
|
+
});
|
|
2208
|
+
}
|
|
2209
|
+
// Handles when a path changes
|
|
2210
|
+
if (isRef(path)) {
|
|
2211
|
+
watch(path, newPath => {
|
|
2212
|
+
const nextValue = klona(currentValue.value);
|
|
2213
|
+
nextTick(() => {
|
|
2214
|
+
setInPath(formValues, newPath, nextValue);
|
|
2215
|
+
});
|
|
2216
|
+
});
|
|
2217
|
+
}
|
|
2218
|
+
return state;
|
|
2219
|
+
}
|
|
2042
2220
|
/**
|
|
2043
2221
|
* Batches validation runs in 5ms batches
|
|
2044
2222
|
* Must have two distinct batch queues to make sure they don't override each other settings #3783
|
|
@@ -2049,17 +2227,17 @@ function useForm(opts) {
|
|
|
2049
2227
|
return (await mode) === 'silent' ? debouncedSilentValidation() : debouncedValidation();
|
|
2050
2228
|
}, (formResult, [mode]) => {
|
|
2051
2229
|
// fields by id lookup
|
|
2052
|
-
const fieldsById = formCtx.fieldsByPath.value || {};
|
|
2053
2230
|
// errors fields names, we need it to also check if custom errors are updated
|
|
2054
2231
|
const currentErrorsPaths = keysOf(formCtx.errorBag.value);
|
|
2055
2232
|
// collect all the keys from the schema and all fields
|
|
2056
|
-
// this ensures we have a complete
|
|
2233
|
+
// this ensures we have a complete key map of all the fields
|
|
2057
2234
|
const paths = [
|
|
2058
|
-
...new Set([...keysOf(formResult.results), ...
|
|
2235
|
+
...new Set([...keysOf(formResult.results), ...pathStates.value.map(p => p.path), ...currentErrorsPaths]),
|
|
2059
2236
|
];
|
|
2060
2237
|
// aggregates the paths into a single result object while applying the results on the fields
|
|
2061
|
-
return paths.reduce((validation,
|
|
2062
|
-
const
|
|
2238
|
+
return paths.reduce((validation, _path) => {
|
|
2239
|
+
const path = _path;
|
|
2240
|
+
const pathState = findPathState(path);
|
|
2063
2241
|
const messages = (formResult.results[path] || { errors: [] }).errors;
|
|
2064
2242
|
const fieldResult = {
|
|
2065
2243
|
errors: messages,
|
|
@@ -2069,24 +2247,37 @@ function useForm(opts) {
|
|
|
2069
2247
|
if (!fieldResult.valid) {
|
|
2070
2248
|
validation.errors[path] = fieldResult.errors[0];
|
|
2071
2249
|
}
|
|
2250
|
+
// clean up extra errors if path state exists
|
|
2251
|
+
if (pathState && extraErrorsBag.value[path]) {
|
|
2252
|
+
delete extraErrorsBag.value[path];
|
|
2253
|
+
}
|
|
2072
2254
|
// field not rendered
|
|
2073
|
-
if (!
|
|
2255
|
+
if (!pathState) {
|
|
2074
2256
|
setFieldError(path, messages);
|
|
2075
2257
|
return validation;
|
|
2076
2258
|
}
|
|
2077
2259
|
// always update the valid flag regardless of the mode
|
|
2078
|
-
|
|
2260
|
+
pathState.valid = fieldResult.valid;
|
|
2079
2261
|
if (mode === 'silent') {
|
|
2080
2262
|
return validation;
|
|
2081
2263
|
}
|
|
2082
|
-
|
|
2083
|
-
if (mode === 'validated-only' && !wasValidated) {
|
|
2264
|
+
if (mode === 'validated-only' && !pathState.validated) {
|
|
2084
2265
|
return validation;
|
|
2085
2266
|
}
|
|
2086
|
-
|
|
2267
|
+
setFieldError(pathState, fieldResult.errors);
|
|
2087
2268
|
return validation;
|
|
2088
2269
|
}, { valid: formResult.valid, results: {}, errors: {} });
|
|
2089
2270
|
});
|
|
2271
|
+
function mutateAllPathState(mutation) {
|
|
2272
|
+
pathStates.value.forEach(mutation);
|
|
2273
|
+
}
|
|
2274
|
+
function findPathState(path) {
|
|
2275
|
+
const pathState = typeof path === 'string' ? pathStates.value.find(state => state.path === path) : path;
|
|
2276
|
+
return pathState;
|
|
2277
|
+
}
|
|
2278
|
+
function unsetPathValue(path) {
|
|
2279
|
+
unsetPath(formValues, path);
|
|
2280
|
+
}
|
|
2090
2281
|
function makeSubmissionFactory(onlyControlled) {
|
|
2091
2282
|
return function submitHandlerFactory(fn, onValidationError) {
|
|
2092
2283
|
return function submissionHandler(e) {
|
|
@@ -2095,10 +2286,7 @@ function useForm(opts) {
|
|
|
2095
2286
|
e.stopPropagation();
|
|
2096
2287
|
}
|
|
2097
2288
|
// Touch all fields
|
|
2098
|
-
|
|
2099
|
-
acc[field] = true;
|
|
2100
|
-
return acc;
|
|
2101
|
-
}, {}));
|
|
2289
|
+
mutateAllPathState(s => (s.touched = true));
|
|
2102
2290
|
isSubmitting.value = true;
|
|
2103
2291
|
submitCount.value++;
|
|
2104
2292
|
return validate()
|
|
@@ -2106,7 +2294,7 @@ function useForm(opts) {
|
|
|
2106
2294
|
const values = klona(formValues);
|
|
2107
2295
|
if (result.valid && typeof fn === 'function') {
|
|
2108
2296
|
const controlled = klona(controlledValues.value);
|
|
2109
|
-
let submittedValues = onlyControlled ? controlled : values;
|
|
2297
|
+
let submittedValues = (onlyControlled ? controlled : values);
|
|
2110
2298
|
if (result.values) {
|
|
2111
2299
|
submittedValues = result.values;
|
|
2112
2300
|
}
|
|
@@ -2146,9 +2334,22 @@ function useForm(opts) {
|
|
|
2146
2334
|
const handleSubmitImpl = makeSubmissionFactory(false);
|
|
2147
2335
|
const handleSubmit = handleSubmitImpl;
|
|
2148
2336
|
handleSubmit.withControlled = makeSubmissionFactory(true);
|
|
2337
|
+
function removePathState(path) {
|
|
2338
|
+
const idx = pathStates.value.findIndex(s => s.path === path);
|
|
2339
|
+
const pathState = pathStates.value[idx];
|
|
2340
|
+
if (idx === -1 || !pathState) {
|
|
2341
|
+
return;
|
|
2342
|
+
}
|
|
2343
|
+
if (pathState.multiple && pathState.fieldsCount) {
|
|
2344
|
+
pathState.fieldsCount--;
|
|
2345
|
+
}
|
|
2346
|
+
if (!pathState.multiple || pathState.fieldsCount <= 0) {
|
|
2347
|
+
pathStates.value.splice(idx, 1);
|
|
2348
|
+
unsetInitialValue(path);
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2149
2351
|
const formCtx = {
|
|
2150
2352
|
formId,
|
|
2151
|
-
fieldsByPath,
|
|
2152
2353
|
values: formValues,
|
|
2153
2354
|
controlledValues,
|
|
2154
2355
|
errorBag,
|
|
@@ -2161,14 +2362,11 @@ function useForm(opts) {
|
|
|
2161
2362
|
keepValuesOnUnmount,
|
|
2162
2363
|
validateSchema: unref(schema) ? validateSchema : undefined,
|
|
2163
2364
|
validate,
|
|
2164
|
-
|
|
2165
|
-
unregister: unregisterField,
|
|
2166
|
-
setFieldErrorBag,
|
|
2365
|
+
setFieldError,
|
|
2167
2366
|
validateField,
|
|
2168
2367
|
setFieldValue,
|
|
2169
2368
|
setValues,
|
|
2170
2369
|
setErrors,
|
|
2171
|
-
setFieldError,
|
|
2172
2370
|
setFieldTouched,
|
|
2173
2371
|
setTouched,
|
|
2174
2372
|
resetForm,
|
|
@@ -2178,102 +2376,63 @@ function useForm(opts) {
|
|
|
2178
2376
|
unsetInitialValue,
|
|
2179
2377
|
setFieldInitialValue,
|
|
2180
2378
|
useFieldModel,
|
|
2379
|
+
createPathState,
|
|
2380
|
+
getPathState: findPathState,
|
|
2381
|
+
unsetPathValue,
|
|
2382
|
+
removePathState,
|
|
2383
|
+
initialValues: initialValues,
|
|
2384
|
+
getAllPathStates: () => pathStates.value,
|
|
2181
2385
|
};
|
|
2182
|
-
function isFieldGroup(fieldOrGroup) {
|
|
2183
|
-
return Array.isArray(fieldOrGroup);
|
|
2184
|
-
}
|
|
2185
|
-
function applyFieldMutation(fieldOrGroup, mutation) {
|
|
2186
|
-
if (Array.isArray(fieldOrGroup)) {
|
|
2187
|
-
return fieldOrGroup.forEach(mutation);
|
|
2188
|
-
}
|
|
2189
|
-
return mutation(fieldOrGroup);
|
|
2190
|
-
}
|
|
2191
|
-
function mutateAllFields(mutation) {
|
|
2192
|
-
Object.values(fieldsByPath.value).forEach(field => {
|
|
2193
|
-
if (!field) {
|
|
2194
|
-
return;
|
|
2195
|
-
}
|
|
2196
|
-
// avoid resetting the field values, because they should've been reset already.
|
|
2197
|
-
applyFieldMutation(field, mutation);
|
|
2198
|
-
});
|
|
2199
|
-
}
|
|
2200
|
-
/**
|
|
2201
|
-
* Manually sets an error message on a specific field
|
|
2202
|
-
*/
|
|
2203
|
-
function setFieldError(field, message) {
|
|
2204
|
-
setFieldErrorBag(field, message);
|
|
2205
|
-
}
|
|
2206
|
-
/**
|
|
2207
|
-
* Sets errors for the fields specified in the object
|
|
2208
|
-
*/
|
|
2209
|
-
function setErrors(fields) {
|
|
2210
|
-
setErrorBag(fields);
|
|
2211
|
-
}
|
|
2212
2386
|
/**
|
|
2213
2387
|
* Sets a single field value
|
|
2214
2388
|
*/
|
|
2215
|
-
function setFieldValue(field, value
|
|
2216
|
-
var _a;
|
|
2217
|
-
const fieldInstance = fieldsByPath.value[field];
|
|
2389
|
+
function setFieldValue(field, value) {
|
|
2218
2390
|
const clonedValue = klona(value);
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
}
|
|
2224
|
-
if (isFieldGroup(fieldInstance) && ((_a = fieldInstance[0]) === null || _a === void 0 ? void 0 : _a.type) === 'checkbox' && !Array.isArray(value)) {
|
|
2225
|
-
// Multiple checkboxes, and only one of them got updated
|
|
2226
|
-
const newValue = klona(resolveNextCheckboxValue(getFromPath(formValues, field) || [], value, undefined));
|
|
2227
|
-
setInPath(formValues, field, newValue);
|
|
2228
|
-
return;
|
|
2391
|
+
const path = typeof field === 'string' ? field : field.path;
|
|
2392
|
+
const pathState = findPathState(path);
|
|
2393
|
+
if (!pathState) {
|
|
2394
|
+
createPathState(path);
|
|
2229
2395
|
}
|
|
2230
|
-
|
|
2231
|
-
// Single Checkbox: toggles the field value unless the field is being reset then force it
|
|
2232
|
-
if (!isFieldGroup(fieldInstance) && fieldInstance.type === 'checkbox' && !force && !RESET_LOCK) {
|
|
2233
|
-
newValue = klona(resolveNextCheckboxValue(getFromPath(formValues, field), value, unref(fieldInstance.uncheckedValue)));
|
|
2234
|
-
}
|
|
2235
|
-
setInPath(formValues, field, newValue);
|
|
2396
|
+
setInPath(formValues, path, clonedValue);
|
|
2236
2397
|
}
|
|
2237
2398
|
/**
|
|
2238
2399
|
* Sets multiple fields values
|
|
2239
2400
|
*/
|
|
2240
2401
|
function setValues(fields) {
|
|
2241
|
-
|
|
2242
|
-
keysOf(formValues).forEach(key => {
|
|
2243
|
-
delete formValues[key];
|
|
2244
|
-
});
|
|
2245
|
-
// set up new values
|
|
2246
|
-
keysOf(fields).forEach(path => {
|
|
2247
|
-
setFieldValue(path, fields[path]);
|
|
2248
|
-
});
|
|
2402
|
+
merge(formValues, fields);
|
|
2249
2403
|
// regenerate the arrays when the form values change
|
|
2250
2404
|
fieldArrays.forEach(f => f && f.reset());
|
|
2251
2405
|
}
|
|
2252
2406
|
function createModel(path) {
|
|
2253
|
-
const
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
}
|
|
2258
|
-
|
|
2259
|
-
|
|
2407
|
+
const pathState = findPathState(unref(path)) || createPathState(path);
|
|
2408
|
+
return computed({
|
|
2409
|
+
get() {
|
|
2410
|
+
return pathState.value;
|
|
2411
|
+
},
|
|
2412
|
+
set(value) {
|
|
2413
|
+
const pathValue = unref(path);
|
|
2414
|
+
setFieldValue(pathValue, value);
|
|
2415
|
+
pathState.validated = true;
|
|
2416
|
+
pathState.pending = true;
|
|
2417
|
+
validateField(pathValue).then(() => {
|
|
2418
|
+
pathState.pending = false;
|
|
2419
|
+
});
|
|
2420
|
+
},
|
|
2260
2421
|
});
|
|
2261
|
-
controlledModelPaths.add(unref(path));
|
|
2262
|
-
return value;
|
|
2263
2422
|
}
|
|
2264
|
-
function useFieldModel(
|
|
2265
|
-
if (!Array.isArray(
|
|
2266
|
-
return createModel(
|
|
2423
|
+
function useFieldModel(pathOrPaths) {
|
|
2424
|
+
if (!Array.isArray(pathOrPaths)) {
|
|
2425
|
+
return createModel(pathOrPaths);
|
|
2267
2426
|
}
|
|
2268
|
-
return
|
|
2427
|
+
return pathOrPaths.map(createModel);
|
|
2269
2428
|
}
|
|
2270
2429
|
/**
|
|
2271
2430
|
* Sets the touched meta state on a field
|
|
2272
2431
|
*/
|
|
2273
2432
|
function setFieldTouched(field, isTouched) {
|
|
2274
|
-
const
|
|
2275
|
-
if (
|
|
2276
|
-
|
|
2433
|
+
const pathState = findPathState(field);
|
|
2434
|
+
if (pathState) {
|
|
2435
|
+
pathState.touched = isTouched;
|
|
2277
2436
|
}
|
|
2278
2437
|
}
|
|
2279
2438
|
/**
|
|
@@ -2285,172 +2444,53 @@ function useForm(opts) {
|
|
|
2285
2444
|
});
|
|
2286
2445
|
}
|
|
2287
2446
|
function resetField(field, state) {
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2447
|
+
var _a;
|
|
2448
|
+
const newValue = state && 'value' in state ? state.value : getFromPath(initialValues.value, field);
|
|
2449
|
+
setFieldInitialValue(field, klona(newValue));
|
|
2450
|
+
setFieldValue(field, newValue);
|
|
2451
|
+
setFieldTouched(field, (_a = state === null || state === void 0 ? void 0 : state.touched) !== null && _a !== void 0 ? _a : false);
|
|
2452
|
+
setFieldError(field, (state === null || state === void 0 ? void 0 : state.errors) || []);
|
|
2292
2453
|
}
|
|
2293
2454
|
/**
|
|
2294
2455
|
* Resets all fields
|
|
2295
2456
|
*/
|
|
2296
|
-
function resetForm(
|
|
2297
|
-
|
|
2298
|
-
// Reset all field states first
|
|
2299
|
-
mutateAllFields(f => f.resetField());
|
|
2300
|
-
// reset values
|
|
2301
|
-
const newValues = (state === null || state === void 0 ? void 0 : state.values) ? state.values : originalInitialValues.value;
|
|
2457
|
+
function resetForm(resetState) {
|
|
2458
|
+
const newValues = (resetState === null || resetState === void 0 ? void 0 : resetState.values) ? resetState.values : originalInitialValues.value;
|
|
2302
2459
|
setInitialValues(newValues);
|
|
2303
2460
|
setValues(newValues);
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
RESET_LOCK = false;
|
|
2461
|
+
mutateAllPathState(state => {
|
|
2462
|
+
var _a;
|
|
2463
|
+
state.validated = false;
|
|
2464
|
+
state.touched = ((_a = resetState === null || resetState === void 0 ? void 0 : resetState.touched) === null || _a === void 0 ? void 0 : _a[state.path]) || false;
|
|
2465
|
+
setFieldValue(state.path, getFromPath(newValues, state.path));
|
|
2466
|
+
setFieldError(state.path, undefined);
|
|
2311
2467
|
});
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
const rawField = markRaw(field);
|
|
2315
|
-
const fieldPath = path;
|
|
2316
|
-
// first field at that path
|
|
2317
|
-
if (!fieldsByPath.value[fieldPath]) {
|
|
2318
|
-
fieldsByPath.value[fieldPath] = rawField;
|
|
2319
|
-
return;
|
|
2320
|
-
}
|
|
2321
|
-
const fieldAtPath = fieldsByPath.value[fieldPath];
|
|
2322
|
-
if (fieldAtPath && !Array.isArray(fieldAtPath)) {
|
|
2323
|
-
fieldsByPath.value[fieldPath] = [fieldAtPath];
|
|
2324
|
-
}
|
|
2325
|
-
// add the new array to that path
|
|
2326
|
-
fieldsByPath.value[fieldPath] = [...fieldsByPath.value[fieldPath], rawField];
|
|
2327
|
-
}
|
|
2328
|
-
function removeFieldFromPath(field, path) {
|
|
2329
|
-
const fieldPath = path;
|
|
2330
|
-
const fieldAtPath = fieldsByPath.value[fieldPath];
|
|
2331
|
-
if (!fieldAtPath) {
|
|
2332
|
-
return;
|
|
2333
|
-
}
|
|
2334
|
-
// same field at path
|
|
2335
|
-
if (!isFieldGroup(fieldAtPath) && field.id === fieldAtPath.id) {
|
|
2336
|
-
delete fieldsByPath.value[fieldPath];
|
|
2337
|
-
return;
|
|
2338
|
-
}
|
|
2339
|
-
if (isFieldGroup(fieldAtPath)) {
|
|
2340
|
-
const idx = fieldAtPath.findIndex(f => f.id === field.id);
|
|
2341
|
-
if (idx === -1) {
|
|
2342
|
-
return;
|
|
2343
|
-
}
|
|
2344
|
-
fieldAtPath.splice(idx, 1);
|
|
2345
|
-
if (!fieldAtPath.length) {
|
|
2346
|
-
delete fieldsByPath.value[fieldPath];
|
|
2347
|
-
}
|
|
2348
|
-
}
|
|
2349
|
-
}
|
|
2350
|
-
function registerField(field) {
|
|
2351
|
-
const fieldPath = unref(field.name);
|
|
2352
|
-
insertFieldAtPath(field, fieldPath);
|
|
2353
|
-
if (isRef(field.name)) {
|
|
2354
|
-
// ensures when a field's name was already taken that it preserves its same value
|
|
2355
|
-
// necessary for fields generated by loops
|
|
2356
|
-
watch(field.name, async (newPath, oldPath) => {
|
|
2357
|
-
// cache the value
|
|
2358
|
-
await nextTick();
|
|
2359
|
-
removeFieldFromPath(field, oldPath);
|
|
2360
|
-
insertFieldAtPath(field, newPath);
|
|
2361
|
-
// re-validate if either path had errors before
|
|
2362
|
-
if (errors.value[oldPath] || errors.value[newPath]) {
|
|
2363
|
-
// clear up both paths errors
|
|
2364
|
-
setFieldError(oldPath, undefined);
|
|
2365
|
-
validateField(newPath);
|
|
2366
|
-
}
|
|
2367
|
-
// clean up the old path if no other field is sharing that name
|
|
2368
|
-
// #3325
|
|
2369
|
-
await nextTick();
|
|
2370
|
-
if (!fieldExists(oldPath)) {
|
|
2371
|
-
unsetPath(formValues, oldPath);
|
|
2372
|
-
}
|
|
2373
|
-
});
|
|
2374
|
-
}
|
|
2375
|
-
// if field already had errors (initial errors) that's not user-set, validate it again to ensure state is correct
|
|
2376
|
-
// the difference being that `initialErrors` will contain the error message while other errors (pre-validated schema) won't have them as initial errors
|
|
2377
|
-
// #3342
|
|
2378
|
-
const initialErrorMessage = unref(field.errorMessage);
|
|
2379
|
-
if (initialErrorMessage && (initialErrors === null || initialErrors === void 0 ? void 0 : initialErrors[fieldPath]) !== initialErrorMessage) {
|
|
2380
|
-
validateField(fieldPath);
|
|
2381
|
-
}
|
|
2382
|
-
// marks the initial error as "consumed" so it won't be matched later with same non-initial error
|
|
2383
|
-
delete initialErrors[fieldPath];
|
|
2384
|
-
}
|
|
2385
|
-
function unregisterField(field) {
|
|
2386
|
-
const fieldName = unref(field.name);
|
|
2387
|
-
const fieldInstance = fieldsByPath.value[fieldName];
|
|
2388
|
-
const isGroup = !!fieldInstance && isFieldGroup(fieldInstance);
|
|
2389
|
-
removeFieldFromPath(field, fieldName);
|
|
2390
|
-
// clears a field error on unmounted
|
|
2391
|
-
// we wait till next tick to make sure if the field is completely removed and doesn't have any siblings like checkboxes
|
|
2468
|
+
setErrors((resetState === null || resetState === void 0 ? void 0 : resetState.errors) || {});
|
|
2469
|
+
submitCount.value = (resetState === null || resetState === void 0 ? void 0 : resetState.submitCount) || 0;
|
|
2392
2470
|
nextTick(() => {
|
|
2393
|
-
|
|
2394
|
-
const shouldKeepValue = (_a = unref(field.keepValueOnUnmount)) !== null && _a !== void 0 ? _a : unref(keepValuesOnUnmount);
|
|
2395
|
-
const currentGroupValue = getFromPath(formValues, fieldName);
|
|
2396
|
-
// The boolean here is we check if the field still belongs to the same control group with that name
|
|
2397
|
-
// if another group claimed the name, we should avoid handling it since it is no longer the same group
|
|
2398
|
-
// this happens with `v-for` over some checkboxes and field arrays.
|
|
2399
|
-
// also if the group no longer exist we can assume this group was the last one that controlled it
|
|
2400
|
-
const isSameGroup = isGroup && (fieldInstance === fieldsByPath.value[fieldName] || !fieldsByPath.value[fieldName]);
|
|
2401
|
-
// group field that still has a dangling value, the field may exist or not after it was removed.
|
|
2402
|
-
// This used to be handled in the useField composable but the form has better context on when it should/not happen.
|
|
2403
|
-
// if it does belong to it that means the group still exists
|
|
2404
|
-
// #3844
|
|
2405
|
-
if (isSameGroup && !shouldKeepValue) {
|
|
2406
|
-
if (Array.isArray(currentGroupValue)) {
|
|
2407
|
-
const valueIdx = currentGroupValue.findIndex(i => isEqual(i, unref(field.checkedValue)));
|
|
2408
|
-
if (valueIdx > -1) {
|
|
2409
|
-
const newVal = [...currentGroupValue];
|
|
2410
|
-
newVal.splice(valueIdx, 1);
|
|
2411
|
-
setFieldValue(fieldName, newVal, { force: true });
|
|
2412
|
-
}
|
|
2413
|
-
}
|
|
2414
|
-
else if (currentGroupValue === unref(field.checkedValue)) {
|
|
2415
|
-
// Remove field if it is a group but does not have an array value, like for radio inputs #3963
|
|
2416
|
-
unsetPath(formValues, fieldName);
|
|
2417
|
-
}
|
|
2418
|
-
}
|
|
2419
|
-
// Field was removed entirely, we should unset its path
|
|
2420
|
-
// #3384
|
|
2421
|
-
if (!fieldExists(fieldName)) {
|
|
2422
|
-
setFieldError(fieldName, undefined);
|
|
2423
|
-
// Checks if the field was configured to be unset during unmount or not
|
|
2424
|
-
// Checks both the form-level config and field-level one
|
|
2425
|
-
// Field has the priority if it is set, otherwise it goes to the form settings
|
|
2426
|
-
if (shouldKeepValue) {
|
|
2427
|
-
return;
|
|
2428
|
-
}
|
|
2429
|
-
// Don't apply emptyContainer check unless the current group value is an array
|
|
2430
|
-
if (isGroup && Array.isArray(currentGroupValue) && !isEmptyContainer(currentGroupValue)) {
|
|
2431
|
-
return;
|
|
2432
|
-
}
|
|
2433
|
-
unsetPath(formValues, fieldName);
|
|
2434
|
-
}
|
|
2471
|
+
validate({ mode: 'silent' });
|
|
2435
2472
|
});
|
|
2436
2473
|
}
|
|
2437
2474
|
async function validate(opts) {
|
|
2438
2475
|
const mode = (opts === null || opts === void 0 ? void 0 : opts.mode) || 'force';
|
|
2439
2476
|
if (mode === 'force') {
|
|
2440
|
-
|
|
2477
|
+
mutateAllPathState(f => (f.validated = true));
|
|
2441
2478
|
}
|
|
2442
2479
|
if (formCtx.validateSchema) {
|
|
2443
2480
|
return formCtx.validateSchema(mode);
|
|
2444
2481
|
}
|
|
2445
2482
|
// No schema, each field is responsible to validate itself
|
|
2446
|
-
const validations = await Promise.all(
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2483
|
+
const validations = await Promise.all(pathStates.value.map(state => {
|
|
2484
|
+
if (!state.validate) {
|
|
2485
|
+
return Promise.resolve({
|
|
2486
|
+
key: state.path,
|
|
2487
|
+
valid: true,
|
|
2488
|
+
errors: [],
|
|
2489
|
+
});
|
|
2450
2490
|
}
|
|
2451
|
-
return
|
|
2491
|
+
return state.validate(opts).then((result) => {
|
|
2452
2492
|
return {
|
|
2453
|
-
key:
|
|
2493
|
+
key: state.path,
|
|
2454
2494
|
valid: result.valid,
|
|
2455
2495
|
errors: result.errors,
|
|
2456
2496
|
};
|
|
@@ -2473,16 +2513,22 @@ function useForm(opts) {
|
|
|
2473
2513
|
errors,
|
|
2474
2514
|
};
|
|
2475
2515
|
}
|
|
2476
|
-
async function validateField(
|
|
2477
|
-
const
|
|
2478
|
-
if (
|
|
2479
|
-
|
|
2480
|
-
|
|
2516
|
+
async function validateField(path) {
|
|
2517
|
+
const state = findPathState(path);
|
|
2518
|
+
if (state) {
|
|
2519
|
+
state.validated = true;
|
|
2520
|
+
}
|
|
2521
|
+
if (schema) {
|
|
2522
|
+
const { results } = await validateSchema('validated-only');
|
|
2523
|
+
return results[path] || { errors: [], valid: true };
|
|
2524
|
+
}
|
|
2525
|
+
if (state === null || state === void 0 ? void 0 : state.validate) {
|
|
2526
|
+
return state.validate();
|
|
2481
2527
|
}
|
|
2482
|
-
if (
|
|
2483
|
-
|
|
2528
|
+
if (!state) {
|
|
2529
|
+
warn$1(`field with path ${path} was not found`);
|
|
2484
2530
|
}
|
|
2485
|
-
return
|
|
2531
|
+
return Promise.resolve({ errors: [], valid: true });
|
|
2486
2532
|
}
|
|
2487
2533
|
function unsetInitialValue(path) {
|
|
2488
2534
|
unsetPath(initialValues.value, path);
|
|
@@ -2491,8 +2537,8 @@ function useForm(opts) {
|
|
|
2491
2537
|
* Sneaky function to set initial field values
|
|
2492
2538
|
*/
|
|
2493
2539
|
function stageInitialValue(path, value, updateOriginal = false) {
|
|
2494
|
-
setInPath(formValues, path, value);
|
|
2495
2540
|
setFieldInitialValue(path, value);
|
|
2541
|
+
setInPath(formValues, path, value);
|
|
2496
2542
|
if (updateOriginal && !(opts === null || opts === void 0 ? void 0 : opts.initialValues)) {
|
|
2497
2543
|
setInPath(originalInitialValues.value, path, klona(value));
|
|
2498
2544
|
}
|
|
@@ -2551,12 +2597,95 @@ function useForm(opts) {
|
|
|
2551
2597
|
deep: true,
|
|
2552
2598
|
});
|
|
2553
2599
|
}
|
|
2554
|
-
|
|
2600
|
+
function defineComponentBinds(path, config) {
|
|
2601
|
+
const pathState = findPathState(unravel(path)) || createPathState(path);
|
|
2602
|
+
const evalConfig = () => (isCallable(config) ? config(omit(pathState, PRIVATE_PATH_STATE_KEYS)) : config || {});
|
|
2603
|
+
function onBlur() {
|
|
2604
|
+
var _a;
|
|
2605
|
+
pathState.touched = true;
|
|
2606
|
+
const validateOnBlur = (_a = evalConfig().validateOnBlur) !== null && _a !== void 0 ? _a : getConfig().validateOnBlur;
|
|
2607
|
+
if (validateOnBlur) {
|
|
2608
|
+
validateField(pathState.path);
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
function onUpdateModelValue(value) {
|
|
2612
|
+
var _a;
|
|
2613
|
+
setFieldValue(pathState.path, value);
|
|
2614
|
+
const validateOnModelUpdate = (_a = evalConfig().validateOnModelUpdate) !== null && _a !== void 0 ? _a : getConfig().validateOnModelUpdate;
|
|
2615
|
+
if (validateOnModelUpdate) {
|
|
2616
|
+
validateField(pathState.path);
|
|
2617
|
+
}
|
|
2618
|
+
}
|
|
2619
|
+
const props = computed(() => {
|
|
2620
|
+
const base = {
|
|
2621
|
+
modelValue: pathState.value,
|
|
2622
|
+
'onUpdate:modelValue': onUpdateModelValue,
|
|
2623
|
+
onBlur,
|
|
2624
|
+
};
|
|
2625
|
+
if (isCallable(config)) {
|
|
2626
|
+
return Object.assign(Object.assign({}, base), (config(pathState).props || {}));
|
|
2627
|
+
}
|
|
2628
|
+
if (config === null || config === void 0 ? void 0 : config.mapProps) {
|
|
2629
|
+
return Object.assign(Object.assign({}, base), config.mapProps(omit(pathState, PRIVATE_PATH_STATE_KEYS)));
|
|
2630
|
+
}
|
|
2631
|
+
return base;
|
|
2632
|
+
});
|
|
2633
|
+
return props;
|
|
2634
|
+
}
|
|
2635
|
+
function defineInputBinds(path, config) {
|
|
2636
|
+
const pathState = (findPathState(unravel(path)) || createPathState(path));
|
|
2637
|
+
const evalConfig = () => (isCallable(config) ? config(omit(pathState, PRIVATE_PATH_STATE_KEYS)) : config || {});
|
|
2638
|
+
function onBlur() {
|
|
2639
|
+
var _a;
|
|
2640
|
+
pathState.touched = true;
|
|
2641
|
+
const validateOnBlur = (_a = evalConfig().validateOnBlur) !== null && _a !== void 0 ? _a : getConfig().validateOnBlur;
|
|
2642
|
+
if (validateOnBlur) {
|
|
2643
|
+
validateField(pathState.path);
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
function onInput(e) {
|
|
2647
|
+
var _a;
|
|
2648
|
+
const value = normalizeEventValue(e);
|
|
2649
|
+
setFieldValue(pathState.path, value);
|
|
2650
|
+
const validateOnInput = (_a = evalConfig().validateOnInput) !== null && _a !== void 0 ? _a : getConfig().validateOnInput;
|
|
2651
|
+
if (validateOnInput) {
|
|
2652
|
+
validateField(pathState.path);
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
function onChange(e) {
|
|
2656
|
+
var _a;
|
|
2657
|
+
const value = normalizeEventValue(e);
|
|
2658
|
+
setFieldValue(pathState.path, value);
|
|
2659
|
+
const validateOnChange = (_a = evalConfig().validateOnChange) !== null && _a !== void 0 ? _a : getConfig().validateOnChange;
|
|
2660
|
+
if (validateOnChange) {
|
|
2661
|
+
validateField(pathState.path);
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
const props = computed(() => {
|
|
2665
|
+
const base = {
|
|
2666
|
+
value: pathState.value,
|
|
2667
|
+
onChange,
|
|
2668
|
+
onInput,
|
|
2669
|
+
onBlur,
|
|
2670
|
+
};
|
|
2671
|
+
if (isCallable(config)) {
|
|
2672
|
+
return Object.assign(Object.assign({}, base), (config(omit(pathState, PRIVATE_PATH_STATE_KEYS)).attrs || {}));
|
|
2673
|
+
}
|
|
2674
|
+
if (config === null || config === void 0 ? void 0 : config.mapAttrs) {
|
|
2675
|
+
return Object.assign(Object.assign({}, base), config.mapAttrs(omit(pathState, PRIVATE_PATH_STATE_KEYS)));
|
|
2676
|
+
}
|
|
2677
|
+
return base;
|
|
2678
|
+
});
|
|
2679
|
+
return props;
|
|
2680
|
+
}
|
|
2681
|
+
return Object.assign(Object.assign({}, formCtx), { handleReset: () => resetForm(), submitForm,
|
|
2682
|
+
defineComponentBinds,
|
|
2683
|
+
defineInputBinds });
|
|
2555
2684
|
}
|
|
2556
2685
|
/**
|
|
2557
2686
|
* Manages form meta aggregation
|
|
2558
2687
|
*/
|
|
2559
|
-
function useFormMeta(
|
|
2688
|
+
function useFormMeta(pathsState, currentValues, initialValues, errors) {
|
|
2560
2689
|
const MERGE_STRATEGIES = {
|
|
2561
2690
|
touched: 'some',
|
|
2562
2691
|
pending: 'some',
|
|
@@ -2566,10 +2695,10 @@ function useFormMeta(fieldsByPath, currentValues, initialValues, errors) {
|
|
|
2566
2695
|
return !isEqual(currentValues, unref(initialValues));
|
|
2567
2696
|
});
|
|
2568
2697
|
function calculateFlags() {
|
|
2569
|
-
const
|
|
2698
|
+
const states = pathsState.value;
|
|
2570
2699
|
return keysOf(MERGE_STRATEGIES).reduce((acc, flag) => {
|
|
2571
2700
|
const mergeMethod = MERGE_STRATEGIES[flag];
|
|
2572
|
-
acc[flag] =
|
|
2701
|
+
acc[flag] = states[mergeMethod](s => s[flag]);
|
|
2573
2702
|
return acc;
|
|
2574
2703
|
}, {});
|
|
2575
2704
|
}
|
|
@@ -2587,7 +2716,7 @@ function useFormMeta(fieldsByPath, currentValues, initialValues, errors) {
|
|
|
2587
2716
|
/**
|
|
2588
2717
|
* Manages the initial values prop
|
|
2589
2718
|
*/
|
|
2590
|
-
function useFormInitialValues(
|
|
2719
|
+
function useFormInitialValues(pathsState, formValues, opts) {
|
|
2591
2720
|
const values = resolveInitialValues(opts);
|
|
2592
2721
|
const providedValues = opts === null || opts === void 0 ? void 0 : opts.initialValues;
|
|
2593
2722
|
// these are the mutable initial values as the fields are mounted/unmounted
|
|
@@ -2608,14 +2737,13 @@ function useFormInitialValues(fields, formValues, opts) {
|
|
|
2608
2737
|
// those are excluded because it's unlikely you want to change the form values using initial values
|
|
2609
2738
|
// we mostly watch them for API population or newly inserted fields
|
|
2610
2739
|
// if the user API is taking too much time before user interaction they should consider disabling or hiding their inputs until the values are ready
|
|
2611
|
-
|
|
2612
|
-
const
|
|
2613
|
-
|
|
2614
|
-
if (!field || wasTouched) {
|
|
2740
|
+
pathsState.value.forEach(state => {
|
|
2741
|
+
const wasTouched = state.touched;
|
|
2742
|
+
if (wasTouched) {
|
|
2615
2743
|
return;
|
|
2616
2744
|
}
|
|
2617
|
-
const newValue = getFromPath(initialValues.value,
|
|
2618
|
-
setInPath(formValues,
|
|
2745
|
+
const newValue = getFromPath(initialValues.value, state.path);
|
|
2746
|
+
setInPath(formValues, state.path, klona(newValue));
|
|
2619
2747
|
});
|
|
2620
2748
|
}
|
|
2621
2749
|
if (isRef(providedValues)) {
|
|
@@ -2631,42 +2759,6 @@ function useFormInitialValues(fields, formValues, opts) {
|
|
|
2631
2759
|
setInitialValues,
|
|
2632
2760
|
};
|
|
2633
2761
|
}
|
|
2634
|
-
function useErrorBag(initialErrors) {
|
|
2635
|
-
const errorBag = ref({});
|
|
2636
|
-
function normalizeErrorItem(message) {
|
|
2637
|
-
return Array.isArray(message) ? message : message ? [message] : [];
|
|
2638
|
-
}
|
|
2639
|
-
/**
|
|
2640
|
-
* Manually sets an error message on a specific field
|
|
2641
|
-
*/
|
|
2642
|
-
function setFieldErrorBag(field, message) {
|
|
2643
|
-
if (!message) {
|
|
2644
|
-
delete errorBag.value[field];
|
|
2645
|
-
return;
|
|
2646
|
-
}
|
|
2647
|
-
errorBag.value[field] = normalizeErrorItem(message);
|
|
2648
|
-
}
|
|
2649
|
-
/**
|
|
2650
|
-
* Sets errors for the fields specified in the object
|
|
2651
|
-
*/
|
|
2652
|
-
function setErrorBag(fields) {
|
|
2653
|
-
errorBag.value = keysOf(fields).reduce((acc, key) => {
|
|
2654
|
-
const message = fields[key];
|
|
2655
|
-
if (message) {
|
|
2656
|
-
acc[key] = normalizeErrorItem(message);
|
|
2657
|
-
}
|
|
2658
|
-
return acc;
|
|
2659
|
-
}, {});
|
|
2660
|
-
}
|
|
2661
|
-
if (initialErrors) {
|
|
2662
|
-
setErrorBag(initialErrors);
|
|
2663
|
-
}
|
|
2664
|
-
return {
|
|
2665
|
-
errorBag,
|
|
2666
|
-
setErrorBag,
|
|
2667
|
-
setFieldErrorBag,
|
|
2668
|
-
};
|
|
2669
|
-
}
|
|
2670
2762
|
|
|
2671
2763
|
const FormImpl = defineComponent({
|
|
2672
2764
|
name: 'Form',
|
|
@@ -2847,7 +2939,10 @@ function useFieldArray(arrayPath) {
|
|
|
2847
2939
|
}
|
|
2848
2940
|
function initFields() {
|
|
2849
2941
|
const currentValues = getCurrentValues();
|
|
2850
|
-
|
|
2942
|
+
if (!Array.isArray(currentValues)) {
|
|
2943
|
+
return;
|
|
2944
|
+
}
|
|
2945
|
+
fields.value = currentValues.map((v, idx) => createEntry(v, idx, fields.value));
|
|
2851
2946
|
updateEntryFlags();
|
|
2852
2947
|
}
|
|
2853
2948
|
initFields();
|
|
@@ -2859,7 +2954,13 @@ function useFieldArray(arrayPath) {
|
|
|
2859
2954
|
entry.isLast = i === fieldsLength - 1;
|
|
2860
2955
|
}
|
|
2861
2956
|
}
|
|
2862
|
-
function createEntry(value) {
|
|
2957
|
+
function createEntry(value, idx, currentFields) {
|
|
2958
|
+
// Skips the work by returning the current entry if it already exists
|
|
2959
|
+
// This should make the `key` prop stable and doesn't cause more re-renders than needed
|
|
2960
|
+
// The value is computed and should update anyways
|
|
2961
|
+
if (currentFields && !isNullOrUndefined(idx) && currentFields[idx]) {
|
|
2962
|
+
return currentFields[idx];
|
|
2963
|
+
}
|
|
2863
2964
|
const key = entryCounter++;
|
|
2864
2965
|
const entry = {
|
|
2865
2966
|
key,
|
|
@@ -2896,8 +2997,9 @@ function useFieldArray(arrayPath) {
|
|
|
2896
2997
|
}
|
|
2897
2998
|
const newValue = [...pathValue];
|
|
2898
2999
|
newValue.splice(idx, 1);
|
|
2899
|
-
|
|
2900
|
-
form
|
|
3000
|
+
const fieldPath = pathName + `[${idx}]`;
|
|
3001
|
+
form.unsetInitialValue(fieldPath);
|
|
3002
|
+
setInPath(form.values, pathName, newValue);
|
|
2901
3003
|
fields.value.splice(idx, 1);
|
|
2902
3004
|
afterMutation();
|
|
2903
3005
|
}
|
|
@@ -2910,8 +3012,8 @@ function useFieldArray(arrayPath) {
|
|
|
2910
3012
|
}
|
|
2911
3013
|
const newValue = [...normalizedPathValue];
|
|
2912
3014
|
newValue.push(value);
|
|
2913
|
-
form
|
|
2914
|
-
form
|
|
3015
|
+
form.stageInitialValue(pathName + `[${newValue.length - 1}]`, value);
|
|
3016
|
+
setInPath(form.values, pathName, newValue);
|
|
2915
3017
|
fields.value.push(createEntry(value));
|
|
2916
3018
|
afterMutation();
|
|
2917
3019
|
}
|
|
@@ -2930,7 +3032,7 @@ function useFieldArray(arrayPath) {
|
|
|
2930
3032
|
const tempEntry = newFields[indexA];
|
|
2931
3033
|
newFields[indexA] = newFields[indexB];
|
|
2932
3034
|
newFields[indexB] = tempEntry;
|
|
2933
|
-
form
|
|
3035
|
+
setInPath(form.values, pathName, newValue);
|
|
2934
3036
|
fields.value = newFields;
|
|
2935
3037
|
updateEntryFlags();
|
|
2936
3038
|
}
|
|
@@ -2944,13 +3046,14 @@ function useFieldArray(arrayPath) {
|
|
|
2944
3046
|
const newFields = [...fields.value];
|
|
2945
3047
|
newValue.splice(idx, 0, value);
|
|
2946
3048
|
newFields.splice(idx, 0, createEntry(value));
|
|
2947
|
-
form
|
|
3049
|
+
setInPath(form.values, pathName, newValue);
|
|
2948
3050
|
fields.value = newFields;
|
|
2949
3051
|
afterMutation();
|
|
2950
3052
|
}
|
|
2951
3053
|
function replace(arr) {
|
|
2952
3054
|
const pathName = unref(arrayPath);
|
|
2953
|
-
form
|
|
3055
|
+
form.stageInitialValue(pathName, arr);
|
|
3056
|
+
setInPath(form.values, pathName, arr);
|
|
2954
3057
|
initFields();
|
|
2955
3058
|
afterMutation();
|
|
2956
3059
|
}
|
|
@@ -2960,7 +3063,7 @@ function useFieldArray(arrayPath) {
|
|
|
2960
3063
|
if (!Array.isArray(pathValue) || pathValue.length - 1 < idx) {
|
|
2961
3064
|
return;
|
|
2962
3065
|
}
|
|
2963
|
-
form
|
|
3066
|
+
setInPath(form.values, `${pathName}[${idx}]`, value);
|
|
2964
3067
|
form === null || form === void 0 ? void 0 : form.validate({ mode: 'validated-only' });
|
|
2965
3068
|
}
|
|
2966
3069
|
function prepend(value) {
|
|
@@ -2971,8 +3074,8 @@ function useFieldArray(arrayPath) {
|
|
|
2971
3074
|
return;
|
|
2972
3075
|
}
|
|
2973
3076
|
const newValue = [value, ...normalizedPathValue];
|
|
2974
|
-
form
|
|
2975
|
-
form
|
|
3077
|
+
form.stageInitialValue(pathName + `[${newValue.length - 1}]`, value);
|
|
3078
|
+
setInPath(form.values, pathName, newValue);
|
|
2976
3079
|
fields.value.unshift(createEntry(value));
|
|
2977
3080
|
afterMutation();
|
|
2978
3081
|
}
|
|
@@ -2990,7 +3093,7 @@ function useFieldArray(arrayPath) {
|
|
|
2990
3093
|
const movedValue = newValue[oldIdx];
|
|
2991
3094
|
newValue.splice(oldIdx, 1);
|
|
2992
3095
|
newValue.splice(newIdx, 0, movedValue);
|
|
2993
|
-
form
|
|
3096
|
+
setInPath(form.values, pathName, newValue);
|
|
2994
3097
|
fields.value = newFields;
|
|
2995
3098
|
afterMutation();
|
|
2996
3099
|
}
|
|
@@ -3129,17 +3232,13 @@ function useResetForm() {
|
|
|
3129
3232
|
* If a field is dirty or not
|
|
3130
3233
|
*/
|
|
3131
3234
|
function useIsFieldDirty(path) {
|
|
3132
|
-
const
|
|
3133
|
-
let field = path ? undefined : inject(FieldContextKey);
|
|
3235
|
+
const fieldOrPath = resolveFieldOrPathState(path);
|
|
3134
3236
|
return computed(() => {
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
}
|
|
3138
|
-
if (!field) {
|
|
3139
|
-
warn(`field with name ${unref(path)} was not found`);
|
|
3237
|
+
var _a, _b;
|
|
3238
|
+
if (!fieldOrPath) {
|
|
3140
3239
|
return false;
|
|
3141
3240
|
}
|
|
3142
|
-
return
|
|
3241
|
+
return (_b = ('meta' in fieldOrPath ? fieldOrPath.meta.dirty : (_a = fieldOrPath === null || fieldOrPath === void 0 ? void 0 : fieldOrPath.value) === null || _a === void 0 ? void 0 : _a.dirty)) !== null && _b !== void 0 ? _b : false;
|
|
3143
3242
|
});
|
|
3144
3243
|
}
|
|
3145
3244
|
|
|
@@ -3147,17 +3246,13 @@ function useIsFieldDirty(path) {
|
|
|
3147
3246
|
* If a field is touched or not
|
|
3148
3247
|
*/
|
|
3149
3248
|
function useIsFieldTouched(path) {
|
|
3150
|
-
const
|
|
3151
|
-
let field = path ? undefined : inject(FieldContextKey);
|
|
3249
|
+
const fieldOrPath = resolveFieldOrPathState(path);
|
|
3152
3250
|
return computed(() => {
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
}
|
|
3156
|
-
if (!field) {
|
|
3157
|
-
warn(`field with name ${unref(path)} was not found`);
|
|
3251
|
+
var _a, _b;
|
|
3252
|
+
if (!fieldOrPath) {
|
|
3158
3253
|
return false;
|
|
3159
3254
|
}
|
|
3160
|
-
return
|
|
3255
|
+
return (_b = ('meta' in fieldOrPath ? fieldOrPath.meta.touched : (_a = fieldOrPath === null || fieldOrPath === void 0 ? void 0 : fieldOrPath.value) === null || _a === void 0 ? void 0 : _a.touched)) !== null && _b !== void 0 ? _b : false;
|
|
3161
3256
|
});
|
|
3162
3257
|
}
|
|
3163
3258
|
|
|
@@ -3165,17 +3260,13 @@ function useIsFieldTouched(path) {
|
|
|
3165
3260
|
* If a field is validated and is valid
|
|
3166
3261
|
*/
|
|
3167
3262
|
function useIsFieldValid(path) {
|
|
3168
|
-
const
|
|
3169
|
-
let field = path ? undefined : inject(FieldContextKey);
|
|
3263
|
+
const fieldOrPath = resolveFieldOrPathState(path);
|
|
3170
3264
|
return computed(() => {
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
}
|
|
3174
|
-
if (!field) {
|
|
3175
|
-
warn(`field with name ${unref(path)} was not found`);
|
|
3265
|
+
var _a, _b;
|
|
3266
|
+
if (!fieldOrPath) {
|
|
3176
3267
|
return false;
|
|
3177
3268
|
}
|
|
3178
|
-
return
|
|
3269
|
+
return (_b = ('meta' in fieldOrPath ? fieldOrPath.meta.valid : (_a = fieldOrPath === null || fieldOrPath === void 0 ? void 0 : fieldOrPath.value) === null || _a === void 0 ? void 0 : _a.valid)) !== null && _b !== void 0 ? _b : false;
|
|
3179
3270
|
});
|
|
3180
3271
|
}
|
|
3181
3272
|
|
|
@@ -3198,19 +3289,19 @@ function useIsSubmitting() {
|
|
|
3198
3289
|
*/
|
|
3199
3290
|
function useValidateField(path) {
|
|
3200
3291
|
const form = injectWithSelf(FormContextKey);
|
|
3201
|
-
|
|
3292
|
+
const field = path ? undefined : inject(FieldContextKey);
|
|
3202
3293
|
return function validateField() {
|
|
3203
|
-
if (
|
|
3204
|
-
field
|
|
3294
|
+
if (field) {
|
|
3295
|
+
return field.validate();
|
|
3205
3296
|
}
|
|
3206
|
-
if (
|
|
3207
|
-
|
|
3208
|
-
return Promise.resolve({
|
|
3209
|
-
errors: [],
|
|
3210
|
-
valid: true,
|
|
3211
|
-
});
|
|
3297
|
+
if (form && path) {
|
|
3298
|
+
return form === null || form === void 0 ? void 0 : form.validateField(unref(path));
|
|
3212
3299
|
}
|
|
3213
|
-
|
|
3300
|
+
warn(`field with name ${unref(path)} was not found`);
|
|
3301
|
+
return Promise.resolve({
|
|
3302
|
+
errors: [],
|
|
3303
|
+
valid: true,
|
|
3304
|
+
});
|
|
3214
3305
|
};
|
|
3215
3306
|
}
|
|
3216
3307
|
|