Skip to content

Commit

Permalink
support of keyboard navigation combinations & simple formatter
Browse files Browse the repository at this point in the history
modify README(short keys)
[bug fix] counting remain

fix test on useTouch
  • Loading branch information
Jiramew committed Mar 5, 2017
1 parent 6633c7f commit b1c5f96
Show file tree
Hide file tree
Showing 6 changed files with 283 additions and 28 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,20 @@ react-native run-ios
<td></td>
<td>custom the down step element</td>
</tr>
<tr>
<td>formatter</td>
<td>Function</td>
<td></td>
<td>Specifies the format of the value presented</td>
</tr>
</tbody>
</table>

## Keyboard Navigation
* When you hit the <kbd>⬆</kbd> or <kbd>⬇</kbd> key, the input value will be increased or decreased by `step`
* With the <kbd>Shift</kbd> key (<kbd>Shift+⬆</kbd>, <kbd>Shift+⬇</kbd>), the input value will be changed by `10 * step`
* 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`

## Test Case

```
Expand Down
1 change: 1 addition & 0 deletions examples/combination-key-format.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
placeholder
56 changes: 56 additions & 0 deletions examples/combination-key-format.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* eslint no-console:0 */
require('rc-input-number/assets/index.less');
const InputNumber = require('rc-input-number');
const React = require('react');
const ReactDOM = require('react-dom');

const Component = React.createClass({
getInitialState() {
return {
disabled: false,
readOnly: false,
value: 5,
};
},
onChange(value) {
console.log('onChange:', value);
this.setState({ value });
},
toggleDisabled() {
this.setState({
disabled: !this.state.disabled,
});
},
toggleReadOnly() {
this.setState({
readOnly: !this.state.readOnly,
});
},
format(num) {
return `$ ${num}`;
},
render() {
return (
<div style={{ margin: 10 }}>
<InputNumber
min={-8000}
max={10000}
value={this.state.value}
style={{ width: 100 }}
readOnly={this.state.readOnly}
onChange={this.onChange}
disabled={this.state.disabled}
autoFocus={false}
step={0.5}
formatter={this.format}
/>
<p>
<button onClick={this.toggleDisabled}>toggle Disabled</button>
<button onClick={this.toggleReadOnly}>toggle readOnly</button>
</p>
</div>
);
},
});

ReactDOM.render(<Component/>, document.getElementById('__react-content'));
33 changes: 28 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const InputNumber = React.createClass({
upHandler: PropTypes.node,
downHandler: PropTypes.node,
useTouch: PropTypes.bool,
formatter: PropTypes.func,
},

mixins: [mixin],
Expand All @@ -56,9 +57,13 @@ const InputNumber = React.createClass({

onKeyDown(e, ...args) {
if (e.keyCode === 38) {
this.up(e);
const ratio = this.getRatio(e);
this.up(e, ratio);
this.stop();
} else if (e.keyCode === 40) {
this.down(e);
const ratio = this.getRatio(e);
this.down(e, ratio);
this.stop();
}
const { onKeyDown } = this.props;
if (onKeyDown) {
Expand All @@ -74,6 +79,16 @@ const InputNumber = React.createClass({
}
},

getRatio(e) {
let ratio = 1;
if (e.metaKey || e.ctrlKey) {
ratio = 0.1;
} else if (e.shiftKey) {
ratio = 10;
}
return ratio;
},

getValueFromEvent(e) {
return e.target.value;
},
Expand All @@ -82,6 +97,13 @@ const InputNumber = React.createClass({
this.refs.input.focus();
},

formatWrapper(num) {
if (this.props.formatter) {
return this.props.formatter(num);
}
return num;
},

render() {
const props = { ...this.props };
const { prefixCls, disabled, readOnly, useTouch } = props;
Expand Down Expand Up @@ -145,6 +167,7 @@ const InputNumber = React.createClass({
onMouseLeave: this.stop,
};
}
const inputDisplayValueFormat = this.formatWrapper(inputDisplayValue);

// ref for test
return (
Expand Down Expand Up @@ -188,8 +211,8 @@ const InputNumber = React.createClass({
autoComplete="off"
onFocus={this.onFocus}
onBlur={this.onBlur}
onKeyDown={this.onKeyDown}
onKeyUp={this.onKeyUp}
onKeyDown={editable ? this.onKeyDown : noop}
onKeyUp={editable ? this.onKeyUp : noop}
autoFocus={props.autoFocus}
readOnly={props.readOnly}
disabled={props.disabled}
Expand All @@ -198,7 +221,7 @@ const InputNumber = React.createClass({
name={props.name}
onChange={this.onChange}
ref="input"
value={inputDisplayValue}
value={inputDisplayValueFormat}
/>
</div>
</div>
Expand Down
49 changes: 26 additions & 23 deletions src/mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export default {
},

onChange(e) {
const input = this.getValueFromEvent(e).trim();
const input = this.getValueFromEvent(e).trim().replace(/^[^\w\.-]*|[^\w\.-]*$/g, '');
this.setState({ inputValue: input });
this.props.onChange(this.toNumberWhenUserInput(input)); // valid number or invalid string
},
Expand Down Expand Up @@ -134,18 +134,19 @@ export default {
// press +
// then value should be 2.51, rather than 2.5
// https://github.com/react-component/input-number/issues/39
getMaxPrecision(currentValue) {
getMaxPrecision(currentValue, ratio = 1) {
const { step } = this.props;
const ratioPrecision = this.getPrecision(ratio);
const stepPrecision = this.getPrecision(step);
const currentValuePrecision = this.getPrecision(currentValue);
if (!currentValue) {
return stepPrecision;
return ratioPrecision + stepPrecision;
}
const currentValuePrecision = this.getPrecision(currentValue);
return currentValuePrecision > stepPrecision ? currentValuePrecision : stepPrecision;
return Math.max(currentValuePrecision, ratioPrecision + stepPrecision);
},

getPrecisionFactor(currentValue) {
const precision = this.getMaxPrecision(currentValue);
getPrecisionFactor(currentValue, ratio = 1) {
const precision = this.getMaxPrecision(currentValue, ratio);
return Math.pow(10, precision);
},

Expand Down Expand Up @@ -184,35 +185,37 @@ export default {
return this.toNumber(num);
},

upStep(val) {
upStep(val, rat) {
const { step, min } = this.props;
const precisionFactor = this.getPrecisionFactor(val);
const precision = Math.abs(this.getMaxPrecision(val));
const precisionFactor = this.getPrecisionFactor(val, rat);
const precision = Math.abs(this.getMaxPrecision(val, rat));
let result;
if (typeof val === 'number') {
result =
((precisionFactor * val + precisionFactor * step) / precisionFactor).toFixed(precision);
((precisionFactor * val + precisionFactor * step * rat)
/ precisionFactor).toFixed(precision);
} else {
result = min === -Infinity ? step : min;
}
return this.toNumber(result);
},

downStep(val) {
downStep(val, rat) {
const { step, min } = this.props;
const precisionFactor = this.getPrecisionFactor(val);
const precision = Math.abs(this.getMaxPrecision(val));
const precisionFactor = this.getPrecisionFactor(val, rat);
const precision = Math.abs(this.getMaxPrecision(val, rat));
let result;
if (typeof val === 'number') {
result =
((precisionFactor * val - precisionFactor * step) / precisionFactor).toFixed(precision);
((precisionFactor * val - precisionFactor * step * rat)
/ precisionFactor).toFixed(precision);
} else {
result = min === -Infinity ? -step : min;
}
return this.toNumber(result);
},

step(type, e) {
step(type, e, ratio = 1) {
if (e) {
e.preventDefault();
}
Expand All @@ -224,7 +227,7 @@ export default {
if (this.isNotCompleteNumber(value)) {
return;
}
const val = this[`${type}Step`](value);
const val = this[`${type}Step`](value, ratio);
if (val > props.max || val < props.min) {
return;
}
Expand All @@ -240,25 +243,25 @@ export default {
}
},

down(e, recursive) {
down(e, ratio, recursive) {
if (e.persist) {
e.persist();
}
this.stop();
this.step('down', e);
this.step('down', e, ratio);
this.autoStepTimer = setTimeout(() => {
this.down(e, true);
this.down(e, ratio, true);
}, recursive ? SPEED : DELAY);
},

up(e, recursive) {
up(e, ratio, recursive) {
if (e.persist) {
e.persist();
}
this.stop();
this.step('up', e);
this.step('up', e, ratio);
this.autoStepTimer = setTimeout(() => {
this.up(e, true);
this.up(e, ratio, true);
}, recursive ? SPEED : DELAY);
},
};
Loading

0 comments on commit b1c5f96

Please sign in to comment.