Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(InputNumber): 修复部分小数点数字无法输入问题 #2264

Merged
merged 4 commits into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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