2019-08-21 21:19:44 +08:00
|
|
|
import "./NumberInput.css";
|
|
|
|
import "./Input.css";
|
|
|
|
import { create_el } from "./dom";
|
|
|
|
import { WritableProperty } from "../observable/WritableProperty";
|
|
|
|
import { property } from "../observable";
|
|
|
|
import { LabelledControl } from "./LabelledControl";
|
2019-08-21 23:56:46 +08:00
|
|
|
import { is_any_property, Property } from "../observable/Property";
|
2019-08-21 21:19:44 +08:00
|
|
|
|
|
|
|
export class NumberInput extends LabelledControl {
|
|
|
|
readonly element: HTMLInputElement = create_el("input", "core_NumberInput core_Input");
|
|
|
|
|
|
|
|
readonly value: WritableProperty<number> = property(0);
|
|
|
|
|
|
|
|
readonly preferred_label_position = "left";
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
value = 0,
|
|
|
|
label?: string,
|
|
|
|
min: number | Property<number> = -Infinity,
|
|
|
|
max: number | Property<number> = Infinity,
|
|
|
|
step: number | Property<number> = 1,
|
|
|
|
) {
|
|
|
|
super(label);
|
|
|
|
|
|
|
|
this.element.type = "number";
|
|
|
|
this.element.valueAsNumber = value;
|
|
|
|
this.element.style.width = "50px";
|
|
|
|
|
|
|
|
this.set_prop("min", min);
|
|
|
|
this.set_prop("max", max);
|
|
|
|
this.set_prop("step", step);
|
|
|
|
|
|
|
|
this.element.onchange = () => this.value.set(this.element.valueAsNumber);
|
|
|
|
|
|
|
|
this.disposables(
|
|
|
|
this.value.observe(value => (this.element.valueAsNumber = value)),
|
|
|
|
|
|
|
|
this.enabled.observe(enabled => (this.element.disabled = !enabled)),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
private set_prop<T>(prop: "min" | "max" | "step", value: T | Property<T>): void {
|
2019-08-21 23:56:46 +08:00
|
|
|
if (is_any_property(value)) {
|
2019-08-21 21:19:44 +08:00
|
|
|
this.element[prop] = String(value.get());
|
|
|
|
this.disposable(value.observe(v => (this.element[prop] = String(v))));
|
|
|
|
} else {
|
|
|
|
this.element[prop] = String(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|