mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-02 05:57:54 +00:00
Add positive_time_period_dict to ha-form (#4090)
* Add positive_time_period_dict to ha-form * select input on focus * Update ha-form-positive_time_period_dict.ts
This commit is contained in:
parent
c25a38b82f
commit
3973374f3f
@ -32,7 +32,7 @@ export class HaFormFloat extends LitElement implements HaFormElement {
|
|||||||
return html`
|
return html`
|
||||||
<paper-input
|
<paper-input
|
||||||
.label=${this.label}
|
.label=${this.label}
|
||||||
.value=${this.data}
|
.value=${this._value}
|
||||||
.required=${this.schema.required}
|
.required=${this.schema.required}
|
||||||
.autoValidate=${this.schema.required}
|
.autoValidate=${this.schema.required}
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
@ -42,9 +42,13 @@ export class HaFormFloat extends LitElement implements HaFormElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get _value() {
|
||||||
|
return this.data || 0;
|
||||||
|
}
|
||||||
|
|
||||||
private _valueChanged(ev: Event) {
|
private _valueChanged(ev: Event) {
|
||||||
const value = Number((ev.target as PaperInputElement).value);
|
const value = Number((ev.target as PaperInputElement).value);
|
||||||
if (this.data === value) {
|
if (this._value === value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fireEvent(
|
fireEvent(
|
||||||
|
@ -41,7 +41,7 @@ export class HaFormInteger extends LitElement implements HaFormElement {
|
|||||||
${this.label}
|
${this.label}
|
||||||
<ha-paper-slider
|
<ha-paper-slider
|
||||||
pin=""
|
pin=""
|
||||||
.value=${this.data}
|
.value=${this._value}
|
||||||
.min=${this.schema.valueMin}
|
.min=${this.schema.valueMin}
|
||||||
.max=${this.schema.valueMax}
|
.max=${this.schema.valueMax}
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
@ -60,11 +60,15 @@ export class HaFormInteger extends LitElement implements HaFormElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get _value() {
|
||||||
|
return this.data || 0;
|
||||||
|
}
|
||||||
|
|
||||||
private _valueChanged(ev: Event) {
|
private _valueChanged(ev: Event) {
|
||||||
const value = Number(
|
const value = Number(
|
||||||
(ev.target as PaperInputElement | PaperSliderElement).value
|
(ev.target as PaperInputElement | PaperSliderElement).value
|
||||||
);
|
);
|
||||||
if (this.data === value) {
|
if (this._value === value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fireEvent(
|
fireEvent(
|
||||||
|
119
src/components/ha-form/ha-form-positive_time_period_dict.ts
Normal file
119
src/components/ha-form/ha-form-positive_time_period_dict.ts
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
import {
|
||||||
|
customElement,
|
||||||
|
LitElement,
|
||||||
|
html,
|
||||||
|
property,
|
||||||
|
TemplateResult,
|
||||||
|
query,
|
||||||
|
} from "lit-element";
|
||||||
|
import { HaFormElement, HaFormTimeData, HaFormTimeSchema } from "./ha-form";
|
||||||
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
|
|
||||||
|
@customElement("ha-form-positive_time_period_dict")
|
||||||
|
export class HaFormTimePeriod extends LitElement implements HaFormElement {
|
||||||
|
@property() public schema!: HaFormTimeSchema;
|
||||||
|
@property() public data!: HaFormTimeData;
|
||||||
|
@property() public label!: string;
|
||||||
|
@property() public suffix!: string;
|
||||||
|
@query("paper-time-input") private _input?: HTMLElement;
|
||||||
|
|
||||||
|
public focus() {
|
||||||
|
if (this._input) {
|
||||||
|
this._input.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render(): TemplateResult | void {
|
||||||
|
return html`
|
||||||
|
<paper-time-input
|
||||||
|
.label=${this.label}
|
||||||
|
.required=${this.schema.required}
|
||||||
|
.autoValidate=${this.schema.required}
|
||||||
|
error-message="Required"
|
||||||
|
enable-second
|
||||||
|
format="24"
|
||||||
|
.hour=${this._parseDuration(this._hours)}
|
||||||
|
.min=${this._parseDuration(this._minutes)}
|
||||||
|
.sec=${this._parseDuration(this._seconds)}
|
||||||
|
@hour-changed=${this._hourChanged}
|
||||||
|
@min-changed=${this._minChanged}
|
||||||
|
@sec-changed=${this._secChanged}
|
||||||
|
float-input-labels
|
||||||
|
no-hours-limit
|
||||||
|
always-float-input-labels
|
||||||
|
hour-label="hh"
|
||||||
|
min-label="mm"
|
||||||
|
sec-label="ss"
|
||||||
|
></paper-time-input>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private get _hours() {
|
||||||
|
return this.data && this.data.hours ? Number(this.data.hours) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private get _minutes() {
|
||||||
|
return this.data && this.data.minutes ? Number(this.data.minutes) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private get _seconds() {
|
||||||
|
return this.data && this.data.seconds ? Number(this.data.seconds) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _parseDuration(value) {
|
||||||
|
return value.toString().padStart(2, "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
private _hourChanged(ev) {
|
||||||
|
this._durationChanged(ev, "hours");
|
||||||
|
}
|
||||||
|
|
||||||
|
private _minChanged(ev) {
|
||||||
|
this._durationChanged(ev, "minutes");
|
||||||
|
}
|
||||||
|
|
||||||
|
private _secChanged(ev) {
|
||||||
|
this._durationChanged(ev, "seconds");
|
||||||
|
}
|
||||||
|
|
||||||
|
private _durationChanged(ev, unit) {
|
||||||
|
let value = Number(ev.detail.value);
|
||||||
|
|
||||||
|
if (value === this[`_${unit}`]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let hours = this._hours;
|
||||||
|
let minutes = this._minutes;
|
||||||
|
|
||||||
|
if (unit === "seconds" && value > 59) {
|
||||||
|
minutes = minutes + Math.floor(value / 60);
|
||||||
|
value %= 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unit === "minutes" && value > 59) {
|
||||||
|
hours = hours + Math.floor(value / 60);
|
||||||
|
value %= 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
fireEvent(
|
||||||
|
this,
|
||||||
|
"value-changed",
|
||||||
|
{
|
||||||
|
value: {
|
||||||
|
hours,
|
||||||
|
minutes,
|
||||||
|
seconds: this._seconds,
|
||||||
|
...{ [unit]: value },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ bubbles: false }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-form-positive_time_period_dict": HaFormTimePeriod;
|
||||||
|
}
|
||||||
|
}
|
@ -14,6 +14,7 @@ import "./ha-form-integer";
|
|||||||
import "./ha-form-float";
|
import "./ha-form-float";
|
||||||
import "./ha-form-boolean";
|
import "./ha-form-boolean";
|
||||||
import "./ha-form-select";
|
import "./ha-form-select";
|
||||||
|
import "./ha-form-positive_time_period_dict";
|
||||||
import { fireEvent } from "../../common/dom/fire_event";
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
|
|
||||||
export type HaFormSchema =
|
export type HaFormSchema =
|
||||||
@ -21,7 +22,8 @@ export type HaFormSchema =
|
|||||||
| HaFormIntegerSchema
|
| HaFormIntegerSchema
|
||||||
| HaFormFloatSchema
|
| HaFormFloatSchema
|
||||||
| HaFormBooleanSchema
|
| HaFormBooleanSchema
|
||||||
| HaFormSelectSchema;
|
| HaFormSelectSchema
|
||||||
|
| HaFormTimeSchema;
|
||||||
|
|
||||||
export interface HaFormBaseSchema {
|
export interface HaFormBaseSchema {
|
||||||
name: string;
|
name: string;
|
||||||
@ -55,6 +57,10 @@ export interface HaFormBooleanSchema extends HaFormBaseSchema {
|
|||||||
type: "boolean";
|
type: "boolean";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface HaFormTimeSchema extends HaFormBaseSchema {
|
||||||
|
type: "time";
|
||||||
|
}
|
||||||
|
|
||||||
export interface HaFormDataContainer {
|
export interface HaFormDataContainer {
|
||||||
[key: string]: HaFormData;
|
[key: string]: HaFormData;
|
||||||
}
|
}
|
||||||
@ -64,13 +70,19 @@ export type HaFormData =
|
|||||||
| HaFormIntegerData
|
| HaFormIntegerData
|
||||||
| HaFormFloatData
|
| HaFormFloatData
|
||||||
| HaFormBooleanData
|
| HaFormBooleanData
|
||||||
| HaFormSelectData;
|
| HaFormSelectData
|
||||||
|
| HaFormTimeData;
|
||||||
|
|
||||||
export type HaFormStringData = string;
|
export type HaFormStringData = string;
|
||||||
export type HaFormIntegerData = number;
|
export type HaFormIntegerData = number;
|
||||||
export type HaFormFloatData = number;
|
export type HaFormFloatData = number;
|
||||||
export type HaFormBooleanData = boolean;
|
export type HaFormBooleanData = boolean;
|
||||||
export type HaFormSelectData = string;
|
export type HaFormSelectData = string;
|
||||||
|
export interface HaFormTimeData {
|
||||||
|
hours?: number;
|
||||||
|
minutes?: number;
|
||||||
|
seconds?: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface HaFormElement extends LitElement {
|
export interface HaFormElement extends LitElement {
|
||||||
schema: HaFormSchema;
|
schema: HaFormSchema;
|
||||||
|
@ -87,6 +87,10 @@ export class PaperTimeInput extends PolymerElement {
|
|||||||
|
|
||||||
label {
|
label {
|
||||||
@apply --paper-font-caption;
|
@apply --paper-font-caption;
|
||||||
|
color: var(
|
||||||
|
--paper-input-container-color,
|
||||||
|
var(--secondary-text-color)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
.time-input-wrap {
|
.time-input-wrap {
|
||||||
@ -106,14 +110,17 @@ export class PaperTimeInput extends PolymerElement {
|
|||||||
id="hour"
|
id="hour"
|
||||||
type="number"
|
type="number"
|
||||||
value="{{hour}}"
|
value="{{hour}}"
|
||||||
|
label="[[hourLabel]]"
|
||||||
on-change="_shouldFormatHour"
|
on-change="_shouldFormatHour"
|
||||||
required=""
|
on-focus="_onFocus"
|
||||||
|
required
|
||||||
|
prevent-invalid-input
|
||||||
auto-validate="[[autoValidate]]"
|
auto-validate="[[autoValidate]]"
|
||||||
prevent-invalid-input=""
|
|
||||||
maxlength="2"
|
maxlength="2"
|
||||||
max="[[_computeHourMax(format)]]"
|
max="[[_computeHourMax(format)]]"
|
||||||
min="0"
|
min="0"
|
||||||
no-label-float=""
|
no-label-float$="[[!floatInputLabels]]"
|
||||||
|
always-float-label$="[[alwaysFloatInputLabels]]"
|
||||||
disabled="[[disabled]]"
|
disabled="[[disabled]]"
|
||||||
>
|
>
|
||||||
<span suffix="" slot="suffix">:</span>
|
<span suffix="" slot="suffix">:</span>
|
||||||
@ -124,15 +131,40 @@ export class PaperTimeInput extends PolymerElement {
|
|||||||
id="min"
|
id="min"
|
||||||
type="number"
|
type="number"
|
||||||
value="{{min}}"
|
value="{{min}}"
|
||||||
|
label="[[minLabel]]"
|
||||||
on-change="_formatMin"
|
on-change="_formatMin"
|
||||||
required=""
|
on-focus="_onFocus"
|
||||||
|
required
|
||||||
auto-validate="[[autoValidate]]"
|
auto-validate="[[autoValidate]]"
|
||||||
prevent-invalid-input=""
|
prevent-invalid-input
|
||||||
maxlength="2"
|
maxlength="2"
|
||||||
max="59"
|
max="59"
|
||||||
min="0"
|
min="0"
|
||||||
no-label-float=""
|
no-label-float$="[[!floatInputLabels]]"
|
||||||
|
always-float-label$="[[alwaysFloatInputLabels]]"
|
||||||
disabled="[[disabled]]"
|
disabled="[[disabled]]"
|
||||||
|
>
|
||||||
|
<span hidden$="[[!enableSecond]]" suffix slot="suffix">:</span>
|
||||||
|
</paper-input>
|
||||||
|
|
||||||
|
<!-- Sec Input -->
|
||||||
|
<paper-input
|
||||||
|
id="sec"
|
||||||
|
type="number"
|
||||||
|
value="{{sec}}"
|
||||||
|
label="[[secLabel]]"
|
||||||
|
on-change="_formatSec"
|
||||||
|
on-focus="_onFocus"
|
||||||
|
required
|
||||||
|
auto-validate="[[autoValidate]]"
|
||||||
|
prevent-invalid-input
|
||||||
|
maxlength="2"
|
||||||
|
max="59"
|
||||||
|
min="0"
|
||||||
|
no-label-float$="[[!floatInputLabels]]"
|
||||||
|
always-float-label$="[[alwaysFloatInputLabels]]"
|
||||||
|
disabled="[[disabled]]"
|
||||||
|
hidden$="[[!enableSecond]]"
|
||||||
>
|
>
|
||||||
</paper-input>
|
</paper-input>
|
||||||
|
|
||||||
@ -180,6 +212,20 @@ export class PaperTimeInput extends PolymerElement {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false,
|
value: false,
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* float the input labels
|
||||||
|
*/
|
||||||
|
floatInputLabels: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* always float the input labels
|
||||||
|
*/
|
||||||
|
alwaysFloatInputLabels: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 12 or 24 hr format
|
* 12 or 24 hr format
|
||||||
*/
|
*/
|
||||||
@ -208,6 +254,48 @@ export class PaperTimeInput extends PolymerElement {
|
|||||||
type: String,
|
type: String,
|
||||||
notify: true,
|
notify: true,
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* second
|
||||||
|
*/
|
||||||
|
sec: {
|
||||||
|
type: String,
|
||||||
|
notify: true,
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Suffix for the hour input
|
||||||
|
*/
|
||||||
|
hourLabel: {
|
||||||
|
type: String,
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Suffix for the min input
|
||||||
|
*/
|
||||||
|
minLabel: {
|
||||||
|
type: String,
|
||||||
|
value: ":",
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Suffix for the sec input
|
||||||
|
*/
|
||||||
|
secLabel: {
|
||||||
|
type: String,
|
||||||
|
value: "",
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* show the sec field
|
||||||
|
*/
|
||||||
|
enableSecond: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* limit hours input
|
||||||
|
*/
|
||||||
|
noHoursLimit: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* AM or PM
|
* AM or PM
|
||||||
*/
|
*/
|
||||||
@ -223,7 +311,7 @@ export class PaperTimeInput extends PolymerElement {
|
|||||||
type: String,
|
type: String,
|
||||||
notify: true,
|
notify: true,
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
computed: "_computeTime(min, hour, amPm)",
|
computed: "_computeTime(min, hour, sec, amPm)",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -238,6 +326,10 @@ export class PaperTimeInput extends PolymerElement {
|
|||||||
if (!this.$.hour.validate() | !this.$.min.validate()) {
|
if (!this.$.hour.validate() | !this.$.min.validate()) {
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
// Validate second field
|
||||||
|
if (this.enableSecond && !this.$.sec.validate()) {
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
// Validate AM PM if 12 hour time
|
// Validate AM PM if 12 hour time
|
||||||
if (this.format === 12 && !this.$.dropdown.validate()) {
|
if (this.format === 12 && !this.$.dropdown.validate()) {
|
||||||
valid = false;
|
valid = false;
|
||||||
@ -248,15 +340,37 @@ export class PaperTimeInput extends PolymerElement {
|
|||||||
/**
|
/**
|
||||||
* Create time string
|
* Create time string
|
||||||
*/
|
*/
|
||||||
_computeTime(min, hour, amPm) {
|
_computeTime(min, hour, sec, amPm) {
|
||||||
if (hour && min) {
|
let str;
|
||||||
// No ampm on 24 hr time
|
if (hour || min || (sec && this.enableSecond)) {
|
||||||
if (this.format === 24) {
|
hour = hour || "00";
|
||||||
amPm = "";
|
min = min || "00";
|
||||||
|
sec = sec || "00";
|
||||||
|
str = hour + ":" + min;
|
||||||
|
// add sec field
|
||||||
|
if (this.enableSecond && sec) {
|
||||||
|
str = str + ":" + sec;
|
||||||
|
}
|
||||||
|
// No ampm on 24 hr time
|
||||||
|
if (this.format === 12) {
|
||||||
|
str = str + " " + amPm;
|
||||||
}
|
}
|
||||||
return hour + ":" + min + " " + amPm;
|
|
||||||
}
|
}
|
||||||
return undefined;
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
_onFocus(ev) {
|
||||||
|
ev.target.inputElement.inputElement.select();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format sec
|
||||||
|
*/
|
||||||
|
_formatSec() {
|
||||||
|
if (this.sec.toString().length === 1) {
|
||||||
|
this.sec = this.sec.toString().padStart(2, "0");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -264,16 +378,16 @@ export class PaperTimeInput extends PolymerElement {
|
|||||||
*/
|
*/
|
||||||
_formatMin() {
|
_formatMin() {
|
||||||
if (this.min.toString().length === 1) {
|
if (this.min.toString().length === 1) {
|
||||||
this.min = this.min < 10 ? "0" + this.min : this.min;
|
this.min = this.min.toString().padStart(2, "0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hour needs a leading zero in 24hr format
|
* Format hour
|
||||||
*/
|
*/
|
||||||
_shouldFormatHour() {
|
_shouldFormatHour() {
|
||||||
if (this.format === 24 && this.hour.toString().length === 1) {
|
if (this.format === 24 && this.hour.toString().length === 1) {
|
||||||
this.hour = this.hour < 10 ? "0" + this.hour : this.hour;
|
this.hour = this.hour.toString().padStart(2, "0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,6 +395,9 @@ export class PaperTimeInput extends PolymerElement {
|
|||||||
* 24 hour format has a max hr of 23
|
* 24 hour format has a max hr of 23
|
||||||
*/
|
*/
|
||||||
_computeHourMax(format) {
|
_computeHourMax(format) {
|
||||||
|
if (this.noHoursLimit) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
if (format === 12) {
|
if (format === 12) {
|
||||||
return format;
|
return format;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user