7ad214f34a
- Click label to focus input - Focusing input selects value - Entering an invalid value reverts selection - Entering a fractional number floors the value
76 lines
1.8 KiB
JavaScript
76 lines
1.8 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();
|
|
}
|
|
|
|
@action focusInput() {
|
|
this.element.querySelector('.stepper-input-input').focus();
|
|
}
|
|
|
|
update(value) {
|
|
debounce(this, sendUpdateAction, value, this.debounce);
|
|
}
|
|
}
|
|
|
|
function sendUpdateAction(value) {
|
|
return this.onChange(value);
|
|
}
|