github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/ui/app/components/stepper-input.js (about) 1 import Component from '@ember/component'; 2 import { action } from '@ember/object'; 3 import { debounce } from '@ember/runloop'; 4 import { oneWay } from '@ember/object/computed'; 5 import { classNames, classNameBindings } from '@ember-decorators/component'; 6 import classic from 'ember-classic-decorator'; 7 8 const ESC = 27; 9 10 @classic 11 @classNames('stepper-input') 12 @classNameBindings('class', 'disabled:is-disabled', 'disabled:tooltip', 'disabled:multiline') 13 export default class StepperInput extends Component { 14 min = 0; 15 max = 10; 16 value = 0; 17 debounce = 500; 18 onChange() {} 19 20 // Internal value changes immediately for instant visual feedback. 21 // Value is still the public API and is expected to mutate and re-render 22 // On onChange which is debounced. 23 @oneWay('value') internalValue; 24 25 @action 26 increment() { 27 if (this.internalValue < this.max) { 28 this.incrementProperty('internalValue'); 29 this.update(this.internalValue); 30 } 31 } 32 33 @action 34 decrement() { 35 if (this.internalValue > this.min) { 36 this.decrementProperty('internalValue'); 37 this.update(this.internalValue); 38 } 39 } 40 41 @action 42 setValue(e) { 43 if (e.target.value !== '') { 44 const newValue = Math.floor(Math.min(this.max, Math.max(this.min, e.target.value))); 45 this.set('internalValue', newValue); 46 this.update(this.internalValue); 47 } else { 48 e.target.value = this.internalValue; 49 } 50 } 51 52 @action 53 resetTextInput(e) { 54 if (e.keyCode === ESC) { 55 e.target.value = this.internalValue; 56 } 57 } 58 59 @action 60 selectValue(e) { 61 e.target.select(); 62 } 63 64 update(value) { 65 debounce(this, sendUpdateAction, value, this.debounce); 66 } 67 } 68 69 function sendUpdateAction(value) { 70 return this.onChange(value); 71 }