diff --git a/src/components/ha-base-time-input.ts b/src/components/ha-base-time-input.ts
index 54490e047bbb..71870d27490d 100644
--- a/src/components/ha-base-time-input.ts
+++ b/src/components/ha-base-time-input.ts
@@ -1,10 +1,12 @@
import "@material/mwc-list/mwc-list-item";
-import { css, html, LitElement, TemplateResult } from "lit";
+import { css, html, LitElement, TemplateResult, nothing } from "lit";
import { customElement, property } from "lit/decorators";
+import { mdiClose } from "@mdi/js";
import { ifDefined } from "lit/directives/if-defined";
import { fireEvent } from "../common/dom/fire_event";
import { stopPropagation } from "../common/dom/stop_propagation";
import "./ha-select";
+import "./ha-icon-button";
import { HaTextField } from "./ha-textfield";
import "./ha-input-helper-text";
@@ -124,116 +126,128 @@ export class HaBaseTimeInput extends LitElement {
*/
@property() amPm: "AM" | "PM" = "AM";
+ @property({ type: Boolean, reflect: true }) public clearable?: boolean;
+
protected render(): TemplateResult {
return html`
${this.label
? html``
: ""}
-
- ${this.helper
- ? html`${this.helper}`
- : ""}
`;
}
+ private _clearValue(): void {
+ fireEvent(this, "value-changed");
+ }
+
private _valueChanged(ev: InputEvent) {
const textField = ev.currentTarget as HaTextField;
this[textField.name] =
@@ -302,18 +320,25 @@ export class HaBaseTimeInput extends LitElement {
}
static styles = css`
+ :host([clearable]) {
+ position: relative;
+ }
:host {
display: block;
}
+ .time-input-wrap-wrap {
+ display: flex;
+ }
.time-input-wrap {
display: flex;
border-radius: var(--mdc-shape-small, 4px) var(--mdc-shape-small, 4px) 0 0;
overflow: hidden;
position: relative;
direction: ltr;
+ padding-right: 3px;
}
ha-textfield {
- width: 40px;
+ width: 55px;
text-align: center;
--mdc-shape-small: 0;
--text-field-appearance: none;
@@ -335,6 +360,21 @@ export class HaBaseTimeInput extends LitElement {
--mdc-shape-small: 0;
width: 85px;
}
+ :host([clearable]) .mdc-select__anchor {
+ padding-inline-end: var(--select-selected-text-padding-end, 12px);
+ }
+ ha-icon-button {
+ position: relative
+ --mdc-icon-button-size: 36px;
+ --mdc-icon-size: 20px;
+ color: var(--secondary-text-color);
+ direction: var(--direction);
+ display: flex;
+ align-items: center;
+ background-color:var(--mdc-text-field-fill-color, whitesmoke);
+ border-bottom-style: solid;
+ border-bottom-width: 1px;
+ }
label {
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
diff --git a/src/components/ha-selector/ha-selector-time.ts b/src/components/ha-selector/ha-selector-time.ts
index ceb8d9fe93eb..bacba114fc87 100644
--- a/src/components/ha-selector/ha-selector-time.ts
+++ b/src/components/ha-selector/ha-selector-time.ts
@@ -27,6 +27,7 @@ export class HaTimeSelector extends LitElement {
.locale=${this.hass.locale}
.disabled=${this.disabled}
.required=${this.required}
+ clearable
.helper=${this.helper}
.label=${this.label}
enable-second
diff --git a/src/components/ha-time-input.ts b/src/components/ha-time-input.ts
index 29893298dc60..696dbef4aac5 100644
--- a/src/components/ha-time-input.ts
+++ b/src/components/ha-time-input.ts
@@ -23,6 +23,8 @@ export class HaTimeInput extends LitElement {
@property({ type: Boolean, attribute: "enable-second" })
public enableSecond = false;
+ @property({ type: Boolean, reflect: true }) public clearable?: boolean;
+
protected render() {
const useAMPM = useAmPm(this.locale);
@@ -48,22 +50,26 @@ export class HaTimeInput extends LitElement {
@value-changed=${this._timeChanged}
.enableSecond=${this.enableSecond}
.required=${this.required}
+ .clearable=${this.clearable && this.value !== undefined}
.helper=${this.helper}
>
`;
}
- private _timeChanged(ev: CustomEvent<{ value: TimeChangedEvent }>) {
+ private _timeChanged(ev: CustomEvent<{ value?: TimeChangedEvent }>) {
ev.stopPropagation();
const eventValue = ev.detail.value;
const useAMPM = useAmPm(this.locale);
- let value;
+ let value: string | undefined;
+ // An undefined eventValue means the time selector is being cleared,
+ // the `value` variable will (intentionally) be left undefined.
if (
- !isNaN(eventValue.hours) ||
- !isNaN(eventValue.minutes) ||
- !isNaN(eventValue.seconds)
+ eventValue !== undefined &&
+ (!isNaN(eventValue.hours) ||
+ !isNaN(eventValue.minutes) ||
+ !isNaN(eventValue.seconds))
) {
let hours = eventValue.hours || 0;
if (eventValue && useAMPM) {