zarm-web
Version:
基于 React 的桌面端UI库
187 lines (168 loc) • 3.84 kB
JavaScript
import React, { PureComponent } from 'react';
import classnames from 'classnames';
import Input from '../input';
import Icon from '../icon';
export default class NumberInput extends PureComponent {
constructor(...args) {
super(...args);
this.state = {
value: this.props.value,
prevPropsValue: this.props.value,
addState: false,
reduceState: false
};
this.onChange = e => {
const {
decimal
} = this.props;
const regex = decimal ? new RegExp(`^\\d+(\\.[0-9]{0,${decimal}})?$`, 'g') : new RegExp(/^\d+$/, 'g');
const {
value
} = e.target;
if (!value) {
this.setState({
value
});
} else if (regex.test(value)) {
this.props.onChange(e);
this.setState({
value
});
}
};
this.onBlur = () => {
const {
onBlur
} = this.props;
this.calculateNum();
if (onBlur) {
onBlur();
}
};
this.increase = () => {
const {
step
} = this.props;
this.countField('increase', step);
};
this.decrease = () => {
const {
step
} = this.props;
this.countField('decrease', step);
};
}
static getDerivedStateFromProps(props, state) {
if (props.value !== state.prevPropsValue) {
return {
value: props.value,
prevPropsValue: props.value
};
}
return null;
}
componentDidMount() {
this.calculateNum();
}
calculateNum() {
let {
value
} = this.state;
const {
min,
max
} = this.props;
if (min !== undefined || max !== undefined) {
if (parseInt(value, 10) < min) {
value = min;
}
if (parseInt(value, 10) > max) {
value = max;
}
}
this.setState({
value
});
}
countField(type, step) {
const {
min,
max,
isDisabled
} = this.props;
const {
addState,
reduceState
} = this.state;
let {
value
} = this.state;
if (type === 'increase' && !addState && !isDisabled) {
value += step;
this.setState({
value
});
}
if (type === 'decrease' && !reduceState && !isDisabled) {
value -= step;
this.setState({
value
});
}
this.setState({
addState: Number(value) >= max,
reduceState: Number(value) <= min
}); // this.calculateNum();
}
render() {
const {
className,
style,
isDisabled,
placeholder,
showStepper
} = this.props;
const {
value,
addState,
reduceState
} = this.state;
const addCountClass = classnames({
'ui-number-input-count': true,
'ui-number-input-countadd': true,
'ui-number-input-count-disable': isDisabled || addState
});
const reduceCountClass = classnames({
'ui-number-input-count': true,
'ui-number-input-countreduce': true,
'ui-number-input-count-disable': isDisabled || reduceState
});
return React.createElement("div", {
className: "ui-number-input-wrapper"
}, showStepper && React.createElement("span", {
className: addCountClass,
onClick: this.increase
}, React.createElement(Icon, {
type: "add"
})), React.createElement(Input, {
className: className,
style: style,
value: value,
onChange: this.onChange,
onBlur: this.onBlur,
isDisabled: isDisabled,
placeholder: placeholder
}), showStepper && React.createElement("span", {
className: reduceCountClass,
onClick: this.decrease
}, React.createElement(Icon, {
type: "minus"
})));
}
}
NumberInput.defaultProps = {
showStepper: false,
decimal: 0,
step: 1,
onChange: () => {}
};