File: //home/arjun/projects/buyercall/node_modules/vee-validate/dist/vee-validate.esm.js
/**
* vee-validate v4.12.3
* (c) 2023 Abdelrahman Awad
* @license MIT
*/
import { getCurrentInstance, inject, warn as warn$1, computed, toValue, ref, watch, nextTick, unref, isRef, reactive, onUnmounted, onMounted, provide, onBeforeUnmount, defineComponent, toRef, resolveDynamicComponent, h, readonly, watchEffect, shallowRef } from 'vue';
import { setupDevtoolsPlugin } from '@vue/devtools-api';
function isCallable(fn) {
return typeof fn === 'function';
}
function isNullOrUndefined(value) {
return value === null || value === undefined;
}
const isObject = (obj) => obj !== null && !!obj && typeof obj === 'object' && !Array.isArray(obj);
function isIndex(value) {
return Number(value) >= 0;
}
function toNumber(value) {
const n = parseFloat(value);
return isNaN(n) ? value : n;
}
function isObjectLike(value) {
return typeof value === 'object' && value !== null;
}
function getTag(value) {
if (value == null) {
return value === undefined ? '[object Undefined]' : '[object Null]';
}
return Object.prototype.toString.call(value);
}
// Reference: https://github.com/lodash/lodash/blob/master/isPlainObject.js
function isPlainObject(value) {
if (!isObjectLike(value) || getTag(value) !== '[object Object]') {
return false;
}
if (Object.getPrototypeOf(value) === null) {
return true;
}
let proto = value;
while (Object.getPrototypeOf(proto) !== null) {
proto = Object.getPrototypeOf(proto);
}
return Object.getPrototypeOf(value) === proto;
}
function merge(target, source) {
Object.keys(source).forEach(key => {
if (isPlainObject(source[key])) {
if (!target[key]) {
target[key] = {};
}
merge(target[key], source[key]);
return;
}
target[key] = source[key];
});
return target;
}
/**
* Constructs a path with dot paths for arrays to use brackets to be compatible with vee-validate path syntax
*/
function normalizeFormPath(path) {
const pathArr = path.split('.');
if (!pathArr.length) {
return '';
}
let fullPath = String(pathArr[0]);
for (let i = 1; i < pathArr.length; i++) {
if (isIndex(pathArr[i])) {
fullPath += `[${pathArr[i]}]`;
continue;
}
fullPath += `.${pathArr[i]}`;
}
return fullPath;
}
const RULES = {};
/**
* Adds a custom validator to the list of validation rules.
*/
function defineRule(id, validator) {
// makes sure new rules are properly formatted.
guardExtend(id, validator);
RULES[id] = validator;
}
/**
* Gets an already defined rule
*/
function resolveRule(id) {
return RULES[id];
}
/**
* Guards from extension violations.
*/
function guardExtend(id, validator) {
if (isCallable(validator)) {
return;
}
throw new Error(`Extension Error: The validator '${id}' must be a function.`);
}
function set(obj, key, val) {
if (typeof val.value === 'object') val.value = klona(val.value);
if (!val.enumerable || val.get || val.set || !val.configurable || !val.writable || key === '__proto__') {
Object.defineProperty(obj, key, val);
} else obj[key] = val.value;
}
function klona(x) {
if (typeof x !== 'object') return x;
var i=0, k, list, tmp, str=Object.prototype.toString.call(x);
if (str === '[object Object]') {
tmp = Object.create(x.__proto__ || null);
} else if (str === '[object Array]') {
tmp = Array(x.length);
} else if (str === '[object Set]') {
tmp = new Set;
x.forEach(function (val) {
tmp.add(klona(val));
});
} else if (str === '[object Map]') {
tmp = new Map;
x.forEach(function (val, key) {
tmp.set(klona(key), klona(val));
});
} else if (str === '[object Date]') {
tmp = new Date(+x);
} else if (str === '[object RegExp]') {
tmp = new RegExp(x.source, x.flags);
} else if (str === '[object DataView]') {
tmp = new x.constructor( klona(x.buffer) );
} else if (str === '[object ArrayBuffer]') {
tmp = x.slice(0);
} else if (str.slice(-6) === 'Array]') {
// ArrayBuffer.isView(x)
// ~> `new` bcuz `Buffer.slice` => ref
tmp = new x.constructor(x);
}
if (tmp) {
for (list=Object.getOwnPropertySymbols(x); i < list.length; i++) {
set(tmp, list[i], Object.getOwnPropertyDescriptor(x, list[i]));
}
for (i=0, list=Object.getOwnPropertyNames(x); i < list.length; i++) {
if (Object.hasOwnProperty.call(tmp, k=list[i]) && tmp[k] === x[k]) continue;
set(tmp, k, Object.getOwnPropertyDescriptor(x, k));
}
}
return tmp || x;
}
const FormContextKey = Symbol('vee-validate-form');
const FieldContextKey = Symbol('vee-validate-field-instance');
const IS_ABSENT = Symbol('Default empty value');
const isClient = typeof window !== 'undefined';
function isLocator(value) {
return isCallable(value) && !!value.__locatorRef;
}
function isTypedSchema(value) {
return !!value && isCallable(value.parse) && value.__type === 'VVTypedSchema';
}
function isYupValidator(value) {
return !!value && isCallable(value.validate);
}
function hasCheckedAttr(type) {
return type === 'checkbox' || type === 'radio';
}
function isContainerValue(value) {
return isObject(value) || Array.isArray(value);
}
/**
* True if the value is an empty object or array
*/
function isEmptyContainer(value) {
if (Array.isArray(value)) {
return value.length === 0;
}
return isObject(value) && Object.keys(value).length === 0;
}
/**
* Checks if the path opted out of nested fields using `[fieldName]` syntax
*/
function isNotNestedPath(path) {
return /^\[.+\]$/i.test(path);
}
/**
* Checks if an element is a native HTML5 multi-select input element
*/
function isNativeMultiSelect(el) {
return isNativeSelect(el) && el.multiple;
}
/**
* Checks if an element is a native HTML5 select input element
*/
function isNativeSelect(el) {
return el.tagName === 'SELECT';
}
/**
* Checks if a tag name with attrs object will render a native multi-select element
*/
function isNativeMultiSelectNode(tag, attrs) {
// The falsy value array is the values that Vue won't add the `multiple` prop if it has one of these values
const hasTruthyBindingValue = ![false, null, undefined, 0].includes(attrs.multiple) && !Number.isNaN(attrs.multiple);
return tag === 'select' && 'multiple' in attrs && hasTruthyBindingValue;
}
/**
* Checks if a node should have a `:value` binding or not
*
* These nodes should not have a value binding
* For files, because they are not reactive
* For multi-selects because the value binding will reset the value
*/
function shouldHaveValueBinding(tag, attrs) {
return !isNativeMultiSelectNode(tag, attrs) && attrs.type !== 'file' && !hasCheckedAttr(attrs.type);
}
function isFormSubmitEvent(evt) {
return isEvent(evt) && evt.target && 'submit' in evt.target;
}
function isEvent(evt) {
if (!evt) {
return false;
}
if (typeof Event !== 'undefined' && isCallable(Event) && evt instanceof Event) {
return true;
}
// this is for IE and Cypress #3161
/* istanbul ignore next */
if (evt && evt.srcElement) {
return true;
}
return false;
}
function isPropPresent(obj, prop) {
return prop in obj && obj[prop] !== IS_ABSENT;
}
/**
* Compares if two values are the same borrowed from:
* https://github.com/epoberezkin/fast-deep-equal
* We added a case for file matching since `Object.keys` doesn't work with Files.
* */
function isEqual(a, b) {
if (a === b)
return true;
if (a && b && typeof a === 'object' && typeof b === 'object') {
if (a.constructor !== b.constructor)
return false;
// eslint-disable-next-line no-var
var length, i, keys;
if (Array.isArray(a)) {
length = a.length;
// eslint-disable-next-line eqeqeq
if (length != b.length)
return false;
for (i = length; i-- !== 0;)
if (!isEqual(a[i], b[i]))
return false;
return true;
}
if (a instanceof Map && b instanceof Map) {
if (a.size !== b.size)
return false;
for (i of a.entries())
if (!b.has(i[0]))
return false;
for (i of a.entries())
if (!isEqual(i[1], b.get(i[0])))
return false;
return true;
}
// We added this part for file comparison, arguably a little naive but should work for most cases.
// #3911
if (isFile(a) && isFile(b)) {
if (a.size !== b.size)
return false;
if (a.name !== b.name)
return false;
if (a.lastModified !== b.lastModified)
return false;
if (a.type !== b.type)
return false;
return true;
}
if (a instanceof Set && b instanceof Set) {
if (a.size !== b.size)
return false;
for (i of a.entries())
if (!b.has(i[0]))
return false;
return true;
}
if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {
length = a.length;
// eslint-disable-next-line eqeqeq
if (length != b.length)
return false;
for (i = length; i-- !== 0;)
if (a[i] !== b[i])
return false;
return true;
}
if (a.constructor === RegExp)
return a.source === b.source && a.flags === b.flags;
if (a.valueOf !== Object.prototype.valueOf)
return a.valueOf() === b.valueOf();
if (a.toString !== Object.prototype.toString)
return a.toString() === b.toString();
keys = Object.keys(a);
length = keys.length;
for (i = length; i-- !== 0;) {
// eslint-disable-next-line no-var
var key = keys[i];
if (!isEqual(a[key], b[key]))
return false;
}
return true;
}
// true if both NaN, false otherwise
// eslint-disable-next-line no-self-compare
return a !== a && b !== b;
}
function isFile(a) {
if (!isClient) {
return false;
}
return a instanceof File;
}
function cleanupNonNestedPath(path) {
if (isNotNestedPath(path)) {
return path.replace(/\[|\]/gi, '');
}
return path;
}
function getFromPath(object, path, fallback) {
if (!object) {
return fallback;
}
if (isNotNestedPath(path)) {
return object[cleanupNonNestedPath(path)];
}
const resolvedValue = (path || '')
.split(/\.|\[(\d+)\]/)
.filter(Boolean)
.reduce((acc, propKey) => {
if (isContainerValue(acc) && propKey in acc) {
return acc[propKey];
}
return fallback;
}, object);
return resolvedValue;
}
/**
* Sets a nested property value in a path, creates the path properties if it doesn't exist
*/
function setInPath(object, path, value) {
if (isNotNestedPath(path)) {
object[cleanupNonNestedPath(path)] = value;
return;
}
const keys = path.split(/\.|\[(\d+)\]/).filter(Boolean);
let acc = object;
for (let i = 0; i < keys.length; i++) {
// Last key, set it
if (i === keys.length - 1) {
acc[keys[i]] = value;
return;
}
// Key does not exist, create a container for it
if (!(keys[i] in acc) || isNullOrUndefined(acc[keys[i]])) {
// container can be either an object or an array depending on the next key if it exists
acc[keys[i]] = isIndex(keys[i + 1]) ? [] : {};
}
acc = acc[keys[i]];
}
}
function unset(object, key) {
if (Array.isArray(object) && isIndex(key)) {
object.splice(Number(key), 1);
return;
}
if (isObject(object)) {
delete object[key];
}
}
/**
* Removes a nested property from object
*/
function unsetPath(object, path) {
if (isNotNestedPath(path)) {
delete object[cleanupNonNestedPath(path)];
return;
}
const keys = path.split(/\.|\[(\d+)\]/).filter(Boolean);
let acc = object;
for (let i = 0; i < keys.length; i++) {
// Last key, unset it
if (i === keys.length - 1) {
unset(acc, keys[i]);
break;
}
// Key does not exist, exit
if (!(keys[i] in acc) || isNullOrUndefined(acc[keys[i]])) {
break;
}
acc = acc[keys[i]];
}
const pathValues = keys.map((_, idx) => {
return getFromPath(object, keys.slice(0, idx).join('.'));
});
for (let i = pathValues.length - 1; i >= 0; i--) {
if (!isEmptyContainer(pathValues[i])) {
continue;
}
if (i === 0) {
unset(object, keys[0]);
continue;
}
unset(pathValues[i - 1], keys[i - 1]);
}
}
/**
* A typed version of Object.keys
*/
function keysOf(record) {
return Object.keys(record);
}
// Uses same component provide as its own injections
// Due to changes in https://github.com/vuejs/vue-next/pull/2424
function injectWithSelf(symbol, def = undefined) {
const vm = getCurrentInstance();
return (vm === null || vm === void 0 ? void 0 : vm.provides[symbol]) || inject(symbol, def);
}
function warn(message) {
warn$1(`[vee-validate]: ${message}`);
}
function resolveNextCheckboxValue(currentValue, checkedValue, uncheckedValue) {
if (Array.isArray(currentValue)) {
const newVal = [...currentValue];
// Use isEqual since checked object values can possibly fail the equality check #3883
const idx = newVal.findIndex(v => isEqual(v, checkedValue));
idx >= 0 ? newVal.splice(idx, 1) : newVal.push(checkedValue);
return newVal;
}
return isEqual(currentValue, checkedValue) ? uncheckedValue : checkedValue;
}
/**
* Creates a throttled function that only invokes the provided function (`func`) at most once per within a given number of milliseconds
* (`limit`)
*/
function throttle(func, limit) {
let inThrottle;
let lastResult;
return function (...args) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const context = this;
if (!inThrottle) {
inThrottle = true;
setTimeout(() => (inThrottle = false), limit);
lastResult = func.apply(context, args);
}
return lastResult;
};
}
function debounceAsync(inner, ms = 0) {
let timer = null;
let resolves = [];
return function (...args) {
// Run the function after a certain amount of time
if (timer) {
clearTimeout(timer);
}
// @ts-expect-error timer is a number
timer = setTimeout(() => {
// Get the result of the inner function, then apply it to the resolve function of
// each promise that has been created since the last time the inner function was run
const result = inner(...args);
resolves.forEach(r => r(result));
resolves = [];
}, ms);
return new Promise(resolve => resolves.push(resolve));
};
}
function applyModelModifiers(value, modifiers) {
if (!isObject(modifiers)) {
return value;
}
if (modifiers.number) {
return toNumber(value);
}
return value;
}
function withLatest(fn, onDone) {
let latestRun;
return async function runLatest(...args) {
const pending = fn(...args);
latestRun = pending;
const result = await pending;
if (pending !== latestRun) {
return result;
}
latestRun = undefined;
return onDone(result, args);
};
}
function computedDeep({ get, set }) {
const baseRef = ref(klona(get()));
watch(get, newValue => {
if (isEqual(newValue, baseRef.value)) {
return;
}
baseRef.value = klona(newValue);
}, {
deep: true,
});
watch(baseRef, newValue => {
if (isEqual(newValue, get())) {
return;
}
set(klona(newValue));
}, {
deep: true,
});
return baseRef;
}
function normalizeErrorItem(message) {
return Array.isArray(message) ? message : message ? [message] : [];
}
function resolveFieldOrPathState(path) {
const form = injectWithSelf(FormContextKey);
const state = path ? computed(() => form === null || form === void 0 ? void 0 : form.getPathState(toValue(path))) : undefined;
const field = path ? undefined : inject(FieldContextKey);
if (!field && !(state === null || state === void 0 ? void 0 : state.value)) {
if ((process.env.NODE_ENV !== 'production')) {
warn(`field with name ${toValue(path)} was not found`);
}
}
return state || field;
}
function omit(obj, keys) {
const target = {};
for (const key in obj) {
if (!keys.includes(key)) {
target[key] = obj[key];
}
}
return target;
}
function debounceNextTick(inner) {
let lastTick = null;
let resolves = [];
return function (...args) {
// Run the function after a certain amount of time
const thisTick = nextTick(() => {
if (lastTick !== thisTick) {
return;
}
// Get the result of the inner function, then apply it to the resolve function of
// each promise that has been created since the last time the inner function was run
const result = inner(...args);
resolves.forEach(r => r(result));
resolves = [];
lastTick = null;
});
lastTick = thisTick;
return new Promise(resolve => resolves.push(resolve));
};
}
function normalizeChildren(tag, context, slotProps) {
if (!context.slots.default) {
return context.slots.default;
}
if (typeof tag === 'string' || !tag) {
return context.slots.default(slotProps());
}
return {
default: () => { var _a, _b; return (_b = (_a = context.slots).default) === null || _b === void 0 ? void 0 : _b.call(_a, slotProps()); },
};
}
/**
* Vue adds a `_value` prop at the moment on the input elements to store the REAL value on them, real values are different than the `value` attribute
* as they do not get casted to strings unlike `el.value` which preserves user-code behavior
*/
function getBoundValue(el) {
if (hasValueBinding(el)) {
return el._value;
}
return undefined;
}
/**
* Vue adds a `_value` prop at the moment on the input elements to store the REAL value on them, real values are different than the `value` attribute
* as they do not get casted to strings unlike `el.value` which preserves user-code behavior
*/
function hasValueBinding(el) {
return '_value' in el;
}
function parseInputValue(el) {
if (el.type === 'number') {
return Number.isNaN(el.valueAsNumber) ? el.value : el.valueAsNumber;
}
if (el.type === 'range') {
return Number.isNaN(el.valueAsNumber) ? el.value : el.valueAsNumber;
}
return el.value;
}
function normalizeEventValue(value) {
if (!isEvent(value)) {
return value;
}
const input = value.target;
// Vue sets the current bound value on `_value` prop
// for checkboxes it it should fetch the value binding type as is (boolean instead of string)
if (hasCheckedAttr(input.type) && hasValueBinding(input)) {
return getBoundValue(input);
}
if (input.type === 'file' && input.files) {
const files = Array.from(input.files);
return input.multiple ? files : files[0];
}
if (isNativeMultiSelect(input)) {
return Array.from(input.options)
.filter(opt => opt.selected && !opt.disabled)
.map(getBoundValue);
}
// makes sure we get the actual `option` bound value
// #3440
if (isNativeSelect(input)) {
const selectedOption = Array.from(input.options).find(opt => opt.selected);
return selectedOption ? getBoundValue(selectedOption) : input.value;
}
return parseInputValue(input);
}
/**
* Normalizes the given rules expression.
*/
function normalizeRules(rules) {
const acc = {};
Object.defineProperty(acc, '_$$isNormalized', {
value: true,
writable: false,
enumerable: false,
configurable: false,
});
if (!rules) {
return acc;
}
// Object is already normalized, skip.
if (isObject(rules) && rules._$$isNormalized) {
return rules;
}
if (isObject(rules)) {
return Object.keys(rules).reduce((prev, curr) => {
const params = normalizeParams(rules[curr]);
if (rules[curr] !== false) {
prev[curr] = buildParams(params);
}
return prev;
}, acc);
}
/* istanbul ignore if */
if (typeof rules !== 'string') {
return acc;
}
return rules.split('|').reduce((prev, rule) => {
const parsedRule = parseRule(rule);
if (!parsedRule.name) {
return prev;
}
prev[parsedRule.name] = buildParams(parsedRule.params);
return prev;
}, acc);
}
/**
* Normalizes a rule param.
*/
function normalizeParams(params) {
if (params === true) {
return [];
}
if (Array.isArray(params)) {
return params;
}
if (isObject(params)) {
return params;
}
return [params];
}
function buildParams(provided) {
const mapValueToLocator = (value) => {
// A target param using interpolation
if (typeof value === 'string' && value[0] === '@') {
return createLocator(value.slice(1));
}
return value;
};
if (Array.isArray(provided)) {
return provided.map(mapValueToLocator);
}
// #3073
if (provided instanceof RegExp) {
return [provided];
}
return Object.keys(provided).reduce((prev, key) => {
prev[key] = mapValueToLocator(provided[key]);
return prev;
}, {});
}
/**
* Parses a rule string expression.
*/
const parseRule = (rule) => {
let params = [];
const name = rule.split(':')[0];
if (rule.includes(':')) {
params = rule.split(':').slice(1).join(':').split(',');
}
return { name, params };
};
function createLocator(value) {
const locator = (crossTable) => {
const val = getFromPath(crossTable, value) || crossTable[value];
return val;
};
locator.__locatorRef = value;
return locator;
}
function extractLocators(params) {
if (Array.isArray(params)) {
return params.filter(isLocator);
}
return keysOf(params)
.filter(key => isLocator(params[key]))
.map(key => params[key]);
}
const DEFAULT_CONFIG = {
generateMessage: ({ field }) => `${field} is not valid.`,
bails: true,
validateOnBlur: true,
validateOnChange: true,
validateOnInput: false,
validateOnModelUpdate: true,
};
let currentConfig = Object.assign({}, DEFAULT_CONFIG);
const getConfig = () => currentConfig;
const setConfig = (newConf) => {
currentConfig = Object.assign(Object.assign({}, currentConfig), newConf);
};
const configure = setConfig;
/**
* Validates a value against the rules.
*/
async function validate(value, rules, options = {}) {
const shouldBail = options === null || options === void 0 ? void 0 : options.bails;
const field = {
name: (options === null || options === void 0 ? void 0 : options.name) || '{field}',
rules,
label: options === null || options === void 0 ? void 0 : options.label,
bails: shouldBail !== null && shouldBail !== void 0 ? shouldBail : true,
formData: (options === null || options === void 0 ? void 0 : options.values) || {},
};
const result = await _validate(field, value);
const errors = result.errors;
return {
errors,
valid: !errors.length,
};
}
/**
* Starts the validation process.
*/
async function _validate(field, value) {
if (isTypedSchema(field.rules) || isYupValidator(field.rules)) {
return validateFieldWithTypedSchema(value, field.rules);
}
// if a generic function or chain of generic functions
if (isCallable(field.rules) || Array.isArray(field.rules)) {
const ctx = {
field: field.label || field.name,
name: field.name,
label: field.label,
form: field.formData,
value,
};
// Normalize the pipeline
const pipeline = Array.isArray(field.rules) ? field.rules : [field.rules];
const length = pipeline.length;
const errors = [];
for (let i = 0; i < length; i++) {
const rule = pipeline[i];
const result = await rule(value, ctx);
const isValid = typeof result !== 'string' && !Array.isArray(result) && result;
if (isValid) {
continue;
}
if (Array.isArray(result)) {
errors.push(...result);
}
else {
const message = typeof result === 'string' ? result : _generateFieldError(ctx);
errors.push(message);
}
if (field.bails) {
return {
errors,
};
}
}
return {
errors,
};
}
const normalizedContext = Object.assign(Object.assign({}, field), { rules: normalizeRules(field.rules) });
const errors = [];
const rulesKeys = Object.keys(normalizedContext.rules);
const length = rulesKeys.length;
for (let i = 0; i < length; i++) {
const rule = rulesKeys[i];
const result = await _test(normalizedContext, value, {
name: rule,
params: normalizedContext.rules[rule],
});
if (result.error) {
errors.push(result.error);
if (field.bails) {
return {
errors,
};
}
}
}
return {
errors,
};
}
function isYupError(err) {
return !!err && err.name === 'ValidationError';
}
function yupToTypedSchema(yupSchema) {
const schema = {
__type: 'VVTypedSchema',
async parse(values) {
var _a;
try {
const output = await yupSchema.validate(values, { abortEarly: false });
return {
output,
errors: [],
};
}
catch (err) {
// Yup errors have a name prop one them.
// https://github.com/jquense/yup#validationerrorerrors-string--arraystring-value-any-path-string
if (!isYupError(err)) {
throw err;
}
if (!((_a = err.inner) === null || _a === void 0 ? void 0 : _a.length) && err.errors.length) {
return { errors: [{ path: err.path, errors: err.errors }] };
}
const errors = err.inner.reduce((acc, curr) => {
const path = curr.path || '';
if (!acc[path]) {
acc[path] = { errors: [], path };
}
acc[path].errors.push(...curr.errors);
return acc;
}, {});
return { errors: Object.values(errors) };
}
},
};
return schema;
}
/**
* Handles yup validation
*/
async function validateFieldWithTypedSchema(value, schema) {
const typedSchema = isTypedSchema(schema) ? schema : yupToTypedSchema(schema);
const result = await typedSchema.parse(value);
const messages = [];
for (const error of result.errors) {
if (error.errors.length) {
messages.push(...error.errors);
}
}
return {
errors: messages,
};
}
/**
* Tests a single input value against a rule.
*/
async function _test(field, value, rule) {
const validator = resolveRule(rule.name);
if (!validator) {
throw new Error(`No such validator '${rule.name}' exists.`);
}
const params = fillTargetValues(rule.params, field.formData);
const ctx = {
field: field.label || field.name,
name: field.name,
label: field.label,
value,
form: field.formData,
rule: Object.assign(Object.assign({}, rule), { params }),
};
const result = await validator(value, params, ctx);
if (typeof result === 'string') {
return {
error: result,
};
}
return {
error: result ? undefined : _generateFieldError(ctx),
};
}
/**
* Generates error messages.
*/
function _generateFieldError(fieldCtx) {
const message = getConfig().generateMessage;
if (!message) {
return 'Field is invalid';
}
return message(fieldCtx);
}
function fillTargetValues(params, crossTable) {
const normalize = (value) => {
if (isLocator(value)) {
return value(crossTable);
}
return value;
};
if (Array.isArray(params)) {
return params.map(normalize);
}
return Object.keys(params).reduce((acc, param) => {
acc[param] = normalize(params[param]);
return acc;
}, {});
}
async function validateTypedSchema(schema, values) {
const typedSchema = isTypedSchema(schema) ? schema : yupToTypedSchema(schema);
const validationResult = await typedSchema.parse(klona(values));
const results = {};
const errors = {};
for (const error of validationResult.errors) {
const messages = error.errors;
// Fixes issue with path mapping with Yup 1.0 including quotes around array indices
const path = (error.path || '').replace(/\["(\d+)"\]/g, (_, m) => {
return `[${m}]`;
});
results[path] = { valid: !messages.length, errors: messages };
if (messages.length) {
errors[path] = messages[0];
}
}
return {
valid: !validationResult.errors.length,
results,
errors,
values: validationResult.value,
};
}
async function validateObjectSchema(schema, values, opts) {
const paths = keysOf(schema);
const validations = paths.map(async (path) => {
var _a, _b, _c;
const strings = (_a = opts === null || opts === void 0 ? void 0 : opts.names) === null || _a === void 0 ? void 0 : _a[path];
const fieldResult = await validate(getFromPath(values, path), schema[path], {
name: (strings === null || strings === void 0 ? void 0 : strings.name) || path,
label: strings === null || strings === void 0 ? void 0 : strings.label,
values: values,
bails: (_c = (_b = opts === null || opts === void 0 ? void 0 : opts.bailsMap) === null || _b === void 0 ? void 0 : _b[path]) !== null && _c !== void 0 ? _c : true,
});
return Object.assign(Object.assign({}, fieldResult), { path });
});
let isAllValid = true;
const validationResults = await Promise.all(validations);
const results = {};
const errors = {};
for (const result of validationResults) {
results[result.path] = {
valid: result.valid,
errors: result.errors,
};
if (!result.valid) {
isAllValid = false;
errors[result.path] = result.errors[0];
}
}
return {
valid: isAllValid,
results,
errors,
};
}
let ID_COUNTER = 0;
function useFieldState(path, init) {
const { value, initialValue, setInitialValue } = _useFieldValue(path, init.modelValue, init.form);
if (!init.form) {
const { errors, setErrors } = createFieldErrors();
const id = ID_COUNTER >= Number.MAX_SAFE_INTEGER ? 0 : ++ID_COUNTER;
const meta = createFieldMeta(value, initialValue, errors, init.schema);
function setState(state) {
var _a;
if ('value' in state) {
value.value = state.value;
}
if ('errors' in state) {
setErrors(state.errors);
}
if ('touched' in state) {
meta.touched = (_a = state.touched) !== null && _a !== void 0 ? _a : meta.touched;
}
if ('initialValue' in state) {
setInitialValue(state.initialValue);
}
}
return {
id,
path,
value,
initialValue,
meta,
flags: { pendingUnmount: { [id]: false }, pendingReset: false },
errors,
setState,
};
}
const state = init.form.createPathState(path, {
bails: init.bails,
label: init.label,
type: init.type,
validate: init.validate,
schema: init.schema,
});
const errors = computed(() => state.errors);
function setState(state) {
var _a, _b, _c;
if ('value' in state) {
value.value = state.value;
}
if ('errors' in state) {
(_a = init.form) === null || _a === void 0 ? void 0 : _a.setFieldError(unref(path), state.errors);
}
if ('touched' in state) {
(_b = init.form) === null || _b === void 0 ? void 0 : _b.setFieldTouched(unref(path), (_c = state.touched) !== null && _c !== void 0 ? _c : false);
}
if ('initialValue' in state) {
setInitialValue(state.initialValue);
}
}
return {
id: Array.isArray(state.id) ? state.id[state.id.length - 1] : state.id,
path,
value,
errors,
meta: state,
initialValue,
flags: state.__flags,
setState,
};
}
/**
* Creates the field value and resolves the initial value
*/
function _useFieldValue(path, modelValue, form) {
const modelRef = ref(unref(modelValue));
function resolveInitialValue() {
if (!form) {
return unref(modelRef);
}
return getFromPath(form.initialValues.value, unref(path), unref(modelRef));
}
function setInitialValue(value) {
if (!form) {
modelRef.value = value;
return;
}
form.setFieldInitialValue(unref(path), value, true);
}
const initialValue = computed(resolveInitialValue);
// if no form is associated, use a regular ref.
if (!form) {
const value = ref(resolveInitialValue());
return {
value,
initialValue,
setInitialValue,
};
}
// to set the initial value, first check if there is a current value, if there is then use it.
// otherwise use the configured initial value if it exists.
// prioritize model value over form values
// #3429
const currentValue = resolveModelValue(modelValue, form, initialValue, path);
form.stageInitialValue(unref(path), currentValue, true);
// otherwise use a computed setter that triggers the `setFieldValue`
const value = computed({
get() {
return getFromPath(form.values, unref(path));
},
set(newVal) {
form.setFieldValue(unref(path), newVal, false);
},
});
return {
value,
initialValue,
setInitialValue,
};
}
/*
to set the initial value, first check if there is a current value, if there is then use it.
otherwise use the configured initial value if it exists.
prioritize model value over form values
#3429
*/
function resolveModelValue(modelValue, form, initialValue, path) {
if (isRef(modelValue)) {
return unref(modelValue);
}
if (modelValue !== undefined) {
return modelValue;
}
return getFromPath(form.values, unref(path), unref(initialValue));
}
/**
* Creates meta flags state and some associated effects with them
*/
function createFieldMeta(currentValue, initialValue, errors, schema) {
var _a, _b;
const isRequired = (_b = (_a = schema === null || schema === void 0 ? void 0 : schema.describe) === null || _a === void 0 ? void 0 : _a.call(schema).required) !== null && _b !== void 0 ? _b : false;
const meta = reactive({
touched: false,
pending: false,
valid: true,
required: isRequired,
validated: !!unref(errors).length,
initialValue: computed(() => unref(initialValue)),
dirty: computed(() => {
return !isEqual(unref(currentValue), unref(initialValue));
}),
});
watch(errors, value => {
meta.valid = !value.length;
}, {
immediate: true,
flush: 'sync',
});
return meta;
}
/**
* Creates the error message state for the field state
*/
function createFieldErrors() {
const errors = ref([]);
return {
errors,
setErrors: (messages) => {
errors.value = normalizeErrorItem(messages);
},
};
}
function installDevtoolsPlugin(app) {
if ((process.env.NODE_ENV !== 'production')) {
setupDevtoolsPlugin({
id: 'vee-validate-devtools-plugin',
label: 'VeeValidate Plugin',
packageName: 'vee-validate',
homepage: 'https://vee-validate.logaretm.com/v4',
app,
logo: 'https://vee-validate.logaretm.com/v4/logo.png',
}, setupApiHooks);
}
}
const DEVTOOLS_FORMS = {};
const DEVTOOLS_FIELDS = {};
let API;
const refreshInspector = throttle(() => {
setTimeout(async () => {
await nextTick();
API === null || API === void 0 ? void 0 : API.sendInspectorState(INSPECTOR_ID);
API === null || API === void 0 ? void 0 : API.sendInspectorTree(INSPECTOR_ID);
}, 100);
}, 100);
function registerFormWithDevTools(form) {
const vm = getCurrentInstance();
if (!API) {
const app = vm === null || vm === void 0 ? void 0 : vm.appContext.app;
if (!app) {
return;
}
installDevtoolsPlugin(app);
}
DEVTOOLS_FORMS[form.formId] = Object.assign({}, form);
DEVTOOLS_FORMS[form.formId]._vm = vm;
onUnmounted(() => {
delete DEVTOOLS_FORMS[form.formId];
refreshInspector();
});
refreshInspector();
}
function registerSingleFieldWithDevtools(field) {
const vm = getCurrentInstance();
if (!API) {
const app = vm === null || vm === void 0 ? void 0 : vm.appContext.app;
if (!app) {
return;
}
installDevtoolsPlugin(app);
}
DEVTOOLS_FIELDS[field.id] = Object.assign({}, field);
DEVTOOLS_FIELDS[field.id]._vm = vm;
onUnmounted(() => {
delete DEVTOOLS_FIELDS[field.id];
refreshInspector();
});
refreshInspector();
}
const INSPECTOR_ID = 'vee-validate-inspector';
const COLORS = {
error: 0xbd4b4b,
success: 0x06d77b,
unknown: 0x54436b,
white: 0xffffff,
black: 0x000000,
blue: 0x035397,
purple: 0xb980f0,
orange: 0xf5a962,
gray: 0xbbbfca,
};
let SELECTED_NODE = null;
function setupApiHooks(api) {
API = api;
api.addInspector({
id: INSPECTOR_ID,
icon: 'rule',
label: 'vee-validate',
noSelectionText: 'Select a vee-validate node to inspect',
actions: [
{
icon: 'done_outline',
tooltip: 'Validate selected item',
action: async () => {
if (!SELECTED_NODE) {
console.error('There is not a valid selected vee-validate node or component');
return;
}
if (SELECTED_NODE.type === 'field') {
await SELECTED_NODE.field.validate();
return;
}
if (SELECTED_NODE.type === 'form') {
await SELECTED_NODE.form.validate();
return;
}
if (SELECTED_NODE.type === 'pathState') {
await SELECTED_NODE.form.validateField(SELECTED_NODE.state.path);
}
},
},
{
icon: 'delete_sweep',
tooltip: 'Clear validation state of the selected item',
action: () => {
if (!SELECTED_NODE) {
console.error('There is not a valid selected vee-validate node or component');
return;
}
if (SELECTED_NODE.type === 'field') {
SELECTED_NODE.field.resetField();
return;
}
if (SELECTED_NODE.type === 'form') {
SELECTED_NODE.form.resetForm();
}
if (SELECTED_NODE.type === 'pathState') {
SELECTED_NODE.form.resetField(SELECTED_NODE.state.path);
}
},
},
],
});
api.on.getInspectorTree(payload => {
if (payload.inspectorId !== INSPECTOR_ID) {
return;
}
const forms = Object.values(DEVTOOLS_FORMS);
const fields = Object.values(DEVTOOLS_FIELDS);
payload.rootNodes = [
...forms.map(mapFormForDevtoolsInspector),
...fields.map(field => mapFieldForDevtoolsInspector(field)),
];
});
api.on.getInspectorState((payload, ctx) => {
if (payload.inspectorId !== INSPECTOR_ID || ctx.currentTab !== `custom-inspector:${INSPECTOR_ID}`) {
return;
}
const { form, field, state, type } = decodeNodeId(payload.nodeId);
if (form && type === 'form') {
payload.state = buildFormState(form);
SELECTED_NODE = { type: 'form', form };
return;
}
if (state && type === 'pathState' && form) {
payload.state = buildFieldState(state);
SELECTED_NODE = { type: 'pathState', state, form };
return;
}
if (field && type === 'field') {
payload.state = buildFieldState({
errors: field.errors.value,
dirty: field.meta.dirty,
valid: field.meta.valid,
touched: field.meta.touched,
value: field.value.value,
initialValue: field.meta.initialValue,
});
SELECTED_NODE = { field, type: 'field' };
return;
}
SELECTED_NODE = null;
});
}
function mapFormForDevtoolsInspector(form) {
const { textColor, bgColor } = getValidityColors(form.meta.value.valid);
const formTreeNodes = {};
Object.values(form.getAllPathStates()).forEach(state => {
setInPath(formTreeNodes, unref(state.path), mapPathForDevtoolsInspector(state, form));
});
function buildFormTree(tree, path = []) {
const key = [...path].pop();
if ('id' in tree) {
return Object.assign(Object.assign({}, tree), { label: key || tree.label });
}
if (isObject(tree)) {
return {
id: `${path.join('.')}`,
label: key || '',
children: Object.keys(tree).map(key => buildFormTree(tree[key], [...path, key])),
};
}
if (Array.isArray(tree)) {
return {
id: `${path.join('.')}`,
label: `${key}[]`,
children: tree.map((c, idx) => buildFormTree(c, [...path, String(idx)])),
};
}
return { id: '', label: '', children: [] };
}
const { children } = buildFormTree(formTreeNodes);
return {
id: encodeNodeId(form),
label: 'Form',
children,
tags: [
{
label: 'Form',
textColor,
backgroundColor: bgColor,
},
{
label: `${form.getAllPathStates().length} fields`,
textColor: COLORS.white,
backgroundColor: COLORS.unknown,
},
],
};
}
function mapPathForDevtoolsInspector(state, form) {
return {
id: encodeNodeId(form, state),
label: unref(state.path),
tags: getFieldNodeTags(state.multiple, state.fieldsCount, state.type, state.valid, form),
};
}
function mapFieldForDevtoolsInspector(field, form) {
return {
id: encodeNodeId(form, field),
label: unref(field.name),
tags: getFieldNodeTags(false, 1, field.type, field.meta.valid, form),
};
}
function getFieldNodeTags(multiple, fieldsCount, type, valid, form) {
const { textColor, bgColor } = getValidityColors(valid);
return [
multiple
? undefined
: {
label: 'Field',
textColor,
backgroundColor: bgColor,
},
!form
? {
label: 'Standalone',
textColor: COLORS.black,
backgroundColor: COLORS.gray,
}
: undefined,
type === 'checkbox'
? {
label: 'Checkbox',
textColor: COLORS.white,
backgroundColor: COLORS.blue,
}
: undefined,
type === 'radio'
? {
label: 'Radio',
textColor: COLORS.white,
backgroundColor: COLORS.purple,
}
: undefined,
multiple
? {
label: 'Multiple',
textColor: COLORS.black,
backgroundColor: COLORS.orange,
}
: undefined,
].filter(Boolean);
}
function encodeNodeId(form, stateOrField) {
const type = stateOrField ? ('path' in stateOrField ? 'pathState' : 'field') : 'form';
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)) : '';
const idObject = { f: form === null || form === void 0 ? void 0 : form.formId, ff: fieldPath, type };
return btoa(encodeURIComponent(JSON.stringify(idObject)));
}
function decodeNodeId(nodeId) {
try {
const idObject = JSON.parse(decodeURIComponent(atob(nodeId)));
const form = DEVTOOLS_FORMS[idObject.f];
if (!form && idObject.ff) {
const field = DEVTOOLS_FIELDS[idObject.ff];
if (!field) {
return {};
}
return {
type: idObject.type,
field,
};
}
if (!form) {
return {};
}
const state = form.getPathState(idObject.ff);
return {
type: idObject.type,
form,
state,
};
}
catch (err) {
// console.error(`Devtools: [vee-validate] Failed to parse node id ${nodeId}`);
}
return {};
}
function buildFieldState(state) {
return {
'Field state': [
{ key: 'errors', value: state.errors },
{
key: 'initialValue',
value: state.initialValue,
},
{
key: 'currentValue',
value: state.value,
},
{
key: 'touched',
value: state.touched,
},
{
key: 'dirty',
value: state.dirty,
},
{
key: 'valid',
value: state.valid,
},
],
};
}
function buildFormState(form) {
const { errorBag, meta, values, isSubmitting, isValidating, submitCount } = form;
return {
'Form state': [
{
key: 'submitCount',
value: submitCount.value,
},
{
key: 'isSubmitting',
value: isSubmitting.value,
},
{
key: 'isValidating',
value: isValidating.value,
},
{
key: 'touched',
value: meta.value.touched,
},
{
key: 'dirty',
value: meta.value.dirty,
},
{
key: 'valid',
value: meta.value.valid,
},
{
key: 'initialValues',
value: meta.value.initialValues,
},
{
key: 'currentValues',
value: values,
},
{
key: 'errors',
value: keysOf(errorBag.value).reduce((acc, key) => {
var _a;
const message = (_a = errorBag.value[key]) === null || _a === void 0 ? void 0 : _a[0];
if (message) {
acc[key] = message;
}
return acc;
}, {}),
},
],
};
}
/**
* Resolves the tag color based on the form state
*/
function getValidityColors(valid) {
return {
bgColor: valid ? COLORS.success : COLORS.error,
textColor: valid ? COLORS.black : COLORS.white,
};
}
/**
* Creates a field composite.
*/
function useField(path, rules, opts) {
if (hasCheckedAttr(opts === null || opts === void 0 ? void 0 : opts.type)) {
return useFieldWithChecked(path, rules, opts);
}
return _useField(path, rules, opts);
}
function _useField(path, rules, opts) {
const { initialValue: modelValue, validateOnMount, bails, type, checkedValue, label, validateOnValueUpdate, uncheckedValue, controlled, keepValueOnUnmount, syncVModel, form: controlForm, } = normalizeOptions(opts);
const injectedForm = controlled ? injectWithSelf(FormContextKey) : undefined;
const form = controlForm || injectedForm;
const name = computed(() => normalizeFormPath(toValue(path)));
const validator = computed(() => {
const schema = toValue(form === null || form === void 0 ? void 0 : form.schema);
if (schema) {
return undefined;
}
const rulesValue = unref(rules);
if (isYupValidator(rulesValue) ||
isTypedSchema(rulesValue) ||
isCallable(rulesValue) ||
Array.isArray(rulesValue)) {
return rulesValue;
}
return normalizeRules(rulesValue);
});
const { id, value, initialValue, meta, setState, errors, flags } = useFieldState(name, {
modelValue,
form,
bails,
label,
type,
validate: validator.value ? validate$1 : undefined,
schema: isTypedSchema(rules) ? rules : undefined,
});
const errorMessage = computed(() => errors.value[0]);
if (syncVModel) {
useVModel({
value,
prop: syncVModel,
handleChange,
shouldValidate: () => validateOnValueUpdate && !flags.pendingReset,
});
}
/**
* Handles common onBlur meta update
*/
const handleBlur = (evt, shouldValidate = false) => {
meta.touched = true;
if (shouldValidate) {
validateWithStateMutation();
}
};
async function validateCurrentValue(mode) {
var _a, _b;
if (form === null || form === void 0 ? void 0 : form.validateSchema) {
const { results } = await form.validateSchema(mode);
return (_a = results[toValue(name)]) !== null && _a !== void 0 ? _a : { valid: true, errors: [] };
}
if (validator.value) {
return validate(value.value, validator.value, {
name: toValue(name),
label: toValue(label),
values: (_b = form === null || form === void 0 ? void 0 : form.values) !== null && _b !== void 0 ? _b : {},
bails,
});
}
return { valid: true, errors: [] };
}
const validateWithStateMutation = withLatest(async () => {
meta.pending = true;
meta.validated = true;
return validateCurrentValue('validated-only');
}, result => {
if (flags.pendingUnmount[field.id]) {
return result;
}
setState({ errors: result.errors });
meta.pending = false;
meta.valid = result.valid;
return result;
});
const validateValidStateOnly = withLatest(async () => {
return validateCurrentValue('silent');
}, result => {
meta.valid = result.valid;
return result;
});
function validate$1(opts) {
if ((opts === null || opts === void 0 ? void 0 : opts.mode) === 'silent') {
return validateValidStateOnly();
}
return validateWithStateMutation();
}
// Common input/change event handler
function handleChange(e, shouldValidate = true) {
const newValue = normalizeEventValue(e);
setValue(newValue, shouldValidate);
}
// Runs the initial validation
onMounted(() => {
if (validateOnMount) {
return validateWithStateMutation();
}
// validate self initially if no form was handling this
// forms should have their own initial silent validation run to make things more efficient
if (!form || !form.validateSchema) {
validateValidStateOnly();
}
});
function setTouched(isTouched) {
meta.touched = isTouched;
}
function resetField(state) {
var _a;
const newValue = state && 'value' in state ? state.value : initialValue.value;
setState({
value: klona(newValue),
initialValue: klona(newValue),
touched: (_a = state === null || state === void 0 ? void 0 : state.touched) !== null && _a !== void 0 ? _a : false,
errors: (state === null || state === void 0 ? void 0 : state.errors) || [],
});
meta.pending = false;
meta.validated = false;
validateValidStateOnly();
}
const vm = getCurrentInstance();
function setValue(newValue, shouldValidate = true) {
value.value = vm && syncVModel ? applyModelModifiers(newValue, vm.props.modelModifiers) : newValue;
const validateFn = shouldValidate ? validateWithStateMutation : validateValidStateOnly;
validateFn();
}
function setErrors(errors) {
setState({ errors: Array.isArray(errors) ? errors : [errors] });
}
const valueProxy = computed({
get() {
return value.value;
},
set(newValue) {
setValue(newValue, validateOnValueUpdate);
},
});
const field = {
id,
name,
label,
value: valueProxy,
meta,
errors,
errorMessage,
type,
checkedValue,
uncheckedValue,
bails,
keepValueOnUnmount,
resetField,
handleReset: () => resetField(),
validate: validate$1,
handleChange,
handleBlur,
setState,
setTouched,
setErrors,
setValue,
};
provide(FieldContextKey, field);
if (isRef(rules) && typeof unref(rules) !== 'function') {
watch(rules, (value, oldValue) => {
if (isEqual(value, oldValue)) {
return;
}
meta.validated ? validateWithStateMutation() : validateValidStateOnly();
}, {
deep: true,
});
}
if ((process.env.NODE_ENV !== 'production')) {
field._vm = getCurrentInstance();
watch(() => (Object.assign(Object.assign({ errors: errors.value }, meta), { value: value.value })), refreshInspector, {
deep: true,
});
if (!form) {
registerSingleFieldWithDevtools(field);
}
}
// if no associated form return the field API immediately
if (!form) {
return field;
}
// associate the field with the given form
// extract cross-field dependencies in a computed prop
const dependencies = computed(() => {
const rulesVal = validator.value;
// is falsy, a function schema or a yup schema
if (!rulesVal ||
isCallable(rulesVal) ||
isYupValidator(rulesVal) ||
isTypedSchema(rulesVal) ||
Array.isArray(rulesVal)) {
return {};
}
return Object.keys(rulesVal).reduce((acc, rule) => {
const deps = extractLocators(rulesVal[rule])
.map((dep) => dep.__locatorRef)
.reduce((depAcc, depName) => {
const depValue = getFromPath(form.values, depName) || form.values[depName];
if (depValue !== undefined) {
depAcc[depName] = depValue;
}
return depAcc;
}, {});
Object.assign(acc, deps);
return acc;
}, {});
});
// Adds a watcher that runs the validation whenever field dependencies change
watch(dependencies, (deps, oldDeps) => {
// Skip if no dependencies or if the field wasn't manipulated
if (!Object.keys(deps).length) {
return;
}
const shouldValidate = !isEqual(deps, oldDeps);
if (shouldValidate) {
meta.validated ? validateWithStateMutation() : validateValidStateOnly();
}
});
onBeforeUnmount(() => {
var _a;
const shouldKeepValue = (_a = toValue(field.keepValueOnUnmount)) !== null && _a !== void 0 ? _a : toValue(form.keepValuesOnUnmount);
const path = toValue(name);
if (shouldKeepValue || !form || flags.pendingUnmount[field.id]) {
form === null || form === void 0 ? void 0 : form.removePathState(path, id);
return;
}
flags.pendingUnmount[field.id] = true;
const pathState = form.getPathState(path);
const matchesId = Array.isArray(pathState === null || pathState === void 0 ? void 0 : pathState.id) && (pathState === null || pathState === void 0 ? void 0 : pathState.multiple)
? pathState === null || pathState === void 0 ? void 0 : pathState.id.includes(field.id)
: (pathState === null || pathState === void 0 ? void 0 : pathState.id) === field.id;
if (!matchesId) {
return;
}
if ((pathState === null || pathState === void 0 ? void 0 : pathState.multiple) && Array.isArray(pathState.value)) {
const valueIdx = pathState.value.findIndex(i => isEqual(i, toValue(field.checkedValue)));
if (valueIdx > -1) {
const newVal = [...pathState.value];
newVal.splice(valueIdx, 1);
form.setFieldValue(path, newVal);
}
if (Array.isArray(pathState.id)) {
pathState.id.splice(pathState.id.indexOf(field.id), 1);
}
}
else {
form.unsetPathValue(toValue(name));
}
form.removePathState(path, id);
});
return field;
}
/**
* Normalizes partial field options to include the full options
*/
function normalizeOptions(opts) {
const defaults = () => ({
initialValue: undefined,
validateOnMount: false,
bails: true,
label: undefined,
validateOnValueUpdate: true,
keepValueOnUnmount: undefined,
syncVModel: false,
controlled: true,
});
const isVModelSynced = !!(opts === null || opts === void 0 ? void 0 : opts.syncVModel);
const modelPropName = typeof (opts === null || opts === void 0 ? void 0 : opts.syncVModel) === 'string' ? opts.syncVModel : (opts === null || opts === void 0 ? void 0 : opts.modelPropName) || 'modelValue';
const initialValue = isVModelSynced && !('initialValue' in (opts || {}))
? getCurrentModelValue(getCurrentInstance(), modelPropName)
: opts === null || opts === void 0 ? void 0 : opts.initialValue;
if (!opts) {
return Object.assign(Object.assign({}, defaults()), { initialValue });
}
// TODO: Deprecate this in next major release
const checkedValue = 'valueProp' in opts ? opts.valueProp : opts.checkedValue;
const controlled = 'standalone' in opts ? !opts.standalone : opts.controlled;
const syncVModel = (opts === null || opts === void 0 ? void 0 : opts.modelPropName) || (opts === null || opts === void 0 ? void 0 : opts.syncVModel) || false;
return Object.assign(Object.assign(Object.assign({}, defaults()), (opts || {})), { initialValue, controlled: controlled !== null && controlled !== void 0 ? controlled : true, checkedValue,
syncVModel });
}
function useFieldWithChecked(name, rules, opts) {
const form = !(opts === null || opts === void 0 ? void 0 : opts.standalone) ? injectWithSelf(FormContextKey) : undefined;
const checkedValue = opts === null || opts === void 0 ? void 0 : opts.checkedValue;
const uncheckedValue = opts === null || opts === void 0 ? void 0 : opts.uncheckedValue;
function patchCheckedApi(field) {
const handleChange = field.handleChange;
const checked = computed(() => {
const currentValue = toValue(field.value);
const checkedVal = toValue(checkedValue);
return Array.isArray(currentValue)
? currentValue.findIndex(v => isEqual(v, checkedVal)) >= 0
: isEqual(checkedVal, currentValue);
});
function handleCheckboxChange(e, shouldValidate = true) {
var _a, _b;
if (checked.value === ((_a = e === null || e === void 0 ? void 0 : e.target) === null || _a === void 0 ? void 0 : _a.checked)) {
if (shouldValidate) {
field.validate();
}
return;
}
const path = toValue(name);
const pathState = form === null || form === void 0 ? void 0 : form.getPathState(path);
const value = normalizeEventValue(e);
let newValue = (_b = toValue(checkedValue)) !== null && _b !== void 0 ? _b : value;
if (form && (pathState === null || pathState === void 0 ? void 0 : pathState.multiple) && pathState.type === 'checkbox') {
newValue = resolveNextCheckboxValue(getFromPath(form.values, path) || [], newValue, undefined);
}
else if ((opts === null || opts === void 0 ? void 0 : opts.type) === 'checkbox') {
newValue = resolveNextCheckboxValue(toValue(field.value), newValue, toValue(uncheckedValue));
}
handleChange(newValue, shouldValidate);
}
return Object.assign(Object.assign({}, field), { checked,
checkedValue,
uncheckedValue, handleChange: handleCheckboxChange });
}
return patchCheckedApi(_useField(name, rules, opts));
}
function useVModel({ prop, value, handleChange, shouldValidate }) {
const vm = getCurrentInstance();
/* istanbul ignore next */
if (!vm || !prop) {
if ((process.env.NODE_ENV !== 'production')) {
console.warn('Failed to setup model events because `useField` was not called in setup.');
}
return;
}
const propName = typeof prop === 'string' ? prop : 'modelValue';
const emitName = `update:${propName}`;
// Component doesn't have a model prop setup (must be defined on the props)
if (!(propName in vm.props)) {
return;
}
watch(value, newValue => {
if (isEqual(newValue, getCurrentModelValue(vm, propName))) {
return;
}
vm.emit(emitName, newValue);
});
watch(() => getCurrentModelValue(vm, propName), propValue => {
if (propValue === IS_ABSENT && value.value === undefined) {
return;
}
const newValue = propValue === IS_ABSENT ? undefined : propValue;
if (isEqual(newValue, value.value)) {
return;
}
handleChange(newValue, shouldValidate());
});
}
function getCurrentModelValue(vm, propName) {
if (!vm) {
return undefined;
}
return vm.props[propName];
}
const FieldImpl = /** #__PURE__ */ defineComponent({
name: 'Field',
inheritAttrs: false,
props: {
as: {
type: [String, Object],
default: undefined,
},
name: {
type: String,
required: true,
},
rules: {
type: [Object, String, Function],
default: undefined,
},
validateOnMount: {
type: Boolean,
default: false,
},
validateOnBlur: {
type: Boolean,
default: undefined,
},
validateOnChange: {
type: Boolean,
default: undefined,
},
validateOnInput: {
type: Boolean,
default: undefined,
},
validateOnModelUpdate: {
type: Boolean,
default: undefined,
},
bails: {
type: Boolean,
default: () => getConfig().bails,
},
label: {
type: String,
default: undefined,
},
uncheckedValue: {
type: null,
default: undefined,
},
modelValue: {
type: null,
default: IS_ABSENT,
},
modelModifiers: {
type: null,
default: () => ({}),
},
'onUpdate:modelValue': {
type: null,
default: undefined,
},
standalone: {
type: Boolean,
default: false,
},
keepValue: {
type: Boolean,
default: undefined,
},
},
setup(props, ctx) {
const rules = toRef(props, 'rules');
const name = toRef(props, 'name');
const label = toRef(props, 'label');
const uncheckedValue = toRef(props, 'uncheckedValue');
const keepValue = toRef(props, 'keepValue');
const { errors, value, errorMessage, validate: validateField, handleChange, handleBlur, setTouched, resetField, handleReset, meta, checked, setErrors, } = useField(name, rules, {
validateOnMount: props.validateOnMount,
bails: props.bails,
standalone: props.standalone,
type: ctx.attrs.type,
initialValue: resolveInitialValue(props, ctx),
// Only for checkboxes and radio buttons
checkedValue: ctx.attrs.value,
uncheckedValue,
label,
validateOnValueUpdate: props.validateOnModelUpdate,
keepValueOnUnmount: keepValue,
syncVModel: true,
});
// If there is a v-model applied on the component we need to emit the `update:modelValue` whenever the value binding changes
const onChangeHandler = function handleChangeWithModel(e, shouldValidate = true) {
handleChange(e, shouldValidate);
};
const sharedProps = computed(() => {
const { validateOnInput, validateOnChange, validateOnBlur, validateOnModelUpdate } = resolveValidationTriggers(props);
function baseOnBlur(e) {
handleBlur(e, validateOnBlur);
if (isCallable(ctx.attrs.onBlur)) {
ctx.attrs.onBlur(e);
}
}
function baseOnInput(e) {
onChangeHandler(e, validateOnInput);
if (isCallable(ctx.attrs.onInput)) {
ctx.attrs.onInput(e);
}
}
function baseOnChange(e) {
onChangeHandler(e, validateOnChange);
if (isCallable(ctx.attrs.onChange)) {
ctx.attrs.onChange(e);
}
}
const attrs = {
name: props.name,
onBlur: baseOnBlur,
onInput: baseOnInput,
onChange: baseOnChange,
};
attrs['onUpdate:modelValue'] = e => onChangeHandler(e, validateOnModelUpdate);
return attrs;
});
const fieldProps = computed(() => {
const attrs = Object.assign({}, sharedProps.value);
if (hasCheckedAttr(ctx.attrs.type) && checked) {
attrs.checked = checked.value;
}
const tag = resolveTag(props, ctx);
if (shouldHaveValueBinding(tag, ctx.attrs)) {
attrs.value = value.value;
}
return attrs;
});
const componentProps = computed(() => {
return Object.assign(Object.assign({}, sharedProps.value), { modelValue: value.value });
});
function slotProps() {
return {
field: fieldProps.value,
componentField: componentProps.value,
value: value.value,
meta,
errors: errors.value,
errorMessage: errorMessage.value,
validate: validateField,
resetField,
handleChange: onChangeHandler,
handleInput: e => onChangeHandler(e, false),
handleReset,
handleBlur: sharedProps.value.onBlur,
setTouched,
setErrors,
};
}
ctx.expose({
value,
meta,
errors,
errorMessage,
setErrors,
setTouched,
reset: resetField,
validate: validateField,
handleChange,
});
return () => {
const tag = resolveDynamicComponent(resolveTag(props, ctx));
const children = normalizeChildren(tag, ctx, slotProps);
if (tag) {
return h(tag, Object.assign(Object.assign({}, ctx.attrs), fieldProps.value), children);
}
return children;
};
},
});
function resolveTag(props, ctx) {
let tag = props.as || '';
if (!props.as && !ctx.slots.default) {
tag = 'input';
}
return tag;
}
function resolveValidationTriggers(props) {
var _a, _b, _c, _d;
const { validateOnInput, validateOnChange, validateOnBlur, validateOnModelUpdate } = getConfig();
return {
validateOnInput: (_a = props.validateOnInput) !== null && _a !== void 0 ? _a : validateOnInput,
validateOnChange: (_b = props.validateOnChange) !== null && _b !== void 0 ? _b : validateOnChange,
validateOnBlur: (_c = props.validateOnBlur) !== null && _c !== void 0 ? _c : validateOnBlur,
validateOnModelUpdate: (_d = props.validateOnModelUpdate) !== null && _d !== void 0 ? _d : validateOnModelUpdate,
};
}
function resolveInitialValue(props, ctx) {
// Gets the initial value either from `value` prop/attr or `v-model` binding (modelValue)
// For checkboxes and radio buttons it will always be the model value not the `value` attribute
if (!hasCheckedAttr(ctx.attrs.type)) {
return isPropPresent(props, 'modelValue') ? props.modelValue : ctx.attrs.value;
}
return isPropPresent(props, 'modelValue') ? props.modelValue : undefined;
}
const Field = FieldImpl;
let FORM_COUNTER = 0;
const PRIVATE_PATH_STATE_KEYS = ['bails', 'fieldsCount', 'id', 'multiple', 'type', 'validate'];
function resolveInitialValues(opts) {
const providedValues = Object.assign({}, toValue((opts === null || opts === void 0 ? void 0 : opts.initialValues) || {}));
const schema = unref(opts === null || opts === void 0 ? void 0 : opts.validationSchema);
if (schema && isTypedSchema(schema) && isCallable(schema.cast)) {
return klona(schema.cast(providedValues) || {});
}
return klona(providedValues);
}
function useForm(opts) {
var _a;
const formId = FORM_COUNTER++;
// Prevents fields from double resetting their values, which causes checkboxes to toggle their initial value
let FIELD_ID_COUNTER = 0;
// If the form is currently submitting
const isSubmitting = ref(false);
// If the form is currently validating
const isValidating = ref(false);
// The number of times the user tried to submit the form
const submitCount = ref(0);
// field arrays managed by this form
const fieldArrays = [];
// a private ref for all form values
const formValues = reactive(resolveInitialValues(opts));
const pathStates = ref([]);
const extraErrorsBag = ref({});
const pathStateLookup = ref({});
const rebuildPathLookup = debounceNextTick(() => {
pathStateLookup.value = pathStates.value.reduce((names, state) => {
names[normalizeFormPath(toValue(state.path))] = state;
return names;
}, {});
});
/**
* Manually sets an error message on a specific field
*/
function setFieldError(field, message) {
const state = findPathState(field);
if (!state) {
if (typeof field === 'string') {
extraErrorsBag.value[normalizeFormPath(field)] = normalizeErrorItem(message);
}
return;
}
// Move the error from the extras path if exists
if (typeof field === 'string') {
const normalizedPath = normalizeFormPath(field);
if (extraErrorsBag.value[normalizedPath]) {
delete extraErrorsBag.value[normalizedPath];
}
}
state.errors = normalizeErrorItem(message);
state.valid = !state.errors.length;
}
/**
* Sets errors for the fields specified in the object
*/
function setErrors(paths) {
keysOf(paths).forEach(path => {
setFieldError(path, paths[path]);
});
}
if (opts === null || opts === void 0 ? void 0 : opts.initialErrors) {
setErrors(opts.initialErrors);
}
const errorBag = computed(() => {
const pathErrors = pathStates.value.reduce((acc, state) => {
if (state.errors.length) {
acc[state.path] = state.errors;
}
return acc;
}, {});
return Object.assign(Object.assign({}, extraErrorsBag.value), pathErrors);
});
// Gets the first error of each field
const errors = computed(() => {
return keysOf(errorBag.value).reduce((acc, key) => {
const errors = errorBag.value[key];
if (errors === null || errors === void 0 ? void 0 : errors.length) {
acc[key] = errors[0];
}
return acc;
}, {});
});
/**
* Holds a computed reference to all fields names and labels
*/
const fieldNames = computed(() => {
return pathStates.value.reduce((names, state) => {
names[state.path] = { name: state.path || '', label: state.label || '' };
return names;
}, {});
});
const fieldBailsMap = computed(() => {
return pathStates.value.reduce((map, state) => {
var _a;
map[state.path] = (_a = state.bails) !== null && _a !== void 0 ? _a : true;
return map;
}, {});
});
// mutable non-reactive reference to initial errors
// we need this to process initial errors then unset them
const initialErrors = Object.assign({}, ((opts === null || opts === void 0 ? void 0 : opts.initialErrors) || {}));
const keepValuesOnUnmount = (_a = opts === null || opts === void 0 ? void 0 : opts.keepValuesOnUnmount) !== null && _a !== void 0 ? _a : false;
// initial form values
const { initialValues, originalInitialValues, setInitialValues } = useFormInitialValues(pathStates, formValues, opts);
// form meta aggregations
const meta = useFormMeta(pathStates, formValues, originalInitialValues, errors);
const controlledValues = computed(() => {
return pathStates.value.reduce((acc, state) => {
const value = getFromPath(formValues, state.path);
setInPath(acc, state.path, value);
return acc;
}, {});
});
const schema = opts === null || opts === void 0 ? void 0 : opts.validationSchema;
function createPathState(path, config) {
var _a, _b;
const initialValue = computed(() => getFromPath(initialValues.value, toValue(path)));
const pathStateExists = pathStateLookup.value[toValue(path)];
const isCheckboxOrRadio = (config === null || config === void 0 ? void 0 : config.type) === 'checkbox' || (config === null || config === void 0 ? void 0 : config.type) === 'radio';
if (pathStateExists && isCheckboxOrRadio) {
pathStateExists.multiple = true;
const id = FIELD_ID_COUNTER++;
if (Array.isArray(pathStateExists.id)) {
pathStateExists.id.push(id);
}
else {
pathStateExists.id = [pathStateExists.id, id];
}
pathStateExists.fieldsCount++;
pathStateExists.__flags.pendingUnmount[id] = false;
return pathStateExists;
}
const currentValue = computed(() => getFromPath(formValues, toValue(path)));
const pathValue = toValue(path);
const isRequired = computed(() => {
var _a, _b, _c, _d, _e, _f;
if (isTypedSchema(schema)) {
return (_c = (_b = (_a = schema).describe) === null || _b === void 0 ? void 0 : _b.call(_a, toValue(path)).required) !== null && _c !== void 0 ? _c : false;
}
// Path own schema
if (isTypedSchema(config === null || config === void 0 ? void 0 : config.schema)) {
return (_f = (_e = (_d = (config === null || config === void 0 ? void 0 : config.schema)).describe) === null || _e === void 0 ? void 0 : _e.call(_d).required) !== null && _f !== void 0 ? _f : false;
}
return false;
});
const id = FIELD_ID_COUNTER++;
const state = reactive({
id,
path,
touched: false,
pending: false,
valid: true,
validated: !!((_a = initialErrors[pathValue]) === null || _a === void 0 ? void 0 : _a.length),
required: isRequired,
initialValue,
errors: shallowRef([]),
bails: (_b = config === null || config === void 0 ? void 0 : config.bails) !== null && _b !== void 0 ? _b : false,
label: config === null || config === void 0 ? void 0 : config.label,
type: (config === null || config === void 0 ? void 0 : config.type) || 'default',
value: currentValue,
multiple: false,
__flags: {
pendingUnmount: { [id]: false },
pendingReset: false,
},
fieldsCount: 1,
validate: config === null || config === void 0 ? void 0 : config.validate,
dirty: computed(() => {
return !isEqual(unref(currentValue), unref(initialValue));
}),
});
pathStates.value.push(state);
pathStateLookup.value[pathValue] = state;
rebuildPathLookup();
if (errors.value[pathValue] && !initialErrors[pathValue]) {
nextTick(() => {
validateField(pathValue, { mode: 'silent' });
});
}
// Handles when a path changes
if (isRef(path)) {
watch(path, newPath => {
rebuildPathLookup();
const nextValue = klona(currentValue.value);
pathStateLookup.value[newPath] = state;
nextTick(() => {
setInPath(formValues, newPath, nextValue);
});
});
}
return state;
}
/**
* Batches validation runs in 5ms batches
* Must have two distinct batch queues to make sure they don't override each other settings #3783
*/
const debouncedSilentValidation = debounceAsync(_validateSchema, 5);
const debouncedValidation = debounceAsync(_validateSchema, 5);
const validateSchema = withLatest(async (mode) => {
return (await (mode === 'silent'
? debouncedSilentValidation()
: debouncedValidation()));
}, (formResult, [mode]) => {
// fields by id lookup
// errors fields names, we need it to also check if custom errors are updated
const currentErrorsPaths = keysOf(formCtx.errorBag.value);
// collect all the keys from the schema and all fields
// this ensures we have a complete key map of all the fields
const paths = [
...new Set([...keysOf(formResult.results), ...pathStates.value.map(p => p.path), ...currentErrorsPaths]),
].sort();
// aggregates the paths into a single result object while applying the results on the fields
const results = paths.reduce((validation, _path) => {
var _a;
const expectedPath = _path;
const pathState = findPathState(expectedPath) || findHoistedPath(expectedPath);
const messages = ((_a = formResult.results[expectedPath]) === null || _a === void 0 ? void 0 : _a.errors) || [];
// This is the real path of the field, because it might've been a hoisted field
const path = (toValue(pathState === null || pathState === void 0 ? void 0 : pathState.path) || expectedPath);
// It is possible that multiple paths are collected across loops
// We want to merge them to avoid overriding any iteration's results
const fieldResult = mergeValidationResults({ errors: messages, valid: !messages.length }, validation.results[path]);
validation.results[path] = fieldResult;
if (!fieldResult.valid) {
validation.errors[path] = fieldResult.errors[0];
}
// clean up extra errors if path state exists
if (pathState && extraErrorsBag.value[path]) {
delete extraErrorsBag.value[path];
}
// field not rendered
if (!pathState) {
setFieldError(path, messages);
return validation;
}
// always update the valid flag regardless of the mode
pathState.valid = fieldResult.valid;
if (mode === 'silent') {
return validation;
}
if (mode === 'validated-only' && !pathState.validated) {
return validation;
}
setFieldError(pathState, fieldResult.errors);
return validation;
}, { valid: formResult.valid, results: {}, errors: {} });
if (formResult.values) {
results.values = formResult.values;
}
return results;
});
function mutateAllPathState(mutation) {
pathStates.value.forEach(mutation);
}
function findPathState(path) {
const normalizedPath = typeof path === 'string' ? normalizeFormPath(path) : path;
const pathState = typeof normalizedPath === 'string' ? pathStateLookup.value[normalizedPath] : normalizedPath;
return pathState;
}
function findHoistedPath(path) {
const candidates = pathStates.value.filter(state => path.startsWith(state.path));
return candidates.reduce((bestCandidate, candidate) => {
if (!bestCandidate) {
return candidate;
}
return (candidate.path.length > bestCandidate.path.length ? candidate : bestCandidate);
}, undefined);
}
let UNSET_BATCH = [];
let PENDING_UNSET;
function unsetPathValue(path) {
UNSET_BATCH.push(path);
if (!PENDING_UNSET) {
PENDING_UNSET = nextTick(() => {
const sortedPaths = [...UNSET_BATCH].sort().reverse();
sortedPaths.forEach(p => {
unsetPath(formValues, p);
});
UNSET_BATCH = [];
PENDING_UNSET = null;
});
}
return PENDING_UNSET;
}
function makeSubmissionFactory(onlyControlled) {
return function submitHandlerFactory(fn, onValidationError) {
return function submissionHandler(e) {
if (e instanceof Event) {
e.preventDefault();
e.stopPropagation();
}
// Touch all fields
mutateAllPathState(s => (s.touched = true));
isSubmitting.value = true;
submitCount.value++;
return validate()
.then(result => {
const values = klona(formValues);
if (result.valid && typeof fn === 'function') {
const controlled = klona(controlledValues.value);
let submittedValues = (onlyControlled ? controlled : values);
if (result.values) {
submittedValues = result.values;
}
return fn(submittedValues, {
evt: e,
controlledValues: controlled,
setErrors,
setFieldError,
setTouched,
setFieldTouched,
setValues,
setFieldValue,
resetForm,
resetField,
});
}
if (!result.valid && typeof onValidationError === 'function') {
onValidationError({
values,
evt: e,
errors: result.errors,
results: result.results,
});
}
})
.then(returnVal => {
isSubmitting.value = false;
return returnVal;
}, err => {
isSubmitting.value = false;
// re-throw the err so it doesn't go silent
throw err;
});
};
};
}
const handleSubmitImpl = makeSubmissionFactory(false);
const handleSubmit = handleSubmitImpl;
handleSubmit.withControlled = makeSubmissionFactory(true);
function removePathState(path, id) {
const idx = pathStates.value.findIndex(s => s.path === path);
const pathState = pathStates.value[idx];
if (idx === -1 || !pathState) {
return;
}
nextTick(() => {
validateField(path, { mode: 'silent', warn: false });
});
if (pathState.multiple && pathState.fieldsCount) {
pathState.fieldsCount--;
}
if (Array.isArray(pathState.id)) {
const idIndex = pathState.id.indexOf(id);
if (idIndex >= 0) {
pathState.id.splice(idIndex, 1);
}
delete pathState.__flags.pendingUnmount[id];
}
if (!pathState.multiple || pathState.fieldsCount <= 0) {
pathStates.value.splice(idx, 1);
unsetInitialValue(path);
rebuildPathLookup();
delete pathStateLookup.value[path];
}
}
function destroyPath(path) {
keysOf(pathStateLookup.value).forEach(key => {
if (key.startsWith(path)) {
delete pathStateLookup.value[key];
}
});
pathStates.value = pathStates.value.filter(s => !s.path.startsWith(path));
nextTick(() => {
rebuildPathLookup();
});
}
const formCtx = {
formId,
values: formValues,
controlledValues,
errorBag,
errors,
schema,
submitCount,
meta,
isSubmitting,
isValidating,
fieldArrays,
keepValuesOnUnmount,
validateSchema: unref(schema) ? validateSchema : undefined,
validate,
setFieldError,
validateField,
setFieldValue,
setValues,
setErrors,
setFieldTouched,
setTouched,
resetForm,
resetField,
handleSubmit,
useFieldModel,
defineInputBinds,
defineComponentBinds: defineComponentBinds,
defineField,
stageInitialValue,
unsetInitialValue,
setFieldInitialValue,
createPathState,
getPathState: findPathState,
unsetPathValue,
removePathState,
initialValues: initialValues,
getAllPathStates: () => pathStates.value,
destroyPath,
isFieldTouched,
isFieldDirty,
isFieldValid,
};
/**
* Sets a single field value
*/
function setFieldValue(field, value, shouldValidate = true) {
const clonedValue = klona(value);
const path = typeof field === 'string' ? field : field.path;
const pathState = findPathState(path);
if (!pathState) {
createPathState(path);
}
setInPath(formValues, path, clonedValue);
if (shouldValidate) {
validateField(path);
}
}
function forceSetValues(fields, shouldValidate = true) {
// clean up old values
keysOf(formValues).forEach(key => {
delete formValues[key];
});
// set up new values
keysOf(fields).forEach(path => {
setFieldValue(path, fields[path], false);
});
if (shouldValidate) {
validate();
}
}
/**
* Sets multiple fields values
*/
function setValues(fields, shouldValidate = true) {
merge(formValues, fields);
// regenerate the arrays when the form values change
fieldArrays.forEach(f => f && f.reset());
if (shouldValidate) {
validate();
}
}
function createModel(path, shouldValidate) {
const pathState = findPathState(toValue(path)) || createPathState(path);
return computed({
get() {
return pathState.value;
},
set(value) {
var _a;
const pathValue = toValue(path);
setFieldValue(pathValue, value, (_a = toValue(shouldValidate)) !== null && _a !== void 0 ? _a : false);
},
});
}
/**
* Sets the touched meta state on a field
*/
function setFieldTouched(field, isTouched) {
const pathState = findPathState(field);
if (pathState) {
pathState.touched = isTouched;
}
}
function isFieldTouched(field) {
const pathState = findPathState(field);
if (pathState) {
return pathState.touched;
}
// Find all nested paths and consider their touched state
return pathStates.value.filter(s => s.path.startsWith(field)).some(s => s.touched);
}
function isFieldDirty(field) {
const pathState = findPathState(field);
if (pathState) {
return pathState.dirty;
}
return pathStates.value.filter(s => s.path.startsWith(field)).some(s => s.dirty);
}
function isFieldValid(field) {
const pathState = findPathState(field);
if (pathState) {
return pathState.valid;
}
return pathStates.value.filter(s => s.path.startsWith(field)).every(s => s.valid);
}
/**
* Sets the touched meta state on multiple fields
*/
function setTouched(fields) {
if (typeof fields === 'boolean') {
mutateAllPathState(state => {
state.touched = fields;
});
return;
}
keysOf(fields).forEach(field => {
setFieldTouched(field, !!fields[field]);
});
}
function resetField(field, state) {
var _a;
const newValue = state && 'value' in state ? state.value : getFromPath(initialValues.value, field);
const pathState = findPathState(field);
if (pathState) {
pathState.__flags.pendingReset = true;
}
setFieldInitialValue(field, klona(newValue), true);
setFieldValue(field, newValue, false);
setFieldTouched(field, (_a = state === null || state === void 0 ? void 0 : state.touched) !== null && _a !== void 0 ? _a : false);
setFieldError(field, (state === null || state === void 0 ? void 0 : state.errors) || []);
nextTick(() => {
if (pathState) {
pathState.__flags.pendingReset = false;
}
});
}
/**
* Resets all fields
*/
function resetForm(resetState, opts) {
let newValues = klona((resetState === null || resetState === void 0 ? void 0 : resetState.values) ? resetState.values : originalInitialValues.value);
newValues = (opts === null || opts === void 0 ? void 0 : opts.force) ? newValues : merge(originalInitialValues.value, newValues);
newValues = isTypedSchema(schema) && isCallable(schema.cast) ? schema.cast(newValues) : newValues;
setInitialValues(newValues);
mutateAllPathState(state => {
var _a;
state.__flags.pendingReset = true;
state.validated = false;
state.touched = ((_a = resetState === null || resetState === void 0 ? void 0 : resetState.touched) === null || _a === void 0 ? void 0 : _a[state.path]) || false;
setFieldValue(state.path, getFromPath(newValues, state.path), false);
setFieldError(state.path, undefined);
});
(opts === null || opts === void 0 ? void 0 : opts.force) ? forceSetValues(newValues, false) : setValues(newValues, false);
setErrors((resetState === null || resetState === void 0 ? void 0 : resetState.errors) || {});
submitCount.value = (resetState === null || resetState === void 0 ? void 0 : resetState.submitCount) || 0;
nextTick(() => {
validate({ mode: 'silent' });
mutateAllPathState(state => {
state.__flags.pendingReset = false;
});
});
}
async function validate(opts) {
const mode = (opts === null || opts === void 0 ? void 0 : opts.mode) || 'force';
if (mode === 'force') {
mutateAllPathState(f => (f.validated = true));
}
if (formCtx.validateSchema) {
return formCtx.validateSchema(mode);
}
isValidating.value = true;
// No schema, each field is responsible to validate itself
const validations = await Promise.all(pathStates.value.map(state => {
if (!state.validate) {
return Promise.resolve({
key: state.path,
valid: true,
errors: [],
});
}
return state.validate(opts).then((result) => {
return {
key: state.path,
valid: result.valid,
errors: result.errors,
};
});
}));
isValidating.value = false;
const results = {};
const errors = {};
for (const validation of validations) {
results[validation.key] = {
valid: validation.valid,
errors: validation.errors,
};
if (validation.errors.length) {
errors[validation.key] = validation.errors[0];
}
}
return {
valid: validations.every(r => r.valid),
results,
errors,
};
}
async function validateField(path, opts) {
var _a;
const state = findPathState(path);
if (state && (opts === null || opts === void 0 ? void 0 : opts.mode) !== 'silent') {
state.validated = true;
}
if (schema) {
const { results } = await validateSchema((opts === null || opts === void 0 ? void 0 : opts.mode) || 'validated-only');
return results[path] || { errors: [], valid: true };
}
if (state === null || state === void 0 ? void 0 : state.validate) {
return state.validate(opts);
}
const shouldWarn = !state && ((_a = opts === null || opts === void 0 ? void 0 : opts.warn) !== null && _a !== void 0 ? _a : true);
if (shouldWarn) {
if ((process.env.NODE_ENV !== 'production')) {
warn$1(`field with path ${path} was not found`);
}
}
return Promise.resolve({ errors: [], valid: true });
}
function unsetInitialValue(path) {
unsetPath(initialValues.value, path);
}
/**
* Sneaky function to set initial field values
*/
function stageInitialValue(path, value, updateOriginal = false) {
setFieldInitialValue(path, value);
setInPath(formValues, path, value);
if (updateOriginal && !(opts === null || opts === void 0 ? void 0 : opts.initialValues)) {
setInPath(originalInitialValues.value, path, klona(value));
}
}
function setFieldInitialValue(path, value, updateOriginal = false) {
setInPath(initialValues.value, path, klona(value));
if (updateOriginal) {
setInPath(originalInitialValues.value, path, klona(value));
}
}
async function _validateSchema() {
const schemaValue = unref(schema);
if (!schemaValue) {
return { valid: true, results: {}, errors: {} };
}
isValidating.value = true;
const formResult = isYupValidator(schemaValue) || isTypedSchema(schemaValue)
? await validateTypedSchema(schemaValue, formValues)
: await validateObjectSchema(schemaValue, formValues, {
names: fieldNames.value,
bailsMap: fieldBailsMap.value,
});
isValidating.value = false;
return formResult;
}
const submitForm = handleSubmit((_, { evt }) => {
if (isFormSubmitEvent(evt)) {
evt.target.submit();
}
});
// Trigger initial validation
onMounted(() => {
if (opts === null || opts === void 0 ? void 0 : opts.initialErrors) {
setErrors(opts.initialErrors);
}
if (opts === null || opts === void 0 ? void 0 : opts.initialTouched) {
setTouched(opts.initialTouched);
}
// if validate on mount was enabled
if (opts === null || opts === void 0 ? void 0 : opts.validateOnMount) {
validate();
return;
}
// otherwise run initial silent validation through schema if available
// the useField should skip their own silent validation if a yup schema is present
if (formCtx.validateSchema) {
formCtx.validateSchema('silent');
}
});
if (isRef(schema)) {
watch(schema, () => {
var _a;
(_a = formCtx.validateSchema) === null || _a === void 0 ? void 0 : _a.call(formCtx, 'validated-only');
});
}
// Provide injections
provide(FormContextKey, formCtx);
if ((process.env.NODE_ENV !== 'production')) {
registerFormWithDevTools(formCtx);
watch(() => (Object.assign(Object.assign({ errors: errorBag.value }, meta.value), { values: formValues, isSubmitting: isSubmitting.value, isValidating: isValidating.value, submitCount: submitCount.value })), refreshInspector, {
deep: true,
});
}
function defineField(path, config) {
const label = isCallable(config) ? undefined : config === null || config === void 0 ? void 0 : config.label;
const pathState = (findPathState(toValue(path)) || createPathState(path, { label }));
const evalConfig = () => (isCallable(config) ? config(omit(pathState, PRIVATE_PATH_STATE_KEYS)) : config || {});
function onBlur() {
var _a;
pathState.touched = true;
const validateOnBlur = (_a = evalConfig().validateOnBlur) !== null && _a !== void 0 ? _a : getConfig().validateOnBlur;
if (validateOnBlur) {
validateField(pathState.path);
}
}
function onInput() {
var _a;
const validateOnInput = (_a = evalConfig().validateOnInput) !== null && _a !== void 0 ? _a : getConfig().validateOnInput;
if (validateOnInput) {
nextTick(() => {
validateField(pathState.path);
});
}
}
function onChange() {
var _a;
const validateOnChange = (_a = evalConfig().validateOnChange) !== null && _a !== void 0 ? _a : getConfig().validateOnChange;
if (validateOnChange) {
nextTick(() => {
validateField(pathState.path);
});
}
}
const props = computed(() => {
const base = {
onChange,
onInput,
onBlur,
};
if (isCallable(config)) {
return Object.assign(Object.assign({}, base), (config(omit(pathState, PRIVATE_PATH_STATE_KEYS)).props || {}));
}
if (config === null || config === void 0 ? void 0 : config.props) {
return Object.assign(Object.assign({}, base), config.props(omit(pathState, PRIVATE_PATH_STATE_KEYS)));
}
return base;
});
const model = createModel(path, () => { var _a, _b, _c; return (_c = (_a = evalConfig().validateOnModelUpdate) !== null && _a !== void 0 ? _a : (_b = getConfig()) === null || _b === void 0 ? void 0 : _b.validateOnModelUpdate) !== null && _c !== void 0 ? _c : true; });
return [model, props];
}
function useFieldModel(pathOrPaths) {
if (!Array.isArray(pathOrPaths)) {
return createModel(pathOrPaths);
}
return pathOrPaths.map(p => createModel(p, true));
}
/**
* @deprecated use defineField instead
*/
function defineInputBinds(path, config) {
const [model, props] = defineField(path, config);
function onBlur(e) {
props.value.onBlur(e);
}
function onInput(e) {
const value = normalizeEventValue(e);
setFieldValue(toValue(path), value, false);
props.value.onInput(e);
}
function onChange(e) {
const value = normalizeEventValue(e);
setFieldValue(toValue(path), value, false);
props.value.onChange(e);
}
return computed(() => {
return Object.assign(Object.assign({}, props.value), { onBlur,
onInput,
onChange, value: model.value });
});
}
/**
* @deprecated use defineField instead
*/
function defineComponentBinds(path, config) {
const [model, props] = defineField(path, config);
const pathState = findPathState(toValue(path));
function onUpdateModelValue(value) {
model.value = value;
}
return computed(() => {
const conf = isCallable(config) ? config(omit(pathState, PRIVATE_PATH_STATE_KEYS)) : config || {};
return Object.assign({ [conf.model || 'modelValue']: model.value, [`onUpdate:${conf.model || 'modelValue'}`]: onUpdateModelValue }, props.value);
});
}
return Object.assign(Object.assign({}, formCtx), { values: readonly(formValues), handleReset: () => resetForm(), submitForm });
}
/**
* Manages form meta aggregation
*/
function useFormMeta(pathsState, currentValues, initialValues, errors) {
const MERGE_STRATEGIES = {
touched: 'some',
pending: 'some',
valid: 'every',
};
const isDirty = computed(() => {
return !isEqual(currentValues, unref(initialValues));
});
function calculateFlags() {
const states = pathsState.value;
return keysOf(MERGE_STRATEGIES).reduce((acc, flag) => {
const mergeMethod = MERGE_STRATEGIES[flag];
acc[flag] = states[mergeMethod](s => s[flag]);
return acc;
}, {});
}
const flags = reactive(calculateFlags());
watchEffect(() => {
const value = calculateFlags();
flags.touched = value.touched;
flags.valid = value.valid;
flags.pending = value.pending;
});
return computed(() => {
return Object.assign(Object.assign({ initialValues: unref(initialValues) }, flags), { valid: flags.valid && !keysOf(errors.value).length, dirty: isDirty.value });
});
}
/**
* Manages the initial values prop
*/
function useFormInitialValues(pathsState, formValues, opts) {
const values = resolveInitialValues(opts);
// these are the mutable initial values as the fields are mounted/unmounted
const initialValues = ref(values);
// these are the original initial value as provided by the user initially, they don't keep track of conditional fields
// this is important because some conditional fields will overwrite the initial values for other fields who had the same name
// like array fields, any push/insert operation will overwrite the initial values because they "create new fields"
// so these are the values that the reset function should use
// these only change when the user explicitly changes the initial values or when the user resets them with new values.
const originalInitialValues = ref(klona(values));
function setInitialValues(values, updateFields = false) {
initialValues.value = merge(klona(initialValues.value) || {}, klona(values));
originalInitialValues.value = merge(klona(originalInitialValues.value) || {}, klona(values));
if (!updateFields) {
return;
}
// update the pristine non-touched fields
// those are excluded because it's unlikely you want to change the form values using initial values
// we mostly watch them for API population or newly inserted fields
// 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
pathsState.value.forEach(state => {
const wasTouched = state.touched;
if (wasTouched) {
return;
}
const newValue = getFromPath(initialValues.value, state.path);
setInPath(formValues, state.path, klona(newValue));
});
}
return {
initialValues,
originalInitialValues,
setInitialValues,
};
}
function mergeValidationResults(a, b) {
if (!b) {
return a;
}
return {
valid: a.valid && b.valid,
errors: [...a.errors, ...b.errors],
};
}
const FormImpl = /** #__PURE__ */ defineComponent({
name: 'Form',
inheritAttrs: false,
props: {
as: {
type: null,
default: 'form',
},
validationSchema: {
type: Object,
default: undefined,
},
initialValues: {
type: Object,
default: undefined,
},
initialErrors: {
type: Object,
default: undefined,
},
initialTouched: {
type: Object,
default: undefined,
},
validateOnMount: {
type: Boolean,
default: false,
},
onSubmit: {
type: Function,
default: undefined,
},
onInvalidSubmit: {
type: Function,
default: undefined,
},
keepValues: {
type: Boolean,
default: false,
},
},
setup(props, ctx) {
const validationSchema = toRef(props, 'validationSchema');
const keepValues = toRef(props, 'keepValues');
const { errors, errorBag, values, meta, isSubmitting, isValidating, submitCount, controlledValues, validate, validateField, handleReset, resetForm, handleSubmit, setErrors, setFieldError, setFieldValue, setValues, setFieldTouched, setTouched, resetField, } = useForm({
validationSchema: validationSchema.value ? validationSchema : undefined,
initialValues: props.initialValues,
initialErrors: props.initialErrors,
initialTouched: props.initialTouched,
validateOnMount: props.validateOnMount,
keepValuesOnUnmount: keepValues,
});
const submitForm = handleSubmit((_, { evt }) => {
if (isFormSubmitEvent(evt)) {
evt.target.submit();
}
}, props.onInvalidSubmit);
const onSubmit = props.onSubmit ? handleSubmit(props.onSubmit, props.onInvalidSubmit) : submitForm;
function handleFormReset(e) {
if (isEvent(e)) {
// Prevent default form reset behavior
e.preventDefault();
}
handleReset();
if (typeof ctx.attrs.onReset === 'function') {
ctx.attrs.onReset();
}
}
function handleScopedSlotSubmit(evt, onSubmit) {
const onSuccess = typeof evt === 'function' && !onSubmit ? evt : onSubmit;
return handleSubmit(onSuccess, props.onInvalidSubmit)(evt);
}
function getValues() {
return klona(values);
}
function getMeta() {
return klona(meta.value);
}
function getErrors() {
return klona(errors.value);
}
function slotProps() {
return {
meta: meta.value,
errors: errors.value,
errorBag: errorBag.value,
values,
isSubmitting: isSubmitting.value,
isValidating: isValidating.value,
submitCount: submitCount.value,
controlledValues: controlledValues.value,
validate,
validateField,
handleSubmit: handleScopedSlotSubmit,
handleReset,
submitForm,
setErrors,
setFieldError,
setFieldValue,
setValues,
setFieldTouched,
setTouched,
resetForm,
resetField,
getValues,
getMeta,
getErrors,
};
}
// expose these functions and methods as part of public API
ctx.expose({
setFieldError,
setErrors,
setFieldValue,
setValues,
setFieldTouched,
setTouched,
resetForm,
validate,
validateField,
resetField,
getValues,
getMeta,
getErrors,
values,
meta,
errors,
});
return function renderForm() {
// avoid resolving the form component as itself
const tag = props.as === 'form' ? props.as : !props.as ? null : resolveDynamicComponent(props.as);
const children = normalizeChildren(tag, ctx, slotProps);
if (!tag) {
return children;
}
// Attributes to add on a native `form` tag
const formAttrs = tag === 'form'
? {
// Disables native validation as vee-validate will handle it.
novalidate: true,
}
: {};
return h(tag, Object.assign(Object.assign(Object.assign({}, formAttrs), ctx.attrs), { onSubmit, onReset: handleFormReset }), children);
};
},
});
const Form = FormImpl;
function useFieldArray(arrayPath) {
const form = injectWithSelf(FormContextKey, undefined);
const fields = ref([]);
// eslint-disable-next-line @typescript-eslint/no-empty-function
const noOp = () => { };
const noOpApi = {
fields,
remove: noOp,
push: noOp,
swap: noOp,
insert: noOp,
update: noOp,
replace: noOp,
prepend: noOp,
move: noOp,
};
if (!form) {
if ((process.env.NODE_ENV !== 'production')) {
warn('FieldArray requires being a child of `<Form/>` or `useForm` being called before it. Array fields may not work correctly');
}
return noOpApi;
}
if (!unref(arrayPath)) {
if ((process.env.NODE_ENV !== 'production')) {
warn('FieldArray requires a field path to be provided, did you forget to pass the `name` prop?');
}
return noOpApi;
}
const alreadyExists = form.fieldArrays.find(a => unref(a.path) === unref(arrayPath));
if (alreadyExists) {
return alreadyExists;
}
let entryCounter = 0;
function getCurrentValues() {
return getFromPath(form === null || form === void 0 ? void 0 : form.values, toValue(arrayPath), []) || [];
}
function initFields() {
const currentValues = getCurrentValues();
if (!Array.isArray(currentValues)) {
return;
}
fields.value = currentValues.map((v, idx) => createEntry(v, idx, fields.value));
updateEntryFlags();
}
initFields();
function updateEntryFlags() {
const fieldsLength = fields.value.length;
for (let i = 0; i < fieldsLength; i++) {
const entry = fields.value[i];
entry.isFirst = i === 0;
entry.isLast = i === fieldsLength - 1;
}
}
function createEntry(value, idx, currentFields) {
// Skips the work by returning the current entry if it already exists
// This should make the `key` prop stable and doesn't cause more re-renders than needed
// The value is computed and should update anyways
if (currentFields && !isNullOrUndefined(idx) && currentFields[idx]) {
return currentFields[idx];
}
const key = entryCounter++;
const entry = {
key,
value: computedDeep({
get() {
const currentValues = getFromPath(form === null || form === void 0 ? void 0 : form.values, toValue(arrayPath), []) || [];
const idx = fields.value.findIndex(e => e.key === key);
return idx === -1 ? value : currentValues[idx];
},
set(value) {
const idx = fields.value.findIndex(e => e.key === key);
if (idx === -1) {
if ((process.env.NODE_ENV !== 'production')) {
warn(`Attempting to update a non-existent array item`);
}
return;
}
update(idx, value);
},
}), // will be auto unwrapped
isFirst: false,
isLast: false,
};
return entry;
}
function afterMutation() {
updateEntryFlags();
// Should trigger a silent validation since a field may not do that #4096
form === null || form === void 0 ? void 0 : form.validate({ mode: 'silent' });
}
function remove(idx) {
const pathName = toValue(arrayPath);
const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);
if (!pathValue || !Array.isArray(pathValue)) {
return;
}
const newValue = [...pathValue];
newValue.splice(idx, 1);
const fieldPath = pathName + `[${idx}]`;
form.destroyPath(fieldPath);
form.unsetInitialValue(fieldPath);
setInPath(form.values, pathName, newValue);
fields.value.splice(idx, 1);
afterMutation();
}
function push(initialValue) {
const value = klona(initialValue);
const pathName = toValue(arrayPath);
const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);
const normalizedPathValue = isNullOrUndefined(pathValue) ? [] : pathValue;
if (!Array.isArray(normalizedPathValue)) {
return;
}
const newValue = [...normalizedPathValue];
newValue.push(value);
form.stageInitialValue(pathName + `[${newValue.length - 1}]`, value);
setInPath(form.values, pathName, newValue);
fields.value.push(createEntry(value));
afterMutation();
}
function swap(indexA, indexB) {
const pathName = toValue(arrayPath);
const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);
if (!Array.isArray(pathValue) || !(indexA in pathValue) || !(indexB in pathValue)) {
return;
}
const newValue = [...pathValue];
const newFields = [...fields.value];
// the old switcheroo
const temp = newValue[indexA];
newValue[indexA] = newValue[indexB];
newValue[indexB] = temp;
const tempEntry = newFields[indexA];
newFields[indexA] = newFields[indexB];
newFields[indexB] = tempEntry;
setInPath(form.values, pathName, newValue);
fields.value = newFields;
updateEntryFlags();
}
function insert(idx, initialValue) {
const value = klona(initialValue);
const pathName = toValue(arrayPath);
const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);
if (!Array.isArray(pathValue) || pathValue.length < idx) {
return;
}
const newValue = [...pathValue];
const newFields = [...fields.value];
newValue.splice(idx, 0, value);
newFields.splice(idx, 0, createEntry(value));
setInPath(form.values, pathName, newValue);
fields.value = newFields;
afterMutation();
}
function replace(arr) {
const pathName = toValue(arrayPath);
form.stageInitialValue(pathName, arr);
setInPath(form.values, pathName, arr);
initFields();
afterMutation();
}
function update(idx, value) {
const pathName = toValue(arrayPath);
const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);
if (!Array.isArray(pathValue) || pathValue.length - 1 < idx) {
return;
}
setInPath(form.values, `${pathName}[${idx}]`, value);
form === null || form === void 0 ? void 0 : form.validate({ mode: 'validated-only' });
}
function prepend(initialValue) {
const value = klona(initialValue);
const pathName = toValue(arrayPath);
const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);
const normalizedPathValue = isNullOrUndefined(pathValue) ? [] : pathValue;
if (!Array.isArray(normalizedPathValue)) {
return;
}
const newValue = [value, ...normalizedPathValue];
setInPath(form.values, pathName, newValue);
form.stageInitialValue(pathName + `[0]`, value);
fields.value.unshift(createEntry(value));
afterMutation();
}
function move(oldIdx, newIdx) {
const pathName = toValue(arrayPath);
const pathValue = getFromPath(form === null || form === void 0 ? void 0 : form.values, pathName);
const newValue = isNullOrUndefined(pathValue) ? [] : [...pathValue];
if (!Array.isArray(pathValue) || !(oldIdx in pathValue) || !(newIdx in pathValue)) {
return;
}
const newFields = [...fields.value];
const movedItem = newFields[oldIdx];
newFields.splice(oldIdx, 1);
newFields.splice(newIdx, 0, movedItem);
const movedValue = newValue[oldIdx];
newValue.splice(oldIdx, 1);
newValue.splice(newIdx, 0, movedValue);
setInPath(form.values, pathName, newValue);
fields.value = newFields;
afterMutation();
}
const fieldArrayCtx = {
fields,
remove,
push,
swap,
insert,
update,
replace,
prepend,
move,
};
form.fieldArrays.push(Object.assign({ path: arrayPath, reset: initFields }, fieldArrayCtx));
onBeforeUnmount(() => {
const idx = form.fieldArrays.findIndex(i => toValue(i.path) === toValue(arrayPath));
if (idx >= 0) {
form.fieldArrays.splice(idx, 1);
}
});
// Makes sure to sync the form values with the array value if they go out of sync
// #4153
watch(getCurrentValues, formValues => {
const fieldsValues = fields.value.map(f => f.value);
// If form values are not the same as the current values then something overrode them.
if (!isEqual(formValues, fieldsValues)) {
initFields();
}
});
return fieldArrayCtx;
}
const FieldArrayImpl = /** #__PURE__ */ defineComponent({
name: 'FieldArray',
inheritAttrs: false,
props: {
name: {
type: String,
required: true,
},
},
setup(props, ctx) {
const { push, remove, swap, insert, replace, update, prepend, move, fields } = useFieldArray(() => props.name);
function slotProps() {
return {
fields: fields.value,
push,
remove,
swap,
insert,
update,
replace,
prepend,
move,
};
}
ctx.expose({
push,
remove,
swap,
insert,
update,
replace,
prepend,
move,
});
return () => {
const children = normalizeChildren(undefined, ctx, slotProps);
return children;
};
},
});
const FieldArray = FieldArrayImpl;
const ErrorMessageImpl = /** #__PURE__ */ defineComponent({
name: 'ErrorMessage',
props: {
as: {
type: String,
default: undefined,
},
name: {
type: String,
required: true,
},
},
setup(props, ctx) {
const form = inject(FormContextKey, undefined);
const message = computed(() => {
return form === null || form === void 0 ? void 0 : form.errors.value[props.name];
});
function slotProps() {
return {
message: message.value,
};
}
return () => {
// Renders nothing if there are no messages
if (!message.value) {
return undefined;
}
const tag = (props.as ? resolveDynamicComponent(props.as) : props.as);
const children = normalizeChildren(tag, ctx, slotProps);
const attrs = Object.assign({ role: 'alert' }, ctx.attrs);
// If no tag was specified and there are children
// render the slot as is without wrapping it
if (!tag && (Array.isArray(children) || !children) && (children === null || children === void 0 ? void 0 : children.length)) {
return children;
}
// If no children in slot
// render whatever specified and fallback to a <span> with the message in it's contents
if ((Array.isArray(children) || !children) && !(children === null || children === void 0 ? void 0 : children.length)) {
return h(tag || 'span', attrs, message.value);
}
return h(tag, attrs, children);
};
},
});
const ErrorMessage = ErrorMessageImpl;
function useResetForm() {
const form = injectWithSelf(FormContextKey);
if (!form) {
if ((process.env.NODE_ENV !== 'production')) {
warn('No vee-validate <Form /> or `useForm` was detected in the component tree');
}
}
return function resetForm(state) {
if (!form) {
return;
}
return form.resetForm(state);
};
}
/**
* If a field is dirty or not
*/
function useIsFieldDirty(path) {
const fieldOrPath = resolveFieldOrPathState(path);
return computed(() => {
var _a, _b;
if (!fieldOrPath) {
return false;
}
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;
});
}
/**
* If a field is touched or not
*/
function useIsFieldTouched(path) {
const fieldOrPath = resolveFieldOrPathState(path);
return computed(() => {
var _a, _b;
if (!fieldOrPath) {
return false;
}
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;
});
}
/**
* If a field is validated and is valid
*/
function useIsFieldValid(path) {
const fieldOrPath = resolveFieldOrPathState(path);
return computed(() => {
var _a, _b;
if (!fieldOrPath) {
return false;
}
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;
});
}
/**
* If the form is submitting or not
*/
function useIsSubmitting() {
const form = injectWithSelf(FormContextKey);
if (!form) {
if ((process.env.NODE_ENV !== 'production')) {
warn('No vee-validate <Form /> or `useForm` was detected in the component tree');
}
}
return computed(() => {
var _a;
return (_a = form === null || form === void 0 ? void 0 : form.isSubmitting.value) !== null && _a !== void 0 ? _a : false;
});
}
/**
* If the form is validating or not
*/
function useIsValidating() {
const form = injectWithSelf(FormContextKey);
if (!form) {
if ((process.env.NODE_ENV !== 'production')) {
warn('No vee-validate <Form /> or `useForm` was detected in the component tree');
}
}
return computed(() => {
var _a;
return (_a = form === null || form === void 0 ? void 0 : form.isValidating.value) !== null && _a !== void 0 ? _a : false;
});
}
/**
* Validates a single field
*/
function useValidateField(path) {
const form = injectWithSelf(FormContextKey);
const field = path ? undefined : inject(FieldContextKey);
return function validateField() {
if (field) {
return field.validate();
}
if (form && path) {
return form === null || form === void 0 ? void 0 : form.validateField(toValue(path));
}
if ((process.env.NODE_ENV !== 'production')) {
warn(`field with name ${unref(path)} was not found`);
}
return Promise.resolve({
errors: [],
valid: true,
});
};
}
/**
* If the form is dirty or not
*/
function useIsFormDirty() {
const form = injectWithSelf(FormContextKey);
if (!form) {
if ((process.env.NODE_ENV !== 'production')) {
warn('No vee-validate <Form /> or `useForm` was detected in the component tree');
}
}
return computed(() => {
var _a;
return (_a = form === null || form === void 0 ? void 0 : form.meta.value.dirty) !== null && _a !== void 0 ? _a : false;
});
}
/**
* If the form is touched or not
*/
function useIsFormTouched() {
const form = injectWithSelf(FormContextKey);
if (!form) {
if ((process.env.NODE_ENV !== 'production')) {
warn('No vee-validate <Form /> or `useForm` was detected in the component tree');
}
}
return computed(() => {
var _a;
return (_a = form === null || form === void 0 ? void 0 : form.meta.value.touched) !== null && _a !== void 0 ? _a : false;
});
}
/**
* If the form has been validated and is valid
*/
function useIsFormValid() {
const form = injectWithSelf(FormContextKey);
if (!form) {
if ((process.env.NODE_ENV !== 'production')) {
warn('No vee-validate <Form /> or `useForm` was detected in the component tree');
}
}
return computed(() => {
var _a;
return (_a = form === null || form === void 0 ? void 0 : form.meta.value.valid) !== null && _a !== void 0 ? _a : false;
});
}
/**
* Validate multiple fields
*/
function useValidateForm() {
const form = injectWithSelf(FormContextKey);
if (!form) {
if ((process.env.NODE_ENV !== 'production')) {
warn('No vee-validate <Form /> or `useForm` was detected in the component tree');
}
}
return function validateField() {
if (!form) {
return Promise.resolve({ results: {}, errors: {}, valid: true });
}
return form.validate();
};
}
/**
* The number of form's submission count
*/
function useSubmitCount() {
const form = injectWithSelf(FormContextKey);
if (!form) {
if ((process.env.NODE_ENV !== 'production')) {
warn('No vee-validate <Form /> or `useForm` was detected in the component tree');
}
}
return computed(() => {
var _a;
return (_a = form === null || form === void 0 ? void 0 : form.submitCount.value) !== null && _a !== void 0 ? _a : 0;
});
}
/**
* Gives access to a field's current value
*/
function useFieldValue(path) {
const form = injectWithSelf(FormContextKey);
// We don't want to use self injected context as it doesn't make sense
const field = path ? undefined : inject(FieldContextKey);
return computed(() => {
if (path) {
return getFromPath(form === null || form === void 0 ? void 0 : form.values, toValue(path));
}
return toValue(field === null || field === void 0 ? void 0 : field.value);
});
}
/**
* Gives access to a form's values
*/
function useFormValues() {
const form = injectWithSelf(FormContextKey);
if (!form) {
if ((process.env.NODE_ENV !== 'production')) {
warn('No vee-validate <Form /> or `useForm` was detected in the component tree');
}
}
return computed(() => {
return (form === null || form === void 0 ? void 0 : form.values) || {};
});
}
/**
* Gives access to all form errors
*/
function useFormErrors() {
const form = injectWithSelf(FormContextKey);
if (!form) {
if ((process.env.NODE_ENV !== 'production')) {
warn('No vee-validate <Form /> or `useForm` was detected in the component tree');
}
}
return computed(() => {
return ((form === null || form === void 0 ? void 0 : form.errors.value) || {});
});
}
/**
* Gives access to a single field error
*/
function useFieldError(path) {
const form = injectWithSelf(FormContextKey);
// We don't want to use self injected context as it doesn't make sense
const field = path ? undefined : inject(FieldContextKey);
return computed(() => {
if (path) {
return form === null || form === void 0 ? void 0 : form.errors.value[toValue(path)];
}
return field === null || field === void 0 ? void 0 : field.errorMessage.value;
});
}
function useSubmitForm(cb) {
const form = injectWithSelf(FormContextKey);
if (!form) {
if ((process.env.NODE_ENV !== 'production')) {
warn('No vee-validate <Form /> or `useForm` was detected in the component tree');
}
}
const onSubmit = form ? form.handleSubmit(cb) : undefined;
return function submitForm(e) {
if (!onSubmit) {
return;
}
return onSubmit(e);
};
}
/**
* Sets a field's error message
*/
function useSetFieldError(path) {
const form = injectWithSelf(FormContextKey);
// We don't want to use self injected context as it doesn't make sense
const field = path ? undefined : inject(FieldContextKey);
return function setFieldError(message) {
if (path && form) {
form.setFieldError(toValue(path), message);
return;
}
if (field) {
field.setErrors(message || []);
return;
}
if ((process.env.NODE_ENV !== 'production')) {
warn(`Could not set error message since there is no form context or a field named "${toValue(path)}", did you forget to call "useField" or "useForm"?`);
}
};
}
/**
* Sets a field's touched meta state
*/
function useSetFieldTouched(path) {
const form = injectWithSelf(FormContextKey);
// We don't want to use self injected context as it doesn't make sense
const field = path ? undefined : inject(FieldContextKey);
return function setFieldTouched(touched) {
if (path && form) {
form.setFieldTouched(toValue(path), touched);
return;
}
if (field) {
field.setTouched(touched);
return;
}
if ((process.env.NODE_ENV !== 'production')) {
warn(`Could not set touched state since there is no form context or a field named "${toValue(path)}", did you forget to call "useField" or "useForm"?`);
}
};
}
/**
* Sets a field's value
*/
function useSetFieldValue(path) {
const form = injectWithSelf(FormContextKey);
// We don't want to use self injected context as it doesn't make sense
const field = path ? undefined : inject(FieldContextKey);
return function setFieldValue(value, shouldValidate = true) {
if (path && form) {
form.setFieldValue(toValue(path), value, shouldValidate);
return;
}
if (field) {
field.setValue(value, shouldValidate);
return;
}
if ((process.env.NODE_ENV !== 'production')) {
warn(`Could not set value since there is no form context or a field named "${toValue(path)}", did you forget to call "useField" or "useForm"?`);
}
};
}
/**
* Sets multiple fields errors
*/
function useSetFormErrors() {
const form = injectWithSelf(FormContextKey);
function setFormErrors(fields) {
if (form) {
form.setErrors(fields);
return;
}
if ((process.env.NODE_ENV !== 'production')) {
warn(`Could not set errors because a form was not detected, did you forget to use "useForm" in a parent component?`);
}
}
return setFormErrors;
}
/**
* Sets multiple fields touched or all fields in the form
*/
function useSetFormTouched() {
const form = injectWithSelf(FormContextKey);
function setFormTouched(fields) {
if (form) {
form.setTouched(fields);
return;
}
if ((process.env.NODE_ENV !== 'production')) {
warn(`Could not set touched state because a form was not detected, did you forget to use "useForm" in a parent component?`);
}
}
return setFormTouched;
}
/**
* Sets multiple fields values
*/
function useSetFormValues() {
const form = injectWithSelf(FormContextKey);
function setFormValues(fields, shouldValidate = true) {
if (form) {
form.setValues(fields, shouldValidate);
return;
}
if ((process.env.NODE_ENV !== 'production')) {
warn(`Could not set form values because a form was not detected, did you forget to use "useForm" in a parent component?`);
}
}
return setFormValues;
}
export { ErrorMessage, Field, FieldArray, FieldContextKey, Form, FormContextKey, IS_ABSENT, cleanupNonNestedPath, configure, defineRule, isNotNestedPath, normalizeRules, useField, useFieldArray, useFieldError, useFieldValue, useForm, useFormErrors, useFormValues, useIsFieldDirty, useIsFieldTouched, useIsFieldValid, useIsFormDirty, useIsFormTouched, useIsFormValid, useIsSubmitting, useIsValidating, useResetForm, useSetFieldError, useSetFieldTouched, useSetFieldValue, useSetFormErrors, useSetFormTouched, useSetFormValues, useSubmitCount, useSubmitForm, useValidateField, useValidateForm, validate, validateObjectSchema as validateObject };