diff --git a/README.md b/README.md index f6ae19e..45c2862 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,8 @@ You can now use custom images, from your local file system or from the Internet. | `onMinimumReached` | Function | Executed when the `minimumValue` is reached. The value is passed as a parameter | null | | `onMaximumReached` | Function | Executed when the `maximumValue` is reached. The value is passed as a parameter | null | | `innerRef` | Function | A reference to the rendered UIStepper. You can use this to gain access to class-based methods. `increment()`, `decrement()`, `resetValue()` and `setValue()` are most commonly used | null | - +| `repeatActionWhenHolding` | Boolean | Continue to increment/decrement when holding | false +| `repeatInterval` | Number | Number of milliseconds between action repetitions when holding. Only works if `repeatActionWhenHolding` is set to `true` | 100 ## Contributing There are no requirements for contributing to the react-native-ui-stepper package. You can [browse](https://github.com/hannigand/react-native-ui-stepper/issues/) or raise issues that you are would like to contribute to. diff --git a/UIStepper.js b/UIStepper.js index 2fe581e..7081ecb 100644 --- a/UIStepper.js +++ b/UIStepper.js @@ -18,6 +18,9 @@ const styles = StyleSheet.create({ }, }); +const ACTION_INCREMENT = 'INCREMENT'; +const ACTION_DECREMENT = 'DECREMENT'; + class UIStepper extends Component { static propTypes = { initialValue: PropTypes.number, @@ -50,6 +53,8 @@ class UIStepper extends Component { displayDecrementFirst: PropTypes.bool, fontFamily: PropTypes.string, innerRef: PropTypes.func, + repeatActionWhenHolding: PropTypes.bool, + repeatInterval: PropTypes.number, }; static defaultProps = { initialValue: 0, @@ -82,12 +87,15 @@ class UIStepper extends Component { displayDecrementFirst: false, fontFamily: 'System', innerRef: null, + repeatActionWhenHolding: false, + repeatInterval: 100, }; constructor(props) { super(props); this.state = { value: props.initialValue, }; + this.timer = null; } componentDidMount() { const { innerRef } = this.props; @@ -114,13 +122,13 @@ class UIStepper extends Component { const { steps, onDecrement } = this.props; let value = this.state.value; value -= steps; - this.validate(value, onDecrement); + this.validate(value, onDecrement, ACTION_DECREMENT); }; increment = () => { const { steps, onIncrement } = this.props; let value = this.state.value; value += steps; - this.validate(value, onIncrement); + this.validate(value, onIncrement, ACTION_INCREMENT); }; isExternalImage = image => typeof image === 'string'; resolveImage = image => { @@ -179,7 +187,7 @@ class UIStepper extends Component { } return imageWidth; }; - validate = (value, callback) => { + validate = (value, callback, actionType) => { const { minimumValue: min, maximumValue: max, @@ -187,6 +195,8 @@ class UIStepper extends Component { onMinimumReached, onMaximumReached, wraps, + repeatActionWhenHolding, + repeatInterval } = this.props; if (min <= value && max >= value) { this.setState({ @@ -198,6 +208,12 @@ class UIStepper extends Component { if (callback) { callback(value); } + if (repeatActionWhenHolding && actionType === ACTION_INCREMENT) { + this.timer = setTimeout(this.increment, repeatInterval); + } + if (repeatActionWhenHolding && actionType === ACTION_DECREMENT) { + this.timer = setTimeout(this.decrement, repeatInterval); + } return; } if (value < min) { @@ -213,6 +229,7 @@ class UIStepper extends Component { } return; } + clearTimeout(this.timer) onMinimumReached && onMinimumReached(value); } if (value > max) { @@ -228,6 +245,7 @@ class UIStepper extends Component { } return; } + clearTimeout(this.timer) onMaximumReached && onMaximumReached(value); } }; @@ -288,7 +306,8 @@ class UIStepper extends Component { ]} > clearTimeout(this.timer)} style={[ styles.button, { @@ -312,7 +331,8 @@ class UIStepper extends Component { )} clearTimeout(this.timer)} style={[ styles.button, {