diff --git a/src/components/ha-area-filter.ts b/src/components/ha-area-filter.ts
index 9640f60e5e..504b4bf9f4 100644
--- a/src/components/ha-area-filter.ts
+++ b/src/components/ha-area-filter.ts
@@ -1,12 +1,12 @@
-import { mdiSofa } from "@mdi/js";
+import { mdiTextureBox } from "@mdi/js";
import { CSSResultGroup, LitElement, TemplateResult, css, html } from "lit";
import { customElement, property } from "lit/decorators";
import { fireEvent } from "../common/dom/fire_event";
import { showAreaFilterDialog } from "../dialogs/area-filter/show-area-filter-dialog";
import { HomeAssistant } from "../types";
+import "./ha-icon-next";
import "./ha-svg-icon";
import "./ha-textfield";
-import "./ha-icon-next";
export type AreaFilterValue = {
hidden?: string[];
@@ -51,7 +51,7 @@ export class HaAreaPicker extends LitElement {
@keydown=${this._edit}
.disabled=${this.disabled}
>
-
+
${this.label}
${description}
= (item) =>
@@ -49,9 +52,14 @@ const rowRenderer: ComboBoxLitRenderer = (item) =>
? "--mdc-list-side-padding-left: 48px;"
: ""}
>
- ${item.icon
- ? html``
- : nothing}
+ ${item.type === "floor"
+ ? html``
+ : item.icon
+ ? html``
+ : html``}
${item.name}
`;
@@ -165,6 +173,7 @@ export class HaAreaFloorPicker extends SubscribeMixin(LitElement) {
name: this.hass.localize("ui.components.area-picker.no_areas"),
icon: null,
strings: [],
+ level: null,
},
];
}
@@ -316,6 +325,7 @@ export class HaAreaFloorPicker extends SubscribeMixin(LitElement) {
name: this.hass.localize("ui.components.area-picker.no_match"),
icon: null,
strings: [],
+ level: null,
},
];
}
@@ -350,6 +360,7 @@ export class HaAreaFloorPicker extends SubscribeMixin(LitElement) {
name: floor.name,
icon: floor.icon,
strings: [floor.floor_id, ...floor.aliases, floor.name],
+ level: floor.level,
});
}
output.push(
@@ -360,6 +371,7 @@ export class HaAreaFloorPicker extends SubscribeMixin(LitElement) {
icon: area.icon,
strings: [area.area_id, ...area.aliases, area.name],
hasFloor: true,
+ level: null,
}))
);
});
@@ -373,6 +385,7 @@ export class HaAreaFloorPicker extends SubscribeMixin(LitElement) {
),
icon: null,
strings: [],
+ level: null,
});
}
@@ -383,6 +396,7 @@ export class HaAreaFloorPicker extends SubscribeMixin(LitElement) {
name: area.name,
icon: area.icon,
strings: [area.area_id, ...area.aliases, area.name],
+ level: null,
}))
);
diff --git a/src/components/ha-area-picker.ts b/src/components/ha-area-picker.ts
index 3f6301060c..a7b404f29a 100644
--- a/src/components/ha-area-picker.ts
+++ b/src/components/ha-area-picker.ts
@@ -1,14 +1,15 @@
+import { mdiTextureBox } from "@mdi/js";
import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
import { HassEntity } from "home-assistant-js-websocket";
-import { html, LitElement, nothing, PropertyValues, TemplateResult } from "lit";
+import { LitElement, PropertyValues, TemplateResult, html } from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import memoizeOne from "memoize-one";
import { fireEvent } from "../common/dom/fire_event";
import { computeDomain } from "../common/entity/compute_domain";
import {
- fuzzyFilterSort,
ScorableTextItem,
+ fuzzyFilterSort,
} from "../common/string/filter/sequence-matching";
import {
AreaRegistryEntry,
@@ -41,7 +42,7 @@ const rowRenderer: ComboBoxLitRenderer = (item) =>
>
${item.icon
? html``
- : nothing}
+ : html``}
${item.name}
`;
diff --git a/src/components/ha-filter-floor-areas.ts b/src/components/ha-filter-floor-areas.ts
index a90fba10f0..2ee817c370 100644
--- a/src/components/ha-filter-floor-areas.ts
+++ b/src/components/ha-filter-floor-areas.ts
@@ -1,4 +1,5 @@
import "@material/mwc-menu/mwc-menu-surface";
+import { mdiTextureBox } from "@mdi/js";
import { UnsubscribeFunc } from "home-assistant-js-websocket";
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
@@ -15,6 +16,9 @@ import { SubscribeMixin } from "../mixins/subscribe-mixin";
import { haStyleScrollbar } from "../resources/styles";
import type { HomeAssistant } from "../types";
import "./ha-check-list-item";
+import "./ha-floor-icon";
+import "./ha-icon";
+import "./ha-svg-icon";
@customElement("ha-filter-floor-areas")
export class HaFilterFloorAreas extends SubscribeMixin(LitElement) {
@@ -70,12 +74,10 @@ export class HaFilterFloorAreas extends SubscribeMixin(LitElement) {
graphic="icon"
@request-selected=${this._handleItemClick}
>
- ${floor.icon
- ? html``
- : nothing}
+
${floor.name}
${repeat(
@@ -108,7 +110,10 @@ export class HaFilterFloorAreas extends SubscribeMixin(LitElement) {
>
${area.icon
? html``
- : nothing}
+ : html``}
${area.name}
`;
}
diff --git a/src/components/ha-floor-icon.ts b/src/components/ha-floor-icon.ts
new file mode 100644
index 0000000000..edb840a57c
--- /dev/null
+++ b/src/components/ha-floor-icon.ts
@@ -0,0 +1,56 @@
+import {
+ mdiHome,
+ mdiHomeFloor0,
+ mdiHomeFloor1,
+ mdiHomeFloor2,
+ mdiHomeFloor3,
+ mdiHomeFloorNegative1,
+} from "@mdi/js";
+import { LitElement, html } from "lit";
+import { customElement, property } from "lit/decorators";
+import { FloorRegistryEntry } from "../data/floor_registry";
+import "./ha-icon";
+import "./ha-svg-icon";
+
+export const floorDefaultIconPath = (
+ floor: Pick
+) => {
+ switch (floor.level) {
+ case 0:
+ return mdiHomeFloor0;
+ case 1:
+ return mdiHomeFloor1;
+ case 2:
+ return mdiHomeFloor2;
+ case 3:
+ return mdiHomeFloor3;
+ case -1:
+ return mdiHomeFloorNegative1;
+ }
+ return mdiHome;
+};
+
+@customElement("ha-floor-icon")
+export class HaFloorIcon extends LitElement {
+ @property({ attribute: false }) public floor!: Pick<
+ FloorRegistryEntry,
+ "icon" | "level"
+ >;
+
+ @property() public icon?: string;
+
+ protected render() {
+ if (this.floor.icon) {
+ return html``;
+ }
+ const defaultPath = floorDefaultIconPath(this.floor);
+
+ return html``;
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "ha-floor-icon": HaFloorIcon;
+ }
+}
diff --git a/src/components/ha-floor-picker.ts b/src/components/ha-floor-picker.ts
index b344057543..1c6be3bf28 100644
--- a/src/components/ha-floor-picker.ts
+++ b/src/components/ha-floor-picker.ts
@@ -1,14 +1,14 @@
import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
-import { html, LitElement, nothing, PropertyValues, TemplateResult } from "lit";
+import { LitElement, PropertyValues, TemplateResult, html } from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import memoizeOne from "memoize-one";
import { fireEvent } from "../common/dom/fire_event";
import { computeDomain } from "../common/entity/compute_domain";
import {
- fuzzyFilterSort,
ScorableTextItem,
+ fuzzyFilterSort,
} from "../common/string/filter/sequence-matching";
import { AreaRegistryEntry } from "../data/area_registry";
import {
@@ -17,24 +17,24 @@ import {
getDeviceEntityDisplayLookup,
} from "../data/device_registry";
import { EntityRegistryDisplayEntry } from "../data/entity_registry";
+import {
+ FloorRegistryEntry,
+ createFloorRegistryEntry,
+ getFloorAreaLookup,
+ subscribeFloorRegistry,
+} from "../data/floor_registry";
import {
showAlertDialog,
showPromptDialog,
} from "../dialogs/generic/show-dialog-box";
+import { SubscribeMixin } from "../mixins/subscribe-mixin";
import { HomeAssistant, ValueChangedEvent } from "../types";
import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
import "./ha-combo-box";
import type { HaComboBox } from "./ha-combo-box";
+import "./ha-floor-icon";
import "./ha-icon-button";
import "./ha-list-item";
-import "./ha-svg-icon";
-import { SubscribeMixin } from "../mixins/subscribe-mixin";
-import {
- createFloorRegistryEntry,
- FloorRegistryEntry,
- getFloorAreaLookup,
- subscribeFloorRegistry,
-} from "../data/floor_registry";
type ScorableFloorRegistryEntry = ScorableTextItem & FloorRegistryEntry;
@@ -43,9 +43,7 @@ const rowRenderer: ComboBoxLitRenderer = (item) =>
graphic="icon"
class=${classMap({ "add-new": item.floor_id === "add_new" })}
>
- ${item.icon
- ? html``
- : nothing}
+
${item.name}
`;
diff --git a/src/components/ha-icon-picker.ts b/src/components/ha-icon-picker.ts
index 871adf5380..e148ff86bd 100644
--- a/src/components/ha-icon-picker.ts
+++ b/src/components/ha-icon-picker.ts
@@ -118,7 +118,7 @@ export class HaIconPicker extends LitElement {
`
- : html``}
+ : html``}
`;
}
diff --git a/src/components/ha-target-picker.ts b/src/components/ha-target-picker.ts
index 608a4ba829..21d32d3ea3 100644
--- a/src/components/ha-target-picker.ts
+++ b/src/components/ha-target-picker.ts
@@ -6,10 +6,10 @@ import "@material/mwc-menu/mwc-menu-surface";
import {
mdiClose,
mdiDevices,
- mdiFloorPlan,
+ mdiHome,
mdiLabel,
mdiPlus,
- mdiSofa,
+ mdiTextureBox,
mdiUnfoldMoreVertical,
} from "@mdi/js";
import { ComboBoxLightOpenedChangedEvent } from "@vaadin/combo-box/vaadin-combo-box-light";
@@ -18,30 +18,23 @@ import {
HassServiceTarget,
UnsubscribeFunc,
} from "home-assistant-js-websocket";
-import { css, CSSResultGroup, html, LitElement, nothing, unsafeCSS } from "lit";
+import { CSSResultGroup, LitElement, css, html, nothing, unsafeCSS } from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { ensureArray } from "../common/array/ensure-array";
+import { computeCssColor } from "../common/color/compute-color";
+import { hex2rgb } from "../common/color/convert-color";
import { fireEvent } from "../common/dom/fire_event";
import { stopPropagation } from "../common/dom/stop_propagation";
import { computeDomain } from "../common/entity/compute_domain";
import { computeStateName } from "../common/entity/compute_state_name";
import { isValidEntityId } from "../common/entity/valid_entity_id";
+import { AreaRegistryEntry } from "../data/area_registry";
import {
- computeDeviceName,
DeviceRegistryEntry,
+ computeDeviceName,
} from "../data/device_registry";
import { EntityRegistryDisplayEntry } from "../data/entity_registry";
-import { HomeAssistant } from "../types";
-import "./device/ha-device-picker";
-import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
-import "./entity/ha-entity-picker";
-import type { HaEntityPickerEntityFilterFunc } from "./entity/ha-entity-picker";
-import "./ha-area-floor-picker";
-import "./ha-icon-button";
-import "./ha-input-helper-text";
-import "./ha-svg-icon";
-import { SubscribeMixin } from "../mixins/subscribe-mixin";
import {
FloorRegistryEntry,
subscribeFloorRegistry,
@@ -50,9 +43,17 @@ import {
LabelRegistryEntry,
subscribeLabelRegistry,
} from "../data/label_registry";
-import { computeCssColor } from "../common/color/compute-color";
-import { AreaRegistryEntry } from "../data/area_registry";
-import { hex2rgb } from "../common/color/convert-color";
+import { SubscribeMixin } from "../mixins/subscribe-mixin";
+import { HomeAssistant } from "../types";
+import "./device/ha-device-picker";
+import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
+import "./entity/ha-entity-picker";
+import type { HaEntityPickerEntityFilterFunc } from "./entity/ha-entity-picker";
+import "./ha-area-floor-picker";
+import { floorDefaultIconPath } from "./ha-floor-icon";
+import "./ha-icon-button";
+import "./ha-input-helper-text";
+import "./ha-svg-icon";
@customElement("ha-target-picker")
export class HaTargetPicker extends SubscribeMixin(LitElement) {
@@ -138,7 +139,7 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
floor?.name || floor_id,
undefined,
floor?.icon,
- mdiFloorPlan
+ floor ? floorDefaultIconPath(floor) : mdiHome
);
})
: ""}
@@ -151,7 +152,7 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
area?.name || area_id,
undefined,
area?.icon,
- mdiSofa
+ mdiTextureBox
);
})
: nothing}
diff --git a/src/data/floor_registry.ts b/src/data/floor_registry.ts
index 32de014100..c69e31cc51 100644
--- a/src/data/floor_registry.ts
+++ b/src/data/floor_registry.ts
@@ -1,16 +1,16 @@
import { Connection, createCollection } from "home-assistant-js-websocket";
import { Store } from "home-assistant-js-websocket/dist/store";
import { stringCompare } from "../common/string/compare";
+import { debounce } from "../common/util/debounce";
import { HomeAssistant } from "../types";
import { AreaRegistryEntry } from "./area_registry";
-import { debounce } from "../common/util/debounce";
export { subscribeAreaRegistry } from "./ws-area_registry";
export interface FloorRegistryEntry {
floor_id: string;
name: string;
- level: number;
+ level: number | null;
icon: string | null;
aliases: string[];
}
diff --git a/src/panels/config/areas/dialog-floor-registry-detail.ts b/src/panels/config/areas/dialog-floor-registry-detail.ts
index eabd0c03b2..421c996b0c 100644
--- a/src/panels/config/areas/dialog-floor-registry-detail.ts
+++ b/src/panels/config/areas/dialog-floor-registry-detail.ts
@@ -6,10 +6,11 @@ import { fireEvent } from "../../../common/dom/fire_event";
import "../../../components/ha-alert";
import "../../../components/ha-aliases-editor";
import { createCloseHeading } from "../../../components/ha-dialog";
+import "../../../components/ha-icon-picker";
import "../../../components/ha-picture-upload";
import "../../../components/ha-settings-row";
+import "../../../components/ha-svg-icon";
import "../../../components/ha-textfield";
-import "../../../components/ha-icon-picker";
import { FloorRegistryEntryMutableParams } from "../../../data/floor_registry";
import { haStyleDialog } from "../../../resources/styles";
import { HomeAssistant } from "../../../types";
@@ -56,6 +57,7 @@ class DialogFloorDetail extends LitElement {
}
const entry = this._params.entry;
const nameInvalid = !this._isNameValid();
+
return html`
+ >
+ ${!this._icon
+ ? html`
+
+ `
+ : nothing}
+