vee-validate 4.4.10 → 4.5.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 +292 -731
- package/dist/vee-validate.d.ts +145 -85
- package/dist/vee-validate.esm.js +1032 -350
- package/dist/vee-validate.js +638 -348
- package/dist/vee-validate.min.js +2 -2
- package/package.json +5 -2
package/dist/vee-validate.esm.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* vee-validate v4.
|
|
2
|
+
* vee-validate v4.5.0
|
|
3
3
|
* (c) 2021 Abdelrahman Awad
|
|
4
4
|
* @license MIT
|
|
5
5
|
*/
|
|
6
|
-
import { inject, getCurrentInstance, warn as warn$1, unref, computed,
|
|
6
|
+
import { inject, getCurrentInstance, warn as warn$1, ref, unref, computed, reactive, watch, onUnmounted, nextTick, onMounted, provide, isRef, onBeforeUnmount, defineComponent, toRef, resolveDynamicComponent, h, markRaw, readonly } from 'vue';
|
|
7
|
+
import { setupDevtoolsPlugin } from '@vue/devtools-api';
|
|
7
8
|
|
|
8
9
|
function isCallable(fn) {
|
|
9
10
|
return typeof fn === 'function';
|
|
@@ -46,8 +47,6 @@ function guardExtend(id, validator) {
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
const FormContextKey = Symbol('vee-validate-form');
|
|
49
|
-
const FormErrorsKey = Symbol('vee-validate-form-errors');
|
|
50
|
-
const FormInitialValuesKey = Symbol('vee-validate-form-initial-values');
|
|
51
50
|
const FieldContextKey = Symbol('vee-validate-field-instance');
|
|
52
51
|
const IS_ABSENT = Symbol('Default empty value');
|
|
53
52
|
|
|
@@ -147,17 +146,14 @@ function cleanupNonNestedPath(path) {
|
|
|
147
146
|
}
|
|
148
147
|
return path;
|
|
149
148
|
}
|
|
150
|
-
|
|
151
|
-
* Gets a nested property value from an object
|
|
152
|
-
*/
|
|
153
|
-
function getFromPath(object, path, fallback = undefined) {
|
|
149
|
+
function getFromPath(object, path, fallback) {
|
|
154
150
|
if (!object) {
|
|
155
151
|
return fallback;
|
|
156
152
|
}
|
|
157
153
|
if (isNotNestedPath(path)) {
|
|
158
154
|
return object[cleanupNonNestedPath(path)];
|
|
159
155
|
}
|
|
160
|
-
const resolvedValue = path
|
|
156
|
+
const resolvedValue = (path || '')
|
|
161
157
|
.split(/\.|\[(\d+)\]/)
|
|
162
158
|
.filter(Boolean)
|
|
163
159
|
.reduce((acc, propKey) => {
|
|
@@ -261,20 +257,6 @@ function normalizeField(field) {
|
|
|
261
257
|
}
|
|
262
258
|
return field;
|
|
263
259
|
}
|
|
264
|
-
/**
|
|
265
|
-
* Applies a mutation function on a field or field group
|
|
266
|
-
*/
|
|
267
|
-
function applyFieldMutation(field, mutation, onlyFirst = false) {
|
|
268
|
-
if (!Array.isArray(field)) {
|
|
269
|
-
mutation(field);
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
if (onlyFirst) {
|
|
273
|
-
mutation(field[0]);
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
field.forEach(mutation);
|
|
277
|
-
}
|
|
278
260
|
function resolveNextCheckboxValue(currentValue, checkedValue, uncheckedValue) {
|
|
279
261
|
if (Array.isArray(currentValue)) {
|
|
280
262
|
const newVal = [...currentValue];
|
|
@@ -283,6 +265,42 @@ function resolveNextCheckboxValue(currentValue, checkedValue, uncheckedValue) {
|
|
|
283
265
|
return newVal;
|
|
284
266
|
}
|
|
285
267
|
return currentValue === checkedValue ? uncheckedValue : checkedValue;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Creates a throttled function that only invokes the provided function (`func`) at most once per within a given number of milliseconds
|
|
271
|
+
* (`limit`)
|
|
272
|
+
*/
|
|
273
|
+
function throttle(func, limit) {
|
|
274
|
+
let inThrottle;
|
|
275
|
+
let lastResult;
|
|
276
|
+
return function (...args) {
|
|
277
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
278
|
+
const context = this;
|
|
279
|
+
if (!inThrottle) {
|
|
280
|
+
inThrottle = true;
|
|
281
|
+
setTimeout(() => (inThrottle = false), limit);
|
|
282
|
+
lastResult = func.apply(context, args);
|
|
283
|
+
}
|
|
284
|
+
return lastResult;
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function debounceAsync(inner, ms = 0) {
|
|
288
|
+
let timer = null;
|
|
289
|
+
let resolves = [];
|
|
290
|
+
return function (...args) {
|
|
291
|
+
// Run the function after a certain amount of time
|
|
292
|
+
if (timer) {
|
|
293
|
+
window.clearTimeout(timer);
|
|
294
|
+
}
|
|
295
|
+
timer = window.setTimeout(() => {
|
|
296
|
+
// Get the result of the inner function, then apply it to the resolve function of
|
|
297
|
+
// each promise that has been created since the last time the inner function was run
|
|
298
|
+
const result = inner(...args);
|
|
299
|
+
resolves.forEach(r => r(result));
|
|
300
|
+
resolves = [];
|
|
301
|
+
}, ms);
|
|
302
|
+
return new Promise(resolve => resolves.push(resolve));
|
|
303
|
+
};
|
|
286
304
|
}
|
|
287
305
|
|
|
288
306
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -773,21 +791,522 @@ var es6 = function equal(a, b) {
|
|
|
773
791
|
};
|
|
774
792
|
|
|
775
793
|
let ID_COUNTER = 0;
|
|
794
|
+
function useFieldState(path, init) {
|
|
795
|
+
const { value, initialValue, setInitialValue } = _useFieldValue(path, init.modelValue, !init.standalone);
|
|
796
|
+
const { errorMessage, errors, setErrors } = _useFieldErrors(path, !init.standalone);
|
|
797
|
+
const meta = _useFieldMeta(value, initialValue, errors);
|
|
798
|
+
const id = ID_COUNTER >= Number.MAX_SAFE_INTEGER ? 0 : ++ID_COUNTER;
|
|
799
|
+
function setState(state) {
|
|
800
|
+
var _a;
|
|
801
|
+
if ('value' in state) {
|
|
802
|
+
value.value = state.value;
|
|
803
|
+
}
|
|
804
|
+
if ('errors' in state) {
|
|
805
|
+
setErrors(state.errors);
|
|
806
|
+
}
|
|
807
|
+
if ('touched' in state) {
|
|
808
|
+
meta.touched = (_a = state.touched) !== null && _a !== void 0 ? _a : meta.touched;
|
|
809
|
+
}
|
|
810
|
+
if ('initialValue' in state) {
|
|
811
|
+
setInitialValue(state.initialValue);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
return {
|
|
815
|
+
id,
|
|
816
|
+
path,
|
|
817
|
+
value,
|
|
818
|
+
initialValue,
|
|
819
|
+
meta,
|
|
820
|
+
errors,
|
|
821
|
+
errorMessage,
|
|
822
|
+
setState,
|
|
823
|
+
};
|
|
824
|
+
}
|
|
825
|
+
/**
|
|
826
|
+
* Creates the field value and resolves the initial value
|
|
827
|
+
*/
|
|
828
|
+
function _useFieldValue(path, modelValue, shouldInjectForm) {
|
|
829
|
+
const form = shouldInjectForm ? injectWithSelf(FormContextKey, undefined) : undefined;
|
|
830
|
+
const modelRef = ref(unref(modelValue));
|
|
831
|
+
function resolveInitialValue() {
|
|
832
|
+
if (!form) {
|
|
833
|
+
return unref(modelRef);
|
|
834
|
+
}
|
|
835
|
+
return getFromPath(form.meta.value.initialValues, unref(path), unref(modelRef));
|
|
836
|
+
}
|
|
837
|
+
function setInitialValue(value) {
|
|
838
|
+
if (!form) {
|
|
839
|
+
modelRef.value = value;
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
form.setFieldInitialValue(unref(path), value);
|
|
843
|
+
}
|
|
844
|
+
const initialValue = computed(resolveInitialValue);
|
|
845
|
+
// if no form is associated, use a regular ref.
|
|
846
|
+
if (!form) {
|
|
847
|
+
const value = ref(resolveInitialValue());
|
|
848
|
+
return {
|
|
849
|
+
value,
|
|
850
|
+
initialValue,
|
|
851
|
+
setInitialValue,
|
|
852
|
+
};
|
|
853
|
+
}
|
|
854
|
+
// to set the initial value, first check if there is a current value, if there is then use it.
|
|
855
|
+
// otherwise use the configured initial value if it exists.
|
|
856
|
+
// prioritize model value over form values
|
|
857
|
+
// #3429
|
|
858
|
+
const currentValue = modelValue ? unref(modelValue) : getFromPath(form.values, unref(path), unref(initialValue));
|
|
859
|
+
form.stageInitialValue(unref(path), currentValue);
|
|
860
|
+
// otherwise use a computed setter that triggers the `setFieldValue`
|
|
861
|
+
const value = computed({
|
|
862
|
+
get() {
|
|
863
|
+
return getFromPath(form.values, unref(path));
|
|
864
|
+
},
|
|
865
|
+
set(newVal) {
|
|
866
|
+
form.setFieldValue(unref(path), newVal);
|
|
867
|
+
},
|
|
868
|
+
});
|
|
869
|
+
return {
|
|
870
|
+
value,
|
|
871
|
+
initialValue,
|
|
872
|
+
setInitialValue,
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
/**
|
|
876
|
+
* Creates meta flags state and some associated effects with them
|
|
877
|
+
*/
|
|
878
|
+
function _useFieldMeta(currentValue, initialValue, errors) {
|
|
879
|
+
const meta = reactive({
|
|
880
|
+
touched: false,
|
|
881
|
+
pending: false,
|
|
882
|
+
valid: true,
|
|
883
|
+
validated: !!unref(errors).length,
|
|
884
|
+
initialValue: computed(() => unref(initialValue)),
|
|
885
|
+
dirty: computed(() => {
|
|
886
|
+
return !es6(unref(currentValue), unref(initialValue));
|
|
887
|
+
}),
|
|
888
|
+
});
|
|
889
|
+
watch(errors, value => {
|
|
890
|
+
meta.valid = !value.length;
|
|
891
|
+
}, {
|
|
892
|
+
immediate: true,
|
|
893
|
+
flush: 'sync',
|
|
894
|
+
});
|
|
895
|
+
return meta;
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* Creates the error message state for the field state
|
|
899
|
+
*/
|
|
900
|
+
function _useFieldErrors(path, shouldInjectForm) {
|
|
901
|
+
const form = shouldInjectForm ? injectWithSelf(FormContextKey, undefined) : undefined;
|
|
902
|
+
function normalizeErrors(messages) {
|
|
903
|
+
if (!messages) {
|
|
904
|
+
return [];
|
|
905
|
+
}
|
|
906
|
+
return Array.isArray(messages) ? messages : [messages];
|
|
907
|
+
}
|
|
908
|
+
if (!form) {
|
|
909
|
+
const errors = ref([]);
|
|
910
|
+
return {
|
|
911
|
+
errors,
|
|
912
|
+
errorMessage: computed(() => errors.value[0]),
|
|
913
|
+
setErrors: (messages) => {
|
|
914
|
+
errors.value = normalizeErrors(messages);
|
|
915
|
+
},
|
|
916
|
+
};
|
|
917
|
+
}
|
|
918
|
+
const errors = computed(() => form.errorBag.value[unref(path)] || []);
|
|
919
|
+
return {
|
|
920
|
+
errors,
|
|
921
|
+
errorMessage: computed(() => errors.value[0]),
|
|
922
|
+
setErrors: (messages) => {
|
|
923
|
+
form.setFieldErrorBag(unref(path), normalizeErrors(messages));
|
|
924
|
+
},
|
|
925
|
+
};
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
function installDevtoolsPlugin(app) {
|
|
929
|
+
if ((process.env.NODE_ENV !== 'production')) {
|
|
930
|
+
setupDevtoolsPlugin({
|
|
931
|
+
id: 'vee-validate-devtools-plugin',
|
|
932
|
+
label: 'VeeValidate Plugin',
|
|
933
|
+
packageName: 'vee-validate',
|
|
934
|
+
homepage: 'https://vee-validate.logaretm.com/v4',
|
|
935
|
+
app,
|
|
936
|
+
logo: 'https://vee-validate.logaretm.com/v4/logo.png',
|
|
937
|
+
}, setupApiHooks);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
const DEVTOOLS_FORMS = {};
|
|
941
|
+
const DEVTOOLS_FIELDS = {};
|
|
942
|
+
let API;
|
|
943
|
+
const refreshInspector = throttle(() => {
|
|
944
|
+
setTimeout(async () => {
|
|
945
|
+
await nextTick();
|
|
946
|
+
API === null || API === void 0 ? void 0 : API.sendInspectorState(INSPECTOR_ID);
|
|
947
|
+
API === null || API === void 0 ? void 0 : API.sendInspectorTree(INSPECTOR_ID);
|
|
948
|
+
}, 100);
|
|
949
|
+
}, 100);
|
|
950
|
+
function registerFormWithDevTools(form) {
|
|
951
|
+
const vm = getCurrentInstance();
|
|
952
|
+
if (!API) {
|
|
953
|
+
const app = vm === null || vm === void 0 ? void 0 : vm.appContext.app;
|
|
954
|
+
if (!app) {
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
957
|
+
installDevtoolsPlugin(app);
|
|
958
|
+
}
|
|
959
|
+
DEVTOOLS_FORMS[form.formId] = Object.assign({}, form);
|
|
960
|
+
DEVTOOLS_FORMS[form.formId]._vm = vm;
|
|
961
|
+
onUnmounted(() => {
|
|
962
|
+
delete DEVTOOLS_FORMS[form.formId];
|
|
963
|
+
refreshInspector();
|
|
964
|
+
});
|
|
965
|
+
refreshInspector();
|
|
966
|
+
}
|
|
967
|
+
function registerSingleFieldWithDevtools(field) {
|
|
968
|
+
const vm = getCurrentInstance();
|
|
969
|
+
if (!API) {
|
|
970
|
+
const app = vm === null || vm === void 0 ? void 0 : vm.appContext.app;
|
|
971
|
+
if (!app) {
|
|
972
|
+
return;
|
|
973
|
+
}
|
|
974
|
+
installDevtoolsPlugin(app);
|
|
975
|
+
}
|
|
976
|
+
DEVTOOLS_FIELDS[field.id] = Object.assign({}, field);
|
|
977
|
+
DEVTOOLS_FIELDS[field.id]._vm = vm;
|
|
978
|
+
onUnmounted(() => {
|
|
979
|
+
delete DEVTOOLS_FIELDS[field.id];
|
|
980
|
+
refreshInspector();
|
|
981
|
+
});
|
|
982
|
+
refreshInspector();
|
|
983
|
+
}
|
|
984
|
+
const INSPECTOR_ID = 'vee-validate-inspector';
|
|
985
|
+
const COLORS = {
|
|
986
|
+
error: 0xbd4b4b,
|
|
987
|
+
success: 0x06d77b,
|
|
988
|
+
unknown: 0x54436b,
|
|
989
|
+
white: 0xffffff,
|
|
990
|
+
black: 0x000000,
|
|
991
|
+
blue: 0x035397,
|
|
992
|
+
purple: 0xb980f0,
|
|
993
|
+
orange: 0xf5a962,
|
|
994
|
+
gray: 0xbbbfca,
|
|
995
|
+
};
|
|
996
|
+
let SELECTED_NODE = null;
|
|
997
|
+
function setupApiHooks(api) {
|
|
998
|
+
API = api;
|
|
999
|
+
api.addInspector({
|
|
1000
|
+
id: INSPECTOR_ID,
|
|
1001
|
+
icon: 'rule',
|
|
1002
|
+
label: 'vee-validate',
|
|
1003
|
+
noSelectionText: 'Select a vee-validate node to inspect',
|
|
1004
|
+
actions: [
|
|
1005
|
+
{
|
|
1006
|
+
icon: 'done_outline',
|
|
1007
|
+
tooltip: 'Validate selected item',
|
|
1008
|
+
action: async () => {
|
|
1009
|
+
if (!SELECTED_NODE) {
|
|
1010
|
+
console.error('There is not a valid selected vee-validate node or component');
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
const result = await SELECTED_NODE.validate();
|
|
1014
|
+
console.log(result);
|
|
1015
|
+
},
|
|
1016
|
+
},
|
|
1017
|
+
{
|
|
1018
|
+
icon: 'delete_sweep',
|
|
1019
|
+
tooltip: 'Clear validation state of the selected item',
|
|
1020
|
+
action: () => {
|
|
1021
|
+
if (!SELECTED_NODE) {
|
|
1022
|
+
console.error('There is not a valid selected vee-validate node or component');
|
|
1023
|
+
return;
|
|
1024
|
+
}
|
|
1025
|
+
if ('id' in SELECTED_NODE) {
|
|
1026
|
+
SELECTED_NODE.resetField();
|
|
1027
|
+
return;
|
|
1028
|
+
}
|
|
1029
|
+
SELECTED_NODE.resetForm();
|
|
1030
|
+
},
|
|
1031
|
+
},
|
|
1032
|
+
],
|
|
1033
|
+
});
|
|
1034
|
+
api.on.getInspectorTree(payload => {
|
|
1035
|
+
if (payload.inspectorId !== INSPECTOR_ID) {
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
const forms = Object.values(DEVTOOLS_FORMS);
|
|
1039
|
+
const fields = Object.values(DEVTOOLS_FIELDS);
|
|
1040
|
+
payload.rootNodes = [
|
|
1041
|
+
...forms.map(mapFormForDevtoolsInspector),
|
|
1042
|
+
...fields.map(field => mapFieldForDevtoolsInspector(field)),
|
|
1043
|
+
];
|
|
1044
|
+
});
|
|
1045
|
+
api.on.getInspectorState((payload, ctx) => {
|
|
1046
|
+
if (payload.inspectorId !== INSPECTOR_ID || ctx.currentTab !== `custom-inspector:${INSPECTOR_ID}`) {
|
|
1047
|
+
return;
|
|
1048
|
+
}
|
|
1049
|
+
const { form, field, type } = decodeNodeId(payload.nodeId);
|
|
1050
|
+
if (form && type === 'form') {
|
|
1051
|
+
payload.state = buildFormState(form);
|
|
1052
|
+
SELECTED_NODE = form;
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
if (field && type === 'field') {
|
|
1056
|
+
payload.state = buildFieldState(field);
|
|
1057
|
+
SELECTED_NODE = field;
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
1060
|
+
SELECTED_NODE = null;
|
|
1061
|
+
});
|
|
1062
|
+
}
|
|
1063
|
+
function mapFormForDevtoolsInspector(form) {
|
|
1064
|
+
const { textColor, bgColor } = getTagTheme(form);
|
|
1065
|
+
const formTreeNodes = {};
|
|
1066
|
+
Object.values(form.fieldsByPath.value).forEach(field => {
|
|
1067
|
+
const fieldInstance = Array.isArray(field) ? field[0] : field;
|
|
1068
|
+
if (!fieldInstance) {
|
|
1069
|
+
return;
|
|
1070
|
+
}
|
|
1071
|
+
setInPath(formTreeNodes, unref(fieldInstance.name), mapFieldForDevtoolsInspector(fieldInstance, form));
|
|
1072
|
+
});
|
|
1073
|
+
function buildFormTree(tree, path = []) {
|
|
1074
|
+
const key = [...path].pop();
|
|
1075
|
+
if ('id' in tree) {
|
|
1076
|
+
return Object.assign(Object.assign({}, tree), { label: key || tree.label });
|
|
1077
|
+
}
|
|
1078
|
+
if (isObject(tree)) {
|
|
1079
|
+
return {
|
|
1080
|
+
id: `${path.join('.')}`,
|
|
1081
|
+
label: key || '',
|
|
1082
|
+
children: Object.keys(tree).map(key => buildFormTree(tree[key], [...path, key])),
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
if (Array.isArray(tree)) {
|
|
1086
|
+
return {
|
|
1087
|
+
id: `${path.join('.')}`,
|
|
1088
|
+
label: `${key}[]`,
|
|
1089
|
+
children: tree.map((c, idx) => buildFormTree(c, [...path, String(idx)])),
|
|
1090
|
+
};
|
|
1091
|
+
}
|
|
1092
|
+
return { id: '', label: '', children: [] };
|
|
1093
|
+
}
|
|
1094
|
+
const { children } = buildFormTree(formTreeNodes);
|
|
1095
|
+
return {
|
|
1096
|
+
id: encodeNodeId(form),
|
|
1097
|
+
label: 'Form',
|
|
1098
|
+
children,
|
|
1099
|
+
tags: [
|
|
1100
|
+
{
|
|
1101
|
+
label: 'Form',
|
|
1102
|
+
textColor,
|
|
1103
|
+
backgroundColor: bgColor,
|
|
1104
|
+
},
|
|
1105
|
+
{
|
|
1106
|
+
label: `${Object.keys(form.fieldsByPath.value).length} fields`,
|
|
1107
|
+
textColor: COLORS.white,
|
|
1108
|
+
backgroundColor: COLORS.unknown,
|
|
1109
|
+
},
|
|
1110
|
+
],
|
|
1111
|
+
};
|
|
1112
|
+
}
|
|
1113
|
+
function mapFieldForDevtoolsInspector(field, form) {
|
|
1114
|
+
const fieldInstance = normalizeField(field);
|
|
1115
|
+
const { textColor, bgColor } = getTagTheme(fieldInstance);
|
|
1116
|
+
const isGroup = Array.isArray(field) && field.length > 1;
|
|
1117
|
+
return {
|
|
1118
|
+
id: encodeNodeId(form, fieldInstance, !isGroup),
|
|
1119
|
+
label: unref(fieldInstance.name),
|
|
1120
|
+
children: Array.isArray(field) ? field.map(fieldItem => mapFieldForDevtoolsInspector(fieldItem, form)) : undefined,
|
|
1121
|
+
tags: [
|
|
1122
|
+
isGroup
|
|
1123
|
+
? undefined
|
|
1124
|
+
: {
|
|
1125
|
+
label: 'Field',
|
|
1126
|
+
textColor,
|
|
1127
|
+
backgroundColor: bgColor,
|
|
1128
|
+
},
|
|
1129
|
+
!form
|
|
1130
|
+
? {
|
|
1131
|
+
label: 'Standalone',
|
|
1132
|
+
textColor: COLORS.black,
|
|
1133
|
+
backgroundColor: COLORS.gray,
|
|
1134
|
+
}
|
|
1135
|
+
: undefined,
|
|
1136
|
+
!isGroup && fieldInstance.type === 'checkbox'
|
|
1137
|
+
? {
|
|
1138
|
+
label: 'Checkbox',
|
|
1139
|
+
textColor: COLORS.white,
|
|
1140
|
+
backgroundColor: COLORS.blue,
|
|
1141
|
+
}
|
|
1142
|
+
: undefined,
|
|
1143
|
+
!isGroup && fieldInstance.type === 'radio'
|
|
1144
|
+
? {
|
|
1145
|
+
label: 'Radio',
|
|
1146
|
+
textColor: COLORS.white,
|
|
1147
|
+
backgroundColor: COLORS.purple,
|
|
1148
|
+
}
|
|
1149
|
+
: undefined,
|
|
1150
|
+
isGroup
|
|
1151
|
+
? {
|
|
1152
|
+
label: 'Group',
|
|
1153
|
+
textColor: COLORS.black,
|
|
1154
|
+
backgroundColor: COLORS.orange,
|
|
1155
|
+
}
|
|
1156
|
+
: undefined,
|
|
1157
|
+
].filter(Boolean),
|
|
1158
|
+
};
|
|
1159
|
+
}
|
|
1160
|
+
function encodeNodeId(form, field, encodeIndex = true) {
|
|
1161
|
+
const fieldPath = form ? unref(field === null || field === void 0 ? void 0 : field.name) : field === null || field === void 0 ? void 0 : field.id;
|
|
1162
|
+
const fieldGroup = fieldPath ? form === null || form === void 0 ? void 0 : form.fieldsByPath.value[fieldPath] : undefined;
|
|
1163
|
+
let idx;
|
|
1164
|
+
if (encodeIndex && field && Array.isArray(fieldGroup)) {
|
|
1165
|
+
idx = fieldGroup.indexOf(field);
|
|
1166
|
+
}
|
|
1167
|
+
const idObject = { f: form === null || form === void 0 ? void 0 : form.formId, ff: fieldPath, idx, type: field ? 'field' : 'form' };
|
|
1168
|
+
return btoa(JSON.stringify(idObject));
|
|
1169
|
+
}
|
|
1170
|
+
function decodeNodeId(nodeId) {
|
|
1171
|
+
try {
|
|
1172
|
+
const idObject = JSON.parse(atob(nodeId));
|
|
1173
|
+
const form = DEVTOOLS_FORMS[idObject.f];
|
|
1174
|
+
if (!form && idObject.ff) {
|
|
1175
|
+
const field = DEVTOOLS_FIELDS[idObject.ff];
|
|
1176
|
+
if (!field) {
|
|
1177
|
+
return {};
|
|
1178
|
+
}
|
|
1179
|
+
return {
|
|
1180
|
+
type: idObject.type,
|
|
1181
|
+
field,
|
|
1182
|
+
};
|
|
1183
|
+
}
|
|
1184
|
+
if (!form) {
|
|
1185
|
+
return {};
|
|
1186
|
+
}
|
|
1187
|
+
const fieldGroup = form.fieldsByPath.value[idObject.ff];
|
|
1188
|
+
return {
|
|
1189
|
+
type: idObject.type,
|
|
1190
|
+
form,
|
|
1191
|
+
field: Array.isArray(fieldGroup) ? fieldGroup[idObject.idx || 0] : fieldGroup,
|
|
1192
|
+
};
|
|
1193
|
+
}
|
|
1194
|
+
catch (err) {
|
|
1195
|
+
// console.error(`Devtools: [vee-validate] Failed to parse node id ${nodeId}`);
|
|
1196
|
+
}
|
|
1197
|
+
return {};
|
|
1198
|
+
}
|
|
1199
|
+
function buildFieldState(field) {
|
|
1200
|
+
const { errors, meta, value } = field;
|
|
1201
|
+
return {
|
|
1202
|
+
'Field state': [
|
|
1203
|
+
{ key: 'errors', value: errors.value },
|
|
1204
|
+
{
|
|
1205
|
+
key: 'initialValue',
|
|
1206
|
+
value: meta.initialValue,
|
|
1207
|
+
},
|
|
1208
|
+
{
|
|
1209
|
+
key: 'currentValue',
|
|
1210
|
+
value: value.value,
|
|
1211
|
+
},
|
|
1212
|
+
{
|
|
1213
|
+
key: 'touched',
|
|
1214
|
+
value: meta.touched,
|
|
1215
|
+
},
|
|
1216
|
+
{
|
|
1217
|
+
key: 'dirty',
|
|
1218
|
+
value: meta.dirty,
|
|
1219
|
+
},
|
|
1220
|
+
{
|
|
1221
|
+
key: 'valid',
|
|
1222
|
+
value: meta.valid,
|
|
1223
|
+
},
|
|
1224
|
+
],
|
|
1225
|
+
};
|
|
1226
|
+
}
|
|
1227
|
+
function buildFormState(form) {
|
|
1228
|
+
const { errorBag, meta, values, isSubmitting, submitCount } = form;
|
|
1229
|
+
return {
|
|
1230
|
+
'Form state': [
|
|
1231
|
+
{
|
|
1232
|
+
key: 'submitCount',
|
|
1233
|
+
value: submitCount.value,
|
|
1234
|
+
},
|
|
1235
|
+
{
|
|
1236
|
+
key: 'isSubmitting',
|
|
1237
|
+
value: isSubmitting.value,
|
|
1238
|
+
},
|
|
1239
|
+
{
|
|
1240
|
+
key: 'touched',
|
|
1241
|
+
value: meta.value.touched,
|
|
1242
|
+
},
|
|
1243
|
+
{
|
|
1244
|
+
key: 'dirty',
|
|
1245
|
+
value: meta.value.dirty,
|
|
1246
|
+
},
|
|
1247
|
+
{
|
|
1248
|
+
key: 'valid',
|
|
1249
|
+
value: meta.value.valid,
|
|
1250
|
+
},
|
|
1251
|
+
{
|
|
1252
|
+
key: 'initialValues',
|
|
1253
|
+
value: meta.value.initialValues,
|
|
1254
|
+
},
|
|
1255
|
+
{
|
|
1256
|
+
key: 'currentValues',
|
|
1257
|
+
value: values,
|
|
1258
|
+
},
|
|
1259
|
+
{
|
|
1260
|
+
key: 'errors',
|
|
1261
|
+
value: keysOf(errorBag.value).reduce((acc, key) => {
|
|
1262
|
+
var _a;
|
|
1263
|
+
const message = (_a = errorBag.value[key]) === null || _a === void 0 ? void 0 : _a[0];
|
|
1264
|
+
if (message) {
|
|
1265
|
+
acc[key] = message;
|
|
1266
|
+
}
|
|
1267
|
+
return acc;
|
|
1268
|
+
}, {}),
|
|
1269
|
+
},
|
|
1270
|
+
],
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1273
|
+
/**
|
|
1274
|
+
* Resolves the tag color based on the form state
|
|
1275
|
+
*/
|
|
1276
|
+
function getTagTheme(fieldOrForm) {
|
|
1277
|
+
// const fallbackColors = {
|
|
1278
|
+
// bgColor: COLORS.unknown,
|
|
1279
|
+
// textColor: COLORS.white,
|
|
1280
|
+
// };
|
|
1281
|
+
const isValid = 'id' in fieldOrForm ? fieldOrForm.meta.valid : fieldOrForm.meta.value.valid;
|
|
1282
|
+
return {
|
|
1283
|
+
bgColor: isValid ? COLORS.success : COLORS.error,
|
|
1284
|
+
textColor: isValid ? COLORS.black : COLORS.white,
|
|
1285
|
+
};
|
|
1286
|
+
}
|
|
1287
|
+
|
|
776
1288
|
/**
|
|
777
1289
|
* Creates a field composite.
|
|
778
1290
|
*/
|
|
779
1291
|
function useField(name, rules, opts) {
|
|
780
|
-
|
|
781
|
-
|
|
1292
|
+
if (hasCheckedAttr(opts === null || opts === void 0 ? void 0 : opts.type)) {
|
|
1293
|
+
return useCheckboxField(name, rules, opts);
|
|
1294
|
+
}
|
|
1295
|
+
return _useField(name, rules, opts);
|
|
1296
|
+
}
|
|
1297
|
+
function _useField(name, rules, opts) {
|
|
1298
|
+
const { initialValue: modelValue, validateOnMount, bails, type, checkedValue, label, validateOnValueUpdate, uncheckedValue, standalone, } = normalizeOptions(unref(name), opts);
|
|
782
1299
|
const form = !standalone ? injectWithSelf(FormContextKey) : undefined;
|
|
783
|
-
const {
|
|
784
|
-
|
|
785
|
-
initValue: initialValue,
|
|
786
|
-
form,
|
|
787
|
-
type,
|
|
788
|
-
checkedValue,
|
|
1300
|
+
const { id, value, initialValue, meta, setState, errors, errorMessage } = useFieldState(name, {
|
|
1301
|
+
modelValue,
|
|
789
1302
|
standalone,
|
|
790
1303
|
});
|
|
1304
|
+
/**
|
|
1305
|
+
* Handles common onBlur meta update
|
|
1306
|
+
*/
|
|
1307
|
+
const handleBlur = () => {
|
|
1308
|
+
meta.touched = true;
|
|
1309
|
+
};
|
|
791
1310
|
const normalizedRules = computed(() => {
|
|
792
1311
|
let rulesValue = unref(rules);
|
|
793
1312
|
const schema = unref(form === null || form === void 0 ? void 0 : form.schema);
|
|
@@ -814,27 +1333,30 @@ function useField(name, rules, opts) {
|
|
|
814
1333
|
meta.pending = true;
|
|
815
1334
|
meta.validated = true;
|
|
816
1335
|
const result = await validateCurrentValue('validated-only');
|
|
1336
|
+
setState({ errors: result.errors });
|
|
817
1337
|
meta.pending = false;
|
|
818
|
-
return
|
|
1338
|
+
return result;
|
|
819
1339
|
}
|
|
820
1340
|
async function validateValidStateOnly() {
|
|
821
1341
|
const result = await validateCurrentValue('silent');
|
|
822
1342
|
meta.valid = result.valid;
|
|
1343
|
+
return result;
|
|
823
1344
|
}
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
if (checked && checked.value === ((_b = (_a = e) === null || _a === void 0 ? void 0 : _a.target) === null || _b === void 0 ? void 0 : _b.checked)) {
|
|
828
|
-
return;
|
|
1345
|
+
function validate$1(opts) {
|
|
1346
|
+
if (!(opts === null || opts === void 0 ? void 0 : opts.mode) || (opts === null || opts === void 0 ? void 0 : opts.mode) === 'force') {
|
|
1347
|
+
return validateWithStateMutation();
|
|
829
1348
|
}
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
if (checked && type === 'checkbox' && !form) {
|
|
833
|
-
newValue = resolveNextCheckboxValue(value.value, unref(checkedValue), unref(uncheckedValue));
|
|
1349
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.mode) === 'validated-only') {
|
|
1350
|
+
return validateWithStateMutation();
|
|
834
1351
|
}
|
|
1352
|
+
return validateValidStateOnly();
|
|
1353
|
+
}
|
|
1354
|
+
// Common input/change event handler
|
|
1355
|
+
const handleChange = (e, shouldValidate = true) => {
|
|
1356
|
+
const newValue = normalizeEventValue(e);
|
|
835
1357
|
value.value = newValue;
|
|
836
1358
|
if (!validateOnValueUpdate && shouldValidate) {
|
|
837
|
-
|
|
1359
|
+
validateWithStateMutation();
|
|
838
1360
|
}
|
|
839
1361
|
};
|
|
840
1362
|
// Runs the initial validation
|
|
@@ -859,17 +1381,31 @@ function useField(name, rules, opts) {
|
|
|
859
1381
|
}
|
|
860
1382
|
watchValue();
|
|
861
1383
|
function resetField(state) {
|
|
1384
|
+
var _a;
|
|
862
1385
|
unwatchValue === null || unwatchValue === void 0 ? void 0 : unwatchValue();
|
|
863
|
-
|
|
1386
|
+
const newValue = state && 'value' in state ? state.value : initialValue.value;
|
|
1387
|
+
setState({
|
|
1388
|
+
value: klona(newValue),
|
|
1389
|
+
initialValue: klona(newValue),
|
|
1390
|
+
touched: (_a = state === null || state === void 0 ? void 0 : state.touched) !== null && _a !== void 0 ? _a : false,
|
|
1391
|
+
errors: (state === null || state === void 0 ? void 0 : state.errors) || [],
|
|
1392
|
+
});
|
|
1393
|
+
meta.pending = false;
|
|
1394
|
+
meta.validated = false;
|
|
864
1395
|
validateValidStateOnly();
|
|
865
1396
|
// need to watch at next tick to avoid triggering the value watcher
|
|
866
1397
|
nextTick(() => {
|
|
867
1398
|
watchValue();
|
|
868
1399
|
});
|
|
869
1400
|
}
|
|
1401
|
+
function setValue(newValue) {
|
|
1402
|
+
value.value = newValue;
|
|
1403
|
+
}
|
|
1404
|
+
function setErrors(errors) {
|
|
1405
|
+
setState({ errors: Array.isArray(errors) ? errors : [errors] });
|
|
1406
|
+
}
|
|
870
1407
|
const field = {
|
|
871
|
-
|
|
872
|
-
fid,
|
|
1408
|
+
id,
|
|
873
1409
|
name,
|
|
874
1410
|
label,
|
|
875
1411
|
value,
|
|
@@ -879,17 +1415,16 @@ function useField(name, rules, opts) {
|
|
|
879
1415
|
type,
|
|
880
1416
|
checkedValue,
|
|
881
1417
|
uncheckedValue,
|
|
882
|
-
checked,
|
|
883
1418
|
bails,
|
|
884
1419
|
resetField,
|
|
885
1420
|
handleReset: () => resetField(),
|
|
886
|
-
validate:
|
|
1421
|
+
validate: validate$1,
|
|
887
1422
|
handleChange,
|
|
888
1423
|
handleBlur,
|
|
889
|
-
|
|
890
|
-
setValidationState,
|
|
1424
|
+
setState,
|
|
891
1425
|
setTouched,
|
|
892
1426
|
setErrors,
|
|
1427
|
+
setValue,
|
|
893
1428
|
};
|
|
894
1429
|
provide(FieldContextKey, field);
|
|
895
1430
|
if (isRef(rules) && typeof unref(rules) !== 'function') {
|
|
@@ -897,11 +1432,20 @@ function useField(name, rules, opts) {
|
|
|
897
1432
|
if (es6(value, oldValue)) {
|
|
898
1433
|
return;
|
|
899
1434
|
}
|
|
900
|
-
|
|
1435
|
+
meta.validated ? validateWithStateMutation() : validateValidStateOnly();
|
|
901
1436
|
}, {
|
|
902
1437
|
deep: true,
|
|
903
1438
|
});
|
|
904
1439
|
}
|
|
1440
|
+
if ((process.env.NODE_ENV !== 'production')) {
|
|
1441
|
+
field._vm = getCurrentInstance();
|
|
1442
|
+
watch(() => (Object.assign(Object.assign({ errors: errors.value }, meta), { value: value.value })), refreshInspector, {
|
|
1443
|
+
deep: true,
|
|
1444
|
+
});
|
|
1445
|
+
if (!form) {
|
|
1446
|
+
registerSingleFieldWithDevtools(field);
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
905
1449
|
// if no associated form return the field API immediately
|
|
906
1450
|
if (!form) {
|
|
907
1451
|
return field;
|
|
@@ -940,7 +1484,7 @@ function useField(name, rules, opts) {
|
|
|
940
1484
|
}
|
|
941
1485
|
const shouldValidate = !es6(deps, oldDeps);
|
|
942
1486
|
if (shouldValidate) {
|
|
943
|
-
meta.
|
|
1487
|
+
meta.validated ? validateWithStateMutation() : validateValidStateOnly();
|
|
944
1488
|
}
|
|
945
1489
|
});
|
|
946
1490
|
return field;
|
|
@@ -965,104 +1509,6 @@ function normalizeOptions(name, opts) {
|
|
|
965
1509
|
const checkedValue = 'valueProp' in opts ? opts.valueProp : opts.checkedValue;
|
|
966
1510
|
return Object.assign(Object.assign(Object.assign({}, defaults()), (opts || {})), { checkedValue });
|
|
967
1511
|
}
|
|
968
|
-
/**
|
|
969
|
-
* Manages the validation state of a field.
|
|
970
|
-
*/
|
|
971
|
-
function useValidationState({ name, initValue, form, type, checkedValue, standalone, }) {
|
|
972
|
-
const { errors, errorMessage, setErrors } = useFieldErrors(name, form);
|
|
973
|
-
const formInitialValues = standalone ? undefined : injectWithSelf(FormInitialValuesKey, undefined);
|
|
974
|
-
// clones the ref value to a mutable version
|
|
975
|
-
const initialValueRef = ref(unref(initValue));
|
|
976
|
-
const initialValue = computed(() => {
|
|
977
|
-
return getFromPath(unref(formInitialValues), unref(name), unref(initialValueRef));
|
|
978
|
-
});
|
|
979
|
-
const value = useFieldValue$1(initialValue, name, form);
|
|
980
|
-
const meta = useFieldMeta(initialValue, value, errors);
|
|
981
|
-
const checked = hasCheckedAttr(type)
|
|
982
|
-
? computed(() => {
|
|
983
|
-
if (Array.isArray(value.value)) {
|
|
984
|
-
return value.value.includes(unref(checkedValue));
|
|
985
|
-
}
|
|
986
|
-
return unref(checkedValue) === value.value;
|
|
987
|
-
})
|
|
988
|
-
: undefined;
|
|
989
|
-
/**
|
|
990
|
-
* Handles common onBlur meta update
|
|
991
|
-
*/
|
|
992
|
-
const handleBlur = () => {
|
|
993
|
-
meta.touched = true;
|
|
994
|
-
};
|
|
995
|
-
/**
|
|
996
|
-
* Handles common on blur events
|
|
997
|
-
* @deprecated You should use `handleChange` instead
|
|
998
|
-
*/
|
|
999
|
-
const handleInput = (e) => {
|
|
1000
|
-
// Checkboxes/Radio will emit a `change` event anyway, custom components will use `update:modelValue`
|
|
1001
|
-
// so this is redundant
|
|
1002
|
-
if (!hasCheckedAttr(type)) {
|
|
1003
|
-
value.value = normalizeEventValue(e);
|
|
1004
|
-
}
|
|
1005
|
-
};
|
|
1006
|
-
// Updates the validation state with the validation result
|
|
1007
|
-
function setValidationState(result) {
|
|
1008
|
-
setErrors(result.errors);
|
|
1009
|
-
return result;
|
|
1010
|
-
}
|
|
1011
|
-
// Resets the validation state
|
|
1012
|
-
function resetValidationState(state) {
|
|
1013
|
-
var _a;
|
|
1014
|
-
const fieldPath = unref(name);
|
|
1015
|
-
const newValue = state && 'value' in state
|
|
1016
|
-
? state.value
|
|
1017
|
-
: getFromPath(unref(formInitialValues), fieldPath, unref(initValue));
|
|
1018
|
-
if (form) {
|
|
1019
|
-
form.setFieldValue(fieldPath, newValue, { force: true });
|
|
1020
|
-
form.setFieldInitialValue(fieldPath, newValue);
|
|
1021
|
-
}
|
|
1022
|
-
else {
|
|
1023
|
-
value.value = klona(newValue);
|
|
1024
|
-
initialValueRef.value = klona(newValue);
|
|
1025
|
-
}
|
|
1026
|
-
setErrors((state === null || state === void 0 ? void 0 : state.errors) || []);
|
|
1027
|
-
meta.touched = (_a = state === null || state === void 0 ? void 0 : state.touched) !== null && _a !== void 0 ? _a : false;
|
|
1028
|
-
meta.pending = false;
|
|
1029
|
-
meta.validated = false;
|
|
1030
|
-
}
|
|
1031
|
-
return {
|
|
1032
|
-
meta,
|
|
1033
|
-
errors,
|
|
1034
|
-
errorMessage,
|
|
1035
|
-
setErrors,
|
|
1036
|
-
setValidationState,
|
|
1037
|
-
resetValidationState,
|
|
1038
|
-
handleBlur,
|
|
1039
|
-
handleInput,
|
|
1040
|
-
value,
|
|
1041
|
-
checked,
|
|
1042
|
-
};
|
|
1043
|
-
}
|
|
1044
|
-
/**
|
|
1045
|
-
* Exposes meta flags state and some associated actions with them.
|
|
1046
|
-
*/
|
|
1047
|
-
function useFieldMeta(initialValue, currentValue, errors) {
|
|
1048
|
-
const meta = reactive({
|
|
1049
|
-
touched: false,
|
|
1050
|
-
pending: false,
|
|
1051
|
-
valid: true,
|
|
1052
|
-
validated: !!unref(errors).length,
|
|
1053
|
-
initialValue: computed(() => unref(initialValue)),
|
|
1054
|
-
dirty: computed(() => {
|
|
1055
|
-
return !es6(unref(currentValue), unref(initialValue));
|
|
1056
|
-
}),
|
|
1057
|
-
});
|
|
1058
|
-
watch(errors, value => {
|
|
1059
|
-
meta.valid = !value.length;
|
|
1060
|
-
}, {
|
|
1061
|
-
immediate: true,
|
|
1062
|
-
flush: 'sync',
|
|
1063
|
-
});
|
|
1064
|
-
return meta;
|
|
1065
|
-
}
|
|
1066
1512
|
/**
|
|
1067
1513
|
* Extracts the validation rules from a schema
|
|
1068
1514
|
*/
|
|
@@ -1074,49 +1520,40 @@ function extractRuleFromSchema(schema, fieldName) {
|
|
|
1074
1520
|
// there is a key on the schema object for this field
|
|
1075
1521
|
return schema[fieldName];
|
|
1076
1522
|
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
},
|
|
1110
|
-
};
|
|
1523
|
+
function useCheckboxField(name, rules, opts) {
|
|
1524
|
+
const form = !(opts === null || opts === void 0 ? void 0 : opts.standalone) ? injectWithSelf(FormContextKey) : undefined;
|
|
1525
|
+
const checkedValue = opts === null || opts === void 0 ? void 0 : opts.checkedValue;
|
|
1526
|
+
const uncheckedValue = opts === null || opts === void 0 ? void 0 : opts.uncheckedValue;
|
|
1527
|
+
function patchCheckboxApi(field) {
|
|
1528
|
+
const handleChange = field.handleChange;
|
|
1529
|
+
const checked = computed(() => {
|
|
1530
|
+
const currentValue = unref(field.value);
|
|
1531
|
+
const checkedVal = unref(checkedValue);
|
|
1532
|
+
return Array.isArray(currentValue) ? currentValue.includes(checkedVal) : checkedVal === currentValue;
|
|
1533
|
+
});
|
|
1534
|
+
function handleCheckboxChange(e, shouldValidate = true) {
|
|
1535
|
+
var _a, _b;
|
|
1536
|
+
if (checked.value === ((_b = (_a = e) === null || _a === void 0 ? void 0 : _a.target) === null || _b === void 0 ? void 0 : _b.checked)) {
|
|
1537
|
+
return;
|
|
1538
|
+
}
|
|
1539
|
+
let newValue = normalizeEventValue(e);
|
|
1540
|
+
// Single checkbox field without a form to toggle it's value
|
|
1541
|
+
if (!form) {
|
|
1542
|
+
newValue = resolveNextCheckboxValue(unref(field.value), unref(checkedValue), unref(uncheckedValue));
|
|
1543
|
+
}
|
|
1544
|
+
handleChange(newValue, shouldValidate);
|
|
1545
|
+
}
|
|
1546
|
+
onBeforeUnmount(() => {
|
|
1547
|
+
// toggles the checkbox value if it was checked
|
|
1548
|
+
if (checked.value) {
|
|
1549
|
+
handleCheckboxChange(unref(checkedValue), false);
|
|
1550
|
+
}
|
|
1551
|
+
});
|
|
1552
|
+
return Object.assign(Object.assign({}, field), { checked,
|
|
1553
|
+
checkedValue,
|
|
1554
|
+
uncheckedValue, handleChange: handleCheckboxChange });
|
|
1111
1555
|
}
|
|
1112
|
-
|
|
1113
|
-
return {
|
|
1114
|
-
errors,
|
|
1115
|
-
errorMessage: computed(() => errors.value[0]),
|
|
1116
|
-
setErrors: (messages) => {
|
|
1117
|
-
form.setFieldErrorBag(unref(path), messages);
|
|
1118
|
-
},
|
|
1119
|
-
};
|
|
1556
|
+
return patchCheckboxApi(_useField(name, rules, opts));
|
|
1120
1557
|
}
|
|
1121
1558
|
|
|
1122
1559
|
const Field = defineComponent({
|
|
@@ -1190,7 +1627,7 @@ const Field = defineComponent({
|
|
|
1190
1627
|
const label = toRef(props, 'label');
|
|
1191
1628
|
const uncheckedValue = toRef(props, 'uncheckedValue');
|
|
1192
1629
|
const hasModelEvents = isPropPresent(props, 'onUpdate:modelValue');
|
|
1193
|
-
const { errors, value, errorMessage, validate: validateField, handleChange, handleBlur,
|
|
1630
|
+
const { errors, value, errorMessage, validate: validateField, handleChange, handleBlur, setTouched, resetField, handleReset, meta, checked, setErrors, } = useField(name, rules, {
|
|
1194
1631
|
validateOnMount: props.validateOnMount,
|
|
1195
1632
|
bails: props.bails,
|
|
1196
1633
|
standalone: props.standalone,
|
|
@@ -1209,8 +1646,13 @@ const Field = defineComponent({
|
|
|
1209
1646
|
ctx.emit('update:modelValue', value.value);
|
|
1210
1647
|
}
|
|
1211
1648
|
: handleChange;
|
|
1649
|
+
const handleInput = (e) => {
|
|
1650
|
+
if (!hasCheckedAttr(ctx.attrs.type)) {
|
|
1651
|
+
value.value = normalizeEventValue(e);
|
|
1652
|
+
}
|
|
1653
|
+
};
|
|
1212
1654
|
const onInputHandler = hasModelEvents
|
|
1213
|
-
? function
|
|
1655
|
+
? function handleInputWithModel(e) {
|
|
1214
1656
|
handleInput(e);
|
|
1215
1657
|
ctx.emit('update:modelValue', value.value);
|
|
1216
1658
|
}
|
|
@@ -1269,6 +1711,13 @@ const Field = defineComponent({
|
|
|
1269
1711
|
setErrors,
|
|
1270
1712
|
};
|
|
1271
1713
|
}
|
|
1714
|
+
ctx.expose({
|
|
1715
|
+
setErrors,
|
|
1716
|
+
setTouched,
|
|
1717
|
+
reset: resetField,
|
|
1718
|
+
validate: validateField,
|
|
1719
|
+
handleChange,
|
|
1720
|
+
});
|
|
1272
1721
|
return () => {
|
|
1273
1722
|
const tag = resolveDynamicComponent(resolveTag(props, ctx));
|
|
1274
1723
|
const children = normalizeChildren(tag, ctx, slotProps);
|
|
@@ -1311,40 +1760,19 @@ function resolveInitialValue(props, ctx) {
|
|
|
1311
1760
|
return isPropPresent(props, 'modelValue') ? props.modelValue : undefined;
|
|
1312
1761
|
}
|
|
1313
1762
|
|
|
1763
|
+
let FORM_COUNTER = 0;
|
|
1314
1764
|
function useForm(opts) {
|
|
1315
|
-
|
|
1316
|
-
|
|
1765
|
+
const formId = FORM_COUNTER++;
|
|
1766
|
+
// A lookup containing fields or field groups
|
|
1767
|
+
const fieldsByPath = ref({});
|
|
1317
1768
|
// If the form is currently submitting
|
|
1318
1769
|
const isSubmitting = ref(false);
|
|
1319
|
-
// a field map object useful for faster access of fields
|
|
1320
|
-
const fieldsById = computed(() => {
|
|
1321
|
-
return fields.value.reduce((acc, field) => {
|
|
1322
|
-
const fieldPath = unref(field.name);
|
|
1323
|
-
// if the field was not added before
|
|
1324
|
-
if (!acc[fieldPath]) {
|
|
1325
|
-
acc[fieldPath] = field;
|
|
1326
|
-
field.idx = -1;
|
|
1327
|
-
return acc;
|
|
1328
|
-
}
|
|
1329
|
-
// if the same name is detected
|
|
1330
|
-
const existingField = acc[fieldPath];
|
|
1331
|
-
if (!Array.isArray(existingField)) {
|
|
1332
|
-
existingField.idx = 0;
|
|
1333
|
-
acc[fieldPath] = [existingField];
|
|
1334
|
-
}
|
|
1335
|
-
const fieldGroup = acc[fieldPath];
|
|
1336
|
-
field.idx = fieldGroup.length;
|
|
1337
|
-
fieldGroup.push(field);
|
|
1338
|
-
return acc;
|
|
1339
|
-
}, {});
|
|
1340
|
-
});
|
|
1341
1770
|
// The number of times the user tried to submit the form
|
|
1342
1771
|
const submitCount = ref(0);
|
|
1772
|
+
// dictionary for field arrays to receive various signals like reset
|
|
1773
|
+
const fieldArraysLookup = {};
|
|
1343
1774
|
// a private ref for all form values
|
|
1344
1775
|
const formValues = reactive(klona(unref(opts === null || opts === void 0 ? void 0 : opts.initialValues) || {}));
|
|
1345
|
-
// a lookup to keep track of values by their field ids
|
|
1346
|
-
// this is important because later we need it if fields swap names
|
|
1347
|
-
const valuesByFid = {};
|
|
1348
1776
|
// the source of errors for the form fields
|
|
1349
1777
|
const { errorBag, setErrorBag, setFieldErrorBag } = useErrorBag(opts === null || opts === void 0 ? void 0 : opts.initialErrors);
|
|
1350
1778
|
// Gets the first error of each field
|
|
@@ -1357,12 +1785,19 @@ function useForm(opts) {
|
|
|
1357
1785
|
return acc;
|
|
1358
1786
|
}, {});
|
|
1359
1787
|
});
|
|
1788
|
+
function getFirstFieldAtPath(path) {
|
|
1789
|
+
const fieldOrGroup = fieldsByPath.value[path];
|
|
1790
|
+
return Array.isArray(fieldOrGroup) ? fieldOrGroup[0] : fieldOrGroup;
|
|
1791
|
+
}
|
|
1792
|
+
function fieldExists(path) {
|
|
1793
|
+
return !!fieldsByPath.value[path];
|
|
1794
|
+
}
|
|
1360
1795
|
/**
|
|
1361
1796
|
* Holds a computed reference to all fields names and labels
|
|
1362
1797
|
*/
|
|
1363
1798
|
const fieldNames = computed(() => {
|
|
1364
|
-
return keysOf(
|
|
1365
|
-
const field =
|
|
1799
|
+
return keysOf(fieldsByPath.value).reduce((names, path) => {
|
|
1800
|
+
const field = getFirstFieldAtPath(path);
|
|
1366
1801
|
if (field) {
|
|
1367
1802
|
names[path] = unref(field.label || field.name) || '';
|
|
1368
1803
|
}
|
|
@@ -1370,9 +1805,9 @@ function useForm(opts) {
|
|
|
1370
1805
|
}, {});
|
|
1371
1806
|
});
|
|
1372
1807
|
const fieldBailsMap = computed(() => {
|
|
1373
|
-
return keysOf(
|
|
1808
|
+
return keysOf(fieldsByPath.value).reduce((map, path) => {
|
|
1374
1809
|
var _a;
|
|
1375
|
-
const field =
|
|
1810
|
+
const field = getFirstFieldAtPath(path);
|
|
1376
1811
|
if (field) {
|
|
1377
1812
|
map[path] = (_a = field.bails) !== null && _a !== void 0 ? _a : true;
|
|
1378
1813
|
}
|
|
@@ -1383,18 +1818,21 @@ function useForm(opts) {
|
|
|
1383
1818
|
// we need this to process initial errors then unset them
|
|
1384
1819
|
const initialErrors = Object.assign({}, ((opts === null || opts === void 0 ? void 0 : opts.initialErrors) || {}));
|
|
1385
1820
|
// initial form values
|
|
1386
|
-
const {
|
|
1821
|
+
const { initialValues, originalInitialValues, setInitialValues } = useFormInitialValues(fieldsByPath, formValues, opts === null || opts === void 0 ? void 0 : opts.initialValues);
|
|
1387
1822
|
// form meta aggregations
|
|
1388
|
-
const meta = useFormMeta(
|
|
1823
|
+
const meta = useFormMeta(fieldsByPath, formValues, initialValues, errors);
|
|
1389
1824
|
const schema = opts === null || opts === void 0 ? void 0 : opts.validationSchema;
|
|
1390
1825
|
const formCtx = {
|
|
1391
|
-
|
|
1826
|
+
formId,
|
|
1827
|
+
fieldsByPath,
|
|
1392
1828
|
values: formValues,
|
|
1393
1829
|
errorBag,
|
|
1830
|
+
errors,
|
|
1394
1831
|
schema,
|
|
1395
1832
|
submitCount,
|
|
1396
1833
|
meta,
|
|
1397
1834
|
isSubmitting,
|
|
1835
|
+
fieldArraysLookup,
|
|
1398
1836
|
validateSchema: unref(schema) ? validateSchema : undefined,
|
|
1399
1837
|
validate,
|
|
1400
1838
|
register: registerField,
|
|
@@ -1410,8 +1848,18 @@ function useForm(opts) {
|
|
|
1410
1848
|
resetForm,
|
|
1411
1849
|
handleSubmit,
|
|
1412
1850
|
stageInitialValue,
|
|
1851
|
+
unsetInitialValue,
|
|
1413
1852
|
setFieldInitialValue,
|
|
1414
1853
|
};
|
|
1854
|
+
function isFieldGroup(fieldOrGroup) {
|
|
1855
|
+
return Array.isArray(fieldOrGroup);
|
|
1856
|
+
}
|
|
1857
|
+
function applyFieldMutation(fieldOrGroup, mutation) {
|
|
1858
|
+
if (Array.isArray(fieldOrGroup)) {
|
|
1859
|
+
return fieldOrGroup.forEach(mutation);
|
|
1860
|
+
}
|
|
1861
|
+
return mutation(fieldOrGroup);
|
|
1862
|
+
}
|
|
1415
1863
|
/**
|
|
1416
1864
|
* Manually sets an error message on a specific field
|
|
1417
1865
|
*/
|
|
@@ -1429,7 +1877,7 @@ function useForm(opts) {
|
|
|
1429
1877
|
*/
|
|
1430
1878
|
function setFieldValue(field, value, { force } = { force: false }) {
|
|
1431
1879
|
var _a;
|
|
1432
|
-
const fieldInstance =
|
|
1880
|
+
const fieldInstance = fieldsByPath.value[field];
|
|
1433
1881
|
const clonedValue = klona(value);
|
|
1434
1882
|
// field wasn't found, create a virtual field as a placeholder
|
|
1435
1883
|
if (!fieldInstance) {
|
|
@@ -1437,28 +1885,17 @@ function useForm(opts) {
|
|
|
1437
1885
|
return;
|
|
1438
1886
|
}
|
|
1439
1887
|
// Multiple checkboxes, and only one of them got updated
|
|
1440
|
-
if (
|
|
1441
|
-
const
|
|
1442
|
-
setInPath(formValues, field,
|
|
1443
|
-
fieldInstance.forEach(fieldItem => {
|
|
1444
|
-
valuesByFid[fieldItem.fid] = newVal;
|
|
1445
|
-
});
|
|
1888
|
+
if (isFieldGroup(fieldInstance) && ((_a = fieldInstance[0]) === null || _a === void 0 ? void 0 : _a.type) === 'checkbox' && !Array.isArray(value)) {
|
|
1889
|
+
const newValue = klona(resolveNextCheckboxValue(getFromPath(formValues, field) || [], value, undefined));
|
|
1890
|
+
setInPath(formValues, field, newValue);
|
|
1446
1891
|
return;
|
|
1447
1892
|
}
|
|
1448
1893
|
let newValue = value;
|
|
1449
1894
|
// Single Checkbox: toggles the field value unless the field is being reset then force it
|
|
1450
|
-
if (!
|
|
1895
|
+
if (!isFieldGroup(fieldInstance) && fieldInstance.type === 'checkbox' && !force) {
|
|
1451
1896
|
newValue = klona(resolveNextCheckboxValue(getFromPath(formValues, field), value, unref(fieldInstance.uncheckedValue)));
|
|
1452
1897
|
}
|
|
1453
1898
|
setInPath(formValues, field, newValue);
|
|
1454
|
-
// multiple radio fields
|
|
1455
|
-
if (fieldInstance && Array.isArray(fieldInstance)) {
|
|
1456
|
-
fieldInstance.forEach(fieldItem => {
|
|
1457
|
-
valuesByFid[fieldItem.fid] = newValue;
|
|
1458
|
-
});
|
|
1459
|
-
return;
|
|
1460
|
-
}
|
|
1461
|
-
valuesByFid[fieldInstance.fid] = newValue;
|
|
1462
1899
|
}
|
|
1463
1900
|
/**
|
|
1464
1901
|
* Sets multiple fields values
|
|
@@ -1472,16 +1909,17 @@ function useForm(opts) {
|
|
|
1472
1909
|
keysOf(fields).forEach(path => {
|
|
1473
1910
|
setFieldValue(path, fields[path]);
|
|
1474
1911
|
});
|
|
1912
|
+
// regenerate the arrays when the form values change
|
|
1913
|
+
Object.values(fieldArraysLookup).forEach(f => f && f.reset());
|
|
1475
1914
|
}
|
|
1476
1915
|
/**
|
|
1477
1916
|
* Sets the touched meta state on a field
|
|
1478
1917
|
*/
|
|
1479
1918
|
function setFieldTouched(field, isTouched) {
|
|
1480
|
-
const fieldInstance =
|
|
1481
|
-
if (
|
|
1482
|
-
|
|
1919
|
+
const fieldInstance = fieldsByPath.value[field];
|
|
1920
|
+
if (fieldInstance) {
|
|
1921
|
+
applyFieldMutation(fieldInstance, f => f.setTouched(isTouched));
|
|
1483
1922
|
}
|
|
1484
|
-
applyFieldMutation(fieldInstance, f => f.setTouched(isTouched));
|
|
1485
1923
|
}
|
|
1486
1924
|
/**
|
|
1487
1925
|
* Sets the touched meta state on multiple fields
|
|
@@ -1501,108 +1939,123 @@ function useForm(opts) {
|
|
|
1501
1939
|
setValues(state === null || state === void 0 ? void 0 : state.values);
|
|
1502
1940
|
}
|
|
1503
1941
|
else {
|
|
1942
|
+
// clean up the initial values back to the original
|
|
1943
|
+
setInitialValues(originalInitialValues.value);
|
|
1504
1944
|
// otherwise clean the current values
|
|
1505
|
-
setValues(
|
|
1945
|
+
setValues(originalInitialValues.value);
|
|
1506
1946
|
}
|
|
1507
|
-
|
|
1508
|
-
|
|
1947
|
+
Object.values(fieldsByPath.value).forEach(field => {
|
|
1948
|
+
if (!field) {
|
|
1949
|
+
return;
|
|
1950
|
+
}
|
|
1951
|
+
applyFieldMutation(field, f => f.resetField());
|
|
1952
|
+
});
|
|
1509
1953
|
if (state === null || state === void 0 ? void 0 : state.touched) {
|
|
1510
1954
|
setTouched(state.touched);
|
|
1511
1955
|
}
|
|
1512
1956
|
setErrors((state === null || state === void 0 ? void 0 : state.errors) || {});
|
|
1513
1957
|
submitCount.value = (state === null || state === void 0 ? void 0 : state.submitCount) || 0;
|
|
1514
1958
|
}
|
|
1959
|
+
function insertFieldAtPath(field, path) {
|
|
1960
|
+
const rawField = markRaw(field);
|
|
1961
|
+
const fieldPath = path;
|
|
1962
|
+
// first field at that path
|
|
1963
|
+
if (!fieldsByPath.value[fieldPath]) {
|
|
1964
|
+
fieldsByPath.value[fieldPath] = rawField;
|
|
1965
|
+
return;
|
|
1966
|
+
}
|
|
1967
|
+
const fieldAtPath = fieldsByPath.value[fieldPath];
|
|
1968
|
+
if (fieldAtPath && !Array.isArray(fieldAtPath)) {
|
|
1969
|
+
fieldsByPath.value[fieldPath] = [fieldAtPath];
|
|
1970
|
+
}
|
|
1971
|
+
// add the new array to that path
|
|
1972
|
+
fieldsByPath.value[fieldPath] = [...fieldsByPath.value[fieldPath], rawField];
|
|
1973
|
+
}
|
|
1974
|
+
function removeFieldFromPath(field, path) {
|
|
1975
|
+
const fieldPath = path;
|
|
1976
|
+
const fieldAtPath = fieldsByPath.value[fieldPath];
|
|
1977
|
+
if (!fieldAtPath) {
|
|
1978
|
+
return;
|
|
1979
|
+
}
|
|
1980
|
+
// same field at path
|
|
1981
|
+
if (!isFieldGroup(fieldAtPath) && field.id === fieldAtPath.id) {
|
|
1982
|
+
delete fieldsByPath.value[fieldPath];
|
|
1983
|
+
return;
|
|
1984
|
+
}
|
|
1985
|
+
if (isFieldGroup(fieldAtPath)) {
|
|
1986
|
+
const idx = fieldAtPath.findIndex(f => f.id === field.id);
|
|
1987
|
+
if (idx === -1) {
|
|
1988
|
+
return;
|
|
1989
|
+
}
|
|
1990
|
+
fieldAtPath.splice(idx, 1);
|
|
1991
|
+
if (fieldAtPath.length === 1) {
|
|
1992
|
+
fieldsByPath.value[fieldPath] = fieldAtPath[0];
|
|
1993
|
+
return;
|
|
1994
|
+
}
|
|
1995
|
+
if (!fieldAtPath.length) {
|
|
1996
|
+
delete fieldsByPath.value[fieldPath];
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
1515
2000
|
function registerField(field) {
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
// eslint-disable-next-line no-unused-expressions
|
|
1519
|
-
fieldsById.value; // force computation of the fields ids to properly set their idx
|
|
2001
|
+
const fieldPath = unref(field.name);
|
|
2002
|
+
insertFieldAtPath(field, fieldPath);
|
|
1520
2003
|
if (isRef(field.name)) {
|
|
1521
|
-
valuesByFid[field.fid] = field.value.value;
|
|
1522
2004
|
// ensures when a field's name was already taken that it preserves its same value
|
|
1523
2005
|
// necessary for fields generated by loops
|
|
1524
|
-
watch(field.name, (newPath, oldPath) => {
|
|
1525
|
-
|
|
1526
|
-
|
|
2006
|
+
watch(field.name, async (newPath, oldPath) => {
|
|
2007
|
+
// cache the value
|
|
2008
|
+
await nextTick();
|
|
2009
|
+
removeFieldFromPath(field, oldPath);
|
|
2010
|
+
insertFieldAtPath(field, newPath);
|
|
2011
|
+
// re-validate if either path had errors before
|
|
2012
|
+
if (errors.value[oldPath] || errors.value[newPath]) {
|
|
2013
|
+
validateField(newPath);
|
|
2014
|
+
}
|
|
1527
2015
|
// clean up the old path if no other field is sharing that name
|
|
1528
2016
|
// #3325
|
|
1529
|
-
|
|
2017
|
+
await nextTick();
|
|
2018
|
+
if (!fieldExists(oldPath)) {
|
|
1530
2019
|
unsetPath(formValues, oldPath);
|
|
1531
|
-
unsetPath(initialValues.value, oldPath);
|
|
1532
2020
|
}
|
|
1533
|
-
}, {
|
|
1534
|
-
flush: 'post',
|
|
1535
2021
|
});
|
|
1536
2022
|
}
|
|
1537
2023
|
// if field already had errors (initial errors) that's not user-set, validate it again to ensure state is correct
|
|
1538
2024
|
// the difference being that `initialErrors` will contain the error message while other errors (pre-validated schema) won't have them as initial errors
|
|
1539
2025
|
// #3342
|
|
1540
|
-
const path = unref(field.name);
|
|
1541
2026
|
const initialErrorMessage = unref(field.errorMessage);
|
|
1542
|
-
if (initialErrorMessage && (initialErrors === null || initialErrors === void 0 ? void 0 : initialErrors[
|
|
1543
|
-
validateField(
|
|
2027
|
+
if (initialErrorMessage && (initialErrors === null || initialErrors === void 0 ? void 0 : initialErrors[fieldPath]) !== initialErrorMessage) {
|
|
2028
|
+
validateField(fieldPath);
|
|
1544
2029
|
}
|
|
1545
2030
|
// marks the initial error as "consumed" so it won't be matched later with same non-initial error
|
|
1546
|
-
delete initialErrors[
|
|
2031
|
+
delete initialErrors[fieldPath];
|
|
1547
2032
|
}
|
|
1548
2033
|
function unregisterField(field) {
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
if (idx === -1) {
|
|
1552
|
-
return;
|
|
1553
|
-
}
|
|
1554
|
-
fields.value.splice(idx, 1);
|
|
1555
|
-
const fid = field.fid;
|
|
1556
|
-
// cleans up the field value from fid lookup
|
|
2034
|
+
const fieldName = unref(field.name);
|
|
2035
|
+
removeFieldFromPath(field, fieldName);
|
|
1557
2036
|
nextTick(() => {
|
|
1558
|
-
delete valuesByFid[fid];
|
|
1559
2037
|
// clears a field error on unmounted
|
|
1560
2038
|
// we wait till next tick to make sure if the field is completely removed and doesn't have any siblings like checkboxes
|
|
1561
2039
|
// #3384
|
|
1562
|
-
if (!
|
|
2040
|
+
if (!fieldExists(fieldName)) {
|
|
1563
2041
|
setFieldError(fieldName, undefined);
|
|
2042
|
+
unsetPath(formValues, fieldName);
|
|
1564
2043
|
}
|
|
1565
2044
|
});
|
|
1566
|
-
const fieldName = unref(field.name);
|
|
1567
|
-
// in this case, this is a single field not a group (checkbox or radio)
|
|
1568
|
-
// so remove the field value key immediately
|
|
1569
|
-
if (field.idx === -1) {
|
|
1570
|
-
// avoid un-setting the value if the field was switched with another that shares the same name
|
|
1571
|
-
// they will be unset once the new field takes over the new name, look at `#registerField()`
|
|
1572
|
-
// #3166
|
|
1573
|
-
const isSharingName = fields.value.find(f => unref(f.name) === fieldName);
|
|
1574
|
-
if (isSharingName) {
|
|
1575
|
-
return;
|
|
1576
|
-
}
|
|
1577
|
-
unsetPath(formValues, fieldName);
|
|
1578
|
-
unsetPath(initialValues.value, fieldName);
|
|
1579
|
-
return;
|
|
1580
|
-
}
|
|
1581
|
-
// otherwise find the actual value in the current array of values and remove it
|
|
1582
|
-
const valueIdx = (_b = (_a = getFromPath(formValues, fieldName)) === null || _a === void 0 ? void 0 : _a.indexOf) === null || _b === void 0 ? void 0 : _b.call(_a, unref(field.checkedValue));
|
|
1583
|
-
if (valueIdx === undefined) {
|
|
1584
|
-
unsetPath(formValues, fieldName);
|
|
1585
|
-
return;
|
|
1586
|
-
}
|
|
1587
|
-
if (valueIdx === -1) {
|
|
1588
|
-
return;
|
|
1589
|
-
}
|
|
1590
|
-
if (Array.isArray(formValues[fieldName])) {
|
|
1591
|
-
unsetPath(formValues, `${fieldName}.${valueIdx}`);
|
|
1592
|
-
return;
|
|
1593
|
-
}
|
|
1594
|
-
unsetPath(formValues, fieldName);
|
|
1595
|
-
unsetPath(initialValues.value, fieldName);
|
|
1596
2045
|
}
|
|
1597
|
-
async function validate() {
|
|
2046
|
+
async function validate(opts) {
|
|
1598
2047
|
if (formCtx.validateSchema) {
|
|
1599
|
-
return formCtx.validateSchema('force');
|
|
2048
|
+
return formCtx.validateSchema((opts === null || opts === void 0 ? void 0 : opts.mode) || 'force');
|
|
1600
2049
|
}
|
|
1601
2050
|
// No schema, each field is responsible to validate itself
|
|
1602
|
-
const validations = await Promise.all(
|
|
1603
|
-
|
|
2051
|
+
const validations = await Promise.all(Object.values(fieldsByPath.value).map(field => {
|
|
2052
|
+
const fieldInstance = Array.isArray(field) ? field[0] : field;
|
|
2053
|
+
if (!fieldInstance) {
|
|
2054
|
+
return Promise.resolve({ key: '', valid: true, errors: [] });
|
|
2055
|
+
}
|
|
2056
|
+
return fieldInstance.validate(opts).then((result) => {
|
|
1604
2057
|
return {
|
|
1605
|
-
key: unref(
|
|
2058
|
+
key: unref(fieldInstance.name),
|
|
1606
2059
|
valid: result.valid,
|
|
1607
2060
|
errors: result.errors,
|
|
1608
2061
|
};
|
|
@@ -1625,8 +2078,8 @@ function useForm(opts) {
|
|
|
1625
2078
|
errors,
|
|
1626
2079
|
};
|
|
1627
2080
|
}
|
|
1628
|
-
function validateField(field) {
|
|
1629
|
-
const fieldInstance =
|
|
2081
|
+
async function validateField(field) {
|
|
2082
|
+
const fieldInstance = fieldsByPath.value[field];
|
|
1630
2083
|
if (!fieldInstance) {
|
|
1631
2084
|
warn$1(`field with name ${field} was not found`);
|
|
1632
2085
|
return Promise.resolve({ errors: [], valid: true });
|
|
@@ -1636,14 +2089,14 @@ function useForm(opts) {
|
|
|
1636
2089
|
}
|
|
1637
2090
|
return fieldInstance.validate();
|
|
1638
2091
|
}
|
|
1639
|
-
function handleSubmit(fn) {
|
|
2092
|
+
function handleSubmit(fn, onValidationError) {
|
|
1640
2093
|
return function submissionHandler(e) {
|
|
1641
2094
|
if (e instanceof Event) {
|
|
1642
2095
|
e.preventDefault();
|
|
1643
2096
|
e.stopPropagation();
|
|
1644
2097
|
}
|
|
1645
2098
|
// Touch all fields
|
|
1646
|
-
setTouched(keysOf(
|
|
2099
|
+
setTouched(keysOf(fieldsByPath.value).reduce((acc, field) => {
|
|
1647
2100
|
acc[field] = true;
|
|
1648
2101
|
return acc;
|
|
1649
2102
|
}, {}));
|
|
@@ -1663,9 +2116,18 @@ function useForm(opts) {
|
|
|
1663
2116
|
resetForm,
|
|
1664
2117
|
});
|
|
1665
2118
|
}
|
|
2119
|
+
if (!result.valid && typeof onValidationError === 'function') {
|
|
2120
|
+
onValidationError({
|
|
2121
|
+
values: klona(formValues),
|
|
2122
|
+
evt: e,
|
|
2123
|
+
errors: result.errors,
|
|
2124
|
+
results: result.results,
|
|
2125
|
+
});
|
|
2126
|
+
}
|
|
1666
2127
|
})
|
|
1667
|
-
.then(
|
|
2128
|
+
.then(returnVal => {
|
|
1668
2129
|
isSubmitting.value = false;
|
|
2130
|
+
return returnVal;
|
|
1669
2131
|
}, err => {
|
|
1670
2132
|
isSubmitting.value = false;
|
|
1671
2133
|
// re-throw the err so it doesn't go silent
|
|
@@ -1676,6 +2138,9 @@ function useForm(opts) {
|
|
|
1676
2138
|
function setFieldInitialValue(path, value) {
|
|
1677
2139
|
setInPath(initialValues.value, path, klona(value));
|
|
1678
2140
|
}
|
|
2141
|
+
function unsetInitialValue(path) {
|
|
2142
|
+
unsetPath(initialValues.value, path);
|
|
2143
|
+
}
|
|
1679
2144
|
/**
|
|
1680
2145
|
* Sneaky function to set initial field values
|
|
1681
2146
|
*/
|
|
@@ -1683,7 +2148,7 @@ function useForm(opts) {
|
|
|
1683
2148
|
setInPath(formValues, path, value);
|
|
1684
2149
|
setFieldInitialValue(path, value);
|
|
1685
2150
|
}
|
|
1686
|
-
async function
|
|
2151
|
+
async function _validateSchema() {
|
|
1687
2152
|
const schemaValue = unref(schema);
|
|
1688
2153
|
if (!schemaValue) {
|
|
1689
2154
|
return { valid: true, results: {}, errors: {} };
|
|
@@ -1694,8 +2159,16 @@ function useForm(opts) {
|
|
|
1694
2159
|
names: fieldNames.value,
|
|
1695
2160
|
bailsMap: fieldBailsMap.value,
|
|
1696
2161
|
});
|
|
2162
|
+
return formResult;
|
|
2163
|
+
}
|
|
2164
|
+
/**
|
|
2165
|
+
* Batches validation runs in 5ms batches
|
|
2166
|
+
*/
|
|
2167
|
+
const debouncedSchemaValidation = debounceAsync(_validateSchema, 5);
|
|
2168
|
+
async function validateSchema(mode) {
|
|
2169
|
+
const formResult = await debouncedSchemaValidation();
|
|
1697
2170
|
// fields by id lookup
|
|
1698
|
-
const fieldsById = formCtx.
|
|
2171
|
+
const fieldsById = formCtx.fieldsByPath.value || {};
|
|
1699
2172
|
// errors fields names, we need it to also check if custom errors are updated
|
|
1700
2173
|
const currentErrorsPaths = keysOf(formCtx.errorBag.value);
|
|
1701
2174
|
// collect all the keys from the schema and all fields
|
|
@@ -1729,7 +2202,7 @@ function useForm(opts) {
|
|
|
1729
2202
|
if (mode === 'validated-only' && !wasValidated) {
|
|
1730
2203
|
return validation;
|
|
1731
2204
|
}
|
|
1732
|
-
applyFieldMutation(field, f => f.
|
|
2205
|
+
applyFieldMutation(field, f => f.setState({ errors: fieldResult.errors }));
|
|
1733
2206
|
return validation;
|
|
1734
2207
|
}, { valid: formResult.valid, results: {}, errors: {} });
|
|
1735
2208
|
}
|
|
@@ -1765,7 +2238,12 @@ function useForm(opts) {
|
|
|
1765
2238
|
}
|
|
1766
2239
|
// Provide injections
|
|
1767
2240
|
provide(FormContextKey, formCtx);
|
|
1768
|
-
|
|
2241
|
+
if ((process.env.NODE_ENV !== 'production')) {
|
|
2242
|
+
registerFormWithDevTools(formCtx);
|
|
2243
|
+
watch(() => (Object.assign(Object.assign({ errors: errorBag.value }, meta.value), { values: formValues, isSubmitting: isSubmitting.value, submitCount: submitCount.value })), refreshInspector, {
|
|
2244
|
+
deep: true,
|
|
2245
|
+
});
|
|
2246
|
+
}
|
|
1769
2247
|
return {
|
|
1770
2248
|
errors,
|
|
1771
2249
|
meta,
|
|
@@ -1789,7 +2267,7 @@ function useForm(opts) {
|
|
|
1789
2267
|
/**
|
|
1790
2268
|
* Manages form meta aggregation
|
|
1791
2269
|
*/
|
|
1792
|
-
function useFormMeta(
|
|
2270
|
+
function useFormMeta(fieldsByPath, currentValues, initialValues, errors) {
|
|
1793
2271
|
const MERGE_STRATEGIES = {
|
|
1794
2272
|
touched: 'some',
|
|
1795
2273
|
pending: 'some',
|
|
@@ -1799,9 +2277,10 @@ function useFormMeta(fields, currentValues, initialValues, errors) {
|
|
|
1799
2277
|
return !es6(currentValues, unref(initialValues));
|
|
1800
2278
|
});
|
|
1801
2279
|
const flags = computed(() => {
|
|
2280
|
+
const fields = Object.values(fieldsByPath.value).flat(1).filter(Boolean);
|
|
1802
2281
|
return keysOf(MERGE_STRATEGIES).reduce((acc, flag) => {
|
|
1803
2282
|
const mergeMethod = MERGE_STRATEGIES[flag];
|
|
1804
|
-
acc[flag] = fields
|
|
2283
|
+
acc[flag] = fields[mergeMethod](field => field.meta[flag]);
|
|
1805
2284
|
return acc;
|
|
1806
2285
|
}, {});
|
|
1807
2286
|
});
|
|
@@ -1813,13 +2292,17 @@ function useFormMeta(fields, currentValues, initialValues, errors) {
|
|
|
1813
2292
|
* Manages the initial values prop
|
|
1814
2293
|
*/
|
|
1815
2294
|
function useFormInitialValues(fields, formValues, providedValues) {
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
2295
|
+
// these are the mutable initial values as the fields are mounted/unmounted
|
|
2296
|
+
const initialValues = ref(klona(unref(providedValues)) || {});
|
|
2297
|
+
// these are the original initial value as provided by the user initially, they don't keep track of conditional fields
|
|
2298
|
+
// this is important because some conditional fields will overwrite the initial values for other fields who had the same name
|
|
2299
|
+
// like array fields, any push/insert operation will overwrite the initial values because they "create new fields"
|
|
2300
|
+
// so these are the values that the reset function should use
|
|
2301
|
+
// these only change when the user explicitly chanegs the initial values or when the user resets them with new values.
|
|
2302
|
+
const originalInitialValues = ref(klona(unref(providedValues)) || {});
|
|
1821
2303
|
function setInitialValues(values, updateFields = false) {
|
|
1822
2304
|
initialValues.value = klona(values);
|
|
2305
|
+
originalInitialValues.value = klona(values);
|
|
1823
2306
|
if (!updateFields) {
|
|
1824
2307
|
return;
|
|
1825
2308
|
}
|
|
@@ -1827,15 +2310,14 @@ function useFormInitialValues(fields, formValues, providedValues) {
|
|
|
1827
2310
|
// those are excluded because it's unlikely you want to change the form values using initial values
|
|
1828
2311
|
// we mostly watch them for API population or newly inserted fields
|
|
1829
2312
|
// 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
|
|
1830
|
-
const hadInteraction = (f) => f.meta.touched;
|
|
1831
2313
|
keysOf(fields.value).forEach(fieldPath => {
|
|
1832
2314
|
const field = fields.value[fieldPath];
|
|
1833
|
-
const
|
|
1834
|
-
if (
|
|
2315
|
+
const wasTouched = Array.isArray(field) ? field.some(f => f.meta.touched) : field === null || field === void 0 ? void 0 : field.meta.touched;
|
|
2316
|
+
if (!field || wasTouched) {
|
|
1835
2317
|
return;
|
|
1836
2318
|
}
|
|
1837
2319
|
const newValue = getFromPath(initialValues.value, fieldPath);
|
|
1838
|
-
setInPath(formValues, fieldPath, newValue);
|
|
2320
|
+
setInPath(formValues, fieldPath, klona(newValue));
|
|
1839
2321
|
});
|
|
1840
2322
|
}
|
|
1841
2323
|
if (isRef(providedValues)) {
|
|
@@ -1845,10 +2327,9 @@ function useFormInitialValues(fields, formValues, providedValues) {
|
|
|
1845
2327
|
deep: true,
|
|
1846
2328
|
});
|
|
1847
2329
|
}
|
|
1848
|
-
provide(FormInitialValuesKey, computedInitials);
|
|
1849
2330
|
return {
|
|
1850
|
-
readonlyInitialValues: computedInitials,
|
|
1851
2331
|
initialValues,
|
|
2332
|
+
originalInitialValues,
|
|
1852
2333
|
setInitialValues,
|
|
1853
2334
|
};
|
|
1854
2335
|
}
|
|
@@ -1921,6 +2402,10 @@ const Form = defineComponent({
|
|
|
1921
2402
|
type: Function,
|
|
1922
2403
|
default: undefined,
|
|
1923
2404
|
},
|
|
2405
|
+
onInvalidSubmit: {
|
|
2406
|
+
type: Function,
|
|
2407
|
+
default: undefined,
|
|
2408
|
+
},
|
|
1924
2409
|
},
|
|
1925
2410
|
setup(props, ctx) {
|
|
1926
2411
|
const initialValues = toRef(props, 'initialValues');
|
|
@@ -1932,7 +2417,7 @@ const Form = defineComponent({
|
|
|
1932
2417
|
initialTouched: props.initialTouched,
|
|
1933
2418
|
validateOnMount: props.validateOnMount,
|
|
1934
2419
|
});
|
|
1935
|
-
const onSubmit = props.onSubmit ? handleSubmit(props.onSubmit) : submitForm;
|
|
2420
|
+
const onSubmit = props.onSubmit ? handleSubmit(props.onSubmit, props.onInvalidSubmit) : submitForm;
|
|
1936
2421
|
function handleFormReset(e) {
|
|
1937
2422
|
if (isEvent(e)) {
|
|
1938
2423
|
// Prevent default form reset behavior
|
|
@@ -1945,7 +2430,7 @@ const Form = defineComponent({
|
|
|
1945
2430
|
}
|
|
1946
2431
|
function handleScopedSlotSubmit(evt, onSubmit) {
|
|
1947
2432
|
const onSuccess = typeof evt === 'function' && !onSubmit ? evt : onSubmit;
|
|
1948
|
-
return handleSubmit(onSuccess)(evt);
|
|
2433
|
+
return handleSubmit(onSuccess, props.onInvalidSubmit)(evt);
|
|
1949
2434
|
}
|
|
1950
2435
|
function slotProps() {
|
|
1951
2436
|
return {
|
|
@@ -1999,6 +2484,203 @@ const Form = defineComponent({
|
|
|
1999
2484
|
},
|
|
2000
2485
|
});
|
|
2001
2486
|
|
|
2487
|
+
let FIELD_ARRAY_COUNTER = 0;
|
|
2488
|
+
function useFieldArray(arrayPath) {
|
|
2489
|
+
const id = FIELD_ARRAY_COUNTER++;
|
|
2490
|
+
const form = injectWithSelf(FormContextKey, undefined);
|
|
2491
|
+
const fields = ref([]);
|
|
2492
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
2493
|
+
const noOp = () => { };
|
|
2494
|
+
const noOpApi = {
|
|
2495
|
+
fields: readonly(fields),
|
|
2496
|
+
remove: noOp,
|
|
2497
|
+
push: noOp,
|
|
2498
|
+
swap: noOp,
|
|
2499
|
+
insert: noOp,
|
|
2500
|
+
update: noOp,
|
|
2501
|
+
replace: noOp,
|
|
2502
|
+
prepend: noOp,
|
|
2503
|
+
};
|
|
2504
|
+
if (!form) {
|
|
2505
|
+
warn('FieldArray requires being a child of `<Form/>` or `useForm` being called before it. Array fields may not work correctly');
|
|
2506
|
+
return noOpApi;
|
|
2507
|
+
}
|
|
2508
|
+
if (!unref(arrayPath)) {
|
|
2509
|
+
warn('FieldArray requires a field path to be provided, did you forget to pass the `name` prop?');
|
|
2510
|
+
return noOpApi;
|
|
2511
|
+
}
|
|
2512
|
+
let entryCounter = 0;
|
|
2513
|
+
function initFields() {
|
|
2514
|
+
const currentValues = getFromPath(form === null || form === void 0 ? void 0 : form.values, unref(arrayPath), []);
|
|
2515
|
+
fields.value = currentValues.map(createEntry);
|
|
2516
|
+
updateEntryFlags();
|
|
2517
|
+
}
|
|
2518
|
+
initFields();
|
|
2519
|
+
function updateEntryFlags() {
|
|
2520
|
+
const fieldsLength = fields.value.length;
|
|
2521
|
+
for (let i = 0; i < fieldsLength; i++) {
|
|
2522
|
+
const entry = fields.value[i];
|
|
2523
|
+
entry.isFirst = i === 0;
|
|
2524
|
+
entry.isLast = i === fieldsLength - 1;
|
|
2525
|
+
}
|
|
2526
|
+
}
|
|
2527
|
+
function createEntry(value) {
|
|
2528
|
+
const key = entryCounter++;
|
|
2529
|
+
const entry = {
|
|
2530
|
+
key,
|
|
2531
|
+
value: computed(() => {
|
|
2532
|
+
const currentValues = getFromPath(form === null || form === void 0 ? void 0 : form.values, unref(arrayPath), []);
|
|
2533
|
+
const idx = fields.value.findIndex(e => e.key === key);
|
|
2534
|
+
return idx === -1 ? value : currentValues[idx];
|
|
2535
|
+
}),
|
|
2536
|
+
isFirst: false,
|
|
2537
|
+
isLast: false,
|
|
2538
|
+
};
|
|
2539
|
+
return entry;
|
|
2540
|
+
}
|
|
2541
|
+
function remove(idx) {
|
|
2542
|
+
const pathName = unref(arrayPath);
|
|
2543
|
+
const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);
|
|
2544
|
+
if (!pathValue || !Array.isArray(pathValue)) {
|
|
2545
|
+
return;
|
|
2546
|
+
}
|
|
2547
|
+
const newValue = [...pathValue];
|
|
2548
|
+
newValue.splice(idx, 1);
|
|
2549
|
+
form === null || form === void 0 ? void 0 : form.unsetInitialValue(pathName + `[${idx}]`);
|
|
2550
|
+
form === null || form === void 0 ? void 0 : form.setFieldValue(pathName, newValue);
|
|
2551
|
+
fields.value.splice(idx, 1);
|
|
2552
|
+
updateEntryFlags();
|
|
2553
|
+
}
|
|
2554
|
+
function push(value) {
|
|
2555
|
+
const pathName = unref(arrayPath);
|
|
2556
|
+
const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);
|
|
2557
|
+
const normalizedPathValue = isNullOrUndefined(pathValue) ? [] : pathValue;
|
|
2558
|
+
if (!Array.isArray(normalizedPathValue)) {
|
|
2559
|
+
return;
|
|
2560
|
+
}
|
|
2561
|
+
const newValue = [...normalizedPathValue];
|
|
2562
|
+
newValue.push(value);
|
|
2563
|
+
form === null || form === void 0 ? void 0 : form.stageInitialValue(pathName + `[${newValue.length - 1}]`, value);
|
|
2564
|
+
form === null || form === void 0 ? void 0 : form.setFieldValue(pathName, newValue);
|
|
2565
|
+
fields.value.push(createEntry(value));
|
|
2566
|
+
updateEntryFlags();
|
|
2567
|
+
}
|
|
2568
|
+
function swap(indexA, indexB) {
|
|
2569
|
+
const pathName = unref(arrayPath);
|
|
2570
|
+
const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);
|
|
2571
|
+
if (!Array.isArray(pathValue) || !pathValue[indexA] || !pathValue[indexB]) {
|
|
2572
|
+
return;
|
|
2573
|
+
}
|
|
2574
|
+
const newValue = [...pathValue];
|
|
2575
|
+
const newFields = [...fields.value];
|
|
2576
|
+
// the old switcheroo
|
|
2577
|
+
const temp = newValue[indexA];
|
|
2578
|
+
newValue[indexA] = newValue[indexB];
|
|
2579
|
+
newValue[indexB] = temp;
|
|
2580
|
+
const tempEntry = newFields[indexA];
|
|
2581
|
+
newFields[indexA] = newFields[indexB];
|
|
2582
|
+
newFields[indexB] = tempEntry;
|
|
2583
|
+
form === null || form === void 0 ? void 0 : form.setFieldValue(pathName, newValue);
|
|
2584
|
+
fields.value = newFields;
|
|
2585
|
+
updateEntryFlags();
|
|
2586
|
+
}
|
|
2587
|
+
function insert(idx, value) {
|
|
2588
|
+
const pathName = unref(arrayPath);
|
|
2589
|
+
const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);
|
|
2590
|
+
if (!Array.isArray(pathValue) || pathValue.length < idx) {
|
|
2591
|
+
return;
|
|
2592
|
+
}
|
|
2593
|
+
const newValue = [...pathValue];
|
|
2594
|
+
const newFields = [...fields.value];
|
|
2595
|
+
newValue.splice(idx, 0, value);
|
|
2596
|
+
newFields.splice(idx, 0, createEntry(value));
|
|
2597
|
+
form === null || form === void 0 ? void 0 : form.setFieldValue(pathName, newValue);
|
|
2598
|
+
fields.value = newFields;
|
|
2599
|
+
updateEntryFlags();
|
|
2600
|
+
}
|
|
2601
|
+
function replace(arr) {
|
|
2602
|
+
const pathName = unref(arrayPath);
|
|
2603
|
+
form === null || form === void 0 ? void 0 : form.setFieldValue(pathName, arr);
|
|
2604
|
+
initFields();
|
|
2605
|
+
}
|
|
2606
|
+
function update(idx, value) {
|
|
2607
|
+
const pathName = unref(arrayPath);
|
|
2608
|
+
const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);
|
|
2609
|
+
if (!Array.isArray(pathValue) || pathValue.length - 1 < idx) {
|
|
2610
|
+
return;
|
|
2611
|
+
}
|
|
2612
|
+
form === null || form === void 0 ? void 0 : form.setFieldValue(`${pathName}[${idx}]`, value);
|
|
2613
|
+
}
|
|
2614
|
+
function prepend(value) {
|
|
2615
|
+
const pathName = unref(arrayPath);
|
|
2616
|
+
const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);
|
|
2617
|
+
const normalizedPathValue = isNullOrUndefined(pathValue) ? [] : pathValue;
|
|
2618
|
+
if (!Array.isArray(normalizedPathValue)) {
|
|
2619
|
+
return;
|
|
2620
|
+
}
|
|
2621
|
+
const newValue = [value, ...normalizedPathValue];
|
|
2622
|
+
form === null || form === void 0 ? void 0 : form.stageInitialValue(pathName + `[${newValue.length - 1}]`, value);
|
|
2623
|
+
form === null || form === void 0 ? void 0 : form.setFieldValue(pathName, newValue);
|
|
2624
|
+
fields.value.unshift(createEntry(value));
|
|
2625
|
+
updateEntryFlags();
|
|
2626
|
+
}
|
|
2627
|
+
form.fieldArraysLookup[id] = {
|
|
2628
|
+
reset: initFields,
|
|
2629
|
+
};
|
|
2630
|
+
onBeforeUnmount(() => {
|
|
2631
|
+
delete form.fieldArraysLookup[id];
|
|
2632
|
+
});
|
|
2633
|
+
return {
|
|
2634
|
+
fields: readonly(fields),
|
|
2635
|
+
remove,
|
|
2636
|
+
push,
|
|
2637
|
+
swap,
|
|
2638
|
+
insert,
|
|
2639
|
+
update,
|
|
2640
|
+
replace,
|
|
2641
|
+
prepend,
|
|
2642
|
+
};
|
|
2643
|
+
}
|
|
2644
|
+
|
|
2645
|
+
const FieldArray = defineComponent({
|
|
2646
|
+
name: 'FieldArray',
|
|
2647
|
+
inheritAttrs: false,
|
|
2648
|
+
props: {
|
|
2649
|
+
name: {
|
|
2650
|
+
type: String,
|
|
2651
|
+
required: true,
|
|
2652
|
+
},
|
|
2653
|
+
},
|
|
2654
|
+
setup(props, ctx) {
|
|
2655
|
+
const { push, remove, swap, insert, replace, update, prepend, fields } = useFieldArray(toRef(props, 'name'));
|
|
2656
|
+
function slotProps() {
|
|
2657
|
+
return {
|
|
2658
|
+
fields: fields.value,
|
|
2659
|
+
push,
|
|
2660
|
+
remove,
|
|
2661
|
+
swap,
|
|
2662
|
+
insert,
|
|
2663
|
+
update,
|
|
2664
|
+
replace,
|
|
2665
|
+
prepend,
|
|
2666
|
+
};
|
|
2667
|
+
}
|
|
2668
|
+
ctx.expose({
|
|
2669
|
+
push,
|
|
2670
|
+
remove,
|
|
2671
|
+
swap,
|
|
2672
|
+
insert,
|
|
2673
|
+
update,
|
|
2674
|
+
replace,
|
|
2675
|
+
prepend,
|
|
2676
|
+
});
|
|
2677
|
+
return () => {
|
|
2678
|
+
const children = normalizeChildren(undefined, ctx, slotProps);
|
|
2679
|
+
return children;
|
|
2680
|
+
};
|
|
2681
|
+
},
|
|
2682
|
+
});
|
|
2683
|
+
|
|
2002
2684
|
const ErrorMessage = defineComponent({
|
|
2003
2685
|
name: 'ErrorMessage',
|
|
2004
2686
|
props: {
|
|
@@ -2012,9 +2694,9 @@ const ErrorMessage = defineComponent({
|
|
|
2012
2694
|
},
|
|
2013
2695
|
},
|
|
2014
2696
|
setup(props, ctx) {
|
|
2015
|
-
const
|
|
2697
|
+
const form = inject(FormContextKey, undefined);
|
|
2016
2698
|
const message = computed(() => {
|
|
2017
|
-
return
|
|
2699
|
+
return form === null || form === void 0 ? void 0 : form.errors.value[props.name];
|
|
2018
2700
|
});
|
|
2019
2701
|
function slotProps() {
|
|
2020
2702
|
return {
|
|
@@ -2065,7 +2747,7 @@ function useIsFieldDirty(path) {
|
|
|
2065
2747
|
let field = path ? undefined : inject(FieldContextKey);
|
|
2066
2748
|
return computed(() => {
|
|
2067
2749
|
if (path) {
|
|
2068
|
-
field = normalizeField(form === null || form === void 0 ? void 0 : form.
|
|
2750
|
+
field = normalizeField(form === null || form === void 0 ? void 0 : form.fieldsByPath.value[unref(path)]);
|
|
2069
2751
|
}
|
|
2070
2752
|
if (!field) {
|
|
2071
2753
|
warn(`field with name ${unref(path)} was not found`);
|
|
@@ -2083,7 +2765,7 @@ function useIsFieldTouched(path) {
|
|
|
2083
2765
|
let field = path ? undefined : inject(FieldContextKey);
|
|
2084
2766
|
return computed(() => {
|
|
2085
2767
|
if (path) {
|
|
2086
|
-
field = normalizeField(form === null || form === void 0 ? void 0 : form.
|
|
2768
|
+
field = normalizeField(form === null || form === void 0 ? void 0 : form.fieldsByPath.value[unref(path)]);
|
|
2087
2769
|
}
|
|
2088
2770
|
if (!field) {
|
|
2089
2771
|
warn(`field with name ${unref(path)} was not found`);
|
|
@@ -2101,7 +2783,7 @@ function useIsFieldValid(path) {
|
|
|
2101
2783
|
let field = path ? undefined : inject(FieldContextKey);
|
|
2102
2784
|
return computed(() => {
|
|
2103
2785
|
if (path) {
|
|
2104
|
-
field = normalizeField(form === null || form === void 0 ? void 0 : form.
|
|
2786
|
+
field = normalizeField(form === null || form === void 0 ? void 0 : form.fieldsByPath.value[unref(path)]);
|
|
2105
2787
|
}
|
|
2106
2788
|
if (!field) {
|
|
2107
2789
|
warn(`field with name ${unref(path)} was not found`);
|
|
@@ -2133,7 +2815,7 @@ function useValidateField(path) {
|
|
|
2133
2815
|
let field = path ? undefined : inject(FieldContextKey);
|
|
2134
2816
|
return function validateField() {
|
|
2135
2817
|
if (path) {
|
|
2136
|
-
field = normalizeField(form === null || form === void 0 ? void 0 : form.
|
|
2818
|
+
field = normalizeField(form === null || form === void 0 ? void 0 : form.fieldsByPath.value[unref(path)]);
|
|
2137
2819
|
}
|
|
2138
2820
|
if (!field) {
|
|
2139
2821
|
warn(`field with name ${unref(path)} was not found`);
|
|
@@ -2226,11 +2908,10 @@ function useFieldValue(path) {
|
|
|
2226
2908
|
// We don't want to use self injected context as it doesn't make sense
|
|
2227
2909
|
const field = path ? undefined : inject(FieldContextKey);
|
|
2228
2910
|
return computed(() => {
|
|
2229
|
-
var _a;
|
|
2230
2911
|
if (path) {
|
|
2231
2912
|
return getFromPath(form === null || form === void 0 ? void 0 : form.values, unref(path));
|
|
2232
2913
|
}
|
|
2233
|
-
return (
|
|
2914
|
+
return unref(field === null || field === void 0 ? void 0 : field.value);
|
|
2234
2915
|
});
|
|
2235
2916
|
}
|
|
2236
2917
|
|
|
@@ -2251,24 +2932,25 @@ function useFormValues() {
|
|
|
2251
2932
|
* Gives access to all form errors
|
|
2252
2933
|
*/
|
|
2253
2934
|
function useFormErrors() {
|
|
2254
|
-
const
|
|
2255
|
-
if (!
|
|
2935
|
+
const form = injectWithSelf(FormContextKey);
|
|
2936
|
+
if (!form) {
|
|
2256
2937
|
warn('No vee-validate <Form /> or `useForm` was detected in the component tree');
|
|
2257
2938
|
}
|
|
2258
|
-
return
|
|
2939
|
+
return computed(() => {
|
|
2940
|
+
return ((form === null || form === void 0 ? void 0 : form.errors.value) || {});
|
|
2941
|
+
});
|
|
2259
2942
|
}
|
|
2260
2943
|
|
|
2261
2944
|
/**
|
|
2262
2945
|
* Gives access to a single field error
|
|
2263
2946
|
*/
|
|
2264
2947
|
function useFieldError(path) {
|
|
2265
|
-
const
|
|
2948
|
+
const form = injectWithSelf(FormContextKey);
|
|
2266
2949
|
// We don't want to use self injected context as it doesn't make sense
|
|
2267
2950
|
const field = path ? undefined : inject(FieldContextKey);
|
|
2268
2951
|
return computed(() => {
|
|
2269
|
-
var _a;
|
|
2270
2952
|
if (path) {
|
|
2271
|
-
return
|
|
2953
|
+
return form === null || form === void 0 ? void 0 : form.errors.value[unref(path)];
|
|
2272
2954
|
}
|
|
2273
2955
|
return field === null || field === void 0 ? void 0 : field.errorMessage.value;
|
|
2274
2956
|
});
|
|
@@ -2288,4 +2970,4 @@ function useSubmitForm(cb) {
|
|
|
2288
2970
|
};
|
|
2289
2971
|
}
|
|
2290
2972
|
|
|
2291
|
-
export { ErrorMessage, Field, FieldContextKey, Form, FormContextKey, configure, defineRule, useField, useFieldError, useFieldValue, useForm, useFormErrors, useFormValues, useIsFieldDirty, useIsFieldTouched, useIsFieldValid, useIsFormDirty, useIsFormTouched, useIsFormValid, useIsSubmitting, useResetForm, useSubmitCount, useSubmitForm, useValidateField, useValidateForm, validate };
|
|
2973
|
+
export { ErrorMessage, Field, FieldArray, FieldContextKey, Form, FormContextKey, configure, defineRule, useField, useFieldArray, useFieldError, useFieldValue, useForm, useFormErrors, useFormValues, useIsFieldDirty, useIsFieldTouched, useIsFieldValid, useIsFormDirty, useIsFormTouched, useIsFormValid, useIsSubmitting, useResetForm, useSubmitCount, useSubmitForm, useValidateField, useValidateForm, validate };
|