@vuesax-alpha/nightly
Version:
A Component Library for Vue 3
328 lines (325 loc) • 11.8 kB
JavaScript
import { defineComponent, ref, reactive, computed, toRef, watch, onMounted, onUpdated, openBlock, createElementBlock, normalizeClass, unref, normalizeStyle, withModifiers, withDirectives, withKeys, createVNode, withCtx, createCommentVNode } from 'vue';
import { isNil } from 'lodash-unified';
import { VsInput } from '../../input/index.mjs';
import { VsIcon } from '../../icon/index.mjs';
import '../../../directives/index.mjs';
import '../../../hooks/index.mjs';
import '../../../utils/index.mjs';
import { Minus, Plus } from '@vuesax-alpha/icons-vue';
import '../../../constants/index.mjs';
import { inputNumberProps, inputNumberEmits } from './input-number.mjs';
import _export_sfc from '../../../_virtual/plugin-vue_export-helper.mjs';
import { useNamespace } from '../../../hooks/use-namespace/index.mjs';
import { getVsColor } from '../../../utils/color.mjs';
import { useDisabled } from '../../../hooks/use-common-props/index.mjs';
import { isNumber, isUndefined } from '../../../utils/types.mjs';
import { debugWarn, throwError } from '../../../utils/error.mjs';
import { INPUT_EVENT, UPDATE_MODEL_EVENT, CHANGE_EVENT } from '../../../constants/event.mjs';
import { isString } from '@vue/shared';
import { RepeatClick } from '../../../directives/repeat-click/index.mjs';
const _hoisted_1 = ["onKeydown"];
const _hoisted_2 = ["onKeydown"];
const __default__ = defineComponent({
name: "VsInputNumber"
});
const _sfc_main = defineComponent({
...__default__,
props: inputNumberProps,
emits: inputNumberEmits,
setup(__props, { expose: __expose, emit }) {
const props = __props;
const ns = useNamespace("input-number");
const input = ref();
const data = reactive({
currentValue: props.modelValue,
userInput: null
});
const wrapperStyle = computed(() => ({
[ns.cssVarBlockName("color")]: getVsColor(props.color),
[ns.cssVarBlockName("background")]: getVsColor(props.background)
}));
const isDisabled = useDisabled(toRef(props, "disabled"));
const minDisabled = computed(
() => isNumber(props.modelValue) && props.modelValue <= props.min
);
const maxDisabled = computed(
() => isNumber(props.modelValue) && props.modelValue >= props.max
);
const numPrecision = computed(() => {
const stepPrecision = getPrecision(props.step);
if (!isUndefined(props.precision)) {
if (stepPrecision > props.precision) {
debugWarn(
"InputNumber",
"precision should not be less than the decimal places of step"
);
}
return props.precision;
} else {
return Math.max(getPrecision(props.modelValue), stepPrecision);
}
});
const displayValue = computed(() => {
if (data.userInput !== null) {
return data.userInput;
}
let currentValue = data.currentValue;
if (isNil(currentValue))
return "";
if (isNumber(currentValue)) {
if (Number.isNaN(currentValue))
return "";
if (!isUndefined(props.precision)) {
currentValue = currentValue.toFixed(props.precision);
}
}
return currentValue;
});
const toPrecision = (num, pre) => {
if (isUndefined(pre))
pre = numPrecision.value;
if (pre === 0)
return Math.round(num);
let snum = String(num);
const pointPos = snum.indexOf(".");
if (pointPos === -1)
return num;
const nums = snum.replace(".", "").split("");
const datum = nums[pointPos + pre];
if (!datum)
return num;
const length = snum.length;
if (snum.charAt(length - 1) === "5") {
snum = `${snum.slice(0, Math.max(0, length - 1))}6`;
}
return Number.parseFloat(Number(snum).toFixed(pre));
};
const getPrecision = (value) => {
if (isNil(value))
return 0;
const valueString = value.toString();
const dotPosition = valueString.indexOf(".");
let precision = 0;
if (dotPosition !== -1) {
precision = valueString.length - dotPosition - 1;
}
return precision;
};
const ensurePrecision = (val, coefficient = 1) => {
if (!isNumber(val))
return data.currentValue;
return toPrecision(val + props.step * coefficient);
};
const increase = () => {
if (props.readonly || isDisabled.value || maxDisabled.value)
return;
const value = Number(displayValue.value) || 0;
const newVal = ensurePrecision(value);
setCurrentValue(newVal);
emit(INPUT_EVENT, data.currentValue);
};
const decrease = () => {
if (props.readonly || isDisabled.value || minDisabled.value)
return;
const value = Number(displayValue.value) || 0;
const newVal = ensurePrecision(value, -1);
setCurrentValue(newVal);
emit(INPUT_EVENT, data.currentValue);
};
const verifyValue = (value, update) => {
const { max, min, step, precision, stepStrictly, valueOnClear } = props;
if (max < min) {
throwError("InputNumber", "min should not be greater than max.");
}
let newVal = Number(value);
if (isNil(value) || Number.isNaN(newVal)) {
return null;
}
if (value === "") {
if (valueOnClear === null) {
return null;
}
newVal = isString(valueOnClear) ? { min, max }[valueOnClear] : valueOnClear;
}
if (stepStrictly) {
newVal = toPrecision(Math.round(newVal / step) * step, precision);
}
if (!isUndefined(precision)) {
newVal = toPrecision(newVal, precision);
}
if (newVal > max || newVal < min) {
newVal = newVal > max ? max : min;
update && emit(UPDATE_MODEL_EVENT, newVal);
}
return newVal;
};
const setCurrentValue = (value, emitChange = true) => {
const oldVal = data.currentValue;
const newVal = verifyValue(value);
if (!emitChange) {
emit(UPDATE_MODEL_EVENT, newVal);
return;
}
if (oldVal === newVal)
return;
data.userInput = null;
emit(UPDATE_MODEL_EVENT, newVal);
emit(CHANGE_EVENT, newVal, oldVal);
data.currentValue = newVal;
};
const handleInput = (value) => {
data.userInput = value;
const newVal = value === "" ? null : Number(value);
emit(INPUT_EVENT, newVal);
setCurrentValue(newVal, false);
};
const handleInputChange = (value) => {
const newVal = value !== "" ? Number(value) : "";
if (isNumber(newVal) && !Number.isNaN(newVal) || value === "") {
setCurrentValue(newVal);
}
data.userInput = null;
};
const focus = () => {
var _a, _b;
(_b = (_a = input.value) == null ? void 0 : _a.focus) == null ? void 0 : _b.call(_a);
};
const blur = () => {
var _a, _b;
(_b = (_a = input.value) == null ? void 0 : _a.blur) == null ? void 0 : _b.call(_a);
};
const handleFocus = (event) => {
emit("focus", event);
};
const handleBlur = (event) => {
emit("blur", event);
};
watch(
() => props.modelValue,
(value) => {
const userInput = verifyValue(data.userInput);
const newValue = verifyValue(value, true);
if (!isNumber(userInput) && (!userInput || userInput !== newValue)) {
data.currentValue = newValue;
data.userInput = null;
}
},
{ immediate: true }
);
onMounted(() => {
var _a;
const { min, max, modelValue } = props;
const innerInput = (_a = input.value) == null ? void 0 : _a.inputRef;
innerInput.setAttribute("role", "spinbutton");
if (Number.isFinite(max)) {
innerInput.setAttribute("aria-valuemax", String(max));
} else {
innerInput.removeAttribute("aria-valuemax");
}
if (Number.isFinite(min)) {
innerInput.setAttribute("aria-valuemin", String(min));
} else {
innerInput.removeAttribute("aria-valuemin");
}
innerInput.setAttribute(
"aria-valuenow",
data.currentValue || data.currentValue === 0 ? String(data.currentValue) : ""
);
innerInput.setAttribute("aria-disabled", String(isDisabled.value));
if (!isNumber(modelValue) && modelValue != null) {
let val = Number(modelValue);
if (Number.isNaN(val)) {
val = null;
}
emit(UPDATE_MODEL_EVENT, val);
}
});
onUpdated(() => {
var _a, _b;
const innerInput = (_a = input.value) == null ? void 0 : _a.inputRef;
innerInput == null ? void 0 : innerInput.setAttribute("aria-valuenow", `${(_b = data.currentValue) != null ? _b : ""}`);
});
__expose({
focus,
blur
});
return (_ctx, _cache) => {
return openBlock(), createElementBlock(
"div",
{
class: normalizeClass([
unref(ns).b(),
unref(ns).is("disabled", unref(isDisabled)),
unref(ns).is("readonly", _ctx.readonly),
unref(ns).is("without-controls", !_ctx.controls)
]),
style: normalizeStyle(wrapperStyle.value),
onDragstart: _cache[1] || (_cache[1] = withModifiers(() => {
}, ["prevent"]))
},
[
_ctx.controls ? withDirectives((openBlock(), createElementBlock("span", {
key: 0,
role: "button",
class: normalizeClass([unref(ns).e("decrease"), unref(ns).is("disabled", minDisabled.value)]),
onKeydown: withKeys(decrease, ["enter"])
}, [
createVNode(unref(VsIcon), null, {
default: withCtx(() => [
createVNode(unref(Minus))
]),
_: 1
})
], 42, _hoisted_1)), [
[unref(RepeatClick), decrease]
]) : createCommentVNode("v-if", true),
_ctx.controls ? withDirectives((openBlock(), createElementBlock("span", {
key: 1,
role: "button",
class: normalizeClass([unref(ns).e("increase"), unref(ns).is("disabled", maxDisabled.value)]),
onKeydown: withKeys(increase, ["enter"])
}, [
createVNode(unref(VsIcon), null, {
default: withCtx(() => [
createVNode(unref(Plus))
]),
_: 1
})
], 42, _hoisted_2)), [
[unref(RepeatClick), increase]
]) : createCommentVNode("v-if", true),
createVNode(unref(VsInput), {
id: _ctx.id,
ref_key: "input",
ref: input,
type: "number",
block: "",
step: _ctx.step,
"model-value": displayValue.value,
placeholder: _ctx.placeholder,
readonly: _ctx.readonly,
disabled: unref(isDisabled),
max: _ctx.max,
min: _ctx.min,
name: _ctx.name,
label: _ctx.label,
onWheel: _cache[0] || (_cache[0] = withModifiers(() => {
}, ["prevent"])),
onKeydown: [
withKeys(withModifiers(increase, ["prevent"]), ["up"]),
withKeys(withModifiers(decrease, ["prevent"]), ["down"])
],
onBlur: handleBlur,
onFocus: handleFocus,
onInput: handleInput,
onChange: handleInputChange
}, null, 8, ["id", "step", "model-value", "placeholder", "readonly", "disabled", "max", "min", "name", "label", "onKeydown"])
],
38
);
};
}
});
var InputNumber = /* @__PURE__ */ _export_sfc(_sfc_main, [["__file", "/home/runner/work/vuesax-alpha/vuesax-alpha/packages/components/input-number/src/input-number.vue"]]);
export { InputNumber as default };
//# sourceMappingURL=input-number2.mjs.map