Home Reference Source Repository

src/appComponent/controlSection/rotors2D/rotor/stepper/stepper.js

import {h, render, Component} from 'preact';
import "./stepper.less";
/**
 * Stepper Element used for change numbers in all device easily
 * @example
 * <Stepper name="propName" onchange={(name,value)=>{}}/>
 */
class Stepper extends Component {
	/**
	 * we don't need to rerender all over stepper when its property changes
	 * @param {object} props
	 */
	shouldComponentUpdate(props) {
		if (!this.textInput) return true;//it needs to render the element again
		if(props.value != this.value){
			this.value = props.value;
			this.textInput.value = this.value;
		}
		return false;
	}

	/**
	 * set value on and text value from props
	 */
	componentWillMount() {
		this.value = this.props.value || 0;
		this.textInput.value = this.value;
	}

	value = 0;
	delay = 150;
	timeoutObject = 0;

	/**
	 * increase the value of stepper
	 */
	increase() {
		this.value++;
		this.onChange();
	}
	/**
	 * start holding increase button
	 */
	holdUp() {
		this.timeoutObject=setTimeout(() => {
			this.increase();
			this.holdUp();
		},this.delay);
	}
	/**
	 * leave increase button
	 */
	leaveUp() {
		clearTimeout(this.timeoutObject);
	}

	/**
	 * decrease the value of stepper
	 */
	decrease() {
		this.value--;
		this.onChange();
	}
	/**
	 * start holding decrease button
	 */
	holdDown() {
		this.timeoutObject=setTimeout(() => {
				this.decrease();
				this.holdDown();
			},this.delay);
	}
	/**
	 * leave decrease buton
	 */
	leaveDown() {
		clearTimeout(this.timeoutObject);
	}

	/**
	 * change value on text changed
	 */
	onInputChange(e) {
		this.value = this.textInput.value;
		this.onChange();
	}


	/**
	 * call event for parents
	 */
	onChange() {
		if (this.textInput) {
			this.textInput.value = this.value;
			if (this.props.onChange) {
				this.props.onChange(this.props.name, this.value);
			}
		}
	}


	/**
	 * render function
	 * @param {object} props
	 * @param {object} state
	 */
	render(props, state) {
		return <div class="stepper">
			<input class="number" type="number" ref={(input) => {
				this.textInput = input;
			}} onInput={this.onInputChange.bind(this)}/>
			<button class="minus" onMouseDown={this.holdDown.bind(this)} onMouseUp={this.leaveDown.bind(this)} onClick={this.decrease.bind(this)}>-</button>
			<button class="plus" onMouseDown={this.holdUp.bind(this)} onMouseUp={this.leaveUp.bind(this)} onClick={this.increase.bind(this)}>+</button>
		</div>;
	}
}
export default Stepper;


//TODO: write on holding increase or decrease button condition
//TODO: on holding key up prevent bubling and run window key down because ThreeOrbit add listener to window