@opensig/opendesign
Version:
234 lines (233 loc) • 6.87 kB
JavaScript
import { useComposition } from "../hooks/use-composition.mjs";
import { isUndefined, isFunction, isNumber } from "../_utils/is.mjs";
import { Enter } from "../_utils/keycode.mjs";
import { ref, computed, watch, nextTick } from "vue";
function useInput(options) {
const {
modelValue,
defaultValue,
format,
emits,
emitUpdate,
validate,
valueOnInvalidChange,
maxLength,
minLength,
showLength,
calculateLength,
inputOnOutlimit,
onlyNumericInput
} = options;
const formatFn = (v) => {
return isFunction(format) ? format(v) : v;
};
const calculateStringLength = (v) => {
return isFunction(calculateLength) ? calculateLength(v) : v == null ? void 0 : v.length;
};
const uncontrolledValue = ref(defaultValue);
const controlledValue = modelValue;
const computedValue = computed(() => {
const cv = controlledValue == null ? void 0 : controlledValue.value;
const ucv = uncontrolledValue.value ?? "";
return cv ?? ucv;
});
const displayValue = ref(formatFn(computedValue.value));
const inputValueLength = computed(() => {
return calculateStringLength(computedValue.value);
});
const validateMaxLength = (length) => {
if (!isNumber(maxLength == null ? void 0 : maxLength.value)) {
return true;
}
return length <= maxLength.value;
};
const validateMinLength = (length) => {
if (!isNumber(minLength == null ? void 0 : minLength.value)) {
return true;
}
return length >= minLength.value;
};
const validateLengthFn = (value) => {
const len = calculateStringLength(value);
return validateMaxLength(len) && validateMinLength(len);
};
const isOutLengthLimit = computed(() => {
return !validateLengthFn(computedValue.value);
});
const mergedValidateFn = (v) => {
const r = validateLengthFn(v);
if (r && isFunction(validate)) {
return validate(v);
}
return r;
};
const inputEl = ref();
const composition = useComposition({ el: inputEl });
const isFocus = ref(false);
const isValid = ref(true);
const validateValue = (value) => {
isValid.value = value === "" ? true : mergedValidateFn(value);
return isValid.value;
};
watch(
() => [maxLength == null ? void 0 : maxLength.value, minLength == null ? void 0 : minLength.value],
() => {
validateValue(computedValue.value);
}
);
let lastValidValue = validateValue(computedValue.value) ? computedValue.value : "";
let lastValue = computedValue.value;
watch(
() => computedValue.value,
(val) => {
if (!isUndefined(val) && validateValue(val)) {
lastValidValue = val;
}
if (isFocus.value) {
displayValue.value = val;
} else {
displayValue.value = formatFn(val);
}
}
);
const updateValue = (value) => {
uncontrolledValue.value = value;
if (value !== computedValue.value) {
emitUpdate(value);
}
};
const getValidValue = () => {
let validVal = computedValue.value;
if (!isValid.value) {
if (isFunction(valueOnInvalidChange)) {
validVal = valueOnInvalidChange(computedValue.value, lastValidValue);
validateValue(validVal);
} else if (valueOnInvalidChange === true && lastValidValue !== "") {
validVal = lastValidValue;
isValid.value = true;
}
}
return validVal;
};
const emitChange = (value) => {
if (value !== lastValue) {
nextTick(() => {
emits("change", computedValue.value, lastValue);
lastValue = computedValue.value;
});
}
};
const keepNativeDisplayValue = () => {
if (inputEl.value && inputEl.value.value !== displayValue.value) {
inputEl.value.value = displayValue.value;
}
};
const isAllowedToInputOnOutLimit = (value) => {
if (!isUndefined(maxLength == null ? void 0 : maxLength.value) && (inputOnOutlimit == null ? void 0 : inputOnOutlimit.value) === true) {
return true;
}
const len = calculateStringLength(value);
const isLower = validateMaxLength(len);
if (isLower) {
return true;
}
if (len < calculateStringLength(computedValue.value)) {
return true;
}
return false;
};
const basicValidRegex = /^-?\d*\.?\d*$/;
const invalidFormatRegex = /-{2,}|\.{2,}|^-\.$|^-\.\d+$/;
const handleInput = (e) => {
var _a;
let value = (_a = e.target) == null ? void 0 : _a.value;
const currentValue = value;
if ((onlyNumericInput == null ? void 0 : onlyNumericInput.value) && !basicValidRegex.test(currentValue) || invalidFormatRegex.test(currentValue)) {
value = displayValue.value;
}
if (composition.isComposing.value) {
displayValue.value = value;
return;
}
let newValue = value;
if (!isAllowedToInputOnOutLimit(value)) {
newValue = value.substring(0, maxLength == null ? void 0 : maxLength.value);
}
updateValue(newValue);
emits("input", e, value);
nextTick(() => {
keepNativeDisplayValue();
});
};
const handleFocus = (e) => {
if (isFocus.value) {
return;
}
isFocus.value = true;
if (format) {
displayValue.value = computedValue.value;
}
emits("focus", e);
};
const handleBlur = (e) => {
isFocus.value = false;
const validValue = getValidValue();
updateValue(validValue);
emitChange(validValue);
displayValue.value = formatFn(computedValue.value);
emits("blur", e);
};
const handlePressEnter = (e) => {
const keyCode = e.key || e.code;
if (!composition.isComposing.value && keyCode === Enter.key) {
const validValue = getValidValue();
updateValue(validValue);
emitChange(validValue);
emits("pressEnter", e);
}
};
const clearValue = () => {
displayValue.value = "";
isValid.value = true;
updateValue("");
emitChange("");
emits("clear");
};
const handleClear = (e) => {
e.stopPropagation();
e.preventDefault();
clearValue();
};
const isShowLength = computed(() => {
if ((showLength == null ? void 0 : showLength.value) === "never") {
return false;
}
if ((showLength == null ? void 0 : showLength.value) === "always") {
return true;
}
const isSetLimit = !isUndefined(maxLength == null ? void 0 : maxLength.value) || !isUndefined(minLength == null ? void 0 : minLength.value);
if ((showLength == null ? void 0 : showLength.value) === "auto" && isSetLimit) {
return true;
}
return false;
});
return {
realValue: computed(() => computedValue.value),
displayValue: computed(() => displayValue.value),
isValid,
inputEl,
clearValue,
isFocus,
inputValueLength,
isShowLength,
isOutLengthLimit,
handleInput,
handleFocus,
handleBlur,
handlePressEnter,
handleClear
};
}
export {
useInput
};