UNPKG

@wocwin/t-ui-plus

Version:

Page level components developed based on Element Plus.

259 lines (256 loc) 9.68 kB
import { defineComponent, useAttrs, useSlots, computed, resolveComponent, createBlock, openBlock, withCtx, createVNode, mergeProps, createSlots, renderList, unref, renderSlot, normalizeProps, guardReactiveProps, createElementBlock, toDisplayString, createElementVNode } from 'vue'; import { ElMessage } from 'element-plus'; import '../../../hooks/index.mjs'; import { useLocale } from '../../../hooks/useLocale.mjs'; const _hoisted_1 = { key: 0 }; const _hoisted_2 = { key: 0 }; var _sfc_main = /* @__PURE__ */ defineComponent({ ...{ name: "TInput" }, __name: "index", props: { modelValue: { default: "" }, placeholder: { default: "" }, decimalLimit: { default: 2 }, inputType: { default: "text" }, appendTitle: { default: "" }, showThousands: { type: Boolean, default: false }, isTip: { type: Boolean, default: false }, isShowErrorTip: { type: Boolean, default: false }, customErrorTip: { default: "" } }, emits: ["update:modelValue"], setup(__props, { emit: __emit }) { const { t } = useLocale(); const attrs = useAttrs(); const props = __props; const emits = __emit; const slots = useSlots(); const REGEX = { INTEGER: /^\d+$/, PHONE: /^1[3456789]\d{9}$/, ID_CARD: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/, NUMBER: /((^[1-9]\d*)|^0)(\.\d+)?$/, NUMBER_DECIMAL: /((^[1-9]\d*)|^0)(\.\d{0,2}){0,1}$/ }; const CHINESE = { DIGITS: ["\u96F6", "\u58F9", "\u8D30", "\u53C1", "\u8086", "\u4F0D", "\u9646", "\u67D2", "\u634C", "\u7396"], FRACTIONS: ["\u89D2", "\u5206"], UNITS: [ ["\u5143", "\u4E07", "\u4EBF", "\u5146"], ["", "\u62FE", "\u4F70", "\u4EDF"] ] }; const showTooltip = computed(() => props.isTip && !props.showThousands); const showAppend = computed(() => slots.append || props.inputType === "amount"); const placeholderText = computed(() => props.placeholder || t("plus.input.placeholder")); const appendTitleText = computed(() => props.appendTitle || t("plus.input.appendTitle")); const inputProps = computed(() => ({ placeholder: placeholderText.value, clearable: true, ...attrs })); const getInputRegex = () => { if (props.inputType instanceof RegExp) { return props.inputType; } switch (props.inputType) { case "integer": return REGEX.INTEGER; case "phone": return REGEX.PHONE; case "idCard": return REGEX.ID_CARD; default: return null; } }; const internalValue = computed({ get() { var _a; if (props.inputType === "integer" && props.modelValue != null) { return typeof props.modelValue === "number" ? String(props.modelValue) : props.modelValue; } return (_a = props.modelValue) != null ? _a : ""; }, set(val) { if (props.inputType === "integer") { if (!val || val === "") { emits("update:modelValue", null); } else { const str = String(val); const regex = getInputRegex(); emits("update:modelValue", (regex == null ? void 0 : regex.test(str)) ? Number(str) : str); } } else { emits("update:modelValue", val != null ? val : ""); } } }); const validate = (value, pattern, errorKey) => { if (pattern.test(value)) return value; if (props.isShowErrorTip) { const errorMsg = props.customErrorTip || (errorKey ? t(errorKey) : t("plus.input.validateError")); ElMessage.error(errorMsg); } return null; }; const formatAmount = (value) => { if (!value) { if (props.isShowErrorTip) { const msg = t("plus.input.format") + (props.inputType === "amount" ? t("plus.input.amount") : t("plus.input.numbers")); ElMessage.error(msg); } return ""; } const fixed = value.toFixed(props.decimalLimit); return props.showThousands ? fixed.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : fixed; }; const currencyFilter = (num, n = 2) => { if (!REGEX.NUMBER.test(String(num)) || num == null && num !== 0) return ""; const n2 = n > 0 && n <= 20 ? n : 2; const numStr = parseFloat(String(num).replace(/^\d\.-/g, "")).toFixed(n2); const [int, dec] = numStr.split("."); return `\uFFE5 ${int.replace(/\B(?=(\d{3})+(?!\d))/g, ",")}.${dec}`; }; const digitUppercase = (num) => { if (!REGEX.NUMBER_DECIMAL.test(String(num))) return t("plus.input.digitUppercase"); const isNegative = Number(num) < 0; let absNum = Math.abs(Number(num)); let result = ""; CHINESE.FRACTIONS.forEach((fraction, index) => { const digit = Math.floor(absNum * 10 * Math.pow(10, index)) % 10; result += (CHINESE.DIGITS[digit] + fraction).replace(/零./, ""); }); result = result || "\u6574"; let integerPart = Math.floor(absNum); for (let i = 0; i < CHINESE.UNITS[0].length && integerPart > 0; i++) { let section = ""; for (let j = 0; j < CHINESE.UNITS[1].length && integerPart > 0; j++) { section = CHINESE.DIGITS[integerPart % 10] + CHINESE.UNITS[1][j] + section; integerPart = Math.floor(integerPart / 10); } result = section.replace(/(零.)*零$/, "").replace(/^$/, "\u96F6") + CHINESE.UNITS[0][i] + result; } return (isNegative ? "\u6B20" : "") + result.replace(/(零.)*零元/, "\u5143").replace(/(零.)+/g, "\u96F6").replace(/^整$/, "\u96F6\u5143\u6574"); }; const handleBlur = () => { var _a, _b, _c; const val = internalValue.value; let formatted = val; if (props.inputType instanceof RegExp) { formatted = (_a = validate(String(val || ""), props.inputType)) != null ? _a : ""; internalValue.value = formatted; return; } switch (props.inputType) { case "amount": case "decimal": formatted = formatAmount(Number(val)); break; case "phone": formatted = (_b = validate(String(val || ""), REGEX.PHONE, "plus.input.validatePhone")) != null ? _b : ""; break; case "integer": { const result = validate(String(val || ""), REGEX.INTEGER, "plus.input.validateInteger"); formatted = result ? Number(result) : null; break; } case "idCard": formatted = (_c = validate(String(val || ""), REGEX.ID_CARD, "plus.input.validateIdCard")) != null ? _c : ""; break; } internalValue.value = formatted; }; return (_ctx, _cache) => { const _component_el_input = resolveComponent("el-input"); const _component_el_tooltip = resolveComponent("el-tooltip"); return showTooltip.value ? (openBlock(), createBlock(_component_el_tooltip, { key: 0, effect: "dark", placement: "bottom-start" }, { content: withCtx(() => [ createElementVNode( "div", null, toDisplayString(currencyFilter(_ctx.modelValue)), 1 /* TEXT */ ), createElementVNode( "div", null, toDisplayString(digitUppercase(_ctx.modelValue)), 1 /* TEXT */ ) ]), default: withCtx(() => [ createVNode(_component_el_input, mergeProps({ modelValue: internalValue.value, "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => internalValue.value = $event) }, inputProps.value, { onBlur: handleBlur }), createSlots({ _: 2 /* DYNAMIC */ }, [ renderList(unref(slots), (_, name) => { return { name, fn: withCtx((data) => [ renderSlot(_ctx.$slots, name, normalizeProps(guardReactiveProps(data))) ]) }; }), showAppend.value ? { name: "append", fn: withCtx(() => [ _ctx.inputType === "amount" ? (openBlock(), createElementBlock( "span", _hoisted_1, toDisplayString(appendTitleText.value), 1 /* TEXT */ )) : renderSlot(_ctx.$slots, "append", { key: 1 }) ]), key: "0" } : void 0 ]), 1040, ["modelValue"]) ]), _: 3 /* FORWARDED */ })) : (openBlock(), createBlock(_component_el_input, mergeProps({ key: 1, modelValue: internalValue.value, "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => internalValue.value = $event) }, inputProps.value, { onBlur: handleBlur }), createSlots({ _: 2 /* DYNAMIC */ }, [ renderList(unref(slots), (_, name) => { return { name, fn: withCtx((data) => [ renderSlot(_ctx.$slots, name, normalizeProps(guardReactiveProps(data))) ]) }; }), showAppend.value ? { name: "append", fn: withCtx(() => [ _ctx.inputType === "amount" ? (openBlock(), createElementBlock( "span", _hoisted_2, toDisplayString(appendTitleText.value), 1 /* TEXT */ )) : renderSlot(_ctx.$slots, "append", { key: 1 }) ]), key: "0" } : void 0 ]), 1040, ["modelValue"])); }; } }); export { _sfc_main as default };