choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
779 lines (650 loc) • 24.5 kB
JavaScript
"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