UNPKG

@oruga-ui/oruga-next

Version:

UI components for Vue.js and CSS framework agnostic

233 lines (232 loc) 7.99 kB
/*! Oruga v0.11.0 | MIT License | github.com/oruga-ui/oruga */ import { computed, ref, watchEffect, watch, triggerRef, nextTick } from "vue"; import { i as injectField } from "./fieldInjection-DJwnFcxS.mjs"; import { u as unrefElement } from "./unrefElement-cze__WCi.mjs"; import { e as isSSR, c as getOption } from "./config-Dl7tu_Ly.mjs"; import { isDefined } from "./helpers.mjs"; const validatableFormElementTypes = isSSR ? [] : [ HTMLButtonElement, HTMLFieldSetElement, HTMLInputElement, HTMLObjectElement, HTMLOutputElement, HTMLSelectElement, HTMLTextAreaElement ]; function asValidatableFormElement(el) { return validatableFormElementTypes.some((t) => el instanceof t) ? el : null; } const constraintValidationAttributes = [ "disabled", "required", "pattern", "maxlength", "minlength", "max", "min", "step" ]; function useInputHandler(inputRef, emits, props) { const { parentField } = injectField(); const maybeElement = computed(() => { const el = unrefElement(inputRef); if (!el) return void 0; if (el.getAttribute("data-oruga-input")) return el; const inputs = el.querySelector("[data-oruga-input]"); if (!inputs) { console.warn( "useInputHandler: Underlaying Oruga input component not found" ); return void 0; } return inputs; }); const element = computed(() => { const el = maybeElement.value; if (!el) console.warn("useInputHandler: inputRef contains no element"); return el; }); const isFocused = ref(false); function setFocus() { nextTick(() => { if (element.value) element.value.focus(); }); } function doClick() { nextTick(() => { if (element.value) element.value.click(); }); } function onBlur(event) { isFocused.value = false; if (parentField == null ? void 0 : parentField.value) parentField.value.setFocus(false); emits("blur", event ? event : new Event("blur")); checkHtml5Validity(); } function onFocus(event) { isFocused.value = true; if (parentField == null ? void 0 : parentField.value) parentField.value.setFocus(true); emits("focus", event ? event : new Event("focus")); } const isValid = ref(true); function setFieldValidity(variant, message) { nextTick(() => { if (parentField == null ? void 0 : parentField.value) { if (!parentField.value.props.variant) parentField.value.setVariant(variant); if (!parentField.value.props.message) parentField.value.setMessage(message); } }); } function checkHtml5Validity() { if (!props.useHtml5Validation) return; if (!element.value) return; if (element.value.validity.valid) { setFieldValidity(null, null); isValid.value = true; } else { setInvalid(); isValid.value = false; } } function setInvalid() { var _a; const variant = "danger"; const message = (_a = element.value) == null ? void 0 : _a.validationMessage; setFieldValidity(variant, message); } function onInvalid(event) { checkHtml5Validity(); const validatable = asValidatableFormElement(event.target); if (validatable && (parentField == null ? void 0 : parentField.value) && props.useHtml5Validation) { event.preventDefault(); let isFirstInvalid = false; if (validatable.form != null) { const formElements = validatable.form.elements; for (let i = 0; i < formElements.length; ++i) { const element2 = asValidatableFormElement( formElements.item(i) ); if ((element2 == null ? void 0 : element2.willValidate) && !element2.validity.valid) { isFirstInvalid = validatable === element2; break; } } } if (isFirstInvalid) { const fieldElement = parentField.value.$el; const invalidHandler = getOption("invalidHandler"); if (invalidHandler instanceof Function) { invalidHandler(validatable, fieldElement ?? void 0); } else { const canScrollToField = (fieldElement == null ? void 0 : fieldElement.scrollIntoView) != void 0; validatable.focus({ preventScroll: canScrollToField }); if (canScrollToField && fieldElement) { fieldElement.scrollIntoView({ block: "nearest" }); } } } } emits("invalid", event); } if (!isSSR) { const forceValidationUpdate = ref(null); watchEffect(() => { forceValidationUpdate.value; if (!(props.useHtml5Validation ?? true)) return; const element2 = maybeElement.value; if (!isDefined(element2)) return; const validity = props.customValidity ?? ""; if (typeof validity === "string") { element2.setCustomValidity(validity); } else { element2.setCustomValidity( validity(props.modelValue, element2.validity) ); } if (!isValid.value) checkHtml5Validity(); }); watch( [maybeElement, () => props.useHtml5Validation ?? true], (newItems, oldItems) => { const newElement = newItems[0]; const newUseValidation = newItems[1]; const oldElement = oldItems[0]; const oldUseValidation = oldItems[1]; if (newElement !== oldElement) { oldElement == null ? void 0 : oldElement.setCustomValidity(""); } else if (oldUseValidation && !newUseValidation) { newElement == null ? void 0 : newElement.setCustomValidity(""); } } ); const onAttributeChange = () => { triggerRef(forceValidationUpdate); }; let validationAttributeObserver = null; watch( [ maybeElement, isValid, () => props.useHtml5Validation ?? true, () => props.customValidity ], (newData, oldData) => { const el = newData[0]; const valid = newData[1]; const useValidation = newData[2]; const functionalValidation = newData[3] instanceof Function; const oldEl = oldData[0]; const needWatcher = isDefined(el) && useValidation && // For inputs known to be invalid, changes in constraint validation properties // may make it so the field is now valid and the message needs to be hidden. // For browser-implemented constraint validation (e.g. the `required` attribute), // we just care about the message displayed to the user, which is hidden for valid inputs // until the next interaction with the control. (!valid || // For inputs with complex custom validation, any changes to validation-related attributes // may affect the results of `props.customValidity`. functionalValidation); if ((!needWatcher || el !== oldEl) && validationAttributeObserver != null) { if (validationAttributeObserver.takeRecords().length > 0) onAttributeChange(); validationAttributeObserver.disconnect(); validationAttributeObserver = null; } if (needWatcher && isDefined(el) && (validationAttributeObserver == null || el !== oldEl)) { if (validationAttributeObserver == null) { validationAttributeObserver = new MutationObserver( onAttributeChange ); } validationAttributeObserver.observe(el, { attributeFilter: constraintValidationAttributes }); let ancestor = el; while (ancestor = ancestor.parentNode) { if (ancestor instanceof HTMLFieldSetElement) { validationAttributeObserver.observe(ancestor, { attributeFilter: ["disabled"] }); } } } } ); } return { input: element, isFocused, isValid, setFocus, doClick, onFocus, onBlur, onInvalid, checkHtml5Validity }; } export { useInputHandler as u }; //# sourceMappingURL=useInputHandler-Cv7NmM5J.mjs.map