UNPKG

choerodon-ui

Version:

An enterprise-class UI design language and React-based implementation

779 lines (650 loc) 24.5 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _classnames = _interopRequireDefault(require("classnames")); var _noop = _interopRequireDefault(require("lodash/noop")); var _isNegativeZero = _interopRequireDefault(require("is-negative-zero")); var _InputHandler = _interopRequireDefault(require("./InputHandler")); var _icon = _interopRequireDefault(require("../../icon")); var _input = _interopRequireDefault(require("../../input")); var _EventManager = require("../../_util/EventManager"); function _createSuper(Derived) { function isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } return function () { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (isNativeReflectConstruct()) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; } function defaultParser(input) { return input.replace(/[^\w\.-]+/g, ''); } /** * When click and hold on a button - the speed of auto changin the value. */ var SPEED = 200; /** * When click and hold on a button - the delay before auto changin the value. */ var DELAY = 600; /** * Max Safe Integer -- on IE this is not available, so manually set the number in that case. * The reason this is used, instead of Infinity is because numbers above the MSI are unstable */ var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || Math.pow(2, 53) - 1; var isValidProps = function isValidProps(value) { return value !== undefined && value !== null; }; var InputNumber = /*#__PURE__*/ function (_Component) { (0, _inherits2["default"])(InputNumber, _Component); var _super = _createSuper(InputNumber); function InputNumber(_props) { var _this; (0, _classCallCheck2["default"])(this, InputNumber); _this = _super.call(this, _props); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "onKeyDown", function (e) { if (e.keyCode === 38) { var ratio = _this.getRatio(e); _this.up(e, ratio); _this.stop(); } else if (e.keyCode === 40) { var _ratio = _this.getRatio(e); _this.down(e, _ratio); _this.stop(); } var onKeyDown = _this.props.onKeyDown; if (onKeyDown) { for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } onKeyDown.apply(void 0, [e].concat(args)); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "onKeyUp", function (e) { _this.stop(); var onKeyUp = _this.props.onKeyUp; if (onKeyUp) { for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { args[_key2 - 1] = arguments[_key2]; } onKeyUp.apply(void 0, [e].concat(args)); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "onChange", function (e) { if (_this.state.focused) { _this.inputting = true; } var input = _this.props.parser(_this.getValueFromEvent(e)); _this.setState({ inputValue: input }); _this.props.onChange(_this.toNumberWhenUserInput(input)); // valid number or invalid string }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "onFocus", function () { var _this$props; _this.setState({ focused: true }); (_this$props = _this.props).onFocus.apply(_this$props, arguments); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "onBlur", function (e) { for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) { args[_key3 - 1] = arguments[_key3]; } _this.inputting = false; _this.setState({ focused: false }); var value = _this.getCurrentValidValue(_this.state.inputValue); e.persist(); // fix https://github.com/react-component/input-number/issues/51 _this.setValue(value, function () { var _this$props2; (_this$props2 = _this.props).onBlur.apply(_this$props2, [e].concat(args)); }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "stop", function () { if (_this.autoStepTimer) { clearTimeout(_this.autoStepTimer); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "down", function (e, ratio, recursive) { _this.pressingUpOrDown = true; _this.step('down', e, ratio, recursive); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "up", function (e, ratio, recursive) { _this.pressingUpOrDown = true; _this.step('up', e, ratio, recursive); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "saveInput", function (node) { _this.input = node; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "renderSuffix", function () { var props = (0, _objectSpread2["default"])({}, _this.props); var prefixCls = props.prefixCls, disabled = props.disabled, readOnly = props.readOnly, useTouch = props.useTouch; var upDisabledClass = ''; var downDisabledClass = ''; var value = _this.state.value; if (value || value === 0) { if (!isNaN(value)) { var val = Number(value); if (val >= props.max) { upDisabledClass = "".concat(prefixCls, "-handler-up-disabled"); } if (val <= props.min) { downDisabledClass = "".concat(prefixCls, "-handler-down-disabled"); } } else { upDisabledClass = "".concat(prefixCls, "-handler-up-disabled"); downDisabledClass = "".concat(prefixCls, "-handler-down-disabled"); } } var editable = !props.readOnly && !props.disabled; var upEvents; var downEvents; if (useTouch) { upEvents = { onTouchStart: editable && !upDisabledClass ? _this.up : _noop["default"], onTouchEnd: _this.stop }; downEvents = { onTouchStart: editable && !downDisabledClass ? _this.down : _noop["default"], onTouchEnd: _this.stop }; } else { upEvents = { onMouseDown: editable && !upDisabledClass ? _this.up : _noop["default"], onMouseUp: _this.stop, onMouseLeave: _this.stop }; downEvents = { onMouseDown: editable && !downDisabledClass ? _this.down : _noop["default"], onMouseUp: _this.stop, onMouseLeave: _this.stop }; } var isUpDisabled = !!upDisabledClass || disabled || readOnly; var isDownDisabled = !!downDisabledClass || disabled || readOnly; return _react["default"].createElement("div", { className: "".concat(prefixCls, "-handler-wrap") }, _react["default"].createElement(_InputHandler["default"], (0, _extends2["default"])({ ref: "up", disabled: isUpDisabled, prefixCls: prefixCls, unselectable: "unselectable" }, upEvents, { role: "button", "aria-label": "Increase Value", "aria-disabled": !!isUpDisabled, className: "".concat(prefixCls, "-handler ").concat(prefixCls, "-handler-up ").concat(upDisabledClass) }), _this.props.upHandler || _react["default"].createElement(_icon["default"], { unselectable: "unselectable", type: "baseline-arrow_drop_up", className: "".concat(prefixCls, "-handler-up-inner"), onClick: _EventManager.preventDefault })), _react["default"].createElement(_InputHandler["default"], (0, _extends2["default"])({ ref: "down", disabled: isDownDisabled, prefixCls: prefixCls, unselectable: "unselectable" }, downEvents, { role: "button", "aria-label": "Decrease Value", "aria-disabled": !!isDownDisabled, className: "".concat(prefixCls, "-handler ").concat(prefixCls, "-handler-down ").concat(downDisabledClass) }), _this.props.downHandler || _react["default"].createElement(_icon["default"], { unselectable: "unselectable", type: "baseline-arrow_drop_down", className: "".concat(prefixCls, "-handler-down-inner"), onClick: _EventManager.preventDefault }))); }); var _value; if ('value' in _props) { _value = _props.value; } else { _value = _props.defaultValue; } _value = _this.toNumber(_value); _this.state = { inputValue: _this.toPrecisionAsStep(_value), value: _value, focused: _props.autoFocus }; return _this; } (0, _createClass2["default"])(InputNumber, [{ key: "componentDidMount", value: function componentDidMount() { this.componentDidUpdate(); } }, { key: "componentWillReceiveProps", value: function componentWillReceiveProps(nextProps) { if ('value' in nextProps) { var value = this.state.focused ? nextProps.value : this.getValidValue(nextProps.value, nextProps.min, nextProps.max); this.setState({ value: value, inputValue: this.inputting ? value : this.toPrecisionAsStep(value) }); } } }, { key: "componentWillUpdate", value: function componentWillUpdate() { try { this.start = this.input.selectionStart; this.end = this.input.selectionEnd; } catch (e) {// Fix error in Chrome: // Failed to read the 'selectionStart' property from 'HTMLInputElement' // http://stackoverflow.com/q/21177489/3040605 } } }, { key: "componentDidUpdate", value: function componentDidUpdate() { // pressingUpOrDown is true means that someone just click up or down button if (!this.pressingUpOrDown) { return; } if (this.props.focusOnUpDown && this.state.focused) { var selectionRange = this.input.setSelectionRange; if (selectionRange && typeof selectionRange === 'function' && this.start !== undefined && this.end !== undefined) { this.input.setSelectionRange(this.start, this.end); } else { this.focus(); } this.pressingUpOrDown = false; } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { this.stop(); } }, { key: "getCurrentValidValue", value: function getCurrentValidValue(value) { var val = value; if (val === '') { val = ''; } else if (!this.isNotCompleteNumber(val)) { val = this.getValidValue(val); } else { val = this.state.value; } return this.toNumber(val); } }, { key: "getRatio", value: function getRatio(e) { var ratio = 1; if (e.metaKey || e.ctrlKey) { ratio = 0.1; } else if (e.shiftKey) { ratio = 10; } return ratio; } }, { key: "getValueFromEvent", value: function getValueFromEvent(e) { // optimize for chinese input expierence return e.target.value.trim().replace(/。/g, '.'); } }, { key: "getValidValue", value: function getValidValue(value) { var min = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.props.min; var max = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.props.max; var val = parseFloat(value, 10); if (isNaN(val)) { return value; } if (val < min) { val = min; } if (val > max) { val = max; } return val; } }, { key: "setValue", value: function setValue(v, callback) { // trigger onChange var newValue = this.isNotCompleteNumber(parseFloat(v, 10)) ? undefined : parseFloat(v, 10); var changed = newValue !== this.state.value || "".concat(newValue) !== "".concat(this.state.inputValue); if (!('value' in this.props)) { this.setState({ value: newValue, inputValue: this.toPrecisionAsStep(v) }, callback); } else { // always set input value same as value this.setState({ inputValue: this.toPrecisionAsStep(this.state.value) }, callback); } if (changed) { this.props.onChange(newValue); } } }, { key: "getPrecision", value: function getPrecision(value) { if ('precision' in this.props) { return this.props.precision; } var valueString = value.toString(); if (valueString.indexOf('e-') >= 0) { return parseInt(valueString.slice(valueString.indexOf('e-') + 2), 10); } var precision = 0; if (valueString.indexOf('.') >= 0) { precision = valueString.length - valueString.indexOf('.') - 1; } return precision; } // step={1.0} value={1.51} // press + // then value should be 2.51, rather than 2.5 // if this.props.precision is undefined // https://github.com/react-component/input-number/issues/39 }, { key: "getMaxPrecision", value: function getMaxPrecision(currentValue) { var ratio = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; if ('precision' in this.props) { return this.props.precision; } var step = this.props.step; var ratioPrecision = this.getPrecision(ratio); var stepPrecision = this.getPrecision(step); var currentValuePrecision = this.getPrecision(currentValue); if (!currentValue) { return ratioPrecision + stepPrecision; } return Math.max(currentValuePrecision, ratioPrecision + stepPrecision); } }, { key: "getPrecisionFactor", value: function getPrecisionFactor(currentValue) { var ratio = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; var precision = this.getMaxPrecision(currentValue, ratio); return Math.pow(10, precision); } }, { key: "focus", value: function focus() { this.input.focus(); } }, { key: "blur", value: function blur() { this.input.blur(); } }, { key: "formatWrapper", value: function formatWrapper(num) { // http://2ality.com/2012/03/signedzero.html if ((0, _isNegativeZero["default"])(num)) { return '-0'; } if (this.props.formatter) { return this.props.formatter(num); } return num; } }, { key: "toPrecisionAsStep", value: function toPrecisionAsStep(num) { if (this.isNotCompleteNumber(num) || num === '') { return num; } var precision = Math.abs(this.getMaxPrecision(num)); if (precision === 0) { return num.toString(); } if (!isNaN(precision)) { return Number(num).toFixed(precision); } return num.toString(); } // '1.' '1x' 'xx' '' => are not complete numbers }, { key: "isNotCompleteNumber", value: function isNotCompleteNumber(num) { return isNaN(num) || num === '' || num === null || num && num.toString().indexOf('.') === num.toString().length - 1; } }, { key: "toNumber", value: function toNumber(num) { var precision = this.props.precision; // num.length > 16 => This is to prevent input of large numbers var numberIsTooLarge = num && num.length > 16; if (this.isNotCompleteNumber(num) || numberIsTooLarge) { return num; } if (isValidProps(precision)) { return Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision); } return Number(num); } // '1.0' '1.00' => may be a inputing number }, { key: "toNumberWhenUserInput", value: function toNumberWhenUserInput(num) { // num.length > 16 => prevent input large number will became Infinity if ((/\.\d*0$/.test(num) || num.length > 16) && this.state.focused) { return num; } return this.toNumber(num); } }, { key: "upStep", value: function upStep(val, rat) { var _this$props3 = this.props, step = _this$props3.step, min = _this$props3.min; var precisionFactor = this.getPrecisionFactor(val, rat); var precision = Math.abs(this.getMaxPrecision(val, rat)); var result; if (typeof val === 'number') { result = ((precisionFactor * val + precisionFactor * step * rat) / precisionFactor).toFixed(precision); } else { result = min === -Infinity ? step : min; } return this.toNumber(result); } }, { key: "downStep", value: function downStep(val, rat) { var _this$props4 = this.props, step = _this$props4.step, min = _this$props4.min; var precisionFactor = this.getPrecisionFactor(val, rat); var precision = Math.abs(this.getMaxPrecision(val, rat)); var result; if (typeof val === 'number') { result = ((precisionFactor * val - precisionFactor * step * rat) / precisionFactor).toFixed(precision); } else { result = min === -Infinity ? -step : min; } return this.toNumber(result); } }, { key: "step", value: function step(type, e) { var _this2 = this; var ratio = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; var recursive = arguments.length > 3 ? arguments[3] : undefined; this.stop(); if (e) { e.persist(); e.preventDefault(); } var props = this.props; if (props.disabled) { return; } var value = this.getCurrentValidValue(this.state.inputValue) || 0; if (this.isNotCompleteNumber(value)) { return; } var val = this["".concat(type, "Step")](value, ratio); var outOfRange = val > props.max || val < props.min; if (val > props.max) { val = props.max; } else if (val < props.min) { val = props.min; } this.setValue(val); this.setState({ focused: true }); if (outOfRange) { return; } this.autoStepTimer = setTimeout(function () { _this2[type](e, ratio, true); }, recursive ? SPEED : DELAY); } }, { key: "render", value: function render() { var _classNames; var props = (0, _objectSpread2["default"])({}, this.props); var prefixCls = props.prefixCls, disabled = props.disabled, readOnly = props.readOnly, useTouch = props.useTouch; var classes = (0, _classnames["default"])((_classNames = {}, (0, _defineProperty2["default"])(_classNames, prefixCls, true), (0, _defineProperty2["default"])(_classNames, props.className, !!props.className), _classNames)); var editable = !props.readOnly && !props.disabled; // focus state, show input value // unfocus state, show valid value var inputDisplayValue; if (this.state.focused) { inputDisplayValue = this.state.inputValue; } else { inputDisplayValue = this.toPrecisionAsStep(this.state.value); } if (inputDisplayValue === undefined || inputDisplayValue === null) { inputDisplayValue = ''; } var inputDisplayValueFormat = this.formatWrapper(inputDisplayValue); // ref for test return _react["default"].createElement("div", { className: classes, style: props.style, onMouseEnter: props.onMouseEnter, onMouseLeave: props.onMouseLeave, onMouseOver: props.onMouseOver, onMouseOut: props.onMouseOut }, _react["default"].createElement(_input["default"], { required: props.required, type: props.type, placeholder: props.placeholder, onClick: props.onClick, tabIndex: props.tabIndex, autoComplete: "off", onFocus: this.onFocus, onBlur: this.onBlur, onKeyDown: editable ? this.onKeyDown : _noop["default"], onKeyUp: editable ? this.onKeyUp : _noop["default"], autoFocus: props.autoFocus, maxLength: props.maxLength, readOnly: props.readOnly, disabled: props.disabled, max: props.max, min: props.min, step: props.step, name: props.name, id: props.id, onChange: this.onChange, ref: this.saveInput, value: inputDisplayValueFormat, pattern: props.pattern, suffix: this.renderSuffix(), label: props.label })); } }]); return InputNumber; }(_react.Component); exports["default"] = InputNumber; (0, _defineProperty2["default"])(InputNumber, "propTypes", { value: _propTypes["default"].oneOfType([_propTypes["default"].number, _propTypes["default"].string]), defaultValue: _propTypes["default"].oneOfType([_propTypes["default"].number, _propTypes["default"].string]), focusOnUpDown: _propTypes["default"].bool, autoFocus: _propTypes["default"].bool, onChange: _propTypes["default"].func, onKeyDown: _propTypes["default"].func, onKeyUp: _propTypes["default"].func, prefixCls: _propTypes["default"].string, tabIndex: _propTypes["default"].string, disabled: _propTypes["default"].bool, onFocus: _propTypes["default"].func, onBlur: _propTypes["default"].func, readOnly: _propTypes["default"].bool, max: _propTypes["default"].number, min: _propTypes["default"].number, step: _propTypes["default"].oneOfType([_propTypes["default"].number, _propTypes["default"].string]), upHandler: _propTypes["default"].node, downHandler: _propTypes["default"].node, useTouch: _propTypes["default"].bool, formatter: _propTypes["default"].func, parser: _propTypes["default"].func, onMouseEnter: _propTypes["default"].func, onMouseLeave: _propTypes["default"].func, onMouseOver: _propTypes["default"].func, onMouseOut: _propTypes["default"].func, precision: _propTypes["default"].number, required: _propTypes["default"].bool, pattern: _propTypes["default"].string, label: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].node]) }); (0, _defineProperty2["default"])(InputNumber, "defaultProps", { focusOnUpDown: true, useTouch: false, prefixCls: 'rc-input-number', min: -MAX_SAFE_INTEGER, step: 1, style: {}, onChange: _noop["default"], onKeyDown: _noop["default"], onFocus: _noop["default"], onBlur: _noop["default"], parser: defaultParser, required: false }); //# sourceMappingURL=index.js.map