Skip to content

Commit 223858a

Browse files
committed
feat: support mouse wheel
1 parent 86a93fe commit 223858a

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-0
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,12 @@ online example: https://input-number.vercel.app/
238238
<td></td>
239239
<td>Specifies the inputmode of input</td>
240240
</tr>
241+
<tr>
242+
<td>wheel</td>
243+
<td>Boolean</td>
244+
<td>true</td>
245+
<td>Allows changing value with mouse wheel</td>
246+
</tr>
241247
</tbody>
242248
</table>
243249

@@ -246,6 +252,10 @@ online example: https://input-number.vercel.app/
246252
* With the <kbd>Shift</kbd> key (<kbd>Shift+⬆</kbd>, <kbd>Shift+⬇</kbd>), the input value will be changed by `10 * step`
247253
* With the <kbd>Ctrl</kbd> or <kbd>⌘</kbd> key (<kbd>Ctrl+⬆</kbd> or <kbd>⌘+⬆</kbd> or <kbd>Ctrl+⬇</kbd> or <kbd>⌘+⬇</kbd> ), the input value will be changed by `0.1 * step`
248254

255+
## Mouse Wheel
256+
* When you scroll up or down, the input value will be increased or decreased by `step`
257+
* Scrolling with the <kbd>Shift</kbd> key, the input value will be changed by `10 * step`
258+
249259
## Test Case
250260

251261
```

src/InputNumber.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export interface InputNumberProps<T extends ValueType = ValueType>
8383
upHandler?: React.ReactNode;
8484
downHandler?: React.ReactNode;
8585
keyboard?: boolean;
86+
wheel?: boolean;
8687

8788
/** Parse display value to validate number */
8889
parser?: (displayValue: string | undefined) => T;
@@ -127,6 +128,7 @@ const InternalInputNumber = React.forwardRef(
127128
upHandler,
128129
downHandler,
129130
keyboard,
131+
wheel,
130132
controls = true,
131133

132134
classNames,
@@ -517,6 +519,16 @@ const InternalInputNumber = React.forwardRef(
517519
shiftKeyRef.current = false;
518520
};
519521

522+
const onWheel = (event) => {
523+
if (wheel === false) {
524+
return;
525+
};
526+
// moving mouse wheel rises wheel event with deltaY < 0
527+
// scroll value grows from top to bottom, as screen Y coordinate
528+
onInternalStep(event.deltaY < 0);
529+
event.preventDefault();
530+
};
531+
520532
// >>> Focus & Blur
521533
const onBlur = () => {
522534
if (changeOnBlur) {
@@ -575,6 +587,7 @@ const InternalInputNumber = React.forwardRef(
575587
onBlur={onBlur}
576588
onKeyDown={onKeyDown}
577589
onKeyUp={onKeyUp}
590+
onWheel={onWheel}
578591
onCompositionStart={onCompositionStart}
579592
onCompositionEnd={onCompositionEnd}
580593
onBeforeInput={onBeforeInput}

tests/wheel.test.tsx

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import KeyCode from 'rc-util/lib/KeyCode';
2+
import InputNumber from '../src';
3+
import { fireEvent, render } from './util/wrapper';
4+
5+
describe('InputNumber.Wheel', () => {
6+
it('wheel up', () => {
7+
const onChange = jest.fn();
8+
const { container } = render(<InputNumber onChange={onChange} />);
9+
fireEvent.wheel(container.querySelector('input'), {deltaY: -1});
10+
expect(onChange).toHaveBeenCalledWith(1);
11+
});
12+
13+
it('wheel up with pressing shift key', () => {
14+
const onChange = jest.fn();
15+
const { container } = render(<InputNumber onChange={onChange} step={0.01} value={1.2} />);
16+
fireEvent.keyDown(container.querySelector('input'), {
17+
which: KeyCode.SHIFT,
18+
key: 'Shift',
19+
keyCode: KeyCode.SHIFT,
20+
shiftKey: true,
21+
});
22+
fireEvent.wheel(container.querySelector('input'), {deltaY: -1});
23+
expect(onChange).toHaveBeenCalledWith(1.3);
24+
});
25+
26+
it('wheel down', () => {
27+
const onChange = jest.fn();
28+
const { container } = render(<InputNumber onChange={onChange} />);
29+
fireEvent.wheel(container.querySelector('input'), {deltaY: 1});
30+
expect(onChange).toHaveBeenCalledWith(-1);
31+
});
32+
33+
it('wheel down with pressing shift key', () => {
34+
const onChange = jest.fn();
35+
const { container } = render(<InputNumber onChange={onChange} step={0.01} value={1.2} />);
36+
fireEvent.keyDown(container.querySelector('input'), {
37+
which: KeyCode.SHIFT,
38+
key: 'Shift',
39+
keyCode: KeyCode.SHIFT,
40+
shiftKey: true,
41+
});
42+
fireEvent.wheel(container.querySelector('input'), {deltaY: 1});
43+
expect(onChange).toHaveBeenCalledWith(1.1);
44+
});
45+
46+
it('disabled wheel', () => {
47+
const onChange = jest.fn();
48+
const { container } = render(<InputNumber wheel={false} onChange={onChange} />);
49+
50+
fireEvent.wheel(container.querySelector('input'), {deltaY: -1});
51+
expect(onChange).not.toHaveBeenCalled();
52+
53+
fireEvent.wheel(container.querySelector('input'), {deltaY: 1});
54+
expect(onChange).not.toHaveBeenCalled();
55+
});
56+
57+
it('wheel is limited to range', () => {
58+
const onChange = jest.fn();
59+
const { container } = render(<InputNumber onChange={onChange} min={-3} max={3} />);
60+
fireEvent.keyDown(container.querySelector('input'), {
61+
which: KeyCode.SHIFT,
62+
key: 'Shift',
63+
keyCode: KeyCode.SHIFT,
64+
shiftKey: true,
65+
});
66+
fireEvent.wheel(container.querySelector('input'), {deltaY: -1});
67+
expect(onChange).toHaveBeenCalledWith(3);
68+
fireEvent.wheel(container.querySelector('input'), {deltaY: 1});
69+
expect(onChange).toHaveBeenCalledWith(-3);
70+
});
71+
});

0 commit comments

Comments
 (0)