UNPKG

mobile-more

Version:

基于 antd-mobile v5 扩展移动端 UI 组件

184 lines (183 loc) 7.39 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; var _excluded = ["type", "disabledWhiteSpace", "prefix", "suffix", "onBlur", "max", "min", "precision", "useFloor", "inputMode", "format", "maxLength"]; import React from 'react'; import { floor, isUndefined } from 'ut2'; import { calculateCursorPosition } from 'util-helpers'; import { useControllableValue } from 'rc-hooks'; import { Input } from 'antd-mobile'; import { prefixClass } from "../../../config"; import { normalizeBankCard, normalizeEmail, normalizeIdCard, normalizeMobile, normalizeNotWhiteSpace, normalizeNumber } from "../utils/normalize"; import "./SuperInput.css"; var prefixCls = "".concat(prefixClass, "-input"); var SuperInput = /*#__PURE__*/React.forwardRef(function (_ref, ref) { var type = _ref.type, disabledWhiteSpace = _ref.disabledWhiteSpace, prefix = _ref.prefix, suffix = _ref.suffix, onBlur = _ref.onBlur, _ref$max = _ref.max, max = _ref$max === void 0 ? Number.MAX_SAFE_INTEGER : _ref$max, _ref$min = _ref.min, min = _ref$min === void 0 ? Number.MIN_SAFE_INTEGER : _ref$min, precision = _ref.precision, useFloor = _ref.useFloor, inputMode = _ref.inputMode, _ref$format = _ref.format, format = _ref$format === void 0 ? true : _ref$format, maxLength = _ref.maxLength, restProps = _objectWithoutProperties(_ref, _excluded); var internalRef = React.useRef(null); var _useControllableValue = useControllableValue(restProps), _useControllableValue2 = _slicedToArray(_useControllableValue, 2), state = _useControllableValue2[0], setState = _useControllableValue2[1]; var maxLen = React.useMemo(function () { if (!isUndefined(maxLength)) { return maxLength; } if (!format) { if (type === 'mobile') { return 11; } else if (type === 'idCard') { return 18; } } return undefined; }, [format, maxLength, type]); var needAdjustPos = React.useMemo(function () { return format && (type === 'mobile' || type === 'bankCard' || type === 'idCard' || type === 'number' || disabledWhiteSpace); }, [disabledWhiteSpace, format, type]); var realType = React.useMemo(function () { if (type === 'mobile') { return 'tel'; } if (type === 'bankCard' || type === 'idCard' || type === 'number' || type === 'email') { return 'text'; } return type; }, [type]); var realInputMode = React.useMemo(function () { if (!inputMode && type === 'number') { return 'decimal'; } return inputMode; }, [type, inputMode]); var calcPosOpts = React.useMemo(function () { var ret = {}; if (type === 'bankCard') { ret.type = 'bankCard'; } else if (type === 'mobile') { ret.type = 'mobile'; } else if (type === 'idCard') { ret.maskReg = /[^\dx]/gi; ret.placeholderChars = []; } else if (type === 'number') { ret.maskReg = /[^\d\\.-]/g; ret.placeholderChars = []; } else if (disabledWhiteSpace) { ret.maskReg = /\s/g; ret.placeholderChars = []; } return ret; }, [type, disabledWhiteSpace]); var normalize = React.useCallback(function (val) { var newValue = val; if (type === 'mobile') { newValue = normalizeMobile(val, format); } else if (type === 'bankCard') { newValue = normalizeBankCard(val, format); } else if (type === 'idCard') { newValue = normalizeIdCard(val, format); } else if (type === 'number') { newValue = normalizeNumber(val); } else if (type === 'email') { newValue = normalizeEmail(val); } else if (disabledWhiteSpace) { newValue = normalizeNotWhiteSpace(val); } return newValue; }, [disabledWhiteSpace, format, type]); var handleChange = React.useCallback(function (val) { var _internalRef$current, _internalRef$current2; var inputElement = (_internalRef$current = internalRef.current) === null || _internalRef$current === void 0 ? void 0 : _internalRef$current.nativeElement; var prevPos = (_internalRef$current2 = internalRef.current) === null || _internalRef$current2 === void 0 || (_internalRef$current2 = _internalRef$current2.nativeElement) === null || _internalRef$current2 === void 0 ? void 0 : _internalRef$current2.selectionEnd; var nextCtrlValue = normalize(val); setState(nextCtrlValue); if (inputElement && needAdjustPos) { var adjustPos = calculateCursorPosition(prevPos, state, val, nextCtrlValue, calcPosOpts); if (inputElement) { if (val !== nextCtrlValue) { window.setTimeout(function () { inputElement.selectionStart = inputElement.selectionEnd = adjustPos; }); } else { inputElement.selectionStart = inputElement.selectionEnd = adjustPos; } } } }, [normalize, setState, needAdjustPos, state, calcPosOpts]); // 处理最大最小值,以及精度 var handelBlur = React.useCallback(function (e) { if (type === 'number' && state) { var numberValue = Number(state); if (numberValue > max) { numberValue = max; } else if (numberValue < min) { numberValue = min; } var newValue = typeof precision === 'number' && precision >= 0 ? (useFloor ? floor(numberValue, precision) : numberValue).toFixed(precision) : String(numberValue); if (newValue !== state) { setState(newValue); } } onBlur === null || onBlur === void 0 || onBlur(e); }, [type, state, onBlur, max, min, precision, useFloor, setState]); var triggerFocus = React.useCallback(function () { var _internalRef$current3; var inputEl = (_internalRef$current3 = internalRef.current) === null || _internalRef$current3 === void 0 ? void 0 : _internalRef$current3.nativeElement; if (inputEl) { var startPos = inputEl.selectionStart; var endPos = inputEl.selectionEnd; inputEl.focus(); window.setTimeout(function () { inputEl.setSelectionRange(startPos, endPos); }); } }, []); React.useImperativeHandle(ref, function () { return _objectSpread(_objectSpread({}, internalRef.current), {}, { focus: triggerFocus }); }, [triggerFocus]); React.useEffect(function () { // 处理直接通过 form.setFieldsValue 或 initialValues if (state && needAdjustPos) { var newValue = normalize(state); if (newValue !== state) { handleChange(newValue); } } }, [handleChange, needAdjustPos, normalize, type, state]); return /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls) }, prefix && /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-prefix") }, prefix), /*#__PURE__*/React.createElement(Input, _extends({ inputMode: realInputMode, ref: internalRef, autoComplete: "off" }, restProps, { type: realType, value: state, onChange: handleChange, onBlur: handelBlur, maxLength: maxLen })), suffix && /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-suffix") }, suffix)); }); SuperInput.displayName = 'SuperInput'; export default SuperInput;