-
Notifications
You must be signed in to change notification settings - Fork 2.6k
/
ha-form-integer.ts
186 lines (165 loc) · 4.65 KB
/
ha-form-integer.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
import "@material/mwc-textfield";
import type { TextField } from "@material/mwc-textfield";
import type { Slider } from "@material/mwc-slider";
import {
css,
CSSResultGroup,
html,
LitElement,
TemplateResult,
PropertyValues,
} from "lit";
import { customElement, property, query } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
import { HaCheckbox } from "../ha-checkbox";
import { HaFormElement, HaFormIntegerData, HaFormIntegerSchema } from "./types";
import "../ha-slider";
@customElement("ha-form-integer")
export class HaFormInteger extends LitElement implements HaFormElement {
@property() public schema!: HaFormIntegerSchema;
@property() public data?: HaFormIntegerData;
@property() public label?: string;
@property({ type: Boolean }) public disabled = false;
@query("mwc-textfield ha-slider") private _input?: HTMLElement;
private _lastValue?: HaFormIntegerData;
public focus() {
if (this._input) {
this._input.focus();
}
}
protected render(): TemplateResult {
if (
this.schema.valueMin !== undefined &&
this.schema.valueMax !== undefined &&
this.schema.valueMax - this.schema.valueMin < 256
) {
return html`
<div>
${this.label}
<div class="flex">
${!this.schema.required
? html`
<ha-checkbox
@change=${this._handleCheckboxChange}
.checked=${this.data !== undefined}
.disabled=${this.disabled}
></ha-checkbox>
`
: ""}
<ha-slider
pin
ignore-bar-touch
.value=${this._value}
.min=${this.schema.valueMin}
.max=${this.schema.valueMax}
.disabled=${this.disabled ||
(this.data === undefined && !this.schema.required)}
@change=${this._valueChanged}
></ha-slider>
</div>
</div>
`;
}
return html`
<mwc-textfield
type="number"
inputMode="numeric"
.label=${this.label}
.value=${this.data !== undefined ? this.data : ""}
.disabled=${this.disabled}
.required=${this.schema.required}
.autoValidate=${this.schema.required}
.suffix=${this.schema.description?.suffix}
.validationMessage=${this.schema.required ? "Required" : undefined}
@input=${this._valueChanged}
></mwc-textfield>
`;
}
protected updated(changedProps: PropertyValues): void {
if (changedProps.has("schema")) {
this.toggleAttribute(
"own-margin",
!("valueMin" in this.schema && "valueMax" in this.schema) &&
!!this.schema.required
);
}
}
private get _value() {
if (this.data !== undefined) {
return this.data;
}
if (!this.schema.required) {
return this.schema.valueMin || 0;
}
return (
this.schema.description?.suggested_value ||
this.schema.default ||
this.schema.valueMin ||
0
);
}
private _handleCheckboxChange(ev: Event) {
const checked = (ev.target as HaCheckbox).checked;
let value: HaFormIntegerData | undefined;
if (checked) {
for (const candidate of [
this._lastValue,
this.schema.description?.suggested_value as HaFormIntegerData,
this.schema.default,
0,
]) {
if (candidate !== undefined) {
value = candidate;
break;
}
}
} else {
// We track last value so user can disable and enable a field without losing
// their value.
this._lastValue = this.data;
}
fireEvent(this, "value-changed", {
value,
});
}
private _valueChanged(ev: Event) {
const source = ev.target as TextField | Slider;
const rawValue = source.value;
let value: number | undefined;
if (rawValue !== "") {
value = parseInt(String(rawValue));
}
if (this.data === value) {
// parseInt will drop invalid text at the end, in that case update textfield
const newRawValue = value === undefined ? "" : String(value);
if (source.value !== newRawValue) {
source.value = newRawValue;
}
return;
}
fireEvent(this, "value-changed", {
value,
});
}
static get styles(): CSSResultGroup {
return css`
:host([own-margin]) {
margin-bottom: 5px;
}
.flex {
display: flex;
}
ha-slider {
flex: 1;
}
mwc-textfield {
display: block;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-form-integer": HaFormInteger;
}
}