@nutui/nutui-react
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
147 lines (146 loc) • 5.74 kB
JavaScript
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
};