From 804c1fa5c575c0f6d4651cae79cc589cd3de3981 Mon Sep 17 00:00:00 2001 From: Kermit Date: Wed, 20 Jan 2021 11:32:09 +0800 Subject: [PATCH 1/9] feat: onKeyDown support preventDefault --- docs/examples/simple.tsx | 17 +++++++++++++++++ src/InputNumber.tsx | 18 ++++++++++++++---- src/interface.ts | 2 +- tests/index.test.js | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/docs/examples/simple.tsx b/docs/examples/simple.tsx index ac6cfa45..acad46da 100644 --- a/docs/examples/simple.tsx +++ b/docs/examples/simple.tsx @@ -8,6 +8,7 @@ class Component extends React.Component { disabled: false, readOnly: false, value: 5, + preventDefault: false }; onChange = value => { @@ -27,10 +28,23 @@ class Component extends React.Component { }); }; + togglePreventDefault = () => { + this.setState({ + preventDefault: !this.state.preventDefault, + }); + }; + + onKeyDown = (e: any, preventDefault: any) => { + if (this.state.preventDefault && e.keyCode === 38) { + preventDefault(); + } + } + render() { return (
toggle readOnly +

); diff --git a/src/InputNumber.tsx b/src/InputNumber.tsx index bf67015a..2c2ba6e7 100644 --- a/src/InputNumber.tsx +++ b/src/InputNumber.tsx @@ -80,6 +80,8 @@ class InputNumber extends React.Component, InputNumber autoStepTimer: NodeJS.Timer; + onKeyDownPreventDefault: boolean; + constructor(props: InputNumberProps) { super(props); let { value } = props; @@ -217,9 +219,20 @@ class InputNumber extends React.Component, InputNumber this.stop(); } - onKeyDown = (e, ...args) => { + onKeyDown = (e: React.KeyboardEvent) => { const { onKeyDown, onPressEnter } = this.props; + const keyDownPreventDefault = () => { + this.onKeyDownPreventDefault = true; + }; + + onKeyDown?.(e, keyDownPreventDefault); + + if (this.onKeyDownPreventDefault) { + this.onKeyDownPreventDefault = false; + return + } + if (e.keyCode === KeyCode.UP) { const ratio = this.getRatio(e); this.up(e, ratio, null); @@ -235,9 +248,6 @@ class InputNumber extends React.Component, InputNumber // Trigger user key down this.recordCursorPosition(); this.lastKeyCode = e.keyCode; - if (onKeyDown) { - onKeyDown(e, ...args); - } }; onKeyUp = (e, ...args) => { diff --git a/src/interface.ts b/src/interface.ts index 6c1df989..fa05e585 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -9,7 +9,7 @@ export type InputNumberProps = { style: React.CSSProperties; className?: string; onKeyUp: (e, ...arg) => void; - onKeyDown: (e, ...arg) => void; + onKeyDown: (e: React.KeyboardEvent, preventDefault: () => void) => void; onMouseUp: (...arg) => void; onFocus: (...arg) => void; onBlur: (...arg) => void; diff --git a/tests/index.test.js b/tests/index.test.js index dd5fa33b..fb12c0b3 100644 --- a/tests/index.test.js +++ b/tests/index.test.js @@ -61,6 +61,7 @@ describe('InputNumber', () => {
{ }); }); + describe('prevent default on keydown', () => { + it('should work correctly if no prevent default', () => { + const onKeyDown = jest.fn(); + example = ReactDOM.render(, container); + inputNumber = example.refs.inputNum; + inputElement = ReactDOM.findDOMNode(inputNumber.input); + Simulate.keyDown(inputElement, { + keyCode: keyCode.UP, + }); + expect(inputNumber.state.value).to.be(99); + expect(onKeyDown.mock.calls.length).to.be(1); + }); + + it("value shouldn't change if prevent default is called", () => { + const onKeyDown = jest.fn(({ keyCode: which }, preventDefault) => { + if (which === keyCode.UP) preventDefault(); + }); + example = ReactDOM.render(, container); + inputNumber = example.refs.inputNum; + inputElement = ReactDOM.findDOMNode(inputNumber.input); + Simulate.keyDown(inputElement, { + keyCode: keyCode.UP, + }); + expect(inputNumber.state.value).to.be(98); + + Simulate.keyDown(inputElement, { + keyCode: keyCode.DOWN, + }); + expect(inputNumber.state.value).to.be(97); + + expect(onKeyDown.mock.calls.length).to.be(2); + }); + }); + describe('clickable', () => { it('up button works', () => { Simulate.mouseDown(findRenderedDOMComponentWithClass(example, 'rc-input-number-handler-up')); From a1e31d49071df1b67b6b7dda854eeaacf13e57d6 Mon Sep 17 00:00:00 2001 From: Kermit Date: Wed, 20 Jan 2021 11:38:01 +0800 Subject: [PATCH 2/9] chore: update interface --- src/interface.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interface.ts b/src/interface.ts index fa05e585..9b1a4f8c 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -9,7 +9,7 @@ export type InputNumberProps = { style: React.CSSProperties; className?: string; onKeyUp: (e, ...arg) => void; - onKeyDown: (e: React.KeyboardEvent, preventDefault: () => void) => void; + onKeyDown: (e: React.KeyboardEvent, preventDefault?: () => void) => void; onMouseUp: (...arg) => void; onFocus: (...arg) => void; onBlur: (...arg) => void; From c25cedeaa278abe50dbd7e96377afeeec47c91dd Mon Sep 17 00:00:00 2001 From: Kermit Date: Wed, 20 Jan 2021 11:42:16 +0800 Subject: [PATCH 3/9] fix: lint --- src/InputNumber.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/InputNumber.tsx b/src/InputNumber.tsx index 2c2ba6e7..debe72f1 100644 --- a/src/InputNumber.tsx +++ b/src/InputNumber.tsx @@ -343,6 +343,7 @@ class InputNumber extends React.Component, InputNumber return value; } + // eslint-disable-next-line @typescript-eslint/no-use-before-define getValidValue(value, min = this.props.min, max = this.props.max) { let val = parseFloat(value); // https://github.com/ant-design/ant-design/issues/7358 From 8bb5e7d553dbdc44b4d5003282d9d38778154dc4 Mon Sep 17 00:00:00 2001 From: Kermit Date: Wed, 20 Jan 2021 11:46:15 +0800 Subject: [PATCH 4/9] chore: optimize preventDefault --- src/InputNumber.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/InputNumber.tsx b/src/InputNumber.tsx index debe72f1..16dbc026 100644 --- a/src/InputNumber.tsx +++ b/src/InputNumber.tsx @@ -224,6 +224,7 @@ class InputNumber extends React.Component, InputNumber const keyDownPreventDefault = () => { this.onKeyDownPreventDefault = true; + e.preventDefault(); }; onKeyDown?.(e, keyDownPreventDefault); From 0ebc3d9c43efbdb1ea71d300df0af312931623fa Mon Sep 17 00:00:00 2001 From: Kermit Date: Thu, 21 Jan 2021 18:19:01 +0800 Subject: [PATCH 5/9] fix: preventDefault only for internal keycodes --- docs/examples/simple.tsx | 4 ++-- src/InputNumber.tsx | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/examples/simple.tsx b/docs/examples/simple.tsx index acad46da..afe04663 100644 --- a/docs/examples/simple.tsx +++ b/docs/examples/simple.tsx @@ -35,7 +35,7 @@ class Component extends React.Component { }; onKeyDown = (e: any, preventDefault: any) => { - if (this.state.preventDefault && e.keyCode === 38) { + if (this.state.preventDefault) { preventDefault(); } } @@ -62,7 +62,7 @@ class Component extends React.Component { toggle readOnly

diff --git a/src/InputNumber.tsx b/src/InputNumber.tsx index 07d5f0e7..73506004 100644 --- a/src/InputNumber.tsx +++ b/src/InputNumber.tsx @@ -224,7 +224,10 @@ class InputNumber extends React.Component, InputNumber const keyDownPreventDefault = () => { this.onKeyDownPreventDefault = true; - e.preventDefault(); + const preventDefaultKeyCodes = [ KeyCode.UP, KeyCode.DOWN ]; + if (preventDefaultKeyCodes.includes(e.keyCode)) { + e.preventDefault(); + } }; onKeyDown?.(e, keyDownPreventDefault); From 5d3772b48c29eba50b8c6b8ff4beb21f3e11d9ad Mon Sep 17 00:00:00 2001 From: Kermit Date: Fri, 22 Jan 2021 17:55:51 +0800 Subject: [PATCH 6/9] refactor: add keyboard prop --- docs/examples/simple.tsx | 18 +++++--------- src/InputNumber.tsx | 51 ++++++++++++++++++++-------------------- src/interface.ts | 3 ++- tests/index.test.js | 25 ++++---------------- 4 files changed, 38 insertions(+), 59 deletions(-) diff --git a/docs/examples/simple.tsx b/docs/examples/simple.tsx index afe04663..8336e8a7 100644 --- a/docs/examples/simple.tsx +++ b/docs/examples/simple.tsx @@ -8,7 +8,7 @@ class Component extends React.Component { disabled: false, readOnly: false, value: 5, - preventDefault: false + keyboard: true }; onChange = value => { @@ -28,23 +28,16 @@ class Component extends React.Component { }); }; - togglePreventDefault = () => { + toggleKeyboard = () => { this.setState({ - preventDefault: !this.state.preventDefault, + keyboard: !this.state.keyboard, }); }; - onKeyDown = (e: any, preventDefault: any) => { - if (this.state.preventDefault) { - preventDefault(); - } - } - render() { return (

-

diff --git a/src/InputNumber.tsx b/src/InputNumber.tsx index 73506004..4206ae31 100644 --- a/src/InputNumber.tsx +++ b/src/InputNumber.tsx @@ -220,38 +220,39 @@ class InputNumber extends React.Component, InputNumber } onKeyDown = (e: React.KeyboardEvent) => { - const { onKeyDown, onPressEnter } = this.props; + const { onKeyDown, onPressEnter, keyboard } = this.props; - const keyDownPreventDefault = () => { - this.onKeyDownPreventDefault = true; - const preventDefaultKeyCodes = [ KeyCode.UP, KeyCode.DOWN ]; - if (preventDefaultKeyCodes.includes(e.keyCode)) { - e.preventDefault(); - } - }; - - onKeyDown?.(e, keyDownPreventDefault); + const supportKeyCodes = [ KeyCode.UP, KeyCode.DOWN ]; - if (this.onKeyDownPreventDefault) { - this.onKeyDownPreventDefault = false; - return - } - - if (e.keyCode === KeyCode.UP) { - const ratio = this.getRatio(e); - this.up(e, ratio, null); - this.stop(); - } else if (e.keyCode === KeyCode.DOWN) { - const ratio = this.getRatio(e); - this.down(e, ratio, null); - this.stop(); - } else if (e.keyCode === KeyCode.ENTER && onPressEnter) { - onPressEnter(e); + // disable keyboard + if (keyboard === false && supportKeyCodes.includes(e.keyCode)) { + e.preventDefault(); + } else { + switch(e.keyCode) { + case KeyCode.UP: { + const ratio = this.getRatio(e); + this.up(e, ratio, null); + this.stop(); + break; + } + case KeyCode.DOWN: { + const ratio = this.getRatio(e); + this.down(e, ratio, null); + this.stop(); + break; + } + case KeyCode.ENTER: { + onPressEnter?.(e); + break; + } + default: + } } // Trigger user key down this.recordCursorPosition(); this.lastKeyCode = e.keyCode; + onKeyDown?.(e); }; onKeyUp = (e, ...args) => { diff --git a/src/interface.ts b/src/interface.ts index 9b1a4f8c..f65af56d 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -9,7 +9,7 @@ export type InputNumberProps = { style: React.CSSProperties; className?: string; onKeyUp: (e, ...arg) => void; - onKeyDown: (e: React.KeyboardEvent, preventDefault?: () => void) => void; + onKeyDown: (e: React.KeyboardEvent) => void; onMouseUp: (...arg) => void; onFocus: (...arg) => void; onBlur: (...arg) => void; @@ -36,6 +36,7 @@ export type InputNumberProps = { upHandler: React.ReactElement; downHandler: React.ReactElement; tabIndex?: number; + keyboard?: boolean; [key: string]: any; } diff --git a/tests/index.test.js b/tests/index.test.js index d2d2c16d..26b71556 100644 --- a/tests/index.test.js +++ b/tests/index.test.js @@ -140,24 +140,9 @@ describe('InputNumber', () => { }); }); - describe('prevent default on keydown', () => { - it('should work correctly if no prevent default', () => { - const onKeyDown = jest.fn(); - example = ReactDOM.render(, container); - inputNumber = example.refs.inputNum; - inputElement = ReactDOM.findDOMNode(inputNumber.input); - Simulate.keyDown(inputElement, { - keyCode: keyCode.UP, - }); - expect(inputNumber.state.value).to.be(99); - expect(onKeyDown.mock.calls.length).to.be(1); - }); - - it("value shouldn't change if prevent default is called", () => { - const onKeyDown = jest.fn(({ keyCode: which }, preventDefault) => { - if (which === keyCode.UP) preventDefault(); - }); - example = ReactDOM.render(, container); + describe('disable keyboard works', () => { + it("value shouldn't change if keyboard is disabled", () => { + example = ReactDOM.render(, container); inputNumber = example.refs.inputNum; inputElement = ReactDOM.findDOMNode(inputNumber.input); Simulate.keyDown(inputElement, { @@ -168,9 +153,7 @@ describe('InputNumber', () => { Simulate.keyDown(inputElement, { keyCode: keyCode.DOWN, }); - expect(inputNumber.state.value).to.be(97); - - expect(onKeyDown.mock.calls.length).to.be(2); + expect(inputNumber.state.value).to.be(98); }); }); From ef90e35173e5fa633c5344e3df66bd765d211b54 Mon Sep 17 00:00:00 2001 From: Kermit Date: Fri, 22 Jan 2021 18:03:03 +0800 Subject: [PATCH 7/9] chore: clean code --- src/InputNumber.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/InputNumber.tsx b/src/InputNumber.tsx index 4206ae31..eb6dcfbd 100644 --- a/src/InputNumber.tsx +++ b/src/InputNumber.tsx @@ -80,8 +80,6 @@ class InputNumber extends React.Component, InputNumber autoStepTimer: NodeJS.Timer; - onKeyDownPreventDefault: boolean; - constructor(props: InputNumberProps) { super(props); let { value } = props; From d01a69f1993723c50efdccf30317d2db3175c888 Mon Sep 17 00:00:00 2001 From: Kermit Date: Wed, 27 Jan 2021 11:10:00 +0800 Subject: [PATCH 8/9] chore: optimize code --- src/InputNumber.tsx | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/InputNumber.tsx b/src/InputNumber.tsx index eb6dcfbd..ae6c5f9b 100644 --- a/src/InputNumber.tsx +++ b/src/InputNumber.tsx @@ -222,10 +222,7 @@ class InputNumber extends React.Component, InputNumber const supportKeyCodes = [ KeyCode.UP, KeyCode.DOWN ]; - // disable keyboard - if (keyboard === false && supportKeyCodes.includes(e.keyCode)) { - e.preventDefault(); - } else { + if (keyboard !== false && supportKeyCodes.includes(e.keyCode)) { switch(e.keyCode) { case KeyCode.UP: { const ratio = this.getRatio(e); @@ -239,14 +236,14 @@ class InputNumber extends React.Component, InputNumber this.stop(); break; } - case KeyCode.ENTER: { - onPressEnter?.(e); - break; - } default: } } + if (e.keyCode === KeyCode.ENTER) { + onPressEnter?.(e); + } + // Trigger user key down this.recordCursorPosition(); this.lastKeyCode = e.keyCode; From a3a6ef496614e2561d1c614dc2c78f636315e02b Mon Sep 17 00:00:00 2001 From: Kermit Date: Wed, 27 Jan 2021 11:16:03 +0800 Subject: [PATCH 9/9] fix: clean code --- src/InputNumber.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/InputNumber.tsx b/src/InputNumber.tsx index ae6c5f9b..741ff5fa 100644 --- a/src/InputNumber.tsx +++ b/src/InputNumber.tsx @@ -223,6 +223,7 @@ class InputNumber extends React.Component, InputNumber const supportKeyCodes = [ KeyCode.UP, KeyCode.DOWN ]; if (keyboard !== false && supportKeyCodes.includes(e.keyCode)) { + // eslint-disable-next-line default-case switch(e.keyCode) { case KeyCode.UP: { const ratio = this.getRatio(e); @@ -236,7 +237,6 @@ class InputNumber extends React.Component, InputNumber this.stop(); break; } - default: } }