Skip to content

Commit

Permalink
Merge pull request #401 from alibaba-fusion/fix/number-picker
Browse files Browse the repository at this point in the history
Fix/number picker
  • Loading branch information
frankqian authored Feb 28, 2019
2 parents 828c9a0 + 8369b4a commit e315a2c
Show file tree
Hide file tree
Showing 2 changed files with 521 additions and 218 deletions.
155 changes: 104 additions & 51 deletions src/number-picker/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { func, obj } from '../util';

/** NumberPicker */
class NumberPicker extends React.Component {

static propTypes = {
/**
* 样式前缀
Expand Down Expand Up @@ -39,10 +38,7 @@ class NumberPicker extends React.Component {
/**
* 步长
*/
step: PropTypes.oneOfType([
PropTypes.number,
PropTypes.string
]),
step: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
/**
* 保留小数点后位数
*/
Expand Down Expand Up @@ -125,7 +121,7 @@ class NumberPicker extends React.Component {
onChange: func.noop,
onKeyDown: func.noop,
onBlur: func.noop,
onCorrect: func.noop
onCorrect: func.noop,
};

constructor(props) {
Expand All @@ -140,21 +136,23 @@ class NumberPicker extends React.Component {

this.state = {
value: typeof value === 'undefined' ? '' : value,
hasFocused: false
hasFocused: false,
};
}

componentWillReceiveProps(nextProps) {
if ('value' in nextProps) {
this.setState({
value: nextProps.value === undefined ? '' : nextProps.value
value: nextProps.value === undefined ? '' : nextProps.value,
});
}
}

onChange(value, e) {
if (this.props.editable === true) {
value = value.trim();
// Compatible Chinese Input Method
value = value.replace('。', '.');
// ignore space
if (this.state.value === value) {
return;
Expand All @@ -165,7 +163,7 @@ class NumberPicker extends React.Component {
// ignore when input start form '-'
if (value === '-' || this.state.value === '-') {
this.setState({
value
value,
});
return;
}
Expand All @@ -174,14 +172,14 @@ class NumberPicker extends React.Component {
// but take care of Number('')=0;
if (Number(this.state.value) === Number(value)) {
this.setState({
value
value,
});
return;
}
// ignore when value < min (because number is inputted one by one)
if (!isNaN(value) && Number(value) < this.props.min) {
this.setState({
value
value,
});
return;
}
Expand All @@ -198,7 +196,7 @@ class NumberPicker extends React.Component {
onCorrect(currentValue, oldValue) {
this.props.onCorrect({
currentValue,
oldValue
oldValue,
});
}

Expand Down Expand Up @@ -248,7 +246,6 @@ class NumberPicker extends React.Component {
if (pointPos !== -1 && strValue.length > cutPos) {
val = Number(strValue.substr(0, cutPos));
}

} else {
val = this.state.value;
}
Expand All @@ -263,11 +260,14 @@ class NumberPicker extends React.Component {
setValue(v, e, triggerType) {
if (!('value' in this.props)) {
this.setState({
value: v
value: v,
});
}

this.props.onChange(isNaN(v) || v === '' ? undefined : v, { ...e, triggerType });
this.props.onChange(isNaN(v) || v === '' ? undefined : v, {
...e,
triggerType,
});
}

setInputValue(v, e) {
Expand All @@ -282,7 +282,7 @@ class NumberPicker extends React.Component {
// Only trigger `setState` if `format` is settled to avoid unnecessary rendering
if (typeof format === 'function') {
this.setState({
hasFocused: status
hasFocused: status,
});
}
}
Expand Down Expand Up @@ -311,7 +311,9 @@ class NumberPicker extends React.Component {
const precisionFactor = this.getPrecisionFactor();
let result;
if (typeof val === 'number') {
result = (precisionFactor * val + precisionFactor * step) / precisionFactor;
result =
(precisionFactor * val + precisionFactor * step) /
precisionFactor;

result = this.hackChrome(result);
} else {
Expand All @@ -325,7 +327,9 @@ class NumberPicker extends React.Component {
const precisionFactor = this.getPrecisionFactor();
let result;
if (typeof val === 'number') {
result = (precisionFactor * val - precisionFactor * step) / precisionFactor;
result =
(precisionFactor * val - precisionFactor * step) /
precisionFactor;

result = this.hackChrome(result);
} else {
Expand Down Expand Up @@ -384,7 +388,9 @@ class NumberPicker extends React.Component {
renderValue() {
const { value, hasFocused } = this.state;
const { format } = this.props;
return (typeof format === 'function' && !hasFocused) ? format(value) : value;
return typeof format === 'function' && !hasFocused
? format(value)
: value;
}

focus() {
Expand All @@ -400,15 +406,30 @@ class NumberPicker extends React.Component {
}

render() {
const { type, prefix, rtl, disabled, style, className, size, max, min, autoFocus, editable, state, upBtnProps, downBtnProps } = this.props;
const {
type,
prefix,
rtl,
disabled,
style,
className,
size,
max,
min,
autoFocus,
editable,
state,
upBtnProps,
downBtnProps,
} = this.props;

const prefixCls = `${prefix}number-picker`;

const cls = classNames({
[prefixCls]: true,
[`${prefixCls}-${this.props.type}`]: this.props.type,
[`${prefix}${size}`]: true,
[className]: className
[className]: className,
});

let upDisabled = false;
Expand All @@ -424,25 +445,50 @@ class NumberPicker extends React.Component {
}
}

let innerAfter = null, innerAfterClassName = null, addonBefore = null, addonAfter = null;
let innerAfter = null,
innerAfterClassName = null,
addonBefore = null,
addonAfter = null;
if (type === 'normal') {
innerAfter = ([
<Button {...upBtnProps} onMouseDown={this.handleMouseDown} disabled={disabled || upDisabled} onClick={this.up.bind(this)} key="0">
innerAfter = [
<Button
{...upBtnProps}
onMouseDown={this.handleMouseDown}
disabled={disabled || upDisabled}
onClick={this.up.bind(this)}
key="0"
>
<Icon size="xxs" type="arrow-up" />
</Button>,
<Button {...downBtnProps} onMouseDown={this.handleMouseDown} disabled={disabled || downDisabled} onClick={this.down.bind(this)} key="1">
<Button
{...downBtnProps}
onMouseDown={this.handleMouseDown}
disabled={disabled || downDisabled}
onClick={this.down.bind(this)}
key="1"
>
<Icon size="xxs" type="arrow-down" />
</Button>
]);
</Button>,
];
innerAfterClassName = `${prefixCls}-handler`;
} else {
addonBefore = (
<Button {...downBtnProps} size={size} disabled={disabled || downDisabled} onClick={this.down.bind(this)}>
<Button
{...downBtnProps}
size={size}
disabled={disabled || downDisabled}
onClick={this.down.bind(this)}
>
<Icon type="minus" size="xs" />
</Button>
);
addonAfter = (
<Button {...upBtnProps} size={size} disabled={disabled || upDisabled} onClick={this.up.bind(this)}>
<Button
{...upBtnProps}
size={size}
disabled={disabled || upDisabled}
onClick={this.up.bind(this)}
>
<Icon type="add" size="xs" />
</Button>
);
Expand All @@ -451,28 +497,35 @@ class NumberPicker extends React.Component {
const others = obj.pickOthers(NumberPicker.propTypes, this.props);
const dataAttrs = obj.pickAttrsWith(this.props, 'data-');

return (<span className={cls} style={style} dir={rtl ? 'rtl' : undefined} {...dataAttrs}>
<Input
{...others}
aria-valuemax={max !== Infinity ? max : undefined}
aria-valuemin={min !== -Infinity ? min : undefined}
state={state === 'error' ? 'error' : null}
onBlur={this.onBlur.bind(this)}
onFocus={this.onFocus.bind(this)}
onKeyDown={this.onKeyDown.bind(this)}
autoFocus={autoFocus}
readOnly={!editable}
value={this.renderValue()}
disabled={disabled}
size={size}
onChange={this.onChange.bind(this)}
ref={this.saveInputRef.bind(this)}
innerAfter={innerAfter}
innerAfterClassName={innerAfterClassName}
addonBefore={addonBefore}
addonAfter={addonAfter}
/>
</span>);
return (
<span
className={cls}
style={style}
dir={rtl ? 'rtl' : undefined}
{...dataAttrs}
>
<Input
{...others}
aria-valuemax={max !== Infinity ? max : undefined}
aria-valuemin={min !== -Infinity ? min : undefined}
state={state === 'error' ? 'error' : null}
onBlur={this.onBlur.bind(this)}
onFocus={this.onFocus.bind(this)}
onKeyDown={this.onKeyDown.bind(this)}
autoFocus={autoFocus}
readOnly={!editable}
value={this.renderValue()}
disabled={disabled}
size={size}
onChange={this.onChange.bind(this)}
ref={this.saveInputRef.bind(this)}
innerAfter={innerAfter}
innerAfterClassName={innerAfterClassName}
addonBefore={addonBefore}
addonAfter={addonAfter}
/>
</span>
);
}
}

Expand Down
Loading

0 comments on commit e315a2c

Please sign in to comment.