diff --git a/src/_common b/src/_common index 430923853..b87072b25 160000 --- a/src/_common +++ b/src/_common @@ -1 +1 @@ -Subproject commit 430923853371f2a8aa167771ad7c3282c59301ca +Subproject commit b87072b25b9532520892d159d4a03de684e0d9fd diff --git a/src/input-number/_example/center.jsx b/src/input-number/_example/center.jsx index 77ed41bd8..a5246ca71 100644 --- a/src/input-number/_example/center.jsx +++ b/src/input-number/_example/center.jsx @@ -45,7 +45,7 @@ export default function InputNumberExample() { diff --git a/src/input-number/_example/format.jsx b/src/input-number/_example/format.jsx index 80691a000..2f4d3c0d9 100644 --- a/src/input-number/_example/format.jsx +++ b/src/input-number/_example/format.jsx @@ -14,12 +14,14 @@ export default function InputNumberExample() { format={(value) => `${value} %`} value={value} onChange={setValue} + style={{ width: 250 }} /> `${fixedNumber} %`} value={value1} onChange={setValue1} + style={{ width: 250 }} /> ); diff --git a/src/input-number/input-number.en-US.md b/src/input-number/input-number.en-US.md index 547ec816b..601c41539 100644 --- a/src/input-number/input-number.en-US.md +++ b/src/input-number/input-number.en-US.md @@ -29,7 +29,7 @@ tips | TNode | - | Typescript:`string \| TNode`。[see more ts definition](htt value | String / Number | - | Typescript:`T` `type InputNumberValue = number \| string`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/input-number/type.ts) | N defaultValue | String / Number | - | uncontrolled property。Typescript:`T` `type InputNumberValue = number \| string`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/input-number/type.ts) | N onBlur | Function | | Typescript:`(value: InputNumberValue, context: { e: FocusEvent }) => void`
| N -onChange | Function | | Typescript:`(value: T, context: ChangeContext) => void`
[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/input-number/type.ts)。
`interface ChangeContext { type: ChangeSource; e: InputEvent \| MouseEvent \| FocusEvent \| KeyboardEvent }`

`type ChangeSource = 'add' \| 'reduce' \| 'input' \| 'blur' \| 'enter' \| 'clear'`
| N +onChange | Function | | Typescript:`(value: T, context: ChangeContext) => void`
[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/input-number/type.ts)。
`interface ChangeContext { type: ChangeSource; e: InputEvent \| MouseEvent \| FocusEvent \| KeyboardEvent \| CompositionEvent }`

`type ChangeSource = 'add' \| 'reduce' \| 'input' \| 'blur' \| 'enter' \| 'clear' \| 'props'`
| N onEnter | Function | | Typescript:`(value: InputNumberValue, context: { e: KeyboardEvent }) => void`
| N onFocus | Function | | Typescript:`(value: InputNumberValue, context: { e: FocusEvent }) => void`
| N onKeydown | Function | | Typescript:`(value: InputNumberValue, context: { e: KeyboardEvent }) => void`
| N diff --git a/src/input-number/input-number.md b/src/input-number/input-number.md index d6ff06e0b..31786f502 100644 --- a/src/input-number/input-number.md +++ b/src/input-number/input-number.md @@ -29,7 +29,7 @@ tips | TNode | - | 输入框下方提示文本,会根据不同的 `status` 呈 value | String / Number | - | 数字输入框的值。当值为 '' 时,输入框显示为空。TS 类型:`T` `type InputNumberValue = number \| string`。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/input-number/type.ts) | N defaultValue | String / Number | - | 数字输入框的值。当值为 '' 时,输入框显示为空。非受控属性。TS 类型:`T` `type InputNumberValue = number \| string`。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/input-number/type.ts) | N onBlur | Function | | TS 类型:`(value: InputNumberValue, context: { e: FocusEvent }) => void`
失去焦点时触发 | N -onChange | Function | | TS 类型:`(value: T, context: ChangeContext) => void`
值变化时触发,`type` 表示触发本次变化的来源。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/input-number/type.ts)。
`interface ChangeContext { type: ChangeSource; e: InputEvent \| MouseEvent \| FocusEvent \| KeyboardEvent }`

`type ChangeSource = 'add' \| 'reduce' \| 'input' \| 'blur' \| 'enter' \| 'clear'`
| N +onChange | Function | | TS 类型:`(value: T, context: ChangeContext) => void`
值变化时触发,`type` 表示触发本次变化的来源。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/input-number/type.ts)。
`interface ChangeContext { type: ChangeSource; e: InputEvent \| MouseEvent \| FocusEvent \| KeyboardEvent \| CompositionEvent }`

`type ChangeSource = 'add' \| 'reduce' \| 'input' \| 'blur' \| 'enter' \| 'clear' \| 'props'`
| N onEnter | Function | | TS 类型:`(value: InputNumberValue, context: { e: KeyboardEvent }) => void`
回车键按下时触发 | N onFocus | Function | | TS 类型:`(value: InputNumberValue, context: { e: FocusEvent }) => void`
获取焦点时触发 | N onKeydown | Function | | TS 类型:`(value: InputNumberValue, context: { e: KeyboardEvent }) => void`
键盘按下时触发 | N diff --git a/src/input-number/type.ts b/src/input-number/type.ts index c644c1ae6..932a1b094 100644 --- a/src/input-number/type.ts +++ b/src/input-number/type.ts @@ -6,7 +6,7 @@ import { InputProps } from '../input'; import { TNode } from '../common'; -import { MouseEvent, KeyboardEvent, FocusEvent, FormEvent } from 'react'; +import { MouseEvent, KeyboardEvent, FocusEvent, FormEvent, CompositionEvent } from 'react'; export interface TdInputNumberProps { /** @@ -142,10 +142,11 @@ export type InputNumberValue = number | string; export interface ChangeContext { type: ChangeSource; e: - | FormEvent + | FormEvent | MouseEvent | FocusEvent - | KeyboardEvent; + | KeyboardEvent + | CompositionEvent; } -export type ChangeSource = 'add' | 'reduce' | 'input' | 'blur' | 'enter' | 'clear'; +export type ChangeSource = 'add' | 'reduce' | 'input' | 'blur' | 'enter' | 'clear' | 'props'; diff --git a/src/input-number/useInputNumber.tsx b/src/input-number/useInputNumber.tsx index 39cd64e0b..960f89865 100644 --- a/src/input-number/useInputNumber.tsx +++ b/src/input-number/useInputNumber.tsx @@ -9,10 +9,12 @@ import { canAddNumber, canInputNumber, canReduceNumber, - formatToNumber, + formatUnCompleteNumber, + canSetValue, getMaxOrMinValidateResult, getStepValue, formatThousandths, + largeNumberToFixed, } from '../_common/js/input-number/number'; import { InputProps } from '../input'; @@ -50,9 +52,10 @@ export default function useInputNumber { const inputValue = [undefined, null].includes(tValue) ? '' : String(tValue); - setUserInput(getUserInput(inputValue)); + // userInput.value 为非合法数字,则表示用户正在输入,此时无需处理 + if (!largeNumber && !Number.isNaN(userInput)) { + if (parseFloat(userInput) !== tValue) { + setUserInput(getUserInput(inputValue)); + } + const fixedNumber = Number(largeNumberToFixed(inputValue, decimalPlaces, largeNumber)); + if (decimalPlaces !== undefined && fixedNumber !== tValue) { + onChange(fixedNumber as T, { type: 'props', e: undefined }); + } + } + if (largeNumber) { + const tmpUserInput = getUserInput(inputValue); + setUserInput(tmpUserInput); + if (decimalPlaces !== undefined && largeNumberToFixed(inputValue, decimalPlaces, largeNumber) !== tValue) { + onChange(tmpUserInput as T, { type: 'props', e: undefined }); + } + } // eslint-disable-next-line }, [tValue]); @@ -118,25 +137,22 @@ export default function useInputNumber 1. -> 1 - const onInnerInputChange: InputProps['onChange'] = (val, { e }) => { - // eslint-disable-next-line no-param-reassign - val = formatThousandths(val); // 处理千分位 + const onInnerInputChange: InputProps['onChange'] = (inputValue, { e }) => { + // 处理千分位 + const val = formatThousandths(inputValue); if (!canInputNumber(val, largeNumber)) return; - if (props.largeNumber) { + + setUserInput(val); + + if (largeNumber) { onChange(val as T, { type: 'input', e }); return; } - // specialCode 新增或删除这些字符时不触发 change 事件 - const isDelete = (e as any).nativeEvent.inputType === 'deleteContentBackward'; - const inputSpecialCode = specialCode.includes(val.slice(-1)) || /\.\d*0+$/.test(val); - const deleteSpecialCode = isDelete && specialCode.includes(String(userInput).slice(-1)); - if ((!isNaN(Number(val)) && !inputSpecialCode) || deleteSpecialCode) { + + if (canSetValue(String(val), Number(tValue))) { const newVal = val === '' ? undefined : Number(val); onChange(newVal as T, { type: 'input', e }); } - if (inputSpecialCode || deleteSpecialCode) { - setUserInput(val); - } }; const handleBlur = (value: string, ctx: { e: React.FocusEvent }) => { @@ -156,12 +172,12 @@ export default function useInputNumber }) => { setUserInput(getUserInput(value)); - const newValue = formatToNumber(value, { + const newValue = formatUnCompleteNumber(value, { decimalPlaces: props.decimalPlaces, largeNumber: props.largeNumber, }); diff --git a/test/snap/__snapshots__/csr.test.jsx.snap b/test/snap/__snapshots__/csr.test.jsx.snap index a6074c0d0..3588805d5 100644 --- a/test/snap/__snapshots__/csr.test.jsx.snap +++ b/test/snap/__snapshots__/csr.test.jsx.snap @@ -120305,7 +120305,7 @@ exports[`csr snapshot test > csr test src/input-number/_example/center.jsx 1`] =
csr test src/input-number/_example/center.jsx 1`] = class="t-input__inner" placeholder="please enter" type="text" - value="3" + value="3.41" /> - 3 + 3.41
@@ -120510,7 +120510,7 @@ exports[`csr snapshot test > csr test src/input-number/_example/center.jsx 1`] =
csr test src/input-number/_example/center.jsx 1`] = class="t-input__inner" placeholder="please enter" type="text" - value="3" + value="3.41" /> - 3 + 3.41
@@ -120942,6 +120942,7 @@ exports[`csr snapshot test > csr test src/input-number/_example/format.jsx 1`] = >
"`; -exports[`ssr snapshot test > ssr test src/input-number/_example/format.jsx 1`] = `"
"`; +exports[`ssr snapshot test > ssr test src/input-number/_example/format.jsx 1`] = `"
"`; exports[`ssr snapshot test > ssr test src/input-number/_example/large-number.jsx 1`] = `"
"`;