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