diff --git a/gallery/src/pages/components/ha-selector.ts b/gallery/src/pages/components/ha-selector.ts
index 053c95d7da..3a456cae66 100644
--- a/gallery/src/pages/components/ha-selector.ts
+++ b/gallery/src/pages/components/ha-selector.ts
@@ -164,9 +164,24 @@ const SCHEMAS: {
},
},
object: { name: "Object", selector: { object: {} } },
+ select_radio: {
+ name: "Select (Radio)",
+ selector: { select: { options: ["Option 1", "Option 2"] } },
+ },
select: {
name: "Select",
- selector: { select: { options: ["Option 1", "Option 2"] } },
+ selector: {
+ select: {
+ options: [
+ "Option 1",
+ "Option 2",
+ "Option 3",
+ "Option 4",
+ "Option 5",
+ "Option 6",
+ ],
+ },
+ },
},
icon: { name: "Icon", selector: { icon: {} } },
media: { name: "Media", selector: { media: {} } },
diff --git a/src/components/ha-form/ha-form-select.ts b/src/components/ha-form/ha-form-select.ts
index 2e342a39a2..73dc74b95c 100644
--- a/src/components/ha-form/ha-form-select.ts
+++ b/src/components/ha-form/ha-form-select.ts
@@ -1,16 +1,20 @@
-import "@material/mwc-list/mwc-list-item";
-import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
-import { customElement, property, query } from "lit/decorators";
+import memoizeOne from "memoize-one";
+import { html, LitElement, TemplateResult } from "lit";
+import { customElement, property } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
-import { stopPropagation } from "../../common/dom/stop_propagation";
-import "../ha-radio";
-import type { HaRadio } from "../ha-radio";
-import "../ha-select";
-import type { HaSelect } from "../ha-select";
-import { HaFormElement, HaFormSelectData, HaFormSelectSchema } from "./types";
+import type { HomeAssistant } from "../../types";
+import type {
+ HaFormElement,
+ HaFormSelectData,
+ HaFormSelectSchema,
+} from "./types";
+import type { SelectSelector } from "../../data/selector";
+import "../ha-selector/ha-selector-select";
@customElement("ha-form-select")
export class HaFormSelect extends LitElement implements HaFormElement {
+ @property({ attribute: false }) public hass!: HomeAssistant;
+
@property({ attribute: false }) public schema!: HaFormSelectSchema;
@property() public data!: HaFormSelectData;
@@ -19,60 +23,35 @@ export class HaFormSelect extends LitElement implements HaFormElement {
@property({ type: Boolean }) public disabled = false;
- @query("ha-select", true) private _input?: HTMLElement;
-
- public focus() {
- if (this._input) {
- this._input.focus();
- }
- }
+ private _selectSchema = memoizeOne(
+ (options): SelectSelector => ({
+ select: {
+ options: options.map((option) => ({
+ value: option[0],
+ label: option[1],
+ })),
+ },
+ })
+ );
protected render(): TemplateResult {
- if (this.schema.required && this.schema.options!.length < 6) {
- return html`
-
- ${this.label}
- ${this.schema.options.map(
- ([value, label]) => html`
-
-
-
- `
- )}
-
- `;
- }
-
return html`
-
- ${!this.schema.required
- ? html``
- : ""}
- ${this.schema.options!.map(
- ([value, label]) => html`
- ${label}
- `
- )}
-
+ .required=${this.schema.required}
+ .selector=${this._selectSchema(this.schema.options)}
+ @value-changed=${this._valueChanged}
+ >
`;
}
private _valueChanged(ev: CustomEvent) {
ev.stopPropagation();
- let value: string | undefined = (ev.target as HaSelect | HaRadio).value;
+ let value: string | undefined = ev.detail.value;
if (value === this.data) {
return;
@@ -86,15 +65,6 @@ export class HaFormSelect extends LitElement implements HaFormElement {
value,
});
}
-
- static get styles(): CSSResultGroup {
- return css`
- ha-select,
- mwc-formfield {
- display: block;
- }
- `;
- }
}
declare global {
diff --git a/src/components/ha-selector/ha-selector-select.ts b/src/components/ha-selector/ha-selector-select.ts
index ebc2704992..96cc114483 100644
--- a/src/components/ha-selector/ha-selector-select.ts
+++ b/src/components/ha-selector/ha-selector-select.ts
@@ -1,17 +1,19 @@
+import "@material/mwc-formfield/mwc-formfield";
import "@material/mwc-list/mwc-list-item";
import { css, CSSResultGroup, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
import { stopPropagation } from "../../common/dom/stop_propagation";
-import { SelectOption, SelectSelector } from "../../data/selector";
-import { HomeAssistant } from "../../types";
+import type { SelectOption, SelectSelector } from "../../data/selector";
+import type { HomeAssistant } from "../../types";
import "../ha-select";
+import "../ha-radio";
@customElement("ha-selector-select")
export class HaSelectSelector extends LitElement {
- @property() public hass!: HomeAssistant;
+ @property({ attribute: false }) public hass!: HomeAssistant;
- @property() public selector!: SelectSelector;
+ @property({ attribute: false }) public selector!: SelectSelector;
@property() public value?: string;
@@ -21,24 +23,51 @@ export class HaSelectSelector extends LitElement {
@property({ type: Boolean }) public disabled = false;
- protected render() {
- return html`
- ${this.selector.select.options.map((item: string | SelectOption) => {
- const value = typeof item === "object" ? item.value : item;
- const label = typeof item === "object" ? item.label : item;
+ @property({ type: Boolean }) public required = true;
- return html`${label}`;
- })}
- `;
+ protected render() {
+ if (this.required && this.selector.select.options!.length < 6) {
+ return html`
+
+ ${this.label}
+ ${this.selector.select.options.map((item: string | SelectOption) => {
+ const value = typeof item === "object" ? item.value : item;
+ const label = typeof item === "object" ? item.label : item;
+
+ return html`
+
+
+
+ `;
+ })}
+
+ `;
+ }
+
+ return html`
+
+ ${this.selector.select.options.map((item: string | SelectOption) => {
+ const value = typeof item === "object" ? item.value : item;
+ const label = typeof item === "object" ? item.label : item;
+
+ return html`${label}`;
+ })}
+
+ `;
}
private _valueChanged(ev) {
@@ -56,6 +85,9 @@ export class HaSelectSelector extends LitElement {
ha-select {
width: 100%;
}
+ mwc-formfield {
+ display: block;
+ }
`;
}
}