Skip to content

Commit

Permalink
fix(InputNumber): 修复部分小数点数字无法输入问题 (#2264)
Browse files Browse the repository at this point in the history
* fix(input-number): can not input some decimal numbers

* fix: update snapshots

* chore: update snapshot

---------

Co-authored-by: Uyarn <uyarnchen@gmail.com>
  • Loading branch information
chaishi and uyarn authored Jun 6, 2023
1 parent bbb88d8 commit 087a059
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 34 deletions.
2 changes: 1 addition & 1 deletion src/_common
Submodule _common updated 35 files
+2 −11 docs/mobile/api_v2/dropdown-menu.md
+1 −1 docs/mobile/api_v2/icon.md
+6 −0 docs/mobile/api_v2/indexes.md
+21 −0 docs/mobile/api_v2/table.md
+5 −1 docs/mobile/api_v2/upload.md
+42 −28 docs/mobile/overview.md
+1 −1 docs/web/api/table.en-US.md
+1 −1 docs/web/api/table.md
+1 −0 js/input-number/large-number.ts
+47 −43 js/input-number/number.ts
+1 −0 style/mobile/components/button/v2/_index.less
+1 −1 style/mobile/components/dropdown-item/v2/_index.less
+1 −0 style/mobile/components/image/v2/_index.less
+1 −0 style/mobile/components/indexes/v2/_index.less
+1 −0 style/mobile/components/input/v2/_index.less
+5 −1 style/mobile/components/list/_index.less
+1 −1 style/mobile/components/overlay/_var.less
+1 −0 style/mobile/components/picker/v2/_index.less
+4 −4 style/mobile/components/progress/v2/_index.less
+1 −1 style/mobile/components/step-item/v2/_index.less
+1,135 −0 style/mobile/components/table/_index.less
+49 −0 style/mobile/components/table/_mixin.less
+89 −0 style/mobile/components/table/_var.less
+10 −0 style/mobile/components/table/mixins/_reset.less
+43 −0 style/mobile/components/table/mixins/_scrollbar.less
+17 −0 style/mobile/components/table/mixins/_text.less
+1 −1 style/mobile/components/toast/v2/_var.less
+5 −4 style/mobile/components/upload/v2/_index.less
+7 −1 style/mobile/components/upload/v2/_var.less
+1 −0 style/web/components/badge/_index.less
+7 −0 style/web/components/dialog/_index.less
+4 −1 style/web/components/menu/_index.less
+4 −0 test/unit/input-number/compareLargeNumber.test.js
+0 −21 test/unit/input-number/formatToNumber.test.js
+83 −1 test/unit/input-number/number.test.js
2 changes: 1 addition & 1 deletion src/input-number/_example/center.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default function InputNumberExample() {
<InputNumber
value={decimalValue}
onChange={setDecimalValue}
decimalPlaces={0}
// decimalPlaces={0}
max={5}
autoWidth
/>
Expand Down
2 changes: 2 additions & 0 deletions src/input-number/_example/format.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ export default function InputNumberExample() {
format={(value) => `${value} %`}
value={value}
onChange={setValue}
style={{ width: 250 }}
/>
<InputNumber
decimalPlaces={2}
format={(_, { fixedNumber }) => `${fixedNumber} %`}
value={value1}
onChange={setValue1}
style={{ width: 250 }}
/>
</Space>
);
Expand Down
2 changes: 1 addition & 1 deletion src/input-number/input-number.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`<br/> | N
onChange | Function | | Typescript:`(value: T, context: ChangeContext) => void`<br/>[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/input-number/type.ts)。<br/>`interface ChangeContext { type: ChangeSource; e: InputEvent \| MouseEvent \| FocusEvent \| KeyboardEvent }`<br/><br/>`type ChangeSource = 'add' \| 'reduce' \| 'input' \| 'blur' \| 'enter' \| 'clear'`<br/> | N
onChange | Function | | Typescript:`(value: T, context: ChangeContext) => void`<br/>[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/input-number/type.ts)。<br/>`interface ChangeContext { type: ChangeSource; e: InputEvent \| MouseEvent \| FocusEvent \| KeyboardEvent \| CompositionEvent }`<br/><br/>`type ChangeSource = 'add' \| 'reduce' \| 'input' \| 'blur' \| 'enter' \| 'clear' \| 'props'`<br/> | N
onEnter | Function | | Typescript:`(value: InputNumberValue, context: { e: KeyboardEvent }) => void`<br/> | N
onFocus | Function | | Typescript:`(value: InputNumberValue, context: { e: FocusEvent }) => void`<br/> | N
onKeydown | Function | | Typescript:`(value: InputNumberValue, context: { e: KeyboardEvent }) => void`<br/> | N
Expand Down
2 changes: 1 addition & 1 deletion src/input-number/input-number.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`<br/>失去焦点时触发 | N
onChange | Function | | TS 类型:`(value: T, context: ChangeContext) => void`<br/>值变化时触发,`type` 表示触发本次变化的来源。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/input-number/type.ts)。<br/>`interface ChangeContext { type: ChangeSource; e: InputEvent \| MouseEvent \| FocusEvent \| KeyboardEvent }`<br/><br/>`type ChangeSource = 'add' \| 'reduce' \| 'input' \| 'blur' \| 'enter' \| 'clear'`<br/> | N
onChange | Function | | TS 类型:`(value: T, context: ChangeContext) => void`<br/>值变化时触发,`type` 表示触发本次变化的来源。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/input-number/type.ts)。<br/>`interface ChangeContext { type: ChangeSource; e: InputEvent \| MouseEvent \| FocusEvent \| KeyboardEvent \| CompositionEvent }`<br/><br/>`type ChangeSource = 'add' \| 'reduce' \| 'input' \| 'blur' \| 'enter' \| 'clear' \| 'props'`<br/> | N
onEnter | Function | | TS 类型:`(value: InputNumberValue, context: { e: KeyboardEvent }) => void`<br/>回车键按下时触发 | N
onFocus | Function | | TS 类型:`(value: InputNumberValue, context: { e: FocusEvent }) => void`<br/>获取焦点时触发 | N
onKeydown | Function | | TS 类型:`(value: InputNumberValue, context: { e: KeyboardEvent }) => void`<br/>键盘按下时触发 | N
Expand Down
9 changes: 5 additions & 4 deletions src/input-number/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<T = InputNumberValue> {
/**
Expand Down Expand Up @@ -142,10 +142,11 @@ export type InputNumberValue = number | string;
export interface ChangeContext {
type: ChangeSource;
e:
| FormEvent<HTMLDivElement>
| FormEvent<HTMLInputElement>
| MouseEvent<HTMLDivElement | SVGElement>
| FocusEvent<HTMLDivElement>
| KeyboardEvent<HTMLDivElement>;
| KeyboardEvent<HTMLDivElement>
| CompositionEvent<HTMLDivElement>;
}

export type ChangeSource = 'add' | 'reduce' | 'input' | 'blur' | 'enter' | 'clear';
export type ChangeSource = 'add' | 'reduce' | 'input' | 'blur' | 'enter' | 'clear' | 'props';
54 changes: 35 additions & 19 deletions src/input-number/useInputNumber.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -50,9 +52,10 @@ export default function useInputNumber<T extends InputNumberValue = InputNumberV
if (!value && value !== 0) return '';
let inputStr = value || value === 0 ? String(value) : '';
if (!inputRef.current.currentElement.contains?.(document.activeElement)) {
const num = formatToNumber(inputStr, {
const num = formatUnCompleteNumber(inputStr, {
decimalPlaces,
largeNumber,
isToFixed: true,
});
inputStr = num || num === 0 ? String(num) : '';
if (props.format) {
Expand All @@ -64,7 +67,23 @@ export default function useInputNumber<T extends InputNumberValue = InputNumberV

useEffect(() => {
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]);

Expand Down Expand Up @@ -118,25 +137,22 @@ export default function useInputNumber<T extends InputNumberValue = InputNumberV
};

// 1.2 -> 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<HTMLDivElement, Element> }) => {
Expand All @@ -156,12 +172,12 @@ export default function useInputNumber<T extends InputNumberValue = InputNumberV
return;
}
}
setUserInput(getUserInput(value));
const newValue = formatToNumber(value, {
const newValue = formatUnCompleteNumber(value, {
decimalPlaces,
largeNumber,
});
if ((newValue !== value && String(newValue) !== value) || Number(newValue) !== Number(tValue)) {
setUserInput(getUserInput(newValue));
if (newValue !== tValue) {
onChange(newValue as T, { type: 'blur', e: ctx.e });
}
props.onBlur?.(newValue, ctx);
Expand Down Expand Up @@ -195,7 +211,7 @@ export default function useInputNumber<T extends InputNumberValue = InputNumberV

const handleEnter = (value: string, ctx: { e: React.KeyboardEvent<HTMLDivElement> }) => {
setUserInput(getUserInput(value));
const newValue = formatToNumber(value, {
const newValue = formatUnCompleteNumber(value, {
decimalPlaces: props.decimalPlaces,
largeNumber: props.largeNumber,
});
Expand Down
16 changes: 10 additions & 6 deletions test/snap/__snapshots__/csr.test.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -120305,7 +120305,7 @@ exports[`csr snapshot test > csr test src/input-number/_example/center.jsx 1`] =
</button>
<div
class="t-input__wrap t-input--auto-width"
value="3"
value="3.41"
>
<div
class="t-input t-align-center"
Expand All @@ -120315,12 +120315,12 @@ exports[`csr snapshot test > csr test src/input-number/_example/center.jsx 1`] =
class="t-input__inner"
placeholder="please enter"
type="text"
value="3"
value="3.41"
/>
<span
class="t-input__input-pre"
>
3
3.41
</span>
</div>
</div>
Expand Down Expand Up @@ -120510,7 +120510,7 @@ exports[`csr snapshot test > csr test src/input-number/_example/center.jsx 1`] =
</button>
<div
class="t-input__wrap t-input--auto-width"
value="3"
value="3.41"
>
<div
class="t-input t-align-center"
Expand All @@ -120520,12 +120520,12 @@ exports[`csr snapshot test > csr test src/input-number/_example/center.jsx 1`] =
class="t-input__inner"
placeholder="please enter"
type="text"
value="3"
value="3.41"
/>
<span
class="t-input__input-pre"
>
3
3.41
</span>
</div>
</div>
Expand Down Expand Up @@ -120942,6 +120942,7 @@ exports[`csr snapshot test > csr test src/input-number/_example/format.jsx 1`] =
>
<div
class="t-input-number t-size-m t-input-number--row"
style="width: 250px;"
>
<button
class="t-input-number__decrease t-button t-button--theme-default t-button--variant-outline t-button--shape-square"
Expand Down Expand Up @@ -121002,6 +121003,7 @@ exports[`csr snapshot test > csr test src/input-number/_example/format.jsx 1`] =
>
<div
class="t-input-number t-size-m t-input-number--row"
style="width: 250px;"
>
<button
class="t-input-number__decrease t-button t-button--theme-default t-button--variant-outline t-button--shape-square"
Expand Down Expand Up @@ -121070,6 +121072,7 @@ exports[`csr snapshot test > csr test src/input-number/_example/format.jsx 1`] =
>
<div
class="t-input-number t-size-m t-input-number--row"
style="width: 250px;"
>
<button
class="t-input-number__decrease t-button t-button--theme-default t-button--variant-outline t-button--shape-square"
Expand Down Expand Up @@ -121130,6 +121133,7 @@ exports[`csr snapshot test > csr test src/input-number/_example/format.jsx 1`] =
>
<div
class="t-input-number t-size-m t-input-number--row"
style="width: 250px;"
>
<button
class="t-input-number__decrease t-button t-button--theme-default t-button--variant-outline t-button--shape-square"
Expand Down
Loading

0 comments on commit 087a059

Please sign in to comment.