diff --git a/src/components/device/ha-device-picker.ts b/src/components/device/ha-device-picker.ts
index 715a42c1db..8b9e477d6a 100644
--- a/src/components/device/ha-device-picker.ts
+++ b/src/components/device/ha-device-picker.ts
@@ -214,7 +214,7 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
if (!devEntities || !devEntities.length) {
return false;
}
- return deviceEntityLookup[device.id].some((entity) => {
+ return devEntities.some((entity) => {
const stateObj = this.hass.states[entity.entity_id];
if (!stateObj) {
return false;
diff --git a/src/components/device/ha-devices-picker.ts b/src/components/device/ha-devices-picker.ts
index 1f1340ef04..327af4c8ac 100644
--- a/src/components/device/ha-devices-picker.ts
+++ b/src/components/device/ha-devices-picker.ts
@@ -4,7 +4,10 @@ import { fireEvent } from "../../common/dom/fire_event";
import { PolymerChangedEvent } from "../../polymer-types";
import { HomeAssistant } from "../../types";
import "./ha-device-picker";
-import type { HaDevicePickerDeviceFilterFunc } from "./ha-device-picker";
+import type {
+ HaDevicePickerDeviceFilterFunc,
+ HaDevicePickerEntityFilterFunc,
+} from "./ha-device-picker";
@customElement("ha-devices-picker")
class HaDevicesPicker extends LitElement {
@@ -44,6 +47,8 @@ class HaDevicesPicker extends LitElement {
@property() public deviceFilter?: HaDevicePickerDeviceFilterFunc;
+ @property() public entityFilter?: HaDevicePickerEntityFilterFunc;
+
protected render(): TemplateResult {
if (!this.hass) {
return html``;
@@ -59,6 +64,7 @@ class HaDevicesPicker extends LitElement {
.curValue=${entityId}
.hass=${this.hass}
.deviceFilter=${this.deviceFilter}
+ .entityFilter=${this.entityFilter}
.includeDomains=${this.includeDomains}
.excludeDomains=${this.excludeDomains}
.includeDeviceClasses=${this.includeDeviceClasses}
@@ -76,8 +82,10 @@ class HaDevicesPicker extends LitElement {
.hass=${this.hass}
.helper=${this.helper}
.deviceFilter=${this.deviceFilter}
+ .entityFilter=${this.entityFilter}
.includeDomains=${this.includeDomains}
.excludeDomains=${this.excludeDomains}
+ .excludeDevices=${currentDevices}
.includeDeviceClasses=${this.includeDeviceClasses}
.label=${this.pickDeviceLabel}
.disabled=${this.disabled}
diff --git a/src/components/ha-area-picker.ts b/src/components/ha-area-picker.ts
index 0f47ed05b9..6f016cc1f7 100644
--- a/src/components/ha-area-picker.ts
+++ b/src/components/ha-area-picker.ts
@@ -233,6 +233,9 @@ export class HaAreaPicker extends LitElement {
});
inputEntities = inputEntities!.filter((entity) => {
const stateObj = this.hass.states[entity.entity_id];
+ if (!stateObj) {
+ return false;
+ }
return entityFilter!(stateObj);
});
}
diff --git a/src/components/ha-target-picker.ts b/src/components/ha-target-picker.ts
index 599720075a..02eb8f1456 100644
--- a/src/components/ha-target-picker.ts
+++ b/src/components/ha-target-picker.ts
@@ -13,6 +13,7 @@ import { HassEntity, HassServiceTarget } 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 { ComboBoxLightOpenedChangedEvent } from "@vaadin/combo-box/vaadin-combo-box-light";
import { ensureArray } from "../common/array/ensure-array";
import { fireEvent } from "../common/dom/fire_event";
import { computeDomain } from "../common/entity/compute_domain";
@@ -31,6 +32,8 @@ import "./ha-area-picker";
import "./ha-icon-button";
import "./ha-input-helper-text";
import "./ha-svg-icon";
+import { stopPropagation } from "../common/dom/stop_propagation";
+import "@material/mwc-menu/mwc-menu-surface";
@customElement("ha-target-picker")
export class HaTargetPicker extends LitElement {
@@ -64,28 +67,21 @@ export class HaTargetPicker extends LitElement {
@property({ type: Boolean, reflect: true }) public disabled = false;
- @property({ type: Boolean }) public horizontal = false;
+ @property({ type: Boolean }) public addOnTop = false;
@state() private _addMode?: "area_id" | "entity_id" | "device_id";
@query("#input") private _inputElement?;
+ @query(".add-container", true) private _addContainer?: HTMLDivElement;
+
+ private _opened = false;
+
protected render() {
- return html`
- ${this.horizontal
- ? html`
-
- ${this._renderChips()} ${this._renderPicker()}
-
- ${this._renderItems()}
- `
- : html`
-
- ${this._renderItems()} ${this._renderPicker()}
- ${this._renderChips()}
-
- `}
- `;
+ if (this.addOnTop) {
+ return html` ${this._renderChips()} ${this._renderItems()} `;
+ }
+ return html` ${this._renderItems()} ${this._renderChips()} `;
}
private _renderItems() {
@@ -132,7 +128,7 @@ export class HaTargetPicker extends LitElement {
private _renderChips() {
return html`
-
+
+ ${this._renderPicker()}
${this.helper
? html`
${this.helper}`
@@ -200,11 +197,8 @@ export class HaTargetPicker extends LitElement {
`;
}
- private async _showPicker(ev) {
+ private _showPicker(ev) {
this._addMode = ev.currentTarget.type;
- await this.updateComplete;
- await this._inputElement?.focus();
- await this._inputElement?.open();
}
private _renderChip(
@@ -239,7 +233,7 @@ export class HaTargetPicker extends LitElement {
${type === "entity_id"
? ""
- : html`
+ : html`
- `;
- case "device_id":
- return html`
-
- `;
- case "entity_id":
- return html`
-
- `;
+ if (!this._addMode) {
+ return html``;
}
- return html``;
+ return html`${this._addMode === "area_id"
+ ? html`
+
+ `
+ : this._addMode === "device_id"
+ ? html`
+
+ `
+ : html`
+
+ `}`;
}
private _targetPicked(ev) {
@@ -347,7 +352,6 @@ export class HaTargetPicker extends LitElement {
const value = ev.detail.value;
const target = ev.currentTarget;
target.value = "";
- this._addMode = undefined;
if (
this.value &&
this.value[target.type] &&
@@ -454,6 +458,31 @@ export class HaTargetPicker extends LitElement {
return undefined;
}
+ private _onClosed(ev) {
+ ev.stopPropagation();
+ ev.target.open = true;
+ }
+
+ private async _onOpened() {
+ if (!this._addMode) {
+ return;
+ }
+ await this._inputElement?.focus();
+ await this._inputElement?.open();
+ this._opened = true;
+ }
+
+ private _openedChanged(ev: ComboBoxLightOpenedChangedEvent) {
+ if (this._opened && !ev.detail.value) {
+ this._opened = false;
+ this._addMode = undefined;
+ }
+ }
+
+ private _preventDefault(ev: Event) {
+ ev.preventDefault();
+ }
+
private _deviceMeetsFilter(device: DeviceRegistryEntry): boolean {
const devEntities = Object.values(this.hass.entities).filter(
(entity) => entity.device_id === device.id
@@ -555,12 +584,6 @@ export class HaTargetPicker extends LitElement {
static get styles(): CSSResultGroup {
return css`
${unsafeCSS(chipStyles)}
- .horizontal-container {
- display: flex;
- flex-wrap: wrap;
- min-height: 56px;
- align-items: center;
- }
.mdc-chip {
color: var(--primary-text-color);
}
@@ -573,6 +596,10 @@ export class HaTargetPicker extends LitElement {
.mdc-chip.add {
color: rgba(0, 0, 0, 0.87);
}
+ .add-container {
+ position: relative;
+ display: inline-flex;
+ }
.mdc-chip:not(.add) {
cursor: default;
}
@@ -644,6 +671,15 @@ export class HaTargetPicker extends LitElement {
opacity: var(--light-disabled-opacity);
pointer-events: none;
}
+ mwc-menu-surface {
+ --mdc-menu-min-width: 100%;
+ }
+ ha-entity-picker,
+ ha-device-picker,
+ ha-area-picker {
+ display: block;
+ width: 100%;
+ }
`;
}
}
diff --git a/src/panels/history/ha-panel-history.ts b/src/panels/history/ha-panel-history.ts
index b3be7664b4..cdaf307565 100644
--- a/src/panels/history/ha-panel-history.ts
+++ b/src/panels/history/ha-panel-history.ts
@@ -156,7 +156,7 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
-
+
@@ -510,18 +510,6 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
height: 100%;
}
- :host([narrow]) .narrow-wrap {
- flex-wrap: wrap;
- }
-
- .horizontal {
- align-items: center;
- }
-
- :host(:not([narrow])) .selector-padding {
- padding-left: 32px;
- }
-
.progress-wrapper {
position: relative;
}
@@ -529,11 +517,7 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
.filters {
display: flex;
align-items: flex-start;
- padding: 8px 16px 0;
- }
-
- :host([narrow]) .filters {
- flex-wrap: wrap;
+ margin-top: 16px;
}
ha-date-range-picker {
@@ -544,11 +528,15 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
direction: var(--direction);
}
- :host([narrow]) ha-date-range-picker {
- margin-right: 0;
- margin-inline-end: 0;
- margin-inline-start: initial;
- direction: var(--direction);
+ @media all and (max-width: 1025px) {
+ .filters {
+ flex-direction: column;
+ }
+ ha-date-range-picker {
+ margin-right: 0;
+ margin-inline-end: 0;
+ width: 100%;
+ }
}
ha-circular-progress {
@@ -558,17 +546,6 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
transform: translate(-50%, -50%);
}
- ha-entity-picker {
- display: inline-block;
- flex-grow: 1;
- max-width: 400px;
- }
-
- :host([narrow]) ha-entity-picker {
- max-width: none;
- width: 100%;
- }
-
.start-search {
padding-top: 16px;
text-align: center;
diff --git a/src/panels/logbook/ha-panel-logbook.ts b/src/panels/logbook/ha-panel-logbook.ts
index 8f53ce7f56..f3983a2c4b 100644
--- a/src/panels/logbook/ha-panel-logbook.ts
+++ b/src/panels/logbook/ha-panel-logbook.ts
@@ -249,6 +249,7 @@ export class HaPanelLogbook extends LitElement {
margin-inline-start: initial;
max-width: 100%;
direction: var(--direction);
+ margin-bottom: -5px;
}
:host([narrow]) ha-date-range-picker {
@@ -256,6 +257,7 @@ export class HaPanelLogbook extends LitElement {
margin-inline-end: 0;
margin-inline-start: initial;
direction: var(--direction);
+ margin-bottom: 8px;
}
.filters {