UNPKG

@nutui/nutui-react

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

171 lines (170 loc) 6.48 kB
import { _ as __rest } from "./tslib.es6.js"; import React__default, { useState, useRef, useEffect } from "react"; import { Minus, Plus } from "@nutui/icons-react"; import classNames from "classnames"; import { u as usePropsValue } from "./use-props-value.js"; import { C as ComponentDefaults } from "./typings.js"; const defaultProps = Object.assign(Object.assign({}, ComponentDefaults), { disabled: false, readOnly: false, allowEmpty: false, min: 1, max: 9999, step: 1, digits: 0, async: false }); const classPrefix = `nut-inputnumber`; const InputNumber = (props) => { const _a = Object.assign(Object.assign({}, defaultProps), props), { children, disabled, min, max, readOnly, value, defaultValue, allowEmpty, digits, step, async, className, style, formatter, onPlus, onMinus, onOverlimit, onBlur, onFocus, onChange } = _a, restProps = __rest(_a, ["children", "disabled", "min", "max", "readOnly", "value", "defaultValue", "allowEmpty", "digits", "step", "async", "className", "style", "formatter", "onPlus", "onMinus", "onOverlimit", "onBlur", "onFocus", "onChange"]); const classes = classNames(classPrefix, className, { [`${classPrefix}-disabled`]: disabled }); const [focused, setFocused] = useState(false); const inputRef = useRef(null); useEffect(() => { var _a2, _b; if (focused) { (_b = (_a2 = inputRef.current) === null || _a2 === void 0 ? void 0 : _a2.select) === null || _b === void 0 ? void 0 : _b.call(_a2); } }, [focused]); const [shadowValue, setShadowValue] = usePropsValue({ value: typeof value === "string" ? parseFloat(value) : value, defaultValue: typeof defaultValue === "string" ? parseFloat(defaultValue) : defaultValue, finalValue: 0, onChange: (value2) => { } }); const bound = (value2, min2, max2) => { let res = value2; if (min2 !== void 0) { res = Math.max(Number(min2), res); } if (max2 !== void 0) { res = Math.min(Number(max2), res); } return res; }; const format = (value2) => { if (value2 === null) return ""; if (typeof value2 === "string") value2 = parseFloat(value2); const fixedValue = bound(value2, Number(min), Number(max)); if (formatter) { return formatter(fixedValue); } if (digits) { return fixedValue.toFixed(digits).toString(); } return fixedValue.toString(); }; const [inputValue, setInputValue] = useState(format(shadowValue)); useEffect(() => { if (!focused && !async) { setShadowValue(bound(Number(shadowValue), Number(min), Number(max))); setInputValue(format(shadowValue)); } }, [focused, shadowValue]); useEffect(() => { if (async) { setShadowValue(bound(Number(value), Number(min), Number(max))); setInputValue(format(value)); } }, [value]); const calcNextValue = (current, step2, symbol) => { const dig = digits + 1; return (parseFloat(current || "0") * dig + parseFloat(step2) * dig * symbol) / dig; }; const update = (negative, e) => { if (step !== void 0) { const shouldOverBoundary = calcNextValue(shadowValue, step, negative ? -1 : 1); const nextValue = bound(shouldOverBoundary, Number(min), Number(max)); setShadowValue(nextValue); if (negative ? shouldOverBoundary < Number(min) : shouldOverBoundary > Number(max)) { onOverlimit === null || onOverlimit === void 0 ? void 0 : onOverlimit(e); } else { onChange === null || onChange === void 0 ? void 0 : onChange(nextValue, e); } } }; const handleReduce = (e) => { if (disabled) return; onMinus === null || onMinus === void 0 ? void 0 : onMinus(e); update(true, e); }; const handlePlus = (e) => { if (disabled) return; onPlus === null || onPlus === void 0 ? void 0 : onPlus(e); update(false, e); }; const parseValue = (text) => { if (text === "") return null; if (text === "-") return null; return text; }; const clampValue = (valueStr) => { if (valueStr === null) return defaultValue; const val = Number(parseFloat(valueStr || "0").toFixed(digits)); return Math.max(Number(min), Math.min(Number(max), val)); }; const handleValueChange = (valueStr, e) => { const val = clampValue(valueStr); if (val !== Number(shadowValue)) { onChange === null || onChange === void 0 ? void 0 : onChange(val, e); } }; const handleInputChange = (e) => { setInputValue(e.target.value); const valueStr = parseValue(e.target.value); if (valueStr === null) { if (allowEmpty) { setShadowValue(null); } else { setShadowValue(defaultValue); } } else { setShadowValue(clampValue(valueStr)); } !async && handleValueChange(valueStr, e); }; const handleFocus = (e) => { setFocused(true); setInputValue(shadowValue !== void 0 && shadowValue !== null ? bound(Number(shadowValue), Number(min), Number(max)).toString() : ""); onFocus === null || onFocus === void 0 ? void 0 : onFocus(e); }; const handleBlur = (e) => { setFocused(false); onBlur === null || onBlur === void 0 ? void 0 : onBlur(e); const valueStr = parseValue(e.target.value); if (valueStr === null) { if (allowEmpty) { setShadowValue(null); } else { setShadowValue(defaultValue); } } else { setShadowValue(clampValue(valueStr)); } async && handleValueChange(valueStr, e); }; return React__default.createElement( "div", Object.assign({ className: classes, style }, restProps), React__default.createElement( "div", { className: "nut-input-minus", onClick: handleReduce }, React__default.createElement(Minus, { className: classNames("nut-inputnumber-icon icon-minus", { [`${classPrefix}-icon-disabled`]: shadowValue === min || disabled }) }) ), React__default.createElement("input", { ref: inputRef, inputMode: "decimal", disabled, readOnly, value: inputValue, onInput: handleInputChange, onBlur: handleBlur, onFocus: handleFocus }), React__default.createElement( "div", { className: "nut-input-add", onClick: handlePlus }, React__default.createElement(Plus, { className: classNames("nut-inputnumber-icon icon-plus", { [`${classPrefix}-icon-disabled`]: shadowValue === max || disabled }) }) ) ); }; InputNumber.displayName = "NutInputNumber"; export { InputNumber as default };