zent
Version:
一套前端设计语言和基于React的实现
327 lines (326 loc) • 15.5 kB
JavaScript
import { __assign, __extends, __rest } from "tslib";
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { Component, createRef } from 'react';
import cx from 'classnames';
import { I18nReceiver as Receiver } from '../i18n';
import Decimal from 'big.js';
import Icon from '../icon';
import Input from '../input';
import Pop from '../pop';
import { InputContext } from '../input/context';
import { DisabledContext } from '../disabled';
import * as Integers from './integer';
import * as Decimals from './decimal';
import { trimLeadingPlus } from './utils';
import { hasOwnProperty } from '../utils/hasOwn';
var is = Object.is;
function getStateFromProps(props, updateValueInState) {
var pop = {
visible: false,
type: '',
text: '',
};
var state = props.showTooltip ? { pop: pop } : {};
if (props.integer === true) {
var _a = Integers.normalizeMinMax(props), min = _a.min, max = _a.max;
return __assign(__assign(__assign({}, state), { prevProps: props, min: min, max: max, delta: Integers.getDelta(props.step) }), (updateValueInState
? Integers.normalizeValue(props.value, min, max)
: {}));
}
else {
var _b = Decimals.normalizeMinMax(props), min = _b.min, max = _b.max;
return __assign(__assign(__assign({}, state), { prevProps: props, min: min, max: max, delta: Decimals.getDelta(props.decimal, props.step) }), (updateValueInState
? Decimals.normalizeValue(props.value, min, max, props.decimal)
: {}));
}
}
var NumberInput = (function (_super) {
__extends(NumberInput, _super);
function NumberInput(props) {
var _this = _super.call(this, props) || this;
_this.focused = false;
_this.timer = null;
_this.inputRef = createRef();
_this.inputContext = {
renderInner: function (children) { return _this.renderChild(children); },
};
_this.onUserInput = function (e) {
var value = e.target.value;
if (_this.props.integer === false) {
var onInput = _this.props.onInput;
if (Decimals.isPotentialValue(value)) {
_this.setState({
input: value,
value: Decimals.EMPTY_DECIMAL,
});
}
else if (Decimals.isDecimal(value)) {
_this.setState({
input: value,
value: new Decimal(trimLeadingPlus(value)),
});
onInput && onInput(value);
}
}
else {
var onInput = _this.props.onInput;
if (Integers.isPotentialValue(value)) {
_this.setState({
input: value,
value: null,
});
onInput && onInput(value);
}
else if (Integers.isInteger(value)) {
var num = parseInt(value, 10) || 0;
_this.setState({
input: value,
value: num,
});
onInput && onInput(value);
}
}
};
_this.onFocus = function (e) {
_this.focused = true;
var onFocus = _this.props.onFocus;
onFocus && onFocus(e);
};
_this.hideTooltip = function () {
_this.timer && clearTimeout(_this.timer);
_this.timer = setTimeout(function () {
_this.setState({
pop: { visible: false, text: '', type: '' },
});
}, 1500);
};
_this.onBlur = function (e) {
_this.focused = false;
if (_this.props.integer === true) {
var _a = _this.props, onChange = _a.onChange, showTooltip_1 = _a.showTooltip;
var _b = _this.state, value = _b.value, min = _b.min, max = _b.max;
var normalized = Integers.normalizeValue(value, min, max, showTooltip_1);
onChange === null || onChange === void 0 ? void 0 : onChange(normalized.value);
_this.setState(normalized, function () {
if (showTooltip_1 && _this.state.pop.visible) {
_this.hideTooltip();
}
});
var onBlur = _this.props.onBlur;
onBlur === null || onBlur === void 0 ? void 0 : onBlur(e);
}
else {
var _c = _this.props, onChange = _c.onChange, decimal = _c.decimal, showTooltip_2 = _c.showTooltip;
var _d = _this.state, input = _d.input, min = _d.min, max = _d.max;
var normalized = Decimals.normalizeValue(input, min, max, decimal, showTooltip_2);
onChange === null || onChange === void 0 ? void 0 : onChange(normalized.input);
_this.setState(normalized, function () {
if (showTooltip_2 && _this.state.pop.visible) {
_this.hideTooltip();
}
});
var onBlur = _this.props.onBlur;
onBlur && onBlur(e);
}
};
_this.inc = function () {
_this.step('inc');
};
_this.dec = function () {
_this.step('dec');
};
_this.state = getStateFromProps(props, true);
return _this;
}
NumberInput.prototype.step = function (type) {
if (this.props.disabled) {
return;
}
if (this.props.integer === true) {
var _a = this.state, value = _a.value, min = _a.min, max = _a.max, delta = _a.delta;
var _b = Integers.calculateLimit(value, min, max), canInc = _b.canInc, canDec = _b.canDec;
if (value === null ||
(type === 'inc' && !canInc) ||
(type === 'dec' && !canDec)) {
return;
}
var onChange = this.props.onChange;
var nextValue = void 0;
if (type === 'inc') {
nextValue = value + delta;
}
else {
nextValue = value - delta;
}
onChange === null || onChange === void 0 ? void 0 : onChange(nextValue);
this.setState({
value: nextValue,
input: String(nextValue),
});
}
else {
var _c = this.props, onChange = _c.onChange, decimal = _c.decimal;
var _d = this.state, value = _d.value, min = _d.min, max = _d.max, delta = _d.delta;
var _e = Decimals.calculateLimit(value, min, max), canInc = _e.canInc, canDec = _e.canDec;
if ((type === 'inc' && !canInc) || (type === 'dec' && !canDec)) {
return;
}
var nextValue = void 0;
if (type === 'inc') {
nextValue = value.plus(delta);
}
else {
nextValue = value.minus(delta);
}
var input = nextValue.toFixed(decimal);
onChange === null || onChange === void 0 ? void 0 : onChange(input);
this.setState({
value: nextValue,
input: input,
});
}
};
NumberInput.getDerivedStateFromProps = function (props, prevState) {
var prevProps = prevState.prevProps;
if (props === prevProps) {
return null;
}
var updateValueInState = isControlled(props);
if (props.integer !== prevProps.integer) {
return getStateFromProps(props, updateValueInState);
}
if (props.integer === true) {
var nextState_1 = __assign(__assign({}, prevState), { prevProps: props });
var minMaxChanged_1 = false;
if (!is(props.min, prevProps.min) || !is(props.max, prevProps.max)) {
var _a = Integers.normalizeMinMax(props), min = _a.min, max = _a.max;
nextState_1.min = min;
nextState_1.max = max;
minMaxChanged_1 = true;
}
if (updateValueInState &&
(minMaxChanged_1 || !is(props.value, prevProps.value))) {
var _b = Integers.normalizeValue(props.value, nextState_1.min, nextState_1.max), value = _b.value, input = _b.input;
nextState_1.value = value;
nextState_1.input = input;
}
return nextState_1;
}
var nextState = __assign(__assign({}, prevState), { prevProps: props });
var minMaxChanged = false;
if (!is(props.min, prevProps.min) || !is(props.max, prevProps.max)) {
var _c = Decimals.normalizeMinMax(props), min = _c.min, max = _c.max;
nextState.min = min;
nextState.max = max;
minMaxChanged = true;
}
if (updateValueInState &&
(minMaxChanged ||
!is(props.value, prevProps.value) ||
!is(props.decimal, prevProps.decimal))) {
var _d = Decimals.normalizeValue(props.value, nextState.min, nextState.max, props.decimal), value = _d.value, input = _d.input;
nextState.value = value;
nextState.input = input;
}
if (!is(props.step, prevProps.step) ||
!is(props.decimal, prevProps.decimal)) {
nextState.delta = Decimals.getDelta(props.decimal, props.step);
}
return nextState;
};
NumberInput.prototype.checkPropsValue = function () {
if (this.props.integer === true) {
if (this.props.value !== this.state.value) {
var onChange = this.props.onChange;
onChange && onChange(this.state.value);
}
}
else {
var _a = this.props, onChange = _a.onChange, decimal = _a.decimal, propsValue = _a.value;
var value = this.state.value;
var roundedStateValue = value.toFixed(decimal);
var roundedPropsValue = typeof propsValue === 'number'
? propsValue.toFixed(decimal)
: propsValue;
if (onChange &&
this.props.value !== '' &&
this.state.input !== '' &&
roundedPropsValue !== roundedStateValue) {
onChange(roundedStateValue);
}
}
};
NumberInput.prototype.componentDidMount = function () {
if ('value' in this.props && !this.focused) {
this.checkPropsValue();
}
};
NumberInput.prototype.componentDidUpdate = function (prevProps) {
if (prevProps !== this.props && 'value' in this.props && !this.focused) {
this.checkPropsValue();
}
};
NumberInput.prototype.renderChild = function (children) {
var _a = this.props, _b = _a.disabled, disabled = _b === void 0 ? this.context.value : _b, readOnly = _a.readOnly, showCounter = _a.showCounter, showStepper = _a.showStepper;
var limits;
if (this.props.integer === true) {
var _c = this.state, min = _c.min, max = _c.max, value = _c.value;
limits = Integers.calculateLimit(value, min, max);
}
else {
var _d = this.state, value = _d.value, min = _d.min, max = _d.max;
limits = Decimals.calculateLimit(value, min, max);
}
var canDec = limits.canDec, canInc = limits.canInc;
var input = this.state.input;
var addState = disabled || readOnly || !canInc || input === '';
var reduceState = disabled || readOnly || !canDec || input === '';
var upArrowClass = cx({
'zent-number-input-arrow': true,
'zent-number-input-arrowup': true,
'zent-number-input-arrow-disable': addState,
});
var downArrowClass = cx({
'zent-number-input-arrow': true,
'zent-number-input-arrowdown': true,
'zent-number-input-arrow-disable': reduceState,
});
var reduceCountClass = cx({
'zent-number-input-count': true,
'zent-number-input-countreduce': true,
'zent-number-input-count-disable': reduceState,
});
var addCountClass = cx({
'zent-number-input-count': true,
'zent-number-input-countadd': true,
'zent-number-input-count-disable': addState,
});
return (_jsxs(_Fragment, { children: [showCounter && (_jsx("div", __assign({ className: reduceCountClass, onClick: this.dec, "data-zv": '10.0.17' }, { children: "\u2013" }), void 0)), children, showCounter && (_jsx("div", __assign({ className: addCountClass, onClick: this.inc, "data-zv": '10.0.17' }, { children: "+" }), void 0)), showStepper && (_jsxs("div", __assign({ className: 'zent-number-input-arrows', "data-zv": '10.0.17' }, { children: [_jsx("div", __assign({ className: upArrowClass, onClick: this.inc, "data-zv": '10.0.17' }, { children: _jsx(Icon, { type: "up" }, void 0) }), void 0), _jsx("div", __assign({ className: downArrowClass, onClick: this.dec, "data-zv": '10.0.17' }, { children: _jsx(Icon, { type: "down" }, void 0) }), void 0)] }), void 0))] }, void 0));
};
NumberInput.prototype.renderInput = function () {
var _a = this.props, integer = _a.integer, className = _a.className, disabled = _a.disabled, readOnly = _a.readOnly, type = _a.type, onChange = _a.onChange, showStepper = _a.showStepper, showCounter = _a.showCounter, min = _a.min, max = _a.max, decimal = _a.decimal, onInput = _a.onInput, showTooltip = _a.showTooltip, inputProps = __rest(_a, ["integer", "className", "disabled", "readOnly", "type", "onChange", "showStepper", "showCounter", "min", "max", "decimal", "onInput", "showTooltip"]);
var input = this.state.input;
if (showStepper && showCounter) {
throw new Error('NumberInput: showStepper、 showCounter cannot exist at the same time');
}
return (_jsx(Input, __assign({ ref: this.inputRef, autoComplete: "off" }, inputProps, { readOnly: readOnly, disabled: disabled, className: cx('zent-number-input', className), value: input, onChange: this.onUserInput, onFocus: this.onFocus, onBlur: this.onBlur }), void 0));
};
NumberInput.prototype.render = function () {
var _this = this;
var pop = this.state.pop;
return this.props.showTooltip ? (_jsx(Receiver, __assign({ componentName: 'NumberInput' }, { children: function (i18n) { return (_jsx(InputContext.Provider, __assign({ value: _this.inputContext }, { children: _jsx(Pop, __assign({ trigger: 'none', content: pop.visible ? i18n[pop.type] + pop.text : '', visible: pop.visible, position: "bottom-left" }, { children: _this.renderInput() }), void 0) }), void 0)); } }), void 0)) : (_jsx(InputContext.Provider, __assign({ value: this.inputContext }, { children: this.renderInput() }), void 0));
};
NumberInput.defaultProps = {
integer: false,
type: 'number',
decimal: 0,
size: 'normal',
};
NumberInput.contextType = DisabledContext;
return NumberInput;
}(Component));
export { NumberInput };
function isControlled(props) {
return hasOwnProperty(props, 'value') && hasOwnProperty(props, 'onChange');
}
export default NumberInput;