hy-checkbox
Version:
checkbox & radio ui components for react
455 lines (407 loc) • 16.4 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _classnames2 = require('classnames');
var _classnames3 = _interopRequireDefault(_classnames2);
var _Input = require('../Input');
var _Input2 = _interopRequireDefault(_Input);
var _Button = require('../Button');
var _Button2 = _interopRequireDefault(_Button);
require('./inputNumber.less');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
* @Author: SiMeiyu
* @Date: 2017-07-04 10:03:02
*/
function noop() {}
function defaultParser(input) {
return input.replace(/[^\w\.-]+/g, '');
}
var InputNumber = function (_React$Component) {
_inherits(InputNumber, _React$Component);
function InputNumber(props) {
_classCallCheck(this, InputNumber);
var _this = _possibleConstructorReturn(this, (InputNumber.__proto__ || Object.getPrototypeOf(InputNumber)).call(this, props));
var value = void 0;
if ('value' in props) {
value = props.value;
} else {
value = props.defaultValue;
}
value = _this.toNumber(value);
_this.state = {
value: value,
inputValue: _this.toPrecisionAsStep(value),
isFocused: false
};
return _this;
}
_createClass(InputNumber, [{
key: 'getCurrentValidValue',
value: function getCurrentValidValue(value) {
var val = value;
var props = this.props;
if (val === '') {
val = '';
} else if (!this.isNotCompleteNumber(val)) {
val = Number(val);
if (val < props.min) {
val = props.min;
}
if (val > props.max) {
val = props.max;
}
} else {
val = this.state.value;
}
return this.toNumber(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;
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;
}
}, {
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: 'toPrecisionAsStep',
value: function toPrecisionAsStep(num) {
if (this.isNotCompleteNumber(num) || num === '') {
return num;
}
var precision = Math.abs(this.getMaxPrecision(num));
if (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) {
if (this.isNotCompleteNumber(num)) {
return num;
}
if ('precision' in this.props) {
return Number(Number(num).toFixed(this.props.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) {
return num;
}
return this.toNumber(num);
}
}, {
key: 'upStep',
value: function upStep(val, rat) {
var _props = this.props,
step = _props.step,
min = _props.min;
var precisionFactor = this.getPrecisionFactor(val, rat);
var precision = Math.abs(this.getMaxPrecision(val, rat));
var result = void 0;
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 _props2 = this.props,
step = _props2.step,
min = _props2.min;
var precisionFactor = this.getPrecisionFactor(val, rat);
var precision = Math.abs(this.getMaxPrecision(val, rat));
var result = void 0;
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 ratio = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
if (e) {
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[type + 'Step'](value, ratio);
if (val > props.max) {
val = props.max;
} else if (val < props.min) {
val = props.min;
}
this.setValue(val);
this.setState({
focused: true
});
}
}, {
key: 'down',
value: function down(e) {
var ratio = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
this.step('down', e, ratio);
}
}, {
key: 'up',
value: function up(e) {
var ratio = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
this.step('up', e, ratio);
}
}, {
key: 'getValueFromEvent',
value: function getValueFromEvent(e) {
return e.target.value;
// return parseFloat(e.target.value);
}
}, {
key: 'onChange',
value: function onChange(e) {
var input = this.props.parser(this.getValueFromEvent(e).trim());
this.setState({ inputValue: input });
this.props.onChange(this.toNumberWhenUserInput(input)); // valid number or invalid string
}
}, {
key: 'onBlur',
value: function onBlur(e) {
var _this2 = this;
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
var value = this.getCurrentValidValue(this.state.inputValue);
this.setValue(value, function () {
var _props3;
(_props3 = _this2.props).onBlur.apply(_props3, [e].concat(args));
});
this.setState({
isFocused: false
});
}
}, {
key: 'onFocus',
value: function onFocus() {
this.setState({
isFocused: true
});
}
}, {
key: 'onWheel',
value: function onWheel(event) {
event.nativeEvent.stopImmediatePropagation();
// if (this.state.isFocused) {
console.log(event.type + ": " + event.deltaY);
if (event.deltaY > 0) {
this.up(event);
} else {
this.down(event);
}
// }
}
}, {
key: 'onKeyDown',
value: function onKeyDown(e) {
if (event.target.focus) {
if (e.keyCode === 38) {
this.up(e);
} else if (e.keyCode === 40) {
this.down(e);
}
var onKeyDown = this.props.onKeyDown;
if (onKeyDown) {
for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
onKeyDown.apply(undefined, [e].concat(args));
}
}
}
}, {
key: 'render',
value: function render() {
var _classnames;
var _props4 = this.props,
prefixCls = _props4.prefixCls,
className = _props4.className,
style = _props4.style,
readOnly = _props4.readOnly,
verticalbuttons = _props4.verticalbuttons,
disabled = _props4.disabled,
postfix = _props4.postfix;
var classes = (0, _classnames3.default)((_classnames = {}, _defineProperty(_classnames, prefixCls + '-input-number', true), _defineProperty(_classnames, prefixCls + '-input-number-verticalbuttons', !!verticalbuttons), _defineProperty(_classnames, prefixCls + '-input-number-disabled', !!disabled), _classnames), className);
var _state = this.state,
value = _state.value,
inputValue = _state.inputValue,
isFocused = _state.isFocused;
var isMaxDisable = void 0,
isMinDisable = void 0;
if (value) {
if (!isNaN(value)) {
var val = Number(value);
if (val >= this.props.max) {
isMaxDisable = true;
isMinDisable = false;
}
if (val <= this.props.min) {
isMaxDisable = false;
isMinDisable = true;
}
} else {
isMaxDisable = false;
isMinDisable = false;
}
}
var inputDisplayValue = inputValue;
if (inputDisplayValue === undefined || inputDisplayValue === null) {
inputDisplayValue = '';
}
var iconDown = !verticalbuttons ? "minus" : "down";
var iconUp = !verticalbuttons ? "add" : "up";
return _react2.default.createElement(
'div',
{ className: classes, style: style },
_react2.default.createElement(_Button2.default, {
className: (0, _classnames3.default)(prefixCls + '-input-number-down'),
icon: iconDown,
disabled: disabled || readOnly || isMinDisable || null,
onClick: this.down.bind(this)
}),
_react2.default.createElement(_Input2.default, {
className: prefixCls + '-input-number-input',
disabled: disabled || readOnly || null,
value: inputDisplayValue,
onChange: this.onChange.bind(this),
onBlur: this.onBlur.bind(this),
onFocus: this.onFocus.bind(this),
onWheel: isFocused ? this.onWheel.bind(this) : null,
onKeyDown: isFocused ? this.onKeyDown.bind(this) : null
}),
postfix ? _react2.default.createElement(
'span',
{ className: prefixCls + '-input-number-postfix' },
postfix
) : null,
_react2.default.createElement(_Button2.default, {
className: prefixCls + '-input-number-up',
icon: iconUp,
disabled: disabled || readOnly || isMaxDisable || null,
onClick: this.up.bind(this)
})
);
}
}]);
return InputNumber;
}(_react2.default.Component);
InputNumber.propTypes = {
prefixCls: _react2.default.PropTypes.string,
className: _react2.default.PropTypes.string,
style: _react2.default.PropTypes.object,
verticalbuttons: _react2.default.PropTypes.bool,
disabled: _react2.default.PropTypes.bool,
defaultValue: _react2.default.PropTypes.number,
value: _react2.default.PropTypes.number,
min: _react2.default.PropTypes.number,
max: _react2.default.PropTypes.number,
precision: _react2.default.PropTypes.number, // 小数位数
postfix: _react2.default.PropTypes.string, // 单位
step: _react2.default.PropTypes.number,
onChange: _react2.default.PropTypes.func
};
InputNumber.defaultProps = {
prefixCls: 'ult',
verticalbuttons: false,
disabled: false,
step: 1,
min: -Infinity,
max: Infinity,
style: {},
onChange: noop,
onKeyDown: noop,
onFocus: noop,
onBlur: noop,
parser: defaultParser
};
exports.default = InputNumber;