diff --git a/src/components/ha-select.ts b/src/components/ha-select.ts
index a0196feb82..e1454795c2 100644
--- a/src/components/ha-select.ts
+++ b/src/components/ha-select.ts
@@ -1,15 +1,32 @@
import { SelectBase } from "@material/mwc-select/mwc-select-base";
import { styles } from "@material/mwc-select/mwc-select.css";
+import { mdiClose } from "@mdi/js";
import { css, html, nothing } from "lit";
import { customElement, property } from "lit/decorators";
import { debounce } from "../common/util/debounce";
import { nextRender } from "../common/util/render-status";
+import "./ha-icon-button";
@customElement("ha-select")
export class HaSelect extends SelectBase {
// @ts-ignore
@property({ type: Boolean }) public icon?: boolean;
+ @property({ type: Boolean, reflect: true }) public clearable?: boolean;
+
+ protected override render() {
+ return html`
+ ${super.render()}
+ ${this.clearable && !this.required && !this.disabled && this.value
+ ? html``
+ : nothing}
+ `;
+ }
+
protected override renderLeadingIcon() {
if (!this.icon) {
return nothing;
@@ -33,6 +50,15 @@ export class HaSelect extends SelectBase {
);
}
+ private _clearValue(): void {
+ if (this.disabled || !this.value) {
+ return;
+ }
+ this.valueSetDirectly = true;
+ this.select(-1);
+ this.mdcFoundation.handleChange();
+ }
+
private _translationsUpdated = debounce(async () => {
await nextRender();
this.layoutOptions();
@@ -41,6 +67,9 @@ export class HaSelect extends SelectBase {
static override styles = [
styles,
css`
+ :host([clearable]) {
+ position: relative;
+ }
.mdc-select:not(.mdc-select--disabled) .mdc-select__icon {
color: var(--secondary-text-color);
}
@@ -71,6 +100,20 @@ export class HaSelect extends SelectBase {
.mdc-select__selected-text-container {
padding-inline-end: var(--select-selected-text-padding-end, 0px);
}
+ :host([clearable]) .mdc-select__selected-text-container {
+ padding-inline-end: var(--select-selected-text-padding-end, 12px);
+ }
+ ha-icon-button {
+ position: absolute;
+ top: 10px;
+ right: 28px;
+ --mdc-icon-button-size: 36px;
+ --mdc-icon-size: 20px;
+ color: var(--secondary-text-color);
+ inset-inline-start: initial;
+ inset-inline-end: 28px;
+ direction: var(--direction);
+ }
`,
];
}
diff --git a/src/components/ha-selector/ha-selector-select.ts b/src/components/ha-selector/ha-selector-select.ts
index 12ea426b74..aec4aa5ad8 100644
--- a/src/components/ha-selector/ha-selector-select.ts
+++ b/src/components/ha-selector/ha-selector-select.ts
@@ -1,10 +1,11 @@
import "@material/mwc-list/mwc-list-item";
import { mdiClose } from "@mdi/js";
-import { css, html, LitElement, nothing } from "lit";
+import { css, html, LitElement } from "lit";
import { customElement, property, query } from "lit/decorators";
+import { ensureArray } from "../../common/array/ensure-array";
import { fireEvent } from "../../common/dom/fire_event";
import { stopPropagation } from "../../common/dom/stop_propagation";
-import { ensureArray } from "../../common/array/ensure-array";
+import { caseInsensitiveStringCompare } from "../../common/string/compare";
import type { SelectOption, SelectSelector } from "../../data/selector";
import type { HomeAssistant } from "../../types";
import "../ha-checkbox";
@@ -13,10 +14,9 @@ import "../ha-chip-set";
import "../ha-combo-box";
import type { HaComboBox } from "../ha-combo-box";
import "../ha-formfield";
+import "../ha-input-helper-text";
import "../ha-radio";
import "../ha-select";
-import "../ha-input-helper-text";
-import { caseInsensitiveStringCompare } from "../../common/string/compare";
@customElement("ha-selector-select")
export class HaSelectSelector extends LitElement {
@@ -198,6 +198,7 @@ export class HaSelectSelector extends LitElement {
.helper=${this.helper ?? ""}
.disabled=${this.disabled}
.required=${this.required}
+ clearable
@closed=${stopPropagation}
@selected=${this._valueChanged}
>
@@ -209,14 +210,6 @@ export class HaSelectSelector extends LitElement {
`
)}
- ${!this.required && !this.disabled && this.value
- ? html``
- : nothing}
`;
}
@@ -233,15 +226,6 @@ export class HaSelectSelector extends LitElement {
);
}
- private _clearValue(): void {
- if (this.disabled || !this.value) {
- return;
- }
- fireEvent(this, "value-changed", {
- value: undefined,
- });
- }
-
private _valueChanged(ev) {
ev.stopPropagation();
const value = ev.detail?.value || ev.target.value;
@@ -359,20 +343,6 @@ export class HaSelectSelector extends LitElement {
mwc-list-item[disabled] {
--mdc-theme-text-primary-on-background: var(--disabled-text-color);
}
- ha-select {
- --select-selected-text-padding-end: 12px;
- }
- ha-icon-button {
- position: absolute;
- top: 10px;
- right: 28px;
- --mdc-icon-button-size: 36px;
- --mdc-icon-size: 20px;
- color: var(--secondary-text-color);
- inset-inline-start: initial;
- inset-inline-end: 28px;
- direction: var(--direction);
- }
`;
}
diff --git a/src/panels/config/entities/entity-registry-settings-editor.ts b/src/panels/config/entities/entity-registry-settings-editor.ts
index 840e310114..c5c19dbee0 100644
--- a/src/panels/config/entities/entity-registry-settings-editor.ts
+++ b/src/panels/config/entities/entity-registry-settings-editor.ts
@@ -455,10 +455,10 @@ export class EntityRegistrySettingsEditor extends LitElement {
.value=${this._deviceClass}
naturalMenuWidth
fixedMenuPosition
+ clearable
@selected=${this._deviceClassChanged}
@closed=${stopPropagation}
>
-
${this._deviceClassesSorted(
domain,
this._deviceClassOptions[0],