mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-01 13:37:47 +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`
|
||||
<paper-input
|
||||
.label=${this.label}
|
||||
.value=${this.data}
|
||||
.value=${this._value}
|
||||
.required=${this.schema.required}
|
||||
.autoValidate=${this.schema.required}
|
||||
@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) {
|
||||
const value = Number((ev.target as PaperInputElement).value);
|
||||
if (this.data === value) {
|
||||
if (this._value === value) {
|
||||
return;
|
||||
}
|
||||
fireEvent(
|
||||
|
@ -41,7 +41,7 @@ export class HaFormInteger extends LitElement implements HaFormElement {
|
||||
${this.label}
|
||||
<ha-paper-slider
|
||||
pin=""
|
||||
.value=${this.data}
|
||||
.value=${this._value}
|
||||
.min=${this.schema.valueMin}
|
||||
.max=${this.schema.valueMax}
|
||||
@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) {
|
||||
const value = Number(
|
||||
(ev.target as PaperInputElement | PaperSliderElement).value
|
||||
);
|
||||
if (this.data === value) {
|
||||
if (this._value === value) {
|
||||
return;
|
||||
}
|
||||
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-boolean";
|
||||
import "./ha-form-select";
|
||||
import "./ha-form-positive_time_period_dict";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
|
||||
export type HaFormSchema =
|
||||
@ -21,7 +22,8 @@ export type HaFormSchema =
|
||||
| HaFormIntegerSchema
|
||||
| HaFormFloatSchema
|
||||
| HaFormBooleanSchema
|
||||
| HaFormSelectSchema;
|
||||
| HaFormSelectSchema
|
||||
| HaFormTimeSchema;
|
||||
|
||||
export interface HaFormBaseSchema {
|
||||
name: string;
|
||||
@ -55,6 +57,10 @@ export interface HaFormBooleanSchema extends HaFormBaseSchema {
|
||||
type: "boolean";
|
||||
}
|
||||
|
||||
export interface HaFormTimeSchema extends HaFormBaseSchema {
|
||||
type: "time";
|
||||
}
|
||||
|
||||
export interface HaFormDataContainer {
|
||||
[key: string]: HaFormData;
|
||||
}
|
||||
@ -64,13 +70,19 @@ export type HaFormData =
|
||||
| HaFormIntegerData
|
||||
| HaFormFloatData
|
||||
| HaFormBooleanData
|
||||
| HaFormSelectData;
|
||||
| HaFormSelectData
|
||||
| HaFormTimeData;
|
||||
|
||||
export type HaFormStringData = string;
|
||||
export type HaFormIntegerData = number;
|
||||
export type HaFormFloatData = number;
|
||||
export type HaFormBooleanData = boolean;
|
||||
export type HaFormSelectData = string;
|
||||
export interface HaFormTimeData {
|
||||
hours?: number;
|
||||
minutes?: number;
|
||||
seconds?: number;
|
||||
}
|
||||
|
||||
export interface HaFormElement extends LitElement {
|
||||
schema: HaFormSchema;
|
||||
|
@ -87,6 +87,10 @@ export class PaperTimeInput extends PolymerElement {
|
||||
|
||||
label {
|
||||
@apply --paper-font-caption;
|
||||
color: var(
|
||||
--paper-input-container-color,
|
||||
var(--secondary-text-color)
|
||||
);
|
||||
}
|
||||
|
||||
.time-input-wrap {
|
||||
@ -106,14 +110,17 @@ export class PaperTimeInput extends PolymerElement {
|
||||
id="hour"
|
||||
type="number"
|
||||
value="{{hour}}"
|
||||
label="[[hourLabel]]"
|
||||
on-change="_shouldFormatHour"
|
||||
required=""
|
||||
on-focus="_onFocus"
|
||||
required
|
||||
prevent-invalid-input
|
||||
auto-validate="[[autoValidate]]"
|
||||
prevent-invalid-input=""
|
||||
maxlength="2"
|
||||
max="[[_computeHourMax(format)]]"
|
||||
min="0"
|
||||
no-label-float=""
|
||||
no-label-float$="[[!floatInputLabels]]"
|
||||
always-float-label$="[[alwaysFloatInputLabels]]"
|
||||
disabled="[[disabled]]"
|
||||
>
|
||||
<span suffix="" slot="suffix">:</span>
|
||||
@ -124,15 +131,40 @@ export class PaperTimeInput extends PolymerElement {
|
||||
id="min"
|
||||
type="number"
|
||||
value="{{min}}"
|
||||
label="[[minLabel]]"
|
||||
on-change="_formatMin"
|
||||
required=""
|
||||
on-focus="_onFocus"
|
||||
required
|
||||
auto-validate="[[autoValidate]]"
|
||||
prevent-invalid-input=""
|
||||
prevent-invalid-input
|
||||
maxlength="2"
|
||||
max="59"
|
||||
min="0"
|
||||
no-label-float=""
|
||||
no-label-float$="[[!floatInputLabels]]"
|
||||
always-float-label$="[[alwaysFloatInputLabels]]"
|
||||
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>
|
||||
|
||||
@ -180,6 +212,20 @@ export class PaperTimeInput extends PolymerElement {
|
||||
type: Boolean,
|
||||
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
|
||||
*/
|
||||
@ -208,6 +254,48 @@ export class PaperTimeInput extends PolymerElement {
|
||||
type: String,
|
||||
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
|
||||
*/
|
||||
@ -223,7 +311,7 @@ export class PaperTimeInput extends PolymerElement {
|
||||
type: String,
|
||||
notify: 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()) {
|
||||
valid = false;
|
||||
}
|
||||
// Validate second field
|
||||
if (this.enableSecond && !this.$.sec.validate()) {
|
||||
valid = false;
|
||||
}
|
||||
// Validate AM PM if 12 hour time
|
||||
if (this.format === 12 && !this.$.dropdown.validate()) {
|
||||
valid = false;
|
||||
@ -248,15 +340,37 @@ export class PaperTimeInput extends PolymerElement {
|
||||
/**
|
||||
* Create time string
|
||||
*/
|
||||
_computeTime(min, hour, amPm) {
|
||||
if (hour && min) {
|
||||
// No ampm on 24 hr time
|
||||
if (this.format === 24) {
|
||||
amPm = "";
|
||||
_computeTime(min, hour, sec, amPm) {
|
||||
let str;
|
||||
if (hour || min || (sec && this.enableSecond)) {
|
||||
hour = hour || "00";
|
||||
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() {
|
||||
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() {
|
||||
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
|
||||
*/
|
||||
_computeHourMax(format) {
|
||||
if (this.noHoursLimit) {
|
||||
return null;
|
||||
}
|
||||
if (format === 12) {
|
||||
return format;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user