taro-ui-vue3
Version:
Taro UI Rewritten in Vue 3.0
204 lines (203 loc) • 5.64 kB
JavaScript
import {h, defineComponent, computed, mergeProps} from "vue";
import _toString from "lodash-es/toString";
import {pxTransform} from "../utils/common";
import {Input, Text, View} from "@tarojs/components";
function addNum(num1, num2) {
let sq1, sq2;
try {
sq1 = _toString(num1).split(".")[1].length;
} catch (e) {
sq1 = 0;
}
try {
sq2 = _toString(num2).split(".")[1].length;
} catch (e) {
sq2 = 0;
}
const m = Math.pow(10, Math.max(sq1, sq2));
return (Math.round(num1 * m) + Math.round(num2 * m)) / m;
}
function parseValue(num) {
if (num === "")
return "0";
const numStr = _toString(num);
if (numStr.indexOf("0") === 0 && numStr.indexOf(".") === -1) {
return _toString(parseFloat(num));
}
return _toString(num);
}
const AtInputNumber = defineComponent({
name: "AtInputNumber",
props: {
type: {
type: String,
default: "number"
},
value: {
type: [Number, String],
default: 1
},
style: String,
min: {
type: Number,
default: 0
},
max: {
type: Number,
default: 100
},
step: {
type: Number,
default: 1
},
size: {
type: String,
default: "normal"
},
width: {
type: Number,
default: 120
},
disabled: Boolean,
disabledInput: Boolean,
onChange: Function,
onBlur: Function,
onErrorInput: Function
},
setup(props, {attrs, emit}) {
const inputValue = computed({
get: () => Number(handleValue(props.value)),
set: (value) => emit("update:value", value)
});
const inputStyle = computed(() => ({
width: props.width ? `${pxTransform(props.width)}` : ""
}));
const rootClasses = computed(() => ({
"at-input-number": true,
"at-input-number--lg": props.size === "large"
}));
const minusBtnClasses = computed(() => ({
"at-input-number__btn": true,
"at-input-number--disabled": inputValue.value <= props.min || props.disabled
}));
const plusBtnClasses = computed(() => ({
"at-input-number__btn": true,
"at-input-number--disabled": inputValue.value >= props.max || props.disabled
}));
function handleClick(clickType, e) {
var _a;
const belowMin = clickType === "minus" && inputValue.value <= props.min;
const overMax = clickType === "plus" && inputValue.value >= props.max;
if (belowMin || overMax || props.disabled) {
const deltaValue2 = clickType === "minus" ? -props.step : props.step;
const errorValue = addNum(inputValue.value, deltaValue2);
if (props.disabled) {
handleError({
type: "DISABLED",
errorValue
});
} else {
handleError({
type: belowMin ? "LOW" : "OVER",
errorValue
});
}
return;
}
const deltaValue = clickType === "minus" ? -props.step : props.step;
let newValue = addNum(inputValue.value, deltaValue);
newValue = Number(handleValue(newValue));
if (attrs["onUpdate:value"]) {
inputValue.value = newValue;
} else {
(_a = props.onChange) == null ? void 0 : _a.call(props, newValue, e);
}
}
function handleValue(value) {
let resultValue = value === "" ? props.min : value;
if (resultValue > props.max) {
resultValue = props.max;
handleError({
type: "OVER",
errorValue: resultValue
});
}
if (resultValue < props.min) {
resultValue = props.min;
handleError({
type: "LOW",
errorValue: resultValue
});
}
if (resultValue && !Number(resultValue)) {
resultValue = parseFloat(String(resultValue)) || props.min;
handleError({
type: "OVER",
errorValue: resultValue
});
}
resultValue = parseValue(String(resultValue));
return resultValue;
}
function handleInput(e) {
var _a;
if (props.disabled)
return;
const {value} = e.target;
const newValue = handleValue(value);
if (attrs["onUpdate:value"]) {
inputValue.value = Number(newValue);
} else {
(_a = props.onChange) == null ? void 0 : _a.call(props, Number(newValue), e);
}
}
function handleBlur(e) {
var _a;
(_a = props.onBlur) == null ? void 0 : _a.call(props, e);
}
function handleError(errorValue) {
if (!props.onErrorInput)
return;
props.onErrorInput(errorValue);
}
return () => h(View, mergeProps(attrs, {
class: rootClasses.value
}), {
default: () => [
h(View, {
class: minusBtnClasses.value,
onTap: handleClick.bind(this, "minus")
}, {
default: () => [
h(Text, {
class: "at-icon at-icon-subtract at-input-number__btn-subtract"
})
]
}),
h(Input, {
class: "at-input-number__input",
style: inputStyle.value,
type: props.type,
value: String(inputValue.value),
disabled: props.disabledInput || props.disabled,
onBlur: handleBlur,
onInput: handleInput
}),
h(View, {
class: plusBtnClasses.value,
onTap: handleClick.bind(this, "plus")
}, {
default: () => [
h(Text, {
class: "at-icon at-icon-add at-input-number__btn-add"
})
]
})
]
});
}
});
var input_number_default = AtInputNumber;
export {
input_number_default as default
};