Skip to content

Commit

Permalink
feat(InputNumber): notify reason of onChange callback triggered
Browse files Browse the repository at this point in the history
  • Loading branch information
Helium-Z authored and yinkaihui committed Mar 15, 2024
1 parent 8242bc3 commit 0514b07
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 16 deletions.
13 changes: 12 additions & 1 deletion components/InputNumber/README.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,22 @@ An input box which only allows to enter number.
|value|To set value|undefined \| number \| string |`-`|-|
|formatter|Specifies the format of the value presented|(value: number \| string, info: { userTyping: boolean; input: string }) => string |`-`|Param `info` in `2.41.0`|
|onBlur|Callback when the input is blurred|(e) => void |`-`|-|
|onChange|Callback when the value changes|(value: number) => void |`-`|-|
|onChange|Callback when the value changes|(value: number, reason: [InputNumberValueChangeReason](#inputnumbervaluechangereason)) => void |`-`|`reason` in 2.61.0|
|onFocus|Callback when the input is focused|(e) => void |`-`|-|
|onKeyDown|Callback when the keyboard is pressed|(e: Event) => void |`-`|-|
|parser|Specifies the value extracted from formatter|(value: string) => number \| string |`(input) => input.replace(/[^\w\.-]+/g, '')`|-|

### InputNumberValueChangeReason

```js
// 造成输入框值改变的原因:用户输入、选中选项、选项下拉框收起、触发自动分词
export type InputNumberValueChangeReason =
| "manual"
| "increase"
| "decrease"
| "outOfRange";
```

## Methods

|Name|Description|
Expand Down
13 changes: 12 additions & 1 deletion components/InputNumber/README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,22 @@
|value|当前值|undefined \| number \| string |`-`|-|
|formatter|定义输入框展示值|(value: number \| string, info: { userTyping: boolean; input: string }) => string |`-`|Param `info` in `2.41.0`|
|onBlur|输入框失去聚焦事件的回调|(e) => void |`-`|-|
|onChange|变化回调|(value: number) => void |`-`|-|
|onChange|变化回调|(value: number, reason: [InputNumberValueChangeReason](#inputnumbervaluechangereason)) => void |`-`|`reason` in 2.61.0|
|onFocus|输入框聚焦事件的回调|(e) => void |`-`|-|
|onKeyDown|键盘事件回调|(e: Event) => void |`-`|-|
|parser|从 formatter 转换为数字,和 formatter 搭配使用。|(value: string) => number \| string |`(input) => input.replace(/[^\w\.-]+/g, '')`|-|

### InputNumberValueChangeReason

```js
// 造成输入框值改变的原因:用户输入、选中选项、选项下拉框收起、触发自动分词
export type InputNumberValueChangeReason =
| "manual"
| "increase"
| "decrease"
| "outOfRange";
```

## 方法/Methods

|名称|描述|
Expand Down
2 changes: 1 addition & 1 deletion components/InputNumber/__test__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ describe('InputNumber ', () => {

fireEvent.mouseDown(wrapper.querySelectorAll('.arco-input-number-step-button')[1]);
expect(getInputValue(wrapper)).toBe(valueStrAfterAddOnce);
expect(onChange).toBeCalledWith(valueStrAfterAddOnce);
expect(onChange).toBeCalledWith(valueStrAfterAddOnce, 'increase');
});

it('avoid Number.toFixed() error while precision is larger than 100', () => {
Expand Down
17 changes: 9 additions & 8 deletions components/InputNumber/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import cs from '../_util/classNames';
import { ArrowUp, ArrowDown } from '../_util/keycode';
import { ConfigContext } from '../ConfigProvider';
import Input, { InputProps } from '../Input';
import { RefInputType } from '../Input/interface';
import { InputNumberProps } from './interface';
import type { RefInputType } from '../Input/interface';
import type { InputNumberProps, InputNumberValueChangeReason } from './interface';
import useMergeProps from '../_util/hooks/useMergeProps';
import omit from '../_util/omit';
import useSelectionRange from './useSelectionRange';
Expand Down Expand Up @@ -109,7 +109,7 @@ function InputNumber(baseProps: InputNumberProps, ref) {

useImperativeHandle(ref, () => refInput.current, []);

const setValue = (newValue: Decimal) => {
const setValue = (newValue: Decimal, reason: InputNumberValueChangeReason) => {
setInnerValue(newValue);
if (!newValue.equals(value) && onChange) {
const newValueStr = newValue.toString({ safe: true, precision: mergedPrecision });
Expand All @@ -120,7 +120,8 @@ function InputNumber(baseProps: InputNumberProps, ref) {
? (newValueStr as any)
: newValue.isNaN
? NaN
: Number(newValueStr)
: Number(newValueStr),
reason
);
}
};
Expand Down Expand Up @@ -158,7 +159,7 @@ function InputNumber(baseProps: InputNumberProps, ref) {

// Don't correct the illegal value caused by prop value. Wait for user to take actions.
if (_isOutOfRange && refHasOperateSincePropValueChanged.current) {
setValue(getLegalValue(value));
setValue(getLegalValue(value), 'outOfRange');
}

setIsOutOfRange(_isOutOfRange);
Expand All @@ -177,7 +178,7 @@ function InputNumber(baseProps: InputNumberProps, ref) {
? getDecimal(min === -Infinity || (min <= 0 && max >= 0) ? 0 : min)
: value.add(method === 'plus' ? step : -step);

setValue(getLegalValue(finalValue));
setValue(getLegalValue(finalValue), method === 'plus' ? 'increase' : 'decrease');
refInput.current && refInput.current.focus();

// auto change while holding
Expand Down Expand Up @@ -219,7 +220,7 @@ function InputNumber(baseProps: InputNumberProps, ref) {

if (isNumber(+parsedValue) || parsedValue === '-' || !parsedValue || parsedValue === '.') {
setInputValue(rawText);
setValue(getLegalValue(getDecimal(parsedValue)));
setValue(getLegalValue(getDecimal(parsedValue)), 'manual');
updateSelectionRangePosition(event);
}
},
Expand All @@ -243,7 +244,7 @@ function InputNumber(baseProps: InputNumberProps, ref) {
onFocus?.(e);
},
onBlur: (e) => {
setValue(getLegalValue(value));
setValue(getLegalValue(value), 'outOfRange');
setIsUserTyping(false);
onBlur?.(e);
},
Expand Down
6 changes: 5 additions & 1 deletion components/InputNumber/interface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { CSSProperties, InputHTMLAttributes, ReactNode } from 'react';

// 造成输入框值改变的原因:用户输入、选中选项、选项下拉框收起、触发自动分词
export type InputNumberValueChangeReason = 'manual' | 'increase' | 'decrease' | 'outOfRange';

/**
* @title InputNumber
*/
Expand Down Expand Up @@ -106,8 +109,9 @@ export interface InputNumberProps
/**
* @zh 变化回调
* @en Callback when the value changes
* @version `reason` in 2.61.0
*/
onChange?: (value: number) => void;
onChange?: (value: number, reason?: InputNumberValueChangeReason) => void;
/**
* @zh 输入框聚焦事件的回调
* @en Callback when the input is focused
Expand Down
8 changes: 4 additions & 4 deletions components/Slider/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ const Input = function (props: InputProps) {
{...{ hideControl: true, ...beginExtraProps, ...baseProps }}
value={innerValue[0]}
key={0}
onChange={(val) => {
onChange={(val, reason) => {
handleChange([val, innerValue[1]]);
beginExtraProps?.onChange && beginExtraProps?.onChange(val);
beginExtraProps?.onChange && beginExtraProps?.onChange(val, reason);
}}
/>,
<div key={1} className={`${prefixCls}-input-range`}>
Expand All @@ -61,9 +61,9 @@ const Input = function (props: InputProps) {
{...{ hideControl: true, ...endExtraProps, ...baseProps }}
key={2}
value={innerValue[1]}
onChange={(val) => {
onChange={(val, reason) => {
handleChange([innerValue[0], val]);
endExtraProps?.onChange && endExtraProps?.onChange(val);
endExtraProps?.onChange && endExtraProps?.onChange(val, reason);
}}
/>
</div>
Expand Down

0 comments on commit 0514b07

Please sign in to comment.