UNPKG

@nutui/nutui-react

Version:

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

147 lines (146 loc) 5.74 kB
import { _ as __rest } from "./tslib.es6.js"; import React__default, { forwardRef, useRef, useState, useImperativeHandle, useCallback } from "react"; import { MaskClose } from "@nutui/icons-react"; import { useRtl, useConfig } from "./ConfigProvider.js"; import { C as ComponentDefaults } from "./typings.js"; import { u as usePropsValue } from "./use-props-value.js"; function trimExtraChar(value, char, regExp) { const index = value.indexOf(char); if (index === -1) { return value; } if (char === "-" && index !== 0) { return value.slice(0, index); } return value.slice(0, index + 1) + value.slice(index).replace(regExp, ""); } function formatNumber(value, allowDot = true, allowMinus = true) { if (allowDot) { value = trimExtraChar(value, ".", /\./g); } else { value = value.split(".")[0]; } if (allowMinus) { value = trimExtraChar(value, "-", /-/g); } else { value = value.replace(/-/, ""); } const regExp = allowDot ? /[^-0-9.]/g : /[^-0-9]/g; return value.replace(regExp, ""); } const defaultProps = Object.assign(Object.assign({}, ComponentDefaults), { type: "text", name: "", placeholder: void 0, confirmType: "done", align: "left", required: false, disabled: false, readOnly: false, maxLength: 9999, clearable: false, clearIcon: null, formatTrigger: "onChange", autoFocus: false }); const Input = forwardRef((props, ref) => { const rtl = useRtl(); const { locale } = useConfig(); const _a = Object.assign(Object.assign({}, defaultProps), props), { type, name, placeholder, align, disabled, readOnly, maxLength, clearable, clearIcon, formatTrigger, autoFocus, style, className, onChange, onFocus, onClear, formatter, onClick, confirmType, defaultValue, value: _value, onCompositionStart, onCompositionEnd } = _a, rest = __rest(_a, ["type", "name", "placeholder", "align", "disabled", "readOnly", "maxLength", "clearable", "clearIcon", "formatTrigger", "autoFocus", "style", "className", "onChange", "onFocus", "onClear", "formatter", "onClick", "confirmType", "defaultValue", "value", "onCompositionStart", "onCompositionEnd"]); const [value, setValue] = usePropsValue({ value: _value, defaultValue, finalValue: "", onChange }); const inputRef = useRef(null); const composingRef = useRef(false); const [active, setActive] = useState(false); useImperativeHandle(ref, () => { return { clear: () => { setValue(""); }, focus: () => { var _a2; (_a2 = inputRef.current) === null || _a2 === void 0 ? void 0 : _a2.focus(); }, blur: () => { var _a2; (_a2 = inputRef.current) === null || _a2 === void 0 ? void 0 : _a2.blur(); }, get nativeElement() { return inputRef.current; } }; }); const inputClass = useCallback(() => { const classPrefix = "nut-input"; return [classPrefix, `${disabled ? `${classPrefix}-disabled` : ""}`].filter(Boolean).join(" "); }, [disabled]); const updateValue = (value2, trigger = "onChange") => { let val = value2; if (type === "number") { val = formatNumber(val, false, true); } if (type === "digit") { val = formatNumber(val, true, true); } if (formatter && trigger === formatTrigger) { val = formatter(val); } setValue(val); const eventHandler = props[trigger]; if (eventHandler && typeof eventHandler === "function" && trigger !== "onChange") { eventHandler(val); } }; const handleFocus = (event) => { const val = event.target.value; onFocus && onFocus(val); setActive(true); }; const handleInput = (value2) => { updateValue(value2, "onChange"); }; const handleBlur = (event) => { const val = event.target.value; updateValue(val, "onBlur"); setTimeout(() => { setActive(false); }, 200); }; const inputType = (type2) => { if (type2 === "digit") { return "text"; } if (type2 === "number") { return "tel"; } return type2; }; return React__default.createElement( "div", { className: `${inputClass()} ${className || ""}`, style, onClick: (e) => { onClick && onClick(e); } }, React__default.createElement("input", Object.assign({}, rest, { name, className: "nut-input-native", ref: inputRef, style: { // eslint-disable-next-line no-nested-ternary textAlign: rtl ? ( // eslint-disable-next-line no-nested-ternary align === "right" ? ( // eslint-disable-next-line no-nested-ternary "left" ) : align === "left" ? "right" : "center" ) : align }, type: inputType(type), maxLength, placeholder: placeholder === void 0 ? locale.placeholder : placeholder, disabled, readOnly, value, autoFocus, enterKeyHint: confirmType, onBlur: (e) => { handleBlur(e); }, onFocus: (e) => { handleFocus(e); }, onChange: (e) => { handleInput(e.currentTarget.value); }, onCompositionStart: (e) => { composingRef.current = true; onCompositionStart === null || onCompositionStart === void 0 ? void 0 : onCompositionStart(e); }, onCompositionEnd: (e) => { composingRef.current = false; onCompositionEnd === null || onCompositionEnd === void 0 ? void 0 : onCompositionEnd(e); } })), clearable && !readOnly && active && value.length > 0 ? React__default.createElement("span", { style: { display: "flex", alignItems: "center", cursor: "pointer" }, onClick: () => { if (!disabled) { setValue(""); onClear && onClear(""); } } }, clearIcon || React__default.createElement(MaskClose, { className: "nut-input-clear" })) : null ); }); Input.displayName = "NutInput"; export { Input as default };