Skip to content
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
14 changes: 13 additions & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,13 @@ nav:
<td>readOnly</td>
<td>Boolean</td>
<td>false</td>
<td>Specifies that an InputNumber is read only </td>
<td>Specifies that an InputNumber is read only</td>
</tr>
<tr>
<td>changeOnWheel</td>
<td>Boolean</td>
<td>false</td>
<td>Specifies that the value is set using the mouse wheel</td>
</tr>
<tr>
<td>controls</td>
Expand Down Expand Up @@ -136,6 +142,12 @@ nav:
<td></td>
<td>Called when an element gets focus</td>
</tr>
<tr>
<td>onStep</td>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to use onChange?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I was tasked with making a request to the server by clicking the arrows and not committing to setting values in the input field. And when entering a value it is through the input field to set it. Accordingly, I track the source of input via onStep and if an arrow was pressed, I forbid onChange to set the value.

<td>(value: T, info: { offset: ValueType; type: 'up' | 'down', emitter: 'handler' | 'keydown' | 'wheel' }) => void</td>
<td></td>
<td>Called when the user clicks the arrows on the keyboard or interface and when the mouse wheel is spun.</td>
</tr>
<tr>
<td>style</td>
<td>Object</td>
Expand Down
46 changes: 46 additions & 0 deletions docs/demo/on-step.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* eslint no-console:0 */
import InputNumber from '@rc-component/input-number';
import React, { useState } from 'react';
import '../../assets/index.less';

export default () => {
const [emitter, setEmitter] = useState('interface buttons (up)');
const [value, setValue] = React.useState<string | number>(0);

const onChange = (val: number) => {
console.warn('onChange:', val, typeof val);
setValue(val);
};

const onStep = (_: number, info: { offset: number; type: 'up' | 'down', emitter: 'handler' | 'keyboard' | 'wheel' }) => {
if (info.emitter === 'handler') {
setEmitter(`interface buttons (${info.type})`);
}

if (info.emitter === 'keyboard') {
setEmitter(`keyboard (${info.type})`);
}

if (info.emitter === 'wheel') {
setEmitter(`mouse wheel (${info.type})`);
}
};

return (
<div style={{ margin: 10 }}>
<h3>onStep callback</h3>
<InputNumber
aria-label="onStep callback example"
min={0}
max={10}
style={{ width: 100 }}
value={value}
changeOnWheel
onChange={onChange}
onStep={onStep}
/>

<div style={{ marginTop: 10 }}>Triggered by: {emitter}</div>
</div>
);
};
4 changes: 4 additions & 0 deletions docs/example.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ nav:

<code src="./demo/small-step.tsx"></code>

## on-step

<code src="./demo/on-step.tsx"></code>

## wheel

<code src="./demo/wheel.tsx"></code>
Expand Down
9 changes: 5 additions & 4 deletions src/InputNumber.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export interface InputNumberProps<T extends ValueType = ValueType>
onChange?: (value: T | null) => void;
onPressEnter?: React.KeyboardEventHandler<HTMLInputElement>;

onStep?: (value: T, info: { offset: ValueType; type: 'up' | 'down' }) => void;
onStep?: (value: T, info: { offset: ValueType; type: 'up' | 'down', emitter: 'handler' | 'keyboard' | 'wheel' }) => void;

/**
* Trigger change onBlur event.
Expand Down Expand Up @@ -432,7 +432,7 @@ const InternalInputNumber = React.forwardRef(
};

// ============================= Step =============================
const onInternalStep = (up: boolean) => {
const onInternalStep = (up: boolean, emitter: 'handler' | 'keyboard' | 'wheel') => {
// Ignore step since out of range
if ((up && upDisabled) || (!up && downDisabled)) {
return;
Expand All @@ -454,6 +454,7 @@ const InternalInputNumber = React.forwardRef(
onStep?.(getDecimalValue(stringMode, updatedValue), {
offset: shiftKeyRef.current ? getDecupleSteps(step) : step,
type: up ? 'up' : 'down',
emitter,
});

inputRef.current?.focus();
Expand Down Expand Up @@ -511,7 +512,7 @@ const InternalInputNumber = React.forwardRef(

// Do step
if (!compositionRef.current && ['Up', 'ArrowUp', 'Down', 'ArrowDown'].includes(key)) {
onInternalStep(key === 'Up' || key === 'ArrowUp');
onInternalStep(key === 'Up' || key === 'ArrowUp', 'keyboard');
event.preventDefault();
}
};
Expand All @@ -526,7 +527,7 @@ const InternalInputNumber = React.forwardRef(
const onWheel = (event) => {
// moving mouse wheel rises wheel event with deltaY < 0
// scroll value grows from top to bottom, as screen Y coordinate
onInternalStep(event.deltaY < 0);
onInternalStep(event.deltaY < 0, 'wheel');
event.preventDefault();
};
const input = inputRef.current;
Expand Down
6 changes: 3 additions & 3 deletions src/StepHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface StepHandlerProps {
downNode?: React.ReactNode;
upDisabled?: boolean;
downDisabled?: boolean;
onStep: (up: boolean) => void;
onStep: (up: boolean, emitter: 'handler' | 'keyboard' | 'wheel') => void;
}

export default function StepHandler({
Expand Down Expand Up @@ -48,11 +48,11 @@ export default function StepHandler({
e.preventDefault();
onStopStep();

onStepRef.current(up);
onStepRef.current(up, 'handler');

// Loop step for interval
function loopStep() {
onStepRef.current(up);
onStepRef.current(up, 'handler');

stepTimeoutRef.current = setTimeout(loopStep, STEP_INTERVAL);
}
Expand Down
21 changes: 12 additions & 9 deletions tests/click.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ describe('InputNumber.Click', () => {
selector: string,
changedValue: string | number,
stepType: 'up' | 'down',
emitter: 'handler' | 'keyboard' | 'wheel',
) {
it(name, () => {
const onChange = jest.fn();
Expand All @@ -36,27 +37,27 @@ describe('InputNumber.Click', () => {
fireEvent.click(container.querySelector(selector));
expect(onChange).toHaveBeenCalledTimes(1);
expect(onChange).toHaveBeenCalledWith(changedValue);
expect(onStep).toHaveBeenCalledWith(changedValue, { offset: 1, type: stepType });
expect(onStep).toHaveBeenCalledWith(changedValue, { offset: 1, type: stepType, emitter });
unmount();
});
}

describe('basic work', () => {
testInputNumber('up button', { defaultValue: 10 }, '.rc-input-number-handler-up', 11, 'up');
testInputNumber('up button', { defaultValue: 10 }, '.rc-input-number-handler-up', 11, 'up', 'handler');

testInputNumber('down button', { value: 10 }, '.rc-input-number-handler-down', 9, 'down');
testInputNumber('down button', { value: 10 }, '.rc-input-number-handler-down', 9, 'down', 'handler');
});

describe('empty input', () => {
testInputNumber('up button', {}, '.rc-input-number-handler-up', 1, 'up');
testInputNumber('up button', {}, '.rc-input-number-handler-up', 1, 'up', 'handler');

testInputNumber('down button', {}, '.rc-input-number-handler-down', -1, 'down');
testInputNumber('down button', {}, '.rc-input-number-handler-down', -1, 'down', 'handler');
});

describe('empty with min & max', () => {
testInputNumber('up button', { min: 6, max: 10 }, '.rc-input-number-handler-up', 6, 'up');
testInputNumber('up button', { min: 6, max: 10 }, '.rc-input-number-handler-up', 6, 'up', 'handler');

testInputNumber('down button', { min: 6, max: 10 }, '.rc-input-number-handler-down', 6, 'down');
testInputNumber('down button', { min: 6, max: 10 }, '.rc-input-number-handler-down', 6, 'down', 'handler');
});

describe('null with min & max', () => {
Expand All @@ -66,6 +67,7 @@ describe('InputNumber.Click', () => {
'.rc-input-number-handler-up',
6,
'up',
'handler',
);

testInputNumber(
Expand All @@ -74,6 +76,7 @@ describe('InputNumber.Click', () => {
'.rc-input-number-handler-down',
6,
'down',
'handler',
);
});

Expand Down Expand Up @@ -183,7 +186,7 @@ describe('InputNumber.Click', () => {
});

expect(onChange).toHaveBeenCalledWith(1.1);
expect(onStep).toHaveBeenCalledWith(1.1, { offset: '0.1', type: 'down' });
expect(onStep).toHaveBeenCalledWith(1.1, { offset: '0.1', type: 'down', emitter: 'keyboard' });
});

it('click up button with pressing shift key', () => {
Expand All @@ -201,6 +204,6 @@ describe('InputNumber.Click', () => {
keyCode: KeyCode.UP,
});
expect(onChange).toHaveBeenCalledWith(1.3);
expect(onStep).toHaveBeenCalledWith(1.3, { offset: '0.1', type: 'up' });
expect(onStep).toHaveBeenCalledWith(1.3, { offset: '0.1', type: 'up', emitter: 'keyboard' });
});
});
Loading