79 lines
1.7 KiB
JavaScript
79 lines
1.7 KiB
JavaScript
import Component from '@ember/component';
|
|
import { action } from '@ember/object';
|
|
import { debounce } from '@ember/runloop';
|
|
import { oneWay } from '@ember/object/computed';
|
|
import { classNames, classNameBindings } from '@ember-decorators/component';
|
|
import classic from 'ember-classic-decorator';
|
|
|
|
const ESC = 27;
|
|
|
|
@classic
|
|
@classNames('stepper-input')
|
|
@classNameBindings(
|
|
'class',
|
|
'disabled:is-disabled',
|
|
'disabled:tooltip',
|
|
'disabled:multiline'
|
|
)
|
|
export default class StepperInput extends Component {
|
|
min = 0;
|
|
max = 10;
|
|
value = 0;
|
|
debounce = 500;
|
|
onChange() {}
|
|
|
|
// Internal value changes immediately for instant visual feedback.
|
|
// Value is still the public API and is expected to mutate and re-render
|
|
// On onChange which is debounced.
|
|
@oneWay('value') internalValue;
|
|
|
|
@action
|
|
increment() {
|
|
if (this.internalValue < this.max) {
|
|
this.incrementProperty('internalValue');
|
|
this.update(this.internalValue);
|
|
}
|
|
}
|
|
|
|
@action
|
|
decrement() {
|
|
if (this.internalValue > this.min) {
|
|
this.decrementProperty('internalValue');
|
|
this.update(this.internalValue);
|
|
}
|
|
}
|
|
|
|
@action
|
|
setValue(e) {
|
|
if (e.target.value !== '') {
|
|
const newValue = Math.floor(
|
|
Math.min(this.max, Math.max(this.min, e.target.value))
|
|
);
|
|
this.set('internalValue', newValue);
|
|
this.update(this.internalValue);
|
|
} else {
|
|
e.target.value = this.internalValue;
|
|
}
|
|
}
|
|
|
|
@action
|
|
resetTextInput(e) {
|
|
if (e.keyCode === ESC) {
|
|
e.target.value = this.internalValue;
|
|
}
|
|
}
|
|
|
|
@action
|
|
selectValue(e) {
|
|
e.target.select();
|
|
}
|
|
|
|
update(value) {
|
|
debounce(this, sendUpdateAction, value, this.debounce);
|
|
}
|
|
}
|
|
|
|
function sendUpdateAction(value) {
|
|
return this.onChange(value);
|
|
}
|