maz-ui
Version:
A standalone components library for Vue.Js 3 & Nuxt.Js 3
101 lines (100 loc) • 4.04 kB
JavaScript
import { e as getContext, f as fieldHasValidation, i as updateFieldState, j as isEqual, k as setFieldValidationState, l as getValidationEvents, h as hasModeIncludes, r as removeEventFromInteractiveElements, m as findInteractiveElements, n as addEventToInteractiveElements, o as handleFieldBlur } from "../chunks/dom-events.CfOiauCR.js";
import { computed, onMounted, onUnmounted } from "vue";
import { useFreezeValue } from "./useFreezeValue.js";
function useFormField(name, options) {
const opts = {
formIdentifier: "main-form-validator",
...options
}, {
fieldsStates,
payload,
options: formOptions,
internalSchema,
errorMessages,
isSubmitted
} = getContext(opts.formIdentifier, "useFormField"), finalOpts = opts, fieldMode = fieldHasValidation(name, internalSchema.value) ? options?.mode ?? formOptions.mode : void 0;
finalOpts.mode = fieldMode;
const fieldState = computed(() => fieldsStates.value[name]);
if (fieldsStates.value[name] = updateFieldState({
name,
fieldState: fieldState.value,
payload: payload.value,
schema: internalSchema.value,
options: { ...formOptions, ...finalOpts }
}), finalOpts.defaultValue !== void 0 && !isEqual(payload.value[name], finalOpts.defaultValue)) {
const initialValue = finalOpts.defaultValue;
payload.value[name] = initialValue, fieldsStates.value[name].initialValue = useFreezeValue(initialValue);
}
fieldMode && setFieldValidationState({
name,
fieldState: fieldState.value,
payload: payload.value,
schema: internalSchema.value,
setError: fieldMode === "aggressive",
setErrorIfInvalidAndNotEmpty: fieldMode === "lazy"
});
function onBlur() {
handleFieldBlur({
name,
fieldState: fieldState.value,
payload: payload.value,
schema: internalSchema.value,
isSubmitted: isSubmitted.value
});
}
const validationEvents = computed(
() => getValidationEvents({
hasRef: !!finalOpts.ref?.value,
onBlur,
fieldState: fieldState.value
})
);
if (finalOpts.ref && fieldMode && hasModeIncludes(["eager", "blur", "progressive"], fieldMode)) {
let interactiveElements = [];
const handleInteractiveElements = (element) => {
interactiveElements.length > 0 && removeEventFromInteractiveElements({
interactiveElements,
onBlur
}), interactiveElements = findInteractiveElements(element), addEventToInteractiveElements({
interactiveElements,
onBlur,
mode: fieldMode
});
};
onMounted(() => {
const element = finalOpts.ref?.value, elementToBind = element instanceof HTMLElement ? element : element?.$el;
if (elementToBind instanceof HTMLElement) {
handleInteractiveElements(elementToBind);
return;
} else if (elementToBind instanceof Text && elementToBind.nextElementSibling instanceof HTMLElement) {
handleInteractiveElements(elementToBind.nextElementSibling);
return;
}
console.warn(`[maz-ui](useFormField) No element found for ref in field '${String(name)}'. Make sure the ref is properly bound to an HTMLElement or Vue component (form identifier: ${String(formOptions.identifier)})`);
}), onUnmounted(() => {
removeEventFromInteractiveElements({
interactiveElements,
onBlur
});
});
}
return {
hasError: computed(() => fieldState.value.error),
errors: computed(() => fieldState.value.errors),
errorMessage: computed(() => errorMessages.value[name]),
isValid: computed(() => fieldState.value.valid),
isDirty: computed(() => fieldState.value.dirty),
isBlurred: computed(() => fieldState.value.blurred),
isValidated: computed(() => fieldState.value.validated),
isValidating: computed(() => fieldState.value.validating),
mode: computed(() => fieldState.value.mode),
value: computed({
get: () => payload.value[name],
set: (value) => payload.value[name] = value
}),
validationEvents
};
}
export {
useFormField
};