diff --git a/src/components/device/ha-device-multi-picker.ts b/src/components/device/ha-device-multi-picker.ts
new file mode 100644
index 000000000000..c01e3ecd1f10
--- /dev/null
+++ b/src/components/device/ha-device-multi-picker.ts
@@ -0,0 +1,331 @@
+// @ts-ignore
+import chipStyles from "@material/chips/dist/mdc.chips.min.css";
+import "@material/mwc-button/mwc-button";
+import "@polymer/paper-tooltip/paper-tooltip";
+import { mdiClose, mdiDevices, mdiPlus } from "@mdi/js";
+import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
+import { css, CSSResultGroup, html, LitElement, unsafeCSS } from "lit";
+import { customElement, property, query, state } from "lit/decorators";
+import { classMap } from "lit/directives/class-map";
+import { fireEvent } from "../../common/dom/fire_event";
+import { ensureArray } from "../../common/ensure-array";
+import {
+ computeDeviceName,
+ DeviceRegistryEntry,
+ subscribeDeviceRegistry,
+} from "../../data/device_registry";
+import { EntityRegistryEntry } from "../../data/entity_registry";
+import { SubscribeMixin } from "../../mixins/subscribe-mixin";
+import { HomeAssistant } from "../../types";
+import { HaDevicePickerDeviceFilterFunc } from "./ha-device-picker";
+import "../ha-icon-button";
+import "../ha-state-icon";
+import "../ha-svg-icon";
+
+@customElement("ha-device-multi-picker")
+export class HaDeviceMultiPicker extends SubscribeMixin(LitElement) {
+ @property({ attribute: false }) public hass!: HomeAssistant;
+
+ @property({ type: Boolean }) public disabled?: boolean;
+
+ @property() public label?: string;
+
+ @property() public value?: any;
+
+ /**
+ * Show only devices with entities from specific domains.
+ * @type {Array}
+ * @attr include-domains
+ */
+
+ @property({ type: Array, attribute: "include-domains" })
+ public includeDomains?: string[];
+
+ /**
+ * Show no devices with entities of these domains.
+ * @type {Array}
+ * @attr exclude-domains
+ */
+ @property({ type: Array, attribute: "exclude-domains" })
+ public excludeDomains?: string[];
+
+ /**
+ * Show only devices with entities of these device classes.
+ * @type {Array}
+ * @attr include-device-classes
+ */
+ @property({ type: Array, attribute: "include-device-classes" })
+ public includeDeviceClasses?: string[];
+
+ @property() public deviceFilter?: HaDevicePickerDeviceFilterFunc;
+
+ @property() public entityFilter?: (entity: EntityRegistryEntry) => boolean;
+
+ @property({ type: Boolean, attribute: "multiple" })
+ public multiple?: boolean;
+
+ @state() private _devices?: { [deviceId: string]: DeviceRegistryEntry };
+
+ @state() private _addMode?: "device_id";
+
+ @query("#input") private _inputElement?;
+
+ public hassSubscribe(): UnsubscribeFunc[] {
+ return [
+ subscribeDeviceRegistry(this.hass.connection!, (devices) => {
+ const deviceLookup: { [deviceId: string]: DeviceRegistryEntry } = {};
+ for (const device of devices) {
+ deviceLookup[device.id] = device;
+ }
+ this._devices = deviceLookup;
+ }),
+ ];
+ }
+
+ protected render() {
+ if (!this._devices) {
+ return html``;
+ }
+ return html`
+
+ ${this.value
+ ? ensureArray(this.value).map((device_id) => {
+ const device = this._devices![device_id];
+ return this._renderChip(
+ "device_id",
+ device_id,
+ device ? computeDeviceName(device, this.hass) : device_id,
+ undefined,
+ mdiDevices
+ );
+ })
+ : ""}
+
+ ${this._renderPicker()}
+
+
+
+
+
+
+ ${this.hass.localize(
+ "ui.components.target-picker.add_device_id"
+ )}
+
+
+
+
+ `;
+ }
+
+ private async _showPicker(ev) {
+ this._addMode = ev.currentTarget.type;
+ await this.updateComplete;
+ setTimeout(() => {
+ this._inputElement?.open();
+ this._inputElement?.focus();
+ }, 0);
+ }
+
+ private _renderChip(
+ type: string,
+ id: string,
+ name: string,
+ entityState?: HassEntity,
+ iconPath?: string
+ ) {
+ return html`
+
+ ${iconPath
+ ? html`
`
+ : ""}
+ ${entityState
+ ? html`
`
+ : ""}
+
+
+ ${name}
+
+
+
+
+ ${this.hass.localize(
+ `ui.components.target-picker.remove_${type}`
+ )}
+
+
+ `;
+ }
+
+ private _renderPicker() {
+ switch (this._addMode) {
+ case "device_id":
+ return html``;
+ }
+ return html``;
+ }
+
+ private _targetPicked(ev) {
+ ev.stopPropagation();
+ if (!ev.detail.value) {
+ return;
+ }
+ const value =
+ this.multiple && this.value
+ ? [...ensureArray(this.value), ev.detail.value]
+ : ev.detail.value;
+ const target = ev.currentTarget;
+ target.value = "";
+ this._addMode = undefined;
+ fireEvent(this, "value-changed", { value });
+ }
+
+ private _handleRemove(ev) {
+ const target = ev.currentTarget as any;
+ fireEvent(this, "value-changed", {
+ value: this._removeItem(this.value, target.id),
+ });
+ }
+
+ private _removeItem(value: this["value"], id: string): this["value"] {
+ const newVal = ensureArray(value!)!.filter((val) => String(val) !== id);
+ if (newVal.length) {
+ return newVal;
+ }
+ return undefined;
+ }
+
+ static get styles(): CSSResultGroup {
+ return css`
+ ${unsafeCSS(chipStyles)}
+ .mdc-chip {
+ color: var(--primary-text-color);
+ }
+ .items {
+ z-index: 2;
+ }
+ .mdc-chip-set {
+ padding: 4px 0;
+ }
+ .mdc-chip.add {
+ color: rgba(0, 0, 0, 0.87);
+ }
+ .mdc-chip:not(.add) {
+ cursor: default;
+ }
+ .mdc-chip ha-icon-button {
+ --mdc-icon-button-size: 24px;
+ display: flex;
+ align-items: center;
+ outline: none;
+ }
+ .mdc-chip ha-icon-button ha-svg-icon {
+ border-radius: 50%;
+ background: var(--secondary-text-color);
+ }
+ .mdc-chip__icon.mdc-chip__icon--trailing {
+ width: 16px;
+ height: 16px;
+ --mdc-icon-size: 14px;
+ color: var(--secondary-text-color);
+ }
+ .mdc-chip__icon--leading {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ --mdc-icon-size: 20px;
+ border-radius: 50%;
+ padding: 6px;
+ margin-left: -14px !important;
+ }
+ .expand-btn {
+ margin-right: 0;
+ }
+ .mdc-chip.area_id:not(.add) {
+ border: 2px solid #fed6a4;
+ background: var(--card-background-color);
+ }
+ .mdc-chip.area_id:not(.add) .mdc-chip__icon--leading,
+ .mdc-chip.area_id.add {
+ background: #fed6a4;
+ }
+ .mdc-chip.device_id:not(.add) {
+ border: 2px solid #a8e1fb;
+ background: var(--card-background-color);
+ }
+ .mdc-chip.device_id:not(.add) .mdc-chip__icon--leading,
+ .mdc-chip.device_id.add {
+ background: #a8e1fb;
+ }
+ .mdc-chip.entity_id:not(.add) {
+ border: 2px solid #d2e7b9;
+ background: var(--card-background-color);
+ }
+ .mdc-chip.entity_id:not(.add) .mdc-chip__icon--leading,
+ .mdc-chip.entity_id.add {
+ background: #d2e7b9;
+ }
+ .mdc-chip:hover {
+ z-index: 5;
+ }
+ paper-tooltip.expand {
+ min-width: 200px;
+ }
+ :host([disabled]) .mdc-chip {
+ opacity: var(--light-disabled-opacity);
+ pointer-events: none;
+ }
+ `;
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "ha-device-multi-picker": HaDeviceMultiPicker;
+ }
+}
diff --git a/src/components/entity/ha-entity-multi-picker.ts b/src/components/entity/ha-entity-multi-picker.ts
new file mode 100644
index 000000000000..c55c49988875
--- /dev/null
+++ b/src/components/entity/ha-entity-multi-picker.ts
@@ -0,0 +1,330 @@
+// @ts-ignore
+import chipStyles from "@material/chips/dist/mdc.chips.min.css";
+import "@material/mwc-button/mwc-button";
+import "@polymer/paper-tooltip/paper-tooltip";
+import { mdiClose, mdiPlus } from "@mdi/js";
+import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
+import { css, CSSResultGroup, html, LitElement, unsafeCSS } from "lit";
+import { customElement, property, query, state } from "lit/decorators";
+import { classMap } from "lit/directives/class-map";
+import { fireEvent } from "../../common/dom/fire_event";
+import { ensureArray } from "../../common/ensure-array";
+import { computeStateName } from "../../common/entity/compute_state_name";
+import {
+ EntityRegistryEntry,
+ subscribeEntityRegistry,
+} from "../../data/entity_registry";
+import { SubscribeMixin } from "../../mixins/subscribe-mixin";
+import { HomeAssistant } from "../../types";
+import type { HaDevicePickerDeviceFilterFunc } from "../device/ha-device-picker";
+import type { HaEntityPickerEntityFilterFunc } from "./ha-entity-picker";
+import "../ha-icon-button";
+import "../ha-state-icon";
+import "../ha-svg-icon";
+
+@customElement("ha-entity-multi-picker")
+export class HaEntityMultiPicker extends SubscribeMixin(LitElement) {
+ @property({ attribute: false }) public hass!: HomeAssistant;
+
+ @property({ type: Boolean }) public disabled?: boolean;
+
+ @property() public label?: string;
+
+ @property() public value?: any;
+
+ /**
+ * Show only entitys with entities from specific domains.
+ * @type {Array}
+ * @attr include-domains
+ */
+
+ @property({ type: Array, attribute: "include-domains" })
+ public includeDomains?: string[];
+
+ /**
+ * Show no entitys with entities of these domains.
+ * @type {Array}
+ * @attr exclude-domains
+ */
+ @property({ type: Array, attribute: "exclude-domains" })
+ public excludeDomains?: string[];
+
+ /**
+ * Show only entitys with entities of these device classes.
+ * @type {Array}
+ * @attr include-device-classes
+ */
+ @property({ type: Array, attribute: "include-device-classes" })
+ public includeDeviceClasses?: string[];
+
+ @property() public deviceFilter?: HaDevicePickerDeviceFilterFunc;
+
+ @property() public entityFilter?: HaEntityPickerEntityFilterFunc;
+
+ @property({ type: Boolean, attribute: "multiple" })
+ public multiple?: boolean;
+
+ @state() private _entities?: { [entityId: string]: EntityRegistryEntry };
+
+ @state() private _addMode?: "entity_id";
+
+ @query("#input") private _inputElement?;
+
+ public hassSubscribe(): UnsubscribeFunc[] {
+ return [
+ subscribeEntityRegistry(this.hass.connection!, (entities) => {
+ const entityLookup: { [entityId: string]: EntityRegistryEntry } = {};
+ for (const entity of entities) {
+ entityLookup[entity.entity_id] = entity;
+ }
+ this._entities = entityLookup;
+ }),
+ ];
+ }
+
+ protected render() {
+ if (!this._entities) {
+ return html``;
+ }
+ return html`
+
+ ${this.value
+ ? ensureArray(this.value).map((entity_id) => {
+ const entity = this.hass.states[entity_id];
+ return this._renderChip(
+ "entity_id",
+ entity_id,
+ entity ? computeStateName(entity) : entity_id,
+ entity
+ );
+ })
+ : ""}
+
+ ${this._renderPicker()}
+
+
+
+
+
+
+ ${this.hass.localize(
+ "ui.components.target-picker.add_entity_id"
+ )}
+
+
+
+
+ `;
+ }
+
+ private async _showPicker(ev) {
+ this._addMode = ev.currentTarget.type;
+ await this.updateComplete;
+ setTimeout(() => {
+ this._inputElement?.open();
+ this._inputElement?.focus();
+ }, 0);
+ }
+
+ private _renderChip(
+ type: string,
+ id: string,
+ name: string,
+ entityState?: HassEntity,
+ iconPath?: string
+ ) {
+ return html`
+
+ ${iconPath
+ ? html`
`
+ : ""}
+ ${entityState
+ ? html`
`
+ : ""}
+
+
+ ${name}
+
+
+
+
+ ${this.hass.localize(
+ `ui.components.target-picker.remove_${type}`
+ )}
+
+
+ `;
+ }
+
+ private _renderPicker() {
+ switch (this._addMode) {
+ case "entity_id":
+ return html``;
+ }
+ return html``;
+ }
+
+ private _targetPicked(ev) {
+ ev.stopPropagation();
+ if (!ev.detail.value) {
+ return;
+ }
+ const value =
+ this.multiple && this.value
+ ? [...ensureArray(this.value), ev.detail.value]
+ : ev.detail.value;
+ const target = ev.currentTarget;
+ target.value = "";
+ this._addMode = undefined;
+ fireEvent(this, "value-changed", { value });
+ }
+
+ private _handleRemove(ev) {
+ const target = ev.currentTarget as any;
+ fireEvent(this, "value-changed", {
+ value: this._removeItem(this.value, target.id),
+ });
+ }
+
+ private _removeItem(value: this["value"], id: string): this["value"] {
+ const newVal = ensureArray(value!)!.filter((val) => String(val) !== id);
+ if (newVal.length) {
+ return newVal;
+ }
+ return undefined;
+ }
+
+ static get styles(): CSSResultGroup {
+ return css`
+ ${unsafeCSS(chipStyles)}
+ .mdc-chip {
+ color: var(--primary-text-color);
+ }
+ .items {
+ z-index: 2;
+ }
+ .mdc-chip-set {
+ padding: 4px 0;
+ }
+ .mdc-chip.add {
+ color: rgba(0, 0, 0, 0.87);
+ }
+ .mdc-chip:not(.add) {
+ cursor: default;
+ }
+ .mdc-chip ha-icon-button {
+ --mdc-icon-button-size: 24px;
+ display: flex;
+ align-items: center;
+ outline: none;
+ }
+ .mdc-chip ha-icon-button ha-svg-icon {
+ border-radius: 50%;
+ background: var(--secondary-text-color);
+ }
+ .mdc-chip__icon.mdc-chip__icon--trailing {
+ width: 16px;
+ height: 16px;
+ --mdc-icon-size: 14px;
+ color: var(--secondary-text-color);
+ }
+ .mdc-chip__icon--leading {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ --mdc-icon-size: 20px;
+ border-radius: 50%;
+ padding: 6px;
+ margin-left: -14px !important;
+ }
+ .expand-btn {
+ margin-right: 0;
+ }
+ .mdc-chip.area_id:not(.add) {
+ border: 2px solid #fed6a4;
+ background: var(--card-background-color);
+ }
+ .mdc-chip.area_id:not(.add) .mdc-chip__icon--leading,
+ .mdc-chip.area_id.add {
+ background: #fed6a4;
+ }
+ .mdc-chip.device_id:not(.add) {
+ border: 2px solid #a8e1fb;
+ background: var(--card-background-color);
+ }
+ .mdc-chip.device_id:not(.add) .mdc-chip__icon--leading,
+ .mdc-chip.device_id.add {
+ background: #a8e1fb;
+ }
+ .mdc-chip.entity_id:not(.add) {
+ border: 2px solid #d2e7b9;
+ background: var(--card-background-color);
+ }
+ .mdc-chip.entity_id:not(.add) .mdc-chip__icon--leading,
+ .mdc-chip.entity_id.add {
+ background: #d2e7b9;
+ }
+ .mdc-chip:hover {
+ z-index: 5;
+ }
+ paper-tooltip.expand {
+ min-width: 200px;
+ }
+ :host([disabled]) .mdc-chip {
+ opacity: var(--light-disabled-opacity);
+ pointer-events: none;
+ }
+ `;
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "ha-entity-multi-picker": HaEntityMultiPicker;
+ }
+}
diff --git a/src/components/ha-area-multi-picker.ts b/src/components/ha-area-multi-picker.ts
new file mode 100644
index 000000000000..9b0a60ca977b
--- /dev/null
+++ b/src/components/ha-area-multi-picker.ts
@@ -0,0 +1,331 @@
+// @ts-ignore
+import chipStyles from "@material/chips/dist/mdc.chips.min.css";
+import "@material/mwc-button/mwc-button";
+import "@polymer/paper-tooltip/paper-tooltip";
+import { mdiClose, mdiPlus, mdiSofa } from "@mdi/js";
+import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
+import { css, CSSResultGroup, html, LitElement, unsafeCSS } from "lit";
+import { customElement, property, query, state } from "lit/decorators";
+import { classMap } from "lit/directives/class-map";
+import { fireEvent } from "../common/dom/fire_event";
+import { ensureArray } from "../common/ensure-array";
+import {
+ AreaRegistryEntry,
+ subscribeAreaRegistry,
+} from "../data/area_registry";
+import { EntityRegistryEntry } from "../data/entity_registry";
+import { SubscribeMixin } from "../mixins/subscribe-mixin";
+import { HomeAssistant } from "../types";
+import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
+import "./ha-area-picker";
+import "./ha-icon-button";
+import "./ha-state-icon";
+import "./ha-svg-icon";
+
+@customElement("ha-area-multi-picker")
+export class HaAreaMultiPicker extends SubscribeMixin(LitElement) {
+ @property({ attribute: false }) public hass!: HomeAssistant;
+
+ @property({ type: Boolean }) public disabled?: boolean;
+
+ @property() public label?: string;
+
+ @property() public value?: any;
+
+ /**
+ * Show only areas with entities from specific domains.
+ * @type {Array}
+ * @attr include-domains
+ */
+
+ @property({ type: Array, attribute: "include-domains" })
+ public includeDomains?: string[];
+
+ /**
+ * Show no areas with entities of these domains.
+ * @type {Array}
+ * @attr exclude-domains
+ */
+ @property({ type: Array, attribute: "exclude-domains" })
+ public excludeDomains?: string[];
+
+ /**
+ * Show only areas with entities of these device classes.
+ * @type {Array}
+ * @attr include-device-classes
+ */
+ @property({ type: Array, attribute: "include-device-classes" })
+ public includeDeviceClasses?: string[];
+
+ @property() public deviceFilter?: HaDevicePickerDeviceFilterFunc;
+
+ @property() public entityFilter?: (entity: EntityRegistryEntry) => boolean;
+
+ @property({ type: Boolean, attribute: "multiple" })
+ public multiple?: boolean;
+
+ @state() private _areas?: { [areaId: string]: AreaRegistryEntry };
+
+ @state() private _addMode?: "area_id";
+
+ @query("#input") private _inputElement?;
+
+ public hassSubscribe(): UnsubscribeFunc[] {
+ return [
+ subscribeAreaRegistry(this.hass.connection!, (areas) => {
+ const areaLookup: { [areaId: string]: AreaRegistryEntry } = {};
+ for (const area of areas) {
+ areaLookup[area.area_id] = area;
+ }
+ this._areas = areaLookup;
+ }),
+ ];
+ }
+
+ protected render() {
+ if (!this._areas) {
+ return html``;
+ }
+ return html`
+
+ ${this.value
+ ? ensureArray(this.value).map((area_id) => {
+ const area = this._areas![area_id];
+ return this._renderChip(
+ "area_id",
+ area_id,
+ area?.name || area_id,
+ undefined,
+ mdiSofa
+ );
+ })
+ : ""}
+
+ ${this._renderPicker()}
+
+
+
+
+
+
+ ${this.hass.localize(
+ "ui.components.target-picker.add_area_id"
+ )}
+
+
+
+
+ `;
+ }
+
+ private async _showPicker(ev) {
+ this._addMode = ev.currentTarget.type;
+ await this.updateComplete;
+ setTimeout(() => {
+ this._inputElement?.open();
+ this._inputElement?.focus();
+ }, 0);
+ }
+
+ private _renderChip(
+ type: string,
+ id: string,
+ name: string,
+ entityState?: HassEntity,
+ iconPath?: string
+ ) {
+ return html`
+
+ ${iconPath
+ ? html`
`
+ : ""}
+ ${entityState
+ ? html`
`
+ : ""}
+
+
+ ${name}
+
+
+
+
+ ${this.hass.localize(
+ `ui.components.target-picker.remove_${type}`
+ )}
+
+
+ `;
+ }
+
+ private _renderPicker() {
+ switch (this._addMode) {
+ case "area_id":
+ return html``;
+ }
+ return html``;
+ }
+
+ private _targetPicked(ev) {
+ ev.stopPropagation();
+ if (!ev.detail.value) {
+ return;
+ }
+ const value =
+ this.multiple && this.value
+ ? [...ensureArray(this.value), ev.detail.value]
+ : ev.detail.value;
+ const target = ev.currentTarget;
+ target.value = "";
+ this._addMode = undefined;
+ fireEvent(this, "value-changed", { value });
+ }
+
+ private _handleRemove(ev) {
+ const target = ev.currentTarget as any;
+ fireEvent(this, "value-changed", {
+ value: this._removeItem(this.value, target.id),
+ });
+ }
+
+ private _removeItem(value: this["value"], id: string): this["value"] {
+ const newVal = ensureArray(value!)!.filter((val) => String(val) !== id);
+ if (newVal.length) {
+ return newVal;
+ }
+ return undefined;
+ }
+
+ static get styles(): CSSResultGroup {
+ return css`
+ ${unsafeCSS(chipStyles)}
+ .mdc-chip {
+ color: var(--primary-text-color);
+ }
+ .items {
+ z-index: 2;
+ }
+ .mdc-chip-set {
+ padding: 4px 0;
+ }
+ .mdc-chip.add {
+ color: rgba(0, 0, 0, 0.87);
+ }
+ .mdc-chip:not(.add) {
+ cursor: default;
+ }
+ .mdc-chip ha-icon-button {
+ --mdc-icon-button-size: 24px;
+ display: flex;
+ align-items: center;
+ outline: none;
+ }
+ .mdc-chip ha-icon-button ha-svg-icon {
+ border-radius: 50%;
+ background: var(--secondary-text-color);
+ }
+ .mdc-chip__icon.mdc-chip__icon--trailing {
+ width: 16px;
+ height: 16px;
+ --mdc-icon-size: 14px;
+ color: var(--secondary-text-color);
+ }
+ .mdc-chip__icon--leading {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ --mdc-icon-size: 20px;
+ border-radius: 50%;
+ padding: 6px;
+ margin-left: -14px !important;
+ }
+ .expand-btn {
+ margin-right: 0;
+ }
+ .mdc-chip.area_id:not(.add) {
+ border: 2px solid #fed6a4;
+ background: var(--card-background-color);
+ }
+ .mdc-chip.area_id:not(.add) .mdc-chip__icon--leading,
+ .mdc-chip.area_id.add {
+ background: #fed6a4;
+ }
+ .mdc-chip.device_id:not(.add) {
+ border: 2px solid #a8e1fb;
+ background: var(--card-background-color);
+ }
+ .mdc-chip.device_id:not(.add) .mdc-chip__icon--leading,
+ .mdc-chip.device_id.add {
+ background: #a8e1fb;
+ }
+ .mdc-chip.entity_id:not(.add) {
+ border: 2px solid #d2e7b9;
+ background: var(--card-background-color);
+ }
+ .mdc-chip.entity_id:not(.add) .mdc-chip__icon--leading,
+ .mdc-chip.entity_id.add {
+ background: #d2e7b9;
+ }
+ .mdc-chip:hover {
+ z-index: 5;
+ }
+ paper-tooltip.expand {
+ min-width: 200px;
+ }
+ :host([disabled]) .mdc-chip {
+ opacity: var(--light-disabled-opacity);
+ pointer-events: none;
+ }
+ `;
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "ha-area-multi-picker": HaAreaMultiPicker;
+ }
+}
diff --git a/src/components/ha-selector/ha-selector-area.ts b/src/components/ha-selector/ha-selector-area.ts
index 5f307dd0130d..097f90a7735b 100644
--- a/src/components/ha-selector/ha-selector-area.ts
+++ b/src/components/ha-selector/ha-selector-area.ts
@@ -5,7 +5,7 @@ import { DeviceRegistryEntry } from "../../data/device_registry";
import { EntityRegistryEntry } from "../../data/entity_registry";
import { AreaSelector } from "../../data/selector";
import { HomeAssistant } from "../../types";
-import "../ha-area-picker";
+import "../ha-area-multi-picker";
@customElement("ha-selector-area")
export class HaAreaSelector extends LitElement {
@@ -34,11 +34,10 @@ export class HaAreaSelector extends LitElement {
}
protected render() {
- return html``;
+ .multiple=${this.selector.area.multiple}
+ >`;
}
private _filterEntities = (entity: EntityRegistryEntry): boolean => {
diff --git a/src/components/ha-selector/ha-selector-device.ts b/src/components/ha-selector/ha-selector-device.ts
index 60da624665bd..7d74352c1107 100644
--- a/src/components/ha-selector/ha-selector-device.ts
+++ b/src/components/ha-selector/ha-selector-device.ts
@@ -4,7 +4,7 @@ import { ConfigEntry, getConfigEntries } from "../../data/config_entries";
import { DeviceRegistryEntry } from "../../data/device_registry";
import { DeviceSelector } from "../../data/selector";
import { HomeAssistant } from "../../types";
-import "../device/ha-device-picker";
+import "../device/ha-device-multi-picker";
@customElement("ha-selector-device")
export class HaDeviceSelector extends LitElement {
@@ -30,7 +30,7 @@ export class HaDeviceSelector extends LitElement {
}
protected render() {
- return html``;
+ .multiple=${this.selector.device.multiple}
+ >`;
}
private _filterDevices = (device: DeviceRegistryEntry): boolean => {
diff --git a/src/components/ha-selector/ha-selector-entity.ts b/src/components/ha-selector/ha-selector-entity.ts
index 2facd604babe..3028940ada9d 100644
--- a/src/components/ha-selector/ha-selector-entity.ts
+++ b/src/components/ha-selector/ha-selector-entity.ts
@@ -6,7 +6,7 @@ import { subscribeEntityRegistry } from "../../data/entity_registry";
import { EntitySelector } from "../../data/selector";
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
import { HomeAssistant } from "../../types";
-import "../entity/ha-entity-picker";
+import "../entity/ha-entity-multi-picker";
@customElement("ha-selector-entity")
export class HaEntitySelector extends SubscribeMixin(LitElement) {
@@ -23,14 +23,15 @@ export class HaEntitySelector extends SubscribeMixin(LitElement) {
@property({ type: Boolean }) public disabled = false;
protected render() {
- return html``;
+ .multiple=${this.selector.entity.multiple}
+ >`;
}
public hassSubscribe(): UnsubscribeFunc[] {
diff --git a/src/data/selector.ts b/src/data/selector.ts
index 3bb2999877b8..39839c96676b 100644
--- a/src/data/selector.ts
+++ b/src/data/selector.ts
@@ -16,6 +16,7 @@ export interface EntitySelector {
integration?: string;
domain?: string;
device_class?: string;
+ multiple?: boolean;
};
}
@@ -28,6 +29,7 @@ export interface DeviceSelector {
domain?: EntitySelector["entity"]["domain"];
device_class?: EntitySelector["entity"]["device_class"];
};
+ multiple?: boolean;
};
}
@@ -50,6 +52,7 @@ export interface AreaSelector {
manufacturer?: DeviceSelector["device"]["manufacturer"];
model?: DeviceSelector["device"]["model"];
};
+ multiple?: boolean;
};
}