From 2b66756d5e2d73c52ba75adfd4a2ba831cccf255 Mon Sep 17 00:00:00 2001 From: zombiej Date: Fri, 24 Sep 2021 15:44:43 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20fix=20=E3=80=82change?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/InputNumber.tsx | 32 ++++++++++++++++++++------------ src/hooks/usePromiseFrame.ts | 23 +++++++++++++++++++++++ 2 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 src/hooks/usePromiseFrame.ts diff --git a/src/InputNumber.tsx b/src/InputNumber.tsx index b5def745..850c4dd0 100644 --- a/src/InputNumber.tsx +++ b/src/InputNumber.tsx @@ -7,6 +7,7 @@ import StepHandler from './StepHandler'; import { getNumberPrecision, num2str, validateNumber } from './utils/numberUtil'; import useCursor from './hooks/useCursor'; import useUpdateEffect from './hooks/useUpdateEffect'; +import usePromiseFrame from './hooks/usePromiseFrame'; /** * We support `stringMode` which need handle correct type when user call in onChange @@ -323,6 +324,8 @@ const InputNumber = React.forwardRef( }; // ========================== User Input ========================== + const onNextPromise = usePromiseFrame(); + // >>> Collect input value const collectInputValue = (inputStr: string) => { recordCursor(); @@ -338,6 +341,22 @@ const InputNumber = React.forwardRef( triggerValueUpdate(finalDecimal, true); } } + + // Trigger onInput later to let user customize value if they want do handle something after onChange + onInput?.(inputStr); + + // optimize for chinese input experience + // https://github.com/ant-design/ant-design/issues/8196 + onNextPromise(() => { + let nextInputStr = inputStr; + if (!parser) { + nextInputStr = inputStr.replace(/。/g, '.'); + } + + if (nextInputStr !== inputStr) { + collectInputValue(nextInputStr); + } + }); }; // >>> Composition @@ -353,18 +372,7 @@ const InputNumber = React.forwardRef( // >>> Input const onInternalInput: React.ChangeEventHandler = (e) => { - let inputStr = e.target.value; - - // optimize for chinese input experience - // https://github.com/ant-design/ant-design/issues/8196 - if (!parser) { - inputStr = inputStr.replace(/。/g, '.'); - } - - collectInputValue(inputStr); - - // Trigger onInput later to let user customize value if they want do handle something after onChange - onInput?.(inputStr); + collectInputValue(e.target.value); }; // ============================= Step ============================= diff --git a/src/hooks/usePromiseFrame.ts b/src/hooks/usePromiseFrame.ts new file mode 100644 index 00000000..d0902577 --- /dev/null +++ b/src/hooks/usePromiseFrame.ts @@ -0,0 +1,23 @@ +import { useRef, useEffect } from 'react'; +import raf from 'rc-util/lib/raf'; + +/** + * Always trigger latest once when call multiple time + */ +export default () => { + const idRef = useRef(0); + + const cleanUp = () => { + raf.cancel(idRef.current); + }; + + useEffect(() => cleanUp, []); + + return (callback: () => void) => { + cleanUp(); + + idRef.current = raf(() => { + callback(); + }); + }; +}; From f17d34b18adb4cd795e4bff5ad76919c18371100 Mon Sep 17 00:00:00 2001 From: zombiej Date: Fri, 24 Sep 2021 16:02:14 +0800 Subject: [PATCH 2/3] test: Fix test case --- tests/github.test.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/github.test.tsx b/tests/github.test.tsx index cd269cad..3095c887 100644 --- a/tests/github.test.tsx +++ b/tests/github.test.tsx @@ -337,11 +337,21 @@ describe('InputNumber.Github', () => { // https://github.com/ant-design/ant-design/issues/8196 it('Allow input 。', () => { + jest.useFakeTimers(); + const onChange = jest.fn(); const wrapper = mount(); wrapper.changeValue('8。1'); + + act(() => { + jest.runAllTimers(); + wrapper.update(); + }); + expect(wrapper.getInputValue()).toEqual('8.1'); expect(onChange).toHaveBeenCalledWith(8.1); + + jest.useRealTimers(); }); // https://github.com/ant-design/ant-design/issues/25614 From 537436711b2f5f83055da4669486f83f33100f40 Mon Sep 17 00:00:00 2001 From: zombiej Date: Fri, 24 Sep 2021 16:30:01 +0800 Subject: [PATCH 3/3] test: fix test case --- src/InputNumber.tsx | 4 ++-- src/hooks/{usePromiseFrame.ts => useFrame.ts} | 0 tests/github.test.tsx | 7 +++---- 3 files changed, 5 insertions(+), 6 deletions(-) rename src/hooks/{usePromiseFrame.ts => useFrame.ts} (100%) diff --git a/src/InputNumber.tsx b/src/InputNumber.tsx index 850c4dd0..7cab51d1 100644 --- a/src/InputNumber.tsx +++ b/src/InputNumber.tsx @@ -7,7 +7,7 @@ import StepHandler from './StepHandler'; import { getNumberPrecision, num2str, validateNumber } from './utils/numberUtil'; import useCursor from './hooks/useCursor'; import useUpdateEffect from './hooks/useUpdateEffect'; -import usePromiseFrame from './hooks/usePromiseFrame'; +import useFrame from './hooks/useFrame'; /** * We support `stringMode` which need handle correct type when user call in onChange @@ -324,7 +324,7 @@ const InputNumber = React.forwardRef( }; // ========================== User Input ========================== - const onNextPromise = usePromiseFrame(); + const onNextPromise = useFrame(); // >>> Collect input value const collectInputValue = (inputStr: string) => { diff --git a/src/hooks/usePromiseFrame.ts b/src/hooks/useFrame.ts similarity index 100% rename from src/hooks/usePromiseFrame.ts rename to src/hooks/useFrame.ts diff --git a/tests/github.test.tsx b/tests/github.test.tsx index 3095c887..19c4c38f 100644 --- a/tests/github.test.tsx +++ b/tests/github.test.tsx @@ -11,6 +11,7 @@ describe('InputNumber.Github', () => { }); afterEach(() => { + jest.clearAllTimers(); jest.useRealTimers(); }); @@ -337,8 +338,6 @@ describe('InputNumber.Github', () => { // https://github.com/ant-design/ant-design/issues/8196 it('Allow input 。', () => { - jest.useFakeTimers(); - const onChange = jest.fn(); const wrapper = mount(); wrapper.changeValue('8。1'); @@ -348,10 +347,10 @@ describe('InputNumber.Github', () => { wrapper.update(); }); + wrapper.update(); + expect(wrapper.getInputValue()).toEqual('8.1'); expect(onChange).toHaveBeenCalledWith(8.1); - - jest.useRealTimers(); }); // https://github.com/ant-design/ant-design/issues/25614